summaryrefslogtreecommitdiffstats
path: root/x/binutils/gas
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2009-01-19 17:25:17 +0000
committerobrien <obrien@FreeBSD.org>2009-01-19 17:25:17 +0000
commit2b02dfaa48ad11ff3ee427ee1db57fb6017a8a5e (patch)
treeaf590d7b357b1c28ab81f0cde1b0ea76a098fb7e /x/binutils/gas
parentcd5f96a9efbe194cb6e0506e727cb6d287247d69 (diff)
downloadFreeBSD-src-2b02dfaa48ad11ff3ee427ee1db57fb6017a8a5e.zip
FreeBSD-src-2b02dfaa48ad11ff3ee427ee1db57fb6017a8a5e.tar.gz
Rename vendor/binutils/*/contrib to vendor/binutils/*/x
Binutils has a "contrib" subdirectory - thus flattening cannot happen without renaming the upper level contrib directory in a first pass. Also, don't record this move and remove any keyword expansion.
Diffstat (limited to 'x/binutils/gas')
-rw-r--r--x/binutils/gas/CONTRIBUTORS110
-rw-r--r--x/binutils/gas/ChangeLog612
-rw-r--r--x/binutils/gas/ChangeLog-00017703
-rw-r--r--x/binutils/gas/ChangeLog-02037519
-rw-r--r--x/binutils/gas/ChangeLog-929513117
-rw-r--r--x/binutils/gas/ChangeLog-96975959
-rw-r--r--x/binutils/gas/ChangeLog-98994860
-rw-r--r--x/binutils/gas/MAINTAINERS1
-rw-r--r--x/binutils/gas/Makefile.am2481
-rw-r--r--x/binutils/gas/Makefile.in3401
-rw-r--r--x/binutils/gas/NEWS422
-rw-r--r--x/binutils/gas/README241
-rw-r--r--x/binutils/gas/acconfig.h79
-rw-r--r--x/binutils/gas/acinclude.m472
-rw-r--r--x/binutils/gas/aclocal.m41006
-rw-r--r--x/binutils/gas/app.c1371
-rw-r--r--x/binutils/gas/as.c1165
-rw-r--r--x/binutils/gas/as.h717
-rw-r--r--x/binutils/gas/asintl.h43
-rw-r--r--x/binutils/gas/atof-generic.c630
-rw-r--r--x/binutils/gas/bignum-copy.c80
-rw-r--r--x/binutils/gas/bignum.h52
-rw-r--r--x/binutils/gas/bit_fix.h48
-rw-r--r--x/binutils/gas/cgen.c730
-rw-r--r--x/binutils/gas/cgen.h102
-rw-r--r--x/binutils/gas/cond.c542
-rw-r--r--x/binutils/gas/conf.in127
-rw-r--r--x/binutils/gas/config.in282
-rw-r--r--x/binutils/gas/config/aout_gnu.h450
-rw-r--r--x/binutils/gas/config/atof-ieee.c734
-rw-r--r--x/binutils/gas/config/atof-vax.c517
-rw-r--r--x/binutils/gas/config/e-i386aout.c19
-rw-r--r--x/binutils/gas/config/e-i386coff.c19
-rw-r--r--x/binutils/gas/config/e-i386elf.c19
-rw-r--r--x/binutils/gas/config/e-mipsecoff.c37
-rw-r--r--x/binutils/gas/config/e-mipself.c37
-rw-r--r--x/binutils/gas/config/i386coff.mt1
-rw-r--r--x/binutils/gas/config/itbl-mips.h47
-rw-r--r--x/binutils/gas/config/obj-aout.c707
-rw-r--r--x/binutils/gas/config/obj-aout.h256
-rw-r--r--x/binutils/gas/config/obj-coff.c4690
-rw-r--r--x/binutils/gas/config/obj-coff.h906
-rw-r--r--x/binutils/gas/config/obj-ecoff.c328
-rw-r--r--x/binutils/gas/config/obj-ecoff.h76
-rw-r--r--x/binutils/gas/config/obj-elf.c2193
-rw-r--r--x/binutils/gas/config/obj-elf.h250
-rw-r--r--x/binutils/gas/config/obj-generic.c41
-rw-r--r--x/binutils/gas/config/obj-generic.h79
-rw-r--r--x/binutils/gas/config/obj-ieee.c633
-rw-r--r--x/binutils/gas/config/obj-ieee.h50
-rw-r--r--x/binutils/gas/config/obj-multi.c4
-rw-r--r--x/binutils/gas/config/obj-multi.h162
-rw-r--r--x/binutils/gas/config/sco5.mt1
-rw-r--r--x/binutils/gas/config/tc-alpha.c5960
-rw-r--r--x/binutils/gas/config/tc-alpha.h182
-rw-r--r--x/binutils/gas/config/tc-arc.c2012
-rw-r--r--x/binutils/gas/config/tc-arc.h74
-rw-r--r--x/binutils/gas/config/tc-arm.c14300
-rw-r--r--x/binutils/gas/config/tc-arm.h211
-rw-r--r--x/binutils/gas/config/tc-generic.c0
-rw-r--r--x/binutils/gas/config/tc-generic.h39
-rw-r--r--x/binutils/gas/config/tc-i386.c6272
-rw-r--r--x/binutils/gas/config/tc-i386.h503
-rw-r--r--x/binutils/gas/config/tc-ia64.c11115
-rw-r--r--x/binutils/gas/config/tc-ia64.h299
-rw-r--r--x/binutils/gas/config/tc-m68851.h303
-rw-r--r--x/binutils/gas/config/tc-mips.c14431
-rw-r--r--x/binutils/gas/config/tc-mips.h188
-rw-r--r--x/binutils/gas/config/tc-ppc.c6063
-rw-r--r--x/binutils/gas/config/tc-ppc.h269
-rw-r--r--x/binutils/gas/config/tc-s390.c2311
-rw-r--r--x/binutils/gas/config/tc-s390.h102
-rw-r--r--x/binutils/gas/config/tc-sh.c4054
-rw-r--r--x/binutils/gas/config/tc-sh.h232
-rw-r--r--x/binutils/gas/config/tc-sparc.c4555
-rw-r--r--x/binutils/gas/config/tc-sparc.h194
-rw-r--r--x/binutils/gas/config/tc-tic30.c1881
-rw-r--r--x/binutils/gas/config/tc-tic30.h55
-rw-r--r--x/binutils/gas/config/tc-v850.c2434
-rw-r--r--x/binutils/gas/config/tc-v850.h98
-rw-r--r--x/binutils/gas/config/tc-z8k.c1566
-rw-r--r--x/binutils/gas/config/tc-z8k.h53
-rw-r--r--x/binutils/gas/config/te-386bsd.h33
-rw-r--r--x/binutils/gas/config/te-aux.h17
-rw-r--r--x/binutils/gas/config/te-freebsd.h30
-rw-r--r--x/binutils/gas/config/te-generic.h22
-rw-r--r--x/binutils/gas/config/te-linux.h4
-rw-r--r--x/binutils/gas/config/te-multi.h22
-rw-r--r--x/binutils/gas/config/te-nbsd.h24
-rw-r--r--x/binutils/gas/config/te-pe.h7
-rw-r--r--x/binutils/gas/config/te-ppcnw.h32
-rw-r--r--x/binutils/gas/config/te-sparcaout.h22
-rw-r--r--x/binutils/gas/config/te-svr4.h4
-rw-r--r--x/binutils/gas/config/te-sysv32.h6
-rw-r--r--x/binutils/gas/config/te-tmips.h40
-rwxr-xr-xx/binutils/gas/configure12362
-rw-r--r--x/binutils/gas/configure.in1084
-rw-r--r--x/binutils/gas/debug.c104
-rw-r--r--x/binutils/gas/dep-in.sed53
-rw-r--r--x/binutils/gas/depend.c206
-rw-r--r--x/binutils/gas/doc/Makefile.am100
-rw-r--r--x/binutils/gas/doc/Makefile.in608
-rw-r--r--x/binutils/gas/doc/all.texi87
-rw-r--r--x/binutils/gas/doc/as.1970
-rw-r--r--x/binutils/gas/doc/as.texinfo6449
-rw-r--r--x/binutils/gas/doc/c-alpha.texi466
-rw-r--r--x/binutils/gas/doc/c-arc.texi207
-rw-r--r--x/binutils/gas/doc/c-arm.texi490
-rw-r--r--x/binutils/gas/doc/c-i386.texi755
-rw-r--r--x/binutils/gas/doc/c-ia64.texi157
-rw-r--r--x/binutils/gas/doc/c-mips.texi377
-rw-r--r--x/binutils/gas/doc/c-ppc.texi126
-rw-r--r--x/binutils/gas/doc/c-sh.texi327
-rw-r--r--x/binutils/gas/doc/c-sparc.texi195
-rw-r--r--x/binutils/gas/doc/c-v850.texi363
-rw-r--r--x/binutils/gas/doc/c-z8k.texi380
-rw-r--r--x/binutils/gas/doc/gasp.texi1456
-rw-r--r--x/binutils/gas/doc/gasver.texi1
-rw-r--r--x/binutils/gas/doc/h8.texi26
-rw-r--r--x/binutils/gas/doc/internals.texi1948
-rw-r--r--x/binutils/gas/dw2gencfi.c1042
-rw-r--r--x/binutils/gas/dw2gencfi.h52
-rw-r--r--x/binutils/gas/dwarf2dbg.c1464
-rw-r--r--x/binutils/gas/dwarf2dbg.h84
-rw-r--r--x/binutils/gas/ecoff.c5236
-rw-r--r--x/binutils/gas/ecoff.h111
-rw-r--r--x/binutils/gas/ehopt.c540
-rw-r--r--x/binutils/gas/emul-target.h64
-rw-r--r--x/binutils/gas/emul.h44
-rw-r--r--x/binutils/gas/expr.c1917
-rw-r--r--x/binutils/gas/expr.h171
-rw-r--r--x/binutils/gas/flonum-copy.c71
-rw-r--r--x/binutils/gas/flonum-konst.c228
-rw-r--r--x/binutils/gas/flonum-mult.c188
-rw-r--r--x/binutils/gas/flonum.h102
-rw-r--r--x/binutils/gas/frags.c378
-rw-r--r--x/binutils/gas/frags.h162
-rw-r--r--x/binutils/gas/gasp.c3761
-rw-r--r--x/binutils/gas/gdbinit.in39
-rw-r--r--x/binutils/gas/hash.c579
-rw-r--r--x/binutils/gas/hash.h78
-rw-r--r--x/binutils/gas/input-file.c273
-rw-r--r--x/binutils/gas/input-file.h66
-rw-r--r--x/binutils/gas/input-scrub.c514
-rw-r--r--x/binutils/gas/itbl-lex.l114
-rw-r--r--x/binutils/gas/itbl-ops.c901
-rw-r--r--x/binutils/gas/itbl-ops.h108
-rw-r--r--x/binutils/gas/itbl-parse.y460
-rw-r--r--x/binutils/gas/link.cmd10
-rw-r--r--x/binutils/gas/listing.c1344
-rw-r--r--x/binutils/gas/listing.h67
-rw-r--r--x/binutils/gas/literal.c95
-rw-r--r--x/binutils/gas/macro.c1177
-rw-r--r--x/binutils/gas/macro.h83
-rw-r--r--x/binutils/gas/messages.c505
-rw-r--r--x/binutils/gas/obj.h94
-rw-r--r--x/binutils/gas/output-file.c154
-rw-r--r--x/binutils/gas/output-file.h26
-rw-r--r--x/binutils/gas/po/Make-in253
-rw-r--r--x/binutils/gas/po/POTFILES.in213
-rw-r--r--x/binutils/gas/po/gas.pot11467
-rw-r--r--x/binutils/gas/read.c5204
-rw-r--r--x/binutils/gas/read.h188
-rw-r--r--x/binutils/gas/sb.c264
-rw-r--r--x/binutils/gas/sb.h99
-rw-r--r--x/binutils/gas/stabs.c708
-rw-r--r--x/binutils/gas/stamp-h.in1
-rw-r--r--x/binutils/gas/struc-symbol.h159
-rw-r--r--x/binutils/gas/subsegs.c646
-rw-r--r--x/binutils/gas/subsegs.h155
-rw-r--r--x/binutils/gas/symbols.c2576
-rw-r--r--x/binutils/gas/symbols.h213
-rw-r--r--x/binutils/gas/tc.h93
-rw-r--r--x/binutils/gas/write.c2839
-rw-r--r--x/binutils/gas/write.h217
175 files changed, 222641 insertions, 0 deletions
diff --git a/x/binutils/gas/CONTRIBUTORS b/x/binutils/gas/CONTRIBUTORS
new file mode 100644
index 0000000..d564ba8
--- /dev/null
+++ b/x/binutils/gas/CONTRIBUTORS
@@ -0,0 +1,110 @@
+(This file is under construction.) -*- text -*-
+
+If you've contributed to gas and your name isn't listed here, it is
+not meant as a slight. I just don't know about it. Email me,
+nickc@redhat.com and I'll correct the situation.
+
+This file will eventually be deleted: The general info will go into
+the documentation, and info on specific files will go into an AUTHORS
+file, as requested by the FSF.
+
+++++++++++++++++
+
+Dean Elsner wrote the original gas for vax. [more details?]
+
+Jay Fenlason maintained gas for a while, adding support for
+gdb-specific debug information and the 68k series machines, most of
+the preprocessing pass, and extensive changes in messages.c,
+input-file.c, write.c.
+
+K. Richard Pixley maintained gas for a while, adding various
+enhancements and many bug fixes, including merging support for several
+processors, breaking gas up to handle multiple object file format
+backends (including heavy rewrite, testing, an integration of the coff
+and b.out backends), adding configuration including heavy testing and
+verification of cross assemblers and file splits and renaming,
+converted gas to strictly ansi C including full prototypes, added
+support for m680[34]0 & cpu32, considerable work on i960 including a
+coff port (including considerable amounts of reverse engineering), a
+sparc opcode file rewrite, decstation, rs6000, and hp300hpux host
+ports, updated "know" assertions and made them work, much other
+reorganization, cleanup, and lint.
+
+Ken Raeburn wrote the high-level BFD interface code to replace most of
+the code in format-specific I/O modules.
+
+The original Vax-VMS support was contributed by David L. Kashtan.
+Eric Youngdale and Pat Rankin have done much work with it since.
+
+The Intel 80386 machine description was written by Eliot Dresselhaus.
+
+Minh Tran-Le at IntelliCorp contributed some AIX 386 support.
+
+The Motorola 88k machine description was contributed by Devon Bowen of
+Buffalo University and Torbjorn Granlund of the Swedish Institute of
+Computer Science.
+
+Keith Knowles at the Open Software Foundation wrote the original MIPS
+back end (tc-mips.c, tc-mips.h), and contributed Rose format support
+that hasn't been merged in yet. Ralph Campbell worked with the MIPS
+code to support a.out format.
+
+Support for the Zilog Z8k and Hitachi H8/300, H8/500 and SH processors
+(tc-z8k, tc-h8300, tc-h8500, tc-sh), and IEEE 695 object file format
+(obj-ieee), was written by Steve Chamberlain of Cygnus Solutions.
+Steve also modified the COFF back end (obj-coffbfd) to use BFD for
+some low-level operations, for use with the Hitachi, 29k and Zilog
+targets.
+
+John Gilmore built the AMD 29000 support, added .include support, and
+simplified the configuration of which versions accept which
+pseudo-ops. He updated the 68k machine description so that Motorola's
+opcodes always produced fixed-size instructions (e.g. jsr), while
+synthetic instructions remained shrinkable (jbsr). John fixed many
+bugs, including true tested cross-compilation support, and one bug in
+relaxation that took a week and required the proverbial one-bit fix.
+
+Ian Lance Taylor of Cygnus Solutions merged the Motorola and MIT
+syntaxes for the 68k, completed support for some COFF targets (68k,
+i386 SVR3, and SCO Unix), wrote the ECOFF support based on Michael
+Meissner's mips-tfile program, wrote the PowerPC and RS/6000 support,
+and made a few other minor patches. He handled the binutils releases
+for versions 2.7 through 2.9.
+
+David Edelsohn contributed fixes for the PowerPC and AIX support.
+
+Steve Chamberlain made gas able to generate listings.
+
+Support for the HP9000/300 was contributed by Glenn Engel of HP.
+
+Support for ELF format files has been worked on by Mark Eichin of
+Cygnus Solutions (original, incomplete implementation), Pete
+Hoogenboom at the University of Utah (HPPA mainly), Michael Meissner
+of the Open Software Foundation (i386 mainly), and Ken Raeburn of
+Cygnus Solutions (sparc, initial 64-bit support).
+
+Several engineers at Cygnus Solutions have also provided many small
+bug fixes and configuration enhancements.
+
+The initial Alpha support was contributed by Carnegie-Mellon
+University. Additional work was done by Ken Raeburn of Cygnus
+Solutions. Richard Henderson then rewrote much of the Alpha support.
+
+Ian Dall updated the support code for the National Semiconductor 32000
+series, and added support for Mach 3 and NetBSD running on the PC532.
+
+Klaus Kaempf ported the assembler and the binutils to openVMS/Alpha.
+
+Steve Haworth contributed the support for the Texas Instruction c30
+(tms320c30).
+
+H.J. Lu has contributed many patches and much testing.
+
+Alan Modra reworked much of the i386 backend, improving the error
+checking, updating the code, and improving the 16 bit support, using
+patches from the work of Martynas Kunigelis and H.J. Lu.
+
+Many others have contributed large or small bugfixes and enhancements. If
+you've contributed significant work and are not mentioned on this list, and
+want to be, let us know. Some of the history has been lost; we aren't
+intentionally leaving anyone out.
diff --git a/x/binutils/gas/ChangeLog b/x/binutils/gas/ChangeLog
new file mode 100644
index 0000000..df93f2a
--- /dev/null
+++ b/x/binutils/gas/ChangeLog
@@ -0,0 +1,612 @@
+2004-05-23 Alan Modra <amodra@bigpond.net.au>
+
+ * expr.c (operand, operator): Don't reject '++' and '--'.
+
+2004-05-13 Joel Sherrill <joel@oarcorp.com>
+
+ * configure.in (or32-*-rtems*): Switch to elf.
+ * configure: Regenerate.
+
+2004-05-13 Nick Clifton <nickc@redhat.com>
+
+ * po/fr.po: Updated French translation.
+
+2004-05-07 Daniel Jacobowitz <dan@debian.org>
+
+ * Makefile.am (DIST_SUBDIRS): Define.
+ * aclocal.m4: Regenerate with automake 1.8.4.
+ * Makefile.in: Likewise.
+ * doc/Makefile.in: Likewise.
+
+2004-05-07 Daniel Jacobowitz <dan@debian.org>
+
+ Merge from mainline:
+ 2004-05-05 Jakub Jelinek <jakub@redhat.com>
+ * tc-s390.h (md_do_align, HANDLE_ALIGN): Remove.
+ (NOP_OPCODE): Define.
+ (s390_align_code): Remove prototype.
+ * tc-s390.c (s390_align_code): Remove.
+
+ 2004-04-22 Bruno De Bus <bdebus@elis.ugent.be>
+ * config/tc-arm.h (enum mstate): Move here, add MAP_UNDEFINED
+ state.
+ (TC_SEGMENT_INFO_TYPE): Define to enum mstate.
+ * config/tc-arm.c (enum mstate): Delete from here.
+ (mapping_state): Remove the static mapstate variable and instead
+ store the state in the segment. This allows a per-section mapping
+ state. Handle and ignore MAP_UNDEFINED states.
+ (arm_elf_change_section): Get the current mapping state from the
+ new section.
+ (s_ltorg): Set the mapping state to MAP_DATA.
+ (arm_cleanup): Use arm_elf_change_section to get the mapping state
+ for each pool as it is emitted.
+
+ 2004-04-22 Nick Clifton <nickc@redhat.com>
+ * config/tc-arm.h: Formatting tidy ups.
+
+2004-05-07 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-frv.h (MAX_MEM_FOR_RS_ALIGN_CODE): New.
+ (HANDLE_ALIGN): New.
+
+2004-05-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure.in: Set em=linux for frv-*-*linux*.
+ * configure: Rebuilt.
+ * config/tc-frv.h (TARGET_FORMAT): Use elf32-frvfdpic if...
+ (frv_md_fdpic_enabled): New.
+ * config/tc-frv.c (frv_md_fdpic_enabled): New.
+ (DEFAULT_FDPIC): New.
+ (frv_flags): Use DEFAULT_FDPIC.
+ (frv_pic_flag): Likewise.
+ (OPTION_NOPIC): New.
+ (md_longopts): Add -mnopic.
+ (md_parse_option): Handle it.
+ (md_show_usage): Add -mfdpic and -mnopic.
+
+2004-04-20 Chris Demetriou <cgd@broadcom.com>
+
+ * NEWS: Note that MIPS -membedded-pic option is deprecated.
+
+2004-04-19 Eric Christopher <echristo@redhat.com>
+
+ * config/tc-mips.c (mips_dwarf2_addr_size): Revert part
+ of previous patch for fix in gcc.
+
+2004-04-16 Alan Modra <amodra@bigpond.net.au>
+
+ * expr.c (operand): Correct checks for ++ and --.
+
+2004-04-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/c-mips.texi (-m{no-,}fix-vr4120): Renamed from
+ -{no-}mfix-vr4122-bugs.
+ * config/tc-mips.c (mips_fix_vr4120): Renamed from mips_fix_4122_bugs.
+ (append_insn, mips_emit_delays): Update accordingly.
+ (OPTION_FIX_VR4120, OPTION_NO_FIX_VR4120): Renamed from *VR4122.
+ (md_longopts): Change -{no-,}mfix-vr4122-bugs to -m{no-,}fix-vr4120.
+ (md_parse_option): Update after above changes.
+ (md_show_usage): Add -mfix-vr4120.
+
+2004-04-11 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * Makefile.am: Remove mips from aout targets.
+ * Makefile.in: Regenerate.
+ * configure.in: Remove mips-dec-bsd* target.
+ * configure: Regenerate.
+
+2004-04-09 Daniel Jacobowitz <drow@mvista.com>
+
+ Merge from mainline:
+ 2004-04-07 Alan Modra <amodra@bigpond.net.au>
+ PR 96
+ * config/tc-ppc.c (ppc_elf_suffix): Add valid32 and valid64 fields
+ to struct map_bfd. Adjust MAP macro, and define MAP32, MAP64.
+ Update "mapping". Restrict some @ modifiers to 32 bit.
+
+ 2004-04-01 Asgari Jinia <asgarij@kpitcummins.com>
+ Dhananjay Deshpande <dhananjayd@kpitcummins.com>
+
+ * config/tc-sh.c (dont_adjust_reloc_32): New variable.
+ (sh_fix_adjustable): Avoid adjusting BFD_RELOC_32 when
+ dont_adjust_reloc_32 is set.
+ (md_longopts): Add option -renesas.
+ (md_parse_option, md_show_usage): Likewise.
+ * doc/c-sh.texi: Likewise.
+
+ 2004-04-01 Dave Korn <dk@artimi.com>
+ * config/tc-dlx.c (md_assemble): set fx_no_overflow flag for
+ hi16 and lo16 fixS structs.
+ (md_assemble): generate bit_fixS for RELOC_DLX_LO16 in
+ exactly the same way as for RELOC_DLX_REL16.
+ (machine_ip): properly respect LO flag in the_insn and
+ output RELOC_DLX_LO16 rather than RELOC_DLX_16.
+ (md_apply_fix3): apply RELOC_DLX_LO16.
+
+ 2004-03-19 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+ * tc-hppa.c (cons_fix_new_hppa): Check for PC relative base type.
+ (pa_comm): Set BSF_OBJECT in symbol flags.
+
+ 2004-03-18 Nathan Sidwell <nathan@codesourcery.com>
+ * read.c (read_a_source_file): Use demand_empty_rest_of_line.
+ (demand_empty_rest_of_line): Issue an error here.
+ (ignore_rest_of_line): Silently skip to end.
+ (demand_copy_string): Issue an error, not warning.
+ (equals): Likewise.
+ * config/obj-elf.c (obj_elf_section_name): Likewise.
+ (obj_elf_section): Likewise.
+ * config/tc-arc.c (arc_extoper): Remove bogus NULL checks.
+ (arc_extinst): Likewise.
+ * config/tc-ia64.c (dot_saveb): Use demand_empty_rest_of_line.
+ (dot_spill): Likewise.
+ (dot_unwabi): Likewise.
+ (dot_prologue): Likewise.
+
+ 2004-03-18 Nathan Sidwell <nathan@codesourcery.com>
+ * expr.c (operand): Reject ++ and --.
+ (operator): Likewise.
+
+ 2004-03-12 Bob Wilson <bob.wilson@acm.org>
+ * read.c (s_leb128): Call md_flush_pending_output.
+
+ 2004-03-07 Andreas Schwab <schwab@suse.de>
+ * doc/c-hppa.texi (HPPA Directives): Fix typo.
+
+ 2004-03-07 Richard Henderson <rth@redhat.com>
+ * dw2gencfi.c (output_cie): Align length to 4 byte boundary.
+ (cfi_finish): Likewise for fde.
+
+ 2004-03-05 H.J. Lu <hongjiu.lu@intel.com>
+ * config/tc-ia64.c (md_assemble): Properly handle NULL
+ align_frag.
+ (ia64_handle_align): Don't abort if failed to add a stop bit.
+
+ 2004-03-04 H.J. Lu <hongjiu.lu@intel.com>
+ * Makefile.in: Regenerated.
+ * aclocal.m4: Likewise.
+ * configure: Likewise.
+ * doc/Makefile.in: Likewise.
+
+ 2004-03-03 H.J. Lu <hongjiu.lu@intel.com>
+ * config/tc-ia64.c (dot_align): New.
+ (ia64_do_align): Make it static.
+ (md_pseudo_table): Use "dot_align" for "align".
+ (ia64_md_do_align): Don't set align_frag here.
+ (ia64_handle_align): Add a stop bit to the previous bundle if
+ needed.
+
+ * config/tc-ia64.h (ia64_do_align): Removed.
+
+ 2004-03-02 H.J. Lu <hongjiu.lu@intel.com>
+ * config/tc-ia64.c (align_frag): New.
+ (md_assemble): Set the tc_frag_data field in align_frag for
+ IA64_OPCODE_FIRST instructions.
+ (ia64_md_do_align): Set align_frag.
+ (ia64_handle_align): Add a stop bit if needed.
+
+ * config/tc-ia64.h (TC_FRAG_TYPE): New.
+ (TC_FRAG_INIT): New.
+
+ 2004-02-27 Nick Clifton <nickc@redhat.com>
+ * config/tc-sh.c (get_operand): Revert previous delta.
+ (tc_gen_reloc): Check for an unknown reloc type before processing
+ the addend.
+
+ 2004-02-27 Hannes Reinecke <hare@suse.de>
+ * config/tc-s390.c (s390_insn): Correct range check for opcode in
+ .insn pseudo operation.
+
+ 2004-02-27 Anil Paranjpe <anilp1@kpitcummins.com>
+ * config/tc-sh.c (get_operand): In case of #Imm, check has been
+ added for wrong syntax.
+
+ 2004-02-26 Andrew Stubbs <andrew.stubbs@superh.com>
+ * config/tc-sh.c (build_Mytes): Add REG_N_D and REG_N_B01
+ nibble types to assembler.
+
+ 2004-02-25 Fred Fish <fnf@redhat.com>
+ * config/tc-iq2000.c: Add missing \n\ in multiline string literal.
+
+ 2004-02-20 James E Wilson <wilson@specifixinc.com>
+ * config/tc-ia64.c (slot_index): New arg before_relax. Use instead of
+ finalize_syms.
+ (fixup_unw_records): New arg before_relax. Pass to slot_index.
+ (ia64_estimate_size_before_relax): New.
+ (ia64_convert_frag): Pass 0 to fixup_unw_records. Add comment.
+ (generate_unwind_image): Pass 1 to fixup_unw_records.
+ * config/tc-ia64.h (ia64_estimate_size_before_relax): Declare.
+ (md_estimate_size_before_relax): Call ia64_estimate_size_before_relax.
+
+ 2004-02-19 Jakub Jelinek <jakub@redhat.com>
+ * stabs.c (generate_asm_file): Avoid warning about use of
+ uninitialized variable.
+
+ 2004-02-18 David Mosberger <davidm@hpl.hp.com>
+ * config/tc-ia64.c (ia64_flush_insns): In addition to prologue,
+ body, and endp, allow unwind records which do not have a "t"
+ (time/instruction) field.
+
+2004-03-22 Bob Wilson <bob.wilson@acm.org>
+
+ * config/tc-xtensa.c (xtensa_post_relax_hook): Create literal
+ tables even when use_literal_section flag is not set.
+
+2004-03-22 Hans-Peter Nilsson <hp@axis.com>
+
+ * doc/c-cris.texi (CRIS-Opts): Document --no-mul-bug-abort,
+ --mul-bug-abort and the default behavior.
+ * config/tc-cris.c (cris_insn_kind): New member CRIS_INSN_MUL.
+ (err_for_dangerous_mul_placement): New variable.
+ (STATE_MUL, OPTION_MULBUG_ABORT_ON, OPTION_MULBUG_ABORT_OFF): New
+ macros.
+ (md_cris_relax_table): Have placeholder for STATE_MUL.
+ (md_longopts): New options --mul-bug-abort and --no-mul-bug-abort.
+ (cris_relax_frag) <case ENCODE_RELAX (STATE_MUL, STATE_BYTE)>: New
+ case doing nothing.
+ (md_estimate_size_before_relax) <case ENCODE_RELAX (STATE_MUL,
+ STATE_BYTE)>: Ditto.
+ (md_convert_frag) <ENCODE_RELAX (STATE_MUL, STATE_BYTE)>: Check
+ alignment and position of this frag, emit error message if
+ suspicious.
+ (md_assemble): For a multiply insn and when checking it,
+ transform the current frag into a special frag for that purpose.
+ (md_parse_option) <case OPTION_MULBUG_ABORT_OFF, case
+ OPTION_MULBUG_ABORT_ON>: Handle new options.
+
+2004-03-19 Bob Wilson <bob.wilson@acm.org>
+
+ * config/tc-xtensa.c (mark_literal_frags): New function.
+ (xtensa_move_literals): Call mark_literal_frags for all literal
+ segments, including init and fini literal segments.
+ (xtensa_post_relax_hook): Swap use of xt_insn_sec and xt_literal_sec.
+
+2004-03-17 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * config/tc-sh.c: Include dw2gencfi.h.
+ (sh_cfi_frame_initial_instructions): New function.
+ (sh_regname_to_dw2regnum): Likewise.
+ * config/tc-sh.h (DWARF2_LINE_MIN_INSN_LENGTH): Move to the end of
+ file.
+ (TARGET_USE_CFIPOP): Define.
+ (tc_cfi_frame_initial_instructions): Likewise.
+ (tc_regname_to_dw2regnum): Likewise.
+ (DWARF2_DEFAULT_RETURN_COLUMN, DWARF2_CIE_DATA_ALIGNMENT): Likewise.
+ * Makefile.am: Update dependencies.
+ * Makefile.in: Regenerate.
+
+2004-03-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.in: Switch sh-*-rtems* to ELF. Add sh-*-rtemscoff*.
+ * configure: Regenerate.
+
+2004-03-12 Bob Wilson <bob.wilson@acm.org>
+
+ * read.c (s_leb128): Call md_flush_pending_output.
+
+2004-03-12 Michal Ludvig <mludvig@suse.cz>
+
+ * config/tc-i386.c (output_insn): Handle PadLock instructions.
+ * config/tc-i386.h (CpuPadLock): New define.
+ (CpuUnknownFlags): Added CpuPadLock.
+
+2004-02-26 Eric Christopher <echristo@redhat.com>
+
+ * config/tc-mips.c (mips_dwarf2_addr_size): New.
+ * config/tc-mips.h (DWARF2_ADDR_SIZE): Use.
+
+2004-02-17 Petko Manolov <petkan@nucleusys.com>
+
+ * config/tc-arm.c (do_mav_dspsc_1): Correct offset of CRn.
+ (do_mav_dspsc_2): Likewise.
+ Fix accumulator registers move opcodes.
+
+2004-02-13 Hannes Reinecke <hare@suse.de>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf2dbg.c (get_filenum): Do not read beyond allocated memory.
+
+2004-02-10 Steve Ellcey <sje@cup.hp.com>
+
+ * config/tc-ia64.h (ia64_frob_symbol): New declaration.
+ (tc_frob_symbol): New macro definition.
+ * config/tc-ia64.c (ia64_frob_symbol): New routine.
+
+2004-02-09 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/tc-arm.c (md_begin): Mark .note.gnu.arm.ident as
+ read-only.
+
+2004-02-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * read.h (IGNORE_OPCODE_CASE): Do not define. Replace with ...
+ (TC_CASE_SENSITIVE): ... this.
+ * read.c: Replace IGNORE_OPCODE_CASE with TC_CASE_SENSITIVE.
+ * doc/internals.texi (TC_CASE_SENSITIVE): Document.
+
+2004-02-06 James E Wilson <wilson@specifixinc.com>
+
+ * config/tc-ia64.c (dot_endp): Delete call to output_endp.
+ (generate_unwind_image): Re-add it here.
+
+2004-02-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * dwarf2dbg.c (DWARF2_ADDR_SIZE): Remove trailing ';'
+ * read.h (SKIP_WHITESPACE): Turn into an expression.
+ * read.c (read_a_source_file): A pseudo is removed by having a
+ NULL handler.
+
+2004-02-05 James E Wilson <wilson@specifixinc.com>
+
+ * config/tc-ia64.c (output_endp): New.
+ (count_bits): Delete.
+ (ia64_flush_insns, process_one_record, optimize_unw_records): Handle
+ endp unwind records.
+ (fixup_unw_records): Handle endp unwind records. Delete code for
+ shortening prologue regions not followed by a body record.
+ (dot_endp): Call add_unwind_entry to emit endp unwind record.
+ * config/tc-ia64.h (unw_record_type): Add endp.
+
+2004-02-03 James E Wilson <wilson@specifixinc.com>
+
+ * config/tc-ia64.c (ia64_convert_frag): Call md_number_to_chars to
+ fill padding bytes with zeroes.
+ (emit_one_bundle): New locals last_ptr, end_ptr. Rewrite code that
+ sets unwind_record slot_number and slot_frag fields.
+
+2004-02-02 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * config/tc-mips.c (add_got_offset_hilo): New function.
+ (macro): Use load_register() and add_got_offset_hilo() to load
+ constants instead of hardcoding code sequences throughout.
+
+2004-01-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/tc-ia64.c (emit_one_bundle): Add proper indentation.
+
+2004-01-26 Bernardo Innocenti <bernie@develer.com>
+
+ * config/tc-m68k.h (EXTERN_FORCE_RELOC): Handle m68k-uclinux specially,
+ like m68k-elf.
+ * config/tc-m68k.c (RELAXABLE_SYMBOL): Use EXTERN_FORCE_RELOC instead
+ of hard-coded test for TARGET_OS=elf.
+
+2004-01-24 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (hilo_interlocks): Change definition
+ so that MIPS32, MIPS64 and later ISAs are included, along with
+ the already-included machines. Update comments.
+
+2004-01-23 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/tc-arm.c (tc_gen_reloc): Improve error message for
+ undefined local labels.
+
+2004-01-23 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (load_address, macro): Update comments about
+ NewABI GP relaxation.
+
+2004-01-23 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (macro_build): Remove place and counter arguments.
+ (mips_build_lui, macro_build_ldst_constoffset): Likewise.
+ (mips16_macro_build, macro_build_jalr): Remove counter argument.
+ (set_at, load_register, load_address, move_register): Likewise.
+ (load_got_offset, add_got_offset): Likewise.
+ Update all calls and tidy accordingly.
+
+2004-01-23 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (RELAX_ENCODE): Remove WARN argument.
+ (RELAX_FIRST, RELAX_SECOND): Turn into 8-bit quantities.
+ (RELAX_USE_SECOND): Bump to 0x10000.
+ (RELAX_SECOND_LONGER, RELAX_NOMACRO, RELAX_DELAY_SLOT): New flags.
+ (mips_macro_warning): New variable.
+ (md_assemble): Wrap macro expansion in macro_start() and macro_end().
+ (s_cpload, s_cpsetup, s_cprestore, s_cpreturn): Likewise.
+ (relax_close_frag): Set mips_macro_warning.first_frag. Adjust use
+ of RELAX_ENCODE.
+ (append_insn): Update mips_macro_warning.sizes.
+ (macro_start, macro_warning, macro_end): New functions.
+ (macro_build): Don't emit warnings here.
+ (macro_build_lui, md_estimate_size_before_relax): ...or here.
+ (md_convert_frag): Check for cases where one macro alternative
+ needs a warning and the other doesn't. Emit a warning if the
+ longer sequence was chosen.
+
+2004-01-23 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.h (tc_frag_data_type, TC_FRAG_TYPE): Remove.
+ * config/tc-mips.c (RELAX_ENCODE): Take three arguments: the size of
+ the first sequence, the size of the second sequence, and a flag
+ that says whether we should warn.
+ (RELAX_OLD, RELAX_NEW, RELAX_RELOC[123]): Delete.
+ (RELAX_FIRST, RELAX_SECOND): New.
+ (mips_relax): New variable.
+ (relax_close_frag, relax_start, relax_switch, relax_end): New fns.
+ (append_insn): Remove "place" argument. Use mips_relax.sequence
+ rather than "place" to check whether we're expanding the second
+ alternative of a relaxable macro. Remove redundant check for
+ branch relaxation. If generating a normal insn, and there
+ is not enough room in the current frag, call relax_close_frag()
+ to close it. Update mips_relax.sizes[]. Emit fixups for the
+ second version of a relaxable macro. Record the first relaxable
+ fixup in mips_relax. Remove tc_gen_reloc workaround.
+ (macro_build): Remove all uses of "place". Use mips_relax.sequence
+ in the same way as in append_insn.
+ (mips16_macro_build): Remove "place" argument.
+ (macro_build_lui): As for macro_build. Don't drop the add_symbol
+ when generating the second version of a relaxable macro.
+ (load_got_offset, add_got_offset): New functions.
+ (load_address, macro): Use new relaxation machinery. Remove
+ tc_gen_reloc workarounds.
+ (md_estimate_size_before_relax): Set RELAX_USE_SECOND if the second
+ version of a relaxable macro is needed. Return -RELAX_SECOND if the
+ first version is needed.
+ (tc_gen_reloc): Remove relaxation handling.
+ (md_convert_frag): Go through the fixups for a relaxable macro and
+ mark those that belong to the unneeded alternative as done. If the
+ second alternative is needed, adjust the fixup addresses to account
+ for the deleted first alternative.
+
+2004-01-23 Richard Sandiford <rsandifo@redhat.com>
+
+ * frags.h (frag_room): Declare.
+ * frags.c (frag_room): New function.
+ * doc/internals.texi: Document it.
+
+2004-01-22 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (append_insn): Don't do r3900 interlock
+ optimization for -mtune=r3900, as this will break on other CPUs.
+
+2004-01-11 Tom Rix <tcrix@worldnet.att.net>
+
+ * config/tc-m68hc11.c (build_indexed_byte): movb and movw cannot
+ be relaxed, use fixup.
+ (md_apply_fix3): Use 5 bit reloc from movb and movw fixup.
+
+2004-01-19 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-sparc.c (sparc_ip): Disallow %f32-%f63 for single
+ precision operands.
+
+2004-01-14 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * config/tc-mips.c (append_insn): Properly detect variant frags
+ that preclude swapping of relaxed branches. Correctly swap
+ instructions between frags when dealing with relaxed branches.
+
+2004-01-14 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * acinclude.m4: Quote names of macros to be defined by AC_DEFUN
+ throughout.
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+
+2004-01-12 Anil Paranjpe <anilp1@KPITCummins.com>
+
+ * config/tc-h8300.c (build_bytes): Apply relaxation to bit
+ manipulation insns.
+
+2004-01-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (macro_build_jalr): When adding an R_MIPS_JALR
+ reloc, reserve space for the delay slot as well as the jalr itself.
+
+2004-01-09 Paul Brook <paul@codesourcery.com>
+
+ * config/tc-arm.c (do_vfp_reg2_from_sp2): Rename from do_vfp_sp_reg2.
+ (do_vfp_sp2_from_reg2): New function.
+ (insns): Use them.
+ (do_vfp_dp_from_reg2): Check return values properly.
+
+2004-01-08 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * config/tc-mips.c (warn_nops): Remove static variable.
+ (macro): Remove test of warn_nops.
+ (md_shortops): Remove 'n'.
+ (md_parse_option): Remove 'n' case.
+ (md_show_usage): Remove -n.
+ * doc/as.texinfo (Overview): Remove MIPS -n option.
+ * doc/c-mips.texi (MIPS Opts): Remove mention -n.
+ * NEWS: Mention removal of MIPS -n option.
+
+ * config/tc-mips.c (ISA_HAS_COPROC_DELAYS): Remove.
+ (cop_interlocks): Check ISA level.
+ (cop_mem_interlocks): Define.
+ (reg_needs_delay): Check cop_interlocks rather than
+ ISA_HAS_COPROC_DELAYS.
+ (append_insn): Likewise. Use cop_mem_interlocks rather than
+ directly checking mips_opts.isa.
+ (mips_emit_delays): Likewise.
+
+2004-01-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/tc-ia64.c (unwind): Move next_slot_number and
+ next_slot_frag to ...
+ (unw_rec_list): Here.
+ (free_list_records): Removed.
+ (output_unw_records): Likewise.
+ (generate_unwind_image): Make it void.
+ (alloc_record): Initialize next_slot_number and next_slot_frag.
+ (slot_index): Take .org, .space and .align into account.
+ (fixup_unw_records): Don't set slot_number to 0. Use
+ list->next_slot_number and list->next_slot_frag instead of
+ unwind.next_slot_number and unwind.next_slot_frag.
+ (ia64_convert_frag): New.
+ (generate_unwind_image): Generate a rs_machine_dependent frag
+ for unwind record.
+ (emit_one_bundle): Use list->next_slot_number and
+ list->next_slot_frag instead of unwind.next_slot_number and
+ unwind.next_slot_frag.
+
+ * config/tc-ia64.h (md_convert_frag): Defined as
+ ia64_convert_frag.
+ (md_estimate_size_before_relax): Defined as (f)->fr_var.
+
+2004-01-06 Alexandre Oliva <aoliva@redhat.com>
+
+ 2003-12-19 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-frv.h (md_apply_fix3): Don't define.
+ * config/tc-frv.c (md_apply_fix3): New. Shift/truncate %hi/%lo
+ operands.
+ * config/tc-frv.h (TC_FORCE_RELOCATION_SUB_LOCAL): Define.
+ 2003-10-07 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-frv.c (line_separator_chars): Add `!'.
+ 2003-09-19 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-frv.c (md_assemble): Clear insn upfront.
+ 2003-09-18 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-frv.c (OPTION_FDPIC): New macro.
+ (md_longopts): Add mfdpic.
+ (md_parse_option): Handle it.
+ 2003-08-04 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-frv.c (md_cgen_lookup_reloc) <FRV_OPERAND_D12,
+ FRV_OPERAND_S12>: Use reloc type encoded in fix-up.
+ (frv_pic_ptr): Parse funcdesc.
+
+2004-01-05 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * doc/as.texinfo: Let texi2pod parse asconfig.texi and
+ gasver.texi. Remove duplicate symbol definitions for texi2pod.
+
+2004-01-05 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * Makefile.am (Makefile): Move the dependency on
+ $(BFDDIR)/configure.in to...
+ (CONFIG_STATUS_DEPENDENCIES): ... here.
+ (AUTOMAKE_OPTIONS): Require automake 1.8.
+ * Makefile.in: Regenerate.
+ * doc/Makefile.am (BASEDIR, BFDDIR): Define.
+ (CONFIG_STATUS_DEPENDENCIES): Add a dependency on
+ $(BFDDIR)/configure.in here as well.
+ * doc/Makefile.in: Regenerate.
+
+2004-01-05 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * Makefile.am (install, install-info, RECURSIVE_TARGETS): Remove.
+ * Makefile.in: Regenerate.
+ * aclocal.m4: Regenerate.
+ * doc/Makefile.am (install, install-info): Remove.
+ (install-data-local): A new hook for install-info.
+ (AUTOMAKE_OPTIONS): Require automake 1.8.
+ * doc/Makefile.in: Regenerate.
+
+2004-01-02 Nutan Singh <nutan@kpitcummins.com>
+
+ * doc/c-sh.texi: Update description about floating point behavior
+ of SH family.
+
+2004-01-02 Bernardo Innocenti <bernie@develer.com>
+
+ * configure.in: Add m68k-uClinux target.
+ * configure: Regenerate.
+
+For older changes see ChangeLog-0203
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/x/binutils/gas/ChangeLog-0001 b/x/binutils/gas/ChangeLog-0001
new file mode 100644
index 0000000..9d8af6f
--- /dev/null
+++ b/x/binutils/gas/ChangeLog-0001
@@ -0,0 +1,7703 @@
+2001-12-31 Richard Henderson <rth@redhat.com>
+
+ * config/tc-ia64.c (errata_nop_necessary_p): Prototype.
+ (make_unw_section_name): Constify local variables.
+
+ * config/tc-ia64.c (has_suffix_p): New.
+ (note_register_values): Use it instead of strstr.
+
+2001-12-31 Jeffrey A Law (law@redhat.com)
+
+ * config/tc-hppa.c (pa_ip): Handle new 'c' mode completers,
+ 'X', 'M', and 'A'.
+
+2001-12-21 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-sparc.h (TC_PARSE_CONS_EXPRESSION): Define.
+ (sparc_cons): Provide prototype.
+ * config/tc-sparc.c (tc_gen_reloc): Handle BFD_RELOC_*_PCREL and
+ BFD_RELOC_SPARC_PLT{32,64}. Enumerate for which relocs
+ reloc->addend = fixp->fx_addnumber shouldn't be done instead of
+ enumarating for which pc relative ones it should be done.
+ (sparc_cons_special_reloc): New variable.
+ (sparc_cons): New function.
+ (cons_fix_new_sparc): Use sparc_cons_special_reloc.
+ * testsuite/gas/sparc/pcrel.s: New test.
+ * testsuite/gas/sparc/pcrel.d: Expected output.
+ * testsuite/gas/sparc/pcrel64.s: New test.
+ * testsuite/gas/sparc/pcrel64.d: Expected output.
+ * testsuite/gas/sparc/plt.s: New test.
+ * testsuite/gas/sparc/plt.d: Expected output.
+ * testsuite/gas/sparc/plt64.s: New test.
+ * testsuite/gas/sparc/plt64.d: Expected output.
+ * testsuite/gas/sparc/sparc.exp: Add pcrel, pcrel64, plt and plt64
+ tests.
+
+2001-12-20 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+ Daniel Jacobowitz <drow@mvista.com>
+
+ * config/tc-mips.c (file_mips_gp32): Initialize to invalid value.
+ (file_mips_fp32): Likewise.
+ (md_begin): Compatibility handling for -mipsN option.
+
+2001-12-20 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-sh.c (parse_at): Reject @(r0) and @(r0,).
+
+2001-12-20 matthew green <mrg@redhat.com>
+
+ * config/tc-ppc.c (md_parse_option): Make -maltivec default
+ to generating PowerPC instructions.
+
+2001-12-20 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * configure.in (mips-dec-netbsd*): Delete.
+ * configure: Regenerate.
+
+ * configure.in (arm-*-netbsdelf*): Add target.
+ * configure: Regenerate.
+
+2001-12-18 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-mips.h (TC_HANDLE_FX_DONE): Remove redundant
+ definition.
+
+2001-12-18 Niibe Yutaka <gniibe@m17n.org>
+
+ * configure.in (assign object format): Bug fix for setting
+ endian.
+ * configure: Regenerate.
+
+2001-12-18 matthew green <mrg@eterna.com.au>
+
+ * configure.in (m68k-*-netbsdelf*): New target.
+ (m68k-*-netbsd*): Also include ELF support.
+ (m68k-*-netbsdaout*): New alias for m68*-*-netbsd*.
+ * configure: Regenerate.
+
+2001-12-18 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * gasp.c (main): Protoype.
+
+2001-12-17 Richard Henderson <rth@redhat.com>
+
+ * config/tc-alpha.c (alpha_handle_align): Encode unop with RB as $sp.
+
+2001-12-17 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * cgen.c: Add prototype for queue_fixup.
+ (gas_cgen_parse_operand): Move initilisastion of errmsg to avoid
+ possible longjmp corruption.
+ * cgen.h: Add prototype for gas_cgen_md_operand.
+
+2001-12-15 Alan Modra <amodra@bigpond.net.au>
+
+ * config/obj-elf.c (obj_elf_init_stab_section): References are
+ kept to section name strings. Don't alloca them!
+
+2001-12-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-d10v.c (get_operands): Mark OPERAND_PLUS after
+ OPERAND_ATSIGN as O_absent.
+
+2001-12-07 Geoffrey Keating <geoffk@redhat.com>
+ Richard Henderson <rth@redhat.com>
+
+ * configure.in: Add support for xstormy16.
+ * configure: Regenerated.
+ * Makefile.am: Add support for xstormy16.
+ * Makefile.in: Regenerated.
+ * config/tc-xstormy16.c: New file.
+ * config/tc-xstormy16.h: New file.
+
+2001-12-06 Richard Earnshaw (rearnsha@arm.com)
+
+ * tc-arm.c (do_arit, do_cmp, do_mov, do_ldst, do_ldstt, do_ldmstm)
+ (do_branch, do_swi, do_adr, do_adrl, do_empty, do_mul, do_mla)
+ (do_swap, do_msr, do_mrs, do_mull, do_ldstv4, do_bx, do_blx)
+ (do_bkpt, do_clz, do_lstc2, do_cdp2, do_co_reg2, do_smla, do_smlal)
+ (do_smul, do_qadd, do_pld, do_ldrd, do_co_reg2c, do_cdp, do_lstc)
+ (do_co_reg, do_fpa_ctrl, do_fpa_ldst, do_fpa_ldmstm, do_fpa_monadic)
+ (do_fpa_dyadic, do_fpa_cmp, do_fpa_from_reg, do_fpa_to_reg, do_mia)
+ (do_mar, do_mra, do_c_binops, do_c_binops_1, do_c_binops_2)
+ (do_c_binops_3, do_c_triple, do_c_triple_4, do_c_triple_5, do_c_quad)
+ (do_c_quad_6, do_c_dspsc, do_c_dspsc_1, do_c_dspsc_2, do_c_shift)
+ (do_c_shift_1, do_c_shift_2, do_c_ldst, do_c_ldst_1, do_c_ldst_2)
+ (do_c_ldst_3, do_c_ldst_4, do_branch25): Delete redundant argument,
+ FLAGS.
+ (struct asm_opcode): Adjust parms field accordingly.
+ (md_assemble): Don't pass dummy second argument when calling worker
+ functions.
+ (build_arm_ops_hsh): Add prototype
+ (BAD_FLAGS): Delete.
+
+2001-12-05 Richard Earnshaw <rearnsha@arm.com>
+
+ * tc-arm.c (struct asm_opcode): Delete comp_suffix and flags. Add
+ cond_offset. Rename variants->variant.
+ (insns): Adjust for new format. Explicitly code each variant that
+ takes flags. Remove temporary instructions.
+ (struct arm_it): Remove redundant field suffix.
+ (s_flag, ldr_flags, str_flags, byte_flag, cmp_flags, ldm_flags)
+ (stm_flags, lfm_flags, sfm_flags, round_flags, fix_flags, except_flag)
+ (long_flag): Delete.
+ (struct asm_flg): Delete.
+ (LONGEST_INST): Delete.
+ (V4_STR_BIT): Define.
+ (struct thumb_opcode): Rename variants->variant.
+ (do_empty): Renamed from do_nop.
+ (ldst_extend): Delete argument hwse. Split code for half-word and
+ signed byte instructions to ...
+ (ldst_extend_v4): ... here.
+ (ld_mode_required_here): Use ldst_extend_v4.
+ (do_ldrd): Simplify now that this is only called for ldrd. No
+ need to test for XScale, which was wrong anyway. Don't reject r12
+ as a target register. Add test that ldrd doesn't update an index
+ register.
+ (do_pld): Don't allow post-indexed or write-back addressing modes.
+ Adjust call to ldst_extend.
+ (do_adr): Split code for adrl to ...
+ (do_adrl): ... here.
+ (do_cmp): No need to fold in COND_BIT.
+ (do_ldst): Simplify. Split code for ldrt/strt into do_ldstt. Split
+ code to handle half-word and signed byte instructions to ...
+ (do_ldstv4): ... here.
+ (do_ldstt): New function. Handle load/store with translate.
+ (do_ldmstm): Write feature modification bits directly into
+ inst.instruction.
+ (do_fpa_ldst): Remove suffix handling code.
+ (do_fpa_dyadic, do_fpa_monadic, do_fpa_from_reg): Likewise.
+ (do_fpa_ldmstm): Type of access is now held in inst.instruction.
+ (build_arm_ops_hsh): New function.
+ (md_begin): Call it. Don't build the ARM opcode directly.
+ (md_assemble): Simplify ARM instruction handling.
+
+2001-12-05 Arati Dikey <aratid@kpit.com>
+
+ * tc-sh.c (parse_at): Corrected incorrect op->type selection due
+ to missing 'else'.
+
+2001-12-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-d10v.c (write_2_short): Don't skip dummy fixups, so
+ that we can tell which operand refers to the insn put in the L
+ container and mark it as such, so that the relocation type can be
+ adjusted.
+
+2001-12-04 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips_cpreturn_offset): Better comment.
+ (load_register): Better error message. Cast away signedness
+ mismatches. Add casts needed for varargs.
+ (load_address): Replace checks of HAVE_64BIT_ADDRESS with dbl.
+ Remove superfluous casts.
+ (macro): Cast away signedness mismatches. Remove superfluous casts.
+ (s_cpload): Fix wrong comment.
+ (s_mips_weakext): Standardize output message.
+ (get_number): Likewise.
+
+2001-12-04 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (append_insn): Add jump address range overflow
+ check.
+
+2001-12-04 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (md_parse_option): Fix comment. Allow -mabi option
+ for ELF only.
+ (show): Document -mabi option.
+
+2001-12-03 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
+
+ * config/tc-arm.c (md_parse_option): Only clear cpu part when
+ specifying 'xscale' cpu (don't change the fpu part).
+
+2001-12-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-d10v.c (find_opcode): Reject SP operand if
+ OPERAND_NOSP flag is present.
+
+2001-12-03 Eric Christopher <echristo@redhat.com>
+
+ * config/tc-mips.c (tc_gen_reloc): One missed BFD_RELOC_MIPS_GPREL.
+
+2001-12-02 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (macro_build): Replace BFD_RELOC_MIPS_GPREL
+ by BFD_RELOC_GPREL16.
+ (load_address): Likewise.
+ (macro): Likewise.
+ (md_apply_fix): Likewise. Replace BFD_RELOC_MIPS_GPREL32 by
+ BFD_RELOC_GPREL32.
+ (s_gpword): Replace BFD_RELOC_MIPS_GPREL32 by BFD_RELOC_GPREL32.
+ (tc_gen_reloc): Replace BFD_RELOC_MIPS_GPREL by BFD_RELOC_GPREL16.
+ *config/tc-mips.h: Replace BFD_RELOC_MIPS_GPREL by BFD_RELOC_GPREL16.
+
+2001-11-29 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-d10v.c (get_operands): Emit OPERAND_PLUS for
+ prefix `+'.
+
+ * config/tc-d10v.c (find_opcode): Reject non-SP operand if
+ flags requires SP.
+
+2001-11-29 Arati Dikey <aratid@kpit.com>
+
+ * tc-sh.c (parse_at): Removed case-sensitivity of index register
+ R8, R9.
+
+2001-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ * write.c (adjust_reloc_syms): Mark SEC_MERGE symbols as used
+ in reloc if it has non-zero addend.
+ * config/tc-alpha.c (tc_gen_reloc): Reinstall SEC_MERGE check.
+ * config/tc-sparc.c (md_apply_fix3): Likewise.
+
+2001-11-28 Andreas Schwab <schwab@suse.de>
+
+ * as.c (parse_args): Call md_after_parse_args if defined.
+ * config/tc-ia64.h (md_after_parse_args): Define.
+ * config/tc-ia64.c (ia64_after_parse_args): Reject --gstabs.
+ * doc/internals.texi (CPU backend): Document md_after_parse_args.
+
+2001-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-alpha.c (tc_gen_reloc): Remove SEC_MERGE test.
+ * write.c (adjust_reloc_syms): Don't handle relocs against
+ SEC_MERGE section symbols specially.
+ (fixup_segment): Likewise.
+
+2001-11-21 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (mips_need_elf_addend_fixup): New, extracted from...
+ (md_apply_fix3): ...here. Don't prevent the symbol value being
+ subtracted twice from GPREL addends.
+ (tc_gen_reloc): Add the symbol value to a GPREL addend if it was
+ subtracted by the previous function.
+
+2001-11-20 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-avr.c (md_apply_fix3): Fix typo introduced by
+ md_apply_fix3 change.
+
+2001-11-20 Ben Elliston <bje@redhat.com>
+
+ * config/tc-m88k.c (md_apply_fix3): Match local variable `val' to
+ usage after md_apply_fix3 cleanups.
+
+2001-11-19 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * doc/c-mmix.texi: Use texinfo 4 features.
+ (MMIX-mmixal): Fix typo.
+
+2001-11-17 Hans-Peter Nilsson <hp@axis.com>
+
+ * config/tc-cris.c (md_apply_fix3): Cast value, not pointer, in
+ val assignment.
+
+2001-11-16 Michael Snyder <msnyder@redhat.com>
+
+ * stabs.c (stabs_generate_asm_lineno): Remember file and line number
+ from one call to the next, and eliminate consecutive duplicates
+ (thereby emitting only one line symbol per source line).
+ * dwarf2dbg.c (dwarf2_gen_line_info): Ditto.
+
+2001-11-16 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-m68k.c (md_apply_fix3): Change val back to a signed type.
+
+2001-11-15 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-hppa.c (md_apply_fix3): Fix a typo.
+
+2001-11-15 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-alpha.c (md_apply_fix3): Fix a typo.
+
+2001-11-15 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * write.c (fixup_segment): Remove references to md_apply_fix and
+ TC_HANDLE_FX_DONE.
+ * cgen.c, config/obj-coff.c, config/tc-*.c: Update all occurances
+ of md_apply_fix to md_apply_fix3.
+ Make all md_apply_fix3 functions void.
+ * cgen.h, config/obj-coff.h, tc-*.h: Remove all definitions of
+ MD_APPLY_FIX3 and TC_HANDLE_FX_DONE.
+ * doc/internals.texi: Update references to md_apply_fix3.
+ * tc.h: Update prototype for md_apply_fix3.
+
+2001-11-15 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.h (md_end): Define.
+ (i386_elf_emit_arch_note): Declare.
+ (CpuUnknown): Delete.
+ * config/tc-i386.c (default_arch): Constify.
+ (smallest_imm_type): Remove CpuUnknown test.
+ (md_assemble): Don't bother checking cpu_arch_flags non-zero.
+ (i386_elf_emit_arch_note): New function.
+
+ * po/POTFILES.in: Regenerate.
+
+2001-11-15 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips_ip): Re-allow %hi() op for non-ELF assembler.
+
+2001-11-15 Alan Modra <amodra@bigpond.net.au>
+
+ * frags.c (frag_grow): Revert last change.
+
+ * dwarf2dbg.c (get_frag_fix): Align last frag size.
+
+ * config/tc-ppc.c (ppc_insert_operand): Pass (ppc_cpu | ppc_size)
+ to operand->insert.
+ (md_assemble): Likewise.
+
+2001-11-12 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * frags.c (frag_grow): Use frag_make_room() to grow the
+ obstack.
+
+2001-11-14 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-sparc.c (md_apply_fix3): Do not remove the symbol's
+ value from the addend for fixups against local symbols in
+ SEC_MERGE sections - it was not added in, in the first place.
+
+2001-11-11 Timothy Wall <twall@alum.mit.edu>
+
+ * write.c (relax_segment): Convert symbol address into an octet
+ offset prior to adding to the frag address, which is an octet
+ offset. Add comments to that effect.
+ * config/tc-tic54x.c: Fix bugs causing tests to fail.
+ * config/tc-tic54x.h: Ditch PARAMS macro.
+
+2001-11-13 Alan Modra <amodra@bigpond.net.au>
+
+ * config/obj-elf.c (obj_elf_version): Ensure terminating NUL is
+ put in note section. Use sizeof instead of hard-coded constants.
+
+2001-11-12 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (support_64bit_objects): Define for OBJ_ELF only.
+ (md_longopts): Allow OPTION_MABI for ELF compilation only. RE-allow
+ OPTION_GP32, OPTION_GP64, OPTION_FP32 for non-ELF compilation.
+ Sort options a bit more logical.
+ (md_parse_option): Allow OPTION_32, OPTION_N32, OPTION_N64,
+ OPTION_MABI only for elf targets.
+
+2001-11-12 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (set_at): Add cast needed for varargs.
+ (load_register): Likewise.
+ (macro): Likewise. Some code reformatting.
+ (macro2): Add cast needed for varargs.
+ (mips16_macro): Likewise.
+
+2001-11-12 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (md_assemble): Remove superflous casts.
+ (append_insn): Likewise.
+ (mips16_macro_build): Likewise.
+ (macro): Likewise.
+ (mips16_ip): Likewise.
+ (s_cpload): Likewise.
+ (mips_relax_frag): Likewise.
+
+2001-11-12 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips_abi_level): Move in front of
+ mips_set_options.
+ (mips_set_options): Add members gp32, fp32, abi.
+ (file_mips_gp32): New flag.
+ (file_mips_fp32): New flag.
+ (mips_opts): Initialize the new members.
+ (mips_gp32): Remove.
+ (mips_fp32): Remove.
+ (HAVE_32BIT_GPRS): Use the new values from mips_opts.
+ (HAVE_32BIT_FPRS): Likewise.
+ (HAVE_NEWABI): Likewise.
+ (HAVE_64BIT_OBJECTS): Likewise.
+ (md_begin): Likewise. Save default (file) values.
+ (md_parse_option): Use the new values from mips_opts.
+ (s_mipsset): Likewise. Fix logic to keep the ABI selection if
+ possible. Let .set mipsN work together with .set push/pop.
+ Enhance error messages.
+ (mips_elf_final_processing): Use file_mips_* for header processing.
+
+2001-11-09 Marek Michalkiewicz <marekm@amelek.gda.pl>
+
+ * config/tc-avr.c (mcu_types): Update for new devices.
+
+2001-11-09 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * doc/Makefile.am (POD2MAN): Use 'GNU Development Tools' for
+ the page man title.
+ * doc/Makefile.in: Rebuild.
+ * doc/as.texinfo: Do not put man SEEALSO in document;
+ Use @command for commands, @option for options; Reorganize usage
+ to clearly identify target specific options.
+
+2001-11-08 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips_force_relocation): Remove duplicate code.
+
+2001-11-06 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (my_getSmallParser): Fix small parser bug.
+
+2001-11-05 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.c (tc_s390_force_relocation): Force all relocations
+ that need the global offset table.
+ (md_apply_fix3): Add code to undo opertions done in fixup_segment
+ triggered by TC_FORCE_RELOCATION.
+ * config/tc-s390.h (TC_FORCE_RELOCATION): Replace macro code with
+ a call to function tc_s390_force_relocation.
+ (TC_FIX_ADJUSTABLE): Define.
+
+2001-11-04 Chris Demetriou <cgd@broadcom.com>
+
+ * configure.in (mips-*-netbsd*): Add support for target.
+ * configure: Regenerate.
+
+2001-11-02 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * configure.in (ALL_LINGUAS): Add 'fr'.
+ * configure: Regernate.
+ * po/fr.po: New file. Obtained from the translation project web
+ site.
+
+2001-11-02 Richard Earnshaw <rearnsha@arm.com>
+
+ * tc-arm.c: Re-arrange prototypes by architecture.
+ (insns): Re-arrange instructions by archtitecture. Pld instruction
+ is part of ARMv5E.
+ (tinsns): blx and bkpt are part of ARMv5T.
+ (do_fp_{ctrl,ldst,ldstm,dyadic,monadic,cmp,from_reg,to_reg}): Rename
+ to do_fpa_*. All callers changed.
+
+ * tc-arm.c (insns): Add two temporary instructions to handle
+ ldrd/strd.
+
+2001-11-01 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * config/tc-m68hc11.c (build_jump_insn): Allocate worst case storage
+ for bra/bsr and use frag_variant(), this ensure that the possible
+ 16-bit BFD_RELOC_16 will be in the same frag.
+
+2001-10-31 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (HAVE_32BIT_ADDRESSES): If compiling embedded
+ PIC code, assume pointers the same size as GPRs.
+ (macro): In M_LA_AB handling for embedded PIC code, support
+ "la $treg,foo-bar($breg)". In load/store handling
+ (label ld_st) support "<op> $treg,<sym>-<local_sym>($breg)"
+ which is used by the compiler for switch statements.
+ In load/store double multi-instruction macro handling
+ (label ldd_std) add a comment that no special handling
+ is currently done for embedded PIC.
+ (mips_ip): In 'o' (16-bit offset) case, only accept 16
+ bit offsets.
+
+2001-10-31 Richard Earnshaw <rearnsha@arm.com>
+
+ General cleanup of feature definitions.
+ * tc-arm.c (ARM_EXT_LONGMUL, ARM_EXT_HALFWORD, ARM_EXT_THUMB): Delete.
+ (ARM_2UP, ARM_ALL, ARM_3UP, ARM_6UP): Delete.
+ (FPU_CORE, FPU_FPA10, FPA_FPA11, FPU_ALL, FPA_MEMMULTI): Delete.
+ (ARM_EXT_V{1,2,2S,3,3M,4,4T,5T,5ExP}): New defines.
+ (ARM_EXT_V{5,5E}): Synchronize with above.
+ (ARM_ARCH_V*): Define a complete set in terms of above features.
+ (ARM_{1,2,3,250,6,7,8,9,STRONG}): Define in terms of architecture.
+ (FPU_FPA_EXT_V[12]): Define.
+ (FPU_ARCH_FPE, FPU_ARCH_FPA): Define in terms of above.
+ (FPU_ANY): Define.
+ (FPU_DEFAULT): Default to FPA.
+ (CPU_DEFAULT): For XScale, this is now just ARM_ARCH_XSCALE; for
+ Thumb, this is now ARM_ARCH_V5T.
+ (insns): Rework for new feature defines.
+ (tinsns): Likewise.
+ (opcode_select, do_ldst, md_begin, md_parse_option): Likewise.
+
+2001-10-31 NIIBE Yutaka <gniibe@m17n.org>
+
+ * configure.in: Handle sh*eb-*-linux* and sh*-*-linux*.
+ * configure: Regenerate.
+ * Makefile.in: Regenerate.
+ * doc/c-sh.texi (SH Options): Added descriptions.
+
+2001-10-30 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * configure.in: Update for MMIX port.
+ * Makefile.am: Ditto. Regenerate dependencies.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * config/tc-mmix.h, config/tc-mmix.c: New files.
+ * doc/Makefile.am (CPU_DOCS): Add c-mmix.texi
+ * doc/Makefile.in: Regenerate.
+ * doc/all.texi: @set MMIX.
+ * doc/as.texinfo: Ditto. Add MMIX gas manpage option overview.
+ Include c-mmix.texi.
+ * doc/c-mmix.texi: New file.
+
+2001-10-24 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (hilo_interlocks, cop_interlocks): Make
+ these evaluate to true if mips_arch indicates SB-1.
+
+2001-10-23 Alan Modra <amodra@bigpond.net.au>
+
+ * as.c (parse_args): Print the date as well for --version.
+
+2001-10-20 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (md_show_usage): Print "sb1" for Broadcom
+ SB-1 CPU for consistency.
+ (mips_cpu_info_table): Tweak comment about SB-1.
+
+2001-10-20 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-arm.c (do_c_shift): Use ISDIGIT instead of isdigit.
+ (cirrus_parse_offset): Likewise.
+
+2001-10-19 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-arm.c: Restore line_comment_chars.
+
+2001-10-18 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-arm.c (comment_chars): Remove semi-colon accidentally
+ added to the list.
+
+2001-10-18 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * write.c (fixup_segment): Handle fixups for SEC_MERGE sections as
+ for undefined symbols.
+
+2001-10-17 Chris Demetriou <cgd@broadcom.com>
+
+ * doc/as.texinfo (MIPS ISA options): Added accidentally
+ omitted "-mips64" option to list of options.
+
+2001-10-17 matthew green <mrg@redhat.com>
+
+ * config/tc-ppc.c (md_show_usage): Add missing -maltivec, -m7400,
+ -m7410, -m7450 and -m7455 options.
+
+2001-10-17 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (PPC_HA, PPC_HIGHERA, PPC_HIGHESTA): Simplify.
+ (ppc_size): Select PPC_OPCODE_64 if 64 bit.
+ (md_begin): Don't set ppc_size here.
+ (ppc_target_format): Test ppc_size as well as BFD_DEFAULT_TARGET_SIZE.
+ (md_shortopts): Constify.
+ (md_longopts): Likewise.
+ (md_longopts_size): Likewise.
+ (ppc_elf_suffix): Only allow 64-bit relocs when ppc_size specifies
+ 64-bit opcodes.
+ (ppc_machine): Explain why this function is a nop.
+
+2001-10-17 Alan Modra <amodra@bigpond.net.au>
+
+ * bit_fix.h: Comment typo fix.
+ * config/tc-mips.c: Likewise.
+ * config/tc-sh.c: Likewise.
+ * config/tc-arc.c (arc_code_symbol): Remove unnecessary test.
+
+ * configure.in (MIPS_STABS_ELF): AC_DEFINE in only one place so
+ that autoheader doesn't duplicate config.in entries.
+ (DEFAULT_ARCH): Ditto.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+
+2001-10-16 Alan Modra <amodra@bigpond.net.au>
+
+ From Andrew Pines <apines@cosmodog.com>
+ * config/tc-m68k.c (m68k_ip): Correct absolute jmp opcodes.
+
+2001-10-16 NIIBE Yutaka <gniibe@m17n.org>,
+ Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/tc-sh.c (shl): Remove.
+ (big): New function.
+ (little): Remove shl handling. Emit error for endian mismatch.
+ (md_show_usage): Add description of -big.
+ (md_parse_option): Handle OPTION_BIG. Remove shl handling.
+ (OPTION_BIG): Add.
+ (md_pseudo_table): Add .big.
+ (md_longopts): Add -big.
+ (md_begin): Don't set target_big_endian here.
+ * config/tc-sh.h (TARGET_BYTES_BIG_ENDIAN): Remove.
+ (LISTING_HEADER, COFF_MAGIC, TARGET_FORMAT): Use target_big_endian.
+ (shl): Remove.
+ * configure.in (endian): Default is big.
+ (sh-*-pe*): Little endian.
+ (cpu_type): Set sh for target sh*.
+ * configure: Regenerate.
+
+2001-10-15 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (md_apply_fix): Preliminary handling of NewABI
+ relocations.
+
+2001-10-13 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-arm.c: Replace CONST with const.
+
+ * cgen.c: Tidy up formatting.
+
+2001-10-12 matthew green <mrg@redhat.com>
+
+ * config/tc-ppc.c (md_parse_option): New -m7410, -m7450 and -m7455
+ flags, equivalent to -m7400. New -maltivec to enable AltiVec
+ instructions. New -mbook64 and -mbooke/-mbooke32 flags to enable
+ 64-bit and 32-bit BookE support, respectively. Change -m403 and
+ -m405 to set PPC403 option.
+ (md_show_usage): Adjust for new options.
+ * doc/all.texi: Set PPC.
+ * doc/as.texinfo: Add PPC support and pull in c-ppc.texi.
+ * doc/c-ppc.texi: New file.
+ * doc/Makefile.am (CPU_DOCS): Add c-ppc.texi.
+ * doc/Makefile.in: Regenerate.
+
+2001-10-12 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * read.c (s_bad_endr): New function. Issues a warning message
+ about a bad use of the .rept pseudo op.
+ (po_table[]): Add .endr.
+ * read.h: Prototype s_bad_endr.
+
+ * CONTRIBUTORS: Update contact email address.
+
+2001-10-11 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-alpha.c: Fix comment typos.
+ * config/tc-cris.c: Likewise.
+ * config/tc-hppa.c: Likewise.
+ * config/tc-i370.c: Likewise.
+ * config/tc-mips.c: Likewise.
+ * config/tc-mn10200.c: Likewise.
+ * config/tc-mn10300.c: Likewise.
+ * config/tc-sh.c: Likewise.
+ * config/tc-tahoe.c: Likewise.
+ * config/tc-v850.c: Likewise.
+
+2001-10-11 Kazu Hirata <kazu@hxi.com>
+
+ * app.c: Fix comment typos.
+ * bit_fix.h: Likewise.
+ * expr.c: Likewise.
+ * itbl-ops.c: Likewise.
+
+2001-10-11 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * input-file.c: Include safe-ctype.h.
+ (input_file_open): Use ISSPACE instead of isspace.
+
+2001-10-10 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips_cpreturn_offset): New variable.
+ (mips_cpreturn_register): Likewise.
+ (mips_gp_register): Likewise.
+ (s_cpsetup): New function prototype.
+ (s_cplocal): Likewise.
+ (s_cpreturn): Likewise.
+ (s_gpvalue): Likewise.
+ (mips_pseudo_table): Add .cpsetup, .cplocal, .cpreturn, .gpvalue
+ pseudo-ops.
+ (macro): Don't warn about .cprestore for NewABI.
+ (md_pcrel_from): Code cleanup.
+ (mips_force_relocation): Force output of some NewABI relocations even
+ without a defined symbol.
+ (s_cpload): Ignore .cpload for NewABI.
+ (s_cpsetup): Handle .cpsetup.
+ (s_cplocal): Handle .cplocal.
+ (s_cprestore): Ignore .cprestore for NewABI.
+ (s_cpreturn): Handle .cpreturn.
+ (s_gpvalue): Handle .gpvalue.
+ (s_cpadd): Ignore .cpadd for NewABI.
+ (nopic_need_relax): Take g_switch_value into account as gp
+ optimization.
+ (tc_gen_reloc): Don't handle BFD_RELOC_MIPS_{CALL,GOT}* for NewABI.
+
+2001-10-10 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (my_getSmallParser): New function prototype.
+ (small_ex_type): Named this enum, more return values for
+ my_getSmallExpression.
+ (mips_ip): Allow SPC and HT between arguments. Handle some NewABI
+ triple relocations. Protect some parts with ifdef OBJ_ELF.
+ (percent_op_match): New struct, lookup table for %some_reloc().
+ (my_getSmallParser): New function, parses nested percent_ops also.
+ (my_getSmallExpression): Rewite to support nested percent_ops.
+
+2001-10-10 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c
+ (load_address): Support both 32- and 64-bit addresses.
+ (macro): Call load_register correctly. Expand 64-bit loads ans stores.
+ (macro2): Call load_address correctly.
+
+2001-10-09 Christian Groessler <cpg@aladdin.de>
+
+ * config/tc-z8k.c: Include opcodes/z8k-opc.h after bfd.h
+ since z8k-opc.h now uses the PARAMS macro.
+
+2001-10-09 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/tc-arm.c: Change MAVERIK to MAVERICK.
+
+2001-10-09 Alan Modra <amodra@bigpond.net.au>
+
+ * config/obj-elf.c: Make use of elf_group_name and elf_next_in_group
+ throughout file.
+ (obj_elf_change_section): Rename "group" to "group_name".
+ (obj_elf_section): Likewise.
+ (elf_frob_file): Don't use sec->lineno for SHT_GROUP section to store
+ first member section; Instead use elf_next_in_group.
+
+2001-10-09 Alan Modra <amodra@bigpond.net.au>
+
+ * config/obj-elf.c: (obj_elf_change_section): Add "group" param.
+ Set elf_section_data group from it. Warn if group name changed.
+ (obj_elf_parse_section_letters): Parse 'G' too.
+ (obj_elf_section): Parse group name.
+ (struct group_list): New.
+ (build_group_lists): New function.
+ (elf_frob_file): Create SEC_GROUP section(s).
+
+ * config/obj-elf.c: (elf_copy_symbol_attributes): Zap trailing
+ whitespace.
+
+2001-10-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * doc/arm/c-arm.texi (ARM Options): Add arm9e documentation.
+
+ * config/tc-arm.c (ARM_EXT_MAVERIK): New macro.
+ (cirrus_regtype): New enum.
+ (LONGEST_INST): Change to 10.
+ (CIRRUS_MODE1): New.
+ (CIRRUS_MODE2): New.
+ (CIRRUS_MODE3): New.
+ (CIRRUS_MODE4): New.
+ (CIRRUS_MODE5): New.
+ (CIRRUS_MODE6): New.
+ (insns): Add cirrus dsp instructions.
+ (ARM_EXT_MAVERIKSC_REG): New.
+ (cirrus_register): New.
+ (cirrus_mvf_register): New.
+ (cirrus_mvd_register): New.
+ (cirrus_mvfx_register): New.
+ (cirrus_mvdx_register): New.
+ (cirrus_mvax_register): New.
+ (ARM_EXT_MAVERIKsc_register): New.
+ (reg_table): Add cirrus registers.
+ (cirrus_valid_reg): New.
+ (cirrus_reg_required_here): New.
+ (do_c_binops_1): New.
+ (do_c_binops_2): New.
+ (do_c_binops_3): New.
+ (do_c_triple_4): New.
+ (do_c_triple_5): New.
+ (do_c_quad_6): New.
+ (do_c_dspsc_1): New.
+ (do_c_dspsc_2): New.
+ (do_c_shift_1): New.
+ (do_c_shift_2): New.
+ (do_c_ldst_1): New.
+ (do_c_ldst_2): New.
+ (do_c_ldst_3): New.
+ (do_c_ldst_4): New.
+ (do_c_binops): New.
+ (do_c_triple): New.
+ (do_c_quad): New.
+ (do_c_dspsc): New.
+ (do_c_shift): New.
+ (cirrus_parse_offset): New.
+ (do_c_ldst): New.
+ (md_parse_option): Add arm9e.
+ (md_show_usage): Same.
+
+2001-10-08 Tom Rix <trix@redhat.com>
+
+ * config/tc-ppc (ppc_bf, ppc_biei) : Set first .bi lineno value to
+ location of next .bf
+ * config/obj-coff.c (coff_frob_symbol) : XCOFF does not use endndx.
+
+2001-10-07 Alan Modra <amodra@bigpond.net.au>
+
+ * config/obj-elf.c: Standardize error/warning messages - don't
+ capitalise, no final period or newline, don't say "ignoring" for
+ as_bad messages. In some cases, change the wording to that used
+ elsewhere for similar messages.
+ (obj_elf_section_name): New function, split out from ..
+ (obj_elf_section): .. here. Correctly mask off SHF_MERGE if
+ entsize not specified.
+
+2001-10-05 Jakub Jelinek <jakub@redhat.com>
+
+ * doc/as.texinfo: Document M and S ELF section flags.
+
+2001-10-05 Alan Modra <amodra@bigpond.net.au>
+
+ * subsegs.c (subseg_text_p): Return 0 for absolute section.
+ * read.c (do_align): If in absolute section, warn about and ignore
+ non-zero fill pattern.
+
+2001-10-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mn10300.c (tc_gen_reloc): Don't free
+ reloc->sym_ptr_ptr if it's not allocated.
+
+2001-10-04 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (prev_insn_reloc_type): Make it an array to hold a
+ relocation triple.
+ (prev_insn_fixp): Likewise.
+ (append_insn): Changed prototype to accept a relocation pointer.
+ (imm_reloc): Make it an array.
+ (offset_reloc): Likewise.
+ (md_assemble): Handle triple relocations.
+ (append_insn): Likewise. Add handling for some NewABI relocations.
+ (mips_no_prev_insn): Handle triple relocations.
+ (macro_build): Likewise. Add handling for some NewABI relocations.
+ Move handling for the 'u' case to append_insn().
+ (mips16_macro_build): Handle triple relocations.
+ (macro_build_lui): Likewise. Don't handle _gp_disp as special symbol
+ for NewABI.
+ (mips_ip): Handle triple relocations.
+ (mips16_ip): Likewise.
+ (mips_force_relocation): Force handling of triple relocations
+ without symbols for NewABI.
+ (md_apply_fix): Add handling for some NewABI relocations.
+
+2001-10-05 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.c (parse_register): If not producing code for
+ x86_64, reject x86_64 register name matches.
+ (md_assemble): Remove now redundant check for x86_64 regs.
+
+2001-10-04 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (md_assemble <DS relocs>): Test ppc_size as well
+ as BFD_DEFAULT_TARGET_SIZE.
+ (ppc_tc): Likewise.
+ (ppc_is_toc_sym): Likewise.
+ (md_apply_fix3): Likewise.
+
+2001-10-03 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips_64): Remove.
+ (mips_target_format): Move downwards in file, use HAVE_64BIT_OBJECTS
+ in it.
+ (mips_abi_level, mips_abi): New enum.
+ (mips_32bit_abi): Remove.
+ (HAVE*PRS): Use mips_abi instead of mips_32bit_abi.
+ (HAVE_NEWABI): New define.
+ (HAVE_64BIT_OBJECTS): New define.
+ (HAVE_32BIT_ADDRESSES): Don't return true for 64bit objects.
+ (HAVE_64BIT_ADDRESSES): New define, inverse of HAVE_32BIT_ADDRESSES.
+ (support_64bit_objects): New prototype.
+ (md_begin): Use mips_abi instead of mips_32bit_abi. Don't write
+ .reginfo section for n32, use .MIPS.options instead.
+ (support_64bit_objects): New function, code from md_parse_option.
+ (md_longopts): Add -n32 option.
+ (md_parse_option): Use mips_abi instead of mips_32bit_abi/mips64.
+ Add -n32 option. Protect with OBJ_ELF.
+ (s_mipsset): Use mips_abi instead of mips_32bit_abi.
+ (mips_elf_final_processing): Likewise. Don't write .reginfo section
+ for n32, use .MIPS.options instead.
+
+2001-10-03 Alan Modra <amodra@bigpond.net.au>
+
+ * po/POTFILES.in: Regenerate.
+ * configure: Regenerate.
+
+2001-10-02 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (md_apply_fix3 <BFD_RELOC_CTOR>): Make it 64
+ bits if target is 64 bit.
+
+ * doc/as.texinfo (listing): Fix typo.
+
+ * as.c (print_version_id): Use BFD_VERSION_STRING in place of
+ BFD_VERSION.
+ * Makefile.am (Makefile): Depend on bfd/configure.in.
+ Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2001-09-30 H.J. Lu <hjl@gnu.org>
+
+ * config/obj-elf.c (obj_elf_parse_section_letters): Accept "am"
+ and "ams" for compatibility.
+
+2001-09-30 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/tc-sh.c (md_pcrel_from_section): Transformed from
+ md_pcrel_from. Handle pc-relativeness against link-time
+ symbol. Handle relativeness to elsewhere than the fixup.
+ * config/tc-sh.h (MD_PCREL_FROM_SECTION): Define.
+ (md_pcrel_from_section): Prototype.
+
+ * Makefile.am: Update dependencies with "make dep-am".
+ * Makefile.in: Regenerate.
+
+2001-09-30 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * config/tc-m68hc11.c (cmp_opcode): Define prototype.
+ (print_opcode_format, skip_whites): Likewise.
+ (convert_branch, m68hc11_new_insn): Likewise.
+ (build_dbranch_insn, build_indexed_byte): Likewise.
+ (build_reg_mode, find, find_opcode): Likewise.
+ (print_insn_format): Fix call to print_opcode_format.
+ (md_assemble): Fix call to build_dbranch_insn.
+
+2001-09-27 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-arm.c: Add missing prototypes.
+
+2001-09-26 Jeff Johnston <jjohnstn@redhat.com>
+
+ * input-file.c (input_file_open): When reading the
+ first line looking for #NO_APP, prepare for the possibility
+ of finding #APP instead. Also fix algorithm to allow
+ white-space to follow either #NO_APP or #APP directives.
+
+2001-09-25 Geoff Berry <geoff.berry@bops.com>
+
+ * listing.c (buffer_line): Don't write past the end of `line' when
+ EOF is reached.
+
+2001-09-25 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mn10300.c (tc_gen_reloc): Don't emit an *ABS*
+ relocation for differences between symbols in a section other
+ than the one in which the difference is to be placed; apply
+ the relocation instead.
+
+2001-09-24 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-arc.c: Add missing prototype.
+ (md_atof): Change type to int. Add missing prototype.
+ * config/tc-arc.h: Prototype exported functions.
+
+2001-09-22 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * as.c: Add missing function prototype.
+ * config/obj-aout.c: Fix compile time warning.
+
+2001-09-21 Bruno Haible <haible@clisp.cons.org>
+
+ * config/tc-openrisc.c: Don't include <ctype.h>.
+
+2001-09-19 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * gas/config/tc-s390.c: Add option -mwarn-areg-zero.
+
+2001-09-19 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i370.c: Fix typo in last change.
+
+2001-09-19 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * doc/as.texinfo (Symbol Names): Improve documentation on local
+ labels and add documenation about dollar labels.
+
+2001-09-18 Bruno Haible <haible@clisp.cons.org>
+
+ * as.h: Don't include <ctype.h>.
+ * as.c (main): For gettext, also set the LC_CTYPE locate facet.
+ * atof-generic.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (atof_generic): Use ISDIGIT instead of isdigit.
+ * config/m68k-parse.y: Include "safe-ctype.h".
+ (yylex): Use ISDIGIT/ISALNUM instead of isdigit/isalnum.
+ * config/obj-elf.c: Include "safe-ctype.h".
+ (obj_elf_vtable_inherit): Use ISSPACE instead of isspace.
+ * config/obj-vms.c: Include "safe-ctype.h".
+ (Write_VMS_MHD_Records): Use TOUPPER instead of islower/toupper.
+ (VMS_Case_Hack_Symbol): Use ISUPPER/ISLOWER/TOUPPER/TOLOWER
+ instead of isupper/islower/toupper/tolower.
+ * config/tc-a29k.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (insert_sreg): Use TOUPPER instead of islower/toupper.
+ (machine_ip): Use ISALPHA/ISALNUM/ISUPPER/TOLOWER instead of
+ isalpha/isalnum/isupper/tolower.
+ (a29k_unrecognized_line, md_operand): Use ISDIGIT instead of
+ isdigit.
+ * config/tc-alpha.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (md_undefined_symbol, s_alpha_ent): Use ISDIGIT instead of isdigit.
+ * config/tc-arc.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (md_assemble): Use ISSPACE/ISALNUM instead of isspace/isalnum.
+ (arc_extoper): Use TOLOWER instead of isupper/tolower.
+ * config/tc-arm.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (arm_psr_parse): Use ISALPHA instead of isalpha.
+ (accum0_required_here): Use ISALNUM instead of isalnum.
+ (do_ldrd): Use ISSPACE instead of isspace.
+ (decode_shift): Use ISALPHA instead of isalpha.
+ (insert_reg): Use TOUPPER instead of islower/toupper.
+ (arm_reg_parse): Use ISALPHA instead of isalpha.
+ (arm_parse_reloc): Use ISALNUM/ISPUNCT/TOLOWER instead of
+ isalnum/ispunct/tolower.
+ * config/tc-avr.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (md_parse_option): Use TOLOWER instead of tolower.
+ (avr_operand): Use ISDIGIT/TOLOWER instead of isdigit/tolower.
+ * config/tc-cris.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (cris_process_instruction): Use ISLOWER instead of islower.
+ (get_gen_reg): Use ISALNUM/ISDIGIT instead of isalnum/isdigit.
+ (get_spec_reg): Use TOLOWER/ISALNUM instead of isupper/tolower/isalnum.
+ (get_flags): Use ISSPACE instead of isspace.
+ * config/tc-d10v.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (do_assemble): Use TOLOWER instead of tolower.
+ * config/tc-d30v.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (do_assemble): Use TOLOWER instead of tolower.
+ (d30v_start_line): Use ISSPACE instead of isspace.
+ * config/tc-fr30.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (fr30_is_colon_insn): Use TOLOWER instead of tolower.
+ * config/tc-h8300.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (skip_colonthing, get_operand): Use ISDIGIT instead of isdigit.
+ * config/tc-h8500.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (start_label): Use ISALPHA instead of isalpha.
+ * config/tc-hppa.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (pa_ip): Use ISUPPER/ISLOWER/TOLOWER instead of
+ isupper/islower/tolower.
+ (pa_parse_number): Use ISDIGIT instead of isdigit.
+ (pa_chk_field_selector): Use TOLOWER instead of tolower.
+ (pa_stringer): Use ISDIGIT instead of isdigit.
+ * config/tc-i370.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (register_name): Use ISALPHA instead of isalpha.
+ (i370_elf_suffix): Use ISALNUM/TOLOWER instead of
+ isalnum/islower/tolower.
+ (i370_addr_offset): Use ISDIGIT/ISALPHA instead of
+ isdigit/isalpha.
+ (i370_addr_cons): Use ISALPHA/ISXDIGIT instead of
+ isalpha/isxdigit.
+ (md_assemble): Use ISSPACE instead of isspace.
+ * config/tc-i386.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (md_begin): Use ISDIGIT/ISLOWER/ISUPPER/TOLOWER/ISALPHA
+ instead of isdigit/islower/isupper/tolower/isalpha.
+ (output_invalid): Use ISPRINT instead of isprint.
+ * config/tc-i860.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (i860_ip): Use ISLOWER/ISDIGIT instead of islower/isdigit.
+ * config/tc-i960.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (get_args): Use ISALNUM instead of isalnum.
+ * config/tc-ia64.c: Include "safe-ctype.h".
+ (dot_pred_rel): Use TOUPPER/ISDIGIT instead of toupper/isdigit.
+ (ia64_unrecognized_line): Use ISDIGIT instead of isdigit.
+ (ia64_parse_name): Likewise.
+ * config/tc-m32r.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (assemble_two_insns): Use ISSPACE/ISALNUM/ISUPPER/TOLOWER
+ instead of isspace/isalnum/isupper/tolower.
+ * config/tc-m68hc11.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (md_assemble): Use TOLOWER/ISALNUM instead of tolower/isalnum.
+ * config/tc-m68k.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (mklower_table): Remove variable.
+ (mklower): Remove macro.
+ (insert_reg): Use TOUPPER instead of islower/toupper.
+ (md_begin): Remove initialization of mklower_table.
+ (s_reg): Use ISALNUM instead of isalnum.
+ (mri_assemble): Use ISUPPER/TOLOWER instead of isupper/tolower.
+ (parse_mri_condition): Use TOLOWER instead of isupper/tolower.
+ (build_mri_control_operand): Use TOLOWER instead of tolower.
+ (s_mri_else, s_mri_break, s_mri_next, s_mri_for): Likewise.
+ * config/tc-m88k.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (md_assemble): Use ISSPACE instead of isspace.
+ (get_imm16): Use ISALNUM instead of isalnum.
+ (get_cnd): Use ISDIGIT/ISUPPER/TOLOWER instead of
+ isdigit/isupper/tolower.
+ (get_bf_offset_expression): Use ISALPHA/ISUPPER/TOLOWER
+ instead of isalpha/isupper/tolower.
+ (hexval): Use ISDIGIT/ISLOWER/ISUPPER instead of
+ isdigit/islower/isupper.
+ * config/tc-mcore.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (mcore_s_section): Use ISSPACE instead of isspace.
+ (parse_reg): Use ISSPACE/TOLOWER/ISALNUM instead of
+ isspace/tolower/isalnum.
+ (parse_creg): Use ISSPACE/TOLOWER instead of isspace/tolower.
+ (parse_psrmod): Use TOLOWER instead of isascii/tolower.
+ (parse_exp, parse_mem, md_assemble): Use ISSPACE instead of
+ isspace.
+ * config/tc-mips.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (mips_ip): Use ISSPACE/ISDIGIT instead of isspace/isdigit.
+ (mips16_ip): Use ISLOWER/ISDIGIT instead of islower/isdigit.
+ (my_getSmallExpression): Use ISDIGIT/TOLOWER instead of
+ isdigit/tolower.
+ (tc_get_register): Likewise.
+ (get_number): Use ISDIGIT/ISXDIGIT instead of isdigit/isxdigit.
+ (s_mips_ent): Use ISDIGIT instead of isdigit.
+ * config/tc-mn10200.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (md_assemble): Use ISSPACE instead of isspace.
+ * config/tc-mn10300.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (md_assemble): Use ISSPACE instead of isspace.
+ * config/tc-ns32k.c: Don't include <ctype.h>.
+ * config/tc-pdp11.c: Include "safe-ctype.h".
+ (mklower): Remove function.
+ (parse_reg): Use TOLOWER instead of mklower.
+ * config/tc-pj.c: Include "safe-ctype.h".
+ (md_assemble): Use ISSPACE instead of isspace.
+ * config/tc-ppc.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (register_name): Use ISALPHA instead of isalpha.
+ (ppc_elf_suffix): Use ISALNUM/TOLOWER instead of
+ isalnum/islower/tolower.
+ (md_assemble): Use ISSPACE instead of isspace.
+ (ppc_canonicalize_symbol_name): Use ISLOWER/TOUPPER instead of
+ islower/toupper.
+ * config/tc-s390.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (register_name): Use ISALPHA instead of isalpha.
+ (s390_elf_suffix, s390_lit_suffix): Use ISALNUM instead of isalnum.
+ (md_gather_operands, md_assemble, s390_insn): Use ISSPACE instead of
+ isspace.
+ * config/tc-sh.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (sh_elf_suffix): Use ISALNUM/TOLOWER instead of
+ isalnum/islower/tolower.
+ (IDENT_CHAR): Use ISALNUM instead of isalnum.
+ (parse_reg): Use TOLOWER instead of tolower.
+ (find_cooked_opcode): Use TOLOWER instead of isupper/tolower.
+ * config/tc-sparc.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (sparc_ip): Use ISLOWER/ISDIGIT instead of islower/isdigit.
+ (parse_keyword_arg): Use ISALNUM instead of isalnum.
+ * config/tc-tahoe.c: Include "safe-ctype.h".
+ (tahoe_reg_parse): Use ISDIGIT instead of isdigit.
+ (tip_op): Use TOLOWER instead of isupper/tolower.
+ * config/tc-tic30.c: Include "safe-ctype.h".
+ (md_begin): Use ISLOWER/ISDIGIT/ISUPPER/TOLOWER/ISLOWER/
+ ISALPHA instead of islower/isdigit/isupper/tolower/islower/isalpha.
+ (tic30_operand): Use TOLOWER instead of tolower.
+ (tic30_find_parallel_insn): Likewise.
+ (output_invalid): Use ISPRINT instead of isprint.
+ * config/tc-tic54x.c: Include "safe-ctype.h".
+ (tic54x_asg, tic54x_eval): Use ISALPHA instead of isalpha.
+ (lookup_version): Use TOUPPER instead of toupper.
+ (tic54x_var): Use ISALPHA instead of isalpha.
+ (tic54x_mlib): Use ISSPACE instead of isspace.
+ (subsym_iscons): Use TOUPPER instead of toupper.
+ (get_operands): Use ISSPACE instead of isspace.
+ (is_type): Use TOUPPER/ISDIGIT instead of toupper/isdigit.
+ (encode_indirect, encode_operand): Use TOUPPER instead of toupper.
+ (next_line_shows_parallel): Use ISSPACE instead of isspace.
+ (subsym_get_arg, subsym_substitute): Use ISDIGIT instead of isdigit.
+ (tic54x_start_line_hook, md_assemble, tic54x_start_label): Use
+ ISSPACE instead of isspace.
+ * config/tc-tic80.c: Include "safe-ctype.h".
+ (md_assemble): Use ISSPACE instead of isspace.
+ * config/tc-v850.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (system_register_name): Use ISDIGIT instead of isdigit.
+ (md_assemble): Use ISSPACE instead of isspace.
+ * config/tc-vax.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (vax_reg_parse): Use TOLOWER/ISDIGIT instead of
+ isupper/tolower/isdigit.
+ (vip_op): Use TOLOWER instead of isupper/tolower.
+ * config/tc-w65.c: Don't include <ctype.h>.
+ * config/tc-z8k.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (tohex): Use ISDIGIT/ISLOWER instead of isdigit/islower.
+ (whatreg): Use ISDIGIT instead of isdigit.
+ * ecoff.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (ecoff_directive_ent, ecoff_stab): Use ISDIGIT instead of isdigit.
+ * expr.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (integer_constant): Use ISALNUM/TOUPPER instead of
+ isalnum/islower/toupper.
+ (operand): Use TOLOWER instead of isupper/tolower.
+ * gasp.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (sb_strtol, level_0, change_base, doinstr): Use ISDIGIT instead
+ of isdigit.
+ (process_assigns, whatcond): Use TOUPPER instead of toupper.
+ (chartype_init): Use ISALPHA/ISDIGIT instead of isalpha/isdigit.
+ (main): For gettext, also set the LC_CTYPE locate facet.
+ * hash.c: Include "safe-ctype.h".
+ (main): Use TOLOWER instead of isupper/tolower.
+ * itbl-lex.l: Don't include <ctype.h>.
+ * listing.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (listing_newline): Use ISCNTRL instead of isascii/iscntrl. Don't
+ omit non-ASCII characters.
+ (debugging_pseudo): Use ISSPACE instead of isspace.
+ * macro.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (buffer_and_nest): Use ISALNUM instead of isalnum.
+ (get_token): Use ISALPHA/ISALNUM instead of isalpha/isalnum.
+ (define_macro): Use ISUPPER/TOLOWER instead of isupper/tolower.
+ (macro_expand_body): Use ISALNUM/ISDIGIT/ISUPPER/ISALPHA
+ instead of isalnum/isdigit/isupper/isalpha.
+ (check_macro): Use ISALPHA/ISALNUM/ISUPPER/TOLOWER instead
+ of isalpha/isalnum/isupper/tolower.
+ * read.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (read_a_source_file): Use ISUPPER/TOLOWER/ISDIGIT instead of
+ isupper/tolower/isdigit.
+ (s_mri_common): Use ISDIGIT instead of isdigit.
+ (s_mri_sect): Use ISDIGIT/TOUPPER instead of isdigit/toupper.
+ (s_float_space): Use ISALPHA instead of isalpha.
+ (ignore_rest_of_line): Use ISPRINT instead of isprint.
+ (float_cons): Use ISALPHA instead of isalpha.
+ (next_char_of_string): Use ISDIGIT/ISXDIGIT instead of
+ isdigit/isxdigit.
+ * symbols.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (save_symbol_name): Use ISLOWER/TOUPPER instead of
+ islower/toupper.
+ (symbol_find_base): Use TOUPPER instead of islower/toupper.
+ (decode_local_label_name): Use ISDIGIT instead of isdigit.
+
+2001-09-18 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * tc-s390.c (s390_insn): Add code to cope with 6 byte O_constants
+ in 64 bit mode and make format "e" work.
+
+2001-09-18 Alan Modra <amodra@bigpond.net.au>
+
+ * dwarf2dbg.c (dwarf2_directive_file): Avoid signed/unsigned warning.
+
+ * write.c (set_symtab): Update bfd_alloc declaration. Use a temp
+ var to ensure bfd_alloc arg is the right type.
+ (write_object_file): Cast args of bfd_seek. Replace bfd_write with
+ bfd_bwrite.
+
+ * config/obj-coff.c: Replace calls to bfd_write with calls to
+ bfd_bwrite. Cast args of bfd_seek.
+
+ * config/obj-elf.c (obj_elf_change_section): Avoid signed/unsigned
+ warning.
+
+ * config/tc-mn10300.c (set_arch_mach): Make param unsigned.
+
+ * config/tc-tic54x.c (tic54x_mlib): Replace bfd_read call with
+ call to bfd_bread.
+
+2001-09-15 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/tc-sh.h (sh_force_relocation): Prototype.
+ (struct fix): Forward declare.
+ * config/tc-sh.c (type sh_operand_info): Move to top of file.
+ (cons, s_align_bytes): Remove old-type declarations.
+ (sh_elf_suffix, parse_reg, dot, parse_exp, parse_at, get_operand,
+ get_operands, get_specific, insert, build_relax,
+ insert_loop_bounds, build_Mytes): Prototype.
+ (little): Make static. Prototype.
+ (check, tc_Nout_fix_to_chars): Delete unused functions.
+
+2001-09-14 Eric Christopher <echristo@redhat.com>
+
+ * config/tc-mips.c (md_parse_option): Remove setting mips_64 via
+ -mgp32/mgp64.
+
+2001-09-14 Kevin Lo <kevlo@openbsd.org>
+
+ * configure.in: Add arm-openbsd target.
+ * configure: Regenerate.
+
+2001-09-14 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * configure.in: Change machine triplets from mips-*-linux-gnu* to
+ mips*-*-linux*.
+
+2001-09-12 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (append_insn): Don't rightshift BFD_RELOC_16_PCREL.
+
+2001-09-11 Richard Henderson <rth@redhat.com>
+
+ * config/tc-alpha.c (alpha_elf_section_letter): New.
+ (alpha_elf_section_flags): New.
+ * config/tc-alpha.h (md_elf_section_letter): New.
+ (md_elf_section_flags): New.
+ * config/tc-ia64.c (ia64_elf_section_letter): New.
+ * config/tc-ia64.h (md_elf_section_letter): New.
+
+2001-09-11 Jakub Jelinek <jakub@redhat.com>
+
+ * config/obj-elf.c (obj_elf_parse_section_letters): Use 'M' instead
+ of 'm', 'S' instead of 's'. Update bad_msg.
+ * config/tc-ppc.c (ppc_section_letter): Update bad_msg.
+ * config/tc-i370.c (i370_sectioN_letter): Update bad_msg.
+
+2001-09-09 Alan Modra <amodra@bigpond.net.au>
+
+ * expr.c (expr): Move code setting "retval" to the end of the loop,
+ and rearrange for efficiency. For "PIC code" subtraction, use
+ "rightseg" rather than recalculating. For "symbol OP symbol"
+ subtract, set "retval" to absolute_section if symbols in same
+ section.
+ * symbols.c (resolve_symbol_value): Resolve "sym +/- expr" to an
+ O_symbol. Simplify a +/- b code. Allow equality and non-equality
+ comparisons on symbols from any section. Allow other comparison
+ operators as for subtraction.
+ (symbol_equated_reloc_p): New predicate function.
+ * symbols.h (symbol_equated_reloc_p): Declare.
+ * write.c (relax_segment <rs_machine_dependent>): Ensure segment
+ for expression syms is set correctly.
+ (adjust_reloc_syms): Use symbol_equated_reloc_p.
+ (write_relocs): Likewise.
+ (write_object_file): Likewise.
+ * config/tc-mips.c (md_estimate_size_before_relax): Likewise.
+ * config/tc-i386.c (md_assemble <Output jumps>): Don't lose part
+ of a complex expression when setting up frag_var.
+
+2001-09-07 Richard Henderson <rth@redhat.com>
+
+ * config/tc-alpha.c (alpha_reloc_op_tag): Replace need_seq with
+ require_seq and allow_seq. Let !literal omit the sequence number.
+ (tokenize_arguments): Reject sequence numbers of !allow_seq.
+
+2001-09-08 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-sparc.c (md_apply_fix3): Handle relocs against SEC_MERGE
+ section symbols the same way as externs.
+
+2001-09-07 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (s_mipsset): Reallow unrestricted use of .set mipsX
+ pseudo-op.
+
+2001-09-07 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (append_insn): Handle BFD_RELOC_16_PCREL.
+ (macro_build): Use BFD_RELOC_16_PCREL_S2 only for embedded
+ PIC, BFD_RELOC_16_PCREL for the rest.
+ (mips_ip): Likewise.
+ (md_pcrel_from): return the right offset for the differently shifted
+ pcrel relocs.
+ (md_apply_fix): Handle BFD_RELOC_16_PCREL.
+
+2001-09-05 Richard Henderson <rth@redhat.com>
+
+ * config/tc-ia64.c (FUNC_IPLT_RELOC): New.
+ (pseudo_func): Add @iplt.
+ (pseudo_opcode): Add data16 and data16.ua.
+ (md_begin): Set iplt pseudo.
+ (ia64_cons_fix_new): Handle 16 byte iplt reloc specially.
+
+2001-09-04 Richard Henderson <rth@redhat.com>
+
+ * config/tc-alpha.c (struct alpha_insn): Make sequence scalar long.
+ (MACRO_LITERAL, MACRO_BASE, MACRO_BYTOFF, MACRO_JSR): Remove.
+ (alpha_macros): Remove occurrences of same.
+ (O_lituse_addr, O_gprel): New.
+ (DUMMY_RELOC_LITUSE_*): New.
+ (s_alpha_ucons, s_alpha_arch): Prototype.
+ (alpha_reloc_op): Construct elements via DEF macro.
+ (ALPHA_RELOC_SEQUENCE_OK): Remove.
+ (struct alpha_reloc_tag): Rename from alpha_literal_tag; rename
+ members to not be literal specific.
+ (next_sequence_num): New.
+ (md_apply_fix3): Cope with missing GPDISP_LO16. Adjust for
+ added/removed BFD relocations.
+ (alpha_force_relocation, alpha_fix_adjustable): Likewise.
+ (alpha_adjust_symtab_relocs): Handle GPDISP relocs as well.
+ (tokenize_arguments): Parse ! relocations properly.
+ (find_macro_match): Delete unused macro argument types.
+ (assemble_insn): Add reloc parameter; emit that instead of the
+ default as appropriate.
+ (get_alpha_reloc_tag): New. Split from ...
+ (emit_insn): ... here. Allocate a reloc tag for GPDISP.
+ (assemble_tokens): Don't search macros if user relocation present.
+ Copy reloc sequence number to insn struct.
+ (emit_ldgp): Remove user reloc handling.
+ (load_expression, emit_lda, emit_ldah, emit_ir_load): Likewise.
+ (emit_loadstore, emit_ldXu, emit_ldil, emit_stX): Likewise.
+ (emit_sextX, emit_division, emit_jsrjmp, emit_retjcr): Likewise.
+ * config/tc-alpha.h (tc_adjust_symtab): Always define.
+ (struct alpha_fix_tag): Name members less literal specific.
+
+2001-09-04 Jeffrey A Law (law@cygnus.com)
+
+ * tc-h8300.c (tc_gen_reloc): Give an error if we try to take the
+ address of two symbols in different sections.
+
+2001-08-31 Eric Christopher <echristo@redhat.com>
+ Jason Eckhardt <jle@redhat.com>
+
+ * config/tc-mips.c (mips_cpu_info): Add support for mipsisa32,
+ 5kc, and 20kc. Clean up old entries.
+
+2001-08-31 J"orn Rennecke <amylaar@redhat.com>
+ Jeff Law <law@redhat.com>
+
+ * config/tc-h8300.c (build_bytes): For OBJ_ELF, make relocation's
+ offset match H8 ELF spec.
+ (md_section_align): Alternate implementation for BFD_ASSEMBLER.
+ (md_apply_fix): Fix argument and return types for BFD_ASSEMBLER.
+
+ * tc-h8300.c (relocation mappings): Remove. Moved to tc-h8300.h.
+ (build_bytes): Mark fixups for PCrel branches as signed. For
+ OBJ_ELF, make sure the reloc's offset points to the first byte
+ to be modified.
+ (md_convert_frag): Update definiton based on BFD_ASSEMBLER.
+ * tc-h8300.h (relocation mappings): Add.
+
+2001-08-30 J"orn Rennecke <amylaar@redhat.com>
+
+ * tc-h8300.c (tc_crawl_symbol_chain, tc_headers_hook): Don't
+ define for BFD_ASSEMBLER.
+ (tc_reloc_mangle): Likewise.
+ (tc_gen_reloc): New function for BFD_ASSEMBLER.
+
+2001-08-29 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-h8300.c (h8300hmode): Record the machine type
+ if BFD_ASSEMBLER is defined.
+ (h8300smode, md_begin): Similarly.
+
+2001-08-29 Joel Sherrill <joel@OARcorp.com>
+
+ * configure.in (i[3456]86-*-rtems*, m68*-*-rtems*): Change
+ default from coff to elf.
+ * configure: Regenerate.
+
+2001-08-29 J"orn Rennecke <amylaar@redhat.com>
+
+ * tc-h8300.c: If OBJ_ELF, include elf/h8.h, and define
+ assorted coff relocations to the corresponding elf relocations.
+ * tc-h8300.h (TARGET_ARCH, TARGET_FORMAT): Define appropriately.
+
+ * configure.in: Add case for h8300-*-elf.
+ * configure: Regenerate.
+
+2001-08-29 J"orn Rennecke <amylaar@redhat.com>
+
+ * doc/internals.texi (MD_PCREL_FROM_SECTION): Change
+ documentation to reflect reality.
+
+2001-08-27 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (load_address): Reflect change to MAX_GPREL_OFFSET.
+ (macro): Reflect change to MAX_GPREL_OFFSET.
+
+2001-08-27 Torbjorn Granlund <tege@swox.com>
+ Staffan Ulfberg <staffanu@swox.se>
+ Linus Nordberg <linus@swox.se>
+ Alan Modra <amodra@bigpond.net.au>
+
+ * configure.in: Recognise powerpc*le*, not just powerpcle*.
+ * configure: Regenerate.
+ * config/tc-ppc.c (PPC_LO, PPC_HI, PPC_HA, PPC_HIGHER,
+ PPC_HIGHERA, PPC_HIGHEST, PPC_HIGHESTA, SEX16): New macros.
+ (md_assemble): Use them.
+ (ppc_machine): Support stub for ELF64 as well as XCOFF.
+ (md_pseudo_table): Add "llong", "quad".
+ (md_parse_option): Match default_cpu of powerpc*.
+ (ppc_arch): Likewise.
+ (ppc_subseg_align): Only for OBJ_XCOFF.
+ (ppc_target_format): Return elf64-powerpc strings for 64 bit ELF.
+ (md_begin): Select PPC_OPCODE_64 for 64 bit.
+ (ppc_insert_operand): Don't bother testing 'file' before calling
+ as_bad_where. Use as_bad_where for operand->insert errors.
+ (mapping): Add ELF64 relocation modifiers.
+ (ppc_elf_suffix): Replace symbol on BFD_RELOC_PPC64_TOC reloc
+ expressions with abs_symbol.
+ (ppc_elf_cons): Correct offset for little endian targets.
+ (ppc_elf_frob_symbol): New.
+ (md_assemble): Add support for 64 bit ELF relocs.
+ (ppc_tc): Ensure 8 byte alignment when 64 bit.
+ (ppc_is_toc_sym): Only define for OBJ_XCOFF and OBJ_ELF. Match
+ ".toc" section for 64 bit ELF.
+ (ppc_fix_adjustable): New. Macro body moved from tc-ppc.h.
+ (md_apply_fix3): Silence warning with ATTRIBUTE_UNUSED. Only do
+ the ppc_is_toc_sym check for OBJ_XCOFF and OBJ_ELF. For 64 bit,
+ use BFD_RELOC_PPC64_TOC16_DS instead of BFD_RELOC_PPC_TOC16.
+ Expand on comments, error message. Add support for 64 bit relocs,
+ and use PPC_HI etc. macros.
+ * config/tc-ppc.h (MAX_MEM_FOR_RS_ALIGN_CODE): Define.
+ (HANDLE_ALIGN): Define to generate nops in code sections rather
+ than zeros.
+ (TC_FORCE_RELOCATION): Force for BFD_RELOC_PPC64_TOC.
+ (ELF_TC_SPECIAL_SECTIONS): Add 64 bit ELF sections.
+ (tc_fix_adjustable): Move body of macro to tc-ppc.c.
+ (ppc_fix_adjustable): Declare.
+ (tc_frob_symbol): Define.
+ (ppc_elf_frob_symbol): Declare.
+
+2001-08-26 Andreas Jaeger <aj@suse.de>
+
+ * config/tc-s390.c: Add missing prototypes
+ (md_gather_operands): Make static.
+
+2001-08-26 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.h (MAX_GPREL_OFFSET): Change it to the maximum
+ allowed value, not the word beyond maximum.
+ * config/tc-mips.c (macro_build_lui): Code cleanup.
+ (macro): Reflect change to MAX_GPREL_OFFSET.
+ (mips_ip): Check explicitly against S_EX_NONE.
+ (my_get_SmallExpression): parse for %gp_rel, not %gprel.
+ (md_apply_fix): Code cleanup.
+
+2001-08-24 Andreas Jaeger <aj@suse.de>
+
+ * config/tc-ppc.h: Fix prototype declaration.
+
+2001-08-23 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-ia64.c (dot_endp): Set function symbol sizes.
+ * config/obj-elf.c (obj_elf_size): When size is constant, free
+ and clear symbol_get_obj(sym)->size if any.
+
+2001-08-21 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (md_begin): Warn about incompatibility between
+ -march=FOO and -mipsN option, continue with default ISA.
+
+2001-08-21 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (md_parse_option): #ifdef the
+ traditional/non-traditional names as it is done in mips_target_format.
+
+2001-08-20 Richard Henderson <rth@redhat.com>
+
+ * config/tc-alpha.h (MD_APPLY_FIX3): Define.
+ * config/tc-alpha.c (md_apply_fix3): Rename from md_apply_fix;
+ use seg parameter instead of now_seg.
+
+2001-08-18 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-mips.c (show): Add the missing prototype.
+
+2001-08-18 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (S_EX_*): New enum for my_getSmallExpression()
+ return values.
+ (mips_ip): Use the new return values instead of characters. Add
+ support for %higher and %highest.
+ (LP): Remove.
+ (RP): Remove.
+ (my_getSmallExpression): Make parsing case insensitive and more
+ reliable. Add support for %higher and %highest. Further support to
+ parse %gprel and %neg is implemented but currently deactivated.
+
+2001-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * ecoff.c (ecoff_frob_symbol): Remove casts from bfd_get_gp_size.
+ (ecoff_build_symbols): Likewise.
+ * read.c (s_lcomm_internal): Fix signed/unsigned warning.
+
+2001-08-16 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips_elf_final_processing): Set elf header flags
+ for n32 ABI if appropriate.
+
+2001-08-16 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (cons_fix_new_mips): Remove.
+ * config/tc-mips.h (TC_CONS_FIX_NEW): Remove.
+ (cons_fix_new_mips): Remove.
+
+2001-08-14 Jeff Johnston <jjohnstn@redhat.com>
+
+ * expr.c (operand)[LITERAL_PREFIXDOLLAR_HEX]: Treat $L as
+ a label, not a hex constant.
+
+2001-08-13 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-v850.h: Add missing prototypes.
+
+2001-08-12 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.c (s390_elf_cons): Correct fixups for PLT
+ relocations.
+
+2001-08-12 TAKAI Kousuke <takai@vlsi.kuee.kyoto-u.ac.jp>
+
+ * config/tc-sparc.c (cons_fix_new_sparc): Move
+ `sparc_no_align_cons = 0;' to...
+ (s_uacons): ...here so that sparc_no_align_cons will get
+ cleared properly.
+
+2001-08-11 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-mips.c: Fix a comment typo.
+
+2001-08-10 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (move_register): New function.
+ (macro_build): Remove OPCODE_IS_MEMBER's gp32 argument.
+ (mips_ip): Likewise.
+ (macro2): Use move_register rather than macro_build for moves.
+ (mips16_macro): Likewise.
+ (macro): Likewise. Handle M_MOVE.
+
+2001-08-10 Andreas Jaeger <aj@suse.de>
+
+ * configure.in: Add -Wstrict-prototypes and -Wmissing-prototypes
+ to build warnings.
+ * configure: Regenerate.
+
+2001-08-10 Alan Modra <amodra@bigpond.net.au>
+
+ * as.h (alloca): Don't declare if __GNUC__. Remove an old comment.
+ Comment indentation of #pragma.
+ * macro.c (alloca): Likewise.
+
+ * config/tc-ppc.c: Revert 2001-08-08.
+
+2001-08-09 Alan Modra <amodra@bigpond.net.au>
+
+ * symbols.c: Add missing prototypes.
+ * config/e-i386elf.c: Likewise.
+ * config/e-i386coff.c: Likewise.
+ * config/e-i386aout.c: Likewise.
+ * config/obj-coff.c: Likewise.
+ (def_symbol_in_progress, stack): Move definition.
+ * config/obj-elf.c: Add missing prototypes.
+ (obj_elf_change_section): Make static.
+ (obj_elf_parse_section_letters): Likewise.
+ (obj_elf_section_word): Likewise.
+ (obj_elf_section_type): Likewise.
+
+2001-08-08 Alan Modra <amodra@bigpond.net.au>
+
+ From 1999-10-25 Torbjorn Granlund <tege@swox.com>
+ * config/tc-ppc.c (md_apply_fix3): Replace haphazard code for
+ determining reloc type with code reading operands->reloc field.
+
+2001-08-08 Alan Modra <amodra@bigpond.net.au>
+
+ * config/obj-elf.c (elf_copy_symbol_attributes): Make it a global
+ function, and expand old obj-elf.h OBJ_COPY_SYMBOL_ATTRIBUTES here.
+ * config/obj-elf.h (elf_copy_symbol_attributes): Declare.
+ (OBJ_COPY_SYMBOL_ATTRIBUTES): Call elf_copy_symbol_attributes.
+
+ * output-file.c (output_file_create): Don't try to open a second
+ time as it's unnecessary. FOPEN_W was undefined too.
+
+2001-08-07 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (macro_build): Replace magic constants by defines.
+ (mips_ip): Likewise. Typo.
+
+2001-08-04 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips_abi_string): Initialize with NULL instead
+ of 0.
+ (RELAX_ENCODE): Replace bfd_vma by valueT.
+ (load_address): Formatting.
+ (macro): Likewise. Code cleanup. Typo.
+ (macro2): Formatting.
+ (md_parse_option): Typo.
+ (s_mipsset): Reorder cases to look nicer.
+ (md_estimate_size_before_relax): Formatting. Code cleanup.
+ (mips_elf_final_processing): Check against NULL instead of 0.
+ (md_obj_end): Remove ugly `' in message string.
+ (s_mips_ent): Remove ugly `' in message string.
+
+2001-07-30 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (md_begin): Take -mcpu value into account even when
+ -mipsX is specified. Make both -mcpu/-march and -mcpu/-mtune pairs
+ mutually exclusive (if they are different).
+ (md_parse_option): Warn if an -march/-mtune/-mcpu/-m<cpu> option is
+ set more than once.
+
+2001-08-03 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (md_apply_fix): Don't subtract the symbol value
+ from GPREL addends.
+
+2001-08-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/c-mips.tex (-mgp32, -mfp32): Added -mfp32, unified with -mgp32.
+ * config/tc-mips.c (mips_fp32, mips_32bit_abi): New static variables.
+ (md_long_opts): Add -mfp32 option.
+ (md_parse_option): Handle it. Set mips_32bit_abi given -mabi=32.
+ (md_show_usage): Show usage for -mfp32 and -mgp32.
+ (HAVE_32BIT_GPRS, HAVE_32BIT_FPRS): New macros.
+ (HAVE_64BIT_GPRS, HAVE_64BIT_FPRS): New macros, inverse of the above.
+ (HAVE_32BIT_ADDRESSES): New macro.
+ (load_register): Use HAVE_32BIT_GPRS to determine the register width.
+ (load_address): Use HAVE_32BIT_ADDRESSES to determine the address size.
+ (s_cprestore, s_cpadd): Likewise.
+ (macro): Use HAVE_32BIT_GPRS to determine the width of registers
+ used in branch and M_LI_D macros. Use HAVE_64BIT_FPRS to determine
+ the width registers used in M_LI_DD macros. Use HAVE_32BIT_ADDRESSES
+ to determine the width of addresses in load, store and jump macros.
+ (macro2): Use HAVE_32BIT_GPRS to determine the width of registers
+ used in set instructions; do not check the address size for them.
+ Use HAVE_32BIT_ADDRESSES to determine the width of addresses in
+ unaligned load and store macros.
+ (mips_ip): Use the new macros to check the width of a register when
+ processing float constants. Force a constant into memory if it is
+ destined for an FPR and the FPRs are wider than the GPRs. Warn about
+ odd FPR numbers if HAVE_32BIT_FPRS. Use HAVE_32BIT_GPRS rather
+ than mips_gp32 to select synthetic instructions.
+ (macro_build): Use HAVE_32BIT_GPRS rather than mips_gp32 to select
+ synthetic instructions.
+
+2001-08-01 Christian Groessler <cpg@aladdin.de>
+
+ * config/tc-z8k.c (parse_reg): If a string starts with "r", "rl",
+ "rh", "rr", "rq", or "sp" then don't automatically assume
+ it's a register name. Check whether there is a number
+ following.
+
+2001-08-01 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.c (lex_got): Match lower case relocation tokens.
+ Don't allocate more space than necessary for the input line copy.
+
+2001-08-01 Alan Modra <amodra@bigpond.net.au>
+
+ * read.c: Standardize error/warning messages - don't capitalise, no
+ final period or newline, don't say "ignored" or "zero assumed" for
+ as_bad messages. In some cases, change the wording to that used
+ elsewhere for similar messages.
+ * app.c: Likewise.
+ * as.c: Likewise.
+ * atof-generic.c: Likewise.
+ * cgen.c: Likewise.
+ * cond.c: Likewise.
+ * depend.c: Likewise.
+ * dwarf2dbg.c: Likewise.
+ * ecoff.c: Likewise.
+ * expr.c: Likewise.
+ * frags.c: Likewise.
+ * input-file.c: Likewise.
+ * input-scrub.c: Likewise.
+ * listing.c: Likewise.
+ * output-file.c: Likewise.
+ * stabs.c: Likewise.
+ * subsegs.c: Likewise.
+ * symbols.c: Likewise.
+ * write.c: Likewise.
+ * ecoff.c (ecoff_directive_end): Test for missing name by
+ comparing input line pointers rather than reading string.
+ (ecoff_directive_ent): Likewise.
+ * read.c (s_set): Likewise.
+ (s_align): Report a warning rather than an error for
+ alignment too large.
+ (s_comm): Check for missing symbol name.
+ (s_lcomm_internal): Likewise.
+ (s_lsym): Likewise.
+ (s_globl): Use is_end_of_line instead of looking for '\n'.
+ (s_lcomm_internal): Likewise.
+ (ignore_rest_of_line): Report a warning rather than an error.
+
+2001-07-31 Geoffrey Keating <geoffk@redhat.com>
+
+ * config/tc-ppc.c (ppc_elf_validate_fix): It's OK to have
+ any kind of relocation against a not-loaded section.
+
+2001-07-30 Alan Modra <amodra@bigpond.net.au>
+
+ * config/obj-elf.c (obj_elf_symver): Temporarily modify lex_type
+ to include '@' in symbol names when parsing versioned symbols
+ rather than calling get_symbol_end multiple times.
+ * config/tc-i370.c (register_name): Format fixes. Don't call
+ get_symbol_end after parsing number.
+ * config/tc-mn10200.c (data_register_name): Format fixes. Hoist
+ code out of conditional.
+ (address_register_name): Likewise.
+ (other_register_name): Likewise.
+ * config/tc-mn10300.c (r_register_name): Likewise.
+ (xr_register_name): Likewise.
+ (data_register_name): Likewise.
+ (address_register_name): Likewise.
+ (other_register_name): Likewise.
+ * config/tc-ppc.c (register_name): Likewise.
+ * config/tc-s390.c (register_name): Likewise.
+
+2001-07-27 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * config/tc-m68hc11.c (md_estimate_size_before_relax): Fix bsr
+ and bra relax: update fragP->fr_fix after the fixup.
+
+2001-07-27 Tracy Kuhrt <Tracy.Kuhrt@microchip.com>
+
+ * read.c (s_set): Check for missing symbol name.
+
+2001-07-26 Alan Modra <amodra@bigpond.net.au>
+
+ * write.c (relax_segment <rs_space>): Account for fr_fix.
+
+2001-07-25 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-mips.c (md_estimate_size_before_relax): Make sure
+ we treat weak like extern only for ELF.
+ (mips_fix_adjustable): Make sure we don't adjust extern/weak
+ symbols only for ELF.
+
+2001-07-25 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c: Fix spelling error in comment.
+
+2001-07-25 Dave Brolley <brolley@redhat.com>
+
+ * app.c (LEX_IS_PARALLEL_SEPARATOR): New macro.
+ (IS_PARALLEL_SEPARATOR): New macro.
+ (do_scrub_begin): Set up characters in tc_parallel_separator_chars
+ as LEX_IS_PARALLEL_SEPARATOR, if it is defined.
+ (do_scrub_chars): Handle LEX_PARALLEL_SEPARATOR chars like
+ LEX_LINE_SEPARATOR except that we go to state 1 (as if the label has
+ been seen).
+
+2001-07-24 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am (DEP_FLAGS): Define, add -DOBJ_MAYBE_ELF.
+ (DEP1, DEPTC, DEPOBJ, DEP2): Use it.
+ Update dependencies with "make dep-am".
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+
+2001-07-23 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-alpha.h: Fix formatting.
+ * config/tc-arc.c: Likewise.
+ * config/tc-d10v.h: Likewise.
+ * config/tc-hppa.c: Likewise.
+ * config/tc-i370.c: Likewise.
+ * config/tc-i386.h: Likewise.
+ * config/tc-i960.h: Likewise.
+ * config/tc-ia64.c: Likewise.
+ * config/tc-ia64.h: Likewise.
+ * config/tc-m32r.c: Likewise.
+ * config/tc-m68k.c: Likewise.
+ * config/tc-m88k.c: Likewise.
+ * config/tc-ns32k.c: Likewise.
+ * config/tc-pdp11.c: Likewise.
+ * config/tc-pj.h: Likewise.
+ * config/tc-s390.c: Likewise.
+ * config/tc-sparc.c: Likewise.
+ * config/tc-sparc.h: Likewise.
+ * config/tc-tic80.c: Likewise.
+ * config/tc-w65.h: Likewise.
+
+2001-07-23 Alan Modra <amodra@bigpond.net.au>
+
+ * symbols.c (S_GET_VALUE): Don't treat O_constant and local
+ symbols specially. Always resolve, adding fr_address to value.
+ * write.c (write_object_file): Don't add fr_address to sym values.
+ (relax_frag): Likewise.
+ (relax_segment): Likewise.
+ * config/obj-ieee.c (do_symbols): Likewise.
+ * config/tc-cris.c (md_convert_frag): Likewise.
+ * config/tc-fr30.c (md_convert_frag): Likewise.
+ * config/tc-i386.c (md_convert_frag): Likewise.
+ * config/tc-m32r.c (md_convert_frag): Likewise.
+ * config/tc-m68hc11.c (md_convert_frag): Likewise.
+ * config/tc-mcore.c (md_convert_frag): Likewise.
+ * config/tc-mips.c (mips16_extended_frag): Likewise.
+ * config/tc-ns32k.c (md_convert_frag): Likewise.
+ * config/tc-m68k.c (md_convert_frag_1): Likewise.
+ (BRANCHBWL, BRABSJUNC, BRABSJCOND, BRANCHBW, FBRANCH, DBCCLBR,
+ DBCCABSJ, PCREL1632, PCINDEX, ABSTOPCREL): Decrement.
+ (md_relax_table): Remove first four entries. Format.
+ (md_estimate_size_before_relax): Remove old_fix. Don't bother
+ setting fr_var. Simplify byte branch checks.
+
+2001-07-23 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-hppa.c (pa_parse_nonneg_cmpsub_cmpltr): Remove
+ "isbranch" param as all calls have it set.
+ (pa_parse_neg_cmpsub_cmpltr): Likewise.
+ (pa_parse_nonneg_add_cmpltr): Likewise. Remember result of
+ strcasecmp in "nullify" var.
+ (pa_parse_neg_add_cmpltr): Likewise.
+ (pa_ip): Don't "save_s" unnecessarily. Update calls to above
+ functions. Don't print wrong conditions in error messages.
+
+2001-07-23 Andreas Jaeger <aj@suse.de>
+
+ * config/tc-s390.c (s390_force_relocation): Removed.
+
+ * config/tc-s390.h: Remove double declaration of
+ TC_FORCE_RELOCATION.
+
+2001-07-22 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-mips.c (s_mips_end): Remove unused variables.
+ (s_mips_frame): Add ATTRIBUTE_UNUSED.
+
+2001-07-17 Andreas Schwab <schwab@suse.de>
+
+ * config/tc-m68k.c (md_pseudo_table) [OBJ_ELF]: Add .file and
+ .loc.
+ (md_assemble) [OBJ_ELF]: Call dwarf2_emit_insn before emitting
+ insn.
+ * config/tc-m68k.h (DWARF2_LINE_MIN_INSN_LENGTH): Define.
+
+2001-07-17 matthew green <mrg@eterna.com.au>
+
+ * config/tc-i386.c (comment_chars): Don't use '/' as comment start if
+ TE_NetBSD.
+ (line_comment_chars): Set to '/' if TE_NetBSD.
+
+2001-07-14 matthew green <mrg@eterna.com.au>
+
+ * configure.in (i386-*-netbsdelf*): New target.
+ * configure: Regenerate.
+
+2001-07-10 Mark Elbrecht <snowball3@softhome.net>
+
+ * config/obj-coff.c (coff_frob_symbol): Don't merge if the storage
+ class of the non-debug symbol is C_NULL.
+
+2001-07-10 Anders Norlander <anorland@synergenix.se>
+
+ * doc/as.texinfo (Incbin): Fix grammatical errors.
+
+2001-07-10 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * depend.c: Use FOPEN_.. macros in calls to fopen().
+ * input-file.c: As above.
+ * itbl-ops.c: As above.
+ * listing.c: As above.
+ * output-file.c: As above.
+ * read.c: As above.
+
+2001-07-08 Anders Norlander <anorland@synergenix.se>
+
+ * read.c (s_incbin): New .incbin function.
+ * read.c (potable): Add "incbin" pseudo-op.
+ * read.h: Add s_incbin prototype.
+ * doc/as.texinfo (incbin): Document .incbin pseudo-op.
+ * NEWS: Mention new feature.
+
+2001-07-07 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * ecoff.c (add_file): Only set debug_type to DEBUG_NONE if it is
+ DEBUG_UNSPECIFIED.
+
+2001-07-06 John Healy <jhealy@redhat.com>
+
+ * cgen.c (gas_cgen_save_fixups): Modified to allow more than one
+ set of fixups to be stored.
+ (gas_cgen_restore_fixups): Modified to allow the fixup chain to be
+ restored to be chosen from any that are saved.
+ (gas_cgen_swap_fixups): Modified to allow the current set of
+ fixups to be swapped with any other set that has been saved.
+ (gas_cgen_initialize_saved_fixups_array): New routine.
+ * cgen.h: Modifed prototypes for gas_cgen_save_fixups,
+ gas_cgen_restore_fixups, and gas_cgen_swap_fixups. Added definitions
+ or MAX_SAVED_FIXUP_CHAINS.
+ * config/tc-m32r.c (assemble_two_insns): Changed calls to fixup
+ store, swap and restore fuctions to reflect the new interface.
+
+2001-07-06 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-m68k.c (md_estimate_size_before_relax): Catch and
+ ignore empty, ineffectual alignment frags when deciding if a
+ branch can be short.
+
+2001-07-05 Steve Ellcey <sje@cup.hp.com>
+
+ * config/tc-ia64.c (special_section): Add SPECIAL_SECTION_INIT_ARRAY
+ and SPECIAL_SECTION_FINI_ARRAY.
+ (special_section_name): Add .init_array and .fini_array.
+ (md_pseudo_table): Add init_array and fini_array.
+ (md): Add pointer_size and pointer_size_shift fields.
+ (setup_unwind_header): New static function.
+ (output_unw_records): Modify to use setup_unwind_header.
+ (generate_unwind_image, dot_endp): Modify to use md.pointer_size and
+ md.pointer_size_shift.
+ (md_begin): Initialize md.pointer_size and md.pointer_size_shift.
+
+2001-07-05 Ben Elliston <bje@redhat.com>
+
+ * README (Supported platforms): m88k no longer suffers bitrot.
+
+ * config/tc-m88k.c (md_pseudo_table): Remove redundant "global".
+
+2001-07-05 Alan Modra <amodra@bigpond.net.au>
+
+ * struc-symbol.h (struct local_symbol): Rename lsy_offset to
+ lsy_value. Correct typos in comments.
+ * symbols.c (local_symbol_make): Update for name change.
+ (local_symbol_convert): Likewise.
+ (colon): Likewise.
+ (S_GET_VALUE): Likewise.
+ (S_SET_VALUE): Likewise.
+ (print_symbol_value_1): Likewise.
+ (resolve_symbol_value): Likewise. Don't divide local sym values
+ by OCTETS_PER_BYTE twice.
+
+2001-07-04 Jim Wilson <wilson@redhat.com>
+
+ * config/tc-ia64.c (md_pseudo_table): Add 2byte, 4byte, and 8byte.
+
+ * config/tc-ia64.c (is_conditional_branch): Rewrite to exclude mod
+ sched branches.
+
+2001-07-05 Ben Elliston <bje@redhat.com>
+
+ * read.c (s_fill): Correct spelling error in comments.
+
+ * doc/c-m88k.texi: New file.
+ * doc/Makefile.am (CPU_DOCS): Add c-m88k.texi.
+ * doc/Makefile.in: Regenerate.
+ * doc/all.texi: Set M880X0.
+ * doc/as.texinfo: Hook in m88k-dependent documentation.
+
+2001-07-04 Eric Christopher <echristo@redhat.com>
+
+ * doc/c-mips.texi (MIPS Opts): Document 12000 as valid cpu.
+
+ * config/tc-mips.c (mips_cpu_info_table): Add rm5200, rm5231, rm5261,
+ and rm5721 as valid cpu strings.
+ (md_show_usage): Add rm5200, rm5231, rm5261, rm5721.
+
+2001-07-04 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (md_apply_fix): Prevent addend from becoming zero
+ if it's expected to be non-zero.
+
+2001-07-03 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-sh.c (sh_frob_section): Replace symbol_get_frag() with
+ fscan->fx_frag.
+
+ * write.c (TC_FINALIZE_SYMS_BEFORE_SIZE_SEG): Default to 1.
+ (write_object_file): Set finalize_syms to
+ TC_FINALIZE_SYMS_BEFORE_SIZE_SEG just before size_segs is
+ called.
+
+ * doc/internals.texi: Document
+ TC_FINALIZE_SYMS_BEFORE_SIZE_SEG.
+
+2001-07-02 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c: Formatting fixes.
+
+2001-07-01 Ben Elliston <bje@redhat.com>
+
+ * config/tc-m88k.c: Back out warning fixes from 2001-06-24, as
+ they cause some subtle breakage. Will fix them again later.
+
+2001-06-28 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/obj-coff.c (obj_coff_ln): Treat a .ln directive
+ outside of a function as a .appline directive.
+
+2001-06-28 Eric Christopher <echristo@redhat.com>
+ H.J. Lu <hjl@gnu.org>
+
+ * config/tc-mips.c (mips_arch): New. Use mips_arch instead
+ of mips_cpu for the ISA selection.
+ (md_longopts): Add OPTION_MARCH and OPTION_MTUNE.
+ (md_parse_option): Handle OPTION_MARCH and OPTION_MTUNE.
+ (mips_tune): New. Use mips_tune for scheduling and optimization
+ issues.
+ (append_insn): Use mips_tune and mips_arch.
+ (macro_build): Ditto.
+ (mips_ip): Ditto.
+ (md_begin): Handle mips_arch, mips_tune and mips_cpu. For
+ backwards compatability mips_cpu generates arch and tune.
+ (md_show_usage): Document new behavior.
+
+ * doc/c-mips.texi (MIPS Opts): Document -march and -mtune.
+ Deprecate -mcpu.
+
+ * NEWS: Update.
+
+2001-06-27 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * write.c (write_object_file): Do not set finalize_syms until
+ after the segments have been sized. Some backends may still
+ need to access the syms's frags in order to adjust relaxed
+ frags.
+
+ * config/tc-arm.c (do_ldst): Use MVN to build simple inverted
+ constants.
+
+2001-06-27 Alan Modra <amodra@bigpond.net.au>
+
+ * write.c (fixup_segment <Difference of 2 syms same seg>): Don't
+ subtract MD_PCREL_FROM_SECTION for 68k.
+ (fixup_segment <Difference of 2 syms different seg>): Only fudge
+ by adding MD_PCREL_FROM_SECTION for 68k or if not already pcrel.
+
+2001-06-27 Tracy A. Kuhrt <Tracy.Kuhrt@microchip.com>
+
+ * write.c (fixup_segment <Difference of 2 syms same seg>): If
+ pcrel, subtract MD_PCREL_FROM_SECTION value.
+
+2001-06-24 Ben Elliston <bje@redhat.com>
+
+ * stabs.c (generate_asm_file): Make local variable `len' a size_t.
+
+2001-06-24 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-alpha.c (tc_gen_reloc): Handle relocs against SEC_MERGE
+ section symbols the same way as externs.
+
+2001-06-24 Ben Elliston <bje@redhat.com>
+
+ * config/tc-m88k.c (md_number_to_imm): Remove; unused since 1993.
+ (emit_relocations): Ditto.
+ (s_bss): Ditto.
+ (md_begin): Reformat comments to conform to the GNU standards.
+ (md_assemble): Ditto.
+
+ * config/tc-m88k.c (get_reg): Adjust type of `reg_prefix' to char.
+ (md_parse_option): Mark parameters as unused.
+ (md_show_usage): Ditto.
+ (calcop): Adjust type of `reg_prefix' to char.
+ (get_reg): Ditto.
+ (getval): Adjust type of local `c' to char.
+ (md_create_short_jump): Mark from_addr, to_addr params as unused.
+ (md_create_long_jump): Ditto.
+ (md_estimate_size_before_relax): Mark parameters as unused.
+
+ * config/tc-m88k.c (md_pseudo_table): Properly terminate the table
+ to allay a possible compiler warning.
+
+2001-06-22 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * doc/internals.texi (CPU backend): Document md_atof.
+
+2001-06-22 Matthew Wilcox <willy@ldl.fc.hp.com>
+
+ * config/tc-hppa.c (pre_defined_registers): Add %mrp (millicode
+ return pointer) alias for %r2 or %r31, depending on 32 or 64 bit
+ architecture.
+
+2001-06-21 Philip Blundell <philb@gnu.org>
+
+ * config/tc-arm.c (cplong_flag): Rename to long_flag. All uses
+ updated.
+ (insns): Remove entry for adrl. Add long_flag for adr.
+ (do_adr): Handle `l' suffix.
+ (do_adrl): Delete.
+
+2001-06-21 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-hppa.c (CHECK_FIELD_WHERE): Define.
+ (md_apply_fix): Use it here. Replace printf with equivalent
+ as_bad_where.
+ (tc_gen_reloc): Use as_bad_where instead of as_bad.
+ (md_apply_fix): Here too.
+ * config/tc-i386.c (tc_gen_reloc): Use as_bad_where instead of as_bad.
+ * config/tc-m68k.c (tc_gen_reloc): Likewise.
+ (md_convert_frag_1): Likewise.
+
+2000-06-20 Tom Rix <trix@redhat.com>
+
+ * config/tc-ppc.c (ppc_comm): Change default alignment to 4 bytes.
+
+2001-06-18 H.J. Lu <hjl@gnu.org>
+
+ * doc/Makefile.am (info): Depend on $(MANS).
+ (as.1): Remove the prefix `$(srcdir)/'.
+ * doc/Makefile.in: Regenerated.
+
+ * as.1: Removed.
+
+2001-06-18 Philip Blundell <philb@gnu.org>
+
+ * config/tc-arm.c (do_msr): Remove restriction on usage of
+ immediate operands.
+
+2001-06-19 Alan Modra <amodra@bigpond.net.au>
+
+ * dwarf2dbg.c (dwarf2_finish): Output file info even when no
+ line info.
+
+2001-06-13 Philip Blundell <philb@gnu.org>
+
+ * config/tc-arm.c (thumb_shift): Improve wording of error message.
+ (do_t_arit): Likewise.
+
+2001-06-13 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-sh.c (md_pseudo_table): Only intercept the .file and
+ .loc pseudos if the dfwarf2 functions are available.
+ (md_assemble): Only call dwarf2_emit_insn if it is available.
+
+ * expr.c: Fix typo in comment.
+
+2001-06-12 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * doc/as.texinfo (Infix Ops): Document that comparison and
+ combiner operators can be used as infix operators.
+
+2001-06-12 Peter Jakubek <pjak@snafu.de>
+
+ * config/tc-m68k.c (parse_mri_control_operand): Fix handling
+ of AND/OR.
+ (swap_mri_condition): Add HS (alias fo CC) and LO (alias for CS).
+ (reverse_mri_condition): Likewise.
+ (swap_mri_condition): Issue warning for conditions that can not be
+ swapped.
+ (build_mri_control_operand): Fix order of operands (swapped).
+ (build_mri_control_operand): Allow upper case extension in structured
+ control directives.
+ (s_mri_else): Likewise.
+ (s_mri_next): Likewise.
+ (s_mri_for): Likewise.
+ (s_mri_if): Fix handling comment ('*') in mri mode.
+ (s_mri_while): Likewise.
+ * macro.c (macro_expand): Allow macro invocation with empty
+ extension.
+
+2001-06-12 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-arm.c: Fix test for overlow of literal pool.
+
+2001-06-11 H.J. Lu <hjl@gnu.org>
+
+ * NEWS: Updated for the new -n option for the MIPS assembler.
+
+ * config/tc-mips.c (md_show_usage): Add -n.
+
+ * doc/as.texinfo: Document the new -n option.
+ * doc/c-mips.texi: Likewise.
+ * doc/as.1: Regenerated.
+
+2001-06-10 Alan Modra <amodra@bigpond.net.au>
+
+ * config/obj-coff.c (obj_coff_section): Formatting fix.
+
+ * config/tc-i386.c (md_assemble): Accept branch hints as ",pt" and
+ ",pn".
+
+2001-06-08 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-mips.c (warn_nops): New variable. Set to 0 to
+ disable warning about all NOPS that the assembler generates.
+ (macro): Warn NOPS generated only if warn_nops is not 0.
+ (md_shortopts): Add `n'.
+ (md_parse_option): Set warn_nops to 1 for `n'.
+
+2001-06-08 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-mips.c (mips_ip): Properly handle illegal operands.
+
+2001-06-08 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-mips.c (md_apply_fix): Don't adjust common
+ extern/weak symbols for ELF.
+ (md_estimate_size_before_relax): Treat weak like extern for
+ ELF.
+ (mips_fix_adjustable): Don't adjust extern/weak symbols for
+ ELF.
+
+2001-06-08 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: 'som' is not wrongly spelled 'some'.
+ * Makefile.in: Regenerate.
+
+ * config/tc-mips.c (mips16_mark_labels): Reduce number of calls to
+ S_GET_VALUE by using a temp.
+ (append_insn): Likewise, and for S_SET_VALUE too.
+ (mips_emit_delays): Likewise.
+ (my_getExpression): Likewise.
+ (md_apply_fix): Likewise. Use "valueT" rather than "long" for "value".
+ (mips16_extended_frag): Remove code concerned with avoiding
+ locking in a frag address now that symbols are not finalized until
+ relaxation is complete. Cater for first relaxation pass having
+ bogus addresses. Use relax_marker to reliably determine whether a
+ symbol frag has been reached on the current pass.
+
+2001-06-07 H.J. Lu <hjl@gnu.org>
+
+ * configure.in: Move "mips-*-linux-gnu*" before "mips-*-gnu*".
+ * configure: Regenerate.
+
+2001-06-07 H.J. Lu <hjl@gnu.org>
+
+ * configure.in: Use MIPS_STABS_ELF for Linux/mips and remove
+ ecoff emulation.
+ * configure: Regenerate.
+
+2001-06-07 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-mips.c (mips_pseudo_table): Add "extern" if
+ MIPS_STABS_ELF is defined.
+
+2001-06-06 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * as.c (show_usage): Remove L from listing options. It is not a
+ generic option.
+
+2001-06-06 Christian Groessler <cpg@aladdin.de>
+
+ * config/tc-z8k.c: Removed many warnings by removing unused
+ variables and tagging unused parameters as such.
+ (md_begin): Fixed a typo (","instead of ";").
+ (struct ctrl_table): Add parentheses to initialize array
+ correctly.
+ (struct flag_table): Likewise.
+ (struct intr_table): Likewise.
+ (struct table): Likewise.
+ (check_operand): "#if 0"'ed since it doesn't seem to be used.
+
+2001-06-06 Peter Jakubek <pjak@snafu.de>
+
+ * config/tc-m68k.c (md_show_usage): Add all supported ColdFire
+ options to list (e.g. m5206e, m5307, m5407).
+
+2001-06-06 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.h (TC_FORCE_RELOCATION): Always emit relocations
+ BFD_RELOC_VTABLE_INHERIT and BFD_RELOC_VTABLE_ENTRY.
+
+2001-06-06 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.c (md_assemble): Handle Pentium4 branch hints.
+ <JumpByte, JumpDword insn output>: Remove dead code.
+
+2001-06-06 Tracy Kuhrt <Tracy.Kuhrt@microchip.com>
+
+ * as.c (parse_args): Correct option name "listing-lhs-width2".
+
+2001-06-05 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * symbols.c (S_SET_EXTERNAL): Do not override a section symbol's
+ status.
+
+2001-05-30 Richard Henderson <rth@redhat.com>
+
+ * read.c (emit_leb128_expr): Call md_cons_align.
+
+2001-05-28 Jeff Sturm <jsturm@one-point.com>
+
+ * config/tc-sparc.c (md_apply_fix3): Handle BFD_RELOC_SPARC_UA16,
+ BFD_RELOC_SPARC_UA32 and BFD_RELOC_SPARC_UA64.
+ (tc_gen_reloc): Likewise.
+ (sparc_cons_align): Don't clear sparc_no_align_cons.
+ (cons_fix_new_sparc): Substitute BFD_RELOC_SPARC_UA{16|32|64} for
+ BFD_RELOC_{16|32|64} iff sparc_no_align_cons is set.
+
+2001-05-27 Alan Modra <amodra@one.net.au>
+
+ * write.c (relax_segment <rs_space>): Check the section of a
+ symbol to determine whether it is absolute rather than comparing
+ its frag against zero_address_frag as listings play tricks with
+ frags.
+
+ * config/tc-m68k.c (md_assemble): Ensure variable part of frag is
+ allocated in the same chunk as the fixed part.
+
+2001-05-26 Alan Modra <amodra@one.net.au>
+
+ * write.c (relax_segment <rs_space>): Calculate growth using
+ addresses before stretch. Prevent repeated error messages.
+ From Peter Jakubek <pjak@snafu.de>
+ Use as_bad_where and as_warn_where to pinpoint errors.
+
+2001-05-25 Alan Modra <amodra@one.net.au>
+
+ * symbols.c (resolve_symbol_value): Always set segment, even when
+ not finalizing symbol value.
+
+ * config/obj-ieee.c (write_object_file): Set finalize_syms.
+ * config/obj-coff.c (write_object_file): Likewise.
+ * (size_section): Remove rs_space assert as fr_symbol is no longer
+ removed.
+ (fill_section): Likewise.
+
+ * configure.in: Replace linuxoldld with linux*oldld.
+ * configure: Regenerate.
+
+ From 2.11 branch 2001-03-30 Richard Henderson <rth@redhat.com>
+ * config/tc-i386.c (md_convert_frag): Don't die on local symbols
+ that have been finalized.
+
+ * symbols.c (resolve_symbol_value): Clear sy_resolving before
+ taking exit_dont_set_value.
+
+ * write.c (relax_segment <rs_space>): Don't zap fr_symbol when
+ relaxing.
+
+2000-05-24 Tom Rix <trix@redhat.com>
+
+ * config/obj-coff.c (add_lineno): xcoff allows negative line
+ numbers
+ * config/tc-ppc.c (ppc_stabx): fix generated symbol
+
+2001-05-24 Alan Modra <amodra@one.net.au>
+
+ * write.c (write_object_file): Set finalize_syms = 1 before
+ size_seg is called.
+
+2001-05-23 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (ISA_HAS_64BIT_REGS): Add ISA_MIPS64 as 64 bit
+ architecture, remove erraneous ISA_MIPS32.
+ (md_show_usage): Add MIPS r12k support.
+ (mips_cpu_info_table): Add MIPS r12k support.
+
+2001-05-22 Alan Modra <amodra@one.net.au>
+
+ * config/tc-arc.c (md_assemble): Use is_end_of_line instead of
+ testing for NULs.
+
+ * symbols.c (resolve_symbol_value): Remove "finalize" param,
+ instead use finalize_syms directly. Don't treat expressions
+ specially with regard to finalize_syms. Update calls to self.
+ (resolve_local_symbol): Update call to resolve_symbol_value.
+ (S_GET_VALUE): Likewise. Return resolve_symbol_value if
+ !finalize_syms.
+ * symbols.h (resolve_symbol_value): Update prototype.
+ * config/obj-aout.c (obj_crawl_symbol_chain): Update call
+ to resolve_symbol_value.
+ * config/obj-bout.c (obj_crawl_symbol_chain): Likewise.
+ * config/obj-coff.c (do_relocs_for): Likewise.
+ (yank_symbols): Likewise.
+ (fixup_segment): Likewise.
+ * config/obj-vms.c (obj_crawl_symbol_chain): Likewise.
+ * config/tc-mips.c (md_convert_frag): Likewise.
+ * config/tc-ppc.c (ppc_frob_symbol): Likewise.
+ (ppc_fix_adjustable): Likewise.
+ * dwarf2dbg.c (dwarf2dbg_estimate_size_before_relax): Likewise.
+ (dwarf2dbg_convert_frag): Likewise.
+ * ehopt.c (eh_frame_estimate_size_before_relax): Likewise.
+ (eh_frame_convert_frag): Likewise.
+ * expr.c (make_expr_symbol): Likewise.
+ * write.c (adjust_reloc_syms): Likewise.
+ (write_object_file): Likewise.
+ (relax_segment): Likewise.
+ (fixup_segment): Likewise.
+ (finalize_syms): Init to zero, and update comment.
+ (write_object_file): Set finalize_syms to 1 rather than 2.
+ * doc/internals.texi (sy_value): Mention finalize_syms.
+ (S_GET_VALUE): Remove restriction on when S_GET_VALUE can be called.
+
+ * config/tc-m68k.c (relaxable_symbol): Only treat external symbols
+ as relaxable if embedded system, make weak syms non-relaxable.
+ Move definition..
+ (tc_m68k_fix_adjustable): ..so it can be used here.
+ (md_apply_fix_2): Sign extend without conditional.
+
+ * config/tc-v850.c: Update copyright.
+
+2001-05-16 Jeff Johnston <jjohnstn@redhat.com>
+
+ * cgen.c (gas_cgen_tc_gen_reloc): Changed error message when
+ howto entry is not found.
+
+2001-05-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mn10300.c (mn10300_force_relocation): Don't
+ optimize differences between symbols in code sections to
+ constants.
+ (mn10300_fix_adjustable): Don't adjust to section+offset
+ relocations pointing at symbols in code sections.
+
+2001-05-16 Alan Modra <amodra@one.net.au>
+
+ * config/tc-arc.c (md_assemble): Correct dwarf2_emit_insn param
+ for 8 byte insns.
+ * config/tc-i386.c (md_assemble): Call dwarf2_emit_insn before
+ opcodes are output rather than after. Delete insn_size.
+ * config/tc-v850.c (md_assemble): Similarly, but delete
+ total_insn_size.
+
+2001-05-14 Richard Henderson <rth@redhat.com>
+
+ * ehopt.c (eh_frame_convert_frag): Fix missed subtype adjustment
+ last change.
+
+2001-05-14 Richard Henderson <rth@redhat.com>
+
+ * ehopt.c (get_cie_info): Rename from eh_frame_code_alignment;
+ also collect whether to expect an FDE augmentation.
+ (check_eh_frame): Rewrite as a state machine. Track where in
+ an FDE we are located, skip any augmentation.
+ (eh_frame_estimate_size_before_relax): Get code alignment from
+ the fragment subtype.
+ (eh_frame_relax_frag, eh_frame_convert_frag): Likewise.
+ * read.c (emit_leb128_expr): Call check_eh_frame.
+
+2001-05-14 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mn10300.c (md_assemble): Anchor dwarf2 line info
+ before a relaxable insns.
+
+2001-05-13 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mn10300.c (tc_gen_reloc): Don't reject differences
+ between symbols if the base symbol is in the current section;
+ emit a PC-relative relocation instead.
+
+2001-05-12 Peter Targett <peter.targett@arccores.com>
+
+ * config/tc-arc.c: Update copyright and tidy source comments.
+ (md_pseudo_table): Add directive .cpu back as an alias for
+ .option. Add .file and .line for dwarf2 support.
+ (arc_mach_type): Make bfd_mach_arc_6 default.
+ (md_longopts): Add entry 'pre-v6' representing old command line
+ option when assembling for 'arc5' core versions.
+ (md_parse_option): Make OPTION_ARC same as OPTION_ARC6, for new
+ default behaviour.
+ (arc_code_symbol): Make symbol value for @h30 fixup expression
+ equal to O_constant.
+ (md_assemble): Call dwarf2_emit_insn.
+ Include "dwarf2dbg2.h". Formatting fixes throughout file.
+ * config/tc-arc.h (DWARF2_LINE_MIN_INSN_LENGTH): Define.
+ * doc/c-arc.texi (ARC_CORE_DEFAULT): Update to new default.
+
+2001-05-11 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-ia64.c (special_linkonce_name): New.
+ (make_unw_section): Map .gnu.linkonce.t.FOO text section into
+ .gnu.linkonce.ia64unw{,i}.FOO.
+ (ia64_elf_section_type): Handle .gnu.linkonce.ia64unw{,i}.FOO.
+ (dot_endp): Add comment about it.
+
+2001-05-11 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-arm.c (arm_handle_align): When truncating an aligned
+ block, ensure that the low order bits of the alignment are
+ preserved.
+
+2001-05-10 Alan Modra <amodra@one.net.au>
+
+ * config/obj-vms.c (obj_crawl_symbol_chain): Don't take address of
+ symbol_next.
+
+ * config/tc-fr30.c (md_estimate_size_before_relax): Return size of
+ current variable part of frag.
+ * config/tc-m32r.c (md_estimate_size_before_relax): Likewise.
+ * config/tc-openrisc.c (md_estimate_size_before_relax): Likewise.
+ * config/tc-m68hc11.c (RELAX_STATE): Define.
+ (RELAX_LENGTH): Define.
+ (md_estimate_size_before_relax): Handle non-relaxable cases
+ separately from relaxable cases for clarity, and return correct
+ size for multi-pass relaxation.
+ * config/tc-tahoe.c (RELAX_LENGTH): Correct.
+ (md_estimate_size_before_relax): As for tc-m68hc11.c.
+ (md_convert_frag): Remove "length_code".
+ * config/tc-vax.c (RELAX_STATE): Define.
+ (RELAX_LENGTH): Define.
+ (md_relax_table): Add missing entry.
+ (md_estimate_size_before_relax): As for tc-m68hc11.c.
+ (md_convert_frag): Remove "length_code".
+ * config/tc-ns32k.c (md_estimate_size_before_relax): Simplify and
+ don't bother setting fr_var. Return correct size for multi-pass
+ relaxation.
+ * config/tc-v850.c (md_estimate_size_before_relax): Rewrite.
+ (md_convert_frag): Don't bother clearing fr_var.
+ (md_pseudo_table): Correct initialization.
+ * config/tc-h8500.c (md_convert_frag): Don't bother clearing fr_var.
+ (md_estimate_size_before_relax): No need to set fr_var.
+ * config/tc-mcore.c (md_convert_frag): Don't bother clearing fr_var.
+ (md_estimate_size_before_relax): No need to set fr_var.
+
+2001-05-09 Richard Henderson <rth@redhat.com>
+
+ * config/tc-ia64.c (generate_unwind_image): Align the fragment
+ beginning a function's unwind info block.
+
+2001-05-09 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mn10300.c (md_apply_fix3): Accept PC-relative relocs.
+
+2001-05-08 Andreas Schwab <schwab@suse.de>
+
+ * config/tc-m68k.c: Instead of replacing -1 by 64 in assignment to
+ fx_pcrel_adjust explicitly sign extend when reading it.
+
+2001-05-08 Alan Modra <amodra@one.net.au>
+
+ * config/tc-m68k.c (md_estimate_size_before_relax): Set fr_var
+ from md_relax_table, and combine some switch cases.
+
+2001-05-06 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mn10300.c (md_assemble): Subtract operand->shift
+ from offset in non-pcrel operands too.
+
+2001-05-06 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-arm.h (MAX_MEM_FOR_RS_ALIGN_CODE): Define.
+ * config/tc-arm.c (arm_handle_align): Do not insert more than
+ MAX_MEM_FOR_RS_ALIGN_CODE bytes.
+ (arm_frag_align_code): Use MAX_MEM_FOR_RS_ALIGN_CODE.
+
+2001-05-03 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * Makefile.am (TARG_ENV_HFILES): Add te-hppa64.h and te-hppalinux64.h.
+ Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * configure.in: Remove duplicate mips-*-ecoff* entry.
+ * configure: Regenerate.
+
+ * config/obj-ecoff.c (obj_pseudo_table): Fix terminating entry.
+ (n_names): Cast away type mismatch.
+ (ecoff_sec_sym_ok_for_reloc): Add unused attribute.
+ (obj_ecoff_frob_symbol): Likewise.
+ * ecoff.c: (add_file): Add unused attribute.
+ (ecoff_directive_begin): Likewise.
+ (ecoff_directive_bend): Likewise.
+ (ecoff_directive_def): Likewise.
+ (ecoff_directive_dim): Likewise.
+ (ecoff_directive_scl): Likewise.
+ (ecoff_directive_size): Likewise.
+ (ecoff_directive_type): Likewise.
+ (ecoff_directive_tag): Likewise.
+ (ecoff_directive_val): Likewise.
+ (ecoff_directive_endef): Likewise.
+ (ecoff_directive_end): Likewise.
+ (ecoff_directive_ent): Likewise.
+ (ecoff_directive_extern): Likewise.
+ (ecoff_directive_file): Likewise.
+ (ecoff_directive_fmask): Likewise.
+ (ecoff_directive_frame): Likewise.
+ (ecoff_directive_mask): Likewise.
+ (ecoff_directive_loc): Likewise.
+ (mark_stabs): Likewise.
+ (ecoff_stab): Likewise.
+ (ecoff_frob_symbol): Cast away type mismatch.
+ (ecoff_padding_adjust): Likewise.
+ (ecoff_build_symbols): Likewise.
+ (ecoff_build_procs): Likewise.
+ (ecoff_build_aux): Likewise.
+ (ecoff_build_strings): Likewise.
+ (ecoff_build_fdr): Likewise.
+ (ecoff_build_debug): Likewise.
+ * itbl-ops.c (itbl_assemble): Variable initialization.
+
+2001-05-03 Alan Modra <amodra@one.net.au>
+
+ * config/tc-i386.c (i386_displacement): Call as_bad for bad GOTOFF
+ expressions rather than triggering an assert.
+
+2001-05-02 Johan Rydberg <jrydberg@opencores.org>
+
+ * config/tc-openrisc.c: New file.
+ * config/tc-openrisc.h: Likewise.
+
+ * Makefile.am: Add OpenRISC target.
+ * Makefile.in: Regenerated.
+
+ * configure.in (openrisc-*-*): Add target.
+ * configure: Regenerated.
+
+2001-05-02 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-arm.c (arm_frag_align_code): Change error message to
+ more explanatory version.
+
+2001-04-29 Keith M Wesolowski <wesolows@foobazco.org>
+
+ * config/tc-mips.c (md_parse_option): Also accept
+ elf64-tradbigmips and elf64-tradlittlemips for OPTION_64.
+
+2001-04-27 David Mosberger <davidm@hpl.hp.com>
+
+ * config/tc-ia64.c (dot_spillmem_p): Fix output_spill_?sprel_p()
+ argument passing order: predicate goes last, not first.
+
+2001-04-27 Sean McNeil <sean@mcneil.com>
+
+ * configure.in: Add arm-vxworks.
+ * configure: Regenerate.
+
+2001-04-26 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-arm.c (arm_handle_align): New Function: Generate
+ no-op filled alignment frags.
+ (arm_frag_align_code): New Function: Create a code alignment frag.
+ (arm_init_frag): New Function: Initialse the target dependent
+ parts of a frag.
+
+ * config/tc-arm.h (TC_FRAG_TYPE): Define.
+ (TC_FRAG_INIT): Define.
+ (HANDLE_ALIGN): Define.
+ (md_do_align): Define.
+
+2001-04-25 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/obj-coff.c (do_linenos_for): Check to see if the filename
+ symbol has been initialised before extracting its symbol index.
+
+2001-04-24 H.J. Lu <hjl@gnu.org>
+
+ * configure: Regenerated with the right version of autoconf.
+
+2001-04-24 Christian Groessler <cpg@aladdin.de>
+
+ * config/tc-z8k.c (build_bytes): 12 and 16 bit displacements now
+ generate R_CALLR and R_REL16 relocations
+
+2000-04-20 Jason Eckhardt <jle@redhat.com>
+
+ * config/tc-d10v.h (tc_frob_label): Update the symbol's frag
+ since frag_now can change after d10v_cleanup is called.
+
+2001-04-16 David O'Brien <obrien@FreeBSD.org>
+
+ * configure.in: Add the em type for FreeBSD targets.
+ * configure: Regenerate.
+
+2001-04-14 Alexandre Oliva <aoliva@redhat.com>
+
+ * struc-symbol.h (struct local_symbol): New TC_LOCAL_SYMFIELD_TYPE.
+ * symbols.c (local_symbol_convert): Call TC_LOCAL_SYMFIELD_CONVERT.
+
+ * config/tc-mn10300.c (md_assemble): Simplify offset adjustment of
+ pc-relative relocations not placed at the end of the instruction.
+
+2001-04-13 Jim Wilson <wilson@redhat.com>
+
+ * tc-ia64.c (is_conditional_branch): Return true for br, brl, and br.
+ excluding br.i.
+
+2001-04-13 Jakub Jelinek <jakub@redhat.com>
+
+ * config/obj-elf.c (obj_elf_change_section): Add entsize argument,
+ handle SHF_MERGE and SHF_STRINGS.
+ (obj_elf_parse_section_letters): Set SHF_MERGE and SHF_STRINGS.
+ (obj_elf_section): Allow additional argument specifying entity size.
+ * write.c (adjust_reloc_syms): Keep relocations against local symbols
+ in SEC_MERGE sections.
+
+2001-04-12 Jason Merrill <jason_merrill@redhat.com>
+
+ * dwarf2dbg.c (process_entries): Don't optimize redundant line notes.
+
+2001-04-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * expr.c (operand): Pass &c to md_parse_name().
+ * config/tc-ia64.h, config/tc-ppc.h, config/tc-tic54x.h: Adjust.
+
+2001-04-07 Steven J. Hill <sjhill@cotw.com>
+
+ * config/tc-mips.c: Support ELF64 for traditional MIPS targets.
+
+ * Makefile.am: (TARG_ENV_HFILES): Add tc-mips.h.
+ * Makefile.in: Regenerated.
+
+ * configure.in: Use traditional MIPS targets for Linux/MIPS.
+ * configure: Regenerated.
+
+2001-04-06 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mn10300.c (xr_registers): Added `pc'.
+
+2001-04-05 Alan Modra <alan@linuxcare.com.au>
+
+ * configure.in: Add h8500-*-coff and h8500-*-rtems targets.
+ * configure: Regenerate.
+
+ * config/tc-h8500.c (md_estimate_size_before_relax): Add missing
+ cases, and always return size based on current fr_subtype.
+ (md_begin): Move initialization of md_relax_table..
+ (md_relax_table): ..to static initializer. Set rlx_length for
+ UNDEF_WORD_DISP cases.
+ * config/tc-w65.c (md_estimate_size_before_relax): Likewise.
+ (md_begin): Likewise.
+ (md_relax_table): Likewise.
+ * config/tc-mcore.c (md_estimate_size_before_relax): Likewise.
+ (md_relax_table): Set rlx_length for UNDEF_WORD_DISP cases.
+ Set rlx_backward and rlx_forward to zero for unused states.
+ * config/tc-sh.c (md_estimate_size_before_relax): Likewise.
+ (md_relax_table): Set rlx_length for UNDEF_WORD_DISP cases.
+ (UNCOND12, UNCOND32): Remove duplicate defines.
+
+2001-04-04 Hans-Peter Nilsson <hp@axis.com>
+
+ * config/tc-cris.c (md_estimate_size_before_relax) <case
+ ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF)>: Don't emit
+ 32-bit branch, just set fragP->fr_subtype. Set fragP->fr_var.
+ <all cases>: Always set fragP->fr_var using md_cris_relax_table.
+ Add cases to cover all relax states.
+ (cris_insn_first_word_frag): New.
+ (md_assemble): Call cris_insn_first_word_frag to get the first
+ frag in an insn, not frag_more. Don't call dwarf2_emit_insn at
+ end. Drop variable insn_size.
+ (gen_bdap): Call cris_insn_first_word_frag, not frag_more.
+ (cris_sym_leading_underscore): Wrap first as_bad parameter in _().
+ (cris_sym_no_leading_underscore, s_cris_file, s_cris_loc): Ditto.
+
+ * write.c (write_object_file): Reset broken word state before
+ calling relax_seg.
+
+2001-03-31 Alan Modra <alan@linuxcare.com.au>
+
+ * listing.c (listing_listing): Enable listing on EDICT_NOLIST_NEXT
+ for one line if not already enabled.
+ * cond.c (s_elseif): Correct conditional assembly listing.
+ (s_else): Likewise.
+
+ * cond.c (s_endif): Correct handling of "if .. elseif .." trees.
+ Don't abort on NULL current_cframe.
+
+2001-03-30 Alan Modra <alan@linuxcare.com.au>
+
+ * dwarf2dbg.c (dwarf2_directive_file): Fix warnings.
+ (dwarf2dbg_convert_frag): Pass `finalize_syms' to resolve_symbol_value.
+ * config/obj-aout.c (obj_crawl_symbol_chain): Likewise.
+ * config/obj-bout.c (obj_crawl_symbol_chain): Likewise.
+ * config/obj-coff.c (do_relocs_for): Likewise.
+ (yank_symbols): Likewise.
+ (fixup_segment): Likewise.
+ * config/tc-ppc.c (ppc_frob_symbol): Likewise.
+ (ppc_fix_adjustable): Likewise.
+ * config/tc-mips.c (md_convert_frag): Likewise.
+ * config/obj-vms.c (obj_crawl_symbol_chain): Likewise.
+ * ehopt.c (eh_frame_convert_frag): Likewise.
+ * expr.c (make_expr_symbol): Likewise.
+
+ * frags.h (struct frag): Add last_fr_address. Reorder fields for
+ better packing.
+ * symbols.c (resolve_symbol_value): Don't fix expression values
+ until relaxation is complete.
+ (resolve_local_symbol): Pass `finalize_syms' to resolve_symbol_value.
+ (S_GET_VALUE): Likewise, and return unresolved expression value.
+ * write.c (finalize_syms): New.
+ (relax_and_size_seg): Split into..
+ (relax_seg): New function, returns 1 if anything changed..
+ (size_seg): And the remainder of relax_and_size_seg.
+ (fixup_segment): Arrange for final resolution of sym values.
+ (adjust_reloc_syms): Likewise.
+ (write_object_file): Likewise, and repeatedly call relax_seg until
+ nothing more changes.
+ (relax_segment): Return 1 if anything changed. Use correct types
+ for rs_org `target' and `after'.
+ * write.h (finalize_syms): Declare.
+ (relax_segment): Update prototype.
+
+ * config/tc-sh.c (md_estimate_size_before_relax): Add extra
+ do-nothing cases to switch to avoid abort on a second relaxation
+ pass, and tidy code a little.
+ * config/tc-cris.c (md_estimate_size_before_relax): Likewise.
+ * config/tc-h8500.c (md_estimate_size_before_relax): Likewise.
+ * config/tc-w65.c (md_estimate_size_before_relax): Likewise.
+ * config/tc-i386.c (UNCOND_JUMP, COND_JUMP, COND_JUMP86): Decrement.
+ (md_relax_table): Remove first four unused entries. Increment
+ rlx_length by one throughout table, and update comments to suit.
+ (md_estimate_size_before_relax): Return size of current variable
+ part of frag to reflect reality when relaxing more than once.
+ * config/tc-mcore.c (COND12, UNCD12): Rename to DISP12 throughout.
+ (COND32, UNCD32): Rename to DISP32 throughout.
+ (UNDEF_WORD_DISP): Renumber to 3.
+ (md_estimate_size_before_relax): Add extra do-nothing cases.
+ * config/tc-mn10200.c (md_estimate_size_before_relax): Rewrite.
+ * config/tc-mn10300.c (md_estimate_size_before_relax): Rewrite.
+ * config/tc-ns32k.c (md_estimate_size_before_relax): Add cases to
+ handle word and dword branches.
+
+2001-03-29 Hans-Peter Nilsson <hp@axis.com>
+
+ * config/tc-cris.h (tc_fix_adjustable): Allow only
+ BFD_RELOC_CRIS_32_GOTREL of the PIC relocs.
+ * config/tc-cris.c (cris_get_pic_suffix): Correct reloc type in
+ example in comment to valid type.
+
+2001-03-28 H.J. Lu <hjl@gnu.org>
+
+ * read.c (equals): Set to local for COFF only if it hasn't been
+ defined before.
+
+2001-03-28 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.c (DEFAULT_LEVEL): Define.
+ (md_begin): Use it when setting default architecture.
+
+2001-03-27 Nick Papadonis <nick@coelacanth.com>
+
+ * read.c (equals): (for COFF) default symbols to being local.
+
+2001-03-27 Hans-Peter Nilsson <hp@axis.com>
+
+ * configure.in (cris-*-*): Change default emulation to criself.
+ (cris-*-*aout*): New rule.
+ * configure: Regenerate.
+
+2001-03-26 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.c (tc_s390_fix_adjustable): Add test for
+ BFD_RELOC_390_GOTENT.
+ * config/tc-s390.h (TC_RELOC_RTSYM_LOC_FIXUP): Add test for
+ BFD_RELOC_390_GOTENT.
+
+2001-03-26 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-s390.h (TC_FORCE_RELOCATION): Define.
+ * config/tc-s390.c (s390_force_relocation): New function: Force
+ relocations for VTINHERIT relocs.
+
+2001-03-23 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * doc/as.texinfo: Put @c man begin to generate the as man page.
+ When generating man, define all the variables. Re-organize some
+ options to obtain better indentation of man page.
+ * doc/Makefile.am (MANCONF, TEXI2POD, POD2MAN): New variable.
+ (as.1): Build from as.texinfo.
+ * doc/Makefile.in: Regenerate.Index: binutils/Makefile.am
+
+2001-03-25 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-i386.c (i386_scale): Accept an absolute expression for
+ scale factor, and return the end of the expression.
+ (i386_operand): Modify for above.
+
+2001-03-23 Nick Clifton <nickc@redhat.com>
+
+ * doc/as.texinfo: Document --listing-XXX command line switches.
+ Explain why listings behave differently when -pipe is used.
+
+2001-03-23 Richard Sandiford <rsandifo@redhat.com>
+
+ * write.c (fix_new_exp): Print an error if passed a register.
+
+2001-03-23 Hans-Peter Nilsson <hp@axis.com>
+
+ * config/tc-cris.c: Tweak attribution. Fix typos. PIC support.
+ (PIC_SUFFIX_CHAR): New macro.
+ (cris_get_pic_suffix, cris_get_pic_reloc_size): New functions.
+ (pic): New variable.
+ (md_longopts): New option --pic.
+ (OPTION_PIC): Define.
+ (md_estimate_size_before_relax): Tweak longish comment.
+ (md_create_long_jump): Make the long jumps generate ADD.D offset,PC.
+ (md_assemble): Handle a PIC relocation on prefix and normal
+ instruction operands.
+ <output_instruction.insn_type == CRIS_INSN_BRANCH>: Handle
+ "complex" operand expressions. Call frag_more outside
+ gen_cond_branch_32 parameter list.
+ (cris_process_instruction): Handle PIC relocs on parsed
+ operand expressions. Validize PIC reloc sizes.
+ (get_autoinc_prefix_or_indir_op): Handle PIC suffix.
+ (gen_bdap): Handle "complex" operand expressions.
+ (gen_cond_branch_32): Use as_warn_where, not as_warn. Use
+ ADD.D offset,PC as jump instruction if generating PIC. Generate
+ error instead of crashing on complex expressions.
+ (cris_number_to_imm): Add segT parameter. All callers changed.
+ Use segT parameter, not now_seg, for segment of fixup. Handle
+ PCREL relocations but check that they are fully resolved.
+ (md_parse_option): Handle OPTION_PIC.
+ (tc_gen_reloc): Handle PIC relocs.
+ (md_show_usage): Update for --pic.
+ (md_apply_fix3): Renamed from md_apply_fix.
+ (md_pcrel_from): Accept emitting PCREL relocs when ELF.
+ (md_cris_force_relocation): Force relocation for PIC relocs.
+
+ * config/tc-cris.h: Tweak attribution.
+ (MD_APPLY_FIX3): Define.
+ (IS_CRIS_PIC_RELOC): New macro.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Define.
+ (tc_fix_adjustable): Don't adjust a globally visible symbol when
+ generating ELF.
+ (tc_frob_symbol): Avoid emitting undefined symbols.
+
+2001-03-20 Alan Modra <alan@linuxcare.com.au>
+
+ * frags.h (struct frag): Add relax_marker.
+ * write.c (is_dnrange): Delete.
+ (relax_frag): Use correct types for `aim', `target', `address'.
+ Delete `offset', `was_address'. Test `relax_marker' instead of
+ using fragile (and slow) address test.
+ (relax_segment): Init and flip `relax_marker'.
+
+2001-03-19 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-i386.c (md_assemble <REGISTER_WARNINGS>): Correct
+ used register name.
+
+2001-03-18 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * config/tc-m68hc11.c (md_pseudo_table): Recognize xrefb to comply
+ with 'Motorola specification for assembly language input standard'.
+
+2001-03-17 Richard Henderson <rth@redhat.com>
+
+ * dwarf2dbg.c (user_filenum, user_filenum_allocated): Remove.
+ (dwarf2_directive_loc): Don't use them.
+ (dwarf2_directive_file): Reject duplicate file definitions.
+ (get_filenum): Zero allocated memory.
+ (out_file_list): Complain about missing file definitions.
+
+2001-03-17 Alan Modra <alan@linuxcare.com.au>
+
+ * read.c (do_org): Handle complex expressions.
+ * cgen.c (gas_cgen_finish_insn): Likewise.
+
+2001-03-15 David Mosberger <davidm@hpl.hp.com>
+
+ * config/tc-ia64.c (md): New member keep_pending_output.
+ (ia64_flush_pending_output): Flush only if md.keep_pending_output
+ is not set.
+ (dot_xdata): Turn on md.keep_pending_output for the duration of
+ this function.
+ (dot_xfloat_cons): Ditto.
+ (dot_xstringer): Ditto.
+ (dot_xdata_ua): Ditto.
+ (dot_xfloat_cons_ua): Ditto.
+
+2001-03-15 Jim Wilson <wilson@redhat.com>
+
+ * config/tc-ia64.c (ia64_unrecognized_line, case '['): Add local
+ label support.
+
+2001-03-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-sh.c (parse_reg): Match capital MACH and MACL.
+
+2001-03-15 DJ Delorie <dj@redhat.com>
+
+ * stabs.c (s_stab_generic): Don't corrupt the notes obstack by
+ blindly freeing string if it isn't at the top of the obstack.
+
+2001-03-13 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-i386.c (RELOC_ENUM): Define. Use throughout file.
+ (NUM_FLAG_CODE): Define.
+ (lex_got): New function.
+ (got_reloc): New global var.
+ (x86_cons_fix_new): New function.
+ (x86_cons): New function.
+ (i386_immediate): Use lex_got here, replacing inline code. Change
+ "ignoring junk.." error message to "junk.."
+ (i386_displacement): Likewise.
+ * config/tc-i386.h (TC_PARSE_CONS_EXPRESSION): Define.
+ (x86_cons): Declare.
+ (TC_CONS_FIX_NEW): Define.
+ (x86_cons_fix_new): Declare.
+
+2001-03-12 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (md_begin): Always set machine type based on
+ cpu_variant.
+
+2001-03-07 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-i386.c (struct _i386_insn): Rename disp_reloc to reloc.
+ (md_assemble) <smallest displacement>: Use correct field of i.op[]
+ union.
+ <JumpInterSegment output>: Use correct i.disp_reloc[].
+ <immediate output>: Likewise.
+
+2001-03-06 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (md_apply_fix3): Clear bit zero of offset in
+ BLX(1) instruction.
+
+2001-03-06 Igor Shevlyakov <igor@windriver.com>
+
+ * config/tc-m68k.c : Add 5407 to archs[] table.
+ (HAVE_LONG_BRANCH): Add mcf5407.
+ (select_control_regs): Recognize 5407.
+
+2001-03-02 Dave Brolley <brolley@redhat.com>
+
+ * config/tc-m32r.c (expand_debug_syms): Call frag_align_code rather
+ than m32r_do_align.
+
+2001-03-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/atof-ieee.c (TC_LARGEST_EXPONENT_IS_NORMAL): New macro.
+ (gen_to_words): Print warnings if NaNs are found and the target CPU
+ does not support them. Allow largest exponent to be used in normal
+ numbers if TC_LARGEST_EXPONENT_IS_NORMAL evaluates to true.
+
+2001-02-28 Andreas Jaeger <aj@suse.de>, Bo Thorsen <bo@suse.de>
+
+ * config/tc-i386.c (tc_gen_reloc): Remove ugly hack which is not needed
+ anymore since we use bfd_elf_generic_reloc now.
+ (md_apply_fix3): Only apply hack for partial_inplace if not using RELA.
+
+2001-02-27 Alan Modra <alan@linuxcare.com.au>
+
+ * configure.in (BFD_VERSION): New.
+ (AM_INIT_AUTOMAKE): Use $BFD_VERSION.
+ * configure: Regenerate.
+ * Makefile.am: Run "make dep-am"
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+
+2001-02-26 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * config/obj-coff.c [BFD_ASSEMBLER] (obj_coff_section): Set
+ SEC_NEVER_LOAD when the 'n' flag is used.
+ Add SEC_NEVER_LOAD to matchflags.
+
+2001-02-24 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * symbols.c (decode_local_label_name): Initialize message_format
+ only when an error is reported (perf pb due to I18N).
+
+2001-02-23 H.J. Lu <hjl@gnu.org>
+
+ * dwarf2dbg.c (dwarf2_directive_file): Call s_app_file (0) if
+ BFD_ASSEMBLER is not defined.
+
+2001-02-23 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mn10300.c (md_apply_fix3): Don't mark a fixup as
+ done if it's against a symbol.
+
+2001-02-22 Timothy Wall <twall@cygnus.com>
+
+ * config/tc-ia64.c (ia64_target_format): Return ia64-aix-specific
+ target formats if applicable.
+ * config/te-ia64aix.h: New. Configuration for AIX5 on IA-64.
+ * Makefile.am (TARG_ENV_HFILES): Added config/te-ia64aix.h.
+ * Makefile.in: Regenerated.
+ * configure.in: Added configuration for ia64-*-aix*.
+ * configure: Regenerated.
+
+2001-02-21 David Mosberger <davidm@hpl.hp.com>
+
+ * config/tc-ia64.c (enum operand_match_result): New type.
+ (operand_match): Change return type to operand_match_result.
+ Fix all returns appropriately, adding support for returning the
+ out-of-range result.
+ (parse_operands): New locals result, error_pos, out_of_range_pos,
+ curr_out_of_range_pos. Rewrite operand matching loop to give better
+ error messages.
+
+2001-02-21 David Mosberger <davidm@hpl.hp.com>
+
+ * config/tc-ia64.c (struct unwind): Add member "prologue_count".
+ (dot_proc): Clear unwind.prologue_count to zero.
+ (dot_prologue): Increment unwind.prologue_count.
+ (dot_restore): If second operand is omitted, use
+ unwind.prologue_count -1 for "ecount" (# of additional regions to
+ pop). Decrement unwind.prologue_count by number of regions
+ popped.
+
+2001-02-21 Nick Clifton <nickc@redhat.com>
+
+ * doc/as.texinfo (Section): Note that some flags to the COFF
+ version of .section remove attributes rather than setting them.
+
+2001-02-20 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-pdp11.c: Fix formatting.
+ * config/tc-pdp11.h: Likewise.
+
+2001-02-20 Bo Thorsen <bo@suse.de>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Fix GOTPCREL GOT
+ entry.
+
+2001-02-18 David O'Brien <obrien@FreeBSD.org>
+
+ * configure.in (cpu_type, arch): Add a generic FreeBSD specification as
+ all FreeBSD platforms should look the same at this level.
+ * configure: Rebuilt.
+ * config/tc-i386.c: Add support for old FreeBSD a.out hosts.
+
+2001-02-18 lars brinkhoff <lars@nocrew.org>
+
+ * Makefile.am: Add PDP-11 target.
+ * configure.in: Likewise.
+ * config/tc-pdp11.c: New file.
+ * config/tc-pdp11.h: New file.
+ * doc/Makefile.am: Add PDP-11 documentation.
+ * doc/all.texi: Likewise.
+ * doc/as.texinfo: Likewise.
+ * doc/c-pdp11.texi: New file.
+
+2001-02-16 matthew green <mrg@redhat.com>
+
+ * cgen.c (gas_cgen_md_apply_fix3): Support BFD_RELOC_64.
+
+2001-02-13 Jim Wilson <wilson@redhat.com>
+
+ * config/tc-ia64.c (operand_match, case TAG13): Make a BFD_RELOC_UNUSED
+ reloc instead of a 0 reloc.
+ (md_apply_fix3): Check for BFD_RELOC_UNUSED instead of 0, and mark it
+ as done.
+ * config/tc-ia64.h (TC_RELOC_RTSYM_LOC_FIXUP): Likewise.
+
+2001-02-13 Ian Lance Taylor <ian@zembu.com>
+
+ * write.c (is_dnrange): Stop as soon as the address becomes
+ larger.
+ (relax_frag): Add segment parameter. Only call symbol_get_frag
+ once. Only call is_dnrange if the symbol is in the same segment,
+ and the symbol address is larger.
+ (relax_segment): Pass segment to md_relax_frag and relax_frag.
+ * write.h (relax_frag): Update declaration.
+ * config/tc-fr30.c (fr30_relax_frag): Add segment parameter. Pass
+ it to relax_frag.
+ * config/tc-m32r.c (m32r_relax_frag): Likewise.
+ * config/tc-m32r.h (md_relax_frag): Add segment parameter.
+ (m32r_relax_frag): Update declaration.
+ * config/tc-mips.h (md_relax_frag): Add segment parameter.
+ * config/tc-tic54x.h (md_relax_frag): Likewise.
+ * doc/internals.texi (CPU backend): Update documentation for
+ md_relax_frag.
+
+2001-02-13 Alan Modra <alan@linuxcare.com.au>
+
+ * doc/c-i386.texi (i386-Arch): Add "jumps"/"nojumps" blurb.
+ Mention effect of < 386 architectures on jump promotion.
+ (i386-Jumps): xref above. Don't assume long disp is 32 bits.
+
+ * config/tc-i386.c (no_cond_jump_promotion): New.
+ (set_cpu_arch): Parse "jumps" arch modifier.
+ (insn_size): Modify usage comment.
+ (ENCODE_RELAX_STATE): Reformat and protect macro arg.
+ (SIZE_FROM_RELAX_STATE): Rename to DISP_SIZE_FROM_RELAX_STATE.
+ (TYPE_FROM_RELAX_STATE): New define.
+ (UNCOND_JUMP, COND_JUMP): Renumber.
+ (md_relax_table): Reorder to suit.
+ (COND_JUMP86): New define.
+ (md_relax_table): Handle COND_JUMP86 cases. Add a few comments.
+ (md_assemble): Create frag var for jumps of max size, encode relax
+ state for COND_JUMP86.
+ (md_estimate_size_before_relax): Handle COND_JUMP86 cases, and
+ leave conditional jumps small if no_cond_jump_promotion.
+ (md_convert_frag): Likewise.
+
+ * expr.c (operator): Don't bump input_line_pointer for two char
+ operators. Instead return operator size via new param num_chars.
+ (expr): Use above to parse multi-char operators correctly.
+
+2001-02-12 Jan Hubicka <jh@suse.cz>
+
+ * config/tc-i386.c (i386_displacement): Fix handling of
+ BFD_RELOC_X86_64_GOTPCREL.
+ (i386_validate_fix): Likewise.
+
+2001-02-12 Philip Blundell <pb@futuretv.com>
+
+ * config/tc-arm.c (do_ldst): Improve warnings for unpredictable
+ ldrt/strt instructions.
+
+2001-02-11 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * config/tc-mips.c (macro): For M_LA_AB emit a
+ BFD_RELOC_MIPS_CALL16 relocation or a
+ BFD_RELOC_MIPS_CALL_HI16/BFD_RELOC_MIPS_CALL_LO16 pair instead of
+ BFD_RELOC_MIPS_GOT16 and
+ BFD_RELOC_MIPS_GOT_HI16/BFD_RELOC_MIPS_GOT_LO16, respectively for
+ loading the jump register when generating SVR4_PIC code.
+
+2001-02-10 Chris Demetriou <cgd@broadcom.com>
+
+ * configure.in: Make 'mipself' and 'mipsecoff' emulations
+ map to MIPS-specific files, as they used to do before the
+ change on 2000-05-21.
+ * configure: Regerate.
+
+2001-02-10 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (md_parse_option): Don't try to compile
+ ELF-only option code if not ELF.
+
+2001-02-08 David Mosberger <davidm@hpl.hp.com>
+
+ * config/tc-ia64.h (md_elf_section_type): New macro.
+ (ELF_TC_SPECIAL_SECTIONS): Drop .IA_64.unwind and .IA_64.unwind_info
+ (they're now handled via ia64_elf_section_type.
+
+ * config/tc-ia64.c (unwind): New members saved_text_seg,
+ saved_text_subseg, and force_unwind_entry.
+ (optimize_unw_records): New function to optimize away unnecessary
+ unwind directives.
+ (ia64_elf_section_type): New function.
+ (output_unw_records): Generate unwind info only if the size is
+ non-zero or if it's forced for some other reason (e.g.,
+ handlerdata or a personality routine).
+ (generate_unwind_image): Don't switch back to previous
+ section---stay inside the unwind info section instead so that
+ handlerdata that may follow goes into the right place.
+ (dot_handlerdata): Force generation of unwind entry and save the
+ current active text segment before generating unwind image.
+ (dot_unwentry): Force generation of unwind entry.
+ (dot_personality): Ditto.
+ (dot_endp): Generate unwind table entry only if there is
+ some unwind info or the unwind entry was forced.
+
+ * config/tc-ia64.c (make_unw_section_name): New macro to form
+ unwind section name.
+ (generate_unwind_image): Add "text_name" argument. Use it to
+ form unwind section name.
+ (dot_handlerdata): Determine current segment (section) name and
+ pass it to generate_unwind_image().
+ (dot_endp): Determine current segment (section) name and use
+ it to determine the appropriate unwind section name.
+ (ia64_md_do_align): Add missing ATTRIBUTE_UNUSED declarations to
+ n, fill, and max arguments.
+
+2001-02-09 Schwidefsky <schwidefsky@de.ibm.com>
+
+ * Makefile.am: Add linux target for S/390.
+ * configure.in: Likewise.
+ * config/tc-s390.c: New file.
+ * config/tc-s390.h: New file.
+
+2001-02-09 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-sh.c (md_pseudo_table): Add uaquad. Use s_uacons for
+ 2byte, 4byte and 8byte.
+
+2001-02-08 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.c (pa_build_unwind_subspace): Don't call
+ md_number_to_chars with size > sizeof (valueT).
+
+2001-02-06 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-ia64.h (TC_RELOC_RTSYM_LOC_FIXUP): Do fixup if
+ there is no relocation.
+
+2001-02-06 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-ia64.h (TC_RELOC_RTSYM_LOC_FIXUP): New. Defined.
+
+ * config/tc-ia64.c (md_parse_option): Only accept the valid
+ ia64 options on "-axxx".
+
+2001-02-05 Jim Wilson <wilson@redhat.com>
+
+ * config/tc-ia64.c (errata_nop_necessary_p): Return 0 instead of
+ aborting for invalid operands.
+
+2001-02-06 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.c (fix_new_hppa): Pass in unwind directly rather
+ than via pointer. Update all callers.
+ (UNWIND_LOW32): Define.
+ (UNWIND_HIGH32): Define.
+ (pa_build_unwind_subspace): Use the above macros instead of dumping
+ bitfields directly. Call frag_more once rather than multiple times.
+ (md_assemble): Use UNWIND_LOW32.
+ (pa_entry): Likewise
+ (pa_procend): Likewise.
+ (process_exit): Use UNWIND_HIGH32.
+
+2001-02-04 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * config/tc-m68hc11.h (LISTING_HEADER): Use m68hc11_listing_header
+ function to select the header according to the cpu.
+ (md_after_pass_hook, md_do_align): Remove.
+ (md_cleanup, m68hc11_cleanup): Remove.
+ (md_pcrel_from_section): Declare.
+ * config/tc-m68hc11.c (build_dbranch_insn): Remove insn_size.
+ (build_jump_insn, build_insn): Likewise.
+ (m68hc11_listing_header): New function.
+ (m68hc11_cleanup): Remove.
+
+2001-02-02 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * config/tc-m68hc11.c (relaxable_symbol): Relax externally visible
+ symbols because there is no support for shared libraries and these
+ symbols can't be overridden (unless they are weak).
+
+2001-02-01 Momchil Velikov <velco@fadata.bg>
+
+ * dwarf2dbg.c (out_debug_abbrev): Terminate the abbreviations
+ for the compilation unit with a zero byte.
+
+2001-01-30 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.c (pa_ip): Support 12 bit branches to absolute
+ destinations. Correct range check for 17 and 22 bit branches.
+
+2001-01-25 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-m68k.c (tc_gen_reloc): Do not abort if tcbit is
+ still set. Issue an error message instead.
+ (md_estimate_size_before_relax): Delete unused variable
+ 'buffer_address'. Fixup parentheses around if statement.
+
+2001-01-23 Kazu Hirata <kazu@hxi.com>
+
+ * as.c: Fix formatting.
+ * ehopt.c: Likewise.
+ * messages.c: Likewise.
+ * stabs.c: Likewise.
+ * symbols.c: Likewise.
+
+2001-01-23 Ben Elliston <bje@redhat.com>
+
+ * config/tc-m32r.c (m32r_handle_align): Declare type of fragp.
+
+2001-01-22 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-alpha.c: Fix formatting.
+
+2001-01-19 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-alpha.c: Fix formatting.
+
+2001-01-18 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-alpha.c: Fix formatting.
+
+2001-01-18 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (ldm_flags): Remove redundant bit from "fa" and
+ "da" flags.
+ (stm_flags): Remove redundant bit from "ed" and "da" flags.
+
+2001-01-18 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure.in (cpu_type, arch): Match i386 too.
+ * configure: Rebuilt.
+
+2001-01-16 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-i386.c: Fix formatting.
+
+2001-01-16 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.c (tc_gen_reloc): Use SEGREL32 instead of DIR32
+ relocs for .PARISC.unwind section.
+
+ * config/tc-hppa.c (pa_build_unwind_subspace): Build unwind
+ depending on section flags, not just for .text.
+
+2001-01-15 Jim Wilson <wilson@redhat.com>
+
+ * config/tc-ia64.c (ia64_flush_insns): Handle unwind directives
+ not immediately followed by an instruction.
+
+2001-01-15 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-m68hc11.c: Fix formatting.
+
+2001-01-15 Nick Clifton <nickc@redhat.com>
+
+ * symbols.c (colon): Change 'already defined symbol' from a
+ fatal error to an ordinary error. There is no reason why this
+ error should be fatal.
+
+ * message.c (as_fatal): Delete output file, if one has been
+ created.
+
+2001-01-14 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.h (TARGET_FORMAT): Add hppa-linux variants.
+
+2001-01-14 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-alpha.c: Fix formatting.
+ * config/tc-arc.c: Likewise.
+ * config/tc-arc.h: Likewise.
+ * config/tc-d10v.c: Likewise.
+ * config/tc-i370.c: Likewise.
+ * config/tc-i386.c: Likewise.
+ * config/tc-i960.c: Likewise.
+ * config/tc-m68k.c: Likewise.
+ * config/tc-ppc.c: Likewise.
+ * config/tc-sparc.c: Likewise.
+ * config/tc-tahoe.c: Likewise.
+ * config/tc-vax.c: Likewise.
+
+ * config/tc-arc.c: Fix formatting.
+
+ * config/tc-arc.c: Fix formatting.
+
+2001-01-14 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.c (pa_build_unwind_subspace): Use SEGREL32 for
+ both 32 and 64 bit ELF.
+
+ * config/tc-hppa.c (pa_ip): Store `a' flag in bit zero of operand
+ and don't bother storing `m' for "ce" completer. Tidy handling of
+ 'J' and 'K' operands to suit. Handle '<' and '>' operands.
+
+2001-01-14 Jan Hubicka <jh@suse.cz>
+
+ * config/tc-i386.h (TARGET_MACH): New macro.
+ (i386_mach): Declare.
+ * config/tc-i386.c (i386_mach): New function.
+
+2001-01-13 Philip Blundell <philb@gnu.org>
+
+ * doc/as.texinfo: Fix spelling and cross-references.
+
+ * doc/c-arm.texi: Fix typos. Say that `;' is a line separator
+ character for all systems, not just GNU/Linux. Make it explicit
+ that `-k' doesn't affect code generation, just ELF flags.
+
+2001-01-13 Jan Hubicka <jh@suse.cz>
+
+ * config/tc-i386.c (md_assemble): Check cpu_flags even for nullary
+ instructions.
+
+2001-01-12 Frank Ch. Eigler <fche@redhat.com>
+
+ * cgen.c (gas_cgen_finish_insn): Call dwarf2_emit_insn.
+
+2001-01-12 Nick Clifton <nickc@redhat.com>
+
+ * as.c (print_args): Update copyright date to 2001.
+
+2001-01-12 Peter Targett <peter.targett@arccores.com>
+
+ * doc/c-arc.texi: New file.
+ Some sections to be expanded.
+
+2001-01-12 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-i386.c (md_longopts): Recognize "--64" only for ELF.
+ (md_parse_option): Always accept "--32".
+
+2001-01-11 Peter Targett <peter.targett@arccores.com>
+
+ * as.h (TC_ARC): Ensure struc-symbol.h included.
+ * as.c (dwarf2dbg.h): Include to remove implicit declaration
+ warnings.
+ * struc-symbol.h (SYMBOLS_NEED_BACKPOINTERS): Define.
+ (TARGET_SYMBOL_FIELDS) added.
+
+ * doc/Makefile.am (CPU_DOCS): Added c-arc.texi.
+ * doc/c-arc.texi: New file.
+ Some sections to be expanded.
+ * doc/as.texinfo: Update command-line options.
+ Removed outdated text for ARC dependant features, instead include
+ text from above file.
+
+ * config/obj-elf.h (ELF_TARGET_SYMBOL_FIELDS): Define local flag.
+ (TARGET_SYMBOL_FIELDS): Alias to previous definition.
+ (targ-cpu.h) header.
+ * config/tc-arc.h:
+ * config/tc-arc.c: New updated configuration for
+ ARC, including selection of core variants, and extensibility of
+ instructions, registers etc. through directives.
+
+ * config/tc-arc.c (arc_extinst): Minor corrections for
+ error messages.
+ (arc_common) Likewise. Make alignment argument optional for local
+ symbols also, with default of zero.
+
+2001-01-11 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * config/tc-m68hc11.c (md_estimate_size_before_relax): Fix
+ STATE_INDEXED_OFFSET when the symbol is undefined (16-bit offset).
+ (build_indexed_byte): Don't relax indexed byte, use 16-bit offset
+ and fix_new_exp() instead.
+ (md_convert_frag): For indexed post byte use the symbol value
+ rather than the displacement.
+ (md_relax_table): Fix indexed offset relax.
+
+2001-01-11 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * config/tc-m68hc11.c (md_estimate_size_before_relax):Don't
+ relax weak symbols.
+ (relaxable_symbol): New function.
+
+2001-01-11 Andreas Jaeger <aj@suse.de>
+
+ * config/tc-i386.h (TC_RELOC_GLOBAL_OFFSET_TABLE): Removed, it's
+ not used anywhere.
+
+2001-01-10 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (arm_fix_adjustable): Define for OBJ_COFF.
+ * config/tc-arm.h (obj_fix_adjustable): Define for OBJ_COFF
+
+2001-01-10 Nick Clifton <nickc@redhat.com>
+
+ * symbols.c (DOLLAR_LABEL_CHAR): New constant - the magic
+ character used to dollar local symbols.
+ (LOCAL_LABEL_CHAR): New constant - the magic character used to
+ local label symbols.
+ (dollar_label_name): Use DOLLAR_LABEL_CHAR.
+ (fb_label_name): Prefix local labels with LOCAL_LABEL_PREFIX,
+ if defined.
+ Use LOCAL_LABEL_CHAR.
+ (decode_local_label_name): Skip LOCAL_LABEL_PREFIX.
+ Use DOLLAR_LABEL_CHAR and LOCAL_LABEL_CHAR.
+ (S_IS_LOCAL): Use DOLLAR_LABEL_CHAR and LOCAL_LABEL_CHAR.
+
+2001-01-08 Bo Thorsen <bo@suse.de>
+
+ * config/tc-i386.c (i386_immediate, i386_displacement):
+ GOTPCREL check fix.
+
+2001-01-07 Ian Lance Taylor <ian@zembu.com>
+
+ * doc/c-i386.texi (i386-Arch): Remove spaces incorrectly inserted
+ in last change.
+
+2001-01-07 Philip Blundell <philb@gnu.org>
+
+ * doc/as.texinfo (Bug Reporting): Update email address for
+ reports.
+ * README: Likewise.
+
+2001-01-06 Jan Hubicka <jh@suse.cz>
+
+ * configure.in: Define DEFAULT_ARCH for i386.
+ * config/tc-i386.c (md_assemble): Return after the error message;
+ move testing for 64bit operands to proper place.
+
+2001-01-06 Jan Hubicka <jh@suse.cz>, Andreas Jaeger <aj@suse.de>
+
+ * doc/as.texinfo: Document '#' as comment character for i386 and
+ x86_64. Add AMD x86-64 into menu of machine dependent information.
+
+ * doc/c-i386.texi: Document x86_64 extensions.
+
+2001-01-05 Jan Hubicka <jh@suse.cz>
+
+ * config/tc-i386.c (md_assemble): Handle third byte of the opcode as prefix.
+
+2001-01-04 Jan Hubicka <jh@suse.cz>
+
+ * config/tc-i386.c (cpu_arch): Add Pentium4 and modify sledgehammer entry.
+ * NEWS: Add note about Pentium4 support.
+
+2001-01-04 Jan Hubicka <jh@suse.cz>
+
+ * config/tc-i387.c (pi, pte, pt): Update.
+ (type_names): Add new types.
+
+2001-01-03 Jan Hubicka <jh@suse.cz>
+
+ * config/tc-i386.h (CpuK6, CpuAthlon, CpuSledgehammer, CpuMMX, Cpu3dnow,
+ CpuUnknown): Renumber
+ (CpuP4, CpuSSE2): New.
+ (CpuUnknownFlags): Add CpuP4 and CpuSSE2
+
+2001-01-03 Philip Blundell <pb@futuretv.com>
+
+ * config/tc-alpha.c (alpha_force_relocation): Handle vtable
+ relocs.
+ (alpha_fix_adjustable): Likewise.
+ (md_apply_fix): Likewise.
+
+2000-12-31 H.J. Lu <hjl@gnu.org>
+
+ * listing.c (listing_message): Allocate string only if it is
+ used.
+
+ * configure: Rebuild.
+
+2000-12-31 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * doc/internals.texi (Relaxing with a table) <after relaxation>:
+ Point out caveats with generating fixups for the opcode in a frag.
+
+2000-12-30 Jan Hubicka <jh@suse.cz>
+
+ * configure.in: Add support for x86_64 and x86_64-*-linux-gnu*
+ * NEWS: Add x86_64.
+
+2000-12-29 H.J. Lu <hjl@gnu.org>
+
+ * listing.c (calc_hex): Print the variable part only if the
+ fragment type is rs_fill.
+
+2000-12-29 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * doc/internals.texi (tc_conditional_pseudoop,
+ TC_LINKRELAX_FIXUP): Fix typos.
+
+2000-12-28 Richard Henderson <rth@redhat.com>
+
+ * write.c (subsegs_finish): Fix thinko last change -- don't
+ "optimize" the alignment == 0 case.
+
+2000-12-28 Richard Henderson <rth@redhat.com>
+
+ * as.h (rs_align_test): New.
+ * frags.c (NOP_OPCODE): Move default from read.c.
+ (MAX_MEM_FOR_RS_ALIGN_CODE): New default.
+ (frag_align_code): New.
+ * frags.h (frag_align_code): Declare.
+ * read.c (NOP_OPCODE): Remove.
+ (do_align): Use frag_align_code.
+ * write.c (NOP_OPCODE): Remove.
+ (get_recorded_alignment): New.
+ (cvt_frag_to_fill): Handle rs_align_test.
+ (relax_segment): Likewise.
+ (subsegs_finish): Align last subseg in section to the
+ section alignment. Use frag_align_code.
+ * write.h (get_recorded_alignment): Declare.
+ * config/obj-coff.c (size_section): Handle rs_align_test.
+ (fill_section, fixup_mdeps): Likewise.
+ (write_object_file): Use frag_align_code.
+
+ * config/tc-alpha.c (alpha_align): Use frag_align_code.
+ (alpha_handle_align): New.
+ * config/tc-alpha.h (HANDLE_ALIGN): New.
+ (MAX_MEM_FOR_RS_ALIGN_CODE): New.
+
+ * config/tc-i386.h (md_do_align): Use frag_align_code.
+ (MAX_MEM_FOR_RS_ALIGN_CODE): New.
+
+ * config/tc-ia64.c (ia64_md_do_align): Don't do code alignment.
+ (ia64_handle_align): New.
+ * config/tc-ia64.h (HANDLE_ALIGN): New.
+ (MAX_MEM_FOR_RS_ALIGN_CODE): New.
+
+ * config/tc-m32r.c (m32r_do_align): Remove.
+ (m32r_handle_align): New.
+ (fill_insn): Use frag_align_code.
+ * config/tc-m32r.h (md_do_align): Remove.
+ (HANDLE_ALIGN, MAX_MEM_FOR_RS_ALIGN_CODE): New.
+ * config/tc-m88k.c, config/tc-m88k.h: Similarly.
+ * config/tc-mips.c, config/tc-mips.h: Similarly.
+
+ * config/tc-sh.c (sh_cons_align): Use rs_align_test.
+ (sh_handle_align): Likewise. Handle rs_align_code.
+ (sh_do_align): Remove.
+ * config/tc-sh.h (md_do_align): Remove.
+ (MAX_MEM_FOR_RS_ALIGN_CODE): New.
+
+ * config/tc-sparc.c (sparc_cons_align): Use rs_align_test.
+ (sparc_handle_align): Likewise. Handle rs_align_code.
+ * config/tc-sparc.h (md_do_align): Remove.
+ (MAX_MEM_FOR_RS_ALIGN_CODE): New.
+
+2000-12-22 DJ Delorie <dj@redhat.com>
+
+ * config/tc-d10v.c (md_assemble): set prev_seg and prev_subseg
+ when we assemble the first half of a pair.
+
+2000-12-22 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-i386.c (reloc): Update the macro for non-bfd
+ assembler.
+ (BFD_RELOC_X86_64_GOTPCREL): Set to 0 for non-bfd assembler.
+
+2000-12-22 H.J. Lu <hjl@gnu.org>
+
+ * dwarf2dbg.c (dwarf2_finish): Remove #if BFD_ASSEMBLER.
+
+2000-12-20 Jan Hubicka <jh@suse.cz>
+
+ * config/tc-i386.h (i386_target_format): Define even for ELFs.
+ (QWORD_MNEM_SUFFIX): New macro.
+ (CpuK6,CpuAthlon,CpuSledgehammer, Cpu64, CpuNo64, CpuUnknownFlags):
+ New macros
+ (CpuMMX,CpuSSE,Cpu3dnow, CpuUnknown): Renumber.
+ (IgnoreSize, DefaultSize, No_?Suf, FWait, IsString, regKludge, IsPrefix,
+ ImmExt): Renumber.
+ (Size64, No_qSuf, NoRex64, Rex64): New macros.
+ (Reg64, Imm32S, Imm64, Disp32S, Disp64): New macros.
+ (Imm8, Imm8S, Imm16, Imm32, Imm1, BaseIndex, Disp8, Disp16, Disp32,
+ InOutPortReg,ShiftCount, Control, Debug, Test, FloatReg, FloatAcc,
+ SReg2, SReg3, Acc, JumpAbsolute, RegMMX, RegXMM, EsSeg, InvMem):
+ Renumber.
+ (Reg, WordReg): Add Reg64.
+ (Imm): Add Imm32S and Imm64.
+ (EncImm): New.
+ (Disp): Add Disp64 and Disp32S.
+ (AnyMem): Add Disp32S.
+ (RegRex, RegRex64): New macros.
+ (rex_byte): New type.
+ * config/tc-i386.c (set_16bit_code_flag): Kill.
+ (fits_in_unsigned_long, fits_in_signed_long): New functions.
+ (reloc): New parameter "signed"; support x86_64.
+ (set_code_flag): New.
+ (DEFAULT_ARCH): New macro; default to "i386".
+ (default_arch): New static variable.
+ (struct _i386_insn): New fields Operand_PCrel; rex.
+ (flag_16bit_code): Kill; All tests replaced to "flag_code == CODE_64BIT"
+ (flag_code): New enum and static variable.
+ (use_rela_relocations): New static variable.
+ (flag_code_names): New static variable.
+ (cpu_arch_flags): Default to CpuUnknownFlags|CpuNo64.
+ (cpu_arch): Add "sledgehammer"; Add CPUAthlon to Athlon and CpuK6 to
+ K6 and Athlon.
+ (i386_align_code): Return plain "nop" for x86_64.
+ (mode_from_disp_size): Support Disp32S.
+ (smallest_imm_type): Support Imm32S and Imm64.
+ (offset_in_range): Support size of 8.
+ (set_cpu_arch): Do not clobber to Cpu64/CpuNo64.
+ (md_pseudo_table): Add "code64"; use set_code_flat.
+ (md_begin): Emit sane error message on hash failure.
+ (tc_i386_fix_adjustable): Support x86_64 relocations.
+ (md_assemble): Support QWORD_MNEM_SUFFIX, REX registers,
+ instructions supported on particular arch just partially,
+ output of 64bit immediates, handling of Imm32S and Disp32S type.
+ (i386_immedaite): Support x86_64 relocations; support 64bit constants.
+ (i386_displacement): Likewise.
+ (i386_index_check): Cleanup; support 64bit addresses.
+ (md_apply_fix3): Support x86_64 relocation and rela.
+ (md_longopts): Add "32" and "64".
+ (md_parse_option): Add OPTION_32 and OPTION_64.
+ (i386_target_format): Call even for ELFs; choose between
+ elf64-x86-64 and elf32-i386.
+ (i386_validate_fix): Refuse GOTOFF in 64bit mode.
+ (tc_gen_reloc): Support rela relocations and x86_64.
+ (intel_e09_1): Support QWORD.
+
+2000-12-15 Diego Novillo <dnovillo@redhat.com>
+
+ * config/tc-i386.c (intel_e09_1): Only flag as a memory operand if
+ it's not an offset expression.
+ (intel_e10_1): Ditto. Also, if the operand is an offset expression,
+ keep the braces '[' and ']' in the output string.
+ (intel_e11): Ditto. Also remove comparison intel_parser.op_modifier
+ != FLAT. There is no such op_modifier.
+
+2000-12-14 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * dwarf2dbg.c: If we don't have <limits.h>, try including <sys/param.h>
+ if we have it.
+
+2000-12-13 Kazu Hirata <kazu@hxi.com>
+
+ * as.h: Fix formatting.
+ * cgen.h: Likewise.
+ * dwarf2dbg.c: Likewise.
+ * input-scrub.c: Likewise.
+ * read.h: Likewise.
+
+2000-12-13 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * configure.in (i386-*-msdosdjgpp): Set bfd_gas to yes.
+ configure: Regenerate.
+
+2000-12-13 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * dwarf2dbg.c: #include <limits.h> only if it exists.
+
+2000-12-13 Rodney Brown <RodneyBrown@mynd.com>
+
+ * config/tc-hppa.c (pa_ip): Correct CHECK_FIELD typo.
+ (md_apply_fix): Here too.
+
+2000-12-12 Jim Wilson <wilson@redhat.com>
+
+ * config/tc-ia64.h (ia64_init): Add prototype.
+
+2000-12-12 H.J. Lu <hjl@gnu.org>
+
+ * dwarf2dbg.c: Enabled only if BFD_ASSEMBLER is defined.
+
+ * read.h (outputting_stabs_line_debug): Change it to int.
+ * stabs.c (outputting_stabs_line_debug): Likewise.
+
+2000-12-12 Geoffrey Keating <geoffk@redhat.com>
+
+ * config/obj-bout.c (obj_crawl_symbol_chain): Don't take
+ the address of a function result.
+
+2000-12-12 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * config/tc-ppc.c (md_pseudo_table): Add .file and .loc.
+ (md_assemble): Call dwarf2_emit_insn.
+ (shlib): Fix typo SHILB -> SHLIB.
+ (md_parse_option): Likewise.
+ (ppc_elf_validate_fix): Likewise:
+ * config/tc-ppc.h (DWARF2_LINE_MIN_INSN_LENGTH): New.
+
+2000-12-12 Nick Clifton <nickc@redhat.com>
+
+ * cgen.h: Fix formatting.
+ * input-scrub.c: Fix formatting.
+ * macro.c: Fix formatting.
+ * config/tc-mips.c: Fix formatting.
+ * doc/c-mips.texi: Fix formatting.
+
+2000-12-11 Jan hubicka <jh@suse.cz>
+
+ * config/tc-i386.c (md_assemble): Refuse 's' and 'l' suffixes in the intel
+ mode; convert 'd' suffix to 's' or 'l'; remove all DWORD_MNEM_SUFFIX
+ references.
+ (intel_e09_1): Convert QWORD to 'l' suffix for FP operations; refuse
+ otherwise.
+ * config/tc-i386.h (DWORD_MNEM_SUFFIX): Kill.
+ (No_dSuf): Kill.
+
+ * i386.h (*_Suf): Remove No_dSuf.
+ (d_suf, wld_Suf,sld_Suf, sldx_Suf, bwld_Suf, d_FP, sld_FP, sldx_FP)
+ Remove.
+ (i386_optab): Remove 'd' in the suffixes.
+
+2000-12-06 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * config/tc-i386.c (T_SHORT): Undefine before defining.
+
+2000-12-05 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-mips.c: Fix formatting.
+
+2000-12-04 Matthew Hiller <hiller@redhat.com>
+
+ * config/tc-d10v.c (flag_allow_gstabs_packing): New variable.
+ (md_longopts): New options --gstabs-packing, --no-gstabs-packing.
+ (md_show_usage): Ditto.
+ (md_parse_option): Ditto.
+ (d10v_cleanup): Writes pending instruction only if
+ ! outputting_stabs_line_debug || ! flag_allow_gstabs_packing.
+ Fix compile time warning messages.
+
+ * doc/c-d10v.texi: Documents new options.
+
+2000-12-04 Matthew Hiller <hiller@redhat.com>
+
+ * stabs.c (outputting_stabs_line_debug): New variable.
+ (stabs_generate_asm_lineno): Set outputting_stabs_line_debug at
+ function entry and unset at function exit.
+
+ * read.h (outputting_stabs_line_debug): New extern declaration.
+
+ * as.c: Include dwarf2dbg.h for definition of dwarf2_finish.
+
+ * dwarf2dbg.c: Fix compile time warning messages.
+
+2000-12-03 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-a29k.c: Fix formatting.
+ * config/tc-alpha.c: Likewise.
+ * config/tc-arm.c: Likewise.
+ * config/tc-cris.c: Likewise.
+ * config/tc-hppa.c: Likewise.
+ * config/tc-i370.c: Likewise.
+ * config/tc-i386.c: Likewise.
+ * config/tc-i860.c: Likewise.
+ * config/tc-i960.c: Likewise.
+ * config/tc-ia64.c: Likewise.
+ * config/tc-m68hc11.c: Likewise.
+ * config/tc-m68k.c: Likewise.
+ * config/tc-m88k.c: Likewise.
+ * config/tc-pj.c: Likewise.
+ * config/tc-ppc.c: Likewise.
+ * config/tc-sh.c: Likewise.
+ * config/tc-sparc.c: Likewise.
+ * config/tc-tahoe.c: Likewise.
+ * config/tc-vax.c: Likewise.
+
+2000-12-01 Chris Demetriou <cgd@sibyte.com>
+
+ * config/tc-mips.c (mips_ip): When calculating offsets,
+ don't accept as constant the difference between the
+ addresses of symbols in two different sections.
+
+ * config/tc-mips.c (macro_build): Add new 'U' and 'J' operand
+ specifiers.
+ (validate_mips_insn): Likewise. Also, update 'B' operand
+ specifier to use OP_*_CODE20 constants and delete 'm' operand
+ specifier.
+ (mips_ip): Remove 'm' operand specifier, add 'U' and 'J'
+ operand specifiers. Change warning generated by 'B' operand
+ specifier to reflect its new multi-purpose usage.
+
+ * config/tc-mips.c (mips_set_options): Use ISA_UNKNOWN rather than
+ -1, and update comment.
+ (file_mips_isa): Likewise.
+ (mips_cpu): Use CPU_UNKNOWN rather than -1, and update comment.
+ (ISA_HAS_COPROC_DELAYS, ISA_HAS_64BIT_REGS, gpr_interlocks): Use
+ ISA_* constants rather than hard-coded numbers.
+ (mips_cpu_info): New structure.
+ (mips_cpu_info_table): New table describing CPU and ISA names
+ and numbers.
+ (mips_cpu_info_from_name, mips_cpu_info_from_isa,
+ mips_cpu_info_from_cpu): New functions.
+ (mips_isa_to_str): New function to get string for ISA name.
+ (mips_cpu_to_str): Convert to use mips_cpu_info_from_cpu, and
+ return const char *.
+ (md_begin): Redo CPU and ISA selection logic, using
+ mips_cpu_info_from_*. Convert to use ISA_* constants rather
+ than hard-coded numbers.
+ (append_insn, mips_emit_delays, macro, macro2): Convert to use
+ ISA_* constants rather than hard-coded numbers.
+ (mips_ip): Convert to use mips_isa_to_str to get ISA name.
+ (md_longopts): Delete OPTION_NO_MIPS32.
+ (md_parse_option): Convert to use ISA_* constants rather than
+ hard-coded numbers. Make OPTIONS_MIPS32 case treat MIPS32
+ as an ISA. Delete OPTION_NO_MIPS32 case. Convert OPTION_MCPU
+ to use strcasecmp to recognize "default" and to use
+ mips_cpu_info_from_name to get CPU numbers from argument.
+ (md_show_usage): Move -mips32 so it's with the rest of the ISA
+ flags. Change 4Kc, 4Kp and 4Km CPU entries to just be
+ mips32-4k.
+ (s_mipsset): Accept ISA value 32.
+ * doc/as.texinfo: Clean up MIPS options summary slightly,
+ remove -no-mips32. Add note about -mips4 and -mips32
+ specifying those ISA levels. Delete -mips32 and -no-mips32
+ cpu flag descriptions.
+ * doc/c-mips.texi: Add -mips32 to list of ISA switches. Clean
+ up the supported CPU switch list, and replace 4Kc, 4Km, and
+ 4Kp entries with a single mips32-4k entry. Note that you can
+ use ".set mips32".
+
+ * config/tc-mips.c (ISA_HAS_64BIT_REGS): Add checks for ISA_MIPS5 and
+ ISA_MIPS64.
+ (md_longopts, OPTION_MIPS5, OPTION_MIPS64): Add options for
+ -mips5 and -mips64.
+ (md_parse_option): Add cases for OPTION_MIPS5 and
+ OPTION_MIPS64.
+ (md_show_usage): Mention -mips5 and -mips64 arguments.
+ (s_mipsset): Add cases for MIPS5 and MIPS64.
+ (mips_cpu_info_table): Add entries for MIPS5 and MIPS64 ISAs
+ and pseudo-CPUs.
+ * doc/as.texinfo: Mention -mips5 and -mips64 options
+ and their meanings.
+ * doc/c-mips.texi: Likewise. Also update introduction
+ and ".set" usage information.
+
+ * config/tc-mips.c (md_show_usage): Add "sb1" to the
+ CPU list.
+ (mips_cpu_info_table): Add SB-1 entries.
+ * doc/c-mips.texi: Add "sb1" to the list of CPUs
+ known to the -mcpu option.
+
+ * doc/as.texinfo: Correct description of MIPS -mcpu
+ option, by copying some of the text from doc/c-mips.texi.
+
+2000-12-01 Joel Sherrill <joel@OARcorp.com>
+
+ * configure.in (arm-*-rtems*, a29k-*rtems*, h8300-*-rtems*):
+ New targets.
+ (sparc*-*-rtemself*, sparc*-*-rtemsaout*): New targets.
+ (sparc*-*-rtems*): Switched from a.out to ELF.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * Makefile.in: Regenerate.
+ * aclocal.m4: Regenerate.
+ * po/gas.pot: Regenerate.
+
+2000-11-30 Philip Blundell <pb@futuretv.com>
+
+ * config/obj-coff.c (obj_coff_weak): Use S_SET_WEAK if it exists,
+ even in non BFD_ASSEMBLER case.
+
+2000-11-30 Diego Novillo <dnovillo@redhat.com>
+
+ * config/tc-i386.c (md_assemble): Swap i.disp_relocs when using intel
+ syntax.
+
+2000-11-29 Richard Henderson <rth@redhat.com>
+
+ * dwarf2dbg.c: Rewrite from scratch. Queue all debugging output
+ until dwarf2_finish; use relaxation to get cross-fragment offsets;
+ thread multiple subsegments properly; handle multiple code
+ sections properly; emit proper compilation unit info for assembler
+ generated debugging.
+
+ * as.h (enum _relax_state): Add rs_dwarf2dbg.
+ * dwarf2dbg.h (struct dwarf2_line_info): Remove filename.
+ (dwarf2dbg_estimate_size_before_relax): Declare.
+ (dwarf2dbg_relax_frag, dwarf2dbg_convert_frag): Declare.
+ * write.c: Include dwarf2dbg.h.
+ (cvt_frag_to_fill): Handle rs_dwarf2dbg.
+ (relax_segment): Likewise.
+
+2000-11-28 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/tc-sh.c (md_convert_frag) <undefined symbol, conditional
+ jump>: Use as_bad_where instead of as_bad. Tweak error message
+ accordingly. Stabilize frag by updating fix part and resetting
+ variant part.
+ <undefined symbol, unconditional jump>: Ditto.
+ (sh_elf_cons): Cast *input_line_pointer to unsigned char when
+ indexing is_end_of_line[].
+ (md_assemble): Initialize size to 0.
+ (md_section_align): Mark parameter seg as unused.
+ (parse_reg): Parse names case-insensitively.
+
+2000-11-28 Kazu Hirata <kazu@hxi.com>
+
+ * config/obj-aout.h: Fix formatting.
+ * config/obj-bout.h: Likewise.
+ * config/obj-coff.c: Likewise.
+ * config/obj-coff.h: Likewise.
+ * config/obj-elf.h: Likewise.
+ * config/obj-som.h: Likewise.
+ * config/obj-vms.c: Likewise.
+ * config/obj-vms.h: Likewise.
+ * config/tc-h8300.h: Likewise.
+ * config/tc-ns32k.h: Likewise.
+ * config/tc-sparc.h: Likewise.
+ * config/tc-tic54x.h: Likewise.
+ * config/tc-z8k.h: Likewise.
+
+2000-11-28 Nick Clifton <nickc@redhat.com>
+
+ * doc/as.1 (COPYING): Mention that the GNU Free Documentation
+ License is present in the sources, but not the output, and
+ also available from the GNU website.
+ (GNU Free Documentation License): Comment out this section.
+
+2000-11-28 Hans-Peter Nilsson <hp@axis.com>
+
+ * Makefile.am (CPU_OBJ_VALID): Add case to filter out invalid coff
+ targets. Remove i860 from valid a.out targets.
+ * Makefile.in: Regenerate.
+
+ * config/tc-cris.c: Include dwarf2dbg.h.
+ (md_pseudo_table): Add .file and .loc.
+ (md_assemble): Call dwarf2_emit_insn if generating ELF.
+ (s_cris_file, s_cris_loc): New.
+ * config/tc-cris.h (DWARF2_LINE_MIN_INSN_LENGTH): Define.
+ * Makefile.am: Regenerate dependencies.
+ * Makefile.in: Regenerate.
+
+2000-11-28 Alan Modra <alan@linuxcare.com.au>
+
+ * expr.c (STANDARD_MUL_PRECEDENCE): Correct value.
+ (MRI_MUL_PRECEDENCE): Likewise.
+ (op_rank): Fix a comment typo.
+
+2000-11-26 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * config/tc-m68hc11.c (build_indexed_byte): Print the offset in
+ the error message.
+ (get_operand): Fix analysis for movw/movb instructions.
+
+2000-11-24 Nick Clifton <nickc@redhat.com>
+
+ * configure.in (xscale-elf): Add target.
+ (xscale-coff): Add target.
+ * configure: Regenerate.
+
+ * config/tc-arm.c (ARM_EXT_V5E): New ARM architecture
+ extenstion.
+ (ARM_EXT_XSCALE): New ARM architecture extension.
+ (ARM_LONGMUL): Rename to ARM_EXT_LONGMUL.
+ (ARM_HALFWORD): Rename to ARM_EXT_HALFWORD.
+ (ARM_THUMB): Rename to ARM_EXT_THUMB.
+ (ARM_ARCH_V4): Remove processor from architecture.
+ (ARM_ARCH_3M): New architecutre definition.
+ (ARM_ARCH_V5TE): New architecutre definition.
+ (ARM_ARCH_XSCALE): New architecutre definition.
+ (CPU_DEFAULT): Allow to be defaulted to XScale.
+ (atpcs): New boolean variable.
+ (ldr_flags): Support 'd' flag for double word loads.
+ (str_flags): Support 'd' flag for double word stored.
+ (do_mia): New function.
+ (do_mar): New function.
+ (do_mra): New function.
+ (do_pld): New function.
+ (do_ldrd): New function.
+ (do_blx): New function.
+ (do_bkpt): New function.
+ (do_clz): New function.
+ (do_lstc2): New function.
+ (do_cdp2): New function.
+ (do_t_blx): New function.
+ (do_t_bkpt): New function.
+ (do_smla): New function.
+ (do_smlal): New function.
+ (do_smul): New function.
+ (do_qadd): New function.
+ (do_co_reg2c): New function.
+ (LONGEST_INSN): Redefine to 7.
+
+ * doc/c-arm.texi: Document -mxscale, -mmarmv5te and -matpcs
+ command line switches.
+
+2000-11-22 Jim Wilson <wilson@redhat.com>
+
+ * config/tc-ia64.c (pseudo_func): Add missing initializers.
+ (struct rsrc): Make line unsigned.
+ (gr_values): Add missing initializer.
+ (SLOT_NUM_NOT_SET): Add unsigned cast.
+ (ia64_elf_section_flags, output_vbyte_mem, count_output, dot_radix,
+ dot_fframe, dot_vframe, dot_vframesp, dot_vframepsp, dot_save,
+ dot_restore, dot_restorereg, dot_restorereg_p, dot_handlerdata,
+ dot_unwentry, dot_altrp, dot_saveg, dot_savef, dot_saveb, dot_savegf,
+ dot_spill, dot_spillreg, dot_spillreg_p, dot_label_state,
+ dot_copy_state, dot_unwabi, dot_personality, dot_proc, dot_body,
+ dot_prologue, dot_endp, dot_regstk, dot_psr, dot_alias, dot_ln,
+ dot_reg_val, dot_entry, dot_mem_offset, ia64_init, mark_resource,
+ md_undefined_symbol, md_apply_fix3, tc_gen_reloc, ia64_md_do_align):
+ Add ATTRIBUTE_UNUSED to unused parameters.
+ (convert_expr_to_ab_reg): Add parens.
+ (convert_expr_to_xy_reg): Add parens. Comment out >= REG_GR test.
+ (dot_prologue): Initialize grsave when declared.
+ (md_pseudo_table): Add missing initializers.
+ (operand_match): Add casts to bfd_vma.
+ (emit_one_bundle): Delete unused local prev. Make required_template
+ unsigned.
+ (specify_resource): Cast i to unsigned.
+ (note_register_values): Use fprintf_vma.
+ (print_dependency): Likewise.
+
+2000-11-21 Jim Wilson <wilson@redhat.com>
+
+ * config/tc-ia64.c (generate_unwind_image): Call record_alignment
+ for unwind info section.
+ (dot_endp): Likewise for unwind section.
+
+ * config/tc-ia64.c (emit_one_bundle): Pass size of 8 not 4 to
+ fix_new_exp.
+
+2000-11-21 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-sparc.c (md_pseudo_table): Add .file and .loc.
+ (output_insn): Call dwarf2_emit_insn.
+ * config/tc-sparc.h (DWARF2_LINE_MIN_INSN_LENGTH): New.
+
+2000-11-17 Richard Henderson <rth@redhat.com>
+
+ * ehopt.c (eh_frame_code_alignment): New arg `in_seg', update all
+ callers. Don't switch segments. Expect CIE == -1 in .debug_frame.
+ (check_eh_frame): Handle .eh_frame and .debug_frame concurrently.
+
+2000-11-17 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (md_pseudo_table): Add support for .line and
+ .file pseudo ops.
+
+2000-11-17 Richard Henderson <rth@redhat.com>
+
+ * config/tc-i386.c (md_pseudo_table): Add .file and .loc.
+
+2000-11-17 Richard Henderson <rth@redhat.com>
+
+ * dwarf2dbg.c (dwarf2_gen_line_info): Early out for no line number.
+ * config/obj-elf.h (ECOFF_DEBUGGING) [TC_ALPHA]: Adjust for
+ tri-state definition of alpha_flag_mdebug.
+ * config/tc-alpha.c (alpha_flag_mdebug): Init to -1.
+ (s_alpha_file): Store first .file directive.
+ (s_alpha_stab): New.
+ (md_pseudo_table): Add stabs and stabn.
+
+2000-11-17 Richard Henderson <rth@redhat.com>
+
+ * config/tc-i386.c (md_assemble): Call dwarf2_emit_insn.
+
+2000-11-17 Richard Henderson <rth@redhat.com>
+
+ * as.c (debug_type): Init to DEBUG_UNSPECIFIED.
+ (main): Call dwarf2_finish.
+ * as.h (debug_type): Clarify documentation of the meaning
+ of this variable.
+ * dwarf2dbg.c (DWARF2_LINE_MIN_INSN_LENGTH): Default to 1.
+ (print_stats): Fix parenthesis problem.
+ (now_subseg_size): New.
+ (dwarf2_finish): Use it. If DEBUG_DWARF2, emit bits for .debug_info.
+ (dwarf2_directive_file): Don't set debug_type.
+ (dwarf2_where): Honor DEBUG_DWARF2 first.
+ (dwarf2_emit_insn): Renamed from dwarf2_generate_asm_lineno;
+ do nothing if not emitting dwarf2 debug info, or no work.
+ * dwarf2dbg.h (dwarf2_emit_insn): Update.
+ * ecoff.c (add_file): Turn on DEBUG_ECOFF only if DEBUG_UNSPECIFIED.
+ (ecoff_new_file): Likewise.
+ * read.c (generate_lineno_debug): Kill ecoff hackery. Update
+ commentary wrt dwarf2.
+
+ * config/tc-alpha.c (alpha_adjust_symtab_relocs): Add
+ ATTRIBUTE_UNUSED as needed.
+ (emit_insn): Call dwarf2_emit_insn.
+ (s_alpha_file): New.
+ (s_alpha_loc): New.
+ (s_alpha_coff_wrapper): Don't handle them.
+ (md_pseudo_table): Update for .file and .loc.
+ * config/tc-alpha.h (DWARF2_LINE_MIN_INSN_LENGTH): New.
+
+ * config/tc-arm.c (output_inst): Update for dwarf2_emit_insn;
+ don't protect with debug_type.
+ * config/tc-hppa.c (md_assemble): Likewise.
+ * config/tc-m68hc11.c (m68hc11_new_insn): Likewise.
+ * config/tc-mn10300.c (md_assemble): Likewise.
+ * config/tc-sh.c (md_assemble): Likewise.
+ * config/tc-v850.c (md_assemble): Likewise.
+
+ * config/tc-arm.c (arm_end_of_source): Remove.
+ * config/tc-hppa.c (pa_end_of_source): Remove.
+ * config/tc-m68hc11.c (m68hc11_end_of_source): Remove.
+ * config/tc-mn10300.c (mn10300_finalize): Remove.
+ * config/tc-sh.c (sh_finalize): Remove.
+ * config/tc-v850.c (sh_finalize): Remove.
+
+ * config/tc-arm.h (md_end): Remove.
+ * config/tc-hppa.h (md_end): Remove.
+ (DWARF2_LINE_MIN_INSN_LENGTH): New.
+ * config/tc-m68hc11.h (md_end): Remove.
+ * config/tc-mn10300.h (md_end): Remove.
+ * config/tc-sh.h (md_end): Remove.
+ * config/tc-v850.h (md_end): Remove.
+
+ * config/tc-ia64.c (emit_one_bundle): Don't protect
+ dwarf2 bits with debug_type.
+ (md_assemble): Likewise.
+ (ia64_end_of_source): Don't call dwarf2_finish.
+
+2000-11-16 Jim Wilson <wilson@redhat.com>
+
+ * config/tc-ia64.c (errata_nop_necessary_p): Abort if general regno
+ >= 128 instead of > 128. Abort if predicate regno is >= 64 instead of
+ > 16.
+
+2000-11-16 H.J. Lu <hjl@gnu.org>
+
+ * config/obj-elf.c (obj_elf_symver): Don't check the missing
+ version name.
+
+2000-11-15 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-tic30.c: Fix formatting.
+ * config/tc-tic80.c: Likewise.
+ * config/tc-v850.c: Likewise.
+ * config/tc-vax.c: Likewise.
+ * config/tc-w65.c: Likewise.
+ * config/tc-z8k.c: Likewise.
+
+2000-11-14 DJ Delorie <dj@redhat.com>
+
+ * config/tc-v850.c: Support dwarf2.
+ * config/tc-v850.h: Ditto.
+
+ * config/tc-v850.c (cons_fix_new_v850): Don't rely on
+ parse_cons_expression_v850 to initialize hold_cons_reloc.
+
+2000-11-15 Bernd Schmidt <bernds@redhat.com>
+
+ * config/tc-ia64.c (struct md): New entries LAST_GROUPS, GROUP_IDX.
+ (errata_nops_necessary_p): New function.
+ (emit_one_bundle): Call it. Update the GROUP_IDX field in struct
+ md.
+
+2000-11-14 Jim Wilson <wilson@redhat.com>
+
+ * config/tc-ia64.c (ia64_target_format): If EF_IA_64_BE not set, then
+ return little endian bfd formats.
+
+2000-11-14 Kazu Hirata <kazu@hxi.com>
+
+ * config/aout_gnu.h: Fix formatting.
+ * config/atof-vax.c: Likewise.
+ * config/m68k-parse.h: Likewise.
+ * config/m88k-opcode.h: Likewise.
+ * config/obj-elf.c: Likewise.
+ * config/tc-arm.c: Likewise.
+ * config/tc-cris.c: Likewise.
+ * config/tc-i386.c: Likewise.
+ * config/tc-ia64.c: Likewise.
+ * config/tc-mn10300.c: Likewise.
+ * config/te-386bsd.h: Likewise.
+ * config/te-hppa.h: Likewise.
+ * config/te-nbsd.h: Likewise.
+ * config/te-ppcnw.h: Likewise.
+ * config/te-sparcaout.h: Likewise.
+ * config/te-tmips.h: Likewise.
+ * config/vax-inst.h: Likewise.
+ * config/vms-conf.h: Likewise.
+
+2000-11-14 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-alpha.c (s_alpha_prologue): Preserve visibility bits.
+
+2000-11-13 H.J. Lu <hjl@gnu.org>
+
+ * config/obj-elf.c (elf_frob_symbol): Support
+ ".symver name,name2@@@nodename".
+ (elf_frob_file_before_adjust): Likewise.
+
+ * doc/as.texinfo: Updated for ".symver name,name2@@@nodename"
+ and ".symver name,name2@@@nodename".
+ Fix a typo.
+
+2000-11-12 H.J. Lu (hjl@gnu.org)
+
+ * config/obj-elf.c (obj_elf_symver): Check missing version
+ name.
+
+2000-11-12 H.J. Lu (hjl@gnu.org)
+
+ * dwarf2dbg.c (dwarf2_generate_asm_lineno): Use addressT
+ instead of bfd_vma for non-bfd assemblers.
+
+2000-11-09 Kazu Hirata <kazu@hxi.com>
+
+ * itbl-ops.c: Fix comment typos.
+
+2000-11-08 Jim Wilson <wilson@redhat.com>
+
+ * config/tc-ia64.c (struct unw_rec_list): Add slot_frag field.
+ (struct unwind): Add next_slot_frag field.
+ (slot_index): New parameters slot_frag and first_frag. Add code
+ to add in frag sizes when different. Add comments.
+ (fixup_unw_records): New locals first_frag and last_frag. Pass new
+ arguments to slot_index.
+ (emit_one_bundle): Set slot_frag field. Set next_slot_number after
+ loop end. Set next_slot_frag field.
+
+2000-11-07 H.J. Lu <hjl@gnu.org>
+
+ * doc/as.texinfo (.symver): Updated for versioned symbol
+ reference.
+
+ * obj.h (format_ops): Add the frob_file_before_adjust field.
+
+ * config/obj-aout.c (aout_format_ops): Set the
+ frob_file_before_adjust field to 0.
+ * config/obj-coff.c (coff_format_ops): Likewise.
+ * config/obj-ecoff.c (ecoff_format_ops): Likewise.
+
+ * config/obj-elf.c (obj_elf_symver): Allow duplicated version
+ name.
+ (elf_frob_file_before_adjust): New function to remove unneeded
+ versioned symbols from the symbol table.
+ (elf_format_ops): Set the frob_file_before_adjust field to
+ elf_frob_file_before_adjust.
+
+ * config/obj-elf.h (obj_frob_file_before_adjust): Defined if
+ not defined.
+
+ * config/obj-multi.h (obj_frob_file_before_adjust): Defined.
+
+2000-11-07 Peter Targett <peter.targett@arccores.com>
+
+ * config/tc-arc.h: Avoid warnings for LITTLE_ENDIAN and
+ BIG_ENDIAN macros.
+ * config/tc-arc.c: Use S_IS_LOCAL to test local symbols.
+ Fix compile time warning messages.
+
+2000-11-07 Nick Clifton <nickc@redhat.com>
+
+ * stabs.c (generate_asm_file): Increase length of xmalloc'ed
+ buffer in order to avoid buffer overflows.
+
+2000-11-06 Steve Ellcey <sje@cup.hp.com>
+
+ * config/tc-ia64.c (md_shortopts, md_parse_option, md_show_usage):
+ Change M to m for -milp32 or -mlp64 to match gcc.
+ (dot_endp): Use bytes_per_address instead of 8.
+ (emit_one_bundle): Use number_to_chars_littleendian instead of
+ md_number_to_chars.
+ (fix_insn): Likewise.
+ (ia64_init): New function.
+ (ia64_target_format): New function.
+ (md_begin): Set endianness, arch, and machine as appropriate.
+ * config/tc-ia64.h: (TARGET_BYTES_BIG_ENDIAN, md_number_to_chars):
+ Make these macros depend on TE_HPUX macro.
+ (TARGET_FORMAT): Define.
+ (HOST_SPECIAL_INIT): Define.
+ * config/te-hpux.h: New file.
+ * configure.in: Add "ia64-*-hpux*" target to configure.
+ * configure: Regenerate.
+
+2000-11-06 Kazu Hirata <kazu@hxi.com>
+
+ * as.c: Fix formatting.
+ * dwarf2dbg.c: Likewise.
+ * input-file.c: Likewise.
+ * input-file.h: Likewise.
+ * input-scrub.c: Likewise.
+ * itbl-ops.c: Likewise.
+ * listing.c: Likewise.
+ * macro.h: Likewise.
+ * messages.c: Likewise.
+ * read.c: Likewise.
+ * subsegs.c: Likewise.
+ * subsegs.h: Likewise.
+ * write.c: Likewise.
+
+2000-11-06 Nick Clifton <nickc@redhat.com>
+
+ * doc/as.texinfo: Add GNU Free Documentation License.
+ * doc/gasp.texi: Add GNU Free Documentation License.
+ * doc/as.1: Add GNU Free Documentation License.
+
+2000-11-05 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c: Add include of "dwarf2dbg.h"
+
+2000-11-02 Per Lundberg <plundis@chaosdev.org>
+
+ * configure.in: Recognise i[3456]86-chaosdev-storm-chaos.
+ * configure: Regenerate.
+
+2000-11-01 Nick Clifton <nickc@redhat.com>
+
+ * read.c (original_case_string): New global variable.
+ (read_a_source_file): Copy opcode string into
+ original_case_string if clobbering the case of the opcode.
+ * read.h: Export the definition of original_case_string.
+ * config/tc-arm.c (md_assembler): When parsing a .req
+ directive use the original opcode string, not the case
+ clobbered version.
+
+2000-11-02 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-mn10300.c (debug_line): Remove this static
+ variable.
+ (md_assemble): Call dwarf2_generate_asm_lineno instead of
+ dwarf2_where and dwarf2_gen_line_info.
+
+2000-11-02 Theo Honohan <th@futuretv.com>
+
+ * config/tc-arm.c (do_msr): Improve error message.
+
+2000-10-31 Eric Christopher <echristo@redhat.com>
+
+ * config/tc-mn10300.c (md_apply_fix3): Use valuep if fully resolved
+ or pc-relative, else use fx_offset.
+
+2000-10-31 Jim Wilson <wilson@redhat.com>
+
+ * config/tc-ia64.c (struct md): New field tag_fixups.
+ (ia64_flush_insns): Handle tag_fixups. Error if dangling
+ qualifying predicate.
+ (emit_one_bundle): Delete spurious multiplication by one. Handle
+ tag_fixups.
+ (ia64_start_line): Error if dangling qualifying predicate.
+ (defining_tag): New static variable.
+ (ia64_unrecognized_line, case '['): Parse tags.
+ (ia64_frob_label): Create tag_fixups.
+ (md_assemble): Reset md.qp.X_op after using it.
+
+2000-10-31 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * config/tc-sh.c (md_apply_fix [BFD_RELOC_SH_PCDISP12BY2]): Allow 4094.
+
+2000-10-31 Bernd Schmidt <bernds@redhat.co.uk>
+
+ * config/tc-ia64.c (extra_goodness): Only prefer F in slot 1 and B in slot 2.
+
+2000-10-30 Kazu Hirata <kazu@hxi.com>
+
+ * expr.c: Fix formatting.
+ * flonum-copy.c: Likewise.
+ * flonum.h: Likewise.
+ * gasp.c: Likewise.
+ * hash.c: Likewise.
+
+2000-10-30 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * as.h (OPTION_MD_BASE): Bump to 190.
+ * as.c (parse_args) <std_longopts>: Add comment about the need to
+ check OPTION_MD_BASE in as.h.
+
+ * config/tc-sh.c (md_apply_fix): For ELF, do not "adjust back" VAL
+ for weak symbols.
+
+2000-10-27 Nick Clifton <nickc@redhat.com>
+
+ * configure.in (emulations): Add m68hc12.
+ * configure: Regenerate.
+ * po/gas.pot: Regenerate.
+
+2000-10-27 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/tc-arm.c (psrs): Remove lowercase versions of spsr* and
+ cpsr*.
+ (arm_psr_parse): Handle lowercase CPSR and SPSR.
+
+2000-10-25 Nick Clifton <nickc@redhat.com>
+
+ * dwarf2out.c (dwarf2_generate_asm_lineno): New function: Generate
+ a DWARF2 line number information sequence.
+
+ *dwarf2out.h: Add prototype for dwarf2_generate_asm_lineno.
+
+ * read.c (generate_lineno_debug): Update comment describing why
+ DWARF2 line number debug information is not generated
+ automatically by this function.
+
+ * doc/as.texinfo: Note that --gdwarf2 only works on some targets,
+ not all.
+
+ * config/tc-arm.h (md_end): Define.
+ (DWARF2_LINE_MIN_INSN_LENGTH): Define.
+
+ * config/tc-arm.c (output_inst): Call dwarf2_generate_asm_lineno
+ if generating DWARF2 line numbers.
+ (arm_end_of_source): New function. Call dwarf2_finish if
+ necessary.
+
+ * config/tc-hppa.c (md_assemble): Use dwarf2_generate_asm_lineno.
+ * config/tc-m68hc11.c (m68hc11_new_insn): Use dwarf2_generate_asm_lineno.
+ * config/tc-sh.c (md_assemble): Use dwarf2_generate_asm_lineno.
+
+2000-10-25 Diego Novillo <dnovillo@cygnus.com>
+
+ * config/tc-i386.c: Fix prototype declarations for functions taking no
+ arguments.
+
+2000-10-24 Diego Novillo <dnovillo@cygnus.com>
+
+ * config/tc-i386.c (i386_operand_modifier): Remove.
+ (build_displacement_string): Remove.
+ (i386_parse_seg): Remove.
+ (i386_intel_memory_operand): Remove.
+ (i386_intel_operand): Re-write using recursive descent parser based
+ on MASM documentation.
+ (struct intel_parser_s): New structure.
+ (intel_parser): New static variable.
+ (struct intel_token): New structure.
+ (cur_token, prev_token): New static variables.
+ (T_NIL): Define.
+ (T_CONST): Define.
+ (T_REG): Define.
+ (T_BYTE): Define.
+ (T_WORD): Define.
+ (T_DWORD): Define.
+ (T_QWORD): Define.
+ (T_XWORD): Define.
+ (T_SHORT): Define.
+ (T_OFFSET): Define.
+ (T_PTR): Define.
+ (T_ID): Define.
+ (intel_match_token): New function.
+ (intel_get_token): New function.
+ (intel_putback_token): New function.
+ (intel_expr): New function.
+ (intel_e05): New function.
+ (intel_e05_1): New function.
+ (intel_e06): New function.
+ (intel_e06_1): New function.
+ (intel_e09): New function.
+ (intel_e09_1): New function.
+ (intel_e10): New function.
+ (intel_e10_1): New function.
+ (intel_e11): New function.
+
+2000-10-20 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-sparc.c (sparc_ip): Fix a bug which caused v9_arg_p
+ instructions to loose any special insn->architecture mask.
+
+ * config/tc-sparc.c (v9a_asr_table): Add v9b ASRs.
+ (sparc_md_end, sparc_arch_types, sparc_arch,
+ sparc_elf_final_processing): Handle v8plusb and v9b architectures.
+ (sparc_ip): Handle siam mode operands. Support v9b ASRs (and
+ request v9b architecture if they are used).
+
+2000-10-18 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * config/tc-m68k.c: Fix the previous misapplied patch.
+
+2000-10-18 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * config/tc-m68k.h (RELAX_RELOC_*): New definitions for both
+ BFD_ASSEMBLER and !BFD_ASSEMBLER.
+ * config/tc-m68k.c (md_convert_frag_1): Use them instead of
+ BFD_RELOC_*.
+
+2000-10-17 Kazu Hirata <kazu@hxi.com>
+
+ * debug.c: Fix formatting.
+ * depend.c: Likewise.
+ * dwarf2dbg.c: Likewise.
+ * dwarf2dbg.h: Likewise.
+ * ecoff.c: Likewise.
+ * expr.c: Likewise.
+ * expr.h: Likewise.
+ * flonum-konst.c: Likewise.
+ * frags.h: Likewise.
+
+2000-10-17 Chandrakala Chavva <cchavva@redhat.com>
+
+ * as.c: New option OPTION_TARGET_HELP. Prints all target specific
+ options.
+ * doc/as.texinfo: Added notes about this new option.
+
+2000-10-16 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/tc-sh.c (JREG): Remove.
+ (md_convert_frag): Remove #if 0:d code using JREG.
+
+2000-10-15 Diego Novillo <dnovillo@cygnus.com>
+
+ * config/tc-i386.c (i386_operand_modifier): Only match
+ modifiers SHORT and FLAT if they are followed by a space.
+ (parse_register): When `allow_naked_reg' is set, do not confuse
+ identifiers that start with a register name with a register.
+
+2000-10-12 Kazu Hirata <kazu@hxi.com>
+
+ * app.c: Fix formatting.
+ * as.c: Likewise.
+ * as.h: Likewise.
+ * bit_fix.h: Likewise.
+ * cgen.c: Likewise.
+ * cgen.h: Likewise.
+ * cond.c: Likewise.
+
+2000-10-11 Alan Modra <alan@linuxcare.com.au>
+
+ * config/obj-elf.c (elf_frob_symbol): Revert 2000-10-07 change.
+
+2000-10-07 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.c (md_apply_fix): Remove plainly wrong assert.
+ Re-arrange function a little and improve error message.
+
+ * write.c (write_relocs): Fix a comment.
+
+ * config/obj-elf.c (elf_frob_symbol): Make section syms global on
+ link-once sections.
+
+2000-10-05 Jim Wilson <wilson@cygnus.com>
+
+ * config/tc-ia64.c (resources_match): Handle IA64_RS_PRr.
+
+2000-10-05 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-i386.c: Delete some useless comments, reformat others.
+
+ * config/tc-i386.h (TC_FIX_ADJUSTABLE): Add check to cover
+ non-global syms in linkonce sections.
+
+2000-10-04 Ralf Baechle <ralf@gnu.org>
+
+ * config/tc-ia64.c (operand_match): Don't use // style comments.
+ * config/tc-i370.c: Likewise.
+
+2000-09-29 Hans-Peter Nilsson <hp@axis.com>
+
+ Changes to handle varying register prefix and user symbol prefix.
+ * config/tc-cris.c (SYNTAX_RELAX_REG_PREFIX,
+ SYNTAX_ENFORCE_REG_PREFIX, SYNTAX_USER_SYM_LEADING_UNDERSCORE,
+ SYNTAX_USER_SYM_NO_LEADING_UNDERSCORE, REGISTER_PREFIX_CHAR): New.
+ (s_syntax, cris_force_reg_prefix, cris_relax_reg_prefix,
+ cris_sym_leading_underscore, cris_sym_no_leading_underscore): New.
+ (demand_register_prefix): New variable.
+ (md_pseudo_table): New pseudo ".syntax".
+ (md_longopts): New options --no-underscore and --underscore.
+ (cris_target_format): Return elf32-us-cris or elf32-cris depending
+ on symbols_have_leading_underscore.
+ (get_gen_reg): Accept or require REGISTER_PREFIX_CHAR.
+ (get_spec_reg): Ditto.
+ (cris_number_to_imm) <case BFD_RELOC_VTABLE_ENTRY>: Remove FIXME.
+ Fix formatting.
+ (md_parse_option) <case 'h' 'H'>: Deprecate; add reference to
+ --help.
+ <case OPTION_NO_US, case OPTION_US>: New.
+ (md_show_usage): Be brief and reformat to match continuation of
+ --help.
+ * po/gas.pot: Regenerate.
+
+2000-09-28 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.c (hppa_force_relocation): If OBJ_SOM, don't
+ force relocs for 12 bit branches.
+ (md_apply_fix): Similarly, adjust logic here.
+
+2000-09-28 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.c (md_apply_fix): Add fmt assertion. Don't
+ adjust for external and weak syms as we will use a reloc. Allow
+ for +8 offset when calculating limits of branches.
+ (hppa_fix_adjustable): Undo 2000-09-23 change.
+ (hppa_force_relocation): Likewise. Add fx_addsy assertion.
+ Correct distance calculation.
+ (tc_gen_reloc): Print the file name and line number if we can't
+ handle a fixup.
+
+ From John David Anglin <dave@hiauly1.hia.nrc.ca>
+ * config/tc-hppa.c (nonzero_dibits): Define.
+ (arg_reloc_stub_needed): Check each arg and return value
+ separately for zero case.
+ (pa_align): Declare argument `bytes'.
+
+2000-09-25 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-cris.c: Fix formatting.
+ * config/tc-d10v.h: Likewise.
+ * config/tc-d30v.c: Likewise.
+ * config/tc-d30v.h: Likewise.
+ * config/tc-fr30.c: Likewise.
+ * config/tc-fr30.h: Likewise.
+ * config/tc-m68k.c: Likewise.
+ * config/tc-m68k.h: Likewise.
+ * config/tc-pj.h: Likewise.
+ * config/tc-ppc.c: Likewise.
+ * config/tc-ppc.h: Likewise.
+ * config/tc-sh.c: Likewise.
+ * config/tc-sh.h: Likewise.
+ * config/tc-sparc.c: Likewise.
+ * config/tc-v850.h: Likewise.
+ * config/tc-vax.h: Likewise.
+ * config/tc-w65.h: Likewise.
+ * config/tc-z8k.h: Likewise.
+
+2000-09-23 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.c (hppa_fix_adjustable): Do the external and weak
+ checks only for ELF.
+ (hppa_force_relocation): Likewise.
+
+2000-09-22 Jim Wilson <wilson@cygnus.com>
+
+ * config/tc-ia64.c (dv_sem): Add "stop".
+ (specify_resource, case IA64_RS_PR): Only handles regs 1 to 15 now.
+ (specify_resource, case IA64_RS_PRr): New for regs 16 to 62.
+ (specify_resource, case IA64_RS_PR63): Reorder (note == 7) test to
+ match above.
+ (mark_resources): Check IA64_RS_PRr.
+
+2000-09-22 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * config/tc-m68k.c (md_relax_table, m68k_ip, md_convert_frag_1,
+ md_estimate_size_before_relax): Redesign and clean up the
+ relaxation mechanism.
+
+2000-09-21 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-ns32k.c: Fix formatting.
+ * config/tc-ns32k.h: Likewise.
+
+2000-09-20 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-m32r.c: Fix formatting.
+ * config/tc-m32r.h: Likewise.
+ * config/tc-m68851.h: Likewise.
+ * config/tc-m68hc11.c: Likewise.
+ * config/tc-m68hc11.h: Likewise.
+ * config/tc-m88k.c: Likewise.
+ * config/tc-mcore.c: Likewise.
+ * config/tc-mcore.h: Likewise.
+ * config/tc-mips.c: Likewise.
+ * config/tc-mips.h: Likewise.
+ * config/tc-mn10200.h: Likewise.
+ * config/tc-mn10300.h: Likewise.
+ * config/tc-tahoe.c: Likewise.
+ * config/tc-tahoe.h: Likewise.
+
+2000-09-19 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * config/tc-vax.c (synthetic_votstrs): Remove jbssi and jbcci.
+ Likewise in relaxation description comments.
+
+2000-09-18 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.h (TC_FORCE_RELOCATION_SECTION): Allow
+ subtraction of two syms without emitting a relocation.
+
+ From David Huggins-Daines <dhd@linuxcare.com>
+ * config/tc-hppa.c (hppa_force_relocation): Force relocations for
+ global or weak symbols.
+
+2000-09-15 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-h8300.h: Fix formatting.
+ * config/tc-h8500.c: Likewise.
+ * config/tc-h8500.h: Likewise.
+ * config/tc-hppa.h: Likewise.
+ * config/tc-i370.h: Likewise.
+ * config/tc-i386.h: Likewise.
+ * config/tc-i860.c: Likewise.
+ * config/tc-i860.h: Likewise.
+ * config/tc-i960.h: Likewise.
+ * config/tc-ia64.c: Likewise.
+ * config/tc-ia64.h: Likewise.
+
+2000-09-14 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-a29k.c: Fix formatting.
+ * config/tc-alpha.c: Likewise.
+ * config/tc-arc.c: Likewise.
+ * config/tc-arc.h: Likewise.
+ * config/tc-arm.c: Likewise.
+ * config/tc-arm.h: Likewise.
+ * config/tc-avr.c: Likewise.
+ * config/tc-avr.h: Likewise.
+ * config/tc-tic30.c: Likewise.
+ * config/tc-tic30.h: Likewise.
+ * config/tc-tic54x.c: Likewise.
+ * config/tc-tic54x.h: Likewise.
+ * config/tc-tic80.c: Likewise.
+ * config/tc-tic80.h: Likewise.
+
+2000-09-14 Timothy Wall <twall@cygnus.com>
+
+ * config/tc-ia64.c (specify_resource): For PR%/PR63, note types of
+ parallel comparisons for later use.
+ (struct rsrc): Add parallel comparison type.
+ (resources_match): Skip special cases of PR usage (non-conflicting
+ parallel compares).
+
+2000-09-13 Kazu Hirata <kazu@hxi.com>
+
+ * config/obj-ecoff.c: Fix formatting.
+ * config/obj-elf.c: Likewise.
+ * config/obj-elf.h: Likewise.
+ * config/obj-evax.h: Likewise.
+ * config/obj-generic.h: Likewise.
+ * config/obj-hp300.c: Likewise.
+ * config/obj-hp300.h: Likewise.
+ * config/obj-ieee.h: Likewise.
+ * config/obj-vms.c: Likewise.
+ * config/obj-vms.h: Likewise.
+
+2000-09-13 Anders Norlander <anorland@acc.umu.se>
+
+ * config/tc-mips.c (md_begin): Recognize 4Kc, 4Km and 4Kp processors.
+ (md_parse_option): Ditto.
+ (md_longopts): Add -mips32 option.
+ (md_show_usage): Document new options.
+ (mips_ip): Assemble sdbbp 20 bit 'm' args for MIPS32.
+ (mips_ip): Assemble mfc0 with a sub-selection code.
+ (validate_mips_insn): Handle 'H' (OP_*_SEL) and 'm' (OP_*_CODE20).
+ (mips_cpu_to_str): New function.
+ (mips_ip): Use mips_cpu_to_str instead of printing numeric cpu value.
+ Use CPU_* defines instead of hardcoded numbers.
+
+ * doc/as.texinfo: Document new options.
+ * doc/c-mips.texi: Ditto.
+
+2000-09-12 Kazu Hirata <kazu@hxi.com>
+
+ * as.h: Fix formatting.
+ * asintl.h: Likewise.
+ * bit_fix.h: Likewise.
+ * config/obj-aout.c: Likewise.
+ * config/obj-aout.h: Likewise.
+ * config/obj-bout.c: Likewise.
+ * config/obj-bout.h: Likewise.
+ * config/obj-coff.c: Likewise.
+ * config/obj-coff.h: Likewise.
+ * dwarf2dbg.h: Likewise.
+ * expr.h: Likewise.
+ * flonum.h: Likewise.
+ * frags.h: Likewise.
+ * itbl-ops.h: Likewise.
+ * macro.h: Likewise.
+ * read.h: Likewise.
+ * sb.h: Likewise.
+ * struc-symbol.h: Likewise.
+ * subsegs.h: Likewise.
+ * symbols.h: Likewise.
+ * tc.h: Likewise.
+ * write.h: Likewise.
+
+2000-09-11 Kazu Hirata <kazu@hxi.com>
+
+ * bignum-copy.c: Fix formatting.
+ * config/tc-i370.c: Likewise.
+ * config/tc-i960.c: Likewise.
+ * config/tc-m68k.c: Likewise.
+ * ehopt.c: Likewise.
+ * flonum-copy.c: Likewise.
+ * flonum-konst.c: Likewise.
+ * flonum-mult.c: Likewise.
+ * literal.c: Likewise.
+ * read.c: Likewise.
+ * sb.c: Likewise.
+ * stabs.c: Likewise.
+ * subsegs.c: Likewise.
+
+2000-09-09 Philip Blundell <philb@gnu.org>
+
+ * configure.in (arm*-*-uclinux*): New target.
+ * configure: Regenerate.
+
+2000-09-09 Kazu Hirata <kazu@hxi.com>
+
+ * input-file.c: Fix formatting.
+ * itbl-ops.c: Likewise.
+ * messages.c: Likewise.
+
+2000-09-08 Philip Blundell <philb@gnu.org>
+
+ * config/tc-arm.c (md_apply_fix3): Correct handling of ADRL when
+ offset is negative.
+
+2000-09-07 H.J. Lu <hjl@gnu.org>
+
+ * configure.in (AC_ISC_POSIX): Put after AC_CANONICAL_SYSTEM.
+ * configure: Rebuild.
+
+2000-09-07 Kazu Hirata <kazu@hxi.com>
+
+ * atof-generic.c: Fix formatting.
+ * config/tc-mips.c: Likewise.
+ * config/tc-vax.c: Likewise.
+ * input-scrub.c: Likewise.
+
+2000-09-07 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-sh.h (TARGET_FORMAT): Use sh-linux targets.
+ * configure.in (sh-*-linux*): Added.
+ * configure: Rebuilt.
+
+2000-09-06 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-hppa.c: Fix formatting.
+
+ * ecoff.c: Fix formatting.
+
+2000-09-06 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure: Rebuilt with new libtool.m4.
+
+2000-09-05 Kazu Hirata <kazu@hxi.com>
+
+ * cgen.c: Fix formatting.
+ * config/tc-ia64.c: Likewise.
+
+2000-09-05 Nick Clifton <nickc@redhat.com>
+
+ * aclocal.m4: Regenerate.
+ * config.in: Regenerate.
+ * configure: Regenerate.
+ * po/gas.pot: Regenerate.
+
+2000-09-05 Hans-Peter Nilsson <hp@axis.com>
+
+ * config/tc-cris.c: Correct comment typos.
+
+2000-09-05 Eric Christopher <echristo@cygnus.com>
+
+ * config/tc-mn10300.c: Cleanup.
+ (md_pcrel_from): Enable.
+
+2000-09-05 Alan Modra <alan@linuxcare.com.au>
+
+ * expr.c (operand): Fix a comment typo.
+ * write.c (write_relocs): Fix a signed/unsigned warning.
+
+ * config/tc-hppa.c (fudge_reg_expressions): New
+ (hppa_force_reg_syms_absolute): New.
+ (pa_equ): Allow reg_section expressions.
+ * config/tc-hppa.c (md_optimize_expr): Define.
+ (hppa_force_reg_syms_absolute): Prototype.
+
+ * config/tc-hppa.c (pa_11_fp_reg_struct): Delete.
+ (pa_parse_number): Pass in arg to select fp reg parsing.
+ Return 1 to indicate format checks pass. If strict, then only
+ accept a register or register symbol. Return value in...
+ (pa_number): New static for pa_parse_number.
+ (FP_REG_BASE): Define.
+ (FP_REG_RSEL): Define.
+ (pre_defined_registers): Apply FP_REG_BASE and FP_REG_RSEL as
+ appropriate. White space changes.
+ (need_pa11_opcode): Don't bother passing any params, get them from
+ globals instead.
+ (pa_ip): Modify all calls to pa_parse_number and need_pa11_opcode.
+ Remove extraneous check in case 'Q'.
+ (pa_equ): Modify call to pa_parse_number to do strict parsing. If
+ reg, set section of resulting symbol to reg_section.
+ (pa_parse_space_stmt): Modify call to pa_parse_number.
+ (pa_space): Likewise.
+
+ * config/tc-hppa.c: (md_apply_fix): Handle vtable relocs.
+ (hppa_force_relocation): Handle vtable relocs.
+ (pa_vtable_entry): New.
+ (pa_vtable_inherit): New.
+ (md_pseudo_table): Add entries for vtable pseudos.
+ (hppa_fix_adjustable): Reject reduction of R_PARISC_GNU_VTINHERIT
+ and R_PARISC_GNU_VTENTRY relocs. Reject reduction of relocs
+ against weak syms.
+ (tc_gen_reloc): Remove ELF_ARG_RELOC_INSN code.
+ (pa_type_args): Don't call symbol_get_bfdsym multiple times.
+ Set STT_PARISC_MILLICODE for OBJ_ELF when encountering a
+ millicode import.
+ * config/obj-elf.c (obj_elf_type): Allow md_elf_symbol_type to
+ specify a symbol type.
+
+ * config/tc-hppa.h: Reorganize file a little, grouping OBJ_ELF
+ dependent things together.
+ (md_elf_symbol_type): Define.
+
+ * config/tc-hppa.c (fix_new_hppa): Elide "$PIC_pcrel$0" pseudo
+ symbol.
+ * config/tc-hppa.h (tc_frob_symbol): Elide "$PIC_pcrel$0" here too.
+
+ * config/obj-elf.h (obj_elf_vtable_inherit): Declare.
+ (obj_elf_vtable_entry): Declare.
+
+ * config/obj-elf.c (obj_elf_vtable_inherit): Return struct fix *
+ and export function.
+ (obj_elf_vtable_entry): Similarly.
+ (elf_pseudo_table): Fix the damage with a cast.
+
+2000-09-03 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-ia64.c (emit_one_bundle): Stop collecting insns
+ for template selection when a label is needed.
+
+2000-09-02 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-ia64.c: Fix formatting.
+
+2000-09-02 Nick Clifton <nickc@redhat.com>
+
+ * configure.in: Increase version number to 2.10.91.
+ * configure: Regenerate.
+ * aclocal.m4: Regenerate.
+ * config.in: Regenerate.
+ * po/gas.pot: Regenerate.
+ * Makefile.in: Regenerate.
+
+2000-09-01 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-sh.h [OBJ_ELF] (TC_FIX_ADJUSTABLE): Define.
+ * config/tc-sh.c (md_apply_fix): Map 32-bit relocations that
+ become PC-relative to BFD_RELOC_32_PCREL. Reject 16- or 8-bit
+ similar relocs.
+ (sh_obj_adjustable): Return 1 for PC-relative offsets used in
+ branches.
+
+2000-09-01 Niibe Yutaka <gniibe@m17n.org>, Kaz Kojima <kkojima@rr.iij4u.or.jp>, Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-sh.h (DIFF_EXPR_OK, GLOBAL_OFFSET_TABLE_NAME,
+ TC_RELOC_GLOBAL_OFFSET_TABLE, TC_RELOC_RTSYM_LOC_FIXUP): Define.
+ * config/tc-sh.c (sh_elf_cons, sh_elf_suffix): New functions.
+ [OBJ_ELF] (md_pseudo_table) <long, int, word, short>: Use them.
+ (GOT_symbol): New variable.
+ (md_undefined_symbol): Set it.
+
+2000-09-01 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-ia64.c (match): Don't inline.
+ (extra_goodness): New.
+ (md_begin): Prefer nop.f and nop.b for best_template.
+
+2000-08-31 Kazu Hirata <kazu@hxi.com>
+
+ * as.c: Fix formatting.
+ * cond.c: Likewise.
+ * frags.c: Likewise.
+ * macro.c: Likewise.
+
+2000-08-31 Eric Christopher <echristo@cygnus.com>
+
+ * config/tc-mn10300.c: Cleanup and fix warnings.
+ (md_pseudo_table): Add initializers.
+ (md_show_usage): Cleanup.
+ (md_parse_option): Fix warnings.
+ (md_undefined_symbol): Fix warnings.
+ (md_conver_frag): Fix warnings.
+ (tc_gen_reloc): Fix warnings.
+ (md_apply_fix3): Fix warnings.
+ (check_operand): Fix warnings.
+
+2000-08-31 Alexandre Oliva <aoliva@redhat.com>
+
+ * acinclude.m4: Include libtool and gettext macros from the
+ top level.
+ * aclocal.m4, configure: Rebuilt.
+
+2000-08-30 Mark Hatle <mhatle@mvista.com>
+
+ * config/tc-ppc.c (md_parse_option): Recognize -m405.
+
+2000-08-31 Kazu Hirata <kazu@hxi.com>
+
+ * listing.c: Fix formatting.
+
+2000-08-29 Kazu Hirata <kazu@hxi.com>
+
+ * app.c: Fix a comment typo. Fix formatting.
+
+2000-08-25 J. David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * config/tc-vax.c (md_convert_frag): Correctly calculate the pc relative
+ offset of the target destination for jmp instructions.
+ (md_assemble): Change mode to VAX_ABSOLUTE_MODE as per comments.
+
+2000-08-24 Hans-Peter Nilsson <hp@axis.com>
+
+ * NEWS: Mention support for CRIS.
+
+2000-08-24 Denis Chertykov <denisc@overta.ru>
+
+ * config/tc-avr.h (TC_IMPLICIT_LCOMM_ALIGNMENT): New macros.
+ Sets `.lcomm' alignment to zero.
+
+2000-08-23 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-i386.h (OBJ_MAYBE_ELF, OBJ_MAYBE_COFF,
+ TC_FIX_ADJUSTABLE): Define.
+
+2000-08-23 Jim Wilson <wilson@cygnus.com>
+
+ * config/tc-ia64.c (output_unw_records): Set U & E flags only if
+ unwind.personality_routine is set.
+
+2000-08-23 H.J. Lu <hjl@gnu.org>
+
+ * write.c (TC_FIX_ADJUSTABLE): Remove the duplicate.
+
+2000-08-23 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-i386.h (TC_FIX_ADJUSTABLE): Do *NOT* define if target
+ environment is pe.
+
+2000-08-22 H.J. Lu <hjl@gnu.org>
+
+ * config.in (STRICTCOFF): New for strict COFF.
+
+ * configure.in: Define STRICTCOFF for i386-*-msdosdjgpp*,
+ i386-*-go32* and i386-go32-rtems*.
+ * configure: Rebuilt.
+
+ * config/obj-coff.c (obj_coff_endef): Follow the historical
+ behavior if STRICTCOFF is not defined.
+
+ * doc/internals.texi: Document STRICTCOFF.
+
+2000-08-22 Alexandre Oliva <aoliva@redhat.com>
+
+ * write.c (TC_FIX_ADJUSTABLE): Define to 1, if not defined.
+ (fixup_segment) Use it instead of TC_DONT_FIX_NON_ADJUSTABLE.
+ * config/tc-i386.h (TC_DONT_FIX_NON_ADJUSTABLE): Remove.
+ <OBJ_ELF, OBJ_COFF, TE_PE> (TC_FIX_ADJUSTABLE): Define.
+ * config/tc-arm.h (TC_DONT_FIX_NON_ADJUSTABLE): Remove.
+ <OBJ_ELF> (TC_FIX_ADJUSTABLE): Define.
+ * config/tc-i960.h, config/tc-m68k.h, config/tc-v850.h:
+ Likewise.
+
+2000-08-22 Eric Christopher <echristo@cygnus.com>
+
+ * config/tc-mn10300.c: (md_apply_fix): New function.
+ (mn10300_force_relocation): New function.
+ (mn10300_fix_adjustable): New function.
+
+ * config/tc-mn10300.h: (TC_FORCE_RELOCATION): Define.
+ (TC_HANDLES_FX_DONE): Define.
+ (obj_fix_adjustable): Define.
+ (MD_APPLY_FIX3): Define.
+ (TC_LINKRELAX_FIXUP): Define.
+
+ * write.c: (TC_LINKRELAX_FIXUP): Define if not
+ previously defined.
+ (fixup_segment): Use TC_LINKRELAX_FIXUP.
+
+ * doc/internals.texi: Document TC_LINKRELAX_FIXUP.
+
+2000-08-21 Jason Eckhardt <jle@cygnus.com>
+
+ * config/tc-i860.c (md_apply_fix3): Do not insert the immediate
+ if the fixup resulted in a relocation.
+
+2000-08-18 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (decode_shift): Replace as_tsktsk with as_warn.
+ Make reference to first element of shift_names explicit.
+
+2000-08-18 Alexandre Oliva <aoliva@redhat.com>
+
+ * write.c (fixup_segment) [TC_DONT_FIX_NON_ADJUSTABLE]: Use
+ obj_fix_adjustable() and tc_fix_adjustable() to tell whether to
+ add a symbol's address. Removed all target-specific #ifdefs that
+ used to accomplished the same.
+ * config/tc-v850.h (TC_DONT_FIX_NON_ADJUSTABLE): Define.
+ * config/tc-m68k.h (TC_DONT_FIX_NON_ADJUSTABLE): Define.
+ * config/tc-arm.h (TC_DONT_FIX_NON_ADJUSTABLE): Define.
+ * config/tc-i960.h (TC_DONT_FIX_NON_ADJUSTABLE): Define.
+ * config/tc-i386.h (TC_DONT_FIX_NON_ADJUSTABLE): Define.
+
+2000-08-17 Kazu Hirata <kazu@hxi.com>
+
+ * dwarf2dbg.c: Fix formatting.
+
+2000-08-17 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (decode_shift): Allow illegal shifts by zero
+ to be recoded as logical shift lefts by zero.
+
+2000-08-16 Jim Wilson <wilson@cygnus.com>
+
+ * config/tc-ia64.c (specify_resource, case IA64_RS_GR): Handle
+ postincrement modified registers. Handle IA64_OPND_R3_2 addl
+ source registers.
+ (note_register_values): Handle IA64_OPND_R3_2 operands.
+
+2000-08-16 Jason Eckhardt <jle@cygnus.com>
+
+ * config/tc-i860.c (md_operand): Silly typo fixed.
+
+2000-08-16 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (struct asm_shift): Delete.
+ (shift[]): Delete.
+ (enum asm_shift_index): New.
+ (struct asm_shift_properties): New.
+ (struct asm_shift_name): New.
+ (shift_properties[]); New.
+ (shift_names[]); New.
+
+ (decode_shift): Use new structures.
+ Issue a warning is "ROR #0" is used.
+ Issue a warning if "ASR #0" or "LSR #0" is used.
+
+ (md_begin): Initialise arm_shift_hsh table from new
+ asm_shift_name array.
+
+2000-08-16 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-sparc.c: Kill all warnings.
+ (md_parse_option): Set -32/-64 for -xarch=, allow all -A archs
+ in -xarch= as well.
+ (md_show_usage): Update usage text.
+
+2000-08-16 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (do_bx): Warn about "bx px" not being very
+ useful.
+
+2000-08-15 Will Cohen <wcohen@redhat.com>
+
+ * config/tc-sh.h (DWARF2_LINE_MIN_INSN_LENGTH): Defined.
+
+ * config/tc-sh.c (md_assemble): Changed so debug_type
+ test performed for ppi_assemble
+ * config/tc-sh.c: Included dwarf2dbg.h.
+ (debug_line): Defined.
+ (md_assemble): Generates dwarf2 line info.
+ (sh_finalize): New function. Finalize dwarf2 info.
+ (assemble_ppi): Returns size of code generated.
+ (build_Mytes): Returns size of code generated.
+ (md_pseudo_table): Added "file" and "loc" psuedo ops.
+ * config/tc-sh.h (md_end): Defined.
+ (sh_finalize): Declared.
+
+2000-08-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-sh.c (md_apply_fix) [BFD_RELOC_32, BFD_RELOC_16]: Use
+ md_number_to_chars.
+
+2000-08-14 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (do_bx): Allow "bx pc".
+
+2000-08-14 Jim Wilson <wilson@cygnus.com>
+
+ * config/tc-ia64.c (md_longopts): Add -mconstant-gp and -mauto-pic.
+ (md_parse_option): Add OPTION_MCONSTANT_GP and OPTION_MAUTO_PIC.
+ (md_begin): Change assignment to md.flag to OR in the new bit.
+
+2000-08-14 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * config/obj-coff.c (obj_coff_endef) [BFD_ASSEMBLER]: Set the debug
+ flag for storage types C_ARG, C_REGPARM, C_FIELD, C_MOS, C_MOE,
+ C_MOU, and C_EOS.
+
+2000-08-14 Jason Eckhardt <jle@cygnus.com>
+
+ * NEWS: Mention i860 support.
+
+2000-08-14 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.h (DWARF2_LINE_MIN_INSN_LENGTH): Define.
+
+2000-08-14 Andreas Schwab <schwab@suse.de>
+
+ * doc/c-arm.texi (ARM Directives): Fix warnings from makeinfo.
+
+2000-08-11 Andreas Schwab <schwab@suse.de>
+
+ * doc/c-i860.texi (Opcodes for i860): Remove braces from @item
+ argument.
+
+2000-08-11 Kazu Hirata <kazu@hxi.com>
+
+ * expr.c: Fix formatting.
+ * config/obj-bout.c: Likewise.
+
+2000-08-10 Jason Eckhardt <jle@cygnus.com>
+
+ * doc/c-i860.texi: Flesh out the i860 section more.
+
+2000-08-10 Kazu Hirata <kazu@hxi.com>
+
+ * symbols.c: Fix formatting.
+ * expr.c: Likewise.
+
+2000-08-09 Diego Novillo <dnovillo@cygnus.com>
+
+ * config/tc-i386.c (md_assemble): Skip suffix check if the opcode
+ modifier has the IgnoreSize bit set.
+
+2000-08-09 Alan Modra <alan@linuxcare.com.au>
+
+ From Rodney Brown <RodneyBrown@mynd.com>
+ * configure.in: Use elf on Unixware 7 (i586-sco-sysv5uw7.1.0)
+ * configure: Regenerate.
+
+2000-08-09 Kazu Hirata <kazu@hxi.com>
+
+ * hash.c: Fix formatting.
+ * gasp.c: Likewise.
+
+2000-08-08 Jason Eckhardt <jle@cygnus.com>
+
+ * config/tc-i860.h: Rework completely for BFD_ASSEMBLER.
+ (i860_fix_info): New enum.
+ (MD_APPLY_FIX3): Define.
+ (WORKING_DOT_WORD): Define.
+ (TC_HANDLES_FX_DONE): Define.
+ (DIFF_EXPR_OK): Define.
+ (LISTING_HEADER): Define.
+ (TARGET_FORMAT): Select target format based on endian flag.
+ (TARGET_BYTES_BIG_ENDIAN): Default to little endian.
+ (target_big_endian): Add external declaration.
+
+ * config/tc-i860.c: All existing code reworked completely. Other
+ new code shown below.
+ (SYNTAX_SVR4): Define.
+ (target_warn_expand): New variable.
+ (md_shortopts): Declare and define (-Qy, -Qn, and -V options).
+ (md_longopts): Declare and define with new options (-EL, -EB,
+ and -mwarn-expand).
+ (md_show_usage): New function.
+ (md_operand): New function.
+ (obtain_reloc_for_imm16): New function.
+ (md_apply_fix3): New function.
+ (tc_gen_reloc): New function.
+
+2000-08-08 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * config/tc-m68hc11.c (build_jump_insn): Make sure the
+ 2 bytes of the jump address are in the same frag.
+ (find): Accept 68hc12 register indirect modes.
+
+ * NEWS: Mention 68HC11 & 68HC12 support.
+
+2000-08-07 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-ia64.c (unwind): Add prologue_mask member.
+ (dot_vframe): Elide psp_gr record if it overlaps prologue_gr.
+ (dot_save): Likewise for pfs_gr, rp_gr, and preds_gr.
+ (dot_body): Clear unwind.prologue_mask.
+ (dot_prologue): Set it. Accept a register second argument.
+
+2000-08-07 Kazu Hirata <kazu@hxi.com>
+
+ * config/atof-ieee.c: Fix formatting.
+ * config/atof-tahoe.c: Likewise.
+
+2000-08-06 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-sparc.c (md_begin): Fix typo in recent formatting
+ work.
+
+ * doc/as.texinfo (Pseudo Ops): Update to include descriptions
+ of .popsection, .previous, .pushsection, .subsection,
+ .version, .vtable_entry, .vtable_inherit and .weak.
+
+2000-08-05 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-cris.c: Fix formatting.
+ * config/tc-i386.c: Likewise.
+ * config/tc-sparc.c (sparc_ip): Simplify the code.
+
+2000-08-04 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-cris.c: Rearrange code for readability.
+ * config/tc-d10v.c: Fix formatting.
+ * config/tc-m32r.c: Likewise.
+ * config/tc-sparc.c: Likewise.
+
+2000-08-02 Jim Wilson <wilson@cygnus.com>
+
+ * config/tc-ia64.c (emit_one_bundle): Call ia64_free_opcode
+ before ia64_find_opcode.
+ (md_assemble): Likewise.
+
+2000-08-01 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (do_mrs): Fix skip of 'cpsr_all' flag.
+ Undo some formatting fixes.
+
+2000-08-01 Kazu Hirata <kazu@hxi.com>
+
+ * config/obj-som.c: Fix formatting.
+ * config/obj-ieee.c: Likewise.
+ * config/tc-arm.c: Likewise.
+ * config/tc-v850.c: Likewise.
+
+2000-08-01 Nick Clifton <nickc@redhat.com>
+
+ * doc/c-m68k.texi (section M680x0 Options): Turn into a table
+ index by command line option.
+
+2000-08-01 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * doc/c-m68k.texi (@cindex @samp{--pcrel}): Rewrite option description.
+ (@node M68K-Branch): Rewrite to match the reality.
+
+2000-07-31 Jason Eckhardt <jle@cygnus.com>
+
+ * doc/c-i860.texi: New file.
+ * doc/Makefile.am (CPU_DOCS): Add c-i860.texi.
+ * doc/Makefile.in: Regenerate.
+ * doc/all.texi: Add I860 as relevant architecture.
+ * doc/as.texinfo: Include i860 dependent file c-i860.texi.
+
+2000-07-31 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-d30v.c: Fix formatting.
+
+2000-07-31 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * config/tc-m68k.c (flag_keep_pcrel, OPTION_PCREL): Add --pcrel option.
+ (md_convert_frag_1, md_estimate_size_before_relax): When making DBcc
+ long emit a long branch if available instead of an absolute jump, never
+ emit absolute jumps for anything with --pcrel.
+
+ * doc/c-m68k.texi: Document new command line option.
+
+2000-07-29 Marek Michalkiewicz <marekm@linux.org.pl>
+
+ * config/tc-avr.c: Use PARAMS macro in function declarations.
+ Don't declare md_pcrel_from_section (already in tc-avr.h).
+ (avr_operands): Use AVR_UNDEF_P and AVR_SKIP_P macros.
+ (avr_operand): Don't set (unsigned) op_mask to -1.
+
+2000-07-28 Jason Eckhardt <jle@cygnus.com>
+
+ * configure.in: Add bits for i860-stardent-{sysv4, elf}*.
+ * configure: Regenerated.
+ * config/obj-elf.c (obj_elf_type): Recognize a fifth type
+ of operand to the .type directive (.e.g, "type").
+
+2000-07-28 Alan Modra <alan@linuxcare.com.au>
+
+ * as.h (warn_comment, found_comment, found_comment_file): Declare.
+ * app.c (do_scrub_chars): Record where first comment found.
+ * read.c (read_a_source_file): Init found_comment on entry, and
+ notify whether comments found on exit.
+ * config/tc-hppa.c (md_shortopts): Add "c".
+ (md_longopts): Add warn-comment.
+ (md_parse_option): Handle it.
+ (md_show_usage): Show available options.
+ * config/tc-hppa.h (WARN_COMMENTS): Define if TE_LINUX
+
+2000-07-27 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/tc-mn10300.c (md_convert_frag): Fix printfs.
+ (tc_gen_reloc): Add cast when assigning bfd_abs_symbol to
+ sym_ptr_ptr
+ (md_estimate_size_before_relax): Don't fall off end of function.
+
+2000-07-27 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-avr.c: Fix formatting.
+ * config/tc-ns32k.c: Likewise.
+
+2000-07-27 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-d10v.c (find_opcode): Remove extraneous `='.
+
+2000-07-27 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-d10v.c: Fix formatting.
+ * config/tc-z8k.c: Likewise.
+ * config/tc-sparc.c: Likewise.
+
+2000-07-26 Dave Brolley <brolley@redhat.com>
+
+ * cgen.c (queue_fixup): Declare opinfo.
+ (gas_cgen_parse_operand): Mark unused parameters with ATTRIBUTE_UNUSED.
+ (gas_cgen_md_operand): Ditto.
+ (gas_cgen_md_apply_fix3): Ditto.
+
+2000-07-24 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * config/obj-coff.c (obj_frob_symbol): Don't merge
+ labels. Don't merge if the symbol isn't constant. Return
+ immediately if a symbol is merged.
+
+2000-07-22 Alan Modra <alan@linuxcare.com.au>
+
+ * frags.c (frag_align): Correct absolute section alignment.
+
+2000-07-20 DJ Delorie <dj@redhat.com>
+
+ * config/obj-coff.c (obj_frob_symbol): revert previous change,
+ it breaks linking against DLLs.
+
+2000-07-20 Hans-Peter Nilsson <hp@axis.com>
+
+ * configure.in: Add CRIS support.
+ * configure: Regenerate.
+ * Makefile.am: (CPU_TYPES): Add cris.
+ (CPU_OBJ_VALID) [aout]: Add cris.
+ (MULTI_CPU_TYPES): Add cris.
+ (MULTI_CPU_OBJ_VALID) [aout]: Add cris.
+ [coff]: Only i386 and mips are valid.
+ (TARGET_CPU_CFILES): Add config/tc-cris.c.
+ (TARGET_CPU_HFILES): Add config/tc-cris.h.
+ (MULTI_CFILES): Add config/e-crisaout.c and config/e-criself.c.
+ Regenerate dependencies.
+ * Makefile.in: Regenerate.
+ * aclocal.m4: Regenerate.
+ * as.c: Declare crisaout, criself.
+ * config/tc-cris.h, config/tc-cris.c: New.
+ * config/e-criself.c, config/e-crisaout.c: New.
+ * po/POTFILES.in, po/gas.pot: Regenerate.
+
+2000-07-20 Kazu Hirata <kazu@hxi.com>
+
+ * read.c: Fix formatting.
+ * write.c: Fix formatting.
+
+2000-07-19 H.J. Lu <hjl@gnu.org>
+
+ * sb.c: Include <stdlib.h> if exists for abort ().
+
+2000-07-19 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.c (hppa_fix_adjustable): Correct LR%/RR% comment.
+ (arg_reloc_stub_needed): #ifdef OBJ_SOM, not #ifdef SOM.
+ (pa_type_args): Same here.
+
+2000-07-17 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * config/obj-coff.c (obj_frob_symbol): Don't merge labels. Don't
+ merge if the symbol isn't constant. Don't call S_SET_EXTERNAL if
+ the storage class is already set.
+
+2000-07-17 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-m68hc11.c: Fix formatting.
+ * config/tc-mn10200.c: Likewise.
+ * config/tc-mn10300.c: Likewise.
+ * config/tc-pj.c: Likewise.
+ * config/tc-tic80.c: Likewise.
+ * config/tc-w65.c: Likewise.
+
+2000-07-17 Frank Ch. Eigler <fche@redhat.com>
+
+ * expr.c (operand): Permit %bin literals if LITERAL_PREFIXPERCENT_BIN
+ is defined.
+
+2000-07-15 Ian Lance Taylor <ian@zembu.com>
+
+ * doc/c-mips.texi (MIPS Opts): Remove erroneous space after
+ @code.
+
+2000-07-15 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.c (hppa_fix_adjustable): Use the same checks for
+ ELF as are used for SOM (except the 32-bit reloc one) to decide
+ whether a symbol can be reduced to a section symbol. Expand on
+ the comment for symbols involved in LR% and RR% expressions.
+
+2000-07-14 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mips.c (mips_disable_float_construction): New
+ static variable. Set to true if doubles should not be
+ constructed by loading two single width fp registers with
+ halves of the value.
+ (mips_ip): Test mips_disable_float_construction.
+ (md_longopts): Add command line switches --construct-floats
+ and --no-construct-floats.
+ (md_parse_option): Parse new command line options.
+ (md_show_usage): Describe new command line options.
+
+ * doc/c-mips.texi: Document new command line options.
+
+2000-07-13 Koundinya K <kk@ddeorg.soft.net>
+
+ * configure.in: Remove the test /usr/dde for mips-*-sysv4*MP*
+ * configure: Regenerate.
+
+2000-07-13 Hans-Peter Nilsson <hp@axis.com>
+
+ * configure.in (DEFAULT_EMULATION setting): Revert part of
+ 2000-07-01 change that set te_multi=multi unless set to tmips.
+ * configure: Regenerate.
+
+2000-07-12 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * config/obj-coff.c (coff_frob_section): Add padding to the last
+ section when aligning it increases its size.
+
+2000-07-11 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-tic54x.c: Fix formatting.
+
+2000-07-10 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-h8500.c: Fix formatting.
+ * config/tc-tic54x.c: Fix formatting.
+
+2000-07-10 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.c (md_apply_fix): Check fmt 12 and 22 pc-rel
+ displacements correctly.
+
+ * read.h (s_abort): Add ATTRIBUTE_NORETURN.
+
+2000-07-10 Ryan Bradetich <rbradetich@uswest.net>
+
+ * hash.c (hash_insert): Add cast to obstruct_alloc to fix
+ warning.
+ (hash_jam): Ditto.
+
+2000-07-09 Alan Modra <alan@linuxcare.com.au>
+
+ From David Huggins-Daines <dhd@linuxcare.com>
+ * config/te-hppalinux64.h: Add a new emulation.
+ * configure.in (emulations): Add configure bits to support the
+ 64-bit Linux/parisc target.
+ * configure: Regenerate.
+
+ * config/tc-hppa.c (md_parse_option): Support `-V' for ELF.
+ (md_shortopts): Add `V' for ELF.
+
+ * config/tc-hppa.c (arg_reloc_stub_needed): Define as zero except
+ when SOM or ELF_ARG_RELOC are defined.
+ (pa_type_args): Only set symbol_arg_reloc_info when SOM or
+ ELF_ARG_RELOC are defined.
+ (pa_stringer_aux): Don't pa_check_current_space_and_subspace here..
+ (pa_stringer): ..Do it here instead. Fix comment typos.
+ (hppa_force_relocation): Cast enums to int before comparing with
+ ints.
+
+ From Ryan Bradetich <rbradetich@uswest.net>
+ * config/tc-hppa.c: Removed unneeded libbfd.h to fix macro
+ redifinition warning.
+ (md_apply_fix): Added cast from enum to int for fixP->fx_r_type.
+ (hppa_force_relocation): ditto
+ (md_apply_fix): Added cast to buf to fix warnings.
+
+ * config/tc-hppa.h (pa_define_label, parse_cons_expression_hppa,
+ cons_fix_new_hppa, hppa_force_relocation): Prototype.
+
+ * config/tc-hppa.c (reloc_type): It's an enum for OBJ_ELF.
+ (R_N0SEL, R_N1SEL): Define only for OBJ_SOM.
+ (tc_gen_reloc): Make `code' a reloc_type and `codes' a
+ reloc_type** to avoid warnings in switch.
+ (md_apply_fix): Make insn, val signed. Zap buf_wd and read insn a
+ little earlier instead.
+
+ * config/tc-hppa.c (symbol_arg_reloc_info): Define for both som
+ and elf.
+ (pa_type_args): Use symbol_arg_reloc_info.
+ (struct pa_it): Make arg_reloc unsigned int.
+ (struct hppa_fix_struct): Likewise for fx_arg_reloc.
+ (pa_text, pa_data, pa_comm): Don't compile for TE_LINUX.
+ (pa_code): Delete. pa_text duplicates this function.
+ (md_pseudo_table): Call obj_elf_text for ".code" if TE_LINUX.
+ (fix_new_hppa): Argument offset is offsetT, arg_reloc is unsigned
+ int.
+ (cons_fix_new_hppa): Actually change selector to e_fsel when
+ warning about assuming so.
+ (tc_gen_reloc): More example elf arg reloc code.
+ (md_apply_fix): Use arg_reloc_stub_needed for elf too.
+ (hppa_force_relocation): Likewise.
+
+ * config/tc-hppa.h: Use TARGET_ARCH_SIZE to select target include
+ files.
+ (pa_end_of_source): Prototype.
+ (hppa_fix_adjustable): Prototype.
+ (LABELS_WITHOUT_COLONS): Move it..
+ * config/te-hppa.h: To here.
+
+ * config/te-hppa64.h: New file.
+
+ * config/tc-hppa.c: Use TARGET_ARCH_SIZE to select target reloc
+ type.
+ (md_apply_fix): Pass stdoutput to bfd_hppa_insn2fmt. Handle
+ format -10, -16, 16 relocs.
+ (hppa_elf_mark_end_of_function): Test for null
+ last_call_info->start_symbol
+
+ * config/tc-hppa.c (pa_ip): In case 'V', pass `strict' to
+ CHECK_FIELD, not INSERT_FIELD_AND_CONTINUE. Don't pass opcode to
+ re_assesmble_* functions. Delete extraneous statements. Fix
+ typos in comments.
+ (md_apply_fix): Compare against 1048575 in case 21. Don't pass
+ insn to re_assemble_*.
+
+2000-07-08 Ulf Carlsson <ulfc@engr.sgi.com>
+
+ * doc/internals.texi (Expressions): Fix typo.
+
+2000-07-08 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-sh.c: Fix formatting.
+ * config/tc-tic54x.c: Fix formatting.
+ * depend.c: Fix formatting.
+ * flonum-konst.c: Likewise.
+ * flonum-mult.c: Likewise.
+
+2000-07-07 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-sh.c: Fix comments.
+ * config/obj-vms.c: Fix comments.
+ * config/tc-a29k.c: Likewise.
+ * config/tc-alpha.c: Likewise.
+ * config/tc-h8300.c: Likewise.
+ * config/tc-h8500.c: Likewise.
+ * config/tc-i370.c: Likewise.
+ * config/tc-ia64.c: Likewise.
+ * config/tc-m68hc11.c: Likewise.
+ * config/tc-m68k.c: Likewise.
+ * config/tc-mips.c: Likewise.
+ * config/tc-ns32k.c: Likewise.
+ * config/tc-ppc.c: Likewise.
+ * config/tc-z8k.c: Likewise.
+
+2000-07-06 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * config/obj-coff.c (TC_COFF_SECTION_DEFAULT_ATTRIBUTES): New.
+ Default to '(SEC_LOAD | SEC_DATA)'.
+ (obj_coff_section) [BFD_ASSEMBLER]: Use it.
+
+ * doc/internals.texi (CPU Backend): Describe
+ TC_COFF_SECTION_DEFAULT_ATTRIBUTES.
+
+2000-06-06 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * as.c (parse_args): NULL terminate the long option list.
+
+2000-06-04 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/tc-d30v.h: Include "write.h" for fixS.
+ (d30v_start_line, md_pcrel_from_section): Add function prototypes.
+
+2000-07-05 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (write_2_short): Further changes to warning
+ messages produced when combining EITHER_BUT_PREFER_MU attributed
+ opcodes.
+
+2000-07-05 DJ Delorie <dj@redhat.com>
+
+ * MAINTAINERS: new
+
+2000-07-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-arm.c (psrs): Accept combinations of flags.
+
+2000-07-03 Marek Michalkiewicz <marekm@linux.org.pl>
+
+ * config/tc-avr.c: Change _ () to _() around all strings marked
+ for translation (exception from the usual coding style).
+ (avr_opt): New struct variable, how the new switches are set.
+ (OPTION_MMCU): Define as 'm' and actually use.
+ (md_longopts): Add -mall-opcodes, -mno-skip-bug, -mno-wrap.
+ (show_mcu_list): New function, display the list of known MCUs.
+ (md_show_usage): Document the new switches. Call show_mcu_list.
+ (avr_set_arch): Change 'm' to OPTION_MMCU.
+ (md_parse_option): Call show_mcu_list if unknown MCU specified.
+ Handle the new switches.
+ (avr_operands): Disable warnings for undefined combinations of
+ operands if -mall-opcodes. Disable warnings for skipping two-word
+ instructions if enhanced core or -mno-skip-bug.
+ (avr_operand): Accept all addressing modes on avr1 if -mall-opcodes.
+ (md_apply_fix3): Reject 8K wrap if >8K or -mno-wrap.
+ (md_assemble): Accept opcodes not supported by MCU if -mall-opcodes.
+ (avr_ldi_expression): Warn about implicit lo8().
+ * config/tc-avr.h (md_pcrel_from_section): Add prototype.
+
+2000-07-01 Koundinya K <kk@ddeorg.soft.net>
+
+ * configure.in: Add entry for mips-*-sysv4*MP*
+ * configure: Rebuild
+ * config/tc-mips.c (mips_target_format): Return elf32-tradbigmips or
+ elf32-tradlittlemips for traditional mips targets.
+ * config/tc-mips.c (md_estimate_size_before_relax): Duplicate the
+ test for Link Once sections as in adjust_reloc_syms.
+ * config/te-tmips.h: New file for traditional mips targets. Define
+ TE_TMIPS.
+
+2000-06-29 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * config/obj-coff.c (obj_coff_setcion) [BFD_ASSEMBLER]: If the
+ flags argument is not present, don't change an existing section's
+ section's attributes. If the flags argument is present, warn if the
+ attributes don't match the section's current attributes. When
+ long section names are supported, set SEC_LINK_ONCE and
+ SEC_LINK_DUPLICATES_DISCARD for a new .gnu.linkonce section.
+
+2000-06-29 Hans-Peter Nilsson <hp@axis.com>
+
+ * config/obj-aout.c (obj_aout_type): Do not ignore for undefined
+ symbols; create them.
+
+2000-06-29 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * write.c (set_segment_vma): New: Set vma and lma for a segment.
+ (write_object_file) [BFD_ASSEMBLER && OBJ_COFF && TE_GO32]: Use it.
+
+2000-06-27 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/tc-mips.c (mips_ip): handle "(foo-.-4)" type of
+ expressions. Ignore the problem when handling 16 bit signed
+ immediates, because the assembler will take care of the relocation
+ later.
+
+2000-06-27 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (write_2_short): Do not allow opcodes with
+ the EITHER_BUT_PREFER_MU attribute to be combined into a reverse
+ sequential order, and emit warning messages if the input source
+ code contains constructs like that, or parallel constructs
+ containing such opcodes.
+
+2000-06-26 Marek Michalkiewicz <marekm@linux.org.pl>
+
+ * config/tc-avr.c (mcu_types): Rename avr4 to avr5, add avr4.
+ Add more MCU types for avr4 and avr5. Replace at94k{10,20,40}
+ with just at94k. Change AVR_ISA_85xx back to AVR_ISA_2xxx.
+ (md_show_usage): Update usage message.
+ (md_parse_option): Allow redefinition of MCU type within the
+ same avr[1-5] bfd machine type. Show both old and new MCU type
+ in the error message.
+ (md_apply_fix3): Support 8K wrap if AVR_ISA_MEGA is not set.
+ Simplify 8K wrap code.
+
+2000-06-25 Kazu Hirata <kazu@hxi.com>
+
+ * config/obj-aout.c: Remove all uses of DEFUN.
+ * config/obj-ieee.c: Likewise.
+ * config/tc-sh.c: Fix comment typos.
+ * config/tc-tahoe.c: Likewise.
+ * config/tc-vax.c: Likewise.
+ * config/tc-w65.c: Likewise.
+ * config/tc-z8k.c: Likewise.
+ * config/tc-h8300.c (build_bytes): Assemble ldmac correctly.
+
+2000-06-24 DJ Delorie <dj@cygnus.com>
+
+ * config/tc-i386.c (md_estimate_size_before_relax): Revert
+ more changes from Sept 1999
+ (tc_i386_fix_adjustable): ditto
+ (md_apply_fix3): ditto
+
+2000-06-24 Frank Ch. Eigler <fche@redhat.com>
+
+ * cgen.c (expr_jmp_buf_p): New validity flag for expr_jmp_buf.
+ (gas_cgen_parse_operand): Set it around expression() call.
+ (gas_cgen_md_operand): Test for it before longjmp().
+
+2000-06-24 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-h8500.c: Remove all uses of DEFUN.
+ * config/tc-sh.c: Likewise.
+ * config/tc-w65.c: Likewise.
+ * config/tc-z8k.c: Likewise.
+
+ * config/tc-h8500.c: Fix typos in comments.
+
+2000-06-23 Frank Ch. Eigler <fche@redhat.com>
+
+ * expr.c (operand): Permit $hex literals if LITERAL_PREFIXDOLLAR_HEX
+ is defined.
+
+2000-06-23 matthew green <mrg@redhat.com>
+
+ * expr.c (operand): Do not as_bad() if RELAX_PAREN_GROUPING is
+ defined. Fix error message for `[' grouping.
+
+2000-06-22 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-h8300.c: Fix formatting and comment typos.
+
+2000-06-22 Timothy Wall <twall@cygnus.com>
+
+ * config/tc-ia64.c (note_register_values): Move premature QP
+ notation clearing into the appropriate place.
+
+2000-06-22 Alan Modra <alan@linuxcare.com.au>
+
+ * dep-in.sed: Escape literal `.'s on patterns. Trim off `../'
+ first before anything else. Add bin-bugs.h, emul.h and progress.h
+ Sort list of files as for $(OBJS) in Makefile.am.
+
+ * Makefile.am (DEP): grep for leading `/' in DEPA, and fail if we
+ find one. Remake dependencies.
+ ($(OBJS)): Add bin-bugs.h, emul.h, and progress.h Sort the list.
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+
+ * config/tc-i386.c (i386_displacement): Don't assume a constant
+ displacement is necessarily 16 bits when in 16 bit code mode.
+ (md_assemble): Instead size the displacement here after we know
+ for sure that a .code16gcc operand hasn't automatically added
+ operand size prefixes.
+
+2000-06-21 H.J. Lu <hjl@gnu.org>
+
+ * Makefile.am: Rebuild dependency.
+ * Makefile.in: Rebuild.
+
+2000-06-21 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-h8300.c (parse_reg): Make the function static.
+ (parse_exp): Likewise.
+
+2000-06-20 DJ Delorie <dj@cygnus.com>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Revert change from
+ Sept 1999; RVA relocs need to be treated more like DIR32 relocs
+ for cygwin import libraries to work properly.
+
+2000-06-20 H.J. Lu <hjl@gnu.org>
+
+ * Makefile.am: Rebuild dependency.
+ * Makefile.in: Rebuild.
+ * configure: Likewise.
+ * doc/Makefile.in: Likewise.
+
+2000-06-20 Timothy Wall <twall@cygnus.com>
+
+ * doc/internals.texi (CPU backend): Add @itemx for
+ TC_START_LABEL_WITHOUT_COLON.
+ * doc/c-tic54x.texi: New.
+ * doc/as.texinfo: Add tic54x features and include primary tic54x
+ documentation file.
+ * doc/all.texi: Add C54X.
+ * doc/Makefile.am (CPU_DOCS): Add c-tic54x.texi.
+ * doc/Makefile.in: Regenerate.
+ * configure.in: Add tic54x and define LIBM for tic54x.
+ * configure: Regenrate.
+ * config/tc-tic54x.[ch]: New.
+ * config/obj-coff.h: Add tic54x.
+ * Makefile.am: (CPU_TYPES): Add tic54x.
+ (TARGET_CPU_CFILES): Add 'tc-tic54x.c'.
+ (TARGET_CPU_HFILES): Add 'tc-tic54x.h'.
+ (as_new_LDADD): Add $(LIBM).
+ * Makefile.in: Regenerate.
+
+2000-06-18 Stephane Carrez <stcarrez@worldnet.fr>
+
+ * doc/Makefile.am (CPU_DOCS): Added 68hc11 file.
+ * doc/c-m68hc11.texi: Document 68HC11 and 68HC12 port.
+ * doc/as.texinfo: Likewise.
+
+ * configure, Makefile.in: Regenerate.
+ * configure.in (emulations): Recognize m6811 and m6812.
+ * Makefile.am (CPU_TYPES, TARGET_CPU_CFILES, TARGET_CPU_HFILES):
+ Added files for 68hc11 and 68hc12 assembler.
+ * config/tc-m68hc11.c: Assembler for 68hc11 and 68hc12.
+ * config/tc-m68hc11.h: Header definition for that assembler.
+
+2000-06-18 Nick Clifton <nickc@redhat.com>
+
+ * symbols.c (resolve_symbol_value): Use bfd_octets_per_byte
+ instead of OCTETS_PER_BYTE.
+
+ * config/tc-v850.c: Fix compile time warnings.
+ * config/tc-ppc.c: Fix compile time warnings.
+
+2000-06-18 H.J. Lu <hjl@gnu.org>
+
+ * configure.in: Don't emulate i386-pc-pe-coff with i386coff.
+ * configure: Rebuild.
+
+2000-06-17 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * config/obj-coff.c (obj_coff_weak): Typo fix: Change BFD_ASSEMLER
+ to BFD_ASSEMBLER.
+
+2000-06-16 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mips.c (md_parse_option): Accept RM5200,RM5230,
+ RM5231, RM5261, RM5721 and RM7000 as r5000 cpu variants.
+
+ * doc/c-mips.texi: Document newly accepted cpu variants.
+
+2000-06-15 Ulf Carlsson <ulfc@engr.sgi.com>
+
+ * config/tc-mips.h: Remove definition of ONLY_STANDARD_ESCAPES.
+
+2000-06-13 Ulf Carlsson <ulfc@engr.sgi.com>
+
+ * macro.c (getstring): Make it possible to escape the quote
+ character.
+
+2000-06-13 Catherine Moore <clm@redhat.com>
+
+ * config/tc-hppa.c (pa_export): Weak symbols can be global.
+
+2000-06-13 H.J. Lu <hjl@gnu.org>
+
+ * configure: Regenerate.
+
+2000-06-09 Alan Modra <alan@linuxcare.com.au>
+
+ * app.c (do_scrub_begin): Don't default lex[';'] as a line
+ separator.
+ * doc/internals.texi (line_separator_chars): Semicolon is no
+ longer a default. Mention null and newline as defaults.
+
+ * read.c (is_end_of_line): Remove ifdef TC_HPPA.
+
+ * config/tc-i386.h (line_separator_chars): Explicitly mention `;'
+ * config/tc-i860.h (line_separator_chars): Likewise.
+ * config/tc-h8300.c (line_separator_chars): Likewise.
+ * config/tc-i960.c (line_separator_chars): Likewise.
+ * config/tc-m68k.c (line_separator_chars): Likewise.
+ * config/tc-mips.c (line_separator_chars): Likewise.
+ * config/tc-ns32k.c (line_separator_chars): Likewise.
+ * config/tc-sparc.c (line_separator_chars): Likewise.
+ * config/tc-vax.c (line_separator_chars): Likewise.
+
+ * config/tc-h8300.c (comment_chars): Use string initialiser.
+ * config/tc-i960.c (line_comment_chars): Likewise.
+ * config/tc-z8k.c (comment_chars, line_comment_chars,
+ line_separator_chars): Likewise.
+
+ * config/tc-arm.c (line_separator_chars): Always use `;', not just
+ for TE_LINUX.
+
+2000-06-08 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (cons_fix_new_arm): Assign correct reloc value
+ for size 1 fixes.
+
+2000-06-08 David O'Brien <obrien@FreeBSD.org>
+
+ * configure.in (VERSION): Update to show this is the CVS mainline.
+
+2000-06-08 Matthew Jacob <mjacob@feral.com>
+
+ * config/tc-alpha.c (md_undefined_symbol): Properly understand that
+ $at is the integer register $r28, vs. both $r28 and the floating
+ point register $f28.
+
+2000-06-08 James E. Wilson <wilson@cygnus.com>
+
+ * config/tc-ia64.c (generate_unwind_image): Call ia64_flush_insns.
+ (dot_endp): Don't call ia64_flush_insns.
+ (emit_one_bundle): Don't delete prologue/body records from
+ unwind_record list in first loop. Rewrite second loop to account for
+ this.
+
+2000-06-07 David Mosberger <davidm@hpl.hp.com>
+
+ * config/tc-ia64.c: Add missing prototypes.
+ (generate_unwind_image): Cast argument to output_unw_records call.
+
+2000-06-07 Denis Chertykov <denisc@overta.ru>
+
+ * config/tc-avr.c (avr_operand): fix the formatting of the comment.
+
+2000-06-07 Denis Chertykov <denisc@overta.ru>
+
+ * config/tc-avr.c (AVR_ISA_???): moved to include/opcode/avr.h
+ (REGISTER_P): likewise.
+ (avr_opcodes): uses include/opcode/avr.h
+ (avr_operand): enable ld r,Z or st r,Z for at90s1200.
+
+2000-06-04 Alan Modra <alan@linuxcare.com.au>
+
+ * read.c (is_end_of_line): No ';' for TC_HPPA. Add missing
+ initializers too.
+
+2000-06-03 H.J. Lu <hjl@gnu.org>
+
+ * read.c (is_end_of_line): Put back `;'.
+
+2000-06-03 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-i386.c (md_shortopts): Remove 'm', add 'q' to non-elf.
+
+2000-06-01 Alan Modra <alan@linuxcare.com.au>
+
+ * expr.c (operand): Test is_end_of_line outside switch to catch
+ line separator chars that are also operators.
+ (operator): Return O_illegal for line separator chars.
+
+ * read.c (is_end_of_line): Use 1 instead of 99. Don't set `;'
+ entry (or `!' entry for TC_HPPA).
+
+ * config/tc-arm.c (my_get_float_expression): Cast to unsigned char
+ before indexing is_end_of_line. Remove redundant check for '\0'.
+ (fp_op2): Likewise.
+ * config/tc-h8500.c (md_assemble): Likewise.
+ * config/tc-mcore.c (md_assemble): Likewise.
+ * config/tc-tic30.c (tic30_find_parallel_insn): Likewise.
+ (md_atof): Likewise
+
+ * config/tc-m88k.c (s_bss): Cast to unsigned char before indexing
+ is_end_of_line.
+ * config/tc-mcore.c (mcore_cons): Likewise.
+ (mcore_float_cons): Likewise.
+ (mcore_stringer): Likewise.
+ * config/tc-tic30.c (tic30_find_parallel_insn): Likewise.
+
+2000-06-01 Scott Bambrough <scottb@netwinder.org>
+
+ * config/tc-arm.c (do_mrs): Allow SPSR_BIT to be set correctly.
+
+2000-05-29 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-sh.c: Fix compile time warning messages.
+
+ * config/tc-mips.c: Fix compile time warning messages.
+
+2000-05-29 Philip Blundell <philb@gnu.org>
+
+ * doc/as.texinfo: Update copyright dates.
+ (Local Labels): Delete misplaced mention of ARM.
+ * NEWS: Mention ARM ELF support.
+
+2000-05-27 Alexandre Oliva <aoliva@cygnus.com>
+
+ * config/tc-mn10300.c (md_assemble): Copy size to real_size before
+ it is modified, and use the real_size to compute the frag address
+ for dwarf2 line info.
+
+2000-05-27 Alan Modra <alan@linuxcare.com.au>
+
+ * Makefile.am (DEP, DEP1, dep, dep-in, dep-am): Use a better sed
+ line-matching scheme to cope with automake moving variables around.
+ ($(TARG_CPU_O)): Remove dependency on TARG_CPU_DEP_@target_cpu_type@
+ * Makefile.in: Regenerate.
+
+2000-05-26 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-sparc.c (sparc_relax): New.
+ (md_longopts): Add -relax and -no-relax options.
+ (md_parse_options, md_show_usage): Likewise.
+ (md_apply_fix3): Optimize tail call into branch always if possible.
+
+2000-05-04 Donald Lindsay <dlindsay@cygnus.com>
+
+ * config/tc-d10v.c (write_2_short, parallel_ok, md_assemble,
+ d10v_cleanup) implement Mitsubishi's newly explained branch-packing
+ rules, with warning when a GAS statement specifies a packing that
+ will result in an instruction being squashed.
+ Added typdef packing_type and enumerals, changed various integer
+ literals to use the enumerals.
+
+2000-05-24 David Mosberger <davidm@hpl.hp.com>
+
+ * config/tc-ia64.c (dot_restorereg_p): New function.
+ (md_pseudo_table): Add restorereg.p.
+ (output_X3_format): Fix typo: record type should be UNW_X3, not UNW_X1.
+ (output_X4_format): Fix typo: record type should be UNW_X4, not UNW_X2.
+
+ * config/tc-ia64.h (unw_record_type): Add unwabi.
+ (unw_r_record): Rename member MASK to GRMASK. Add sub-structure
+ called MASK with members for imask, and the masks produced by
+ fr_mem, gr_mem, br_mem, and frgr_mem.
+ (unw_p_record): Add members ABI and CONTEXT.
+ (unw_x_record): Add member AB.
+ * config/tc-ia64.c (enum reg_symbol): Add REG_PSP and REG_PRIUNAT
+ as pseudo-register for use during unwind info generation.
+ (AR_PFS, AR_LC): New macros.
+ (enum pseudo_type): Add PSEUDO_FUNC_REG to permit declaring registers
+ whose names start with an at sign (as in "@priunat").
+ (pseudo_func): Add "svr4", "hpux", "nt" constants and "priunat"
+ register.
+ (unwind_list, unwind_tail, current_unwind_entry, proc_start,
+ proc_end, unwind_info, personality_routine): Consolidate into
+ "unwind" structure to reduce offset-table use. Add member
+ NEXT_SLOT_NUMBER to track the slot number for the next instruction
+ to be emitted.
+ (output_R1_format, output_R3_format, output_P3_format,
+ output_P6_format): Initialize R with zero to reduce compiler warnings.
+ (output_P7_format): Ditto. Add `default' branch to switch
+ statement to reduce compiler warnings.
+ (output_P8_format, output_B1_format, output_B4_format): Ditto.
+ (output_P4_format): Rename 2nd & 3rd arg to IMASK and IMASK_SIZE.
+ (format_ab_reg): Rename from format_a_b_reg. Merge A and B args
+ into single argument.
+ (output_X1_format, output_X3_format): Initialize R with zero to reduce
+ compiler warnings. Merge A and B args into single argument.
+ (output_X2_format, output_X4_format): Remove unused variable R. Merge
+ A and B args into single argument.
+ (free_record): Removed (wasn't used).
+ (free_list_records): Also free imasks in prologue records.
+ (output_prologue, output_prologue_gr): Initialize mask bits to zero.
+ (output_spill_mask): Remove.
+ (output_unwabi): New function.
+ (output_epilogue, output_label_state, output_copy_state): Call
+ alloc_record.
+ (output_spill_psprel, output_spill_sprel, output_spill_psprel_p,
+ output_spill_sprel_p, output_spill_reg, output_spill_reg_p): Add AB
+ argument.
+ (process_one_record): New locals FR_MASK and GR_MASK. Ignore
+ gr_mem, fr_mem, br_mem, and frgr_mem records and instead emit them
+ as part of handling the prologue records. Emit region's imask if
+ we have one. Handle unwabi, epilogue, label_state, copy_state,
+ spill_psprel, spill_sprel, spill_reg, spill_psprel_p,
+ spill_sprel_p, and spill_reg_p records.
+ (set_imask, count_bits, slot_index): New function.
+ (fixup_unw_records): Fix region size computation. Handle
+ epilogue, spill_reg, spill_sprel, spill_psprel, spill_reg_p,
+ spill_sprel_p, and spill_psprel_p records. Merge mask bits of
+ frgr_mem, fr_mem, gr_mem, br_mem on a per-region basis and
+ set_imask accordingly. Update imask for gr_gr, and br_gr records.
+ (convert_expr_to_ab_reg, convert_expr_to_xy_reg): New function.
+ (dot_save): Use manifest constants for applicaton registers.
+ Handle REG_PR and REG_PRIUNAT.
+ (dot_restore): Don't just ignore it.
+ (dot_restorereg): New function..
+ (generate_unwind_image): Ensure unwind info is a multiple of eight
+ bytes, not just four bytes.
+ (dot_handlerdata, dot_unwentry): Demand empty rest of line.
+ (dot_altrp): Don't just ignore it.
+ (dot_savemem): New function. Replaces dot_savesp() and
+ dot_savepsp(). Use manifest constants for applicaton registers.
+ Handle REG_PR and REG_PRIUNAT.
+ (dot_savef): Simplify.
+ (dot_saveb): Support generation of br_gr.
+ (dot_spillreg, dot_spillmem, dot_spillreg_p, dot_spillmem_p,
+ dot_label_state, dot_copy_state): New function.
+ (dot_unwabi): Don't just ignore it.
+ (md_pseudo_table): Add restorereg, spillreg, spillsp, spillpsp,
+ spillreg.p, spillsp.p, spillpsp, label_state, copy_state,
+ unwabi, vframesp, and vframepsp. Fix typo alprp->altrp.
+ (emit_one_bundle): Set slot number for prologue/body records
+ *before* emitting the first insn.
+ (emit_one_bundle): Set UNWIND.NEXT_SLOT_NUMBER.
+ (md_begin): Declare "psp" pseudo-register.
+ (md_operand): Handle PSEUDO_FUNC_REG. Fix printing of error message
+ so we don't get segfault.
+ (output_psp_sprel): Output sp/psp relative offsets as 4-byte word
+ counts as required per SW Conventions manual
+ (output_rp_psprel, output_rp_sprel, output_pfs_psprel,output_pfs_sprel,
+ output_preds_psprel, output_preds_sprel, output_spill_base,
+ output_unat_psprel, output_unat_sprel, output_lc_psprel,
+ output_lc_sprel, output_fpsr_psprel, output_fpsr_sprel,
+ output_priunat_psprel, output_priunat_sprel, output_bsp_psprel,
+ output_bsp_sprel, output_bspstore_psprel, output_bspstore_sprel,
+ output_rnat_psprel, output_rnat_sprel, output_spill_psprel,
+ output_spill_sprel, output_spill_psprel_p, output_spill_sprel_p):Ditto.
+ (dot_vframe): Implement.
+ (dot_vframesp, dot_vframepsp): New function.
+
+2000-05-23 Hans-Peter Nilsson <hp@axis.com>
+
+ * configure.in (i386-*-freebsd a.out entry): Quote properly.
+ * configure: Regenerate.
+
+2000-05-23 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-i386.c (md_assemble): Pass jump reloc in fr_var...
+ (md_estimate_size_before_relax): so we can use it here instead of
+ old kludges. Localise vars to blocks. Comment.
+
+ * frags.c (frag_new): Update fr_var comments.
+ * frags.h (struct frag): Ditto.
+
+2000-05-22 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-ia64.c (FUNC_PC_RELATIVE): New.
+ (pseudo_func): Add pcrel.
+ (operand_match): Handle IA64_OPND_TGT64.
+ (build_insn): Likewise.
+ (md_begin): Initialize pseudo_func[FUNC_PC_RELATIVE].
+ (ia64_gen_real_reloc_type): Handle FUNC_PC_RELATIVE.
+ (fix_insn): Handle all three 64-bit relocation types.
+
+2000-05-22 Hans-Peter Nilsson <hp@axis.com>
+
+ * obj.h (struct format_ops): New members begin, app_file,
+ s_set_other, s_set_desc, s_get_type, s_set_type,
+ separate_stab_sections, init_stab_section.
+
+ * config/obj-multi.h: Update GPL notice to v2.
+ (obj_begin): New.
+ (obj_app_file): New.
+ (S_SET_SIZE): Test s_set_size for NULL before calling.
+ (S_SET_ALIGN): Similar for s_set_align.
+ (S_SET_OTHER): New.
+ (S_SET_DESC): New.
+ (S_GET_TYPE): New.
+ (S_SET_TYPE): New.
+ (SEPARATE_STAB_SECTIONS): New.
+ (INIT_STAB_SECTION): New.
+ (EMIT_SECTION_SYMBOLS): New.
+ (AOUT_STABS) [OBJ_MAYBE_AOUT]: Define.
+
+ * config/obj-elf.h: Update GPL notice to v2.
+ Mention that this file is included from obj-multi.h.
+ (obj_begin): Wrap definition in ifndef.
+ (elf_file_symbol): Constify declaration.
+ (obj_app_file): Ditto.
+ (SEPARATE_STAB_SECTIONS, INIT_STAB_SECTION, OBJ_PROCESS_STAB):
+ Wrap in ifndef SEPARATE_STAB_SECTIONS.
+
+ * config/obj-elf.c (elf_s_set_other): New.
+ (elf_file_symbol): Constify argument.
+ (elf_separate_stab_sections): New.
+ (elf_init_stab_section): New.
+ (elf_format_ops): Add new members. Remove comma at end.
+
+ * config/obj-ecoff.c (ecoff_separate_stab_sections): New.
+ (ecoff_format_ops): Add new fields. Remove comma at end.
+ Mention inconsistency for emit_section_symbols.
+
+ * config/obj-coff.h (c_dot_file_symbol): Constify declaration.
+
+ * config/obj-coff.c (c_dot_file_symbol): Constify argument.
+ (coff_separate_stab_sections): New.
+ (coff_format_ops): Add new members.
+
+ * config/obj-aout.c (obj_aout_sec_sym_ok_for_reloc): New.
+ (obj_aout_s_set_other): New.
+ (obj_aout_s_set_desc): New.
+ (obj_aout_s_get_type): New.
+ (obj_aout_s_set_type): New.
+ (obj_aout_separate_stab_sections): New.
+ (aout_format_ops): New members added. Use obj_aout_process_stab,
+ not 0. Use obj_aout_sec_sym_ok_for_reloc, not 0.
+ (obj_aout_frob_symbol): Add ATTRIBUTE_UNUSED to args as
+ appropriate.
+ (obj_aout_line, obj_aout_weak, obj_aout_type): Ditto.
+
+2000-05-22 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Prevent adjustment
+ for OBJ_MAYBE_ELF too. Use S_IS_EXTERNAL instead of S_IS_EXTERN.
+ (md_estimate_size_before_relax): Ensure jumps to weak and
+ externally visible symbols are relocatable.
+
+2000-05-20 Hans-Peter Nilsson <hp@axis.com>
+
+ * stabs.c (aout_process_stab): Make global.
+ (s_desc): Add ATTRIBUTE_UNUSED to args as appropriate.
+ * read.h (aout_process_stab): Declare.
+
+ * configure.in (EMULATIONS) [i386aout, i386coff, i386elf]:
+ Generalize to *aout, *coff *elf.
+ * configure: Regenerated.
+
+ * doc/internals.texi (Object format backend): Say
+ SEPARATE_STAB_SECTIONS needs to be nonzero, not just defined.
+
+ * Makefile.am (TARG_ENV_HFILES): Delete te-multi.h.
+ * Makefile.in: Regenerated.
+
+2000-05-19 Catherine Moore <clm@cygnus.com>
+
+ * cgen.h (GAS_CGEN_MAX_FIXUPS): Check if already defined.
+
+2000-05-18 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.c (md_apply_fix): Mask out immediate bits of
+ instruction to reflect change in re_assemble_*.
+
+2000-05-18 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in (hppa-*-hpux11*): If the cpu is hppa*64*, then
+ build PA64 ELF tools.
+ * configure: Rebuilt.
+
+2000-05-17 Alan Modra <alan@linuxcare.com.au>
+
+ * Makefile.am: Regenerate dependencies.
+ * Makefile.in: Regenerate.
+
+2000-05-15 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (struct asm_psr): Add boolean field
+ distinguishing between CSPR and SPSR. Rename 'number' field
+ to 'field'.
+ (psrs): Rearrange contents to match new asm_psr structure.
+ (arm_psr_parse): Move next to psr_required_here. Make it
+ return an asm_psr structure.
+ (psr_required_here): Use asm_psr structure returned by
+ arm_psr_parse.
+ (do_msr): Reorganise to allow psr_required_here to be called
+ only once.
+ (md_undefined_name): Mark 'name' parameter as unused, since
+ the COFF target does not use it.
+
+2000-05-14 David O'Brien <obrien@FreeBSD.org>
+
+ * config/te-386bsd.h: Clean up comments to adhere to the GNU coding
+ standards.
+ * config/te-aux.h: Likewise.
+ * config/te-dpx2.h: Likewise.
+ * config/te-go32.h: Likewise.
+ * config/te-hp300.h: Likewise.
+ * config/te-hppa.h: Likewise.
+ * config/te-i386aix.h: Likewise.
+ * config/te-ic960.h: Likewise.
+ * config/te-interix.h: Likewise.
+ * config/te-nbsd532.h: Likewise.
+ * config/te-pc532mach.h: Likewise.
+ * config/te-ppcnw.h: Likewise.
+ * config/te-psos.h: Likewise.
+ * config/te-sparcaout.h: Likewise.
+ * config/te-sun3.h: Likewise.
+ * config/te-sysv32.h: Likewise.
+
+2000-05-14 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-h8300.c (do_a_fix_imm): Don't rely on `short' being 16
+ bits. Instead explicitly mask and sign extend. Do the 8 bit mask
+ and sign extend without an if statement.
+ (build_bytes): Likewise.
+
+2000-05-14 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-h8300.c (do_a_fix_imm): Output a reloc for no
+ X_add_symbol L_32 case.
+
+2000-05-14 David O'Brien <obrien@FreeBSD.org>
+
+ * config/te-freebsd.h: New file.
+
+2000-05-13 Alan Modra <alan@linuxcare.com.au>
+
+ * asintl.h (gettext, dgettext, dcgettext, textdomain,
+ bindtextdomain): Replace defines with those from intl/libgettext.h
+ to quieten gcc warnings.
+
+ * NEWS: Mention x86 .arch and -q.
+
+ * config/tc-i386.c (quiet_warnings): New.
+ (md_assemble): Use quiet_warnings.
+ (md_parse_option): Set quiet_warnings from -q.
+ (md_show_usage): Mention -q, delete -m.
+ (flag_do_long_jump): Delete.
+ (md_parse_option): Remove -m.
+ (md_show_usage): Remove -m.
+ (md_create_long_jump): Remove useless flag_do_long_jump code.
+
+ * as.c (parse_args): In case OPTION_DEFSYM, use a valueT to hold
+ the symbol value, and use bfd_scan_vma if BFD_ASSEMBLER.
+
+2000-05-13 Alan Modra <alan@linuxcare.com.au>
+ Alexander Sokolov <robocop@netlink.ru>
+
+ * doc/c-i386.texi (i386-Arch): New section.
+ (i386-Syntax): Mention .intel_syntax and .att_syntax.
+
+ * config/tc-i386.c (cpu_arch_name, cpu_arch_flags): New.
+ (smallest_imm_type): Use smallest opcode for shift by one if cpu
+ architecture has been given and is not 486.
+ (set_cpu_arch): New.
+ (md_pseudo_table): Add .arch.
+ (md_assemble): Warn if cpu architecture has been given and an
+ unsupported instruction.
+
+ * config/tc-i386.h (SMALLEST_DISP_TYPE): Delete.
+ Move operand_types bit defines after relevant template field.
+ (template): Add cpu_flags.
+ (Cpu*): Define.
+ (arch_entry): New.
+
+2000-05-12 Alexandre Oliva <aoliva@cygnus.com>
+
+ * config/tc-mn10300.h (md_end): Define.
+ (mn10300_finalize): Declare.
+ * config/tc-mn10300.c: Include dwarf2dbg.h.
+ (debug_line): Define.
+ (md_assemble): Generate dwarf2 line info.
+ (mn10300_finalize): New function. Finalize dwarf2 info.
+
+2000-05-11 Ulf Carlsson <ulfc@engr.sgi.com>
+
+ * config/tc-mips.c (md_estimate_size_before_relax): Use the
+ external version of the relocation for weak symbols.
+
+2000-05-08 David Mosberger <davidm@hpl.hp.com>
+
+ * config/tc-ia64.c (output_P7_format, case mem_stack_f): Output fixed
+ frame size in units of 16 bytes, as required per SW Conventions manual.
+ (output_unw_records): Output info-block header as a dword to get
+ byte-order right.
+
+2000-05-08 Alan Modra <alan@linuxcare.com.au>
+
+ * as.h: #include "file", not <file> on files from ../include.
+ (as_abort, as_fatal): Add ATTRIBUTE_NORETURN.
+ * config/tc-m68k.c (m68k_ip): Fix signed/unsigned warnings.
+ (md_convert_frag): Add ATTRIBUTE_UNUSED.
+ (tc_coff_symbol_emit_hook): Ditto.
+ (OPTCOUNT): Cast to int to avoid compiler warning.
+ (md_begin): Fix signed/unsigned warnings.
+
+2000-05-08 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * config/tc-m68k.c (md_convert_frag_1): Abort if we end up in the
+ ABRANCH LONG case for a conditional branch on a 68000.
+ (md_estimate_size_before_relax): Likewise. Also handle
+ flag_short_refs correctly for ABRANCH, BCC68000, and DBCC.
+ (m68k-ip: case ABSL): Relax absolute references to 16-bit
+ PC-relative on all CPUs.
+ (md_estimate_size_before_relax): Likewise.
+
+2000-05-04 Alan Modra <alan@linuxcare.com.au>
+
+ * as.c (parse_args): Just mention current year in printed
+ copyright message.
+
+2000-05-03 J.T. Conklin <jtc@redback.com>
+
+ * config/tc-ppc.c (pre_defined_registers): Add entries for vector
+ unit registers.
+ (md_parse_option): Recognize -m7400.
+
+2000-05-03 Ian Lance Taylor <ian@zembu.com>
+
+ * config/atof-ieee.c (gen_to_words): When adding carry back in,
+ don't permit lp to become less than the words array.
+
+2000-05-03 Rodney Brown <RodneyBrown@pmsc.com>
+
+ config/tc-mcore.c (md_apply_fix3): BFD_RELOC_MCORE_PCREL_IMM11BY2
+ Fix little-endian case.
+
+2000-05-03 David O'Brien <obrien@NUXI.com>
+
+ * as.c (parse_args): Update copyright.
+
+2000-05-03 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * config/tc-i386.h (SUB_SEGMENT_ALIGN): If TE_GO32, return 4
+ for the .bss section too.
+
+2000-05-02 Alan Modra <alan@linuxcare.com.au>
+
+ * configure.in: Set em=linux for hppa-*-linux.
+ * configure: Regenerate.
+ * doc/Makefile.in: Regenerate with correct automake.
+
+ * frags.c (frag_grow): Sanity check chunk_size.
+
+ * config/obj-elf.h: #include "bfd.h" not <bfd.h>
+ * config/obj-som.h: Likewise.
+ * config/obj-ieee.h: Likewise.
+
+ * config/tc-hppa.h: Test BFD_ARCH_SIZE, not BFD64.
+
+ * config/tc-hppa.c (log2): Only compile when OBJ_SOM.
+ (md_pseudo_table): Fully initialise OBJ_ELF cases.
+ (fix_new_hppa): Add ATTRIBUTE_UNUSED to args as appropriate.
+ (pa_ip): low_sign_unext now returns via function value. Use
+ re_assemble_* instead of dis_assemble_* and
+ INSERT_FIELD_AND_CONTINUE combination. Don't call sign_unext
+ unnecessarily.
+ (md_convert_frag): Add ATTRIBUTE_UNUSED to args as appropriate.
+ (md_section_align, md_parse_option, md_show_usage,
+ md_undefined_symbol, pa_align, pa_block, pa_brtab, pa_try,
+ pa_callinfo, pa_code, pa_comm, pa_end, pa_enter, pa_entry,
+ pa_exit, pa_export, pa_import, pa_label, pa_leave, pa_level,
+ pa_origin, pa_param, pa_proc, pa_procend, pa_space, pa_spnum,
+ pa_version, pa_compiler, pa_copyright, pa_data, pa_fill, pa_lsym,
+ pa_text): Likewise.
+ (md_apply_fix): Change type of new_val to offsetT. Delete w1, w2,
+ w, resulti. Add insn, val. Move bfd_get_32 and bfd_put_32
+ outside of switch. Correct mask and shifting errors in case 10
+ and case -11. In case 21, compare against signed range to suit
+ hppa_field_adjust changes. In case 12, use re_assemble_12. In
+ case 17 and case 22, use offsetT variable to properly check range.
+ Use re_assemble_* here too.
+ (evaluate_absolute): Change type of value to offsetT. Call
+ hppa_field_adjust to do the work for us.
+ (pa_parse_cmpb_64_cmpltr): Delete save_s.
+ (pa_parse_cmpib_64_cmpltr): Ditto.
+ (pa_build_unwind_subspace): Delete unused var subseg. Change type
+ of i to unsigned int.
+ (pa_type_args): Conditionally declare symbol if OBJ_SOM.
+ (pa_end_of_source): Return type is void.
+
+2000-05-01 Catherine Moore <clm@cygnus.com>
+
+ * macro.c (macro_expand_body): Don't prepend macro number with zeroes.
+
+2000-05-01 Denis Chertykov <denisc@overta.ru>
+
+ * config/tc-avr.c: ATTRIBUTE_UNUSED added to the necessary places.
+ More comments added.
+ (md_begin): Removed "construct symbols for each register name".
+ Because register names conflicts with GCC generated function
+ names.
+ (avr_operand): Now constant numbers can be used as a register
+ identifiers (0 as r0, 31 as r31).
+ (md_assemble): use skip_space () before parsing instruction
+ operands.
+
+2000-05-01 Alan Modra <alan@linuxcare.com.au>
+
+ * configure.in: Set bfd_gas=yes on i386-*-pe and i386-*-nt* to
+ ensure all pe targets use bfd. Remove unnecessary bfd_gas=yes on
+ arm-*-netbsd* and arm-*-wince as this is set for all arm*.
+ * configure: Regenerate.
+
+2000-04-29 Andreas Jaeger <aj@suse.de>
+
+ * as.h: Correctly check GCC version.
+
+2000-04-26 David O'Brien <obrien@FreeBSD.org>
+
+ * doc/as.1: Fix unbalanced brackets.
+
+ * config/tc-i386.c (comment_chars): Don't use '/' as comment start if
+ TE_FreeBSD.
+ (line_comment_chars): Set to '/' if TE_FreeBSD.
+
+2000-04-25 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in: Configury support for PA64 (currently disabled).
+ * configure: Rebuilt.
+
+2000-04-25 Machida Hiroyuki <machida@sm.sony.co.jp>
+
+ * config/tc-mips.c (s_change_sec): Use record_alignment, not
+ bfd_set_section_alignment.
+
+2000-04-25 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-i386.c (offset_in_range): Ensure shift counts are less
+ than 32.
+
+2000-04-24 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-arm.texi (ARM Directives): Document behaviour of .align 0.
+ * doc/as.texinfo (Align): Include arm and strongarm in list of
+ targets that have the second form of the behaviour of the .align
+ directive.
+
+2000-04-24 Mark Klein <mklein@dis.com>
+
+ * config/obj-som.c: Terminate obj_pseudo_table.
+
+2000-04-24 Clinton Popetz <cpopetz@cygnus.com>
+
+ * as.c (parse_args): Allow md_parse_option to override -a listing
+ option.
+ * config/obj-coff.c (add_lineno): Change type of offset parameter
+ from "int" to "bfd_vma."
+ * config/tc-ppc.c (md_pseudo_table): Add "llong" and "machine."
+ (ppc_mach, ppc_subseg_align, ppc_target_format): New.
+ (ppc_change_csect): Align correctly for XCOFF64.
+ (ppc_machine): New function, which discards "ppc_machine" line.
+ (ppc_tc): Cons for 8 when code is 64 bit.
+ (md_apply_fix3): Don't check operand->insert. Handle 64 bit
+ relocations.
+ (md_parse_option): Handle -a64 and -a32.
+ (ppc_xcoff64): New.
+ * config/tc-ppc.h (TARGET_MACH): Define.
+ (TARGET_FORMAT): Move to function.
+ (SUB_SEGMENT_ALIGN): Use ppc_subseg_align.
+
+2000-04-23 Denis Chertykov <denisc@overta.ru>
+
+ * config/tc-avr.c: New AVR_ISA_ defined.
+ (md_assemble): Handle opcodes with optional operands (lpm,elpm).
+ (avr_operand): Handle 'a', 'v' and 'z' constraint letters needed
+ for `fmul', `movw' and `lpm R,Z' instructions.
+ (avr_operands): Warn if current opcode is a two-word instruction
+ and previous opcode was cpse/sbic/sbis/sbrc/sbrs.
+ (avr_opcodes): New commands added.
+ (REGISTER_P): Check 'a' and 'v' constraint letters.
+ (mcu_types): New MCU added.
+
+2000-04-22 Timothy Wall <twall@cygnus.com>
+
+ * config/tc-ia64.c (pseudo_func[]): Add new "nat" entry equivalent
+ to "natval".
+ (operand_match): Conditionally insert default bit values for IMMU9.
+
+2000-04-14 Matthew Green <mrg@cygnus.com>
+
+ * configure.in: Add NetBSD/sparc ELF and NetBSD/sparc64 support.
+ * configure: Rebuilt.
+
+2000-04-21 Jeffrey A Law (law@cygnus.com)
+ Jason Eckhardt <jle@cygnus.com>
+
+ * config/tc-hppa.c (md_apply_fix): Handle new PA2.0 formats.
+
+ * config/tc-hppa.c (CHECK_ALIGN): New macro.
+ Added handling of new operand types l,y,&,fe,fE,fx.
+
+2000-04-21 Richard Henderson <rth@cygnus.com>
+ David Mosberger <davidm@hpl.hp.com>
+ Timothy Wall <twall@cygnus.com>
+ Andrew MacLeod <amacleod@cygnus.com>
+ Jim Wilson <wilson@cygnus.com>
+
+ * Makefile.am (CPU_TYPES): Add ia64.
+ (TARGET_CPU_CFILES): Add config/tc-ia64.c.
+ (TARGET_CPU_HFILES): Add config/tc-ia64.h.
+ * Makefile.in: Rebuild.
+ * app.c (do_scrub_chars): Handle DOUBLESLASH_COMMENTS.
+ * configure: Rebuild.
+ * configure.in: Recognize ia64 as cpu type. Set bfd_gas.
+ (ia64-*-elf*, ia64-*-linux-gnu*): New targets.
+ * expr.c (expr): Handle md_optimize_expr.
+ * read.c (LEX_HASH): Add comment.
+ * config/tc-ia64.c, config/tc-ia64.h: New files.
+
+2000-04-21 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-d30v.c (write_2_short): Disregard opcode1->ecc when
+ bundling a non-delayed branch type instruction.
+
+2000-04-20 Alexandre Oliva <aoliva@cygnus.com>
+
+ * config/tc-mn10300.c (HAVE_AM30): Define.
+ (md_assemble): Use it.
+
+2000-04-19 Alan Modra <alan@linuxcare.com.au>
+
+ * config/obj-elf.c (obj_elf_change_section): Check for changed
+ section attributes.
+
+ * Makefile.am: (CPU_MULTI_VALID): Remove.
+ (MULTI_CPU_TYPES): Define.
+ (MULTI_CPU_OBJ_VALID): Define.
+ (DEPTC): Use the above.
+ (DEPOBJ): Same here.
+ (DEP2): And here.
+ Regenerate dependencies.
+ * Makefile.in: Regenerate.
+
+2000-04-19 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * Makefile.am (YACC, LEX): Get them from configure.
+
+2000-04-18 H.J. Lu (hjl@gnu.org)
+
+ * config/tc-i386.c (offset_in_range): Use addressT instead of
+ bfd_vma for non-bfd assemblers.
+
+2000-04-17 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-i386.c (offset_in_range): Sign extend val so BFD64
+ doesn't give spurious errors.
+
+2000-04-14 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * as.h (SEEK_SET): Define if undefined.
+
+2000-04-13 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-arm.c (md_apply_fix3): Don't use UL suffix on
+ constants, and don't assume offsetT is 32 bits.
+
+2000-04-12 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/tc-d10v.h: Include "write.h" to get definition of fixS.
+ (md_pcrel_from_section): Add prototype.
+ (d10v_fix_adjustable): Add prototype.
+ (d10v_force_relocation): Replace 'struct fix' with 'fixS'.
+
+ * config/tc-d10v.c (md_apply_fix3): Add paren around &&.
+
+2000-04-12 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d10v.c (find_opcode): Correctly calculate position of
+ symbol in frag chain.
+
+2000-04-10 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-i386.c (fits_in_signed_byte): Change arg to offsetT.
+ (fits_in_unsigned_byte, fits_in_unsigned_word): Ditto.
+ (fits_in_signed_word, smallest_imm_type): Ditto.
+ (md_assemble): Use an offsetT var to hold offsetT values, not a
+ long.
+ (offset_in_range): New.
+ (md_assemble): Use it.
+ (md_convert_frag): Change type of target_address, opcode_address,
+ and displacement_from_opcode_start to offsetT.
+ (md_create_short_jump): Change type of offset to offsetT.
+ (md_create_long_jump): Ditto.
+ (md_apply_fix3): Use -4, not 0xfffffffc for BFD_RELOC_386_PLT32.
+ (md_chars_to_number): Remove.
+ (output_invalid): Remove duplicate prototype.
+
+2000-04-09 Nick Clifton <nickc@cygnus.com>
+
+ * Makefile.am (CPU_TYPES): Add 'avr'.
+ (TARGET_CPU_CFILES): Add 'tc-avr.c'.
+ (TARGET_CPU_HFILES): Add 'tc-avr.h'.
+
+ * Makefile.in: Regenerate.
+
+ * doc/as.texinfo: Add M32R documentation.
+
+2000-04-07 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (WARN_CFLAGS): Set to -W -Wall by default. Add
+ --enable-build-warnings option.
+ * Makefile.am (AM_CFLAGS, WARN_CFLAGS): Add definitions.
+ * Makefile.in, configure: Re-generate.
+
+2000-04-07 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_apply_fix3): Treat BFD_RELOC_ARM_PCREL_BLX
+ in the same way as BFD_RELOC_ARM_PCREL_BRANCH, and
+ BFD_RELOC_THUMB_PCREL_BLX lie BFD_RELOC_THUMB_PCREL_BRANCH.
+ (tc_gen_reloc): Accept BFD_RELOC_{ARM|THUMB}_PCREL_BLX.
+ (arm_force_relocation): Force relocations for
+ BFD_RELOC_{ARM|THUMB}_PCREL_BLX as well.
+
+2000-04-05 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-sh.c (get_operands): There's no third operand if the
+ first operand is an immediate.
+
+2000-04-05 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-sh.c (immediate): Delete.
+ (sh_operand_info): Add immediate member.
+ (parse_reg): Use A_PC for pc.
+ (parse_exp): Add second argument 'op'. All callers changed.
+ (parse_at): Expect pc to be coded as A_PC.
+ Use immediate field in *op.
+ (insert): Add fourth argument 'op'. All callers changed.
+ (build_relax): Add second argument 'op'. All callers changed.
+ (insert_loop_bounds): New function.
+ (build_Mytes): Remove DISP_4.
+ Split IMM_[48]{,BY[24]} into IMM[01]_[48]{,BY[24]}. Add REPEAT.
+ (assemble_ppi): Use immediate field in *operand.
+ (sh_force_relocation): Handle BFD_RELOC_SH_LOOP_{START,END}.
+ (md_apply_fix): Likewise.
+ (tc_gen_reloc): Likewise. Check for a pcrel BFD_RELOC_SH_LABEL.
+
+2000-04-05 Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+
+ * config/tc-sparc.c (sparc_ip): Avoid string pasting.
+
+2000-04-04 Hans-Peter Nilsson <hp@axis.com>
+
+ * internals.texi (CPU backend): Document
+ TC_CHECK_ADJUSTED_BROKEN_DOT_WORD.
+
+2000-04-04 Alan Modra <alan@linuxcare.com.au>
+
+ * po/gas.pot: Regenerate.
+
+ * as.c (show_usage): Restore translated part of bug string.
+ * gasp.c (show_usage): Likewise.
+
+ * Makefile.am (MKDEP): Use gcc -MM rather than ../mkdep.
+ (DEP): Quote when passing vars to sub-make. Use "mv -f" rather
+ than move-if-change.
+ (DEP1): Modify for "gcc -MM".
+ (DEPTC): Likewise.
+ (DEPOBJ): Likewise.
+ (DEP2): Likewise.
+ (CLEANFILES): Add DEPTCA, DEPOBJA, DEP2a, DEPA.
+ Update dependencies.
+ * Makefile.in: Regenerate.
+
+2000-04-03 Alexandre Oliva <aoliva@cygnus.com>
+
+ * config/tc-mn10300.c (md_pseudo_table): Use constant names.
+ (md_begin): Likewise.
+ (HAVE_AM33): New macro.
+ (md_assemble): Use it. Match r_regs and xr_regs only if
+ HAVE_AM33.
+
+2000-04-03 Alan Modra <alan@linuxcare.com.au>
+
+ * as.h: #include "bin-bugs.h"
+ * as.c (show_usage): Use REPORT_BUGS_TO.
+ * gasp.c: #include "bin-bugs.h"
+ (show_usage): Use REPORT_BUGS_TO.
+
+ * config/tc-sparc.c (md_show_usage): Add a trailing newline.
+
+2000-04-03 Hans-Peter Nilsson <hp@axis.com>
+
+ * write.c (write_object_file) [! WORKING_DOT_WORD]: If defined,
+ call TC_CHECK_ADJUSTED_BROKEN_DOT_WORD for each word after
+ adjustments.
+
+2000-04-03 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-i386.c (i386_immediate): Don't assume a constant
+ immediate is necessarily 16 bits when in 16 bit code mode.
+ (md_assemble): Instead set guess_suffix here after we have checked
+ registers.
+
+2000-04-02 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-d30v.c (check_range): Allow signed or unsigned 32-bit
+ quantities. Correct right shift sign extension.
+ (build_insn): Make `number' unsigned long. Mask top 6 bits of
+ 32-bit value when shifting into place.
+
+2000-04-01 Ian Lance Taylor <ian@zembu.com>
+
+ * app.c: Add ATTRIBUTE_UNUSED as needed.
+ * config/tc-ppc.c: Likewise.
+ (ppc_size): Make unsigned long.
+ (ppc_insert_operand): Add casts to avoid warnings.
+
+2000-03-31 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d10v.h (md_flush_pending_output): Define.
+
+2000-03-29 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-sh.h (SEG_NAME): New macro: return the name of a
+ segment. Works for both BFD_ASSEMBLER and others.
+ (SUB_SEGMENT_ALIGN): Use SEG_NAME.
+
+2000-03-29 Nick Clifton <nickc@cygnus.com
+
+ * config/tc-arm.c (tinsns): Add "bal" instruction pattern.
+
+2000-03-28 Alan Modra <alan@linuxcare.com.au>
+
+ * listing.c (LISTING_LHS_WIDTH): Default depends on
+ LISTING_WORD_SIZE.
+ (LISTING_LHS_WIDTH_SECOND): Default to LISTING_LHS_WIDTH.
+
+2000-03-27 Ian Lance Taylor <ian@zembu.com>
+
+ * config/tc-sh.c (md_show_usage): Use backslash before newline in
+ string literal.
+
+2000-03-27 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-avr.h (TC_HANDLES_FX_DONE): Define.
+
+ * config/tc-avr.c (mcu_types): Add missing initialiser.
+ (md_pcrel_from_section): Add prototype.
+ (avr_operand): Remove redundant test of unsigned < 0.
+ (avr_cons_fix_new): Ensure exp_mod_pm zero on function exit.
+
+2000-03-27 Denis Chertykov <denisc@overta.ru>
+
+ * config/tc-avr.c: New file for AVR support.
+ * config/tc-avr.h: Likewise.
+ * configure.in: Add AVR support.
+ * configure: Regenerate.
+
+2000-03-26 Timothy Wall <twall@cygnus.com>
+
+ * gasp.c (macro_op): Add new argument to check_macro call.
+ Macro structure definitions moved to macro.h
+ * sb.h: Add argument to prototype for input_scrub_include_sb.
+ * input-scrub.c (input_scrub_include_sb): Allow disabling of sb
+ nesting checks with an additional flag.
+ (struct input_save): Add flag to indicate whether current sb
+ should be checked for proper macro/conditional nesting.
+ (input_scrub_push/pop): Save/restore nest check flag.
+ (input_scrub_next_buffer): Ditto. Also call end of macro hook if
+ defined.
+ * macro.c (check_macro): Allow caller to retrieve parsed macro
+ information if a pointer is provided. This information may be
+ used by the new macro hooks.
+ * macro.h: Update prototype for check_macro. Macro struct
+ definitions moved here from macro.c/gasp.c.
+ * read.c (read_a_source_file): Add parameter to check_macro call,
+ and pass macro info to the macro hook, if defined.
+ (input_scrub_insert_line): New. Allow insertion of a line of
+ characters into the input stream.
+ (input_scrub_insert_file): New. Allow insertion of an arbitrary
+ file into the input stream.
+ (s_include): Use input_scrub_insert_file.
+ * internals.texi: Document new macro hooks.
+ * as.h: New prototypes added.
+
+2000-03-26 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-i386.c: Don't start any as_bad or as_warn message with
+ an initial capital letter.
+ (i386_index_check): Reindent.
+
+2000-03-19 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_apply_fix3): Fix bug detecting overflow of pc
+ relative branches.
+
+2000-03-17 Thomas de Lellis <tdel@windriver.com>
+
+ * config/tc-arm.c (do_t_adr): Flag "adr Rd,label"
+ instruction operand bad if Rd > 7 when generating
+ thumb instructions. Prevents for example,
+ "adr r12,label" from silently failing and generating
+ the wrong instruction.
+
+2000-03-17 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_apply_fix3): Handle same-section relocations
+ that have a destingation >= 0x400000.
+ Fix compile time warning messages.
+
+2000-03-16 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-sh.c (md_begin): When encountering insn that are
+ not supported by the current arch, only change the name if
+ its contents are the same as prev_name.
+ (get_specific): If the the architecture doesn't match, fail.
+
+2000-03-16 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-sh.c (IDENT_CHAR): Define.
+ (parse_reg): Use it instead of isalnum. Put r[0..7]_bank operand
+ matching back where it came from.
+
+2000-03-16 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-sh.c (md_show_usage): Add description of -dsp.
+
+2000-03-15 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * config/tc-sh.c (parse_reg): Match r[0..7]_bank operands before
+ normal operands.
+
+2000-03-15 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-h8300.c: Add ATTRIBUTE_UNUSED as appropriate.
+
+2000-03-13 Hans-Peter Nilsson <hp@axis.se>
+
+ * expr.c (operand) [case 'f']: When testing if '0f' can start a
+ floating-point-number, make sure 'f' is in FLT_CHARS.
+
+2000-03-11 Hans-Peter Nilsson <hp@axis.se>
+
+ * read.c (TC_IMPLICIT_LCOMM_ALIGNMENT): New default-definition.
+ (s_lcomm_internal): Use it.
+ * doc/internals.texi (CPU backend): Document it.
+ * config/obj-evax.h (TC_IMPLICIT_LCOMM_ALIGNMENT): Set to 2**3
+ bytes.
+
+2000-03-10 Geoffrey Keating <geoffk@cygnus.com>
+
+ * config/tc-mips.c (mips_ip): Don't put stuff in .rodata
+ when embedded-pic.
+
+ * config/tc-mips.c (SWITCH_TABLE): The ELF embedded-pic
+ implementation doesn't have special handling for switch
+ statements.
+ (macro_build): Allow for code in sections other than .text.
+ (macro): Likewise.
+ (mips_ip): Likewise.
+ (md_apply_fix): Do pc-relative relocation madness for MIPS ELF.
+ Don't perform relocs if we will be outputting them.
+ (tc_gen_reloc): For ELF, just use fx_addnumber for pc-relative
+ relocations. Allow BFD_RELOC_16_PCREL_S2 relocs when
+ embedded-pic.
+
+2000-03-09 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-m32r.c (m32r_fix_adjustable): Look up the
+ relocation type based on the entry in the fixup structure.
+ Put S_IS_EXTERN processing back in.
+
+2000-03-08 H.J. Lu (hjl@gnu.org)
+
+ * Makefile.am (install-exec-tooldir): Depend on
+ install-exec-bindir for parallel make.
+ * Makefile.in: Regenerated.
+
+2000-03-06 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c (struct md_longopts): Add -m32r command line
+ switch.
+ (md_parse_option): Parse -m32r command line switch - disable m32rx
+ compatability.
+ (md_show_usage): Document new option.
+
+ * doc/Makefile.am (CPU_DOCS): Add c-m32r.texi.
+ * doc/Makefile.in: Regenerate.
+ * doc/c-m32r.texi (M32R-Opts): Document new command line switch.
+
+2000-03-02 Michael Meissner <meissner@redhat.com>
+
+ * config/tc-d30v.c (check_range): Remove code that incorrectly
+ sign extended values where bits < 32.
+
+2000-03-02 H.J. Lu (hjl@gnu.org)
+
+ * configure.in: Support --enable-targets=all on ia32.
+ * configure: Regenerated.
+
+2000-03-01 Nick Clifton <nickc@cygnus.com>
+
+ * gasp.c (do_align): Remove bogus check of alignment value.
+
+2000-02-27 Thomas de Lellis <tdel@windriver.com>
+
+ * config/obj-elf.c (elf_frob_symbol): Remove code which when
+ TC_PPC was defined forced the type of a symbol with no other type
+ to be BSF_OBJECT.
+
+2000-02-27 Hans-Peter Nilsson <hp@axis.com>
+
+ * doc/internals.texi (CPU backend): Mention that
+ line_separator_chars do not break up comments. Fix typos for
+ LEX_AT and LEX_NAME descriptions. Document operands for
+ TC_EQUAL_IN_INSN, md_operand and md_section_align. Correct
+ description of md_create_short_jump usage. Document argument for
+ md_undefined_symbol.
+
+2000-02-27 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-sparc.c (OPTION_UNDECLARED_REGS): New option.
+ (md_parse_option): Handle it.
+ (md_show_usage): Document it.
+
+2000-02-27 Ian Lance Taylor <ian@zembu.com>
+
+ * config/tc-alpha.c (md_assemble): Accept `1' and `9' in an
+ opcode, for the instruction `pal19'. From Andrea Arcangeli
+ <andrea@suse.de>.
+
+2000-02-26 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (i386_immediate): Move constant operand sizing
+ from here..
+ (md_assemble): To here, before template operands are matched.
+ Also ensure a constant immediate is sign extended when we know the
+ size is at most 16 bits. This is to catch cases like "add
+ $0xffc0,%ax" where we don't know the size, and thus that the
+ immediate can be represented as Imm8S until after parsing the
+ register operand.
+ (i386_displacement): Similarly sign extend 16 bit constant
+ displacements.
+ (md_assemble): Relax 16-bit jump constant range check to suit sign
+ extended displacements.
+
+2000-02-26 Andreas Jaeger <aj@suse.de>
+
+ * doc/c-mips.texi (MIPS Opts): Fix typo in last patch.
+
+2000-02-25 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (md_assemble): Don't swap intersegment jmp and
+ call operands when intel_syntax.
+ (intel_float_operand): Return 2 for "fi...".
+ (i386_operand_modifier): Change "DWORD PTR" test to suit above.
+ Return SHORT_MNEM_SUFFIX for "WORD PTR" when "fi...". Revert
+ earlier "SHORT" change.
+ (md_assemble): When determining suffix from Regs, exclude
+ InOutPortReg.
+
+2000-02-24 Nick Clifton <nickc@cygnus.com>
+
+ * configure: Add arm-wince, mips-pe and sh-pe targets.
+ * configure: Regenerate.
+
+ * config/obj-coff.h (COFF_WITH_PE): Define for mips-pe and
+ sh-pe targets.
+ (TARGET_FORMAT): Set to "pe-shl" for the sh-pe target and to
+ "pe-mips" for the mips-pe target.
+
+ * config/tc-arm.c (insns): Change displacement encoded in BL
+ and B instructions if the target port is arm-wince.
+ (do_ldst): Do not bias the relocation offset if the target
+ port is arm-wince.
+ (md_pcrel_from): Add in missing relocation offset bias if the
+ target os arm-wince.
+
+ * config/tc-mips.c (mips_target_format): Support COFF flavour.
+ (md_begin): Disable -G support for mips-pe target.
+ (md_apply_fix): Treat BFD_RELOC_RVA reloc as BFD_RELOC_32.
+ * config/tc-mips.h (USE_GLOBAL_POINTER_OPT): Add support for
+ COFF flavour.
+
+ * config/tc-sh.c (md_begin): sh-pe target is little endian.
+ * config/tc-sh.h (SUB_SEGMENT_ALIGN): If using a BFD
+ assembler, just set the alignment to 4.
+
+ * config/te-wince-pe.h: New file for WinCE targets. Define
+ TE_WINCE.
+
+2000-02-25 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (md_assemble): Swap segments too for intel mode
+ string instructions.
+ (i386_operand_modifier): Set i.suffix = WORD_MNEM_SUFFIX for SHORT.
+ (i386_intel_memory_operand): After finding a segment override,
+ check again for no `[' before looking for a displacement. Bomb if
+ more than one displacement rather than silently discarding the
+ second and subsequent ones. Free strings malloc'd by
+ build_displacement_string.
+
+2000-02-24 Catherine Moore <clm@cygnus.com>
+
+ * config/obj-som.c (obj_pseudo_table): Add "weak".
+ (obj_som_weak): New routine.
+
+2000-02-24 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (union i386_op): New.
+ (struct _i386_insn): Delete disps[], imms[], regs[]. Add op[].
+ Throughout file replace occurences of disps[n], imms[n], regs[n]
+ with equivalent op[n].disps, op[n].imms, op[n].regs. Simplify
+ intel mode operand swapping. Add assert in regKludge and
+ fake_zero_displacement code. Test i.types[n] when outputting
+ displacements and immediates. Combine output of Disp16 with
+ Disp32.
+ (md_assemble): Don't try to fix broken UNIXWARE_COMPAT opcodes
+ when in intel mode by (not) reversing fsub and fdiv operands
+ before the template search. This fails for single operand
+ shorthand forms of the instruction, and if UNIXWARE_COMPAT is
+ undefined. Instead fix the base_opcode after we've found the
+ template. Move base_opcode xor with found_reverse_match from
+ opcode output code to before this fix so we test for the correct
+ opcodes.
+ (md_assemble): Don't use strcmp when deciding to ignore the suffix
+ check in intel mode. Instead compare opcodes.
+
+ * config/tc-i386.h (TC_RELOC): Delete.
+ * config/tc-i386.c (TC_RELOC): Delete. Replace usage of TC_RELOC
+ with equivalent call to reloc.
+
+ * as.h (flag_m68k_mri): Move declaration after target include, and
+ only declare when TC_M68K defined. Define as zero otherwise.
+ (LABELS_WITHOUT_COLONS, NO_PSEUDO_DOT): If undefined, define as 0.
+ * app.c (scrub_m68k_mri): Declare only when TC_M68K defined.
+ Define as zero otherwise.
+ (do_scrub_begin): Use m68k_mri parameter only when TC_M68K defined.
+ (struct app_save): Declare scrub_m68k_mri only when TC_M68K.
+ (app_push, app_pop): Save scrub_m68k_mri only when TC_M68K.
+ (do_scrub_chars): Use LABELS_WITHOUT_COLONS directly rather than
+ testing whether defined.
+ * cond.c (ignore_input): Use NO_PSEUDO_DOT directly.
+ * expr.c (operand): #ifdef unused case labels when TC_M68K undefined.
+ * read.c: Use LABELS_WITHOUT_COLONS and NO_PSEUDO_DOT directly
+ rather than testing whether defined.
+ (s_mri): Set flag_m68k_mri only when TC_M68K defined.
+ (parse_mri_cons): Declare and use only when TC_M68K.
+ * config/tc-hppa.h (LABELS_WITHOUT_COLONS): Define as 1.
+ * config/tc-m68k.h (NO_PSEUDO_DOT): Define as 1.
+ * config/tc-m88k.h (NO_PSEUDO_DOT): Define as 1.
+
+ * NEWS: Mention IBM 370 support.
+
+2000-02-23 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-i386.c (md_assemble): When swapping operands for
+ intel_syntax, assume everything that's not Imm or Disp is a
+ register.
+
+2000-02-23 Linas Vepstas <linas@linas.org>
+
+ * config/tc-i370.c, config/tc-i370.h: New files.
+ * Makefile.am: Add support for Linux/IBM 370.
+ * configure.in: Likewise.
+ * app.c (do_scrub_begin): Don't lex single quote when TC_I370.
+ * config/obj-elf.c: Include elf/i370.h
+ (obj_elf_section): Don't do anything special for flag_mri if TC_I370.
+
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+
+ * doc/c-i370.texi: New file.
+ * doc/all.texi: Include it.
+ * doc/as.texinfo: And here.
+ * doc/Makefile.am(CPU_DOCS): Add c-i370.texi.
+ * doc/Makefile.in: Regenerate.
+
+2000-02-19 Michael Meissner <meissner@redhat.com>
+
+ * config/tc-d30v.c (parallel_ok): Use FLAG_NOT_WITH_ADDSUBppp to
+ determine if an instruction can be used in parallel with an ADDppp
+ or SUBppp instruction.
+
+2000-02-22 Andrew Haley <aph@cygnus.com>
+
+ * doc/c-mips.texi (MIPS Opts): Document -mgp32 and -mgp64.
+
+2000-02-22 Andrew Haley <aph@cygnus.com>
+
+ * config/tc-mips.c (mips_gp32): New variable.
+ (macro_build) Use mips_gp32.
+ (mips_ip): Ditto.
+ (md_longopts): Add "-mgp32" and "-mgp64".
+ (md_parse_option): Add OPTION_GP32 and OPTION_GP64.
+
+ (OPTION_M7900): Change offset
+ (OPTION_NO_M7900): Ditto.
+
+2000-02-22 Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+
+ * config/obj-coff.c (add_lineno): Accept non-positive lineno with
+ warning, and bump it to 1.
+
+2000-02-22 Ian Lance Taylor <ian@zembu.com>
+
+ From Brad Lucier <lucier@math.purdue.edu>:
+ * dwarf2dbg.c (print_stats): Add cast to force printf argument to
+ match format.
+
+2000-02-21 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-mips.c (MF_HILO_INSN): Define.
+ (mips_7000_hilo_fix): Declare.
+ (append_insn): Conditionally insert nops after an mfhi/mflo insn.
+ (md_parse_option): Check for 7000_HILO_FIX options.
+ (OPTION_M7000_HILO_FIX): Define.
+ (OPTION_NO_M7000_HILO_FIX): Define.
+ * doc/c-mips.texi (-mfix7000): Describe.
+
+2000-02-21 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * listing.c (print_lines): Remove unused variable `end'.
+
+ * config/tc-i386.c (md_assemble): Use `reloc()' to select reloc
+ type for JumpInterSegment output. Use enum bfd_reloc_code_real for
+ reloc_type when BFD_ASSEMBLER.
+ (md_estimate_size_before_relax): Use enum bfd_reloc_code_real for
+ reloc_type when BFD_ASSEMBLER. Move common code out of switch
+ statement and quell signed vs. unsigned comparison warning.
+
+2000-02-18 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d10v.c (find_opcode): Add a symbol's value to
+ the computed frag offset, rather than overwriting it.
+
+2000-02-17 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-sh.c ("elf/sh.h"): Include.
+ (sh_dsp, valid_arch, reg_x, reg_y, reg_efg): New static variables.
+ (md.begin): Initialize target_arch.
+ Only include opcodes in has table that match selected architecture.
+ (parse_reg): Recognize register names for sh-dsp.
+ (parse_at): Recognize post-modify addressing.
+ (get_operands): The leading space is now optional.
+ (get_specific): Remove FDREG_N support. Add support for sh-dsp
+ arguments. Update valid_arch.
+ (build_Mytes): Add support for SDT_REG_N.
+ (find_cooked_opcode): New function, broken out of md_assemble.
+ (assemble_ppi, sh_elf_final_processing): New functions.
+ (md_assemble): Use find_cooked_opcode and assemble_ppi.
+ (md_longopts, md_parse_option): New option: -dsp.
+ * config/tc-sh.h (elf_tc_final_processing): Define.
+ (sh_elf_final_processing): Declare.
+
+2000-02-11 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_build_unwind_subspace): Use subseg_new to create
+ the unwinder subspace. Save the current seg/subseg before creating
+ the new seg/subseg.
+
+2000-02-10 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.c (INST_BYTE0): Redefine to handle big and
+ little endian targets.
+ (INST_BYTE1): Redefine to handle big and little endian
+ targets.
+ (cpu_type): New type: Select between M340 and M210.
+ (parse_psrmod): New function: Parse the PSRCLR and PSRSET
+ instructions of the M340.
+ (md_assemble): Add support for the MULSH and OPSR classes of
+ instructions.
+ (md_atof): Add support for little endian targets.
+ (md_parse_option): Add support for -EL, -EB and -mcpu command
+ line switches.
+ (md_convert_frag): Add support for little endian targets.
+ (md_apply_fix3): Add support for little endian targets.
+ (md_number_to_chars): Add support for little endian targets.
+
+2000-02-10 Timothy Wall <twall@redhat.com>
+
+ * read.c (read_a_source_file): If TC_START_LABEL_WITHOUT_COLON is
+ defined, use it to verify the symbol just read should be a label.
+
+2000-02-10 Timothy Wall <twall@redhat.com>
+
+ * app.c (do_scrub_chars): Handle "||" for parallel instructions
+ when DOUBLEBAR_PARALLEL is defined. Avoid stripping whitespace
+ around colons when KEEP_WHITE_AROUND_COLON is defined.
+ * doc/internals.texi (CPU backend): Document DOUBLEBAR_PARALLEL
+ and KEEP_WHITE_AROUND_COLON.
+
+2000-02-08 Timothy Wall <twall@redhat.com>
+
+ * read.c (s_rept): Call do_repeat, which abstracts the repeat
+ logic.
+ (do_repeat): New. Abstract repeat logic so that a "break" can be
+ implemented.
+ (end_repeat): New. Provide support for a "break" out of the
+ repeat loop.
+ * read.h: Add prototypes for new functions.
+
+2000-02-08 Timothy Wall <twall@redhat.com>
+
+ * doc/internals.texi: Document NUMBERS_WITH_SUFFIX macro.
+ * as.h: Provide a default NUMBERS_WITH_SUFFIX definition (zero).
+ * expr.c: Handle numbers with suffixes if NUMBERS_WITH_SUFFIX is
+ non-zero.
+
+2000-02-08 Timothy Wall <twall@redhat.com>
+
+ * read.c: Added elseif to directives table.
+ * read.h: Added prototype for s_elseif.
+ * doc/as.texinfo: Added description for elseif.
+ * cond.c (s_elseif): New function
+
+2000-02-04 Timothy Wall <twall@redhat.com>
+
+ * listing.c (print_lines): Remove conditionals causing bug in
+ listings.
+
+2000-02-03 Timothy Wall <twall@cygnus.com>
+
+ * as.h: Define OCTETS_PER_BYTE and OCTETS_PER_BYTE_POWER
+ default values.
+ * frags.c (frag_new): Calculate fr_fix in octets
+ (frag_now_fix) Return offset as target address offset (bytes).
+ (frag_now_fix_octets) New - Return offset in octets (8-bit
+ quantities).
+ * frags.h: Added prototype for frag_now_fix_octets().
+ Distinguish between octets and bytes in field descriptions.
+ * listing.c (calc_hex): Account for octets vs bytes when
+ printing addresses/offsets.
+ (print_lines) Ditto. Also, if LISTING_WORD_SIZE is not 1, and
+ target is little-endian, print the octets in a word in big-endian
+ order so that the display looks like a proper hexadecimal number,
+ instead of having the octets reversed.
+ * read.c (do_align): When recording alignment, alignment power
+ should be in terms of target bytes (minimum addressible unit)
+ instead of octets.
+ (do_org) Convert ORG target address (byte) argument into an
+ octet offset when generating a variable fragment.
+ * symbols.c (resolve_symbol_value): Symbol final value
+ converted to a target address offset (bytes) from its octet offset.
+ * config/obj-coff.c (coff_frob_symbol): Symbol target address
+ offset (bytes) is adjusted by the frag offset (octets) converted
+ to bytes.
+ (coff_frob_section) Section alignment power is in terms of bytes;
+ convert it to an octet alignment power when calculating size (and
+ size mask) in octets. Don't modify the section size in order to
+ "align" it for TI COFF, since that format has a different method
+ for storing alignment information.
+
+2000-02-01 Timothy Wall <twall@cygnus.com>
+
+ * stabs.c (generate_asm_file): Escape backslashes in stabs file
+ entries, matching the way GCC generates them. If not escaped, the
+ filename is encoded incorrectly.
+
+2000-01-31 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (reg_table): Add support for ATPCS register
+ naming conventions.
+
+2000-01-31 Geoff Keating <geoffk@cygnus.com>
+
+ * config/obj-coff.h (OBJ_COPY_SYMBOL_ATTRIBUTES): Don't define if
+ already defined.
+ * config/tc-ppc.h [OBJ_XCOFF] (OBJ_COPY_SYMBOL_ATTRIBUTES):
+ New macro.
+ * config/tc-ppc.c (ppc_fix_adjustable): Don't look at the frag
+ of a symbol when we really care about its value.
+
+2000-01-19 Chandra Chavva <cchavva@cygnus.com>
+
+ * config/tc-mcore.c (md_assemble): Give warning message if
+ operands passes to instruction are more than the spec.
+
+2000-01-27 Thomas de Lellis <tdel@windriver.com>
+
+ * config/tc-arm.c (armadjust_symtab): If the assembler is in
+ Thumb mode but the label seen was not declared as '.thumb_func'
+ then set the ST_INFO type to STT_ARM_16BIT mode. This allows
+ correct disassembly of Thumb code bounded by non function labels.
+
+2000-01-27 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * Makefile.am (MULTI_CFILES): Add config/e-i386aout.c
+ Add dependencies for e-i386aout.o. Fix 2 comment lines.
+
+ * Makefile.in: Same here.
+ Update copyright.
+
+ * configure.in: Set bfd_gas for i386-aout when primary target
+ is bfd. Handle i386aout emulation. Don't use te_file=multi, as
+ we may need the primary te_file. Remove incorrect comment.
+
+ * configure: Regenerate.
+
+ * config/e-i386aout.c: New file.
+
+ * as.c (USE_EMULATIONS): Move to before print_version_id.
+ (struct emulation): Add i386aout.
+ (show_usage): Split text strings. Reformat -a text. Add --em
+ help.
+ Update copyright.
+
+ * obj.h (struct format_ops): Add s_get_other and s_get_desc.
+ (aout_format_ops): New.
+ Update copyright.
+
+ * read.c (s_lcomm_internal): Rewrite OBJ_AOUT,OBJ_BOUT
+ preprocessor conditional and add aout USE_EMULATIONS tests.
+ (read_a_source_file): Don't pass error strings to printf as
+ format arg.
+ Update copyright.
+
+ * gasp.c (exp_get_abs): Don't pass error strings to printf as
+ format arg.
+ (do_data): Same here.
+ (process_file): And here.
+ Update copyright.
+
+ * symbols.c (colon): Rewrite "already defined" fatal message
+ code for aout with USE_EMULATIONS.
+ Update copyright.
+
+ * config/obj-aout.c (OBJ_HEADER): Define.
+ (obj_pseudo_table): Rename to aout_pseudo_table. Init all
+ fields of sentinel.
+ (obj_aout_frob_symbol): Expand S_GET_DESC, S_GET_TYPE,
+ S_GET_OTHER, S_SET_TYPE macros since we don't need obj-multi
+ forms here.
+ (obj_aout_type): Expand S_SET_OTHER here too.
+ (obj_read_begin_hook): Remove.
+ (aout_pop_insert): New.
+ (obj_aout_s_get_other): New.
+ (obj_aout_s_get_desc): New.
+ (aout_format_ops): New.
+ Update copyright.
+
+ * config/obj-aout.h (obj_pop_insert): Define so non-multi usage
+ gets aout_pseudo_table.
+ (aout_pseudo_table): Declare.
+ (obj_read_begin_hook): Define.
+ Update copyright.
+
+ * config/obj-coff.c (obj_pseudo_table): Rename to
+ coff_pseudo_table.
+ (coff_pop_insert): Use coff_pseudo_table.
+ (coff_sec_sym_ok_for_reloc): Remove.
+ (coff_format_ops): Add 0 entries for s_get_size, s_set_size,
+ and comment all zero entries and remove #if 0 code.
+ Update copyright.
+
+ * config/obj-coff.h (obj_pop_insert): Define.
+ (coff_pseudo_table): Declare.
+ Update copyright.
+
+ * config/obj-ecoff.c (ecoff_format_ops): Add 0 entries for
+ s_get_size, s_set_size. Comment all zero entries.
+ Update copyright.
+
+ * config/obj-elf.c (elf_s_get_other): New function.
+ (obj_read_begin_hook): Rename to elf_obj_read_begin_hook.
+ (obj_symbol_new_hook): Rename to elf_obj_symbol_new_hook.
+ (elf_format_ops): Add elf_s_get_other, 0 s_get_size entry, and
+ comment.
+ (obj_elf_parse_section_letters): Don't pass error strings to
+ printf as format arg.
+ Update copyright.
+
+ * config/obj-elf.h (ECOFF_DEBUGGING): Define when
+ OBJ_MAYBE_ECOFF.
+ (elf_s_get_other): Declare.
+ (S_GET_OTHER) Define as elf_s_get_other if not already
+ defined.
+ (S_SET_OTHER): Only define when not already defined.
+ (elf_obj_read_begin_hook): Declare.
+ (obj_read_begin_hook): Define.
+ (elf_obj_symbol_new_hook): Declare.
+ (obj_symbol_new_hook): Define.
+ Update copyright.
+
+ * config/obj-multi.h: Add copyright header and protect against
+ multiple inclusion. Add * to all function pointers.
+ (OBJ_HEADER): If defined, include it rather than other defines
+ in this file.
+ (obj_frob_file_after_relocs): Test for NULL.
+ (obj_symbol_new_hook): Here too.
+ (obj_sec_sym_ok_for_reloc): And here.
+ (S_GET_OTHER): Define.
+ (S_GET_DESC): Define.
+ (ECOFF_DEBUGGING): Remove as it's done in obj-elf.h
+ (OBJ_MAYBE_ELF): Update comment.
+
+ * config/tc-i386.c (i386_immediate): Add OBJ_MAYBE_AOUT to
+ OBJ_AOUT preprocessor conditional and handle emulation by
+ testing OUTPUT_FLAVOR.
+ (i386_displacement): Here too.
+ (md_section_align): Similarly here.
+ (i386_target_format): Conditionally compile when more than one
+ of OBJ_MAYBE_{ELF,COFF,AOUT} defined. Add aout case.
+ (i386_immediate): Fix error message for aout BFD_ASSMBLER.
+ (i386_displacement): Here too.
+ Update copyright.
+
+ * config/tc-i386.h (AOUT_TARGET_FORMAT): Define for each TE_*.
+ Define TARGET_FORMAT for aout only when not multi.
+ Update copyright.
+
+ * config/te-multi.h: Delete file as it's identical to te-generic.h
+
+2000-01-15 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.h (DWORD_MNEM_SUFFIX): Delete.
+ * config/tc-i386.c (DWORD_MNEM_SUFFIX): Rename all occurrences to
+ LONG_MNEM_SUFFIX.
+
+ * config/tc-i386.h (INTEL_DWORD_MNEM_SUFFIX): Rename to
+ DWORD_MNEM_SUFFIX.
+ * config/tc-i386.c (INTEL_DWORD_MNEM_SUFFIX): Here too. Fix some
+ comments.
+
+2000-01-13 Clinton Popetz <cpopetz@cygnus.com>
+
+ * config/tc-mips.c (mips_do_align): New function.
+ * config/tc-mips.h (md_do_align): Define.
+
+2000-01-10 Philip Blundell <philb@gnu.org>
+
+ * doc/c-arm.texi (ARM Options): Fix typo.
+ (ARM-Chars): Correct description of `#'. Mention that `;' is a
+ line separator for Linux.
+ * doc/as.texinfo (Comments): Mention the ARM.
+
+2000-01-10 Philip Blundell <pb@futuretv.com>
+
+ * configure.in (arm*-*-conix*): New target.
+ (arm*-*-linux-gnu*): Match instead of arm-*-linux* and
+ armv*-*-linux-gnu.
+ * configure: Regenerate.
+
+2000-01-03 Martin v. Loewis <loewis@informatik.hu-berlin.de>
+
+ * config/obj-elf.c (elf_pseudo_table): Define visibility pseudos.
+ (obj_elf_visibility): New function.
+
+ * doc/as.texinfo (Visibility): New node: document visibility
+ pseudo ops.
+
+For older changes see ChangeLog-9899
diff --git a/x/binutils/gas/ChangeLog-0203 b/x/binutils/gas/ChangeLog-0203
new file mode 100644
index 0000000..e22a5d5
--- /dev/null
+++ b/x/binutils/gas/ChangeLog-0203
@@ -0,0 +1,7519 @@
+2003-12-29 Paul Brook <paul@codesourcery.com>
+
+ * gas/config/tc-arm.c (arm_cpus): Add 926ejs and 1026ejs.
+ * gas/doc/c-arm.texi: Document them.
+
+2003-23-12 Paul Brook <paul@codesourcery.com>
+
+ * config/tc-arm.c (arm_archs): Add armv6.
+ * doc/c-arm.texi: Document -march=armv6.
+
+2003-12-20 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-ppc.c (md_apply_fix3): Handle the case where a
+ .byte directive generates a pc-relative relocation.
+
+2003-12-19 Nick Clifton <nickc@redhat.com>
+ Andreas Schwab <schwab@suse.de>
+
+ * messages.c (as_perror): Save errno around library calls.
+ * input-file.c [BFD_ASSEMBLER]: Set the BFD error to
+ bfd_error_system_call before each call to as_perror.
+ (input_file_open): Simplify the error reporting code to just use
+ as_perror().
+ * output-file.c (output_file_create) [BFD_ASSEMBLER]: Set the BFD
+ error to bfd_error_system_call before calling as_perror.
+ (output_file_close) [BFD_ASSEMBLER]: Likewise.
+ (output_file_append) [BFD_ASSEMBLER]: Likewise.
+ * listing.c (listing_print) [BFD_ASSEMBLER]: Likewise.
+
+2003-12-19 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ Add m32r-linux and PIC support. Add new ABI that uses RELA.
+ * configure.in: Add m32r-linux targets.
+ * configure: Regenerate.
+ * config/tc-m32r.c (md_parse_option): Add -KPIC option.
+ (tc_gen_reloc): Added.
+ (debug_sym, md_estimate_size_before_relax, md_convert_frag,
+ md_pcrel_from_section, m32r_fix_adjustable): Changed for PIC.
+ * config/tc-m32r.h (tc_gen_reloc, EXTERN_FORCE_RELOC): Undefined.
+ (TC_HANDLES_FX_DONE, TC_FIX_ADJUSTABLE, TC_RELOC_RTSYM_LOC_FIXUP):
+ Defined.
+ * doc/c-m32r.texi: Document -KPIC option.
+ * NEWS: Mention the support m32r Linux and PIC.
+
+2003-12-18 Nick Clifton <nickc@redhat.com>
+
+ * input-file.c (input_file_open): Remove call to stat().
+ Add a check for getc() failing, and catch the case where the
+ failure is due to an attempt to read a directory.
+
+2003-12-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (mips_need_elf_addend_fixup): Delete.
+ (md_apply_fix3): Remove bfd_install_relocation workarounds.
+ (tc_gen_reloc): Likewise. Factor handling of pc-relative relocations
+ and treat fx_addnumber as relative to the relocation address.
+
+2003-12-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (s_change_section): When parsing the MIPS-specific
+ .section syntax, map SHT_MIPS_DWARF to SHT_PROGBITS.
+
+2003-12-17 Mark Mitchell <mark@codesourcery.com>
+
+ * config/tc-arm.c (arm_archs): Change "armv6" to "armv6j".
+ * doc/c-arm.texi (ARM Options): Likewise.
+
+2003-12-17 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-m32r.c (error_explicit_parallel_conflicts): Rename
+ to 'ignore_parallel_conflicts'.
+ (md_longopts): Change option names as well.
+ (md_parse_option): Separate the warn_explicit and ignore
+ parallel conflicts options.
+ (md_show_usage): Update descriptions of these options.
+ (first_writes_to_seconds_operands): Do not run this check if
+ ignoring parallel conflicts.
+ (assemble_two_insns): Remove code that checked
+ error_explicit_parallel_conflicts.
+ * doc/c-m32r.texi: Update descriptions of the options.
+
+2003-12-16 Dmitry Semyonov <Dmitry.Semyonov@oktet.ru>
+
+ * tc-arm.c (do_adr): Do not adjust pc by -8 if TE_WINCE is
+ defined.
+ (do_adrl): Likewise.
+
+2003-12-15 Christian Groessler <chris@groessler.org>
+
+ * config/tc-z8k.c (struct z8k_exp): Remove, not used anywhere.
+ (ctrl_table): Add "flags" keyword and some comments.
+ (flag_table): Convert to uppercase.
+ (get_flags_operand): Be case insensitive.
+ (get_interrupt_operand): Be case insensitive. Support notation
+ where the inperrupt arguments are separated by commas.
+ (get_operands): Check whether get_flags_operand consumed all
+ arguments. Return failure if get_ctrl_operand didn't recognize a
+ valid control register.
+ (get_specific): Add case CLASS_CTRL: Test for valid control
+ register for ldctlb opcode.
+ (build_bytes): Check for valid control registers.
+
+2003-12-15 Nick Clifton <nickc@redhat.com>
+
+ * config/obj-aout.c (obj_crawl_symbol_chain): Skip defined
+ symbols which resolve to symbolic values.
+
+2003-12-13 Alan Modra <amodra@bigpond.net.au>
+
+ * config/obj-elf.c: Convert to C90, remove unneeded prototypes and
+ casts. Formatting.
+ * config/obj-elf.h: Remove PARAMS.
+
+ * read.c (s_lcomm_internal): Make global.
+ * read.h (s_lcomm_internal): Declare.
+ * config/obj-elf.c (elf_pseudo_table): Handle lcomm.
+ (obj_elf_lcomm): New function.
+
+2003-12-13 Alan Modra <amodra@bigpond.net.au>
+
+ * read.c: Remove unneeded prototypes.
+ (s_comm): Split out code to..
+ (s_comm_internal): ..here. Tidy error returns. Rearrange so that
+ "name" from input line may be used in more places. Merge code
+ testing for valid size from elf_common. Merge code from
+ s_lcomm_internal. Call comm_parse_extra.
+ (bss_alloc): New function, split out of s_lcomm_internal and
+ elf_common.
+ (parse_align): Likewise.
+ (s_lcomm_internal): Rewrite.
+ (s_lcomm, s_lcomm_bytes): Use s_comm_internal.
+ * read.h (bss_alloc, parse_align, s_comm_internal): Declare.
+ * config/obj-elf.c (elf_common): Split out code to..
+ (elf_common_parse): ..here. Remove code common to s_comm_internal,
+ parse_align and bss_alloc. Rearrange and Tidy.
+ * config/tc-alpha.h (TC_IMPLICIT_LCOMM_ALIGNMENT): Define.
+
+2003-12-10 Zack Weinberg <zack@codesourcery.com>
+
+ * tc-ppc.c (md_assemble): Rewrite comment about optional operands
+ to indicate that 'all or none' is also handled. Pluralize a
+ word in another comment.
+
+2003-12-10 Paul Brook <paul@codesourcery.com>
+
+ * config/tc-arm.c (FPU_MAVERICK): Define.
+ (FPU_ARCH_MAVERICK): Define.
+ (arm_float_abi): Define.
+ (mfloat_abi_opt): New variable.
+ (md_begin): Use them.
+ (arm_opts): Add msoft-float and mhard-float.
+ (arm_cpus): Use FPU_ARCH_MAVERICK.
+ (arm_fpus): Add maverick.
+ (arm_float_abis): Add.
+ (arm_parse_float_abi): New function.
+ (arm_long_options): Add mfloat-abi.
+ * doc/as.texinfo: Document -mfloat-abi=.
+ * doc/c-arm.text: Ditto. Menution -fpu=maverick.
+
+2003-12-09 Paul Brook <paul@codesourcery.com>
+
+ * config/tc-arm.c (do_umaal): Fix typo.
+
+2003-12-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * dwarf2dbg.c: Convert to ISO-C.
+ * write.c: Likewise.
+ * write.h: Likewise.
+
+2003-12-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (macro): Switch misordered call to frag_grow()
+ and setting of tc_fr_offset.
+
+2003-12-05 Ricardo Anguiano <anguiano@codesourcery.com>
+ Mark Mitchell <mark@codesourcery.com>
+ Richard Earnshaw <rearnsha@arm.com>
+
+ Add V6 support.
+ * config/tc-arm.c (ARM_EXT_V6): New macro.
+ (ARM_ARCH_V6): Likewise.
+ (SHIFT_IMMEDIATE): Likewise.
+ (SHIFT_LSL_OR_ASR_IMMEDIATE): Likewise.
+ (SHIFT_ASR_IMMEDIATE): Likewise.
+ (SHIFT_LSL_IMMMEDIATE): Likewise.
+ (do_cps): New function.
+ (do_cpsi): Likewise.
+ (do_ldrex): Likewise.
+ (do_pkhbt): Likewise.
+ (do_pkhtb): Likewise.
+ (do_qadd16): Likewise.
+ (do_rev): Likewise.
+ (do_rfe): Likewise.
+ (do_sxtah): Likewise.
+ (do_sxth): Likewise.
+ (do_setend): Likewise.
+ (do_smlad): Likewise.
+ (do_smlald): Likewise.
+ (do_smmul): Likewise.
+ (do_ssat): Likewise.
+ (do_usat): Likewise.
+ (do_srs): Likewise.
+ (do_ssat16): Likewise.
+ (do_usat16): Likewise.
+ (do_strex): Likewise.
+ (do_umaal): Likewise.
+ (do_cps_mode): Likewise.
+ (do_cps_flags): Likewise.
+ (do_endian_specifier): Likewise.
+ (do_pkh_core): Likewise.
+ (do_sat): Likewise.
+ (do_sat16): Likewise.
+ (insns): Add V6 instructions.
+ (do_t_cps): New function.
+ (do_t_cpy): Likewise.
+ (do_t_setend): Likewise.
+ (THUMB_CPY): New macro.
+ (tinsns): Add V6 instructions.
+ (decode_shift): Handle V6 restricted-shift options.
+ (thumb_mov_compare): Support CPY.
+ (arm_cores): Add arm1136js and arm1136jfs.
+ (arm_archs): Add armv6.
+ (arm_fpus): Add arm1136jfs.
+ * doc/c-arm.texi (ARM Options): Mention arm1136js, arm1136jfs, and
+ armv6 options.
+
+2003-12-06 Christian Groessler <chris@groessler.org>
+
+ * config/tc-z8k.c (parse_reg): Be case insensitive when checking
+ register names.
+ (get_ctrl_operand): Be case insensitive when checking ctrl names.
+
+2003-12-05 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-sh.c (md_show_usage): Fix compilation errors
+ introduced by the previous delta.
+
+2003-12-03 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-sh.c: Add support for sh4a and no-fpu variants.
+ * testsuite/gas/sh/basic.exp: Call tests for sh4a.
+ * testsuite/gas/sh/{err-sh4a-fp.s, err-sh4a.s,
+ err-sh4al-dsp.s, sh4a-dsp.d, sh4a-dsp.s, sh4a-fp.d,
+ sh4a-fp.s, sh4a.d, sh4a.s, sh4al-dsp.d, sh4al-dsp.s:
+ New files, tests for sh4a and related variants.
+
+2003-12-05 Michael Snyder <msnyder@redhat.com>
+
+ * config/tc-sh.c (md_show_usage): Mention new -isa options.
+ * doc/c-sh.texi: Document new -isa options.
+ * doc/c-sh64.texi: Ditto.
+ * NEWS: Mention new support for sh4a.
+
+2003-12-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/tc-alpha.c (s_alpha_end): Don't crash if there is no
+ matching .ent.
+
+2003-12-04 Alan Modra <amodra@bigpond.net.au>
+
+ * tc.h (md_pcrel_from): Don't declare if defined as a macro.
+
+2003-12-03 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * config/tc-m32r.h : Add support for new machine m32r2.
+ * config/tc-m32r.c : Likewise.
+ Add new command line switches and directives to allow endian-ness
+ to be selected and some warnings to be turned into errors.
+ (line_separator_chars) : Use '!'.
+ * doc/c-m32r.texi: Document new switches and directives.
+ * NEWS: Mention new support.
+
+2003-12-03 Dave Airlie <airlied@linux.ie>
+
+ * configure.in: Likewise.
+ * configure: Regenerate.
+ * config/tc-vax.c (md_shortopts): Add 'Q'.
+ (md_parse_option): Ignore 'Q' for now.
+
+2003-12-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * messages.c: Convert to ISO-C.
+ * obj.h: Likewise.
+ * output-file.c: Likewise.
+ * output-file.h: Likewise.
+ * sb.c: Likewise.
+ * sb.h: Likewise.
+ * stabs.c: Likewise.
+ * subsegs.c: Likewise.
+ * subsegs.h: Likewise.
+ * tc.h: Likewise.
+
+2003-12-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/obj-elf.c: Remove ARGSUSED.
+
+2003-12-02 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2003-11-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * symbols.c: Convert to ISO-C.
+ * symbols.h: Likewise.
+
+2003-11-28 Christian Groessler <chris@groessler.org>
+
+ * config/tc-z8k.c: Convert to ISO-C.
+ * config/tc-z8k.h: Likewise.
+
+2003-11-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * read.c: Convert to ISO-C.
+ * read.h: Likewise.
+
+2003-11-27 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-sh.c (sh_elf_cons): If md_cons_align is defined
+ call it to make sure that the constants that are going to be
+ emitted are correctly aligned.
+
+2003-11-27 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-frv.c (md_pcrel_from_section): Don't adjust when
+ referencing symbol in a different section.
+
+2003-11-26 Christian Groessler <chris@groessler.org>
+
+ * config/tc-z8k.c (s_segm): Fix indentation.
+ (md_apply_fix3): Likewise.
+ (cc_names): Add alias names for the names generated by the
+ disassembler.
+ (get_cc_operand): Be case insensitive.
+ (get_operands): Improve error handling for cc operands.
+ (check_operand): Not used, remove.
+ (md_assemble): Remove unused variable prev_opcode. Skip
+ whitespace until end-of-line only. Restore *op_end after call to
+ hash_find.
+
+2003-11-26 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-h8300.c (get_operand): Allow er4-er7 for ldm/stm
+ instructions on the H8SX.
+
+2003-11-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/tc-h8300.c (h8_exp): Remove.
+
+2003-11-25 Asgari Jinia <asgarij@kpitcummins.com>
+
+ * config/tc-h8300.c (md_assemble): Check operands validity for
+ ldm/stm.
+ (get_operand): Check register pair's validity as per technical
+ note TN-H8*-193A/E from Renesas for H8s and for H8Sx manual.
+
+2003-11-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * listing.c: Convert to ISO-C.
+ * listing.h: Likewise.
+ * macro.c: Likewise.
+ * macro.h: Likewise.
+
+2003-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ * app.c (do_scrub_chars): Add PUT (ch) and ch = GET ()
+ when transitioning from states 14 or 15 to 0 or 1.
+
+2003-11-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * hash.c: Convert to ISO-C.
+ * hash.h: Likewise.
+ * input-file.c: Likewise.
+ * input-file.h: Likewise.
+ * input-scrub.c: Likewise.
+ * itbl-ops.c: Likewise.
+ * itbl-ops.h: Likewise.
+
+2003-11-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/tc-h8300.c (Hmode): Make it global.
+ (Smode): Likewise.
+ (Nmode): Likewise.
+ (SXmode): Likewise.
+
+2003-11-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ehopt.c: Convert to ISO-C.
+ * emul.h: Likewise.
+ * expr.c: Likewise.
+ * expr.h: Likewise.
+ * flonum-copy.c: Likewise.
+ * flonum-mult.c: Likewise.
+ * flonum.h: Likewise.
+ * frags.c: Likewise.
+ * frags.h: Likewise.
+
+2003-11-22 Alan Modra <amodra@bigpond.net.au>
+
+ * doc/c-ppc.texi (PowerPC-Pseudo): Add section.
+
+ * app.c (do_scrub_chars): Revert 2003-04-23 and 2003-04-22.
+
+2003-11-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ecoff.c: Convert to ISO-C.
+ * ecoff.h: Likewise.
+
+2003-11-22 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (parse_cpu): New function, broken out from..
+ (md_parse_option): ..here.
+ (ppc_setup_opcodes): New function, broken out from..
+ (md_begin): ..here.
+ (ppc_machine): Implement .machine pseudo op.
+
+2003-11-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * depend.c: Convert to ISO-C.
+ * dwarf2dbg.c: Likewise.
+ * dwarf2dbg.h: Likewise.
+
+2003-11-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * app.c: Convert to ISO-C.
+ * as.h: Likewise.
+ * atof-generic.c: Likewise.
+ * bignum-copy.c: Likewise.
+ * bignum.h: Likewise.
+ * cgen.c: Likewise.
+ * cgen.h: Likewise.
+ * cond.c: Likewise.
+
+2003-11-20 DJ Delorie <dj@redhat.com>
+
+ * config/tc-sh64.c (shmedia_frob_section): Only frob elf32
+ sections.
+
+2003-11-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/tc-h8300.c: Make some functions and global
+ variables static appropriately.
+
+2003-11-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/obj-ieee.c: Remove duplicate prototypes.
+ * config/tc-h8300.c: Likewise.
+
+2003-11-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/tc-h8300.c: Convert to ISO-C.
+ * config/tc-h8300.h: Likewise.
+
+2003-11-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/tc-mcore.h: Remove prototypes already in tc.h.
+ * config/tc-tic4x.c: Likewise.
+
+2003-11-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/tc-arc.c: Remove a local prototype of atof_ieee.
+ * config/tc-ip2k.c: Likewise.
+ * config/tc-iq2000.c: Likewise.
+ * config/tc-tic30.c: Remove a comment.
+
+2003-11-19 Bob Wilson <bob.wilson@acm.org>
+
+ * config/tc-xtensa.c (xg_emit_insn): Include "dwarf2dbg.h" and add
+ call to dwarf2_emit_insn.
+
+2003-11-18 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * config/tc-mips.c (macro): Handle new macros: "lca" and "dlca"
+ for loading addresses using CALL relocations.
+ Don't emit CALL relocations when a base register is used.
+
+2003-11-15 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * config/tc-mips.c: Formatting fixes.
+
+2003-11-14 Ben Elliston <bje@wasabisystems.com>
+
+ * config/tc-arm.c (arm_elf_change_section): Not static.
+
+2003-11-13 Nick Clifton <nickc@redhat.com>
+
+ * tc-arm.c (mapping_state): New function. Emit a mapping
+ symbol if necessary.
+ (arm_elf_change_section): New function. Intercept section
+ changes and generate mapping symbols.
+ (s_bss): Likewise.
+ (s_arm_elf_cons): Likewise.
+ (opcode_select): Choose the correct mapping state.
+ (md_assemble): Likewise.
+ * tc-arm.h (md_elf_section_change_hook): Define.
+ * doc/c-arm.texi (ARM Mapping Symbols): New node.
+ * NEWS: Mention new feature.
+
+2003-11-12 Daniel Jacobowitz <drow@mvista.com>
+
+ * Makefile.am (install, install-info, RECURSIVE_TARGETS): Define.
+ * doc/Makefile.am (install-info): Define.
+
+ * aclocal.m4: Regenerate.
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+
+2003-11-11 Dmitry Semyonov <Dmitry.Semyonov@oktet.ru>
+
+ * configure.in: Add support for arm-wince-pe target.
+ * configure: Regenerate.
+
+2003-11-11 Jan Hubicka <jh@suse.cz>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable):
+
+2003-11-10 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ia64.c (ia64_handle_align): Remove bogus be_nop.
+
+2003-11-10 Alan Modra <amodra@bigpond.net.au>
+
+ * README: Update bug report address. Move bug reporting info to
+ binutils/README.
+
+2003-11-07 Christian Groessler <chris@groessler.org>
+
+ * doc/c-z8k.texi: Document command-line options. Fix byte
+ register names. Document '.z8001' and '.z8002' directives.
+ Extend addressing modes documentation.
+
+2003-11-07 Jonathan R. Grant <jg-binutils@jguk.org>
+
+ * input-file.c (input_file_open): Use "No such file" error
+ message.
+
+2003-11-06 Pete Gonzalez <pgonzalez@bluel.com>
+
+ * config/tc-arm.texi (struct reg_entry): Add new field 'builtin'.
+ (rn_table, iwmmxt_table, cp_table, cn_table, fn_table, sn_table,
+ dn_table, mav_mvf_table, mac_mvd_table, mav_mvfx_table,
+ mav_mvax_table, mav_dspc_table): Initialise new field.
+ (insert_reg_alias): Initialise new field.
+ (md_pseudo_table): Add "unreq" entry.
+ (s_unreq): New function: Undo the effects of a previous .req.
+ * doc/c-arm.texi: Document new pseudo op.
+ * NEWS: Mention new feature.
+
+2003-11-06 Bruno Rohee <bruno@rohee.com>
+
+ * config/obj-vms.c: Fix "the the" typo.
+ * doc/c-arm.texi: Likewise.
+
+2003-11-06 Nick Clifton <nickc@redhat.com>
+
+ * config/obj-vms.c: Convert to ISO-C.
+
+2003-11-05 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.h (TC_FORCE_RELOCATION): Only define for ELF and XCOFF.
+
+2003-10-31 Christian Groessler <chris@groessler.org>
+
+ * config/tc-i860.c (md_pcrel_from): Fix typo in comment.
+
+2003-10-29 Phil Edwards <phil@codesourcery.com>
+
+ * configure.in (arm-*-vxworks, i386-*-vxworks, mips-*-vxworks,
+ ppc-*-vxworks, ppc-*-windiss): Remove separate outdated stanzas.
+ (*-*-vxworks, *-*-windiss): Use common stanzas, all ELF.
+ * configure: Regenerated.
+
+2003-10-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Fix typos.
+ * ChangeLog-9295: Likewise.
+ * as.c: Fix comment typos.
+ * as.h: Likewise.
+ * atof-generic.c: Likewise.
+ * bit_fix.h: Likewise.
+ * frags.h: Likewise.
+ * hash.c: Likewise.
+ * input-file.c: Likewise.
+ * input-scrub.c: Likewise.
+ * itbl-ops.c: Likewise.
+ * itbl-parse.y: Likewise.
+ * listing.c: Likewise.
+ * macro.h: Likewise.
+ * read.c: Likewise.
+ * sb.c: Likewise.
+ * sb.h: Likewise.
+ * symbols.c: Likewise.
+ * symbols.h: Likewise.
+
+2003-10-27 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/tc-m68hc11.c: Convert to ISO C90.
+ * config/tc-m68hc11.h: Likewise.
+
+2003-10-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/c-sh64.texi: Fix a typo.
+
+2003-10-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/c-alpha.texi: Fix typos.
+ * doc/c-ia64.texi: Likewise.
+ * doc/c-mmix.texi: Likewise.
+ * doc/c-sh64.texi: Likewise.
+ * doc/c-xtensa.texi: Likewise.
+ * doc/internals.texi: Likewise.
+
+2003-10-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/obj-elf.c (obj_elf_change_section): Allow SHF_ALLOC
+ for .interp, .strtab and .symtab. Use specified section
+ attributes.
+
+2003-10-22 Andreas Schwab <schwab@suse.de>
+ H.J. Lu <hongjiu.lu@intel.com>
+ Jim Wilson <wilson@specifixinc.com>
+
+ * config/tc-ia64.c (update_qp_mutex): New.
+ (note_register_values): Properly handle one of PRs in compare
+ is PR0. Don't add a mutex relation for .and.orcm/.or.andcm.
+ Clear mutex relation for .none/.unc. Don't clear mutex relation
+ on predicated compare.
+
+2003-10-21 Wouter van Heyst <wouter@vidicode.nl>
+
+ * config/tc-arm.c (all_reg_maps): Correct text describing Maverick
+ register requirements.
+ (md_begin): Remove F_SOFT_FLOAT if enabling MAVERICK FP.
+
+2003-10-21 Peter Barada <pbarada@mail.wm.sps.mot.com>
+ Bernardo Innocenti <bernie@develer.com>
+
+ * config/tc-m68k.c: Add MCF528x (MCFv4) support.
+ * config/m68k-parse.h: Likewise.
+ * NEWS: Mention the new support.
+ * doc/c-m68k.texi: Document new processor selection switch.
+
+2003-10-19 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (normalize_constant_expr): New function to fix sign
+ extensions broken by gas' expression evaluation of constants.
+ (check_absolute_expr): Use it.
+ (mips_ip): Likewise.
+
+2003-10-18 Hans-Peter Nilsson <hp@bitrange.com>
+
+ Generate BFD_RELOC_MMIX_PUSHJ_STUBBABLE for PUSHJ when possible.
+ * doc/c-mmix.texi (MMIX-Opts): Document --no-pushj-stubs and
+ --no-stubs.
+ * config/tc-mmix.c: Include limits.h. Expand on mmix_relax_table
+ comment.
+ (expand_op, mmix_next_semicolon_is_eoln): Fix head comment.
+ (pushj_stubs): New variable.
+ (OPTION_NOPUSHJSTUBS, STATE_PUSHJSTUB, PUSHJSTUB_MIN)
+ (PUSHJSTUB_MAX): New macros.
+ (md_longopts): New options "--no-pushj-stubs" and synonym
+ "--no-stubs".
+ (mmix_relax_table): Handle new entry for STATE_PUSHJSTUB.
+ (md_parse_option): Handle OPTION_NOPUSHJSTUBS.
+ (md_estimate_size_before_relax): Modify STATE_PUSHJ state for
+ PUSHJ stub relaxation.
+ (md_convert_frag): Handle STATE_PUSHJSTUB.
+ (md_apply_fix3): Handle BFD_RELOC_MMIX_PUSHJ_STUBBABLE.
+ (tc_gen_reloc): Ditto.
+ (mmix_md_relax_frag): Handle PUSHJ stub relaxation.
+ * config/tc-mmix.h (TC_SEGMENT_INFO_TYPE): Define.
+ (struct mmix_segment_info_type): New.
+
+2003-10-17 Paul Dale <pauli@snapgear.com>
+ Bernardo Innocenti <bernie@develer.com>
+
+ * config/tc-m68k.c (make_pcrel_absolute): Enforce
+ PC-relative jumps with --pcrel.
+ (md_convert_frag_1): Likewise.
+ (md_create_long_jump): Likewise.
+
+2003-10-17 Shrinivas Atre <shrinivasa@KPITCummins.com>
+
+ * config/tc-h8300.c (PSIZE): Correct for Normal mode.
+ (get_operand): Accept both 16 bit 32 bit registers as pointer
+ registers, when operating in Normal mode.
+ (fix_operand_size): Make default address size 16 for Normal mode.
+
+2003-10-17 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * config/tc-arm.c (do_iwmmxt_byte_addr): Reject control
+ registers.
+ (do_iwmmxt_word_addr): With a control register, reject conditional
+ execution and reject a non-word size.
+
+2003-10-16 Peter Bergner <bergner@vnet.ibm.com>
+
+ * configure.in: Set em=linux for ppc-*-linux-gnu* target.
+ * configure: Regenerate.
+
+2003-10-15 Alan Modra <amodra@bigpond.net.au>
+
+ * doc/as.texinfo (Align): Correct list of byte targets.
+
+2003-10-15 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (macro_build_ldst_constoffset,load_register,macro):
+ Fix indentation. Better error message.
+
+2003-10-14 Bob Wilson <bob.wilson@acm.org>
+
+ * config/tc-xtensa.c (xtensa_create_property_segments): Remove bfd
+ argument in call to xtensa_get_property_section_name. Formatting.
+
+2003-10-11 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * config/tc-sh.h (sh_coff_reloc_mangle): Delete an extra
+ parenthesis.
+
+2003-10-11 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * config/tc-sh.c: Convert to ISO C90. Remove unnecessary
+ prototypes and casts.
+ * config/tc-sh.h: Likewise.
+ * config/tc-sh64.c: Likewise.
+ * config/tc-sh64.h: Likewise.
+
+2003-10-08 Dave Brolley <brolley@redhat.com>
+
+ * config/tc-frv.c (fr550_check_insn_acc_range): New function.
+ (fr550_check_acc_range): New function.
+ (md_assemble): Call fr550_check_acc_range.
+
+2003-10-08 Dave Brolley <brolley@redhat.com>
+
+ * config/tc-frv.c: Handle DEFAULT_CPU_FR550.
+ (md_parse_option): Handle OPTION_CPU==fr550.
+ (md_show_usage): Document fr550.
+
+2003-10-08 Philippe De Muyter <phdm@macqel.be>
+
+ * as.c (use_gnu_debug_info_extensions) : New variable.
+ (parse_args) : Accept new --gstabs+ option, and set
+ `use_gnu_debug_info_extensions'.
+ (show_usage) : Document --gstabs+ option.
+ * as.h (use_gnu_debug_info_extensions) : New extern declaration.
+ * stabs.c (stabs_generate_asm_file) : If
+ `use_gnu_debug_info_extensions' is set, add the compilation
+ directory to the stabs debug info.
+ * doc/as.texinfo : Document --gstabs+ option.
+ * NEWS: Mention new feature.
+
+2003-10-06 Matt Thomas <matt@3am-software.com>
+
+ Switch NetBSD/hppa to use Linux PA-RISC ELF ABI and
+ assembler syntax.
+
+ * tc-hppa.c: Add "%farg[0-3]", "%fret", "%t[1-4]", "%tf[1-4]"
+ register names. Change all "defined (TE_LINUX)" to
+ "(defined (TE_LINUX) || defined (TE_NETBSD))".
+
+ * tc-hppa.h: Make NetBSD use "elfXX-hppa-linux" bfd target.
+ Remove NetBSD's use of LABELS_WITHOUT_COLONS.
+
+2003-10-06 Robert Millan <robertmh@gnu.org>
+
+ * configure.in: Match GNU/KNetBSD with new knetbsd*-gnu triplet.
+ * configure: Regenerate.
+
+2003-10-05 Nick Clifton <nickc@redhat.com>
+
+ * as.c (parse_args): Revert patch to change handling of -f
+ option. Its behaviour is mandated by the POSIX 2 spec.
+
+2003-10-04 Christian Groessler <chris@groessler.org>
+
+ * tc-z8k.c (newfix): Tell fix_new_exp about pc relativeness.
+ (md_apply_fix3): Fix R_JR, R_DISP7, and R_CALLR cases.
+ (md_pcrel_from): This function now gets called. Supply return
+ value.
+
+2003-10-04 Nick Clifton <nickc@redhat.com>
+
+ * as.c: Convert to ISO C90.
+
+2003-10-04 Nick Clifton <nickc@redhat.com>
+
+ * as.c (std_shortopts): Remove 'f'.
+ (std_longopts): Add 'f'. Doing this prevents -f<foo> being
+ acecpted as an alias for -f.
+
+2003-10-04 Danny Smith <danny_r_smith_2001@yahoo.co.nz>
+
+ * config/obj-coff.c (obj_coff_section [BEF_ASSEMBLER]):
+ Make 'r' mean readonly data.
+
+2003-10-01 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (macro_build_ldst_constoffset,load_register,macro):
+ Unbreak overflow checks.
+
+2003-10-01 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (s_cpreturn): Correct errors in comment.
+
+2003-10-01 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (macro_build_ldst_constoffset): Fix sign extension
+ tests.
+ (load_register): Likewise.
+ (macro): Likewise.
+
+2003-09-30 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (mips_ip): Capitalize first word of
+ existing condition code warning, and add condition code
+ warnings for .ps instructions, and for bc1any[24][tf].
+
+2003-09-30 Chris Demetriou <cgd@broadcom.com>
+
+ * NEWS: Mention support for MIPS64 Release 2.
+
+2003-09-30 Chris Demetriou <cgd@broadcom.com>
+
+ * NEWS: Add an indication of the cutoff for 2.14.
+
+2003-09-30 Chris Demetriou <cgd@broadcom.com>
+
+ * configure.in (mipsisa64r2, mipsisa64r2el, mipsisa64r2*): New CPUs.
+ * configure: Regenerate.
+ * config/tc-mips.c (imm2_expr): New variable.
+ (md_assemble, mips16_ip): Initialize imm2_expr.
+ (ISA_HAS_64BIT_REGS, ISA_HAS_DROR, ISA_HAS_ROR): Add ISA_MIPS64R2.
+ (macro_build): Handle +A, +B, +C, +E, +F, +G, and +H format operands.
+ (macro): Handle M_DEXT and M_DINS.
+ (validate_mips_insn): Handle +E, +F, +G, +H, and +I format operands.
+ (mips_ip): Likewise.
+ (OPTION_MIPS64R2): New define.
+ (md_longopts): New entry for -mips64r2 (OPTION_MIPS64R2).
+ OPTION_ASE_BASE): Increase to compensate for OPTION_MIPS64R2.
+ (md_parse_option): Handle OPTION_MIPS64R2.
+ (s_mipsset): Handle setting "mips64r2" ISA.
+ (mips_cpu_info_table): Add mips64r2.
+ (md_show_usage): Document -mips64r2 option.
+ * doc/as.texinfo: Docuemnt -mips64r2 option.
+ * doc/c-mips.texi: Likewise.
+
+2003-09-27 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * config/tc-hppa.c (pa_ip): Check for invalid 64-bit conditions.
+
+2003-09-26 Matt Thomas <matt@3am-software.com>
+
+ * config/tc-vax.c (md_shortopts): Fix a typo. Remove 'K'.
+ (OPTION_PIC): Define.
+ (md_longopts): Add "pic" option.
+ (md_parse_option): Change 'K' to OPTION_PIC.
+
+2003-09-23 Alan Modra <alan@modra.org>
+
+ * config/obj-elf.c (obj_elf_change_section): Adjust for
+ _bfd_elf_get_sec_type_attr changes. Allow SHF_MERGE and SHF_STRINGS
+ to be set when defaults are not. Don't set attr from defaults if
+ old_sec.
+
+2003-09-18 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (macro_build_ldst_constoffset): Don't silently
+ truncate values which won't fit im 32 bits.
+ (load_register): Likewise.
+ (macro): Likewise.
+
+2003-09-17 Dmitry Diky <diwil@mail.ru>
+
+ * config/tc-msp430.c (MAX_OP_LEN): Set to 256.
+ (msp430_operands): Remove redundant l2[16] within switch-case.
+
+2003-09-16 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.in: Handle arm-*-rtems* and thumb-*rtems*.
+ * configure: Regenerate.
+
+2003-09-14 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (HAVE_64BIT_ADDRESS_CONSTANTS): Remove.
+ (macro_build_ldst_constoffset): Sign-extend 32-bit constants. Change
+ the function prototype.
+ (load_register): Likewise. Simplify the checks for sign-extended
+ constants.
+ (macro): Likewise. Fix code generation for 64-bit address constants
+ outside the 32-bit compatibility space. Adjust
+ macro_build_ldst_constoffset calls.
+ (s_cprestore): Adjust macro_build_ldst_constoffset call.
+
+2003-09-11 Bob Wilson <bob.wilson@acm.org>
+
+ * config/tc-xtensa.c (insn_labels, free_insn_labels, saved_insn_labels,
+ literal_syms): New global variables.
+ (xtensa_define_label, add_target_symbol, xtensa_find_label,
+ map_over_defined_symbols, is_loop_target_label,
+ xtensa_mark_target_fragments, xtensa_move_frag_symbol,
+ xtensa_move_frag_symbols, defined_symbols, branch_targets): Delete.
+ (xtensa_begin_directive): Call md_flush_pending_output. Move symbols
+ from insn_labels to saved_insn_labels when entering a literal region.
+ (xtensa_end_directive): Call md_flush_pending_output. Restore
+ insn_labels list when leaving a literal region.
+ (xtensa_literal_position): Call xtensa_clear_insn_labels.
+ (xtensa_literal_pseudo): Add check to disallow .literal inside a
+ literal region. Move insn_labels to saved_insn_labels and then restore
+ insn_labels on exit.
+ (xg_add_branch_and_loop_targets): Replace add_target_symbol calls with
+ code to set is_loop_target or is_branch_target flag on the symbol
+ (xtensa_create_literal_symbol): Call xtensa_add_literal_sym.
+ (xtensa_add_literal_sym, xtensa_add_insn_label,
+ xtensa_clear_insn_labels): New functions.
+ (xtensa_move_labels): Remove old_frag and old_offset arguments. Add
+ loops_ok argument. Rewrite to use insn_labels list instead of
+ calling xtensa_find_label and to check the is_loop_target flag on
+ symbols when loops_ok is false.
+ (xtensa_frob_label): Remove call to xtensa_define_label. Add call
+ to either xtensa_add_literal_sym or xtensa_add_insn_label. Adjust
+ call to xtensa_move_labels. Propagate is_branch_target and
+ is_loop_target flags from symbols to frags.
+ (xtensa_flush_pending_output): Call xtensa_clear_insn_labels.
+ (md_assemble): Use xtensa_move_labels with loops_ok = FALSE when
+ aligning a loop instruction. Adjust call to xtensa_move_labels for
+ aligning entry instructions. Add call to xtensa_clear_insn_labels.
+ (xtensa_end): Remove call to xtensa_mark_target_fragments.
+ (xtensa_move_literals): Replace xtensa_move_frag_symbols call with
+ code to use new literal_syms list.
+ * config/tc-xtensa.h (xtensa_symfield_type): Add is_loop_target and
+ is_branch_target flags.
+
+2003-09-09 Bob Wilson <bob.wilson@acm.org>
+
+ * config/tc-xtensa.c (xtensa_mark_literal_pool_location): Remove
+ "move_labels" argument and corresponding call to xtensa_move_labels.
+ (md_assemble): Add a separate call to xtensa_move_labels and remove
+ argument for call to xtensa_mark_literal_pool_location.
+ (xtensa_literal_position, xtensa_switch_to_literal_fragment): Fix
+ calls to xtensa_mark_literal_pool_location.
+ (xtensa_create_local_symbol): Delete and inline the code into...
+ (xtensa_create_literal_symbol): ...here.
+ (xtensa_frob_label): Combine conditionals.
+ (expression_maybe_register, xtensa_symbol_new_hook,
+ fix_new_exp_in_seg): Use symbol_get_tc.
+
+2003-09-09 Bob Wilson <bob.wilson@acm.org>
+
+ * config/tc-xtensa.c (xtensa_literal_pseudo): Remove code for
+ combining identical literals.
+ (expression_maybe_register): Remove call to find_lit_sym_translation.
+ (is_duplicate_expression, cache_literal, is_duplicate_literal,
+ add_lit_sym_translation, find_lit_sym_translation): Delete.
+
+2003-09-07 Nick Clifton <nickc@redhat.com>
+
+ * doc/as.texinfo (Comments): Comment character for PPC is #.
+
+2003-09-06 Stephane Carrez <stcarrez@nerim.fr>
+
+ PR savannah/4358:
+ * config/tc-m68hc11.c (s_m68hc11_relax): Use 2 for size to avoid
+ overflow complain.
+
+2003-09-05 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-frv.c (md_pcrel_from_section): Heed TC_FORCE_RELOCATION.
+
+2003-09-04 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-v850.c (set_machine): Accept v850e1 machine number.
+ (md_pseudo_table): Add .v850e1 pseudo op.
+ (md_show_usage): Document -mv850e1 switch.
+ (md_parse_option): Accept -mv850e1 switch.
+ (md_begin): Allow TARGET_CPU to be v850e1.
+ * doc/c-v850.texi: Document -mv850e1 switch and .v850e1 pseudo op.
+ * NEWS: Mention support for v850e1.
+
+2003-09-04 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (md_parse_option): Add PPC_OPCODE_ANY to existing
+ ppc_cpu selection rather than replacing.
+ (ppc_set_cpu): Ignore and preserve PPC_OPCODE_ANY in ppc_cpu.
+ (md_begin): When PPC_OPCODE_ANY, insert all opcodes in ppc_hash.
+
+2003-09-03 Robert Millan <robertmh@gnu.org>
+
+ * configure.in: Match GNU/KFreeBSD with new kfreebsd*-gnu
+ triplet.
+ * configure: Regenerate.
+
+2003-09-02 Daniel Jacobowitz <drow@mvista.com>
+
+ * configure.in: Update AC_PREREQ to 2.57. Use AC_CONFIG_FILES
+ and AC_CONFIG_COMMANDS instead of the three-argument AC_OUTPUT.
+ Specify AC_CONFIG_AUX_DIR.
+ * aclocal.m4: Regenerated with aclocal-1.7.
+ * configure: Regenerated with autoconf 2.57.
+ * Makefile.in, doc/Makefile.in: Regenerated with automake-1.7.
+
+2003-08-29 Jakub Jelinek <jakub@redhat.com>
+
+ * dw2gencfi.c (cfi_pseudo_table): Add cfi_window_save.
+ (dot_cfi, output_cfi_insn): Handle DW_CFA_GNU_window_save.
+ (output_cie): Don't use DW_EH_PE_pcrel if neither DIFF_EXPR_OK
+ nor tc_cfi_emit_pcrel_expr are defined.
+ (output_fde): Use tc_cfi_emit_pcrel_expr if available and
+ DIFF_EXPR_OK is not defined.
+ * config/tc-sparc.h (TARGET_USE_CFIPOP): Define.
+ (tc_cfi_frame_initial_instructions, tc_regname_to_dw2regnum,
+ tc_cfi_emit_pcrel_expr): Define.
+ (sparc_cfi_frame_initial_instructions, sparc_regname_to_dw2regnum,
+ sparc_cfi_emit_pcrel_expr): New prototypes.
+ (sparc_cie_data_alignment): New decl.
+ (DWARF2_DEFAULT_RETURN_COLUMN, DWARF2_CIE_DATA_ALIGNMENT): Define.
+ * config/tc-sparc.c: Include dw2gencfi.h.
+ (sparc_cie_data_alignment): New variable.
+ (md_begin): Initialize it.
+ (sparc_cfi_frame_initial_instructions): New function.
+ (sparc_regname_to_dw2regnum): Likewise.
+ (sparc_cfi_emit_pcrel_expr): Likewise.
+ * doc/as.texinfo: Document .cfi_window_save.
+
+ * config/tc-sparc.c (s_common): Cast last argument to long and
+ change format string to shut up warning.
+
+2003-08-25 Jason Eckhardt <jle@rice.edu>
+
+ * doc/c-i860.texi: Update text about relocatable address expansions.
+
+2003-08-24 Jason Eckhardt <jle@rice.edu>
+
+ * config/tc-i860.c (md_assemble): Use isrc2 from the original
+ instruction when expanding E_ADDR.
+
+2003-08-21 Nick Clifton <nickc@redhat.com>
+
+ * po/tr.po: Updated Turkish translation.
+
+2003-08-20 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (md_parse_option): Add PPC_OPCODE_ISEL and
+ PPC_OPCODE_RFMCI to -m440 selected ppc_cpu.
+
+2003-08-19 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (cp_address_required_here): Add code to handle
+ unindexed addressing mode.
+
+2003-08-19 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (md_parse_option): Handle -m440.
+ (md_show_usage): Add -m440.
+ (md_apply_fix3): Warning fix.
+ * doc/c-ppc.texi: Document -m440.
+
+2003-08-16 Benjamin Kalytta <bkausbk@web.de>
+
+ * read.c (s_print): Check for NULL.
+
+2003-08-16 Alan Modra <amodra@bigpond.net.au>
+
+ * write.c (fixup_segment): When handling an expression involving
+ the subtraction of two symbols in the same segment, don't clear
+ fx_pcrel except for TC_M68K.
+
+2003-08-14 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.h: Remove BFD_ASSEMBLER tests and all !BFD_ASSEMBLER
+ code.
+ * config/tc-i386.c: Likewise.
+ (RELOC_ENUM): Don't define. Replace throughout with enum.
+
+ * dep-in.sed: Remove libintl.h. Ignore include/fopen-*.h
+ * Makefile.am (POTFILES.in): Unset LC_COLLATE.
+ Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2003-08-08 Andreas Schwab <schwab@suse.de>
+
+ * config/tc-m68k.h (TARGET_USE_CFIPOP)
+ (DWARF2_DEFAULT_RETURN_COLUMN, DWARF2_CIE_DATA_ALIGNMENT)
+ (tc_regname_to_dw2regnum, tc_cfi_frame_initial_instructions):
+ Define.
+ * config/tc-m68k.c: Include "dw2gencfi.h".
+ (tc_m68k_regname_to_dw2regnum)
+ (tc_m68k_frame_initial_instructions): New functions.
+
+2003-08-08 Dmitry Diky <diwil@mail.ru>
+
+ * config/tc-msp430.c: Add xW42 and xE42 parts. Sort MPU list
+ according to gcc order.
+
+2003-08-07 Jason Eckhardt <jle@rice.edu>
+
+ * config/tc-i860.c (i860_check_label): New function.
+ * config/tc-i860.h (i860_check_label): New prototype.
+ (tc_check_label): Define macro as i860_check_label.
+
+2003-08-06 Jason Eckhardt <jle@rice.edu>
+
+ * config/tc-i860.c (s_align_wrapper): New function and prototype.
+ (md_pseudo_table): Change s_align_bytes to s_align_wrapper, remove
+ surrounding OBJ_ELF ifdef, and re-format slightly.
+ * doc/c-i860.texi: Document the special .align syntax available
+ in Intel mode.
+
+2003-08-06 Jason Eckhardt <jle@rice.edu>
+
+ * config/tc-i860.c (i860_handle_align): New function.
+ * config/tc-i860.h (HANDLE_ALIGN): Define macro.
+ (MAX_MEM_FOR_RS_ALIGN_CODE): Define macro.
+
+2003-08-06 Jason Eckhardt <jle@rice.edu>
+
+ * config/tc-i860.c (i860_process_insn): Check that instructions
+ with their dual-bit set are 8-byte aligned.
+
+2003-08-06 Nick Clifton <nickc@redhat.com>
+
+ * po/fr.po: Updated French translation.
+
+2003-08-05 Jason Eckhardt <jle@rice.edu>
+
+ * config/tc-i860.c (i860_process_insn): Don't handle dual-bit
+ setting during flop argument parsing. Instead, do it after
+ instruction is fully parsed.
+
+2003-08-05 Jason Eckhardt <jle@rice.edu>
+
+ * doc/c-i860.texi: Mention that .dual, .enddual, and .atmp
+ directives are only available in Intel syntax mode.
+
+2003-08-05 Jason Eckhardt <jle@rice.edu>
+
+ * config/tc-i860.c (s_dual): Accept .dual directive only in
+ the Intel syntax mode.
+ (s_enddual): Likewise for .enddual.
+ (s_atmp): Likewise for .atmp.
+
+2003-08-04 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.c (i386_intel_operand): Always call i386_index_check
+ for memory operands. Pass the full operand_string to i386_index_check.
+
+2003-08-01 Jason Eckhardt <jle@rice.edu>
+
+ * config/tc-i860.c: Remove SYNTAX_SVR4 macro and occurrences.
+ (target_intel_syntax): Declare variable.
+ (OPTION_INTEL_SYNTAX): Declare macro.
+ (md_longopts): Add option -mintel-syntax.
+ (md_parse_option): Set target_intel_syntax.
+ (md_show_usage): Add -mintel-syntax usage.
+ (md_begin): Set reg_prefix based on target_intel_syntax.
+ (i860_process_insn): Skip register prefix only if there is one.
+ Parse relocatable expressions in either Intel or AT&T syntax based
+ on target_intel_syntax instead of the SYNTAX_SVR4 macro.
+ * doc/c-i860.texi: Document -mintel-syntax option and give blurb
+ about the differences in syntax.
+
+2003-08-01 Dmitry Diky <diwil@mail.ru>
+
+ * config/tc-msp430.c (msp430_srcoperand): Extend 'push' bug workaround
+ to all arches.
+
+2003-07-30 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config/tc-sh.c (md_assemble): For branches, check & update
+ valid_arch here.
+
+2003-07-30 Jason Eckhardt <jle@rice.edu>
+
+ * config/tc-i860.c: Convert to ISO C90.
+
+2003-07-30 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * read.c (s_space): Revert 2003-07-28 change.
+
+2003-07-30 Alan Modra <amodra@bigpond.net.au>
+
+ * config/obj-elf.c (obj_elf_change_section): Allow "x" for .note*.
+
+2003-07-29 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-sh.c (tc_gen_reloc): Test for R_SH_IND12W only when ELF.
+
+2003-07-29 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-ppc.c (md_apply_fix3): Fix check for lq insns.
+
+2003-07-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/obj-elf.c (obj_elf_section_type): Also accept "note".
+
+2003-07-28 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * read.c (s_space): Don't warn about .space 0.
+
+2003-07-28 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/tc-mips.c (mips_flag_pdr): Define.
+ (md_begin) [OBJ_ELF]: Use it to control .pdr creation.
+ (s_mips_end) [OBJ_ELF]: Likewise.
+ (md_longopts) [OBJ_ELF]: Define OPTION_PDR, OPTION_NO_PDR.
+ (md_parse_option) [OBJ_ELF]: Handle them.
+ (md_show_usage) [OBJ_ELF]: Document -mpdr, -mno-pdr.
+
+ * doc/c-mips.texi (MIPS Opts): Document -mpdr, -mno-pdr.
+ * doc/as.texinfo (Overview) [MIPS]: Likewise.
+
+2003-07-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/obj-elf.c (obj_elf_change_section): Update
+ elf_section_type and elf_section_flags only when they are
+ specified.
+
+2003-07-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/obj-elf.c (obj_elf_change_section): Always set section
+ type and flags.
+
+2003-07-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/obj-elf.c (special_sections): Removed.
+ (obj_elf_change_section): Call _bfd_elf_get_sec_type_attr. Set
+ elf_section_type and elf_section_flags.
+ (elf_frob_file): Set SHT_GROUP.
+
+ * config/obj-elf.h (obj_sec_set_private_data): New.
+
+ * config/tc-alpha.h (ELF_TC_SPECIAL_SECTIONS): Removed.
+ * config/tc-ia64.h: Likewise.
+ * config/tc-m32r.h: Likewise.
+ * config/tc-m68hc11.h: Likewise.
+ * config/tc-mcore.h: Likewise.
+ * config/tc-mips.h: Likewise.
+ * config/tc-ppc.h: Likewise.
+ * config/tc-sh64.h: Likewise.
+ * config/tc-v850.h: Likewise.
+ * config/tc-xtensa.h: Likewise.
+
+ * config/tc-v850.h (SHF_V850_GPREL): Removed.
+ (SHF_V850_EPREL): Likewise.
+ (SHF_V850_R0REL): Likewise.
+
+ * subsegs.c (subseg_get): Call obj_sec_set_private_data if it
+ is defined.
+
+2003-07-24 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/tc-m68hc11.h (DWARF2_ADDR_SIZE): Use 32-bit address for
+ debugging symbols so that we handle page memory correctly.
+
+2003-07-24 Nick Clifton <nickc@redhat.com>
+
+ * po/fr.po: Updated French translation.
+
+2003-07-23 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/tc-arm.c (arm_archs): Add iwmmxt.
+
+2003-07-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * read.c (do_parse_cons_expression): Mark nbytes unused to
+ silence gcc.
+
+2003-07-22 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-h8300.c (get_specific): No PCREL8 encoding for bsr/bc
+ or bsr/bs.
+
+ * config/tc-h8300.c (md_assemble): Make sure characters after
+ slash and dot are lower-case.
+
+2003-07-17 Nick Clifton <nickc@redhat.com>
+
+ * po/es.po: New Spanish translation.
+ * po/tr.po: New Turkish translation.
+ * po/opcodes.pot: Regenerate.
+
+2003-07-16 Alan Modra <amodra@bigpond.net.au>
+
+ * dwarf2dbg.c (get_frag_fix): Revert 2001-11-15 change.
+ (generic_dwarf2_emit_offset): Don't define function when
+ TC__DWARF2_EMIT_OFFSET is defined.
+
+2003-07-15 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (hilo_interlocks): True for CPU_RM7000.
+ (mips_cpu_info_table): Add rm7000 and rm9000 entries.
+ * doc/c-mips.texi: Document -march=rm9000.
+
+2003-07-15 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-v850.c (md_assemble): When no reloc, create pcrel fixups
+ only for V850_OPERAND_DISP operands.
+
+2003-07-15 Alan Modra <amodra@bigpond.net.au>
+
+ * frags.c (frag_more): Move segment checks to..
+ (frag_alloc_check): ..here. New function.
+ (frag_append_1_char): Call frag_alloc_check.
+
+2003-07-14 Nick Clifton <nickc@redhat.com>
+
+ * po/tr.po: Update with latest version.
+ * po/POTFILES.in: Regenerate.
+ * po/gas.pot: Regenerate.
+ * configure: Regenerate.
+
+2003-07-14 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-ip2k.c: Remove inclusion of <ctype.h>
+ * config/tc-tic4x.c: Replace inclusion of <ctype.h> with
+ "safe-ctype.h" and update use of macros.
+ * Makefile.am: Update dependencies.
+ * Makefile.in: Regenerate.
+
+2003-07-11 Alan Modra <amodra@bigpond.net.au>
+
+ * po/gas.pot: Regenerate.
+
+2003-07-10 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-ppc.h (DWARF2_LINE_MIN_INSN_LENGTH): Define always.
+ (TARGET_USE_CFIPOP, tc_cfi_frame_initial_instructions,
+ tc_regname_to_dw2regnum, DWARF2_DEFAULT_RETURN_COLUMN,
+ DWARF2_CIE_DATA_ALIGNMENT): Define.
+ (ppc_cfi_frame_initial_instructions, tc_ppc_regname_to_dw2regnum): New
+ prototypes.
+ (ppc_cie_data_alignment): Declare.
+ * config/tc-ppc.c: Include dw2gencfi.h.
+ (ppc_cie_data_alignment): Define.
+ (md_begin): Initialize ppc_cie_data_alignment.
+ (ppc_cfi_frame_initial_instructions, tc_ppc_regname_to_dw2regnum): New
+ functions.
+ * config/tc-s390.h (DWARF2_LINE_MIN_INSN_LENGTH): Define always.
+ (TARGET_USE_CFIPOP, tc_cfi_frame_initial_instructions,
+ tc_regname_to_dw2regnum, DWARF2_DEFAULT_RETURN_COLUMN,
+ DWARF2_CIE_DATA_ALIGNMENT): Define.
+ (s390_cfi_frame_initial_instructions, tc_s390_regname_to_dw2regnum):
+ New prototypes.
+ (s390_cie_data_alignment): Declare.
+ * config/tc-s390.c: Include dw2gencfi.h.
+ (s390_cie_data_alignment): Define.
+ (md_begin): Initialize s390_cie_data_alignment.
+ (s390_cfi_frame_initial_instructions, tc_s390_regname_to_dw2regnum):
+ New functions.
+
+2003-07-10 Alexandre Oliva <aoliva@redhat.com>
+
+ 2002-12-12 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-mn10300.h (EXTERN_FORCE_RELOC): Don't define to zero.
+ 2001-05-09 Alexandre Oliva <aoliva@redhat.com>
+ * configure.in (am33_2.0, mn10300-*-linux*): Added.
+ * configure: Rebuilt.
+ * config/tc-mn10300.h (TARGET_FORMAT) [TE_LINUX]: Define to
+ elf32-am33lin.
+ * config/tc-mn10300.c (md_begin) [TE_LINUX]: Choose AM33/2.0
+ by default.
+
+2003-07-09 Alexandre Oliva <aoliva@redhat.com>
+
+ 2003-02-25 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-mn10300.c (mn10300_check_fixup): Set GOT_PCREL type
+ for subtracts from GLOBAL_OFFSET_TABLE that could not be
+ simplified.
+ 2002-07-18 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-mn10300.c (mn10300_check_fixup): Accept subtracts that
+ could not be simplified.
+ (tc_gen_reloc): Turn an absolute fx_subsy into part of fx_offset.
+ 2001-11-04 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-mn10300.h (TC_RELOC_RTSYM_LOC_FIXUP): Don't adjust
+ BDF_RELOC_MN10300_GOT32.
+ * config/tc-mn10300.c (mn10300_fix_adjustable): If
+ TC_RELOC_RTSYM_LOC_FIXUP doesn't hold, it's not adjustable.
+ 2001-05-09 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-mn10300.c (mn10300_parse_name): Don't return a
+ symbol if we know its value.
+ 2001-05-09 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-mn10300.h (GLOBAL_OFFSET_TABLE_NAME): Remove
+ duplicate underscore prefix.
+ 2001-05-09 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-mn10300.c (mn10300_parse_name): Store relocation
+ type in X_md, not X_add_number. Zero X_add_number.
+ (mn10300_check_fixup): Extract relocation type from X_md.
+ * config/tc-mn10300.h: Update comment.
+ 2001-04-14 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-mn10300.h (O_GOTOFF, O_PLT, O_GOT): Replace with...
+ (O_PIC_reloc): this.
+ * config/tc-mn10300.c (mn10300_PIC_related_p): Use it.
+ (mn10300_check_fixup): Likewise.
+ (mn10300_parse_name): Set X_add_number to relocation type.
+ * config/tc-mn10300.h (DIFF_EXPR_OK, GLOBAL_OFFSET_TABLE_NAME,
+ TC_RELOC_RTSYM_LOC_FIXUP, md_parse_name, TC_CONS_FIX_NEW,
+ O_GOTOFF, O_PLT, O_GOT): Define.
+ * config/tc-mn10300.c (mn10300_PIC_related_p): New fn.
+ (mn10300_check_fixup): New fn.
+ (md_assemble): Call it. Check for PIC-related relocs.
+ (mn10300_cons_fix_new): Likewise. New fn.
+ (mn10300_end_of_match): New fn.
+ (mn10300_md_parse_name_cont): New fn.
+
+2003-07-09 Alexandre Oliva <aoliva@redhat.com>
+
+ 2000-05-25 Alexandre Oliva <aoliva@cygnus.com>
+ * config/tc-mn10300.c (mn10300_insert_operand): Negate negative
+ accumulator's shift.
+ 2000-05-08 Alexandre Oliva <aoliva@cygnus.com>
+ * config/tc-mn10300.c (md_relax_table, md_convert_frag,
+ md_assemble, md_estimate_size_before_relax): Handle fbCC.
+ 2000-04-20 Alexandre Oliva <aoliva@cygnus.com>
+ * config/tc-mn10300.c (HAVE_AM33): Redefine in terms of
+ HAVE_AM33_2.
+ 2000-04-03 Alexandre Oliva <aoliva@cygnus.com>
+ * config/tc-mn10300.c (md_pseudo_table): Use AM33_2 constant.
+ (HAVE_AM33): Match AM33_2 too.
+ (HAVE_AM33_2): New macro.
+ (md_assemble): Use it. Match 2.0 registers only if HAVE_AM33_2.
+ 2000-04-01 Alexandre Oliva <aoliva@cygnus.com>
+ * config/tc-mn10300.c (md_pseudo_table): Added `am33_2'.
+ (float_registers, double_registers): New variables.
+ (float_register_name, double_register_name): New functions.
+ (md_assemble): Recognize FP registers. Implement FMT_D3.
+ (mn10300_insert_operand): Support FP registers.
+
+2003-07-08 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (mips_validate_fix): Do not warn about branch
+ target being a global symbol if not compiling SVR4 PIC code.
+
+2003-07-07 Nick Clifton <nickc@redhat.com>
+
+ * doc/c-m32r.texi (M32R-Directives): New node. Document the
+ .high, .shigh and .low directives.
+
+2003-07-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-h8300.c (h8300sxnmode): Add prototype.
+ (DSYMMODE): Remove.
+ (parse_exp): Replace expressionS argument with a h8_op. Parse the
+ operand size as well.
+ (skip_colonthing): Remove unused expression argument. Tighten checks
+ for 2-digit sizes.
+ (colonmod24): Remove.
+ (get_mova_operands): Combine calls to parse_exp and skip_colonthing.
+ (get_operand): Likewise. Use the standard code to read the size of
+ pc-relative operands.
+ (fix_operand_size): Include the size-guessing logic that used to be
+ in colonmod24 and get_operand. Don't apply dd:2 optimizations to
+ offsets with a symbolic component.
+
+2003-07-04 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-i386.c (tc_x86_regname_to_dw2regnum): Use ARRAY_SIZE
+ macro to compute size of selected register name array.
+
+2003-07-01 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.c (md_parse_option): Add cpu type z990.
+ (md_begin): Add minimal cpu type logic for instructions with different
+ binary format depending on the cpu.
+ (md_assemble): Remove check for minimal cpu.
+ (s390_insert_operand): Add support for long displacements.
+ (md_gather_operands): Likewise.
+ (tc_s390_fix_adjustable): Likewise.
+ (tc_s390_force_relocation): Likewise.
+ (md_apply_fix3): Likewise.
+
+2003-06-30 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (s_mipsset): Implement -march= handling
+ differently.
+
+2003-06-30 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c: Convert to ISO C90 prototypes. Remove unnecessary
+ prototypes and casts. Replace PTR with void *. Reformat.
+ * config/tc-mips.h: Likewise.
+
+2003-06-30 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ia64.c (note_register_values): Warning fix.
+ * config/tc-mips.c (append_insn): Likewise.
+
+2003-06-29 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips_set_options,mips_opts): Support for
+ .set arch=FOO.
+ (file_mips_arch): Rename mips_arch.
+ (mips_arch_info,mips_tune_info): Remove.
+ (hilo_interlocks,gpr_interlocks,cop_interlocks): Use mips_opts.arch.
+ (mips_cpu_info_from_arch): New function.
+ (md_begin): Use file_mips_arch.
+ (macro_build,macro,mips_ip): Use mips_opts.arch.
+ (mips_set_architecture): Init file_mips_arch and mips_opts.arch.
+ (mips_after_parse_args): Remove mips_arch_info and mips_tune_info.
+ Use file_mips_arch.
+ (s_mipsset): Support for .set arch=FOO.
+ (mips_cpu_info_table): Fix typo.
+
+2003-06-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/tc-i386.c (md_assemble): Declare "exp" before "if".
+
+2003-06-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-h8300.c (get_specific): Allow ':8' to be used for
+ unsigned 8-bit operands.
+
+2003-06-24 Nick Clifton <nickc@redhat.com>
+
+ * read.c (s_comm): Change error message to assume an unsigned size
+ has been passed to .comm.
+ * config/tc-sparc.c (s_common): Likewise.
+ * write.c (write_contents): Replace 'unsigned long' with
+ 'addressT' and 'long' with offsetT in order to allow computations
+ with very large values to work for 64-bit addressed targets.
+ (relax_and_size_all_segments): Likewise.
+ (relax_frag): Likewise.
+ (relax_segment): Likewise.
+
+2003-06-23 Mark Mitchell <mark@codesourcery.com>
+
+ * config/tc-ppc.c (ppc_cleanup): Use bytes to count APUinfo slots.
+
+2003-06-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ * gas/config/tc-i386.c (md_assemble): Support Intel Precott New
+ Instructions.
+
+ * gas/config/tc-i386.h (CpuPNI): New.
+ (CpuUnknownFlags): Add CpuPNI.
+
+2003-06-23 <davidm@hpl.hp.com>
+
+ * config/tc-ia64.c (pseudo_func): Add ABI constants for linux,
+ freebsd, openvms, and nsk (non-stop kernel).
+
+2003-06-22 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/tc-ns32k.c (md_begin): Initialize inst_hash_table after
+ all locals have been declared.
+
+2003-06-21 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (ADDRESS_ADD_INSN,ADDRESS_ADDI_INSN): Remove
+ special handling for n32 ABI.
+ (macro): Likewise.
+
+2003-06-19 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (s_cpsetup,s_cprestore,s_cpreturn): Revert
+ 2003-06-11 change.
+
+2003-06-19 Christian Groessler <chris@groessler.org>
+
+ * config/tc-z8k.c (parse_reg): Invalid registers generate an error
+ now, not only a warning. Add some more checks to detect invalid
+ registers.
+ (get_operand): For CLASS_IR remember register size in mode struct.
+ (get_specific): Handle new CLASS_IRO type. Add register size
+ checks for CLASS_IR and CLASS_IRO.
+ (md_apply_fix3): Fix undefined usage of buf.
+
+2003-06-19 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (ppc_csect): Pass alignment to ppc_change_csect.
+ (ppc_change_csect): Add align param. Align frag at start of csect.
+ (ppc_section, ppc_named_section): Adjust ppc_change_csect calls.
+ (ppc_frob_section): Align vma.
+
+2003-06-18 Jakub Jelinek <jakub@redhat.com>
+
+ * dw2gencfi.c (EH_FRAME_ALIGNMENT): Define if not defined.
+ (output_cie): Don't pad.
+ (output_fde): Add align argument. Pad to align if not 0.
+ (cfi_finish): Set .eh_frame alignment to EH_FRAME_ALIGNMENT.
+ Pad just last FDE to EH_FRAME_ALIGNMENT.
+
+2003-06-18 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.c (init_default_arch): Make current_mode_mask
+ dependent on s390_arch_size and current_cpu dependent on
+ current_mode_mask.
+
+2003-06-18 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * configure.in: Add c4x as an architecture variant to tic4x.
+ * configure: Regenerate.
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+
+2003-06-18 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Don't remove symbols other than
+ ".TOC." from PPC64_TOC relocs.
+
+2003-06-17 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (md_apply_fix3): Allow BRTAKEN, BRNTAKEN relocs.
+
+2003-06-16 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (ADDRESS_ADD_INSN,ADDRESS_ADDI_INSN,
+ ADDRESS_LOAD_INSN,ADDRESS_STORE_INSN): New macros.
+ (macro_build_ldst_constoffset,load_address,macro,s_cpsetup,
+ s_cprestore,s_cpadd): Use them.
+
+2003-06-16 Hans-Peter Nilsson <hp@axis.com>
+
+ * configure.in: Add specific case for cris-*-linux-gnu* with
+ em=linux.
+ * configure: Regenerate.
+ * config/tc-cris.c (DEFAULT_CRIS_AXIS_LINUX_GNU): New macro, TRUE
+ if TE_LINUX defined, else FALSE.
+ (bfd_boolean demand_register_prefix): Set default from
+ DEFAULT_CRIS_AXIS_LINUX_GNU.
+ (symbols_have_leading_underscore): Similar.
+ * config/tc-cris.h (LOCAL_LABELS_DOLLAR): Define to 1.
+
+2003-06-13 Richard Earnshaw <rearnsha@arm.com>
+
+ * tc-arm.c (FPU_DEFAULT, case TE_LINUX): Default to FPU_ARCH_FPA.
+ (FPU_DEFAULT, case TE_NetBSD): Default to FPU_ARCH_VFP for ELF,
+ FPU_ARCH_FPA for AOUT.
+ (md_begin): Don't try to guess the floating point architecture from
+ the CPU if the OS ABI (Linux, NetBSD) mandates a particular form.
+
+2003-06-13 Robert Millan <zeratul2@wanadoo.es>
+
+ * configure.in: Add i386-netbsd-gnu target.
+ * configure: Regenerate.
+
+2003-06-12 Tom Tromey <tromey@redhat.com>
+
+ * doc/as.texinfo (Comm): Added @node. Moved before CFI
+ directives node.
+
+2003-06-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (append_insn): In a compound relocation, take the
+ field width from the final (outermost) operator.
+
+2003-06-11 Richard Henderson <rth@redhat.com>
+
+ * dw2gencfi.c (struct cfi_escape_data): New.
+ (cfi_add_CFA_nop): Remove.
+ (CFI_escape, dot_cfi_escape): New.
+ (dot_cfi): Remove nop.
+ (cfi_pseudo_table): Remove nop; add escape.
+ (output_cfi_insn): Likewise.
+ (select_cie_for_fde): Stop on escape.
+ * dw2gencfi.h (cfi_add_CFA_nop): Remove.
+ * read.c, read.h (do_parse_cons_expression): New.
+ * doc/as.texinfo (.cfi_escape): New.
+
+2003-06-11 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (s_cpsetup): Use mips_frame_reg instead of SP.
+ (s_cprestore): Likewise.
+ (s_cpreturn): Likewise.
+
+2003-06-11 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (tc_gen_reloc): Initialize retval amd reloc
+ with zeros.
+
+2003-06-11 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (md_pcrel_from): Return actual pcrel address.
+ (md_apply_fix3): Ignore non-special relocations. Remove superfluous
+ exceptions from size assert. Remove most of the addend fixup
+ specialcasing. Remove value, use valP directly. simplify fx_addnumber
+ handling. Remove zero addend specialcases.
+ (tc_gen_reloc): Use appropriate value for reloc2 addend. Remove
+ the addend fixup specialcase.
+ * config/tc-mips.h (MD_APPLY_SYM_VALUE): Define as 0.
+
+2003-06-11 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * write.c (write_relocs): Use xcalloc. Fix relocs initialization
+ in the RELOC_EXPANSION_POSSIBLE case.
+
+2003-06-11 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i960.c (line_comment_chars): Add '#'.
+ * config/tc-mn10200.c (tc_gen_reloc): Don't ignore fx_subsy.
+
+2003-06-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ * po/Make-in (DESTDIR): New.
+ (install-data-yes): Support $(DESTDIR).
+ (uninstall): Likewise.
+
+2003-06-11 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * po/POTFILES.in: Regenerate.
+
+2003-06-10 Doug Evans <dje@sebabeach.org>
+
+ * cgen.c (gas_cgen_finish_insn): CGEN_INSN_RELAX renamed to
+ CGEN_INSN_RELAXED.
+ * config/tc-fr30.c (md_estimate_size_before_relax): Ditto.
+ * config/tc-m32r.c (md_estimate_size_before_relax): Ditto.
+ * config/tc-openrisc.c (md_estimate_size_before_relax): Ditto.
+
+2003-06-10 Alan Modra <amodra@bigpond.net.au>
+ Gary Hade <garyhade@us.ibm.com>
+
+ * config/tc-ppc.c (md_assemble): Handle PPC_OPERAND_DQ.
+ (md_apply_fix3): Special case lq insn.
+
+2003-06-10 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-h8300.c (get_rtsl_operands): Accept unbracketed register
+ lists. Allow single-register ranges.
+
+2003-06-10 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-h8300.c (h8300sxnmode): New.
+ (md_pseudo_table): Add .h8300sxn entry.
+
+2003-06-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ * NEWS: Updated for the new -n option for the i386 assembler.
+
+ * config/tc-i386.c (optimize_align_code): New.
+ (md_shortopts): Add 'n'.
+ (md_parse_option): Handle 'n'.
+ (md_show_usage): Add '-n'.
+
+ * config/tc-i386.h (optimize_align_code): Declared.
+ (md_do_align): Optimize code alignment only if optimize_align_code
+ is not 0.
+
+ * doc/as.texinfo: Add the new -n option.
+
+ * doc/c-i386.texi: Document the new -n option.
+
+2003-06-07 Richard Henderson <rth@redhat.com>
+
+ * doc/as.texinfo: Document .cfi_rel_offset.
+
+ * dw2gencfi.c (struct cfa_save_data, cfa_save_stack): New.
+ (cfi_add_CFA_offset): Detect invalid offsets.
+ (cfi_add_CFA_remember_state): Save cur_cfa_offset.
+ (cfi_add_CFA_restore_state): Restore it.
+ (CFI_rel_offset): New.
+ (cfi_pseudo_table): Add it.
+ (dot_cfi): Handle it.
+
+2003-06-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * app.c (do_scrub_chars): Add states 14 and 15 to handle
+ predicate for ia64.
+
+2003-06-05 Michael Snyder <msnyder@redhat.com>
+
+ * config/tc-h8sx.c (get_specific): Distinguish h8h from h8s ops.
+ (build_bytes): Ditto.
+
+2003-06-05 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-h8sx.c (DMODE): Remove.
+ (colonmod24): Don't choose a default if the operand is a 16-bit
+ constant integer.
+ (fix_operand_size): New function.
+ (md_assemble): Use it to choose between @(d:2, ERn) and @(d:16,ERn).
+ Adjust @(d:2,ERn) operands before choosing the specific opcodes.
+
+2003-06-05 Michal Ludvig <mludvig@suse.cz>
+
+ * dw2gencfi.c (cfi_add_CFA_insn, cfi_add_CFA_insn_reg)
+ (cfi_add_CFA_insn_reg_reg, cfi_add_CFA_insn_reg_offset): New.
+ (cfi_add_CFA_offset, cfi_add_CFA_def_cfa)
+ (cfi_add_CFA_register, cfi_add_CFA_def_cfa_register)
+ (cfi_add_CFA_def_cfa_offset): Use cfi_add_CFA_insn_*().
+ (cfi_add_CFA_restore, cfi_add_CFA_undefined)
+ (cfi_add_CFA_same_value, cfi_add_CFA_remember_state)
+ (cfi_add_CFA_restore_state, cfi_add_CFA_nop): New.
+ (cfi_pseudo_table): New directives .cfi_return_column,
+ .cfi_restore, .cfi_undefined, .cfi_same_value,
+ .cfi_remember_state, .cfi_restore_state, .cfi_nop.
+ (dot_cfi, output_cfi_insn): Handle new directives.
+ * dw2gencfi.h (cfi_add_CFA_restore, cfi_add_CFA_undefined)
+ (cfi_add_CFA_same_value, cfi_add_CFA_remember_state)
+ (cfi_add_CFA_restore_state, cfi_add_CFA_nop): New prototypes.
+
+2003-06-04 Richard Henderson <rth@redhat.com>
+
+ * dw2gencfi.c (output_cfi_insn): Fix typo for negative offsets.
+
+ * dw2gencfi.c (cfi_finish): Set .eh_frame read-only.
+
+2003-06-04 Richard Henderson <rth@redhat.com>
+
+ * config/tc-alpha.c (s_alpha_usepv): New.
+ (md_pseudo_table): Add it.
+ (alpha_cfi_frame_initial_instructions): New.
+ * config/tc-alpha.h (TARGET_USE_CFIPOP): New.
+ (tc_cfi_frame_initial_instructions): New.
+ * doc/c-alpha.texi: Document .usepv.
+
+2003-06-04 Jakub Jelinek <jakub@redhat.com>
+
+ * as.c (show_usage): Document --execstack and --noexecstack.
+ (parse_args): Add --execstack and --noexecstack.
+ (main): Create .note.GNU-stack section if --execstack or
+ --noexecstack was given on comand line, set its SHF_EXECINSTR bit.
+ * as.h (flag_execstack, flag_noexecstack): New.
+
+2003-06-03 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c: (OPTION_ARCH_BASE, OPTION_ASE_BASE)
+ (OPTION_COMPAT_ARCH_BASE, OPTION_FIX_BASE)
+ (OPTION_MISC_BASE): New defines.
+ (OPTION_BREAK, OPTION_CONSTRUCT_FLOATS, OPTION_EB, OPTION_EL)
+ (OPTION_ELF_BASE, OPTION_FIX_VR4122, OPTION_FP32, OPTION_FP64)
+ (OPTION_GP32, OPTION_GP64, OPTION_M3900, OPTION_M4010, OPTION_M4100)
+ (OPTION_M4650, OPTION_M7000_HILO_FIX, OPTION_MARCH, OPTION_MDMX)
+ (OPTION_MEMBEDDED_PIC, OPTION_MIPS1, OPTION_MIPS16, OPTION_MIPS2)
+ (OPTION_MIPS3, OPTION_MIPS32, OPTION_MIPS32R2, OPTION_MIPS3D)
+ (OPTION_MIPS4, OPTION_MIPS5, OPTION_MIPS64)
+ (OPTION_MNO_7000_HILO_FIX, OPTION_MTUNE, OPTION_NO_CONSTRUCT_FLOATS)
+ (OPTION_NO_FIX_VR4122, OPTION_NO_M3900, OPTION_NO_M4010)
+ (OPTION_NO_M4100, OPTION_NO_M4650, OPTION_NO_MDMX, OPTION_NO_MIPS16)
+ (OPTION_NO_MIPS3D, OPTION_NO_RELAX_BRANCH, OPTION_RELAX_BRANCH)
+ (OPTION_TRAP): Redefine in terms of new defines.
+ (md_longopts): Reorder entries.
+
+2003-05-14 Michael Snyder <msnyder@redhat.com>
+ From Bernd Schmidt <bernds@redhat.com>
+ and Michael Snyder <msnyder@redhat.com>
+ and Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-h8300.c: Add insns and addressing modes for h8300sx.
+ * config/tc-h8300.h: Ditto.
+
+2003-06-03 Nick Clifton <nickc@redhat.com>
+
+ * tc-v850.c (tc-gen_reloc): Translate BFD_RELOC_32 into
+ BFD_RELOC_32_PCREL if the reloc is pc-relative. Do this
+ before calling bfd_reloc_type_lookup.
+
+2003-06-02 Alan Modra <amodra@bigpond.net.au>
+
+ * read.c (emit_expr): Set dot_value.
+ * dw2gencfi.c (output_fde): Remove pcrel reloc hack.
+
+2003-06-02 Alan Modra <amodra@bigpond.net.au>
+
+ * macro.c (sub_actual): Don't lose string if it turns out that
+ &string wasn't an arg.
+
+2003-05-31 Richard Henderson <rth@redhat.com>
+
+ * dw2gencfi.c (output_fde): Use fix_new to emit pc-relative reloc.
+ (cfi_finish): Set flag_traditional_format around .eh_frame data.
+
+2003-05-29 Richard Henderson <rth@redhat.com>
+
+ * config/tc-alpha.c (alpha_cur_ent_sym): Remove.
+ (all_frame_data, plast_frame_data, cur_frame_data): New.
+ (s_alpha_ent): Record data for dwarf2 cfi.
+ (s_alpha_end, s_alpha_mask, s_alpha_frame, s_alpha_prologue): Likewise.
+ (alpha_elf_md_end): Emit dwarf2 cfi for ecoff unwind directives.
+ * config/tc-alpha.h (md_end): New.
+ (DWARF2_DEFAULT_RETURN_COLUMN): New.
+ (DWARF2_CIE_DATA_ALIGNMENT): New.
+
+2003-05-29 Nick Clifton <nickc@redhat.com>
+
+ * configure.in: Add i386-*-freebsd* entry.
+ * configure: Regenerate.
+
+2003-05-29 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * config/tc-m32r.c: Amend comment to refer to Renesas
+
+2003-05-27 Richard Henderson <rth@redhat.com>
+
+ * expr.c (make_expr_symbol): Fold FAKE_LABEL_NAME use into the
+ symbol_create call.
+ (current_location): Use symbol_temp_new_now.
+ * stabs.c (s_stab_generic): Use symbol_temp_new.
+ * symbols.c (temp_label_name): Remove.
+ (symbol_temp_new, symbol_temp_make): Use FAKE_LABEL_NAME.
+
+2003-05-27 Richard Henderson <rth@redhat.com>
+
+ * dw2gencfi.c, dw2gencfi.h: Rewrite from scratch.
+ * as.c (main): Always call cfi_finish.
+ * config/tc-i386.c (x86_dwarf2_return_column): New.
+ (x86_cie_data_alignment): New.
+ (md_begin): Set them.
+ (tc_x86_cfi_init): Remove.
+ (tc_x86_regname_to_dw2regnum): Fix 32-bit register numbers;
+ return int, not unsigned long; don't as_bad here.
+ (tc_x86_frame_initial_instructions): Streamline; use
+ updated api.
+ * config/tc-i386.h (tc_cfi_init): Remove.
+ (DWARF2_DEFAULT_RETURN_COLUMN): New.
+ (DWARF2_CIE_DATA_ALIGNMENT): New.
+
+2003-05-27 Richard Henderson <rth@redhat.com>
+
+ * symbols.c (temp_label_name): New.
+ (symbol_temp_new, symbol_temp_new_now, symbol_temp_make): New.
+ (symbol_set_value_now): New.
+ * symbols.h: Prototype them.
+ * dwarf2dbg.c: Use them.
+ (fake_label_name, symbol_new_now, set_symbol_value_now): Remove.
+
+2003-05-23 Jason Eckhardt <jle@rice.edu>
+
+ * config/tc-i860.c (target_xp): Declare variable.
+ (OPTION_XP): Declare macro.
+ (md_longopts): Add option -mxp.
+ (md_parse_option): Set target_xp.
+ (md_show_usage): Add -mxp usage.
+ (i860_process_insn): Recognize XP registers bear, ccr, p0-p3.
+ (md_assemble): Don't try expansions if XP_ONLY is set.
+ * doc/c-i860.texi: Document -mxp option and i860XP support.
+
+2003-05-23 Eric Christopher <echristo@redhat.com>
+
+ * config/tc-mips.c (macro_build_jalr): Warning patrol.
+
+2003-05-22 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (append_insn): Use actual relocation size for new
+ fixp's. Don't relax overflow checking for partial_inplace relocations.
+ Use the actual relocation type in combined relocs, not just the type
+ of the first one.
+ (macro_build_jalr): Use actual relocation size for new fix.
+ (s_cpsetup, s_gpdword): Likewise.
+
+2003-05-22 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (macro): Don't use uninitialized tempreg.
+
+2003-05-22 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-xstormy16.c (md_pcrel_from_section): Do not produce
+ section relative offsets for relocs that will not be based on the
+ section symbol.
+ (xstormy16_md_apply_fix3): Remove previous patch to this
+ function.
+
+2003-05-07 Eric Christopher <echristo@redhat.com>
+
+ * config/tc-mips.c (mips_abicalls): New variable.
+ (md_parse_option): Use.
+ (s_option): Ditto.
+ (s_abicalls): Ditto.
+ (mips_elf_final_processing): Set EF_MIPS_PIC and
+ EF_MIPS_CPIC dependent on above.
+
+2003-05-21 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * tc-hppa.c (hppa_symbol_chars): Remove `,' and `!'.
+
+2003-05-21 Nick Clifton <nickc@redhat.com>
+
+ * config/obj-elf.c: Include dwarf2dbg.h.
+ (elf_pseudo_tab): Add .file and .loc.
+ * config/tc-arc.c (md_pseudo_table): Remove .file and .loc.
+ * config/tc-arm.c: Likewise.
+ * config/tc-h8300.c: Likewise.
+ * config/tc-hppa.c: Likewise.
+ * config/tc-ia64.c: Likewise.
+ * config/tc-m68hc11.c: Likewise.
+ * config/tc-m68k.c: Likewise.
+ * config/tc-mmix.c: Likewise.
+ * config/tc-mn10300.c: Likewise.
+ * config/tc-ppc.c: Likewise.
+ * config/tc-sh.c: Likewise.
+ * config/tc-sparc.c: Likewise.
+ * config/tc-v850.c: Likewise.
+ * config/tc-frv.c: Likewise, and remove redundant inclusion of
+ dwarf2dbg.h.
+ * config/tc-ip2k.c: Likewise.
+ * config/tc-iq2000.c: Likewise.
+ * config/tc-xstormy16.c: Likewise.
+ * config/tc-xtensa.c: Likewise.
+ * Makefile.am: Regenerate dependencies.
+ * Makefile.in: Regenerate.
+ * aclocal.m4: Regenerate.
+ * config.in: Regenerate.
+ * configure: Regenerate.
+ * po/POTFILES.in: Regenerate.
+ * po/gas.pot: Regenerate.
+
+2003-05-21 Nick Clifton <nickc@redhat.com>
+
+ * dw2gencfi.c (cfi_get_label): Use symbol_make for non
+ BFD_ASSEMBLER targets.
+ (cfi_startproc): Change type of saved_seg and cfi_seg to segT.
+ (dot_cfi_endproc): Only call bfd_set_section_flags for targets
+ defining BFD_ASSEMBLER.
+
+2003-05-20 Michal Ludvig <mludvig@suse.cz>
+
+ * as.c (main): Remove tc_cfi_init().
+ * dw2gencfi.c (cfi_parse_arg): Allow regnames beginning
+ with '%'.
+ (cfi_pseudo_table): Add "cfi_register" entry.
+ (cfi_make_insn): Handle CFA_register.
+ (cfi_output_insn): Ditto.
+ (dot_cfi): Ditto.
+ (cfi_get_label): Add 'simple' modifier to .cfi_startproc.
+ (dot_cfi_endproc): Reuse already emitted CIEs.
+ * testsuite/gas/cfi/cfi-i386.d: New pattern.
+ * testsuite/gas/cfi/cfi-x86-64.d: Ditto.
+
+2003-05-20 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-xstormy16.c: Include dwarf2dbg.h.
+ (md_pseudo_table): Add entries for .loc and .line.
+
+2003-05-20 Alan Modra <amodra@bigpond.net.au>
+
+ * dw2gencfi.c (cfi_parse_arg): Only use tc_regname_to_dw2regnum if
+ defined.
+ (dot_cfi_endproc): Avoid C99 construct.
+
+2003-05-20 Michal Ludvig <mludvig@suse.cz>
+
+ * dw2gencfi.c, dw2gencfi.h: New files.
+ * config/tc-i386.c (tc_x86_cfi_init): New function.
+ * config/tc-i386.h (TARGET_USE_CFIPOP, tc_cfi_init): New defines.
+ * as.c (parse_args): Set verbose flag on --verbose.
+ (main): Call tc_cfi_init()/cfi_finish().
+ * as.h (verbose): New external variable.
+ * read.c (pobegin): Insert CFI pops to the list.
+ * symbols.c (local_symbol_make): Make symbol external.
+ * symbols.h (local_symbol_make): New prototype.
+ * Makefile.am: Add dw2gencfi.[ch] files. Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * doc/as.texinfo: Added node "CFI directives" with description of
+ all implemented .cfi_* directives.
+ * doc/Makefile.in: Regenerate.
+ * po/POTFILES.in: Regenerate.
+
+2003-05-19 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * config/tc-tic4x.c (md_assemble): Added support for one-line parallel
+ insns.
+ * config/tc-tic4x.h: Added DOUBLEBAR_PARALLEL definition
+
+2003-05-18 Jason Eckhardt <jle@rice.edu>
+
+ * config/tc-i860.c (i860_process_insn): Initialize fc after
+ each opcode mismatch.
+
+2003-05-16 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * configure.in: Accept i[3-7]86 variants.
+ * configure: Regenerate.
+
+2003-05-15 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.h: Fix comment formatting.
+
+2003-05-13 Hans-Peter Nilsson <hp@axis.com>
+
+ * read.c (old_buffer, old_input, old_limit): Remove variables.
+ (read_a_source_file): Delete label contin.
+ <handling #APP/#NO_APP>: Use an "sb" to push #APP expansion into
+ input as with macros, instead of in separate old_* variables.
+ Zero-terminate string being scrubbed.
+
+2003-05-12 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-xstormy16.c (skipping_fptr): New local variable.
+ (md_assemble): Reset skipping_fptr.
+ (md_operand): If @fptr() is followed by a minus sign, set
+ skipping_fptr and ignore the fptr. If skipping_fptr is set and an
+ @fptr is detected, ignore it and reset skipping_fptr.
+
+2003-05-11 Jason Eckhardt <jle@rice.edu>
+
+ * config/tc-i860.c (MAX_FIXUPS): Define.
+ (struct i860_fi fi[]): New struct.
+ (struct i860_it the_insn): Add above as member and move fields
+ exp, reloc, pcrel and fup into i860_fi.
+ (md_assemble): Replace all instances of exp, reloc, pcrel
+ and fup with fi[].exp, fi[].reloc, fi[].pcrel, fi[].fup.
+ Add a loop to possibly emit multiple fix-ups for each insn.
+ (i860_process_insn): Likewise.
+ (i860_get_expression): Likewise.
+ (md_apply_fix3): Use a bitwise check for OP_IMM_U5, not equality.
+
+2003-05-09 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.c (s390_target_format): Always call init_default_arch.
+
+2003-05-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/tc-ia64.c (alias_hash): New.
+ (alias_name_hash): New.
+ (secalias_hash): New.
+ (secalias_name_hash): New.
+ (md_pseudo_table): Add "secalias".
+ (md_begin): Initialize alias_hash, alias_name_hash,
+ secalias_hash and secalias_name_hash.
+ (struct alias): New.
+ (dot_alias): Implement .alias and .secalias directives.
+ (do_alias): New.
+ (ia64_adjust_symtab): New.
+ (do_secalias): New.
+ (ia64_frob_file): New.
+
+ * config/tc-ia64.h (ia64_adjust_symtab): New.
+ (tc_adjust_symtab): Defined.
+ (ia64_frob_file): New.
+ (tc_frob_file): Defined.
+
+2003-05-07 Dmitry Diky <diwil@mail.ru>
+
+ * tc-msp430.c: Add missing lines to known cpus list.
+
+2003-05-06 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure.in (MIPS_DEFAULT_ABI): AC_DEFINE.
+ * config/tc-mips.c (mips_after_parse_args): Set mips_abi to it.
+ * config.in, configure: Rebuilt.
+
+2003-05-05 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-mips.c (tc_gen_reloc): Add addend just once if
+ howto->partial_inplace is false.
+
+2003-05-05 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/tc-mips.c (mips_need_elf_addend_fixup): Remove
+ symbol_used_in_reloc_p check.
+ (md_apply_fix3): Remove check for howto->pcrel_offset.
+
+2003-05-03 H.J. Lu <hjl@gnu.org>
+
+ * config/obj-elf.c (obj_elf_parse_section_letters): Make it a
+ fatal error for unknown section attribute.
+
+ * config/tc-alpha.c (alpha_elf_section_letter): Return -1 for
+ unknown section attribute.
+ * config/tc-ia64.c (ia64_elf_section_letter): Likewise.
+ * config/tc-ppc.c (ppc_section_letter): Likewise.
+
+ * config/tc-ia64.c (ia64_elf_section_letter): Handle 'o'.
+ (ia64_elf_section_type): Accept "unwind".
+
+2003-05-02 H.J. Lu <hjl@gnu.org>
+
+ * read.h (demand_copy_string): New.
+
+ * config/tc-alpha.c (demand_copy_string): Removed.
+
+2003-05-02 Michael Snyder <msnyder@redhat.com>
+
+ * write.h (FAKE_LABEL_NAME): Allow override
+ (for targets that like eg. a leading dot in a local label).
+
+2003-05-02 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-xstormy16.c (xstormy16_md_apply_fix3): Do not bias the
+ addend with the symbol's value for pc-relative relocations against
+ a defined symbol - this will be done automatically.
+
+2003-05-01 H.J. Lu <hjl@gnu.org>
+
+ * config/obj-elf.c (obj_elf_type): Accept "notype" and
+ "STT_NOTYPE".
+
+2003-05-01 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-ia64.h (tc_canonicalize_section_name): New.
+
+ * config/obj-elf.c (obj_elf_section_name): Call
+ tc_canonicalize_section_name if it is defined.
+
+2003-05-01 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-ia64.c (ia64_check_label): New.
+ * config/tc-ia64.h (tc_check_label): New.
+
+ * read.c (read_a_source_file): Call tc_check_label after
+ creating a user-defined label if defined.
+
+2003-05-02 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (md_show_usage): Mention -a32, -a64, -l, -le, -b,
+ -be and split strings to below 509 bytes in length.
+
+2003-05-01 Christian Groessler <chris@groessler.org>
+
+ * expr.h: Fix comments in operatorT typedef.
+ * config/tc-z8k.c: Add 2003 to copyright message.
+ Fold s_segm() and s_unseg() into one function s_segm(parm) which
+ decides by the parameter.
+ (md_begin): Don't set linkrelax. Only set Z8002 default if no
+ command line argument was given to select the intended
+ architecure.
+ (get_interrupt_operand): Warn if NOP type code is emitted.
+ (newfix): New parameter 'size', forward it to 'fix_new_exp'.
+ (apply_fix): Call newfix with additional 'size' parameter.
+ (build_bytes): Remove unused variable 'nib'. Detect overflow in
+ 4 bit immediate arguments.
+ (md_longopts): Add 'linkrelax' option.
+ (md_parse_option): Adapt to new s_segm function. Set 'linkrelax'
+ variable when 'linkrelax' command line option is specified.
+ (md_show_usage): Display 'linkrelax' option.
+ (md_apply_fix3): Fix cases R_IMM4L, R_JR, and R_IMM8. Add cases
+ R_CALLR and R_REL16.
+ * config/tc-z8k.h: Undef WARN_SIGNED_OVERFLOW_WORD.
+
+2003-04-30 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-ia64.c (ia64_number_to_chars): New function pointer.
+ (ia64_float_to_chars): Likewise.
+ (dot_byteorder): Set target_big_endian, ia64_number_to_chars
+ and ia64_float_to_chars by tc_segment_info_data.endian from
+ the current segment if byteorder == -1.
+ (md_begin): Call dot_byteorder to set target_big_endian.
+ (md_atof): Call ia64_float_to_chars to convert floating point.
+ (ia64_float_to_chars_bigendian): New function.
+ (ia64_float_to_chars_littleendian): Likewise.
+ (ia64_elf_section_change_hook): Likewise.
+
+ * config/tc-ia64.h (ia64_number_to_chars): New.
+ (md_number_to_chars): Changed to (*ia64_number_to_chars)
+ (ia64_elf_section_change_hook): New.
+ (md_elf_section_change_hook): Defined.
+ (ia64_segment_info_type): New struct.
+ (TC_SEGMENT_INFO_TYPE): Defined.
+
+2003-04-30 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-ia64.c (md_section_align): Deleted.
+
+ * config/tc-ia64.h (SUB_SEGMENT_ALIGN): New.
+ (md_section_align): New.
+
+2003-04-30 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-ia64.c (stmt_float_cons): Fix alignment for real10
+ and add real16.
+ (md_pseudo_table): Add "xreal16", "xreal16.ua", "real16" and
+ "real16.ua".
+ (md_atof): Add 6 byte padding of zero for real16.
+
+2003-04-29 Nick Clifton <nickc@redhat.com>
+
+ * config/obj-elf.c (obj_elf_symver): Skip whitespace before the
+ start of a version name.
+
+2003-04-28 Chris Demetriou <cgd@broadcom.com>
+
+ * configure.in (mips-*-*n*bsd*): Replace with...
+ (mips-*-netbsd*, mips-*-openbsd*): These.
+ * configure: Regenerate.
+
+2003-04-28 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-hppa.c (hppa_symbol_chars): New.
+ * config/tc-hppa.h (tc_symbol_chars): Likewise.
+
+2003-04-26 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.h (TC_FORCE_RELOCATION_SUB_SAME): Define again.
+
+2003-04-25 Chris Demetriou <cgd@broadcom.com>
+
+ * NEWS: Belatedly mention support for MIPS32 Release 2.
+
+2003-04-24 Eric Christopher <echristo@redhat.com>
+
+ * config/tc-mips.c (nopic_need_relax): Revert previous
+ change.
+
+2003-04-24 Dhananjay Deshpande <dhananjayd@kpitcummins.com>
+
+ * config/tc-h8300.h (DWARF2_LINE_MIN_INSN_LENGTH): New
+ * config/tc-h8300.c (dwarf2dbg.h): Include
+ (md_pseudo_table): Handle .loc and .file
+ (md_assemble): Call dwarf2_emit_insn if BFD_ASSEMBLER.
+ * Makefile.am: Add dependency on dwarf2dbg.h for h8300 targets.
+ * Makefile.in: Regenerate.
+
+2003-04-24 Dhananjay Deshpande <dhananjayd@kpitcummins.com>
+
+ * config/tc-h8300.c (Nmode, h8300hnmode, h8300snmode): New.
+ (md_pseudo_table): Add h8300hn, h8300sn.
+ * config/tc-h8300.h (COFF_MAGIC): Handle h8300hn, h8300sn.
+ * doc/c-h8300.texi : Add documentation for new machine directives.
+
+2003-04-24 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-ppc.c (ppc_symbol_chars): Define.
+ * config/tc-ppc.h (tc_symbol_chars): Define.
+
+2003-04-23 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config/tc-sh.c: Amend comment to refer to SuperH.
+ * config/tc-sh.h: Likewise.
+ (LISTING_HEADER): Amend to refer to SuperH.
+ * config/tc-sh64.c: Change comment to refer to SuperH.
+ * config/tc-sh64.h (LISTING_HEADER): Change to refer to SuperH.
+ * doc/as.texinfo [SH, GENERIC]: Amend / Change to refer to SuperH.
+ * doc/c-sh.texi: Amend to refer to SuperH.
+ Add SuperH architecture documentation references.
+ * doc/c-sh64.texi: Change to refer to SuperH.
+
+2003-04-23 H.J. Lu <hjl@gnu.org>
+
+ * app.c (do_scrub_chars): More checks for valid labels.
+
+2003-04-22 H.J. Lu <hjl@gnu.org>
+
+ * app.c (do_scrub_chars): Check for valid label.
+
+2003-04-22 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * doc/as.texinfo: Replace references to Mitsubishi M32R with
+ references to Renesas M32R.
+ * doc/c-m32r.texi: Likewise.
+
+2003-04-21 Richard Henderson <rth@redhat.com>
+
+ * dwarf2dbg.c (get_filenum): Skip as-yet unassigned file numbers.
+ (out_file_list): Assign non-null filename after generating error.
+
+2003-04-18 Jakub Jelinek <jakub@redhat.com>
+
+ * ehopt.c (check_eh_frame): For aug_size == 0
+ in state_seeing_aug_size state skip the state_skipping_aug
+ state.
+
+2003-04-15 Rohit Kumar Srivastava <rohits@kpitcummins.com>
+
+ * doc/c-h8300.texi: Replace occurrances of 'Hitachi' with
+ 'Renesas'.
+ * doc/c-h8500.texi: Likewise.
+ * doc/c-sh.texi: Likewise.
+ * doc/c-sh64.texi: Likewise.
+ * doc/h8.texi: Likewise.
+ * config/tc-h8300.c: Likewise.
+ * config/tc-h8300.h: Likewise.
+ * config/tc-h8500.c: Likewise.
+ * config/tc-h8500.h: Likewise.
+ * config/tc-sh.c: Likewise.
+ * config/tc-sh.h: Likewise.
+ * config/tc-sh64.c: Likewise.
+ * config/tc-sh64.h: Likewise.
+
+2003-04-10 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mips.h (tc_frag_data_type, TC_FRAG_TYPE): New.
+ * config/tc-mips.c: Use signed add for n32 address arithmetic.
+ (append_insn): When filling delay slots with instructions
+ that have fixups that tc_gen_reloc might consider modifyable
+ in variant frags, start a new frag.
+ (load_address): Generate GOT_DISP with of without offset
+ depending on whether symbol is local. For -xgot, use
+ GOT_PAGE/GOT_OFST or GOT_HI16/GOT_LO16.
+ (macro) <M_DLA_AB, M_LA_AB>: Likewise.
+ <M_JAL_A>: In NewABI, use CALL16 or GOT_DISP for small got,
+ CALL_HI16/CALL_LO16 or GOT_PAGE/GOT_OFST for big got.
+ <ld_st>: In NewABI with small got, always use
+ GOT_PAGE/GOT_OFST, with the latter in the load/store
+ instruction. With big got, use GOT_HI16/GOT_LO16 or
+ GOT_PAGE/GOT_OFST.
+ (tc_gen_reloc): Adjust variant frags with GOT_DISP in NewABI.
+ Add tc_frag_data.tc_fr_offset to addends. Decay CALL16,
+ GOT_OFST and GOT_DISP to GOT_DISP in NewABI.
+ (md_convert_frag): Use memmove for safe copying of overlapping
+ regions.
+
+2003-04-09 Stephane Carrez <stcarrez@nerim.fr>
+
+ * doc/c-m68hc11.texi (M68HC11-Opts): Document -m68hcs12, -mshort,
+ -mlong, -mshort-double and -mlong-double options; use table @code.
+ (M68HC11-Syntax): Update to document 68HC12 operands.
+ (M68HC11-Modifiers): New section for operand modifiers.
+ (M68HC11-Directives): New section for specific assembler directives.
+ (M68HC11-Branch): Fix Overfull hbox error.
+
+2003-04-09 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mips.c (macro): Add comments explaining the rationale
+ for Chris' change.
+
+2003-04-09 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (macro): Put back `+ 0x8000' in test for 64-bit
+ constant address that Alexandre took out by accident. Reject
+ 64-bit addresses that are not sign extensions of 32 bits only if
+ we don't support 64-bit address constants.
+
+2003-04-09 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (md_apply_fix3): Generate ADDR16 relocs.
+
+2003-04-08 Nick Clifton <nickc@redhat.com>
+
+ * as.c (perform_an_assembly_pass): If using cgen, call
+ gas_cgen_begin.
+ * cgen.c (gas_cgen_begin): New function. If
+ flag_signed_overflow_ok is set call cgen_set_signed_overflow_ok
+ otherwise call cgen_clear_signed_overflow_ok.
+ * cgen.h: Prototype gas_cgen_begin.
+
+2003-04-07 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * write.c (write_relocs): Remove unused variable.
+
+2003-04-06 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (HAVE_64BIT_ADDRESS_CONSTANTS): New.
+ (macro): Use new macro to decide whether to emit constant address
+ as 32 or 64 bits if addresses are 32-bit wide but registers are
+ 64-bit wide.
+
+2003-04-05 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/tc-m68hc11.c (M6811_OP_CALL_ADDR): New internal define.
+ (M6811_OP_PAGE_ADDR): New internal define.
+ (get_operand): New modifier %page and %addr to obtain page and
+ address part of a far-function.
+ (fixup8): Use BFD_RELOC_M68HC11_PAGE for a %page modifier; don't
+ complain on overflow for the BFD_RELOC_M68HC11_PAGE and truncation
+ relocs.
+ (fixup16): Use BFD_RELOC_M68HC11_LO16 for a %addr modifier.
+ (find_opcode): Add comment.
+ (md_estimate_size_before_relax): Force relocation of
+ STATE_UNDEXED_OFFSET types when the symbol is not absolute.
+ (tc_m68hc11_fix_adjustable): Check for BFD_RELOC_M68HC11_LO16
+ instead of BFD_RELOC_LO16; temporarily make the BFD_RELOC_32
+ on the symbol itself so that DWARF2 strings are merged correctly.
+
+2003-04-04 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * config/obj-coff.h (TARGET_FORMAT): Namespace cleanup, changed
+ default tic4x target format to 'coff2-tic4x'.
+ * config/tc-tic4x.c: Namespace cleanup. Replace s/c4x/tic4x/ and
+ s/c3x/tic3x/
+ * config/tc-tic4x.h: Ditto
+
+2003-04-03 Nick Clifton <nickc@redhat.com>
+
+ * NEWS: Mention support for Xtensa architecture.
+
+2003-04-02 Philip Blundell <philb@gnu.org>
+
+ * config/tc-arm.c (arm_force_relocation): Return 0 for OFFSET_IMM.
+
+2003-04-02 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (macro2): Adjust implementation of
+ M_ULH, M_ULHU, M_ULW, and M_ULD so that they work properly
+ in the case where the source and destination registers
+ are the same.
+
+2003-04-01 Bob Wilson <bob.wilson@acm.org>
+
+ * Makefile.am (CPU_TYPES): Add xtensa.
+ (TARGET_CPU_CFILES): Add config/tc-xtensa.c.
+ (TARGET_CPU_HFILES): Add config/tc-xtensa.h.
+ (xtensa-relax.o): New target.
+ Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * configure.in: Handle xtensa-*-*. Add xtensa-relax.o to
+ extra_objects for xtensa targets.
+ * configure: Regenerate.
+ * write.c (write_object_file): Add new md_post_relax_hook.
+ * config/tc-xtensa.c: New file.
+ * config/tc-xtensa.h: Likewise.
+ * config/xtensa-istack.h: Likewise.
+ * config/xtensa-relax.c: Likewise.
+ * config/xtensa-relax.h: Likewise.
+ * doc/Makefile.am (CPU_DOCS): Add c-xtensa.texi.
+ * doc/Makefile.in: Regenerate.
+ * doc/all.texi: Set new XTENSA variable.
+ * doc/as.texinfo: Set new Xtensa variable. Describe
+ Xtensa-specific options. Define line comment character for
+ Xtensa. Add Xtensa processors to list of ELF targets where
+ alignment is specified in bytes. Add new Xtensa-Dependent node.
+ Add acknowledgements for those contributing to the Xtensa port.
+ * doc/internals.texi: Describe new md_post_relax_hook.
+ * doc/c-xtensa.texi: New file.
+
+2003-04-01 Nick Clifton <nickc@redhat.com>
+ Richard Earnshaw <rearnsha@arm.com>
+
+ * config/tc-arm.c: Remove presence of (r) and (tm) symbols.
+ (ARM_ARCH_IWMMXT): Simplify.
+ (insns): Place iwmmx instructions in correct place in table.
+ (arm_add_note): New function: Add a note entry to a .note section.
+ (md_begin): Make the default architecture be unknown.
+ Suppress the creation of an arm note section.
+
+2003-03-26 Eric Christopher <echristo@redhat.com>
+
+ * config/tc-mips.c (nopic_need_relax): Check for S_IS_EXTERN.
+
+2003-03-25 Stan Cox <scox@redhat.com>
+ Nick Clifton <nickc@redhat.com>
+
+ Contribute support for Intel's iWMMXt chip - an ARM variant:
+
+ * config/tc-arm.c: (ARM_CEXT_IWMMXT, ARM_ARCH_IWMMXT, WR_PREFIX,
+ WC_PREFIX, REG_TYPE_IWMMXT): New constants.
+ (enum wreg_type, enum iwmmxt_insn_type): New types.
+ (wr_register, wc_register, wcg_register): New macros.
+ (iwmmxt_table): New variable.
+ (wreg_required_here, do_iwmmxt_byte_addr, do_iwmmxt_tandc,
+ do_iwmmxt_tbcst, do_iwmmxt_textrc, do_iwmmxt_textrm,
+ do_iwmmxt_tinsr, do_iwmmxt_tmcr, do_iwmmxt_tmcrr, do_iwmmxt_tmia,
+ do_iwmmxt_tmovmsk, do_iwmmxt_tmrc, do_iwmmxt_tmrrc,
+ do_iwmmxt_torc, do_iwmmxt_waligni, do_iwmmxt_wmov,
+ do_iwmmxt_word_addr, do_iwmmxt_wrwr, do_iwmmxt_wrwrwcg,
+ do_iwmmxt_wrwrwr, do_iwmmxt_wshufh, do_iwmmxt_wzero,
+ cp_byte_address_offset, cp_byte_address_required_here,
+ check_iwmmxt_insn): New functions.
+ (asm_opcode_insns): Add iWMMXt instructions.
+ (md_begin): Set the mach value for iWMMXt targets. Create a note
+ section to identify iwmmxt binaries.
+ (md_apply_fix3): Handle BFD_RELOC_ARM_CP_OFF_IMM_S2.
+ * doc/c-arm.texi: Document the support for the iWMMXt.
+ * NEWS: Mention new support.
+
+2003-03-24 Daniel Néri <dne@mayonnaise.net>
+
+ * doc/as.texinfo: Rename the all occurances of C54X to TIC54X.
+ * doc/all.texi: Likewise.
+ * doc/c-tic54x.texi: Likewise.
+
+2003-03-21 Andreas Schwab <schwab@suse.de>
+
+ * config/tc-ia64.c (generate_unwind_image): Fix type of unw_rec to
+ avoid aliasing issue.
+
+2003-03-21 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.c (s390_arch_size): Initialize to zero.
+ (current_arch_mask): Rename to current_mode_mask.
+ (current_arch_requested): Remove variable.
+ (current_cpu): New variable.
+ (init_default_arch): Set defaults values for s390_arch_size,
+ current_mode_mask and current_cpu.
+ (md_parse_option): New options -mesa, -mzarch and -march={g5,g6,z900}.
+ (md_begin): Replace current_arch_mask by current_cpu.
+ (md_assemble): Adapt check and error message to current_mode_mask and
+ current_cpu.
+
+2003-03-09 James E Wilson <wilson@tuliptree.org>
+
+ * macro.c (buffer_and_nest): Store more to sb instead of '\n'.
+ * read.c (get_line_sb): Return end of line character or '\n' if
+ it is zero or non-existent.
+
+2003-03-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mips.c (mips_validate_fix): New function.
+ * config/tc-mips.h (TC_VALIDATE_FIX): Define.
+ (mips_validate_fix): Declare.
+
+2003-03-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * Reverted 2003-03-02's patch.
+
+2003-03-11 Steve Ellcey <sje@cup.hp.com>
+
+ * dwarf2dbg.c (generic_dwarf2_emit_offset): New.
+ (TC_DWARF2_EMIT_OFFSET): Provide default.
+ (out_debug_aranges, out_debug_info): Use it.
+ * config/tc-ia64.c (ia64_dwarf2_emit_offset): New.
+ (ia64_cons_fix_new): Move FUNC_DTP_RELATIVE handling ...
+ (ia64_gen_real_reloc_type): ... here.
+ * config/tc-ia64.h (TC_DWARF2_EMIT_OFFSET): New.
+
+2003-03-09 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (s_mips_end): Remove !BFD_ASSEMBLER case.
+ (s_mips_ent): Likewise.
+
+2003-03-04 Dmitry Diky <diwil@mail.ru>
+
+ * config/tc-msp430.c (mcu_types): Add recently announced x1122
+ and x1123 devices, add missed x437.
+ (md_show_usage): Sort device list.
+
+2003-03-03 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config/tc-sh.c (sh_dsp): Replace with preset_target_arch.
+ (md_begin): Use preset_target_arch.
+ (md_longopts): Make isa option unconditional.
+ (md_parse_option): Make OPTION_DSP and OPTION_ISA sh4 / any
+ set preset_target_arch.
+ (md_apply_fix3): If BFD_ASSEMBLER, adjust SWITCH_TABLE fixups
+ by -S_GET_VALUE (fixP->fx_subsy).
+ (tc_gen_reloc): For SWITCH_TABLE fixups, the symbol is fixp->fx_subsy,
+ and the addend is 0.
+ Adjust addend of R_SH_IND12W relocations by fixp->fx_offset - 4.
+ * config/tc-sh.h (TC_FORCE_RELOCATION_SUB_LOCAL): Define.
+
+2003-03-02 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (append_insn): Add handling of
+ BFD_RELOC_MIPSEMB_16_PCREL_S2. Avoid emitting unneeded
+ BFD_RELOC_16_PCREL_S2 relocs and add earlier warnings about
+ misaligned address and reange overflow.
+ (macro_build): Add handling of BFD_RELOC_MIPSEMB_16_PCREL_S2. Add
+ earlier warnings about misaligned address and reange overflow.
+ (mips_ip): Add handling of BFD_RELOC_MIPSEMB_16_PCREL_S2.
+ (md_apply_fix): Likewise. Fix warning output.
+ (tc_gen_reloc): Add handling of BFD_RELOC_MIPSEMB_16_PCREL_S2.
+ Allow BFD_RELOC_16_PCREL_S2 for all ABIs.
+ (md_convert_frag): Add handling of BFD_RELOC_MIPSEMB_16_PCREL_S2.
+
+2003-02-21 Nick Clifton <nickc@redhat.com>
+
+ * NEWS: Mention availability of test generator program.
+
+2003-02-21 Miles Bader <miles@gnu.org>
+
+ * config/tc-v850.c (system_registers): Add v850e debug registers.
+ (system_register_name): Accept up to 27 (the last v850e sys register).
+
+2003-02-21 Bob Wilson <bob.wilson@acm.org>
+
+ * doc/as.texinfo: Define new COFF-ELF variable to conditionalize text
+ relevant to both COFF and ELF. Fix obvious typos and texinfo bugs.
+ Capitalize section headings consistently. Format index entries more
+ consistently. Unconditionalize text about whether text and data
+ sections are alterable. Use @ifnottex for alternatives to @tex output
+ so that HTML works. Clean up COFF vs. ELF descriptions of .section,
+ .size and .type directives. Be more polite about bad bug reports.
+ Move FDL into a separate file.
+ * doc/fdl.texi: New file.
+
+2003-02-21 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (prev_reloc_op_frag): New variable.
+ (macro): Check it to decide whether a new frag is needed.
+ (my_getSmallExpression): Set it.
+
+2003-02-20 jmc <jmc@prioris.mini.pw.edu.pl>
+
+ * cgen.c: Fix typo: intial -> initial.
+
+2003-02-19 Jie Zhang <zhangjie@magima.com.cn>
+
+ * app.c (do_scrub_chars): Handle '||' in two states.
+
+2003-02-13 Alan Modra <amodra@bigpond.net.au>
+
+ * write.c (TC_FORCE_RELOCATION_SUB_SAME): Revert last change.
+ * config/tc-s390.h (TC_FORCE_RELOCATION_SUB_SAME): Define.
+
+2003-02-11 Uwe Stieber <uwe@wwws.de>
+
+ * configure.in: Add support for kaOS as cross build target system.
+ * configure: Regenerated.
+
+2003-02-10 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (md_begin): If the Maverick co-processor is
+ selected, set the EF_ARM_MAVERICK_FLOAT flag and
+ bfd_mach_arm_ep9312 machine number.
+
+2003-02-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (reloc_needs_lo_p): New function.
+ (fixup_has_matching_lo_p): New function.
+ (append_insn): Use reloc_needs_lo_p to check whether a relocation
+ might need a matching %lo(). Reuse the head of mips_hi_fixup_list
+ if that fixup already has a matching %lo(). Don't call frag_wane here.
+ (macro): Call frag_wane here if the last unmatched hi was in the
+ current frag.
+ (pic_need_relax): New function, split out from...
+ (md_estimate_size_before_relax): ...here.
+ (mips_frob_file): Use reloc_needs_lo_p. Use pic_need_relax to test
+ whether BFD_RELOC_MIPS_GOT16 fixups refer to global symbols.
+
+2003-02-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (my_getSmallExpression): Rework bracket handling.
+
+2003-02-06 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Undo part of last change so that
+ x@toc+off works.
+
+2003-02-05 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (mapping): Handle new TLS reloc specs.
+ (ppc_elf_suffix): Don't warn for x+off@got when ppc64 and don't
+ accept x@got+off etc.
+ (md_assemble): Handle TLS relocs.
+ (ppc_force_relocation): Force for all TLS relocs.
+ (ppc_fix_adjustable): Likewise.
+ (md_apply_fix3): Handle TLS relocs.
+
+2003-02-04 Alan Modra <amodra@bigpond.net.au>
+
+ * config/obj-elf.c (obj_elf_change_section): Set SEC_LINK_ONCE and
+ SEC_LINK_DUPLICATES_DISCARD directly rather than using elf_linkonce_p.
+
+2003-02-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (enum small_ex_type): Remove.
+ (imm_unmatched_hi): Remove.
+ (md_assemble): Remove use of imm_unmatched_hi. Remove the last
+ argument from calls to append_insn.
+ (append_insn): Remove unmatched_hi parameter; check reloc_type[0]
+ instead.
+ (macro_build): Update append_insn calls.
+ (mips16_macro_build, macro_build_lui): Likewise.
+ (mips_ip): Rework handling of small expressions. Move explicit
+ relocation handling into my_getSmallExpression. Assume that the
+ value of 'o' operands is zero if there is only one bracketed
+ expression left.
+ (percent_op): Make constant. Record the BFD relocation code
+ associated with each operator.
+ (my_getSmallParser, my_getPercentOp): Remove.
+ (parse_relocation): New function.
+ (my_getSamllExpression): Rework. Fill in relocations here
+ rather than in mips_ip.
+
+2003-01-29 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-i386.c (line_comment_chars): Add '#'. This makes the
+ assembler's handling of # <linenum> "<filename>" directives work.
+
+2003-01-28 Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf2dbg.c: Include filenames.h.
+ (struct file_entry): Make filename const char *.
+ (dirs, dirs_in_use, dirs_allocated): New variables.
+ (get_filenum): Add NUM argument. Build directory table.
+ (dwarf2_where): Adjust caller.
+ (dwarf2_directive_file): Use get_filenum to allocate
+ slot in file and directory tables.
+ (dwarf2_directive_loc): Recreate full filename from
+ directory and filename part if needed for listing.
+ (out_file_list): Output directory table.
+ Output main source file dirname before its filename.
+
+2003-01-28 Dmitry Diky <diwil@mail.ru>
+
+ * config/tc-msp430.c: Replace occurences of 'tolower' with
+ 'TOLOWER'.
+
+2003-01-27 David Mosberger <davidm@hpl.hp.com>
+
+ * config/tc-ia64.c (dot_vframesp): Correct error message.
+ (dot_vframepsp): Ditto.
+
+2003-01-27 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure.in (em): Set to irix on all Irix systems.
+ * configure: Rebuilt.
+ * config/te-irix.h: New file.
+ * config/tc-mips.c (mips_dwarf2_format): Use TE_IRIX to decide
+ whether to use Irix-specific 64-bit format.
+
+2003-01-27 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.c (s390_elf_cons): Avoid designated initializers.
+
+2003-01-25 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-sparc.c (sparc_ip): Handle TLS % operators.
+ (tc_gen_reloc): Handle TLS relocs.
+ (sparc_cons, cons_fix_new_sparc): Handle %r_tls_dtpoff.
+ * config/tc-sparc.h (tc_fix_adjustable): Don't adjust TLS
+ relocs.
+ * config/obj-elf.c (obj_elf_section_word): Handle tls.
+ (obj_elf_type): Handle tls_object.
+
+2003-01-24 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.c (s390_tls_suffix): New function.
+ (elf_suffix_type): Add suffix enums for TLS relocations.
+ (s390_elf_suffix): Add suffix strings for TLS relocations.
+ (s390_elf_cons): Map new lenght/elf suffix combinations for TLS to
+ bfd relocations.
+ (md_gather_operands): Map new instruction operand/elf suffix
+ combinations for TLS to bfd relocations.
+ (tc_s390_fix_adjustable): Add new TLS relocations.
+ (tc_s390_force_relocation): Likewise.
+ (md_apply_fix3): Likewise.
+
+2003-01-24 Alan Modra <amodra@bigpond.net.au>
+
+ * as.h: Update copyright date.
+ * symbols.c: Likewise.
+ * config/tc-d10v.h: Likewise.
+ * config/tc-fr30.h: Likewise.
+ * config/tc-i960.h: Likewise.
+ * config/tc-mips.h: Likewise.
+
+ * config/tc-hppa.h (DIFF_EXPR_OK): Define.
+ (MD_APPLY_SYM_VALUE): Move.
+
+2003-01-23 Nick Clifton <nickc@redhat.com>
+
+ * NEWS: Announce sh2e support.
+
+ Add sh2e support:
+ 2002-04-02 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-sh.c (md_show_usage): Added sh2e next to sh3e.
+ (sh_elf_final_processing): Handle arch_sh2e.
+
+2003-01-23 Alan Modra <amodra@bigpond.net.au>
+
+ * symbols.c (S_FORCE_RELOC): Add "strict" param.
+ * symbols.h (S_FORCE_RELOC): Likewise.
+ * config/obj-aout.h (S_FORCE_RELOC): Likewise.
+ * config/obj-bout.h (S_FORCE_RELOC): Likewise.
+ * config/obj-coff.h (S_FORCE_RELOC): Likewise.
+ * config/obj-ieee.h (S_FORCE_RELOC): Likewise.
+ * config/obj-vms.h (S_FORCE_RELOC): Likewise.
+ * write.c (generic_force_reloc): New function.
+ (TC_FORCE_RELOCATION): Use it here instead of S_FORCE_RELOC.
+ (TC_FORCE_RELOCATION_SUB_SAME): Test TC_FORCE_RELOCATION too.
+ (adjust_reloc_syms): Adjust S_FORCE_RELOC call.
+ * as.h (generic_force_reloc): Declare.
+ * doc/internals.texi (S_FORCE_RELOC): Update.
+ (TC_FORCE_RELOCATION_SUB_SAME): Update.
+
+ * config/tc-alpha.c (alpha_force_relocation): Adjust to use
+ generic_force_reloc.
+ (alpha_fix_adjustable): Likewise.
+ * config/tc-arm.c (arm_force_relocation): Likewise.
+ * config/tc-cris.c (md_cris_force_relocation): Likewise.
+ * config/tc-frv.c (frv_force_relocation): Likewise.
+ * config/tc-i386.c (md_apply_fix3): Likewise.
+ * config/tc-ia64.c (ia64_force_relocation): Likewise.
+ * config/tc-ip2k.c (ip2k_force_relocation): Likewise.
+ * config/tc-m32r.c (m32r_force_relocation): Likewise.
+ * config/tc-m68hc11.c (tc_m68hc11_force_relocation): Likewise.
+ * config/tc-mcore.c (mcore_force_relocation): Likewise.
+ * config/tc-mips.c (mips_force_relocation): Likewise.
+ * config/tc-mmix.c (mmix_force_relocation): Likewise.
+ * config/tc-ppc.c (ppc_force_relocation): Likewise.
+ * config/tc-s390.c (tc_s390_force_relocation): Likewise.
+ * config/tc-sh.c (sh_force_relocation): Likewise.
+ (md_pcrel_from_section): Likewise.
+ * config/tc-sparc.c (tc_gen_reloc): Likewise.
+ * config/tc-v850.c (v850_force_relocation): Likewise.
+ * config/tc-xstormy16.c (xstormy16_force_relocation): Likewise.
+ * config/tc-i386.h (TC_FORCE_RELOCATION): Likewise.
+ * config/tc-mcore.h (TC_FORCE_RELOCATION): Likewise.
+ * config/tc-sparc.h (tc_fix_adjustable): Likewise.
+
+ * config/tc-d10v.c (d10v_force_relocation): Delete.
+ * config/tc-d10v.h (TC_FORCE_RELOCATION): Don't define.
+ * config/tc-dlx.c (md_dlx_force_relocation): Delete.
+ * config/tc-dlx.h (TC_FORCE_RELOCATION): Don't define.
+ * config/tc-fr30.c (fr30_force_relocation): Delete.
+ * config/tc-fr30.h (TC_FORCE_RELOCATION): Don't define.
+ * config/tc-mn10300.c (mn10300_force_relocation): Delete.
+ * config/tc-mn10300.h (TC_FORCE_RELOCATION): Don't define.
+ (TC_FORCE_RELOCATION_SUB_SAME): Test TC_FORCE_RELOCATION too.
+ * config/tc-i960.h (TC_FORCE_RELOCATION_SUB_SAME): Likewise.
+ * config/tc-hppa.c (hppa_force_relocation): Adjust S_FORCE_RELOC call.
+ * config/tc-mips.c (RELAX_BRANCH_TOOFAR): Warning fix.
+ * config/tc-mips.h (TC_FORCE_RELOCATION_SUB_SAME): Don't define.
+ * config/tc-openrisc.c (openrisc_force_relocation): Delete.
+ * config/tc-openrisc.h (TC_FORCE_RELOCATION): Don't define.
+ * config/tc-sparc.c (elf32_sparc_force_relocation): Delete.
+ * config/tc-sparc.h (TC_FORCE_RELOCATION): Don't define for ELF.
+ * config/tc-i386.c (i386_force_relocation): Delete.
+ * config/tc-i386.h (TC_FORCE_RELOCATION): Don't define for
+ BFD_ASSEMBLER.
+ (EXTERN_FORCE_RELOC): Fix TE_PE and STRICT_PE_FORMAT nesting.
+ * config/tc-m68k.h (TC_FORCE_RELOCATION): Don't define.
+ * config/tc-pj.h (TC_FORCE_RELOCATION): Don't define.
+ * config/tc-sh.h (TC_FORCE_RELOCATION_SUB_ABS): Don't call
+ S_FORCE_RELOC.
+ (TC_FORCE_RELOCATION_SUB_SAME): Test TC_FORCE_RELOCATION too.
+ * config/tc-sh64.h (TC_FORCE_RELOCATION_SUB_SAME): Likewise.
+
+2003-01-23 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-sh64.c (shmedia_frob_section_type): Adjust for changed
+ sh64_elf_section_data.
+ * config/tc-sh64.h: Include elf32-sh64.h.
+ * config/tc-m68hc11.c: Don't include stdio.h.
+ (md_show_usage): Fix missing continuation.
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2003-01-22 Nick Clifton <nickc@redhat.com>
+
+ * as.h: Include fopen-bin.h not fopen-same.h for mingw32 hosts.
+
+2003-01-21 Fabio Alemagna <falemagn@aros.org>
+
+ * configure.in: Handle *-*-aros*.
+ * configure: Regenerated from configure.in.
+
+2003-01-20 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.c (elf_suffix_type): Add suffix enums for gotoff,
+ gotplt and pltoff relocations.
+ (s390_elf_suffix): Add suffix strings for gotoff, gotplt and pltoff.
+ (s390_elf_cons): Map new lenght/elf suffix combinations for gotoff,
+ gotplt and pltoff to bfd relocations.
+ (md_gather_operands): Map new instruction operand/elf suffix
+ combinations to bfd relocations.
+ (tc_s390_fix_adjustable): Add new gotoff, gotplt and pltoff relocations
+ to the list of unadjustable relocations.
+ (tc_s390_force_relocation): Always emit relocations for gotoff, gotplt
+ and pltoff relocations.
+ (md_apply_fix3): Add the new relocations.
+
+2003-01-20 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.c (md_apply_fix3): Emit error message for relocations
+ with a subsy symbol.
+
+2003-01-17 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/tc-m68hc11.c (tc_m68hc11_fix_adjustable): Prevent adjustment
+ of relocs for memory bank addressing.
+
+2003-01-17 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/tc-m68hc11.c (md_show_usage): Update usage.
+ (md_parse_option): Recognize -m68hcs12.
+ (m68hc11_elf_final_processing): Set EF_M68HCS12_MACH flag to identify
+ HCS12.
+ * doc/as.texinfo (Overview): Document new option -m68hcs12.
+
+2003-01-16 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-ia64.c (ia64_cons_fix_new): Handle @dtprel() in data.
+
+2003-01-16 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * po/POTFILES.in: Regenerate.
+
+2003-01-11 Alan Modra <amodra@bigpond.net.au>
+
+ * read.c (get_absolute_expr): New, split out from..
+ (get_absolute_expression): ..here.
+ * read.h (get_absolute_expr): Declare.
+ * config/obj-elf.c (elf_common): Use offsetT for "temp" and "size".
+ Trim size to arch bits_per_address, and test for negative input
+ via get_absolute_expr.
+
+2003-01-07 DJ Delorie <dj@redhat.com>
+
+ * config/tc-xstormy16.c (md_cgen_lookup_reloc): Adjust value based
+ on operand type.
+ (xstormy16_md_apply_fix3): Use adjustment.
+
+2003-01-02 Ben Elliston <bje@redhat.com>
+
+ * configure.in: Add iq2000-elf target.
+ * configure: Regenerate.
+ * config/tc-iq2000.c: New file.
+ * config/tc-iq2000.h: Likewise.
+ * po/gas.pot: Regenerate.
+
+2003-01-02 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c: Update copyright years to include 2003.
+ (mips_ip): Fix indentation of "+A", "+B", and "+C" handling.
+ Additionally, clean up their code slightly and clean up their
+ comments some more.
+
+ * doc/c-mips.texi: Add MIPS32r2 to ".set mipsN" documentation.
+
+2003-01-01 Daniel Jacobowitz <drow@mvista.com>
+
+ * doc/Makefile.am (as.1): Depend on "asconfig.texi gasver.texi
+ $(CPU_DOCS)".
+ * doc/Makefile.in: Regenerate.
+
+2003-01-01 John David Anglin <dave.anglin@nrc.ca>
+
+ * config/obj-elf.c (special_sections): Work around HP's incorrect usage
+ of .init and .fini sections for array initializers and finalizers.
+
+2002-12-31 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (validate_mips_insn, mips_ip): Recognize
+ the "+D" operand, which will be used only by the disassembler.
+
+2002-12-30 Chris Demetriou <cgd@broadcom.com>
+
+ * configure.in: Recognize mipsisa32r2, mipsisa32r2el, and
+ CPU variants.
+ * configure: Regenerate.
+ * config/tc-mips.c (ISA_HAS_DROR, ISA_HAS_ROR): New defines.
+ (macro_build): Handle "K" operand.
+ (macro2): Use ISA_HAS_DROR and ISA_HAS_ROR in the places where
+ CPU_HAS_DROR and CPU_HAS_ROR are currently used.
+ (mips_ip): New variable "lastpos", and implement "+A", "+B",
+ and "+C" operands for MIPS32 Release 2 ins/ext instructions.
+ Implement "K" operand for MIPS32 Release 2 rdhwr instruction.
+ (validate_mips_insn): Implement "+" as a way to extend the
+ allowed operands, and implement "K", "+A", "+B", and "+C"
+ operands.
+ (OPTION_MIPS32R2): New define.
+ (md_longopts): Add entry for OPTION_MIPS32R2.
+ (OPTION_ELF_BASE): Adjust to accommodate OPTIONS_MIPS32R2.
+ (md_parse_option): Handle OPTION_MIPS32R2.
+ (s_mipsset): Reimplement handling of ".set mipsN" options
+ and add support for ".set mips32r2".
+ (mips_cpu_info_table): Add entry for "mips32r2" (MIPS32 Release 2).
+ (md_show_usage): Document "-mips32r2" option.
+ * doc/as.texinfo: Document "-mips32r2" option.
+ * doc/c-mips.texi: Likewise.
+
+2002-12-30 Dmitry Diky <diwil@mail.ru>
+
+ * configure.in: Add msp430 target.
+ * configure: Regenerate.
+ * Makefile.am: Add msp430 target.
+ * Makefile.in: Regenerate.
+ * config/tc-msp430.c: New file: msp430 assembler.
+ * config/tc-msp430.h: New file: target macros for msp430.
+ * doc/Makefile.am: Add msp430 target.
+ * doc/Makefile.in: Regenerate.
+ * doc/as.texinfo: Include msp430 documenation.
+ * doc/all.texi: Enable msp430 documentation.
+ * doc/c-msp430.texi: New file: document msp430 specific features
+ of the assembler.
+
+2002-12-25 Alexandre Oliva <aoliva@redhat.com>
+
+ * dwarf2dbg.c (DWARF2_ADDR_SIZE): New macro.
+ (dwarf2_finish): Use it.
+ * doc/internals.texi (DWARF2_ADDR_SIZE): Document it.
+ * config/tc-mips.h (DWARF2_ADDR_SIZE): Override.
+
+2002-12-20 DJ Delorie <dj@redhat.com>
+
+ * config/tc-xstormy16.c (md_cgen_lookup_reloc): Support
+ BFD_RELOC_XSTORMY16_12.
+
+2002-12-19 Alan Modra <amodra@bigpond.net.au>
+
+ * doc/as.texinfo (Invoking): Typo fix.
+ * config/tc-tic54x.c (encode_operand): Comment typo fix.
+
+2002-12-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/c-alpha.texi: Fix typos.
+ * doc/c-arm.texi: Likewise.
+ * doc/c-d10v.texi: Likewise.
+ * doc/c-i370.texi: Likewise.
+ * doc/c-i960.texi: Likewise.
+ * doc/c-ia64.texi: Likewise.
+ * doc/c-mmix.texi: Likewise.
+ * doc/c-ns32k.texi: Likewise.
+ * doc/c-pdp11.texi: Likewise.
+ * doc/c-pj.texi: Likewise.
+ * doc/c-sh64.texi: Likewise.
+ * doc/c-sparc.texi: Likewise.
+ * doc/c-tic54x.texi: Likewise.
+ * doc/c-v850.texi: Likewise.
+ * doc/c-vax.texi: Likewise.
+ * doc/internals.texi: Likewise.
+
+2002-12-18 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (macro): In M_DROL, M_DROR, M_ROL, and M_ROR,
+ use hardware rotate ops as appropriate. In M_DROL_I, M_DROR_I,
+ M_ROL_I, and M_ROR_I, simplify code, clean up warnings, and
+ arrange not to issue warnings about use of AT when AT is not
+ actually used.
+
+2002-12-17 Nick Clifton <nickc@redhat.com>
+
+ * as.c (std_longopts): Duplicate --keep-locals entry in order to
+ prevent it being confused with -k.
+
+2002-12-16 Andrew MacLeod <amacleod@redhat.com>
+
+ * config/tc-xstormy16.c (md_cgen_lookup_reloc): If a relocation
+ has already been set up, use it.
+
+2002-12-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog-9295: Fix a typo.
+ * README: Likewise.
+ * config/tc-d10v.c: Fix a comment typo.
+ * config/tc-dlx.c: Likewise.
+ * config/tc-h8300.h: Likewise.
+ * config/tc-h8500.h: Likewise.
+ * config/tc-mips.c: Likewise.
+ * config/tc-s390.c: Likewise.
+ * config/tc-sh.h: Likewise.
+ * config/tc-tic80.h: Likewise.
+ * config/tc-w65.h: Likewise.
+ * config/tc-z8k.c: Likewise.
+ * config/tc-z8k.h: Likewise.
+ * testsuite/gas/h8300/cmpsi2.s: Likewise.
+
+2002-12-16 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-d30v.c (check_range): Warning fixes, formatting.
+ Simplify sign extension. Remove redundant unsigned < 0 test.
+ * config/tc-i960.c (md_ri_to_chars): Prototype.
+ * config/tc-mcore.c (md_pseudo_table): Fix typo.
+ (dump_literals): Init brarsym, and test later instead of isforce.
+
+ * config/tc-ns32k.c (encode_operand): Constify operandsP and suffixP.
+ (parse): Constify line and lineptr.
+ (md_begin): Calculate endop here.
+
+2002-12-13 Alan Modra <amodra@bigpond.net.au>
+
+ * config/obj-vms.c: Formatting. Include fnctl.h.
+ (Create_VMS_Object_File): Fix creat call for sane unix systems.
+ (Object_Record_Offset): Make it a size_t.
+ (Flush_VMS_Object_Record_Buffer): Fix signed/unsigned warning.
+ (VMS_TBT_Routine_End <Size>): Make var unsigned long.
+ (VMS_Fix_Indirect_Reference <Offset>): Make arg addressT.
+ (synthesize_data_segment <data_size>): Remove ATTRIBUTE_UNUSED.
+ (vms_fixup_data_section <data_size>): Add here instead.
+ * config/e-criself.c: Fix typo in last change.
+
+2002-12-13 Alan Modra <amodra@bigpond.net.au>
+
+ * write.c (write_object_file): Fix signed/unsigned warning.
+ * config/e-crisaout.c (crisaout_bfd_name): Prototype.
+ * config/e-criself.c (criself_bfd_name): Prototype.
+ * config/obj-aout.c (s_sect): Remove unused function.
+ * config/obj-bout.c (obj_bout_line <ignore>): Add ATTRIBUTE_UNUSED.
+ * config/obj-coff.c (coff_last_bf): Don't declare for OBJ_XCOFF.
+ (fixup_mdeps <h>): Add ATTRIBUTE_UNUSED.
+ * config/obj-ecoff.c (ecoff_frob_file <addr>): Likewise.
+ * config/obj-vms.c (setup_basic_type <spnt>): Likewise.
+ (VMS_RSYM_Parse <Current_Routine>): Likewise.
+ (vms_fixup_text_section <text_siz>): Likewise.
+ (synthesize_data_segment <data_size>): Likewise.
+ (vms_fixup_xtors_section <sect_no>): Likewise.
+ (structure_count): Don't use implicit int type.
+ * config/tc-a29k.c (insert_sreg): Prototype.
+ (define_some_regs): Prototype, make static.
+ (parse_operand): Likewise.
+ (md_parse_option <c,arg>): Add ATTRIBUTE_UNUSED.
+ (md_show_usage <stream>): Likewise.
+ (md_section_align <segment>): Likewise.
+ (md_convert_frag <all args>): Likewise.
+ (md_estimate_size_before_relax <all args>): Likewise.
+ (md_apply_fix3): Don't cast valP pointer type. Fix bogus >>='s.
+ * config/tc-arm.c (arm_validate_fix): Only for OBJ_COFF or OBJ_ELF.
+ * config/tc-d30v.c (md_parse_option <arg>): Add ATTRIBUTE_UNUSED.
+ (md_undefined_symbol <name>): Likewise.
+ (md_convert_frag <all args>): Likewise.
+ (write_long <opcode>): Likewise.
+ (tc_gen_reloc <seg>): Likewise.
+ (md_estimate_size_before_relax <all args>): Likewise.
+ (md_apply_fix3 <seg>): Likewise.
+ (s_d30v_align <ignore>): Likewise.
+ (build_insn): Correct format string.
+ (md_apply_fix3): Likewise.
+ * config/tc-fr30.c (md_parse_option <c,arg>): Add ATTRIBUTE_UNUSED.
+ (md_undefined_symbol <name>): Likewise.
+ (md_convert_frag <all args>): Likewise.
+ (md_cgen_lookup_reloc <insn>): Likewise.
+ (md_begin): Delete unused vars.
+ (md_assemble): Likewise.
+ (md_estimate_size_before_relax): Likewise.
+ (fr30_relax_frag): #if 0 out, seems unused.
+ (md_atof): Remove declaration of atof_ieee.
+ (restore_colon): Prototype.
+ * config/tc-frv.c (frv_insert_vliw_insn): Prototype.
+ (frv_find_in_vliw): Likewise.
+ (frv_debug_tomcat): Likewise.
+ (frv_adjust_vliw_count): Likewise.
+ (frv_tomcat_shuffle): Likewise.
+ (frv_tomcat_analyze_vliw_chains): Likewise. Correct args to
+ frv_find_in_vliw call.
+ (md_atof): Remove declaration of atof_ieee.
+ * config/tc-h8500.c (cons): Delete declaration.
+ (md_begin <opcode>): Constify.
+ (displacement_size, immediate_size, absolute_size): Remove.
+ (build_relaxable_instruction <operand>): Add ATTRIBUTE_UNUSED.
+ (tc_crawl_symbol_chain <headers>): Likewise.
+ (md_undefined_symbol <name>): Likewise.
+ (tc_headers_hook <headers>): Likewise.
+ (md_parse_option <c,arg>): Likewise.
+ (md_show_usage <stream>): Likewise.
+ (md_convert_frag <headers, seg>): Likewise.
+ (tc_coff_symbol_emit_hook <ignore>): Likewise.
+ (md_atof): Remove declaration of atof_ieee.
+ (tc_aout_fix_to_chars): Remove unused function.
+ (parse_reg): Prototype.
+ (parse_exp): Prototype.
+ (skip_colonthing): Prototype. Use &&, not & in logical expressions.
+ (parse_reglist): Prototype.
+ (get_operand): Prototype.
+ (get_operands): Prototype.
+ (get_specific): Prototype. Make "this_index" signed.
+ (check): Prototype, make static.
+ (insert): Prototype
+ (build_relaxable_instruction): Prototype, make static.
+ (build_bytes): Prototype.
+ (wordify_scb): Prototype.
+ * config/tc-h8500.h (start_label): Declare.
+ (tc_coff_sizemachdep): Declare.
+ * config/tc-i370.c (i370_ebcdic <unused>): Add ATTRIBUTE_UNUSED.
+ (i370_rmode <unused>): Likewise.
+ (i370_csect <unused>): Likewise.
+ (i370_dc <unused>): Likewise.
+ (i370_ds <unused>): Likewise.
+ (i370_elf_lcomm <unused>): Likewise.
+ (i370_ltorg <ignore>): Likewise.
+ (i370_using <ignore>): Likewise.
+ (i370_drop <ignore>): Likewise.
+ (i370_byte <ignore>): Likewise.
+ (i370_tc <ignore>): Likewise.
+ (md_estimate_size_before_relax <fragp, seg>): Likewise.
+ (md_convert_frag <all args>): Likewise.
+ (md_undefined_symbol <name>): Likewise.
+ (md_pcrel_from_section <sec>): Likewise.
+ (tc_gen_reloc <seg>): Likewise.
+ (i370_section_letter): #if 0 unused functions.
+ (i370_section_word, i370_section_type, i370_section_flags): Likewise.
+ (symbol_locate): Prototype.
+ * config/tc-i860.c (md_atof): Remove declaration of atof_ieee.
+ (md_number_to_disp, md_number_to_field): Remove.
+ (md_apply_fix3): Correct format string and cast "fup".
+ * config/tc-i960.c (md_convert_frag): Add ATTRIBUTE_UNUSED to args.
+ (s_endian <ignore>): Likewise.
+ (md_undefined_symbol <name>): Likewise.
+ (tc_crawl_symbol_chain <headers>): Likewise.
+ (tc_set_bal_of_call): Likewise.
+ (tc_coff_symbol_emit_hook <symbolP>): Likewise.
+ (i960_handle_align <fragp>): Likewise.
+ (i960_validate_fix <this_segment_type>): Likewise
+ (tc_gen_reloc <section>): Likewise.
+ (tc_coff_symbol_emit_hook): Only define for OBJ_COFF.
+ (struct memS, struct regop): Forward declare.
+ (brcnt_emit, brlab_next, cobr_fmt, ctrl_fmt, emit, get_args,
+ get_cdisp, get_ispec, get_regnum, i_scan, mem_fmt, mema_to_memb,
+ parse_expr, parse_ldconst, parse_memop, parse_po, parse_regop,
+ reg_fmt, relax_cobr, s_leafproc, s_sysproc, shift_ok, syntax,
+ targ_has_sfr, targ_has_iclass, tc_bfd_fix2rtype): Prototype.
+ (md_chars_to_number, md_number_to_imm): Make static, prototype.
+ (md_number_to_field): Likewise.
+ (md_number_to_disp): Remove unused function.
+ (md_atof): Remove declaration of atof_ieee.
+ (md_apply_fix3): Correct md_number_to_imm call.
+ * config/tc-ip2k.c (md_assemble): Warning fix.
+ * config/tc-m32r.c (md_parse_option <arg>): Add ATTRIBUTE_UNUSED.
+ (fill_insn <ignore>): Likewise.
+ (debug_sym <ignore>): Likewise.
+ (md_undefined_symbol <name>): Likewise.
+ (m32r_scomm <ignore>): Likewise.
+ (md_convert_frag <abfd>): Likewise.
+ (md_cgen_lookup_reloc <insn>): Likewise.
+ (m32r_record_hi16 <seg>): Likewise.
+ (md_estimate_size_before_relax): #if 0 old_fr_fix.
+ (allow_m32rx): Prototype.
+ (first_writes_to_seconds_operands): Prototype.
+ (writes_to_pc): Prototype.
+ (can_make_parallel): Prototype.
+ (make_parallel): Prototype.
+ (target_make_parallel): Prototype.
+ (assemble_two_insns): Prototype.
+ (m32r_record_hi16): Prototype.
+ (md_atof): Remove declaration of atof_ieee.
+ * config/tc-m32r.h (m32r_fix_adjustable): Declare.
+ (m32r_force_relocation): Prototype.
+ (m32r_elf_section_change_hook): Prototype.
+ * config/tc-m68k.c (tc_gen_reloc <section>): Add ATTRIBUTE_UNUSED.
+ (md_show_usage): Fix signed/unsigned warning.
+ * config/tc-m88k.c (get_reg): Make reg_prefix param unsigned.
+ (calcop): Ditto for reg_prefix var.
+ (hexval): Add cast to fix signed/unsigned warning.
+ (md_number_to_disp): Delete unused function.
+ (md_number_to_field): Likewise.
+ (float_cons, cons, s_globl, s_space, s_set, s_lcomm): Remove decl.
+ (match_name): Prototype.
+ (get_bf2): Prototype.
+ (get_bf_offset_expression): Prototype.
+ * config/tc-mcore.c (mcore_s_literals <ignore>): Add ATTRIBUTE_UNUSED.
+ (md_undefined_symbol <ignore>): Likewise.
+ (md_create_short_jump <all args>): Likewise.
+ (md_create_long_jump <all args>): Likewise.
+ (md_convert_frag <abfd, sec>): Likewise.
+ (md_apply_fix3 <segment>): Likewise.
+ (md_section_align <segment>): Likewise.
+ (md_pcrel_from_section <sec>): Likewise.
+ (tc_gen_reloc <section>): Likewise.
+ (reg_m, reg_n, immediate): Delete unused vars.
+ (dump_literals): Fix signed/unsigned warning.
+ (enter_literal): Likewise.
+ (parse_imm): Likewise. Also fix format string.
+ (parse_mem): Remove unused var.
+ (md_assemble <LS>): Abort on unexpected inst.
+ (md_atof): Remove declaration of atof_ieee.
+ (md_parse_option): Remove unused vars.
+ (md_apply_fix3): Fix format strings, cast args.
+ (tc_gen_reloc): Delete unused var.
+ * config/tc-mcore.h (tc_coff_sizemachdep): Declare.
+ * config/tc-mn10200.c (md_parse_option <c, arg>): Add ATTRIBUTE_UNUSED.
+ (md_undefined_symbol <name>): Likewise.
+ (md_convert_frag <abfd>): Likewise.
+ (tc_gen_reloc <seg>): Likewise.
+ (check_operand <insn>): Likewise.
+ (md_convert_frag): Fix format strings.
+ (tc_gen_reloc): Delete fx_addsy - fx_subsy code.
+ * config/tc-openrisc.c (ignore_pseudo): Prototype.
+ (md_atof): Remove declaration of atof_ieee.
+ * config/tc-or32.c (parse_operand): Prototype non-BFD too.
+ (md_apply_fix3): Fix bogus >>='s.
+ (md_undefined_symbol): Delete unused var.
+ * config/tc-pj.c (little, big, parse_exp_save_ilp): Prototype.
+ (c_to_r, ipush_code, fake_opcode, alias): Likewise.
+ (fake_opcode): Adjust for pj_opc_int_t change.
+ (md_begin): Likewise.
+ (md_assemble): Likewise.
+ (ipush_code): Correct parse_exp_save_ilp call. Test pending_reloc
+ instead of non-existent third arg of parse_exp_save_ilp.
+ (md_parse_option): Correct "little" and "big" calls.
+ * config/tc-sparc.c (s_register): Only declare #ifdef OBJ_ELF.
+ (md_apply_fix3 <segment>): Add ATTRIBUTE_UNUSED.
+ (tc_gen_reloc <section>): Likewise.
+ * config/tc-tic30.c: #include stdarg.h or varargs.h.
+ (debug): Rewrite using VA_* macros.
+ (md_estimate_size_before_relax): Add ATTRIBUTE_UNUSED to args.
+ (md_convert_frag): Likewise.
+ (md_parse_option): Likewise.
+ (md_show_usage): Likewise.
+ (md_undefined_symbol): Likewise.
+ (tc_gen_reloc): Likewise.
+ (md_operand): Likewise.
+ (tc_aout_pre_write_hook): Delete.
+ (struct tic30_insn): Make "operands" unsigned.
+ (struct tic30_par_insn): Likewise.
+ (md_assemble): Likewise for "count", "i" and "numops".
+ (tic30_parallel_insn): Likewise for vars here.
+ (tic30_operand): Likewise. Remove useless unsigned >= 0 comparison.
+ * config/tc-tic30.h (tc_aout_pre_write_hook): Define as empty.
+ * config/tc-tic80.c (obj_coff_section): Delete declaration.
+ (md_estimate_size_before_relax): Add ATTRIBUTE_UNUSED on args.
+ (md_undefined_symbol): Likewise.
+ (md_parse_option): Likewise.
+ (md_convert_frag): Likewise.
+ (tc_coff_symbol_emit_hook): Likewise.
+ (md_atof): Remove declaration of atof_ieee.
+ (const_overflow): Warning fixes, tidy.
+ (get_operands): Delete unused vars.
+ (internal_error_a): Adjust format string to expect a long for arg.
+ (find_opcode): Warning fixes, simplify.
+ (build_insn): Cast internal_error_a arg.
+ (md_begin): Likewise.
+ (md_apply_fix3): Likewise.
+ (md_assemble): Delete unused var.
+ * config/tc-tic80.h (tc_coff_fix2rtype): Prototype.
+ * config/tc-z8k.c (cons, obj_coff_section): Delete declarations.
+ (whatreg, parse_reg, parse_exp): Make static, prototype.
+ (checkfor, regword, regaddr, get_ctrl_operand): Prototype.
+ (get_flags_operand, get_interrupt_operand, get_cc_operand): Likewise.
+ (get_operand, get_operands, get_specific, newfix): Likewise.
+ (apply_fix, build_bytes): Likewise.
+ (md_atof): Remove declaration of atof_ieee.
+ (tc_aout_fix_to_chars): Delete.
+ (md_begin): Constify "opcode". Don't try to init opcode->idx.
+ Fix s_unseg call.
+ (md_parse_option): Fix s_segm and s_unseg calls.
+
+2002-12-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * tc-mips.c (RELAX_BRANCH_ENCODE): Remove reloc_s2 argument.
+ Adjust callers.
+ (RELAX_BRANCH_RELOC_S2): Delete.
+ (append_insn): Use only BFD_RELOC_16_PCREL_S2 for branches.
+ Do not handle BFD_RELOC_16_PCREL.
+ (macro_build, mips_ip): Likewise.
+ (md_pcrel_from): Return 4 for undefined symbols regardless of
+ mips_pic.
+ (md_apply_fix3): Use only BFD_RELOC_16_PCREL_S2 for branches.
+ Don't dereference howto if no such relocation is available.
+ Do not apply hack for in-place zero addend in NEWABI.
+ (md_convert_frag): Use only BFD_RELOC_16_PCREL_S2 for branches.
+
+2002-12-12 Alexandre Oliva <aoliva@redhat.com>,
+ Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-mn10300.h (TC_VALIDATE_FIX_SUB): Define.
+ (TC_LINKRELAX_FIXUP): Add comments.
+
+2002-12-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mn10300.c (set_arch_mach): Change argument type to
+ avoid warnings.
+ (r_register_name, xr_register_name): Add prototype declarations.
+
+2002-12-08 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-ia64.c (md_apply_fix3): Remove the PCREL hack
+ copied from tc-i386.c.
+
+2002-12-08 Stephane Carrez <stcarrez@nerim.fr>
+
+ Fix Bug savannah/1825:
+ * config/tc-m68hc11.c (STATE_INDEXED_PCREL): New relax code.
+ (md_relax_table): Define specific relax for PC-rel offsets.
+ (build_indexed_byte): Use a STATE_INDEXED_PCREL relax code.
+ (m68hc11_relax_frag): Handle the new relax code.
+ (md_convert_frag): Likewise.
+ (md_estimate_size_before_relax): Likewise.
+
+2002-12-08 Alan Modra <amodra@bigpond.net.au>
+
+ * subsegs.c (section_symbol): Use the symbol, not the section, name.
+
+2002-12-05 Richard Henderson <rth@redhat.com>
+
+ * config/ia64.c (enum reloc_func): Add FUNC_LT_RELATIVE_X.
+ (ia64_gen_real_reloc_type): Handle it.
+ (pseudo_func): Add @ltoffx.
+ (md_begin): Build .<ltoffx>.
+ (ia64_force_relocation): True for LTOFF22X and LDXMOV.
+
+2002-12-05 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-arm.c (arm_force_relocation): Move out of #if OBJ_ELF.
+ Move OBJ_COFF TC_FORCE_RELOCATION code here so that COFF handles
+ ARM_IMMEDIATE and ARM_ADRL_IMMEDIATE relocs as for ELF.
+ * config/tc-arm.h (TC_FORCE_RELOCATION): Define for both ELF and
+ COFF to call arm_force_relocation.
+
+2002-12-04 David Mosberger <davidm@hpl.hp.com>
+
+ * config/tc-ia64.c (pseudo_func): Add "@pause" constant for "hint"
+ instruction.
+ (emit_one_bundle): Handle "hint" instruction.
+ (operand_match): Match IA64_OPND_AR_CSD.
+
+2002-12-04 Alan Modra <amodra@bigpond.net.au>
+
+ * dwarf2dbg.c (scale_addr_delta): Correct parameter. Move prototype
+ inside #if.
+
+2002-12-03 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-ppc.c (ppc_cleanup): Do not set SEC_MERGE flag on
+ .PPC.EMB.apuinfo sections.
+
+2002-12-03 Richard Henderson <rth@redhat.com>
+
+ * config/tc-ia64.c (operand_match): Add IA64_OPND_LDXMOV case.
+
+2002-12-03 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-w65.c (s_longa): Prototype. Make static, specify int arg.
+ (cons, s_align_bytes): Delete declaration.
+ (relax): Delete.
+ (md_begin): Constify "struct opinfo *" var. Don't try to make "name"
+ strings common.
+ (dot): Delete unused function.
+ (w65_expression): Remove unused arg.
+ (parse_exp): Prototype. Remove unused arg. Adjust w65_expression
+ call.
+ (get_operands): Prototype. Constify "struct opinfo *" arg. Fix
+ parse_exp call.
+ (get_specific): Prototype. Constify "struct opinfo *" arg and return
+ value.
+ (check): Remove unused function.
+ (build_Mytes): Prototype. Constify "struct opinfo *" arg. Abort
+ on unhandled switch case.
+ (md_assemble): Remove unused op_start, op_end, nlen, p vars. Constify
+ "opcode".
+ (tc_crawl_symbol_chain): Delete unused function.
+ (tc_headers_hook): Likewise.
+ (tc_Nout_fix_to_chars): Likewise.
+ (md_undefined_symbol): Add ATTRIBUTE_UNUSED.
+ (md_parse_option): Likewise.
+ (md_convert_frag): Likewise.
+ (tc_coff_symbol_emit_hook): Likewise.
+ (md_show_usage): Likewise.
+ * config/tc-w65.h (tc_coff_sizemachdep): Declare.
+ (TC_PARSE_CONS_EXPRESSION): w65_expression takes one arg.
+ (w65_expression): Declare.
+
+ * po/POTFILES.in: Regenerate.
+
+ * config/tc-arm.c (arm_force_relocation): Return 0 for ARM_IMMEDIATE
+ and ARM_ADRL_IMMEDIATE.
+
+2002-12-02 Nick Clifton <nickc@redhat.com>
+
+ * gasp.c: Delete. It has been deprecated.
+ * NEWS: Mention that gasp has been removed.
+ * Makefile.am: Remove references to gasp.
+ * makefile.vms: Likewise.
+ * mpw-make.sed: Likewise.
+ * Makeile.in: Regenerate.
+ * doc/gasp.texi: Delete.
+ * doc/Makefile.am: Remove references to gasp.texi.
+ * doc/Makefile.in: Regenerate.
+ * macro.c: Delete references to gasp.
+ Remove use of comment_char function parameter as it is no longer
+ needed.
+ * macro.h: Update prototypes to remove comment_char parameter.
+ Fix formatting.
+ * read.c (read_a_source_file, s_irp): Remove comment_char
+ parameter from invocation of functions in macro.c
+
+2002-12-02 Hans-Peter Nilsson <hp@axis.com>
+
+ * read.c (emit_expr) [!WORKING_DOT_WORD]: Initialize x->use_jump.
+
+2002-12-01 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/tc-m68hc11.c (md_begin): Fix qsort warning.
+ (tc_gen_reloc): Mark section param as not used.
+
+2002-12-01 Stephane Carrez <stcarrez@nerim.fr>
+
+ Fix Bug savannah/1825:
+ * config/tc-m68hc11.h (md_relax_frag): Define to support relaxations
+ that are not pc-relative.
+ (m68hc11_relax_frag): Declare.
+
+ * config/tc-m68hc11.c (build_indexed_byte): Use a frag_var to handle
+ the offsetable indexed addressing modes (n,r).
+ (build_insn): Cleanup some locals.
+ (m68hc11_relax_frag): New function imported from tc-cris.c to handle
+ relaxation of difference between two symbols of same section.
+ (md_convert_frag): For INDEXED_OFFSET relaxs, use the displacement
+ only when this is a PC-relative operand and the offset is not absolute.
+ (md_estimate_size_before_relax): Convert the INDEXED_OFFSET,UNDEF frag
+ to INDEXED_OFFSET,STATE_BITS5 when the symbol is absolute; this will
+ be handled by m68hc11_relax_frag.
+
+2002-12-01 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/tc-m68hc11.c (elf_flags): Set default ABI to gcc default
+ (32-bit int, 64-bit double).
+ (md_longopts): New options -mshort, -mlong, -mshort-double and
+ -mlong-double to control the ABI.
+ (md_show_usage): Update.
+ (md_parse_option): Handle new options.
+ * doc/as.texinfo (Overview): Document new options for HC11/HC12.
+
+2002-12-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * symbols.c (report_op_error): New function, broken out of ...
+ (resolve_symbol_value): ... here. Use for both monadic and dyadic
+ operators.
+
+2002-11-30 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * config/tc-sh.c (md_apply_fix3): Take account of fx_offset
+ for BFD_RELOC_32_PLT_PCREL.
+
+2002-11-30 Alan Modra <amodra@bigpond.net.au>
+
+ * dwarf2dbg.c, write.c, config/obj-aout.c, config/obj-coff.c,
+ config/obj-ecoff.c, config/obj-elf.c, config/obj-som.c,
+ config/tc-arm.c, config/tc-arm.h, config/tc-avr.c, config/tc-cris.c,
+ config/tc-d10v.c, config/tc-d10v.h, config/tc-d30v.c, config/tc-d30v.h,
+ config/tc-dlx.c, config/tc-dlx.h, config/tc-fr30.c, config/tc-fr30.h,
+ config/tc-frv.c, config/tc-frv.h, config/tc-hppa.c, config/tc-i370.c,
+ config/tc-i386.c, config/tc-i386.h, config/tc-m32r.c,
+ config/tc-m68hc11.c, config/tc-mcore.c, config/tc-mcore.h,
+ config/tc-mips.c, config/tc-mips.h, config/tc-mn10200.c,
+ config/tc-mn10300.c, config/tc-mn10300.h, config/tc-openrisc.c,
+ config/tc-openrisc.h, config/tc-ppc.c, config/tc-s390.c,
+ config/tc-sh.c, config/tc-sh.h, config/tc-sh64.c, config/tc-tic54x.c,
+ config/tc-v850.c, config/tc-v850.h, config/tc-xstormy16.c,
+ config/tc-xstormy16.h: Replace boolean with bfd_boolean, true with
+ TRUE, false with FALSE. Simplify comparisons of bfd_boolean vars with
+ TRUE/FALSE. Formatting.
+
+2002-11-29 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (do_t_bkpt): If no operand is specified,
+ assume a value of zero.
+ (do_bkpt): Likewise.
+
+2002-11-29 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * config/tc-sh.c (md_apply_fix3): Call S_SET_THREAD_LOCAL
+ for TLS relocations.
+
+2002-11-29 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-ia64.c (md_apply_fix3): Add default case.
+
+2002-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ * symbols.c (S_SET_THREAD_LOCAL): New function.
+ * symbols.h (S_SET_THREAD_LOCAL): New prototype.
+ * config/tc-i386.c (md_apply_fix3): Call S_SET_THREAD_LOCAL
+ for TLS relocations.
+ * config/tc-ia64.c (md_apply_fix3): Likewise.
+ * config/tc-alpha.c (md_apply_fix3): Likewise.
+
+2002-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ * write.c (subsegs_finish): For SEC_MERGE sections pad last fragment
+ to entsize.
+
+2002-11-26 DJ Delorie <dj@redhat.com.
+
+ * dwarf2dbg.c (scale_addr_delta): New.
+ (size_inc_line_addr): Use it.
+ (emit_inc_line_addr): Use it.
+
+2002-11-26 Hans-Peter Nilsson <hp@axis.com>
+
+ * config/tc-cris.c (cris_relax_frag): Fix typo in comment.
+ (md_assemble): Don't pass on branches to constants as relaxable.
+ Tweak comment.
+
+2002-11-25 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * config/tc-tic4x.c (c4x_operands_match): Bugfix in direct mode
+
+2002-11-21 Randolph Chung <randolph@tausq.org>
+
+ * config/tc-hppa.h (tc_frob_symbol): Frob undefined unused symbols
+ only if they have default visibility.
+
+2002-11-21 Richard Henderson <rth@redhat.com>
+
+ * config/tc-alpha.c (alpha_fix_adjustable): Remove redundant
+ S_IS_DEFINED test.
+
+2002-11-21 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-mcore.c (mcore_pool_count): New function.
+ (mcore_cons, mcore_float_cons, mcore_stringer, mcore_fill): Use it.
+
+2002-11-20 Klee Dienes <kdienes@apple.com>
+
+ * config/tc-mcore.c (md_begin): Use a const iterator. Don't
+ coalesce the name fields to use the same pointer.
+
+ * config/tc-sh.c (md_begin): Use a const iterator. Don't coalesce
+ the name fields to use the same pointer.
+ (get_specific): Check for opcodes with the same name using strcmp
+ as well as comparing the pointer.
+
+2002-11-20 Alan Modra <amodra@bigpond.net.au>
+
+ * write.c (adjust_reloc_syms): Don't reduce SEC_MERGE fixups with
+ fx_subsy non-NULL.
+
+2002-11-19 Richard Henderson <rth@redhat.com>
+
+ * config/obj-elf.c (obj_elf_visibility): Overwrite only the
+ visibility portion of st_other.
+
+2002-11-19 Klee Dienes <kdienes@apple.com>
+
+ * config/tc-h8300.c (struct h8_instruction): New type, used to
+ wrap h8_opcodes with length, noperands, idx, and size fields
+ (computed at run-time).
+ (h8_instructions): New variable.
+ (md_begin): Allocate the storage for h8_instructions. Fill
+ h8_instructions with pointers to the appropriate opcode and the
+ correct value for the additional fields.
+ (clever_message): Update to use h8_instructions instead of
+ h8_opcodes.
+ (build_bytes): Ditto.
+ (get_specific): Ditto.
+ (md_assemble): Ditto.
+
+2002-11-19 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.c (tc_s390_fix_adjustable): Re-add patch to prevent
+ adjustments to symbols in merge sections.
+
+2002-11-19 Luke Deller <luked@cse.unsw.edu.au>
+
+ * config/tc-alpha.c (s_alpha_prologue): as_bad when sym is NULL.
+
+2002-11-18 Kevin Buettner <kevinb@redhat.com>
+
+ * dwarf2dbg.h (dwarf2_format): New enum.
+ * dwarf2dbg.c (DWARF2_FORMAT): Provide default definition.
+ (out_debug_line, out_debug_info): Add code for handling 64-bit
+ DWARF 2 formats.
+ * config/tc-mips.h (mips_dwarf2_format): Declare.
+ * config/tc-mips.c (mips_dwarf2_format): New function.
+ * doc/internals.texi (DWARF2_FORMAT): Document.
+
+2002-11-18 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mips.c (s_change_section): Make sure input buffer
+ is not accessed past the end. Don't hand
+ obj_elf_change_section a pointer into the input buffer.
+
+2002-11-18 Alexandre Oliva <aoliva@redhat.com>, Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (tc_gen_reloc): Fix typo in handling of
+ GOT_LO16 on NEWABI.
+
+2002-11-18 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * config/tc-tic4x.c: Fixed proper commandline
+ parameters. Added support for new opcode-list format. General
+ error message fixups.
+ (c4x_inst_add): Reject insn not for our CPU
+ (md_begin): Added matrix for setting the proper opcode-level &
+ device-flags according to cpu type and revision. Rewrite the
+ opcode hasher.
+ (c4x_operand_parse): Fix opcode bug
+ (c4x_operands_match): New function argument. Added dry-run
+ mechanism, that is optional error generation. Added constraint 'i'
+ and 'j'.
+ (c4x_insn_check): Added new function for post-verification of the
+ generated insn.
+ (md_assemble): Check all opcodes before croaking because of an
+ argument mismatch. Need this to be able to fully support
+ ortogonally arguments.
+ (md_parse_options): Revised commandprompt swicthes and added new
+ ones.
+ (md_show_usage): Complete rewrite of printout.
+
+2002-11-16 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * config/tc-tic4x.c: Remove c4x_pseudo_ignore function.
+ (c4x_operands_match): Added check for 8-bits LDF insn. Give
+ warning when using constant direct bigger than 2^16. Add the new
+ arguments.
+
+2002-11-11 Christopher Faylor <cgf@redhat.com>
+
+ * configure.in: Use .gdbinit under Cygwin.
+ * configure: Regenerate.
+
+2002-11-11 Christopher Faylor <cgf@redhat.com>
+
+ * config/tc-i386.h (EXTERN_FORCE_RELOC): Define only if
+ STRICT_PE_FORMAT.
+
+2002-11-11 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * config/tc-tic4x.c: Declare as many functions as possible as
+ static. Maintenance on the general indenting. Removed unnecessary
+ pseudo-ops and added new ones. Removed obsoleted c4x_pseudo_ignore
+ function. Add support for new DSP, TMS320VC33. Fix bug for
+ converting flonum constants.
+ (c4x_do_align): Add proper align handling. Setup align to insert
+ NOP's.
+ (c4x_gen_to_words): Support for extended TI type floats.
+ (md_atof): Proper dumping of multiple-word littlenums.
+ (c4x_atof): Added support for extended TI type floats.
+ (c4x_stringer): Added new function to handle compact strings.
+ (c4x_emit_char): Added new function argument to handle custom
+ length inserts, like single-byte strings.
+ * config/tc-tic4x.h: Add proper align handling with NOP's.
+ * Makefile.am: Added tic4x dependecy
+ * Makefile.in: Regenerate
+
+2002-11-11 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * macro.c (get_any_string): Correct logic for not going beyond end
+ of in->ptr[].
+
+2002-11-10 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/tc-mmix.c (get_putget_operands): Mark both possible
+ operands as invalid at beginning.
+
+ * config/tc-mmix.c (md_convert_frag) <case STATE_GREG_DEF>:
+ Initialize target of fixup to zero.
+
+2002-11-07 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mips.c (macro_build_lui): _gp_disp is not special on
+ NEWABI, but we should still emit HI16_S for non-PIC n32.
+
+2002-11-06 Richard Henderson <rth@redhat.com>
+
+ * config/tc-alpha.c (alpha_validate_fix): Move code ...
+ (alpha_fix_adjustable): ... here.
+ * config/tc-alpha.h (TC_VALIDATE_FIX): Remove.
+
+2002-11-07 Eric Kohl <ekohl@rz-online.de>
+
+ * config/te-pe.h (LEX_AT): Accept at-sign (@) as first character
+ of a label.
+
+2002-11-05 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-mips.c (support_64bit_objects): Check *l before it
+ is freed.
+
+2002-11-04 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/obj-coff.c (obj-coff-section): Set SEC_DATA and
+ SEC_LOAD flags for sections marked as 's'.
+
+2002-11-01 Alan Modra <amodra@bigpond.net.au>
+
+ * write.c (TC_FORCE_RELOCATION_SUB_ABS): Default to zero.
+ (TC_FORCE_RELOCATION_SUB_LOCAL): Likewise when DIFF_EXPR_OK.
+ * doc/internals.texi (TC_FORCE_RELOCATION_SUB_ABS): Document changed
+ default.
+
+ * dep-in.sed: Fix typo.
+
+2002-10-30 Daniel Jacobowitz <drow@mvista.com>
+
+ * configure.in: Update ARM CPU patterns.
+ * configure: Regenerated.
+
+2002-10-29 Daniel Jacobowitz <drow@mvista.com>
+
+ * itbl-lex.l: Use #include <> for generated headers.
+ * itbl-ops.c: Likewise.
+
+2002-10-28 Daniel Jacobowitz <drow@mvista.com>
+
+ * doc/gasp.texi: Fix typo in deprecation note.
+
+2002-10-23 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (tc_gen_reloc): Allow an absolute reference to
+ _GLOBAL_TABLE_OFFSET_ to be converted into a GOT reloc.
+
+2002-10-23 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/tc-mmix.h (mmix_frob_file_before_adjust): Don't declare.
+ (tc_frob_file_before_adjust): Don't define.
+ * config/tc-mmix.c (mmix_frob_local_reloc): Remove unused
+ function.
+ (mmix_frob_file_before_adjust): Remove ineffective function.
+
+2002-10-23 Hans-Peter Nilsson <hp@axis.com>
+
+ * config/tc-cris.c (SIMPLE_EXPR): New macro.
+ (cris_relax_frag): New function.
+ (md_estimate_size_before_relax) <case ENCODE_RELAX
+ (STATE_BASE_PLUS_DISP_PREFIX, STATE_UNDF)>: Pass on unresolved
+ expressions that will become absolute expressions to relaxation.
+ (md_convert_frag) <case ENCODE_RELAX (STATE_BASE_PLUS_DISP_PREFIX,
+ STATE_WORD)>: Expect only absolute expressions. Use the symbol
+ value, not distance to symbol.
+ <case ENCODE_RELAX (STATE_BASE_PLUS_DISP_PREFIX, STATE_BYTE)>:
+ Ditto. Correct placement of fixup.
+ (md_assemble): Use SIMPLE_EXPR when dissecting expressions.
+ (gen_bdap): Ditto.
+ * config/tc-cris.h (cris_relax_frag): Declare.
+ (md_relax_frag): Define.
+
+2002-10-22 Alan Modra <amodra@bigpond.net.au>
+
+ * config/obj-elf.c (special_sections): Use correct types for init
+ array sections.
+ (obj_elf_change_section): Don't mess with init array section type.
+
+2002-10-21 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (mips_need_elf_addend_fixup): Return true
+ for relocs against symbols in a merged section.
+
+2002-10-18 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mips.c (md_begin): Add $fcc registers to the symbol
+ table as register names.
+
+2002-10-18 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/tc-s390.c (md_parse_option): Set s390_arch_size to 32
+ for option -m31.
+
+2002-10-18 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * expr.c (operand): Add support for n.nn flonums.
+
+2002-10-17 Johannes Stezenbach <js@convergence.de>
+
+ * itbl-parse.y (entry): Provide empty action.
+
+2002-10-16 Alan Modra <amodra@bigpond.net.au>
+
+ * configure.in (BFDVER_H): Set and subst.
+ * dep-in.sed: Replace bfdver.h with $(BFDVER_H).
+ * Makefile.am: Run "make dep-am".
+ (BFDVER_H): Define.
+ * configure: Regenerate.
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+
+2002-10-15 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.h (EXTERN_FORCE_RELOC): Define.
+ (MD_APPLY_SYM_VALUE): Define for PE too.
+
+2002-10-14 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ (CPU_OBJ_VALID): sh64 coff is invalid.
+ * as.c: #include "bfdver.h".
+ * Makefile.in: Regenerate.
+ * config.in: Regenerate.
+
+2002-10-14 Momchil Velikov <velco@fadata.bg>
+
+ * config/tc-v850.c (CHECK_): Remove token pasting operator.
+
+2002-10-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * configure.in (mips64vr-elf, mips64vrel-elf): New config.
+ * configure: Regenerate.
+
+2002-10-13 Eric Christopher <echristo@redhat.com>
+ Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mips.c (s_gpdword): New function.
+ (mips_pseudo_table): Add .gpdword.
+ (mips_need_elf_addend_fixup): never for NEWABI.
+ (md_apply_fix3): Don't mark BFD_RELOC64 after GPREL16 or
+ GPREL32 as done.
+ (s_cpadd): Generate .cpadd on NEWABI.
+
+2002-10-12 Elias Athanasopoulos <eathan@otenet.gr>
+
+ * config/tc-ppc.c (ppc_cleanup): Make 'i' unsigned int.
+
+2002-10-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mips.h (mips_relax_frag): Take segment as argument.
+ (md_relax_frag): Adjust macro.
+ * config/tc-mips.c (mips_relax_branch): New variable.
+ (RELAX_BRANCH_ENCODE, RELAX_BRANCH_P, RELAX_BRANCH_LIKELY,
+ RELAX_BRANCH_LINK, RELAX_BRANCH_TOOBAR): New.
+ (RELAX_MIPS16_P): Adjust.
+ (append_insn): Emit branch to non-constant in a frag_var if
+ branch-relaxation is desirable and possible.
+ (OPTION_RELAX_BRANCH, OPTION_NO_RELAX_BRANCH): New options.
+ (OPTION_ELF_BASE): Adjust.
+ (md_parse_option): Handle new options.
+ (md_apply_fix3): Update comment on EMBEDDED_PIC conditional
+ branch relaxation.
+ (relaxed_branch_length): New function.
+ (md_estimate_size_before_relax): Handle branch frags.
+ (mips_relax_frag): Likewise.
+ (md_convert_frag): Handle branch frags. Warn if branch is
+ relaxed.
+
+2002-10-11 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * config/tc-sh.c (sh_force_relocation): Make sure TLS relocs get
+ emitted.
+ (md_apply_fix3): Add TLS relocs.
+ (sh_parse_name): Support @TLSGD, @TLSLDM, @GOTTPOFF, @TPOFF and
+ @DTPOFF.
+
+2002-10-11 Michel Six <msix@ccr.jussieu.fr>
+ Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.c (output_jump): Set fx_signed for loop/jcxz.
+ (md_estimate_size_before_relax): Likewise for 8 bit branches.
+
+Thu Oct 10 14:31:30 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config/tc-sh.c (assemble_ppi): Initialize reg_x / reg_y / reg_n
+ inside loop.
+
+2002-10-09 Richard Shann <richard.shann@superh.com>
+ Stephen Clarke <stephen.clarke@superh.com>
+
+ * config/tc-sh64.c (sh64_target_format): Add support for sh64
+ Linux environment.
+
+2002-10-03 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * contig/tc-sh.c (sh_local_pcrel): New.
+ (sh_force_relocation): Use sh_local_pcrel.
+ (md_pcrel_from_section): Check the relocation type whether it
+ should be resolved locally. Use S_FORCE_RELOC.
+
+2002-10-01 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-mips.h (TC_FORCE_RELOCATION_SUB_SAME): Define.
+ (TC_FORCE_RELOCATION): Tidy arg.
+
+2002-09-30 Gavin Romig-Koch <gavin@redhat.com>
+ Ken Raeburn <raeburn@cygnus.com>
+ Aldy Hernandez <aldyh@redhat.com>
+ DJ Delorie <dj@redhat.com>
+ Michael Meissner <meissner@redhat.com>
+ Eric Christopher <echristo@redhat.com>
+ Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/c-mips.texi: Add entries for -march=vr4120,vr4130,vr4181,
+ vr5400 and vr5500. Add entry for -mfix-vr4122-bugs.
+ * config/tc-mips.c (CPU_HAS_DROR, CPU_HAS_ROR): New macros.
+ (hilo_interlocks): True for CPU_VR5500.
+ (gpr_interlocks, cop_interlocks): True for CPU_VR5400 and CPU_VR5500.
+ (mips_fix_vr4122_bugs): New.
+ (append_insn): Work around 4122 errors if mips_fix_vr4122_bugs.
+ (mips_emit_delays): Likewise.
+ (macro2) [M_DROLI]: Use dror or dror32 if CPU_HAS_DROR.
+ [M_ROLI]: Likewise ror if CPU_HAS_ROR.
+ (validate_mips_insn, mips_ip): Handle '[', ']', 'e' and '%'.
+ (OPTION_FIX_VR4122, OPTION_NO_FIX_VR4122): New options.
+ (md_longopts): Add -mfix-vr4122-bugs and -no-mfix-vr4122-bugs.
+ (OPTION_ELF_BASE): Bump.
+ (md_parse_option): Handle the new options.
+ (mips_cpu_info_table): Add entries for vr4120, vr4130, vr4181,
+ vr5400 and vr5500.
+
+2002-09-29 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-mips.c (md_apply_fix3): Subtract the symbol value
+ twice if howto->pcrel_offset is true.
+
+2002-09-28 Matt Thomas <matt@3am-software.com>
+ Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/tc-vax.c (md_estimate_size_before_relax): Only try to
+ convert undefined references to GOT32/PLT32 if PIC code is
+ requested. Fix comment.
+
+2002-09-27 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * config/tc-sh.c (sh_force_relocation): Return 0 for
+ some PC relative relocations when not relaxing.
+
+2002-09-26 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Add x86-64 TLS relocs.
+ Define them if not BFD_ASSEMBLER.
+ (lex_got): Handle @tlsgd, @dtpoff and @tpoff in 64-bit mode, add
+ @tlsld.
+ (md_apply_fix3): No addend for BFD_RELOC_X86_64_TLSGD,
+ BFD_RELOC_X86_64_TLSLD and BFD_RELOC_X86_64_GOTTPOFF.
+ (tc_gen_reloc): Handle x86-64 TLS relocs.
+
+2002-09-27 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-avr.c (md_apply_fix3): Reinstate code handling pcrel
+ fixups to current or absolute section.
+
+2002-09-26 Jim Wilson <wilson@redhat.com>
+
+ * config/tc-v850.c (v850_offset): Use frag_var instead of frag_now_fix
+ and frag_more.
+
+2002-09-26 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (CPU_HAS_MIPS16): Add mips-lsi-elf as MIPS16
+ capable configuration.
+ (macro_build): Check for MIPS16 capability, not for actual MIPS16 code
+ generation.
+ (mips_ip): Likewise.
+
+2002-09-26 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (append_insn): Fix jump overflow check.
+
+2002-09-24 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.c (process_operands): Warn about "lea" segment
+ overrides.
+
+2002-09-22 Mark Elbrecht <snowball3@softhome.net>
+
+ * write.c: Delete set_segment_vma and prototype. Update all callers.
+
+2002-09-21 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.c (md_apply_fix3): Replace S_IS_EXTERNAL,
+ S_IS_WEAK etc. with S_FORCE_RELOC call. Correct comment.
+ Rename "fseg" to "sym_seg".
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+
+2002-09-20 Nick Clifton <nickc@redhat.com>
+
+ * symbols.c (colon): Do not allow symbols to be created in the
+ absolute section if WORKING_DOT_WORD is not defined and
+ new_broken_words would require a new frag to be created.
+
+2002-09-20 Alan Modra <amodra@bigpond.net.au>
+
+ * expr.c (expr): Simplify foo-foo here.
+ (clean_up_expression): Remove O_subtract code.
+
+ * write.h (struct fix): Add fx_dot_value.
+ (dot_value): Declare.
+ * write.c (dot_value): New var.
+ (fix_new_internal): Save dot_value as fx_dot_value.
+ (fixup_segment): Adjust fx_offset using fx_dot_value.
+ * expr.c (expr): Update dot_value.
+
+2002-09-19 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Handle
+ BFD_RELOC_386_TLS_IE and BFD_RELOC_386_TLS_GOTIE.
+ (BFD_RELOC_386_TLS_IE, BFD_RELOC_386_TLS_GOTIE): Define to 0
+ if not defined.
+ (lex_got): Handle @GOTNTPOFF and @INDNTPOFF.
+ (md_apply_fix3, tc_gen_reloc): Handle BFD_RELOC_386_TLS_IE and
+ BFD_RELOC_386_TLS_GOTIE.
+
+2002-09-19 Richard Henderson <rth@redhat.com>
+
+ * config/tc-alpha.c (md_pcrel_from): Only adjust special for
+ branch type relocs.
+ (alpha_force_relocation): Don't special-case branch type relocs.
+
+2002-09-19 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-m68k.c (select_control_regs): Handle situation where
+ architecture has not yet been selected.
+
+2002-09-18 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (IS_SEXT_32BIT_NUM): Move closer to top of file.
+ (IS_SEXT_16BIT_NUM): New macro.
+ (macro_build_ldst_constoffset): New function, to build a set of
+ instructions to do a load or store from a constant offset relative
+ to a given register.
+ (macro, s_cprestore): Use macro_build_ldst_constoffset to implement
+ .cprestore pseudo-op.
+
+2002-09-18 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (md_apply_fix3): Just return for BFD_RELOC_8.
+
+2002-09-18 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (s_change_section): Fix parsing. Code cleanup.
+
+2002-09-17 Stan Cox <scox@redhat.com>
+
+ * tc-mips.c (load_address): Use BFD_RELOC_MIPS_GOT_DISP for newabi.
+ (macro): Likewise for la. Likewise for ld.
+ (mips_after_parse_args): Make -xgot optional, not the default.
+ (md_apply_fix3): Allow composite relocation to set up gp.
+ (tc_gen_reloc): Allow relaxing for newabi.
+ Relax R_MIPS_CALL16 to R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST if local.
+ Relax R_MIPS_GOT16/R_MIPS_LO16 to R_MIPS_GOT_DISP if local.
+
+2002-09-17 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (md_apply_fix3): Note that an implemented
+ BFD_RELOC_ARM_IMMEDIATE has been done.
+ (tc_gen_reloc): Do not issue reloc number of unimplemented
+ BFD_RELOC_ARM_IMMEDIATE and BFD_RELOC_ARM_OFFSET_IMM relocs -
+ their name is already in the error message - plus remove them
+ from the default case.
+
+ * config/tc-arm.c (do_ldmstm): Warn about unpredictable
+ behavior of instructions.
+
+2002-09-17 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * config/tc-tic4x.c: Add function declarations and ATTRIBUTE_UNUSED.
+ Convert functions to K&R format.
+
+2002-09-17 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (pdr_seg): Define only for ELF.
+ (s_change_section): Remove unused variable. Don't use for nonELF.
+
+2002-09-17 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/obj-elf.c (obj_elf_change_section): Move prototype to
+ obj-elf.h
+ * config/obj-elf.h (obj_elf_change_section): Likewise.
+
+2002-09-16 Elias Athanasopoulos <eathan@otenet.gr>
+
+ * dwarf2dbg.c (out_debug_abbrev): Add support for the DW_AT_name field.
+ (out_debug_info): Likewise.
+
+2002-09-16 Bruno Haible <bruno@clisp.org>
+
+ * config/tc-i386.h (ELF_TARGET_FORMAT): New macro.
+ (TARGET_FORMAT): Use ELF_TARGET_FORMAT instead of "elf32-i386".
+ * config/tc-i386.c (i386_target_format): Likewise.
+ * config/tc-alpha.h (ELF_TARGET_FORMAT): New macro.
+ (TARGET_FORMAT): Use ELF_TARGET_FORMAT instead of "elf64-alpha".
+
+2002-09-13 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-ppc.c (md_assemble): Do not count FAKE operands
+ when deciding if any operands have been skipped.
+
+2002-09-11 Nick Clifton <nickc@redhat.com>
+
+ * NEWS: New TI port supports both C4x and C3x series of DSPs.
+
+ * po/tr.po: Updated Turkish translation.
+
+2002-09-11 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-i386.c (md_apply_fix3): Allow addend for
+ BFD_RELOC_386_TLS_LDO_32, BFD_RELOC_386_TLS_LE and
+ BFD_RELOC_386_TLS_LE_32.
+
+2002-09-05 Jeff Law <law@redhat.com>
+
+ * config/tc-hppa.c (md_apply_fix3): Don't set fx_done for
+ marker relocations such as ENTRY/EXIT.
+ * config/tc-hppa.h (MD_APPLY_SYM_VALUE): Definition applies
+ to both OBJ_ELF and OBJ_SOM.
+
+2002-09-05 Alan Modra <amodra@bigpond.net.au>
+
+ * doc/internals.texi (md_apply_fix3): Expand.
+ (TC_VALIDATE_FIX, TC_FORCE_RELOCATION, TC_FORCE_RELOCATION_ABS,
+ TC_FORCE_RELOCATION_LOCAL, TC_FORCE_RELOCATION_SUB_SAME,
+ TC_FORCE_RELOCATION_SUB_ABS, TC_FORCE_RELOCATION_SUB_LOCAL,
+ TC_VALIDATE_FIX_SUB, MD_APPLY_SYM_VALUE, S_FORCE_RELOC,
+ EXTERN_FORCE_RELOC): Document.
+ (TC_HANDLES_FX_DONE, obj_fix_adjustable): Remove.
+ * as.h: Don't include struc-symbol.h for arc.
+ (IS_ELF): Define.
+ * cgen.c (gas_cgen_md_apply_fix3): Remove *valP fudges and code to
+ subtract absolute symbol.
+ * obj.h (struct format_ops): Add frob_file_before_fix.
+ * subsegs.c (section_symbol): Set BSF_SECTION_SYM flag.
+ * symbols.c (S_FORCE_RELOC): New function.
+ * symbols.h (S_FORCE_RELOC): Declare.
+ * write.c (TC_FORCE_RELOCATION): Change default.
+ (TC_FORCE_RELOCATION_ABS): Define.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Don't define.
+ (TC_FORCE_RELOCATION_LOCAL): Define this instead.
+ (TC_FORCE_RELOCATION_SECTION): Don't define.
+ (TC_FORCE_RELOCATION_SUB_SAME): Define this instead.
+ (TC_FORCE_RELOCATION_SUB_ABS): Define.
+ (TC_FORCE_RELOCATION_SUB_LOCAL): Define.
+ (TC_VALIDATE_FIX_SUB): Define.
+ (TC_FIX_ADJUSTABLE): Don't define.
+ (MD_APPLY_SYM_VALUE): Define this instead.
+ (abs_section_sym): New variable.
+ (adjust_reloc_syms): Use S_FORCE_RELOC. Remove obj_fix_adjustable
+ call. Don't symbol_mark_used_in_reloc here. Simplify link_once tests.
+ Don't put the absolute section sym on fixups here.
+ (fix_segment): New function.
+ (write_relocs): Don't call fixup_segment from here.
+ (write_object_file): Instead call tc_frob_file_before_fix,
+ obj_frob_file_before_fix, and fix_segment prior to symbol table code.
+ Don't output the absolute section symbol.
+ (fixup_segment): Rewrite.
+ * write.h (abs_section_sym): Declare.
+ * config/obj-aout.c (obj_aout_frob_file_before_fix): Rename from
+ obj_aout_frob_file.
+ (aout_format_ops): Adjust to suit.
+ * config/obj-aout.h (obj_frob_file): Don't define.
+ (obj_frob_file_before_fix): Define.
+ (obj_aout_frob_file_before_fix): Rename from obj_aout_frob_file.
+ (S_FORCE_RELOC): Define.
+ * config/obj-bout.h (S_FORCE_RELOC): Define.
+ * config/obj-coff.c (coff_format_ops): Init new field.
+ * config/obj-coff.h: Formatting fixes.
+ (obj_sec_sym_ok_for_reloc): Define.
+ (S_FORCE_RELOC): Define.
+ * config/obj-ecoff.c (ecoff_frob_file_before_fix): Split out ..
+ (ecoff_frob_file): .. from here.
+ (ecoff_format_ops): Add new function.
+ * config/obj-ecoff.h (ecoff_frob_file_before_fix): Declare.
+ (obj_frob_file_before_fix): Define.
+ * config/obj-elf.c (elf_format_ops): Init new field.
+ * config/obj-elf.h (obj_sec_sym_ok_for_reloc): Expand comment.
+ * config/obj-ieee.h: Formatting fixes.
+ (S_FORCE_RELOC): Define.
+ * config/obj-multi.h (obj_frob_file_before_fix): Define.
+ * config/obj-vms.h (S_FORCE_RELOC): Define.
+ * config/tc-alpha.c (md_apply_fix3): Correct GPDISP comment.
+ (alpha_force_relocation): Use S_FORCE_RELOC, and don't return 0
+ for BFD_RELOC_32 and BFD_RELOC_64.
+ (alpha_fix_adjustable): Remove extern and weak tests.
+ (alpha_before_fix): Rename from alpha_adjust_symtab.
+ (alpha_adjust_relocs): Rename from alpha_adjust_symtab_relocs.
+ * config/tc-alpha.h (struct fix, struct alpha_reloc_tag): Declare.
+ (TC_VALIDATE_FIX): Tweak param name.
+ (TC_FORCE_RELOCATION, tc_fix_adjustable): Likewise.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Don't define.
+ (TC_FORCE_RELOCATION_LOCAL): Define this instead.
+ (MD_APPLY_SYM_VALUE): Define.
+ (tc_adjust_symtab): Don't define.
+ (alpha_adjust_symtab): Don't declare.
+ (tc_frob_file_before_fix): Define.
+ (alpha_before_fix): Declare.
+ (TC_INIT_FIX_DATA): Tweak param names.
+ * config/tc-arc.c: Include "struc-symbol.h".
+ (md_pcrel_from): Remove undefined sym fudge.
+ (md_apply_fix3): Remove *valP fudges and code to subtract abs sym.
+ Don't set fx_addnumber.
+ (tc_gen_reloc): Remove spurious fx_addnumber comment.
+ * config/tc-arc.h (MD_APPLY_SYM_VALUE): Define.
+ (EXTERN_FORCE_RELOC): Define.
+ * config/tc-arm.c (md_apply_fix3 <case BFD_RELOC_ARM_GOTPC>): Remove.
+ (tc_gen_reloc): Fudge ARM_GOTPC addend.
+ (arm_validate_fix): Return void.
+ (arm_fix_adjustable <elf version>): Remove extern and weak tests.
+ Add plt and got reloc tests.
+ (arm_force_relocation): Call S_FORCE_RELOC.
+ * config/tc-arm.h (struct fix): Forward declare.
+ (TC_VALIDATE_FIX): No longer set add_symbolP.
+ (arm_validate_fix): Adjust declaration.
+ (TC_FORCE_RELOCATION <pe version): Call S_FORCE_RELOC.
+ (TC_FORCE_RELOCATION): Tweak param name.
+ (TC_INIT_FIX_DATA): Likewise.
+ (obj_fix_adjustable): Don't define.
+ (tc_fix_adjustable): Call arm_fix_adjustable.
+ (TC_FIX_ADJUSTABLE): Don't define.
+ (MD_APPLY_SYM_VALUE): Define.
+ (EXTERN_FORCE_RELOC): Define.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Don't define.
+ (TC_FORCE_RELOCATION_LOCAL): Define this instead.
+ * config/tc-avr.c (md_apply_fix3): Don't cast valP pointer type.
+ Remove *valP fudges and code to subtract abs sym. Don't set
+ fx_addnumber.
+ * config/tc-avr.h: Formatting.
+ (EXTERN_FORCE_RELOC): Define.
+ (MD_APPLY_SYM_VALUE): Define.
+ * config/tc-cris.c (tc_gen_reloc): Don't use fx_addnumber.
+ (md_apply_fix3): Remove code to subtract abs sym.
+ (md_cris_force_relocation): Update comment. Call S_FORCE_RELOC.
+ * config/tc-cris.h (TC_FORCE_RELOCATION): Tweak param name.
+ (IS_CRIS_PIC_RELOC, tc_fix_adjustable): Likewise.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Don't define.
+ (TC_FORCE_RELOCATION_LOCAL): Define this instead.
+ (tc_fix_adjustable): Remove extern, weak tests.
+ * config/tc-d10v.c (tc_gen_reloc): Don't fiddle address of
+ BFD_RELOC_VTABLE_INHERIT relocs. Don't use fx_addnumber.
+ (md_apply_fix3): Don't cast valP pointer type. Remove *valP fudges
+ and code to subtract abs sym.
+ (d10v_fix_adjustable): Remove extern, weak, SEC_MERGE tests.
+ (d10v_force_relocation): Call S_FORCE_RELOC.
+ * config/tc-d10v.h: Don't include write.h.
+ (struct fix): Instead, forward declare.
+ (MD_PCREL_FROM_SECTION): Tweak param names.
+ (md_pcrel_from_section): Use "struct fix" instead of "fixS".
+ (d10v_fix_adjustable): Likewise.
+ (obj_fix_adjustable): Don't define.
+ (tc_fix_adjustable): Define.
+ (TC_FORCE_RELOCATION): Tweak param name.
+ (MD_APPLY_SYM_VALUE): Define.
+ (EXTERN_FORCE_RELOC): Define.
+ * config/tc-d30v.c (tc_gen_reloc): Don't use fx_addnumber.
+ (md_apply_fix3): Don't cast valP pointer type. Remove *valP fudges
+ and code to subtract abs sym.
+ * config/tc-d30v.h: Don't include write.h.
+ (struct fix): Instead, forward declare.
+ (MD_PCREL_FROM_SECTION): Tweak param names.
+ (md_pcrel_from_section): Use "struct fix" instead of "fixS".
+ (MD_APPLY_SYM_VALUE): Define.
+ (EXTERN_FORCE_RELOC): Define.
+ * config/tc-dlx.c (md_dlx_force_relocation): Call S_FORCE_RELOC.
+ (md_dlx_fix_adjustable): Don't test for NULL fx_addsy.
+ (md_apply_fix3): No need to test fx_pcrel before setting fx_done.
+ (tc_gen_reloc): Don't fiddle with BFD_RELOC_VTABLE_INHERIT relocs.
+ Adjust the address for BFD_RELOC_VTABLE_ENTRY, not the addend.
+ Don't use fx_addnumber.
+ * config/tc-dlx.h: Don't include write.h.
+ (md_convert_frag): We're not alpha twice over.
+ (EXTERN_FORCE_RELOC): Define.
+ (obj_fix_adjustable): Don't define.
+ (tc_fix_adjustable): Define.
+ (TC_FIX_ADJUSTABLE): Don't define.
+ (MD_APPLY_SYM_VALUE): Define.
+ (LOCAL_LABELS_DOLLAR): Undef always.
+ * config/tc-fr30.c (fr30_force_relocation): Call S_FORCE_RELOC.
+ (fr30_fix_adjustable): Remove extern, weak tests.
+ * config/tc-fr30.h (MD_APPLY_SYM_VALUE): Define.
+ (obj_fix_adjustable): Don't define.
+ (tc_fix_adjustable): Define.
+ (struct fix): Forward declare.
+ (MD_PCREL_FROM_SECTION): Tweak param name. Remove duplicate.
+ * config/tc-frv.c (frv_force_relocation): Call S_FORCE_RELOC.
+ (frv_fix_adjustable): Don't do extern, weak tests.
+ * config/tc-frv.h (MD_APPLY_SYM_VALUE): Define.
+ (TC_FIX_ADJUSTABLE): Don't define.
+ (obj_fix_adjustable): Don't define.
+ (tc_fix_adjustable): Define.
+ (struct fix): Forward declare.
+ (MD_PCREL_FROM_SECTION): Tweak param name. Remove duplicate.\
+ * config/tc-h8300.c (md_apply_fix3): Don't cast valP pointer type.
+ * config/tc-h8300.h (struct fix): Forward declare.
+ (EXTERN_FORCE_RELOC): Define.
+ * config/tc-hppa.c (md_apply_fix3): Remove subtraction of sym value.
+ (hppa_fix_adjustable): Don't test extern or weak. Don't
+ symbol_mark_used_in_reloc.
+ (hppa_force_relocation): Use S_FORCE_RELOC instead of S_IS_EXTERNAL
+ and S_IS_WEAK.
+ * config/tc-hppa.h (EXTERN_FORCE_RELOC): Define
+ (TC_FORCE_RELOCATION, TC_INIT_FIX_DATA): Tweak param name.
+ (TC_FORCE_RELOCATION_SECTION): Don't define.
+ (MD_APPLY_SYM_VALUE): Define.
+ * config/tc-i370.c (md_apply_fix3): Remove *valP fudges and code
+ to subtract abs sym.
+ * config/tc-i370.h: Remove ifdef OBJ_ELF tests.
+ (MD_APPLY_SYM_VALUE): Define.
+ (MD_PCREL_FROM_SECTION): Tweak param name.
+ * config/tc-i386.c (tc_i386_fix_adjustable): Remove weak, extern tests.
+ (md_apply_fix3): Test fx_addsy, not fx_pcrel.
+ (i386_force_relocation): New function.
+ * config/tc-i386.h (TC_COFF_FIX2RTYPE): Tweak param name.
+ (TC_VALIDATE_FIX): Likewise.
+ (TC_FIX_ADJUSTABLE): Don't define.
+ (MD_APPLY_SYM_VALUE): Define.
+ (TC_FORCE_RELOCATION <elf version>): Call i386_force_relocation.
+ (i386_force_relocation): Declare.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Don't define.
+ (TC_FORCE_RELOCATION_LOCAL): Define this instead.
+ (TC_FORCE_RELOCATION <coff version>): Call S_FORCE_RELOC.
+ * config/tc-i860.c (md_apply_fix3): Don't cast valP pointer type.
+ * config/tc-i860.h (MD_APPLY_SYM_VALUE): Define.
+ (EXTERN_FORCE_RELOC): Define.
+ * config/tc-i960.c (reloc_callj): Remove declaration. Return false.
+ (md_apply_fix3): Don't cast valP pointer type. Move code here from
+ old fixup_segment. No need to test fx_pcrel before setting fx_done.
+ (i960_validate_fix): Remove add_symbolPP arg and add_symbolP macro.
+ Use fx_addsy instead of add_symbolP, as_bad_where instead of as_bad.
+ Remove #if 0 code. Invert return boolean.
+ * config/tc-i960.h (TC_COUNT_RELOC): Tweak param name.
+ (TC_COFF_FIX2RTYPE, TC_ADJUST_RELOC_COUNT, TC_VALIDATE_FIX): Likewise.
+ (tc_headers_hook, tc_coff_fix2rtype): Remove declaration.
+ (tc_coff_sizemachdep): Prototype.
+ (i960_handle_align): Likewise.
+ (i960_validate_fix): Adjust declaration.
+ (reloc_callj): Likewise.
+ (EXTERN_FORCE_RELOC): Define.
+ (TC_FORCE_RELOCATION_SUB_SAME): Define.
+ (TC_FORCE_RELOCATION_ABS): Define.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Don't define.
+ (TC_FORCE_RELOCATION_LOCAL): Define this instead.
+ (TC_FIX_ADJUSTABLE): Don't define.
+ (MD_APPLY_SYM_VALUE): Define.
+ * config/tc-ia64.c (ia64_force_relocation): Call S_FORCE_RELOC.
+ * config/tc-ia64.h (MD_APPLY_SYM_VALUE): Define.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Don't define.
+ (TC_FORCE_RELOCATION_LOCAL): Define this instead.
+ * config/tc-ip2k.c (ip2k_force_relocation): Call S_FORCE_RELOC.
+ * config/tc-ip2k.h (MD_APPLY_FIX3): Don't define.
+ (MD_APPLY_SYM_VALUE): Define.
+ (EXTERN_FORCE_RELOC): Define.
+ (TC_FORCE_RELOCATION): Tweak param name.
+ * config/tc-m32r.c (m32r_force_relocation): Call S_FORCE_RELOC.
+ (m32r_fix_adjustable): Don't test extern, weak.
+ * config/tc-m32r.h (MD_PCREL_FROM_SECTION): Tweak param name.
+ (MD_APPLY_SYM_VALUE): Define.
+ (obj_fix_adjustable): Don't define.
+ (tc_fix_adjustable): Define.
+ (tc_frob_file): Don't define.
+ (tc_frob_file_before_fix): Define.
+ (EXTERN_FORCE_RELOC): Define.
+ * config/tc-m68hc11.c (tc_gen_reloc): Set addend to zero. Adjust
+ BFD_RELOC_VTABLE_ENTRY address.
+ (tc_m68hc11_force_relocation): Call S_FORCE_RELOC.
+ (tc_m68hc11_fix_adjustable): Don't test relaxable_symbol.
+ (md_apply_fix3): Remove *valP fudges and code to subtract abs sym.
+ Remove duplicated fx_done code.
+ * config/tc-m68hc11.h (MD_APPLY_SYM_VALUE): Define.
+ (EXTERN_FORCE_RELOC): Define.
+ * config/tc-m68k.c (tc_m68k_fix_adjustable): Don't test
+ relaxable_symbol.
+ * config/tc-m68k.h (TC_COFF_FIX2RTYPE): Tweak param name.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Don't define.
+ (TC_FIX_ADJUSTABLE): Don't define.
+ (EXTERN_FORCE_RELOC): Define.
+ (MD_APPLY_SYM_VALUE): Define.
+ (TC_FORCE_RELOCATION): Call S_FORCE_RELOC.
+ * config/tc-mcore.c (md_apply_fix3): Don't cast valP pointer type.
+ Remove fx_addsy tests.
+ (mcore_force_relocation): Call S_FORCE_RELOC.
+ (mcore_fix_adjustable): Don't test fx_addsy.
+ * config/tc-mcore.h (MD_PCREL_FROM_SECTION): Tweak param name.
+ (EXTERN_FORCE_RELOC): Define.
+ (obj_fix_adjustable): Don't define.
+ (tc_fix_adjustable): Define.
+ (MD_APPLY_SYM_VALUE): Define.
+ * config/tc-mips.c (enum mips_pic_level): Move to tc-mips.h.
+ (mips_pic): No longer static.
+ (mips_force_relocation): Call S_FORCE_RELOC.
+ (mips_fix_adjustable): Remove extern, weak tests.
+ * config/tc-mips.h (enum mips_pic_level): Declare.
+ (mips_pic): Declare.
+ (tc_frob_file): Don't define.
+ (tc_frob_file_before_fix): Define this instead.
+ (EXTERN_FORCE_RELOC): Define.
+ * config/tc-mmix.c (md_apply_fix3): Replace real_reg_section tests
+ with reg_section tests. Set fx_done instead of calling
+ symbol_clear_used_in_reloc on bad relocs.
+ (tc_gen_reloc): Zero fx_addsy on bad relocs.
+ (mmix_force_relocation): Remove weak sym test. Call S_FORCE_RELOC.
+ (mmix_adjust_symtab): Simplify list handling. Abort on any
+ nonsense.
+ * config/tc-mmix.h (tc_fix_adjustable): Remove weak tests. Check
+ BFD_RELOC_MMIX_LOCAL.
+ (tc_frob_symbol): Keep user defined syms in reg_section. Don't punt.
+ (EXTERN_FORCE_RELOC): Define.
+ (MD_PCREL_FROM_SECTION): Tweak param name.
+ (tc_frob_file): Don't define.
+ (tc_frob_file_before_fix): Define this instead.
+ * config/tc-mn10300.c (mn10300_force_relocation): Call S_FORCE_RELOC.
+ Remove SEC_CODE checks.
+ (mn10300_fix_adjustable): Remove extern and weak tests.
+ * config/tc-mn10300.h (EXTERN_FORCE_RELOC): Define.
+ (TC_FORCE_RELOCATION): Tweak param name.
+ (obj_fix_adjustable): Don't define.
+ (TC_FORCE_RELOCATION_SUB_SAME): Define to handle SEC_CODE.
+ * config/tc-ns32k.h (TC_FIX_DATA_PRINT): Tweak param name.
+ * config/tc-openrisc.c (openrisc_force_relocation): Call S_FORCE_RELOC.
+ (openrisc_fix_adjustable): Don't test fx_addsy.
+ * config/tc-openrisc.h (MD_APPLY_SYM_VALUE): Define.
+ (obj_fix_adjustable): Don't define.
+ (tc_fix_adjustable): Define this instead.
+ (MD_PCREL_FROM_SECTION): Remove duplicate. Tweak param name.
+ * config/tc-or32.c (md_apply_fix3): Don't cast valP pointer type.
+ (tc_gen_reloc): Don't fiddle with BFD_RELOC_VTABLE_INHERIT relocs.
+ Adjust the address for BFD_RELOC_VTABLE_ENTRY, not the addend.
+ * config/tc-or32.h (EXTERN_FORCE_RELOC): Define.
+ (MD_APPLY_SYM_VALUE): Define.
+ * config/tc-pj.c (md_apply_fix3): Don't cast valP pointer type.
+ Don't subtract symbol value.
+ * config/tc-pj.h (md_pcrel_from): Tweak param name.
+ (EXTERN_FORCE_RELOC): Define.
+ (TC_FORCE_RELOCATION): Call S_FORCE_RELOC.
+ (MD_APPLY_SYM_VALUE): Define.
+ (obj_fix_adjustable): Don't define.
+ (tc_fix_adjustable): Define this instead.
+ * config/tc-ppc.c (ppc_frob_symbol <coff version>): Ignore absolute
+ section sym.
+ (ppc_force_relocation <coff version>): Call S_FORCE_RELOC.
+ (ppc_force_relocation <elf version>): New.
+ (ppc_fix_adjustable <elf version>): Remove extern and weak tests.
+ (md_apply_fix3): Don't subtract symbol values for ELF. Update
+ comments. Don't subtract fx_subsy as that is already done.
+ * config/tc-ppc.h (tc_fix_adjustable): Tweak param name.
+ (MD_PCREL_FROM_SECTION): Likewise.
+ (TC_FORCE_RELOCATION): Define for both ELF and XCOFF as calling
+ ppc_force_relocation.
+ (TC_FORCE_RELOCATION_SECTION): Delete.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Don't define.
+ (TC_FORCE_RELOCATION_LOCAL): Define this instead.
+ (MD_APPLY_SYM_VALUE): Define.
+ * config/tc-s390.c: #include "dwarf2dbg.h".
+ (s390_insn): Remove excess parens.
+ (tc_s390_fix_adjustable): Remove extern, weak, SEC_MERGE tests.
+ (tc_s390_force_relocation): Call S_FORCE_RELOC.
+ (md_apply_fix3): Add ATTRIBUTE_UNUSED on "seg". Abort when fx_subsy
+ non-NULL. Don't subtract off fx_addsy value.
+ * config/tc-s390.h (TC_RELOC_RTSYM_LOC_FIXUP): Don't define.
+ (TC_FORCE_RELOCATION, MD_PCREL_FROM_SECTION): Tweak param name.
+ (TC_FIX_ADJUSTABLE): Don't define.
+ (MD_APPLY_SYM_VALUE): Define.
+ * config/tc-sh.c (SWITCH_TABLE_CONS): Move to tc-sh.h.
+ (SWITCH_TABLE): Likewise.
+ (sh_force_relocation): Call S_FORCE_RELOC.
+ (sh_fix_adjustable): Remove "return 1" cases handled by the default.
+ Replace TC_RELOC_RTSYM_LOC_FIXUP with reloc type tests.
+ (md_apply_fix3 <case BFD_RELOC_32_PLT_PCREL>): Simplify,
+ fx_addnumber is zero on entry. Save val in fx_addnumber.
+ (tc_gen_reloc): Don't subtract fx_subsy.
+ * config/tc-sh.h (struct fix): Move.
+ (obj_fix_adjustable): Don't define.
+ (tc_fix_adjustable): Define this instead.
+ (TC_FIX_ADJUSTABLE): Don't define.
+ (MD_APPLY_SYM_VALUE): Define.
+ (SWITCH_TABLE_CONS): Define.
+ (SWITCH_TABLE): Define.
+ (TC_FORCE_RELOCATION_SUB_SAME): Define.
+ (TC_VALIDATE_FIX_SUB): Define.
+ (MD_PCREL_FROM_SECTION): Tweak param name.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Don't define.
+ (TC_FORCE_RELOCATION_LOCAL): Define this instead.
+ (TC_FORCE_RELOCATION_SUB_ABS): Define.
+ * config/tc-sh64.h (TC_RELOC_RTSYM_LOC_FIXUP): Don't define.
+ (TC_FORCE_RELOCATION_LOCAL): Define this instead.
+ (TC_FORCE_RELOCATION_SUB_SAME): Define.
+ (TC_VALIDATE_FIX_SUB): Define.
+ (MD_PCREL_FROM_SECTION): Tweak param name.
+ * config/tc-sparc.c (md_apply_fix3): Don't subtract off symbol value.
+ (tc_gen_reloc): Use S_FORCE_RELOC.
+ (elf32_sparc_force_relocation): Call S_FORCE_RELOC.
+ * config/tc-sparc.h (TC_FORCE_RELOCATION <coff version>): Remove.
+ (TC_FORCE_RELOCATION_ABS): Define this instead.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Don't define.
+ (TC_FORCE_RELOCATION_LOCAL): Define this instead.
+ (tc_fix_adjustable): Remove extern and weak tests. Use S_FORCE_RELOC.
+ (MD_APPLY_SYM_VALUE): Define.
+ (TC_FIX_DATA_PRINT): Tweak param name.
+ * config/tc-tic30.c (USE_STDOUT): Don't define.
+ (md_parse_option): Remove stupid debug code.
+ (tc_gen_reloc): Don't use fx_addnumber.
+ * config/tc-v850.c (v850_fix_adjustable): Remove extern and weak tests.
+ (v850_force_relocation): Remove weak test. Call S_FORCE_RELOC.
+ * config/tc-v850.h (obj_fix_adjustable): Don't define.
+ (tc_fix_adjustable): Define this instead.
+ (TC_FIX_ADJUSTABLE): Don't define.
+ (MD_APPLY_SYM_VALUE): Define this instead.
+ (TC_FORCE_RELOCATION, MD_PCREL_FROM_SECTION): Tweak param name.
+ * config/tc-vax.h (TC_RELOC_RTSYM_LOC_FIXUP): Don't define.
+ (TC_FIX_ADJUSTABLE): Don't define.
+ (MD_APPLY_SYM_VALUE): Define this instead.
+ (tc_fix_adjustable): Remove extern and weak tests.
+ * config/tc-w65.h (struct fix): Forward declare.
+ * config/tc-xstormy16.c (xstormy16_force_relocation): Call
+ S_FORCE_RELOC.
+ (xstormy16_fix_adjustable): Remove extern and weak tests. Don't
+ call xstormy16_force_relocation; Instead test for FPTR16 reloc.
+ (xstormy16_md_apply_fix3): Remove *valP fudges and code to subtract
+ absolute symbol.
+ * config/tc-xstormy16.h (MD_APPLY_FIX3): Don't define.
+ (MD_APPLY_SYM_VALUE): Define.
+ (obj_fix_adjustable): Don't define.
+ (tc_fix_adjustable): Define this instead.
+ (MD_PCREL_FROM_SECTION): Remove duplicate. Tweak param name.
+
+2002-09-04 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (ppc_frob_symbol): Formatting, warning fix.
+ (ppc_fix_adjustable <coff version>): Cleanup.
+
+ * config/tc-ppc.c (PPC_HIGHER, PPC_HIGHEST): Fix warning.
+ (md_parse_option): No -a64 without BFD64.
+ (ppc_set_cpu): Select appropriate cpu when ppc_obj64.
+ (ppc_arch): Use bfd_mach_rs6k for bfd_arch_rs6000.
+
+2002-09-04 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-ppc.c (md_begin): Do not insert non-BookE32
+ instructions into the hash table if the target cpu is the BookE32.
+
+2002-08-31 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * read.c (do_align): Use ATTRIBUTE_UNUSED_LABEL for label, not
+ ATTRIBUTE_UNUSED.
+
+2000-08-28 Catherine Moore <clm@redhat.com>
+
+ * tc-v850.c (v850_relax): Declare.
+ (v850_longcode): New routine.
+ (v850_handle_align): New routine.
+ (md_pseudo_table): Add longcall and longjump.
+ (md_parse_option): Check for relax option.
+ (tc_gen_reloc): Handle BFD_RELOC_V850_LONGCALL,
+ BFD_RELOC_V850_LONGJUMP, and BFD_RELOC_V850_ALIGN.
+ (md_apply_fix3): Likewise.
+ (v850_force_relocation): Likewise.
+ (v850_comm): Change the current section.
+ (md_assemble): Ensure that the correct value is put in the
+ fixup.
+ (v850_sdata, v850_tdata, v850_zdata, v850_sbss, v850_tbss,
+ v850_zbss, v850_rosdata, v850_rozdata): Fix section book keeping.
+ Remove redundant v850ea support.
+ * tc-v850.h (HANDLE_ALIGN): Define.
+ (v850_handle_align): Declare.
+ * doc/c-v850.c: Document -mrelax, .longcall and .longjump.
+
+2002-08-28 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * configure.in: Add tic4x-coff* and c4x-coff*-coff-coff targets.
+ * configure: Regenerate.
+ * NEWS: Mention new port.
+
+2002-08-28 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/obj-coff.c: Add sdef definition.
+ * config/obj-coff.h: Add tic4x include file and set
+ target format.
+ * config/tc-tic4x.c: New file.
+ * config/tc-tic4x.h: New file.
+
+2002-08-28 Alan Modra <amodra@bigpond.net.au>
+
+ * write.c (BFD_FAST_SECTION_FILL): Remove unused macro.
+ (TC_ADJUST_RELOC_COUNT): Tweak param name.
+ (TC_FORCE_RELOCATION, TC_FORCE_RELOCATION_SECTION): Likewise.
+ (TC_FIX_ADJUSTABLE, MD_PCREL_FROM_SECTION): Likewise.
+ (RELOC_ENUM): Define.
+ (fix_new_internal): Use RELOC_ENUM.
+ (fix_new, fix_new_exp): Likewise.
+ (adjust_reloc_syms): Comment. Remove unnecessary tests on sym != NULL.
+ Replace gotos with continue.
+ (write_relocs): Formatting. Avoid symbol loops in
+ RELOC_EXPANSION_POSSIBLE case too. Report bfd_reloc_outofrange
+ errors, and error number in other cases.
+ (fixup_segment): Remove param names from prototype. Rename
+ "this_segment_type" to "this_segment". Update linkrelax comment.
+ Remove "size, "place" and "where" local vars. Formatting. Update
+ "no symbol" comment. Remove #if 0 and #if 1.
+
+ * app.c (do_scrub_chars): Don't test IGNORE_NONSTANDARD_ESCAPES. Tidy.
+
+2002-08-27 Alan Modra <amodra@bigpond.net.au>
+
+ * dwarf2dbg.c: Always include dwarf2dbg.h.
+ (dwarf2_directive_file): Adjust dummy version args.
+ * ecoff.c (ecoff_directive_weakext): Add ATTRIBUTE_UNUSED.
+ * expr.c (clean_up_expression <O_subtract>): Allow subtraction
+ when symbol values differ.
+ * read.c (do_align): Add ATTRIBUTE_UNUSED to label.
+ (pseudo_set <O_subtract>): Remove unnecessary segment test.
+ * config/obj-bout.c (obj_pseudo_table): Warning fix.
+
+2002-08-26 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-w65.c (md_section_align): Fix typo.
+ (md_parse_option): Return 0, not 1.
+
+2002-08-22 Nick Clifton <nickc@redhat.com>
+
+ * doc/as.texinfo (Section): Note that if '@' is a comment
+ character then another symbol is used to prefix the section's
+ type.
+
+2002-08-22 Christian Groessler <chris@groessler.org>
+
+ * config/tc-z8k.c (get_operands): Adjust ptr variable also in
+ "case 0" case.
+
+2002-08-12 Graeme Peterson <gp@qnx.com>
+
+ * configure.in: Add support for sh-**-nto* target.
+ * configure: Regenerate.
+
+2002-08-21 Nitin Gupta <niting@noida.hcltech.com>
+
+ * config/tc-h8300.h (TC_LINKRELAX_FIXUP): Define.
+
+2002-08-21 Elena Zannoni <ezannoni@redhat.com>
+
+ * config/tc-ppc.c (ppc_cleanup): Do something only if format
+ is ELF.
+ (ppc_apuinfo_section_add): Define only if format is ELF.
+ (md_assemble): Emit APUinfo section only if format is ELF.
+ Fix formatting.
+
+2002-08-21 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-arc.c (md_pseudo_table <dwarf2_directive_file>): Cast.
+ * config/tc-frv.c: Likewise.
+ * config/tc-hppa.c: Likewise.
+ * config/tc-ia64.c: Likewise.
+ * config/tc-ip2k.c: Likewise.
+ * config/tc-m68hc11.c: Likewise.
+ * config/tc-m68k.c: Likewise.
+ * config/tc-mmix.c: Likewise.
+ * config/tc-mn10300.c: Likewise.
+ * config/tc-sh.c: Likewise.
+ * config/tc-sparc.c: Likewise.
+ * config/tc-v850.c: Likewise.
+
+2002-08-20 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (macro2): Implement rotates by zero using shifts
+ by zero.
+
+2002-08-19 Elena Zannoni <ezannoni@redhat.com>
+
+ From matthew green <mrg@redhat.com>
+
+ * config/tc-ppc.c (PPC_OPCODE_CLASSIC): Enable this everywhere
+ PPC_OPCODE_PPC is, except for BookE architectures.
+ (md_parse_option): Add support for -mspe.
+ (md_show_usage): Add -mspe.
+ (md_parse_option): Add support for -me500 and
+ -me500x2 to generate code for Motorola e500 core complex.
+ (md_show_usage): Add -me500 and -me500x2.
+
+ (PPC_APUINFO_ISEL, PPC_APUINFO_PMR, PPC_APUINFO_RFMCI,
+ PPC_APUINFO_CACHELCK, PPC_APUINFO_SPE, PPC_APUINFO_EFS,
+ PPC_APUINFO_BRLOCK): New macros.
+
+ (ppc_cleanup): New function.
+ (ppc_apuinfo_section_add): New function.
+ (APUID): New macro.
+ (md_assemble): Collect info and write the APUinfo section.
+
+ * config/tc-ppc.h (md_cleanup): Define.
+ (ppc_cleanup): Export.
+ (ELF_TC_SPECIAL_SECTIONS): Add .PPC.EMB.apuinfo section.
+
+2002-08-17 Stan Cox <scox@redhat.com>
+
+ * config/obj-elf.c (obj_elf_change_section): Make non-static.
+ config/tc-mips.c (s_change_section): New function to support
+ IRIX .section pseudo-op.
+
+2002-08-16 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-v850.c (md_assemble): Fix assembling of "callt 0x3f".
+
+2002-08-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mips.c (macro_build_jalr): Make sure we generate
+ the fix-up against on the right frag.
+ (s_cpsetup): Likewise. Parse third argument as expression, to
+ handle global symbols and forward/backward labels correctly.
+
+2002-08-14 Nick Clifton <nickc@redhat.com>
+
+ * read.c (stringer): Catch attempts to create strings in the abs
+ section.
+
+ * config/tc-alpha.c: Fix compiling for COFF targets.
+ Some minor formatting tidyups.
+
+2002-08-13 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/tc-m68hc11.h (MD_PCREL_FROM_SECTION): Remove.
+ (TC_HANDLES_FX_DONE): Define to let md_apply_fix3 set fx_done flag
+ according to the reloc.
+ (tc_fix_adjustable, tc_m68hc11_fix_adjustable): Define.
+ (TC_FORCE_RELOCATION): Define.
+ (tc_m68hc11_force_relocation): Declare.
+
+ * config/tc-m68hc11.c (md_pseudo_table): Add relax command.
+ (s_m68hc11_relax): New function for relax group.
+ (build_insn, build_jump_insn): Emit a M68HC11_RL_JUMP reloc at
+ beginning of jump instruction.
+ (md_pcrel_from): Rename from md_pcrel_from_section and fix
+ address computation.
+ (tc-gen_reloc): Update.
+ (md_estimate_size_before_relax): Create the BFD_RELOC_16_PCREL as
+ PC-relative fixup.
+ (tc_m68hc11_force_relocation): New function, handle new relocs.
+ (tc_m68hc11_fix_adjustable): New to make sure there are enough
+ reloc for the linker relax pass.
+ (md_apply_fix3): Handle M68HC11_RL_JUMP, M68HC11_RL_GROUP
+ and VTABLE relocs.
+
+2002-08-13 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/tc-m68hc11.c (m68hc11_elf_final_processing): New function.
+ (md_pseudo_table): Add .mode, .far and .interrupt pseudo op.
+ (s_m68hc11_mode): New function for .mode pseudo op.
+ (s_m68hc11_mark_symbol): New function for .far and .interrupt
+ pseudo op.
+ * config/tc-m68hc11.h (elf_tc_final_processing): Define.
+ (m68hc11_elf_final_processing): Declare.
+
+2002-08-13 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/tc-m68hc11.c (md_begin): Take into account additional
+ page operand for call instruction.
+ (print_opcode_format): Likewise.
+ (check_range): Likewise for page range checking.
+ (get_operand): Don't skip a possible comma in operands.
+ (fixup8): Generate BFD_RELOC_M68HC11_PAGE reloc.
+ (fixup16): Likwise with BFD_RELOC_M68HC11_LO16.
+ (fixup24): New to handle call reloc.
+ (build_insn): Handle missing page operand for call instruction.
+ (find): Likewise.
+ (md_apply_fix3): Take into account new relocs.
+ (get_operand): Fix the mode for indexed indirect addressing.
+ (build_indexed_byte): Fix post index byte for indexed indirect mode.
+
+2002-08-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (mips_ip): Don't work out the value of
+ constant %hi()s here.
+
+2002-08-10 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Test OUTPUT_FLAVOR
+ for ELF, and don't bother checking ELF relocs when non-ELF.
+ (i386_immediate): Allow absolute_section expressions for aout.
+ (i386_displacement): Likewise. Also test bfd_is_com_section.
+ (md_estimate_size_before_relax): Test OUTPUT_FLAVOR for ELF.
+ (md_apply_fix3): Hack for bfd_install_relocation when fx_pcrel,
+ not when fx_addsy. Remove dead code.
+
+2002-08-09 Graeme Peterson <gp@qnx.com>
+
+ * configure.in: Add support for ppc-*-nto* target.
+ * configure: Regenerate.
+
+2002-08-09 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.h: Reorganize.
+
+2002-08-09 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * config/tc-mips.c (macro): Handle a register plus a 16-bit
+ immediate offset in "dla" and "la" expansions.
+
+2002-08-09 Alan Modra <amodra@bigpond.net.au>
+
+ * configure.in: bfd_gas=yes for all i386 targets. Formatting.
+ Remove "bfd_gas=yes" from target table when covered later.
+ Consolidate some entries.
+ * configure: Regenerate
+
+2002-08-09 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-i386.c (output_insn): Save frag_now and frag_now_fix ()
+ at start of insn, pass it to output_disp and output_imm.
+ (output_disp): Added arguments. If _GLOBAL_OFFSET_TABLE_ is seen
+ in displacement for R_386_32 reloc, use R_386_GOTPC and compute
+ properly addend.
+ (output_imm): Added arguments. Compute properly addend for
+ R_386_GOTPC.
+ (md_apply_fix3): Remove R_386_GOTPC handling.
+
+2002-08-06 George France <france@handhelds.org>
+
+ * config/tc-alpha.c (cpu_types): Enabled ev67, ev68, -m21264a
+ and m21264b processor names and cpu types.
+ * doc/c-alpha.texi: Documented new types.
+
+2002-08-06 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (md_apply_fix3): Adjust 16 bit XCOFF reloc offset.
+
+2002-08-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-mips.c (tc_gen_reloc): Extend GP-relative addend
+ handling to BFD_RELOC_MIPS16_GPREL.
+
+2002-08-01 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (add_to_lit_pool): Ensure that offset to literal
+ pool is computed using signed arithmetic so that proper sign
+ extension is performed if X_add_number is a 64-bit integer.
+
+2002-08-01 H.J. Lu <hjl@gnu.org>
+ Daniel Jacobowitz <drow@mvista.com>
+
+ * dwarf2dbg.c (dwarf2_finish): Don't emit unreferenced
+ .debug_line section unless it has line information.
+
+2002-07-31 Ian Dall <ian@sibyl.beware.dropbear.id.au>
+
+ * config/tc-ns32k.h (md_pcrel_adjust): Supply prototype.
+ * config/tc-ns32k.c (convert_iif, md_parse_option, md_show_usage):
+ Allow default displacement size to be an option "--disp-size-default".
+ (md_number_to_disp): Make error messages include value. Use %d to
+ print integers, not %s.
+ (fix_new_ns32k): Conditionally set fx_no_overflow so we don't
+ get duplicate messages sometimes.
+ (convert_iif): Grow frag to max possible instruction size. Avoid
+ creating unnecessary fixes.
+ (md_number_to_field) Add prototype.
+ (encode_operand, parse, convert_iif, md_fix_pcrel_adjust): Add
+ prototypes and make static.
+ (struct addr_mode): Make mode and scaled_mode explicitly signed.
+ (evaluate_expr): Use resultP argument instead of exprP global.
+ (get_addr_mode): Quiten compiler warnings.
+ (encode_operand): eliminate unused variables. Quiten compiler
+ warnings. Eliminate nul character in format strings.
+ (parse): argc is unsigned.
+ (reloc): Type cast index to quieten compiler.
+ (md_pcrel_adjust, md_apply_fix3): Remove unused variable.
+ (md_convert_frag): Note unused parameters. Remove unused
+ variables.
+ (md_create_long_jump, md_create_short_jump,
+ md_undefined_symbol_name, md_section_align, tc_gen_reloc): Note
+ unused parameters.
+
+2002-07-31 Nick Clifton <nickc@redhat.com>
+
+ * NEWS: Retroactively add entry for Lars Brinkhoff's contribution
+ of the PDP-11 and 2.11BSD a.out support.
+
+2002-07-31 Momchil Velikov <velco@fadata.bg>
+
+ * config/tc-v850.c (md_assemble): Fix range check for immediate
+ operand.
+
+2002-07-30 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (mips_cpu_info_table): Clean up entries related
+ to Broadcom SB-1 core support.
+
+2002-07-31 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips_target_format): Fix formatting.
+ Add recognition of n32 ABI formats.
+
+2002-07-30 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * tc-mips.c (load_address): Don't clobber $at when loading a
+ 64-bit address in non-PIC code if noat is in effect.
+ (macro): Likewise.
+
+2002-07-30 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * config/tc-mips.c (macro): Use codes 6 and 7 in trap instructions
+ used in division/multiply macro expansions similarly to how they
+ are used in the variants with break instructions.
+ (macro2): Likewise.
+
+2002-07-30 Graeme Peterson <gp@qnx.com>
+
+ * configure.in: Add support for arm-*-nto target.
+ * configure: Regenerate.
+
+2002-07-30 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (struct literal_pool): Add fields to allow
+ multiple literal pools to be maintained.
+ (find_literal_pool): New function.
+ (find_or_make_literal_pool): New function.
+ (add_to_literal_pool): Use find_or_make_literal_pool.
+ (arm_s_text, arm_s_data, arm_s_section): Remove - no longer
+ needed.
+ (s_ltorg): Use find_literal_pool.
+ (arm_cleanup): Dump all literal pools.
+ * doc/c-arm.texi: Document new behaviour of only dumping literal
+ pools upon request.
+
+2002-07-26 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (ppc_set_cpu): Use PPC_OPCODE_64 as the default
+ rather than PPC_OPCODE_32 for powerpc64*.
+
+2002-07-25 Nick Clifton <nickc@redhat.com>
+
+ * po/es.po: Updated Spanish translation.
+ * po/fr.po: Updated French translation.
+
+2002-07-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/c-mips.texi: Remove -mcpu. Document -mabi.
+ * configure.in (MIPS_CPU_STRING_DEFAULT): New configuration macro.
+ (USE_E_MIPS_ABI_O32, MIPS_DEFAULT_64BIT): New configuration macros.
+ * configure, config.in: Regenerate.
+ * config/tc-mips.c (file_mips_abi): Rename to mips_abi.
+ (mips_set_options): Remove "abi" field.
+ (mips_opts): Update accordingly. Replace all uses of mips_opts.abi
+ with mips_abi.
+ (mips_cpu): Remove.
+ (mips_arch_string, mips_arch_info): New vars.
+ (mips_tune_string, mips_tune_info): New vars.
+ (ABI_NEEDS_32BIT_REGS, ABI_NEEDS_64BIT_REGS): New macros.
+ (HAVE_32BIT_GPRS, HAVE_32BIT_FPRS): Don't check the ABI.
+ (mips_isa_to_str, mips_cpu_to_str): Remove.
+ (mips_ip): If the selected architecture is a generic ISA rather
+ than a processor, only mention the ISA level in error messages.
+ (OPTION_MCPU): Remove.
+ (OPTION_FP64): New.
+ (md_longopts): Add -mfp64, remove -mcpu.
+ (mips_set_option_string): New fn.
+ (md_parse_option): Make -mipsN update file_mips_isa rather than
+ mips_opts.isa. Use mips_set_option_string to set -march or -mtune.
+ Don't let -mgp32 and -mfp32 change the ABI.
+ (show): Move to end of file. Constify string argument.
+ (md_show_usage): Move to the end of the file. Read available
+ architectures from mips_cpu_info_table.
+ (mips_set_architecture): New fn.
+ (mips_after_parse_args): Rework. Remove -mcpu handling. -mipsN
+ is an alias for -march=mipsN. Don't change the ABI based on other
+ flags. Infer the register size from the ABI as well as the
+ architecture. Complain about more conflicting arguments.
+ Unify logic with GCC.
+ (s_mipsset): Don't change the ABI.
+ (mips_elf_final_processing): Check USE_E_MIPS_ABI_O32.
+ (mips_cpu_info_table): Remove Generic-MIPS* entries, keeping just
+ "mipsN"-type entries. Remove entries that vary only in the
+ manufacturer's prefix, or that have "000" replaced by "k".
+ Remove TARGET_CPU entries. Make r2000 entry use CPU_R3000.
+ (mips_strict_matching_cpu_name_p, mips_matching_cpu_name_p): New fns.
+ (mips_parse_cpu): New fn.
+ (mips_cpu_info_from_name, mips_cpu_info_from_cpu): Remove.
+ (mips_cpu_info_from_isa): Minor formatting tweak.
+
+2002-07-24 Nick Clifton <nickc@redhat.com>
+
+ * po/sv.po: Updated Swedish translation.
+ * po/es.po: Updated Spanish translation.
+
+2002-07-23 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+ * config.in: Regenerate.
+ * po/POTFILES.in: Regenerate.
+
+2002-07-23 Nick Clifton <nickc@redhat.com>
+
+ * po/fr.po: Updated French translation.
+
+2002-07-23 Nick Clifton <nickc@redhat.com>
+
+ * CONTRIBUTORS: Ken Raeburn is no longer the maintainer for
+ GAS.
+
+2002-07-19 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips_need_elf_addend_fixup): Use S_IS_EXTERNAL
+ instead of S_IS_EXTERN.
+ (md_estimate_size_before_relax): Likewise.
+ (mips_fix_adjustable): Likewise.
+
+2002-07-19 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips_pic_level): Remove IRIX4_PIC.
+
+2002-07-19 Miroslav Tichy <tichm9am@ss1000.ms.mff.cuni.cz>
+ Nick Clifton <nickc@redhat.com>
+
+ * cond.c (s_ifdef): Treat a referenced but not yet defined
+ symbol as if it were undefined, in exactly the same way as
+ .equiv.
+
+ * doc/as.texinfo: Document that .ifdef, .ifndef and .equiv
+ consider referenced bug not yet defined symbols to be
+ undefined.
+
+2002-07-18 Denis Chertykov <denisc@overta.ru>
+ Frank Ch. Eigler <fche@redhat.com>
+ Alan Lehotsky <alehotsky@cygnus.com>
+ John Healy <jhealy@redhat.com>
+ Jeff Johnston <jjohnstn@redhat.com>
+
+ * configure.in: Add ip2k configuraton.
+ * configure: Regenerate.
+ * Makefile.am: Add ip2k configuraton.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * Makefile.in: Regenerate.
+ * config/tc-ip2k.c: New file.
+ * config/tc-ip2k.h: New files.
+ * NEWS: Mention new support.
+ * doc/Makefile.am (CPU_DOCS): Add c-ip2k.texi.
+ * doc/Makefile.in: Regenerate.
+ * doc/all.texi: Set IP2K
+ * doc/as.texinfo: Add IP2K description.
+ * doc/c-ip2k.texi: New file.
+
+2002-07-19 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * NEWS: Reformat to match style of other NEWS files.
+
+2002-07-17 Jan Hubicka <jh@suse.cz>
+
+ * tc-i386.c (i386_align_code): Implement x86_64 neutral code fillers.
+
+2002-07-16 Moritz Jodeit <moritz@jodeit.org>
+
+ * config/tc-z8k.c (build_bytes): Correct order of memset args.
+
+2002-07-16 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * NEWS: Add 'Changes in 2.13'.
+
+2002-07-15 Matt Fredette <fredette@netbsd.org>
+
+ * config/tc-hppa.h (LABELS_WITHOUT_COLONS): Define if TE_NetBSD.
+
+2002-07-12 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.c (process_suffix): Merge CODE_64BIT JumpByte
+ case with non CODE_64BIT case. Don't warn on "qword ptr" if
+ not CODE_64BIT.
+
+2002-07-11 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-ppc.c (ppc_elf_frob_symbol): Delete.
+ (ppc_frob_file_before_adjust): New function.
+ * config/tc-ppc.h (tc_frob_symbol): Don't define.
+ (ppc_elf_frob_symbol): Don't declare.
+ (tc_frob_file_before_adjust): Define.
+ (ppc_frob_file_before_adjust): Declare.
+
+ * config/tc-ppc.c (md_pseudo_table): Warning fix.
+ (ppc_cpu): Make it unsigned long to agree with struct powerpc_opcode
+ flags.
+ (ppc_size): Delete.
+ (ppc_xcoff64): Rename to ppc_obj64.
+ (md_parse_option <m>): Encode old ppc_size value in ppc_cpu.
+ (ppc_set_cpu): Set PPC_OPCODE_32 too.
+ (ppc_arch): Use ppc_obj64 instead of ppc_size to select bfd_mach_ppc64
+ or bfd_mach_ppc.
+ (ppc_target_format): Use ppc_obj64 to select format.
+ (md_begin): Adjust for PPC_OPCODE_32/64 in ppc_cpu.
+ (ppc_insert_operand): Use ppc_obj64 instead of ppc_size.
+ (ppc_elf_suffix): Likewise. Don't depend on BFD_DEFAULT_TARGET_SIZE.
+ (tc_frob_symbol): Likewise.
+ (md_assemble): Use ppc_obj64 instead of ppc_size. Don't depend on
+ BFD_DEFAULT_TARGET_SIZE.
+ (ppc_tc): Likewise.
+ (ppc_is_toc_sym): Likewise.
+ (md_apply_fix3): Likewise.
+ * config/tc-ppc.h (TC_FORCE_RELOCATION): Don't depend on
+ BFD_DEFAULT_TARGET_SIZE.
+ (ELF_TC_SPECIAL_SECTIONS): Likewise.
+ (tc_frob_symbol): Likewise.
+
+2002-07-09 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (macro_build): Handle MIPS16 insns.
+ (mips_ip): Likewise.
+
+2002-07-09 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.c (md_pseudo_table <file>): Warning fix.
+ (BFD_RELOC_8, BFD_RELOC_8_PCREL): Define for non-BFD.
+ (md_apply_fix3): Formatting. Remove redundant test.
+ (tc_gen_reloc): Remove redundant code.
+ (tc_i386_force_relocation): Delete. Movy body of function to..
+ * config/tc-i386.h (TC_FORCE_RELOCATION): .. here.
+
+2002-07-09 Federico G. Schwindt <fgsch@olimpo.com.br>
+
+ * configure.in: Add hppa-*-openbsd* target, change
+ alpha*-*-openbsd* format to elf, and use elf for sparc-*-openbsd*
+ with sparc64 cpu.
+ * configure: Regenerate.
+
+2002-07-08 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * config/tc-mips.c (macro): Shift the 32-bit address range
+ accessible with a lone "lui" down by 32768.
+
+2002-07-08 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * config/tc-mips.c (load_address): Use non-trapping "daddu"
+ instead of "dadd" in address calculations.
+ (macro): Likewise.
+
+2002-07-08 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.c (process_suffix): Remove intel mode movsx and
+ movzx fudges.
+ (md_assemble): Instead, zap the suffix here.
+
+2002-07-03 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * NEWS: Remove next release number until the release is actually
+ upon us.
+
+2002-07-03 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am (check-DEJAGNU): Revert 2002-06-25 change.
+ Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2002-07-02 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.c (tc_s390_fix_adjustable): Prevent any adjustment
+ to symbols in merge sections, even non pc-relative ones.
+
+2002-06-29 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/tc-m68hc11.h (m68hc11_listing_header): Fix warning.
+
+2002-06-29 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/tc-m68hc11.h (ELF_TC_SPECIAL_SECTIONS): New sections
+ .softregs and .eeprom.
+
+2002-06-28 David O'Brien <obrien@FreeBSD.org>
+
+ * NEWS: Note the next release is 2.13.
+
+2002-06-26 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * po/tr.po: New translation imported.
+
+2002-06-26 Elias Athanasopoulos <eathan@otenet.gr>
+
+ * ecoff.c: (get_tag): Replace strcpy with xstrdup.
+ (ecoff_directive_def): Likewise.
+ (ecoff_directive_tag): Likewise.
+ * listing.c (file_info): Likewise.
+ * hash.c (what): Likewise.
+
+2002-06-25 H.J. Lu <hjl@gnu.org>
+
+ * Makefile.am (check-DEJAGNU): Set LC_ALL=C and export it.
+ * Makefile.in: Regenerated.
+
+2002-06-19 Dhananjay R. Deshpande <dhananjayd@kpit.com>
+
+ * config/tc-sh.c (get_specific): Revert 2002-05-01 change.
+ (assemble_ppi): Generate warning if the same register is used
+ twice as destination in the same padd / pmuls instruction.
+
+2002-06-18 Dave Brolley <brolley@redhat.com>
+
+ From Catherine Moore, Michael Meissner, Richard Sandiford, Dave Brolley
+ * po/POTFILES.in: Add tc-frv.c, tc-frv.h.
+ * configure.in: Support frv-*-*.
+ * Makefile.am (CPU_TYPES): Add frv.
+ (TARGET_CPU_CFILES): Add tc-frv.c.
+ (TARGET_CPU_HFILES): Add tc-frv.h.
+ (DEPTC_frv_coff): New variable.
+ (DEPTC_frv_elf): New variable.
+ (DEPOBJ_frv_coff): New variable.
+ (DEPOBJ_frv_elf): New variable.
+ (DEP_frv_coff): New variable.
+ (DEP_frv_elf): New variable.
+ * tc-frv.c: New file.
+ * tc-frv.h: New file.
+
+2002-06-17 Catherine Moore <clm@redhat.com>
+
+ * config/obj-elf.h (TARGET_SYMBOL_FIELDS): Conditionally define.
+
+2002-06-17 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config/tc-sh.c (assemble_ppi): Initialize reg_n.
+
+2002-06-17 Tom Rix <trix@redhat.com>
+
+ * config/tc-i370.h (tc_comment_chars): Define for i370-elf.
+
+2002-06-14 H.J. Lu <hjl@gnu.org>
+ Daniel Jacobowitz <drow@mvista.com>
+
+ * dwarf2dbg.h (dwarf2_directive_file): Return char *.
+ * dwarf2dbg.c (dwarf2_directive_file): Return filename.
+ * config/tc-mips.c (s_mips_file): Call s_app_file_string
+ and new_logical_line for the first .file directive.
+ * read.c (s_app_file_string): New function.
+ (s_app_file): Call it.
+ * read.h (s_app_file_string): Add declaration.
+
+2002-06-14 Daniel Jacobowitz <drow@mvista.com>
+
+ * configure.in: Remove MIPS_STABS_ELF.
+ * configure: Regenerated.
+ * config.in: Regenerated.
+ * config/obj-elf.h (ECOFF_DEBUGGING): Define to mips_flag_mdebug
+ for MIPS targets.
+ * config/tc-mips.c (mips_pseudo_table): Remove #ifdef around
+ ".extern".
+ (pdr_seg): Declare unconditionally.
+ (md_begin): Always generate .pdr unless ECOFF_DEBUGGING or not ELF.
+ (s_mips_end): Likewise. Generate stabs function markers.
+ (s_mips_ent): Generate stabs function markers.
+ (s_mips_frame): Always generate .pdr unless ECOFF_DEBUGGING or not
+ ELF.
+ (s_mips_mask): Likewise.
+ (mips_flag_mdebug): New.
+ (md_longopts): Add "mdebug" and "no-mdebug".
+ (md_parse_options): Add OPTION_MDEBUG and OPTION_NO_MDEBUG.
+ (mips_after_parse_args): Set mips_flag_mdebug.
+ * doc/as.texinfo: Add "-mdebug" and "-no-mdebug" for MIPS.
+
+2002-06-13 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * config/tc-mips.c (md_apply_fix3): Don't subtract the symbol's
+ value twice for RELA relocations.
+
+2002-06-12 Ben Elliston <bje@redhat.com>
+
+ * symbols.c (resolve_symbol_value): Initialise final_val.
+
+ * subsegs.c (subsegs_print_statistics): Cast frchp to void *.
+
+2002-06-11 Tom Rix <trix@redhat.com>
+
+ * config/tc-ppc.c (ppc_subseg_align): Delete.
+ (ppc_change_csect): Default csect align is 2.
+ * config/tc-ppc.h (SUB_SEGMENT_ALIGN): Delete
+
+2002-06-09 Marek Michalkiewicz <marekm@amelek.gda.pl>
+
+ * config/tc-avr.c (mcu_types): Update.
+
+2002-06-08 Matt Thomas <matt@3am-software.com>
+
+ * configure.in (vax-*-netbsdelf*, vax-*-netbsdaout*)
+ (vax-*-netbsd*): New targets.
+ * configure: Regenerate.
+ * config/aout_gnu.h (enum machine_type): Add M_VAX4K_NETBSD.
+ * config/tc-vax.c: Add support for ELF and PIC.
+ (flag_want_pic): New flag.
+ (float_cons): Fix prototype.
+ (md_apply_fix3): Adjust for BFD_ASSEMBLER.
+ (md_assemble): Introduce a new is_absolute local, and use it
+ rather than repeating the test. Make fatal errors actually
+ fatal by using as_fatal as appropriate. Adjust for BFD_ASSEMBLER.
+ Add support for ELF. Add support for PIC.
+ (md_convert_frag): Adjust for BFD_ASSEMBLER.
+ (tc_aout_fix_to_chars): Only include if OBJ_AOUT and not
+ BFD_ASSEMBLER.
+ (vax_reg_parse): Make the % register prefix mandatory for ELF,
+ optional for a.out, and not allowed for VMS. Adjust all callers.
+ (md_create_short_jump): Add ATTRIBUTE_UNUSED to unused arguments.
+ (md_create_long_jump): Likewise.
+ (md_undefined_symbol): Likewise.
+ (md_section_align): Likewise.
+ (md_shortopts): Allow -k and -K for ELF.
+ (md_parse_option): Set flag_want_pic if -k or -K.
+ (tc_headers_hook): New function if OBJ_AOUT and not BFD_ASSEMBLER.
+ (tc_gen_reloc): New function if BFD_ASSEMBLER.
+ * config/tc-vax.h (tc_headers_hook): Remove.
+ (TARGET_FORMAT): Set according to object format and target
+ environment.
+ (BFD_ARCH, TARGET_ARCH): Define.
+ (NO_RELOC): Adjust for BFD_ASSEMBLER.
+ (TC_RELOC_RTSYM_LOC_FIXUP, TC_FIX_ADJUSTABLE)
+ (tc_fix_adjustable): Define if BFD_ASSEMBLER.
+ * config/vax-inst.h (VAX_JSB, VAX_CALLS, VAX_CALLG): Define.
+
+2002-06-08 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+ * as.c: Replace CONST with const.
+ * write.c: Likewise.
+ * config/obj-coff.c: Likewise.
+ * config/tc-a29k.c: Likewise.
+ * config/tc-arm.c: Likewise.
+ * config/tc-dlx.c: Likewise.
+ * config/tc-h8300.c: Likewise.
+ * config/tc-h8500.c: Likewise.
+ * config/tc-i370.c: Likewise.
+ * config/tc-i860.c: Likewise.
+ * config/tc-i960.c: Likewise.
+ * config/tc-m68hc11.c: Likewise.
+ * config/tc-m68k.c: Likewise.
+ * config/tc-m88k.c: Likewise.
+ * config/tc-mcore.c: Likewise.
+ * config/tc-mips.c: Likewise.
+ * config/tc-ns32k.c: Likewise.
+ * config/tc-pdp11.c: Likewise.
+ * config/tc-pj.c: Likewise.
+ * config/tc-s390.c: Likewise.
+ * config/tc-sh.c: Likewise.
+ * config/tc-sparc.c: Likewise.
+ * config/tc-tahoe.c: Likewise.
+ * config/tc-tic80.c: Likewise.
+ * config/tc-v850.c: Likewise.
+ * config/tc-vax.c: Likewise.
+ * config/tc-w65.c: Likewise.
+ * config/tc-z8k.c: Likewise.
+
+2002-06-08 Daniel Jacobowitz <drow@mvista.com>
+
+ Based on patch from Matt Green:
+ * config/obj-elf.h (ECOFF_DEBUGGING): Make configurable.
+ * config/tc-mips.c (s_mips_file): Renamed from s_file.
+ (s_mips_loc): New function.
+ (mips_nonecoff_pseudo_table): Call them.
+ (append_insn): Call dwarf2_emit_insn.
+
+2002-06-08 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips_opts): Fix comment, all ASE fields are set
+ to -1.
+ (file_ase_mips16): New veriable.
+ (mips_eabi64): Remove.
+ (CPU_HAS_MIPS16): New define.
+ (CPU_HAS_MDMX): Fix data type.
+ (md_begin): Code cleanup. Use file_ase_mips16.
+ (mips_elf_final_processing): Handle mips16 header flag.
+ Handle EABI flag without intermediate variable.
+
+2002-06-08 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * doc/as.texinfo: Update MIPS documentation.
+
+2002-06-08 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c: Add define for $zero register.
+ (md_begin): Add $zero as alias name for $0.
+ (insn_uses_reg): Use ZERO define.
+ (mips_ip): Add $zero as alias name for $0.
+ (mips16_ip): Likewise.
+ (s_cplocal): Demand empty rest of input line.
+ (tc_get_register): Likewise. Add support for $kt0, kt1 register
+ names. Use ZERO define. Fix input_line_pointer progress.
+
+2002-06-07 Alan Modra <amodra@bigpond.net.au>
+
+ * symbols.c: Replace CONST by const throughout.
+ (symbol_find_exact): Split out from..
+ (symbol_find_base): ..here.
+ * symbols.h: Replace CONST by const throughout.
+ (symbol_find_exact): Declare.
+ * config/obj-elf.c: #include "struc-symbol.h".
+ (elf_frob_file): If group name matches an exported symbol, use that
+ symbol for the signature and ".group" as the section name.
+
+2002-06-06 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config/tc-sh.c (parse_at): @(symbol,pc) is A_DISP_PC again,
+ but warn about it.
+
+2002-06-06 Daniel Jacobowitz <drow@mvista.com>
+
+ * tc-mips.c (mips_after_parse_args): Always set mips_opts.ase_mips3d
+ and mips_opts.ase_mdmx if they are uninitialized.
+
+2002-06-06 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * gas/config/tc-hppa.c (pa_ip): Replace "L$0\001" with FAKE_LABEL_NAME.
+ (hppa_force_relocation): Check if a stub just before the start symbol
+ of the last call_info is reachable before forcing relocation. Fix
+ typo.
+
+2002-06-04 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * config/tc-mips.c (mips_after_parse_args): New function.
+ (md_begin): Move processing of defaults to mips_after_parse_args.
+ config/tc-mips.h (md_after_parse_args): Define.
+
+2002-06-04 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * configure.in (sh5*): Set cpu_type to sh64 and endian to big.
+ (sh5le*, sh64le*): Set cpu_type to sh64 and endian to little.
+ (sh5*-*-netbsd*, sh64*-*-netbsd*): New targets.
+ * configure: Regenerate.
+ * config/tc-sh64.c (sh64_target_format): Add support for NetBSD
+ environment.
+
+2002-06-04 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/tc-sh64.h (MD_PCREL_FROM_SECTION): Undef before redefining.
+
+2002-06-04 Alan Modra <amodra@bigpond.net.au>
+
+ * config/obj-elf.c (obj_elf_change_section): Set and check elf
+ linkonce flag. Print all warnings.
+ (obj_elf_section): Parse ",comdat" for groups.
+ (elf_frob_file): Set SEC_LINK_ONCE on COMDAT groups. Check
+ consistency of comdat flag.
+
+2002-06-02 Richard Henderson <rth@redhat.com>
+
+ * config/tc-alpha.c (alpha_adjust_symtab_relocs): Fix thinko
+ with LITERALs without sequence numbers.
+
+2002-06-01 Richard Henderson <rth@redhat.com>
+
+ * config/tc-alpha.c: Move LITUSE constants to "elf/alpha.h".
+ Rename them LITUSE_ALPHA_*.
+
+2002-05-31 Shrinivas Atre <ShrinivasA@kpit.com>
+
+ * config/tc-h8300.c (get_operand): Allow stm.l and ldm.l insns to
+ accept parentheses enclosed register lists.
+
+2002-05-31 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * po/POTFILES.in: Regenerate.
+
+2002-05-31 Graeme Peterson <gp@qnx.com>
+
+ * configure.in: Add i386-*-nto-qnx*.
+ * configure: Regenerate.
+
+2002-05-31 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips_ip): Use unsigned long values for
+ warning output.
+
+2002-05-31 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (s_cpsetup): Fix initialization of
+ mips_cpreturn_register and mips_cpreturn_offset.
+
+2002-05-31 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (s_cpsetup): Fix comment.
+
+2002-05-31 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (md_begin): Add $ra as alias name for $31.
+ (mips_ip): Likewise.
+ (mips16_ip): Likewise.
+ (tc_get_register): Likewise.
+
+2002-05-30 Chris G. Demetriou <cgd@broadcom.com>
+ Ed Satterthwaite <ehs@broadcom.com>
+
+ * config/tc-mips.c (mips_set_options): New "ase_mdmx" member.
+ (mips_opts): Initialize "ase_mdmx" member.
+ (file_ase_mdmx): New variable.
+ (CPU_HAS_MDMX): New macro.
+ (md_begin): Initialize mips_opts.ase_mdmx and file_ase_mdmx
+ based on command line options and configuration defaults.
+ (macro_build): Note in comment that use of MDMX in macros is
+ not currently allowed.
+ (validate_mips_insn): Add support for the "O", "Q", "X", "Y", and
+ "Z" MDMX operand types.
+ (mips_ip): Accept MDMX instructions if mips_opts.ase_mdmx is set,
+ and add support for the "O", "Q", "X", "Y", and "Z" MDMX operand
+ types.
+ (OPTION_MDMX, OPTION_NO_MDMX, md_longopts, md_parse_option):
+ Add support for "-mdmx" and "-no-mdmx" options.
+ (OPTION_ELF_BASE): Move to accommodate new options.
+ (s_mipsset): Support ".set mdmx" and ".set nomdmx".
+ (mips_elf_final_processing): Set MDMX ASE ELF header flag if
+ file_ase_mdmx was set.
+ * doc/as.texinfo: Document -mdmx and -no-mdmx options.
+ * doc/c-mips.texi: Likewise, and document ".set mdmx" and ".set
+ nomdmx" directives.
+
+2002-05-31 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (OPTION_NO_M7000_HILO_FIX): Rename to
+ OPTION_MNO_7000_HILO_FIX. Add alternate "mno-fix7000"
+ command line switch conforming to gcc conventions.
+ * doc/c-mips.texi: Document -mno-fix7000 instead of no-mfix-7000.
+
+2002-05-31 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (macro_build_jalr): New Function.
+ (md_begin): NewABI uses big GOTs.
+ (macro_build): Recognize BFD_RELOC_MIPS_GOT_DISP,
+ BFD_RELOC_MIPS_GOT_PAGE, BFD_RELOC_MIPS_GOT_OFST as valid.
+ (load_address): Add some NewABI PIC support.
+ (macro): Likewise.
+ (md_apply_fix): Special handling for BFD_RELOC_MIPS_JALR.
+ (tc_gen_reloc): Don't encode NewABI vtables in REL relocations.
+
+2002-05-31 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (load_address): Use mips_gp_register instead
+ of hardcoded value. Remove dbl parameter, use HAVE_32BIT_ADDRESSES
+ instead.
+ (macro): Use mips_gp_register instead of hardcoded value.
+
+2002-05-30 Richard Henderson <rth@redhat.com>
+
+ * expr.h (operatorT): Add O_md17..O_md32.
+ * config/tc-alpha.c (O_lituse_tlsgd, O_lituse_tlsldm, O_tlsgd,
+ O_tlsldm, O_gotdtprel, O_dtprelhi, O_dtprello, O_dtprel, O_gottprel,
+ O_tprelhi, O_tprello, O_tprel): New.
+ (USER_RELOC_P, alpha_reloc_op_tag, debug_exp): Include them.
+ (DUMMY_RELOC_LITUSE_TLSGD, DUMMY_RELOC_LITUSE_TLSLDM): New.
+ (LITUSE_TLSGD, LITUSE_TLSLDM): New.
+ (struct alpha_reloc_tag): Add master, saw_tlsgd, saw_tlsld,
+ saw_lu_tlsgd, saw_lu_tlsldm. Make multi_section_p a bit field.
+ (md_apply_fix3): Handle TLS relocations.
+ (alpha_force_relocation, alpha_fix_adjustable): Likewise.
+ (alpha_adjust_symtab_relocs): Sort LITERAL relocs after the
+ associated TLS reloc. Check lituse_tls relocs match up.
+ (emit_insn): Handle TLS relocations.
+ (ldX_op): Remove.
+
+ * doc/c-alpha.texi: Add docs for tls relocations.
+
+2002-05-30 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips_gprel_offset): New variable.
+ (s_gpvalue): Use it.
+
+2002-05-30 Diego Novillo <dnovillo@redhat.com>
+
+ * gas/config/tc-d10v.c (check_resource_conflict): Only check
+ write-write conflicts.
+ (md_assemble): Reformat introductory comment.
+ (parallel_ok): Prevent packing only if the first
+ instruction cannot be packed.
+
+2002-05-30 Jason Eckhardt <jle@redhat.com>
+ Tom Rix <trix@redhat.com>
+
+ * config/tc-d10v.c (build_insn): Check for immediates.
+
+2002-05-28 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c: Replace GP in comments by $gp.
+ (mips_big_got): Initialize.
+ (mips_trap): Initialize.
+ (load_address): Use mips_gp_register instead of hardcoded value.
+ Remove dbl parameter, use HAVE_32BIT_ADDRESSES instead.
+ (macro): Use mips_gp_register instead of hardcoded value.
+ (macro2): Change load_address calls.
+ (md_pcrel_from): Comment formatting.
+ (s_cpload): Use mips_gp_register instead of hardcoded value.
+ (s_cprestore): Likewise. Comment formatting.
+ (s_gpword): Fix data type.
+ (s_cpadd): Use mips_gp_register instead of hardcoded value.
+ (nopic_need_relax): Replace GP in comments by $gp.
+ (mips_elf_final_processing): Better comment.
+
+2002-05-28 Kuang Hwa Lin <kuang@sbcglobal.net>
+
+ * configure.in: Add DLX configuraton
+ * Makefile.am: Add DLX configuraton
+ * configure: Regenerate.
+ * Makefile.in: Regenerate.
+ * config/tc-dlx.c: New file.
+ * config/tc-dlx.h: New files.
+ * NEWS: Mention new support.
+
+2002-05-27 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/obj-coff.c (write_object_file): Add missing semicolon.
+
+2002-05-26 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips_emit_delays): Replace magic constant for RA
+ by the define. Remove superfluous check of mips_opts.mips16.
+ (append_insn): Likewise. Canonicalize variable increments.
+ (macro_build): Canonicalize variable increments.
+ (macro_build_lui): Likewise.
+ (load_register): Likewise.
+ (load_address): Move pointer initialization.
+ (macro): Move pointer to a more local scope. Canonicalize variable
+ increments. Better comments. Replace magic constant for RA by the
+ define.
+ (macro2): Replace magic constant for RA by the define. Canonicalize
+ variable increments.
+ (mips_ip): Canonicalize variable increments.
+ (mips16_ip): Replace magic constant for RA by the define.
+ (my_getSmallParser): Canonicalize variable increments/decrements.
+ (my_getPercentOp): Likewise.
+ (my_getSmallExpression): Likewise.
+ (s_align): Likewise.
+ (s_mipsset): Likewise.
+ (s_cpsetup): Likewise.
+ (s_insn): Remove superfluous check of mips_opts.mips16.
+ (s_mips_stab): Likewise.
+ (mips_handle_align): Canonicalize variable increments.
+ (s_mips_ent): Likewise.
+ (s_mips_end): Add comment.
+
+2002-05-26 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * configure.in: Use ns32k-*-netbsd* instead of ns32k-pc532-netbsd*.
+ * configure: Regenerate.
+
+2002-05-25 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am (OBJS): Depend on ansidecl.h and fopen-same.h.
+ * Makefile.in: Regenerate.
+ * dep-in.sed: Reorder to match OBJS in Makefile.am.
+ * configure.in (ALL_OBJ_DEPS): Add symcat.h when need_bfd.
+ * configure: Regenerate.
+ * as.h: Use #include "" instead of <> for local header files.
+ * flonum-konst.c: Likewise.
+ * flonum-mult.c: Likewise.
+ * gasp.c: Likewise.
+ * listing.c: Likewise.
+ * config/tc-ia64.h: Likewise.
+ * config/tc-v850.h: Likewise.
+
+2002-05-24 TAMURA Kent <kent@netbsd.org>
+
+ * configure.in: Add a target for i386-netbsdpe.
+ * configure: Regenerate.
+
+2002-05-23 Jakub Jelinek <jakub@redhat.com>
+
+ * config/obj-elf.c (elf_common): Renamed from obj_elf_common.
+ (obj_elf_common): Call elf_common.
+ (obj_elf_tls_common): New function.
+ (elf_pseudo_tab): Support .tls_common.
+ (special_sections): Add .tdata and .tbss.
+ (obj_elf_change_section): Set SEC_THREAD_LOCAL for SHF_TLS
+ sections.
+ (obj_elf_parse_section_letters): Support T in section flags (SHF_TLS).
+ (obj_elf_parse_section_letters): Include T in error message.
+ * config/tc-ppc.c (ppc_section_letter): Likewise.
+ * config/tc-alpha.c (alpha_elf_section_letter): Likewise.
+ (tc_gen_reloc): Handle SEC_THREAD_LOCAL the same way as
+ SEC_MERGE.
+ * config/tc-sparc.c (md_apply_fix3): Likewise.
+ * config/tc-i386.c (tc_i386_fix_adjustable): Add TLS relocs.
+ Define them if not BFD_ASSEMBLER.
+ (lex_got): Support @TLSGD, @TLSLDM, @GOTTPOFF, @TPOFF, @DTPOFF
+ and @NTPOFF.
+ (md_apply_fix3): Add TLS relocs.
+ * config/tc-ia64.c (enum reloc_func): Add FUNC_DTP_MODULE,
+ FUNC_DTP_RELATIVE, FUNC_TP_RELATIVE, FUNC_LT_DTP_MODULE,
+ FUNC_LT_DTP_RELATIVE, FUNC_LT_TP_RELATIVE.
+ (pseudo_func): Support @dtpmod(), @dtprel() and @tprel().
+ (ia64_elf_section_letter): Include T in error message.
+ (md_begin): Support TLS operators.
+ (md_operand): Likewise.
+ (ia64_gen_real_reloc_type): Support TLS relocs.
+ * write.c (adjust_reloc_syms): Don't change symbols in
+ SEC_THREAD_LOCAL sections to STT_SECTION + addend.
+
+2002-05-23 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-arm.c (md_apply_fix3): For the Thumb BLX reloc
+ round the relocation up rather than down.
+
+2002-05-23 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/obj-coff.c (obj_coff_section): Silently ignore an 'a'
+ flag.
+ * doc/as.texinfo: Document that the COFF version of .section
+ ignores the 'a' flag.
+
+2002-05-23 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-alpha.c (assemble_tokens): Protect use of
+ ALPHA_RELOC_TABLE with #ifdef RELOC_OP_P.
+
+ * write.c (size_seg): Check adjustment to last frag.
+ (SUB_SEGMENT_ALIGN): If HANDLE_ALIGN defined, pad out last frag to
+ section alignment.
+ * config/obj-coff.c (SUB_SEGMENT_ALIGN): Likewise.
+ * config/obj-ieee.c (SUB_SEGMENT_ALIGN): Likewise.
+ (write_object_file): Invoke md_do_align if available, and use
+ frag_align_code on text sections.
+ * config/obj-vms.h (SUB_SEGMENT_ALIGN): Now two args.
+ * config/tc-m88k.h (SUB_SEGMENT_ALIGN): Likewise.
+ * config/tc-ppc.h (SUB_SEGMENT_ALIGN): Likewise.
+ * config/tc-sh.h (SUB_SEGMENT_ALIGN): Likewise.
+ * config/tc-i386.h (SUB_SEGMENT_ALIGN): Likewise. Define for
+ BFD_ASSEMBLER too.
+
+2002-05-22 H.J. Lu <hjl@gnu.org>
+
+ * dwarf2dbg.c (dwarf2_directive_loc): Call listing_source_file
+ for source file.
+
+2002-05-22 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-arm.c (arm_s_section): Enable for COFF builds as well
+ as ELF builds.
+
+2002-05-22 H.J. Lu <hjl@gnu.org>
+
+ * dwarf2dbg.c (dwarf2_emit_insn): Emit only one line symbol
+ for one .loc for compiler.
+
+2002-05-22 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (macro): Relax warning, it's toot strict for
+ embedded-PIC.
+
+2002-05-22 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (macro2): Add 64 bit drol, dror macros.
+ Optimize the rotate by zero case.
+
+2002-05-21 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * configure.in: Remove accidental enabling of bfd_gas=yes for
+ sh-coff targets.
+ * configure: Regenerate.
+
+2002-05-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * app.c: Fix formatting.
+ * as.c: Likewise.
+ * ehopt.c: Likewise.
+ * expr.c: Likewise.
+ * input-file.c: Likewise.
+ * listing.c: Likewise.
+ * macro.h: Likewise.
+ * stabs.c: Likewise.
+ * symbols.c: Likewise.
+
+2002-05-17 Alan Modra <amodra@bigpond.net.au>
+
+ * config/obj-generic.c: Delete file.
+ * config/obj-generic.h: Likewise.
+
+2002-05-16 Marek Michalkiewicz <marekm@amelek.gda.pl>
+
+ * config/tc-avr.c (mcu_types): Update for new devices.
+
+2002-05-15 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (macro): Warn about wrong la/dla use.
+
+2002-05-15 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc_mips.c (s_cpsetup): Fix completely bogus code which had
+ worked sometimes by accident. Fix copy&paste comment.
+
+2002-05-15 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (md_begin): Fix .reginfo and .MIPS.option section
+ alignment for NewABI. Let n32 use .reginfo. Remove useless casts.
+ (mips_elf_final_processing): Let n32 use .reginfo.
+
+2002-05-15 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (append_insn): Fix too small range of variable.
+
+2002-05-14 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-arm.c (arm_cleanup): Remove redundant call to
+ listing_prev_line().
+
+2002-05-13 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-arm.c (md_assemble): Remove redundant call to
+ listing_prev().
+
+ * dwarf2dbg.c (dwarf2_emit_insn): Do not reset
+ loc_directive_seen.
+
+ * stabs.c (s_stab_generic): Fix grammatical error in warning
+ message.
+
+2002-05-13 Alan Modra <amodra@bigpond.net.au>
+
+ * write.c (subsegs_finish): Don't specially align last subseg.
+
+2002-05-11 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * stabs.c (s_stab_generic): Warn about a description field that is
+ too big.
+
+ * config/obj-coff.c: Fix compile time warnings when compiling
+ without BFD_ASSEMBLER defined.
+ Fix formatting.
+
+ * config/tc-sh.c (md_pcrel_from): Define for use with sh-hms
+ target.
+ (md_pcrel_from_section): Use md_pcrel_from().
+
+2002-05-11 Bruno Haible <bruno@clisp.org>
+
+ * dwarf2dbg.c (dwarf2_emit_insn): Use the 'current' struct filled
+ by dwarf2_directive_loc, instead of calling dwarf2_where.
+
+2002-05-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/obj-coff.h: Fix formatting.
+ * config/tc-mcore.c: Likewise.
+ * config/tc-mn10300.c: Likewise.
+ * config/tc-openrisc.c: Likewise.
+ * config/tc-or32.c: Likewise.
+ * config/tc-pdp11.c: Likewise.
+ * config/tc-ppc.c: Likewise.
+ * config/tc-ppc.h: Likewise.
+ * config/tc-sh64.c: Likewise.
+ * config/tc-sh.c: Likewise.
+ * config/tc-tic54x.c: Likewise.
+ * config/tc-xstormy16.c: Likewise.
+ * config/tc-xstormy16.h: Likewise.
+
+2002-05-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/obj-coff.c: Fix formatting.
+ * config/obj-elf.c: Likewise.
+ * config/tc-alpha.c: Likewise.
+ * config/tc-arm.c: Likewise.
+ * config/tc-d10v.c: Likewise.
+ * config/tc-d30v.c: Likewise.
+ * config/tc-h8300.c: Likewise.
+ * config/tc-hppa.c: Likewise.
+
+2002-05-09 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.c (md_estimate_size_before_relax) Don't lose
+ reloc when no_cond_jump_promotion.
+
+2002-05-08 Jim Wilson <wilson@redhat.com>
+
+ * config/tc-i960.c (md_estimate_size_before_relax): Return size of
+ current variable part of frag.
+
+2002-05-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/tc-mmix.c: Fix formatting.
+ * config/tc-mmix.h: Likewise.
+
+2002-05-08 Alan Modra <amodra@bigpond.net.au>
+
+ * configure: Regenerate.
+
+2002-05-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/tc-m68k.c: Fix formatting.
+
+2002-05-07 Federico G. Schwindt <fgsch@olimpo.com.br>
+
+ * Makefile.am: Honour DESTDIR.
+ * Makefile.in: Regenerate.
+
+2002-05-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/tc-ia64.c: Fix formatting.
+ * config/tc-ia64.h: Likewise.
+
+2002-05-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/tc-mips.c: Fix formatting.
+ * config/tc-s390.c: Likewise.
+ * config/tc-s390.h: Likewise.
+
+2002-05-03 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-s390.c (md_gather_operands): Emit dwarf2 line-number
+ information for instructions.
+
+2002-05-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * as.h: Fix formatting.
+ * cgen.c: Likewise.
+ * cgen.h: Likewise.
+ * dwarf2dbg.c: Likewise.
+ * frags.h: Likewise.
+ * gasp.c: Likewise.
+ * macro.c: Likewise.
+ * read.c: Likewise.
+ * stabs.c: Likewise.
+ * symbols.c: Likewise.
+
+2002-05-02 Alan Modra <amodra@bigpond.net.au>
+
+ * app.c (mri_pseudo): Only declare for TC_M68K.
+
+ * config/tc-ppc.c (mapping): Map sectoff to BFD_RELOC_16_BASEREL.
+ (ppc_elf_validate_fix): Replace BFD_RELOC_32_BASEREL with
+ BFD_RELOC_16_BASEREL.
+ (md_assemble): Likewise.
+ (md_apply_fix3): Likewise.
+
+2002-05-02 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-arm.c (thumb_add_sub): Do not convert a subtract of
+ zero into an add of zero - it is not the same.
+
+2002-05-01 Arati Dikey <aratid@kpit.com>
+
+ * tc-sh.c (get_specific): Generate warning if the same
+ destination register is used in parallel instructions.
+
+2002-05-01 Andrew Macleod <amacleod@cygnus.com>
+
+ * config/tc-i386.c (extra_symbol_chars): Add '[' to the list.
+
+2002-05-01 Alan Modra <amodra@bigpond.net.au>
+
+ * write.c (cvt_frag_to_fill): Set fr_offset to zero on .org
+ backwards to prevent cascading errors.
+
+2002-04-30 Mark Mitchell <mark@codesourcery.com>
+
+ * configure.in: Add support for powerpc-*-windiss.
+ * configure: Regenerated.
+
+2002-04-28 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-s390.c (md_parse_option): Formatting.
+
+ * config/tc-i386.c: Formatting fixes, add missing space in error
+ message.
+
+2002-04-24 Christian Groessler <chris@groessler.org>
+
+ * config/tc-z8k.c (build_bytes): Add support for new cases:
+ CLASS_IGNORE and ARG_NIM4.
+ (md_assemble): Prevent destruction of input_line_pointer if
+ get_operands returns failure.
+
+2002-04-24 Chris G. Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (macro_build): Do _not_ allow MIPS-3D
+ instructions to be generated by macros.
+
+2002-04-24 Andreas Schwab <schwab@suse.de>
+
+ * config/tc-i386.c (output_jump, output_disp)
+ (md_estimate_size_before_relax): Don't set fx_pcrel_adjust any
+ more.
+ (md_apply_fix3): Remember addend value for rela relocations.
+ (tc_gen_reloc): Correctly compute pc-relative relocation addend.
+
+2002-04-22 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (macro_build): Add close-parenthesis missing
+ from previous change.
+
+2002-04-22 Eric Christopher <echristo@redhat.com>
+
+ * config/tc-mips.c (macro_build): Add warning if macro instructions
+ are expanded into a branch delay slot.
+
+2002-04-17 Geoffrey Keating <geoffk@redhat.com>
+
+ * dwarf2dbg.c (dwarf2_gen_line_info): Do emit duplicate line
+ numbers, gdb relies on them to detect the start of the prologue.
+
+2002-04-17 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.c (tc_s390_fix_adjustable): Prevent adjustments to
+ symbols in merge sections.
+
+2002-04-16 Alan Modra <amodra@bigpond.net.au>
+
+ * as.c (main): Don't reference _bfd_chunksize.
+
+2002-04-15 Tom Rix <trix@redhat.com>
+
+ * config/tc-d10v.c (d10v_fix_adjustable): Prevent adjustments to
+ symbols in merge sections.
+
+2002-04-11 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/invoke.texi (TC_LARGEST_EXPONENT_IS_NORMAL): Document.
+ * config/atof-ieee.c (TC_LARGEST_EXPONENT_IS_NORMAL): Add an
+ argument for the precision.
+ (gen_to_words): Update accordingly.
+
+2002-04-10 Alan Modra <amodra@bigpond.net.au>
+
+ * as.c (parse_args <OPTION_VERSION>): Use VERSION is
+ BFD_VERSION_STRING unavailable.
+ * config/tc-i386.c (INLINE): Define (for non-BFD assembler).
+
+2002-04-09 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config/tc-sh.h (TC_FIX_ADJUSTABLE): Disable adjusting if
+ symbol_used_in_reloc_p is true.
+
+ * config/tc-sh.c (md_apply_fix3): Don't zero relocations on big
+ endian hosts.
+
+2002-04-04 Alan Modra <amodra@bigpond.net.au>
+
+ * dep-in.sed: Cope with absolute paths.
+ * Makefile.am (dep.sed): Subst TOPDIR.
+ Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2002-04-04 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (mips16_macro_build): Cast type mismatch.
+ (mips_ip): Remove unused variable.
+ (md_apply_fix3): Cast signed/unsignes mismatches. Replace
+ unsigned char with bfd_byte.
+ (s_file): Remove unused variable.
+ (s_mips_ent): Likewise.
+
+2002-04-03 Tom Rix <trix@redhat.com>
+
+ * config/tc-d10v.c (d10v_insert_operand): Fix warning in as_bad_where.
+ (build_insn): Same.
+ (find_opcode): Fix warning in as_warn.
+ * config/tc-d10v.h: Update Copyright.
+
+2002-04-03 Alan Matsuoka <alanm@redhat.com>
+ Tom Rix <trix@redhat.com>
+
+ From Jeff Knaggs <jknaggs@redhat.com>
+ * config/tc-d10v.c (check_resource_conflict): New function to
+ check for resource conflicts.
+
+ From Jason Eckhardt <jle@redhat.com>
+ * config/tc-d10v.c (build_insn): Check for unresolved imm4 or
+ imm3 fields.
+ * config/tc-d10v.c (find_opcode): Emit a warning if one of the
+ reserved control registers is used.
+ * config/tc-d10v.c (build_insn): Check for unresolved imm4 or
+ imm3 fields.
+
+ From 2001-03-28 Diego Novillo <dnovillo@redhat.com>
+ * tc-d10v.c (parallel_ok): Prevent packing only if the first
+ instruction cannot be packed.
+
+ From 2001-03-30 Diego Novillo <dnovillo@redhat.com>
+ * gas/config/tc-d10v.c (check_resource_conflict): Only check
+ write-write conflicts.
+ (md_assemble): Reformat introductory comment.
+ * opcodes/d10v-opc.c (d10v_opcodes): `btsti' does not modify its
+ arguments.
+
+2002-04-03 Alan Modra <amodra@bigpond.net.au>
+
+ * symbols.c (resolve_symbol_value <O_uminus, O_bit_not,
+ O_logical_not>): Derive final_seg from add_symbol.
+ <O_multiply..O_logical_or>: More final_seg twiddles.
+
+2002-04-01 Jessica Han <jessica@cup.hp.com>
+
+ * config/tc-ia64.c (ia64_cons_fix_new): Handle 8 byte iplt reloc
+ in 32-bit mode.
+
+2002-03-27 Andreas Schwab <schwab@suse.de>
+
+ * config/tc-i386.c (output_jump): Set fx_pcrel_adjust to size of
+ field for pc-relative fixups.
+ (output_disp): Likewise.
+ (md_estimate_size_before_relax): Likewise.
+ (tc_gen_reloc): Subtract fx_pcrel_adjust instead of fx_size for
+ pc-relative fixups in 64bit mode.
+
+2002-03-22 Alan Modra <amodra@bigpond.net.au>
+
+ * config/te-aix5.h: Typo fix.
+
+2002-03-21 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+
+2002-03-20 Albert Chin-A-Young <china@thewrittenword.com>
+
+ * config/tc-arm.c (vfp_dp_reg_required_here): Fix typo
+ (vfp_sp_reg_pos -> vfp_dp_reg_pos).
+
+2002-03-18 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mips.c (md_estimate_size_before_relax): Do not modify
+ the EXTENDED bit here; report the estimate according to the
+ current size.
+
+2002-03-18 Tom Rix <trix@redhat.com>
+
+ * configure.in: Add AIX 5 support.
+ * config/tc-ppc.c (ppc_target_format): Add AIX 5 64 bit target.
+ * config/te-aix5.h: New file. AIX 5 support.
+ * configure: Regenerate.
+
+2002-03-18 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * po/fr.po: Updated version.
+
+2002-03-16 Andreas Jaeger <aj@suse.de>
+
+ * doc/c-mips.texi (Machine Dependencies): Add new node.
+
+2002-03-15 Chris G. Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (mips_set_options): New "ase_mips3d" member.
+ (mips_opts): Initialize "ase_mips3d" member.
+ (file_ase_mips3d): New variable.
+ (CPU_HAS_MIPS3D): New macro.
+ (md_begin): Initialize mips_opts.ase_mips3d and file_ase_mips3d
+ based on command line options and configuration defaults.
+ (macro_build, mips_ip): Accept MIPS-3D instructions if
+ mips_opts.ase_mips3d is set.
+ (OPTION_MIPS3D, OPTION_NO_MIPS3D, md_longopts, md_parse_option):
+ Add support for "-mips3d" and "-no-mips3d" options.
+ (OPTION_ELF_BASE): Move to accommodate new options.
+ (s_mipsset): Support ".set mips3d" and ".set nomips3d".
+ (mips_elf_final_processing): Add a comment indicating that a
+ MIPS-3D ASE ELF header flag should be set, when one exists.
+ * doc/as.texinfo: Document -mips3d and -no-mips3d options.
+ * doc/c-mips.texi: Likewise, and document ".set mips3d" and ".set
+ nomips3d" directives.
+
+2002-03-14 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/tc-mmix.c (md_estimate_size_before_relax): Don't consider
+ a weak symbol in same section to be within reach.
+
+2002-03-13 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * po/fr.po: Updated version.
+
+2002-03-12 Andreas Schwab <schwab@suse.de>
+
+ * config/tc-ia64.c (fixup_unw_records): Clear region when seeing a
+ body record so that an error is given for misplaced .save
+ pseudo-ops.
+
+2002-03-09 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.h (REX_OPCODE): Define.
+ (REX_MODE64, REX_EXTX, REX_EXTY, REX_EXTZ): Define.
+ (rex_byte): typedef to int.
+ * config/tc-i386.c: Group prototypes and vars together.
+ Formatting fixes. Remove occurrences of "register" keyword.
+ (true): Delete.
+ (false): Delete.
+ (mode_from_disp_size): Add INLINE keyword to prototype.
+ (fits_in_signed_byte): Likewise.
+ (fits_in_unsigned_byte): Likewise.
+ (fits_in_unsigned_word): Likewise.
+ (fits_in_signed_word): Likewise.
+ (fits_in_unsigned_long): Likewise.
+ (fits_in_signed_long): Likewise.
+ (type_names): Constify.
+ (intel_float_operand): Constify param.
+ (add_prefix): Use REX_OPCODE.
+ (md_assemble): Likewise. Modify for changed rex_byte.
+ (parse_insn): Split out of md_assemble.
+ (parse_operands): Likewise.
+ (swap_operands): Likewise.
+ (optimize_imm): Likewise.
+ (optimize_disp): Likewise.
+ (match_template): Likewise.
+ (check_string): Likewise.
+ (process_suffix): Likewise.
+ (check_byte_reg): Likewise.
+ (check_long_reg): Likewise.
+ (check_qword_reg): Likewise.
+ (check_word_reg): Likewise.
+ (finalize_imm): Likewise.
+ (process_operands): Likewise.
+ (build_modrm_byte): Likewise.
+ (output_insn): Likewise.
+ (output_branch): Likewise.
+ (output_jump): Likewise.
+ (output_interseg_jump): Likewise.
+ (output_disp): Likewise.
+ (output_imm): Likewise.
+
+2002-03-07 Daniel Jacobowitz <drow@mvista.com>
+
+ * doc/as.texinfo: Wrap @menu in @ifnottex, not @ifinfo.
+
+2002-03-06 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-i386.c (tc_gen_reloc): Don't attempt to handle 8 byte
+ relocs except when BFD64.
+
+ * write.c (number_to_chars_bigendian): Don't abort when N is
+ larger than sizeof (VAL).
+ (number_to_chars_littleendian): Likewise.
+
+2002-03-05 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * config/tc-hppa.c (md_apply_fix3): Add cast.
+ (hppa_fix_adjustable): Adjust list of selectors using e_lrsel and
+ e_rrsel.
+
+2002-03-05 Paul Koning <pkoning@equallogic.com>
+
+ * tc-pdp11.c: Use VAX float format support for PDP-11 target.
+ (parse_ac5): New function for parsing float regs in float operand.
+ (parse_expression): Remove attempt to make literals be octal.
+ (parse_op_no_deferred): Support float literals.
+ (parse_op): Reject attempts to refer to float regs.
+ (parse_fop): New function, like parse_op but for float operand.
+ (md_assemble): Add cases to parse float operands. Also fix
+ IMM3, IMM6, IMM8 cases to pick up the operand from the right spot.
+
+2002-03-04 H.J. Lu <hjl@gnu.org>
+
+ * config/obj-elf.c (special_section): Add .init_array,
+ .fini_array and .preinit_array.
+
+ * config/tc-ia64.h (ELF_TC_SPECIAL_SECTIONS): Remove
+ .init_array and .fini_array.
+
+2002-03-01 Jakub Jelinek <jakub@redhat.com>
+
+ * config/obj-elf.c (elf_copy_symbol_attributes): Don't copy
+ visibility.
+ (obj_frob_symbol): Copy visibility.
+
+2002-02-28 Jakub Jelinek <jakub@redhat.com>
+
+ * config/tc-alpha.c (s_alpha_text): Use obj_elf_text for OBJ_ELF, not
+ s_text.
+ (s_alpha_data): Use obj_elf_data for OBJ_ELF, not s_data.
+
+2002-02-27 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * po/es.po: Updated.
+
+2002-02-26 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (mips_need_elf_addend_fixup): For embedded-PIC
+ only, undo the changes made on 2001-06-08, with the
+ effect being that common or extern symbols are
+ adjusted for embedded-PIC, but weak symbols are not.
+ (md_estimate_size_before_relax: Likewise, with the effect
+ that extern symbols are treated the same as weak symbols
+ only if not embedded-PIC.
+ (mips_fix_adjustable) Likewise, with the effect that
+ weak or extern symbols are not adjusted for embedded-PIC.
+ (md_apply_fix3): Tweak so that the case where value is zero
+ is handled more correctly for embedded-PIC code.
+
+2002-02-26 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * doc/as.texinfo (Overview): Add missing @ifset IA64
+
+ * configure.in (LINGUAS): Add es.po.
+ * configure: Regenerate.
+ * po/es.po: New file.
+
+2002-02-25 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (set_at): Fix handling of 64bit register loads.
+ (macro): Likewise. Fix la/dla address expansions for EMBEDDED_PIC
+ and NO_PIC cases. Code cleanup.
+ (macro2): Fix handling of 64bit register loads.
+
+2002-02-25 David Mosberger <davidm@hpl.hp.com>
+
+ * doc/as.texinfo: Add entry for IA64.
+ * doc/c-ia64.texi: New file.
+
+2002-02-25 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-hppa.c: Update copyright date.
+
+ * doc/c-ppc.texi (PowerPC-Opts): Add -mpower4, -maltivec and -m7400
+ Remove references to chip manufacturers.
+ * config/tc-ppc.c (md_parse_option): Handle -mpower4 option.
+ Correct comments.
+ (md_show_usage): Remove references to chip manufacturers. Mention
+ -mpower4.
+ (md_begin): Test power4 opcode flag bits.
+
+2002-02-22 David Mosberger <davidm@hpl.hp.com>
+
+ * config/tc-ia64.c (dot_restore): Issue error message of epilogue
+ count exceeds prologue count.
+ (md_show_usage): Describe -mconstant-gp and -mauto-pic.
+ (unwind.label_prologue_count): New member.
+
+ Based on a patch by Hans Boehm <hboehm@hpl.hp.com>:
+
+ (get_saved_prologue_count): New function.
+ (save_prologue_count): New function.
+ (free_saved_prologue_count): New function.
+ (dot_label_state): Record state label by calling save_prologue_count().
+ (dot_copy_state): Restore prologue count by calling
+ get_saved_prologue_count().
+ (generate_unwind_image): Free up list of saved prologue
+ counts by calling free_saved_prologue_counts().
+
+2002-02-22 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-tic54x.c: Add missing prototypes and remove ANSI style
+ function declarations.
+
+2002-02-21 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * NEWS: Note that GASP is now deprecated.
+ * Makefile.am: Do not build gasp-new by default.
+ * Makefile.in: Regenerate.
+ * doc/Makefile.am: Do not install gasp.info.
+ * doc/Makefile.in: Regenerate.
+ * gas/gasp.texi: Note that gasp is now deprecated.
+
+2002-02-20 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * NEWS: Mark 2.12 branch.
+
+2002-02-19 Tom Tromey <tromey@redhat.com>
+
+ * config/tc-xstormy16.h (DWARF2_LINE_MIN_INSN_LENGTH): Define.
+
+2002-02-19 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config/tc-mips.c (md_parse_option): Complain about invalid -mabi
+ option input.
+
+2002-02-19 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.c (md_parse_option): Add switches -m31 and -m64.
+ Make bit size independent of architecture switch.
+ (md_begin): Add warning for -m64 with -Aesa.
+ (s390_md_end): Use renamed architecture defines.
+
+2002-02-18 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/obj-coff.h: Check !target_big_endian, not shl, for coff-sh.
+
+2002-02-16 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * doc/as.texinfo (Machine Dependencies): Fix typo: MMIX used
+ instead of CRIS.
+
+2002-02-15 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (md_estimate_size_before_relax): Really
+ make sure we treat weak like extern only for ELF. (Fixes
+ patch from 2001-07-25.)
+
+2002-02-15 Ben Elliston <bje@redhat.com>
+
+ * doc/as.texinfo: Add duplicate directory entry so that "info gas"
+ works as expected.
+
+2002-02-15 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * NEWS: Mention support for MMIX.
+
+2002-02-13 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (mips_need_elf_addend_fixup): Restructure into
+ a sequence of indpendent 'if' statements for easier debugging
+ and future modification.
+
+2002-02-13 Matt Fredette <fredette@netbsd.org>
+
+ * config/tc-m68k.c (md_show_usage): No longer display a
+ hard-coded "68020" for the default CPU, instead display the
+ canonical name of the true, configured default CPU.
+ (m68k_elf_final_processing): Mark objects for sub-68020
+ CPUs with the new EF_M68000 flag.
+
+2002-02-13 Andreas Schwab <schwab@suse.de>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Don't adjust
+ pc-relative relocations to merge sections in 64-bit mode.
+
+2002-02-13 Ben Elliston <bje@redhat.com>
+
+ * NEWS: Document floating point number handling in gasp.
+ * gasp.c: Include <assert.h> and "xregex.h".
+ (is_flonum): New function.
+ (chew_flownum): Likewise.
+ (change_base): Consume flonums from the input, where possible.
+ * doc/gasp.texi (Constants): Document floating point numbers.
+
+2002-02-12 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * config/tc-hppa.c (hppa_fix_adjustable): Don't adjust final types
+ that implicitly use LR and RR selectors.
+
+2002-02-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mn10300.c (other_registers): Added `epsw'. Mark `pc'
+ and `epsw' as available on AM33 and above only.
+ (other_register_name): Add logic to handle machine type encoded in
+ reg_number.
+
+2002-02-11 Tom Rix <trix@redhat.com>
+
+ * config/tc-ppc.c (md_apply_fix3): Check for insert fop invalid for
+ xcoff64.
+
+2002-06-11 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-sparc.c (U0x80000000, U0xffffffff): New constants.
+ Use all over.
+
+2002-02-11 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (md_assemble): Support 32bit address prefix.
+ (i386_displacement): Likewise.
+ (i386_index_check): Accept 32bit addressing in 64bit mode.
+
+2002-02-11 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-sh.c (dot): Removed unused function.
+
+2002-02-11 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: "make dep-am".
+ * Makefile.in: Regenerate.
+ * aclocal.m4: Regenerate.
+ * config.in: Regenerate.
+ * configure: Regenerate.
+ * doc/Makefile.in: Regenerate.
+
+2002-02-10 Richard Henderson <rth@redhat.com>
+
+ * doc/c-alpha.texi: New file.
+ * doc/Makefile.am (CPU_DOCS): Add it.
+ * doc/all.texi, doc/as.texinfo: Add hooks for Alpha.
+
+2002-02-09 Richard Henderson <rth@redhat.com>
+
+ * config/tc-alpha.c (O_samegp): New.
+ (USER_RELOC_P): Include it.
+ (alpha_reloc_op_tag, debug_exp, find_macro_match): Add it.
+ (md_apply_fix3): Handle BFD_RELOC_ALPHA_BRSGP.
+ (alpha_force_relocation, alpha_fix_adjustable): Likewise.
+ (alpha_validate_fix): New.
+ * config/tc-alpha.h (TC_VALIDATE_FIX): New.
+
+2002-02-09 Hans-Peter Nilsson <hp@axis.com>
+
+ * doc/c-cris.texi: New.
+ * doc/all.texi: @set CRIS.
+ * doc/as.texinfo: Ditto. Add CRIS gas manpage option overview.
+ Include c-cris.texi.
+ * doc/Makefile.am (CPU_DOCS): Add c-cris.texi
+ * doc/Makefile.in: Regenerate.
+
+2002-02-08 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (IS_SEXT_32BIT_NUM): New macro to
+ determine if a number is a sign-extended 32-bit number.
+ (load_register): Use IS_SEXT_32BIT_NUM.
+ (macro): Check if load/store macro handling is using a
+ constant 32-bit address on 64-bit address systems, and if
+ so optimize the generation of that address.
+
+2002-02-08 Richard Henderson <rth@redhat.com>
+
+ * config/tc-alpha.c (alpha_force_relocation): Don't assert that
+ we've eliminated all foreign relocation types yet.
+ (alpha_fix_adjustable): Likewise.
+
+2002-02-08 Alexandre Oliva <aoliva@redhat.com>
+
+ Contribute sh64-elf.
+ 2002-02-08 Alexandre Oliva <aoliva@redhat.com>
+ Stephen Clarke <Stephen.Clarke@st.com>
+ * doc/c-sh64.texi: Fix citation of SH64 architecture manual.
+ 2002-01-31 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-sh.c (md_relax_table): Added default sizes for
+ non-PC-relative UNDEF_MOVI, and relaxation sequences for
+ MOVI_16, MOVI_32 and MOVI_48.
+ * config/tc-sh64.c (shmedia_md_apply_fix3): Fix warning.
+ (shmedia_md_convert_frag): Handle non-PC-relative UNDEF_MOVI
+ and MOVI_16.
+ (shmedia_md_estimate_size_before_relax): Remove redundant
+ blocks. Set fragP->fr_var even if relaxation type unchanged.
+ Retain UNDEF_MOVI until expression decays to number.
+ 2002-01-24 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-sh64.c (shmedia_init_reloc): Handle new SHmedia PIC
+ relocation types. Take fixP->fx_addnumber into account too.
+ (shmedia_md_apply_fix): Likewise.
+ (shmedia_md_convert_frag): Likewise.
+ (shmedia_build_Mytes): Likewise.
+ (sh64_consume_datalabel): Complain about nested datalabel.
+ Support PIC relocs. Call sh_parse_name.
+ * config/tc-sh64.h (TC_RELOC_RTSYM_LOC_FIXUP): Extend definition
+ in tc-sh.h to SHmedia reloc types.
+ * config/tc-sh.c (SH64PCRELPLT, MOVI_PLT, MOVI_GOTOFF,
+ MOVI_GOTPC): New relaxation constants.
+ (md_relax_table): Introduce relaxation directives for PIC-related
+ constants.
+ (sh_PIC_related_p): Handle datalabel.
+ (sh_check_fixup): Choose SH5 PIC relocations.
+ (sh_cons_fix_new): Added BDF_RELOC_64.
+ (md_apply_fix3, sh_parse_name): Handle GOTPLT.
+ 2002-01-18 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-sh64.c (sh64_max_mem_for_rs_align_code): If the
+ current ISA is SHmedia, get 7 bytes.
+ 2001-11-28 Nick Clifton <nickc@cambridge.redhat.com>
+ * config/tc-sh.c (md_apply_fix3): Treat shmedia_md_apply_fix3 as a
+ void function.
+ * config/tc-sh64.c (shmedia_apply_fix): Rename to
+ shmedia_apply_fix3 and make void.
+ 2001-05-17 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-sh64.c (s_sh64_abi): Remove unused arguments passed to
+ as_bad.
+ 2001-04-12 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-sh64.h (md_parse_name): Take &c as argument.
+ 2001-03-14 DJ Delorie <dj@redhat.com>
+ * doc/Makefile.am (CPU_DOCS): Added c-sh64.texi
+ * doc/Makefile.in(CPU_DOCS): Ditto.
+ * doc/c-sh64.texi: New file.
+ * doc/as.texinfo: Add SH64 support.
+ 2001-03-13 DJ Delorie <dj@redhat.com>
+ * config/tc-sh64.c (shmedia_get_operands): Rename A_RESV_Fx to
+ A_REUSE_PREV so that its purpose is more obvious.
+ (shmedia_build_Mytes): Ditto.
+ 2001-03-07 DJ Delorie <dj@redhat.com>
+ * config/tc-sh64.c (sh64_vtable_entry): New, strip datalabels
+ before processing.
+ (sh64_vtable_inherit): Ditto.
+ (strip_datalabels): New, strip "datalabel" from given line.
+ * config/tc-sh.c (md_pseudo_table): Add sh64-specific vtable
+ pseudos.
+ 2001-03-06 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh64.c (shmedia_md_assemble): Move dwarf2_emit_insn
+ call ...
+ (shmedia_build_Mytes): ... to here.
+ 2001-03-06 DJ Delorie <dj@redhat.com>
+ * config/tc-sh.c: Remove sh64-specific uaquad now that there
+ is a generic one.
+ 2001-01-21 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh64.h (DWARF2_LINE_MIN_INSN_LENGTH): Override.
+ * config/tc-sh64.c (shmedia_md_assemble): Offset recorded insn
+ address by one in call to dwarf2_emit_insn.
+ 2001-01-13 Hans-Peter Nilsson <hpn@cygnus.com>
+ Implement ".abi" pseudo and correct .cranges descriptors. Correct
+ alignment handling broken by imported changes.
+ * config/tc-sh64.h (HANDLE_ALIGN): Override definition in tc-sh.h.
+ (sh64_handle_align): Declare.
+ (MAX_MEM_FOR_RS_ALIGN_CODE): Override definition in tc-sh.h.
+ (sh64_max_mem_for_rs_align_code): Declare.
+ (enum sh64_isa_values): Moved here from tc-sh64.c.
+ (md_do_align): Define.
+ (sh64_do_align): Declare.
+ (struct sh64_tc_frag_data): New.
+ (TC_FRAG_TYPE): Change to struct sh64_tc_frag_data. Users
+ changed.
+ (TC_FRAG_INIT): Change to set new datatype.
+ (struct sh64_segment_info_type): Rename member
+ last_flushed_location to last_contents_mark. All users changed.
+ (md_elf_section_change_hook, TC_CONS_FIX_NEW): Do not define.
+ (shmedia_elf_new_section, sh64_tc_cons_fix_new): Do not prototype.
+ * config/tc-sh.c (md_pseudo_table): Add ".abi".
+ (sh_elf_cons) [HAVE_SH64]: Call sh64_update_contents_mark instead
+ of unsetting seen_insn.
+ (md_assemble) [HAVE_SH64] <before new SHcompact sequence>: Also
+ call sh64_update_contents_mark.
+ (sh_handle_align): Remove HAVE_SH64-conditioned code.
+ * config/tc-sh64.c (sh64_isa_mode): Correct type from boolean to
+ enum sh64_isa_values.
+ (sh64_set_contents_type): Drop segT parameter. All callers changed.
+ (emitting_crange): Boolean guard moved to file scope from function
+ scope in sh64_set_contents_type.
+ (s_sh64_abi): New.
+ (sh64_update_contents_mark): New; most split out from
+ sh64_flush_pending_output.
+ (shmedia_md_end): Call sh64_update_contents_mark. Set
+ sh64_isa_mode to sh64_isa_sh5_guard unless sh64_isa_unspecified.
+ (sh64_do_align): New function.
+ (sh64_max_mem_for_rs_align_code): New function.
+ (sh64_handle_align): Rename from shmedia_do_align. Make
+ non-static. Add head comment. Emit zero bytes for n bytes modulo
+ four. Change return-type to void.
+ (shmedia_elf_new_section): Remove.
+ (shmedia_md_assemble): Call sh64_update_contents_mark.
+ (s_sh64_mode): Ditto. Do not call md_flush_pending_output. Make
+ new frag. Call sh64_update_contents_mark after making the new
+ frag.
+ (sh64_flush_pending_output): Just call sh64_update_contents_mark
+ and sh_flush_pending_output.
+ (sh64_flag_output): Also call md_flush_pending_output, but add
+ condition on not emitting_crange.
+ (sh64_tc_cons_fix_new): Remove.
+ 2001-01-12 Nick Clifton <nickc@redhat.com>
+ * config/tc-sh64.c (shmedia_do_align): Fix to work with new
+ alignment handling scheme imported from sourceware.
+ 2001-01-12 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh64.h (TARGET_FORMAT): Define.
+ (sh64_target_format): Prototype.
+ * config/tc-sh64.c (sh64_target_mach): New function.
+ 2001-01-07 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh64.c (shmedia_md_end): When equating a symbol, use
+ zero_address_frag instead of copying the frag of the symbol.
+ (shmedia_frob_file_before_adjust): Ditto.
+ (shmedia_md_apply_fix) <case BFD_RELOC_SH_IMM_MEDLOW16>: Cast mask
+ to valueT to remove signedness.
+ (shmedia_md_convert_frag): Add parameter final. Rename parameter
+ headers to output_bfd. Do not evaluate symbols if final is false;
+ do emit fixups.
+ (shmedia_md_estimate_size_before_relax) <case C (MOVI_IMM_32,
+ UNDEF_MOVI) et al>: If symbol cannot be modified to be PC-relative
+ to the current frag, call shmedia_md_convert_frag to emit fixups
+ and make frag_wane neutralize the frag. Update comments.
+ * config/tc-sh.c (md_convert_frag): Change caller of
+ shmedia_md_convert_frag.
+ 2001-01-06 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh64.h: Tweak comments and correct formatting.
+ * config/tc-sh64.c: Ditto.
+ (shmedia_md_convert_frag) <PT/PTA/PTB 32, 48 and 64 bit
+ expansion, MOVI pcrel expansion>: Fix thinko calculating offset
+ for the no-relocation case.
+ (shmedia_check_limits): Fix range check being off-by-one for PTA.
+ * config/tc-sh.c: Ditto. Add proper comments to #ifdef/#ifndef
+ wrappers.
+ (SH64PCREL16_F): Increment for proper max-PTA handling. Update
+ comment.
+ (SH64PCREL16_M, MOVI_16_M): Correct range thinko.
+ (SH64PCREL48_M, MOVI_48_M): Similar; don't count in length of
+ expansion.
+ (SH64PCREL32_M, MOVI_32_M): Ditto; handle overflowing expression.
+ Correct comment.
+ 2001-01-05 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh64.c (shmedia_md_apply_fix) <second switch, case
+ BFD_RELOC_SH_PT_16>: Set lowest bit in field to be relocated to 1.
+ (shmedia_md_convert_frag) <case C (SH64PCREL16_32, SH64PCREL16) et
+ al>: Set lowest bit of field to relocate to 1 and rest to empty,
+ if reloc is emitted.
+ 2000-12-31 Hans-Peter Nilsson <hpn@cygnus.com>
+ New options plus bugfixes.
+ * config/tc-sh.c (md_longopts): New options "-no-expand" and
+ "-expand-pt32".
+ (md_parse_option): Handle new options.
+ (md_show_usage): Add blurb for new options.
+ * config/tc-sh64.c (SHMEDIA_BFD_RELOC_PT): New macro.
+ (sh64_expand, sh64_pt32): New variables.
+ (shmedia_init_reloc): Handle BFD_RELOC_SH_PT_16.
+ (shmedia_md_apply_fix): Hold original fixP->fx_r_type in
+ orig_fx_r_type. Change SHMEDIA_BFD_RELOC_PT into
+ BFD_RELOC_SH_PT_16. Handle BFD_RELOC_SH_PT_16 as pc-relative.
+ <resolved previously-pc-relative relocs>: Handle
+ SHMEDIA_BFD_RELOC_PT and BFD_RELOC_SH_PT_16.
+ (shmedia_md_convert_frag) <case C (SH64PCREL16PT_64, SH64PCREL16),
+ case C (SH64PCREL16PT_32, SH64PCREL16)>: Modify to PTB if operand
+ points to SHcompact code.
+ <case C (SH64PCREL16_32, SH64PCREL16), case C (SH64PCREL16_64,
+ SH64PCREL16)>: Check that ISA of what operand points at and
+ PTA/PTB matches, or emit error.
+ (shmedia_check_limits): Handle BFD_RELOC_SH_PT_16 and
+ SHMEDIA_BFD_RELOC_PT.
+ (shmedia_immediate_op): If pcrel, emit fixup also for constant
+ operand.
+ (shmedia_build_Mytes) <case A_IMMS16>: Also check sh64_expand in
+ condition for MOVI expansion.
+ <case A_PCIMMS16BY4>: Handle expansion to 32 bits only, if
+ sh64_pt32. Emit only a BFD_RELOC_SH_PT_16 fixup if not
+ sh64_expand.
+ <case A_PCIMMS16BY4_PT>: Likewise, but emit a SHMEDIA_BFD_RELOC_PT
+ fixup.
+ (sh64_target_format): Error-check setting of sh64_pt32 and
+ sh64_expand. Fix typo in check for sh64_shcompact_const_crange.
+ (shmedia_md_pcrel_from_section): Handle BFD_RELOC_SH_PT_16 and
+ SHMEDIA_BFD_RELOC_PT as coming from SHmedia code.
+ 2000-12-31 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh64.c: Improve comments.
+ (shmedia_md_convert_frag): Remove inactive is_pt_variant code. Do
+ not say the linker will check correctness of PTA/PTB expansion.
+ (shmedia_md_end): Make non-static.
+ * config/tc-sh64.h (md_end): Define to shmedia_md_end. Add
+ prototype.
+ * config/tc-sh.c (sh_finalize): Remove.
+ * config/tc-sh.h (md_end): Do not define.
+ Remove prototype for sh_finalize.
+ 2000-12-30 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh64.c (shmedia_frob_section_type): Use a struct
+ sh64_section_data container when storing section type in tdata
+ field in elf_section_data.
+ * config/tc-sh.c (sh_elf_final_processing): Change from EF_SH64 to
+ EF_SH5.
+ * Makefile.am: Update dependencies.
+ * Makefile.in: Regenerate.
+ 2000-12-22 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh64.c (shmedia_md_assemble): Don't protect
+ dwarf2_emit_insn call with test on debug_type.
+ 2000-12-19 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh64.c (sh64_set_contents_type): Make contents-type
+ CRT_SH5_ISA32 sticky for 64-bit.
+ 2000-12-18 Hans-Peter Nilsson <hpn@cygnus.com>
+ Generate .crange sections when switching ISA mode or emitting
+ constants in same section as code.
+ * config/tc-sh64.c: Reformat structure definitions.
+ (sh64_end_of_assembly, sh64_mix, sh64_shcompact_const_crange): New
+ variables.
+ (sh64_set_contents_type): Rename from sh64_init_section. Rewrite
+ to emit a .cranges descriptor when contents type changes. Only
+ emit error if changing contents type and -no-mix is in effect.
+ (sh64_emit_crange, sh64_flush_last_crange, sh64_flag_output,
+ sh64_flush_pending_output, sh64_tc_cons_fix_new): New functions.
+ (shmedia_md_end): Set sh64_end_of_assembly. Pass
+ sh64_flush_last_crange over sections.
+ When checking main symbol of datalabel symbol, check for
+ STO_SH5_ISA32, not ISA type of section in definition.
+ (shmedia_frob_file_before_adjust): Check main symbol for
+ STO_SH5_ISA32; don't check ISA type of section in definition.
+ (shmedia_frob_section_type): Adjust for .cranges; set section flag
+ to SHF_SH5_ISA32_MIXED or SHF_SH5_ISA32 according to whether
+ .cranges entries have been output.
+ (shmedia_elf_new_section): Just call md_flush_pending_output.
+ (shmedia_md_assemble): Do not emit a BFD_RELOC_SH_SHMEDIA_CODE
+ fix. Do not set tc_segment_info_data.in_code for section. Call
+ sh64_set_contents_type for SHmedia code.
+ (s_sh64_mode): Do not call sh64_init_section or set seen_insn to
+ false. Call md_flush_pending_output.
+ (sh64_target_format): Check that -no-mix and
+ -shcompact-const-crange are used in sane combination with other
+ options.
+ (shmedia_md_pcrel_from_section): Check type of fix for how to
+ adjust pc-relative.
+ (sh64_consume_datalabel): Check symbol for having STO_SH5_ISA32,
+ not ISA type of section in definition.
+ * config/tc-sh64.h (struct sh64_segment_info_type): Rewrite to
+ hold contents-type state.
+ (md_flush_pending_output): Redefine to sh64_flush_pending_output.
+ (sh64_flush_pending_output): Declare.
+ (TC_CONS_FIX_NEW): Define to sh64_tc_cons_fix_new.
+ (sh64_tc_cons_fix_new): Declare.
+ * config/tc-sh.c (sh_elf_cons) [HAVE_SH64]: Unset seen_insn and
+ call sh64_flag_output.
+ (md_assemble) [HAVE_SH64]: Do not emit BFD_RELOC_SH_CODE. Just
+ call sh64_set_contents_type to mark SHcompact code and set
+ seen_insn.
+ (md_longopts): New options "-no-mix" and
+ "-shcompact-const-crange".
+ (md_parse_option): Handle new options.
+ (md_show_usage): Add blurb for new options.
+ (md_number_to_chars) [HAVE_SH64]: Call sh64_flag_output.
+ 2000-12-15 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh64.c: Delete investigated and obsolete fixme:s.
+ (sh64_last_insn_frag): New.
+ (shmedia_md_convert_frag): Use tc_frag_data field of incoming frag
+ to get frag for insn opcode for generating fixups; do not assume it
+ is the same frag.
+ (shmedia_build_Mytes): Set sh64_last_insn_frag after growing frag
+ for new insn.
+ * config/tc-sh64.h (ELF_TC_SPECIAL_SECTIONS): Define for .cranges
+ section.
+ (TC_FRAG_TYPE): Define as fragS *.
+ (TC_FRAG_INIT): Define to set tc_frag_data to sh64_last_insn_frag.
+ (sh64_last_insn_frag): Declare.
+ (sh64_consume_datalabel): Fix typo; check for seginfo != NULL,
+ not == NULL before dereferencing.
+ 2000-12-12 Hans-Peter Nilsson <hpn@cygnus.com>
+ Get rid of BFD section flag and EF_SH64_ABI64.
+ * config/tc-sh64.c (shmedia_frob_section_type): Use
+ elf_section_data (sec)->tdata, not a specific BFD section flag, to
+ communicate the section as containing SHmedia code. Describe why.
+ * config/tc-sh.c (sh_elf_final_processing): Tweak comment. Set
+ EF_SH64 regardless of ABI.
+ * config/tc-sh64.c (shmedia_md_apply_fix): Decapitalize "invalid"
+ in error message. Handle resolved expressions for
+ BFD_RELOC_SH_IMMS10, BFD_RELOC_SH_IMMS10BY2,
+ BFD_RELOC_SH_IMMS10BY4 and BFD_RELOC_64.
+ (shmedia_check_limits): Handle BFD_RELOC_64.
+ (sh64_adjust_symtab): Do not decrement the GAS symbol value for
+ a STO_SH5_ISA32 symbol, only the BFD value.
+ 2000-12-11 Ben Elliston <bje@redhat.com>
+ * config/tc-sh64.c: Call dwarf2_emit_insn, not the defunct
+ dwarf2_generate_asm_lineno.
+ 2000-12-11 Hans-Peter Nilsson <hpn@cygnus.com>
+ Handle PC-relative MOVI expansions with assembler relaxation.
+ Generate PC-relative relocs from 16-bit PC-relative expressions.
+ * config/tc-sh64.c (SHMEDIA_MD_PCREL_FROM_FIX): Break out from...
+ (shmedia_md_pcrel_from_section): ...here.
+ (shmedia_md_apply_fix): Handle fixups for 16-bit operands that has
+ turned completely resolved. Adjust relocation type for 16-bit
+ immediate operands that has turned PC-relative. Adjust back for
+ MD_PCREL_FROM_SECTION being applied twice.
+ (shmedia_md_convert_frag): Always emit reloc for expression with
+ global or weak symbol. Handle relaxation result for PC-relative
+ expressions.
+ (shmedia_md_estimate_size_before_relax): An expression with a weak
+ or global symbol can not be relaxed. Break out tests for
+ relaxable symbol into variable sym_relaxable.
+ <cases C (MOVI_IMM_64, UNDEF_MOVI) and C (MOVI_IMM_32,
+ UNDEF_MOVI)>: Break out any PC-relative expression and change
+ relaxation type.
+ (shmedia_build_Mytes): CSE &operands->operands[j] into variable
+ opjp.
+ <case A_IMMS16>: Fix typo for initial minor relaxation type of
+ MOVI expansion. If X_op_symbol of the immediate expression is
+ set, make an expression symbol for the argument to frag_var.
+ * config/tc-sh.c (MOVI_IMM_32_PCREL, MOVI_IMM_64_PCREL): New
+ relaxations.
+ (END): Adjust for new relaxations.
+ (md_relax_table): Add entries for new relaxations.
+ 2000-12-07 Ben Elliston <bje@redhat.com>
+ * config/tc-sh64.c (shmedia_parse_reg): Initialize variable len.
+ 2000-12-07 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh64.c (shmedia_md_convert_frag): Correct all MOVI and
+ SHORI operand offsets in PT/PTA/PTB expansions.
+ 2000-12-05 Hans-Peter Nilsson <hpn@cygnus.com>
+ Implement DataLabel semantics.
+ * config/tc-sh.c (sh_frob_file) [HAVE_SH64]: Call
+ shmedia_frob_file_before_adjust.
+ * config/tc-sh64.c [! OBJ_ELF]: Emit #error.
+ (DATALABEL_SUFFIX): Define.
+ (shmedia_md_end) <before adjusting STO_SH5_ISA32 symbols>: Walk
+ symbol list to update "datalabel" symbols to their main symbol
+ counterparts.
+ (shmedia_frob_file_before_adjust): New.
+ (sh64_adjust_symtab): For remaining datalabel symbols, set to
+ undefined and set STT_DATALABEL.
+ (sh64_frob_label): Initialize TC symbol field.
+ (sh64_consume_datalabel): Actually implement semantics. New
+ parameter operandf, call it instead of expression.
+ (sh64_exclude_symbol): New.
+ * config/tc-sh64.h (md_parse_name): Pass on the function operand
+ to sh64_consume_datalabel.
+ (tc_symbol_new_hook): Define to tc_frob_symbol.
+ (TC_SYMFIELD_TYPE): Define to symbolS *.
+ (tc_frob_symbol): Define to call sh64_exclude_symbol.
+ 2000-12-01 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh64.c (shmedia_init_reloc): Tweak comment for default
+ case.
+ (shmedia_md_assemble): Call dwarf2_generate_asm_lineno if
+ generating dwarf2 debug information.
+ 2000-11-30 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh64.c (sh64_target_format): Use elf64-sh64l and
+ elf64-sh64 for the 64-bit ABI.
+ * config/tc-sh.c (md_show_usage): Tweak usage output for -abi=*
+ option.
+ 2000-11-29 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh.c: Remove conditionalizing on HAVE_SH64 for
+ case-insensitivity.
+ 2000-11-27 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh64.c: Tweak comments, formatting and error messages.
+ (enum sh64_abi_values): New type.
+ (enum sh64_isa_values): New type.
+ (sh64_isa_mode): Replace shmedia_mode. All referers changed.
+ (seen_shcompact_mode, seen_shmedia_mode): Delete.
+ (sh64_abi): Replace shmedia_64.
+ (shmedia_md_convert_frag) <C (MOVI_IMM_64, MOVI_64),
+ C (MOVI_IMM_32, MOVI_32)>: Correct register number handling.
+ (s_sh64_mode): Check validity for this target.
+ (sh64_target_format): Initialize defaults for ISA and ABI.
+ Fallback to old object format if no SH64 ISA or ABI has been
+ specified.
+ * config/tc-sh.c (md_parse_option): Check combinations for errors.
+ (sh_elf_final_processing): Change to have EF_SH64_ABI64 for 64-bit
+ ABI and EF_SH64 for 32-bit ABI, if SH64 options are specified.
+ * config/tc-sh64.h: Fix typo in comment.
+ 2000-11-25 Hans-Peter Nilsson <hpn@cygnus.com>
+ * config/tc-sh64.c (shmedia_md_estimate_size_before_relax)
+ <PT fixups for absolute values>: Size will be longest, not
+ shortest.
+ (shmedia_md_convert_frag): Disable PTB-warning machinery. Correct
+ all MOVI and SHORI operand offsets in PT/PTA/PTB expansions.
+ * config/tc-sh.c (parse_reg) [HAVE_SH64]: Add local variables l0
+ and l1 to hold lowercase of two first characters. Change all
+ remaining TO_LOWER to tolower.
+ * config/tc-sh64.c (TO_LOWER): Delete.
+ (shmedia_find_cooked_opcode): Use tolower, not TO_LOWER.
+ (md_parse_name): Define.
+ (sh64_consume_datalabel): Declare.
+ (DOLLAR_DOT): Define.
+ * config/tc-sh64.c (shmedia_parse_exp): New.
+ (sh64_consume_datalabel): New; just ignoring datalabel semantics.
+ (shmedia_parse_reg): Remove const from src
+ parameter.
+ (shmedia_get_operands): Ditto for args parameter and ptr variable.
+ (shmedia_md_assemble): Ditto for op_end variable.
+ (shmedia_get_operand): Ditto for ptr parameter and src variable.
+ Use shmedia_parse_exp, not parse_exp.
+ * config/tc-sh64.c (shmedia_parse_reg): Add shmedia_arg_type
+ parameter. All callers changed.
+ (shmedia_get_operand): Add shmedia_arg_type parameter. All
+ callers changed.
+ (shmedia_parse_reg): Put first two character in local variables.
+ Use tolower, not TO_LOWER. If no register is found and argtype
+ indicates a control register, scan shmedia_creg_table
+ case-insensitive.
+ 2000-11-24 Hans-Peter Nilsson <hpn@cygnus.com>
+ * Makefile.am (CPU_TYPES): Add sh64.
+ (TARGET_CPU_CFILES): Add config/tc-sh64.c.
+ (TARGET_CPU_HFILES): Add config/tc-sh64.h.
+ Regenerate dependencies.
+ * Makefile.in: Regenerate.
+ * configure.in: Add support for sh64-*-elf*.
+ * configure: Regenerate.
+ * config/tc-sh64.h: New.
+ * config/tc-sh64.c: New.
+ * config/tc-sh.c (md_pseudo_table) [HAVE_SH64]: New pseudos
+ .mode, .isa and .uaquad.
+ [HAVE_SH64] (SH64PCREL16_32, SH64PCREL16_64, SH64PCREL16PT_32,
+ SH64PCREL16PT_64, MOVI_IMM_32, MOVI_IMM_64): Define.
+ [HAVE_SH64] (END): Define as 10.
+ [HAVE_SH64] (UNDEF_SH64PCREL, SH64PCREL16, SH64PCREL32,
+ SH64PCREL48, SH64PCREL64, UNDEF_MOVI, MOVI_16, MOVI_32, MOVI_48,
+ MOVI_64): Define.
+ [HAVE_SH64] (SH64PCREL16_F, SH64PCREL16_M, SH64PCREL16_LENGTH,
+ SH64PCREL32_F, SH64PCREL32_M, SH64PCREL32_LENGTH, SH64PCREL48_F,
+ SH64PCREL48_M, SH64PCREL48_LENGTH, SH64PCREL64_LENGTH,
+ MOVI_16_LENGTH, MOVI_32_LENGTH, MOVI_48_LENGTH, MOVI_64_LENGTH):
+ Define.
+ (md_relax_table) [HAVE_SH64]: Provide relaxations for SHmedia.
+ (md_begin) [HAVE_SH64]: Call shmedia_md_begin.
+ (parse_reg) [HAVE_SH64]: Parse register names case-insensitive.
+ (md_assemble) [HAVE_SH64]: Call shmedia_md_assemble if assembling
+ SHmedia instructions. Handle state-change after switching to
+ SHcompact.
+ (md_longopts) [HAVE_SH64]: New options --isa=* and --abi=*.
+ (md_parse_option) [HAVE_SH64]: Parse new options.
+ (md_show_usage) [HAVE_SH64]: Show usage of new options.
+ (md_convert_frag) [HAVE_SH64] <default>: Call
+ shmedia_md_convert_frag instead of abort.
+ (sh_force_relocation) [HAVE_SH64]: Also force relocation for
+ BFD_RELOC_SH_SHMEDIA_CODE.
+ (sh_elf_final_processing) [HAVE_SH64]: Set flags identifying
+ SHcompact or SHmedia code.
+ (md_apply_fix) [HAVE_SH64] <default>: Return result from calling
+ shmedia_md_apply_fix instead of abort.
+ (md_estimate_size_before_relax) [HAVE_SH64] <default>: Return
+ result from calling shmedia_md_estimate_size_before_relax instead
+ of calling abort.
+ (sh_do_align) [HAVE_SH64]: If shmedia_mode, let shmedia_do_align
+ do the work.
+ (tc_gen_reloc) [HAVE_SH64]: For unrecognized relocs, call
+ shmedia_init_reloc and do nothing more if it returns non-zero.
+ (sh_finalize) [HAVE_SH64]: Call shmedia_md_end.
+ * po/POTFILES.in: Regenerate.
+ * po/gas.pot: Regenerate.
+
+2002-02-06 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-sh.c (parse_at): Install the correct version of
+ 2002-02-04's patch.
+
+ * config/tc-sh.c (md_apply_fix3) <BFD_RELOC_32_PLT_PCREL>: Don't
+ assume fixP->fx_subsy is non-NULL.
+
+2002-02-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-sh.c (parse_at): Set arg type of @(expr,pc) to
+ A_DISP_PC_ABS, and adjust it by -4.
+ (get_specific): Accept A_DISP_PC_ABS where A_DISP_PC is
+ expected.
+ (build_Mytes): Mark PCRELIMM fix-ups as pc-relative only if
+ the operand type is not A_DISP_PC_ABS.
+
+2002-02-04 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/tc-mmix.c (tc_gen_reloc): Don't try and take the value of
+ common and weak symbols. Handle common and weak symbols as
+ undefined symbols with regards to GREG handling and merging.
+ (mmix_frob_file): Ditto.
+
+2002-02-02 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * configure.in (hppa-*-netbsd*): New target.
+ * configure: Regenerate.
+ * config/tc-hppa.h: Also define WARN_COMMENTS if TE_NetBSD.
+
+2002-02-02 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-v850.c: Add missing prototypes amd use old-style
+ function definitions.
+ (AREA_ZDA, AREA_SDA, AREA_TDA): Delete.
+ (sdata_section tdata_section, zdata_section, sbss_section,
+ tbss_section, zbss_section, rosdata_section, rozdata_section,
+ scommon_section, tcommon_section, zcommon_section,
+ call_table_data_section, call_table_text_section): Delete.
+ (v850_sdata, v850_tdata, v850_zdata, v850_sbss, v850_tbss,
+ v850_zbss, v850_bss, v850_rosdata, v850_rozdata,
+ v850_call_table_data, v850_call_table_text): Delete.
+ (struct v850_seg_entry): New.
+ (v850_seg_table): New.
+ (SDATA_SECTION TDATA_SECTION, ZDATA_SECTION, SBSS_SECTION,
+ TBSS_SECTION, ZBSS_SECTION, BSS_SECTION, ROSDATA_SECTION,
+ ROZDATA_SECTION, SCOMMON_SECTION, TCOMMON_SECTION, ZCOMMON_SECTION,
+ CALL_TABLE_DATA_SECTION, CALL_TABLE_TEXT_SECTION): Define.
+ (do_v850_seg): New.
+ (v850_seg): New.
+ (v850_comm): Use do_v850_seg and v850_seg_table. Simplify
+ recording of alignment.
+ (md_pseudo_table): Use v850_seg.
+ (md_begin): Don't init .call_table_data and .call_table_text here.
+ Set v850_seg_table bss entry.
+
+2002-02-01 Hans-Peter Nilsson <hp@bitrange.com>
+
+ Support on-demand global register allocation by passing on
+ base-plus-offset relocs to the linker.
+ * config/tc-mmix.c: Tweak and fix typos in comments.
+ (allocate_undefined_gregs_in_linker): New variable.
+ (OPTION_LINKER_ALLOCATED_GREGS): New option macro.
+ (md_longopts): Add --linker-allocated-gregs.
+ (md_parse_option) <case 'x'>: Imply --linker-allocated-gregs.
+ <case OPTION_LINKER_ALLOCATED_GREGS>: New.
+ (md_show_usage): Update text for -x. Add text for
+ --linker-allocated-gregs.
+ (tc_gen_reloc): Derive default value for addend from val and
+ baddsy. Use addsec and bfd_is_abs_section in more places. Don't
+ emit error for BFD_RELOC_MMIX_BASE_PLUS_OFFSET without suitable
+ GREG if allocate_undefined_gregs_in_linker.
+ * doc/as.texinfo (Overview) <Target MMIX options>: Add
+ --linker-allocated-gregs.
+ * doc/c-mmix.texi (MMIX-Opts): Add blurb about
+ --linker-allocated-gregs. Mention that it's implied by -x.
+ (MMIX-Pseudos) <GREG>: Mention when and how a GREG can be omitted.
+ (MMIX-mmixal): Clarify dated comparison and location of MMIXware.
+
+ * config/tc-mmix.h (md_parse_name): Use ISUPPER, not isupper.
+
+2002-02-01 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am"
+ * Makefile.in: Regenerate.
+
+2002-01-31 Ivan Guzvinec <ivang@opencores.org>
+
+ * config/tc-or32.c: New file.
+ * config/tc-or32.h: New file.
+ * configure.in: Add support for or32 targets.
+ * configure: Regenerate.
+ * config/obj-coff.c: Add support for or32 targets.
+ * config/obj-coff.h: Add support for or32 targets.
+ * Makefile.am: Add support for or32 targets.
+ * Makefile.in: Regenerate.
+ * NEWS: Mention support for OpenRISC.
+ * doc/Makefile.in: Regenerate.
+ * po/POTFILES.in: Regenerate.
+ * po/gas.pot: Regenerate.
+
+2002-01-30 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/tc-sh.c (parse_reg): Fix end-of-word check for is, ix, iy
+ and mod.
+
+2002-01-29 Chris Demetriou <cgd@broadcom.com>
+
+ * config/tc-mips.c (tc_gen_reloc): Arrange for
+ BFD_RELOC_PCREL_HI16_S relocations to be output relative to
+ their LO16 parts, even for ELF.
+
+2002-01-29 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/tc-i386.c: Protect definitions of true and false
+ from redefinition.
+
+2002-01-28 Jakub Jelinek <jakub@redhat.com>
+
+ * config/obj-elf.c (elf_frob_file_before_adjust): Remove symbols
+ made because of .weak, if they are neither defined nor used in any
+ way.
+
+2002-01-27 Daniel Jacobowitz <drow@mvista.com>
+
+ * configure: Regenerated.
+
+2002-01-26 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * doc/Makefile.am (install): Depend on install-info.
+ * doc/Makefile.in: Regenerate.
+
+2002-01-26 Nick Clifton <nick@redhat.com>
+
+ * po/fr.po: Updated version
+
+2002-01-24 Kazu Hirata <kazu@hxi.com>
+
+ * config/tc-h8300.c (check_operand): Don't print a warning
+ when a valid 24-bit address is given to a 16-bit address
+ operand.
+
+2002-01-24 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-sh.c (sh_elf_suffix): Removed.
+ (sh_PIC_related_p, sh_check_fixup, sh_cons_fix_new,
+ sh_end_of_match, sh_parse_name): New functions.
+ (sh_elf_cons): Simplify.
+ (parse_exp): Reject misplaced PIC operands.
+ (md_undefined_symbol): Simplify.
+ (sh_fix_adjustable): Let @GOTOFF be adjusted.
+ (md_apply_fix3): Write @PLT and @GOTOFF addends in place.
+ (tc_gen_reloc): Move fixp subsy absolute value into addnumber.
+ Complain if subsy remains at the end.
+ * config/tc-sh.h (sh_parse_name, sh_cons_fix_new): Declare.
+ (md_parse_name, TC_CONS_FIX_NEW, O_PIC_reloc): Define.
+
+2002-01-22 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-mn10300.c (xr_registers): Move `pc'...
+ (other_registers): ... here.
+
+2002-01-22 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * gas/po/POTFILES.in: Regenerate.
+
+2002-01-21 DJ Delorie <dj@redhat.com>
+
+ * config/obj-coff.c (obj_coff_init_stab_section): Make the
+ stabstr_name allocation permanent, as it will be referenced from
+ the section hash.
+
+2002-01-21 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * configure.in (ia64-*-netbsd*): New target.
+ * configure: Regenerate.
+
+2002-01-21 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * doc/as.texinfo (Overview) <Target ARM options>: Add missing {}
+ to @dots call.
+ <Detailed description, ARM options>: Ditto.
+ * doc/c-arm.texi (ARM Options): Ditto.
+
+2002-01-18 Richard Earnshaw <rearnsha@arm.com>
+
+ * tc-arm.c (do_xsc_mia, do_xsc_mar, do_xsc_mra): Renamed from
+ do_mia, do_mar and do_mra respectively.
+ (do_mav_*): Renamed from do_c_*.
+ (mav_reg_required_here, mav_parse_offset): Renamed from
+ cirrus_reg_required_here and cirrus_parse_offset respectively.
+ (MAV_MODE?): Renamed from CIRRUS_MODE?.
+
+2002-01-18 Richard Earnshaw <rearnsha@arm.com>
+ Keith Walker <keith.walker@arm.com>
+
+ * tc-arm.c (ARM_EXT_V5J, ARM_ARCH_V5TEJ): Define.
+ (insns): Add pattern for bxj instruction.
+ (do_bxj): New function.
+ (arm_cpus): Add arm926ej.
+ (arm_archs): Add armv5tej.
+
+2002-01-18 Richard Earnshaw <rearnsha@arm.com>
+
+ * doc/c-arm.texi: Add new fpe options to list of supported flags.
+
+2002-01-19 Keith Walker <keith.walker@arm.com>
+
+ * tc-arm.c (arm_fpus): Add fpe2 and fpe3.
+
+2002-01-18 Richard Earnshaw <rearnsha@arm.com>
+
+ * NEWS: Mention new ARM command-line options and VFP support.
+
+ * config/tc-arm.c (ARM_CEXT_XSCALE): Replaces ARM_EXT_XSCALE. All
+ uses changed.
+ (ARM_CEXT_MAVERICK): Similarly.
+ (ARM_ANY): Now means any core instruction.
+ (CPU_DEFAULT): Default to ARM_ANY.
+ (uses_apcs_26, atcps, support_interwork, uses_apcs_float)
+ (pic_code): Declare for all object types. Make type int.
+ (legacy_cpu, legacy_fpu, mcpu_cpu_opt, mcpu_fpu_opt, march_cpu_opt)
+ (march_fpu_opt, mfpu_opt): Declare.
+ (md_longopts): Tidy up conditional definitions.
+ (arm_opts, arm_cpus, arm_archs, arm_fpus, arm_extensions)
+ (arm_long_opts): New tables.
+ (arm_parse_cpu, arm_parse_arch, arm_parse_fpu): New functions.
+ (arm_parse_extension): New function.
+ (md_parse_option): Rewrite using new table-driven system.
+ (md_show_usage): Use new table-driven system.
+ (md_begin): Calculate cpu_variant from command line option data.
+ * doc/as.texinfo (ARM ISA options): Docuement new ARM-specific
+ command-line options.
+ * doc/c-arm.texi: Likewise.
+
+2002-01-18 Andreas Jaeger <aj@suse.de>
+
+ * as.c (parse_args): Update year.
+
+2002-01-17 Timothy Wall <twall@alum.mit.edu>
+
+ * config/tc-tic54x.c (encode_address): Add a more informative
+ warning about incorrect syntax.
+
+2002-01-17 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * po/gas.pot: Regenerate.
+
+2002-01-17 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * macro.c (get_any_string): Add no-c-format comment to prevent
+ confusion when translating string.
+ * gasp.c (get_any_string): Add no-c-format comment to prevent
+ confusion when translating string.
+
+2002-01-16 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+ Johannes Stezenbach <js@convergence.de>
+ * config/tc-mips.c (percent_op): Ensure longer percent_op's are
+ matched before the shorter ones.
+ (my_getSmallParser): Fix handling of nested parentheses in
+ percent_op's. Code cleanup.
+ (my_getPercentOp): New function, code from my_getSmallParser.
+ (my_getSmallExpression): Fix handling of closing parentheses.
+ Code cleanup. Better comments.
+
+2002-01-16 Nick Clifton <nickc@redhat.com>
+
+ po/tr.po: New file: Turkish translation.
+ configure.in (LINGUAS): Add "tr".
+ configure: Regenerate.
+
+2002-01-15 Richard Earnshaw <rearnsha@arm.com>
+
+ Support for VFP instructions
+ * tc-arm.c (CP_WB_OK, CP_NO_WB): New defines.
+ (cp_address_required_here): New argument wb_ok. When false, do not
+ accept write-back forms of addressing. Change all callers.
+ (FPU_VFP_EXT_NONE, FPU_VFP_EXT_V1xD, FPU_VFP_VFP_V1)
+ (FPU_VFP_EXT_V2): Define.
+ (FPU_ARCH_VFP, FPU_ARCH_VFP_V1xD, FPU_ARCH_VFP_V1, FPU_ARCH_VFP_V2):
+ Define in terms of above.
+ (vfp_dp_reg_pos, vfp_sp_reg_pos, vfp_ldstm_type): New enums.
+ (vfp_reg): New struct.
+ (vfp_regs): New array of registers.
+ (insns): Add VFP instructions.
+ (sn_table): New array of VFP single-precision register names.
+ (dn_table): New array of VFP double-precision register names.
+ (all_reg_maps): Add the new register tables.
+ (arm_reg_type): Add new values for above. Increase RET_TYPE_MAX.
+ (vfp_sp_reg_required_here, vfp_dp_reg_required_here, do_vfp_sp_monadic)
+ (do_vfp_dp_monadic, do_vfp_sp_dyadic, do_vfp_dp_dyadic)
+ (do_vfp_reg_from_sp, do_vfp_sp_reg2, do_vfp_sp_from_reg)
+ (do_vfp_reg_from_dp, do_vfp_reg2_from_dp, do_vfp_dp_from_reg)
+ (do_vfp_dp_from_reg2, vfp_psr_parse, vfp_psr_required_here)
+ (do_vfp_reg_from_ctrl, do_vfp_ctrl_from_reg, do_vfp_sp_ldst)
+ (do_vfp_dp_ldst, vfp_sp_reg_list, vfp_dp_reg_list, vfp_sp_ldstm)
+ (vfp_dp_ldstm, do_vfp_sp_ldstmia, do_vfp_sp_ldstmdb, do_vfp_ldstmia)
+ (do_vfp_dp_ldstmdb, do_vfp_xp_ldstmia, do_vfp_xp_ldstmdb)
+ (do_vfp_sp_compare_z, do_vfp_dp_compare_z, do_vfp_dp_sp_cvt)
+ (do_vfp_sp_dp_cvt): New functions.
+ (md_begin): Set soft-float flag for appropriate VFP work.
+ (md_atof): Handle VFP-format doubles.
+ (md_parse_option): Handle VFP command-line options.
+ (md_show_usage): Display VFP command-line options.
+
+2002-01-15 Richard Earnshaw <rearnsha@arm.com>
+
+ * tc-arm.c (md_parse_option): Tidy up setting of cpu_variant for
+ various command line options.
+
+2002-01-15 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-xstormy16.c: (xstormy16_fix_adjustable): Do not fix
+ vtinherit relocs.
+ (xstormy16_md_apply_fix3): Do not return a value.
+
+2002-01-14 Richard Earnshaw <rearnsha@arm.com>
+
+ * tc-arm.c (md_longopts): On targets that aren't bi-endian, support
+ the -EL/-EB option that matches the target's endianness.
+ (md_parse_option): Likewise.
+
+2002-01-14 Richard Earnshaw <rearnsha@arm.com>
+
+ * tc-arm.c (md_longopts): Fix misplaced #endif -- the -oabi option
+ is not dependent on ARM_BI_ENDIAN.
+
+2002-01-14 Richard Earnshaw <rearnsha@arm.com>
+
+ * tc-arm.c (all error messages): Normalize capitalization of messages.
+
+ * tc-arm.h (md_operand): Delete define.
+ * tc-arm.c (in_my_get_expression): New static variable.
+ (my_get_expression): Set and clear it.
+ (md_operand): New function. If called from my_get_expression
+ put the error in inst.error.
+ (output_inst): Now takes argument of instruction being assembled.
+ Print it out with any error message.
+ (do_ldst, do_ldstv4, thumb_load_store): Fault attempt to use a store
+ with '=' syntax.
+ (end_of_line): Don't update inst.error if it is already set.
+
+2002-01-11 Richard Earnshaw <rearnsha@arm.com>
+
+ * tc-arm.c (do_ldst): Fix handling an immediate expression pseudo
+ op that can be translated into a mvn instruction.
+
+2002-01-11 Steve Ellcey <sje@cup.hp.com>
+
+ * gas/config/tc-ia64.h (MD_FLAGS_DEFAULT): New Macro for
+ setting default md.flags.
+ (SHT_INIT_ARRAY): New elf special section used by HP-UX.
+ (SHT_FINI_ARRAY): New elf special section used by HP-UX.
+ * gas/config/tc-ia64.c (setup_unwind_header): Add support
+ for 32 bit unwind info blocks.
+ (generate_unwind_image): Add support for different types
+ of unwind images (32 bits and/or big-endian).
+ (ia64_init): Use MD_FLAGS_DEFAULT to set md.flags.
+ (ia64_target_format): Add support for hpux target formats.
+ (ia64_gen_real_reloc_type): Add support for FUNC_IPLT_RELOC.
+ (ia64_elf_section_type): Add support for SHT_INIT_ARRAY and
+ SHT_FINI_ARRAY elf section types.
+
+2002-01-10 Richard Earnshaw <rearnsha@arm.com>
+
+ * tc-arm.c (struct reg_entry): Move before prototypes.
+ (int_register, cp_register, fp_register): Delete.
+ (reg_table): Delete. Replaced with ...
+ (rn_table, cp_table, cn_table, fn_table, mav_mvf_table)
+ (mav_mvd_table, mav_mvfx_table, mav_mvdx_table, mav_mvax_table)
+ (mav_dspsc_table): ... one table per register set.
+ (arm_reg_hsh): Delete.
+ (struct reg_map): New structure.
+ (all_reg_maps): New array.
+ (enum arm_reg_type): New enums.
+ (build_reg_hsh): New function.
+ (insert_reg_alias): Use hash table passed by caller. Adjust all
+ callers.
+ (create_register_alias): New function, split out from ...
+ (md_assemble): ... here.
+ (md_begin): Build new register hash tables.
+ (arm_reg_parse): New argument for the hash table to search. Adjust all
+ callers.
+ (arm_reg_parse_any): New function.
+ (co_proc_number): Look up the processor number in the processor hash
+ table.
+ (cirrus_regtype): Delete.
+ (cirrus_register, cirrus_mvf_register, cirrus_mvd_register)
+ (cirrus_mvfx_register, cirrus_mvdx_register, cirrus_mvax_register)
+ (ARM_EXT_MAVERICKsc_register): Delete.
+ (do_c_binops_1, do_c_binops_2, do_c_binops_3): Delete.
+ (do_c_binops_1[a-o], do_c_binops_2[a-c], do_c_binops_3[a-d]): New
+ functions.
+ (do_c_triple_4, do_c_triple_5): Delete.
+ (do_c_triple_4[ab], do_c_triple_5[a-h]): New functions.
+ (do_c_quad_6): Delete.
+ (do_c_quad_6[ab]): New functions.
+ (do_c_binops, do_c_triple, do_c_quad, do_c_shift, do_c_ldst): Rework
+ arguments to use new register parsing methods.
+ (cirrus_reg_required_here): Likewise.
+ (insns): Reclassify cirrus maverick worker functions.
+ (cirrus_valid_reg): Delete.
+
+2002-01-07 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * configure.in (sh*le): Set cpu_type=sh and endian=little.
+ (sh*-*-netbsdelf*): New target.
+ * configure: Regenerate.
+ * tc-sh.h: Update copyright years.
+ (TARGET_FORMAT): Add version for TE_NetBSD.
+
+2002-01-07 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * read.c (emit_expr): Do not allow 'size' or 'nbytes' to go
+ negative.
+
+2002-01-06 Alan Modra <amodra@bigpond.net.au>
+
+ * config/tc-m68k.h (md_prepare_relax_scan): Rewrite.
+ * config/tc-m68k.c (md_relax_table): Add md_prepare_relax_scan comment.
+
+2002-01-05 Daniel Jacobowitz <drow@mvista.com>
+
+ * tc-mips.c (mips_cprestore_valid): New flag.
+ (mips_frame_reg_valid): New flag.
+ (macro) [M_JAL_2]: Check both flags.
+ [M_JAL_A]: Likewise.
+ (s_cprestore): Set mips_cprestore_valid.
+ (tc_get_register): If setting mips_frame_reg, set
+ mips_frame_reg_valid and clear mips_cprestore_valid.
+ (s_mips_ent): Clear both flags.
+ (s_mips_end): Clear both flags.
+
+2002-01-05 Alan Modra <amodra@bigpond.net.au>
+
+ * write.c (write_object_file): Make use of bfd_section_list_remove.
+ * config/obj-ecoff.c (ecoff_frob_file): Likewise.
+ * config/tc-mmix.c (mmix_frob_file): Likewise.
+
+2002-01-04 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * configure.in (i386-*-netbsdelf*): Collapse target into...
+ (i386-*-netbsd*): ...this. Add support for x86-64.
+ * configure: Regenerated.
+
+2002-01-03 matthew green <mrg@redhat.com>
+
+ * config/tc-ppc.c (md_parse_option): BookE is not Motorola specific.
+
+2002-01-02 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-m68k.c (md_estimate_size_before_relax): Test for a
+ NULL frag link.
+
+For older changes see ChangeLog-0001
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/x/binutils/gas/ChangeLog-9295 b/x/binutils/gas/ChangeLog-9295
new file mode 100644
index 0000000..7135733
--- /dev/null
+++ b/x/binutils/gas/ChangeLog-9295
@@ -0,0 +1,13117 @@
+Sat Dec 30 23:42:51 1995 Jeffrey A Law (law@cygnus.com)
+
+ * ecoff.c (ecoff_stab): Simplify. Correctly handle sym + offset
+ addresses for static variables.
+
+Thu Dec 21 12:54:32 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (mapping): Make @got give a real GOT relocation,
+ and xgot give the old toc16 relocation.
+ (md_apply_fix3): Support all GOT relocations.
+
+Wed Dec 20 14:57:17 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (load_address): Correctly handle a constant in
+ SVR4_PIC case. From Richard Kenner <kenner@vlsi1.ultra.nyu.edu>.
+
+Fri Dec 15 14:25:07 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/tc-sh.c (parse_reg): Recognize SH3 registers.
+ (get_specific): Handle A_SSR, A_SPC and A_REG_B.
+ (build_Mbytes): Handle REG_B.
+
+Fri Dec 15 16:07:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (ecoff_build_aux): Use new bfd_big_endian macro.
+
+Fri Dec 15 12:11:48 1995 Raymond Jou <rjou@mexican.cygnus.com>
+
+ * mpw-make.sed: If linking, edit ALL_CFLAGS to CFLAGS.
+
+Thu Dec 14 15:09:52 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (write_object_file): Set the s_align field to
+ the number of bytes, rather than to the power of 2.
+
+Tue Dec 12 12:19:37 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (DISTCLEAN_HERE): New variable.
+ (distclean): Use it.
+ (maintainer-clean): Depend upon clean-here rather than clean,
+ distclean, and clean-info. Run make maintainer-clean in doc.
+ Remove files listed in DISTCLEAN_HERE.
+ * doc/Makefile.in (maintainer-clean realclean): Split out from
+ distclean. Depend upon clean-info and distclean.
+
+Mon Dec 11 16:23:51 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mac-as.r: Fix copyright and version strings.
+ (cfrg): Use PROG_NAME instead of literal name.
+
+Mon Dec 11 14:14:08 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (read_a_source_file): If tc_unrecognized_line is defined,
+ call it.
+ * config/tc-a29k.h (tc_unrecognized_line): Define.
+ * config/tc-a29k.c (a29k_unrecognized_line): New function.
+ (md_operand): Handle a29k style local dollar labels.
+
+Wed Dec 6 17:52:52 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-multi.h: If OBJ_MAYBE_ELF, define OBJ_SYMFIELD_TYPE.
+
+Tue Dec 5 13:26:34 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * read.c (s_fill): If md_flush_pending_output is defined, call
+ it.
+
+Mon Dec 4 15:10:53 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/obj-coff.c (size_section, fill_section, fixup_mdeps):
+ Treat rs_align_code like rs_align.
+
+Sun Dec 3 16:46:54 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * config/tc-arm.c (cp_address_required_here): Set pre_inc when
+ converting an absolute address into a PC-relative one.
+
+Fri Dec 1 11:57:56 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Don't always use te-generic.h for emulation.
+ (powerpc-apple-macos): Use emulation te-macos.h.
+ * mpw-make.sed (install, install-only): Edit in Mac-specific
+ install procedure.
+
+Fri Dec 1 10:59:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Improve message about unsupported ELF targets.
+ * configure: Rebuild.
+
+ * config/tc-m88k.c (m88k_do_align): Correct check for whether fill
+ pattern is zero. From Manfred Hollstein.
+
+Thu Nov 30 13:25:49 1995 Kim Knuttila <krk@cygnus.com>
+
+ * config/tc-ppc.c (ppc_pe_section): To get the alignment right for
+ the various idata sections, we check the name on the .section pseudo.
+
+Thu Nov 30 11:23:42 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
+
+ * config/obj-coff.c (fixup_segment): If TC_M88K is defined, do not
+ add section's paddr to add_number; compatibility to native as and
+ ld forbids.
+
+Wed Nov 29 23:14:27 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * configure.in: Treat m68k-sysv4 like m68k-elf, not m68k-sysv3.
+
+ * hash.c (struct hash_entry): Moved here...
+ * hash.h (struct hash_entry): ...from here.
+
+ * config/obj-elf.c (elf_frob_symbol): Don't free and clear sy_obj
+ if it's already known to be null.
+
+Wed Nov 29 13:00:20 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (md_apply_fix3): Don't adjust the value for 32
+ bit relocs converted to PC relative relocs. This turned out to
+ add the offset from the beginning of .text twice.
+
+Tue Nov 28 10:42:36 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * stabs.c (s_stab_generic): In 's' case, free string from
+ obstack.
+
+ * config/obj-elf.h (ELF_TARGET_SYMBOL_FIELDS): Remove unused field
+ sy_name_offset.
+ * config/obj-multi.h (ELF_TARGET_SYMBOL_FIELDS) [OBJ_MAYBE_ELF]:
+ Ditto.
+
+ * subsegs.h (segment_info_type): Make bitfields unsigned.
+
+ * expr.h (struct expressionS): Make X_op and X_unsigned bitfields,
+ and move them together. On most systems this will reduce the
+ structure size by one word.
+ (operatorT): Define O_max.
+ * expr.c (expr_begin): Verify that X_op is wide enough to hold
+ O_max.
+
+ * read.c (pop_insert): Print error returned by hash table
+ insertion code.
+
+ * as.c (dump_statistics): Split out from main; dump some hash
+ table stats and target-specific stats.
+ (start_time): No longer automatic to main.
+ (main): Set file-level start_time and call dump_statistics at
+ exit. Exit by calling xexit.
+ (show_usage): Make --statistics description less specific.
+ * subsegs.c (subsegs_print_statistics): New function.
+ * write.c (write_print_statistics): New function.
+ (n_fixups): New static variable.
+ (fix_new_internal): Increment it.
+ * read.c (read_print_statistics): New function.
+ * read.h (read_print_statistics): Declare.
+ * symbols.c (symbol_print_statistics): New function.
+ * symbols.h (symbol_print_statistics): Declare.
+ * hash.c (hash_print_statistics): New function.
+ * hash.h (hash_print_statistics): Declare.
+ * config/tc-i386.c (i386_print_statistics): New function.
+ * config/tc-i386.h (i386_print_statistics): Declare.
+ (tc_print_statistics): New macro.
+ * messages.c (as_fatal, as_assert, as_abort): Use xexit, not
+ exit.
+
+ * hash.c (DELETED): Rewrite to use a valid but unique address.
+ (START_POWER): Reduce to 10.
+ (enum stat_enum): New enumerator, replacing STAT_* index macros.
+ Add new values for counting strcmp calls.
+ (GROW_FACTOR): New macro.
+ (hash_grow): Use GROW_FACTOR. Rewrite for quick returns instead
+ of nesting blocks.
+ (FULL_VALUE): New macro. Use 1/4 of table size instead of 1/2.
+ (hash_new): Use FULL_VALUE.
+ (struct hash_control): Definition moved here.
+ (hash_code): Don't mask to low bits.
+ (hash_ask): Mask returned hash code here. Check hash value before
+ calling strcmp; count strcmp calls.
+ * hash.h (struct hash_control): Declare, don't define, here.
+ (HASH_STATLENGTH): Deleted.
+ (struct hash_entry): Add field for hash code.
+ (hash_say, hash_apply): Don't declare.
+
+ * hash.c (destroy): Return void.
+ (applicatee): Ditto.
+ (main): Fix declarations.
+ (hash_apply): Return void. Argument `function' returns void. Put
+ inside "#ifdef TEST".
+ (hash_say): Define only if TEST is defined.
+ * hash.h (hash_apply, hash_say): Declarations deleted.
+
+Mon Nov 27 13:18:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild with autoconf 2.7.
+
+Tue Nov 21 18:39:01 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4 (AC_PROG_CC): Remove local definition.
+ * configure: Rebuild with autoconf 2.6.
+
+Mon Nov 20 17:26:00 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_debug_name_section_size): Remove.
+ (ppc_stabx): Don't increment ppc_debug_name_section_size.
+ (ppc_bc): Likewise.
+ (ppc_frob_file): Remove.
+ * config/tc-ppc.h (tc_frob_file): Don't define.
+ (ppc_frob_file): Don't declare.
+
+Mon Nov 20 13:37:05 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * Makefile.in (TARG_CPU_DEP_alpha): Mention alpha-opcode.h.
+ * config/alpha-opcode.h: Include one-operand variants of jmp and
+ jsr.
+
+ * config/te-delt88.h: Renamed from te-delta88.h, to avoid conflict
+ with te-delta.h in 8.3 file systems.
+ * configure.in: Adjusted.
+
+Thu Nov 16 12:49:38 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (s_err): Remove; just use the one in read.c.
+
+ * config/m68k-parse.y (yylex): In MRI mode, '@' can start an octal
+ number.
+ * expr.c (operand): Handle MRI suffixes after unadorned 0.
+
+Thu Nov 16 00:21:44 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Version 2.6 released.
+ * Makefile.in (VERSION): Updated to 2.6.
+
+ * config/obj-coff.c (write_object_file): Change use of md_do_align
+ to pass a pointer rather than a fill value, to match other uses.
+
+Wed Nov 15 03:52:00 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/tc-ns32k.h (TC_FIX_TYPE): Add missing semicolon.
+
+ * as.c (main): Move md_end call to just after call to
+ perform_an_assembly_pass. Delete cpu-specific code here.
+ * config/tc-i960.h (md_end): New macro, calls brtab_emit.
+ * config/tc-arm.c (md_end): Unused function deleted.
+ * config/tc-ns32k.c (md_end): Ditto.
+
+ * config/tc-i386.c (i386_align_code): New function, moved here
+ from HANDLE_ALIGN macro.
+ * config/tc-i386.h (HANDLE_ALIGN): Call it.
+
+ Mon Jul 31 14:53:19 1995 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.h (md_do_align): cast fill and 0x90 to char
+ before comparing
+
+ Mon May 1 10:91:49 1995 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.h (md_do_align): Make ".align n,0x90" generate
+ multi-byte nops to avoid changing gcc. The necessary gcc change
+ might break old assemblers.
+
+ Sat Apr 22 20:53:05 1995 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.h (md_do_align, HANDLE_ALIGN): Add macros to
+ generate optimal multi-byte nop instructions for ".align n"
+ ".align n,0x90", and aligns requiring more than 15 bytes of
+ padding still generate multiple 0x90's as before.
+
+Mon Nov 13 17:40:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (s_mri_until): Call pop_mri_control.
+
+Mon Nov 13 20:39:06 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.in (ppc-*-macos*, ppc-*-mpw*): New configurations.
+ * configure: Update.
+ * mpw-make.sed: Reorder commands to make sed happier.
+ * config/te-macos.h: New file.
+ * config/tc-ppc.h (TARGET_FORMAT): Set correctly for PowerMac.
+
+Sun Nov 12 21:14:56 1995 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_ip): Fix off-by-2 bug in length check for
+ conditional branches.
+ (md_apply_fix): Likewise.
+
+Thu Nov 9 16:14:01 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-a29k.c (md_apply_fix): Warn if an attempt is made to
+ generate a reloc which the linker will not handle correctly. Fix
+ overflow checking--R_IREL is 18 bits, not 17.
+
+Wed Nov 8 19:59:36 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): Don't subtract md_pcrel_from
+ from a PC relative reloc if TC_A29K.
+
+ * config/tc-a29k.c (line_separator_chars): Restore '@'. Existing
+ code depends upon it.
+
+ * config/tc-a29k.c (md_operand): Handle $float, $double, and
+ $extend. Based on code from Eric Freudenthal
+ <freudenthal@nyu.edu>.
+ * config/tc-a29k.h (LEX_DOLLAR): Define.
+ * read.c (LEX_DOLLAR): Define if not defined.
+ (lex_type): Use LEX_DOLLAR.
+
+Wed Nov 8 16:38:14 1995 Eric Freudenthal <freudenthal@nyu.edu>
+
+ * configure.in (a29k-nyu-sym1): New target, just like other a29k
+ targets.
+
+Wed Nov 8 11:38:48 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (c_dot_file_symbol): Cast xmalloc return.
+
+Tue Nov 7 09:14:35 1995 Kim Knuttila <krk@cygnus.com>
+
+ * config/tc-ppc.c (md_apply_fix3): Added BFD_RELOC_RVA. Currently
+ used only by "dlltool.c".
+
+Mon Nov 6 18:51:26 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-alpha.c: Undefine inline if not __GNUC__.
+ (md_pseudo_table): Don't define "extern".
+
+Sat Nov 4 00:51:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_biei): Force symbol into text_section.
+
+ * config/tc-ppc.c (md_show_usage): Put backslash at end of line.
+
+Fri Nov 3 13:02:59 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * macro.c (macro_expand_body): Don't warn about == with a
+ nonexistent parameter, in case it is in a comment field.
+
+ * as.c (main): On TC_A29K, call macro_init with macro_alternate
+ set to 1.
+ * macro.c (get_any_string): Don't keep quotes if macro_strip_at is
+ set, even if macro_alternate is set.
+ (get_apost_token): If macro_strip_at, only skip kind if it is '@'.
+ (sub_actual): If macro_strip_at, and kind is '@', don't look up
+ the token unless it ended in '@'.
+ * config/tc-a29k.c (line_separator_chars): Remove '@'.
+ * doc/c-a29k.texi: Document macro usage on A29K.
+
+Thu Nov 2 23:07:57 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Handle new 'W' place, meaning a
+ signed word.
+ (install_operand): Likewise.
+
+ * config/obj-elf.c (ecoff_debug_pseudo_table): Add "extern".
+
+Wed Nov 1 15:17:02 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
+
+ * configure.in (m88k-motorola-sysv*): New target.
+ * configure: Rebuild.
+ * config/te-delta88.h: New file.
+ * config/obj-coff.c (write_object_file): Use md_do_align if it is
+ defined.
+ * config/tc-m88k.h (SUB_SEGMENT_ALIGN): Define.
+ (md_do_align): Define.
+ * config/tc-m88k.c: Include "subsegs.h".
+ (m88k_do_align): New function.
+
+ * config/te-delta.h (STRIP_UNDERSCORE): Don't define.
+ (COFF_NOLOAD_PROBLEM): Define.
+ (LOCAL_LABELS_DOLLAR, LOCAL_LABELS_FB): Define.
+
+Wed Nov 1 16:07:43 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/tc-i386.c (md_assemble): For a jump instruction with
+ non-constant target, require 7 available bytes in the current
+ frag, not 6.
+
+Tue Oct 31 15:37:16 1995 Fred Fish <fnf@rtl.cygnus.com>
+
+ * config/obj-elf.h: Include bfd/elf-bfd.h rather than
+ bfd/libelf.h.
+
+Tue Oct 31 16:34:28 1995 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * configure.in (alpha-*-linux*): Use ecoff.
+ * configure: Rebuild.
+ * ecoff.c (ecoff_directive_extern): New function.
+ (ecoff_directive_weakext): New function.
+ (ecoff_build_symbols): Handle weak symbols.
+ (ecoff_setup_ext): Likewise.
+ (ecoff_frob_symbol): Warn about weak common symbols.
+ * ecoff.h (ecoff_directive_extern): Declare.
+ (ecoff_directive_weakext): Declare.
+ * symbols.c (S_IS_WEAK): New function.
+ * symbols.h (S_IS_WEAK): Declare.
+ * config/obj-ecoff.c (obj_pseudo_table): Add "extern" and
+ "weakext".
+ * config/tc-mips.c (mips_pseudo_table): Remove "extern".
+ (s_extern): Remove.
+
+Tue Oct 31 13:29:08 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_lglobl): Do the right thing.
+
+ * config/tc-ppc.c (ppc_bb): Call SF_SET_PROCESS.
+ (ppc_eb): Likewise. Set the storage class to C_BLOCK, not C_FCN.
+ (ppc_frob_symbol): Don't change C_BLOCK symbols to C_HIDEXT.
+ * config/obj-coff.c (coff_frob_symbol): Don't call
+ SA_SET_SYM_ENDNDX with the current symbol; call it with the next
+ one. If OBJ_XCOFF, try to figure out whether the symbol is going
+ to be dropped.
+
+ * config/tc-ppc.c (md_pseudo_table): Add "bc" and "ec".
+ (ppc_stab_symbol): New static variable.
+ (ppc_change_csect): Check that ppc_toc_csect is not NULL.
+ (ppc_stabx): Set ppc_stab_symbol around call to symbol_make. Set
+ sy_tc.real_name to the stab string.
+ (ppc_bc, ppc_ec): New static functions.
+ (ppc_canonicalize_symbol_name): If ppc_stab_symbol is set, don't
+ do anything.
+ (ppc_symbol_new_hook): If ppc_stab_symbol is set, don't look for a
+ suffix.
+ (ppc_frob_symbol): Set BSF_NOT_AT_END for symbols with csect aux
+ entries.
+
+ * input-scrub.c (input_scrub_push): Reset sb_index.
+
+Mon Oct 30 17:52:46 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * listing.c (listing_newline): Don't create a frag in the absolute
+ section.
+
+Sat Oct 28 01:02:05 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (md_pseudo_table): Add "data" and "text".
+ (ppc_csect): Move most of the code to ppc_change_csect, and call
+ it.
+ (ppc_change_csect): New static function, taken from ppc_csect.
+ (ppc_section): New static function.
+ (ppc_saw_abs): New static varable.
+ (ppc_frob_symbol): Create aux entry for absolute symbols. Warn if
+ a symbol has no csect.
+ (ppc_adjust_symtab): New function.
+ * config/tc-ppc.h (tc_adjust_symtab): Define if OBJ_XCOFF.
+ (ppc_adjust_symtab): Declare if OBJ_XCOFF.
+
+ * write.c (write_object_file): If tc_adjust_symtab is defined,
+ call it just before the call to obj_adjust_symtab.
+
+ * symbols.c (symbol_find_or_make): Change name to be const.
+ * symbols.h (symbol_find_or_make): Update declaration.
+
+Thu Oct 26 19:18:27 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * doc/as.texinfo (Align): Mention SH.
+ * doc/c-m68k.texi (M68K-Directives, .even): Describe behavior, not
+ .align value.
+ * doc/c-z8k.texi (Z8000 Directives, global): Fix minor typo.
+ (Z8000 Directives, even): Don't give numeric align value, instead
+ explain behavior.
+
+Thu Oct 26 11:45:03 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * config/tc-arm.c (do_ldst): Assemble ldr/str r0, [r1] as a
+ pre-increment instruction.
+
+Wed Oct 25 11:59:24 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in (diststuff): Also make info.
+ (maintainer-clean realclean): Also make clean-info.
+
+Tue Oct 24 15:21:33 1995 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (md_pseudo_table): Add new ".nsubspa" opcode.
+ (pa_subspace): For ".nsubspa", always create a new subspace
+ with the given attributes, even if one already exists with the
+ same name.
+
+Tue Oct 24 14:50:38 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.h (TC_FORCE_RELOCATION_SECTION): Rename from
+ TC_FORCE_RELOCATION, taking an additional section argument. If
+ the section of the target symbol is not the same as the current
+ section, always force the relocation to be used.
+ (MD_PCREL_FROM_SECTION): New macro to call md_pcrel_from_section.
+
+ * config/tc-ppc.c (md_pcrel_from_section): Rename from the
+ md_pcrel_from function, taking an additional section argument.
+ Invoke TC_FORCE_RELOCATION_SECTION instead of TC_FORCE_RELOCATION.
+
+ * write.c (TC_FORCE_RELOCATION_SECTION): Define in terms of the
+ older TC_FORCE_RELOCATION if not defined.
+ (MD_PCREL_FROM_SECTION): If not defined, invoke md_pcrel_from.
+ (fixup_segment): Use MD_PCREL_FROM_SECTION instead of
+ md_pcrel_from, and TC_FORCE_RELOCATION_SECTION instead of
+ TC_FORCE_RELOCATION.
+
+Mon Oct 23 16:20:04 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * input-scrub.c (as_where): Set name to null pointer if we don't
+ have a file name.
+ * messages.c (identify): Only print filename if non-null.
+ (as_show_where): Ditto, for line number too.
+ (as_warn_internal, as_bad_internal): Ditto.
+
+ * input-file.c (input_file_open): If the input file can't be
+ opened, consider it an error.
+
+Mon Oct 23 11:15:44 1995 James G. Smith <jsmith@pasanda.cygnus.co.uk>
+
+ * config/tc-mips.c: Added mips_4100 control, and support for
+ accepting the 4100 as a MIPS architecture variant (md_begin,
+ macro_build, mips_ip, md_parse_option). Adding suitable
+ command-line OPTIONs, and updating the help text (md_show_usage).
+
+Wed Oct 18 13:20:32 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * subsegs.c (subseg_begin): Only set absolute_frchain.fix_* when
+ BFD_ASSEMBLER is defined.
+
+ * Use one active frag and one obstack per frag chain:
+ * frags.c (frags): Variable deleted.
+ (frag_alloc): New function.
+ (frag_grow, frag_more, frag_variant, frag_now_fix,
+ frag_append_1_char): Refer to frchain_now->frch_obstack instead of
+ frags variable.
+ (frag_new): Ditto. Verify that frch_last and frag_now match on
+ entry and exit, and that old frag_now has non-zero type. Replace
+ "know" uses with "assert". Use frag_alloc instead of mucking with
+ obstack alignment.
+ * frags.h (frags): Declaration deleted.
+ * subsegs.h (struct frchain): Add new field frch_frag_now.
+ * subsegs.c (frchains, dummy_frag, absolute_frchain): New static
+ variables.
+ (subsegs_begin): Initialize frchains obstack. Under gcc, don't
+ give it any stricter alignment than frchainS structures need. Do
+ not initialize frags obstack. Set frag_now to point to
+ dummy_obstack. Initialize absolute_frchain.
+ (subseg_set_rest): Save and restore frag_now in frch_frag_now
+ field of frchainS. Don't create new frags on section switch, and
+ use frag_alloc when creating a new frag chain. For absolute
+ section, set frchain_now to absolute_frchain. Verify that
+ frch_last and frag_now match on entry and exit. Initialize
+ per-chain obstack, and under gcc, set required alignment to that
+ needed by fragS structure.
+
+ * write.c (chain_frchains_together_1): Verify fr_type is nonzero.
+
+ * stabs.c (get_stab_string_offset): Only copy input string if a
+ fresh copy is needed, not if the section already exists.
+ (s_stab_generic): Cache stab section name to bypass lookups, since
+ usually it will match. Could be made faster still by changing the
+ memory allocation rules.
+ (s_xstab): Cache section name to bypass repeated string
+ allocation.
+
+ * frags.c (frag_new): Deleted register declarations.
+
+ * listing.c (frag_now): Don't declare.
+
+ * as.c (chunksize): New variable.
+ (debug_memory): New variable.
+ (main): If debug_memory is set, reduce chunksize and
+ _bfd_chunksize.
+ * as.h (chunksize): Declare it.
+ * read.c (read_begin): Use it.
+
+ * config/tc-alpha.c (md_shortopts): Include 'g'.
+ (md_parse_option): Ignore it.
+
+ * Makefile.in (distclean): Remove Makefile and config.status from
+ testsuite directory.
+ (clean-here): Don't delete testsuite. Instead, delete only the
+ files within it that would be generated by running tests.
+
+ * config/tc-hppa.c (hppa_elf_mark_end_of_function): Call
+ frag_now_fix instead of accessing obstack info directly.
+ * config/tc-arm.c (s_ltorg): Ditto.
+ (md_assemble): Ditto.
+
+ * config/tc-i386.c (md_assemble): Call frag_grow instead of
+ obstack_room.
+
+Wed Oct 18 12:22:59 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * stabs.c (aout_process_stab): Insert debug symbol into symbol
+ chain after parsing value expression, if any, to avoid separating
+ continued .stabs lines.
+
+Mon Oct 16 10:56:41 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_elf_pseudo_table): Remove.
+ (mips_pop_insert): Don't call pop_insert on mips_elf_pseudo_table.
+
+Mon Oct 16 07:07:37 1995 Michael Meissner <meissner@wogglebug.tiac.net>
+
+ * config/tc-ppc.c (md_begin): Use new flags PPC_OPCODE_COMMON for
+ -mcom support and PPC_OPCODE_ANY for -many.
+ (md_parse_option): Ditto.
+ (ppc_arch): Ditto.
+ (md_begin): For duplicate instructions, print all duplicates
+ before aborting.
+
+Sun Oct 15 22:06:14 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.c (md_parse_option): Support for -mcom to turn on
+ common mode operation.
+ (md_show_usage): Add -mcom to usage message.
+
+Fri Oct 13 13:32:45 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * expr.c (op_rank): Add O_symbol_rva.
+ * expr.h (operatorT): Add O_symbol_rva.
+ * read.c (cons_worker): Set O_symbol_rva when necessary.
+ * write.c (fix_new_exp): Understand O_symbol_rva.
+
+Tue Oct 10 11:34:14 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c: Correct s_cons arguments. From Michael
+ Joosten <joost@ori.cadlab.de>.
+
+Mon Oct 9 19:59:53 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_macro): Make count unsigned.
+ (ppc_biei): Set segment to now_seg and value to coff_n_line_nos.
+ (ppc_frob_symbol): Handle C_BINCL and C_EINCL symbols by setting
+ the fix_line field.
+ * config/obj-coff.c (coff_n_line_nos): Rename from n_line_nos, and
+ make non-static. Change all users.
+ * config/obj-coff.h (coff_n_line_nos): Declare.
+
+Fri Oct 6 16:24:27 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Mon Sep 25 22:49:32 1995 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * configure.in (AC_ARG_WITH(bfd-assembler)): Fix help message.
+
+ * config/obj-elf.c (obj_elf_common): Convert specified byte
+ alignment to power of two. Set size of local bss symbol.
+
+ * config/tc-m68k.c (tc_gen_reloc): Fix typo in variable name.
+
+Fri Oct 6 15:22:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * sb.c, macro.c: Decide whether to include <string.h> or
+ <strings.h> just as as.h does.
+
+Fri Oct 6 09:55:33 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (site.exp): Fix setting of $srcdir.
+
+ * config/tc-arm.c (md_atof): Fix little-endian output.
+ * config/tc-arm.h (ARM_BI_ENDIAN): Move definition so defined for
+ all coff targets.
+
+Thu Oct 5 20:17:30 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * doc/as.texinfo: Split out the NS32k family documentation,
+ despite its being commented out for now.
+ * doc/c-ns32k.texi: New file.
+
+ * sb.c, macro.c: Include string.h.
+
+ * Makefile.in (comparison): Only check *.o; we don't care if
+ timestamps inserted by the native linker differ.
+
+ * config/tc-alpha.c (alpha_align): Only fill with a no-op pattern
+ if alignment stricter than 4 bytes is requested; in that case,
+ align to a 4-byte boundary first.
+
+ Thu Sep 28 19:35:27 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.c (VMS_RSYM_Parse): eliminate "might be used
+ uninitialized" warning for `Max_Source_Offset'.
+
+Wed Oct 4 16:17:02 1995 Kim Knuttila <krk@cygnus.com>
+
+ * config/tc-ppc.c (parse_toc_entry): New function to parse [toc]
+ qualifiers and detect errors if present.
+ (md_assemble): Add call to parse_toc_entry. Also added some support
+ for the [tocv] qualifier.
+ (ppc_pe_tocd): New function to support data in the toc section.
+
+Wed Oct 4 14:03:39 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_frob_symbol): Don't create an aux entry for
+ an absolute symbol.
+
+Tue Oct 3 12:18:19 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (isword): Accept all values from -65536 to
+ +65535, so ~VAL will not be rejected.
+
+ * cond.c (s_endif): Call demand_empty_rest_of_line. In MRI mode,
+ skip characters after the pseudo-op.
+ (s_else): Likewise.
+ * read.c (get_line_sb): Don't look past buffer_limit.
+ (s_include): In MRI mode, skip characters after the file name.
+
+Mon Oct 2 16:15:27 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/m68k-parse.y (m68k_reg_parse): In MRI mode, permit
+ periods in register names.
+
+Sat Sep 30 23:03:31 1995 Jeff Law (law@hurl.cygnus.com)
+
+ * config/tc-hppa.c (hppa_fix_adjustable): DP relative relocs
+ are not adjustable in SOM to avoid confusing the optimizing
+ linker.
+
+Fri Sep 29 15:18:08 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ Add some support for i960 MRI compatibility mode.
+ * config/tc-i960.c (md_pseudo_table): Add endian.
+ (get_args): Don't discard a space between alphanumeric characters.
+ (get_cdisp): Change text_section to now_seg.
+ (s_endian): New static function.
+ * config/tc-i960.h (MRI_MODE_NEEDS_PSEUDO_DOT): Define.
+ * expr.h (operatorT): Add O_logical_not, O_logical_and, and
+ O_logical_or.
+ * expr.c (operand): Treat '!' as logical not operator. If
+ TC_I960, in MRI mode permit `sizeof secname' and `startof
+ secname'.
+ (op_rank): Bump values by 2 to make room for && and ||. Add
+ entries for !, &&, and ||.
+ (expr_begin): Only do MRI changes if TC_M68K.
+ (operator): Recognize || and &&.
+ (expr): Handle new operatorT values.
+ * symbols.c (resolve_symbol_value): Handle new operatorT values.
+ (print_expr_1): Likewise.
+ * read.c (potable): Add debug, err, irep, irepc, print, purgem,
+ and rep.
+ (read_a_source_file): Handle MRI_MODE_NEEDS_PSEUDO_DOT.
+ (mri_comment_field): Only handle weird comments if TC_M68K.
+ (s_err): New function.
+ (s_org): Only punt in MRI mode if TC_M68K.
+ (s_mri_sect): Write TC_I960 version.
+ (s_print, s_purgem): New functions.
+ * read.h (s_err, s_print, s_purgem): Declare.
+ * cond.c (s_ifeqs): Implement.
+ (ignore_input): Handle MRI_MODE_NEEDS_PSEUDO_DOT.
+ * macro.c (macro_strip_at): New static variable.
+ (macro_init): Add strip_at parameter.
+ (do_formals): If macro_strip_at, change NARG to $NARG.
+ (define_macro): Skip a comma after the macro name.
+ (get_apost_token): Skip character if macro_strip_at, even if
+ macro_mri.
+ (macro_expand_body): If macro_strip_at, don't recognize parameters
+ in strings unless they are preceded by an '@'. If macro_strip_at,
+ pass '@' as strip character to sub_actual. If macro_strip_at,
+ strip '@' characters.
+ (macro_expand): If macro_strip_at, change NARG to $NARG.
+ (delete_macro): New function.
+ (expand_irp): Skip leading and trailing '"' characters if irpc.
+ * macro.h (macro_init): Mention new strip_at parameter.
+ (delete_macro): Declare.
+ * as.c (main): If TC_I960, pass flag_mri to macro_init as
+ strip_at; otherwise, pass 0.
+ * gasp.c (process_pseudo_op): Pass 0 to macro_init as strip_at.
+ (main): Likewise.
+ * doc/as.texinfo: Document i960 MRI mode.
+
+ * as.c (show_usage): Mention --defsym.
+
+Thu Sep 28 19:25:04 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Translate "powerpc" into "ppc", remove gen of
+ VERSION, move gen of "conf" here from makefile.
+ * mpw-make.sed: New file, sed commands to translate Unix makefile
+ into MPW syntax.
+ * mpw-make.in: Remove.
+ * mac-as.r: New file, Mac resource file.
+ * as.h (inline): Don't decide about defining if __MWERKS__,
+ remove redundant conditional and definition.
+
+ * stabs.c (s_stab_generic): Fix syntax for OBJ_PROCESS_STAB.
+
+Thu Sep 28 15:43:15 1995 Kim Knuttila <krk@nellie>
+
+ * config/tc-ppc.c (md_apply_fix3): Removed some TE_PE specific
+ manipulations, since I can't prove they're needed.
+ (md_begin): Removed init_regtable, insert_reg, and the call points.
+ (register_name): New function. Parses a register name, if appropriate.
+ (md_assemble): Added call to register_name to handle symbolic names.
+ (ppc_pe_section): Removed all duplicate IMAGE defines, and include
+ coff/pe.h instead.
+
+Thu Sep 28 12:09:19 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.h (tc_fix_adjustable): Define.
+ (ppc_pe_fix_adjustable): Declare.
+ * config/tc-ppc.c (ppc_pe_fix_adjustable): New function.
+
+Thu Sep 28 01:11:58 1995 Doug Evans <dje@deneb.cygnus.com>
+
+ * config/tc-arm.h (TARGET_FORMAT): Define for arm-coff.
+
+Wed Sep 27 12:53:58 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (S_IS_LOCAL): All symbols in reg_section are local.
+
+ * config/tc-ppc.h (OBJ_XCOFF): Define if OBJ_COFF and not TE_PE.
+ Change OBJ_COFF checks to check OBJ_XCOFF instead.
+ (TARGET_FORMAT): Fully parenthesize.
+ (LEX_QM): Define if TE_PE.
+ * config/tc-ppc.c: Replace OBJ_COFF by OBJ_XCOFF throughout.
+ Remove checks of TE_PE within #ifdef OBJ_XCOFF sections.
+ (init_regtable): Make i unsigned.
+ (ppc_set_current_section): Rename from setCurrentSection. Change
+ all callers.
+ (ppc_arch): Return after as_fatal to avoid gcc warning.
+ (md_assemble): Only declare reloc if OBJ_ELF. Add default to
+ switch on fixups[i].reloc to avoid gcc warning.
+ (IMAGE_SGN_LNK_OTHER): Fix nested comment.
+ (ppc_pe_function): Don't call ppc_canonicalize_symbol_name.
+ (ppc_frob_symbol): Remove TE_PE section checks.
+ (md_estimate_size_before_relax): Return after abort to avoid gcc
+ warning.
+ (md_apply_fix3): Add BFD_RELOC_16_GOT_PCREL to switch.
+ * read.c (LEX_QM): Define as 0 if not defined.
+ (lex_type): Use LEX_QM for '?'.
+
+ * configure.in: No need to check whether ${cpu_type} is powerpc;
+ it never will be.
+ * configure: Rebuild.
+
+Wed Sep 27 11:33:38 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (md_apply_fix3): Remove Sep 26 changes to this
+ function, keeping other Sep. 26 changes.
+
+Wed Sep 27 10:29:13 1995 Kim Knuttila <krk@nellie>
+
+ * configure (emulations): Added support for ppcle-*-[pe|winnt]
+ (target_frag): Removed an extraneous PPC definition.
+ * configure.in (emulations): Same
+ * config/tc-ppc.h:
+ * config/tc-ppc.c (md_pseudo_table): Base support for new or altered
+ pseudo ops - <previous, pdata, ydata, reldata, rdata, ualong, znop,
+ section, comm, function> There will be more.
+ (pre_defined_registers): Predefined reg table to name registers, etc
+ (md_begin): Setup reg table initialization
+ (md_assemble): Initial [toc]x(rtoc) support
+ (ppc_frob_label): Removed some xcoff specific processing from TE_PE
+ (ppc_frob_symbol): Removed some xcoff specific processing from TE_PE
+ Added support for more predefined sections
+ (ppc_frob_section): Removed some xcoff specific processing from TE_PE
+ (ppc_fix_adjustable): Removed from TE_PE mainline
+ (md_apply_fix3): For TE_PE toc entries, we don't need to mess
+ with fx_addnumber. Removed for the time being.
+ (lots): Put back missing assignments to ppc_current_csect.
+
+Tue Sep 26 14:57:59 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Support all of the V.4
+ relocations.
+ (ppc_elf_cons): Remove restriction that @ suffixes must be done
+ with .long. Add error if relocation does not fit in the number of
+ bytes provided.
+ (md_assemble): For absolute branches, map PC relative relocations
+ back into an equivalent absolute relocation.
+ (md_pcrel_from): If TC_FORCE_RELOCATION is true, relocation offset
+ is 0, not segment start.
+ (md_apply_fix3): Don't bother writing addend into the instruction,
+ since it is ignored, given that we use RELA relocations for ELF.
+
+ * config/tc-ppc.h (TC_FORCE_RELOCATION): Define to force all
+ branch prediction relocations to always be emitted.
+
+Mon Sep 25 16:08:43 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Lower case reloc before
+ testing.
+ (md_assemble): Be more robust in terms of relocations.
+ (md_apply_fix3): Allow 14 bit relocs to be emitted for external
+ symbols in addition to 26 bit relocs. Properly insert 26/14 bit
+ reloc value fields into the instruction stream.
+
+Mon Sep 25 00:23:16 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-arm.c (md_atof): Output little endian constants in
+ little endian mode.
+
+ * config/obj-coff.c (obj_coff_section): Pass &type, not type,
+ s_mri_sect.
+
+ * configure.in: Fix typo: fmt-elf to fmt=elf.
+
+Fri Sep 22 16:34:46 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Rewrite to use a table of
+ strings and relocations they represent. Add @br{,n}taken for
+ branch taken/not taken support.
+ (md_apply_fix3): Add BFD_RELOC_PPC_B16_BR{,N}TAKEN support.
+
+Thu Sep 21 21:10:17 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.c (md_parse_option): -mrelocatable-lib now only
+ sets EF_PPC_RELOCATABLE_LIB and not also EF_PPC_RELOCATABLE.
+
+Thu Sep 21 16:30:56 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * subsegs.c (subseg_set): Permit SEG_ABSOLUTE in know expression.
+ * expr.c (expr): Account for new operatorT values in know
+ expression.
+
+ * write.c (fixup_segment): Clear fixp->fx_subsy if the relocation
+ is fully resolved.
+
+Thu Sep 21 14:11:49 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.c (ppc_flags): New variable to hold the flag bits
+ to set in the ELF header.
+ (md_parse_option): Add support for -mrelocatable-lib. Make both
+ -mrelocatable and -mrelocatable-lib set ppc_flags.
+ (md_begin): Set ELF flags with ppc_flags.
+
+Wed Sep 20 13:01:52 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (maintainer-clean): New target, synonym for
+ realclean. Add GNU standard maintainer-clean echos.
+ * doc/Makefile.in (maintainer-clean): New target, synonym for
+ realclean.
+
+Tue Sep 19 11:31:31 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Reject immediate operands for '%'.
+
+ * config/tc-m68k.c (m68k_ip): Reject immediate operands for '|'.
+ Replace 'P' with '0', '1', and '2'.
+
+ * config/tc-m68k.c (parse_mri_control_operand): Change leftstop
+ and rightstop to not be const.
+ (parse_mri_control_expression): Likewise.
+ (build_mri_control_operand): Likewise. Use m68k_ip_op to examine
+ the operand, not m68k_reg_parse.
+ (s_mri_if): In MRI mode, stop at the first '*'.
+ (s_mri_while): Likewise.
+ (s_mri_else): In MRI mode, ignore trailing characters.
+ (s_mri_endi, s_mri_break, s_mri_next, s_mri_for): Likewise.
+ (s_mri_endf, s_mri_repeat, s_mri_until, s_mri_endw): Likewise.
+ * config/m68k-parse.y: Revert yesterday's change.
+ * config/m68k-parse.h: Revert yesterday's change.
+
+Mon Sep 18 15:22:28 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (parse_mri_control_operand): Change leftstart
+ and rightstart to not be const.
+ (parse_mri_control_expression): Likewise.
+ (build_mri_control_operand): Likewise. If the left side of the
+ comparison is a register, and the right side is not, swap the two
+ sides.
+ * config/m68k-parse.y (m68k_reg_parse): Make globally visible.
+ * config/m68k-parse.h (m68k_reg_parse): Declare.
+
+ * read.c (mri_comment_field): New function.
+ (mri_comment_end): New function.
+ (s_align_bytes): Use mri_comment_field.
+ (s_align_ptwo, s_comm, s_mri_common, s_fail, s_globl): Likewise.
+ (s_float_space, s_struct): Likewise.
+ (s_space): Use mri_comment_field rather than doing it by hand.
+ (cons_worker, equals): Likewise.
+ (s_end): Ignore comments starting with '*' or '!'.
+ * read.h (mri_comment_field): Declare.
+ (mri_comment_end): Declare.
+ * cond.c (s_if): Use mri_comment_field.
+ * config/tc-m68k.c (s_chip, s_reg): Likewise.
+
+ * write.c (fixup_segment): Handle ABS-sym in -sym case rather than
+ sym-sym case.
+ * config/obj-coff.c (fixup_segment): Likewise. Permit negative
+ symbols if TC_M68K.
+ * config/tc-m68k.c (tc_coff_fix2rtype): If fx_tcbit is set, return
+ R_RELLONG_NEG.
+ (tc_gen_reloc): If fx_tcbit is set, abort.
+ (md_apply_fix_2): For a negative reloc, move fx_subsy to fx_addsy,
+ and set fx_tcbit.
+
+ * config/tc-m68k.c (s_reg): Ignore comment field in MRI mode.
+
+Mon Sep 18 14:44:04 1995 Arne H. Juul <arnej@pvv.unit.no>
+
+ * configure.in (mips-dec-netbsd*): New target.
+ * configure: Rebuild.
+
+Sun Sep 17 22:17:43 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set endian to little for mips-*-ultrix*.
+ * configure: Rebuild.
+
+Fri Sep 15 13:16:55 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * expr.c (current_location): New static function. Handle magic
+ symbol `.'; in absolute section, return a constant.
+ (operand): Call current_location for '.' and '$', instead of doing
+ it inline. In MRI mode, call current_location for '*'.
+
+Fri Sep 15 21:39:29 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-m68k.c: Change some "CONST" references to "const".
+
+Fri Sep 15 17:27:41 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Tue Sep 12 17:08:23 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.c (VMS_stab_parse): simplify first loop;
+ use S_GET_NAME/modify/S_SET_NAME sequence instead of abusing
+ S_GET_NAME when updating symbol name.
+ (local_symbols_DST): first prefix/postfix typo from July 21st.
+ [plus comment reformatting --kr]
+
+Wed Sep 13 12:33:03 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (EXPECT): New variable.
+ (CHECKFLAGS): Remove.
+ (site.exp): New target.
+ (check): Rewrite to invoke runtest directly, rather than recurring
+ down into testsuite.
+ (clean-here): Remove testsuite directory.
+ (clean, distclean): Don't recur into testsuite.
+ * configure.in: Don't call AC_CONFIG_SUBDIRS(testsuite).
+ * configure: Rebuild.
+
+ * write.c (relax_and_size_seg): Change to the segment we are
+ relaxing, in case md_convert_frag, called by cvt_frag_to_fill,
+ wants to call fix_new.
+ * config/tc-m68k.c (m68k_ip): Permit PC relative code if the
+ segment of the symbol is the current segment, not just in
+ text_section.
+ (md_convert_frag_1): Don't call subseg_change.
+ (md_estimate_size_before_relax): Likewise.
+
+Tue Sep 12 10:36:40 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-arm.c (md_atof): Fix debugging printf, and leave it
+ out by default.
+
+Mon Sep 11 11:39:11 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/configure.in: Remove unused file.
+
+ * app.c (do_scrub_chars): Grab all available spaces at start of
+ line before preserving a single space. Remove state == 0 test
+ which will never succeed.
+ * macro.c (macro_expand_body): Delete local variables from the
+ formal hash table.
+ (macro_expand): In MRI mode, stop when whitespace is seen in the
+ argument list.
+
+ * sb.c: Include "libiberty.h".
+ * macro.c: Likewise. Also include <stdlib.h> if it exists.
+
+Fri Sep 8 00:27:46 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * app.c (do_scrub_chars): In MRI mode, keep a space before a
+ possible comment character.
+ * config/tc-m68k.c (m68k_ip): In MRI mode, ignore anything after
+ an instruction which takes no operands.
+
+ * Makefile.in (install): Don't install gasp in $(tooldir).
+
+ * config/tc-mips.c (macro): Handle a non zero base register for
+ M_U{L,S}{D,W,H}_A.
+
+ * gasp.c (show_usage): Put program_name argument in first fprintf,
+ not second.
+
+Thu Sep 7 12:33:58 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * expr.c (operand): Handle 08 and 09 in MRI mode.
+ * macro.c (ISSEP): Remove duplicated `"' character.
+ (get_any_string): Copy some characters for which ISSEP is true:
+ ';', '>', '(', ')'. Otherwise we can get in an infinite loop.
+ * read.c (s_space): In MRI mode, the expressions stop at the first
+ unquoted space.
+ (cons_worker): In MRI mode, restore the terminating character at
+ the end of the function.
+
+ * read.c (cons_worker): Don't use #elif; old compilers don't
+ support it.
+
+Wed Sep 6 21:13:06 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * app.c (do_scrub_chars): In MRI mode, silently end quoted strings
+ at newline characters. In MRI mode, always keep spaces in the
+ operands field. In MRI mode, treat a line comment character as a
+ regular comment character following a space.
+ * cond.c (ignore_input): Use strncasecmp rather than strncmp when
+ looking for special pseudo-ops.
+ * read.c (cons_worker): In MRI mode, the expressions stop at the
+ first unquoted space.
+ (equals): Likewise.
+
+Wed Sep 6 15:03:53 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * config/tc-sh.c (get_operands): Read third arg if it exists.
+ Otherwise, clear it.
+ (get_specific, case F_FR0): Add.
+
+Wed Sep 6 15:03:53 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * config/tc-sh.c (get_specific): Delete arg_to_test.
+ (md_assemble): Increase operand array from 2 to 3.
+
+Tue Sep 5 16:47:36 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/tc-mips.c: Remove CYGNUS LOCAL comments.
+ (md_begin): Use 0/1 instead of TRUE/FALSE.
+ (md_show_usage): Break up long format string for the benefit
+ of lame compilers.
+ * config/tc-m68k.c (md_show_usage): Ditto.
+ * gasp.c (show_usage): Ditto.
+ * macro.c (check_macro): Cast result of hash_find.
+
+Tue Sep 5 14:46:38 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * configure.in: When testing for a free() declaration in system
+ header files, cast the address to a function pointer, not to an
+ integer.
+
+ * write.c (fix_new_internal): Call TC_INIT_FIX_DATA if TC_FIX_TYPE
+ is defined. Don't initialize fx_bsr. Verify that fx_size field
+ is wide enough to hold stored value.
+ * write.h (struct fix): Change tc_fix_data to type TC_FIX_TYPE if
+ that is defined, otherwise omit it. Delete fx_bsr. Change
+ fx_size to unsigned char.
+ * config/tc-i960.h (TC_FIX_TYPE, fx_bsr, TC_INIT_FIX_DATA): New
+ macros.
+ * config/tc-ns32k.h (TC_FIX_TYPE, fx_bsr, TC_INIT_FIX_DATA): New
+ macros.
+ * config/tc-hppa.h (TC_FIX_TYPE): Define as PTR.
+
+ * config/tc-i860.c (md_apply_fix): Delete code for checking
+ fx_im_disp, and for handling non-zero values, since it never gets
+ set after being initialized to zero.
+
+ * write.h (struct fix): Make fx_im_disp always 2 bits, since the
+ only tc-* files actually using it need that much.
+
+ NS32K changes from Ian Dall:
+ * configure.in: Treat ns32k-pc532-ux* like ns32k-pc532-mach*, and
+ ns32k-pc532-lites* like ns32k-pc532-netbsd*.
+ * config/tc-ns32k.h (LOCAL_LABELS_FB): Define to 1.
+
+Fri Sep 1 17:02:15 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * write.c (fixup_segment): Get TC_FORCE_RELOCATION up the
+ right way!
+
+Fri Sep 1 08:20:19 1995 James G. Smith <jsmith@beauty.cygnus.com>
+
+ * config/tc-mips.c (md_parse_option, md_begin, md_show_usage):
+ Add support for "-mcpu=vr4300" as processor identifier.
+
+Thu Aug 31 16:41:06 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * write.c (fixup_segment): Remove change of 29th.
+ * config/tc-{i386,arm}.h (TC_FORCE_RELOCATION): Keep RVA relocs.
+
+Tue Aug 29 19:42:58 1995 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (m68k_ip) [case POST/PRE/BASE]: Fix typo when
+ looking at outer displacement. Don't set the postindex bit if the
+ index suppress bit is set (for memory indirect addressing mode).
+
+Thu Aug 31 06:49:37 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-arm.c (tc_gen_reloc): Delete duplicated code.
+
+Wed Aug 30 23:51:57 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * app.c (do_scrub_chars): Free saved_input when the from buffer
+ exactly fills the to buffer.
+
+Wed Aug 30 13:46:39 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-sparc.c (parse_keyword_arg, parse_const_expr_arg): New fns.
+ (sparc_ip): Call them for asi, membar, and prefetch parsing.
+
+Tue Aug 29 15:45:37 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-sparc.c (membar_masks): Deleted.
+ (sparc_ip): Clean up ASI and membar support.
+
+Tue Aug 29 13:20:27 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * read.c (potable): Rva is new entry.
+ (cons_worker): New, split from cons. Handles rva.
+ (cons, s_rva): Call cons_worker.
+ * read.h (s_rva): New declaration.
+ * write.c (fixup_segment): Don't throw away rva relocs.
+ * config/tc-arm.c (md_apply_fix, tc_gen_reloc): Handle RVA.
+ * config/tc-i386.c (tc_coff_fix2type): Handle RVA.
+ * config/tc-i386.h (TC_COUNT_RELOC): Remember RVAs.
+ (TC_RVA_RELOC): New definition.
+
+Sun Aug 27 17:41:05 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-arm.c (do_swi): Allow optional leading '#'.
+
+Sat Aug 26 17:24:20 1995 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-m68k.c (comment_chars): If TE_DELTA is defined,
+ include '#'.
+ * config/tc-m68k.h (NO_PSEUDO_DOT): Define if TE_DELTA is
+ defined.
+
+ * config/te-delta.h: Include obj-format.h.
+ * config/te-sco386.h: Likewise.
+ * config/te-sysv32.h: Likewise.
+
+ * app.c (scrub_file): Remove.
+ (scrub_from_file, scrub_to_file): Remove.
+ (scrub_string, scrub_last_string): Remove.
+ (scrub_from_string, scrub_to_string): Remove.
+ (saved_input, saved_input_len): New static variables.
+ (struct app_saved): Remove scrub_string, scrub_last_string, and
+ scrub_file fields. Add saved_input and saved_input_len fields.
+ (app_push): Adjust saved fields for changes in struct app_save.
+ Initialize state and saved_input.
+ (app_pop): Adjust saved fields for changes in struct app_save.
+ (do_scrub_chars): Rename from do_scrub_next_char and rewrite to
+ process a buffer at a time rather than a character at a time.
+ (main, as_warn): Remove obsolete testing code.
+ * as.h (do_scrub_next_char): Don't declare.
+ (do_scrub_chars): Declare.
+ (scrub_from_file, scrub_from_string): Don't declare.
+ (scrub_to_file, scrub_to_string): Don't declare.
+ * input-file.c (input_file_get): New static function.
+ (input_file_give_next_buffer): Call do_scrub_chars rather than
+ do_scrub_next_char.
+ * read.c (scrub_string, scrub_string_end): New static variables.
+ (scrub_from_string): New static function.
+ (read_a_source_file): Call do_scrub_chars rather than
+ do_scrub_next_char.
+
+Thu Aug 24 18:50:19 1995 Ian Lance Taylor (ian@cygnus.com)
+
+ * gasp.c (as_abort): New function.
+ * sb.c (sb_build): Revert yesterday's patch.
+
+ * Makefile.in (gasp.new): Depend upon ../libiberty/libiberty.a.
+ Just link against libiberty, not against $(LIBS).
+
+Wed Aug 23 15:18:20 1995 Ian Lance Taylor (ian@cygnus.com)
+
+ * sb.c (sb_build): Undefine abort before calling it, since gasp
+ does not provide as_abort.
+
+Wed Aug 23 10:40:41 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (set_target_endian): New static to say whether
+ we've initialized target_big_endian or not.
+ (md_parse_option): Set set_target_endian if we set the variable
+ target_big_endian.
+ (md_begin): Only set target_big_endian if !set_target_endian.
+
+Tue Aug 22 03:00:33 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ Sat Aug 19 18:08:16 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.h (DST_S_C_SRC_SETREC_W, DST_S_C_SRC_DEFLINES_B):
+ New macros.
+ * config/obj-vms.c (VMS_TBT_Line_PC_Correlation,
+ VMS_TBT_Source_Lines): Make traceback info be robust enough to
+ handle huge source files.
+ (VMS_TBT_Source_File): Reorganize the native- vs cross-assembly
+ support so that actual object file output is clearer.
+ (VMS_TBT_Source_File: Fab, Nam, Date_Xab, File_Header_Xab):
+ Replace static variables with automatic ones.
+
+ Sat Aug 12 20:18:15 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.c (Module_Name): new file scope variable.
+ (VMS_TBT_Module_Begin): use it instead of local variable.
+ (Write_VMS_MHD_Records): ditto; assign its value here.
+ (Write_VMS_EOM_Record): second argument has type valueT.
+ (VMS_Initialized_Data_Size): simplify search loop; return
+ type is offsetT; second argument is unsigned.
+
+ Sat Jun 17 19:05:25 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * messages.c (as_perror): Use xstrerror instead of strerror.
+
+Mon Aug 21 13:57:20 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.c (parse_args): Accept --defsym SYM=VALUE.
+ * doc/as.texinfo, doc/as.1: Document --defsym.
+
+ * read.c (read_a_source_file): In MRI mode, don't end the
+ statement inside a quotation.
+ (s_space): Don't warn about a zero repeat count in MRI mode.
+ * config/tc-m68k.c (crack_operand): In MRI mode, don't count
+ parentheses inside quotes.
+ (md_assemble): In MRI mode, anything after the operands field is a
+ comment.
+ (parse_mri_control_operand): Adjust start and stop to remove
+ spaces.
+ (s_mri_for): Likewise.
+
+ * cond.c (s_ifdef): Restore the character after the symbol name,
+ in case it is a newline.
+ (s_if): If ignoring the current tree, don't try to parse the
+ expression.
+
+ * app.c (do_scrub_next_char): If LEX_IS_STRINGQUOTE or
+ LEX_IS_ONECHAR_QUOTE is seen in state 10, preserve one space.
+
+ * doc/as.texinfo: Document irp, irpc, macro, and rept. MRI mode
+ now supports macros, ifc, ifnc, irp, irpc, rept, and endr, without
+ using gasp.
+
+ Add support for macros.
+ * as.c: Include sb.h and macro.h.
+ (max_macro_next): New global variable.
+ (main): Call macro_init.
+ (macro_expr): New static function.
+ * as.h (max_macro_nest): Declare.
+ * read.c (line_label): Rename from mri_line_label. Change all
+ uses.
+ (potable): Add exitm, irp, irpc, macro, mexit, rept.
+ (read_a_source_file): Always clear line_label at the start of a
+ line, not just when flag_mri or LABELS_WITHOUT_COLONS. Fix
+ MRI/LABELS_WITHOUT_COLONS handling. In MRI mode, permit label:
+ equ val. Set line_label when calling colon. In MRI mode, a
+ leading '.' does not imply a pseudo-op. Check for macro expansion
+ before calling md_assemble.
+ (s_irp): New function.
+ (get_line_sb): New static function.
+ (s_macro): New function.
+ (s_mexit): New function.
+ (s_rept): New function.
+ * read.h (line_label): Rename from mri_line_label.
+ (s_irp, s_rept): Declare.
+ (s_macro, s_mexit): Declare.
+ * input-scrub.c: Include sb.h.
+ (sb_index, from_sb): New static variables.
+ (macro_nest): New static variable.
+ (struct input_save): Add sb_index and from_sb fields. Change
+ next_saved_file field to be struct input_save *.
+ (next_saved_file): Changed to be struct input_save *.
+ (input_scrub_push): Change to return type struct input_save *.
+ Save sb_index and from_sb.
+ (input_scrub_pop): Change parameter type to struct input_save *.
+ Restore sb_index and from_sb.
+ (input_scrub_include_sb): New function.
+ (input_scrub_next_buffer): Handle reading from from_sb.
+ (bump_line_counters): Only increment lines if not using from_sb.
+ * config/tc-m68k.c (opt_table): Add nest.
+ (opt_nest): New static function.
+ * gasp.c: Include sb.h and macro.h. Move all sb related functions
+ and definitions to sb.h and sb.c. Move all macro related
+ functions and definitions to macro.h and macro.c.
+ * sb.h, sb.c: New files, extracted from gasp.c.
+ * macro.h, macro.c: Likewise.
+ * Makefile.in (OBJS): Add sb.o and macro.o
+ (GASPOBJS): Define.
+ (gasp.new): Depend upon $(GASPOBJS). Use $(GASPOBJS) to link.
+ (TARG_CPU_DEP_m68k): Depend upon subsegs.h.
+ (gasp.o): Depend upon sb.h and macro.h.
+ (sb.o): New target.
+ (macro.o): New target.
+ (as.o): Depend upon sb.h and macro.h.
+ (input-scrub.o): Depend upon sb.h.
+ (read.o): Depend upon sb.h and macro.h.
+
+ * cond.c (get_mri_string): New static function.
+ (s_ifc): New function.
+ * read.c (potable): Add ifc and ifnc.
+ * read.h (s_ifc): Declare.
+
+ * app.c (do_scrub_begin): In MRI mode, set lex of ' to
+ LEX_IS_STRINGQUOTE.
+
+Mon Aug 21 13:41:33 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.c (md_assemble): Allow @HA, @L, and @H suffixes on
+ constant expressions.
+
+Sun Aug 20 15:54:37 1995 Jim Wilson <wilson@cygnus.com>
+
+ * config/tc-arm.c (md_reloc_size): Add const to declaration.
+
+Fri Aug 18 10:58:09 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (s_include): In MRI mode, don't expect quotes around the
+ file name.
+ * listing.c (listing_title): Don't require the title to be quoted.
+
+ * gasp.c (include_print_where_line): Always subtract 1 from
+ linecount before printing it.
+ (process_file): In MRI mode, lines beginning with '*' or '!' are
+ comments.
+ (do_reg): In MRI mode, don't require parentheses.
+ (do_include): In MRI mode, don't requires quotes. If the file can
+ not be found in the include path, try opening it in the current
+ directory. Print the file name correctly in the error message.
+ (chartype_init): In MRI mode, set FIRSTBIT for '.'.
+ (main): Set comment_char to ';' when entering MRI mode.
+
+ * config/tc-m68k.c: Include subsegs.h.
+ (m68k_ip): Pass 64 rather than -1 to add_Fix in 'B' 'B' case.
+ (md_pcrel_from): If fx_pcrel_adjust is 64, use -1 instead.
+
+ * config/tc-sparc.h (tc_fix_adjustable): For OBJ_AOUT case, adjust
+ BFD_RELOC_16 and BFD_RELOC_32 relocs.
+
+Wed Aug 16 14:48:44 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * as.h (alloca): Use void* declaration on HP/UX.
+
+Wed Aug 16 12:49:17 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c (tc_gen_reloc): If PIC, only change PCREL_S2
+ to WPLT30 for an undefined or external symbol. Don't consider
+ PC10 or PC22 to be a PC relative reloc when choosing between
+ fx_addnumber and fx_offset.
+
+ * config/tc-z8k.c (md_number_to_chars): Don't do it here, call
+ number_to_chars_bigendian.
+ * config/tc-z8k.h (TARGET_BYTES_BIG_ENDIAN): Define.
+
+ * expr.c (operand): Add support for .startof. and .sizeof. by
+ using magic symbol names which the linker will recognize
+ specially.
+ * doc/as.texinfo: Take out note that .startof. and .sizeof. are
+ not supported.
+
+Tue Aug 15 15:08:49 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (md_pseudo_table): Add MRI structured control
+ directives: if, if.b, if.w, if.l, else, else.s, else.l, endi,
+ break, break.s, break.l, next, next.s, next.l, for, for.b, for.w,
+ for.l, endf, repeat, until, until.b, until.w, until.l, while,
+ while.b, while.w, while.l, endw.
+ (enum mri_control_type): Define.
+ (struct mri_control_info): Define.
+ (mri_control_stack): New static variable.
+ (mri_control_index): New static variable.
+ (mri_control_label): New static function.
+ (push_mri_control, pop_mri_control): New static functions.
+ (parse_mri_condition): New static function.
+ (parse_mri_control_operand): New static function.
+ (swap_mri_condition, reverse_mri_condition): New static functions.
+ (build_mri_control_operand): New static function.
+ (parse_mri_control_expression): New static function.
+ (s_mri_if, s_mri_else, s_mri_endi): New static functions.
+ (s_mri_break, s_mri_next): New static functions.
+ (s_mri_for, s_mri_endf): New static functions.
+ (s_mri_repeat, s_mri_until): New static functions.
+ (s_mri_while, s_mri_endw): New static functions.
+ * gasp.c (mrikinfo): Remove IF.
+ * expr.c (get_symbol_end): Accept \001 as part of a name.
+
+ * symbols.c (colon): Change parameter to const char *.
+ * symbols.h (colon): Update declaration.
+
+Mon Aug 14 20:51:56 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * write.c (write_contents): Always do it the BFD_FAST_SECTION_FILL
+ way. Reformat and reindent that code to GNU standards.
+ (BFD_FAST_SECTION_FILL): Don't define.
+
+Mon Aug 14 14:08:07 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): Don't try to apply BEGIN_BRTAB
+ or END_BRTAB fixups.
+
+Mon Aug 14 15:45:07 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gasp.c (do_align, get_any_string): Mark as static.
+ (do_assigna, do_assignc, new_file): Likewise.
+
+ * config/tc-m68k.c (s_reg): Rename local op to rop to avoid
+ confusion with macro op.
+
+ * gasp.c (strip_comments): Comment out; it's not used.
+ (do_end): Add parameter. In MRI mode, print it out.
+ (do_irp): New static function.
+ (sub_actual): Change parameter m to formal_hash, changing type
+ from macro_entryh * to hash_table *.
+ (macro_expand_body): New static function, broken out of
+ macro_expand.
+ (macro_expand): Call macro_expand_body.
+ (K_*): Fully parenthesize.
+ (K_IRP, K_IRPC): Define.
+ (mrikinfo): Add IRP and IRPC.
+ (process_pseudo_op): In MRI mode, print out END pseudo-op. Pass
+ line to do_end. Handle K_IRP and K_IRPC.
+
+ * config/tc-m68k.c (s_opt): Reset *input_line_pointer even if we
+ don't do anything with the option.
+
+Sun Aug 13 17:03:58 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * frags.c (frag_align): Handle absolute_section.
+ * write.c (record_alignment): Likewise.
+
+ * config/tc-mips.c (macro_build): Skip insns with an inappropriate
+ ISA level.
+
+Sun Aug 13 00:35:02 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_pseudo_table): Add entries for
+ "begin_brtab" and "end_brtab" pseudo-ops.
+ (pa_brtab): New function.
+ (tc_gen_reloc, SOM version): Handle R_BEGIN_BRTAB and R_END_BRTAB.
+ (hppa_force_relocation): Force relocations for BRTAB fixups
+ when OBJ_SOM is defined.
+
+Fri Aug 11 20:34:05 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * Makefile.in (TE_OBJS): Add empty definition.
+
+Fri Aug 11 19:16:08 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gasp.c (change_base): Don't treat ' specially in MRI mode.
+ (process_file): Don't warn about missing END in MRI mode.
+ (do_if): New static function.
+ (get_mri_string, do_ifc): New static functions.
+ (buffer_and_nest): Treat MRI mode like alternate syntax mode.
+ (do_aendr): Change error message in MRI mode.
+ (do_arepeat): Use REPT/ENDR in MRI mode.
+ (do_formals): In MRI mode, add special NARG formal.
+ (macro_expand): Various changes for MRI mode: permit a qualifier
+ on the macro name; set special NARG formal; permit unnamed
+ positional arguments; use && to concatenate named parameters;
+ permit \d to specify an unnamed parameter; permit named parameters
+ to not start with \; use == to see if a parameter exists.
+ (getstring): In MRI mode, allow <> to quote a string.
+ (K_IFEQ, K_IFNE, K_IFLT, K_IFLE, K_IFGE, K_IFGT): Define.
+ (K_IFC, K_IFNC): Define.
+ (struct keyword): Name structure used in kinfo array.
+ (mrikinfo): New static array.
+ (process_pseudo_op): Don't require leading '.' in MRI mode.
+ Handle new MRI pseudo-op definitions.
+ (add_keyword): New static function, broken out of process_init.
+ (process_init): Use add_keyword. In MRI mode, add mrikinfo table.
+ (long_options): Add "mri".
+ (show_usage): Mention -M/--mri.
+ (main): Call process_init after processing arguments. Handle -M.
+ * doc/gasp.texi: Document -M/--mri.
+
+ * gasp.c: Include ansidecl.h. Make all local functions static.
+ Add prototypes for all static functions.
+ (mri): New global variable.
+ (sb_add_char): Change parameter c from char to int.
+ (sb_add_string): Make parameter s into a const pointer.
+ (sb_add_buffer): Likewise.
+ (checkconst): Change parameter op from char to int.
+ (exp_get_abs): Make parameter emsg into a const pointer.
+ (do_res): Change parameter type from char to int.
+ (buffer_and_nest): Make parameters from and to into const
+ pointers.
+ (do_sdata): Change parameter type from char to int.
+ (new_file): Make parameter name into a const pointer.
+ (do_define): Make parameter string into a const pointer.
+
+ * config/tc-h8300.c (md_number_to_chars): Don't do it here, call
+ number_to_chars_bigendian.
+ * config/tc-h8300.h (TARGET_BYTES_BIG_ENDIAN): Define.
+
+Fri Aug 11 13:23:56 1995 Michael Meissner <meissner@cygnus.com>
+
+ * write.h (struct fix): Add new field fx_no_overflow.
+
+ * write.c (fixup_segment): If fx_no_overflow is non-zero, don't
+ complain if the addend is too large.
+
+ * config/tc-ppc.c (md_assemble): Set fx_no_overflow if the half
+ word relocations BFD_RELOC_{LO16,HI16,HI16_S}.
+
+Thu Aug 10 20:56:38 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * read.c (s_mri_sect) [BFD_ASSEMBLER]: Fix typos in choosing and
+ setting section flags.
+
+Thu Aug 10 00:38:11 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo: Add documentation for MRI compatibility mode.
+ * doc/as.1: Likewise.
+
+ * config/tc-m68k.c (m68k_ip): When recognizing '#', use isbyte and
+ iword rather than expr8 and expr16. When recognizing 'M', use
+ issbyte rather than expr8. When recognizing 'Q' and 't', just
+ check for O_constant rather than using expr8.
+ * config/m68k-parse.h (expr8, expr16): Don't define.
+ * Makefile.in (m68k-parse.o): Depend upon m68k-parse.h, not
+ m68k-parse.y.
+
+ * read.c (potable): Add spc, ttl, xcom, xref.
+ (s_mri_sect): New function.
+ * read.h (s_mri_sect): Declare.
+ * config/obj-coff.c (obj_coff_section) (both versions): In MRI
+ mode, call s_mri_sect.
+ (obj_pseudo_table): Add sect.s and section.s. Move sect outside
+ of ifndef BFD_ASSEMBLER.
+ * config/obj-elf.c (elf_pseudo_table): Add section.s, sect,
+ sect.s.
+ (obj_elf_section): In MRI mode, call s_mri_sect.
+ * config/tc-m68k.c (md_pseudo_table): Add restore, save.
+ (struct save_opts): Define.
+ (save_stack): New static variable.
+ (s_save, s_restore): New static functions.
+
+ * read.c (s_set): Remove unused local ptr.
+ (hex_float): Check target_big_endian.
+ (equals): Remove unused local p.
+
+ * config/tc-a29k.h (TARGET_BYTES_BIG_ENDIAN): Define.
+ * config/tc-h8500.h (TARGET_BYTES_BIG_ENDIAN): Define.
+ * config/tc-hppa.h (TARGET_BYTES_BIG_ENDIAN): Define.
+ * config/tc-i860.h (TARGET_BYTES_BIG_ENDIAN): Define.
+ * config/tc-m68k.h (TARGET_BYTES_BIG_ENDIAN): Define.
+ * config/tc-m88k.h (TARGET_BYTES_BIG_ENDIAN): Define.
+ * config/tc-tahoe.h (TARGET_BYTES_BIG_ENDIAN): Define.
+ * config/tc-sh.c (little): Set target_big_endian.
+ (md_begin): Likewise.
+ (md_parse_option): Likewise.
+ (build_relax): Check target_big_endian rather than shl.
+ (build_Mytes, md_atof): Likewise.
+ (md_convert_frag, md_apply_fix): Likewise.
+ (md_number_to_chars): Likewise.
+
+Wed Aug 9 10:51:48 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_abspcadd): New static variable.
+ (m68k_quick): New static variable.
+ (m68k_rel32): New static variable.
+ (md_pseudo_table): Add opt and reg.
+ (m68k_ip): Permit absolute symbols in 'l'/'L' recognition. Check
+ m68k_quick in 'M' and 'Q' recognition. Check m68k_abspcadd in
+ DISP handling. Check m68k_rel32 in BASE/POST/PRE handling.
+ (md_begin): In MRI mode, initialize m68k_abspcadd and m68k_rel32.
+ In MRI mode, change unsized branch aliases to be variable sized.
+ (struct opt_action): Define.
+ (opt_table): Define.
+ (s_opt): New static function.
+ (skip_to_comma): New static function.
+ (opt_chip): New static function.
+ (opt_list): New static function.
+ (opt_list_symbols): New static function.
+ (s_reg): New static function.
+ * as.h (flag_keep_locals): Change from unsigned char to int.
+ (flag_no_warnings): Likewise.
+
+ * read.c (mri_line_label): Make non-static.
+ (potable): Add nopage, page, plen.
+ (s_org): Error if in MRI mode.
+ * read.h (mri_line_label): Declare.
+ * listing.c (listing_nopage): New function.
+ * listing.h (listing_nopage): Declare.
+
+ * symbols.c (symbol_begin): Set sy_frag of abs_symbol to
+ &zero_address_frag.
+
+ * write.c (adjust_reloc_syms): Check that symbol is not NULL
+ before checking sy_mri_common.
+ (fixup_segment): Likewise.
+ * config/obj-coff.c (fixup_segment): Likewise.
+
+ * read.c (abs_section_offset): New global variable.
+ (potable): Add offset, struct.
+ (do_org): New static function; handle changing the origin in the
+ absolute section.
+ (s_org): Use do_org.
+ (s_set): Likewise.
+ (equals): Likewise.
+ (s_space): In absolute_section, just increase abs_section_offset.
+ (s_struct): New function.
+ (emit_expr): Handle absolute_section specially.
+ * read.h (abs_section_offset): Declare.
+ (s_struct): Declare.
+ * frags.c (frag_more): Warn if in absolute_section.
+ (frag_now_fix): In absolute_section, return abs_section_offset.
+ * subsegs.c (subseg_change): If switching to absolute_section,
+ just set now_seg and now_subseg.
+ (subseg_set_rest): Special handling when switching to or from
+ absolute_section.
+
+ * config/tc-m68k.c (m68k_float_copnum): New static variable.
+ (md_pseudo_table): Add fopt and mask2.
+ (m68k_ip): Use m68k_float_copnum, not COPNUM, when setting
+ coprocessor register to use. In case 'I' when checking operands,
+ correct coprocessor register numbers. In case 'I' when setting
+ operands, don't add 1.
+ (s_fopt): New static function.
+ * config/m68k-parse.h (COPNUM): Don't define.
+
+ * read.c (potable): Add ifeq, ifge, ifgt, ifle, iflt, ifne.
+ Change if to pass O_ne to s_if.
+ (read_a_source_file): Don't define an label without a colon if
+ ignore_input returns true.
+ * cond.c (s_if): Treat argument as an operatorT describing how to
+ compare the argument against zero.
+ (ignore_input): Don't require an initial dot in MRI mode, or if
+ NO_PSEUDO_DOT is defined.
+
+ * read.c (potable): Add dcb, dcb.b, dcb.d, dcb.l, dcb.s, dcb.w,
+ dcb.x, ds.d, ds.p, ds.s, ds.x, elsec, endc, fail, format, llen,
+ noformat.
+ (read_a_source_file): If pseudo-op handler is s_end, quit
+ immediately.
+ (s_end): New function.
+ (s_fail): New function.
+ (s_float_space): New function.
+ (hex_float): New static function.
+ (float_cons): Use hex_float.
+ * read.h (s_fail): Declare.
+ (s_float_space): Declare.
+ * cond.c (s_end): Remove.
+ * listing.c (listing_psize): Treat argument as indicating whether
+ a height is expected.
+
+ * read.c (mri_pending_align): New static variable.
+ (read_a_source_file): Handle mri_pending_align.
+ (cons): Set mri_pending_align if appropriate.
+
+ * configure.in: Move random special target handling before
+ possible break.
+ * configure: Rebuild.
+
+Tue Aug 8 23:41:25 1995 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * configure.in: Consistently use ${target_cpu_type} rather than
+ ${cpu_type} after the loop.
+ * configure: Rebuild.
+ * Makefile.in (targ-cpu.o): Use @target_cpu_type@ rather than
+ @cpu_type@.
+
+Tue Aug 8 17:27:17 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * expr.h (operatorT): Remove comma after last enumerator value.
+
+ * config/obj-vms.c: Some whitespace cleanup from Pat Rankin.
+
+ * as.h (alloca): If __STDC__, declare void* instead of char*.
+
+ Wed Aug 2 18:54:37 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.c (Flush_VMS_Object_Record_Buffer,
+ Close_VMS_Object_File): Reorganize the `#if !VMS' cross-assmebler
+ support code.
+ (Close_VMS_Object_File): Call Set_VMS_Object_File_Record to flush
+ output buffer--just in case--before closing the file.
+
+Tue Aug 8 13:07:05 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (archs): Add 68ec000, 68hc000, 68hc001,
+ 68ec020, 68ec030, 68ec040, and 68330.
+ (md_pseudo_table): Add chip and comline.
+ (m68k_init_after_args): Use strcasecmp when comparing default_cpu
+ against architectures.
+ (mri_chip, s_chip): New static functions.
+
+ * struc-symbol.h (struct symbol): Add sy_mri_common bit.
+ * read.h (mri_comon_symbol): Declare.
+ (s_mri_common): Declare.
+ * read.c (mri_line_label): New static variable.
+ (mri_common_symbol): New global variable.
+ (potable): Add "common" and "common.s".
+ (read_a_source_file): In MRI mode, set mri_line_label for a label
+ at the start of a line.
+ (s_mri_common): New function.
+ (s_space): Handle mri_common_symbol.
+ * symbols.c (colon): Change return value from void to symbolS *,
+ and return new symbol. If mri_common_symbol is set, attach the
+ new symbol to it.
+ (resolve_symbol_value): Handle an sy_mri_common symbol.
+ * symbols.h (colon): Change return value in declaration.
+ * subsegs.c (subseg_set_rest): Clear mri_common_symbol.
+ (subseg_set (both versions)): Likewise.
+ * frags.c (frag_more): Warn if mri_common_symbol is not NULL.
+ * write.c (adjust_reloc_syms): Skip sy_mri_common symbols.
+ (write_object_file): Discard sy_mri_common symbols.
+ (fixup_segment): Change relocations against sy_mri_common symbols
+ to be against the common symbol itself.
+ * config/obj-coff.c (yank_symbols): Discard sy_mri_common symbols.
+ (fixup_segment): Change relocations against sy_mri_common symbols
+ to be against the common symbol itself.
+ * config/obj-aout.c (obj_crawl_symbol_chain): Discard
+ sy_mri_common symbols.
+
+ * doc/c-m68k.texi: Add documentation for CPU specific options, and
+ for Motorola syntax.
+
+ * config/m68k-parse.y (motorola_operand): For (%pc), set mode to
+ DISP, not BASE.
+
+Tue Aug 8 02:31:38 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * write.c (relax_align): Add extra padding for linkrelax only if
+ LINKER_RELAXING_SHRINKS_ONLY is defined.
+ * config/tc-i960.h (LINKER_RELAXING_SHRINKS_ONLY): Define it.
+ * doc/internals.texi (Relaxation): Write up some stuff on linker
+ relaxing and LINKER_RELAXING_SHRINKS_ONLY.
+
+Mon Aug 7 17:18:10 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/m68k-parse.y: New file: bison grammar for m68k operands,
+ including support for Motorola syntax.
+ * config/m68k-parse.h: New file; definitions shared between
+ m68k-parse.y and tc-m68k.c.
+ * config/tc-m68k.c: Include m68k-parse.h.
+ (enum operand_type): Move to m68k-parse.h, where it is named
+ m68k_operand_type. Rename all uses. Rearrange somewhat. Add
+ FPREG. Rename AOFF to DISP. Rename AINDX to BASE. Rename APODX
+ to POST. Rename APRDX to PRE. Remove AMIND. Rename MSCR to
+ CONTROL. Remove DINDR.
+ (struct m68k_exp): Move to m68k-parse.h. Remove e_beg, e_end and
+ e_seg fields. Rename e_exp to exp. Rename e_siz to size, and
+ change type to enum m68k_size. Change all uses.
+ (enum _register): Move to m68k-parse.h, where it is named
+ m68k_register. Rename all uses. Add ZDATA0-7 and ZADDR0-7.
+ (struct m68k_op): Move to m68k-parse.h. Change all fields.
+ (seg): Don't define.
+ (add_exp): Remove.
+ (FAIL, OK): Remove.
+ (m68k_reg_parse): Move to m68k-parse.y, and rewrite.
+ (SKIP_WHITE, SKIP_W): Remove.
+ (try_moto_index, try_index): Remove.
+ (m68k_ip_op): Move to m68k-parse.y, and rewrite to use grammar.
+ (main): Remove obsolete test function.
+ (m68k_ip): Extensive changes to use new grammar.
+ (get_regs): Remove.
+ (crack_operand): m68k_ip_op now returns 0 on success.
+ (init_table): Add ssp, zd0-7 and za0-7.
+ (md_assemble): Make er const. Correct loop over operands when
+ looking for error message.
+ (md_begin): Set alt_notend_table for '(' and '@'.
+ (get_num): Expression is already parsed. Don't set seg.
+ * configure.in: If cpu_type is m68k, put m68k-parse.o in
+ extra-objects.
+ * configure: Rebuild.
+ * Makefile.in (DISTSTUFF): Add m68k-parse.c.
+ (BISON): Use ../bison/bison if it exists.
+ (BISONFLAGS): Define as empty.
+ (TARG_CPU_DEP_m68k): Depend upon $(srcdir)/config/m68k-parse.h.
+ (m68k-parse.c, m68k-parse.o): New targets.
+
+Mon Aug 7 02:54:20 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-sh.c (parse_reg): Handle new FP registers.
+ (get_specific): Handle new operand types.
+
+Fri Aug 4 12:29:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * expr.c (op_encoding): Make non-const. Don't set '"' to
+ O_bit_not.
+ (expr_begin): Set op_encoding['"'] in MRI mode.
+
+Wed Aug 2 18:39:43 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c: Remove BREAK_UP_BIG_DECL stuff.
+ (struct m68k_incant): Change m_operands field to be const.
+ (struct m68k_it): Change args field to be const.
+ (m68k_ip): Change local variable s to be const.
+ (opcode_ptr): Remove.
+ (md_begin): Use m68k_numopcodes, not numopcodes. Use
+ m68k_opcodes, not removed opcode_ptr. Use m68k_numaliases, not
+ numaliases.
+
+Tue Aug 1 17:35:26 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (init_table): Add "control", "status", "iaddr",
+ "sfcr", and "dfcr" as synonyms for existing entries.
+ (md_begin): In MRI mode, force flag_reg_prefix_optional to 1.
+ (md_parse_option): Removed unused locals i and arch. Change type
+ of arch (another one) to unsigned long.
+ (tc_coff_sizemachdep): Add return after abort to avoid warning.
+
+ Initial support for MRI style labels and expressions.
+ * as.h (flag_mri): Declare/define.
+ * as.c (show_usage): Mention -M and its synonym --mri.
+ (parse_args): Add 'M' to std_shortopts. Add "mri" to
+ std_longopts. Set flag_mri if -M is seen.
+ (main): Call parse_args before input_scrub_begin. Call
+ expr_begin.
+ * app.c (do_scrub_begin): Don't set lex for '"' or '\'' in MRI
+ mode. Do set lex for ';', '*', and '!' in MRI mode.
+ (do_scrub_next_char): Remove MRI ifdef in LEX_IS_WHITESPACE case.
+ In MRI mode, keep spaces between labels and colons. Remove MRI
+ ifndef around LEX_IS_ONECHAR_QUOTE case. In MRI mode, don't use
+ '!' or '*' as comment characters even if they are in
+ comment_chars.
+ * read.h (lex_type): No longer const.
+ * read.c: Include libiberty.h.
+ (lex_type): No longer const.
+ (read_begin): In MRI mode, set lex_type of '?' to 3.
+ (potable): Add dc, dc.b, dc.d, dc.l, dc.s, dc.w, dc.x, ds, ds.b,
+ ds.l, ds.w, and xdef.
+ (read_a_source_file): Change LABELS_WITHOUT_COLON ifdef to check
+ for MRI mode at runtime rather than compile time. Handle the EQU
+ pseudo-op in MRI mode. Remove bogus MRI ifdef around done_pseudo.
+ Change NO_PSEUDO_DOT ifdef to also take effect for MRI mode at
+ runtime.
+ (cons): In MRI mode, always call parse_mri_cons rather than
+ TC_PARSE_CONS_EXPRESSION.
+ (parse_mri_cons): Always compile, not just when MRI is defined.
+ Call TC_PARSE_CONS_EXPRESSION, not expression, when the input is
+ not a string constant. Handle A and E modifiers.
+ (float_cons): Accept :xxxx, where the x's are hex digits.
+ * expr.h (operatorT): Add O_eq, O_ne, O_lt, O_le, O_ge, O_gt.
+ (expr_begin): Declare.
+ * expr.c (integer_constant): In MRI mode, if the base was not
+ specified, look for a suffix on the number to set the base.
+ (mri_char_constant): New static function.
+ (operand): Remove MRI ifdef. In MRI mode, do various things: Pass
+ 0 as the base when calling integer_constant if there was no
+ prefix. Check for a hex constant suffix if when a leading '0' is
+ seen. Don't accept 0x or 0b as a prefix. Check for E'chars' and
+ A'chars'. Handle MRI character constants. Treat '"' as the
+ unary bitwise not operator. Treat $ as the program counter, or as
+ the prefix for a hex constant. Treat % as the prefix for a binary
+ constant and @ as the prefix for an octal constant. Treat : as
+ the prefix for a hex constant.
+ (op_encoding): Set '"' to O_bit_not, '<' to O_lt, and '>' to O_gt.
+ (op_rank): No longer const. Change rank values.
+ (expr_begin): New function.
+ (operator): New static function.
+ (expr): Use operator. Don't bother to mention the operator in
+ warnings. Remove bogus #if 0 code. Handle new operatorT values.
+ * atof-generic.c (atof_generic): In MRI mode, accept underscores
+ around the exponent in floating point numbers.
+ * symbols.h (symbols_case_sensitive): Declare.
+ * symbols.c (symbols_case_sensitive): New global variable.
+ (symbol_create): Check symbols_case_sensitive.
+ (symbol_find_base): Likewise.
+ (resolve_symbol_value): Handle new operatorT values.
+ (print_expr_1): Likewise.
+ (S_IS_LOCAL): In MRI mode, names beginning with two '?' characters
+ are local.
+
+Tue Aug 1 11:35:18 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * config/tc-sh.c (md_convert_frag): Make some error messages
+ more explict.
+
+Mon Jul 31 21:40:47 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Sat Jul 29 18:55:23 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.c (COPY_SHORT, COPY_LONG, PUT_SHORT, PUT_LONG):
+ Make expansion be safe for use in expressions.
+ (PUT_COUNTED_STRING): Bracket expansion with `do {...} while (0)'
+ rather than just `{...}'.
+
+Mon Jul 31 18:19:26 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * gasp.c (main): Parse -I option.
+ (do_include): Look through include list.
+ * gasp.c (change_base): Don't modify numbers in strings.
+
+Mon Jul 31 12:16:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.h (SUB_SEGMENT_ALIGN): Define. From Niclas
+ Andersson <nican@ida.liu.se>.
+
+Thu Jul 27 20:47:12 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): Don't do further pcrel
+ processing after converting difference of two symbols in the
+ same segment. From Jim Wilson.
+
+ * configure.in (i386-*-linuxoldld): Add as synonym for
+ i386-*-linux*aout*. From Fred Fish.
+ * configure: Regenerated.
+
+Thu Jul 27 16:14:56 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.c (enum ps_type {ps_TEXT,ps_DATA,ps_COMMON,
+ ps_CONST}): New constants.
+ (VMS_Psect_Spec): Use them instead of literal strings.
+ (vms_write_object_file, global_symbol_directory): Adjust callers.
+
+Wed Jul 26 18:31:35 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.c (const_flag): Change from char to unsigned char.
+ * config/obj-vms.h (const_flag): Ditto.
+ (struct nlist): Replace union n_un and n_un.{n_name,n_next,n_strx}
+ fields with just n_name; delete field n_value; change n_other from
+ char to unsigned char and n_desc from short to int; insert explicit
+ padding for alignment.
+
+Mon Jul 24 20:06:17 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * subsegs.h (struct seg_info_trash): Make bitfield types valid.
+
+ * config/obj-coff.c (fixup_segment): Local add_number should not
+ be declared register since its address is taken for
+ MD_APPLY_FIX3.
+
+ Fri Jul 21 15:28:18 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ Split huge vms_write_object_file routine into managable pieces.
+
+ * config/obj-vms.c (vms_fixup_text_section, synthesize_data_segment,
+ vms_fixup_data_section, global_symbol_directory, local_symbols_DST,
+ vms_build_DST): New routines.
+ (vms_write_object_file): Call them.
+ (struct vms_obj_state): New file scope variable used by the above.
+
+Mon Jul 24 14:10:24 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (md_pseudo_table): Add "uses".
+ (s_uses): New static function.
+ (sh_coff_frob_file): New function.
+ (md_convert_frag): Call subseg_change before calling fix_new.
+ (sh_handle_align): New function.
+ (SWITCH_TABLE): Define.
+ (sh_force_relocation): New function.
+ (md_apply_fix): Handle R_SH_USES, R_SH_COUNT and R_SH_ALIGN.
+ (sh_coff_reloc_mangle): Likewise. Also handle switch table
+ entries.
+ * config/tc-sh.h (HANDLE_ALIGN): Define.
+ (sh_handle_align): Declare.
+ (TC_FORCE_RELOCATION): Define.
+ (sh_force_relocation): Declare.
+ (TC_COUNT_RELOC): Simplify; rely on TC_FORCE_RELOCATION instead.
+ (tc_frob_file): Define.
+ (sh_coff_frob_file): Declare.
+ * config/obj-coff.c (write_object_file): Call tc_frob_file if it
+ is defined.
+ (fixup_mdeps): Call HANDLE_ALIGN if it is defined.
+ (TC_FORCE_RELOCATION): Define if not defined.
+ (fixup_segment): Use TC_FORCE_RELOCATION to decide whether to
+ clear the symbol fields of fixP.
+
+Fri Jul 21 22:38:00 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Add support for R_PPC_SDAREL
+ relocation.
+ (md_apply_fix3): Ditto.
+
+Thu Jul 20 13:00:56 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/tc-m68k.c (md_convert_frag): Rename argument seg to sec,
+ since seg is a macro name in this file.
+
+ * configure.in (arm-*-riscix*): Don't set emulation.
+
+Wed Jul 19 16:08:29 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/obj-coff.h (TE_PE): Delete.
+ * config/tc-arm.h (BYTE_ORDER): Delete.
+ (TARGET_FORMAT): Provide value for OBJ_COFF and TE_PE.
+ (ARM_BI_ENDIAN): Define if OBJ_COFF and TE_PE.
+ * config/tc-arm.c (byte_order): Delete.
+ (md_number_to_chars): Reference target_big_endian, not byte_order.
+ (md_chars_to_number): Likewise.
+ (md_longopts): Add -EB/-EL if ARM_BI_ENDIAN.
+ (md_parse_options): Recognize -EB/-EL.
+ (md_show_usage): List -EB/-EL.
+
+Wed Jul 19 11:49:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gasp.c (process_assigns): Use toupper before comparing against
+ upper case letter.
+ (whatcond): Likewise.
+
+ * config/tc-sh.c (sh_relax): Rename from relax, and make global.
+ Renamed all uses.
+ (insert): Pass a size of 2, not 4.
+ (build_relax): Remove unused len variable.
+ (md_show_usage): Mention -little option.
+ (md_convert_frag): Add segT argument. Rewrite to generate relocs
+ rather than to generate complete instructions here.
+ (md_apply_fix): Adjust and clarify R_SH_PCRELIMM8BY4 case for
+ changes in insert and md_pcrel_from. Add cases for R_SH_PCDISP
+ and R_SH_PCDISP8BY2.
+ (md_pcrel_from): Don't subtract 1, add 2.
+ (tc_coff_fix2rtype): Remove.
+ (sh_coff_reloc_mangle): New function.
+ * config/tc-sh.h (TC_COFF_FIX2RTYPE): Just return fx_r_type.
+ (sh_relax): Declare.
+ (TC_COUNT_RELOC): If relaxing, count PC relative relocs.
+ (TC_RELOC_MANGLE): Define.
+ (sh_coff_reloc_mangle): Declare.
+ (tc_coff_sizemachdep): Declare.
+ * tc.h (md_convert_frag): Add segT parameter to non BFD_ASSEMBLER
+ declaration.
+ * write.c (cvt_frag_to_fill): Add sec argument to non
+ BFD_ASSEMBLER version. Pass it to md_convert_frag.
+ (write_object_file): Pass SEG_TEXT to cvs_frag_to_fill.
+ * config/obj-coff.c (do_relocs_for): Pass segment info to
+ TC_RELOC_MANGLE.
+ (fixup_mdeps): Pass segment type to md_convert_frag.
+ * config/tc-a29k.c (md_convert_frag): Add segT argument.
+ * config/tc-h8300.c (md_convert_frag): Likewise.
+ * config/tc-h8500.c (md_convert_frag): Likewise.
+ * config/tc-i386.c (md_convert_frag): Likewise.
+ * config/tc-i860.c (md_convert_frag): Likewise.
+ * config/tc-i960.c (md_convert_frag): Likewise.
+ * config/tc-m68k.c (md_convert_frag): Likewise.
+ * config/tc-m88k.h (md_convert_frag): Likewise.
+ * config/tc-ns32k.c (md_convert_frag): Likewise.
+ * config/tc-tahoe.c (md_convert_frag): Likewise.
+ * config/tc-vax.c (md_convert_frag): Likewise.
+ * config/tc-w65.c (md_convert_frag): Likewise.
+ * config/tc-z8k.c (md_convert_frag): Likewise.
+ * config/tc-h8300.h (TC_RELOC_MANGLE): Add segment argument.
+ * config/tc-h8500.h (TC_RELOC_MANGLE): Likewise.
+ * config/tc-w65.h (TC_RELOC_MANGLE): Likewise.
+ * config/tc-z8k.h (TC_RELOC_MANGLE): Likewise.
+
+Mon Jul 17 15:02:54 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.c (Current_Routine, Text_Psect): Delete as file
+ scope variables.
+ (Define_Routine, Define_Local_Symbols): Take Current_Routine and
+ Text_Psect as arguments.
+ (VMS_DBG_Define_Routine): Delete.
+ (VMS_TBT_Block_End): Change `Size' argument from int to valueT.
+ (vms_write_object_file: text and data fixup loops): Difference
+ of two symbols has type offsetT rather than int; convert with
+ md_number_to_chars before passing to VMS_Store_Immediate_Data.
+ (vms_write_object_file: debug symbol loop): Call Define_Routine
+ instead of VMS_DBG_Define_Routine.
+
+Sat Jul 15 00:01:35 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Add @fixup so that the
+ compiler can mark which relocs not to complain about with
+ -mrelocatable.
+ (ppc_elf_validate_fix): Add .fixup to sections not to complain
+ about, and also don't complain for BFD_RELOC_CTOR relocations in
+ writable non-code segments.
+ (md_apply_fix): Treat BFD_RELOC_CTOR just like BFD_RELOC_32.
+
+Fri Jul 14 19:54:28 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ Add support for SPARC SunOS PIC:
+ * config/tc-sparc.h (sparc_pic_code): Always declare, not just
+ when OBJ_ELF.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Define when OBJ_AOUT.
+ (tc_fix_adjustable): New definition for OBJ_AOUT.
+ * config/tc-sparc.c (sparc_pic_code): Always define, not just when
+ OBJ_ELF.
+ (md_apply_fix): Adjust reloc addend for OBJ_AOUT and PIC. In
+ BFD_RELOC_32_PCREL_S2 case, don't increment val for an external
+ symbol when PIC.
+ (tc_gen_reloc): Generate different PIC relocs when OBJ_AOUT, as
+ well as when OBJ_ELF.
+ (md_shortopts): If OBJ_AOUT, include `k'.
+ (md_parse_option): If OBJ_AOUT, handle 'k'.
+ (md_show_usage): Mention -k if OBJ_AOUT, and -KPIC if OBJ_ELF.
+ (md_pcrel_from): Don't add in size for an external symbol when
+ PIC.
+
+Thu Jul 13 21:16:43 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.h (UNDEFINED_DIFFERENCE_OK): Define for SOM.
+ * write.c (adjust_reloc_syms): Set sy_used_in_reloc for both
+ symbols in a fixup where a defined symbol is subtracted from an
+ undefined symbol (when UNDEFINED_DIFFERENCE_OK is defined).
+ (fixup_segment): Do nothing for the difference of two symbols if
+ UNDEFINED_DIFFERENCE_OK is defined.
+
+Wed Jul 12 23:33:40 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): Support MD_APPLY_FIX3.
+
+Wed Jul 12 01:12:12 1995 Ken Raeburn <raeburn@kr-pc.cygnus.com>
+
+ * write.c (fix_new): Use int, not short int, for argument type.
+ (fix_new_exp): Ditto.
+
+ * configure.in (arm-*-riscix*): Don't set emulations.
+
+ * config/tc-mips.c (NO_ECOFF_DEBUGGING): Define if ECOFF_DEBUGGING
+ wasn't previously defined.
+ (s_extern): Don't set ecoff_extern_size if NO_ECOFF_DEBUGGING.
+ (nopic_need_relax): Don't check it if NO_ECOFF_DEBUGGING.
+ (macro_build) [!USE_STDARG]: Don't use variadic prototype.
+ (mips_local_label) [NO_ECOFF_DEBUGGING]: Don't preserve potential
+ ECOFF debugging symbols.
+
+ * emul.h (struct emulation): Use unsigned, not unsigned char, for
+ bitfields.
+ * obj.h (struct format_ops): Likewise.
+
+ * config/tc-arm.c (symbol_make_empty) [BFD_ASSEMBLER]: Set
+ udata.p, not udata.
+
+Tue Jul 11 14:30:19 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/c-mips.texi: Document -m4010 and -mno-4010.
+
+Tue Jul 11 14:28:55 1995 Jeff Spiegel <jeffs@lsil.com>
+
+ * config/tc-mips.c (mips_4010): New static variable.
+ (interlocks): New static variable.
+ (md_begin): Check for a cpu of "r4010". Set mips_4010 correctly.
+ If mips_4650 or mips_4010, set interlocks.
+ (append_insn): Check interlocks, not mips_4650.
+ (mips_emit_delays): Likewise.
+ (mips_ip): Only permit INSN_4010 instructions if mips_4010.
+ (md_longopts): Add "m4010" and "no-m4010".
+ (md_parse_option): Accept -mcpu=r4010. Handle -m4010 and
+ -no-m4010.
+ (md_show_usage): Document -m4010 and -no-m4010.
+
+Tue Jul 11 13:22:50 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (struct efdr): Add new field fake.
+ (init_file): Initialize fake.
+ (add_file): Add new parameter fake. Change all callers.
+ (ecoff_build_debug): Don't warn about a missing .end for a fake
+ file.
+
+Mon Jul 10 16:01:31 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * doc/as.texinfo: Split out most cpu chapters...
+ * doc/c-*.texi: ...to here.
+
+ * read.c (po_hash): Now static.
+
+Mon Jul 10 13:47:22 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patches from H.J. Lu <hjl@nynexst.com>:
+ * config/tc-i386.c (md_apply_fix3): Rename from md_apply_fix1.
+ Accept pointer to value and segment. Fix OBJ_ELF PCREL case to
+ handle global defined symbols correctly.
+ (md_apply_fix): Remove both versions.
+ * config/tc-i386.h (MD_APPLY_FIX3): Define.
+
+ * configure.in: When switching on ${cpu}, use ${cpu}, not
+ $[target_cpu}, in default case.
+ * configure: Rebuild.
+
+Sat Jul 8 13:27:55 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (fixup_segment): Call resolve_symbol_value on
+ sub_symbolP, in case it isn't in the symbol table.
+
+Fri Jul 7 11:17:27 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (s_lcomm): For .lcomm 1, set align to 0, not 1.
+
+ * config/obj-coff.c (coff_frob_symbol): If SF_GET_FUNCTION, set
+ BSF_FUNCTION.
+ (symbol_globalP, symbol_global_lastP): New global variables.
+ (yank_symbols): Sort defined global symbols to the end, just
+ before the undefined symbols.
+ (glue_symbols): Add two arguments, and use them instead of
+ referring directly to global variables.
+ (crawl_symbols): Call glue_symbols twice, once for defined globals
+ and once for undefined. Add corresponding know calls.
+
+ * app.c (do_scrub_next_char): Always accept \v. Don't make it
+ conditional on BACKSLASH_V.
+ * read.c (next_char_of_string): Likewise.
+ * config/obj-bout.h (BACKSLASH_V): Don't define.
+ * config/tc-mips.h (BACKSLASH_V): Don't define.
+
+ Add SPARC ELF PIC support.
+ * write.c (fixup_segment): Pass fixP to TC_RELOC_RTSYM_LOC_FIXUP,
+ not fixP->fx_r_type.
+ * config/tc-sparc.c (sparc_pic_code): New global variable.
+ (md_apply_fix): If generating PIC, adjust fx_addnumber for any non
+ PC relative reloc.
+ (tc_gen_reloc): If generating PIC, adjust various reloc types.
+ Remove fx_pcrel assert, since it is no longer true.
+ (md_parse_option): Handle -K PIC.
+ * config/tc-sparc.h (sparc_pic_code): Declare if OBJ_ELF.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Define if OBJ_ELF.
+ (tc_fix_adjustable): Don't adjust PC relative relocs if PIC.
+ * config/tc-i386.h (TC_RELOC_RTSYM_LOC_FIXUP): Take a fixp, not a
+ reloc type.
+
+ * Makefile.in (Makefile): Add dependency on conf.in, so that conf
+ is rebuilt when conf.in changes.
+
+Thu Jul 6 16:49:38 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * All files: Updated FSF address.
+
+Thu Jul 6 16:30:34 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * ecoff.c (add_file): Don't collapse multiple .file commands into
+ a single file structure.
+ (ecoff_build_lineno): Set ilineBase to sum of previous file's
+ ilineBase and cline.
+
+Thu Jul 6 12:54:27 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ Patches from Jerry Blakely <gerry_blakley@wellfleet.com>:
+ * as.c (listing_filename): New static variable.
+ (show_usage): Mention -a=file.
+ (parse_args): Support = option of -a to set name of listing file.
+ (main): Pass listing_filename to listing_print.
+ * listing.c (list_file): New static variable.
+ (various): Replace printf with fprintf to list_file.
+ (listing_print): If name argument is not NULL, open it as
+ list_file.
+ * doc/as.texinfo, doc/as.1: Document -a=file.
+
+ * config/tc-sparc.c (s_reserve): Don't permit redefinition, even
+ if the symbol was already in bss_section. Fix warning message.
+
+ * listing.c (struct file_info_struct): Rename end_pending field to
+ at_end.
+ (file_info): Initialize at_end, not end_pending.
+ (buffer_line): If at_end set, just return immediately. Don't
+ worry about end_pending cases. Set at_end when EOF is read.
+ (print_source): Check at_end, not end_pending.
+ (listing_listing): Likewise.
+
+ * config/tc-alpha.h (alpha_do_align): Don't declare.
+ (md_do_align): Don't define.
+ (tc_frob_label): Define.
+ (alpha_define_label): Declare.
+ (md_flush_pending_output): Define.
+ (alpha_flush_pending_output): Declare.
+ * config/tc-alpha.c (insn_label): New static variable.
+ (auto_align): New static variable.
+ (md_pseudo_table): Add cases for .text, .data, .align, .byte,
+ .hword, .int, .long, .octa, .quad, .short, .word, .double, .float,
+ and .single. Change .t_floating, .s_floating, .f_floating,
+ .g_floating, and .d_floating to use s_alpha_float_cons rather than
+ float_cons.
+ (s_alpha_text, s_alpha_data): New static functions.
+ (s_rdata, s_sdata): Clear insn_label and set auto_align.
+ (s_gprel32): If auto_align, align. Clear insn_label.
+ (emit_insn): Clear insn_label.
+ (s_alpha_align): New static function.
+ (alpha_align): Make static. Take label argument.
+ (alpha_flush_pending_output): New static function.
+ (s_alpha_cons, s_alpha_float_cons): New static functions.
+ (alpha_define_label): New function.
+
+Wed Jul 5 22:49:31 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * conf.in: Regenerate with autoreconf.
+
+ Mon Jul 3 19:47:53 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.h (vms_resolve_symbol_redef): Use full prototype.
+ (vms_check_for_special_label, tc_frob_label): Move them to group
+ with other prototypes.
+ [WANT_VMS_OBJ_DEFS]: Only define the many OBJ_x, DBG_x, and DST_x
+ macros when this is defined.
+ * config/obj-vms.c: Fully prototype all local functions.
+ [symbolS, fragS]: Use consistently instead of their struct tags.
+ [WANT_VMS_OBJ_DEFS]: Define this.
+ (s_const): Make definition correctly match actual usage.
+ (VMS_stab_parse): Make `expected_type' arg be int rather than char.
+ (get_VMS_time_on_unix): Define as `static void'.
+ (hash_string): Make definition match actual usage; argument is
+ `char const *' rather than `unsigned char *'.
+ (VMS_Case_Hack_Symbol, VMS_Modify_Psect_Attributes, VMS_Psect_Spec,
+ VMS_Global_Symbol_Spec): Declare string args as `const char *'.
+ [IS_GXX_VTABLE]: New macro.
+ (vms_write_object_file: GSD loop): Use it.
+ (vms_write_object_file: data segment): Reorganize `fill' loop.
+
+Wed Jul 5 12:01:49 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c (md_shortopts): Add "K:" if OBJ_ELF.
+ (md_parse_option): If OBJ_ELF, check for -K. Die if -K PIC, since
+ PIC code is not currently supported.
+
+ * as.c (parse_args): Change std_shortopts to be an array rather
+ than a constant string. Only include 'K' if WORKING_DOT_WORD is
+ not defined. Only check for 'K' in that case as well.
+ * as.h (flag_warn_displacement): Only declare if WORKING_DOT_WORD
+ is not defined.
+
+ * conf.in: Add undef of HAVE_SBRK.
+
+ * config/obj-coff.c (obj_coff_line): Call listing_source_line, in
+ both BFD_ASSEMBLER and non BFD_ASSEMBLER versions of the function.
+
+ * symbols.c (S_SET_EXTERNAL): Warn if symbol is weak.
+ (S_CLEAR_EXTERNAL): Likewise.
+ (S_SET_WEAK): Warn if symbol is global.
+
+ * config/obj-aout.c (obj_aout_frob_symbol): Warn about an attempt
+ to put an undefined symbol into a set.
+
+ * Makefile.in: Remove @configure_input@; it's not needed in
+ files named Makefile.
+
+ * config/tc-m88k.c (md_pseudo_table): Add ".set" so that the
+ explicit pseudo-op works, while continuing to treat "set" as an
+ instruction.
+
+ * ecoff.c (ecoff_debugging_seen): New global variable.
+ (ecoff_directive_def): Set ecoff_debugging_seen.
+ (ecoff_stab): Likewise.
+ * ecoff.h: Make idempotent.
+ (ecoff_debugging_seen): Declare.
+ * config/tc-mips.c: Include ecoff.h.
+ (mips_debug): New static variable.
+ (s_stringer, s_mips_space): Remove unneeded declarations.
+ (md_parse_option): In case 'g', set mips_debug to debugging level.
+ (mips_local_label): New function.
+ * config/tc-mips.h (LOCAL_LABEL): Call mips_local_label.
+ (mips_local_label): Declare.
+
+Wed Jul 5 00:59:22 1995 Fred Fish (fnf@cygnus.com)
+
+ * as.c (main): Only use sbrk when HAVE_SBRK defined.
+ * configure.in: Add test for sbrk.
+ * configure: Regenerate using autoconf 2.4.
+
+Mon Jul 3 15:58:16 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.h (MAX_RELOC_EXPANSION): Bump to 6.
+ * config/tc-hppa.c (tc_gen_reloc, SOM version): Handle
+ relocations for the difference of two (possibly external)
+ symbols.
+ (hppa_fix_adjustable): For SOM, reject reductions involving
+ the difference of two symbols.
+ (hppa_force_relocation): Force relocations for expressions
+ involving the difference of two symbols.
+
+Mon Jul 3 14:22:59 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * configure[.in] (i386-*-win32): New host and target.
+
+Thu Jun 29 17:25:43 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ Support for long filenames non-bfd coff.
+ * config/obj-coff.c (filename_list_head, filename_list_tail): New.
+ (yank_symbols): Notice and record filenames which are too long.
+ (w_strings): Write out filename strings.
+ (c_dot_file_symbols): Put long filenames onto list.
+
+Wed Jun 28 17:33:13 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): PE doesn't use
+ the strange common symbol format that other 386s formats
+ do.
+ * config/tc-i386.c (md_begin): If LEX_AT defined then
+ '@' is in the set of identifiers.
+ (i386_operand): If LEX_AT, then don't look for @goto stuff.
+ * config/te-pe.h: Define LEX_AT.
+
+Wed Jun 28 17:49:59 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * doc/as.texinfo (H8/500 Floating Point): Indicate that IEEE FP
+ numbers are for the standard emulation code.
+ (SH Floating Point): Ditto.
+ (Overview): Describe new --emulation option for MIPS.
+ * doc/*.m4: Deleted.
+
+Thu Jun 22 19:26:25 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Sun May 7 11:53:41 MDT 1995 Bryan Ford <baford@cs.utah.edu>
+
+ * configure.in: Added i386-*-moss* target.
+
+Thu Jun 22 14:41:23 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * write.c (write_object_file): Cast decode_local_label_name
+ argument to char * to avoid warning.
+
+Wed Jun 21 18:07:59 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Changes from Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>:
+ * config/tc-m68k.c (insword): Increment the frag offsets.
+ (struct m68k_it): Add reloc[].pcrel_fix field to hold pc-rel
+ fixup.
+ (add_fix): Accept additional parameter, the pc-rel fixup. All
+ callers changed. Fix offset address if width == 'b'.
+ (m68k_ip) [case AINDX]: Allow explicit size spec. Don't make the
+ outer displacement pc-relative.
+ (md_pcrel_from): Make it relative to the first extension word of
+ the operand.
+ (opcode_ptr): Make it a macro if DO_BREAK_UP_BIG_DECL is
+ undefined.
+ (md_convert_frag_1): Don't reference fragP->fr_opcode[2..].
+ (md_estimate_size_before_relax) [case TAB (FBRANCH, SZ_UNDEF)]:
+ Turn on long bit.
+ (m68k_ip) [case 'C']: Don't set set long bit, set it in the opcode
+ table.
+ (md_estimate_size_before_relax) [case TAB (PCINDEX, SZ_UNDEF)]:
+ Variable part increases by four, not six.
+ * write.c (fixup_segment) [TC_M68K]: Don't do further pcrel
+ processing after converting difference of two symbols in the
+ same segment.
+
+ * write.c (fixup_segment): Don't conditionalize the pcrel fix on
+ TC_M68K.
+
+ * config/tc-sparc.c (sparc_ip, case 'A'): If ASI is not a "#"
+ value, don't shift it an extra time.
+
+Wed Jun 21 14:18:37 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * gasp.c (do_print, do_form, buffer_and_nest): Use case insensitive
+ string compares.
+
+Tue Jun 20 14:55:02 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/obj-coff.c (write_object_file): Cast time() argument to
+ time_t *.
+
+Tue Jun 20 12:00:53 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_build_unwind_subspace): Fix typo in last
+ change.
+
+Mon Jun 19 15:27:17 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_build_unwind_subspace): Zero out memory
+ from frag_more calls.
+
+Thu Jun 15 16:53:37 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/obj-coff.c: Don't use "bfd/" when including libbfd.h
+ and libcoff.h.
+ (fill_section): Call PROGRESS.
+ * Makefile.in (INCLUDES): Add bfd srcdir.
+
+ * mpw-config.in: Add bfd_gas flag and set for each config.
+ (i386-unknown-go32, m68k-unknown-coff): Recognize.
+ * mpw-make.in (HACK_O_RAMA, OBJ_COFF_OMIT_TIMESTAMP): Add to
+ config.h.
+
+Thu Jun 15 10:04:26 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-arm.h (LOCAL_LABEL): Prepend '.' if not OBJ_AOUT.
+ (FAKE_LABEL_NAME): Likewise.
+
+Mon Jun 12 22:25:39 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip): Check for invalid register in single
+ precision fmpyadd and fmpysub instructions.
+
+Thu Jun 8 19:33:02 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.c (myname): Delete all references.
+ (VMS_stab_parse, Write_VMS_MHD_Records, VMS_Case_Hack_Symbol):
+ Replace printf calls with as_tsktsk.
+ (PUT_LONG, PUT_SHORT): Use COPY_LONG, COPY_SHORT.
+ (VMS_Store_Immediate_Data): Move second buffer capacity check
+ below bottom of loop; first check at top suffices for loop itself.
+ (find_file): Remove redundant pointer checks in first two loops;
+ replace third loop with pointer to last list element determined
+ in first loop.
+
+Tue Jun 6 13:53:06 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-sparc.c (sparc_ip): Handle defined absolute symbols as
+ ASI values.
+
+ * config/obj-vms.c (vms_write_object_file, case N_DATA): Use
+ strcmp against FAKE_LABEL_NAME instead of checking third
+ character. (Suggested by Pat Rankin.)
+
+Mon Jun 5 20:10:46 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ Add support for N_ABS and N_ABS|N_EXT type symbols.
+
+ * config/obj-vms.h (LSY_S_M_{DEF,REL}, ENV_S_M_{DEF,NESTED}):
+ New macros for local symbols (from <lsydef.h> and <envdef.h>).
+ * config/obj-vms.c (Current_Environment): New file-scope variable.
+ (VMS_Local_Environment_Setup): New routine.
+ (GBLSYM_LCL): New macro.
+ (VMS_Global_Symbol_Spec): Handle local symbols too.
+ (VMS_Psect_Spec): Set GLOBALVALUE_BIT for absolute symbols.
+ (VMS_Emit_Globalvalues): Handle local and global absolute symbols.
+ (VMS_Store_PIC_Symbol_Reference): Ditto.
+ (vms_write_object_file: GSD symbol loop): Ditto.
+
+Mon Jun 5 16:10:40 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * config/tc-arm.h (LOCAL_LABELS_FB): Define.
+
+Mon Jun 5 02:17:58 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * configure.in (i386-*-gnu*): Always use GNU ELF config.
+
+Wed May 31 17:49:18 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.c (obj_crawl_symbol_chain): Update *symbolPP
+ in `else' clause when removing a symbol. Also, revise comments
+ to match the code.
+ (vms_write_object_file (GSD symbol loop, case N_DATA)): Never
+ output symbol definitions for local numeric labels.
+
+Tue May 30 18:29:10 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * configure.in (architecture variants, cases armeb and arm*): Remove
+ spaces round assignment to endian.
+
+Tue May 30 12:31:31 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * write.c (write_object_file): Check for undefined local dollar
+ and fb labels.
+
+ * symbols.c (decode_local_label_name): Extract instance number
+ from the correct location.
+
+Sat May 27 21:28:49 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/te-dpx2.h: Include obj-format.h.
+ (COFF_MAGIC): Renamed from FILE_HEADER_MAGIC.
+
+Wed May 24 13:45:32 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * configure, configure.in, config/obj-coff.c, config/obj-coff.h:
+ Add support for ARM pe
+
+Tue May 23 17:00:32 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-sparc.c (tc_gen_reloc): Handle BFD_RELOC_SPARC_WDISP16
+ and BFD_RELOC_SPARC_WDISP19.
+
+Tue May 23 19:18:33 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * as.c (parse_args) [! USE_EMULATIONS]: Always print an error
+ message.
+
+ * doc/internals.texi: Document obj_app_file and
+ TARGET_BYTES_BIG_ENDIAN.
+
+Mon May 22 20:03:23 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * ecoff.c (ecoff_stab): Add extra leading argument, for 4 May
+ change.
+ * ecoff.h (ecoff_stab): Fix declaration.
+ * obj.h (format_ops.process_stab): Include prototype.
+ * config/obj-elf.h (OBJ_PROCESS_STAB): Pass through seg argument.
+ * config/obj-ecoff.h (OBJ_PROCESS_STAB): Ditto.
+
+ * config/e-mipself.c (mipself): New emulation mode, doesn't change
+ endianness from configured default.
+ * config/e-mipsecoff.c (mipsecoff): Ditto.
+ * configure.in (mips ecoff/elf targets): Include them.
+ * as.c (mipself, mipsecoff): Declare.
+
+ * as.c (emulation_name): New variable.
+ (select_emulation_mode): Set emulation_name. Don't change argv.
+ (parse_args): Handle --emulation; complain if the supplied name
+ isn't what select_emulation_name came up with.
+
+Sun May 21 21:36:17 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: Reverse changes from Dec. 19th which
+ changed the way unwinds were built for ELF. Rely on relocation
+ symbol reductions to avoid placing the end of function marker
+ symbols into the object file's symbol table.
+
+Sat May 20 12:31:36 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ Added improved VMS support from Pat Rankin:
+
+ Fri 19 May 16:51:40 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.h (AOUT_STABS): Define.
+
+ * config/obj-vms.c (fpush, rpush): New routines.
+ (push): Replaced by the above.
+ (find_symbol): Slight reorganization to expose tail recursion.
+
+ Fri Mar 17 18:40:36 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * Makefile.in (VMS_OTHER_OBJS): delete this.
+ * vmsconf.sh (make-gas.com): build ../libiberty/liberty.olb
+ first if necessary; link gas against it.
+
+Fri May 19 16:37:39 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * gasp.c (istrue): Correctly test for string inequality.
+
+Thu May 18 04:25:11 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ Wed May 10 14:28:16 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * config/tc-arm.c (CP_T_{Pre,UD,WB}): Define, bits in co-processor
+ instructions.
+ ([ls]fm_flags): Correct error in bitmasks.
+ (cp_address_required_here): Delete second parameter, FLAGS. All
+ callers changed. Remove all dead code referring to FLAGS. If
+ address is just "[Reg]" then convert into a PRE-INCREMENT UP format.
+ (do_fp_ldmstm): Handle full-descending and empty-ascending stack
+ formats explicitly.
+
+ * config/tc-arm.c (internalError): Define.
+ (ARM_{1,2,250,3,6,7,7DM,ANY,2UP,ALL,3UP,6UP,LONGMUL}): Define processor
+ variants.
+ (FPU_{CORE,FPA10,FPA11,NONE,ALL,MEMMULTI}): Define floating point
+ variants.
+ ({CPU,FPU}_DEFAULT): Define.
+ (cpu_variant): New variable.
+ (asm_flg): Change more_flags to flag_bits.
+ Add prototypes for new functions.
+ (FLAG_{S,P,B,T,ED,FD,FA,EA,IB,IA,DB,DA,L}): Delete.
+ (s_flag[], ldst_flags[], byte_flag[], cmp_flags[], ldm_flags[],
+ stm_flags[], lfm_flags[], sfm_flags[], round_flags[], except_flags[],
+ cplong_flag[]): New variables.
+ (asm_opcode, insns[]): New format, add version support.
+ (arm_flg_hsh): Delete.
+ (do_mul, do_mla): Remove "Warning" from warning messages.
+ (do_arit): Simplify.
+ (do_swap): Make error message more appropriate.
+ (md_begin): Build hash tables starting at first entry in tables.
+ (md_number_to_chars): Cope with big/little-endian selection.
+ (md_chars_to_number): New function.
+ (md_apply_fix): Rewrite to make endian independent.
+ (tc_gen_reloc): Better error messages.
+ (md_assemble): Reject opcodes forbidden by the currently selected cpu
+ variant. Rewrite handling code for instruction flags.
+ (md_shortopts): Add option "m:".
+ (md_parse_option): Get the desired cpu/fpu variant.
+
+ From: David Taylor (dtaylor@armltd.co.uk)
+ * configure.in (architecture variants): Check for "armeb" and "arm*",
+ set endianness accordingly.
+ * read.c (read_a_source_file): New hooks md_start_line_hook and
+ md_after_pass_hook.
+ * config/arm-{big,lit}.mt: New files
+ * config/tc-arm.h ({LITTLE,BIG}_ENDIAN, BYTE_ORDER): Define.
+ (TARGET_FORMAT): Select depending on endianness and emulation and
+ object format.
+ (md_after_pass_hook, md_start_line_hook): Define.
+ * config/tc-arm.c: Include subsegs.h, symbols.h and listing.h.
+ (shift[]): Add uppper case equivalents.
+ (CP_T_[XY], TRANS_BIT): Define.
+ (conds[]): Delete initial NULL entry, add "lo" entry as synonym for
+ "cc".
+ (LONGEST_FLAG, flags[]): Delete.
+ (arm_psr): New structure.
+ (psrs[]): New variable.
+ (PSR_ALL): Define.
+ (LONGEST_INST): Bump to 5.
+ (LITERAL_MASK, COND_MASK, OPCODE_MASK, DATA_OP_SHIFT): Define.
+ (OPCODE_{AND,EOR,SUB,RSB,ADD,ADC,SBC,RSC,TST,TEQ,CMP,CMN,ORR,MOV,BIC,
+ MVN}): Define.
+ (insns[]): Add smull, umull, smlal, umlal, ldfm, stfm, msr and mrs
+ instructions. Add nop and adr pseudo ops.
+ (reg_table): Add APCS register name variants.
+ (arm_psr_hsh): New hash table.
+ (md_pseudo_table): Add "ltorg", "pool", "extend", "ldouble" and
+ "packed".
+ (MAX_LITERAL_POOL_SIZE): Define.
+ (struct literalS): New structure.
+ (literals, next_literal_pool_place, lit_pool_num, current_poolP): New
+ variables.
+ (add_to_lit_pool, symbol_locate, symbol_make_empty): New functions.
+ (validate_immediate): Return FAIL on failure.
+ (s_ltorg): New function.
+ (psr_required_here, psrf_required_here): New functions.
+ (cp_address_required_here): New parameter, flag, all callers changed.
+ If flag is non-zero, restrict the legal addressing modes.
+ (do_nop, do_mrs, do_msr, do_mull): New functions.
+ (negate_data_op): New function.
+ (data_op2): accept #x,y meaning x rotated right by y, but only when
+ suitable constants. If immediate is not legal, try changing the
+ opcode.
+ (do_adr): New function.
+ (do_ldst): accept "ldr reg, =expr". Put expr in the pool if it can't
+ be done as an immediate.
+ (do_fp_ldst): Use CP_T_[XY], not immediate values.
+ (do_fp_ldmstm): New function.
+ (arm_psr_parse): New function.
+ (output_inst): Use INSN_SIZE in call to md_number_to_chars.
+ (md_assemble): Add hack so that "Label instruction" causes alignment of
+ the label.
+ (arm_after_pass_hook, arm_start_line_hook, arm_frob_symbol): New
+ functions.
+
+Wed May 17 05:25:16 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (md_show_usage): Add \'s at end of lines in
+ strings for non-GCC compilers.
+
+Tue May 16 19:36:00 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/obj-ecoff.c (ecoff_pop_insert): New function.
+ (ecoff_format_ops): Use it.
+ (obj_ecoff_frob_symbol): Now static.
+
+Wed May 17 00:59:12 1995 Andrew Cagney - aka Noid <cagney@highland.com.au>
+
+ * config/tc-ppc.c (md_begin): Was assuming that an instruction was
+ bigendian and hence 16bit relocs withing instructions would
+ ALWAYS be at addresses i+2-i+3. In LE mode it is i+0-i+1.
+
+Tue May 16 16:29:58 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/obj-multi.h (obj_frob_symbol, obj_frob_file, S_GET_SIZE,
+ S_SET_SIZE, S_GET_ALIGN, S_SET_ALIGN, obj_copy_symbol_attributes,
+ OBJ_PROCESS_STAB): New macros.
+ * config/tc-mips.c: Protect against redefining them also when
+ including obj-elf.h. Test only OBJ_ELF for including elf/mips.h.
+ (mips_init_after_args): New function. Set byte_order here.
+ (md_parse_option): Not here.
+ (byte_order): Don't bother initializing.
+ * config/tc-mips.h (mips_init_after_args): Declare.
+ (tc_init_after_args): New macro.
+
+ * read.c (s_lcomm): Do ELF/ECOFF test at run time, not compile
+ time.
+
+Fri May 12 14:17:47 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ Initial support for PE object files.
+ * configure.in, configure (i386-*-pe, i386-*-*nt): Add.
+ * config/obj-coff.c (fixup_segment): Cope with PE wierdness.
+ * config/obj-coff.h (TE_PE): New target format.
+
+Thu May 11 14:58:21 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/obj-elf.c (NEED_ECOFF_DEBUG): Define if ECOFF_DEBUGGING
+ was defined by header files. Test in preprocessor conditionals
+ instead of ECOFF_DEBUGGING.
+ (ecoff_debug_pseudo_table): Make empty if NEED_ECOFF_DEBUG is not
+ defined.
+ (obj_read_begin_hook, obj_symbol_new_hook, elf_frob_symbol,
+ elf_frob_file): Only call ecoff routines if NEED_ECOFF_DEBUG is
+ defined.
+ (elf_ecoff_set_ext, elf_get_extr, elf_set_index): Define only if
+ NEED_ECOFF_DEBUG is defined.
+ (elf_format_ops): Reference elf_ecoff_set_ext only if
+ NEED_ECOFF_DEBUG.
+
+Wed May 10 18:09:12 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (OBJS): Include @extra_objects@.
+ (obj-elf.o, obj-ecoff.o, e-mipself.o, e-mipsecoff.o): New rules
+ for building these independently.
+ * emul-target.h, config/e-mipself.c, config/e-mipsecoff.c: New
+ files.
+
+ * acconfig.h (DEFAULT_EMULATION, EMULATIONS, USE_EMULATIONS,
+ OBJ_MAYBE_*, I386COFF, M68KCOFF, M88KCOFF): New macros.
+ * aclocal.m4 (GAS_UNIQ): New macro.
+
+ * as.c (emulations, n_emulations) [USE_EMULATIONS]: New variable.
+ (select_emulation_mode, default_emul_bfd_name, common_emul_init)
+ [USE_EMULATIONS]: New functions.
+ (main) [USE_EMULATIONS]: Call select_emulation_mode before other
+ initialization.
+ * emul.h: New file.
+ * as.h [USE_EMULATIONS]: Include it.
+
+ * configure.in: Handle enable-targets option. Iterate over target
+ list, building up a list of object file formats and emulation
+ configurations. (Only supports emulations for MIPS CPU so far.)
+ If multiple formats are needed, set obj_format to multi and add
+ format config files to extra_files. If emulation modes are
+ needed, add the relevant files to extra_files.
+
+ * configure.in: Define I386COFF, M68KCOFF, M88KCOFF for those
+ configurations.
+
+ * ecoff.c (ecoff_generate_asm_lineno): Filename argument now
+ points to const.
+ * ecoff.h (ecoff_generate_asm_lineno): Updated declaration.
+
+ * obj.h (obj_read_begin_hook): Don't declare function if it's
+ already a macro.
+
+ * read.c (s_space, cons, stringer): If md_flush_pending_output is
+ defined, call it on entry.
+ * config/obj-elf.c (obj_elf_section): If md_flush_pending_output
+ is defined, call it on entry. If md_elf_section_change_hook is
+ defined, call it before returning normally.
+
+ * read.h (target_big_endian): Declare.
+
+ * obj.h (struct format_ops): Added new function pointer fields
+ ecoff_set_ext, read_begin_hook, symbol_new_hook.
+ (ecoff_format_ops, elf_format_ops): Declare.
+ * config/obj-elf.c (elf_s_get_size, elf_s_set_size,
+ elf_s_get_align, elf_s_set_align, elf_copy_symbol_attributes,
+ elf_sec_sym_ok_for_reloc): New functions.
+ (elf_format_ops): New variable.
+ (elf_frob_symbol): Now takes additional int* argument.
+ * config/obj-elf.h (elf_frob_symbol): Update declaration.
+ (elf_pop_insert): Declare.
+ (obj_pop_insert): Define to call elf_pop_insert.
+ * config/obj-ecoff.c (ecoff_sec_sym_ok_for_reloc,
+ obj_ecoff_frob_symbol): New functions.
+ (ecoff_format_ops): New variable.
+
+ * config/te-generic.h: If OBJ_HEADER is defined, use it as the
+ filename to include in place of obj-format.h.
+ * config/te-multi.h: New file, copied from te-generic.h.
+ * config/obj-elf.c (OBJ_HEADER): Define it to "obj-elf.h".
+ * config/obj-ecoff.c (OBJ_HEADER): Define it to "obj-ecoff.h".
+
+ * config/obj-elf.c (ECOFF_DEBUGGING): Default to 0.
+ (obj_read_begin_hook, obj_symbol_new_hook, elf_frob_symbol,
+ elf_frob_file): Test it at run time.
+ (obj_ecoff_set_ext, elf_get_extr, elf_set_index): Define
+ unconditionally.
+ (elf_pseudo_table): Renamed from obj_pseudo_table, now static.
+ (ecoff_debug_pseudo_table): Split off into separate table. Define
+ it unconditionally.
+ (elf_pop_insert): New function.
+ * config/obj-elf.h (elf_pop_insert): Declare.
+ (obj_pop_insert): New macro.
+ (obj_ecoff_set_ext) [!OBJ_MAYBE_ELF]: Define to elf_ecoff_set_ext.
+ * config/obj-ecoff.h (obj_ecoff_set_ext): Define to ecoff_set_ext.
+
+ * config/tc-mips.h: Protect against multiple inclusions.
+ (mips_pop_insert): Declare.
+ (md_pop_insert): Call it.
+
+ * config/tc-mips.c: If OBJ_MAYBE_ELF is defined, include
+ obj-elf.h, but preserve OUTPUT_FLAVOR and protect some other
+ macros from redefinition.
+ (ECOFF_DEBUGGING): Default to 0. All references changed to
+ run-time tests or made unconditional.
+ (s_stringer, s_mips_space, s_elf_section): Deleted.
+ (md_pseudo_table): Don't refer to them. Split table into three
+ sections, for MIPS, non-ECOFF_DEBUGGING, and ELF.
+ (mips_pop_insert): New function.
+ (mips_flush_pending_output): New function.
+ (mips_enable_auto_align): New function.
+ * config/tc-mips.h (mips_pop_insert): Declare.
+ (md_pop_insert): New macro.
+ (mips_flush_pending_output): Declare.
+ (md_flush_pending_output): New macro.
+ (mips_enable_auto_align): Declare.
+ (md_elf_section_change_hook): New macro, calls
+ mips_enable_auto_align.
+
+Tue May 9 17:07:41 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in: Add little endian PowerPC support.
+ * configure: Rebuild with autoconf.
+ * config/ppc-big.mt: New file for big endian PowerPC systems.
+ * config/ppc-lit.mt: New file for little endian PowerPC systems.
+
+ * config/tc-ppc.h (target_big_endian): Declare.
+ (TARGET_FORMAT): Deal with little and big endian ELF variants.
+ (TARGET_BYTES_BIG_ENDIAN): Define as 1, not empty.
+
+ * config/tc-ppc.c (ppc_big_endian): Delete variable, use
+ target_big_endian instead.
+ (md_parse_option): Parse -mlittle and -mlittle-endian to use
+ little endian support. Parse -mbig and -mbig-endian to use big
+ endian support.
+ (md_show_usage): Update to reflect current switches.
+ (ppc_set_cpu): Recognize powerpcle as little endian PowerPC. Use
+ as_fatal, not abort if unknown machine.
+
+Tue May 9 10:58:41 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): Cast *valp to an integer when
+ comparing against signed values.
+ (hppa_force_relocation): Make "distance" an integer.
+
+Tue May 9 00:47:03 1995 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * obj.h (struct format_ops) [BFD_ASSEMBLER]: New type.
+ (this_format) [BFD_ASSEMBLER]: Declare new variable, if not
+ already defined as a macro.
+
+Mon May 8 21:44:13 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * subsegs.h (seg_info): Provide dummy version for
+ non-BFD_ASSEMBLER, non-MANY_SEGMENTS configuration. It should
+ never get invoked, but this is easier than conditionalizing some
+ of the uses.
+ (struct seg_info_trash): Dummy type used by above to make code
+ compile.
+
+Fri May 5 14:47:13 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/obj-coff.h (SEPARATE_STAB_SECTIONS): Define to 1, not
+ empty.
+ * config/obj-elf.h (SEPARATE_STAB_SECTIONS): Ditto.
+ * config/obj-som.h (SEPARATE_STAB_SECTIONS): Ditto.
+
+Thu May 4 19:26:55 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * stabs.c (get_stab_string_offset): Always define. If
+ SEPARATE_STAB_SECTIONS isn't set, abort.
+ (SEPARATE_STAB_SECTIONS): Default to zero.
+ (aout_process_stab): New function, split out from s_stab_generic.
+ (OBJ_PROCESS_STAB) [AOUT_STABS]: Define to call aout_process_stab,
+ if not already defined.
+ (s_stab_generic): Test SEPARATE_STAB_SECTIONS at run time. If
+ it's not set, and OBJ_PROCESS_STAB isn't defined, abort. Always
+ pass six arguments to OBJ_PROCESS_STAB.
+ * read.h (get_stab_string_offset): Declare unconditionally.
+ * config/obj-aout.h (AOUT_STABS): Define.
+ * config/obj-bout.h (AOUT_STABS): Define.
+ * config/obj-ecoff.h (OBJ_PROCESS_STAB): Add new first argument,
+ ignored.
+ * config/obj-elf.h (OBJ_PROCESS_STAB) [ECOFF_DEBUGGING]: Ditto.
+
+ * config/obj-ecoff.h (ECOFF_DEBUGGING): Define to 1, not empty.
+ * config/obj-elf.h (ECOFF_DEBUGGING): Ditto. Test value, not
+ whether it's defined.
+
+Wed May 3 21:38:20 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * as.h (LOCAL_LABELS_DOLLAR, LOCAL_LABELS_FB): If not already
+ defined, define them to zero.
+ * config/tc-*.h, config/te-*.h: If defining them, define them to
+ be 1 instead of empty.
+ * expr.c (integer_constant, operand): Test them at run time
+ instead of compile time.
+ * read.c (read_a_source_file): Ditto.
+ * symbols.c (colon): Ditto.
+ (dollar_*, define_dollar_label, fb_*): Define unconditionally.
+ * symbols.h (dollar_*, define_dollar_label, fb_*): Declare
+ unconditionally.
+
+Wed May 3 13:08:53 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): Do nothing for an out of range
+ PC relative call since those only occur in cases where the linker
+ can fix them up.
+ (hppa_force_relocation): Force relocations for out of range PC
+ relative calls.
+
+Tue May 2 16:34:47 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * configure (hppa*-*-lites*): Handle just like hppa*-*-*elf*.
+ * configure.in: Likewise.
+
+Tue May 2 11:22:00 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * read.c (pop_insert): New function.
+ (pop_override_ok, pop_table_name): New variables.
+ (md_pop_insert, obj_pop_insert): New macros.
+ (pobegin): Use them.
+
+ * config/tc-mips.c: Use USE_STDARG and USE_VARARGS instead of
+ NO_STDARG &c.
+
+ * read.c (target_big_endian): If TARGET_BYTES_BIG_ENDIAN is
+ defined, initialize to 1.
+ * config/tc-mips.c (mips_target_format): Changed to a function,
+ checking flavor and byte order at run time.
+ (md_parse_option, cases OPTION_EB and OPTION_EL): Set
+ target_big_endian here.
+ (md_begin): Not here.
+ * config/tc-mips.h (mips_target_format): Adjust declaration.
+ (TARGET_FORMAT): Call mips_target_format.
+
+ * config/tc-mips.h (USE_GLOBAL_POINTER_OPT): Define in terms of
+ OUTPUT_FLAVOR.
+ * config/tc-mips.c (g_switch_value, g_switch_seen): Define
+ unconditionally.
+ (md_begin, mips_ip, md_parse_option, s_change_sec, s_option,
+ s_abicalls, nopic_need_relax): Check USE_GLOBAL_POINTER_OPT at run
+ time, instead of compiling conditionally on GPOPT.
+ (GPOPT): Don't define.
+ (md_shortopts): Always include -G.
+ (RDATA_SECTION_NAME): Select at run time.
+ (md_begin): Test for ELF format at run time instead of compile time.
+ (mips_ip, s_change_sec): Ditto.
+ (md_parse_option, cases OPTION_CALL_SHARED and OPTION_NON_SHARED):
+ Ditto.
+ (OPTION_CALL_SHARED, OPTION_NON_SHARED, mips_regmask_frag): Define
+ unconditionally.
+
+Tue May 2 00:17:04 1995 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * Makefile.in (TARG_CPU_DEP_*): New variables.
+ (targ-cpu.o): Depend on one, selected by autoconf substitution,
+ instead of TARG_CPU_DEPENDENTS.
+ * configure.in: Substitute $cpu_type, $obj_format, $atof, and
+ $emulation into Makefile.in.
+ * config/h8300.mt: Deleted.
+ * config/h8500.mt: Deleted.
+ * config/i386coff.mt (TARG_CPU_DEPENDENTS): Deleted.
+ * config/m68k.mt: Deleted.
+ * config/m68kcoff.mt (TARG_CPU_DEPENDENTS): Deleted.
+ * config/m88kcoff.mt (TARG_CPU_DEPENDENTS): Deleted.
+ * config/mips-big.mt (TARG_CPU_DEPENDENTS): Deleted.
+ * config/mips-lit.mt (TARG_CPU_DEPENDENTS): Deleted.
+ * config/sh.mt: Deleted.
+ * config/w65.mt: Deleted.
+ * config/z8k.mt: Deleted.
+
+ * config/te-dpx2.h (dpx2): Deleted unused macro.
+ * config/te-generic.h (TE_GENERIC): Ditto.
+ * config/te-go32.h (TE_GO32): Ditto.
+ * config/te-hp300.h (TE_HP300): Ditto.
+ * config/te-hppa.h (PA, _TE_PA_H): Ditto.
+ * config/te-ic960.h (TE_IC960): Ditto.
+ * config/te-nbsd532.h (TE_NETBSD532): Ditto.
+ * config/te-pc532mach.h (TE_PC532MACH): Ditto.
+ * config/te-ppcnw.h (TE_PPCNW): Ditto.
+ * config/te-sco386.h (scounix): Ditto.
+
+Mon May 1 15:59:56 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * read.c (s_app_file): If obj_app_file is defined, call it with
+ string as argument. Don't call c_dot_file_symbol or
+ elf_file_symbol.
+ * config/obj-coff.h (obj_app_file): Define as c_dot_file_symbol.
+ * config/obj-elf.h (obj_app_file): Define as elf_file_symbol.
+
+ * as.h (OUTPUT_FLAVOR): Don't define here.
+ * config/obj-aout.h (OUTPUT_FLAVOR) [BFD_ASSEMBLER]: Define.
+ * config/obj-bout.h (OUTPUT_FLAVOR): Define.
+ * config/obj-coff.h (OUTPUT_FLAVOR) [BFD_ASSEMBLER]: Define.
+ * config/obj-ecoff.h (OUTPUT_FLAVOR): Define.
+ * config/obj-elf.h (OUTPUT_FLAVOR): Define.
+
+Thu Apr 27 20:07:33 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (RUNTEST): Use one in srcdir if present.
+ (RUNTESTFLAGS): Define.
+
+Wed Apr 26 15:54:10 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Support for more portable alignment handling in assembly code,
+ based on patches from Bryan Ford <baford@schirf.cs.utah.edu>:
+ * read.c (potable): Added balign and p2align, for aligning by
+ bytes or powers of two independent of what ".align" does for a
+ given target.
+ * doc/as.texinfo: Document them.
+
+Tue Apr 25 11:12:04 1995 Rob Savoye <rob@thepub.cygnus.com>
+
+ * configure, configure.in: Look for m68k-*-vxworks* rather than
+ just m68k-wrs-vxworks so gas can be configured for
+ m68k-vxworks5.1.
+
+Fri Apr 21 15:19:06 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-sh.c (md_apply_fix): If fx_r_type is zero, handle
+ fx_size of 1, and abort on unrecognized sizes.
+
+ * config/tc-m68k.c (m68k_ip): Fix bug in last change regarding
+ non-isvar case.
+
+Sun Apr 16 01:52:52 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * config/tc-m68k.h (md_relax_table, TC_GENERIC_RELAX_TABLE):
+ Missed this one in 11 Apr changes.
+
+ * config/tc-i386.h (TC_GENERIC_RELAX_TABLE): Fix typo.
+
+Thu Apr 13 18:18:08 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-sh.c (md_convert_frag): Instead of aborting on large
+ displacements, print an error message. Don't invoke the code that
+ followed the abort call until it's been verified.
+
+ * config/tc-m68k.c (md_show_usage): Add 68060 to list. Split cpu
+ list into three lines.
+
+Thu Apr 13 14:34:36 1995 Torbjorn Granlund <tege@adder.cygnus.com>
+
+ * config/tc-m68k.c (m68k_init_after_args): Test for m68360.
+ (md_parse_option): Likewise.
+ (md_show_usage): Mention m68360.
+ * config/tc-m68k.h (TARGET_WORD_SIZE): Define.
+ (TARGET_ARCH): Define.
+
+ * expr.c (integer_constant): If TARGET_WORD_SIZE is defined,
+ sign-extend appropriately.
+
+Thu Apr 13 11:20:17 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_validate_fix): Properly use PARAMS to
+ hide prototype from non-ANSI compilers, and don't use ANSI syntax
+ for arguments.
+
+Wed Apr 12 12:20:19 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in (TDEFINES): Put empty definition into
+ makefile fragment.
+ * mpw-make.in (xmalloc.c.o): Remove.
+ (as.new): Depend on Version.r.
+ (Version.r): Generate from version info.
+
+ * mpw-make.in: Delete references to hex-value.c.
+
+ * mpw-config.in: Add mapping from configs to object file formats,
+ get VERSION from Makefile.in and add to mk.tmp.
+ (mips-idt-ecoff) [TDEFINES]: Add TARGET_BYTES_BIG_ENDIAN.
+ * mpw-make.in (VERSION, gC): Don't define.
+ (ALL_CFLAGS): Remove -d flags.
+ (config.h): Remove definition of MPW, add HAVE_STDARG_H,
+ BFD_ASSEMBLER.
+
+ * mpw-make.in (ALL_CFLAGS): Add definition of HAVE_STDARG_H,
+ include of ::libiberty:.
+ (config.h): Ifdef contents on GAS_VERSION.
+
+ * mpw-make.in (as.c): Compile with C not gC.
+ (config-stamp): Touch correctly.
+ (install-only): New target.
+ (install): Depend on all and install-only.
+
+ * mpw-config.in: Parse target and use to generate forward includes
+ to tc-, obj-, and atof- files, use te-generic.h for emulation.
+ * mpw-make.in (VERSION): Define.
+ (as.c): Compile with GCC.
+ (TARG_OBJECTS, CLIBS): Define.
+ (as.new): Use LDFLAGS, TARG_OBJECTS, CLIBS and EXTRALIBS in link
+ command.
+ (config.h, config-stamp): Build.
+
+ * mpw-make.in (C, CFLAGS): Removed definitions.
+ (ALL_CFLAGS): Define.
+ Set default rule to use {CC} instead of {C}.
+
+ * mpw-make.in (install): Moved here from mpw-build.in.
+ * mpw-build.in: Removed, functionality in mpw-make.in
+
+ * mpw-make.in (CFLAGS): Add more include paths.
+
+ * mpw-config.in (varargs.h, sys/*.h): Don't create when
+ configuring.
+ * mpw-make.in (CFLAGS): Add -w flag.
+
+ * mpw-make.in: Replace 8-bit chars with their names.
+
+ * mpw-config.in: New file, MPW version of configure.in.
+ * mpw-make.in: New file, MPW version of Makefile.in.
+
+Tue Apr 11 01:42:36 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * configure.in: Require at least autoconf 2.3, because earlier
+ versions lose on some AIX versions.
+ * configure: Regenerated.
+
+ * configure.in: Add m68k-*-elf.
+ * config/tc-m68k.c (comment_chars) [OBJ_ELF]: Include '#'.
+ (md_pseudo_table) [OBJ_ELF]: Ignore "swbeg".
+ (md_begin): Set alt_notend_table['&'], so svr4-style immediate
+ operands are accepted.
+ (md_apply_fix): Argument VALP should point to valueT.
+ (md_convert_frag): Argument SEC should be type segT.
+ (md_shortopts) [OBJ_ELF]: Accept 'Q' with an argument.
+ (md_parse_option): Ignore it.
+ (md_convert_frag_1): Add in frag address for the symbol in the
+ displacement calculation.
+ * config/tc-m68k.h (TARGET_FORMAT) [OBJ_ELF]: Use "elf32-m68k".
+ (TARGET_ARCH): Define.
+ (REGISTER_PREFIX_OPTIONAL) [OBJ_ELF]: Default to 0.
+ (LOCAL_LABEL, FAKE_LABEL_NAME, REGISTER_PREFIX_OPTIONAL): Handle
+ these the same way for OBJ_ELF as for M68KCOFF.
+
+ * gdbinit.in: Add breakpoint in as_abort.
+
+ * write.c (cvt_frag_to_fill): If offset is less than zero,
+ complain about it specifically, instead of reporting an assertion
+ failure.
+ (relax_segment): Complain about .org backwards, then ignore it.
+ Do generic rs_machine_dependent relaxation only if
+ TC_GENERIC_RELAX_TABLE is defined, and use its value for the base
+ of the table.
+ * tc.h (md_relax_table): Delete declaration.
+ * as.h (struct relax_type): Add forward declaration for type.
+ * config/tc-a29k.c: Deleted md_relax_table.
+ * config/tc-{alpha,arm,h8300,hppa,i860,m88k,mips,ppc,sparc,z8k}.c:
+ Ditto.
+ * config/tc-{h8500,i386,i960,ns32k,sh,tahoe,vax,w65}.h: Declare
+ md_relax_table here, and define TC_GENERIC_RELAX_TABLE to expand
+ to md_relax_table.
+ * config/tc-h8500.c (md_relax_table): No longer const.
+ * config/tc-w65.c (md_relax_table): Ditto.
+ * config/tc-sparc.c (md_short_jump_size, md_long_jump_size):
+ Deleted.
+ * doc/internals.texi: Describe TC_GENERIC_RELAX_TABLE and
+ WORKING_DOT_WORD. Mention md_*_jump_size (but description needs
+ to be fleshed out later). Note m68k PCINDEX mode has been checked
+ in.
+
+Mon Apr 10 15:57:42 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-mips.c (nopic_need_relax): New static function, split
+ out from md_estimate_size_before_relax.
+ (md_estimate_size_before_relax): Call it.
+ (load_address, macro): In NO_PIC branches, if nopic_need_relax
+ returns nonzero, don't attempt GP optimization.
+
+ * config/tc-m68k.c (PCINDEX): New macro.
+ (md_relax_table): No longer const. Add PCINDEX entries.
+ (m68k_ip): For AINDX with simple symbol operand, generate a
+ PCINDEX frag if PC is used, or do normal non-AINDX processing for
+ address register.
+ (m68k_init_after_args): If cpu is 68000 or 68010, fix
+ md_relax_table to prevent relaxation of PCINDEX/BYTE mode to
+ SHORT, since they don't support that mode.
+ (md_convert_frag_1, case PCLEA/LONG): Add 4 to offset, not 2. Add
+ support for new PCINDEX modes.
+ (md_estimate_size_before_relax): Process PCINDEX/SZ_UNDEF mode.
+
+ * config/tc-m68k.c (md_convert_frag_1, case PCLEA/SHORT): Add 2 to
+ offset.
+ (m68k_ip, case most punctuation/AOFF): If using PC, call add_frag
+ using PCLEA.
+
+ * config/tc-m68k.c: Don't explicitly include config.h. Deleted a
+ bunch of "#if 0" code and useless comments.
+ (struct m68k_cpu): New type.
+ (archs, n_archs): New variables, with single list of name/enum
+ mapping and aliases.
+ (m68k_ip): Delete the table here.
+ (m68k_init_after_args): Use the new table here instead of
+ open-coding it.
+ (md_parse_option, case 'm'): Ditto.
+
+ * doc/Makefile.in (Makefile): Fix rule for running config.status.
+ (internals.dvi, internals.ps, internals.ps4): New targets, not
+ built by default.
+
+ * doc/internals.texi: Add loud disclaimer. Refill to 79 columns,
+ specify fill-column in local-variables section. Change
+ subheadings to subsections so they can be cross-referenced.
+ Describe broken words, frags, frag chains, generic relaxation,
+ relax table, m68k relaxation, m68k addressing modes, test suite
+ code. Add a few words about various file formats.
+
+ * doc/as.texinfo (m68k): Recommend using `%' with registers as the
+ normal case, instead of the exceptional case.
+
+Thu Mar 30 14:38:47 1995 H.J. Lu (hjl@nynexst.com)
+
+ * configure.in: Change linux to default to elf. Using
+ i[345]86-*-linuxaout will defaults to a.out.
+ * configure: Rebuild.
+
+Wed Mar 29 17:16:30 1995 Torbjorn Granlund <tege@adder.cygnus.com>
+
+ * config/tc-m68k.c (md_apply_fix_2): Cast negative offsets to offsetT
+ (for hosting on 64 bit machines).
+
+Tue Mar 21 16:53:27 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_show_usage): Mention -mips4 and -m4650.
+
+Fri Mar 17 16:47:13 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * write.c (write_object_file): Add PROGRESS macros.
+
+Fri Mar 17 12:40:34 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_comm): Make sure to always reset the frag
+ and section for common symbols.
+
+Thu Mar 16 17:26:18 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_validate_fix): Allow non PC relative
+ pointers in the .ctors and .dtors section also when using the
+ -mrelocatable option.
+ (md_parse_option): Support -m403 as a PowerPC computer.
+ (md_show_usage): Ditto.
+
+Wed Mar 15 14:45:42 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (ecoff_build_debug): The cur_scope field of a fil_ptr
+ may be NULL when given strange input. Don't core dump.
+
+Tue Mar 14 21:36:34 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (load_register): Don't use addiu for dli of an
+ unsigned seemingly negative number. Don't bother shifting a zero
+ value.
+ (mips_ip): For case 'j', if there are more alternatives, and the
+ ISA level is at least 3, don't accept an unsigned seemingly
+ negative number.
+
+Tue Mar 14 19:16:43 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * read.c (s_app_line): Fix last patch to deal with a line number
+ of 1.
+
+Tue Mar 14 17:00:57 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_validate_fix): Use as_warn_where, not
+ as_bad_where to give a warning instead of an error.
+
+Mon Mar 13 17:03:46 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/tc-vax.c (md_assemble): issue a warning if a constant
+ is used as an operand where an immediate value is not allowed.
+
+Fri Mar 10 19:21:19 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/obj-coff.c: Redo my 10 Jan change, but get it right this
+ time. :-)
+ (fixup_segment): If linkrelax is set, just return.
+ (write_object_file): Don't treat h8300 and z8k specially with
+ regard to fixups.
+ * config/tc-h8300.c (md_begin): Set linkrelax.
+ * config/tc-z8k.c (md_begin): Ditto.
+
+Thu Mar 9 18:01:37 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (coff_header_append): Check return value of
+ bfd_coff_swap_scnhdr_out.
+
+Thu Mar 9 13:51:30 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ Delete this patch, it breaks the h8300 assembler.
+ Tue Jan 10 13:34:14 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+ * config/obj-coff.c (write_object_file): Don't treat h8300 and z8k
+ specially with regard to fixups.
+
+Thu Mar 9 12:28:18 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (mrelocatable): Change type to boolean.
+ (md_begin): Set the EF_PPC_RELOCATABLE if -mrelocatable.
+
+Wed Mar 8 15:39:39 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_begin): Check for a cpu string of r8000 or
+ r10000. If mips_isa is 4, set the machine number to 8000.
+ (append_insn): If mips_isa is at least 4, don't generate nops for
+ coprocessor delays. Check INSN_READ_FPR_R when setting
+ mips_cprmask[1].
+ (mips_emit_delays): If mips_isa is at least 4, don't generate nops
+ for coprocessor delays.
+ (mips_ip): Check for INSN_ISA4 instructions. Handle new argument
+ types 'h', 'R', 'N', and 'M'.
+ (md_longopts): Accept "mips4".
+ (md_parse_option): Handle -mips4, and -mcpu=10000 and -mcpu=8000.
+ (s_mipsset): Permit .set mips4.
+
+Wed Mar 8 09:36:05 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_validate_fix): Allow .stab sections to
+ have non PC relative relocations with -mrelocatable.
+
+Wed Mar 8 02:57:53 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-m68k.c (opcode_ptr): Return pointer to const.
+ (md_begin): Make hash table errors fatal. Process opcode aliases
+ after main opcode table.
+ (md_apply_fix_2, case 4): Recode setting of lower_limit to avoid
+ gcc warning.
+
+Tue Mar 7 16:07:10 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo: Add documentation for SPARC V9, from Doug Evans
+ <dje@cygnus.com>.
+
+Mon Mar 6 09:58:34 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: Change all occurences of pa-89 with pa-11 to
+ be consistent with current naming conventions.
+ (md_begin): Set a default architecture and machine type.
+ (pa_ip): If the current instruction specifies a newer machine type
+ than the current machine type, then update the current machine
+ type.
+ (need_pa11_opcode): Likewise.
+
+Sun Mar 5 19:38:09 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip, case 'z'): Don't lose argument
+ relocation bits for absolute calls.
+
+Fri Mar 3 17:41:50 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-h8300.* (md_operand): Change empty function to empty
+ macro.
+
+ * config/tc-h8300.c (build_bytes): Make H8/300-H warning message
+ clearer.
+
+ * write.c (write_contents): If bfd_set_section_contents fails,
+ print a message and exit, instead of aborting.
+
+Fri Mar 3 16:26:19 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * tc.h (md_apply_fix3): If MD_APPLY_FIX3 is defined, declare
+ md_apply_fix3.
+
+ * write.c (fixup_segment): If MD_APPLY_FIX3 is defined, call
+ md_apply_fix3 with the normal 2 arguments and the current segment
+ pointer instead of md_apply_fix.
+
+ * config/tc-ppc.h (MD_APPLY_FIX3): Define.
+
+ * config/tc-ppc.c (ppc_elf_validate_fix): Warn if -mrelocatable
+ and a non PC relative relocation that isn't in the .got2 segment
+ was performed.
+ (md_apply_fix3): Rename from md_apply_fix and take segment pointer
+ as third argument. If ELF object format, call ppc_elf_validate_fix
+ for normal relocations.
+ (md_parse_option): If ELF object format, recognize the
+ -mrelocatable switch.
+
+Thu Mar 2 16:34:44 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.h (AOUT_MACHTYPE): Define as 100, not 0.
+
+Tue Feb 28 18:29:27 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-arm.c, config/tc-arm.h (md_operand): Replaced empty
+ function in .c file with empty macro in .h file.
+ * config/tc-h8500.*, config/tc-hppa.*, config/tc-i386.*,
+ config/tc-i860.*, config/tc-i960.*, config/tc-ns32k.*,
+ config/tc-ppc.*, config/tc-sh.*, config/tc-sparc.*,
+ config/tc-tahoe.*, config/tc-vax.*, config/tc-w65.*,
+ config/tc-z8k.*: Ditto.
+ * config/tc-m68k.*: Ditto.
+
+ * config/tc-m68k.c (mote_pseudo_table): Removed dots from opcode
+ names.
+
+ * read.c (s_app_line): Ignore non-positive line numbers.
+
+Tue Feb 28 15:34:14 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Don't adjust PLT or
+ GOT relocs either.
+
+Mon Feb 27 13:03:41 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * configure.in: add a29k-*-vxworks configuration.
+
+Fri Feb 24 14:41:15 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (load_register): Take dbl argument to determine
+ handling of signed 32 bit values in 64 bit modes. Change all
+ callers.
+ (macro): Handle M_DLI and M_DLA_AB.
+
+Wed Feb 22 23:10:56 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): Don't subtract the value of the
+ add symbol if it's a common symbol (the value of a common symbol
+ is its size, not a value in the traditional sense).
+
+Wed Feb 22 21:12:28 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (append_insn): If listing_prev_line is called,
+ call frag_grow to make sure there is still room for a variant.
+
+Fri Feb 17 14:50:08 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_pseudo_table): Add 2byte, 4byte and 8byte
+ if OBJ_ELF. From gary@Intrepid.COM (Gary Funck).
+
+ * config/obj-elf.c (elf_frob_symbol): Warn if a symbol is both
+ weak and common.
+ * config/obj-aout.c (obj_aout_frob_symbol): Likewise.
+
+Fri Feb 17 12:43:47 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (md_pseudo_table): Don't redefine byte under
+ ELF.
+ (ppc_elf_cons): Don't support @pcrel any more, since DIFF_EXPR_OK
+ allows the normal expressions to generate it.
+ (md_apply_fix): Convert BFD_RELOC_32 with pcrel bit set into
+ BFD_RELOC_32_PCREL. Abort if either BFD_RELOC_16 or BFD_RELOC_8
+ need PC relative relocations.
+
+ * config/tc-ppc.h (DIFF_EXPR_OK): Define to allow PC relative
+ expressions to be handled.
+
+Thu Feb 16 14:30:13 1995 Doug Evans <dje@cygnus.com>
+
+ * expr.c (operand): Move md_operand handling to default case
+ (so it works).
+
+Wed Feb 15 16:08:47 1995 Jason Molenda <crash@cygnus.com>
+
+ * config/tc-h8500.c (tc_coff_symbol_emit_hook): Add ignored
+ parameter, to match prototype.
+
+Wed Feb 15 15:07:00 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (md_pseudo_table): If ELF, go to ppc_elf_cons
+ instead of cons.
+ (md_show_usage): Show all of the PowerPc options.
+ (ppc_elf_suffix): New function to recognize ELF suffixes that
+ specify a relocation, such as @GOT.
+ (ppc_elf_cons): Replacement for the standard cons function that
+ knows about the ELF suffixes.
+ (ppc_fixup): Add reloc field to hold non-standard relocation.
+ (md_assemble): Handle ELF suffixes like @GOT.
+ (md_create_short_jump): Dummy in case WORKING_DOT_WORD is not
+ defined.
+ (md_create_long_jump): Ditto.
+ (md_short_jump_size): Ditto.
+ (md_long_jump_size): Ditto.
+ (md_apply_fix): Handle BFD_RELOC_32_PCREL, BFD_RELOC_LO16,
+ BFD_RELOC_HI16, BFD_RELOC_HI16_S, BFD_RELOC_PPC_TOC16, and
+ BFD_RELOC_16 relocations. If relocation can not be found, print
+ the decimal value of the relocation.
+
+Wed Feb 15 11:46:02 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_apply_fix): Accept BFD_RELOC_16, for
+ DWARF. From gary@Intrepid.COM (Gary Funck).
+
+ * config/tc-mips.c (macro): Handle M_U{L,S}D[_A] (unaligned double
+ loads and stores).
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Do adjust global
+ symbols if OBJ_AOUT.
+
+ * config/tc-mips.c (macro): Don't use the target register as a
+ base register when building the address for M_L{W,D}{L,R}_AB.
+
+Mon Feb 13 14:44:32 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (KT0, KT1): Define.
+ (mips_ip): Recognize $kt0 and $kt1 as register names.
+
+ * config/tc-sparc.h (tc_fix_adjustable): Define if OBJ_ELF.
+ * config/tc-sparc.c (md_apply_fix): If OBJ_ELF, subtract out the
+ value of a defined symbol; the value was added in by
+ fixup_segment. This was previously corrected, if the reloc was
+ changed to be against a section symbol, in tc_gen_reloc.
+
+Fri Feb 10 14:04:04 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Use S_IS_EXTERN
+ rather than !S_IS_LOCAL.
+
+Thu Feb 9 18:16:34 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (md_assemble): Adjust conditions for changing
+ BFD_RELOC_32 to BFD_RELOC_386_GOTPC to handle a switch in frags.
+ Patch originally from Rob Ryan <robr@cmu.edu>.
+
+ * config/tc-i386.c: Include subsegs.h.
+ (tc_i386_fix_adjustable): Declare return value.
+ (i386_operand): Don't use an assignment directly as a condition.
+
+Thu Feb 9 10:37:13 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): In some cases subtract the
+ value of the add symbol from valp. Offsets braindamage in the
+ "machine independent" fixup_segment.
+
+Wed Feb 8 18:51:23 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * messages.c (as_abort): New function.
+ * as.h (as_abort): Declare it.
+ (abort): New macro.
+
+ Thu Jan 19 18:10:05 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/vms-conf.h (HAVE_UNISTD_H): define it unconditionally.
+ * config-gas.com: test for availability of <unistd.h>; create a
+ rudimentary one if necessary.
+
+Tue Feb 7 13:34:46 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in: Add powerpc-*-eabi support, which is the same as
+ powerpc-*-elf.
+ (configure): Rebuild with autoconf.
+
+Mon Feb 6 03:37:00 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Changes from Bryan Ford <baford@schirf.cs.utah.edu> for i386
+ 16-bit and msdos support:
+ * config/tc-i386.c (flag_16bit_code): New variable.
+ (set_16bit_code_flag): New function.
+ (md_pseudo_table): Added entries "code16" and "code32".
+ (md_assemble): Ensure that correct data-size prefixes get emitted,
+ based on the current mode. Ensure that 32-bit addressing will
+ always be done. Move segment-prefix handling code. (Why?) Use
+ 16-bit jumps for 16-bit code, 32-bit jumps for 32-bit code.
+ * config/tc-i386.h (MAX_PREFIXES): Bump to 5.
+ (Data16, Data32): Define.
+ * doc/as.texinfo (i386-16bit): New node.
+ * configure.in (i386-*-msdos*): New target, using a.out format.
+ * configure: Regenerated.
+
+Thu Feb 2 15:21:24 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-m68k.c (cpu32_control_regs): New macro.
+ (m68k_init_after_args): Use it, for cpu32 processors.
+
+ Tue Jan 31 17:20:45 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.c (vms_tir_stack_psect): new routine;
+ (VMS_Set_Data, VMS_Set_Psect, VMS_Store_PIC_Symbol_Reference,
+ VMS_TBT_Routine_Begin, VMS_TBT_Line_PC_Correlation): use it;
+ (VMS_Global_Symbol_Spec, VMS_Procedure_Entry_Pt): treat
+ Psect_Number as `unsigned'.
+
+ Thu Jan 26 17:06:28 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.c: performance tuning.
+ (VMS_Symbol_type_list): convert from single list head to small
+ array of list heads;
+ (SYMTYP_HASH): new macro for accessing VMS_Symbol_type_list[];
+ (find_symbol, setup_basic_type, VMS_typedef_parse): use it;
+ (VMS_RSYM_Parse): move S_GET_VALUE() inside switch to avoid
+ calling it for uninteresting cases.
+
+Wed Feb 1 23:52:45 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): Go ahead and call
+ hppa_field_adjust to get a new value for R_DATA_ONE_SYMBOL
+ relocations in SOM.
+ (hppa_fix_adjustable): Refine somewhat.
+
+Fri Jan 27 21:29:53 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.h (NO_STRING_ESCAPES): Don't define if we are
+ using ELF.
+
+Thu Jan 26 19:03:42 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-h8300.c (get_specific): Add parens around | inside &.
+ (skip_colonthing): Set L_8 if ":8" is specified.
+
+Thu Jan 26 18:38:01 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (md_begin): Permit mfdec to be duplicated on the
+ 601. Check that the error return from hash_insert is "exists".
+
+Thu Jan 26 11:35:33 1995 Michael Meissner <meissner@cygnus.com>
+
+ * configure: Add support for configuring powerpc-*-eabi.
+
+ * config/tc-ppc.c (GOT_symbol): Define if object format is ELF.
+
+ * config/tc-ppc.h (GLOBAL_OFFSET_TABLE_NAME): Define if object
+ format is ELF and not defined to be "_GLOBAL_OFFSET_TABLE_".
+
+Wed Jan 25 16:23:13 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * config/tc-sh.c (little): Add argument IGNORE to avoid
+ compiler warnings.
+ (md_pseudo_table): Add space for consistent formatting.
+ (COND8_RANGE, COND12_RANGE): Delete unused macros.
+ (COND8_F, COND8_M, COND12_F, COND12_M, UNCOND12_F, UNCOND12_M):
+ Correct minimum and maximum branch offsets. Add comments explaining
+ why these numbers are correct.
+
+Wed Jan 25 15:32:09 1995 David Edelsohn <edelsohn@mhpcc.edu>
+
+ * config/tc-ppc.c (md_parse_option): Accept mpwr2 as a synonym for
+ mpwrx; mppc32, m603, and m604 as synonyms for mppc; and mppc64 and
+ m620 for PowerPC64 mode.
+ (ppc_symbol_new_hook): Add T0 as synonym for TC0 suffix.
+
+Tue Jan 24 16:44:23 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-vax.c (vip): Introduce new ptr-to-const local variable
+ for scanning operand string.
+
+ Sat Jan 21 17:50:38 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/vax-inst.h (struct vop, fields `vop_warn', `vop_error'):
+ make them pointers to const char;
+ (struct vit, field `vit_error'): ditto.
+ * config/atof-vax.c (md_atof): rename local `littlenum_pointer'
+ to `littlenumP' to avoid shadowing file scope variable.
+ * config/tc-vax.c (vip_begin, vip_op_defaults, vip_op_1): make
+ string arguments be pointers to const char;
+ (vip): make `alloperr' const char *;
+ (vip_op): make `err' and `wrn' const char *; rename `access' to
+ `access_mode' to avoid shadowing library function.
+ * config/obj-vms.c (`symbol_name'): make it const char *;
+ (get_struct_name): cast one use of `symbol_name' to char *
+ [caller guarantees that it won't modify the pointer's target];
+ (PUT_COUNTED_STRING): use pointer to const char;
+ (VMS_typedef_parse): make `pnt2' const char *;
+ (Write_VMS_MHD_Records): make `cp' const char *;
+ (VMS_Modify_Psect_Attributes, array `Attributes'): make const,
+ and make field `Name' pointer to const char;
+
+ * as.h (`seg_name[]' declaration): pointers to const char;
+ (struct _pseudo_type, field `poc_name'): pointer to const char.
+ * subsegs.c (`seg_name[]' definition): ditto;
+ * hash.c (hash_ask): rename argument `access' to `access_type'
+ to avoid shadowing library function.
+ * write.c (variable `the_object_file'): move from file scope
+ to block scope within write_object_file(); free it after use;
+ (fixup_segment): conditionally exclude it for OBJ_VMS.
+ (cvt_frag_to_fill): rename argument `headers' to `headersP'
+ to avoid shadowing file scope variable.
+
+Mon Jan 23 21:42:39 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip, case 'D'): Fix typo which caused
+ miscompilation of "diag" instructions.
+
+Mon Jan 23 15:51:41 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * configure: Regenerated.
+
+ * config/tc-mips.c: Include libiberty.h.
+
+Mon Jan 23 14:07:58 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-sh.h (tc_init_after_args): Don't define.
+ * config/tc-sh.c (md_begin): Remove unused variable table.
+ (md_assemble): Remove unused variable p.
+ (md_convert_frag): Cast fr_address to unsigned long for printf.
+ (md_apply_fix): Use as_warn_where rather than as_warn.
+ (sh_init_after_args): Remove empty function.
+
+ * configure.in (i386-*-gnu*elf*): New target.
+
+Sat Jan 21 19:02:23 1995 Ian Lance Taylor <ian@tweedledumb.cygnus.com>
+
+ * hash.c (hash_ask): If we find the slot after wrapping around,
+ break out of the loop. Fixes bug in Jan 18 change.
+
+Fri Jan 20 17:07:31 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * hash.c (hash_code): Undo last change.
+
+Thu Jan 19 14:49:47 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-alpha.c (alpha_ip): Initialize local variables to keep
+ gcc quiet.
+ (gpdisp_hi16_howto): Don't use "const" with reloc_howto_type.
+ (in_range_signed): Add parens around subtraction inside shift.
+ * gasp.c (do_data): Initialize local variable "opname".
+ (istrue): Provide a default case to set "res" and keep "gcc -Wall"
+ quiet.
+ * write.c (write_contents): Deleted unused variable.
+ (print_symbol_value_1): Declare.
+ * hash.c (hash_ask): Delete disabled non-strcmp version of the
+ code, and automatic variables used only in those sections.
+ * write.c (chain_frchains_together_1): Only define local variable
+ "prev_fix" if BFD_ASSEMBLER.
+ * flonum-konst.c (dummy1): Return void.
+ * config/tc-vax.c (md_assemble): Remove two comparisons of
+ unsigned numbers versus zero.
+ * as.h (bcopy): If neither memcpy nor bcopy is defined as a macro,
+ define to use memcpy.
+
+ * config/tc-alpha.c, config/alpha-opcode.h: Revert 2 June changes.
+ Turns out we never got the assignment done after all.
+
+ Cleanup of VAX and VMS code, from Pat Rankin:
+ * config/obj-vms.c: Changed exported function names to lower case.
+ (Changed call sites in write.c.) Declare VMS system function
+ names used, conditional on actually being on VMS. Changed many
+ functions that returned no useful value to now be declared to
+ return void. Removed many unused variables. Supply missing
+ return statements or values. Supply `default' case in switch
+ statements. Ensure local variables get initialized.
+ * config/tc-vax.c: Minor changes to silence "gcc -Wall".
+ * config/obj-vms.h, config/tc-vax.h: Added some missing
+ declarations.
+
+Wed Jan 18 13:49:26 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * atof-generic.c (flonum_print) [TRACE]: New function.
+ (atof_generic) [TRACE]: Print multiplier before multiplication,
+ and print multiplication result before and after copy.
+
+ * flonum-mult.c (flonum_multip): Avoid sign extension problems
+ around multiplication operation.
+
+ * atof-generic.c (ASSUME_DECIMAL_MARK_IS_DOT): Define.
+ (atof_generic) [ASSUME_DECIMAL_MARK_IS_DOT]: Check for '.'
+ explicitly instead of calling strchr.
+
+ * config/tc-sparc.c (sparc_ip): When scanning successive opcode
+ table entries, check names for pointer equality before doing
+ string comparisons.
+
+ * hash.c (hash_ask): Call strcmp instead of expanding it inline.
+ (hash_code): Replaced with a version from bfd.
+
+ * config/obj-coff.c (write_object_file): If COFF_FLAGS isn't
+ defined, default it to zero.
+
+Wed Jan 18 12:16:07 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * write.c (fix_new_internal): Clear fx_bsr on those targets which
+ use it.
+
+ * expr.c (operand): Parenthesize && within ||.
+ * listing.c (listing_newline): Likewise.
+ (list_symbol_table): Use %lu to print sizeof.
+ * symbols.c: Comment out unused function indent.
+ (print_symbol_value_1): Cast pointer to unsigned long for printf.
+ * config/obj-coff.c (do_relocs_for): Only declare symbol_ptr if it
+ will be used.
+ * config/tc-h8300.c (md_begin): Remove unused variable reg.
+ (get_operand): Declare type of parameter direction. Remove unused
+ variable size.
+ (get_specific): Fix comment to avoid nested comments.
+ (check_operand): Cast X_add_number to unsigned long for printf.
+ (build_bytes): Remove unused local variables output_ptr, part, and
+ high.
+ (build_bytes): Cast X_add_number to unsigned long for printf.
+ (clever_message): Remove unused variable scan.
+ (md_assemble): Remove unused variable i.
+ (tc_coff_sizemachdep): Remove unused function.
+ * config/tc-h8300.h (tc_reloc_mangle): Declare.
+
+Tue Jan 17 10:58:06 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-mips.c (mips_4650): New static variable.
+ (md_begin): Handle a cpu string of "4650". If mips_4650 was not
+ initialized, set it to 0.
+ (append_insn): Don't insert nops around HI and LO on a 4650.
+ (mips_emit_delays): Likewise.
+ (mips_ip): Use INSN_ISA mask to check ISA of instruction. Check
+ for INSN_4650.
+ (md_longopts): Add m4650 and no-m4650.
+ (md_parse_option): Handle mips-cpu=4650. Handle -m4650 and
+ -no-m4650.
+ * doc/as.texinfo: Document new MIPS options.
+
+Sat Jan 14 23:48:13 1995 Steve Chamberlain <sac@jonny>
+
+ * config/tc-w65.c, config/tc-w65.h, config/w65.mt: Newfiles.
+ * config/obj-coff.h: Cope with w65.
+ * configure, configure.in: Recognize w65.
+
+Thu Jan 12 17:56:24 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * app.c (do_scrub_next_char) [__GNUC__ && __OPTIMIZE__]: If `get'
+ function is scrub_from_file, call scrub_from_file directly, and
+ get gcc's inlining capability into the act.
+
+ * Makefile.in (VMS_OTHER_OBJS): Add ../libiberty/hex.o.
+ (OBJS): Delete hex-value.o.
+ (REAL_SOURCES): Delete hex-value.c.
+ (hex-value.o): Delete dependencies.
+ * hex-value.c: Deleted.
+ * as.c (main): Call hex_init.
+ * expr.c, config/tc-mips.c: Include libiberty.h. Replace
+ hex_value array references with hex_* macros.
+
+Wed Jan 11 17:51:38 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-h8300.h (COFF_FLAGS): Don't define.
+ * config/tc-h8500.h (COFF_FLAGS), config/tc-sh.h (COFF_FLAGS),
+ config/tc-z8k.h (COFF_FLAGS): Ditto.
+
+ * config/obj-coff.c (KEEP_RELOC_INFO): Make sure it's always
+ defined.
+
+ * config/tc-m68k.c (m68k_ip, cases AOFF and AINDEX): Don't
+ generate 68020 addressing modes for a 68000 processor.
+ (md_estimate_size_before_relax, cases PCREL and PCLEA): Ditto.
+
+Tue Jan 10 13:34:14 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/obj-coff.c (write_object_file): Don't treat h8300 and z8k
+ specially with regard to fixups.
+
+Mon Jan 9 16:22:28 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-mips.c (RELAX_RELOC1, RELAX_RELOC2): Cast values to
+ bfd_vma before subtracting.
+
+ * config/obj-coff.c (size_section): Handle rs_space like rs_fill,
+ but make sure fr_symbol is null.
+ (fill_section): Ditto.
+
+Sun Jan 8 16:14:19 1995 Ian Lance Taylor <ian@tweedledumb.cygnus.com>
+
+ * config/tc-mips.c (mips_ip): Fix handling of floating point
+ values when GPOPT is not defined.
+
+Fri Jan 6 16:59:41 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * gasp.c: Include string.h. Put config.h before other includes.
+
+ * config/tc-alpha.c (alpha_ip): Delay calls to emit_add64 until
+ after any remaining operands are also known to match.
+
+Fri Dec 30 18:21:41 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * listing.c (list_symbol_table): Build a format string based on
+ the size of the value to be printed, as long as "unsigned long" is
+ at least as wide, after handling the special case of 4-byte
+ values.
+
+ * Makefile.in (dependencies): Make $(OBJS) depend on as.h and
+ everything it includes. Delete those files from per-file
+ dependencies.
+
+ * as.h (relax_substateT): Now defined to be unsigned int.
+ (relax_stateT): Separate typedef from enum definition.
+ (enum _relax_state): Reordered for better punctuation. Added new
+ values rs_align_code and rs_space.
+ (lineno, struct lineno_struct): Unused, deleted.
+
+ * as.h: No longer include assert.h.
+ (as_assert): Declare.
+ (assert): New definition, calls as_assert longer needed.
+ (__PRETTY_FUNCTION__): Provide default for older versions of gcc.
+ * messages.c (as_assert): New function.
+ * gdbinit.in: Put a breakpoint there.
+
+ * read.c (s_space): Rewrite to handle general expressions.
+ Generate rs_space frags for non-constant values.
+ * write.c (cvt_frag_to_fill): Treat rs_align_code and rs_space
+ like rs_align and rs_org. Verify that fr_offset is non-negative,
+ and force frag type to rs_fill only after assertion checks.
+ (relax_segment): Treat rs_align_code like rs_align. Treat
+ rs_space like rs_org in the first switch; in the second, force the
+ operand to a constant, and use it for the growth size.
+
+Wed Dec 28 20:57:37 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_subspace): For sections with the ZERO
+ attribute, set the "bss" field in the appropriate seginfo structure.
+
+Wed Dec 28 15:01:01 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * subsegs.h: Include obstack.h.
+
+Tue Dec 27 18:16:04 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * as.h (struct frag): Enable align* components now.
+
+Tue Dec 20 14:56:31 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * frags.c (frag_init): Call obstack_begin on `frags'.
+ * subsegs.c (subsegs_begin): Don't do it here.
+ * as.c (main): Call frag_init before subsegs_begin.
+
+ * frags.c (frag_append_1_char): New function.
+ * frags.h (frag_append_1_char): Declare it.
+ (FRAG_APPEND_1_CHAR): Call it. Old definition is commented out
+ for now.
+
+ * as.h (struct frag): Added (but commented out) new fields for
+ tracking current alignment.
+ (frag_now_fix): Changed macro to function declaration.
+ * frags.c (frag_now_fix): Define function here.
+ (frag_new): Use it instead of accessing `frags' directly.
+ * frags.h (frags): Change comment to indicate it shouldn't be
+ accessed directly.
+ * subsegs.h (struct frchain): New field frch_obstack, intended to
+ eventually replace global `frags' obstack.
+ * subsegs.c (subseg_set_rest): Use frag_now_fix instead of
+ accessing `frags' directly. Initialize fields of new frchainS
+ explicitly instead of with memset.
+ * config/obj-coff.c (obj_coff_ln) [!BFD_ASSEMBLER]: Use
+ frag_now_fix.
+ * config/tc-mips.c (s_loc), config/obj-vms.c
+ (vms_resolve_symbol_redef), symbols.c (colon): Likewise.
+
+ * config/tc-m68k.c (md_apply_fix_2): Use offsetT and addressT
+ instead of long and unsigned long.
+ (md_apply_fix): Cast value before passing it.
+
+ * config/obj-aout.h, config/obj-coff.c, config/obj-elf.h,
+ config/obj-som.h, config/tc-h8500.c, config/tc-hppa.c,
+ config/tc-hppa.h, config/tc-sh.c, config/tc-z8k.c: Don't rely on
+ use of ".." when including header files.
+
+ * config/obj-coff.c (fixup_segment): Reformat condition in an `if'
+ statement.
+
+ * Makefile.in (SUBDIR_INCLUDES): Deleted.
+
+Tue Dec 20 13:40:36 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/obj-coff.h: Include bfd/libcoff.h, not libcoff.h.
+
+Mon Dec 19 16:53:36 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-mips.c (load_register): Rewrite to handle O_big 64 bit
+ constants.
+ (mips_ip): Accept O_big constants in case 'I'. Change case
+ 'i'/'j' to treat an O_big constant as an out of range value.
+
+Mon Dec 19 14:15:07 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_subspace): Make sure SEC_HAS_CONTENTS is
+ clear for a section with the "ZERO" attribute.
+
+ * Reduce useless symbols for ELF in an attempt to make smaller
+ objects and speed up the linker.
+ * config/tc-hppa.c (struct call_info): Replace end_symbol field
+ with a size field.
+ (hppa_elf_mark_end_function): Delete unneeded function.
+ (pa_build_unwind_subspace): For the 2nd unwind relocation, use
+ the function symbol + function size instead of a special symbol
+ for the end of the function.
+ (process_exit): Compute the function size here. Don't call
+ hppa_elf_mark_end_of_function anymore.
+ (pa_procend): Likewise.
+ (hppa_fix_adjustable): Only reject 32bit relocations for SOM.
+ (elf_hppa_final_processing): Simplify.
+
+Mon Dec 19 13:49:07 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * configure.in: Recognize mips-sony-bsd and mips-dec-bsd, but
+ reject other vendors until we can be sure we're consistent with
+ bfd.
+
+ * config/obj-vms.c (Create_VMS_Object_File): Instead of formatting
+ a buffer to pass to `error', just call `as_fatal' directly.
+ (VMS_Psect_Spec): Ditto.
+ (VMS_TBT_Module_Begin, VMS_TBT_Source_File, gen1,
+ VMS_typedef_parse, VMS_LSYM_Parse, VMS_Emit_Globalvalues): Call
+ as_tsktsk instead of printf.
+ (VMS_TBT_Module_Begin, VMS_TBT_Line_PC_Correlation,
+ VMS_TBT_Source_File, VMS_TBT_Source_Lines,
+ VMS_Store_Repeated_Data, VMS_Check_For_Main): Use explicit
+ integers rather than sizeof expressions using basic integer types,
+ in case host and target aren't the same. Use memcpy or COPY_*
+ macros instead of possibly unaligned word or longword assignment.
+
+ * config/obj-vms.h (OBJ_SYMFIELD_TYPE): New macro.
+ * config/obj-vms.c (VMS_Store_PIC_Symbol_Reference,
+ VMS_Check_For_Main, VMS_write_object_file): Use sy_obj instead of
+ forcing sy_number to hold a pointer.
+
+Fri Dec 16 14:40:16 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-sh.c (md_begin): Don't fill in md_relax_table here.
+ (md_relax_table): Use static initialization.
+
+ * config/tc-h8300.c (parse_exp, get_operands, clever_message,
+ md_assemble, tc_crawl_symbol_chain, md_undefined_symbol,
+ tc_headers_hook, md_operand, md_number_to_chars): Don't use DEFUN.
+
+ * Makefile.in (CHECKFLAGS): Don't pass AS_FOR_TARGET,
+ CC_FOR_TARGET, OBJDUMP_FOR_TARGET, NM_FOR_TARGET; they're not
+ used.
+ (AS_FOR_TARGET, CC_FOR_TARGET, OBJDUMP, OBJDUMP_FOR_TARGET, NM,
+ NM_FOR_TARGET): Don't define.
+ (VMS_OTHER_OBJS): Add xmalloc.o and xexit.o from libiberty.
+ (tooldir): Use exec_prefix, not libdir.
+
+Fri Dec 16 11:07:10 1994 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/obj-coff.h: Include libcoff.h, not ../bfd/libcoff.h.
+
+ * as.h: Include progress.h.
+ * as.c (main): Call START_PROGRESS and END_PROGRESS.
+ (main, perform_an_assembly_pass): Call PROGRESS.
+
+Fri Dec 16 00:46:08 1994 Ian Lance Taylor <ian@tweedledumb.cygnus.com>
+
+ * write.c (adjust_reloc_syms): Use bfd_is_und_section and
+ bfd_is_abs_section rather than comparing against &bfd_und_section
+ and &bfd_abs_section.
+
+Thu Dec 15 15:27:14 1994 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * config/tc-sh.c (md_begin): Use a local variable when
+ initializing md_relax_table to avoid errors about modifying a
+ const data structure.
+
+Tue Dec 13 15:42:27 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-ppc.c (tc_gen_reloc): Remove OBJ_ELF hack which
+ appears to no longer be needed.
+
+Tue Dec 13 08:04:15 1994 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (macro_build): Accept BFD_RELOC_PCREL* without
+ requiring that the X_op_symbol be in the text_section.
+ (macro): Change the test for a legel expression difference to
+ correspond to changes in pseudo_set in read.c.
+
+Fri Dec 9 21:04:17 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * write.c (write_relocs) [RELOC_EXPANSION_POSSIBLE]: Use
+ bfd_install_relocation.
+
+ * ecoff.c (ecoff_set_gp_prolog_size): If there is no current
+ routine, just return.
+
+ * config/tc-alpha.c (alpha_ip, case 'B', subcase 'c'): Use opcode
+ value from pattern instead of assuming jsr.
+ * config/alpha-opcode.h (jmp): Add a "1,Bc" form.
+
+Thu Dec 8 17:48:25 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (NM_FOR_TARGET): Use ../binutils/nm.new, not just
+ plain nm.
+
+ * configure.in (ns32k-pc532-mach*): Select correct emulation.
+ (mips-sony-bsd*): Use ecoff.
+ (mips-*-gnu*): New target, using aout format, from Roland McGrath.
+ * configure: Regenerated.
+
+Tue Nov 29 13:58:10 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Use libiberty version of xmalloc:
+ * Makefile.in (REAL_SOURCES): Delete xmalloc.c.
+ (OBJS): Delete xmalloc.o.
+ (xmalloc.o): Delete dependencies.
+ * as.c (main): Call xmalloc_set_program_name once program name is
+ known.
+
+ * config/tc-alpha.c (in_range_signed, in_range_unsigned): New
+ routines, split from in_range.
+ (in_range): Deleted. All calls changed to in_range_*signed.
+ (create_lita_section): Macro deleted. Single use expanded in
+ place.
+ (alpha_ip): Handle `t' and `8' operand types.
+ (md_apply_fix): Handle BFD_RELOC_12_PCREL. Print name of
+ unhandled relocation types.
+ * config/alpha-opcode.h: Added HALT and DRAINA. Disabled MOVI,
+ since it doesn't work, and isn't supported by the native
+ assembler.
+
+ * input-scrub.c: Change wording of a comment to avoid interference
+ with Cygnus source-control tools.
+
+ * as.h (errno) [NEED_DECLARATION_ERRNO]: Declare.
+
+ * config/tc-m68k.c (init_table): List buscr and pcr control
+ registers.
+ (m68k_ip, case 'J'): Handle them.
+
+ Delete signal handler code. It's been disabled since March 1993
+ without complaints.
+ * as.c: Don't include signal.h.
+ (got_sig): Unused function deleted, declaration deleted.
+ (SIGTY): Macro deleted.
+ (main): Deleted disabled code for establishing signal handler.
+
+Mon Nov 28 11:37:35 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * app.c (do_scrub_next_char): Insert missing newline at end of file
+ like warning says we do.
+
+Mon Nov 28 00:11:15 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.h (pa_check_eof): Declare new extern function.
+ (tc_frob_file): Define to call pa_check_eof.
+
+ * config/tc-hppa.c (pa_check_current_space_and_subspace): New
+ function to verify the current space and subspace are reasonable.
+ Call for the appropriate pseudo-ops and before instruction parsing.
+ (pa_check_eof): New function to verify enter/exit and proc/procend
+ pairs match at EOF.
+ (pa_code): Simplify.
+
+ * config/obj-som.c: Delete #if 0 code.
+
+Wed Nov 23 19:36:09 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/obj-coff.h (TARGET_FORMAT): Select between coff-shl and
+ coff-sh.
+ * config/sh.mh (TARG_CPU_DEPENDENTS): Get it right.
+ * config/tc-sh.c (little): New function.
+ (md_parse_option): Notice new option.
+ (build_relax, build_Mytes, md_atof, md_convert_frag, md_apply_fix):
+ Cope with little endian data.
+ * config/tc-sh.h (COFF_MAGIC, LISTING_HEADER): Endian dependent.
+
+Wed Nov 23 10:54:38 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (tc_gen_reloc, ELF variant): Revert last
+ change. The real bug was in bfd/elfcode.h and has been fixed.
+
+Tue Nov 22 23:31:20 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (tc_gen_reloc, ELF variant): Add section->vma
+ to the relocation's offset.
+
+Tue Nov 22 14:37:58 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * Makefile.in (INSTALL_XFORM): Fix typo.
+
+Tue Nov 22 10:23:25 1994 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/tc-alpha.c (s_alpha_set): Ignore the .set (no)move and
+ .set (no)volatile directives.
+
+Tue Nov 15 21:44:13 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_subspace): Make sure to always reset
+ current_subspace.
+ (pa_text, pa_data): Likewise.
+
+ * config/tc-hppa.c (pa_align): New function. Aligns the current
+ offset within the current subspace along with updating the
+ alignment of the subspace itself.
+ (pa_subspace): Default alignment to one byte rathern than zero
+ bytes to avoid setting alignment to log2(0).
+ (md_pseudo_table): Use pa_alignment for .align.
+
+Tue Nov 15 15:24:45 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * messages.c (as_fatal): Always put a space after "fatal error:"
+ when printing message.
+
+Tue Nov 15 11:10:43 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.h (obj_frob_symbol): Delete.
+ (tc_frob_symbol): Make definition conditional on OBJ_SOM or
+ OBJ_ELF. For ELF subtract out symbol->section->vma for non common
+ symbols.
+
+Wed Nov 9 14:53:03 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/te-delta.h: New file, derived from te-sysv32.h.
+
+Wed Nov 9 11:52:44 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-ppc.c (ppc_bf): Always set coff_line_base.
+
+Mon Nov 7 01:58:49 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (VERSION): Bump to 2.5.3.
+
+ * configure.in: Compare generic cpu name against "sparc", not
+ "sparc*", since sparc variants should be changed to "sparc".
+ * configure: Regenerated with autoconf 2.1.
+
+ * config/tc-a29k.c (octal, toHex): Variables deleted.
+ (isoctal): Macro deleted.
+ (md_begin): Don't initialize them.
+ (machine_ip, case 'P'/'A'): For absolute operand, generate an
+ error message if it's out of range.
+ (md_apply_fix, case RELOC_JUMPTARG): Check range for PC-relative
+ jumps.
+ (md_apply_fix): Delete code inside "#if 0".
+
+Thu Nov 3 20:20:40 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/go32.mh: Unused file deleted.
+
+ * read.c (get_absolute_expression): Indicate that the error may
+ merely be that the expression can't currently be reduced.
+
+Thu Nov 3 16:09:59 1994 J.T. Conklin (jtc@rtl.cygnus.com)
+
+ * config/tc-m68k.h (TARGET_FORMAT): If TE_NetBSD define as
+ "a.out-m68k-netbsd".
+ * config/tc-sparc.h (TARGET_FORMAT): If TE_NetBSD define as
+ "a.out-sparc-netbsd".
+
+ * config/te-nbsd.h: New file, NetBSD target emulation
+ * config/te-netbsd.h: Removed.
+ * configure.in (i[345]86-*-netbsd*,m68*-*-netbsd*,sparc*-*-netbsd*):
+ Set bfd_gas. Use nbsd emulation.
+
+Thu Nov 3 17:44:47 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Changes from net 2.5.2 release branch:
+
+ * configure.in: Put AC_DEFINE(sparcv9) on its own line, so that
+ the shell variable settings associated with it are permanent. For
+ CPUs requiring bfd_gas=yes, select it based on CPU only, not
+ individual target names. Handle m68k-hp-hpux*, not just -hpux.
+
+ * config/tc-z8k.c (tc_coff_symbol_emit_hook): Add dummy argument
+ to match prototype in obj-coff.h.
+
+ * configure.in: Skip tests for defining WANT_FOPEN_BIN and
+ IBM_COMPILER_SUX.
+ * acconfig.h: Deleted them.
+ * configure, conf.in: Rebuild with autoconf 2.0.
+ * config/go32.cfg, config/vms-conf.h: Updated.
+
+ * config/tc-m68k.c (md_apply_fix_2, md_convert_frag_1): Always use
+ IBM_COMPILER_SUX version of code, with comments indicating why.
+
+ * listing.c (file_info): Use text mode when opening file for read.
+ Use "r" directly, no macro.
+ * input-file.c (input_file_open): Don't use FOPEN_RT, just use
+ "r".
+ * read.c (s_include): Ditto.
+ * output-file.c (output_file_create): Try both "wb" and "w", don't
+ bother with FOPEN_* macros.
+ * as.h: Don't include fopen-*.h.
+
+ * config/alpha-opcode.h: Make "ret" with no operands equivalent to
+ "ret zero,(ra)", to match OSF1 and to be consistent with both
+ one-operand forms.
+
+ Patches from DJ Delorie:
+ * as.h (alloca): undef alloca before defining it just in case
+ * config/go32.cfg: new file for autoconf values
+ * config/te-go32.h: new file
+ * configure.bat: new for autoconf
+
+ * config/tc-i386.c (md_assemble): Fix typo in GOTPC check; had =
+ for ==.
+
+ * configure.in: If target_frag doesn't exist, use /dev/null.
+
+ * as.c (parse_args): For non-VMS systems, re-add `v' to
+ std_shortopts. Add "verbose" to list of long options.
+
+ * write.c (adjust_reloc_syms): When generating an absolute section
+ symbol as a placeholder, don't mark it as used in a relocation
+ entry, here.
+
+ * Makefile.in (comparison): Compare using makefile code from gcc,
+ stripped down to discard subdir stuff and adapted to give a
+ non-zero exit status if either file differs.
+
+Thu Nov 3 15:43:02 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-mips.c (load_address): Fix RELAX_ENCODE arguments for
+ NO_PIC case.
+
+Tue Nov 1 16:10:59 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-mips.c (s_change_sec): If not GPOPT, don't permit
+ switching to the readonly data section.
+
+ * ecoff.c (ecoff_directive_type): Fix warning message.
+
+Sun Oct 30 00:57:35 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_proc): Delete disabled code to put each
+ proc in its own subspace, we're not going to use it.
+
+Tue Oct 25 14:44:33 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-mips.c (macro): Ensure that mips2 case of M_LI_DD in
+ .rdata does not become a variant frag.
+
+ * config/tc-mips.c (mips_cpu): Initialize to -1.
+ (md_begin): Don't mips_cpu if it was already set.
+ (md_parse_option): For -mipsN, don't set mips_cpu if it was
+ already set. For -mcpu=, just set mips_cpu, not mips_isa.
+
+Fri Oct 21 20:42:29 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-mips.c (md_pseudo_table): If OBJ_ELF, handle .section.
+ (s_elf_section): New static function.
+ * ecoff.c (ecoff_build_symbols): Don't abort if we don't recognize
+ the section when setting the storage class; default to sc_Data.
+
+Thu Oct 20 00:43:38 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): Set new_val to 8 for all
+ fixups to branch instructions (not just pc-relative ones) which
+ will generate SOM relocations.
+
+Wed Oct 19 13:41:56 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-a29k.c: Include ctype.h with angle brackets.
+ (define_some_regs): Add new special register names defined on the
+ 29040.
+ (parse_operand): Add argument opt. If non-zero, don't warn about
+ a missing operand.
+ (machine_ip): If handling argument type 'I', pass opt as non-zero
+ to parse_operand. Handle new optional operand type 'I'.
+ (md_undefined_symbol): Handle special register names (srNN).
+
+Tue Oct 18 00:45:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * write.c (renumber_sections): New static BFD_ASSEMBLER function.
+ (write_object_file): Call it after removing gas created sections.
+
+Mon Oct 17 18:06:05 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * symbols.c (symbol_create): Use udata.p, not just udata.
+ * config/obj-elf.c (obj_ecoff_set_ext): Likewise.
+ (elf_get_extr): Likewise.
+
+ * read.c (read_a_source_file): The second argument to as_where is
+ unsigned int *, not int *.
+
+Mon Oct 17 02:26:32 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: Eliminate all uses of fx_addnumber.
+ (tc_gen_reloc): Simplify. It's no longer necessary to set a
+ reloc's addend field to zero for function symbols.
+ (md_apply_fix): Simplify. For fixups which will require a SOM
+ reloc, just clear out the necessary bits in the output file.
+
+Fri Oct 14 19:06:46 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (BISON): Use bison -y, not bison.
+
+Thu Oct 13 19:22:54 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (VERSION): Updated to 2.5.
+ (clean-here): Delete stamp-mk.com.
+ (distclean): Delete .gdbinit.
+ * Version 2.5 released.
+
+Wed Oct 12 20:30:51 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/te-nbsd532.h: Renamed from te-netbsd532.h.
+ * configure.in, configure: Adjusted.
+
+Wed Oct 12 16:33:38 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * config/cplus-dem.c: Removed. It isn't used. Even if it was,
+ it's better to use the one in libiberty.
+
+Wed Oct 12 18:48:39 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * symbols.c (resolve_symbol_value, case O_symbol): Undo last
+ change; it breaks the rs6000 support, and doesn't seem to be
+ needed.
+
+Wed Oct 12 11:56:50 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * config/tc-i386.h,te-netbsd532.h (TARGET_FORMAT): Changed to
+ a.out-<arch>-netbsd to match corresponding changes in BFD.
+
+Wed Oct 12 11:06:11 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-ppc.c (ppc_fix_adjustable): Resolve symbol values
+ rather than explicitly adding the frag address.
+ * config/obj-coff.c (coff_frob_symbol): Add a zero entry to mark
+ the end of the line numbers; this replaces the zero entry which
+ used to be added by coff_add_linesym, removed Oct 7.
+ (coff_adjust_section_syms): Ignore sections with no seginfo.
+
+Wed Oct 12 01:41:37 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (bootstrap, bootstrap2, bootstrap3): Create a
+ "stage" symlink to the appropriate stage* directory, and use it
+ instead in the -B options.
+ (comparison): Revert yesterday's change.
+
+Tue Oct 11 16:48:11 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-sparc.c (tc_gen_reloc): For non-a.out relocations, if
+ pc-relative, use fx_offset only, ignore address of relocation.
+
+Tue Oct 11 15:24:00 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-mips.c (mips_ip): Don't use S_IS_LOCAL when checking
+ for an embedded PIC switch expression, since the definition of
+ S_IS_LOCAL was changed.
+
+Tue Oct 11 15:05:11 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * Makefile.in (comparison): When comparing as.new or gasp.new, try
+ running the binary through sed to avoid differences due to
+ "stage1" or "stage2" having been written into the binary.
+
+Sat Oct 8 01:48:04 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ ELF symbol size handling, based on code from Eric Youngdale:
+ * config/obj-elf.h (OBJ_SYMFIELD_TYPE): New macro. Adds an
+ expression pointer to the symbol structure, used for `size'
+ expressions that couldn't be reduced to constants when initially
+ processed.
+ (elf_frob_symbol): Declare.
+ (obj_frob_symbol): Call elf_frob_symbol always, rather than
+ ecoff_frob_symbol only if ECOFF_DEBUGGING defined.
+ * config/obj-elf.c (obj_symbol_new_hook): Deleted unused code.
+ Clear sy_obj field.
+ (obj_elf_size): Deleted unused code. If size is non-reducible
+ expression, allocate some storage for the sy_obj field and copy
+ the expression.
+ (elf_frob_symbol): New function. Computes sizes, calls
+ ecoff_frob_symbol if appropriate.
+
+ * write.c (fixup_segment): For i386 elf and coff (for now), don't
+ add in value of symbol from another defined section of the file.
+
+Fri Oct 7 17:54:02 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-m88k.h (TC_KEEP_FX_OFFSET): Define.
+ * config/obj-coff.c (do_relocs_for): Test only TC_KEEP_FX_OFFSET,
+ rather than both it and TC_M88K.
+ (coff_adjust_section_syms): New function.
+ (coff_frob_section): For non-empty sections, create aux entry for
+ the section symbol, indicating the size.
+ (n_line_nos): New variable.
+ (add_lineno): Increment it.
+ (coff_add_linesym): Increment n_line_nos, don't call add_lineno.
+ (coff_frob_file): New function; map coff_adjust_section_syms over
+ sections.
+ (obj_coff_line): Only reset line_base for .bf symbols.
+ * config/obj-coff.h (coff_adjust_section_syms, coff_frob_file):
+ Declare.
+ (obj_frob_file): New macro.
+
+ * config/obj-coff.h (OBJ_COPY_SYMBOL_ATTRIBUTES): Renamed from
+ obj_frob_forward_symbol, and rewritten for new parameter list.
+
+ Mon Oct 3 21:02:38 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.h (S_IS_LOCAL): fix obsolete flagseen[] reference.
+
+Wed Oct 5 11:49:26 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/obj-ecoff.c (obj_pseudo_table): Accept .esize and .etype
+ as synonyms for .size and .type.
+
+Wed Oct 5 00:08:10 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-coff.c (coff_frob_section): Remove assert about
+ section alignment.
+ * config/tc-sparc.c (md_section_align): Use section alignment, not
+ xvec align_power_min field.
+
+Fri Sep 30 19:05:20 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * vmsconf.sh (make-gas.com): handle DCL verification to enable
+ sensible feedback to the user while gas is being built.
+
+Fri Sep 30 16:23:31 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (DISTSTUFF): New variable, listing only make-gas.com
+ for now.
+ (diststuff): New target; builds DISTSTUFF.
+ (realclean): Separate target, depend on clean and distclean, then
+ delete DISTSTUFF.
+ * make-gas.com: Deleted.
+
+ * config/tc-i386.c (i386_validate_fix) [BFD_ASSEMBLER]: New
+ function. Converts reloc for "foo-GOT" to BFD_RELOC_386_GOTOFF
+ reloc for "foo".
+ (i386_operand): Don't look up section symbol for
+ undefined_section.
+ (reloc): Always permit return of 8- and 16-bit relocation types.
+ Add a space after "pc-relative" in the error message.
+ (tc_i386_fix_adjustable) [BFD_ASSEMBLER]: Reject
+ BFD_RELOC_386_GOTOFF relocs.
+ (i386_operand): For any GOTOFF reloc, convert it to a BFD_RELOC_32
+ with a "foo-GOT" value.
+ * config/tc-i386.h (i386_validate_fix): Declare it.
+ (TC_VALIDATE_FIX): New macro -- call it.
+ (NOP_OPCODE): Cast to `char' to avoid compiler warnings.
+
+ * as.h: If __STDC__ is not defined and varargs.h is available, use
+ it rather than stdarg.h.
+
+ * write.h (struct fix): Added new bitfield fx_plt, for fixups
+ referring to PLT entries.
+ * write.c (fix_new_internal): Initialize fx_plt to zero.
+ (adjust_reloc_syms): Re-fetch `sym' after top of reduction loop.
+ Don't adjust fx_offset by frag address, since S_GET_VALUE now
+ includes the frag address.
+ (fixup_segment): Changed local var PCREL to type int, added PLT.
+ If PC-relative fixup refers to a PLT entry for a symbol in the
+ current section, don't reduce it.
+
+ * write.c (adjust_reloc_syms): Exit loop through a label. If
+ DEBUG5 is defined, print out each fixup before and after
+ processing.
+ (fixup_segment): If DEBUG5 is defined, print out each fixup before
+ and after processing.
+ (print_fixup): Added prototype. Show address on first line. Show
+ fx_offset and fx_subsy. [!BFD_ASSEMBLER]: Only show fx_r_type if
+ NEED_FX_R_TYPE is defined.
+
+ * symbols.c (print_symbol_value_1): Check S_IS_LOCAL, S_IS_EXTERN,
+ S_IS_DEBUG, S_IS_DEFINED also.
+
+Thu Sep 29 18:57:06 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (all): Depend on .gdbinit.
+ (.gdbinit): Rebuild from gdbinit.in by running config.status.
+
+ * gdbinit.in: Define new function "pf". Fix doc on "pe" and "ps".
+
+ * write.c (print_fixup): Print source location on first line.
+ Show fx_r_type and fx_addsy fields.
+
+Wed Sep 28 14:56:39 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * configure.in: Set bfd_gas for all sparc targets in one place,
+ instead of separately for each. Correctly handle user-supplied
+ "--enable-bfd-gas" option.
+
+ * gdbinit.in: Move "break abort" to end, in case gdb complains.
+
+ * as.h (PRINTF_WHERE_LIKE, PRINT_LIKE) [USE_STDARG, !__GNUC__]:
+ Use PARAMS macro.
+
+ * symbols.c (resolve_symbol_value, case O_symbol): Don't do any
+ processing if add_symbol is undefined or in expr_section.
+ (resolve_symbol_value, case O_add): For symbol plus
+ constant-valued symbol, convert to O_symbol and re-reduce.
+ (S_GET_VALUE): If symbol needs resolving, resolve it.
+ (indent_level): No longer static.
+ (print_symbol_value_1): Don't print frag address if it matches
+ zero_address_frag. Don't print "resolving" if already resolved.
+ Print segment name. Don't call print_expr_1 on an undefined
+ symbol.
+ (print_expr_1): Fix whitespace before printing X_add_number.
+
+ * expr.c (make_expr_symbol): No longer static. Use symbol_create,
+ not symbol_new, for symbols holding expression values.
+ * expr.h (make_expr_symbol): Move declaration here.
+ * write.c (fix_new_exp): Handle O_add by creating an
+ expression-valued symbol, and calling fix_new_exp recursively.
+ (adjust_reloc_syms): If a fixup's symbol value is a sum of an
+ undefined symbol and a constant, fold the constant into the fixup,
+ and refer to the undefined symbol directly. Then process the
+ fixup again from scratch.
+ (write_object_file): Before calling adjust_reloc_syms, make a pass
+ through the symbol list trying to resolve values.
+
+ * write.c (print_fixup): New routine, for debugging.
+ (write_relocs): Call bfd_install_relocation. Deleted various
+ hacks for working around problems with bfd_perform_relocation.
+
+ * Makefile.in (VERSION): Update to 2.4.90.
+
+Wed Sep 28 11:50:40 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * Makefile.in (gasp.o): Depends upon config.h.
+
+ * config/tc-mips.c: Include subsegs.h.
+ (md_apply_fix): If an unconditional b or bal overflows, and we are
+ not assembling PIC code, replace it with a j or jal.
+
+ * config/tc-mips.c (md_apply_fix): Correct branch overflow test.
+ Use as_bad_where and as_warn_where rather than as_bad and as_warn.
+
+Mon Sep 26 17:15:59 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * write.c (write_relocs): Add file name and line number to
+ as_fatal calls. Handle bfd_reloc_overflow case specifically when
+ RELOC_EXPANSION_POSSIBLE.
+
+Fri Sep 23 16:11:28 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * as.h (USE_STDARG, USE_VARARGS): Define one or neither of these
+ here. Use them for deciding which PRINTF*LIKE macro definitions
+ to use.
+ * messages.c: Use them, instead of NO_STDARG, NO_VARARGS.
+ [!USE_STDARG && !USE_VARARGS] (va_alist, va_dcl, ...): Provide
+ default definitions matching what we were doing before.
+ (as_tsktsk): Remove the non-stdarg, non-varargs version, and
+ always use the varargs form if not using stdarg. It's safe to
+ always use vfprintf, because libiberty will provide it if the
+ native system doesn't. Also, always make format be const.
+ (as_warn, as_warn_where, as_bad, as_bad_where, as_fatal): Ditto.
+
+Fri Sep 23 14:42:34 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-mips.c (load_register): Always use addiu when adding a
+ constant to $zero--no need to use daddiu.
+ (macro): Hack the -mips3 overflow tests to not fail when offsetT
+ is only 32 bits.
+
+ * symbols.h (copy_symbol_attributes): Declare.
+
+Thu Sep 22 21:58:24 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * listing.c: Bugfixes based in part on patches from Paul
+ Kranenburg.
+ (listing_newline): Check filename as well as line number when
+ deciding whether to record it.
+ (list_symbol_table) [S_IS_REGISTER]: Check that S_IS_REGISTER is
+ false (if defined) as well as checking for reg_section.
+ (listing_listing): Iterate fetching lines while line number is too
+ low, and we haven't run off the end of the input file.
+
+ * config/vms-conf.h: Changed HAVE_DELETE to HAVE_REMOVE.
+
+Thu Sep 22 13:39:10 1994 Kung Hsu (kung@x1.cygnus.com)
+
+ * ecoff.c (ecoff_generate_asm_lineno): check if
+ current_stabs_filename is NULL before strcmp.
+ * read.c (read_a_source_file): fix a bug in generate_asm_lineno
+ checking.
+
+Wed Sep 21 18:17:35 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/ho-*.h: Now-unused files deleted.
+
+ * symbols.c (copy_symbol_attributes): New function. Copies BFD
+ symbol flags and calls OBJ_COPY_SYMBOL_ATTRIBUTES.
+ (resolve_symbol_value, case O_symbol): Call it, if X_add_number is
+ zero. Don't call obj_frob_forward_symbol.
+ * read.c (pseudo_set): Call copy_symbol_attributes, but only if
+ X_add_number is zero.
+ * config/obj-elf.h (obj_frob_forward_symbol): Deleted.
+
+ * config/tc-i960.c: Lots of whitespace, comment reformatting,
+ using GNU indent.
+ (strchr): Don't declare.
+ [BFD_ASSEMBLER]: Don't compile md_convert_frag,
+ md_estimate_size_before_relax, md_ri_to_chars,
+ md_create_short_jump, md_create_long_jump.
+ (brtab_emit): Use data_section, not SEG_DATA.
+
+ Mon Sep 19 17:14:44 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/vms-conf.h: new file, manually derived from conf.in.
+ * config-gas.com: use it, and eliminate obsolete "host.h".
+
+Wed Sep 21 11:11:30 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-ppc.c (ppc_current_block): New static variable.
+ (ppc_stabx): Set sy_tc.within of a C_STSYM symbol to
+ ppc_current_block. Don't move around any stab symbol, just those
+ for common symbols.
+ (ppc_bs): Set ppc_current_block.
+ (ppc_es): Clear ppc_current_block.
+ (ppc_frob_symbol): Set the value of a C_STSYM symbol to the offset
+ from the csect of the enclosing block.
+
+ * config/tc-mips.c (insns_since_cache_access): Remove.
+ (append_insn): Remove setting of insns_since_cache_access, and
+ special 4600 handling; it turns out not to be required.
+
+Tue Sep 20 16:13:18 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-mips.c (md_shortopts): Remove E.
+ (md_longopts): Add EB and EL.
+ (md_parse_option): Handle -EB and -EL as separate options, rather
+ than as a single -E option with an argument.
+
+Mon Sep 19 12:42:05 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (hppa_fix_adjustable): Reject reductions
+ involving global symbols too.
+
+Mon Sep 19 12:12:46 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * as.h: Test NEED_DECLARATION_*, not NEED_*_DECLARATION.
+
+ * configure.in: Test for remove, not delete. Fix cross-assembler
+ test.
+ * as.h: Test HAVE_REMOVE, not HAVE_DELETE; define unlink to
+ remove, not delete.
+
+ * read.c (pseudo_set, case O_symbol): If
+ OBJ_COPY_SYMBOL_ATTRIBUTES is defined, invoke it.
+ [BFD_ASSEMBLER]: Copy BSF_FUNCTION setting too.
+ * config/obj-elf.h (OBJ_COPY_SYMBOL_ATTRIBUTES): Define.
+
+ Wed Aug 10 19:15:30 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.h (DSG_S_C_UBITU, DST_K_VFLAGS_DSC, DST_K_TS_ATOM,
+ many others): new macros; values obtained from "DSTRECRDS.SDL".
+ * config/obj-vms.h (various): use them.
+ (USE_BITSTRING_DESCRIPTOR): new macro, for selecting bitfield
+ representation (only enum bitfields can avoid being bitstrings).
+ (bitfield_suffix, setup_basic_type): new routines.
+ (VMS_typedef_parse): use them. Now recognize bitfields of all
+ integral types, not just type `int'. Caveat: the representation
+ used for bitfields still does not work for objects placed in
+ registers, and gcc's optimizer sometimes puts small structs there.
+
+ Tue Jun 14 17:31:44 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * read.c (s_text) [#if OBJ_VMS]: clear the IN_DEFAULT_SECTION
+ bit from const_flag.
+ * config/obj-vms.h (IN_DEFAULT_SECTION): define this macro.
+ (tc_frob_label): define this to call vms_check_for_special_label,
+ and declare the latter.
+ * config/obj-vms.c (vax_g_doubles): declare this file-scope
+ variable.
+ (const_flag): initialize to IN_DEFAULT_SECTION instead of 0.
+ (vms_check_for_special_label): new routine (tc_frob_label).
+ (VMS_TBT_Routine_End): don't bother checking for `gcc_compiled.'
+ and `gcc2_compiled.' labels; they won't reach here any more.
+ (VMS_typedef_parse) [case 'r']: for types `double' and `complex
+ double', use `vax_g_doubles' flag to select type of double.
+ (VMS_write_object_file) [traceback setup]: don't pass symbols
+ with the IN_DEFAULT_SECTION attribute to the TBT_Routine_Begin
+ and TBT_Routine_End functions.
+
+ Mon Jun 6 20:52:20 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.c (VMS_TBT_Routine_End): cache the result of
+ S_GET_VALUE() to avoid many repeated function calls.
+ (VMS_Check_For_Main) [#if HACK_DEC_C_STARTUP]: capitalize
+ _C$MAIN_ARGS in advance, in case -h3 (leave symbol name as-is)
+ gets requested. [All the HACK_DEC_C_STARTUP code appears to
+ be obsolete; gcc does it automatically for vms target. It's
+ also misnamed, because it is for the "VAX C" run-time library,
+ not the newer "DEC C" one which has much different startup code.]
+ {various}: use `S_SET_xxx(symbol,new_value)' rather than
+ `S_GET_xxx(symbol) = new_value'.
+
+Mon Sep 19 12:05:03 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/obj-coff.c (c_dot_file_symbol): Use bfd_abs_section_ptr,
+ not &bfd_abs_section.
+
+Thu Sep 15 18:36:34 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * expr.c (clean_up_expression): Use addressT, not bfd_vma.
+
+Tue Sep 13 20:05:47 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * expr.c (expr): Don't reduce the difference of two symbols in the
+ same frag if the symbols are not in normal sections.
+
+ * config/obj-som.h (S_SET_OTHER, S_SET_TYPE): Delete a.out crud.
+ (S_SET_DESC, S_GET_OTHER, S_GET_TYPE, S_GET_DESC): Likewise.
+ (obj_attach_unwind_info): Do not define. Not needed anymore.
+ * config/tc-hppa.c: Delete whitespace at EOL.
+ (struct hppa_fix_struct): Delete fx_unwind field and all references.
+ (fix_new_hppa): Last arg is now a pointer to an int. Do not
+ call obj_attach_unwind_info anymore. For SOM R_ENTRY and R_EXIT
+ fixups, store 32bits of unwind information in the fx_addnumber
+ field of the fixup.
+ (md_assemble, pa_entry, process_exit, pa_procend): For SOM R_ENTRY
+ and R_EXIT fixups, pass a NULL pointer to fix_new_hppa, and a
+ pointer to 32 bits of unwind info.
+ (tc_gen_reloc): For SOM R_ENTRY and R_EXIT fixups, set the symbol
+ pointer to the dummy symbol; set the addend field to fx_addnumber.
+ (pa_comm, pa_equ, pa_type_args, pa_import): Use bfd_XXX_section_ptr
+ rather than &bfd_XXX_section.
+
+Tue Sep 13 21:15:36 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-i386.c (md_apply_fix_1): For GOTPC relocs, decrement
+ value by one; discard adjustments previously being made. From
+ Eric Youngdale.
+
+ VMS- and Vax-related changes from Pat Rankin:
+ * Makefile.in (VMS_OTHER_OBJS): add concat, getopt, and getopt1.
+ * vmsconf.sh: no longer have make-gas.com echo text about needing
+ to modify the gcc-vms driver when intending to use with gcc 1.x.
+ * as.c (parse_options): suppress 'v' from std_short_options and
+ eliminate VMS-specific conditional initialization;
+ [default case]: check for '-v' if md_parse_options doesn't recognize
+ an option;
+ [default case, #if VMS]: check for filename argument when '-v' seen;
+ [case 'v']: delete.
+ * config/tc-vax.c (md_assemble): don't rely on `this_add_number'
+ for O_big literal operands (double floats and long long ints);
+ [VMS, md_shortopts]: add second colon after 'v';
+ (md_parse_options) [VMS, case 'v']: check for argument, so
+ caller can handle `-v' w/o arg.
+
+Tue Sep 13 16:45:08 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/obj-coff.c (do_relocs_for): If TC_KEEP_FX_OFFSET
+ is defined, put the tx_offset into the r_offset.
+ * config/tc-sh.c (line_comment_chars): Add #
+ (tc_reloc_mangle): Deleted.
+ * config/tc-sh.h (TC_KEEP_FX_OFFSET): Define.
+ (TC_RELOC_MANGLE): Delete.
+
+Tue Sep 13 16:20:36 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * flonum-konst.c: Change preprocessor tests of HO_VMS to just VMS.
+ * hex-value.c: Ditto.
+ * config/obj-vms.c: Ditto.
+
+ * config/tc-sparc.c (sparc_ip): Replace as_bad/exit sequence with
+ a call to as_fatal.
+ * config/tc-i860.c (i860_ip): Ditto.
+ * config/tc-hppa.c (pa_ip): Ditto.
+ * config/tc-alpha.c (alpha_ip): Ditto.
+ * as.c (parse_args): Ditto.
+
+ * config/tc-mips.c (mips_ip): Replace as_warn/exit sequence with a
+ call to as_fatal.
+
+ * write.c (write_contents): Use EXIT_FAILURE.
+ * output-file.c (output_file_create, output_file_close,
+ output_file_create, output_file_close): Ditto.
+ * messages.c (as_fatal): Ditto.
+ * config/obj-som.c (obj_som_version, obj_som_copyright): Ditto.
+ * config/obj-ieee.c (write_object_file): Ditto.
+ * config/obj-coff.c (write_object_file): Ditto.
+ * config/tc-vax.c (main): Use EXIT_SUCCESS.
+ * config/tc-m68k.c (main): Ditto.
+
+ * hash.c (main): Pass a value to exit().
+
+ * as.h (EXIT_SUCCESS, EXIT_FAILURE): Moved here.
+ * as.c: ...from here.
+ (parse_args): Use them always.
+ (main): Use exit rather than return.
+
+ * Makefile.in (*_FOR_TARGET, INSTALL_XFORM, install, uninstall):
+ Rewrite handling of program_transform_name.
+
+ * configure.in: Test for functions unlink and delete.
+ * as.h: If unlink isn't available but delete is, define unlink to
+ be delete.
+
+ Update for autoconf 1.118:
+ * gdbinit.in: New file, created from old .gdbinit.
+ * .gdbinit: Deleted.
+ * aclocal.m4 (GAS_GDBINIT): Deleted.
+ * configure.in: Don't use it. Instead, generate .gdbinit from
+ gdbinit.in. Don't substitute cpu_type, obj_format, emulation,
+ atof. Switched order of AC_LINK_FILES arguments. Use AC_PREREQ
+ to ensure that older versions of autoconf aren't used.
+ * Makefile.in: Added @configure_input@ line.
+ (configure): Deleted rule.
+
+Tue Sep 13 12:08:20 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/obj-coff.c (fixup_segment): After handling the difference
+ of two symbols from the same segment, set fx_subsy to NULL, to
+ satisfy existing TC_COUNT_RELOC macros.
+
+Tue Sep 13 01:47:08 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * aclocal.m4 (GAS_GDBINIT): New macro.
+ * configure.in: Use it.
+ * configure: Regenerated.
+
+Mon Sep 12 20:56:38 1994 Ken Raeburn (raeburn@kr-laptop.cygnus.com)
+
+ * .gdbinit (pe, ps): Define new commands.
+ * symbols.c (indent_level): New static variable.
+ (indent, print_expr_1, print_symbol_value_1, print_symbol_value,
+ print_expr): New functions.
+
+ * Makefile.in (config-stamp): Add a "this file generated by make"
+ message to config.h.
+
+ PIC implementation for i386-linux, based on code from Eric
+ Youngdale and Paul Kranenburg, with some work of my own:
+
+ * write.c (fixup_segment): Test TC_RELOC_RTSYM_LOC_FIXUP on fixup
+ before processing same-section pcrel relocations.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Default to 1.
+
+ * expr.c (make_expr_symbol): If operator is O_symbol and
+ X_add_number is zero, just return the symbol. If operator is
+ O_constant, resolve the symbol's value before returning.
+ (operand): Permit use of "[]" for grouping.
+ (clean_up_expression): For difference of two symbols in the same
+ frag, add the difference of their offsets into X_add_number.
+ (expr): Reduce difference of two symbols in same frag to their
+ difference.
+
+ * config/tc-i386.c (TC_RELOC): New macro.
+ (struct _i386_insn): New field disp_reloc.
+ (GOT_symbol): New variable.
+ (operand_special_chars): Added square-brackets and at-sign.
+ (reloc) [BFD_ASSEMBLER]: Added new argument OTHER; if it is not
+ NO_RELOC, just return it.
+ (reloc) [! BFD_ASSEMBLER]: Add third argument to dummy macro.
+ (BFD_RELOC_386_PLT32, _GOT32, _GOTOFF) [! BFD_ASSEMBLER]: More
+ dummy macros.
+ (tc_i386_fix_adjustable): New function. Returns zero if symbol in
+ fixup is not local, to prevent relocations against externals from
+ being dropped.
+ (md_assemble): Initialize disp_reloc field to NO_RELOC. Pass
+ disp_reloc field to reloc() function, and use TC_RELOC to generate
+ value to pass to fix_new_exp.
+ (md_assemble): Change 32-bit reloc against GOT_symbol into a GOTPC
+ reloc.
+ (i386_operand): Initialize disp_reloc field to NO_RELOC. Handle
+ @GOTOFF, @PLT, @GOT operands. For GOTOFF relocations with local
+ symbols, force generation of the section symbol.
+ (md_estimate_size_before_relax): If GOT_symbol exists, decide
+ we're generating PIC code, and convert relocations against
+ undefined symbols from PCREL to PLT32.
+ (md_apply_fix_1) [OBJ_ELF]: Fix up values for dynamic-linking
+ relocs.
+ (md_undefined_symbol): Notice GLOBAL_OFFSET_TABLE_NAME and set
+ and return GOT_symbol if it matches.
+ (F, MAP): Move macro definitions outside function.
+ (tc_gen_reloc): Only switch on size and pcrel if code wasn't
+ already supplied as PLT32. GOT32, GOTOFF, or GOTPC. Convert
+ BFD_RELOC_32 using GOT_symbol into GOTPC.
+ * config/tc-i386.h (TC_RELOC, tc_fix_adjustable,
+ TC_RELOC_GLOBAL_OFFSET_TABLE, TC_RELOC_RTSYM_LOC_FIXUP): New
+ macros.
+ (NEED_FX_R_TYPE): Define.
+ (LOCAL_LABEL): Accept ".X" prefix too.
+ (GLOBAL_OFFSET_TABLE_NAME): Default to "_GLOBAL_OFFSET_TABLE_".
+
+Mon Sep 12 17:51:39 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/obj-elf.c (obj_elf_type): Rewrite to accept syntax
+ reportedly to be used on Irix 6.
+
+ * config/tc-mips.c (md_pseudo_table): Handle .globl and .global.
+ (s_mips_globl): New static function; needed for Irix 5 support.
+ * ecoff.c (ecoff_build_symbols): If BSF_FUNCTION is set for an
+ external symbol with no type, set the type to st_Proc rather than
+ st_Global. Don't set the index of an external st_Proc or
+ st_StaticProc symbol unless it is also a local symbol.
+
+ * read.c (read_a_source_file): The second argument to as_where is
+ unsigned int *, not int *.
+
+Thu Sep 8 17:18:24 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * config/obj-ecoff.h : Change names to OBJ_GENERATE_ASM_LINENO,
+ and generate_asm_lineno.
+ * config/obj-elf.h : ditto.
+ * read.h : ditto.
+ * read.c (read_a_source_file): if no file when inst is read, set
+ generate_asm_lineno to true.
+ * ecoff.h : change name to generate_asm_lineno and add function
+ ecoff_no_current_file.
+ * ecoff.c : change name to generate_asm_lineno.
+ * ecoff.c (ecoff_generate_asm_lineno) : new function, to generate
+ ecoff style line for asm file.
+
+Thu Sep 8 19:43:49 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/obj-coff.c (size_section): Do an fprintf to stderr rather
+ than a printf.
+ (fixup_segment): Use as_bad_where rather than as_bad.
+
+Wed Sep 7 17:21:12 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/tc-{h8300,sh}.[ch] (tc_coff_symbol_emit): Function doing
+ nothing becomes macro doing nothing.
+
+Wed Sep 7 19:10:09 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * Makefile.in (Makefile): Depend on config.status.
+ (config.status): Run config.status from . instead of srcdir.
+
+ * config/tc-i386.c (tc_gen_reloc): Use bfd_get_reloc_code_name to
+ display the name of the relocation type that couldn't be handled.
+ * config/tc-sparc.c (tc_gen_reloc): Likewise.
+ * config/tc-alpha.c (tc_gen_reloc): Likewise. Deleted abort call
+ after call to as_fatal.
+
+ * configure.in (i386-*-linux*): Don't set bfd_gas.
+
+ * Makefile.in (CC_FOR_TARGET, NM_FOR_TARGET, OBJDUMP_FOR_TARGET,
+ install, uninstall): Don't use "brokensed" hack any more, the new
+ autoconf code should never let program_transform_name be empty.
+
+ Update for autoconf beta 1.112:
+ * aclocal.m4 (GAS_CHECK_DECL_NEEDED, GAS_WORKING_ASSERT): New
+ macros.
+ * configure.in: Use them. Use AC_ARG_PROGRAM (now provided by
+ autoconf) instead of my hacked-up AC_PROGRAM_TRANSFORM_NAME. Move
+ test for CROSS_COMPILE just before AC_FUNC_ALLOCA, and emit a
+ message to try to ease confusion about autoconf's
+ "cross-compiling" message.
+ * acconfig.h (NEED_DECLARATION_MALLOC, NEED_DECLARATION_FREE,
+ NEED_DECLARATION_ERRNO): Renamed from NEED_*_DECLARATION.
+ * configure, conf.in: Regenerated.
+
+Wed Sep 7 12:49:55 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * configure.in: Check ${host} and ${target} rather than
+ ${host_canon} and ${target_canon}.
+ * configure: Likewise.
+
+Tue Sep 6 11:42:38 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-mips.c (mips_cpu): New static variable.
+ (insns_since_cache_access): New static variable.
+ (md_begin): Set mips_cpu as well as mips_isa.
+ (append_insn): If mips_cpu is 4600, require four nop instructions
+ between an instruction which accesses the cache and certain CACHE
+ instructions. Keep track of the number of instructions seen since
+ an instruction which accesses the cache.
+ (md_parse_option): Set mips_cpu as well as mips_isa.
+
+Mon Sep 5 07:09:00 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * doc/Makefile.in (VPATH): Define using @srcdir@.
+ (prefix, program_transform_name, exec_prefix): Use autoconf style
+ @-substitutions.
+
+Sun Sep 04 17:58:10 1994 Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+
+ * config/ho-riscix.h, config/tc-arm.c, config/tc-arm.h: New files
+ * configure.in: Recognize the arm.
+
+Fri Sep 2 16:05:50 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ecoff.c (add_file): Don't try to generate line numbers if the
+ symbol table has been frozen.
+
+Thu Sep 1 19:48:01 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * aclocal.m4 (AC_PROG_CC): Use AC_DEFUN, and omit AC_PROVIDE.
+
+ * configure.in: Handle user-specified bfd-assembler option with
+ separate variable from preferred configuration, until the two are
+ resolved. Indicate bfd_gas=preferred for linux a.out. Use
+ AC_PROGRAM_TRANSFORM_NAME, for which a patch has been sent to djm.
+ * Makefile.in (target_alias, program_transform_name): Define,
+ using autoconf @-substitutions.
+
+Wed Aug 31 17:43:06 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * atof-generic.c: Deleted alloca handling here.
+
+ * Makefile.in (prefix, exec_prefix): Use @-subtitutions.
+
+ * aclocal.m4 (AC_OUTPUT_LINKS): Deleted redefinition, since
+ autoconf 1.109 has this fixed.
+ * configure.in: Don't change quote characters around AC_MSG_ERROR
+ invocation. Don't use AC_HEADER_STDC, since it requires running a
+ program. Cache NEED_*_DECLARATION values.
+ * configure, conf.in: Regenerated with a modified autoconf 1.109.
+
+ * as.h (volatile): Don't test or define here; not needed.
+ (alloca): Replace alloca-conf.h inclusion with code recommended in
+ autoconf documentation. Include config.h first.
+
+Wed Aug 31 11:20:48 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/obj-coff.h (S_IS_DEFINED): Absolute symbols are defined
+ also.
+
+ * configure.in, configure: Initialize bfd_gas to no.
+
+Tue Aug 30 19:31:14 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * as.h: Include alloca-conf.h from "libiberty", not
+ "../libiberty".
+
+Mon Aug 29 16:11:30 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-ppc.c (md_apply_fix): Don't generate a reloc when a
+ symbol is used as an offset into a CSECT that is not a TOC. These
+ types of loads are generated by gcc -mminimal-toc.
+
+Sun Aug 28 13:22:52 1994 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * as.h (flag_*): Added comments describing meanings of some of
+ these variables.
+ (struct frag): Add some comments about the ns32k-specific fields
+ and why they're here.
+ (SIZEOF_STRUCT_FRAG): Cast addresses to char*, not int.
+ (flag_print_statistics): Declare.
+
+ * as.c (parse_args): Set flag_print_statistics instead of
+ statistics_flag. Options array is now const. Added new option
+ "dump-config"; if specified, print TARGET_ALIAS, TARGET_CANONICAL,
+ TARGET_CPU, TARGET_OBJ_FORMAT, and TARGET_FORMAT, if defined.
+ (main): Change test to check flag_print_statistics.
+ (statistics_flag): Deleted.
+
+ * frags.c (frag_variant): Removed PCREL_ADJUST and BSR arguments.
+ Always initialize them to zero.
+ * frags.h (frag_variant): Fixed prototype.
+ * config/tc-i960.c (get_cdisp): Don't pass the extra zero args.
+ * config/tc-ns32k.c (convert_iif): Don't pass the arguments; cache
+ the value of frag_now and fill in the fields later.
+
+ * Makefile.in (distclean, realclean): Remove new
+ configure-generated files.
+
+Sat Aug 27 20:26:12 1994 Ken Raeburn (raeburn@kr-laptop.cygnus.com)
+
+ Conversion to autoconf:
+ * acconfig.h, aclocal.m4: New files.
+ * configure.in: Rewritten (except for some target-specific code)
+ for autoconf.
+ * conf.in, configure: New files, generated from the above.
+ * Makefile.in: Changed magic sequence indicating insertion of
+ makefile fragments.
+ (VPATH, srcdir, CC, LIBS, OBJS dependencies): Use @-substitutions
+ from configure.
+ (LINKED_HEADERS): Deleted a.out.gnu.h, a.out.h, and host.h.
+ (config.status, configure): Rewrite rules.
+ (config-stamp): Depend on conf. Skip variables that configure is
+ now substituting itself.
+ (*.o dependencies): Deleted host.h.
+ (distclean, realclean): Don't delete host.h.
+ * as.c: Don't include stdio.h, string.h, sys/types.h. Include
+ signal.h after as.h.
+ * as.h: Include alloca-conf.h first. Include ctype.h, string.h,
+ strings.h, stdlib.h, unistd.h, sys/types.h, fopen-bin.h,
+ fopen-same.h, as suggested by autoconf test results.
+ [BROKEN_ASSERT]: Don't include assert.h.
+ (strdup): Declare.
+ (volatile, const): Define if not __STDC__ and not already defined.
+ (malloc, realloc) [NEED_MALLOC_DECLARATION]: Declare.
+ (free) [NEED_FREE_DECLARATION]: Declare.
+ * gasp.c: Include config.h, stdlib.h (if HAVE_STDLIB_H). Don't
+ include host.h.
+ (malloc) [NEED_MALLOC_DECLARATION]: Declare.
+ * messages.c: Include as.h first. Include errno.h only if
+ HAVE_ERRNO_H. If HAVE_VARARGS_H and not __STDC__, undefine
+ HAVE_STDARG_H. Set NO_STDARG and NO_VARARGS as appropriate.
+ * doc/Makefile.in (srcdir, INSTALL, INSTALL_PROGRAM,
+ INSTALL_DATA): Use autoconf @-substitutions.
+
+ * input-file.c: Don't include assert.h here, 'cause as.h already
+ includes it.
+
+ * config/tc-alpha.c: Added various prototypes for static
+ functions.
+ (in_range): New function, tests whether a value can fit in an
+ N-bit field.
+ (build_mem, build_operate_n): New functions for constructing
+ opcode values.
+ (emit_sll_n, emit_ldah_num, emit_addq_r, emit_lda_n): New
+ functions for emitting single instructions, no longer requiring a
+ recursive call to md_assemble.
+ (emit_add64): New function for expanding a REG:=REG+CONST
+ operation into one or more instructions, to handle wide constants.
+ (clear_insn): New variable.
+ (md_begin): Fill it in with zeros and BFD_RELOC_NONE values.
+ (alpha_ip): Use it to initialize local variable insns.
+ (alpha_ip, label "immediate" and cases 'P', 'G'): Use emit_add64
+ for calculations.
+
+Fri Aug 26 14:46:15 1994 Ken Raeburn (raeburn@kr-laptop.cygnus.com)
+
+ * subsegs.c (section_symbol): Reverse still-wrong test of
+ EMIT_SECTION_SYMBOLS.
+
+ * write.c (BFD_FAST_SECTION_FILL): Always define.
+ (write_contents): If fill_size is 1, use memset instead of looping
+ calling memcpy.
+
+Wed Aug 24 12:46:08 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-mips.h (LOCAL_LABEL): Define as 0, for compatibility
+ with native MIPS assembler.
+ * configure.in (mips-*-irix*): Don't set emulation.
+ * config/te-irix.h: Remove.
+
+ * ecoff.c (ecoff_symbol_new_hook): Don't add a new file if we
+ haven't seen any input files yet.
+ * config/tc-alpha.c (md_begin): Just call symbol_create, rather
+ than calling symbol_new and then removing the symbol from the
+ list.
+
+ * as.c (main): Move a inside the #if 0 block which uses it.
+ * ecoff.c (current_stabs_filename): Make const.
+ * frags.h (frag_align_pattern): Declare.
+ * gasp.c (new_file): Cast isp to long, and use %ld to print it.
+ * config/tc-alpha.h (md_operand): Add cast to void.
+ (alpha_do_align): Declare argument types.
+ (tc_get_register): Declare.
+ (alpha_frob_ecoff_data): Declare.
+ * config/tc-alpha.c: Include <ctype.h>.
+ (s_mask): Don't declare; does not exist.
+ (line_comment_chars): Remove /* from descriptive comment.
+ (tc_get_register): Remove unused local reg.
+ (tc_gen_reloc): Don't bother to compare unsigned to zero.
+ (s_base): Correct warning to actually print register number.
+ (md_begin): Remove unused locals retval, lose, and i.
+ (alpha_fix_adjustable): Move default case inside switch to avoid
+ warning.
+ (load_symbol_address): Remove unused locals reloc_addr, p, sym,
+ and addend.
+ (emit_byte_manip_r): Declare types for all arguments.
+ (emit_extract_r, emit_insert_r, emit_mask_r): Likewise.
+ (emit_sign_extend, emit_bis_r, s_proc): Likewise.
+ (alpha_ip): Use sprint_value to print offsetT value. Remove
+ unused local size. Remove unused label get_macro.
+ (alpha_do_align): Make fill const.
+ (md_apply_fix): Remove unused label check_zov.
+
+ * configure.in: Recognize i586 as a synonym for i[34]86.
+
+Tue Aug 23 12:32:14 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/obj-coff.c (c_line_new): Change line_number argument from
+ unsigned short to int so that the type in the prototype matches
+ the promoted type in the definition.
+ (stack_delete): Comment out; not used.
+ * config/obj-coff.h (tc_coff_symbol_emit_hook): Declare if not
+ BFD_ASSEMBLER, not if BFD_ASSEMBLER. Declare argument type.
+ * config/tc-m68k.h (tc_coff_sizemachdep): Declare.
+ * config/tc-m68k.c (tc_coff_symbol_emit_hook): Add ignored
+ argument.
+
+Tue Aug 16 01:48:20 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/config/tc-hppa.c (pa_comm): Undo last change. Set sy_frag for
+ the common symbol to the zero address frag (the correct fix).
+
+Tue Aug 16 01:48:20 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/config/tc-hppa.c (pa_comm): Undo last change. Set sy_frag for
+ the common symbol to the zero address frag (the correct fix).
+
+ * config/tc-hppa.c (pa_comm): Set sy_resolved for the common
+ symbol.
+
+Fri Aug 12 17:51:48 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-mips.c (md_begin): Drop "el" from the end of
+ TARGET_CPU. Check for mips64orion.
+
+Tue Aug 9 19:43:45 1994 Stu Grossman (grossman@cygnus.com)
+
+ * configure.in: Recognize ppc-*-netware.
+ * config/te-ppcnw.h: New file to support Power-PC/Netware
+ configurations. Currently, it just enables the use of backslash
+ escapes in string directives.
+
+Tue Aug 9 11:12:13 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-ppc.c (ppc_stabx): Call expression directly, rather
+ than via pseudo_set. If expression is a symbol, move stab symbol
+ to just after symbol from expression.
+
+ * ecoff.c (ecoff_build_procs): Don't force adr of first fdr to be
+ zero. Undoes change of June 4, 1993.
+
+ * config/tc-mips.c (md_parse_option): Accept -mcpu=4400, 4600, and
+ orion.
+
+Mon Aug 8 16:28:08 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * as.h: Remove FOPEN_WB patch of Aug 6.
+ * configure.in: Configure for ho-go32 correctly.
+ * config/ho-go32.h: Fix copyright.
+
+Mon Aug 8 11:59:51 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/config/tc-hppa.c (md_pseudo_table): Delete redundant
+ upper-case versions of the pseudo-ops.
+
+Mon Aug 8 13:42:16 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-sparc.c (md_apply_fix): If we are going to generate a
+ non PC relative reloc, don't put the addend in the object file.
+
+Sat Aug 6 01:15:02 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * as.h: If FOPEN_WB is not defined, do the right thing in a go32
+ environment.
+
+Mon Jul 11 11:34:52 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/tc-h8300.c (pint): New function for handling varying
+ size of int pseudo op.
+ * doc/as.texinfo: Fix typo describing .h8300h pseduop.
+
+Mon Aug 1 02:40:43 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (create_new_space): Initialize sd_subspaces
+ field in the space chain.
+
+ * config/tc-hppa.c (tc_gen_reloc): Cast return value from
+ hppa_gen_reloc_type.
+
+Thu Jul 28 15:45:37 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Check more carefully for
+ conflicting architectures.
+ (md_parse_option) [NO_V9]: Complain if v9 was selected.
+ (md_show_usage): Derive architecture list in usage message from
+ architecture_pname array.
+ (cypress): Macro deleted.
+ (op_hash): Don't initialize.
+ (s_common): Use bfd_und_section_ptr instead of bfd_und_section.
+
+ * config/tc-sparc.c (BSR): New function.
+ (sparc_ip): Use it for right-shift operations of 32 bits or more.
+
+ * config/tc-sparc.c (sparc_ip): Implement new operand type 'x'.
+
+Tue Jul 26 18:21:24 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/obj-coff.h: Moved common includes and TARGET_FORMAT
+ definitions together.
+ (WORKING_DOT_WORD, WARN_SIGNED_OVERFLOW_WORD,
+ OBJ_COFF_OMIT_OPTIONAL_HEADER, BFD_HEADERS, BFD) [!BFD_ASSEMBLER]:
+ Moved these definitions to the start of the file, before the
+ includes.
+ (SYMBOLS_NEED_BACKPOINTERS, OBJ_COFF_MAX_AUXENTRIES): Always
+ define these.
+ (S_GET_ZEROES): Deleted.
+ (S_SET_ZEROES): Moved to obj-coff.c.
+
+ * config/obj-coff.c (obj_coff_* psuedo-op fns): Deleted
+ forward declarations.
+ (obj_pseudo_table): Moved to one version end of file,
+ conditionalized internally.
+ (stack typedef, stack_init, stack_delete, stack_push, stack_pop,
+ tag_hash, tag_init, tag_insert, tag_find, tag_find_or_make): Moved
+ to one combined version at top of file, unconditional. Deleted
+ forward declarations.
+ (s_get_name): Moved one copy of declarations to start of file.
+ (def_symbol_in_progress): Ditto. Don't initialize.
+ (S_SET_ZEROES): Moved here from obj-coff.h.
+ (write_object_file): If TC_COFF_SET_MACHINE is defined, call it on
+ the file headers.
+
+ * config/obj-coff.c (seg_info_off_by_4): Now const and static.
+ (SEG_INFO_FROM_SEG_NUMBER): Unused macro deleted.
+ (previous_file_symbol, def_symbol_in_progress, symbol_externP,
+ symbol_extern_lastP, last_functionP) [!BFD_ASSEMBLER]: Don't
+ bother explicitly initializing to zero value.
+
+ * config/obj-coff.c (fixup_segment) [TC_I960]: Use SF_GET_BALNAME
+ and SF_GET_CALLNAME instead of the TC_S_IS_ versions.
+
+ * config/tc-i960.h (TC_COFF_SET_MACHINE): New macro. Calls
+ tc_headers_hook.
+
+ * config/tc-i960.c (targ_has_iclass): Use I_CX | I_CX2 where I_CX
+ was used previously.
+ (tc_headers_hook): If I_CX2 is found, set flags to F_I960CA.
+
+ * config/tc-i960.c (po_hash): Declaration deleted.
+ (next_object_file_charP): Ditto.
+ (regnames, aregs, coj): Now const.
+ (parse_memop): Static array def_scale now const.
+ (md_begin): Cast away const when passing hash routines addresses
+ of values in regnames or aregs.
+ (md_longopts): Added "link-relax" and "no-relax" hyphenated forms.
+ Continue to accept one-word forms.
+ (struct tabentry, arch_tab): Moved to top level from inside
+ md_parse_option. Now const.
+ (md_show_usage): Use arch_tab to generate usage message. Print
+ hyphenated forms of relax options.
+
+ * config/tc-i960.h (DEFINE_I960_AOUT, TC_S_IS_*, TC_S_*_SYSPROC,
+ TC_S_FORCE_TO_*): Moved from here...
+ * config/tc-i960.c: ... to here. Changed DEFINE_I960_AOUT stuff
+ to test OBJ_AOUT and OBJ_BOUT directly.
+
+ * config/tc-i960.h (CTRL, COBR, COJ, REG, MEM*, FBRA, CALLJ,
+ M1-M3, REG_OPC, R_*, SFR, LIT, FP, OP, R, RS, RL, RSL, F,
+ {R,F}{,L}{2,4}, M, SFR_OK, LIT_OK, FP_OK, REG_ALIGN, MEMOP, I_*):
+ Macros deleted.
+
+ * config/tc-i960.c (ARCH_JX): Define.
+ (arch_tab): Include JX.
+ (targ_has_sfr, targ_has_iclass): Handle JX.
+ (tc_headers_hook): Set flags to F_I960JX for i960JX.
+
+Fri Jul 15 15:36:51 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * subsegs.c (section_symbol): Had last change backwards.
+
+Thu Jul 14 13:21:06 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/atof-ns32k.c: Deleted.
+
+ * config/obj-aout.c (obj_aout_frob_symbol): Use
+ bfd_ind_section_ptr and bfd_und_section_ptr.
+
+ * subsegs.c (subseg_set_rest): Compare segT values directly,
+ without casting to int first.
+
+ * config/tc-ns32k.c (md_begin): Return value from hash_insert
+ should be pointer to const. Don't call exit explicitly after
+ calling as_fatal; it won't return.
+ (convert_iif): Make local variable j be pointer to bit_fixS, since
+ that's how it's used.
+ (encode_operand, case 'b'): Ignore sprintf return value. Don't try
+ converting freeptr to int and back.
+
+ Merged in NS32K support update from Ian Dall (dall@hfrd.dsto.gov.au):
+
+ * config/te-pc532mach.h: New file. pc532-mach target emulation.
+
+ * config/te-netbsd532.h: New file. Netbsd532 target emulation.
+
+ * config/tc-ns32k.h: Add definition of NOP_OPCODE.
+
+ * config/tc-ns32k.h: Add prototype for fix_new_ns32k_exp.
+
+ * config/tc-ns32k.h: Add BFD_ASSEMBLER support.
+
+ * config/tc-ns32k.c (tc_gen_reloc): New function for BFD_ASSEMBLER.
+
+ * config/tc-ns32k.c (fix_new_ns32k_exp): Get reloc type
+ differently for BFD_ASSEMBLER.
+
+ * config/tc-ns32k.c (md_estimate_size_before_relax): Get reloc
+ type differently for BFD_ASSEMBLER.
+
+ * config/tc-ns32k.c (md_create_long_jump): Size of opcode is one
+ not 2.
+
+ * config/tc-ns32k.c (md_convert_frag): Code for the BFD_ASSEMBLER
+ case. Also use smart md_pcrel_adjust function.
+
+ * config/tc-ns32k.c (md_apply_fix): Code for the BFD_ASSEMBLER
+ case. Also use smart md_fix_pcrel_adjust function.
+
+ * config/tc-ns32k.c (md_fix_pcrel_adjust): New function which can
+ find offset from opcode to operand even if in another frag
+ and in the presence of relaxing.
+
+ * config/tc-ns32k.c (md_pcrel_adjust): New function which can
+ find offset from opcode to operand even if in another frag
+ and in the presence of relaxing.
+
+ * config/tc-ns32k.c (md_number_to_disp): Check ranges properly.
+
+ * config/tc-ns32k.c (md_atof): use atof_ieee instead of special
+ atof_ns32k.
+
+ * config/tc-ns32k.c (reloc): New (static) function for
+ BFD_ASSEMBLER.
+
+ * config/tc-ns32k.c (convert_iif): More correct pc relative code.
+ md_relax must be able to find opcode address even if in another frag.
+
+ * config/tc-ns32k.c: More extensive comments.
+
+ * config/tc-ns32k.c (encode_operand): Support new operand classes I
+ and Z. Drop Q.
+
+ * config/tc-ns32k.c (fix_new_ns32k_exp): new function and
+ corresponding prototype.
+
+ * config/tc-ns32k.c: make 32532 default machine instead of 32032.
+
+ * config/tc-ns32k.c: include opcode/ns32k.h after as.h
+
+ * aout_gnu.h: r_disp needs to be 2 bits for TC_NS32K
+
+ * write.h: fx_im_disp needs to be 2 bits big for TC_NS32K
+
+ * write.c (relax_segment): Use TC_PCREL_ADJUST macro (if defined)
+ instead of adding pcrel_adjust.
+
+ * write.c (write_object_file): Adjust to_addr for the
+ BROKEN_DOT_WORD feature for the BFD_ASSEMBLER case.
+
+ * write.c (write_object_file): Use TC_CONS_FIX_NEW if it is defined.
+
+ * write.c (write_contents): Add code (currently if
+ BFD_FAST_SECTION_FILL is defined) to make large fills a lot faster.
+
+ * configure.in: Remove ns32k from special FP list. All the ns32k
+ series use ieee float.
+
+ * configure.in: Add ns32k-pc532-mach and ns32k-pc532-netbsd targets
+
+ * as.h: include expr.h before targ-env.h. Some target dependent file
+ want to use expr structures.
+
+Wed Jul 13 14:49:05 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip): Change rp to be a const pointer.
+ (md_parse_option): Clear cpu field of current_architecture before
+ setting a new cpu type. Clear no_68881 for m68881 or m68882.
+ Clear no_68851 for m68851.
+
+Tue Jul 12 21:27:05 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/ho-sysv.h (realloc): Declare.
+
+ * symbols.c (symbol_create): New function, most of the guts of the
+ old symbol_new function.
+ (symbol_new): Now just checks symbol_table_frozen, calls
+ symbol_create, and enters the symbol into the symbol table.
+ * subsegs.c (section_symbol): If EMIT_SECTION_SYMBOLS is not true,
+ and the symbol table is frozen, call symbol_create instead of
+ symbol_new.
+ * symbols.h (symbol_create, symbol_table_frozen): Declare.
+
+ * symbols.c (symbol_clear_list_pointers): Always a function now.
+ * struc-symbol.h (symbol_clear_list_pointers): Deleted macro
+ version.
+
+ * symbols.c (debug_verify_symchain): New macro, defined to be
+ verify_symbol_chain or a cast to void, depending on DEBUG_SYMS.
+ (many functions): Invoke debug_verify_symchain unconditionally.
+
+Tue Jul 12 12:06:42 1994 Kung Hsu (kung@x1.cygnus.com)
+
+ * config/obj-ecoff.h: change calling interface of
+ OBJ_GENERATE_ASM_LINE_STAB.
+ * config/obj-elf.h: ditto.
+ * read.c (read_a_source_file): ditto.
+ * ecoff.h: change calling interface of
+ ecoff_generate_asm_line_stab.
+ * ecoff.c (add_file): record of filename to handle case of include
+ files, also change default built-in type from int to void for
+ asm file.
+ * ecoff.c (ecoff_generate_asm_line_stab): handle case of include
+ files.
+
+Mon Jul 11 17:20:23 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-mips.c (macro): In case M_LA_AB, SVR4_PIC, large
+ constant, and case ldd_std, set mips_optimize to 2 temporarily to
+ avoid inserting an unexpected nop instruction.
+
+Sat Jul 9 00:05:12 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_build_lineno): Handle count correctly for last
+ line number.
+
+Fri Jul 8 15:22:07 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * gasp.c (process_pseudo_op): Pass right args to do do_aif.
+ (get_any_string): New arg 'pretend_quote'.
+ (get_and_process, do_formals, macro_expand, do_sdata,
+ process_pseudo_op): Use new arg.
+
+Fri Jul 8 12:23:44 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * config/obj-ecoff.h: define macro OBJ_GENERATE_ASM_LINE_STAB.
+ * config/obj-elf.h: ditto.
+ * read.c (read_a_source_file): generate line stabs for asm file.
+ * read.h: add extern generate_asm_line_stab.
+ * ecoff.h : add prototype for ecoff_generate_asm_line_stab().
+ * ecoff.c (add_file): if there's no filename provided, set switch
+ to generate line stabs for .s file.
+ * ecoff.c (add_procedure): add stabs symbol for .ent directive.
+ * ecoff.c (generate_ecoff_stab): creates an artificial stabs.
+ * ecoff.c (generate_asm_line_stab): generate a artifitial label
+ for each line and generate a stabn for the line.
+
+Thu Jul 7 17:04:03 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * gasp.c (get_any_string): Cope with getting a string with an
+ alternate base specifier.
+ (do_aif, do_aelse): Only enable output if expression is true and previous
+ level was on.
+ (chartype_init): Add BASEBIT chartype.
+ (process_pseudo_op): Notice nesteed AIFs.
+
+Thu Jul 7 12:30:22 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * h8300.c (do_a_fix_imm): Code for 2 bit reloc type using in trapa
+ insn. (fix pr 5165, 5174)
+
+Thu Jul 7 11:31:32 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (R_DLT_REL): If it isn't defined, then define
+ to an appropriate value to avoid losing on old hpux systems.
+
+ * config/tc-hppa.c (hppa_fix_adjustable): Reject reductions for
+ symbols in DLT relative relocs.
+ (tc_gen_reloc): Zero out the addend field for DLT relative relocs.
+
+Wed Jul 6 01:07:54 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-ppc.c (ppc_tc): If not OBJ_COFF, force TOC entry to
+ align to a four byte boundary.
+
+Tue Jul 5 15:42:09 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-alpha.c (load_expression): Handle 32-bit addends.
+ (gpdisp_hi16_howto): Now points to const.
+ (load_insn_table, alpha_ip): Fix uses of const.
+
+ * doc/internals.texi: Updates to COFF description. Added "@end
+ defmac" as needed, and some extra heading and "@bye" so it'll
+ format as a separate document.
+
+Tue Jul 5 13:54:00 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/obj-elf.h (S_GET_ALIGN, S_SET_ALIGN): Define.
+ * config/obj-elf.c (obj_elf_common): Set alignment of common
+ symbol.
+ * config/tc-sparc.c (s_common): If OBJ_ELF, set alignment of
+ common symbol.
+
+Mon Jul 4 18:29:43 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (is_complex): New macro.
+ (cons_fix_new_hppa): "Handle" complex expressions.
+
+Fri Jul 1 00:48:12 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-coff.c (write_object_file): Set s_align field from
+ section_alignment array.
+
+Thu Jun 30 15:05:28 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * write.c (write_object_file): Use bfd_com_section_ptr.
+ * as.h (absolute_section, undefined_section): Use new BFD macros
+ bfd_abs_section_ptr and bfd_und_section_ptr.
+
+Thu Jun 30 14:36:37 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-mips.c (macro): For M_LI_SS, decide how to handle it
+ based on contents of imm_expr and offset_expr, rather than
+ mips_pic. For M_LI_DD, decide how to handle it based on segment
+ name of offset_expr, rather than mips_pic.
+ (mips_ip): If g_switch_value < 4, use immediate values for 'l'.
+ If g_switch_value < 8, use .rdata rather than .lit for 'L'.
+
+Wed Jun 29 17:30:46 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * as.c (show_usage): Break long string into shorter ones.
+ (parse_args): Add -v, prints version id and continues.
+ * config/tc-mips.c (md_show_usage): Break long string.
+
+Mon Jun 27 09:47:16 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * config/tc-i386.c (md_parse_option): Handle "-V" and "-Q" if
+ OBJ_ELF is defined.
+
+Sun Jun 26 16:30:48 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * as.c (main) [HOST_SPECIAL_INIT]: New hook, for host-specific
+ initialization.
+
+Wed Jun 22 00:24:55 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.h (obj_frob_symbol): Define for OBJ_ELF.
+ More gas/bfd lossage exposed by the new linker code.
+
+Tue Jun 21 11:32:18 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * subsegs.c (subseg_change): Clear seginfo after allocating it.
+ (subseg_get): Pass actual size of seginfo to memset.
+
+ * subsegs.c (abs_seg_info, und_seg_info): Define if BFD_ASSEMBLER.
+ (subseg_change): Store seg_info for bfd_abs_section_ptr in
+ abs_seg_info, and store seg_info for bfd_und_section_ptr in
+ und_seg_info.
+ (subseg_get): Likewise. Also, don't set output_section if it is
+ already set.
+ (seg_info): Define as function.
+ * subsegs.h (seg_info): Declare as function rather than defining
+ as macro.
+ * write.c (relax_and_size_seg): Call seg_info rather than
+ bfd_get_section_userdata.
+
+Mon Jun 20 16:30:54 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * configure.in (ppc-*-elf*): New target, like -sysv4*.
+
+ * expr.c (operand): If "0f" is followed by '\0', don't do eol
+ checks.
+
+Mon Jun 20 15:17:43 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ecoff.c (ecoff_build_aux): Call swap_tir_out and swap_rndx_out
+ via backend pointer, not directly.
+
+Fri Jun 17 18:05:06 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (config-stamp): Make sure there is at least one
+ element in the for loop.
+
+Fri Jun 17 11:01:04 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: Misc trivial changes to make gcc -Wall happy.
+
+ * config/tc-hppa.h (elf_hppa_final_processing): Declare.
+
+Wed Jun 15 20:44:46 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * as.c (parse_args): Cast xmalloc return value.
+
+ * Makefile.in (config-stamp): If $(defs) contains multiple words,
+ emit a #define line for each.
+ * configure.in: For sparc64 target, use sparc cpu files and add
+ sparcv9 to extra_defs. No longer treat sparc64-*-aout* specially.
+
+ * config/tc-sparc.c (membar_masks): Now static and const.
+ (md_show_usage) [!NO_V9]: Add -Av9 to usage message.
+ (current_architecture) [sparcv9]: Initialize to v9.
+ (md_begin) [sparcv9]: Don't bother changing it unconditionally
+ here.
+ (s_reserve): Don't pass unexpected argument to as_bad with
+ bad-segment message.
+
+ * as.h (bfd_alloc_by_size_t) [BFD_ASSEMBLER]: Declare.
+
+ * config/atof-ieee.c (int_to_gen): Commented out unused routine.
+
+ * config/tc-vax.c (md_assemble): Removed check of operand section.
+
+ Fri Jun 3 17:25:08 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.h (DBG_S_C_COMPLX4, DBG_S_C_COMPLX8): define
+ these new VMS symbol-type macros for `complex float' and
+ `complex double' support. Their values come from the existing
+ DSC$K_DTYPE_FC and DSC$K_DTYPE_DC macros in <descrip.h>.
+ (DBG_S_C_REAL8_G, DBG_S_C_COMPLX8_G): G_float versions of
+ REAL8 and COMPLX8; not used yet, because gcc outputs the same
+ .stabs for `double' regardless of whether `-mg' is used.
+ * config/obj-vms.c (VMS_typedef_parse) [case 'r']: add entries
+ for gcc2's predefined types "complex float", "complex double",
+ and "complex long double" (identical to complex double).
+
+Wed Jun 15 12:32:55 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-coff.c (coff_frob_symbol): Use C_STAT for the .text
+ section symbol, not C_LABEL.
+
+ * config/tc-mips.c (mips_ip): Permit a modifier in 'o' case, and
+ permit non constant expressions in 'u' case. Lets ``lui
+ $8,%hi(foo); lw $8,%lo(foo)($8)'' work correctly.
+
+Mon Jun 13 12:08:52 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-aout.c (obj_aout_frob_symbol): Warn about an attempt
+ to put a common symbol in a set.
+
+Sat Jun 11 16:41:21 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Add weak symbols as an extension to a.out.
+ * read.c (pseudo_set): Only preserve external bit for OBJ_AOUT and
+ OBJ_BOUT if not BFD_ASSEMBLER.
+ * config/aout_gnu.h (N_WEAKU, N_WEAKA, N_WEAKT, N_WEAKD, N_WEAKB):
+ Define as in ../include/aout/aout64.h.
+ * config/obj-aout.h (OBJ_SYMFIELD_TYPE): If not BFD_ASSEMBLER,
+ define as char.
+ (S_GET_WEAK, S_SET_WEAK): Define if not BFD_ASSEMBLER.
+ * config/obj-aout.c (obj_pseudo_table): Add "weak".
+ (obj_emit_symbols): Adjust type of weak symbols.
+ (obj_aout_weak): New static function.
+
+Fri Jun 10 13:48:49 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-elf.c (obj_elf_section): Don't set any flags based on
+ the type of a special section.
+
+ * config/ho-sunos.h: Include <stdlib.h>. Don't declare malloc,
+ realloc, free, or atol.
+
+Wed Jun 8 06:28:37 1994 Bill Cox (bill@cygnus.com)
+
+ * Makefile.in (check): Delete as.new dependency, so that
+ regression test doesn't trigger an assembler build.
+
+Tue Jun 7 13:33:18 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (mostlyclean, realclean): New targets.
+ * doc/Makefile.in, testsuite/Makefile.in: Likewise.
+
+Mon Jun 6 13:10:54 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (RDATA_SECTION_NAME): Define.
+ (macro): Correct M_LI_SS SVR4_PIC/EMBEDDED_PIC case. After M_LI_D
+ or M_L_DOB or label dob, force a new frag to avoid getting
+ confused in tc_gen_reloc.
+ (mips_ip): Use RDATA_SECTION_NAME, not .rdata.
+ (s_change_sec): Likewise.
+
+Fri Jun 3 23:35:36 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * read.c (emit_expr): Use memset to zero out memory, rather than
+ going through md_number_to_chars. This permits handling symbolic
+ arguments when the size is larger than sizeof (valueT), if
+ TC_CONS_FIX_NEW is prepared to handle the case (as it is on MIPS).
+
+Fri Jun 3 12:50:13 1994 David J. MacKenzie (djm@rtl.cygnus.com)
+
+ * as.c (show_usage), config/tc-alpha.c (md_show_usage),
+ config/tc-mips.c (md_show_usage): Fix up messages.
+
+ * as.h: Replace flagseen with separate variables.
+ * as.c (parse_args): Set them. Don't accept -1 option, or -v
+ explicitly (it's a synonym for --version).
+ * as.c, input-scrub.c, messages.c, read.c, symbols.c, write.c,
+ config/obj-aout.c, config/obj-aout.h, config/obj-bout.c,
+ config/obj-bout.h, config/obj-coff.c, config/obj-coff.h,
+ config/obj-vms.c, config/tc-hppa.c, config/tc-i386.c,
+ config/tc-i960.c, config/tc-m68k.c, config/tc-mips.c,
+ config/tc-vax.c: Use the new flag variables instead of flagseen.
+ * config/tc-vax.c [OBJ_VMS]: Recognize -+, -1, -v, and document in
+ usage.
+
+ * as.c (show_usage): Remove target specific messages;
+ instead, call md_show_usage.
+ (parse_args): Use getopt_long_only. Take pointers to argc and
+ argv.
+ (main): Pass parse_args pointers.
+ * as.h: Remove 3 variables that are redundant with flagseen.
+ * as.c, messages.c: Change their users to use flagseen.
+ Define getopt stuff.
+ * tc.h: Update md_parse_option decl. Add md_show_usage decl.
+ * config/tc-*.c: Add md_shortopts, md_longopts,
+ md_longopts_size, md_show_usage. Change calling convention for
+ md_parse_option. Remove md_parse_long_option.
+ * config/tc-ns32k.c: Rename `struct option' to `struct ns32k_option'.
+ * config/tc-i386.h: Don't define md_parse_option.
+
+Thu Jun 2 13:54:46 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * as.c (show_usage): New function.
+ (parse_args): Code moved from main.
+ Recognize --help and --version.
+ * config/tc-ns32k.h: Define TC_NS32K.
+ * doc/as.texinfo: Document all of the target-independent command
+ line options.
+
+Thu Jun 2 12:07:25 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * gasp.c (hash_new_table): Clear newly allocated table.
+
+ * config/tc-m68k.c (enum _register): Add 68060 control registers
+ BUSCR and PCR.
+ (last_movec_reg): New macro.
+ (m68000_control_regs, m68010_control_regs, m68020_control_regs,
+ m68040_control_regs, m68060_control_regs): New arrays.
+ (control_regs): New pointer.
+ (m68k_ip): Use control_regs instead of testing CPU every time.
+ Use last_movec_reg too. In error messages, handle 68060, and
+ print 68060 for mfloat, too.
+ (m68k_init_after_args): Handle "68060". Use m68040up for making
+ m68851 choice. Set control_regs.
+ (md_parse_option): Handle "68060".
+ * configure.in: Setting cpu_type, recognize m68060 too.
+
+ * config/obj-coff.c (fixup_segment) [!BFD_ASSEMBLER]
+ [DIFF_EXPR_OK]: Do conversion to pc-relative for difference, even
+ if pcrel is already set.
+
+ * read.c (potable): Add this_gcc_requires_the_gnu_assembler in all
+ lower-case, in case we're ignoring case of opcodes in the input
+ file.
+
+ * doc/as.texinfo (.section): Document as unavailable for a.out
+ type formats.
+
+ * config/tc-alpha.c (machine): New variable.
+ (load_insn): New macro.
+ (load_insn_table): New function.
+ (md_begin): Call load_insn_table, once for basic instructions and
+ once for appropriate PAL instruction table.
+ (md_parse_option): Set `machine' based on -m##### arguments.
+ * config/alpha-opcode.h (alpha_pal21064_opcodes): Split out from
+ alpha_opcodes.
+ (alpha_pal21164_opcodes): New table.
+ (NUM21064OPCODES, NUM21164OPCODES): New macros.
+
+ * configure.in (target i386-*-netbsd0.8): Use 386bsd emulation.
+
+ * doc/Makefile.in (install-info-gasp): Use $$dir when installing
+ file.
+
+Wed Jun 1 10:48:19 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Force floating point values to be
+ aligned correctly.
+
+Fri May 27 10:05:53 1994 Ken Raeburn (raeburn@cygnus.com)
+
+ Merged in changes from gas-2.3 net release:
+
+ * Makefile.in (VERSION): Updated to cygnus-2.3.1.
+
+ * config/obj-vms.c: Replaced unchecked uses of malloc with
+ xmalloc.
+
+ * listing.c (list_symbol_table): Only test BFD64, not
+ BFD_ASSEMBLER too.
+
+ * config/obj-coff.c (fixup_segment) [BFD_ASSEMBLER]
+ [DIFF_EXPR_OK]: Don't check pcrel, just convert it.
+
+ * config/obj-vms.c: Removed lots of extra semicolons after
+ compound statements.
+ (strchr): Don't declare here.
+
+ * config/ho-vax.h (realloc): Declare.
+
+ * config/ho-vms.h (strchr, strdup): Declare.
+
+ * config/tc-sparc.c (md_parse_option) [OBJ_ELF]: Accept and ignore
+ option `-q'.
+
+ Wed May 18 20:50:35 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.h (DBG_S_C_SQUAD, DBG_S_C_UQUAD): define these
+ new VMS symbol-type macros; signed and unsigned quadword integers,
+ for `long long' support. Their values come from the existing
+ DSC$K_DTYPE_QU and DSC$K_DTYPE_Q macros in <descrip.h>. The
+ VMS debugger now recognizes `long long' variables correctly.
+ * config/obj-vms.c (VMS_typedef_parse) [case 'r']: add entries
+ for gcc2's predefined types "long double" (same as double, as
+ per gcc's current state), "long long int", "long long unsigned
+ int", and final `otherwise' case (to avoid uninitialized type
+ and size fields). [caveat: predefined types "complex int",
+ "complex float", "complex double", and "complex long double" are
+ still missing.]
+
+ * config/ho-vms.h (EXIT_FAILURE): define as 0x10000002 instead
+ of 0, because the latter indicates success rather than failure
+ when passed to `exit' or return from `main' compiled by gcc2.
+
+ * config/obj-vms.c (array_suffix, generate_suffix): replace two
+ hardcoded `0xa3's with macro DBG_S_C_ADVANCED_TYPE from obj-vms.h.
+ (VMS_typedef_parse): eliminate redundant if-then-else when
+ allocating new symbol entry and linking it to VMS_Symbol_type_list.
+
+ Tue May 17 20:47:31 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.c (Write_VMS_MHD_Records): don't try to interpret
+ the contents of the GAS_VERSION string when falling back to it for
+ language processor identification.
+
+ * make-gas.com, vmsconf.sh (ENVIRON): fix misspelling of
+ `psect_attr' in linker options.
+
+ Wed May 11 22:32:00 1994 DJ Delorie (dj@ctron.com)
+
+ * configure.bat: update to latest makefile.in
+ * config/te-go32.h: [new] go32's environment
+
+Fri May 20 17:59:34 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * as.h: Don't declare parameters for strstr.
+
+Thu May 19 15:40:13 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-sparc.c (md_section_align): Don't change the size if
+ OBJ_ELF.
+
+Wed May 18 13:08:07 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (install): Redirect ln output to /dev/null. If ln
+ fails on gasp, install gasp.new, not gasp.
+
+Wed May 18 09:16:36 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip): Use R_HPPA_ABS_CALL, not R_HPPA for
+ absolute calls.
+
+Tue May 17 12:50:46 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_parse_fp_cmp_cond): Report an error
+ on a partial completer match.
+
+Mon May 16 12:03:49 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: Change .hppa_unwind to .PARISC.unwind
+ throughout code.
+ (is_complex): Delete definition and support for complex relocation
+ types.
+ (tc_gen_reloc): Delete special unwind crud for ELF. Simplify and
+ rewrite ELF code based on 94-02-02 PA ELF draft spec.
+ (pa_build_unwind_subspace): Use standard PARISC_DIR32 relocs for
+ the unwind descriptors.
+
+Fri May 6 14:13:15 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * config/go32.mh: New makefile fragment for go32 crossing.
+ * configure.in (host==go32): Use new fragment.
+
+Fri May 6 14:35:58 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * gasp.c: Include libiberty.h.
+ (main): Remove unused variable i.
+
+ * config/tc-ppc.c (md_begin): When using -many, permit comparison
+ instructions to appear multiple times in the opcode table.
+
+Thu May 5 19:14:43 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * Makefile.in (VERSION): Update to 2.2.90.
+
+ * symbols.c (symbol_new) [BFD_ASSEMBLER]: Don't permit additions
+ to the symbol table if it's already been set in the output bfd.
+ (symbol_begin) [! EMIT_SECTION_SYMBOLS] [RELOC_REQUIRES_SYMBOL]:
+ Don't use bfd_abs_section.symbol for gas absolute symbol.
+
+ * doc/Makefile.in (distclean, clean-dvi, clean-info): Delete gasp
+ files too.
+
+Thu May 5 18:12:51 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_emit_delays): Make call to
+ mips_no_prev_insn unconditional.
+
+Thu May 5 17:25:38 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/obj-coff*.*: Merged coffbfd versions into coff versions,
+ with a single "#ifdef BFD_ASSEMBLER" controlling most of it for
+ now. Deleted obj-coffbfd.* files.
+ * configure.in: Always use obj-coff.* for COFF targets.
+
+Wed May 4 13:34:11 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/te-dpx2.h (TARGET_FORMAT, REGISTER_PREFIX_OPTIONAL):
+ Define.
+ * configure.in (m68k-bull-sysv3*): Enable.
+
+ * config/coff_gnu.h: Deleted.
+
+Wed May 4 11:29:17 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-m68k.h (TARGET_FORMAT): If not TE_SUN3, define as
+ "a.out-zero.big".
+
+ * config/obj-coffbfd.c (fixup_segment): Make common symbol and PC
+ relative adjustments when TE_LYNX is defined as well as when
+ TC_I386 is defined.
+
+Wed May 4 02:29:21 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * as.h (strstr): Restore declaration.
+ (subseg_get) [BFD_ASSEMBLER]: Declare.
+
+ * write.c (write_object_file): If obj_adjust_symtab is defined,
+ invoke it. Then call set_symtab, and finally invoke *_frob_file
+ hooks.
+ * config/obj-coff.c (coff_adjust_symtab): Renamed from
+ coff_frob_file.
+ * config/obj-coff.h (coff_adjust_symtab): Changed declaration
+ accordingly.
+ (obj_adjust_symtab): Macro also changed.
+
+ * configure.in (i386-*-gnu*): New target, handled like i386-mach.
+
+Tue May 3 21:04:16 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/obj-coff.h (TARGET_FORMAT) [TC_I960]: Select little
+ endian version.
+
+ * config/obj-coffbfd.h (TARGET_FORMAT) [TC_I960]: Ditto.
+
+ * config/obj-coff.c (coff_frob_section): Round up the size of
+ every section to a multiple of the alignment, so that BFD doesn't
+ surprise us.
+
+ Eliminate many simple differences between the two COFF back ends:
+
+ * config/obj-coffbfd.c: Removed all uses of DEFUN and DEFUN_VOID.
+ Made minor stylistic changes, deleted some register declarations.
+ (stack_top): Deleted.
+ (symbol_to_chars): Use absolute_section and reg_section instead of
+ the corresponding SEG_* symbols.
+ (obj_coff_endef, tag_find_or_make, fixup_segment): Likewise.
+ (stack typedef, stack_init, stack_delete, stack_push, stack_pop):
+ Moved to just after pseudo-op table. All functions now static.
+ (stack_delete): Removed declaration.
+ (tag_init, tag_insert, tag_find_or_make, tag_find): Moved to just
+ after stack functions.
+ * config/obj-coffbfd.h: Reordered some declarations and macros.
+ (stack_init, stack_delete, stack_push, stack_pop): Don't declare.
+ (stack typedef): Deleted.
+ (SYMBOLS_NEED_BACKPOINTERS): Always undef then define; don't test.
+ (SYM_AUXENT): New macro.
+ (SA_GET_*, SA_SET_*): Define in terms of SYM_AUXENT when feasible.
+ (SF_GET_*, SF_SET_*): Define in terms of SF_GET when feasible.
+ (SA_GET_SYM_TAGNDX, SA_GET_SYM_ENDNDX, SA_SET_SYM_TAGNDX,
+ SA_SET_SYM_ENDNDX, object_headers typedef, data_section_header,
+ text_section_header): Delete non-BFD_HEADERS versions, since we
+ always define that symbol now.
+
+ * config/obj-coff.c (stack_top): Deleted.
+ (obj_coff_endef, obj_coff_dim, obj_coff_line, obj_coff_size,
+ obj_coff_scl, obj_coff_tag, obj_coff_type, obj_coff_val): Change
+ argument name from "ignored" to "ignore".
+ (obj_coff_val): Use frag_now_fix.
+ (obj_pseudo_table): Removed IGNORE_DEBUG version, since it doesn't
+ get used.
+ (stack typedef, stack_init, stack_delete, stack_push, stack_pop):
+ Moved to just after pseudo-op table. All functions now static.
+ (tag_init, tag_insert, tag_find_or_make, tag_find): Moved to just
+ after stack functions.
+ * config/obj-coff.h: Reordered some declarations and macros.
+ Protected against multiple inclusions.
+ (stack_init, stack_delete, stack_push, stack_pop): Don't declare.
+ (stack typedef): Deleted.
+ (SYMBOLS_NEED_BACKPOINTERS): Always undef then define; don't test.
+ (stdoutput): Deleted declaration.
+ (TARGET_FORMAT) [TC_I386]: Don't define if already defined.
+
+Mon May 2 17:09:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * subsegs.h (segment_info_type): Use fix_tail field even if
+ BFD_ASSEMBLER.
+ * subsegs.c (subseg_change): Initialize fix_tail field.
+ (subseg_get): Likewise.
+ * write.c (frags_chained): New static variable.
+ (fix_new_internal): If frags_chained is set, use fix_root and
+ fix_tail from seg_info (now_seg), rather than frchain_now.
+ (chain_frchains_together_1): Set fix_tail field.
+ (chain_frchains_together): Set frags_chained.
+
+Thu Apr 28 01:39:15 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config/tc-mips.c (s_option): Only refer to g_switch_* variables
+ if GPOPT is defined.
+ (s_abicalls): Ditto.
+ (md_apply_fix): Cast char* to unsigned char* to avoid pointer
+ mismatch.
+
+Wed Apr 27 11:06:32 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * configure.in (i386-*-go32): Uses coff now.
+ * gasp.c (main): Now takes -D on command line.
+ (show_usage): Describe new options.
+
+Tue Apr 26 17:10:30 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * listing.c (list_symbol_table): Print "NO DEFINED SYMBOLS" and
+ "NO UNDEFINED SYMBOLS" if there aren't any, instead of displaying
+ the header with an empty list.
+
+ * config/obj-coffbfd.c (fill_section): Check COFF_NOLOAD_PROBLEM
+ also before setting STYP_NOLOAD for .bss section.
+
+ * config/tc-m68k.c (flag_reg_prefix_optional): New variable.
+ Initialized to value of REGISTER_PREFIX_OPTIONAL, if defined, or
+ zero.
+ (m68k_reg_parse): If flag_reg_prefix_optional is set, permit
+ register prefix to be absent.
+ (m68k_ip_op): Accept `&' also for immediate constants.
+ (insert_reg): Don't bother with (two!?) sanity checks of the
+ symbol table when inserting each register.
+ (m68k_parse_long_option): New function. Set
+ flag_reg_prefix_optional if "register-prefix-optional" is passed.
+ * config/tc-m68k.h (REGISTER_PREFIX): Always define if not already
+ defined.
+ (OPTIONAL_REGISTER_PREFIX): Don't define.
+ (REGISTER_PREFIX_OPTIONAL): If not already defined, define as zero
+ or one depending on M68KCOFF.
+
+ Some changes to help Apollo support, from troy@cbme.unsw.edu.au:
+ * config/tc-m68k.c (DATA, ADDR, SP, FPREG, COPNUM, BAD, BAC):
+ Define as macros instead of enumerators, since the Apollo compiler
+ can't handle "enumVal1, enumVal2 = enumVal1" when defining an enum
+ type.
+ (make_pcrel_absolute) [NO_PCREL_RELOCS]: New function.
+ (tc_coff_fix2rtype) [NO_PCREL_RELOCS]: Generate only R_RELBYTE,
+ R_DIR16, and R_DIR32 relocs.
+ * config/tc-m68k.h [TE_APOLLO] (COFF_MAGIC, COFF_AOUTHDR_MAGIC):
+ Use Apollo versions.
+ [TE_APOLLO] (OBJ_COFF_OMIT_OPTIONAL_HEADER): Undefine. That is,
+ do include the optional header for Apollo target.
+ (COFF_MAGIC): Don't define as MC68MAGIC if it's already defined.
+
+ * config/tc-m68k.h [TE_DELTA] (LEX_PCT): Define as 1, so that `%'
+ can be used within a label name.
+
+ * config/tc-m68k.h (m68k_init_after_args): Declare.
+ (tc_init_after_args): Define as m68k_init_after_args.
+ * config/tc-m68k.c (m68k_init_after_args): New function,
+ containing one-shot code from md_assemble. Added warning for
+ combination of 68040 and 68851.
+ (md_assemble): Startup-time code deleted.
+
+Mon Apr 25 16:19:17 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * doc/Makefile.in (clean, distclean): Remove asconfig.texi.
+
+Sun Apr 24 00:13:08 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip): 13 bit immediate constant (for break
+ instruction) is unsigned.
+
+Fri Apr 22 17:58:22 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-ecoff.c (ecoff_frob_file): Use bfd_ecoff_set_gp_value
+ and bfd_ecoff_set_regmasks to set the GP value and the register
+ masks, rather than using the now obsolete fake .reginfo section.
+
+Fri Apr 22 15:17:06 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * listing.c (list_symbol_table): Don't print register symbols as
+ undefined.
+
+ * config/obj-coff.c (obj_symbol_new_hook): Don't need to strip
+ underscores, since symbol_new will already have done it.
+ * config/obj-coffbfd.c (obj_symbol_new_hook): Ditto.
+
+ * as.c (main): If tc_init_after_args is defined, invoke it after
+ all arguments have been processed.
+
+ Some changes to help Apollo support, from troy@cbme.unsw.edu.au:
+ * as.c (perform_an_assembly_pass) [TE_APOLLO]: Create .wtext
+ section instead of .text. Call create_target_segments.
+ * read.c (demand_copy_string): No longer static.
+
+Thu Apr 21 15:50:04 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (append_insn): Permit branches to be switched
+ with the preceding instruction even if .set nobopt has been seen.
+ .set nobopt actually controls whether to bring up an instruction
+ from the branch target, which gas does not currently support.
+
+Wed Apr 20 18:46:14 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/obj-coff.h, config/obj-coff.c: Deleted all code used only
+ when BFD_ASSEMBLER is not defined, and all conditionals relating
+ to such code. No such targets remain.
+
+ Fixes for stabs-in-coff:
+ * config/obj-coff.c: Include subsegs.h.
+ (coff_frob_section): New function.
+ (obj_coff_init_stab_section): New function.
+ * config/obj-coff.h (obj_coff_init_stab_section,
+ coff_frob_section): Declare.
+ (obj_frob_section): New macro; uses coff_frob_section.
+ (INIT_STAB_SECTION): New macro; uses obj_coff_init_stab_section.
+
+ * config/tc-sparc.c (md_section_align): Always round up to
+ multiple of alignment power specified in bfd target vector.
+
+ * gasp.c: Include ctype.h.
+
+Mon Apr 18 21:08:01 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * doc/Makefile.in, doc/as.texinfo: Renamed asdoc-config.texi to
+ asconfig.texi.
+
+ * doc/Makefile.in (install-info-as, install-info-gasp): Get file
+ names from source directory without pathname.
+
+ * config/obj-vms.c (VMS_write_object_file): While looking for
+ register mask, skip empty fill frags caused by enabling listing
+ output.
+
+ * config/ho-sysv.h: Include string.h.
+
+ * doc/internals.texi: New (well, recently added) file. Just added
+ info on as_warn and friends.
+
+Mon Apr 18 14:28:22 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_parse_space_stmt): Use the built-in
+ defaults for defined, private, and spnum fields for the
+ $TEXT$ and $PRIVATE$ spaces. Do not clobber spnum. Do
+ not reset the segment if just updating a space.
+ (pa_spaces_begin): Set BFD section flags for all built-in
+ subspaces.
+
+Fri Apr 15 10:51:51 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (first_proc_ptr): New static variable.
+ (add_procedure): Set first_proc_ptr if it hasn't been set.
+ (ecoff_build_lineno): If the first procedure does not start at
+ address zero, insert a dummy line to compensate.
+
+ * Makefile.in (bootstrap, bootstrap2, bootstrap3): Make gasp.new
+ as well as as.new.
+
+Thu Apr 14 15:12:36 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * expr.c (operand): Try to parse "0f" and "0b" sequences as
+ floating point and binary numbers respectively; if it doesn't
+ work, treat them as local labels.
+
+ * Makefile.in: Make $(OBJS) depend on $(ALL_OBJ_DEPS).
+ * configure.in: Set ALL_OBJ_DEPS in output Makefile.
+
+ Based on suggestions from <BAILEY@hmivax.humgen.upenn.edu>
+ (Charles Bailey):
+ * vmsconf.sh: In generated file, get ".obj" suffix right, build
+ source files from other directories into objects in the current
+ directory, and specify PSECT attributes explicitly to linker.
+ Also added missing label.
+ * Makefile.in (stamp-mk.com): Reference new variable
+ VMS_OTHER_OBJS for list of non-local object files, instead of
+ listing them here.
+ (VMS_OTHER_OBJS): New variable, added more libiberty files.
+ * make-gas.com: Regenerated.
+
+ * config/ho-vms.h (unlink): Define as delete.
+
+ * config-gas.com: Fix quoting on TARGET_CANONICAL definition.
+ Delete files before creating them.
+
+Thu Apr 14 13:34:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (de-stage1, de-stage2, de-stage3): Use rm -f.
+
+ * config/tc-mips.h (DIFF_EXPR_OK): Define.
+ * config/tc-mips.c (macro_build): Permit BFD_RELOC_PCREL_LO16 for
+ certain cases of 'i', 'j' and 'o'. Change 'u' to take an
+ argument, the reloc type.
+ (load_register): Pass reloc type to macro_build for 'u'.
+ (macro): Likewise. For M_LA_AB permit a difference expression
+ when generating embedded PIC code between an arbitrary symbol and
+ a symbol in the .text section.
+ (mips_force_relocation): Force BFD_RELOC_PCREL_HI16_S and
+ BFD_RELOC_PCREL_LO16 to be emitted.
+ (md_apply_fix): Check that most relocs are not PC relative.
+ Handle BFD_RELOC_PCREL_HI16_S and BFD_RELOC_PCREL_LO16.
+ (tc_gen_reloc): Change #error to as_fatal. Handle
+ BFD_RELOC_PCREL_LO16 and BFD_RELOC_PCREL_HI16_S.
+
+Tue Apr 12 18:25:13 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * subsegs.c (subsegs_begin): Call memset with args in the correct
+ order.
+ (subseg_get): Clear newly allocated seginfo, set its pointer slots
+ to NULL instead of 0.
+
+Mon Apr 11 09:00:57 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_procend): Handle case where label was
+ defined after the .proc directive.
+
+ * config/tc-hppa.c (pa_procend): Give an error if we encounter a
+ procend for a procedure without a name.
+
+Thu Apr 7 14:28:30 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (macro): Pass NULL for expression argument to
+ macro_build for nori case.
+ (SWITCH_TABLE): Define.
+ (mips_force_relocation): Force a relocation for a switch table
+ entry.
+ (md_apply_fix): Write switch table entry value into file.
+ (tc_gen_reloc): Use BFD_RELOC_GPREL32 for a switch table entry,
+ and set the addend to the difference between the reloc address and
+ the subtrahend.
+
+Thu Apr 7 10:38:18 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.h (elf_tc_symbol): Delete. No longer used.
+ (elf_tc_make_sections): Likewise.
+ (hppa_tc_make_sections, hppa_tc_symbol): Delete extern decls.
+
+ * config/tc-hppa.c (hppa_tc_make_sections): Delete function.
+ (hppa_tc_symbol): Likewise.
+
+ * config/obj-elf.c (elf_frob_file): Delete elf_tc_symbol and
+ elf_tc_make_sections stuff. It was there to support PA braindamage
+ which has been fixed, and in the case of elf_tc_make_sections is
+ redundant with elf_tc_final_processing.
+
+Wed Apr 6 20:48:30 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * configure.in (hppa*-*-*elf*): Don't require "-hp-" for the
+ manufacturer.
+
+Tue Apr 5 15:48:03 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_ip): For case 'o', when generating
+ embedded PIC code, accept the difference between two local symbols
+ as being constant.
+ (mips_force_relocation): Only force a reloc to be generated for a
+ PC relative fixup.
+ (md_apply_fix): For BFD_RELOC_32 and BFD_RELOC_LO16, put the fixup
+ value into the file if the fixup will not generate a reloc.
+
+Tue Apr 5 11:14:14 1994 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * config/tc-sparc.c (s_reserve): If section passed isn't bss,
+ don't spew remainder of input file in error message.
+ (tc_gen_reloc): If bfd_reloc_type_lookup returns null, print error
+ message with reloc type and try to process remainder of file.
+
+ * doc/Makefile.in (install-info-as, install-info-gasp): New
+ targets, now explicitly checking $(srcdir) for info files.
+ (install-info): Depend on both of them; do nothing more.
+
+Mon Apr 4 17:06:04 1994 Jeffrey A. Law (law@cygnus.com)
+
+ * config/tc-hppa.c (tc_gen_reloc): Fix thinko in ELF version.
+
+Mon Apr 4 12:39:23 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-ppc.c (ppc_insert_operand): Check PPC_OPERAND_SIGNED
+ flag rather than signedp field. Only permit extended range if
+ PPC_OPERAND_SIGNOPT flag is set and assembling in 32 bit mode.
+ Based on patch from David Edelsohn (edelsohn@npac.syr.edu).
+
+ * config/tc-ppc.c (ppc_size): New static variable.
+ (ppc_arch): Check for PPC_OPCODE_PPC before PPC_OPCODE_POWER.
+ (md_begin): If an instruction has a size specific flag set, only
+ add it if we are assembling that size.
+
+Thu Mar 31 16:51:16 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-sparc.c (tc_gen_reloc): Add a gruesome hack to get
+ cross section PC relative relocs right for COFF and ELF.
+
+Mon Mar 28 14:38:23 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/obj-coff.h (SEPARATE_STAB_SECTIONS): Always define.
+ (OBJ_PROCESS_STAB): Don't define.
+
+Mon Mar 28 12:40:25 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-aout.c (obj_aout_frob_symbols): Don't let BFD clobber
+ the type of symbol set symbols which happen to be in the absolute
+ or undefined section.
+
+Mon Mar 28 12:35:00 1994 David Edelsohn (edelsohn@npac.syr.edu)
+
+ * config/tc-ppc.c (md_parse_option): Add -mpwrx (POWER/2 aka
+ RIOS2), -mpwr (POWER aka RIOS1), -mppc (PowerPC aka MPC603/604),
+ and -many (all architectures).
+
+Sun Mar 27 14:04:19 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (tc_gen_reloc): Set addend for relocation
+ involving a function symbol which is not a plabel to zero.
+ (md_apply_fix): Never pass a function symbol to field_adjust.
+
+Fri Mar 25 17:35:49 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-aout.c (obj_aout_frob_symbol): If N_EXT is set for an
+ N_INDR symbol, set BSF_EXPORT and clear BSF_LOCAL.
+
+ * config/tc-mips.c (append_insn): If EMBEDDED_PIC, don't swap a
+ branch with an instruction that uses $at, in case the branch is
+ later expanded.
+ (macro): If EMBEDDED_PIC, case M_JAL_A may use $at.
+ (md_pcrel_from): If not OBJ_AOUT, return 4 for an undefined symbol
+ to make it pcrel_offset.
+ (tc_gen_reloc): If not OBJ_AOUT, set the reloc addend to
+ reloc->address; another gruesome hack to get gas reloc handling to
+ do the right thing.
+
+Thu Mar 24 21:29:29 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-alpha.c (alpha_ip): Only set GP prolog size if using
+ PV register.
+ (T12): New macro.
+ (emit_insn): New function.
+ (md_assemble): Call it.
+ (alpha_force_relocation): Handle BFD_RELOC_26, for call_pal
+ instructions.
+ (lituse_pending): New variable. Set by anything that generates a
+ LITERAL reloc, cleared by anything that generates a LITUSE reloc,
+ tested by code that might want to emit a LITUSE reloc.
+ (emit_unaligned_io): New function. Currently calls md_assemble,
+ but it should eventually be converted to generate the insn itself
+ and call emit_insn directly.
+ (emit_load_unal, emit_store_unal, emit_byte_manip_r,
+ emit_extract_r, emit_insert_r, emit_mask_r, emit_sign_extend,
+ emit_bis_r): Likewise.
+ (alpha_ip, case 'I'): Handle with BFD_RELOC_23.
+ (alpha_ip, label get_macro): Don't emit the final instruction if
+ the opcode is zero.
+ (alpha_ip, case 'B', subcase 'd'): New case, for subword and
+ unaligned memory access macros.
+ (md_apply_fix): Handle BFD_RELOC_26. Generate an error message if
+ the value can't be resolved.
+
+Wed Mar 23 16:06:08 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (md_parse_option): For -membedded-pic, force
+ the -G value to 0x7fffffff. For SVR4 PIC options, don't call
+ bfd_set_gp_size here, it's done in md_begin. Don't permit -G with
+ -membedded-pic.
+ (mips_force_relocation): New function.
+ (md_apply_fix): Set fixP->fx_done appropriately.
+ (s_change_sec): For EMBEDDED_PIC, change .data and .rdata to
+ .sdata.
+ * config/tc-mips.h (TC_FORCE_RELOCATION): Define.
+ (mips_force_relocation): Declare.
+ (TC_HANDLE_FX_DONE): Define.
+
+Tue Mar 22 13:58:37 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (enum mips_pic_level): New enum.
+ (mips_pic): Change from int to enum mips_pic_level. Change all
+ uses (0 becomes NO_PIC, 2 becomes SVR4_PIC).
+ (load_address): Handle EMBEDDED_PIC.
+ (macro): Handle EMBEDDED_PIC in all PIC cases.
+ (md_parse_option): Accept -membedded-pic to use EMBEDDED_PIC. If
+ OBJ_ELF, accept -KPIC and -call_shared to use SVR4_PIC and accept
+ -non_shared to use NO_PIC (this is how the Irix 5 assembler
+ works). Do not permit -G with SVR4_PIC.
+ (s_abicalls): Warn if -G was used, and force -G 0.
+ (tc_gen_reloc): Set reloc->addend to 0 for a PC relative reloc for
+ anything but a.out, not just for ELF. For ECOFF, don't generate a
+ BFD_RELOC_16_PCREL_S2 reloc unless using EMBEDDED_PIC.
+
+ * config/obj-ecoff.h (obj_sec_sym_ok_for_reloc): Define to be 1.
+
+Sun Mar 20 16:31:55 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (create_new_space): Use ints, not chars as
+ parameters to avoid losing when compiling with HP CC.
+ (create_new_subspace, update_subspace, fix_new_hppa): Likewise.
+
+Sun Mar 20 14:43:14 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * Makefile.in (config-stamp): If `defs' is defined, emit a
+ preprocessor directive to create a macro named by this value into
+ config.new; don't explicitly go for BFD_ASSEMBLER.
+ * configure.in: Define `defs', not `BFDDEF'. Set it to
+ MANY_SEGMENTS for any obj-coffbfd target.
+ * config/obj-coffbfd.h (BFD_HEADERS, BFD): Define.
+ * config/i386coff.mt (TDEFINES): Don't define BFD, MANY_SEGMENTS,
+ or BFD_HEADERS.
+ (LOCAL_LOADLIBES): Deleted.
+ * config/m68kcoff.mt (TDEFINES): Don't define those macros.
+ * config/m88kcoff.mt (TDEFINES): Ditto.
+ * config/ebmon29k.mt: Deleted.
+ * config/h8300hds.mt: Deleted.
+ * config/ic960coff.mt: Deleted.
+ * config/sparc.mt: Deleted.
+ * config/h8300.mt (LOCAL_LOADLIBES, TDEFINES): Deleted.
+ * config/h8500.mt (LOCAL_LOADLIBES, TDEFINES): Deleted.
+ * config/sh.mt (LOCAL_LOADLIBES, TDEFINES): Deleted.
+ * config/z8k.mt (LOCAL_LOADLIBES): Deleted.
+ (TDEFINES): Don't define the coffbfd macros.
+
+ * Makefile.in: Insert makefile fragments before OBJS definition.
+ (OBJS): Add $(TE_OBJS).
+
+ * config/obj-coff.c (obj_pseudo_table): Supply "section"
+ unconditionally.
+
+ * write.c (set_symtab): Define only if BFD_ASSEMBLER.
+
+Sun Mar 20 12:06:05 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Makefile.in (STAGESTUFF): Add gasp.new.
+
+Fri Mar 18 20:09:16 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * write.c (symbol_table_frozen): New variable, to be set after
+ bfd_set_symtab is called.
+ (dump_section_relocs): Note whether a symbol is a section symbol
+ or not.
+ (adjust_reloc_syms): For now, always supply an absolute symbol for
+ fixups without symbols but not yet `done'. Use section_symbol to
+ get the symbol, instead of going directly for abs_symbol.
+ (write_relocs) [DEBUG4]: Abort if any symbol referred to by a
+ reloc is not a section symbol and is not in the symbol table.
+ (set_symtab): New function, broken out from write_object_file.
+ Counts symbol table instead of relying on an earlier count.
+ (write_object_file): Call set_symtab, but do it after potentially
+ invoking the *_frob_file macros. Don't bother counting symbols.
+ Call symbol_remove, instead of expanding it in place. Moved the
+ conditionalized `object_file_size' declaration down to
+ conditionalized block where it's used. When using the absolute
+ symbol for a fixup without a symbol, set sy_used_in_reloc.
+ (write_object_file) [BFD_ASSEMBLER]: Call section_symbol to get
+ the correct symbol for the absolute section.
+
+ * subsegs.c (section_symbol): Use symbol_new instead of
+ symbol_make, since we may want it to go into the symbol table.
+ Make the new symbol have internal linkage. If
+ obj_sec_sym_ok_for_reloc says it's okay, use the BFD section
+ symbol with the newly created GAS symbol.
+ (obj_sec_sym_ok_for_reloc): Default to always returning 0.
+ * config/obj-aout.h (obj_sec_sym_ok_for_reloc) [BFD_ASSEMBLER]:
+ New macro.
+ * config/obj-elf.h (obj_sec_sym_ok_for_reloc): New macro.
+
+ * config/tc-sparc.c: Include subsegs.h.
+ (in_signed_range): New function.
+ (sparc_ip): Use it.
+ (sparc_ip, case 'i'): Use BFD_RELOC_SPARC13, not _BASE13.
+ (sparc_ip, label "immediate"): Reject constants for pcrel
+ instructions only if the relocation type indicates a "call"
+ instruction and the offset is within range of a "jmpl %g0". If
+ it's not in range, use the absolute section symbol plus an offset.
+ (md_apply_fix): Use in_signed_range. Combined _SPARC13 and
+ _BASE13 cases.
+ (tc_gen_reloc): Permit BFD_RELOC_SPARC13.
+
+ * config/ic960coff.mt (TDEFINES): Fixed typo (MANY_SECTIONS, not
+ MANY_SEGMENTS).
+
+ * configure.in: Eliminated all targets using obj-coff but not
+ defining BFD_ASSEMBLER; I think all such targets that are
+ supported will be matched by real CPU-OS combinations earlier in
+ the case statement.
+ (targets *-*-coff*, *-sysv*, *-*-sco*, *-*-sysv32): Deleted. Made
+ some comments about the dpx2 configuration, but left it disabled,
+ since it couldn't be reached before.
+ (target a29k-amd-ebmonold): Deleted.
+
+Thu Mar 17 13:36:09 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_import): Correctly handle importing of an
+ already defined symbol.
+
+Wed Mar 16 17:11:37 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Only accept overly large values for
+ the 'j' operand if there are no further alternatives for this
+ instruction.
+
+ * config/obj-coffbfd.c (adjust_stab_section): Initialize
+ stabstrseg to SEG_UNKNOWN, not -1. After loop, check whether it
+ is not SEG_UNKNOWN rather than checking whether it is >= 0.
+
+ * config/tc-mips.c (mips_align): Take new argument, label, and use
+ it instead of global insn_label.
+ (s_align, s_cons, s_float_cons, s_gpword): Save insn_label before
+ call to mips_emit_delay and pass it to mips_align.
+
+Wed Mar 16 11:54:12 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_equ): Handle both .reg and .equ correctly.
+
+ * config/tc-hppa.c (pa_callinfo): Accept "millicode" as an
+ argument to a .callinfo directive. Don't loop forever on errors.
+
+ * config/tc-hppa.c (pa_equ): Use pa_parse_number so that we can
+ use pre-defined registers as arguments.
+
+Mon Mar 14 14:29:45 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * write.c (write_object_file): Check both S_IS_LOCAL and
+ S_IS_EXTERNAL when deciding whether to discard a symbol.
+
+ * config-gas.com: Scan Makefile.in, not version.c, for current
+ version number. Delete all versions of temp files when finished
+ with them. Create config.h.
+
+ * config/obj-vms.c (VMS_Initialized_Data_Size): Cache symbol
+ values to reduce number of lookups with S_GET_VALUE. Skip debug
+ symbols to avoid "a really nasty bug". (From Holger Teutsch,
+ holger@botbso.rhein-main.de.)
+ (VMS_write_object_file): For "__vt.*" symbols, set S_GET_OTHER
+ field. (Also from Holger Teutsch.) Watch for a would-be register
+ mask that spans frags.
+
+ * config/obj-coffbfd.c (obj_coff_line): Set symbol lnno field with
+ this_base, not line_base. (Patch from Andreas Arens,
+ ari@obelix.av.rwth-aachen.de.)
+
+ * config/obj-aout.c (obj_crawl_symbol_chain): Retain symbols that
+ look local if they're exported or undefined. Used to be done for
+ i960 only.
+
+ * read.c (s_lcomm, s_comm): Print symbol name being redefined.
+ Get it from the looked-up symbol, instead of using the string from
+ the input stream, which is no longer null-terminated.
+ (LEX_PCT): New macro, defaults to 0.
+ (lex_type): Use it for `%'.
+
+ * config/tc-vax.c (md_parse_option): Handle `-h#' option for VMS.
+ (vip_op): Now static, and returns void. Callers changed. Added
+ forward decl.
+ (vip): Ditto. Call as_fatal directly if a program bug is
+ detected.
+ (op_hash): Let default initialization suffice.
+
+ * Makefile.in (literal.o): Provide dependencies.
+
+ * configure.in: Set new makefile variable OPCODES_LIB.
+ * Makefile.in (LIBS): Use it.
+
+ * Makefile.in (make-gas.com, stamp-mk.com): New targets.
+ * vmsconf.sh: New file.
+ * make-gas.com: Regenerated from new script.
+
+ * configure.in (sparc*-*-lynxos*): Handle any version number
+ suffix after "lynxos". Set emulation to lynx.
+
+Mon Mar 14 11:30:49 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config/obj-coff.c (obj_coff_section): Delete declaration.
+
+Fri Mar 11 22:25:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-ppc.c (md_pcrel_from): Return 0 for undefined ELF
+ symbols.
+ (ppc_is_toc_sym): Change .toc to .got.
+ (md_apply_fix): Change handling of ELF relocs.
+ (tc_gen_reloc): Likewise.
+
+Fri Mar 11 17:42:20 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/obj-vms.c (Close_VMS_Object_File): Add comment pointing
+ out some code that doesn't belong in this file.
+
+ * config/obj-vms.h: Include aout/stab_gnu.h.
+ (N_GSYM, ..., N_LENG): Deleted.
+ (NO_RELOC): Undefine before defining as part of enum reloc_type.
+
+ * config/tc-alpha.c: Add comment questioning need for all the
+ characters in FLT_CHARS.
+
+ * as.c (main) [OBJ_VMS]: Don't call output_file_close.
+
+ * config/obj-ecoff.c (ecoff_frob_file): Set strict order for
+ sections with recognized names, before computing VMA values.
+
+Fri Mar 11 17:56:23 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Accept numbers between 0x8000 and
+ 0xffff for 'j' to be compatible with MIPS assembler. These
+ numbers are actually treated as negative.
+
+Thu Mar 10 13:36:29 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/tc-sparc.h (LOCAL_LABEL): Local labels are .Lfoo.
+
+Tue Mar 8 21:17:12 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/obj-coff.c: Minor formatting/stylistic changes, plus:
+ (obj_coff_section): Declare.
+ (obj_pseudo_table): Make it available only if MANY_SECTIONS.
+ (obj_symbol_to_chars) [CROSS_COMPILE]: Some attemps to make this
+ work. It still doesn't. It now fails to compile, instead of
+ silently compiling to do nothing.
+ * config/obj-coff.h (SEPARATE_STAB_SECTIONS): Define only if
+ MANY_SECTIONS.
+ (OBJ_PROCESS_STAB) [! MANY_SECTIONS]: New macro, just emits
+ warning.
+
+ Handle Alpha load-immediate-FP pseudo-instructions:
+ * config/alpha-opcode.h (ldif, ldig, ldis, ldit): New patterns.
+ * config/tc-alpha.c (lit8_sec, lit4_sec, lit8_sym, lit4_sym): New
+ variables.
+ (create_literal_section): New function.
+ (create_lita_section): Now a macro.
+ (get_lit8_offset, get_lit4_offset): New functions.
+ (maybe_set_gp): New function.
+ (select_gp_value): Call it.
+ (load_expression): Preserve addend if symbol is a section symbol.
+ (alpha_ip): Handle new operand type `F' for floating-point
+ constants; store them in .lit{4,8} sections.
+ (alpha_ip, case 'G'): Emit LITUSE relocations for symbol exprs.
+
+ * config/tc-i386.c (smallest_imm_type): Never return Imm1.
+
+Tue Mar 8 14:18:15 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/obj-coffbfd.c (w_strings): Only copy strings out if
+ their symbols are going to be written.
+
+Tue Mar 8 11:49:27 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * messages.c (as_perror): Declare arguments const.
+ * as.h (as_perror): Change declaration.
+
+Mon Mar 7 16:08:25 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (load_address): When calling frag_grow, allow
+ for the (up to) two nops which may be inserted by append_insn if
+ mips_optimize is 0.
+ (macro): Likewise.
+
+Thu Mar 3 11:37:55 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/atof-ieee.c (make_invalid_floating_point_number):
+ Add cast to avoid warning from gcc.
+
+Wed Mar 2 10:31:01 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: Add a few casts to make HP C compiler happy.
+
+ * config/obj-som.c (obj_som_version, obj_som_copyright): Be
+ prepared
+ to handle an error from bfd_som_attach_aux_hdr.
+
+ * config/tc-hppa.h: Wrap ELF specific decls inside an ifdef.
+
+Mon Feb 28 15:03:26 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-alpha.c (md_atof): Omit warning about FP values.
+ (line_comment_chars): Add ! to list.
+ (md_apply_fix): Do process 32- and 64-bit relocations.
+
+ * config/obj-coffbfd.c (obj_coff_lcomm): Put "#if 0" around the
+ unused parts (most of the function).
+ (obj_coff_init_stab_section): Cast alloca result.
+
+ * configure.in (i960-*-coff, i960-*-vxworks5.*): Use coffbfd, and
+ gas_target ic960coff.
+ * config/ic960coff.mt: New file.
+ * config/obj-coffbfd.h [TC_I960]: Include coff/i960.h.
+ (TARGET_FORMAT) [TC_I960]: Use coff-Intel-little.
+ * config/te-ic960.h (CROSS_COMPILE): Don't undef this. We'll
+ always build little-endian object files.
+ * config/tc-i960.c (md_reloc_size): Don't define at all if BFD or
+ BFD_ASSEMBLER is defined.
+ (mem_fmt): Since COFF doesn't handle callx relocations yet, treat
+ them like normal 32-bit relocations.
+ (md_apply_fix): For callx relocations, store zero.
+ (tc_bout_fix_to_chars): Store symbol index for all callx
+ relocations, regardless of link-relax setting.
+ (tc_coff_fix2rtype, tc_coff_sizemachdep): New functions.
+ (i960_handle_align) [! OBJ_BOUT]: If link-relax option is
+ selected, print an error message and clear it.
+ * config/tc-i960.h (BFD_ARCH, COFF_FLAGS, COFF_MAGIC,
+ TC_COUNT_RELOC, TC_COFF_FIX2RTYPE, TC_COFF_SIZEMACHDEP,
+ tc_fix_adjustable): New macros.
+ (tc_coff_fix2rtype, tc_coff_sizemachdep): Declare.
+
+Fri Feb 25 20:56:57 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (hppa_tc_symbol): Call PA ELF BFD version.
+ (hppa_tc_make_sections): Likewise.
+ (pa_build_symextn_section): Delete unused function.
+ (hppa_tc_make_symextn_section): Likewise.
+ (pa_export): Delete call to pa_build_symextn_section.
+
+ * config/tc-hppa.h (hppa_tc_symbol): Add extern decl.
+ (elf_hppa_final_processing): Delete extern decl.
+ (hppa_tc_symbol): Delete extern decl.
+
+Fri Feb 25 13:15:31 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-coffbfd.c (fill_section): Correct test for whether to
+ fill a section (from Minh Tran-Le <TRANLE@intellicorp.com>).
+
+Thu Feb 24 11:30:26 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * configure.in: Don't require version number for i386-*-mach.
+
+ * read.c (potable): Added ".this_GCC_requires_the_GNU_assembler",
+ which is ignored by gas, but will cause other assemblers to choke.
+ Intended for use by gcc ports that require gas instead of native
+ assemblers.
+
+Thu Feb 24 07:10:31 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/ho-hppaosf.h: Fix braino in test for ANSI-C.
+
+Wed Feb 23 16:51:43 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * write.c (write_contents): Give the user a reasonable error
+ message rather than "assertion failed" if bfd_set_section_contents
+ fails.
+
+Tue Feb 22 10:07:32 1994 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * config/ho-mach3.h: New file.
+
+Mon Feb 21 11:41:18 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * ecoff.c (ecoff_build_debug): Don't set hdr->magic here. It is
+ now set in bfd/ecofflink.c:ecoff_write_symhdr.
+
+ * config/obj-coffbfd.c (write_object_file): use bfd_get_error (),
+ not bfd_error.
+ * config/obj-elf.c (elf_frob_file): Likewise.
+
+ * read.c (s_lcomm): Use an alignment power of 3 for 8 byte .lcomm
+ variables.
+
+ * config/ho-hpux.h (BROKEN_ASSERT): Define if not __GNUC__.
+
+ * read.c (read_a_source_file): Use correct arguments to memcpy
+ (broken 19 Jul 1993). From kjd@pescadero.stanford.edu (Kenneth
+ Duda).
+
+Sun Feb 20 18:01:54 1994 Ian Lance Taylor (ian@lisa.cygnus.com)
+
+ * config/obj-coff.h (obj_coff_section): Declare.
+ * config/obj-coff.c (obj_pseudo_table): For "section", use
+ obj_coff_section.
+ (obj_coff_section): Rewrite.
+
+Fri Feb 18 14:16:32 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * configure.in (i386-*-mach3*): New target; uses BFD.
+ * config/te-mach.h: New file.
+ * config/obj-aout.c (obj_aout_frob_file): New function.
+ * config/obj-aout.h (obj_aout_frob_file): Declare it.
+ (frob_file): New macro.
+ * config/tc-i386.c (md_apply_fix_1) [TE_Mach]: Don't adjust
+ pcrel32 relocations.
+ * config/tc-i386.h (TARGET_FORMAT) [TE_Mach]: Use a.out-mach3.
+
+ * write.c (write_object_file): Removed register declarations.
+
+Thu Feb 17 16:25:18 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Some support for PowerPC ELF.
+ * configure.in: If cpu is powerpc*, use ppc.
+ (ppc-*-sysv4*): Use object format elf.
+ * config/tc-ppc.h: Only declare a number of things if OBJ_COFF is
+ defined.
+ (TARGET_ARCH): Make it call ppc_arch.
+ (ppc_arch): Declare.
+ (TARGET_FORMAT): Set based on OBJ_COFF or OBJ_ELF.
+ (NO_STRING_ESCAPES): Define.
+ (LOCAL_LABEL, FAKE_LABEL_NAME): Define for OBJ_ELF.
+ * config/tc-ppc.c: Only define a number of functions of OBJ_COFF
+ is defined.
+ (md_pseudo_table): Most pseudo-ops are OBJ_COFF specific. Added
+ OBJ_COFF specific "bi" and "ei".
+ (md_parse_option): Fix handling of -u. Make -m601 set
+ PPC_OPCODE_601. If OBJ_ELF, accept -V and -Q.
+ (ppc_set_cpu): New function.
+ (ppc_arch): New function.
+ (md_begin): Call ppc_set_cpu.
+ (ppc_insert_operand): For a signed operand accept an unsigned
+ value, for IBM compatibility.
+ (ppc_byte): Don't call stringer for strings; instead, treat two
+ double quotes as a single double quote.
+ (ppc_comm): Set sy_tc.output for a .lcomm symbol.
+ (ppc_biei): New function.
+ (ppc_tc): If not OBJ_COFF, ignore first argument.
+ (ppc_fix_adjustable): Call as_bad_where, not as_bad.
+ (ppc_is_toc_sym): New function.
+ (md_apply_fix): Use ppc_is_toc_sym. Handle BFD_RELOC_16 and
+ BFD_RELOC_8.
+
+Thu Feb 17 09:29:37 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * messages.c (as_perror) [BFD_ASSEMBLER]: Use bfd_get_error and
+ bfd_set_error and new error names.
+
+Tue Feb 15 20:23:20 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * configure.in: Support i960-vxworks versions > 5.0 as coff.
+ Default is still bout if no version is specified.
+
+ * atof-generic.c (atof_generic): Use switch and strcasecmp instead
+ of large number of compares when looking for inf/nan values.
+
+Fri Feb 11 13:13:27 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (macro): Do unaligned loads and stores
+ correctly when big endian, and give errors on overflow rather than
+ generating incorrect code.
+
+Thu Feb 10 11:24:20 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * as.c: Include libiberty.h.
+
+ * read.c (do_align): Don't define label just_record_alignment
+ unless it might be used.
+
+ * as.c (main): If md_parse_long_option is defined, call it with a
+ long option.
+ * config/tc-mips.h (md_parse_long_option): Define.
+ * config/tc-mips.c (mips_trap): New static variable.
+ (md_begin): Report an error if mips_trap is set at ISA level 1.
+ (macro): If mips_trap, use trap instructions instead of break
+ instructions for overflow and divide by zero detection.
+ (mips_parse_long_option): New function. Support --trap,
+ --no-break, --break and --no-trap.
+ * doc/as.texinfo: Document new options.
+
+ * read.c (potable): Add "zero".
+ * config/tc-i386.c (md_pseudo_table): Remove "zero".
+ * config/tc-m88k.c (md_pseudo_table): Likewise.
+
+Thu Feb 10 01:24:27 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Reject integer values for
+ pc-relative operand fields. This forces "call 0" to become "jmpl
+ %g0,%o7" with no relocations needed.
+
+Wed Feb 9 13:08:32 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * as.h (xmalloc, xrealloc): Declare using PTR rather than char *.
+ * xmalloc.c (xmalloc, xrealloc): Use PTR rather than char *.
+
+ * app.c (do_scrub_next_char): If NO_STRING_ESCAPES is defined,
+ don't treat backslash specially inside strings.
+ * read.c (next_char_of_string): Likewise.
+
+Wed Feb 9 09:42:45 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config/obj-coffbfd.c (obj_coff_init_stab_section): Use memset
+ instead of memcpy to zero the initial stab symbol, duh.
+ * config/obj-elf.c (obj_elf_init_stab_section): Ditto.
+ * config/obj-som.c (obj_som_init_stab_section): Ditto.
+
+Tue Feb 8 17:25:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * write.c (fixup_segment): Use as_bad_where, not as_bad.
+
+ * subsegs.c (subseg_set_rest): Call memset with the arguments in
+ the right order. Explicitly clear fix_root and fix_tail fields.
+
+Tue Feb 8 16:00:25 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/obj-coff.c (coff_frob_symbol): For abs_symbol, set *punt
+ and do nothing else.
+
+ * symbols.c (symbol_begin): Initialize value of abs_symbol
+ properly.
+
+ * write.c (adjust_reloc_syms): Use abs_symbol instead of calling
+ section_symbol.
+
+ * ecoff.c (ecoff_build_debug): Fix "/*" in comment to silence
+ complaint from "gcc -Wall".
+
+ * configure.in (alpha-*-netware*): New target, like alpha-*-osf*.
+
+ * config/tc-alpha.c (GP_ADJUSTMENT): Move definition to start of
+ file.
+ (tc_gen_reloc): Remove uninitialized variable `code', and code
+ that tried to use it (incorrectly). For LITERAL reloc, set addend
+ to negative of GP value.
+ (load_symbol_address): Don't adjust return value by GP_ADJUSTMENT.
+
+ * write.c (write_relocs): Print some sensible error message if
+ bfd_perform_relocation returns bfd_reloc_overflow.
+
+Mon Feb 7 15:49:24 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * configure.in (hppa*-*elf*): New configuration for PA ELF.
+ (hppa*-*-osf*): Default object format is SOM.
+
+Mon Feb 7 16:07:35 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-alpha.c (md_atof): Warn that floating-point values
+ might not assemble properly.
+
+ * configure.in (target alpha-*-osf*): Don't set "dev=yes" any
+ more.
+
+ * config/tc-alpha.c (load_expression): Parenthesize operations in
+ range checking, to avoid precedence questions.
+
+ * config/tc-alpha.c (addr32): New static variable.
+ (md_parse_option): Set it for "-32addr".
+ (load_symbol_address): If addr32 is set, use ldl instead of ldq.
+
+ * atof-generic.c (atof_generic): Calculate maximum_useful_digits
+ and more_than_enough_bits_for_digits in integer arithmetic, to
+ eliminate the only sources of dependence on floating point
+ support, which doesn't work yet on the Alpha.
+
+Mon Feb 7 03:56:05 1994 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * ecoff.c (ecoff_build_debug) [TC_ALPHA]: Specify version stamp as
+ 0x30b for Alpha for now, until ".verstamp" is handled.
+
+ * literal.c (add_to_literal_pool): Use seginfo->frchainP, which
+ actually refers to the literal pool section, rather than
+ frchain_now, which refers to whatever section the assembler was
+ in.
+
+ * write.c (fixup_segment): Only do range checking if size of fixup
+ is smaller than word size. Otherwise, we always wind up with
+ zeros.
+
+ * config/tc-alpha.c (md_section_align): Change second argument and
+ return type to valueT, to agree with tc.h.
+ (alpha_do_align): Local static array nop_pattern is now unsigned
+ char, to avoid overflow warnings.
+ * config/tc-alpha.h (md_section_align): Delete declaration.
+
+ * config/obj-ecoff.c (ecoff_frob_file): Ensure that ecoff_data for
+ output bfd is non-null before indirecting through it.
+
+ * config/tc-alpha.c (alpha_frob_ecoff_data): Renamed from
+ alpha_frob_file.
+ * config/tc-alpha.h (tc_frob_file): Macro deleted.
+ * config/obj-ecoff.c (ecoff_frob_file) [TC_ALPHA]: Call
+ alpha_frob_ecoff_data, then fill in optional-header info with gp
+ value and register masks.
+
+Sun Feb 6 16:13:47 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * configure.in (hiux): Fixes from m-kasahr@sramhc.sra.co.JP.
+
+ * config/obj-som.c (obj_som_init_stab_section): Same change
+ as coffbfd and elf below. Zero the initial stab symbol after
+ allocating it.
+
+Sat Feb 5 12:30:32 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config/obj-coffbfd.c (obj_coff_init_stab_section): Zero the
+ initial stab symbol after allocating it.
+ * config/obj-elf.c (obj_elf_init_stab_section): Ditto.
+
+Sat Feb 5 11:53:31 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip): addb[tf] should only accept
+ non-negated condition completers. Add support for addb pseudo-op
+ which accepts both negated and non-negated completers.
+
+Sat Feb 5 00:15:49 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in (rs6000*): Use cpu_type ppc.
+ (ppc-*-aix*): New target; use coff and force bfd_gas.
+ * config/tc-ppc.h, config/tc-ppc.c: New files for PowerPC/POWER
+ (RS/6000) support. At the moment, only XCOFF is supported.
+
+ * config/obj-coff.c (SA_SET_SYM_ENDNDX): Made non-static.
+ (S_SET_DATA_TYPE): Likewise.
+ (coff_last_function): Renamed from local static last_functionP in
+ coff_frob_symbol and made externally visible.
+ (coff_frob_symbol): New local static set_end; use it to try to
+ avoid calling SA_SET_SYM_ENDNDX on a symbol that will be punted.
+ * config/obj-coff.h (S_SET_DATA_TYPE): Declare.
+ (SA_SET_SYM_ENDNDX): Declare.
+ (coff_last_function): Declare.
+
+ * expr.c (operand): If DOLLAR_DOT is defined, accept `$' as
+ equivalent to `.' to mean the current location.
+
+ * read.c (LEX_BR): If not defined, define as 0.
+ (lex_type): Use LEX_BR as the type of `{',`}',`[',`]'.
+
+ * symbols.c (symbol_new): If tc_canonicalize_symbol_name is
+ defined, call it with preserved_copy_of_name. If
+ tc_symbol_new_hook is defined, call it on the new symbol.
+ (symbol_find_base): If tc_canonicalize_symbol_name is defined,
+ call it on a copy of the name argument.
+
+ * write.c (write_object_file): Simplified usage of obj_frob_symbol
+ and tc_frob_symbol. Always call both if the symbol is going to be
+ output.
+
+ * write.c (relax_segment): Use %ld rather than %d when printing
+ fragP->fr_var, and cast it to long.
+
+ Changed relocs to be based on subsegments (when BFD_ASSEMBLER).
+ * subsegs.h (struct frchain): If BFD_ASSEMBLER, added new fields
+ fix_root and fix_tail.
+ (segment_info_type): If BFD_ASSEMBLER, don't define fix_tail
+ field.
+ * write.c (fix_new_internal): If BFD_ASSEMBLER, set fix_rootP and
+ fix_tailP based on frchain_now, not seg_info (now_seg).
+ (chain_frchains_together_1): Chain the subsegment relocs together.
+ * subsegs.c (subseg_change): Don't clear fix_tail field.
+ (subseg_get): Likewise.
+ * literal.c (add_to_literal_pool): Look through the relocs via
+ frchain_now, not seginfo.
+
+Thu Feb 3 23:07:30 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-ecoff.h (TARGET_SYMBOL_FIELDS): Changed
+ ecoff_undefined to ecoff_extern_size.
+ * config/obj-elf.h (ELF_TARGET_SYMBOL_FIELDS): Likewise.
+ * config/tc-mips.c (s_extern): Set ecoff_extern_size to the
+ external symbol size, rathern than setting the symbol value.
+ (md_estimate_size_before_relax): Check both ecoff_extern_size and
+ symbol value to see if GP referencing can be used.
+ * ecoff.c (ecoff_symbol_new_hook): Clear ecoff_extern_size, not
+ ecoff_undefined.
+ (ecoff_frob_symbol): Don't check ecoff_undefined.
+ (ecoff_build_symbols): Get size of an undefined symbol from
+ sym->ecoff_extern_size, not S_GET_VALUE (sym).
+
+Wed Feb 2 13:55:08 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Makefile.in: Avoid bug in losing hpux sed.
+
+Wed Feb 2 11:40:11 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (file_mips_isa): New static variable.
+ (md_begin): Set it.
+ (s_mipsset): Add support for .set mipN to set the ISA level.
+
+ * gasp.c (kinfo): Fully bracket initializer.
+
+Tue Feb 1 19:28:12 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * gasp.c (malloc): Don't declare, since host.h or system header
+ files may declare it differently.
+
+ * config/atof-ieee.c (int_to_gen): Now static.
+
+ * config/ho-i386aix.h: Include sys/types.h and stdlib.h, not
+ ho-sysv.h. Based loosely on a patch from Minh Tran-Le.
+
+Tue Feb 1 10:50:17 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * gasp.c: Include host.h.
+
+Tue Feb 1 12:13:01 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Make an unsupported instruction a
+ warning, not an error.
+
+ * config/obj-coff.c (dot_text_symbol, dot_data_symbol,
+ dot_bss_symbol): Don't define if BFD_ASSEMBLER.
+ (obj_symbol_to_chars): bfd_coff_swap_aux_out now takes more
+ arguments.
+ (coff_line_base): Renamed from line_base. Changed all uses.
+ (coff_add_linesym): Renamed from add_line_sym. Made non-static.
+ Changed all uses.
+ * config/obj-coff.h: If TC_PPC, include coff/rs6000.h.
+ (S_SET_STORAGE_CLASS, S_GET_STORAGE_CLASS): Declare if
+ BFD_ASSEMBLER.
+ (coff_line_base): Declare.
+ (coff_add_linesym): Declare if BFD_ASSEMBLER.
+ * config/obj-coffbfd.c (symbol_to_chars): bfd_coff_swap_aux_out
+ now takes more arguments.
+
+Mon Jan 31 17:55:14 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * as.c (statistics_flag): Renamed from quiet_flag.
+ (main): Get statistics with --statistics instead of -noquiet.
+
+Mon Jan 31 07:19:30 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * Makefile.in: Support for Gnu ASsembler Preprocessor.
+ * gasp.c: New file.
+ * read.c (s_lcomm): Align lcomm data.
+ * config/tc-z8k.c (tc_reloc_mangle): Don't allow subtraction
+ from different sections.
+
+Sun Jan 30 14:58:26 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * write.c (write_object_file): If tc_frob_file is defined, call it
+ just before calling obj_frob_file.
+ * config/tc-alpha.c (alpha_gp_value): Renamed from gp_value
+ (references changed), and made non-static.
+ (getExpression): Return void.
+ (select_gp_value): Abort if gp_value is non-zero. Delete call to
+ non-existent bfd_set_gp_value.
+ (alpha_validate_fix): Function deleted.
+ (alpha_frob_symbol): Function deleted.
+ (alpha_local_label): Function deleted.
+ (alpha_frob_file): Renamed from alpha_end.
+ * config/tc-alpha.h (alpha_frob_symbol, alpha_validate_fix,
+ alpha_local_label, alpha_end): Declarations deleted.
+ (alpha_gp_value, alpha_frob_file): Declare.
+ (tc_frob_symbol, TC_VALIDATE_FIX, md_end): Macros deleted.
+ (LOCAL_LABEL): Move code here from tc-alpha.c:alpha_local_label.
+ (md_convert_frag): Simplified slightly.
+ (tc_frob_file): New macro.
+
+ * read.c (do_align): New function, most of guts of s_align_*
+ functions. Look for md_do_align macro, give it a chance to bypass
+ all but recording of section alignment.
+ (s_align_bytes, s_align_ptwo): Call do_align.
+ (s_lcomm) [TC_ALPHA]: Align object to largest power of two that
+ divides object size.
+
+ * frags.c (frag_align_pattern): New function.
+ (frag_align): Rewrite for clarity.
+
+ * config/tc-vax.c (md_assemble): Handle O_constant expression.
+ (vip_begin): Returns pointer to const char. Cast hash_insert arg
+ to PTR to avoid compiler complaints about const.
+ (md_begin): Local variable errtxt must point to const.
+
+ * configure.in: Handle host vax-*-ultrix* like vax-*-bsd*. Don't
+ bother with *-*-ultrix or *-*-sysv*, except *-*-sysv, since only
+ the last has an existing host support file. Do handle vax-bsd and
+ vax-ultrix targets.
+
+Fri Jan 28 11:26:40 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-coff.c (obj_coff_section_header_append): Do not
+ declare if BFD_ASSEMBLER.
+ (stack_pop): Correct test for stack underflow.
+ (obj_coff_endef, obj_coff_dim, obj_coff_line, obj_coff_size,
+ obj_coff_scl, obj_coff_tag, obj_coff_type, obj_coff_val): Declare
+ type of ignored argument to avoid gcc warning.
+ (align): Removed unused function.
+
+Thu Jan 27 18:14:19 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-alpha.c, config/tc-alpha.h, config/alpha-opcode.h: New
+ files, based on port of gas-1.38 contributed by CMU, using a.out
+ variant. Updated for gas-2.x and ECOFF. Floating-point constants
+ are still broken, bootstrap testing incomplete.
+
+ * literal.c: Comment changes.
+
+ * listing.c (listing_source_file): Check for null listing_tail
+ before indirecting through it.
+
+ * expr.h (struct expressionS): Added struct tag.
+
+ * as.h: If __GNUC__ and inline are both undefined, define inline
+ away.
+
+ * write.c (cvt_frag_to_fill): Don't assume that fr_var for
+ rs_align or rs_org frags will be 1.
+ (relax_segment): For rs_align, if fr_var is not 1, complain if
+ required padding is not a multiple of the size of the pad pattern.
+ (fixup_segment): Leave gp-relative relocations alone. For pcrel
+ relocations referring to the same segment, clear fx_pcrel when
+ clearing fx_addsy.
+ * as.h: Adjust comments on rs_align.
+
+ * atof-generic.c: Some reformatting.
+ (atof_generic): Be careful when mixing signed/unsigned values of
+ different sizes.
+
+ * write.c, config/obj-{aout,bout,coff*}.c, config/tc-sparc.c:
+ Query the fx_done field instead of fx_addsy to see if the fixup
+ still needs to be applied. Set fx_done and clear fx_addsy both,
+ for now. If TC_HANDLES_FX_DONE isn't defined, assume md_apply_fix
+ will only clear fx_addsy, and set fx_done accordingly after
+ returning.
+ * config/tc-sparc.h (TC_HANDLES_FX_DONE): Define.
+ * config/tc-sparc.c (md_apply_fix): Set fx_done for non-pcrel fix
+ with no fx_addsy.
+
+ * symbols.c (dot_text_symbol, dot_data_symbol, dot_bss_symbol):
+ Deleted.
+ (symbol_begin): Moved to end of file, so function inlining can
+ work better.
+ (fb_label_count, fb_label_max): Default C static initializers are
+ sufficient.
+ * symbols.h (dot_text_symbol, dot_data_symbol, dot_bss_symbol):
+ Declarations deleted.
+ * config/obj-coff.c (dot_text_symbol, dot_data_symbol,
+ dot_bss_symbol): Defined here, static.
+
+ * config/obj-aout.c [BFD_ASSEMBLER]: Undef NO_RELOC before
+ including aout/aout64.h.
+
+ * write.c (write_object_file): If EMIT_SECTION_SYMBOLS is false,
+ don't write out a section symbol even if it's used in a
+ relocation; assume relocations will handle section numbers
+ somehow. Rename "punt_it" label to "punt_it_if_unused" to reflect
+ it's true use.
+ (EMIT_SECTION_SYMBOLS): Default to 1.
+ (adjust_reloc_syms): Don't create a new symbol for an absolute
+ reference; just use the absolute section symbol.
+ (write_relocs): Make printout of reloc values dependent on flag
+ DEBUG3, not DEBUG2.
+ * config/obj-aout.h (EMIT_SECTION_SYMBOLS): Define as 0.
+ * config/obj-ecoff.h (EMIT_SECTION_SYMBOLS): Ditto.
+
+Thu Jan 27 16:43:51 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * read.c (lex_type): No longer make '{' a valid character for
+ symbol names.
+
+ * as.c (main): Print long values using %ld.
+
+ * messages.c (as_warn_internal): New static function.
+ (as_warn, 3 versions): Use as_warn_internal.
+ (as_warn_where, 3 versions): New function.
+ * as.h (as_warn_where): Declare.
+
+Tue Jan 25 18:30:34 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * as.c (quiet_flag): New flag.
+ (main): If -noquiet given, display execution time and memory used.
+
+Tue Jan 25 15:53:11 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * doc/{all.texi,as.texinfo}: Add documentation for HPPA port.
+
+Mon Jan 24 19:18:23 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_frob_symbol): New function. Put undefined
+ symbols of known size in the undefined section. Put small common
+ symbols in a .scommon section.
+ * ecoff.h (ecoff_frob_symbol): Declare.
+ * config/obj-ecoff.h (obj_frob_symbol): Define.
+ * config/obj-elf.c (obj_elf_write_symbol_p, obj_elf_write_symbol,
+ obj_elf_frob_symbol): Removed unused functions.
+ * config/obj-elf.h (obj_frob_symbol, obj_write_symbol): Removed
+ unused macros.
+ (obj_elf_frob_symbol, obj_elf_write_symbol): Removed declarations
+ of unused functions.
+ (obj_frob_symbol): Define if ECOFF_DEBUGGING.
+
+ * config/tc-mips.c (g_switch_seen): New static variable.
+ (md_parse_option): Set g_switch_seen for -G option.
+ (s_option): If creating PIC code, force the GP size to be 0. Warn
+ if -G switch used with a non-zero value.
+
+ * symbols.c (S_IS_COMMON): Use bfd_is_com_section rather than
+ comparing against bfd_com_section.
+
+Mon Jan 24 14:12:25 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * read.c (s_lcomm): Treat Alpha like MIPS in handling of .sbss
+ section.
+
+Thu Jan 20 13:17:58 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * expr.c (operand): For floating point operand with unusual fp
+ char from FLT_CHARS, preserve the character. Patch from Lisa
+ Repka.
+
+Wed Jan 19 23:15:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (md_pseudo_table): Add all data allocation
+ pseudo-ops: .hword, .int, .long, .octa, .quad, .short, .single.
+
+Tue Jan 18 15:51:59 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/obj-coffbfd.c (obj_coff_endef): For C_EFCN, C_BLOCK and
+ C_FCN assume .val has been set to .
+
+Tue Jan 18 16:19:58 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: Disable multiple $CODE$ subspace code. It
+ confuses GDB for some unknown reason.
+ * config/obj-som.c: Likewise.
+
+Tue Jan 18 19:05:32 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * literal.c (add_to_literal_pool): Handle duplicates of values
+ already written to literal pool.
+
+Tue Jan 18 17:23:52 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-aout.c (obj_aout_frob_symbol): Try to get symbols
+ with explicitly marked stabs through BFD: if a symbol marked
+ N_UNDF | N_EXT is in the absolute section, move it to the
+ undefined section; move a symbol marked N_INDR into
+ bfd_ind_section and set the BSF_INDIRECT flag; set the
+ BSF_WARNING flag for a symbol makred N_WARNING.
+
+Mon Jan 17 15:40:23 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.h (ecoff_set_gp_prolog_size): Declare.
+ * ecoff.c (ecoff_set_gp_prolog_size): Return type is void.
+
+Mon Jan 17 00:18:55 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip): Explicitly check for comma before 'u'
+ and 'f' template operand.
+
+ * config/tc-hppa.c (pa_ip): Handle 'N', 'O', 'o', '0', '1', 'u',
+ and '2' in copr and sfu instruction templates.
+
+Sun Jan 16 16:44:23 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * as.h (subseg_force_new): Add prototype.
+
+Sat Jan 15 09:20:55 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * app.c (do_scrub_next_char): Allow lines like " foolab :".
+
+ * read.c (emit_expr): Fix computation of mask.
+ * config/obj-elf.c (obj_elf_section): Fix loop termination test.
+
+Thu Jan 13 16:15:15 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * ecoff.c (ecoff_set_gp_prolog_size): New function.
+ (current_file_idx): New static variable.
+ (add_file): Use and increment current_file_idx instead of indx
+ parameter.
+
+ * struc-symbol.h (struct symbol): Make all bitfields unsigned.
+
+ * config/tc-i960.c (i960_validate_fix): Added argument
+ add_symbolPP. Indirect through it to get "add_symbolP".
+ * config/tc-i960.h (i960_validate_fix): Supply prototype.
+ (TC_VALIDATE_FIX): Pass address of add_symbolP.
+
+ * configure.in (i386-*-netbsd*): New target, using te-netbsd.h.
+ (i386-*-netbsd0.8): New target, like 386bsd.
+
+ * configure.in: Set BFDDEF in Makefile to "define" or "undef".
+ * Makefile.in (config.h): Protect against multiple inclusions.
+ Define or undef BFD_ASSEMBLER as specified by $(BFDDEF).
+ (ALL_CFLAGS): Omit $(BFDDEF).
+ * as.h: Include config.h.
+ (struct symbol): Added forward declaration.
+ (add_to_literal_pool): Fix declaration.
+ * as.c: Don't include config.h.
+
+ * literal.c (add_to_literal_pool): Take symbol and addend as
+ arguments, instead of expression, for now. Fix calculation of
+ offset to return.
+
+ * subsegs.h (segment_info_type) [NEED_LITERAL_POOL]: Add field
+ literal_pool_size.
+
+Thu Jan 13 12:14:21 1994 Jeffrey A. Law (law@snake.cs.utah.edu
+
+ * subsegs.c (subseg_get): Accept new argument "force_new". If
+ set then a new segment is always created. All callers changed.
+ (subseg_force_new): New function. Similar to subseg_new, but
+ always force a new segment to be created.
+
+ * config/obj-som.c (som_frob_file): Call adjust_code_sections
+ for each section.
+ (adjust_code_sections): New function. Adjusts the VMA for all the
+ $CODE$ subspaces.
+
+ * config/tc-hppa.c (md_assemble): Also handle creating a fixup
+ for the unwind descriptors if a function's label follows the
+ .PROC and .ENTRY directives.
+ (pa_entry): Don't set BSF_FUNCTION for the label symbol here; it
+ is done elsewhere. Don't create a fixup for the unwind
+ descriptors if the function's label has not been defined yet.
+ (pa_proc): For SOM, place each procedure within a new $CODE$
+ subspace. Adjust the segment and frag for the associated
+ function label if it exists.
+
+Wed Jan 12 22:05:33 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (hppa_fix_struct): Add new "segment" field.
+ (hppa_fix_new): Initialize segment field.
+ (md_apply_fix): Do nothing for pc-relative fixup which involves
+ crossing a segment boundary.
+ (pa_procend): Undefine the current label after handling .PROC
+ and .PROCEND directives.
+ (dummy_symbol): Make type "symbolS *". Change references as
+ appropriate.
+
+Wed Jan 12 13:29:31 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * read.c (read_a_source_file): Cast array argument to unsigned
+ char.
+ * write.c (adjust_reloc_syms): Remove unused variable symseginfo.
+ (write_object_file): Don't define punt_it if it won't be used.
+ (fixup_segment): Don't define skip if it won't be used.
+
+ * config/tc-mips.h (TARGET_FORMAT): Define as mips_target_format.
+ (mips_target_format): Declare.
+ * config/tc-mips.c (mips_target_format): Define with appropriate
+ default definition.
+ (md_parse_option): If -EL or -EB is used, change byte_order and
+ mips_target_format as appropriate.
+
+Tue Jan 11 21:52:36 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * app.c (do_scrub_next_char): Another attempt to fix bugs
+ dealing with labels without colons (for HPPA and MRI).
+
+Tue Jan 11 17:01:06 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Truncate args to %hi/%lo to 32 bits.
+
+ * expr.c (integer_constant): Fix computation of too_many_digits.
+ Variable digit_2 renamed to start. Fix check for whether number
+ will fit in 32 bits.
+ * read.c (emit_expr): Use valueT instead of long.
+
+Tue Jan 11 13:01:20 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-elf.c: If TC_MIPS, include elf/mips.h.
+ (special_sections): Define.
+ (obj_elf_special_section): Get default types and attributes from
+ list of special sections.
+ * config/tc-mips.c (ELF_TC_SPECIAL_SECTIONS): Define.
+
+ * config/obj-ecoff.c (ecoff_frob_file): Force .sdata and .sbss
+ sections to be close together.
+
+ * config/tc-mips.c (macro): Corrected $at warnings in a couple of
+ spots.
+
+ * listing.c (listing_prev_line): New function.
+ * listing.c: Include subsegs.h.
+ (listing_prev_line): New function.
+ (calc_hex): Reset byte_in_frag to zero for each new frag.
+ * config/tc-mips.c (append_insn): Call listing_prev_line after
+ emitting nop instructions.
+ * Makefile.in (listing.o): Depends upon subsegs.h.
+
+Mon Jan 10 09:52:23 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip): Put check for missing label on .PROC
+ here. Handle case where label may be defined after the .PROC.
+ (pa_proc): It is not an error if the procedure's label isn't
+ defined before the .PROC directive.
+
+Sun Jan 9 04:43:30 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config/te-netbsd.h: New file.
+ * config/tc-i386.h (TARGET_FORMAT) [TE_NetBSD]: Use bfd target
+ a.out-netbsd-386 for this configuration.
+
+Fri Jan 7 17:38:28 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_stab): Don't clobber the ECOFF symbol information
+ with the associated stabs information.
+ (ecoff_build_symbols): Never set the type of stabs symbols to
+ st_Global. Don't update the symbol index or ifd if the gas symbol
+ is not the same as the ECOFF symbol (which is now the case for
+ stabs symbols).
+
+Fri Jan 7 11:14:07 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config/tc-mips.c (macro): Add a LOSING_COMPILER ifdef that
+ splits the function.
+ (macro2): New function, if LOSING_COMPILER defined.
+
+Fri Jan 7 09:38:25 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * config/obj-coffbfd.c (fill_section): Don't ever fill past the
+ end of a section. (write_object_file): Temporary fix - setup
+ stdoutput.
+
+Thu Jan 6 18:05:21 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-sparc.c (tc_gen_reloc): Fix handling of addends in
+ non-pcrel_offset relocations.
+
+Thu Jan 6 01:06:40 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Warn about using $1 as well as $at
+ without .set noat.
+
+Wed Jan 5 14:22:22 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * literal.c: New file.
+ * Makefile.in (REAL_SOURCES, OBJS): List it.
+
+ * as.h (DEBUG): Don't define.
+ (struct expressionS, struct fix): Declare in case they're used in
+ prototypes.
+ (add_to_literal_pool) [BFD_ASSEMBLER]: Declare.
+
+ * config/tc-mips.h (TARGET_FORMAT) [OBJ_AOUT]: Fix for new names
+ in bfd.
+
+ * subsegs.c (subseg_get): New function. Creates segment if
+ needed, returns pointer, but doesn't change current segment.
+ (subseg_new): Use it.
+
+Tue Jan 4 15:12:43 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * Makefile.in (INCLUDES): Add $(srcdir)/.. to places to search.
+ * config/obj-ecoff.c: Include files as "bfd/" instead of "../bfd/".
+ * app.c, flonum.h, hex-value.c (const): Change #if to be more
+ portable.
+
+Tue Jan 4 22:11:34 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * config/ho-vsta.h, configure.in: Add support for VSTa
+ micro-kernel.
+
+Thu Dec 30 15:27:16 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * write.c (write_relocs): bfd_perform_relocation now takes an
+ additional argument, to return an error string (which we ignore).
+
+Wed Dec 29 14:37:26 1993 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * write.h (struct fix): Field tc_fix_data should be type PTR, not
+ void*, for compatibility with non-ANSI compilers. Added
+ single-bit field "fx_done".
+
+Sun Dec 26 14:31:47 1993 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * config/tc-hppa.c (pre_defined_registers): Convert to lower case.
+ Delete spurious register names "%r4L", etc.
+ (selector_table): Sort and convert to lower case.
+ (cons_fix_new_hppa): `reloc_type' => `rel_type'.
+ (pa_ip): Always use strcmp for non-text and strcasecmp for text.
+ (reg_name_search): Rewrite to call strcasecmp only once per
+ iteration.
+ (pa_chk_field_selector): Rewrite to use binary search.
+ (pa_parse_neg_add_cmpltr): Use strcasecmp for completer comparisons.
+ (pa_parse_space_stmt): $TEXT$ and $PRIVATE$ are symbols; use case
+ sensitive comparisons.
+ (pa_parse_space_stmt): Canonicalize strncasecmp arg to lower case.
+ (pa_space): "$text$" => "$TEXT$"; "$private$" => "$PRIVATE$". Use
+ case sensitive comparison for all symbolic names.
+ (pa_subspace): Canonicalize strncasecmp arg to lower case.
+ (pa_subspace_start): Use case sensitive comparison for symbolic names.
+
+Mon Dec 20 10:37:48 1993 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * write.c (adjust_reloc_syms) [RELOC_REQUIRES_SYMBOL]: If no
+ symbol is present (i.e., relocation against absolute), create a
+ phony local symbol, and use it in the reloc.
+ (fixup_segment): When adjusting a reloc with an absolute symbol,
+ have TC_FORCE_RELOCATION control clearing add_symbolP too.
+ * config/tc-sparc.h (RELOC_REQUIRES_SYMBOL): Define, for OBJ_COFF.
+
+ * symbols.c (S_IS_EXTERNAL, S_IS_LOCAL): Don't use both BSF_EXPORT
+ and BSF_GLOBAL, since they're the same.
+
+ * as.c (main): Only invoke md_end if it's defined as a macro.
+ * tc.h (md_end): Don't declare it.
+ * config/tc-*.[ch] (md_end): Deleted, in cases where it doesn't do
+ anything.
+ * config/tc-vax.c (vip_end): Deleted null function.
+ * config/tc-mips.c (md_mips_end): Renamed from md_end.
+ * config/tc-mips.h (md_mips_end): Declare.
+ (md_end): New macro, calls md_mips_end.
+
+ * write.c (write_object_file): Don't close output file.
+ * as.c (main): Close output file (if needed) after calling
+ listing_print, which should be after calling write_object_file,
+ which sets the frag addresses.
+
+ * config/obj-coff.c (obj_coff_dim, obj_coff_endef, obj_coff_line,
+ obj_coff_scl, obj_coff_size, obj_coff_tag, obj_coff_type,
+ obj_coff_val): Add unused int argument to satisfy prototypes; goes
+ with Ian's 10 Sep changes.
+ (S_GET_DATA_TYPE, S_SET_DATA_TYPE, S_GET_STORAGE_CLASS,
+ S_SET_STORAGE_CLASS): Now function instead of macros.
+ (obj_emit_lineno) [BFD_ASSEMBLER]: Deleted.
+ (tag_insert): Local var ERROR_STRING is const. Use "const" not
+ "CONST" for argument NAME. Fixed prototype.
+ (coff_frob_symbol): Removed explicit "#if 1" directive. If
+ S_IS_EXTERNAL, set storage class to C_EXT.
+ (s_get_name): Use "const" not "CONST".
+ * config/obj-coff.h (S_GET_DATA_TYPE, S_SET_DATA_TYPE,
+ S_GET_STORAGE_CLASS, S_SET_STORAGE_CLASS): Deleted.
+ (obj_emit_lineno): Declare only for non-BFD_ASSEMBLER. For
+ BFD_ASSEMBLER, define as macro that aborts.
+ (obj_extra_stuff, tc_headers_hook): Declare only for
+ non-BFD_ASSEMBLER.
+ (coff_frob_symbol): Fix prototype.
+
+Sun Dec 19 00:37:20 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (tc_gen_reloc): Test of pcrel_offset had sense
+ reversed.
+
+Thu Dec 16 21:13:11 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_begin): Initialize "dummy_label".
+ (tc_gen_reloc, SOM version): For relocations which have no symbol,
+ set sym_ptr_ptr to dummy_label. Avoids lossage in generic BFD code.
+
+Thu Dec 16 16:07:56 1993 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * read.c (lex_type): No longer make '[' a valid character for
+ symbol names.
+
+ * config/tc-vax.c (tc_aout_fix_to_chars): Local variable
+ NBYTES_R_LENGTH now const.
+
+ * config/obj-*.c, config/tc-*.c: Omit superfluous "return"
+ statements at ends of functions. Don't check for null return from
+ hash_new, since it won't return at all if there's no memory
+ available. Also, check for null return from hash_insert, rather
+ than zero-length string, as success indicator.
+
+ * subsegs.c (section_symbol): New function.
+ * subsegs.h (section_symbol): Declare.
+ * write.c (adjust_reloc_syms): Use it.
+
+Wed Dec 15 15:39:53 1993 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * Makefile.in (RUNTEST): New variable.
+ (CHECKFLAGS): Pass it down.
+
+ * ecoff.c (ecoff_directive_frame): Permit extra trailing operands;
+ unused for now, but supplied by Alpha OSF1 compiler.
+
+ * as.h: Protect against multiple inclusions.
+ (int_to_gen): Don't declare.
+
+ * config/atof-vax.c (atof_vax): NULL is not a valid character
+ constant.
+
+Tue Dec 14 21:38:25 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * configure.in (hppa*-*-osf*): Do not consider this a developmental
+ configuration.
+
+ * config/tc-hppa.c (md_apply_fix): Handle cases where no
+ relocation will be emitted for 32bit formats.
+
+Mon Dec 13 23:33:40 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): Do not call hppa_field_adjust
+ for any of the 'T' field selectors.
+
+Sat Dec 11 11:23:12 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/tc-h8500.c (build_bytes): Get reloc type right for a
+ %page operation. (md_assemble): Don't modify input_line_pointer.
+ (mdcoff_sizemachdep): New function.
+ * config/tc-h8500.h (TC_COFF_SIZEMACHDEP): New macro.
+ * config/tc-z8k.c (get_operand): Delete bogus check.
+
+Wed Dec 8 16:31:51 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * write.c (number_to_chars_*): Delete bogus range check.
+
+ * output-file.c (TARGET_ARCH): No default.
+
+Tue Dec 7 16:02:53 1993 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/tc-sh.c (md_convert_frag): Truncate disps before calling
+ md_number_to_chars. (md_assemble): Don't modify
+ input_line_pointer.
+
+Mon Dec 6 11:49:03 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/tc-h8300.c (md_assemble): Don't update input_line_pointer.
+
+Mon Dec 6 11:20:02 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/obj-som.[ch] (obj_read_begin_hook): Remove last change.
+ Breaks with the HP compilers.
+
+ * config/tc-hppa.c (struct call_info): Remove fields which were
+ set but never used. Remove all code which sets those fields.
+ (struct subspace_dictionary_chain): Likewise.
+ (struct space_dictionary_chain): Likewise.
+ (pa_desc): Delete useless function. Delete all references.
+ (hppa_tc_make_sections): No need to count the number of symbols for
+ the symbol extension section.
+
+Sun Dec 5 17:05:29 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/obj-som.c (obj_som_version): Pass version string to
+ SOM BFD backend.
+ (obj_som_copyright): New function. Much like obj_som_version.
+
+ * config/tc-hppa.c (obj_copyright): Define as appropriate for
+ SOM and ELF.
+ (pa_copyright): Just a stub now.
+
+ * config/obj-som.c (obj_read_begin_hook): Delete unused function.
+ * config/obj-som.h (obj_read_begin_hook): Provide dummy definition.
+ (TARGET_SYMBOL_FIELDS): Delete. SOM isn't making use of them.
+
+ * config/tc-hppa.c (tc_gen_reloc, SOM version): Handle relocation
+ expansion due to rounding mode selectors. Handle R_[RDSN]_MODE
+ relocations for selecting the current rounding mode.
+
+ * config/tc-hppa.c (evaluate_absolute): Support e_rrsel and
+ e_rlsel field selectors.
+
+Fri Dec 3 18:33:24 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-elf.h: If ECOFF_DEBUGGING, undef
+ SEPARATE_STAB_SECTIONS and INIT_STAB_SECTION, and define
+ OBJ_PROCESS_STAB to call ecoff_stab.
+ * config/obj-elf.c: Don't compile obj_elf_init_stab_section if
+ INIT_STAB_SECTION is not defined.
+
+Fri Dec 3 10:56:40 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): Delete old wrapper function.
+ (md_apply_fix_1): Rename to md_apply_fix. Fix argument decls.
+ Fix comments in various places. Always return a value.
+ Avoid dereferencing a NULL fx_addsy.
+ (hppa_force_relocation): Avoid dereferencing a NULL fx_addsy.
+
+ Fri Dec 3 09:47:30 1993 Pete Hoogenboom (hoogen@cs.utah.edu)
+
+ * config/tc-hppa.c: (tc_gen_reloc): Addend for a plabel relocation should
+ be either 0 or 2 (no static link or static link required). Always
+ assume no static link.
+
+Thu Dec 2 11:52:21 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/tc-sparc.c (tc_gen_reloc): Make adjustment to addend be
+ dependent on howto fields, not on format flavour.
+
+ * struc-symbol.h (struct symbol): New fields sy_obj and sy_tc,
+ defined as types OBJ_SYMFIELD_TYPE and TC_SYMFIELD_TYPE, if those
+ macros are defined.
+ * config/obj-coff.h (TC_SYMFIELD_TYPE, OBJ_SYMFIELD_TYPE): Define.
+ (TARGET_SYMBOL_FIELDS, I960_SYM_FIELDS): Don't define.
+ (sy_tc, sy_obj): Define so that the fields look like they used to,
+ until all references get changed.
+
+ * write.c (fixup_segment): Lots of variables no longer register.
+ Reordered some code for easier reading.
+ * config/obj-coff.c (obj_coff_dim): dim_index no longer register.
+ Deleted superfluous return statement.
+ (obj_coff_line, obj_coff_size, obj_coff_scl, obj_coff_type,
+ obj_coff_val, tag_init, tag_insert): Deleted superfluous return
+ statement.
+ (align, obj_coff_section): Deleted debugging printfs.
+ * config/tc-i386.c (md_assemble): Discard some register decls.
+ Use assignment rather than memcpy to copy template.
+ (op_hash, reg_hash, prefix_hash): Default C initialization of
+ statics is sufficient.
+ * config/tc-sparc.c (print_insn): Array Reloc is now const, and
+ points to const.
+
+ * config/obj-coff.h (TARGET_FORMAT): Only use coff-sparc-lynx if
+ TE_LYNX; use coff-sparc otherwise.
+ [USE_NATIVE_HEADERS]: Delete this code; it isn't used.
+
+ * write.c (fixup_segment): Call TC_VALIDATE_FIX, if defined,
+ before processing a fixup. Call TC_ADJUST_RELOC_COUNT just before
+ returning. Remove some i960-coff-specific code.
+ (TC_ADJUST_RELOC_COUNT): Default to doing nothing.
+ * config/tc-i960.h (TC_ADJUST_RELOC_COUNT) [OBJ_COFF]: Define.
+ (i960_validate_fix): Declare.
+ (TC_VALIDATE_FIX): Define.
+ * config/tc-i960.c (i960_validate_fix): New function.
+
+ * write.c (number_to_chars_littleendian): New function. Write out
+ bytes in little endian order, doing size and range checking.
+ (number_to_chars_bigendian): New function, similar.
+ * write.h: Declare them.
+ * config/tc-*.c (md_number_to_chars): Use them.
+ * config/tc-vax.c (md_apply_fix): Ditto.
+ * config/tc-i386.c (md_apply_fix): Ditto.
+
+ * config/obj-coff.c: Rearranged code for handling line number
+ data.
+ (line_fsym): Renamed from function_lineoff in BFD_ASSEMBLER case,
+ since the usage is different from non-BFD_ASSEMBLER case.
+ (in_function, clear_function, set_function): New macros, to
+ combine some of the functionality implemented in differnet ways in
+ BFD_ASSEMBLER and non-... code. Used in other functions that used
+ to check function_lineoff &c.
+ (obj_emit_lineno): Split into two copies, one for BFD_ASSEMBLER,
+ one for not. Non-BFD_ASSEMBLER version now has temporary variable
+ to contain char* pointer pointed to by char** argument. Always
+ follow CROSS_COMPILE code; easier to read that way.
+ (obj_coff_ln): Don't call add_lineno or c_line_new if appline is
+ set.
+ (obj_coff_endef) [BFD_ASSEMBLER]: Don't do anything special for
+ ".bf", it's been done elsewhere.
+ (coff_frob_symbol): If ilne number data is pending, call
+ add_linesym to flush it.
+ (coff_frob_file): Don't do that here.
+ * config/obj-coff.h (coff_frob_file): Declare.
+ (obj_frob_file): Define, to call it.
+
+ * config/tc-sparc.h (md_create_short_jump, md_create_long_jump,
+ md_estimate_size_before_relax: Define them as macros calling
+ as_fatal.
+ * config/tc-sparc.c: Don't define them as functions.
+
+ * configure.in: Handle target alpha-*-osf*. (No cpu files yet.)
+
+Wed Dec 1 23:37:14 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Makefile (clean): Depend on clean-here.
+
+Wed Dec 1 11:35:21 1993 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/ho-go32.h: Include fopen-bin.h.
+ * as.h: If FOPEN_WB isn't defined, include fopen-same.h.
+ * output-file.c (output_file_create): Use FOPEN_WB instead of "w".
+ * input-file.c (input_file_open): Use FOPEN_RT instead of "r".
+ * listing.c (file_info): Use FOPEN_RB instead of "rb".
+ * read.c (s_include): Use FOPEN_RT instead of "r".
+
+ * stabs.c: Include obstack.h.
+
+ * tc.h (md_create_long_jump): Don't declare if it's already
+ defined as a macro.
+ (md_create_short_jump, md_estimate_size_before_relax): Ditto.
+
+ * messages.c (as_perror) [BFD_ASSEMBLER]: Use bfd_errmsg instead
+ of strerror. Clear bfd_error.
+
+ * config/te-lynx.h (LOCAL_LABELS_FB): Define, if not already
+ defined.
+
+Wed Dec 1 10:41:56 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (hppa_elf_mark_end_of_function): New function.
+ (pa_process_exit, pa_procend): Call it for ELF objects.
+
+Wed Dec 1 12:10:41 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (macro): Subtract 8 from offset in non PIC l.d
+ case. See comment. From wilson@cygnus.com: for M_L_DAB, set
+ coproc before doing goto ld.
+
+Tue Nov 30 13:40:30 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * write.c (TC_FORCE_RELOCATION): Provide a default definition.
+ (fixup_segment): Allow the target machine to specify that a
+ relocation must be generated for a particular fixup. Remove
+ #ifndef TC_HPPA hack.
+
+ * config/tc-hppa.h (TC_FORCE_RELOCATION): Define.
+
+ * config/tc-hppa.c (md_apply_fix_1): Never change fx_addsy to
+ be NULL. Only fixup_segment is supposed to do that.
+ (hppa_force_relocation): New function.
+
+Tue Nov 30 11:21:41 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (stabs.o): Added dependencies.
+
+ * config/obj-ecoff.c (ecoff_frob_file): Don't call bfd_set_symtab.
+
+Sun Nov 28 12:11:40 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * app.c (do_scrub_next_char): Output a TAB before any
+ .app* directive.
+
+ * config/tc-hppa.c (fix_new_hppa): Make sure a sub_symbol
+ exists before trying to peek at its name.
+ (pa_space): Do not call pa_align_subseg. See hppa/unsorted/align3.s
+ for testcase.
+ (pa_align_subseg): Delete unused/unwanted function.
+
+Sat Nov 27 22:49:07 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * read.c (read_a_source_file): Fix test for when to stick a colon
+ on the end of a label. Make code conditional on either MRI or
+ LABELS_WITHOUT_COLONS.
+
+ * app.c (do_scrub_next_char): If a line begins with whitespace, leave
+ the single whitespace character alone. Eat all others.
+
+ * config/tc-hppa.h (LABELS_WITHOUT_COLONS): Define.
+
+Wed Nov 24 01:22:54 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_procend): Do not call process_exit.
+ (exit_processing_complete): Delete unwanted variable and all
+ references.
+
+Wed Nov 24 02:31:38 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_setup_ext): Renamed from ecoff_build_ext.
+ Changed to not actually build the external symbol information, as
+ that is now done by the ECOFF back end.
+ (ecoff_build_debug): Changed accordingly.
+ * ecoff.h (obj_ecoff_set_ext): Declare. obj-format.c function
+ called by ecoff_setup_ext.
+ * config/obj-ecoff.c (ecoff_frob_file): If debug_info count is 0,
+ set corresponding pointer to NULL. Don't set raw_size and
+ raw_syments.
+ (obj_ecoff_set_sym_index): Removed.
+ (obj_ecoff_set_ext): New function.
+ * config/obj-ecoff.h (obj_set_sym_index): Don't define.
+ (obj_ecoff_set_sym_index): Don't declare.
+ * config/obj-elf.c (obj_ecoff_set_ext, elf_get_extr,
+ elf_set_index): New functions used for ECOFF_DEBUGGING.
+ (elf_frob_file): Reworked ECOFF debug generation to use
+ new functions in bfd/ecofflink.c.
+
+Sun Nov 21 23:54:52 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_def_subspaces): Only create the unwind
+ subspace for ELF. In the SOM world, the linker is responsible
+ for creating the unwind subspaces.
+
+Fri Nov 19 16:25:09 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-coffbfd.c: Use PARAMS rather than EXFUN.
+ (yank_symbols): Don't call S_SET_EXTERNAL if the storage class is
+ already set. Fixes .def var; .val external_var; .scl 3; .endef.
+ (adjust_stab_section): Make static. Declare return type. Remove
+ unused variables.
+
+ * config/tc-i386.h: Declare tc_coff_fix2rtype and
+ tc_coff_sizemachdep.
+
+Fri Nov 19 04:33:59 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * write.c (write_object_file): Disable obj_check_file_symbols
+ hook; only back end using it wasn't using it correctly.
+ (write_object_file): Always call obj_frob_symbol and
+ tc_frob_symbol; always retain symbol if it's used by a relocation,
+ regardless of what these routines indicate.
+ * config/obj-coff.c (coff_frob_symbol): Renamed from
+ coff_check_file_symbols.
+ * config/obj-coff.h (obj_check_file_symbols): Deleted.
+ (coff_frob_symbol): Declare.
+ (obj_frob_symbol): Call it.
+
+ * config/obj-coff.c (obj_crawl_symbol_chain, obj_emit_strings,
+ obj_pre_write_hook): Don't define for BFD_ASSEMBLER.
+ (c_section_header): Ditto. Delete superfluous return at end of
+ function.
+
+ * config/obj-coff.h [TC_SPARC]: Include coff/sparc.h, and specify
+ coff-sparc-lynx.
+ (SA_GET_SYM_TAGNDX): Use BFD_HEADERS version for BFD_ASSEMBLER
+ too.
+ (c_section_header): Rewrite prototype so that it contains no
+ preprocessing directives. Don't declare it at all if
+ BFD_ASSEMBLER.
+
+ * configure.in (sparc*-*-lynxos): New target, using coff and
+ BFD_ASSEMBLER.
+
+ * stabs.c: New file.
+ * Makefile.in (REAL_SOURCES, OBJS): List it.
+ * read.c (STAB_SECTION_NAME, STAB_STRING_SECTION_NAME,
+ get_stab_string_offset, s_stab_generic, s_stab, s_xstab, s_desc):
+ Moved to new file.
+
+ * config/tc-sparc.c (tc_gen_reloc): Handle coff files like elf
+ files.
+
+Wed Nov 17 17:23:53 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in (mips-*-irix5*): New target. Use elf and mips-big.
+ * config/obj-elf.c: If ECOFF_DEBUGGING, include ecoff.h.
+ (obj_pseudo_table): If ECOFF_DEBUGGING, define ECOFF
+ pseudo-ops.
+ (obj_read_begin_hook): If ECOFF_DEBUGGING, call
+ ecoff_read_begin_hook.
+ (obj_symbol_new_hook): If ECOFF_DEBUGGING, call
+ ecoff_symbol_new_hook.
+ (obj_elf_init_stab_section): Cast alloca result.
+ (elf_frob_file): If ECOFF_DEBUGGING, finish up ECOFF debugging
+ information and write it out into .mdebug section.
+ * config/obj-elf.h (ELF_TARGET_SYMBOL_FIELDS): New macro.
+ (TARGET_SYMBOL_FIELDS): Use ELF_TARGET_SYMBOL_FIELDS.
+ (ECOFF_DEBUGGING): Define if TC_MIPS.
+ (TARGET_SYMBOL_FIELDS): If ECOFF_DEBUGGING, override to add
+ fields required by ECOFF.
+ * config/tc-mips.c: Check ECOFF_DEBUGGING rather than
+ OBJ_ECOFF in many cases.
+ (mips_any_noreorder): New variable.
+ (mips_cprestore_offset): Initialize to -1.
+ (mips_frame_reg): New variable.
+ (RELAX_ENCODE, RELAX_OLD, RELAX_NEW, RELAX_RELOC1,
+ RELAX_RELOC2, RELAX_RELOC3, RELAX_WARN): New macros.
+ (md_pseudo_table): Handle "gpword" and "cpadd".
+ (md_begin): Initialize ok to false. If OBJ_ELF, set alignment
+ of text, data and bss sections to 4. Set alignment of
+ .reginfo section to 2. If ECOFF_DEBUGGING, create .mdebug
+ section.
+ (ALIGN_ERR, ALIGN_ERR2): Removed unused and useless alignment
+ check.
+ (append_insn, macro_build, macro_build_lui): Take place
+ argument. Changed all callers.
+ (append_insn): If appending a nop, don't emit one.
+ (macro_build): Changed assertion for 'i', 'j', 'o' case.
+ (gp_reference): Removed.
+ (load_address): New function.
+ (macro): If mips_noreorder is used, set mips_any_noreorder.
+ Extensive changes to handle GP and PIC symbols differently.
+ Build both possible code choices using a variant frag, and
+ make a final decision at the end of assembly when all
+ information is known. Added PIC support for all symbol
+ references.
+ (mips_ip): Don't permit anything but a number after $ for a
+ coprocessor register. Don't use .lit4 or .lit8 sections when
+ generating PIC code. If OBJ_ELF, set alignment of .lit4 or
+ .lit8 section to 4.
+ (md_apply_fix): Accept and ignore GOT16 and GPREL32 relocs.
+ (s_change_sec): Set alignment of ELF .rodata or .sdata section
+ to 4.
+ (s_mipsset): If .set noreorder, set mips_any_noreorder.
+ (s_cpload): Ignore .cpload if not generating PIC code. Warn
+ if .cpload is not in noreorder section.
+ (s_cprestore): Ignore .cprestore if not generating PIC code.
+ (s_gpword, s_cpadd): New functions.
+ (tc_get_register): Added frame argument; if true, set
+ mips_frame_reg to return value. Changed all callers.
+ (md_estimate_size_before_relax): Don't error out, but instead
+ determine how much a frag should grow.
+ (tc_gen_reloc): Return multiple relocs if appropriate, as
+ determined by md_estimate_size_before_relax.
+ (md_convert_frag): New function.
+ (mips_elf_final_processing): Set ELF header flags based on
+ mips_any_noreorder and mips_pic.
+ * config/tc-mips.h (RELOC_EXPANSION_POSSIBLE): Define.
+ (MAX_RELOC_EXPANSION): Define to be 3.
+ (md_relax_frag): Define to be 0.
+ (md_convert_frag): Don't define.
+ (tc_get_register): Changed declaration.
+
+ * ecoff.h, ecoff.c: New files pulled out of config/obj-ecoff.c to
+ support generating ECOFF debugging information for MIPS ELF
+ targets. Compiled only if ECOFF_DEBUGGING is defined. Changed
+ handling of external symbols: it now always generates exactly
+ those external symbols that are defined in the global symbol list.
+ * Makefile.in (REAL_SOURCES): Added ecoff.c.
+ (REAL_HEADERS): Added ecoff.h.
+ (OBJS): Added ecoff.o.
+ (ecoff.o): New target.
+ * config/obj-ecoff.c: Almost entirely moved into ecoff.c.
+ Remaining code mostly just calls ecoff.c code.
+ * config/obj-ecoff.h: Define ECOFF_DEBUGGING.
+ (TARGET_SYMBOL_FIELDS): Make ecoff_symbol a pointer to a
+ struct localsym.
+ (obj_read_begin_hook, obj_symbol_new_hook): Define to call
+ functions in ecoff.c.
+ (ecoff_stab): Don't declare (now declared in ecoff.h).
+ (obj_set_sym_index): Define.
+ (obj_ecoff_set_sym_index): Declare.
+
+ * frags.h (frag_grow): Declare.
+ * frags.c (frag_grow): Made non-static.
+
+ * write.c (is_dnrange): Do not define if md_relax_frag is defined.
+ (relax_segment): If md_relax_frag is defined, use it to handle a
+ frag of type rs_machine_dependent rather than looking through
+ md_relax_table.
+
+ * read.c (read_a_source_file): If we find a bad pseudo-op,
+ do a continue to go on to the next line rather than a break.
+ Removed duplicate bad pseudo-op code which was never executed.
+
+ * read.c (s_lcomm): Do not require a comma after the name.
+
+ * subsegs.h (segment_info_type): Changed hadone field to bitfield.
+ Added bss bitfield.
+ * as.c (perform_an_assembly_pass): Set bss flag for bss_section.
+ * read.c (s_lcomm): Set bss flag for .sbss section if used.
+ * write.c (relax_and_size_seg): Don't set SEC_HAS_CONTENTS for a
+ bss section. Set SEC_RELOC if there are any relocations, even for
+ a zero size section.
+
+ * write.c (write_relocs): In RELOC_EXPANSION_POSSIBLE case, base
+ data offset on reloc[0]->address rather than reloc[j]->address, so
+ that multiple relocs can affect different memory locations.
+
+ * write.c (chain_frchains_together, relax_and_size_seg,
+ adjust_reloc_syms, write_relocs): Make third argument PTR, not
+ char *, to match definition of bfd_map_over_sections.
+
+ * app.c (do_scrub_next_char): Don't interpret a comment character
+ as starting a CPP line directive unless it is a '#' and is the
+ very first characters on the line (i.e., do not permit leading
+ whitespace).
+
+ * messages.c (identify): Make file argument non-const, to match
+ callers.
+
+Tue Nov 16 20:38:21 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip): Fix thinko in 21bit range check.
+
+Sat Nov 13 18:22:48 1993 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/tc-sh.c (md_apply_fix): Cope with IMM16 type too.
+ * config/tc-z8k.c (build_bytes, md_apply_fix): Understand nDISP7
+ relocs.
+
+Fri Nov 12 16:51:47 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.[ch]: Fix assorted trivial indention problems.
+ * config/obj-som.c (obj_som_version): Add missing ';'.
+ (som_frob_file): Delete whitespace at EOL.
+
+Fri Nov 12 15:26:21 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * Makefile.in (VERSION): Updated following 2.2 release.
+
+Fri Nov 12 14:52:17 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (hppa_fix_struct): Use a real type for the
+ field selector, rather than an int. All uses of field selectors
+ fixed.
+ (tc_gen_reloc): For SOM PLABELs, always set addend to zero for now.
+ (md_apply_fix_1): Do not call hppa_field_adjust for any PLABEL
+ field.
+
+ Thu Nov 11 15:49:08 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_type_args): For .import statements,
+ silently ignore attempt to change the symbol type for a function
+ from ST_ENTRY to ST_CODE on .import.
+
+Wed Nov 10 16:19:13 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * write.h (fixS): Rename fx_callj field to fx_tcbit.
+ * write.c, config/obj-coff.c, config/obj-coffbfd.c,
+ config/tc-i960.c: Corresponding changes.
+
+Tue Nov 9 00:49:01 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Makefile.in (distclean): Delete config-stamp and config.h
+
+ * config/tc-hppa.c (evaluate_absolute): Avoid relying on
+ ANSI-C features.
+
+ * config/tc-hppa.c (pa_type_args): Renamed from pa_export_args.
+ Accept new argument "is_export". All callers changed. When
+ processing a .export directive for a function, do not allow
+ the user to set the type to "CODE", instead warn and set the
+ type to "ENTRY".
+
+Mon Nov 8 12:05:07 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_ip, printInsn): Handle 'k' (from Ted
+ Lemon <mellon@pepper.ncd.com>).
+ (mips_ip): Permit odd numbered floating point registers if -mips3.
+ (macro): Use BFD_RELOC_MIPS_LITERAL relocation for M_LI_SS.
+
+Mon Nov 8 07:45:01 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * configure.in: Remove h8300h, we have multilib now.
+
+Mon Nov 8 06:09:18 1993 D. V. Henkel-Wallace (gumby@cirdan.cygnus.com)
+
+ * configure.in: Support generic netware as being ELF format.
+ Recognise unixware if the user supplies it.
+
+Sun Nov 7 01:02:08 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * First cut at cleaning up PA instruction parsing.
+ * config/tc-hppa.c (pa_get_absolute_expression): Accept pointer to
+ insn structure as an argument, and a pointer to a string. All
+ callers changed. Always read any field selector here. Call
+ evaluate absolute to get a return value.
+ (evaluate_absolute): Addept pointer to insn structure as its
+ argument. All callers changed.
+ (INSERT_FIELD_AND_CONTINUE): New macro for inserting a bitfield
+ into an instruction and continuing the main pa_ip loop.
+ (CHECK_FIELD): New macro for simple range checking of fields.
+ (pa_ip): Delete unused variables. Use INSERT_FIELD_AND_CONTINUE
+ and CHECK_FIELD. All immediate fields now pass through
+ pa_get_absolute_expression which will also handle field selectors.
+ Delete dead code. Simplify.
+ (md_apply_fix_1): Use CHECK_FIELD to verify any fixes that are
+ applied are in range. Use bfd_put_32 rather than inserting each
+ byte of the fixed instrution into the buffer ourselves.
+
+ * write.c (fixup_segment): Delete {SEG,GLOBAL}_DIFF_ALLOWED code,
+ it was PA specific and is no longer needed (it's now handled
+ within the PA backend).
+ * config/tc-hppa.h (SEG_DIFF_ALLOWED): Delete definition.
+ * config/tc-hppa.c (fix_new_hppa): If the subtract symbol for
+ a fixup is $global$ change it to NULL as $global$ is really only
+ needed long enough to determine the base type of relocation to use.
+
+ * config/tc-hppa.c (create_new_subspace): Initialize subspace_defined.
+
+ * config/tc-hppa.c (pa-ip, case 'z'): Make field selectors work
+ for 'z' operands (target of ble branch).
+
+Sat Nov 6 22:41:57 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: (update_subspace): Fix type and name of last
+ parameter. All callers fixed.
+ (md_begin, pa_chk_field_selector, pa_entry): Lint.
+
+ * config/tc-hppa.c (cons_fix_new_hppa): Reset field selector
+ to default state after it's been used.
+
+Fri Nov 5 12:08:21 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/obj-som.c (obj_som_init_stab_section): Change
+ space/subspace sort keys for the stab sections so as to avoid
+ bugs in the hp linker and pxdb.
+
+Thu Nov 4 17:00:05 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * write.c (chain_frchains_together): Update pointer to last
+ frag for a segment in the seginfo structure.
+
+Thu Nov 04 09:09:35 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * Makefile.in: Changed RUNTESTFLAGS to RUNTEST_FLAGS
+
+Wed Nov 3 12:16:27 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * write.c (fixup_segment): Handle conversion of subtraction to
+ pc-relative addressing even if pc-relative flag is already set.
+
+ * config/tc-m68k.c (m68k_ip_op): Use strchr, not index. Don't
+ declare either.
+
+ * doc/Makefile.in (distclean): Delete intermediate files from dvi
+ build, but not the dvi or info files.
+ * Makefile.in (clean-here): New target; cleans up current
+ directory only.
+ (distclean): Use it instead of clean.
+
+ * read.c (s_xstab): Don't use alloca.
+
+ * messages.c (identify): New routine; print message identifying
+ following messages as coming from assembler.
+ (as_show_where, as_bad_internal, as_bad_where): Call it.
+ (as_fatal): Don't need to identify program any more.
+
+Tue Nov 2 18:04:11 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Add default case to reloc switch.
+
+ * read.c (s_lcomm): Put small objects in .sbss for MIPS ELF as
+ well as MIPS ECOFF.
+ (get_stab_string_offset): Remove unused variable aligned.
+
+Tue Nov 2 15:07:07 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: Add %dp and %rp as synonyms for %r27 and %r2 in the
+ predefined register table.
+ (pa_parse_number): Handle %rp in common register shortcut code.
+ Consistently set return value to -1 for an error. Clean up error
+ messages and only print them when "print_errors" is true. Handle
+ empty string case like the HP assembler -- assume a value of
+ zero.
+
+ * config/ho-hpux.h: Do not include ho-sysv.h. Instead include
+ standard hpux include files to pick up various function decls.
+
+ * config/ho-hppaosf.h: Delete _IO* macros. They are defined in
+ stdio.h. Delete bogus declaration of free. Get path to
+ alloca-conf.h right.
+
+Tue Nov 2 13:57:30 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * expr.c (operand): Fix checks for characters following "0b" or
+ "0f".
+
+Mon Nov 1 21:37:04 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/obj-som.h (obj_attach_unwind_info): Define as a hook
+ so GAS can attach unwind descriptor information to a BFD symbol.
+ * config/tc-hppa.c (fix_new_hppa): If necessary attach unwind
+ descriptor information to the BFD symbol.
+ (md_apply_fix): R_HPPA_ENTRY and R_HPPA_EXIT can never be "applied",
+ they are simply markers. Make R_HPPA_UNWIND_* handling OBJ_ELF
+ dependent.
+ (pa_build_unwind_subspace): Whole function is OBJ_ELF dependent.
+ (pa_entry): Build a R_HPPA_ENTRY relocation when configured for SOM.
+ (pa_exit): Likewise, but built a R_HPPA_EXIT relocation. Do not
+ build "end-of-function" symbols for SOM, they are not needed.
+
+ * config/tc-hppa.c (process_exit): Create temporary symbols with
+ correct prefixes so they can be eliminated later.
+
+ * config/tc-hppa.c (call_info struct): Delete unused "frame" field.
+ (pa_callinfo): Insert framesize into the unwind information as
+ soon as it's available.
+ (pa_build_unwind_subspace): Do not insert framesize into the unwind
+ information here.
+
+ * Add support for marker type relocations. These mark areas
+ of interest to the linker. ENTRY/EXIT relocations for SOM are
+ an example of marker relocations.
+ * write.c (write_relocs): Instead of assuming size of a relocation
+ is 4 bytes, pick up the size from relocation itself.
+ (fixup_segment): Do not complain that a value is too small for
+ marker relocations.
+
+ * struc-symbol.h: Add new "sy_used" field to the symbol structure.
+ * expr.c (operand): Set sy_used for any symbol used as an operand.
+ (expr): Likewise for any symbol used in an expression.
+ * config/tc-hppa.h (tc_frob_symbol): Define. Punt imported
+ symbols which are never used and absolute symbols which local scope.
+
+ * config/obj-som.h (obj_frob_file): Define.
+ * config/obj-som.c (obj_som_init_stab_section): Set alignment
+ of stab sections. Make space for the special stab entry.
+ (adjust_stab_sections): Adjust the special entry in the
+ stabs section.
+ (som_frob_file): New function. Simply calls adjust_stab_sections
+ for each section.
+
+Mon Nov 1 17:54:29 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (PIC_CALL_REG, SP, FP): Define.
+ (mips_pic, mips_cprestore_offset): New static variables.
+ (md_pseudo_table): Handle .abicalls, .cpload, and .cprestore.
+ Ignore .bgnb and .endb.
+ (gp_reference): _gp_disp is never addressed off GP.
+ (macro_build): Ignore macros while searching for insn. For cases
+ i, j, and o, accept the reloc type as an argument rather than
+ assuming BFD_RELOC_LO16. Don't try to convert BFD_RELOC_LO16 to
+ BFD_RELOC_MIPS_GPREL. Added new case a.
+ (set_at, load_register, macro): Changed calls to macro_build to
+ pass new argument for i, j and o cases.
+ (macro): Handle M_JAL_1, M_JAL_2 and M_JAL_A. These require
+ special handling when generating SVR4 PIC code.
+ (mips_ip, tc_get_register, s_frame): Use macros FP, SP, GP and AT
+ rather than hard coded constants.
+ (md_apply_fix): Handle BFD_RELOC_MIPS_LITERAL and
+ BFD_RELOC_MIPS_CALL16.
+ (s_option): Set mips_pic based on .option picN.
+ (s_abicalls): New function; set mips_pic to 2.
+ (s_cpload): New function; handle .cpload.
+ (s_cprestore): New function; handle .cprestore.
+
+ * config/obj-ecoff.c (obj_pseudo_table): Add entries for .bgnb,
+ .endb and .verstamp, setting them to s_ignore.
+
+Sun Oct 31 00:36:40 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (subspace_dictionary_chain): Add new ssd_defined
+ field. Define SUBSPACE_DEFINED accessor macro.
+ (pa_subspace): Allow user to override subspace attributes for
+ built-in subspaces. Set ssd_defined at the end of fcn -- that
+ way the attributes can only be changed once. Pass newly allocated
+ name to is_defined_subspace, not a pointer to the input line.
+ Fix typo in space/subspace rework.
+ (is_defined_subspace): Delete unused 2nd arg. All callers changed.
+
+ * config/tc-hppa.c (pa_import): If currently in the text segment
+ and a symbol is imported without type information, set BSF_FUNCTION
+ for the symbol.
+ * write.c (relax_and_size_seg): Correct test to determine if
+ the section's size was rounded up.
+
+ * config/obj-som.h (obj_set_symbol_type): Define a hook so GAS
+ can properly set all the SOM symbol types.
+ * config/tc-hppa.c (pa_symbol_type): New enum to represent the
+ symbol types which can be set from an IMPORT/EXPORT statement.
+ (pa_export_args): Set the pa_symbol_type type based on arguments.
+ If defined, call obj_set_symbol_type to pass this information on
+ to the BFD backend.
+
+ * read.c (get_stab_string_offset): Set SEC_DEBUGGING for any
+ stab section we make.
+ (s_stab_generic): Likewise.
+
+Sat Oct 30 14:26:20 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Allow backends to override the value of the fake label.
+ * write.h (LOCAL_LABEL): Delete DOT_LABEL_PREFIX code. Instead
+ assume backends will define LOCAL_LABEL if anything other than
+ 'L' is used to denote a local label.
+ (FAKE_LABEL_NAME): New macro. Defines the default name used for
+ the "fake" label.
+ * expr.c (make_expr_symbol): Delete DOT_LABEL_PREFIX code
+ and instead simply use the string defined by FAKE_LABEL_NAME.
+ (operand): Likewise.
+ * read.c (s_stab_generic): Likewise.
+ * config/tc-hppa.h (FAKE_LABEL_NAME): Define as L$0\001 so it's
+ known to be a local label.
+ * config/tc-i386.h (DOT_LABEL_PREFIX): Delete.
+ (LOCAL_LABEL, FAKE_LABEL_NAME): Define.
+ * config/tc-m68k.h (DOT_LABEL_PREFIX): Delete.
+ (LOCAL_LABEL, FAKE_LABEL_NAME): Define.
+ * config/te-sco386.h (DOT_LABEL_PREFIX): Delete.
+ (LOCAL_LABEL, FAKE_LABEL_NAME): Define.
+
+ Rework space/subspace handling in PA code to fully support
+ SOM spaces/subspaces.
+ * config/tc-hppa.c (USE_ALIASES): New object-format dependent define
+ to control the use of space/subspace name aliases.
+ (update_subspace): Accept space chain entry for containing space
+ as a new parameter. All callers changed.
+ (pa_get_label): Use current_space rather than pa_segment_to_space.
+ (pa_define_label): Likewise.
+ (pa_undefine_label): Likewise.
+ (md_begin): Change into the (possibly modified) text_section.
+ (pa_parse_space_stmt): Create a new segment/space if create_flag
+ is true, and the space name is not one of the two predefined spaces.
+ (pa_subspace): Use current_space rather than a lookup via
+ pa_segment_to_space. Reset BFD section flags as required by
+ the .subspace directive. Likewise for the section alignment.
+ Pass the current space to update_subspace and create_new_subspace.
+ (pa_spaces_begin): Only use space/subspace aliases if USE_ALIASES
+ is true. When not using aliases, create a BFD section for each
+ subspace encountered. When not using aliases replace the default
+ text, data, and bss segments with new ones.
+ (create_new_subspace): When not using aliases each subspace has a
+ section/segment and subsegments are not needed, so set the subsegment
+ to zero.
+
+ * config/tc-hppa.c (pa_parse_space_stmt): If needed, call
+ obj_set_section_attributes to pass space attributes to the
+ BFD backend.
+ (create_new_space): Likewise.
+ (create_new_subspace): Likewise for subspace attributes using
+ obj_set_subsection_attributes.
+ (update_subspace): Likewise for subspace attributes using
+ obj_set_subsection_attributes.
+
+ * config/tc-hppa.c (pa_parse_space_stmt): Get segment and sort key
+ for $TEXT$ and $PRIVATE$ from the default space structure.
+
+ * config/tc-hppa.c (pa_export_args): Always set BSF_FUNCTION
+ as appropriate for the given type.
+
+ * config/tc-hppa.c (tc_gen_reloc): Preliminary stab at handling
+ SOM relocations.
+
+ * config/tc-hppa.c (pa_comm): Delete incorrect check for symbol
+ redefinition.
+
+ * config/obj-som.[ch]: New files for SOM support. Note SOM
+ support is not yet complete in GAS or BFD.
+
+ * config/ho-hppabsd.h: Delete IO* macros, they are defined in
+ stdio.h. Delete declaration of free. Include stdlib.h, unistd.h,
+ and string.h.
+
+Fri Oct 29 13:26:12 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Allow backends to override the section names used for embedded
+ stabs support. Needed for SOM.
+ * read.c (STAB_SECTION_NAME): Default the name of the stab section
+ to ".stab".
+ (STAB_STRING_SECTION_NAME): Likewise for the stab strings section.
+ (get_stab_string_offset): Is now passed the full name for the
+ stab string section rather than a name prefix. All references
+ changed.
+ (s_stab_generic): New argument for the stab string section name.
+ all references changed.
+ (s_xstab): Append "str" to the stab section name to get the
+ stab string section name.
+ * config/obj-coffbfd.c (obj_coff_init_stab_section): Append "str"
+ to stab section name to get the stab string section name. Pass
+ the full name of the stab string section to get_stab_string_offset.
+ * config/obj-elf.c (obj_elf_init_stab_section): Likewise.
+
+ * config/tc-hppa.c (md_begin): Disable "-R" option to fold
+ textand data segments. Warn user "-R" is unsupported on the
+ PA.
+
+Thu Oct 28 12:36:13 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_pseudo_table): Default alignment is 8 for
+ .align and .ALIGN directives.
+
+ * config/tc-hppa.c (pa_space): Do not report an error for a .space
+ directive which does not define a "well-known" space and does
+ not include a space number as an argument.
+
+ * config/tc-hppa.c (pa_def_subspaces): Correct initialization of the
+ "defined", "loadable", "code_only" and "space_index" fields.
+ (pa_def_spaces): Correct initialization of the "spnum", "defined",
+ and "private" fields.
+
+ * write.h (struct fix): Add new tc_fix_data field for the various
+ backends to attach machine dependent fixup information to.
+ * write.c (fix_new_internal): Initialize new tc_fix_data field.
+ * config/tc-hppa.c (hppa_fix_struct): Delete unnecessary fix_fixP and
+ fx_next fields.
+ (hppa_find_hppa_fix): Delete unnecessary function. Fix all
+ callers to get HPPA fixup information from the tc_fix_data field
+ in the GAS fixup.
+ (hppa_fix_root): Delete unnecessary variable.
+ (fix_new_hppa): Attach HPPA fixup data to the GAS fixup.
+
+ * config/tc-hppa.c (pa_set_start_symbol); Delete unwanted
+ function. Fix all callers.
+ (subspace_dictionary_chain): Delete unused ssd_start_sym field.
+
+ * config/tc-hppa.c (hppa_fix_adjustable): New function to determine
+ if a particular fixup is adjustable.
+ * config/tc-hppa.h (tc_fix_adjustable): Call hppa_fix_adjustable to
+ perform the real work.
+
+ * config/tc-hppa.h (RELOC_EXPANSION_POSSIBLE): Move definition out
+ of OBJ_XXX conditionals.
+ (MAX_RELOC_EXPANSION): Likewise.
+
+ * config/tc-hppa.c (log2): Renamed from is_power_of_2. Fix all
+ callers. Now returns log2 (N) for positive N which are an exact
+ power of two or -1 for an error.
+
+ * config/tc-hppa.c (pa_callinfo): Range check values provided for
+ ENTRY_GR, ENTRY_FR and ENTRY_SR. Properly adjust vaues before
+ inserting them into the unwind table.
+
+ * config/tc-hppa.c (NEEDS_FIXUP): Delete definition and all references.
+ (hppa_gen_reloc_type): New object format dependent macro.
+ (pa_ip): Delete tons of code which was either OBJ_SOM or OBJ_ELF
+ conditional. The code can (and will) be shared between SOM & ELF
+ formats in the near future.
+ (cons_fix_new_hppa, md_apply_fix_1): Likewise.
+ (pa_build_unwind_subspace, process_exit, pa_exit): Likewise.
+ (tc_gen_reloc): Use hppa_gen_reloc rather than an object format
+ specific call.
+
+ * config/tc-hppa.c (pa_comm): Set the segment for a common symbol
+ to bfd_und_section.
+
+ * config/obj-elf.h (obj_elf_version): Add extern prototype.
+
+ * configure.in (hppa-*-bsd*): New configuration.
+ BFD is always used for GAS generating SOM objects.
+
+ * write.c (adjust_reloc_syms): Set sy_used_in_reloc if an
+ adjustment is rejected by the target machine.
+
+ * config/tc-hppa.c (pa_big_cons): Delete function and its
+ declaration. All callers changed to use pa_cons.
+
+ * write.c (fixup_segment): Fix indention and open/close brace
+ problem.
+
+ From Pete Hoogenboom:
+ * config/tc-hppa.c (md_atof): Return a NULL on success rather than
+ an empty string.
+
+ * config/tc-hppa.c (pa_parse_space_stmt): Advance
+ input_line_poitner when an invalid argument is encountered.
+
+Thu Oct 28 13:09:26 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-a29k.c (md_begin): When opcodes are mashed together in
+ the table, require that the one without bit 0x1000000 set come
+ first. Require further that it be case 'b' or 'P'. The a29k
+ opcode table already meets these constraints.
+ (machine_ip): When handling case 'i' or 'A', make sure that the
+ appropriate opcode really exists by looking at the next entry in
+ the opcode table.
+
+Wed Oct 27 11:48:56 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip): Adjust offsets for PC relative
+ fixups. Add 6 for long 7.3 case, 2 for short 7.2 case.
+
+ * config/obj-ecoff.c (obj_ecoff_ent): Ignore an optional number
+ after a .ent directive.
+
+ * config/tc-mips.c (mips_ip): Handle '>' case (shift amount
+ between 32 and 63 for double shift instruction). Do & 0x1f rather
+ than % 32.
+ (printInsn): Handle '>'.
+
+Tue Oct 26 16:58:36 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-ns32k.c (tc_aout_fix_to_chars): Output the symbol
+ number in the right place. Untested. Probably does not work for
+ cross assembly. From cagney@cs.adelaide.edu.au (Andrew Cagney).
+
+ * config/tc-m68k.c (md_apply_fix_2): Error if a short branch uses
+ an illegal offset of 0 or -1.
+
+ * config/obj-elf.c (obj_elf_init_stab_section): Align .stab
+ section to a longword boundary.
+
+Tue Oct 26 10:24:31 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * Makefile.in (CHECKFLAGS): Pass down RUNTESTFLAGS.
+
+ From Jeff Law:
+ * config/tc-hppa.c (tc_gen_reloc): ELF32_HPPA_R_ADDEND ->
+ HPPA_R_ADDEND.
+
+Mon Oct 25 14:06:17 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Fix up membar argument handling.
+
+Mon Oct 25 11:17:58 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * config/tc-sh.c (build_Mbytes): Write the relocs to the correct
+ address. (md_assemble): Make error handling a bit more graceful.
+ (md_apply_fix): Don't warn on non aligned displacement.
+
+ * config/tc-z8k.c (get_specific, built_bytes): Understand all the
+ aspects of lda.
+
+Mon Oct 25 10:20:31 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * doc/Makefile.in (install-info): Use "$<*" so VPATH will find
+ as.info* even if they're in $(srcdir) (e.g., for FSF
+ distributions).
+
+ * write.c (write_relocs): For relocs that are pc_relative and
+ pcrel_offset and not partial_inplace, adjust reloc->addend to
+ compensate for a bfd_perform_relocation bug.
+
+ * config/tc-sparc.h: Removed remaining non-BFD_ASSEMBLER code.
+ * config/tc-sparc.c: Ditto.
+ (tc_gen_reloc): Include fx_offset for pcrel fixups.
+
+Sun Oct 24 16:49:00 1993 Jim Wilson (wilson@x1.cygnus.com)
+
+ * config/tc-mips.c (md_pseudo_table): Add dword pseudo op.
+
+Fri Oct 22 20:40:56 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * messages.c: replaced all variables called Format with 'format',
+ for consistency throughout
+
+ * configure.in: handle mips*- instead of mips, mips*el for little
+ endian configurations
+
+Fri Oct 22 14:45:49 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * input-scrub.c (physical_input_file, logical_input_file,
+ physical_input_line, logical_input_line): Made static.
+ (as_where): Return current file name and line number, don't print
+ them out.
+ * messages.c (as_show_where): New static function. Other
+ functions use it instead of as_where.
+ (as_bad_internal): New static function.
+ (as_bad): Use as_bad_internal.
+ (as_bad_where): New function, like as_bad but taking a file name
+ and line number.
+ * as.h (as_bad_where): Declare.
+ (as_where): Change prototype for new arguments.
+ * write.h (fixS): Added fields fx_file and fx_line.
+ * write.c (fix_new_internal): Save file and line number in fix.
+ (fixup_segment): Use as_bad_where, not as_bad.
+ * input-file.c (f_in, file_name): Made static.
+ * cond.c (struct file_line): Just use file and line fields.
+ (s_else): Use as_where and as_bad_where, not get_file_line and
+ set_file_line.
+ (get_file_line, set_file_line): Removed.
+ * listing.c (listing_newline): Use as_where.
+ * config/obj-coffbfd.c (obj_coff_init_stab_section): Use as_where.
+ * config/obj-ecoff.c (add_file): Use as_where.
+ * config/obj-elf.c (obj_elf_init_stab_section): Use as_where.
+ * config/tc-m68k.c (md_apply_fix_2): Use as_bad_where.
+ * config/tc-mips.c (tc_gen_reloc): Use as_bad_where, not assert.
+
+Thu Oct 21 12:52:01 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/tc-m68k.h: Don't define REGISTER_PREFIX or
+ OPTIONAL_REGISTER_PREFIX if either is already defined.
+
+ * config/tc-m68k.c (m68k_ip): Delete some code in "#if 0".
+
+ * configure.in: Set bfd_gas for all sparc targets. Added facility
+ for keeping or rejecting configurations still under development;
+ default is to assume production environment, and reject configs
+ still being worked on. Mark Elf configurations (except sparc and
+ i386) as developmental. Deleted cases matching some generic names
+ in favor of more specific names. (E.g., when we get Alpha
+ support, we'll still only support VMS for Vax.)
+
+ * config/tc-sparc.h (md_end): New macro.
+ * config/tc-sparc.c (md_end): Function deleted.
+ (BFD_RELOC_*): Delete macros that used to help keep the non-bfd
+ version compiling. All sparc targets will use bfd now.
+ * tc.h (md_end): Don't declare if it's defined as a macro.
+
+ Changes from Jeff Law and Peter Hoogenboom:
+
+ * read.c (next_char_of_string): Limit octal character constants to
+ three digits.
+
+ * config/tc-hppa.h: Major cleanup. Use GNU-style comments. Warn
+ against placing additional object-file dependent code here. Warn
+ against contaminating all of GAS with the internals of tc-hppa.c
+ through inclusion of tc-hppa.h. Delete all forward declarations
+ for functions only used within tc-hppa.c, likewise for structures,
+ variables, and #defines. Try to group OBJ_ELF and OBJ_SOM
+ conditional code in a few small places.
+
+ * config/tc-hppa.c: Major cleanup. Use GNU-style comments. Group
+ structures, global variables, forward declarations together.
+ Reduce (or in some cases eliminate) OBJ_ELF and OBJ_SOM
+ conditional code -- try to group conditional code together
+ into a few places. Make all functions and variables which
+ are only used within tc-hppa.c static. PARAMize all functions.
+ Add comments to functions. Delete unused functions, variables,
+ #defines, etc. Delete unused members within structures. Delete
+ ldil;ble hacks -- it is believed they were installed to work
+ around old gas bugs. Avoid using mixed case for local
+ functions, variables, and structures. Fix formatting problems
+ not found by GNU-indent. Add FIXME notices for things which
+ should be worked on the near future. Delete lots of old
+ useless (1.36 PA-SOM) code.
+
+ * config/tc-hppa.c: (fix_new_hppa): Initialize the fx_r_type
+ field of the fixS structure. Needed to build unwind
+ descriptors correctly.
+
+ * write.c: (fixup_segment): Allow expressions such as
+ sym1-sym2+const as long as sym2 is $global$.
+
+ * write.c (adjust_reloc_syms): Provide a hook so that a target
+ cpu configuration can reject certain relocation reductions.
+ * config/tc-hppa.h (tc_fix_adjustable): New macro. Only accept relocations
+ which do not involve function symbols.
+
+ * config/tc-hppa.h: Reindent with GNU-indent. Delete references
+ to OBJ_OSFROSE. Fix typos (OBJ_SOME -> OBJ_SOM). Delete unused
+ STAB_FIXUP macro.
+ * config/tc-hppa.c: Likewise.
+
+ * config/tc-hppa.c (md_apply_fix_1): Use elf_symbol_type, instead
+ of elf32_symbol_type.
+ (pa_export_args): Likewise.
+ (elf_hppa_final_processing): Likewise.
+ (pa_desc): Do not call obj_elf_desc. (Is pa_desc even needed
+ anymore?)
+ (hppa_tc_make_sections): Do not declare elf_get_symtab_map any
+ ore.
+
+ * config/tc-hppa.c: (md_section_align): Align all sections to
+ a multiple of the section alignment rather than always a
+ multiple of 8.
+
+ * config/tc-hppa.c (hppa_tc_symbol): If the argument relocation
+ bits are zero (eg they specify no relocations), then do not even
+ bother adding their entries to thesymextn section.
+
+Thu Oct 21 15:44:55 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-sparc.c (md_parse_option): Accept and ignore -sparc
+ option, which is used by the SunOS make default .s.o rule.
+
+Wed Oct 20 12:26:33 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip, label "immediate"): Convert relocs
+ operating on upper 32 bits of immediate constants to lower-half
+ relocs with adjusted constants.
+
+Tue Oct 19 18:13:26 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-m68k.h (AOUT_MACHTYPE): Define to be external variable
+ m68k_aout_machtype.
+ * config/tc-m68k.c (omagic): Remove obsolete and unused variable.
+ (m68k_aout_machtype): New variable, if OBJ_AOUT.
+ (md_assemble): Initialize m68k_aout_machtype based on
+ current_architecture, if OBJ_AOUT.
+ (md_parse_option): Remove obsolete reference to omagic.
+
+Thu Oct 14 16:51:00 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (md_pseudo_table): Ignore .livereg pseudo-op.
+ (s_option): Ignore .option O* and .option pic*.
+ (s_ent): Skip whitespace between symbol and optional digit.
+ (my_getSmallExpression): Handle ($xx) correctly: assume 0($xx).
+
+ * app.c (do_scrub_next_char): Always accept 'x' and 'X' as escape
+ characters in state 6.
+ * read.c (next_char_of_string): Accept \Xh* and \xh* where h* are
+ hexadecimal digits.
+
+ * config/tc-i386.c (md_apply_fix_1): Make cross segment calls work
+ for ELF by hacking around bizarre bfd_perform_relocation behaviour
+ that I don't dare change.
+
+Thu Oct 14 11:33:25 1993 Michael Meissner (meissner@osf.org)
+
+ * config/tc-i386.c: (md_begin): Do not zero static arrays. Don't
+ call strchr for each character to see if it is a special char,
+ instead add a second loop over special_chars. Set alignment
+ of text, data and bss sections to 4.
+ (pi, te, pt, pe, ps): Add declarations so that DEBUG386 can be
+ used again.
+ (reloc): Don't return 8 and 16 bit non-PC relative relocations on
+ ELF, since the ELF object format does not have these type of
+ relocations. Change the abort into as as_bad and return
+ BFD_RELOC_NONE to silence compiler warnings.
+ (md_assemble): Keep track of the instruction size. Allow white
+ space between the $ and the constant for compatibility with older
+ gases and other assemblers.
+ (i386_operand): Skip spaces between $ and expression.
+ (tc_gen_reloc): Don't allow anything but 32 bit relocations on
+ ELF. Convert abort into an as_bad and assert into as_fatal.
+
+Wed Oct 13 16:50:55 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-coffbfd.c (fixup_segment) [DIFF_EXPR_OK]: If
+ sub_symbolP is in the current segment, convert to a PC-relative
+ fixup and discard the symbol.
+
+Wed Oct 13 14:00:02 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-ecoff.c (ecoff_build_symbols): Handle st_End symbol
+ for st_StaticProc just like st_Proc.
+
+ * write.c (relax_and_size_all_segments): Moved #endif for OBJ_BOUT
+ so that OBJ_BOUT doesn't forget to adjust all the fragments in the
+ .bss section.
+
+Tue Oct 12 17:26:15 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c: If OBJ_ELF, include elf/mips.h.
+ (mips_regmask_frag): New static variable, if OBJ_ELF.
+ (md_begin): If OBJ_ELF, create .reginfo section and set
+ mips_regmask_frag to a frag.
+ (mips_elf_final_processing): New function, if OBJ_ELF. Set
+ mips_regmask_frag to register mask information.
+ * config/tc-mips.h (elf_tc_final_processing): New macro, defined
+ if OBJ_ELF.
+
+Tue Oct 12 03:33:26 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * messages.c (as_fatal): Use myname when printing messages.
+
+ * config/tc-i960.c (md_begin): Use null pointer, not empty string,
+ as initial "return" value in case hashing isn't needed.
+
+ * config/tc-a29k.c (md_atof): Return null, not empty string, on
+ success.
+ * config/tc-h8300.c (md_atof), config/tc-h8500.c (md_atof),
+ config/tc-hppa.c (md_atof), config/tc-i860.c (md_atof),
+ config/tc-i960.c (md_atof), config/tc-m88k.c (md_atof),
+ config/tc-ns32k.c (md_atof), config/tc-sh.c (md_atof): Ditto.
+
+Mon Oct 11 16:46:31 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ fix for pr 3571
+ * config/tc-h8300.c (get_specific): Special action if 8 bit
+ address seen. (check_operand): Don't complain if truncating top
+ bits of an 8 bit address. (build_bytes): Allow an immediate and
+ an absolute in the same insn.
+
+Mon Oct 11 17:18:51 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * write.c (write_contents): Don't crash if seginfo is NULL.
+
+ * config/obj-ecoff.c (ecoff_frob_file): Write out register masks
+ by modifying .reginfo section, not by directly modifying BFD
+ backend data.
+
+Mon Oct 11 14:11:32 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * config/ho-sunos.h: remove extern time declaration
+
+Mon Oct 11 16:14:43 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * messages.c (as_fatal): Do mention that it's the assembler that
+ got the fatal error.
+
+Fri Oct 8 14:09:35 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_gprmask, mips_cprmask): New variables to
+ hold register masks.
+ (md_begin): Initialize them to zero.
+ (append_insn): Update mips_gprmask and mips_cprmask. Also add
+ register variables pinfo and prev_pinfo.
+ * config/tc-mips.h (mips_gprmask, mips_cprmask): Declare.
+ * config/obj-ecoff.c (ecoff_frob_file): If TC_MIPS, set gprmask
+ and cprmask from mips_gprmask and mips_cprmask.
+
+ * config/tc-mips.h: Define TARGET_FORMAT if OBJ_ELF.
+ * config/tc-mips.c (GPOPT): Define if OBJ_ECOFF or OBJ_ELF.
+ (various): Change all references to GP references to apply if
+ GPOPT, not if OBJ_ECOFF.
+ (s_change_sec): Rearrange somewhat. If OBJ_ELF, use .rodata
+ instead of .rdata. If OBJ_ELF, set section flags for .rodata and
+ .sdata sections.
+ (s_frame, s_loc, s_mask): Comment out entire functions, rather
+ than just body. They're not used anyhow.
+ * configure.in: Set cpu_type to mips for mips*. Accept
+ mips-*-elfl* and mips-*-elf*.
+
+Thu Oct 7 18:36:29 1993 Michael Meissner (meissner@osf.org)
+
+ * config/obj-elf.c (obj_elf_common): Allow the alignment field to
+ not be specified.
+
+Wed Oct 6 13:01:34 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (cons_fix_new_mips): New function. Turn
+ BFD_RELOC_64 into BFD_RELOC_32.
+ * config/tc-mips.h (TC_CONS_FIX_NEW): Define.
+ (cons_fix_new_mips): Declare.
+
+ Changes to let cons handle bignums like general expressions.
+ * expr.h (expressionS): New field X_unsigned.
+ * expr.c (operand): Initialize X_unsigned to 1. Set it to 0 for
+ unary minus case.
+ (expr) Fix typo resultP to right if missing operand. Set
+ X_unsigned to 1 when building new expression.
+ * read.c (potable): Make "octa" and "quad" call cons, not
+ big_cons.
+ (cons): Handle bignums. If given an O_constant (small integer) to
+ fill a big space, turn it into a bignum.
+ (parse_bitfield_cons): Set X_unsigned field.
+ (bignum_low, bignum_limit, bignum_high, grow_bignum, big_cons):
+ Removed.
+ * read.h (big_cons): Remove prototype.
+ * symbols.c (resolve_symbol_value): Don't give a warning if a
+ symbol in expr_section can not be resolved.
+ (S_SET_VALUE): Clear X_unsigned.
+ * write.c (write_object_file): If resolve_symbol_value failed on a
+ symbol we are writing out, give a warning.
+ * config/tc-h8500.c (parse_reglist): Set X_unsigned.
+ * config/tc-hppa.c (md_pseudo_table): Change "octa" and "quad" to
+ call pa_cons, not pa_big_cons.
+ (pa_big_cons): Remove.
+ * config/tc-hppa.h (pa_big_cons): Remove declaration.
+ * config/tc-i960.c (md_pseudo_table): Change "quad" to call cons,
+ not big_cons.
+
+Tue Oct 5 10:53:36 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * doc/as.texinfo (Copying): new node, to handle the recent changes
+ in the texinfo/gpl.texinfo file
+
+Mon Oct 4 17:10:15 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * read.c (big_cons): Handle "0" correctly.
+
+ * config/tc-mips.c (md_begin): Set target_big_endian correctly.
+
+Mon Oct 4 15:37:57 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip): Mode 7.3 operand using PC should
+ have pc-relative fixup.
+ (md_parse_option): Move "-k" case down near "-pic" case.
+
+ * configure.in: Alphabetize list of cpu type alternatives. Enable
+ OS values of "linux*elf*" and "linux*coff*" to select those
+ formats, with linux emulation. Don't bother checking for upper-
+ or mixed-case versions of "ose".
+
+Thu Sep 30 11:05:35 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * config/z8k.c (md_pseudo_table): add "unseg".
+
+Wed Sep 29 16:15:11 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * config/m88k-opcode.h (m88k_opcodes): correct a few mistakes
+ found while extending the dissassembler.
+
+Tue Sep 28 12:02:04 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * configure.in: Split i386 LynxOS out from other coff targets,
+ add a specific Lynx emulation.
+ Add m68k LynxOS target.
+ * config/tc-i386.c: Define specific Lynx target format.
+ * config/tc-m68k.c: Define specific Lynx target format.
+ * config/te-lynx.h: New file.
+
+ * config/obj-coffbfd.h: Don't set TARGET_FORMAT to be
+ "coff-{i386,m68k}" if TARGET_FORMAT already defined.
+ (INIT_STAB_SECTION): Define.
+ * config/obj-coffbfd.c: Include <time.h>.
+ (write_object_file): Look for .stab sections and call
+ adjust_stab_section.
+ (adjust_stab_section): New function, fills in the first symbol
+ of a stab section with number of symbols and string table size.
+ (obj_coff_init_stab_section): New function, creates the initial
+ symbol for a stab section.
+
+Mon Sep 27 15:21:55 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/atof-vax.c (md_atof): Return null on success instead of
+ empty string.
+ * config/atof-tahoe.c (md_atof): Ditto.
+ * read.c (float_cons): Expect a null pointer for success, not an
+ empty string.
+
+ * hash.c (hash_insert, hash_jam, hash_grow): Return null pointer
+ on success, instead of empty string. All callers changed.
+
+ * config/tc-vax.c: Use PARAMS in declarations.
+ (vip_op): Use NULL instead of empty string for success in error
+ and warning fields.
+
+Sun Sep 26 23:45:29 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * expr.c (expr) [DIFF_EXPR_OK]: Permit subtraction of two symbols
+ in different defined segments.
+
+ * write.c (relax_segment): Localize "aim" variable. If
+ DIFF_EXPR_OK, don't impose checks on symbol segment types.
+ (fixup_segment) [DIFF_EXPR_OK]: If sub_symbolP is in the current
+ segment, convert to a PC-relative fixup and discard the symbol.
+
+ * config/tc-m68k.c (flag_want_pic): New variable, mostly ignored.
+ (md_parse_option) [TE_SUN3]: Set it for "-k".
+ (m68k_ip): Generate proper fixup for mode 7.3.
+ * config/tc-m68k.h (DIFF_EXPR_OK): Define.
+
+Sat Sep 25 05:08:19 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-m68k.c (struct m68k_incant, getone, gettwo): Moved
+ earlier in the file.
+ (insop, add_exp): Now defined as functions, for readability.
+ (insop): Now takes two arguments; callers changed.
+
+Fri Sep 24 12:37:59 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * config/tc-m88k.c (get_o6): new function.
+ (get_bf, get_cmp, get_cnd, get_cr, get_fcr, get_imm16, get_reg,
+ get_vec9, getval, get_pcr, calcop, match_name): make static and
+ prototype.
+ (s_file): remove extraneous forward decl.
+ (md_begin): add const to retval decl.
+ (calcop): cope with instructions without arguments. Handle 'o'
+ type argument, the o6 field of the prot insn.
+ (md_estimate_size_before_relax): return a dummy value.
+
+ * config/m88k-opcode.h (m88k_opcodes): comment change; o6 field is
+ in bits 10 through 7. flt.[dxs]s requires an r register in the
+ second argument. New instruction lda.x. New instruction muls
+ (alias for mul).
+
+Fri Sep 24 13:43:30 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (distclean): Recurse like clean.
+ * doc/Makefile.in (distclean): New target.
+
+ * config/tc-mips.c (md_begin): Set BFD architecture and machine
+ based on MIPS ISA level.
+
+Thu Sep 23 17:58:58 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * as.c (main): "exhausted", not "exhuasted".
+
+ * struc-symbol.h (struct symbol): Add sy_used_in_reloc field.
+ * write.c (adjust_reloc_syms): Set sy_used_in_reloc.
+ (write_object_file): Never strip symbols with sy_used_in_reloc
+ set.
+
+ * config/obj-elf.c (obj_elf_section): Rewrote to handle both
+ Solaris and SVR4 style .section pseudo-ops.
+ (obj_elf_ident): Set SEC_READONLY for .comment section.
+ * config/tc-sparc.c (md_apply_fix): If this is ELF, and we're
+ generating a reloc, don't apply a fix.
+
+Thu Sep 23 13:16:58 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-coffbfd.c (relax_align): Now static.
+
+Mon Sep 20 19:23:35 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * read.c (get_stab_string_offset): Make non-static. Make
+ arguments const. Don't align strings to 4 byte boundaries.
+ * read.h: Declare get_stab_string_offset.
+ * config/obj-elf.c (obj_elf_section): Set SEC_ALLOC as well as
+ SEC_LOAD for progbits section.
+ (obj_elf_init_stab_section): New function.
+ (adjust_stab_sections): Add casts to avoid warnings.
+ * config/obj-elf.h (INIT_STAB_SECTION): Call
+ obj_elf_init_stab_section.
+ (OBJ_PROCESS_STAB): Removed definition.
+
+Fri Sep 17 18:12:34 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-elf.h (S_GET_SIZE): Define.
+ (obj_frob_forward_symbol): Define.
+ * config/tc-i386.c (line_comment_chars): Initialize in all cases.
+
+Thu Sep 16 14:23:08 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * tc.h: Declare tc_gen_reloc differently depending upon
+ RELOC_EXPANSION_POSSIBLE.
+ * config/obj-elf.c (obj_elf_section): Only set flags when first
+ creating the section.
+
+Wed Sep 15 12:15:53 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (append_insn): Don't swap a trap instruction
+ with a branch.
+
+Tue Sep 14 13:31:04 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-elf.c (obj_elf_data, obj_elf_text): New functions;
+ set previous_section and previous_subsection and then call s_data
+ and s_text, respectively.
+ (obj_pseudo_table): Add data and text.
+ (obj_elf_section): Add SEC_LOAD to default initialization of
+ flags. Treat .rodata1 like .rodata. Set SEC_LOAD as well as
+ SEC_ALLOC for "alloc" string. Don't bother trying to find the
+ section; just use subseg_new.
+
+ * read.c (change_to_section): Removed. This is now done by
+ subseg_new.
+ (get_stab_string_offset): Rearranged somewhat. Create the section
+ using subseg_new. Store the string index in seg_info, rather than
+ in a static variable. Force the first string to be empty. Use
+ frag_more rather than FRAG_APPEND_1_CHAR.
+ (s_stab_generic): Rewrote.
+ * subsegs.h (segment_info_type): Added stabu union.
+ * subsegs.c (subseg_new): Initialize stab_string_size to 0.
+ * config/obj-aout.c: Don't include aout/stab_gnu.h.
+ (obj_aout_stab, obj_aout_desc): Removed.
+ (obj_pseudo_table): Removed desc and stabX entries.
+ * config/obj-bout.c: Same changes as config/obj-aout.c.
+ * config/obj-bout.h (S_SET_TYPE): Define.
+ (tc_bout_fix_to_chars): Declare.
+ * config/obj-coff.c (obj_coff_stab): Removed.
+ (obj_pseudo_table): Removed desc and stabX entries.
+ * config/obj-coff.h (SEPARATE_STAB_SECTIONS): Define.
+ * config/obj-coffbfd.c (current_stab_symbol): Removed.
+ * config/obj-coffbfd.h (obj_symbol_type): Removed n_strx, n_type,
+ n_other, n_desc and n_value fields.
+ (S_{S,G}ET_{OFFSET,OTHER,TYPE,DESC}): Removed.
+ (MAKE_STAB_SYMBOL): Removed.
+ * config/obj-ecoff.c (obj_ecoff_stab): Renamed to ecoff_stab.
+ Changed arguments and removed parsing code.
+ (obj_pseudo_table): Removed stabX entries.
+ * config/obj-ecoff.h (ecoff_stab): Declare.
+ (OBJ_PROCESS_STAB): Define.
+ * config/obj-elf.c: Don't include aout/stab_gnu.h.
+ (obj_elf_stab, obj_elf_xstab, obj_elf_desc,
+ elf_stab_symbol_string, elf_stab_symbol, obj_elf_stab_generic):
+ Removed.
+ (obj_pseudo_table): Removed desc, stabX and xstabs entries.
+ (obj_elf_version): Use subseg_new, not bfd_make_section. Don't
+ set SEC_LOAD for .note section.
+ (adjust_stab_sections): Get frag pointer from seg_info, rather
+ than looking through frags.
+ * config/obj-elf.h (S_{S,G}ET_{OTHER,TYPE,DESC}): Removed.
+ (SEPARATE_STAB_SECTIONS, INIT_STAB_SECTION, OBJ_PROCESS_STAB):
+ Define.
+ * config/obj-vms.c (obj_aout_stab): Removed.
+ (obj_pseudo_table): Removed stabX entries.
+ * config/obj-vms.h (S_SET_TYPE): Define.
+
+ * as.h: Declare listing.
+ * read.c: Don't declare listing.
+ (emit_expr): Cast fix_new_exp argument.
+ (parse_bitfield_cons): Correct printf format.
+ * symbols.c (symbol_new): Add cast to avoid warning.
+ * write.h: Declare text_last_frag and data_last_frag.
+ * config/obj-bout.c (obj_bout_line): Added dummy argument.
+ * config/obj-coffbfd.c: Add some casts to avoid warnings.
+ * config/tc-a29k.c: Likewise.
+ * config/tc-i960.c: Likewise. Also fully bracket structure
+ initializations, fix printf formats, and remove unused variables.
+
+Mon Sep 13 16:48:38 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * read.c (s_desc): Only compile and use if S_SET_DESC is defined.
+ * struc-symbol.h: Declare verify_symbol_chain and
+ verify_symbol_chain_2 even if not SYMBOLS_NEED_BACKPOINTERS.
+ * symbols.c (verify_symbol_chain): Removed useless expression.
+ * write.c (headers, the_object_file): Only use if not
+ BFD_ASSEMBLER and not BFD.
+ (fixup_segment, cvs_frag_to_fill): Only use if BFD_ASSEMBLER or
+ not BFD.
+ (merge_data_into_text): Only use if BFD_ASSEMBLER or (not BFD and
+ not OBJ_AOUT).
+ * write.h: Declare relax_segment.
+ * config/obj-coffbfd.c (stack_pop, stack_push, stack_init): Made
+ static.
+ (stack_top): Commented out, since it's not used.
+ Fixed up pseudo-op functions to take an ignored int argument.
+ (size_section): Added default BAD_CASE to switch.
+ Changed bzero calls to memset.
+ * config/obj-coffbfd.h (S_IS_LOCAL): Call strchr on S_GET_NAME
+ (s), not on s itself.
+ * config/tc-a29k.c (s_use): Take ignored int argument. Only
+ define if OBJ_COFF is not defined.
+ * config/tc-i386.c: (fits_in_signed_byte, smallest_imm_type): Make
+ argument signed again.
+ * config/tc-m68k.c (s_bss, s_even, s_proc): Take ignored int
+ argument.
+ (m68k_ip): Fully bracket initialization of archs.
+ Correct several formats for __LINE__ to be %d rather than %s.
+ (init_table): Fully bracket initialization.
+ Cast values larger than 0x7f assigned to fr_opcode to char.
+
+ * subsegs.c: Renamed non-BFD_ASSEMBLER subseg_new to subseg_set.
+ Wrote non-BFD_ASSEMBLER subseg_new. Now subseg_new always takes a
+ section name, and subseg_set always takes a segT. Changed all
+ callers as appropriate.
+ * config/obj-coffbfd.c (change_to_section): Renamed to
+ obj_coff_add_segment. Corrected. Made callers use subseg_new.
+ * config/obj-coffbfd.h (obj_segment_name, obj_add_segment):
+ Define.
+
+Mon Sep 13 13:15:03 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/tc-sparc.h (LOCAL_LABEL): Remove test for name[0] == 'L'.
+
+Fri Sep 10 11:22:08 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-elf.h (S_SET_SIZE): Actually set the size.
+
+ Gcc lint.
+ * Added a number of casts to function calls.
+ * app.c (do_scrub_begin), as.c (main), expr.c (integer_constant,
+ operand, expr), read.c (read_begin, HANDLE_CONDITIONAL_ASSEMBLY,
+ read_a_source_file, s_align_bytes, demand_empty_rest_of_line,
+ ignore_rest_of_line, big_cons, is_it_end_of_statement, s_ignore),
+ read.h (is_name_beginner, is_part_of_name), config/obj-elf.c
+ (obj_elf_section), config/tc-i386.c (parse_register),
+ config/tc-sparc.c (isoctal, s_proc): Cast char
+ array indices to unsigned char.
+ * app.c (process_escape): Make static. Add prototype. Change
+ argument from char to int.
+ * as.c: Include output-file.h for prototypes. Comment out unused
+ function got_sig.
+ * Makefile.in (as.o): Depend on output-file.h.
+ * as.h (BAD_CASE): Cast val argument to long, and use %ld.
+ (pseudo_typeS): Add prototype to poc_handler field.
+ (print_version_id): Add prototype.
+ (xmalloc, xrealloc): Change size arguments to unsigned long.
+ (do_scrub_next_char): Add prototypes for function arguments.
+ (had_errors, had_warnings, scrub_from_file): Remove duplicate
+ declarations.
+ * atof-generic.c (atof_generic): Make size variables unsigned.
+ * cond.c (ignore_input): Removed unused local variable ptr.
+ * expr.c (floating_constant, integer_constant): Make static. Add
+ prototypes.
+ * flonum-copy.c (flonum_copy): Make size variables unsigned.
+ * frags.h: Add prototype for frag_init.
+ * hash.h, hash.c: Change hash values from char * to PTR, make hash
+ strings const, make returned error strings const char *. Added
+ prototypes for functions.
+ * input-file.h, input-file.c (input_file_buffer_size): Return
+ unsigned int.
+ * input-scrub.c (buffer_length): Make unsigned.
+ (input_scrub_push, input_scrub_pop): Make static.
+ * listing.c (list_symbol_table): Cast sprintf argument to unsigned
+ long and use %lx. Print name of segment rather than address of
+ structure.
+ (listing_list, listing_title): Change argument to int.
+ (listing_eject, listing_flags, listing_psize): Add int argument.
+ * listing.h: Corresponding declaration changes.
+ * obj.h (obj_emit_symbols): Rename prototype argument to avoid
+ shadowing.
+ * read.h: Change get_absolute_expression prototype to return
+ offsetT. Add prototype for next_char_of_string. Various
+ prototype changes.
+ * read.c: Remove prototype for next_char_of_string.
+ (pobegin): Make errtxt const. Make new_length, tmp_len and num
+ unsigned.
+ (s_abort, s_align_ptwo, s_comm, s_data, s_app_line, s_fill,
+ s_globl, s_lsym, s_org, s_set, s_text, s_desc): Add int argument.
+ Change all callers.
+ (s_comm): Change temp from valueT to offsetT. Cast to long when
+ printing and use %ld (only for error messages anyhow).
+ (s_long, s_int): Remove unused functions.
+ (cons): Change argument to int.
+ (emit_expr): Use %lx when printing longs.
+ (get_absolute_expression): Return offsetT, not long.
+ (get_stab_string_offset): Comment out unless
+ SEPARATE_STAB_SECTIONS.
+ (s_stab_generic): Remove unused offset. Define seg_is_new only
+ if SEPARATE_STAB_SECTIONS. Use toP only in local block.
+ * struc-symbol.h (verify_symbol_chain_2): Add prototype.
+ * symbols.c: Remove nested comment.
+ (symbol_new): Rename value to valu.
+ (colon): Use %ld and cast to long in error message.
+ * symbols.h: Remove duplicate verify_symbol_chain declaration.
+ * tc.h: Remove unused md_emit_relocations declaration.
+ (tc_gen_reloc): Add declaration.
+ * write.c (cvt_frag_to_fill): Change first argument name depending
+ on BFD_ASSEMBLER.
+ (write_relocs): Remove unused offset, frags. Remove tc_gen_reloc
+ declarations. Make n unsigned.
+ (write_contents): Remove unused i, n, relocs, fixp. Rename frags
+ to f to avoid shadowing.
+ (write_object_file): Define fragP only if not BFD_ASSEMBLER or not
+ WORKING_DOT_WORD. Remove unused keep. Only declare punt and
+ punt_it if they will be used. Make i and n unsigned.
+ (fixup_segment): Cast to long and use %ld in error message.
+ * xmalloc.c (xmalloc, xrealloc): Make size argument unsigned.
+ * config/obj-aout.h: Remove nested comment. Add prototype for
+ obj_aout_frob_symbol.
+ (obj_aout_line, obj_aout_desc): Add int argument.
+ * config/obj-ecoff.c: Changed build routines to use an unsigned
+ offset.
+ (add_string): Make len unsigned long.
+ (obj_ecoff_stab): Use %lu in error message.
+ * config/obj-elf.c (obj_elf_common): Comment out unused label
+ allocate_bss.
+ (obj_elf_frob_symbol): Return 0 (currently broken).
+ (obj_elf_desc, obj_elf_version, obj_elf_size, obj_elf_type,
+ obj_elf_ident, obj_elf_weak, obj_elf_local, obj_elf_common,
+ obj_elf_line, obj_elf_previous): Add int argument.
+ (obj_elf_write_symbol_p): Make static.
+ * config/obj-elf.h (obj_elf_write_symbol): Add prototype.
+ * config/tc-hppa.h: Remove declarations of functions declared in
+ read.h.
+ * config/tc-i386.c (ENCODE_RELAX_STATE): Cast to relax_substateT.
+ (s_bss): Add int argument.
+ (fits_in_signed_byte, smallest_imm_type): Make argument unsigned.
+ (dummy): Remove unused function.
+ (md_assemble): Rename local o to op to avoid shadowing.
+ (tc_gen_reloc): Rename local reloc to rel to avoid shadowing.
+ * config/tc-m68k.c (s_data1, s_data2): Add int argument.
+ * config/tc-mips.c (mips_ip, md_apply_fix): Cast to long and use
+ %ld in error messages.
+ * config/tc-sparc.c: Remove duplicate declarations.
+ (getExpression): Rewrite condition to avoid empty conditional
+ body.
+ (s_reg, s_proc, s_reserve, s_common, s_seg, s_xword): Add int
+ argument.
+
+Thu Sep 9 17:10:00 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ Changes from Jeff Law:
+
+ * config/tc-hppa.c (md_assemble): Fix typo.
+ (pa_ip): Delete unused variables and labels. Do not check for
+ unsigned values being < 0, it can't happen.
+ (is_same_frag): Return a value in recursive call case.
+ (pa_callinfo): Delete unused variables and labels.
+ (pa_comm): Likewise.
+ (pa_copyright): Likewise.
+ (pa_export): Likewise.
+ (pa_import): Likewise.
+ (pa_param): Likewise.
+ (pa_space): Likewise.
+ (pa_subspace): Likewise.
+
+Thu Sep 9 15:05:34 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * read.c (get_stab_string_offset, s_stab_generic): If
+ BFD_ASSEMBLER, call subseg_set rather than subseg_new.
+
+Wed Sep 8 15:09:17 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-elf.c (obj_elf_section): Set SEC_LOAD when using
+ default flag values.
+
+Tue Sep 7 10:22:52 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * read.c: (change_to_section): Don't include body if not MANY_SECTIONS.
+
+ * read.c: (s_stab, s_xstab, s_desc): New functions to parse
+ various stab-related directives.
+ * read.h: (s_stab, s_xstab, s_desc): New function prototypes.
+ * write.c: (merge_data_into_text): Fix ifdef tangle.
+ * config/obj-coffbfd.c (current_stab_symbol): Fake symbol
+ for stab reader to use.
+ * config/obj-coffbfdh.h (obj_symbol_type): Added fields for
+ stab reader, macros to access.
+
+Fri Sep 3 16:44:03 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-elf.h (elf_symbol): No longer special-cased on
+ sparcv9, since elf_symbol_type is now independent of size.
+
+ * config/obj-elf.h (elf_symbol): Fixed name of elf_symbol_type.
+
+ * config/tc-hppa.h (struct default_subspace_dict, struct
+ default_space_dict): Field "sort" is now unsigned char.
+
+ * config/tc-hppa.c (pa_def_subspaces, pa_def_spaces): Align
+ columns for easier reading.
+ (bcmp, index): Deleted USG-specific definitions. Should be dealt
+ with in ho-*.h, or in libiberty. Changed mention of index to
+ strchr.
+ (label_symbolP, label_symbol_defined, callinfo_found,
+ within_entry_exit, exit_processing_complete, within_procedure,
+ pa_def_subspaces, pa_def_spaces, pa_pseudo_op_moves_pc,
+ label_symbols_rootP, pa_get_label, pa_label_is_defined,
+ pa_undefine_label): Now static.
+ (movers): Now const, in addition to pointing to const data.
+ * config/tc-hppa.h (label_symbolS_rootP, pa_get_label,
+ pa_label_is_defined, pa_undefine_label, pa_pseudo_op_moves_pc):
+ Delete declarations.
+
+ Merged more changes from Jeff Law and Pete Hoogenboom:
+
+ * config/tc-hppa.c (pa_def_subspaces, pa_def_subspaces): Remove
+ entries for .stab and .stabstr.
+
+ * config/obj-elf.c: (elf_stab_symbol_string): Set the
+ SEC_LOAD attribute for the .stabstr section.
+ (obj_elf_stab_generic): Set the SEC_LOAD attribute for the
+ .stab section.
+ (obj_elf_stab_generic): Change '#if 1' to '#if 0'.
+ (obj_elf_stab_generic): Incorrect byte count on call to
+ md_number_to_chars function.
+
+ * config/tc-hppa.c (hppa_tc_symbol): Static functions need
+ argument relocation bits too.
+
+ * config/tc-hppa.c (pa_stringer): Correctly handle escaping
+ characters which should appear unaltered in the output string (for
+ example an escaped double-quote).
+
+ * config/tc-hppa.c (pa_parse_nonneg_cmpsub_cmpltr): Always
+ initialize name.
+ (pa_parse_neg_cmpsub_cmpltr): Likewise.
+ (pa_parse_nonneg_add_cmpltr): Likewise.
+ (pa_parse_neg_add_cmpltr): Likewise.
+
+ * config/tc-hppa.h (parse_cons_expression_hppa): Remove prototype
+ for now.
+ (cons_fix_new_hppa): Likewise.
+ * config/tc-hppa.c (md_apply_fix): Fix type of valp to match
+ prototype.
+
+ * config/tc-hppa.c: Include libhppa.h.
+
+ * config/tc-hppa.h: Delete extern declarations of functions
+ found in libhppa.h.
+
+ * config/tc-hppa.c (pa_space): Rework to avoid unwanted #ifdef
+ OBJ_ELF conditionals.
+ * config/tc-hppa.h (LOCAL_LABEL): Correctly identify local labels
+ on the PA.
+
+Thu Sep 2 10:43:57 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (macro_build): Accept 'z', and ignore it.
+ (macro): Use "z,s,t" for div instructions to match corresponding
+ change in opcode table.
+ (mips_ip): Added 'z'--must be zero register.
+
+Wed Sep 1 15:56:42 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * write.c (write_relocs) [RELOC_EXPANSION_POSSIBLE]: Declare
+ tc_gen_reloc correctly.
+
+ * configure.in: Use "case" instead of "if" when possible. Rewrote
+ Makefile editing to reduce work done. Treat "hppa*" as "hppa".
+
+Wed Sep 1 12:19:07 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * config/obj-coffbfd.c (obj_coff_section): add 'd' as an alias for
+ section type of data. 'd' seems to be used for m88k.
+
+Wed Aug 25 22:33:22 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_align, s_stringer, s_cons, s_float_cons,
+ s_mips_space): Set insn_label to NULL to avoid changing it at the
+ next .align statement.
+ (append_insn): Don't swap jal with instruction that sets the
+ register that jal sets.
+
+Wed Aug 25 16:15:57 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * configure.in: recognize m88110.
+
+Wed Aug 25 13:37:46 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ Merged changes from Pete Hoogenboom and Jeff Law at Utah:
+ * config/tc-hppa.c (pa_build_unwind_subspace): SEC_ALLOC should
+ not be on for .hppa_unwind.
+ (md_pseudo_table): .PARAM and .param are valid pseudo-ops for GAS.
+ (pa_param): New function to handle .PARAM directives.
+ (pa_ip): Pass "isbranch" argument down to pa_parse_*_compltr
+ functions. Handle '|' for movb; allow movb,n.
+ (pa_parse_nonneg_cmpsub_cmpltr): Delete old useless
+ version. Handle cases where no completer exists for
+ comb,n or addb,n.
+ (pa_parse_neg_cmpsub_cmpltr): Handle cases where no
+ completer exists for comb,n or addb,n. Make logic
+ mirror that of pa_parse_nonneg_cmpsub_cmpltr.
+ (pa_parse_nonneg_add_cmpltr): Likewise.
+ (pa_parse_neg_add_cmpltr): Likewise.
+ * config/tc-hppa.h (pa_param): Declare.
+
+Tue Aug 24 15:41:35 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-hppa.c (hppa_tc_make_symextn_section): Now static.
+ Added forward declaration.
+
+ Merged changes from Pete Hoogenboom and Jeff Law at Utah:
+
+ * config/obj-elf.c (elf_frob_file): Arguments were incorrect on
+ call to elf_tc_make_sections.
+ (obj_elf_version): A .note section shouldn't have the SEC_ALLOC
+ attribute.
+
+ * config/tc-hppa.c (hppa_tc_make_sections): Add some processing to
+ handle symbol extension sections.
+
+ * config/tc-hppa.c (pa_build_symextn_section): New function to
+ create a symbol extension section.
+ (pa_export_args): Make call to pa_build_symextn_section.
+ (hppa_tc_symbol, hppa_tc_make_sections,
+ hppa_tc_make_symextn_section): New functions.
+ * config/tc-hppa.h: Update elf_tc_symbol and elf_tc_make_sections
+ macros.
+
+ * read.c (emit_expr): Place check for TC_CONS_FIX_NEW in the
+ BFD_ASSEMBLER branch as well.
+
+ * config/tc-hppa.h: If ELF is the target object format, define
+ some ELF- and hppa-specific types and constants.
+
+ * config/tc-hppa.c (getExpression): Fix a typo.
+
+ * read.c (read_a_source_file): Use TC_EQUAL_IN_INSN to determine
+ if a `=' is part of an instruction.
+ (read_a_source_file): Handle case where end-of-line markers are
+ also used within instructions.
+ * config/tc-hppa.h (TC_EQUAL_IN_INSN, TC_EOL_IN_INSN): Define.
+
+ * config/tc-hppa.c (md_apply_fix_1): Keep relocations for
+ out-of-range branches/'calls using "bl" or calls which may need
+ argument relocation stubs. Do not need/keep relocations for
+ conditional branches.
+ (elf_hppa_final_processing): Fix calculation of function size.
+
+ * config/obj-elf.c (obj_elf_version): Mark .note section as
+ READONLY.
+
+ * config/tc-hppa.c (parse_cons_expression_hppa): Pass exp, not the
+ address of exp, to expression.
+ (pa_build_unwind_subspace): Turn SEC_HAS_CONTENTS flag on.
+ (md_apply_fix_1): Delete unwanted comments.
+ (process_exit): Symbols marking the end of a function are always
+ BSF_LOCAL.
+
+ * config/tc-hppa.c: Include elf32-hppa.h from BFD tree.
+ (pa_space): Declare and initialize gdb_section.
+
+ * config/obj-elf.c (elf_frob_file): Change
+ elf_tc_final_processing_hook to elf_tc_final_processing.
+
+ * config/tc-hppa.c (fix_new_hppa): Fix argument list to match
+ argument type declarations.
+ (getExpression): Fix typo.
+ (pa_export_args): Change elf_symbol_type to elf32_symbol_type.
+ (elf_hppa_final_processing): Likewise. Name changed from
+ elf_hppa_final_processing_hook.
+ (start_symbol_root, start_symbol_last): Deleted.
+
+ * config/tc-hppa.h (TC_PARSE_CONS_EXPRESSION): Fix typo.
+
+ * config/tc-hppa.h: Replace "symbolS" with "struct symbol" to
+ avoid changing include ordering.
+
+ * config/tc-hppa.c (pa_ip, case 'y'): Handle just like 't'.
+
+Mon Aug 23 12:47:58 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (set_at): Added unsignedp argument. Use
+ load_register.
+ (set_at_unsigned): Removed; changed callers to use set_at.
+ (load_register): Removed unused ip argument. Changed callers.
+ (append_insn): Don't swap branch and branch likely.
+ (macro_build): Handle 'u'.
+ (load_register): Handle 64 bit constants.
+ (macro): Added M_DABS, removed M_ABSU. Numerous changes to
+ support 64 bit constants.
+ (mips_ip): Use hex constants in range checks for clarity.
+ (md_number_to_chars): Support 8 byte values.
+
+Fri Aug 20 16:50:59 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * config/tc-m88k.h: updated copyrights.
+ (TC_CONS_RELOC): declare to be RELOC_32.
+
+Fri Aug 20 11:16:44 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_isa): New static variable.
+ (md_begin): Initialize mips_isa based on TARGET_CPU. Don't sanity
+ check macros. Set text alignment and GP size here.
+ (md_assemble): Don't set text alignment and GP size here.
+ (append_insn): Don't insert NOPs for load delays if mips_isa >= 2.
+ Use the right mask and shift for WRITE_FPR_T and WRITE_FPR_S. Add
+ a NOP after a branch likely.
+ (mips_emit_delays): Don't insert NOPS for load delays if mips_isa
+ >= 2.
+ (macro): Support r6000 and r4000 macros.
+ (mips_ip): Check insn ISA level against mips_isa before using it.
+ Added 'x' case for ignored register.
+ (md_parse_option): Handle -mipsN and -mcpu=XX.
+
+Fri Aug 20 01:26:52 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-i386.c (md_pseudo_table) [OBJ_ELF]: Handle ".zero".
+
+Thu Aug 19 12:15:18 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (s_local): Function moved and renamed...
+ * config/obj-elf.c (obj_elf_local): ...to here.
+ * config/tc-sparc.c (md_pseudo_table), config/obj-elf.c
+ (obj_pseudo_table): Move handling of ".local".
+
+ * tc.h (md_parse_option): Don't declare if defined as a macro.
+
+ * config/tc-i386.h (NO_RELOC) [BFD_ASSEMBLER]: Define as
+ BFD_RELOC_NONE.
+ (md_parse_option): New macro, converted from function.
+ * config/tc-i386.c (md_parse_option): Function deleted.
+ (comment_chars) [OBJ_ELF]: Include "/".
+ (line_comment_chars) [OBJ_ELF || TE_I386AIX]: Don't include "/".
+ (md_assemble): Cast 0xe9 to char explicitly, to avoid compiler
+ warning.
+ (md_assemble, md_estimate_size_before_relax, md_create_long_jump):
+ Call reloc for fix_new type, or use correct enumerator, instead of
+ always using NO_RELOC.
+ (i386_operand): Change "ifndef I386COFF" to "ifdef OBJ_AOUT" for
+ tests for valid section.
+ (md_convert_frag) [BFD_ASSEMBLER]: Compensate for frag start
+ address.
+ (md_apply_fix_1) [BFD_ASSEMBLER]: For pc-relative reloc with
+ symbol, compensate for location of reloc.
+ (reloc, BFD_RELOC_32, BFD_RELOC_32_PCREL) [!BFD_ASSEMBLER]: Define
+ to return zero.
+
+Wed Aug 18 16:51:29 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-elf.c: Undef NO_RELOC before including aout/aout64.h.
+ (obj_elf_weak): New function.
+ (obj_pseudo_table): Handle ".weak".
+ (obj_elf_section): If section directive includes a string, ignore
+ it for now. Accept "progbits" flag.
+ (obj_elf_type): Accept `@' before flag name.
+
+ * write.c (relax_and_size_seg) [BFD_ASSEMBLER]: Get rid of `if(1)'
+ condition.
+ (fixup_segment) [BFD_ASSEMBLER]: Use bfd_is_com_section, rather
+ than checking for bfd_com_section directly.
+ (fixup_segment): Simplify range check.
+ (fixup_segment) [OBJ_COFF && TC_I960]: Simplify cpp condition
+ test.
+
+ * symbols.h (S_SET_WEAK): Declare.
+ * symbols.c (S_SET_WEAK): New function.
+ (S_SET_EXTERNAL, S_CLEAR_EXTERNAL): Don't bother with BSF_EXPORT,
+ it's not a separate flag any more. Clear BSF_WEAK.
+
+ * read.c (potable): Treat "string" like "asciz".
+
+Wed Aug 18 15:30:29 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (append_insn): Don't swap branch instructions
+ if .set nobopt or .set volatile.
+ (gp_reference): .lit8 and .lit4 are accessed via the GP register.
+ (macro): Added cases M_LI_S, M_LI_SS. Fixed M_LI_D and M_LI_DD.
+ (mips_ip): Added cases 'F', 'L', 'f', 'l' for floating point.
+ * config/obj-ecoff.c: Renamed some variables to avoid shadow
+ warnings.
+
+Mon Aug 16 14:16:02 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * config/obj-coff.h (S_IS_COMMON): add missing backslash
+
+ * configure.in (z8k-*-{coff,sim}): use coffbfd for this target
+
+Thu Aug 12 11:47:58 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Suggested by
+ davidj@ICSI.Berkeley.EDU (David Johnson): Don't accept symbolic
+ names for 'E' and 'G' argument types (coprocessor registers) and
+ don't warn if $1 is used on the coprocessor.
+ (macro): Handle M_{L,S}WC{0,2,3}_AB correctly.
+
+Mon Aug 9 12:09:14 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * read.c (emit_expr): Use BFD_RELOC_16 for 2-byte values.
+ * config/tc-sparc.c (md_apply_fix, tc_gen_reloc): Handle
+ BFD_RELOC_16.
+ * config/tc-sparc.h (WORKING_DOT_WORD): Define.
+
+Mon Aug 9 13:36:22 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * write.c (merge_data_into_text): Define only if BFD_ASSEMBLER is
+ defined or BFD is not.
+ (relax_and_size_all_segments): Declare local variable fragP.
+
+Fri Aug 6 15:22:53 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (md_apply_fix, case BFD_RELOC_32): Fill in
+ bytes with real values, not zeros.
+
+Fri Aug 6 10:57:59 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in (mips-*-riscos*, mips-*-sysv*): New (untested)
+ targets, using ecoff and mips-big.
+
+ * config/tc-mips.c (mips_ip): From davidj@ICSI.Berkeley.EDU (David
+ Johnson): Added case for 'C' for coprocessor instruction codes.
+
+Thu Aug 5 13:08:56 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (md_apply_fix, case BFD_RELOC_64): Fill in
+ bytes with real values, not zeros.
+ (md_pseudo_table): Call cons for .uaxword.
+
+ * config/obj-elf.c (obj_pseudo_table): Handle ".8byte".
+
+ * read.c (emit_expr): Use BFD_RELOC_64 for 8-byte expressions.
+
+ * write.c (write_object_file): Test DEBUG_SYMS instead of DEBUG
+ for verifying symbol chain.
+ (merge_data_into_text, relax_and_size_all_segments): New
+ functions, split out from write_object_file.
+
+Tue Aug 3 15:43:55 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-elf.c (obj_elf_stab_generic, in disabled code): If
+ debug section is new, allocate an extra 12 bytes at its start. If
+ ".stabs" type is N_SO, fill in filename symbol field of that first
+ entry. Return early if "goof", to simplify later code slightly.
+ (adjust_stab_sections): New function.
+ (elf_frob_file): Apply adjust_stab_sections to each section.
+
+ * config/obj-elf.c (obj_elf_section, obj_elf_previous): No longer
+ static.
+ * config/obj-elf.h (obj_elf_section, obj_elf_previous): Declare.
+ * config/tc-sparc.c (md_pseudo_table): Call them for "pushsection"
+ and "popsection", and call cons for "uaword" and "uahalf".
+
+ * config/obj-elf.c (obj_elf_version): Use English in error
+ messages.
+
+Tue Aug 3 11:29:06 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-ecoff.c: Updated for BFD ECOFF changes. Now gets the
+ swapping routines and external structure sizes via the
+ ecoff_backend information. No longer includes coff/mips.h.
+
+Mon Aug 2 17:35:48 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-ecoff.c (get_tag): Save tag name in permanent memory
+ and in hash_ptr->string.
+
+ * app.c (do_scrub_next_char): Reset state to 0 after .appline if
+ file name is not seen.
+
+Mon Aug 2 11:51:41 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (md_apply_fix, case BFD_RELOC_64): New case,
+ parallel to BFD_RELOC_32.
+ (tc_gen_reloc): Accept BFD_RELOC_64.
+
+Thu Jul 29 22:21:28 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * write.c: Don't use short int in a prototype.
+
+ * expr.c (operand): Make return value simply depend on contents of
+ returned expression.
+
+Thu Jul 29 18:38:37 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in: sparc*-aout and sparc*-vxworks are BFD assemblers
+
+Thu Jul 29 18:38:37 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * config/ho-sunos.h: remove some old function decls that conflict
+ w/ ANSI, and which weren't needed anyway
+
+Wed Jul 28 16:34:55 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-elf.h (obj_frob_symbol): Renamed from tc_frob_symbol,
+ and disabled since it breaks Ian's new symbol-value code.
+
+ * expr.c (integer_constant): Accept more digits if BFD64.
+
+Wed Jul 28 11:30:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip): If we have a normal constant when we
+ expect a bignum, turn it into a bignum. Output extra zeroes
+ before a short bignum, rather than after.
+
+Tue Jul 27 15:54:27 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * symbols.c (symbol_new): Conditionalize verify_symbol_chain call
+ on DEBUG_SYMS, not DEBUG.
+ (symbol_remove): Likewise.
+ (symbol_insert): Likewise.
+
+Tue Jul 27 08:45:05 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-mips.c (mips_optimize): New static variable.
+ (append_insn): If mips_optimize == 0, always insert NOP
+ instructions. If mips_optimize < 2, don't swap branches.
+ (md_parse_option): If -Ox or -gx, set mips_optimize accordingly.
+
+Mon Jul 26 18:02:43 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * Makefile.in (clean): if testsuite does not exist, then skip it.
+
+Fri Jul 23 14:13:25 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (prev_insn_unreordered,
+ prev_prev_insn_unreordered): New static variables.
+ (append_insn): Don't swap branch instruction if
+ prev_prev_insn_unreordered (see comment).
+ (mips_no_prev_insn): Clear the unreordered variables.
+ (s_mipsset): When turning on reordering, set the unreordered
+ variables.
+
+Fri Jul 23 13:09:44 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-elf.c (obj_elf_section): Sections ".init" and ".fini"
+ are also magic, and have special default flag settings.
+ (obj_elf_frob_symbol): Since the return value from this function
+ isn't used, don't bother calling obj_elf_write_symbol_p, since it
+ doesn't accomplish anything else.
+
+ * config/tc-sparc.c (md_section_align): Round up section size only
+ for a.out format.
+
+ * symbols.c: Don't define DEBUG by default.
+
+Thu Jul 22 12:09:41 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * write.c (fix_new_exp): Handle a O_uminus expression.
+
+ * expr.c (expr): Don't let absolute_section override
+ undefined_section for the return value.
+
+ * read.c (read_a_source_file): In NO_PSEUDO_DOT case, if we find a
+ pseudo-op with a poc_handler field of NULL, ignore it and treat it
+ as an instruction instead.
+ * config/tc-m88k.c (md_pseudo_table): Add "set" with a NULL
+ poc_handler field.
+
+ * config/tc-h8500.c (md_begin): Use a local variable when
+ initializing md_relax_table to avoid warnings about modifying a
+ supposedly const data structure.
+
+Thu Jul 22 10:58:51 1993 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * config/obj-aout.c: Only include aout/aout64.h if BFD_ASSEMBLER
+ is defined.
+
+Wed Jul 21 17:32:02 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * configure.in (case ${host}): Map *-*-sysv4* to gas_host=sysv.
+ * configure.in (case ${generic_target}): Add i[34]86-*-sysv4*
+ case to set obj_format=elf. Must go before i386-*-sysv* case that
+ sets obj_format=coffbsd. Add *-*-sysv4* to *-*-elf and
+ *-*-solaris case, and move to before *-sysv* case that wants to
+ set obj_format to coff.
+ * config/tc-i386.c (i386_operand): Change all 'exp.X_op' to
+ 'exp->X_op'.
+ * config/tc-i386.c (md_apply_fix): Fix valp to be 'valueT *' for
+ BFD_ASSEMBLER case.
+
+Wed Jul 21 12:47:51 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-aout.c: Include aout/aout64.h.
+ (obj_aout_frob_symbol): Set BSF_DEBUGGING for a constructor
+ symbol, so that BFD doesn't tamper with the type.
+
+ * read.c (read_a_source_file): If NO_PSEUDO_DOT is defined, look
+ up opcodes as pseudo-ops even if they don't start with '.'.
+ * config/tc-m88k.h (NO_PSEUDO_DOT): Define.
+ * config/tc-m88k.c (md_assemble): Removed special pseudo-op
+ handling.
+ (md_apply_fix): Set fx_offset to the upper 16 bits of the reloc.
+ Output the low 16 bits for RELOC_HI16, not the high 16 bits.
+ * config/obj-coffbfd.c (do_relocs_for): If TC_M88K, set the
+ r_offset field of the reloc to the fixup offset.
+ (fixup_segments): If TC_M88K, don't warn about fixup overflows.
+ * doc/as.texinfo: Minor updates.
+
+Tue Jul 20 19:28:56 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Extensive changes to permit symbols to contain any expression
+ type and to delay the computation of the expression until the
+ value is actually needed. This permits setting symbols to values
+ calculated based on object code size. Expressions were changed to
+ no longer be in a section, to stop the overloading of segment and
+ expression type that previously occurred.
+
+ * as.c (big_section, pass1_section, diff_section, absent_section):
+ Removed.
+ (expr_section): Added (used for dummy symbols which hold
+ intermediate expression values).
+ (perform_an_assembly_pass): Create expr_section, do not create the
+ sections now removed.
+ * as.h (segT): Removed SEG_ABSENT, SEG_PASS1, SEG_BIG, and
+ SEG_DIFFERENCE. Added SEG_EXPR.
+ (SEG_NORMAL): Corresponding changes.
+ * subsegs.c (seg_name, subsegs_begin): Changed accordingly.
+ * write.c (write_object_file): Ditto.
+ * config/obj-aout.c (seg_N_TYPE): Ditto.
+ * config/obj-bout.c (seg_N_TYPE): Ditto.
+ * config/obj-coff.c (seg_N_TYPE): Ditto.
+ * config/obj-coffbfd.c (seg_N_TYPE): Ditto.
+ * config/obj-vms.c (seg_N_TYPE): Ditto.
+
+ * expr.h (operatorT): Moved in from expr.c, added some values.
+ (expressionS): Added X_op field, removed X_seg field; renamed
+ X_subtract_symbol to X_op_symbol.
+ * expr.c: Extensive changes to assign expression types rather than
+ sections and to simplify the parsing.
+ * write.c (fix_new_internal): New static function.
+ (fix_new): Removed sub_symbol argument.
+ (fix_new_exp): New function, takes expression argument.
+ * write.h: Prototype changes for fix_new and fix_new_exp.
+ * cond.c (s_if): Changed accordingly.
+ * read.c (s_lsym, pseudo_set, emit_expr, parse_bitfield_cons,
+ parse_repeat_cons, get_segmented_expression,
+ get_known_segmented_expression, get_absolute_expression): Ditto.
+ * symbols.c (resolve_symbol_value, S_GET_VALUE, S_SET_VALUE):
+ Ditto.
+ * write.c (write_object_file): Ditto.
+ * config/obj-coff.c (obj_coff_def, obj_coff_val): Ditto.
+ * config/obj-coffbfd.c (obj_coff_def, obj_coff_val,
+ obj_coff_endef, yank_symbols): Ditto.
+ * config/obj-elf.c (obj_elf_stab_generic, obj_elf_size): Ditto.
+ * config/tc-a29k.c (md_assemble, parse_operand, machine_ip,
+ print_insn, md_operand): Ditto.
+ * config/tc-h8300.c (parse_exp, colonmod24, check_operand,
+ do_a_fix_imm, build_bytes): Ditto.
+ * config/tc-h8500.c (parse_exp, skip_colonthing, parse_reglist,
+ get_specific, check, insert, md_convert_frag): Ditto.
+ * config/tc-hppa.c (the_insn, fix_new_hppa, cons_fix_new_hppa,
+ md_assemble, pa_ip, getExpression, getAbsoluteExpression,
+ evaluateAbsolute, pa_build_unwind_subspace, pa_entry,
+ process_exit): Ditto.
+ * config/tc-hppa.h (STAB_FIXUP, is_DP_relative, is_PC_relative,
+ is_complex): Ditto.
+ * config/tc-i386.c (pe, md_assemble, i386_operand,
+ md_estimate_size_before_relax, md_create_long_jump): Ditto.
+ * config/tc-i860.c (md_assemble, getExpression, print_insn):
+ Ditto.
+ * config/tc-i960.c (parse_expr, subs, segs, md_convert_frag,
+ get_cdisp, mem_fmt, parse_ldconst, relax_cobr, s_sysproc,
+ i960_handle_align): Ditto.
+ * config/tc-m68k.c (struct m68k_exp, struct m68k_it, seg, op,
+ subs, add_fix, isvar, m68k_ip, md_assemble, md_convert_frag_1,
+ md_estimate_size_before_relax, md_create_long_jump, get_num):
+ Ditto.
+ * config/tc-m88k.c (md_assemble, get_imm16, get_pcr,
+ md_create_short_jump, md_create_long_jump): Ditto.
+ * config/tc-mips.c (md_assemble, append_insn, gp_reference,
+ macro_build, macro, my_getExpression): Ditto. Also removed
+ get_optional_absolute_expression; just use get_absolute_expression
+ instead.
+ * config/tc-ns32k.c (get_addr_mode, evaluate_expr, convert_iif,
+ fix_new_ns32k, fix_new_ns32k_exp, cons_fix_new_ns32k): Ditto.
+ * config/tc-ns32k.h (fix_new_ns32k prototype): Ditto.
+ * config/tc-sh.c (parse_exp, check, insert, md_convert_frag):
+ Ditto.
+ * config/tc-sparc.c (md_assemble, sparc_ip, getExpression,
+ print_insn): Ditto.
+ * config/tc-tahoe.c (struct top, md_estimate_size_before_relax,
+ tip_op, md_assemble): Ditto.
+ * config/tc-vax.c (seg_of_operand, md_assemble,
+ md_estimate_size_before_relax, md_create_long_jump): Ditto.
+ * config/tc-z8k.c (parse_exp, check_operand, newfix): Ditto.
+
+Tue Jul 20 12:17:16 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in: i386-lynx is the same as i386-coff
+
+Mon Jul 19 15:21:20 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * config/obj-elf.c (obj_elf_previous): New function.
+ (previous_section, previous_subsection): New vars.
+ (obj_elf_section): Save current place in case DWARF code wants us
+ to pop back to it. Handle unquoted section name as well as quoted
+ section name. Don't crash on invalid strings.
+ (obj_pseudo_table): Handle new pseudos "previous", "2byte", and
+ "4byte".
+
+ * config/obj-elf.h: Don't include struc-symbol.h.
+ (obj_elf_frob_symbol): Declare arg as struct symbol *.
+
+ * config/tc-sparc.h (LOCAL_LABEL) [OBJ_ELF]: Local labels can start with
+ "L" or "_.L_".
+
+ * write.c (write_relocs): New function, split off from
+ write_contents. Use memset instead of bzero.
+ (write_object_file): Apply write_relocs to each section before
+ applying write_contents.
+
+ * read.c (read_begin): Call obstack_begin with values closer to 1K
+ multiples.
+ (read_a_source_file, big_cons, float_cons): Use memcpy instead of
+ bcopy.
+
+Mon Jul 19 14:30:00 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip_op): Don't decrement strend when
+ calculating opP->isiz; this permits the expression size to be
+ determined as well, later on.
+
+ * expr.c (clean_up_expression): Don't cancel the subtraction of
+ undefined symbols.
+
+ * read.c (s_data), config/obj-coffbfd.c (obj_coff_data): If -R,
+ switch to text section rather than data section.
+
+Mon Jul 19 12:35:39 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip, case AINDX): Add 6 to operand
+ expression (to take the pc-rel instruction itself into account)
+ before using the expression, instead of after.
+
+Fri Jul 16 08:56:04 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * read.c (float_cons): Simplified parsing logic. If
+ REPEAT_CONS_EXPRESSIONS is defined, accept a repeat count.
+
+ * symbols.c (colon): Rather than a special case for TC_HPPA,
+ use new macro tc_frob_label.
+ * config/tc-hppa.h (tc_frob_label): Define.
+
+ * config/tc-mips.c: Many changes to support simple assembler
+ optimization.
+ (insn_label, prev_insn, prev_prev_insn, dummy_opcode,
+ prev_insn_valid, prev_insn_frag, prev_insn_where,
+ prev_insn_fixp, prev_insn_is_delay_slot): New static
+ variables.
+ (insn_uses_reg, mips_no_prev_insn, mips_emit_delays,
+ mips_align, s_stringer, s_mips_space): New static functions.
+ (mips_define_label): New global function.
+ (md_pseudo_table): For "ascii", "asciz", "asciiz", call
+ s_stringer. Changed argument to float_cons from 0 or 1 to 'f'
+ or 'd'. For "space" call s_mips_space.
+ (md_begin): Call mips_no_prev_insn.
+ (append_insn): Only insert necessary NOP instructions.
+ (macro): Call mips_emit_delays before setting mips_noreorder.
+ Increment and decrement mips_noreorder rather than using
+ save_reorder_condition. Don't bother to use noreorder in
+ M_L_DOB and M_L_DAB, since append_insn will not insert a NOP.
+ (md_atof): Handle floating point numbers correctly for both
+ big and little endian targets.
+ (s_align, s_cons): Call mips_align rather than frag_align.
+ (s_change_seg, s_cons): Call mips_emit_delays.
+ (s_float_cons): Let float_cons do the work.
+ (s_mipsset): Call mips_emit_delays when setting noreorder.
+ * config/tc-mips.h (tc_frob_label): Define to be
+ mips_define_label.
+
+ * config/obj-ecoff.c (ecoff_build_symbols, ecoff_build_procs,
+ ecoff_frob_files): Consistently use S_GET_VALUE rather than
+ bfd_asymbol_value. Warn if taking difference of symbols in
+ different segments.
+
+Thu Jul 15 11:51:03 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-ecoff.c (ecoff_frob_file): Discard all open scopes,
+ with a warning.
+
+ * config/obj-coffbfd.c (fixup_segment): If TC_M88K, don't adjust
+ by md_pcrel_from if we are relocating against a symbol (we still
+ need md_pcrel_from for a PC relative relocation within the same
+ file).
+ * config/tc-m88k.c (md_pcrel_from): Corrected return value.
+ (omagic): Removed unused variable.
+
+ * Preliminary support for m88k-coff.
+ * configure.in (m88k-*-coff*): New target. Use coffbfd and
+ m88kcoff.
+ * config/m88kcoff.mt: New file.
+ * read.c (lex_type): New macro LEX_AT to set lex type of '@'.
+ (pseudo_set): Handle difference of symbols in different fragments
+ by saving the entire expression as the value of the symbol.
+ * symbols.c (resolve_symbol_value): Resolve difference
+ expressions.
+ * config/obj-coffbfd.c (obj_pseudo_table): If TC_M88K, accept
+ "sdef" as a synonym for "def".
+ * config/obj-coffbfd.h: If TC_M88K, include coff/m88k.h and set
+ TARGET_FORMAT.
+ (S_IS_LOCAL): Any symbol which includes \001 in the name is local.
+ * config/tc-m88k.c, config/tc-m88k.h: Numerous changes to bring
+ m88k port up to date, and to add COFF support.
+
+Wed Jul 14 15:09:32 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Removed sy_forward and replaced it with an undefined expression
+ as the value of a symbol.
+ * struc-symbol.h (struct symbol): Removed sy_forward field. Added
+ sy_resolved and sy_resolving single bit fields.
+ * symbols.c (symbol_new): Don't initialize sy_forward field.
+ (resolve_symbol_value): New function to adjust symbol value by
+ fragment address, using recursion to resolve forward symbols.
+ * symbols.h: Added prototype for new function.
+ * read.c (pseudo_set): Set symbolP->sy_value to an undefined
+ expression rather than setting symbolP->sy_forward.
+ * write.c (write_object_file): Use resolve_symbol_value on
+ symbols, keeping the common case (the old behaviour) inline.
+ * config/obj-aout.c (obj_aout_frob_symbol): Removed sy_forward
+ handling (subsumed by write.c change).
+ * config/obj-coff.c, config/obj-coffbfd.c (obj_coff_val): Set
+ sy_value rather than sy_forward.
+ * config/obj-coffbfd.c (obj_coff_endef, yank_symbols): Check
+ expression segment rather than sy_forward.
+ (yank_symbols): Use resolve_symbol_value.
+ (crawl_symbols): Removed extra pass over symbols.
+ * config/obj-aout.c, config/obj-bout.c, config/obj-coff.c,
+ config/obj-vms.c (obj_crawl_symbol_chain): Removed extra pass over
+ symbols which handled sy_forward; use resolve_symbol_value
+ instead.
+ * config/obj-coff.h, config/obj-coffbfd.h (obj_frob_forward_symbol):
+ Define.
+ * config/obj-elf.c (obj_elf_stab_generic): Check expression
+ segment rather than sy_forward.
+ * config/obj-vms.c (VMS_Check_For_Main): Don't initialize
+ sy_forward; do initialize sy_resolved and sy_resolving.
+ * config/tc-hppa.h (STAB_FIXUP): Use sy_value, not sy_forward.
+
+ * Changes to keep a full expression as the value of a symbol, not
+ just a longword:
+ * struc-symbol.h: New field sy_value.
+ * as.h: Include expr.h before struc-symbol.h.
+ * expr.h: Use struct symbol rather than symbolS.
+ * symbols.c (S_GET_VALUE, S_SET_VALUE): Rewrote to retrieve value
+ of sy_value field; compile unconditionally, not just if
+ BFD_ASSEMBLER.
+ * symbols.h: Compile S_{SG}ET_VALUE prototypes unconditionally.
+ * write.c (write_object_file): Set BFD symbol value to gas symbol
+ value.
+ * config/obj-aout.h, config/obj-bout.h, config/obj-coff.h,
+ config/obj-coffbfd.h, config/obj-generic.h, config/obj-vms.h
+ (S_GET_VALUE, S_SET_VALUE): Removed macro definitions.
+ * config/obj-ieee.c (S_GET_VALUE, S_SET_VALUE): Removed.
+ * config/obj-coff.h, obj-coffbfd.h: Rewrote several macros to use
+ S_GET_VALUE rather than ost_entry.n_value.
+ * config/obj-aout.c (obj_symbol_to_chars), config/obj-bout.c
+ (obj_symbol_to_chars), config/obj-coff.c (obj_symbol_to_chars),
+ config/obj-coffbfd.c (symbol_to_chars): Get value to write out
+ using S_GET_VALUE--don't assume it is already set.
+ * config/obj-ieee.c (do_symbols): Set BFD symbol value to gas
+ symbol value.
+ * config/obj-vms.c (various): Don't assign directly to
+ S_GET_VALUE; use S_SET_VALUE instead.
+
+Wed Jul 14 09:35:23 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * configure.in: Make sparc64-*-aout* use bfd gas.
+
+ * configure.in: Recognize h8300h.
+
+Tue Jul 13 12:09:44 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * config/tc-h8500.c (line_comment_chars): Add hash.
+ (parse_exp, skip_colonthing, build_bytes): Add support for
+ R_H8500_HIGH16 relocation type.
+
+Mon Jul 12 11:15:34 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * config/obj-elf.c (obj_elf_section): Allow `@' to introduce an
+ attribute name. Handle `execinstr' attribute.
+
+Mon Jul 12 07:22:28 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Don't warn on 'i' or 'j' mismatch if
+ there is another alternative for the instruction.
+
+Fri Jul 9 17:31:34 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * doc/as.texinfo: updates for H8/300H
+
+Thu Jul 8 14:41:43 1993 Mark Eichin (eichin@cygnus.com)
+
+ * config/tc-i960.c (md_create_short_jump, md_create_long_jump,
+ md_number_to_chars, md_section_align): Adjusted to use valueT,
+ addressT, to match tc.h.
+
+Thu Jul 8 14:15:05 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (s_common): Revamp to handle both syntaxes,
+ independent of format.
+
+Thu Jul 8 07:25:25 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/tc-h8300.h (TC_CONS_RELOC): Use R_RELLONG if H8/300H.
+
+Wed Jul 7 18:11:07 1993 david d `zoo' zuhn (zoo at rtl.cygnus.com)
+
+ * configure.in: define CROSS=-DCROSS_COMPILE if it is a cross
+ build; also recognize h8300-*-coff
+
+Wed Jul 7 10:21:24 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * symbols.c (fb_label_instance, fb_label_instance_inc): Don't dump
+ core just because somebody uses a label before it is defined.
+
+ * config/mips-opcode.h: Moved to opcode/mips.h.
+ * config/tc-mips.c: Include opcode/mips.h rather than
+ mips-opcode.h.
+ (append_insn): An extra NOP is only needed after instructions
+ which set HI or LO, not after instructions which read it.
+ (macro_build, mips_ip): Support new 'E', 'G' and 'B' arguments.
+ (macro): cfc1 and ctc1 now take "t,G" rather than "t,d".
+ * config/tc-mips.h (struct mips_opcode): Don't define.
+ * config/mips-big.mt, config/mips-lit.mt (TARG_CPU_DEPENDENTS):
+ Set to $(srcdir)/../include/opcode/mips.h.
+
+ Get the MIPS assembler up to speed with other gas changes:
+
+ * config/obj-ecoff.c (ecoff_set_vma, ecoff_frob_symbol):
+ Removed; don't change the symbol value.
+ (ecoff_build_symbols, ecoff_build_procs, ecoff_frob_file): Use
+ bfd_asymbol_value rather than S_GET_VALUE to include section
+ vma in symbol value.
+ (ecoff_frob_file): Ignore BSF_SECTION_SYM symbols, since ECOFF
+ doesn't output them. Set the vma of sections.
+ * config/obj-ecoff.h: Don't define obj_frob_symbol.
+ * config/tc-mips.c (tc_gen_reloc): Adjustment by section vma is no
+ longer necessary.
+ (various): use valueT rather than long.
+
+Wed Jul 7 08:33:30 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.h (ENV64): Define for v9.
+
+ * config/tc-sparc.c (s_xword): For numbers, call big_cons.
+ (sparc_ip, md_apply_fix, tc_gen_reloc): Handle some sparc64
+ relocation types.
+ (md_number_to_chars): Handle 8-byte value.
+
+ * config/obj-elf.h (elf_symbol): For v9, use 64-bit symbol type.
+
+ * as.h (valueT): Typedef moved here.
+ * struc-symbol.h (valueT): ...from here.
+ * write.c (write_object_file): Locals from_addr, to_addr,
+ table_addr are now addressT. Supply prototype for bfd_alloc for
+ now.
+ (fixup_segment): Local add_number is now valueT. Correct some
+ range-checking bugs.
+ (relax_align): Type `int' should be sufficient for the exponent.
+ (fix_new): Argument offset is type offsetT. Locals size and
+ newsize are type valueT.
+ * write.h (struct fix): Fields fx_offset and fx_addnumber are now
+ type valueT.
+ (fix_new): Fix prototype.
+ * symbols.c (symbol_new): Symbol value is type valueT.
+ (S_SET_VALUE, S_GET_VALUE): Likewise.
+ (S_IS_*): Specify int return type explicitly.
+ * symbols.h (symbol_new, S_GET_VALUE, S_SET_VALUE): Fixed
+ prototypes.
+ * read.c (s_comm): Values read are type valueT.
+ * expr.h (expressionS): Field X_add_number is an offsetT.
+ * tc.h (md_create_long_jump, md_create_short_jump,
+ md_section_align): Addresses are now type addressT.
+ (md_number_to_chars, md_apply_fix): Pass value as valueT.
+ * config/tc-i386.c (md_create_short_jump, md_create_long_jump,
+ md_number_to_chars, md_section_align): Adjusted.
+ * config/tc-sparc.c (sparc_ip): Initialize `len' variable to make
+ gcc shut up.
+ (md_create_short_jump, md_create_long_jump, md_number_to_chars,
+ md_section_align): Adjusted.
+
+ * config/tc-sparc.c (s_reserve): Permit use for other than a.out
+ format.
+ (s_common): Handle Solaris-2 version.
+
+ * config/ho-generic.h (free): Returns void if __STDC__.
+
+ * config/obj-elf.h (obj_elf_frob_symbol, elf_frob_file,
+ elf_file_symbol): Declare.
+
+ * expr.c (floating_constant, integer_constant): Now return void.
+
+Thu Jul 1 12:13:43 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in: Match on sparc*-fujitsu-none rather than
+ sparclite*-fujitsu-none.
+
+Wed Jun 30 11:12:02 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * read.c (cons): Conditionalize parsing of expression. Move
+ putting value into object file into separate function. Separate
+ out MRI and WANT_BITFIELDS cases into separate functions.
+ (emit_expr): New function to write data into object file.
+ Conditionalize on TC_CONS_FIX_NEW and TC_CONS_RELOC rather than on
+ processor types.
+ (parse_bitfield_cons): New function to parse bitfield expressions
+ as used by i960 assemblers. Only compiled if
+ BITFIELD_CONS_EXPRESSIONS is defined.
+ (parse_mri_cons): New function to parse MRI style strings. Only
+ compiled if MRI is defined.
+ (parse_repeat_cons): New function to parse repeat counts. Only
+ compiled if REPEAT_CONS_EXPRESSIONS is defined.
+ * read.h (emit_expr): Added declaration of new function.
+ * config/tc-a29k.h (TC_CONS_RELOC): Define to be RELOC_32.
+ * config/tc-h8300.h (TC_CONS_RELOC): Define to be R_RELWORD.
+ * config/tc-hppa.c (parse_cons_expression_hppa): New function to
+ parse a HPPA expression, rather than special case in cons
+ function.
+ (cons_fix_new_hppa): New function to emit an HPPA fixup, rather
+ than special case in emit_expr function.
+ * config/tc-hppa.h (TC_PARSE_CONS_EXPRESSION, TC_CONS_FIX_NEW):
+ Define to use new functions from tc-hppa.c.
+ * config/tc-i960.h (BITFIELD_CONS_EXPRESSIONS): Define.
+ (WANT_BITFIELDS): Removed; now obsolete.
+ * config/tc-mips.h (REPEAT_CONS_EXPRESSIONS): Define.
+ * config/tc-ns32k.c (cons_fix_new_ns32k): New function to emit an
+ NS32K fixup, rather than special case in emit_expr function.
+ * config/tc-ns32k.h (TC_CONS_FIX_NEW): Define to be
+ cons_fix_new_ns32k. Also use PARAMS rather than checking
+ __STDC__.
+ * config/tc-sparc.h (TC_CONS_RELOC): Define to RELOC_32.
+
+ * write.c (relax_and_size_seg, adjust_reloc_syms, write_contents):
+ Don't core dump if gas has no information about a section.
+
+Wed Jun 30 06:21:27 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (md_begin): If sparcv9 is defined, reset
+ current_architecture to v9 automatically.
+
+ * config/tc-sparc.h (TARGET_FORMAT): Use elf64-sparc for v9.
+
+ * config/tc-sparc64.h, config/tc-sparc64.c: New files.
+ * configure.in: Use sparc64 cpu files for v9, and default to elf
+ format.
+
+ * write.c (relax_and_size_seg): Always fully process a section.
+ Section size is last frag's (vm)address plus its size. If no
+ relocations are present, force SEC_RELOC flag clear.
+ (dump_section_relocs): New debugging routine.
+ (adjust_reloc_syms): New routine, broken out from write_contents.
+ Don't adjust relocs that are already relative to section symbol.
+ Look for obj_fix_adjustable macro to know what else to skip,
+ instead of obj_write_symbol. Look for section symbol stored in
+ section information.
+ (write_object_file): Map adjust_reloc_syms over all sections.
+ (write_contents): Clear SEC_RELOC flag if no relocations are
+ found.
+
+ * as.h (__PTR_TO_INT, __INT_TO_PTR): New versions for Saber, to
+ keep it quiet.
+
+ * write.c (remove_subsegs): Don't define for BFD_ASSEMBLER.
+
+Fri Jun 25 14:42:53 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * Makefile.in (all, dvi, info, install-info, clean-info): do not
+ echo recursion lines.
+ (install-info, clean-info): collapse into the dvi and info rule.
+
+Fri Jun 25 10:47:24 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Remove support for %d/%q fp regs.
+ All fp regs are now specified as %f.
+ (priv_reg_table): fpq -> fq.
+
+Fri Jun 25 03:43:06 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * as.h (strstr): Disable declaration for now.
+ (fprint_value, sprint_value): Declare.
+
+ * subsegs.c (subseg_new_rest): Use memset to clear new frag.
+ (subseg_new) [BFD_ASSEMBLER]: Initialize all seginfo fields.
+
+ * expr.c (expr_part): Made sanity checks a.out-specific.
+ (expr): Disabled sanity checks.
+
+ * subsegs.h (segment_info_type) [BFD_ASSEMBLER]: Add field for
+ section symbol.
+ * subsegs.c (subseg_change): Initialize section symbol pointer
+ when setting up a new section.
+
+ * symbols.c (symbol_new) [BFD_ASSEMBLER]: Point BFD symbol's udata
+ field back at gas symbol structure.
+
+ * symbols.c (colon): Cast obstack_next_free value to char* before
+ doing arithmetic on it.
+ * subsegs.c (subseg_new_rest): Likewise.
+ * as.h (frag_now_fix): Likewise.
+
+ * config/obj-elf.c (elf_file_symbol): Use subseg_new instead of
+ calling bfd_make_section_old_way directly, and call subseg_set
+ instead of subseg_change. Now returns void.
+ (obj_elf_write_symbol): Only check local symbols for now.
+ (elf_stab_symbol): Now static and void, and disabled until it
+ works completely.
+ (obj_elf_size): For expression values, fail silently for now.
+ (obj_symbol_new_hook): Do nothing.
+
+ * config/tc-sparc.c (tc_gen_reloc): Handle BFD_RELOC_SPARC_WDISP22
+ relocation.
+ (s_local) [OBJ_ELF]: New function.
+ (md_pseudo_table) [OBJ_ELF]: Call it for "local".
+ (s_common): Rearrange to handle Solaris .common pseudo, which may
+ sometimes use bss space instead of common.
+ * config/obj-elf.h (TARGET_SYMBOL_FIELDS): Add new `local' field.
+
+Thu Jun 24 16:33:53 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: set host config to hpux for hppa*-hp-hpux
+
+Thu Jun 24 13:35:06 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * app.c (app_pop, app_push): Fix bug reported by Chris Arthur.
+
+Tue Jun 22 01:04:23 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * subsegs.c (subseg_new): Don't special-case a.out -R flag here.
+ * config/obj-aout.c (s_sect): Do it here.
+
+ * as.h (BAD_CASE): Don't make some lame compilers think we want
+ substitution inside strings.
+
+ * as.c (print_version_id): New function, split off from main.
+ (main): Call it.
+ * config/tc-sparc.c (md_parse_option) [OBJ_ELF]: Print version id
+ for -V. Ignore -Q and -s options for now.
+
+Mon Jun 21 17:37:59 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: make installation & builds work again for crosses
+
+Sun Jun 20 18:18:26 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * listing.c (list_symbol_table): Rewrite to print wide (>32 bits)
+ symbol values correctly.
+
+ * write.c (write_object_file): Deleted unused variables.
+ (fixup_segment): Use sprint_value.
+
+ * messages.c (sprint_value, fprint_value): New routines.
+
+ * config/obj-elf.c (elf_stab_symbol): Now returns void.
+ (obj_elf_stab_generic): Fix typo in logic.
+
+ * Makefile.in (INCLUDES): Look in ../bfd for bfd.h.
+
+ * as.h (addressT, offsetT): New types, using BFD types if
+ available.
+ (relax_addressT, struct frag): Use them.
+ * struc-symbol.h (valueT, struct broken_word): Likewise.
+
+ * as.h (subseg_new) [BFD_ASSEMBLER]: Name argument is const.
+ * subsegs.c (subseg_new) [BFD_ASSEMBLER]: Name argument is const.
+
+Thu Jun 17 16:53:56 1993 david d `zoo' zuhn (zoo@cygnus.com)
+
+ * Makefile.in: canonicalize install.sh; for use within
+ this directory (and subdirs)
+
+Sun Jun 20 02:34:04 1993 Ashley Saulsbury (ans@sics.se)
+
+ * m88k-opcode.h : fixed tiny tiny mistake - xcr was incorrectly
+ specified, should have both S1 and S2 fields identical
+ If only finding the problem was as fast as fixing the bug !!!!
+
+Tue Jun 15 16:01:57 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * write.c (write_contents): Do write out non-loadable sections.
+ Debug sections can fall in this category.
+
+ * read.c (s_app_file): Call elf_file_symbol for ELF files.
+ * config/obj-elf.c (elf_file_symbol): New function.
+
+ * config/obj-elf.c (elf_stab_symbol_string): Renamed from pa_...,
+ added argument to specify section base name.
+ (obj_elf_stab_generic): Renamed from ..._stab. New argument
+ specifies section base name.
+ (obj_elf_stab): New function, calls obj_elf_stab_generic with
+ ".stab" as section base name.
+ (obj_elf_xstab): New function, calls obj_elf_stab_generic.
+ (obj_elf_type): Handle "object". Use bitwise-or to merge in
+ symbol flags rather than simply replacing, so global/local flags
+ are preserved.
+ (obj_elf_ident): Rewrite.
+
+Tue Jun 15 17:03:25 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: remove parentdir support; use INSTALL_XFORM
+
+Wed Jun 9 11:26:07 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-i386.c (md_pseudo_table): .align uses a power of two
+ for any a.out target, not just Linux and 386BSD.
+ * config/tc-i386.h (DOT_LABEL_PREFIX): Do not define for any a.out
+ target.
+
+Mon Jun 7 13:33:19 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-m88k.c: Don't include flonum.h, md.h, m88k.h. They
+ don't exist or duplicate other inclusions.
+
+ * config/tc-vax.h (NO_RELOC): Define.
+
+Mon Jun 7 09:55:03 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Fix parsing of asi number.
+ Fix error message.
+
+Sat Jun 5 19:32:52 1993 Torbjorn Granlund (tege@nada.kth.se)
+
+ * gas/config/m88k-opcode.h (m88k_opcodes): Add 88110 instructions.
+ * gas/config/tc-m88k.c (get_reg): New arg reg_prefix. Compare first
+ char to reg_prefix instead of to 'r'.
+ (calcop): Change calls to get_reg.
+ (calcop): Handle new case 'x' to set reg_prefix.
+ (calcop): Set reg_prefix to 'r' after each call to get_reg.
+ (cmpslot): Add 88110 conditions.
+
+ * gas/config/m88k-opcode.h: Swap cases for "rot" for consistency.
+
+ * gas/config/tc-m88k.c (get_bf): Always restore input_line_pointer
+ before returning.
+
+ * gas/config/m88k-opcode.h (m88k_opcodes): Make equal mnemonics
+ adjacent; mov.s and mov.d swapped.
+ (m88k_opcodes): Fix typo `r2' -> `2'.
+
+Fri Jun 4 15:59:31 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * config/h8300.c: Support for H8/300-H opcodes.
+
+ * config/obj-coffbfd.c (w_strings): String table length is 4
+ bytes, no matter what the host int size is.
+
+ * configure.in (alpha-*-osf*): New.
+
+Fri Jun 4 07:51:18 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in (mips-*-ecoffl*): New target; use ecoff and
+ mips-lit.
+ (mips-*-ecoff*): Added trailing '*'.
+
+ * config/obj-ecoff.c (ecoff_build_procs): Force the adr of the
+ first FDR in a file to be zero.
+
+Thu Jun 3 14:09:59 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (VERSION): Jump to 2.1.4.
+
+ * config/ho-hppabsd.h: New file, from Peter Hoogenboom.
+
+ * config/tc-mips.c (md_assemble): Call bfd_set_gp_size only for
+ ECOFF format.
+
+Tue Jun 1 15:21:57 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-m68k.c (md_assemble): The 68040 cpu doesn't want a
+ separate '851 mmu.
+
+ * config/obj-elf.c, config/obj-elf.h: Update for new type, macro,
+ and routine names. Assuming 32 bits for now.
+
+ * config/obj-elf.c (elf_frob_file): Look for macro
+ elf_tc_final_processing_hook, instead of assuming a function
+ always exists.
+ * config/tc-hppa.c (elf_hppa_final_processing_hook): Renamed from
+ tc_final_processing_hook.
+ * config/tc-hppa.h (elf_tc_final_processing_hook): Use it.
+
+ * config/tc-hppa.h (elf_tc_symbol, elf_tc_make_sections): Macros
+ moved here from obj-elf.h.
+ * config/obj-elf.h: Don't include CPU-specific header files.
+
+Sun May 30 16:49:37 1993 Peter Hoogenboom (hoogen@fast.cs.utah.edu)
+
+ * configure.in: configurations should match on 'hppa*' not 'hppa'.
+
+ * read.c: Add support for HPPA assembly language syntax (denoted
+ with '#ifdef TC_HPPA').
+
+ * symbols.c: Add support for HPPA assembly language syntax (denoted
+ with '#ifdef TC_HPPA').
+
+ * write.c (write_contents): Add support for HPPA-style
+ relocations.
+
+ * config/obj-elf.c: Stab symbols weren't written properly.
+ (obj_elf_version):
+ (obj_elf_desc):
+ (obj_elf_write_symbol):
+ (obj_elf_write_symbol_p):
+ (obj_elf_frob_symbol):
+ (elf_stab_symbol):
+ (elf_frob_file):
+
+ * config/tc-hppa.c: Support for HPPA symbol extension sections.
+ Remove some unused code. Support for HPPA assembly language
+ syntax.
+
+ * app.c:
+
+ * symbols.c:
+
+ * config/obj-elf.h:
+ (obj_write_symbol):
+ (obj_frob_file):
+ (elf_tc_symbol):
+ (elf_tc_make_sections):
+
+ * config/tc-hppa.h:
+
+Sun May 30 21:44:45 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config/obj-ecoff.c (obj_read_begin_hook, add_file): Assume
+ hash_new will have succeeded if it returns.
+ * config/tc-a29k.c (md_begin): Likewise.
+
+ * config/tc-i386.c (tc_aout_fix_to_chars): Now nbytes_r_length is
+ const.
+ (mode_from_disp_size, opcode_suffic_to_type): Now inline under
+ gcc.
+ (fits_in_{signed,unsigned}_{byte,word}): Likewise.
+
+ * expr.c: Delete register declarations; gcc ignores them anyways.
+
+Fri May 28 19:03:32 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * hash.c (hash_new): Use xmalloc, since many callers don't check
+ for failure.
+
+Thu May 27 13:02:15 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * frags.c (zero_address_frag, bss_address_frag): These are
+ external.
+
+ * tc.h (md_reloc_size): This is const.
+ * config/tc-{a29k,h8300,h8500,i386,i860,i960,m68k,ns32k,z8k}.c
+ (md_reloc_size): Now const.
+
+ * config/aout_gnu.h (enum machine_type, enum reloc_type): Delete
+ trailing commas.
+ * as.h (enum _segT): Ditto.
+
+ * struc-symbol.h (N_TYPE_seg): This should be const.
+
+Thu May 27 11:43:59 1993 Michael Meissner (meissner@osf.org)
+
+ * config/obj-ecoff.c (add_file): Cast file_name to char * in
+ listing_source_file call.
+
+ * config/obj-elf.c (elf_stab_symbol_string): Cast first argument
+ of subseg_new call to eliminate const attribute.
+ (obj_elf_stab): Ditto.
+ (obj_symbol_new_hook): Cast first argument of bzero call to char *.
+
+ * read.c (s_align_bytes): Properly record alignment.
+
+ * expr.c (__): Undefine __ macro before use, since OSF/1 uses it
+ for the prototype/no prototype macro.
+
+ * as.c (got_sig): Don't do return ((SIGTY) 0), SIGTY might well be
+ void.
+
+ * as.h (relax_stateT enum): Delete trailing comma.
+
+Thu May 27 11:07:50 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * app.c (do_scrub_begin): Let line_comment_chars override
+ comment_chars.
+ (do_scrub_next_char): If a line comment character is not at the
+ start of a line, treat it as a comment character if it is one.
+ For a CPP line comment use pseudo-op .appline rather than .line.
+ * input-scrub.c (logical_input_line): Make int rather than
+ unsigned.
+ (input_scrub_push, input_scrub_begin): Initialize
+ logical_input_line to -1 rather than 0.
+ (bump_line_counters): Increment logical_input_line.
+ (new_logical_line): If line_number is -2, decrement
+ logical_input_line.
+ (as_where): Use logical_input_line even if it is 0.
+ * read.h (s_app_file prototype): Now takes an int argument.
+ * read.c (potable): Make .appfile call s_app_file with 1. New
+ .appline pseudo-op calls s_app_line.
+ (s_app_file): If .appfile, call new_logical_line with -2 to
+ account for newline inserted by do_scrub_next_char. If listing,
+ call listing_source_file.
+ (s_app_line): New function to handle fake pseudo-op .appline.
+ * config/obj-coff.c (obj_pseudo_table): Make .appline call
+ obj_coff_ln.
+ (obj_coff_ln): Added argument to indicate whether .appline.
+ * config/obj-coffbfd.c (obj_pseudo_table): Make .appline call
+ obj_coff_ln.
+ (obj_coff_ln): Added argument to indicate whether .appline.
+ * config/tc-mips.c (s_file): Pass argument to s_app_file.
+
+Tue May 25 11:59:07 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-bout.h (S_GET_VALUE): Removed unnecessary cast.
+
+Thu May 20 19:14:24 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-m68k.c (md_apply_fix_2): Straighten out check for
+ invalid values.
+
+Wed May 19 07:33:17 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * config/tc-h5000.c (build_bytes): Understand @rd mode and build
+ relocations correctly.
+
+Mon May 17 15:06:26 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * Makefile.in (FLAGS_TO_PASS): Leave out TEXI2DVI for now, because
+ it's wrong.
+
+ * config/tc-m68k.c (md_apply_fix_2): Apply range checks and warn
+ if value is out of range.
+
+ Patch from Minh Tran-Le:
+ * config/tc-i386.c (i386_operand): For in/out port register used
+ as base reg, include InOutPortReg in operand type.
+ (MATCH): Accept overlap value of InOutPortReg.
+
+Mon May 17 09:29:34 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-ecoff.c (add_file, obj_ecoff_loc, obj_ecoff_stab):
+ Add calls to listing routines to produce combined source/assembler
+ listings.
+ (obj_ecoff_stab): Create a file pointer if none used yet.
+ (ecoff_frob_file): Set symcount to correct value.
+
+Fri May 14 06:53:33 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * Makefile.in (VERSION): Bump to version 2.1, in preparation for
+ release.
+
+ * config/obj-aout.h (H_GET_HEADER_SIZE, H_SET_SYMBOL_TABLE_SIZE):
+ Define in terms of constants, not C structure sizes.
+
+ * config/tc-rs6000.c, config/tc-rs6000.h: Delete empty files.
+
+Thu May 13 17:01:55 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-aout.c (obj_header_append): Don't define if it's
+ defined as a macro.
+ * config/obj-hp300.h (obj_header_append): Define it as a macro.
+ * config/obj-hp300.c (hp300_header_append): New function.
+
+ * Makefile.in (distclean): Don't bother cleaning up doc files;
+ they aren't going to be in this directory.
+
+Thu May 13 07:51:35 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-ecoff.c (ecoff_build_symbols): Handle absolute
+ symbols.
+
+ * tc.h (TC_COFF_SIZEMACHDEP): Don't define here.
+ * config/tc-sh.h (TC_COFF_SIZEMACHDEP): Define here instead.
+
+Mon May 10 06:01:12 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config/obj-vms.c (VMS_Symbol_type_list): Don't bother with
+ initialization.
+
+ * configure.in (targets): Treat m68*-*-sysv* like m68k-*-coff.
+
+Wed May 5 14:00:49 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-mips.c (macro): Correct floating point double word
+ loads and stores for big endian target.
+
+Wed May 5 08:39:21 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * config/tc-i386.c: Replace SEG_* with *_section, fix up subseg_*
+ calls. Deleted some unused code.
+ * config/obj-coff.c: Likewise.
+
+ ELF support, mostly contributed by Utah:
+ * config/obj-elf.c (obj_elf_section, obj_elf_stab, obj_elf_line,
+ obj_elf_type): Rewrite.
+ (obj_elf_frob_symbol, elf_stab_symbol_string, elf_stab_symbol,
+ obj_elf_desc, obj_elf_version, obj_symbol_new_hook, obj_elf_size):
+ New functions.
+ (obj_elf_ident): Dummy.
+ * config/obj-elf.h (FALSE, TRUE, S_*, tc_frob_symbol,
+ TARGET_SYMBOL_FIELDS): New macros.
+ (gdb_section): New variable decl.
+
+ * config/tc-i386.c (md_atof): Return zero, not empty string, on
+ success.
+
+ BFD_ASSEMBLER conditional changes:
+ * config/obj-coff.c (lineno_rootP, seg_N_TYPE, *_section_header):
+ Don't define these.
+ (SA_SET_SYM_ENDNDX, SA_SET_SYM_TAGNDX): New functions.
+ (fetch_coff_debug_section): Ditto.
+ (obj_coff_endef): Call fetch_coff_debug_section.
+ (struct line_no): New type.
+ (c_symbol_merge): New way for copying aux fields.
+ (c_dot_file_symbol): Put symbol in absolute section, and set flag
+ BSF_DEBUGGING.
+ (function_lineoff): New symbol.
+ (function_lineoff, text_lineno_number, our_lineno_number,
+ lineno_lastP): Don't define.
+ (c_line_new): Don't define.
+ (obj_emit_lineno, obj_coff_endef): Use abort calls as, uh,
+ placeholders, until
+ line-number recording gets implemented.
+ (obj_new_symbol_hook): New code for handling aux fields.
+ (add_lineno, add_linesym): New functions.
+ (obj_coff_ln): Call add_lineno, not c_line_new.
+ (obj_coff_endef): New code for handling symbol names. New lineno
+ code. Look for section name "*DEBUG*" for debugging section.
+ (align, coff_check_file_symbols, obj_coff_section,
+ coff_frob_file): New functions.
+ * config/obj-coff.h: Reordered some includes.
+ (BYTE_ORDERING, FILE_HEADER_MAGIC, seg_N_TYPE, N_TYPE_seg,
+ DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE, AOUTHDR, AOUTHDRSIZE): Don't
+ define these.
+ (TARGET_SYMBOL_FIELDS, I960_SYM_FIELDS): New macros.
+ (SYM_AUXENT): New macro (for non-BFD_ASSEMBLER too) for accessing
+ aux entries. Most SA_* macros now use it unconditionally.
+ (S_*): Use `bsym' field, and access BFD private data.
+ (SF_*): Use `sy_flags' symbol field for most of these.
+ (H_*, object_headers, lineno, lineno_*P, OBJ_EMIT_LINENO): Don't
+ define.
+ (*_section_header): Don't define.
+ * config/tc-i386.c (md_convert_frag, md_apply_fix): Changed
+ interface.
+ (tc_gen_reloc) [I386COFF]: New function.
+ (tc_aout_fix_to_chars, tc_coff_fix2rtype): Don't define.
+ * config/tc-i386.h (TARGET_ARCH, TARGET_BYTES_BIG_ENDIAN): New
+ macros.
+
+ * config/obj-coff.c (stack_init): Don't do assignments inside
+ conditions.
+ (obj_coff_def): Simplified handling of symbol name a bit.
+ (tag_insert): Name argument is now pointer to CONST.
+ (obj_crawl_symbol_chain): Commented out.
+
+ * config/obj-coff.h: Use PARAMS macro in prototypes.
+
+ * write.c (relax_and_size_seg) [BFD_ASSEMBLER]: Don't indirect
+ through frchainP pointer if it is null.
+
+ * configure.in: Warn if BFD mode is explicitly turned off but is
+ required by specified target.
+ (mips ecoff targets): Don't need to set bfd_gas here; it gets
+ taken care of later.
+
+ * config/obj-coffbfd.c (crawl_symbols): Don't clear sy_forward
+ field.
+ (yank_symbols): Merge symbols only if sy_forward is null.
+
+ * config/tc-m68k.h (AOUT_MACHTYPE): Don't define if already
+ defined.
+
+ * tc.h (md_convert_frag) [BFD_ASSEMBLER]: Section arg is not
+ pointer.
+ * config/tc-m68k.c (md_convert_frag) [BFD_ASSEMBLER]: Ditto.
+
+ * config/tc-sparc.h (LOCAL_LABEL) [OBJ_ELF]: Anything starting
+ with "." is a local label.
+
+ * config/te-hppa.h, config/tc-hppa.h, config/tc-hppa.c: New config
+ files.
+
+ * config/te-linux.h, config/te-386bsd.h: New config files.
+ * configure.in (i386-*-linux, i386-*-bsd): Use them.
+ * config/tc-i386.h (TARGET_FORMAT): Select format based on target
+ environment.
+ (DOT_LABEL_PREFIX): Don't define for 386bsd or Linux.
+
+Wed May 5 13:14:01 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-ecoff.c (init_file): Set fMerge to 0 since dbx seems
+ to want it that way.
+ (ecoff_build_symbols): Turn local st_Proc symbols into
+ st_StaticProc symbols. Set index field of external st_Proc and
+ st_staticProc symbols correctly.
+ * config/tc-mips.h (NO_LISTING): Don't define. People might want
+ listings.
+
+Tue May 4 21:22:54 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-hp300.h, config/obj-hp300.c, config/te-hp300.h: New
+ files.
+ * configure.in (m68k-*-hpux): Use them.
+
+ * config/obj-aout.c (obj_pre_write_hook): Use AOUT_VERSION if
+ defined, otherwise zero.
+
+ * config/aout_gnu.h (OMAGIC): Don't define if already defined.
+
+Mon May 3 15:59:32 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Allow any abs expression as an
+ address space number.
+
+Wed Apr 28 19:11:22 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * config/obj-aout.h (TARGET_DEFAULT): Don't default this at all.
+
+ * config/tc-a29k.c: Include ctype.h.
+ (define_some_regs): Added special-purpose registers for 29050.
+
+ * config/tc-i386.c (comment_chars) [TE_I386AIX]: Include "/".
+
+ * config/obj-coffbfd.c (fill_section): Don't set STYP_REG here.
+ (change_to_section): Set it here instead.
+
+Wed Apr 28 13:40:29 1993 Ian Lance Taylor (ian@rtl.cygnus.com)
+
+ * config/obj-ecoff.c (obj_symbol_new_hook): Make up a .file if one
+ hasn't been seen yet.
+ (add_ecoff_symbol): Don't refer to cur_file_ptr if it is NULL.
+
+Mon Apr 26 18:29:05 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/tc-sh.c, config/tc-sh.h: New files supporting Hitachi
+ SH.
+
+Mon Apr 26 12:28:27 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * expr.c (operand): Fix unary plus operator (previously was the
+ same as '~' operator!).
+
+Wed Apr 21 00:20:11 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * write.c (cvt_frag_to_fill): Define even if BFD is defined.
+ (write_object_file): Do define if BFD_ASSEMBLER. Invoke
+ obj_check_file_symbols if defined. Call verify_symbol_chain_2
+ instead of open-coding it. Fix some bugs in patching up symbol
+ chain.
+ (relax_segment): Make some code we "ought to be able to" use for
+ all targets no longer conditionalized on ns32k target; instead, do
+ it always, and if the appropriate conditions fail, abort.
+
+ * symbols.c (DEBUG): Enabled.
+ (symbol_new): Make sure bfd_make_empty_symbol works.
+ (verify_symbol_chain_2): New function; takes one symbol as
+ argument, anywhere in the chain.
+ (dollar_label*): Use default initializers.
+
+ * as.c (perform_an_assembly_pass): Call md_begin here...
+ (main): ...and not here.
+
+ * config/tc-m68k.h (TARGET_FORMAT): Use a.out-sunos-big for a.out.
+ (tc_frob_symbol): New macro: Get rid of symbols in reg_section.
+
+ * config/tc-m68k.c (omagic): Don't define for BFD_ASSEMBLER.
+ (add_fix, add_frag): Now functions instead of macros.
+ (m68k_reg_parse, m68k_ip, md_estimate_size_before_relax, get_num,
+ s_data1, s_data2, s_bss): Use new *_section names, for
+ compatibility with BFD_ASSEMBLER mode; rewrite switch statements
+ to handle non-integral segT.
+ (tc_coff_fix2rtype, tc_aout_fix_to_chars,
+ tc_coff_symbol_emit_hook): Don't define for BFD_ASSEMBLER.
+ (tc_gen_reloc): New routine for BFD_ASSEMBLER.
+ (md_apply_fix, md_apply_fix_2): Renamed old md_apply_fix to
+ md_apply_fix_2; new md_apply_fix definition varies interface
+ depending on BFD_ASSEMBLER.
+ (md_convert_frag, md_convert_frag_1): Likewise. Use new *_section
+ names.
+
+ * config/obj-vms.c: Include config.h.
+ (version_string): Delete declaration.
+ (Write_VMS_MHD_Records): Use GAS_VERSION instead.
+ (vms_resolve_symbol_redef): New function, taken from VMS code in
+ symbols.c.
+ (_doprnt): Deleted.
+ (VMS_Store_Struct, VMS_Def_Struct, VMS_Set_Struct,
+ VMS_TBT_Block_End, get_VMS_time_on_unix, generate_suffix,
+ VMS_Psect_Spec): Fixed to compile under traditional C.
+ * config/obj-vms.h: Use PARAMS macro.
+ (vms_resolve_symbol_redef): Declare.
+ (RESOLVE_SYMBOL_REDEFINITION): New macro.
+ * symbols.c (colon): Remove some VMS-specific code, look for
+ RESOLVE_SYMBOL_REDEFINITION macro instead.
+
+ * config/tc-m68k.c (m68k_ip): Don't try expanding DBcc
+ instructions.
+
+ * config/tc-i386.c: Reordered some functions so inlining might
+ work. Use PARAMS in function declarations.
+ (reloc): New routine.
+ (md_assemble): Rearrange switch statements to work with
+ non-integral segT.
+
+ * struc-symbol.h [BFD_ASSEMBLER]: Undefine
+ SYMBOLS_NEED_BACKPOINTERS before defining it.
+
+ * subsegs.c (subseg_new_rest): Now static.
+
+ * read.c (pseudo_set): Better error message for difference of
+ symbols in different frags.
+
+ * Makefile.in (check): Pass down some new variables, indicating
+ pathname or program name for cc, nm, objdump.
+
+ * as.h (OUTPUT_FLAVOR): New macro.
+ * config/tc-sparc.c (tc_gen_reloc): Use OUTPUT_FLAVOR.
+
+ * configure.in: Initialize bfd_gas properly. Warn that ELF
+ support is incomplete.
+
+Thu Apr 15 22:39:05 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * read.c (float_cons): Accept null pointer return from md_atof.
+ * config/tc-m68k.c (md_atof): Return null for success.
+ * config/tc-sparc.c (md_atof): Ditto.
+
+Thu Apr 15 16:04:39 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * doc/as.texinfo: formatting and comment cleanups; show SPARC
+ alternative options in same style as other machines; simplify some
+ conditional use; include GPL as separate file (from texinfo dir)
+
+ * doc/Makefile.in: (as.info) include directory containing GPL in
+ makeinfo search path
+
+ * doc/h8.texi: new file; conditional settings for GAS manual
+ on Hitachi chips
+
+Tue Apr 13 15:31:40 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * doc/as.texinfo: mention SPARC architecture options.
+
+Fri Apr 9 17:43:11 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * configure.in: Rearranged whitespace in per-host/per-target
+ sections. Added hooks for dropping in HPPA support (not included
+ yet). Separate out overrides of variables based on target format
+ and bfd-gas selection from actual target-specific commands. Add
+ error message for recognized but unsupported format name.
+
+Fri Apr 9 09:05:47 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-ecoff.h (ecoff_build_lineno): Make ilineMax in
+ symbolic header match cline in FDR; the native linker seems to
+ want that.
+
+Thu Apr 8 15:51:28 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * doc/Makefile.in: as.texinfo is in $(srcdir). Use
+ $(srcdir)/as.texinfo explicitly in several places
+
+Thu Apr 8 15:15:02 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * doc/Makefile.in: update dvi, clean targets for new source
+ file structure
+
+Thu Apr 8 12:52:46 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/ho-decstatn.h: Define BROKEN_ASSERT if not __GNUC__,
+ rather than undefining know.
+ * configure.in: Match ultrix*, not just ultrix.
+
+Wed Apr 7 20:18:10 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * doc/as.texinfo: converted conditional markup to use new
+ Texinfo facilities, avoiding m4.
+
+ * doc/as-all.texinfo, all.m4, pretex.m4: deleted.
+
+ * doc/Makefile.in: recast doc configuration to use a link to an
+ included texinfo file.
+
+ * doc/all.texi: settings for generic form of documentation.
+
+Tue Apr 6 11:56:21 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * read.c (cons): Zero out frag when creating reloc.
+
+Mon Apr 5 09:41:58 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-mips.c (gp_reference): Certain magic symbols can never
+ be referenced off the GP register.
+
+ * app.c (do_scrub_next_char): Handle states 9 and 10 correctly
+ when dealing with characters of type LEX_IS_TWOCHAR_COMMENT_1ST,
+ LEX_IS_STRINGQUOTE, and LEX_IS_ONECHAR_QUOTE.
+
+ * config/te-irix.h: New file; irix needs a different LOCAL_LABEL
+ definition from other MIPS targets.
+ * configure.in (mips-*-irix): Use emulation irix.
+
+Sun Apr 4 15:21:09 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/tc-h8500.c: Get relax size of branch instructions right,
+ (get_operand): Parse @sp+ correctly.
+
+Fri Apr 2 15:59:49 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * subsegs.h (segment_info_type) [BFD_ASSEMBLER]: Don't include
+ COFF section header field.
+
+ * configure.in: Print error message if host or target is not
+ supported.
+
+ * configure.in: If with-bfd-assembler, use obj-coff instead of
+ obj-coffbfd.
+
+ * config/ho-generic.h: Include string.h.
+
+Fri Apr 2 08:54:57 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-mips.h (LOCAL_LABEL): Treat any label starting with
+ '$' as local, for any object file format.
+
+ * config/tc-mips.c (macro): Optimizations to branching code and a
+ couple of bug fixes from ralphc@pyrps5.eng.pyramid.com (Ralph
+ Campbell).
+
+ * config/ho-irix.h: New file; if not gcc, define BROKEN_ASSERT.
+ * configure.in (mips-sgi-irix*): Set gas_host to irix.
+
+Wed Mar 31 17:53:54 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * subsegs.c (subseg_new): Set output_section of new section.
+ * as.c (perform_an_assemly_pass): Don't set output_section here.
+ * expr.c (expr_part, expr): Turn off section assertions for ECOFF,
+ since it has additional sections.
+ * read.c (s_lcomm): For MIPS ECOFF, put small objects in .sbss,
+ not bss_section.
+ * config/obj-ecoff.h (TARGET_SYMBOL_FIELDS): Added
+ ecoff_undefined field.
+ * config/obj-ecoff.c (obj_symbol_new_hook): Initialize
+ ecoff_undefined field.
+ (add_file): If using stabs, just output a stabs symbol rather than
+ creating a new fdr.
+ (obj_ecoff_begin, obj_ecoff_bend): Ignore line number by reading
+ it with get_absolute_expression, rather than skipping it by hand.
+ (obj_ecoff_loc): If using stabs, just output a stabs symbol rather
+ than ECOFF line number information.
+ (obj_ecoff_stab): Accept non-zero values for stabs line number.
+ (ecoff_build_symbols): Set ifilesym correctly. Set storage class
+ to small, undefined and/or readonly sections if appropriate.
+ Don't output symbol names containing \001 characters.
+ (ecoff_frob_file): Make sure at least one fdr is output.
+ * config/tc-mips.h: Define TC_MIPS.
+ * config/tc-mips.c (g_switch_value): New static variable.
+ (md_assemble): Set gp size of output BFD.
+ (gp_reference): New function; returns 1 if expression can be
+ accesssed via gp. Always returns 0 if not using ECOFF.
+ (macro_build): Convert BFD_RELOC_LO16 to BFD_RELOC_MIPS_GPREL if
+ possible.
+ (macro): Generate sequences using gp if possible.
+ (md_parse_option): Ignore -EL and -EB. Parse -G.
+ (md_apply_fix): Added BFD_RELOC_MIPS_GPREL to ignored case.
+ (s_change_sec): Handle .rdata and .sdata for ECOFF.
+ (s_extern): Mark symbol as external. Set ecoff_undefined field.
+
+Tue Mar 30 10:11:41 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * output-file.c (output_file_create): Don't call as_perror for
+ filename rejected by application.
+
+ * as.c (main) [BFD_ASSEMBLER]: If errors occur, close and unlink
+ the output file.
+
+ * doc/as.texinfo: Don't use @value in node names for the moment;
+ references don't appear to work right.
+
+ * as.h (const, volatile): Put these definitions back, and use
+ them.
+
+ * doc/as.texinfo: First pass at using new texinfo features --
+ variables, conditional tests. Far from complete.
+
+Mon Mar 29 16:05:40 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * read.c: Temporary hack to handle some 64-bit constants. This
+ should be redone later.
+ (target_big_endian): Declare.
+ (big_cons): If it's set, reverse order of bytes being copied.
+ * config/tc-sparc.c (md_begin): Set target_big_endian.
+
+ * read.c (s_ignore): Delete declaration of is_end_of_line.
+
+ * config/obj-coffbfd.c (yank_symbols): Build list of file symbol
+ forward pointers properly.
+
+Mon Mar 29 13:47:33 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/obj-coffbfd.c (do_relocs_for): Fix bug where nrelocs
+ wasn't being stored into scnhdr.
+ * config/obj-coffbfd.h: Add prototype of s_get_segment.
+ * read.c (TC_START_LABEL): Default definition.
+ (read_a_source_file): Use TC_START_LABEL macro to work out
+ if a label has been seen.
+
+Mon Mar 29 12:56:56 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in: Set BFDDEF and BFDLIB at the top of Makefile, not
+ the bottom (make expands variables in dependencies when the
+ dependencies are read, not when they are used).
+
+ * config/obj-coffbfd.c (fill_section): Don't set NOLOAD bit for
+ a29k .bss section; the mondfe program doesn't like it.
+
+Sun Mar 28 08:12:53 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config/tc-m68k.c: Use PARAMS macro, and use CONST instead of
+ const.
+ (current_architecture): Don't need initializer.
+
+Fri Mar 26 08:12:48 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * doc/none.m4: Define Z8000.
+ * doc/Makefile.in (as-*.texinfo): Refer to $(srcdir). Remove the
+ texinfo file before recreating it.
+ (TEXI2DVI): Need to set TEXINPUTS if "make as.dvi" is to work in
+ this directory.
+ (srcdir): Delete second, bogus definition.
+ (as.info): Look for as-*.texinfo in current directory rather than
+ in $(srcdir).
+ (as.dvi): Ditto.
+ (dvi): New rule.
+ * doc/configure.in: Create links to all as-*.texinfo files in the
+ source directory, if that's not the current directory.
+
+ * configure.in (per-host): Accept MIPS host with BSD version
+ number.
+ (per-target): Classify i486 as i386. Use generic cpu_type instead
+ of target_cpu in selecting format etc.
+
+ * app.c (do_scrub_next_char): Use .appfile, not .app-file.
+ * read.c (potable): Change .app-file to .appfile.
+
+ * config/ho-decstatn.h: Renamed from ho-decstation.h.
+ * configure.in: Adjusted.
+
+ * config/obj-bfd-sunos.*: Unused; deleted.
+
+ * Makefile.in (version.c, vers-stamp): Deleted.
+ (config.h): Define GAS_VERSION.
+ * as.c (version_string): Deleted declaration.
+ (main): Look for GAS_VERSION instead.
+
+ * doc/as.texinfo: Updated description of -a* (listing) options,
+ and describe how to pass them through from gcc.
+
+ * config/obj-coffbfd.c (do_relocs_for): Don't allocate storage or
+ process relocs if there aren't any relocs to process. Avoids
+ malloc/free bug on SCO too.
+
+ * as.h: Move local include files below system include files, to
+ avoid some redefinition complaints on some systems.
+ (const, volatile): Don't need these conditionally defined if we
+ use CONST and VOLATILE from ansidecl.h.
+ (seg_name): Use CONST, not const.
+
+Fri Mar 26 10:22:04 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-mips.c: Reindented to GNU standards.
+
+Thu Mar 25 08:59:14 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-coffbfd.c (do_relocs_for): Remove a29k special case.
+ (fixup_segment): Add a29k special case; the linker is not prepared
+ to see a segment offset here.
+
+ * app.c (do_scrub_next_char): Added new state, 10, modifying state
+ 9 to only keep a space in between identifier characters.
+
+Wed Mar 24 02:16:22 1993 david d `zoo' zuhn (zoo at poseidon.cygnus.com)
+
+ * Makefile.in: add dvi target; as-$(config).texinfo might live in
+ srcdir, might be in objdir.
+
+ * doc/Makefile.in: dvi depends on as.dvi
+
+Mon Mar 22 23:59:13 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: add installcheck target
+
+Mon Mar 22 16:25:57 1993 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Add support for membar mask names.
+ Add missing colons in prefetch error messages. Add support for
+ ASI names.
+
+Mon Mar 22 10:19:00 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-mips.c (macro): Use $AT for any floating point load.
+
+Sat Mar 20 12:50:51 1993 Ken Raeburn (raeburn@urth.cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip): For operand type 'M', reject
+ bignums, but don't emit error message.
+
+Fri Mar 19 21:02:19 1993 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * Makefile.in (targ-cpu.o): Depend on config.h.
+
+Wed Mar 17 16:44:06 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * app.c (do_scrub_next_char): Added new state, 9, to avoid
+ dropping a space immediately following an identifier.
+ * expr.c, write.c: Rewrote assert expressions to not use multiple
+ lines; I don't think that can be done portably.
+ * config/tc-mips.c (macro): Use $AT if target register is zero in
+ load instruction, which it can be for a floating point load.
+
+Mon Mar 15 12:17:28 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * write.c (write_contents): Compute the relocs before writing out
+ the section contents.
+ * config/obj-ecoff.h, config/obj-ecoff.c: Numerous changes to get
+ symbol table and values right.
+ * config/tc-mips.h (LOCAL_LABEL): If OBJ_ECOFF, any label starting
+ with $L is local.
+ * config/tc-mips.c (tc_gen_reloc): If OBJ_ECOFF, adjust the addend
+ by the section vma.
+
+ * config/z8k.mt (TARG_CPU_DEPENDENTS): The relevant file is
+ z8k-opc.h, not z8k.h.
+
+ * config/obj-coffbfd.c (obj_coff_endef): Correct test for .bf
+ symbol.
+
+Fri Mar 12 18:33:36 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: recognize sparc-sun-solaris2* instead of -solaris2
+
+Fri Mar 12 12:00:07 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * expr.c, write.c: Ultrix native 4.2 cc requires assert condition
+ to be on a single line.
+
+Thu Mar 11 17:56:22 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (config.h): Create file, writing out definitions of
+ target cpu, alias, and canonical name.
+ (ALL_CFLAGS): No longer define TARGET_CPU.
+
+ * Makefile.in (check): Print a message, instead of quitting
+ silently.
+
+ * as.c (main): Don't catch any signals, for now.
+
+ * version.c: Deleted.
+ * Makefile.in: Generate it, putting in only the version number
+ itself.
+ (VERSION): New variable.
+ * as.c: Include config.h.
+ (main): Reformatted version string. Include target alias. Don't
+ print if not requested (i.e., unknown -v argument).
+
+ * as.c (stralloc): Deleted.
+ (main): Call strdup instead.
+
+ * configure.in: Handle all 68300 series chips.
+ * config/tc-m68k.c: Include config.h.
+ (md_assemble): Assume TARGET_CPU is defined. Accept some 68300
+ series cpus as defaults.
+ (md_parse_option): Accept some m68300 series CPUs as defaults.
+
+Wed Mar 10 17:41:16 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * as.c (EXIT_SUCCESS, EXIT_FAILURE): Define to normal values if
+ not already defined.
+ (main, got_sig): Use them.
+ * config/ho-vms.h (EXIT_SUCCESS, EXIT_FAILURE): Reverse default
+ values.
+
+Tue Mar 9 07:40:06 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-ecoff.c, config/obj-ecoff.h: Preliminary ECOFF
+ support.
+
+ * config/tc-mips.h (TARGET_FORMAT): Define based on OBJ_AOUT vs.
+ OBJ_ECOFF as well as TARGET_BYTES_*_ENDIAN.
+ (struct loc, struct proc, struct file): Moved to tc-mips.c within
+ #ifndef OBJ_ECOFF block, since ECOFF uses different versions.
+ * config/tc-mips.c: Rearranged for ECOFF support. Added
+ prototypes for all static functions. Moved existing minimal
+ debugging format support info #ifndef OBJ_ECOFF blocks.
+ (macro_build_lui): Eliminated sign_extend argument, because ECOFF
+ does not support a non sign extended high 16 bits reloc. Adjusted
+ all callers accordingly.
+ (tc_get_register): Renamed from get_register, and made non-static.
+
+ * config/mips-big.mt, config/mips-lit.mt: New files. Define
+ TARGET_BYTES_BIG_ENDIAN and TARGET_BYTES_LITTLE_ENDIAN,
+ respectively.
+ * configure.in (mips-*-bsd*): Use gas_target mips-lit.
+ (mips-*-ultrix*, mips-*-irix*, mips-*-ecoff): New targets, using
+ obj_format ecoff and gas_target mips-lit or mips-big.
+
+Tue Mar 9 07:43:01 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * version.c: Bump to version 2.0.1.
+
+Tue Mar 9 07:40:06 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * write.c (chain_frchains_together): Check that seg_info (section)
+ is not NULL.
+ (write_object_file): Call obj_frob_file after setting the symbols,
+ not before.
+
+Tue Mar 9 00:00:00 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * Version 2.0 released.
+
+Mon Mar 8 14:57:10 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-i386.h (TC_COUNT_RELOC): Look for fx_addsy only.
+
+Fri Mar 5 09:05:55 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * read.h: Define stringer here.
+ * read.c, config/obj-ieee.c, config/obj-tcm88k.c: Not any of these
+ places.
+
+Thu Mar 4 11:52:23 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * read.c (s_space): Multiply repeat count by mult, not fill.
+
+Thu Mar 4 05:20:42 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * read.c: Include ctype.h.
+
+Wed Mar 3 10:41:46 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ Patches from Eric Youngdale:
+ * make-gas.com: Find obstack.obj if it's not in the current
+ directory.
+ * read.c (s_ignore): Don't declare is_end_of_line. It's
+ redundant, and triggers a VMS gcc compiler bug.
+
+ * write.c (write_object_file): Macro SUB_SEGMENT_ALIGN now takes
+ current segment as an argument. (Ignored in all cases but VMS.)
+ All callers and definitions changed.
+
+Tue Mar 2 11:56:19 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * listing.c: Cleaned up a bit, added prototypes, made NO_LISTING
+ case compile again.
+
+Tue Mar 2 08:53:34 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/tc-m68k.c (isbyte): Accept all values from -255 to +255,
+ so "~0x80" won't be rejected.
+
+ * config/obj-elf.c: No longer include elf/reloc.h.
+ (obj_elf_section): Set SEC_READONLY and SEC_CODE for text section.
+ (obj_elf_stab, obj_elf_desc): Deleted do-nothing and commented-out
+ routines.
+ (obj_elf_xstab): New routine.
+ (obj_elf_set_size): Call as_warn, not fprintf. Pass desired
+ argument to s_ignore. Put "#if 0" around unused code.
+ (obj_pseudo_table): Use s_ignore instead of do-nothing routines.
+ Call elf_xstabs for .stabs and .xstabs operators.
+
+ * config/tc-sparc.h (TARGET_FORMAT) [OBJ_ELF]: Now "elf32-sparc".
+
+ * write.c (relax_and_size_seg): Set SEC_RELOC only if fixups are
+ present.
+
+ * configure.in: mips-bsd configuration was missing format spec.
+ Should use aout.
+
+ * Makefile.in (Makefile): Depends on configure.in.
+
+ * config/tc-mips.c (append_insn): Don't check for alignment of
+ frag in memory; alignment of instructions in section is a separate
+ matter.
+
+ * config/tc-mips.c (macro_build_lui): Fix some assumptions of ANSI
+ C availability.
+
+ * listing.h: Always provide function declarations, not macros, so
+ pcc won't lose.
+
+Tue Mar 2 00:50:43 1993 John Gilmore (gnu@cygnus.com)
+
+ * CONTRIBUTORS: Update Gilmore entry.
+
+Mon Mar 1 12:03:16 1993 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Correctly assemble prefetch
+ instructions. Accept integer prefetch function numbers.
+
+Wed Feb 24 14:58:19 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (s_xword): Now call big_cons, so large
+ constants are accepted, but symbolic values are not. GCC will not
+ generate the latter currently.
+
+ * frags.c (frag_init): New function.
+ (zero_address_frag, bss_address_frag): Now initialized at run
+ time.
+ * as.c (main): Call frag_init.
+
+Wed Feb 24 10:32:42 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * app.c (do_scrub_next_char): In LEX_IS_LINE_COMMENT_START case:
+ Don't unget ch2 if we didn't get it.
+
+Wed Feb 24 04:14:07 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * doc/Makefile.in (TEXIDIR): Updated for new layout.
+
+ * config/tc-sparc.c (s_common): Add support for ELF version.
+ (tc_gen_reloc) [BFD_ASSEMBLER]: New function.
+ * config/tc-sparc.h (TARGET_ARCH, TARGET_FORMAT) [BFD_ASSEMBLER]:
+ New macros.
+ (md_convert_frag): New macro.
+
+ * config/tc-m68k.c (m68k_ip): For PC-relative addressing of a
+ symbol, fix the offset so "+2" isn't required.
+
+ * config/tc-i960.c (line_comment_chars, line_separator_chars):
+ Define as common/bss.
+ (op_hash, reg_hash, areg_hash, iclasses_seen, br_cnt): Default C
+ initializers are sufficient.
+
+ * config/obj-aout.h [BFD_ASSEMBLER]: Include libaout.h from bfd.
+ (TARGET_FORMAT) [BFD_ASSEMBLER]: Default to "a.out".
+ (S_SET_*, S_GET_*, obj_frob_symbol) [BFD_ASSEMBLER]: New macros.
+ (S_SET_TYPE) [!BFD_ASSEMBLER]: New macro.
+ * config/obj-aout.c: Use PARAMS macro for declarations. Remove
+ "IGNORE_DEBUG" conditional, since both branches are identical.
+ Use S_SET_TYPE, S_GET_TYPE, and S_GET_DESC instead of directly
+ referencing symbol structure members.
+ (obj_aout_frob_symbol) [BFD_ASSEMBLER]: New function.
+
+ * as.h (struct frag): Reordered a couple of fields for better
+ packing.
+
+ * write.c (record_alignment) [BFD_ASSEMBLER]: Record it in the
+ section info.
+ (write_contents) [BFD_ASSEMBLER]: New function.
+ (write_object_file) [BFD_ASSEMBLER]: Always handle -R here. Call
+ fix_new with BFD_RELOC_NONE instead of 0 or NO_RELOC. Call
+ obj_frob_file, obj_frob_symbol, tc_frob_symbol if defined.
+ (fixup_segment): Make sure common-section symbols get treated the
+ same as undefined symbols.
+ (fix_new) [BFD_ASSEMBLER]: Argument r_type is of type
+ bfd_reloc_code_real_type. Use seg_fix_{root,tail}P derived from
+ section info.
+ * write.h (fix_new): Update prototype.
+
+ * tc.h (md_operand, md_convert_frag, tc_headers_hook,
+ md_section_align, md_undefined_symbol): Don't provide prototypes
+ if these are defined as macros.
+ (md_convert_frag) [BFD_ASSEMBLER]: BFD version needs bfd and
+ section passed.
+
+ * symbols.c (symbol_new): Argument NAME is now pointer to const.
+ Simplified STRIP_UNDERSCORE code. Remove assumptions about null
+ pointers in freshly allocated storage. [BFD_ASSEMBLER]: Get new
+ BFD symbol.
+ (colon): Display other/desc fields of redefined symbol only if
+ S_GET_OTHER and S_GET_DESC are defined.
+ (symbol_make): Argument NAME is now pointer to const.
+ (symbol_find, symbol_find_base): Likewise.
+ (S_IS_*, S_GET_*, S_SET_*) [BFD_ASSEMBLER]: New functions.
+ * symbols.h: Fix prototypes for new const arguments. Add
+ prototypes for BFD_ASSEMBLER S_* functions.
+
+ * subsegs.c (subseg_change) [BFD_ASSEMBLER]: BFD version of code
+ for changing to an existing section.
+ (subseg_new_rest) [BFD_ASSEMBLER]: Split off from subseg_new,
+ called by subseg_new and subseg_set.
+ (subseg_new) [BFD_ASSEMBLER]: Rewritten to change to new section,
+ given section name and subseg number.
+ (subseg_set) [BFD_ASSEMBLER]: New function; change to a possibly
+ new section/subsection.
+
+ * read.c: Don't include ctype.h.
+ (cons) [BFD_ASSEMBLER]: For undefined symbols, use BFD_RELOC_32
+ for now; should be machine-dependent.
+
+ * configure.in: Accept *-*-elf and *-*-solaris* as ELF format
+ targets, forcing BFD use.
+
+Wed Feb 17 18:59:03 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c: Use PARAMS macro for static function
+ declarations. Use BFD_RELOC_ macros everywhere, with
+ compatibility macros declared for non-BFD mode.
+ (struct sparc_it) [BFD_ASSEMBLER]: Use bfd_reloc_code_real_type
+ instead of enum reloc_type.
+ (emit_sparc_reloc): Commented-out function deleted.
+ (md_convert_frag): Deleted.
+ (tc_aout_pre_write_hook): Don't define for BFD_ASSEMBLER.
+ (md_apply_fix): Changed calling sequence (conditionally) for BFD
+ version.
+ * config/tc-sparc.h (md_convert_frag): New macro.
+
+ * config/obj-aout.c (obj_aout_stab): Refer to undefined_section,
+ not SEG_UNKNOWN. Use S_SET_TYPE, S_GET_TYPE, S_GET_DESC instead
+ of referencing fields directly.
+
+ * write.c (cvt_frag_to_fill): New function; extracted from
+ write_object_file.
+ (write_object_file) [! BFD_ASSEMBLER]: Call it.
+ (relax_and_size_seg) [BFD_ASSEMBLER]: New function; relax section
+ and set its size and flags.
+
+ * struc-symbol.h (struct symbol) [BFD_ASSEMBLER]: Replace some
+ fields with BFD equivalents. Turn on back-pointers, and add
+ target-specific fields at end.
+
+Thu Feb 11 09:20:37 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-coffbfd.c (fill_section): Don't set vaddr here.
+ (write_object_file): Set it here instead, so that fixup_segment
+ can see the correct value.
+
+Mon Feb 8 13:56:17 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * write.c (write_object_file): Check for errors and warnings and
+ bail out before processing contents.
+ (chain_frchains_together_1): New function, does most of the work
+ of remove_subsegs.
+ (chain_frchains_together) [BFD_ASSEMBLER]: New function.
+ (remove_subsegs) [! BFD]: Call it.
+ (write_object_file) [BFD_ASSEMBLER]: Converted to use BFD
+ structures and routines.
+
+ * config/obj-elf.*: New files.
+
+ * config/mips.mt, config/rs6000.mt: Deleted.
+
+ * config/h8300.mt: Don't specify compiler here.
+
+ * config/z8k.mt: The z8k code depends on the z8k opcode table,
+ not the h8300 one.
+ * config/tc-z8k.h: Comment fix.
+
+ * write.c: Reordered some functions for better inlining.
+ (fixup_segment): Linkrelax code is no longer conditional on
+ TC_I960.
+
+Thu Feb 4 12:45:16 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/{h8500.mt, config/tc-h8500.c, config/tc-h8500.h,
+ config/obj-coffbfd.c, obj-coffbfd.h}: support for the H8/500.
+
+Wed Feb 3 19:28:18 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-vms.h (SUB_SEGMENT_ALIGN): Define VMS version here.
+ * write.c (write_object_file): Not here.
+ (fix_new): Initialize fx_addnumber.
+
+ * listing.c: Don't include target-cpu.h explicitly, since as.h
+ includes it.
+
+Thu Jan 28 00:35:40 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * write.h [BFD_ASSEMBLER]: Don't declare next_object_file_charP,
+ *_fix_root, *_fix_tail, seg_fix_rootP, seg_fix_tailP.
+ (struct fix): Reordered fields for compactness and efficiency.
+ Converted some logical fields to 1-bit fields.
+
+ * config/obj-aout.h: Use PARAMS.
+ [BFD_ASSEMBLER]: Don't define/declare AOUT_MACHTYPE, seg_N_TYPE,
+ N_TYPE_seg, DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE.
+
+ * read.c: Don't include listing.h; as.h includes it. Removed
+ DONTDEF code.
+ [BFD_ASSEMBLER]: Include subsegs.h.
+ (old_buffer, new_broken_words): Default initialization is
+ sufficient.
+
+ * output-file.c [BFD_ASSEMBLER]: Include bfd.h, default TARGET_MACH
+ to 0, define stdoutput.
+ (output_file_create) [BFD_ASSEMBLER]: Call bfd_perror on failure.
+ Call bfd_set_arch_mach.
+ (output_file_close) [BFD_ASSEMBLER]: Call bfd_close, not
+ bfd_close_all_done. Call bfd_perror on failure.
+ (output_file_append) [BFD_ASSEMBLER]: Don't define.
+
+ * config/m68kcoff.mt (LOCAL_LOADLIBES): Delete definition.
+
+ * subsegs.h (segment_info_type): Always define. Omit field scnhdr
+ if not MANY_SEGMENTS. Define new field bfd_section if
+ BFD_ASSEMBLER.
+ (seg_info): New macro.
+
+ * expr.c, input-scrub.c: Use PARAMS macro. Deleted unused
+ variables, and some irrelevant comments.
+
+ * Makefile.in (ALL_CFLAGS): Include $(BFDDEF).
+ (LIBS): Include $(BFDLIB). Don't bother with $(CLIB).
+ * configure.in: Permit --with-bfd-assembler now, with a warning.
+ Variable need_bfd is now a boolean, as is new variable bfd_gas.
+ Set BFDDEF and BFDLIB in Makefile when appropriate.
+
+ * as.c: Removed "#ifdef DONTDEF" and "#ifdef comment" code.
+ (main): Refer to flag_always_generate_output instead of
+ flagseen['Z'].
+
+ * as.c (main) [BFD_ASSEMBLER]: Open output bfd.
+ (*_section) [BFD_ASSEMBLER]: Define them.
+ (perform_an_assembly_pass) [BFD_ASSEMBLER]: Initialize them, and
+ set section flags when appropriate.
+ * as.h (SEG_NORMAL) [BFD_ASSEMBLER]: Require that the specified
+ section is not absolute, undefined, or an assembler internal one.
+ (absolute_section, undefined_section): Always define.
+ * expr.c, read.c, symbols.c: Refer to *_section, not SEG_*; break
+ switch statements into if-else trees.
+ * symbols.c [MANY_SEGMENTS]: Deleted redundant definitions of
+ SEG_BSS and SEG_DATA.
+
+ * as.h (frag_now_fix): New macro.
+ * symbols.c (colon): Use it.
+
+Wed Jan 27 21:43:53 PST 1993 Ralph Campbell (ralphc@pyramid.com)
+
+ * config/tc-mips.c: Added mips support for mips-dec-bsd.
+ * config/tc-mips.h: Added mips support for mips-dec-bsd.
+ * config/ho-mipsbsd.h: Added mips support for mips-dec-bsd.
+ * config/mips-opcode.h: Added mips support for mips-dec-bsd.
+ * configure.in: Added mips support for mips-dec-bsd.
+ * atof-generic.c: Define TRUE and FALSE if not defined.
+
+Thu Jan 21 12:48:19 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * version.c: Bumped version number to 1.93.05.
+
+Wed Jan 20 17:11:53 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-coff.c (obj_emit_relocations): Don't use #elif.
+ (obj_emit_lineno): Don't need return at end of void function.
+ (obj_symbol_new_hook): Ditto.
+
+ * config/tc-m68k.c: Removed some unused code.
+ (tc_aout_fix_to_chars): Array nbytes_r_length is now const.
+
+ * config/tc-m68k.h (TC_COUNT_RELOC): Don't emit reloc if only
+ offset field is set.
+
+Fri Jan 8 05:44:49 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): For %uhi and %ulo, if not
+ ENV64, emit no reloc.
+ (md_pseudo_table): For ".xword", call s_xword.
+ (s_xword): New function.
+
+ * config/tc-sparc.c (architecture_requested, warn_on_bump,
+ md_relax_table): Use default zero initialization.
+ (s_reserve): Since SEG_E2 is equivalent to SEG_BSS, just use the
+ latter, instead of selecting with preprocessor conditionals.
+
+Thu Jan 7 08:58:21 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: recognise all sparclite variants
+
+Thu Jan 7 05:25:25 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * read.c (s_data) [!BFD_ASSEMBLER]: Fix typo in 4 Jan change --
+ accidentally changed to use subseg_change where it should have
+ been subseg_new.
+
+Tue Jan 5 08:42:16 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * expr.c (operand): If character other than comma or newline is a
+ logical end-of-line character, use the newline case.
+ From Eric Youngdale:
+ (operand): Set X_add_number field for floating-point numbers.
+ (operand): Treat zero byte as end-of-operand.
+
+ * configure.in (per-target): Look for with_bfd_assembler option.
+ For now, only accept "no", until the merge is done.
+
+ Merged changes from Eric Youngdale (youngdale@v6550c.nrl.navy.mil):
+ * as.c, flonum-konst.c, hex-value.c, input-file.c, version.c,
+ config/obj-aout.h, config/obj-vms.c: VMS -> HO_VMS.
+ * read.c: Finish conversion to S_* macros in the VMS only
+ parts of the program. Add "const" modifier to hex_value.
+ * as.c, read.c, symbols.c, write.c: Change "ifdef VMS" to
+ "ifdef OBJ_VMS".
+ * expr.c: Add "const" modifier to hex_value.
+ * symbols.c: Finish conversion to S_* macros in the VMS only
+ parts of the program. Add "const" modifier to
+ md_[long,short]_jump_size. Remove declaration of const_flag
+ (which will be declared in obj-vms.h).
+ * write.c: Add "const" modifier to md_[long,short]_jump_size.
+ Fix arguments to VMS_write_object_file.
+ * config-gas.com: New file. Script for VMS systems to set up the
+ configuration to build gas for VMS, and create config.status.
+ * make-gas.com: Redone to work with new scheme.
+ * config/obj-vms.c: Patch to fix bug where we were not correctly parsing the
+ stabs directives.
+ * config/obj-vms.c: Define macros COPY_LONG and COPY_SHORT which
+ will swap bytes if needed on a big endian system. Use throughout
+ as needed.
+ * config/obj-vms.c (obj_aout_stab): Add code to generate listing file.
+ * config/obj-vms.c (VMS_typedef_parse): Add alias to correctly handle certain
+ types of malformed stabs. Change parsing algorithm so that we are
+ more certain of having all of the information that we need on hand.
+ * config/obj-vms.c (final_forward_reference): New function, used to help
+ resolve the data types of as many struct elements as possible
+ when some part of the struct is not fully defined by the compiler.
+ * config/obj-vms.c (VMS_LSYM_Parse): Correctly handle case of continuation
+ stabs directives.
+ * config/obj-vms.c (VMS_write_object_file): Define all vtable psects
+ as symbols as well in the object file. Look for external functions
+ that start with "__vt.", and turn them into variables, since the
+ g++ compiler is incapable of doing this.
+ * config/tc-vax.c: Add '1' option for backward compatibility with older GCC
+ versions.
+ * bignum-copy.c (bignum_copy): Fix bug where we pad with zeroes.
+ * input-scrub.c (as_where): Fix bug where as would crash if we did not
+ have the name of the source file yet.
+ * config/ho-vms.h: define HO_VMS, not HO_VAX.
+
+Mon Jan 4 05:17:26 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * read.c (s_data): Always use "data_section", since it'll map to
+ SEG_DATA or SEG_E1 if needed.
+ (s_lcomm): Likewise with bss_section.
+ (s_fill): Use memset, not bzero.
+
+Thu Dec 31 04:29:27 1992 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * read.c: Deleted some code under "#ifdef DONTDEF" that was for
+ handling GDB symbol table data.
+
+ * config/obj-aout.h (segment_name): Delete definition.
+ (seg_name): Delete declaration.
+ * config/obj-bout.h (segment_name, seg_name): Ditto.
+ * config/obj-vms.h (segment_name, seg_name): Ditto.
+ * config/obj-coff.h (segment_name): Ditto.
+ * config/obj-coffbfd.h (segment_name): Ditto.
+
+ * Changes for BFD_ASSEMBLER:
+ * obj.h (obj_crawl_symbol_chain): Declare only if not
+ BFD_ASSEMBLER.
+ (obj_header_append, obj_pre_write_hook): Ditto.
+ * as.h (stdoutput): New var, defined only if BFD_ASSEMBLER.
+ (segT) [BFD_ASSEMBLER]: New typedef for "asection *".
+ (segment_name) If BFD_ASSEMBLER, look up BFD section name;
+ otherwise, use seg_name array.
+ (seg_name): Declare only if not BFD_ASSEMBLER.
+ (section_alignment): Declare only if not BFD_ASSEMBLER.
+ (big_section, reg_section, pass1_section, diff_section,
+ absent_section, text_section, data_section, bss_section): If
+ BFD_ASSEMBLER, declare as variables; otherwise, declare as macros,
+ mapping to segT enum values.
+ (tc_aout_fix_to_chars, next_object_file_charP): Force parse errors
+ if these are used or defined, if BFD_ASSEMBLER.
+ (subseg_set, subseg_new) [BFD_ASSEMBLER]: Functionality of old
+ subseg_new split into two functions.
+ (SEG_NORMAL): For BFD_ASSEMBLER, always return true, for now.
+
+ * as.h (volatile): Don't define if already defined.
+ (had_errors, had_warnings): Provide prototypes for ANSI C even if
+ NO_STDARG.
+ (as_bad, as_fatal, as_tsktsk, as_warn): For GNU C version 2,
+ declare with format attribute for -Wformat checking.
+
+Wed Dec 30 10:18:57 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * app.c, config/tc-*.c: Don't include read.h, since it is already
+ included by as.h.
+
+ * These are based on patches from Minh Tran-le
+ <mtranle@paris.intellicorp.com>.
+ * configure.in (i[34]86-ibm-aix*): Accept i486 for host. Use
+ obj_format coffbfd and gas_target i386coff for target.
+ (i[34]86-*-isc*): New host (uses sysv).
+ * config/i386aix.mt: Removed (no longer used).
+ * config/mh-i386aix (RANLIB): Use true rather than /bin/true.
+ (MINUS_G): Removed.
+ (LDFLAGS): Added, defined as -shlib.
+ * config/te-i386aix.h (REVERSE_SORT_RELOCS): Undefine.
+ * config/te-sco386.h (LOCAL_LABEL): Don't define.
+ (DOT_LABEL_PREFIX): Define.
+ * expr.c (operand): If DOT_LABEL_PREFIX, use .L0\001 as a label
+ name rather than L0\001.
+ * read.c (s_lcomm): Make a frag in SEG_BSS rather than using
+ local_bss_counter.
+ * symbols.c, symbols.h (local_bss_counter): Removed.
+ * write.c (write_object_file): bss no longer uses
+ local_bss_counter. Pass correct data and bss size to
+ VMS_write_object_file.
+ * config/obj-vms.c (VMS_write_object_file): Accept bss size as
+ argument, rather than using local_bss_counter.
+ * config/tc-m88k.c (s_bss): Don't use local_bss_counter.
+ * config/tc-sparc.c (s_reserve): Don't use local_bss_counter.
+ * config/obj-coffbfd.c (had_lineno, had_reloc): Removed.
+ (size_section): Restored sanity check.
+ (do_relocs_for): Base section address on s_paddr rather than
+ computing it. Adjust a29k R_IHIHALF special case to account for
+ section paddr (used to require paddr to be zero). If there are no
+ reclos, set s_relptr to 0. Set relocation size in object_headers.
+ (fill_section): Always set s_vaddr here, removing
+ ZERO_BASED_SEGMENTS case. Force s_scnptr for bss to 0. Don't set
+ NOLOAD for i386 .bss, because it confuses the SVR3 native linker.
+ Set STYP_INFO for .comment.
+ (coff_header_append): Use object headers and H_{SET,GET}_* macros.
+ Make aouthdr writing depend on OBJ_COFF_OMIT_OPTIONAL_HEADER.
+ (crawl_symbols): Handle 8 character section name correctly. Use
+ H_{SET,GET}_* macros.
+ (do_linenos_for): Set lineno size in object_headers.
+ (write_object_file): Use H_{SET,GET}_* macros. Don't bother to
+ set s_vaddr here. If string_byte_count remains 4, set it back to
+ 0, and only write strings out if there are some. Call
+ fill_section before do_relocs_for and do_linenos_for.
+ (obj_coff_section): Handle optional quoted second argument giving
+ section characteristics.
+ (obj_coff_bss): Added to handle .bss.
+ (obj_coff_ident): Added to handle .ident (puts string in .comment
+ section).
+ (obj_coff_lcomm): Put common symbols in .bss, not .data.
+ (fixup_mdeps): Change to segment. Call frag_wane after
+ md_convert_frag.
+ (fixup_segment): Explicitly check S_IS_COMMON before making 386
+ adjustment (already happened only for common symbols, but this is
+ clearer).
+ * config/obj-coffbfd.h (OBJ_COFF_OMIT_OPTIONAL_HEADER): Define.
+ * config/tc-i386.c (s_bss): Don't use if I386COFF.
+ (md_pseudo_table): Ignore .optim and .noopt.
+ (tc_coff_sizemachdep): New function.
+ * config/tc-i386.h (REVERSE_SORT_RELOCS): Undef, for SVR3
+ compatibility.
+ (LOCAL_LABEL): Removed definition.
+ (DOT_LABEL_PREFIX): Defined.
+
+Mon Dec 28 10:32:05 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * app.c (app_push): Use memcpy, not bcopy.
+ (do_scrub_next_char): For \", return " not '.
+ (symbol_chars): Now const.
+
+ * expr.c (operand): If not LOCAL_LABELS_FB, don't look for "0f"
+ and "0b". If LOCAL_LABELS_DOLLAR, check for "0$".
+
+ * config/obj-coff.h: Don't use #elif.
+
+ * config/ho-sunos.h: Don't include sys/stdtypes.h; 4.0.3 doesn't
+ have it. (Reported by Noah Friedman, friedman@gnu.ai.mit.edu.)
+
+Wed Dec 16 12:12:33 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * write.c, config/obj-ieee.c: don't define SUB_SEGMENT_ALIGN
+ if it is already defined.
+
+Tue Dec 15 12:40:11 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * app.c (do_scrub_begin): allow single quote strings if so
+ configured.
+
+ * config/*z8k*: checkpoint
+
+Sun Dec 13 00:04:38 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * read.c (read_a_source_file): avoid calling xmalloc (0).
+
+Sat Dec 12 15:26:34 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * listing.c: Call xmalloc, not malloc; don't declare malloc.
+
+ * Changes to support SCO 3.2v4:
+ * read.c (s_align_bytes, s_align_ptwo): If not SEG_DATA or
+ SEG_BSS, fill with NOP_OPCODE.
+ * config/i386coff.mt: Add opcode/i386.h to TARG_CPU_DEPENDENTS.
+ * config/obj-coffbfd.c (do_relocs_for): Increment addr even if not
+ using ZERO_BASED_SEGMENTS.
+ (fill_section): If ZERO_BASED_SEGMENTS, set segment addresses, but
+ never set segment address for SEG_E2 (.bss) and don't write out
+ SEG_E2 contents. Set .init and .fini sections to STYP_TEXT.
+ (obj_coff_endef): Don't merge labels or symbols awaiting forward
+ definitions, and don't merge tags with non-tags. Check for .bf
+ rather than just checking whether the second character is b and
+ the third character is f.
+ (obj_coff_val): gcc can generate values which we don't handle
+ correctly; discard information for now, since it only affects the
+ debugging information.
+ (tag_find_or_name): Don't insert tags in the symbol table.
+ (yank_symbols): Don't merge labels.
+ (write_object_file): Don't define SUB_SEGMENT_ALIGN if it is
+ already defined. Fill subsegments with NOP_OPCODE, not 0. Don't
+ set segment address if ZERO_BASED_SEGMENTS.
+ (obj_coff_section): Accept and ignore a trailing quoted string, as
+ used in AT&T i386 syntax.
+ (fixup_segment): Take segment as argument. On the i386, adjust PC
+ relative addends by the segment vaddr.
+ * config/tc-i386.h: Define SUB_SEGMENT_ALIGN.
+ * config/tc-a29k.h: Define ZERO_BASED_SEGMENTS.
+ * config/tc-i386.c: (i386_operand): If I386COFF, accept any segment type.
+
+Tue Dec 8 00:06:48 1992 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * config/obj-coffbfd.c: Include libcoff.h.
+
+ * version.c: Now version 1.93.
+
+Mon Dec 7 00:39:09 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/tc-i386.c (md_pseudo_table): For 386bsd and linux, do
+ power-of-two alignment for .align.
+
+ * as.h: If BROKEN_ASSERT, just redefine `assert' to be trivial,
+ and leave everything else alone.
+
+Fri Dec 4 16:58:42 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (as.new): Don't bother saving as.old.
+
+ * write.c: Conditionalize on OBJ_VMS, not VMS.
+ (magic_number_for_object_file): Don't define if OBJ_VMS.
+
+ * config/obj-vms.c: Changes for traditional C.
+
+Thu Dec 3 01:24:07 1992 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config/ho-generic.h (malloc, realloc): Declare.
+
+ * Lots of comment/whitespace changes.
+
+ * write.h (struct fix): Some fields reordered, narrowed.
+
+ * read.c (MASK_CHAR): Define using C types, not magic number.
+
+ * as.c, input-file.c: Deleted some unused code.
+
+ * app.c, as.h: Doc fix.
+
+ * flonum-konst.c, flonum-mult.c: Include ansidecl.h.
+
+ * as.h (xmalloc): Argument is long.
+
+ * xmalloc.c (error): Remove declaration; as.h takes care of it.
+
+ * doc/as.texinfo: Regrouped documentation of some command-line
+ options. Updated options documentation for m68k. Some minor
+ wording/punctuation changes.
+
+Mon Nov 30 11:42:11 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * configure.in: Accept target OS "vms".
+
+ * symbols.c: Merged ANSI and non-ANSI function decls, using
+ PARAMS macro.
+
+ * xmalloc.c: Just include as.h, don't bother trying to figure out
+ other header files.
+
+ * strstr.c, strerror.c: Deleted.
+ * Makefile.in: Deleted references.
+
+ * config/tc-ns32k.c: Don't include header file for string
+ declarations; leave that to ho-*.h.
+
+Fri Nov 27 04:11:36 1992 Ken Raeburn (raeburn at cambridge-laptop.cygnus.com)
+
+ * config/coff_gnu.h [TC_I860]: Guesses for reloc type values,
+ imported from FSF sources.
+
+ * messages.c (strerror): Declare unconditionally.
+
+ * as.h: Delete alloca and register definitions.
+
+ * config/atof-ieee.c (mask): Now const.
+
+ * obstack.c, obstack.h: Deleted.
+
+ * as.h (flag_readonly_data_in_text): New flag.
+ * as.c (main): Set it for -R.
+
+ * as.h (flag_suppress_warnings): New flag.
+ * as.c (main): Set it for -W.
+ * messages.c (as_warn): Check it instead of flagseen['W'].
+
+ * as.h (flag_always_generate_output): New flag.
+ * as.c (main): Set it for -Z.
+
+ * config/tc-sparc.h: Define NEED_FX_R_TYPE.
+ * config/tc-a29k.h: Ditto.
+ * write.h (struct fix): Don't conditionalize fx_r_type field on TC
+ macros.
+
+ * as.h: Merged ANSI and non-ANSI function decls, using PARAMS
+ macro.
+ * bignum.h, expr.h, flonum.h, frags.h, input-file.h, listing.h,
+ obj.h, output-file.h, read.h, struc-symbol.h, symbols.h, tc.h,
+ write.h: Likewise.
+ * read.c: Likewise.
+
+ * xmalloc.c: Conditionalize on HAVE_MALLOC_H, not USG. Fold in
+ xrealloc from xrealloc.c.
+ * xrealloc.c: Deleted.
+ * Makefile.in (REAL_SOURCES, OBJS): Adjusted.
+
+ * configure.in: For host CPU a29k, rs6000, vax, consider using bsd
+ or vms ho- files.
+
+ * config/ho-sysv.h (setbuffer, HO_USG): Deleted.
+
+ * config/atof-ieee.c (atof_ieee): Exponent field isn't a pointer;
+ don't initialize it with NULL.
+
+ * config/ho-vax.h (M_VAX): Deleted; was unused.
+
+ * README-vms, config/ho-vms.h, config/obj-vms.c, config/obj-vms.h:
+ New files imported from FSF version, contributed by Eric Youngdale.
+ * README-vms-dbg, config/vms: Deleted.
+
+ * ChangeLog, config/ChangeLog: Merged.
+
+ * config/*tahoe*, configure.in: Tahoe support brought in from FSF
+ version.
+
+ * input-file.c (input_file_open): Eliminate call to setvbuf.
+ [USG] (setbuffer): Deleted macro.
+
+Mon Nov 23 11:00:16 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * all files: Whitespace changes for GNU indentation style, done by
+ GNU `indent'. Some cleanup still needed, especially of comments.
+
+ * configure.in: No te-386bsd.h file exists; don't try to use it.
+
+ * config/obj-coff.c (obj_coff_endef): Use as_warn, not fprintf.
+
+ * config/tc-m68k.c (md_assemble): Don't complain about 68000 with 68881;
+ could be doing emulation.
+
+Thu Nov 19 11:47:19 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ z8000 documentation
+ * doc/Makefile.in, doc/all.m4, doc/as-all.texinfo, doc/as.texinfo:
+ all modified.
+
+Tue Nov 10 09:49:24 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (as.o, obj-format.o): added dependency on subsegs.h.
+
+ * subsegs.h: add extern to segment_info declaration.
+
+ * read.h: added extern declarations for comment_chars,
+ line_comment_chars, and line_separator_chars.
+ read.c, app.c: removed definitions of comment_chars,
+ line_comment_chars, and line_separator_chars.
+
+ * config/tc-m68k.c (m68k_reg_parse): If REGISTER_PREFIX isn't defined,
+ still accept (but don't require) OPTIONAL_REGISTER_PREFIX before
+ the register name.
+ (insert_reg): put REGISTER_PREFIX before register names before
+ putting them in the symbol table.
+ * config/tc-m68k.h (OPTIONAL_REGISTER_PREFIX): Define to be "%", if not
+ M68KCOFF.
+
+ * config/obj-coffbfd.c (fill_section): set STYP_NOLOAD bit for .bss
+ section.
+
+ * config/atof-ieee.c, config/atof-ns32k.c, config/tc-*.c: made
+ EXP_CHARS, FLT_CHARS, comment_chars, line_comment_chars and
+ line_seperator_chars consistently const, and always
+ initialized them. Included read.h.
+
+Thu Nov 5 17:55:41 1992 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Add code to flag error if an absolute
+ constant will not fit in an immediate field.
+ (md_apply_fix, RELOC_BASE13 case): Check for relocation overflow.
+
+Wed Nov 4 07:50:46 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/obj-coff.c (callj_table): Delete global variable.
+ (obj_emit_relocations): Define it locally here, and only if
+ TC_I960 is defined.
+
+ * config/tc-m68k.c (m68k_reg_parse): Underscore is part of a symbol name.
+ (m68k_ip): Don't warn about bignum used as float bit-pattern.
+
+ * config/obj-coff.c: Replaced ANSI and non-ANSI function declarations
+ with a single set using PARAMS macro.
+
+ * config/tc-i960.c (tc_bout_fix_to_chars): Bit-field fixups want a length
+ of 2.
+
+ * config/tc-i960.c: Missed a couple of 0->NO_RELOC conversions.
+
+ * config/tc-i960.h (N_BALNAME, N_CALLNAME): Define as char-type values,
+ so widening works consistently.
+
+Wed Oct 28 08:52:34 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * version.c: Put conditional "const" before version_string, not
+ before dummy function for VMS. Now version 1.91.03.
+
+ * app.c (do_scrub_next_char): Need double-\ before `000' to show
+ printed rep of null character.
+
+Fri Oct 23 14:40:38 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-coffbfd.c (write_object_file): check return value of
+ bfd_close_all_done.
+
+Tue Oct 20 12:18:08 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Support for i386-sysv.
+ obj-coffbfd.c (do_relocs_for, write_object_file): set segment
+ addresses to reasonable sizes. New define ZERO_BASED_SEGMENTS can
+ be used to set them all to zero as was done before.
+ (fill_section): segment addresses now set in write_object_file.
+ (fill_section): Don't set STYP_NOLOAD for .bss section.
+ (fixup_segment): 386 uses strange common symbol format.
+ tc-i386.c (tc_coff_fix2rtype): use R_DIR32, not R_RELLONG, for
+ compatibility with SVR3.2 linker.
+ * configure.in: i386-sysv and i386-sco use coffbfd.
+
+ * app.c (do_scrub_next_char): discard whitespace after a label.
+
+Sat Oct 10 12:33:45 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: differentiate between SunOS 4 and Solaris2 for Sun4
+ hosts, use the sysv configuration for solaris2
+
+Mon Oct 5 09:28:57 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ fix i960+non-bfd coff bit rot.
+ * config/obj-coff.c (c_dot_file_symbol, obj_coff_ln, obj_coff_line):
+ support for C source listings. (obj_coff_endef): look in the right
+ part of the symbol for the symbol name
+
+ * config/tc-m68k.c (get_num): make it work for all segments, not just the
+ first three.
+
+Mon Oct 5 03:30:36 1992 Mark Eichin (eichin at tweedledumber.cygnus.com)
+
+ * configure.in: recognize i386-*-bsd emulation.
+
+Thu Oct 1 23:05:12 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: use the cpu-vendor-os triple for host and target
+
+Tue Sep 29 12:22:52 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/obj-coffbfd.c (write_object_file): don't fixup for the z8k
+ * config/tc-z8k.c: lots of bug fixes
+
+Tue Sep 29 10:51:55 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-i960.h, config/tc-i960.c: avoid the ANSI
+ preprocessor addition #elif, since it is not supported by old
+ compilers.
+ config/ho-rs6000.h, config/tc-m68k.c: the native RS/6000
+ compiler miscompiles a couple of expressions in tc-m68k.c.
+
+Mon Sep 28 21:18:24 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * read.c (cons): If NO_RELOC is defined, use it.
+
+ * config/tc-i960.c (get_cdisp): Use NO_RELOC, not 0, in call to fix_new.
+
+Fri Sep 25 18:18:52 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-m68k.h: if M68KCOFF, define DOT_LABEL_PREFIX (to require
+ local labels to start with a .) and set REGISTER_PREFIX to %.
+ tc-m68k.c (m68k_reg_parse): accept REGISTER_PREFIX if defined.
+
+Fri Sep 25 17:53:43 1992 John Gilmore (gnu@cygnus.com)
+
+ * messages.c: Comment changes.
+
+Fri Sep 25 14:12:58 1992 Ken Raeburn (raeburn@kyriath.cygnus.com)
+
+ * as.h: Test if __STDC__ is defined only, don't test its value.
+ * messages.c: If __STDC__ is not defined, define NO_STDARG.
+
+Thu Sep 24 12:42:32 1992 Brendan Kehoe (brendan@rtl.cygnus.com)
+
+ * listing.c (debugging_pseudo): Add stabs and stabn as things to
+ ignore.
+
+Tue Sep 22 13:02:07 1992 Sean Eric Fagan (sef@cygnus.com)
+
+ * config/obj-coffbfd.c (do_relocs_for,fill_section): now allocate all
+ sections starting from zero, rather than making them consecutive.
+ This makes subsequent reloc calculations easier, esp if the object
+ format doesn't understand addends. (obj_coff_lcomm): (maybe temporarily)
+ allocate lcomm in .data rather than in .bss. It seems that some
+ tools can't cope with a non-zero sized bss before linkage.
+
+Tue Sep 22 15:10:51 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-m68k.c: Replace "enum m68k_architecture" with "int"
+ throughout. That enum no longer means what we thought it meant.
+
+ * config/tc-m68k.c (md_assemble, md_parse_option): Handle new
+ "-mno-688[58]1" options.
+
+ * config/tc-m68k.c: Added CPU32 support.
+
+Fri Sep 18 08:02:18 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip): An(disp) is not pc relative.
+
+Tue Sep 15 17:25:05 1992 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * Makefile.in (as.new): Remove dependence on LOCAL_LOADLIBES.
+ Change LIBDEPS dependence to LIBS.
+
+Tue Sep 15 15:32:02 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (install): if $(tooldir) exists, install as in
+ $(tooldir)/bin.
+
+Sun Sep 13 20:30:10 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Added WARN_SIGNED_OVERFLOW_WORD define to give an error if any
+ .word is < -32768 or > 32767. The -J flag causes the error to be
+ ignored. This is to catch over-sized switches generated by gcc on
+ systems which don't support the broken .word hack.
+ as.c (main): permit -J if WARN_SIGNED_OVERFLOW_WORD.
+ write.c (fixup_segment): check for signed .word overflow if
+ WARN_SIGNED_OVERFLOW_WORD.
+
+ * write.c (fixup_segment): fixed missing parens in expression
+ checking for byte or word overflow.
+
+ * config/obj-coffbfd.h: define WARN_SIGNED_OVERFLOW_WORD.
+ obj-coffbfd.c (fixup_segment): check for signed .word overflow if
+ WARN_SIGNED_OVERFLOW_WORD.
+
+ * config/obj-coffbfd.c (fixup_segment): fixed missing parens in
+ expression checking for byte or word overflow.
+
+Fri Sep 11 10:21:04 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ Support for i386 coff
+ * config/obj-coffbfd.h : added stuff
+ * config/tc-i386.c (tc_coff_fix2rtype): new function
+ * config/tc-i386.h : new coff defines
+
+Thu Sep 10 09:23:15 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * input-scrub.c (input_scrub_push): call input_file_begin, not
+ input_scrub_begin.
+ messages.c (as_perror): print ": " between the passed in error and
+ the strerror, like perror does.
+
+Wed Sep 9 11:06:25 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: use gas_target instead of modifying target_cpu.
+ From Steve Chamberlain:
+ Makefile.in: Handle m68*-*-coff*.
+ read.c, read.h: add mult argument to s_space
+
+ * config/tc-m68k.c (m68k_ip, m68k_ip_op, get_num, try_moto_index): merge
+ Motorola and MIT syntax; gas can now assemble either type of
+ file.
+ * config/tc-m68kmote.c, config/tc-m68kmote.h: removed now
+ superfluous files.
+
+ From Steve Chamberlain:
+ * config/m68kcoff.mt: for m68k COFF.
+ * config/obj-coffbfd.c: (fixup_mdeps) added
+ (size_section) removed bad sanity check
+ (fill_section) added rs_machine_dependent case
+ (write_object_file) call fixup_mdeps
+ (fixup_segment) set fx_subsy to 0.
+ * config/ obj-coffbfd.h: define WORKING_DOT_WORD (too hard to
+ support) and handle m68k.
+ * config/tc-m68k.c, config/tc-m68k.h: added m68k COFF support
+ and Motorala pseudo ops.
+
+Tue Sep 8 17:10:58 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (LIBS): Include opcode library.
+
+Fri Sep 4 18:20:56 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/tc-m68k.c (get_num, case SEG_BIG): If only small integers
+ including zero are accepted, pass +0.0.
+
+Sun Aug 30 21:24:46 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: map "as" through program_transform_name when
+ installing.
+
+ * doc/Makefile.in: map "as" through program_transform_name when
+ installing.
+
+Sat Aug 29 12:11:12 1992 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * Makefile.in (as.new): Depend on LOCAL_LOADLIBES.
+
+Fri Aug 28 16:25:22 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-bout.h, config/obj-bout.c (obj_header_append,
+ obj_symbol_to_chars).
+ * config/tc-i960.c (md_ri_to_chars): Always output bout object
+ file in little endian byte order (used to use endianness of
+ host).
+
+Tue Aug 25 15:50:48 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-m68k.c (init_table): Now const. Always include 68851
+ data, so that "bc" is available to 68040 cache instructions.
+ Added "tt0", "tt1", and 68ec030 variants.
+ (md_assemble): Complain if 68000 (only) and 68881 are specified.
+ (enum _register): Added TT0, TT1.
+ (m68k_ip, cases '3' and 't'): Handle new operand type codes. Pass
+ line number correctly in "internal error" messages. Don't print
+ architecture-mismatch message for operand errors.
+
+ From Colin Smith (colin@wrs.com):
+ * config/tc-m68k.c (m68k_ip, case '_'): Use addword twice rather
+ than install_operand.
+
+Tue Aug 25 15:13:48 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * listing.c (buffer_line): rewind to the start of include
+ files, they might be included twice.
+
+ * z8k.c, z8k.h, z8k.mt: z8000 support stuff
+
+Mon Aug 24 12:45:43 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: defined TARGET_CPU for C code so that it can choose
+ one element of a family.
+
+ * config/tc-m68k.c: use TARGET_CPU to choose default cpu type.
+
+ * config/te-generic.h: default to LOCAL_LABELS_DOLLAR and LOCAL_LABELS_FB
+ so that we can assemble hand-written libgcc code.
+
+Fri Aug 21 14:38:44 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * messages.c (as_warn): Use fputs, not fprintf, with a buffer that
+ has already been formatted (but may still contain %-characters).
+ (as_bad): Likewise.
+
+Wed Aug 19 11:20:59 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-m68k.c, tc-m68kmote.c: the cas2 instruction is supposed to be
+ written with indirection on the last two operands, which can be
+ either data or address registers. Added a new operand type 'r'
+ which accepts either register type. Added '(' to notend stuff in
+ tc-m68kmote.c to accept (a0):(a2) in cas2 instruction.
+
+Wed Aug 19 09:25:09 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * as.h (enum _relax_state): Start off at one, not zero, to better
+ catch uninitialized-variable errors.
+ (linkrelax): Declare new variable.
+
+ * messages.c (warning_count, error_count): Default initializer is
+ sufficient.
+
+ * write.c: Merged some declarations, using PARMS macro.
+ (text_frag_root, data_frag_root, bss_frag_root, text_last_frag,
+ data_last_frag): No longer static.
+ (write_object_file, case rs_align or rs_org): If HANDLE_ALIGN is
+ defined, call it. Change segments before calling fixup_segment.
+ (relax_align): If linkrelax, provide extra padding.
+
+ * config/obj-bout.c (obj_emit_relocations): Emit alignment relocs despite
+ their not having symbols associated.
+
+ * config/tc-i960.c (norelax, instrument_branches): Default initializer is
+ sufficient.
+ (linkrelax): Delete variable definition.
+ (mem_fmt): Call fix_new with NO_RELOC.
+ (tc_bout_fix_to_chars): Handle alignment relocs.
+ (i960_handle_align): New function.
+ * config/tc-i960.h (linkrelax): Delete declaration.
+ (HANDLE_ALIGN): New macro; calls i960_handle_align.
+ (NEED_FX_R_TYPE, NO_RELOC): New macros.
+
+Tue Aug 18 14:59:21 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/sparc.mt: New file. Grab sparc opcode table from bfd
+ library.
+
+Tue Aug 18 14:16:38 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: always create installation directories. Removed
+ MINUS_G, set CFLAGS to default to -g, added FLAGS_TO_PASS, passed
+ FLAGS_TO_PASS to recursive makes.
+
+ * doc/Makefile.in: always create installation directories.
+
+Mon Aug 17 15:09:56 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * input-scrub.c (input_scrub_pop, input_scrub_push): memcpy was
+ being used with args swapped, causing occasional lossage when
+ refilling buffers after an include file.
+
+Mon Aug 17 13:18:51 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * messages.c (as_tsktsk): Use correct ANSI form for stdarg
+ version. Discard bogus DONTDEF version.
+ (as_warn, as_bad, as_fatal): Likewise.
+
+Fri Aug 14 18:31:14 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip): If instruction is invalid for the
+ selected architecture, print a message saying so and listing what
+ processors support it, rather than saying "operands mismatch".
+
+Thu Aug 13 13:53:19 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * as.h [BROKEN_ASSERT]: If defined, turn off all assertion checks.
+
+ * config/ho-rs6000.h (M_RS6000): Don't define it.
+ (free): Declare it.
+ (BROKEN_ASSERT): Define it if not __STDC__.
+
+Tue Aug 11 12:58:14 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * sparc.mt: New file.
+
+Mon Aug 10 14:37:08 1992 Per Bothner (bothner@cygnus.com)
+
+ * config/tc-m68k.c: ".align N" means align to N-byte boundary *only*
+ if TN_SUN3; otherwise align to 2**N-byte bounary.
+
+Thu Aug 6 12:10:39 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * read.c (s_fill): make the .fill size clamped error a warn and
+ fix bug where 0's were always placed.
+
+ * config/tc-h8300.c: if a :8 is seen after an operand, fill top
+ two bytes of any constant with 0xff:
+
+Wed Aug 5 12:02:40 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/tc-m68k.c (md_pseudo_table): fix the .align thing
+ the right way; for just the 68k. Sun 3 .align is nbytes, not ptwo.
+
+Wed Aug 5 01:54:34 1992 John Gilmore (gnu at cygnus.com)
+
+ * config/tc-m68k.c (try_index): Error if index scaling specified and
+ assembling for an older CPU than a 68020.
+
+Sat Aug 1 19:10:13 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/tc-sparc.c (tc_aout_fix_to_chars): If pc-relative, take
+ fx_offset into account.
+
+Fri Jul 31 21:53:28 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * configure.in (mips host): Accept "ultrix" with version number.
+
+ * expr.c (floating_constant): Separate "=-" to avoid confusing
+ ancient or broken compilers.
+
+ * config/tc-m68k.c (m68k_ip): Mismatch error could also indicate
+ processor/opcode mismatch, so reword the error message.
+ (md_assemble): If no CPU has been set (even if FPU/PMMU
+ characteristics have been), default to 68020. Don't need extra
+ quotes around error string.
+
+Fri Jul 31 12:26:34 1992 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * read.c (potable): Revert sac's incorrect change made Jul 13.
+ Align really is supposed to be ptwo not nbytes.
+
+Mon Jul 20 02:51:59 1992 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * Makefile.in: _Do_ include libiberty. (from sef)
+
+Fri Jul 17 15:15:28 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * expr.c (integer_constant): Handle "0f" and "0b" label references
+ properly.
+
+Thu Jul 16 08:20:17 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * write.c (fixup_segment): if relaxing, don't do anything.
+ * config/obj-bout.[ch] : maintain the a_relaxable file header info
+ * config/tc-i960.c: new option -linkrelax
+
+Mon Jul 13 14:11:36 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * expr.c (expr): allow SEG_BSS in expressions
+ * read.c (potable): align should be nbytes, not ptwo!
+ * write.c (write_object_file): extra glue for new bss attributes
+ (relax_segment): SEG_BSS is ok now
+ * config/tc-m68k.c (m68k_ip_op): can now parse more @( modes
+
+Mon Jul 6 17:09:32 1992 Steve Chamberlain (sac@cygnus.com)
+
+ * config/obj-coffbfd.c (fill_section): mark .lit sections as STYP_LIT
+
+Mon Jun 1 16:20:22 1992 Michael Tiemann (tiemann@cygnus.com)
+
+ * configure.in: recognize m680x0 as having sun3 emulation mode for
+ vxworks environment.
+
+
+Tue Jun 30 20:25:54 1992 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * Makefile.in: Add program_suffix (parallel to program_prefix)
+
+Wed Jun 24 10:57:54 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * app.c (process_escape): new function to handle escapes the right
+ way, (do_scrub_next_char): use new function
+ * cond.c (s_ifdef): do ifdef/ifndef right
+ * read.c (s_fill): make the , expressions optional like the doc
+ says
+ * config/tc-h8300.[ch]: better warnings
+
+Tue Jun 9 07:54:54 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * subsegs.c (subsegs_begin): create bss0_frchainP in the same was
+ as data0_frchainP
+
+ * write.c (write_object_file): various changes to handle data in
+ the BSS segment in much the same was as stuff in the DATA segment.
+
+ * config/tc-m68k.c (m68kip): Fix typo so that only arch's >=68020 do
+ pcrel data stuff. (md_estimate_size_before_relax): when relaxing a
+ 68010 bxx into a bra+6 jmpxx, put the bytes of the jmp opcode into
+ the right place. (s_bss): Don't put .bss stuff into SEG_DATA, put
+ it into SEG_BSS
+
+Thu Jun 4 11:59:13 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * expr.c(expr): allow SEG_REGISTER in expressions.
+ * read.c(pseudo_set): register expressions can be the source of a
+ set.
+ * subsegs.c (subseg_new): Now -R forces all changes to SEG_DATA to
+ goto SEG_TEXT (if a.out)
+ * write.c (write_object_file): If a.out don't use the old way for
+ -R.
+ * config/obj-a.out (s_sect): complain if the user tries to use a
+ subsegment with a value which might interfere with out -R hackery.
+ * config/tc-m68k.c (m68k_reg_parse): lookup names in symbol table
+ rather than use ugly if tree. (init_regtable): insert register
+ names into symbol table.
+
+Tue Jun 2 16:47:09 1992 Steve Chamberlain (sac@cygnus.com)
+
+ * write.c (write_object_file): keep the fix_tail clean, which
+ fixes a bug in -R where relocations were being lost.
+
+Mon Jun 1 16:20:22 1992 Michael Tiemann (tiemann@cygnus.com)
+
+ * configure.in: recognize m680x0 as having sun3 emulation mode for
+ vxworks environment.
+
+Sun May 31 05:33:00 1992 david d `zoo' zuhn (zoo@cygnus.com)
+
+ * configure.in: recognize m680x0 as an m68k
+
+Thu May 28 11:22:02 1992 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * configure.in: Recognize sparclite as a sparc variant.
+
+ * config/tc-sparc.c: Use new ARCHITECTURES_CONFLICT_P macro. Mention new
+ -Asparclite flag.
+
+Tue May 26 16:47:56 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/tc-a29k.c: lint
+ * listing.c, expr.c: patches from Andrew Smith
+
+Thu May 14 17:22:48 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * doc/Makefile.in: use m4 rather than gm4.
+
+Mon May 4 18:56:19 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/obj-coffbfd.c: use is a synonym for section, (do_relocs_for):
+ calc the base of relocs correctly.
+ * config/tc-a29k.c (parse_operand): allow expressions to be in any section.
+
+Mon Apr 27 13:13:31 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * as.c, write.c: use -K rather than -k for the broken word warning
+ option.
+
+Tue Apr 21 13:35:30 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: do not print recursion lines.
+
+Wed Apr 15 21:19:31 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: the tooldir copy of gas goes directly in tooldir.
+
+Tue Apr 14 14:50:22 1992 Ken Raeburn (Raeburn@Cygnus.COM)
+
+ * write.c (write_object_file): For b.out format, round up section
+ start addresses to match required alignment.
+
+Thu Apr 9 05:45:29 1992 Ken Raeburn (Raeburn@Cygnus.COM)
+
+ * Makefile.in (install): Install into $(tooldir)/bin, since that's
+ where gcc looks for it.
+
+Tue Apr 7 15:12:15 1992 Sean Eric Fagan (sef@cygnus.com)
+
+ * Makefile.in: Changed some lines to be less confusing for some
+ makes.
+
+ * input-file.c: Conditionalize on _IOFBF, not VMS.
+
+ * read.c, write.c: Change a series of ifdef/elif to
+ ifdef/else/ifdef etc.
+
+Fri Mar 27 12:21:16 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * symbols.c (fb_label_init): fix sizeof to memset.
+
+Fri Mar 13 15:45:44 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: install the man page.
+
+ * Makefile.in: pass down MAKEINFO explicitly on info.
+
+ * doc/Makefile.in: use $(MAKEINFO) not makeinfo.
+
+Fri Mar 13 08:03:03 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * flonum-const.c: renamed flonum-konst.c to stop dos name
+ conflict.
+
+Thu Mar 12 04:42:38 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * config/tc-m68k.h, config/te-sun3.h: moved LOCAL_LABELS_FB
+ definition from tc-m68k.h to te-sun3.h.
+
+Wed Mar 11 23:32:42 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * configure.in: vxworks68 gets te-sun3.h.
+
+ * expr.c: remove limitation that local_labels_dollar or
+ local_labels_fb must be < 10.
+
+ * symbols.c: remove local_labels_dollar, replace with a function
+ interface for a sparse array. All users adjusted.
+
+ * config/te-sun3.h: add LOCAL_LABELS_DOLLAR.
+
+Sat Mar 7 00:06:25 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * doc/Makefile.in: commented out line for building as-all.texinfo.
+ This is temporary.
+
+ * doc/as.texinfo, doc/as-all.texinfo: added menu item hooks.
+
+Fri Mar 6 21:57:18 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: added check target.
+
+Tue Mar 3 15:45:56 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: added tooldir and program_prefix.
+
+Sun Mar 1 04:43:19 1992 Michael Tiemann (tiemann@cygnus.com)
+
+ * write.{c,h} (fix_new): Make these declarations consistent.
+
+Sat Feb 29 13:59:10 1992 Michael Tiemann (tiemann@cygnus.com)
+
+ * Makefile.in (strerror.o): Add rule so that broken Sun make can
+ work in subdirs.
+
+Wed Feb 26 19:26:28 1992 Steve Chamberlain (sac at thepub.cygnus.com)
+
+ * read.c, obj-coffbfd.c : fix h8300 specific bit rot
+
+ * expr.c (operand): if can't work out what sort of operand it is,
+ then look through FLT_CHARS for a hint.
+
+Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in, configure.in: removed traces of namesubdir,
+ -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced
+ copyrights to '92, changed some from Cygnus to FSF.
+
+ * doc/Makefile.in, doc/configure.in: removed traces of namesubdir,
+ -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced
+ copyrights to '92, changed some from Cygnus to FSF.
+
+Tue Feb 25 14:17:15 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * expr.c: If an expression is single comma, then return with
+ SEG_ABSENT rather than an error - since the sparc front end does
+ really strange things with things like fbge,a
+
+ * as.h: include bfd.h if using many sections
+ * expr.c: LOCAL_LABELS_FB had been changed to lower case - so
+ local labels didn't work.
+ * listing.c (list_symbol_table): don't core dump when there's no
+ symbol there.
+ * write.c, write.h: call fix_new with the right number of args on
+ the H8.
+ * config/tc-h8300.[ch] : fix bugs reported by HMSI, and make
+ errors nices
+
+Sat Feb 22 12:26:28 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * app.c: MRI compatibility - allow single quote to start a string.
+ * as.c: fix typo recently introduced.
+ * as.h : Don't include aout/reloc.h - it's not right for COFF!
+ * expr.c: Much rewriting, to accommodate MRI syntax for
+ expressions. Also easier to read now.
+ * listing.c: Put back defuns
+ * read.c: modified to accept MRI syntax, put back listing pseudo
+ ops so that an assembler built with NO_LISTING ignores list ops
+ rather than pukes.
+ * write.c, write.h: fixs - only keep a reloc type in a fix if the target
+ machine is a SPARC or a 29K.
+ * config/obj-aout.c: added s_sect pseudo op
+ * config/obj-coffbfd.c: lints, set the filehdr flags right and
+ fill in the timestamp.
+ * config/obj-coffbfd.h: Since we don't include aout/reloc.h
+ anymore, define all the relocs which the tc-<x> bit will use so we
+ can translate from them to the coff types.
+ * config/tc-a29k.c: reloc_type isn't ane enum any more
+ * config/tc-m68k.c: Added NO_RELOC definition.
+
+Fri Feb 21 06:21:07 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: put header files before C source for TAGS; remove
+ references to non-existent syscalls.h.
+
+ * read.c, write.c subsegs.c: back out the .bss changes.
+
+ * config/obj-aout.c: do not include stab.gnu.h if NO_LISTING.
+
+ * config/tc-i860.c, a.out.gnu.h: move i860 relocs to a proper place.
+
+ * a.out.h: removed.
+
+Fri Feb 21 01:08:48 1992 Minh Tran-Le (TRANLE@INTELLICORP.COM)
+
+ * symbols.c (local_label_name): symbols now start with ^A.
+
+ * read.c, subsegs.c, write.c obj-coff.c: added handling of
+ `.bss` pseudo op for unitialized data. The new gcc (1.37.9x)
+ generate these sections. .align: will use NOP_OPCODE or 0
+ for padding. This is just for being nice to the
+ disassembler.
+
+ * expr.c (operand): changed to generate local label "\001L0"
+ starting with a ^A so that it is recognized as a local label.
+
+ * as.c (perform_an_assembly_pass): zero bss_fix_root, too.
+
+ * config/tc-i386.c: tc-i386.c: added handling of the following opcodes:
+ i/o opcodes - inb, inw, outb and outw. string manipulation with
+ att syntax - scmp, slod, smov, ssca, ssto.
+
+ * config/obj-coff.c: (for aix386) Moved the symbols .text, .data and .bss
+ to just after .file .
+
+ In obj_crawl_symbol_chain() where it tries to put the external
+ symbols apart, with the condition:
+ (!S_IS_DEFINED(symbolP) &&
+ !S_IS_DEBUG(symbolP) &&
+ !SF_GET_STATICS(symbolP))
+ it was moving too many symbols out. So I switch it back to the
+ condition:
+ (S_GET_STORAGE_CLASS(symbolP) == C_EXT && !SF_GET_FUNCTION(symbolP))
+
+ In obj_emit_relocations() added the conditional on KEEP_RELOC_INFO
+ so that we don't use the F_RELFLG which make the linker complain
+ that somebody has stripped the relocation info.
+
+ Also, the AIX ld program require that the relocation table
+ is sorted by r_vaddr like the standard ATT assembler does.
+
+ [he also changed the sizeof(struct ...)'s into the coff
+ style FOOSZ macros. I'm not sure this is right, but I can't
+ remember why. xoxorich.]
+
+Fri Feb 21 01:08:48 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in, configure.in, doc: use the doc. Build it, install
+ it, clean it, etc.
+
+Tue Feb 18 02:21:25 1992 K. Richard Pixley (rich at cygnus.com)
+
+ * read.c: white space and comments only.
+
+ * configure.in: use the new atof-ns32.c for ns32k.
+
+ * write.c: comment change only.
+
+ * config/tc-m88k.[hc]: pulled in from hack's unfinished work. These
+ aren't yet integrated.
+
+ * config/tc-i860.[hc]: blew off the dust. Something must still be done
+ about conflicting relocation types.
+
+ * config/tc-ns32k.c: Replaced previous tc_aout_fix_to_chars stub with the
+ real thing.
+
+ * config/tc-i960.c, config/tc-sparc.c: white space and comments only.
+
+ * config/tc-a29k.h: delete duplicate macro definition.
+
+ * new file atof-ns32k.c copied from hack's last unreleased gas.
+
+Mon Feb 17 07:51:06 1992 K. Richard Pixley (rich at cygnus.com)
+
+ * config/tc-ns32k.c: actually make tc_aout_fix_to_chars work
+ rather than abort.
+
+ * nearly everything. flush ChangeLog, package as gas-1.92.1.
+ ChangeLog's prior to this are sketchy at best. I have logs.
+ They just aren't ChangeLogs.
diff --git a/x/binutils/gas/ChangeLog-9697 b/x/binutils/gas/ChangeLog-9697
new file mode 100644
index 0000000..7ffff3e
--- /dev/null
+++ b/x/binutils/gas/ChangeLog-9697
@@ -0,0 +1,5959 @@
+Wed Dec 31 12:29:47 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_relax_table): Correct branch ranges.
+
+Mon Dec 22 13:06:05 1997 Joel Sherrill <joel@oarcorp.com>
+
+ * configure.in (i386*-go32-rtems*): Fix to be the same as
+ i[3456]86-go32.
+ * configure: Rebuild.
+
+Mon Dec 22 12:54:07 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (macro): The 4650 doesn't permit M_LDC1_AB,
+ M_SDC1_AB, M_L_DOB, M_L_DAB, M_S_DAB, or M_S_DOB.
+ (mips_ip): Always check for FP_D, not just for instructions that
+ are not part of the regular ISA.
+
+Thu Dec 18 16:49:28 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-d10v.c (build_insn): Make `number' a long for 64-bit hosts.
+
+Thu Dec 18 16:42:57 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (cpu_types): 21164pc/pca56 does not have CIX.
+
+Wed Dec 17 21:23:07 1997 Jeffrey A Law (law@cygnus.com)
+
+ * expr.c (integer_constant 32bit bignum): Mask off bits outside
+ the range we care about.
+
+Wed Dec 17 15:29:03 1997 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-d30v.c (md_shortopts): Add 'n' and 'N' options.
+ (exec_type_enum): Enumeration giving all of the exec types.
+ (warn_nops): New static variable to give nop warning level.
+ ({cur,prev}_mul32_p): New static variable to keep track of whether
+ the current/previous instruction is a 32-bit multiply.
+ (Optimizing): Make static.
+ (NOP{2,_LEFT,_RIGHT}): Macros for word of nops and left/right
+ nops.
+ (d30v_insert_operand): Delete declaration of unused function.
+ (write_2_short): Make exec_type argument enum, not int.
+ (parallel_ok): Ditto.
+ (check_range): Delete unused variable(s).
+ (build_insn): Ditto.
+ (find_format): Ditto.
+ (md_apply_fix3): Ditto.
+ (md_show_usage): Document -n and -N.
+ (md_parse_option): Parse -n and -N.
+ (write_1_short): If -n, warn about adding a nop. Use
+ NOP_{LEFT,RIGHT}.
+ (write_2_short): Use enumeration values instead of hard coded
+ integers. Reset exec_type for default operations. For explicit
+ parallel operations, call parallel_ok to make sure everything is
+ ok. If writing out a parallel operation, and the previous
+ instruction was a 32-bit multiply, indicate current instruction
+ is.
+ (parallel_ok): Allow add/tx ... to be done in parallel with
+ another add/tx ... assuming the gpr registers don't overlap.
+ (md_assemble): Use exec type enumeration values, not hard coded
+ ints. Check for loads or 16-bit multiplies following in the next
+ cycle after a 32-bit multiply. Add nops if that is the case.
+ (do_assemble): Copy prev_mul32_p to cur_mul32_p, and set
+ cur_mul32_p if current instruction is a 32-bit multiply.
+ (find_format): Change spacing and layout.
+
+Tue Dec 16 16:55:45 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (tic80_relax): New static variable.
+ (md_longopts): Add new OPTION_RELAX and OPTION_NO_RELAX options.
+ (md_parse_option): Handle new relax options.
+ (md_show_usage): Document new relax options.
+ (find_opcode): Don't use short forms of PC relative branches if
+ tic80_relax is set.
+
+Tue Dec 16 15:26:03 1997 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-d30v.c (parallel_ok): Remove non-register bits from
+ used/set flag fields. Make flag vars unsigned long. Use
+ FLAG_A{0,1} for accumulators. Allow any 2 insns to be done in
+ parallel if they use the same conditional flag with reversed
+ meaning. Allow 2 add/sub insns that set the carry or overflow
+ flags but do not query them to be done in parallel. Don't allow 2
+ word store operations to be done in parallel with ADDppp or
+ SUBppp. Don't allow loads to be done in parallel with 16 bit
+ multiplies.
+
+Tue Dec 16 09:20:43 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c: Prevent use of interworking support for
+ non-COFF targets.
+
+Mon Dec 15 15:20:32 1997 Nick Clifton <nickc@cygnus.com>
+
+ * doc/all.texi: Add M32R cpu.
+
+ * doc/as.texinfo: Add documentation of m32r processor.
+
+ * doc/c-m32r.texi: New file, documenting m32r specific features.
+
+Mon Dec 15 10:32:28 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Correctly insert 'P' operands into
+ the instruction.
+
+Fri Dec 12 11:44:20 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (build_insn): Handle instructions that have
+ long (32 bit) PC relative offsets. Fix places that previously
+ misused R_MPPCR for 15 bit offsets to use the new R_MPPCR15W type.
+ (md_apply_fix): Add case to handle long PC relative offsets.
+
+Fri Dec 12 10:35:01 1997 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-arm.texi (ARM Options): Document support for new ARM
+ processor names.
+
+ * config/tc-arm.c (md_parse_option): Add support for new ARM
+ processor names.
+
+Thu Dec 11 17:46:50 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Don't overwrite opcode table data.
+ (insop, m68k_ip): Make `opcode' const so it doesn't happen again.
+
+Fri Dec 5 11:23:59 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_assemble): Fix BFD_RELOC_32 against a
+ symbol + offset.
+
+ * config/tc-v850.h (ELF_TC_SPECIAL_SECTIONS): Use
+ SHT_V850_{S|T|Z}COMMON to mark special common sections.
+
+Tue Dec 2 17:05:13 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c: Brought up to date with the branch.
+
+Mon Dec 1 20:24:18 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-sh.c (SWITCH_TABLE_CONS): Handle (fix)->fx_size == 1.
+ (SWITCH_TABLE): Handle BFD_RELOC_8.
+ (md_apply_fix): #ifndef BFD_ASSEMBLER code: Handle fixP->fx_size == 1.
+ (coff_reloc_map): Add BFD_RELOC_8_PCREL entry.
+ (sh_coff_reloc_mangle): SWITCH_TABLE case: Handle BFD_RELOC_8.
+
+Sat Nov 22 16:19:22 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (range_signed_16, range_signed_32): Work around an
+ apparent bug in gcc's long long support crossing from x86.
+
+Sat Nov 22 14:26:09 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c: Brought up to date with latest changes on arm
+ branch.
+
+Sat Nov 22 15:50:09 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * config-gas.com: Get version info from configure.in.
+
+ * makefile.vms: include depend.obj in OBJS.
+
+ * config/tc-alpha.c (s_alpha_section): Remove ".lcomm" handling.
+
+ * config/tc-alpha.c (alpha_basereg_clobbered): Remove variable and
+ all corresponding code.
+
+Thu Nov 20 15:06:08 1997 Richard Earnshaw <rearnsha@arm.com>
+
+ * config/tc-arm.h (TARGET_FORMAT for generic a.out targets): Allow
+ run-time endian selection.
+
+Wed Nov 19 17:44:42 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-sh.c (parse_reg): Properly quote for fv4.
+
+Wed Nov 19 23:46:18 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (resolve_symbol_value): Add missing breaks in case on
+ symbol value operator.
+
+Tue Nov 18 18:45:14 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-d10v.c (parallel_ok, find_opcode):
+ Split OPERAND_FLAG into OPERAND_FFLAG and OPERAND_CFLAG.
+
+Sun Nov 16 10:05:07 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): Cast second arg of
+ md_apply_fix3 call to type "valueT *".
+
+Thu Nov 13 13:53:10 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (emulations): Make FreeBSD an aout / i386bsd
+ variant.
+ * configure: Re-generate.
+
+Thu Nov 13 11:07:14 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (macro_build): Use the membership field
+ for INSN_MACRO's.
+ (mips_ip): Same.
+
+Thu Nov 13 02:04:55 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-d10v.c (find_opcode): For OPCODE_FAKE, add check for
+ first argument if it's supposed to be a register.
+
+Tue Nov 11 19:25:05 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * app.c (do_scrub_chars): If d10v, re-insert a space before
+ a '#' when in state 10.
+
+Tue Nov 11 13:33:15 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-h8300.c: Include "subsegs.h".
+ (tc_reloc_mangle): Handle references to symbols which are not
+ being output, so that references to `.' work.
+
+Mon Nov 10 13:43:33 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Call add_fix when needed for '_'
+ case.
+
+ * macro.c (sub_actual): If we don't find a parameter for an &,
+ just substitute &.
+
+Fri Nov 7 21:29:32 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/tc-mips.c (mips_ip): In default case, call as_bad
+ instead of fprintf, to get "assembler messages:" message output
+ before instead of after.
+
+Fri Nov 7 10:36:22 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * frags.h: Handle multiple inclusion.
+
+Wed Nov 5 10:51:49 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ Based on a patch from Ian.Dall@dsto.defence.gov.au.
+ * as.h (struct frag, frag support): Moved from here.
+ * frags.h: To here.
+ (struct frag, member tc_frag_data): New member if TC_FRAG_TYPE
+ is defined.
+ (struct frag, member fr_cgen): Renamed from fr_targ.cgen.
+ * cgen.c (cgen_asm_finish_insn): Update.
+ * config/tc-m32r.c (md_estimate_size_before_relax): Update.
+ * config/tc-m32r.h (TC_FRAG_INIT): Renamed from md_init_frag.
+ (md_convert_frag): Ditto.
+ * config/tc-ns32k.h (TC_FRAG_TYPE): Define.
+ (frag_opcode_frag,frag_opcode_offset,frag_bsr): Update.
+ (TC_FRAG_INIT): Update.
+
+Tue Nov 4 16:35:57 1997 Ian Dall <Ian.Dall@dsto.defence.gov.au>
+
+ * write.c (print_fixup): Use TC_FIX_DATA_PRINT (if defined) to
+ print out MD fields of fix.
+ * frags.c (frag_var, frag_variant): Use TC_FRAG_INIT macro (if
+ defined) to initialize MD fields in frag.
+ * as.h (struct frag, ns32k support): Rename ns32k to fr_ns32k.
+ Delete pcrel_adjust. Add fr_opcode_fragP, fr_opcode_offset.
+ * config/tc-ns32k.h: Add comments. Remove obsolete
+ BFD_FAST_SECTION_FILL definition, change prototypes for
+ fix_new_ns32k and fix_new_ns32k_exp to add new arguments
+ opcode_frag and opcode_offset and remove pcrel_adjust.
+ (TC_FIX_TYPE): add opcode_fragP and opcode_offset fields.
+ (TC_FIX_DATA_PRINT): new macro to print out TC_FIX_TYPE.
+ (TC_FRAG_INIT): new macro to initialize machine dependent field in
+ frags.
+ (frag_opcode_frag, frag_opcode_offset, frag_bsr): macros to access
+ MD fields in frag structure.
+ (fix_im_disp, fix_bit_fixP, fix_opcode_frag, fix_opcode_offset,
+ fix_bsr): macros to access MD fields in fix structure.
+ * config/tc-ns32k.c: Avoid overlength lines. Align comments. Don't
+ use struct opcode_location as these fields are now in the frag
+ structure.
+ (convert_iif): Call frag_more as it is needed instead
+ of trying to allocate for the whole insn. Avoid call of frag_more
+ with negative argument.
+ (md_pcrel_adjust, md_fix_pcrel_adjust, md_apply_fix,
+ md_estimate_size_before_relax, md_pcrel_from,
+ tc_aout_fix_to_chars): use accessor macros to get md fields in fix
+ and frag structures.
+ (fix_new_ns32k, fix_new_ns32k_exp): add new arguments opcode_frag and
+ opcode_offset and remove pcrel_adjust.
+ (convert_iif, cons_fix_new_ns32k): call fix_new_ns32k,
+ fix_new_ns32k_exp with changed arguments.
+
+Mon Nov 3 13:30:17 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (md_begin): Reorganize setting of default values so
+ that mips_cpu depends on TARGET_CPU, and mips_opts.isa depends on
+ mips_cpu.
+ (md_parse_option): Remove all code that sets defaults; md_begin
+ handles all of this now.
+
+Sun Nov 2 14:46:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (STAGESTUFF): Change bin_PROGRAMS to
+ noinst_PROGRAMS.
+ (bootstrap, bootstrap2, bootstrap3): Likewise.
+ * Makefile.in: Rebuild.
+
+ * config/tc-ppc.c (ppc_fix_adjustable): Don't adjust relocs in the
+ TOC section to be against the csect.
+
+Fri Oct 31 18:19:55 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/tc-mips.c (validate_mips_insn): New function, checks
+ match versus mask bits, and also verifies that all bits to be
+ output are actually specified somewhere.
+ (md_begin): Call it for 32-bit instructions, instead of doing
+ match/mask check here. In case of failure, print a message, but
+ check the rest of the opcode table before exiting.
+
+Thu Oct 30 13:46:20 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_apply_fix3): Fix thumb ADR pseudo op. Patch
+ from Tony Thompson at ARM: athompso@arm.com
+
+Thu Oct 30 11:11:26 1997 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-d30v.c (build_insn): Allow odd registers for ld2w and
+ friends.
+
+Fri Oct 24 15:56:47 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (md_assemble): When handling @l, always sign
+ extend if the operand expects a signed value.
+
+ * config/tc-mips.h (LOCAL_LABELS_DOLLAR): Don't define; use
+ default which is to permit dollar labels.
+
+Fri Oct 24 11:19:22 1997 Jakub Jelinek <jj@sunsite.mff.cuni.cz>
+
+ * config/tc-sparc.c (sparc_memory_model): New variable.
+ (md_longopts): Add -TSO/-PSO/-RMO options.
+ (md_parse_options): Handle them.
+ (sparc_elf_final_processing): For 64 ELF, set required
+ memory ordering in e_flags. Default to RMO and let the user
+ override it through command line.
+
+ * config/tc-sparc.h (elf_tc_final_processing): Add.
+
+Wed Oct 22 17:42:12 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-sparc.c (v9a_asr_table): New variable.
+ (sparc_ip): Handle v9a asr's.
+ Patch from David Miller <davem@vger.rutgers.edu>.
+
+Wed Oct 22 17:22:59 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-sparc.h (md_do_align): New macro.
+ * config/tc-sparc.c (sparc_handle_align): Handle rs_align_code.
+ Patch from Jakub Jelinek <jj@sunsite.mff.cuni.cz>.
+
+Wed Oct 22 12:51:18 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (sh_small): New variable.
+ (OPTION_SMALL): Define.
+ (md_longopts): Add "small".
+ (md_parse_option): Handle OPTION_SMALL.
+ (md_show_usage): Mention -small.
+ * config/tc-sh.h (sh_small): Declare.
+ (SUB_SEGMENT_ALIGN): Handle sh_small.
+ * config/obj-coff.h (TARGET_FORMAT): Check sh_small in TC_SH
+ case.
+
+ * config/tc-mips.c (macro): Correct handling of constant in M_LI_D
+ case in little endian mode.
+
+Tue Oct 21 10:20:11 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * config/tc-sparc.c (md_apply_fix3, cases ..._H44, ..._HIX22): Leave
+ overflow signalling to linker.
+
+Mon Oct 20 14:54:06 1997 Klaus K"ampf <kkaempf@progis.de>
+
+ * makefile.vms: Fix for dec c.
+
+ * config-gas.com: Give explanation for dec c setup in error
+ message.
+
+ * config/tc-alpha.c (s_alpha_comm): Make .comm symbols separate
+ sections on openvms/alpha.
+
+ * config/obj-evax.c: support .weak pseudo-op
+
+Mon Oct 20 10:13:32 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * config/tc-sparc.c (default_arch_size): New static local.
+ (struct sparc_arch): Rename arch_size to default_arch_size.
+ New member user_option_p.
+ (sparc_arch_table): Always include v9, v9a. New entry v9-64.
+ (init_default_arch): Check whether default arch is valid.
+ Set default_arch_size in addition to sparc_arch_size.
+ (OPTION_32,OPTION_64): Define.
+ (md_longopts): New entries for -32, -64.
+ (md_parse_option): Handle them.
+ (md_show_usage): Print them. Ensure init_default_arch called.
+ * configure.in (sparc64): Set arch to v9-64.
+ * configure: Regenerated.
+
+Sun Oct 19 13:50:50 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (subsegs_finish): New function, broken out of
+ write_object_file.
+ (write_object_file): Some code moves into subsegs_finish.
+ * write.c (subsegs_finish): Declare.
+ * as.c (main): Call subsegs_finish.
+
+ * read.c (s_include): Check for error return from
+ demand_copy_string.
+
+Tue Oct 14 20:50:58 1997 Richard Henderson <rth@cygnus.com>
+
+ * read.c (get_line_sb): Accept any eol marker while scanning macros.
+
+Tue Oct 14 19:12:45 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.h (DIFF_EXPR_OK): Define.
+ * config/tc-i386.h (DIFF_EXPR_OK): Define.
+ * config/tc-alpha.c (md_apply_fix): Notice fx_pcrel and substitute
+ the correct relocation when it exists.
+ * config/tc-i386.c (md_apply_fix3): Likewise.
+
+ * config/tc-ppc.h: Correct typo in comment.
+ * config/tc-v850.h: Likewise.
+
+Fri Oct 10 16:09:35 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/tc-d10v.c (parallel_ok): Allow parallel instruction issue
+ when second instruction is writing to first instructions inputs.
+
+Mon Oct 13 15:27:17 1997 Richard Henderson <rth@cygnus.com>
+
+ * ecoff.c (PAGE_SIZE): Double to 8k as a hack to allow some C++
+ templated programs to build with -g.
+
+Fri Oct 10 17:48:29 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_relax_table): Add support for relaxing
+ unconditional branches. This patch is courtesy of Jim Wilson.
+ (md_convert_frag): Fix relaxing of branches. This patch is
+ courtesy of Jim Wilson.
+ (md_assemble): Create different fixups for conditional and
+ unconditional branches. This patch is courtesy of Jim Wilson.
+ (md_estimate_size_before_relax): Estimate size of variable part of
+ fixup based on whether it is for a conditional or an unconditional
+ branch. This patch is courtesy of Jim Wilson.
+ (v850_sdata, v850_tdata, v850_zdata, v850_sbss, v850_tbss,
+ v850_zbss, v850_rosdata, v850_rozdata, v850_bss): Add call to
+ obj_elf_section_change_hook().
+ (v850_comm): New function.
+ (md_pseudo_table): Add new pseudo ops .zcomm, .scomm and .tcomm.
+ (md_begin): Add bss flag to seg_info of bss sections.
+
+ Add support for .scommon, .tcommon and .zcommon sections.
+
+ * config/tc-v850.h (ELF_TC_SPECIAL_SECTIONS): Add .scommon,
+ .zcommon, .tbss, .call_table_data and .call_table_text.
+
+Fri Oct 10 15:01:14 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.in (sparc): Set DEFAULT_ARCH from correct target.
+ * configure: Regenerated.
+
+Fri Oct 10 11:22:45 1997 Martin M. Hunt <hunt@cygnus.com>
+
+ * config/tc-d10v.c: Fixes to make sure the AT_WORD
+ expression is not confused with -1.
+
+Fri Oct 10 11:54:50 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/tc-d10v.c (parallel_ok): Flag SP as modified for @-sp
+ operand - OPERAND_ATMINUS.
+
+Fri Oct 10 00:47:44 1997 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-d10v.c (parallel_ok): Note that auto increment and
+ decrement modify the index register.
+
+Thu Oct 9 15:17:50 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Robin Kirkham <Robin.Kirkham@mlb.dmt.csiro.au>:
+ * config/tc-m68k.c (archs): Add 68306, 68307, 68322, 68356, 68334,
+ 68336, 68341, 68349.
+ * doc/c-m68k.texi (M68K-Opts): Add -m68ec000 -m68hc000 -m68hc001
+ -m68306, -m68307, -m68322, -m68356, -m68ec020, -m68ec030,
+ -m68ec040, -m68ec060, -m68330, -m68334, -m68336, -m68341,
+ -m68349.
+
+ * doc/Makefile.am (CPU_DOCS): Define.
+ (as.info): Depend upon $(CPU_DOCS).
+ * doc/Makefile.in: Rebuild.
+
+ * configure.in: Remove AM_PROG_INSTALL; it's called by
+ AM_INIT_AUTOMAKE.
+ * configure: Rebuild.
+
+Thu Oct 9 01:44:36 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-d10v.h (TC_START_LABEL): Don't define.
+ (tc_frob_label): Define.
+
+Thu Oct 9 00:07:23 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-d10v.c (write_2_short): Fix bug that wouldn't allow
+ to pair a branch and link with anything but an exe instruction.
+
+Wed Oct 8 16:28:53 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (load_expression): Disable the sym+const .got
+ optimization to reduce the alignment surprises for gcc.
+
+Wed Oct 8 16:11:15 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/obj-coff.h (TC_SPARC): Don't define TARGET_FORMAT.
+ * config/tc-sparc.c (sparc_target_format): Handle coff here.
+ (sparc_ip): Add %hix,%lox.
+ (md_apply_fix3): Call as_bad_where, not as_bad.
+ Add support for BFD_RELOC_SPARC_{HIX22,LOX10}.
+ (tc_gen_reloc): Add support for BFD_RELOC_SPARC_{HIX22,LOX10}.
+
+Wed Oct 8 12:33:32 1997 Richard Henderson <rth@cygnus.com>
+
+ * configure.in: Change alpha-*-* to alpha*-*-*; config.guess now
+ recognizes alphaev5 etc.
+ * configure: Rebuild.
+
+Wed Oct 8 00:04:05 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (md_begin): Replace the TARGET_CPU value
+ of mipsr3900 with mipstx39.
+
+ * config/tc-mips.c (mips_ip): Don't print the 'opcode requires
+ -mipsXX message' if the insn isn't an ISA insn.
+
+Tue Oct 7 12:48:30 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-sparc.h (TARGET_FORMAT support): Moved to tc-sparc.c.
+ Redefine TARGET_FORMAT to call sparc_target_format.
+ * config/tc-sparc.c (in_unsigned_range): New function.
+ (sparc_arch_size): Make static.
+ (sparc_target_format): New function.
+ (sparc_ip): Delete variable immediate_max. Rewrite %hi/etc reloc
+ handling. Add support for %hh,%hm,%lm,%h44,%m44,%l44.
+ (output_insn): Set `fx_no_overflow'.
+ (md_apply_fix3): Handle BFD_RELOC_SPARC_{7,H44,M44,L44}.
+ (tc_gen_reloc): Likewise.
+
+Mon Oct 6 14:04:50 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (v850_section): Remove.
+
+ * config/obj-elf.c (obj_elf_section): Enhance error message.
+
+Fri Oct 3 15:40:38 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c: Undef OBJ_COPY_SYMBOL_ATTRIBUTES before
+ including obj-elf.h in OBJ_MAYBE_ELF case.
+ (mips_target_format): Return NULL after abort to avoid warning.
+
+ * ecoff.c (generate_ecoff_stab): Remove unused static function.
+
+ * expr.c (operator): Accept ==. From Anders Blomdell
+ <anders.blomdell@control.lth.se>.
+
+ * config/atof-ieee.c (gen_to_words): When generating a denormal
+ number, handle an overflow into the smallest normalized number.
+
+Mon Sep 29 15:24:52 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * as.h, input-scrub.c (new_logical_line): New return value.
+ * read.c (s_app_file): Don't note the same file several times
+ in a row.
+
+Thu Sep 25 13:08:02 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Remove ` operand specifier.
+
+Wed Sep 24 16:54:40 1997 Joel Sherrill <joel@oarcorp.com>
+
+ * configure.in (sh*-*-rtems*): New target, like sh-*-elf*.
+ * configure: Rebuild.
+
+Wed Sep 24 11:30:25 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Handle q and v operand specifiers.
+
+ * doc/c-i386.texi (i386-Float): Remove incorrect assertion that
+ fn* instructions do not insert implicit fwait. This was changed
+ Jan 29, 1996.
+
+ * config/m68k-parse.y (yylex): Permit an expression to be used for
+ the scale factor.
+
+ * Makefile.am (EXTRA_as_new_SOURCES): Set to config/m68k-parse.y,
+ not m68k-parse.y.
+ * Makefile.in: Rebuild.
+
+ * aclocal.m4: Rebuild with new libtool.
+ * configure: Rebuild.
+
+Tue Sep 23 17:48:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * app.c (do_scrub_chars): Clear mri_state at end of .mri
+ pseudo-op.
+
+ * config/tc-mips.c (hilo_interlocks): Change from a static
+ variable to a macro, so that it varies with the variables upon
+ which it depends.
+ (gpr_interlocks, cop_interlocks): Likewise.
+ (md_begin): Don't initialize them.
+
+Fri Sep 19 17:08:41 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_assemble): Use strcasecomp instead
+ of strcmp where appropriate.
+
+Thu Sep 18 14:11:56 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_assemble): Cope with a zero data area
+ relocation with a constant offset.
+ (md_assemble): Produce error message when special data area
+ relocations are used on instructions which do not support them.
+ (md_assemble): Reset processor mask if defined by command line
+ switch.
+
+Thu Sep 18 11:24:01 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-sparc.c: Reorganize file.
+ (parse_keyword_arg): Allow numbers in reg names.
+ (SPECIAL_CASE_NONE): New macro.
+ (md_assemble): Use it.
+ (lookup_arch,init_default_arch): New functions.
+ (default_arch,default_init_p,sparc_arch_table): New static locals.
+ (sparc_arch_size): New static local.
+ (max_architecture): Initialize in init_default_arch.
+ (md_parse_options): Call init_default_arch if necessary.
+ Rewrite -xarch/-A processing.
+ (md_show_usage): Print -A values from sparc_arch_table.
+ (md_begin): Call init_default_arch if necessary.
+ (sparc_md_end): Handle both 32 and 64 bit environments.
+ * config/tc-sparc.h (TARGET_FORMAT): Likewise.
+ * acconfig.h (SPARC_V9,SPARC_ARCH64): Delete.
+ (DEFAULT_ARCH): Add.
+ * config.in: Regenerate.
+ * configure.in (sparc): Default DEFAULT_ARCH based on target cpu.
+ (SPARC_V9,SPARC_ARCH64): Delete.
+ * configure: Regenerate.
+ * config/vms-conf.h (SPARC_V9,SPARC_ARCH64): Delete.
+
+Wed Sep 17 16:54:20 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (v850_reloc_prefix): Recoded to use CHECK_ ()
+ macro.
+ (handle_tdaoff, handle_zdaoff, handle_sdaoff): New functions.
+
+ * config/tc-v850.c (md_assemble): Corrected typo.
+ * config/tc-v850.c Add new sections: call_table_data and
+ call_table_text.
+ (v850_reloc_prefix): Add support for ctoff() relocation prefix.
+ (handle_ctoff): New Function.
+
+ * doc/c-v850.texi (V850 Opcodes): Document call table relocations.
+
+Tue Sep 16 14:18:22 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (v850_reloc_prefix): Add support for a 16 bit
+ displacement from the tiny data area pointer.
+
+Mon Sep 15 21:28:09 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (fix_new_hppa): Make declaration match
+ definition.
+
+Mon Sep 15 18:33:06 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (processor_mask): New variable.
+ (set_machine, md_parse_option): Set processor_mask.
+ (md_assemble): Check that instruction is available to target
+ processor.
+
+ * config/tc-v850.h (TARGET_PROCESSOR): New constant.
+
+Mon Sep 15 11:28:04 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ Merge in work from Martin Hunt:
+
+ * config/tc-d30v.c (build_insn): For mvfsys and mvtsys,
+ CR is 0 for PSWL and PSWH.
+
+ * config/tc-d30v.c (do_assemble): Don't accept
+ illegal condition codes for cmpu instruction.
+
+ * config/tc-d30v.c: Add support for BFD_RELOC_D30V_9_PCREL
+ used in d*i instructions.
+
+ * config/tc-d30v.c (check_size): New function. Check
+ relocations for overflows.
+ (md_pcrel_from_section): Fix relocations between sections.
+ (md_apply_fix3): Use new relocation types for 15 and 21
+ bit relocations in the right container. Needed because
+ the address of the instruction is not eight-byte aligned
+ but the relocations must be.
+
+ * config/tc-d30v.c (md_apply_fix3): Check for overflow.
+ (find_format): If ".s" or ".l" are used, don't try
+ to compute branch sizes.
+
+ * config/tc-d30v.c (do_assemble): Check for ".s" or
+ ".l" extensions to opcode names.
+ (find_format): Generate the correct instructions when
+ ".s" or ".l" are used.
+
+ * config/tc-d30v.c (build_insn): Check for odd registers
+ on instructions that require even registers.
+
+ * config/tc-d30v.h (md_start_line_hook): Define.
+ * config/tc-d30v.c (md_start_line_hook): New hook.
+ Checks the beginning of each line for a ".". If it
+ finds one, assume a pseudo-op and flush any unwritten
+ instructions.
+
+ * config/tc-d30v.c (md_apply_fix3): Fix problem
+ with determining when fixups were done.
+
+ * config/tc-d30v.c (build_insn): Fix bug where the numeric
+ part of a symbol (for example, "foo+8") was being written
+ into the instruction.
+ (md_pseudo_table): Change .word to be 32 bits and add
+ .hword as 16 bits.
+
+ * config/tc-d30v.c (parallel_ok): Check to see if first
+ instruction is a jump.
+
+ * config/tc-d30v.c (parallel_ok): Major code reorganization.
+
+Wed Sep 10 10:07:08 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_assemble): Corrected spelling mistake.
+ * configure.in (emulations): Add v850 emulation.
+
+Tue Sep 9 17:14:33 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.am (CPU_TYPES): Add arc.
+ (TARGET_CPU_CFILES): Add tc-arc.c.
+ (TARGET_CPU_HFILES): Add tc-arc.h.
+ (dependencies): Rebuild.
+ * Makefile.in: Rebuild.
+ * configure.in: Recognize arc-*-elf*.
+ * configure: Regenerated.
+ * config/tc-arc.[ch]: New files.
+
+Tue Sep 9 10:19:37 1997 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-v850.texi (V850 Opcodes): Document hi0() reloc prefix.
+ Correct description of hi() reloc prefix.
+
+ * doc/c-v850.texi (V850 Opcodes): Document new reloc prefix.
+ * config/tc-v850.c (v850_reloc_prefix): Add hilo() reloc prefix.
+ * config/tc-v850.c (md_assemble): Add support for BFD_RELOC_32.
+
+ * doc/c-v850.texi: Document new pseudo ops and command line
+ options.
+
+ * config/tc-v850.c (set_machine): New function.
+ * config/tc-v850.c (.v850): New pseudo op.
+ * config/tc-v850.c (.v850e): New pseudo op.
+ * config/tc-v850.c (.v850ea): New pseudo op.
+
+
+Mon Sep 8 23:08:04 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Support -alh and -ald for DWARF 1:
+ * listing.c (struct list_info_struct): Add debugging field.
+ (listing_newline): Initialize the debugging field. If ELF, if the
+ section starts with .debug or .line, set the debugging field in
+ the listing structure.
+ (debugging_pseudo): Add list parameter. Change all callers. If
+ the debugging field is set, consider it to be a debugging pseudo.
+ If ELF, skip blank lines between debugging lines.
+ * read.c (emit_expr): If ELF, look for line numbers.
+ (stringer): If ELF, look for file names.
+
+Mon Sep 8 12:33:40 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (v850_insert_operand): Only test for overflow
+ if there is no insert function.
+
+ * config/tc-v850.h (TARGET_MACHINE): New constant.
+
+ * config/tc-v850.c (v850_insert_operand): Add
+ -mwarn_unsigned_overflow.
+ (md_begin): Set BFD machine number based on machine variable.
+ (md_parse_option): Add -mv850, -mv850e and -mv850ea options.
+
+Mon Sep 8 11:20:46 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.h: Don't declare alloca if it is a macro.
+ * macro.c: Likewise.
+
+Sun Sep 7 00:30:19 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (md_parse_option): Move m[] out to top level and
+ rename to cpu_types[].
+ (s_alpha_arch): New function.
+ (md_pseudo_table): Add "arch".
+
+ * config/tc-alpha.c (md_begin): Merge the two loops through the
+ opcode table.
+ (s_alpha_proc): Add initial SKIP_WHITESPACE.
+ (s_alpha_set): Likewise. Use get_symbol_end instead local while loop.
+
+Sat Sep 6 19:38:12 1997 Fred Fish <fnf@cygnus.com>
+
+ * read.h (s_lcomm_bytes): Add prototype (for real this time).
+
+Thu Sep 4 12:10:01 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-elf.c (elf_frob_symbol): Only set BSF_OBJECT for
+ symbols on Irix.
+
+Wed Sep 3 11:21:33 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c: Remove BFD_RELOC_V850_16_PCREL.
+
+Tue Sep 2 18:32:30 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_convert_frag): PC relative instructions arex
+ relative to the next instruction, not the current instruction.
+ (md_assemble): Similarly.
+
+Tue Sep 2 15:58:52 1997 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-v850.texi: Explanations of offsets in SDA/ZDA areas
+ correcetd.
+
+ * config/tc-v850.c: Add support for SDA/TDA/ZDA sections.
+ (v850_reloc_prefix): Duplicate code eliminated. Add code to
+ recognise special instructions.
+ (md_assemble): Calculation of the size of a fixups corrected.
+
+ * config/tc-v850.h (ELF_TC_SPECIAL_SECTIONS): Add SDA/TDA/ZDA
+ sections.
+
+Tue Sep 2 15:40:56 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/tc-v850.c (md_assemble): Use opcode->name instead of
+ opcode->opcode as the sentinal. Zero is a valid opcode.
+
+Tue Aug 26 16:51:14 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo (Machine Dependencies): Add v850 to menu.
+ * doc/c-v850.texi: Change node name to match other chapter nodes.
+
+Tue Aug 26 09:46:22 1997 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-v850.texi (V850 Opcodes): Correct name for tiny data area
+ pointer.
+
+Tue Aug 26 12:23:25 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * expr.c (integer_constant): If BFD64, don't make a bignum if the
+ number will fit in 64 bits.
+
+ * config/tc-alpha.c (load_expression): Check explicitly for O_big,
+ rather than calling abort.
+
+ * as.h: Don't define alloca if __GNUC__. Just declare it.
+ * macro.c: Copy alloca handling from as.h.
+
+ * config/tc-i386.c (i386_align_code): Correct 16 bit noops. From
+ Gabriel Paubert <paubert@iram.es>.
+
+ * config/tc-i386.c (md_assemble): In JumpByte case, when looking
+ for a WORD_PREFIX_OPCODE, change it to ADDR_PREFIX_OPCODE if this
+ is jcxz or a loop instruction.
+
+Mon Aug 25 16:04:14 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (pre_defined_registers): Add 'hp' as alias for
+ r2.
+ (md_begin): Set up machine architecture and type.
+
+Mon Aug 25 14:25:48 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (resolve_symbol_value): Store the value back into the
+ symbol expression, to handle add or subtract simplification
+ correctly. Handle O_symbol_rva. Add default case.
+
+ * config/tc-ppc.c (ppc_change_csect): Temporarily lower the
+ chunksize while creating the new subsection.
+ * as.c (chunksize): Initialize to zero.
+ * subsegs.c (subseg_set_rest): Change 5000 to chunksize when
+ calling obstack_begin.
+
+Mon Aug 25 11:21:48 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_assemble): Restore input_line_pointer upon
+ exit.
+
+ * config/tc-v850.c (parse_register_list): Support constant
+ expressions as register lists.
+
+Mon Aug 25 10:19:34 1997 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-v850.texi: Change the major node to v850 Machine
+ Dependencies.
+
+Fri Aug 22 11:16:14 1997 Nick Clifton <nickc@cygnus.com>
+
+ * doc/as.texinfo: Add inclusion of c-v850.texi
+
+ * doc/c-v850.texi: New file.
+
+ * read.c (is_end_of_line): Make NUL character be considered to be
+ a line terminator.
+
+Fri Aug 22 10:45:33 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (parse_register_list): Add support for curly
+ brace syntax.
+ (cc_names): Add "e" and "ne" conditions.
+
+Thu Aug 21 11:00:36 1997 Nick Clifton <nickc@cygnus.com>
+
+ * app.c (do_scrub_chars): Support a double dash as starting a
+ comment that extends to end of line.
+
+Thu Aug 21 10:54:27 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (v850_section, v850_bss, v850_offset): New
+ functions.
+ (md_pseudo_table): New pseudo ops: .bss, .offset, .section
+
+Thu Aug 21 00:59:53 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-m32r.c (md_estimate_size_before_relax): Update recorded
+ insn when changing to a different instruction.
+
+Wed Aug 20 00:45:20 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-sh.c (parse_reg, get_specific, build_Mytes): Add SH4
+ floating point extensions.
+ (parse_reg): parse sgr and dbr.
+
+Tue Aug 19 17:07:34 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (system_register_name): Support numbers for
+ system register IDs.
+
+Tue Aug 19 08:59:12 1997 Fred Fish <fnf@cygnus.com>
+
+ * read.c (s_lcomm_internal): Renamed from s_lcomm, added arg to
+ flag when alignment is in bytes instead of power of 2, and code to
+ use that flag to convert alignment to bytes.
+ (s_lcomm, s_lcomm_bytes): New helpers that call s_lcomm_internal.
+ * read.h (s_lcomm_bytes): Add prototype.
+ * config/obj-coff.c (write_object_file): If ALIGNMENT_IN_S_FLAGS is
+ defined, write alignment to alignment bits in section header s_flags
+ rather than the s_align field.
+ * config/obj-coff.h (ALIGNMENT_IN_S_FLAGS): Define for TC_TIC80.
+ * config/tc-tic80.c (md_pseudo_table): Use s_lcomm_bytes for bss
+ pseudo, instead of s_lcomm which wants a power of two for alignment.
+
+Mon Aug 18 20:42:23 1997 Richard Henderson <rth@cygnus.com>
+
+ * macro.c (check_macro): use alloca instead of xmalloc to plug leak.
+
+Mon Aug 18 20:33:06 1997 Richard Henderson <rth@cygnus.com>
+
+ * as.c (show_usage): Add -am.
+ * input-scrub.c (input_scrub_include_sb): Don't add leading \n
+ if we've already got one.
+ * listing.c (struct list_info_struct): Add line_contents.
+ (listing_newline): Put unused argument to work: if non-null, save it...
+ (listing_listing): ... and regurgitate during listing instead of line
+ from file.
+ * listing.h (LISTING_MACEXP): New define.
+ (LISTING_NEWLINE): Argument is NULL.
+ * read.c (read_a_source_file): If expanding macros, break up input
+ lines and pass them to listing_newline.
+ * doc/as.texinfo: Document -ac and -am.
+
+ * cond.c (s_ifc): Add missing demand_empty_rest_of_line.
+
+Mon Aug 18 11:26:36 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_apply_fix3): Add support for new 16 bit PC
+ relative reloc.
+
+Mon Aug 18 11:24:21 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c: Remove support_v850e flag and command line
+ option.
+
+ * configure.in (emulations): Add support for v850e target
+
+ * configure (emulations): Add support for v850e target
+
+Mon Aug 18 11:24:21 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c: Remove support_v850ea flag and command line
+ option.
+
+ * configure.in (emulations): Add support for v850ea target
+
+ * configure (emulations): Add support for v850ea target
+
+Fri Aug 15 14:00:13 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (check-DEJAGNU): Don't cd into testsuite until after
+ setting EXPECT and TCL_LIBRARY.
+ * Makefile.in: Rebuild.
+
+ * as.h (enum debug_info_type): Define.
+ (debug_type): Declare.
+ * as.c (debug_type): New global variable.
+ (show_usage): Add --gstabs.
+ (parse_args): Handle --gstabs.
+ * read.c (generate_asm_lineno): Remove.
+ (read_a_source_file): Output stabs debugging if appropriate.
+ Change checks of generate_asm_lineno to check debug_type. Only
+ generate ECOFF debugging if ECOFF_DEBUGGING is defined.
+ * read.h (generate_asm_lineno): Don't declare.
+ (stabs_generate_asm_lineno): Declare.
+ * stabs.c (stabs_generate_asm_lineno): New function.
+ * ecoff.c (add_file): Use debug_type, not generate_asm_lineno.
+ Don't turn off debugging.
+ (add_file): Remove old #if 0 code.
+ (ecoff_new_file): Set debug_type, not generate_asm_lineno.
+ (ecoff_directive_end): Don't generate stabs line symbols.
+ (ecoff_generate_asm_lineno): Don't check stabs_seen. Don't set
+ generate_asm_lineno.
+ (line_label_cnt): Remove.
+ (ecoff_generate_asm_line_stab): Remove.
+ * ecoff.h (ecoff_generate_asm_line_stab): Don't declare.
+ * doc/as.texinfo, doc/as.1: Document --gstabs.
+
+Wed Aug 13 18:58:56 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_assemble, md_show_usage, md_parse_option):
+ Add support for v850ea instructions.
+
+ * config/tc-v850.c (md_assemble, md_show_usage, md_parse_option):
+ Add support for v850e instructions.
+
+ * config/tc-v850.c (md_assemble): Fix error recovery to reload
+ text of entire opcode.
+
+Tue Aug 12 10:27:34 1997 Richard Henderson <rth@cygnus.com>
+
+ * doc/internals.texi: Document rs_leb128.
+
+Tue Aug 12 12:17:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Give an error message for SIZE_BYTE
+ in ABSL case, rather than calling abort.
+
+Mon Aug 11 21:48:00 1997 Richard Henderson <rth@cygnus.com>
+
+ * as.h (enum _relax_state): Add rs_leb128.
+ * read.c (potable): Add sleb128 and uleb128.
+ (sizeof_*leb128, output_*leb128, emit_leb128_expr, s_leb128): New
+ functions.
+ * read.h: Update prototypes.
+ * symbols.c (resolve_symbol_value): Streamline quite a bit. Return
+ the symbol value, add a second FINALIZE argument that prevents
+ changes from being comitted. Update all callers.
+ * write.c (cvt_frag_to_fill, relax_segment): Handle rs_leb128.
+ * doc/as.texinfo: Document the new pseudos.
+
+Sun Aug 10 14:51:49 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (MOSTLYCLEANFILES): Add site.bak, site.exp, stage,
+ stage1, and stage2.
+ (DISTCLEANFILES): Define.
+ * doc/Makefile.am (DISTCLEANFILES): Define.
+ * Makefile.in, doc/Makefile.in: Rebuild.
+
+Wed Aug 6 00:30:30 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Define TARGET_BYTES_BIG_ENDIAN if endian is set.
+ Don't set targ or gas_target. Define SCO_ELF and
+ TARGET_SOLARIS_COMMENT when appropriate. Don't substitute for
+ target_frag.
+ * Makefile.am: Remove @target_frag@.
+ (INCLUDES): Remove $(INTERNAL_CFLAGS), $(CROSS), $(HDEFINES), and
+ $(TDEFINES).
+ (dep-am): Mark as phony.
+ * acconfig.h: Add TARGET_BYTES_BIG_ENDIAN, TARGET_SOLARIS_COMMENT,
+ and SCO_ELF.
+ * config/arm-big.mt, config/arm-lit.mt: Remove.
+ * config/mips-big.mt, config/mips-lit.mt: Remove.
+ * config/ppc-big.mt, config/ppc-lit.mt: Remove.
+ * config/ppc-sol.mt: Remove.
+ * config/i386coff.mt, config/m68kcoff.mt: Remove.
+ * config/m88kcoff.mt: Remove.
+ * config/sco5.mt: Remove.
+ * configure, config.in, Makefile.in: Rebuild.
+
+ * Makefile.am ($(srcdir)/config/m68k-parse.h): New target, to
+ further try to circumvent the .y.h rule.
+ * Makefile.in: Rebuild.
+
+Tue Aug 5 12:32:07 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: New file, based on old Makefile.in.
+ * acinclude.m4: New file, from old aclocal.m4.
+ * configure.in: Call AM_INIT_AUTOMAKE and AM_PROG_LIBTOOL. Remove
+ shared library handling; now handled by libtool. Replace
+ AC_CONFIG_HEADER with AM_CONFIG_HEADER. Call AC_PROG_YACC,
+ AC_PROG_LEX, and AC_DECL_YYTEXT. Call AM_MAINTAINER_MODE,
+ AM_CYGWIN32, and AM_EXEEXT. Don't call CY_CYGWIN32 or CY_EXEEXT.
+ * config.in: New file, created by autoheader.
+ * conf.in: Remove.
+ * acconfig.h: Mention PACKAGE, VERSION, and USING_CGEN.
+ * stamp-h.in: New file.
+ * as.c (print_version_id): Change GAS_VERSION to VERSION.
+ (parse_args): Likewise.
+ * config/obj-vms.c: (Write_VMS_MHD_Records): Likewise.
+ * doc/Makefile.am: New file, based on old doc/Makefile.in.
+ * Makefile.in, doc/Makefile.in: Now built with automake.
+ * aclocal.m4: Now built with aclocal.
+ * configure: Rebuild.
+
+ * cond.c (s_else): If not listing false conditionals, turn listing
+ off in the false branch of the else.
+
+Mon Aug 4 11:28:35 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (macro): Fix handling of a double load from a
+ symbol plus an offset.
+
+ * ecoff.c (ecoff_build_symbols): Set fMerge to 0 for an FDR which
+ has an associated external symbol.
+
+Sun Aug 3 23:23:59 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (s_alpha_ucons): New function.
+ (md_pseudo_table): Add unaligned data pseudos for DWARF.
+
+Thu Jul 31 15:13:43 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_assemble): Ignore the rest of the current
+ line if we encounter an error.
+
+ * config/tc-v850.c (md_assemble): Sign extend constants value
+ for hi and hi0 expressions.
+ (v850_insert_operand): Enable range checking for generic 16bit
+ operands.
+
+Tue Jul 29 14:20:43 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_assemble): Turn on fx_no_overflow for
+ LO16, HI16 and HI16_S relocs.
+
+Mon Jul 28 18:41:41 1997 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * configure.in: Use CYGWIN and EXEEXT autoconf macro to look for
+ win32 dependencies.
+ * configure: Regenerated with autoconf 2.12.
+ * Makefile.in: Add $(EXEEXT) to all executables.
+
+Fri Jul 25 10:54:43 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (md_apply_fix): Improve warnings for out of range
+ unconditional branches.
+ (hppa_fix_adjustable): Don't adjust anything with a RR% or LR%
+ field selector.
+
+Thu Jul 24 15:21:49 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-sparc.c (md_begin): Cast sparc_opcodes to PTR for hash_insert.
+
+Thu Jul 24 17:51:29 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * macro.c (define_macro): Make sure the index is in range before
+ checking for '('.
+
+Thu Jul 24 12:13:19 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (build_insn): Remove "extended" and replace with
+ "fx" and "fxfrag". Add "ffrag". Change code to initialize and use
+ the right f/ffrag and fx/fxfrag pairs since instruction may be split
+ across frags.
+
+Tue Jul 22 18:38:56 1997 Robert Hoehne <robert.hoehne@Mathematik.TU-Chemnitz.DE>
+
+ * config/te-go32.h (USE_ALIGN_PTWO): Define.
+ * config/tc-i386.c (md_pseudo_table): If USE_ALIGN_PTWO is
+ defined, use s_align_ptwo for .align.
+ * configure.in (i386-*-msdosdjgpp*): New target.
+ (i386-*-go32*): Set em to go32 and targ to coffgo32.
+ * configure: Rebuild.
+
+Tue Jul 22 12:41:40 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-sparc.c (last_opcode): New static local.
+ (md_assemble): Don't issue "FP branch in delay slot" warning if
+ the delay slot has been annulled.
+
+Tue Jul 22 13:25:13 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (md_apply_fix_2): Check for PC relative reloc
+ code if BFD_ASSEMBLER.
+
+Mon Jul 21 08:57:17 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (system_registers): Fix ordering of registers.
+
+Tue Jul 15 16:29:54 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (build_insn): Initialize extended word to zero
+ when it will be filled in later by relocation information.
+
+Mon Jul 14 23:10:58 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (macro_build): Restore check of fmt argument.
+ (mips_ip): Fix ISA checks.
+
+Mon Jul 14 19:30:55 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (build_insn): Fix endianness problem with
+ O_big operands.
+
+Sun Jul 13 20:43:46 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (check_absolute_expr): Change warning to
+ error.
+
+Fri Jul 11 10:18:47 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (macro_build): Refine code to check if an
+ instruction is available on a particular cpu variant.
+ (mips_ip): Likewise.
+
+Mon Jul 7 22:53:08 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Change ifndef
+ OBJ_AOUT to ifdef OBJ_ELF.
+ (md_apply_fix3): When mangling 32 bit PC relative reloc for
+ BFD_ASSEMBLER, handle one ELF case for COFF as well, and add a PE
+ case.
+ * write.c (fixup_segment): Change special case for i386-coff to
+ not apply for i386-pe.
+ * config/obj-coff.c (coff_adjust_section_syms): Only count fixups
+ which were not done.
+ (coff_frob_file_after_relocs): Rename from coff_frob_file.
+ (coff_format_ops): Initialize frob_file_after_relocs field rather
+ than frob_file field.
+ * config/obj-coff.h (coff_frob_file): Don't declare.
+ (coff_frob_file_after_relocs): Declare.
+ (obj_frob_file): Don't define.
+ (obj_frob_file_after_relocs): Define.
+ * configure.in: Set bfd_gas to yes for i386-*-cygwin32.
+ * configure: Rebuild.
+
+Wed Jul 2 12:05:00 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): Never subtract section
+ address from PC relative reloc which will be fully resolved.
+
+Tue Jul 1 15:23:07 1997 Jeffrey A Law (law@cygnus.com)
+
+ * ecoff.c (page_type): Renamed from page_t to avoid conflict
+ with hpux10 header files.
+
+Mon Jun 30 12:27:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Jason Merrill <jason@cygnus.com>:
+ * read.c (do_align): If BFD_ASSEMBLER, only use NOP_OPCODE if
+ SEC_CODE is set.
+ * config/tc-i386.h (md_maybe_text): Define.
+ (md_do_align): Use md_maybe_text.
+
+Fri Jun 27 19:15:27 1997 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.h (tc_fix_adjustable): Only check for GOT type
+ relocations, don't check for symbol being external, weak, etc.
+
+Mon Jun 16 19:12:51 1997 Geoff Keating <geoffk@ozemail.com.au>
+
+ * config/tc-ppc.h (tc_fix_adjustable): Don't let the assembler
+ calculate relocations to any external symbol, because we might be
+ linking a shared object and the symbol might be overriden or moved
+ (for instance, moved into a static executable's .bss section).
+ (GLOBAL_OFFSET_TABLE_NAME): Delete. This is an i386 wierdness.
+
+ * config/tc-ppc.h (tc_fix_adjustable): GOT-based relocations can't
+ be calculated by the assembler.
+
+ * config/tc-ppc.c (md_apply_fix3): Handle @plt or @local branch
+ whose destination lies in the same file, by ignoring the @plt or
+ @local and aiming the branch at its destination.
+
+Mon Jun 16 13:59:18 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * symbols.c (copy_symbol_attributes): Copy BSF_OBJECT flag.
+ * config/obj-elf.h (OBJ_COPY_SYMBOL_ATTRIBUTES): Copy size
+ expression.
+
+ * config/obj-multi.h (OBJ_COPY_SYMBOL_ATTRIBUTES): Define instead
+ of obj_copy_symbol_attributes.
+
+Mon Jun 16 12:45:56 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_insert_operand): In 32 bit mode, with a
+ signed operand, sign extend a 32 bit value to the host size.
+
+ * Makefile.in (CFLAGS): Subsitute from configure script. From
+ Jeff Makey <jeff@cts.com>.
+
+ * config/tc-i386.c (i386_operand): Use alloca rather than a fixed
+ buffer size to make a copy of the symbol.
+
+ * Makefile.in (OBJS): Put @extra_objects@ on the same line as
+ macro.o.
+
+Thu Jun 12 12:16:20 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (write_object_file): In non BFD_ASSEMBLER code, as we
+ step through the frags calling cvt_frag_to_fill, switch to
+ SEG_DATA when we reach data_frag_root.
+
+Tue Jun 10 17:08:34 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_assemble): Allow an empty register
+ list for instructions which use register lists.
+
+Tue Jun 10 11:18:09 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * config/tc-arm.c (md_apply_fix3): Make temp unsigned long.
+
+ * config/tc-arm.c (arm_adjust_symtab): Only set storage classes if
+ OBJ_COFF.
+
+ * config/tc-arm.c: Add prototypes for many static functions.
+ (struct asm_opcode ): Add prototypes for parms field.
+ (struct thumb_opcode ): Likewise.
+ (fp_op2): Remove unused flags parameter.
+ (output_inst): Make static.
+ (arm_after_pass_hook): Remove unused ignore parameter.
+ * config/tc-arm.h (arm_after_pass_hook): Declare.
+ (arm_start_line_hook): Declare.
+ (arm_frob_label): Declare.
+
+Mon Jun 9 12:55:45 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * depend.c (wrap_output): new prototype.
+
+Mon Jun 9 12:52:44 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (md_apply_fix): Check for overflow.
+
+ * config/tc-m68k.c (md_section_align): If a.out and BFD, force
+ section size to be aligned.
+
+Fri Jun 6 17:15:55 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.h (md_cons_align): Define.
+ (sh_cons_align): Declare.
+ * config/tc-sh.c (md_pseudo_table): Add .uaword and .ualong.
+ (sh_no_align_cons): New static variable.
+ (s_uacons): New static function.
+ (sh_cons_align): New function.
+ (sh_handle_align): Warn about misaligned data.
+ * doc/c-sh.texi: Document .uaword and .ualong.
+
+Thu Jun 5 15:38:17 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * macro.c (macro_expand): In MRI mode, treat single quote as a
+ separator character when checking for a positional argument.
+
+Tue Jun 3 16:15:13 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_parse_option): Merge in changes from
+ armT-970328-branch.
+
+ * config/tc-arm.h: Merge in changes from armT-970328-branch.
+
+ * configure.in (emulations): Add Thumb architecture support from
+ armT-9703-28-branch.
+
+Mon Jun 2 16:25:07 1997 Nick Clifton <nickc@cygnus.com>
+
+ * doc/all.texi: Add enabling of ARM documentation.
+
+ * doc/as.texinfo: Add ARM documentation from armT-970328-branch.
+
+Mon Jun 2 11:55:12 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c: Added r3900 support.
+
+Thu May 29 12:58:26 1997 Ben Pfaff <pfaffben@pilot.msu.edu>
+
+ * as.c: (parse_args) `-t' option requires an argument.
+
+Wed May 28 15:45:07 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_begin): Change call to
+ coff_arm_bfd_set_private_flags() to a call to
+ bfd_set_private_flags().
+
+Wed May 28 16:17:34 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Rebuild dependencies.
+
+ * config/tc-i386.c (tc_gen_reloc): Don't try to convert the type
+ of a BFD_RELOC_RVA reloc.
+
+Wed May 28 10:48:14 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (tc_fix_adjustable): Reject absolute calls/jumps.
+ (hppa_force_relocation): Force a relocation for an absolute
+ call/jump.
+
+Mon May 26 13:24:25 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo: Don't use @value in section names or index
+ entries; it confuses texinfo.tex.
+
+Fri May 23 00:09:35 1997 Tom Tromey <tromey@cygnus.com>
+
+ * doc/as.texinfo: Updated for -MD option.
+ * Makefile.in (CFILES): Added depend.c.
+ (OBJS): Added depend.o.
+ * as.h (start_dependencies, register_dependency,
+ print_dependencies): New declarations.
+ * depend.c: New file.
+ * as.c (parse_args): Added -MD option.
+ (main): Call print_dependencies.
+ (show_usage): Added help for -MD.
+ * read.c (s_app_file): Call register_dependency.
+ (s_include): Call register_dependency when file is found.
+ (read_a_source_file): Call register_dependency.
+
+Wed May 21 17:39:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (symbol_to_chars): If TE_PE, don't add the
+ section address to the symbol value.
+
+Tue May 20 11:23:31 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (macro_build,mips_ip): Move the INSN_ISA field
+ into the new membership field.
+
+Thu May 15 10:00:53 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_begin): If no cpu type is specified on the
+ command line then the ARM7 is now chosen by default when setting
+ the BFD machine and architecture.
+
+Wed May 14 09:54:53 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (global variables): Added 'uses_apcs_26' flag to
+ hold APCS selection.
+ (md_begin): Added code to generate flags to be set into the COFF
+ header and the calls to the BFD functions to do this.
+ (md_parse_option, md_show_usage): Added new command line
+ options -mapcs-32, -mapcs-26, -marmv2, -marmv2a, -marmv3,
+ -marmv3m, -marmv4, -marmv4t.
+
+ * config/tc-arm.h (LOCAL_LABEL): Removed the definition of this macro
+ as it is never used.
+
+Tue May 13 22:26:14 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_convert_frag): Prefix temporary
+ label name with ".".
+ * config/tc-mn10300.c (md_convert_frag): Likewise.
+
+Tue May 13 14:44:39 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (set_at): Check for bignum.
+ (check_absolute_expr, macro, mips16_macro): Likewise.
+
+Tue May 13 10:45:56 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (md_apply_fix): Check PC relative relocations
+ for overflow/underflow, only insert lower 15 bits into instruction.
+
+Mon May 12 13:33:08 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * config/tc-i386.c (pi): Check for RegMMX.
+
+Thu May 8 11:10:15 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * expr.c (expr): When subtracting values in the same frag,
+ subtract X_add_number rather than adding it.
+
+Wed May 7 15:39:48 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (write_object_file): Just pass NULL to
+ md_do_align, not the address of a char holding NOP_OPCODE.
+
+ * config/tc-mips.c (macro): Handle constants for M_LI_D and
+ M_LI_DD.
+ (mips_ip): For 'F', 'L', 'f', and 'l', generate a constant rather
+ than an address if the floating point value looks sufficiently
+ simple.
+
+Tue May 6 12:18:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (md_section_align): If a.out and BFD, force
+ section size to be aligned.
+
+Mon May 5 17:16:55 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * cond.c: Include "macro.h".
+ (struct conditional_frame): Add macro_nest field.
+ (initialize_cframe): Initialize macro_nest.
+ (cond_finish_check): Add nest parameter. Change all callers.
+ (cond_exit_macro): New function.
+ * as.h (cond_finish_check): Update declaration.
+ (cond_exit_macro): Declare.
+ * input-scrub.c (macro_nest): Make globally visible.
+ (input_scrub_next_buffer): Call cond_finish_check.
+ * macro.h (macro_nest): Declare.
+ * read.c (s_mexit): Call cond_exit_macro.
+
+ * config/tc-i386.h (RegMMX): Define.
+ * config/tc-i386.c (pi): Check for all register types.
+ (type_names): Add RegMMX.
+ (md_assemble): Handle RegMMX.
+
+Wed Apr 30 12:47:00 1997 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * config/obj-coff.c (c_section_symbol): Clear the LOCAL bit #ifdef
+ TE_DELTA.
+
+Tue Apr 29 20:23:10 1997 Jim Wilson <wilson@cygnus.com>
+
+ * config/tc-mips.c (nopic_need_relax): Add new parameter
+ before_relaxing. Use it when testing ecoff_extern_size.
+ (load_address, macro, md_estimate_size_before_relax): Fix all
+ callers.
+
+Tue Apr 29 19:54:36 1997 Richard Henderson <rth@tamu.edu>
+
+ * config/obj-elf.c (elf_pseudo_table): Add "subsection".
+ (obj_elf_subsection): New static function.
+
+Tue Apr 29 19:52:47 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (coff_header_append): Don't reset string_size
+ each time through the loop.
+
+Fri Apr 25 14:17:46 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * Makefile.in (DISTSTUFF): Add itbl-parse.h.
+
+Fri Apr 25 12:03:15 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/internals.texi (Porting GAS): Correct documentation for
+ current configure handling of targ-cpu.h, et. al.
+ (CPU backend): Document listing macros.
+
+ * listing.c (data_buffer): Set size based on other listing macros,
+ rather than always using 100.
+ (data_buffer_size): Remove static variable.
+ (calc_hex): Make data_buffer_size a local variable. Don't leave
+ any slop when filling data_buffer.
+
+Mon Apr 21 15:33:19 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/c-mips.texi: Document .set autoextend.
+
+Sat Apr 19 23:09:25 1997 Niklas Hallqvist <niklas@petra.appli.se>
+
+ * configure.in (i386-*-openbsd*, m68k-*-openbsd*,
+ mips-dec-openbsd*, ppc-*-*bsd*, ns32k-pc532-openbsd*,
+ sparc-*-openbsd*): New targets.
+ * configure: Rebuild.
+
+Sat Apr 19 22:52:03 1997 Jim Wilson <wilson@cygnus.com>
+
+ * config/obj-elf.c (elf_frob_symbol): If TC_MIPS, set BSF_OBJECT
+ for all undefined symbols.
+
+Fri Apr 18 13:37:35 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_fix_adjustable): Handle zero length csects
+ correctly.
+
+Fri Apr 18 11:51:35 1997 Niklas Hallqvist <niklas@appli.se>
+
+ * configure.in (alpha*-*-openbsd*): New target.
+ * configure: Rebuild.
+
+Thu Apr 17 13:59:47 1997 Per Fogelstrom <pefo@openbsd.org>
+
+ * configure.in (mips-*-openbsd*): New target.
+ * configure: Rebuild.
+
+Wed Apr 16 12:31:24 1997 Martin Hunt <hunt@cygnus.com>
+
+ * config/tc-d30v.c (parallel_ok): Fix parallel checking
+ for instructions using conditional execution.
+
+Tue Apr 15 18:11:44 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (insn_uses_reg): Correct test for fpr pairs.
+
+Tue Apr 15 13:04:47 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (srcroot): Remove.
+ (INSTALL): Set to @INSTALL@.
+ (INSTALL_XFORM, INSTALL_XFORM1): Remove.
+ (all, dvi): Don't set srcroot.
+ (install): Depend upon as.new, gasp.new, and installdirs. Use
+ $(program_transform_name) directly, rather than using
+ $(INSTALL_XFORM) and $(INSTALL_XFORM1).
+ (installdirs): New target.
+ * doc/Makefile.in (INSTALL_XFORM1): Remove.
+ (install): Depend upon installdirs. Use $(program_transform_name)
+ directly, rather than using $(INSTALL_XFORM) and
+ $(INSTALL_XFORM1).
+ (installdirs): New target.
+ (install-info-as): Run mkinstalldirs.
+ (install-info-gasp): Likewise.
+
+Mon Apr 14 11:59:08 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (INSTALL): Change install.sh to install-sh.
+
+ * symbols.c (resolve_symbol_value): Check for division by zero.
+
+ From Thomas Graichen <graichen@rzpd.de>:
+ * Makefile.in: Always use $(SHELL) when running move-if-change.
+ * configure.in: Use ${CONFIG_SHELL} when running $ac_config_sub.
+ * configure: Rebuild.
+
+Thu Apr 10 14:40:00 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * cgen.c (cgen_parse_operand): Renamed from cgen_asm_parse_operand.
+ New argument `want'. Update enum cgen_parse_operand_result values.
+ Initialize if CGEN_PARSE_OPERAND_INIT.
+ * config/tc-m32r.c (md_begin): Set cgen_parse_operand_fn.
+ (md_assemble): Call cgen_asm_init_parse.
+ Update call to m32r_cgen_assemble_insn, call as_bad if assembly failed.
+
+Wed Apr 9 11:49:41 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Handle #j.
+
+Tue Apr 8 16:37:57 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_convert_frag): Create fixup at the
+ right address for call label:32,regs,imm.
+
+Mon Apr 7 14:58:22 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_subspace_start): If OBJ_ELF, then always return
+ zero.
+ * config/tc-hppa.h (tc_frob_symbol): Don't reset the value of the
+ symbol for OBJ_ELF anymore.
+
+Mon Apr 7 10:54:59 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in: Regenerate dependencies.
+ (TARG_CPU): New variable.
+ (cgen.o): Depend on cgen.h, $(TARG_CPU)-opc.h.
+ (.dep1): Delete creating of cgen-opc.h.
+ (.tcdep): Put proper contents in cgen-opc.h.
+ * configure.in (m32r): Delete setting of extra_files, extra_links.
+ (AC_OUTPUT): Create cgen-opc.h.
+ * configure: Regenerated.
+
+Sat Apr 5 13:19:12 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: Update to build gasp.exe.
+
+Fri Apr 4 16:10:02 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * write.c (relax_frag): Make non-static.
+ * write.h (relax_frag): Add prototype for.
+ * config/tc-m32r.h (md_do_align): New arg `max'.
+ * config/tc-m32r.c (m32r_do_align): Likewise.
+ Update calls to frag_align, frag_align_pattern.
+ (fill_insn): Update call to m32r_do_align.
+ (m32r_scomm): Update call to frag_align.
+
+ * config/tc-m32r.[ch]: New files.
+ * cgen.c: New file.
+ * Makefile.in (CPU_TYPES): Add m32r.
+ (TARGET_CPU_CFILES): Add tc-m32r.c.
+ (TARGET_CPU_HFILES): Add tc-m32r.h.
+ (DISTCLEAN_HERE): Add cgen-opc.h.
+ (.dep1,.tcdep): Create empty cgen-opc.h.
+ (cgen.o): Add dependencies.
+ (dependencies): Regenerate.
+ * as.h (struct frag): New member fr_targ.
+ (fr_pcrel_adjust,fr_bsr): Move into union fr_targ.ns32k.
+ * conf.in (USING_CGEN): New macro.
+ * configure.in (m32r-*-*): Add entry for.
+ Add cgen.o to extra_objects.
+ * configure: Regenerate.
+ * frags.c (frag_var): fr_pcrel_adjust renamed to
+ fr_targ.ns32k.pcrel_adjust. fr_bsr renamed to fr_targ.ns32k.bsr.
+ (frag_variant): Likewise.
+ * write.c (relax_frag): Likewise.
+ * config/tc-ns32k.c (*): Likewise.
+
+Fri Apr 4 13:26:10 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-hppa.h (TC_EOL_IN_INSN): Check explicitly for '!',
+ rather than for any end of line character.
+
+ * config/tc-hppa.c (tc_gen_reloc): If hppa_ren_reloc_type fails,
+ call abort (i.e., as_abort) rather than crashing.
+
+ * config/tc-mips.c: Protect uses of STO_MIPS16 with an ifdef of
+ OBJ_ELF, rather than of S_GET_OTHER.
+
+ * Makefile.in (DISTCLEAN_HERE): Add site.exp and site.bak.
+
+Thu Apr 3 13:16:18 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (VERSION): Set to 2.8.1.
+
+ * Branched binutils 2.8.
+
+Wed Apr 2 12:24:10 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * COPYING: Update FSF address.
+
+ * config/tc-mips.c (mips16_macro): Handle M_DMUL and M_MUL.
+
+Tue Apr 1 18:29:47 1997 Jim Wilson <wilson@cygnus.com>
+
+ * config/tc-mips.c (md_begin): Don't set interlocks for 4100.
+
+Tue Apr 1 16:24:28 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * config-gas.com: Update to handle both vax and alpha.
+ * makefile.vms: Update to use config-gas.
+ * conf-a-gas.com: Remove file.
+
+Tue Apr 1 16:08:21 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Remove unnecessary itbl-parse.h, ibtl-parse.c, and
+ itbl-lex.c dependencies. Remove rules for itbl-lex.o,
+ itbl-parse.o, and itbl-ops.o; just use the normal .c.o rule.
+
+Tue Apr 1 11:25:56 1997 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-tic80.c (line_comment_char): Make '#' start comments
+ at the beginning of a line for compatibility with .S files where
+ cpp leaves the filename transitions beginning with '#'.
+
+Tue Apr 1 00:07:30 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c: Only compile tc_coff_symbol_emit_hook and
+ tc_coff_sizemachdep if OBJ_COFF.
+
+Mon Mar 31 23:53:44 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * config/tc-ppc.c (register_name): Declare.
+
+Mon Mar 31 16:31:04 1997 Joel Sherrill <joel@oarcorp.com>
+
+ * configure.in (hppa*-*-rtems*): New target, like hppa-*-*elf*.
+ * configure: Rebuild.
+
+Mon Mar 31 14:15:19 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_pseudo_table): Add "stabn".
+ (mips16_mark_labels): New static function.
+ (append_insn): Call mips16_mark_labels.
+ (mips_emit_delays): Likewise.
+ (s_insn): Likewise. Don't call mips_clear_insn_labels.
+ (s_mips_stab): New static function.
+
+ * configure.in: Use ELF for mips-*-gnu*.
+ * configure: Rebuild.
+
+Mon Mar 31 14:01:40 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * config/tc-m68k.h (TARGET_FORMAT): Set to "coff-m68k-sysv" if
+ TE_DELTA.
+
+Fri Mar 28 18:03:19 1997 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * configure.in: Add AC_ARG_ENABLE for commonbfdlib. If it is set,
+ set OPCODES_LIB to empty.
+ * configure: Rebuild.
+
+Fri Mar 28 15:25:24 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * configure.in (sparc-*-linux*aout*, sparc-*-linux*): New
+ targets.
+ * configure: Rebuild.
+
+Fri Mar 28 13:08:33 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * itbl-parse.y (yyerror): Make static. Declare.
+
+ From Ralf Baechle <ralf@gnu.ai.mit.edu>:
+ * configure.in: Set emulations for mips-*-linux*-*.
+ * configure: Rebuild.
+
+ * config/tc-mips.c (struct mips_set_options): Define.
+ (mips_opts): New static variable.
+ (mips_isa): Remove. Now a field in mips_opts. Change all
+ references.
+ (mips16, mips16_autoextend, mips_warn_about_macros): Likewise.
+ (mips_noreorder, mips_nomove, mips_noat, mips_nobopt): Likewise.
+ (struct mips_option_stack): Define.
+ (mips_opts_stack): New static variable.
+ (s_mipsset): Add support for .set push and .set pop.
+ * doc/c-mips.texi: Document .set push and .set pop.
+
+ * config/obj-elf.c (obj_elf_section_change_hook): New function.
+ * config/obj-elf.h (obj_elf_section_change_hook): Declare it.
+ * config/tc-mips.c (s_change_sec): Call it if OBJ_ELF.
+
+Thu Mar 27 12:23:56 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.c (parse_args): Update copyright date in version message.
+
+ * Makefile.in (clean-here): Remove dependency files.
+
+ * read.c (s_comm): Check S_IS_COMMON as well as S_IS_DEFINED.
+ (s_mri_common): Check S_IS_COMMON unconditionally.
+ * symbols.c (colon): Check S_IS_COMMON as well as S_IS_DEFINED.
+ * config/tc-alpha.c (s_alpha_comm): Likewise.
+ * config/tc-mips.c (nopic_need_relax): Likewise.
+ * config/tc-ppc.c (ppc_elf_lcomm): Likewise.
+ (ppc_pe_comm): Likewise.
+ * config/obj-elf.c (obj_elf_common): Likewise. Set segment of
+ common symbol to bfd_com_section_ptr.
+ * config/tc-sparc.c (s_common): Likewise.
+ (tc_gen_reloc): Likewise.
+
+Thu Mar 27 00:29:46 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d30v.c (md_apply_fix3): Get the relocs right.
+
+Wed Mar 26 13:35:15 1997 H.J. Lu <hjl@lucon.org>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Only define if
+ BFD_ASSEMBLER.
+
+Wed Mar 26 11:32:51 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * input-scrub.c (input_scrub_next_buffer): Handle very long input
+ lines correctly.
+
+ * listing.c (print_lines): Add lineno parameter. Change all
+ callers.
+ (listing_listing): Only call calc_hex for the right line.
+ (listing_list): Set the new edict based on the current edict, in
+ order to handle listing commands in macros correctly.
+
+ * config/tc-mips.c (insn_uses_reg): Map register numbers in mips16
+ instructions.
+
+ * cond.c (cond_finish_check): New function.
+ * as.h (cond_finish_check): Declare.
+ * as.c (main): Call cond_finish_check.
+
+Tue Mar 25 14:45:54 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d30v.c (md_assemble): If two instructions
+ are supposed to be assembled in parallel and the first one is
+ long, print an error and stop.
+ (md_apply_fix3): Don't calculate absolute relocs. Just write
+ them out.
+
+Mon Mar 24 12:11:18 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.h (iclrKludge): Define.
+ * config/tc-i386.c (md_assemble): Handle iclrKludge.
+
+ * config/tc-alpha.h (tc_frob_file_before_adjust): Define if
+ OBJ_ECOFF.
+ (alpha_frob_file_before_adjust): Declare if OBJ_ECOFF.
+ * config/tc-alpha.c (alpha_debug): New static variable.
+ (md_parse_option): Set alpha_debug if -g is seen.
+ (alpha_frob_file_before_adjust): New function if OBJ_ECOFF.
+
+Sun Mar 23 18:03:31 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d30v.c (build_insn): Enable range-checking code.
+ (postfix): Stop at space or comma.
+ (md_assemble): Change error message.
+
+Sat Mar 22 13:44:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Added automatic dependency building.
+ * dep-in.sed: New file.
+
+Fri Mar 21 15:42:37 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-ieee.c (segment_name): Don't define function if this
+ is a macro.
+
+ * config/obj-coff.h (DO_STRIP): Don't define.
+ * config/tc-h8300.h (DO_STRIP): Don't define.
+ * config/tc-h8500.h (DO_STRIP): Don't define.
+ * config/tc-w65.h (DO_STRIP): Don't define.
+ * config/tc-z8k.h (DO_STRIP): Don't define.
+
+ * symbols.c (colon): Call obj_frob_label if it is defined.
+ * config/obj-vms.h (obj_frob_label): Rename from tc_frob_label.
+
+ * configure.in: Don't set files and links. Don't call
+ AC_LINK_FILES. Substitute te_file. Create targ-cpu.h,
+ obj-format.h, targ-env.h, and itbl-cpu.h in AC_OUTPUT.
+ * configure: Rebuild.
+ * Makefile.in (TARG_CPU_C): New variable.
+ (TARG_CPU_O, TARG_CPU_H): New variables.
+ (OBJ_FORMAT_C, OBJ_FORMAT_O, OBJ_FORMAT_H): New variables.
+ (TARG_ENV_H, ATOF_TARG_C, ATOF_TARG_O): New variables.
+ (SOURCES): Rename from REAL_SOURCES. Delete old definition.
+ (LINKED_SOURCES): Remove.
+ (HEADERS): Rename from REAL_HEADERS. Delete old definition.
+ (LINKED_HEADERS): Remove.
+ (OBJS): Use $(TARG_CPU_O), etc., rather than targ-cpu.o, etc.
+ ($(OBJS)): Depend upon $(TARG_ENV_H), etc., rather than
+ targ-cpu.h, etc.
+ ($(TARG_CPU_O), $(OBJ_FORMAT_O) $(ATOF_TARG_O)): New targets.
+ (targ-cpu.o, obj-format.o, atof-targ.o): Remove targets.
+ (itbl-cpu.h): Remove target.
+ (DISTCLEAN_HERE): Remove targ-cpu.c, obj-format.c, atof-targ.c,
+ atof-targ.h.
+
+Thu Mar 20 19:18:58 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo (Symbol Names): Don't use obsolete @ctrl macro.
+
+Thu Mar 20 16:49:14 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (mri_chip): Replace calls to get_symbol_end by
+ open coded loop that does not require the name to start with a
+ name beginner.
+
+Thu Mar 20 13:42:01 1997 H.J. Lu <hjl@lucon.org>
+
+ * frags.c (frag_var): Change offset parameter to offsetT.
+ (frag_variant): Likewise.
+ * frags.h (frag_variant, frag_var): Update declarations.
+ * config/tc-m68k.c (struct m68k_it): Change foff field to
+ offsetT.
+ (add_frag): Change off parameter to offsetT.
+ * Several files: Add casts to calls to frag_var.
+
+ * Makefile.in (m68k-parse.c): Depend upon itbl-parse.c, to
+ serialize a parallel make.
+ (itbl-parse.h): Split target out from itbl-parse.c.
+
+Thu Mar 20 12:48:45 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * config/m68k-parse.y (motorola_operand): Allow (zdireg,EXPR).
+
+ * config/te-delta.h (COFF_COMMON_ADDEND): Define.
+ * config/obj-coff.c (fixup_segment): Check COFF_COMMON_ADDEND when
+ storing the value of a common symbol.
+
+Wed Mar 19 11:37:57 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * config/obj-coff.c (glue_symbols): Unused variable symbolP
+ removed.
+ (crawl_symbols): Do not modify symbol_rootP and symbol_lastP here;
+ that is done by symbol_remove and symbol_insert.
+
+ * config/obj-coff.h (S_IS_LOCAL): Return 0 for a debugging
+ symbol.
+
+Wed Mar 19 11:06:29 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (load_register): In 32 bit mode, when not
+ dealing with a 64 bit number, permit the upper 32 bits to be set
+ even if bit 31 is not set.
+
+Tue Mar 18 23:30:14 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (potable): Add "equiv".
+ (s_set): Handle .equiv based on argument.
+ * doc/as.texinfo (Equiv): New node to document .equiv.
+ (Err): New node to document .err.
+
+Tue Mar 18 15:50:13 1997 H.J. Lu <hjl@lucon.org>
+
+ * Many files: Add function prototypes.
+ * as.c (show_usage, parse_args): Make static.
+ * frags.h (frag_alloc): Declare.
+ * subsegs.c (subseg_set_rest): Don't declare frag_alloc.
+ * symbols.c (dollar_label_instance): Change return type to long.
+ * symbols.h (print_symbol_value): Declare.
+ (print_expr, print_expr_1, print_symbol_value_1): Declare.
+ * write.c (fix_new_exp): Don't declare make_expr_symbol.
+ (remove_subsegs, relax_frag): Make static.
+ * config/atof-vax.c (atof_vax_sizeof): Change letter to int.
+ (what_kind_of_float): Likewise.
+ (atof_vax): Make static. Change what_kind to int.
+ (md_atof): Change what_statement_type to int.
+ * config/obj-ecoff.h (obj_ecoff_set_ext): Declare.
+ * config/tc-alpha.c (vax_md_atof): Declare.
+ (md_atof): Don't declare atof_ieee and vax_md_atof.
+ * config/tc-i386.c (set_16bit_code_flag): Make static.
+ * config/tc-i386.h (tc_i386_fix_adjustable): Declare.
+ * config/tc-m68k.c (add_fix): Change width to int.
+ (insert_reg): Change regname to const.
+ (md_atof): Don't declare atof_ieee.
+ (demand_empty_rest_of_line): Don't declare.
+ * config/tc-m88k.c (md_atof): Don't declare atof_ieee.
+ * config/tc-sparc.c (cmp_reg_entry): Change args to const PTR.
+ (parse_keyword_arg): Change lookup_fn to take const arg.
+ (md_atof): Don't declare atof_ieee.
+ * config/tc-sparc.h: Add ifdef for multiple inclusion.
+ (tc_aout_pre_write_hook): Don't declare.
+
+Mon Mar 17 11:21:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.h (bfd_alloc_by_size_t): Don't declare.
+ * Many files: Use xmalloc rather than bfd_alloc_by_size_t.
+
+Sun Mar 16 13:49:21 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * symbols.c (symbol_new): Don't call debug_verify_symchain.
+ (symbol_append): Set sy_next and sy_previous when adding a single
+ symbol to an empty list. Call debug_verify_symchain.
+ (verify_symbol_chain): Use assert, not know.
+
+Sat Mar 15 20:27:12 1997 Fred Fish <fnf@cygnus.com>
+
+ * NEWS: Note BeOS support.
+ * configure.in: (ppc-*-beos): New target, use coff as object format.
+ * configure: Regenerate with autoconf.
+
+Sat Mar 15 19:14:02 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_apply_fix): Improve error message for out
+ of range branch.
+
+ * Makefile.in: Add dependencies on obstack.h where needed.
+
+Fri Mar 14 15:33:38 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_estimate_size_before_relax): Handle the
+ case of a symbol equated to another symbol when using SVR4_PIC.
+
+ * Makefile.in (TARG_CPU_DEP_sparc): Add opcode/sparc.h.
+
+Thu Mar 13 11:20:51 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (read_a_source_file): Call LISTING_NEWLINE before
+ HANDLE_CONDITIONAL_ASSEMBLY when handling an MRI line label.
+
+ * config/obj-elf.c (obj_elf_data): Call md_flush_pending_output
+ and md_elf_section_change_hook if they are defined.
+ (obj_elf_text, obj_elf_previous): Likewise.
+
+Wed Mar 12 11:40:20 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-multi.h (struct elf_obj_sy): Define if
+ OBJ_MAYBE_ELF.
+ (OBJ_SYMFIELD_TYPE): Define as struct elf_obj_sy if
+ OBJ_MAYBE_ELF.
+ * config/obj-elf.h (struct elf_obj_sy): Don't define if
+ OBJ_SYMFIELD_TYPE is defined.
+
+ * doc/as.texinfo (bss): Improve description of .bss section. In
+ ELF or COFF, you are permitted to switch into the section.
+ (Comm): Rewrite description of common symbols.
+ (Lcomm): Mention that some targets permit a third argument.
+
+Tue Mar 11 01:13:31 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_lcomm): Don't call S_CLEAR_EXTERNAL.
+
+ * symbols.c (colon): Change type of local to int. From Alan Modra
+ <alan@spri.levels.unisa.edu.au>.
+
+ * config/tc-m88k.c (m88k_do_align): Don't use a special nop
+ alignment if a zero fill pattern was explicitly specified.
+ * config/tc-sh.c (sh_do_align): Likewise.
+
+ * read.c (equals): Always permit register names to be redefined.
+
+ * config/tc-mips.c (mips_fix_adjustable): Permit a reloc against a
+ mips16 symbol to be adjusted if a symbol is being subtracted from
+ it.
+
+ From Eric Youngdale <eric@andante.jic.com>:
+ * config/obj-elf.c (obj_elf_symver): Check for duplicate or
+ illegal symbol version names.
+ (elf_frob_symbol): Check for external default versions.
+
+Sun Mar 9 23:49:12 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Eric Youngdale <eric@andante.jic.com>:
+ * config/obj-elf.h (struct elf_obj_sy): Define.
+ (OBJ_SYMFIELD_TYPE): Define to elf_obj_sy struct. Change all
+ users.
+ * config/obj-elf.c (obj_elf_symver): Just record the name.
+ (obj_symbol_new_hook): Initialized versioned_name field.
+ (elf_frob_symbol): If there is a versioned_name, either rename the
+ symbol, or add an alias with that name.
+
+Thu Mar 6 13:55:32 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_relax_table): Define.
+ (md_convert_frag): Implement.
+ (md_assemble): Handle relaxable operands/instructions correctly.
+ (md_estimate_size_before_relax): Implement.
+ * config/tc-mn10300.h (TC_GENERIC_RELAX_TABLE): Define.
+
+ * config/tc-mn10200.c (md_relax_table): Fix typos.
+
+ * config/tc-mn10300.c (md_assemble): Don't use any MN10300 specific
+ relocs anymore. Tweak fx_offset for pc-relative relocs.
+
+Wed Mar 5 15:46:16 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * cond.c (s_ifc): Call mri_comment_field and mri_comment_end when
+ in MRI mode.
+
+Tue Mar 4 19:34:21 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (md_pseudo_table): Add "sect" and "section"
+ pseudo-ops.
+ * config/tc-tic80.c (md_begin): Declare external variable
+ coff_flags and insert an F_AR32WR bit into it.
+
+Tue Mar 4 10:01:04 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (equals): Add reassign parameter. Change all callers.
+ * read.h (equals): Update declaration.
+
+Sat Mar 1 01:04:04 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips16_extended_frag): Don't assume that we
+ can rely on the frag address to determine whether a frag is
+ earlier or later.
+
+Fri Feb 28 14:40:00 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.h (LOCAL_LABEL): Only define if not BFD_ASSEMBLER.
+ (S_LOCAL_NAME): Likewise.
+ (FAKE_LABEL_NAME): Define unconditionally.
+ * symbols.c (colon): Call bfd_is_local_label, not LOCAL_LABEL, if
+ BFD_ASSEMBLER.
+ (S_IS_LOCAL): Call bfd_is_local_label_name, not LOCAL_LABEL.
+ * config/tc-*.h: Only define LOCAL_LABEL if not BFD_ASSEMBLER.
+ Don't define FAKE_LABEL_NAME.
+ * config/te-ic960.h: Likewise.
+ * config/tc-mips.h (tc_frob_file_before_adjust): Define.
+ (mips_frob_file_before_adjust): Declare.
+ * config/tc-mips.c (mips_frob_file_before_adjust): New function.
+ (mips_local_label): Remove.
+
+ * config/te-sco386.h: Remove; not used.
+
+Thu Feb 27 15:39:16 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80 (md_pseudo_table): Add align pseudo op to do
+ byte alignment rather than power-of-two alignment that is the
+ GAS default.
+
+Thu Feb 27 13:29:04 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (md_assemble): Handle a reloc width of 'W'.
+
+ * gasp.c (hash_add_to_string_table): Correct misspelling in error
+ message, and add newline.
+ (process_file): Don't process assignments in the label if this is
+ a equ or assign pseudo-op.
+ (process_pseudo_op): Swap first argument to do_assign for K_ASSIGN
+ and K_EQU, to match documentation.
+
+Thu Feb 27 12:00:03 1997 Michael Meissner <meissner@cygnus.com>
+
+ * config/obj-coff.c (obj_coff_section): Add 'r' section attribute
+ to denote read-only data sections.
+
+Thu Feb 27 00:26:33 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-elf.c (obj_elf_common): Set BSF_OBJECT in flags.
+ * config/tc-sparc.c (s_common): Likewise, if BFD_ASSEMBLER.
+
+ * expr.c (operand): Simplify 0b handling. Don't treat 0b as a
+ binary number if the next character is '+' or '-'.
+
+Wed Feb 26 20:47:12 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (FLT_CHARS): Change from "dD" to "fF".
+ (find_opcode): Match operands that can be floats.
+ (build_insn): Handle O_big (float) expressions and build
+ correct opcode.
+
+Wed Feb 26 18:19:00 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.in (mips*-*-lnews*): New target, also make empty
+ emulation list for this target.
+ * configure: Update.
+ * config/tc-mips.c (ECOFF_LITTLE_FORMAT): Define.
+ (mips_target_format): Use.
+ * config/te-lnews.h: New file.
+
+Wed Feb 26 15:33:46 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (find_opcode, build_insn): Changes to match
+ operands with :m or :s modifiers and generate the right opcodes
+ for them.
+
+Wed Feb 26 11:56:11 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (itbl-parse.c itbl-parse.h): Use $(BISON) and
+ $(BISONFLAGS), not $(YACC) and $(YACCFLAGS).
+
+Tue Feb 25 22:02:23 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * config/tc-m68k.c (instring): Useless local declaration of
+ crack_operand removed.
+ * expr.h (expressionS): Changed type of X_op field to operatorT if
+ __GNUC__.
+
+Tue Feb 25 13:17:27 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patches from Robert Lipe <robertl@dgii.com>:
+ * configure.in: Add i386coff and i386elf to emulation list.
+ * configure: Rebuild.
+ * as.c (i386coff, i386elf): Declare.
+ * obj.h (coff_format_ops): Declare.
+ * config/obj-coff.c (OBJ_HEADER): Define.
+ (coff_obj_symbol_new_hook): Rename from obj_symbol_new_hook.
+ (coff_obj_read_begin_hook): Rename from obj_read_begin_hook.
+ (obj_pseudo_table): Add "version".
+ (coff_pop_insert): New static function.
+ (coff_sec_sym_ok_for_reloc): New static function.
+ (no_func): New static function.
+ (coff_format_ops): New variable.
+ * config/obj-coff.h (coff_obj_symbol_new_hook): Declare.
+ (obj_symbol_new_hook): Define.
+ (coff_obj_read_begin_hook): Declare.
+ (obj_read_begin_hook): Define.
+ * config/tc-i386.h (i386_target_format): Declare.
+ * config/tc-i386.c: Check OBJ_MAYBE_ELF as well as OBJ_ELF; check
+ OUTPUT_FLAVOR when appropriate.
+ (i386_target_format): New function.
+ * Makefile.in (obj-coff.o): New target.
+ (e-i386coff.o, e-i386elf.o): New targets.
+
+ From Stephen Williams <steve@icarus.icarus.com>:
+ * config/tc-i960.h (TC_SYMFIELD_TYPE): Define if OBJ_COFF.
+ (_tc_get_bal_of_call): Don't declare.
+ (tc_get_bal_of_call): Declare as function, don't define as macro.
+ * config/tc-i960.c (tc_set_bal_of_call): If OBJ_COFF, store balP
+ in sy_tc field, not x_balntry field.
+ (tc_get_bal_of_call): Rename from _tc_get_bal_of_call. Change
+ return type to symbolS *. If OBJ_COFF, retrieve value from sy_tc
+ field, not x_balntry field.
+
+ * config/obj-elf.c (obj_elf_section): Permit a .note section to
+ have the SHF_ALLOC attribute.
+
+ * Makefile.in ($(OBJS)): Don't depend upon $(IT_HDRS).
+ (TARG_CPU_DEP_mips): Depend upon $(srcdir)/itbl-ops.h.
+ (itbl-lex.o): Depend upon itbl-parse.h.
+
+ * itbl-parse.y (yyerror): Change return type to int. Change to
+ use old style function declaration.
+
+ * Makefile.in (itbl-lex.o): Remove -Wall.
+ (itbl-parse.o): Likewise.
+
+ * cond.c (s_ifdef): If we should omit conditionals from listings,
+ call listing_list.
+ (s_if, s_ifc, s_endif, s_else, s_ifeqs): Likewise.
+ * listing.c (list_info_struct): Add EDICT_NOLIST_NEXT.
+ (listing_listing): Handle EDICT_NOLIST_NEXT.
+ (listing_list): An argument of 2 means EDICT_NOLIST_NEXT.
+ * listing.h (LISTING_NOCOND): Define.
+ (LISTING_SKIP_COND): Define.
+ * as.c (show_usage): Mention c as a suboption of -a.
+ (parse_args): Handle c as a suboption of -a.
+ * doc/as.texinfo: Document -alc.
+
+Mon Feb 24 23:34:14 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (md_apply_fix): Handle R_ABS type fixups.
+
+Mon Feb 24 18:27:43 1997 Eric Youngdale <eric@andante.jic.com>
+
+ * doc/as.texinfo: Document .symver.
+
+Mon Feb 24 15:19:57 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Change pre_defined_registers to
+ d10v_predefined_registers and reg_name_cnt to d10v_reg_name_cnt.
+
+Mon Feb 24 10:40:45 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/obj-coff.c: Fix typo in comment section.
+ * config/tc-tic80.c (md_pseudo_table): Add entry for bss, which takes
+ an additional alignment argument.
+ (find_opcode): Allow O_symbol relocs for any 32 bit field, not just
+ base relative ones.
+ (build_insn): Handle O_symbol relocs for any 32 bit field, not just
+ base relative ones.
+
+Mon Feb 24 02:23:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * Makefile.in: Remove dependancies on itbl-cpu.h.
+ * as.c: Define stubs for itbl_parse and itbl_init if HAVE_ITBL_CPU
+ is not defined.
+
+Mon Feb 24 02:03:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * itbl-ops.h: Include as.h.
+
+Mon Feb 24 01:04:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * as.c: Remove -t option.
+ * configure, configure.in: Move itbl-cpu.h to mips specific configure.
+ * itbl-ops.h: Include itbl-cpu.h only if HAVE_ITBL_CPU is defined.
+ * config/tc-mips.h: Define HAVE_ITBL_CPU.
+
+Sun Feb 23 18:01:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * itbl-ops.c: Don't define DEBUG.
+
+Sun Feb 23 17:49:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * Makefile.in: Update itbl-test.c to reflect its new location.
+
+Sun Feb 23 15:50:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * itbl-ops.c: Add test for itbl_have_entries.
+ * config/tc-mips.c: Remove test for itbl_have_entries.
+ * config/tc-mips.h: Define tc_init_after_args to mips_init_after_args.
+
+Sun Feb 23 18:13:19 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (DISTSTUFF): Remove itbl-parse.y, itbl-lex.l, and
+ itbl-ops.c. Add itbl-parse.c and itbl-lex.c.
+ (LEX, LEXFLAGS): Define.
+ * itbl-ops.c (append_insns_as_macros): Remove bogus ASSERT.
+
+Sat Feb 22 21:25:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * itbl-parse.y: Fix indentation mistakes from indent program.
+ * itbl-lex.l: Fix indentation mistakes from indent program.
+ * itbl-ops.h: Add include for ansidecl.h.
+ Add PARAMS around function arguments.
+ Add declaration for itbl_have_entries.
+ * itbl-ops.c: Add PARAMS around function arguments.
+ * Makefile.in: Add itbl build rules.
+ Add dependancies for itbl files to mips target.
+ * as.c: Add itbl support.
+ Add new option "--insttbl" for dynamically extending instruction set.
+ * as.h: Declare insttbl_file_name;
+ the name of file defining extensions to the basic instruction set
+ * configure.in, configure: Add itbl-parse.o, itbl-lex.o, and
+ itbl-ops.o to extra_objects for mips configuration.
+ Add include file link from itbl-cpu.h to
+ config/itbl-${target_cpu_type}.h.
+ * config/tc-mips.c: Allow copz instructions.
+ Add notes for future additions to the itbl support.
+ Add debug macros.
+ (macro): Call itbl_assemble to assemble itbl instructions.
+ See if an unknown register is specified in an itbl entry.
+
+Sat Feb 22 20:53:01 1997 Fred Fish <fnf@cygnus.com>
+ * doc/internals.texi (CPU backend): Fix typo in md_section_align
+ description.
+ * config/tc-tic80.h (NEED_FX_R_TYPE): Define.
+ * config/tc-tic80.c (find_opcode): Add code to support O_symbol
+ operands.
+ (build_insn): Grab a frag early so we can use the address in
+ fixups. Take one's complement of BITNUM values before insertion
+ in opcode. Add code to support O_symbol operands.
+ (md_apply_fix): Replace unimplemented warning with implementation.
+ (md_pcrel_from): Ditto.
+ (tc_coff_fix2rtype): Ditto.
+
+Fri Feb 21 14:34:31 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d30v.c (parallel_ok): New function.
+ * config/tc-d30v.h: Define TARGET_BYTES_BIG_ENDIAN.
+ * config/tc-d10v.c (md_pcrel_from_section): Return 0 if
+ relocation is in different section.
+
+Fri Feb 21 10:08:25 1997 Jim Wilson <wilson@cygnus.com>
+
+ * config/tc-mips.c (mips_ip): If configured for an embedded ELF system,
+ don't set the section alignment to 2**4.
+
+Fri Feb 21 11:55:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (line_comment_chars): Add '*'.
+
+ * app.c (LEX_IS_TWOCHAR_COMMENT_2ND): Don't define.
+ (do_scrub_begin): Don't set lex['*'].
+ (do_scrub_chars): When handling LEX_IS_TWOCHAR_COMMENT_1ST, don't
+ check for LEX_IS_TWOCHAR_COMMENT_2ND. Instead, just check for
+ a literal '*'.
+
+ * configure.in: Set em=svr4 for m68k-*-sysv4*.
+ * configure: Rebuild.
+ * config/te-svr4.h: New file.
+ * config/tc-m68k.c (m68k_comment_chars): Only include `#' if
+ TE_SVR4 or TE_DELTA.
+
+Thu Feb 20 22:24:39 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_convert_frag): Create a fixup for the
+ short conditional branch around a long unconditional branch.
+
+Thu Feb 20 13:56:00 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (obj_coff_ln [both versions]): Call
+ new_logical_line.
+
+ * config/tc-arm.c (fix_new_arm): Use make_expr_symbol to handle a
+ complex expression.
+
+ * symbols.c (resolve_symbol_value): If both left and right
+ operands are undefined, warn about both of them.
+
+Wed Feb 19 00:53:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patches from Eric Youngdale <eric@andante.jic.com>:
+ * config/obj-elf.c (elf_pseudo_table): Add "symver".
+ (obj_elf_symver): New static function.
+ * config/obj-elf.h (OBJ_COPY_SYMBOL_ATTRIBUTES): Copy the st_other
+ field.
+
+ * write.c (relax_segment): Make type and printf format agree.
+
+ * read.c (get_line_sb): Don't end the line on a semicolon inside a
+ string.
+
+Tue Feb 18 18:42:51 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d30v.c, config/tc-d30v.h: New files.
+
+ * configure: Rebuilt.
+
+ * configure.in: Add case for d30v.
+
+Sun Feb 16 17:47:29 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-alpha.h (md_operand): Define with a null expansion,
+ like all the other targets.
+ * doc/internals.texi (CPU backend): Add missing word in
+ md_flush_pending_output description. Fix typo in md_convert_frag
+ description.
+ * config/tc-tic80: Minor comment additions/changes.
+
+Fri Feb 14 18:09:59 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * config/tc-m68k.c (LOCAL_LABEL): Macro redefined if TE_DELTA.
+ (tc_canonicalize_symbol_name): Macro defined if TE_DELTA.
+ * config/obj-coff.c (obj_coff_def): Use
+ tc_canonicalize_symbol_name if defined.
+ (obj_coff_tag, obj_coff_val): Likewise.
+ * expr.c (operand): Reject '~' as operator if is_name_beginner.
+
+Fri Feb 14 17:24:48 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on notes from Peter Eriksson <peter@ifm.liu.se>. The target
+ does not actually work, though:
+ * configure.in (i386-sequent-bsd*): New target.
+ * configure: Rebuild.
+ * config/tc-dynix.h: New file.
+ * config/tc-i386.h: Define TARGET_FORMAT if TE_DYNIX.
+
+ * read.c (do_align): Add max parameter. Change all callers.
+ Remove useless static variables.
+ (s_align): New static function. Do common portion of
+ s_align_bytes and s_align_ptwo.
+ (s_align_bytes, s_align_ptwo): Just call s_align.
+ * frags.c (frag_align): Add max parameter. Change all callers.
+ (frag_align_pattern): Likewise.
+ * frags.h (frag_align, frag_align_pattern): Update declarations.
+ * write.c (relax_segment): Limit alignment change to fr_subtype.
+ Fix some types to be addressT.
+ * config/obj-coff.c (size_section): Likewise.
+ * config/obj-ieee.c (size_section): Likewise.
+ * config/tc-d10v.h (md_do_align): Add max parameter.
+ * config/tc-i386.h (md_do_align): Likewise.
+ * config/tc-m88k.h (md_do_align): Likewise.
+ * config/tc-m88k.c (m88k_do_align): Likewise.
+ * config/tc-sh.h (md_do_align): Likewise.
+ * config/tc-sh.c (sh_do_align): Likewise.
+ * as.h: Improve comments on rs_align and rs_align_code.
+ * doc/as.texinfo: Document new alignment arguments.
+ * doc/internals.texi (Frags): Document use of fr_subtype field for
+ rs_align and rs_align_code.
+
+Fri Feb 14 15:56:06 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c: Changed opcode parsing.
+
+Thu Feb 13 20:02:16 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/{tc-alpha.h, tc-d10v.h, tc-generic.h, tc-i960.h,
+ tc-mn10200.h, tc-mn10300.h, tc-sh.h, tc-vax.h, tc-w65.h}:
+ Add default definition of zero for TARGET_BYTES_BIG_ENDIAN.
+ * config/{tc-arm.h, tc-hppa.h, tc-i386.h, tc-mips.h, tc-ns32k.h,
+ tc-ppc.h, tc-sparc.h}: Move definition of TARGET_BYTES_BIG_ENDIAN
+ to a location consistent with the rest of the target include files.
+ * config/tc-i386.c: Remove misleading comment.
+ * doc/internals.texi (CPU backend): Add description of function
+ md_undefined_symbol.
+ * config/tc-tic80.c: Add code to insert predefined symbols into the
+ symbol table so they can be parsed by the standard expression parser.
+ Remove custom code that use to parse them.
+ * config/tc-tic80.h: Move definition of TARGET_BYTES_BIG_ENDIAN
+ to a location consistent with the rest of the target include files.
+
+Thu Feb 13 21:44:18 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * as.h: GNU c provides unlink() function.
+
+ Unify section handling on openVMS/Alpha:
+ * config/tc-alpha.c(s_alpha_link): Remove.
+ (s_alpha_section): New function.
+ Remove case-hacking of symbols
+ Add .code_address pseudo-op.
+ (BFD_RELOC_ALPHA_CODEADDR): New relocation.
+ (s_alpha_code_address): New function.
+ (alpha_ctors_section, alpha_dtors_section): New sections for C++
+ static constructors/destructors.
+ Add debug code for crash debugs, to be removed when traceback code
+ is added to object code.
+ (s_alpha_name): New function for .name pseudo-op.
+ (alpha_print_token): New function to print token expressions with
+ alpha specific extensions.
+
+ * makefile.vms: Allow compilation with current gcc snapshot.
+
+Thu Feb 13 16:29:04 1997 Fred Fish <fnf@cygnus.com>
+
+ * doc/Makefile.in (TEXI2DVI): Set to just name of program.
+ (DVIPS): Set to dvips.
+ (ps, as.ps, gasp.ps): New targets.
+ (internals.info, gasp.dvi, internals.dvi): Set both TEXINPUTS
+ and MAKEINFO env variables.
+ (internals.ps): Use DVIPS macro.
+ (clean): Remove core and backup files.
+ (distclean): Remove temporary files from building internals.
+ (clean-dvi): Ditto.
+ * doc/internals.texi (Frags): Fix typo.
+ (GAS processing): Ditto.
+ (CPU backend): Ditto.
+ * ecoff.c (init_file): Use TARGET_BYTES_BIG_ENDIAN value directly.
+ * mpw-config.in: Define TARGET_BYTES_BIG_ENDIAN as 1.
+ * read.c: Remove ugly hack that dealt with config files not
+ correctly defining TARGET_BYTES_BIG_ENDIAN.
+ (target_big_endian): Use TARGET_BYTES_BIG_ENDIAN directly.
+ * config/arm-big.mt: Define TARGET_BYTES_BIG_ENDIAN to 1.
+ * config/arm-lit.mt: Define TARGET_BYTES_BIG_ENDIAN to 0.
+ * config/mips-big.mt: Define TARGET_BYTES_BIG_ENDIAN to 1.
+ * config/mips-lit.mt: Define TARGET_BYTES_BIG_ENDIAN to 0.
+ * config/ppc-lit.mt: Define TARGET_BYTES_BIG_ENDIAN to 1.
+ * config/ppc-sol.mt: Replace TARGET_BYTES_LITTLE_ENDIAN
+ with TARGET_BYTES_BIG_ENDIAN defined to 0.
+ * config/tc-arm.h: Remove use of TARGET_BYTES_LITTLE_ENDIAN
+ and simplify. Test value of TARGET_BYTES_BIG_ENDIAN, not just
+ whether it is defined or not.
+ * config/tc-mips.h: Remove use of TARGET_BYTES_LITTLE_ENDIAN.
+ * config/tc-ppc.h: Remove use of TARGET_BYTES_LITTLE_ENDIAN
+ and simplify. Test value of TARGET_BYTES_BIG_ENDIAN, not just
+ whether it is defined or not.
+ * config/tic80.h (TARGET_FORMAT): Define to coff-tic80.
+ (TARGET_BYTES_BIG_ENDIAN): Define to 0.
+
+Thu Feb 13 14:40:16 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * write.c (write_relocs): Correct text in as_fatal error message,
+ bfd_perform_relocation -> bfd_install_relocation.
+
+Thu Feb 13 14:48:03 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * config/tc-m68k.c (LEX_TILDE): Define if TE_DELTA.
+ * read.c (LEX_TILDE): Define if not defined.
+ (lex_type): Use LEX_TILDE.
+ * expr.c (get_symbol_end): Check first char with is_name_beginner,
+ not is_part_of_name.
+
+Thu Feb 13 11:40:58 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c (md_show_usage): Add missing backslash at end
+ of continued line.
+
+ * config/tc-mips.c (mips16_extended_frag): Correct base address
+ for an extended PC relative instruction.
+ (md_convert_frag): Likewise.
+
+ * config/tc-mips.c (prev_nop_frag): New static variable.
+ (prev_nop_frag_holds): New static variable.
+ (prev_nop_frag_required): New static variable.
+ (prev_nop_frag_since): New static variable.
+ (append_insn): If we aren't reordering, and prev_nop_frag is not
+ NULL, and we don't need any nops, then decrease the size of
+ prev_nop_frag. Don't insert nops because of instructions in
+ noreorder sections. Remember whether the previous instructions
+ where in noreorder sections even when not reordering.
+ (mips_no_prev_insn): Add preserver parameter. Change all
+ callers. Refer prev_nop_frag variables when appropriate.
+ (mips_emit_delays): Set up prev_nop_frag.
+ (s_mipsset): Clear prev_nop_frag if reordering.
+
+Wed Feb 12 14:36:29 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (append_insn): Remove useless code which
+ handled swapping a mips16 jump with a mips16 instruction with a
+ reloc.
+
+ * config/tc-mips.c (md_parse_option): When debugging, set
+ mips_optimize to 1, not 0.
+
+ * config/tc-mips.c (mips16_ip): Handle an extend operand.
+
+ * config/tc-mips.c (my_getExpression): In mips16 mode, if it looks
+ like the expression was based on `.', adjust the value of the
+ symbol.
+
+ * config/tc-mips.c (append_insn): Warn about an attempt to put an
+ extended instruction in a delay slot when not reordering.
+ (md_convert_frag): Warn if an extended instruction appears in a
+ delay slot.
+
+ * config/tc-mips.c (mips_pseudo_table): Add "insn".
+ (s_insn): New static function.
+ * doc/c-mips.texi: Document .insn.
+
+ * config/tc-mips.c (md_begin): Add the general registers to the
+ symbol table.
+ (mips16_ip): First parse the expression, and then see whether it
+ came up with a register, rather than trying to first see whether
+ we are looking at a register.
+
+Tue Feb 11 15:13:39 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c: Numerous changes and additions to flesh
+ out functions that were previously just stubs, and fix some
+ problems found using the new TIc80 testsuite cases.
+
+Tue Feb 11 15:52:22 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips16_ip): Handle %gprel modifier.
+ (md_apply_fix): Handle BFD_RELOC_MIPS16_GPREL.
+
+ * config/tc-mips.c (append_insn): Output jump instruction as a
+ pair of 2 byte instructions, rather than as a single 4 byte
+ instruction.
+
+Mon Feb 10 22:06:00 1997 Dawn Perchik (dawn@cygnus.com)
+
+ * itbl-ops.c, itbl-lex.l, itbl-parse.y, itbl-ops.h,
+ config/itbl-mips.h: Add copyright message and fix indentation.
+
+Mon Feb 10 18:09:00 1997 Dawn Perchik (dawn@cygnus.com)
+
+ * itbl-ops.c: New file. Add support for dynamically read
+ instruction registers, opcodes and formats. Build internal table
+ for new instructions and provide callbacks for assembler and
+ disassembler.
+ * itbl-lex.l, itbl-parse.y: Lex and yacc parsers for instruction
+ spec table.
+ * itbl-ops.h: New file. Header file for itbl support.
+ * config/itbl-mips.h: New file. Mips specific definitions for
+ itbl support.
+
+Fri Feb 7 09:52:34 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_assemble): If a constant operand won't
+ fit into the constant field of a relaxable operand, then it does
+ not match.
+
+Thu Feb 6 20:08:12 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_estimate_size_before_relax): Treat
+ a jsr target in a different section just like a jsr to
+ an undefined target.
+
+Thu Feb 6 16:52:57 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_fix_adjustable): Don't adjust relocations
+ against any mips16 symbols, not just externally visible ones.
+ (md_apply_fix): Corresponding change.
+
+Wed Feb 5 11:11:06 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips16_ip): Accept floating point registers in
+ the operand of the exit instruction.
+
+Tue Feb 4 14:12:39 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (resolve_symbol_value): If we leave an equated symbol
+ as O_symbol, copy over the segment.
+
+Mon Feb 3 12:35:54 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_apply_fix): If we aren't adjusting this
+ fixup to be against the section symbol, adjust the value
+ accordingly.
+
+ * symbols.c (resolve_symbol_value): Don't change X_add_number for
+ an equated symbol.
+ * write.c (write_relocs): Avoid looping on equated symbols.
+ Adjust fx_offset by X_add_number for each symbol.
+ * config/obj-coff.c (do_relocs_for): Avoid looping on equated
+ symbols.
+ (fixup_segment): Add a loop to track down equated symbols and
+ adjust fx_offset appropriately.
+
+Fri Jan 31 15:21:02 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_relax_table): Add entries to allow
+ jmp -> bra relaxing.
+ (md_convert_frag): Handle jmp->bra relaxing.
+ (md_assemble): Handle jmp->bra relaxing.
+ (md_estimate_size_before_relax): Likewise.
+
+Fri Jan 31 13:15:05 1997 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (i386_align_code): Add comments explaining the
+ nop instructions.
+
+Fri Jan 31 10:46:14 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c (enforce_aligned_data): New static variable.
+ (sparc_cons_align): Don't do anything unless enforce_aligned_data
+ is set.
+ (md_longopts): Add "enforce-aligned-data".
+ (md_show_usage): Mention --enforce-aligned-data.
+ * doc/c-sparc.texi (Sparc-Aligned-Data): New node; document
+ enforce-aligned-data.
+
+ * config/tc-ppc.c (md_pseudo_table): If OBJ_XCOFF, add "long",
+ "word", and "short".
+ (ppc_xcoff_cons): New static function.
+
+ * write.c (relax_segment): Give an error if a .space symbol is
+ common or undefined.
+
+ * read.c (read_a_source_file): Don't handle mri_pending_align if
+ the handler is s_globl or s_ignore.
+
+Thu Jan 30 11:46:59 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-d10v.c (find_opcode): Remove unused variable "numops".
+ * config/tc-tic80.c: Many additions to previous placeholder file.
+ * config/tc-tic80.h: Ditto.
+
+Thu Jan 30 12:28:18 1997 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (i386_align_code): Improve the nop patterns.
+
+Thu Jan 30 12:08:40 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_fix_adjustable): New function.
+ * config/tc-mips.h (tc_fix_adjustable): Call mips_fix_adjustable.
+ (mips_fix_adjustable): Declare.
+
+ Ideas from Srinivas Addagarla <srinivas@cdotd.ernet.in>:
+ * read.c (read_a_source_file): After doing an mri_pending_align,
+ adjust the line_label if there is one.
+ (s_space): Set mri_pending_align if an odd number of bytes were
+ output.
+
+Wed Jan 29 15:31:12 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.h (md_do_align): Add this hook to call
+ d10v_cleanup() when a ".align" is detected.
+
+ * config/tc-d10v.c (find_opcode): Correctly calculate
+ branch displacement when .aligns are present.
+
+Wed Jan 29 09:42:11 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_relax_table): Define.
+ (md_convert_frag): Implement.
+ (md_assemble): Handle relaxable operands/instructions correctly.
+ (md_estimate_size_before_relax): Implement.
+ * config/tc-mn10200.h (TC_GENERIC_RELAX_TABLE): Define.
+
+Tue Jan 28 15:27:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (append_insn): Give an error for jumps to a
+ misaligned address.
+ (md_apply_fix): Make a branch to an odd address an error rather
+ than a warning.
+
+ * config/tc-mips.c (md_convert_frag): If the user explicitly
+ requested an extended opcode, pass warn as true to mips16_immed.
+
+ * config/tc-mips.c (mips16_ip): Handle a missing expression like
+ an explicit 0, so that explicitly extended instructions work
+ correctly.
+
+Mon Jan 27 17:41:20 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (ecoff_build_symbols): Don't generate a local ECOFF
+ symbol for a common symbol.
+
+Wed Jan 22 10:39:39 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ Patch presumed to have been checked in awhile ago but wasn't.
+ Mon Nov 25 10:45:14 1996 Doug Evans <dje@seba.cygnus.com>
+ * write.c: Delete "ifndef md_relax_frag" around is_dnrange.
+ (relax_segment, case rs_org): Move code inside braces. Move locals
+ target,after inside too.
+ (relax_segment, case rs_machine_dependent): Guts moved to ...
+ (relax_frag): New function.
+ Call md_prepare_relax_scan if defined.
+
+Mon Jan 20 10:56:47 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (m68k_ip): Reject pc-relative addresses for the
+ 'p' operand specifier.
+
+Mon Jan 20 10:39:36 1997 J.T. Conklin <jtc@cygnus.com>
+
+ * config/tc-m68k.c (HAVE_LONG_BRANCH): New macro, returns true for
+ m68k family cpus which support long branch addressing modes.
+ (m68k_ip, md_convert_frag_1, md_estimate_size_before_relax,
+ md_create_long_jump): Use it.
+
+Mon Jan 20 12:42:06 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_begin): Don't set SEC_ALLOC or SEC_LOAD for
+ the .reginfo or .MIPS.options section if configured for an
+ embedded target.
+
+ * config/tc-mips.c (md_begin): Don't set interlocks for
+ mips_4650.
+
+Wed Jan 15 13:51:50 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (read_a_source_file): Make sure the symbol ends with
+ whitespace before checking whether the next character is '='.
+
+Tue Jan 14 15:07:27 1997 Robert Lipe <robertl@dgii.com>
+
+ * config/tc-i386.c (sco_id): Moved from here...
+ * config/obj-elf.c (sco_id): ...to here. Adding the identifier
+ really is an SCO ELF specific thing, not just a SCO x86 specific
+ thing.
+
+Mon Jan 13 22:43:01 1997 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (tic80-*-*): Don't require 'coff'.
+ * configure: Regenerate.
+
+Thu Jan 9 09:08:43 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (emit_expr): Check for overflow of a negative value
+ correctly.
+ * write.c (fixup_segment): Likewise.
+ * config/obj-coff.c (fixup_segment): Likewise.
+
+ * config/tc-m68k.c (struct label_line): Define.
+ (labels, current_label): New static variables.
+ (md_assemble): Mark current_label as text, and clear it.
+ (m68k_frob_label): New function.
+ (m68k_flush_pending_output): New function.
+ (m68k_frob_symbol): New function.
+ * config/tc-m68k.h (tc_frob_label): Define.
+ (md_flush_pending_output): Define.
+ (tc_frob_symbol): Don't warn, just call m68k_frob_symbol.
+ (tc_frob_coff_symbol): Likewise.
+
+ * read.c (read_a_source_file): When defining a macro in MRI mode,
+ don't add the symbol to the symbol table.
+
+Tue Jan 7 11:21:42 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (tc_gen_reloc): Handle sym1-sym2 fixups
+ here since fixup_segment doesn't (linkrelax is set).
+ * config/tc-mn10200.c (tc_gen_reloc): Likewise.
+
+Mon Jan 6 15:19:32 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_assemble): Tweak fx_offset for pc-relative
+ relocs.
+
+Fri Jan 3 16:47:08 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (struct hppa_fix_struct): Tweak fx_r_field's type
+ to avoid warnings with the native HP compiler.
+ (fix_new_hppa): Similarly for the r_type argument.
+ (pa_build_unwind_subspace, hppa_elf_mark_end_of_function): Enclose
+ in an #if OBJ_ELF to keep gcc -Wall quiet.
+ (md_apply_fix): Always initialize "result".
+
+ * config/tc-mn10200.c (md_assemble): Generate relocations.
+
+Fri Jan 3 18:17:23 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (s_even): Adjust the alignment of the current
+ section.
+
+Fri Jan 3 17:10:33 1997 Richard Henderson <rth@tamu.edu>
+
+ * config/obj-elf.c (elf_file_symbol): When using ECOFF debugging,
+ pass on the new file hook.
+
+ * config/tc-alpha.c (alpha_fix_adjustable): Not quite the same as
+ !alpha_force_relocation, as local LITERALs can be adjusted to be
+ relative to the section.
+
+Fri Jan 3 12:09:24 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (yank_symbols): If tc_frob_coff_symbol is
+ defined, call it.
+ * config/tc-m68k.h (tc_frob_symbol): Check whether text label is
+ aligned to odd boundary.
+ (tc_frob_coff_symbol): Define.
+
+ * doc/as.texinfo (Set): Change parenthesized @xref to @pxref.
+
+ * macro.c (macro_expand_body): In MRI mode, just copy a single &.
+
+ * config/tc-m68k.c (m68k_ip): Call frag_grow before adding a
+ PCINDEX frag. From Ronald F. Guilmette <rfg@monkeys.com>.
+
+ * config/tc-m68k.c (m68k_ip): Accept 'B' as a size for an
+ immediate value.
+ (md_assemble): If the size is 'B', set fx_signed.
+ (md_apply_fix_2): Use fx_signed when checking for overflow.
+
+ * write.h (struct fix): Add fx_signed field.
+ * write.c (fix_new_internal): Initialize fx_no_overflow and
+ fx_signed fields.
+ (fixup_segment): Use fx_signed when checking for overflow.
+ * config/obj-coff.c (fixup_segment): Check fx_no_overflow and
+ fx_signed when checking for overflow.
+
+Thu Jan 2 13:37:29 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * NOTES, NOTES.config: Removed. These are rarely, if ever,
+ updated, and all the useful information is in doc/internals.texi.
+
+ Based on patch from Ronald F. Guilmette <rfg@monkeys.com>:
+ * read.c (read_a_source_file): Check for conditional operators
+ before doing an MRI pending alignment.
+ * config/tc-m68k.h (m68k_conditional_pseudoop): Declare.
+ (tc_conditional_pseudop): Define.
+ * config/tc-m68k.c (m68k_conditional_pseudop): New function.
+ * doc/internals.texi (CPU backend): Describe
+ tc_conditional_pseudoop.
+
+ Based on patch from Ronald F. Guilmette <rfg@monkeys.com>:
+ * config/tc-m68k.c (m68k_rel32_from_cmdline): New static
+ variable.
+ (md_begin): Check m68k_rel32_from_cmdline before setting
+ m68k_rel32.
+ (m68k_mri_mode_change): Likewise.
+ (md_longopts): Add --disp-size-default-16 and
+ --disp-size-default-32.
+ (md_parse_option): Handle new options.
+ (md_show_usage): Mention new options.
+ * doc/c-m68k.texi (M68K-Opts): Document new options.
+
+ Based on patch from Ronald F. Guilmette <rfg@monkeys.com>:
+ * config/tc-m68k.c (m68k_index_width_default): New static
+ variable.
+ (m68k_ip): Use m68k_index_width_default to set the size of a base
+ register whose size was not given.
+ (md_longopts): Add --base-size-default-16 and
+ --base-size-default-32.
+ (md_parse_option): Handle new options.
+ (md_show_usage): Mention new options.
+ * doc/c-m68k.texi (M68K-Opts): Document new options.
+
+ * doc/c-mips.texi: Mention ISA level 4, and the -mips16 option.
+
+ * configure.in: Recognize mips-*-linux* target.
+ * configure: Rebuild.
+
+ * config/tc-mips.c (load_register): Rewrite 64 bit handling to
+ work if valueT is only 32 bits.
+
+ * config/tc-mips.c: Throughout, check target_big_endian rather
+ than byte_order.
+ (byte_order): Remove.
+ (mips_init_after_args): Remove.
+ * config/tc-mips.h (LITTLE_ENDIAN, BIG_ENDIAN): Don't define.
+ (mips_init_after_args): Don't declare.
+ (tc_init_after_args): Don't define.
+
+ * config/tc-mips.h (tc_frob_after_relocs): Define if
+ OBJ_MAYBE_ELF.
+ (mips_elf_final_processing): Likewise.
+ (ELF_TC_SPECIAL_SECTIONS): Likewise.
+
+Tue Dec 31 15:12:35 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-v850.c (md_assemble): If this is sst.{h,w} or
+ sld.{h,w} and the operand is relocatable, adjust the adend by
+ shifting it right one bit.
+
+Tue Dec 31 12:56:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (read_a_source_file): Check mri_pending_align after
+ checking for a macro. From Ronald F. Guilmette
+ <rfg@monkeys.com>.
+
+ * Makefile.in (ALL_CFLAGS): Add -D_GNU_SOURCE.
+
+ * config/tc-sparc.c (md_apply_fix3): Rename from md_apply_fix, and
+ add segment argument. If OBJ_ELF, treat a relocation against a
+ symbol in a linkonce section like a relocation against an external
+ symbol.
+ * config/tc-sparc.h (MD_APPLY_FIX3): Define.
+
+Mon Dec 30 11:35:40 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips16_macro): Add case for M_ABS.
+
+Fri Dec 27 22:51:51 1996 Fred Fish <fnf@cygnus.com>
+
+ * NOTES.config (Implementation): as.h #define's "GAS" not "gas",
+ includes config.h instead of host.h, tc.h instead of tp.h, and
+ targ-env.h instead of target-environment.h.
+ Also, obj-format.h includes targ-cpu.h instead of
+ target-processor.h.
+ * configure.in (case ${generic_target}): Add tic80-*-coff entry.
+ * configure: Rebuild with autoconf.
+ * config/obj-coff.h (coff/tic80.h): Include if TC_TIC80 defined.
+ (TARGET_FORMAT): Define to "coff-tic80".
+ * config/tc-tic80.c: New file for TIc80 support.
+ * config/tc-tic80.h: New file for TIc80 support.
+
+Fri Dec 27 11:42:29 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo (M): Mention explicitly that -M changes macro
+ handling.
+
+Thu Dec 19 12:06:08 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (adjust_reloc_syms): If the fixup symbol has been
+ equated to an undefined symbol, convert the fixup to being against
+ the target symbol. Remove obsolete code handling a special case
+ for i386 PIC.
+
+Wed Dec 18 22:54:39 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Use NewFolderRecursive for installation.
+
+Wed Dec 18 16:00:42 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (do_assemble): Correct previous bug fix.
+
+Wed Dec 18 15:27:40 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (md_assemble): Fix bug which caused
+ second instruction in a line to be case sensitize.
+
+Wed Dec 18 10:08:46 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (mn10200_insert_operand): Don't
+ range check operands with MN10200_OPERAND_NOCHECK set.
+ (check_operand): Likewise.
+
+Tue Dec 17 10:59:32 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c: Undo part of last Friday's alignment changes.
+ (md_begin): Always align the text section to a four byte
+ boundary.
+ (append_insn): Remove call to record_align.
+
+ * config/tc-mips.c (insn_label): Remove.
+ (struct insn_label_list): Define.
+ (insn_labels, free_insn_labels): New static variables.
+ (mips_clear_insn_labels): New static function.
+ (append_insn): Mark all mips16 text labels, and make them odd.
+ Handle all labels after emitting a nop, not just one. Call
+ mips_clear_insn_labels rather than just clearing insn_label.
+ (mips_emit_delays): Add insns parameter, and use it to decide
+ whether to mark mips16 labels. Handle all labels, not just one.
+ Force mips16 labels to be odd. Change all callers.
+ (mips16_immed): Don't check for an odd branch target.
+ (md_apply_fix): Don't check mips16 mode for a branch reloc.
+ (mips16_extended_frag): Ignore the low bit in a branch target.
+ (md_convert_frag): Likewise.
+ (mips_no_prev_insn): Call mips_clear_insn_labels rather than just
+ clearing insn_label.
+ (mips_align, mips_flush_pending_output, s_cons): Likewise.
+ (s_float_cons, s_gpword): Likewise.
+ (s_align): Use insn_labels rather than insn_label.
+ (s_cons, s_float_cons, s_gpword): Likewise.
+ (mips_frob_file_after_relocs): New function.
+ (mips_define_label): Rewrite to add to insn_labels list.
+ * config/tc-mips.h (tc_frob_file_after_relocs): Define.
+ * ecoff.c (ecoff_build_symbols): If the size of a function comes
+ out odd, increment it.
+
+ * config/tc-mips.c (append_insn): Only update prev_insn when not
+ reordering if place is NULL.
+
+ * config/tc-mips.c (mips16_ip): Check for a missing expression
+ when using the register indirect addressing mode.
+
+Mon Dec 16 10:08:46 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (mn10200_insert_operand): Don't
+ check 24bit operands for overflow.
+ (check_operand): Likewise.
+
+Mon Dec 16 11:50:40 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo (Section): Document how to use the .section
+ pseudo-op for COFF and ELF.
+
+Sun Dec 15 15:26:37 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (adjust_reloc_syms): Fix linkonce check for ELF.
+
+Sat Dec 14 22:37:27 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (prev_insn_reloc_type): New static variable.
+ (RELAX_MIPS16_ENCODE): Add dslot and jal_dslot arguments, and
+ store them. Adjust other RELAX_MIPS16 macros.
+ (RELAX_MIPS16_DSLOT): Define.
+ (RELAX_MIPS16_JAL_DSLOT): Define.
+ (append_insn): Pass new arguments to RELAX_MIPS16_ENCODE. Correct
+ handling of whether previous instruction has a fixup. Set
+ prev_insn_reloc_type.
+ (mips_no_prev_insn): Clear prev_insn_reloc_type.
+ (mips16_extended_frag): Use the right base address for a PC
+ relative add or load.
+ (md_convert_frag): Likewise. If a PC relative add or load is
+ used, record the alignment for the section.
+
+Fri Dec 13 13:00:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (adjust_reloc_syms): Don't reduce a reloc against a
+ linkonce section into a reloc against the section symbol.
+
+ * config/tc-mips.c (mips16_macro): Remove nop instructions after
+ branch instructions.
+
+ * config/tc-mips.c (md_begin): If configured for an embedded ELF
+ system, don't set the section alignment to 2**4.
+ (s_change_sec): Likewise.
+ (append_insn): Call record_alignment for the section.
+ (md_section_align): Don't align the section size for an embedded
+ ELF system.
+
+Thu Dec 12 16:40:47 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (adjust_reloc_syms): Make sure that symbols are
+ resolved; expression symbols may have been skipped.
+ * config/obj-coff.c (fixup_segment): Likewise.
+
+Thu Dec 12 15:18:21 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Move @plt to
+ BFD_RELOC_24_PLT_PCREL relocation.
+ (md_apply_fix3): Support BFD_RELOC_24_PLT_PCREL.
+
+Tue Dec 10 13:51:55 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (write_2_short): Remove code that called
+ parallel_ok() when the programmer specified parallel instructions.
+
+Tue Dec 10 12:23:19 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_assemble): Update to handle endianness
+ issues correctly.
+
+ * config/tc-mn10200.c (md_assemble): Opcode 0x0 is valid!
+ * config/tc-mn10300.c (md_assemble): Likewise.
+
+Tue Dec 10 11:37:14 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (append_insn): Make sure there is enough room
+ in a frag after a mips16 instruction to switch it with a jump
+ instruction.
+
+ * config/tc-mips.c (mips16_extended_frag): Give an error for an
+ attempt to use a non absolute symbol in an extending frag.
+
+Mon Dec 9 16:48:20 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c: Flesh out assembler support for MN10200.
+ * config/tc-mn10200.h: Likewise.
+
+Mon Dec 9 17:09:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * app.c (do_scrub_chars): At the end of a C comment, pass space to
+ UNGET rather than PUT. Set old_state before setting state to -2.
+
+ * config/tc-mips.c (mips16_extended_frag): Avoid an infinite loop
+ when extending because the value is exactly maxtiny + 1.
+
+ * config/tc-mips.c (RELAX_MIPS16_ENCODE): Add small and ext
+ arguments, and store them. Adjust other RELAX_MIPS16 macros.
+ (RELAX_MIPS16_USER_SMALL): Define.
+ (RELAX_MIPS16_USER_EXT): Define.
+ (mips16_small, mips16_ext): New static variables.
+ (append_insn): Pass mips16_small and mips16_ext to
+ RELAX_MIPS16_ENCODE.
+ (mips16_ip): Set mips16_small and mips16_ext.
+ (mips16_immed): Don't check mips16_autoextend.
+ (mips16_extended_frag): Check USER_SMALL and USER_EXT.
+
+ * write.c (write_relocs): Print an error for an out of range
+ fixup, rather than calling abort.
+
+ * as.c (main): Unlink the output file if there are errors while
+ generating the fixups.
+
+Fri Dec 6 18:48:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips16_extended_frag): Don't call
+ S_GET_VALUE.
+ (md_convert_frag): Call resolve_symbol_value before calling
+ S_GET_VALUE, and don't add in the frag address.
+
+ * config/tc-mips.c (mips16_immed): Add file and line parameters,
+ and use them when reporting errors. Change all callers.
+
+Fri Dec 6 15:36:32 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c: Fix various gcc -Wall warnings.
+ Remove '$' prefixing for registers.
+
+Fri Dec 6 00:55:48 1996 Martin <hunt@cygnus.com>
+
+ * config/tc-d10v.c (md_assemble): Check to see if prev_seg
+ is initialized before using it.
+ (d10v_cleanup): No longer uses its argument, so make it void.
+
+ * config/tc-d10v.h (d10v_cleanup): Change prototype.
+
+Thu Dec 5 11:03:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (fixup_segment): Don't discard the symbol for a PC
+ relative fixup to an absolute symbol.
+
+Wed Dec 4 15:42:41 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (md_assemble, d10v_cleanup): Fix bug
+ with multiple sections.
+
+Wed Dec 4 13:00:07 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_longopts): Rename mips-16 to mips16, and
+ no-mips-16 to no-mips16.
+ (s_mipsset): Accept .set mips16 and .set nomips16.
+
+Wed Dec 4 10:35:33 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Take expressionS pointer
+ argument, and check for +/- constant following the suffix, folding
+ it into the expression.
+ (ppc_elf_cons): Change ppc_elf_suffix calls.
+ (md_assemble): Ditto.
+ (shlib): Replace boolean mrelocatable with enumeration shlib.
+ (md_parse_option): Discriminate between PIC style shared libraries
+ and -mrelocatable.
+ (ppc_elf_validate_fix): Don't report warnings for PIC style shared
+ libraries.
+
+Tue Dec 3 23:18:29 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.h ({tc,ppc}_comment_chars): Define, so that we can
+ change the comment characters.
+
+ * config/tc-ppc.c (comment_chars): Delete in favor of
+ tc_comment_chars.
+ (ppc_{eabi,solaris}_comment_chars): Eabi and Solaris versions of
+ comment chars.
+ (ppc_comment_chars): Select appropriate comment chars by default.
+ (msolaris): New flag for -m{,no-}solaris.
+ (md_parse_option): Recognize -K pic. Add support for
+ -m{,no-}solaris.
+ (md_show_usage): Update.
+ (md_begin): Do not set ELF flags if Solaris.
+ (ppc_elf_suffix): @local sets R_PPC_LOCAL24PC relocation.
+ (md_apply_fix3): Add support for R_PPC_LOCAL24PC.
+
+Mon Dec 2 13:48:57 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.c (main): Correct handling of flag_always_generate_output.
+
+Sun Dec 1 21:46:05 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (tc_gen_reloc): Get the addend from
+ fx_offset, not fx_addnumber.
+
+ * config/tc-mn10300.h (tc_fix_adjustable): Don't do any
+ reloc adjustments.
+
+Sat Nov 30 17:34:48 1996 Eliot Dresselhaus <eliot@wally.edc.com>
+
+ * config/tc-i386.c: Correct misspelling: balenced to balanced.
+
+Wed Nov 27 13:25:39 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_section_align): Check for an alignment of
+ 4, not an alignment of 16. Corrects August 7 patch.
+
+Tue Nov 26 10:33:16 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure, conf.in: Rebuild with autoconf 2.12.
+
+ * config/tc-ppc.c (ppc_elf_lcomm): Don't give an error if no
+ alignment is specified.
+
+ Add support for mips16 (16 bit MIPS implementation):
+ * config/tc-mips.c: Extensive additions for mips16 support, not
+ listed here.
+ (RELAX_OLD, RELAX_NEW): Use only 7 bits each.
+ (insn_uses_reg): Change last parameter to an enum.
+ * config/tc-mips.h (LOCAL_LABELS_DOLLAR): Define as 0.
+ (md_relax_frag): Define as mips_relax_frag.
+ (mips_relax_frag): Declare.
+ (struct mips_cl_insn): Add use_extend and extend fields.
+ (tc_fix_adjustable): Define.
+ * config/obj-elf.h (S_GET_OTHER): Define.
+ (S_SET_OTHER): Define.
+
+Mon Nov 25 18:02:29 1996 J.T. Conklin <jtc@beauty.cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Implement cases for new <, >, m, n,
+ o and p operand specifiers.
+
+Mon Nov 25 10:45:14 1996 Doug Evans <dje@seba.cygnus.com>
+
+ * write.c: Delete "ifndef md_relax_frag" around is_dnrange.
+ (relax_segment, case rs_org): Move code inside braces. Move locals
+ target,after inside too.
+ (relax_segment, case rs_machine_dependent): Guts moved to ...
+ (relax_frag): New function.
+ Call md_prepare_relax_scan if defined.
+ * config/tc-m68k.h (md_prepare_relax_scan): Renamed from
+ M68K_AIM_KLUDGE.
+
+Mon Nov 25 08:49:36 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (address_registers): Use '$' as register
+ prefix instead of '%'.
+ (data_registers, other_registers, md_assemble): Likewise.
+
+ * config/tc-mn10300.c (address_registers): Use '%' prefix for regs.
+ (data_registers, other_registers, md_assemble): Likewise.
+
+ * config/tc-mn10300.c (md_assemble): Correctly determine the
+ correct location and type for each relocation.
+ (md_pcrel_from): Simplify.
+
+Fri Nov 22 15:42:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (md_convert_frag): Improve warning when branch is
+ converted into branch around branch.
+
+Thu Nov 21 11:56:11 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.h (DIFF_EXPR_OK): Don't define this.
+ (tc_fix_adjustable): Don't adjust relocs against weak symbols or
+ pc-relative relocs.
+ * config/tc-mn10300.c (md_begin): Set linkrelax.
+ (md_assemble): Create fixups as needed.
+ (md_apply_fix3): Gut. It shouldn't ever get called anymore.
+
+Tue Nov 19 17:48:06 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-d10v.c (parallel_ok): When automatically converting
+ serial ops to parallel, do not consider a branch as the first
+ instruction.
+
+Tue Nov 19 13:35:22 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_assemble): Handle MN10300_OPERAND_REG_LIST.
+
+Mon Nov 18 15:26:55 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (mn10300_insert_operand): Provide prototype
+ via PARAMS.
+ (check_operand): Likewise.
+
+Mon Nov 18 15:22:28 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-d10v.c (parallel_ok): Branch and link instructions
+ modify r13.
+ (write_2_short): Call parallel_ok to check whether two short
+ instructions the user requested execute in parallel, can be
+ executed that way.
+
+Thu Nov 14 11:17:49 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (write_2_short): Fix bug that wouldn't
+ allow a branch and link in parallel with an exe instruction.
+
+Fri Nov 8 13:55:03 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * doc/c-d10v.texi: Add info on @word modifier.
+
+Wed Nov 6 13:46:07 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (mn10300_insert_operand): MN10300_OPERAND_SPLIT
+ operands are assumed to be 32bits. Use "bits" field to hold the
+ number of bits in the main instruction word for MN10300_OPERAND_SPLIT.
+ (mn10300_check_operand): MN10300_OPERAND_SPLIT operands are assumed
+ to be 32bits.
+
+ * config/tc-mn10300.c (mn10300_insert_operand): Shift low part
+ of a MN10300_OPERAND_SPLIT operand by operand->shift.
+
+ * config/tc-mn10300.c (mn10300_insert_operand): Handle
+ MN10300_OPERAND_SPLIT.
+
+Tue Nov 5 13:30:40 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_assemble): Insert operands into
+ the extension part of the instruction if necessary.
+ (mn10300_insert_operand): Accept pointer to extension word
+ argument. Make insn a pointer argument too. Return type
+ is now void. All callers changed.
+
+Mon Nov 4 12:53:40 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (mn10300_insert_operand): Handle
+ repeated register operands.
+
+Fri Nov 1 10:42:49 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo: Added section on reporting bugs.
+
+ * config/tc-alpha.c: Change uses of void * to PTR. Change the
+ alpha_macro emit field to expect a const argument, and change the
+ arg field to be const. Fix some spacing to follow the GNU
+ standard.
+
+Fri Nov 1 10:32:03 1996 Richard Henderson <rth@tamu.edu>
+
+ * config/tc-alpha.c (md_parse_option): Add knowledge of 21164pc
+ (pca56) and 21264 (ev6) cpus.
+ (md_apply_fix): Private relocation types are now negative.
+ (alpha_force_relocation): Likewise.
+ (tc_gen_reloc): Likewise.
+ (emit_insn): Likewise.
+ (emit_ldXu): Do the right thing when the hardware can do byte insns.
+ (emit_stX): Likewise.
+ (emit_sextX): Likewise.
+
+Thu Oct 31 16:33:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (do_relocs_for): Call resolve_symbol_value on
+ a symbol found in a reloc.
+
+ * symbols.c (resolve_symbol_value): Improve the error message if
+ an undefined symbol is used in an expression.
+
+Wed Oct 30 20:15:35 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/internals.texi: Rewrite, and add a lot of documentation.
+ * doc/Makefile.in (internals.info): New target.
+
+Wed Oct 30 14:55:57 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.h (tc_fix_adjustable): Don't adjust relocs
+ against weak symbols.
+
+Tue Oct 29 12:28:16 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_assemble): Don't lose for relaxable
+ addresses like .+6.
+
+ * config/tc-v850.c (md_convert_frag): Make sure we insert the
+ fixup at the right address within the frag.
+
+ * config/tc-v850.c (md_convert_frag): Don't set fragP->fr_fix
+ to an absolute value, instead increment it as needed.
+
+ * config/tc-v850.h (TC_GENERIC_RELAX_TABLE): Define.
+ * config/tc-v850.c: Fix some indention problems.
+ (md_relax_table): Define for D9->D99 branch displacement
+ relaxing.
+ (md_convert_frag): Do something useful instead of aborting.
+ (md_estimate_size_before_relax): Likewise.
+ (md_assemble): Note if the matching instruction has a relaxable
+ operand. If it does, allocate frag with frag_var and don't
+ do any fixups.
+
+Mon Oct 28 10:48:40 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.h (md_cleanup): New function. This is needed to
+ write out any buffered instructions when a ".end" is found.
+
+Mon Oct 28 10:43:45 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * read.c (read_a_source_file): New hook md_cleanup().
+
+Fri Oct 25 00:01:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (fix_new_exp): Use make_expr_symbol to build an
+ expression symbol for a complex fixup.
+
+Thu Oct 24 14:31:04 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (v850_reloc_prefix): Several disgusting
+ hacks to improve parsing of complex hi, lo, zda, etc
+ expressions.
+ (md_assemble): Don't demand and eat a trailing ')' after finding
+ a v850 relocation prefix. Sign extend the constant in a
+ BFD_RELOC_LO16 expression. Do eat a trailing ')' after a complete
+ operand.
+ (parse_cons_expression_v850): Don't eat a trailing ')' after
+ finding a v850 relocation prefix.
+
+ * config/tc-v850.h (TC_PARSE_CONS_EXPRESSION): Define.
+ (TC_CONS_FIX_NEW): Likewise.
+ * config/tc-v850.c (parse_cons_expression_v850): New function.
+ (cons_fix_new_v850): Likewise.
+
+ * config/tc-v850.h (tc_fix_adjustable): Don't adjust TDA relocs.
+
+Wed Oct 23 18:20:29 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (md_apply_fix3): Give a better warning message
+ for an unknown relocation type.
+
+Wed Oct 23 16:21:28 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_pseudo_table): Add .word; allocates
+ 4 bytes of space.
+
+Tue Oct 22 22:01:25 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_assemble): Handle TDAOFF relocs
+ differently for movea & sst/sld insns.
+
+Tue Oct 22 17:09:32 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-d10v.c (parallel_ok): Don't allow illegal combinations
+ of instructions.
+
+Tue Oct 22 11:28:39 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * obj.h (struct format_ops): Add frob_file_after_relocs field.
+ * config/obj-multi.h (obj_frob_file_after_relocs): Define.
+ * config/obj-ecoff.c (ecoff_format_ops): Initialize new
+ frob_file_after_relocs field.
+ * config/obj-elf.c (elf_format_ops): Likewise.
+ * config/tc-mips.c: Undefine obj_frob_file_after_relocs before
+ including obj-elf.h.
+
+Mon Oct 21 11:38:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (cons_fix_new_mips): Only treat 8 byte reloc
+ specially if not ELF.
+ (md_apply_fix): Handle BFD_RELOC_64.
+ (tc_gen_reloc): Handle BFD_RELOC_64.
+
+ * config/tc-i386.c (md_apply_fix3): Don't increment value for a PC
+ relative reloc when BFD_ASSEMBLER and OBJ_AOUT (more ugly gas
+ reloc hacking).
+
+ * config/obj-aout.h (S_IS_DEFINE): non BFD_ASSEMBLER version:
+ Don't check S_GET_OTHER.
+
+Fri Oct 18 14:06:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_ip): Accept an odd floating point
+ register with l.s or s.s.
+
+ * config/obj-aout.c (obj_pseudo_table): Use obj_aout_type for
+ .type pseudo-op.
+ (obj_aout_type): New static function.
+
+Thu Oct 17 17:55:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in ($(OBJS)): Depend upon libiberty.h.
+
+Wed Oct 16 11:28:31 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (v850_reloc_prefix): Recognize zdaoff, tdaoff
+ and sdaoff expressions.
+
+ * write.c (fixup_segment): Don't add symbol value to addend if
+ TC_V850 and OBJ_ELF.
+ * config/tc-v850.h (tc_fix_adjustable): Don't adjust any
+ pc-relative fixups.
+
+ * config/tc-v850.c (md_pcrel_from): Undo yesterday's changes.
+ (md_pcrel_from_section): Likewise.
+ * config/tc-v850.h (MD_PCREL_FROM_SECTION): Likewise.
+
+Tue Oct 15 23:19:00 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_pcrel_from): Delete unused function.
+ (md_pcrel_from_section): New function.
+ * config/tc-v850.h (MD_PCREL_FROM_SECTION): Define.
+
+Mon Oct 14 13:59:12 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (load_register): Add cast to offsetT when using
+ a constant with &~.
+
+Mon Oct 14 11:24:28 1996 Richard Henderson <rth@tamu.edu>
+
+ * config/obj-elf.c (elf_frob_file): Move ECOFF debug processing to ...
+ (elf_frob_file_after_relocs): ... here. New function.
+ * config/obj-elf.h (obj_from_file_after_relocs): New macro.
+ * write.c (write_object_file): Call *frob_after_relocs after the
+ call to write_relocs.
+
+ * config/tc-alpha.c: Use new BFD_RELOC_ALPHA_ELF_LITERAL reloc.
+
+ * config/tc-alpha.c (load_expression): Don't SET_VALUE on the section
+ symbol, as this messes up linking. Instead, expand the recursive call
+ inline and change up the appropriate bits to get the 0x8000 offset
+ in the reloc addend.
+
+Thu Oct 10 17:30:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.h (tc_fix_adjustable): Permit the difference of
+ two symbols in the same segment to be adjusted.
+
+ * configure.in: Don't get confused by CPU-VENDOR-linux-gnu.
+ * configure: Rebuild.
+
+Thu Oct 10 17:22:18 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_insert_operand): Change most warnings into
+ errors.
+ (ppc_elf_validate_fix): Ditto.
+ (md_assemble): Ditto.
+ (ppc_tc): Ditto.
+ (ppc_pe_section): Ditto.
+ (ppc_frob_symbol): Ditto.
+
+Thu Oct 10 12:05:45 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/mn10300.c (md_assemble): Pass an extra shift count
+ to mn10300_insert_operand based on the opcode format.
+ (mn10300_insert_operand): Accept and use extra shift count
+ parameter.
+
+ * config/tc-mn10300.c (md_assemble): Use FMT_* macros for
+ formats rather than hard-coded constants.
+
+ * config/tc-mn10300.c (md_assemble): Format D5 instructions
+ are 7 bytes long. Write out instructions in big-endian format.
+
+Tue Oct 8 14:56:15 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_assemble): Tweak further so
+ that all instructions are parsed correctly.
+
+Tue Oct 8 13:02:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.h: Include libiberty.h.
+ (xmalloc, xrealloc): Don't declare.
+ * as.c: Don't include libiberty.h.
+ * expr.c, read.c, stabs.c, config/obj-coff.c: Likewise.
+ * config/tc-mips.c: Likewise.
+ * messages.c: Likewise.
+ (xstrerror): Don't declare.
+ * xmalloc.c: Remove.
+
+Mon Oct 7 16:53:23 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.h (pre_defined_registers) Remove.
+ (system_registers, cc_names): Likewise.
+ (address_registers, data_registers, other_registers): New register
+ arrays.
+ (register_name, system_register_name, cc_name): Remove.
+ (mn10300_reloc_prefix): Likewise.
+ (data_register_name): New function.
+ (address_register_name, other_register_name): Likewise.
+ (md_assemble): Rough cut at parsing operands. Remove lots of
+ unwanted code.
+ (md_apply_fix3): Disable for now.
+
+Mon Oct 7 11:38:34 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (select_control_regs): New function, extracted
+ out of m68k_init_after_args.
+ (m68k_init_after_args): Use it.
+ (mri_chip): Use it here as well to update set of allowed control
+ regs for movec.
+
+Mon Oct 7 11:24:29 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-elf.c (elf_begin): New function.
+ (obj_elf_section): Add the section symbol to the symbol table.
+ * config/obj-elf.h (obj_begin): Define.
+ (elf_begin): Declare.
+ * as.c (perform_an_assembly_pass): Call obj_begin if it is
+ defined.
+
+Fri Oct 4 18:37:32 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): Subtract the section address
+ from a PC relative reloc if TC_M68K.
+
+Thu Oct 3 15:15:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c (md_pseudo_table): Make .uahalf, .uaword, and
+ .uaxword available even if not OBJ_ELF.
+ (md_atof): Remove unused local variable wordP.
+
+Thu Oct 3 00:16:50 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10x00.c, config/tc-mn10x00.h: New files
+ for Matsushita MN10x00 support.
+ * configure.in: Recognize mn10x00-*-*
+ * configure: Rebuilt.
+
+Wed Oct 2 15:54:03 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ * config/obj-evax.h: move openvms definitions from here to tc-alpha.c.
+ * config/tc-alpha.c: add support for vms_case_hack like in vax/vms.
+ (load_expression): track clobbering of base reg before jmp/jsr.
+ (s_alpha_file): pass case_hack flags and source filename via
+ symbol table to bfd.
+ * config/tc-alpha.h (TC_CONS_FIX_NEW): define
+
+Tue Oct 1 16:16:01 1996 Joel Sherrill <joel@oarcorp.com>
+
+ * configure.in (mips-*-rtems*): New target, like mips-*-elf*.
+ * configure: Rebuild.
+
+Tue Oct 1 12:37:48 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (s_macro): Warn if a macro has the same name as a
+ pseudo-op.
+ (s_space): In m68k MRI mode, align to a word boundary.
+ * macro.c (define_macro): Add namep parameter. Change all
+ callers.
+ * macro.h (define_macro): Update declaration.
+
+ * as.c (show_usage): Print bug report address.
+ (parse_args): Change version printing to match current GNU
+ standards.
+ * gasp.c (show_usage): Print bug report address.
+ (main): Change version printing to match current GNU standards.
+
+ * config/tc-m68k.c (init_table): Correct access control unit
+ register numbers. From Ken Rose <rose@netcom.com>.
+
+ * config/tc-alpha.c: Add some static function prototypes.
+ (alpha_macros): Move to top of file. Make static.
+ (alpha_num_macros): Move to top of file.
+
+Tue Oct 1 09:36:19 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * config/tc-v850.h: Define LOCAL_LABEL to recognise _.L_* symbols
+ generated by DWARF.
+
+Sat Sep 28 03:38:08 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * listing.c (list_symbol_table): Remove bogus code in BFD64 case,
+ and just call sprintf_vma.
+
+Thu Sep 26 16:04:11 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * expr.c (expr): Change >>= to >> (fix typo). (From meissner).
+
+Tue Sep 24 19:05:08 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (float_cons): Call md_flush_pending_output if it is
+ defined.
+
+Tue Sep 24 12:22:18 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (md_operand): Created. Allows operands to
+ start with '#'.
+ * config/tc-d10v.h (md_operand): Undefined.
+
+Mon Sep 23 12:13:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (add_fix): Treat a width of '3' like 'B'.
+ (md_assemble): A fixup width of '3' means a 1 byte reloc.
+
+Thu Sep 19 12:21:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): Don't adjust PC relative
+ reloc for the i960 for a reloc in the same section. This undoes
+ one of the two changes made Aug 19.
+
+Wed Sep 18 12:11:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (obj_coff_endef): Both versions: Move C_STAT
+ symbols to the position of the debugging information.
+
+Mon Sep 16 11:41:40 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * expr.c (expr): Always use unsigned right shifts for >>.
+
+Thu Sep 12 10:25:45 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-arm.c (md_apply_fix3): Update two thumb instruction
+ slots when processing BL fixups.
+
+ * config/tc-arm.c (output_inst): Ensure Thumb BL fixup is marked
+ on the first half of the instruction.
+
+Wed Sep 11 00:09:35 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (ecoff_stab): Create an expression symbol for a complex
+ stabs expression, rather than giving an error.
+
+ * ecoff.c (ecoff_new_file): Don't do anything if we are still in
+ the same file.
+
+Tue Sep 10 11:45:37 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (append_insn): Fill in the value for a constant
+ jump, rather than creating a reloc.
+
+Mon Sep 9 10:57:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (append_insn): Don't swap an instruction which
+ sets a condition code with an instruction which uses a condition
+ code.
+ (mips_ip): In cases 'N' and 'M', look for $fccN rather than an
+ immediate value.
+
+ * config/tc-mips.c (md_begin): Recognize r5000 for cpu.
+ (mips_ip): Give a better error message if the ISA level is wrong.
+ (md_parse_option): Recognize -mcpu=[v][r]5000.
+
+Sat Sep 7 13:25:55 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-mips.c (COUNT_TOP_ZEROES): Added macro to count
+ leading zeroes.
+ (load_register): Ensure hi32 bits are not lost during lo32bit
+ processing. Fix shift offset that was overflowing into the next
+ instruction field. Add code to generate shorter sequences for
+ constants with a single contiguous seqeuence of ones.
+
+Fri Sep 6 17:07:12 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (d10v_dot_word): New function to support
+ "@word" with the word pseudo-op.
+ (md_apply_fix3): Cleanup and changes to support correct sizes
+ for 16 and 18-bit relocs.
+
+Fri Sep 6 16:00:29 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.in (sparc-*-aout): Set `em'.
+ * configure: Regenerated.
+ * config/te-sparcaout.h: New file.
+ * config/tc-sparc.h (TARGET_BYTES_BIG_ENDIAN): Define.
+ Ifdef TE_SPARCOUT define TARGET_FORMAT and SPARC_BIENDIAN.
+ * config/tc-sparc.c (INSN_BIG_ENDIAN): New macro.
+ (SPECIAL_CASE_{SETSW,SETX}): Define.
+ ({NOP,OR,FMOVS,SETHI,SLLX,SRA}_INSN): Define.
+ (md_begin): Delete setting of `target_big_endian'.
+ (output_insn): New function.
+ (md_assemble): Rewrite. Add `setx' support.
+ (sparc_ip): Handle `0' operand char. Recognize setuw, setsw, setx
+ special cases.
+ (md_atof): Add little endian support.
+ (md_number_to_chars): Likewise.
+ (md_apply_fix): Likewise.
+ (md_longopts): Recognize -EL,-EB ifdef SPARC_BIENDIAN.
+ (md_parse_option): Likewise.
+ (md_show_usage): Print -EL, -EB ifdef SPARC_BIENDIAN.
+
+Thu Sep 5 13:40:29 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (ecoff_new_file): New function.
+ * ecoff.h (ecoff_new_file): Declare.
+ * config/obj-ecoff.h (obj_app_file): Define.
+
+Thu Sep 5 13:39:25 1996 Richard Henderson <rth@tamu.edu>
+
+ * config/tc-alpha.c (load_expression): Bias the .lit8 section
+ symbol by 32k so that our 16-bit signed offset can address the
+ entire chunk. Reported by <matt@lkg.dec.com>.
+
+Wed Sep 4 10:23:20 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (load_register): Remove unused variable tmp.
+
+Wed Sep 4 11:24:29 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-mips.c (load_register): Remove unnecessary code that
+ was causing the high 32bits of 64bit constants to be lost.
+
+Tue Sep 3 13:52:56 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Added changes to support function
+ pointers and "@word" syntax.
+
+Tue Sep 3 11:57:18 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c: Remove commented out and #if 0'd code.
+ (v850_reloc_prefix): Provide prototype.
+ (postfix, get_reloc, build_insn): Remove prototypes for nonexistant
+ functions.
+ (md_begin, md_assemble, md_apply_fix3): Remove unused variables.
+ (md_assemble): Add default to case statement.
+
+Sat Aug 31 16:03:00 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_assemble): Compute size of the instrction
+ from the opcode.
+
+ * config/tc-v850.c (md_apply_fix3): Do simple byte, short and
+ word fixups too.
+
+Fri Aug 30 23:50:08 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_apply_fix3): Use little endian get/put
+ routines to fetch/store the updated instruction from/to memory.
+ (v850_insert_operand): If the operand has a specialized insert
+ routine, call it.
+
+Fri Aug 30 18:35:26 1996 J.T. Conklin <jtc@hippo.cygnus.com>
+
+ * config/tc-v850.c (reg_name_search): Align calling convention to
+ be like identical function found in tc-ppc.c.
+ (get_reloc): Removed.
+ (v850_reloc_prefix): New function, parse lo(), hi() and hi0().
+ (md_assemble): emit fixups.
+ (md_pcrel_from): renamed from md_pcrel_from_section, emit proper
+ displacement.
+ (md_apply_fix3): handle fixups/relocs.
+ * config/tc-v850.h (MD_PCREL_FROM_SECTION): Removed definition.
+
+Fri Aug 30 18:12:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ Add SH ELF support.
+ * configure.in (sh-*-elf*): New target.
+ * config/tc-sh.h (TARGET_ARCH): Define.
+ (WORKING_DOT_WORD): Define.
+ (TC_COFF_FIX2RTYPE): Only define if OBJ_COFF.
+ (BFD_ARCH, COFF_MAGIC, TC_COUNT_RELOC): Likewise.
+ (TC_RELOC_MANGLE, tc_coff_symbol_emit_hook): Likewise.
+ (DO_NOT_STRIP, NEED_FX_R_TYPE, TC_KEEP_FX_OFFSET): Likewise.
+ (TC_COFF_SIZEMACHDEP, tc_frob_file): Likewise.
+ (SUB_SEGMENT_ALIGN): Likewise.
+ (RELOC_32): Don't define.
+ (tc_frob_file_before_adjust): Define if BFD_ASSEMBLER.
+ (target_big_endian): Declare if OBJ_ELF.
+ (TARGET_FORMAT): Define if OBJ_ELF.
+ * config/tc-sh.c: Use BFD reloc codes instead of SH COFF reloc
+ numbers throughout.
+ (tc_crawl_symbol_chain): Only define if OBJ_COFF.
+ (tc_headers_hook, tc_coff_sizemachdep): Likewise.
+ (struct sh_count_relocs): Define.
+ (sh_count_relocs): New static function, broken out of
+ sh_frob_file. Add BFD_ASSEMBLER code.
+ (sh_frob_section): Likewise.
+ (sh_frob_file): Call sh_frob_section.
+ (md_convert_frag): If BFD_ASSEMBLER, change type of headers, and
+ call section_symbol rather than seg_info (seg)->dot.
+ (md_section_align): Add OBJ_ELF version.
+ (SWITCH_TABLE_CONS): Define.
+ (SWITCH_TABLE): Use SWITCH_TABLE_CONS.
+ (md_apply_fix): Change parameter types if BFD_ASSEMBLER. Only
+ handle fx_r_type == 0 if not BFD_ASSEMBLER. Return 0 if
+ BFD_ASSEMBLER.
+ (struct reloc_map): Define if not BFD_ASSEMBLER.
+ (coff_reloc_map): Likewise.
+ (sh_coff_reloc_mangle): Use coff_reloc_map to convert fx_r_type.
+ (tc_gen_reloc): New function if BFD_ASSEMBLER.
+ * write.c (write_relocs): Ifdef out fx_where test which triggers
+ inappropriately for SH ELF.
+ (write_object_file): Call tc_frob_file_before_adjust and
+ obj_frob_file_before_adjust if they are defined.
+
+ * write.c (write_object_file): Use BFD_RELOC_16, not
+ BFD_RELOC_NONE, when calling fix_new_exp for a broken word.
+
+ * read.c (emit_expr): Fix conversion of byte count to BFD reloc
+ code.
+
+Fri Aug 30 14:47:38 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (find_opcode): Fix problem with calculating
+ branch sizes in across sections.
+
+Fri Aug 30 00:44:13 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-850.c (md_assemble): Handle hi() correctly. Handle
+ hi0() too.
+
+Wed Aug 28 23:11:08 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_begin): Deal with end of opcode
+ table marker.
+
+Wed Aug 28 19:20:04 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (find_opcode): Fix a bug which could generate
+ the wrong opcode for cases like st2w where there are many forms
+ of the same instruction.
+
+Tue Aug 27 13:53:22 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * expr.c (operand): If md_parse_name is defined, call it before
+ calling symbol_find_or_make.
+ * config/tc-ppc.h (md_parse_name): Define.
+ (ppc_parse_name): Declare.
+ * config/tc-ppc.c (reg_name_search): Add regs and regcount
+ parameters.
+ (register_name): Update call to reg_name_search.
+ (cr_operand): New static variable.
+ (cr_names): New static const array.
+ (ppc_parse_name): New function.
+ (md_assemble): If PPC_OPERAND_CR is set in the operand flags, set
+ cr_operand before calling expression.
+
+Tue Aug 27 09:05:50 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (tc_gen_reloc): Add new argument to
+ hppa_gen_reloc_type call.
+
+Mon Aug 26 18:24:51 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Fixed ".word". Fixed problem with range checking
+ on addresses. Improved error messages.
+ * doc/c-d10v.texi: Added docs for register pairs.
+
+Mon Aug 26 13:39:27 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (parallel_ok): Fix bug in parallel
+ checking code.
+
+Mon Aug 26 14:38:22 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (init_file): Initialize fMerge to 1.
+ (add_file): Restore old file merging code, but only merge files if
+ fMerge is set.
+ (ecoff_directive_loc): Clear fMerge field of current file.
+ (ecoff_generate_asm_lineno): Likewise.
+
+Fri Aug 23 11:40:47 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * doc/c-d10v.texi: Fix typo.
+
+Fri Aug 23 10:41:32 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_assemble): Correct bit masking for
+ hi and lo expressions.
+
+ * config/tc-v850.c (md_assemble): Rough cut at demanding
+ "ep" or "r30" in sst and sld instructions.
+ (md_apply_fix3): Don't abort. Just warn that we don't
+ have relocs yet.
+
+ * config/tc-v850.c (CC_NAME_CNT): Define.
+ (cc_name): New function.
+ (md_assemble): Handle V850_OPERAND_CC correctly.
+
+ * config/tc-v850.c (md_assemble): Don't forget to initialize
+ "insn"!
+
+ * config/tc-v850.c (reg_name_search): Generalize to search
+ any given register table.
+ (register_name): Pass appropriate table and size to reg_name_search.
+ (system_register_name): New function.
+ (SYSREG_NAME_CNT): Define.
+ (md_assemble): Handle operands which are system registers.
+
+ * config/tc-v850.c (md_assemble): If we find a register, but the
+ opcode doesn't want a register, then we don't have a match.
+ (md_assemble): Get size of the instruction from the opcode table.
+
+Thu Aug 22 10:20:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set and substitute HLDENV.
+ * configure: Rebuild.
+ * Makefile.in (HLDENV): New variable.
+ (as.new): Use $(HLDENV).
+
+ * ecoff.c (ecoff_directive_endef): Avoid a division by zero error
+ if an array dimension is not known.
+
+Thu Aug 22 10:50:00 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Fix a reloc bug caused by my last change.
+ * doc/c-d10v.texi: Cleanup.
+
+Tue Aug 20 15:15:16 1996 J.T. Conklin <jtc@hippo.cygnus.com>
+
+ * config/tc-v850.c: New file.
+ * config/tc-v850.h: New file.
+ * configure (v850-*-elf): New target.
+ * configure.in (v850-*-elf): New target.
+
+Wed Aug 21 15:50:54 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * doc/c-d10v.texi: New file.
+ * doc/all.texi: Added D10V stuff.
+ * doc/as.texinfo: Added D10V stuff.
+
+Tue Aug 20 14:10:02 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: All references to defined symbols should
+ now use the optimal instruction. .float and .double now work.
+
+Mon Aug 19 14:41:36 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): Adjust PC relative reloc by
+ section address for the i960 as is done for the i386.
+
+Thu Aug 15 16:37:59 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Add wildcards for config matching, add mips-*-*
+ case, forward-include bfd/elf-bfd.h.
+
+Thu Aug 15 13:24:30 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Add additional information to the opcode
+ table to help determinine which instructions can be done
+ in parallel.
+
+Thu Aug 15 17:01:31 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-arm.c: Major changes to add Thumb support, with lots
+ of change input from <rearnsha@armltd.co.uk>.
+ Reverted to INSN_SIZE macro, rather than insn_size variable.
+ (insns): Added ARM "bx" instruction support.
+ (tinsns): Added Thumb instruction definition structure.
+ (arm_tops_hsh): Added hash structure for Thumb opcodes.
+ (md_pseudo_table): Added ".arm", ".thumb" and ".code" pseudo-ops.
+ (opcode_select,s_arm,s_thumb,s_code): Added.
+ (decode_shift): Allow upper-case RRX.
+ (do_ldst): Simpler halfword support.
+ (do_ldmstm): Improved.
+ (reg_list, do_bx, thumb_reg, thumb_add_sub, thumb_shift,
+ thumb_mov_compare, thumb_load_store, do_t_arit, do_t_add,
+ do_t_asr, do_t_branch, do_t_bx, do_t_compare, do_t_ldmstm,
+ do_t_ldrb, do_t_ldrh, do_t_lds, do_t_lsl, do_t_lsr, do_t_mov,
+ do_t_push_pop, do_t_str, do_t_strb, do_t_strh, do_t_sub, do_t_swi,
+ do_t_adr): Added.
+ (md_apply_fix3): Add support for BFD_RELOC_ARM_THUMB_* relocations.
+ (md_parse_option): Add support for -mthumb.
+ (md_show_usage): Updated to reflect new command line option.
+ (arm_data_in_code, arm_canonicalize_symbol_name): Added.
+ * config/tc-arm.h: Provide TC_FIX_TYPE to allow private ARM
+ fragment information to be held.
+
+Thu Aug 15 16:12:00 1996 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * config/tc-arm.c (md_apply_fix3): Also set fixP->fx_done if fx_addsy is
+ non-null, but is a constant.
+ (fix_new_arm): Call make_expr_symbol to make the expression symbol
+ so that error reporting will work correctly.
+
+Wed Aug 14 10:37:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Don't adjust relocs
+ against weak symbols.
+
+Tue Aug 13 17:39:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.h (TC_FORCE_RELOCTION): Define if OBJ_XCOFF.
+ (ppc_force_relocation): Declare if OBJ_XCOFF.
+ * config/tc-ppc.c (ppc_force_relocation): New function if
+ OBJ_XCOFF.
+
+Mon Aug 12 16:49:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.h (BYTE_ORDER): Don't define. No longer used.
+
+Fri Aug 9 17:48:28 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Fix problem with relocs.
+
+Fri Aug 9 14:16:14 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (sh_do_align): If not BFD_ASSEMBLER, always align
+ with nops if not in data_section or bss_section.
+
+Thu Aug 8 12:32:56 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ Add support for openVMS/Alpha.
+ * as.h (PRINTF_LIKE): Don't define if VMS, for now.
+ * config/obj-evax.c: New file.
+ * config/obj-evax.h: New file.
+ * config/tc-alpha.c: Add support for EVAX format if OBJ_EVAX is
+ defined.
+ * config/tc-alpha.h: Add support for EVAX format if OBJ_EVAX is
+ defined. Add case for bfd_target_evax_flavour.
+ * config/vms-a-conf.h: New file.
+ * conf-a-gas.com: New file.
+ * configure.in: Add target alpha-*-*vms*.
+ * configure: Rebuild.
+ * makefile.vms: New file.
+ * read.c (s_lcomm): Align bss_seg on 8 byte boundary if OBJ_EVAX.
+ Don't call ffs on openVMS/Alpha.
+
+Wed Aug 7 14:19:03 1996 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * configure.in: Make GAS_CHECK_DECL_NEEDED include <string.h> or
+ <strings.h> if they exist. Call GAS_CHECK_DECL_NEEDED on strstr
+ and sbrk.
+ * acconfig.h (NEED_DECLARATION_STRSTR): New macro.
+ (NEED_DECLARATION_SBRK): New macro.
+ * configure, conf.in: Rebuild.
+ * as.h: Only include <strings.h> if HAVE_STRINGS_H.
+ (strstr): Declare if NEED_DECLARATION_STRSTR.
+ * as.c: If HAVE_SBRK and NEED_DECLARATION_SBRK, declare sbrk.
+
+Wed Aug 7 11:50:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (resolve_symbol_value): Handle addition or subtraction
+ by a constant before entering the main switch. Reject attempts to
+ apply an arithmetic function to non-absolute symbols, except for
+ the special case of subtraction of two symbols in the same
+ section.
+
+ * config/tc-mips.c (md_section_align): Do align if OBJ_ELF, but
+ not to more than a 16 byte boundary.
+
+ * config/tc-i386.c (tc_gen_reloc): Accept all relocs; remove
+ #ifndef OBJ_ELF lines. From Eric Valette <valette@crf.canon.fr>.
+ (tc_gen_reloc): If out of memory call as_fatal rather than
+ assert. If no howto found, call as_bad_where rather than
+ as_fatal. Change the error message slightly. Set howto to a
+ non-NULL value in order to keep going.
+
+Tue Aug 6 12:58:03 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Added code to support 32-bit fixups for stabs.
+
+Tue Aug 6 11:15:26 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-h8300.c (get_specific): New operand "size" derived
+ from ".b", ".w" and ".l" extensions. All callers changed. If
+ the base instruction has no operands, then use the size to
+ determine which specific instruction to use.
+
+Mon Aug 5 14:21:10 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i960.c (mem_fmt): Call parse_expr before emit.
+
+Fri Aug 2 11:23:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_section_align): Don't change addr if
+ OBJ_ELF.
+
+Thu Aug 1 23:51:52 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c: Revert yesterday's changes.
+
+Wed Jul 31 14:46:11 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Disable range checking on 16-bit values.
+
+Wed Jul 31 16:27:19 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Set ok_arch for every instruction,
+ not just the ones that don't match.
+
+Wed Jul 31 11:45:15 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Fixed bugs in short relocs and range checking.
+
+Wed Jul 31 15:41:42 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-arm.c: Changed INSN_SIZE to variable insn_size, as
+ pre-cursor to adding Thumb support. Also added cpu_variant flag
+ information to each of the asm_flg structures.
+ (md_parse_option): Updated ARM7 parsing to allow 't' for
+ thumb/halfword support, aswell as 'm' for long multiply.
+ (md_show_usage): Updated help message.
+ (md_assemble): Check that instruction flags are applicated to the
+ current cpu variant.
+ (md_apply_fix3, tc_gen_reloc): Add BFD_RELOC_ARM_OFFSET_IMM8 and
+ BFD_RELOC_ARM_HWLITERAL relocation support for new halfword and
+ signextension instructions.
+ (do_ldst): Generate halfword and signextension variants if
+ mnemonic flags match.
+ (ldst_extend): Do not allow shifts in the offset field of halfword
+ or signextension instructions.
+ (validate_offset_imm): Provide check on halfword and signextension
+ immediate range.
+ (add_to_lit_pool): Merge identical literal pool values.
+
+Tue Jul 30 14:28:23 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (selector_table): Add 'E' selector.
+ (cons_fix_new_hppa): Don't coke on e_esel.
+ (tc_gen_reloc, SOM version): Handle R_COMP2 when used
+ to help generate exception handling tables.
+ (md_apply_fix): Don't try to apply fixups with an e_esel
+ selector.
+ (hppa_fix_adjustable): Fixups with e_esel selectors
+ are not adjustable.
+
+Tue Jul 30 15:51:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c (md_pseudo_table): Add 2byte, 4byte, and 8byte
+ pseudo-ops.
+
+Fri Jul 26 11:43:03 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Added lots of error checking. Added hacks
+ to support accumulator shifts.
+
+Fri Jul 26 11:56:08 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (S_SET_EXTERNAL): Let .weak override.
+ (S_CLEAR_EXTERNAL): Likewise.
+ (S_SET_WEAK): Remove error; just let .weak override.
+
+Thu Jul 25 15:22:51 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (md_assemble): Now handles multiline
+ instructions.
+
+Thu Jul 25 12:03:33 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Fix packaging bug. Added range checking.
+ Added kludge for divs instruction. Fixed minor problem with
+ multiple text sections.
+ * config/tc-d10v.h (d10v_cleanup): Change prototype.
+
+Tue Jul 23 10:49:36 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (md_apply_fix3): Fix all instruction
+ addresses to be right-shifted by 2.
+
+Mon Jul 22 11:32:36 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Many changes to get relocs working.
+ (register_name): No longer creates a symbol for register names.
+ (pre_defined_registers): moved to opcodes/d10v-opc.c.
+ (d10v_insert_operand): Now works correctly for either container.
+ * config/tc-d10v.h (d10v_cleanup): Declare.
+
+Mon Jul 22 14:01:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (tc_gen_reloc): BFD_RELOC_PCREL_HI16_S and
+ BFD_RELOC_PCREL_LO16 are expected to be PC relative.
+
+Mon Jul 22 12:46:55 1996 Richard Henderson <rth@tamu.edu>
+
+ * config/tc-alpha.c: Patches to track current minimum alignment to reduce
+ the number of fragments created with frag_align.
+ (alpha_current_align): New static variable.
+ (s_alpha_text): Reset alignment to 0.
+ (s_alpha_data, s_alpha_rdata, s_alpha_sdata): Likewise.
+ (s_alpha_stringer, s_alpha_space): New functions.
+ (s_alpha_cons, alpha_flush_pending_output): Remove functions.
+ (alpha_cons_align): New function to replace both of them.
+ (emit_insn): Only align if alpha_current_align is less than 2;
+ reset alpha_current_align to 2.
+ (s_alpha_gprel32): Likewise.
+ (s_alpha_section): New function. Basically duplicate the other
+ alpha section change hooks. Only define for ELF.
+ (s_alpha_float_cons): Simplify alignment handling.
+ (md_pseudo_table): Only define "rdata" and "sdata" if OBJ_ECOFF.
+ If OBJ_ELF, define "section", "section.s", "sect", and "sect.s".
+ Don't define the s_alpha_cons pseudo-ops. Do define
+ s_alpha_stringer and s_alpha_space pseudo-ops.
+ (alpha_align): Skip if less than current default alignment. Set
+ default alignment.
+ * config/tc-alpha.h (md_flush_pending_output): Remove.
+ (md_cons_align): Add.
+
+ * config/tc-alpha.c: Add oodles of function description comments.
+ (md_bignum_to_chars): Remove; there are no callers.
+ (md_show_usage): Mention some more variants.
+
+Thu Jul 18 15:54:54 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ From Andrew Gierth <ANDREWG@microlise.co.uk>:
+ * configure.in (sparc-*-sysv4*): New target.
+ * configure: Rebuild.
+
+ * config/tc-sparc.c (md_pseudo_table): Change uahalf, uaword, and
+ uaxword to use s_uacons.
+ (sparc_no_align_cons): New static variable.
+ (s_uacons): New static function.
+ (sparc_cons_align): If sparc_no_align_cons is set, just clear it
+ and return.
+
+ * config/tc-sparc.c (s_common): Remove unused label allocate_bss.
+
+ * configure.in: Add mips-*-irix6* target. Handle Irix 6 like Irix
+ 5 with regard to shared libraries.
+ * configure: Rebuild.
+
+ * config/tc-m68k.c (m68k_ip): Use the correct length when
+ allocating space for the unsupported architecture error message.
+
+Thu Jul 18 12:57:10 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (d10v-*-*): Allow d10v-*-*, don't require d10v-*-elf*.
+
+Wed Jul 17 14:25:13 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: New file.
+ * config/tc-d10v.h: New file.
+ * configure (d10v-*-elf): New target.
+ * configure.in (d10v-*-elf): New target.
+
+Fri Jul 12 20:54:19 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (md_parse_option): Recognize -K PIC.
+
+Wed Jul 10 12:39:08 1996 Richard Henderson <rth@tamu.edu>
+
+ * config/tc-alpha.c (alpha_align): Change fill parameter
+ to a pointer. Take NULL as 0 or nop depending on section. Change
+ all callers.
+ (s_alpha_align): Rename local variables.
+
+ * doc/as.texinfo (.align): Document action of omitted
+ fill parameter.
+
+Wed Jul 10 00:23:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (md_apply_fix3): Give a useful error message
+ when an unsupported PC relative reloc is seen, rather than calling
+ abort.
+
+ * app.c (do_scrub_chars): Remove not_cpp_line local variable.
+ Instead, check state when '#' comment is seen.
+
+Mon Jul 8 14:11:49 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_regmask_frag): Only define if OBJ_ELF or
+ OBJ_MAYBE_ELF.
+ (tc_gen_reloc): If fixup was changed to be PC relative, change
+ reloc type accordingly. Use name of reloc in error message.
+
+ * as.h: Don't define const or volatile.
+ * flonum.h: Don't define const.
+
+ * config/tc-m68k.c (tc_gen_reloc): Change the code appropriately
+ if fx_pcrel is set. Correct setting the addend case in the
+ OBJ_ELF case (from Andreas Schwab
+ <schwab@issan.informatik.uni-dortmund.de>).
+ (md_show_usage): Correct -mfc5200 to -m5200.
+
+Fri Jul 5 10:32:58 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * doc/c-m68k.texi: Document -m5200 flag.
+ * doc/as.texinfo: Likewise.
+
+ * config/tc-m68k.c (m68k_ip): The coldfire does not support 8x
+ scale factor.
+
+Fri Jul 5 11:07:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (S_SET_EXTERNAL): Change as_warn to as_bad.
+ (S_CLEAR_EXTERNAL, S_SET_WEAK): Likewise.
+
+Thu Jul 4 11:59:46 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (VERSION): Set to cygnus-2.7.1.
+
+ * Released binutils 2.7.
+
+Thu Jul 4 10:11:33 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-mips.c (mips_ip): Only perform range check when
+ dealing with O_constant expressions.
+
+Wed Jul 3 15:02:21 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * m68k-parse.h (m68k_register): Add new coldfile control
+ registers.
+
+ * config/tc-m68k.c (mcf5200_control_regs): New variable,
+ array of control registers for the coldfire.
+ (cpu_of_arch): Added mcf5200.
+ (archs): Added mcf5200.
+ (init_table): Add new control registers.
+ (m68k_ip): Added support for new control registers.
+ (m68k_init_after_args): Likewise.
+
+ * config/tc-m68k.c (md_show_usage): Add -m5200 to usage text.
+
+Wed Jul 3 16:05:50 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.h (is_it_end_of_statement): Declare.
+ * read.c (is_it_end_of_statement): Remove declaration.
+
+ * config/tc-ppc.c (ppc_elf_suffix): Correct parenthesization of ||
+ within &&.
+ (md_assemble): Fix handling of @l with an unsigned constant. Add
+ default case to reloc switch.
+
+ * config/tc-i386.h (AOUT_MACHTYPE): Define as 0 if TE_386BSD.
+
+ Based on patches from Tom Quiggle <quiggle@sgi.com>:
+ * ecoff.c (last_lineno): New static variable.
+ (add_procedure): Set last_lineno.
+ (ecoff_directive_loc): Likewise.
+ (ecoff_generate_asm_lineno): Likewise.
+ (ecoff_fix_loc): New function.
+ * ecoff.h (ecoff_fix_loc): Declare.
+ * config/tc-mips.c (append_insn): When inserting nops, and using
+ ECOFF debugging, call ecoff_fix_loc.
+
+Tue Jul 2 23:02:12 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-h8300.c (build_bytes): If an operand type is
+ marked as SRC_IN_DST retrieve it from the "destination" op.
+
+Sat Jun 29 13:38:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in (arm-*-riscix*): Set emulation to riscix.
+ * configure: Rebuild.
+ * config/te-riscix.h: New file to define TE_RISCIX.
+
+ * config/tc-sh.h (SUB_SEGMENT_ALIGN): Define.
+
+Fri Jun 28 15:14:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (config.status): Just run config.status as other
+ tools do.
+
+Fri Jun 28 11:09:38 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in (TARGET_OS): Add definition to conf.
+
+Thu Jun 27 20:39:40 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-mips.c (append_insn): Parenthesize
+ cop_interlocks expressions.
+
+Thu Jun 27 12:18:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * listing.c (listing_print): Close the listing file if it is not
+ stdout. Close the other files opened for the listing.
+
+ * config/tc-sparc.h (md_cons_align): Define.
+ (sparc_cons_align): Declare.
+ (HANDLE_ALIGN): Define.
+ (sparc_handle_align): Declare.
+ * config/tc-sparc.c (sparc_cons_align): New function.
+ (sparc_handle_align): New function.
+ * read.c (cons_worker): Call md_cons_align if it is defined.
+
+ * as.h (struct frag): Add fr_file and fr_line fields.
+ * frags.c (frag_new): Set fr_file and fr_line.
+ (frag_var): Likewise.
+ (frag_variant): Likewise.
+
+ * as.h (struct frag): Remove unused align_mask and align_offset
+ fields.
+
+ * listing.c (calc_hex): Offset by fr_fix when examining fr_var.
+ From <uddeborg@carmen.se>.
+
+Wed Jun 26 13:21:34 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in (mips-*-osf*): New target.
+ * configure: Rebuild.
+
+ * config/tc-m68k.c: Add 68ec060 as a synonym for 68060.
+
+Wed Jun 26 16:23:08 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-mips.c: Added cop_interlocks, to avoid NOP insertion
+ between co-processor comparisons and branches for the VR4300.
+
+Mon Jun 24 18:02:50 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (bindir, libdir, datadir, mandir, infodir, includedir,
+ INSTALL_PROGRAM, INSTALL_DATA): Use autoconf-set values.
+ (docdir): Removed.
+ * configure.in (AC_PREREQ): autoconf 2.5 or higher.
+ * doc/Makefile.in (bindir, libdir, datadir, mandir, infodir,
+ includedir): Use autoconf set values.
+ (docdir): Removed.
+
+Mon Jun 24 11:58:14 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * listing.c (listing_eject): Don't do anything if listing is 0.
+ (listing_list): Likewise.
+ (listing_source_line): Likewise.
+ (listing_title): Don't save title if listing is 0.
+ (listing_source_file): Check listing rather than listing_tail.
+
+ * configure.in: On alpha*-*-osf*, link against libbfd.a if not
+ using shared libraries.
+ * configure: Rebuild.
+
+Fri Jun 21 18:22:23 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_ip): In case 'i'/'j', don't require an
+ absolute expression if a relocation type was specified.
+
+Fri Jun 21 17:40:16 1996 Joel Sherrill <joel@merlin.gcs.redstone.army.mil>
+
+ * configure.in: Add support for *-*-rtems* configurations.
+ * configure: Rebuild.
+
+Fri Jun 21 16:01:18 1996 Richard Henderson <rth@tamu.edu>
+
+ * configure.in: Add alpha-*-linuxecoff* target. Use elf for
+ alpha-*-linux* target. Force bfd_gas for alpha-*. Require
+ opcodes library for alpha.
+ * configure: Rebuild with autoconf 2.10.
+ * config/tc-alpha.c: Substantial rewrite to add ELF support and
+ use new opcode table.
+ * config/tc-alpha.h (md_undefined_symbol): Don't define.
+ (LOCAL_LABEL): Define differently if OBJ_ELF.
+ (FAKE_LABEL_NAME): Define if OBJ_ELF.
+ * config/alpha-opcode.h: Remove.
+ * config/obj-elf.h: If TC_ALPHA, define ECOFF_DEBUGGING.
+ * Makefile.in (TARG_CPU_DEP_alpha): Depend upon
+ include/opcode/alpha.h rather than config/alpha-opcode.h.
+
+Thu Jun 20 19:10:28 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-aout.c (obj_emit_relocations): Give an error if the
+ relocation symbol was not resolved.
+ * config/obj-coff.c (do_relocs_for): Likewise.
+
+ * write.c (adjust_reloc_syms): Refetch the symbol section after
+ calling S_GET_VALUE, since it may have changed.
+
+ * expr.c (struct expr_symbol_line): Define.
+ (expr_symbol_lines): New static variable.
+ (make_expr_symbol): Add entry to expr_symbol_lines.
+ (expr_symbol_where): New function.
+ * expr.h: Use extern on function declarations.
+ (expr_symbol_where): Declare.
+ * symbols.c (resolve_symbol_value): Try to use expr_symbol_where
+ rather than printing the meaningless name of an expression
+ symbol.
+
+Thu Jun 20 15:57:41 1996 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/tc-i386.c (md_number_to_chars): Deleted.
+ * config/tc-i386.h (md_number_to_chars): New macro.
+
+ * config/tc-alpha.c (build_operate_n, build_mem): Moved earlier in
+ the file.
+ (load_symbol_address, load_expression): Use build_mem.
+ (build_operate): New function.
+ (emit_addq_r): Use it.
+
+ Wed Mar 13 22:14:14 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * symbols.c (colon): #if VMS, use S_SET_OTHER to store `const_flag'.
+
+ Tue Mar 5 14:31:45 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/tc-vax.h (NOP_OPCODE): Define.
+
+ Sun Feb 4 21:01:03 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.h (S_IS_COMMON): Define.
+ (S_IS_LOCAL): Check for \002 as well as \001.
+ (LONGWORD_ALIGNMENT): New macro.
+ (SUB_SEGMENT_ALIGN): Use it.
+
+ Fri Jan 26 17:44:09 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/vms-conf.h: Reconcile with conf.in.
+
+Wed Jun 19 11:31:50 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (is_dnrange): Only define if TC_GENERIC_RELAX_TABLE is
+ defined.
+
+ * doc/as.texinfo: Document that any number of hex digits can
+ follow \x.
+
+ * as.c (struct defsym_list): Define.
+ (defsyms): New static variable.
+ (parse_args): Just put --defsym arguments on defsyms list, rather
+ than defining them.
+ (main): Define defsyms after output file is created.
+
+ * config/tc-m68k.c (m68k_ip): Reject PRE and POST indexing mode on
+ cpu32. From Eric Norum <Eric.Norum@usask.ca>.
+
+ * config/tc-mips.c (mips_ip): In cases 'I', 'i', and 'j', set
+ insn_error rather than calling check_absolute_expr.
+
+ * as.c (emulation_name): Remove unused static variable.
+ (default_emul_bfd_name): Add return NULL to avoid warning.
+ * ecoff.c (ecoff_stab): Remove unused variables name and
+ name_end.
+ * frags.c (frag_new): Remove unused variable tmp.
+ * hash.c (hash_grow): Parenthesize + within <<.
+ (hash_print_statistics): Use %lu, not %d, to print unsigned
+ long variables.
+ * messages.c: Include "libiberty.h".
+ (fprint_value): Add cast to avoid printf warning.
+ (sprint_value): Likewise.
+ * read.c: Include "ecoff.h".
+ (emit_expr): Add casts to avoid printf warnings.
+ * read.h: Use extern for function declarations.
+ (pop_insert): Declare.
+ * stabs.c: Include "ecoff.h".
+ * subsegs.c (subseg_set_rest): Remove unused variables tmp,
+ former_last_fragP, and new_fragP.
+ * subsegs.h (subsegs_print_statistics): Declare.
+ * symbols.c (debug_verify_symchain): Change macro to discard
+ arguments.
+ * write.c (dump_section_relocs): Likewise.
+ * write.h: Use extern for function declarations.
+ (write_print_statistics): Declare.
+ * config/e-mipsecoff.c (mipsecoff_bfd_name): Return NULL to avoid
+ warning.
+ * config/e-mipself.c (mipself_bfd_name): Likewise.
+ * config/obj-elf.h (elf_ecoff_set_ext): Declare.
+
+ * config/tc-sparc.h (TC_RELOC_RTSYM_LOC_FIXUP): If OBJ_ELF, always
+ emit relocations against external symbols.
+
+ * config/tc-alpha.c (tc_gen_reloc): Output a sensible error
+ message if bfd_reloc_type_lookup fails, rather than calling
+ assert.
+
+ * config/tc-alpha.c (alpha_force_relocation): Add
+ BFD_RELOC_12_PCREL to switch.
+
+Tue Jun 18 20:29:57 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-i386.h (LOCAL_LABEL,FAKE_LABEL_NAME): Use defaults for
+ TE_PE (Lfoo, not .Lfoo).
+
+Tue Jun 18 17:13:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (s_fill): Don't warn about a zero repeat count.
+
+ * config/tc-mips.c (mips_ip): Don't warn about using AT as a
+ coprocessor register.
+
+ * config/tc-i386.c (md_assemble): When checking the size of a
+ register to set the size of an instruction, do a bitwise and with
+ Reg8 and Reg16 rather than requiring the type to be exactly Reg8
+ or Reg16.
+
+Tue Jun 18 13:19:51 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * config/tc-h8300.c (parse_reg): Tweak error messages.
+ (build_bytes): Likewise.
+ (skip_colonthing): Handle :32 suffix.
+ (get_specific): Promote L_24 to L_32 if it makes a match.
+ Don't always promote L_8 to L_16.
+ (do_a_fix_imm): Clean up L_32 and L_24 handling.
+
+ * config/tc-h8300.c (Smode): New variable.
+ (h8300hmode): Turn off Hmode.
+ (h8300smode): New function. Turn on Smode and Hmode.
+ (md_pseudo_table): New ".h8300s" pseudo-op.
+ (parse_reg): Handle "exr" register.
+ (get_operand): Handle bizarre syntax for "stm.l" and "ldm.l".
+ Handle "mach" and "machl" operands for ldmac.
+ (get_specific): Handle "stm.l" and "ldm.l".
+ (build_bytes): Handle "stm.l" and "ldm.l"; handle MACREG operands.
+ * config/tc-h8300.h (COFF_MAGIC): Handle H8/S magic number.
+ (Smode): Declare.
+
+Mon Jun 17 15:50:53 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * doc/as.texinfo: Reorder chapter of machine dependent options so
+ that it is sorted by chip name.
+
+ * doc/as.texinfo: Use consistant spelling of Vax.
+ * doc/c-vax.texi: Likewise.
+
+Mon Jun 17 11:26:56 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * config/tc-hppa.c (md_pseudo_table): Add ".begin_try" and ".end_try"
+ pseudo ops.
+ (tc_gen_reloc, SOM version): Handle R_BEGIN_TRY and R_END_TRY.
+ (md_apply_fix): Likewise.
+ (pa_try): New function.
+ (hppa_force_relocation): Force relocs for BEGIN_TRY and END_TRY.
+
+Sun Jun 16 22:57:47 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * config/tc-hppa.c (md_pseudo_table): Add ".level" pseudo op.
+ (pa_level): New function.
+
+Fri Jun 14 20:06:44 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * listing.c (listing_newline): Don't do anything if listing is 0.
+
+Thu Jun 13 17:50:54 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * subsegs.c (section_symbol): If symbol_table_frozen is set, call
+ symbol_create, not symbol_new.
+
+Wed Jun 12 14:10:44 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (adjust_reloc_syms): Don't set sy_used_in_reloc for an
+ absolute symbol unless TC_FORCE_RELOCATION returns true.
+
+ * config/obj-coff.c (previous_file_symbol): Remove BFD_ASSEMBLER
+ version.
+ (c_dot_file_symbol): BFD_ASSEMBLER version: Don't set the value of
+ the symbol to a pointer. Don't set previous_file_symbol.
+ Simplify symbol list rearrangement.
+ (coff_frob_symbol): Don't do anything with C_FILE symbols.
+ (coff_adjust_symtab): Don't check previous_file_symbol.
+
+Mon Jun 10 14:52:29 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_lcomm): New function for .lcomm
+ directive.
+ (md_pseudo_table): Add ppc_elf_lcomm.
+
+Mon Jun 10 11:45:51 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Accept ABSL for 'O', so that `bfextu
+ d0{24:1},d0' works without an immediate prefix on the bit numbers.
+ (md_begin): Add digits to alt_notend_table.
+ (md_parse_option): Make s a const pointer.
+
+ * config/tc-sparc.c (md_pseudo_table): Add "empty".
+ (s_empty): New static function.
+
+ * config/obj-coff.c (struct filename_list): Only define if not
+ BFD_ASSEMBLER.
+ (filename_list_head, filename_list_tail): Likewise.
+ (c_section_symbol): Remove unused BFD_ASSEMBLER version.
+ (obj_coff_endef, BFD_ASSEMBLER version): Don't set the debugging
+ flag for C_MOS, C_MOE, C_MOU, or C_EOS symbols, since they should
+ have a section of N_ABS rather than N_DEBUG. If we do a merge,
+ remove the new symbol from the list.
+ (obj_coff_endef, both versions): Call tag_insert even if there is
+ an old symbol with the same name, if the old symbol does not
+ happen to be a tag.
+ (coff_frob_symbol): Check SF_GET_TAG, C_EOF, and C_FILE outside of
+ the SF_GET_DEBUG condition. Don't call SA_SET_SYM_ENDNDX with a
+ symbol that will be moved to the end of the symbol list.
+ (coff_adjust_section_syms): Always call section_symbol for .text,
+ .data, and .bss.
+ (coff_frob_section): Likewise. Also, remove unused variable
+ strname.
+
+ * config/tc-ns32k.c (convert_iif): Call frag_grow rather than
+ manipulating frags directly.
+ (md_number_to_field): Adjust mem_ptr correctly if ENDIAN is
+ defined.
+
+ * app.c (do_scrub_chars): If '/' is LINE_COMMENT_START, check
+ whether the next character is '*' before checking whether we are
+ at the start of a line. Permit LINE_COMMENT_START to start a
+ comment in state 1 (seen some whitespace) as well, to match the
+ documentation.
+
+ * gasp.c (do_align): Permit a fill value for .align.
+
+Wed Jun 5 17:09:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (next_char_of_string): Warn if a newline is seen in the
+ middle of a string. Call bump_line_counters when appropriate.
+
+Wed Jun 5 17:08:36 1996 Richard Henderson <rth@tamu.edu>
+
+ * symbols.c (colon): Use LOCAL_LABEL.
+
+Tue Jun 4 10:55:16 1996 Tom Tromey <tromey@csk3.cygnus.com>
+
+ * Makefile.in (install): Don't check to see if tooldir exists.
+ Make $(tooldir) and $(tooldir)/bin.
+
+Tue Jun 4 10:14:53 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/ppc-sol.mt (TDEFINES): Don't turn on -mregnames by
+ default.
+
+Mon Jun 3 11:34:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_ip): Don't call as_warn if we are setting
+ insn_error. Don't put the string "ERROR" in insn_error. Set
+ insn_error rather than calling as_warn for an unsupported opcode.
+
+Sat Jun 1 21:51:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_parse_option): Check for a 64 bit format
+ before permitting -64.
+ * output-file.c (output_file_create): Remove duplicate
+ bfd_perror.
+
+Fri May 31 01:08:06 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_begin): If -64, create a .MIPS.options
+ section rather than a .reginfo section.
+ (mips_elf_final_processing): If -64, write out 64 bit RegInfo
+ information.
+
+ * config/tc-mips.c (load_register): If mips_isa < 3, permit a 32
+ bit value with the high bit set.
+
+Thu May 30 19:00:19 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (s_lcomm): Set section flags for .sbss section.
+
+ * config/tc-mips.c (mips_64): New static variable.
+ (mips_target_format): If mips_64, return elf64 targets rather than
+ elf32 ones.
+ (md_longopts): Add "32" and "64".
+ (md_parse_option): Handle -32 and -64.
+ (md_show_usage): Mention -32 and -64.
+ (cons_fix_new_mips): If mips_64, don't convert an 8 byte reloc to
+ a 4 byte one.
+
+Thu May 30 10:36:19 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (comment_chars): Make '!' a comment character
+ for Solaris compatibility.
+
+ * stabs.c (s_stab_generic): Under PowerPC Solaris, convert a
+ .stabd with 4 arguments into a .stabn.
+
+Wed May 29 16:43:16 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (macro): When passing X_add_number to
+ macro_build, cast it to int first.
+
+Tue May 28 13:29:39 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-z8k.c (md_apply_fix): Handle fx_r_type of 0, as
+ created by emit_expr.
+
+ * symbols.c (symbol_create): If bfd_make_empty_symbol fails, call
+ as_perror rather than assert.
+
+Fri May 24 18:24:11 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_ip): Mark sections created to hold
+ floating point information as read only.
+
+Fri May 24 12:07:54 1996 David Edelsohn <edelsohn@mhpcc.edu>
+
+ * config/tc-ppc.c (ppc_set_cpu): Change defaults to match AIX.
+
+Thu May 23 17:34:24 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * read.c (potable): Add .skip as a synonym for .space.
+
+ * stabs.c (s_stab_generic): For PowerPC ELF, allow .stabd to take
+ 4 arguments, providing the 4th argument is 0, to allow
+ compatibility with the Solaris assembler.
+
+Thu May 16 15:51:48 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.h (struct sh_segment_info_type): Define.
+ (TC_SEGMENT_INFO_TYPE): Define.
+ (sh_frob_label): Declare.
+ (tc_frob_label): Define.
+ (sh_flush_pending_output): Declare.
+ (md_flush_pending_output): Define.
+ * config/tc-sh.c (md_assemble): If relaxing, emit a R_SH_CODE
+ reloc before the instruction if necessary.
+ (sh_frob_label): New function.
+ (sh_flush_pending_output): New function.
+ (sh_coff_frob_file): Ignore ALIGN, CODE, DATA, and LABEL relocs
+ when looking for the reloc for the target of .uses.
+ (md_convert_frag): Fix printf format (%0xlx to 0x%lx).
+ (sh_force_relocation): Force CODE, DATA, and LABEL relocs to be
+ emitted.
+ (md_apply_fix): Ignore CODE, DATA, and LABEL relocs.
+ (sh_coff_reloc_mangle): Force CODE, DATA, and LABEL relocs to use
+ the absolute symbol.
+
+ * subsegs.h (segment_info_type): Add tc_segment_info_data field if
+ TC_SEGMENT_INFO_TYPE is defined.
+
+Wed May 15 12:23:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (md_assemble): Make sure the opcode suffix
+ matches the register size.
+
+Wed May 15 08:33:37 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/obj-coff.c (count_entries_in_chain): Ignore Fixups with
+ fx_done set.
+ (do_relocs_for): Likewise.
+ (fixup_segment): Don't just quit if linkrelax is set. Try to
+ apply non pc-relative sym1-sym2 fixups, even if linkrelax is
+ nonzero.
+
+Fri May 10 14:16:59 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_validate_fix): Allow GOT and section
+ relative relocations with -mrelocatable. Also allow unfixed
+ relocs in .ex_shared.
+
+Tue May 7 11:24:10 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (yank_symbols): Check that FNAME_OFFSET is
+ non-zero before assuming this is a long file name.
+ (w_strings): Likewise.
+ (c_dot_file_symbol): Set FNAME_OFFSET to 1 for a long file name.
+
+ * config/obj-coff.c (w_strings): Move declaration of i inside
+ #ifdef block which uses it.
+
+Tue May 7 00:49:58 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-h8300.c (do_a_fix_imm): Rename last argument to
+ "relaxmode". Output relocs which identify various relaxing
+ possibilities for mov.[bwl] instructions.
+ (build_bytes): Pass in a relaxing mode to do_a_fix_imm.
+
+Mon May 6 15:26:28 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-arm.h (TC_HANDLES_FX_DONE): Define.
+ (MD_APPLY_FIX3): Define.
+ * config/tc-arm.c (my_get_expression): Only watch for bad segments
+ if OBJ_AOUT.
+ (md_apply_fix3): Renamed from md_apply_fix.
+ If pcrel reloc and symbol is in different section, undo effects
+ of md_pcrel_from.
+
+Sat May 4 12:49:35 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (hppa_fix_adjustable): Don't adjust
+ any reloc with an LR% or RR% field selector for SOM.
+
+Sat May 4 11:26:19 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Add subsegs.h to appropriate TARG_CPU_DEP_*
+ variables.
+
+Fri May 3 17:58:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (coff_frob_symbol): Don't merge a symbol with
+ SF_GET_STATICS set.
+ (yank_symbols): Likewise.
+
+Wed May 1 13:38:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * subsegs.h (segment_info_type): If MANY_SEGMENTS and not
+ BFD_ASSEMBLER, add name field.
+ * config/obj-coff.c: Include "libiberty.h".
+ (coff_header_append): Handle long section names.
+ (crawl_symbols): Just use the name field for the symbol name,
+ without worrying about null byte termination.
+ (w_strings): Handle long section names.
+ (write_object_file): Likewise. Also, use the name field, rather
+ than scnhdr.s_name.
+ (obj_coff_add_segment): Permit long section names.
+ (obj_coff_init_stab_section): Use the name field, rather than
+ scnhdr.s_name.
+ (adjust_stab_section): Likewise.
+ * config/te-pe.h (COFF_LONG_SECTION_NAMES): Define.
+
+ * config/tc-i960.c (brtab_emit): Don't set fx_im_disp field.
+ (mem_fmt): Likewise.
+ (md_apply_fix): Don't check fx_im_disp field.
+
+Thu Apr 25 11:39:51 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add * after sparc*-*-vxworks.
+ * configure: Rebuild.
+
+ * app.c (do_scrub_begin): If tc_comment_chars is not defined,
+ define it to comment_chars. Use tc_comment_chars rather than
+ comment_chars.
+ (do_scrub_chars): Use tc_comment_chars rather than comment_chars.
+ * config/tc-m68k.h (tc_comment_chars): Define.
+ (m68k_comment_chars): Declare.
+ * config/tc-m68k.c (m68k_comment_chars): Rename from
+ comment_chars. Change into a pointer rather than an array.
+ (md_longopts): Add "bitwise-or".
+ (md_parse_option): Handle OPTION_BITWISE_OR.
+ (md_show_usage): Mention --bitwise-or.
+ * doc/c-m68k.texi: Document --bitwise-or.
+
+Wed Apr 24 11:28:38 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Prevent attempts to use long offsets
+ in 68000 mode.
+
+ * config/obj-coff.c (obj_coff_section): BFD_ASSEMBLER version:
+ call demand_empty_rest_of_line. Non BFD_ASSEMBLER version:
+ correct handling of input line pointer, and call
+ demand_empty_rest_of_line.
+
+Mon Apr 22 18:02:37 1996 Doug Evans <dje@blues.cygnus.com>
+
+ * config/tc-sparc.c (in_bitfield_range): New static function.
+ (sparc_ip): New cases X,Y. Use SPARC_OPCODE_ARCH_V9_P.
+ (md_apply_fix, cases BFD_RELOC_32_PCREL_S2,
+ BFD_RELOC_SPARC_{WDISP16,WDISP19}): Fix undefined code.
+ (md_apply_fix): New cases BFD_RELOC_SPARC_[56].
+ (tc_gen_reloc): New cases BFD_RELOC_SPARC_[56].
+
+Thu Apr 18 18:58:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c: BFD_ASSEMBLER:
+ (coff_last_bf): New static variable.
+ (coff_frob_symbol): Set endndx of a .bf symbol.
+ Non BFD_ASSEMBLER:
+ (obj_coff_endef): Call SF_SET_PROCESS on a .bf symbol.
+ (last_bfP): New static variable.
+ (yank_symbols): Set endndx of a .bf symbol.
+
+Thu Apr 18 11:53:58 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (md_parse_option): Add support for Solaris's -le
+ and -s options. Add -be for good measure.
+
+Wed Apr 17 12:31:01 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (s_space): Support non-constant fill value. Handle fill
+ value correctly for a size other than 1.
+
+Tue Apr 16 15:17:40 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-arm.c (my_get_float_expression): Update call to
+ gen_to_words, X_PRECISION changed from 6 to 5.
+
+Tue Apr 16 10:25:42 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (register_name,reg_name_search): Move register
+ name lookup from PE specific code to all targets. Add support for
+ -mregnames/-mno-regnames to control whether register names are
+ expanded or not.
+ (md_assemble): Call register_name for all platforms.
+ (md_parse_option): Add support for -mregnames/-mno-regnames.
+
+ * configure.in (powerpcle*-*-solaris): Add support.
+ (powerpc*-*-linux): Ditto.
+ * configure: Regenerate.
+
+ * config/ppc-sol.mt: New config file for PowerPC Solaris.
+
+Mon Apr 15 12:26:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_frob_file): Permit multiple %hi relocs to
+ be associated with a single %lo reloc.
+
+ * config/tc-mips.c (load_address): Cast X_add_number to valueT
+ before comparing against MAX_GPREL_OFFSET, so that negative
+ numbers are handled correctly.
+ (macro): Likewise.
+
+Thu Apr 11 12:39:02 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c (last_insn): New static variable.
+ (md_assemble): Warn about putting floating point branches in a
+ delay slot. If architecture is less than v9, insert NOP
+ instructions between floating point instructions and floating
+ point branches. (The SunOS assembler does both these operations.)
+ Save the last instruction opcode.
+ (sparc_ip): Add pinsn parameter. Change caller.
+
+ * config/tc-m68k.c (md_estimate_size_before_relax): Correct check
+ for byte jump to next instruction to skip empty frags.
+
+Wed Apr 10 16:48:12 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-alpha.c (alpha_ip): If we are going to call emit_add64
+ for addq with a 16 bit signed value, just emit a lda instruction
+ instead.
+
+Wed Apr 10 14:34:49 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-h8300.c (do_a_fix_imm): Don't cut off high bits
+ of a 32bit operand.
+
+Mon Apr 8 14:42:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Permit --enable-shared to specify a list of
+ directories.
+ * configure: Rebuild.
+
+Fri Apr 5 17:01:35 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-h8300.c (get_specific): Remove some #if 0 code.
+ (build_bytes): Remove all ABSMOV related code; it's unnecessary.
+
+Fri Apr 5 15:13:10 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/atof-ieee.c: Fix handling of denormalized extended
+ precision numbers and overflow/underflow detection.
+ (MAX_PRECISION, X_PRECISION, P_PRECISION): Changed from 6 to 5, to
+ not include the 16 bit gap in the m68k extended precision format.
+
+Fri Apr 5 14:29:23 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add i386-*-freebsdelf* target; from John Polstra
+ <jdp@polstra.com>.
+ * configure: Rebuild.
+
+Fri Apr 5 18:39:28 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-mips.c: Allow non-zero offsets from .sdata symbols to
+ be accessed using the $gp register.
+ * config/tc-mips.h (MAX_GPREL_OFFSET): Added.
+
+Wed Apr 3 10:56:14 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-sparc.c (sparc_md_end): Set bfd machine number to
+ bfd_mach_sparc_sparclet if current_architecture is sparclet.
+
+Mon Apr 1 16:55:44 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (get_line_sb): Bump line counters based on
+ input_line_pointer[-1], not *input_line_pointer. Don't bother to
+ call LISTING_NEWLINE.
+ (s_macro): Don't call demand_empty_rest_of_line.
+ * app.c (do_scrub_chars): When handling C style comments, unget
+ ch2 rather than ch.
+
+Fri Mar 29 16:15:06 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.h (enum linkonce_type): Define.
+ (s_linkonce): Declare.
+ * read.c (potable): Add "linkonce".
+ (s_linkonce): New function.
+ * subsegs.h (segment_info_type): Add linkonce field to
+ MANY_SEGMENTS && ! BFD_ASSEMBLER section.
+ * config/obj-coff.h (obj_handle_link_once): Define if TE_PE.
+ (obj_coff_pe_handle_link_once): Declare if TE_PE.
+ * config/obj-coff.c: If TE_PE and not BFD_ASSEMBLER, #include
+ "coff/pe.h".
+ (obj_coff_pe_handle_link_once): New function, defined if TE_PE.
+ (c_section_symbol): If TE_PE, set the x_comdat field in the aux
+ entry based on the linkonce field in segment_info.
+ * doc/as.texinfo: Document .linkonce.
+
+Fri Mar 29 11:31:27 1996 J.T. Conklin (jtc@lisa.cygnus.com)
+
+ * doc/as.1: Changed to be recognized by catman -w on Solaris.
+
+Thu Mar 28 15:27:47 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.c (s_stab_generic): Call the listing functions before
+ doing the rest of the processing, which may involve freeing the
+ string. Pass string, not string + stroff, to OBJ_PROCESS_STAB in
+ SEPARATE_STAB_SECTIONS case.
+
+ * config/tc-hppa.c: Remove nested comment.
+ (tc_gen_reloc): Move label done inside the ifdef in which it is
+ used.
+ (md_apply_fix): Pass pointers to correct types to libhppa.h
+ functions. Always return a value.
+
+ * config/tc-mips.h (tc_frob_file): Define.
+ (mips_frob_file): Declare.
+ * config/tc-mips.c (struct mips_hi_fixup): Define.
+ (mips_hi_fixup_list): New static variable.
+ (imm_unmatched_hi): New static variable.
+ (md_assemble): Clear imm_reloc, imm_unmatched_hi, and
+ offset_reloc. Pass imm_unmatched_hi to append_insn.
+ (append_insn): Add unmatched_hi parameter. If it is set, add the
+ new fixup to mips_hi_fixup_list. Change all callers.
+ (mips_ip): Set imm_unmatched_hi when appropriate.
+ (mips_frob_file): New function.
+
+Thu Mar 28 11:47:59 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.in (sparc-*-solaris2*): Renamed from sparc*-*-solaris2*.
+ * configure: Regenerated.
+
+Tue Mar 26 18:19:12 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.c (main): Call bfd_set_error_program_name.
+
+Fri Mar 22 11:13:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.h (strdup): Don't declare.
+ * stabs.c: Include libiberty.h
+ (get_stab_string_offset): Use xstrdup rather than strdup.
+ (s_stab_generic): Likewise.
+ * as.c (parse_args): Likewise.
+ * read.c (s_mri_sect): Likewise.
+
+ * gasp.c (change_base): Recognize \(...) construct documented to
+ pass through enclosed characters literally through to the output.
+ (process_assigns): Likewise. Also, be more careful to avoid
+ looking past the end of the buffer.
+
+Thu Mar 21 13:18:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (md_parse_option): If OBJ_ELF, ignore -k for
+ FreeBSD compatibility. From John Polstra <jdp@polstra.com>.
+
+Wed Mar 20 18:13:32 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * doc/as.texinfo, doc/c-i960.texi: Fix typos.
+
+Wed Mar 20 17:05:16 1996 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * config/alpha-opcode.h: Added cvtst instruction.
+
+Mon Mar 18 13:12:46 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (ecoff_stab): Don't try to make a symbol out of the stab
+ string. Extract the addend from the result of expression.
+
+Fri Mar 15 17:10:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * app.c (do_scrub_chars): If whitespace is seen in state 11, and
+ LABELS_WITHOUT_COLONS is not defined, and we are not in m68k MRI
+ mode, change the state to 3 rather than 1.
+
+Thu Mar 14 18:18:25 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.h (C_REGISTER_SECTION): Change from 20 to 50, to
+ correspond to 11 March change.
+
+Thu Mar 14 15:27:10 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-h8300.c (build_bytes, MEMIND case): Generate
+ an R_MEM_INDIRECT reloc rather than R_RELBYTE.
+
+Tue Mar 12 12:21:10 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild with autoconf 2.8.
+
+Mon Mar 11 18:57:12 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/atof-ieee.c (gen_to_words): Improve handling of
+ X_PRECISION numbers. Based on patches from Andreas Schwab
+ <schwab@issan.informatik.uni-dortmund.de>.
+
+Mon Mar 11 09:59:53 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * as.h (SEG_NORMAL, SEG_LIST): Bump segment limit from 10 to 40.
+ (SEG_LAST): New.
+ * subsegs.c (MANY_SEGMENTS): Increase segment limit.
+ * config/obj-coff.c (seg_N_TYPE, seg_info_off_by_4): Likewise.
+ (do_relocs_for, w_symbols, obj_coff_add_segment, do_linenos_for,
+ crawl_symbols, coff_header_append): Loop to SEG_LAST rather than
+ SEG_E9.
+
+Thu Mar 7 15:17:39 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config/tc-sparc.c (sparc_ip): Handle operand char 'O' (neg reg).
+
+Thu Mar 7 09:19:15 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (SUBSEG_MILLI): Define.
+ (pa_def_subspaces): Add $MILLICODE$.
+ (pa_spaces_begin): Set section flags for $MILLICODE$.
+
+Wed Mar 6 14:11:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-elf.c (obj_elf_section): Only SEC_LOAD if the type is
+ not SHT_NOBITS. Don't tamper with flags based on type if a
+ special section was found (revert Feb 29 change).
+
+ * config/tc-sh.c (sh_do_align): Only align using the nop pattern
+ if aligning to a longword boundary or greater.
+
+Tue Mar 5 15:10:43 1996 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * config/tc-sh.c (sh_do_align): Pass 1 not 2 to frag_align.
+
+Mon Mar 4 20:50:57 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * configure.in (i386-*-cygwin32): Don't use bfd_gas.
+ * configure: Regenerated.
+
+Mon Mar 4 10:13:06 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c: Add default definitions for R_N0SEL and
+ R_N1SEL since they're not defined for old versions of hpux.
+
+ * config/tc-hppa.c (tc_gen_reloc): Fix typo in R_COMP2 code.
+ Set "sym_ptr_ptr" and "addend" fields to dummy values for
+ R_N0SEL and R_N1SEL.
+
+Fri Mar 1 10:20:52 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * flonum-konst.c: Add two more constants for 1e+-2048 and
+ 1e+-4096, and correct the other constants.
+
+ * symbols.c (resolve_symbol_value): Handle O_logical_not.
+
+Thu Feb 29 13:58:35 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/obj-elf.c (obj_elf_section): Allow predefined section
+ types to set the nobits type. Avoid a shadowed declaration.
+
+Wed Feb 28 15:38:56 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (hppa_fix_adjustable): For SOM, don't
+ reduce relocs using e_nlrsel field selectors.
+
+ * write.c (fix_new_exp): Don't use #elif. Some compilers
+ don't handle it.
+
+ * config/tc-hppa.c (selector_table): Add "n", "nl", and "nlr" to
+ the selector table.
+ (pa_chk_field_selector): Handle new field selectors for SOM.
+
+Tue Feb 27 14:42:27 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * configure.in (m68k-*-linux*aout*, m68k-*-linux*): New targets.
+ * configure: Rebuild.
+ * config/te-linux.h (LOCAL_LABELS_FB): Define.
+ * config/tc-m68k.h (TARGET_FORMAT) [TE_LINUX]: Define to
+ "a.out-m68k-linux".
+ * config/tc-m68k.c (comment_chars): Don't include '#' if TE_LINUX
+ is defined.
+
+Mon Feb 26 18:58:58 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Update to handle shared library support.
+
+Mon Feb 26 10:34:10 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config/tc-sparc.c (sparc_ip): Print all architectures that support
+ the insn on mismatch.
+
+Fri Feb 23 21:44:39 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * configure.in: Add support for a29-coff.
+ * configure: Rebuild.
+
+Thu Feb 22 16:39:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (sh_coff_frob_file): Don't consider the address
+ of the section when looking for the R_SH_USES fixup, because the
+ frag addresses have not yet been adjusted.
+
+ * gdbinit.in: Set a breakpoint on as_warn_where.
+
+ * config/tc-mips.c (macro): Add missing arguments to macro_build
+ omitted in last change. From Jim Wilson <wilson@cygnus.com>.
+
+Wed Feb 21 17:00:32 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-h8300.c (tc_reloc_mangle): Change reloc based on size
+ if it is TC_CONS_RELOC. Set a size of 4 to R_RELLONG.
+
+Wed Feb 21 09:25:39 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config/tc-sparc.c (sparc_ip): Recognize %asr0 for v8.
+
+Tue Feb 20 21:48:03 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config/tc-sparc.c (parse_keyword_arg): Accept leading '%'.
+ (sparc_ip): Accept %asr[1..31] for v8 and %asr[%16..31] for v9.
+ Recognize [uU] format args as sparclet cpregs.
+
+Tue Feb 20 22:25:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (sh_handle_align): Don't emit R_SH_ALIGN relocs
+ in bss_section.
+
+Mon Feb 19 14:16:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.h (TC_RELOC_RTSYM_LOC_FIXUP): Check S_IS_WEAK as
+ well as S_IS_EXTERNAL.
+ (tc_fix_adjustable): Likewise.
+ * config/tc-sparc.c (md_apply_fix): In OBJ_ELF case, check for
+ S_IS_WEAK as well as S_IS_EXTERNAL when deciding whether to return
+ early.
+ (tc_gen_reloc): Check S_IS_WEAK as wel as S_IS_EXTERNAL when
+ deciding whether to convert BFD_RELOC_32_PCREL_S2 if PIC.
+
+Mon Feb 19 02:15:57 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config/tc-sparc.c (max_architecture): Change to sparclite for
+ 32 bit arch.
+ (default_compatible): Delete.
+ (sparc_ffs): New function.
+ (md_begin): Only call SPARC_OPCODE_CONFLICT_P once.
+ (sparc_ip): Rewrite architecture match and bump logic.
+
+Sun Feb 18 15:03:50 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Check for 'do not mix' from native linker before
+ trying to use -rpath.
+ * configure: Rebuild.
+
+Fri Feb 16 16:53:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.h (SF_ADJ_LNNOPTR): Define (non BFD_ASSEMBLER).
+ (SF_GET_ADJ_LNNOPTR): Define (non BFD_ASSEMBLER).
+ (SF_SET_ADJ_LNNOPTR): Define (non BFD_ASSEMBLER).
+ * config/obj-coff.c (obj_coff_endef): Set ADJ_LNNOPTR when LNNOPTR
+ is set.
+ (w_symbols): If ADJ_LNNOPTR is set, add the section lnnoptr field
+ to the symbol lnnoptr field, to get the correct file offset.
+
+Thu Feb 15 14:48:38 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/obj-elf.c (elf_frob_symbol): On the PowerPC, force all
+ symbols that are not function, file, or section symbols to be
+ object types.
+
+Thu Feb 15 11:20:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Set and substitute RPATH_ENVVAR.
+ * configure: Rebuild.
+ * Makefile.in (RPATH_ENVVAR): New variable.
+ (check): Use $(RPATH_ENVVAR) rather than LD_LIBRARY_PATH.
+
+ * configure.in: Accept i686. From H.J. Lu <hjl@zoom.com>: i386
+ doesn't need opcodes. If configuring shared, opcodes needs bfd.
+ * configure: Rebuild.
+
+Wed Feb 14 16:33:12 1996 Martin Anantharaman <martin@mail.imech.uni-duisburg.de>
+
+ * read.c (s_mri_sect): Don't return '\0' in type. Set all
+ appropriate flags in BFD section.
+
+ * configure.in (m68k-*-psos*): New target.
+ * configure: Rebuild.
+ * config/te-psos.h: New file.
+ * config/tc-m68k.c (comment_chars): Don't include '#' if TE_PSOS
+ is defined.
+
+Wed Feb 14 13:43:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ From Alan Modra <alan@spri.levels.unisa.edu.au>:
+ * configure.in: Remove duplicate setting of cpu_type. Check
+ whether opcodes library is required for on all targets, not just
+ primary one.
+ * configure: Rebuild.
+
+ * config/tc-mips.c (mips_big_got): New static variable.
+ (s_extern): Don't declare.
+ (reg_needs_delay): New static function.
+ (macro_build): Permit GOT/CALL_HI/LO relocs.
+ (macro_build_lui): If place is not NULL, use the number in the
+ expression.
+ (load_address): Handle mips_big_got case.
+ (macro): Handle mips_big_got for M_LA_AB, M_JAL_A, and load and
+ store macros.
+ (OPTION_XGOT): Define.
+ (md_longopts): Add "xgot" if OBJ_ELF.
+ (md_parse_option): Handle -xgot.
+ (md_show_usage): Mention -xgot.
+ (md_apply_fix): Permit GOT/CALL_HI/LO relocs.
+ (tc_gen_reloc): Handle GOT/CALL_HI/LO relocs.
+
+Wed Feb 14 11:22:27 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (m68k_ip) [operand kind '#']: When fixing
+ the byte relocation, point it to the low byte of the word.
+
+Tue Feb 13 15:31:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set HDLFLAGS for *-*-hpux with --enable-shared.
+ * configure: Rebuild.
+
+Mon Feb 12 15:53:46 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * configure.in: Recognize any sparc* cpu.
+ * configure: Regenerated.
+
+Mon Feb 12 15:41:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (potable): Add "mri" and ".mri".
+ (s_mri): New function.
+ * read.h (s_mri): Declare.
+ * app.c (scrub_m68k_mri): New static variable.
+ (mri_pseudo): New static variable.
+ (do_scrub_begin): Add m68k_mri parameter. Use it rather than
+ flag_m68k_mri. Initialize scrub_m68k_mri.
+ (mri_state, mri_last_ch): New static variables.
+ (struct app_save): Add scrub_m68k_mri, mri_state, and mri_last_ch
+ fields.
+ (app_push): Save new fields.
+ (app_pop): Restore new fields.
+ (do_scrub_chars): Check scrub_m68k_mri rather than flag_mri_mri.
+ If TC_M68K, use a trivial state machine to look for occurrences of
+ the .mri pseudo-op, and change the mode appropriately.
+ * as.h (do_scrub_begin): Update prototype.
+ * input-scrub.c (input_scrub_begin): Pass flag_m68k_mri to
+ do_scrub_begin.
+ * config/tc-m68k.c (reg_prefix_optional_seen): New static
+ variable.
+ (m68k_mri_mode_change): New function.
+ (md_parse_option): Set reg_prefix_optional_seen.
+ * config/tc-m68k.h (m68k_mri_mode_change): Declare.
+ (MRI_MODE_CHANGE): Define.
+ * doc/as.texinfo: Document .mri pseudo-op.
+
+ * app.c (do_scrub_chars): In MRI mode, don't treat '#' as a
+ comment character.
+
+Mon Feb 12 15:16:29 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ Support for OBJ_ELF on m68k, mostly inside #ifdef OBJ_ELF:
+ * config/m68k-parse.h (enum pic_relocation): Define.
+ (struct m68k_exp): Add pic_reloc field.
+ * config/tc-m68k.h (TC_RELOC_RTSYM_LOC_FIXUP): Define.
+ (tc_fix_adjustable): Define to call tc_m68k_fix_adjustable.
+ (NO_RELOC): Define to BFD_RELOC_NONE if BFD_ASSEMBLER, to zero
+ otherwise.
+ * config/tc-m68k.c: Delete definition of NO_RELOC.
+ (struct m68k_it): Add pic_reloc field.
+ (add_fix): Copy over pic_reloc field.
+ (md_pseudo_table): Interpret .align parameter as byte count.
+ (mote_pseudo_table): Likewise.
+ (tc_m68k_fix_adjustable): New function.
+ (get_reloc_code): New function.
+ (md_assemble): Use it as last argument to fix_new_exp.
+ (md_apply_fix_2): For a relocation against a symbol don't put the
+ addend into the data.
+ (tc_gen_reloc): Different addend computation for OBJ_ELF.
+ (m68k_ip): Don't relax an operand that requires pic relocation.
+ (md_begin): Align .text, .data and .bss on 4 byte boundary by
+ default.
+ * write.c (fixup_segment): Don't add symbol value to addend if
+ TC_M68K and OBJ_ELF.
+ * config/m68k-parse.y (yylex): Handle @PLTPC, etc.
+ (motorola_operand): Add rule for `(zapc, EXPR)'.
+
+Mon Feb 12 10:07:33 1996 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * ecoff.c (ecoff_directive_weakext): Fixed so that whitespace
+ *really* is permissible before the comma.
+
+Mon Feb 12 00:12:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (sh_do_align): Align to a 2 byte boundary before
+ inserting nop instructions.
+
+Fri Feb 9 10:54:19 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/te-aux.h: Change include of aux.h to aux-coff.h.
+
+Thu Feb 8 20:02:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i960.c (tc_coff_symbol_emit_hook): Correct storage
+ class setting for a CALLNAME symbol in COFF.
+
+ * read.c (potable): Pass negative numbers for new .balign[wl] and
+ .p2align[wl] pseudo-ops.
+ (s_align_bytes): Treat a negative argument as specifying the fill
+ length.
+ (s_align_ptwo): Likewise.
+
+Wed Feb 7 14:12:03 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (potable): Add balignw, balignl, p2alignw, and p2alignl.
+ (do_align): Take new len parameter. Change all callers. Pass it
+ to md_do_align.
+ (s_align_bytes): Arg now indicates the length of the fill pattern.
+ (s_align_ptwo): Likewise.
+ * config/obj-coff.c (write_object_file): Pass length to
+ md_do_align.
+ * config/tc-i386.h (md_do_align): Take new len parameter.
+ * config/tc-m88k.h (md_do_align): Likewise.
+ * config/tc-m88k.c (m88k_do_align): Likewise.
+ * config/tc-sh.h (md_do_align): Likewise.
+ * config/tc-sh.c (sh_do_align): Likewise.
+ * doc/as.texinfo: Document new pseudo-ops.
+
+ * config/obj-coff.c (fixup_mdeps): Divide offset by fr_var, as is
+ done in cvt_frag_to_fill.
+
+ * config/tc-sh.h (sh_do_align): Declare.
+ (md_do_align): Define.
+ * config/tc-sh.c (sh_do_align): New function.
+
+ * ecoff.c (ecoff_build_lineno): Don't try to store the address
+ difference if the next address is before the current one.
+
+ * config/tc-m68k.c (struct m68k_cpu): Add alias field.
+ (archs): Initialize new field.
+ (m68k_ip): Don't list alias names when listing CPUs which support
+ an instruction.
+
+ * as.c (main): Call parse_args before read_begin.
+ * app.c (do_scrub_chars): If flag_m68k_mri, don't put a dot in
+ front of generated pseudo-ops.
+ * read.c (potable): Ignore "name".
+ (s_app_file): Permit a single quote after the string, since one
+ may appear in m68k MRI mode.
+
+ * configure.in: Check for --enable-shared. If linking against
+ shared BFD and opcodes, fix library name on SunOS, and try to set
+ -rpath reasonably.
+ * configure: Rebuild.
+
+Tue Feb 6 15:16:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.h (flag_m68k_mri): Declare.
+ * as.c (parse_args): If TC_M68K, set flag_m68k_mri for -M.
+ * Many files: For MRI syntax that is specific to the m68k MRI
+ assembler, check flag_m68k_mri rather than flag_mri or
+ MRI_MODE_NEEDS_PSEUDO_DOT.
+
+Mon Feb 5 16:29:11 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i960.c (ARCH_HX): Define.
+ (arch_tab): Add HX.
+ (targ_has_sfr): Handle ARCH_HX.
+ (targ_has_iclass): Handle ARCH_HX.
+ (tc_coff_fix2rtype): Add return 0 to avoid warning.
+ (tc_headers_hook): If the architecture was specified explicitly,
+ use it when setting the flags. Set the extern variable coff_flags
+ rather than headers->filehdr.f_flags, since the latter is set
+ unconditionally in obj-coff.c.
+ (i960_handle_align): Remove unused variable fixp.
+
+ Support for building bfd and opcodes as shared libraries, based on
+ patches from Alan Modra <alan@spri.levels.unisa.edu.au>:
+ * configure.in: Set OPCODES and BFD to search directories.
+ Substitute OPCODES_DEP and BFDDEP. On SunOS, set HLDFLAGS.
+ * configure: Rebuild.
+ * Makefile.in (LDFLAGS, HLDFLAGS): New variables.
+ (LIBDEPS): New variable.
+ (as.new0: Depend upon $(LIBDEPS) rather than $(LIBS). Use
+ $(HLDFLAGS) in link.
+ (check): Set LD_LIBRARY_PATH in the environment.
+
+Fri Feb 2 17:41:53 1996 Michael Meissner <meissner@wogglebug.tiac.net>
+
+ * config/tc-ppc.h (ELF_TC_SPECIAL_SECTIONS): Make .sdata2, .sbss2,
+ .PPC.EMB.sdata0, and .PPC.EMB.sbss0 sections all default to
+ read-only, not read/write.
+
+Fri Feb 2 14:09:25 1996 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * Makefile.in (INSTALL_XFORM): Remove -e.
+
+Fri Feb 2 12:32:15 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (write_relocs): Use S_IS_DEFINED and S_IS_COMMON rather
+ than comparing S_GET_SEGMENT to undefined_section.
+ (write_object_file): Skip symbols which were equated to an
+ undefined or common symbol.
+ * symbols.c (resolve_symbol_value): Use S_IS_DEFINED and
+ S_IS_COMMON rather than comparing S_GET_SEGMENT to
+ undefined_section.
+ (S_GET_VALUE): Likewise. Avoid recursion problems if S_IS_DEFINED
+ or S_IS_COMMON call S_GET_VALUE.
+ * config/obj-aout.h (S_IS_COMMON): Define if not BFD_ASSEMBLER.
+ * config/obj-aout.c (obj_emit_relocations): If a reloc is equated
+ to an undefined or common symbol, convert the reloc to be against
+ the target symbol.
+ (obj_crawl_symbol_chain): Skip symbols which were equated to an
+ undefined or common symbol.
+ * config/obj-bout.h (S_IS_COMMON): Define if not BFD_ASSEMBLER.
+ * config/obj-bout.c (obj_emit_relocations): If a reloc is equated
+ to an undefined or common symbol, convert the reloc to be against
+ the target symbol.
+ (obj_crawl_symbol_chain): Skip symbols which were equated to an
+ undefined or common symbol.
+ * config/obj-coff.c (do_relocs_for): Use S_IS_DEFINED and
+ S_IS_COMMON rather than comparing S_GET_SEGMENT to
+ undefined_section.
+ (yank_symbols): Skip symbols which were equated to an undefined or
+ common symbol.
+
+Thu Feb 1 15:34:32 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-aout.h (S_IS_LOCAL): Check for \002 as well as \001.
+ * config/obj-bout.h (S_IS_LOCAL): Likewise.
+
+ * configure.in: Make sure we only add m68k-parse.o to
+ ${extra_objects} once, no matter how many m68k targets have been
+ enabled.
+ * configure: Rebuild.
+
+Wed Jan 31 18:31:46 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * configure.in (i386-*-cygwin32, ppc-*-cygwin32): New.
+ * configure: Rebuild.
+
+Wed Jan 31 14:03:17 1996 Richard Henderson <rth@tamu.edu>
+
+ * config/tc-m68k.c (md_pseudo_table): Add "extend" and "ldouble".
+ * doc/c-m68k.texi: Document .extend and .ldouble.
+
+ * configure.in (m68*-apple-aux*): New target.
+ * config/te-aux.h: New file.
+ * config/obj-coff.c (compare_external_relocs): New static function
+ if TE_AUX.
+ (do_relocs_for): Sort relocs if TE_AUX.
+ (fixup_segment): If TE_AUX, store common symbol value in segment.
+ * config/tc-m68k.h (TARGET_FORMAT): Define if TE_AUX.
+
+Wed Jan 31 12:24:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.h (S_IS_LOCAL): Check for \002 as well as \001.
+
+ * config/tc-mips.c (s_mips_globl): Set BSF_OBJECT if it is not
+ BSF_FUNCTION.
+ (s_cpload): Set BSF_OBJECT for _gp_disp symbol.
+ * read.c (s_lcomm): If S_SET_SIZE is defined, set the size of the
+ symbol.
+ * ecoff.c (add_procedure): Set the BSF_FUNCTION flag.
+ (ecoff_build_symbols): If S_SET_SIZE is defined, set the size of
+ an undefined symbol and the size of a function symbol.
+ * config/obj-elf.c (elf_frob_symbol): If TC_MIPS, set BSF_OBJECT
+ for all common symbols.
+
+Tue Jan 30 12:35:24 1996 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/tc-i960.c (parse_memop): In MRI mode, don't use implicit
+ scaling of index.
+
+ * expr.c (operand): Accept 0x hex constants in MRI mode if not on
+ m68k.
+
+Mon Jan 29 12:21:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-elf.c (obj_elf_type): Set BSF_OBJECT flag for a type
+ of object. From Ronald F. Guilmette <rfg@monkeys.com>.
+
+ * ecoff.c (localsym_t): Add addend field.
+ (add_ecoff_symbol): Add addend argument. Change all callers.
+ (coff_sym_value): Make static.
+ (coff_sym_addend): New static variable.
+ (ecoff_directive_def): Initialize coff_sym_addend.
+ (ecoff_directive_val): Accept symbol + constant.
+ (ecoff_directive_endef): Pass coff_sym_addend to add_ecoff_symbol.
+ (ecoff_build_symbols): Include the addend in the symbol value.
+
+Fri Jan 26 19:28:52 1996 Kim Knuttila <krk@cygnus.com>
+
+ * config/tc-ppc.c (md_assemble): Ignore overflow on
+ BFD_RELOC_16_GOTOFF and BFD_RELOC_PPC_TOC16.
+
+Fri Jan 26 16:14:17 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (md_apply_fix3): SDA21 relocations are now 4
+ bytes in size, so offset appropriately in big endian mode when
+ writing the bottom 2 bytes.
+
+Thu Jan 25 20:26:23 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config/tc-sparc.c (default_compatible): New static local.
+ (md_begin): Initialize it. Rewrite warn_on_bump handling.
+ (sparc_ip): If no architecture or -bump specified, don't mark as
+ mismatched those in default_compatible.
+
+Thu Jan 25 12:21:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ SCO ELF support from Robert Lipe <robertl@arnet.com>:
+ * configure.in (i386-*-sco*elf*): Use fmt elf, targ sco5.
+ * configure: Rebuild.
+ * config/sco5.mt: New file; set TDEFINES to -DSCO_ELF.
+ * config/tc-i386.c (sco_id): New function, if SCO_ELF.
+ * config/tc-i386.h (tc_init_after_args): Define if SCO_ELF.
+ (sco_id): Declare if SCO_ELF.
+
+Thu Jan 25 03:10:53 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config/tc-sparc.c (initial_architecture,can_bump_v9_p): Deleted.
+ ({max,warn_after}_architecture): New static locals.
+ (md_begin): Replace NUMOPCODES with sparc_num_opcodes.
+ If both architecture and -bump requested, set max_architecture to max.
+ (sparc_md_end): Simplify.
+ (sparc_ip): Replace references to can_bump_v9_p with max_architecture.
+ Rewrite code to bump architecture and check for conflicts.
+ (md_longopts): Recognize -xarch={v8plus,v8plusa} for compatibility
+ with Solaris assembler.
+ (md_parse_option): Likewise. Call sparc_opcode_lookup_arch.
+ (md_show_usage): Update.
+
+Wed Jan 24 22:11:03 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * Makefile.in (RUNTEST): Fix reference to $${srcdir}.
+
+Mon Jan 22 09:21:36 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config/tc-sparc.h (TARGET_FORMAT): Use #ifdef SPARC_ARCH64 instead of
+ #ifdef sparcv9 when choosing value.
+ (ENV64): Delete.
+ (md_end): Define.
+ (sparc_md_end): Declare.
+ * config/tc-sparc.c (SPARC_V9): Renamed from sparcv9.
+ (initial_architecture): New static local.
+ (can_bump_v9_p): Likewise.
+ (NO_V9): Delete all occurrences.
+ (sparc_md_end): New function.
+ (sparc_ip): New local v9_arg_p. Rework fp reg number test.
+ Don't bump architecture to v9 unless can_bump_v9_p set.
+ (md_parse_option): -A<arch> passed, set can_bump_v9_p accordingly.
+ * configure.in (sparc64 target cpu): Don't set obj_format here.
+ (SPARC_V9): Renamed from sparcv9.
+ (sparc64-*-elf*): Define SPARC_ARCH64.
+ * configure: Regenerated.
+ * acconfig.h (SPARC_V9): Renamed from sparcv9.
+ (SPARC_ARCH64): Add.
+ * conf.in: Regenerated.
+ * config/vmsconf.h: Update.
+
+Mon Jan 22 17:24:47 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-mips.c (load_register): Optimise "dli" loads.
+ (md_show_usage): add "-mcpu=vr4100" to help text.
+
+Mon Jan 22 11:53:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (resolve_symbol_value): If a symbol is equated to an
+ undefined symbol, preserve the X_op of O_symbol.
+ (S_GET_VALUE): Fix check to permit this case.
+ * write.c (write_relocs): If a reloc is against an undefined
+ symbol equated to another symbol, change the reloc to be against
+ the latter symbol.
+ * config/obj-coff.c (do_relocs_for): Likewise.
+
+ * config/tc-ppc.c (ppc_csect): An unnamed csect is storage class
+ XMC_PR.
+
+Mon Jan 22 10:59:48 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/obj-elf.c (elf/ppc.h): Include elf/ppc.h if target
+ computer is PowerPC.
+
+ * config/tc-ppc.c (md_apply_fix3): Add more embedded relocations.
+
+ * config/tc-ppc.h (ELF_TC_SPECIAL_SECTIONS): Add sections
+ mentioned in the eabi.
+
+Thu Jan 18 17:58:19 1996 Kim Knuttila <krk@cygnus.com>
+
+ * config/tc-ppc.c (ppc_reldata): Changed alignement on reldata_section
+ * config/tc-ppc.c (ppc_pdata): Changed the alignment on pdata_section
+
+Mon Jan 15 17:43:42 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (mapping): Add more relocation suffixes.
+
+Sun Jan 14 21:29:36 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_validate_fix): Allow .gcc_except_table
+ as a section it is ok to have unadorned -mrelocatable pointers in.
+
+Sat Jan 13 11:09:08 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_section*): Wrap these functions inside
+ #ifdef OBJ_ELF.
+
+Fri Jan 12 15:32:07 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/obj-elf.c (obj_elf_section): Add hooks so machine
+ dependent section attributes can be handled.
+
+ * config/tc-ppc.h: (md_elf_section_{letter,type,word,flags}): New
+ macros to add support for exclude section flag and ordered section
+ type.
+
+ * config/tc-ppc.c (ppc_elf_section_{letter,type,word,flags}): New
+ functions to add support for exclude section flag and ordered
+ section type.
+
+Fri Jan 12 12:04:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * subsegs.c (section_symbol): Don't try to look up the section
+ symbol in the hash table. It should be possible to have a symbol
+ with the same name as a section, but no connection to it.
+
+ * read.c (cons_worker): Only call mri_comment_end from flag_mri.
+ From James Carlson <carlson@xylogics.com>.
+
+ * expr.c (operand): Skip whitespace after a close parenthesis.
+ From James Carlson <carlson@xylogics.com>.
+
+Tue Jan 2 12:43:23 1996 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * config/tc-sh.c (md_apply_fix): Call as_bad_where instead of
+ as_warn_where for relocation overflow.
+ (parse_reg): Accept register name only if next character is
+ not alphanumeric.
+
+For older changes see ChangeLog-9295
diff --git a/x/binutils/gas/ChangeLog-9899 b/x/binutils/gas/ChangeLog-9899
new file mode 100644
index 0000000..c2e4d89
--- /dev/null
+++ b/x/binutils/gas/ChangeLog-9899
@@ -0,0 +1,4860 @@
+1999-12-27 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (MATCH): Relax JumpAbsolute check. Emit a
+ warning for absolute jump/call without `*' in non-intel mode. No
+ need to set i.types[0] JumpAbsolute in intel mode.
+
+1999-12-22 Philip Blundell <pb@futuretv.com>
+
+ * config/tc-arm.c (arm_s_text): If OBJ_ELF, call the appropriate
+ hook function when changing sections.
+ (arm_s_data): Likewise.
+
+1999-12-14 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_parse_option): Add support for -marm720
+ command line switch.
+
+Tue Nov 30 22:59:00 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_pseudo_table): Add ".am33" pseudo-op.
+ (r_registers, xr_registers): Define.
+ (r_register_name, xr_register_name): New functions.
+ (md_assemble): Handle new am33 operand types and instruction
+ formats.
+ (mn10300_insert_operand, check_operand): Likewise.
+
+1999-11-29 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (thumb_mode): Turn into a tristate variable.
+ (s_force_thumb): Set thumb_mode to 2.
+ (md_assemble): Do not complain about thumb instructions on a
+ non-thumb target if thumb_mode is set to 2.
+
+1999-11-28 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-alpha.c (toplevel): Include struc-symbol.h.
+ (alpha_macro_arg): Add MACRO_{LITERAL,BASE,BYTOFF,JSR} cases.
+ (O_...): Add new machine dependent expressions if we are handling
+ explicit relocations.
+ (alpha_reloc_op): New static table holding the explicit relocation
+ information.
+ (alpha_literal_hash): New static to hold the hash table for
+ explicit relocations.
+ (alpha_macros): Add support for explicit relocations.
+ (md_begin): If explicit relocations, initialize hash table.
+ (md_assemble): Don't print a second error if tokenize_arguments
+ already printed an error message.
+ (md_apply_fix): Add support for explicit relocations.
+ (alpha_force_relocation): Ditto.
+ (alpha_fix_adjustable): Ditto.
+ (alpha_adjust_symtab): New function to support explicit
+ relocations.
+ (alpha_adjust_symtab_relocs): Ditto.
+ (debug_exp): Debug stub compiled if DEBUG_ALPHA is defined.
+ (tokenize_arguments): Add debug code if DEBUG_ALPHA is defined.
+ Add support for explicit relocations. Return -2 if an error
+ message was already printed.
+ (find_macro_match): Add support for explicit relocations. Comment
+ each of the cases.
+ (emit_insn): Add support for explicit relocations.
+ (assemble_tokens): Ditto.
+ (emit_ldgp): Ditto.
+ (load_expression): Ditto.
+ (emit_lda): Ditto.
+ (emit_ldah): Ditto.
+ (emit_ir_load): Ditto.
+ (emit_loadstore): Ditto.
+ (emit_ldXu): Ditto.
+ (emit_ldil): Ditto.
+ (emit_sextX): Ditto.
+ (emit_division): Ditto.
+ (emit_jsrjmp): Ditto.
+ (emit_retjcr): Ditto.
+
+ * config/tc-alpha.h (RELOC_OP_P): Enable explicit relocations if
+ ELF object format.
+ (tc_adjust_symtab): If explicit relocations, call the function
+ alpha_adjust_symtab.
+ (TC_FIX_TYPE): Add fields to be able to move explicit lituse
+ relocations next to the literal relocation they reference.
+ (TC_INIT_FIX_DATA): Initialize the new fields.
+ (TC_FIX_DATA_PRINT): Print the new fields if DEBUG5 is defined.
+
+Wed Nov 24 20:27:58 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_ip): Handle PA2.0 unit completers. Handle
+ 'B' operand for PA2.0 bb instruction.
+
+1999-11-18 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.h (TC_FORCE_RELOCATION): Define for Mcore-pe
+ target.
+
+ * config/tc-mcore.c (tc_gen_reloc): Support generation of RVA
+ relocs.
+ (mcore_force_relocation): Force relocations to be generated for
+ RVA relocs.
+
+1999-11-16 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (i386_immediate): Disallow O_big immediates.
+ (i386_displacement): Disallow O_big displacements.
+
+Mon Nov 15 20:12:43 1999 Donald Lindsay <dlindsay@cygnus.com>
+
+ * config/tc-arm.c (do_mia,do_mar,do_mra,do_pld,do_ldrl,do_co_reg):
+ Small improvements in error checking.
+ (md_assemble): Support for unconditional ARM instructions.
+ (md_parse_option): Support for -m[arm]v5e flag.
+
+1999-11-12 Nick Clifton <nickc@cygnus.com>
+
+ * macro.c (buffer_and_nest): Do not check beyond the end of the
+ buffer.
+
+1999-11-11 Nick Clifton <nickc@cygnus.com>
+
+ * macro.c (buffer_and_nest): Look for seperator after TO and
+ FROM tokens.
+
+1999-11-08 Andrew Haley <aph@cygnus.com>
+
+ * app.c (do_scrub_chars): When in State 10, treat backslash
+ characters in the same way as as symbol characters.
+
+1999-11-07 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (alpha_align): Check, don't assert, that
+ the previous label was in the current section before playing
+ with auto-alignment.
+
+1999-11-06 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (v850_force_relocation): Force relocation
+ for weak symbols.
+ (v850_pcrel_from_selection): Do not compute a pcrel offset if
+ the symbol is weak.
+
+1999-11-05 Michael Meissner <meissner@cygnus.com>
+
+ * expr.h (operatorT): Increase machine dependent operators to 16.
+ * expr.c (op_rank): Ditto.
+
+1999-11-03 Ian Lance Taylor <ian@zembu.com>
+
+ * read.c (pseudo_set): Reject attempts to set the value of a
+ section symbol.
+
+ * config/obj-elf.c (obj_elf_ident): Call md_flush_pending_output
+ if it is defined.
+
+ * config/obj-elf.c (elf_set_index): Add ATTRIBUTE_UNUSED.
+
+ * config/obj-elf.c (elf_frob_file_after_relocs): Don't pass NULL
+ to bfd_set_section_contents.
+
+1999-11-03 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.h (TARGET_BYTES_BIG_ENDIAN): Change to false.
+
+1999-11-01 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (macro_build): Use OPCODE_IS_MEMBER.
+ (mips_ip): Use OPCODE_IS_MEMBER.
+
+Wed Oct 27 16:50:44 1999 Don Lindsay <dlindsay@cygnus.com>
+
+ * config/tc-arm.c (reg_required_here): Improve comments.
+
+ * config/tc-arm.c (thumb_opcode): Add "variants" field.
+ (tinsns): Initialize variants field.
+
+ * config/tc-arm.c (bad_args, bad_pc): Renamed to BAD_ARGS and
+ BAD_PC respectively.
+
+1999-10-27 Scott Bambrough <scottb@netwinder.org>
+
+ * config/tc-arm.c (reloc_map[]): Fix compiler warning.
+ * config/tc-arm.h: Fix compile time warnings.
+
+Mon Oct 18 18:11:10 MDT 1999 Diego Novillo <dnovillo@cygnus.com>
+
+ * config/tc-d10v.c (find_opcode): Allow ATSIGN to match
+ expressions of the form @abs16, @(abs16) and @(abs16 + imm).
+
+1999-10-21 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (ISA_HAS_COPROC_DELAYS) : New.
+ (ISA_HAS_64_BIT_REGS) New.
+ (gpr_interlocks,md_begin,reg_needs_delay,append_insn,
+ mips_emit_delays,macro_build,load_register,load_addresss,
+ macro,macro2,mips_ip,s_cprestore,s_cpadd): Simplify
+ and/or use new ISA_xxx macros in expressions involving
+ ISA, particularly mips_opts.isa.
+
+1999-10-18 Michael Meissner <meissner@cygnus.com>
+
+ * expr.h (operatorT): Add machine dependent operators md1..md8.
+ (expressionS): Make X_op 8 bits instead of 7. Add a X_md field
+ for the machine dependent operators to use.
+
+ * expr.c (op_rank): Add machine dependent operators.
+
+ * config/tc-alpha.c (O_pregister): Define as a machine dependent
+ operator.
+ (O_cpregister): Ditto.
+ (md_begin): Change X_op test that field is wide enough to use
+ O_max instead of O_alpha_max.
+ (cpu_types): Fill in missing initializer.
+ (alpha_num_macros): Make unsigned.
+ (md_assemble): Make opnamelen be size_t.
+ (md_apply_fix): Cast alpha_num_operands to int before testing.
+ (alpha_force_relocation): Ditto.
+ (alpha_fix_adjustable): Ditto.
+ (alpha_fix_adjustable): Mark unused arguments ATTRIBUTE_UNUSED.
+ (tc_gen_reloc): Ditto.
+ (tc_get_register): Ditto.
+ (emit_ldgp): Ditto.
+ (emit_lda): Ditto.
+ (emit_ldah): Ditto.
+ (emit_ldil): Ditto.
+ (s_alpha_ent): Ditto.
+ (s_alpha_end): Ditto.
+ (s_alpha_frame): Ditto.
+ (s_alpha_prologue): Ditto.
+ (s_alpha_file): Ditto.
+ (s_alpha_gprel32): Ditto.
+ (s_alpha_proc): Ditto.
+ (s_alpha_set): Ditto.
+ (s_alpha_base): Ditto.
+ (s_alpha_align): Ditto.
+ (s_alpha_arch): Ditto.
+ (alpha_align): Ditto.
+ (assemble_insn): Suppress unused variable warning.
+ (emit_insn): Ditto.
+ (assemble_insn): Don't assume X_op and X_unsigned are in a given
+ order in the structure.
+ (s_alpha_coff_wrapper): Avoid int/unsigned comparison.
+
+Sun Oct 17 17:15:58 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (md_apply_fix): Make "fmt" an int.
+
+1999-10-12 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (i386_index_check): Correct #endif location.
+
+Mon Oct 11 14:02:40 1999 Geoffrey Keating <geoffk@cygnus.com>
+
+ * as.c (show_usage): Document new options.
+ (parse_args): Add --no-warn, --warn, --fatal-warnings,
+ which become 'W', OPTION_WARN, and OPTION_WARN_FATAL.
+ (parse_args): Parse the new options.
+ (main): If there were warnings, and --fatal-warnings
+ was specified, print an error.
+ * as.h: New variable, flag_fatal_warnings, for new option.
+
+Sun Oct 10 01:47:23 1999 Jerry Quinn <jerry.quinn.adv91@alum.dartmouth.org>
+
+ * config/tc-hppa.c (pa_ip): Add new codes 'cc', 'cd', 'cC', 'co',
+ '@'. Change autoincrement completers to fall through to cache control
+ completers.
+
+ * config/tc-hppa.c (pa_ip): Remove unused args. Add code to '?W'
+ arg.
+ (pa_parse_addb_64_cmpltr): New function.
+
+ * config/tc-hppa.c (pa_ip): Change error message.
+ (pa_ip,pa_parse_cmpb_64_cmpltr,pa_parse_cmpib_64_cmpltr) Fix '?N' and
+ '?Q' args to allow falling through.
+
+ * config/tc-hppa.c (pa_ip): Implement conditional codes "?N", "?Q".
+ Remove unused conditional codes.
+ (pa_parse_cmpb_64_cmpltr,pa_parse_cmpib_64_cmpltr): New.
+
+Thu Oct 7 00:23:53 MDT 1999 Diego Novillo <dnovillo@cygnus.com>
+
+ * config/tc-d30v.c (CHAR_BIT): Define.
+ (check_range): Fix bit operations to support integers bigger than
+ 32 bits.
+
+Thu Oct 7 00:11:50 MDT 1999 Diego Novillo <dnovillo@cygnus.com>
+
+ * config/tc-d10v.c (check_range): Check range for RESTRICTED_NUM3
+ operands.
+
+Mon Oct 4 17:24:23 1999 Nick Clifton <nickc@cygnus.com>
+ Doug Evans <devans@cygnus.com>
+
+ Add support for m32rx.
+ * config/tc-m32r.c (enable_m32rx): New static global.
+ (enable_special,warn_explicit_parallel_conflicts,optimize): Ditto.
+ (allow_m32rx): New function.
+ (M32R_SHORTOPTS): Add `O'.
+ (md_longopts): Add --m32rx plus several warning options.
+ (md_parse_option): Handle new options.
+ (md_show_usage): Print them.
+ (md_begin): Enable m32rx.
+ (OPERAND_IS_COND_BIT): New macro.
+ (first_writes_to_seconds_operands): New function.
+ (writes_to_pc,can_make_parallel,make_parallel): New functions.
+ (target_make_parallel,assemble_two_insns): New functions.
+ (md_assemble): Recognize "insn1 -> insn2" and "insn1 || insn2".
+ If optimizing and m32rx, try to make consecutive insns parallel.
+
+Tue Sep 28 14:06:44 1999 Geoffrey Keating <geoffk@cygnus.com>
+
+ * config/tc-mips.c (nopic_need_relax): Allow for the
+ .sdata.foo sections generated by -fdata-sections,
+ and for the .gnu.linkonce.s sections generated by C++.
+
+Thu Sep 23 07:13:45 1999 Jerry Quinn <jquinn@nortelnetworks.com>
+
+ * config/tc-hppa.c (pa_ip): Replace 'B', 'M', 'l' and 'g' handling
+ with cleaner code using completer prefixes. Add 'Y'.
+
+ * config/tc-hppa.c (pa_ip): Add parens to silence compiler.
+
+Wed Sep 22 09:37:19 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_ip): Avoid ANSI specific initialization.
+ (pa_ip, case 'm'): Failure to get a CBIT specifier just means the
+ insn does not match and we should try the next insn in the table.
+
+1999-09-22 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (MULTI_SET_PSR): Rename to LDM_TYPE_2_OR_3.
+
+Mon Sep 20 04:01:41 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_ip): Fix thinkos in recent cleanup
+ of PA2.0 support.
+
+1999-09-19 Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+
+ * config/tc-i386.c (md_shortopts): Check OBJ_MAYBE_ELF as well as
+ OBJ_ELF. If ELF, add "sq".
+ (md_parse_option): If ELF, ignore -s and -q.
+ (md_show_usage): Mention ELF options.
+
+Sun Sep 19 10:43:31 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_ip): Handle 'J', 'K' and 'cc'
+ operands.
+
+ * config/tc-hppa.c (pa_ip): Handle "fe", and 'cJ'.
+
+ * config/tc-hppa.c (pa_ip): Handle 'd', '#' and 'cq'.
+
+ * config/tc-hppa.c (struct pa_it): New field "trunc".
+ (pa_ip): Handle 'h', 'm', '=', '{', and '_' operands.
+ (pa_parse_ftest_gfx_completer): New function
+ (pa_parse_fp_cnv_format): New function.
+
+ * config/tc-hppa.c (pa_ip): Handle 'X' operand.
+ (md_apply_fix): Handle 22bit pc-rel branches.
+
+ * config/tc-hppa.c (pa_ip): Handle 'B' operand.
+
+ * config/tc-hppa.c (pa_ip): Handle 'L' and 'M' operands.
+
+ * config/tc-hppa.c (pa_ip): Handle 'l' operand.
+
+ * config/tc-hppa.c (pa_ip): Handle 'g' operand.
+
+Sat Sep 18 12:13:28 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (md_assemble): Fix dwarf2 line handling.
+ (pa_ip): Handle 'fX'.
+
+Fri Sep 17 11:57:34 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_build_unwind_subspace): Do not build
+ unwinds unless the function is in the text space.
+ (pa_type_args): Set BSF_FUNCTION for an exproted data symbol.
+
+Wed Sep 15 05:14:32 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_ip): Move dwarf2 stuff from here.
+ (md_assemble): To here. Tweak address generation.
+
+ * config/tc-hppa.c: Include dwarf2dbg.h if OBJ_ELF. Declare
+ debug_line.
+ (md_pseudo_table): Add .file and .line pseudo-ops for OBJ_ELF.
+ (md_assemble): Call dwarf2_where for OBJ_ELF.
+ (pa_ip): Call dwarf2_gen_line_info for OBJ_ELF.
+ (pa_end_of_source): New function.
+ * config/tc-hppa.h (md_end): Define for OBJ_ELF.
+
+1999-09-14 Michael Meissner <meissner@cygnus.com>
+
+ * configure.in (Canonicalization of target names): Remove adding
+ ${CONFIG_SHELL} in front of $ac_config_sub, since autoconfig 2.14
+ generates $ac_config_sub with a ${CONFIG_SHELL} already.
+ * configure: Regenerate.
+
+1999-09-14 Donn Terry <donn@interix.com>
+
+ * config/te-interix.h (GLOBAL_OFFSET_TABLE_NAME): Define.
+
+1999-09-13 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (md_assemble): Handle "jmp/call constant" as a
+ pc-relative jmp/call to an absolute symbol.
+ (md_apply_fix3): When OBJ_ELF, don't add the values in twice for
+ absolute section symbols.
+
+ * config/tc-i386.c (md_assemble): Correct frag_var size. Tidy
+ jump handling code and comments.
+
+1999-09-12 Ian Lance Taylor <ian@zembu.com>
+
+ * config/tc-i386.c (md_apply_fix3): Add horrible adjustments to
+ the value if TE_PE and a global defined symbol.
+
+1999-09-11 Ian Lance Taylor <ian@zembu.com>
+
+ * write.c (dump_section_relocs): Call print_symbol_value_1 to
+ print the symbol, rather than printing it here.
+
+1999-09-11 Donn Terry <donn@interix.com>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Don't adjust
+ BFD_RELOC_RVA relocations.
+
+ * config/tc-i386.c (md_undefined_symbol): Compare the name against
+ the macro GLOBAL_OFFSET_TABLE_NAME, rather than assuming that it
+ starts with "_G".
+
+ * write.c (write_relocs): Call SET_SECTION_RELOCS if it is
+ defined.
+ * config/obj-coff.h (SET_SECTION_RELOCS): Define.
+ * doc/internals.texi (Object format backend): Document
+ SET_SECTION_RELOCS.
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Don't adjust
+ relocations against global symbols if TE_PE.
+
+ * config/obj-coff.c (obj_coff_ident): Add BFD_ASSEMBLER version.
+ (obj_pseudo_table): Always handle ".ident" with obj-coff_ident.
+
+ * config/obj-coff.c (coff_frob_symbol): Prohibit weak common
+ symbols.
+
+ * config/obj-coff.c (obj_coff_endef): Don't merge labels, or
+ symbols which do not have a constant value, or tags with
+ non-tags. Remove the symbol from the list before adding it at the
+ end.
+
+ * config/obj-coff.c (obj_coff_endef) [BFD_ASSEMBLER]: Handle .ef
+ C_FCN symbol differently if TE_PE.
+ (obj_coff_line) [BFD_ASSEMBLER]: Always use the line number which
+ appears in the pseudo-op, rather coff_line_base which is only set
+ for a .bf symbol.
+
+ * config/obj-coff.c (obj_coff_loc): New static function.
+ (obj_pseudo_table): Add "loc".
+
+ * config/obj-coff.c (add_lineno): Check that the line number is
+ positive.
+
+ * config/atof-ieee.c (atof_ieee): Change what_kind to int.
+ * config/atof-vax.c (flonum_gen2vax): Change format_letter to
+ int.
+ (md_atof): Return NULL rather than 0.
+ * config/tc-i386.c (md_atof): Change type to int.
+ * expr.c (expr): Change first parameter to int.
+ * config/obj-coff.c: Add declarations for static functions.
+ (coff_frob_symbol): Use SYM_AUXENT.
+ * config/tc-i386.h (flag_16bit_code): Don't declare.
+
+ * config/obj-coff.c (obj_coff_section): Default to setting
+ SEC_LOAD. Don't set SEC_DATA for 'w' modifier.
+
+ * write.c (adjust_reloc_syms): Print adjusted fixup.
+
+ * expr.c (integer_constant): Correct too_many_digits calculation
+ in base 10 case.
+
+1999-09-09 Andreas Schwab <schwab@suse.de>
+
+ * doc/c-arm.texi: Fix arguments of @var to not contain
+ punctuation.
+
+1999-09-08 Philip Blundell <pb@nexus.co.uk>
+
+ * config/tc-arm.c (s_thumb_set): Only support interworking for ELF
+ and COFF targets.
+ (md_parse_option): Only support -k flag for ELF and COFF targets.
+
+Tue Sep 7 13:28:59 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_ip): Put strict register checks before
+ call to pa_parse_number.
+
+ * config/tc-hppa.c (pa_ip): Support 'Z' argument.
+
+1999-09-06 Ian Lance Taylor <ian@zembu.com>
+
+ * config/obj-coff.c: Add ATTRIBUTE_UNUSED as needed for
+ BFD_ASSEMBLER code.
+
+1999-09-06 Donn Terry <donn@interix.com>
+
+ * as.c (perform_an_assembly_pass): Set SEC_DATA for data_section.
+
+Mon Sep 6 04:26:56 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_ip): Get strict/non-strict mode from the
+ candidate instruction. Require registers for register arguments
+ when in strict mode. Require assemble-time constants for
+ constants when in strict mode.
+ (pa_get_absolute_expression): Require a constant when in strict
+ mode.
+
+1999-09-06 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c (md_longopts): Fix value for -Wnuh.
+
+1999-09-04 Steve Chamberlain <sac@pobox.com>
+
+ * config/tc-pj.c: New file, supports picoJava in ELF.
+ * config/tc-pj.h: Ditto.
+ * configure.in (pjl*, pj*): New targets.
+ * Makefile.am: Rebuild dependencies.
+ (CPU_TYPES): Add pj.
+ (TARGET_CPU_CFILES): Add config/tc-pj.c.
+ (TARGET_CPU_HFILES): Add config/tc-pj.h.
+ * doc/c-pj.texi: New file.
+ * doc/as.texinfo: Add some PJ specifics.
+ * doc/all.texi: Add PJ to the list of all architectures, sort them
+ all alphabetically.
+ * doc/Makefile.in (CPU_DOCS): Add c-pj.texi.
+ * configure, Makefile.in, doc/Makefile.in: Rebuild.
+
+1999-09-02 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/obj-multi.h: Include obj-elf.h if OBJ_MAYBE_ELF. Reformat.
+ (obj_frob_file): Test for null pointer.
+ (OBJ_COPY_SYMBOL_ATTRIBUTES): Here too.
+ (OBJ_PROCESS_STAB): And here.
+ (elf_obj_sy): Remove
+
+ * config/obj-elf.h: #ifndef everything defined in obj-multi.h,
+ except OBJ_PROCESS_STAB, which we #undef for ecoff.
+ (elf_obj_sy): Remove #ifndef OBJ_SYMFIELD_TYPE.
+
+ * config/obj-coff.c (no_func): Remove.
+ (coff_format_ops): Change occurrences of no_func to 0, as we test
+ for 0 in obj-multi.h.
+
+ * configure.in: Enable bfd for i386-coff when primary target is
+ bfd. Enable i386 elf,coff emulation support. Don't set
+ USE_EMULATIONS=1 or te_file=multi unless there is more than one
+ emulation to support.
+ *configure: Regenerate.
+
+1999-09-02 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.c (mcore_s_section): Do not dump literals if a
+ .section .line directive is encountered.
+
+1999-09-01 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_section_align): Do not align sections in ELF
+ format.
+
+ * as.c (show_usage): Add --gdwarf2 to list of options displayed.
+ * as.texinfo: Document --gdwarf2 command line option.
+ Add additional documentation of ARM command line switches.
+
+1999-08-30 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (i386_intel_memory_operand): Combine
+ i386_is_reg and parse_register calls. Remove END_STRING_AND_SAVE
+ and RESTORE_END_STRING around parse_register calls.
+ (i386_operand): Here too.
+ (i386_is_reg): Remove.
+ (parse_register): Move as_bad calls from within this function to
+ callers.
+
+1999-08-29 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ Based on a patch from H.J. Lu <hjl@gnu.org>
+ * config/tc-i386.c (parse_register): Handle FP regs specially.
+ (md_begin): Remove '(' and ')' from register_chars.
+
+1999-08-29 Doug Evans <devans@casey.cygnus.com>
+
+ * config/tc-m32r.c (md_parse_option): Delete unrecognized option
+ error message (done elsewhere).
+
+Sat Aug 28 01:23:11 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_ip): Do not allow '*' in 32bit completers.
+
+Sat Aug 28 00:26:26 1999 Jerry Quinn <jquinn@nortelnetworks.com>
+
+ * config/tc-hppa.c (pa_ip): Replace 'f' by 'v'. Prefix float register
+ args by 'f'.
+
+ * config/tc-hppa.c (pa_ip): Add args q, %, and |.
+
+ * config/tc-hppa.c (pa_ip): Absorb white space in instructions
+ between args.
+ Add new completers. Fix bug in 64 bit condition handling.
+
+ * config/tc-hppa.c (pa_ip): Add completer codes 'a', 'ch', 'cH',
+ 'cS', and 'c*'.
+
+ * config/tc-hppa.c (pa_ip): Place completers behind prefix 'c'.
+
+ * config/tc-hppa.c (pa_ip): Add cases for '.', '~'. '$'. and '!'
+
+ * config/tc-hppa.c (pa_ip): Add case for 'I'.
+
+1999-08-27 Jim Wilson <wilson@cygnus.com>
+
+ * dwarf2dbg.c (MAX_SPECIAL_ADDR_DELTA): Correct typo in comment.
+ (struct ls): Add frag field. Initialize it to zero.
+ (out_end_sequence): New local text_frag. Set it while in text section.
+ Replace address check with frag check. Set ls.frag to text_frag if
+ out_set_addr called.
+ (dwarf2_gen_line_info): Add explanatory comment. New local saved_frag.
+ Set it before switching sections. Replace address check with frag
+ check. Set ls.frag to saved_frag if out_set_addr called.
+
+1999-08-26 David Mosberger <davidm@hpl.hp.com>
+
+ * dwarf2dbg.c (out_end_sequence): If address changed, directly
+ output "advance_pc" opcode instead of calling gen_addr_line().
+ The latter has the undesired side-effect of creating a new row
+ in the debug line info matrix.
+
+1999-08-26 Jim Wilson <wilson@cygnus.com>
+
+ * dwarf2dbg.c (out_end_sequence): Correct comments. Set last to
+ ls.last_filename if last is less than zero. Set ls.last_filename
+ when allocating new entry.
+ (dwarf2_gen_line_info): Save seg and subseg info before subseg_new
+ call.
+
+1999-08-20 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (i386_index_check): Fix the displacement size
+ when INFER_ADDR_PREFIX.
+
+1999-08-18 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_apply_fix3): If an offset is invalid,
+ display its value.
+
+1999-08-17 Ian Lance Taylor <ian@zembu.com>
+
+ * config/tc-ppc.c (md_assemble): Trim @ha constant to 16 bits, to
+ handle 0xffffNNNN constants correctly.
+
+1999-08-16 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (do_ldst): Look for register conflicts on stores
+ as well as loads.
+
+1999-08-13 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (validate_offset_imm): Work on unsigned values.
+ (md_apply_fix3): Always pass positive values to
+ validate_offset_imm.
+
+1999-08-12 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (skip_whitespace): New macro.
+ Formatting tidy ups.
+
+ (md_apply_fix3): Store relocation offset in addend for ELF based
+ relocs.
+ (arm_force_relocation): Always generate relocs for Thumb function
+ calls.
+
+1999-08-11 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (md_assemble): Remove dead code. intel_syntax
+ LONG_DOUBLE_MNEM_SUFFIX floating point is done in opcode/i386.h
+
+Tue Aug 10 12:58:31 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_build_unwind_subspace): Use sane section
+ flags for the unwind subspace.
+
+ * config/tc-hppa.c (UNWIND_SECTION_NAME): Define for ELF.
+ (pa_build_unwind_subspace): Remove #if 0 wrapper. Select a
+ suitable relocation based on the size of the target's pointer.
+ Always Use subsegment zero for the unwinders.
+ (pa_level): Handle "2.0w".
+
+Mon Aug 9 20:02:22 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-d30v.c (write_2_short): Don't group repeat instructions
+ with the following instruction unless this was specified.
+
+1999-08-09 Ian Lance Taylor <ian@zembu.com>
+
+ * config/tc-i386.h (SUB_SEGMENT_ALIGN): If TE_GO32, return 4 for
+ certain sections, to match BFD changes.
+
+1999-08-08 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * Makefile.am (noinst_SCRIPTS): Change .gdbinit to $(GDBINIT).
+ (EXTRA_SCRIPTS): Define to keep automake happy.
+ * Makefile.in: Rebuild.
+
+1999-08-08 Ian Lance Taylor <ian@zembu.com>
+
+ * Makefile.am: Rename .dep* files to DEP*.
+ (MKDEP): Rename from DEP. Change all uses. Use $${srcdir} rather
+ than $(srcdir). Rename TCDEP targets to DEPTC. Rename OBJDEP
+ targets to DEPOBJ.
+ * Makefile.in: Rebuild.
+
+1999-08-08 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * config/tc-sparc.c (sparc_ip): Allow assembly of %lo()+%reg.
+
+1999-08-08 Ian Lance Taylor <ian@zembu.com>
+
+ * Makefile.am: Change all uses of itbl-test-ops to itbl-tops to
+ avoid problems on DOS filesystems.
+ * Makefile.in: Rebuild.
+
+ * doc/as.texinfo (Section): Document 's' flag for COFF version.
+
+1999-08-08 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * config/obj-coff.c (obj_coff_section): Handle 's' (shared)
+ section flag.
+
+1999-08-08 Ian Lance Taylor <ian@zembu.com>
+
+ * configure.in: Define and substitute GDBINIT. Change AC_OUTPUT
+ line to create ${GDBINIT} rather than .gdbinit.
+ * configure, Makefile.in, doc/Makefile.in: Rebuild.
+
+Fri Aug 6 12:12:44 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_ip, case '?'): Add missing break.
+
+Fri Aug 6 09:46:35 1999 Jerry Quinn <jquinn@nortelnetworks.com>
+
+ * config/tc-hppa.c (pa_ip): Add 64 bit condition completers.
+
+1999-08-06 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * config/tc-sparc.h (tc_fix_adjustable): Fix check for PIC local
+ non-adjustable symbols.
+
+Thu Aug 5 16:52:51 1999 Jerry Quinn <jquinn@nortelnetworks.com>
+
+ * config/tc-hppa.c (pa_ip): Change condition args to have '?' prefix.
+
+Thu Aug 5 23:05:56 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-sh.c (md_assemble): Call as_bad when there are excess
+ operands.
+
+1999-08-05 Donn Terry <donn@interix.com>
+
+ * config/te-interix.h: New file.
+ * configure.in (i386-*-interix*): New target.
+ * configure: Rebuild.
+
+Wed Aug 4 13:12:17 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_chk_field_selector): Allow 3 byte
+ selectors for ELF too.
+ (selector_table): Add "ltp" and "rtp" selectors.
+
+1999-08-04 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (i386_operand): No need to change
+ operand_string pointer in segment reg case before goto
+ do_memory_reference. Initialise displacement_string_start and
+ displacement_string_end after do_memory_reference label.
+ (i386_index_check): Add operand_string param, and print error
+ message on failure here.
+ (i386_intel_memory_operand): Instead of here.
+ (i386_operand): And here.
+ (INFER_ADDR_PREFIX): Enable.
+
+ * doc/c-i386.texi (i386-16bit): Document .code16gcc.
+
+ * config/tc-i386.h (DefaultSize): Define. Renumber following
+ opcode_modifier defines.
+
+ From Etienne Lorrain <etienne.lorrain@ibm.net>
+ * config/tc-i386.c (stackop_size): New variable.
+ (set_16bit_code_flag): Clear it here.
+ (set_16bit_gcc_code_flag): New function.
+ (md_pseudo_table): Add "code16gcc" entry.
+ (md_assemble): Set i.suffix for insns with DefaultSize modifier.
+
+1999-08-03 Ian Lance Taylor <ian@zembu.com>
+
+ * config/obj-coff.c (coff_frob_symbol): Always update set_end with
+ next_set_end even if the end symbol is being discarded.
+
+ * gasp.c: Add ATTRIBUTE_UNUSED as needed for non-BFD_ASSEMBLER.
+ * output-file.c, symbols.c, config/tc-i386.c: Likewise.
+ * config/obj-coff.c: Likewise.
+ (seg_info_type): Remove.
+ (seg_info_off_by_4): Change to array of segT.
+ (s_get_segment): Adjust accordingly.
+ (obj_pseudo_table): Fully initialize sentinel entry.
+
+ * config/tc-mips.c (append_insn): Correct INSN_SYNC test. From
+ Ralf Baechle <ralf@uni-koblenz.de>.
+
+1999-08-03 Etienne Lorrain <etienne.lorrain@ibm.net>
+
+ * config/tc-i386.c (f16_3): New. Fixes 16 bit 3 byte nop.
+
+1999-08-03 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c: Indentation and white space changes.
+ (i386_index_check): New function. Add INFER_ADDR_PREFIX code, but
+ don't enable it by default.
+ (i386_intel_operand): Remove redundant prototype.
+ Move check on number of memory operands, and i.mem_operands++
+ (i386_intel_memory_operand): To here.
+ Remove i386_immediate code from here. Remove special case code
+ for input and output using (%dx). Remove base/index checks and
+ call i386_index_check instead. Save initial operand_string
+ argument for error message.
+ (i386_operand): Remove redundant prototype. Move base/index
+ checks to i386_index_check.
+ (i386_displacement): Move intel mode check for non-zero
+ i.disp_operand
+ (i386_intel_memory_operand): To here.
+
+1999-07-30 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * config/tc-sparc.c (md_longopts): Add --no-undeclared-regs option.
+ (sparc_ip): Warn if %g2 or %g3 register is used and not covered
+ by .register pseudo-op if -64 and --no-undeclared-regs.
+ (s_register, sparc_adjust_symtab): New functions.
+ * config/tc-sparc.h (tc_adjust_symtab, sparc_adjust_symtab):
+ Declare sparc_adjust_symtab as tc_adjust_symtab.
+ * doc/c-sparc.texi: Add description of #ignore special literal
+ for .register pseudo-op.
+
+1999-07-30 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-arm.c (tc_gen_reloc): Record the vtable entry in
+ the relocation's section offset.
+
+1999-07-29 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * write.c (fixup_segment): Fix generic error check overflow test.
+
+ * config/tc-i386.c (pe): Change %d to %ld, %x to %lx, and cast
+ X_add_number to long.
+
+Wed Jul 28 02:04:24 1999 "Jerry Quinn" <jquinn@nortelnetworks.com>
+
+ * config/tc-hppa.c (pa_ip): Add 'J' and 'K' code
+ processing.
+
+1999-07-27 Ian Lance Taylor <ian@zembu.com>
+
+ * config/tc-sparc.h (tc_fix_adjustable): Don't adjust GOT, PLT, or
+ VTABLE relocations.
+
+1999-07-21 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * config/te-go32.h (COFF_LONG_SECTION_NAMES): Define.
+
+ * configure.bat: Remove; obsolete.
+ * config/go32.cfg: Likewise.
+
+1999-07-21 Brad M. Garcia <bgarcia@fore.com>
+
+ * configure.in (i386-*-vxworks*): New target.
+ * configure: Rebuild.
+
+1999-07-16 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * doc/c-sparc.texi: Document .register and .nword pseudo-ops.
+
+1999-07-16 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * config/tc-sparc.c (sparc_ip): Allow OLO10 relocations
+ on -64 and not pic.
+ (output_insn): Put OLO10's secondary addend into tc_fix_data.
+ (md_apply_fix3): Handle BFD_RELOC_SPARC_OLO10.
+ (tc_gen_reloc): Return two relocs for OLO10, LO10 and SPARC13.
+ * config/tc-sparc.h (RELOC_EXPANSION_POSSIBLE,
+ MAX_RELOC_EXPANSION): Define.
+ (TC_FIX_TYPE, TC_INIT_FIX_DATA, TC_FIX_DATA_PRINT): Likewise.
+
+1999-07-16 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (intel_float_operand): Add prototype, make static.
+ (md_assemble): Localize *exp variable to if (fake_zero_displacement)
+ block. Print a warning if an 8-bit or 16-bit constant
+ displacement or immediate is truncated on output.
+ (i386_immediate): Ensure Imm16 is always legal for a 16-bit mode
+ immediate.
+ (i386_operand): Disallow immediate jump absolute operand.
+
+1999-07-15 Ian Lance Taylor <ian@zembu.com>
+
+ * configure.in: Bump version number to 2.9.5.
+ * configure: Rebuild.
+
+ * dwarf2dbg.c (dwarf2_gen_line_info): Don't assume that long long
+ or %llx work.
+
+Thu Jul 15 02:45:30 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (md_pseudo_table): Add ".dword" pseudo-op.
+ (cons_fix_new_hppa): Derive size of fixup from size of the object.
+
+1999-07-14 Philip Blundell <pb@nexus.co.uk>
+
+ * symbols.c (dollar_label_name): Prepend LOCAL_LABEL_PREFIX if it
+ is defined.
+ * config/tc-arm.h (LOCAL_LABEL_PREFIX): Define to '.' for ELF.
+
+ * config/tc-arm.c (md_begin): Set F_SOFTFLOAT in the output file
+ if -mno-fpu was given.
+ (tc_gen_reloc): Fix typo. Delete bogus code related to GOTPC
+ relocs.
+ (cons_fix_new_arm): Remove misleading comments.
+
+1999-07-14 Ian Lance Taylor <ian@zembu.com>
+
+ * write.c (cvt_frag_to_fill): Use frag file and line in rs_org
+ error message.
+ (relax_segment): Likewise. After giving a rs_org error, convert
+ the frag to rs_align to avoid cascading errors.
+
+1999-07-12 Andreas Schwab <schwab@suse.de>
+
+ * config/tc-m68k.c: Add some ATTRIBUTE_UNUSED.
+
+1999-07-11 Ian Lance Taylor <ian@zembu.com>
+
+ * Many files: Changes to avoid gcc warnings: Add ATTRIBUTE_UNUSED
+ as appropriate. Fill in structure initializations. Add variable
+ initializations. Add casts.
+ * dwarf2dbg.c (print_stats): Change i to size_t.
+ * listing.c (listing_listing): Change list_line to unsigned int.
+
+1999-07-10 Ian Lance Taylor <ian@zembu.com>
+
+ * config/tc-ppc.h (tc_fix_adjustable) [OBJ_ELF]: Call S_IS_LOCAL
+ rather than checking for \001 and \002 in symbol name.
+ * config/tc-sparc.h (tc_fix_adjustable) [OBJ_ELF]: Likewise.
+
+Thu Jul 8 12:32:23 1999 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * configure.in (hppa*-linux-gnu*): New target.
+ * configure: Rebuilt.
+
+1999-07-08 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-arm.texi (ARM Directives): Document .thumb_set directive.
+
+1999-07-07 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (v850_comm): Use symbol_get_obj() rather than
+ accessing symbolP directly.
+
+Tue Jul 6 10:41:42 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.h (tc_frob_symbol): Always punt "$global$" symbol
+ for ELF.
+
+1999-07-05 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (ARM_EXT_V5): Define.
+ (ARM_ARCH_V5, ARM_ARCH_V5T): Define.
+ (md_begin): Detect ARM v5 architectures.
+ (md_parse_option): Accept arm v5 specification.
+ (md_show_usage): Documment -marmv5 switch.
+
+ * doc/c-arm.texi: Document -marmv5 command line option.
+
+ * config/tc-arm.c (do_adrl): New function. Implement ADRL pseudo
+ op.
+ (validate_immediate_twopart): New function. Determine if a
+ constant can be computed by two ADD instructions.
+ (output_inst): Remove its command line parameter - it was never
+ used.
+ (md_apply_fix3): Support BFD_RELOC_ARM_ADRL_IMMEDIATE, used to
+ implememt the ADRL pseudo op.
+ (tc_gen_reloc): Generate a suitable error message if an ADRL
+ instruction tries to generate a real reloc.
+
+ * doc/c-arm.texi: Document NOP, ADR and ADRL pseudo ops.
+
+Thu Jul 1 15:33:10 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_ip): Convert the opcode and all completers
+ into lower case.
+
+1999-06-27 H.J. Lu <hjl@gnu.org>
+
+ * subsegs.c (subseg_text_p): Use 1/0 instead of true/false for
+ non BFD_ASSEMBLER case.
+
+1999-06-26 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * config/obj-coff.c (obj_coff_section): Mark writable sections as
+ data.
+
+1999-06-26 David Mosberger <davidm@hpl.hp.com>
+
+ * dwarf2dbg.c (dwarf2_gen_line_info): Don't call
+ out_end_sequence() when the address decreases due to a new frag.
+ (gen_dir_list): Set ls.file[i].dir to j + 1 (not j) because file
+ numbering starts with 1.
+
+1999-06-23 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.c (md_pseudo_table): Add .comm for ELF and allow
+ .section for COFF.
+ (mcore_s_text): Call obj_elf_text for ELF target.
+ (mcore_s_data): Call obj_elf_data for ELF target.
+ (mcore_s_section): No longer ELF specific. Call obj_coff_section
+ for COFF target.
+ (mcore_s_bss): New function: Dump literal table before changing
+ sections.
+ (mcore_s_comm): New function: Dump literal table before changing
+ sections.
+
+ * config/obj-elf.c (obj_elf_common, obj_elf_data, obj_elf_text):
+ No longer static functions.
+ * config/obj-elf.h (obj_elf_common, obj_elf_data, obj_elf_text):
+ Provide prototypes for these functions.
+
+1999-06-22 Ian Lance Taylor <ian@zembu.com>
+
+ * subsegs.c (subseg_text_p): Rewrite non BFD_ASSEMBLER case to use
+ a list of names, to try obj_segment_name, and to try abbreviated
+ names when using COFF without long section names.
+
+ * config/tc-alpha.c: More use of symbol accessor functions.
+ * config/tc-arc.c: Likewise.
+ * config/tc-d30v.c: Likewise.
+ * config/tc-fr30.c: Likewise.
+ * config/tc-i860.c: Likewise.
+ * config/tc-m88k.c: Likewise.
+ * config/tc-mcore.c: Likewise.
+ * config/tc-ns32k.c: Likewise.
+ * config/tc-sparc.c: Likewise.
+ * config/tc-v850.c: Likewise.
+
+ * config/tc-arc.c (get_arc_exp_reloc_type): Change uses of
+ sy_value with appropriate accessor functions.
+ * config/tc-arm.c (md_apply_fix3): Likewise.
+ * config/tc-d10v.c (AT_WORD_P): Likewise.
+ * config/tc-v850.c (reg_name_search): Likewise.
+
+ * config/obj-ecoff.c (obj_ecoff_set_ext): Change uses of bsym to
+ use symbol_get_bfdsym instead.
+ * config/tc-ppc.c (md_assemble): Likewise.
+ * config/tc-v850.c (v850_comm): Likewise.
+
+1999-06-22 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * config/tc-arc.c (tc_gen_reloc): Use symbol_get_bfdsym to get at
+ the symbol, rather than accessing the bsym member.
+ * config/tc-d10v.c (tc_gen_reloc): Likewise.
+ * config/tc-d30v.c (tc_gen_reloc): Likewise.
+ * config/tc-mcore.c (tc_gen_reloc): Likewise.
+ * config/tc-mn10200.c (tc_gen_reloc): Likewise.
+ * config/tc-mn10300.c (tc_gen_reloc): Likewise.
+ * config/tc-ns32k.c (tc_gen_reloc): Likewise.
+ * config/tc-tic30.c (tc_gen_reloc): Likewise.
+ * config/tc-v850.c (tc_gen_reloc): Likewise.
+
+Mon Jun 21 16:45:19 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (elf_hppa_reloc_type): Renamed from elf32_hppa_reloc_type.
+ (hppa_gen_reloc_type): Conditionalize on BFD64.
+ (tc_gen_reloc): Re-enable ELF relocations.
+ * config/tc-hppa.h (TARGET_FORMAT): Handle elf64-hppa format.
+
+1999-06-21 Ian Lance Taylor <ian@zembu.com>
+
+ * config/tc-arm.c (ldst_extend): Add parentheses to avoid
+ warning.
+ (do_ldst): Move assignment out of if condition.
+ (md_apply_fix3): Add casts to avoid printf format warnings. Add
+ parentheses to avoid warning.
+
+1999-06-21 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (arm_adjust_symtab): Use symbol_get_bfdsym()
+ macro to get at the BFD symbol associated with a GAS symbol.
+
+1999-06-19 Ian Lance Taylor <ian@zembu.com>
+
+ * config/tc-ppc.c: Update for symbol handling changes.
+ * config/obj-coff.c: Likewise.
+
+Fri Jun 18 14:34:18 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c: General cleanups of ELF support. No more spaces
+ and subspaces for ELF.
+ (GDB_DEBUG_SPACE_NAME): Delete definition for ELF.
+ (GDB_STRINGS_SUBSPACE_NAME): Likewise.
+ (GDB_SYMBOLS_SUBSPACE_NAME): Likewise
+ (UNWIND_SECTION_NAME): Likewise.
+ (space/subspace related structures): Conditionalize definitions
+ on OBJ_SOM.
+ (space/subspace directives and support routines): Conditionalize
+ definitions and references/uses on OBJ_SOM.
+ (label_symbol_struct): For ELF, track the symbol's segment. For
+ SOM track its space.
+ (pa_define_label, pa_undefine_label, pa_get_label): Corresponding
+ changes.
+ (USE_ALIASES): Kill for both SOM & ELF.
+ (pa_def_subspaces, pa_def_spaces): Corresponding changes.
+ (pa_space, pa_subspace): Corresponding changes.
+ (pa_spaces_begin): Corresponding chagnes.
+ (md_begin): Do not muck around with space/subspace stuff for
+ OBJ_ELF.
+ (md_apply_fix): Temporarily disable argument relocation stuff
+ for OBJ_ELF.
+ (tc_gen_reloc): Temporarily disable relocation generation for
+ OBJ_ELF
+ (pa_build_unwind_subspace): Similarly.
+
+1999-06-16 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (thumb_set): New pseudo op.
+ (text, data, section): Override these pseudo ops with ARM
+ specific versions.
+ (s_thumb_set): New function: Perform the same as a .set pseudo
+ op, but also mark the alias'ed symbol as being a Thumb
+ function.
+ (arm_s_text): New function: Perform the same as the .text
+ pseudo op, but dump the literal pool before changing
+ sections.
+ (arm_s_data): New function: Perform the same as the .data
+ pseudo op, but dump the literal pool before changing
+ sections.
+ (arm_s_section): New function: Perform the same as the
+ .section pseudo op, but dump the literal pool before changing
+ sections.
+ (arm_cleanup): Do not reset the current section before dumping
+ the literal pool.
+
+1999-06-17 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c (md_longopts): Fix OPTION_WARN_UNMATCHED and
+ OPTION_NO_WARN_UNMATCHED entries.
+ (md_parse_option): Generate a warning message if an unrecognised
+ option is encountered.
+
+ * config/tc-d10v.c (do_not_ignore_hash): New variable.
+ (get_operands): When parsing an expression after an '@' symbol
+ has been detected, do not ignore '#' symbols.
+ (md_operand): Only ignore '#' symbols if do_not_ignore_hash is
+ false.
+
+1999-06-13 Ian Lance Taylor <ian@zembu.com>
+
+ From K. Richard Pixley <rich@noir.com>:
+ * configure.in (ppc-*-vxworks*): New target.
+ * configure: Rebuild.
+
+1999-06-12 Philip Blundell <philb@gnu.org>
+
+ * config/tc-arm.c (tc_gen_reloc): Fix handling of GOTPC relocs.
+
+1999-06-13 Ian Lance Taylor <ian@zembu.com>
+
+ * write.c (adjust_reloc_syms): Rather than never reducing reloc
+ which refer to symbols in linkonce sections, permit reducing the
+ relocs if the symbol is local.
+
+1999-06-12 Ian Lance Taylor <ian@zembu.com>
+
+ * subsegs.c (subseg_text_p): New function.
+ * as.h (subseg_text_p): Declare.
+ * read.c (do_align): Use subseg_text_p to set the default fill.
+ * write.c (subsegs_finish): Likewise.
+ * config/obj-coff.c (write_object_file): Likewise.
+ * config/tc-i386.h (md_maybe_text): Don't define.
+ (md_do_align): Use subseg_text_p to set the default fill.
+ * config/tc-m32r.c (m32r_do_align): Likewise.
+ * config/tc-sh.c (sh_do_align): Likewise.
+ * config/tc-sparc.h (md_do_align): Likewise.
+
+1999-06-12 David O'Brien <obrien@freebsd.org>
+
+ * configure.in: (i[3456]86-*-freebsd*): Now defaults to ELF.
+ * configure: Rebuild.
+
+1999-06-12 Ian Lance Taylor <ian@zembu.com>
+
+ * dwarf2dbg.c: Include elf/dwarf2.h with "", not <>.
+ * Makefile.am: Rebuild dependencies.
+ * Makefile.in: Rebuild.
+
+ * config/tc-i386.c (i386_immediate): Remove unused label
+ seg_unimplemented.
+
+ * struc-symbol.h: Put local_symbol code in ifdef BFD_ASSEMBLER.
+ * symbols.c: Likewise.
+ * config/obj-aout.c (obj_crawl_symbol_chain): Refer directly to
+ sy_next field when taking address, rather than symbol_next.
+
+ * dwarf2dbg.c: Change bfd_vma to addressT and bfd_signed_vma to
+ offsetT.
+ (out_set_addr): Don't use BYTES_PER_ADDRESS. Instead, get the
+ value from the output file architecture.
+ (dwarf2_gen_line_info): Ifdef BFD_ASSEMBLER specific code.
+ * dwarf2dbg.h: Change bfd_vma to addressT.
+
+1999-06-11 Ian Lance Taylor <ian@zembu.com>
+
+ * dwarf2dbg.h: Use PARAMS in function declarations.
+
+1999-06-11 Martin Dorey <mdorey@madge.com>
+
+ * write.c (fixup_segment): Don't add symbol value for i960 ELF.
+ * config/tc-i960.c (s_leafproc): Don't call tc_set_bal_of_cal if
+ OBJ_ELF.
+ (md_apply_fix): Simplify BFD_ASSEMBLER handling.
+
+1999-06-11 Ian Lance Taylor <ian@zembu.com>
+
+ * config/tc-i386.c (md_apply_fix3): Add default case to switch.
+
+ * config/tc-sparc.c (md_pseudo_table): Remove pushsection and
+ popsection.
+
+ * config/tc-sparc.c (sparc_ip): Add default case to reloc switch.
+
+ * read.c (read_a_source_file): Only declare inescape if
+ QUOTES_IN_INSN.
+
+ * itbl-ops.c (itbl_disassemble): Change sprintf format strings to
+ match parameters.
+ (find_entry_byval): Add parens to avoid warning.
+
+ * as.c: If HAVE_ITBL_CPU, include "itbl-ops.h".
+
+ * symbols.c (resolve_symbol_value): Don't permit subtraction of
+ undefined symbols.
+
+1999-06-10 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * config/tc-sparc.c (sparc_ip): Don't use side-effect expression
+ with isoctal.
+
+ * config/tc-sparc.c (synthetize_setuw, synthetize_setsw,
+ synthetize_setx): New functions.
+ (md_assemble): Broken the special cases into the above
+ functions. Make compiler happy if sizeof(bfd_vma)==4.
+ Fix sethi generated from set/setuw. If instructions have a relloc,
+ always clear the fields to be relocated in the opcode.
+ (sparc_ip): Remove special_case global variable.
+
+1999-06-10 Ian Lance Taylor <ian@zembu.com>
+
+ Based on patches from John W. Woznack <jwoznack@concentric.net>:
+ * itbl-ops.c (itbl_get_reg_val): Add pval parameter. Return
+ indication of success rather than a value.
+ (itbl_get_val): Likewise.
+ (itbl_get_field): Use strcspn. Change delimiters to include
+ parens.
+ * itbl-ops.h (itbl_get_reg_val): Update declaration.
+ (itbl_get_val): Likewise.
+ * config/tc-mips.c (mips_ip): Update call to itbl_get_reg_val.
+
+ * symbols.c (copy_symbol_attributes): Convert local symbols to
+ regular symbols.
+
+1999-06-10 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_parse_option): Add support for ARM920 and
+ ARM920t.
+
+1999-06-07 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * config/tc-sparc.c (md_assemble): Fix up setx, support setsw.
+ Optimize set if sizeof(bfd_vma) == 64.
+ (sparc_ip): Fix sethi - without %hi() it should generate
+ R_SPARC_22 reloc, not R_SPARC_HI22.
+ (tc_gen_reloc): Handle BFD_RELOC_SPARC22.
+
+1999-06-07 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * config/tc-sparc.c (md_begin): Handle native wordsize aliases.
+ (s_ncons): New function.
+ (native_op_table): New table.
+ (sparc_ip): Be more strict on %hi() etc.; prepare assembler for
+ R_SPARC_OLO10 handling.
+
+Mon Jun 7 10:22:16 1999 Richard Henderson <rth@cygnus.com>
+
+ * expr.h (struct expressionS): Revert last change; widen X_op.
+ * config/tc-alpha.c (md_begin): Check the field is wide enough.
+
+Mon Jun 7 11:25:16 1999 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * Makefile.am (TARGET_CPU_CFILES): Add config/tc-fr30.c.
+ (TARGET_CPU_HFILES): Add config/tc-fr30.h.
+ (TARG_ENV_HFILES): Add config/te-epoc-pe.h.
+ * Makefile.in: Regenerated.
+
+ * config/obj-elf.c (obj_elf_common): In MRI mode if called as
+ `common' pass on to s_mri_common.
+ (elf_pseudo_table): Pass 1 to obj_elf_common for `common'.
+
+1999-06-06 Richard Henderson <rth@cygnus.com>
+
+ * config/obj-elf.c (obj_elf_section): Don't free the return
+ value of demand_copy_C_string.
+
+1999-06-05 Richard Henderson <rth@cygnus.com>
+
+ * dwarf2dbg.c (dwarf2_gen_line_info): Mirror the section symbol
+ creation logic from obj_elf_create_section.
+
+ * config/obj-elf.c (elf_pseudo_tab): Add pushsection/popsection.
+ (section_stack): New.
+ (special_sections): Make const.
+ (obj_elf_section): Gut and rewrite parsing.
+ (obj_elf_change_section): New function broken out of obj_elf_section.
+ (obj_elf_parse_section_letters): Likewise.
+ (obj_elf_section_word): Likewise.
+ (obj_elf_section_type): Likewise.
+ (obj_elf_previous): Treat as a toggle.
+ (obj_elf_popsection): New.
+ * config/tc-ppc.c (ppc_section_word): Take str+len not ptr_str.
+ (ppc_section_type): Likewise.
+ * config/tc-ppc.h: Likewise.
+
+ * expr.h (struct expressionS): Don't make X_op a bitfield.
+ * config/tc-alpha.c: Update for symbol handling changes.
+ (md_apply_fix) [case GPREL]: Use now_seg instead of absolute_section.
+ (load_expression, emit_ir_load, emit_loadstore, emit_jsrjmp): Likewise.
+
+1999-06-05 Richard Henderson <rth@cygnus.com>
+
+ * dwarf2dbg.c (*): Convert to K&R + prototypes.
+ (dwarf2_gen_line_info): Kill unused variables.
+ (dwarf2_finish): Likewise.
+ (dwarf2_where): Likewise.
+ (dwarf2_directive_file): If we've only got a string,
+ hand off to s_app_file.
+ * ecoff.c: Move the include of ecoff.h.
+ * symbols.h (S_IS_FUNCTION): Prototype.
+
+ * read.c (LEX_HASH): Supply a default.
+ (lex_type): Use it.
+ (s_globl): Update `c' after skipping whitespace.
+ * read.h (LEX_END_NAME, is_name_ender): New.
+ * expr.c (get_symbol_end): Respect it.
+
+1999-06-04 Mark Klein <mklein@dis.com>
+
+ * config/tc-hppa.c (md_begin): Convert local symbol dummy_symbol
+ to real if OBJ_SOM
+ (tc_gen_reloc): Still need bfd_abs_symbol in some relocs.
+
+ * config/tc-hppa.c: Update for symbol handling changes.
+
+1999-06-03 Ian Lance Taylor <ian@zembu.com>
+
+ * cgen.c: Update for symbol handling changes.
+ * config/tc-m32r.c: Likewise.
+
+ * config/tc-hppa.h: Update for symbol handling changes.
+ * config/tc-hppa.c: Likewise.
+
+ * config/tc-arm.h: Update for symbol handling changes.
+ * config/tc-arm.c: Likewise.
+ (symbol_make_empty): Remove. Just use symbol_create.
+
+ * symbols.c (symbol_set_tc): Correct name.
+
+ * Makefile.am: Rebuild dependencies.
+ ($(OBJS)): Don't depend upon struc-symbol.h.
+ (.dep1, .tcdep, .objdep): Create itbl-parse.h.
+ * dep-in.sed: Don't remove struc-symbol.h.
+ * Makefile.in: Rebuild.
+
+ * doc/internals.texi (Symbols): Describe changes in symbol
+ handling.
+
+1999-06-03 Richard Henderson <rth@cygnus.com>
+
+ * dwarf2dbg.c (dwarf2_gen_line_info): Use section_symbol
+ instead of doing the work by hand.
+
+1999-06-03 David Mosberger <davidm@hpl.hp.com>
+
+ * dwarf2dbg.c (INITIAL_STATE): New macro encapsulating initial
+ state of line state-machine.
+ (struct ls): Collect DWARF2 line state-machine state in new member
+ SM. Add member EMPTY_SEQUENCE to keep track if a code sequence
+ resulted in any DWARF2 directives.
+ (reset_state_machine): New function.
+ (out_end_sequence): Ditto.
+ (dwarf2_gen_line_info): When switching sections or switching to a
+ lower text address, call out_end_sequence() first to terminate the
+ previous code sequence as code sequences MUST have monotonically
+ increasing addresses.
+ (dwarf2_finish): Call out_end_sequence() instead of open coding it.
+
+1999-06-03 David Mosberger <davidm@hpl.hp.com>
+
+ * as.c (parse_args): Add option -gdwarf2 to allow requesting
+ DWARF2 debug info (line information only, at this point).
+ * as.h: Update comment about supported debug formats.
+ * dwarf2dbg.c, dwarf2dbg.h: New files.
+ * Makefile.am (GAS_CFILES, HFILES, GENERIC_OBJS): Add them.
+
+ * expr.c (operand): Don't use [ for parens if we want an index op.
+ (op_encoding): Switch [ into O_index, if desired.
+ (op_rank): Renumber with O_index on bottom.
+ (expr): If O_index, match closing bracket.
+ * expr.h (O_index): New.
+
+ * read.c (read_a_source_file): Conditionally allow matched "
+ in lines passed to md_assemble.
+
+ * config/obj-elf.c (elf_pseudo_table): Add `common'.
+
+1999-06-03 Ian Lance Taylor <ian@zembu.com>
+
+ Add support for storing local symbols in a small structure to save
+ memory when assembling large files.
+ * as.h: Don't include struc-symbol.h.
+ (symbolS): Add typedef.
+ * symbols.c: Include struc-symbol.h.
+ (local_hash): New static variable.
+ (save_symbol_name): New static function, from symbol_create.
+ (symbol_create): Call save_symbol_name.
+ (local_symbol_count): New static variable.
+ (local_symbol_conversion_count): Likewise.
+ (LOCAL_SYMBOL_CHECK): Define.
+ (local_symbol_make): New static function.
+ (local_symbol_convert): New static function.
+ (colon): Handle local symbols. Create local symbol for local
+ label name.
+ (symbol_table_insert): Handle local symbols.
+ (symbol_find_or_make): Create local symbol for local label name.
+ (symbol_find_base): Check for local symbol.
+ (symbol_append, symbol_insert): Check for local symbols.
+ (symbol_clear_list_pointers, symbol_remove): Likewise.
+ (verify_symbol_chain): Likewise.
+ (copy_symbol_attributes): Likewise.
+ (resolve_symbol_value): Handle local symbols.
+ (resolve_local_symbol): New static function.
+ (resolve_local_symbol_values): New function.
+ (S_GET_VALUE, S_SET_VALUE): Handle local symbols.
+ (S_IS_FUNCTION, S_IS_EXTERNAL, S_IS_WEAK, S_IS_COMMON): Likewise.
+ (S_IS_DEFINED, S_IS_DEBUG, S_IS_LOCAL, S_GET_NAME): Likewise.
+ (S_GET_SEGMENT, S_SET_SEGMENT, S_SET_EXTERNAL): Likewise.
+ (S_CLEAR_EXTERNAL, S_SET_WEAK, S_SET_NAME): Likewise.
+ (symbol_previous, symbol_next): New functions.
+ (symbol_get_value_expression): Likewise.
+ (symbol_set_value_expression): Likewise.
+ (symbol_set_frag, symbol_get_frag): Likewise.
+ (symbol_mark_used, symbol_clear_used, symbol_used_p): Likewise.
+ (symbol_mark_used_in_reloc): Likewise.
+ (symbol_clear_used_in_reloc, symbol_used_in_reloc_p): Likewise.
+ (symbol_mark_mri_common, symbol_clear_mri_common): Likewise.
+ (symbol_mri_common_p): Likewise.
+ (symbol_mark_written, symbol_clear_written): Likewise.
+ (symbol_written_p): Likewise.
+ (symbol_mark_resolved, symbol_resolved_p): Likewise.
+ (symbol_section_p, symbol_equated_p): Likewise.
+ (symbol_constant_p): Likewise.
+ (symbol_get_bfdsym, symbol_set_bfdsym): Likewise.
+ (symbol_get_obj, symbol_set_obj): Likewise.
+ (symbol_get_tc, symbol_set_tc): Likewise.
+ (symbol_begin): Initialize local_hash.
+ (print_symbol_value_1): Handle local symbols.
+ (symbol_print_statistics): Print local symbol statistics.
+ * symbols.h: Include "struc-symbol.h" if not BFD_ASSEMBLER.
+ Declare new symbols.c functions. Move many declarations here from
+ struc-symbol.h.
+ (SYMBOLS_NEED_BACKPOINTERS): Define if needed.
+ * struc-symbol.h (SYMBOLS_NEED_BACKPOINTERS): Don't set.
+ (struct symbol): Move bsym to make it clearly the first field.
+ Remove TARGET_SYMBOL_FIELDS.
+ (symbolS): Don't typedef.
+ (struct broken_word): Remove.
+ (N_TYPE_seg, seg_N_TYPE): Move to symbol.h.
+ (SEGMENT_TO_SYMBOL_TYPE, N_REGISTER): Likewise.
+ (symbol_clear_list_pointers): Likewise.
+ (symbol_insert, symbol_remove): Likewise.
+ (symbol_previous, symbol_append): Likewise.
+ (verify_symbol_chain, verify_symbol_chain_2): Likewise.
+ (struct local_symbol): Define.
+ (local_symbol_converted_p, local_symbol_mark_converted): Define.
+ (local_symbol_resolved_p, local_symbol_mark_resolved): Define.
+ (local_symbol_get_frag, local_symbol_set_frag): Define.
+ (local_symbol_get_real_symbol): Define.
+ (local_symbol_set_real_symbol): Define.
+ Define.
+ * write.c (write_object_file): Call resolve_local_symbol_values.
+ * config/obj-ecoff.h (OBJ_SYMFIELD_TYPE): Define.
+ (TARGET_SYMBOL_FIELDS): Don't define.
+ * config/obj-elf.h (OBJ_SYMFIELD_TYPE): Add local field. If
+ ECOFF_DEBUGGING, add ECOFF fields.
+ (ELF_TARGET_SYMBOL_FIELDS, TARGET_SYMBOL_FIELDS): Don't define.
+ * config/obj-multi.h (struct elf_obj_sy): Add local field. If
+ ECOFF_DEBUGGING, add ECOFF fields.
+ (ELF_TARGET_SYMBOL_FIELDS, TARGET_SYMBOL_FIELDS): Don't define.
+ (ECOFF_DEBUG_TARGET_SYMBOL_FIELDS): Don't define.
+ * config/tc-mcore.h: Don't include struc-symbol.h.
+ (TARGET_SYMBOL_FIELDS): Don't define.
+ (struct mcore_tc_sy): Define.
+ (TC_SYMFIELD_TYPE): Define.
+ * Many files: Use symbolS instead of struct symbol. Use new
+ accessor functions rather than referring to symbolS fields
+ directly.
+
+ * read.c (s_mri_common): Don't add in value of line_label.
+
+ * config/tc-mips.c (md_apply_fix): Correct parenthesization when
+ checking for SEC_LINK_ONCE.
+
+ * config/tc-sh.h (sh_fix_adjustable): Declare.
+
+ * app.c (input_buffer): New static variable.
+ (app_push): Save saved_input in allocated buffer.
+ (app_pop): Restored saved_input.
+ (do_scrub_chars): Change get parameter to take char * and int as
+ arguments. Change GET macro to pass input_buffer to get
+ function. Don't save input into allocated buffer.
+ * as.h (do_scrub_chars): Update declaration.
+ * input-file.c (input_file_get): Change to take char * and int.
+ Read data into passed in buffer. Remove static buffer.
+ * read.c (scrub_from_string): Change to take char * and int. Copy
+ data into passed in buffer.
+
+ * hash.h: Neaten. Declare hash_traverse.
+ * hash.c: Complete rewrite based on BFD hashing code.
+ * gasp.c (chunksize): New variable.
+ * macro.c (macro_expand_body): Call hash_jam with NULL rather than
+ hash_delete.
+
+1999-05-28 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_apply_fix3): Add pipeline offset into reloc
+ addend unless the target uses an old ABI.
+
+Mon May 24 13:36:55 1999 Doug Evans <devans@canuck.cygnus.com>
+
+ -Wchar-subscripts cleanup
+ * listing.c (listing_newline): Use unsigned char variable, so
+ calls to isascii,iscntrl are correct.
+ * atof-generic.c (atof_generic): Cast arg to isdigit, et. al. with
+ (unsigned char).
+ * ecoff.c (ecoff_directive_ent,ecoff_stab): Ditto.
+ * config/obj-elf.c (obj_elf_vtable_inherit): Ditto.
+ * config/tc-mips.c (mips_ip,mips16_ip): Ditto.
+ (my_getSmallExpression,get_number,s_mips_ent): Ditto.
+
+1999-05-28 Torbjorn Granlund <tege@matematik.su.se>
+
+ * config/tc-m68k.c (m68k_ip): Check for disallowed index register
+ width for Coldfire.
+ (arch_coldfire_p): New #define.
+ (m68k_ip, m68k_init_after_args): Use arch_coldfire_p.
+
+1999-05-28 Linus Nordberg <linus.nordberg@canit.se>
+
+ * config/tc-m68k.c (install_operand): Add places `n', `o'.
+
+ * config/tc-m68k.c (m68k_ip): Add formats `E', `G', `H'.
+ (install_operand): Add place `N'.
+ (init_table): Add registers ACC, MACSR, MASK.
+
+ * config/m68k-parse.h (m68k_register): Add ACC, MACSR, MASK.
+
+ * config/tc-m68k.c: Change mcf5200 --> mcf.
+ (archs): Add mcf5206e, mcf5307.
+ (m68k_ip): Add format `u'.
+ (install_operand): Add place `m', `M', `h'.
+ (init_table): Add upper/lower registers.
+
+ * config/m68k-parse.h (m68k_register): Add upper/lower registers.
+
+1999-05-28 Martin Dorey <mdorey@madge.com>
+
+ * config/tc-i960.c: Several minor changes to add ELF and
+ BFD_ASSEMBLER support.
+ * config/tc-i960.h: Likewise.
+ * configure.in (i960-*-elf*): New target.
+ * aclocal.m4, configure: Rebuild.
+
+1999-05-25 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (md_apply_fix3): Only do 1999-05-17 fx_pcrel
+ reloc changes when defined(BFD_ASSEMBLER).
+
+1999-05-17 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (tc_gen_reloc): Remove F and MAP macros.
+
+ * write.c (write_print_statistics): Output to file, not stderr.
+
+ * expr.c (generic_bignum_to_int32,64): Prototype.
+
+ * read.c (s_lcomm_internal, sizeof_sleb128, sizeof_uleb128,
+ output_sleb128, output_uleb128, output_big_sleb128,
+ output_big_uleb128, output_big_leb128): Prototype.
+ (output_big_sleb128, output_big_uleb128): Make inline.
+ (output_big_leb128): Remove inline
+
+ From Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+ * config/tc-i386.c (md_apply_fix3): Convert BFD_RELOC_16 with
+ fx_pcrel set to BFD_RELOC_16_PCREL. Similarly for BFD_RELOC_8.
+ Handle BFD_RELOC_16_PCREL and BFD_RELOC_8_PCREL. Return changed
+ value for correct overflow check in write.c:fixup_segment.
+ * write.c (fixup_segment): Move bitfield overflow checks to after
+ the md_apply_fix call.
+ * config/obj-coff.c (fixup_segment): Likewise.
+ * doc/internals.texi (CPU backend): Mention md_apply_fix modifying
+ valueT *val argument.
+
+Fri May 14 10:52:13 1999 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * config/atof-ieee.c (gen_to_words): Correctly round a
+ denormalized number. Fix off-by-one in range checking for
+ exponent in a denormal.
+
+1999-05-10 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.c (parse_reg): Accept 'sp' as a valid register
+ name.
+
+Thu May 13 09:46:59 1999 Joel Sherrill (joel@OARcorp.com)
+
+ * configure.in (i386-*-rtemself*, sh-*-rtemself*): New targets.
+
+1999-05-12 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.h (InvMem): New flag. Add to AnyMem.
+ (ReverseRegRegmem): Remove.
+ (ImmExt): New flag. Renumber some of the opcode_modifier bits.
+ * config/tc-i386.c (md_assemble): Test for PIII SIMD and AMD
+ 3DNow! via ImmExt opcode_modifier. Remove ReverseRegRegmem
+ kludge.
+
+ From Doug Ledford <dledford@redhat.com>
+ * config/tc-i386.h (RegXMM): New for P/III.
+ * config/tc-i386.c: Add support for P/III.
+
+Sat May 8 23:28:50 1999 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-ppc.c (md_parse_option): Recognize -mppc64bridge.
+ (md_begin): Allow ppc32 insns in ppc64bridge mode.
+ (ppc_insert_operand): Accept SIGNOPT in ppc64 mode.
+
+Thu May 6 23:13:39 1999 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-i386.c (i386_immediate): Skip whitespace before
+ complaining about junk after expression.
+ (i386_displacement): Likewise.
+
+Thu May 6 19:50:14 1999 Richard Henderson <rth@cygnus.com>
+
+ * symbols.c (symbol_find_base): Use memcpy instead of strcpy.
+ Don't copy before downcaseing.
+
+1999-05-05 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-m68k.c: Include elf/m68k.h.
+ (m68k_elf_final_processing): New routine.
+ * config/tc-m68k.h (elf_tc_final_processing m68k_elf_final_processing):
+ Define.
+
+Mon May 3 10:26:03 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (md_apply_fix): Handle 22 bit fmt insn like a
+ 17 bit fmt insn.
+
+1999-04-30 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.c (mcore_s_section): Dump literals before
+ changing section.
+
+1999-04-29 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.c (md_apply_fix3): Insert reloc addend into insn
+ for COFF/PE port.
+
+Mon Apr 26 12:34:37 1999 Doug Evans <devans@canuck.cygnus.com>
+
+ * config/tc-fr30.h (TC_FIX_TYPE): Delete, cgen fields moved to write.h.
+ (TC_INIT_FIX_DATA): Delete.
+ * config/tc-m32r.h (TC_FIX_TYPE): Delete, cgen fields moved to write.h.
+ (TC_INIT_FIX_DATA): Delete.
+ * write.h (struct fix): New member fx_cgen, ifdef USING_CGEN.
+ * write.c (fix_new_internal): Initialize fx_cgen member.
+ * cgen.c (gas_cgen_record_fixup,gas_cgen_record_fixup_exp): Update.
+ (gas_cgen_md_apply_fix3): Update.
+ * config/tc-m32r.c (md_cgen_lookup_reloc): Update.
+ (md_cgen_record_fixup_exp): Update.
+ (FX_OPINFO_R_TYPE): Update.
+
+ * frags.c (frag_var,frag_variant): Initialize fr_cgen here.
+ * config/tc-fr30.h (TC_FRAG_INIT): Delete.
+ * config/tc-m32r.h (TC_FRAG_INIT): Delete.
+ * frags.h (struct frag): Make opindex, opinfo ints.
+
+ * config/tc-fr30.c (FX_OPINFO_R_TYPE): Delete, unused.
+
+1999-04-26 Tom Tromey <tromey@cygnus.com>
+
+ * aclocal.m4, configure: Updated for new version of libtool.
+
+1999-04-22 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.c (md_apply_fix3): Renamed function from
+ md_apply_fix.
+ (md_apply_fix3): Do not fix up absolute relocations against
+ symbolic values.
+
+ * config/tc-mcore.h (MD_APPLY_FIX3): Define.
+
+1999-04-20 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.c (md_pseudo_table): Add intercepts for section
+ changes and data-in-text directives.
+ (mcore_cons): New function: intercept cons() operations.
+ (mcore_float_cons): New function: intercept float_cons()
+ operations.
+ (mcore_stringer): New function: intercept stringer() operations.
+
+1999-04-18 Ian Lance Taylor <ian@zembu.com>
+
+ * obj.h (struct format_ops): Change generate_asm_lineno field to
+ take no parameters.
+ * config/obj-ecoff.h (OBJ_GENERATE_ASM_LINENO): Don't define.
+
+ * config/tc-alpha.c (find_opcode_match): Add default case to
+ switch.
+ (find_macro_match): Likewise.
+ (load_expression): Parenthesize && within ||.
+
+ * config/tc-alpha.h (TC_RELOC_RTSYM_LOC_FIXUP): Define.
+
+1999-04-17 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.c (md_pseudo_table): Add overrides for .bss
+ .text .data .section pseudo ops.
+ (mcore_s_section): New function. Dump lits before changing secs.
+ (mcore_s_text): New function. Dump lits before changing secs.
+ (mcore_s_data): New function. Dump lits before changing secs.
+
+1999-04-16 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (mips_32bitmode): New.
+ (md_begin): Set mips_32bitmode if needed.
+ (mips_elf_final_processing): Don't set EF_MIPS_ARCH.
+ Set EF_MIPS_32BITMODE.
+
+Fri Apr 16 12:26:39 1999 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/obj-coff.c (c_section_symbol): Fix typo in previous
+ change.
+
+1999-04-16 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.h (LOCAL_LABELS_FB): Define to 1.
+
+Thu Apr 15 16:52:09 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_get_absolute_exression): Try to handle "5 %r3"
+ expressions correctly.
+
+
+1999-04-15 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (mips_elf_final_processing): Set EF_MIPS_ARCH.
+
+Mon Apr 12 23:45:07 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_ip, case '3'): New case for PA2.0 fmpyfadd
+ and fmpynfadd instructions.
+
+1999-04-11 Richard Henderson <rth@cygnus.com>
+
+ * as.h (environ): Declare it, if needed.
+ * as.c (dump_statistics): Don't declare environ.
+ * configure.in (environ): Detect declaration.
+ * configure, config.in: Rebuild
+
+ * config/tc-i386.c (i386_immediate): Accept @GOT relocations.
+ (i386_displacement): Allocate enough space for replacement buffer.
+ Clean up replacement buffer initialization.
+
+1999-04-11 Bob Manson <manson@charmed.cygnus.com>:
+
+ * subsegs.c (section_symbol): Don't create a new symbol if one
+ already exists; instead, use the existing one, but set its segment
+ and frag data if it hasn't already been defined.
+ * config/obj-coff.c (c_section_symbol): Likewise.
+
+Sat Apr 10 20:10:02 1999 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (load_expression): Call as_bad instead of abort.
+
+1999-04-08 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.c: New File: Support routines for MCore
+ assembler.
+ * config/tc-mcore.h: New File: Definitions for MCore assembler.
+ * config/obj-coff.c: Add support for mcore-pe target.
+
+ * Makefile.am: Add support for MCore targets.
+ * Makefile.in: Regenerate.
+ * configure.in: Add support for MCore targets.
+ * configure: Regenerate.
+
+ * doc/all.texi: Set MCORE.
+ * doc/as.texinfo: Document MCore specific command line options.
+
+ * write.h: Prevent multiple inclusion.
+
+1999-04-06 Ian Lance Taylor <ian@zembu.com>
+
+ * asintl.h (LC_MESSAGES): Never define.
+ * as.c (main): Don't pass LC_MESSAGES to setlocale if the system
+ does not define it.
+ * gasp.c (main): Don't pass LC_MESSAGES to setlocale if the system
+ does not define it.
+
+ * Makefile.am (m68k-parse.c): If configuring in the source
+ directory, copy m68k-parse.y into the local directory before
+ running ylwrap, to remove spurious differences when generating
+ snapshots.
+ * Makefile.in: Rebuild.
+
+ * config/tc-sparc.h (md_do_align): Just allocate the number of
+ bytes necessary, rather than always allocating 1024.
+
+1999-04-04 Ian Lance Taylor <ian@zembu.com>
+
+ * listing.c (listing_newline): Add cast to avoid warning.
+ * read.c (generate_lineno_debug): Add cases to switch. Reindent.
+ * config/tc-i386.c (i386_scale): Add return value.
+ (build_displacement_string): Remove unused local temp_disp2.
+ (i386_intel_memory_operand): Add parentheses to avoid warning.
+ (i386_intel_operand): Remove unused local end_of_operand_string.
+ (i386_operand): Remove unused local operand_modifier.
+ (i386_operand): Add parens to avoid warning.
+
+1999-04-04 Don Bowman <don@pixsci.com>
+
+ * configure.in: Add mips*-*-vxworks* target; have it define
+ MIPS_STABS_ELF.
+ * configure, config.in: Rebuild.
+
+1999-03-31 Nick Clifton <nickc@cygnus.com>
+
+ * configure.in (emulations): Add support for arm-epoc-pe.
+ * configure: Regenerate.
+ * config/te-epoc-pe.h: New file. Define macros specific to
+ arm-epoc-pe target.
+ * config/tc-arm.h: Select epoc-pe-arm target format if configured
+ for arm-epoc-pe target.
+
+Mon Mar 29 10:15:40 CST 1999 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-mips.c (md_apply_fix): Adjust value for linkonce sections.
+
+Wed Mar 24 14:11:10 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_parse_nonneg_cmpsub_cmpltr): Clean up code to
+ detect ",n" without a condition.
+ (pa_parse_neg_cmpsub_cmpltr): Likewise.
+
+
+Tue Mar 23 11:28:23 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_ip, case '~'): The condition for a branch on bit
+ instruction is encoded with one bit.
+
+
+1999-03-23 Ian Lance Taylor <ian@zembu.com>
+
+ * doc/internals.texi (CPU backend): Mention that
+ line_separator_chars should not include newline. From thi
+ <ttn@mingle.glug.org>.
+
+1999-03-22 Doug Evans <devans@casey.cygnus.com>
+
+ * config/tc-fr30.c (md_begin): Update call to fr30_cgen_cpu_open.
+ * config/tc-m32r.c (md_begin): Update call to m32r_cgen_cpu_open.
+
+Sun Mar 21 18:08:18 1999 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (md_assemble): Allow '6' in an opcode.
+
+Thu Mar 18 10:55:30 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_ip, case 'a'): Do not call pa_parse_..._cmpsub_cmpltr.
+
+
+Thu Mar 18 02:30:07 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_ip, case 'd'): Do not allow ",n".
+
+1999-03-15 Martin Hunt <hunt@cygnus.com>
+
+ * app.c (do_scrub_begin): Change '-' back to a symbol char
+ so we can use multiple opcodes on a line again.
+
+ * config/tc-d30v.c: By default, warn if a symbol has
+ the same name as a register. Plus some minor
+ updates from the branch.
+
+1999-03-13 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_apply_fix3): Handle BFD_RELOC_8,
+ BFD_RELOC_16 and BFD_RELOC_64.
+
+1999-03-12 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * expr.c (expr): Add missing else.
+
+1999-03-12 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_apply_fix3): Improve error message.
+
+1999-03-11 Doug Evans <devans@casey.cygnus.com>
+
+ * Makefile.am (CPU_TYPES): Add fr30.
+ (cgen.o): Add $(CGEN_CPU_PREFIX)-desc.h dependency.
+ (fr30,m32r dependencies): Update.
+ * Makefile.in: Rebuild.
+
+ * cgen.c (gas_cgen_record_fixup): Update use of operand->type.
+ (gas_cgen_record_fixup_exp): Ditto.
+ (gas_cgen_finish_insn): Call cgen_operand_lookup_by_num.
+ (gas_cgen_md_apply_fix3): Ditto. Update call to set_vma_operand.
+ * config/tc-fr30.c (md_begin): Update call to fr30_cgen_cpu_open.
+ (md_cgen_lookup_reloc): Update use of operand->type.
+ * config/tc-m32r.c (md_begin): Update call to fr30_cgen_cpu_open.
+ (md_convert_frag): Call cgen_operand_lookup_by_num.
+ (md_cgen_lookup_reloc): Update use of operand->type.
+ (m32r_cgen_record_fixup_exp): Ditto.
+
+1999-03-09 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * config/tc-mips.c (md_show_usage): Fix message.
+
+1999-03-03 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-arm.texi (ARM Syntax): Document new command line switches
+ and LDR reg,=<expr> instruction.
+
+ * config/tc-arm.c: Add support for -mcpu=arm810, -mcpu=arm9 and
+ -mcpu=arm9tdmi.
+
+Fri Feb 19 09:36:30 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/c-arm.texi (ARM-Chars): Fix typo in use of '@'.
+
+1999-02-17 Nick Clifton <nickc@cygnus.com>
+
+ This patch was created by: Scott Bambrough
+ <scottb@corelcomputer.com>
+
+ * app.c:
+ Special cased '@' character. The '@' character is used as the
+ ARM assembler comment character, as a special character
+ and in ELF .symver pseudo-op's, and as a special character in
+ .type and .section pseudo-ops.
+ (symver_pseudo): New static variable.
+ (symver_state): New static variable.
+ (struct app_save): Add field 'symver_state'.
+ (app_push): Save global symver_state int struct app_save.
+ (app_pop): Restore global symver_state from struct app_save.
+ (do_scrub_chars): Special case handling of '@' character in
+ .symver pseudo-ops.
+
+ * configure.in: Modified to recognize armv* uname syntax from ARM
+ Linux kernel.
+ * configure: Regenerated.
+
+ * config/obj-elf.c (obj_elf_section): Allow '%' as well as '@' as
+ a prefix to the section's type.
+ (obj_elf_type): Allow '%' as well as '@' and '#' as prefixes to
+ the type's typename.
+
+ * config/tc-arm.h: Add support for PIC generation:
+ (pic_code): New boolean.
+ (obj_relocate_extern): Define.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Define
+ (TC_CONS_FIX_NEW): Define.
+ (tc_fix_adjustable): Define.
+ (GLOBAL_OFFSET_TABLE_NAME): Define.
+
+ * config/tc-arm.c: Add support for PIC generation:
+ (line_seperator_chars): Allow ';' as a seperator for Linux.
+ (is_immediate_prefix): New macro.
+ (arm_parse_reloc): New function.
+ (s_arm_elf_cons): New function.
+ (do_branch): Special case for BFD_RELOC_ARM_PLT32.
+ (md_undefined_symbol): Special case handling for the Global Offset
+ Table's symbol.
+ (md_apply_fix3): Handle PIC relocs.
+ (tc_gen_reloc): Handle PIC relocs.
+ (md_parse_option): Add support for '-k' command line switch to
+ enable PIC generation.
+ (cons_fix_new_arm): New function.
+ (s_arm_elf_cons): New function.
+
+Tue Feb 16 16:31:53 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add comments for uses of AC_DEFINE.
+ * acinclude.m4: Likewise.
+ * acconfig.h: Remove.
+ * aclocal.m4: Rebuild.
+ * configure: Rebuild.
+ * Makefile.in: Rebuild.
+ * config.in: Rebuild.
+
+1999-02-15 Jim Lemke <jlemke@cygnus.com>
+
+ * config/tc-mips.c (mips_ip: case 'o'): Fix assertion failure for
+ non-constant offset from a base register.
+
+1999-02-14 Ken Raeburn <raeburn@raeburn.org>
+
+ * config/tc-alpha.c (md_show_usage): Put \ before newline in
+ strings always.
+
+Sat Feb 13 14:10:10 1999 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (cpu_types): Enable EV6 PALcode with -m21264.
+ (emit_insn): Look for pc-relative and no-overflow specifiers on
+ internal relocation types.
+
+1999-02-13 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * doc/c-mips.texi (MIPS Opts): Updated list of -mNNNN and
+ -mcpu=NNNN flags.
+
+ * config/tc-mips.c: Remove all the mips_NNNN variables; just use
+ mips_cpu instead.
+ (mips_4650, mips_4010, mips_4100): Variables removed.
+ (hilo_interlocks, gpr_interlocks, append_insn, macro_build, macro,
+ macro2, mips16_macro, mips_ip): Test mips_cpu, not the mips_NNNN
+ variables.
+ (md_begin): Don't bother initializing the mips_NNNN variables;
+ mips_cpu is set, and that's good enough now.
+ (md_parse_option): Have the -mNNNN options set mips_cpu instead of
+ the mips_NNNN variable. The -no-mNNNN flags are now no-ops.
+ (show): New function, to handle wrapping in the CPU lists.
+ (md_show_usage): Update lists of -mcpu and -mNNNN switches.
+
+Sat Feb 13 00:17:26 1999 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-i386.c (i386_intel_operand): Ignore `SHORT' rather
+ than treat as an immediate specifier.
+
+Thu Feb 11 16:18:31 1999 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-i386.c: Prototype many functions.
+ (set_intel_syntax): Accept `prefix'/`noprefix' specifiers.
+ (i386_immediate): Remove unused second argument.
+ (i386_intel_operand): Fix i386_is_reg typo.
+ (i386_operand): Use allow_naked_reg.
+ (output_invalid): Make operand int for K&R.
+
+Thu Feb 11 11:21:02 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (EXTRA_as_new_SOURCES): Uncomment--fixed by automake
+ patch.
+ * Makefile.in: Rebuild.
+
+1999-02-09 Doug Evans <devans@casey.cygnus.com>
+
+ * Makefile.am (DISTCLEANFILES): Change cgen-opc.h to cgen-desc.h.
+ (cgen.o): Ditto.
+ (EXTRA_as_new_SOURCES): Comment out.
+ (.tcdep): <arch>-opc.h renamed to <arch>-desc.h.
+ * Makefile.in: Rebuild.
+ * doc/Makefile.in: Rebuild.
+ * configure.in: Require autoconf 2.13. Redo using_cgen handling.
+ Delete call to AM_CYGWIN32. Replace AM_EXEEXT with AC_EXEEXT.
+ (AC_OUTPUT): <arch>-opc.h renamed to <arch>-desc.h.
+ * configure: Rebuild.
+ * aclocal.m4: Rebuild.
+ * config.in: Rebuild.
+ * cgen.c: Include cgen-desc.h, not cgen-opc.h.
+ (*): CGEN_OPCODE_DESC renamed to CGEN_CPU_DESC.
+ (gas_cgen_cpu_desc): Renamed from gas_cgen_opcode_desc.
+ CGEN_INSN_ATTR renamed to CGEN_INSN_ATTR_VALUE.
+ CGEN_OPERAND_ATTR renamed to CGEN_OPERAND_ATTR_VALUE.
+ (gas_cgen_record_fixup): Remove unnecessary != 0 test.
+ (gas_cgen_record_fixup_exp): Ditto.
+ (gas_cgen_finish_insn): Ditto. Refer to operand table via cpu
+ descriptor, not global variable.
+ (gas_cgen_md_apply_fix3): Refer to operand_table via cpu
+ descriptor, not global variable. Refer to insert_operand handler
+ via cpu descriptor, not global function.
+ * cgen.h (*): CGEN_OPCODE_DESC renamed to CGEN_CPU_DESC.
+ * config/tc-fr30.c: Include opcodes/fr30-desc.h.
+ (*): gas_cgen_opcode_desc renamed to gas_cgen_cpu_desc.
+ CGEN_INSN_ATTR renamed to CGEN_INSN_ATTR_VALUE.
+ Update call to CGEN_OPERAND_TYPE,CGEN_INSN_OPERANDS.
+ * config/tc-m32r.c: Ditto.
+ (assemble_two_insns): Update calls to cgen_lookup_get_insn_operands.
+ (md_assemble): Ditto.
+ (md_convert_frag): Update call to CGEN_OPERAND_ENTRY.
+
+1999-02-09 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_apply_fix3): Fix handling of label1 - label2
+ relocations for ELF targets.
+
+1999-02-08 Nick Clifton <nickc@cygnus.com>
+
+ * configure.in: Add support for StrongARM target.
+ * configure: Regenerate.
+
+1999-02-05 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.h: Tidy OBJ_ELF and OBJ_COFF definitions.
+
+ * config/tc-arm.c (md_apply_fix3): Fix BFD_RELOC_ARM_PCREL_BRANCH
+ for COFF ports.
+
+Wed Feb 3 11:35:47 1999 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (md_show_usage): Document pca56 and ev6 options.
+
+Mon Feb 1 20:37:30 1999 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-i386.h (LONG_DOUBLE_MNEM_SUFFIX): Define.
+ (INTEL_DWORD_MNEM_SUFFIX): Define.
+ (BYTE_PTR): Define.
+ (WORD_PTR): Define.
+ (DWORD_PTR): Define.
+ (XWORD_PTR): Define.
+ (SHORT): Define.
+ (OFFSET_FLAT): Define.
+ (FLAT): Define.
+ (NONE_FOUND): Define.
+ (No_dSuf): Define.
+ (No_xSuf): Define.
+ * config/tc-i386.c (set_intel_syntax): New routine.
+ (intel_syntax): Declare.
+ (allow_naked_reg): Declare.
+ (md_pseudo_table): Support .intel_syntax and .att_syntax.
+ (intel_float_operand): New routine.
+ (md_assemble): Handle INTEL_DWORD_MNEM_SUFFIX.
+ Handle brackets as well as parens. Call i386_intel_operand for
+ intel syntax. Reverse operands if appropriate. Handle new
+ suffixes. Handle movzx and movsx.
+ (i386_is_reg): New routine.
+ (i386_immediate): New routine.
+ (i386_scale): New routine.
+ (i386_displacement): New routine.
+ (i386_operand_modifier): New routine.
+ (build_displacement_string): New routine.
+ (i386_parse_seg): New routine.
+ (i386_intel_memory_operand): New routine.
+ (i386_intel_operand): New routine.
+ (i386_operand): Call i386_displacement, i386_immediate,
+ i386_scale, etc. instead of handling inline.
+ (parse_register): Handle registers without prefix.
+
+Mon Feb 1 12:24:58 1999 Catherine Moore <clm@cygnus.com>
+
+ * configure: Regenerate.
+ * configure.in (arm-*-oabi): New.
+ (thumb-*-oabi): New.
+ * config/tc-arm.c (target_oabi): Declare.
+ (md_apply_fix3): Support REL relocs.
+ (md_parse_option): Handle -oabi.
+ (elf32_arm_target_format): New routine.
+ (md_longopts): Add OPTION_OABI.
+ * config/tc-arm.h: Redefine TARGET_FORMAT.
+
+
+1999-01-28 Nick Clifton <nickc@cygnus.com>
+
+ * write.c (write_relocs): Handle out of range error.
+
+ * config/tc-fr30.c (fr30_fix_adjustable): New function.
+ (fr30_force_relocation): Default to 0.
+
+ * config/tc-fr30.h (obj_fix_adjustable): Define.
+ (TC_FORCE_RELOCATION): Define.
+
+ * cgen.c (gas_cgen_md_apply_fix3): Do not apply fixes to VTABLE
+ relocs.
+
+1999-01-16 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (write_2_short): Do not generate a sequential
+ merge of two instructions if the left instruciton kills the right.
+
+1999-01-11 Doug Evans <devans@casey.cygnus.com>
+
+ * Makefile.in: Regenerate.
+ * configure.in: Redo test for using cgen.
+ * configure: Regenerate.
+
+1999-01-09 Nick Clifton <nickc@cygnus.com>
+
+ * config/obj-coff.h (obj_adjust_symtab): Prevent accidental
+ redefinition of this macro.
+
+Tue Jan 5 21:58:03 1999 Doug Evans <devans@canuck.cygnus.com>
+
+ * config/tc-mips.c (mips_frob_file): Disable "Unmatched %hi reloc"
+ warning.
+
+1998-12-29 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (append_insn): For mips16, insert a nop between
+ a read of HI or LO and an immediatly following branch.
+
+1998-12-29 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (md_begin): Another correction to the setting of
+ mips_eabi64.
+
+1998-12-23 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (md_begin): Correct type-o in setting of
+ mips_eabi64.
+
+1998-12-21 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c (md_assemble): Emit a NOP after a relaxable 16
+ bit insn when optimizing, so that parallelised instructions will
+ start on a 32 bit boundary.
+
+1998-12-19 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (mips_eabi64): New.
+ (md_begin): Set mips_eabi64.
+ (mips_elf_final_processing): Use it.
+
+1998-12-18 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (mips_elf_final_processing):
+ Correct setting of ABI in e_flags.
+
+Wed Dec 16 16:17:22 1998 Dave Brolley <brolley@cygnus.com>
+
+ * config/tc-fr30.c (md_assemble): Warn about invalid instructions
+ in delay slots.
+
+1998-12-16 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (md_begin,md_parse_option): Handle vr4111.
+
+1998-12-15 Doug Evans <devans@casey.cygnus.com>
+
+ * cgen.c (gas_cgen_md_apply_fix3): Mark as an error, rather than a
+ warning, values that don't fit in the field.
+
+1998-12-15 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (mips_abi_string): New.
+ (md_parse_option,md_longopts): Add mabi.
+ (mips_elf_final_processing): Set e_flags based on mabi flag.
+
+1998-12-15 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (md_parse_option): Handle vr4111.
+
+98-12-11 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/tc-h8300.c (build_bytes): Change message given if the
+ instruction requires H8/300H mode and we're not in Hmode, to
+ suggest that it may be the operand modes that are the problem, not
+ necessarily the opcode.
+
+1998-12-10 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.c: Add line separator character.
+
+Tue Dec 8 19:51:50 1998 Mark Klein <mklein@dis.com>
+
+ * configure.in (hppa-*-mpeix*): New target.
+ * config/obj-som.h (obj_som_compiler): Declare.
+ * config/obj-som.c (compiler_seen): New static variable.
+ (obj_som_compiler): New function.
+ * config/tc-hppa.c: Update tc_data uses for change to bfd/som.h.
+ (md_pseudo_table): Add "compiler" if OBJ_SOM.
+ (pa_type_args): Set hppa_priv_level.
+ (pa_compiler): New static function if OBJ_SOM.
+ * configure: Rebuild.
+
+Tue Dec 8 15:00:50 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (output_leb128): Don't mark as inline.
+
+1998-12-08 Andrew MacLeod <amacleod@cygnus.com>
+
+ * config/tc-ppc.c (ppc_vbyte): Prototype and new function for
+ AIX .vbyte unaligned data support.
+ (md_pseudo_table): Add 'vbyte' to list of valid pseudos.
+ (ppc_elf_validate_fix): Add eh_frame to list of ELF relocatable
+ sections.
+
+1998-12-07 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_assemble, do_assemble): Improve erroneous
+ input handling.
+
+Mon Dec 7 09:48:34 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-arm.c (elf32_arm_force_relocation): Check for
+ BFD_RELOC_ARM_PCREL_BRANCH.
+
+Sun Dec 6 12:46:36 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Define TARGET_BYTES_{BIG,LITTLE}_ENDIAN after
+ checking the target type.
+ (mips-dec-bsd*): Set endian to little.
+ * configure: Rebuild.
+
+ COFF weak symbol support, based on patches from Mark Elbrecht
+ <snowball3@usa.net>:
+ * config/obj-coff.h (S_IS_WEAK): Define if not BFD_ASSEMBLER.
+ * config/obj-coff.c (obj_coff_weak): New static function.
+ (obj_coff_endef) [both versions]: Handle weak symbols.
+ (coff_frob_symbol): Likewise.
+ (yank_symbols): Likewise.
+ (obj_pseudo_table): Add "weak".
+
+ * configure.in (m68k-*-gnu*): New target. From Aymeric Vincent
+ <aymeric.vincent@emi.u-bordeaux.fr>.
+ * aclocal.m4: Rebuild with current tools.
+ * configure: Rebuild.
+
+ * config/tc-alpha.c (emit_ldgp): Give an error message rather than
+ an assertion failure for a case we can't handle when OBJ_ECOFF.
+
+ * expr.c (operator): And with 0xff to avoid problems with signed
+ char.
+
+1998-12-03 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.c (md_cgen_lookup_reloc): Generate
+ BFD_RELOC_FR30_48 instead of BFD_RELOC_FR30_32.
+
+1998-12-02 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.c (md_cgen_lookup_reloc): Enable relocs for
+ LDI:20 insn.
+
+Thu Nov 26 11:23:48 1998 Dave Brolley <brolley@cygnus.com>
+
+ * config/tc-fr30.c (md_pcrel_from_section): Restore previous
+ calculation of pcrel point.
+
+Tue Nov 24 17:21:52 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.c (md_pcrel_from_section): Fix calculation of
+ pcrel point.
+
+Tue Nov 24 14:54:38 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d10v.c (md_assemble): Make static 'etype' have file
+ scope.
+ (d10v_cleanup): Only generate previous insn if a multiline insn is
+ not pending.
+
+Fri Nov 20 11:41:13 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.c (md_cgen_lookup_reloc): Add support for
+ FR30_OPERAND_I32.
+
+Thu Nov 19 15:01:29 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_parse_option): Add support for -marm7xxx and
+ -marm6xxx command line switches.
+
+1998-11-18 Doug Evans <devans@casey.cygnus.com>
+
+ * Makefile.am (DEP): Use $(srcdir)/../mkdep.
+ (itbl-ops.o): Delete duplicate dependencies.
+ Rebuild dependencies.
+ Add fr30 dependencies.
+ * Makefile.in: Rebuild.
+
+Tue Nov 17 13:42:42 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.c (md_cgen_lookup_reloc): Updated to match latest
+ opcode list.
+ * listing.c: Ignore line terminator characters found inside
+ strings.
+
+Thu Nov 12 19:21:24 1998 Dave Brolley <brolley@cygnus.com>
+
+ * po/gas.pot: Regenerated.
+
+Thu Nov 12 10:54:16 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.c (fr30_is_colon_insn): New name for
+ fr30_is_label_start(). Also checks for delay slot insns.
+
+ * config/tc-fr30.c (fr30_is_label_start): New function: Handle
+ FR30 instructions which contain a colon in the mnemonic.
+
+ * config/tc-fr30.h (TC_START_LABEL): Define this macro.
+
+Wed Nov 11 09:58:21 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.c: Removed currently superflous code.
+
+Tue Nov 10 13:13:05 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.h: New file.
+ * config/tc-fr30.c: Tweaking so that it will compile.
+
+Tue Nov 10 14:41:33 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-d10v.h (obj_fix_adjustable): Define.
+ (TC_FORCE_RELOCATION): Define.
+ (d10v_force_relocation): Declare.
+ * config/tc-d10v.c (tc_gen_reloc): Handle Vtable relocs.
+ (md_apply_fix3): Handle Vtable relocs.
+ (d10v_fix_adjustable): New.
+ (d10v_force_relocation): New.
+
+Mon Nov 9 14:25:06 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c: Change default behaviour to ignore potential
+ conflicts between register name and symbol names.
+
+Wed Nov 4 18:42:00 1998 Dave Brolley <brolley@cygnus.com>
+
+ * configure.in: Add fr30-*-*.
+ * config/tc-fr30.c: New file.
+ * Makefile.in: Regenerated.
+ * config.in: Regenerated.
+ * configure: Regenerated.
+ * doc/Makefile.in: Regenerated.
+ * po/gas.pot: Regenerated.
+
+Mon Nov 2 20:54:16 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * config/tc-m32r.c (assemble_two_insns): Ensure both insns
+ are 16 bit insns.
+
+Mon Nov 2 20:10:18 1998 Martin von Loewis <loewis@informatik.hu-berlin.de>
+
+ * app.c (do_scrub_begin): Set characters above 127 to be symbol
+ characters.
+ (do_scrub_chars): Add some casts to unsigned char to avoid
+ unwanted sign extension.
+ * read.c (lex_type): Set characters about 127 to be symbol
+ characters.
+ * config/tc-i386.c (md_begin): Set identifier_chars and
+ operand_chars for values above 127.
+
+Mon Nov 2 15:05:33 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: detect cygwin* instead of cygwin32*
+ * configure: regenerate
+
+Tue Oct 27 13:18:40 1998 Nick Clifton <nickc@cygnus.com>
+
+ * listing.c: Add support for producing a listing from piped
+ input.
+
+Tue Oct 27 08:56:44 1998 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (hilo_interlocks): Remove mips_3900.
+ (append_insn): Account for the tx39's multiply behavior.
+
+1998-10-26 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-m32r.c (assemble_two_insns): Rename assemble_two_insns
+ from assemble_parallel_insns. Add support for '->' to indicate
+ explicitly serializing the instructions.
+ (md_assemble): Ditto.
+
+Sat Oct 24 15:12:19 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-sh.c (sh_fix_adjustable): Adjust EXTERN and
+ WEAK handling.
+
+Thu Oct 22 12:41:33 1998 Catherine Moore <clm@cygnus.com>
+
+ * cgen.c (gas_cgen_md_apply_fix3): Revert last change.
+
+Thu Oct 22 10:03:15 1998 Ron Unrau <runrau@cygnus.com>
+
+ * config/tc-mips.c: support frame and regmask/fregmask when
+ MIPS_STABS_ELF is specified.
+
+Wed Oct 21 11:34:51 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-sh.c (sh_fix_adjustable): Only include if OBJ_ELF.
+ (md_apply_fix): Don't return 1 for VTABLE relocs.
+ * config/tc-sh.h (obj_fix_adjustable): Define only if OBJ_ELF.
+
+Tue Oct 20 11:18:28 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * doc/c-i386.texi: Replace occurences of "opcode" with
+ "instruction mnemonic", "instruction", or "mnemonic" when
+ referring to the name of an instruction. Use "opcode" when
+ referring to the sequence of machine bytes.
+
+ * config/tc-i386.c (opcode_chars): Rename to mnemonic_chars.
+ (is_opcode_char): Rename to is_mnemonic_char.
+ (md_assemble and i386_operand): Correct error messages from
+ "opcode" to "instruction mnemonic"
+ Rename throughout opcode[] -> mnemonic[], opp -> mnem_p,
+ MAX_OPCODE_SIZE -> MAX_MNEM_SIZE,
+ DWORD_OPCODE_SUFFIX -> DWORD_MNEM_SUFFIX,
+ WORD_OPCODE_SUFFIX -> WORD_MNEM_SUFFIX,
+ BYTE_OPCODE_SUFFIX -> BYTE_MNEM_SUFFIX,
+ SHORT_OPCODE_SUFFIX -> SHORT_MNEM_SUFFIX
+ LONG_OPCODE_SUFFIX -> LONG_MNEM_SUFFIX
+
+ * config/tc-i386.h (*_MNEM_SUFFIX): Rename from *_OPCODE_SUFFIX.
+
+ * config/tc-i386.c (i386_operand): Check for garbage after
+ register name.
+
+Tue Oct 20 10:49:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (md_apply_fix3): Change handling of PCREL reloc
+ for BFD_ASSEMBLER to only change value when COFF if TE_PE.
+
+Mon Oct 19 20:20:42 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-sh.h (obj_fix_adjustable): Define.
+ * config/tc-sh.c (sh_force_relocation): Handle VT relocs.
+ (md_apply_fix): Likewise.
+ (tc_gen_reloc): Likewise.
+ (sh_fix_adjustable): New.
+
+Mon Oct 19 12:35:43 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.c (gas_cgen_finish_insn): Update handling of CGEN_INT_INSN_P.
+ * cgen.h (gas_cgen_finish_insn): Update prototype.
+ * config/tc-m32r.c (m32r_insn): CGEN_INT_INSN -> CGEN_INT_INSN_P.
+ cgen_insn_t -> CGEN_INSN_INT.
+ (make_parallel): Update handling of CGEN_INT_INSN_P.
+ (assemble_parallel_insn): Ditto.
+ (target_make_parallel): New function.
+ (md_assemble): Use it.
+
+Mon Oct 19 13:16:12 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-m32r.c (m32r_force_relocation): Fix typo.
+
+Sun Oct 18 18:48:57 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-sh.c (md_assemble): Make sure the entire opcode is
+ converted into lower case.
+
+Fri Oct 16 13:36:34 CDT Catherine Moore <clm@cygnus.com>
+
+ * cgen.c (gas_cgen_md_apply_fix3): Handle VTABLE relocs.
+ (gas_cgen_tc_gen_reloc): Likewise.
+ * config/tc-m32r.h (obj_fix_adjustable): Define.
+ * config/tc-m32r.c (m32r_fix_adjustable): New.
+ (m32r_force_relocation): Handle VTABLE relocs.
+
+Wed Oct 14 11:33:38 1998 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-arm.texi (ARM Directives): Document .ltorn directive.
+
+Mon Oct 12 11:07:21 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c (assemble_parallel_insn): Convert second opcode
+ to lower case before parsing.
+
+ * config/tc-d30v.c (parallel_ok): Ignore conflicts when explicitly
+ parallel insns modift buts in the PSW as a side effect.
+
+Thu Oct 8 10:18:33 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (find_format): Test for missing flag and
+ control registers.
+
+ (md_apply_fix3): Fix error messages to avoid
+ assumption about presence of a symbol.
+
+ (parallel_ok): Disallow parallel instructions that both modify the
+ same flag register.
+
+ (find_format): Generate a warning if an odd numbered register is
+ used as the first register in a mutli-register instruction.
+
+Wed Oct 7 14:09:14 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_apply_fix3): Do not assume that bad
+ relocations are always associated with a symbol.
+
+Tue Oct 6 09:31:15 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-sparc.h (TC_FORCE_RELOCATION): Define.
+ (elf32_sparc_force_relocation): Declare.
+ * config/tc-sparc.c (md_apply_fix3): Handle vtable relocs.
+ (tc_gen_reloc): Handle vtable relocs.
+ (elf32_sparc_force_relocation): New.
+
+Mon Oct 5 09:25:32 1998 Catherine Moore <clm@cygnsu.com>
+
+ * symbols.c (S_IS_FUNCTION): New.
+ * config/tc-v850.h (obj_fix_adjustable): Define.
+ (TC_FORCE_RELOCATION): Define.
+ (v850_force_relocation): Declare.
+ * config/tc-v850.c (tc_gen_reloc): Use offset instead
+ of fx_addnumber for VTABLE reloc addends.
+ (md_apply_fix3): Handle VTABLE relocs.
+ (v850_fix_adjustable): New.
+ (v850_force_relocation): New.
+
+Mon Oct 5 00:48:52 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (fp_operand_format): Add some additional formats.
+ (pa_ip): Do not automatically promote into pa2.0 mode.
+ (pa_level): Handle ".level 2.0".
+
+Sun Oct 4 20:57:43 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (md_assemble): Handle AMD_3DNOW_OPCODE.
+ * config/tc-i386.h (template.extension_opcode): Change to
+ unsigned int to allow full range of 8-bit opcode suffixes.
+ (None): Redefine as 0xffff.
+
+ From Jeff B Epler <jepler@usgs.gov>
+ * doc/c-i386.texi (i386-SIMD): New section.
+
+Thu Oct 1 15:37:54 1998 Richard Henderson <rth@cygnus.com>
+
+ * read.c (discard_rest_of_line): New function.
+ * read.h: Declare it.
+ * config/tc-alpha.c (s_alpha_mask, s_alpha_frame): Use it.
+
+Thu Oct 1 10:33:53 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d10v.c (find_symbol_matching_register): New function.
+ (find_opcode): Cope with the case where a register name matches
+ a symbol name.
+
+Wed Sep 30 10:52:32 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_pcrel_from): Rename to
+ v850_pcrel_from_section.
+ (v850_pcrel_from_section): Do not resolves symbols in other
+ sections.
+
+ * config/tc-v850.h (MD_PCREL_FROM_SECTION): Define.
+
+Mon Sep 28 11:01:20 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d10v.c (find_opcode): Generate an error if a register
+ is supplied for an operand that should not be a register.
+
+Fri Sep 25 10:04:21 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (write_2_short): But do allow delayed branch
+ instructions to have another instruction in the right bin.
+
+Thu Sep 24 09:28:34 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (write_2_short): Do not allow instructions in
+ the right container if the left container holds a branch
+ instruction.
+
+Wed Sep 23 10:54:29 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (reg_name_search): Only warn if a name matches
+ both a register name and symbol name.
+ (find_format): Allow correct parsing of MVTSYS and MVFSYS insns.
+
+Tue Sep 22 17:49:16 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (write_2_short): Implement EITHER_BUT_PREFER_MU
+ execution unit class.
+
+ (reg_name_search): If a name matches a register and a symbol,
+ prefer the register.
+ (find_format): Disallow flag registers when a general purpose
+ register is required.
+ If a number is required, but a register has been given, check to
+ see if a symbol with the same name as the register exists, and if
+ so, use that symbol.
+
+Tue Sep 22 16:40:52 1998 Jim Wilson <wilson@cygnus.com>
+
+ * config/obj-elf.h (ECOFF_DEBUGGING): Add missing parens.
+
+Tue Sep 22 15:44:21 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (find_format): Do not accept flag registers as
+ general purpose registers.
+ (find_format): If an immediate value is expected at a given place
+ in a format, but a register name has been provided instead, check
+ to see if that register name matches the name of a predefined
+ symbol and if it does, then use the symbol instead.
+ (reg_name_search): If a register name matches a symbol name,
+ prefer the register name to the symbol name.
+
+Mon Sep 21 10:42:57 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c (m32r_do_align): After inserting NOPs, reset
+ the previous insn to empty.
+
+1998-09-20 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.c (md_apply_fix3): Do not break string into two
+ pieces, forcing the use of an ANSI compiler.
+
+Sun Sep 20 00:58:12 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.h (TC_FORCE_RELOCATION): New macro. Force vtable
+ relocs.
+ * config/tc-m68k.c (md_apply_fix_2): Do nothing for vtable relocs.
+
+Tue Sep 15 08:51:07 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/obj-elf.c (obj_elf_vtable_inherit): Handle arm
+ assembler syntax.
+ (obj_elf_vtable_entry): Likewise.
+ * config/tc-arm.h: Define TC_FORCE_RELOCATION for OBJ_ELF.
+ * config/tc-arm.c (md_apply_fix3): Handle VTABLE relocations.
+ (tc_gen_reloc): Likewise.
+ (arm_fix_adjustable): Likewise.
+ (elf32_arm_force_relocation): New.
+ (armelf_frob_symbol): Remove coff-style symbol support.
+
+Wed Sep 9 11:27:16 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-i386.c (i386_operand): Fix typo in last patch.
+
+Tue Sep 8 18:10:01 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-arm.c (arm_adjust_symtab): Move #ifdef
+ OBJ_COFF so that routine is defined for a.out format.
+
+Tue Sep 8 15:56:19 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-i386.c (i386_operand): Detect non-segment registers
+ used as segment prefixes.
+
+Sat Sep 5 19:00:38 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ehopt.c (check_eh_frame): Check the size of the FDE, and don't
+ optimize across FDE boundaries.
+
+ * config/obj-coff.c (obj_coff_section): Preserve any link once
+ flags when setting the section flags.
+
+Fri Sep 4 17:07:14 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.h (obj_adjust_symtab): Fixed typo.
+ * config/tc-arm.c (armelf_adjust_symtab): Reformatted.
+
+Fri Sep 4 13:57:43 1998 Jakub Jelinek <jj@sunsite.ms.mff.cuni.cz>
+
+ * config/tc-sparc.c (in_signed_range): Sign extend 32-bit words
+ to the host width.
+
+Wed Sep 2 11:31:14 1998 Richard Henderson <rth@cygnus.com>
+
+ * frags.c (frag_grow): Include the size of the frag struct in the
+ obstack chunk size.
+
+ * subsegs.c (subseg_set_rest): Adjust the seginfo frchain start
+ if the new subseg comes before the old.
+
+Tue Sep 1 15:01:33 1998 Jakub Jelinek <jj@sunsite.ms.mff.cuni.cz>
+
+ * config/tc-sparc.c (sparc_ip): Allow all digits in an instruction
+ to handle edge8 and edge16.
+
+Mon Aug 31 09:51:14 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/obj-elf.c (obj_elf_vtable_inherit): Print error message
+ before we clobber the symbol involved.
+
+Mon Aug 31 10:58:06 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-arm.c: Remove OBJ_ELF definitions for
+ S_GET_STORAGE_CLASS and S_SET_STORAGE_CLASS. Only
+ use arm_adjust_symtab for OBJ_COFF.
+ (armelf_adjust_symtab): New Routine.
+ * config/tc-arm.h: Define obj_adjust_symtab to
+ armelf_adjust_symtab for OBJ_ELF.
+
+Sat Aug 29 22:18:51 1998 Richard Henderson <rth@cygnus.com>
+
+ * configure.in: Make all i386-elf targets use bfd_gas.
+ * config/tc-i386.c (tc_i386_force_relocation): New.
+ (tc_i386_fix_adjustable): Don't fix vtable relocs.
+ (md_apply_fix3): Likewise.
+ (tc_gen_reloc): Handle them.
+ * config/tc-i386.h (TC_FORCE_RELOCATION): Always define, calling
+ tc_i386_force_relocation.
+
+Mon Aug 24 13:40:21 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_show_usage): Improve formatting of --help output.
+
+Fri Aug 21 18:43:48 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_assemble): Copy previous opcode over
+ current opcode after writing the first insturction of a reverse
+ sequential pair.
+
+Fri Aug 21 07:30:35 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * read.h (generate_lineno_debug): Add prototype.
+ * read.c (generate_lineno_debug): Make non-static.
+
+Thu Aug 20 23:17:04 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (md_assemble): Only warn for address/data size
+ prefixes.
+
+Thu Aug 20 14:45:08 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (arm_fix_adjustable): Do not adjust relocations
+ against Thumb function names, as the linker needs this information.
+
+1998-08-20 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * expr.c (operand): Check also that there is no advance in operand
+ after atof_generic in order to decide "is it label 0f or floating
+ point number?".
+
+Wed Aug 19 09:30:16 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c: Replace double dash prefix to M32R specific
+ command line options with a single dash.
+ * doc/c-m32r.texi: Replace double dash prefix with a single dash.
+
+Tue Aug 18 11:59:43 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-arm.h: Define obj_fix_adjustable for OBJ_ELF.
+ * config/tc-arm.c (arm_fix_adjustable): New routine.
+
+1998-08-13 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * read.c (s_align, s_comm, s_mri_common, s_fail, s_globl, s_space,
+ s_float_space, s_struct, cons_worker): Move ignore_rest_of_line or
+ demand_empty_rest_of_line before mri_comment_end.
+ (equals): Check garbage after expression before
+ mri_comment_end in MRI mode.
+
+Thu Aug 13 15:08:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (macro): Correct M_SGE_I/M_SGEUI_I case for a
+ small immediate constant to use the constant itself rather than
+ always using 1.
+
+Wed Aug 12 18:47:38 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-hppa.c (pa_enter): Call as_bad rather than abort.
+ (pa_leave): Likewise.
+
+Wed Aug 12 13:25:03 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (md_assemble): Emit a warning for stand-alone
+ prefixes.
+ (i386_operand): Fix an error message.
+
+Tue Aug 11 14:44:32 1998 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-arm.texi (ARM Directives): Document .req directive.
+
+ * config/tc-arm.c (reg_required_here): Display erroneous string if
+ the register name could not be decoded.
+ Do not set inst.instruction if the sift is -1.
+
+Mon Aug 10 15:39:56 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (tc_gen_reloc): Bias WEAK symbols just as
+ we do for EXTERN.
+
+Mon Aug 10 15:06:18 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (d30v_align): Always perform alignment request,
+ even if it is belived to be unnecessary.
+
+Mon Aug 10 17:48:09 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ config/tc-i386.c (i386_operand): Size immediate constants by
+ suffix (erroneously removed as part of July 7 change).
+
+Sun Aug 9 20:45:32 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/obj-elf.h: Check for redefinition of obj_frob_symbol.
+ * config/tc-arm.c: Define S_GET_STORAGE_CLASS and S_SET_STORAGE_CLASS.
+ (armelf_frob_symbol): New Routine.
+ * config/tc-arm.h: Define obj_frob_symbol if OBJ_ELF.
+
+Sat Aug 8 15:21:28 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (alpha_fix_adjustable): Don't adjust weak syms.
+
+Wed Aug 5 15:54:14 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_begin): Set BFD private flags depending upon
+ command line switches passed to assembler.
+
+Mon Aug 3 14:02:52 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.h (GAS_CGEN_MAX_FIXUPS): GAS_ prepended, all uses updated.
+ (gas_cgen_opcode_desc): Declare.
+ (gas_cgen_parse_operand): Declare.
+ (*): Prepend gas_ to gas specific fns to denote them as such.
+ All uses updated.
+ * cgen.c (gas_cgen_opcode_desc): New global
+ (gas_cgen_init_parse): Renamed from cgen_asm_init_parse.
+ (queue_fixup): Renamed from cgen_queue_fixup.
+ (*): Prepend gas_ to gas specific fns to denote them as such.
+ All uses updated.
+ (gas_cgen_md_apply_fix3): Update call to insert_operand.
+ (gas_cgen_finish_insn): Renamed from cgen_asm_finish_insn.
+ * config/tc-m32r.c (md_begin): Remove use of CGEN_SYM.
+ Open opcode table and initialize it.
+ (make_parallel): Use gas_cgen_opcode_desc.
+ (assemble_parallel_insn): Ditto. Remove use of CGEN_SYM.
+ (md_assemble): Ditto.
+
+Sat Aug 1 19:27:30 1998 Richard Henderson <rth@cygnus.com>
+
+ * as.h (debug_info_type): Add entries for unspecified and dwarf*.
+ * ecoff.c (ecoff_generate_asm_lineno): Take no arguments; call
+ as_where ourselves. Provide a stub for !ECOFF_DEBUGGING.
+ * ecoff.h: Move ECOFF_DEBUGGING protection inside GAS_ECOFF_H.
+ Move ecoff_generate_asm_lineno outside ECOFF_DEBUGGING protection.
+ * read.c (generate_lineno_debug): Tidy ECOFF bits. Use
+ DEBUG_UNSPECIFIED rather than DEBUG_NONE for initial test.
+ * config/obj-elf.h (ECOFF_DEBUGGING) [TC_ALPHA]: Define to a variable.
+ (SEPARATE_STAB_SECTIONS): Conditionalize on value of ECOFF_DEBUGGING.
+ (INIT_STAB_SECTION): Likewise.
+ (OBJ_PROCESS_STAB): Likewise.
+
+ * config/tc-alpha.c (md_longopts): New options -mdebug/-no-mdebug.
+ (md_parse_option): Watch for them.
+ (alpha_cur_ent_sym, alpha_flag_mdebug): New variables.
+ (md_begin): Kill neverdef code.
+ (s_alpha_ent, s_alpha_end, s_alpha_mask, s_alpha_frame): New.
+ (s_alpha_prologue): Watch alpha_cur_ent_sym.
+ (s_alpha_coff_wrapper): New.
+ (md_pseudo_table): Trap all ECOFF pseudos.
+
+Fri Jul 31 16:45:54 1998 Ron Unrau <runrau@cygnus.com>
+
+ Start of changes to remove mdebug section from mips*-elf
+ Based on MIPS_STAB_ELF definition
+ * acconfig.h: undef if not configured
+ * config.in: undef if not configured
+ * config/mips-elf.h: only set ECOFF debugging if not stabs-in-elf
+ * config/tc-mips.c (s_ent): set BSF_FUNCTION
+ * stabs.c (s_stab_generic): flush frag
+
+Fri Jul 31 16:14:45 1998 Catherine Moore <clm@cygnus.com>
+
+ * configure.in: (arm-*-elf): Handle.
+ (thumb-*-elf): Handle.
+ * configure: Regenerate.
+ * read.c (stringer): Fix typo in comment.
+ * write.c (fixup_segment): Don't add symbol value to addend if
+ TC_ARM and OBJ_ELF.
+ * config/tc-arm.c (md_section_align): Don't align dwarf debug
+ sections.
+ (tc_gen_reloc): Always set the reloc addend to fixp->fx_offset
+ for OBJ_ELF.
+
+Thu Jul 30 21:38:43 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * config/tc-d30v.c ({cur,prev}_left_kills_right_p): New variables.
+ (write_2_short): Emit warning if new flag is set.
+ (do_assemble): Set flags if left instruction is one of special
+ "right-instruction-killer" type.
+
+Tue Jun 28 18:12:28 1998 Stan Cox <scox@cygnus.com>
+
+ * config/tc-sparc.c (md_number_to_chars, cons_fix_new_sparc):
+ Always output words in debug_info section as big endian.
+ (sparc_target_format): Choose correct bfd target.
+ (md_apply_fix3): Rename BFD_RELOC_SPARC_32LE to BFD_RELOC_SPARC_REV32.
+
+Tue Jul 28 11:01:21 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_assemble): Fix "errmsg" initialization
+ to work with internationalization code. Issue an error when two
+ operands match that are not allowed to match.
+
+Mon Jul 27 16:25:58 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * configure.in (install_tooldir): Allow target to specify whether
+ it wants to be installed in $(tooldir)/bin.
+ * configure: Regenerate.
+ * Makefile.am (install-exec-local): Set install-exec-tooldir
+ dependency via configure.
+ * Makefile.in: Regenerate.
+
+Fri Jul 24 19:58:59 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * Makefile.am (install-exec-local): Split into two ...
+ (install-exec-bindir,install-exec-tooldir): New rules.
+ * Makefile.in: Regenerate.
+
+Fri Jul 24 16:31:49 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (install-exec-local): Don't remove the file before
+ checking whether $(bindir) == $(tooldir)/bin. From Maciej
+ W. Rozycki <macro@ds2.pg.gda.pl>.
+ * Makefile.in: Rebuild.
+
+Fri Jul 24 09:13:46 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * cgen.c: Include libiberty.h.
+ (cgen_md_apply_fix3): Update call to md_cgen_lookup_reloc.
+ (cgen_tc_gen_reloc): Use xmalloc, not bfd_alloc.
+ * cgen.h (cgen_md_apply_fix3,cgen_tc_gen_reloc): Declare.
+ (md_cgen_lookup_reloc)): Declare.
+ (md_cgen_record_fixup_exp): Declare.
+ * config/tc-m32r.h (md_pcrel_from_section): Declare.
+ (m32r_relax_frag): Declare.
+ (cgen_md_apply_fix3): Decls moved to cgen.h.
+ (cgen_record_fixup_exp,cgen_tc_gen_reloc): Ditto.
+ (m32r_cgen_record_fixup_exp): Delete decl.
+ * config/tc-m32r.c (m32r_cpu_desc): #if 0 out.
+ (assemble_nop): Delete.
+ (expand_debug_syms): Delete unused `exp'.
+ (md_cgen_lookup_reloc): Renamed from CGEN_SYM (lookup_reloc).
+ Add default case for -Wall.
+ (m32r_cgen_record_fixup_exp): Add default case for -Wall.
+ (md_atof): Delete unused wordP.
+
+Thu Jul 23 13:19:50 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_assemble): Make sure "errmsg" has a non-NULL
+ value.
+
+Wed Jul 22 14:36:56 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo: Add documentation for .end, .exitm, .fail,
+ .ifc, .ifeqs, .ifge, .ifgt, .ifle, .iflt, .ifnc, .ifne, .ifnes,
+ .print, .purgem, and .struct. Remove documentation for
+ .app-file.
+
+Tue Jul 21 16:50:52 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.c (cgen_md_apply_fix3): set_operand renamed to set_vma_operand.
+ Update call to insert_operand.
+
+Fri Jul 17 11:42:20 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c (ms_show_usage): Formatting changes.
+
+Wed Jul 15 15:38:28 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (md_assemble): Don't get confused by trailing
+ whitespace after a prefix operator.
+
+Tue Jul 14 15:32:56 1998 Richard Henderson <rth@cygnus.com>
+
+ * configure.in (i386-*-beos{pe,elf,}*): Recognize.
+
+Tue Jul 14 12:33:44 1998 Chris Torek <torek@bsdi.com>
+
+ * config/tc-sparc.c (log2): New static function.
+ (s_reserve): Use log2 to convert alignment before calling
+ record_alignment.
+ (s_common): Use log2 to convert alignment before calling
+ record_alignment and frag_align.
+ (sparc_cons_align): Use log2.
+
+Tue Jul 14 11:58:40 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c (s_reserve): Set symbol size if OBJ_ELF.
+ (s_common): Likewise.
+
+ * config/tc-sparc.c (sparc_handle_align): Reindent a bit. Correct
+ initialization of waddr.
+ (sparc_elf_final_processing): Add default case to switch.
+
+Tue Jul 14 11:00:16 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * doc/c-i386.texi: Fix a typo. Use the term 80-bit real rather
+ than temporary real.
+
+Mon Jul 13 13:55:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (subsegs_finish): Don't align the segments if there were
+ any errors.
+
+ * config/obj-coff.c (c_symbol_merge): Correct number of bytes when
+ copying aux information.
+
+ * expr.c (make_expr_symbol): Catch attempts to turn an O_big
+ expression into a symbol.
+
+Mon Jul 13 13:29:04 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (mode_from_disp_size): Change arg and return
+ type to unsigned int.
+ (md_assemble): Change type used to store offsets from unsigned
+ long to long.
+ (i386_operand): Switch error check to only call RESTORE_END_STRING
+ once after parse_register.
+
+Fri Jul 10 16:00:04 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_show_usage): Changed format to match that
+ of gcc, ld, etc.
+
+ * as.c (show_usage): Changed format to match that of gcc, ld, etc.
+
+Thu Jul 9 12:09:57 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (tc_m68k_fix_adjustable): Don't adjust vtable
+ relocs.
+ (md_apply_fix_2): Force the symbol of the vtable reloc to be
+ weak.
+
+Thu Jul 9 11:31:54 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/Makefile.am (MAINTAINERCLEANFILES): Define.
+ * doc/Makefile.in: Rebuild.
+
+Wed Jul 8 12:18:56 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (mips_ip, case 'i' and 'j'): Mask off high bits
+ for %lo expressions.
+ (mips_ip, case 'u'): Move range check after code to mask
+ off bits in %hi/%lo expressions. Mask off high bits for
+ %lo expressions.
+
+Tue Jul 7 17:57:38 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/Makefile.am (gasver.texi): New target.
+ (as.info, as.dvi): Depends upon gasver.texi.
+ * doc/as.texinfo: Include gasver.texi. Mention version number on
+ title page and in top node.
+ * doc/Makefile.in: Rebuild.
+
+Tue Jul 7 11:42:16 1998 Richard Henderson <rth@cygnus.com>
+
+ * listing.c (listing_listing): For EDICT_LIST, skip all lines up to
+ but not including the line containing the edict.
+ * listing.h (LISTING_EOF): New.
+ * input-scrub.c (input_scrub_next_buffer): Call it.
+
+Tue Jul 7 13:00:37 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (i386_operand): Don't set the size of an
+ immediate address based solely on the suffix and the mode.
+
+ * config/tc-i386.c (md_assemble): Add assertion to make sure
+ overlap2 does not set Imm.
+
+ * config/tc-i386.c (space_chars): Remove. The scrubber converts
+ sequences of whitespace to a single space.
+ (is_space_chars): Just compare with space.
+ (md_begin): Don't initialize space_chars.
+ (md_assemble): Just skip a single whitespace character.
+ (i386_operand): Rewrite base-index parsing to use new
+ parse_register, and to skip white space. Skip white space in a
+ number of other places too. Don't give error message if
+ parse_register fails.
+ (parse_register): Change reg_string parameter to be non-const.
+ Add end_op parameter. Skip white space after the `%', and return
+ end of register string. Give error message here rather than
+ caller.
+
+Fri Jul 3 15:34:34 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patch from Matt Semersky <matts@scd.hp.com>:
+ * expr.c (op_encoding): Make const.
+ (expr_set_precedence): New function.
+ (expr_begin): Don't set operator rankings, just call
+ expr_set_precedence.
+ * expr.h (expr_set_precedence): Declare.
+ * read.c (s_mri): Call expr_set_precedence.
+
+Thu Jul 2 16:24:58 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo (Statements): Remove paragraph discussing
+ continuing lines with a backslash. This hasn't worked for years,
+ if it ever did.
+
+Thu Jul 2 14:06:22 1998 Klaus Kaempf <kkaempf@rmi.de>
+
+ * config/obj-vms.c: Add C++ support with ctors/dtors sections. Add weak
+ symbol definitions.
+ (Ctors_Symbols, Dtors_Symbols): New symbol chains.
+ (ps_CTORS, ps_DTORS): New section types.
+ (vms_fixup_xtors_section): New function
+ (Ctors_Psect, Dtors_Psect): Define.
+ (IS_GXX_XTOR): Define
+ (global_symbol_directory): Change check of gxx_bug_fixed to 0.
+ Filter static constructors/destructors and add to
+ Ctors_Symbols/Dtors_Symbols chain.
+ (vms_write_object_file): Write Ctors_Symbols/Dtors_Symbols to
+ appropriate section.
+
+ * config/tc-alpha.h (TARGET_FORMAT): Rename "evax-alpha" to "vms-alpha".
+ * makefile.vms: Merge vax/vms support.
+
+Wed Jul 1 20:06:20 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/obj-elf.c (obj_elf_vtable_inherit, obj_elf_vtable_entry): New.
+ (elf_pseudo_table): Add them.
+ * config/tc-mips.c (mips_force_relocation): Force vtable relocs.
+ (md_apply_fix): Accept them.
+ (mips_fix_adjustable): Don't adjust them.
+ (tc_gen_reloc): Mung BFD_RELOC_VTABLE_ENTRY for Rel.
+ * config/tc-ppc.c (md_apply_fix3): Accept vtable relocs.
+ * config/tc-ppc.h (TC_FORCE_RELOCATION_SECTION): Force vtable relocs.
+ (tc_fix_adjustable): Don't adjust them.
+
+Wed Jul 1 16:35:32 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * Makefile.am (CGEN_CPU_PREFIX): New variable.
+ (cgen.o): Use it.
+ * Makefile.in: Regenerate.
+ * configure.in: AC_SUBST cgen_cpu_prefix.
+ * configure: Regenerate.
+
+Wed Jul 1 21:38:56 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-sh.c (COND_JUMP_DELAY, COND12_DELAY_LENGTH): Define.
+ Changed all users of COND12_DELAY.
+
+Fri Jun 26 11:21:11 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (set_arch_mach): New function.
+ (md_pseudo_table): Add pseudo-ops to set the current machine type.
+ (md_begin): Default to mn10300 mode.
+ (md_assemble): Only accept instructions for the core mn10300
+ chip and the active machine type.
+
+Wed Jun 24 19:06:04 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * subsegs.h (segment_info_type): Give the struct a name.
+ * config/tc-h8300.h (tc_reloc_mangle): Add prototype.
+ * config/tc-h8500.h (tc_reloc_mangle): Declare.
+ * config/tc-sh.h (sh_coff_reloc_mangle): Add prototype.
+ * config/tc-w65.h (tc_reloc_mangle): Declare.
+ * config/tc-z8k.h (tc_reloc_mangle): Declare.
+
+Wed Jun 24 13:45:00 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-v850.c (v850_comm): Restore old section
+ after common processing.
+
+Wed Jun 24 11:50:54 1998 Klaus Kaempf <kkaempf@progis.de>
+
+ * config/obj-vms.c (Create_VMS_Object_File): Force binary file.
+
+Tue Jun 23 17:47:31 1998 Jim Wilson <wilson@cygnus.com>
+
+ * config/tc-h8300.c (do_a_fix_imm, build_bytes): Replace cast to
+ char with code that explicitly sign-extends.
+
+Tue Jun 23 13:54:57 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_begin): Restore text section as the current
+ section after creating call table sections.
+ * config/obj-coff.h (SYM_AUXINFO): New macro to conceal ugly
+ code.
+
+ * config/obj-coff.c (c_symbol_merge): Replace complex expresion
+ with call to macro SYM_AUXINFO.
+
+Tue Jun 23 15:09:27 1998 Mike Stump <mrs@wrs.com>
+
+ * Makefile.am (install-exec-local): Don't let EXEEXT interfere
+ with the program transform name.
+ * Makefile.in: Rebuild.
+
+Mon Jun 22 19:52:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (c_symbol_merge): Fix copying of auxiliary
+ information.
+
+Mon Jun 22 15:18:58 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (i386_operand): Be prepared for a space between
+ the open parenthesis and the start of the register operand,
+ because of the June 16 change.
+
+Sun Jun 21 21:27:03 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (md_apply_fix): Handle weak symbols correctly if
+ BFD_ASSEMBLER.
+
+Sun Jun 21 12:26:36 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (d30v_align): Always perform alignment request,
+ even if it is belived to be unnecessary.
+
+Fri Jun 19 13:57:06 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (adjust_reloc_syms): Never adjust relocs against weak
+ symbols.
+ * config/tc-mips.c (md_apply_fix): Adjust accordingly.
+
+Fri Jun 19 09:50:17 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (mn10300_insert_operand): Do not hardcode the
+ shift amount for a repeated operand. The shift amount for the
+ repeated copy comes from the size of the operand.
+
+Fri Jun 19 00:44:19 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-h8300.c (get_operand): Fix typos in ldm/stm support.
+
+Wed Jun 17 13:07:05 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_show_usage): Fix -mipsN usage.
+
+Tue Jun 16 13:06:21 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * app.c (do_scrub_begin): If tc_symbol_chars is defined, treat all
+ characters in it as LEX_IS_SYMBOL_COMPONENT.
+ * config/tc-i386.h (tc_symbol_chars): Define.
+ (extra_symbol_chars): Declare.
+ * config/tc-i386.c (extra_symbol_chars): Define.
+ (comment_chars): Don't use '/' as comment start if TE_LINUX.
+ (line_comment_chars): Set to '/' if TE_LINUX.
+ * doc/c-i386.texi (i386-prefixes): Update.
+ * doc/internals.texi (CPU backend): Document tc_symbol_chars.
+
+Fri Jun 12 13:36:54 1998 Tom Tromey <tromey@cygnus.com>
+
+ * po/Make-in (all-yes): If maintainer mode, depend on .pot file.
+ ($(PACKAGE).pot): Unconditionally depend on POTFILES.
+
+1998-06-12 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * config/tc-d10v.c (md_apply_fix3): Checking displacement
+ constraint in instructions REP & REPI.
+
+Thu Jun 11 08:56:46 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_apply_fix3): Catch BFD_RELOC_8,
+ BFD_RELOC_16, BFD_RELOC_64 and issue appropriate error messages.
+
+ (check_range): If the operand is shifted, then shift the number
+ before checking its range.
+
+ * write.c (adjust_reloc_syms): Add more checks for NULL pointers.
+
+ * config/tc-v850.c (v850_comm): Set SEC_COMMON bit on special
+ common sections.
+
+Wed Jun 10 17:26:35 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (v850_comm): Create special sections as needed.
+
+1998-06-10 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * config/tc-d10v.c (write_2_short): Addition of swapping
+ instructions for sequential and reverse sequential order when
+ given order is not possible.
+
+Tue Jun 9 13:52:53 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: Rebuild dependencies.
+ (DEP_INCLUDES): Fix reference to intl build directory.
+ * Makefile.in: Rebuild.
+
+Tue Jun 9 12:20:05 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * doc/c-i386.texi: Update 16 bit documentation.
+
+ * config/tc-i386.h: Change Data16 to Size16, Data32 to Size32,
+ IgnoreDataSize to IgnoreSize as they are used for address size as
+ well as data size.
+ * config/tc-i386.c: Likewise. Add code to reject addr32/data32 in
+ 32-bit mode, similarly addr16/data16 and variants.
+
+Mon Jun 8 18:32:01 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_assemble): Fix handling of reverse
+ sequential word multiply instructions.
+
+ (do_assemble): Add extra command line argument, to allow mul32
+ attribute to be preserved across parallel insns.
+ (md_assemble): Insert NOPs between explicitly parallel insns which
+ contain an 32 bit multiply and a 16 multiply.
+
+Mon Jun 8 12:20:30 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c: REPNE renamed to REPNE_PREFIX_OPCODE, and
+ likewise for REPE.
+
+ * config/tc-i386.c (reloc): Add braces.
+
+ * config/tc-i386.c (struct _i386_insn): Rename bi to sib to be
+ consistent with Intel naming.
+ * config/tc-i386.h (base_index_byte): Rename to sib_byte. Don't
+ use bitfields in sib_byte.
+ (modrm_byte): Don't use bitfields here either.
+
+ * config/tc-i386.c (current_templates): Add const.
+ (parse_register): Add const to return, param, and char *s.
+ (i386_operand): Add const to reg_entry *r.
+ * config/tc-i386.h (templates): Add const to start, end.
+
+ Inspired by code for 16 bit gas support from Martynas Kunigelis
+ <martynas@nm3.ktu.lt>:
+ * config/tc-i386.c (md_assemble): Add full support for 16 bit
+ modrm, and Jump, JumpByte, JumpDword, JumpInterSegment insns.
+ (uses_mem_addrmode): Remove.
+ (md_estimate_size_before_relax): Add support here too.
+ (md_relax_table): Rewrite interface to md_relax for 16 bit
+ support.
+ (BYTE, WORD, DWORD, UNKNOWN_SIZE): Remove.
+ (opcode_suffix_to_type): Remove.
+ (CODE16, SMALL, SMALL16, BIG, BIG16): Define.
+ (SIZE_FROM_RELAX_STATE): Modify to suit above.
+ (md_convert_frag): Likewise.
+ (i386_operand): Add support for 16 bit base/index regs,
+ immediates, and displacements. Remove some unnecessary casts, and
+ localise end_of_operand_string, displacement_string_start,
+ displacement_string_end variables. Add GCC_ASM_O_HACK.
+ * config/tc-i386.h (NO_BASE_REGISTER_16): Define.
+
+ * config/tc-i386.c (prefix_hash): Remove.
+ (md_begin): Rewrite without obstacks. Remove prefix hash table
+ handling. Rewrite lexical table handling.
+ (i386_print_statistics): Don't print prefix statistics.
+ (md_assemble): Rewrite instruction parser so that line is not
+ converted to lower case. Don't do a hash_find for prefixes,
+ instead recognise them via opcode modifier.
+ (expecting_operand, paren_not_balanced): Localise variables.
+ * config/tc-i386.h (IsPrefix): Define.
+ (prefix_entry): Remove.
+
+ * config/tc-i386.h (PREFIX_SEPERATOR): Don't define.
+ * config/tc-i386.c (PREFIX_SEPARATOR): Define here instead, using
+ '\\' in case where comment_chars contains '/'.
+
+ * config/tc-i386.c (MATCH): Ensure given operand and template
+ match for JumpAbsolute. Makes e.g. `ljmp table(%ebx)' invalid;
+ you must write `ljmp *table(%ebx)'.
+
+ From H.J. Lu <hjl@gnu.org>:
+ * config/tc-i386.c (BFD_RELOC_16, BFD_RELOC_16_PCREL): Define
+ as 0 ifndef BFD_ASSEMBLER.
+ (md_assemble): Allow immediate operands without suffix or
+ other reg operand to default in size to the current code size.
+
+Mon Jun 8 09:45:00 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-v850.c (md_begin): Restore creation of
+ .call_table_text and .call_table_data sections.
+
+Sat Jun 6 00:02:41 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_assemble): Set execution type to unknown
+ after emitting a word of noops.
+
+Fri Jun 5 23:27:04 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (mode_from_disp_size): Disp16 is mode 2.
+ (i386_operand): Simplify checks for valid base/index combinations.
+ Disallow `in 4(%dx),%al'.
+
+ * config/tc-i386.c (struct _i386_insn): Make regs, base_reg, and
+ index_reg const.
+ (add_prefix): Change parameter from char to int.
+
+ * config/tc-i386.h (Ugh): Define opcode modifier.
+ * config/tc-i386.c (md_assemble): Print warnings for Ugh insns.
+
+ * config/tc-i386.c (md_assemble): Rewrite MATCH and
+ CONSISTENT_REGISTER_MATCH macros to check register types more
+ thoroughly. Check for illegal suffix/operand combinations
+ when matching insns with operands. Handle new `s' suffix, and
+ associated FloatMF opcode modifier for float insns with memory
+ operands.
+ * config/tc-i386.h (FloatMF): Define new opcode modifier.
+ (No_sSuf, No_bSuf, No_wSuf, No_lSuf): Likewise.
+ (SHORT_OPCODE_SUFFIX, LONG_OPCODE_SUFFIX): Define.
+ * config/tc-i386.c: Rename WORD_PREFIX_OPCODE to
+ DATA_PREFIX_OPCODE throughout.
+
+ * config/tc-i386.c (REGISTER_WARNINGS): Define.
+ (md_assemble): Rewrite suffix/register operand checking code to be
+ more thorough. Remove Abs8,16,32. Change occurrences of Mem to
+ AnyMem, the better to grep.
+ (pi): Remove Abs.
+ (i386_operand): Don't set Mem bits in i.types[this_operand] when
+ given a memory operand. Don't set Abs bits either.
+ (type_names): Remove Mem*, Abs*.
+ * config/tc-i386.h (Mem8, Mem16, Mem32, Abs8, Abs16, Abs32): Don't
+ define opcode_modifiers as these cases are handled by Disp8,
+ Disp16, Disp32 and suffix checks.
+ (COMES_IN_BOTH_DIRECTIONS): Remove.
+ (FloatR): Define. It's OK to share the bit with ReverseRegRegmem.
+
+ * config/tc-i386.c (md_assemble): Don't emit operand size prefix
+ if IgnoreDataSize modifier given. Remove ShortformW modifier
+ test. Add test for ShortForm in W base_opcode modification.
+ Merge Seg2ShortForm and Seg3ShortForm code.
+ * config/tc-i386.h (ShortFormW): Remove.
+ (IgnoreDataSize): Define.
+
+Fri Jun 5 10:50:53 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_assemble): Store previous segment state
+ with previous instruction.
+
+Wed Jun 3 18:21:56 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (SCALE1_WHEN_NO_INDEX): Define.
+ (ebp, esp): Remove static variables.
+ (MATCH): Remove test for InOutPortReg.
+ (i386_operand): Properly handle InOutPortReg here instead.
+ Disallows `inb (%dx,2)', `inb %es:(%dx)' and `mov (%dx),%ax'
+ (md_assemble): Simplify and correct modrm and sib generation.
+ (i386_operand): Add warning for scale without index.
+ Rewrite checks for valid base/index combinations.
+
+ * config/tc-i386.c (END_STRING_AND_SAVE): Protect arguments of
+ macros and enclose in do while(0).
+ (RESTORE_END_STRING): Likewise.
+ (md_assemble): Add one to printed operand number so we start
+ from 1 not 0. Add some more gettext invocations.
+ (i386_operand): Fix `%%s' -> `%%%s'. Inc printed operand
+ number here too.
+
+ * config/tc-i386.h (WAIT_PREFIX, LOCKREP_PREFIX, ADDR_PREFIX,
+ DATA_PREFIX, SEG_PREFIX): Define.
+ * config/tc-i386.c (struct _i386_insn): Remove wait_prefix field.
+ (check_prefix): Remove function.
+ (add_prefix): New function. Add prefix to i.prefix as well as
+ doing checks.
+ (md_assemble): Changes for add_prefix. Remove hack for wait
+ prefix, instead always output prefixes in fixed order. Test
+ for jcxz/loop when selecting between word & dword operations,
+ and add address size prefix rather than operand size prefix.
+ Remove operand -> address size hack when emitting jcxz/loop.
+ (i386_operand): Remove O_Absent check as it's done in expr.
+
+Wed Jun 3 15:09:10 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Recognize m5200 as a cpu_type of m68k.
+ * aclocal.m4: Rebuild with current libtool.
+ * configure: Rebuild.
+
+Wed Jun 3 14:11:59 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (md_estimate_size_before_relax): Add more calls
+ to relaxable_symbol to prevent references to external symbol from
+ being relaxed.
+
+Wed Jun 3 14:10:36 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (relaxable_symbol): If TARGET_OS is "elf", all
+ symbols are relaxable.
+
+Wed Jun 3 09:16:00 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-v850.c (md_begin): Don't create special
+ sections by default.
+
+Tue Jun 2 14:52:56 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (macro): For div and udiv, close the
+ reorder block as soon as possible.
+
+Tue Jun 2 15:36:13 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ From Matt Semersky <matts@scd.hp.com>:
+ * macro.c (macro_mri_mode): New function.
+ * macro.h (macro_mri_mode): Declare.
+ * read.c (s_mri): Call macro_mri_mode when switching in and out of
+ MRI mode.
+
+Tue Jun 2 13:32:22 1998 Klaus Kaempf <kkaempf@progis.de>
+
+ * config/tc-alpha.c (s_alpha_comm): Allow alignment parameter in
+ OBJ_EVAX case.
+
+ * config/tc-alpha.c (s_alpha_comm): Defer restoring character
+ until after xstrdup in OBJ_EVAX case.
+
+Tue Jun 2 13:11:13 1998 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/tc-vax.c (md_create_short_jump): Fix off by two bug in
+ offset calculation. Also, use VAX_BRW from vax-inst.h instead
+ of hardcoded magic number.
+ (md_create_long_jump): Use VAX_JMP and VAX_ABSOLUTE_MODE macros.
+
+Tue Jun 2 09:25:34 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * read.c (do_s_func): New function.
+ (s_func): Call it.
+ * read.h (do_s_func): Add prototype.
+
+Mon Jun 1 12:47:30 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * config/tc-m32r.c (m32r_do_align): Only fill code sections with
+ nops if fill pattern not specified.
+
+Mon Jun 1 14:08:35 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ From Andrew Crabtree <andrewc@typhoon.rose.hp.com>:
+ * config/te-go32.h (TE_GO32): Define.
+ * config/tc-i386.h (LOCAL_LABEL): Don't define if TE_GO32.
+
+Sun May 31 15:43:06 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ Implement .func/.endfunc pseudo-ops.
+ * read.h (stabs_generate_asm_func,stabs_generate_asm_endfunc): Declare.
+ (s_func): Declare.
+ * read.c (potable): Add .func,.endfunc.
+ (s_func): New function.
+ * stabs.c (stabs_generate_asm_func,stabs_generate_asm_endfunc): New
+ functions.
+ (in_doc_func_p,current_function_label): New static globals.
+ (stabs_generate_asm_lineno): Emit function relative stabs if in .func.
+
+Fri May 29 18:13:12 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-a29k.h (WORKING_DOT_WORD): Define.
+ * config/tc-alpha.h (WORKING_DOT_WORD): Define.
+ * config/tc-arm.h (WORKING_DOT_WORD): Define.
+ * config/tc-h8300.h (WORKING_DOT_WORD): Define.
+ * config/tc-h8500.h (WORKING_DOT_WORD): Define.
+ * config/tc-hppa.h (WORKING_DOT_WORD): Define.
+ * config/tc-i860.h (WORKING_DOT_WORD): Define.
+ * config/tc-i960.h (WORKING_DOT_WORD): Define.
+ * config/tc-tic30.h (WORKING_DOT_WORD): Define.
+ * config/tc-w65.h (WORKING_DOT_WORD): Define.
+ * config/tc-z8k.h (WORKING_DOT_WORD): Define.
+ * config/tc-a29k.c: Don't define md_short_jump_size,
+ md_long_jump_size, md_create_short_jump or md_create_long_jump.
+ * config/tc-alpha.c: Likewise.
+ * config/tc-alpha.h: Likewise.
+ * config/tc-arm.c: Likewise.
+ * config/tc-h8300.c: Likewise.
+ * config/tc-h8500.c: Likewise.
+ * config/tc-hppa.c: Likewise.
+ * config/tc-i860.c: Likewise.
+ * config/tc-i960.c: Likewise.
+ * config/tc-ppc.c: Likewise.
+ * config/tc-sh.c: Likewise.
+ * config/tc-sparc.h: Likewise.
+ * config/tc-tic30.c: Likewise.
+ * config/tc-w65.c: Likewise.
+ * config/tc-z8k.c: Likewise.
+
+Fri May 29 16:03:26 1998 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/tc-vax.c (_): Delete this macro used for placeholder
+ values in vax_operand_width_size; it conflicts with the _() macro
+ used for internationalization.
+
+Fri May 29 13:46:07 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (symbol_find_base): Fix case insensitive symbol name
+ code. From Chris Moller <moller@bops.com>.
+
+ Based on patch from Klaus Kaempf <kkaempf@progis.de>:
+ * struc-symbol.h (struct broken_word): Add seg and subseg fields.
+ * read.c (emit_expr): Initialize seg and subseg fields of a new
+ broken word.
+ * write.c (write_object_file): Switch to the appropriate segment
+ and subsegment when processing a broken word.
+
+ * config/tc-m68k.c (mri_assemble): New static function.
+ (build_mri_control_operand): Call mri_assemble rather than
+ md_assemble.
+ (s_mri_else, s_mri_break, s_mri_next, s_mri_for): Likewise.
+ (s_mri_endf, s_mri_endw): Likewise.
+
+Wed May 27 11:16:25 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (s_org): Call md_flush_pending_output if it is defined.
+
+ * config/tc-sparc.c (md_show_usage): Add \n\ to new string.
+
+Tue May 26 19:27:52 1998 Stan Cox <scox@equinox.cygnus.com>
+
+ * config/tc-sparc.c (OPTION_LITTLE_ENDIAN_DATA): New.
+ (md_parse_option): Add for same.
+ (sparc_md_end): Set bfd_mach_sparc_sparclite_le.
+ (md_apply_fix3, tc_gen_reloc): Allow BFD_RELOC_SPARC_32LE.
+ (cons_fix_new_sparc): Added to create BFD_RELOC_SPARC_32LE.
+
+ * config/tc-sparc.h (cons_fix_new_sparc): Added.
+
+Thu May 21 15:02:41 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (find_real_start): Relax definition of local
+ labels.
+
+Tue May 19 16:59:44 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (d30v_align): Apply address adjustment to all
+ symbols at the given address, not just the last one specified.
+
+Tue May 19 08:25:19 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-sparc.c (sparc_handle_align): Use number_to_chars_bigendian
+ or number_to_chars_littleendian to write data.
+
+Mon May 18 17:09:30 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_assemble): Remove artificially created
+ register name symbols.
+
+Mon May 18 13:47:06 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * write.c (fixup_segment): Change "segment" to "section" in
+ error message.
+
+Mon May 18 16:55:40 1998 Michael Meissner <meissner@cygnus.com>
+
+ * write.c (fixup_segment): Change sym1-sym2 message again.
+
+Mon May 18 09:31:43 1998 Michael Meissner <meissner@cygnus.com>
+
+ * write.c (fixup_segment): Improve error message for sym1-sym2
+ errors when sym1 is in a different segment from sym2.
+
+Wed May 13 10:16:37 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * config/tc-m32r.c (warn_unmatched_high): New static local.
+ (OPTION_WARN_PARALLEL): Rename from OPTION_WARN.
+ (OPTION_NO_WARN_PARALLEL): Rename from OPTION_NO_WARN.
+ (md_longopts): Recognize --{no-,}warn-unmatched-high.
+ (md_parse_option): Likewise.
+ (md_show_usage): Likewise.
+ (m32r_frob_file): Likewise.
+
+ * read.c (generate_file_debug,generate_lineno_debug): New functions.
+ (read_a_source_file): Call them.
+ * read.h (stabs_generate_asm_file): Declare.
+ * stabs.c (stabs_generate_asm_file): New function.
+ (generate_asm_file): New function.
+ (stabs_generate_asm_lineno): Move file name handling into
+ generate_asm_file.
+
+Tue May 12 12:03:44 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-d30v.c (cur_mul32_p, prev_mul32_p): Make static.
+ (d30v_current_align, d30v_current_align_seg): New variables.
+ (d30v_last_label): New variable.
+ (d30v_align, s_d30v_align, s_d30v_text): New functions.
+ (s_d30v_data, s_d30v_section): Likewise.
+ (md_pseudo_table): Call them.
+ (md_begin): Initialize d30v_current_align_seg.
+ (md_assemble): Call d30v_align when needed by known current alignment.
+ (d30v_frob_label, d30v_cons_align): New functions.
+ * config/tc-d30v.h (md_do_align): Remove.
+ (tc_frob_label): Call d30v_frob_label.
+ (md_cons_align): New.
+
+ * config/tc-d30v.c (find_format): Convert complex expressions to
+ expression symbols before processing. Clean up code formatting.
+
+Sun May 10 22:35:02 1998 Jeffrey A Law (law@cygnus.com)
+
+ * po/Make-in (install-info): New target.
+
+Thu May 7 15:49:07 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_assemble): Handle "bra" just like "jmp"
+ instructions.
+ * config/tc-mn10300.c (md_assemble): Likewise.
+
+Thu May 7 11:47:22 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * Makefile.am: Update with `make dep-am'.
+ (HFILES): Add cgen.h.
+ (cgen.o): Depend on cgen.h.
+ * Makefile.in: Regenerate.
+
+ * cgen.c (cgen_md_apply_fix3): Don't pass newline to as_warn_where.
+
+Thu May 7 13:20:56 1998 Anders Blomdell <anders.blomdell@control.lth.se>
+
+ * gasp.c (grab_label): Permit a label to be a preprocessor
+ variable by permitting a label to start with a backslash.
+
+Thu May 7 12:50:33 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * config/tc-mips.c (validate_mips_insn): Removed hack
+ for previously inaccessible bitfields in some INSN_TRAP
+ instructions.
+
+Thu May 7 11:13:00 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * config/tc-d30v.c (do_assemble): Abort with error message
+ if opcode operands do not match.
+
+Thu May 7 09:36:06 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * config/tc-mips.c (macro_build, validate_mips_insn): Implement
+ 'q' operand format for 20-bit "break"/"sdbbp" instructions.
+ (mips_ip): Truncate overflowed "break" 'c' operand. Implement
+ similar new 'q' operand.
+
+Thu May 7 07:47:14 1998 Michael Meissner <meissner@cygnus.com>
+
+ * cgen.c (cgen_asm_finish_insn): Fix typo.
+
+Thu May 7 02:19:14 1998 Doug Evans <devans@charmed.cygnus.com>
+
+ * cgen.h: New file.
+ * cgen.c: Include it.
+ (MAX_FIXUPS): Renamed to CGEN_MAX_FIXUPS.
+ (cgen_asm_finish_insn): Result is now void. New arg `result'.
+ All callers updated.
+ * config/tc-m32r.c: Include cgen.h.
+ (m23r_insn): New members num_fixups,fixups.
+
+Wed May 6 16:29:19 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (md_apply_fix): Slightly rework some code
+ to avoid compiler warning.
+
+Wed May 6 15:26:34 1998 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: Run dec c with /nodebug. Pass CC value when
+ calling make.
+
+ * makefile.vms (OBJS): Add ehopt.obj
+
+Wed May 6 15:11:12 1998 Klaus Kaempf <kkaempf@progis.de>
+
+ * doc/c-vax.texi: Correct and extend vax/vms documentation.
+
+Wed May 6 11:51:51 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-d30v.c (do_assemble): Accept a new parameter requesting
+ a short format insn.
+ (md_assemble): Set it for explicitly packed insns.
+
+Tue May 5 13:23:13 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/obj-coff.c (c_symbol_merge): Do not take address of
+ native fields when performing the memcpy.
+
+Tue May 5 13:10:41 1998 Gavin Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (macro,macro2): Implement
+ M_DMULO_I, M_MULO_I, M_DMULOU_I, and M_MULOU_I.
+
+Mon May 4 17:49:14 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.h (TC_RELOC_RTSYM_LOC_FIXUP): Changed to keep
+ relocations against globally visible symbols.
+ * config/tc-m68k.c (relaxable_symbol): New macro.
+ (m68k_ip, md_estimate_size_before_relax): Use it.
+ (tc_m68k_fix_adjustable): Also handle weak symbols.
+
+Mon May 4 16:12:23 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.h (TC_RELOC_RTSYM_LOC_FIXUP): Keep relocs for all
+ references to externally visible symbols.
+ * config/tc-i386.c (md_apply_fix3): When OBJ_ELF, don't add the
+ values in twice for a PC relative reloc if the symbol is
+ externally defined.
+
+ * config/tc-sparc.h (tc_fix_adjustable) [OBJ_AOUT]: When PIC,
+ don't adjust a PC relative reloc against an externally visible
+ symbol.
+ * config/tc-sparc.c (md_apply_fix3): When generating a.out PIC,
+ for a PC relative fixup against an externally visible defined
+ symbol, arrange to store object file and addend values as though
+ the symbol were not defined.
+ (tc_gen_reloc): Likewise.
+
+Thu Apr 30 13:09:39 1998 Fred Fish <fnf@ninemoons.com>
+
+ * read.c (sizeof_leb128): Referenced externally by write.c so
+ don't inline.
+
+Wed Apr 29 15:45:57 1998 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-m32r.c ({,expand_}debug_sym): New functions to record
+ and expand a 'debug' symbol associated with the next instruction
+ that does not cause a short instruction to be filled with a NOP.
+ (md_pseudo_table): Add support for .debugsym.
+ (assemble_parallel_insn): Add calls to expand_debug_sym as
+ appropriate.
+ (md_assemble): Ditto.
+
+Tue Apr 28 19:16:26 1998 Tom Tromey <tromey@cygnus.com>
+
+ * as.c (main): Conditionally call setlocale.
+ * gasp.c (main): Likewise.
+ * asintl.h: Include <locale.h> if HAVE_LOCALE_H.
+ (LC_MESSAGES): Now can be defined even when ENABLE_NLS.
+
+Tue Apr 28 18:33:23 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * config/tc-d30v.c (md_show_usage): Correct gettext typo.
+
+Tue Apr 28 12:16:30 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-hppa.c: Change all calls to bzero to use memset.
+ (pa_ip): Add cast to avoid warning.
+ (tc_gen_reloc, md_apply_fix): Likewise.
+ (pa_find_space_by_number): Likewise.
+ (hppa_force_relocation): Likewise.
+ (pa_block): Change i to unsigned int.
+ * config/obj-som.h (obj_som_copyright): Declare.
+
+Tue Apr 28 11:35:56 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * ecoff.c (ecoff_build_lineno): Do not use dummy first_lineno
+ for line numbers for assembly source.
+
+Mon Apr 27 15:58:46 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Change version number to 2.9.4
+ * configure: Rebuild.
+
+Mon Apr 27 12:07:33 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.c (cgen_asm_finish_insn): New arg relax_p. All callers updated.
+
+Mon Apr 27 15:16:12 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.h: Change symbolS in function declaration to struct
+ symbol.
+
+Sun Apr 26 13:44:22 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (parse_reg): Add casts to avoid warnings.
+ (md_convert_frag): Fix i18n typo.
+
+Sat Apr 25 20:12:02 1998 Richard Henderson <rth@cygnus.com>
+
+ * ecoff.c (ecoff_get_cur_proc_sym): New function.
+ * ecoff.h: Protoype it.
+ * config/tc-alpha.c [ELF] (s_alpha_prologue): New function.
+ [EVAX] (s_alpha_prologue): Delete.
+ (md_pseudo_table): Update.
+
+Sat Apr 25 14:00:52 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i960.c (md_assemble): Change bp_error_msg from static
+ array to local pointer.
+ (get_args, parse_expr): Add casts to avoid warnings.
+
+Fri Apr 24 12:47:42 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * read.c (s_set): Cast xmalloc return value to fragS *.
+ * config/tc-m68k.c (m68k_ip): Function made static to match
+ previous forward declaration.
+ (insert_reg, init_regtable, md_convert_frag_1): Likewise.
+
+Fri Apr 24 09:26:46 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c: Add internationalisation macros to error
+ strings.
+
+ * config/tc-m32r.c (can_make_parallel): Add internationalisation
+ macros to error strings.
+
+Thu Apr 23 19:23:23 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_fix_adjustable): Correct test of whether a
+ reloc is in the TOC csect.
+ (md_apply_fix3): Correct gettext typo.
+
+Thu Apr 23 14:58:31 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (find_real_start): Ignore symbols starting with
+ .L - they are local labels and the branches are not really
+ function calls but rather far jumps.
+
+Wed Apr 22 15:57:21 1998 Tom Tromey <tromey@cygnus.com>
+
+ * po/Make-in (MKINSTALLDIRS): Don't look in $(top_srcdir).
+
+Wed Apr 22 14:52:36 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (md_assemble): Print operand number rather than
+ using ordinal_names.
+ (i386_operand): Likewise.
+
+Tue Apr 21 22:34:25 1998 Tom Tromey <tromey@scribbles.cygnus.com>
+
+ * Makefile.am (INTLLIBS): Define to work around apparent automake
+ bug.
+ All Makefiles: Regenerated.
+
+ * Many files: Added gettext invocations around user-visible
+ strings.
+ * acconfig.h (ENABLE_NLS, HAVE_CATGETS, HAVE_GETTEXT, HAVE_STPCPY,
+ HAVE_LC_MESSAGES): Define.
+ * dep-in.sed: Added asintl.h.
+ * po/Make-in: New file.
+ * gasp.c (main): Call setlocale, bindtextdomain, and textdomain.
+ Include "asintl.h".
+ * read.c (Z_): Renamed from `_'.
+ * Makefile.am (SUBDIRS): Added po.
+ (POTFILES): new macro.
+ (po/POTFILES.in): New target.
+ ($(OBJS)): Added asintl.h.
+ (HFILES): Likewise.
+ (INCLUDES): Added -DLOCALEDIR, -I$(top_srcdir)/../intl.
+ (as_new_LDADD): Added $(INTLLIBS).
+ (as_new_DEPENDENCIES): Added $(INTLDEPS).
+ (gasp_new_LDADD): Added $(INTLLIBS).
+ (gasp_new_DEPENDENCIES): New macro.
+ * configure, aclocal.m4: Rebuilt.
+ * configure.in: Call CY_GNU_GETTEXT. Generate po/Makefile.in and
+ po/Makefile.
+ (ALL_LINGUAS): Define.
+ * macro.c: Include "asintl.h".
+ * as.c (main): Call setlocale, bindtextdomain, and textdomain.
+ * as.h: Include "asintl.h".
+ * config/tc-i386.c (ordinal_names): Removed.
+ (md_assemble): Changed error text to avoid ordinal_names.
+ (i386_operand): Likewise.
+ (reloc): Added as_bad to avoid i18n problems.
+ (tc_gen_reloc): Likewise.
+ * config/tc-arm.c (bad_args): Now a #define.
+ (bad_pc): Likewise.
+ * config/obj-vms.c (VMS_stab_parse): Changed type of
+ `long_const_msg'.
+ (global_symbol_directory): Unified strings to avoid i18n
+ problems.
+ * config/tc-m68k.c (get_reloc_code): Added some as_bad calls to
+ avoid i18n problems.
+ * config/tc-ns32k.c (reloc): Added as_bad to avoid i18n problems.
+ * config/tc-ppc.c (md_apply_fix3): Added as_bad_where to avoid
+ i18n problems.
+ * config/tc-sh.c (md_convert_frag): Added as_bad to avoid i18n
+ problems.
+ * config/tc-v850.c (md_assemble): Changed C++ comment into C
+ comment.
+ * config/tc-vax.c (md_assemble): Added as_warn to avoid i18n
+ problems.
+ * as.c (print_version_id): Added an fprintf to avoid i18n
+ problems.
+ * cond.c (cond_finish_check): Added as_bad call to avoid i18n
+ problems.
+ * expr.c (expr): Added as_warn call to avoid i18n problems.
+ * messages.c (as_assert): Changed code to avoid i18n problems.
+ (as_abort): Likewise.
+ * read.c (pseudo_set): Added as_bad call to avoid i18n problems.
+ (s_space): Likewise.
+ * po/Make-in, po/POTFILES.in, po/gas.pot: New files.
+
+Tue Apr 21 17:01:22 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (check_prefix): New static function, split out
+ from md_assemble.
+ (struct _i386_insn): Add wait_prefix field.
+ (md_assemble): Remove wait_prefix local variable. Use
+ check_prefix when adding a prefix.
+
+ * config/tc-i386.c (current_templates): New static variable.
+ (md_assemble): Remove current_templates local variable.
+ (md_assemble, i386_operand): Improve error and warning messages in
+ many places. Add RESTORE_END_STRING in many places before error
+ return. Clarify some comments.
+
+ * config/tc-i386.c (struct _i386_insn): Change seg field to a two
+ element array.
+ (md_assemble): Parse string instruction operands, looking for
+ segment override prefixes. Check for invalid segment prefixes on
+ string instruction.
+ (i386_operand): i.seg[] and max mem_operand changes for string
+ insns.
+ * config/tc-i386.h (EsSeg): Define.
+
+ * config/tc-i386.h (regKludge): Define.
+ (iclrKludge, imulKludge): Don't define.
+ * config/tc-i386.c (md_assemble): Merge imulKludge and iclrKludge
+ code. Move ReverseRegRegmem fudges into Modrm case. Reorder
+ opcode_modifier checks to look for more common cases first. Add
+ default_seg for IsString case.
+
+Tue Apr 21 16:18:12 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Call AM_PROG_LEX rather than AC_PROG_LEX and
+ AC_DECL_YYTEXT.
+ * configure: Rebuild with new automake and libtool.
+ * aclocal.m4, Makefile.in: Likewise.
+
+ * doc/Makefile.am (as.dvi): New target.
+ * doc/Makefile.in: Rebuild.
+
+Sat Apr 18 01:21:04 1998 Stan Cox <scox@cygnus.com>
+
+ * configure.in: Added sparc86x support.
+
+ * configure: Rebuild.
+
+ * config/tc-sparc.c (lookup_arch): Added arch_type to struct
+ sparc_arch.
+ (md_parse_option): Warn if -EL is not supported for this architecture.
+
+ * config/tc-sparc.h (SPARC_BIENDIAN) Always define.
+
+Sat Apr 18 01:19:01 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Note when we use get match on
+ the full instruction name.
+
+Wed Apr 15 15:17:27 1998 Richard Henderson <rth@cygnus.com>
+
+ * symbols.c (resolve_symbol_value) [O_symbol]: Also store the symbol
+ back into the expression to handle add/sub simplification correctly.
+
+Wed Apr 15 07:06:04 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-mips.c (hilo_interlocks): Remove 4300.
+
+Mon Apr 13 16:51:04 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (do_msr): Support undocumented 'msr cpsr_flg,
+ #<n>' instruction.
+
+Thu Apr 9 10:29:42 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * symbols.c (max_indent_level): New global.
+ (print_symbol_value_1): Use it.
+ * expr.h (expr_build_dot): Declare.
+ * expr.c (expr_build_dot): New function.
+
+Wed Apr 8 16:16:11 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * symbols.c (print_binary): New function.
+ (print_expr_1): Call it.
+
+Mon Apr 6 12:06:39 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (m68k_ip, case "#B"): Install the offset of the
+ operand in the opcode.
+
+Fri Apr 3 11:58:19 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.h: Reorder operand flags and opcode modifier
+ flags for clarity. Remove unused definitions: Unknown,
+ ImmUnknown, DispUnknown, NoModrm.
+ * config/tc-i386.c (type_names): Add missing Debug type.
+ (md_assemble): Better duplicate prefix checking. Quicker string
+ instruction check via new opcode_modifier flag.
+
+Fri Apr 3 11:44:34 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo (Invoking): Clarify -Wa example.
+
+Fri Apr 3 09:12:23 1998 Gavin Koch <gavin@cetus.cygnus.com>
+
+ * config/tc-mips.c (mips_pseudo_table): Add weakext entry.
+ (s_mips_weakext): Define.
+ * ecoff.c (ecoff_directive_weakext): Don't define if defined(TC_MIPS).
+ * config/obj-ecoff.c (obj_pseudo_table): Don't add weakext if
+ defined(TC_MIPS).
+
+Thu Apr 2 22:42:02 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (tc_gen_reloc): The difference of two symbols
+ is an error if the value can not be computed at assembly time.
+ * config/tc-mn10300.c (tc_gen-reloc): Likewise.
+
+Thu Apr 2 16:36:47 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * gasp.c (main): Set next field of new include_path structure to
+ NULL. From Avery Pennarun <averyp@gdc.ca>.
+
+ * read.c (s_mri_sect): Call as_bad rather than abort for an
+ unsupported MRI target.
+
+Wed Apr 1 11:08:27 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (arm_validate_fix): New function. Determine if
+ the destination of a branch instruction should be altered.
+ (find_real_start): New function: Locate the real, Thumb coded
+ start of a Thumb function.
+ (do_t_branch23): Alter the destination of branches to Thumb
+ functions.
+
+ * config/tc-arm.h: Define TC_VALIDATE_FIX.
+
+Tue Mar 31 13:27:33 1998 Dean M. Deaver <deaver@amt.tay1.dec.com>
+
+ * config/tc-arm.c (decode_shift): Handle addressing mode 2 w/rrx
+ also.
+
+Wed Apr 1 13:13:20 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * doc/as.texinfo: Use @itemx for a secondary item in a table.
+ * doc/c-hppa.texi: Likewise.
+
+Tue Mar 31 17:52:40 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: Rebuild dependencies.
+ * Makefile.in: Rebuild.
+
+ * Makefile.am (DEP_INCLUDES): New variable.
+ (.dep1): Change to work when srcdir is not an absolute path.
+ (.tcdep, .objdep, .dep2, dep.sed): Likewise.
+ * Makefile.in: Rebuild.
+
+Mon Mar 30 12:46:48 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.h, config/tc-i386.c: Revert March 24
+ LinearAddress patch.
+
+ * configure.in: Set version to 2.9.1.
+ * configure: Rebuild.
+
+ * Branched binutils 2.9.
+
+Mon Mar 30 11:22:08 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.h (FWait): Define.
+ * config/tc-i386.c (md_assemble): Emit fwait prefix before any
+ other prefixes. Check FWait flag in opcode table to see which
+ instructions require an fwait prefix.
+
+Mon Mar 30 10:12:00 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * stabs.c (get_stab_string_offset): Always create a stab string
+ section.
+
+Sat Mar 28 22:28:02 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Fix some gcc -Wall warnings:
+ * atof-generic.c (atof_generic): Add casts to avoid warnings.
+ * ehopt.c (eh_frame_code_alignment): Likewise.
+ * expr.c (integer_constant, operand): Likewise.
+ * frags.c (frag_align): Likewise.
+ * gasp.c (level_0, change_base, doinstr): Likewise.
+ * hash.c (hash_ask): Likewise.
+ * listing.c (listing_page, calc_hex, print_lines): Likewise.
+ (debugging_pseudo): Likewise.
+ * macro.c (define_macro, check_macro): Likewise.
+ * read.c (read_a_source_file, s_align, s_float_space): Likewise.
+ (ignore_rest_of_line, float_cons): Likewise.
+ * symbols.c (decode_local_label_name): Likewise.
+ * write.c (record_alignment, cvs_frag_to_fill): Likewise.
+ (fixup_segment, number_to_chars_bigendian): Likewise.
+ (number_to_chars_littleendian): Likewise.
+ * config/atof-ieee.c (gen_to_words): Likewise.
+ * config/tc-sparc.c (md_begin, md_assemble): Likewise.
+ (sparc_ip, parse_keyword_arg, s_common): Likewise.
+ * read.c (output_big_sleb128): Initialize locals to avoid
+ warnings.
+ (output_big_uleb128, equals): Likewise.
+ * atof-generic.c (atof_generic): Change number_of_digits_* locals
+ to unsigned int. Change zeros to unsigned int.
+ * cond.c (s_if): Add return to default case.
+ * frags.c (frag_now_fix): Change return type to addressT.
+ * frags.h (frag_now_fix): Update declaration.
+ * listing.c (file_info_struct): Change linenum to unsigned int.
+ (struct list_info_struct): Change hll_line to unsigned int.
+ (print_source): Update format string.
+ * read.c (emit_expr): Change scan to unsigned int, and don't
+ bother to initialize it.
+ * symbols.c (dollar_label_count): Change to unsigned long.
+ * write.c (adjust_reloc_syms): Remove unused label reduce_fixup.
+ * config/tc-sparc.c (sparc_memory_model): Only define if OBJ_ELF.
+ * config/tc-sparc.c (tc_gen_reloc): Add return to default case.
+
+Fri Mar 27 12:46:47 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Check legal addressing modes for
+ mcf5200 just as we do for m68000.
+ (m68k_init_after_args): Likewise.
+ (md_estimate_size_before_relax): Likewise.
+
+Fri Mar 27 10:30:01 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-v850.c (md_assemble): Store relocation addend in
+ fixup instead of instruction.
+
+Thu Mar 26 23:07:18 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (md_assemble): Swap template arguments to
+ CONSISTENT_REGISTER_MATCH macro in reverse direction test.
+ This macro is currently symmetric, so passing them the wrong
+ way didn't cause any problem, but may if the macro is changed
+ in the future.
+ After copying template to i.tm, use i.tm. rather than t-> to
+ access fields, and make t a const*
+ Move i.tm.operand_types[] swap to immediately after the copy.
+
+Wed Mar 25 13:44:18 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * expr.h (expr_build_uconstant): Add prototype.
+ (expr_build_unary,expr_build_binary): Add prototypes.
+ * expr.c (expr_build_uconstant): New function.
+ (expr_build_unary,expr_build_binary): New functions.
+
+Wed Mar 25 13:10:42 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de>
+
+ * gasp.c (IS*): Cast argument to unsigned char, not unsigned int.
+ * macro.c (macro_expand_body): Increase buffer size.
+ * messages.c (as_warn): Likewise.
+ (as_warn_where, as_bad, as_bad_where): Likewise.
+
+Wed Mar 25 12:59:07 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patch from H.J. Lu <hjl@gnu.org>:
+ * Makefile.am (DISTSTUFF): New variable.
+ (diststuff): New target.
+ * Makefile.in: Rebuild.
+
+Tue Mar 24 16:51:29 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.h (md_cleanup, md_elf_section_change_hook): Call
+ m32r_elf_section_change_hook.
+
+ * config/tc-m32r.c (m32r_elf_section_change_hook): New function to
+ emit a nop if a section ends with a 16 bit instruction.
+
+Tue Mar 24 19:48:09 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (obj_coff_bss): Compile unconditionally. Call
+ s_lcomm rather than obj_coff_lcomm.
+ (obj_pseudo_table): Compile .bss pseudo-op unconditionally.
+
+Tue Mar 24 18:30:58 1998 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-i386.h (LinearAddress): Define.
+ * config/tc-i386.c (md_assemble): If LinearAddress is set for the
+ instruction, don't use a default segment.
+
+Mon Mar 23 18:53:40 1998 Joel Sherrill <joel@OARcorp.com>
+
+ * configure.in: (sh*-*-rtems*): Switched from ELF to COFF.
+ * configure: Rebuild.
+
+Fri Mar 20 19:15:44 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4, configure: Rebuild with libtool 1.2.
+
+Thu Mar 19 16:03:12 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_apply_fix3): fix code to test the range of
+ PC relative branches. Patch courtesy of Jonathan Walton.
+
+
+Wed Mar 18 09:29:51 1998 Nick Clifton <nickc@cygnus.com>
+
+ * configure.in (emulations): Add thumb-pe target.
+
+ * configure (emulations): Add thumb-pe target.
+
+1998-03-17 Ken Raeburn <raeburn@cygnus.com>
+
+ * itbl-lex.l (yywrap): Don't define if already defined as a
+ macro.
+
+Fri Mar 13 16:31:38 1998 Tom Tromey <tromey@cygnus.com>
+
+ * depend.c (quote_string_for_make): New function.
+ (wrap_output): Use it.
+
+Thu Mar 12 18:28:22 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/obj-elf.c (obj_elf_section): Set bss flag in seg_info
+ structure if type is SHT_NOBITS. [Bug fix courtesy of rth]
+
+Sat Feb 28 17:28:55 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (md_shortopts, md_longopts, md_parse_option):
+ Recognize -GN and -relax.
+ (md_begin): Initialize gp size from -G switch.
+ (alpha_force_relocation): Always force if -relax.
+ (alpha_align): Take a new argument that will specify when to
+ emit an R_ALPHA_ALIGN relocation (though we don't do that now).
+ Change all callers. Emit nop alignment padding as nop+unop pair.
+
+Sat Feb 28 17:06:22 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/obj-elf.c [TC_ALPHA]: Include <elf/alpha.h>.
+ * config/tc-alpha.h (ELF_TC_SPECIAL_SECTIONS): New.
+
+Thu Feb 26 15:49:04 1998 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-d30v.c (write_2_short): Delayed jsr instructions don't
+ require padding to the next long word boundary.
+
+Mon Feb 23 11:29:06 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.c: #include symcat.h.
+ * config/tc-m32r.c: Likewise.
+
+Mon Feb 23 10:27:40 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (mips_ip, case 'P'): Make 'P' arguments be
+ absolute expressions instead of '$' prefixed register names.
+
+Sat Feb 21 22:36:52 1998 Richard Henderson <rth@cygnus.com>
+
+ * read.c (s_set): Record file and line info for symbols when -as.
+ (pseudo_set): Don't overwrite that dummy fragment.
+
+Fri Feb 20 15:03:13 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (md_pseudo_table): Add "section".
+ (ppc_named_section): New static function.
+
+Thu Feb 19 22:25:42 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-ppc.c (ppc_biei): Cache the last symbol we inserted
+ so we don't have to scan the entire list.
+
+Tue Feb 17 17:02:15 1998 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-d30v.c (parallel_ok): For the explicitly parallel
+ case, allow the parallel instructions to modify the same flag
+ bits.
+
+Thu Feb 19 16:08:15 1998 Richard Henderson <rth@cygnus.com>
+
+ * listing.c (list_symbol_table): Categorize symbols by
+ undefined_section rather than sy_frag->line == NULL.
+
+Wed Feb 18 23:39:46 1998 Richard Henderson <rth@cygnus.com>
+
+ * Makefile.am (install-exec-local): Install properly when ln
+ fails or tooldir == prefix.
+
+Tue Feb 17 18:58:51 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.c (cgen_md_apply_fix3): Delete call to validate_operand.
+ Test result of insert_operand for error.
+
+Fri Feb 13 16:41:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Add cygnus.
+ * configure, Makefile.in, aclocal.m4: Rebuild with automake 1.2e.
+ * doc/Makefile.am (AUTOMAKE_OPTIONS): Define.
+ * doc/Makefile.in: Rebuild.
+
+Fri Feb 13 00:47:44 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (macro_build): Handle operand type 'C'.
+ (macro): Fix handling of M_COP[0-3].
+
+Thu Feb 12 14:06:59 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patches from Ross Harvey <ross@teraflop.com>:
+ * macro.c (ISSEP): Only treat '<' and '>' as separator characters
+ if macro_alternate or macro_mri.
+ (getstring): Remove support for byte constants between < and >.
+ (get_any_string): '<' only starts a string if macro_alternate or
+ macro_mri.
+ (macro_expand_body): Permit keyword parameters following
+ positional parameters.
+
+ NetBSD patches from Gordon W. Ross <gwr@mc.com>:
+ * configure.in (alpha*-*-netbsd*): New target.
+ * config/te-nbsd.h (LOCAL_LABELS_FB): Define.
+ * configure: Rebuild.
+
+ * as.h (flag_warn_suppress_instructionswap): Move from here...
+ * config/tc-d10v.c (flag_warn_suppress_instructionswap): ...to
+ here, and make static.
+
+ * ehopt.c (eh_frame_code_alignment): Only use seg_info if
+ BFD_ASSEMBLER or MANY_SEGMENTS.
+
+ * as.c (show_usage): Update bug-gnu-utils address.
+ * gasp.c (show_usage): Likewise.
+ * doc/as.texinfo (Bug Reporting): Likewise.
+
+Wed Feb 11 23:26:28 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (load_address): Don't use mips III or mips IV
+ insns regardless of the size of a pointer if we're in mips I or
+ MIPS II mode.
+ (macro, macro2, s_cprestore, s_cpadd): Likewise.
+
+Thu Feb 12 03:41:00 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ Fix rac to accept only a0:
+ * config/tc-d10v.c (parallel_ok, find_opcode):
+ Split OPERAND_ACC into OPERAND_ACC0 and OPERAND_ACC1.
+ Introduce OPERAND_GPR.
+
+Wed Feb 11 16:28:13 1998 Richard Henderson <rth@cygnus.com>
+
+ * read.c (s_fill): Handle non-constant repeat counts by creating
+ an rs_space fragment.
+
+Tue Feb 10 18:31:31 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (i386_operand): Change error added Jan 2 1998
+ from as_bad to as_warn.
+
+Tue Feb 10 18:04:00 1998 Jim Lemke <jlemke@cygnus.com>
+
+ * as.c: (perform_an_assembly_pass): Use [TEXT|DATA|BSS]_SECTION_NAME
+ * as.h: Define default values of [TEXT|DATA|BSS]_SECTION_NAME
+ * config/obj-elf.c (elf_begin): Use [TEXT|DATA|BSS]_SECTION_NAME
+
+Tue Feb 10 17:58:18 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ehopt.c (eh_frame_code_alignment): If not BFD_ASSEMBLER, use
+ seg_fix_rotP rather than fix_root from seg_info.
+
+Tue Feb 10 15:32:22 1998 Ian Carmichael <iancarm@cygnus.com>
+
+ * expr.c: Add support for 0x1_2_3_4 bignums.
+
+Tue Feb 10 14:43:40 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Change -linux* to -linux-gnu*.
+ * configure: Rebuild.
+
+ * app.c (do_scrub_begin): Treat \r as whitespace.
+
+Mon Feb 9 14:16:11 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: Update dependencies.
+ * Makefile.in: Rebuild.
+
+Sat Feb 7 15:33:51 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure, aclocal.m4: Rebuild with new libtool.
+
+Fri Feb 6 16:08:30 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (md_begin): If mips_cpu is set, then use it as
+ the argument to bfd_set_arch_mach.
+ (load_address): Use bfd_arch_bits_per_address to determine the
+ bit size of an address instead of looking at the isa level.
+ (macro, macro2, s_cprestore, s_cpadd): Likewise.
+
+Fri Feb 6 14:44:34 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_parse_option): Add -mv850any command line option.
+
+Thu Feb 5 12:39:08 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ehopt.c: New file.
+ * as.h (enum _relax_state): Add rs_cfa.
+ (check_eh_frame, eh_frame_estimate_size_before_relax): Declare.
+ (eh_frame_relax_frag, eh_frame_convert_frag): Declare.
+ * read.c (emit_expr): Call check_eh_frame.
+ * write.c (cvt_frag_to_fill): Handle rs_cfa.
+ (relax_segment): Likewise.
+ * Makefile.am: Rebuild dependencies.
+ (GAS_CFILES): Add ehopt.c.
+ (GENERIC_OBJS): Add ehopt.o.
+ * doc/internals.texi (Frags): Document rs_cfa.
+
+ * as.c (show_usage): Mention --traditional-format.
+ (parse_args): Accept --traditional-format.
+ * as.h (flag_traditional_format): Declare.
+ * output-file.c (output_file_create): If flag_traditional_format,
+ set BFD_TRADITIONAL_FORMAT on stdoutput.
+ * doc/as.texinfo, doc/as.1: Document --traditional-format.
+
+ * config/tc-mips.c (append_insn): Make sure that if we have a
+ fixup for an unmatched %hi reloc, it does not associated with a
+ variant frag.
+
+ * configure, Makefile.in, aclocal.m4: Rebuild with new libtool.
+ * doc/Makefile.in: Likewise.
+
+Wed Feb 4 15:41:54 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c (check_for_side_effects): New function.
+ (can_make_parallel): Add checks for instruction side effects
+ clashing with the other instruction.
+ (assemble_parallel_insn): Improve warning messages. Return error
+ message from non-swapped instruction order.
+
+Wed Feb 4 20:00:26 1998 James G. Smith <jsmith@teknema.demon.co.uk>
+
+ * config/tc-arm.c: Rename arm_after_pass_hook() to arm_cleanup().
+
+ * config/tc-arm.h: Replace md_after_pass_hook definition with a
+ md_cleanup definition. This moves the forced literal output to
+ the end of the source pass, and avoids macro's inserting literals
+ into the code immediately after the macro expansion.
+
+Wed Feb 4 13:17:19 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.h (tc_fix_adjustable) [OBJ_ELF]: A reloc against
+ a gas internal symbol is adjustable.
+ * config/tc-ppc.h (tc_fix_adjustable): Likewise.
+
+ * as.h: If gcc version greater than 2.6, use `__format__' and
+ `__printf__' in function attributes, rather than `format' and
+ `printf'.
+
+Mon Feb 2 18:38:18 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c: Only include elf/sparc.h if OBJ_ELF.
+
+Mon Feb 2 18:30:34 1998 Steve Haworth <steve@pm.cse.rmit.EDU.AU>
+
+ Add tms320c30 support:
+ * config/tc-tic30.h: New file.
+ * config/tc-tic30.c: New file.
+ * config/obj-coff.h: If TC_TIC30, include coff/tic30.h and define
+ TARGET_FORMAT as "coff-tic30".
+ * configure.in (tic30-*-*aout*, tic30-*-*coff*): New targets.
+ * Makefile.am: Rebuild dependencies.
+ (CPU_TYPES): Add tic30.
+ (CPU_OBJ_VALID): tic30-aout is valid.
+ (TARGET_CPU_CFILES): Add config/tc-tic30.c.
+ (TARGET_CPU_HFILES): Add config/tc-tic30.h.
+ * configure, Makefile.in: Rebuild.
+
+Mon Feb 2 10:20:37 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_assemble): Improvements to error messages.
+
+Mon Feb 2 12:39:05 1998 Geoff Keating <geoffk@ozemail.com.au>
+
+ * config/tc-ppc.c (md_apply_fix3): Change BFD_RELOC_HI16 and
+ BFD_RELOC_HI16_S to store the high bits of any value.
+
+ * config/tc-ppc.h (tc_fix_adjustable): Undo change of Fri Jun 27.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Don't let the
+ assembler calculate relocations to any external symbol at all.
+ * config/tc-ppc.c (md_apply_fix3) [OBJ_ELF]: Correct bugs
+ involving generation of pc-relative relocs.
+ (md_pcrel_from_section) [OBJ_ELF]: The job this code used to do
+ has been moved to md_apply_fix3.
+
+ * config/tc-ppc.c (md_apply_fix3): Fix test for too-far branch.
+ (ppc_elf_suffix): Warn about 'identifier+constant@got' syntax,
+ which actually means (the address of identifier's GOT entry) +
+ constant, which is not particularly useful.
+
+Fri Jan 30 11:02:35 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * read.h (include_dirs): Declare.
+ (include_dir_count,include_dir_maxlen): Declare.
+
+Fri Jan 30 11:47:02 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Correct check for shared opcodes library.
+ * configure: Rebuild.
+
+ * listing.c (buffer_line): If we can't open the file, set at_end.
+ (listing_print): Remove unused local variable fi.
+
+ * config/m68k-parse.y (reglistpair): Handle register list in
+ either order.
+
+ * config/vms-conf.h: Don't undef VERSION.
+
+Thu Jan 29 14:42:44 1998 Pat Rankin <rankin@eql.caltech.edu>
+
+ * Makefile.am (CONFIG_OBJS): New variable, containing part of old
+ OBJS variable.
+ (GENERIC_OBJS): New variable, with the rest of the old OBJS
+ variable.
+ (OBJS): Now just $(CONFIG_OBJS) and $(GENERIC_OBJS).
+ ($(srcdir)/make-gas.com): Rename from make-gas.com.
+ (stamp-mk.com): Replace $(OBJS) with $(GENERIC_OBJS).
+ (EXTRA_DIST): Define.
+ * vmsconf.sh: Handle {targ-cpu, obj-format, atof-targ} modules
+ explicitly rather than via the list of object files.
+ (gcc-as.opt): New file created when make-gas.com is run.
+ * config-gas.com: Create {targ-cpu.h, obj-format.h, targ-env.h,
+ itbl-cpu.h} to #include appropriate file rather than copying that
+ file.
+ * config/vms-conf.h: Synchronize with current config.in.
+ * Makefile.in: Rebuild.
+
+Thu Jan 29 18:48:19 1998 Bill Moyer <billm@cygnus.com>
+
+ * config/tc-d30v.c (do_assemble): Added flag_explicitly_parallel.
+ (parallel_ok): Relaxed parallel subinstruction dependency check.
+
+Wed Jan 28 14:35:00 1998 Bill Moyer <billm@cygnus.com>
+
+ * as.h (flag_warn_suppress_instructionswap): added new flag.
+ * config/tc-d10v.c (md_parse_option,md_longopts): added "--nowarnswap"
+ command line argument.
+ * config/tc-d10v.c (write_2_short): emit "Swapping instructions"
+ warning only if flag_warn_suppress_instructionswap is false.
+
+Wed Jan 28 16:41:19 1998 J.J. van der Heijden <J.J.vanderHeijden@student.utwente.nl>
+
+ * configure.in (i386-*-mingw32*): New target.
+ * configure: Rebuild.
+
+Wed Jan 28 14:51:18 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (resolve_symbol_value): Don't set the segment if it
+ hasn't changed, and this is OBJ_AOUT without BFD_ASSEMBLER.
+
+ * config/obj-aout.h (S_IS_LOCAL): Correct typo--pass argument to
+ S_GET_SEGMENT.
+
+Wed Jan 28 13:54:50 1998 Pat Rankin <rankin@eql.caltech.edu>
+
+ as.h (unlink): Reverse 13-Feb-97 change; use of unlink vs remove
+ depends upon HAVE_{UNLINK,REMOVE} values rather than host
+ compiler.
+
+Wed Jan 28 13:48:08 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.h (RESOLVE_SYMBOL_REDEFINITION): Define.
+
+Wed Jan 28 09:52:00 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (v850_insert_operand): Display instruction when
+ an error is encountered.
+
+Tue Jan 27 13:32:01 1998 Robert Lipe <robertl@dgii.com>
+
+ * configure.in (i386-*-sco3.2v5*): Defaults to ELF now.
+ (i386-*-sco3.2v5*coff): New target.
+ (i386-*-sco3.2*): New target.
+ * configure: Rebuild.
+
+Tue Jan 27 11:06:52 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c: Tidy error message production.
+
+Tue Jan 27 12:24:32 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-arm.c (md_apply_fix3): Add new variable newimm to hold
+ validate_immediate return value in the right type for comparisons
+ to FAIL.
+
+Tue Jan 27 06:51:59 1998 Richard Henderson <rth@cygnus.com>
+
+ * listing.c (MAX_BYTES): Use listing variables not constants.
+ (data_buffer): No longer an array, but a pointer.
+ (calc_hex): sizeof(data_buffer) -> MAX_BYTES.
+ (listing_listing): Allocate data_buffer.
+
+Tue Jan 27 06:38:35 1998 Richard Henderson <rth@cygnus.com>
+
+ * as.c (parse_args): Add --listing-lhs-width, --listing-lhs-width2,
+ --listing-rhs-width, --listing-cont-lines.
+ (show_usage): Update.
+ * listing.c (listing_lhs_width, listing_lhs_width_second): New vars.
+ (listing_lhs_cont_lines, listing_rhs_width): New vars.
+ (print_lines): Use the variables instead of the constants.
+ (listing_listing): Likewise.
+ * listing.h: Declare the new vars.
+
+Tue Jan 27 05:32:05 1998 Richard Henderson <rth@cygnus.com>
+
+ * as.c (parse_args): Add --keep-locals alias for -L.
+ Add --strip-local-absolute.
+ (show_usage): Update.
+ * as.h (flag_strip_local_absolute): New flag.
+ * symbols.c (S_IS_LOCAL): Use it.
+ * config/obj-aout.h (S_IS_LOCAL): Likewise.
+ * config/obj-bout.h (S_IS_LOCAL): Likewise.
+ * config/obj-coff.h (S_IS_LOCAL): Likewise.
+
+Mon Jan 26 13:07:41 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c: Detect if explicitly parallel instructions
+ might have an io conflict and issue a warning message.
+
+Thu Jan 22 17:51:44 1998 Nick Clifton <nickc@cygnus.com>
+
+ * cgen.c (cgen_save_fixups, cgen_restore_fixups,
+ cgen_swap_fixups): Functions to save, restore and swap the fixup
+ chain with a backup copy.
+ (cgen_asm_finish_insn): Returns address of constructed insn.
+
+Wed Jan 21 16:49:10 1998 Richard Henderson <rth@cygnus.com>
+
+ * listing.c (file_info_struct): Remove FILE, add POS.
+ (last_open_file_info, last_open_file): New; a one entry FILE* cache.
+ (file_info): Don't open the file.
+ (buffer_line): Check for the file in the last_open cache, updating
+ as necessary.
+ (print_source): Don't reference file_info->file.
+ (listing_listing): Likewise.
+ (listing_print): Close the file in the cache, if any.
+
+Fri Jan 16 14:51:48 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (dwarf_file_string): New file static variable.
+ (emit_expr): Look for constant sequence that leads up to a file
+ name in DWARF debugging output.
+ (stringer): Use dwarf_file_string to decide whether to accept a
+ string as a file name.
+
+Fri Jan 16 11:30:37 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Remove absl->reglst MRI hack.
+ (crack_operand): Add reg->reglst MRI hack.
+ (r_seg): Put reglst symbols in reg_section.
+ (m68k_frob_symbol): Frob reglst symbols into absolute_section.
+
+Thu Jan 15 14:19:01 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-sh.c (get_specific): Handle SGR & DBR.
+
+Thu Jan 15 13:46:48 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-h8300.c (parse_reg): Take the length of the symbol into
+ account when attempting to match a register name.
+ * config/tc-h8500.c (parse_reg): Likewise.
+
+Wed Jan 14 17:52:33 1998 Nick Clifton <nickc@cygnus.com>
+
+ * cgen.c: Formatting changes to improve readability.
+
+Wed Jan 14 15:41:41 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (macro): Rework division code to avoid unfilled
+ delay slot.
+
+Wed Jan 14 18:04:20 1998 Michael Meissner <meissner@cygnus.com>
+
+ Based on a patch from Jim Wilson
+ * config/tc-d30v.c (do_assemble): Remove non-ansi default case.
+ (tc_gen_reloc): Handle cross section PC relative relocs
+ correctly.
+
+Wed Jan 14 15:02:19 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * config/tc-mips.c (mips_ip): Don't test pinfo flags if INSN_MACRO.
+
+Mon Jan 12 13:04:57 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.c: #include setjmp.h. Clean up pass over `struct foo' usage.
+ (expr_jmp_buf): New static local.
+ (cgen_parse_operand): Allow use of longjmp in parsing to handle errors.
+ (cgen_md_operand): New function.
+ * config/tc-m32r.c: Clean up pass over `struct foo' usage.
+ (md_estimate_size_before_relax): Use CGEN_INSN_MNEMONIC.
+
+Tue Jan 6 15:36:02 1998 Richard Henderson <rth@cygnus.com>
+
+ * symbols.c (S_SET_SEGMENT): Don't set the segment for section syms.
+ (S_IS_EXTERNAL, S_IS_LOCAL): Correct parenthetication.
+
+Fri Jan 2 16:08:54 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (i386_operand): Give an error if there are
+ unrecognized characters after an expression.
+
+For older changes see ChangeLog-9697
diff --git a/x/binutils/gas/MAINTAINERS b/x/binutils/gas/MAINTAINERS
new file mode 100644
index 0000000..d59a3bd
--- /dev/null
+++ b/x/binutils/gas/MAINTAINERS
@@ -0,0 +1 @@
+See ../binutils/MAINTAINERS
diff --git a/x/binutils/gas/Makefile.am b/x/binutils/gas/Makefile.am
new file mode 100644
index 0000000..7728434
--- /dev/null
+++ b/x/binutils/gas/Makefile.am
@@ -0,0 +1,2481 @@
+## Process this file with automake to generate Makefile.in
+
+## Work around apparent automake bug.
+INTLLIBS = @INTLLIBS@
+
+AUTOMAKE_OPTIONS = 1.8 cygnus dejagnu
+
+SUBDIRS = doc po
+# Automake should figure this out on its own. It doesn't, because
+# of the "cygnus" option. But distclean still wants it.
+DIST_SUBDIRS = $(SUBDIRS)
+
+tooldir = $(exec_prefix)/$(target_alias)
+
+YACC = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L../bison/bison ; else echo @YACC@ ; fi`
+LEX = `if [ -f ../flex/flex ] ; then echo ../flex/flex ; else echo @LEX@ ; fi`
+
+WARN_CFLAGS = @WARN_CFLAGS@
+AM_CFLAGS = $(WARN_CFLAGS)
+
+MKDEP = gcc -MM
+
+TARG_CPU = @target_cpu_type@
+TARG_CPU_C = $(srcdir)/config/tc-@target_cpu_type@.c
+TARG_CPU_O = tc-@target_cpu_type@.o
+TARG_CPU_H = $(srcdir)/config/tc-@target_cpu_type@.h
+OBJ_FORMAT_C = $(srcdir)/config/obj-@obj_format@.c
+OBJ_FORMAT_O = obj-@obj_format@.o
+OBJ_FORMAT_H = $(srcdir)/config/obj-@obj_format@.h
+TARG_ENV_H = $(srcdir)/config/te-@te_file@.h
+ATOF_TARG_C = $(srcdir)/config/atof-@atof@.c
+ATOF_TARG_O = atof-@atof@.o
+
+# use @target_cpu_type@ for refering to configured target name
+IT_HDRS=itbl-parse.h $(srcdir)/itbl-ops.h
+IT_SRCS=itbl-parse.c itbl-lex.c $(srcdir)/itbl-ops.c
+IT_DEPS=$(srcdir)/itbl-parse.y $(srcdir)/itbl-lex.l $(srcdir)/config/itbl-@target_cpu_type@.h
+IT_OBJS=itbl-parse.o itbl-lex.o itbl-ops.o
+
+# CPU types. This is only used for dependency information.
+
+CPU_TYPES = \
+ a29k \
+ alpha \
+ arc \
+ arm \
+ avr \
+ cris \
+ d10v \
+ d30v \
+ dlx \
+ fr30 \
+ frv \
+ h8300 \
+ h8500 \
+ hppa \
+ ia64 \
+ i370 \
+ i386 \
+ i860 \
+ i960 \
+ ip2k \
+ m32r \
+ m68hc11 \
+ m68k \
+ m88k \
+ mcore \
+ mips \
+ mmix \
+ mn10200 \
+ mn10300 \
+ msp430 \
+ ns32k \
+ openrisc \
+ or32 \
+ pdp11 \
+ pj \
+ ppc \
+ s390 \
+ sh \
+ sh64 \
+ sparc \
+ tahoe \
+ tic30 \
+ tic4x \
+ tic54x \
+ tic80 \
+ vax \
+ w65 \
+ v850 \
+ xstormy16 \
+ xtensa \
+ z8k
+
+# Object format types. This is only used for dependency information.
+# We deliberately omit SOM, since it does not work as a cross assembler.
+
+OBJ_FORMATS = \
+ aout \
+ bout \
+ coff \
+ ecoff \
+ elf \
+ evax \
+ hp300 \
+ ieee \
+ vms
+
+# This is an sh case which sets valid according to whether the CPU
+# type in the shell variable c and the OS type in the shell variable o
+# are supported. This helps cuts down on the amount of dependency
+# information.
+
+CPU_OBJ_VALID = \
+ valid= ; \
+ case $$o in \
+ aout) \
+ case $$c in \
+ a29k | arm | cris | i386 | m68k | ns32k | pdp11 | sparc | tahoe | tic30 | vax) \
+ valid=yes ;; \
+ esac ;; \
+ bout) \
+ case $$c in \
+ i960) valid=yes ;; \
+ esac ;; \
+ coff) valid=yes; \
+ case $$c in \
+ cris | i860 | mmix | sh64) \
+ valid= ;; \
+ esac ;; \
+ ecoff) \
+ case $$c in \
+ mips | alpha) valid=yes ;; \
+ esac ;; \
+ elf) valid=yes ;; \
+ evax) \
+ case $$c in \
+ alpha) valid=yes ;; \
+ esac ;; \
+ hp300) \
+ case $$c in \
+ m68k) valid=yes ;; \
+ esac ;; \
+ vms) \
+ case $$c in \
+ vax) valid=yes ;; \
+ esac ;; \
+ esac;
+
+# These are like CPU_TYPES and CPU_OBJ_VALID, for the obj=multi case.
+
+MULTI_CPU_TYPES = i386 mips cris
+
+MULTI_CPU_OBJ_VALID = \
+ valid= ; \
+ case $$o in \
+ aout) \
+ case $$c in \
+ i386 | cris) valid=yes ;; \
+ esac ;; \
+ coff) \
+ case $$c in \
+ i386 | mips) valid=yes ;; \
+ esac ;; \
+ ecoff) \
+ case $$c in \
+ mips) valid=yes ;; \
+ esac ;; \
+ elf) valid=yes ;; \
+ esac;
+
+# Regular source files.
+
+GAS_CFILES = \
+ app.c \
+ as.c \
+ atof-generic.c \
+ bignum-copy.c \
+ cond.c \
+ depend.c \
+ dwarf2dbg.c \
+ dw2gencfi.c \
+ ecoff.c \
+ ehopt.c \
+ expr.c \
+ flonum-copy.c \
+ flonum-konst.c \
+ flonum-mult.c \
+ frags.c \
+ hash.c \
+ input-file.c \
+ input-scrub.c \
+ listing.c \
+ literal.c \
+ macro.c \
+ messages.c \
+ output-file.c \
+ read.c \
+ sb.c \
+ stabs.c \
+ subsegs.c \
+ symbols.c \
+ write.c
+
+CFILES = $(GAS_CFILES) itbl-ops.c
+
+HFILES = \
+ as.h \
+ asintl.h \
+ bignum.h \
+ bit_fix.h \
+ cgen.h \
+ dwarf2dbg.h \
+ dw2gencfi.h \
+ ecoff.h \
+ emul-target.h \
+ emul.h \
+ expr.h \
+ flonum.h \
+ frags.h \
+ hash.h \
+ input-file.h \
+ itbl-ops.h \
+ listing.h \
+ macro.h \
+ obj.h \
+ output-file.h \
+ read.h \
+ sb.h \
+ struc-symbol.h \
+ subsegs.h \
+ symbols.h \
+ tc.h \
+ write.h
+
+# CPU files in config.
+
+TARGET_CPU_CFILES = \
+ config/tc-a29k.c \
+ config/tc-alpha.c \
+ config/tc-arc.c \
+ config/tc-arm.c \
+ config/tc-avr.c \
+ config/tc-cris.c \
+ config/tc-d10v.c \
+ config/tc-d30v.c \
+ config/tc-dlx.c \
+ config/tc-fr30.c \
+ config/tc-frv.c \
+ config/tc-h8300.c \
+ config/tc-h8500.c \
+ config/tc-hppa.c \
+ config/tc-ia64.c \
+ config/tc-i370.c \
+ config/tc-i386.c \
+ config/tc-i860.c \
+ config/tc-i960.c \
+ config/tc-ip2k.c \
+ config/tc-m32r.c \
+ config/tc-m68hc11.c \
+ config/tc-m68k.c \
+ config/tc-m88k.c \
+ config/tc-mcore.c \
+ config/tc-mips.c \
+ config/tc-mmix.c \
+ config/tc-mn10200.c \
+ config/tc-mn10300.c \
+ config/tc-msp430.c \
+ config/tc-ns32k.c \
+ config/tc-openrisc.c \
+ config/tc-or32.c \
+ config/tc-pdp11.c \
+ config/tc-pj.c \
+ config/tc-ppc.c \
+ config/tc-s390.c \
+ config/tc-sh.c \
+ config/tc-sh64.c \
+ config/tc-sparc.c \
+ config/tc-tahoe.c \
+ config/tc-tic30.c \
+ config/tc-tic54x.c \
+ config/tc-tic80.c \
+ config/tc-vax.c \
+ config/tc-w65.c \
+ config/tc-v850.c \
+ config/tc-xstormy16.c \
+ config/tc-xtensa.c \
+ config/tc-z8k.c
+
+TARGET_CPU_HFILES = \
+ config/tc-a29k.h \
+ config/tc-alpha.h \
+ config/tc-arc.h \
+ config/tc-arm.h \
+ config/tc-avr.h \
+ config/tc-cris.h \
+ config/tc-d10v.h \
+ config/tc-d30v.h \
+ config/tc-dlx.h \
+ config/tc-fr30.h \
+ config/tc-frv.h \
+ config/tc-h8300.h \
+ config/tc-h8500.h \
+ config/tc-hppa.h \
+ config/tc-ia64.h \
+ config/tc-i370.h \
+ config/tc-i386.h \
+ config/tc-i860.h \
+ config/tc-i960.h \
+ config/tc-ip2k.h \
+ config/tc-m32r.h \
+ config/tc-m68hc11.h \
+ config/tc-m68k.h \
+ config/tc-m88k.h \
+ config/tc-mcore.h \
+ config/tc-mips.h \
+ config/tc-mmix.h \
+ config/tc-mn10200.h \
+ config/tc-mn10300.h \
+ config/tc-msp430.h \
+ config/tc-ns32k.h \
+ config/tc-openrisc.h \
+ config/tc-or32.h \
+ config/tc-pdp11.h \
+ config/tc-pj.h \
+ config/tc-ppc.h \
+ config/tc-s390.h \
+ config/tc-sh.h \
+ config/tc-sh64.h \
+ config/tc-sparc.h \
+ config/tc-tahoe.h \
+ config/tc-tic30.h \
+ config/tc-tic54x.h \
+ config/tc-tic80.h \
+ config/tc-vax.h \
+ config/tc-w65.h \
+ config/tc-v850.h \
+ config/tc-xstormy16.h \
+ config/tc-xtensa.h \
+ config/tc-z8k.h
+
+# OBJ files in config
+
+OBJ_FORMAT_CFILES = \
+ config/obj-aout.c \
+ config/obj-bout.c \
+ config/obj-coff.c \
+ config/obj-ecoff.c \
+ config/obj-elf.c \
+ config/obj-evax.c \
+ config/obj-hp300.c \
+ config/obj-ieee.c \
+ config/obj-som.c \
+ config/obj-vms.c
+
+OBJ_FORMAT_HFILES = \
+ config/obj-aout.h \
+ config/obj-bout.h \
+ config/obj-coff.h \
+ config/obj-ecoff.h \
+ config/obj-elf.h \
+ config/obj-evax.h \
+ config/obj-hp300.h \
+ config/obj-ieee.h \
+ config/obj-som.h \
+ config/obj-vms.h
+
+# Emulation header files in config
+
+TARG_ENV_HFILES = \
+ config/te-386bsd.h \
+ config/te-aux.h \
+ config/te-delta.h \
+ config/te-delt88.h \
+ config/te-dpx2.h \
+ config/te-dynix.h \
+ config/te-epoc-pe.h \
+ config/te-generic.h \
+ config/te-go32.h \
+ config/te-hp300.h \
+ config/te-hppa.h \
+ config/te-hppa64.h \
+ config/te-hppalinux64.h \
+ config/te-i386aix.h \
+ config/te-ia64aix.h \
+ config/te-ic960.h \
+ config/te-linux.h \
+ config/te-lnews.h \
+ config/te-lynx.h \
+ config/te-mach.h \
+ config/te-macos.h \
+ config/te-nbsd.h \
+ config/te-nbsd532.h \
+ config/te-pc532mach.h \
+ config/te-pe.h \
+ config/te-ppcnw.h \
+ config/te-psos.h \
+ config/te-riscix.h \
+ config/te-sparcaout.h \
+ config/te-sun3.h \
+ config/te-svr4.h \
+ config/te-sysv32.h \
+ config/te-tmips.h
+
+# Multi files in config
+
+MULTI_CFILES = \
+ config/e-crisaout.c \
+ config/e-criself.c \
+ config/e-i386aout.c \
+ config/e-i386coff.c \
+ config/e-i386elf.c \
+ config/e-mipsecoff.c \
+ config/e-mipself.c
+
+CONFIG_OBJS = \
+ $(TARG_CPU_O) \
+ $(OBJ_FORMAT_O) \
+ $(ATOF_TARG_O) \
+ $(extra_objects)
+
+GENERIC_OBJS = \
+ app.o \
+ as.o \
+ atof-generic.o \
+ bignum-copy.o \
+ cond.o \
+ depend.o \
+ dwarf2dbg.o \
+ dw2gencfi.o \
+ ehopt.o \
+ expr.o \
+ flonum-konst.o \
+ flonum-copy.o \
+ flonum-mult.o \
+ frags.o \
+ hash.o \
+ input-file.o \
+ input-scrub.o \
+ literal.o \
+ messages.o \
+ output-file.o \
+ read.o \
+ subsegs.o \
+ symbols.o \
+ write.o \
+ listing.o \
+ ecoff.o \
+ stabs.o \
+ sb.o \
+ macro.o
+
+OBJS = $(CONFIG_OBJS) $(GENERIC_OBJS)
+
+POTFILES = $(MULTI_CFILES) $(TARGET_ENV_HFILES) $(OBJ_FORMAT_HFILES) \
+ $(OBJ_FORMAT_CFILES) $(TARGET_CPU_HFILES) $(TARGET_CPU_CFILES) \
+ $(HFILES) $(CFILES) $(GAS_CFILES)
+po/POTFILES.in: @MAINT@ Makefile
+ for f in $(POTFILES); do echo $$f; done | LC_COLLATE= sort > tmp \
+ && mv tmp $(srcdir)/po/POTFILES.in
+
+# Note: GASP is now deprecated and has been removed. It is still
+# available in the CVS archive or older binutils releases if it is needed.
+noinst_PROGRAMS = as-new
+noinst_SCRIPTS = $(GDBINIT)
+EXTRA_SCRIPTS = .gdbinit
+
+$(srcdir)/make-gas.com: stamp-mk.com
+stamp-mk.com: vmsconf.sh Makefile
+ sh $(srcdir)/vmsconf.sh $(GENERIC_OBJS) > new-make.com
+ $(SHELL) $(srcdir)/../move-if-change new-make.com $(srcdir)/make-gas.com
+ touch stamp-mk.com
+
+EXTRA_DIST = make-gas.com m68k-parse.c itbl-parse.c itbl-parse.h itbl-lex.c
+diststuff: $(EXTRA_DIST) info
+
+DISTCLEANFILES = targ-cpu.h obj-format.h targ-env.h itbl-cpu.h cgen-desc.h
+
+# Now figure out from those variables how to compile and link.
+
+BASEDIR = $(srcdir)/..
+BFDDIR = $(BASEDIR)/bfd
+INCDIR = $(BASEDIR)/include
+
+# This is the variable actually used when we compile.
+# Specify the directories to be searched for header files.
+# Both . and srcdir are used, in that order,
+# so that tm.h and config.h will be found in the compilation
+# subdirectory rather than in the source directory.
+INCLUDES = -D_GNU_SOURCE -I. -I$(srcdir) -I../bfd -I$(srcdir)/config -I$(INCDIR) -I$(srcdir)/.. -I$(BFDDIR) -I$(srcdir)/../intl -I../intl -DLOCALEDIR="\"$(prefix)/share/locale\""
+
+# This should be parallel to INCLUDES, but should replace $(srcdir)
+# with $${srcdir}, and should work in a subdirectory. This is used
+# when building dependencies, because the dependency building is done
+# in a subdirectory.
+DEP_INCLUDES = -D_GNU_SOURCE -I.. -I$${srcdir} -I../../bfd -I$${srcdir}/config -I$${srcdir}/../include -I$${srcdir}/.. -I$${srcdir}/../bfd -I$${srcdir}/../intl -I../../intl -DLOCALEDIR="\"$(prefix)/share/locale\""
+
+DEP_FLAGS = -DBFD_ASSEMBLER -DOBJ_MAYBE_ELF \
+ -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES)
+
+# How to link with both our special library facilities
+# and the system's installed libraries.
+
+GASLIBS = @OPCODES_LIB@ @BFDLIB@ ../libiberty/libiberty.a
+
+# Files to be copied away after each stage in building.
+STAGESTUFF = *.o $(noinst_PROGRAMS)
+
+BFDVER_H = @BFDVER_H@
+
+$(OBJS): @ALL_OBJ_DEPS@
+
+as_new_SOURCES = $(GAS_CFILES)
+as_new_LDADD = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \
+ $(extra_objects) $(GASLIBS) $(INTLLIBS) $(LIBM)
+as_new_DEPENDENCIES = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \
+ $(extra_objects) $(GASLIBS) $(INTLDEPS)
+
+# Stuff that every object file depends upon. If anything is removed
+# from this list, remove it from dep-in.sed as well.
+$(OBJS): $(INCDIR)/bin-bugs.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/progress.h $(INCDIR)/fopen-same.h \
+ $(OBJ_FORMAT_H) $(TARG_CPU_H) $(TARG_ENV_H) \
+ as.h asintl.h bignum.h bit_fix.h config.h emul.h expr.h flonum.h \
+ frags.h hash.h listing.h obj.h read.h symbols.h tc.h write.h
+
+EXPECT = `if [ -f $${rootme}/../expect/expect ] ; then \
+ echo $${rootme}/../expect/expect ; \
+ else echo expect ; fi`
+
+RUNTEST = `if [ -f $${srcdir}/../dejagnu/runtest ] ; then \
+ echo $${srcdir}/../dejagnu/runtest ; else echo runtest; \
+ fi`
+RUNTESTFLAGS=
+
+check-DEJAGNU: site.exp
+ if [ -d testsuite ]; then \
+ true; \
+ else \
+ mkdir testsuite; \
+ fi
+ rm -f testsuite/site.exp
+ cp site.exp testsuite/site.exp
+ rootme=`pwd`; export rootme; \
+ srcdir=`cd ${srcdir}; pwd` ; export srcdir ; \
+ EXPECT=${EXPECT} ; export EXPECT ; \
+ if [ -f $(top_builddir)/../expect/expect ]; then \
+ TCL_LIBRARY=`cd $(top_srcdir)/../tcl/library && pwd`; \
+ export TCL_LIBRARY; \
+ fi; \
+ runtest=$(RUNTEST); \
+ cd testsuite; \
+ if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+ $$runtest --tool $(DEJATOOL) --srcdir $${srcdir}/testsuite \
+ $(RUNTESTFLAGS); \
+ else echo "WARNING: could not find \`runtest'" 1>&2; :;\
+ fi
+
+# The implicit .c.o rule doesn't work for these, perhaps because of
+# the variables, or perhaps because the sources are not on vpath.
+$(TARG_CPU_O): $(TARG_CPU_C)
+ $(COMPILE) -c $(TARG_CPU_C)
+$(ATOF_TARG_O): $(ATOF_TARG_C)
+ $(COMPILE) -c $(ATOF_TARG_C)
+
+# ecoff.c only has full dependencies when ECOFF_DEBUGGING is defined,
+# so the automatic dependency stuff doesn't work.
+ecoff.o : ecoff.c ecoff.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/symconst.h \
+ $(INCDIR)/aout/stab_gnu.h
+
+# We need all these explicit rules for the multi stuff. Because of
+# these rules, we don't need one for OBJ_FORMAT_O.
+
+obj-aout.o : $(srcdir)/config/obj-aout.c
+ $(COMPILE) -c $(srcdir)/config/obj-aout.c
+obj-bout.o : $(srcdir)/config/obj-bout.c
+ $(COMPILE) -c $(srcdir)/config/obj-bout.c
+obj-coff.o: $(srcdir)/config/obj-coff.c
+ $(COMPILE) -c $(srcdir)/config/obj-coff.c
+obj-ecoff.o : $(srcdir)/config/obj-ecoff.c
+ $(COMPILE) -c $(srcdir)/config/obj-ecoff.c
+obj-elf.o : $(srcdir)/config/obj-elf.c
+ $(COMPILE) -c $(srcdir)/config/obj-elf.c
+obj-evax.o : $(srcdir)/config/obj-evax.c
+ $(COMPILE) -c $(srcdir)/config/obj-evax.c
+obj-hp300.o : $(srcdir)/config/obj-hp300.c
+ $(COMPILE) -c $(srcdir)/config/obj-hp300.c
+obj-ieee.o : $(srcdir)/config/obj-ieee.c
+ $(COMPILE) -c $(srcdir)/config/obj-ieee.c
+obj-multi.o : $(srcdir)/config/obj-multi.c
+ $(COMPILE) -c $(srcdir)/config/obj-multi.c
+obj-som.o : $(srcdir)/config/obj-som.c
+ $(COMPILE) -c $(srcdir)/config/obj-som.c
+obj-vms.o : $(srcdir)/config/obj-vms.c
+ $(COMPILE) -c $(srcdir)/config/obj-vms.c
+
+e-mipself.o : $(srcdir)/config/e-mipself.c
+ $(COMPILE) -c $(srcdir)/config/e-mipself.c
+e-mipsecoff.o : $(srcdir)/config/e-mipsecoff.c
+ $(COMPILE) -c $(srcdir)/config/e-mipsecoff.c
+e-i386aout.o: $(srcdir)/config/e-i386aout.c
+ $(COMPILE) -c $(srcdir)/config/e-i386aout.c
+e-i386coff.o: $(srcdir)/config/e-i386coff.c
+ $(COMPILE) -c $(srcdir)/config/e-i386coff.c
+e-i386elf.o: $(srcdir)/config/e-i386elf.c
+ $(COMPILE) -c $(srcdir)/config/e-i386elf.c
+e-crisaout.o: $(srcdir)/config/e-crisaout.c
+ $(COMPILE) -c $(srcdir)/config/e-crisaout.c
+e-criself.o: $(srcdir)/config/e-criself.c
+ $(COMPILE) -c $(srcdir)/config/e-criself.c
+
+xtensa-relax.o: $(srcdir)/config/xtensa-relax.c
+ $(COMPILE) -c $(srcdir)/config/xtensa-relax.c
+
+# The m68k operand parser.
+
+EXTRA_as_new_SOURCES = config/m68k-parse.y
+
+# If m68k-parse.y is in a different directory, then ylwrap will use an
+# absolute path when it invokes yacc, which will cause yacc to put the
+# absolute path into the generated file. That's a pain when it comes
+# to generating snapshots, because it introduces spurious diffs.
+# Since when we make the snapshots $(srcdir) = ".", we check for that
+# case and handle it differently. This means that anybody who
+# configures with $(srcdir) = "." will have to set their path in the
+# debugger if they want to debug m68k-parse.y. This is bad, but on
+# the other hand it's good that people who use the prebuilt
+# m68k-parse.c don't get a spurious absolute path.
+m68k-parse.c: $(srcdir)/config/m68k-parse.y
+ f=$(srcdir)/config/m68k-parse.y; \
+ if [ $$f = "./config/m68k-parse.y" ]; then \
+ ln -s config/m68k-parse.y . > /dev/null 2>/dev/null || \
+ ln config/m68k-parse.y . > /dev/null 2>/dev/null || \
+ cp config/m68k-parse.y . >/dev/null 2>/dev/null; \
+ f=m68k-parse.y; \
+ else true; fi; \
+ $(SHELL) $(YLWRAP) "$(YACC)" $$f y.tab.c m68k-parse.c --; \
+ if [ $$f = "m68k-parse.y" ]; then \
+ rm -f m68k-parse.y; \
+ else true; fi
+m68k-parse.o: m68k-parse.c $(srcdir)/config/m68k-parse.h
+
+# Don't let the .y.h rule clobber m68k-parse.h.
+m68k-parse.h: ; @true
+$(srcdir)/config/m68k-parse.h: ; @true
+
+# The instruction table specification lexical analyzer and parser.
+
+itbl-lex.c: $(srcdir)/itbl-lex.l
+itbl-lex.o: itbl-lex.c itbl-parse.h
+
+itbl-parse.o: itbl-parse.c itbl-parse.h $(srcdir)/itbl-ops.h
+
+itbl-ops.o: $(srcdir)/itbl-ops.c $(srcdir)/itbl-ops.h itbl-parse.h
+
+itbl-parse.c itbl-parse.h: $(srcdir)/itbl-parse.y
+ $(SHELL) $(YLWRAP) "$(YACC)" $(srcdir)/itbl-parse.y y.tab.c itbl-parse.c y.tab.h itbl-parse.h -- -d
+
+# stand-alone itbl assembler & disassembler
+
+EXTRA_PROGRAMS = itbl-test
+itbl_test_SOURCES = itbl-parse.y itbl-lex.l
+itbl_test_LDADD = itbl-tops.o itbl-test.o $(GASLIBS) @LEXLIB@
+
+itbl-tops.o: $(srcdir)/itbl-ops.c $(srcdir)/itbl-ops.h itbl-parse.h
+ $(COMPILE) -o itbl-tops.o -DSTAND_ALONE -c $(srcdir)/itbl-ops.c
+
+itbl-test.o: $(srcdir)/testsuite/gas/all/itbl-test.c $(srcdir)/itbl-ops.h
+ $(COMPILE) -c -DSTAND_ALONE $(srcdir)/testsuite/gas/all/itbl-test.c
+
+# CGEN interface.
+
+CGEN_CPU_PREFIX = @cgen_cpu_prefix@
+
+cgen.o: cgen.c cgen.h cgen-desc.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/$(CGEN_CPU_PREFIX)-desc.h \
+ $(srcdir)/../opcodes/$(CGEN_CPU_PREFIX)-opc.h
+
+# Remake the info files.
+
+MOSTLYCLEANFILES = $(STAGESTUFF) core stamp-mk.com \
+ testsuite/*.o testsuite/*.out testsuite/gas.log testsuite/gas.sum \
+ testsuite/site.exp site.bak site.exp stage stage1 stage2
+
+CLEANFILES = dep.sed DEPTC DEPTCA DEPOBJ DEPOBJA DEP2 DEP2A DEP1 DEPA DEP DEPDIR
+
+.PHONY: install-exec-local install-data-local
+.PHONY: install-exec-bindir install-exec-tooldir
+
+install-exec-local: install-exec-bindir @install_tooldir@
+
+install-exec-bindir: $(noinst_PROGRAMS)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+install-exec-tooldir: install-exec-bindir $(noinst_PROGRAMS)
+ $(mkinstalldirs) $(DESTDIR)$(tooldir)/bin
+ n=`echo as | sed '$(transform)'`; \
+ if [ "$(bindir)/$$n$(EXEEXT)" != "$(tooldir)/bin/as$(EXEEXT)" ]; then \
+ rm -f $(DESTDIR)$(tooldir)/bin/as$(EXEEXT); \
+ ln $(DESTDIR)$(bindir)/$$n$(EXEEXT) $(DESTDIR)$(tooldir)/bin/as$(EXEEXT) >/dev/null 2>/dev/null \
+ || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) as-new$(EXEEXT) $(DESTDIR)$(tooldir)/bin/as$(EXEEXT); \
+ else \
+ true ; \
+ fi
+
+# These exist for maintenance purposes.
+
+.PHONY: bootstrap bootstrap2 bootstrap3 stage1 stage2 stage3 comparison
+
+bootstrap: as-new
+ $(MAKE) stage1
+ rm -f stage && ln -s stage1 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) stage2
+ rm -f stage && ln -s stage2 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) comparison against=stage2
+
+bootstrap2:
+ rm -f stage && ln -s stage1 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) stage2
+ rm -f stage && ln -s stage2 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) comparison against=stage2
+
+bootstrap3:
+ rm -f stage && ln -s stage2 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) comparison against=stage2
+
+# Copy the object files from a particular stage into a subdirectory.
+stage1:
+ -mkdir stage1
+ -mv $(STAGESTUFF) stage1
+ if [ -f stage1/as-new$(EXEEXT) -a ! -f stage1/as$(EXEEXT) ] ; then (cd stage1 ; ln -s as-new$(EXEEXT) as$(EXEEXT)) ; fi
+
+stage2:
+ -mkdir stage2
+ -mv $(STAGESTUFF) stage2
+ if [ -f stage2/as-new$(EXEEXT) -a ! -f stage2/as$(EXEEXT) ] ; then (cd stage2 ; ln -s as-new$(EXEEXT) as$(EXEEXT)) ; fi
+
+stage3:
+ -mkdir stage3
+ -mv $(STAGESTUFF) stage3
+ if [ -f stage3/as-new$(EXEEXT) -a ! -f stage3/as$(EXEEXT) ] ; then (cd stage3 ; ln -s as-new as$(EXEEXT)) ; fi
+
+against=stage2
+
+# This rule is derived from corresponding code in the Makefile.in for gcc.
+# The "tail +16c" is to bypass headers which may include timestamps or
+# temporary assembly file names.
+comparison:
+ x=0 ; \
+ for file in *.o ; do \
+ tail +16c ./$$file > tmp-foo1; \
+ if tail +16c ${against}/$$file > tmp-foo2 2>/dev/null ; then \
+ if cmp tmp-foo1 tmp-foo2 ; then \
+ true ; \
+ else \
+ echo $$file differs ; \
+ x=1 ; \
+ fi ; \
+ else true; fi ; \
+ done ; \
+ exit $$x
+ -rm -f tmp-foo*
+
+.PHONY: de-stage1 de-stage2 de-stage3
+
+de-stage1:
+ - (cd stage1 ; rm -f as$(EXEEXT) ; mv -f * ..)
+ - rmdir stage1
+
+de-stage2:
+ - (cd stage2 ; rm -f as$(EXEEXT) ; mv -f * ..)
+ - rmdir stage2
+
+de-stage3:
+ - (cd stage3 ; rm -f as$(EXEEXT) ; mv -f * ..)
+ - rmdir stage3
+
+DEP_FILE_DEPS = $(CFILES) $(HFILES) $(TARGET_CPU_CFILES) \
+ $(TARGET_CPU_HFILES) $(OBJ_FORMAT_CFILES) $(OBJ_FORMAT_HFILES)
+
+CONFIG_STATUS_DEPENDENCIES = $(BFDDIR)/configure.in
+
+# Automatic dependency computation. This is a real pain, because the
+# dependencies change based on target_cpu_type and obj_format.
+# Just to make things even more complicated, automake separates the
+# dependency variable assignments from the dependency rules, and tacks
+# on a .NOEXPORT at the end of Makefile.in.
+
+DEP: dep.sed $(DEP_FILE_DEPS) DEPTC DEPOBJ DEP2
+ rm -f DEP1 # delete because we use $? in DEP1 rule
+ srcdir=`cd $(srcdir); pwd`; \
+ $(MAKE) MKDEP="$(MKDEP)" srcdir="$${srcdir}" VPATH="$${srcdir}" DEP1
+ rm -rf DEPDIR
+ echo 'AMKDEP = #DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING BELOW.' > DEPA
+ sed -f dep.sed < DEPTC >> DEPA
+ sed -f dep.sed < DEPOBJ >> DEPA
+ sed -f dep.sed < DEP2 >> DEPA
+ echo 'BMKDEP = #DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING ABOVE.' >> DEPA
+ echo '#MKDEP DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING BELOW.' >> DEPA
+ sed -f dep.sed < DEP1 >> DEPA
+ echo '$$(OBJS): $$(DEP_@target''_cpu_type@_@obj''_format@)' >> DEPA
+ echo '$$(TARG_CPU_O): $$(DEPTC_@target''_cpu_type@_@obj''_format@)' >> DEPA
+ echo '$$(OBJ_FORMAT_O): $$(DEPOBJ_@target''_cpu_type@_@obj''_format@)' >> DEPA
+ echo '#MKDEP DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING ABOVE.' >> DEPA
+ if grep ' /' DEPA > /dev/null 2> /dev/null; then \
+ echo 'make DEP failed!'; exit 1; \
+ else \
+ mv -f DEPA $@; \
+ fi
+
+DEP1: $(CFILES) $(MULTI_CFILES)
+ if [ -d DEPDIR ]; then true; else mkdir DEPDIR; fi
+ srcdir=`cd $(srcdir); pwd`; \
+ cd DEPDIR; \
+ echo '' > targ-cpu.h; \
+ echo '' > obj-format.h; \
+ echo '' > targ-env.h; \
+ echo '' > itbl-cpu.h; \
+ echo '' > itbl-parse.h; \
+ $(MKDEP) $(DEP_FLAGS) $? > DEP
+ mv -f DEPDIR/DEP $@
+
+# Work out the special dependencies for the tc-*.c files.
+DEPTC: $(TARGET_CPU_CFILES)
+ rm -f DEPTCA
+ if [ -d DEPDIR ]; then true; else mkdir DEPDIR; fi
+ srcdir=`cd $(srcdir); pwd`; \
+ cd DEPDIR; \
+ for c in $(CPU_TYPES); do \
+ for o in $(OBJ_FORMATS); do \
+ $(CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '#include "tc-'"$${c}"'.h"' > targ-cpu.h; \
+ echo '#include "obj-'"$${o}"'.h"' > obj-format.h; \
+ echo '#include "te-generic.h"' > targ-env.h; \
+ echo '' > itbl-cpu.h; \
+ echo '' > itbl-parse.h; \
+ echo '#include "opcodes/'"$${c}"'-desc.h"' > cgen-desc.h; \
+ rm -f dummy.c; \
+ cp $${srcdir}/config/tc-$${c}.c dummy.c; \
+ $(MKDEP) $(DEP_FLAGS) dummy.c | \
+ sed -e "s/dummy.o: dummy.c/DEPTC_$${c}_$${o} =/" >> ../DEPTCA; \
+ rm -f dummy.c; \
+ else true; fi; \
+ done; \
+ done
+ echo 'DEPTC_hppa_som = $$(srcdir)/config/tc-hppa.h subsegs.h \' >> DEPTCA
+ echo ' $$(INCDIR)/obstack.h $$(BFDDIR)/libhppa.h \' >> DEPTCA
+ echo ' $$(INCDIR)/opcode/hppa.h $$(BFDDIR)/som.h' >> DEPTCA
+ for c in $(MULTI_CPU_TYPES); do \
+ echo "DEPTC_$${c}"'_multi = \' >> DEPTCA; \
+ for o in $(OBJ_FORMATS); do \
+ $(MULTI_CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '$$(DEPTC_'"$${c}_$${o}"') \' >> DEPTCA; \
+ else true; fi; \
+ done; \
+ echo '' >> DEPTCA; \
+ done
+ mv -f DEPTCA DEPTC
+
+# Work out the special dependencies for the obj-*.c files.
+DEPOBJ: $(OBJ_FORMAT_CFILES)
+ rm -f DEPOBJA
+ if [ -d DEPDIR ]; then true; else mkdir DEPDIR; fi
+ srcdir=`cd $(srcdir); pwd`; \
+ cd DEPDIR; \
+ for c in $(CPU_TYPES); do \
+ for o in $(OBJ_FORMATS); do \
+ $(CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '#include "tc-'"$${c}"'.h"' > targ-cpu.h; \
+ echo '#include "obj-'"$${o}"'.h"' > obj-format.h; \
+ echo '#include "te-generic.h"' > targ-env.h; \
+ echo '' > itbl-cpu.h; \
+ echo '' > itbl-parse.h; \
+ rm -f dummy.c; \
+ cp $${srcdir}/config/obj-$${o}.c dummy.c; \
+ $(MKDEP) $(DEP_FLAGS) dummy.c | \
+ sed -e "s/dummy.o: dummy.c/DEPOBJ_$${c}_$${o} =/" >> ../DEPOBJA; \
+ rm -f dummy.c; \
+ else true; fi; \
+ done; \
+ done
+ echo 'DEPOBJ_hppa_som = $$(srcdir)/config/obj-som.h subsegs.h \' >> DEPOBJA
+ echo ' $$(INCDIR)/obstack.h $$(BFDDIR)/libhppa.h \' >> DEPOBJA
+ echo ' $$(BFDDIR)/som.h $$(INCDIR)/aout/stab_gnu.h \' >> DEPOBJA
+ echo ' $$(INCDIR)/aout/stab.def' >> DEPOBJA
+ for c in $(MULTI_CPU_TYPES); do \
+ echo "DEPOBJ_$${c}"'_multi = \' >> DEPOBJA; \
+ for o in $(OBJ_FORMATS); do \
+ $(MULTI_CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '$$(DEPOBJ_'"$${c}_$${o}"') \' >> DEPOBJA; \
+ else true; fi; \
+ done; \
+ echo '' >> DEPOBJA; \
+ done
+ mv -f DEPOBJA DEPOBJ
+
+# Work out the dependencies for each CPU/OBJ combination.
+# Note that SOM is a special case, because it only works native.
+DEP2: $(TARGET_CPU_HFILES) $(OBJ_FORMAT_HFILES)
+ rm -f DEP2A
+ if [ -d DEPDIR ]; then true; else mkdir DEPDIR; fi
+ srcdir=`cd $(srcdir); pwd`; \
+ cd DEPDIR; \
+ for c in $(CPU_TYPES); do \
+ for o in $(OBJ_FORMATS); do \
+ $(CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '#include "tc-'"$${c}"'.h"' > targ-cpu.h; \
+ echo '#include "obj-'"$${o}"'.h"' > dummy.c; \
+ $(MKDEP) $(DEP_FLAGS) dummy.c | \
+ sed -e "s/dummy.o: dummy.c/DEP_$${c}_$${o} =/" >> ../DEP2A; \
+ else true; fi; \
+ done; \
+ done
+ echo 'DEP_hppa_som = $$(BFDDIR)/som.h' >> DEP2A
+ for c in $(MULTI_CPU_TYPES); do \
+ echo "DEP_$${c}"'_multi = \' >> DEP2A; \
+ for o in $(OBJ_FORMATS); do \
+ $(MULTI_CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '$$(DEP_'"$${c}_$${o}"') \' >> DEP2A; \
+ else true; fi; \
+ done; \
+ echo '' >> DEP2A; \
+ done
+ mv -f DEP2A DEP2
+
+dep.sed: dep-in.sed config.status
+ srcdir=`cd $(srcdir); pwd`; \
+ sed <$(srcdir)/dep-in.sed >dep.sed \
+ -e "s!@INCDIR@!$${srcdir}/../include!" \
+ -e "s!@BFDDIR@!$${srcdir}/../bfd!" \
+ -e "s!@SRCDIR@!$${srcdir}!" \
+ -e 's!@TOPDIR@!'`echo $(srcdir) | sed -e s,/gas,,`'!'
+
+dep: DEP
+ sed -e '/^.MKDEP.*WARNING BELOW./,/^.MKDEP.*WARNING ABOVE./d' \
+ < Makefile > tmp-Makefile
+ cat DEP >> tmp-Makefile
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile Makefile
+
+dep-in: DEP
+ sed -e '/^.MKDEP.*WARNING BELOW./,/^.MKDEP.*WARNING ABOVE./d' \
+ < $(srcdir)/Makefile.in > tmp-Makefile.in
+ cat DEP >> tmp-Makefile.in
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in
+
+dep-am: DEP
+ sed -e '/^.MKDEP.*WARNING BELOW./,/^.MKDEP.*WARNING ABOVE./d' \
+ < $(srcdir)/Makefile.am > tmp-Makefile.am
+ cat DEP >> tmp-Makefile.am
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am
+
+# HEED THE MKDEP WARNINGS.
+# ANYTHING CHANGED OR ADDED BETWEEN THE WARNING LINES MAY GO AWAY.
+.PHONY: dep dep-in dep-am
+
+AMKDEP = #DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING BELOW.
+DEPTC_a29k_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-a29k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/a29k.h
+DEPTC_a29k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-a29k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/a29k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/a29k.h
+DEPTC_a29k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-a29k.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/a29k.h
+DEPTC_alpha_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-alpha.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h ecoff.h $(INCDIR)/opcode/alpha.h $(INCDIR)/safe-ctype.h \
+ $(srcdir)/config/atof-vax.c
+DEPTC_alpha_ecoff = $(INCDIR)/symcat.h $(srcdir)/config/obj-ecoff.h \
+ $(srcdir)/config/tc-alpha.h ecoff.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h $(INCDIR)/opcode/alpha.h $(INCDIR)/safe-ctype.h \
+ $(srcdir)/config/atof-vax.c
+DEPTC_alpha_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-alpha.h \
+ subsegs.h $(INCDIR)/obstack.h struc-symbol.h ecoff.h \
+ $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h $(INCDIR)/opcode/alpha.h \
+ $(INCDIR)/elf/alpha.h $(INCDIR)/elf/reloc-macros.h \
+ dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/safe-ctype.h \
+ $(srcdir)/config/atof-vax.c
+DEPTC_alpha_evax = $(INCDIR)/symcat.h $(srcdir)/config/obj-evax.h \
+ $(srcdir)/config/tc-alpha.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h ecoff.h $(INCDIR)/opcode/alpha.h $(INCDIR)/safe-ctype.h \
+ $(srcdir)/config/atof-vax.c
+DEPTC_arc_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-arc.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h struc-symbol.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/arc.h $(srcdir)/../opcodes/arc-ext.h \
+ $(INCDIR)/elf/arc.h $(INCDIR)/elf/reloc-macros.h dwarf2dbg.h
+DEPTC_arc_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arc.h \
+ struc-symbol.h $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/arc.h $(srcdir)/../opcodes/arc-ext.h \
+ $(INCDIR)/elf/arc.h $(INCDIR)/elf/reloc-macros.h dwarf2dbg.h
+DEPTC_arm_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-arm.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h
+DEPTC_arm_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-arm.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/arm.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h subsegs.h \
+ $(INCDIR)/obstack.h
+DEPTC_arm_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arm.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h dwarf2dbg.h
+DEPTC_avr_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-avr.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/avr.h
+DEPTC_avr_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-avr.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/avr.h
+DEPTC_cris_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-cris.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/cris.h dwarf2dbg.h
+DEPTC_cris_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-cris.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/cris.h dwarf2dbg.h
+DEPTC_d10v_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-d10v.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/d10v.h \
+ $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h
+DEPTC_d10v_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d10v.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/d10v.h $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h
+DEPTC_d30v_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-d30v.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/d30v.h
+DEPTC_d30v_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d30v.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/d30v.h
+DEPTC_dlx_coff = $(INCDIR)/safe-ctype.h $(INCDIR)/symcat.h \
+ $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-dlx.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/opcode/dlx.h
+DEPTC_dlx_elf = $(INCDIR)/safe-ctype.h $(INCDIR)/symcat.h \
+ $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(srcdir)/config/tc-dlx.h $(INCDIR)/opcode/dlx.h
+DEPTC_fr30_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-fr30.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/fr30-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/fr30-opc.h \
+ cgen.h
+DEPTC_fr30_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-fr30.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/fr30-desc.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/fr30-opc.h cgen.h
+DEPTC_frv_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-frv.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/frv-desc.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/frv-opc.h cgen.h $(BFDDIR)/libbfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/frv.h $(INCDIR)/elf/reloc-macros.h
+DEPTC_frv_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-frv.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/frv-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/frv-opc.h \
+ cgen.h $(BFDDIR)/libbfd.h $(INCDIR)/elf/frv.h $(INCDIR)/elf/reloc-macros.h
+DEPTC_h8300_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-h8300.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/h8300.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h dwarf2dbg.h \
+ $(INCDIR)/opcode/h8300.h $(INCDIR)/safe-ctype.h
+DEPTC_h8300_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8300.h \
+ subsegs.h $(INCDIR)/obstack.h dwarf2dbg.h $(INCDIR)/opcode/h8300.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/elf/h8.h $(INCDIR)/elf/reloc-macros.h
+DEPTC_h8500_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-h8500.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/h8500.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/h8500-opc.h \
+ $(INCDIR)/safe-ctype.h
+DEPTC_h8500_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8500.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/h8500-opc.h \
+ $(INCDIR)/safe-ctype.h
+DEPTC_hppa_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-hppa.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(BFDDIR)/libhppa.h $(INCDIR)/opcode/hppa.h
+DEPTC_hppa_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-hppa.h \
+ $(BFDDIR)/elf32-hppa.h $(BFDDIR)/libhppa.h $(INCDIR)/elf/hppa.h \
+ $(INCDIR)/elf/reloc-macros.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/hppa.h \
+ dwarf2dbg.h
+DEPTC_ia64_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-ia64.h $(INCDIR)/opcode/ia64.h \
+ $(INCDIR)/elf/ia64.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ dwarf2dbg.h subsegs.h $(INCDIR)/obstack.h
+DEPTC_ia64_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ia64.h \
+ $(INCDIR)/opcode/ia64.h $(INCDIR)/elf/ia64.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/safe-ctype.h dwarf2dbg.h subsegs.h $(INCDIR)/obstack.h
+DEPTC_i370_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-i370.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h struc-symbol.h $(INCDIR)/opcode/i370.h
+DEPTC_i370_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i370.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h $(INCDIR)/opcode/i370.h $(INCDIR)/elf/i370.h \
+ $(INCDIR)/elf/reloc-macros.h
+DEPTC_i386_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-i386.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/i386.h
+DEPTC_i386_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-i386.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/i386.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h subsegs.h \
+ $(INCDIR)/obstack.h dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h \
+ $(INCDIR)/opcode/i386.h
+DEPTC_i386_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i386.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/i386.h
+DEPTC_i860_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i860.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/i860.h $(INCDIR)/elf/i860.h $(INCDIR)/elf/reloc-macros.h
+DEPTC_i960_bout = $(INCDIR)/symcat.h $(srcdir)/config/obj-bout.h \
+ $(srcdir)/config/tc-i960.h $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/i960.h
+DEPTC_i960_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-i960.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/i960.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h $(INCDIR)/opcode/i960.h
+DEPTC_i960_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h $(INCDIR)/opcode/i960.h
+DEPTC_ip2k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-ip2k.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/ip2k-desc.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/ip2k-opc.h cgen.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/ip2k.h $(INCDIR)/elf/reloc-macros.h $(BFDDIR)/libbfd.h
+DEPTC_ip2k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ip2k.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/ip2k-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/ip2k-opc.h \
+ cgen.h $(INCDIR)/elf/ip2k.h $(INCDIR)/elf/reloc-macros.h \
+ $(BFDDIR)/libbfd.h
+DEPTC_m32r_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-m32r.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/m32r-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/m32r-opc.h \
+ cgen.h
+DEPTC_m32r_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32r.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/m32r-desc.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/m32r-opc.h cgen.h
+DEPTC_m68hc11_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-m68hc11.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/m68k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/m68hc11.h dwarf2dbg.h \
+ $(INCDIR)/elf/m68hc11.h $(INCDIR)/elf/reloc-macros.h
+DEPTC_m68hc11_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68hc11.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/m68hc11.h dwarf2dbg.h $(INCDIR)/elf/m68hc11.h \
+ $(INCDIR)/elf/reloc-macros.h
+DEPTC_m68k_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-m68k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h subsegs.h \
+ dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/m68k.h \
+ $(srcdir)/config/m68k-parse.h
+DEPTC_m68k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-m68k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/m68k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h \
+ subsegs.h dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h \
+ $(INCDIR)/opcode/m68k.h $(srcdir)/config/m68k-parse.h
+DEPTC_m68k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68k.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h subsegs.h \
+ dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/m68k.h \
+ $(srcdir)/config/m68k-parse.h $(INCDIR)/elf/m68k.h \
+ $(INCDIR)/elf/reloc-macros.h
+DEPTC_m68k_hp300 = $(INCDIR)/symcat.h $(srcdir)/config/obj-hp300.h \
+ $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/obstack.h subsegs.h dwarf2dbg.h dw2gencfi.h \
+ $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/m68k.h $(srcdir)/config/m68k-parse.h
+DEPTC_m88k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-m88k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/m88k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h subsegs.h \
+ $(INCDIR)/obstack.h $(srcdir)/config/m88k-opcode.h
+DEPTC_m88k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m88k.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/config/m88k-opcode.h
+DEPTC_mcore_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-mcore.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/mcore.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/mcore-opc.h \
+ $(INCDIR)/safe-ctype.h
+DEPTC_mcore_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mcore.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/mcore-opc.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/elf/mcore.h $(INCDIR)/elf/reloc-macros.h
+DEPTC_mips_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-mips.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/opcode/mips.h itbl-ops.h dwarf2dbg.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+DEPTC_mips_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-mips.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/mipspe.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/opcode/mips.h itbl-ops.h dwarf2dbg.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+DEPTC_mips_ecoff = $(INCDIR)/symcat.h $(srcdir)/config/obj-ecoff.h \
+ $(srcdir)/config/tc-mips.h ecoff.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/mips.h itbl-ops.h \
+ dwarf2dbg.h $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h
+DEPTC_mips_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mips.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/opcode/mips.h itbl-ops.h dwarf2dbg.h $(INCDIR)/elf/mips.h \
+ $(INCDIR)/elf/reloc-macros.h ecoff.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h
+DEPTC_mmix_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mmix.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/elf/mmix.h \
+ $(INCDIR)/elf/reloc-macros.h $(INCDIR)/opcode/mmix.h \
+ $(INCDIR)/safe-ctype.h dwarf2dbg.h
+DEPTC_mn10200_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-mn10200.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10200.h
+DEPTC_mn10200_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10200.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/mn10200.h
+DEPTC_mn10300_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-mn10300.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10300.h \
+ dwarf2dbg.h
+DEPTC_mn10300_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10300.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/mn10300.h dwarf2dbg.h
+DEPTC_msp430_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-msp430.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/msp430.h $(INCDIR)/safe-ctype.h
+DEPTC_msp430_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-msp430.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/msp430.h \
+ $(INCDIR)/safe-ctype.h
+DEPTC_ns32k_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-ns32k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/opcode/ns32k.h $(INCDIR)/obstack.h
+DEPTC_ns32k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-ns32k.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/ns32k.h \
+ $(INCDIR)/obstack.h
+DEPTC_ns32k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ns32k.h \
+ $(INCDIR)/opcode/ns32k.h $(INCDIR)/obstack.h
+DEPTC_openrisc_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-openrisc.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/openrisc-desc.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/openrisc-opc.h cgen.h
+DEPTC_openrisc_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-openrisc.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/openrisc-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/openrisc-opc.h \
+ cgen.h
+DEPTC_or32_coff = $(INCDIR)/safe-ctype.h $(INCDIR)/symcat.h \
+ $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-or32.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/or32.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/opcode/or32.h $(INCDIR)/elf/or32.h \
+ $(INCDIR)/elf/reloc-macros.h
+DEPTC_or32_elf = $(INCDIR)/safe-ctype.h $(INCDIR)/symcat.h \
+ $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(srcdir)/config/tc-or32.h $(INCDIR)/opcode/or32.h \
+ $(INCDIR)/elf/or32.h $(INCDIR)/elf/reloc-macros.h
+DEPTC_pdp11_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-pdp11.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/pdp11.h
+DEPTC_pdp11_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-pdp11.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/opcode/pdp11.h
+DEPTC_pdp11_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-pdp11.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/pdp11.h
+DEPTC_pj_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-pj.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/opcode/pj.h
+DEPTC_pj_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-pj.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/pj.h
+DEPTC_ppc_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-ppc.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/rs6000.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/ppc.h
+DEPTC_ppc_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ppc.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/ppc.h \
+ $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h dwarf2dbg.h
+DEPTC_s390_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-s390.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h struc-symbol.h dwarf2dbg.h \
+ dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/s390.h \
+ $(INCDIR)/elf/s390.h $(INCDIR)/elf/reloc-macros.h
+DEPTC_s390_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-s390.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h \
+ $(INCDIR)/opcode/s390.h $(INCDIR)/elf/s390.h $(INCDIR)/elf/reloc-macros.h
+DEPTC_sh_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-sh.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/sh.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/sh-opc.h \
+ $(INCDIR)/safe-ctype.h struc-symbol.h dwarf2dbg.h dw2gencfi.h
+DEPTC_sh_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/sh-opc.h \
+ $(INCDIR)/safe-ctype.h struc-symbol.h $(INCDIR)/elf/sh.h \
+ $(INCDIR)/elf/reloc-macros.h dwarf2dbg.h dw2gencfi.h
+DEPTC_sh64_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh64.h \
+ $(srcdir)/config/tc-sh.h $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h \
+ $(BFDDIR)/elf32-sh64.h $(INCDIR)/safe-ctype.h $(srcdir)/../opcodes/sh64-opc.h \
+ $(srcdir)/config/tc-sh.c subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/sh-opc.h struc-symbol.h dwarf2dbg.h dw2gencfi.h
+DEPTC_sparc_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-sparc.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/sparc.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h
+DEPTC_sparc_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-sparc.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/sparc.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/sparc.h dw2gencfi.h \
+ $(INCDIR)/elf/dwarf2.h
+DEPTC_sparc_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sparc.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/sparc.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h \
+ $(INCDIR)/elf/sparc.h $(INCDIR)/elf/reloc-macros.h \
+ dwarf2dbg.h
+DEPTC_tahoe_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-tahoe.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h $(INCDIR)/opcode/tahoe.h
+DEPTC_tahoe_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tahoe.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/tahoe.h
+DEPTC_tahoe_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tahoe.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h $(INCDIR)/opcode/tahoe.h
+DEPTC_tic30_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-tic30.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/tic30.h
+DEPTC_tic30_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tic30.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/tic30.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/tic30.h
+DEPTC_tic30_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic30.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/tic30.h
+DEPTC_tic4x_coff = $(INCDIR)/safe-ctype.h $(INCDIR)/symcat.h \
+ $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic4x.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic4x.h $(INCDIR)/coff/ti.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/tic4x.h \
+ subsegs.h $(INCDIR)/obstack.h
+DEPTC_tic4x_elf = $(INCDIR)/safe-ctype.h $(INCDIR)/symcat.h \
+ $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(srcdir)/config/tc-tic4x.h $(INCDIR)/opcode/tic4x.h \
+ subsegs.h $(INCDIR)/obstack.h
+DEPTC_tic54x_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tic54x.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/tic54x.h $(INCDIR)/coff/ti.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h sb.h macro.h \
+ subsegs.h $(INCDIR)/obstack.h struc-symbol.h $(INCDIR)/opcode/tic54x.h
+DEPTC_tic54x_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic54x.h \
+ $(INCDIR)/safe-ctype.h sb.h macro.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h $(INCDIR)/opcode/tic54x.h $(srcdir)/config/obj-coff.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic54x.h $(INCDIR)/coff/ti.h \
+ $(BFDDIR)/libcoff.h
+DEPTC_tic80_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tic80.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/tic80.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/tic80.h
+DEPTC_tic80_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic80.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/tic80.h
+DEPTC_vax_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-vax.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(srcdir)/config/vax-inst.h $(INCDIR)/obstack.h subsegs.h \
+ $(INCDIR)/opcode/vax.h $(INCDIR)/safe-ctype.h
+DEPTC_vax_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-vax.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(srcdir)/config/vax-inst.h \
+ $(INCDIR)/obstack.h subsegs.h $(INCDIR)/opcode/vax.h \
+ $(INCDIR)/safe-ctype.h
+DEPTC_vax_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-vax.h \
+ $(srcdir)/config/vax-inst.h $(INCDIR)/obstack.h subsegs.h \
+ $(INCDIR)/elf/vax.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/opcode/vax.h \
+ $(INCDIR)/safe-ctype.h
+DEPTC_vax_vms = $(INCDIR)/symcat.h $(srcdir)/config/obj-vms.h \
+ $(srcdir)/config/tc-vax.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(srcdir)/config/vax-inst.h \
+ $(INCDIR)/obstack.h subsegs.h $(INCDIR)/opcode/vax.h \
+ $(INCDIR)/safe-ctype.h
+DEPTC_w65_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-w65.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/w65.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/w65-opc.h
+DEPTC_w65_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-w65.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/w65-opc.h
+DEPTC_v850_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-v850.h $(INCDIR)/elf/v850.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/v850.h dwarf2dbg.h
+DEPTC_v850_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-v850.h \
+ $(INCDIR)/elf/v850.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/v850.h \
+ dwarf2dbg.h
+DEPTC_xstormy16_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-xstormy16.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/xstormy16-desc.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/xstormy16-opc.h cgen.h
+DEPTC_xstormy16_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xstormy16.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/xstormy16-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/xstormy16-opc.h \
+ cgen.h
+DEPTC_xtensa_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xtensa.h \
+ $(INCDIR)/xtensa-config.h sb.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/config/xtensa-relax.h \
+ $(INCDIR)/xtensa-isa.h $(srcdir)/config/xtensa-istack.h \
+ dwarf2dbg.h struc-symbol.h
+DEPTC_z8k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-z8k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/z8k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h $(srcdir)/../opcodes/z8k-opc.h
+DEPTC_z8k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-z8k.h \
+ $(INCDIR)/safe-ctype.h $(srcdir)/../opcodes/z8k-opc.h
+DEPTC_hppa_som = $(srcdir)/config/tc-hppa.h subsegs.h \
+ $(INCDIR)/obstack.h $(BFDDIR)/libhppa.h $(INCDIR)/opcode/hppa.h \
+ $(BFDDIR)/som.h
+DEPTC_i386_multi = $(DEPTC_i386_aout) $(DEPTC_i386_coff) \
+ $(DEPTC_i386_elf)
+DEPTC_mips_multi = $(DEPTC_mips_coff) $(DEPTC_mips_ecoff) \
+ $(DEPTC_mips_elf)
+DEPTC_cris_multi = $(DEPTC_cris_aout) $(DEPTC_cris_elf)
+DEPOBJ_a29k_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-a29k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+DEPOBJ_a29k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-a29k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/a29k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_a29k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-a29k.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_alpha_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-alpha.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_alpha_ecoff = $(INCDIR)/symcat.h $(srcdir)/config/obj-ecoff.h \
+ $(srcdir)/config/tc-alpha.h ecoff.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(BFDDIR)/libecoff.h
+DEPOBJ_alpha_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-alpha.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h ecoff.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/elf/alpha.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/aout/aout64.h
+DEPOBJ_alpha_evax = $(INCDIR)/symcat.h $(srcdir)/config/obj-evax.h \
+ $(srcdir)/config/tc-alpha.h
+DEPOBJ_arc_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-arc.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_arc_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arc.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_arm_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-arm.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+DEPOBJ_arm_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-arm.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/arm.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_arm_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arm.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_avr_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-avr.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_avr_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-avr.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_cris_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-cris.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+DEPOBJ_cris_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-cris.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_d10v_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-d10v.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_d10v_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d10v.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_d30v_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-d30v.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_d30v_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d30v.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_dlx_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-dlx.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_dlx_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-dlx.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_fr30_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-fr30.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_fr30_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-fr30.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_frv_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-frv.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_frv_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-frv.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_h8300_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-h8300.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/h8300.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_h8300_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8300.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_h8500_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-h8500.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/h8500.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_h8500_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8500.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_hppa_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-hppa.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_hppa_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-hppa.h \
+ $(BFDDIR)/elf32-hppa.h $(BFDDIR)/libhppa.h $(INCDIR)/elf/hppa.h \
+ $(INCDIR)/elf/reloc-macros.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h struc-symbol.h dwarf2dbg.h \
+ $(INCDIR)/aout/aout64.h
+DEPOBJ_ia64_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-ia64.h $(INCDIR)/opcode/ia64.h \
+ $(INCDIR)/elf/ia64.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_ia64_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ia64.h \
+ $(INCDIR)/opcode/ia64.h $(INCDIR)/elf/ia64.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_i370_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-i370.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_i370_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i370.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/elf/i370.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/aout/aout64.h
+DEPOBJ_i386_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-i386.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+DEPOBJ_i386_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-i386.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/i386.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_i386_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i386.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_i860_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i860.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_i960_bout = $(INCDIR)/symcat.h $(srcdir)/config/obj-bout.h \
+ $(srcdir)/config/tc-i960.h $(INCDIR)/obstack.h
+DEPOBJ_i960_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-i960.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/i960.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_i960_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_ip2k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-ip2k.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_ip2k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ip2k.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_m32r_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-m32r.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_m32r_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32r.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_m68hc11_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-m68hc11.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/m68k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_m68hc11_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68hc11.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_m68k_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-m68k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+DEPOBJ_m68k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-m68k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/m68k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_m68k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68k.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_m68k_hp300 = $(srcdir)/config/obj-aout.c $(INCDIR)/symcat.h \
+ $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+DEPOBJ_m88k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-m88k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/m88k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_m88k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m88k.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_mcore_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-mcore.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/mcore.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_mcore_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mcore.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_mips_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-mips.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+DEPOBJ_mips_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-mips.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/mipspe.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_mips_ecoff = $(INCDIR)/symcat.h $(srcdir)/config/obj-ecoff.h \
+ $(srcdir)/config/tc-mips.h ecoff.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(BFDDIR)/libecoff.h
+DEPOBJ_mips_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mips.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h ecoff.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/aout/aout64.h
+DEPOBJ_mmix_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mmix.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_mn10200_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-mn10200.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_mn10200_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10200.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_mn10300_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-mn10300.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_mn10300_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10300.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_msp430_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-msp430.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_msp430_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-msp430.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_ns32k_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-ns32k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+DEPOBJ_ns32k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-ns32k.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_ns32k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ns32k.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_openrisc_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-openrisc.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_openrisc_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-openrisc.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_or32_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-or32.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/or32.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_or32_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-or32.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_pdp11_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-pdp11.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+DEPOBJ_pdp11_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-pdp11.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_pdp11_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-pdp11.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_pj_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-pj.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_pj_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-pj.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_ppc_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-ppc.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/rs6000.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_ppc_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ppc.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/aout/aout64.h
+DEPOBJ_s390_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-s390.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_s390_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-s390.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_sh_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-sh.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/sh.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_sh_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_sh64_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh64.h \
+ $(srcdir)/config/tc-sh.h $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h \
+ $(BFDDIR)/elf32-sh64.h $(INCDIR)/safe-ctype.h subsegs.h \
+ $(INCDIR)/obstack.h struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_sparc_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-sparc.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+DEPOBJ_sparc_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-sparc.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/sparc.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_sparc_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sparc.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_tahoe_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-tahoe.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+DEPOBJ_tahoe_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tahoe.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_tahoe_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tahoe.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_tic30_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-tic30.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+DEPOBJ_tic30_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tic30.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/tic30.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_tic30_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic30.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_tic4x_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tic4x.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/tic4x.h $(INCDIR)/coff/ti.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_tic4x_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic4x.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_tic54x_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tic54x.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/tic54x.h $(INCDIR)/coff/ti.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_tic54x_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic54x.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_tic80_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tic80.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/tic80.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_tic80_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic80.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_vax_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-vax.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+DEPOBJ_vax_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-vax.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_vax_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_vax_vms = $(INCDIR)/symcat.h $(srcdir)/config/obj-vms.h \
+ $(srcdir)/config/tc-vax.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/safe-ctype.h subsegs.h \
+ $(INCDIR)/obstack.h
+DEPOBJ_w65_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-w65.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/w65.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_w65_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-w65.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_v850_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-v850.h $(INCDIR)/elf/v850.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_v850_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-v850.h \
+ $(INCDIR)/elf/v850.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h struc-symbol.h dwarf2dbg.h \
+ $(INCDIR)/aout/aout64.h
+DEPOBJ_xstormy16_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-xstormy16.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+DEPOBJ_xstormy16_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xstormy16.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_xtensa_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xtensa.h \
+ $(INCDIR)/xtensa-config.h $(INCDIR)/safe-ctype.h subsegs.h \
+ $(INCDIR)/obstack.h struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_z8k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-z8k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/z8k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+DEPOBJ_z8k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-z8k.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_hppa_som = $(srcdir)/config/obj-som.h subsegs.h \
+ $(INCDIR)/obstack.h $(BFDDIR)/libhppa.h $(BFDDIR)/som.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+DEPOBJ_i386_multi = $(DEPOBJ_i386_aout) $(DEPOBJ_i386_coff) \
+ $(DEPOBJ_i386_elf)
+DEPOBJ_mips_multi = $(DEPOBJ_mips_coff) $(DEPOBJ_mips_ecoff) \
+ $(DEPOBJ_mips_elf)
+DEPOBJ_cris_multi = $(DEPOBJ_cris_aout) $(DEPOBJ_cris_elf)
+DEP_a29k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-a29k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_a29k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-a29k.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/a29k.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_a29k_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-a29k.h
+DEP_alpha_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-alpha.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_alpha_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-alpha.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+DEP_alpha_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-alpha.h
+DEP_alpha_evax = $(srcdir)/config/obj-evax.h $(srcdir)/config/tc-alpha.h
+DEP_arc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arc.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_arc_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arc.h
+DEP_arm_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-arm.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_arm_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arm.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/arm.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_arm_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arm.h
+DEP_avr_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-avr.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_avr_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-avr.h
+DEP_cris_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-cris.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_cris_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-cris.h
+DEP_d10v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d10v.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_d10v_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d10v.h
+DEP_d30v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d30v.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_d30v_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d30v.h
+DEP_dlx_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-dlx.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_dlx_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-dlx.h
+DEP_fr30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-fr30.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_fr30_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-fr30.h
+DEP_frv_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-frv.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_frv_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-frv.h
+DEP_h8300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8300.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8300.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_h8300_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8300.h
+DEP_h8500_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8500.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8500.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_h8500_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8500.h
+DEP_hppa_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-hppa.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_hppa_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-hppa.h \
+ $(BFDDIR)/elf32-hppa.h $(BFDDIR)/libhppa.h $(INCDIR)/elf/hppa.h \
+ $(INCDIR)/elf/reloc-macros.h
+DEP_ia64_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ia64.h \
+ $(INCDIR)/opcode/ia64.h $(INCDIR)/symcat.h $(INCDIR)/elf/ia64.h \
+ $(INCDIR)/elf/reloc-macros.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_ia64_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ia64.h \
+ $(INCDIR)/opcode/ia64.h $(INCDIR)/elf/ia64.h $(INCDIR)/elf/reloc-macros.h
+DEP_i370_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i370.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_i370_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i370.h
+DEP_i386_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i386.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_i386_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i386.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/i386.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_i386_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i386.h
+DEP_i860_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i860.h
+DEP_i960_bout = $(srcdir)/config/obj-bout.h $(srcdir)/config/tc-i960.h
+DEP_i960_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i960.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/i960.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_i960_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h
+DEP_ip2k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ip2k.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_ip2k_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ip2k.h
+DEP_m32r_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m32r.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_m32r_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32r.h
+DEP_m68hc11_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m68hc11.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/m68k.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_m68hc11_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68hc11.h
+DEP_m68k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_m68k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m68k.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/m68k.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_m68k_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68k.h
+DEP_m68k_hp300 = $(srcdir)/config/obj-hp300.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-m68k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_m88k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m88k.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/m88k.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_m88k_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m88k.h
+DEP_mcore_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mcore.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/mcore.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_mcore_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mcore.h
+DEP_mips_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-mips.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_mips_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mips.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/mipspe.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_mips_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-mips.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+DEP_mips_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mips.h
+DEP_mmix_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mmix.h
+DEP_mn10200_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10200.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_mn10200_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10200.h
+DEP_mn10300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10300.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_mn10300_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10300.h
+DEP_msp430_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-msp430.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_msp430_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-msp430.h
+DEP_ns32k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-ns32k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_ns32k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ns32k.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_ns32k_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ns32k.h
+DEP_openrisc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-openrisc.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_openrisc_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-openrisc.h
+DEP_or32_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-or32.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/or32.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_or32_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-or32.h
+DEP_pdp11_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-pdp11.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_pdp11_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-pdp11.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_pdp11_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-pdp11.h
+DEP_pj_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-pj.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_pj_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-pj.h
+DEP_ppc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ppc.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/rs6000.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_ppc_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ppc.h
+DEP_s390_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-s390.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_s390_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-s390.h
+DEP_sh_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sh.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/sh.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_sh_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh.h
+DEP_sh64_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh64.h \
+ $(srcdir)/config/tc-sh.h $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h \
+ $(BFDDIR)/elf32-sh64.h
+DEP_sparc_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-sparc.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_sparc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sparc.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/sparc.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_sparc_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sparc.h
+DEP_tahoe_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tahoe.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_tahoe_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tahoe.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_tahoe_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tahoe.h
+DEP_tic30_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tic30.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_tic30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic30.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic30.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_tic30_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic30.h
+DEP_tic4x_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic4x.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic4x.h \
+ $(INCDIR)/coff/ti.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_tic4x_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic4x.h
+DEP_tic54x_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic54x.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic54x.h \
+ $(INCDIR)/coff/ti.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_tic54x_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic54x.h
+DEP_tic80_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic80.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic80.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_tic80_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic80.h
+DEP_vax_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-vax.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_vax_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_vax_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-vax.h
+DEP_vax_vms = $(srcdir)/config/obj-vms.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+DEP_w65_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-w65.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/w65.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_w65_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-w65.h
+DEP_v850_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-v850.h \
+ $(INCDIR)/elf/v850.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/symcat.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_v850_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-v850.h \
+ $(INCDIR)/elf/v850.h $(INCDIR)/elf/reloc-macros.h
+DEP_xstormy16_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-xstormy16.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_xstormy16_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xstormy16.h
+DEP_xtensa_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xtensa.h \
+ $(INCDIR)/xtensa-config.h
+DEP_z8k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-z8k.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/z8k.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_z8k_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-z8k.h
+DEP_hppa_som = $(BFDDIR)/som.h
+DEP_i386_multi = $(DEP_i386_aout) $(DEP_i386_coff) \
+ $(DEP_i386_elf)
+DEP_mips_multi = $(DEP_mips_coff) $(DEP_mips_ecoff) \
+ $(DEP_mips_elf)
+DEP_cris_multi = $(DEP_cris_aout) $(DEP_cris_elf)
+BMKDEP = #DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING ABOVE.
+#MKDEP DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING BELOW.
+app.o: app.c $(INCDIR)/symcat.h
+as.o: as.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h \
+ output-file.h sb.h macro.h dwarf2dbg.h dw2gencfi.h \
+ $(INCDIR)/elf/dwarf2.h $(BFDVER_H)
+atof-generic.o: atof-generic.c $(INCDIR)/symcat.h $(INCDIR)/safe-ctype.h
+bignum-copy.o: bignum-copy.c $(INCDIR)/symcat.h
+cond.o: cond.c $(INCDIR)/symcat.h macro.h sb.h $(INCDIR)/obstack.h
+depend.o: depend.c $(INCDIR)/symcat.h
+dwarf2dbg.o: dwarf2dbg.c $(INCDIR)/symcat.h dwarf2dbg.h \
+ $(INCDIR)/filenames.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/elf/dwarf2.h
+dw2gencfi.o: dw2gencfi.c $(INCDIR)/symcat.h dw2gencfi.h \
+ $(INCDIR)/elf/dwarf2.h
+ecoff.o: ecoff.c $(INCDIR)/symcat.h ecoff.h
+ehopt.o: ehopt.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/elf/dwarf2.h
+expr.o: expr.c $(INCDIR)/symcat.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/obstack.h
+flonum-copy.o: flonum-copy.c $(INCDIR)/symcat.h
+flonum-konst.o: flonum-konst.c
+flonum-mult.o: flonum-mult.c
+frags.o: frags.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h
+hash.o: hash.c $(INCDIR)/symcat.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/obstack.h
+input-file.o: input-file.c $(INCDIR)/symcat.h input-file.h \
+ $(INCDIR)/safe-ctype.h
+input-scrub.o: input-scrub.c $(INCDIR)/symcat.h input-file.h \
+ sb.h
+listing.o: listing.c $(INCDIR)/symcat.h $(INCDIR)/obstack.h \
+ $(INCDIR)/safe-ctype.h input-file.h subsegs.h
+literal.o: literal.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h
+macro.o: macro.c $(INCDIR)/safe-ctype.h sb.h macro.h
+messages.o: messages.c $(INCDIR)/symcat.h
+output-file.o: output-file.c $(INCDIR)/symcat.h output-file.h
+read.o: read.c $(INCDIR)/symcat.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h sb.h macro.h ecoff.h \
+ dw2gencfi.h $(INCDIR)/elf/dwarf2.h
+sb.o: sb.c sb.h
+stabs.o: stabs.c $(INCDIR)/symcat.h $(INCDIR)/obstack.h \
+ subsegs.h ecoff.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+subsegs.o: subsegs.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h
+symbols.o: symbols.c $(INCDIR)/symcat.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/obstack.h subsegs.h struc-symbol.h
+write.o: write.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h \
+ output-file.h dwarf2dbg.h
+itbl-ops.o: itbl-ops.c itbl-ops.h $(INCDIR)/symcat.h
+e-crisaout.o: $(srcdir)/config/e-crisaout.c $(INCDIR)/symcat.h \
+ emul-target.h
+e-criself.o: $(srcdir)/config/e-criself.c $(INCDIR)/symcat.h \
+ emul-target.h
+e-i386aout.o: $(srcdir)/config/e-i386aout.c $(INCDIR)/symcat.h \
+ emul-target.h
+e-i386coff.o: $(srcdir)/config/e-i386coff.c $(INCDIR)/symcat.h \
+ emul-target.h
+e-i386elf.o: $(srcdir)/config/e-i386elf.c $(INCDIR)/symcat.h \
+ emul-target.h
+e-mipsecoff.o: $(srcdir)/config/e-mipsecoff.c $(INCDIR)/symcat.h \
+ emul-target.h
+e-mipself.o: $(srcdir)/config/e-mipself.c $(INCDIR)/symcat.h \
+ emul-target.h
+$(OBJS): $(DEP_@target_cpu_type@_@obj_format@)
+$(TARG_CPU_O): $(DEPTC_@target_cpu_type@_@obj_format@)
+$(OBJ_FORMAT_O): $(DEPOBJ_@target_cpu_type@_@obj_format@)
+#MKDEP DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING ABOVE.
diff --git a/x/binutils/gas/Makefile.in b/x/binutils/gas/Makefile.in
new file mode 100644
index 0000000..67ed432
--- /dev/null
+++ b/x/binutils/gas/Makefile.in
@@ -0,0 +1,3401 @@
+# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+SOURCES = $(as_new_SOURCES) $(EXTRA_as_new_SOURCES) $(itbl_test_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = .
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+noinst_PROGRAMS = as-new$(EXEEXT)
+EXTRA_PROGRAMS = itbl-test$(EXEEXT)
+DIST_COMMON = $(srcdir)/../config.guess $(srcdir)/../config.sub NEWS \
+ README ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/configure $(am__configure_deps) \
+ $(srcdir)/config.in $(srcdir)/../mkinstalldirs \
+ $(srcdir)/gdbinit.in $(srcdir)/gdbinit.in \
+ $(top_srcdir)/po/Make-in m68k-parse.c itbl-parse.c itbl-lex.c \
+ $(srcdir)/../ylwrap $(srcdir)/../ltmain.sh \
+ $(srcdir)/../config.guess $(srcdir)/../config.sub
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/../libtool.m4 $(top_srcdir)/../gettext.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno configure.status.lineno
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = gdb.ini .gdbinit po/Makefile.in
+PROGRAMS = $(noinst_PROGRAMS)
+am__objects_1 = app.$(OBJEXT) as.$(OBJEXT) atof-generic.$(OBJEXT) \
+ bignum-copy.$(OBJEXT) cond.$(OBJEXT) depend.$(OBJEXT) \
+ dwarf2dbg.$(OBJEXT) dw2gencfi.$(OBJEXT) ecoff.$(OBJEXT) \
+ ehopt.$(OBJEXT) expr.$(OBJEXT) flonum-copy.$(OBJEXT) \
+ flonum-konst.$(OBJEXT) flonum-mult.$(OBJEXT) frags.$(OBJEXT) \
+ hash.$(OBJEXT) input-file.$(OBJEXT) input-scrub.$(OBJEXT) \
+ listing.$(OBJEXT) literal.$(OBJEXT) macro.$(OBJEXT) \
+ messages.$(OBJEXT) output-file.$(OBJEXT) read.$(OBJEXT) \
+ sb.$(OBJEXT) stabs.$(OBJEXT) subsegs.$(OBJEXT) \
+ symbols.$(OBJEXT) write.$(OBJEXT)
+am_as_new_OBJECTS = $(am__objects_1)
+as_new_OBJECTS = $(am_as_new_OBJECTS)
+am__DEPENDENCIES_1 = tc-@target_cpu_type@.o
+am__DEPENDENCIES_2 = obj-@obj_format@.o
+am__DEPENDENCIES_3 = atof-@atof@.o
+am__DEPENDENCIES_4 =
+am__DEPENDENCIES_5 = ../libiberty/libiberty.a
+am_itbl_test_OBJECTS = itbl-parse.$(OBJEXT) itbl-lex.$(OBJEXT)
+itbl_test_OBJECTS = $(am_itbl_test_OBJECTS)
+itbl_test_DEPENDENCIES = itbl-tops.o itbl-test.o $(am__DEPENDENCIES_5)
+SCRIPTS = $(noinst_SCRIPTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
+depcomp =
+am__depfiles_maybe =
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS)
+LTLEXCOMPILE = $(LIBTOOL) --mode=compile $(LEX) $(LFLAGS) $(AM_LFLAGS)
+YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
+LTYACCCOMPILE = $(LIBTOOL) --mode=compile $(YACC) $(YFLAGS) \
+ $(AM_YFLAGS)
+YLWRAP = $(top_srcdir)/../ylwrap
+SOURCES = $(as_new_SOURCES) $(EXTRA_as_new_SOURCES) \
+ $(itbl_test_SOURCES)
+DIST_SOURCES = $(as_new_SOURCES) $(EXTRA_as_new_SOURCES) \
+ $(itbl_test_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-exec-recursive install-info-recursive \
+ install-recursive installcheck-recursive installdirs-recursive \
+ pdf-recursive ps-recursive uninstall-info-recursive \
+ uninstall-recursive
+ETAGS = etags
+CTAGS = ctags
+DEJATOOL = $(PACKAGE)
+RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALL_OBJ_DEPS = @ALL_OBJ_DEPS@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BFDVER_H = @BFDVER_H@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GDBINIT = @GDBINIT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LDFLAGS = @LDFLAGS@
+LEX = `if [ -f ../flex/flex ] ; then echo ../flex/flex ; else echo @LEX@ ; fi`
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+OBJEXT = @OBJEXT@
+OPCODES_LIB = @OPCODES_LIB@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+YACC = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L../bison/bison ; else echo @YACC@ ; fi`
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+atof = @atof@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+cgen_cpu_prefix = @cgen_cpu_prefix@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+extra_objects = @extra_objects@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+install_tooldir = @install_tooldir@
+l = @l@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+obj_format = @obj_format@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_cpu_type = @target_cpu_type@
+target_os = @target_os@
+target_vendor = @target_vendor@
+te_file = @te_file@
+AUTOMAKE_OPTIONS = 1.8 cygnus dejagnu
+SUBDIRS = doc po
+# Automake should figure this out on its own. It doesn't, because
+# of the "cygnus" option. But distclean still wants it.
+DIST_SUBDIRS = $(SUBDIRS)
+tooldir = $(exec_prefix)/$(target_alias)
+AM_CFLAGS = $(WARN_CFLAGS)
+MKDEP = gcc -MM
+TARG_CPU = @target_cpu_type@
+TARG_CPU_C = $(srcdir)/config/tc-@target_cpu_type@.c
+TARG_CPU_O = tc-@target_cpu_type@.o
+TARG_CPU_H = $(srcdir)/config/tc-@target_cpu_type@.h
+OBJ_FORMAT_C = $(srcdir)/config/obj-@obj_format@.c
+OBJ_FORMAT_O = obj-@obj_format@.o
+OBJ_FORMAT_H = $(srcdir)/config/obj-@obj_format@.h
+TARG_ENV_H = $(srcdir)/config/te-@te_file@.h
+ATOF_TARG_C = $(srcdir)/config/atof-@atof@.c
+ATOF_TARG_O = atof-@atof@.o
+
+# use @target_cpu_type@ for refering to configured target name
+IT_HDRS = itbl-parse.h $(srcdir)/itbl-ops.h
+IT_SRCS = itbl-parse.c itbl-lex.c $(srcdir)/itbl-ops.c
+IT_DEPS = $(srcdir)/itbl-parse.y $(srcdir)/itbl-lex.l $(srcdir)/config/itbl-@target_cpu_type@.h
+IT_OBJS = itbl-parse.o itbl-lex.o itbl-ops.o
+
+# CPU types. This is only used for dependency information.
+CPU_TYPES = \
+ a29k \
+ alpha \
+ arc \
+ arm \
+ avr \
+ cris \
+ d10v \
+ d30v \
+ dlx \
+ fr30 \
+ frv \
+ h8300 \
+ h8500 \
+ hppa \
+ ia64 \
+ i370 \
+ i386 \
+ i860 \
+ i960 \
+ ip2k \
+ m32r \
+ m68hc11 \
+ m68k \
+ m88k \
+ mcore \
+ mips \
+ mmix \
+ mn10200 \
+ mn10300 \
+ msp430 \
+ ns32k \
+ openrisc \
+ or32 \
+ pdp11 \
+ pj \
+ ppc \
+ s390 \
+ sh \
+ sh64 \
+ sparc \
+ tahoe \
+ tic30 \
+ tic4x \
+ tic54x \
+ tic80 \
+ vax \
+ w65 \
+ v850 \
+ xstormy16 \
+ xtensa \
+ z8k
+
+
+# Object format types. This is only used for dependency information.
+# We deliberately omit SOM, since it does not work as a cross assembler.
+OBJ_FORMATS = \
+ aout \
+ bout \
+ coff \
+ ecoff \
+ elf \
+ evax \
+ hp300 \
+ ieee \
+ vms
+
+
+# This is an sh case which sets valid according to whether the CPU
+# type in the shell variable c and the OS type in the shell variable o
+# are supported. This helps cuts down on the amount of dependency
+# information.
+CPU_OBJ_VALID = \
+ valid= ; \
+ case $$o in \
+ aout) \
+ case $$c in \
+ a29k | arm | cris | i386 | m68k | ns32k | pdp11 | sparc | tahoe | tic30 | vax) \
+ valid=yes ;; \
+ esac ;; \
+ bout) \
+ case $$c in \
+ i960) valid=yes ;; \
+ esac ;; \
+ coff) valid=yes; \
+ case $$c in \
+ cris | i860 | mmix | sh64) \
+ valid= ;; \
+ esac ;; \
+ ecoff) \
+ case $$c in \
+ mips | alpha) valid=yes ;; \
+ esac ;; \
+ elf) valid=yes ;; \
+ evax) \
+ case $$c in \
+ alpha) valid=yes ;; \
+ esac ;; \
+ hp300) \
+ case $$c in \
+ m68k) valid=yes ;; \
+ esac ;; \
+ vms) \
+ case $$c in \
+ vax) valid=yes ;; \
+ esac ;; \
+ esac;
+
+
+# These are like CPU_TYPES and CPU_OBJ_VALID, for the obj=multi case.
+MULTI_CPU_TYPES = i386 mips cris
+MULTI_CPU_OBJ_VALID = \
+ valid= ; \
+ case $$o in \
+ aout) \
+ case $$c in \
+ i386 | cris) valid=yes ;; \
+ esac ;; \
+ coff) \
+ case $$c in \
+ i386 | mips) valid=yes ;; \
+ esac ;; \
+ ecoff) \
+ case $$c in \
+ mips) valid=yes ;; \
+ esac ;; \
+ elf) valid=yes ;; \
+ esac;
+
+
+# Regular source files.
+GAS_CFILES = \
+ app.c \
+ as.c \
+ atof-generic.c \
+ bignum-copy.c \
+ cond.c \
+ depend.c \
+ dwarf2dbg.c \
+ dw2gencfi.c \
+ ecoff.c \
+ ehopt.c \
+ expr.c \
+ flonum-copy.c \
+ flonum-konst.c \
+ flonum-mult.c \
+ frags.c \
+ hash.c \
+ input-file.c \
+ input-scrub.c \
+ listing.c \
+ literal.c \
+ macro.c \
+ messages.c \
+ output-file.c \
+ read.c \
+ sb.c \
+ stabs.c \
+ subsegs.c \
+ symbols.c \
+ write.c
+
+CFILES = $(GAS_CFILES) itbl-ops.c
+HFILES = \
+ as.h \
+ asintl.h \
+ bignum.h \
+ bit_fix.h \
+ cgen.h \
+ dwarf2dbg.h \
+ dw2gencfi.h \
+ ecoff.h \
+ emul-target.h \
+ emul.h \
+ expr.h \
+ flonum.h \
+ frags.h \
+ hash.h \
+ input-file.h \
+ itbl-ops.h \
+ listing.h \
+ macro.h \
+ obj.h \
+ output-file.h \
+ read.h \
+ sb.h \
+ struc-symbol.h \
+ subsegs.h \
+ symbols.h \
+ tc.h \
+ write.h
+
+
+# CPU files in config.
+TARGET_CPU_CFILES = \
+ config/tc-a29k.c \
+ config/tc-alpha.c \
+ config/tc-arc.c \
+ config/tc-arm.c \
+ config/tc-avr.c \
+ config/tc-cris.c \
+ config/tc-d10v.c \
+ config/tc-d30v.c \
+ config/tc-dlx.c \
+ config/tc-fr30.c \
+ config/tc-frv.c \
+ config/tc-h8300.c \
+ config/tc-h8500.c \
+ config/tc-hppa.c \
+ config/tc-ia64.c \
+ config/tc-i370.c \
+ config/tc-i386.c \
+ config/tc-i860.c \
+ config/tc-i960.c \
+ config/tc-ip2k.c \
+ config/tc-m32r.c \
+ config/tc-m68hc11.c \
+ config/tc-m68k.c \
+ config/tc-m88k.c \
+ config/tc-mcore.c \
+ config/tc-mips.c \
+ config/tc-mmix.c \
+ config/tc-mn10200.c \
+ config/tc-mn10300.c \
+ config/tc-msp430.c \
+ config/tc-ns32k.c \
+ config/tc-openrisc.c \
+ config/tc-or32.c \
+ config/tc-pdp11.c \
+ config/tc-pj.c \
+ config/tc-ppc.c \
+ config/tc-s390.c \
+ config/tc-sh.c \
+ config/tc-sh64.c \
+ config/tc-sparc.c \
+ config/tc-tahoe.c \
+ config/tc-tic30.c \
+ config/tc-tic54x.c \
+ config/tc-tic80.c \
+ config/tc-vax.c \
+ config/tc-w65.c \
+ config/tc-v850.c \
+ config/tc-xstormy16.c \
+ config/tc-xtensa.c \
+ config/tc-z8k.c
+
+TARGET_CPU_HFILES = \
+ config/tc-a29k.h \
+ config/tc-alpha.h \
+ config/tc-arc.h \
+ config/tc-arm.h \
+ config/tc-avr.h \
+ config/tc-cris.h \
+ config/tc-d10v.h \
+ config/tc-d30v.h \
+ config/tc-dlx.h \
+ config/tc-fr30.h \
+ config/tc-frv.h \
+ config/tc-h8300.h \
+ config/tc-h8500.h \
+ config/tc-hppa.h \
+ config/tc-ia64.h \
+ config/tc-i370.h \
+ config/tc-i386.h \
+ config/tc-i860.h \
+ config/tc-i960.h \
+ config/tc-ip2k.h \
+ config/tc-m32r.h \
+ config/tc-m68hc11.h \
+ config/tc-m68k.h \
+ config/tc-m88k.h \
+ config/tc-mcore.h \
+ config/tc-mips.h \
+ config/tc-mmix.h \
+ config/tc-mn10200.h \
+ config/tc-mn10300.h \
+ config/tc-msp430.h \
+ config/tc-ns32k.h \
+ config/tc-openrisc.h \
+ config/tc-or32.h \
+ config/tc-pdp11.h \
+ config/tc-pj.h \
+ config/tc-ppc.h \
+ config/tc-s390.h \
+ config/tc-sh.h \
+ config/tc-sh64.h \
+ config/tc-sparc.h \
+ config/tc-tahoe.h \
+ config/tc-tic30.h \
+ config/tc-tic54x.h \
+ config/tc-tic80.h \
+ config/tc-vax.h \
+ config/tc-w65.h \
+ config/tc-v850.h \
+ config/tc-xstormy16.h \
+ config/tc-xtensa.h \
+ config/tc-z8k.h
+
+
+# OBJ files in config
+OBJ_FORMAT_CFILES = \
+ config/obj-aout.c \
+ config/obj-bout.c \
+ config/obj-coff.c \
+ config/obj-ecoff.c \
+ config/obj-elf.c \
+ config/obj-evax.c \
+ config/obj-hp300.c \
+ config/obj-ieee.c \
+ config/obj-som.c \
+ config/obj-vms.c
+
+OBJ_FORMAT_HFILES = \
+ config/obj-aout.h \
+ config/obj-bout.h \
+ config/obj-coff.h \
+ config/obj-ecoff.h \
+ config/obj-elf.h \
+ config/obj-evax.h \
+ config/obj-hp300.h \
+ config/obj-ieee.h \
+ config/obj-som.h \
+ config/obj-vms.h
+
+
+# Emulation header files in config
+TARG_ENV_HFILES = \
+ config/te-386bsd.h \
+ config/te-aux.h \
+ config/te-delta.h \
+ config/te-delt88.h \
+ config/te-dpx2.h \
+ config/te-dynix.h \
+ config/te-epoc-pe.h \
+ config/te-generic.h \
+ config/te-go32.h \
+ config/te-hp300.h \
+ config/te-hppa.h \
+ config/te-hppa64.h \
+ config/te-hppalinux64.h \
+ config/te-i386aix.h \
+ config/te-ia64aix.h \
+ config/te-ic960.h \
+ config/te-linux.h \
+ config/te-lnews.h \
+ config/te-lynx.h \
+ config/te-mach.h \
+ config/te-macos.h \
+ config/te-nbsd.h \
+ config/te-nbsd532.h \
+ config/te-pc532mach.h \
+ config/te-pe.h \
+ config/te-ppcnw.h \
+ config/te-psos.h \
+ config/te-riscix.h \
+ config/te-sparcaout.h \
+ config/te-sun3.h \
+ config/te-svr4.h \
+ config/te-sysv32.h \
+ config/te-tmips.h
+
+
+# Multi files in config
+MULTI_CFILES = \
+ config/e-crisaout.c \
+ config/e-criself.c \
+ config/e-i386aout.c \
+ config/e-i386coff.c \
+ config/e-i386elf.c \
+ config/e-mipsecoff.c \
+ config/e-mipself.c
+
+CONFIG_OBJS = \
+ $(TARG_CPU_O) \
+ $(OBJ_FORMAT_O) \
+ $(ATOF_TARG_O) \
+ $(extra_objects)
+
+GENERIC_OBJS = \
+ app.o \
+ as.o \
+ atof-generic.o \
+ bignum-copy.o \
+ cond.o \
+ depend.o \
+ dwarf2dbg.o \
+ dw2gencfi.o \
+ ehopt.o \
+ expr.o \
+ flonum-konst.o \
+ flonum-copy.o \
+ flonum-mult.o \
+ frags.o \
+ hash.o \
+ input-file.o \
+ input-scrub.o \
+ literal.o \
+ messages.o \
+ output-file.o \
+ read.o \
+ subsegs.o \
+ symbols.o \
+ write.o \
+ listing.o \
+ ecoff.o \
+ stabs.o \
+ sb.o \
+ macro.o
+
+OBJS = $(CONFIG_OBJS) $(GENERIC_OBJS)
+POTFILES = $(MULTI_CFILES) $(TARGET_ENV_HFILES) $(OBJ_FORMAT_HFILES) \
+ $(OBJ_FORMAT_CFILES) $(TARGET_CPU_HFILES) $(TARGET_CPU_CFILES) \
+ $(HFILES) $(CFILES) $(GAS_CFILES)
+
+noinst_SCRIPTS = $(GDBINIT)
+EXTRA_SCRIPTS = .gdbinit
+EXTRA_DIST = make-gas.com m68k-parse.c itbl-parse.c itbl-parse.h itbl-lex.c
+DISTCLEANFILES = targ-cpu.h obj-format.h targ-env.h itbl-cpu.h cgen-desc.h
+
+# Now figure out from those variables how to compile and link.
+BASEDIR = $(srcdir)/..
+BFDDIR = $(BASEDIR)/bfd
+INCDIR = $(BASEDIR)/include
+
+# This is the variable actually used when we compile.
+# Specify the directories to be searched for header files.
+# Both . and srcdir are used, in that order,
+# so that tm.h and config.h will be found in the compilation
+# subdirectory rather than in the source directory.
+INCLUDES = -D_GNU_SOURCE -I. -I$(srcdir) -I../bfd -I$(srcdir)/config -I$(INCDIR) -I$(srcdir)/.. -I$(BFDDIR) -I$(srcdir)/../intl -I../intl -DLOCALEDIR="\"$(prefix)/share/locale\""
+
+# This should be parallel to INCLUDES, but should replace $(srcdir)
+# with $${srcdir}, and should work in a subdirectory. This is used
+# when building dependencies, because the dependency building is done
+# in a subdirectory.
+DEP_INCLUDES = -D_GNU_SOURCE -I.. -I$${srcdir} -I../../bfd -I$${srcdir}/config -I$${srcdir}/../include -I$${srcdir}/.. -I$${srcdir}/../bfd -I$${srcdir}/../intl -I../../intl -DLOCALEDIR="\"$(prefix)/share/locale\""
+DEP_FLAGS = -DBFD_ASSEMBLER -DOBJ_MAYBE_ELF \
+ -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES)
+
+
+# How to link with both our special library facilities
+# and the system's installed libraries.
+GASLIBS = @OPCODES_LIB@ @BFDLIB@ ../libiberty/libiberty.a
+
+# Files to be copied away after each stage in building.
+STAGESTUFF = *.o $(noinst_PROGRAMS)
+as_new_SOURCES = $(GAS_CFILES)
+as_new_LDADD = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \
+ $(extra_objects) $(GASLIBS) $(INTLLIBS) $(LIBM)
+
+as_new_DEPENDENCIES = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \
+ $(extra_objects) $(GASLIBS) $(INTLDEPS)
+
+EXPECT = `if [ -f $${rootme}/../expect/expect ] ; then \
+ echo $${rootme}/../expect/expect ; \
+ else echo expect ; fi`
+
+RUNTEST = `if [ -f $${srcdir}/../dejagnu/runtest ] ; then \
+ echo $${srcdir}/../dejagnu/runtest ; else echo runtest; \
+ fi`
+
+RUNTESTFLAGS =
+
+# The m68k operand parser.
+EXTRA_as_new_SOURCES = config/m68k-parse.y
+itbl_test_SOURCES = itbl-parse.y itbl-lex.l
+itbl_test_LDADD = itbl-tops.o itbl-test.o $(GASLIBS) @LEXLIB@
+
+# CGEN interface.
+CGEN_CPU_PREFIX = @cgen_cpu_prefix@
+
+# Remake the info files.
+MOSTLYCLEANFILES = $(STAGESTUFF) core stamp-mk.com \
+ testsuite/*.o testsuite/*.out testsuite/gas.log testsuite/gas.sum \
+ testsuite/site.exp site.bak site.exp stage stage1 stage2
+
+CLEANFILES = dep.sed DEPTC DEPTCA DEPOBJ DEPOBJA DEP2 DEP2A DEP1 DEPA DEP DEPDIR
+against = stage2
+DEP_FILE_DEPS = $(CFILES) $(HFILES) $(TARGET_CPU_CFILES) \
+ $(TARGET_CPU_HFILES) $(OBJ_FORMAT_CFILES) $(OBJ_FORMAT_HFILES)
+
+CONFIG_STATUS_DEPENDENCIES = $(BFDDIR)/configure.in
+AMKDEP = #DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING BELOW.
+DEPTC_a29k_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-a29k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/a29k.h
+
+DEPTC_a29k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-a29k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/a29k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/a29k.h
+
+DEPTC_a29k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-a29k.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/a29k.h
+
+DEPTC_alpha_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-alpha.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h ecoff.h $(INCDIR)/opcode/alpha.h $(INCDIR)/safe-ctype.h \
+ $(srcdir)/config/atof-vax.c
+
+DEPTC_alpha_ecoff = $(INCDIR)/symcat.h $(srcdir)/config/obj-ecoff.h \
+ $(srcdir)/config/tc-alpha.h ecoff.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h $(INCDIR)/opcode/alpha.h $(INCDIR)/safe-ctype.h \
+ $(srcdir)/config/atof-vax.c
+
+DEPTC_alpha_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-alpha.h \
+ subsegs.h $(INCDIR)/obstack.h struc-symbol.h ecoff.h \
+ $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h $(INCDIR)/opcode/alpha.h \
+ $(INCDIR)/elf/alpha.h $(INCDIR)/elf/reloc-macros.h \
+ dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/safe-ctype.h \
+ $(srcdir)/config/atof-vax.c
+
+DEPTC_alpha_evax = $(INCDIR)/symcat.h $(srcdir)/config/obj-evax.h \
+ $(srcdir)/config/tc-alpha.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h ecoff.h $(INCDIR)/opcode/alpha.h $(INCDIR)/safe-ctype.h \
+ $(srcdir)/config/atof-vax.c
+
+DEPTC_arc_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-arc.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h struc-symbol.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/arc.h $(srcdir)/../opcodes/arc-ext.h \
+ $(INCDIR)/elf/arc.h $(INCDIR)/elf/reloc-macros.h dwarf2dbg.h
+
+DEPTC_arc_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arc.h \
+ struc-symbol.h $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/arc.h $(srcdir)/../opcodes/arc-ext.h \
+ $(INCDIR)/elf/arc.h $(INCDIR)/elf/reloc-macros.h dwarf2dbg.h
+
+DEPTC_arm_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-arm.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h
+
+DEPTC_arm_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-arm.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/arm.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h subsegs.h \
+ $(INCDIR)/obstack.h
+
+DEPTC_arm_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arm.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h dwarf2dbg.h
+
+DEPTC_avr_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-avr.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/avr.h
+
+DEPTC_avr_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-avr.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/avr.h
+
+DEPTC_cris_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-cris.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/cris.h dwarf2dbg.h
+
+DEPTC_cris_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-cris.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/cris.h dwarf2dbg.h
+
+DEPTC_d10v_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-d10v.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/d10v.h \
+ $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h
+
+DEPTC_d10v_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d10v.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/d10v.h $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h
+
+DEPTC_d30v_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-d30v.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/d30v.h
+
+DEPTC_d30v_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d30v.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/d30v.h
+
+DEPTC_dlx_coff = $(INCDIR)/safe-ctype.h $(INCDIR)/symcat.h \
+ $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-dlx.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/opcode/dlx.h
+
+DEPTC_dlx_elf = $(INCDIR)/safe-ctype.h $(INCDIR)/symcat.h \
+ $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(srcdir)/config/tc-dlx.h $(INCDIR)/opcode/dlx.h
+
+DEPTC_fr30_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-fr30.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/fr30-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/fr30-opc.h \
+ cgen.h
+
+DEPTC_fr30_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-fr30.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/fr30-desc.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/fr30-opc.h cgen.h
+
+DEPTC_frv_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-frv.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/frv-desc.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/frv-opc.h cgen.h $(BFDDIR)/libbfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/frv.h $(INCDIR)/elf/reloc-macros.h
+
+DEPTC_frv_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-frv.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/frv-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/frv-opc.h \
+ cgen.h $(BFDDIR)/libbfd.h $(INCDIR)/elf/frv.h $(INCDIR)/elf/reloc-macros.h
+
+DEPTC_h8300_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-h8300.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/h8300.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h dwarf2dbg.h \
+ $(INCDIR)/opcode/h8300.h $(INCDIR)/safe-ctype.h
+
+DEPTC_h8300_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8300.h \
+ subsegs.h $(INCDIR)/obstack.h dwarf2dbg.h $(INCDIR)/opcode/h8300.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/elf/h8.h $(INCDIR)/elf/reloc-macros.h
+
+DEPTC_h8500_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-h8500.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/h8500.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/h8500-opc.h \
+ $(INCDIR)/safe-ctype.h
+
+DEPTC_h8500_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8500.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/h8500-opc.h \
+ $(INCDIR)/safe-ctype.h
+
+DEPTC_hppa_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-hppa.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(BFDDIR)/libhppa.h $(INCDIR)/opcode/hppa.h
+
+DEPTC_hppa_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-hppa.h \
+ $(BFDDIR)/elf32-hppa.h $(BFDDIR)/libhppa.h $(INCDIR)/elf/hppa.h \
+ $(INCDIR)/elf/reloc-macros.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/hppa.h \
+ dwarf2dbg.h
+
+DEPTC_ia64_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-ia64.h $(INCDIR)/opcode/ia64.h \
+ $(INCDIR)/elf/ia64.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ dwarf2dbg.h subsegs.h $(INCDIR)/obstack.h
+
+DEPTC_ia64_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ia64.h \
+ $(INCDIR)/opcode/ia64.h $(INCDIR)/elf/ia64.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/safe-ctype.h dwarf2dbg.h subsegs.h $(INCDIR)/obstack.h
+
+DEPTC_i370_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-i370.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h struc-symbol.h $(INCDIR)/opcode/i370.h
+
+DEPTC_i370_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i370.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h $(INCDIR)/opcode/i370.h $(INCDIR)/elf/i370.h \
+ $(INCDIR)/elf/reloc-macros.h
+
+DEPTC_i386_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-i386.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/i386.h
+
+DEPTC_i386_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-i386.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/i386.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h subsegs.h \
+ $(INCDIR)/obstack.h dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h \
+ $(INCDIR)/opcode/i386.h
+
+DEPTC_i386_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i386.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/i386.h
+
+DEPTC_i860_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i860.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/i860.h $(INCDIR)/elf/i860.h $(INCDIR)/elf/reloc-macros.h
+
+DEPTC_i960_bout = $(INCDIR)/symcat.h $(srcdir)/config/obj-bout.h \
+ $(srcdir)/config/tc-i960.h $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/i960.h
+
+DEPTC_i960_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-i960.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/i960.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h $(INCDIR)/opcode/i960.h
+
+DEPTC_i960_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h $(INCDIR)/opcode/i960.h
+
+DEPTC_ip2k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-ip2k.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/ip2k-desc.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/ip2k-opc.h cgen.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/ip2k.h $(INCDIR)/elf/reloc-macros.h $(BFDDIR)/libbfd.h
+
+DEPTC_ip2k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ip2k.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/ip2k-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/ip2k-opc.h \
+ cgen.h $(INCDIR)/elf/ip2k.h $(INCDIR)/elf/reloc-macros.h \
+ $(BFDDIR)/libbfd.h
+
+DEPTC_m32r_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-m32r.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/m32r-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/m32r-opc.h \
+ cgen.h
+
+DEPTC_m32r_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32r.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/m32r-desc.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/m32r-opc.h cgen.h
+
+DEPTC_m68hc11_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-m68hc11.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/m68k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/m68hc11.h dwarf2dbg.h \
+ $(INCDIR)/elf/m68hc11.h $(INCDIR)/elf/reloc-macros.h
+
+DEPTC_m68hc11_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68hc11.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/m68hc11.h dwarf2dbg.h $(INCDIR)/elf/m68hc11.h \
+ $(INCDIR)/elf/reloc-macros.h
+
+DEPTC_m68k_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-m68k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h subsegs.h \
+ dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/m68k.h \
+ $(srcdir)/config/m68k-parse.h
+
+DEPTC_m68k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-m68k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/m68k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h \
+ subsegs.h dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h \
+ $(INCDIR)/opcode/m68k.h $(srcdir)/config/m68k-parse.h
+
+DEPTC_m68k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68k.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h subsegs.h \
+ dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/m68k.h \
+ $(srcdir)/config/m68k-parse.h $(INCDIR)/elf/m68k.h \
+ $(INCDIR)/elf/reloc-macros.h
+
+DEPTC_m68k_hp300 = $(INCDIR)/symcat.h $(srcdir)/config/obj-hp300.h \
+ $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/obstack.h subsegs.h dwarf2dbg.h dw2gencfi.h \
+ $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/m68k.h $(srcdir)/config/m68k-parse.h
+
+DEPTC_m88k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-m88k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/m88k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h subsegs.h \
+ $(INCDIR)/obstack.h $(srcdir)/config/m88k-opcode.h
+
+DEPTC_m88k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m88k.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/config/m88k-opcode.h
+
+DEPTC_mcore_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-mcore.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/mcore.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/mcore-opc.h \
+ $(INCDIR)/safe-ctype.h
+
+DEPTC_mcore_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mcore.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/mcore-opc.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/elf/mcore.h $(INCDIR)/elf/reloc-macros.h
+
+DEPTC_mips_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-mips.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/opcode/mips.h itbl-ops.h dwarf2dbg.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+
+DEPTC_mips_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-mips.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/mipspe.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/opcode/mips.h itbl-ops.h dwarf2dbg.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+
+DEPTC_mips_ecoff = $(INCDIR)/symcat.h $(srcdir)/config/obj-ecoff.h \
+ $(srcdir)/config/tc-mips.h ecoff.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/mips.h itbl-ops.h \
+ dwarf2dbg.h $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h
+
+DEPTC_mips_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mips.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/opcode/mips.h itbl-ops.h dwarf2dbg.h $(INCDIR)/elf/mips.h \
+ $(INCDIR)/elf/reloc-macros.h ecoff.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h
+
+DEPTC_mmix_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mmix.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/elf/mmix.h \
+ $(INCDIR)/elf/reloc-macros.h $(INCDIR)/opcode/mmix.h \
+ $(INCDIR)/safe-ctype.h dwarf2dbg.h
+
+DEPTC_mn10200_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-mn10200.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10200.h
+
+DEPTC_mn10200_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10200.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/mn10200.h
+
+DEPTC_mn10300_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-mn10300.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10300.h \
+ dwarf2dbg.h
+
+DEPTC_mn10300_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10300.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/mn10300.h dwarf2dbg.h
+
+DEPTC_msp430_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-msp430.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/msp430.h $(INCDIR)/safe-ctype.h
+
+DEPTC_msp430_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-msp430.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/msp430.h \
+ $(INCDIR)/safe-ctype.h
+
+DEPTC_ns32k_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-ns32k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/opcode/ns32k.h $(INCDIR)/obstack.h
+
+DEPTC_ns32k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-ns32k.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/ns32k.h \
+ $(INCDIR)/obstack.h
+
+DEPTC_ns32k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ns32k.h \
+ $(INCDIR)/opcode/ns32k.h $(INCDIR)/obstack.h
+
+DEPTC_openrisc_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-openrisc.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/openrisc-desc.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/openrisc-opc.h cgen.h
+
+DEPTC_openrisc_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-openrisc.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/openrisc-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/openrisc-opc.h \
+ cgen.h
+
+DEPTC_or32_coff = $(INCDIR)/safe-ctype.h $(INCDIR)/symcat.h \
+ $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-or32.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/or32.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/opcode/or32.h $(INCDIR)/elf/or32.h \
+ $(INCDIR)/elf/reloc-macros.h
+
+DEPTC_or32_elf = $(INCDIR)/safe-ctype.h $(INCDIR)/symcat.h \
+ $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(srcdir)/config/tc-or32.h $(INCDIR)/opcode/or32.h \
+ $(INCDIR)/elf/or32.h $(INCDIR)/elf/reloc-macros.h
+
+DEPTC_pdp11_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-pdp11.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/pdp11.h
+
+DEPTC_pdp11_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-pdp11.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/opcode/pdp11.h
+
+DEPTC_pdp11_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-pdp11.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/pdp11.h
+
+DEPTC_pj_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-pj.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/opcode/pj.h
+
+DEPTC_pj_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-pj.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/pj.h
+
+DEPTC_ppc_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-ppc.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/rs6000.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/ppc.h
+
+DEPTC_ppc_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ppc.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/ppc.h \
+ $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h dwarf2dbg.h
+
+DEPTC_s390_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-s390.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h struc-symbol.h dwarf2dbg.h \
+ dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/s390.h \
+ $(INCDIR)/elf/s390.h $(INCDIR)/elf/reloc-macros.h
+
+DEPTC_s390_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-s390.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h \
+ $(INCDIR)/opcode/s390.h $(INCDIR)/elf/s390.h $(INCDIR)/elf/reloc-macros.h
+
+DEPTC_sh_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-sh.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/sh.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/sh-opc.h \
+ $(INCDIR)/safe-ctype.h struc-symbol.h dwarf2dbg.h dw2gencfi.h
+
+DEPTC_sh_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/sh-opc.h \
+ $(INCDIR)/safe-ctype.h struc-symbol.h $(INCDIR)/elf/sh.h \
+ $(INCDIR)/elf/reloc-macros.h dwarf2dbg.h dw2gencfi.h
+
+DEPTC_sh64_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh64.h \
+ $(srcdir)/config/tc-sh.h $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h \
+ $(BFDDIR)/elf32-sh64.h $(INCDIR)/safe-ctype.h $(srcdir)/../opcodes/sh64-opc.h \
+ $(srcdir)/config/tc-sh.c subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/sh-opc.h struc-symbol.h dwarf2dbg.h dw2gencfi.h
+
+DEPTC_sparc_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-sparc.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/sparc.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h
+
+DEPTC_sparc_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-sparc.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/sparc.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/sparc.h dw2gencfi.h \
+ $(INCDIR)/elf/dwarf2.h
+
+DEPTC_sparc_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sparc.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/sparc.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h \
+ $(INCDIR)/elf/sparc.h $(INCDIR)/elf/reloc-macros.h \
+ dwarf2dbg.h
+
+DEPTC_tahoe_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-tahoe.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h $(INCDIR)/opcode/tahoe.h
+
+DEPTC_tahoe_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tahoe.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/tahoe.h
+
+DEPTC_tahoe_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tahoe.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h $(INCDIR)/opcode/tahoe.h
+
+DEPTC_tic30_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-tic30.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/tic30.h
+
+DEPTC_tic30_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tic30.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/tic30.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/tic30.h
+
+DEPTC_tic30_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic30.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/tic30.h
+
+DEPTC_tic4x_coff = $(INCDIR)/safe-ctype.h $(INCDIR)/symcat.h \
+ $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic4x.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic4x.h $(INCDIR)/coff/ti.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/tic4x.h \
+ subsegs.h $(INCDIR)/obstack.h
+
+DEPTC_tic4x_elf = $(INCDIR)/safe-ctype.h $(INCDIR)/symcat.h \
+ $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(srcdir)/config/tc-tic4x.h $(INCDIR)/opcode/tic4x.h \
+ subsegs.h $(INCDIR)/obstack.h
+
+DEPTC_tic54x_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tic54x.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/tic54x.h $(INCDIR)/coff/ti.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h sb.h macro.h \
+ subsegs.h $(INCDIR)/obstack.h struc-symbol.h $(INCDIR)/opcode/tic54x.h
+
+DEPTC_tic54x_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic54x.h \
+ $(INCDIR)/safe-ctype.h sb.h macro.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h $(INCDIR)/opcode/tic54x.h $(srcdir)/config/obj-coff.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic54x.h $(INCDIR)/coff/ti.h \
+ $(BFDDIR)/libcoff.h
+
+DEPTC_tic80_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tic80.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/tic80.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/tic80.h
+
+DEPTC_tic80_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic80.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/tic80.h
+
+DEPTC_vax_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-vax.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(srcdir)/config/vax-inst.h $(INCDIR)/obstack.h subsegs.h \
+ $(INCDIR)/opcode/vax.h $(INCDIR)/safe-ctype.h
+
+DEPTC_vax_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-vax.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(srcdir)/config/vax-inst.h \
+ $(INCDIR)/obstack.h subsegs.h $(INCDIR)/opcode/vax.h \
+ $(INCDIR)/safe-ctype.h
+
+DEPTC_vax_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-vax.h \
+ $(srcdir)/config/vax-inst.h $(INCDIR)/obstack.h subsegs.h \
+ $(INCDIR)/elf/vax.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/opcode/vax.h \
+ $(INCDIR)/safe-ctype.h
+
+DEPTC_vax_vms = $(INCDIR)/symcat.h $(srcdir)/config/obj-vms.h \
+ $(srcdir)/config/tc-vax.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(srcdir)/config/vax-inst.h \
+ $(INCDIR)/obstack.h subsegs.h $(INCDIR)/opcode/vax.h \
+ $(INCDIR)/safe-ctype.h
+
+DEPTC_w65_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-w65.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/w65.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/w65-opc.h
+
+DEPTC_w65_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-w65.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/w65-opc.h
+
+DEPTC_v850_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-v850.h $(INCDIR)/elf/v850.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/v850.h dwarf2dbg.h
+
+DEPTC_v850_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-v850.h \
+ $(INCDIR)/elf/v850.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/v850.h \
+ dwarf2dbg.h
+
+DEPTC_xstormy16_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-xstormy16.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/xstormy16-desc.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/xstormy16-opc.h cgen.h
+
+DEPTC_xstormy16_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xstormy16.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/xstormy16-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/xstormy16-opc.h \
+ cgen.h
+
+DEPTC_xtensa_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xtensa.h \
+ $(INCDIR)/xtensa-config.h sb.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h $(srcdir)/config/xtensa-relax.h \
+ $(INCDIR)/xtensa-isa.h $(srcdir)/config/xtensa-istack.h \
+ dwarf2dbg.h struc-symbol.h
+
+DEPTC_z8k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-z8k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/z8k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h $(srcdir)/../opcodes/z8k-opc.h
+
+DEPTC_z8k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-z8k.h \
+ $(INCDIR)/safe-ctype.h $(srcdir)/../opcodes/z8k-opc.h
+
+DEPTC_hppa_som = $(srcdir)/config/tc-hppa.h subsegs.h \
+ $(INCDIR)/obstack.h $(BFDDIR)/libhppa.h $(INCDIR)/opcode/hppa.h \
+ $(BFDDIR)/som.h
+
+DEPTC_i386_multi = $(DEPTC_i386_aout) $(DEPTC_i386_coff) \
+ $(DEPTC_i386_elf)
+
+DEPTC_mips_multi = $(DEPTC_mips_coff) $(DEPTC_mips_ecoff) \
+ $(DEPTC_mips_elf)
+
+DEPTC_cris_multi = $(DEPTC_cris_aout) $(DEPTC_cris_elf)
+DEPOBJ_a29k_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-a29k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+
+DEPOBJ_a29k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-a29k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/a29k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_a29k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-a29k.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_alpha_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-alpha.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_alpha_ecoff = $(INCDIR)/symcat.h $(srcdir)/config/obj-ecoff.h \
+ $(srcdir)/config/tc-alpha.h ecoff.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(BFDDIR)/libecoff.h
+
+DEPOBJ_alpha_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-alpha.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h ecoff.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/elf/alpha.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/aout/aout64.h
+
+DEPOBJ_alpha_evax = $(INCDIR)/symcat.h $(srcdir)/config/obj-evax.h \
+ $(srcdir)/config/tc-alpha.h
+
+DEPOBJ_arc_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-arc.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_arc_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arc.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_arm_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-arm.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+
+DEPOBJ_arm_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-arm.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/arm.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_arm_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arm.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_avr_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-avr.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_avr_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-avr.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_cris_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-cris.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+
+DEPOBJ_cris_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-cris.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_d10v_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-d10v.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_d10v_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d10v.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_d30v_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-d30v.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_d30v_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d30v.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_dlx_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-dlx.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_dlx_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-dlx.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_fr30_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-fr30.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_fr30_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-fr30.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_frv_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-frv.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_frv_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-frv.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_h8300_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-h8300.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/h8300.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_h8300_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8300.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_h8500_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-h8500.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/h8500.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_h8500_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8500.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_hppa_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-hppa.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_hppa_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-hppa.h \
+ $(BFDDIR)/elf32-hppa.h $(BFDDIR)/libhppa.h $(INCDIR)/elf/hppa.h \
+ $(INCDIR)/elf/reloc-macros.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h struc-symbol.h dwarf2dbg.h \
+ $(INCDIR)/aout/aout64.h
+
+DEPOBJ_ia64_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-ia64.h $(INCDIR)/opcode/ia64.h \
+ $(INCDIR)/elf/ia64.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_ia64_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ia64.h \
+ $(INCDIR)/opcode/ia64.h $(INCDIR)/elf/ia64.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_i370_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-i370.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_i370_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i370.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/elf/i370.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/aout/aout64.h
+
+DEPOBJ_i386_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-i386.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+
+DEPOBJ_i386_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-i386.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/i386.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_i386_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i386.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_i860_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i860.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_i960_bout = $(INCDIR)/symcat.h $(srcdir)/config/obj-bout.h \
+ $(srcdir)/config/tc-i960.h $(INCDIR)/obstack.h
+
+DEPOBJ_i960_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-i960.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/i960.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_i960_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_ip2k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-ip2k.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_ip2k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ip2k.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_m32r_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-m32r.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_m32r_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32r.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_m68hc11_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-m68hc11.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/m68k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_m68hc11_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68hc11.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_m68k_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-m68k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+
+DEPOBJ_m68k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-m68k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/m68k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_m68k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68k.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_m68k_hp300 = $(srcdir)/config/obj-aout.c $(INCDIR)/symcat.h \
+ $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+
+DEPOBJ_m88k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-m88k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/m88k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_m88k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m88k.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_mcore_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-mcore.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/mcore.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_mcore_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mcore.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_mips_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-mips.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+
+DEPOBJ_mips_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-mips.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/mipspe.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_mips_ecoff = $(INCDIR)/symcat.h $(srcdir)/config/obj-ecoff.h \
+ $(srcdir)/config/tc-mips.h ecoff.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(BFDDIR)/libecoff.h
+
+DEPOBJ_mips_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mips.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h ecoff.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/aout/aout64.h
+
+DEPOBJ_mmix_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mmix.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_mn10200_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-mn10200.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_mn10200_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10200.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_mn10300_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-mn10300.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_mn10300_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10300.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_msp430_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-msp430.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_msp430_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-msp430.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_ns32k_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-ns32k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+
+DEPOBJ_ns32k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-ns32k.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_ns32k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ns32k.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_openrisc_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-openrisc.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_openrisc_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-openrisc.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_or32_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-or32.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/or32.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_or32_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-or32.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_pdp11_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-pdp11.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+
+DEPOBJ_pdp11_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-pdp11.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_pdp11_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-pdp11.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_pj_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-pj.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_pj_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-pj.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_ppc_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-ppc.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/rs6000.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_ppc_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ppc.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/aout/aout64.h
+
+DEPOBJ_s390_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-s390.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_s390_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-s390.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_sh_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-sh.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/sh.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_sh_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_sh64_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh64.h \
+ $(srcdir)/config/tc-sh.h $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h \
+ $(BFDDIR)/elf32-sh64.h $(INCDIR)/safe-ctype.h subsegs.h \
+ $(INCDIR)/obstack.h struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_sparc_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-sparc.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+
+DEPOBJ_sparc_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-sparc.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/sparc.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_sparc_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sparc.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_tahoe_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-tahoe.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+
+DEPOBJ_tahoe_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tahoe.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_tahoe_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tahoe.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_tic30_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-tic30.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+
+DEPOBJ_tic30_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tic30.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/tic30.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_tic30_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic30.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_tic4x_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tic4x.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/tic4x.h $(INCDIR)/coff/ti.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_tic4x_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic4x.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_tic54x_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tic54x.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/tic54x.h $(INCDIR)/coff/ti.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_tic54x_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic54x.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_tic80_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-tic80.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/tic80.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_tic80_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic80.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_vax_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-vax.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+
+DEPOBJ_vax_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-vax.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_vax_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_vax_vms = $(INCDIR)/symcat.h $(srcdir)/config/obj-vms.h \
+ $(srcdir)/config/tc-vax.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/safe-ctype.h subsegs.h \
+ $(INCDIR)/obstack.h
+
+DEPOBJ_w65_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-w65.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/w65.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_w65_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-w65.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_v850_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-v850.h $(INCDIR)/elf/v850.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_v850_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-v850.h \
+ $(INCDIR)/elf/v850.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h struc-symbol.h dwarf2dbg.h \
+ $(INCDIR)/aout/aout64.h
+
+DEPOBJ_xstormy16_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-xstormy16.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h
+
+DEPOBJ_xstormy16_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xstormy16.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_xtensa_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xtensa.h \
+ $(INCDIR)/xtensa-config.h $(INCDIR)/safe-ctype.h subsegs.h \
+ $(INCDIR)/obstack.h struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_z8k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-z8k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/z8k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+DEPOBJ_z8k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-z8k.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
+DEPOBJ_hppa_som = $(srcdir)/config/obj-som.h subsegs.h \
+ $(INCDIR)/obstack.h $(BFDDIR)/libhppa.h $(BFDDIR)/som.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+
+DEPOBJ_i386_multi = $(DEPOBJ_i386_aout) $(DEPOBJ_i386_coff) \
+ $(DEPOBJ_i386_elf)
+
+DEPOBJ_mips_multi = $(DEPOBJ_mips_coff) $(DEPOBJ_mips_ecoff) \
+ $(DEPOBJ_mips_elf)
+
+DEPOBJ_cris_multi = $(DEPOBJ_cris_aout) $(DEPOBJ_cris_elf)
+DEP_a29k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-a29k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_a29k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-a29k.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/a29k.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_a29k_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-a29k.h
+
+DEP_alpha_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-alpha.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_alpha_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-alpha.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+
+DEP_alpha_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-alpha.h
+
+DEP_alpha_evax = $(srcdir)/config/obj-evax.h $(srcdir)/config/tc-alpha.h
+DEP_arc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arc.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_arc_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arc.h
+
+DEP_arm_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-arm.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_arm_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arm.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/arm.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_arm_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arm.h
+
+DEP_avr_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-avr.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_avr_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-avr.h
+
+DEP_cris_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-cris.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_cris_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-cris.h
+
+DEP_d10v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d10v.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_d10v_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d10v.h
+
+DEP_d30v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d30v.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_d30v_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d30v.h
+
+DEP_dlx_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-dlx.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_dlx_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-dlx.h
+
+DEP_fr30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-fr30.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_fr30_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-fr30.h
+
+DEP_frv_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-frv.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_frv_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-frv.h
+
+DEP_h8300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8300.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8300.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_h8300_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8300.h
+
+DEP_h8500_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8500.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8500.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_h8500_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8500.h
+
+DEP_hppa_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-hppa.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_hppa_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-hppa.h \
+ $(BFDDIR)/elf32-hppa.h $(BFDDIR)/libhppa.h $(INCDIR)/elf/hppa.h \
+ $(INCDIR)/elf/reloc-macros.h
+
+DEP_ia64_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ia64.h \
+ $(INCDIR)/opcode/ia64.h $(INCDIR)/symcat.h $(INCDIR)/elf/ia64.h \
+ $(INCDIR)/elf/reloc-macros.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_ia64_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ia64.h \
+ $(INCDIR)/opcode/ia64.h $(INCDIR)/elf/ia64.h $(INCDIR)/elf/reloc-macros.h
+
+DEP_i370_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i370.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_i370_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i370.h
+
+DEP_i386_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i386.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_i386_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i386.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/i386.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_i386_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i386.h
+
+DEP_i860_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i860.h
+
+DEP_i960_bout = $(srcdir)/config/obj-bout.h $(srcdir)/config/tc-i960.h
+DEP_i960_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i960.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/i960.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_i960_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h
+
+DEP_ip2k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ip2k.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_ip2k_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ip2k.h
+
+DEP_m32r_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m32r.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_m32r_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32r.h
+
+DEP_m68hc11_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m68hc11.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/m68k.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_m68hc11_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68hc11.h
+
+DEP_m68k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_m68k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m68k.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/m68k.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_m68k_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68k.h
+
+DEP_m68k_hp300 = $(srcdir)/config/obj-hp300.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-m68k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_m88k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m88k.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/m88k.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_m88k_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m88k.h
+
+DEP_mcore_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mcore.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/mcore.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_mcore_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mcore.h
+
+DEP_mips_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-mips.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_mips_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mips.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/mipspe.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_mips_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-mips.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+
+DEP_mips_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mips.h
+
+DEP_mmix_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mmix.h
+
+DEP_mn10200_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10200.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_mn10200_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10200.h
+
+DEP_mn10300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10300.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_mn10300_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10300.h
+
+DEP_msp430_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-msp430.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_msp430_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-msp430.h
+
+DEP_ns32k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-ns32k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_ns32k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ns32k.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_ns32k_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ns32k.h
+
+DEP_openrisc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-openrisc.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_openrisc_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-openrisc.h
+
+DEP_or32_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-or32.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/or32.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_or32_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-or32.h
+
+DEP_pdp11_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-pdp11.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_pdp11_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-pdp11.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_pdp11_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-pdp11.h
+
+DEP_pj_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-pj.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_pj_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-pj.h
+
+DEP_ppc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ppc.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/rs6000.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_ppc_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ppc.h
+
+DEP_s390_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-s390.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_s390_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-s390.h
+
+DEP_sh_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sh.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/sh.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_sh_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh.h
+
+DEP_sh64_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh64.h \
+ $(srcdir)/config/tc-sh.h $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h \
+ $(BFDDIR)/elf32-sh64.h
+
+DEP_sparc_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-sparc.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_sparc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sparc.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/sparc.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_sparc_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sparc.h
+
+DEP_tahoe_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tahoe.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_tahoe_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tahoe.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_tahoe_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tahoe.h
+
+DEP_tic30_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tic30.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_tic30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic30.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic30.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_tic30_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic30.h
+
+DEP_tic4x_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic4x.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic4x.h \
+ $(INCDIR)/coff/ti.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_tic4x_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic4x.h
+
+DEP_tic54x_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic54x.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic54x.h \
+ $(INCDIR)/coff/ti.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_tic54x_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic54x.h
+
+DEP_tic80_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic80.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic80.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_tic80_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic80.h
+
+DEP_vax_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-vax.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_vax_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_vax_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-vax.h
+
+DEP_vax_vms = $(srcdir)/config/obj-vms.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+
+DEP_w65_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-w65.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/w65.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_w65_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-w65.h
+
+DEP_v850_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-v850.h \
+ $(INCDIR)/elf/v850.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/symcat.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_v850_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-v850.h \
+ $(INCDIR)/elf/v850.h $(INCDIR)/elf/reloc-macros.h
+
+DEP_xstormy16_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-xstormy16.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_xstormy16_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xstormy16.h
+
+DEP_xtensa_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xtensa.h \
+ $(INCDIR)/xtensa-config.h
+
+DEP_z8k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-z8k.h \
+ $(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/z8k.h \
+ $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_z8k_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-z8k.h
+
+DEP_hppa_som = $(BFDDIR)/som.h
+DEP_i386_multi = $(DEP_i386_aout) $(DEP_i386_coff) \
+ $(DEP_i386_elf)
+
+DEP_mips_multi = $(DEP_mips_coff) $(DEP_mips_ecoff) \
+ $(DEP_mips_elf)
+
+DEP_cris_multi = $(DEP_cris_aout) $(DEP_cris_elf)
+BMKDEP = #DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING ABOVE.
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .l .lo .o .obj .y
+am--refresh:
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \
+ cd $(srcdir) && $(AUTOMAKE) --foreign \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+config.h: stamp-h1
+ @if test ! -f $@; then \
+ rm -f stamp-h1; \
+ $(MAKE) stamp-h1; \
+ else :; fi
+
+stamp-h1: $(srcdir)/config.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+gdb.ini: $(top_builddir)/config.status $(srcdir)/gdbinit.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+.gdbinit: $(top_builddir)/config.status $(srcdir)/gdbinit.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+po/Makefile.in: $(top_builddir)/config.status $(top_srcdir)/po/Make-in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+as-new$(EXEEXT): $(as_new_OBJECTS) $(as_new_DEPENDENCIES)
+ @rm -f as-new$(EXEEXT)
+ $(LINK) $(as_new_LDFLAGS) $(as_new_OBJECTS) $(as_new_LDADD) $(LIBS)
+itbl-test$(EXEEXT): $(itbl_test_OBJECTS) $(itbl_test_DEPENDENCIES)
+ @rm -f itbl-test$(EXEEXT)
+ $(LINK) $(itbl_test_LDFLAGS) $(itbl_test_OBJECTS) $(itbl_test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+.l.c:
+ $(LEXCOMPILE) $<
+ sed '/^#/ s|$(LEX_OUTPUT_ROOT)\.c|$@|' $(LEX_OUTPUT_ROOT).c >$@
+ rm -f $(LEX_OUTPUT_ROOT).c
+
+.y.c:
+ $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE)
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @set fnord $$MAKEFLAGS; amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $$MAKEFLAGS; amf=$$2; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) config.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -z "$$unique" && unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) config.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+site.exp: Makefile
+ @echo 'Making a new site.exp file...'
+ @echo '## these variables are automatically generated by make ##' >site.tmp
+ @echo '# Do not edit here. If you wish to override these values' >>site.tmp
+ @echo '# edit the last section' >>site.tmp
+ @echo 'set srcdir $(srcdir)' >>site.tmp
+ @echo "set objdir `pwd`" >>site.tmp
+ @echo 'set build_alias "$(build_alias)"' >>site.tmp
+ @echo 'set build_triplet $(build_triplet)' >>site.tmp
+ @echo 'set host_alias "$(host_alias)"' >>site.tmp
+ @echo 'set host_triplet $(host_triplet)' >>site.tmp
+ @echo 'set target_alias "$(target_alias)"' >>site.tmp
+ @echo 'set target_triplet $(target_triplet)' >>site.tmp
+ @echo '## All variables above are generated by configure. Do Not Edit ##' >>site.tmp
+ @test ! -f site.exp || \
+ sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp
+ @-rm -f site.bak
+ @test ! -f site.exp || mv site.exp site.bak
+ @mv site.tmp site.exp
+
+distclean-DEJAGNU:
+ -rm -f site.exp site.bak
+ -l='$(DEJATOOL)'; for tool in $$l; do \
+ rm -f $$tool.sum $$tool.log; \
+ done
+check-am:
+ $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
+check: check-recursive
+all-am: Makefile $(PROGRAMS) $(SCRIPTS) config.h
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+ -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f $(CONFIG_CLEAN_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -rm -f m68k-parse.c
+ -rm -f itbl-lex.c
+ -rm -f itbl-parse.c
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -f Makefile
+distclean-am: clean-am distclean-DEJAGNU distclean-compile \
+ distclean-generic distclean-hdr distclean-libtool \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-exec-local
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
+ check-DEJAGNU check-am clean clean-generic clean-libtool \
+ clean-noinstPROGRAMS clean-recursive ctags ctags-recursive \
+ distclean distclean-DEJAGNU distclean-compile \
+ distclean-generic distclean-hdr distclean-libtool \
+ distclean-recursive distclean-tags dvi dvi-am html html-am \
+ info info-am install install-am install-data install-data-am \
+ install-exec install-exec-am install-exec-local install-info \
+ install-info-am install-man install-strip installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic maintainer-clean-recursive \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool mostlyclean-recursive pdf pdf-am ps ps-am \
+ tags tags-recursive uninstall uninstall-am uninstall-info-am
+
+po/POTFILES.in: @MAINT@ Makefile
+ for f in $(POTFILES); do echo $$f; done | LC_COLLATE= sort > tmp \
+ && mv tmp $(srcdir)/po/POTFILES.in
+
+$(srcdir)/make-gas.com: stamp-mk.com
+stamp-mk.com: vmsconf.sh Makefile
+ sh $(srcdir)/vmsconf.sh $(GENERIC_OBJS) > new-make.com
+ $(SHELL) $(srcdir)/../move-if-change new-make.com $(srcdir)/make-gas.com
+ touch stamp-mk.com
+diststuff: $(EXTRA_DIST) info
+
+$(OBJS): @ALL_OBJ_DEPS@
+
+# Stuff that every object file depends upon. If anything is removed
+# from this list, remove it from dep-in.sed as well.
+$(OBJS): $(INCDIR)/bin-bugs.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/progress.h $(INCDIR)/fopen-same.h \
+ $(OBJ_FORMAT_H) $(TARG_CPU_H) $(TARG_ENV_H) \
+ as.h asintl.h bignum.h bit_fix.h config.h emul.h expr.h flonum.h \
+ frags.h hash.h listing.h obj.h read.h symbols.h tc.h write.h
+
+check-DEJAGNU: site.exp
+ if [ -d testsuite ]; then \
+ true; \
+ else \
+ mkdir testsuite; \
+ fi
+ rm -f testsuite/site.exp
+ cp site.exp testsuite/site.exp
+ rootme=`pwd`; export rootme; \
+ srcdir=`cd ${srcdir}; pwd` ; export srcdir ; \
+ EXPECT=${EXPECT} ; export EXPECT ; \
+ if [ -f $(top_builddir)/../expect/expect ]; then \
+ TCL_LIBRARY=`cd $(top_srcdir)/../tcl/library && pwd`; \
+ export TCL_LIBRARY; \
+ fi; \
+ runtest=$(RUNTEST); \
+ cd testsuite; \
+ if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+ $$runtest --tool $(DEJATOOL) --srcdir $${srcdir}/testsuite \
+ $(RUNTESTFLAGS); \
+ else echo "WARNING: could not find \`runtest'" 1>&2; :;\
+ fi
+
+# The implicit .c.o rule doesn't work for these, perhaps because of
+# the variables, or perhaps because the sources are not on vpath.
+$(TARG_CPU_O): $(TARG_CPU_C)
+ $(COMPILE) -c $(TARG_CPU_C)
+$(ATOF_TARG_O): $(ATOF_TARG_C)
+ $(COMPILE) -c $(ATOF_TARG_C)
+
+# ecoff.c only has full dependencies when ECOFF_DEBUGGING is defined,
+# so the automatic dependency stuff doesn't work.
+ecoff.o : ecoff.c ecoff.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/symconst.h \
+ $(INCDIR)/aout/stab_gnu.h
+
+# We need all these explicit rules for the multi stuff. Because of
+# these rules, we don't need one for OBJ_FORMAT_O.
+
+obj-aout.o : $(srcdir)/config/obj-aout.c
+ $(COMPILE) -c $(srcdir)/config/obj-aout.c
+obj-bout.o : $(srcdir)/config/obj-bout.c
+ $(COMPILE) -c $(srcdir)/config/obj-bout.c
+obj-coff.o: $(srcdir)/config/obj-coff.c
+ $(COMPILE) -c $(srcdir)/config/obj-coff.c
+obj-ecoff.o : $(srcdir)/config/obj-ecoff.c
+ $(COMPILE) -c $(srcdir)/config/obj-ecoff.c
+obj-elf.o : $(srcdir)/config/obj-elf.c
+ $(COMPILE) -c $(srcdir)/config/obj-elf.c
+obj-evax.o : $(srcdir)/config/obj-evax.c
+ $(COMPILE) -c $(srcdir)/config/obj-evax.c
+obj-hp300.o : $(srcdir)/config/obj-hp300.c
+ $(COMPILE) -c $(srcdir)/config/obj-hp300.c
+obj-ieee.o : $(srcdir)/config/obj-ieee.c
+ $(COMPILE) -c $(srcdir)/config/obj-ieee.c
+obj-multi.o : $(srcdir)/config/obj-multi.c
+ $(COMPILE) -c $(srcdir)/config/obj-multi.c
+obj-som.o : $(srcdir)/config/obj-som.c
+ $(COMPILE) -c $(srcdir)/config/obj-som.c
+obj-vms.o : $(srcdir)/config/obj-vms.c
+ $(COMPILE) -c $(srcdir)/config/obj-vms.c
+
+e-mipself.o : $(srcdir)/config/e-mipself.c
+ $(COMPILE) -c $(srcdir)/config/e-mipself.c
+e-mipsecoff.o : $(srcdir)/config/e-mipsecoff.c
+ $(COMPILE) -c $(srcdir)/config/e-mipsecoff.c
+e-i386aout.o: $(srcdir)/config/e-i386aout.c
+ $(COMPILE) -c $(srcdir)/config/e-i386aout.c
+e-i386coff.o: $(srcdir)/config/e-i386coff.c
+ $(COMPILE) -c $(srcdir)/config/e-i386coff.c
+e-i386elf.o: $(srcdir)/config/e-i386elf.c
+ $(COMPILE) -c $(srcdir)/config/e-i386elf.c
+e-crisaout.o: $(srcdir)/config/e-crisaout.c
+ $(COMPILE) -c $(srcdir)/config/e-crisaout.c
+e-criself.o: $(srcdir)/config/e-criself.c
+ $(COMPILE) -c $(srcdir)/config/e-criself.c
+
+xtensa-relax.o: $(srcdir)/config/xtensa-relax.c
+ $(COMPILE) -c $(srcdir)/config/xtensa-relax.c
+
+# If m68k-parse.y is in a different directory, then ylwrap will use an
+# absolute path when it invokes yacc, which will cause yacc to put the
+# absolute path into the generated file. That's a pain when it comes
+# to generating snapshots, because it introduces spurious diffs.
+# Since when we make the snapshots $(srcdir) = ".", we check for that
+# case and handle it differently. This means that anybody who
+# configures with $(srcdir) = "." will have to set their path in the
+# debugger if they want to debug m68k-parse.y. This is bad, but on
+# the other hand it's good that people who use the prebuilt
+# m68k-parse.c don't get a spurious absolute path.
+m68k-parse.c: $(srcdir)/config/m68k-parse.y
+ f=$(srcdir)/config/m68k-parse.y; \
+ if [ $$f = "./config/m68k-parse.y" ]; then \
+ ln -s config/m68k-parse.y . > /dev/null 2>/dev/null || \
+ ln config/m68k-parse.y . > /dev/null 2>/dev/null || \
+ cp config/m68k-parse.y . >/dev/null 2>/dev/null; \
+ f=m68k-parse.y; \
+ else true; fi; \
+ $(SHELL) $(YLWRAP) "$(YACC)" $$f y.tab.c m68k-parse.c --; \
+ if [ $$f = "m68k-parse.y" ]; then \
+ rm -f m68k-parse.y; \
+ else true; fi
+m68k-parse.o: m68k-parse.c $(srcdir)/config/m68k-parse.h
+
+# Don't let the .y.h rule clobber m68k-parse.h.
+m68k-parse.h: ; @true
+$(srcdir)/config/m68k-parse.h: ; @true
+
+# The instruction table specification lexical analyzer and parser.
+
+itbl-lex.c: $(srcdir)/itbl-lex.l
+itbl-lex.o: itbl-lex.c itbl-parse.h
+
+itbl-parse.o: itbl-parse.c itbl-parse.h $(srcdir)/itbl-ops.h
+
+itbl-ops.o: $(srcdir)/itbl-ops.c $(srcdir)/itbl-ops.h itbl-parse.h
+
+itbl-parse.c itbl-parse.h: $(srcdir)/itbl-parse.y
+ $(SHELL) $(YLWRAP) "$(YACC)" $(srcdir)/itbl-parse.y y.tab.c itbl-parse.c y.tab.h itbl-parse.h -- -d
+
+itbl-tops.o: $(srcdir)/itbl-ops.c $(srcdir)/itbl-ops.h itbl-parse.h
+ $(COMPILE) -o itbl-tops.o -DSTAND_ALONE -c $(srcdir)/itbl-ops.c
+
+itbl-test.o: $(srcdir)/testsuite/gas/all/itbl-test.c $(srcdir)/itbl-ops.h
+ $(COMPILE) -c -DSTAND_ALONE $(srcdir)/testsuite/gas/all/itbl-test.c
+
+cgen.o: cgen.c cgen.h cgen-desc.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/$(CGEN_CPU_PREFIX)-desc.h \
+ $(srcdir)/../opcodes/$(CGEN_CPU_PREFIX)-opc.h
+
+.PHONY: install-exec-local install-data-local
+.PHONY: install-exec-bindir install-exec-tooldir
+
+install-exec-local: install-exec-bindir @install_tooldir@
+
+install-exec-bindir: $(noinst_PROGRAMS)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+install-exec-tooldir: install-exec-bindir $(noinst_PROGRAMS)
+ $(mkinstalldirs) $(DESTDIR)$(tooldir)/bin
+ n=`echo as | sed '$(transform)'`; \
+ if [ "$(bindir)/$$n$(EXEEXT)" != "$(tooldir)/bin/as$(EXEEXT)" ]; then \
+ rm -f $(DESTDIR)$(tooldir)/bin/as$(EXEEXT); \
+ ln $(DESTDIR)$(bindir)/$$n$(EXEEXT) $(DESTDIR)$(tooldir)/bin/as$(EXEEXT) >/dev/null 2>/dev/null \
+ || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) as-new$(EXEEXT) $(DESTDIR)$(tooldir)/bin/as$(EXEEXT); \
+ else \
+ true ; \
+ fi
+
+# These exist for maintenance purposes.
+
+.PHONY: bootstrap bootstrap2 bootstrap3 stage1 stage2 stage3 comparison
+
+bootstrap: as-new
+ $(MAKE) stage1
+ rm -f stage && ln -s stage1 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) stage2
+ rm -f stage && ln -s stage2 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) comparison against=stage2
+
+bootstrap2:
+ rm -f stage && ln -s stage1 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) stage2
+ rm -f stage && ln -s stage2 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) comparison against=stage2
+
+bootstrap3:
+ rm -f stage && ln -s stage2 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) comparison against=stage2
+
+# Copy the object files from a particular stage into a subdirectory.
+stage1:
+ -mkdir stage1
+ -mv $(STAGESTUFF) stage1
+ if [ -f stage1/as-new$(EXEEXT) -a ! -f stage1/as$(EXEEXT) ] ; then (cd stage1 ; ln -s as-new$(EXEEXT) as$(EXEEXT)) ; fi
+
+stage2:
+ -mkdir stage2
+ -mv $(STAGESTUFF) stage2
+ if [ -f stage2/as-new$(EXEEXT) -a ! -f stage2/as$(EXEEXT) ] ; then (cd stage2 ; ln -s as-new$(EXEEXT) as$(EXEEXT)) ; fi
+
+stage3:
+ -mkdir stage3
+ -mv $(STAGESTUFF) stage3
+ if [ -f stage3/as-new$(EXEEXT) -a ! -f stage3/as$(EXEEXT) ] ; then (cd stage3 ; ln -s as-new as$(EXEEXT)) ; fi
+
+# This rule is derived from corresponding code in the Makefile.in for gcc.
+# The "tail +16c" is to bypass headers which may include timestamps or
+# temporary assembly file names.
+comparison:
+ x=0 ; \
+ for file in *.o ; do \
+ tail +16c ./$$file > tmp-foo1; \
+ if tail +16c ${against}/$$file > tmp-foo2 2>/dev/null ; then \
+ if cmp tmp-foo1 tmp-foo2 ; then \
+ true ; \
+ else \
+ echo $$file differs ; \
+ x=1 ; \
+ fi ; \
+ else true; fi ; \
+ done ; \
+ exit $$x
+ -rm -f tmp-foo*
+
+.PHONY: de-stage1 de-stage2 de-stage3
+
+de-stage1:
+ - (cd stage1 ; rm -f as$(EXEEXT) ; mv -f * ..)
+ - rmdir stage1
+
+de-stage2:
+ - (cd stage2 ; rm -f as$(EXEEXT) ; mv -f * ..)
+ - rmdir stage2
+
+de-stage3:
+ - (cd stage3 ; rm -f as$(EXEEXT) ; mv -f * ..)
+ - rmdir stage3
+
+# Automatic dependency computation. This is a real pain, because the
+# dependencies change based on target_cpu_type and obj_format.
+# Just to make things even more complicated, automake separates the
+# dependency variable assignments from the dependency rules, and tacks
+# on a .NOEXPORT at the end of Makefile.in.
+
+DEP: dep.sed $(DEP_FILE_DEPS) DEPTC DEPOBJ DEP2
+ rm -f DEP1 # delete because we use $? in DEP1 rule
+ srcdir=`cd $(srcdir); pwd`; \
+ $(MAKE) MKDEP="$(MKDEP)" srcdir="$${srcdir}" VPATH="$${srcdir}" DEP1
+ rm -rf DEPDIR
+ echo 'AMKDEP = #DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING BELOW.' > DEPA
+ sed -f dep.sed < DEPTC >> DEPA
+ sed -f dep.sed < DEPOBJ >> DEPA
+ sed -f dep.sed < DEP2 >> DEPA
+ echo 'BMKDEP = #DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING ABOVE.' >> DEPA
+ echo '#MKDEP DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING BELOW.' >> DEPA
+ sed -f dep.sed < DEP1 >> DEPA
+ echo '$$(OBJS): $$(DEP_@target''_cpu_type@_@obj''_format@)' >> DEPA
+ echo '$$(TARG_CPU_O): $$(DEPTC_@target''_cpu_type@_@obj''_format@)' >> DEPA
+ echo '$$(OBJ_FORMAT_O): $$(DEPOBJ_@target''_cpu_type@_@obj''_format@)' >> DEPA
+ echo '#MKDEP DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING ABOVE.' >> DEPA
+ if grep ' /' DEPA > /dev/null 2> /dev/null; then \
+ echo 'make DEP failed!'; exit 1; \
+ else \
+ mv -f DEPA $@; \
+ fi
+
+DEP1: $(CFILES) $(MULTI_CFILES)
+ if [ -d DEPDIR ]; then true; else mkdir DEPDIR; fi
+ srcdir=`cd $(srcdir); pwd`; \
+ cd DEPDIR; \
+ echo '' > targ-cpu.h; \
+ echo '' > obj-format.h; \
+ echo '' > targ-env.h; \
+ echo '' > itbl-cpu.h; \
+ echo '' > itbl-parse.h; \
+ $(MKDEP) $(DEP_FLAGS) $? > DEP
+ mv -f DEPDIR/DEP $@
+
+# Work out the special dependencies for the tc-*.c files.
+DEPTC: $(TARGET_CPU_CFILES)
+ rm -f DEPTCA
+ if [ -d DEPDIR ]; then true; else mkdir DEPDIR; fi
+ srcdir=`cd $(srcdir); pwd`; \
+ cd DEPDIR; \
+ for c in $(CPU_TYPES); do \
+ for o in $(OBJ_FORMATS); do \
+ $(CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '#include "tc-'"$${c}"'.h"' > targ-cpu.h; \
+ echo '#include "obj-'"$${o}"'.h"' > obj-format.h; \
+ echo '#include "te-generic.h"' > targ-env.h; \
+ echo '' > itbl-cpu.h; \
+ echo '' > itbl-parse.h; \
+ echo '#include "opcodes/'"$${c}"'-desc.h"' > cgen-desc.h; \
+ rm -f dummy.c; \
+ cp $${srcdir}/config/tc-$${c}.c dummy.c; \
+ $(MKDEP) $(DEP_FLAGS) dummy.c | \
+ sed -e "s/dummy.o: dummy.c/DEPTC_$${c}_$${o} =/" >> ../DEPTCA; \
+ rm -f dummy.c; \
+ else true; fi; \
+ done; \
+ done
+ echo 'DEPTC_hppa_som = $$(srcdir)/config/tc-hppa.h subsegs.h \' >> DEPTCA
+ echo ' $$(INCDIR)/obstack.h $$(BFDDIR)/libhppa.h \' >> DEPTCA
+ echo ' $$(INCDIR)/opcode/hppa.h $$(BFDDIR)/som.h' >> DEPTCA
+ for c in $(MULTI_CPU_TYPES); do \
+ echo "DEPTC_$${c}"'_multi = \' >> DEPTCA; \
+ for o in $(OBJ_FORMATS); do \
+ $(MULTI_CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '$$(DEPTC_'"$${c}_$${o}"') \' >> DEPTCA; \
+ else true; fi; \
+ done; \
+ echo '' >> DEPTCA; \
+ done
+ mv -f DEPTCA DEPTC
+
+# Work out the special dependencies for the obj-*.c files.
+DEPOBJ: $(OBJ_FORMAT_CFILES)
+ rm -f DEPOBJA
+ if [ -d DEPDIR ]; then true; else mkdir DEPDIR; fi
+ srcdir=`cd $(srcdir); pwd`; \
+ cd DEPDIR; \
+ for c in $(CPU_TYPES); do \
+ for o in $(OBJ_FORMATS); do \
+ $(CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '#include "tc-'"$${c}"'.h"' > targ-cpu.h; \
+ echo '#include "obj-'"$${o}"'.h"' > obj-format.h; \
+ echo '#include "te-generic.h"' > targ-env.h; \
+ echo '' > itbl-cpu.h; \
+ echo '' > itbl-parse.h; \
+ rm -f dummy.c; \
+ cp $${srcdir}/config/obj-$${o}.c dummy.c; \
+ $(MKDEP) $(DEP_FLAGS) dummy.c | \
+ sed -e "s/dummy.o: dummy.c/DEPOBJ_$${c}_$${o} =/" >> ../DEPOBJA; \
+ rm -f dummy.c; \
+ else true; fi; \
+ done; \
+ done
+ echo 'DEPOBJ_hppa_som = $$(srcdir)/config/obj-som.h subsegs.h \' >> DEPOBJA
+ echo ' $$(INCDIR)/obstack.h $$(BFDDIR)/libhppa.h \' >> DEPOBJA
+ echo ' $$(BFDDIR)/som.h $$(INCDIR)/aout/stab_gnu.h \' >> DEPOBJA
+ echo ' $$(INCDIR)/aout/stab.def' >> DEPOBJA
+ for c in $(MULTI_CPU_TYPES); do \
+ echo "DEPOBJ_$${c}"'_multi = \' >> DEPOBJA; \
+ for o in $(OBJ_FORMATS); do \
+ $(MULTI_CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '$$(DEPOBJ_'"$${c}_$${o}"') \' >> DEPOBJA; \
+ else true; fi; \
+ done; \
+ echo '' >> DEPOBJA; \
+ done
+ mv -f DEPOBJA DEPOBJ
+
+# Work out the dependencies for each CPU/OBJ combination.
+# Note that SOM is a special case, because it only works native.
+DEP2: $(TARGET_CPU_HFILES) $(OBJ_FORMAT_HFILES)
+ rm -f DEP2A
+ if [ -d DEPDIR ]; then true; else mkdir DEPDIR; fi
+ srcdir=`cd $(srcdir); pwd`; \
+ cd DEPDIR; \
+ for c in $(CPU_TYPES); do \
+ for o in $(OBJ_FORMATS); do \
+ $(CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '#include "tc-'"$${c}"'.h"' > targ-cpu.h; \
+ echo '#include "obj-'"$${o}"'.h"' > dummy.c; \
+ $(MKDEP) $(DEP_FLAGS) dummy.c | \
+ sed -e "s/dummy.o: dummy.c/DEP_$${c}_$${o} =/" >> ../DEP2A; \
+ else true; fi; \
+ done; \
+ done
+ echo 'DEP_hppa_som = $$(BFDDIR)/som.h' >> DEP2A
+ for c in $(MULTI_CPU_TYPES); do \
+ echo "DEP_$${c}"'_multi = \' >> DEP2A; \
+ for o in $(OBJ_FORMATS); do \
+ $(MULTI_CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '$$(DEP_'"$${c}_$${o}"') \' >> DEP2A; \
+ else true; fi; \
+ done; \
+ echo '' >> DEP2A; \
+ done
+ mv -f DEP2A DEP2
+
+dep.sed: dep-in.sed config.status
+ srcdir=`cd $(srcdir); pwd`; \
+ sed <$(srcdir)/dep-in.sed >dep.sed \
+ -e "s!@INCDIR@!$${srcdir}/../include!" \
+ -e "s!@BFDDIR@!$${srcdir}/../bfd!" \
+ -e "s!@SRCDIR@!$${srcdir}!" \
+ -e 's!@TOPDIR@!'`echo $(srcdir) | sed -e s,/gas,,`'!'
+
+dep: DEP
+ sed -e '/^.MKDEP.*WARNING BELOW./,/^.MKDEP.*WARNING ABOVE./d' \
+ < Makefile > tmp-Makefile
+ cat DEP >> tmp-Makefile
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile Makefile
+
+dep-in: DEP
+ sed -e '/^.MKDEP.*WARNING BELOW./,/^.MKDEP.*WARNING ABOVE./d' \
+ < $(srcdir)/Makefile.in > tmp-Makefile.in
+ cat DEP >> tmp-Makefile.in
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in
+
+dep-am: DEP
+ sed -e '/^.MKDEP.*WARNING BELOW./,/^.MKDEP.*WARNING ABOVE./d' \
+ < $(srcdir)/Makefile.am > tmp-Makefile.am
+ cat DEP >> tmp-Makefile.am
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am
+
+# HEED THE MKDEP WARNINGS.
+# ANYTHING CHANGED OR ADDED BETWEEN THE WARNING LINES MAY GO AWAY.
+.PHONY: dep dep-in dep-am
+#MKDEP DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING BELOW.
+app.o: app.c $(INCDIR)/symcat.h
+as.o: as.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h \
+ output-file.h sb.h macro.h dwarf2dbg.h dw2gencfi.h \
+ $(INCDIR)/elf/dwarf2.h $(BFDVER_H)
+atof-generic.o: atof-generic.c $(INCDIR)/symcat.h $(INCDIR)/safe-ctype.h
+bignum-copy.o: bignum-copy.c $(INCDIR)/symcat.h
+cond.o: cond.c $(INCDIR)/symcat.h macro.h sb.h $(INCDIR)/obstack.h
+depend.o: depend.c $(INCDIR)/symcat.h
+dwarf2dbg.o: dwarf2dbg.c $(INCDIR)/symcat.h dwarf2dbg.h \
+ $(INCDIR)/filenames.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/elf/dwarf2.h
+dw2gencfi.o: dw2gencfi.c $(INCDIR)/symcat.h dw2gencfi.h \
+ $(INCDIR)/elf/dwarf2.h
+ecoff.o: ecoff.c $(INCDIR)/symcat.h ecoff.h
+ehopt.o: ehopt.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/elf/dwarf2.h
+expr.o: expr.c $(INCDIR)/symcat.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/obstack.h
+flonum-copy.o: flonum-copy.c $(INCDIR)/symcat.h
+flonum-konst.o: flonum-konst.c
+flonum-mult.o: flonum-mult.c
+frags.o: frags.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h
+hash.o: hash.c $(INCDIR)/symcat.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/obstack.h
+input-file.o: input-file.c $(INCDIR)/symcat.h input-file.h \
+ $(INCDIR)/safe-ctype.h
+input-scrub.o: input-scrub.c $(INCDIR)/symcat.h input-file.h \
+ sb.h
+listing.o: listing.c $(INCDIR)/symcat.h $(INCDIR)/obstack.h \
+ $(INCDIR)/safe-ctype.h input-file.h subsegs.h
+literal.o: literal.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h
+macro.o: macro.c $(INCDIR)/safe-ctype.h sb.h macro.h
+messages.o: messages.c $(INCDIR)/symcat.h
+output-file.o: output-file.c $(INCDIR)/symcat.h output-file.h
+read.o: read.c $(INCDIR)/symcat.h $(INCDIR)/safe-ctype.h \
+ subsegs.h $(INCDIR)/obstack.h sb.h macro.h ecoff.h \
+ dw2gencfi.h $(INCDIR)/elf/dwarf2.h
+sb.o: sb.c sb.h
+stabs.o: stabs.c $(INCDIR)/symcat.h $(INCDIR)/obstack.h \
+ subsegs.h ecoff.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+subsegs.o: subsegs.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h
+symbols.o: symbols.c $(INCDIR)/symcat.h $(INCDIR)/safe-ctype.h \
+ $(INCDIR)/obstack.h subsegs.h struc-symbol.h
+write.o: write.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h \
+ output-file.h dwarf2dbg.h
+itbl-ops.o: itbl-ops.c itbl-ops.h $(INCDIR)/symcat.h
+e-crisaout.o: $(srcdir)/config/e-crisaout.c $(INCDIR)/symcat.h \
+ emul-target.h
+e-criself.o: $(srcdir)/config/e-criself.c $(INCDIR)/symcat.h \
+ emul-target.h
+e-i386aout.o: $(srcdir)/config/e-i386aout.c $(INCDIR)/symcat.h \
+ emul-target.h
+e-i386coff.o: $(srcdir)/config/e-i386coff.c $(INCDIR)/symcat.h \
+ emul-target.h
+e-i386elf.o: $(srcdir)/config/e-i386elf.c $(INCDIR)/symcat.h \
+ emul-target.h
+e-mipsecoff.o: $(srcdir)/config/e-mipsecoff.c $(INCDIR)/symcat.h \
+ emul-target.h
+e-mipself.o: $(srcdir)/config/e-mipself.c $(INCDIR)/symcat.h \
+ emul-target.h
+$(OBJS): $(DEP_@target_cpu_type@_@obj_format@)
+$(TARG_CPU_O): $(DEPTC_@target_cpu_type@_@obj_format@)
+$(OBJ_FORMAT_O): $(DEPOBJ_@target_cpu_type@_@obj_format@)
+#MKDEP DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING ABOVE.
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/x/binutils/gas/NEWS b/x/binutils/gas/NEWS
new file mode 100644
index 0000000..1a31e79
--- /dev/null
+++ b/x/binutils/gas/NEWS
@@ -0,0 +1,422 @@
+-*- text -*-
+
+* The MIPS -membedded-pic option (Embedded-PIC code generation) is
+ deprecated and will be removed in a future release.
+
+* Added PIC m32r Linux (ELF) and support to M32R assembler.
+
+* Added support for ARM V6.
+
+* Added support for sh4a and variants.
+
+* Support for Renesas M32R2 added.
+
+* Limited support for Mapping Symbols as specified in the ARM ELF
+ specification has been added to the arm assembler.
+
+* On ARM architectures, added a new gas directive ".unreq" that undoes
+ definitions created by ".req".
+
+* Support for Motorola ColdFire MCF528x added.
+
+* Added --gstabs+ switch to enable the generation of STABS debug format
+ information with GNU extensions.
+
+* Added support for MIPS64 Release 2.
+
+* Added support for v850e1.
+
+* Added -n switch for x86 assembler. By default, x86 GAS replaces
+ multiple nop instructions used for alignment within code sections
+ with multi-byte nop instructions such as leal 0(%esi,1),%esi. This
+ switch disables the optimization.
+
+* Removed -n option from MIPS assembler. It was not useful, and confused the
+ existing -non_shared option.
+
+Changes in 2.14:
+
+* Added support for MIPS32 Release 2.
+
+* Added support for Xtensa architecture.
+
+* Support for Intel's iWMMXt processor (an ARM variant) added.
+
+* An assembler test generator has been contributed and an example file that
+ uses it (gas/testsuite/gas/all/test-gen.c and test-exmaple.c).
+
+* Support for SH2E added.
+
+* GASP has now been removed.
+
+* Support for Texas Instruments TMS320C4x and TMS320C3x series of
+ DSP's contributed by Michael Hayes and Svein E. Seldal.
+
+* Support for the Ubicom IP2xxx microcontroller added.
+
+Changes in 2.13:
+
+* Support for the Fujitsu FRV architecture added by Red Hat. Models for FR400
+ and FR500 included.
+
+* Support for DLX processor added.
+
+* GASP has now been deprecated and will be removed in a future release. Use
+ the macro facilities in GAS instead.
+
+* GASP now correctly parses floating point numbers. Unless the base is
+ explicitly specified, they are interpreted as decimal numbers regardless of
+ the currently specified base.
+
+Changes in 2.12:
+
+* Support for Don Knuth's MMIX, by Hans-Peter Nilsson.
+
+* Support for the OpenRISC 32-bit embedded processor by OpenCores.
+
+* The ARM assembler now accepts -march=..., -mcpu=... and -mfpu=... for
+ specifying the target instruction set. The old method of specifying the
+ target processor has been deprecated, but is still accepted for
+ compatibility.
+
+* Support for the VFP floating-point instruction set has been added to
+ the ARM assembler.
+
+* New psuedo op: .incbin to include a set of binary data at a given point
+ in the assembly. Contributed by Anders Norlander.
+
+* The MIPS assembler now accepts -march/-mtune. -mcpu has been deprecated
+ but still works for compatability.
+
+* The MIPS assembler no longer issues a warning by default when it
+ generates a nop instruction from a macro. The new command line option
+ -n will turn on the warning.
+
+Changes in 2.11:
+
+* Support for PDP-11 and 2.11BSD a.out format, by Lars Brinkhoff.
+
+* x86 gas now supports the full Pentium4 instruction set.
+
+* Support for AMD x86-64 architecture, by Jan Hubicka, SuSE Labs.
+
+* Support for Motorola 68HC11 and 68HC12.
+
+* Support for Texas Instruments TMS320C54x (tic54x).
+
+* Support for IA-64.
+
+* Support for i860, by Jason Eckhardt.
+
+* Support for CRIS (Axis Communications ETRAX series).
+
+* x86 gas has a new .arch pseudo op to specify the target CPU architecture.
+
+* x86 gas -q command line option quietens warnings about register size changes
+ due to suffix, indirect jmp/call without `*', stand-alone prefixes, and
+ translating various deprecated floating point instructions.
+
+Changes in 2.10:
+
+* Support for the ARM msr instruction was changed to only allow an immediate
+ operand when altering the flags field.
+
+* Support for ATMEL AVR.
+
+* Support for IBM 370 ELF. Somewhat experimental.
+
+* Support for numbers with suffixes.
+
+* Added support for breaking to the end of repeat loops.
+
+* Added support for parallel instruction syntax (DOUBLEBAR_PARALLEL).
+
+* New .elseif pseudo-op added.
+
+* New --fatal-warnings option.
+
+* picoJava architecture support added.
+
+* Motorola MCore 210 processor support added.
+
+* A new pseudo-op .intel_syntax has been implemented to allow gas to parse i386
+ assembly programs with intel syntax.
+
+* New pseudo-ops .func,.endfunc to aid in debugging user-written assembler code.
+
+* Added -gdwarf2 option to generate DWARF 2 debugging information.
+
+* Full 16-bit mode support for i386.
+
+* Greatly improved instruction operand checking for i386. This change will
+ produce errors or warnings on incorrect assembly code that previous versions
+ of gas accepted. If you get unexpected messages from code that worked with
+ older versions of gas, please double check the code before reporting a bug.
+
+* Weak symbol support added for COFF targets.
+
+* Mitsubishi D30V support added.
+
+* Texas Instruments c80 (tms320c80) support added.
+
+* i960 ELF support added.
+
+* ARM ELF support added.
+
+Changes in 2.9:
+
+* Texas Instruments c30 (tms320c30) support added.
+
+* The assembler now optimizes the exception frame information generated by egcs
+ and gcc 2.8. The new --traditional-format option disables this optimization.
+
+* Added --gstabs option to generate stabs debugging information.
+
+* The -a option takes a new suboption, m (e.g., -alm) to expand macros in a
+ listing.
+
+* Added -MD option to print dependencies.
+
+Changes in 2.8:
+
+* BeOS support added.
+
+* MIPS16 support added.
+
+* Motorola ColdFire 5200 support added (configure for m68k and use -m5200).
+
+* Alpha/VMS support added.
+
+* m68k options --base-size-default-16, --base-size-default-32,
+ --disp-size-default-16, and --disp-size-default-32 added.
+
+* The alignment directives now take an optional third argument, which is the
+ maximum number of bytes to skip. If doing the alignment would require
+ skipping more than the given number of bytes, the alignment is not done at
+ all.
+
+* The ELF assembler has a new pseudo-op, .symver, used for symbol versioning.
+
+* The -a option takes a new suboption, c (e.g., -alc), to skip false
+ conditionals in listings.
+
+* Added new pseudo-op, .equiv; it's like .equ, except that it is an error if
+ the symbol is already defined.
+
+Changes in 2.7:
+
+* The PowerPC assembler now allows the use of symbolic register names (r0,
+ etc.) if -mregnames is used. Symbolic names preceded by a '%' (%r0, etc.)
+ can be used any time. PowerPC 860 move to/from SPR instructions have been
+ added.
+
+* Alpha Linux (ELF) support added.
+
+* PowerPC ELF support added.
+
+* m68k Linux (ELF) support added.
+
+* i960 Hx/Jx support added.
+
+* i386/PowerPC gnu-win32 support added.
+
+* SCO ELF support added. For OpenServer 5 targets (i386-unknown-sco3.2v5) the
+ default is to build COFF-only support. To get a set of tools that generate
+ ELF (they'll understand both COFF and ELF), you must configure with
+ target=i386-unknown-sco3.2v5elf.
+
+* m88k-motorola-sysv3* support added.
+
+Changes in 2.6:
+
+* Gas now directly supports macros, without requiring GASP.
+
+* Gas now has an MRI assembler compatibility mode. Use -M or --mri to select
+ MRI mode. The pseudo-op ``.mri 1'' will switch into the MRI mode until the
+ ``.mri 0'' is seen; this can be convenient for inline assembler code.
+
+* Added --defsym SYM=VALUE option.
+
+* Added -mips4 support to MIPS assembler.
+
+* Added PIC support to Solaris and SPARC SunOS 4 assembler.
+
+Changes in 2.4:
+
+* Converted this directory to use an autoconf-generated configure script.
+
+* ARM support, from Richard Earnshaw.
+
+* Updated VMS support, from Pat Rankin, including considerably improved
+ debugging support.
+
+* Support for the control registers in the 68060.
+
+* Handles (ignores) a new directive ".this_GCC_requires_the_GNU_assembler", to
+ provide for possible future gcc changes, for targets where gas provides some
+ features not available in the native assembler. If the native assembler is
+ used, it should become obvious pretty quickly what the problem is.
+
+* Usage message is available with "--help".
+
+* The GNU Assembler Preprocessor (gasp) is included. (Actually, it was in 2.3
+ also, but didn't get into the NEWS file.)
+
+* Weak symbol support for a.out.
+
+* A bug in the listing code which could cause an infinite loop has been fixed.
+ Bugs in listings when generating a COFF object file have also been fixed.
+
+* Initial i386-svr4 PIC implementation from Eric Youngdale, based on code by
+ Paul Kranenburg.
+
+* Improved Alpha support. Immediate constants can have a much larger range
+ now. Support for the 21164 has been contributed by Digital.
+
+* Updated ns32k (pc532-mach, netbsd532) support from Ian Dall.
+
+Changes in 2.3:
+
+* Mach i386 support, by David Mackenzie and Ken Raeburn.
+
+* RS/6000 and PowerPC support by Ian Taylor.
+
+* VMS command scripts (make-gas.com, config-gas.com) have been worked on a bit,
+ based on mail received from various people. The `-h#' option should work
+ again too.
+
+* HP-PA work, by Jeff Law. Note, for the PA, gas-2.3 has been designed to work
+ with gdb-4.12 and gcc-2.6. As gcc-2.6 has not been released yet, a special
+ version of gcc-2.5.8 has been patched to work with gas-2.3. You can retrieve
+ this special version of gcc-2.5.8 via anonymous ftp from jaguar.cs.utah.edu
+ in the "dist" directory.
+
+* Vax support in gas fixed for BSD, so it builds and seems to run a couple
+ simple tests okay. I haven't put it through extensive testing. (GNU make is
+ currently required for BSD 4.3 builds.)
+
+* Support for the DEC Alpha, running OSF/1 (ECOFF format). The gas support is
+ based on code donated by CMU, which used an a.out-based format. I'm afraid
+ the alpha-a.out support is pretty badly mangled, and much of it removed;
+ making it work will require rewriting it as BFD support for the format anyways.
+
+* Irix 5 support.
+
+* The test suites have been fixed up a bit, so that they should work with a
+ couple different versions of expect and dejagnu.
+
+* Symbols' values are now handled internally as expressions, permitting more
+ flexibility in evaluating them in some cases. Some details of relocation
+ handling have also changed, and simple constant pool management has been
+ added, to make the Alpha port easier.
+
+* New option "--statistics" for printing out program run times. This is
+ intended to be used with the gcc "-Q" option, which prints out times spent in
+ various phases of compilation. (You should be able to get all of them
+ printed out with "gcc -Q -Wa,--statistics", I think.)
+
+Changes in 2.2:
+
+* RS/6000 AIX and MIPS SGI Irix 5 support has been added.
+
+* Configurations that are still in development (and therefore are convenient to
+ have listed in configure.in) still get rejected without a minor change to
+ gas/Makefile.in, so people not doing development work shouldn't get the
+ impression that support for such configurations is actually believed to be
+ reliable.
+
+* The program name (usually "as") is printed when a fatal error message is
+ displayed. This should prevent some confusion about the source of occasional
+ messages about "internal errors".
+
+* ELF support is falling into place. Support for the 386 should be working.
+ Support for SPARC Solaris is in. HPPA support from Utah is being integrated.
+
+* Symbol values are maintained as expressions instead of being immediately
+ boiled down to add-symbol, sub-symbol, and constant. This permits slightly
+ more complex calculations involving symbols whose values are not alreadey
+ known.
+
+* DBX-style debugging info ("stabs") is now supported for COFF formats.
+ If any stabs directives are seen in the source, GAS will create two new
+ sections: a ".stab" and a ".stabstr" section. The format of the .stab
+ section is nearly identical to the a.out symbol format, and .stabstr is
+ its string table. For this to be useful, you must have configured GCC
+ to generate stabs (by defining DBX_DEBUGGING_INFO), and must have a GDB
+ that can use the stab sections (4.11 or later).
+
+* LynxOS, on i386 and m68k platforms, is now supported. SPARC LynxOS
+ support is in progress.
+
+Changes in 2.1:
+
+* Several small fixes for i386-aix (PS/2) support from Minh Tran-Le have been
+ incorporated, but not well tested yet.
+
+* Altered the opcode table split for m68k; it should require less VM to compile
+ with gcc now.
+
+* Some minor adjustments to add (Convergent Technologies') Miniframe support,
+ suggested by Ronald Cole.
+
+* HPPA support (running OSF only, not HPUX) has been contributed by Utah. This
+ includes improved ELF support, which I've started adapting for SPARC Solaris
+ 2.x. Integration isn't completely, so it probably won't work.
+
+* HP9000/300 support, donated by HP, has been merged in.
+
+* Ian Taylor has finished the MIPS ECOFF (Ultrix, Irix) support.
+
+* Better error messages for unsupported configurations (e.g., hppa-hpux).
+
+* Test suite framework is starting to become reasonable.
+
+Changes in 2.0:
+
+* Mostly bug fixes.
+
+* Some more merging of BFD and ELF code, but ELF still doesn't work.
+
+Changes in 1.94:
+
+* BFD merge is partly done. Adventurous souls may try giving configure the
+ "--with-bfd-assembler" option. Currently, ELF format requires it, a.out
+ format accepts it; SPARC CPU accepts it. It's the default only for OS "elf"
+ or "solaris". (ELF isn't really supported yet. It needs work. I've got
+ some code from Utah for HP-PA ELF, and from DG for m88k ELF, but they're not
+ fully merged yet.)
+
+* The 68K opcode table has been split in half. It should now compile under gcc
+ without consuming ridiculous amounts of memory.
+
+* A couple data structures have been reduced in size. This should result in
+ saving a little bit of space at runtime.
+
+* Support for MIPS, from OSF and Ralph Campbell, has been merged in. The OSF
+ code provided ROSE format support, which I haven't merged in yet. (I can
+ make it available, if anyone wants to try it out.) Ralph's code, for BSD
+ 4.4, supports a.out format. We don't have ECOFF support in just yet; it's
+ coming.
+
+* Support for the Hitachi H8/500 has been added.
+
+* VMS host and target support should be working now, thanks chiefly to Eric
+ Youngdale.
+
+Changes in 1.93.01:
+
+* For m68k, support for more processors has been added: 68040, CPU32, 68851.
+
+* For i386, .align is now power-of-two; was number-of-bytes.
+
+* For m68k, "%" is now accepted before register names. For COFF format, which
+ doesn't use underscore prefixes for C labels, it is required, so variable "a0"
+ can be distinguished from the register.
+
+* Last public release was 1.38. Lots of configuration changes since then, lots
+ of new CPUs and formats, lots of bugs fixed.
+
+
+Local variables:
+fill-column: 79
+End:
diff --git a/x/binutils/gas/README b/x/binutils/gas/README
new file mode 100644
index 0000000..7905395
--- /dev/null
+++ b/x/binutils/gas/README
@@ -0,0 +1,241 @@
+ README for GAS
+
+A number of things have changed since version 1 and the wonderful
+world of gas looks very different. There's still a lot of irrelevant
+garbage lying around that will be cleaned up in time. Documentation
+is scarce, as are logs of the changes made since the last gas release.
+My apologies, and I'll try to get something useful.
+
+Unpacking and Installation - Summary
+====================================
+
+See ../binutils/README.
+
+To build just the assembler, make the target all-gas.
+
+Documentation
+=============
+
+The GAS release includes texinfo source for its manual, which can be processed
+into `info' or `dvi' forms.
+
+The DVI form is suitable for printing or displaying; the commands for doing
+this vary from system to system. On many systems, `lpr -d' will print a DVI
+file. On others, you may need to run a program such as `dvips' to convert the
+DVI file into a form your system can print.
+
+If you wish to build the DVI file, you will need to have TeX installed on your
+system. You can rebuild it by typing:
+
+ cd gas/doc
+ make as.dvi
+
+The Info form is viewable with the GNU Emacs `info' subsystem, or the
+stand-alone `info' program, available as part of the GNU Texinfo distribution.
+To build the info files, you will need the `makeinfo' program. Type:
+
+ cd gas/doc
+ make info
+
+Specifying names for hosts and targets
+======================================
+
+ The specifications used for hosts and targets in the `configure'
+script are based on a three-part naming scheme, but some short
+predefined aliases are also supported. The full naming scheme encodes
+three pieces of information in the following pattern:
+
+ ARCHITECTURE-VENDOR-OS
+
+ For example, you can use the alias `sun4' as a HOST argument or in a
+`--target=TARGET' option. The equivalent full name is
+`sparc-sun-sunos4'.
+
+ The `configure' script accompanying GAS does not provide any query
+facility to list all supported host and target names or aliases.
+`configure' calls the Bourne shell script `config.sub' to map
+abbreviations to full names; you can read the script, if you wish, or
+you can use it to test your guesses on abbreviations--for example:
+
+ % sh config.sub sun4
+ sparc-sun-sunos411
+ % sh config.sub sun3
+ m68k-sun-sunos411
+ % sh config.sub decstation
+ mips-dec-ultrix42
+ % sh config.sub hp300bsd
+ m68k-hp-bsd
+ % sh config.sub i386v
+ i386-unknown-sysv
+ % sh config.sub i786v
+ Invalid configuration `i786v': machine `i786v' not recognized
+
+
+`configure' options
+===================
+
+ Here is a summary of the `configure' options and arguments that are
+most often useful for building GAS. `configure' also has several other
+options not listed here.
+
+ configure [--help]
+ [--prefix=DIR]
+ [--srcdir=PATH]
+ [--host=HOST]
+ [--target=TARGET]
+ [--with-OPTION]
+ [--enable-OPTION]
+
+You may introduce options with a single `-' rather than `--' if you
+prefer; but you may abbreviate option names if you use `--'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`-prefix=DIR'
+ Configure the source to install programs and files under directory
+ `DIR'.
+
+`--srcdir=PATH'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--host=HOST'
+ Configure GAS to run on the specified HOST. Normally the
+ configure script can figure this out automatically.
+
+ There is no convenient way to generate a list of all available
+ hosts.
+
+`--target=TARGET'
+ Configure GAS for cross-assembling programs for the specified
+ TARGET. Without this option, GAS is configured to assemble .o files
+ that run on the same machine (HOST) as GAS itself.
+
+ There is no convenient way to generate a list of all available
+ targets.
+
+`--enable-OPTION'
+ These flags tell the program or library being configured to
+ configure itself differently from the default for the specified
+ host/target combination. See below for a list of `--enable'
+ options recognized in the gas distribution.
+
+`configure' accepts other options, for compatibility with configuring
+other GNU tools recursively; but these are the only options that affect
+GAS or its supporting libraries.
+
+The `--enable' options recognized by software in the gas distribution are:
+
+`--enable-targets=...'
+ This causes one or more specified configurations to be added to those for
+ which BFD support is compiled. Currently gas cannot use any format other
+ than its compiled-in default, so this option is not very useful.
+
+`--enable-bfd-assembler'
+ This causes the assembler to use the new code being merged into it to use
+ BFD data structures internally, and use BFD for writing object files.
+ For most targets, this isn't supported yet. For most targets where it has
+ been done, it's already the default. So generally you won't need to use
+ this option.
+
+Supported platforms
+===================
+
+At this point I believe gas to be ANSI only code for most target cpu's. That
+is, there should be relatively few, if any host system dependencies. So
+porting (as a cross-assembler) to hosts not yet supported should be fairly
+easy. Porting to a new target shouldn't be too tough if it's a variant of one
+already supported.
+
+Native assembling should work on:
+
+ sun3
+ sun4
+ 386bsd
+ bsd/386
+ delta (m68k-sysv from Motorola)
+ delta88 (m88k-sysv from Motorola)
+ GNU/linux
+ m68k hpux 8.0 (hpux 7.0 may be a problem)
+ vax bsd, ultrix, vms
+ hp9000s300
+ decstation
+ irix 4
+ irix 5
+ miniframe (m68k-sysv from Convergent Technologies)
+ i386-aix (ps/2)
+ hppa (hpux 4.3bsd, osf1)
+ AIX
+ unixware
+ sco 3.2v4.2
+ sco openserver 5.0 (a.k.a. 3.2v5.0 )
+ sparc solaris
+ ns32k (netbsd, lites)
+
+I believe that gas as a cross-assembler can currently be targeted for
+most of the above hosts, plus
+
+ arm
+ decstation-bsd (a.out format, to be used in BSD 4.4)
+ ebmon29k
+ go32 (DOS on i386, with DJGPP -- old a.out version)
+ H8/300, H8/500 (Hitachi)
+ i386-aix (ps/2)
+ i960-coff
+ mips ecoff (decstation-ultrix, iris, mips magnum, mips-idt-ecoff)
+ Mitsubishi d10v and d30v
+ nindy960
+ powerpc EABI
+ SH (Hitachi)
+ sco386
+ TI tic30 and tic80
+ vax bsd or ultrix?
+ vms
+ vxworks68k
+ vxworks960
+ z8000 (Zilog)
+
+MIPS ECOFF support has been added, but GAS will not run a C-style
+preprocessor. If you want that, rename your file to have a ".S" suffix, and
+run gcc on it. Or run "gcc -xassembler-with-cpp foo.s".
+
+Support for ELF should work now for sparc, hppa, i386, alpha, m68k,
+MIPS, powerpc.
+
+Support for sequent (ns32k), tahoe, i860 may be suffering from bitrot.
+
+If you try out gas on some host or target not listed above, please let me know
+the results, so I can update the list.
+
+Compiler Support Hacks
+======================
+
+On a few targets, the assembler has been modified to support a feature
+that is potentially useful when assembling compiler output, but which
+may confuse assembly language programmers. If assembler encounters a
+.word pseudo-op of the form symbol1-symbol2 (the difference of two
+symbols), and the difference of those two symbols will not fit in 16
+bits, the assembler will create a branch around a long jump to
+symbol1, and insert this into the output directly before the next
+label: The .word will (instead of containing garbage, or giving an
+error message) contain (the address of the long jump)-symbol2. This
+allows the assembler to assemble jump tables that jump to locations
+very far away into code that works properly. If the next label is
+more than 32K away from the .word, you lose (silently); RMS claims
+this will never happen. If the -K option is given, you will get a
+warning message when this happens.
+
+
+REPORTING BUGS IN GAS
+=====================
+
+Bugs in gas should be reported to:
+
+ bug-binutils@gnu.org.
+
+They may be cross-posted to gcc-bugs@gnu.org if they affect the use of
+gas with gcc. They should not be reported just to gcc-bugs, since not
+all of the maintainers read that list.
+
+See ../binutils/README for what we need in a bug report.
diff --git a/x/binutils/gas/acconfig.h b/x/binutils/gas/acconfig.h
new file mode 100644
index 0000000..c9c6002
--- /dev/null
+++ b/x/binutils/gas/acconfig.h
@@ -0,0 +1,79 @@
+/* Name of package. */
+#undef PACKAGE
+
+/* Version of package. */
+#undef VERSION
+
+/* Should gas use high-level BFD interfaces? */
+#undef BFD_ASSEMBLER
+
+/* Some assert/preprocessor combinations are incapable of handling
+ certain kinds of constructs in the argument of assert. For example,
+ quoted strings (if requoting isn't done right) or newlines. */
+#undef BROKEN_ASSERT
+
+/* If we aren't doing cross-assembling, some operations can be optimized,
+ since byte orders and value sizes don't need to be adjusted. */
+#undef CROSS_COMPILE
+
+/* Some gas code wants to know these parameters. */
+#undef TARGET_ALIAS
+#undef TARGET_CPU
+#undef TARGET_CANONICAL
+#undef TARGET_OS
+#undef TARGET_VENDOR
+
+/* Sometimes the system header files don't declare strstr. */
+#undef NEED_DECLARATION_STRSTR
+
+/* Sometimes the system header files don't declare malloc and realloc. */
+#undef NEED_DECLARATION_MALLOC
+
+/* Sometimes the system header files don't declare free. */
+#undef NEED_DECLARATION_FREE
+
+/* Sometimes the system header files don't declare sbrk. */
+#undef NEED_DECLARATION_SBRK
+
+/* Sometimes errno.h doesn't declare errno itself. */
+#undef NEED_DECLARATION_ERRNO
+
+#undef MANY_SEGMENTS
+
+/* The configure script defines this for some targets based on the
+ target name used. It is not always defined. */
+#undef TARGET_BYTES_BIG_ENDIAN
+
+/* Needed only for some configurations that can produce multiple output
+ formats. */
+#undef DEFAULT_EMULATION
+#undef EMULATIONS
+#undef USE_EMULATIONS
+#undef OBJ_MAYBE_AOUT
+#undef OBJ_MAYBE_BOUT
+#undef OBJ_MAYBE_COFF
+#undef OBJ_MAYBE_ECOFF
+#undef OBJ_MAYBE_ELF
+#undef OBJ_MAYBE_GENERIC
+#undef OBJ_MAYBE_HP300
+#undef OBJ_MAYBE_IEEE
+#undef OBJ_MAYBE_SOM
+#undef OBJ_MAYBE_VMS
+
+/* Used for some of the COFF configurations, when the COFF code needs
+ to select something based on the CPU type before it knows it... */
+#undef I386COFF
+#undef M68KCOFF
+#undef M88KCOFF
+
+/* Using cgen code? */
+#undef USING_CGEN
+
+/* Needed only for sparc configuration. */
+#undef DEFAULT_ARCH
+
+/* Needed only for PowerPC Solaris. */
+#undef TARGET_SOLARIS_COMMENT
+
+/* Needed only for SCO 5. */
+#undef SCO_ELF
diff --git a/x/binutils/gas/acinclude.m4 b/x/binutils/gas/acinclude.m4
new file mode 100644
index 0000000..4a3ccf3
--- /dev/null
+++ b/x/binutils/gas/acinclude.m4
@@ -0,0 +1,72 @@
+dnl GAS_CHECK_DECL_NEEDED(name, typedefname, typedef, headers)
+AC_DEFUN([GAS_CHECK_DECL_NEEDED],[
+AC_MSG_CHECKING(whether declaration is required for $1)
+AC_CACHE_VAL(gas_cv_decl_needed_$1,
+AC_TRY_LINK([$4],
+[
+typedef $3;
+$2 x;
+x = ($2) $1;
+], gas_cv_decl_needed_$1=no, gas_cv_decl_needed_$1=yes))dnl
+AC_MSG_RESULT($gas_cv_decl_needed_$1)
+if test $gas_cv_decl_needed_$1 = yes; then
+ AC_DEFINE([NEED_DECLARATION_]translit($1, [a-z], [A-Z]), 1,
+ [Define if $1 is not declared in system header files.])
+fi
+])dnl
+dnl
+dnl Some non-ANSI preprocessors botch requoting inside strings. That's bad
+dnl enough, but on some of those systems, the assert macro relies on requoting
+dnl working properly!
+dnl GAS_WORKING_ASSERT
+AC_DEFUN([GAS_WORKING_ASSERT],
+[AC_MSG_CHECKING([for working assert macro])
+AC_CACHE_VAL(gas_cv_assert_ok,
+AC_TRY_LINK([#include <assert.h>
+#include <stdio.h>], [
+/* check for requoting problems */
+static int a, b, c, d;
+static char *s;
+assert (!strcmp(s, "foo bar baz quux"));
+/* check for newline handling */
+assert (a == b
+ || c == d);
+], gas_cv_assert_ok=yes, gas_cv_assert_ok=no))dnl
+AC_MSG_RESULT($gas_cv_assert_ok)
+test $gas_cv_assert_ok = yes || AC_DEFINE(BROKEN_ASSERT, 1, [assert broken?])
+])dnl
+dnl
+dnl Since many Bourne shell implementations lack subroutines, use this
+dnl hack to simplify the code in configure.in.
+dnl GAS_UNIQ(listvar)
+AC_DEFUN([GAS_UNIQ],
+[_gas_uniq_list="[$]$1"
+_gas_uniq_newlist=""
+dnl Protect against empty input list.
+for _gas_uniq_i in _gas_uniq_dummy [$]_gas_uniq_list ; do
+ case [$]_gas_uniq_i in
+ _gas_uniq_dummy) ;;
+ *) case " [$]_gas_uniq_newlist " in
+ *" [$]_gas_uniq_i "*) ;;
+ *) _gas_uniq_newlist="[$]_gas_uniq_newlist [$]_gas_uniq_i" ;;
+ esac ;;
+ esac
+done
+$1=[$]_gas_uniq_newlist
+])dnl
+
+sinclude(../libtool.m4)
+dnl The lines below arrange for aclocal not to bring libtool.m4
+dnl AM_PROG_LIBTOOL into aclocal.m4, while still arranging for automake
+dnl to add a definition of LIBTOOL to Makefile.in.
+ifelse(yes,no,[
+AC_DEFUN([AM_PROG_LIBTOOL],)
+AC_DEFUN([AC_CHECK_LIBM],)
+AC_SUBST(LIBTOOL)
+])
+
+sinclude(../gettext.m4)
+ifelse(yes,no,[
+AC_DEFUN([CY_WITH_NLS],)
+AC_SUBST(INTLLIBS)
+])
diff --git a/x/binutils/gas/aclocal.m4 b/x/binutils/gas/aclocal.m4
new file mode 100644
index 0000000..c5ef088
--- /dev/null
+++ b/x/binutils/gas/aclocal.m4
@@ -0,0 +1,1006 @@
+# generated automatically by aclocal 1.8.4 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+# Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# -*- Autoconf -*-
+# Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+# Generated from amversion.in; do not edit by hand.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.8"])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION so it can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+ [AM_AUTOMAKE_VERSION([1.8.4])])
+
+# AM_AUX_DIR_EXPAND
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 6
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])
+AC_SUBST([$1_FALSE])
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.])
+fi])])
+
+# serial 7 -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+#serial 2
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # So let's grep whole file.
+ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
+ # Extract the definition of DEP_FILES from the Makefile without
+ # running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+ # We invoke sed twice because it is the simplest approach to
+ # changing $(DEPDIR) to its actual value in the expansion.
+ for file in `sed -n '
+ /^DEP_FILES = .*\\\\$/ {
+ s/^DEP_FILES = //
+ :loop
+ s/\\\\$//
+ p
+ n
+ /\\\\$/ b loop
+ p
+ }
+ /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 7
+
+# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
+AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# This macro actually does too much some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 11
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.58])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+ test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_MISSING_PROG(AMTAR, tar)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $1 | $1:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+# -*- Autoconf -*-
+# Copyright (C) 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 1
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 4
+
+# AM_PROG_LEX
+# -----------
+# Autoconf leaves LEX=: if lex or flex can't be found. Change that to a
+# "missing" invocation, for better error output.
+AC_DEFUN([AM_PROG_LEX],
+[AC_PREREQ(2.50)dnl
+AC_REQUIRE([AM_MISSING_HAS_RUN])dnl
+AC_REQUIRE([AC_PROG_LEX])dnl
+if test "$LEX" = :; then
+ LEX=${am_missing_run}flex
+fi])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+AC_DEFUN([AM_MAINTAINER_MODE],
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ USE_MAINTAINER_MODE=$enableval,
+ USE_MAINTAINER_MODE=no)
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST(MAINT)dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# -*- Autoconf -*-
+
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
+
+# Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
+# created by `make install' are always world readable, even if the
+# installer happens to have an overly restrictive umask (e.g. 077).
+# This was a mistake. There are at least two reasons why we must not
+# use `-m 0755':
+# - it causes special bits like SGID to be ignored,
+# - it may be too restrictive (some setups expect 775 directories).
+#
+# Do not use -m 0755 and let people choose whatever they expect by
+# setting umask.
+#
+# We cannot accept any implementation of `mkdir' that recognizes `-p'.
+# Some implementations (such as Solaris 8's) are not thread-safe: if a
+# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
+# concurrently, both version can detect that a/ is missing, but only
+# one can create it and the other will error out. Consequently we
+# restrict ourselves to GNU make (using the --version option ensures
+# this.)
+AC_DEFUN([AM_PROG_MKDIR_P],
+[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+ # Keeping the `.' argument allows $(mkdir_p) to be used without
+ # argument. Indeed, we sometimes output rules like
+ # $(mkdir_p) $(somedir)
+ # where $(somedir) is conditionally defined.
+ # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more
+ # expensive solution, as it forces Make to start a sub-shell.)
+ mkdir_p='mkdir -p -- .'
+else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ for d in ./-p ./--version;
+ do
+ test -d $d && rmdir $d
+ done
+ # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+ if test -f "$ac_aux_dir/mkinstalldirs"; then
+ mkdir_p='$(mkinstalldirs)'
+ else
+ mkdir_p='$(install_sh) -d'
+ fi
+fi
+AC_SUBST([mkdir_p])])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# AM_PROG_INSTALL_STRIP
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+m4_include([acinclude.m4])
diff --git a/x/binutils/gas/app.c b/x/binutils/gas/app.c
new file mode 100644
index 0000000..1dbc49a
--- /dev/null
+++ b/x/binutils/gas/app.c
@@ -0,0 +1,1371 @@
+/* This is the Assembler Pre-Processor
+ Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2002, 2003
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Modified by Allen Wirfs-Brock, Instantiations Inc 2/90. */
+/* App, the assembler pre-processor. This pre-processor strips out excess
+ spaces, turns single-quoted characters into a decimal constant, and turns
+ # <number> <filename> <garbage> into a .line <number>\n.file <filename>
+ pair. This needs better error-handling. */
+
+#include <stdio.h>
+#include "as.h" /* For BAD_CASE() only. */
+
+#if (__STDC__ != 1)
+#ifndef const
+#define const /* empty */
+#endif
+#endif
+
+#ifdef TC_M68K
+/* Whether we are scrubbing in m68k MRI mode. This is different from
+ flag_m68k_mri, because the two flags will be affected by the .mri
+ pseudo-op at different times. */
+static int scrub_m68k_mri;
+
+/* The pseudo-op which switches in and out of MRI mode. See the
+ comment in do_scrub_chars. */
+static const char mri_pseudo[] = ".mri 0";
+#else
+#define scrub_m68k_mri 0
+#endif
+
+#if defined TC_ARM && defined OBJ_ELF
+/* The pseudo-op for which we need to special-case `@' characters.
+ See the comment in do_scrub_chars. */
+static const char symver_pseudo[] = ".symver";
+static const char * symver_state;
+#endif
+
+static char lex[256];
+static const char symbol_chars[] =
+"$._ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+#define LEX_IS_SYMBOL_COMPONENT 1
+#define LEX_IS_WHITESPACE 2
+#define LEX_IS_LINE_SEPARATOR 3
+#define LEX_IS_COMMENT_START 4
+#define LEX_IS_LINE_COMMENT_START 5
+#define LEX_IS_TWOCHAR_COMMENT_1ST 6
+#define LEX_IS_STRINGQUOTE 8
+#define LEX_IS_COLON 9
+#define LEX_IS_NEWLINE 10
+#define LEX_IS_ONECHAR_QUOTE 11
+#ifdef TC_V850
+#define LEX_IS_DOUBLEDASH_1ST 12
+#endif
+#ifdef TC_M32R
+#define DOUBLEBAR_PARALLEL
+#endif
+#ifdef DOUBLEBAR_PARALLEL
+#define LEX_IS_DOUBLEBAR_1ST 13
+#endif
+#define LEX_IS_PARALLEL_SEPARATOR 14
+#define IS_SYMBOL_COMPONENT(c) (lex[c] == LEX_IS_SYMBOL_COMPONENT)
+#define IS_WHITESPACE(c) (lex[c] == LEX_IS_WHITESPACE)
+#define IS_LINE_SEPARATOR(c) (lex[c] == LEX_IS_LINE_SEPARATOR)
+#define IS_PARALLEL_SEPARATOR(c) (lex[c] == LEX_IS_PARALLEL_SEPARATOR)
+#define IS_COMMENT(c) (lex[c] == LEX_IS_COMMENT_START)
+#define IS_LINE_COMMENT(c) (lex[c] == LEX_IS_LINE_COMMENT_START)
+#define IS_NEWLINE(c) (lex[c] == LEX_IS_NEWLINE)
+
+static int process_escape (int);
+
+/* FIXME-soon: The entire lexer/parser thingy should be
+ built statically at compile time rather than dynamically
+ each and every time the assembler is run. xoxorich. */
+
+void
+do_scrub_begin (int m68k_mri ATTRIBUTE_UNUSED)
+{
+ const char *p;
+ int c;
+
+ lex[' '] = LEX_IS_WHITESPACE;
+ lex['\t'] = LEX_IS_WHITESPACE;
+ lex['\r'] = LEX_IS_WHITESPACE;
+ lex['\n'] = LEX_IS_NEWLINE;
+ lex[':'] = LEX_IS_COLON;
+
+#ifdef TC_M68K
+ scrub_m68k_mri = m68k_mri;
+
+ if (! m68k_mri)
+#endif
+ {
+ lex['"'] = LEX_IS_STRINGQUOTE;
+
+#if ! defined (TC_HPPA) && ! defined (TC_I370)
+ /* I370 uses single-quotes to delimit integer, float constants. */
+ lex['\''] = LEX_IS_ONECHAR_QUOTE;
+#endif
+
+#ifdef SINGLE_QUOTE_STRINGS
+ lex['\''] = LEX_IS_STRINGQUOTE;
+#endif
+ }
+
+ /* Note: if any other character can be LEX_IS_STRINGQUOTE, the loop
+ in state 5 of do_scrub_chars must be changed. */
+
+ /* Note that these override the previous defaults, e.g. if ';' is a
+ comment char, then it isn't a line separator. */
+ for (p = symbol_chars; *p; ++p)
+ lex[(unsigned char) *p] = LEX_IS_SYMBOL_COMPONENT;
+
+ for (c = 128; c < 256; ++c)
+ lex[c] = LEX_IS_SYMBOL_COMPONENT;
+
+#ifdef tc_symbol_chars
+ /* This macro permits the processor to specify all characters which
+ may appears in an operand. This will prevent the scrubber from
+ discarding meaningful whitespace in certain cases. The i386
+ backend uses this to support prefixes, which can confuse the
+ scrubber as to whether it is parsing operands or opcodes. */
+ for (p = tc_symbol_chars; *p; ++p)
+ lex[(unsigned char) *p] = LEX_IS_SYMBOL_COMPONENT;
+#endif
+
+ /* The m68k backend wants to be able to change comment_chars. */
+#ifndef tc_comment_chars
+#define tc_comment_chars comment_chars
+#endif
+ for (p = tc_comment_chars; *p; p++)
+ lex[(unsigned char) *p] = LEX_IS_COMMENT_START;
+
+ for (p = line_comment_chars; *p; p++)
+ lex[(unsigned char) *p] = LEX_IS_LINE_COMMENT_START;
+
+ for (p = line_separator_chars; *p; p++)
+ lex[(unsigned char) *p] = LEX_IS_LINE_SEPARATOR;
+
+#ifdef tc_parallel_separator_chars
+ /* This macro permits the processor to specify all characters which
+ separate parallel insns on the same line. */
+ for (p = tc_parallel_separator_chars; *p; p++)
+ lex[(unsigned char) *p] = LEX_IS_PARALLEL_SEPARATOR;
+#endif
+
+ /* Only allow slash-star comments if slash is not in use.
+ FIXME: This isn't right. We should always permit them. */
+ if (lex['/'] == 0)
+ lex['/'] = LEX_IS_TWOCHAR_COMMENT_1ST;
+
+#ifdef TC_M68K
+ if (m68k_mri)
+ {
+ lex['\''] = LEX_IS_STRINGQUOTE;
+ lex[';'] = LEX_IS_COMMENT_START;
+ lex['*'] = LEX_IS_LINE_COMMENT_START;
+ /* The MRI documentation says '!' is LEX_IS_COMMENT_START, but
+ then it can't be used in an expression. */
+ lex['!'] = LEX_IS_LINE_COMMENT_START;
+ }
+#endif
+
+#ifdef TC_V850
+ lex['-'] = LEX_IS_DOUBLEDASH_1ST;
+#endif
+#ifdef DOUBLEBAR_PARALLEL
+ lex['|'] = LEX_IS_DOUBLEBAR_1ST;
+#endif
+#ifdef TC_D30V
+ /* Must do this is we want VLIW instruction with "->" or "<-". */
+ lex['-'] = LEX_IS_SYMBOL_COMPONENT;
+#endif
+}
+
+/* Saved state of the scrubber. */
+static int state;
+static int old_state;
+static char *out_string;
+static char out_buf[20];
+static int add_newlines;
+static char *saved_input;
+static int saved_input_len;
+static char input_buffer[32 * 1024];
+static const char *mri_state;
+static char mri_last_ch;
+
+/* Data structure for saving the state of app across #include's. Note that
+ app is called asynchronously to the parsing of the .include's, so our
+ state at the time .include is interpreted is completely unrelated.
+ That's why we have to save it all. */
+
+struct app_save
+{
+ int state;
+ int old_state;
+ char * out_string;
+ char out_buf[sizeof (out_buf)];
+ int add_newlines;
+ char * saved_input;
+ int saved_input_len;
+#ifdef TC_M68K
+ int scrub_m68k_mri;
+#endif
+ const char * mri_state;
+ char mri_last_ch;
+#if defined TC_ARM && defined OBJ_ELF
+ const char * symver_state;
+#endif
+};
+
+char *
+app_push (void)
+{
+ register struct app_save *saved;
+
+ saved = (struct app_save *) xmalloc (sizeof (*saved));
+ saved->state = state;
+ saved->old_state = old_state;
+ saved->out_string = out_string;
+ memcpy (saved->out_buf, out_buf, sizeof (out_buf));
+ saved->add_newlines = add_newlines;
+ if (saved_input == NULL)
+ saved->saved_input = NULL;
+ else
+ {
+ saved->saved_input = xmalloc (saved_input_len);
+ memcpy (saved->saved_input, saved_input, saved_input_len);
+ saved->saved_input_len = saved_input_len;
+ }
+#ifdef TC_M68K
+ saved->scrub_m68k_mri = scrub_m68k_mri;
+#endif
+ saved->mri_state = mri_state;
+ saved->mri_last_ch = mri_last_ch;
+#if defined TC_ARM && defined OBJ_ELF
+ saved->symver_state = symver_state;
+#endif
+
+ /* do_scrub_begin() is not useful, just wastes time. */
+
+ state = 0;
+ saved_input = NULL;
+
+ return (char *) saved;
+}
+
+void
+app_pop (char *arg)
+{
+ register struct app_save *saved = (struct app_save *) arg;
+
+ /* There is no do_scrub_end (). */
+ state = saved->state;
+ old_state = saved->old_state;
+ out_string = saved->out_string;
+ memcpy (out_buf, saved->out_buf, sizeof (out_buf));
+ add_newlines = saved->add_newlines;
+ if (saved->saved_input == NULL)
+ saved_input = NULL;
+ else
+ {
+ assert (saved->saved_input_len <= (int) (sizeof input_buffer));
+ memcpy (input_buffer, saved->saved_input, saved->saved_input_len);
+ saved_input = input_buffer;
+ saved_input_len = saved->saved_input_len;
+ free (saved->saved_input);
+ }
+#ifdef TC_M68K
+ scrub_m68k_mri = saved->scrub_m68k_mri;
+#endif
+ mri_state = saved->mri_state;
+ mri_last_ch = saved->mri_last_ch;
+#if defined TC_ARM && defined OBJ_ELF
+ symver_state = saved->symver_state;
+#endif
+
+ free (arg);
+}
+
+/* @@ This assumes that \n &c are the same on host and target. This is not
+ necessarily true. */
+
+static int
+process_escape (int ch)
+{
+ switch (ch)
+ {
+ case 'b':
+ return '\b';
+ case 'f':
+ return '\f';
+ case 'n':
+ return '\n';
+ case 'r':
+ return '\r';
+ case 't':
+ return '\t';
+ case '\'':
+ return '\'';
+ case '"':
+ return '\"';
+ default:
+ return ch;
+ }
+}
+
+/* This function is called to process input characters. The GET
+ parameter is used to retrieve more input characters. GET should
+ set its parameter to point to a buffer, and return the length of
+ the buffer; it should return 0 at end of file. The scrubbed output
+ characters are put into the buffer starting at TOSTART; the TOSTART
+ buffer is TOLEN bytes in length. The function returns the number
+ of scrubbed characters put into TOSTART. This will be TOLEN unless
+ end of file was seen. This function is arranged as a state
+ machine, and saves its state so that it may return at any point.
+ This is the way the old code used to work. */
+
+int
+do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
+{
+ char *to = tostart;
+ char *toend = tostart + tolen;
+ char *from;
+ char *fromend;
+ int fromlen;
+ register int ch, ch2 = 0;
+
+ /*State 0: beginning of normal line
+ 1: After first whitespace on line (flush more white)
+ 2: After first non-white (opcode) on line (keep 1white)
+ 3: after second white on line (into operands) (flush white)
+ 4: after putting out a .line, put out digits
+ 5: parsing a string, then go to old-state
+ 6: putting out \ escape in a "d string.
+ 7: After putting out a .appfile, put out string.
+ 8: After putting out a .appfile string, flush until newline.
+ 9: After seeing symbol char in state 3 (keep 1white after symchar)
+ 10: After seeing whitespace in state 9 (keep white before symchar)
+ 11: After seeing a symbol character in state 0 (eg a label definition)
+ -1: output string in out_string and go to the state in old_state
+ -2: flush text until a '*' '/' is seen, then go to state old_state
+#ifdef TC_V850
+ 12: After seeing a dash, looking for a second dash as a start
+ of comment.
+#endif
+#ifdef DOUBLEBAR_PARALLEL
+ 13: After seeing a vertical bar, looking for a second
+ vertical bar as a parallel expression separator.
+#endif
+#ifdef TC_IA64
+ 14: After seeing a `(' at state 0, looking for a `)' as
+ predicate.
+ 15: After seeing a `(' at state 1, looking for a `)' as
+ predicate.
+#endif
+ */
+
+ /* I added states 9 and 10 because the MIPS ECOFF assembler uses
+ constructs like ``.loc 1 20''. This was turning into ``.loc
+ 120''. States 9 and 10 ensure that a space is never dropped in
+ between characters which could appear in an identifier. Ian
+ Taylor, ian@cygnus.com.
+
+ I added state 11 so that something like "Lfoo add %r25,%r26,%r27" works
+ correctly on the PA (and any other target where colons are optional).
+ Jeff Law, law@cs.utah.edu.
+
+ I added state 13 so that something like "cmp r1, r2 || trap #1" does not
+ get squashed into "cmp r1,r2||trap#1", with the all important space
+ between the 'trap' and the '#1' being eliminated. nickc@cygnus.com */
+
+ /* This macro gets the next input character. */
+
+#define GET() \
+ (from < fromend \
+ ? * (unsigned char *) (from++) \
+ : (saved_input = NULL, \
+ fromlen = (*get) (input_buffer, sizeof input_buffer), \
+ from = input_buffer, \
+ fromend = from + fromlen, \
+ (fromlen == 0 \
+ ? EOF \
+ : * (unsigned char *) (from++))))
+
+ /* This macro pushes a character back on the input stream. */
+
+#define UNGET(uch) (*--from = (uch))
+
+ /* This macro puts a character into the output buffer. If this
+ character fills the output buffer, this macro jumps to the label
+ TOFULL. We use this rather ugly approach because we need to
+ handle two different termination conditions: EOF on the input
+ stream, and a full output buffer. It would be simpler if we
+ always read in the entire input stream before processing it, but
+ I don't want to make such a significant change to the assembler's
+ memory usage. */
+
+#define PUT(pch) \
+ do \
+ { \
+ *to++ = (pch); \
+ if (to >= toend) \
+ goto tofull; \
+ } \
+ while (0)
+
+ if (saved_input != NULL)
+ {
+ from = saved_input;
+ fromend = from + saved_input_len;
+ }
+ else
+ {
+ fromlen = (*get) (input_buffer, sizeof input_buffer);
+ if (fromlen == 0)
+ return 0;
+ from = input_buffer;
+ fromend = from + fromlen;
+ }
+
+ while (1)
+ {
+ /* The cases in this switch end with continue, in order to
+ branch back to the top of this while loop and generate the
+ next output character in the appropriate state. */
+ switch (state)
+ {
+ case -1:
+ ch = *out_string++;
+ if (*out_string == '\0')
+ {
+ state = old_state;
+ old_state = 3;
+ }
+ PUT (ch);
+ continue;
+
+ case -2:
+ for (;;)
+ {
+ do
+ {
+ ch = GET ();
+
+ if (ch == EOF)
+ {
+ as_warn (_("end of file in comment"));
+ goto fromeof;
+ }
+
+ if (ch == '\n')
+ PUT ('\n');
+ }
+ while (ch != '*');
+
+ while ((ch = GET ()) == '*')
+ ;
+
+ if (ch == EOF)
+ {
+ as_warn (_("end of file in comment"));
+ goto fromeof;
+ }
+
+ if (ch == '/')
+ break;
+
+ UNGET (ch);
+ }
+
+ state = old_state;
+ UNGET (' ');
+ continue;
+
+ case 4:
+ ch = GET ();
+ if (ch == EOF)
+ goto fromeof;
+ else if (ch >= '0' && ch <= '9')
+ PUT (ch);
+ else
+ {
+ while (ch != EOF && IS_WHITESPACE (ch))
+ ch = GET ();
+ if (ch == '"')
+ {
+ UNGET (ch);
+ if (scrub_m68k_mri)
+ out_string = "\n\tappfile ";
+ else
+ out_string = "\n\t.appfile ";
+ old_state = 7;
+ state = -1;
+ PUT (*out_string++);
+ }
+ else
+ {
+ while (ch != EOF && ch != '\n')
+ ch = GET ();
+ state = 0;
+ PUT (ch);
+ }
+ }
+ continue;
+
+ case 5:
+ /* We are going to copy everything up to a quote character,
+ with special handling for a backslash. We try to
+ optimize the copying in the simple case without using the
+ GET and PUT macros. */
+ {
+ char *s;
+ int len;
+
+ for (s = from; s < fromend; s++)
+ {
+ ch = *s;
+ /* This condition must be changed if the type of any
+ other character can be LEX_IS_STRINGQUOTE. */
+ if (ch == '\\'
+ || ch == '"'
+ || ch == '\''
+ || ch == '\n')
+ break;
+ }
+ len = s - from;
+ if (len > toend - to)
+ len = toend - to;
+ if (len > 0)
+ {
+ memcpy (to, from, len);
+ to += len;
+ from += len;
+ }
+ }
+
+ ch = GET ();
+ if (ch == EOF)
+ {
+ as_warn (_("end of file in string; inserted '\"'"));
+ state = old_state;
+ UNGET ('\n');
+ PUT ('"');
+ }
+ else if (lex[ch] == LEX_IS_STRINGQUOTE)
+ {
+ state = old_state;
+ PUT (ch);
+ }
+#ifndef NO_STRING_ESCAPES
+ else if (ch == '\\')
+ {
+ state = 6;
+ PUT (ch);
+ }
+#endif
+ else if (scrub_m68k_mri && ch == '\n')
+ {
+ /* Just quietly terminate the string. This permits lines like
+ bne label loop if we haven't reach end yet. */
+ state = old_state;
+ UNGET (ch);
+ PUT ('\'');
+ }
+ else
+ {
+ PUT (ch);
+ }
+ continue;
+
+ case 6:
+ state = 5;
+ ch = GET ();
+ switch (ch)
+ {
+ /* Handle strings broken across lines, by turning '\n' into
+ '\\' and 'n'. */
+ case '\n':
+ UNGET ('n');
+ add_newlines++;
+ PUT ('\\');
+ continue;
+
+ case EOF:
+ as_warn (_("end of file in string; '\"' inserted"));
+ PUT ('"');
+ continue;
+
+ case '"':
+ case '\\':
+ case 'b':
+ case 'f':
+ case 'n':
+ case 'r':
+ case 't':
+ case 'v':
+ case 'x':
+ case 'X':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ break;
+
+ default:
+#ifdef ONLY_STANDARD_ESCAPES
+ as_warn (_("unknown escape '\\%c' in string; ignored"), ch);
+#endif
+ break;
+ }
+ PUT (ch);
+ continue;
+
+ case 7:
+ ch = GET ();
+ state = 5;
+ old_state = 8;
+ if (ch == EOF)
+ goto fromeof;
+ PUT (ch);
+ continue;
+
+ case 8:
+ do
+ ch = GET ();
+ while (ch != '\n' && ch != EOF);
+ if (ch == EOF)
+ goto fromeof;
+ state = 0;
+ PUT (ch);
+ continue;
+
+#ifdef DOUBLEBAR_PARALLEL
+ case 13:
+ ch = GET ();
+ if (ch != '|')
+ abort ();
+
+ /* Reset back to state 1 and pretend that we are parsing a
+ line from just after the first white space. */
+ state = 1;
+ PUT ('|');
+ continue;
+#endif
+ }
+
+ /* OK, we are somewhere in states 0 through 4 or 9 through 11. */
+
+ /* flushchar: */
+ ch = GET ();
+
+#ifdef TC_IA64
+ if (ch == '(' && (state == 0 || state == 1))
+ {
+ state += 14;
+ PUT (ch);
+ continue;
+ }
+ else if (state == 14 || state == 15)
+ {
+ if (ch == ')')
+ {
+ state -= 14;
+ PUT (ch);
+ ch = GET ();
+ }
+ else
+ {
+ PUT (ch);
+ continue;
+ }
+ }
+#endif
+
+ recycle:
+
+#if defined TC_ARM && defined OBJ_ELF
+ /* We need to watch out for .symver directives. See the comment later
+ in this function. */
+ if (symver_state == NULL)
+ {
+ if ((state == 0 || state == 1) && ch == symver_pseudo[0])
+ symver_state = symver_pseudo + 1;
+ }
+ else
+ {
+ /* We advance to the next state if we find the right
+ character. */
+ if (ch != '\0' && (*symver_state == ch))
+ ++symver_state;
+ else if (*symver_state != '\0')
+ /* We did not get the expected character, or we didn't
+ get a valid terminating character after seeing the
+ entire pseudo-op, so we must go back to the beginning. */
+ symver_state = NULL;
+ else
+ {
+ /* We've read the entire pseudo-op. If this is the end
+ of the line, go back to the beginning. */
+ if (IS_NEWLINE (ch))
+ symver_state = NULL;
+ }
+ }
+#endif /* TC_ARM && OBJ_ELF */
+
+#ifdef TC_M68K
+ /* We want to have pseudo-ops which control whether we are in
+ MRI mode or not. Unfortunately, since m68k MRI mode affects
+ the scrubber, that means that we need a special purpose
+ recognizer here. */
+ if (mri_state == NULL)
+ {
+ if ((state == 0 || state == 1)
+ && ch == mri_pseudo[0])
+ mri_state = mri_pseudo + 1;
+ }
+ else
+ {
+ /* We advance to the next state if we find the right
+ character, or if we need a space character and we get any
+ whitespace character, or if we need a '0' and we get a
+ '1' (this is so that we only need one state to handle
+ ``.mri 0'' and ``.mri 1''). */
+ if (ch != '\0'
+ && (*mri_state == ch
+ || (*mri_state == ' '
+ && lex[ch] == LEX_IS_WHITESPACE)
+ || (*mri_state == '0'
+ && ch == '1')))
+ {
+ mri_last_ch = ch;
+ ++mri_state;
+ }
+ else if (*mri_state != '\0'
+ || (lex[ch] != LEX_IS_WHITESPACE
+ && lex[ch] != LEX_IS_NEWLINE))
+ {
+ /* We did not get the expected character, or we didn't
+ get a valid terminating character after seeing the
+ entire pseudo-op, so we must go back to the
+ beginning. */
+ mri_state = NULL;
+ }
+ else
+ {
+ /* We've read the entire pseudo-op. mips_last_ch is
+ either '0' or '1' indicating whether to enter or
+ leave MRI mode. */
+ do_scrub_begin (mri_last_ch == '1');
+ mri_state = NULL;
+
+ /* We continue handling the character as usual. The
+ main gas reader must also handle the .mri pseudo-op
+ to control expression parsing and the like. */
+ }
+ }
+#endif
+
+ if (ch == EOF)
+ {
+ if (state != 0)
+ {
+ as_warn (_("end of file not at end of a line; newline inserted"));
+ state = 0;
+ PUT ('\n');
+ }
+ goto fromeof;
+ }
+
+ switch (lex[ch])
+ {
+ case LEX_IS_WHITESPACE:
+ do
+ {
+ ch = GET ();
+ }
+ while (ch != EOF && IS_WHITESPACE (ch));
+ if (ch == EOF)
+ goto fromeof;
+
+ if (state == 0)
+ {
+ /* Preserve a single whitespace character at the
+ beginning of a line. */
+ state = 1;
+ UNGET (ch);
+ PUT (' ');
+ break;
+ }
+
+#ifdef KEEP_WHITE_AROUND_COLON
+ if (lex[ch] == LEX_IS_COLON)
+ {
+ /* Only keep this white if there's no white *after* the
+ colon. */
+ ch2 = GET ();
+ UNGET (ch2);
+ if (!IS_WHITESPACE (ch2))
+ {
+ state = 9;
+ UNGET (ch);
+ PUT (' ');
+ break;
+ }
+ }
+#endif
+ if (IS_COMMENT (ch)
+ || ch == '/'
+ || IS_LINE_SEPARATOR (ch)
+ || IS_PARALLEL_SEPARATOR (ch))
+ {
+ if (scrub_m68k_mri)
+ {
+ /* In MRI mode, we keep these spaces. */
+ UNGET (ch);
+ PUT (' ');
+ break;
+ }
+ goto recycle;
+ }
+
+ /* If we're in state 2 or 11, we've seen a non-white
+ character followed by whitespace. If the next character
+ is ':', this is whitespace after a label name which we
+ normally must ignore. In MRI mode, though, spaces are
+ not permitted between the label and the colon. */
+ if ((state == 2 || state == 11)
+ && lex[ch] == LEX_IS_COLON
+ && ! scrub_m68k_mri)
+ {
+ state = 1;
+ PUT (ch);
+ break;
+ }
+
+ switch (state)
+ {
+ case 0:
+ state++;
+ goto recycle; /* Punted leading sp */
+ case 1:
+ /* We can arrive here if we leave a leading whitespace
+ character at the beginning of a line. */
+ goto recycle;
+ case 2:
+ state = 3;
+ if (to + 1 < toend)
+ {
+ /* Optimize common case by skipping UNGET/GET. */
+ PUT (' '); /* Sp after opco */
+ goto recycle;
+ }
+ UNGET (ch);
+ PUT (' ');
+ break;
+ case 3:
+ if (scrub_m68k_mri)
+ {
+ /* In MRI mode, we keep these spaces. */
+ UNGET (ch);
+ PUT (' ');
+ break;
+ }
+ goto recycle; /* Sp in operands */
+ case 9:
+ case 10:
+ if (scrub_m68k_mri)
+ {
+ /* In MRI mode, we keep these spaces. */
+ state = 3;
+ UNGET (ch);
+ PUT (' ');
+ break;
+ }
+ state = 10; /* Sp after symbol char */
+ goto recycle;
+ case 11:
+ if (LABELS_WITHOUT_COLONS || flag_m68k_mri)
+ state = 1;
+ else
+ {
+ /* We know that ch is not ':', since we tested that
+ case above. Therefore this is not a label, so it
+ must be the opcode, and we've just seen the
+ whitespace after it. */
+ state = 3;
+ }
+ UNGET (ch);
+ PUT (' '); /* Sp after label definition. */
+ break;
+ default:
+ BAD_CASE (state);
+ }
+ break;
+
+ case LEX_IS_TWOCHAR_COMMENT_1ST:
+ ch2 = GET ();
+ if (ch2 == '*')
+ {
+ for (;;)
+ {
+ do
+ {
+ ch2 = GET ();
+ if (ch2 != EOF && IS_NEWLINE (ch2))
+ add_newlines++;
+ }
+ while (ch2 != EOF && ch2 != '*');
+
+ while (ch2 == '*')
+ ch2 = GET ();
+
+ if (ch2 == EOF || ch2 == '/')
+ break;
+
+ /* This UNGET will ensure that we count newlines
+ correctly. */
+ UNGET (ch2);
+ }
+
+ if (ch2 == EOF)
+ as_warn (_("end of file in multiline comment"));
+
+ ch = ' ';
+ goto recycle;
+ }
+#ifdef DOUBLESLASH_LINE_COMMENTS
+ else if (ch2 == '/')
+ {
+ do
+ {
+ ch = GET ();
+ }
+ while (ch != EOF && !IS_NEWLINE (ch));
+ if (ch == EOF)
+ as_warn ("end of file in comment; newline inserted");
+ state = 0;
+ PUT ('\n');
+ break;
+ }
+#endif
+ else
+ {
+ if (ch2 != EOF)
+ UNGET (ch2);
+ if (state == 9 || state == 10)
+ state = 3;
+ PUT (ch);
+ }
+ break;
+
+ case LEX_IS_STRINGQUOTE:
+ if (state == 10)
+ {
+ /* Preserve the whitespace in foo "bar". */
+ UNGET (ch);
+ state = 3;
+ PUT (' ');
+
+ /* PUT didn't jump out. We could just break, but we
+ know what will happen, so optimize a bit. */
+ ch = GET ();
+ old_state = 3;
+ }
+ else if (state == 9)
+ old_state = 3;
+ else
+ old_state = state;
+ state = 5;
+ PUT (ch);
+ break;
+
+#ifndef IEEE_STYLE
+ case LEX_IS_ONECHAR_QUOTE:
+ if (state == 10)
+ {
+ /* Preserve the whitespace in foo 'b'. */
+ UNGET (ch);
+ state = 3;
+ PUT (' ');
+ break;
+ }
+ ch = GET ();
+ if (ch == EOF)
+ {
+ as_warn (_("end of file after a one-character quote; \\0 inserted"));
+ ch = 0;
+ }
+ if (ch == '\\')
+ {
+ ch = GET ();
+ if (ch == EOF)
+ {
+ as_warn (_("end of file in escape character"));
+ ch = '\\';
+ }
+ else
+ ch = process_escape (ch);
+ }
+ sprintf (out_buf, "%d", (int) (unsigned char) ch);
+
+ /* None of these 'x constants for us. We want 'x'. */
+ if ((ch = GET ()) != '\'')
+ {
+#ifdef REQUIRE_CHAR_CLOSE_QUOTE
+ as_warn (_("missing close quote; (assumed)"));
+#else
+ if (ch != EOF)
+ UNGET (ch);
+#endif
+ }
+ if (strlen (out_buf) == 1)
+ {
+ PUT (out_buf[0]);
+ break;
+ }
+ if (state == 9)
+ old_state = 3;
+ else
+ old_state = state;
+ state = -1;
+ out_string = out_buf;
+ PUT (*out_string++);
+ break;
+#endif
+
+ case LEX_IS_COLON:
+#ifdef KEEP_WHITE_AROUND_COLON
+ state = 9;
+#else
+ if (state == 9 || state == 10)
+ state = 3;
+ else if (state != 3)
+ state = 1;
+#endif
+ PUT (ch);
+ break;
+
+ case LEX_IS_NEWLINE:
+ /* Roll out a bunch of newlines from inside comments, etc. */
+ if (add_newlines)
+ {
+ --add_newlines;
+ UNGET (ch);
+ }
+ /* Fall through. */
+
+ case LEX_IS_LINE_SEPARATOR:
+ state = 0;
+ PUT (ch);
+ break;
+
+ case LEX_IS_PARALLEL_SEPARATOR:
+ state = 1;
+ PUT (ch);
+ break;
+
+#ifdef TC_V850
+ case LEX_IS_DOUBLEDASH_1ST:
+ ch2 = GET ();
+ if (ch2 != '-')
+ {
+ UNGET (ch2);
+ goto de_fault;
+ }
+ /* Read and skip to end of line. */
+ do
+ {
+ ch = GET ();
+ }
+ while (ch != EOF && ch != '\n');
+
+ if (ch == EOF)
+ as_warn (_("end of file in comment; newline inserted"));
+
+ state = 0;
+ PUT ('\n');
+ break;
+#endif
+#ifdef DOUBLEBAR_PARALLEL
+ case LEX_IS_DOUBLEBAR_1ST:
+ ch2 = GET ();
+ UNGET (ch2);
+ if (ch2 != '|')
+ goto de_fault;
+
+ /* Handle '||' in two states as invoking PUT twice might
+ result in the first one jumping out of this loop. We'd
+ then lose track of the state and one '|' char. */
+ state = 13;
+ PUT ('|');
+ break;
+#endif
+ case LEX_IS_LINE_COMMENT_START:
+ /* FIXME-someday: The two character comment stuff was badly
+ thought out. On i386, we want '/' as line comment start
+ AND we want C style comments. hence this hack. The
+ whole lexical process should be reworked. xoxorich. */
+ if (ch == '/')
+ {
+ ch2 = GET ();
+ if (ch2 == '*')
+ {
+ old_state = 3;
+ state = -2;
+ break;
+ }
+ else
+ {
+ UNGET (ch2);
+ }
+ }
+
+ if (state == 0 || state == 1) /* Only comment at start of line. */
+ {
+ int startch;
+
+ startch = ch;
+
+ do
+ {
+ ch = GET ();
+ }
+ while (ch != EOF && IS_WHITESPACE (ch));
+
+ if (ch == EOF)
+ {
+ as_warn (_("end of file in comment; newline inserted"));
+ PUT ('\n');
+ break;
+ }
+
+ if (ch < '0' || ch > '9' || state != 0 || startch != '#')
+ {
+ /* Not a cpp line. */
+ while (ch != EOF && !IS_NEWLINE (ch))
+ ch = GET ();
+ if (ch == EOF)
+ as_warn (_("end of file in comment; newline inserted"));
+ state = 0;
+ PUT ('\n');
+ break;
+ }
+ /* Looks like `# 123 "filename"' from cpp. */
+ UNGET (ch);
+ old_state = 4;
+ state = -1;
+ if (scrub_m68k_mri)
+ out_string = "\tappline ";
+ else
+ out_string = "\t.appline ";
+ PUT (*out_string++);
+ break;
+ }
+
+#ifdef TC_D10V
+ /* All insns end in a char for which LEX_IS_SYMBOL_COMPONENT is true.
+ Trap is the only short insn that has a first operand that is
+ neither register nor label.
+ We must prevent exef0f ||trap #1 to degenerate to exef0f ||trap#1 .
+ We can't make '#' LEX_IS_SYMBOL_COMPONENT because it is
+ already LEX_IS_LINE_COMMENT_START. However, it is the
+ only character in line_comment_chars for d10v, hence we
+ can recognize it as such. */
+ /* An alternative approach would be to reset the state to 1 when
+ we see '||', '<'- or '->', but that seems to be overkill. */
+ if (state == 10)
+ PUT (' ');
+#endif
+ /* We have a line comment character which is not at the
+ start of a line. If this is also a normal comment
+ character, fall through. Otherwise treat it as a default
+ character. */
+ if (strchr (tc_comment_chars, ch) == NULL
+ && (! scrub_m68k_mri
+ || (ch != '!' && ch != '*')))
+ goto de_fault;
+ if (scrub_m68k_mri
+ && (ch == '!' || ch == '*' || ch == '#')
+ && state != 1
+ && state != 10)
+ goto de_fault;
+ /* Fall through. */
+ case LEX_IS_COMMENT_START:
+#if defined TC_ARM && defined OBJ_ELF
+ /* On the ARM, `@' is the comment character.
+ Unfortunately this is also a special character in ELF .symver
+ directives (and .type, though we deal with those another way).
+ So we check if this line is such a directive, and treat
+ the character as default if so. This is a hack. */
+ if ((symver_state != NULL) && (*symver_state == 0))
+ goto de_fault;
+#endif
+#ifdef WARN_COMMENTS
+ if (!found_comment)
+ as_where (&found_comment_file, &found_comment);
+#endif
+ do
+ {
+ ch = GET ();
+ }
+ while (ch != EOF && !IS_NEWLINE (ch));
+ if (ch == EOF)
+ as_warn (_("end of file in comment; newline inserted"));
+ state = 0;
+ PUT ('\n');
+ break;
+
+ case LEX_IS_SYMBOL_COMPONENT:
+ if (state == 10)
+ {
+ /* This is a symbol character following another symbol
+ character, with whitespace in between. We skipped
+ the whitespace earlier, so output it now. */
+ UNGET (ch);
+ state = 3;
+ PUT (' ');
+ break;
+ }
+
+ if (state == 3)
+ state = 9;
+
+ /* This is a common case. Quickly copy CH and all the
+ following symbol component or normal characters. */
+ if (to + 1 < toend
+ && mri_state == NULL
+#if defined TC_ARM && defined OBJ_ELF
+ && symver_state == NULL
+#endif
+ )
+ {
+ char *s;
+ int len;
+
+ for (s = from; s < fromend; s++)
+ {
+ int type;
+
+ ch2 = *(unsigned char *) s;
+ type = lex[ch2];
+ if (type != 0
+ && type != LEX_IS_SYMBOL_COMPONENT)
+ break;
+ }
+
+ if (s > from)
+ /* Handle the last character normally, for
+ simplicity. */
+ --s;
+
+ len = s - from;
+
+ if (len > (toend - to) - 1)
+ len = (toend - to) - 1;
+
+ if (len > 0)
+ {
+ PUT (ch);
+ if (len > 8)
+ {
+ memcpy (to, from, len);
+ to += len;
+ from += len;
+ }
+ else
+ {
+ switch (len)
+ {
+ case 8: *to++ = *from++;
+ case 7: *to++ = *from++;
+ case 6: *to++ = *from++;
+ case 5: *to++ = *from++;
+ case 4: *to++ = *from++;
+ case 3: *to++ = *from++;
+ case 2: *to++ = *from++;
+ case 1: *to++ = *from++;
+ }
+ }
+ ch = GET ();
+ }
+ }
+
+ /* Fall through. */
+ default:
+ de_fault:
+ /* Some relatively `normal' character. */
+ if (state == 0)
+ {
+ state = 11; /* Now seeing label definition. */
+ }
+ else if (state == 1)
+ {
+ state = 2; /* Ditto. */
+ }
+ else if (state == 9)
+ {
+ if (!IS_SYMBOL_COMPONENT (ch))
+ state = 3;
+ }
+ else if (state == 10)
+ {
+ if (ch == '\\')
+ {
+ /* Special handling for backslash: a backslash may
+ be the beginning of a formal parameter (of a
+ macro) following another symbol character, with
+ whitespace in between. If that is the case, we
+ output a space before the parameter. Strictly
+ speaking, correct handling depends upon what the
+ macro parameter expands into; if the parameter
+ expands into something which does not start with
+ an operand character, then we don't want to keep
+ the space. We don't have enough information to
+ make the right choice, so here we are making the
+ choice which is more likely to be correct. */
+ PUT (' ');
+ }
+
+ state = 3;
+ }
+ PUT (ch);
+ break;
+ }
+ }
+
+ /*NOTREACHED*/
+
+ fromeof:
+ /* We have reached the end of the input. */
+ return to - tostart;
+
+ tofull:
+ /* The output buffer is full. Save any input we have not yet
+ processed. */
+ if (fromend > from)
+ {
+ saved_input = from;
+ saved_input_len = fromend - from;
+ }
+ else
+ saved_input = NULL;
+
+ return to - tostart;
+}
+
diff --git a/x/binutils/gas/as.c b/x/binutils/gas/as.c
new file mode 100644
index 0000000..0911aa1
--- /dev/null
+++ b/x/binutils/gas/as.c
@@ -0,0 +1,1165 @@
+/* as.c - GAS main program.
+ Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Main program for AS; a 32-bit assembler of GNU.
+ Understands command arguments.
+ Has a few routines that don't fit in other modules because they
+ are shared.
+
+ bugs
+
+ : initialisers
+ Since no-one else says they will support them in future: I
+ don't support them now. */
+
+#include "ansidecl.h"
+
+#define COMMON
+
+#include "as.h"
+#include "subsegs.h"
+#include "output-file.h"
+#include "sb.h"
+#include "macro.h"
+#include "dwarf2dbg.h"
+#include "dw2gencfi.h"
+
+#ifdef BFD_ASSEMBLER
+#include "bfdver.h"
+#endif
+
+#ifdef HAVE_ITBL_CPU
+#include "itbl-ops.h"
+#else
+#define itbl_parse(itbl_file) 1
+#define itbl_init()
+#endif
+
+#ifdef HAVE_SBRK
+#ifdef NEED_DECLARATION_SBRK
+extern PTR sbrk ();
+#endif
+#endif
+
+#ifdef USING_CGEN
+/* Perform any cgen specific initialisation for gas. */
+extern void gas_cgen_begin (void);
+#endif
+
+/* Keep a record of the itbl files we read in. */
+struct itbl_file_list
+{
+ struct itbl_file_list *next;
+ char *name;
+};
+
+/* We build a list of defsyms as we read the options, and then define
+ them after we have initialized everything. */
+struct defsym_list
+{
+ struct defsym_list *next;
+ char *name;
+ valueT value;
+};
+
+
+/* True if a listing is wanted. */
+int listing;
+
+/* Type of debugging to generate. */
+enum debug_info_type debug_type = DEBUG_UNSPECIFIED;
+int use_gnu_debug_info_extensions = 0;
+
+/* Maximum level of macro nesting. */
+int max_macro_nest = 100;
+
+/* argv[0] */
+char * myname;
+
+/* The default obstack chunk size. If we set this to zero, the
+ obstack code will use whatever will fit in a 4096 byte block. */
+int chunksize = 0;
+
+/* To monitor memory allocation more effectively, make this non-zero.
+ Then the chunk sizes for gas and bfd will be reduced. */
+int debug_memory = 0;
+
+/* Enable verbose mode. */
+int verbose = 0;
+
+#ifdef BFD_ASSEMBLER
+segT reg_section;
+segT expr_section;
+segT text_section;
+segT data_section;
+segT bss_section;
+#endif
+
+/* Name of listing file. */
+static char *listing_filename = NULL;
+
+static struct defsym_list *defsyms;
+
+static struct itbl_file_list *itbl_files;
+
+static long start_time;
+
+
+#ifdef USE_EMULATIONS
+#define EMULATION_ENVIRON "AS_EMULATION"
+
+extern struct emulation mipsbelf, mipslelf, mipself;
+extern struct emulation mipsbecoff, mipslecoff, mipsecoff;
+extern struct emulation i386coff, i386elf, i386aout;
+extern struct emulation crisaout, criself;
+
+static struct emulation *const emulations[] = { EMULATIONS };
+static const int n_emulations = sizeof (emulations) / sizeof (emulations[0]);
+
+static void
+select_emulation_mode (int argc, char **argv)
+{
+ int i;
+ char *p, *em = 0;
+
+ for (i = 1; i < argc; i++)
+ if (!strncmp ("--em", argv[i], 4))
+ break;
+
+ if (i == argc)
+ goto do_default;
+
+ p = strchr (argv[i], '=');
+ if (p)
+ p++;
+ else
+ p = argv[i + 1];
+
+ if (!p || !*p)
+ as_fatal (_("missing emulation mode name"));
+ em = p;
+
+ do_default:
+ if (em == 0)
+ em = getenv (EMULATION_ENVIRON);
+ if (em == 0)
+ em = DEFAULT_EMULATION;
+
+ if (em)
+ {
+ for (i = 0; i < n_emulations; i++)
+ if (!strcmp (emulations[i]->name, em))
+ break;
+ if (i == n_emulations)
+ as_fatal (_("unrecognized emulation name `%s'"), em);
+ this_emulation = emulations[i];
+ }
+ else
+ this_emulation = emulations[0];
+
+ this_emulation->init ();
+}
+
+const char *
+default_emul_bfd_name (void)
+{
+ abort ();
+ return NULL;
+}
+
+void
+common_emul_init (void)
+{
+ this_format = this_emulation->format;
+
+ if (this_emulation->leading_underscore == 2)
+ this_emulation->leading_underscore = this_format->dfl_leading_underscore;
+
+ if (this_emulation->default_endian != 2)
+ target_big_endian = this_emulation->default_endian;
+
+ if (this_emulation->fake_label_name == 0)
+ {
+ if (this_emulation->leading_underscore)
+ this_emulation->fake_label_name = "L0\001";
+ else
+ /* What other parameters should we test? */
+ this_emulation->fake_label_name = ".L0\001";
+ }
+}
+#endif
+
+void
+print_version_id (void)
+{
+ static int printed;
+
+ if (printed)
+ return;
+ printed = 1;
+
+#ifdef BFD_ASSEMBLER
+ fprintf (stderr, _("GNU assembler version %s (%s) using BFD version %s"),
+ VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
+#else
+ fprintf (stderr, _("GNU assembler version %s (%s)"), VERSION, TARGET_ALIAS);
+#endif
+ fprintf (stderr, "\n");
+}
+
+static void
+show_usage (FILE * stream)
+{
+ fprintf (stream, _("Usage: %s [option...] [asmfile...]\n"), myname);
+
+ fprintf (stream, _("\
+Options:\n\
+ -a[sub-option...] turn on listings\n\
+ Sub-options [default hls]:\n\
+ c omit false conditionals\n\
+ d omit debugging directives\n\
+ h include high-level source\n\
+ l include assembly\n\
+ m include macro expansions\n\
+ n omit forms processing\n\
+ s include symbols\n\
+ =FILE list to FILE (must be last sub-option)\n"));
+
+ fprintf (stream, _("\
+ -D produce assembler debugging messages\n"));
+ fprintf (stream, _("\
+ --defsym SYM=VAL define symbol SYM to given value\n"));
+#ifdef USE_EMULATIONS
+ {
+ int i;
+ char *def_em;
+
+ fprintf (stream, "\
+ --em=[");
+ for (i = 0; i < n_emulations - 1; i++)
+ fprintf (stream, "%s | ", emulations[i]->name);
+ fprintf (stream, "%s]\n", emulations[i]->name);
+
+ def_em = getenv (EMULATION_ENVIRON);
+ if (!def_em)
+ def_em = DEFAULT_EMULATION;
+ fprintf (stream, _("\
+ emulate output (default %s)\n"), def_em);
+ }
+#endif
+#if defined BFD_ASSEMBLER && (defined OBJ_ELF || defined OBJ_MAYBE_ELF)
+ fprintf (stream, _("\
+ --execstack require executable stack for this object\n"));
+ fprintf (stream, _("\
+ --noexecstack don't require executable stack for this object\n"));
+#endif
+ fprintf (stream, _("\
+ -f skip whitespace and comment preprocessing\n"));
+ fprintf (stream, _("\
+ --gstabs generate stabs debugging information\n"));
+ fprintf (stream, _("\
+ --gstabs+ generate stabs debug info with GNU extensions\n"));
+ fprintf (stream, _("\
+ --gdwarf2 generate DWARF2 debugging information\n"));
+ fprintf (stream, _("\
+ --help show this message and exit\n"));
+ fprintf (stream, _("\
+ --target-help show target specific options\n"));
+ fprintf (stream, _("\
+ -I DIR add DIR to search list for .include directives\n"));
+ fprintf (stream, _("\
+ -J don't warn about signed overflow\n"));
+ fprintf (stream, _("\
+ -K warn when differences altered for long displacements\n"));
+ fprintf (stream, _("\
+ -L,--keep-locals keep local symbols (e.g. starting with `L')\n"));
+ fprintf (stream, _("\
+ -M,--mri assemble in MRI compatibility mode\n"));
+ fprintf (stream, _("\
+ --MD FILE write dependency information in FILE (default none)\n"));
+ fprintf (stream, _("\
+ -nocpp ignored\n"));
+ fprintf (stream, _("\
+ -o OBJFILE name the object-file output OBJFILE (default a.out)\n"));
+ fprintf (stream, _("\
+ -R fold data section into text section\n"));
+ fprintf (stream, _("\
+ --statistics print various measured statistics from execution\n"));
+ fprintf (stream, _("\
+ --strip-local-absolute strip local absolute symbols\n"));
+ fprintf (stream, _("\
+ --traditional-format Use same format as native assembler when possible\n"));
+ fprintf (stream, _("\
+ --version print assembler version number and exit\n"));
+ fprintf (stream, _("\
+ -W --no-warn suppress warnings\n"));
+ fprintf (stream, _("\
+ --warn don't suppress warnings\n"));
+ fprintf (stream, _("\
+ --fatal-warnings treat warnings as errors\n"));
+ fprintf (stream, _("\
+ --itbl INSTTBL extend instruction set to include instructions\n\
+ matching the specifications defined in file INSTTBL\n"));
+ fprintf (stream, _("\
+ -w ignored\n"));
+ fprintf (stream, _("\
+ -X ignored\n"));
+ fprintf (stream, _("\
+ -Z generate object file even after errors\n"));
+ fprintf (stream, _("\
+ --listing-lhs-width set the width in words of the output data column of\n\
+ the listing\n"));
+ fprintf (stream, _("\
+ --listing-lhs-width2 set the width in words of the continuation lines\n\
+ of the output data column; ignored if smaller than\n\
+ the width of the first line\n"));
+ fprintf (stream, _("\
+ --listing-rhs-width set the max width in characters of the lines from\n\
+ the source file\n"));
+ fprintf (stream, _("\
+ --listing-cont-lines set the maximum number of continuation lines used\n\
+ for the output data column of the listing\n"));
+
+ md_show_usage (stream);
+
+ fputc ('\n', stream);
+ fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
+}
+
+/* Since it is easy to do here we interpret the special arg "-"
+ to mean "use stdin" and we set that argv[] pointing to "".
+ After we have munged argv[], the only things left are source file
+ name(s) and ""(s) denoting stdin. These file names are used
+ (perhaps more than once) later.
+
+ check for new machine-dep cmdline options in
+ md_parse_option definitions in config/tc-*.c. */
+
+static void
+parse_args (int * pargc, char *** pargv)
+{
+ int old_argc;
+ int new_argc;
+ char ** old_argv;
+ char ** new_argv;
+ /* Starting the short option string with '-' is for programs that
+ expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1. */
+ char *shortopts;
+ extern const char *md_shortopts;
+ static const char std_shortopts[] =
+ {
+ '-', 'J',
+#ifndef WORKING_DOT_WORD
+ /* -K is not meaningful if .word is not being hacked. */
+ 'K',
+#endif
+ 'L', 'M', 'R', 'W', 'Z', 'a', ':', ':', 'D', 'f', 'I', ':', 'o', ':',
+#ifndef VMS
+ /* -v takes an argument on VMS, so we don't make it a generic
+ option. */
+ 'v',
+#endif
+ 'w', 'X',
+ /* New option for extending instruction set (see also --itbl below). */
+ 't', ':',
+ '\0'
+ };
+ struct option *longopts;
+ extern struct option md_longopts[];
+ extern size_t md_longopts_size;
+ /* Codes used for the long options with no short synonyms. */
+ enum option_values
+ {
+ OPTION_HELP = OPTION_STD_BASE,
+ OPTION_NOCPP,
+ OPTION_STATISTICS,
+ OPTION_VERSION,
+ OPTION_DUMPCONFIG,
+ OPTION_VERBOSE,
+ OPTION_EMULATION,
+ OPTION_DEFSYM,
+ OPTION_INSTTBL,
+ OPTION_LISTING_LHS_WIDTH,
+ OPTION_LISTING_LHS_WIDTH2,
+ OPTION_LISTING_RHS_WIDTH,
+ OPTION_LISTING_CONT_LINES,
+ OPTION_DEPFILE,
+ OPTION_GSTABS,
+ OPTION_GSTABS_PLUS,
+ OPTION_STRIP_LOCAL_ABSOLUTE,
+ OPTION_TRADITIONAL_FORMAT,
+ OPTION_GDWARF2,
+ OPTION_WARN,
+ OPTION_TARGET_HELP,
+ OPTION_EXECSTACK,
+ OPTION_NOEXECSTACK,
+ OPTION_WARN_FATAL
+ };
+
+ static const struct option std_longopts[] =
+ {
+ {"help", no_argument, NULL, OPTION_HELP},
+ /* getopt allows abbreviations, so we do this to stop it from
+ treating -k as an abbreviation for --keep-locals. Some
+ ports use -k to enable PIC assembly. */
+ {"keep-locals", no_argument, NULL, 'L'},
+ {"keep-locals", no_argument, NULL, 'L'},
+ {"mri", no_argument, NULL, 'M'},
+ {"nocpp", no_argument, NULL, OPTION_NOCPP},
+ {"statistics", no_argument, NULL, OPTION_STATISTICS},
+ {"version", no_argument, NULL, OPTION_VERSION},
+ {"dump-config", no_argument, NULL, OPTION_DUMPCONFIG},
+ {"verbose", no_argument, NULL, OPTION_VERBOSE},
+ {"emulation", required_argument, NULL, OPTION_EMULATION},
+ {"defsym", required_argument, NULL, OPTION_DEFSYM},
+ /* New option for extending instruction set (see also -t above).
+ The "-t file" or "--itbl file" option extends the basic set of
+ valid instructions by reading "file", a text file containing a
+ list of instruction formats. The additional opcodes and their
+ formats are added to the built-in set of instructions, and
+ mnemonics for new registers may also be defined. */
+ {"itbl", required_argument, NULL, OPTION_INSTTBL},
+ {"listing-lhs-width", required_argument, NULL, OPTION_LISTING_LHS_WIDTH},
+ {"listing-lhs-width2", required_argument, NULL, OPTION_LISTING_LHS_WIDTH2},
+ {"listing-rhs-width", required_argument, NULL, OPTION_LISTING_RHS_WIDTH},
+ {"listing-cont-lines", required_argument, NULL, OPTION_LISTING_CONT_LINES},
+ {"MD", required_argument, NULL, OPTION_DEPFILE},
+ {"gstabs", no_argument, NULL, OPTION_GSTABS},
+ {"gstabs+", no_argument, NULL, OPTION_GSTABS_PLUS},
+ {"strip-local-absolute", no_argument, NULL, OPTION_STRIP_LOCAL_ABSOLUTE},
+ {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT},
+ {"gdwarf2", no_argument, NULL, OPTION_GDWARF2},
+ {"no-warn", no_argument, NULL, 'W'},
+ {"warn", no_argument, NULL, OPTION_WARN},
+ {"target-help", no_argument, NULL, OPTION_TARGET_HELP},
+#if defined BFD_ASSEMBLER && (defined OBJ_ELF || defined OBJ_MAYBE_ELF)
+ {"execstack", no_argument, NULL, OPTION_EXECSTACK},
+ {"noexecstack", no_argument, NULL, OPTION_NOEXECSTACK},
+#endif
+ {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL}
+ /* When you add options here, check that they do not collide with
+ OPTION_MD_BASE. See as.h. */
+ };
+
+ /* Construct the option lists from the standard list and the target
+ dependent list. Include space for an extra NULL option and
+ always NULL terminate. */
+ shortopts = concat (std_shortopts, md_shortopts, (char *) NULL);
+ longopts = xmalloc (sizeof (std_longopts) + md_longopts_size + sizeof (struct option));
+ memcpy (longopts, std_longopts, sizeof (std_longopts));
+ memcpy (((char *) longopts) + sizeof (std_longopts), md_longopts, md_longopts_size);
+ memset (((char *) longopts) + sizeof (std_longopts) + md_longopts_size,
+ 0, sizeof (struct option));
+
+ /* Make a local copy of the old argv. */
+ old_argc = *pargc;
+ old_argv = *pargv;
+
+ /* Initialize a new argv that contains no options. */
+ new_argv = xmalloc (sizeof (char *) * (old_argc + 1));
+ new_argv[0] = old_argv[0];
+ new_argc = 1;
+ new_argv[new_argc] = NULL;
+
+ while (1)
+ {
+ /* getopt_long_only is like getopt_long, but '-' as well as '--' can
+ indicate a long option. */
+ int longind;
+ int optc = getopt_long_only (old_argc, old_argv, shortopts, longopts,
+ &longind);
+
+ if (optc == -1)
+ break;
+
+ switch (optc)
+ {
+ default:
+ /* md_parse_option should return 1 if it recognizes optc,
+ 0 if not. */
+ if (md_parse_option (optc, optarg) != 0)
+ break;
+ /* `-v' isn't included in the general short_opts list, so check for
+ it explicitly here before deciding we've gotten a bad argument. */
+ if (optc == 'v')
+ {
+#ifdef VMS
+ /* Telling getopt to treat -v's value as optional can result
+ in it picking up a following filename argument here. The
+ VMS code in md_parse_option can return 0 in that case,
+ but it has no way of pushing the filename argument back. */
+ if (optarg && *optarg)
+ new_argv[new_argc++] = optarg, new_argv[new_argc] = NULL;
+ else
+#else
+ case 'v':
+#endif
+ case OPTION_VERBOSE:
+ print_version_id ();
+ verbose = 1;
+ break;
+ }
+ /* Fall through. */
+
+ case '?':
+ exit (EXIT_FAILURE);
+
+ case 1: /* File name. */
+ if (!strcmp (optarg, "-"))
+ optarg = "";
+ new_argv[new_argc++] = optarg;
+ new_argv[new_argc] = NULL;
+ break;
+
+ case OPTION_TARGET_HELP:
+ md_show_usage (stdout);
+ exit (EXIT_SUCCESS);
+
+ case OPTION_HELP:
+ show_usage (stdout);
+ exit (EXIT_SUCCESS);
+
+ case OPTION_NOCPP:
+ break;
+
+ case OPTION_STATISTICS:
+ flag_print_statistics = 1;
+ break;
+
+ case OPTION_STRIP_LOCAL_ABSOLUTE:
+ flag_strip_local_absolute = 1;
+ break;
+
+ case OPTION_TRADITIONAL_FORMAT:
+ flag_traditional_format = 1;
+ break;
+
+ case OPTION_VERSION:
+ /* This output is intended to follow the GNU standards document. */
+#ifdef BFD_ASSEMBLER
+ printf (_("GNU assembler %s\n"), BFD_VERSION_STRING);
+#else
+ printf (_("GNU assembler %s\n"), VERSION);
+#endif
+ printf (_("Copyright 2002 Free Software Foundation, Inc.\n"));
+ printf (_("\
+This program is free software; you may redistribute it under the terms of\n\
+the GNU General Public License. This program has absolutely no warranty.\n"));
+ printf (_("This assembler was configured for a target of `%s'.\n"),
+ TARGET_ALIAS);
+ exit (EXIT_SUCCESS);
+
+ case OPTION_EMULATION:
+#ifdef USE_EMULATIONS
+ if (strcmp (optarg, this_emulation->name))
+ as_fatal (_("multiple emulation names specified"));
+#else
+ as_fatal (_("emulations not handled in this configuration"));
+#endif
+ break;
+
+ case OPTION_DUMPCONFIG:
+ fprintf (stderr, _("alias = %s\n"), TARGET_ALIAS);
+ fprintf (stderr, _("canonical = %s\n"), TARGET_CANONICAL);
+ fprintf (stderr, _("cpu-type = %s\n"), TARGET_CPU);
+#ifdef TARGET_OBJ_FORMAT
+ fprintf (stderr, _("format = %s\n"), TARGET_OBJ_FORMAT);
+#endif
+#ifdef TARGET_FORMAT
+ fprintf (stderr, _("bfd-target = %s\n"), TARGET_FORMAT);
+#endif
+ exit (EXIT_SUCCESS);
+
+ case OPTION_DEFSYM:
+ {
+ char *s;
+ valueT i;
+ struct defsym_list *n;
+
+ for (s = optarg; *s != '\0' && *s != '='; s++)
+ ;
+ if (*s == '\0')
+ as_fatal (_("bad defsym; format is --defsym name=value"));
+ *s++ = '\0';
+#ifdef BFD_ASSEMBLER
+ i = bfd_scan_vma (s, (const char **) NULL, 0);
+#else
+ i = strtol (s, (char **) NULL, 0);
+#endif
+ n = xmalloc (sizeof *n);
+ n->next = defsyms;
+ n->name = optarg;
+ n->value = i;
+ defsyms = n;
+ }
+ break;
+
+ case OPTION_INSTTBL:
+ case 't':
+ {
+ /* optarg is the name of the file containing the instruction
+ formats, opcodes, register names, etc. */
+ struct itbl_file_list *n;
+
+ if (optarg == NULL)
+ {
+ as_warn (_("no file name following -t option"));
+ break;
+ }
+
+ n = xmalloc (sizeof * n);
+ n->next = itbl_files;
+ n->name = optarg;
+ itbl_files = n;
+
+ /* Parse the file and add the new instructions to our internal
+ table. If multiple instruction tables are specified, the
+ information from this table gets appended onto the existing
+ internal table. */
+ itbl_files->name = xstrdup (optarg);
+ if (itbl_parse (itbl_files->name) != 0)
+ as_fatal (_("failed to read instruction table %s\n"),
+ itbl_files->name);
+ }
+ break;
+
+ case OPTION_DEPFILE:
+ start_dependencies (optarg);
+ break;
+
+ case OPTION_GSTABS_PLUS:
+ use_gnu_debug_info_extensions = 1;
+ /* Fall through. */
+ case OPTION_GSTABS:
+ debug_type = DEBUG_STABS;
+ break;
+
+ case OPTION_GDWARF2:
+ debug_type = DEBUG_DWARF2;
+ break;
+
+ case 'J':
+ flag_signed_overflow_ok = 1;
+ break;
+
+#ifndef WORKING_DOT_WORD
+ case 'K':
+ flag_warn_displacement = 1;
+ break;
+#endif
+ case 'L':
+ flag_keep_locals = 1;
+ break;
+
+ case OPTION_LISTING_LHS_WIDTH:
+ listing_lhs_width = atoi (optarg);
+ if (listing_lhs_width_second < listing_lhs_width)
+ listing_lhs_width_second = listing_lhs_width;
+ break;
+ case OPTION_LISTING_LHS_WIDTH2:
+ {
+ int tmp = atoi (optarg);
+ if (tmp > listing_lhs_width)
+ listing_lhs_width_second = tmp;
+ }
+ break;
+ case OPTION_LISTING_RHS_WIDTH:
+ listing_rhs_width = atoi (optarg);
+ break;
+ case OPTION_LISTING_CONT_LINES:
+ listing_lhs_cont_lines = atoi (optarg);
+ break;
+
+ case 'M':
+ flag_mri = 1;
+#ifdef TC_M68K
+ flag_m68k_mri = 1;
+#endif
+ break;
+
+ case 'R':
+ flag_readonly_data_in_text = 1;
+ break;
+
+ case 'W':
+ flag_no_warnings = 1;
+ break;
+
+ case OPTION_WARN:
+ flag_no_warnings = 0;
+ flag_fatal_warnings = 0;
+ break;
+
+ case OPTION_WARN_FATAL:
+ flag_no_warnings = 0;
+ flag_fatal_warnings = 1;
+ break;
+
+#if defined BFD_ASSEMBLER && (defined OBJ_ELF || defined OBJ_MAYBE_ELF)
+ case OPTION_EXECSTACK:
+ flag_execstack = 1;
+ flag_noexecstack = 0;
+ break;
+
+ case OPTION_NOEXECSTACK:
+ flag_noexecstack = 1;
+ flag_execstack = 0;
+ break;
+#endif
+ case 'Z':
+ flag_always_generate_output = 1;
+ break;
+
+ case 'a':
+ if (optarg)
+ {
+ if (md_parse_option (optc, optarg) != 0)
+ break;
+
+ while (*optarg)
+ {
+ switch (*optarg)
+ {
+ case 'c':
+ listing |= LISTING_NOCOND;
+ break;
+ case 'd':
+ listing |= LISTING_NODEBUG;
+ break;
+ case 'h':
+ listing |= LISTING_HLL;
+ break;
+ case 'l':
+ listing |= LISTING_LISTING;
+ break;
+ case 'm':
+ listing |= LISTING_MACEXP;
+ break;
+ case 'n':
+ listing |= LISTING_NOFORM;
+ break;
+ case 's':
+ listing |= LISTING_SYMBOLS;
+ break;
+ case '=':
+ listing_filename = xstrdup (optarg + 1);
+ optarg += strlen (listing_filename);
+ break;
+ default:
+ as_fatal (_("invalid listing option `%c'"), *optarg);
+ break;
+ }
+ optarg++;
+ }
+ }
+ if (!listing)
+ listing = LISTING_DEFAULT;
+ break;
+
+ case 'D':
+ /* DEBUG is implemented: it debugs different
+ things from other people's assemblers. */
+ flag_debug = 1;
+ break;
+
+ case 'f':
+ flag_no_comments = 1;
+ break;
+
+ case 'I':
+ { /* Include file directory. */
+ char *temp = xstrdup (optarg);
+ add_include_dir (temp);
+ break;
+ }
+
+ case 'o':
+ out_file_name = xstrdup (optarg);
+ break;
+
+ case 'w':
+ break;
+
+ case 'X':
+ /* -X means treat warnings as errors. */
+ break;
+ }
+ }
+
+ free (shortopts);
+ free (longopts);
+
+ *pargc = new_argc;
+ *pargv = new_argv;
+
+#ifdef md_after_parse_args
+ md_after_parse_args ();
+#endif
+}
+
+static void
+dump_statistics (void)
+{
+#ifdef HAVE_SBRK
+ char *lim = (char *) sbrk (0);
+#endif
+ long run_time = get_run_time () - start_time;
+
+ fprintf (stderr, _("%s: total time in assembly: %ld.%06ld\n"),
+ myname, run_time / 1000000, run_time % 1000000);
+#ifdef HAVE_SBRK
+ fprintf (stderr, _("%s: data size %ld\n"),
+ myname, (long) (lim - (char *) &environ));
+#endif
+
+ subsegs_print_statistics (stderr);
+ write_print_statistics (stderr);
+ symbol_print_statistics (stderr);
+ read_print_statistics (stderr);
+
+#ifdef tc_print_statistics
+ tc_print_statistics (stderr);
+#endif
+
+#ifdef obj_print_statistics
+ obj_print_statistics (stderr);
+#endif
+}
+
+/* The interface between the macro code and gas expression handling. */
+
+static int
+macro_expr (const char *emsg, int idx, sb *in, int *val)
+{
+ char *hold;
+ expressionS ex;
+
+ sb_terminate (in);
+
+ hold = input_line_pointer;
+ input_line_pointer = in->ptr + idx;
+ expression (&ex);
+ idx = input_line_pointer - in->ptr;
+ input_line_pointer = hold;
+
+ if (ex.X_op != O_constant)
+ as_bad ("%s", emsg);
+
+ *val = (int) ex.X_add_number;
+
+ return idx;
+}
+
+/* Here to attempt 1 pass over each input file.
+ We scan argv[*] looking for filenames or exactly "" which is
+ shorthand for stdin. Any argv that is NULL is not a file-name.
+ We set need_pass_2 TRUE if, after this, we still have unresolved
+ expressions of the form (unknown value)+-(unknown value).
+
+ Note the un*x semantics: there is only 1 logical input file, but it
+ may be a catenation of many 'physical' input files. */
+
+static void
+perform_an_assembly_pass (int argc, char ** argv)
+{
+ int saw_a_file = 0;
+#ifdef BFD_ASSEMBLER
+ flagword applicable;
+#endif
+
+ need_pass_2 = 0;
+
+#ifndef BFD_ASSEMBLER
+#ifdef MANY_SEGMENTS
+ {
+ unsigned int i;
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ segment_info[i].fix_root = 0;
+ }
+ /* Create the three fixed ones. */
+ {
+ segT seg;
+
+#ifdef TE_APOLLO
+ seg = subseg_new (".wtext", 0);
+#else
+ seg = subseg_new (".text", 0);
+#endif
+ assert (seg == SEG_E0);
+ seg = subseg_new (".data", 0);
+ assert (seg == SEG_E1);
+ seg = subseg_new (".bss", 0);
+ assert (seg == SEG_E2);
+#ifdef TE_APOLLO
+ create_target_segments ();
+#endif
+ }
+
+#else /* not MANY_SEGMENTS. */
+ text_fix_root = NULL;
+ data_fix_root = NULL;
+ bss_fix_root = NULL;
+#endif /* not MANY_SEGMENTS. */
+#else /* BFD_ASSEMBLER. */
+ /* Create the standard sections, and those the assembler uses
+ internally. */
+ text_section = subseg_new (TEXT_SECTION_NAME, 0);
+ data_section = subseg_new (DATA_SECTION_NAME, 0);
+ bss_section = subseg_new (BSS_SECTION_NAME, 0);
+ /* @@ FIXME -- we're setting the RELOC flag so that sections are assumed
+ to have relocs, otherwise we don't find out in time. */
+ applicable = bfd_applicable_section_flags (stdoutput);
+ bfd_set_section_flags (stdoutput, text_section,
+ applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_CODE | SEC_READONLY));
+ bfd_set_section_flags (stdoutput, data_section,
+ applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_DATA));
+ bfd_set_section_flags (stdoutput, bss_section, applicable & SEC_ALLOC);
+ seg_info (bss_section)->bss = 1;
+ subseg_new (BFD_ABS_SECTION_NAME, 0);
+ subseg_new (BFD_UND_SECTION_NAME, 0);
+ reg_section = subseg_new ("*GAS `reg' section*", 0);
+ expr_section = subseg_new ("*GAS `expr' section*", 0);
+
+#endif /* BFD_ASSEMBLER. */
+
+ subseg_set (text_section, 0);
+
+ /* This may add symbol table entries, which requires having an open BFD,
+ and sections already created, in BFD_ASSEMBLER mode. */
+ md_begin ();
+
+#ifdef USING_CGEN
+ gas_cgen_begin ();
+#endif
+#ifdef obj_begin
+ obj_begin ();
+#endif
+
+ /* Skip argv[0]. */
+ argv++;
+ argc--;
+
+ while (argc--)
+ {
+ if (*argv)
+ { /* Is it a file-name argument? */
+ PROGRESS (1);
+ saw_a_file++;
+ /* argv->"" if stdin desired, else->filename. */
+ read_a_source_file (*argv);
+ }
+ argv++; /* Completed that argv. */
+ }
+ if (!saw_a_file)
+ read_a_source_file ("");
+}
+
+
+int
+main (int argc, char ** argv)
+{
+ int macro_alternate;
+ int macro_strip_at;
+ int keep_it;
+
+ start_time = get_run_time ();
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+#if defined (HAVE_SETLOCALE)
+ setlocale (LC_CTYPE, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ if (debug_memory)
+ chunksize = 64;
+
+#ifdef HOST_SPECIAL_INIT
+ HOST_SPECIAL_INIT (argc, argv);
+#endif
+
+ myname = argv[0];
+ xmalloc_set_program_name (myname);
+
+ START_PROGRESS (myname, 0);
+
+#ifndef OBJ_DEFAULT_OUTPUT_FILE_NAME
+#define OBJ_DEFAULT_OUTPUT_FILE_NAME "a.out"
+#endif
+
+ out_file_name = OBJ_DEFAULT_OUTPUT_FILE_NAME;
+
+ hex_init ();
+#ifdef BFD_ASSEMBLER
+ bfd_init ();
+ bfd_set_error_program_name (myname);
+#endif
+
+#ifdef USE_EMULATIONS
+ select_emulation_mode (argc, argv);
+#endif
+
+ PROGRESS (1);
+ symbol_begin ();
+ frag_init ();
+ subsegs_begin ();
+ parse_args (&argc, &argv);
+ read_begin ();
+ input_scrub_begin ();
+ expr_begin ();
+
+ if (flag_print_statistics)
+ xatexit (dump_statistics);
+
+ macro_alternate = 0;
+ macro_strip_at = 0;
+#ifdef TC_I960
+ macro_strip_at = flag_mri;
+#endif
+#ifdef TC_A29K
+ /* For compatibility with the AMD 29K family macro assembler
+ specification. */
+ macro_alternate = 1;
+ macro_strip_at = 1;
+#endif
+
+ macro_init (macro_alternate, flag_mri, macro_strip_at, macro_expr);
+
+ PROGRESS (1);
+
+#ifdef BFD_ASSEMBLER
+ output_file_create (out_file_name);
+ assert (stdoutput != 0);
+#endif
+
+#ifdef tc_init_after_args
+ tc_init_after_args ();
+#endif
+
+ itbl_init ();
+
+ /* Now that we have fully initialized, and have created the output
+ file, define any symbols requested by --defsym command line
+ arguments. */
+ while (defsyms != NULL)
+ {
+ symbolS *sym;
+ struct defsym_list *next;
+
+ sym = symbol_new (defsyms->name, absolute_section, defsyms->value,
+ &zero_address_frag);
+ symbol_table_insert (sym);
+ next = defsyms->next;
+ free (defsyms);
+ defsyms = next;
+ }
+
+ PROGRESS (1);
+
+ /* Assemble it. */
+ perform_an_assembly_pass (argc, argv);
+
+ cond_finish_check (-1);
+
+#ifdef md_end
+ md_end ();
+#endif
+
+#if defined BFD_ASSEMBLER && (defined OBJ_ELF || defined OBJ_MAYBE_ELF)
+ if ((flag_execstack || flag_noexecstack)
+ && OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ {
+ segT gnustack;
+
+ gnustack = subseg_new (".note.GNU-stack", 0);
+ bfd_set_section_flags (stdoutput, gnustack,
+ SEC_READONLY | (flag_execstack ? SEC_CODE : 0));
+
+ }
+#endif
+
+ /* If we've been collecting dwarf2 .debug_line info, either for
+ assembly debugging or on behalf of the compiler, emit it now. */
+ dwarf2_finish ();
+
+ /* If we constructed dwarf2 .eh_frame info, either via .cfi
+ directives from the user or by the backend, emit it now. */
+ cfi_finish ();
+
+ if (seen_at_least_1_file ()
+ && (flag_always_generate_output || had_errors () == 0))
+ keep_it = 1;
+ else
+ keep_it = 0;
+
+#if defined (BFD_ASSEMBLER) || !defined (BFD)
+ /* This used to be done at the start of write_object_file in
+ write.c, but that caused problems when doing listings when
+ keep_it was zero. This could probably be moved above md_end, but
+ I didn't want to risk the change. */
+ subsegs_finish ();
+#endif
+
+ if (keep_it)
+ write_object_file ();
+
+#ifndef NO_LISTING
+ listing_print (listing_filename);
+#endif
+
+#ifndef OBJ_VMS /* Does its own file handling. */
+#ifndef BFD_ASSEMBLER
+ if (keep_it)
+#endif
+ output_file_close (out_file_name);
+#endif
+
+ if (flag_fatal_warnings && had_warnings () > 0 && had_errors () == 0)
+ as_bad (_("%d warnings, treating warnings as errors"), had_warnings ());
+
+ if (had_errors () > 0 && ! flag_always_generate_output)
+ keep_it = 0;
+
+ if (!keep_it)
+ unlink (out_file_name);
+
+ input_scrub_end ();
+
+ END_PROGRESS (myname);
+
+ /* Use xexit instead of return, because under VMS environments they
+ may not place the same interpretation on the value given. */
+ if (had_errors () > 0)
+ xexit (EXIT_FAILURE);
+
+ /* Only generate dependency file if assembler was successful. */
+ print_dependencies ();
+
+ xexit (EXIT_SUCCESS);
+}
+
diff --git a/x/binutils/gas/as.h b/x/binutils/gas/as.h
new file mode 100644
index 0000000..5e30f47
--- /dev/null
+++ b/x/binutils/gas/as.h
@@ -0,0 +1,717 @@
+/* as.h - global header file
+ Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef GAS
+#define GAS 1
+/* I think this stuff is largely out of date. xoxorich.
+ *
+ * CAPITALISED names are #defined.
+ * "lowercaseH" is #defined if "lowercase.h" has been #include-d.
+ * "lowercaseT" is a typedef of "lowercase" objects.
+ * "lowercaseP" is type "pointer to object of type 'lowercase'".
+ * "lowercaseS" is typedef struct ... lowercaseS.
+ *
+ * #define DEBUG to enable all the "know" assertion tests.
+ * #define SUSPECT when debugging hash code.
+ * #define COMMON as "extern" for all modules except one, where you #define
+ * COMMON as "".
+ * If TEST is #defined, then we are testing a module: #define COMMON as "".
+ */
+
+#include "config.h"
+#include "bin-bugs.h"
+
+/* This is the code recommended in the autoconf documentation, almost
+ verbatim. If it doesn't work for you, let me know, and notify
+ djm@gnu.ai.mit.edu as well. */
+/* Added void* version for STDC case. This is to be compatible with
+ the declaration in bison.simple, used for m68k operand parsing.
+ --KR 1995.08.08 */
+/* Force void* decl for hpux. This is what Bison uses. --KR 1995.08.16 */
+
+#ifndef __GNUC__
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+/* Indented so that pre-ansi C compilers will ignore it, rather than
+ choke on it. Some versions of AIX require this to be the first
+ thing in the file. */
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+# if !defined (__STDC__) && !defined (__hpux)
+extern char *alloca ();
+# else
+extern void *alloca ();
+# endif /* __STDC__, __hpux */
+# endif /* alloca */
+# endif /* _AIX */
+# endif /* HAVE_ALLOCA_H */
+#endif /* __GNUC__ */
+
+/* Now, tend to the rest of the configuration. */
+
+/* System include files first... */
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+/* for size_t, pid_t */
+#include <sys/types.h>
+#endif
+
+#include "getopt.h"
+/* The first getopt value for machine-independent long options.
+ 150 isn't special; it's just an arbitrary non-ASCII char value. */
+#define OPTION_STD_BASE 150
+/* The first getopt value for machine-dependent long options.
+ 190 gives the standard options room to grow. */
+#define OPTION_MD_BASE 190
+
+#ifdef DEBUG
+#undef NDEBUG
+#endif
+#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6)
+#define __PRETTY_FUNCTION__ ((char*)0)
+#endif
+#if 0
+
+/* Handle lossage with assert.h. */
+#ifndef BROKEN_ASSERT
+#include <assert.h>
+#else /* BROKEN_ASSERT */
+#ifndef NDEBUG
+#define assert(p) ((p) ? 0 : (as_assert (__FILE__, __LINE__, __PRETTY_FUNCTION__), 0))
+#else
+#define assert(p) ((p), 0)
+#endif
+#endif /* BROKEN_ASSERT */
+
+#else
+
+#define assert(P) ((P) ? 0 : (as_assert (__FILE__, __LINE__, __PRETTY_FUNCTION__), 0))
+#undef abort
+#define abort() as_abort (__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#endif
+
+/* Now GNU header files... */
+#include "ansidecl.h"
+#ifdef BFD_ASSEMBLER
+#include "bfd.h"
+#endif
+#include "libiberty.h"
+
+/* Define the standard progress macros. */
+#include "progress.h"
+
+/* This doesn't get taken care of anywhere. */
+#ifndef __MWERKS__ /* Metrowerks C chokes on the "defined (inline)" */
+#if !defined (__GNUC__) && !defined (inline)
+#define inline
+#endif
+#endif /* !__MWERKS__ */
+
+/* Other stuff from config.h. */
+#ifdef NEED_DECLARATION_STRSTR
+extern char *strstr ();
+#endif
+#ifdef NEED_DECLARATION_MALLOC
+extern PTR malloc ();
+extern PTR realloc ();
+#endif
+#ifdef NEED_DECLARATION_FREE
+extern void free ();
+#endif
+#ifdef NEED_DECLARATION_ERRNO
+extern int errno;
+#endif
+#ifdef NEED_DECLARATION_ENVIRON
+extern char **environ;
+#endif
+
+/* This is needed for VMS. */
+#if ! defined (HAVE_UNLINK) && defined (HAVE_REMOVE)
+#define unlink remove
+#endif
+
+/* Hack to make "gcc -Wall" not complain about obstack macros. */
+#if !defined (memcpy) && !defined (bcopy)
+#define bcopy(src,dest,size) memcpy (dest, src, size)
+#endif
+
+/* Make Saber happier on obstack.h. */
+#ifdef SABER
+#undef __PTR_TO_INT
+#define __PTR_TO_INT(P) ((int) (P))
+#undef __INT_TO_PTR
+#define __INT_TO_PTR(P) ((char *) (P))
+#endif
+
+#ifndef __LINE__
+#define __LINE__ "unknown"
+#endif /* __LINE__ */
+
+#ifndef __FILE__
+#define __FILE__ "unknown"
+#endif /* __FILE__ */
+
+#ifndef FOPEN_WB
+#if defined GO32 || defined __MINGW32__
+#include "fopen-bin.h"
+#else
+#include "fopen-same.h"
+#endif
+#endif
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#define EXIT_FAILURE 1
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free xfree
+
+#define xfree free
+
+#include "asintl.h"
+
+#define BAD_CASE(val) \
+ { \
+ as_fatal (_("Case value %ld unexpected at line %d of file \"%s\"\n"), \
+ (long) val, __LINE__, __FILE__); \
+ }
+
+#include "flonum.h"
+
+/* These are assembler-wide concepts */
+
+#ifdef BFD_ASSEMBLER
+extern bfd *stdoutput;
+typedef bfd_vma addressT;
+typedef bfd_signed_vma offsetT;
+#else
+typedef unsigned long addressT;
+typedef long offsetT;
+#endif
+
+/* Type of symbol value, etc. For use in prototypes. */
+typedef addressT valueT;
+
+#ifndef COMMON
+#ifdef TEST
+#define COMMON /* declare our COMMONs storage here. */
+#else
+#define COMMON extern /* our commons live elsewhere */
+#endif
+#endif
+/* COMMON now defined */
+
+#ifdef DEBUG
+#ifndef know
+#define know(p) assert(p) /* Verify our assumptions! */
+#endif /* not yet defined */
+#else
+#define know(p) /* know() checks are no-op.ed */
+#endif
+
+/* input_scrub.c */
+
+/* Supplies sanitised buffers to read.c.
+ Also understands printing line-number part of error messages. */
+
+/* subsegs.c Sub-segments. Also, segment(=expression type)s.*/
+
+#ifndef BFD_ASSEMBLER
+
+#ifdef MANY_SEGMENTS
+#include "bfd.h"
+#define N_SEGMENTS 40
+#define SEG_NORMAL(x) ((x) >= SEG_E0 && (x) <= SEG_E39)
+#define SEG_LIST SEG_E0,SEG_E1,SEG_E2,SEG_E3,SEG_E4,SEG_E5,SEG_E6,SEG_E7,SEG_E8,SEG_E9,\
+ SEG_E10,SEG_E11,SEG_E12,SEG_E13,SEG_E14,SEG_E15,SEG_E16,SEG_E17,SEG_E18,SEG_E19,\
+ SEG_E20,SEG_E21,SEG_E22,SEG_E23,SEG_E24,SEG_E25,SEG_E26,SEG_E27,SEG_E28,SEG_E29,\
+ SEG_E30,SEG_E31,SEG_E32,SEG_E33,SEG_E34,SEG_E35,SEG_E36,SEG_E37,SEG_E38,SEG_E39
+#define SEG_TEXT SEG_E0
+#define SEG_DATA SEG_E1
+#define SEG_BSS SEG_E2
+#define SEG_LAST SEG_E39
+#else
+#define N_SEGMENTS 3
+#define SEG_NORMAL(x) ((x) == SEG_TEXT || (x) == SEG_DATA || (x) == SEG_BSS)
+#define SEG_LIST SEG_TEXT,SEG_DATA,SEG_BSS
+#endif
+
+typedef enum _segT {
+ SEG_ABSOLUTE = 0,
+ SEG_LIST,
+ SEG_UNKNOWN,
+ SEG_GOOF, /* Only happens if AS has a logic error. */
+ /* Invented so we don't crash printing */
+ /* error message involving weird segment. */
+ SEG_EXPR, /* Intermediate expression values. */
+ SEG_DEBUG, /* Debug segment */
+ SEG_NTV, /* Transfert vector preload segment */
+ SEG_PTV, /* Transfert vector postload segment */
+ SEG_REGISTER /* Mythical: a register-valued expression */
+} segT;
+
+#define SEG_MAXIMUM_ORDINAL (SEG_REGISTER)
+#else
+typedef asection *segT;
+#define SEG_NORMAL(SEG) ((SEG) != absolute_section \
+ && (SEG) != undefined_section \
+ && (SEG) != reg_section \
+ && (SEG) != expr_section)
+#endif
+typedef int subsegT;
+
+/* What subseg we are accessing now? */
+COMMON subsegT now_subseg;
+
+/* Segment our instructions emit to. */
+COMMON segT now_seg;
+
+#ifdef BFD_ASSEMBLER
+#define segment_name(SEG) bfd_get_section_name (stdoutput, SEG)
+#else
+extern char const *const seg_name[];
+#define segment_name(SEG) seg_name[(int) (SEG)]
+#endif
+
+#ifndef BFD_ASSEMBLER
+extern int section_alignment[];
+#endif
+
+#ifdef BFD_ASSEMBLER
+extern segT reg_section, expr_section;
+/* Shouldn't these be eliminated someday? */
+extern segT text_section, data_section, bss_section;
+#define absolute_section bfd_abs_section_ptr
+#define undefined_section bfd_und_section_ptr
+#else
+#define reg_section SEG_REGISTER
+#define expr_section SEG_EXPR
+#define text_section SEG_TEXT
+#define data_section SEG_DATA
+#define bss_section SEG_BSS
+#define absolute_section SEG_ABSOLUTE
+#define undefined_section SEG_UNKNOWN
+#endif
+
+/* relax() */
+
+enum _relax_state {
+ /* Variable chars to be repeated fr_offset times.
+ Fr_symbol unused. Used with fr_offset == 0 for a
+ constant length frag. */
+ rs_fill = 1,
+
+ /* Align. The fr_offset field holds the power of 2 to which to
+ align. The fr_var field holds the number of characters in the
+ fill pattern. The fr_subtype field holds the maximum number of
+ bytes to skip when aligning, or 0 if there is no maximum. */
+ rs_align,
+
+ /* Align code. The fr_offset field holds the power of 2 to which
+ to align. This type is only generated by machine specific
+ code, which is normally responsible for handling the fill
+ pattern. The fr_subtype field holds the maximum number of
+ bytes to skip when aligning, or 0 if there is no maximum. */
+ rs_align_code,
+
+ /* Test for alignment. Like rs_align, but used by several targets
+ to warn if data is not properly aligned. */
+ rs_align_test,
+
+ /* Org: Fr_offset, fr_symbol: address. 1 variable char: fill
+ character. */
+ rs_org,
+
+#ifndef WORKING_DOT_WORD
+ /* JF: gunpoint */
+ rs_broken_word,
+#endif
+
+ /* machine-specific relaxable (or similarly alterable) instruction */
+ rs_machine_dependent,
+
+ /* .space directive with expression operand that needs to be computed
+ later. Similar to rs_org, but different.
+ fr_symbol: operand
+ 1 variable char: fill character */
+ rs_space,
+
+ /* A DWARF leb128 value; only ELF uses this. The subtype is 0 for
+ unsigned, 1 for signed. */
+ rs_leb128,
+
+ /* Exception frame information which we may be able to optimize. */
+ rs_cfa,
+
+ /* Cross-fragment dwarf2 line number optimization. */
+ rs_dwarf2dbg
+};
+
+typedef enum _relax_state relax_stateT;
+
+/* This type is used in prototypes, so it can't be a type that will be
+ widened for argument passing. */
+typedef unsigned int relax_substateT;
+
+/* Enough bits for address, but still an integer type.
+ Could be a problem, cross-assembling for 64-bit machines. */
+typedef addressT relax_addressT;
+
+struct relax_type
+{
+ /* Forward reach. Signed number. > 0. */
+ offsetT rlx_forward;
+ /* Backward reach. Signed number. < 0. */
+ offsetT rlx_backward;
+
+ /* Bytes length of this address. */
+ unsigned char rlx_length;
+
+ /* Next longer relax-state. 0 means there is no 'next' relax-state. */
+ relax_substateT rlx_more;
+};
+
+typedef struct relax_type relax_typeS;
+
+/* main program "as.c" (command arguments etc) */
+
+COMMON unsigned char flag_no_comments; /* -f */
+COMMON unsigned char flag_debug; /* -D */
+COMMON unsigned char flag_signed_overflow_ok; /* -J */
+#ifndef WORKING_DOT_WORD
+COMMON unsigned char flag_warn_displacement; /* -K */
+#endif
+
+/* True if local symbols should be retained. */
+COMMON int flag_keep_locals; /* -L */
+
+/* True if we are assembling in MRI mode. */
+COMMON int flag_mri;
+
+/* Should the data section be made read-only and appended to the text
+ section? */
+COMMON unsigned char flag_readonly_data_in_text; /* -R */
+
+/* True if warnings should be inhibited. */
+COMMON int flag_no_warnings; /* -W */
+
+/* True if warnings count as errors. */
+COMMON int flag_fatal_warnings; /* --fatal-warnings */
+
+/* True if we should attempt to generate output even if non-fatal errors
+ are detected. */
+COMMON unsigned char flag_always_generate_output; /* -Z */
+
+/* This is true if the assembler should output time and space usage. */
+COMMON unsigned char flag_print_statistics;
+
+/* True if local absolute symbols are to be stripped. */
+COMMON int flag_strip_local_absolute;
+
+/* True if we should generate a traditional format object file. */
+COMMON int flag_traditional_format;
+
+/* TRUE if .note.GNU-stack section with SEC_CODE should be created */
+COMMON int flag_execstack;
+
+/* TRUE if .note.GNU-stack section with SEC_CODE should be created */
+COMMON int flag_noexecstack;
+
+/* name of emitted object file */
+COMMON char *out_file_name;
+
+/* name of file defining extensions to the basic instruction set */
+COMMON char *insttbl_file_name;
+
+/* TRUE if we need a second pass. */
+COMMON int need_pass_2;
+
+/* TRUE if we should do no relaxing, and
+ leave lots of padding. */
+COMMON int linkrelax;
+
+/* TRUE if we should produce a listing. */
+extern int listing;
+
+/* Type of debugging information we should generate. We currently support
+ stabs, ECOFF, and DWARF2.
+
+ NOTE! This means debug information about the assembly source code itself
+ and _not_ about possible debug information from a high-level language.
+ This is especially relevant to DWARF2, since the compiler may emit line
+ number directives that the assembler resolves. */
+
+enum debug_info_type {
+ DEBUG_UNSPECIFIED,
+ DEBUG_NONE,
+ DEBUG_STABS,
+ DEBUG_ECOFF,
+ DEBUG_DWARF,
+ DEBUG_DWARF2
+};
+
+extern enum debug_info_type debug_type;
+extern int use_gnu_debug_info_extensions;
+
+/* Maximum level of macro nesting. */
+extern int max_macro_nest;
+
+/* Verbosity level. */
+extern int verbose;
+
+/* Obstack chunk size. Keep large for efficient space use, make small to
+ increase malloc calls for monitoring memory allocation. */
+extern int chunksize;
+
+struct _pseudo_type {
+ /* assembler mnemonic, lower case, no '.' */
+ const char *poc_name;
+ /* Do the work */
+ void (*poc_handler) (int);
+ /* Value to pass to handler */
+ int poc_val;
+};
+
+typedef struct _pseudo_type pseudo_typeS;
+
+/* Prefer varargs for non-ANSI compiler, since some will barf if the
+ ellipsis definition is used with a no-arguments declaration. */
+#if defined (HAVE_VARARGS_H) && !defined (__STDC__)
+#undef HAVE_STDARG_H
+#endif
+
+#if defined (HAVE_STDARG_H)
+#define USE_STDARG
+#endif
+#if !defined (USE_STDARG) && defined (HAVE_VARARGS_H)
+#define USE_VARARGS
+#endif
+
+#ifdef USE_STDARG
+#if (__GNUC__ >= 2) && !defined(VMS)
+/* for use with -Wformat */
+
+#if __GNUC__ == 2 && __GNUC_MINOR__ < 6
+/* Support for double underscores in attribute names was added in gcc
+ 2.6, so avoid them if we are using an earlier version. */
+#define __printf__ printf
+#define __format__ format
+#endif
+
+#define PRINTF_LIKE(FCN) \
+ void FCN (const char *format, ...) \
+ __attribute__ ((__format__ (__printf__, 1, 2)))
+#define PRINTF_WHERE_LIKE(FCN) \
+ void FCN (char *file, unsigned int line, const char *format, ...) \
+ __attribute__ ((__format__ (__printf__, 3, 4)))
+
+#else /* __GNUC__ < 2 || defined(VMS) */
+
+#define PRINTF_LIKE(FCN) void FCN (const char *format, ...)
+#define PRINTF_WHERE_LIKE(FCN) void FCN (char *file, \
+ unsigned int line, \
+ const char *format, ...)
+
+#endif /* __GNUC__ < 2 || defined(VMS) */
+
+#else /* ! USE_STDARG */
+
+#define PRINTF_LIKE(FCN) void FCN ()
+#define PRINTF_WHERE_LIKE(FCN) void FCN ()
+
+#endif /* ! USE_STDARG */
+
+PRINTF_LIKE (as_bad);
+PRINTF_LIKE (as_fatal) ATTRIBUTE_NORETURN;
+PRINTF_LIKE (as_tsktsk);
+PRINTF_LIKE (as_warn);
+PRINTF_WHERE_LIKE (as_bad_where);
+PRINTF_WHERE_LIKE (as_warn_where);
+
+void as_assert (const char *, int, const char *);
+void as_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
+
+void fprint_value (FILE *file, addressT value);
+void sprint_value (char *buf, addressT value);
+
+int had_errors (void);
+int had_warnings (void);
+
+void print_version_id (void);
+char *app_push (void);
+char *atof_ieee (char *str, int what_kind, LITTLENUM_TYPE * words);
+char *input_scrub_include_file (char *filename, char *position);
+extern void input_scrub_insert_line (const char *line);
+extern void input_scrub_insert_file (char *path);
+char *input_scrub_new_file (char *filename);
+char *input_scrub_next_buffer (char **bufp);
+int do_scrub_chars (int (*get) (char *, int), char *to, int tolen);
+int gen_to_words (LITTLENUM_TYPE * words, int precision,
+ long exponent_bits);
+int had_err (void);
+int ignore_input (void);
+void cond_finish_check (int);
+void cond_exit_macro (int);
+int seen_at_least_1_file (void);
+void app_pop (char *arg);
+void as_howmuch (FILE * stream);
+void as_perror (const char *gripe, const char *filename);
+void as_where (char **namep, unsigned int *linep);
+void bump_line_counters (void);
+void do_scrub_begin (int);
+void input_scrub_begin (void);
+void input_scrub_close (void);
+void input_scrub_end (void);
+int new_logical_line (char *fname, int line_number);
+void subsegs_begin (void);
+void subseg_change (segT seg, int subseg);
+segT subseg_new (const char *name, subsegT subseg);
+segT subseg_force_new (const char *name, subsegT subseg);
+void subseg_set (segT seg, subsegT subseg);
+#ifdef BFD_ASSEMBLER
+segT subseg_get (const char *, int);
+#endif
+int subseg_text_p (segT);
+
+void start_dependencies (char *);
+void register_dependency (char *);
+void print_dependencies (void);
+
+struct expressionS;
+struct fix;
+typedef struct symbol symbolS;
+struct relax_type;
+typedef struct frag fragS;
+
+#ifdef BFD_ASSEMBLER
+/* literal.c */
+valueT add_to_literal_pool (symbolS *, valueT, segT, int);
+#endif
+
+int check_eh_frame (struct expressionS *, unsigned int *);
+int eh_frame_estimate_size_before_relax (fragS *);
+int eh_frame_relax_frag (fragS *);
+void eh_frame_convert_frag (fragS *);
+
+int generic_force_reloc (struct fix *);
+
+#include "expr.h" /* Before targ-*.h */
+
+/* this one starts the chain of target dependant headers */
+#include "targ-env.h"
+
+#ifdef OBJ_MAYBE_ELF
+#define IS_ELF (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+#else
+#ifdef OBJ_ELF
+#define IS_ELF 1
+#else
+#define IS_ELF 0
+#endif
+#endif
+
+#include "write.h"
+#include "frags.h"
+#include "hash.h"
+#include "read.h"
+#include "symbols.h"
+
+#include "tc.h"
+#include "obj.h"
+
+#ifdef USE_EMULATIONS
+#include "emul.h"
+#endif
+#include "listing.h"
+
+#ifdef TC_M68K
+/* True if we are assembling in m68k MRI mode. */
+COMMON int flag_m68k_mri;
+#else
+#define flag_m68k_mri 0
+#endif
+
+#ifdef WARN_COMMENTS
+COMMON int warn_comment;
+COMMON unsigned int found_comment;
+COMMON char *found_comment_file;
+#endif
+
+#ifndef NUMBERS_WITH_SUFFIX
+#define NUMBERS_WITH_SUFFIX 0
+#endif
+
+#ifndef LOCAL_LABELS_DOLLAR
+#define LOCAL_LABELS_DOLLAR 0
+#endif
+
+#ifndef LOCAL_LABELS_FB
+#define LOCAL_LABELS_FB 0
+#endif
+
+#ifndef LABELS_WITHOUT_COLONS
+#define LABELS_WITHOUT_COLONS 0
+#endif
+
+#ifndef NO_PSEUDO_DOT
+#define NO_PSEUDO_DOT 0
+#endif
+
+#ifndef TEXT_SECTION_NAME
+#define TEXT_SECTION_NAME ".text"
+#define DATA_SECTION_NAME ".data"
+#define BSS_SECTION_NAME ".bss"
+#endif
+
+#ifndef OCTETS_PER_BYTE_POWER
+#define OCTETS_PER_BYTE_POWER 0
+#endif
+#ifndef OCTETS_PER_BYTE
+#define OCTETS_PER_BYTE (1<<OCTETS_PER_BYTE_POWER)
+#endif
+#if OCTETS_PER_BYTE != (1<<OCTETS_PER_BYTE_POWER)
+ #error "Octets per byte conflicts with its power-of-two definition!"
+#endif
+
+#endif /* GAS */
diff --git a/x/binutils/gas/asintl.h b/x/binutils/gas/asintl.h
new file mode 100644
index 0000000..41bb218
--- /dev/null
+++ b/x/binutils/gas/asintl.h
@@ -0,0 +1,43 @@
+/* asintl.h - gas-specific header for gettext code.
+ Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
+
+ Written by Tom Tromey <tromey@cygnus.com>
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(String) gettext (String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+# else
+# define N_(String) (String)
+# endif
+#else
+# define gettext(Msgid) (Msgid)
+# define dgettext(Domainname, Msgid) (Msgid)
+# define dcgettext(Domainname, Msgid, Category) (Msgid)
+# define textdomain(Domainname) while (0) /* nothing */
+# define bindtextdomain(Domainname, Dirname) while (0) /* nothing */
+# define _(String) (String)
+# define N_(String) (String)
+#endif
diff --git a/x/binutils/gas/atof-generic.c b/x/binutils/gas/atof-generic.c
new file mode 100644
index 0000000..8c599b5
--- /dev/null
+++ b/x/binutils/gas/atof-generic.c
@@ -0,0 +1,630 @@
+/* atof_generic.c - turn a string of digits into a Flonum
+ Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <string.h>
+
+#include "as.h"
+#include "safe-ctype.h"
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+#ifndef TRUE
+#define TRUE (1)
+#endif
+
+#ifdef TRACE
+static void flonum_print (const FLONUM_TYPE *);
+#endif
+
+#define ASSUME_DECIMAL_MARK_IS_DOT
+
+/***********************************************************************\
+ * *
+ * Given a string of decimal digits , with optional decimal *
+ * mark and optional decimal exponent (place value) of the *
+ * lowest_order decimal digit: produce a floating point *
+ * number. The number is 'generic' floating point: our *
+ * caller will encode it for a specific machine architecture. *
+ * *
+ * Assumptions *
+ * uses base (radix) 2 *
+ * this machine uses 2's complement binary integers *
+ * target flonums use " " " " *
+ * target flonums exponents fit in a long *
+ * *
+ \***********************************************************************/
+
+/*
+
+ Syntax:
+
+ <flonum> ::= <optional-sign> <decimal-number> <optional-exponent>
+ <optional-sign> ::= '+' | '-' | {empty}
+ <decimal-number> ::= <integer>
+ | <integer> <radix-character>
+ | <integer> <radix-character> <integer>
+ | <radix-character> <integer>
+
+ <optional-exponent> ::= {empty}
+ | <exponent-character> <optional-sign> <integer>
+
+ <integer> ::= <digit> | <digit> <integer>
+ <digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
+ <exponent-character> ::= {one character from "string_of_decimal_exponent_marks"}
+ <radix-character> ::= {one character from "string_of_decimal_marks"}
+
+ */
+
+int
+atof_generic (/* return pointer to just AFTER number we read. */
+ char **address_of_string_pointer,
+ /* At most one per number. */
+ const char *string_of_decimal_marks,
+ const char *string_of_decimal_exponent_marks,
+ FLONUM_TYPE *address_of_generic_floating_point_number)
+{
+ int return_value; /* 0 means OK. */
+ char *first_digit;
+ unsigned int number_of_digits_before_decimal;
+ unsigned int number_of_digits_after_decimal;
+ long decimal_exponent;
+ unsigned int number_of_digits_available;
+ char digits_sign_char;
+
+ /*
+ * Scan the input string, abstracting (1)digits (2)decimal mark (3) exponent.
+ * It would be simpler to modify the string, but we don't; just to be nice
+ * to caller.
+ * We need to know how many digits we have, so we can allocate space for
+ * the digits' value.
+ */
+
+ char *p;
+ char c;
+ int seen_significant_digit;
+
+#ifdef ASSUME_DECIMAL_MARK_IS_DOT
+ assert (string_of_decimal_marks[0] == '.'
+ && string_of_decimal_marks[1] == 0);
+#define IS_DECIMAL_MARK(c) ((c) == '.')
+#else
+#define IS_DECIMAL_MARK(c) (0 != strchr (string_of_decimal_marks, (c)))
+#endif
+
+ first_digit = *address_of_string_pointer;
+ c = *first_digit;
+
+ if (c == '-' || c == '+')
+ {
+ digits_sign_char = c;
+ first_digit++;
+ }
+ else
+ digits_sign_char = '+';
+
+ switch (first_digit[0])
+ {
+ case 'n':
+ case 'N':
+ if (!strncasecmp ("nan", first_digit, 3))
+ {
+ address_of_generic_floating_point_number->sign = 0;
+ address_of_generic_floating_point_number->exponent = 0;
+ address_of_generic_floating_point_number->leader =
+ address_of_generic_floating_point_number->low;
+ *address_of_string_pointer = first_digit + 3;
+ return 0;
+ }
+ break;
+
+ case 'i':
+ case 'I':
+ if (!strncasecmp ("inf", first_digit, 3))
+ {
+ address_of_generic_floating_point_number->sign =
+ digits_sign_char == '+' ? 'P' : 'N';
+ address_of_generic_floating_point_number->exponent = 0;
+ address_of_generic_floating_point_number->leader =
+ address_of_generic_floating_point_number->low;
+
+ first_digit += 3;
+ if (!strncasecmp ("inity", first_digit, 5))
+ first_digit += 5;
+
+ *address_of_string_pointer = first_digit;
+
+ return 0;
+ }
+ break;
+ }
+
+ number_of_digits_before_decimal = 0;
+ number_of_digits_after_decimal = 0;
+ decimal_exponent = 0;
+ seen_significant_digit = 0;
+ for (p = first_digit;
+ (((c = *p) != '\0')
+ && (!c || !IS_DECIMAL_MARK (c))
+ && (!c || !strchr (string_of_decimal_exponent_marks, c)));
+ p++)
+ {
+ if (ISDIGIT (c))
+ {
+ if (seen_significant_digit || c > '0')
+ {
+ ++number_of_digits_before_decimal;
+ seen_significant_digit = 1;
+ }
+ else
+ {
+ first_digit++;
+ }
+ }
+ else
+ {
+ break; /* p -> char after pre-decimal digits. */
+ }
+ } /* For each digit before decimal mark. */
+
+#ifndef OLD_FLOAT_READS
+ /* Ignore trailing 0's after the decimal point. The original code here
+ * (ifdef'd out) does not do this, and numbers like
+ * 4.29496729600000000000e+09 (2**31)
+ * come out inexact for some reason related to length of the digit
+ * string.
+ */
+ if (c && IS_DECIMAL_MARK (c))
+ {
+ unsigned int zeros = 0; /* Length of current string of zeros */
+
+ for (p++; (c = *p) && ISDIGIT (c); p++)
+ {
+ if (c == '0')
+ {
+ zeros++;
+ }
+ else
+ {
+ number_of_digits_after_decimal += 1 + zeros;
+ zeros = 0;
+ }
+ }
+ }
+#else
+ if (c && IS_DECIMAL_MARK (c))
+ {
+ for (p++;
+ (((c = *p) != '\0')
+ && (!c || !strchr (string_of_decimal_exponent_marks, c)));
+ p++)
+ {
+ if (ISDIGIT (c))
+ {
+ /* This may be retracted below. */
+ number_of_digits_after_decimal++;
+
+ if ( /* seen_significant_digit || */ c > '0')
+ {
+ seen_significant_digit = TRUE;
+ }
+ }
+ else
+ {
+ if (!seen_significant_digit)
+ {
+ number_of_digits_after_decimal = 0;
+ }
+ break;
+ }
+ } /* For each digit after decimal mark. */
+ }
+
+ while (number_of_digits_after_decimal
+ && first_digit[number_of_digits_before_decimal
+ + number_of_digits_after_decimal] == '0')
+ --number_of_digits_after_decimal;
+#endif
+
+ if (flag_m68k_mri)
+ {
+ while (c == '_')
+ c = *++p;
+ }
+ if (c && strchr (string_of_decimal_exponent_marks, c))
+ {
+ char digits_exponent_sign_char;
+
+ c = *++p;
+ if (flag_m68k_mri)
+ {
+ while (c == '_')
+ c = *++p;
+ }
+ if (c && strchr ("+-", c))
+ {
+ digits_exponent_sign_char = c;
+ c = *++p;
+ }
+ else
+ {
+ digits_exponent_sign_char = '+';
+ }
+
+ for (; (c); c = *++p)
+ {
+ if (ISDIGIT (c))
+ {
+ decimal_exponent = decimal_exponent * 10 + c - '0';
+ /*
+ * BUG! If we overflow here, we lose!
+ */
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (digits_exponent_sign_char == '-')
+ {
+ decimal_exponent = -decimal_exponent;
+ }
+ }
+
+ *address_of_string_pointer = p;
+
+ number_of_digits_available =
+ number_of_digits_before_decimal + number_of_digits_after_decimal;
+ return_value = 0;
+ if (number_of_digits_available == 0)
+ {
+ address_of_generic_floating_point_number->exponent = 0; /* Not strictly necessary */
+ address_of_generic_floating_point_number->leader
+ = -1 + address_of_generic_floating_point_number->low;
+ address_of_generic_floating_point_number->sign = digits_sign_char;
+ /* We have just concocted (+/-)0.0E0 */
+
+ }
+ else
+ {
+ int count; /* Number of useful digits left to scan. */
+
+ LITTLENUM_TYPE *digits_binary_low;
+ unsigned int precision;
+ unsigned int maximum_useful_digits;
+ unsigned int number_of_digits_to_use;
+ unsigned int more_than_enough_bits_for_digits;
+ unsigned int more_than_enough_littlenums_for_digits;
+ unsigned int size_of_digits_in_littlenums;
+ unsigned int size_of_digits_in_chars;
+ FLONUM_TYPE power_of_10_flonum;
+ FLONUM_TYPE digits_flonum;
+
+ precision = (address_of_generic_floating_point_number->high
+ - address_of_generic_floating_point_number->low
+ + 1); /* Number of destination littlenums. */
+
+ /* Includes guard bits (two littlenums worth) */
+#if 0 /* The integer version below is very close, and it doesn't
+ require floating point support (which is currently buggy on
+ the Alpha). */
+ maximum_useful_digits = (((double) (precision - 2))
+ * ((double) (LITTLENUM_NUMBER_OF_BITS))
+ / (LOG_TO_BASE_2_OF_10))
+ + 2; /* 2 :: guard digits. */
+#else
+ maximum_useful_digits = (((precision - 2))
+ * ( (LITTLENUM_NUMBER_OF_BITS))
+ * 1000000 / 3321928)
+ + 2; /* 2 :: guard digits. */
+#endif
+
+ if (number_of_digits_available > maximum_useful_digits)
+ {
+ number_of_digits_to_use = maximum_useful_digits;
+ }
+ else
+ {
+ number_of_digits_to_use = number_of_digits_available;
+ }
+
+ /* Cast these to SIGNED LONG first, otherwise, on systems with
+ LONG wider than INT (such as Alpha OSF/1), unsignedness may
+ cause unexpected results. */
+ decimal_exponent += ((long) number_of_digits_before_decimal
+ - (long) number_of_digits_to_use);
+
+#if 0
+ more_than_enough_bits_for_digits
+ = ((((double) number_of_digits_to_use) * LOG_TO_BASE_2_OF_10) + 1);
+#else
+ more_than_enough_bits_for_digits
+ = (number_of_digits_to_use * 3321928 / 1000000 + 1);
+#endif
+
+ more_than_enough_littlenums_for_digits
+ = (more_than_enough_bits_for_digits
+ / LITTLENUM_NUMBER_OF_BITS)
+ + 2;
+
+ /* Compute (digits) part. In "12.34E56" this is the "1234" part.
+ Arithmetic is exact here. If no digits are supplied then this
+ part is a 0 valued binary integer. Allocate room to build up
+ the binary number as littlenums. We want this memory to
+ disappear when we leave this function. Assume no alignment
+ problems => (room for n objects) == n * (room for 1
+ object). */
+
+ size_of_digits_in_littlenums = more_than_enough_littlenums_for_digits;
+ size_of_digits_in_chars = size_of_digits_in_littlenums
+ * sizeof (LITTLENUM_TYPE);
+
+ digits_binary_low = (LITTLENUM_TYPE *)
+ alloca (size_of_digits_in_chars);
+
+ memset ((char *) digits_binary_low, '\0', size_of_digits_in_chars);
+
+ /* Digits_binary_low[] is allocated and zeroed. */
+
+ /*
+ * Parse the decimal digits as if * digits_low was in the units position.
+ * Emit a binary number into digits_binary_low[].
+ *
+ * Use a large-precision version of:
+ * (((1st-digit) * 10 + 2nd-digit) * 10 + 3rd-digit ...) * 10 + last-digit
+ */
+
+ for (p = first_digit, count = number_of_digits_to_use; count; p++, --count)
+ {
+ c = *p;
+ if (ISDIGIT (c))
+ {
+ /*
+ * Multiply by 10. Assume can never overflow.
+ * Add this digit to digits_binary_low[].
+ */
+
+ long carry;
+ LITTLENUM_TYPE *littlenum_pointer;
+ LITTLENUM_TYPE *littlenum_limit;
+
+ littlenum_limit = digits_binary_low
+ + more_than_enough_littlenums_for_digits
+ - 1;
+
+ carry = c - '0'; /* char -> binary */
+
+ for (littlenum_pointer = digits_binary_low;
+ littlenum_pointer <= littlenum_limit;
+ littlenum_pointer++)
+ {
+ long work;
+
+ work = carry + 10 * (long) (*littlenum_pointer);
+ *littlenum_pointer = work & LITTLENUM_MASK;
+ carry = work >> LITTLENUM_NUMBER_OF_BITS;
+ }
+
+ if (carry != 0)
+ {
+ /*
+ * We have a GROSS internal error.
+ * This should never happen.
+ */
+ as_fatal (_("failed sanity check"));
+ }
+ }
+ else
+ {
+ ++count; /* '.' doesn't alter digits used count. */
+ }
+ }
+
+ /*
+ * Digits_binary_low[] properly encodes the value of the digits.
+ * Forget about any high-order littlenums that are 0.
+ */
+ while (digits_binary_low[size_of_digits_in_littlenums - 1] == 0
+ && size_of_digits_in_littlenums >= 2)
+ size_of_digits_in_littlenums--;
+
+ digits_flonum.low = digits_binary_low;
+ digits_flonum.high = digits_binary_low + size_of_digits_in_littlenums - 1;
+ digits_flonum.leader = digits_flonum.high;
+ digits_flonum.exponent = 0;
+ /*
+ * The value of digits_flonum . sign should not be important.
+ * We have already decided the output's sign.
+ * We trust that the sign won't influence the other parts of the number!
+ * So we give it a value for these reasons:
+ * (1) courtesy to humans reading/debugging
+ * these numbers so they don't get excited about strange values
+ * (2) in future there may be more meaning attached to sign,
+ * and what was
+ * harmless noise may become disruptive, ill-conditioned (or worse)
+ * input.
+ */
+ digits_flonum.sign = '+';
+
+ {
+ /*
+ * Compute the mantssa (& exponent) of the power of 10.
+ * If successful, then multiply the power of 10 by the digits
+ * giving return_binary_mantissa and return_binary_exponent.
+ */
+
+ LITTLENUM_TYPE *power_binary_low;
+ int decimal_exponent_is_negative;
+ /* This refers to the "-56" in "12.34E-56". */
+ /* FALSE: decimal_exponent is positive (or 0) */
+ /* TRUE: decimal_exponent is negative */
+ FLONUM_TYPE temporary_flonum;
+ LITTLENUM_TYPE *temporary_binary_low;
+ unsigned int size_of_power_in_littlenums;
+ unsigned int size_of_power_in_chars;
+
+ size_of_power_in_littlenums = precision;
+ /* Precision has a built-in fudge factor so we get a few guard bits. */
+
+ decimal_exponent_is_negative = decimal_exponent < 0;
+ if (decimal_exponent_is_negative)
+ {
+ decimal_exponent = -decimal_exponent;
+ }
+
+ /* From now on: the decimal exponent is > 0. Its sign is separate. */
+
+ size_of_power_in_chars = size_of_power_in_littlenums
+ * sizeof (LITTLENUM_TYPE) + 2;
+
+ power_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars);
+ temporary_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars);
+ memset ((char *) power_binary_low, '\0', size_of_power_in_chars);
+ *power_binary_low = 1;
+ power_of_10_flonum.exponent = 0;
+ power_of_10_flonum.low = power_binary_low;
+ power_of_10_flonum.leader = power_binary_low;
+ power_of_10_flonum.high = power_binary_low + size_of_power_in_littlenums - 1;
+ power_of_10_flonum.sign = '+';
+ temporary_flonum.low = temporary_binary_low;
+ temporary_flonum.high = temporary_binary_low + size_of_power_in_littlenums - 1;
+ /*
+ * (power) == 1.
+ * Space for temporary_flonum allocated.
+ */
+
+ /*
+ * ...
+ *
+ * WHILE more bits
+ * DO find next bit (with place value)
+ * multiply into power mantissa
+ * OD
+ */
+ {
+ int place_number_limit;
+ /* Any 10^(2^n) whose "n" exceeds this */
+ /* value will fall off the end of */
+ /* flonum_XXXX_powers_of_ten[]. */
+ int place_number;
+ const FLONUM_TYPE *multiplicand; /* -> 10^(2^n) */
+
+ place_number_limit = table_size_of_flonum_powers_of_ten;
+
+ multiplicand = (decimal_exponent_is_negative
+ ? flonum_negative_powers_of_ten
+ : flonum_positive_powers_of_ten);
+
+ for (place_number = 1;/* Place value of this bit of exponent. */
+ decimal_exponent;/* Quit when no more 1 bits in exponent. */
+ decimal_exponent >>= 1, place_number++)
+ {
+ if (decimal_exponent & 1)
+ {
+ if (place_number > place_number_limit)
+ {
+ /* The decimal exponent has a magnitude so great
+ that our tables can't help us fragment it.
+ Although this routine is in error because it
+ can't imagine a number that big, signal an
+ error as if it is the user's fault for
+ presenting such a big number. */
+ return_value = ERROR_EXPONENT_OVERFLOW;
+ /* quit out of loop gracefully */
+ decimal_exponent = 0;
+ }
+ else
+ {
+#ifdef TRACE
+ printf ("before multiply, place_number = %d., power_of_10_flonum:\n",
+ place_number);
+
+ flonum_print (&power_of_10_flonum);
+ (void) putchar ('\n');
+#endif
+#ifdef TRACE
+ printf ("multiplier:\n");
+ flonum_print (multiplicand + place_number);
+ (void) putchar ('\n');
+#endif
+ flonum_multip (multiplicand + place_number,
+ &power_of_10_flonum, &temporary_flonum);
+#ifdef TRACE
+ printf ("after multiply:\n");
+ flonum_print (&temporary_flonum);
+ (void) putchar ('\n');
+#endif
+ flonum_copy (&temporary_flonum, &power_of_10_flonum);
+#ifdef TRACE
+ printf ("after copy:\n");
+ flonum_print (&power_of_10_flonum);
+ (void) putchar ('\n');
+#endif
+ } /* If this bit of decimal_exponent was computable.*/
+ } /* If this bit of decimal_exponent was set. */
+ } /* For each bit of binary representation of exponent */
+#ifdef TRACE
+ printf ("after computing power_of_10_flonum:\n");
+ flonum_print (&power_of_10_flonum);
+ (void) putchar ('\n');
+#endif
+ }
+
+ }
+
+ /*
+ * power_of_10_flonum is power of ten in binary (mantissa) , (exponent).
+ * It may be the number 1, in which case we don't NEED to multiply.
+ *
+ * Multiply (decimal digits) by power_of_10_flonum.
+ */
+
+ flonum_multip (&power_of_10_flonum, &digits_flonum, address_of_generic_floating_point_number);
+ /* Assert sign of the number we made is '+'. */
+ address_of_generic_floating_point_number->sign = digits_sign_char;
+
+ }
+ return return_value;
+}
+
+#ifdef TRACE
+static void
+flonum_print (f)
+ const FLONUM_TYPE *f;
+{
+ LITTLENUM_TYPE *lp;
+ char littlenum_format[10];
+ sprintf (littlenum_format, " %%0%dx", sizeof (LITTLENUM_TYPE) * 2);
+#define print_littlenum(LP) (printf (littlenum_format, LP))
+ printf ("flonum @%p %c e%ld", f, f->sign, f->exponent);
+ if (f->low < f->high)
+ for (lp = f->high; lp >= f->low; lp--)
+ print_littlenum (*lp);
+ else
+ for (lp = f->low; lp <= f->high; lp++)
+ print_littlenum (*lp);
+ printf ("\n");
+ fflush (stdout);
+}
+#endif
+
+/* end of atof_generic.c */
diff --git a/x/binutils/gas/bignum-copy.c b/x/binutils/gas/bignum-copy.c
new file mode 100644
index 0000000..5697472
--- /dev/null
+++ b/x/binutils/gas/bignum-copy.c
@@ -0,0 +1,80 @@
+/* bignum_copy.c - copy a bignum
+ Copyright 1987, 1990, 1991, 1992, 1993, 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "as.h"
+
+/*
+ * bignum_copy ()
+ *
+ * Copy a bignum from in to out.
+ * If the output is shorter than the input, copy lower-order littlenums.
+ * Return 0 or the number of significant littlenums dropped.
+ * Assumes littlenum arrays are densely packed: no unused chars between
+ * the littlenums. Uses memcpy() to move littlenums, and wants to
+ * know length (in chars) of the input bignum.
+ */
+
+/* void */
+int
+bignum_copy (register LITTLENUM_TYPE *in,
+ register int in_length, /* in sizeof(littlenum)s */
+ register LITTLENUM_TYPE *out,
+ register int out_length /* in sizeof(littlenum)s */)
+{
+ int significant_littlenums_dropped;
+
+ if (out_length < in_length)
+ {
+ LITTLENUM_TYPE *p; /* -> most significant (non-zero) input
+ littlenum. */
+
+ memcpy ((void *) out, (void *) in,
+ (unsigned int) out_length << LITTLENUM_SHIFT);
+ for (p = in + in_length - 1; p >= in; --p)
+ {
+ if (*p)
+ break;
+ }
+ significant_littlenums_dropped = p - in - in_length + 1;
+
+ if (significant_littlenums_dropped < 0)
+ {
+ significant_littlenums_dropped = 0;
+ }
+ }
+ else
+ {
+ memcpy ((char *) out, (char *) in,
+ (unsigned int) in_length << LITTLENUM_SHIFT);
+
+ if (out_length > in_length)
+ {
+ memset ((char *) (out + in_length),
+ '\0',
+ (unsigned int) (out_length - in_length) << LITTLENUM_SHIFT);
+ }
+
+ significant_littlenums_dropped = 0;
+ }
+
+ return (significant_littlenums_dropped);
+} /* bignum_copy() */
+
+/* end of bignum-copy.c */
diff --git a/x/binutils/gas/bignum.h b/x/binutils/gas/bignum.h
new file mode 100644
index 0000000..fbb77ff
--- /dev/null
+++ b/x/binutils/gas/bignum.h
@@ -0,0 +1,52 @@
+/* bignum.h-arbitrary precision integers
+ Copyright 1987, 1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/***********************************************************************\
+ * *
+ * Arbitrary-precision integer arithmetic. *
+ * For speed, we work in groups of bits, even though this *
+ * complicates algorithms. *
+ * Each group of bits is called a 'littlenum'. *
+ * A bunch of littlenums representing a (possibly large) *
+ * integer is called a 'bignum'. *
+ * Bignums are >= 0. *
+ * *
+ \***********************************************************************/
+
+#define LITTLENUM_NUMBER_OF_BITS (16)
+#define LITTLENUM_RADIX (1 << LITTLENUM_NUMBER_OF_BITS)
+#define LITTLENUM_MASK (0xFFFF)
+#define LITTLENUM_SHIFT (1)
+#define CHARS_PER_LITTLENUM (1 << LITTLENUM_SHIFT)
+#ifndef BITS_PER_CHAR
+#define BITS_PER_CHAR (8)
+#endif
+
+typedef unsigned short LITTLENUM_TYPE;
+
+/* JF truncated this to get around a problem with GCC */
+#define LOG_TO_BASE_2_OF_10 (3.3219280948873623478703194294893901758651)
+/* WARNING: I haven't checked that the trailing digits are correct! */
+
+/* lengths are in sizeof(littlenum)s */
+
+int bignum_copy (LITTLENUM_TYPE * in, int in_length,
+ LITTLENUM_TYPE * out, int out_length);
+
+/* end of bignum.h */
diff --git a/x/binutils/gas/bit_fix.h b/x/binutils/gas/bit_fix.h
new file mode 100644
index 0000000..1676d2c
--- /dev/null
+++ b/x/binutils/gas/bit_fix.h
@@ -0,0 +1,48 @@
+/* bit_fix.h
+ Copyright 1987, 1992, 2000, 2001 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* The bit_fix was implemented to support machines that need variables
+ to be inserted in bitfields other than 1, 2 and 4 bytes.
+ Furthermore it gives us a possibility to mask in bits in the symbol
+ when it's fixed in the objectcode and check the symbols limits.
+
+ The or-mask is used to set the huffman bits in displacements for the
+ ns32k port.
+ The acbi, addqi, movqi, cmpqi instruction requires an assembler that
+ can handle bitfields. Ie. handle an expression, evaluate it and insert
+ the result in some bitfield. (eg: 5 bits in a short field of an opcode)
+ */
+
+#ifndef __bit_fix_h__
+#define __bit_fix_h__
+
+struct bit_fix {
+ int fx_bit_size; /* Length of bitfield */
+ int fx_bit_offset; /* Bit offset to bitfield */
+ long fx_bit_base; /* Where do we apply the bitfix.
+ If this is zero, default is assumed. */
+ long fx_bit_base_adj; /* Adjustment of base */
+ long fx_bit_max; /* Signextended max for bitfield */
+ long fx_bit_min; /* Signextended min for bitfield */
+ long fx_bit_add; /* Or mask, used for huffman prefix */
+};
+typedef struct bit_fix bit_fixS;
+
+#endif /* __bit_fix_h__ */
diff --git a/x/binutils/gas/cgen.c b/x/binutils/gas/cgen.c
new file mode 100644
index 0000000..5ce7f4c
--- /dev/null
+++ b/x/binutils/gas/cgen.c
@@ -0,0 +1,730 @@
+/* GAS interface for targets using CGEN: Cpu tools GENerator.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <setjmp.h>
+#include "ansidecl.h"
+#include "libiberty.h"
+#include "bfd.h"
+#include "symcat.h"
+#include "cgen-desc.h"
+#include "as.h"
+#include "subsegs.h"
+#include "cgen.h"
+#include "dwarf2dbg.h"
+
+static void queue_fixup (int, int, expressionS *);
+
+/* Opcode table descriptor, must be set by md_begin. */
+
+CGEN_CPU_DESC gas_cgen_cpu_desc;
+
+/* Callback to insert a register into the symbol table.
+ A target may choose to let GAS parse the registers.
+ ??? Not currently used. */
+
+void
+cgen_asm_record_register (name, number)
+ char *name;
+ int number;
+{
+ /* Use symbol_create here instead of symbol_new so we don't try to
+ output registers into the object file's symbol table. */
+ symbol_table_insert (symbol_create (name, reg_section,
+ number, &zero_address_frag));
+}
+
+/* We need to keep a list of fixups. We can't simply generate them as
+ we go, because that would require us to first create the frag, and
+ that would screw up references to ``.''.
+
+ This is used by cpu's with simple operands. It keeps knowledge of what
+ an `expressionS' is and what a `fixup' is out of CGEN which for the time
+ being is preferable.
+
+ OPINDEX is the index in the operand table.
+ OPINFO is something the caller chooses to help in reloc determination. */
+
+struct fixup
+{
+ int opindex;
+ int opinfo;
+ expressionS exp;
+};
+
+static struct fixup fixups[GAS_CGEN_MAX_FIXUPS];
+static int num_fixups;
+
+/* Prepare to parse an instruction.
+ ??? May wish to make this static and delete calls in md_assemble. */
+
+void
+gas_cgen_init_parse ()
+{
+ num_fixups = 0;
+}
+
+/* Queue a fixup. */
+
+static void
+queue_fixup (opindex, opinfo, expP)
+ int opindex;
+ int opinfo;
+ expressionS * expP;
+{
+ /* We need to generate a fixup for this expression. */
+ if (num_fixups >= GAS_CGEN_MAX_FIXUPS)
+ as_fatal (_("too many fixups"));
+ fixups[num_fixups].exp = *expP;
+ fixups[num_fixups].opindex = opindex;
+ fixups[num_fixups].opinfo = opinfo;
+ ++ num_fixups;
+}
+
+/* The following functions allow fixup chains to be stored, retrieved,
+ and swapped. They are a generalization of a pre-existing scheme
+ for storing, restoring and swapping fixup chains that was used by
+ the m32r port. The functionality is essentially the same, only
+ instead of only being able to store a single fixup chain, an entire
+ array of fixup chains can be stored. It is the user's responsibility
+ to keep track of how many fixup chains have been stored and which
+ elements of the array they are in.
+
+ The algorithms used are the same as in the old scheme. Other than the
+ "array-ness" of the whole thing, the functionality is identical to the
+ old scheme.
+
+ gas_cgen_initialize_saved_fixups_array():
+ Sets num_fixups_in_chain to 0 for each element. Call this from
+ md_begin() if you plan to use these functions and you want the
+ fixup count in each element to be set to 0 initially. This is
+ not necessary, but it's included just in case. It performs
+ the same function for each element in the array of fixup chains
+ that gas_init_parse() performs for the current fixups.
+
+ gas_cgen_save_fixups (element):
+ element - element number of the array you wish to store the fixups
+ to. No mechanism is built in for tracking what element
+ was last stored to.
+
+ gas_cgen_restore_fixups (element):
+ element - element number of the array you wish to restore the fixups
+ from.
+
+ gas_cgen_swap_fixups(int element):
+ element - swap the current fixups with those in this element number.
+*/
+
+struct saved_fixups
+{
+ struct fixup fixup_chain[GAS_CGEN_MAX_FIXUPS];
+ int num_fixups_in_chain;
+};
+
+static struct saved_fixups stored_fixups[MAX_SAVED_FIXUP_CHAINS];
+
+void
+gas_cgen_initialize_saved_fixups_array ()
+{
+ int i = 0;
+
+ while (i < MAX_SAVED_FIXUP_CHAINS)
+ stored_fixups[i++].num_fixups_in_chain = 0;
+}
+
+void
+gas_cgen_save_fixups (i)
+ int i;
+{
+ if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
+ {
+ as_fatal ("index into stored_fixups[] out of bounds");
+ return;
+ }
+
+ stored_fixups[i].num_fixups_in_chain = num_fixups;
+ memcpy (stored_fixups[i].fixup_chain, fixups,
+ sizeof (fixups[0]) * num_fixups);
+ num_fixups = 0;
+}
+
+void
+gas_cgen_restore_fixups (i)
+ int i;
+{
+ if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
+ {
+ as_fatal ("index into stored_fixups[] out of bounds");
+ return;
+ }
+
+ num_fixups = stored_fixups[i].num_fixups_in_chain;
+ memcpy (fixups, stored_fixups[i].fixup_chain,
+ (sizeof (stored_fixups[i].fixup_chain[0])) * num_fixups);
+ stored_fixups[i].num_fixups_in_chain = 0;
+}
+
+void
+gas_cgen_swap_fixups (i)
+ int i;
+{
+ if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
+ {
+ as_fatal ("index into stored_fixups[] out of bounds");
+ return;
+ }
+
+ if (num_fixups == 0)
+ gas_cgen_restore_fixups (i);
+
+ else if (stored_fixups[i].num_fixups_in_chain == 0)
+ gas_cgen_save_fixups (i);
+
+ else
+ {
+ int tmp;
+ struct fixup tmp_fixup;
+
+ tmp = stored_fixups[i].num_fixups_in_chain;
+ stored_fixups[i].num_fixups_in_chain = num_fixups;
+ num_fixups = tmp;
+
+ for (tmp = GAS_CGEN_MAX_FIXUPS; tmp--;)
+ {
+ tmp_fixup = stored_fixups[i].fixup_chain [tmp];
+ stored_fixups[i].fixup_chain[tmp] = fixups [tmp];
+ fixups [tmp] = tmp_fixup;
+ }
+ }
+}
+
+/* Default routine to record a fixup.
+ This is a cover function to fix_new.
+ It exists because we record INSN with the fixup.
+
+ FRAG and WHERE are their respective arguments to fix_new_exp.
+ LENGTH is in bits.
+ OPINFO is something the caller chooses to help in reloc determination.
+
+ At this point we do not use a bfd_reloc_code_real_type for
+ operands residing in the insn, but instead just use the
+ operand index. This lets us easily handle fixups for any
+ operand type. We pick a BFD reloc type in md_apply_fix3. */
+
+fixS *
+gas_cgen_record_fixup (frag, where, insn, length, operand, opinfo, symbol, offset)
+ fragS * frag;
+ int where;
+ const CGEN_INSN * insn;
+ int length;
+ const CGEN_OPERAND * operand;
+ int opinfo;
+ symbolS * symbol;
+ offsetT offset;
+{
+ fixS *fixP;
+
+ /* It may seem strange to use operand->attrs and not insn->attrs here,
+ but it is the operand that has a pc relative relocation. */
+ fixP = fix_new (frag, where, length / 8, symbol, offset,
+ CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
+ (bfd_reloc_code_real_type)
+ ((int) BFD_RELOC_UNUSED
+ + (int) operand->type));
+ fixP->fx_cgen.insn = insn;
+ fixP->fx_cgen.opinfo = opinfo;
+
+ return fixP;
+}
+
+/* Default routine to record a fixup given an expression.
+ This is a cover function to fix_new_exp.
+ It exists because we record INSN with the fixup.
+
+ FRAG and WHERE are their respective arguments to fix_new_exp.
+ LENGTH is in bits.
+ OPINFO is something the caller chooses to help in reloc determination.
+
+ At this point we do not use a bfd_reloc_code_real_type for
+ operands residing in the insn, but instead just use the
+ operand index. This lets us easily handle fixups for any
+ operand type. We pick a BFD reloc type in md_apply_fix3. */
+
+fixS *
+gas_cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp)
+ fragS * frag;
+ int where;
+ const CGEN_INSN * insn;
+ int length;
+ const CGEN_OPERAND * operand;
+ int opinfo;
+ expressionS * exp;
+{
+ fixS *fixP;
+
+ /* It may seem strange to use operand->attrs and not insn->attrs here,
+ but it is the operand that has a pc relative relocation. */
+ fixP = fix_new_exp (frag, where, length / 8, exp,
+ CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
+ (bfd_reloc_code_real_type)
+ ((int) BFD_RELOC_UNUSED
+ + (int) operand->type));
+ fixP->fx_cgen.insn = insn;
+ fixP->fx_cgen.opinfo = opinfo;
+
+ return fixP;
+}
+
+/* Used for communication between the next two procedures. */
+static jmp_buf expr_jmp_buf;
+static int expr_jmp_buf_p;
+
+/* Callback for cgen interface. Parse the expression at *STRP.
+ The result is an error message or NULL for success (in which case
+ *STRP is advanced past the parsed text).
+ WANT is an indication of what the caller is looking for.
+ If WANT == CGEN_ASM_PARSE_INIT the caller is beginning to try to match
+ a table entry with the insn, reset the queued fixups counter.
+ An enum cgen_parse_operand_result is stored in RESULTP.
+ OPINDEX is the operand's table entry index.
+ OPINFO is something the caller chooses to help in reloc determination.
+ The resulting value is stored in VALUEP. */
+
+const char *
+gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
+ CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
+ enum cgen_parse_operand_type want;
+ const char **strP;
+ int opindex;
+ int opinfo;
+ enum cgen_parse_operand_result *resultP;
+ bfd_vma *valueP;
+{
+#ifdef __STDC__
+ /* These are volatile to survive the setjmp. */
+ char * volatile hold;
+ enum cgen_parse_operand_result * volatile resultP_1;
+#else
+ static char *hold;
+ static enum cgen_parse_operand_result *resultP_1;
+#endif
+ const char *errmsg;
+ expressionS exp;
+
+ if (want == CGEN_PARSE_OPERAND_INIT)
+ {
+ gas_cgen_init_parse ();
+ return NULL;
+ }
+
+ resultP_1 = resultP;
+ hold = input_line_pointer;
+ input_line_pointer = (char *) *strP;
+
+ /* We rely on md_operand to longjmp back to us.
+ This is done via gas_cgen_md_operand. */
+ if (setjmp (expr_jmp_buf) != 0)
+ {
+ expr_jmp_buf_p = 0;
+ input_line_pointer = (char *) hold;
+ *resultP_1 = CGEN_PARSE_OPERAND_RESULT_ERROR;
+ return _("illegal operand");
+ }
+
+ expr_jmp_buf_p = 1;
+ expression (&exp);
+ expr_jmp_buf_p = 0;
+ errmsg = NULL;
+
+ *strP = input_line_pointer;
+ input_line_pointer = hold;
+
+ /* FIXME: Need to check `want'. */
+
+ switch (exp.X_op)
+ {
+ case O_illegal:
+ errmsg = _("illegal operand");
+ *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
+ break;
+ case O_absent:
+ errmsg = _("missing operand");
+ *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
+ break;
+ case O_constant:
+ *valueP = exp.X_add_number;
+ *resultP = CGEN_PARSE_OPERAND_RESULT_NUMBER;
+ break;
+ case O_register:
+ *valueP = exp.X_add_number;
+ *resultP = CGEN_PARSE_OPERAND_RESULT_REGISTER;
+ break;
+ default:
+ queue_fixup (opindex, opinfo, &exp);
+ *valueP = 0;
+ *resultP = CGEN_PARSE_OPERAND_RESULT_QUEUED;
+ break;
+ }
+
+ return errmsg;
+}
+
+/* md_operand handler to catch unrecognized expressions and halt the
+ parsing process so the next entry can be tried.
+
+ ??? This could be done differently by adding code to `expression'. */
+
+void
+gas_cgen_md_operand (expressionP)
+ expressionS *expressionP ATTRIBUTE_UNUSED;
+{
+ /* Don't longjmp if we're not called from within cgen_parse_operand(). */
+ if (expr_jmp_buf_p)
+ longjmp (expr_jmp_buf, 1);
+}
+
+/* Finish assembling instruction INSN.
+ BUF contains what we've built up so far.
+ LENGTH is the size of the insn in bits.
+ RELAX_P is non-zero if relaxable insns should be emitted as such.
+ Otherwise they're emitted in non-relaxable forms.
+ The "result" is stored in RESULT if non-NULL. */
+
+void
+gas_cgen_finish_insn (insn, buf, length, relax_p, result)
+ const CGEN_INSN *insn;
+ CGEN_INSN_BYTES_PTR buf;
+ unsigned int length;
+ int relax_p;
+ finished_insnS *result;
+{
+ int i;
+ int relax_operand;
+ char *f;
+ unsigned int byte_len = length / 8;
+
+ /* ??? Target foo issues various warnings here, so one might want to provide
+ a hook here. However, our caller is defined in tc-foo.c so there
+ shouldn't be a need for a hook. */
+
+ /* Write out the instruction.
+ It is important to fetch enough space in one call to `frag_more'.
+ We use (f - frag_now->fr_literal) to compute where we are and we
+ don't want frag_now to change between calls.
+
+ Relaxable instructions: We need to ensure we allocate enough
+ space for the largest insn. */
+
+ if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED))
+ /* These currently shouldn't get here. */
+ abort ();
+
+ /* Is there a relaxable insn with the relaxable operand needing a fixup? */
+
+ relax_operand = -1;
+ if (relax_p && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE))
+ {
+ /* Scan the fixups for the operand affected by relaxing
+ (i.e. the branch address). */
+
+ for (i = 0; i < num_fixups; ++i)
+ {
+ if (CGEN_OPERAND_ATTR_VALUE (cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex),
+ CGEN_OPERAND_RELAX))
+ {
+ relax_operand = i;
+ break;
+ }
+ }
+ }
+
+ if (relax_operand != -1)
+ {
+ int max_len;
+ fragS *old_frag;
+ expressionS *exp;
+ symbolS *sym;
+ offsetT off;
+
+#ifdef TC_CGEN_MAX_RELAX
+ max_len = TC_CGEN_MAX_RELAX (insn, byte_len);
+#else
+ max_len = CGEN_MAX_INSN_SIZE;
+#endif
+ /* Ensure variable part and fixed part are in same fragment. */
+ /* FIXME: Having to do this seems like a hack. */
+ frag_grow (max_len);
+
+ /* Allocate space for the fixed part. */
+ f = frag_more (byte_len);
+
+ /* Create a relaxable fragment for this instruction. */
+ old_frag = frag_now;
+
+ exp = &fixups[relax_operand].exp;
+ sym = exp->X_add_symbol;
+ off = exp->X_add_number;
+ if (exp->X_op != O_constant && exp->X_op != O_symbol)
+ {
+ /* Handle complex expressions. */
+ sym = make_expr_symbol (exp);
+ off = 0;
+ }
+
+ frag_var (rs_machine_dependent,
+ max_len - byte_len /* max chars */,
+ 0 /* variable part already allocated */,
+ /* FIXME: When we machine generate the relax table,
+ machine generate a macro to compute subtype. */
+ 1 /* subtype */,
+ sym,
+ off,
+ f);
+
+ /* Record the operand number with the fragment so md_convert_frag
+ can use gas_cgen_md_record_fixup to record the appropriate reloc. */
+ old_frag->fr_cgen.insn = insn;
+ old_frag->fr_cgen.opindex = fixups[relax_operand].opindex;
+ old_frag->fr_cgen.opinfo = fixups[relax_operand].opinfo;
+ if (result)
+ result->frag = old_frag;
+ }
+ else
+ {
+ f = frag_more (byte_len);
+ if (result)
+ result->frag = frag_now;
+ }
+
+ /* If we're recording insns as numbers (rather than a string of bytes),
+ target byte order handling is deferred until now. */
+#if CGEN_INT_INSN_P
+ cgen_put_insn_value (gas_cgen_cpu_desc, f, length, *buf);
+#else
+ memcpy (f, buf, byte_len);
+#endif
+
+ /* Emit DWARF2 debugging information. */
+ dwarf2_emit_insn (byte_len);
+
+ /* Create any fixups. */
+ for (i = 0; i < num_fixups; ++i)
+ {
+ fixS *fixP;
+ const CGEN_OPERAND *operand =
+ cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex);
+
+ /* Don't create fixups for these. That's done during relaxation.
+ We don't need to test for CGEN_INSN_RELAXED as they can't get here
+ (see above). */
+ if (relax_p
+ && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE)
+ && CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_RELAX))
+ continue;
+
+#ifndef md_cgen_record_fixup_exp
+#define md_cgen_record_fixup_exp gas_cgen_record_fixup_exp
+#endif
+
+ fixP = md_cgen_record_fixup_exp (frag_now, f - frag_now->fr_literal,
+ insn, length, operand,
+ fixups[i].opinfo,
+ &fixups[i].exp);
+ if (result)
+ result->fixups[i] = fixP;
+ }
+
+ if (result)
+ {
+ result->num_fixups = num_fixups;
+ result->addr = f;
+ }
+}
+
+/* Apply a fixup to the object code. This is called for all the
+ fixups we generated by the call to fix_new_exp, above. In the call
+ above we used a reloc code which was the largest legal reloc code
+ plus the operand index. Here we undo that to recover the operand
+ index. At this point all symbol values should be fully resolved,
+ and we attempt to completely resolve the reloc. If we can not do
+ that, we determine the correct reloc code and put it back in the fixup. */
+
+/* FIXME: This function handles some of the fixups and bfd_install_relocation
+ handles the rest. bfd_install_relocation (or some other bfd function)
+ should handle them all. */
+
+void
+gas_cgen_md_apply_fix3 (fixP, valP, seg)
+ fixS * fixP;
+ valueT * valP;
+ segT seg ATTRIBUTE_UNUSED;
+{
+ char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
+ valueT value = * valP;
+ /* Canonical name, since used a lot. */
+ CGEN_CPU_DESC cd = gas_cgen_cpu_desc;
+
+ if (fixP->fx_addsy == (symbolS *) NULL)
+ fixP->fx_done = 1;
+
+ /* We don't actually support subtracting a symbol. */
+ if (fixP->fx_subsy != (symbolS *) NULL)
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
+
+ if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
+ {
+ int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
+ const CGEN_OPERAND *operand = cgen_operand_lookup_by_num (cd, opindex);
+ const char *errmsg;
+ bfd_reloc_code_real_type reloc_type;
+ CGEN_FIELDS *fields = alloca (CGEN_CPU_SIZEOF_FIELDS (cd));
+ const CGEN_INSN *insn = fixP->fx_cgen.insn;
+
+ /* If the reloc has been fully resolved finish the operand here. */
+ /* FIXME: This duplicates the capabilities of code in BFD. */
+ if (fixP->fx_done
+ /* FIXME: If partial_inplace isn't set bfd_install_relocation won't
+ finish the job. Testing for pcrel is a temporary hack. */
+ || fixP->fx_pcrel)
+ {
+ CGEN_CPU_SET_FIELDS_BITSIZE (cd) (fields, CGEN_INSN_BITSIZE (insn));
+ CGEN_CPU_SET_VMA_OPERAND (cd) (cd, opindex, fields, (bfd_vma) value);
+
+#if CGEN_INT_INSN_P
+ {
+ CGEN_INSN_INT insn_value =
+ cgen_get_insn_value (cd, where, CGEN_INSN_BITSIZE (insn));
+
+ /* ??? 0 is passed for `pc'. */
+ errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
+ &insn_value, (bfd_vma) 0);
+ cgen_put_insn_value (cd, where, CGEN_INSN_BITSIZE (insn),
+ insn_value);
+ }
+#else
+ /* ??? 0 is passed for `pc'. */
+ errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields, where,
+ (bfd_vma) 0);
+#endif
+ if (errmsg)
+ as_bad_where (fixP->fx_file, fixP->fx_line, "%s", errmsg);
+ }
+
+ if (fixP->fx_done)
+ return;
+
+ /* The operand isn't fully resolved. Determine a BFD reloc value
+ based on the operand information and leave it to
+ bfd_install_relocation. Note that this doesn't work when
+ partial_inplace == false. */
+
+ reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
+
+ if (reloc_type != BFD_RELOC_NONE)
+ fixP->fx_r_type = reloc_type;
+ else
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("unresolved expression that must be resolved"));
+ fixP->fx_done = 1;
+ return;
+ }
+ }
+ else if (fixP->fx_done)
+ {
+ /* We're finished with this fixup. Install it because
+ bfd_install_relocation won't be called to do it. */
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_8:
+ md_number_to_chars (where, value, 1);
+ break;
+ case BFD_RELOC_16:
+ md_number_to_chars (where, value, 2);
+ break;
+ case BFD_RELOC_32:
+ md_number_to_chars (where, value, 4);
+ break;
+ case BFD_RELOC_64:
+ md_number_to_chars (where, value, 8);
+ break;
+ default:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("internal error: can't install fix for reloc type %d (`%s')"),
+ fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
+ break;
+ }
+ }
+ /* else
+ bfd_install_relocation will be called to finish things up. */
+
+ /* Tuck `value' away for use by tc_gen_reloc.
+ See the comment describing fx_addnumber in write.h.
+ This field is misnamed (or misused :-). */
+ fixP->fx_addnumber = value;
+}
+
+/* Translate internal representation of relocation info to BFD target format.
+
+ FIXME: To what extent can we get all relevant targets to use this? */
+
+arelent *
+gas_cgen_tc_gen_reloc (section, fixP)
+ asection * section ATTRIBUTE_UNUSED;
+ fixS * fixP;
+{
+ arelent *reloc;
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
+ if (reloc->howto == (reloc_howto_type *) NULL)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation is not supported"));
+ return NULL;
+ }
+
+ assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
+
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
+
+ /* Use fx_offset for these cases. */
+ if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
+ reloc->addend = fixP->fx_offset;
+ else
+ reloc->addend = fixP->fx_addnumber;
+
+ reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
+ return reloc;
+}
+
+/* Perform any cgen specific initialisation.
+ Called after gas_cgen_cpu_desc has been created. */
+
+void
+gas_cgen_begin ()
+{
+ if (flag_signed_overflow_ok)
+ cgen_set_signed_overflow_ok (gas_cgen_cpu_desc);
+ else
+ cgen_clear_signed_overflow_ok (gas_cgen_cpu_desc);
+}
diff --git a/x/binutils/gas/cgen.h b/x/binutils/gas/cgen.h
new file mode 100644
index 0000000..8cf72af
--- /dev/null
+++ b/x/binutils/gas/cgen.h
@@ -0,0 +1,102 @@
+/* GAS cgen support.
+ Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef GAS_CGEN_H
+#define GAS_CGEN_H
+
+/* Opcode table handle. */
+extern CGEN_CPU_DESC gas_cgen_cpu_desc;
+
+/* Maximum number of fixups in an insn.
+ If you need to change this, allow target to override and do so there. */
+#ifndef GAS_CGEN_MAX_FIXUPS
+#define GAS_CGEN_MAX_FIXUPS 3
+#endif
+
+/* Struct defining result of gas_cgen_finish_insn. */
+typedef struct {
+ /* frag containing the insn */
+ fragS * frag;
+ /* Address of insn in frag. */
+ char * addr;
+ /* Number of fixups this insn has. */
+ int num_fixups;
+ /* Array of fixups. */
+ fixS * fixups[GAS_CGEN_MAX_FIXUPS];
+} finished_insnS;
+
+/* Callback for operand parsing.
+ The result is an error message or NULL for success.
+ The parsed value is stored in the bfd_vma *. */
+extern const char * gas_cgen_parse_operand
+ (CGEN_CPU_DESC, enum cgen_parse_operand_type,
+ const char **, int, int, enum cgen_parse_operand_result *,
+ bfd_vma *);
+
+/* Call this from md_assemble to initialize the assembler callback. */
+extern void gas_cgen_init_parse (void);
+
+/* Routines and macros for saving fixup chains. */
+extern void gas_cgen_save_fixups (int);
+extern void gas_cgen_restore_fixups (int);
+extern void gas_cgen_swap_fixups (int);
+extern void gas_cgen_initialize_saved_fixups_array (void);
+#define MAX_SAVED_FIXUP_CHAINS 50
+
+/* Add a register to the assembler's hash table.
+ This makes lets GAS parse registers for us.
+ ??? This isn't currently used, but it could be in the future. */
+extern void cgen_asm_record_register (char *, int);
+
+/* After CGEN_SYM (assemble_insn) is done, this is called to
+ output the insn and record any fixups. */
+extern void gas_cgen_finish_insn (const CGEN_INSN *,
+ CGEN_INSN_BYTES_PTR, unsigned int,
+ int, finished_insnS *);
+
+/* Record a fixup. */
+extern fixS * gas_cgen_record_fixup (fragS *, int, const CGEN_INSN *,
+ int, const CGEN_OPERAND *, int,
+ symbolS *, offsetT);
+extern fixS * gas_cgen_record_fixup_exp (fragS *, int, const CGEN_INSN *,
+ int, const CGEN_OPERAND *, int,
+ expressionS *);
+
+/* md_apply_fix3 handler */
+extern void gas_cgen_md_apply_fix3 (fixS *, valueT *, segT);
+
+/* tc_gen_reloc handler */
+extern arelent *gas_cgen_tc_gen_reloc (asection *, fixS *);
+
+/* Target supplied routine to lookup a reloc. */
+extern bfd_reloc_code_real_type
+md_cgen_lookup_reloc (const CGEN_INSN *, const CGEN_OPERAND *, fixS *);
+
+/* Optional target supplied routine to record a fixup for an expression. */
+extern fixS *
+md_cgen_record_fixup_exp (fragS *, int, const CGEN_INSN *, int,
+ const CGEN_OPERAND *, int, expressionS *);
+
+extern void gas_cgen_md_operand (expressionS *);
+
+/* Perform any cgen specific initialisation for gas. */
+extern void gas_cgen_begin (void);
+
+#endif /* GAS_CGEN_H */
diff --git a/x/binutils/gas/cond.c b/x/binutils/gas/cond.c
new file mode 100644
index 0000000..870a7d5
--- /dev/null
+++ b/x/binutils/gas/cond.c
@@ -0,0 +1,542 @@
+/* cond.c - conditional assembly pseudo-ops, and .include
+ Copyright 1990, 1991, 1992, 1993, 1995, 1997, 1998, 2000, 2001
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+#include "macro.h"
+
+#include "obstack.h"
+
+/* This is allocated to grow and shrink as .ifdef/.endif pairs are
+ scanned. */
+struct obstack cond_obstack;
+
+struct file_line {
+ char *file;
+ unsigned int line;
+};
+
+/* We push one of these structures for each .if, and pop it at the
+ .endif. */
+
+struct conditional_frame {
+ /* The source file & line number of the "if". */
+ struct file_line if_file_line;
+ /* The source file & line of the "else". */
+ struct file_line else_file_line;
+ /* The previous conditional. */
+ struct conditional_frame *previous_cframe;
+ /* Have we seen an else yet? */
+ int else_seen;
+ /* Whether we are currently ignoring input. */
+ int ignoring;
+ /* Whether a conditional at a higher level is ignoring input.
+ Set also when a branch of an "if .. elseif .." tree has matched
+ to prevent further matches. */
+ int dead_tree;
+ /* Macro nesting level at which this conditional was created. */
+ int macro_nest;
+};
+
+static void initialize_cframe (struct conditional_frame *cframe);
+static char *get_mri_string (int, int *);
+
+static struct conditional_frame *current_cframe = NULL;
+
+/* Performs the .ifdef (test_defined == 1) and
+ the .ifndef (test_defined == 0) pseudo op. */
+
+void
+s_ifdef (int test_defined)
+{
+ /* Points to name of symbol. */
+ char *name;
+ /* Points to symbol. */
+ symbolS *symbolP;
+ struct conditional_frame cframe;
+ char c;
+
+ /* Leading whitespace is part of operand. */
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+
+ if (!is_name_beginner (*name))
+ {
+ as_bad (_("invalid identifier for \".ifdef\""));
+ obstack_1grow (&cond_obstack, 0);
+ ignore_rest_of_line ();
+ return;
+ }
+
+ c = get_symbol_end ();
+ symbolP = symbol_find (name);
+ *input_line_pointer = c;
+
+ initialize_cframe (&cframe);
+
+ if (cframe.dead_tree)
+ cframe.ignoring = 1;
+ else
+ {
+ int is_defined;
+
+ /* Use the same definition of 'defined' as .equiv so that a symbol
+ which has been referenced but not yet given a value/address is
+ considered to be undefined. */
+ is_defined =
+ symbolP != NULL
+ && S_IS_DEFINED (symbolP)
+ && S_GET_SEGMENT (symbolP) != reg_section;
+
+ cframe.ignoring = ! (test_defined ^ is_defined);
+ }
+
+ current_cframe = ((struct conditional_frame *)
+ obstack_copy (&cond_obstack, &cframe,
+ sizeof (cframe)));
+
+ if (LISTING_SKIP_COND ()
+ && cframe.ignoring
+ && (cframe.previous_cframe == NULL
+ || ! cframe.previous_cframe->ignoring))
+ listing_list (2);
+
+ demand_empty_rest_of_line ();
+}
+
+void
+s_if (int arg)
+{
+ expressionS operand;
+ struct conditional_frame cframe;
+ int t;
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ /* Leading whitespace is part of operand. */
+ SKIP_WHITESPACE ();
+
+ if (current_cframe != NULL && current_cframe->ignoring)
+ {
+ operand.X_add_number = 0;
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+ else
+ {
+ expression (&operand);
+ if (operand.X_op != O_constant)
+ as_bad (_("non-constant expression in \".if\" statement"));
+ }
+
+ switch ((operatorT) arg)
+ {
+ case O_eq: t = operand.X_add_number == 0; break;
+ case O_ne: t = operand.X_add_number != 0; break;
+ case O_lt: t = operand.X_add_number < 0; break;
+ case O_le: t = operand.X_add_number <= 0; break;
+ case O_ge: t = operand.X_add_number >= 0; break;
+ case O_gt: t = operand.X_add_number > 0; break;
+ default:
+ abort ();
+ return;
+ }
+
+ /* If the above error is signaled, this will dispatch
+ using an undefined result. No big deal. */
+ initialize_cframe (&cframe);
+ cframe.ignoring = cframe.dead_tree || ! t;
+ current_cframe = ((struct conditional_frame *)
+ obstack_copy (&cond_obstack, &cframe, sizeof (cframe)));
+
+ if (LISTING_SKIP_COND ()
+ && cframe.ignoring
+ && (cframe.previous_cframe == NULL
+ || ! cframe.previous_cframe->ignoring))
+ listing_list (2);
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+
+ demand_empty_rest_of_line ();
+}
+
+/* Get a string for the MRI IFC or IFNC pseudo-ops. */
+
+static char *
+get_mri_string (int terminator, int *len)
+{
+ char *ret;
+ char *s;
+
+ SKIP_WHITESPACE ();
+ s = ret = input_line_pointer;
+ if (*input_line_pointer == '\'')
+ {
+ ++s;
+ ++input_line_pointer;
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ *s++ = *input_line_pointer++;
+ if (s[-1] == '\'')
+ {
+ if (*input_line_pointer != '\'')
+ break;
+ ++input_line_pointer;
+ }
+ }
+ SKIP_WHITESPACE ();
+ }
+ else
+ {
+ while (*input_line_pointer != terminator
+ && ! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ s = input_line_pointer;
+ while (s > ret && (s[-1] == ' ' || s[-1] == '\t'))
+ --s;
+ }
+
+ *len = s - ret;
+ return ret;
+}
+
+/* The MRI IFC and IFNC pseudo-ops. */
+
+void
+s_ifc (int arg)
+{
+ char *stop = NULL;
+ char stopc;
+ char *s1, *s2;
+ int len1, len2;
+ int res;
+ struct conditional_frame cframe;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ s1 = get_mri_string (',', &len1);
+
+ if (*input_line_pointer != ',')
+ as_bad (_("bad format for ifc or ifnc"));
+ else
+ ++input_line_pointer;
+
+ s2 = get_mri_string (';', &len2);
+
+ res = len1 == len2 && strncmp (s1, s2, len1) == 0;
+
+ initialize_cframe (&cframe);
+ cframe.ignoring = cframe.dead_tree || ! (res ^ arg);
+ current_cframe = ((struct conditional_frame *)
+ obstack_copy (&cond_obstack, &cframe, sizeof (cframe)));
+
+ if (LISTING_SKIP_COND ()
+ && cframe.ignoring
+ && (cframe.previous_cframe == NULL
+ || ! cframe.previous_cframe->ignoring))
+ listing_list (2);
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+
+ demand_empty_rest_of_line ();
+}
+
+void
+s_elseif (int arg)
+{
+ if (current_cframe == NULL)
+ {
+ as_bad (_("\".elseif\" without matching \".if\""));
+ }
+ else if (current_cframe->else_seen)
+ {
+ as_bad (_("\".elseif\" after \".else\""));
+ as_bad_where (current_cframe->else_file_line.file,
+ current_cframe->else_file_line.line,
+ _("here is the previous \"else\""));
+ as_bad_where (current_cframe->if_file_line.file,
+ current_cframe->if_file_line.line,
+ _("here is the previous \"if\""));
+ }
+ else
+ {
+ as_where (&current_cframe->else_file_line.file,
+ &current_cframe->else_file_line.line);
+
+ current_cframe->dead_tree |= !current_cframe->ignoring;
+ current_cframe->ignoring = current_cframe->dead_tree;
+ }
+
+ if (current_cframe == NULL || current_cframe->ignoring)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+
+ if (current_cframe == NULL)
+ return;
+ }
+ else
+ {
+ expressionS operand;
+ int t;
+
+ /* Leading whitespace is part of operand. */
+ SKIP_WHITESPACE ();
+
+ expression (&operand);
+ if (operand.X_op != O_constant)
+ as_bad (_("non-constant expression in \".elseif\" statement"));
+
+ switch ((operatorT) arg)
+ {
+ case O_eq: t = operand.X_add_number == 0; break;
+ case O_ne: t = operand.X_add_number != 0; break;
+ case O_lt: t = operand.X_add_number < 0; break;
+ case O_le: t = operand.X_add_number <= 0; break;
+ case O_ge: t = operand.X_add_number >= 0; break;
+ case O_gt: t = operand.X_add_number > 0; break;
+ default:
+ abort ();
+ return;
+ }
+
+ current_cframe->ignoring = current_cframe->dead_tree || ! t;
+ }
+
+ if (LISTING_SKIP_COND ()
+ && (current_cframe->previous_cframe == NULL
+ || ! current_cframe->previous_cframe->ignoring))
+ {
+ if (! current_cframe->ignoring)
+ listing_list (1);
+ else
+ listing_list (2);
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+void
+s_endif (int arg ATTRIBUTE_UNUSED)
+{
+ struct conditional_frame *hold;
+
+ if (current_cframe == NULL)
+ {
+ as_bad (_("\".endif\" without \".if\""));
+ }
+ else
+ {
+ if (LISTING_SKIP_COND ()
+ && current_cframe->ignoring
+ && (current_cframe->previous_cframe == NULL
+ || ! current_cframe->previous_cframe->ignoring))
+ listing_list (1);
+
+ hold = current_cframe;
+ current_cframe = current_cframe->previous_cframe;
+ obstack_free (&cond_obstack, hold);
+ } /* if one pop too many */
+
+ if (flag_mri)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+void
+s_else (int arg ATTRIBUTE_UNUSED)
+{
+ if (current_cframe == NULL)
+ {
+ as_bad (_("\".else\" without matching \".if\""));
+ }
+ else if (current_cframe->else_seen)
+ {
+ as_bad (_("duplicate \"else\""));
+ as_bad_where (current_cframe->else_file_line.file,
+ current_cframe->else_file_line.line,
+ _("here is the previous \"else\""));
+ as_bad_where (current_cframe->if_file_line.file,
+ current_cframe->if_file_line.line,
+ _("here is the previous \"if\""));
+ }
+ else
+ {
+ as_where (&current_cframe->else_file_line.file,
+ &current_cframe->else_file_line.line);
+
+ current_cframe->ignoring =
+ current_cframe->dead_tree | !current_cframe->ignoring;
+
+ if (LISTING_SKIP_COND ()
+ && (current_cframe->previous_cframe == NULL
+ || ! current_cframe->previous_cframe->ignoring))
+ {
+ if (! current_cframe->ignoring)
+ listing_list (1);
+ else
+ listing_list (2);
+ }
+
+ current_cframe->else_seen = 1;
+ }
+
+ if (flag_mri)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+void
+s_ifeqs (int arg)
+{
+ char *s1, *s2;
+ int len1, len2;
+ int res;
+ struct conditional_frame cframe;
+
+ s1 = demand_copy_C_string (&len1);
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_(".ifeqs syntax error"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ ++input_line_pointer;
+
+ s2 = demand_copy_C_string (&len2);
+
+ res = len1 == len2 && strncmp (s1, s2, len1) == 0;
+
+ initialize_cframe (&cframe);
+ cframe.ignoring = cframe.dead_tree || ! (res ^ arg);
+ current_cframe = ((struct conditional_frame *)
+ obstack_copy (&cond_obstack, &cframe, sizeof (cframe)));
+
+ if (LISTING_SKIP_COND ()
+ && cframe.ignoring
+ && (cframe.previous_cframe == NULL
+ || ! cframe.previous_cframe->ignoring))
+ listing_list (2);
+
+ demand_empty_rest_of_line ();
+}
+
+int
+ignore_input (void)
+{
+ char *s;
+
+ s = input_line_pointer;
+
+ if (NO_PSEUDO_DOT || flag_m68k_mri)
+ {
+ if (s[-1] != '.')
+ --s;
+ }
+ else
+ {
+ if (s[-1] != '.')
+ return (current_cframe != NULL) && (current_cframe->ignoring);
+ }
+
+ /* We cannot ignore certain pseudo ops. */
+ if (((s[0] == 'i'
+ || s[0] == 'I')
+ && (!strncasecmp (s, "if", 2)
+ || !strncasecmp (s, "ifdef", 5)
+ || !strncasecmp (s, "ifndef", 6)))
+ || ((s[0] == 'e'
+ || s[0] == 'E')
+ && (!strncasecmp (s, "else", 4)
+ || !strncasecmp (s, "endif", 5)
+ || !strncasecmp (s, "endc", 4))))
+ return 0;
+
+ return (current_cframe != NULL) && (current_cframe->ignoring);
+}
+
+static void
+initialize_cframe (struct conditional_frame *cframe)
+{
+ memset (cframe, 0, sizeof (*cframe));
+ as_where (&cframe->if_file_line.file,
+ &cframe->if_file_line.line);
+ cframe->previous_cframe = current_cframe;
+ cframe->dead_tree = current_cframe != NULL && current_cframe->ignoring;
+ cframe->macro_nest = macro_nest;
+}
+
+/* Give an error if a conditional is unterminated inside a macro or
+ the assembly as a whole. If NEST is non negative, we are being
+ called because of the end of a macro expansion. If NEST is
+ negative, we are being called at the of the input files. */
+
+void
+cond_finish_check (int nest)
+{
+ if (current_cframe != NULL && current_cframe->macro_nest >= nest)
+ {
+ if (nest >= 0)
+ as_bad (_("end of macro inside conditional"));
+ else
+ as_bad (_("end of file inside conditional"));
+ as_bad_where (current_cframe->if_file_line.file,
+ current_cframe->if_file_line.line,
+ _("here is the start of the unterminated conditional"));
+ if (current_cframe->else_seen)
+ as_bad_where (current_cframe->else_file_line.file,
+ current_cframe->else_file_line.line,
+ _("here is the \"else\" of the unterminated conditional"));
+ }
+}
+
+/* This function is called when we exit out of a macro. We assume
+ that any conditionals which began within the macro are correctly
+ nested, and just pop them off the stack. */
+
+void
+cond_exit_macro (int nest)
+{
+ while (current_cframe != NULL && current_cframe->macro_nest >= nest)
+ {
+ struct conditional_frame *hold;
+
+ hold = current_cframe;
+ current_cframe = current_cframe->previous_cframe;
+ obstack_free (&cond_obstack, hold);
+ }
+}
diff --git a/x/binutils/gas/conf.in b/x/binutils/gas/conf.in
new file mode 100644
index 0000000..d56807c
--- /dev/null
+++ b/x/binutils/gas/conf.in
@@ -0,0 +1,127 @@
+/* conf.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Should gas use high-level BFD interfaces? */
+#undef BFD_ASSEMBLER
+
+/* Some assert/preprocessor combinations are incapable of handling
+ certain kinds of constructs in the argument of assert. For example,
+ quoted strings (if requoting isn't done right) or newlines. */
+#undef BROKEN_ASSERT
+
+/* If we aren't doing cross-assembling, some operations can be optimized,
+ since byte orders and value sizes don't need to be adjusted. */
+#undef CROSS_COMPILE
+
+/* Some gas code wants to know these parameters. */
+#undef TARGET_ALIAS
+#undef TARGET_CPU
+#undef TARGET_CANONICAL
+#undef TARGET_OS
+#undef TARGET_VENDOR
+
+/* Sometimes the system header files don't declare strstr. */
+#undef NEED_DECLARATION_STRSTR
+
+/* Sometimes the system header files don't declare malloc and realloc. */
+#undef NEED_DECLARATION_MALLOC
+
+/* Sometimes the system header files don't declare free. */
+#undef NEED_DECLARATION_FREE
+
+/* Sometimes the system header files don't declare sbrk. */
+#undef NEED_DECLARATION_SBRK
+
+/* Sometimes errno.h doesn't declare errno itself. */
+#undef NEED_DECLARATION_ERRNO
+
+#undef MANY_SEGMENTS
+
+/* Needed only for sparc configuration. */
+#undef SPARC_V9
+#undef SPARC_ARCH64
+
+/* Defined if using CGEN. */
+#undef USING_CGEN
+
+/* Needed only for some configurations that can produce multiple output
+ formats. */
+#undef DEFAULT_EMULATION
+#undef EMULATIONS
+#undef USE_EMULATIONS
+#undef OBJ_MAYBE_AOUT
+#undef OBJ_MAYBE_BOUT
+#undef OBJ_MAYBE_COFF
+#undef OBJ_MAYBE_ECOFF
+#undef OBJ_MAYBE_ELF
+#undef OBJ_MAYBE_GENERIC
+#undef OBJ_MAYBE_HP300
+#undef OBJ_MAYBE_IEEE
+#undef OBJ_MAYBE_SOM
+#undef OBJ_MAYBE_VMS
+
+/* Used for some of the COFF configurations, when the COFF code needs
+ to select something based on the CPU type before it knows it... */
+#undef I386COFF
+#undef M68KCOFF
+#undef M88KCOFF
+
+/* Define if you have the remove function. */
+#undef HAVE_REMOVE
+
+/* Define if you have the sbrk function. */
+#undef HAVE_SBRK
+
+/* Define if you have the unlink function. */
+#undef HAVE_UNLINK
+
+/* Define if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
+
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the <varargs.h> header file. */
+#undef HAVE_VARARGS_H
diff --git a/x/binutils/gas/config.in b/x/binutils/gas/config.in
new file mode 100644
index 0000000..fe2bc3f
--- /dev/null
+++ b/x/binutils/gas/config.in
@@ -0,0 +1,282 @@
+/* config.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if lex declares yytext as a char * by default, not a char[]. */
+#undef YYTEXT_POINTER
+
+/* Define if you have the __argz_count function. */
+#undef HAVE___ARGZ_COUNT
+
+/* Define if you have the __argz_next function. */
+#undef HAVE___ARGZ_NEXT
+
+/* Define if you have the __argz_stringify function. */
+#undef HAVE___ARGZ_STRINGIFY
+
+/* Define if you have the dcgettext function. */
+#undef HAVE_DCGETTEXT
+
+/* Define if you have the getcwd function. */
+#undef HAVE_GETCWD
+
+/* Define if you have the getpagesize function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the munmap function. */
+#undef HAVE_MUNMAP
+
+/* Define if you have the putenv function. */
+#undef HAVE_PUTENV
+
+/* Define if you have the remove function. */
+#undef HAVE_REMOVE
+
+/* Define if you have the sbrk function. */
+#undef HAVE_SBRK
+
+/* Define if you have the setenv function. */
+#undef HAVE_SETENV
+
+/* Define if you have the setlocale function. */
+#undef HAVE_SETLOCALE
+
+/* Define if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strchr function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the unlink function. */
+#undef HAVE_UNLINK
+
+/* Define if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
+/* Define if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <nl_types.h> header file. */
+#undef HAVE_NL_TYPES_H
+
+/* Define if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
+
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the <values.h> header file. */
+#undef HAVE_VALUES_H
+
+/* Define if you have the <varargs.h> header file. */
+#undef HAVE_VARARGS_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
+/* Define if defaulting to ELF on SCO 5. */
+#undef SCO_ELF
+
+/* Using strict COFF? */
+#undef STRICTCOFF
+
+/* Define if default target is PowerPC Solaris. */
+#undef TARGET_SOLARIS_COMMENT
+
+/* Define as 1 if big endian. */
+#undef TARGET_BYTES_BIG_ENDIAN
+
+/* Default CPU for MIPS targets. */
+#undef MIPS_CPU_STRING_DEFAULT
+
+/* Allow use of E_MIPS_ABI_O32 on MIPS targets. */
+#undef USE_E_MIPS_ABI_O32
+
+/* Generate 64-bit code by default on MIPS targets. */
+#undef MIPS_DEFAULT_64BIT
+
+/* Choose a default ABI for MIPS targets. */
+#undef MIPS_DEFAULT_ABI
+
+/* Default architecture. */
+#undef DEFAULT_ARCH
+
+/* Using cgen code? */
+#undef USING_CGEN
+
+/* Using i386 COFF? */
+#undef I386COFF
+
+/* Using m68k COFF? */
+#undef M68KCOFF
+
+/* Using m88k COFF? */
+#undef M88KCOFF
+
+/* a.out support? */
+#undef OBJ_MAYBE_AOUT
+
+/* b.out support? */
+#undef OBJ_MAYBE_BOUT
+
+/* COFF support? */
+#undef OBJ_MAYBE_COFF
+
+/* ECOFF support? */
+#undef OBJ_MAYBE_ECOFF
+
+/* ELF support? */
+#undef OBJ_MAYBE_ELF
+
+/* generic support? */
+#undef OBJ_MAYBE_GENERIC
+
+/* HP300 support? */
+#undef OBJ_MAYBE_HP300
+
+/* IEEE support? */
+#undef OBJ_MAYBE_IEEE
+
+/* SOM support? */
+#undef OBJ_MAYBE_SOM
+
+/* VMS support? */
+#undef OBJ_MAYBE_VMS
+
+/* Use emulation support? */
+#undef USE_EMULATIONS
+
+/* Supported emulations. */
+#undef EMULATIONS
+
+/* Default emulation. */
+#undef DEFAULT_EMULATION
+
+/* old COFF support? */
+#undef MANY_SEGMENTS
+
+/* Use BFD interface? */
+#undef BFD_ASSEMBLER
+
+/* Target alias. */
+#undef TARGET_ALIAS
+
+/* Canonical target. */
+#undef TARGET_CANONICAL
+
+/* Target CPU. */
+#undef TARGET_CPU
+
+/* Target vendor. */
+#undef TARGET_VENDOR
+
+/* Target OS. */
+#undef TARGET_OS
+
+/* Define if you have the stpcpy function */
+#undef HAVE_STPCPY
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define to 1 if NLS is requested */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
+/* Compiling cross-assembler? */
+#undef CROSS_COMPILE
+
+/* assert broken? */
+#undef BROKEN_ASSERT
+
+/* Define if strstr is not declared in system header files. */
+#undef NEED_DECLARATION_STRSTR
+
+/* Define if malloc is not declared in system header files. */
+#undef NEED_DECLARATION_MALLOC
+
+/* Define if free is not declared in system header files. */
+#undef NEED_DECLARATION_FREE
+
+/* Define if sbrk is not declared in system header files. */
+#undef NEED_DECLARATION_SBRK
+
+/* Define if environ is not declared in system header files. */
+#undef NEED_DECLARATION_ENVIRON
+
+/* Define if errno is not declared in system header files. */
+#undef NEED_DECLARATION_ERRNO
+
diff --git a/x/binutils/gas/config/aout_gnu.h b/x/binutils/gas/config/aout_gnu.h
new file mode 100644
index 0000000..0942fd3
--- /dev/null
+++ b/x/binutils/gas/config/aout_gnu.h
@@ -0,0 +1,450 @@
+/* This file is aout_gnu.h
+
+ Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef __A_OUT_GNU_H__
+#define __A_OUT_GNU_H__
+
+/* There are two main flavours of a.out, one which uses the standard
+ relocations, and one which uses extended relocations.
+
+ Today, the extended reloc uses are
+ TC_SPARC, TC_A29K
+
+ each must define the enum reloc_type
+
+*/
+
+#define USE_EXTENDED_RELOC (defined(TC_SPARC) || defined(TC_A29K))
+
+#if defined(TC_SPARC) || defined(TC_A29K)
+enum reloc_type
+ {
+ RELOC_8, RELOC_16, RELOC_32,/* simple relocations */
+ RELOC_DISP8, RELOC_DISP16, RELOC_DISP32, /* pc-rel displacement */
+ RELOC_WDISP30, RELOC_WDISP22,
+ RELOC_HI22, RELOC_22,
+ RELOC_13, RELOC_LO10,
+ RELOC_SFA_BASE, RELOC_SFA_OFF13,
+ RELOC_BASE10, RELOC_BASE13, RELOC_BASE22, /* P.I.C. (base-relative) */
+ RELOC_PC10, RELOC_PC22, /* for some sort of pc-rel P.I.C. (?) */
+ RELOC_JMP_TBL, /* P.I.C. jump table */
+ RELOC_SEGOFF16, /* reputedly for shared libraries somehow */
+ RELOC_GLOB_DAT, RELOC_JMP_SLOT, RELOC_RELATIVE,
+ RELOC_10, RELOC_11,
+ RELOC_WDISP2_14,
+ RELOC_WDISP19,
+ RELOC_HHI22,
+ RELOC_HLO10,
+
+ /* 29K relocation types */
+ RELOC_JUMPTARG, RELOC_CONST, RELOC_CONSTH,
+
+ RELOC_WDISP14, RELOC_WDISP21,
+
+ NO_RELOC
+ };
+
+#endif /* TC_SPARC or TC_A29K */
+
+#define __GNU_EXEC_MACROS__
+
+#ifndef __STRUCT_EXEC_OVERRIDE__
+
+/* This is the layout on disk of a Unix V7, Berkeley, SunOS, Vax Ultrix
+ "struct exec". Don't assume that on this machine, the "struct exec"
+ will lay out the same sizes or alignments. */
+
+struct exec_bytes
+ {
+ unsigned char a_info[4];
+ unsigned char a_text[4];
+ unsigned char a_data[4];
+ unsigned char a_bss[4];
+ unsigned char a_syms[4];
+ unsigned char a_entry[4];
+ unsigned char a_trsize[4];
+ unsigned char a_drsize[4];
+ };
+
+/* How big the "struct exec" is on disk */
+#define EXEC_BYTES_SIZE (8 * 4)
+
+/* This is the layout in memory of a "struct exec" while we process it. */
+
+struct exec
+{
+ unsigned long a_info; /* Use macros N_MAGIC, etc for access */
+ unsigned a_text; /* length of text, in bytes */
+ unsigned a_data; /* length of data, in bytes */
+ unsigned a_bss; /* length of uninitialized data area for file, in bytes */
+ unsigned a_syms; /* length of symbol table data in file, in bytes */
+ unsigned a_entry; /* start address */
+ unsigned a_trsize; /* length of relocation info for text, in bytes */
+ unsigned a_drsize; /* length of relocation info for data, in bytes */
+};
+
+#endif /* __STRUCT_EXEC_OVERRIDE__ */
+
+/* these go in the N_MACHTYPE field */
+/* These symbols could be defined by code from Suns...punt 'em */
+#undef M_UNKNOWN
+#undef M_68010
+#undef M_68020
+#undef M_SPARC
+enum machine_type
+ {
+ M_UNKNOWN = 0,
+ M_68010 = 1,
+ M_68020 = 2,
+ M_SPARC = 3,
+ /* skip a bunch so we don't run into any of sun's numbers */
+ M_386 = 100,
+ M_29K = 101,
+ M_RS6000 = 102, /* IBM RS/6000 */
+ M_VAX4K_NETBSD = 150,
+ /* HP/BSD formats */
+ M_HP200 = 200, /* hp200 (68010) BSD binary */
+ M_HP300 = 300, /* hp300 (68020+68881) BSD binary */
+ M_HPUX23 = 0x020C /* hp200/300 HPUX binary */
+ };
+
+#define N_MAGIC(exec) ((exec).a_info & 0xffff)
+#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
+#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
+#define N_SET_INFO(exec, magic, type, flags) \
+ ((exec).a_info = ((magic) & 0xffff) \
+ | (((int)(type) & 0xff) << 16) \
+ | (((flags) & 0xff) << 24))
+#define N_SET_MAGIC(exec, magic) \
+ ((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff)))
+
+#define N_SET_MACHTYPE(exec, machtype) \
+ ((exec).a_info = \
+ ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
+
+#define N_SET_FLAGS(exec, flags) \
+ ((exec).a_info = \
+ ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
+
+/* Code indicating object file or impure executable. */
+#ifndef OMAGIC
+#define OMAGIC 0407
+#endif
+/* Code indicating pure executable. */
+#define NMAGIC 0410
+/* Code indicating demand-paged executable. */
+#define ZMAGIC 0413
+
+/* Virtual Address of text segment from the a.out file. For OMAGIC,
+ (almost always "unlinked .o's" these days), should be zero.
+ For linked files, should reflect reality if we know it. */
+
+#ifndef N_TXTADDR
+#define N_TXTADDR(x) (N_MAGIC(x)==OMAGIC? 0 : TEXT_START_ADDR)
+#endif
+
+#ifndef N_BADMAG
+#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
+ && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC)
+#endif
+
+/* By default, segment size is constant. But on some machines, it can
+ be a function of the a.out header (e.g. machine type). */
+#ifndef N_SEGSIZE
+#define N_SEGSIZE(x) SEGMENT_SIZE
+#endif
+
+/* This complexity is for encapsulated COFF support */
+#ifndef _N_HDROFF
+#define _N_HDROFF(x) (N_SEGSIZE(x) - sizeof (struct exec))
+#endif
+
+#ifndef N_TXTOFF
+#define N_TXTOFF(x) (N_MAGIC(x) == ZMAGIC ? \
+ _N_HDROFF((x)) + sizeof (struct exec) : \
+ sizeof (struct exec))
+#endif
+
+#ifndef N_DATOFF
+#define N_DATOFF(x) ( N_TXTOFF(x) + (x).a_text )
+#endif
+
+#ifndef N_TRELOFF
+#define N_TRELOFF(x) ( N_DATOFF(x) + (x).a_data )
+#endif
+
+#ifndef N_DRELOFF
+#define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize )
+#endif
+
+#ifndef N_SYMOFF
+#define N_SYMOFF(x) ( N_DRELOFF(x) + (x).a_drsize )
+#endif
+
+#ifndef N_STROFF
+#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms )
+#endif
+
+/* Address of text segment in memory after it is loaded. */
+#ifndef N_TXTADDR
+#define N_TXTADDR(x) 0
+#endif
+
+#ifndef N_DATADDR
+#define N_DATADDR(x) \
+ (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+(x).a_text) \
+ : (N_SEGSIZE(x) + ((N_TXTADDR(x)+(x).a_text-1) & ~(N_SEGSIZE(x)-1))))
+#endif
+
+/* Address of bss segment in memory after it is loaded. */
+#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
+
+struct nlist
+ {
+ union
+ {
+ char *n_name;
+ struct nlist *n_next;
+ long n_strx;
+ }
+ n_un;
+ unsigned char n_type;
+ char n_other;
+ short n_desc;
+ unsigned long n_value;
+ };
+
+#define N_UNDF 0
+#define N_ABS 2
+#define N_TEXT 4
+#define N_DATA 6
+#define N_BSS 8
+#define N_COMM 0x12 /* common (visible in shared lib commons) */
+#define N_FN 0x1F /* File name of a .o file */
+
+/* Note: N_EXT can only usefully be OR-ed with N_UNDF, N_ABS, N_TEXT,
+ N_DATA, or N_BSS. When the low-order bit of other types is set,
+ (e.g. N_WARNING versus N_FN), they are two different types. */
+#define N_EXT 1
+#define N_TYPE 036
+#define N_STAB 0340
+
+/* The following type indicates the definition of a symbol as being
+ an indirect reference to another symbol. The other symbol
+ appears as an undefined reference, immediately following this symbol.
+
+ Indirection is asymmetrical. The other symbol's value will be used
+ to satisfy requests for the indirect symbol, but not vice versa.
+ If the other symbol does not have a definition, libraries will
+ be searched to find a definition. */
+
+#define N_INDR 0xa
+
+/* The following symbols refer to set elements.
+ All the N_SET[ATDB] symbols with the same name form one set.
+ Space is allocated for the set in the text section, and each set
+ element's value is stored into one word of the space.
+ The first word of the space is the length of the set (number of elements).
+
+ The address of the set is made into an N_SETV symbol
+ whose name is the same as the name of the set.
+ This symbol acts like a N_DATA global symbol
+ in that it can satisfy undefined external references. */
+
+/* These appear as input to LD, in a .o file. */
+#define N_SETA 0x14 /* Absolute set element symbol */
+#define N_SETT 0x16 /* Text set element symbol */
+#define N_SETD 0x18 /* Data set element symbol */
+#define N_SETB 0x1A /* Bss set element symbol */
+
+/* This is output from LD. */
+#define N_SETV 0x1C /* Pointer to set vector in data area. */
+
+/* Warning symbol. The text gives a warning message, the next symbol
+ in the table will be undefined. When the symbol is referenced, the
+ message is printed. */
+
+#define N_WARNING 0x1e
+
+/* Weak symbols. These are a GNU extension to the a.out format. The
+ semantics are those of ELF weak symbols. Weak symbols are always
+ externally visible. The N_WEAK? values are squeezed into the
+ available slots. The value of a N_WEAKU symbol is 0. The values
+ of the other types are the definitions. */
+#define N_WEAKU 0x0d /* Weak undefined symbol. */
+#define N_WEAKA 0x0e /* Weak absolute symbol. */
+#define N_WEAKT 0x0f /* Weak text symbol. */
+#define N_WEAKD 0x10 /* Weak data symbol. */
+#define N_WEAKB 0x11 /* Weak bss symbol. */
+
+/* This structure describes a single relocation to be performed.
+ The text-relocation section of the file is a vector of these structures,
+ all of which apply to the text section.
+ Likewise, the data-relocation section applies to the data section. */
+
+/* The following enum and struct were borrowed from SunOS's
+ /usr/include/sun4/a.out.h and extended to handle
+ other machines. It is currently used on SPARC and AMD 29000.
+
+ reloc_ext_bytes is how it looks on disk. reloc_info_extended is
+ how we might process it on a native host. */
+#if USE_EXTENDED_RELOC
+
+struct reloc_ext_bytes
+ {
+ unsigned char r_address[4];
+ unsigned char r_index[3];
+ unsigned char r_bits[1];
+ unsigned char r_addend[4];
+ };
+
+#define RELOC_EXT_BITS_EXTERN_BIG 0x80
+#define RELOC_EXT_BITS_EXTERN_LITTLE 0x01
+
+#define RELOC_EXT_BITS_TYPE_BIG 0x1F
+#define RELOC_EXT_BITS_TYPE_SH_BIG 0
+#define RELOC_EXT_BITS_TYPE_LITTLE 0xF8
+#define RELOC_EXT_BITS_TYPE_SH_LITTLE 3
+
+#define RELOC_EXT_SIZE 12 /* Bytes per relocation entry */
+
+struct reloc_info_extended
+{
+ unsigned long r_address;
+ unsigned int r_index:24;
+# define r_symbolnum r_index
+ unsigned r_extern:1;
+ unsigned:2;
+ /* RS/6000 compiler does not support enum bitfield
+ enum reloc_type r_type:5; */
+ enum reloc_type r_type;
+ long int r_addend;
+};
+
+#else
+
+/* The standard, old-fashioned, Berkeley compatible relocation struct */
+
+#ifdef TC_I860
+/* NOTE: three bits max, see struct reloc_info_i860.r_type */
+enum i860_reloc_type
+ {
+ NO_RELOC = 0, BRADDR, LOW0, LOW1, LOW2, LOW3, LOW4, SPLIT0, SPLIT1, SPLIT2, RELOC_32,
+ };
+
+typedef enum i860_reloc_type reloc_type;
+
+/* NOTE: two bits max, see reloc_info_i860.r_type */
+enum highlow_type
+ {
+ NO_SPEC = 0, PAIR, HIGH, HIGHADJ,
+ };
+
+struct reloc_info_i860
+{
+ unsigned long r_address;
+ /*
+ * Using bit fields here is a bad idea because the order is not portable. :-(
+ */
+ unsigned int r_symbolnum:24;
+ unsigned int r_pcrel:1;
+ unsigned int r_extern:1;
+ /* combining the two field simplifies the argument passing in "new_fix()" */
+ /* and is compatible with the existing Sparc #ifdef's */
+ /* r_type: highlow_type - bits 5,4; reloc_type - bits 3-0 */
+ unsigned int r_type:6;
+ long r_addend;
+};
+
+#endif /* TC_I860 */
+
+struct reloc_std_bytes
+ {
+ unsigned char r_address[4];
+ unsigned char r_index[3];
+ unsigned char r_bits[1];
+ };
+
+#define RELOC_STD_BITS_PCREL_BIG 0x80
+#define RELOC_STD_BITS_PCREL_LITTLE 0x01
+
+#define RELOC_STD_BITS_LENGTH_BIG 0x60
+#define RELOC_STD_BITS_LENGTH_SH_BIG 5 /* To shift to units place */
+#define RELOC_STD_BITS_LENGTH_LITTLE 0x06
+#define RELOC_STD_BITS_LENGTH_SH_LITTLE 1
+
+#define RELOC_STD_BITS_EXTERN_BIG 0x10
+#define RELOC_STD_BITS_EXTERN_LITTLE 0x08
+
+#define RELOC_STD_BITS_BASEREL_BIG 0x08
+#define RELOC_STD_BITS_BASEREL_LITTLE 0x08
+
+#define RELOC_STD_BITS_JMPTABLE_BIG 0x04
+#define RELOC_STD_BITS_JMPTABLE_LITTLE 0x04
+
+#define RELOC_STD_BITS_RELATIVE_BIG 0x02
+#define RELOC_STD_BITS_RELATIVE_LITTLE 0x02
+
+#define RELOC_STD_SIZE 8 /* Bytes per relocation entry */
+
+#endif /* USE_EXTENDED_RELOC */
+
+#ifndef CUSTOM_RELOC_FORMAT
+struct relocation_info
+{
+ /* Address (within segment) to be relocated. */
+ int r_address;
+ /* The meaning of r_symbolnum depends on r_extern. */
+ unsigned int r_symbolnum:24;
+ /* Nonzero means value is a pc-relative offset
+ and it should be relocated for changes in its own address
+ as well as for changes in the symbol or section specified. */
+ unsigned int r_pcrel:1;
+ /* Length (as exponent of 2) of the field to be relocated.
+ Thus, a value of 2 indicates 1<<2 bytes. */
+ unsigned int r_length:2;
+ /* 1 => relocate with value of symbol.
+ r_symbolnum is the index of the symbol
+ in file's the symbol table.
+ 0 => relocate with the address of a segment.
+ r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS
+ (the N_EXT bit may be set also, but signifies nothing). */
+ unsigned int r_extern:1;
+ /* The next three bits are for SunOS shared libraries, and seem to
+ be undocumented. */
+#ifdef TC_NS32K
+ unsigned int r_bsr:1;
+ unsigned int r_disp:2;
+#else
+ unsigned int r_baserel:1; /* Linkage table relative */
+ unsigned int r_jmptable:1; /* pc-relative to jump table */
+ unsigned int r_relative:1; /* "relative relocation" */
+#endif /* TC_NS32K */
+ /* unused */
+ unsigned int r_pad:1; /* Padding -- set to zero */
+};
+
+#endif /* CUSTOM_RELOC_FORMAT */
+
+#endif /* __A_OUT_GNU_H__ */
+
+/* end of aout_gnu.h */
diff --git a/x/binutils/gas/config/atof-ieee.c b/x/binutils/gas/config/atof-ieee.c
new file mode 100644
index 0000000..0ad39c9
--- /dev/null
+++ b/x/binutils/gas/config/atof-ieee.c
@@ -0,0 +1,734 @@
+/* atof_ieee.c - turn a Flonum into an IEEE floating point number
+ Copyright 1987, 1992, 1994, 1996, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+
+/* Flonums returned here. */
+extern FLONUM_TYPE generic_floating_point_number;
+
+static int next_bits PARAMS ((int));
+static void unget_bits PARAMS ((int));
+static void make_invalid_floating_point_number PARAMS ((LITTLENUM_TYPE *));
+
+extern const char EXP_CHARS[];
+/* Precision in LittleNums. */
+/* Don't count the gap in the m68k extended precision format. */
+#define MAX_PRECISION (5)
+#define F_PRECISION (2)
+#define D_PRECISION (4)
+#define X_PRECISION (5)
+#define P_PRECISION (5)
+
+/* Length in LittleNums of guard bits. */
+#define GUARD (2)
+
+#ifndef TC_LARGEST_EXPONENT_IS_NORMAL
+#define TC_LARGEST_EXPONENT_IS_NORMAL(PRECISION) 0
+#endif
+
+static const unsigned long mask[] =
+{
+ 0x00000000,
+ 0x00000001,
+ 0x00000003,
+ 0x00000007,
+ 0x0000000f,
+ 0x0000001f,
+ 0x0000003f,
+ 0x0000007f,
+ 0x000000ff,
+ 0x000001ff,
+ 0x000003ff,
+ 0x000007ff,
+ 0x00000fff,
+ 0x00001fff,
+ 0x00003fff,
+ 0x00007fff,
+ 0x0000ffff,
+ 0x0001ffff,
+ 0x0003ffff,
+ 0x0007ffff,
+ 0x000fffff,
+ 0x001fffff,
+ 0x003fffff,
+ 0x007fffff,
+ 0x00ffffff,
+ 0x01ffffff,
+ 0x03ffffff,
+ 0x07ffffff,
+ 0x0fffffff,
+ 0x1fffffff,
+ 0x3fffffff,
+ 0x7fffffff,
+ 0xffffffff,
+};
+
+static int bits_left_in_littlenum;
+static int littlenums_left;
+static LITTLENUM_TYPE *littlenum_pointer;
+
+static int
+next_bits (number_of_bits)
+ int number_of_bits;
+{
+ int return_value;
+
+ if (!littlenums_left)
+ return (0);
+ if (number_of_bits >= bits_left_in_littlenum)
+ {
+ return_value = mask[bits_left_in_littlenum] & *littlenum_pointer;
+ number_of_bits -= bits_left_in_littlenum;
+ return_value <<= number_of_bits;
+
+ if (--littlenums_left)
+ {
+ bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
+ --littlenum_pointer;
+ return_value |=
+ (*littlenum_pointer >> bits_left_in_littlenum)
+ & mask[number_of_bits];
+ }
+ }
+ else
+ {
+ bits_left_in_littlenum -= number_of_bits;
+ return_value =
+ mask[number_of_bits] & (*littlenum_pointer >> bits_left_in_littlenum);
+ }
+ return return_value;
+}
+
+/* Num had better be less than LITTLENUM_NUMBER_OF_BITS. */
+
+static void
+unget_bits (num)
+ int num;
+{
+ if (!littlenums_left)
+ {
+ ++littlenum_pointer;
+ ++littlenums_left;
+ bits_left_in_littlenum = num;
+ }
+ else if (bits_left_in_littlenum + num > LITTLENUM_NUMBER_OF_BITS)
+ {
+ bits_left_in_littlenum =
+ num - (LITTLENUM_NUMBER_OF_BITS - bits_left_in_littlenum);
+ ++littlenum_pointer;
+ ++littlenums_left;
+ }
+ else
+ bits_left_in_littlenum += num;
+}
+
+static void
+make_invalid_floating_point_number (words)
+ LITTLENUM_TYPE *words;
+{
+ as_bad (_("cannot create floating-point number"));
+ /* Zero the leftmost bit. */
+ words[0] = (LITTLENUM_TYPE) ((unsigned) -1) >> 1;
+ words[1] = (LITTLENUM_TYPE) -1;
+ words[2] = (LITTLENUM_TYPE) -1;
+ words[3] = (LITTLENUM_TYPE) -1;
+ words[4] = (LITTLENUM_TYPE) -1;
+ words[5] = (LITTLENUM_TYPE) -1;
+}
+
+/* Warning: This returns 16-bit LITTLENUMs. It is up to the caller to
+ figure out any alignment problems and to conspire for the
+ bytes/word to be emitted in the right order. Bigendians beware! */
+
+/* Note that atof-ieee always has X and P precisions enabled. it is up
+ to md_atof to filter them out if the target machine does not support
+ them. */
+
+/* Returns pointer past text consumed. */
+
+char *
+atof_ieee (str, what_kind, words)
+ char *str; /* Text to convert to binary. */
+ int what_kind; /* 'd', 'f', 'g', 'h'. */
+ LITTLENUM_TYPE *words; /* Build the binary here. */
+{
+ /* Extra bits for zeroed low-order bits.
+ The 1st MAX_PRECISION are zeroed, the last contain flonum bits. */
+ static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
+ char *return_value;
+ /* Number of 16-bit words in the format. */
+ int precision;
+ long exponent_bits;
+ FLONUM_TYPE save_gen_flonum;
+
+ /* We have to save the generic_floating_point_number because it
+ contains storage allocation about the array of LITTLENUMs where
+ the value is actually stored. We will allocate our own array of
+ littlenums below, but have to restore the global one on exit. */
+ save_gen_flonum = generic_floating_point_number;
+
+ return_value = str;
+ generic_floating_point_number.low = bits + MAX_PRECISION;
+ generic_floating_point_number.high = NULL;
+ generic_floating_point_number.leader = NULL;
+ generic_floating_point_number.exponent = 0;
+ generic_floating_point_number.sign = '\0';
+
+ /* Use more LittleNums than seems necessary: the highest flonum may
+ have 15 leading 0 bits, so could be useless. */
+
+ memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
+
+ switch (what_kind)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ precision = F_PRECISION;
+ exponent_bits = 8;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ precision = D_PRECISION;
+ exponent_bits = 11;
+ break;
+
+ case 'x':
+ case 'X':
+ case 'e':
+ case 'E':
+ precision = X_PRECISION;
+ exponent_bits = 15;
+ break;
+
+ case 'p':
+ case 'P':
+
+ precision = P_PRECISION;
+ exponent_bits = -1;
+ break;
+
+ default:
+ make_invalid_floating_point_number (words);
+ return (NULL);
+ }
+
+ generic_floating_point_number.high
+ = generic_floating_point_number.low + precision - 1 + GUARD;
+
+ if (atof_generic (&return_value, ".", EXP_CHARS,
+ &generic_floating_point_number))
+ {
+ make_invalid_floating_point_number (words);
+ return (NULL);
+ }
+ gen_to_words (words, precision, exponent_bits);
+
+ /* Restore the generic_floating_point_number's storage alloc (and
+ everything else). */
+ generic_floating_point_number = save_gen_flonum;
+
+ return return_value;
+}
+
+/* Turn generic_floating_point_number into a real float/double/extended. */
+
+int
+gen_to_words (words, precision, exponent_bits)
+ LITTLENUM_TYPE *words;
+ int precision;
+ long exponent_bits;
+{
+ int return_value = 0;
+
+ long exponent_1;
+ long exponent_2;
+ long exponent_3;
+ long exponent_4;
+ int exponent_skippage;
+ LITTLENUM_TYPE word1;
+ LITTLENUM_TYPE *lp;
+ LITTLENUM_TYPE *words_end;
+
+ words_end = words + precision;
+#ifdef TC_M68K
+ if (precision == X_PRECISION)
+ /* On the m68k the extended precision format has a gap of 16 bits
+ between the exponent and the mantissa. */
+ words_end++;
+#endif
+
+ if (generic_floating_point_number.low > generic_floating_point_number.leader)
+ {
+ /* 0.0e0 seen. */
+ if (generic_floating_point_number.sign == '+')
+ words[0] = 0x0000;
+ else
+ words[0] = 0x8000;
+ memset (&words[1], '\0',
+ (words_end - words - 1) * sizeof (LITTLENUM_TYPE));
+ return return_value;
+ }
+
+ /* NaN: Do the right thing. */
+ if (generic_floating_point_number.sign == 0)
+ {
+ if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
+ as_warn ("NaNs are not supported by this target\n");
+ if (precision == F_PRECISION)
+ {
+ words[0] = 0x7fff;
+ words[1] = 0xffff;
+ }
+ else if (precision == X_PRECISION)
+ {
+#ifdef TC_M68K
+ words[0] = 0x7fff;
+ words[1] = 0;
+ words[2] = 0xffff;
+ words[3] = 0xffff;
+ words[4] = 0xffff;
+ words[5] = 0xffff;
+#else /* ! TC_M68K */
+#ifdef TC_I386
+ words[0] = 0xffff;
+ words[1] = 0xc000;
+ words[2] = 0;
+ words[3] = 0;
+ words[4] = 0;
+#else /* ! TC_I386 */
+ abort ();
+#endif /* ! TC_I386 */
+#endif /* ! TC_M68K */
+ }
+ else
+ {
+ words[0] = 0x7fff;
+ words[1] = 0xffff;
+ words[2] = 0xffff;
+ words[3] = 0xffff;
+ }
+ return return_value;
+ }
+ else if (generic_floating_point_number.sign == 'P')
+ {
+ if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
+ as_warn ("Infinities are not supported by this target\n");
+
+ /* +INF: Do the right thing. */
+ if (precision == F_PRECISION)
+ {
+ words[0] = 0x7f80;
+ words[1] = 0;
+ }
+ else if (precision == X_PRECISION)
+ {
+#ifdef TC_M68K
+ words[0] = 0x7fff;
+ words[1] = 0;
+ words[2] = 0;
+ words[3] = 0;
+ words[4] = 0;
+ words[5] = 0;
+#else /* ! TC_M68K */
+#ifdef TC_I386
+ words[0] = 0x7fff;
+ words[1] = 0x8000;
+ words[2] = 0;
+ words[3] = 0;
+ words[4] = 0;
+#else /* ! TC_I386 */
+ abort ();
+#endif /* ! TC_I386 */
+#endif /* ! TC_M68K */
+ }
+ else
+ {
+ words[0] = 0x7ff0;
+ words[1] = 0;
+ words[2] = 0;
+ words[3] = 0;
+ }
+ return return_value;
+ }
+ else if (generic_floating_point_number.sign == 'N')
+ {
+ if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
+ as_warn ("Infinities are not supported by this target\n");
+
+ /* Negative INF. */
+ if (precision == F_PRECISION)
+ {
+ words[0] = 0xff80;
+ words[1] = 0x0;
+ }
+ else if (precision == X_PRECISION)
+ {
+#ifdef TC_M68K
+ words[0] = 0xffff;
+ words[1] = 0;
+ words[2] = 0;
+ words[3] = 0;
+ words[4] = 0;
+ words[5] = 0;
+#else /* ! TC_M68K */
+#ifdef TC_I386
+ words[0] = 0xffff;
+ words[1] = 0x8000;
+ words[2] = 0;
+ words[3] = 0;
+ words[4] = 0;
+#else /* ! TC_I386 */
+ abort ();
+#endif /* ! TC_I386 */
+#endif /* ! TC_M68K */
+ }
+ else
+ {
+ words[0] = 0xfff0;
+ words[1] = 0x0;
+ words[2] = 0x0;
+ words[3] = 0x0;
+ }
+ return return_value;
+ }
+
+ /* The floating point formats we support have:
+ Bit 15 is sign bit.
+ Bits 14:n are excess-whatever exponent.
+ Bits n-1:0 (if any) are most significant bits of fraction.
+ Bits 15:0 of the next word(s) are the next most significant bits.
+
+ So we need: number of bits of exponent, number of bits of
+ mantissa. */
+ bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
+ littlenum_pointer = generic_floating_point_number.leader;
+ littlenums_left = (1
+ + generic_floating_point_number.leader
+ - generic_floating_point_number.low);
+
+ /* Seek (and forget) 1st significant bit. */
+ for (exponent_skippage = 0; !next_bits (1); ++exponent_skippage);;
+ exponent_1 = (generic_floating_point_number.exponent
+ + generic_floating_point_number.leader
+ + 1
+ - generic_floating_point_number.low);
+
+ /* Radix LITTLENUM_RADIX, point just higher than
+ generic_floating_point_number.leader. */
+ exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
+
+ /* Radix 2. */
+ exponent_3 = exponent_2 - exponent_skippage;
+
+ /* Forget leading zeros, forget 1st bit. */
+ exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2);
+
+ /* Offset exponent. */
+ lp = words;
+
+ /* Word 1. Sign, exponent and perhaps high bits. */
+ word1 = ((generic_floating_point_number.sign == '+')
+ ? 0
+ : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
+
+ /* Assume 2's complement integers. */
+ if (exponent_4 <= 0)
+ {
+ int prec_bits;
+ int num_bits;
+
+ unget_bits (1);
+ num_bits = -exponent_4;
+ prec_bits =
+ LITTLENUM_NUMBER_OF_BITS * precision - (exponent_bits + 1 + num_bits);
+#ifdef TC_I386
+ if (precision == X_PRECISION && exponent_bits == 15)
+ {
+ /* On the i386 a denormalized extended precision float is
+ shifted down by one, effectively decreasing the exponent
+ bias by one. */
+ prec_bits -= 1;
+ num_bits += 1;
+ }
+#endif
+
+ if (num_bits >= LITTLENUM_NUMBER_OF_BITS - exponent_bits)
+ {
+ /* Bigger than one littlenum. */
+ num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits;
+ *lp++ = word1;
+ if (num_bits + exponent_bits + 1
+ > precision * LITTLENUM_NUMBER_OF_BITS)
+ {
+ /* Exponent overflow. */
+ make_invalid_floating_point_number (words);
+ return return_value;
+ }
+#ifdef TC_M68K
+ if (precision == X_PRECISION && exponent_bits == 15)
+ *lp++ = 0;
+#endif
+ while (num_bits >= LITTLENUM_NUMBER_OF_BITS)
+ {
+ num_bits -= LITTLENUM_NUMBER_OF_BITS;
+ *lp++ = 0;
+ }
+ if (num_bits)
+ *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - (num_bits));
+ }
+ else
+ {
+ if (precision == X_PRECISION && exponent_bits == 15)
+ {
+ *lp++ = word1;
+#ifdef TC_M68K
+ *lp++ = 0;
+#endif
+ *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - num_bits);
+ }
+ else
+ {
+ word1 |= next_bits ((LITTLENUM_NUMBER_OF_BITS - 1)
+ - (exponent_bits + num_bits));
+ *lp++ = word1;
+ }
+ }
+ while (lp < words_end)
+ *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
+
+ /* Round the mantissa up, but don't change the number. */
+ if (next_bits (1))
+ {
+ --lp;
+ if (prec_bits >= LITTLENUM_NUMBER_OF_BITS)
+ {
+ int n = 0;
+ int tmp_bits;
+
+ n = 0;
+ tmp_bits = prec_bits;
+ while (tmp_bits > LITTLENUM_NUMBER_OF_BITS)
+ {
+ if (lp[n] != (LITTLENUM_TYPE) - 1)
+ break;
+ --n;
+ tmp_bits -= LITTLENUM_NUMBER_OF_BITS;
+ }
+ if (tmp_bits > LITTLENUM_NUMBER_OF_BITS
+ || (lp[n] & mask[tmp_bits]) != mask[tmp_bits]
+ || (prec_bits != (precision * LITTLENUM_NUMBER_OF_BITS
+ - exponent_bits - 1)
+#ifdef TC_I386
+ /* An extended precision float with only the integer
+ bit set would be invalid. That must be converted
+ to the smallest normalized number. */
+ && !(precision == X_PRECISION
+ && prec_bits == (precision * LITTLENUM_NUMBER_OF_BITS
+ - exponent_bits - 2))
+#endif
+ ))
+ {
+ unsigned long carry;
+
+ for (carry = 1; carry && (lp >= words); lp--)
+ {
+ carry = *lp + carry;
+ *lp = carry;
+ carry >>= LITTLENUM_NUMBER_OF_BITS;
+ }
+ }
+ else
+ {
+ /* This is an overflow of the denormal numbers. We
+ need to forget what we have produced, and instead
+ generate the smallest normalized number. */
+ lp = words;
+ word1 = ((generic_floating_point_number.sign == '+')
+ ? 0
+ : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
+ word1 |= (1
+ << ((LITTLENUM_NUMBER_OF_BITS - 1)
+ - exponent_bits));
+ *lp++ = word1;
+#ifdef TC_I386
+ /* Set the integer bit in the extended precision format.
+ This cannot happen on the m68k where the mantissa
+ just overflows into the integer bit above. */
+ if (precision == X_PRECISION)
+ *lp++ = 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
+#endif
+ while (lp < words_end)
+ *lp++ = 0;
+ }
+ }
+ else
+ *lp += 1;
+ }
+
+ return return_value;
+ }
+ else if ((unsigned long) exponent_4 > mask[exponent_bits]
+ || (! TC_LARGEST_EXPONENT_IS_NORMAL (precision)
+ && (unsigned long) exponent_4 == mask[exponent_bits]))
+ {
+ /* Exponent overflow. Lose immediately. */
+
+ /* We leave return_value alone: admit we read the
+ number, but return a floating exception
+ because we can't encode the number. */
+ make_invalid_floating_point_number (words);
+ return return_value;
+ }
+ else
+ {
+ word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits))
+ | next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits);
+ }
+
+ *lp++ = word1;
+
+ /* X_PRECISION is special: on the 68k, it has 16 bits of zero in the
+ middle. Either way, it is then followed by a 1 bit. */
+ if (exponent_bits == 15 && precision == X_PRECISION)
+ {
+#ifdef TC_M68K
+ *lp++ = 0;
+#endif
+ *lp++ = (1 << (LITTLENUM_NUMBER_OF_BITS - 1)
+ | next_bits (LITTLENUM_NUMBER_OF_BITS - 1));
+ }
+
+ /* The rest of the words are just mantissa bits. */
+ while (lp < words_end)
+ *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
+
+ if (next_bits (1))
+ {
+ unsigned long carry;
+ /* Since the NEXT bit is a 1, round UP the mantissa.
+ The cunning design of these hidden-1 floats permits
+ us to let the mantissa overflow into the exponent, and
+ it 'does the right thing'. However, we lose if the
+ highest-order bit of the lowest-order word flips.
+ Is that clear? */
+
+ /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
+ Please allow at least 1 more bit in carry than is in a LITTLENUM.
+ We need that extra bit to hold a carry during a LITTLENUM carry
+ propagation. Another extra bit (kept 0) will assure us that we
+ don't get a sticky sign bit after shifting right, and that
+ permits us to propagate the carry without any masking of bits.
+ #endif */
+ for (carry = 1, lp--; carry; lp--)
+ {
+ carry = *lp + carry;
+ *lp = carry;
+ carry >>= LITTLENUM_NUMBER_OF_BITS;
+ if (lp == words)
+ break;
+ }
+ if (precision == X_PRECISION && exponent_bits == 15)
+ {
+ /* Extended precision numbers have an explicit integer bit
+ that we may have to restore. */
+ if (lp == words)
+ {
+#ifdef TC_M68K
+ /* On the m68k there is a gap of 16 bits. We must
+ explicitly propagate the carry into the exponent. */
+ words[0] += words[1];
+ words[1] = 0;
+ lp++;
+#endif
+ /* Put back the integer bit. */
+ lp[1] |= 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
+ }
+ }
+ if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
+ {
+ /* We leave return_value alone: admit we read the number,
+ but return a floating exception because we can't encode
+ the number. */
+ *words &= ~(1 << (LITTLENUM_NUMBER_OF_BITS - 1));
+#if 0
+ make_invalid_floating_point_number (words);
+ return return_value;
+#endif
+ }
+ }
+ return return_value;
+}
+
+#if 0
+/* Unused. */
+/* This routine is a real kludge. Someone really should do it better,
+ but I'm too lazy, and I don't understand this stuff all too well
+ anyway. (JF) */
+
+static void
+int_to_gen (x)
+ long x;
+{
+ char buf[20];
+ char *bufp;
+
+ sprintf (buf, "%ld", x);
+ bufp = &buf[0];
+ if (atof_generic (&bufp, ".", EXP_CHARS, &generic_floating_point_number))
+ as_bad (_("Error converting number to floating point (Exponent overflow?)"));
+}
+#endif
+
+#ifdef TEST
+char *
+print_gen (gen)
+ FLONUM_TYPE *gen;
+{
+ FLONUM_TYPE f;
+ LITTLENUM_TYPE arr[10];
+ double dv;
+ float fv;
+ static char sbuf[40];
+
+ if (gen)
+ {
+ f = generic_floating_point_number;
+ generic_floating_point_number = *gen;
+ }
+ gen_to_words (&arr[0], 4, 11);
+ memcpy (&dv, &arr[0], sizeof (double));
+ sprintf (sbuf, "%x %x %x %x %.14G ", arr[0], arr[1], arr[2], arr[3], dv);
+ gen_to_words (&arr[0], 2, 8);
+ memcpy (&fv, &arr[0], sizeof (float));
+ sprintf (sbuf + strlen (sbuf), "%x %x %.12g\n", arr[0], arr[1], fv);
+
+ if (gen)
+ generic_floating_point_number = f;
+
+ return (sbuf);
+}
+
+#endif
diff --git a/x/binutils/gas/config/atof-vax.c b/x/binutils/gas/config/atof-vax.c
new file mode 100644
index 0000000..7c9f04e
--- /dev/null
+++ b/x/binutils/gas/config/atof-vax.c
@@ -0,0 +1,517 @@
+/* atof_vax.c - turn a Flonum into a VAX floating point number
+ Copyright 1987, 1992, 1993, 1995, 1997, 1999, 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+
+static int atof_vax_sizeof PARAMS ((int));
+static int next_bits PARAMS ((int));
+static void make_invalid_floating_point_number PARAMS ((LITTLENUM_TYPE *));
+static int what_kind_of_float PARAMS ((int, int *, long *));
+static char *atof_vax PARAMS ((char *, int, LITTLENUM_TYPE *));
+
+/* Precision in LittleNums. */
+#define MAX_PRECISION (8)
+#define H_PRECISION (8)
+#define G_PRECISION (4)
+#define D_PRECISION (4)
+#define F_PRECISION (2)
+
+/* Length in LittleNums of guard bits. */
+#define GUARD (2)
+
+int flonum_gen2vax PARAMS ((int format_letter, FLONUM_TYPE * f,
+ LITTLENUM_TYPE * words));
+
+/* Number of chars in flonum type 'letter'. */
+static int
+atof_vax_sizeof (letter)
+ int letter;
+{
+ int return_value;
+
+ /*
+ * Permitting uppercase letters is probably a bad idea.
+ * Please use only lower-cased letters in case the upper-cased
+ * ones become unsupported!
+ */
+ switch (letter)
+ {
+ case 'f':
+ case 'F':
+ return_value = 4;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'g':
+ case 'G':
+ return_value = 8;
+ break;
+
+ case 'h':
+ case 'H':
+ return_value = 16;
+ break;
+
+ default:
+ return_value = 0;
+ break;
+ }
+ return (return_value);
+} /* atof_vax_sizeof */
+
+static const long mask[] =
+{
+ 0x00000000,
+ 0x00000001,
+ 0x00000003,
+ 0x00000007,
+ 0x0000000f,
+ 0x0000001f,
+ 0x0000003f,
+ 0x0000007f,
+ 0x000000ff,
+ 0x000001ff,
+ 0x000003ff,
+ 0x000007ff,
+ 0x00000fff,
+ 0x00001fff,
+ 0x00003fff,
+ 0x00007fff,
+ 0x0000ffff,
+ 0x0001ffff,
+ 0x0003ffff,
+ 0x0007ffff,
+ 0x000fffff,
+ 0x001fffff,
+ 0x003fffff,
+ 0x007fffff,
+ 0x00ffffff,
+ 0x01ffffff,
+ 0x03ffffff,
+ 0x07ffffff,
+ 0x0fffffff,
+ 0x1fffffff,
+ 0x3fffffff,
+ 0x7fffffff,
+ 0xffffffff
+};
+
+
+/* Shared between flonum_gen2vax and next_bits */
+static int bits_left_in_littlenum;
+static LITTLENUM_TYPE *littlenum_pointer;
+static LITTLENUM_TYPE *littlenum_end;
+
+static int
+next_bits (number_of_bits)
+ int number_of_bits;
+{
+ int return_value;
+
+ if (littlenum_pointer < littlenum_end)
+ return 0;
+ if (number_of_bits >= bits_left_in_littlenum)
+ {
+ return_value = mask[bits_left_in_littlenum] & *littlenum_pointer;
+ number_of_bits -= bits_left_in_littlenum;
+ return_value <<= number_of_bits;
+ bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
+ littlenum_pointer--;
+ if (littlenum_pointer >= littlenum_end)
+ return_value |= ((*littlenum_pointer) >> (bits_left_in_littlenum)) & mask[number_of_bits];
+ }
+ else
+ {
+ bits_left_in_littlenum -= number_of_bits;
+ return_value = mask[number_of_bits] & ((*littlenum_pointer) >> bits_left_in_littlenum);
+ }
+ return (return_value);
+}
+
+static void
+make_invalid_floating_point_number (words)
+ LITTLENUM_TYPE *words;
+{
+ *words = 0x8000; /* Floating Reserved Operand Code */
+}
+
+static int /* 0 means letter is OK. */
+what_kind_of_float (letter, precisionP, exponent_bitsP)
+ int letter; /* In: lowercase please. What kind of float? */
+ int *precisionP; /* Number of 16-bit words in the float. */
+ long *exponent_bitsP; /* Number of exponent bits. */
+{
+ int retval; /* 0: OK. */
+
+ retval = 0;
+ switch (letter)
+ {
+ case 'f':
+ *precisionP = F_PRECISION;
+ *exponent_bitsP = 8;
+ break;
+
+ case 'd':
+ *precisionP = D_PRECISION;
+ *exponent_bitsP = 8;
+ break;
+
+ case 'g':
+ *precisionP = G_PRECISION;
+ *exponent_bitsP = 11;
+ break;
+
+ case 'h':
+ *precisionP = H_PRECISION;
+ *exponent_bitsP = 15;
+ break;
+
+ default:
+ retval = 69;
+ break;
+ }
+ return (retval);
+}
+
+/***********************************************************************\
+ * *
+ * Warning: this returns 16-bit LITTLENUMs, because that is *
+ * what the VAX thinks in. It is up to the caller to figure *
+ * out any alignment problems and to conspire for the bytes/word *
+ * to be emitted in the right order. Bigendians beware! *
+ * *
+ \***********************************************************************/
+
+static char * /* Return pointer past text consumed. */
+atof_vax (str, what_kind, words)
+ char *str; /* Text to convert to binary. */
+ int what_kind; /* 'd', 'f', 'g', 'h' */
+ LITTLENUM_TYPE *words; /* Build the binary here. */
+{
+ FLONUM_TYPE f;
+ LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
+ /* Extra bits for zeroed low-order bits. */
+ /* The 1st MAX_PRECISION are zeroed, */
+ /* the last contain flonum bits. */
+ char *return_value;
+ int precision; /* Number of 16-bit words in the format. */
+ long exponent_bits;
+
+ return_value = str;
+ f.low = bits + MAX_PRECISION;
+ f.high = NULL;
+ f.leader = NULL;
+ f.exponent = 0;
+ f.sign = '\0';
+
+ if (what_kind_of_float (what_kind, &precision, &exponent_bits))
+ {
+ return_value = NULL; /* We lost. */
+ make_invalid_floating_point_number (words);
+ }
+
+ if (return_value)
+ {
+ memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
+
+ /* Use more LittleNums than seems */
+ /* necessary: the highest flonum may have */
+ /* 15 leading 0 bits, so could be useless. */
+ f.high = f.low + precision - 1 + GUARD;
+
+ if (atof_generic (&return_value, ".", "eE", &f))
+ {
+ make_invalid_floating_point_number (words);
+ return_value = NULL; /* we lost */
+ }
+ else
+ {
+ if (flonum_gen2vax (what_kind, &f, words))
+ {
+ return_value = NULL;
+ }
+ }
+ }
+ return (return_value);
+} /* atof_vax() */
+
+/*
+ * In: a flonum, a vax floating point format.
+ * Out: a vax floating-point bit pattern.
+ */
+
+int /* 0: OK. */
+flonum_gen2vax (format_letter, f, words)
+ int format_letter; /* One of 'd' 'f' 'g' 'h'. */
+ FLONUM_TYPE *f;
+ LITTLENUM_TYPE *words; /* Deliver answer here. */
+{
+ LITTLENUM_TYPE *lp;
+ int precision;
+ long exponent_bits;
+ int return_value; /* 0 == OK. */
+
+ return_value = what_kind_of_float (format_letter, &precision, &exponent_bits);
+
+ if (return_value != 0)
+ {
+ make_invalid_floating_point_number (words);
+ }
+ else
+ {
+ if (f->low > f->leader)
+ {
+ /* 0.0e0 seen. */
+ memset (words, '\0', sizeof (LITTLENUM_TYPE) * precision);
+ }
+ else
+ {
+ long exponent_1;
+ long exponent_2;
+ long exponent_3;
+ long exponent_4;
+ int exponent_skippage;
+ LITTLENUM_TYPE word1;
+
+ /* JF: Deal with new Nan, +Inf and -Inf codes */
+ if (f->sign != '-' && f->sign != '+')
+ {
+ make_invalid_floating_point_number (words);
+ return return_value;
+ }
+ /*
+ * All vaxen floating_point formats (so far) have:
+ * Bit 15 is sign bit.
+ * Bits 14:n are excess-whatever exponent.
+ * Bits n-1:0 (if any) are most significant bits of fraction.
+ * Bits 15:0 of the next word are the next most significant bits.
+ * And so on for each other word.
+ *
+ * All this to be compatible with a KF11?? (Which is still faster
+ * than lots of vaxen I can think of, but it also has higher
+ * maintenance costs ... sigh).
+ *
+ * So we need: number of bits of exponent, number of bits of
+ * mantissa.
+ */
+
+#ifdef NEVER /******* This zeroing seems redundant - Dean 3may86 **********/
+ /*
+ * No matter how few bits we got back from the atof()
+ * routine, add enough zero littlenums so the rest of the
+ * code won't run out of "significant" bits in the mantissa.
+ */
+ {
+ LITTLENUM_TYPE *ltp;
+ for (ltp = f->leader + 1;
+ ltp <= f->low + precision;
+ ltp++)
+ {
+ *ltp = 0;
+ }
+ }
+#endif
+
+ bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
+ littlenum_pointer = f->leader;
+ littlenum_end = f->low;
+ /* Seek (and forget) 1st significant bit */
+ for (exponent_skippage = 0;
+ !next_bits (1);
+ exponent_skippage++);;
+
+ exponent_1 = f->exponent + f->leader + 1 - f->low;
+ /* Radix LITTLENUM_RADIX, point just higher than f->leader. */
+ exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
+ /* Radix 2. */
+ exponent_3 = exponent_2 - exponent_skippage;
+ /* Forget leading zeros, forget 1st bit. */
+ exponent_4 = exponent_3 + (1 << (exponent_bits - 1));
+ /* Offset exponent. */
+
+ if (exponent_4 & ~mask[exponent_bits])
+ {
+ /*
+ * Exponent overflow. Lose immediately.
+ */
+
+ make_invalid_floating_point_number (words);
+
+ /*
+ * We leave return_value alone: admit we read the
+ * number, but return a floating exception
+ * because we can't encode the number.
+ */
+ }
+ else
+ {
+ lp = words;
+
+ /* Word 1. Sign, exponent and perhaps high bits. */
+ /* Assume 2's complement integers. */
+ word1 = (((exponent_4 & mask[exponent_bits]) << (15 - exponent_bits))
+ | ((f->sign == '+') ? 0 : 0x8000)
+ | next_bits (15 - exponent_bits));
+ *lp++ = word1;
+
+ /* The rest of the words are just mantissa bits. */
+ for (; lp < words + precision; lp++)
+ {
+ *lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
+ }
+
+ if (next_bits (1))
+ {
+ /*
+ * Since the NEXT bit is a 1, round UP the mantissa.
+ * The cunning design of these hidden-1 floats permits
+ * us to let the mantissa overflow into the exponent, and
+ * it 'does the right thing'. However, we lose if the
+ * highest-order bit of the lowest-order word flips.
+ * Is that clear?
+ */
+
+ unsigned long carry;
+
+ /*
+ #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
+ Please allow at least 1 more bit in carry than is in a LITTLENUM.
+ We need that extra bit to hold a carry during a LITTLENUM carry
+ propagation. Another extra bit (kept 0) will assure us that we
+ don't get a sticky sign bit after shifting right, and that
+ permits us to propagate the carry without any masking of bits.
+ #endif
+ */
+ for (carry = 1, lp--;
+ carry && (lp >= words);
+ lp--)
+ {
+ carry = *lp + carry;
+ *lp = carry;
+ carry >>= LITTLENUM_NUMBER_OF_BITS;
+ }
+
+ if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
+ {
+ make_invalid_floating_point_number (words);
+ /*
+ * We leave return_value alone: admit we read the
+ * number, but return a floating exception
+ * because we can't encode the number.
+ */
+ }
+ } /* if (we needed to round up) */
+ } /* if (exponent overflow) */
+ } /* if (0.0e0) */
+ } /* if (float_type was OK) */
+ return (return_value);
+} /* flonum_gen2vax() */
+
+/* JF this used to be in vax.c but this looks like a better place for it */
+
+/*
+ * md_atof()
+ *
+ * In: input_line_pointer->the 1st character of a floating-point
+ * number.
+ * 1 letter denoting the type of statement that wants a
+ * binary floating point number returned.
+ * Address of where to build floating point literal.
+ * Assumed to be 'big enough'.
+ * Address of where to return size of literal (in chars).
+ *
+ * Out: Input_line_pointer->of next char after floating number.
+ * Error message, or 0.
+ * Floating point literal.
+ * Number of chars we used for the literal.
+ */
+
+#define MAXIMUM_NUMBER_OF_LITTLENUMS (8) /* For .hfloats. */
+
+char *
+md_atof (what_statement_type, literalP, sizeP)
+ int what_statement_type;
+ char *literalP;
+ int *sizeP;
+{
+ LITTLENUM_TYPE words[MAXIMUM_NUMBER_OF_LITTLENUMS];
+ register char kind_of_float;
+ register int number_of_chars;
+ register LITTLENUM_TYPE *littlenumP;
+
+ switch (what_statement_type)
+ {
+ case 'F': /* .float */
+ case 'f': /* .ffloat */
+ kind_of_float = 'f';
+ break;
+
+ case 'D': /* .double */
+ case 'd': /* .dfloat */
+ kind_of_float = 'd';
+ break;
+
+ case 'g': /* .gfloat */
+ kind_of_float = 'g';
+ break;
+
+ case 'h': /* .hfloat */
+ kind_of_float = 'h';
+ break;
+
+ default:
+ kind_of_float = 0;
+ break;
+ };
+
+ if (kind_of_float)
+ {
+ register LITTLENUM_TYPE *limit;
+
+ input_line_pointer = atof_vax (input_line_pointer,
+ kind_of_float,
+ words);
+ /*
+ * The atof_vax() builds up 16-bit numbers.
+ * Since the assembler may not be running on
+ * a little-endian machine, be very careful about
+ * converting words to chars.
+ */
+ number_of_chars = atof_vax_sizeof (kind_of_float);
+ know (number_of_chars <= MAXIMUM_NUMBER_OF_LITTLENUMS * sizeof (LITTLENUM_TYPE));
+ limit = words + (number_of_chars / sizeof (LITTLENUM_TYPE));
+ for (littlenumP = words; littlenumP < limit; littlenumP++)
+ {
+ md_number_to_chars (literalP, *littlenumP, sizeof (LITTLENUM_TYPE));
+ literalP += sizeof (LITTLENUM_TYPE);
+ };
+ }
+ else
+ {
+ number_of_chars = 0;
+ };
+
+ *sizeP = number_of_chars;
+ return kind_of_float ? NULL : _("Bad call to md_atof()");
+}
+
+/* end of atof-vax.c */
diff --git a/x/binutils/gas/config/e-i386aout.c b/x/binutils/gas/config/e-i386aout.c
new file mode 100644
index 0000000..f8435ab
--- /dev/null
+++ b/x/binutils/gas/config/e-i386aout.c
@@ -0,0 +1,19 @@
+#include "as.h"
+#include "emul.h"
+
+static const char *i386aout_bfd_name PARAMS ((void));
+
+static const char *
+i386aout_bfd_name ()
+{
+ abort ();
+ return NULL;
+}
+
+#define emul_bfd_name i386aout_bfd_name
+#define emul_format &aout_format_ops
+
+#define emul_name "i386aout"
+#define emul_struct_name i386aout
+#define emul_default_endian 0
+#include "emul-target.h"
diff --git a/x/binutils/gas/config/e-i386coff.c b/x/binutils/gas/config/e-i386coff.c
new file mode 100644
index 0000000..f6510a4
--- /dev/null
+++ b/x/binutils/gas/config/e-i386coff.c
@@ -0,0 +1,19 @@
+#include "as.h"
+#include "emul.h"
+
+static const char *i386coff_bfd_name PARAMS ((void));
+
+static const char *
+i386coff_bfd_name ()
+{
+ abort ();
+ return NULL;
+}
+
+#define emul_bfd_name i386coff_bfd_name
+#define emul_format &coff_format_ops
+
+#define emul_name "i386coff"
+#define emul_struct_name i386coff
+#define emul_default_endian 0
+#include "emul-target.h"
diff --git a/x/binutils/gas/config/e-i386elf.c b/x/binutils/gas/config/e-i386elf.c
new file mode 100644
index 0000000..e11fc3d
--- /dev/null
+++ b/x/binutils/gas/config/e-i386elf.c
@@ -0,0 +1,19 @@
+#include "as.h"
+#include "emul.h"
+
+static const char *i386elf_bfd_name PARAMS ((void));
+
+static const char *
+i386elf_bfd_name ()
+{
+ abort ();
+ return NULL;
+}
+
+#define emul_bfd_name i386elf_bfd_name
+#define emul_format &elf_format_ops
+
+#define emul_name "i386elf"
+#define emul_struct_name i386elf
+#define emul_default_endian 0
+#include "emul-target.h"
diff --git a/x/binutils/gas/config/e-mipsecoff.c b/x/binutils/gas/config/e-mipsecoff.c
new file mode 100644
index 0000000..be2f71b
--- /dev/null
+++ b/x/binutils/gas/config/e-mipsecoff.c
@@ -0,0 +1,37 @@
+#include "as.h"
+#include "emul.h"
+
+static const char *mipsecoff_bfd_name PARAMS ((void));
+
+static const char *
+mipsecoff_bfd_name ()
+{
+ abort ();
+ return NULL;
+}
+
+#define emul_bfd_name mipsecoff_bfd_name
+#define emul_format &ecoff_format_ops
+
+#define emul_name "mipsbecoff"
+#define emul_struct_name mipsbecoff
+#define emul_default_endian 1
+#include "emul-target.h"
+
+#undef emul_name
+#undef emul_struct_name
+#undef emul_default_endian
+
+#define emul_name "mipslecoff"
+#define emul_struct_name mipslecoff
+#define emul_default_endian 0
+#include "emul-target.h"
+
+#undef emul_name
+#undef emul_struct_name
+#undef emul_default_endian
+
+#define emul_name "mipsecoff"
+#define emul_struct_name mipsecoff
+#define emul_default_endian 2
+#include "emul-target.h"
diff --git a/x/binutils/gas/config/e-mipself.c b/x/binutils/gas/config/e-mipself.c
new file mode 100644
index 0000000..eea72f5
--- /dev/null
+++ b/x/binutils/gas/config/e-mipself.c
@@ -0,0 +1,37 @@
+#include "as.h"
+#include "emul.h"
+
+static const char *mipself_bfd_name PARAMS ((void));
+
+static const char *
+mipself_bfd_name ()
+{
+ abort ();
+ return NULL;
+}
+
+#define emul_bfd_name mipself_bfd_name
+#define emul_format &elf_format_ops
+
+#define emul_name "mipsbelf"
+#define emul_struct_name mipsbelf
+#define emul_default_endian 1
+#include "emul-target.h"
+
+#undef emul_name
+#undef emul_struct_name
+#undef emul_default_endian
+
+#define emul_name "mipslelf"
+#define emul_struct_name mipslelf
+#define emul_default_endian 0
+#include "emul-target.h"
+
+#undef emul_name
+#undef emul_struct_name
+#undef emul_default_endian
+
+#define emul_name "mipself"
+#define emul_struct_name mipself
+#define emul_default_endian 2
+#include "emul-target.h"
diff --git a/x/binutils/gas/config/i386coff.mt b/x/binutils/gas/config/i386coff.mt
new file mode 100644
index 0000000..efda833
--- /dev/null
+++ b/x/binutils/gas/config/i386coff.mt
@@ -0,0 +1 @@
+TDEFINES=-DI386COFF
diff --git a/x/binutils/gas/config/itbl-mips.h b/x/binutils/gas/config/itbl-mips.h
new file mode 100644
index 0000000..8ecb9ec
--- /dev/null
+++ b/x/binutils/gas/config/itbl-mips.h
@@ -0,0 +1,47 @@
+
+/* itbl-mips.h
+
+ Copyright 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Defines for Mips itbl cop support */
+
+#include "opcode/mips.h"
+
+/* Values for processors will be from 0 to NUMBER_OF_PROCESSORS-1 */
+#define NUMBER_OF_PROCESSORS 4
+#define MAX_BITPOS 31
+
+/* Mips specifics */
+#define MIPS_OPCODE_COP0 (0x21) /* COPz+CO, bits 31-25: 0100zz1 */
+#define MIPS_ENCODE_COP_NUM(z) ((MIPS_OPCODE_COP0|z<<1)<<25)
+#define MIPS_IS_COP_INSN(insn) ((MIPS_OPCODE_COP0&(insn>>25)) \
+ == MIPS_OPCODE_COP0)
+#define MIPS_DECODE_COP_NUM(insn) ((~MIPS_OPCODE_COP0&(insn>>25))>>1)
+#define MIPS_DECODE_COP_COFUN(insn) ((~MIPS_ENCODE_COP_NUM(3))&(insn))
+
+/* definitions required by generic code */
+#define ITBL_IS_INSN(insn) MIPS_IS_COP_INSN(insn)
+#define ITBL_DECODE_PNUM(insn) MIPS_DECODE_COP_NUM(insn)
+#define ITBL_ENCODE_PNUM(pnum) MIPS_ENCODE_COP_NUM(pnum)
+
+#define ITBL_OPCODE_STRUCT mips_opcode
+#define ITBL_OPCODES mips_opcodes
+#define ITBL_NUM_OPCODES NUMOPCODES
+#define ITBL_NUM_MACROS M_NUM_MACROS
diff --git a/x/binutils/gas/config/obj-aout.c b/x/binutils/gas/config/obj-aout.c
new file mode 100644
index 0000000..6e5fd29
--- /dev/null
+++ b/x/binutils/gas/config/obj-aout.c
@@ -0,0 +1,707 @@
+/* a.out object file format
+ Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000,
+ 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2,
+or (at your option) any later version.
+
+GAS is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#define OBJ_HEADER "obj-aout.h"
+
+#include "as.h"
+#ifdef BFD_ASSEMBLER
+#undef NO_RELOC
+#include "aout/aout64.h"
+#endif
+#include "obstack.h"
+
+#ifndef BFD_ASSEMBLER
+/* in: segT out: N_TYPE bits */
+const short seg_N_TYPE[] =
+{
+ N_ABS,
+ N_TEXT,
+ N_DATA,
+ N_BSS,
+ N_UNDF, /* unknown */
+ N_UNDF, /* error */
+ N_UNDF, /* expression */
+ N_UNDF, /* debug */
+ N_UNDF, /* ntv */
+ N_UNDF, /* ptv */
+ N_REGISTER, /* register */
+};
+
+const segT N_TYPE_seg[N_TYPE + 2] =
+{ /* N_TYPE == 0x1E = 32-2 */
+ SEG_UNKNOWN, /* N_UNDF == 0 */
+ SEG_GOOF,
+ SEG_ABSOLUTE, /* N_ABS == 2 */
+ SEG_GOOF,
+ SEG_TEXT, /* N_TEXT == 4 */
+ SEG_GOOF,
+ SEG_DATA, /* N_DATA == 6 */
+ SEG_GOOF,
+ SEG_BSS, /* N_BSS == 8 */
+ SEG_GOOF,
+ SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
+ SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
+ SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
+ SEG_REGISTER, /* dummy N_REGISTER for regs = 30 */
+ SEG_GOOF,
+};
+#endif
+
+static void obj_aout_line PARAMS ((int));
+static void obj_aout_weak PARAMS ((int));
+static void obj_aout_type PARAMS ((int));
+
+const pseudo_typeS aout_pseudo_table[] =
+{
+ {"line", obj_aout_line, 0}, /* source code line number */
+ {"ln", obj_aout_line, 0}, /* coff line number that we use anyway */
+
+ {"weak", obj_aout_weak, 0}, /* mark symbol as weak. */
+
+ {"type", obj_aout_type, 0},
+
+ /* coff debug pseudos (ignored) */
+ {"def", s_ignore, 0},
+ {"dim", s_ignore, 0},
+ {"endef", s_ignore, 0},
+ {"ident", s_ignore, 0},
+ {"line", s_ignore, 0},
+ {"ln", s_ignore, 0},
+ {"scl", s_ignore, 0},
+ {"size", s_ignore, 0},
+ {"tag", s_ignore, 0},
+ {"val", s_ignore, 0},
+ {"version", s_ignore, 0},
+
+ {"optim", s_ignore, 0}, /* For sun386i cc (?) */
+
+ /* other stuff */
+ {"ABORT", s_abort, 0},
+
+ {NULL, NULL, 0} /* end sentinel */
+}; /* aout_pseudo_table */
+
+#ifdef BFD_ASSEMBLER
+
+void
+obj_aout_frob_symbol (sym, punt)
+ symbolS *sym;
+ int *punt ATTRIBUTE_UNUSED;
+{
+ flagword flags;
+ asection *sec;
+ int desc, type, other;
+
+ flags = symbol_get_bfdsym (sym)->flags;
+ desc = aout_symbol (symbol_get_bfdsym (sym))->desc;
+ type = aout_symbol (symbol_get_bfdsym (sym))->type;
+ other = aout_symbol (symbol_get_bfdsym (sym))->other;
+ sec = S_GET_SEGMENT (sym);
+
+ /* Only frob simple symbols this way right now. */
+ if (! (type & ~ (N_TYPE | N_EXT)))
+ {
+ if (type == (N_UNDF | N_EXT)
+ && sec == &bfd_abs_section)
+ {
+ sec = bfd_und_section_ptr;
+ S_SET_SEGMENT (sym, sec);
+ }
+
+ if ((type & N_TYPE) != N_INDR
+ && (type & N_TYPE) != N_SETA
+ && (type & N_TYPE) != N_SETT
+ && (type & N_TYPE) != N_SETD
+ && (type & N_TYPE) != N_SETB
+ && type != N_WARNING
+ && (sec == &bfd_abs_section
+ || sec == &bfd_und_section))
+ return;
+ if (flags & BSF_EXPORT)
+ type |= N_EXT;
+
+ switch (type & N_TYPE)
+ {
+ case N_SETA:
+ case N_SETT:
+ case N_SETD:
+ case N_SETB:
+ /* Set the debugging flag for constructor symbols so that
+ BFD leaves them alone. */
+ symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
+
+ /* You can't put a common symbol in a set. The way a set
+ element works is that the symbol has a definition and a
+ name, and the linker adds the definition to the set of
+ that name. That does not work for a common symbol,
+ because the linker can't tell which common symbol the
+ user means. FIXME: Using as_bad here may be
+ inappropriate, since the user may want to force a
+ particular type without regard to the semantics of sets;
+ on the other hand, we certainly don't want anybody to be
+ mislead into thinking that their code will work. */
+ if (S_IS_COMMON (sym))
+ as_bad (_("Attempt to put a common symbol into set %s"),
+ S_GET_NAME (sym));
+ /* Similarly, you can't put an undefined symbol in a set. */
+ else if (! S_IS_DEFINED (sym))
+ as_bad (_("Attempt to put an undefined symbol into set %s"),
+ S_GET_NAME (sym));
+
+ break;
+ case N_INDR:
+ /* Put indirect symbols in the indirect section. */
+ S_SET_SEGMENT (sym, bfd_ind_section_ptr);
+ symbol_get_bfdsym (sym)->flags |= BSF_INDIRECT;
+ if (type & N_EXT)
+ {
+ symbol_get_bfdsym (sym)->flags |= BSF_EXPORT;
+ symbol_get_bfdsym (sym)->flags &=~ BSF_LOCAL;
+ }
+ break;
+ case N_WARNING:
+ /* Mark warning symbols. */
+ symbol_get_bfdsym (sym)->flags |= BSF_WARNING;
+ break;
+ }
+ }
+ else
+ {
+ symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
+ }
+
+ aout_symbol (symbol_get_bfdsym (sym))->type = type;
+
+ /* Double check weak symbols. */
+ if (S_IS_WEAK (sym))
+ {
+ if (S_IS_COMMON (sym))
+ as_bad (_("Symbol `%s' can not be both weak and common"),
+ S_GET_NAME (sym));
+ }
+}
+
+void
+obj_aout_frob_file_before_fix ()
+{
+ /* Relocation processing may require knowing the VMAs of the sections.
+ Since writing to a section will cause the BFD back end to compute the
+ VMAs, fake it out here.... */
+ bfd_byte b = 0;
+ bfd_boolean x = TRUE;
+ if (bfd_section_size (stdoutput, text_section) != 0)
+ {
+ x = bfd_set_section_contents (stdoutput, text_section, &b, (file_ptr) 0,
+ (bfd_size_type) 1);
+ }
+ else if (bfd_section_size (stdoutput, data_section) != 0)
+ {
+ x = bfd_set_section_contents (stdoutput, data_section, &b, (file_ptr) 0,
+ (bfd_size_type) 1);
+ }
+ assert (x);
+}
+
+#else /* ! BFD_ASSEMBLER */
+
+/* Relocation. */
+
+/*
+ * emit_relocations()
+ *
+ * Crawl along a fixS chain. Emit the segment's relocations.
+ */
+void
+obj_emit_relocations (where, fixP, segment_address_in_file)
+ char **where;
+ fixS *fixP; /* Fixup chain for this segment. */
+ relax_addressT segment_address_in_file;
+{
+ for (; fixP; fixP = fixP->fx_next)
+ if (fixP->fx_done == 0)
+ {
+ symbolS *sym;
+
+ sym = fixP->fx_addsy;
+ while (sym->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
+ sym = sym->sy_value.X_add_symbol;
+ fixP->fx_addsy = sym;
+
+ if (! sym->sy_resolved && ! S_IS_DEFINED (sym))
+ {
+ char *file;
+ unsigned int line;
+
+ if (expr_symbol_where (sym, &file, &line))
+ as_bad_where (file, line, _("unresolved relocation"));
+ else
+ as_bad (_("bad relocation: symbol `%s' not in symbol table"),
+ S_GET_NAME (sym));
+ }
+
+ tc_aout_fix_to_chars (*where, fixP, segment_address_in_file);
+ *where += md_reloc_size;
+ }
+}
+
+#ifndef obj_header_append
+/* Aout file generation & utilities */
+void
+obj_header_append (where, headers)
+ char **where;
+ object_headers *headers;
+{
+ tc_headers_hook (headers);
+
+#ifdef CROSS_COMPILE
+ md_number_to_chars (*where, headers->header.a_info, sizeof (headers->header.a_info));
+ *where += sizeof (headers->header.a_info);
+ md_number_to_chars (*where, headers->header.a_text, sizeof (headers->header.a_text));
+ *where += sizeof (headers->header.a_text);
+ md_number_to_chars (*where, headers->header.a_data, sizeof (headers->header.a_data));
+ *where += sizeof (headers->header.a_data);
+ md_number_to_chars (*where, headers->header.a_bss, sizeof (headers->header.a_bss));
+ *where += sizeof (headers->header.a_bss);
+ md_number_to_chars (*where, headers->header.a_syms, sizeof (headers->header.a_syms));
+ *where += sizeof (headers->header.a_syms);
+ md_number_to_chars (*where, headers->header.a_entry, sizeof (headers->header.a_entry));
+ *where += sizeof (headers->header.a_entry);
+ md_number_to_chars (*where, headers->header.a_trsize, sizeof (headers->header.a_trsize));
+ *where += sizeof (headers->header.a_trsize);
+ md_number_to_chars (*where, headers->header.a_drsize, sizeof (headers->header.a_drsize));
+ *where += sizeof (headers->header.a_drsize);
+
+#else /* CROSS_COMPILE */
+
+ append (where, (char *) &headers->header, sizeof (headers->header));
+#endif /* CROSS_COMPILE */
+
+}
+#endif /* ! defined (obj_header_append) */
+
+void
+obj_symbol_to_chars (where, symbolP)
+ char **where;
+ symbolS *symbolP;
+{
+ md_number_to_chars ((char *) &(S_GET_OFFSET (symbolP)), S_GET_OFFSET (symbolP), sizeof (S_GET_OFFSET (symbolP)));
+ md_number_to_chars ((char *) &(S_GET_DESC (symbolP)), S_GET_DESC (symbolP), sizeof (S_GET_DESC (symbolP)));
+ md_number_to_chars ((char *) &(symbolP->sy_symbol.n_value), S_GET_VALUE (symbolP), sizeof (symbolP->sy_symbol.n_value));
+
+ append (where, (char *) &symbolP->sy_symbol, sizeof (obj_symbol_type));
+}
+
+void
+obj_emit_symbols (where, symbol_rootP)
+ char **where;
+ symbolS *symbol_rootP;
+{
+ symbolS *symbolP;
+
+ /* Emit all symbols left in the symbol chain. */
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ {
+ /* Used to save the offset of the name. It is used to point
+ to the string in memory but must be a file offset. */
+ register char *temp;
+
+ temp = S_GET_NAME (symbolP);
+ S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
+
+ /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */
+ if (!S_IS_DEBUG (symbolP) && !S_IS_DEFINED (symbolP))
+ S_SET_EXTERNAL (symbolP);
+
+ /* Adjust the type of a weak symbol. */
+ if (S_GET_WEAK (symbolP))
+ {
+ switch (S_GET_TYPE (symbolP))
+ {
+ case N_UNDF: S_SET_TYPE (symbolP, N_WEAKU); break;
+ case N_ABS: S_SET_TYPE (symbolP, N_WEAKA); break;
+ case N_TEXT: S_SET_TYPE (symbolP, N_WEAKT); break;
+ case N_DATA: S_SET_TYPE (symbolP, N_WEAKD); break;
+ case N_BSS: S_SET_TYPE (symbolP, N_WEAKB); break;
+ default: as_bad (_("%s: bad type for weak symbol"), temp); break;
+ }
+ }
+
+ obj_symbol_to_chars (where, symbolP);
+ S_SET_NAME (symbolP, temp);
+ }
+}
+
+#endif /* ! BFD_ASSEMBLER */
+
+static void
+obj_aout_line (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ /* Assume delimiter is part of expression.
+ BSD4.2 as fails with delightful bug, so we
+ are not being incompatible here. */
+ new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
+ demand_empty_rest_of_line ();
+} /* obj_aout_line() */
+
+/* Handle .weak. This is a GNU extension. */
+
+static void
+obj_aout_weak (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+
+ do
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ S_SET_WEAK (symbolP);
+ if (c == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\n')
+ c = '\n';
+ }
+ }
+ while (c == ',');
+ demand_empty_rest_of_line ();
+}
+
+/* Handle .type. On {Net,Open}BSD, this is used to set the n_other field,
+ which is then apparently used when doing dynamic linking. Older
+ versions of gas ignored the .type pseudo-op, so we also ignore it if
+ we can't parse it. */
+
+static void
+obj_aout_type (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *name;
+ int c;
+ symbolS *sym;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ sym = symbol_find_or_make (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '@')
+ {
+ ++input_line_pointer;
+ if (strncmp (input_line_pointer, "object", 6) == 0)
+#ifdef BFD_ASSEMBLER
+ aout_symbol (symbol_get_bfdsym (sym))->other = 1;
+#else
+ S_SET_OTHER (sym, 1);
+#endif
+ else if (strncmp (input_line_pointer, "function", 8) == 0)
+#ifdef BFD_ASSEMBLER
+ aout_symbol (symbol_get_bfdsym (sym))->other = 2;
+#else
+ S_SET_OTHER (sym, 2);
+#endif
+ }
+ }
+
+ /* Ignore everything else on the line. */
+ s_ignore (0);
+}
+
+#ifndef BFD_ASSEMBLER
+
+void
+obj_crawl_symbol_chain (headers)
+ object_headers *headers;
+{
+ symbolS *symbolP;
+ symbolS **symbolPP;
+ int symbol_number = 0;
+
+ tc_crawl_symbol_chain (headers);
+
+ symbolPP = &symbol_rootP; /*->last symbol chain link. */
+ while ((symbolP = *symbolPP) != NULL)
+ {
+ if (symbolP->sy_mri_common)
+ {
+ if (S_IS_EXTERNAL (symbolP))
+ as_bad (_("%s: global symbols not supported in common sections"),
+ S_GET_NAME (symbolP));
+ *symbolPP = symbol_next (symbolP);
+ continue;
+ }
+
+ if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_DATA))
+ {
+ S_SET_SEGMENT (symbolP, SEG_TEXT);
+ } /* if pushing data into text */
+
+ resolve_symbol_value (symbolP);
+
+ /* Skip symbols which were equated to undefined or common
+ symbols. Also skip defined uncommon symbols which can
+ be resolved since in this case they should have been
+ resolved to a non-symbolic constant. */
+ if (symbolP->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (symbolP)
+ || S_IS_COMMON (symbolP)
+ || symbol_resolved_p (symbolP)))
+ {
+ *symbolPP = symbol_next (symbolP);
+ continue;
+ }
+
+ /* OK, here is how we decide which symbols go out into the brave
+ new symtab. Symbols that do are:
+
+ * symbols with no name (stabd's?)
+ * symbols with debug info in their N_TYPE
+
+ Symbols that don't are:
+ * symbols that are registers
+ * symbols with \1 as their 3rd character (numeric labels)
+ * "local labels" as defined by S_LOCAL_NAME(name) if the -L
+ switch was passed to gas.
+
+ All other symbols are output. We complain if a deleted
+ symbol was marked external. */
+
+ if (!S_IS_REGISTER (symbolP)
+ && (!S_GET_NAME (symbolP)
+ || S_IS_DEBUG (symbolP)
+ || !S_IS_DEFINED (symbolP)
+ || S_IS_EXTERNAL (symbolP)
+ || (S_GET_NAME (symbolP)[0] != '\001'
+ && (flag_keep_locals || !S_LOCAL_NAME (symbolP)))))
+ {
+ symbolP->sy_number = symbol_number++;
+
+ /* The + 1 after strlen account for the \0 at the
+ end of each string */
+ if (!S_IS_STABD (symbolP))
+ {
+ /* Ordinary case. */
+ symbolP->sy_name_offset = string_byte_count;
+ string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
+ }
+ else /* .Stabd case. */
+ symbolP->sy_name_offset = 0;
+ symbolPP = &symbolP->sy_next;
+ }
+ else
+ {
+ if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))
+ /* This warning should never get triggered any more.
+ Well, maybe if you're doing twisted things with
+ register names... */
+ {
+ as_bad (_("Local symbol %s never defined."), decode_local_label_name (S_GET_NAME (symbolP)));
+ } /* oops. */
+
+ /* Unhook it from the chain */
+ *symbolPP = symbol_next (symbolP);
+ } /* if this symbol should be in the output */
+ } /* for each symbol */
+
+ H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
+}
+
+/*
+ * Find strings by crawling along symbol table chain.
+ */
+
+void
+obj_emit_strings (where)
+ char **where;
+{
+ symbolS *symbolP;
+
+#ifdef CROSS_COMPILE
+ /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
+ md_number_to_chars (*where, string_byte_count, sizeof (string_byte_count));
+ *where += sizeof (string_byte_count);
+#else /* CROSS_COMPILE */
+ append (where, (char *) &string_byte_count, (unsigned long) sizeof (string_byte_count));
+#endif /* CROSS_COMPILE */
+
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ {
+ if (S_GET_NAME (symbolP))
+ append (&next_object_file_charP, S_GET_NAME (symbolP),
+ (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1));
+ } /* walk symbol chain */
+}
+
+#ifndef AOUT_VERSION
+#define AOUT_VERSION 0
+#endif
+
+void
+obj_pre_write_hook (headers)
+ object_headers *headers;
+{
+ H_SET_DYNAMIC (headers, 0);
+ H_SET_VERSION (headers, AOUT_VERSION);
+ H_SET_MACHTYPE (headers, AOUT_MACHTYPE);
+ tc_aout_pre_write_hook (headers);
+}
+
+#endif /* ! BFD_ASSEMBLER */
+
+#ifdef BFD_ASSEMBLER
+
+/* Support for an AOUT emulation. */
+
+static void aout_pop_insert PARAMS ((void));
+static int obj_aout_s_get_other PARAMS ((symbolS *));
+static void obj_aout_s_set_other PARAMS ((symbolS *, int));
+static int obj_aout_s_get_desc PARAMS ((symbolS *));
+static void obj_aout_s_set_desc PARAMS ((symbolS *, int));
+static int obj_aout_s_get_type PARAMS ((symbolS *));
+static void obj_aout_s_set_type PARAMS ((symbolS *, int));
+static int obj_aout_separate_stab_sections PARAMS ((void));
+static int obj_aout_sec_sym_ok_for_reloc PARAMS ((asection *));
+static void obj_aout_process_stab PARAMS ((segT, int, const char *, int, int, int));
+
+static void
+aout_pop_insert ()
+{
+ pop_insert (aout_pseudo_table);
+}
+
+static int
+obj_aout_s_get_other (sym)
+ symbolS *sym;
+{
+ return aout_symbol (symbol_get_bfdsym (sym))->other;
+}
+
+static void
+obj_aout_s_set_other (sym, o)
+ symbolS *sym;
+ int o;
+{
+ aout_symbol (symbol_get_bfdsym (sym))->other = o;
+}
+
+static int
+obj_aout_sec_sym_ok_for_reloc (sec)
+ asection *sec ATTRIBUTE_UNUSED;
+{
+ return obj_sec_sym_ok_for_reloc (sec);
+}
+
+static void
+obj_aout_process_stab (seg, w, s, t, o, d)
+ segT seg ATTRIBUTE_UNUSED;
+ int w;
+ const char *s;
+ int t;
+ int o;
+ int d;
+{
+ aout_process_stab (w, s, t, o, d);
+}
+
+static int
+obj_aout_s_get_desc (sym)
+ symbolS *sym;
+{
+ return aout_symbol (symbol_get_bfdsym (sym))->desc;
+}
+
+static void
+obj_aout_s_set_desc (sym, d)
+ symbolS *sym;
+ int d;
+{
+ aout_symbol (symbol_get_bfdsym (sym))->desc = d;
+}
+
+static int
+obj_aout_s_get_type (sym)
+ symbolS *sym;
+{
+ return aout_symbol (symbol_get_bfdsym (sym))->type;
+}
+
+static void
+obj_aout_s_set_type (sym, t)
+ symbolS *sym;
+ int t;
+{
+ aout_symbol (symbol_get_bfdsym (sym))->type = t;
+}
+
+static int
+obj_aout_separate_stab_sections ()
+{
+ return 0;
+}
+
+/* When changed, make sure these table entries match the single-format
+ definitions in obj-aout.h. */
+const struct format_ops aout_format_ops =
+{
+ bfd_target_aout_flavour,
+ 1, /* dfl_leading_underscore */
+ 0, /* emit_section_symbols */
+ 0, /* begin */
+ 0, /* app_file */
+ obj_aout_frob_symbol,
+ 0, /* frob_file */
+ 0, /* frob_file_before_adjust */
+ obj_aout_frob_file_before_fix,
+ 0, /* frob_file_after_relocs */
+ 0, /* s_get_size */
+ 0, /* s_set_size */
+ 0, /* s_get_align */
+ 0, /* s_set_align */
+ obj_aout_s_get_other,
+ obj_aout_s_set_other,
+ obj_aout_s_get_desc,
+ obj_aout_s_set_desc,
+ obj_aout_s_get_type,
+ obj_aout_s_set_type,
+ 0, /* copy_symbol_attributes */
+ 0, /* generate_asm_lineno */
+ obj_aout_process_stab,
+ obj_aout_separate_stab_sections,
+ 0, /* init_stab_section */
+ obj_aout_sec_sym_ok_for_reloc,
+ aout_pop_insert,
+ 0, /* ecoff_set_ext */
+ 0, /* read_begin_hook */
+ 0 /* symbol_new_hook */
+};
+#endif /* BFD_ASSEMBLER */
diff --git a/x/binutils/gas/config/obj-aout.h b/x/binutils/gas/config/obj-aout.h
new file mode 100644
index 0000000..23a2907
--- /dev/null
+++ b/x/binutils/gas/config/obj-aout.h
@@ -0,0 +1,256 @@
+/* obj-aout.h, a.out object file format for gas, the assembler.
+ Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000,
+ 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2,
+ or (at your option) any later version.
+
+ GAS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Tag to validate a.out object file format processing */
+#define OBJ_AOUT 1
+
+#include "targ-cpu.h"
+
+#ifdef BFD_ASSEMBLER
+
+#include "bfd/libaout.h"
+
+#define OUTPUT_FLAVOR bfd_target_aout_flavour
+
+#else /* ! BFD_ASSEMBLER */
+
+#ifndef VMS
+#include "aout_gnu.h" /* Needed to define struct nlist. Sigh. */
+#else
+#include "a_out.h"
+#endif
+
+#ifndef AOUT_MACHTYPE
+#define AOUT_MACHTYPE 0
+#endif /* AOUT_MACHTYPE */
+
+extern const short seg_N_TYPE[];
+extern const segT N_TYPE_seg[];
+
+#ifndef DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE
+#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (OMAGIC)
+#endif /* DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE */
+
+#endif /* ! BFD_ASSEMBLER */
+
+extern const pseudo_typeS aout_pseudo_table[];
+
+#ifndef obj_pop_insert
+#define obj_pop_insert() pop_insert (aout_pseudo_table)
+#endif
+
+/* SYMBOL TABLE */
+/* Symbol table entry data type */
+
+typedef struct nlist obj_symbol_type; /* Symbol table entry */
+
+/* Symbol table macros and constants */
+
+#ifdef BFD_ASSEMBLER
+
+#define S_SET_OTHER(S,V) \
+ (aout_symbol (symbol_get_bfdsym (S))->other = (V))
+#define S_SET_TYPE(S,T) \
+ (aout_symbol (symbol_get_bfdsym (S))->type = (T))
+#define S_SET_DESC(S,D) \
+ (aout_symbol (symbol_get_bfdsym (S))->desc = (D))
+#define S_GET_OTHER(S) \
+ (aout_symbol (symbol_get_bfdsym (S))->other)
+#define S_GET_TYPE(S) \
+ (aout_symbol (symbol_get_bfdsym (S))->type)
+#define S_GET_DESC(S) \
+ (aout_symbol (symbol_get_bfdsym (S))->desc)
+
+asection *text_section, *data_section, *bss_section;
+
+#define obj_frob_symbol(S,PUNT) obj_aout_frob_symbol (S, &PUNT)
+#define obj_frob_file_before_fix() obj_aout_frob_file_before_fix ()
+extern void obj_aout_frob_symbol PARAMS ((symbolS *, int *));
+extern void obj_aout_frob_file_before_fix PARAMS ((void));
+
+#define obj_sec_sym_ok_for_reloc(SEC) (1)
+
+#else
+
+/* We use the sy_obj field to record whether a symbol is weak. */
+#define OBJ_SYMFIELD_TYPE char
+
+/*
+ * Macros to extract information from a symbol table entry.
+ * This syntactic indirection allows independence regarding a.out or coff.
+ * The argument (s) of all these macros is a pointer to a symbol table entry.
+ */
+
+/* True if the symbol is external */
+#define S_IS_EXTERNAL(s) ((s)->sy_symbol.n_type & N_EXT)
+
+/* True if symbol has been defined, ie is in N_{TEXT,DATA,BSS,ABS} or N_EXT */
+#define S_IS_DEFINED(s) \
+ (S_GET_TYPE (s) != N_UNDF || S_GET_DESC (s) != 0)
+
+#define S_IS_COMMON(s) \
+ (S_GET_TYPE (s) == N_UNDF && S_GET_VALUE (s) != 0)
+
+/* Return true for symbols that should not be reduced to section
+ symbols or eliminated from expressions, because they may be
+ overridden by the linker. */
+#define S_FORCE_RELOC(s, strict) \
+ (!SEG_NORMAL (S_GET_SEGMENT (s)))
+
+#define S_IS_REGISTER(s) ((s)->sy_symbol.n_type == N_REGISTER)
+
+/* True if a debug special symbol entry */
+#define S_IS_DEBUG(s) ((s)->sy_symbol.n_type & N_STAB)
+/* True if a symbol is local symbol name */
+#define S_IS_LOCAL(s) \
+ ((S_GET_NAME (s) \
+ && !S_IS_DEBUG (s) \
+ && (strchr (S_GET_NAME (s), '\001') != NULL \
+ || strchr (S_GET_NAME (s), '\002') != NULL \
+ || (S_LOCAL_NAME(s) && !flag_keep_locals))) \
+ || (flag_strip_local_absolute \
+ && ! S_IS_EXTERNAL(s) \
+ && S_GET_SEGMENT (s) == absolute_section))
+/* True if a symbol is not defined in this file */
+#define S_IS_EXTERN(s) ((s)->sy_symbol.n_type & N_EXT)
+/* True if the symbol has been generated because of a .stabd directive */
+#define S_IS_STABD(s) (S_GET_NAME(s) == (char *)0)
+
+/* Accessors */
+/* The name of the symbol */
+#define S_GET_NAME(s) ((s)->sy_symbol.n_un.n_name)
+/* The pointer to the string table */
+#define S_GET_OFFSET(s) ((s)->sy_symbol.n_un.n_strx)
+/* The type of the symbol */
+#define S_GET_TYPE(s) ((s)->sy_symbol.n_type & N_TYPE)
+/* The numeric value of the segment */
+#define S_GET_SEGMENT(s) (N_TYPE_seg[S_GET_TYPE(s)])
+/* The n_other expression value */
+#define S_GET_OTHER(s) ((s)->sy_symbol.n_other)
+/* The n_desc expression value */
+#define S_GET_DESC(s) ((s)->sy_symbol.n_desc)
+/* Whether the symbol is weak. */
+#define S_GET_WEAK(s) ((s)->sy_obj)
+
+/* Modifiers */
+/* Assume that a symbol cannot be simultaneously in more than on segment */
+/* set segment */
+#define S_SET_SEGMENT(s,seg) ((s)->sy_symbol.n_type &= ~N_TYPE,(s)->sy_symbol.n_type|=SEGMENT_TO_SYMBOL_TYPE(seg))
+/* The symbol is external */
+#define S_SET_EXTERNAL(s) ((s)->sy_symbol.n_type |= N_EXT)
+/* The symbol is not external */
+#define S_CLEAR_EXTERNAL(s) ((s)->sy_symbol.n_type &= ~N_EXT)
+/* Set the name of the symbol */
+#define S_SET_NAME(s,v) ((s)->sy_symbol.n_un.n_name = (v))
+/* Set the offset in the string table */
+#define S_SET_OFFSET(s,v) ((s)->sy_symbol.n_un.n_strx = (v))
+/* Set the n_type field */
+#define S_SET_TYPE(s,t) ((s)->sy_symbol.n_type = (t))
+/* Set the n_other expression value */
+#define S_SET_OTHER(s,v) ((s)->sy_symbol.n_other = (v))
+/* Set the n_desc expression value */
+#define S_SET_DESC(s,v) ((s)->sy_symbol.n_desc = (v))
+/* Mark the symbol as weak. This causes n_type to be adjusted when
+ the symbol is written out. */
+#define S_SET_WEAK(s) ((s)->sy_obj = 1)
+
+/* File header macro and type definition */
+
+#define H_GET_FILE_SIZE(h) (H_GET_HEADER_SIZE(h) \
+ + H_GET_TEXT_SIZE(h) \
+ + H_GET_DATA_SIZE(h) \
+ + H_GET_SYMBOL_TABLE_SIZE(h) \
+ + H_GET_TEXT_RELOCATION_SIZE(h) \
+ + H_GET_DATA_RELOCATION_SIZE(h) \
+ + H_GET_STRING_SIZE(h))
+
+#define H_GET_HEADER_SIZE(h) (EXEC_BYTES_SIZE)
+#define H_GET_TEXT_SIZE(h) ((h)->header.a_text)
+#define H_GET_DATA_SIZE(h) ((h)->header.a_data)
+#define H_GET_BSS_SIZE(h) ((h)->header.a_bss)
+#define H_GET_TEXT_RELOCATION_SIZE(h) ((h)->header.a_trsize)
+#define H_GET_DATA_RELOCATION_SIZE(h) ((h)->header.a_drsize)
+#define H_GET_SYMBOL_TABLE_SIZE(h) ((h)->header.a_syms)
+#define H_GET_ENTRY_POINT(h) ((h)->header.a_entry)
+#define H_GET_STRING_SIZE(h) ((h)->string_table_size)
+#define H_GET_LINENO_SIZE(h) (0)
+
+#define H_GET_DYNAMIC(h) ((h)->header.a_info >> 31)
+#define H_GET_VERSION(h) (((h)->header.a_info >> 24) & 0x7f)
+#define H_GET_MACHTYPE(h) (((h)->header.a_info >> 16) & 0xff)
+#define H_GET_MAGIC_NUMBER(h) ((h)->header.a_info & 0xffff)
+
+#define H_SET_DYNAMIC(h,v) ((h)->header.a_info = (((v) << 31) \
+ | (H_GET_VERSION(h) << 24) \
+ | (H_GET_MACHTYPE(h) << 16) \
+ | (H_GET_MAGIC_NUMBER(h))))
+
+#define H_SET_VERSION(h,v) ((h)->header.a_info = ((H_GET_DYNAMIC(h) << 31) \
+ | ((v) << 24) \
+ | (H_GET_MACHTYPE(h) << 16) \
+ | (H_GET_MAGIC_NUMBER(h))))
+
+#define H_SET_MACHTYPE(h,v) ((h)->header.a_info = ((H_GET_DYNAMIC(h) << 31) \
+ | (H_GET_VERSION(h) << 24) \
+ | ((v) << 16) \
+ | (H_GET_MAGIC_NUMBER(h))))
+
+#define H_SET_MAGIC_NUMBER(h,v) ((h)->header.a_info = ((H_GET_DYNAMIC(h) << 31) \
+ | (H_GET_VERSION(h) << 24) \
+ | (H_GET_MACHTYPE(h) << 16) \
+ | ((v))))
+
+#define H_SET_TEXT_SIZE(h,v) ((h)->header.a_text = md_section_align(SEG_TEXT, (v)))
+#define H_SET_DATA_SIZE(h,v) ((h)->header.a_data = md_section_align(SEG_DATA, (v)))
+#define H_SET_BSS_SIZE(h,v) ((h)->header.a_bss = md_section_align(SEG_BSS, (v)))
+
+#define H_SET_RELOCATION_SIZE(h,t,d) (H_SET_TEXT_RELOCATION_SIZE((h),(t)),\
+ H_SET_DATA_RELOCATION_SIZE((h),(d)))
+
+#define H_SET_TEXT_RELOCATION_SIZE(h,v) ((h)->header.a_trsize = (v))
+#define H_SET_DATA_RELOCATION_SIZE(h,v) ((h)->header.a_drsize = (v))
+#define H_SET_SYMBOL_TABLE_SIZE(h,v) ((h)->header.a_syms = (v) * 12)
+
+#define H_SET_ENTRY_POINT(h,v) ((h)->header.a_entry = (v))
+#define H_SET_STRING_SIZE(h,v) ((h)->string_table_size = (v))
+
+typedef struct
+ {
+ struct exec header; /* a.out header */
+ long string_table_size; /* names + '\0' + sizeof (int) */
+ }
+
+object_headers;
+
+/* line numbering stuff. */
+#define OBJ_EMIT_LINENO(a, b, c) {;}
+
+struct fix;
+void tc_aout_fix_to_chars PARAMS ((char *where, struct fix *fixP, relax_addressT segment_address));
+
+#endif
+
+#define obj_read_begin_hook() {;}
+#define obj_symbol_new_hook(s) {;}
+
+#define EMIT_SECTION_SYMBOLS 0
+
+#define AOUT_STABS
diff --git a/x/binutils/gas/config/obj-coff.c b/x/binutils/gas/config/obj-coff.c
new file mode 100644
index 0000000..bd08c2b
--- /dev/null
+++ b/x/binutils/gas/config/obj-coff.c
@@ -0,0 +1,4690 @@
+/* coff object file format
+ Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of GAS.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define OBJ_HEADER "obj-coff.h"
+
+#include "as.h"
+#include "obstack.h"
+#include "subsegs.h"
+
+/* I think this is probably always correct. */
+#ifndef KEEP_RELOC_INFO
+#define KEEP_RELOC_INFO
+#endif
+
+/* The BFD_ASSEMBLER version of obj_coff_section will use this macro to set
+ a new section's attributes when a directive has no valid flags or the
+ "w" flag is used. This default should be appropriate for most. */
+#ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES
+#define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)
+#endif
+
+/* This is used to hold the symbol built by a sequence of pseudo-ops
+ from .def and .endef. */
+static symbolS *def_symbol_in_progress;
+
+typedef struct
+ {
+ unsigned long chunk_size;
+ unsigned long element_size;
+ unsigned long size;
+ char *data;
+ unsigned long pointer;
+ }
+stack;
+
+static stack *stack_init PARAMS ((unsigned long, unsigned long));
+static char *stack_push PARAMS ((stack *, char *));
+static char *stack_pop PARAMS ((stack *));
+static void tag_init PARAMS ((void));
+static void tag_insert PARAMS ((const char *, symbolS *));
+static symbolS *tag_find PARAMS ((char *));
+static symbolS *tag_find_or_make PARAMS ((char *));
+static void obj_coff_bss PARAMS ((int));
+static void obj_coff_weak PARAMS ((int));
+const char *s_get_name PARAMS ((symbolS * s));
+static void obj_coff_ln PARAMS ((int));
+static void obj_coff_def PARAMS ((int));
+static void obj_coff_endef PARAMS ((int));
+static void obj_coff_dim PARAMS ((int));
+static void obj_coff_line PARAMS ((int));
+static void obj_coff_size PARAMS ((int));
+static void obj_coff_scl PARAMS ((int));
+static void obj_coff_tag PARAMS ((int));
+static void obj_coff_val PARAMS ((int));
+static void obj_coff_type PARAMS ((int));
+static void obj_coff_ident PARAMS ((int));
+#ifdef BFD_ASSEMBLER
+static void obj_coff_loc PARAMS((int));
+#endif
+
+/* stack stuff */
+
+static stack *
+stack_init (chunk_size, element_size)
+ unsigned long chunk_size;
+ unsigned long element_size;
+{
+ stack *st;
+
+ st = (stack *) malloc (sizeof (stack));
+ if (!st)
+ return 0;
+ st->data = malloc (chunk_size);
+ if (!st->data)
+ {
+ free (st);
+ return 0;
+ }
+ st->pointer = 0;
+ st->size = chunk_size;
+ st->chunk_size = chunk_size;
+ st->element_size = element_size;
+ return st;
+}
+
+#if 0
+/* Not currently used. */
+static void
+stack_delete (st)
+ stack *st;
+{
+ free (st->data);
+ free (st);
+}
+#endif
+
+static char *
+stack_push (st, element)
+ stack *st;
+ char *element;
+{
+ if (st->pointer + st->element_size >= st->size)
+ {
+ st->size += st->chunk_size;
+ if ((st->data = xrealloc (st->data, st->size)) == (char *) 0)
+ return (char *) 0;
+ }
+ memcpy (st->data + st->pointer, element, st->element_size);
+ st->pointer += st->element_size;
+ return st->data + st->pointer;
+}
+
+static char *
+stack_pop (st)
+ stack *st;
+{
+ if (st->pointer < st->element_size)
+ {
+ st->pointer = 0;
+ return (char *) 0;
+ }
+ st->pointer -= st->element_size;
+ return st->data + st->pointer;
+}
+
+/*
+ * Maintain a list of the tagnames of the structures.
+ */
+
+static struct hash_control *tag_hash;
+
+static void
+tag_init ()
+{
+ tag_hash = hash_new ();
+}
+
+static void
+tag_insert (name, symbolP)
+ const char *name;
+ symbolS *symbolP;
+{
+ const char *error_string;
+
+ if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
+ {
+ as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
+ name, error_string);
+ }
+}
+
+static symbolS *
+tag_find (name)
+ char *name;
+{
+#ifdef STRIP_UNDERSCORE
+ if (*name == '_')
+ name++;
+#endif /* STRIP_UNDERSCORE */
+ return (symbolS *) hash_find (tag_hash, name);
+}
+
+static symbolS *
+tag_find_or_make (name)
+ char *name;
+{
+ symbolS *symbolP;
+
+ if ((symbolP = tag_find (name)) == NULL)
+ {
+ symbolP = symbol_new (name, undefined_section,
+ 0, &zero_address_frag);
+
+ tag_insert (S_GET_NAME (symbolP), symbolP);
+#ifdef BFD_ASSEMBLER
+ symbol_table_insert (symbolP);
+#endif
+ } /* not found */
+
+ return symbolP;
+}
+
+/* We accept the .bss directive to set the section for backward
+ compatibility with earlier versions of gas. */
+
+static void
+obj_coff_bss (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (*input_line_pointer == '\n')
+ subseg_new (".bss", get_absolute_expression ());
+ else
+ s_lcomm (0);
+}
+
+/* Handle .weak. This is a GNU extension. */
+
+static void
+obj_coff_weak (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+
+ do
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+
+#if defined BFD_ASSEMBLER || defined S_SET_WEAK
+ S_SET_WEAK (symbolP);
+#endif
+
+#ifdef TE_PE
+ S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
+#else
+ S_SET_STORAGE_CLASS (symbolP, C_WEAKEXT);
+#endif
+
+ if (c == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\n')
+ c = '\n';
+ }
+ }
+ while (c == ',');
+
+ demand_empty_rest_of_line ();
+}
+
+#ifdef BFD_ASSEMBLER
+
+static segT fetch_coff_debug_section PARAMS ((void));
+static void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *));
+static int S_GET_DATA_TYPE PARAMS ((symbolS *));
+void c_symbol_merge PARAMS ((symbolS *, symbolS *));
+static void add_lineno PARAMS ((fragS *, addressT, int));
+
+#define GET_FILENAME_STRING(X) \
+((char*) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
+
+/* @@ Ick. */
+static segT
+fetch_coff_debug_section ()
+{
+ static segT debug_section;
+ if (!debug_section)
+ {
+ const asymbol *s;
+ s = bfd_make_debug_symbol (stdoutput, (char *) 0, 0);
+ assert (s != 0);
+ debug_section = s->section;
+ }
+ return debug_section;
+}
+
+void
+SA_SET_SYM_ENDNDX (sym, val)
+ symbolS *sym;
+ symbolS *val;
+{
+ combined_entry_type *entry, *p;
+
+ entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
+ p = coffsymbol (symbol_get_bfdsym (val))->native;
+ entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
+ entry->fix_end = 1;
+}
+
+static void
+SA_SET_SYM_TAGNDX (sym, val)
+ symbolS *sym;
+ symbolS *val;
+{
+ combined_entry_type *entry, *p;
+
+ entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
+ p = coffsymbol (symbol_get_bfdsym (val))->native;
+ entry->u.auxent.x_sym.x_tagndx.p = p;
+ entry->fix_tag = 1;
+}
+
+static int
+S_GET_DATA_TYPE (sym)
+ symbolS *sym;
+{
+ return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;
+}
+
+int
+S_SET_DATA_TYPE (sym, val)
+ symbolS *sym;
+ int val;
+{
+ coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val;
+ return val;
+}
+
+int
+S_GET_STORAGE_CLASS (sym)
+ symbolS *sym;
+{
+ return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;
+}
+
+int
+S_SET_STORAGE_CLASS (sym, val)
+ symbolS *sym;
+ int val;
+{
+ coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val;
+ return val;
+}
+
+/* Merge a debug symbol containing debug information into a normal symbol. */
+
+void
+c_symbol_merge (debug, normal)
+ symbolS *debug;
+ symbolS *normal;
+{
+ S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
+ S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
+
+ if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
+ {
+ /* take the most we have */
+ S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
+ }
+
+ if (S_GET_NUMBER_AUXILIARY (debug) > 0)
+ {
+ /* Move all the auxiliary information. */
+ memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug),
+ (S_GET_NUMBER_AUXILIARY (debug)
+ * sizeof (*SYM_AUXINFO (debug))));
+ }
+
+ /* Move the debug flags. */
+ SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
+}
+
+void
+c_dot_file_symbol (filename)
+ const char *filename;
+{
+ symbolS *symbolP;
+
+ /* BFD converts filename to a .file symbol with an aux entry. It
+ also handles chaining. */
+ symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
+
+ S_SET_STORAGE_CLASS (symbolP, C_FILE);
+ S_SET_NUMBER_AUXILIARY (symbolP, 1);
+
+ symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;
+
+#ifndef NO_LISTING
+ {
+ extern int listing;
+ if (listing)
+ {
+ listing_source_file (filename);
+ }
+ }
+#endif
+
+ /* Make sure that the symbol is first on the symbol chain */
+ if (symbol_rootP != symbolP)
+ {
+ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+ symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
+ } /* if not first on the list */
+}
+
+/* Line number handling */
+
+struct line_no {
+ struct line_no *next;
+ fragS *frag;
+ alent l;
+};
+
+int coff_line_base;
+
+/* Symbol of last function, which we should hang line#s off of. */
+static symbolS *line_fsym;
+
+#define in_function() (line_fsym != 0)
+#define clear_function() (line_fsym = 0)
+#define set_function(F) (line_fsym = (F), coff_add_linesym (F))
+
+
+void
+coff_obj_symbol_new_hook (symbolP)
+ symbolS *symbolP;
+{
+ long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
+ char * s = (char *) xmalloc (sz);
+
+ memset (s, 0, sz);
+ coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
+
+ S_SET_DATA_TYPE (symbolP, T_NULL);
+ S_SET_STORAGE_CLASS (symbolP, 0);
+ S_SET_NUMBER_AUXILIARY (symbolP, 0);
+
+ if (S_IS_STRING (symbolP))
+ SF_SET_STRING (symbolP);
+
+ if (S_IS_LOCAL (symbolP))
+ SF_SET_LOCAL (symbolP);
+}
+
+
+/*
+ * Handle .ln directives.
+ */
+
+static symbolS *current_lineno_sym;
+static struct line_no *line_nos;
+/* @@ Blindly assume all .ln directives will be in the .text section... */
+int coff_n_line_nos;
+
+static void
+add_lineno (frag, offset, num)
+ fragS *frag;
+ addressT offset;
+ int num;
+{
+ struct line_no *new_line =
+ (struct line_no *) xmalloc (sizeof (struct line_no));
+ if (!current_lineno_sym)
+ {
+ abort ();
+ }
+
+#ifndef OBJ_XCOFF
+ /* The native aix assembler accepts negative line number */
+
+ if (num <= 0)
+ {
+ /* Zero is used as an end marker in the file. */
+ as_warn (_("Line numbers must be positive integers\n"));
+ num = 1;
+ }
+#endif /* OBJ_XCOFF */
+ new_line->next = line_nos;
+ new_line->frag = frag;
+ new_line->l.line_number = num;
+ new_line->l.u.offset = offset;
+ line_nos = new_line;
+ coff_n_line_nos++;
+}
+
+void
+coff_add_linesym (sym)
+ symbolS *sym;
+{
+ if (line_nos)
+ {
+ coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno =
+ (alent *) line_nos;
+ coff_n_line_nos++;
+ line_nos = 0;
+ }
+ current_lineno_sym = sym;
+}
+
+static void
+obj_coff_ln (appline)
+ int appline;
+{
+ int l;
+
+ if (! appline && def_symbol_in_progress != NULL)
+ {
+ as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ l = get_absolute_expression ();
+
+ /* If there is no lineno symbol, treat a .ln
+ directive as if it were a .appline directive. */
+ if (appline || current_lineno_sym == NULL)
+ new_logical_line ((char *) NULL, l - 1);
+ else
+ add_lineno (frag_now, frag_now_fix (), l);
+
+#ifndef NO_LISTING
+ {
+ extern int listing;
+
+ if (listing)
+ {
+ if (! appline)
+ l += coff_line_base - 1;
+ listing_source_line (l);
+ }
+ }
+#endif
+
+ demand_empty_rest_of_line ();
+}
+
+/* .loc is essentially the same as .ln; parse it for assembler
+ compatibility. */
+
+static void
+obj_coff_loc (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ int lineno;
+
+ /* FIXME: Why do we need this check? We need it for ECOFF, but why
+ do we need it for COFF? */
+ if (now_seg != text_section)
+ {
+ as_warn (_(".loc outside of .text"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (def_symbol_in_progress != NULL)
+ {
+ as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ /* Skip the file number. */
+ SKIP_WHITESPACE ();
+ get_absolute_expression ();
+ SKIP_WHITESPACE ();
+
+ lineno = get_absolute_expression ();
+
+#ifndef NO_LISTING
+ {
+ extern int listing;
+
+ if (listing)
+ {
+ lineno += coff_line_base - 1;
+ listing_source_line (lineno);
+ }
+ }
+#endif
+
+ demand_empty_rest_of_line ();
+
+ add_lineno (frag_now, frag_now_fix (), lineno);
+}
+
+/* Handle the .ident pseudo-op. */
+
+static void
+obj_coff_ident (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ segT current_seg = now_seg;
+ subsegT current_subseg = now_subseg;
+
+#ifdef TE_PE
+ {
+ segT sec;
+
+ /* We could put it in .comment, but that creates an extra section
+ that shouldn't be loaded into memory, which requires linker
+ changes... For now, until proven otherwise, use .rdata. */
+ sec = subseg_new (".rdata$zzz", 0);
+ bfd_set_section_flags (stdoutput, sec,
+ ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
+ & bfd_applicable_section_flags (stdoutput)));
+ }
+#else
+ subseg_new (".comment", 0);
+#endif
+
+ stringer (1);
+ subseg_set (current_seg, current_subseg);
+}
+
+/*
+ * def()
+ *
+ * Handle .def directives.
+ *
+ * One might ask : why can't we symbol_new if the symbol does not
+ * already exist and fill it with debug information. Because of
+ * the C_EFCN special symbol. It would clobber the value of the
+ * function symbol before we have a chance to notice that it is
+ * a C_EFCN. And a second reason is that the code is more clear this
+ * way. (at least I think it is :-).
+ *
+ */
+
+#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
+#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
+ *input_line_pointer == '\t') \
+ input_line_pointer++;
+
+static void
+obj_coff_def (what)
+ int what ATTRIBUTE_UNUSED;
+{
+ char name_end; /* Char after the end of name */
+ char *symbol_name; /* Name of the debug symbol */
+ char *symbol_name_copy; /* Temporary copy of the name */
+ unsigned int symbol_name_length;
+
+ if (def_symbol_in_progress != NULL)
+ {
+ as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ SKIP_WHITESPACES ();
+
+ symbol_name = input_line_pointer;
+#ifdef STRIP_UNDERSCORE
+ if (symbol_name[0] == '_' && symbol_name[1] != 0)
+ symbol_name++;
+#endif /* STRIP_UNDERSCORE */
+
+ name_end = get_symbol_end ();
+ symbol_name_length = strlen (symbol_name);
+ symbol_name_copy = xmalloc (symbol_name_length + 1);
+ strcpy (symbol_name_copy, symbol_name);
+#ifdef tc_canonicalize_symbol_name
+ symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
+#endif
+
+ /* Initialize the new symbol */
+ def_symbol_in_progress = symbol_make (symbol_name_copy);
+ symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
+ S_SET_VALUE (def_symbol_in_progress, 0);
+
+ if (S_IS_STRING (def_symbol_in_progress))
+ SF_SET_STRING (def_symbol_in_progress);
+
+ *input_line_pointer = name_end;
+
+ demand_empty_rest_of_line ();
+}
+
+unsigned int dim_index;
+
+static void
+obj_coff_endef (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ symbolS *symbolP = NULL;
+
+ /* DIM BUG FIX sac@cygnus.com */
+ dim_index = 0;
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ /* Set the section number according to storage class. */
+ switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
+ {
+ case C_STRTAG:
+ case C_ENTAG:
+ case C_UNTAG:
+ SF_SET_TAG (def_symbol_in_progress);
+ /* intentional fallthrough */
+ case C_FILE:
+ case C_TPDEF:
+ SF_SET_DEBUG (def_symbol_in_progress);
+ S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
+ break;
+
+ case C_EFCN:
+ SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */
+ /* intentional fallthrough */
+ case C_BLOCK:
+ SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing */
+ /* intentional fallthrough */
+ case C_FCN:
+ {
+ const char *name;
+ S_SET_SEGMENT (def_symbol_in_progress, text_section);
+
+ name = S_GET_NAME (def_symbol_in_progress);
+ if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
+ {
+ switch (name[1])
+ {
+ case 'b':
+ /* .bf */
+ if (! in_function ())
+ as_warn (_("`%s' symbol without preceding function"), name);
+ /* Will need relocating. */
+ SF_SET_PROCESS (def_symbol_in_progress);
+ clear_function ();
+ break;
+#ifdef TE_PE
+ case 'e':
+ /* .ef */
+ /* The MS compilers output the actual endline, not the
+ function-relative one... we want to match without
+ changing the assembler input. */
+ SA_SET_SYM_LNNO (def_symbol_in_progress,
+ (SA_GET_SYM_LNNO (def_symbol_in_progress)
+ + coff_line_base));
+ break;
+#endif
+ }
+ }
+ }
+ break;
+
+#ifdef C_AUTOARG
+ case C_AUTOARG:
+#endif /* C_AUTOARG */
+ case C_AUTO:
+ case C_REG:
+ case C_ARG:
+ case C_REGPARM:
+ case C_FIELD:
+
+ /* According to the COFF documentation:
+
+ http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
+
+ A special section number (-2) marks symbolic debugging symbols,
+ including structure/union/enumeration tag names, typedefs, and
+ the name of the file. A section number of -1 indicates that the
+ symbol has a value but is not relocatable. Examples of
+ absolute-valued symbols include automatic and register variables,
+ function arguments, and .eos symbols.
+
+ But from Ian Lance Taylor:
+
+ http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
+
+ the actual tools all marked them as section -1. So the GNU COFF
+ assembler follows historical COFF assemblers.
+
+ However, it causes problems for djgpp
+
+ http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
+
+ By defining STRICTCOFF, a COFF port can make the assembler to
+ follow the documented behavior. */
+#ifdef STRICTCOFF
+ case C_MOS:
+ case C_MOE:
+ case C_MOU:
+ case C_EOS:
+#endif
+ SF_SET_DEBUG (def_symbol_in_progress);
+ S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
+ break;
+
+#ifndef STRICTCOFF
+ case C_MOS:
+ case C_MOE:
+ case C_MOU:
+ case C_EOS:
+ S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
+ break;
+#endif
+
+ case C_EXT:
+ case C_WEAKEXT:
+#ifdef TE_PE
+ case C_NT_WEAK:
+#endif
+ case C_STAT:
+ case C_LABEL:
+ /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
+ break;
+
+ default:
+ case C_USTATIC:
+ case C_EXTDEF:
+ case C_ULABEL:
+ as_warn (_("unexpected storage class %d"),
+ S_GET_STORAGE_CLASS (def_symbol_in_progress));
+ break;
+ } /* switch on storage class */
+
+ /* Now that we have built a debug symbol, try to find if we should
+ merge with an existing symbol or not. If a symbol is C_EFCN or
+ absolute_section or untagged SEG_DEBUG it never merges. We also
+ don't merge labels, which are in a different namespace, nor
+ symbols which have not yet been defined since they are typically
+ unique, nor do we merge tags with non-tags. */
+
+ /* Two cases for functions. Either debug followed by definition or
+ definition followed by debug. For definition first, we will
+ merge the debug symbol into the definition. For debug first, the
+ lineno entry MUST point to the definition function or else it
+ will point off into space when obj_crawl_symbol_chain() merges
+ the debug symbol into the real symbol. Therefor, let's presume
+ the debug symbol is a real function reference. */
+
+ /* FIXME-SOON If for some reason the definition label/symbol is
+ never seen, this will probably leave an undefined symbol at link
+ time. */
+
+ if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
+ || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
+ || (!strcmp (bfd_get_section_name (stdoutput,
+ S_GET_SEGMENT (def_symbol_in_progress)),
+ "*DEBUG*")
+ && !SF_GET_TAG (def_symbol_in_progress))
+ || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
+ || ! symbol_constant_p (def_symbol_in_progress)
+ || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress),
+ DO_NOT_STRIP)) == NULL
+ || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
+ {
+ /* If it already is at the end of the symbol list, do nothing */
+ if (def_symbol_in_progress != symbol_lastP)
+ {
+ symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
+ symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
+ &symbol_lastP);
+ }
+ }
+ else
+ {
+ /* This symbol already exists, merge the newly created symbol
+ into the old one. This is not mandatory. The linker can
+ handle duplicate symbols correctly. But I guess that it save
+ a *lot* of space if the assembly file defines a lot of
+ symbols. [loic] */
+
+ /* The debug entry (def_symbol_in_progress) is merged into the
+ previous definition. */
+
+ c_symbol_merge (def_symbol_in_progress, symbolP);
+ symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
+
+ def_symbol_in_progress = symbolP;
+
+ if (SF_GET_FUNCTION (def_symbol_in_progress)
+ || SF_GET_TAG (def_symbol_in_progress)
+ || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
+ {
+ /* For functions, and tags, and static symbols, the symbol
+ *must* be where the debug symbol appears. Move the
+ existing symbol to the current place. */
+ /* If it already is at the end of the symbol list, do nothing */
+ if (def_symbol_in_progress != symbol_lastP)
+ {
+ symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
+ symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
+ }
+ }
+ }
+
+ if (SF_GET_TAG (def_symbol_in_progress))
+ {
+ symbolS *oldtag;
+
+ oldtag = symbol_find_base (S_GET_NAME (def_symbol_in_progress),
+ DO_NOT_STRIP);
+ if (oldtag == NULL || ! SF_GET_TAG (oldtag))
+ tag_insert (S_GET_NAME (def_symbol_in_progress),
+ def_symbol_in_progress);
+ }
+
+ if (SF_GET_FUNCTION (def_symbol_in_progress))
+ {
+ know (sizeof (def_symbol_in_progress) <= sizeof (long));
+ set_function (def_symbol_in_progress);
+ SF_SET_PROCESS (def_symbol_in_progress);
+
+ if (symbolP == NULL)
+ {
+ /* That is, if this is the first time we've seen the
+ function... */
+ symbol_table_insert (def_symbol_in_progress);
+ } /* definition follows debug */
+ } /* Create the line number entry pointing to the function being defined */
+
+ def_symbol_in_progress = NULL;
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_dim (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ int dim_index;
+
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
+
+ for (dim_index = 0; dim_index < DIMNUM; dim_index++)
+ {
+ SKIP_WHITESPACES ();
+ SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
+ get_absolute_expression ());
+
+ switch (*input_line_pointer)
+ {
+ case ',':
+ input_line_pointer++;
+ break;
+
+ default:
+ as_warn (_("badly formed .dim directive ignored"));
+ /* intentional fallthrough */
+ case '\n':
+ case ';':
+ dim_index = DIMNUM;
+ break;
+ }
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_line (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ int this_base;
+
+ if (def_symbol_in_progress == NULL)
+ {
+ /* Probably stabs-style line? */
+ obj_coff_ln (0);
+ return;
+ }
+
+ this_base = get_absolute_expression ();
+ if (!strcmp (".bf", S_GET_NAME (def_symbol_in_progress)))
+ coff_line_base = this_base;
+
+ S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
+ SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
+
+ demand_empty_rest_of_line ();
+
+#ifndef NO_LISTING
+ if (strcmp (".bf", S_GET_NAME (def_symbol_in_progress)) == 0)
+ {
+ extern int listing;
+
+ if (listing)
+ listing_source_line ((unsigned int) this_base);
+ }
+#endif
+}
+
+static void
+obj_coff_size (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
+ SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_scl (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_tag (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *symbol_name;
+ char name_end;
+
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
+ symbol_name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+#ifdef tc_canonicalize_symbol_name
+ symbol_name = tc_canonicalize_symbol_name (symbol_name);
+#endif
+
+ /* Assume that the symbol referred to by .tag is always defined.
+ This was a bad assumption. I've added find_or_make. xoxorich. */
+ SA_SET_SYM_TAGNDX (def_symbol_in_progress,
+ tag_find_or_make (symbol_name));
+ if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
+ {
+ as_warn (_("tag not found for .tag %s"), symbol_name);
+ } /* not defined */
+
+ SF_SET_TAGGED (def_symbol_in_progress);
+ *input_line_pointer = name_end;
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_type (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
+
+ if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
+ S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
+ {
+ SF_SET_FUNCTION (def_symbol_in_progress);
+ } /* is a function */
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_val (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ if (is_name_beginner (*input_line_pointer))
+ {
+ char *symbol_name = input_line_pointer;
+ char name_end = get_symbol_end ();
+
+#ifdef tc_canonicalize_symbol_name
+ symbol_name = tc_canonicalize_symbol_name (symbol_name);
+#endif
+ if (!strcmp (symbol_name, "."))
+ {
+ symbol_set_frag (def_symbol_in_progress, frag_now);
+ S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
+ /* If the .val is != from the .def (e.g. statics) */
+ }
+ else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
+ {
+ expressionS exp;
+
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = symbol_find_or_make (symbol_name);
+ exp.X_op_symbol = NULL;
+ exp.X_add_number = 0;
+ symbol_set_value_expression (def_symbol_in_progress, &exp);
+
+ /* If the segment is undefined when the forward reference is
+ resolved, then copy the segment id from the forward
+ symbol. */
+ SF_SET_GET_SEGMENT (def_symbol_in_progress);
+
+ /* FIXME: gcc can generate address expressions here in
+ unusual cases (search for "obscure" in sdbout.c). We
+ just ignore the offset here, thus generating incorrect
+ debugging information. We ignore the rest of the line
+ just below. */
+ }
+ /* Otherwise, it is the name of a non debug symbol and its value
+ will be calculated later. */
+ *input_line_pointer = name_end;
+ }
+ else
+ {
+ S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
+ } /* if symbol based */
+
+ demand_empty_rest_of_line ();
+}
+
+void
+coff_obj_read_begin_hook ()
+{
+ /* These had better be the same. Usually 18 bytes. */
+#ifndef BFD_HEADERS
+ know (sizeof (SYMENT) == sizeof (AUXENT));
+ know (SYMESZ == AUXESZ);
+#endif
+ tag_init ();
+}
+
+symbolS *coff_last_function;
+#ifndef OBJ_XCOFF
+static symbolS *coff_last_bf;
+#endif
+
+void
+coff_frob_symbol (symp, punt)
+ symbolS *symp;
+ int *punt;
+{
+ static symbolS *last_tagP;
+ static stack *block_stack;
+ static symbolS *set_end;
+ symbolS *next_set_end = NULL;
+
+ if (symp == &abs_symbol)
+ {
+ *punt = 1;
+ return;
+ }
+
+ if (current_lineno_sym)
+ coff_add_linesym ((symbolS *) 0);
+
+ if (!block_stack)
+ block_stack = stack_init (512, sizeof (symbolS*));
+
+ if (S_IS_WEAK (symp))
+ {
+#ifdef TE_PE
+ S_SET_STORAGE_CLASS (symp, C_NT_WEAK);
+#else
+ S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
+#endif
+ }
+
+ if (!S_IS_DEFINED (symp)
+ && !S_IS_WEAK (symp)
+ && S_GET_STORAGE_CLASS (symp) != C_STAT)
+ S_SET_STORAGE_CLASS (symp, C_EXT);
+
+ if (!SF_GET_DEBUG (symp))
+ {
+ symbolS * real;
+
+ if (!SF_GET_LOCAL (symp)
+ && !SF_GET_STATICS (symp)
+ && S_GET_STORAGE_CLASS (symp) != C_LABEL
+ && symbol_constant_p(symp)
+ && (real = symbol_find_base (S_GET_NAME (symp), DO_NOT_STRIP))
+ && S_GET_STORAGE_CLASS (real) == C_NULL
+ && real != symp)
+ {
+ c_symbol_merge (symp, real);
+ *punt = 1;
+ return;
+ }
+
+ if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
+ {
+ assert (S_GET_VALUE (symp) == 0);
+ S_SET_EXTERNAL (symp);
+ }
+ else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
+ {
+ if (S_GET_SEGMENT (symp) == text_section
+ && symp != seg_info (text_section)->sym)
+ S_SET_STORAGE_CLASS (symp, C_LABEL);
+ else
+ S_SET_STORAGE_CLASS (symp, C_STAT);
+ }
+
+ if (SF_GET_PROCESS (symp))
+ {
+ if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
+ {
+ if (!strcmp (S_GET_NAME (symp), ".bb"))
+ stack_push (block_stack, (char *) &symp);
+ else
+ {
+ symbolS *begin;
+
+ begin = *(symbolS **) stack_pop (block_stack);
+ if (begin == 0)
+ as_warn (_("mismatched .eb"));
+ else
+ next_set_end = begin;
+ }
+ }
+
+ if (coff_last_function == 0 && SF_GET_FUNCTION (symp))
+ {
+ union internal_auxent *auxp;
+
+ coff_last_function = symp;
+ if (S_GET_NUMBER_AUXILIARY (symp) < 1)
+ S_SET_NUMBER_AUXILIARY (symp, 1);
+ auxp = SYM_AUXENT (symp);
+ memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
+ sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
+ }
+
+ if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
+ {
+ if (coff_last_function == 0)
+ as_fatal (_("C_EFCN symbol out of scope"));
+ SA_SET_SYM_FSIZE (coff_last_function,
+ (long) (S_GET_VALUE (symp)
+ - S_GET_VALUE (coff_last_function)));
+ next_set_end = coff_last_function;
+ coff_last_function = 0;
+ }
+ }
+
+ if (S_IS_EXTERNAL (symp))
+ S_SET_STORAGE_CLASS (symp, C_EXT);
+ else if (SF_GET_LOCAL (symp))
+ *punt = 1;
+
+ if (SF_GET_FUNCTION (symp))
+ symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
+
+ /* more ... */
+ }
+
+ /* Double check weak symbols. */
+ if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
+ as_bad (_("Symbol `%s' can not be both weak and common"),
+ S_GET_NAME (symp));
+
+ if (SF_GET_TAG (symp))
+ last_tagP = symp;
+ else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
+ next_set_end = last_tagP;
+
+#ifdef OBJ_XCOFF
+ /* This is pretty horrible, but we have to set *punt correctly in
+ order to call SA_SET_SYM_ENDNDX correctly. */
+ if (! symbol_used_in_reloc_p (symp)
+ && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
+ || (! S_IS_EXTERNAL (symp)
+ && ! symbol_get_tc (symp)->output
+ && S_GET_STORAGE_CLASS (symp) != C_FILE)))
+ *punt = 1;
+#endif
+
+ if (set_end != (symbolS *) NULL
+ && ! *punt
+ && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
+ || (S_IS_DEFINED (symp)
+ && ! S_IS_COMMON (symp)
+ && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
+ {
+ SA_SET_SYM_ENDNDX (set_end, symp);
+ set_end = NULL;
+ }
+
+ if (next_set_end != NULL)
+ {
+ if (set_end != NULL)
+ as_warn ("Warning: internal error: forgetting to set endndx of %s",
+ S_GET_NAME (set_end));
+ set_end = next_set_end;
+ }
+
+#ifndef OBJ_XCOFF
+ if (! *punt
+ && S_GET_STORAGE_CLASS (symp) == C_FCN
+ && strcmp (S_GET_NAME (symp), ".bf") == 0)
+ {
+ if (coff_last_bf != NULL)
+ SA_SET_SYM_ENDNDX (coff_last_bf, symp);
+ coff_last_bf = symp;
+ }
+#endif
+ if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
+ {
+ int i;
+ struct line_no *lptr;
+ alent *l;
+
+ lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
+ for (i = 0; lptr; lptr = lptr->next)
+ i++;
+ lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
+
+ /* We need i entries for line numbers, plus 1 for the first
+ entry which BFD will override, plus 1 for the last zero
+ entry (a marker for BFD). */
+ l = (alent *) xmalloc ((i + 2) * sizeof (alent));
+ coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
+ l[i + 1].line_number = 0;
+ l[i + 1].u.sym = NULL;
+ for (; i > 0; i--)
+ {
+ if (lptr->frag)
+ lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
+ l[i] = lptr->l;
+ lptr = lptr->next;
+ }
+ }
+}
+
+void
+coff_adjust_section_syms (abfd, sec, x)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *sec;
+ PTR x ATTRIBUTE_UNUSED;
+{
+ symbolS *secsym;
+ segment_info_type *seginfo = seg_info (sec);
+ int nlnno, nrelocs = 0;
+
+ /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
+ tc-ppc.c. Do not get confused by it. */
+ if (seginfo == NULL)
+ return;
+
+ if (!strcmp (sec->name, ".text"))
+ nlnno = coff_n_line_nos;
+ else
+ nlnno = 0;
+ {
+ /* @@ Hope that none of the fixups expand to more than one reloc
+ entry... */
+ fixS *fixp = seginfo->fix_root;
+ while (fixp)
+ {
+ if (! fixp->fx_done)
+ nrelocs++;
+ fixp = fixp->fx_next;
+ }
+ }
+ if (bfd_get_section_size_before_reloc (sec) == 0
+ && nrelocs == 0
+ && nlnno == 0
+ && sec != text_section
+ && sec != data_section
+ && sec != bss_section)
+ return;
+ secsym = section_symbol (sec);
+ /* This is an estimate; we'll plug in the real value using
+ SET_SECTION_RELOCS later */
+ SA_SET_SCN_NRELOC (secsym, nrelocs);
+ SA_SET_SCN_NLINNO (secsym, nlnno);
+}
+
+void
+coff_frob_file_after_relocs ()
+{
+ bfd_map_over_sections (stdoutput, coff_adjust_section_syms, (char*) 0);
+}
+
+/* Implement the .section pseudo op:
+ .section name {, "flags"}
+ ^ ^
+ | +--- optional flags: 'b' for bss
+ | 'i' for info
+ +-- section name 'l' for lib
+ 'n' for noload
+ 'o' for over
+ 'w' for data
+ 'd' (apparently m88k for data)
+ 'x' for text
+ 'r' for read-only data
+ 's' for shared data (PE)
+ But if the argument is not a quoted string, treat it as a
+ subsegment number.
+
+ Note the 'a' flag is silently ignored. This allows the same
+ .section directive to be parsed in both ELF and COFF formats. */
+
+void
+obj_coff_section (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ /* Strip out the section name */
+ char *section_name;
+ char c;
+ char *name;
+ unsigned int exp;
+ flagword flags, oldflags;
+ asection *sec;
+
+ if (flag_mri)
+ {
+ char type;
+
+ s_mri_sect (&type);
+ return;
+ }
+
+ section_name = input_line_pointer;
+ c = get_symbol_end ();
+
+ name = xmalloc (input_line_pointer - section_name + 1);
+ strcpy (name, section_name);
+
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+
+ exp = 0;
+ flags = SEC_NO_FLAGS;
+
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '"')
+ exp = get_absolute_expression ();
+ else
+ {
+ ++input_line_pointer;
+ while (*input_line_pointer != '"'
+ && ! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ switch (*input_line_pointer)
+ {
+ case 'b': flags |= SEC_ALLOC; flags &=~ SEC_LOAD; break;
+ case 'n': flags &=~ SEC_LOAD; flags |= SEC_NEVER_LOAD; break;
+
+ case 's': flags |= SEC_SHARED; /* fall through */
+ case 'd': flags |= SEC_DATA | SEC_LOAD; /* fall through */
+ case 'w': flags &=~ SEC_READONLY; break;
+
+ case 'a': break; /* For compatibility with ELF. */
+ case 'x': flags |= SEC_CODE | SEC_LOAD; break;
+ case 'r': flags |= SEC_DATA | SEC_LOAD | SEC_READONLY; break;
+
+ case 'i': /* STYP_INFO */
+ case 'l': /* STYP_LIB */
+ case 'o': /* STYP_OVER */
+ as_warn (_("unsupported section attribute '%c'"),
+ *input_line_pointer);
+ break;
+
+ default:
+ as_warn(_("unknown section attribute '%c'"),
+ *input_line_pointer);
+ break;
+ }
+ ++input_line_pointer;
+ }
+ if (*input_line_pointer == '"')
+ ++input_line_pointer;
+ }
+ }
+
+ sec = subseg_new (name, (subsegT) exp);
+
+ oldflags = bfd_get_section_flags (stdoutput, sec);
+ if (oldflags == SEC_NO_FLAGS)
+ {
+ /* Set section flags for a new section just created by subseg_new.
+ Provide a default if no flags were parsed. */
+ if (flags == SEC_NO_FLAGS)
+ flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
+
+#ifdef COFF_LONG_SECTION_NAMES
+ /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
+ sections so adjust_reloc_syms in write.c will correctly handle
+ relocs which refer to non-local symbols in these sections. */
+ if (strncmp (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1) == 0)
+ flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
+#endif
+
+ if (! bfd_set_section_flags (stdoutput, sec, flags))
+ as_warn (_("error setting flags for \"%s\": %s"),
+ bfd_section_name (stdoutput, sec),
+ bfd_errmsg (bfd_get_error ()));
+ }
+ else if (flags != SEC_NO_FLAGS)
+ {
+ /* This section's attributes have already been set. Warn if the
+ attributes don't match. */
+ flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
+ | SEC_DATA | SEC_SHARED | SEC_NEVER_LOAD);
+ if ((flags ^ oldflags) & matchflags)
+ as_warn (_("Ignoring changed section attributes for %s"), name);
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+void
+coff_adjust_symtab ()
+{
+ if (symbol_rootP == NULL
+ || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
+ c_dot_file_symbol ("fake");
+}
+
+void
+coff_frob_section (sec)
+ segT sec;
+{
+ segT strsec;
+ char *p;
+ fragS *fragp;
+ bfd_vma size, n_entries, mask;
+ bfd_vma align_power = (bfd_vma)sec->alignment_power + OCTETS_PER_BYTE_POWER;
+
+ /* The COFF back end in BFD requires that all section sizes be
+ rounded up to multiples of the corresponding section alignments,
+ supposedly because standard COFF has no other way of encoding alignment
+ for sections. If your COFF flavor has a different way of encoding
+ section alignment, then skip this step, as TICOFF does. */
+ size = bfd_get_section_size_before_reloc (sec);
+ mask = ((bfd_vma) 1 << align_power) - 1;
+#if !defined(TICOFF)
+ if (size & mask)
+ {
+ bfd_vma new_size;
+ fragS *last;
+
+ new_size = (size + mask) & ~mask;
+ bfd_set_section_size (stdoutput, sec, new_size);
+
+ /* If the size had to be rounded up, add some padding in
+ the last non-empty frag. */
+ fragp = seg_info (sec)->frchainP->frch_root;
+ last = seg_info (sec)->frchainP->frch_last;
+ while (fragp->fr_next != last)
+ fragp = fragp->fr_next;
+ last->fr_address = size;
+ fragp->fr_offset += new_size - size;
+ }
+#endif
+
+ /* If the section size is non-zero, the section symbol needs an aux
+ entry associated with it, indicating the size. We don't know
+ all the values yet; coff_frob_symbol will fill them in later. */
+#ifndef TICOFF
+ if (size != 0
+ || sec == text_section
+ || sec == data_section
+ || sec == bss_section)
+#endif
+ {
+ symbolS *secsym = section_symbol (sec);
+
+ S_SET_STORAGE_CLASS (secsym, C_STAT);
+ S_SET_NUMBER_AUXILIARY (secsym, 1);
+ SF_SET_STATICS (secsym);
+ SA_SET_SCN_SCNLEN (secsym, size);
+ }
+
+ /* @@ these should be in a "stabs.h" file, or maybe as.h */
+#ifndef STAB_SECTION_NAME
+#define STAB_SECTION_NAME ".stab"
+#endif
+#ifndef STAB_STRING_SECTION_NAME
+#define STAB_STRING_SECTION_NAME ".stabstr"
+#endif
+ if (strcmp (STAB_STRING_SECTION_NAME, sec->name))
+ return;
+
+ strsec = sec;
+ sec = subseg_get (STAB_SECTION_NAME, 0);
+ /* size is already rounded up, since other section will be listed first */
+ size = bfd_get_section_size_before_reloc (strsec);
+
+ n_entries = bfd_get_section_size_before_reloc (sec) / 12 - 1;
+
+ /* Find first non-empty frag. It should be large enough. */
+ fragp = seg_info (sec)->frchainP->frch_root;
+ while (fragp && fragp->fr_fix == 0)
+ fragp = fragp->fr_next;
+ assert (fragp != 0 && fragp->fr_fix >= 12);
+
+ /* Store the values. */
+ p = fragp->fr_literal;
+ bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
+ bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
+}
+
+void
+obj_coff_init_stab_section (seg)
+ segT seg;
+{
+ char *file;
+ char *p;
+ char *stabstr_name;
+ unsigned int stroff;
+
+ /* Make space for this first symbol. */
+ p = frag_more (12);
+ /* Zero it out. */
+ memset (p, 0, 12);
+ as_where (&file, (unsigned int *) NULL);
+ stabstr_name = (char *) xmalloc (strlen (seg->name) + 4);
+ strcpy (stabstr_name, seg->name);
+ strcat (stabstr_name, "str");
+ stroff = get_stab_string_offset (file, stabstr_name);
+ know (stroff == 1);
+ md_number_to_chars (p, stroff, 4);
+}
+
+#ifdef DEBUG
+/* for debugging */
+const char *
+s_get_name (s)
+ symbolS *s;
+{
+ return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
+}
+
+void
+symbol_dump ()
+{
+ symbolS *symbolP;
+
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ {
+ printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
+ (unsigned long) symbolP,
+ S_GET_NAME(symbolP),
+ (long) S_GET_DATA_TYPE(symbolP),
+ S_GET_STORAGE_CLASS(symbolP),
+ (int) S_GET_SEGMENT(symbolP));
+ }
+}
+
+#endif /* DEBUG */
+
+#else /* not BFD_ASSEMBLER */
+
+#include "frags.h"
+/* This is needed because we include internal bfd things. */
+#include <time.h>
+
+#include "libbfd.h"
+#include "libcoff.h"
+
+#ifdef TE_PE
+#include "coff/pe.h"
+#endif
+
+/* The NOP_OPCODE is for the alignment fill value. Fill with nop so
+ that we can stick sections together without causing trouble. */
+#ifndef NOP_OPCODE
+#define NOP_OPCODE 0x00
+#endif
+
+/* The zeroes if symbol name is longer than 8 chars */
+#define S_SET_ZEROES(s,v) ((s)->sy_symbol.ost_entry.n_zeroes = (v))
+
+#define MIN(a,b) ((a) < (b)? (a) : (b))
+
+/* This vector is used to turn a gas internal segment number into a
+ section number suitable for insertion into a coff symbol table.
+ This must correspond to seg_info_off_by_4. */
+
+const short seg_N_TYPE[] =
+{ /* in: segT out: N_TYPE bits */
+ C_ABS_SECTION,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ C_UNDEF_SECTION, /* SEG_UNKNOWN */
+ C_UNDEF_SECTION, /* SEG_GOOF */
+ C_UNDEF_SECTION, /* SEG_EXPR */
+ C_DEBUG_SECTION, /* SEG_DEBUG */
+ C_NTV_SECTION, /* SEG_NTV */
+ C_PTV_SECTION, /* SEG_PTV */
+ C_REGISTER_SECTION, /* SEG_REGISTER */
+};
+
+int function_lineoff = -1; /* Offset in line#s where the last function
+ started (the odd entry for line #0) */
+
+/* Structure used to keep the filenames which
+ are too long around so that we can stick them
+ into the string table. */
+struct filename_list
+{
+ char *filename;
+ struct filename_list *next;
+};
+
+static struct filename_list *filename_list_head;
+static struct filename_list *filename_list_tail;
+
+static symbolS *last_line_symbol;
+
+/* Add 4 to the real value to get the index and compensate the
+ negatives. This vector is used by S_GET_SEGMENT to turn a coff
+ section number into a segment number. */
+
+bfd *abfd;
+static symbolS *previous_file_symbol;
+static int line_base;
+
+void c_symbol_merge PARAMS ((symbolS *, symbolS *));
+symbolS *c_section_symbol PARAMS ((char *, int));
+void obj_coff_section PARAMS ((int));
+void do_relocs_for PARAMS ((bfd *, object_headers *, unsigned long *));
+char * symbol_to_chars PARAMS ((bfd *, char *, symbolS *));
+void w_strings PARAMS ((char *));
+
+static void fixup_segment PARAMS ((segment_info_type *, segT));
+static void fixup_mdeps PARAMS ((fragS *, object_headers *, segT));
+static void fill_section PARAMS ((bfd *, object_headers *, unsigned long *));
+static int c_line_new PARAMS ((symbolS *, long, int, fragS *));
+static void w_symbols PARAMS ((bfd *, char *, symbolS *));
+static void adjust_stab_section PARAMS ((bfd *, segT));
+static void obj_coff_lcomm PARAMS ((int));
+static void obj_coff_text PARAMS ((int));
+static void obj_coff_data PARAMS ((int));
+static unsigned int count_entries_in_chain PARAMS ((unsigned int));
+static void coff_header_append PARAMS ((bfd *, object_headers *));
+static unsigned int yank_symbols PARAMS ((void));
+static unsigned int glue_symbols PARAMS ((symbolS **, symbolS **));
+static unsigned int tie_tags PARAMS ((void));
+static void crawl_symbols PARAMS ((object_headers *, bfd *));
+static void do_linenos_for PARAMS ((bfd *, object_headers *, unsigned long *));
+static void remove_subsegs PARAMS ((void));
+
+
+
+/* When not using BFD_ASSEMBLER, we permit up to 40 sections.
+
+ This array maps a COFF section number into a gas section number.
+ Because COFF uses negative section numbers, you must add 4 to the
+ COFF section number when indexing into this array; this is done via
+ the SEG_INFO_FROM_SECTION_NUMBER macro. This must correspond to
+ seg_N_TYPE. */
+
+static const segT seg_info_off_by_4[] =
+{
+ SEG_PTV,
+ SEG_NTV,
+ SEG_DEBUG,
+ SEG_ABSOLUTE,
+ SEG_UNKNOWN,
+ SEG_E0, SEG_E1, SEG_E2, SEG_E3, SEG_E4,
+ SEG_E5, SEG_E6, SEG_E7, SEG_E8, SEG_E9,
+ SEG_E10, SEG_E11, SEG_E12, SEG_E13, SEG_E14,
+ SEG_E15, SEG_E16, SEG_E17, SEG_E18, SEG_E19,
+ SEG_E20, SEG_E21, SEG_E22, SEG_E23, SEG_E24,
+ SEG_E25, SEG_E26, SEG_E27, SEG_E28, SEG_E29,
+ SEG_E30, SEG_E31, SEG_E32, SEG_E33, SEG_E34,
+ SEG_E35, SEG_E36, SEG_E37, SEG_E38, SEG_E39,
+ (segT) 40,
+ (segT) 41,
+ (segT) 42,
+ (segT) 43,
+ (segT) 44,
+ (segT) 45,
+ (segT) 0,
+ (segT) 0,
+ (segT) 0,
+ SEG_REGISTER
+};
+
+#define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
+
+static relax_addressT relax_align PARAMS ((relax_addressT, long));
+
+static relax_addressT
+relax_align (address, alignment)
+ relax_addressT address;
+ long alignment;
+{
+ relax_addressT mask;
+ relax_addressT new_address;
+
+ mask = ~((~0) << alignment);
+ new_address = (address + mask) & (~mask);
+ return (new_address - address);
+}
+
+segT
+s_get_segment (x)
+ symbolS * x;
+{
+ return SEG_INFO_FROM_SECTION_NUMBER (x->sy_symbol.ost_entry.n_scnum);
+}
+
+static unsigned int size_section PARAMS ((bfd *, unsigned int));
+
+/* Calculate the size of the frag chain and fill in the section header
+ to contain all of it, also fill in the addr of the sections. */
+
+static unsigned int
+size_section (abfd, idx)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ unsigned int idx;
+{
+
+ unsigned int size = 0;
+ fragS *frag = segment_info[idx].frchainP->frch_root;
+
+ while (frag)
+ {
+ size = frag->fr_address;
+ if (frag->fr_address != size)
+ {
+ fprintf (stderr, _("Out of step\n"));
+ size = frag->fr_address;
+ }
+
+ switch (frag->fr_type)
+ {
+#ifdef TC_COFF_SIZEMACHDEP
+ case rs_machine_dependent:
+ size += TC_COFF_SIZEMACHDEP (frag);
+ break;
+#endif
+ case rs_space:
+ case rs_fill:
+ case rs_org:
+ size += frag->fr_fix;
+ size += frag->fr_offset * frag->fr_var;
+ break;
+ case rs_align:
+ case rs_align_code:
+ case rs_align_test:
+ {
+ addressT off;
+
+ size += frag->fr_fix;
+ off = relax_align (size, frag->fr_offset);
+ if (frag->fr_subtype != 0 && off > frag->fr_subtype)
+ off = 0;
+ size += off;
+ }
+ break;
+ default:
+ BAD_CASE (frag->fr_type);
+ break;
+ }
+ frag = frag->fr_next;
+ }
+ segment_info[idx].scnhdr.s_size = size;
+ return size;
+}
+
+static unsigned int
+count_entries_in_chain (idx)
+ unsigned int idx;
+{
+ unsigned int nrelocs;
+ fixS *fixup_ptr;
+
+ /* Count the relocations. */
+ fixup_ptr = segment_info[idx].fix_root;
+ nrelocs = 0;
+ while (fixup_ptr != (fixS *) NULL)
+ {
+ if (fixup_ptr->fx_done == 0 && TC_COUNT_RELOC (fixup_ptr))
+ {
+#if defined(TC_A29K) || defined(TC_OR32)
+ if (fixup_ptr->fx_r_type == RELOC_CONSTH)
+ nrelocs += 2;
+ else
+ nrelocs++;
+#else
+ nrelocs++;
+#endif
+ }
+
+ fixup_ptr = fixup_ptr->fx_next;
+ }
+ return nrelocs;
+}
+
+#ifdef TE_AUX
+
+static int compare_external_relocs PARAMS ((const PTR, const PTR));
+
+/* AUX's ld expects relocations to be sorted. */
+
+static int
+compare_external_relocs (x, y)
+ const PTR x;
+ const PTR y;
+{
+ struct external_reloc *a = (struct external_reloc *) x;
+ struct external_reloc *b = (struct external_reloc *) y;
+ bfd_vma aadr = bfd_getb32 (a->r_vaddr);
+ bfd_vma badr = bfd_getb32 (b->r_vaddr);
+ return (aadr < badr ? -1 : badr < aadr ? 1 : 0);
+}
+
+#endif
+
+/* Output all the relocations for a section. */
+
+void
+do_relocs_for (abfd, h, file_cursor)
+ bfd * abfd;
+ object_headers * h;
+ unsigned long *file_cursor;
+{
+ unsigned int nrelocs;
+ unsigned int idx;
+ unsigned long reloc_start = *file_cursor;
+
+ for (idx = SEG_E0; idx < SEG_LAST; idx++)
+ {
+ if (segment_info[idx].scnhdr.s_name[0])
+ {
+ struct external_reloc *ext_ptr;
+ struct external_reloc *external_reloc_vec;
+ unsigned int external_reloc_size;
+ unsigned int base = segment_info[idx].scnhdr.s_paddr;
+ fixS *fix_ptr = segment_info[idx].fix_root;
+ nrelocs = count_entries_in_chain (idx);
+
+ if (nrelocs)
+ /* Bypass this stuff if no relocs. This also incidentally
+ avoids a SCO bug, where free(malloc(0)) tends to crash. */
+ {
+ external_reloc_size = nrelocs * RELSZ;
+ external_reloc_vec =
+ (struct external_reloc *) malloc (external_reloc_size);
+
+ ext_ptr = external_reloc_vec;
+
+ /* Fill in the internal coff style reloc struct from the
+ internal fix list. */
+ while (fix_ptr)
+ {
+ struct internal_reloc intr;
+
+ /* Only output some of the relocations. */
+ if (fix_ptr->fx_done == 0 && TC_COUNT_RELOC (fix_ptr))
+ {
+#ifdef TC_RELOC_MANGLE
+ TC_RELOC_MANGLE (&segment_info[idx], fix_ptr, &intr,
+ base);
+#else
+ symbolS *dot;
+ symbolS *symbol_ptr = fix_ptr->fx_addsy;
+
+ intr.r_type = TC_COFF_FIX2RTYPE (fix_ptr);
+ intr.r_vaddr =
+ base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where;
+
+#ifdef TC_KEEP_FX_OFFSET
+ intr.r_offset = fix_ptr->fx_offset;
+#else
+ intr.r_offset = 0;
+#endif
+
+ while (symbol_ptr->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (symbol_ptr)
+ || S_IS_COMMON (symbol_ptr)))
+ {
+ symbolS *n;
+
+ /* We must avoid looping, as that can occur
+ with a badly written program. */
+ n = symbol_ptr->sy_value.X_add_symbol;
+ if (n == symbol_ptr)
+ break;
+ symbol_ptr = n;
+ }
+
+ /* Turn the segment of the symbol into an offset. */
+ if (symbol_ptr)
+ {
+ resolve_symbol_value (symbol_ptr);
+ if (! symbol_ptr->sy_resolved)
+ {
+ char *file;
+ unsigned int line;
+
+ if (expr_symbol_where (symbol_ptr, &file, &line))
+ as_bad_where (file, line,
+ _("unresolved relocation"));
+ else
+ as_bad (_("bad relocation: symbol `%s' not in symbol table"),
+ S_GET_NAME (symbol_ptr));
+ }
+
+ dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
+ if (dot)
+ intr.r_symndx = dot->sy_number;
+ else
+ intr.r_symndx = symbol_ptr->sy_number;
+ }
+ else
+ intr.r_symndx = -1;
+#endif
+ (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
+ ext_ptr++;
+#if defined(TC_A29K)
+ /* The 29k has a special kludge for the high 16 bit
+ reloc. Two relocations are emitted, R_IHIHALF,
+ and R_IHCONST. The second one doesn't contain a
+ symbol, but uses the value for offset. */
+ if (intr.r_type == R_IHIHALF)
+ {
+ /* Now emit the second bit. */
+ intr.r_type = R_IHCONST;
+ intr.r_symndx = fix_ptr->fx_addnumber;
+ (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
+ ext_ptr++;
+ }
+#endif
+#if defined(TC_OR32)
+ /* The or32 has a special kludge for the high 16 bit
+ reloc. Two relocations are emitted, R_IHIHALF,
+ and R_IHCONST. The second one doesn't contain a
+ symbol, but uses the value for offset. */
+ if (intr.r_type == R_IHIHALF)
+ {
+ /* Now emit the second bit. */
+ intr.r_type = R_IHCONST;
+ intr.r_symndx = fix_ptr->fx_addnumber;
+ (void) bfd_coff_swap_reloc_out (abfd, & intr, ext_ptr);
+ ext_ptr ++;
+ }
+#endif
+ }
+
+ fix_ptr = fix_ptr->fx_next;
+ }
+#ifdef TE_AUX
+ /* Sort the reloc table. */
+ qsort ((PTR) external_reloc_vec, nrelocs,
+ sizeof (struct external_reloc), compare_external_relocs);
+#endif
+ /* Write out the reloc table. */
+ bfd_bwrite ((PTR) external_reloc_vec,
+ (bfd_size_type) external_reloc_size, abfd);
+ free (external_reloc_vec);
+
+ /* Fill in section header info. */
+ segment_info[idx].scnhdr.s_relptr = *file_cursor;
+ *file_cursor += external_reloc_size;
+ segment_info[idx].scnhdr.s_nreloc = nrelocs;
+ }
+ else
+ {
+ /* No relocs. */
+ segment_info[idx].scnhdr.s_relptr = 0;
+ }
+ }
+ }
+
+ /* Set relocation_size field in file headers. */
+ H_SET_RELOCATION_SIZE (h, *file_cursor - reloc_start, 0);
+}
+
+/* Run through a frag chain and write out the data to go with it, fill
+ in the scnhdrs with the info on the file positions. */
+
+static void
+fill_section (abfd, h, file_cursor)
+ bfd * abfd;
+ object_headers *h ATTRIBUTE_UNUSED;
+ unsigned long *file_cursor;
+{
+ unsigned int i;
+ unsigned int paddr = 0;
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ unsigned int offset = 0;
+ struct internal_scnhdr *s = &(segment_info[i].scnhdr);
+
+ PROGRESS (1);
+
+ if (s->s_name[0])
+ {
+ fragS *frag = segment_info[i].frchainP->frch_root;
+ char *buffer = NULL;
+
+ if (s->s_size == 0)
+ s->s_scnptr = 0;
+ else
+ {
+ buffer = xmalloc (s->s_size);
+ s->s_scnptr = *file_cursor;
+ }
+ know (s->s_paddr == paddr);
+
+ if (strcmp (s->s_name, ".text") == 0)
+ s->s_flags |= STYP_TEXT;
+ else if (strcmp (s->s_name, ".data") == 0)
+ s->s_flags |= STYP_DATA;
+ else if (strcmp (s->s_name, ".bss") == 0)
+ {
+ s->s_scnptr = 0;
+ s->s_flags |= STYP_BSS;
+
+ /* @@ Should make the i386 and a29k coff targets define
+ COFF_NOLOAD_PROBLEM, and have only one test here. */
+#ifndef TC_I386
+#ifndef TC_A29K
+#ifndef TC_OR32
+#ifndef COFF_NOLOAD_PROBLEM
+ /* Apparently the SVR3 linker (and exec syscall) and UDI
+ mondfe progrem are confused by noload sections. */
+ s->s_flags |= STYP_NOLOAD;
+#endif
+#endif
+#endif
+#endif
+ }
+ else if (strcmp (s->s_name, ".lit") == 0)
+ s->s_flags = STYP_LIT | STYP_TEXT;
+ else if (strcmp (s->s_name, ".init") == 0)
+ s->s_flags |= STYP_TEXT;
+ else if (strcmp (s->s_name, ".fini") == 0)
+ s->s_flags |= STYP_TEXT;
+ else if (strncmp (s->s_name, ".comment", 8) == 0)
+ s->s_flags |= STYP_INFO;
+
+ while (frag)
+ {
+ unsigned int fill_size;
+ switch (frag->fr_type)
+ {
+ case rs_machine_dependent:
+ if (frag->fr_fix)
+ {
+ memcpy (buffer + frag->fr_address,
+ frag->fr_literal,
+ (unsigned int) frag->fr_fix);
+ offset += frag->fr_fix;
+ }
+
+ break;
+ case rs_space:
+ case rs_fill:
+ case rs_align:
+ case rs_align_code:
+ case rs_align_test:
+ case rs_org:
+ if (frag->fr_fix)
+ {
+ memcpy (buffer + frag->fr_address,
+ frag->fr_literal,
+ (unsigned int) frag->fr_fix);
+ offset += frag->fr_fix;
+ }
+
+ fill_size = frag->fr_var;
+ if (fill_size && frag->fr_offset > 0)
+ {
+ unsigned int count;
+ unsigned int off = frag->fr_fix;
+ for (count = frag->fr_offset; count; count--)
+ {
+ if (fill_size + frag->fr_address + off <= s->s_size)
+ {
+ memcpy (buffer + frag->fr_address + off,
+ frag->fr_literal + frag->fr_fix,
+ fill_size);
+ off += fill_size;
+ offset += fill_size;
+ }
+ }
+ }
+ break;
+ case rs_broken_word:
+ break;
+ default:
+ abort ();
+ }
+ frag = frag->fr_next;
+ }
+
+ if (s->s_size != 0)
+ {
+ if (s->s_scnptr != 0)
+ {
+ bfd_bwrite (buffer, s->s_size, abfd);
+ *file_cursor += s->s_size;
+ }
+ free (buffer);
+ }
+ paddr += s->s_size;
+ }
+ }
+}
+
+/* Coff file generation & utilities. */
+
+static void
+coff_header_append (abfd, h)
+ bfd * abfd;
+ object_headers * h;
+{
+ unsigned int i;
+ char buffer[1000];
+ char buffero[1000];
+#ifdef COFF_LONG_SECTION_NAMES
+ unsigned long string_size = 4;
+#endif
+
+ bfd_seek (abfd, (file_ptr) 0, 0);
+
+#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
+ H_SET_MAGIC_NUMBER (h, COFF_MAGIC);
+ H_SET_VERSION_STAMP (h, 0);
+ H_SET_ENTRY_POINT (h, 0);
+ H_SET_TEXT_START (h, segment_info[SEG_E0].frchainP->frch_root->fr_address);
+ H_SET_DATA_START (h, segment_info[SEG_E1].frchainP->frch_root->fr_address);
+ H_SET_SIZEOF_OPTIONAL_HEADER (h, bfd_coff_swap_aouthdr_out(abfd, &h->aouthdr,
+ buffero));
+#else /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */
+ H_SET_SIZEOF_OPTIONAL_HEADER (h, 0);
+#endif /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */
+
+ i = bfd_coff_swap_filehdr_out (abfd, &h->filehdr, buffer);
+
+ bfd_bwrite (buffer, (bfd_size_type) i, abfd);
+ bfd_bwrite (buffero, (bfd_size_type) H_GET_SIZEOF_OPTIONAL_HEADER (h), abfd);
+
+ for (i = SEG_E0; i < SEG_LAST; i++)
+ {
+ if (segment_info[i].scnhdr.s_name[0])
+ {
+ unsigned int size;
+
+#ifdef COFF_LONG_SECTION_NAMES
+ /* Support long section names as found in PE. This code
+ must coordinate with that in write_object_file and
+ w_strings. */
+ if (strlen (segment_info[i].name) > SCNNMLEN)
+ {
+ memset (segment_info[i].scnhdr.s_name, 0, SCNNMLEN);
+ sprintf (segment_info[i].scnhdr.s_name, "/%lu", string_size);
+ string_size += strlen (segment_info[i].name) + 1;
+ }
+#endif
+ size = bfd_coff_swap_scnhdr_out (abfd,
+ &(segment_info[i].scnhdr),
+ buffer);
+ if (size == 0)
+ as_bad (_("bfd_coff_swap_scnhdr_out failed"));
+ bfd_bwrite (buffer, (bfd_size_type) size, abfd);
+ }
+ }
+}
+
+char *
+symbol_to_chars (abfd, where, symbolP)
+ bfd * abfd;
+ char *where;
+ symbolS * symbolP;
+{
+ unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
+ unsigned int i;
+ valueT val;
+
+ /* Turn any symbols with register attributes into abs symbols. */
+ if (S_GET_SEGMENT (symbolP) == reg_section)
+ S_SET_SEGMENT (symbolP, absolute_section);
+
+ /* At the same time, relocate all symbols to their output value. */
+#ifndef TE_PE
+ val = (segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr
+ + S_GET_VALUE (symbolP));
+#else
+ val = S_GET_VALUE (symbolP);
+#endif
+
+ S_SET_VALUE (symbolP, val);
+
+ symbolP->sy_symbol.ost_entry.n_value = val;
+
+ where += bfd_coff_swap_sym_out (abfd, &symbolP->sy_symbol.ost_entry,
+ where);
+
+ for (i = 0; i < numaux; i++)
+ {
+ where += bfd_coff_swap_aux_out (abfd,
+ &symbolP->sy_symbol.ost_auxent[i],
+ S_GET_DATA_TYPE (symbolP),
+ S_GET_STORAGE_CLASS (symbolP),
+ i, numaux, where);
+ }
+
+ return where;
+}
+
+void
+coff_obj_symbol_new_hook (symbolP)
+ symbolS *symbolP;
+{
+ char underscore = 0; /* Symbol has leading _ */
+
+ /* Effective symbol. */
+ /* Store the pointer in the offset. */
+ S_SET_ZEROES (symbolP, 0L);
+ S_SET_DATA_TYPE (symbolP, T_NULL);
+ S_SET_STORAGE_CLASS (symbolP, 0);
+ S_SET_NUMBER_AUXILIARY (symbolP, 0);
+ /* Additional information. */
+ symbolP->sy_symbol.ost_flags = 0;
+ /* Auxiliary entries. */
+ memset ((char *) &symbolP->sy_symbol.ost_auxent[0], 0, AUXESZ);
+
+ if (S_IS_STRING (symbolP))
+ SF_SET_STRING (symbolP);
+ if (!underscore && S_IS_LOCAL (symbolP))
+ SF_SET_LOCAL (symbolP);
+}
+
+/* Handle .ln directives. */
+
+static void
+obj_coff_ln (appline)
+ int appline;
+{
+ int l;
+
+ if (! appline && def_symbol_in_progress != NULL)
+ {
+ /* Wrong context. */
+ as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ l = get_absolute_expression ();
+ c_line_new (0, frag_now_fix (), l, frag_now);
+
+ if (appline)
+ new_logical_line ((char *) NULL, l - 1);
+
+#ifndef NO_LISTING
+ {
+ extern int listing;
+
+ if (listing)
+ {
+ if (! appline)
+ l += line_base - 1;
+ listing_source_line ((unsigned int) l);
+ }
+
+ }
+#endif
+ demand_empty_rest_of_line ();
+}
+
+/* Handle .def directives.
+
+ One might ask : why can't we symbol_new if the symbol does not
+ already exist and fill it with debug information. Because of
+ the C_EFCN special symbol. It would clobber the value of the
+ function symbol before we have a chance to notice that it is
+ a C_EFCN. And a second reason is that the code is more clear this
+ way. (at least I think it is :-). */
+
+#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
+#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
+ *input_line_pointer == '\t') \
+ input_line_pointer++;
+
+static void
+obj_coff_def (what)
+ int what ATTRIBUTE_UNUSED;
+{
+ char name_end; /* Char after the end of name. */
+ char *symbol_name; /* Name of the debug symbol. */
+ char *symbol_name_copy; /* Temporary copy of the name. */
+ unsigned int symbol_name_length;
+
+ if (def_symbol_in_progress != NULL)
+ {
+ as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ SKIP_WHITESPACES ();
+
+ def_symbol_in_progress = (symbolS *) obstack_alloc (&notes, sizeof (*def_symbol_in_progress));
+ memset (def_symbol_in_progress, 0, sizeof (*def_symbol_in_progress));
+
+ symbol_name = input_line_pointer;
+ name_end = get_symbol_end ();
+ symbol_name_length = strlen (symbol_name);
+ symbol_name_copy = xmalloc (symbol_name_length + 1);
+ strcpy (symbol_name_copy, symbol_name);
+#ifdef tc_canonicalize_symbol_name
+ symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
+#endif
+
+ /* Initialize the new symbol. */
+#ifdef STRIP_UNDERSCORE
+ S_SET_NAME (def_symbol_in_progress, (*symbol_name_copy == '_'
+ ? symbol_name_copy + 1
+ : symbol_name_copy));
+#else /* STRIP_UNDERSCORE */
+ S_SET_NAME (def_symbol_in_progress, symbol_name_copy);
+#endif /* STRIP_UNDERSCORE */
+ /* free(symbol_name_copy); */
+ def_symbol_in_progress->sy_name_offset = (unsigned long) ~0;
+ def_symbol_in_progress->sy_number = ~0;
+ def_symbol_in_progress->sy_frag = &zero_address_frag;
+ S_SET_VALUE (def_symbol_in_progress, 0);
+
+ if (S_IS_STRING (def_symbol_in_progress))
+ SF_SET_STRING (def_symbol_in_progress);
+
+ *input_line_pointer = name_end;
+
+ demand_empty_rest_of_line ();
+}
+
+unsigned int dim_index;
+
+static void
+obj_coff_endef (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ symbolS *symbolP = 0;
+ /* DIM BUG FIX sac@cygnus.com */
+ dim_index = 0;
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ /* Set the section number according to storage class. */
+ switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
+ {
+ case C_STRTAG:
+ case C_ENTAG:
+ case C_UNTAG:
+ SF_SET_TAG (def_symbol_in_progress);
+ /* Intentional fallthrough. */
+
+ case C_FILE:
+ case C_TPDEF:
+ SF_SET_DEBUG (def_symbol_in_progress);
+ S_SET_SEGMENT (def_symbol_in_progress, SEG_DEBUG);
+ break;
+
+ case C_EFCN:
+ /* Do not emit this symbol. */
+ SF_SET_LOCAL (def_symbol_in_progress);
+ /* Intentional fallthrough. */
+
+ case C_BLOCK:
+ /* Will need processing before writing. */
+ SF_SET_PROCESS (def_symbol_in_progress);
+ /* Intentional fallthrough. */
+
+ case C_FCN:
+ S_SET_SEGMENT (def_symbol_in_progress, SEG_E0);
+
+ if (strcmp (S_GET_NAME (def_symbol_in_progress), ".bf") == 0)
+ { /* .bf */
+ if (function_lineoff < 0)
+ fprintf (stderr, _("`.bf' symbol without preceding function\n"));
+
+ SA_GET_SYM_LNNOPTR (last_line_symbol) = function_lineoff;
+
+ SF_SET_PROCESS (last_line_symbol);
+ SF_SET_ADJ_LNNOPTR (last_line_symbol);
+ SF_SET_PROCESS (def_symbol_in_progress);
+ function_lineoff = -1;
+ }
+
+ /* Value is always set to . */
+ def_symbol_in_progress->sy_frag = frag_now;
+ S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
+ break;
+
+#ifdef C_AUTOARG
+ case C_AUTOARG:
+#endif /* C_AUTOARG */
+ case C_AUTO:
+ case C_REG:
+ case C_MOS:
+ case C_MOE:
+ case C_MOU:
+ case C_ARG:
+ case C_REGPARM:
+ case C_FIELD:
+ case C_EOS:
+ SF_SET_DEBUG (def_symbol_in_progress);
+ S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
+ break;
+
+ case C_EXT:
+ case C_WEAKEXT:
+#ifdef TE_PE
+ case C_NT_WEAK:
+#endif
+ case C_STAT:
+ case C_LABEL:
+ /* Valid but set somewhere else (s_comm, s_lcomm, colon). */
+ break;
+
+ case C_USTATIC:
+ case C_EXTDEF:
+ case C_ULABEL:
+ as_warn (_("unexpected storage class %d"), S_GET_STORAGE_CLASS (def_symbol_in_progress));
+ break;
+ }
+
+ /* Now that we have built a debug symbol, try to find if we should
+ merge with an existing symbol or not. If a symbol is C_EFCN or
+ absolute_section or untagged SEG_DEBUG it never merges. We also
+ don't merge labels, which are in a different namespace, nor
+ symbols which have not yet been defined since they are typically
+ unique, nor do we merge tags with non-tags. */
+
+ /* Two cases for functions. Either debug followed by definition or
+ definition followed by debug. For definition first, we will
+ merge the debug symbol into the definition. For debug first, the
+ lineno entry MUST point to the definition function or else it
+ will point off into space when crawl_symbols() merges the debug
+ symbol into the real symbol. Therefor, let's presume the debug
+ symbol is a real function reference. */
+
+ /* FIXME-SOON If for some reason the definition label/symbol is
+ never seen, this will probably leave an undefined symbol at link
+ time. */
+
+ if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
+ || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
+ || (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG
+ && !SF_GET_TAG (def_symbol_in_progress))
+ || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
+ || def_symbol_in_progress->sy_value.X_op != O_constant
+ || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL
+ || (SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP)))
+ {
+ symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
+ &symbol_lastP);
+ }
+ else
+ {
+ /* This symbol already exists, merge the newly created symbol
+ into the old one. This is not mandatory. The linker can
+ handle duplicate symbols correctly. But I guess that it save
+ a *lot* of space if the assembly file defines a lot of
+ symbols. [loic] */
+
+ /* The debug entry (def_symbol_in_progress) is merged into the
+ previous definition. */
+
+ c_symbol_merge (def_symbol_in_progress, symbolP);
+ /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
+ def_symbol_in_progress = symbolP;
+
+ if (SF_GET_FUNCTION (def_symbol_in_progress)
+ || SF_GET_TAG (def_symbol_in_progress)
+ || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
+ {
+ /* For functions, and tags, and static symbols, the symbol
+ *must* be where the debug symbol appears. Move the
+ existing symbol to the current place. */
+ /* If it already is at the end of the symbol list, do nothing. */
+ if (def_symbol_in_progress != symbol_lastP)
+ {
+ symbol_remove (def_symbol_in_progress, &symbol_rootP,
+ &symbol_lastP);
+ symbol_append (def_symbol_in_progress, symbol_lastP,
+ &symbol_rootP, &symbol_lastP);
+ }
+ }
+ }
+
+ if (SF_GET_TAG (def_symbol_in_progress))
+ {
+ symbolS *oldtag;
+
+ oldtag = symbol_find_base (S_GET_NAME (def_symbol_in_progress),
+ DO_NOT_STRIP);
+ if (oldtag == NULL || ! SF_GET_TAG (oldtag))
+ tag_insert (S_GET_NAME (def_symbol_in_progress),
+ def_symbol_in_progress);
+ }
+
+ if (SF_GET_FUNCTION (def_symbol_in_progress))
+ {
+ know (sizeof (def_symbol_in_progress) <= sizeof (long));
+ function_lineoff
+ = c_line_new (def_symbol_in_progress, 0, 0, &zero_address_frag);
+
+ SF_SET_PROCESS (def_symbol_in_progress);
+
+ if (symbolP == NULL)
+ {
+ /* That is, if this is the first time we've seen the
+ function... */
+ symbol_table_insert (def_symbol_in_progress);
+ }
+ }
+
+ def_symbol_in_progress = NULL;
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_dim (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ int dim_index;
+
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
+
+ for (dim_index = 0; dim_index < DIMNUM; dim_index++)
+ {
+ SKIP_WHITESPACES ();
+ SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
+ get_absolute_expression ());
+
+ switch (*input_line_pointer)
+ {
+ case ',':
+ input_line_pointer++;
+ break;
+
+ default:
+ as_warn (_("badly formed .dim directive ignored"));
+ /* Intentional fallthrough. */
+
+ case '\n':
+ case ';':
+ dim_index = DIMNUM;
+ break;
+ }
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_line (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ int this_base;
+ const char *name;
+
+ if (def_symbol_in_progress == NULL)
+ {
+ obj_coff_ln (0);
+ return;
+ }
+
+ name = S_GET_NAME (def_symbol_in_progress);
+ this_base = get_absolute_expression ();
+
+ /* Only .bf symbols indicate the use of a new base line number; the
+ line numbers associated with .ef, .bb, .eb are relative to the
+ start of the containing function. */
+ if (!strcmp (".bf", name))
+ {
+#if 0 /* XXX Can we ever have line numbers going backwards? */
+ if (this_base > line_base)
+#endif
+ line_base = this_base;
+
+#ifndef NO_LISTING
+ {
+ extern int listing;
+ if (listing)
+ listing_source_line ((unsigned int) line_base);
+ }
+#endif
+ }
+
+ S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
+ SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_size (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
+ SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_scl (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_tag (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *symbol_name;
+ char name_end;
+
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
+ symbol_name = input_line_pointer;
+ name_end = get_symbol_end ();
+#ifdef tc_canonicalize_symbol_name
+ symbol_name = tc_canonicalize_symbol_name (symbol_name);
+#endif
+
+ /* Assume that the symbol referred to by .tag is always defined.
+ This was a bad assumption. I've added find_or_make. xoxorich. */
+ SA_SET_SYM_TAGNDX (def_symbol_in_progress,
+ (long) tag_find_or_make (symbol_name));
+ if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
+ as_warn (_("tag not found for .tag %s"), symbol_name);
+
+ SF_SET_TAGGED (def_symbol_in_progress);
+ *input_line_pointer = name_end;
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_type (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
+
+ if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
+ S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
+ SF_SET_FUNCTION (def_symbol_in_progress);
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_val (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (is_name_beginner (*input_line_pointer))
+ {
+ char *symbol_name = input_line_pointer;
+ char name_end = get_symbol_end ();
+
+#ifdef tc_canonicalize_symbol_name
+ symbol_name = tc_canonicalize_symbol_name (symbol_name);
+#endif
+
+ if (!strcmp (symbol_name, "."))
+ {
+ def_symbol_in_progress->sy_frag = frag_now;
+ S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
+ /* If the .val is != from the .def (e.g. statics). */
+ }
+ else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
+ {
+ def_symbol_in_progress->sy_value.X_op = O_symbol;
+ def_symbol_in_progress->sy_value.X_add_symbol =
+ symbol_find_or_make (symbol_name);
+ def_symbol_in_progress->sy_value.X_op_symbol = NULL;
+ def_symbol_in_progress->sy_value.X_add_number = 0;
+
+ /* If the segment is undefined when the forward reference is
+ resolved, then copy the segment id from the forward
+ symbol. */
+ SF_SET_GET_SEGMENT (def_symbol_in_progress);
+
+ /* FIXME: gcc can generate address expressions here in
+ unusual cases (search for "obscure" in sdbout.c). We
+ just ignore the offset here, thus generating incorrect
+ debugging information. We ignore the rest of the line
+ just below. */
+ }
+ /* Otherwise, it is the name of a non debug symbol and
+ its value will be calculated later. */
+ *input_line_pointer = name_end;
+
+ /* FIXME: this is to avoid an error message in the
+ FIXME case mentioned just above. */
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+ else
+ {
+ S_SET_VALUE (def_symbol_in_progress,
+ (valueT) get_absolute_expression ());
+ } /* if symbol based */
+
+ demand_empty_rest_of_line ();
+}
+
+#ifdef TE_PE
+
+/* Handle the .linkonce pseudo-op. This is parsed by s_linkonce in
+ read.c, which then calls this object file format specific routine. */
+
+void
+obj_coff_pe_handle_link_once (type)
+ enum linkonce_type type;
+{
+ seg_info (now_seg)->scnhdr.s_flags |= IMAGE_SCN_LNK_COMDAT;
+
+ /* We store the type in the seg_info structure, and use it to set up
+ the auxiliary entry for the section symbol in c_section_symbol. */
+ seg_info (now_seg)->linkonce = type;
+}
+
+#endif /* TE_PE */
+
+void
+coff_obj_read_begin_hook ()
+{
+ /* These had better be the same. Usually 18 bytes. */
+#ifndef BFD_HEADERS
+ know (sizeof (SYMENT) == sizeof (AUXENT));
+ know (SYMESZ == AUXESZ);
+#endif
+ tag_init ();
+}
+
+/* This function runs through the symbol table and puts all the
+ externals onto another chain. */
+
+/* The chain of globals. */
+symbolS *symbol_globalP;
+symbolS *symbol_global_lastP;
+
+/* The chain of externals. */
+symbolS *symbol_externP;
+symbolS *symbol_extern_lastP;
+
+stack *block_stack;
+symbolS *last_functionP;
+static symbolS *last_bfP;
+symbolS *last_tagP;
+
+static unsigned int
+yank_symbols ()
+{
+ symbolS *symbolP;
+ unsigned int symbol_number = 0;
+ unsigned int last_file_symno = 0;
+
+ struct filename_list *filename_list_scan = filename_list_head;
+
+ for (symbolP = symbol_rootP;
+ symbolP;
+ symbolP = symbolP ? symbol_next (symbolP) : symbol_rootP)
+ {
+ if (symbolP->sy_mri_common)
+ {
+ if (S_GET_STORAGE_CLASS (symbolP) == C_EXT
+#ifdef TE_PE
+ || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
+#endif
+ || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT)
+ as_bad (_("%s: global symbols not supported in common sections"),
+ S_GET_NAME (symbolP));
+ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+ continue;
+ }
+
+ if (!SF_GET_DEBUG (symbolP))
+ {
+ /* Debug symbols do not need all this rubbish. */
+ symbolS *real_symbolP;
+
+ /* L* and C_EFCN symbols never merge. */
+ if (!SF_GET_LOCAL (symbolP)
+ && !SF_GET_STATICS (symbolP)
+ && S_GET_STORAGE_CLASS (symbolP) != C_LABEL
+ && symbolP->sy_value.X_op == O_constant
+ && (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), DO_NOT_STRIP))
+ && real_symbolP != symbolP)
+ {
+ /* FIXME-SOON: where do dups come from?
+ Maybe tag references before definitions? xoxorich. */
+ /* Move the debug data from the debug symbol to the
+ real symbol. Do NOT do the opposite (i.e. move from
+ real symbol to debug symbol and remove real symbol from the
+ list.) Because some pointers refer to the real symbol
+ whereas no pointers refer to the debug symbol. */
+ c_symbol_merge (symbolP, real_symbolP);
+ /* Replace the current symbol by the real one. */
+ /* The symbols will never be the last or the first
+ because : 1st symbol is .file and 3 last symbols are
+ .text, .data, .bss. */
+ symbol_remove (real_symbolP, &symbol_rootP, &symbol_lastP);
+ symbol_insert (real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
+ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+ symbolP = real_symbolP;
+ }
+
+ if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_E1))
+ S_SET_SEGMENT (symbolP, SEG_E0);
+
+ resolve_symbol_value (symbolP);
+
+ if (S_GET_STORAGE_CLASS (symbolP) == C_NULL)
+ {
+ if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
+ {
+ S_SET_EXTERNAL (symbolP);
+ }
+
+ else if (S_GET_SEGMENT (symbolP) == SEG_E0)
+ S_SET_STORAGE_CLASS (symbolP, C_LABEL);
+
+ else
+ S_SET_STORAGE_CLASS (symbolP, C_STAT);
+ }
+
+ /* Mainly to speed up if not -g. */
+ if (SF_GET_PROCESS (symbolP))
+ {
+ /* Handle the nested blocks auxiliary info. */
+ if (S_GET_STORAGE_CLASS (symbolP) == C_BLOCK)
+ {
+ if (!strcmp (S_GET_NAME (symbolP), ".bb"))
+ stack_push (block_stack, (char *) &symbolP);
+ else
+ {
+ /* .eb */
+ symbolS *begin_symbolP;
+
+ begin_symbolP = *(symbolS **) stack_pop (block_stack);
+ if (begin_symbolP == (symbolS *) 0)
+ as_warn (_("mismatched .eb"));
+ else
+ SA_SET_SYM_ENDNDX (begin_symbolP, symbol_number + 2);
+ }
+ }
+ /* If we are able to identify the type of a function, and we
+ are out of a function (last_functionP == 0) then, the
+ function symbol will be associated with an auxiliary
+ entry. */
+ if (last_functionP == (symbolS *) 0 &&
+ SF_GET_FUNCTION (symbolP))
+ {
+ last_functionP = symbolP;
+
+ if (S_GET_NUMBER_AUXILIARY (symbolP) < 1)
+ S_SET_NUMBER_AUXILIARY (symbolP, 1);
+
+ /* Clobber possible stale .dim information. */
+#if 0
+ /* Iffed out by steve - this fries the lnnoptr info too. */
+ bzero (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
+ sizeof (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
+#endif
+ }
+ if (S_GET_STORAGE_CLASS (symbolP) == C_FCN)
+ {
+ if (strcmp (S_GET_NAME (symbolP), ".bf") == 0)
+ {
+ if (last_bfP != NULL)
+ SA_SET_SYM_ENDNDX (last_bfP, symbol_number);
+ last_bfP = symbolP;
+ }
+ }
+ else if (S_GET_STORAGE_CLASS (symbolP) == C_EFCN)
+ {
+ /* I don't even know if this is needed for sdb. But
+ the standard assembler generates it, so... */
+ if (last_functionP == (symbolS *) 0)
+ as_fatal (_("C_EFCN symbol out of scope"));
+ SA_SET_SYM_FSIZE (last_functionP,
+ (long) (S_GET_VALUE (symbolP) -
+ S_GET_VALUE (last_functionP)));
+ SA_SET_SYM_ENDNDX (last_functionP, symbol_number);
+ last_functionP = (symbolS *) 0;
+ }
+ }
+ }
+ else if (SF_GET_TAG (symbolP))
+ {
+ /* First descriptor of a structure must point to
+ the first slot after the structure description. */
+ last_tagP = symbolP;
+
+ }
+ else if (S_GET_STORAGE_CLASS (symbolP) == C_EOS)
+ {
+ /* +2 take in account the current symbol. */
+ SA_SET_SYM_ENDNDX (last_tagP, symbol_number + 2);
+ }
+ else if (S_GET_STORAGE_CLASS (symbolP) == C_FILE)
+ {
+ /* If the filename was too long to fit in the
+ auxent, put it in the string table. */
+ if (SA_GET_FILE_FNAME_ZEROS (symbolP) == 0
+ && SA_GET_FILE_FNAME_OFFSET (symbolP) != 0)
+ {
+ SA_SET_FILE_FNAME_OFFSET (symbolP, string_byte_count);
+ string_byte_count += strlen (filename_list_scan->filename) + 1;
+ filename_list_scan = filename_list_scan->next;
+ }
+ if (S_GET_VALUE (symbolP))
+ {
+ S_SET_VALUE (symbolP, last_file_symno);
+ last_file_symno = symbol_number;
+ }
+ }
+
+#ifdef tc_frob_coff_symbol
+ tc_frob_coff_symbol (symbolP);
+#endif
+
+ /* We must put the external symbols apart. The loader
+ does not bomb if we do not. But the references in
+ the endndx field for a .bb symbol are not corrected
+ if an external symbol is removed between .bb and .be.
+ I.e in the following case :
+ [20] .bb endndx = 22
+ [21] foo external
+ [22] .be
+ ld will move the symbol 21 to the end of the list but
+ endndx will still be 22 instead of 21. */
+
+ if (SF_GET_LOCAL (symbolP))
+ {
+ /* Remove C_EFCN and LOCAL (L...) symbols. */
+ /* Next pointer remains valid. */
+ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+
+ }
+ else if (symbolP->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP)))
+ {
+ /* Skip symbols which were equated to undefined or common
+ symbols. */
+ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+ }
+ else if (!S_IS_DEFINED (symbolP)
+ && !S_IS_DEBUG (symbolP)
+ && !SF_GET_STATICS (symbolP)
+ && (S_GET_STORAGE_CLASS (symbolP) == C_EXT
+#ifdef TE_PE
+ || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
+#endif
+ || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT))
+ {
+ /* If external, Remove from the list. */
+ symbolS *hold = symbol_previous (symbolP);
+
+ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+ symbol_clear_list_pointers (symbolP);
+ symbol_append (symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
+ symbolP = hold;
+ }
+ else if (! S_IS_DEBUG (symbolP)
+ && ! SF_GET_STATICS (symbolP)
+ && ! SF_GET_FUNCTION (symbolP)
+ && (S_GET_STORAGE_CLASS (symbolP) == C_EXT
+#ifdef TE_PE
+ || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
+#endif
+ || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK))
+ {
+ symbolS *hold = symbol_previous (symbolP);
+
+ /* The O'Reilly COFF book says that defined global symbols
+ come at the end of the symbol table, just before
+ undefined global symbols. */
+ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+ symbol_clear_list_pointers (symbolP);
+ symbol_append (symbolP, symbol_global_lastP, &symbol_globalP,
+ &symbol_global_lastP);
+ symbolP = hold;
+ }
+ else
+ {
+ if (SF_GET_STRING (symbolP))
+ {
+ symbolP->sy_name_offset = string_byte_count;
+ string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
+ }
+ else
+ {
+ symbolP->sy_name_offset = 0;
+ }
+
+ symbolP->sy_number = symbol_number;
+ symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
+ }
+ }
+
+ return symbol_number;
+}
+
+static unsigned int
+glue_symbols (head, tail)
+ symbolS **head;
+ symbolS **tail;
+{
+ unsigned int symbol_number = 0;
+
+ while (*head != NULL)
+ {
+ symbolS *tmp = *head;
+
+ /* Append. */
+ symbol_remove (tmp, head, tail);
+ symbol_append (tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
+
+ /* Process. */
+ if (SF_GET_STRING (tmp))
+ {
+ tmp->sy_name_offset = string_byte_count;
+ string_byte_count += strlen (S_GET_NAME (tmp)) + 1;
+ }
+ else
+ {
+ /* Fix "long" names. */
+ tmp->sy_name_offset = 0;
+ }
+
+ tmp->sy_number = symbol_number;
+ symbol_number += 1 + S_GET_NUMBER_AUXILIARY (tmp);
+ }
+
+ return symbol_number;
+}
+
+static unsigned int
+tie_tags ()
+{
+ unsigned int symbol_number = 0;
+ symbolS *symbolP;
+
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ {
+ symbolP->sy_number = symbol_number;
+
+ if (SF_GET_TAGGED (symbolP))
+ {
+ SA_SET_SYM_TAGNDX
+ (symbolP,
+ ((symbolS *) SA_GET_SYM_TAGNDX (symbolP))->sy_number);
+ }
+
+ symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
+ }
+
+ return symbol_number;
+}
+
+
+static void
+crawl_symbols (h, abfd)
+ object_headers *h;
+ bfd *abfd ATTRIBUTE_UNUSED;
+{
+ unsigned int i;
+
+ /* Initialize the stack used to keep track of the matching .bb .be. */
+
+ block_stack = stack_init (512, sizeof (symbolS *));
+
+ /* The symbol list should be ordered according to the following sequence
+ order :
+ . .file symbol
+ . debug entries for functions
+ . fake symbols for the sections, including .text .data and .bss
+ . defined symbols
+ . undefined symbols
+ But this is not mandatory. The only important point is to put the
+ undefined symbols at the end of the list. */
+
+ /* Is there a .file symbol ? If not insert one at the beginning. */
+ if (symbol_rootP == NULL
+ || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
+ c_dot_file_symbol ("fake");
+
+ /* Build up static symbols for the sections, they are filled in later. */
+
+ for (i = SEG_E0; i < SEG_LAST; i++)
+ if (segment_info[i].scnhdr.s_name[0])
+ segment_info[i].dot = c_section_symbol ((char *) segment_info[i].name,
+ i - SEG_E0 + 1);
+
+ /* Take all the externals out and put them into another chain. */
+ H_SET_SYMBOL_TABLE_SIZE (h, yank_symbols ());
+ /* Take the externals and glue them onto the end. */
+ H_SET_SYMBOL_TABLE_SIZE (h,
+ (H_GET_SYMBOL_COUNT (h)
+ + glue_symbols (&symbol_globalP,
+ &symbol_global_lastP)
+ + glue_symbols (&symbol_externP,
+ &symbol_extern_lastP)));
+
+ H_SET_SYMBOL_TABLE_SIZE (h, tie_tags ());
+ know (symbol_globalP == NULL);
+ know (symbol_global_lastP == NULL);
+ know (symbol_externP == NULL);
+ know (symbol_extern_lastP == NULL);
+}
+
+/* Find strings by crawling along symbol table chain. */
+
+void
+w_strings (where)
+ char *where;
+{
+ symbolS *symbolP;
+ struct filename_list *filename_list_scan = filename_list_head;
+
+ /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK. */
+ md_number_to_chars (where, (valueT) string_byte_count, 4);
+ where += 4;
+
+#ifdef COFF_LONG_SECTION_NAMES
+ /* Support long section names as found in PE. This code must
+ coordinate with that in coff_header_append and write_object_file. */
+ {
+ unsigned int i;
+
+ for (i = SEG_E0; i < SEG_LAST; i++)
+ {
+ if (segment_info[i].scnhdr.s_name[0]
+ && strlen (segment_info[i].name) > SCNNMLEN)
+ {
+ unsigned int size;
+
+ size = strlen (segment_info[i].name) + 1;
+ memcpy (where, segment_info[i].name, size);
+ where += size;
+ }
+ }
+ }
+#endif /* COFF_LONG_SECTION_NAMES */
+
+ for (symbolP = symbol_rootP;
+ symbolP;
+ symbolP = symbol_next (symbolP))
+ {
+ unsigned int size;
+
+ if (SF_GET_STRING (symbolP))
+ {
+ size = strlen (S_GET_NAME (symbolP)) + 1;
+ memcpy (where, S_GET_NAME (symbolP), size);
+ where += size;
+ }
+ if (S_GET_STORAGE_CLASS (symbolP) == C_FILE
+ && SA_GET_FILE_FNAME_ZEROS (symbolP) == 0
+ && SA_GET_FILE_FNAME_OFFSET (symbolP) != 0)
+ {
+ size = strlen (filename_list_scan->filename) + 1;
+ memcpy (where, filename_list_scan->filename, size);
+ filename_list_scan = filename_list_scan ->next;
+ where += size;
+ }
+ }
+}
+
+static void
+do_linenos_for (abfd, h, file_cursor)
+ bfd * abfd;
+ object_headers * h;
+ unsigned long *file_cursor;
+{
+ unsigned int idx;
+ unsigned long start = *file_cursor;
+
+ for (idx = SEG_E0; idx < SEG_LAST; idx++)
+ {
+ segment_info_type *s = segment_info + idx;
+
+ if (s->scnhdr.s_nlnno != 0)
+ {
+ struct lineno_list *line_ptr;
+
+ struct external_lineno *buffer =
+ (struct external_lineno *) xmalloc (s->scnhdr.s_nlnno * LINESZ);
+
+ struct external_lineno *dst = buffer;
+
+ /* Run through the table we've built and turn it into its external
+ form, take this chance to remove duplicates. */
+
+ for (line_ptr = s->lineno_list_head;
+ line_ptr != (struct lineno_list *) NULL;
+ line_ptr = line_ptr->next)
+ {
+ if (line_ptr->line.l_lnno == 0)
+ {
+ /* Turn a pointer to a symbol into the symbols' index,
+ provided that it has been initialised. */
+ if (line_ptr->line.l_addr.l_symndx)
+ line_ptr->line.l_addr.l_symndx =
+ ((symbolS *) line_ptr->line.l_addr.l_symndx)->sy_number;
+ }
+ else
+ line_ptr->line.l_addr.l_paddr += ((struct frag *) (line_ptr->frag))->fr_address;
+
+ (void) bfd_coff_swap_lineno_out (abfd, &(line_ptr->line), dst);
+ dst++;
+ }
+
+ s->scnhdr.s_lnnoptr = *file_cursor;
+
+ bfd_bwrite (buffer, (bfd_size_type) s->scnhdr.s_nlnno * LINESZ, abfd);
+ free (buffer);
+
+ *file_cursor += s->scnhdr.s_nlnno * LINESZ;
+ }
+ }
+
+ H_SET_LINENO_SIZE (h, *file_cursor - start);
+}
+
+/* Now we run through the list of frag chains in a segment and
+ make all the subsegment frags appear at the end of the
+ list, as if the seg 0 was extra long. */
+
+static void
+remove_subsegs ()
+{
+ unsigned int i;
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ frchainS *head = segment_info[i].frchainP;
+ fragS dummy;
+ fragS *prev_frag = &dummy;
+
+ while (head && head->frch_seg == i)
+ {
+ prev_frag->fr_next = head->frch_root;
+ prev_frag = head->frch_last;
+ head = head->frch_next;
+ }
+ prev_frag->fr_next = 0;
+ }
+}
+
+unsigned long machine;
+int coff_flags;
+
+#ifndef SUB_SEGMENT_ALIGN
+#ifdef HANDLE_ALIGN
+/* The last subsegment gets an alignment corresponding to the alignment
+ of the section. This allows proper nop-filling at the end of
+ code-bearing sections. */
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \
+ (!(FRCHAIN)->frch_next || (FRCHAIN)->frch_next->frch_seg != (SEG) \
+ ? get_recorded_alignment (SEG) : 0)
+#else
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 1
+#endif
+#endif
+
+extern void
+write_object_file ()
+{
+ int i;
+ const char *name;
+ struct frchain *frchain_ptr;
+
+ object_headers headers;
+ unsigned long file_cursor;
+ bfd *abfd;
+ unsigned int addr;
+ abfd = bfd_openw (out_file_name, TARGET_FORMAT);
+
+ if (abfd == 0)
+ {
+ as_perror (_("FATAL: Can't create %s"), out_file_name);
+ exit (EXIT_FAILURE);
+ }
+ bfd_set_format (abfd, bfd_object);
+ bfd_set_arch_mach (abfd, BFD_ARCH, machine);
+
+ string_byte_count = 4;
+
+ /* Run through all the sub-segments and align them up. Also
+ close any open frags. We tack a .fill onto the end of the
+ frag chain so that any .align's size can be worked by looking
+ at the next frag. */
+ for (frchain_ptr = frchain_root;
+ frchain_ptr != (struct frchain *) NULL;
+ frchain_ptr = frchain_ptr->frch_next)
+ {
+ int alignment;
+
+ subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
+
+ alignment = SUB_SEGMENT_ALIGN (now_seg, frchain_ptr);
+
+#ifdef md_do_align
+ md_do_align (alignment, (char *) NULL, 0, 0, alignment_done);
+#endif
+ if (subseg_text_p (now_seg))
+ frag_align_code (alignment, 0);
+ else
+ frag_align (alignment, 0, 0);
+
+#ifdef md_do_align
+ alignment_done:
+#endif
+
+ frag_wane (frag_now);
+ frag_now->fr_fix = 0;
+ know (frag_now->fr_next == NULL);
+ }
+
+ remove_subsegs ();
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ relax_segment (segment_info[i].frchainP->frch_root, i);
+
+ /* Relaxation has completed. Freeze all syms. */
+ finalize_syms = 1;
+
+ H_SET_NUMBER_OF_SECTIONS (&headers, 0);
+
+ /* Find out how big the sections are, and set the addresses. */
+ addr = 0;
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ long size;
+
+ segment_info[i].scnhdr.s_paddr = addr;
+ segment_info[i].scnhdr.s_vaddr = addr;
+
+ if (segment_info[i].scnhdr.s_name[0])
+ {
+ H_SET_NUMBER_OF_SECTIONS (&headers,
+ H_GET_NUMBER_OF_SECTIONS (&headers) + 1);
+
+#ifdef COFF_LONG_SECTION_NAMES
+ /* Support long section names as found in PE. This code
+ must coordinate with that in coff_header_append and
+ w_strings. */
+ {
+ unsigned int len;
+
+ len = strlen (segment_info[i].name);
+ if (len > SCNNMLEN)
+ string_byte_count += len + 1;
+ }
+#endif /* COFF_LONG_SECTION_NAMES */
+ }
+
+ size = size_section (abfd, (unsigned int) i);
+ addr += size;
+
+ /* I think the section alignment is only used on the i960; the
+ i960 needs it, and it should do no harm on other targets. */
+#ifdef ALIGNMENT_IN_S_FLAGS
+ segment_info[i].scnhdr.s_flags |= (section_alignment[i] & 0xF) << 8;
+#else
+ segment_info[i].scnhdr.s_align = 1 << section_alignment[i];
+#endif
+
+ if (i == SEG_E0)
+ H_SET_TEXT_SIZE (&headers, size);
+ else if (i == SEG_E1)
+ H_SET_DATA_SIZE (&headers, size);
+ else if (i == SEG_E2)
+ H_SET_BSS_SIZE (&headers, size);
+ }
+
+ /* Turn the gas native symbol table shape into a coff symbol table. */
+ crawl_symbols (&headers, abfd);
+
+ if (string_byte_count == 4)
+ string_byte_count = 0;
+
+ H_SET_STRING_SIZE (&headers, string_byte_count);
+
+#ifdef tc_frob_file
+ tc_frob_file ();
+#endif
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ fixup_mdeps (segment_info[i].frchainP->frch_root, &headers, i);
+ fixup_segment (&segment_info[i], i);
+ }
+
+ /* Look for ".stab" segments and fill in their initial symbols
+ correctly. */
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ name = segment_info[i].name;
+
+ if (name != NULL
+ && strncmp (".stab", name, 5) == 0
+ && strncmp (".stabstr", name, 8) != 0)
+ adjust_stab_section (abfd, i);
+ }
+
+ file_cursor = H_GET_TEXT_FILE_OFFSET (&headers);
+
+ bfd_seek (abfd, (file_ptr) file_cursor, 0);
+
+ /* Plant the data. */
+ fill_section (abfd, &headers, &file_cursor);
+
+ do_relocs_for (abfd, &headers, &file_cursor);
+
+ do_linenos_for (abfd, &headers, &file_cursor);
+
+ H_SET_FILE_MAGIC_NUMBER (&headers, COFF_MAGIC);
+#ifndef OBJ_COFF_OMIT_TIMESTAMP
+ H_SET_TIME_STAMP (&headers, (long)time((time_t *)0));
+#else
+ H_SET_TIME_STAMP (&headers, 0);
+#endif
+#ifdef TC_COFF_SET_MACHINE
+ TC_COFF_SET_MACHINE (&headers);
+#endif
+
+#ifndef COFF_FLAGS
+#define COFF_FLAGS 0
+#endif
+
+#ifdef KEEP_RELOC_INFO
+ H_SET_FLAGS (&headers, ((H_GET_LINENO_SIZE(&headers) ? 0 : F_LNNO) |
+ COFF_FLAGS | coff_flags));
+#else
+ H_SET_FLAGS (&headers, ((H_GET_LINENO_SIZE(&headers) ? 0 : F_LNNO) |
+ (H_GET_RELOCATION_SIZE(&headers) ? 0 : F_RELFLG) |
+ COFF_FLAGS | coff_flags));
+#endif
+
+ {
+ unsigned int symtable_size = H_GET_SYMBOL_TABLE_SIZE (&headers);
+ char *buffer1 = xmalloc (symtable_size + string_byte_count + 1);
+
+ H_SET_SYMBOL_TABLE_POINTER (&headers, bfd_tell (abfd));
+ w_symbols (abfd, buffer1, symbol_rootP);
+ if (string_byte_count > 0)
+ w_strings (buffer1 + symtable_size);
+ bfd_bwrite (buffer1, (bfd_size_type) symtable_size + string_byte_count,
+ abfd);
+ free (buffer1);
+ }
+
+ coff_header_append (abfd, &headers);
+#if 0
+ /* Recent changes to write need this, but where it should
+ go is up to Ken.. */
+ if (!bfd_close_all_done (abfd))
+ as_fatal (_("Can't close %s: %s"), out_file_name,
+ bfd_errmsg (bfd_get_error ()));
+#else
+ {
+ extern bfd *stdoutput;
+ stdoutput = abfd;
+ }
+#endif
+
+}
+
+/* Add a new segment. This is called from subseg_new via the
+ obj_new_segment macro. */
+
+segT
+obj_coff_add_segment (name)
+ const char *name;
+{
+ unsigned int i;
+
+#ifndef COFF_LONG_SECTION_NAMES
+ char buf[SCNNMLEN + 1];
+
+ strncpy (buf, name, SCNNMLEN);
+ buf[SCNNMLEN] = '\0';
+ name = buf;
+#endif
+
+ for (i = SEG_E0; i < SEG_LAST && segment_info[i].scnhdr.s_name[0]; i++)
+ if (strcmp (name, segment_info[i].name) == 0)
+ return (segT) i;
+
+ if (i == SEG_LAST)
+ {
+ as_bad (_("Too many new sections; can't add \"%s\""), name);
+ return now_seg;
+ }
+
+ /* Add a new section. */
+ strncpy (segment_info[i].scnhdr.s_name, name,
+ sizeof (segment_info[i].scnhdr.s_name));
+ segment_info[i].scnhdr.s_flags = STYP_REG;
+ segment_info[i].name = xstrdup (name);
+
+ return (segT) i;
+}
+
+/* Implement the .section pseudo op:
+ .section name {, "flags"}
+ ^ ^
+ | +--- optional flags: 'b' for bss
+ | 'i' for info
+ +-- section name 'l' for lib
+ 'n' for noload
+ 'o' for over
+ 'w' for data
+ 'd' (apparently m88k for data)
+ 'x' for text
+ 'r' for read-only data
+ But if the argument is not a quoted string, treat it as a
+ subsegment number. */
+
+void
+obj_coff_section (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ /* Strip out the section name. */
+ char *section_name, *name;
+ char c;
+ unsigned int exp;
+ long flags;
+
+ if (flag_mri)
+ {
+ char type;
+
+ s_mri_sect (&type);
+ flags = 0;
+ if (type == 'C')
+ flags = STYP_TEXT;
+ else if (type == 'D')
+ flags = STYP_DATA;
+ segment_info[now_seg].scnhdr.s_flags |= flags;
+
+ return;
+ }
+
+ section_name = input_line_pointer;
+ c = get_symbol_end ();
+
+ name = xmalloc (input_line_pointer - section_name + 1);
+ strcpy (name, section_name);
+
+ *input_line_pointer = c;
+
+ exp = 0;
+ flags = 0;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != '"')
+ exp = get_absolute_expression ();
+ else
+ {
+ ++input_line_pointer;
+ while (*input_line_pointer != '"'
+ && ! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ switch (*input_line_pointer)
+ {
+ case 'b': flags |= STYP_BSS; break;
+ case 'i': flags |= STYP_INFO; break;
+ case 'l': flags |= STYP_LIB; break;
+ case 'n': flags |= STYP_NOLOAD; break;
+ case 'o': flags |= STYP_OVER; break;
+ case 'd':
+ case 'w': flags |= STYP_DATA; break;
+ case 'x': flags |= STYP_TEXT; break;
+ case 'r': flags |= STYP_LIT; break;
+ default:
+ as_warn(_("unknown section attribute '%c'"),
+ *input_line_pointer);
+ break;
+ }
+ ++input_line_pointer;
+ }
+ if (*input_line_pointer == '"')
+ ++input_line_pointer;
+ }
+ }
+
+ subseg_new (name, (subsegT) exp);
+
+ segment_info[now_seg].scnhdr.s_flags |= flags;
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_text (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ subseg_new (".text", get_absolute_expression ());
+}
+
+static void
+obj_coff_data (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (flag_readonly_data_in_text)
+ subseg_new (".text", get_absolute_expression () + 1000);
+ else
+ subseg_new (".data", get_absolute_expression ());
+}
+
+static void
+obj_coff_ident (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ segT current_seg = now_seg; /* Save current seg. */
+ subsegT current_subseg = now_subseg;
+
+ subseg_new (".comment", 0); /* .comment seg. */
+ stringer (1); /* Read string. */
+ subseg_set (current_seg, current_subseg); /* Restore current seg. */
+}
+
+void
+c_symbol_merge (debug, normal)
+ symbolS *debug;
+ symbolS *normal;
+{
+ S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
+ S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
+
+ if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
+ S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
+
+ if (S_GET_NUMBER_AUXILIARY (debug) > 0)
+ memcpy ((char *) &normal->sy_symbol.ost_auxent[0],
+ (char *) &debug->sy_symbol.ost_auxent[0],
+ (unsigned int) (S_GET_NUMBER_AUXILIARY (debug) * AUXESZ));
+
+ /* Move the debug flags. */
+ SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
+}
+
+static int
+c_line_new (symbol, paddr, line_number, frag)
+ symbolS * symbol;
+ long paddr;
+ int line_number;
+ fragS * frag;
+{
+ struct lineno_list *new_line =
+ (struct lineno_list *) xmalloc (sizeof (struct lineno_list));
+
+ segment_info_type *s = segment_info + now_seg;
+ new_line->line.l_lnno = line_number;
+
+ if (line_number == 0)
+ {
+ last_line_symbol = symbol;
+ new_line->line.l_addr.l_symndx = (long) symbol;
+ }
+ else
+ {
+ new_line->line.l_addr.l_paddr = paddr;
+ }
+
+ new_line->frag = (char *) frag;
+ new_line->next = (struct lineno_list *) NULL;
+
+ if (s->lineno_list_head == (struct lineno_list *) NULL)
+ s->lineno_list_head = new_line;
+ else
+ s->lineno_list_tail->next = new_line;
+
+ s->lineno_list_tail = new_line;
+ return LINESZ * s->scnhdr.s_nlnno++;
+}
+
+void
+c_dot_file_symbol (filename)
+ char *filename;
+{
+ symbolS *symbolP;
+
+ symbolP = symbol_new (".file",
+ SEG_DEBUG,
+ 0,
+ &zero_address_frag);
+
+ S_SET_STORAGE_CLASS (symbolP, C_FILE);
+ S_SET_NUMBER_AUXILIARY (symbolP, 1);
+
+ if (strlen (filename) > FILNMLEN)
+ {
+ /* Filename is too long to fit into an auxent,
+ we stick it into the string table instead. We keep
+ a linked list of the filenames we find so we can emit
+ them later. */
+ struct filename_list *f = ((struct filename_list *)
+ xmalloc (sizeof (struct filename_list)));
+
+ f->filename = filename;
+ f->next = 0;
+
+ SA_SET_FILE_FNAME_ZEROS (symbolP, 0);
+ SA_SET_FILE_FNAME_OFFSET (symbolP, 1);
+
+ if (filename_list_tail)
+ filename_list_tail->next = f;
+ else
+ filename_list_head = f;
+ filename_list_tail = f;
+ }
+ else
+ {
+ SA_SET_FILE_FNAME (symbolP, filename);
+ }
+#ifndef NO_LISTING
+ {
+ extern int listing;
+ if (listing)
+ listing_source_file (filename);
+ }
+#endif
+ SF_SET_DEBUG (symbolP);
+ S_SET_VALUE (symbolP, (valueT) previous_file_symbol);
+
+ previous_file_symbol = symbolP;
+
+ /* Make sure that the symbol is first on the symbol chain. */
+ if (symbol_rootP != symbolP)
+ {
+ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+ symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
+ }
+}
+
+/* Build a 'section static' symbol. */
+
+symbolS *
+c_section_symbol (name, idx)
+ char *name;
+ int idx;
+{
+ symbolS *symbolP;
+
+ symbolP = symbol_find_base (name, DO_NOT_STRIP);
+ if (symbolP == NULL)
+ symbolP = symbol_new (name, idx, 0, &zero_address_frag);
+ else
+ {
+ /* Mmmm. I just love violating interfaces. Makes me feel...dirty. */
+ S_SET_SEGMENT (symbolP, idx);
+ symbolP->sy_frag = &zero_address_frag;
+ }
+
+ S_SET_STORAGE_CLASS (symbolP, C_STAT);
+ S_SET_NUMBER_AUXILIARY (symbolP, 1);
+
+ SF_SET_STATICS (symbolP);
+
+#ifdef TE_DELTA
+ /* manfred@s-direktnet.de: section symbols *must* have the LOCAL bit cleared,
+ which is set by the new definition of LOCAL_LABEL in tc-m68k.h. */
+ SF_CLEAR_LOCAL (symbolP);
+#endif
+#ifdef TE_PE
+ /* If the .linkonce pseudo-op was used for this section, we must
+ store the information in the auxiliary entry for the section
+ symbol. */
+ if (segment_info[idx].linkonce != LINKONCE_UNSET)
+ {
+ int type;
+
+ switch (segment_info[idx].linkonce)
+ {
+ default:
+ abort ();
+ case LINKONCE_DISCARD:
+ type = IMAGE_COMDAT_SELECT_ANY;
+ break;
+ case LINKONCE_ONE_ONLY:
+ type = IMAGE_COMDAT_SELECT_NODUPLICATES;
+ break;
+ case LINKONCE_SAME_SIZE:
+ type = IMAGE_COMDAT_SELECT_SAME_SIZE;
+ break;
+ case LINKONCE_SAME_CONTENTS:
+ type = IMAGE_COMDAT_SELECT_EXACT_MATCH;
+ break;
+ }
+
+ SYM_AUXENT (symbolP)->x_scn.x_comdat = type;
+ }
+#endif /* TE_PE */
+
+ return symbolP;
+}
+
+static void
+w_symbols (abfd, where, symbol_rootP)
+ bfd * abfd;
+ char *where;
+ symbolS * symbol_rootP;
+{
+ symbolS *symbolP;
+ unsigned int i;
+
+ /* First fill in those values we have only just worked out. */
+ for (i = SEG_E0; i < SEG_LAST; i++)
+ {
+ symbolP = segment_info[i].dot;
+ if (symbolP)
+ {
+ SA_SET_SCN_SCNLEN (symbolP, segment_info[i].scnhdr.s_size);
+ SA_SET_SCN_NRELOC (symbolP, segment_info[i].scnhdr.s_nreloc);
+ SA_SET_SCN_NLINNO (symbolP, segment_info[i].scnhdr.s_nlnno);
+ }
+ }
+
+ /* Emit all symbols left in the symbol chain. */
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ {
+ /* Used to save the offset of the name. It is used to point
+ to the string in memory but must be a file offset. */
+ char *temp;
+
+ /* We can't fix the lnnoptr field in yank_symbols with the other
+ adjustments, because we have to wait until we know where they
+ go in the file. */
+ if (SF_GET_ADJ_LNNOPTR (symbolP))
+ SA_GET_SYM_LNNOPTR (symbolP) +=
+ segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_lnnoptr;
+
+ tc_coff_symbol_emit_hook (symbolP);
+
+ temp = S_GET_NAME (symbolP);
+ if (SF_GET_STRING (symbolP))
+ {
+ S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
+ S_SET_ZEROES (symbolP, 0);
+ }
+ else
+ {
+ memset (symbolP->sy_symbol.ost_entry.n_name, 0, SYMNMLEN);
+ strncpy (symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
+ }
+ where = symbol_to_chars (abfd, where, symbolP);
+ S_SET_NAME (symbolP, temp);
+ }
+}
+
+static void
+obj_coff_lcomm (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ s_lcomm(0);
+ return;
+#if 0
+ char *name;
+ char c;
+ int temp;
+ char *p;
+
+ symbolS *symbolP;
+
+ name = input_line_pointer;
+
+ c = get_symbol_end ();
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after name"));
+ ignore_rest_of_line ();
+ return;
+ }
+ if (*input_line_pointer == '\n')
+ {
+ as_bad (_("Missing size expression"));
+ return;
+ }
+ input_line_pointer++;
+ if ((temp = get_absolute_expression ()) < 0)
+ {
+ as_warn (_("lcomm length (%d.) <0! Ignored."), temp);
+ ignore_rest_of_line ();
+ return;
+ }
+ *p = 0;
+
+ symbolP = symbol_find_or_make (name);
+
+ if (S_GET_SEGMENT (symbolP) == SEG_UNKNOWN &&
+ S_GET_VALUE (symbolP) == 0)
+ {
+ if (! need_pass_2)
+ {
+ char *p;
+ segT current_seg = now_seg; /* Save current seg. */
+ subsegT current_subseg = now_subseg;
+
+ subseg_set (SEG_E2, 1);
+ symbolP->sy_frag = frag_now;
+ p = frag_var(rs_org, 1, 1, (relax_substateT)0, symbolP,
+ (offsetT) temp, (char *) 0);
+ *p = 0;
+ subseg_set (current_seg, current_subseg); /* Restore current seg. */
+ S_SET_SEGMENT (symbolP, SEG_E2);
+ S_SET_STORAGE_CLASS (symbolP, C_STAT);
+ }
+ }
+ else
+ as_bad (_("Symbol %s already defined"), name);
+
+ demand_empty_rest_of_line ();
+#endif
+}
+
+static void
+fixup_mdeps (frags, h, this_segment)
+ fragS *frags;
+ object_headers *h ATTRIBUTE_UNUSED;
+ segT this_segment;
+{
+ subseg_change (this_segment, 0);
+
+ while (frags)
+ {
+ switch (frags->fr_type)
+ {
+ case rs_align:
+ case rs_align_code:
+ case rs_align_test:
+ case rs_org:
+#ifdef HANDLE_ALIGN
+ HANDLE_ALIGN (frags);
+#endif
+ frags->fr_type = rs_fill;
+ frags->fr_offset =
+ ((frags->fr_next->fr_address - frags->fr_address - frags->fr_fix)
+ / frags->fr_var);
+ break;
+ case rs_machine_dependent:
+ md_convert_frag (h, this_segment, frags);
+ frag_wane (frags);
+ break;
+ default:
+ ;
+ }
+ frags = frags->fr_next;
+ }
+}
+
+#if 1
+
+#ifndef TC_FORCE_RELOCATION
+#define TC_FORCE_RELOCATION(fix) 0
+#endif
+
+static void
+fixup_segment (segP, this_segment_type)
+ segment_info_type * segP;
+ segT this_segment_type;
+{
+ fixS * fixP;
+ symbolS *add_symbolP;
+ symbolS *sub_symbolP;
+ long add_number;
+ int size;
+ char *place;
+ long where;
+ char pcrel;
+ fragS *fragP;
+ segT add_symbol_segment = absolute_section;
+
+ for (fixP = segP->fix_root; fixP; fixP = fixP->fx_next)
+ {
+ fragP = fixP->fx_frag;
+ know (fragP);
+ where = fixP->fx_where;
+ place = fragP->fr_literal + where;
+ size = fixP->fx_size;
+ add_symbolP = fixP->fx_addsy;
+ sub_symbolP = fixP->fx_subsy;
+ add_number = fixP->fx_offset;
+ pcrel = fixP->fx_pcrel;
+
+ /* We want function-relative stabs to work on systems which
+ may use a relaxing linker; thus we must handle the sym1-sym2
+ fixups function-relative stabs generates.
+
+ Of course, if you actually enable relaxing in the linker, the
+ line and block scoping information is going to be incorrect
+ in some cases. The only way to really fix this is to support
+ a reloc involving the difference of two symbols. */
+ if (linkrelax
+ && (!sub_symbolP || pcrel))
+ continue;
+
+#ifdef TC_I960
+ if (fixP->fx_tcbit && SF_GET_CALLNAME (add_symbolP))
+ {
+ /* Relocation should be done via the associated 'bal' entry
+ point symbol. */
+
+ if (!SF_GET_BALNAME (tc_get_bal_of_call (add_symbolP)))
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("No 'bal' entry point for leafproc %s"),
+ S_GET_NAME (add_symbolP));
+ continue;
+ }
+ fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP);
+ }
+#endif
+
+ /* Make sure the symbols have been resolved; this may not have
+ happened if these are expression symbols. */
+ if (add_symbolP != NULL && ! add_symbolP->sy_resolved)
+ resolve_symbol_value (add_symbolP);
+
+ if (add_symbolP != NULL)
+ {
+ /* If this fixup is against a symbol which has been equated
+ to another symbol, convert it to the other symbol. */
+ if (add_symbolP->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (add_symbolP)
+ || S_IS_COMMON (add_symbolP)))
+ {
+ while (add_symbolP->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (add_symbolP)
+ || S_IS_COMMON (add_symbolP)))
+ {
+ symbolS *n;
+
+ /* We must avoid looping, as that can occur with a
+ badly written program. */
+ n = add_symbolP->sy_value.X_add_symbol;
+ if (n == add_symbolP)
+ break;
+ add_number += add_symbolP->sy_value.X_add_number;
+ add_symbolP = n;
+ }
+ fixP->fx_addsy = add_symbolP;
+ fixP->fx_offset = add_number;
+ }
+ }
+
+ if (sub_symbolP != NULL && ! sub_symbolP->sy_resolved)
+ resolve_symbol_value (sub_symbolP);
+
+ if (add_symbolP != NULL
+ && add_symbolP->sy_mri_common)
+ {
+ know (add_symbolP->sy_value.X_op == O_symbol);
+ add_number += S_GET_VALUE (add_symbolP);
+ fixP->fx_offset = add_number;
+ add_symbolP = fixP->fx_addsy = add_symbolP->sy_value.X_add_symbol;
+ }
+
+ if (add_symbolP)
+ add_symbol_segment = S_GET_SEGMENT (add_symbolP);
+
+ if (sub_symbolP)
+ {
+ if (add_symbolP == NULL || add_symbol_segment == absolute_section)
+ {
+ if (add_symbolP != NULL)
+ {
+ add_number += S_GET_VALUE (add_symbolP);
+ add_symbolP = NULL;
+ fixP->fx_addsy = NULL;
+ }
+
+ /* It's just -sym. */
+ if (S_GET_SEGMENT (sub_symbolP) == absolute_section)
+ {
+ add_number -= S_GET_VALUE (sub_symbolP);
+ fixP->fx_subsy = 0;
+ fixP->fx_done = 1;
+ }
+ else
+ {
+#ifndef TC_M68K
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Negative of non-absolute symbol %s"),
+ S_GET_NAME (sub_symbolP));
+#endif
+ add_number -= S_GET_VALUE (sub_symbolP);
+ } /* not absolute */
+
+ /* if sub_symbol is in the same segment that add_symbol
+ and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE. */
+ }
+ else if (S_GET_SEGMENT (sub_symbolP) == add_symbol_segment
+ && SEG_NORMAL (add_symbol_segment))
+ {
+ /* Difference of 2 symbols from same segment. Can't
+ make difference of 2 undefineds: 'value' means
+ something different for N_UNDF. */
+#ifdef TC_I960
+ /* Makes no sense to use the difference of 2 arbitrary symbols
+ as the target of a call instruction. */
+ if (fixP->fx_tcbit)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("callj to difference of 2 symbols"));
+#endif /* TC_I960 */
+ add_number += S_GET_VALUE (add_symbolP) -
+ S_GET_VALUE (sub_symbolP);
+ add_symbolP = NULL;
+
+ if (!TC_FORCE_RELOCATION (fixP))
+ {
+ fixP->fx_addsy = NULL;
+ fixP->fx_subsy = NULL;
+ fixP->fx_done = 1;
+#ifdef TC_M68K /* is this right? */
+ pcrel = 0;
+ fixP->fx_pcrel = 0;
+#endif
+ }
+ }
+ else
+ {
+ /* Different segments in subtraction. */
+ know (!(S_IS_EXTERNAL (sub_symbolP) && (S_GET_SEGMENT (sub_symbolP) == absolute_section)));
+
+ if ((S_GET_SEGMENT (sub_symbolP) == absolute_section))
+ add_number -= S_GET_VALUE (sub_symbolP);
+
+#ifdef DIFF_EXPR_OK
+ else if (S_GET_SEGMENT (sub_symbolP) == this_segment_type
+#if 0 /* Okay for 68k, at least... */
+ && !pcrel
+#endif
+ )
+ {
+ /* Make it pc-relative. */
+ add_number += (md_pcrel_from (fixP)
+ - S_GET_VALUE (sub_symbolP));
+ pcrel = 1;
+ fixP->fx_pcrel = 1;
+ sub_symbolP = 0;
+ fixP->fx_subsy = 0;
+ }
+#endif
+ else
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %ld."),
+ segment_name (S_GET_SEGMENT (sub_symbolP)),
+ S_GET_NAME (sub_symbolP),
+ (long) (fragP->fr_address + where));
+ }
+ }
+ }
+
+ if (add_symbolP)
+ {
+ if (add_symbol_segment == this_segment_type && pcrel)
+ {
+ /* This fixup was made when the symbol's segment was
+ SEG_UNKNOWN, but it is now in the local segment.
+ So we know how to do the address without relocation. */
+#ifdef TC_I960
+ /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
+ in which cases it modifies *fixP as appropriate. In the case
+ of a 'calls', no further work is required, and *fixP has been
+ set up to make the rest of the code below a no-op. */
+ reloc_callj (fixP);
+#endif /* TC_I960 */
+
+ add_number += S_GET_VALUE (add_symbolP);
+ add_number -= md_pcrel_from (fixP);
+
+ /* We used to do
+ add_number -= segP->scnhdr.s_vaddr;
+ if defined (TC_I386) || defined (TE_LYNX). I now
+ think that was an error propagated from the case when
+ we are going to emit the relocation. If we are not
+ going to emit the relocation, then we just want to
+ set add_number to the difference between the symbols.
+ This is a case that would only arise when there is a
+ PC relative reference from a section other than .text
+ to a symbol defined in the same section, and the
+ reference is not relaxed. Since jump instructions on
+ the i386 are relaxed, this could only arise with a
+ call instruction. */
+
+ pcrel = 0; /* Lie. Don't want further pcrel processing. */
+ if (!TC_FORCE_RELOCATION (fixP))
+ {
+ fixP->fx_addsy = NULL;
+ fixP->fx_done = 1;
+ }
+ }
+ else
+ {
+ switch (add_symbol_segment)
+ {
+ case absolute_section:
+#ifdef TC_I960
+ /* See comment about reloc_callj() above. */
+ reloc_callj (fixP);
+#endif /* TC_I960 */
+ add_number += S_GET_VALUE (add_symbolP);
+ add_symbolP = NULL;
+
+ if (!TC_FORCE_RELOCATION (fixP))
+ {
+ fixP->fx_addsy = NULL;
+ fixP->fx_done = 1;
+ }
+ break;
+ default:
+
+#if defined(TC_A29K) || (defined(TE_PE) && defined(TC_I386)) || defined(TC_M88K) || defined(TC_OR32)
+ /* This really should be handled in the linker, but
+ backward compatibility forbids. */
+ add_number += S_GET_VALUE (add_symbolP);
+#else
+ add_number += S_GET_VALUE (add_symbolP) +
+ segment_info[S_GET_SEGMENT (add_symbolP)].scnhdr.s_paddr;
+#endif
+ break;
+
+ case SEG_UNKNOWN:
+#ifdef TC_I960
+ if ((int) fixP->fx_bit_fixP == 13)
+ {
+ /* This is a COBR instruction. They have only a
+ 13-bit displacement and are only to be used
+ for local branches: flag as error, don't generate
+ relocation. */
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("can't use COBR format with external label"));
+ fixP->fx_addsy = NULL;
+ fixP->fx_done = 1;
+ continue;
+ }
+#endif /* TC_I960 */
+#if ((defined (TC_I386) || defined (TE_LYNX) || defined (TE_AUX)) && !defined(TE_PE)) || defined (COFF_COMMON_ADDEND)
+ /* 386 COFF uses a peculiar format in which the
+ value of a common symbol is stored in the .text
+ segment (I've checked this on SVR3.2 and SCO
+ 3.2.2) Ian Taylor <ian@cygnus.com>. */
+ /* This is also true for 68k COFF on sysv machines
+ (Checked on Motorola sysv68 R3V6 and R3V7.1, and also on
+ UNIX System V/M68000, Release 1.0 from ATT/Bell Labs)
+ Philippe De Muyter <phdm@info.ucl.ac.be>. */
+ if (S_IS_COMMON (add_symbolP))
+ add_number += S_GET_VALUE (add_symbolP);
+#endif
+ break;
+
+ }
+ }
+ }
+
+ if (pcrel)
+ {
+#if !defined(TC_M88K) && !(defined(TE_PE) && defined(TC_I386)) && !defined(TC_A29K) && !defined(TC_OR32)
+ /* This adjustment is not correct on the m88k, for which the
+ linker does all the computation. */
+ add_number -= md_pcrel_from (fixP);
+#endif
+ if (add_symbolP == 0)
+ fixP->fx_addsy = &abs_symbol;
+#if defined (TC_I386) || defined (TE_LYNX) || defined (TC_I960) || defined (TC_M68K)
+ /* On the 386 we must adjust by the segment vaddr as well.
+ Ian Taylor.
+
+ I changed the i960 to work this way as well. This is
+ compatible with the current GNU linker behaviour. I do
+ not know what other i960 COFF assemblers do. This is not
+ a common case: normally, only assembler code will contain
+ a PC relative reloc, and only branches which do not
+ originate in the .text section will have a non-zero
+ address.
+
+ I changed the m68k to work this way as well. This will
+ break existing PC relative relocs from sections which do
+ not start at address 0, but it will make ld -r work.
+ Ian Taylor, 4 Oct 96. */
+
+ add_number -= segP->scnhdr.s_vaddr;
+#endif
+ }
+
+ md_apply_fix3 (fixP, (valueT *) & add_number, this_segment_type);
+
+ if (!fixP->fx_bit_fixP && ! fixP->fx_no_overflow)
+ {
+#ifndef TC_M88K
+ /* The m88k uses the offset field of the reloc to get around
+ this problem. */
+ if ((size == 1
+ && ((add_number & ~0xFF)
+ || (fixP->fx_signed && (add_number & 0x80)))
+ && ((add_number & ~0xFF) != (-1 & ~0xFF)
+ || (add_number & 0x80) == 0))
+ || (size == 2
+ && ((add_number & ~0xFFFF)
+ || (fixP->fx_signed && (add_number & 0x8000)))
+ && ((add_number & ~0xFFFF) != (-1 & ~0xFFFF)
+ || (add_number & 0x8000) == 0)))
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Value of %ld too large for field of %d bytes at 0x%lx"),
+ (long) add_number, size,
+ (unsigned long) (fragP->fr_address + where));
+ }
+#endif
+#ifdef WARN_SIGNED_OVERFLOW_WORD
+ /* Warn if a .word value is too large when treated as a
+ signed number. We already know it is not too negative.
+ This is to catch over-large switches generated by gcc on
+ the 68k. */
+ if (!flag_signed_overflow_ok
+ && size == 2
+ && add_number > 0x7fff)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Signed .word overflow; switch may be too large; %ld at 0x%lx"),
+ (long) add_number,
+ (unsigned long) (fragP->fr_address + where));
+#endif
+ }
+ }
+}
+
+#endif
+
+/* The first entry in a .stab section is special. */
+
+void
+obj_coff_init_stab_section (seg)
+ segT seg;
+{
+ char *file;
+ char *p;
+ char *stabstr_name;
+ unsigned int stroff;
+
+ /* Make space for this first symbol. */
+ p = frag_more (12);
+ /* Zero it out. */
+ memset (p, 0, 12);
+ as_where (&file, (unsigned int *) NULL);
+ stabstr_name = (char *) alloca (strlen (segment_info[seg].name) + 4);
+ strcpy (stabstr_name, segment_info[seg].name);
+ strcat (stabstr_name, "str");
+ stroff = get_stab_string_offset (file, stabstr_name);
+ know (stroff == 1);
+ md_number_to_chars (p, stroff, 4);
+}
+
+/* Fill in the counts in the first entry in a .stab section. */
+
+static void
+adjust_stab_section(abfd, seg)
+ bfd *abfd;
+ segT seg;
+{
+ segT stabstrseg = SEG_UNKNOWN;
+ const char *secname, *name2;
+ char *name;
+ char *p = NULL;
+ int i, strsz = 0, nsyms;
+ fragS *frag = segment_info[seg].frchainP->frch_root;
+
+ /* Look for the associated string table section. */
+
+ secname = segment_info[seg].name;
+ name = (char *) alloca (strlen (secname) + 4);
+ strcpy (name, secname);
+ strcat (name, "str");
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ name2 = segment_info[i].name;
+ if (name2 != NULL && strncmp(name2, name, 8) == 0)
+ {
+ stabstrseg = i;
+ break;
+ }
+ }
+
+ /* If we found the section, get its size. */
+ if (stabstrseg != SEG_UNKNOWN)
+ strsz = size_section (abfd, stabstrseg);
+
+ nsyms = size_section (abfd, seg) / 12 - 1;
+
+ /* Look for the first frag of sufficient size for the initial stab
+ symbol, and collect a pointer to it. */
+ while (frag && frag->fr_fix < 12)
+ frag = frag->fr_next;
+ assert (frag != 0);
+ p = frag->fr_literal;
+ assert (p != 0);
+
+ /* Write in the number of stab symbols and the size of the string
+ table. */
+ bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
+ bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
+}
+
+#endif /* not BFD_ASSEMBLER */
+
+const pseudo_typeS coff_pseudo_table[] =
+{
+ {"def", obj_coff_def, 0},
+ {"dim", obj_coff_dim, 0},
+ {"endef", obj_coff_endef, 0},
+ {"line", obj_coff_line, 0},
+ {"ln", obj_coff_ln, 0},
+#ifdef BFD_ASSEMBLER
+ {"loc", obj_coff_loc, 0},
+#endif
+ {"appline", obj_coff_ln, 1},
+ {"scl", obj_coff_scl, 0},
+ {"size", obj_coff_size, 0},
+ {"tag", obj_coff_tag, 0},
+ {"type", obj_coff_type, 0},
+ {"val", obj_coff_val, 0},
+ {"section", obj_coff_section, 0},
+ {"sect", obj_coff_section, 0},
+ /* FIXME: We ignore the MRI short attribute. */
+ {"section.s", obj_coff_section, 0},
+ {"sect.s", obj_coff_section, 0},
+ /* We accept the .bss directive for backward compatibility with
+ earlier versions of gas. */
+ {"bss", obj_coff_bss, 0},
+ {"weak", obj_coff_weak, 0},
+ {"ident", obj_coff_ident, 0},
+#ifndef BFD_ASSEMBLER
+ {"use", obj_coff_section, 0},
+ {"text", obj_coff_text, 0},
+ {"data", obj_coff_data, 0},
+ {"lcomm", obj_coff_lcomm, 0},
+#else
+ {"optim", s_ignore, 0}, /* For sun386i cc (?) */
+#endif
+ {"version", s_ignore, 0},
+ {"ABORT", s_abort, 0},
+#if defined( TC_M88K ) || defined ( TC_TIC4X )
+ /* The m88k and tic4x uses sdef instead of def. */
+ {"sdef", obj_coff_def, 0},
+#endif
+ {NULL, NULL, 0} /* end sentinel */
+}; /* coff_pseudo_table */
+
+#ifdef BFD_ASSEMBLER
+
+/* Support for a COFF emulation. */
+
+static void coff_pop_insert PARAMS ((void));
+static int coff_separate_stab_sections PARAMS ((void));
+
+static void
+coff_pop_insert ()
+{
+ pop_insert (coff_pseudo_table);
+}
+
+static int
+coff_separate_stab_sections ()
+{
+ return 1;
+}
+
+const struct format_ops coff_format_ops =
+{
+ bfd_target_coff_flavour,
+ 0, /* dfl_leading_underscore */
+ 1, /* emit_section_symbols */
+ 0, /* begin */
+ c_dot_file_symbol,
+ coff_frob_symbol,
+ 0, /* frob_file */
+ 0, /* frob_file_before_adjust */
+ 0, /* frob_file_before_fix */
+ coff_frob_file_after_relocs,
+ 0, /* s_get_size */
+ 0, /* s_set_size */
+ 0, /* s_get_align */
+ 0, /* s_set_align */
+ 0, /* s_get_other */
+ 0, /* s_set_other */
+ 0, /* s_get_desc */
+ 0, /* s_set_desc */
+ 0, /* s_get_type */
+ 0, /* s_set_type */
+ 0, /* copy_symbol_attributes */
+ 0, /* generate_asm_lineno */
+ 0, /* process_stab */
+ coff_separate_stab_sections,
+ obj_coff_init_stab_section,
+ 0, /* sec_sym_ok_for_reloc */
+ coff_pop_insert,
+ 0, /* ecoff_set_ext */
+ coff_obj_read_begin_hook,
+ coff_obj_symbol_new_hook
+};
+
+#endif
diff --git a/x/binutils/gas/config/obj-coff.h b/x/binutils/gas/config/obj-coff.h
new file mode 100644
index 0000000..5200552
--- /dev/null
+++ b/x/binutils/gas/config/obj-coff.h
@@ -0,0 +1,906 @@
+/* coff object file format
+ Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2002, 2003
+ Free Software Foundation, Inc.
+
+ This file is part of GAS.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef OBJ_FORMAT_H
+#define OBJ_FORMAT_H
+
+#define OBJ_COFF 1
+
+#ifndef BFD_ASSEMBLER
+
+#define WORKING_DOT_WORD
+#define WARN_SIGNED_OVERFLOW_WORD
+#define OBJ_COFF_OMIT_OPTIONAL_HEADER
+#define BFD_HEADERS
+#define BFD
+
+#endif
+
+#include "targ-cpu.h"
+
+#include "bfd.h"
+
+/* This internal_lineno crap is to stop namespace pollution from the
+ bfd internal coff headerfile. */
+#define internal_lineno bfd_internal_lineno
+#include "coff/internal.h"
+#undef internal_lineno
+
+/* CPU-specific setup: */
+
+#ifdef TC_ARM
+#include "coff/arm.h"
+#ifndef TARGET_FORMAT
+#define TARGET_FORMAT "coff-arm"
+#endif
+#endif
+
+#ifdef TC_PPC
+#ifdef TE_PE
+#include "coff/powerpc.h"
+#else
+#include "coff/rs6000.h"
+#endif
+#endif
+
+#ifdef TC_SPARC
+#include "coff/sparc.h"
+#endif
+
+#ifdef TC_I386
+#include "coff/i386.h"
+
+#ifdef TE_PE
+#define TARGET_FORMAT "pe-i386"
+#endif
+
+#ifndef TARGET_FORMAT
+#define TARGET_FORMAT "coff-i386"
+#endif
+#endif
+
+#ifdef TC_M68K
+#include "coff/m68k.h"
+#ifndef TARGET_FORMAT
+#define TARGET_FORMAT "coff-m68k"
+#endif
+#endif
+
+#ifdef TC_A29K
+#include "coff/a29k.h"
+#define TARGET_FORMAT "coff-a29k-big"
+#endif
+
+#ifdef TC_OR32
+#include "coff/or32.h"
+#define TARGET_FORMAT "coff-or32-big"
+#endif
+
+#ifdef TC_I960
+#include "coff/i960.h"
+#define TARGET_FORMAT "coff-Intel-little"
+#endif
+
+#ifdef TC_Z8K
+#include "coff/z8k.h"
+#define TARGET_FORMAT "coff-z8k"
+#endif
+
+#ifdef TC_H8300
+#include "coff/h8300.h"
+#define TARGET_FORMAT "coff-h8300"
+#endif
+
+#ifdef TC_H8500
+#include "coff/h8500.h"
+#define TARGET_FORMAT "coff-h8500"
+#endif
+
+#ifdef TC_SH
+
+#ifdef TE_PE
+#define COFF_WITH_PE
+#endif
+
+#include "coff/sh.h"
+
+#ifdef TE_PE
+#define TARGET_FORMAT "pe-shl"
+#else
+
+#define TARGET_FORMAT \
+ (!target_big_endian \
+ ? (sh_small ? "coff-shl-small" : "coff-shl") \
+ : (sh_small ? "coff-sh-small" : "coff-sh"))
+
+#endif
+#endif
+
+#ifdef TC_MIPS
+#define COFF_WITH_PE
+#include "coff/mipspe.h"
+#undef TARGET_FORMAT
+#define TARGET_FORMAT "pe-mips"
+#endif
+
+#ifdef TC_M88K
+#include "coff/m88k.h"
+#define TARGET_FORMAT "coff-m88kbcs"
+#endif
+
+#ifdef TC_W65
+#include "coff/w65.h"
+#define TARGET_FORMAT "coff-w65"
+#endif
+
+#ifdef TC_TIC30
+#include "coff/tic30.h"
+#define TARGET_FORMAT "coff-tic30"
+#endif
+
+#ifdef TC_TIC4X
+#include "coff/tic4x.h"
+#define TARGET_FORMAT "coff2-tic4x"
+#endif
+
+#ifdef TC_TIC54X
+#include "coff/tic54x.h"
+#define TARGET_FORMAT "coff1-c54x"
+#endif
+
+#ifdef TC_TIC80
+#include "coff/tic80.h"
+#define TARGET_FORMAT "coff-tic80"
+#define ALIGNMENT_IN_S_FLAGS 1
+#endif
+
+#ifdef TC_MCORE
+#include "coff/mcore.h"
+#ifndef TARGET_FORMAT
+#define TARGET_FORMAT "pe-mcore"
+#endif
+#endif
+
+/* Targets may also set this. Also, if BFD_ASSEMBLER is defined, this
+ will already have been defined. */
+#undef SYMBOLS_NEED_BACKPOINTERS
+#define SYMBOLS_NEED_BACKPOINTERS 1
+
+#ifndef OBJ_COFF_MAX_AUXENTRIES
+#define OBJ_COFF_MAX_AUXENTRIES 1
+#endif /* OBJ_COFF_MAX_AUXENTRIES */
+
+extern void coff_obj_symbol_new_hook PARAMS ((symbolS *));
+#define obj_symbol_new_hook coff_obj_symbol_new_hook
+
+extern void coff_obj_read_begin_hook PARAMS ((void));
+#define obj_read_begin_hook coff_obj_read_begin_hook
+
+/* This file really contains two implementations of the COFF back end.
+ They are in the process of being merged, but this is only a
+ preliminary, mechanical merging. Many definitions that are
+ identical between the two are still found in both versions.
+
+ The first version, with BFD_ASSEMBLER defined, uses high-level BFD
+ interfaces and data structures. The second version, with
+ BFD_ASSEMBLER not defined, also uses BFD, but mostly for swapping
+ data structures and for doing the actual I/O. The latter defines
+ the preprocessor symbols BFD and BFD_HEADERS. Try not to let this
+ confuse you.
+
+ These two are in the process of being merged, and eventually the
+ BFD_ASSEMBLER version should take over completely. Release timing
+ issues and namespace problems convinced me to merge the two
+ together in this fashion, a little sooner than I would have liked.
+ The real merge should be much better done by the time the next
+ release comes out.
+
+ For now, the structure of this file is:
+ <common>
+ #ifdef BFD_ASSEMBLER
+ <one version>
+ #else
+ <other version>
+ #endif
+ <common>
+ Unfortunately, the common portions are very small at the moment,
+ and many declarations or definitions are duplicated. The structure
+ of obj-coff.c is similar.
+
+ See doc/internals.texi for a brief discussion of the history, if
+ you care.
+
+ Ken Raeburn, 5 May 1994. */
+
+#ifdef BFD_ASSEMBLER
+
+#include "bfd/libcoff.h"
+
+#define OUTPUT_FLAVOR bfd_target_coff_flavour
+
+/* SYMBOL TABLE */
+
+/* Alter the field names, for now, until we've fixed up the other
+ references to use the new name. */
+#ifdef TC_I960
+#define TC_SYMFIELD_TYPE symbolS *
+#define sy_tc bal
+#endif
+
+#define OBJ_SYMFIELD_TYPE unsigned long
+#define sy_obj sy_flags
+
+/* We can't use the predefined section symbols in bfd/section.c, as
+ COFF symbols have extra fields. See bfd/libcoff.h:coff_symbol_type. */
+#ifndef obj_sec_sym_ok_for_reloc
+#define obj_sec_sym_ok_for_reloc(SEC) ((SEC)->owner != 0)
+#endif
+
+#define SYM_AUXENT(S) \
+ (&coffsymbol (symbol_get_bfdsym (S))->native[1].u.auxent)
+#define SYM_AUXINFO(S) \
+ (&coffsymbol (symbol_get_bfdsym (S))->native[1])
+
+#define DO_NOT_STRIP 0
+
+extern void obj_coff_section PARAMS ((int));
+
+/* The number of auxiliary entries. */
+#define S_GET_NUMBER_AUXILIARY(s) \
+ (coffsymbol (symbol_get_bfdsym (s))->native->u.syment.n_numaux)
+/* The number of auxiliary entries. */
+#define S_SET_NUMBER_AUXILIARY(s,v) (S_GET_NUMBER_AUXILIARY (s) = (v))
+
+/* True if a symbol name is in the string table, i.e. its length is > 8. */
+#define S_IS_STRING(s) (strlen(S_GET_NAME(s)) > 8 ? 1 : 0)
+
+extern int S_SET_DATA_TYPE PARAMS ((symbolS *, int));
+extern int S_SET_STORAGE_CLASS PARAMS ((symbolS *, int));
+extern int S_GET_STORAGE_CLASS PARAMS ((symbolS *));
+extern void SA_SET_SYM_ENDNDX PARAMS ((symbolS *, symbolS *));
+
+/* Auxiliary entry macros. SA_ stands for symbol auxiliary. */
+/* Omit the tv related fields. */
+/* Accessors. */
+
+#define SA_GET_SYM_TAGNDX(s) (SYM_AUXENT (s)->x_sym.x_tagndx.l)
+#define SA_GET_SYM_LNNO(s) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_lnno)
+#define SA_GET_SYM_SIZE(s) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_size)
+#define SA_GET_SYM_FSIZE(s) (SYM_AUXENT (s)->x_sym.x_misc.x_fsize)
+#define SA_GET_SYM_LNNOPTR(s) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#define SA_GET_SYM_ENDNDX(s) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_endndx)
+#define SA_GET_SYM_DIMEN(s,i) (SYM_AUXENT (s)->x_sym.x_fcnary.x_ary.x_dimen[(i)])
+#define SA_GET_FILE_FNAME(s) (SYM_AUXENT (s)->x_file.x_fname)
+#define SA_GET_SCN_SCNLEN(s) (SYM_AUXENT (s)->x_scn.x_scnlen)
+#define SA_GET_SCN_NRELOC(s) (SYM_AUXENT (s)->x_scn.x_nreloc)
+#define SA_GET_SCN_NLINNO(s) (SYM_AUXENT (s)->x_scn.x_nlinno)
+
+#define SA_SET_SYM_LNNO(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_lnno=(v))
+#define SA_SET_SYM_SIZE(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_size=(v))
+#define SA_SET_SYM_FSIZE(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_fsize=(v))
+#define SA_SET_SYM_LNNOPTR(s,v) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_lnnoptr=(v))
+#define SA_SET_SYM_DIMEN(s,i,v) (SYM_AUXENT (s)->x_sym.x_fcnary.x_ary.x_dimen[(i)]=(v))
+#define SA_SET_FILE_FNAME(s,v) strncpy(SYM_AUXENT (s)->x_file.x_fname,(v),FILNMLEN)
+#define SA_SET_SCN_SCNLEN(s,v) (SYM_AUXENT (s)->x_scn.x_scnlen=(v))
+#define SA_SET_SCN_NRELOC(s,v) (SYM_AUXENT (s)->x_scn.x_nreloc=(v))
+#define SA_SET_SCN_NLINNO(s,v) (SYM_AUXENT (s)->x_scn.x_nlinno=(v))
+
+/* Internal use only definitions. SF_ stands for symbol flags.
+
+ These values can be assigned to sy_symbol.ost_flags field of a symbolS.
+
+ You'll break i960 if you shift the SYSPROC bits anywhere else. for
+ more on the balname/callname hack, see tc-i960.h. b.out is done
+ differently. */
+
+#define SF_I960_MASK (0x000001ff) /* Bits 0-8 are used by the i960 port. */
+#define SF_SYSPROC (0x0000003f) /* bits 0-5 are used to store the sysproc number */
+#define SF_IS_SYSPROC (0x00000040) /* bit 6 marks symbols that are sysprocs */
+#define SF_BALNAME (0x00000080) /* bit 7 marks BALNAME symbols */
+#define SF_CALLNAME (0x00000100) /* bit 8 marks CALLNAME symbols */
+
+#define SF_NORMAL_MASK (0x0000ffff) /* bits 12-15 are general purpose. */
+
+#define SF_STATICS (0x00001000) /* Mark the .text & all symbols */
+#define SF_DEFINED (0x00002000) /* Symbol is defined in this file */
+#define SF_STRING (0x00004000) /* Symbol name length > 8 */
+#define SF_LOCAL (0x00008000) /* Symbol must not be emitted */
+
+#define SF_DEBUG_MASK (0xffff0000) /* bits 16-31 are debug info */
+
+#define SF_FUNCTION (0x00010000) /* The symbol is a function */
+#define SF_PROCESS (0x00020000) /* Process symbol before write */
+#define SF_TAGGED (0x00040000) /* Is associated with a tag */
+#define SF_TAG (0x00080000) /* Is a tag */
+#define SF_DEBUG (0x00100000) /* Is in debug or abs section */
+#define SF_GET_SEGMENT (0x00200000) /* Get the section of the forward symbol. */
+/* All other bits are unused. */
+
+/* Accessors. */
+#define SF_GET(s) (*symbol_get_obj (s))
+#define SF_GET_DEBUG(s) (symbol_get_bfdsym (s)->flags & BSF_DEBUGGING)
+#define SF_SET_DEBUG(s) (symbol_get_bfdsym (s)->flags |= BSF_DEBUGGING)
+#define SF_GET_NORMAL_FIELD(s) (SF_GET (s) & SF_NORMAL_MASK)
+#define SF_GET_DEBUG_FIELD(s) (SF_GET (s) & SF_DEBUG_MASK)
+#define SF_GET_FILE(s) (SF_GET (s) & SF_FILE)
+#define SF_GET_STATICS(s) (SF_GET (s) & SF_STATICS)
+#define SF_GET_DEFINED(s) (SF_GET (s) & SF_DEFINED)
+#define SF_GET_STRING(s) (SF_GET (s) & SF_STRING)
+#define SF_GET_LOCAL(s) (SF_GET (s) & SF_LOCAL)
+#define SF_GET_FUNCTION(s) (SF_GET (s) & SF_FUNCTION)
+#define SF_GET_PROCESS(s) (SF_GET (s) & SF_PROCESS)
+#define SF_GET_TAGGED(s) (SF_GET (s) & SF_TAGGED)
+#define SF_GET_TAG(s) (SF_GET (s) & SF_TAG)
+#define SF_GET_GET_SEGMENT(s) (SF_GET (s) & SF_GET_SEGMENT)
+#define SF_GET_I960(s) (SF_GET (s) & SF_I960_MASK) /* used by i960 */
+#define SF_GET_BALNAME(s) (SF_GET (s) & SF_BALNAME) /* used by i960 */
+#define SF_GET_CALLNAME(s) (SF_GET (s) & SF_CALLNAME) /* used by i960 */
+#define SF_GET_IS_SYSPROC(s) (SF_GET (s) & SF_IS_SYSPROC) /* used by i960 */
+#define SF_GET_SYSPROC(s) (SF_GET (s) & SF_SYSPROC) /* used by i960 */
+
+/* Modifiers. */
+#define SF_SET(s,v) (SF_GET (s) = (v))
+#define SF_SET_NORMAL_FIELD(s,v) (SF_GET (s) |= ((v) & SF_NORMAL_MASK))
+#define SF_SET_DEBUG_FIELD(s,v) (SF_GET (s) |= ((v) & SF_DEBUG_MASK))
+#define SF_SET_FILE(s) (SF_GET (s) |= SF_FILE)
+#define SF_SET_STATICS(s) (SF_GET (s) |= SF_STATICS)
+#define SF_SET_DEFINED(s) (SF_GET (s) |= SF_DEFINED)
+#define SF_SET_STRING(s) (SF_GET (s) |= SF_STRING)
+#define SF_SET_LOCAL(s) (SF_GET (s) |= SF_LOCAL)
+#define SF_CLEAR_LOCAL(s) (SF_GET (s) &= ~SF_LOCAL)
+#define SF_SET_FUNCTION(s) (SF_GET (s) |= SF_FUNCTION)
+#define SF_SET_PROCESS(s) (SF_GET (s) |= SF_PROCESS)
+#define SF_SET_TAGGED(s) (SF_GET (s) |= SF_TAGGED)
+#define SF_SET_TAG(s) (SF_GET (s) |= SF_TAG)
+#define SF_SET_GET_SEGMENT(s) (SF_GET (s) |= SF_GET_SEGMENT)
+#define SF_SET_I960(s,v) (SF_GET (s) |= ((v) & SF_I960_MASK)) /* used by i960 */
+#define SF_SET_BALNAME(s) (SF_GET (s) |= SF_BALNAME) /* used by i960 */
+#define SF_SET_CALLNAME(s) (SF_GET (s) |= SF_CALLNAME) /* used by i960 */
+#define SF_SET_IS_SYSPROC(s) (SF_GET (s) |= SF_IS_SYSPROC) /* used by i960 */
+#define SF_SET_SYSPROC(s,v) (SF_GET (s) |= ((v) & SF_SYSPROC)) /* used by i960 */
+
+/* -------------- Line number handling ------- */
+extern int text_lineno_number;
+extern int coff_line_base;
+extern int coff_n_line_nos;
+
+#define obj_emit_lineno(WHERE,LINE,FILE_START) abort ()
+extern void coff_add_linesym PARAMS ((symbolS *));
+
+void c_dot_file_symbol PARAMS ((const char *filename));
+#define obj_app_file c_dot_file_symbol
+
+extern void coff_frob_symbol PARAMS ((symbolS *, int *));
+extern void coff_adjust_symtab PARAMS ((void));
+extern void coff_frob_section PARAMS ((segT));
+extern void coff_adjust_section_syms PARAMS ((bfd *, asection *, PTR));
+extern void coff_frob_file_after_relocs PARAMS ((void));
+#define obj_frob_symbol(S,P) coff_frob_symbol(S,&P)
+#ifndef obj_adjust_symtab
+#define obj_adjust_symtab() coff_adjust_symtab()
+#endif
+#define obj_frob_section(S) coff_frob_section (S)
+#define obj_frob_file_after_relocs() coff_frob_file_after_relocs ()
+
+extern symbolS *coff_last_function;
+
+/* Forward the segment of a forwarded symbol, handle assignments that
+ just copy symbol values, etc. */
+#ifndef OBJ_COPY_SYMBOL_ATTRIBUTES
+#ifndef TE_I386AIX
+#define OBJ_COPY_SYMBOL_ATTRIBUTES(dest,src) \
+ (SF_GET_GET_SEGMENT (dest) \
+ ? (S_SET_SEGMENT (dest, S_GET_SEGMENT (src)), 0) \
+ : 0)
+#else
+#define OBJ_COPY_SYMBOL_ATTRIBUTES(dest,src) \
+ (SF_GET_GET_SEGMENT (dest) && S_GET_SEGMENT (dest) == SEG_UNKNOWN \
+ ? (S_SET_SEGMENT (dest, S_GET_SEGMENT (src)), 0) \
+ : 0)
+#endif
+#endif
+
+/* Sanity check. */
+
+#ifdef TC_I960
+#ifndef C_LEAFSTAT
+hey ! Where is the C_LEAFSTAT definition ? i960 - coff support is depending on it.
+#endif /* no C_LEAFSTAT */
+#endif /* TC_I960 */
+
+#else /* not BFD_ASSEMBLER */
+
+#if defined TC_A29K || defined TC_OR32
+/* Allow translate from aout relocs to coff relocs. */
+#define NO_RELOC 20
+#define RELOC_32 1
+#define RELOC_8 2
+#define RELOC_CONST 3
+#define RELOC_CONSTH 4
+#define RELOC_JUMPTARG 5
+#define RELOC_BASE22 6
+#define RELOC_HI22 7
+#define RELOC_LO10 8
+#define RELOC_BASE13 9
+#define RELOC_WDISP22 10
+#define RELOC_WDISP30 11
+#endif
+
+extern const segT N_TYPE_seg[];
+
+/* Magic number of paged executable. */
+#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE 0x8300
+
+/* SYMBOL TABLE */
+
+/* Symbol table entry data type. */
+
+typedef struct
+{
+ /* Basic symbol */
+ struct internal_syment ost_entry;
+ /* Auxiliary entry. */
+ union internal_auxent ost_auxent[OBJ_COFF_MAX_AUXENTRIES];
+ /* obj_coff internal use only flags. */
+ unsigned int ost_flags;
+} obj_symbol_type;
+
+#ifndef DO_NOT_STRIP
+#define DO_NOT_STRIP 0
+#endif
+/* Symbol table macros and constants. */
+
+/* Possible and useful section number in symbol table
+ The values of TEXT, DATA and BSS may not be portable. */
+
+#define C_ABS_SECTION N_ABS
+#define C_UNDEF_SECTION N_UNDEF
+#define C_DEBUG_SECTION N_DEBUG
+#define C_NTV_SECTION N_TV
+#define C_PTV_SECTION P_TV
+#define C_REGISTER_SECTION 50
+
+/* Macros to extract information from a symbol table entry.
+ This syntactic indirection allows independence regarding a.out or coff.
+ The argument (s) of all these macros is a pointer to a symbol table entry. */
+
+/* Predicates. */
+/* True if the symbol is external. */
+#define S_IS_EXTERNAL(s) \
+ ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION)
+
+/* True if symbol has been defined, ie :
+ section > 0 (DATA, TEXT or BSS)
+ section == 0 and value > 0 (external bss symbol). */
+#define S_IS_DEFINED(s) \
+ ((s)->sy_symbol.ost_entry.n_scnum > C_UNDEF_SECTION \
+ || ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION \
+ && S_GET_VALUE (s) > 0) \
+ || ((s)->sy_symbol.ost_entry.n_scnum == C_ABS_SECTION))
+
+/* Return true for symbols that should not be reduced to section
+ symbols or eliminated from expressions, because they may be
+ overridden by the linker. */
+#define S_FORCE_RELOC(s, strict) \
+ (!SEG_NORMAL (S_GET_SEGMENT (s)) || (strict && S_IS_WEAK (s)))
+
+/* True if a debug special symbol entry. */
+#define S_IS_DEBUG(s) \
+ ((s)->sy_symbol.ost_entry.n_scnum == C_DEBUG_SECTION)
+
+/* True if a symbol is local symbol name. */
+/* A symbol name whose name includes ^A is a gas internal pseudo symbol. */
+#define S_IS_LOCAL(s) \
+ ((s)->sy_symbol.ost_entry.n_scnum == C_REGISTER_SECTION \
+ || (S_LOCAL_NAME(s) && ! flag_keep_locals && ! S_IS_DEBUG (s)) \
+ || strchr (S_GET_NAME (s), '\001') != NULL \
+ || strchr (S_GET_NAME (s), '\002') != NULL \
+ || (flag_strip_local_absolute \
+ && !S_IS_EXTERNAL(s) \
+ && (s)->sy_symbol.ost_entry.n_scnum == C_ABS_SECTION))
+
+/* True if a symbol is not defined in this file. */
+#define S_IS_EXTERN(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 \
+ && S_GET_VALUE (s) == 0)
+
+/* True if a symbol can be multiply defined (bss symbols have this def
+ though it is bad practice). */
+#define S_IS_COMMON(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 \
+ && S_GET_VALUE (s) != 0)
+
+/* True if a symbol name is in the string table, i.e. its length is > 8. */
+#define S_IS_STRING(s) (strlen(S_GET_NAME(s)) > 8 ? 1 : 0)
+
+/* True if a symbol is defined as weak. */
+#ifdef TE_PE
+#define S_IS_WEAK(s) \
+ ((s)->sy_symbol.ost_entry.n_sclass == C_NT_WEAK \
+ || (s)->sy_symbol.ost_entry.n_sclass == C_WEAKEXT)
+#else
+#define S_IS_WEAK(s) \
+ ((s)->sy_symbol.ost_entry.n_sclass == C_WEAKEXT)
+#endif
+
+/* Accessors. */
+/* The name of the symbol. */
+#define S_GET_NAME(s) ((char*) (s)->sy_symbol.ost_entry.n_offset)
+
+/* The pointer to the string table. */
+#define S_GET_OFFSET(s) ((s)->sy_symbol.ost_entry.n_offset)
+
+/* The numeric value of the segment. */
+#define S_GET_SEGMENT(s) s_get_segment(s)
+
+/* The data type. */
+#define S_GET_DATA_TYPE(s) ((s)->sy_symbol.ost_entry.n_type)
+
+/* The storage class. */
+#define S_GET_STORAGE_CLASS(s) ((s)->sy_symbol.ost_entry.n_sclass)
+
+/* The number of auxiliary entries. */
+#define S_GET_NUMBER_AUXILIARY(s) ((s)->sy_symbol.ost_entry.n_numaux)
+
+/* Modifiers. */
+/* Set the name of the symbol. */
+#define S_SET_NAME(s,v) \
+ ((s)->sy_symbol.ost_entry.n_offset = (unsigned long) (v))
+
+/* Set the offset of the symbol. */
+#define S_SET_OFFSET(s,v) \
+ ((s)->sy_symbol.ost_entry.n_offset = (v))
+
+/* The numeric value of the segment. */
+#define S_SET_SEGMENT(s,v) \
+ ((s)->sy_symbol.ost_entry.n_scnum = SEGMENT_TO_SYMBOL_TYPE(v))
+
+/* The data type. */
+#define S_SET_DATA_TYPE(s,v) \
+ ((s)->sy_symbol.ost_entry.n_type = (v))
+
+/* The storage class. */
+#define S_SET_STORAGE_CLASS(s,v) \
+ ((s)->sy_symbol.ost_entry.n_sclass = (v))
+
+/* The number of auxiliary entries. */
+#define S_SET_NUMBER_AUXILIARY(s,v) \
+ ((s)->sy_symbol.ost_entry.n_numaux = (v))
+
+/* Additional modifiers. */
+/* The symbol is external (does not mean undefined). */
+#define S_SET_EXTERNAL(s) \
+ { S_SET_STORAGE_CLASS(s, C_EXT) ; SF_CLEAR_LOCAL(s); }
+
+/* Auxiliary entry macros. SA_ stands for symbol auxiliary. */
+/* Omit the tv related fields. */
+/* Accessors. */
+#define SYM_AUXENT(S) (&(S)->sy_symbol.ost_auxent[0])
+
+#define SA_GET_SYM_TAGNDX(s) (SYM_AUXENT (s)->x_sym.x_tagndx.l)
+#define SA_GET_SYM_LNNO(s) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_lnno)
+#define SA_GET_SYM_SIZE(s) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_size)
+#define SA_GET_SYM_FSIZE(s) (SYM_AUXENT (s)->x_sym.x_misc.x_fsize)
+#define SA_GET_SYM_LNNOPTR(s) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#define SA_GET_SYM_ENDNDX(s) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_endndx.l)
+#define SA_GET_SYM_DIMEN(s,i) (SYM_AUXENT (s)->x_sym.x_fcnary.x_ary.x_dimen[(i)])
+#define SA_GET_FILE_FNAME(s) (SYM_AUXENT (s)->x_file.x_fname)
+#define SA_GET_FILE_FNAME_OFFSET(s) (SYM_AUXENT (s)->x_file.x_n.x_offset)
+#define SA_GET_FILE_FNAME_ZEROS(s) (SYM_AUXENT (s)->x_file.x_n.x_zeroes)
+#define SA_GET_SCN_SCNLEN(s) (SYM_AUXENT (s)->x_scn.x_scnlen)
+#define SA_GET_SCN_NRELOC(s) (SYM_AUXENT (s)->x_scn.x_nreloc)
+#define SA_GET_SCN_NLINNO(s) (SYM_AUXENT (s)->x_scn.x_nlinno)
+
+/* Modifiers. */
+#define SA_SET_SYM_TAGNDX(s,v) (SYM_AUXENT (s)->x_sym.x_tagndx.l=(v))
+#define SA_SET_SYM_LNNO(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_lnno=(v))
+#define SA_SET_SYM_SIZE(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_size=(v))
+#define SA_SET_SYM_FSIZE(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_fsize=(v))
+#define SA_SET_SYM_LNNOPTR(s,v) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_lnnoptr=(v))
+#define SA_SET_SYM_ENDNDX(s,v) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_endndx.l=(v))
+#define SA_SET_SYM_DIMEN(s,i,v) (SYM_AUXENT (s)->x_sym.x_fcnary.x_ary.x_dimen[(i)]=(v))
+#define SA_SET_FILE_FNAME(s,v) strncpy(SYM_AUXENT (s)->x_file.x_fname,(v),FILNMLEN)
+#define SA_SET_FILE_FNAME_OFFSET(s,v) (SYM_AUXENT (s)->x_file.x_n.x_offset=(v))
+#define SA_SET_FILE_FNAME_ZEROS(s,v) (SYM_AUXENT (s)->x_file.x_n.x_zeroes=(v))
+#define SA_SET_SCN_SCNLEN(s,v) (SYM_AUXENT (s)->x_scn.x_scnlen=(v))
+#define SA_SET_SCN_NRELOC(s,v) (SYM_AUXENT (s)->x_scn.x_nreloc=(v))
+#define SA_SET_SCN_NLINNO(s,v) (SYM_AUXENT (s)->x_scn.x_nlinno=(v))
+
+/* Internal use only definitions. SF_ stands for symbol flags.
+
+ These values can be assigned to sy_symbol.ost_flags field of a symbolS.
+
+ You'll break i960 if you shift the SYSPROC bits anywhere else. for
+ more on the balname/callname hack, see tc-i960.h. b.out is done
+ differently. */
+
+#define SF_I960_MASK (0x000001ff) /* Bits 0-8 are used by the i960 port. */
+#define SF_SYSPROC (0x0000003f) /* bits 0-5 are used to store the sysproc number */
+#define SF_IS_SYSPROC (0x00000040) /* bit 6 marks symbols that are sysprocs */
+#define SF_BALNAME (0x00000080) /* bit 7 marks BALNAME symbols */
+#define SF_CALLNAME (0x00000100) /* bit 8 marks CALLNAME symbols */
+
+#define SF_NORMAL_MASK (0x0000ffff) /* bits 12-15 are general purpose. */
+
+#define SF_STATICS (0x00001000) /* Mark the .text & all symbols */
+#define SF_DEFINED (0x00002000) /* Symbol is defined in this file */
+#define SF_STRING (0x00004000) /* Symbol name length > 8 */
+#define SF_LOCAL (0x00008000) /* Symbol must not be emitted */
+
+#define SF_DEBUG_MASK (0xffff0000) /* bits 16-31 are debug info */
+
+#define SF_FUNCTION (0x00010000) /* The symbol is a function */
+#define SF_PROCESS (0x00020000) /* Process symbol before write */
+#define SF_TAGGED (0x00040000) /* Is associated with a tag */
+#define SF_TAG (0x00080000) /* Is a tag */
+#define SF_DEBUG (0x00100000) /* Is in debug or abs section */
+#define SF_GET_SEGMENT (0x00200000) /* Get the section of the forward symbol. */
+#define SF_ADJ_LNNOPTR (0x00400000) /* Has a lnnoptr */
+/* All other bits are unused. */
+
+/* Accessors. */
+#define SF_GET(s) ((s)->sy_symbol.ost_flags)
+#define SF_GET_NORMAL_FIELD(s) (SF_GET (s) & SF_NORMAL_MASK)
+#define SF_GET_DEBUG_FIELD(s) (SF_GET (s) & SF_DEBUG_MASK)
+#define SF_GET_FILE(s) (SF_GET (s) & SF_FILE)
+#define SF_GET_STATICS(s) (SF_GET (s) & SF_STATICS)
+#define SF_GET_DEFINED(s) (SF_GET (s) & SF_DEFINED)
+#define SF_GET_STRING(s) (SF_GET (s) & SF_STRING)
+#define SF_GET_LOCAL(s) (SF_GET (s) & SF_LOCAL)
+#define SF_GET_FUNCTION(s) (SF_GET (s) & SF_FUNCTION)
+#define SF_GET_PROCESS(s) (SF_GET (s) & SF_PROCESS)
+#define SF_GET_DEBUG(s) (SF_GET (s) & SF_DEBUG)
+#define SF_GET_TAGGED(s) (SF_GET (s) & SF_TAGGED)
+#define SF_GET_TAG(s) (SF_GET (s) & SF_TAG)
+#define SF_GET_GET_SEGMENT(s) (SF_GET (s) & SF_GET_SEGMENT)
+#define SF_GET_ADJ_LNNOPTR(s) (SF_GET (s) & SF_ADJ_LNNOPTR)
+#define SF_GET_I960(s) (SF_GET (s) & SF_I960_MASK) /* used by i960 */
+#define SF_GET_BALNAME(s) (SF_GET (s) & SF_BALNAME) /* used by i960 */
+#define SF_GET_CALLNAME(s) (SF_GET (s) & SF_CALLNAME) /* used by i960 */
+#define SF_GET_IS_SYSPROC(s) (SF_GET (s) & SF_IS_SYSPROC) /* used by i960 */
+#define SF_GET_SYSPROC(s) (SF_GET (s) & SF_SYSPROC) /* used by i960 */
+
+/* Modifiers. */
+#define SF_SET(s,v) (SF_GET (s) = (v))
+#define SF_SET_NORMAL_FIELD(s,v) (SF_GET (s) |= ((v) & SF_NORMAL_MASK))
+#define SF_SET_DEBUG_FIELD(s,v) (SF_GET (s) |= ((v) & SF_DEBUG_MASK))
+#define SF_SET_FILE(s) (SF_GET (s) |= SF_FILE)
+#define SF_SET_STATICS(s) (SF_GET (s) |= SF_STATICS)
+#define SF_SET_DEFINED(s) (SF_GET (s) |= SF_DEFINED)
+#define SF_SET_STRING(s) (SF_GET (s) |= SF_STRING)
+#define SF_SET_LOCAL(s) (SF_GET (s) |= SF_LOCAL)
+#define SF_CLEAR_LOCAL(s) (SF_GET (s) &= ~SF_LOCAL)
+#define SF_SET_FUNCTION(s) (SF_GET (s) |= SF_FUNCTION)
+#define SF_SET_PROCESS(s) (SF_GET (s) |= SF_PROCESS)
+#define SF_SET_DEBUG(s) (SF_GET (s) |= SF_DEBUG)
+#define SF_SET_TAGGED(s) (SF_GET (s) |= SF_TAGGED)
+#define SF_SET_TAG(s) (SF_GET (s) |= SF_TAG)
+#define SF_SET_GET_SEGMENT(s) (SF_GET (s) |= SF_GET_SEGMENT)
+#define SF_SET_ADJ_LNNOPTR(s) (SF_GET (s) |= SF_ADJ_LNNOPTR)
+#define SF_SET_I960(s,v) (SF_GET (s) |= ((v) & SF_I960_MASK)) /* used by i960 */
+#define SF_SET_BALNAME(s) (SF_GET (s) |= SF_BALNAME) /* used by i960 */
+#define SF_SET_CALLNAME(s) (SF_GET (s) |= SF_CALLNAME) /* used by i960 */
+#define SF_SET_IS_SYSPROC(s) (SF_GET (s) |= SF_IS_SYSPROC) /* used by i960 */
+#define SF_SET_SYSPROC(s,v) (SF_GET (s) |= ((v) & SF_SYSPROC)) /* used by i960 */
+
+/* File header macro and type definition. */
+
+/* File position calculators. Beware to use them when all the
+ appropriate fields are set in the header. */
+
+#ifdef OBJ_COFF_OMIT_OPTIONAL_HEADER
+#define OBJ_COFF_AOUTHDRSZ (0)
+#else
+#define OBJ_COFF_AOUTHDRSZ (AOUTHDRSZ)
+#endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
+
+#define H_GET_FILE_SIZE(h) \
+ (long) (FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+ H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \
+ H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h) + \
+ H_GET_RELOCATION_SIZE(h) + H_GET_LINENO_SIZE(h) + \
+ H_GET_SYMBOL_TABLE_SIZE(h) + \
+ (h)->string_table_size)
+#define H_GET_TEXT_FILE_OFFSET(h) \
+ (long) (FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+ H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ)
+#define H_GET_DATA_FILE_OFFSET(h) \
+ (long) (FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+ H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \
+ H_GET_TEXT_SIZE(h))
+#define H_GET_BSS_FILE_OFFSET(h) 0
+#define H_GET_RELOCATION_FILE_OFFSET(h) \
+ (long) (FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+ H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \
+ H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h))
+#define H_GET_LINENO_FILE_OFFSET(h) \
+ (long) (FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+ H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \
+ H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h) + \
+ H_GET_RELOCATION_SIZE(h))
+#define H_GET_SYMBOL_TABLE_FILE_OFFSET(h) \
+ (long) (FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+ H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \
+ H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h) + \
+ H_GET_RELOCATION_SIZE(h) + H_GET_LINENO_SIZE(h))
+
+/* Accessors. */
+/* aouthdr. */
+#define H_GET_MAGIC_NUMBER(h) ((h)->aouthdr.magic)
+#define H_GET_VERSION_STAMP(h) ((h)->aouthdr.vstamp)
+#define H_GET_TEXT_SIZE(h) ((h)->aouthdr.tsize)
+#define H_GET_DATA_SIZE(h) ((h)->aouthdr.dsize)
+#define H_GET_BSS_SIZE(h) ((h)->aouthdr.bsize)
+#define H_GET_ENTRY_POINT(h) ((h)->aouthdr.entry)
+#define H_GET_TEXT_START(h) ((h)->aouthdr.text_start)
+#define H_GET_DATA_START(h) ((h)->aouthdr.data_start)
+/* filehdr. */
+#define H_GET_FILE_MAGIC_NUMBER(h) ((h)->filehdr.f_magic)
+#define H_GET_NUMBER_OF_SECTIONS(h) ((h)->filehdr.f_nscns)
+#define H_GET_TIME_STAMP(h) ((h)->filehdr.f_timdat)
+#define H_GET_SYMBOL_TABLE_POINTER(h) ((h)->filehdr.f_symptr)
+#define H_GET_SYMBOL_COUNT(h) ((h)->filehdr.f_nsyms)
+#define H_GET_SYMBOL_TABLE_SIZE(h) (H_GET_SYMBOL_COUNT(h) * SYMESZ)
+#define H_GET_SIZEOF_OPTIONAL_HEADER(h) ((h)->filehdr.f_opthdr)
+#define H_GET_FLAGS(h) ((h)->filehdr.f_flags)
+/* Extra fields to achieve bsd a.out compatibility and for convenience. */
+#define H_GET_RELOCATION_SIZE(h) ((h)->relocation_size)
+#define H_GET_STRING_SIZE(h) ((h)->string_table_size)
+#define H_GET_LINENO_SIZE(h) ((h)->lineno_size)
+
+#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
+#define H_GET_HEADER_SIZE(h) (sizeof (FILHDR) \
+ + sizeof (AOUTHDR)\
+ + (H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ))
+#else /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
+#define H_GET_HEADER_SIZE(h) (sizeof (FILHDR) \
+ + (H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ))
+#endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
+
+#define H_GET_TEXT_RELOCATION_SIZE(h) (text_section_header.s_nreloc * RELSZ)
+#define H_GET_DATA_RELOCATION_SIZE(h) (data_section_header.s_nreloc * RELSZ)
+
+/* Modifiers. */
+/* aouthdr. */
+#define H_SET_MAGIC_NUMBER(h,v) ((h)->aouthdr.magic = (v))
+#define H_SET_VERSION_STAMP(h,v) ((h)->aouthdr.vstamp = (v))
+#define H_SET_TEXT_SIZE(h,v) ((h)->aouthdr.tsize = (v))
+#define H_SET_DATA_SIZE(h,v) ((h)->aouthdr.dsize = (v))
+#define H_SET_BSS_SIZE(h,v) ((h)->aouthdr.bsize = (v))
+#define H_SET_ENTRY_POINT(h,v) ((h)->aouthdr.entry = (v))
+#define H_SET_TEXT_START(h,v) ((h)->aouthdr.text_start = (v))
+#define H_SET_DATA_START(h,v) ((h)->aouthdr.data_start = (v))
+/* filehdr. */
+#define H_SET_FILE_MAGIC_NUMBER(h,v) ((h)->filehdr.f_magic = (v))
+#define H_SET_NUMBER_OF_SECTIONS(h,v) ((h)->filehdr.f_nscns = (v))
+#define H_SET_TIME_STAMP(h,v) ((h)->filehdr.f_timdat = (v))
+#define H_SET_SYMBOL_TABLE_POINTER(h,v) ((h)->filehdr.f_symptr = (v))
+#define H_SET_SYMBOL_TABLE_SIZE(h,v) ((h)->filehdr.f_nsyms = (v))
+#define H_SET_SIZEOF_OPTIONAL_HEADER(h,v) ((h)->filehdr.f_opthdr = (v))
+#define H_SET_FLAGS(h,v) ((h)->filehdr.f_flags = (v))
+/* Extra fields to achieve bsd a.out compatibility and for convenience. */
+#define H_SET_RELOCATION_SIZE(h,t,d) ((h)->relocation_size = (t)+(d))
+#define H_SET_STRING_SIZE(h,v) ((h)->string_table_size = (v))
+#define H_SET_LINENO_SIZE(h,v) ((h)->lineno_size = (v))
+
+/* Segment flipping. */
+
+typedef struct
+{
+ struct internal_aouthdr aouthdr; /* a.out header */
+ struct internal_filehdr filehdr; /* File header, not machine dep. */
+ long string_table_size; /* names + '\0' + sizeof (int) */
+ long relocation_size; /* Cumulated size of relocation
+ information for all sections in
+ bytes. */
+ long lineno_size; /* Size of the line number information
+ table in bytes. */
+} object_headers;
+
+struct lineno_list
+{
+ struct bfd_internal_lineno line;
+ char *frag; /* Frag to which the line number is related. */
+ struct lineno_list *next; /* Forward chain pointer. */
+};
+
+#define obj_segment_name(i) (segment_info[(int) (i)].scnhdr.s_name)
+
+#define obj_add_segment(s) obj_coff_add_segment (s)
+
+extern segT obj_coff_add_segment PARAMS ((const char *));
+
+extern void obj_coff_section PARAMS ((int));
+
+extern void c_dot_file_symbol PARAMS ((char *filename));
+#define obj_app_file c_dot_file_symbol
+extern void obj_extra_stuff PARAMS ((object_headers * headers));
+
+extern segT s_get_segment PARAMS ((symbolS *ptr));
+
+extern void c_section_header PARAMS ((struct internal_scnhdr * header,
+ char *name,
+ long core_address,
+ long size,
+ long data_ptr,
+ long reloc_ptr,
+ long lineno_ptr,
+ long reloc_number,
+ long lineno_number,
+ long alignment));
+
+#ifndef tc_coff_symbol_emit_hook
+void tc_coff_symbol_emit_hook PARAMS ((symbolS *));
+#endif
+
+/* Sanity check. */
+
+#ifdef TC_I960
+#ifndef C_LEAFSTAT
+hey ! Where is the C_LEAFSTAT definition ? i960 - coff support is depending on it.
+#endif /* no C_LEAFSTAT */
+#endif /* TC_I960 */
+extern struct internal_scnhdr data_section_header;
+extern struct internal_scnhdr text_section_header;
+
+/* Forward the segment of a forwarded symbol. */
+#define OBJ_COPY_SYMBOL_ATTRIBUTES(dest,src) \
+ (SF_GET_GET_SEGMENT (dest) \
+ ? (S_SET_SEGMENT (dest, S_GET_SEGMENT (src)), 0) \
+ : 0)
+
+#ifdef TE_PE
+#define obj_handle_link_once(t) obj_coff_pe_handle_link_once (t)
+extern void obj_coff_pe_handle_link_once ();
+#endif
+
+#endif /* not BFD_ASSEMBLER */
+
+extern const pseudo_typeS coff_pseudo_table[];
+
+#ifndef obj_pop_insert
+#define obj_pop_insert() pop_insert (coff_pseudo_table)
+#endif
+
+/* In COFF, if a symbol is defined using .def/.val SYM/.endef, it's OK
+ to redefine the symbol later on. This can happen if C symbols use
+ a prefix, and a symbol is defined both with and without the prefix,
+ as in start/_start/__start in gcc/libgcc1-test.c. */
+#define RESOLVE_SYMBOL_REDEFINITION(sym) \
+(SF_GET_GET_SEGMENT (sym) \
+ ? (sym->sy_frag = frag_now, \
+ S_SET_VALUE (sym, frag_now_fix ()), \
+ S_SET_SEGMENT (sym, now_seg), \
+ 0) \
+ : 0)
+
+/* Stabs in a coff file go into their own section. */
+#define SEPARATE_STAB_SECTIONS 1
+
+/* We need 12 bytes at the start of the section to hold some initial
+ information. */
+extern void obj_coff_init_stab_section PARAMS ((segT));
+#define INIT_STAB_SECTION(seg) obj_coff_init_stab_section (seg)
+
+/* Store the number of relocations in the section aux entry. */
+#define SET_SECTION_RELOCS(sec, relocs, n) \
+ SA_SET_SCN_NRELOC (section_symbol (sec), n)
+
+#endif /* OBJ_FORMAT_H */
diff --git a/x/binutils/gas/config/obj-ecoff.c b/x/binutils/gas/config/obj-ecoff.c
new file mode 100644
index 0000000..69f8d9a
--- /dev/null
+++ b/x/binutils/gas/config/obj-ecoff.c
@@ -0,0 +1,328 @@
+/* ECOFF object file format.
+ Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+ This file was put together by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GAS.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define OBJ_HEADER "obj-ecoff.h"
+#include "as.h"
+#include "coff/internal.h"
+#include "bfd/libcoff.h"
+#include "bfd/libecoff.h"
+
+/* Almost all of the ECOFF support is actually in ecoff.c in the main
+ gas directory. This file mostly just arranges to call that one at
+ the right times. */
+
+static int ecoff_sec_sym_ok_for_reloc PARAMS ((asection *));
+static void obj_ecoff_frob_symbol PARAMS ((symbolS *, int *));
+static void ecoff_pop_insert PARAMS ((void));
+static int ecoff_separate_stab_sections PARAMS ((void));
+
+/* These are the pseudo-ops we support in this file. Only those
+ relating to debugging information are supported here.
+
+ The following pseudo-ops from the Kane and Heinrich MIPS book
+ should be defined here, but are currently unsupported: .aent,
+ .bgnb, .endb, .verstamp, .vreg.
+
+ The following pseudo-ops from the Kane and Heinrich MIPS book are
+ MIPS CPU specific, and should be defined by tc-mips.c: .alias,
+ .extern, .galive, .gjaldef, .gjrlive, .livereg, .noalias, .option,
+ .rdata, .sdata, .set.
+
+ The following pseudo-ops from the Kane and Heinrich MIPS book are
+ not MIPS CPU specific, but are also not ECOFF specific. I have
+ only listed the ones which are not already in read.c. It's not
+ completely clear where these should be defined, but tc-mips.c is
+ probably the most reasonable place: .asciiz, .asm0, .endr, .err,
+ .half, .lab, .repeat, .struct, .weakext. */
+
+const pseudo_typeS obj_pseudo_table[] =
+{
+ /* COFF style debugging information. .ln is not used; .loc is used
+ instead. */
+ { "def", ecoff_directive_def, 0 },
+ { "dim", ecoff_directive_dim, 0 },
+ { "endef", ecoff_directive_endef, 0 },
+ { "file", ecoff_directive_file, 0 },
+ { "scl", ecoff_directive_scl, 0 },
+ { "size", ecoff_directive_size, 0 },
+ { "esize", ecoff_directive_size, 0 },
+ { "tag", ecoff_directive_tag, 0 },
+ { "type", ecoff_directive_type, 0 },
+ { "etype", ecoff_directive_type, 0 },
+ { "val", ecoff_directive_val, 0 },
+
+ /* ECOFF specific debugging information. */
+ { "begin", ecoff_directive_begin, 0 },
+ { "bend", ecoff_directive_bend, 0 },
+ { "end", ecoff_directive_end, 0 },
+ { "ent", ecoff_directive_ent, 0 },
+ { "fmask", ecoff_directive_fmask, 0 },
+ { "frame", ecoff_directive_frame, 0 },
+ { "loc", ecoff_directive_loc, 0 },
+ { "mask", ecoff_directive_mask, 0 },
+
+ /* Other ECOFF directives. */
+ { "extern", ecoff_directive_extern, 0 },
+
+#ifndef TC_MIPS
+ /* For TC_MIPS, tc-mips.c adds this. */
+ { "weakext", ecoff_directive_weakext, 0 },
+#endif
+
+ /* These are used on Irix. I don't know how to implement them. */
+ { "bgnb", s_ignore, 0 },
+ { "endb", s_ignore, 0 },
+ { "verstamp", s_ignore, 0 },
+
+ /* Sentinel. */
+ { NULL, s_ignore, 0 }
+};
+
+/* Set section VMAs and GP values before reloc processing. */
+
+void
+ecoff_frob_file_before_fix ()
+{
+ bfd_vma addr;
+ asection **sec;
+
+ /* Set the section VMA values. We force the .sdata and .sbss
+ sections to the end to ensure that their VMA addresses are close
+ together so that the GP register can address both of them. We
+ put the .bss section after the .sbss section.
+
+ Also, for the Alpha, we must sort the sections, to make sure they
+ appear in the output file in the correct order. (Actually, maybe
+ this is a job for BFD. But the VMAs computed would be out of
+ whack if we computed them given our initial, random ordering.
+ It's possible that that wouldn't break things; I could do some
+ experimenting sometime and find out.
+
+ This output ordering of sections is magic, on the Alpha, at
+ least. The .lita section must come before .lit8 and .lit4,
+ otherwise the OSF/1 linker may silently trash the .lit{4,8}
+ section contents. Also, .text must preceed .rdata. These differ
+ from the order described in some parts of the DEC OSF/1 Assembly
+ Language Programmer's Guide, but that order doesn't seem to work
+ with their linker.
+
+ I don't know if section ordering on the MIPS is important. */
+
+ static const char *const names[] = {
+ /* text segment */
+ ".text", ".rdata", ".init", ".fini",
+ /* data segment */
+ ".data", ".lita", ".lit8", ".lit4", ".sdata", ".got",
+ /* bss segment */
+ ".sbss", ".bss",
+ };
+#define n_names ((int) (sizeof (names) / sizeof (names[0])))
+
+ /* Sections that match names, order to be straightened out later. */
+ asection *secs[n_names];
+ int i;
+
+ addr = 0;
+ for (i = 0; i < n_names; i++)
+ secs[i] = 0;
+
+ for (sec = &stdoutput->sections; *sec != (asection *) NULL; )
+ {
+ for (i = 0; i < n_names; i++)
+ if (!strcmp ((*sec)->name, names[i]))
+ {
+ secs[i] = *sec;
+ bfd_section_list_remove (stdoutput, sec);
+ break;
+ }
+ if (i == n_names)
+ {
+ bfd_set_section_vma (stdoutput, *sec, addr);
+ addr += bfd_section_size (stdoutput, *sec);
+ sec = &(*sec)->next;
+ }
+ }
+ for (i = 0; i < n_names; i++)
+ if (secs[i])
+ {
+ bfd_set_section_vma (stdoutput, secs[i], addr);
+ addr += bfd_section_size (stdoutput, secs[i]);
+ }
+ for (i = n_names - 1; i >= 0; i--)
+ if (secs[i])
+ bfd_section_list_insert (stdoutput, &stdoutput->sections, secs[i]);
+
+ /* Fill in the register masks. */
+ {
+ unsigned long gprmask = 0;
+ unsigned long fprmask = 0;
+ unsigned long *cprmask = NULL;
+
+#ifdef TC_MIPS
+ /* Fill in the MIPS register masks. It's probably not worth
+ setting up a generic interface for this. */
+ gprmask = mips_gprmask;
+ cprmask = mips_cprmask;
+#endif
+
+#ifdef TC_ALPHA
+ alpha_frob_ecoff_data ();
+
+ if (! bfd_ecoff_set_gp_value (stdoutput, alpha_gp_value))
+ as_fatal (_("Can't set GP value"));
+
+ gprmask = alpha_gprmask;
+ fprmask = alpha_fprmask;
+#endif
+
+ if (! bfd_ecoff_set_regmasks (stdoutput, gprmask, fprmask, cprmask))
+ as_fatal (_("Can't set register masks"));
+ }
+}
+
+/* Swap out the symbols and debugging information for BFD. */
+
+void
+ecoff_frob_file ()
+{
+ const struct ecoff_debug_swap * const debug_swap
+ = &ecoff_backend (stdoutput)->debug_swap;
+ bfd_vma addr ATTRIBUTE_UNUSED;
+ HDRR *hdr;
+ char *buf;
+ char *set;
+
+ /* Build the ECOFF debugging information. */
+ assert (ecoff_data (stdoutput) != 0);
+ hdr = &ecoff_data (stdoutput)->debug_info.symbolic_header;
+ ecoff_build_debug (hdr, &buf, debug_swap);
+
+ /* Finish up the ecoff_tdata structure. */
+ set = buf;
+#define SET(ptr, count, type, size) \
+ if (hdr->count == 0) \
+ ecoff_data (stdoutput)->debug_info.ptr = (type) NULL; \
+ else \
+ { \
+ ecoff_data (stdoutput)->debug_info.ptr = (type) set; \
+ set += hdr->count * size; \
+ }
+
+ SET (line, cbLine, unsigned char *, sizeof (unsigned char));
+ SET (external_dnr, idnMax, PTR, debug_swap->external_dnr_size);
+ SET (external_pdr, ipdMax, PTR, debug_swap->external_pdr_size);
+ SET (external_sym, isymMax, PTR, debug_swap->external_sym_size);
+ SET (external_opt, ioptMax, PTR, debug_swap->external_opt_size);
+ SET (external_aux, iauxMax, union aux_ext *, sizeof (union aux_ext));
+ SET (ss, issMax, char *, sizeof (char));
+ SET (ssext, issExtMax, char *, sizeof (char));
+ SET (external_rfd, crfd, PTR, debug_swap->external_rfd_size);
+ SET (external_fdr, ifdMax, PTR, debug_swap->external_fdr_size);
+ SET (external_ext, iextMax, PTR, debug_swap->external_ext_size);
+#undef SET
+}
+
+/* This is called by the ECOFF code to set the external information
+ for a symbol. We just pass it on to BFD, which expects the swapped
+ information to be stored in the native field of the symbol. */
+
+void
+obj_ecoff_set_ext (sym, ext)
+ symbolS *sym;
+ EXTR *ext;
+{
+ const struct ecoff_debug_swap * const debug_swap
+ = &ecoff_backend (stdoutput)->debug_swap;
+ ecoff_symbol_type *esym;
+
+ know (bfd_asymbol_flavour (symbol_get_bfdsym (sym))
+ == bfd_target_ecoff_flavour);
+ esym = ecoffsymbol (symbol_get_bfdsym (sym));
+ esym->local = FALSE;
+ esym->native = xmalloc (debug_swap->external_ext_size);
+ (*debug_swap->swap_ext_out) (stdoutput, ext, esym->native);
+}
+
+static int
+ecoff_sec_sym_ok_for_reloc (sec)
+ asection *sec ATTRIBUTE_UNUSED;
+{
+ return 1;
+}
+
+static void
+obj_ecoff_frob_symbol (sym, puntp)
+ symbolS *sym;
+ int *puntp ATTRIBUTE_UNUSED;
+{
+ ecoff_frob_symbol (sym);
+}
+
+static void
+ecoff_pop_insert ()
+{
+ pop_insert (obj_pseudo_table);
+}
+
+static int
+ecoff_separate_stab_sections ()
+{
+ return 0;
+}
+
+const struct format_ops ecoff_format_ops =
+{
+ bfd_target_ecoff_flavour,
+ 0, /* dfl_leading_underscore */
+
+ /* FIXME: A comment why emit_section_symbols is different here (1) from
+ the single-format definition (0) would be in order. */
+ 1, /* emit_section_symbols */
+ 0, /* begin */
+ ecoff_new_file,
+ obj_ecoff_frob_symbol,
+ ecoff_frob_file,
+ 0, /* frob_file_before_adjust */
+ ecoff_frob_file_before_fix,
+ 0, /* frob_file_after_relocs */
+ 0, /* s_get_size */
+ 0, /* s_set_size */
+ 0, /* s_get_align */
+ 0, /* s_set_align */
+ 0, /* s_get_other */
+ 0, /* s_set_other */
+ 0, /* s_get_desc */
+ 0, /* s_set_desc */
+ 0, /* s_get_type */
+ 0, /* s_set_type */
+ 0, /* copy_symbol_attributes */
+ ecoff_generate_asm_lineno,
+ ecoff_stab,
+ ecoff_separate_stab_sections,
+ 0, /* init_stab_section */
+ ecoff_sec_sym_ok_for_reloc,
+ ecoff_pop_insert,
+ ecoff_set_ext,
+ ecoff_read_begin_hook,
+ ecoff_symbol_new_hook
+};
diff --git a/x/binutils/gas/config/obj-ecoff.h b/x/binutils/gas/config/obj-ecoff.h
new file mode 100644
index 0000000..54ee043
--- /dev/null
+++ b/x/binutils/gas/config/obj-ecoff.h
@@ -0,0 +1,76 @@
+/* ECOFF object file format header file.
+ Copyright 1993, 1994, 1995, 1996, 1997, 1999, 2002
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GAS.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define OBJ_ECOFF 1
+
+/* Use the generic ECOFF debugging code. */
+#define ECOFF_DEBUGGING 1
+
+#define OUTPUT_FLAVOR bfd_target_ecoff_flavour
+
+#include "targ-cpu.h"
+
+#include "ecoff.h"
+
+/* For each gas symbol we keep track of which file it came from, of
+ whether we have generated an ECOFF symbol for it, and whether the
+ symbols is undefined (this last is needed to distinguish a .extern
+ symbols from a .comm symbol). */
+
+struct ecoff_sy_obj
+{
+ struct efdr *ecoff_file;
+ struct localsym *ecoff_symbol;
+ valueT ecoff_extern_size;
+};
+
+#define OBJ_SYMFIELD_TYPE struct ecoff_sy_obj
+
+/* Modify the ECOFF symbol. */
+#define obj_frob_symbol(symp, punt) ecoff_frob_symbol (symp)
+
+/* Set section VMAs and GP. */
+extern void ecoff_frob_file_before_fix PARAMS ((void));
+#define obj_frob_file_before_fix() ecoff_frob_file_before_fix ()
+
+/* This is used to write the symbolic data in the format that BFD
+ expects it. */
+extern void ecoff_frob_file PARAMS ((void));
+#define obj_frob_file() ecoff_frob_file ()
+
+/* We use the ECOFF functions as our hooks. */
+#define obj_read_begin_hook ecoff_read_begin_hook
+#define obj_symbol_new_hook ecoff_symbol_new_hook
+
+/* Record file switches in the ECOFF symbol table. */
+#define obj_app_file(name) ecoff_new_file (name)
+
+/* At the moment we don't want to do any stabs processing in read.c. */
+#define OBJ_PROCESS_STAB(seg, what, string, type, other, desc) \
+ ecoff_stab ((seg), (what), (string), (type), (other), (desc))
+
+#define EMIT_SECTION_SYMBOLS 0
+#define obj_sec_sym_ok_for_reloc(SEC) 1
+
+#define obj_ecoff_set_ext ecoff_set_ext
+extern void obj_ecoff_set_ext PARAMS ((symbolS *, EXTR *));
diff --git a/x/binutils/gas/config/obj-elf.c b/x/binutils/gas/config/obj-elf.c
new file mode 100644
index 0000000..14d48f2
--- /dev/null
+++ b/x/binutils/gas/config/obj-elf.c
@@ -0,0 +1,2193 @@
+/* ELF object file format
+ Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2,
+ or (at your option) any later version.
+
+ GAS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define OBJ_HEADER "obj-elf.h"
+#include "as.h"
+#include "safe-ctype.h"
+#include "subsegs.h"
+#include "obstack.h"
+#include "struc-symbol.h"
+#include "dwarf2dbg.h"
+
+#ifndef ECOFF_DEBUGGING
+#define ECOFF_DEBUGGING 0
+#else
+#define NEED_ECOFF_DEBUG
+#endif
+
+#ifdef NEED_ECOFF_DEBUG
+#include "ecoff.h"
+#endif
+
+#ifdef TC_ALPHA
+#include "elf/alpha.h"
+#endif
+
+#ifdef TC_MIPS
+#include "elf/mips.h"
+#endif
+
+#ifdef TC_PPC
+#include "elf/ppc.h"
+#endif
+
+#ifdef TC_I370
+#include "elf/i370.h"
+#endif
+
+static void obj_elf_line (int);
+static void obj_elf_size (int);
+static void obj_elf_type (int);
+static void obj_elf_ident (int);
+static void obj_elf_weak (int);
+static void obj_elf_local (int);
+static void obj_elf_visibility (int);
+static void obj_elf_symver (int);
+static void obj_elf_subsection (int);
+static void obj_elf_popsection (int);
+static void obj_elf_tls_common (int);
+static void obj_elf_lcomm (int);
+
+static const pseudo_typeS elf_pseudo_table[] =
+{
+ {"comm", obj_elf_common, 0},
+ {"common", obj_elf_common, 1},
+ {"ident", obj_elf_ident, 0},
+ {"lcomm", obj_elf_lcomm, 0},
+ {"local", obj_elf_local, 0},
+ {"previous", obj_elf_previous, 0},
+ {"section", obj_elf_section, 0},
+ {"section.s", obj_elf_section, 0},
+ {"sect", obj_elf_section, 0},
+ {"sect.s", obj_elf_section, 0},
+ {"pushsection", obj_elf_section, 1},
+ {"popsection", obj_elf_popsection, 0},
+ {"size", obj_elf_size, 0},
+ {"type", obj_elf_type, 0},
+ {"version", obj_elf_version, 0},
+ {"weak", obj_elf_weak, 0},
+
+ /* These define symbol visibility. */
+ {"internal", obj_elf_visibility, STV_INTERNAL},
+ {"hidden", obj_elf_visibility, STV_HIDDEN},
+ {"protected", obj_elf_visibility, STV_PROTECTED},
+
+ /* These are used for stabs-in-elf configurations. */
+ {"line", obj_elf_line, 0},
+
+ /* This is a GNU extension to handle symbol versions. */
+ {"symver", obj_elf_symver, 0},
+
+ /* A GNU extension to change subsection only. */
+ {"subsection", obj_elf_subsection, 0},
+
+ /* These are GNU extensions to aid in garbage collecting C++ vtables. */
+ {"vtable_inherit", (void (*) (int)) &obj_elf_vtable_inherit, 0},
+ {"vtable_entry", (void (*) (int)) &obj_elf_vtable_entry, 0},
+
+ /* These are used for dwarf. */
+ {"2byte", cons, 2},
+ {"4byte", cons, 4},
+ {"8byte", cons, 8},
+ /* These are used for dwarf2. */
+ { "file", (void (*) (int)) dwarf2_directive_file, 0 },
+ { "loc", dwarf2_directive_loc, 0 },
+
+ /* We need to trap the section changing calls to handle .previous. */
+ {"data", obj_elf_data, 0},
+ {"text", obj_elf_text, 0},
+
+ {"tls_common", obj_elf_tls_common, 0},
+
+ /* End sentinel. */
+ {NULL, NULL, 0},
+};
+
+static const pseudo_typeS ecoff_debug_pseudo_table[] =
+{
+#ifdef NEED_ECOFF_DEBUG
+ /* COFF style debugging information for ECOFF. .ln is not used; .loc
+ is used instead. */
+ { "def", ecoff_directive_def, 0 },
+ { "dim", ecoff_directive_dim, 0 },
+ { "endef", ecoff_directive_endef, 0 },
+ { "file", ecoff_directive_file, 0 },
+ { "scl", ecoff_directive_scl, 0 },
+ { "tag", ecoff_directive_tag, 0 },
+ { "val", ecoff_directive_val, 0 },
+
+ /* COFF debugging requires pseudo-ops .size and .type, but ELF
+ already has meanings for those. We use .esize and .etype
+ instead. These are only generated by gcc anyhow. */
+ { "esize", ecoff_directive_size, 0 },
+ { "etype", ecoff_directive_type, 0 },
+
+ /* ECOFF specific debugging information. */
+ { "begin", ecoff_directive_begin, 0 },
+ { "bend", ecoff_directive_bend, 0 },
+ { "end", ecoff_directive_end, 0 },
+ { "ent", ecoff_directive_ent, 0 },
+ { "fmask", ecoff_directive_fmask, 0 },
+ { "frame", ecoff_directive_frame, 0 },
+ { "loc", ecoff_directive_loc, 0 },
+ { "mask", ecoff_directive_mask, 0 },
+
+ /* Other ECOFF directives. */
+ { "extern", ecoff_directive_extern, 0 },
+
+ /* These are used on Irix. I don't know how to implement them. */
+ { "alias", s_ignore, 0 },
+ { "bgnb", s_ignore, 0 },
+ { "endb", s_ignore, 0 },
+ { "lab", s_ignore, 0 },
+ { "noalias", s_ignore, 0 },
+ { "verstamp", s_ignore, 0 },
+ { "vreg", s_ignore, 0 },
+#endif
+
+ {NULL, NULL, 0} /* end sentinel */
+};
+
+#undef NO_RELOC
+#include "aout/aout64.h"
+
+/* This is called when the assembler starts. */
+
+void
+elf_begin (void)
+{
+ asection *s;
+
+ /* Add symbols for the known sections to the symbol table. */
+ s = bfd_get_section_by_name (stdoutput, TEXT_SECTION_NAME);
+ symbol_table_insert (section_symbol (s));
+ s = bfd_get_section_by_name (stdoutput, DATA_SECTION_NAME);
+ symbol_table_insert (section_symbol (s));
+ s = bfd_get_section_by_name (stdoutput, BSS_SECTION_NAME);
+ symbol_table_insert (section_symbol (s));
+}
+
+void
+elf_pop_insert (void)
+{
+ pop_insert (elf_pseudo_table);
+ if (ECOFF_DEBUGGING)
+ pop_insert (ecoff_debug_pseudo_table);
+}
+
+static bfd_vma
+elf_s_get_size (symbolS *sym)
+{
+ return S_GET_SIZE (sym);
+}
+
+static void
+elf_s_set_size (symbolS *sym, bfd_vma sz)
+{
+ S_SET_SIZE (sym, sz);
+}
+
+static bfd_vma
+elf_s_get_align (symbolS *sym)
+{
+ return S_GET_ALIGN (sym);
+}
+
+static void
+elf_s_set_align (symbolS *sym, bfd_vma align)
+{
+ S_SET_ALIGN (sym, align);
+}
+
+int
+elf_s_get_other (symbolS *sym)
+{
+ return elf_symbol (symbol_get_bfdsym (sym))->internal_elf_sym.st_other;
+}
+
+static void
+elf_s_set_other (symbolS *sym, int other)
+{
+ S_SET_OTHER (sym, other);
+}
+
+static int
+elf_sec_sym_ok_for_reloc (asection *sec)
+{
+ return obj_sec_sym_ok_for_reloc (sec);
+}
+
+void
+elf_file_symbol (const char *s)
+{
+ symbolS *sym;
+
+ sym = symbol_new (s, absolute_section, 0, NULL);
+ symbol_set_frag (sym, &zero_address_frag);
+ symbol_get_bfdsym (sym)->flags |= BSF_FILE;
+
+ if (symbol_rootP != sym)
+ {
+ symbol_remove (sym, &symbol_rootP, &symbol_lastP);
+ symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
+#ifdef DEBUG
+ verify_symbol_chain (symbol_rootP, symbol_lastP);
+#endif
+ }
+
+#ifdef NEED_ECOFF_DEBUG
+ ecoff_new_file (s);
+#endif
+}
+
+/* Called from read.c:s_comm after we've parsed .comm symbol, size.
+ Parse a possible alignment value. */
+
+static symbolS *
+elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
+{
+ addressT align = 0;
+ int is_local = symbol_get_obj (symbolP)->local;
+
+ if (*input_line_pointer == ',')
+ {
+ char *save = input_line_pointer;
+
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer == '"')
+ {
+ /* For sparc. Accept .common symbol, length, "bss" */
+ input_line_pointer++;
+ /* Some use the dot, some don't. */
+ if (*input_line_pointer == '.')
+ input_line_pointer++;
+ /* Some say data, some say bss. */
+ if (strncmp (input_line_pointer, "bss\"", 4) == 0)
+ input_line_pointer += 4;
+ else if (strncmp (input_line_pointer, "data\"", 5) == 0)
+ input_line_pointer += 5;
+ else
+ {
+ char *p = input_line_pointer;
+ char c;
+
+ while (*--p != '"')
+ ;
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ if (*input_line_pointer++ == '"')
+ break;
+ c = *input_line_pointer;
+ *input_line_pointer = '\0';
+ as_bad (_("bad .common segment %s"), p);
+ *input_line_pointer = c;
+ ignore_rest_of_line ();
+ return NULL;
+ }
+ /* ??? Don't ask me why these are always global. */
+ is_local = 0;
+ }
+ else
+ {
+ input_line_pointer = save;
+ align = parse_align (is_local);
+ if (align == (addressT) -1)
+ return NULL;
+ }
+ }
+
+ if (is_local)
+ {
+ bss_alloc (symbolP, size, align);
+ S_CLEAR_EXTERNAL (symbolP);
+ }
+ else
+ {
+ S_SET_VALUE (symbolP, size);
+ S_SET_ALIGN (symbolP, align);
+ S_SET_EXTERNAL (symbolP);
+ S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
+ }
+
+ symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
+
+ return symbolP;
+}
+
+void
+obj_elf_common (int is_common)
+{
+ if (flag_mri && is_common)
+ s_mri_common (0);
+ else
+ s_comm_internal (0, elf_common_parse);
+}
+
+static void
+obj_elf_tls_common (int ignore ATTRIBUTE_UNUSED)
+{
+ symbolS *symbolP = s_comm_internal (0, elf_common_parse);
+
+ if (symbolP)
+ symbol_get_bfdsym (symbolP)->flags |= BSF_THREAD_LOCAL;
+}
+
+static void
+obj_elf_lcomm (int ignore ATTRIBUTE_UNUSED)
+{
+ symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
+
+ if (symbolP)
+ symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
+}
+
+static void
+obj_elf_local (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+
+ do
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ S_CLEAR_EXTERNAL (symbolP);
+ symbol_get_obj (symbolP)->local = 1;
+ if (c == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\n')
+ c = '\n';
+ }
+ }
+ while (c == ',');
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_elf_weak (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+
+ do
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ S_SET_WEAK (symbolP);
+ symbol_get_obj (symbolP)->local = 1;
+ if (c == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\n')
+ c = '\n';
+ }
+ }
+ while (c == ',');
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_elf_visibility (int visibility)
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+ asymbol *bfdsym;
+ elf_symbol_type *elfsym;
+
+ do
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+
+ bfdsym = symbol_get_bfdsym (symbolP);
+ elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
+
+ assert (elfsym);
+
+ elfsym->internal_elf_sym.st_other &= ~3;
+ elfsym->internal_elf_sym.st_other |= visibility;
+
+ if (c == ',')
+ {
+ input_line_pointer ++;
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer == '\n')
+ c = '\n';
+ }
+ }
+ while (c == ',');
+
+ demand_empty_rest_of_line ();
+}
+
+static segT previous_section;
+static int previous_subsection;
+
+struct section_stack
+{
+ struct section_stack *next;
+ segT seg, prev_seg;
+ int subseg, prev_subseg;
+};
+
+static struct section_stack *section_stack;
+
+/* Handle the .section pseudo-op. This code supports two different
+ syntaxes.
+
+ The first is found on Solaris, and looks like
+ .section ".sec1",#alloc,#execinstr,#write
+ Here the names after '#' are the SHF_* flags to turn on for the
+ section. I'm not sure how it determines the SHT_* type (BFD
+ doesn't really give us control over the type, anyhow).
+
+ The second format is found on UnixWare, and probably most SVR4
+ machines, and looks like
+ .section .sec1,"a",@progbits
+ The quoted string may contain any combination of a, w, x, and
+ represents the SHF_* flags to turn on for the section. The string
+ beginning with '@' can be progbits or nobits. There should be
+ other possibilities, but I don't know what they are. In any case,
+ BFD doesn't really let us set the section type. */
+
+void
+obj_elf_change_section (const char *name,
+ int type,
+ int attr,
+ int entsize,
+ const char *group_name,
+ int linkonce,
+ int push)
+{
+ asection *old_sec;
+ segT sec;
+ flagword flags;
+ const struct bfd_elf_special_section *ssect;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ /* Switch to the section, creating it if necessary. */
+ if (push)
+ {
+ struct section_stack *elt;
+ elt = xmalloc (sizeof (struct section_stack));
+ elt->next = section_stack;
+ elt->seg = now_seg;
+ elt->prev_seg = previous_section;
+ elt->subseg = now_subseg;
+ elt->prev_subseg = previous_subsection;
+ section_stack = elt;
+ }
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+
+ old_sec = bfd_get_section_by_name (stdoutput, name);
+ sec = subseg_new (name, 0);
+ ssect = _bfd_elf_get_sec_type_attr (stdoutput, name);
+
+ if (ssect != NULL)
+ {
+ bfd_boolean override = FALSE;
+
+ if (type == SHT_NULL)
+ type = ssect->type;
+ else if (type != ssect->type)
+ {
+ if (old_sec == NULL
+ /* FIXME: gcc, as of 2002-10-22, will emit
+
+ .section .init_array,"aw",@progbits
+
+ for __attribute__ ((section (".init_array"))).
+ "@progbits" is incorrect. */
+ && ssect->type != SHT_INIT_ARRAY
+ && ssect->type != SHT_FINI_ARRAY
+ && ssect->type != SHT_PREINIT_ARRAY)
+ {
+ /* We allow to specify any type for a .note section. */
+ if (ssect->type != SHT_NOTE)
+ as_warn (_("setting incorrect section type for %s"),
+ name);
+ }
+ else
+ {
+ as_warn (_("ignoring incorrect section type for %s"),
+ name);
+ type = ssect->type;
+ }
+ }
+
+ if (old_sec == NULL && (attr & ~ssect->attr) != 0)
+ {
+ /* As a GNU extension, we permit a .note section to be
+ allocatable. If the linker sees an allocatable .note
+ section, it will create a PT_NOTE segment in the output
+ file. We also allow "x" for .note.GNU-stack. */
+ if (ssect->type == SHT_NOTE
+ && (attr == SHF_ALLOC || attr == SHF_EXECINSTR))
+ ;
+ /* Allow different SHF_MERGE and SHF_STRINGS if we have
+ something like .rodata.str. */
+ else if (ssect->suffix_length == -2
+ && name[ssect->prefix_length] == '.'
+ && (attr
+ & ~ssect->attr
+ & ~SHF_MERGE
+ & ~SHF_STRINGS) == 0)
+ ;
+ /* .interp, .strtab and .symtab can have SHF_ALLOC. */
+ else if (attr == SHF_ALLOC
+ && (strcmp (name, ".interp") == 0
+ || strcmp (name, ".strtab") == 0
+ || strcmp (name, ".symtab") == 0))
+ override = TRUE;
+ else
+ {
+ as_warn (_("setting incorrect section attributes for %s"),
+ name);
+ override = TRUE;
+ }
+ }
+ if (!override && old_sec == NULL)
+ attr |= ssect->attr;
+ }
+
+ if (type != SHT_NULL)
+ elf_section_type (sec) = type;
+ if (attr != 0)
+ elf_section_flags (sec) = attr;
+
+ /* Convert ELF type and flags to BFD flags. */
+ flags = (SEC_RELOC
+ | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
+ | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
+ | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
+ | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)
+ | ((attr & SHF_MERGE) ? SEC_MERGE : 0)
+ | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0)
+ | ((attr & SHF_TLS) ? SEC_THREAD_LOCAL : 0));
+#ifdef md_elf_section_flags
+ flags = md_elf_section_flags (flags, attr, type);
+#endif
+
+ if (old_sec == NULL)
+ {
+ symbolS *secsym;
+
+ /* Prevent SEC_HAS_CONTENTS from being inadvertently set. */
+ if (type == SHT_NOBITS)
+ seg_info (sec)->bss = 1;
+
+ if (linkonce)
+ flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
+ bfd_set_section_flags (stdoutput, sec, flags);
+ if (flags & SEC_MERGE)
+ sec->entsize = entsize;
+ elf_group_name (sec) = group_name;
+
+ /* Add a symbol for this section to the symbol table. */
+ secsym = symbol_find (name);
+ if (secsym != NULL)
+ symbol_set_bfdsym (secsym, sec->symbol);
+ else
+ symbol_table_insert (section_symbol (sec));
+ }
+ else if (attr != 0)
+ {
+ /* If section attributes are specified the second time we see a
+ particular section, then check that they are the same as we
+ saw the first time. */
+ if (((old_sec->flags ^ flags)
+ & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
+ | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
+ | SEC_THREAD_LOCAL)))
+ as_warn (_("ignoring changed section attributes for %s"), name);
+ if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
+ as_warn (_("ignoring changed section entity size for %s"), name);
+ if ((attr & SHF_GROUP) != 0
+ && strcmp (elf_group_name (old_sec), group_name) != 0)
+ as_warn (_("ignoring new section group for %s"), name);
+ }
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+}
+
+static int
+obj_elf_parse_section_letters (char *str, size_t len)
+{
+ int attr = 0;
+
+ while (len > 0)
+ {
+ switch (*str)
+ {
+ case 'a':
+ attr |= SHF_ALLOC;
+ break;
+ case 'w':
+ attr |= SHF_WRITE;
+ break;
+ case 'x':
+ attr |= SHF_EXECINSTR;
+ break;
+ case 'M':
+ attr |= SHF_MERGE;
+ break;
+ case 'S':
+ attr |= SHF_STRINGS;
+ break;
+ case 'G':
+ attr |= SHF_GROUP;
+ break;
+ case 'T':
+ attr |= SHF_TLS;
+ break;
+ /* Compatibility. */
+ case 'm':
+ if (*(str - 1) == 'a')
+ {
+ attr |= SHF_MERGE;
+ if (len > 1 && str[1] == 's')
+ {
+ attr |= SHF_STRINGS;
+ str++, len--;
+ }
+ break;
+ }
+ default:
+ {
+ char *bad_msg = _("unrecognized .section attribute: want a,w,x,M,S,G,T");
+#ifdef md_elf_section_letter
+ int md_attr = md_elf_section_letter (*str, &bad_msg);
+ if (md_attr >= 0)
+ attr |= md_attr;
+ else
+#endif
+ as_fatal ("%s", bad_msg);
+ }
+ break;
+ }
+ str++, len--;
+ }
+
+ return attr;
+}
+
+static int
+obj_elf_section_word (char *str, size_t len)
+{
+ if (len == 5 && strncmp (str, "write", 5) == 0)
+ return SHF_WRITE;
+ if (len == 5 && strncmp (str, "alloc", 5) == 0)
+ return SHF_ALLOC;
+ if (len == 9 && strncmp (str, "execinstr", 9) == 0)
+ return SHF_EXECINSTR;
+ if (len == 3 && strncmp (str, "tls", 3) == 0)
+ return SHF_TLS;
+
+#ifdef md_elf_section_word
+ {
+ int md_attr = md_elf_section_word (str, len);
+ if (md_attr >= 0)
+ return md_attr;
+ }
+#endif
+
+ as_warn (_("unrecognized section attribute"));
+ return 0;
+}
+
+static int
+obj_elf_section_type (char *str, size_t len)
+{
+ if (len == 8 && strncmp (str, "progbits", 8) == 0)
+ return SHT_PROGBITS;
+ if (len == 6 && strncmp (str, "nobits", 6) == 0)
+ return SHT_NOBITS;
+ if (len == 4 && strncmp (str, "note", 4) == 0)
+ return SHT_NOTE;
+
+#ifdef md_elf_section_type
+ {
+ int md_type = md_elf_section_type (str, len);
+ if (md_type >= 0)
+ return md_type;
+ }
+#endif
+
+ as_warn (_("unrecognized section type"));
+ return 0;
+}
+
+/* Get name of section. */
+static char *
+obj_elf_section_name (void)
+{
+ char *name;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '"')
+ {
+ int dummy;
+
+ name = demand_copy_C_string (&dummy);
+ if (name == NULL)
+ {
+ ignore_rest_of_line ();
+ return NULL;
+ }
+ }
+ else
+ {
+ char *end = input_line_pointer;
+
+ while (0 == strchr ("\n\t,; ", *end))
+ end++;
+ if (end == input_line_pointer)
+ {
+ as_bad (_("missing name"));
+ ignore_rest_of_line ();
+ return NULL;
+ }
+
+ name = xmalloc (end - input_line_pointer + 1);
+ memcpy (name, input_line_pointer, end - input_line_pointer);
+ name[end - input_line_pointer] = '\0';
+#ifdef tc_canonicalize_section_name
+ name = tc_canonicalize_section_name (name);
+#endif
+ input_line_pointer = end;
+ }
+ SKIP_WHITESPACE ();
+ return name;
+}
+
+void
+obj_elf_section (int push)
+{
+ char *name, *group_name, *beg;
+ int type, attr, dummy;
+ int entsize;
+ int linkonce;
+
+#ifndef TC_I370
+ if (flag_mri)
+ {
+ char mri_type;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+
+ s_mri_sect (&mri_type);
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+
+ return;
+ }
+#endif /* ! defined (TC_I370) */
+
+ name = obj_elf_section_name ();
+ if (name == NULL)
+ return;
+ type = SHT_NULL;
+ attr = 0;
+ group_name = NULL;
+ entsize = 0;
+ linkonce = 0;
+
+ if (*input_line_pointer == ',')
+ {
+ /* Skip the comma. */
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer == '"')
+ {
+ beg = demand_copy_C_string (&dummy);
+ if (beg == NULL)
+ {
+ ignore_rest_of_line ();
+ return;
+ }
+ attr |= obj_elf_parse_section_letters (beg, strlen (beg));
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ {
+ char c;
+ char *save = input_line_pointer;
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ c = *input_line_pointer;
+ if (c == '"')
+ {
+ beg = demand_copy_C_string (&dummy);
+ if (beg == NULL)
+ {
+ ignore_rest_of_line ();
+ return;
+ }
+ type = obj_elf_section_type (beg, strlen (beg));
+ }
+ else if (c == '@' || c == '%')
+ {
+ beg = ++input_line_pointer;
+ c = get_symbol_end ();
+ *input_line_pointer = c;
+ type = obj_elf_section_type (beg, input_line_pointer - beg);
+ }
+ else
+ input_line_pointer = save;
+ }
+
+ SKIP_WHITESPACE ();
+ if ((attr & SHF_MERGE) != 0 && *input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ entsize = get_absolute_expression ();
+ SKIP_WHITESPACE ();
+ if (entsize < 0)
+ {
+ as_warn (_("invalid merge entity size"));
+ attr &= ~SHF_MERGE;
+ entsize = 0;
+ }
+ }
+ else if ((attr & SHF_MERGE) != 0)
+ {
+ as_warn (_("entity size for SHF_MERGE not specified"));
+ attr &= ~SHF_MERGE;
+ }
+
+ if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ group_name = obj_elf_section_name ();
+ if (group_name == NULL)
+ attr &= ~SHF_GROUP;
+ else if (strncmp (input_line_pointer, ",comdat", 7) == 0)
+ {
+ input_line_pointer += 7;
+ linkonce = 1;
+ }
+ else if (strncmp (name, ".gnu.linkonce", 13) == 0)
+ linkonce = 1;
+ }
+ else if ((attr & SHF_GROUP) != 0)
+ {
+ as_warn (_("group name for SHF_GROUP not specified"));
+ attr &= ~SHF_GROUP;
+ }
+ }
+ else
+ {
+ do
+ {
+ char c;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '#')
+ {
+ as_bad (_("character following name is not '#'"));
+ ignore_rest_of_line ();
+ return;
+ }
+ beg = ++input_line_pointer;
+ c = get_symbol_end ();
+ *input_line_pointer = c;
+
+ attr |= obj_elf_section_word (beg, input_line_pointer - beg);
+
+ SKIP_WHITESPACE ();
+ }
+ while (*input_line_pointer++ == ',');
+ --input_line_pointer;
+ }
+ }
+
+ demand_empty_rest_of_line ();
+
+ obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push);
+}
+
+/* Change to the .data section. */
+
+void
+obj_elf_data (int i)
+{
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+ s_data (i);
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+}
+
+/* Change to the .text section. */
+
+void
+obj_elf_text (int i)
+{
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+ s_text (i);
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+}
+
+static void
+obj_elf_subsection (int ignore ATTRIBUTE_UNUSED)
+{
+ register int temp;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+
+ temp = get_absolute_expression ();
+ subseg_set (now_seg, (subsegT) temp);
+ demand_empty_rest_of_line ();
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+}
+
+/* This can be called from the processor backends if they change
+ sections. */
+
+void
+obj_elf_section_change_hook (void)
+{
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+}
+
+void
+obj_elf_previous (int ignore ATTRIBUTE_UNUSED)
+{
+ segT new_section;
+ int new_subsection;
+
+ if (previous_section == 0)
+ {
+ as_warn (_(".previous without corresponding .section; ignored"));
+ return;
+ }
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ new_section = previous_section;
+ new_subsection = previous_subsection;
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+ subseg_set (new_section, new_subsection);
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+}
+
+static void
+obj_elf_popsection (int xxx ATTRIBUTE_UNUSED)
+{
+ struct section_stack *top = section_stack;
+
+ if (top == NULL)
+ {
+ as_warn (_(".popsection without corresponding .pushsection; ignored"));
+ return;
+ }
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ section_stack = top->next;
+ previous_section = top->prev_seg;
+ previous_subsection = top->prev_subseg;
+ subseg_set (top->seg, top->subseg);
+ free (top);
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+}
+
+static void
+obj_elf_line (int ignore ATTRIBUTE_UNUSED)
+{
+ /* Assume delimiter is part of expression. BSD4.2 as fails with
+ delightful bug, so we are not being incompatible here. */
+ new_logical_line (NULL, get_absolute_expression ());
+ demand_empty_rest_of_line ();
+}
+
+/* This handles the .symver pseudo-op, which is used to specify a
+ symbol version. The syntax is ``.symver NAME,SYMVERNAME''.
+ SYMVERNAME may contain ELF_VER_CHR ('@') characters. This
+ pseudo-op causes the assembler to emit a symbol named SYMVERNAME
+ with the same value as the symbol NAME. */
+
+static void
+obj_elf_symver (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ char c;
+ char old_lexat;
+ symbolS *sym;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ sym = symbol_find_or_make (name);
+
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("expected comma after name in .symver"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+
+ /* Temporarily include '@' in symbol names. */
+ old_lexat = lex_type[(unsigned char) '@'];
+ lex_type[(unsigned char) '@'] |= LEX_NAME;
+ c = get_symbol_end ();
+ lex_type[(unsigned char) '@'] = old_lexat;
+
+ if (symbol_get_obj (sym)->versioned_name == NULL)
+ {
+ symbol_get_obj (sym)->versioned_name = xstrdup (name);
+
+ *input_line_pointer = c;
+
+ if (strchr (symbol_get_obj (sym)->versioned_name,
+ ELF_VER_CHR) == NULL)
+ {
+ as_bad (_("missing version name in `%s' for symbol `%s'"),
+ symbol_get_obj (sym)->versioned_name,
+ S_GET_NAME (sym));
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ else
+ {
+ if (strcmp (symbol_get_obj (sym)->versioned_name, name))
+ {
+ as_bad (_("multiple versions [`%s'|`%s'] for symbol `%s'"),
+ name, symbol_get_obj (sym)->versioned_name,
+ S_GET_NAME (sym));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ *input_line_pointer = c;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* This handles the .vtable_inherit pseudo-op, which is used to indicate
+ to the linker the hierarchy in which a particular table resides. The
+ syntax is ".vtable_inherit CHILDNAME, PARENTNAME". */
+
+struct fix *
+obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
+{
+ char *cname, *pname;
+ symbolS *csym, *psym;
+ char c, bad = 0;
+
+ if (*input_line_pointer == '#')
+ ++input_line_pointer;
+
+ cname = input_line_pointer;
+ c = get_symbol_end ();
+ csym = symbol_find (cname);
+
+ /* GCFIXME: should check that we don't have two .vtable_inherits for
+ the same child symbol. Also, we can currently only do this if the
+ child symbol is already exists and is placed in a fragment. */
+
+ if (csym == NULL || symbol_get_frag (csym) == NULL)
+ {
+ as_bad ("expected `%s' to have already been set for .vtable_inherit",
+ cname);
+ bad = 1;
+ }
+
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("expected comma after name in .vtable_inherit");
+ ignore_rest_of_line ();
+ return NULL;
+ }
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer == '#')
+ ++input_line_pointer;
+
+ if (input_line_pointer[0] == '0'
+ && (input_line_pointer[1] == '\0'
+ || ISSPACE (input_line_pointer[1])))
+ {
+ psym = section_symbol (absolute_section);
+ ++input_line_pointer;
+ }
+ else
+ {
+ pname = input_line_pointer;
+ c = get_symbol_end ();
+ psym = symbol_find_or_make (pname);
+ *input_line_pointer = c;
+ }
+
+ demand_empty_rest_of_line ();
+
+ if (bad)
+ return NULL;
+
+ assert (symbol_get_value_expression (csym)->X_op == O_constant);
+ return fix_new (symbol_get_frag (csym),
+ symbol_get_value_expression (csym)->X_add_number,
+ 0, psym, 0, 0, BFD_RELOC_VTABLE_INHERIT);
+}
+
+/* This handles the .vtable_entry pseudo-op, which is used to indicate
+ to the linker that a vtable slot was used. The syntax is
+ ".vtable_entry tablename, offset". */
+
+struct fix *
+obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ symbolS *sym;
+ offsetT offset;
+ char c;
+
+ if (*input_line_pointer == '#')
+ ++input_line_pointer;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ sym = symbol_find_or_make (name);
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("expected comma after name in .vtable_entry");
+ ignore_rest_of_line ();
+ return NULL;
+ }
+
+ ++input_line_pointer;
+ if (*input_line_pointer == '#')
+ ++input_line_pointer;
+
+ offset = get_absolute_expression ();
+
+ demand_empty_rest_of_line ();
+
+ return fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0,
+ BFD_RELOC_VTABLE_ENTRY);
+}
+
+void
+elf_obj_read_begin_hook (void)
+{
+#ifdef NEED_ECOFF_DEBUG
+ if (ECOFF_DEBUGGING)
+ ecoff_read_begin_hook ();
+#endif
+}
+
+void
+elf_obj_symbol_new_hook (symbolS *symbolP)
+{
+ struct elf_obj_sy *sy_obj;
+
+ sy_obj = symbol_get_obj (symbolP);
+ sy_obj->size = NULL;
+ sy_obj->versioned_name = NULL;
+
+#ifdef NEED_ECOFF_DEBUG
+ if (ECOFF_DEBUGGING)
+ ecoff_symbol_new_hook (symbolP);
+#endif
+}
+
+/* When setting one symbol equal to another, by default we probably
+ want them to have the same "size", whatever it means in the current
+ context. */
+
+void
+elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
+{
+ struct elf_obj_sy *srcelf = symbol_get_obj (src);
+ struct elf_obj_sy *destelf = symbol_get_obj (dest);
+ if (srcelf->size)
+ {
+ if (destelf->size == NULL)
+ destelf->size = xmalloc (sizeof (expressionS));
+ *destelf->size = *srcelf->size;
+ }
+ else
+ {
+ if (destelf->size != NULL)
+ free (destelf->size);
+ destelf->size = NULL;
+ }
+ S_SET_SIZE (dest, S_GET_SIZE (src));
+ /* Don't copy visibility. */
+ S_SET_OTHER (dest, (ELF_ST_VISIBILITY (S_GET_OTHER (dest))
+ | (S_GET_OTHER (src) & ~ELF_ST_VISIBILITY (-1))));
+}
+
+void
+obj_elf_version (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ unsigned int c;
+ char *p;
+ asection *seg = now_seg;
+ subsegT subseg = now_subseg;
+ Elf_Internal_Note i_note;
+ Elf_External_Note e_note;
+ asection *note_secp = NULL;
+ int len;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\"')
+ {
+ ++input_line_pointer; /* -> 1st char of string. */
+ name = input_line_pointer;
+
+ while (is_a_char (c = next_char_of_string ()))
+ ;
+ c = *input_line_pointer;
+ *input_line_pointer = '\0';
+ *(input_line_pointer - 1) = '\0';
+ *input_line_pointer = c;
+
+ /* create the .note section */
+
+ note_secp = subseg_new (".note", 0);
+ bfd_set_section_flags (stdoutput,
+ note_secp,
+ SEC_HAS_CONTENTS | SEC_READONLY);
+
+ /* process the version string */
+
+ len = strlen (name);
+
+ i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
+ i_note.descsz = 0; /* no description */
+ i_note.type = NT_VERSION;
+ p = frag_more (sizeof (e_note.namesz));
+ md_number_to_chars (p, i_note.namesz, sizeof (e_note.namesz));
+ p = frag_more (sizeof (e_note.descsz));
+ md_number_to_chars (p, i_note.descsz, sizeof (e_note.descsz));
+ p = frag_more (sizeof (e_note.type));
+ md_number_to_chars (p, i_note.type, sizeof (e_note.type));
+ p = frag_more (len + 1);
+ strcpy (p, name);
+
+ frag_align (2, 0, 0);
+
+ subseg_set (seg, subseg);
+ }
+ else
+ {
+ as_bad (_("expected quoted string"));
+ }
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_elf_size (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name = input_line_pointer;
+ char c = get_symbol_end ();
+ char *p;
+ expressionS exp;
+ symbolS *sym;
+
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ *p = 0;
+ as_bad (_("expected comma after name `%s' in .size directive"), name);
+ *p = c;
+ ignore_rest_of_line ();
+ return;
+ }
+ input_line_pointer++;
+ expression (&exp);
+ if (exp.X_op == O_absent)
+ {
+ as_bad (_("missing expression in .size directive"));
+ exp.X_op = O_constant;
+ exp.X_add_number = 0;
+ }
+ *p = 0;
+ sym = symbol_find_or_make (name);
+ *p = c;
+ if (exp.X_op == O_constant)
+ {
+ S_SET_SIZE (sym, exp.X_add_number);
+ if (symbol_get_obj (sym)->size)
+ {
+ xfree (symbol_get_obj (sym)->size);
+ symbol_get_obj (sym)->size = NULL;
+ }
+ }
+ else
+ {
+ symbol_get_obj (sym)->size = xmalloc (sizeof (expressionS));
+ *symbol_get_obj (sym)->size = exp;
+ }
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the ELF .type pseudo-op. This sets the type of a symbol.
+ There are five syntaxes:
+
+ The first (used on Solaris) is
+ .type SYM,#function
+ The second (used on UnixWare) is
+ .type SYM,@function
+ The third (reportedly to be used on Irix 6.0) is
+ .type SYM STT_FUNC
+ The fourth (used on NetBSD/Arm and Linux/ARM) is
+ .type SYM,%function
+ The fifth (used on SVR4/860) is
+ .type SYM,"function"
+ */
+
+static void
+obj_elf_type (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ char c;
+ int type;
+ const char *typename;
+ symbolS *sym;
+ elf_symbol_type *elfsym;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ sym = symbol_find_or_make (name);
+ elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym);
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ ++input_line_pointer;
+
+ SKIP_WHITESPACE ();
+ if ( *input_line_pointer == '#'
+ || *input_line_pointer == '@'
+ || *input_line_pointer == '"'
+ || *input_line_pointer == '%')
+ ++input_line_pointer;
+
+ typename = input_line_pointer;
+ c = get_symbol_end ();
+
+ type = 0;
+ if (strcmp (typename, "function") == 0
+ || strcmp (typename, "STT_FUNC") == 0)
+ type = BSF_FUNCTION;
+ else if (strcmp (typename, "object") == 0
+ || strcmp (typename, "STT_OBJECT") == 0)
+ type = BSF_OBJECT;
+ else if (strcmp (typename, "tls_object") == 0
+ || strcmp (typename, "STT_TLS") == 0)
+ type = BSF_OBJECT | BSF_THREAD_LOCAL;
+ else if (strcmp (typename, "notype") == 0
+ || strcmp (typename, "STT_NOTYPE") == 0)
+ ;
+#ifdef md_elf_symbol_type
+ else if ((type = md_elf_symbol_type (typename, sym, elfsym)) != -1)
+ ;
+#endif
+ else
+ as_bad (_("unrecognized symbol type \"%s\""), typename);
+
+ *input_line_pointer = c;
+
+ if (*input_line_pointer == '"')
+ ++input_line_pointer;
+
+ elfsym->symbol.flags |= type;
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
+{
+ static segT comment_section;
+ segT old_section = now_seg;
+ int old_subsection = now_subseg;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ if (!comment_section)
+ {
+ char *p;
+ comment_section = subseg_new (".comment", 0);
+ bfd_set_section_flags (stdoutput, comment_section,
+ SEC_READONLY | SEC_HAS_CONTENTS);
+ p = frag_more (1);
+ *p = 0;
+ }
+ else
+ subseg_set (comment_section, 0);
+ stringer (1);
+ subseg_set (old_section, old_subsection);
+}
+
+#ifdef INIT_STAB_SECTION
+
+/* The first entry in a .stabs section is special. */
+
+void
+obj_elf_init_stab_section (segT seg)
+{
+ char *file;
+ char *p;
+ char *stabstr_name;
+ unsigned int stroff;
+
+ /* Force the section to align to a longword boundary. Without this,
+ UnixWare ar crashes. */
+ bfd_set_section_alignment (stdoutput, seg, 2);
+
+ /* Make space for this first symbol. */
+ p = frag_more (12);
+ /* Zero it out. */
+ memset (p, 0, 12);
+ as_where (&file, NULL);
+ stabstr_name = xmalloc (strlen (segment_name (seg)) + 4);
+ strcpy (stabstr_name, segment_name (seg));
+ strcat (stabstr_name, "str");
+ stroff = get_stab_string_offset (file, stabstr_name);
+ know (stroff == 1);
+ md_number_to_chars (p, stroff, 4);
+ seg_info (seg)->stabu.p = p;
+}
+
+#endif
+
+/* Fill in the counts in the first entry in a .stabs section. */
+
+static void
+adjust_stab_sections (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
+{
+ char *name;
+ asection *strsec;
+ char *p;
+ int strsz, nsyms;
+
+ if (strncmp (".stab", sec->name, 5))
+ return;
+ if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
+ return;
+
+ name = alloca (strlen (sec->name) + 4);
+ strcpy (name, sec->name);
+ strcat (name, "str");
+ strsec = bfd_get_section_by_name (abfd, name);
+ if (strsec)
+ strsz = bfd_section_size (abfd, strsec);
+ else
+ strsz = 0;
+ nsyms = bfd_section_size (abfd, sec) / 12 - 1;
+
+ p = seg_info (sec)->stabu.p;
+ assert (p != 0);
+
+ bfd_h_put_16 (abfd, nsyms, p + 6);
+ bfd_h_put_32 (abfd, strsz, p + 8);
+}
+
+#ifdef NEED_ECOFF_DEBUG
+
+/* This function is called by the ECOFF code. It is supposed to
+ record the external symbol information so that the backend can
+ write it out correctly. The ELF backend doesn't actually handle
+ this at the moment, so we do it ourselves. We save the information
+ in the symbol. */
+
+void
+elf_ecoff_set_ext (symbolS *sym, struct ecoff_extr *ext)
+{
+ symbol_get_bfdsym (sym)->udata.p = ext;
+}
+
+/* This function is called by bfd_ecoff_debug_externals. It is
+ supposed to *EXT to the external symbol information, and return
+ whether the symbol should be used at all. */
+
+static bfd_boolean
+elf_get_extr (asymbol *sym, EXTR *ext)
+{
+ if (sym->udata.p == NULL)
+ return FALSE;
+ *ext = *(EXTR *) sym->udata.p;
+ return TRUE;
+}
+
+/* This function is called by bfd_ecoff_debug_externals. It has
+ nothing to do for ELF. */
+
+static void
+elf_set_index (asymbol *sym ATTRIBUTE_UNUSED,
+ bfd_size_type indx ATTRIBUTE_UNUSED)
+{
+}
+
+#endif /* NEED_ECOFF_DEBUG */
+
+void
+elf_frob_symbol (symbolS *symp, int *puntp)
+{
+ struct elf_obj_sy *sy_obj;
+
+#ifdef NEED_ECOFF_DEBUG
+ if (ECOFF_DEBUGGING)
+ ecoff_frob_symbol (symp);
+#endif
+
+ sy_obj = symbol_get_obj (symp);
+
+ if (sy_obj->size != NULL)
+ {
+ switch (sy_obj->size->X_op)
+ {
+ case O_subtract:
+ S_SET_SIZE (symp,
+ (S_GET_VALUE (sy_obj->size->X_add_symbol)
+ + sy_obj->size->X_add_number
+ - S_GET_VALUE (sy_obj->size->X_op_symbol)));
+ break;
+ case O_constant:
+ S_SET_SIZE (symp,
+ (S_GET_VALUE (sy_obj->size->X_add_symbol)
+ + sy_obj->size->X_add_number));
+ break;
+ default:
+ as_bad (_(".size expression too complicated to fix up"));
+ break;
+ }
+ free (sy_obj->size);
+ sy_obj->size = NULL;
+ }
+
+ if (sy_obj->versioned_name != NULL)
+ {
+ char *p;
+
+ p = strchr (sy_obj->versioned_name, ELF_VER_CHR);
+ know (p != NULL);
+
+ /* This symbol was given a new name with the .symver directive.
+
+ If this is an external reference, just rename the symbol to
+ include the version string. This will make the relocs be
+ against the correct versioned symbol.
+
+ If this is a definition, add an alias. FIXME: Using an alias
+ will permit the debugging information to refer to the right
+ symbol. However, it's not clear whether it is the best
+ approach. */
+
+ if (! S_IS_DEFINED (symp))
+ {
+ /* Verify that the name isn't using the @@ syntax--this is
+ reserved for definitions of the default version to link
+ against. */
+ if (p[1] == ELF_VER_CHR)
+ {
+ as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"),
+ sy_obj->versioned_name);
+ *puntp = TRUE;
+ }
+ S_SET_NAME (symp, sy_obj->versioned_name);
+ }
+ else
+ {
+ if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
+ {
+ size_t l;
+
+ /* The @@@ syntax is a special case. It renames the
+ symbol name to versioned_name with one `@' removed. */
+ l = strlen (&p[3]) + 1;
+ memmove (&p[2], &p[3], l);
+ S_SET_NAME (symp, sy_obj->versioned_name);
+ }
+ else
+ {
+ symbolS *symp2;
+
+ /* FIXME: Creating a new symbol here is risky. We're
+ in the final loop over the symbol table. We can
+ get away with it only because the symbol goes to
+ the end of the list, where the loop will still see
+ it. It would probably be better to do this in
+ obj_frob_file_before_adjust. */
+
+ symp2 = symbol_find_or_make (sy_obj->versioned_name);
+
+ /* Now we act as though we saw symp2 = sym. */
+
+ S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
+
+ /* Subtracting out the frag address here is a hack
+ because we are in the middle of the final loop. */
+ S_SET_VALUE (symp2,
+ (S_GET_VALUE (symp)
+ - symbol_get_frag (symp)->fr_address));
+
+ symbol_set_frag (symp2, symbol_get_frag (symp));
+
+ /* This will copy over the size information. */
+ copy_symbol_attributes (symp2, symp);
+
+ S_SET_OTHER (symp2, S_GET_OTHER (symp));
+
+ if (S_IS_WEAK (symp))
+ S_SET_WEAK (symp2);
+
+ if (S_IS_EXTERNAL (symp))
+ S_SET_EXTERNAL (symp2);
+ }
+ }
+ }
+
+ /* Double check weak symbols. */
+ if (S_IS_WEAK (symp))
+ {
+ if (S_IS_COMMON (symp))
+ as_bad (_("symbol `%s' can not be both weak and common"),
+ S_GET_NAME (symp));
+ }
+
+#ifdef TC_MIPS
+ /* The Irix 5 and 6 assemblers set the type of any common symbol and
+ any undefined non-function symbol to STT_OBJECT. We try to be
+ compatible, since newer Irix 5 and 6 linkers care. However, we
+ only set undefined symbols to be STT_OBJECT if we are on Irix,
+ because that is the only time gcc will generate the necessary
+ .global directives to mark functions. */
+
+ if (S_IS_COMMON (symp))
+ symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
+
+ if (strstr (TARGET_OS, "irix") != NULL
+ && ! S_IS_DEFINED (symp)
+ && (symbol_get_bfdsym (symp)->flags & BSF_FUNCTION) == 0)
+ symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
+#endif
+
+#if 0 /* TC_PPC */
+ /* If TC_PPC is defined, we used to force the type of a symbol to be
+ BSF_OBJECT if it was otherwise unset. This was required by some
+ version of VxWorks. Thomas de Lellis <tdel@windriver.com> says
+ that this is no longer needed, so it is now commented out. */
+ if ((symbol_get_bfdsym (symp)->flags
+ & (BSF_FUNCTION | BSF_FILE | BSF_SECTION_SYM)) == 0
+ && S_IS_DEFINED (symp))
+ symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
+#endif
+}
+
+struct group_list
+{
+ asection **head; /* Section lists. */
+ unsigned int *elt_count; /* Number of sections in each list. */
+ unsigned int num_group; /* Number of lists. */
+};
+
+/* Called via bfd_map_over_sections. If SEC is a member of a group,
+ add it to a list of sections belonging to the group. INF is a
+ pointer to a struct group_list, which is where we store the head of
+ each list. */
+
+static void
+build_group_lists (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
+{
+ struct group_list *list = inf;
+ const char *group_name = elf_group_name (sec);
+ unsigned int i;
+
+ if (group_name == NULL)
+ return;
+
+ /* If this group already has a list, add the section to the head of
+ the list. */
+ for (i = 0; i < list->num_group; i++)
+ {
+ if (strcmp (group_name, elf_group_name (list->head[i])) == 0)
+ {
+ elf_next_in_group (sec) = list->head[i];
+ list->head[i] = sec;
+ list->elt_count[i] += 1;
+ return;
+ }
+ }
+
+ /* New group. Make the arrays bigger in chunks to minimize calls to
+ realloc. */
+ i = list->num_group;
+ if ((i & 127) == 0)
+ {
+ unsigned int newsize = i + 128;
+ list->head = xrealloc (list->head, newsize * sizeof (*list->head));
+ list->elt_count = xrealloc (list->elt_count,
+ newsize * sizeof (*list->elt_count));
+ }
+ list->head[i] = sec;
+ list->elt_count[i] = 1;
+ list->num_group += 1;
+}
+
+void
+elf_frob_file (void)
+{
+ struct group_list list;
+ unsigned int i;
+
+ bfd_map_over_sections (stdoutput, adjust_stab_sections, NULL);
+
+ /* Go find section groups. */
+ list.num_group = 0;
+ list.head = NULL;
+ list.elt_count = NULL;
+ bfd_map_over_sections (stdoutput, build_group_lists, &list);
+
+ /* Make the SHT_GROUP sections that describe each section group. We
+ can't set up the section contents here yet, because elf section
+ indices have yet to be calculated. elf.c:set_group_contents does
+ the rest of the work. */
+ for (i = 0; i < list.num_group; i++)
+ {
+ const char *group_name = elf_group_name (list.head[i]);
+ const char *sec_name;
+ asection *s;
+ flagword flags;
+ struct symbol *sy;
+ int has_sym;
+
+ flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP;
+ for (s = list.head[i]; s != NULL; s = elf_next_in_group (s))
+ if ((s->flags ^ flags) & SEC_LINK_ONCE)
+ {
+ flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
+ if (s != list.head[i])
+ {
+ as_warn (_("assuming all members of group `%s' are COMDAT"),
+ group_name);
+ break;
+ }
+ }
+
+ sec_name = group_name;
+ sy = symbol_find_exact (group_name);
+ has_sym = 0;
+ if (sy != NULL
+ && (sy == symbol_lastP
+ || (sy->sy_next != NULL
+ && sy->sy_next->sy_previous == sy)))
+ {
+ has_sym = 1;
+ sec_name = ".group";
+ }
+ s = subseg_force_new (sec_name, 0);
+ if (s == NULL
+ || !bfd_set_section_flags (stdoutput, s, flags)
+ || !bfd_set_section_alignment (stdoutput, s, 2))
+ {
+ as_fatal (_("can't create group: %s"),
+ bfd_errmsg (bfd_get_error ()));
+ }
+ elf_section_type (s) = SHT_GROUP;
+
+ /* Pass a pointer to the first section in this group. */
+ elf_next_in_group (s) = list.head[i];
+ if (has_sym)
+ elf_group_id (s) = sy->bsym;
+
+ s->_raw_size = 4 * (list.elt_count[i] + 1);
+ s->contents = frag_more (s->_raw_size);
+ frag_now->fr_fix = frag_now_fix_octets ();
+ }
+
+#ifdef elf_tc_final_processing
+ elf_tc_final_processing ();
+#endif
+}
+
+/* It removes any unneeded versioned symbols from the symbol table. */
+
+void
+elf_frob_file_before_adjust (void)
+{
+ if (symbol_rootP)
+ {
+ symbolS *symp;
+
+ for (symp = symbol_rootP; symp; symp = symbol_next (symp))
+ if (!S_IS_DEFINED (symp))
+ {
+ if (symbol_get_obj (symp)->versioned_name)
+ {
+ char *p;
+
+ /* The @@@ syntax is a special case. If the symbol is
+ not defined, 2 `@'s will be removed from the
+ versioned_name. */
+
+ p = strchr (symbol_get_obj (symp)->versioned_name,
+ ELF_VER_CHR);
+ know (p != NULL);
+ if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
+ {
+ size_t l = strlen (&p[3]) + 1;
+ memmove (&p[1], &p[3], l);
+ }
+ if (symbol_used_p (symp) == 0
+ && symbol_used_in_reloc_p (symp) == 0)
+ symbol_remove (symp, &symbol_rootP, &symbol_lastP);
+ }
+
+ /* If there was .weak foo, but foo was neither defined nor
+ used anywhere, remove it. */
+
+ else if (S_IS_WEAK (symp)
+ && symbol_used_p (symp) == 0
+ && symbol_used_in_reloc_p (symp) == 0)
+ symbol_remove (symp, &symbol_rootP, &symbol_lastP);
+ }
+ }
+}
+
+/* It is required that we let write_relocs have the opportunity to
+ optimize away fixups before output has begun, since it is possible
+ to eliminate all fixups for a section and thus we never should
+ have generated the relocation section. */
+
+void
+elf_frob_file_after_relocs (void)
+{
+#ifdef NEED_ECOFF_DEBUG
+ if (ECOFF_DEBUGGING)
+ /* Generate the ECOFF debugging information. */
+ {
+ const struct ecoff_debug_swap *debug_swap;
+ struct ecoff_debug_info debug;
+ char *buf;
+ asection *sec;
+
+ debug_swap
+ = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
+ know (debug_swap != NULL);
+ ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
+
+ /* Set up the pointers in debug. */
+#define SET(ptr, offset, type) \
+ debug.ptr = (type) (buf + debug.symbolic_header.offset)
+
+ SET (line, cbLineOffset, unsigned char *);
+ SET (external_dnr, cbDnOffset, void *);
+ SET (external_pdr, cbPdOffset, void *);
+ SET (external_sym, cbSymOffset, void *);
+ SET (external_opt, cbOptOffset, void *);
+ SET (external_aux, cbAuxOffset, union aux_ext *);
+ SET (ss, cbSsOffset, char *);
+ SET (external_fdr, cbFdOffset, void *);
+ SET (external_rfd, cbRfdOffset, void *);
+ /* ssext and external_ext are set up just below. */
+
+#undef SET
+
+ /* Set up the external symbols. */
+ debug.ssext = debug.ssext_end = NULL;
+ debug.external_ext = debug.external_ext_end = NULL;
+ if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, TRUE,
+ elf_get_extr, elf_set_index))
+ as_fatal (_("failed to set up debugging information: %s"),
+ bfd_errmsg (bfd_get_error ()));
+
+ sec = bfd_get_section_by_name (stdoutput, ".mdebug");
+ assert (sec != NULL);
+
+ know (!stdoutput->output_has_begun);
+
+ /* We set the size of the section, call bfd_set_section_contents
+ to force the ELF backend to allocate a file position, and then
+ write out the data. FIXME: Is this really the best way to do
+ this? */
+ sec->_raw_size = bfd_ecoff_debug_size (stdoutput, &debug, debug_swap);
+
+ /* Pass BUF to bfd_set_section_contents because this will
+ eventually become a call to fwrite, and ISO C prohibits
+ passing a NULL pointer to a stdio function even if the
+ pointer will not be used. */
+ if (! bfd_set_section_contents (stdoutput, sec, buf, 0, 0))
+ as_fatal (_("can't start writing .mdebug section: %s"),
+ bfd_errmsg (bfd_get_error ()));
+
+ know (stdoutput->output_has_begun);
+ know (sec->filepos != 0);
+
+ if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
+ sec->filepos))
+ as_fatal (_("could not write .mdebug section: %s"),
+ bfd_errmsg (bfd_get_error ()));
+ }
+#endif /* NEED_ECOFF_DEBUG */
+}
+
+#ifdef SCO_ELF
+
+/* Heavily plagiarized from obj_elf_version. The idea is to emit the
+ SCO specific identifier in the .notes section to satisfy the SCO
+ linker.
+
+ This looks more complicated than it really is. As opposed to the
+ "obvious" solution, this should handle the cross dev cases
+ correctly. (i.e, hosting on a 64 bit big endian processor, but
+ generating SCO Elf code) Efficiency isn't a concern, as there
+ should be exactly one of these sections per object module.
+
+ SCO OpenServer 5 identifies it's ELF modules with a standard ELF
+ .note section.
+
+ int_32 namesz = 4 ; Name size
+ int_32 descsz = 12 ; Descriptive information
+ int_32 type = 1 ;
+ char name[4] = "SCO" ; Originator name ALWAYS SCO + NULL
+ int_32 version = (major ver # << 16) | version of tools ;
+ int_32 source = (tool_id << 16 ) | 1 ;
+ int_32 info = 0 ; These are set by the SCO tools, but we
+ don't know enough about the source
+ environment to set them. SCO ld currently
+ ignores them, and recommends we set them
+ to zero. */
+
+#define SCO_MAJOR_VERSION 0x1
+#define SCO_MINOR_VERSION 0x1
+
+void
+sco_id (void)
+{
+
+ char *name;
+ unsigned int c;
+ char ch;
+ char *p;
+ asection *seg = now_seg;
+ subsegT subseg = now_subseg;
+ Elf_Internal_Note i_note;
+ Elf_External_Note e_note;
+ asection *note_secp = NULL;
+ int i, len;
+
+ /* create the .note section */
+
+ note_secp = subseg_new (".note", 0);
+ bfd_set_section_flags (stdoutput,
+ note_secp,
+ SEC_HAS_CONTENTS | SEC_READONLY);
+
+ /* process the version string */
+
+ i_note.namesz = 4;
+ i_note.descsz = 12; /* 12 descriptive bytes */
+ i_note.type = NT_VERSION; /* Contains a version string */
+
+ p = frag_more (sizeof (i_note.namesz));
+ md_number_to_chars (p, i_note.namesz, 4);
+
+ p = frag_more (sizeof (i_note.descsz));
+ md_number_to_chars (p, i_note.descsz, 4);
+
+ p = frag_more (sizeof (i_note.type));
+ md_number_to_chars (p, i_note.type, 4);
+
+ p = frag_more (4);
+ strcpy (p, "SCO");
+
+ /* Note: this is the version number of the ELF we're representing */
+ p = frag_more (4);
+ md_number_to_chars (p, (SCO_MAJOR_VERSION << 16) | (SCO_MINOR_VERSION), 4);
+
+ /* Here, we pick a magic number for ourselves (yes, I "registered"
+ it with SCO. The bottom bit shows that we are compat with the
+ SCO ABI. */
+ p = frag_more (4);
+ md_number_to_chars (p, 0x4c520000 | 0x0001, 4);
+
+ /* If we knew (or cared) what the source language options were, we'd
+ fill them in here. SCO has given us permission to ignore these
+ and just set them to zero. */
+ p = frag_more (4);
+ md_number_to_chars (p, 0x0000, 4);
+
+ frag_align (2, 0, 0);
+
+ /* We probably can't restore the current segment, for there likely
+ isn't one yet... */
+ if (seg && subseg)
+ subseg_set (seg, subseg);
+
+}
+
+#endif /* SCO_ELF */
+
+static int
+elf_separate_stab_sections (void)
+{
+#ifdef NEED_ECOFF_DEBUG
+ return (!ECOFF_DEBUGGING);
+#else
+ return 1;
+#endif
+}
+
+static void
+elf_init_stab_section (segT seg)
+{
+#ifdef NEED_ECOFF_DEBUG
+ if (!ECOFF_DEBUGGING)
+#endif
+ obj_elf_init_stab_section (seg);
+}
+
+const struct format_ops elf_format_ops =
+{
+ bfd_target_elf_flavour,
+ 0, /* dfl_leading_underscore */
+ 1, /* emit_section_symbols */
+ elf_begin,
+ elf_file_symbol,
+ elf_frob_symbol,
+ elf_frob_file,
+ elf_frob_file_before_adjust,
+ 0, /* obj_frob_file_before_fix */
+ elf_frob_file_after_relocs,
+ elf_s_get_size, elf_s_set_size,
+ elf_s_get_align, elf_s_set_align,
+ elf_s_get_other,
+ elf_s_set_other,
+ 0, /* s_get_desc */
+ 0, /* s_set_desc */
+ 0, /* s_get_type */
+ 0, /* s_set_type */
+ elf_copy_symbol_attributes,
+#ifdef NEED_ECOFF_DEBUG
+ ecoff_generate_asm_lineno,
+ ecoff_stab,
+#else
+ 0, /* generate_asm_lineno */
+ 0, /* process_stab */
+#endif
+ elf_separate_stab_sections,
+ elf_init_stab_section,
+ elf_sec_sym_ok_for_reloc,
+ elf_pop_insert,
+#ifdef NEED_ECOFF_DEBUG
+ elf_ecoff_set_ext,
+#else
+ 0, /* ecoff_set_ext */
+#endif
+ elf_obj_read_begin_hook,
+ elf_obj_symbol_new_hook
+};
diff --git a/x/binutils/gas/config/obj-elf.h b/x/binutils/gas/config/obj-elf.h
new file mode 100644
index 0000000..e713797
--- /dev/null
+++ b/x/binutils/gas/config/obj-elf.h
@@ -0,0 +1,250 @@
+/* ELF object file format.
+ Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* HP PA-RISC support was contributed by the Center for Software Science
+ at the University of Utah. */
+
+#ifndef _OBJ_ELF_H
+#define _OBJ_ELF_H
+
+#define OBJ_ELF 1
+
+/* Note that all macros in this file should be wrapped in #ifndef, for
+ sake of obj-multi.h which includes this file. */
+
+#ifndef OUTPUT_FLAVOR
+#define OUTPUT_FLAVOR bfd_target_elf_flavour
+#endif
+
+#include "bfd.h"
+
+#define BYTES_IN_WORD 4 /* for now */
+#include "bfd/elf-bfd.h"
+
+#include "targ-cpu.h"
+
+#ifdef TC_ALPHA
+#define ECOFF_DEBUGGING (alpha_flag_mdebug > 0)
+extern int alpha_flag_mdebug;
+#endif
+
+/* For now, always set ECOFF_DEBUGGING for a MIPS target. */
+#ifdef TC_MIPS
+#define ECOFF_DEBUGGING mips_flag_mdebug
+extern int mips_flag_mdebug;
+#endif /* TC_MIPS */
+
+#ifdef OBJ_MAYBE_ECOFF
+#ifndef ECOFF_DEBUGGING
+#define ECOFF_DEBUGGING 1
+#endif
+#endif
+
+/* Additional information we keep for each symbol. */
+struct elf_obj_sy
+{
+ /* Whether the symbol has been marked as local. */
+ int local;
+
+ /* Use this to keep track of .size expressions that involve
+ differences that we can't compute yet. */
+ expressionS *size;
+
+ /* The name specified by the .symver directive. */
+ char *versioned_name;
+
+#ifdef ECOFF_DEBUGGING
+ /* If we are generating ECOFF debugging information, we need some
+ additional fields for each symbol. */
+ struct efdr *ecoff_file;
+ struct localsym *ecoff_symbol;
+ valueT ecoff_extern_size;
+#endif
+};
+
+#define OBJ_SYMFIELD_TYPE struct elf_obj_sy
+
+/* Symbol fields used by the ELF back end. */
+#define ELF_TARGET_SYMBOL_FIELDS int local:1;
+
+/* Don't change this; change ELF_TARGET_SYMBOL_FIELDS instead. */
+#ifndef TARGET_SYMBOL_FIELDS
+#define TARGET_SYMBOL_FIELDS ELF_TARGET_SYMBOL_FIELDS
+#endif
+
+/* #include "targ-cpu.h" */
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE !FALSE
+#endif
+
+#ifndef obj_begin
+#define obj_begin() elf_begin ()
+#endif
+extern void elf_begin (void);
+
+/* should be conditional on address size! */
+#define elf_symbol(asymbol) ((elf_symbol_type *) (&(asymbol)->the_bfd))
+
+#ifndef S_GET_SIZE
+#define S_GET_SIZE(S) \
+ (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_size)
+#endif
+#ifndef S_SET_SIZE
+#define S_SET_SIZE(S,V) \
+ (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_size = (V))
+#endif
+
+#ifndef S_GET_ALIGN
+#define S_GET_ALIGN(S) \
+ (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_value)
+#endif
+#ifndef S_SET_ALIGN
+#define S_SET_ALIGN(S,V) \
+ (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_value = (V))
+#endif
+
+int elf_s_get_other (symbolS *);
+#ifndef S_GET_OTHER
+#define S_GET_OTHER(S) (elf_s_get_other (S))
+#endif
+#ifndef S_SET_OTHER
+#define S_SET_OTHER(S,V) \
+ (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_other = (V))
+#endif
+
+extern asection *gdb_section;
+
+#ifndef obj_sec_set_private_data
+#define obj_sec_set_private_data(B, S) \
+ if (! BFD_SEND ((B), _new_section_hook, ((B), (S)))) \
+ as_fatal (_("can't allocate ELF private section data: %s"), \
+ bfd_errmsg (bfd_get_error ()))
+#endif
+
+#ifndef obj_frob_file
+#define obj_frob_file elf_frob_file
+#endif
+extern void elf_frob_file (void);
+
+#ifndef obj_frob_file_before_adjust
+#define obj_frob_file_before_adjust elf_frob_file_before_adjust
+#endif
+extern void elf_frob_file_before_adjust (void);
+
+#ifndef obj_frob_file_after_relocs
+#define obj_frob_file_after_relocs elf_frob_file_after_relocs
+#endif
+extern void elf_frob_file_after_relocs (void);
+
+#ifndef obj_app_file
+#define obj_app_file elf_file_symbol
+#endif
+extern void elf_file_symbol (const char *);
+
+extern void obj_elf_section_change_hook (void);
+
+extern void obj_elf_section (int);
+extern void obj_elf_previous (int);
+extern void obj_elf_version (int);
+extern void obj_elf_common (int);
+extern void obj_elf_data (int);
+extern void obj_elf_text (int);
+extern void obj_elf_change_section
+ (const char *, int, int, int, const char *, int, int);
+extern struct fix *obj_elf_vtable_inherit (int);
+extern struct fix *obj_elf_vtable_entry (int);
+
+/* BFD wants to write the udata field, which is a no-no for the
+ predefined section symbols in bfd/section.c. They are read-only. */
+#ifndef obj_sec_sym_ok_for_reloc
+#define obj_sec_sym_ok_for_reloc(SEC) ((SEC)->owner != 0)
+#endif
+
+void elf_obj_read_begin_hook (void);
+#ifndef obj_read_begin_hook
+#define obj_read_begin_hook elf_obj_read_begin_hook
+#endif
+
+void elf_obj_symbol_new_hook (symbolS *);
+#ifndef obj_symbol_new_hook
+#define obj_symbol_new_hook elf_obj_symbol_new_hook
+#endif
+
+void elf_copy_symbol_attributes (symbolS *, symbolS *);
+#ifndef OBJ_COPY_SYMBOL_ATTRIBUTES
+#define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST, SRC) \
+ (elf_copy_symbol_attributes (DEST, SRC))
+#endif
+
+#ifndef SEPARATE_STAB_SECTIONS
+/* Avoid ifndef each separate macro setting by wrapping the whole of the
+ stab group on the assumption that whoever sets SEPARATE_STAB_SECTIONS
+ caters to ECOFF_DEBUGGING and the right setting of INIT_STAB_SECTIONS
+ and OBJ_PROCESS_STAB too, without needing the tweaks below. */
+
+/* Stabs go in a separate section. */
+#define SEPARATE_STAB_SECTIONS 1
+
+/* We need 12 bytes at the start of the section to hold some initial
+ information. */
+extern void obj_elf_init_stab_section (segT);
+#define INIT_STAB_SECTION(seg) obj_elf_init_stab_section (seg)
+
+#ifdef ECOFF_DEBUGGING
+/* We smuggle stabs in ECOFF rather than using a separate section.
+ The Irix linker can not handle a separate stabs section. */
+
+#undef SEPARATE_STAB_SECTIONS
+#define SEPARATE_STAB_SECTIONS (!ECOFF_DEBUGGING)
+
+#undef INIT_STAB_SECTION
+#define INIT_STAB_SECTION(seg) \
+ ((void) (ECOFF_DEBUGGING ? 0 : (obj_elf_init_stab_section (seg), 0)))
+
+#undef OBJ_PROCESS_STAB
+#define OBJ_PROCESS_STAB(seg, what, string, type, other, desc) \
+ if (ECOFF_DEBUGGING) \
+ ecoff_stab ((seg), (what), (string), (type), (other), (desc))
+#endif /* ECOFF_DEBUGGING */
+
+#endif /* SEPARATE_STAB_SECTIONS not defined. */
+
+extern void elf_frob_symbol (symbolS *, int *);
+#ifndef obj_frob_symbol
+#define obj_frob_symbol(symp, punt) elf_frob_symbol (symp, &punt)
+#endif
+
+extern void elf_pop_insert (void);
+#ifndef obj_pop_insert
+#define obj_pop_insert() elf_pop_insert()
+#endif
+
+#ifndef OBJ_MAYBE_ELF
+#define obj_ecoff_set_ext elf_ecoff_set_ext
+#ifdef ANSI_PROTOTYPES
+struct ecoff_extr;
+#endif
+extern void elf_ecoff_set_ext (symbolS *, struct ecoff_extr *);
+#endif
+
+#endif /* _OBJ_ELF_H */
diff --git a/x/binutils/gas/config/obj-generic.c b/x/binutils/gas/config/obj-generic.c
new file mode 100644
index 0000000..69fc3d1
--- /dev/null
+++ b/x/binutils/gas/config/obj-generic.c
@@ -0,0 +1,41 @@
+/* This file is obj-generic.c and is intended to be a template for
+ object format specific source files.
+
+ Copyright (C) 1987-1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+/* These chars start a comment anywhere in a source file (except inside
+ another comment */
+const char comment_chars[] = "#";
+
+/*
+ * Local Variables:
+ * comment-column: 0
+ * fill-column: 131
+ * End:
+ */
+
+/* end of obj-generic.c */
diff --git a/x/binutils/gas/config/obj-generic.h b/x/binutils/gas/config/obj-generic.h
new file mode 100644
index 0000000..8cb8020
--- /dev/null
+++ b/x/binutils/gas/config/obj-generic.h
@@ -0,0 +1,79 @@
+/* This file is obj-generic.h
+ Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ * This file is obj-generic.h and is intended to be a template for
+ * object format specific header files.
+ */
+
+/* define an obj specific macro off which target cpu back ends may key. */
+#define OBJ_GENERIC 1
+
+/* include whatever target cpu is appropriate. */
+#include "targ-cpu.h"
+
+/*
+ * SYMBOLS
+ */
+
+/*
+ * If your object format needs to reorder symbols, define this. When
+ * defined, symbols are kept on a doubly linked list and functions are
+ * made available for push, insert, append, and delete. If not defined,
+ * symbols are kept on a singly linked list, only the append and clear
+ * facilities are available, and they are macros.
+ */
+
+/* #define SYMBOLS_NEED_PACKPOINTERS */
+
+/* */
+typedef struct
+ {
+ void *nothing;
+ }
+
+obj_symbol_type; /* should be the format's symbol structure */
+
+typedef void *object_headers;
+
+/* symbols have names */
+#define S_GET_NAME(s) ("foo") /* get the name of a symbolP */
+#define S_SET_NAME(s,v) ;
+/* symbols have segments */
+#define S_GET_SEGMENT(s) (SEG_UNKNOWN)
+#define S_SET_SEGMENT(s,v) ;
+/* symbols may be external */
+#define S_IS_EXTERNAL(s) (0)
+#define S_SET_EXTERNAL(s) ;
+
+/* symbols may or may not be defined */
+#define S_IS_DEFINED(s) (0)
+
+#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (0) /* your magic number */
+
+#define OBJ_EMIT_LINENO(a,b,c) /* must be *something*. This no-op's it out. */
+
+/*
+ * Local Variables:
+ * comment-column: 0
+ * fill-column: 131
+ * End:
+ */
diff --git a/x/binutils/gas/config/obj-ieee.c b/x/binutils/gas/config/obj-ieee.c
new file mode 100644
index 0000000..02f4339
--- /dev/null
+++ b/x/binutils/gas/config/obj-ieee.c
@@ -0,0 +1,633 @@
+/* obj-format for ieee-695 records.
+ Copyright 1991, 1992, 1993, 1994, 1997, 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Created by Steve Chamberlain <steve@cygnus.com>. */
+
+/* This will hopefully become the port through which bfd and gas talk,
+ for the moment, only ieee is known to work well. */
+
+#include "bfd.h"
+#include "as.h"
+#include "subsegs.h"
+#include "output-file.h"
+#include "frags.h"
+
+bfd *abfd;
+
+/* How many addresses does the .align take? */
+
+static relax_addressT
+relax_align (address, alignment)
+ /* Address now. */
+ register relax_addressT address;
+
+ /* Alignment (binary). */
+ register long alignment;
+{
+ relax_addressT mask;
+ relax_addressT new_address;
+
+ mask = ~((~0) << alignment);
+ new_address = (address + mask) & (~mask);
+ return (new_address - address);
+}
+
+/* Calculate the size of the frag chain
+ and create a bfd section to contain all of it. */
+
+static void
+size_section (abfd, idx)
+ bfd *abfd;
+ unsigned int idx;
+{
+ asection *sec;
+ unsigned int size = 0;
+ fragS *frag = segment_info[idx].frag_root;
+
+ while (frag)
+ {
+ if (frag->fr_address != size)
+ {
+ printf (_("Out of step\n"));
+ size = frag->fr_address;
+ }
+ size += frag->fr_fix;
+ switch (frag->fr_type)
+ {
+ case rs_fill:
+ case rs_org:
+ size += frag->fr_offset * frag->fr_var;
+ break;
+ case rs_align:
+ case rs_align_code:
+ {
+ addressT off;
+
+ off = relax_align (size, frag->fr_offset);
+ if (frag->fr_subtype != 0 && off > frag->fr_subtype)
+ off = 0;
+ size += off;
+ }
+ }
+ frag = frag->fr_next;
+ }
+ if (size)
+ {
+ char *name = segment_info[idx].name;
+
+ if (name == (char *) NULL)
+ name = ".data";
+
+ segment_info[idx].user_stuff =
+ (char *) (sec = bfd_make_section (abfd, name));
+ /* Make it output through itself. */
+ sec->output_section = sec;
+ sec->flags |= SEC_HAS_CONTENTS;
+ bfd_set_section_size (abfd, sec, size);
+ }
+}
+
+/* Run through a frag chain and write out the data to go with it. */
+
+static void
+fill_section (abfd, idx)
+ bfd *abfd;
+ unsigned int idx;
+{
+ asection *sec = segment_info[idx].user_stuff;
+
+ if (sec)
+ {
+ fragS *frag = segment_info[idx].frag_root;
+ unsigned int offset = 0;
+ while (frag)
+ {
+ unsigned int fill_size;
+ unsigned int count;
+ switch (frag->fr_type)
+ {
+ case rs_fill:
+ case rs_align:
+ case rs_org:
+ if (frag->fr_fix)
+ {
+ bfd_set_section_contents (abfd,
+ sec,
+ frag->fr_literal,
+ frag->fr_address,
+ frag->fr_fix);
+ }
+ offset += frag->fr_fix;
+ fill_size = frag->fr_var;
+ if (fill_size)
+ {
+ unsigned int off = frag->fr_fix;
+ for (count = frag->fr_offset; count; count--)
+ {
+ bfd_set_section_contents (abfd, sec,
+ frag->fr_literal +
+ frag->fr_fix,
+ frag->fr_address + off,
+ fill_size);
+ off += fill_size;
+ }
+ }
+ break;
+ default:
+ abort ();
+ }
+ frag = frag->fr_next;
+ }
+ }
+}
+
+/* Count the relocations in a chain. */
+
+static unsigned int
+count_entries_in_chain (idx)
+ unsigned int idx;
+{
+ unsigned int nrelocs;
+ fixS *fixup_ptr;
+
+ /* Count the relocations. */
+ fixup_ptr = segment_info[idx].fix_root;
+ nrelocs = 0;
+ while (fixup_ptr != (fixS *) NULL)
+ {
+ fixup_ptr = fixup_ptr->fx_next;
+ nrelocs++;
+ }
+ return nrelocs;
+}
+
+/* Output all the relocations for a section. */
+
+void
+do_relocs_for (idx)
+ unsigned int idx;
+{
+ unsigned int nrelocs;
+ arelent **reloc_ptr_vector;
+ arelent *reloc_vector;
+ asymbol **ptrs;
+ asection *section = (asection *) (segment_info[idx].user_stuff);
+ unsigned int i;
+ fixS *from;
+
+ if (section)
+ {
+ nrelocs = count_entries_in_chain (idx);
+
+ reloc_ptr_vector =
+ (arelent **) malloc ((nrelocs + 1) * sizeof (arelent *));
+ reloc_vector = (arelent *) malloc (nrelocs * sizeof (arelent));
+ ptrs = (asymbol **) malloc (nrelocs * sizeof (asymbol *));
+ from = segment_info[idx].fix_root;
+ for (i = 0; i < nrelocs; i++)
+ {
+ arelent *to = reloc_vector + i;
+ asymbol *s;
+ reloc_ptr_vector[i] = to;
+ to->howto = (reloc_howto_type *) (from->fx_r_type);
+
+#if 0
+ /* We can't represent complicated things in a reloc yet. */
+ if (from->fx_addsy == 0 || from->fx_subsy != 0)
+ abort ();
+#endif
+
+ s = &(from->fx_addsy->sy_symbol.sy);
+ to->address = ((char *) (from->fx_frag->fr_address +
+ from->fx_where))
+ - ((char *) (&(from->fx_frag->fr_literal)));
+ to->addend = from->fx_offset;
+ /* If we know the symbol which we want to relocate to, turn
+ this reloaction into a section relative.
+
+ If this relocation is pcrelative, and we know the
+ destination, we still want to keep the relocation - since
+ the linker might relax some of the bytes, but it stops
+ being pc relative and turns into an absolute relocation. */
+ if (s)
+ {
+ if ((s->flags & BSF_UNDEFINED) == 0)
+ {
+ to->section = s->section;
+
+ /* We can refer directly to the value field here,
+ rather than using S_GET_VALUE, because this is
+ only called after do_symbols, which sets up the
+ value field. */
+ to->addend += s->value;
+
+ to->sym_ptr_ptr = 0;
+ if (to->howto->pcrel_offset)
+ /* This is a pcrel relocation, the addend should
+ be adjusted. */
+ to->addend -= to->address + 1;
+ }
+ else
+ {
+ to->section = 0;
+ *ptrs = &(from->fx_addsy->sy_symbol.sy);
+ to->sym_ptr_ptr = ptrs;
+
+ if (to->howto->pcrel_offset)
+ /* This is a pcrel relocation, the addend should
+ be adjusted. */
+ to->addend -= to->address - 1;
+ }
+ }
+ else
+ to->section = 0;
+
+ ptrs++;
+ from = from->fx_next;
+ }
+
+ /* Attach to the section. */
+ section->orelocation = reloc_ptr_vector;
+ section->reloc_count = nrelocs;
+ section->flags |= SEC_LOAD;
+ }
+}
+
+/* Do the symbols. */
+
+static void
+do_symbols (abfd)
+ bfd *abfd;
+{
+ extern symbolS *symbol_rootP;
+ symbolS *ptr;
+ asymbol **symbol_ptr_vec;
+ asymbol *symbol_vec;
+ unsigned int count = 0;
+ unsigned int index;
+
+ for (ptr = symbol_rootP;
+ ptr != (symbolS *) NULL;
+ ptr = ptr->sy_next)
+ {
+ if (SEG_NORMAL (ptr->sy_symbol.seg))
+ {
+ ptr->sy_symbol.sy.section =
+ (asection *) (segment_info[ptr->sy_symbol.seg].user_stuff);
+ S_SET_VALUE (ptr, S_GET_VALUE (ptr));
+ if (ptr->sy_symbol.sy.flags == 0)
+ ptr->sy_symbol.sy.flags = BSF_LOCAL;
+ }
+ else
+ {
+ switch (ptr->sy_symbol.seg)
+ {
+ case SEG_ABSOLUTE:
+ ptr->sy_symbol.sy.flags |= BSF_ABSOLUTE;
+ ptr->sy_symbol.sy.section = 0;
+ break;
+ case SEG_UNKNOWN:
+ ptr->sy_symbol.sy.flags = BSF_UNDEFINED;
+ ptr->sy_symbol.sy.section = 0;
+ break;
+ default:
+ abort ();
+ }
+ }
+ ptr->sy_symbol.sy.value = S_GET_VALUE (ptr);
+ count++;
+ }
+ symbol_ptr_vec = (asymbol **) malloc ((count + 1) * sizeof (asymbol *));
+
+ index = 0;
+ for (ptr = symbol_rootP;
+ ptr != (symbolS *) NULL;
+ ptr = ptr->sy_next)
+ {
+ symbol_ptr_vec[index] = &(ptr->sy_symbol.sy);
+ index++;
+ }
+ symbol_ptr_vec[index] = 0;
+ abfd->outsymbols = symbol_ptr_vec;
+ abfd->symcount = count;
+}
+
+/* The generic as->bfd converter. Other backends may have special case
+ code. */
+
+void
+bfd_as_write_hook ()
+{
+ int i;
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ size_section (abfd, i);
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ fill_section (abfd, i);
+
+ do_symbols (abfd);
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ do_relocs_for (i);
+}
+
+S_SET_SEGMENT (x, y)
+ symbolS *x;
+ int y;
+{
+ x->sy_symbol.seg = y;
+}
+
+S_IS_DEFINED (x)
+ symbolS *x;
+{
+ if (SEG_NORMAL (x->sy_symbol.seg))
+ {
+ return 1;
+ }
+ switch (x->sy_symbol.seg)
+ {
+ case SEG_UNKNOWN:
+ return 0;
+ default:
+ abort ();
+ }
+}
+
+S_IS_EXTERNAL (x)
+{
+ abort ();
+}
+
+S_GET_DESC (x)
+{
+ abort ();
+}
+
+S_GET_SEGMENT (x)
+ symbolS *x;
+{
+ return x->sy_symbol.seg;
+}
+
+S_SET_EXTERNAL (x)
+ symbolS *x;
+{
+ x->sy_symbol.sy.flags |= BSF_GLOBAL | BSF_EXPORT;
+}
+
+S_SET_NAME (x, y)
+ symbolS *x;
+ char *y;
+{
+ x->sy_symbol.sy.name = y;
+}
+
+S_GET_OTHER (x)
+{
+ abort ();
+}
+
+S_IS_DEBUG (x)
+{
+ abort ();
+}
+
+#ifndef segment_name
+char *
+segment_name ()
+{
+ abort ();
+}
+#endif
+
+void
+obj_read_begin_hook ()
+{
+}
+
+static void
+obj_ieee_section (ignore)
+ int ignore;
+{
+ extern char *input_line_pointer;
+ extern char is_end_of_line[];
+ char *p = input_line_pointer;
+ char *s = p;
+ int i;
+
+ /* Look up the name, if it doesn't exist, make it. */
+ while (*p && *p != ' ' && *p != ',' && !is_end_of_line[*p])
+ {
+ p++;
+ }
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ if (segment_info[i].hadone)
+ {
+ if (strncmp (segment_info[i].name, s, p - s) == 0)
+ goto ok;
+ }
+ else
+ break;
+ }
+ if (i == SEG_UNKNOWN)
+ {
+ as_bad (_("too many sections"));
+ return;
+ }
+
+ segment_info[i].hadone = 1;
+ segment_info[i].name = malloc (p - s + 1);
+ memcpy (segment_info[i].name, s, p - s);
+ segment_info[i].name[p - s] = 0;
+ok:
+ subseg_set (i, 0);
+ while (!is_end_of_line[*p])
+ p++;
+ input_line_pointer = p;
+}
+
+const pseudo_typeS obj_pseudo_table[] =
+{
+ {"section", obj_ieee_section, 0},
+ {"data.b" , cons , 1},
+ {"data.w" , cons , 2},
+ {"data.l" , cons , 4},
+ {"export" , s_globl , 0},
+ {"option" , s_ignore , 0},
+ {"end" , s_ignore , 0},
+ {"import" , s_ignore , 0},
+ {"sdata" , stringer , 0},
+ 0,
+};
+
+void
+obj_symbol_new_hook (symbolP)
+ symbolS *symbolP;
+{
+ symbolP->sy_symbol.sy.the_bfd = abfd;
+}
+
+#if 1
+
+#ifndef SUB_SEGMENT_ALIGN
+#ifdef HANDLE_ALIGN
+/* The last subsegment gets an alignment corresponding to the alignment
+ of the section. This allows proper nop-filling at the end of
+ code-bearing sections. */
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \
+ (!(FRCHAIN)->frch_next || (FRCHAIN)->frch_next->frch_seg != (SEG) \
+ ? get_recorded_alignment (SEG) : 0)
+#else
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 2
+#endif
+#endif
+
+extern void
+write_object_file ()
+{
+ int i;
+ struct frchain *frchain_ptr;
+ struct frag *frag_ptr;
+
+ abfd = bfd_openw (out_file_name, "ieee");
+
+ if (abfd == 0)
+ {
+ as_perror (_("FATAL: Can't create %s"), out_file_name);
+ exit (EXIT_FAILURE);
+ }
+ bfd_set_format (abfd, bfd_object);
+ bfd_set_arch_mach (abfd, bfd_arch_h8300, 0);
+ subseg_set (1, 0);
+ subseg_set (2, 0);
+ subseg_set (3, 0);
+
+ /* Run through all the sub-segments and align them up. Also
+ close any open frags. We tack a .fill onto the end of the
+ frag chain so that any .align's size can be worked by looking
+ at the next frag. */
+ for (frchain_ptr = frchain_root;
+ frchain_ptr != (struct frchain *) NULL;
+ frchain_ptr = frchain_ptr->frch_next)
+ {
+ int alignment;
+
+ subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
+
+ alignment = SUB_SEGMENT_ALIGN (now_seg, frchain_ptr)
+
+#ifdef md_do_align
+ md_do_align (alignment, (char *) NULL, 0, 0, alignment_done);
+#endif
+ if (subseg_text_p (now_seg))
+ frag_align_code (alignment, 0);
+ else
+ frag_align (alignment, 0, 0);
+
+#ifdef md_do_align
+ alignment_done:
+#endif
+
+ frag_wane (frag_now);
+ frag_now->fr_fix = 0;
+ know (frag_now->fr_next == NULL);
+ }
+
+ /* Now build one big frag chain for each segment, linked through
+ fr_next. */
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ fragS **prev_frag_ptr_ptr;
+ struct frchain *next_frchain_ptr;
+
+#if 0
+ struct frag **head_ptr = segment_info[i].frag_root;
+#endif
+
+ segment_info[i].frag_root = segment_info[i].frchainP->frch_root;
+#if 0
+ /* I'm not sure what this is for. */
+ for (frchain_ptr = segment_info[i].frchainP->frch_root;
+ frchain_ptr != (struct frchain *) NULL;
+ frchain_ptr = frchain_ptr->frch_next)
+ {
+ *head_ptr = frchain_ptr;
+ head_ptr = &frchain_ptr->next;
+ }
+#endif
+ }
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ relax_segment (segment_info[i].frag_root, i);
+
+ /* Relaxation has completed. Freeze all syms. */
+ finalize_syms = 1;
+
+ /* Now the addresses of the frags are correct within the segment. */
+
+ bfd_as_write_hook ();
+ bfd_close (abfd);
+}
+
+#endif
+
+H_SET_TEXT_SIZE (a, b)
+{
+ abort ();
+}
+
+H_GET_TEXT_SIZE ()
+{
+ abort ();
+}
+
+H_SET_BSS_SIZE ()
+{
+ abort ();
+}
+
+H_SET_STRING_SIZE ()
+{
+ abort ();
+}
+
+H_SET_RELOCATION_SIZE ()
+{
+ abort ();
+}
+
+H_SET_MAGIC_NUMBER ()
+{
+ abort ();
+}
+
+H_GET_FILE_SIZE ()
+{
+ abort ();
+}
+
+H_GET_TEXT_RELOCATION_SIZE ()
+{
+ abort ();
+}
diff --git a/x/binutils/gas/config/obj-ieee.h b/x/binutils/gas/config/obj-ieee.h
new file mode 100644
index 0000000..c0bd628
--- /dev/null
+++ b/x/binutils/gas/config/obj-ieee.h
@@ -0,0 +1,50 @@
+/* This file is obj-ieee.h
+ Copyright 1987, 1988, 1989, 1990, 1991, 1992, 2000, 2002, 2003
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define BFD 1
+
+#include "bfd.h"
+
+typedef struct
+{
+ asymbol sy;
+ int seg;
+}
+obj_symbol_type;
+
+#define S_GET_NAME(s) (((s)->sy_symbol.sy.name))
+
+/* Return true for symbols that should not be reduced to section
+ symbols or eliminated from expressions, because they may be
+ overridden by the linker. */
+#define S_FORCE_RELOC(s, strict) (!SEG_NORMAL (x->sy_symbol.seg))
+
+typedef struct
+ {
+ int x;
+ }
+object_headers;
+
+#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE 1
+
+int lineno_rootP;
+
+#define IEEE_STYLE
diff --git a/x/binutils/gas/config/obj-multi.c b/x/binutils/gas/config/obj-multi.c
new file mode 100644
index 0000000..d115093
--- /dev/null
+++ b/x/binutils/gas/config/obj-multi.c
@@ -0,0 +1,4 @@
+/* foo */
+
+#include "as.h"
+
diff --git a/x/binutils/gas/config/obj-multi.h b/x/binutils/gas/config/obj-multi.h
new file mode 100644
index 0000000..37d9fe8
--- /dev/null
+++ b/x/binutils/gas/config/obj-multi.h
@@ -0,0 +1,162 @@
+/* Multiple object format emulation.
+ Copyright 1995, 1996, 1997, 1999, 2000, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef _OBJ_MULTI_H
+#define _OBJ_MULTI_H
+
+#ifdef OBJ_HEADER
+#include OBJ_HEADER
+#else
+
+#include "emul.h"
+#include "targ-cpu.h"
+
+#define OUTPUT_FLAVOR \
+ (this_format->flavor)
+
+#define obj_begin() \
+ (this_format->begin \
+ ? (*this_format->begin) () \
+ : (void) 0)
+
+#define obj_app_file(NAME) \
+ (this_format->app_file \
+ ? (*this_format->app_file) (NAME) \
+ : (void) 0)
+
+#define obj_frob_symbol(S,P) \
+ (*this_format->frob_symbol) (S, &(P))
+
+#define obj_frob_file() \
+ (this_format->frob_file \
+ ? (*this_format->frob_file) () \
+ : (void) 0)
+
+#define obj_frob_file_before_adjust() \
+ (this_format->frob_file_before_adjust \
+ ? (*this_format->frob_file_before_adjust) () \
+ : (void) 0)
+
+#define obj_frob_file_before_fix() \
+ (this_format->frob_file_before_fix \
+ ? (*this_format->frob_file_before_fix) () \
+ : (void) 0)
+
+#define obj_frob_file_after_relocs() \
+ (this_format->frob_file_after_relocs \
+ ? (*this_format->frob_file_after_relocs) () \
+ : (void) 0)
+
+#define obj_ecoff_set_ext \
+ (*this_format->ecoff_set_ext)
+
+#define obj_pop_insert \
+ (*this_format->pop_insert)
+
+#define obj_read_begin_hook() \
+ (this_format->read_begin_hook \
+ ? (*this_format->read_begin_hook) () \
+ : (void) 0)
+
+#define obj_symbol_new_hook(S) \
+ (this_format->symbol_new_hook \
+ ? (*this_format->symbol_new_hook) (S) \
+ : (void) 0)
+
+#define obj_sec_sym_ok_for_reloc(A) \
+ (this_format->sec_sym_ok_for_reloc \
+ ? (*this_format->sec_sym_ok_for_reloc) (A) \
+ : 0)
+
+#define S_GET_SIZE \
+ (*this_format->s_get_size)
+
+#define S_SET_SIZE(S, N) \
+ (this_format->s_set_size \
+ ? (*this_format->s_set_size) (S, N) \
+ : (void) 0)
+
+#define S_GET_ALIGN \
+ (*this_format->s_get_align)
+
+#define S_SET_ALIGN(S, N) \
+ (this_format->s_set_align \
+ ? (*this_format->s_set_align) (S, N) \
+ : (void) 0)
+
+#define S_GET_OTHER \
+ (*this_format->s_get_other)
+
+#define S_SET_OTHER(S, O) \
+ (this_format->s_set_other \
+ ? (*this_format->s_set_other) (S, O) \
+ : (void) 0)
+
+#define S_GET_DESC \
+ (*this_format->s_get_desc)
+
+#define S_SET_DESC(S, D) \
+ (this_format->s_set_desc \
+ ? (*this_format->s_set_desc) (S, D) \
+ : (void) 0)
+
+#define S_GET_TYPE \
+ (*this_format->s_get_desc)
+
+#define S_SET_TYPE(S, T) \
+ (this_format->s_set_type \
+ ? (*this_format->s_set_type) (S, T) \
+ : (void) 0)
+
+#define OBJ_COPY_SYMBOL_ATTRIBUTES(d,s) \
+ (this_format->copy_symbol_attributes \
+ ? (*this_format->copy_symbol_attributes) (d, s) \
+ : (void) 0)
+
+#define OBJ_PROCESS_STAB(SEG,W,S,T,O,D) \
+ (this_format->process_stab \
+ ? (*this_format->process_stab) (SEG,W,S,T,O,D) \
+ : (void) 0)
+
+#define SEPARATE_STAB_SECTIONS \
+ ((*this_format->separate_stab_sections) ())
+
+#define INIT_STAB_SECTION(S) \
+ (this_format->init_stab_section \
+ ? (*this_format->init_stab_section) (S) \
+ : (void) 0)
+
+#define EMIT_SECTION_SYMBOLS (this_format->emit_section_symbols)
+
+#ifdef OBJ_MAYBE_ELF
+/* We need OBJ_SYMFIELD_TYPE so that symbol_get_obj is defined in symbol.c
+ We also need various STAB defines for stab.c */
+#include "obj-elf.h"
+#endif
+
+#ifdef OBJ_MAYBE_AOUT
+/* We want aout_process_stab in stabs.c for the aout table. Defining this
+ macro will have no other effect. */
+#define AOUT_STABS
+#endif
+
+#endif /* !OBJ_HEADER */
+#endif /* _OBJ_MULTI_H */
diff --git a/x/binutils/gas/config/sco5.mt b/x/binutils/gas/config/sco5.mt
new file mode 100644
index 0000000..8879320
--- /dev/null
+++ b/x/binutils/gas/config/sco5.mt
@@ -0,0 +1 @@
+TDEFINES=-DSCO_ELF
diff --git a/x/binutils/gas/config/tc-alpha.c b/x/binutils/gas/config/tc-alpha.c
new file mode 100644
index 0000000..9360047
--- /dev/null
+++ b/x/binutils/gas/config/tc-alpha.c
@@ -0,0 +1,5960 @@
+/* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
+ Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Carnegie Mellon University, 1993.
+ Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
+ Modified by Ken Raeburn for gas-2.x and ECOFF support.
+ Modified by Richard Henderson for ELF support.
+ Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1993 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "as.h"
+#include "subsegs.h"
+#include "struc-symbol.h"
+#include "ecoff.h"
+
+#include "opcode/alpha.h"
+
+#ifdef OBJ_ELF
+#include "elf/alpha.h"
+#include "dwarf2dbg.h"
+#include "dw2gencfi.h"
+#endif
+
+#include "safe-ctype.h"
+
+/* Local types. */
+
+#define TOKENIZE_ERROR -1
+#define TOKENIZE_ERROR_REPORT -2
+
+#define MAX_INSN_FIXUPS 2
+#define MAX_INSN_ARGS 5
+
+struct alpha_fixup
+{
+ expressionS exp;
+ bfd_reloc_code_real_type reloc;
+};
+
+struct alpha_insn
+{
+ unsigned insn;
+ int nfixups;
+ struct alpha_fixup fixups[MAX_INSN_FIXUPS];
+ long sequence;
+};
+
+enum alpha_macro_arg
+ {
+ MACRO_EOA = 1,
+ MACRO_IR,
+ MACRO_PIR,
+ MACRO_OPIR,
+ MACRO_CPIR,
+ MACRO_FPR,
+ MACRO_EXP,
+ };
+
+struct alpha_macro
+{
+ const char *name;
+ void (*emit) PARAMS ((const expressionS *, int, const PTR));
+ const PTR arg;
+ enum alpha_macro_arg argsets[16];
+};
+
+/* Extra expression types. */
+
+#define O_pregister O_md1 /* O_register, in parentheses */
+#define O_cpregister O_md2 /* + a leading comma */
+
+/* The alpha_reloc_op table below depends on the ordering of these. */
+#define O_literal O_md3 /* !literal relocation */
+#define O_lituse_addr O_md4 /* !lituse_addr relocation */
+#define O_lituse_base O_md5 /* !lituse_base relocation */
+#define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation */
+#define O_lituse_jsr O_md7 /* !lituse_jsr relocation */
+#define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation */
+#define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation */
+#define O_gpdisp O_md10 /* !gpdisp relocation */
+#define O_gprelhigh O_md11 /* !gprelhigh relocation */
+#define O_gprellow O_md12 /* !gprellow relocation */
+#define O_gprel O_md13 /* !gprel relocation */
+#define O_samegp O_md14 /* !samegp relocation */
+#define O_tlsgd O_md15 /* !tlsgd relocation */
+#define O_tlsldm O_md16 /* !tlsldm relocation */
+#define O_gotdtprel O_md17 /* !gotdtprel relocation */
+#define O_dtprelhi O_md18 /* !dtprelhi relocation */
+#define O_dtprello O_md19 /* !dtprello relocation */
+#define O_dtprel O_md20 /* !dtprel relocation */
+#define O_gottprel O_md21 /* !gottprel relocation */
+#define O_tprelhi O_md22 /* !tprelhi relocation */
+#define O_tprello O_md23 /* !tprello relocation */
+#define O_tprel O_md24 /* !tprel relocation */
+
+#define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
+#define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
+#define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
+#define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
+#define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5)
+#define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6)
+
+#define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
+
+/* Macros for extracting the type and number of encoded register tokens. */
+
+#define is_ir_num(x) (((x) & 32) == 0)
+#define is_fpr_num(x) (((x) & 32) != 0)
+#define regno(x) ((x) & 31)
+
+/* Something odd inherited from the old assembler. */
+
+#define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
+#define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
+
+/* Predicates for 16- and 32-bit ranges */
+/* XXX: The non-shift version appears to trigger a compiler bug when
+ cross-assembling from x86 w/ gcc 2.7.2. */
+
+#if 1
+#define range_signed_16(x) \
+ (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
+#define range_signed_32(x) \
+ (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
+#else
+#define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
+ (offsetT) (x) <= (offsetT) 0x7FFF)
+#define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
+ (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
+#endif
+
+/* Macros for sign extending from 16- and 32-bits. */
+/* XXX: The cast macros will work on all the systems that I care about,
+ but really a predicate should be found to use the non-cast forms. */
+
+#if 1
+#define sign_extend_16(x) ((short) (x))
+#define sign_extend_32(x) ((int) (x))
+#else
+#define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
+#define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
+ ^ 0x80000000) - 0x80000000)
+#endif
+
+/* Macros to build tokens. */
+
+#define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
+ (t).X_op = O_register, \
+ (t).X_add_number = (r))
+#define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
+ (t).X_op = O_pregister, \
+ (t).X_add_number = (r))
+#define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
+ (t).X_op = O_cpregister, \
+ (t).X_add_number = (r))
+#define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
+ (t).X_op = O_register, \
+ (t).X_add_number = (r) + 32)
+#define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
+ (t).X_op = O_symbol, \
+ (t).X_add_symbol = (s), \
+ (t).X_add_number = (a))
+#define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
+ (t).X_op = O_constant, \
+ (t).X_add_number = (n))
+
+/* Prototypes for all local functions. */
+
+static struct alpha_reloc_tag *get_alpha_reloc_tag PARAMS ((long));
+static void alpha_adjust_relocs PARAMS ((bfd *, asection *, PTR));
+
+static int tokenize_arguments PARAMS ((char *, expressionS *, int));
+static const struct alpha_opcode *find_opcode_match
+ PARAMS ((const struct alpha_opcode *, const expressionS *, int *, int *));
+static const struct alpha_macro *find_macro_match
+ PARAMS ((const struct alpha_macro *, const expressionS *, int *));
+static unsigned insert_operand
+ PARAMS ((unsigned, const struct alpha_operand *, offsetT, char *, unsigned));
+static void assemble_insn
+ PARAMS ((const struct alpha_opcode *, const expressionS *, int,
+ struct alpha_insn *, bfd_reloc_code_real_type));
+static void emit_insn PARAMS ((struct alpha_insn *));
+static void assemble_tokens_to_insn
+ PARAMS ((const char *, const expressionS *, int, struct alpha_insn *));
+static void assemble_tokens
+ PARAMS ((const char *, const expressionS *, int, int));
+
+static long load_expression
+ PARAMS ((int, const expressionS *, int *, expressionS *));
+
+static void emit_ldgp PARAMS ((const expressionS *, int, const PTR));
+static void emit_division PARAMS ((const expressionS *, int, const PTR));
+static void emit_lda PARAMS ((const expressionS *, int, const PTR));
+static void emit_ldah PARAMS ((const expressionS *, int, const PTR));
+static void emit_ir_load PARAMS ((const expressionS *, int, const PTR));
+static void emit_loadstore PARAMS ((const expressionS *, int, const PTR));
+static void emit_jsrjmp PARAMS ((const expressionS *, int, const PTR));
+static void emit_ldX PARAMS ((const expressionS *, int, const PTR));
+static void emit_ldXu PARAMS ((const expressionS *, int, const PTR));
+static void emit_uldX PARAMS ((const expressionS *, int, const PTR));
+static void emit_uldXu PARAMS ((const expressionS *, int, const PTR));
+static void emit_ldil PARAMS ((const expressionS *, int, const PTR));
+static void emit_stX PARAMS ((const expressionS *, int, const PTR));
+static void emit_ustX PARAMS ((const expressionS *, int, const PTR));
+static void emit_sextX PARAMS ((const expressionS *, int, const PTR));
+static void emit_retjcr PARAMS ((const expressionS *, int, const PTR));
+
+static void s_alpha_text PARAMS ((int));
+static void s_alpha_data PARAMS ((int));
+#ifndef OBJ_ELF
+static void s_alpha_comm PARAMS ((int));
+static void s_alpha_rdata PARAMS ((int));
+#endif
+#ifdef OBJ_ECOFF
+static void s_alpha_sdata PARAMS ((int));
+#endif
+#ifdef OBJ_ELF
+static void s_alpha_section PARAMS ((int));
+static void s_alpha_ent PARAMS ((int));
+static void s_alpha_end PARAMS ((int));
+static void s_alpha_mask PARAMS ((int));
+static void s_alpha_frame PARAMS ((int));
+static void s_alpha_prologue PARAMS ((int));
+static void s_alpha_file PARAMS ((int));
+static void s_alpha_loc PARAMS ((int));
+static void s_alpha_stab PARAMS ((int));
+static void s_alpha_coff_wrapper PARAMS ((int));
+static void s_alpha_usepv PARAMS ((int));
+#endif
+#ifdef OBJ_EVAX
+static void s_alpha_section PARAMS ((int));
+#endif
+static void s_alpha_gprel32 PARAMS ((int));
+static void s_alpha_float_cons PARAMS ((int));
+static void s_alpha_proc PARAMS ((int));
+static void s_alpha_set PARAMS ((int));
+static void s_alpha_base PARAMS ((int));
+static void s_alpha_align PARAMS ((int));
+static void s_alpha_stringer PARAMS ((int));
+static void s_alpha_space PARAMS ((int));
+static void s_alpha_ucons PARAMS ((int));
+static void s_alpha_arch PARAMS ((int));
+
+static void create_literal_section PARAMS ((const char *, segT *, symbolS **));
+#ifndef OBJ_ELF
+static void select_gp_value PARAMS ((void));
+#endif
+static void alpha_align PARAMS ((int, char *, symbolS *, int));
+
+/* Generic assembler global variables which must be defined by all
+ targets. */
+
+/* Characters which always start a comment. */
+const char comment_chars[] = "#";
+
+/* Characters which start a comment at the beginning of a line. */
+const char line_comment_chars[] = "#";
+
+/* Characters which may be used to separate multiple commands on a
+ single line. */
+const char line_separator_chars[] = ";";
+
+/* Characters which are used to indicate an exponent in a floating
+ point number. */
+const char EXP_CHARS[] = "eE";
+
+/* Characters which mean that a number is a floating point constant,
+ as in 0d1.0. */
+#if 0
+const char FLT_CHARS[] = "dD";
+#else
+/* XXX: Do all of these really get used on the alpha?? */
+char FLT_CHARS[] = "rRsSfFdDxXpP";
+#endif
+
+#ifdef OBJ_EVAX
+const char *md_shortopts = "Fm:g+1h:HG:";
+#else
+const char *md_shortopts = "Fm:gG:";
+#endif
+
+struct option md_longopts[] =
+ {
+#define OPTION_32ADDR (OPTION_MD_BASE)
+ { "32addr", no_argument, NULL, OPTION_32ADDR },
+#define OPTION_RELAX (OPTION_32ADDR + 1)
+ { "relax", no_argument, NULL, OPTION_RELAX },
+#ifdef OBJ_ELF
+#define OPTION_MDEBUG (OPTION_RELAX + 1)
+#define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
+ { "mdebug", no_argument, NULL, OPTION_MDEBUG },
+ { "no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG },
+#endif
+ { NULL, no_argument, NULL, 0 }
+ };
+
+size_t md_longopts_size = sizeof (md_longopts);
+
+#ifdef OBJ_EVAX
+#define AXP_REG_R0 0
+#define AXP_REG_R16 16
+#define AXP_REG_R17 17
+#undef AXP_REG_T9
+#define AXP_REG_T9 22
+#undef AXP_REG_T10
+#define AXP_REG_T10 23
+#undef AXP_REG_T11
+#define AXP_REG_T11 24
+#undef AXP_REG_T12
+#define AXP_REG_T12 25
+#define AXP_REG_AI 25
+#undef AXP_REG_FP
+#define AXP_REG_FP 29
+
+#undef AXP_REG_GP
+#define AXP_REG_GP AXP_REG_PV
+#endif /* OBJ_EVAX */
+
+/* The cpu for which we are generating code. */
+static unsigned alpha_target = AXP_OPCODE_BASE;
+static const char *alpha_target_name = "<all>";
+
+/* The hash table of instruction opcodes. */
+static struct hash_control *alpha_opcode_hash;
+
+/* The hash table of macro opcodes. */
+static struct hash_control *alpha_macro_hash;
+
+#ifdef OBJ_ECOFF
+/* The $gp relocation symbol. */
+static symbolS *alpha_gp_symbol;
+
+/* XXX: what is this, and why is it exported? */
+valueT alpha_gp_value;
+#endif
+
+/* The current $gp register. */
+static int alpha_gp_register = AXP_REG_GP;
+
+/* A table of the register symbols. */
+static symbolS *alpha_register_table[64];
+
+/* Constant sections, or sections of constants. */
+#ifdef OBJ_ECOFF
+static segT alpha_lita_section;
+#endif
+#ifdef OBJ_EVAX
+static segT alpha_link_section;
+static segT alpha_ctors_section;
+static segT alpha_dtors_section;
+#endif
+static segT alpha_lit8_section;
+
+/* Symbols referring to said sections. */
+#ifdef OBJ_ECOFF
+static symbolS *alpha_lita_symbol;
+#endif
+#ifdef OBJ_EVAX
+static symbolS *alpha_link_symbol;
+static symbolS *alpha_ctors_symbol;
+static symbolS *alpha_dtors_symbol;
+#endif
+static symbolS *alpha_lit8_symbol;
+
+/* Literal for .litX+0x8000 within .lita. */
+#ifdef OBJ_ECOFF
+static offsetT alpha_lit8_literal;
+#endif
+
+/* Is the assembler not allowed to use $at? */
+static int alpha_noat_on = 0;
+
+/* Are macros enabled? */
+static int alpha_macros_on = 1;
+
+/* Are floats disabled? */
+static int alpha_nofloats_on = 0;
+
+/* Are addresses 32 bit? */
+static int alpha_addr32_on = 0;
+
+/* Symbol labelling the current insn. When the Alpha gas sees
+ foo:
+ .quad 0
+ and the section happens to not be on an eight byte boundary, it
+ will align both the symbol and the .quad to an eight byte boundary. */
+static symbolS *alpha_insn_label;
+
+/* Whether we should automatically align data generation pseudo-ops.
+ .align 0 will turn this off. */
+static int alpha_auto_align_on = 1;
+
+/* The known current alignment of the current section. */
+static int alpha_current_align;
+
+/* These are exported to ECOFF code. */
+unsigned long alpha_gprmask, alpha_fprmask;
+
+/* Whether the debugging option was seen. */
+static int alpha_debug;
+
+#ifdef OBJ_ELF
+/* Whether we are emitting an mdebug section. */
+int alpha_flag_mdebug = -1;
+#endif
+
+/* Don't fully resolve relocations, allowing code movement in the linker. */
+static int alpha_flag_relax;
+
+/* What value to give to bfd_set_gp_size. */
+static int g_switch_value = 8;
+
+#ifdef OBJ_EVAX
+/* Collect information about current procedure here. */
+static struct {
+ symbolS *symbol; /* proc pdesc symbol */
+ int pdsckind;
+ int framereg; /* register for frame pointer */
+ int framesize; /* size of frame */
+ int rsa_offset;
+ int ra_save;
+ int fp_save;
+ long imask;
+ long fmask;
+ int type;
+ int prologue;
+} alpha_evax_proc;
+
+static int alpha_flag_hash_long_names = 0; /* -+ */
+static int alpha_flag_show_after_trunc = 0; /* -H */
+
+/* If the -+ switch is given, then a hash is appended to any name that is
+ longer than 64 characters, else longer symbol names are truncated. */
+
+#endif
+
+#ifdef RELOC_OP_P
+/* A table to map the spelling of a relocation operand into an appropriate
+ bfd_reloc_code_real_type type. The table is assumed to be ordered such
+ that op-O_literal indexes into it. */
+
+#define ALPHA_RELOC_TABLE(op) \
+(&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
+ ? (abort (), 0) \
+ : (int) (op) - (int) O_literal) ])
+
+#define DEF(NAME, RELOC, REQ, ALLOW) \
+ { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
+
+static const struct alpha_reloc_op_tag
+{
+ const char *name; /* string to lookup */
+ size_t length; /* size of the string */
+ operatorT op; /* which operator to use */
+ bfd_reloc_code_real_type reloc; /* relocation before frob */
+ unsigned int require_seq : 1; /* require a sequence number */
+ unsigned int allow_seq : 1; /* allow a sequence number */
+}
+alpha_reloc_op[] =
+{
+ DEF(literal, BFD_RELOC_ALPHA_ELF_LITERAL, 0, 1),
+ DEF(lituse_addr, DUMMY_RELOC_LITUSE_ADDR, 1, 1),
+ DEF(lituse_base, DUMMY_RELOC_LITUSE_BASE, 1, 1),
+ DEF(lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1, 1),
+ DEF(lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1),
+ DEF(lituse_tlsgd, DUMMY_RELOC_LITUSE_TLSGD, 1, 1),
+ DEF(lituse_tlsldm, DUMMY_RELOC_LITUSE_TLSLDM, 1, 1),
+ DEF(gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1),
+ DEF(gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0),
+ DEF(gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0),
+ DEF(gprel, BFD_RELOC_GPREL16, 0, 0),
+ DEF(samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0),
+ DEF(tlsgd, BFD_RELOC_ALPHA_TLSGD, 0, 1),
+ DEF(tlsldm, BFD_RELOC_ALPHA_TLSLDM, 0, 1),
+ DEF(gotdtprel, BFD_RELOC_ALPHA_GOTDTPREL16, 0, 0),
+ DEF(dtprelhi, BFD_RELOC_ALPHA_DTPREL_HI16, 0, 0),
+ DEF(dtprello, BFD_RELOC_ALPHA_DTPREL_LO16, 0, 0),
+ DEF(dtprel, BFD_RELOC_ALPHA_DTPREL16, 0, 0),
+ DEF(gottprel, BFD_RELOC_ALPHA_GOTTPREL16, 0, 0),
+ DEF(tprelhi, BFD_RELOC_ALPHA_TPREL_HI16, 0, 0),
+ DEF(tprello, BFD_RELOC_ALPHA_TPREL_LO16, 0, 0),
+ DEF(tprel, BFD_RELOC_ALPHA_TPREL16, 0, 0),
+};
+
+#undef DEF
+
+static const int alpha_num_reloc_op
+ = sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op);
+#endif /* RELOC_OP_P */
+
+/* Maximum # digits needed to hold the largest sequence # */
+#define ALPHA_RELOC_DIGITS 25
+
+/* Structure to hold explicit sequence information. */
+struct alpha_reloc_tag
+{
+ fixS *master; /* the literal reloc */
+ fixS *slaves; /* head of linked list of lituses */
+ segT segment; /* segment relocs are in or undefined_section*/
+ long sequence; /* sequence # */
+ unsigned n_master; /* # of literals */
+ unsigned n_slaves; /* # of lituses */
+ unsigned saw_tlsgd : 1; /* true if ... */
+ unsigned saw_tlsldm : 1;
+ unsigned saw_lu_tlsgd : 1;
+ unsigned saw_lu_tlsldm : 1;
+ unsigned multi_section_p : 1; /* true if more than one section was used */
+ char string[1]; /* printable form of sequence to hash with */
+};
+
+/* Hash table to link up literals with the appropriate lituse */
+static struct hash_control *alpha_literal_hash;
+
+/* Sequence numbers for internal use by macros. */
+static long next_sequence_num = -1;
+
+/* A table of CPU names and opcode sets. */
+
+static const struct cpu_type
+{
+ const char *name;
+ unsigned flags;
+}
+cpu_types[] =
+{
+ /* Ad hoc convention: cpu number gets palcode, process code doesn't.
+ This supports usage under DU 4.0b that does ".arch ev4", and
+ usage in MILO that does -m21064. Probably something more
+ specific like -m21064-pal should be used, but oh well. */
+
+ { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
+ { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
+ { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
+ { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
+ { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 },
+ { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX },
+ { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX
+ |AXP_OPCODE_MAX) },
+ { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
+ |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
+ { "21264a", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
+ |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
+ { "21264b", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
+ |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
+
+ { "ev4", AXP_OPCODE_BASE },
+ { "ev45", AXP_OPCODE_BASE },
+ { "lca45", AXP_OPCODE_BASE },
+ { "ev5", AXP_OPCODE_BASE },
+ { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX },
+ { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX },
+ { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
+ { "ev67", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
+ { "ev68", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
+
+ { "all", AXP_OPCODE_BASE },
+ { 0, 0 }
+};
+
+/* The macro table */
+
+static const struct alpha_macro alpha_macros[] =
+{
+/* Load/Store macros */
+ { "lda", emit_lda, NULL,
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "ldah", emit_ldah, NULL,
+ { MACRO_IR, MACRO_EXP, MACRO_EOA } },
+
+ { "ldl", emit_ir_load, "ldl",
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "ldl_l", emit_ir_load, "ldl_l",
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "ldq", emit_ir_load, "ldq",
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "ldq_l", emit_ir_load, "ldq_l",
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "ldq_u", emit_ir_load, "ldq_u",
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "ldf", emit_loadstore, "ldf",
+ { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "ldg", emit_loadstore, "ldg",
+ { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "lds", emit_loadstore, "lds",
+ { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "ldt", emit_loadstore, "ldt",
+ { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+
+ { "ldb", emit_ldX, (PTR) 0,
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "ldbu", emit_ldXu, (PTR) 0,
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "ldw", emit_ldX, (PTR) 1,
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "ldwu", emit_ldXu, (PTR) 1,
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+
+ { "uldw", emit_uldX, (PTR) 1,
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "uldwu", emit_uldXu, (PTR) 1,
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "uldl", emit_uldX, (PTR) 2,
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "uldlu", emit_uldXu, (PTR) 2,
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "uldq", emit_uldXu, (PTR) 3,
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+
+ { "ldgp", emit_ldgp, NULL,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
+
+ { "ldi", emit_lda, NULL,
+ { MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "ldil", emit_ldil, NULL,
+ { MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "ldiq", emit_lda, NULL,
+ { MACRO_IR, MACRO_EXP, MACRO_EOA } },
+#if 0
+ { "ldif" emit_ldiq, NULL,
+ { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+ { "ldid" emit_ldiq, NULL,
+ { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+ { "ldig" emit_ldiq, NULL,
+ { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+ { "ldis" emit_ldiq, NULL,
+ { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+ { "ldit" emit_ldiq, NULL,
+ { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+#endif
+
+ { "stl", emit_loadstore, "stl",
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "stl_c", emit_loadstore, "stl_c",
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "stq", emit_loadstore, "stq",
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "stq_c", emit_loadstore, "stq_c",
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "stq_u", emit_loadstore, "stq_u",
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "stf", emit_loadstore, "stf",
+ { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "stg", emit_loadstore, "stg",
+ { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "sts", emit_loadstore, "sts",
+ { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "stt", emit_loadstore, "stt",
+ { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+
+ { "stb", emit_stX, (PTR) 0,
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "stw", emit_stX, (PTR) 1,
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "ustw", emit_ustX, (PTR) 1,
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "ustl", emit_ustX, (PTR) 2,
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+ { "ustq", emit_ustX, (PTR) 3,
+ { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
+
+/* Arithmetic macros */
+#if 0
+ { "absl" emit_absl, 1, { IR } },
+ { "absl" emit_absl, 2, { IR, IR } },
+ { "absl" emit_absl, 2, { EXP, IR } },
+ { "absq" emit_absq, 1, { IR } },
+ { "absq" emit_absq, 2, { IR, IR } },
+ { "absq" emit_absq, 2, { EXP, IR } },
+#endif
+
+ { "sextb", emit_sextX, (PTR) 0,
+ { MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EOA,
+ /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
+ { "sextw", emit_sextX, (PTR) 1,
+ { MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EOA,
+ /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
+
+ { "divl", emit_division, "__divl",
+ { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_IR, MACRO_EOA,
+ /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
+ { "divlu", emit_division, "__divlu",
+ { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_IR, MACRO_EOA,
+ /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
+ { "divq", emit_division, "__divq",
+ { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_IR, MACRO_EOA,
+ /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
+ { "divqu", emit_division, "__divqu",
+ { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_IR, MACRO_EOA,
+ /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
+ { "reml", emit_division, "__reml",
+ { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_IR, MACRO_EOA,
+ /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
+ { "remlu", emit_division, "__remlu",
+ { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_IR, MACRO_EOA,
+ /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
+ { "remq", emit_division, "__remq",
+ { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_IR, MACRO_EOA,
+ /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
+ { "remqu", emit_division, "__remqu",
+ { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_IR, MACRO_EOA,
+ /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
+
+ { "jsr", emit_jsrjmp, "jsr",
+ { MACRO_PIR, MACRO_EXP, MACRO_EOA,
+ MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA,
+ MACRO_EXP, MACRO_EOA } },
+ { "jmp", emit_jsrjmp, "jmp",
+ { MACRO_PIR, MACRO_EXP, MACRO_EOA,
+ MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA,
+ MACRO_EXP, MACRO_EOA } },
+ { "ret", emit_retjcr, "ret",
+ { MACRO_IR, MACRO_EXP, MACRO_EOA,
+ MACRO_IR, MACRO_EOA,
+ MACRO_PIR, MACRO_EXP, MACRO_EOA,
+ MACRO_PIR, MACRO_EOA,
+ MACRO_EXP, MACRO_EOA,
+ MACRO_EOA } },
+ { "jcr", emit_retjcr, "jcr",
+ { MACRO_IR, MACRO_EXP, MACRO_EOA,
+ MACRO_IR, MACRO_EOA,
+ MACRO_PIR, MACRO_EXP, MACRO_EOA,
+ MACRO_PIR, MACRO_EOA,
+ MACRO_EXP, MACRO_EOA,
+ MACRO_EOA } },
+ { "jsr_coroutine", emit_retjcr, "jcr",
+ { MACRO_IR, MACRO_EXP, MACRO_EOA,
+ MACRO_IR, MACRO_EOA,
+ MACRO_PIR, MACRO_EXP, MACRO_EOA,
+ MACRO_PIR, MACRO_EOA,
+ MACRO_EXP, MACRO_EOA,
+ MACRO_EOA } },
+};
+
+static const unsigned int alpha_num_macros
+ = sizeof (alpha_macros) / sizeof (*alpha_macros);
+
+/* Public interface functions */
+
+/* This function is called once, at assembler startup time. It sets
+ up all the tables, etc. that the MD part of the assembler will
+ need, that can be determined before arguments are parsed. */
+
+void
+md_begin ()
+{
+ unsigned int i;
+
+ /* Verify that X_op field is wide enough. */
+ {
+ expressionS e;
+ e.X_op = O_max;
+ assert (e.X_op == O_max);
+ }
+
+ /* Create the opcode hash table. */
+ alpha_opcode_hash = hash_new ();
+ for (i = 0; i < alpha_num_opcodes;)
+ {
+ const char *name, *retval, *slash;
+
+ name = alpha_opcodes[i].name;
+ retval = hash_insert (alpha_opcode_hash, name, (PTR) &alpha_opcodes[i]);
+ if (retval)
+ as_fatal (_("internal error: can't hash opcode `%s': %s"),
+ name, retval);
+
+ /* Some opcodes include modifiers of various sorts with a "/mod"
+ syntax, like the architecture manual suggests. However, for
+ use with gcc at least, we also need access to those same opcodes
+ without the "/". */
+
+ if ((slash = strchr (name, '/')) != NULL)
+ {
+ char *p = xmalloc (strlen (name));
+ memcpy (p, name, slash - name);
+ strcpy (p + (slash - name), slash + 1);
+
+ (void) hash_insert (alpha_opcode_hash, p, (PTR) &alpha_opcodes[i]);
+ /* Ignore failures -- the opcode table does duplicate some
+ variants in different forms, like "hw_stq" and "hw_st/q". */
+ }
+
+ while (++i < alpha_num_opcodes
+ && (alpha_opcodes[i].name == name
+ || !strcmp (alpha_opcodes[i].name, name)))
+ continue;
+ }
+
+ /* Create the macro hash table. */
+ alpha_macro_hash = hash_new ();
+ for (i = 0; i < alpha_num_macros;)
+ {
+ const char *name, *retval;
+
+ name = alpha_macros[i].name;
+ retval = hash_insert (alpha_macro_hash, name, (PTR) &alpha_macros[i]);
+ if (retval)
+ as_fatal (_("internal error: can't hash macro `%s': %s"),
+ name, retval);
+
+ while (++i < alpha_num_macros
+ && (alpha_macros[i].name == name
+ || !strcmp (alpha_macros[i].name, name)))
+ continue;
+ }
+
+ /* Construct symbols for each of the registers. */
+ for (i = 0; i < 32; ++i)
+ {
+ char name[4];
+
+ sprintf (name, "$%d", i);
+ alpha_register_table[i] = symbol_create (name, reg_section, i,
+ &zero_address_frag);
+ }
+ for (; i < 64; ++i)
+ {
+ char name[5];
+
+ sprintf (name, "$f%d", i - 32);
+ alpha_register_table[i] = symbol_create (name, reg_section, i,
+ &zero_address_frag);
+ }
+
+ /* Create the special symbols and sections we'll be using. */
+
+ /* So .sbss will get used for tiny objects. */
+ bfd_set_gp_size (stdoutput, g_switch_value);
+
+#ifdef OBJ_ECOFF
+ create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
+
+ /* For handling the GP, create a symbol that won't be output in the
+ symbol table. We'll edit it out of relocs later. */
+ alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
+ &zero_address_frag);
+#endif
+
+#ifdef OBJ_EVAX
+ create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
+#endif
+
+#ifdef OBJ_ELF
+ if (ECOFF_DEBUGGING)
+ {
+ segT sec = subseg_new (".mdebug", (subsegT) 0);
+ bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
+ bfd_set_section_alignment (stdoutput, sec, 3);
+ }
+#endif /* OBJ_ELF */
+
+ /* Create literal lookup hash table. */
+ alpha_literal_hash = hash_new ();
+
+ subseg_set (text_section, 0);
+}
+
+/* The public interface to the instruction assembler. */
+
+void
+md_assemble (str)
+ char *str;
+{
+ char opname[32]; /* Current maximum is 13. */
+ expressionS tok[MAX_INSN_ARGS];
+ int ntok, trunclen;
+ size_t opnamelen;
+
+ /* Split off the opcode. */
+ opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819");
+ trunclen = (opnamelen < sizeof (opname) - 1
+ ? opnamelen
+ : sizeof (opname) - 1);
+ memcpy (opname, str, trunclen);
+ opname[trunclen] = '\0';
+
+ /* Tokenize the rest of the line. */
+ if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
+ {
+ if (ntok != TOKENIZE_ERROR_REPORT)
+ as_bad (_("syntax error"));
+
+ return;
+ }
+
+ /* Finish it off. */
+ assemble_tokens (opname, tok, ntok, alpha_macros_on);
+}
+
+/* Round up a section's size to the appropriate boundary. */
+
+valueT
+md_section_align (seg, size)
+ segT seg;
+ valueT size;
+{
+ int align = bfd_get_section_alignment (stdoutput, seg);
+ valueT mask = ((valueT) 1 << align) - 1;
+
+ return (size + mask) & ~mask;
+}
+
+/* Turn a string in input_line_pointer into a floating point constant
+ of type TYPE, and store the appropriate bytes in *LITP. The number
+ of LITTLENUMS emitted is stored in *SIZEP. An error message is
+ returned, or NULL on OK. */
+
+/* Equal to MAX_PRECISION in atof-ieee.c. */
+#define MAX_LITTLENUMS 6
+
+extern char *vax_md_atof PARAMS ((int, char *, int *));
+
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+
+ switch (type)
+ {
+ /* VAX floats */
+ case 'G':
+ /* VAX md_atof doesn't like "G" for some reason. */
+ type = 'g';
+ case 'F':
+ case 'D':
+ return vax_md_atof (type, litP, sizeP);
+
+ /* IEEE floats */
+ case 'f':
+ prec = 2;
+ break;
+
+ case 'd':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to MD_ATOF()");
+ }
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+
+ for (wordP = words + prec - 1; prec--;)
+ {
+ md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+
+ return 0;
+}
+
+/* Take care of the target-specific command-line options. */
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case 'F':
+ alpha_nofloats_on = 1;
+ break;
+
+ case OPTION_32ADDR:
+ alpha_addr32_on = 1;
+ break;
+
+ case 'g':
+ alpha_debug = 1;
+ break;
+
+ case 'G':
+ g_switch_value = atoi (arg);
+ break;
+
+ case 'm':
+ {
+ const struct cpu_type *p;
+ for (p = cpu_types; p->name; ++p)
+ if (strcmp (arg, p->name) == 0)
+ {
+ alpha_target_name = p->name, alpha_target = p->flags;
+ goto found;
+ }
+ as_warn (_("Unknown CPU identifier `%s'"), arg);
+ found:;
+ }
+ break;
+
+#ifdef OBJ_EVAX
+ case '+': /* For g++. Hash any name > 63 chars long. */
+ alpha_flag_hash_long_names = 1;
+ break;
+
+ case 'H': /* Show new symbol after hash truncation */
+ alpha_flag_show_after_trunc = 1;
+ break;
+
+ case 'h': /* for gnu-c/vax compatibility. */
+ break;
+#endif
+
+ case OPTION_RELAX:
+ alpha_flag_relax = 1;
+ break;
+
+#ifdef OBJ_ELF
+ case OPTION_MDEBUG:
+ alpha_flag_mdebug = 1;
+ break;
+ case OPTION_NO_MDEBUG:
+ alpha_flag_mdebug = 0;
+ break;
+#endif
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Print a description of the command-line options that we accept. */
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fputs (_("\
+Alpha options:\n\
+-32addr treat addresses as 32-bit values\n\
+-F lack floating point instructions support\n\
+-mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
+ specify variant of Alpha architecture\n\
+-m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
+ these variants include PALcode opcodes\n"),
+ stream);
+#ifdef OBJ_EVAX
+ fputs (_("\
+VMS options:\n\
+-+ hash encode (don't truncate) names longer than 64 characters\n\
+-H show new symbol after hash truncation\n"),
+ stream);
+#endif
+}
+
+/* Decide from what point a pc-relative relocation is relative to,
+ relative to the pc-relative fixup. Er, relatively speaking. */
+
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_23_PCREL_S2:
+ case BFD_RELOC_ALPHA_HINT:
+ case BFD_RELOC_ALPHA_BRSGP:
+ return addr + 4;
+ default:
+ return addr;
+ }
+}
+
+/* Attempt to simplify or even eliminate a fixup. The return value is
+ ignored; perhaps it was once meaningful, but now it is historical.
+ To indicate that a fixup has been eliminated, set fixP->fx_done.
+
+ For ELF, here it is that we transform the GPDISP_HI16 reloc we used
+ internally into the GPDISP reloc used externally. We had to do
+ this so that we'd have the GPDISP_LO16 reloc as a tag to compute
+ the distance to the "lda" instruction for setting the addend to
+ GPDISP. */
+
+void
+md_apply_fix3 (fixP, valP, seg)
+ fixS *fixP;
+ valueT * valP;
+ segT seg;
+{
+ char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
+ valueT value = * valP;
+ unsigned image, size;
+
+ switch (fixP->fx_r_type)
+ {
+ /* The GPDISP relocations are processed internally with a symbol
+ referring to the current function's section; we need to drop
+ in a value which, when added to the address of the start of
+ the function, gives the desired GP. */
+ case BFD_RELOC_ALPHA_GPDISP_HI16:
+ {
+ fixS *next = fixP->fx_next;
+
+ /* With user-specified !gpdisp relocations, we can be missing
+ the matching LO16 reloc. We will have already issued an
+ error message. */
+ if (next)
+ fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
+ - fixP->fx_frag->fr_address - fixP->fx_where);
+
+ value = (value - sign_extend_16 (value)) >> 16;
+ }
+#ifdef OBJ_ELF
+ fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
+#endif
+ goto do_reloc_gp;
+
+ case BFD_RELOC_ALPHA_GPDISP_LO16:
+ value = sign_extend_16 (value);
+ fixP->fx_offset = 0;
+#ifdef OBJ_ELF
+ fixP->fx_done = 1;
+#endif
+
+ do_reloc_gp:
+ fixP->fx_addsy = section_symbol (seg);
+ md_number_to_chars (fixpos, value, 2);
+ break;
+
+ case BFD_RELOC_16:
+ if (fixP->fx_pcrel)
+ fixP->fx_r_type = BFD_RELOC_16_PCREL;
+ size = 2;
+ goto do_reloc_xx;
+ case BFD_RELOC_32:
+ if (fixP->fx_pcrel)
+ fixP->fx_r_type = BFD_RELOC_32_PCREL;
+ size = 4;
+ goto do_reloc_xx;
+ case BFD_RELOC_64:
+ if (fixP->fx_pcrel)
+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
+ size = 8;
+ do_reloc_xx:
+ if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
+ {
+ md_number_to_chars (fixpos, value, size);
+ goto done;
+ }
+ return;
+
+#ifdef OBJ_ECOFF
+ case BFD_RELOC_GPREL32:
+ assert (fixP->fx_subsy == alpha_gp_symbol);
+ fixP->fx_subsy = 0;
+ /* FIXME: inherited this obliviousness of `value' -- why? */
+ md_number_to_chars (fixpos, -alpha_gp_value, 4);
+ break;
+#else
+ case BFD_RELOC_GPREL32:
+#endif
+ case BFD_RELOC_GPREL16:
+ case BFD_RELOC_ALPHA_GPREL_HI16:
+ case BFD_RELOC_ALPHA_GPREL_LO16:
+ return;
+
+ case BFD_RELOC_23_PCREL_S2:
+ if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
+ {
+ image = bfd_getl32 (fixpos);
+ image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
+ goto write_done;
+ }
+ return;
+
+ case BFD_RELOC_ALPHA_HINT:
+ if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
+ {
+ image = bfd_getl32 (fixpos);
+ image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
+ goto write_done;
+ }
+ return;
+
+#ifdef OBJ_ELF
+ case BFD_RELOC_ALPHA_BRSGP:
+ return;
+
+ case BFD_RELOC_ALPHA_TLSGD:
+ case BFD_RELOC_ALPHA_TLSLDM:
+ case BFD_RELOC_ALPHA_GOTDTPREL16:
+ case BFD_RELOC_ALPHA_DTPREL_HI16:
+ case BFD_RELOC_ALPHA_DTPREL_LO16:
+ case BFD_RELOC_ALPHA_DTPREL16:
+ case BFD_RELOC_ALPHA_GOTTPREL16:
+ case BFD_RELOC_ALPHA_TPREL_HI16:
+ case BFD_RELOC_ALPHA_TPREL_LO16:
+ case BFD_RELOC_ALPHA_TPREL16:
+ if (fixP->fx_addsy)
+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
+ return;
+#endif
+
+#ifdef OBJ_ECOFF
+ case BFD_RELOC_ALPHA_LITERAL:
+ md_number_to_chars (fixpos, value, 2);
+ return;
+#endif
+ case BFD_RELOC_ALPHA_ELF_LITERAL:
+ case BFD_RELOC_ALPHA_LITUSE:
+ case BFD_RELOC_ALPHA_LINKAGE:
+ case BFD_RELOC_ALPHA_CODEADDR:
+ return;
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ return;
+
+ default:
+ {
+ const struct alpha_operand *operand;
+
+ if ((int) fixP->fx_r_type >= 0)
+ as_fatal (_("unhandled relocation type %s"),
+ bfd_get_reloc_code_name (fixP->fx_r_type));
+
+ assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
+ operand = &alpha_operands[-(int) fixP->fx_r_type];
+
+ /* The rest of these fixups only exist internally during symbol
+ resolution and have no representation in the object file.
+ Therefore they must be completely resolved as constants. */
+
+ if (fixP->fx_addsy != 0
+ && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("non-absolute expression in constant field"));
+
+ image = bfd_getl32 (fixpos);
+ image = insert_operand (image, operand, (offsetT) value,
+ fixP->fx_file, fixP->fx_line);
+ }
+ goto write_done;
+ }
+
+ if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
+ return;
+ else
+ {
+ as_warn_where (fixP->fx_file, fixP->fx_line,
+ _("type %d reloc done?\n"), (int) fixP->fx_r_type);
+ goto done;
+ }
+
+write_done:
+ md_number_to_chars (fixpos, image, 4);
+
+done:
+ fixP->fx_done = 1;
+}
+
+/* Look for a register name in the given symbol. */
+
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ if (*name == '$')
+ {
+ int is_float = 0, num;
+
+ switch (*++name)
+ {
+ case 'f':
+ if (name[1] == 'p' && name[2] == '\0')
+ return alpha_register_table[AXP_REG_FP];
+ is_float = 32;
+ /* FALLTHRU */
+
+ case 'r':
+ if (!ISDIGIT (*++name))
+ break;
+ /* FALLTHRU */
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (name[1] == '\0')
+ num = name[0] - '0';
+ else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0')
+ {
+ num = (name[0] - '0') * 10 + name[1] - '0';
+ if (num >= 32)
+ break;
+ }
+ else
+ break;
+
+ if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
+ as_warn (_("Used $at without \".set noat\""));
+ return alpha_register_table[num + is_float];
+
+ case 'a':
+ if (name[1] == 't' && name[2] == '\0')
+ {
+ if (!alpha_noat_on)
+ as_warn (_("Used $at without \".set noat\""));
+ return alpha_register_table[AXP_REG_AT];
+ }
+ break;
+
+ case 'g':
+ if (name[1] == 'p' && name[2] == '\0')
+ return alpha_register_table[alpha_gp_register];
+ break;
+
+ case 's':
+ if (name[1] == 'p' && name[2] == '\0')
+ return alpha_register_table[AXP_REG_SP];
+ break;
+ }
+ }
+ return NULL;
+}
+
+#ifdef OBJ_ECOFF
+/* @@@ Magic ECOFF bits. */
+
+void
+alpha_frob_ecoff_data ()
+{
+ select_gp_value ();
+ /* $zero and $f31 are read-only */
+ alpha_gprmask &= ~1;
+ alpha_fprmask &= ~1;
+}
+#endif
+
+/* Hook to remember a recently defined label so that the auto-align
+ code can adjust the symbol after we know what alignment will be
+ required. */
+
+void
+alpha_define_label (sym)
+ symbolS *sym;
+{
+ alpha_insn_label = sym;
+}
+
+/* Return true if we must always emit a reloc for a type and false if
+ there is some hope of resolving it at assembly time. */
+
+int
+alpha_force_relocation (f)
+ fixS *f;
+{
+ if (alpha_flag_relax)
+ return 1;
+
+ switch (f->fx_r_type)
+ {
+ case BFD_RELOC_ALPHA_GPDISP_HI16:
+ case BFD_RELOC_ALPHA_GPDISP_LO16:
+ case BFD_RELOC_ALPHA_GPDISP:
+ case BFD_RELOC_ALPHA_LITERAL:
+ case BFD_RELOC_ALPHA_ELF_LITERAL:
+ case BFD_RELOC_ALPHA_LITUSE:
+ case BFD_RELOC_GPREL16:
+ case BFD_RELOC_GPREL32:
+ case BFD_RELOC_ALPHA_GPREL_HI16:
+ case BFD_RELOC_ALPHA_GPREL_LO16:
+ case BFD_RELOC_ALPHA_LINKAGE:
+ case BFD_RELOC_ALPHA_CODEADDR:
+ case BFD_RELOC_ALPHA_BRSGP:
+ case BFD_RELOC_ALPHA_TLSGD:
+ case BFD_RELOC_ALPHA_TLSLDM:
+ case BFD_RELOC_ALPHA_GOTDTPREL16:
+ case BFD_RELOC_ALPHA_DTPREL_HI16:
+ case BFD_RELOC_ALPHA_DTPREL_LO16:
+ case BFD_RELOC_ALPHA_DTPREL16:
+ case BFD_RELOC_ALPHA_GOTTPREL16:
+ case BFD_RELOC_ALPHA_TPREL_HI16:
+ case BFD_RELOC_ALPHA_TPREL_LO16:
+ case BFD_RELOC_ALPHA_TPREL16:
+ return 1;
+
+ default:
+ break;
+ }
+
+ return generic_force_reloc (f);
+}
+
+/* Return true if we can partially resolve a relocation now. */
+
+int
+alpha_fix_adjustable (f)
+ fixS *f;
+{
+ /* Are there any relocation types for which we must generate a reloc
+ but we can adjust the values contained within it? */
+ switch (f->fx_r_type)
+ {
+ case BFD_RELOC_ALPHA_GPDISP_HI16:
+ case BFD_RELOC_ALPHA_GPDISP_LO16:
+ case BFD_RELOC_ALPHA_GPDISP:
+ return 0;
+
+ case BFD_RELOC_ALPHA_LITERAL:
+ case BFD_RELOC_ALPHA_ELF_LITERAL:
+ case BFD_RELOC_ALPHA_LITUSE:
+ case BFD_RELOC_ALPHA_LINKAGE:
+ case BFD_RELOC_ALPHA_CODEADDR:
+ return 1;
+
+ case BFD_RELOC_VTABLE_ENTRY:
+ case BFD_RELOC_VTABLE_INHERIT:
+ return 0;
+
+ case BFD_RELOC_GPREL16:
+ case BFD_RELOC_GPREL32:
+ case BFD_RELOC_ALPHA_GPREL_HI16:
+ case BFD_RELOC_ALPHA_GPREL_LO16:
+ case BFD_RELOC_23_PCREL_S2:
+ case BFD_RELOC_32:
+ case BFD_RELOC_64:
+ case BFD_RELOC_ALPHA_HINT:
+ return 1;
+
+ case BFD_RELOC_ALPHA_TLSGD:
+ case BFD_RELOC_ALPHA_TLSLDM:
+ case BFD_RELOC_ALPHA_GOTDTPREL16:
+ case BFD_RELOC_ALPHA_DTPREL_HI16:
+ case BFD_RELOC_ALPHA_DTPREL_LO16:
+ case BFD_RELOC_ALPHA_DTPREL16:
+ case BFD_RELOC_ALPHA_GOTTPREL16:
+ case BFD_RELOC_ALPHA_TPREL_HI16:
+ case BFD_RELOC_ALPHA_TPREL_LO16:
+ case BFD_RELOC_ALPHA_TPREL16:
+ /* ??? No idea why we can't return a reference to .tbss+10, but
+ we're preventing this in the other assemblers. Follow for now. */
+ return 0;
+
+#ifdef OBJ_ELF
+ case BFD_RELOC_ALPHA_BRSGP:
+ /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
+ let it get resolved at assembly time. */
+ {
+ symbolS *sym = f->fx_addsy;
+ const char *name;
+ int offset = 0;
+
+ if (generic_force_reloc (f))
+ return 0;
+
+ switch (S_GET_OTHER (sym) & STO_ALPHA_STD_GPLOAD)
+ {
+ case STO_ALPHA_NOPV:
+ break;
+ case STO_ALPHA_STD_GPLOAD:
+ offset = 8;
+ break;
+ default:
+ if (S_IS_LOCAL (sym))
+ name = "<local>";
+ else
+ name = S_GET_NAME (sym);
+ as_bad_where (f->fx_file, f->fx_line,
+ _("!samegp reloc against symbol without .prologue: %s"),
+ name);
+ break;
+ }
+ f->fx_r_type = BFD_RELOC_23_PCREL_S2;
+ f->fx_offset += offset;
+ return 1;
+ }
+#endif
+
+ default:
+ return 1;
+ }
+ /*NOTREACHED*/
+}
+
+/* Generate the BFD reloc to be stuck in the object file from the
+ fixup used internally in the assembler. */
+
+arelent *
+tc_gen_reloc (sec, fixp)
+ asection *sec ATTRIBUTE_UNUSED;
+ fixS *fixp;
+{
+ arelent *reloc;
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+
+ /* Make sure none of our internal relocations make it this far.
+ They'd better have been fully resolved by this point. */
+ assert ((int) fixp->fx_r_type > 0);
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+ if (reloc->howto == NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("cannot represent `%s' relocation in object file"),
+ bfd_get_reloc_code_name (fixp->fx_r_type));
+ return NULL;
+ }
+
+ if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
+ {
+ as_fatal (_("internal error? cannot generate `%s' relocation"),
+ bfd_get_reloc_code_name (fixp->fx_r_type));
+ }
+ assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
+
+#ifdef OBJ_ECOFF
+ if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
+ {
+ /* Fake out bfd_perform_relocation. sigh. */
+ reloc->addend = -alpha_gp_value;
+ }
+ else
+#endif
+ {
+ reloc->addend = fixp->fx_offset;
+#ifdef OBJ_ELF
+ /* Ohhh, this is ugly. The problem is that if this is a local global
+ symbol, the relocation will entirely be performed at link time, not
+ at assembly time. bfd_perform_reloc doesn't know about this sort
+ of thing, and as a result we need to fake it out here. */
+ if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
+ || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)
+ || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL))
+ && !S_IS_COMMON (fixp->fx_addsy))
+ reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
+#endif
+ }
+
+ return reloc;
+}
+
+/* Parse a register name off of the input_line and return a register
+ number. Gets md_undefined_symbol above to do the register name
+ matching for us.
+
+ Only called as a part of processing the ECOFF .frame directive. */
+
+int
+tc_get_register (frame)
+ int frame ATTRIBUTE_UNUSED;
+{
+ int framereg = AXP_REG_SP;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '$')
+ {
+ char *s = input_line_pointer;
+ char c = get_symbol_end ();
+ symbolS *sym = md_undefined_symbol (s);
+
+ *strchr (s, '\0') = c;
+ if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
+ goto found;
+ }
+ as_warn (_("frame reg expected, using $%d."), framereg);
+
+found:
+ note_gpreg (framereg);
+ return framereg;
+}
+
+/* This is called before the symbol table is processed. In order to
+ work with gcc when using mips-tfile, we must keep all local labels.
+ However, in other cases, we want to discard them. If we were
+ called with -g, but we didn't see any debugging information, it may
+ mean that gcc is smuggling debugging information through to
+ mips-tfile, in which case we must generate all local labels. */
+
+#ifdef OBJ_ECOFF
+
+void
+alpha_frob_file_before_adjust ()
+{
+ if (alpha_debug != 0
+ && ! ecoff_debugging_seen)
+ flag_keep_locals = 1;
+}
+
+#endif /* OBJ_ECOFF */
+
+static struct alpha_reloc_tag *
+get_alpha_reloc_tag (sequence)
+ long sequence;
+{
+ char buffer[ALPHA_RELOC_DIGITS];
+ struct alpha_reloc_tag *info;
+
+ sprintf (buffer, "!%ld", sequence);
+
+ info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
+ if (! info)
+ {
+ size_t len = strlen (buffer);
+ const char *errmsg;
+
+ info = (struct alpha_reloc_tag *)
+ xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
+
+ info->segment = now_seg;
+ info->sequence = sequence;
+ strcpy (info->string, buffer);
+ errmsg = hash_insert (alpha_literal_hash, info->string, (PTR) info);
+ if (errmsg)
+ as_fatal (errmsg);
+ }
+
+ return info;
+}
+
+/* Before the relocations are written, reorder them, so that user
+ supplied !lituse relocations follow the appropriate !literal
+ relocations, and similarly for !gpdisp relocations. */
+
+void
+alpha_before_fix ()
+{
+ if (alpha_literal_hash)
+ bfd_map_over_sections (stdoutput, alpha_adjust_relocs, NULL);
+}
+
+static void
+alpha_adjust_relocs (abfd, sec, ptr)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *sec;
+ PTR ptr ATTRIBUTE_UNUSED;
+{
+ segment_info_type *seginfo = seg_info (sec);
+ fixS **prevP;
+ fixS *fixp;
+ fixS *next;
+ fixS *slave;
+
+ /* If seginfo is NULL, we did not create this section; don't do
+ anything with it. By using a pointer to a pointer, we can update
+ the links in place. */
+ if (seginfo == NULL)
+ return;
+
+ /* If there are no relocations, skip the section. */
+ if (! seginfo->fix_root)
+ return;
+
+ /* First rebuild the fixup chain without the explicit lituse and
+ gpdisp_lo16 relocs. */
+ prevP = &seginfo->fix_root;
+ for (fixp = seginfo->fix_root; fixp; fixp = next)
+ {
+ next = fixp->fx_next;
+ fixp->fx_next = (fixS *) 0;
+
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_ALPHA_LITUSE:
+ if (fixp->tc_fix_data.info->n_master == 0)
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("No !literal!%ld was found"),
+ fixp->tc_fix_data.info->sequence);
+#ifdef RELOC_OP_P
+ if (fixp->fx_offset == LITUSE_ALPHA_TLSGD)
+ {
+ if (! fixp->tc_fix_data.info->saw_tlsgd)
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("No !tlsgd!%ld was found"),
+ fixp->tc_fix_data.info->sequence);
+ }
+ else if (fixp->fx_offset == LITUSE_ALPHA_TLSLDM)
+ {
+ if (! fixp->tc_fix_data.info->saw_tlsldm)
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("No !tlsldm!%ld was found"),
+ fixp->tc_fix_data.info->sequence);
+ }
+#endif
+ break;
+
+ case BFD_RELOC_ALPHA_GPDISP_LO16:
+ if (fixp->tc_fix_data.info->n_master == 0)
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("No ldah !gpdisp!%ld was found"),
+ fixp->tc_fix_data.info->sequence);
+ break;
+
+ case BFD_RELOC_ALPHA_ELF_LITERAL:
+ if (fixp->tc_fix_data.info
+ && (fixp->tc_fix_data.info->saw_tlsgd
+ || fixp->tc_fix_data.info->saw_tlsldm))
+ break;
+ /* FALLTHRU */
+
+ default:
+ *prevP = fixp;
+ prevP = &fixp->fx_next;
+ break;
+ }
+ }
+
+ /* Go back and re-chain dependent relocations. They are currently
+ linked through the next_reloc field in reverse order, so as we
+ go through the next_reloc chain, we effectively reverse the chain
+ once again.
+
+ Except if there is more than one !literal for a given sequence
+ number. In that case, the programmer and/or compiler is not sure
+ how control flows from literal to lituse, and we can't be sure to
+ get the relaxation correct.
+
+ ??? Well, actually we could, if there are enough lituses such that
+ we can make each literal have at least one of each lituse type
+ present. Not implemented.
+
+ Also suppress the optimization if the !literals/!lituses are spread
+ in different segments. This can happen with "intersting" uses of
+ inline assembly; examples are present in the Linux kernel semaphores. */
+
+ for (fixp = seginfo->fix_root; fixp; fixp = next)
+ {
+ next = fixp->fx_next;
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_ALPHA_TLSGD:
+ case BFD_RELOC_ALPHA_TLSLDM:
+ if (!fixp->tc_fix_data.info)
+ break;
+ if (fixp->tc_fix_data.info->n_master == 0)
+ break;
+ else if (fixp->tc_fix_data.info->n_master > 1)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("too many !literal!%ld for %s"),
+ fixp->tc_fix_data.info->sequence,
+ (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD
+ ? "!tlsgd" : "!tlsldm"));
+ break;
+ }
+
+ fixp->tc_fix_data.info->master->fx_next = fixp->fx_next;
+ fixp->fx_next = fixp->tc_fix_data.info->master;
+ fixp = fixp->fx_next;
+ /* FALLTHRU */
+
+ case BFD_RELOC_ALPHA_ELF_LITERAL:
+ if (fixp->tc_fix_data.info
+ && fixp->tc_fix_data.info->n_master == 1
+ && ! fixp->tc_fix_data.info->multi_section_p)
+ {
+ for (slave = fixp->tc_fix_data.info->slaves;
+ slave != (fixS *) 0;
+ slave = slave->tc_fix_data.next_reloc)
+ {
+ slave->fx_next = fixp->fx_next;
+ fixp->fx_next = slave;
+ }
+ }
+ break;
+
+ case BFD_RELOC_ALPHA_GPDISP_HI16:
+ if (fixp->tc_fix_data.info->n_slaves == 0)
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("No lda !gpdisp!%ld was found"),
+ fixp->tc_fix_data.info->sequence);
+ else
+ {
+ slave = fixp->tc_fix_data.info->slaves;
+ slave->fx_next = next;
+ fixp->fx_next = slave;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+#ifdef DEBUG_ALPHA
+static void
+debug_exp (tok, ntok)
+ expressionS tok[];
+ int ntok;
+{
+ int i;
+
+ fprintf (stderr, "debug_exp: %d tokens", ntok);
+ for (i = 0; i < ntok; i++)
+ {
+ expressionS *t = &tok[i];
+ const char *name;
+
+ switch (t->X_op)
+ {
+ default: name = "unknown"; break;
+ case O_illegal: name = "O_illegal"; break;
+ case O_absent: name = "O_absent"; break;
+ case O_constant: name = "O_constant"; break;
+ case O_symbol: name = "O_symbol"; break;
+ case O_symbol_rva: name = "O_symbol_rva"; break;
+ case O_register: name = "O_register"; break;
+ case O_big: name = "O_big"; break;
+ case O_uminus: name = "O_uminus"; break;
+ case O_bit_not: name = "O_bit_not"; break;
+ case O_logical_not: name = "O_logical_not"; break;
+ case O_multiply: name = "O_multiply"; break;
+ case O_divide: name = "O_divide"; break;
+ case O_modulus: name = "O_modulus"; break;
+ case O_left_shift: name = "O_left_shift"; break;
+ case O_right_shift: name = "O_right_shift"; break;
+ case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
+ case O_bit_or_not: name = "O_bit_or_not"; break;
+ case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
+ case O_bit_and: name = "O_bit_and"; break;
+ case O_add: name = "O_add"; break;
+ case O_subtract: name = "O_subtract"; break;
+ case O_eq: name = "O_eq"; break;
+ case O_ne: name = "O_ne"; break;
+ case O_lt: name = "O_lt"; break;
+ case O_le: name = "O_le"; break;
+ case O_ge: name = "O_ge"; break;
+ case O_gt: name = "O_gt"; break;
+ case O_logical_and: name = "O_logical_and"; break;
+ case O_logical_or: name = "O_logical_or"; break;
+ case O_index: name = "O_index"; break;
+ case O_pregister: name = "O_pregister"; break;
+ case O_cpregister: name = "O_cpregister"; break;
+ case O_literal: name = "O_literal"; break;
+ case O_lituse_addr: name = "O_lituse_addr"; break;
+ case O_lituse_base: name = "O_lituse_base"; break;
+ case O_lituse_bytoff: name = "O_lituse_bytoff"; break;
+ case O_lituse_jsr: name = "O_lituse_jsr"; break;
+ case O_lituse_tlsgd: name = "O_lituse_tlsgd"; break;
+ case O_lituse_tlsldm: name = "O_lituse_tlsldm"; break;
+ case O_gpdisp: name = "O_gpdisp"; break;
+ case O_gprelhigh: name = "O_gprelhigh"; break;
+ case O_gprellow: name = "O_gprellow"; break;
+ case O_gprel: name = "O_gprel"; break;
+ case O_samegp: name = "O_samegp"; break;
+ case O_tlsgd: name = "O_tlsgd"; break;
+ case O_tlsldm: name = "O_tlsldm"; break;
+ case O_gotdtprel: name = "O_gotdtprel"; break;
+ case O_dtprelhi: name = "O_dtprelhi"; break;
+ case O_dtprello: name = "O_dtprello"; break;
+ case O_dtprel: name = "O_dtprel"; break;
+ case O_gottprel: name = "O_gottprel"; break;
+ case O_tprelhi: name = "O_tprelhi"; break;
+ case O_tprello: name = "O_tprello"; break;
+ case O_tprel: name = "O_tprel"; break;
+ }
+
+ fprintf (stderr, ", %s(%s, %s, %d)", name,
+ (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
+ (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
+ (int) t->X_add_number);
+ }
+ fprintf (stderr, "\n");
+ fflush (stderr);
+}
+#endif
+
+/* Parse the arguments to an opcode. */
+
+static int
+tokenize_arguments (str, tok, ntok)
+ char *str;
+ expressionS tok[];
+ int ntok;
+{
+ expressionS *end_tok = tok + ntok;
+ char *old_input_line_pointer;
+ int saw_comma = 0, saw_arg = 0;
+#ifdef DEBUG_ALPHA
+ expressionS *orig_tok = tok;
+#endif
+#ifdef RELOC_OP_P
+ char *p;
+ const struct alpha_reloc_op_tag *r;
+ int c, i;
+ size_t len;
+ int reloc_found_p = 0;
+#endif
+
+ memset (tok, 0, sizeof (*tok) * ntok);
+
+ /* Save and restore input_line_pointer around this function. */
+ old_input_line_pointer = input_line_pointer;
+ input_line_pointer = str;
+
+#ifdef RELOC_OP_P
+ /* ??? Wrest control of ! away from the regular expression parser. */
+ is_end_of_line[(unsigned char) '!'] = 1;
+#endif
+
+ while (tok < end_tok && *input_line_pointer)
+ {
+ SKIP_WHITESPACE ();
+ switch (*input_line_pointer)
+ {
+ case '\0':
+ goto fini;
+
+#ifdef RELOC_OP_P
+ case '!':
+ /* A relocation operand can be placed after the normal operand on an
+ assembly language statement, and has the following form:
+ !relocation_type!sequence_number. */
+ if (reloc_found_p)
+ {
+ /* Only support one relocation op per insn. */
+ as_bad (_("More than one relocation op per insn"));
+ goto err_report;
+ }
+
+ if (!saw_arg)
+ goto err;
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ p = input_line_pointer;
+ c = get_symbol_end ();
+
+ /* Parse !relocation_type. */
+ len = input_line_pointer - p;
+ if (len == 0)
+ {
+ as_bad (_("No relocation operand"));
+ goto err_report;
+ }
+
+ r = &alpha_reloc_op[0];
+ for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
+ if (len == r->length && memcmp (p, r->name, len) == 0)
+ break;
+ if (i < 0)
+ {
+ as_bad (_("Unknown relocation operand: !%s"), p);
+ goto err_report;
+ }
+
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '!')
+ {
+ if (r->require_seq)
+ {
+ as_bad (_("no sequence number after !%s"), p);
+ goto err_report;
+ }
+
+ tok->X_add_number = 0;
+ }
+ else
+ {
+ if (! r->allow_seq)
+ {
+ as_bad (_("!%s does not use a sequence number"), p);
+ goto err_report;
+ }
+
+ input_line_pointer++;
+
+ /* Parse !sequence_number. */
+ expression (tok);
+ if (tok->X_op != O_constant || tok->X_add_number <= 0)
+ {
+ as_bad (_("Bad sequence number: !%s!%s"),
+ r->name, input_line_pointer);
+ goto err_report;
+ }
+ }
+
+ tok->X_op = r->op;
+ reloc_found_p = 1;
+ ++tok;
+ break;
+#endif /* RELOC_OP_P */
+
+ case ',':
+ ++input_line_pointer;
+ if (saw_comma || !saw_arg)
+ goto err;
+ saw_comma = 1;
+ break;
+
+ case '(':
+ {
+ char *hold = input_line_pointer++;
+
+ /* First try for parenthesized register ... */
+ expression (tok);
+ if (*input_line_pointer == ')' && tok->X_op == O_register)
+ {
+ tok->X_op = (saw_comma ? O_cpregister : O_pregister);
+ saw_comma = 0;
+ saw_arg = 1;
+ ++input_line_pointer;
+ ++tok;
+ break;
+ }
+
+ /* ... then fall through to plain expression. */
+ input_line_pointer = hold;
+ }
+
+ default:
+ if (saw_arg && !saw_comma)
+ goto err;
+
+ expression (tok);
+ if (tok->X_op == O_illegal || tok->X_op == O_absent)
+ goto err;
+
+ saw_comma = 0;
+ saw_arg = 1;
+ ++tok;
+ break;
+ }
+ }
+
+fini:
+ if (saw_comma)
+ goto err;
+ input_line_pointer = old_input_line_pointer;
+
+#ifdef DEBUG_ALPHA
+ debug_exp (orig_tok, ntok - (end_tok - tok));
+#endif
+#ifdef RELOC_OP_P
+ is_end_of_line[(unsigned char) '!'] = 0;
+#endif
+
+ return ntok - (end_tok - tok);
+
+err:
+#ifdef RELOC_OP_P
+ is_end_of_line[(unsigned char) '!'] = 0;
+#endif
+ input_line_pointer = old_input_line_pointer;
+ return TOKENIZE_ERROR;
+
+#ifdef RELOC_OP_P
+err_report:
+ is_end_of_line[(unsigned char) '!'] = 0;
+#endif
+ input_line_pointer = old_input_line_pointer;
+ return TOKENIZE_ERROR_REPORT;
+}
+
+/* Search forward through all variants of an opcode looking for a
+ syntax match. */
+
+static const struct alpha_opcode *
+find_opcode_match (first_opcode, tok, pntok, pcpumatch)
+ const struct alpha_opcode *first_opcode;
+ const expressionS *tok;
+ int *pntok;
+ int *pcpumatch;
+{
+ const struct alpha_opcode *opcode = first_opcode;
+ int ntok = *pntok;
+ int got_cpu_match = 0;
+
+ do
+ {
+ const unsigned char *opidx;
+ int tokidx = 0;
+
+ /* Don't match opcodes that don't exist on this architecture. */
+ if (!(opcode->flags & alpha_target))
+ goto match_failed;
+
+ got_cpu_match = 1;
+
+ for (opidx = opcode->operands; *opidx; ++opidx)
+ {
+ const struct alpha_operand *operand = &alpha_operands[*opidx];
+
+ /* Only take input from real operands. */
+ if (operand->flags & AXP_OPERAND_FAKE)
+ continue;
+
+ /* When we expect input, make sure we have it. */
+ if (tokidx >= ntok)
+ {
+ if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
+ goto match_failed;
+ continue;
+ }
+
+ /* Match operand type with expression type. */
+ switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
+ {
+ case AXP_OPERAND_IR:
+ if (tok[tokidx].X_op != O_register
+ || !is_ir_num (tok[tokidx].X_add_number))
+ goto match_failed;
+ break;
+ case AXP_OPERAND_FPR:
+ if (tok[tokidx].X_op != O_register
+ || !is_fpr_num (tok[tokidx].X_add_number))
+ goto match_failed;
+ break;
+ case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
+ if (tok[tokidx].X_op != O_pregister
+ || !is_ir_num (tok[tokidx].X_add_number))
+ goto match_failed;
+ break;
+ case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
+ if (tok[tokidx].X_op != O_cpregister
+ || !is_ir_num (tok[tokidx].X_add_number))
+ goto match_failed;
+ break;
+
+ case AXP_OPERAND_RELATIVE:
+ case AXP_OPERAND_SIGNED:
+ case AXP_OPERAND_UNSIGNED:
+ switch (tok[tokidx].X_op)
+ {
+ case O_illegal:
+ case O_absent:
+ case O_register:
+ case O_pregister:
+ case O_cpregister:
+ goto match_failed;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ /* Everything else should have been fake. */
+ abort ();
+ }
+ ++tokidx;
+ }
+
+ /* Possible match -- did we use all of our input? */
+ if (tokidx == ntok)
+ {
+ *pntok = ntok;
+ return opcode;
+ }
+
+ match_failed:;
+ }
+ while (++opcode - alpha_opcodes < (int) alpha_num_opcodes
+ && !strcmp (opcode->name, first_opcode->name));
+
+ if (*pcpumatch)
+ *pcpumatch = got_cpu_match;
+
+ return NULL;
+}
+
+/* Search forward through all variants of a macro looking for a syntax
+ match. */
+
+static const struct alpha_macro *
+find_macro_match (first_macro, tok, pntok)
+ const struct alpha_macro *first_macro;
+ const expressionS *tok;
+ int *pntok;
+{
+ const struct alpha_macro *macro = first_macro;
+ int ntok = *pntok;
+
+ do
+ {
+ const enum alpha_macro_arg *arg = macro->argsets;
+ int tokidx = 0;
+
+ while (*arg)
+ {
+ switch (*arg)
+ {
+ case MACRO_EOA:
+ if (tokidx == ntok)
+ return macro;
+ else
+ tokidx = 0;
+ break;
+
+ /* Index register. */
+ case MACRO_IR:
+ if (tokidx >= ntok || tok[tokidx].X_op != O_register
+ || !is_ir_num (tok[tokidx].X_add_number))
+ goto match_failed;
+ ++tokidx;
+ break;
+
+ /* Parenthesized index register. */
+ case MACRO_PIR:
+ if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
+ || !is_ir_num (tok[tokidx].X_add_number))
+ goto match_failed;
+ ++tokidx;
+ break;
+
+ /* Optional parenthesized index register. */
+ case MACRO_OPIR:
+ if (tokidx < ntok && tok[tokidx].X_op == O_pregister
+ && is_ir_num (tok[tokidx].X_add_number))
+ ++tokidx;
+ break;
+
+ /* Leading comma with a parenthesized index register. */
+ case MACRO_CPIR:
+ if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
+ || !is_ir_num (tok[tokidx].X_add_number))
+ goto match_failed;
+ ++tokidx;
+ break;
+
+ /* Floating point register. */
+ case MACRO_FPR:
+ if (tokidx >= ntok || tok[tokidx].X_op != O_register
+ || !is_fpr_num (tok[tokidx].X_add_number))
+ goto match_failed;
+ ++tokidx;
+ break;
+
+ /* Normal expression. */
+ case MACRO_EXP:
+ if (tokidx >= ntok)
+ goto match_failed;
+ switch (tok[tokidx].X_op)
+ {
+ case O_illegal:
+ case O_absent:
+ case O_register:
+ case O_pregister:
+ case O_cpregister:
+ case O_literal:
+ case O_lituse_base:
+ case O_lituse_bytoff:
+ case O_lituse_jsr:
+ case O_gpdisp:
+ case O_gprelhigh:
+ case O_gprellow:
+ case O_gprel:
+ case O_samegp:
+ goto match_failed;
+
+ default:
+ break;
+ }
+ ++tokidx;
+ break;
+
+ match_failed:
+ while (*arg != MACRO_EOA)
+ ++arg;
+ tokidx = 0;
+ break;
+ }
+ ++arg;
+ }
+ }
+ while (++macro - alpha_macros < (int) alpha_num_macros
+ && !strcmp (macro->name, first_macro->name));
+
+ return NULL;
+}
+
+/* Insert an operand value into an instruction. */
+
+static unsigned
+insert_operand (insn, operand, val, file, line)
+ unsigned insn;
+ const struct alpha_operand *operand;
+ offsetT val;
+ char *file;
+ unsigned line;
+{
+ if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
+ {
+ offsetT min, max;
+
+ if (operand->flags & AXP_OPERAND_SIGNED)
+ {
+ max = (1 << (operand->bits - 1)) - 1;
+ min = -(1 << (operand->bits - 1));
+ }
+ else
+ {
+ max = (1 << operand->bits) - 1;
+ min = 0;
+ }
+
+ if (val < min || val > max)
+ {
+ const char *err =
+ _("operand out of range (%s not between %d and %d)");
+ char buf[sizeof (val) * 3 + 2];
+
+ sprint_value (buf, val);
+ if (file)
+ as_warn_where (file, line, err, buf, min, max);
+ else
+ as_warn (err, buf, min, max);
+ }
+ }
+
+ if (operand->insert)
+ {
+ const char *errmsg = NULL;
+
+ insn = (*operand->insert) (insn, val, &errmsg);
+ if (errmsg)
+ as_warn (errmsg);
+ }
+ else
+ insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
+
+ return insn;
+}
+
+/* Turn an opcode description and a set of arguments into
+ an instruction and a fixup. */
+
+static void
+assemble_insn (opcode, tok, ntok, insn, reloc)
+ const struct alpha_opcode *opcode;
+ const expressionS *tok;
+ int ntok;
+ struct alpha_insn *insn;
+ bfd_reloc_code_real_type reloc;
+{
+ const struct alpha_operand *reloc_operand = NULL;
+ const expressionS *reloc_exp = NULL;
+ const unsigned char *argidx;
+ unsigned image;
+ int tokidx = 0;
+
+ memset (insn, 0, sizeof (*insn));
+ image = opcode->opcode;
+
+ for (argidx = opcode->operands; *argidx; ++argidx)
+ {
+ const struct alpha_operand *operand = &alpha_operands[*argidx];
+ const expressionS *t = (const expressionS *) 0;
+
+ if (operand->flags & AXP_OPERAND_FAKE)
+ {
+ /* fake operands take no value and generate no fixup */
+ image = insert_operand (image, operand, 0, NULL, 0);
+ continue;
+ }
+
+ if (tokidx >= ntok)
+ {
+ switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
+ {
+ case AXP_OPERAND_DEFAULT_FIRST:
+ t = &tok[0];
+ break;
+ case AXP_OPERAND_DEFAULT_SECOND:
+ t = &tok[1];
+ break;
+ case AXP_OPERAND_DEFAULT_ZERO:
+ {
+ static expressionS zero_exp;
+ t = &zero_exp;
+ zero_exp.X_op = O_constant;
+ zero_exp.X_unsigned = 1;
+ }
+ break;
+ default:
+ abort ();
+ }
+ }
+ else
+ t = &tok[tokidx++];
+
+ switch (t->X_op)
+ {
+ case O_register:
+ case O_pregister:
+ case O_cpregister:
+ image = insert_operand (image, operand, regno (t->X_add_number),
+ NULL, 0);
+ break;
+
+ case O_constant:
+ image = insert_operand (image, operand, t->X_add_number, NULL, 0);
+ assert (reloc_operand == NULL);
+ reloc_operand = operand;
+ reloc_exp = t;
+ break;
+
+ default:
+ /* This is only 0 for fields that should contain registers,
+ which means this pattern shouldn't have matched. */
+ if (operand->default_reloc == 0)
+ abort ();
+
+ /* There is one special case for which an insn receives two
+ relocations, and thus the user-supplied reloc does not
+ override the operand reloc. */
+ if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
+ {
+ struct alpha_fixup *fixup;
+
+ if (insn->nfixups >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+
+ fixup = &insn->fixups[insn->nfixups++];
+ fixup->exp = *t;
+ fixup->reloc = BFD_RELOC_ALPHA_HINT;
+ }
+ else
+ {
+ if (reloc == BFD_RELOC_UNUSED)
+ reloc = operand->default_reloc;
+
+ assert (reloc_operand == NULL);
+ reloc_operand = operand;
+ reloc_exp = t;
+ }
+ break;
+ }
+ }
+
+ if (reloc != BFD_RELOC_UNUSED)
+ {
+ struct alpha_fixup *fixup;
+
+ if (insn->nfixups >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+
+ /* ??? My but this is hacky. But the OSF/1 assembler uses the same
+ relocation tag for both ldah and lda with gpdisp. Choose the
+ correct internal relocation based on the opcode. */
+ if (reloc == BFD_RELOC_ALPHA_GPDISP)
+ {
+ if (strcmp (opcode->name, "ldah") == 0)
+ reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
+ else if (strcmp (opcode->name, "lda") == 0)
+ reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
+ else
+ as_bad (_("invalid relocation for instruction"));
+ }
+
+ /* If this is a real relocation (as opposed to a lituse hint), then
+ the relocation width should match the operand width. */
+ else if (reloc < BFD_RELOC_UNUSED)
+ {
+ reloc_howto_type *reloc_howto
+ = bfd_reloc_type_lookup (stdoutput, reloc);
+ if (reloc_howto->bitsize != reloc_operand->bits)
+ {
+ as_bad (_("invalid relocation for field"));
+ return;
+ }
+ }
+
+ fixup = &insn->fixups[insn->nfixups++];
+ if (reloc_exp)
+ fixup->exp = *reloc_exp;
+ else
+ fixup->exp.X_op = O_absent;
+ fixup->reloc = reloc;
+ }
+
+ insn->insn = image;
+}
+
+/* Actually output an instruction with its fixup. */
+
+static void
+emit_insn (insn)
+ struct alpha_insn *insn;
+{
+ char *f;
+ int i;
+
+ /* Take care of alignment duties. */
+ if (alpha_auto_align_on && alpha_current_align < 2)
+ alpha_align (2, (char *) NULL, alpha_insn_label, 0);
+ if (alpha_current_align > 2)
+ alpha_current_align = 2;
+ alpha_insn_label = NULL;
+
+ /* Write out the instruction. */
+ f = frag_more (4);
+ md_number_to_chars (f, insn->insn, 4);
+
+#ifdef OBJ_ELF
+ dwarf2_emit_insn (4);
+#endif
+
+ /* Apply the fixups in order. */
+ for (i = 0; i < insn->nfixups; ++i)
+ {
+ const struct alpha_operand *operand = (const struct alpha_operand *) 0;
+ struct alpha_fixup *fixup = &insn->fixups[i];
+ struct alpha_reloc_tag *info = NULL;
+ int size, pcrel;
+ fixS *fixP;
+
+ /* Some fixups are only used internally and so have no howto. */
+ if ((int) fixup->reloc < 0)
+ {
+ operand = &alpha_operands[-(int) fixup->reloc];
+ size = 4;
+ pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
+ }
+ else if (fixup->reloc > BFD_RELOC_UNUSED
+ || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
+ || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
+ {
+ size = 2;
+ pcrel = 0;
+ }
+ else
+ {
+ reloc_howto_type *reloc_howto
+ = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
+ assert (reloc_howto);
+
+ size = bfd_get_reloc_size (reloc_howto);
+ assert (size >= 1 && size <= 4);
+
+ pcrel = reloc_howto->pc_relative;
+ }
+
+ fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
+ &fixup->exp, pcrel, fixup->reloc);
+
+ /* Turn off complaints that the addend is too large for some fixups,
+ and copy in the sequence number for the explicit relocations. */
+ switch (fixup->reloc)
+ {
+ case BFD_RELOC_ALPHA_HINT:
+ case BFD_RELOC_GPREL32:
+ case BFD_RELOC_GPREL16:
+ case BFD_RELOC_ALPHA_GPREL_HI16:
+ case BFD_RELOC_ALPHA_GPREL_LO16:
+ case BFD_RELOC_ALPHA_GOTDTPREL16:
+ case BFD_RELOC_ALPHA_DTPREL_HI16:
+ case BFD_RELOC_ALPHA_DTPREL_LO16:
+ case BFD_RELOC_ALPHA_DTPREL16:
+ case BFD_RELOC_ALPHA_GOTTPREL16:
+ case BFD_RELOC_ALPHA_TPREL_HI16:
+ case BFD_RELOC_ALPHA_TPREL_LO16:
+ case BFD_RELOC_ALPHA_TPREL16:
+ fixP->fx_no_overflow = 1;
+ break;
+
+ case BFD_RELOC_ALPHA_GPDISP_HI16:
+ fixP->fx_no_overflow = 1;
+ fixP->fx_addsy = section_symbol (now_seg);
+ fixP->fx_offset = 0;
+
+ info = get_alpha_reloc_tag (insn->sequence);
+ if (++info->n_master > 1)
+ as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
+ if (info->segment != now_seg)
+ as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
+ insn->sequence);
+ fixP->tc_fix_data.info = info;
+ break;
+
+ case BFD_RELOC_ALPHA_GPDISP_LO16:
+ fixP->fx_no_overflow = 1;
+
+ info = get_alpha_reloc_tag (insn->sequence);
+ if (++info->n_slaves > 1)
+ as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
+ if (info->segment != now_seg)
+ as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
+ insn->sequence);
+ fixP->tc_fix_data.info = info;
+ info->slaves = fixP;
+ break;
+
+ case BFD_RELOC_ALPHA_LITERAL:
+ case BFD_RELOC_ALPHA_ELF_LITERAL:
+ fixP->fx_no_overflow = 1;
+
+ if (insn->sequence == 0)
+ break;
+ info = get_alpha_reloc_tag (insn->sequence);
+ info->master = fixP;
+ info->n_master++;
+ if (info->segment != now_seg)
+ info->multi_section_p = 1;
+ fixP->tc_fix_data.info = info;
+ break;
+
+#ifdef RELOC_OP_P
+ case DUMMY_RELOC_LITUSE_ADDR:
+ fixP->fx_offset = LITUSE_ALPHA_ADDR;
+ goto do_lituse;
+ case DUMMY_RELOC_LITUSE_BASE:
+ fixP->fx_offset = LITUSE_ALPHA_BASE;
+ goto do_lituse;
+ case DUMMY_RELOC_LITUSE_BYTOFF:
+ fixP->fx_offset = LITUSE_ALPHA_BYTOFF;
+ goto do_lituse;
+ case DUMMY_RELOC_LITUSE_JSR:
+ fixP->fx_offset = LITUSE_ALPHA_JSR;
+ goto do_lituse;
+ case DUMMY_RELOC_LITUSE_TLSGD:
+ fixP->fx_offset = LITUSE_ALPHA_TLSGD;
+ goto do_lituse;
+ case DUMMY_RELOC_LITUSE_TLSLDM:
+ fixP->fx_offset = LITUSE_ALPHA_TLSLDM;
+ goto do_lituse;
+ do_lituse:
+ fixP->fx_addsy = section_symbol (now_seg);
+ fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
+
+ info = get_alpha_reloc_tag (insn->sequence);
+ if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD)
+ info->saw_lu_tlsgd = 1;
+ else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM)
+ info->saw_lu_tlsldm = 1;
+ if (++info->n_slaves > 1)
+ {
+ if (info->saw_lu_tlsgd)
+ as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
+ insn->sequence);
+ else if (info->saw_lu_tlsldm)
+ as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
+ insn->sequence);
+ }
+ fixP->tc_fix_data.info = info;
+ fixP->tc_fix_data.next_reloc = info->slaves;
+ info->slaves = fixP;
+ if (info->segment != now_seg)
+ info->multi_section_p = 1;
+ break;
+
+ case BFD_RELOC_ALPHA_TLSGD:
+ fixP->fx_no_overflow = 1;
+
+ if (insn->sequence == 0)
+ break;
+ info = get_alpha_reloc_tag (insn->sequence);
+ if (info->saw_tlsgd)
+ as_bad (_("duplicate !tlsgd!%ld"), insn->sequence);
+ else if (info->saw_tlsldm)
+ as_bad (_("sequence number in use for !tlsldm!%ld"),
+ insn->sequence);
+ else
+ info->saw_tlsgd = 1;
+ fixP->tc_fix_data.info = info;
+ break;
+
+ case BFD_RELOC_ALPHA_TLSLDM:
+ fixP->fx_no_overflow = 1;
+
+ if (insn->sequence == 0)
+ break;
+ info = get_alpha_reloc_tag (insn->sequence);
+ if (info->saw_tlsldm)
+ as_bad (_("duplicate !tlsldm!%ld"), insn->sequence);
+ else if (info->saw_tlsgd)
+ as_bad (_("sequence number in use for !tlsgd!%ld"),
+ insn->sequence);
+ else
+ info->saw_tlsldm = 1;
+ fixP->tc_fix_data.info = info;
+ break;
+#endif
+ default:
+ if ((int) fixup->reloc < 0)
+ {
+ if (operand->flags & AXP_OPERAND_NOOVERFLOW)
+ fixP->fx_no_overflow = 1;
+ }
+ break;
+ }
+ }
+}
+
+/* Given an opcode name and a pre-tokenized set of arguments, assemble
+ the insn, but do not emit it.
+
+ Note that this implies no macros allowed, since we can't store more
+ than one insn in an insn structure. */
+
+static void
+assemble_tokens_to_insn (opname, tok, ntok, insn)
+ const char *opname;
+ const expressionS *tok;
+ int ntok;
+ struct alpha_insn *insn;
+{
+ const struct alpha_opcode *opcode;
+
+ /* search opcodes */
+ opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
+ if (opcode)
+ {
+ int cpumatch;
+ opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
+ if (opcode)
+ {
+ assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
+ return;
+ }
+ else if (cpumatch)
+ as_bad (_("inappropriate arguments for opcode `%s'"), opname);
+ else
+ as_bad (_("opcode `%s' not supported for target %s"), opname,
+ alpha_target_name);
+ }
+ else
+ as_bad (_("unknown opcode `%s'"), opname);
+}
+
+/* Given an opcode name and a pre-tokenized set of arguments, take the
+ opcode all the way through emission. */
+
+static void
+assemble_tokens (opname, tok, ntok, local_macros_on)
+ const char *opname;
+ const expressionS *tok;
+ int ntok;
+ int local_macros_on;
+{
+ int found_something = 0;
+ const struct alpha_opcode *opcode;
+ const struct alpha_macro *macro;
+ int cpumatch = 1;
+ bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
+
+#ifdef RELOC_OP_P
+ /* If a user-specified relocation is present, this is not a macro. */
+ if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
+ {
+ reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
+ ntok--;
+ }
+ else
+#endif
+ if (local_macros_on)
+ {
+ macro = ((const struct alpha_macro *)
+ hash_find (alpha_macro_hash, opname));
+ if (macro)
+ {
+ found_something = 1;
+ macro = find_macro_match (macro, tok, &ntok);
+ if (macro)
+ {
+ (*macro->emit) (tok, ntok, macro->arg);
+ return;
+ }
+ }
+ }
+
+ /* Search opcodes. */
+ opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
+ if (opcode)
+ {
+ found_something = 1;
+ opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
+ if (opcode)
+ {
+ struct alpha_insn insn;
+ assemble_insn (opcode, tok, ntok, &insn, reloc);
+
+ /* Copy the sequence number for the reloc from the reloc token. */
+ if (reloc != BFD_RELOC_UNUSED)
+ insn.sequence = tok[ntok].X_add_number;
+
+ emit_insn (&insn);
+ return;
+ }
+ }
+
+ if (found_something)
+ {
+ if (cpumatch)
+ as_bad (_("inappropriate arguments for opcode `%s'"), opname);
+ else
+ as_bad (_("opcode `%s' not supported for target %s"), opname,
+ alpha_target_name);
+ }
+ else
+ as_bad (_("unknown opcode `%s'"), opname);
+}
+
+/* Some instruction sets indexed by lg(size). */
+static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
+static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
+static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
+static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
+static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
+static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
+static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
+static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
+static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
+
+/* Implement the ldgp macro. */
+
+static void
+emit_ldgp (tok, ntok, unused)
+ const expressionS *tok;
+ int ntok ATTRIBUTE_UNUSED;
+ const PTR unused ATTRIBUTE_UNUSED;
+{
+#ifdef OBJ_AOUT
+FIXME
+#endif
+#if defined(OBJ_ECOFF) || defined(OBJ_ELF)
+ /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
+ with appropriate constants and relocations. */
+ struct alpha_insn insn;
+ expressionS newtok[3];
+ expressionS addend;
+
+#ifdef OBJ_ECOFF
+ if (regno (tok[2].X_add_number) == AXP_REG_PV)
+ ecoff_set_gp_prolog_size (0);
+#endif
+
+ newtok[0] = tok[0];
+ set_tok_const (newtok[1], 0);
+ newtok[2] = tok[2];
+
+ assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
+
+ addend = tok[1];
+
+#ifdef OBJ_ECOFF
+ if (addend.X_op != O_constant)
+ as_bad (_("can not resolve expression"));
+ addend.X_op = O_symbol;
+ addend.X_add_symbol = alpha_gp_symbol;
+#endif
+
+ insn.nfixups = 1;
+ insn.fixups[0].exp = addend;
+ insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
+ insn.sequence = next_sequence_num;
+
+ emit_insn (&insn);
+
+ set_tok_preg (newtok[2], tok[0].X_add_number);
+
+ assemble_tokens_to_insn ("lda", newtok, 3, &insn);
+
+#ifdef OBJ_ECOFF
+ addend.X_add_number += 4;
+#endif
+
+ insn.nfixups = 1;
+ insn.fixups[0].exp = addend;
+ insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
+ insn.sequence = next_sequence_num--;
+
+ emit_insn (&insn);
+#endif /* OBJ_ECOFF || OBJ_ELF */
+}
+
+#ifdef OBJ_EVAX
+
+/* Add symbol+addend to link pool.
+ Return offset from basesym to entry in link pool.
+
+ Add new fixup only if offset isn't 16bit. */
+
+valueT
+add_to_link_pool (basesym, sym, addend)
+ symbolS *basesym;
+ symbolS *sym;
+ offsetT addend;
+{
+ segT current_section = now_seg;
+ int current_subsec = now_subseg;
+ valueT offset;
+ bfd_reloc_code_real_type reloc_type;
+ char *p;
+ segment_info_type *seginfo = seg_info (alpha_link_section);
+ fixS *fixp;
+
+ offset = - *symbol_get_obj (basesym);
+
+ /* @@ This assumes all entries in a given section will be of the same
+ size... Probably correct, but unwise to rely on. */
+ /* This must always be called with the same subsegment. */
+
+ if (seginfo->frchainP)
+ for (fixp = seginfo->frchainP->fix_root;
+ fixp != (fixS *) NULL;
+ fixp = fixp->fx_next, offset += 8)
+ {
+ if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
+ {
+ if (range_signed_16 (offset))
+ {
+ return offset;
+ }
+ }
+ }
+
+ /* Not found in 16bit signed range. */
+
+ subseg_set (alpha_link_section, 0);
+ p = frag_more (8);
+ memset (p, 0, 8);
+
+ fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
+ BFD_RELOC_64);
+
+ subseg_set (current_section, current_subsec);
+ seginfo->literal_pool_size += 8;
+ return offset;
+}
+
+#endif /* OBJ_EVAX */
+
+/* Load a (partial) expression into a target register.
+
+ If poffset is not null, after the call it will either contain
+ O_constant 0, or a 16-bit offset appropriate for any MEM format
+ instruction. In addition, pbasereg will be modified to point to
+ the base register to use in that MEM format instruction.
+
+ In any case, *pbasereg should contain a base register to add to the
+ expression. This will normally be either AXP_REG_ZERO or
+ alpha_gp_register. Symbol addresses will always be loaded via $gp,
+ so "foo($0)" is interpreted as adding the address of foo to $0;
+ i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
+ but this is what OSF/1 does.
+
+ If explicit relocations of the form !literal!<number> are allowed,
+ and used, then explicit_reloc with be an expression pointer.
+
+ Finally, the return value is nonzero if the calling macro may emit
+ a LITUSE reloc if otherwise appropriate; the return value is the
+ sequence number to use. */
+
+static long
+load_expression (targreg, exp, pbasereg, poffset)
+ int targreg;
+ const expressionS *exp;
+ int *pbasereg;
+ expressionS *poffset;
+{
+ long emit_lituse = 0;
+ offsetT addend = exp->X_add_number;
+ int basereg = *pbasereg;
+ struct alpha_insn insn;
+ expressionS newtok[3];
+
+ switch (exp->X_op)
+ {
+ case O_symbol:
+ {
+#ifdef OBJ_ECOFF
+ offsetT lit;
+
+ /* Attempt to reduce .lit load by splitting the offset from
+ its symbol when possible, but don't create a situation in
+ which we'd fail. */
+ if (!range_signed_32 (addend) &&
+ (alpha_noat_on || targreg == AXP_REG_AT))
+ {
+ lit = add_to_literal_pool (exp->X_add_symbol, addend,
+ alpha_lita_section, 8);
+ addend = 0;
+ }
+ else
+ {
+ lit = add_to_literal_pool (exp->X_add_symbol, 0,
+ alpha_lita_section, 8);
+ }
+
+ if (lit >= 0x8000)
+ as_fatal (_("overflow in literal (.lita) table"));
+
+ /* emit "ldq r, lit(gp)" */
+
+ if (basereg != alpha_gp_register && targreg == basereg)
+ {
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+ if (targreg == AXP_REG_AT)
+ as_bad (_("macro requires $at while $at in use"));
+
+ set_tok_reg (newtok[0], AXP_REG_AT);
+ }
+ else
+ set_tok_reg (newtok[0], targreg);
+ set_tok_sym (newtok[1], alpha_lita_symbol, lit);
+ set_tok_preg (newtok[2], alpha_gp_register);
+
+ assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
+
+ assert (insn.nfixups == 1);
+ insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
+ insn.sequence = emit_lituse = next_sequence_num--;
+#endif /* OBJ_ECOFF */
+#ifdef OBJ_ELF
+ /* emit "ldq r, gotoff(gp)" */
+
+ if (basereg != alpha_gp_register && targreg == basereg)
+ {
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+ if (targreg == AXP_REG_AT)
+ as_bad (_("macro requires $at while $at in use"));
+
+ set_tok_reg (newtok[0], AXP_REG_AT);
+ }
+ else
+ set_tok_reg (newtok[0], targreg);
+
+ /* XXX: Disable this .got minimizing optimization so that we can get
+ better instruction offset knowledge in the compiler. This happens
+ very infrequently anyway. */
+ if (1
+ || (!range_signed_32 (addend)
+ && (alpha_noat_on || targreg == AXP_REG_AT)))
+ {
+ newtok[1] = *exp;
+ addend = 0;
+ }
+ else
+ {
+ set_tok_sym (newtok[1], exp->X_add_symbol, 0);
+ }
+
+ set_tok_preg (newtok[2], alpha_gp_register);
+
+ assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
+
+ assert (insn.nfixups == 1);
+ insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
+ insn.sequence = emit_lituse = next_sequence_num--;
+#endif /* OBJ_ELF */
+#ifdef OBJ_EVAX
+ offsetT link;
+
+ /* Find symbol or symbol pointer in link section. */
+
+ if (exp->X_add_symbol == alpha_evax_proc.symbol)
+ {
+ if (range_signed_16 (addend))
+ {
+ set_tok_reg (newtok[0], targreg);
+ set_tok_const (newtok[1], addend);
+ set_tok_preg (newtok[2], basereg);
+ assemble_tokens_to_insn ("lda", newtok, 3, &insn);
+ addend = 0;
+ }
+ else
+ {
+ set_tok_reg (newtok[0], targreg);
+ set_tok_const (newtok[1], 0);
+ set_tok_preg (newtok[2], basereg);
+ assemble_tokens_to_insn ("lda", newtok, 3, &insn);
+ }
+ }
+ else
+ {
+ if (!range_signed_32 (addend))
+ {
+ link = add_to_link_pool (alpha_evax_proc.symbol,
+ exp->X_add_symbol, addend);
+ addend = 0;
+ }
+ else
+ {
+ link = add_to_link_pool (alpha_evax_proc.symbol,
+ exp->X_add_symbol, 0);
+ }
+ set_tok_reg (newtok[0], targreg);
+ set_tok_const (newtok[1], link);
+ set_tok_preg (newtok[2], basereg);
+ assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
+ }
+#endif /* OBJ_EVAX */
+
+ emit_insn (&insn);
+
+#ifndef OBJ_EVAX
+ if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
+ {
+ /* emit "addq r, base, r" */
+
+ set_tok_reg (newtok[1], basereg);
+ set_tok_reg (newtok[2], targreg);
+ assemble_tokens ("addq", newtok, 3, 0);
+ }
+#endif
+
+ basereg = targreg;
+ }
+ break;
+
+ case O_constant:
+ break;
+
+ case O_subtract:
+ /* Assume that this difference expression will be resolved to an
+ absolute value and that that value will fit in 16 bits. */
+
+ set_tok_reg (newtok[0], targreg);
+ newtok[1] = *exp;
+ set_tok_preg (newtok[2], basereg);
+ assemble_tokens ("lda", newtok, 3, 0);
+
+ if (poffset)
+ set_tok_const (*poffset, 0);
+ return 0;
+
+ case O_big:
+ if (exp->X_add_number > 0)
+ as_bad (_("bignum invalid; zero assumed"));
+ else
+ as_bad (_("floating point number invalid; zero assumed"));
+ addend = 0;
+ break;
+
+ default:
+ as_bad (_("can't handle expression"));
+ addend = 0;
+ break;
+ }
+
+ if (!range_signed_32 (addend))
+ {
+ offsetT lit;
+ long seq_num = next_sequence_num--;
+
+ /* For 64-bit addends, just put it in the literal pool. */
+
+#ifdef OBJ_EVAX
+ /* emit "ldq targreg, lit(basereg)" */
+ lit = add_to_link_pool (alpha_evax_proc.symbol,
+ section_symbol (absolute_section), addend);
+ set_tok_reg (newtok[0], targreg);
+ set_tok_const (newtok[1], lit);
+ set_tok_preg (newtok[2], alpha_gp_register);
+ assemble_tokens ("ldq", newtok, 3, 0);
+#else
+
+ if (alpha_lit8_section == NULL)
+ {
+ create_literal_section (".lit8",
+ &alpha_lit8_section,
+ &alpha_lit8_symbol);
+
+#ifdef OBJ_ECOFF
+ alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
+ alpha_lita_section, 8);
+ if (alpha_lit8_literal >= 0x8000)
+ as_fatal (_("overflow in literal (.lita) table"));
+#endif
+ }
+
+ lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
+ if (lit >= 0x8000)
+ as_fatal (_("overflow in literal (.lit8) table"));
+
+ /* emit "lda litreg, .lit8+0x8000" */
+
+ if (targreg == basereg)
+ {
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+ if (targreg == AXP_REG_AT)
+ as_bad (_("macro requires $at while $at in use"));
+
+ set_tok_reg (newtok[0], AXP_REG_AT);
+ }
+ else
+ set_tok_reg (newtok[0], targreg);
+#ifdef OBJ_ECOFF
+ set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
+#endif
+#ifdef OBJ_ELF
+ set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
+#endif
+ set_tok_preg (newtok[2], alpha_gp_register);
+
+ assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
+
+ assert (insn.nfixups == 1);
+#ifdef OBJ_ECOFF
+ insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
+#endif
+#ifdef OBJ_ELF
+ insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
+#endif
+ insn.sequence = seq_num;
+
+ emit_insn (&insn);
+
+ /* emit "ldq litreg, lit(litreg)" */
+
+ set_tok_const (newtok[1], lit);
+ set_tok_preg (newtok[2], newtok[0].X_add_number);
+
+ assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
+
+ assert (insn.nfixups < MAX_INSN_FIXUPS);
+ insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
+ insn.fixups[insn.nfixups].exp.X_op = O_absent;
+ insn.nfixups++;
+ insn.sequence = seq_num;
+ emit_lituse = 0;
+
+ emit_insn (&insn);
+
+ /* emit "addq litreg, base, target" */
+
+ if (basereg != AXP_REG_ZERO)
+ {
+ set_tok_reg (newtok[1], basereg);
+ set_tok_reg (newtok[2], targreg);
+ assemble_tokens ("addq", newtok, 3, 0);
+ }
+#endif /* !OBJ_EVAX */
+
+ if (poffset)
+ set_tok_const (*poffset, 0);
+ *pbasereg = targreg;
+ }
+ else
+ {
+ offsetT low, high, extra, tmp;
+
+ /* for 32-bit operands, break up the addend */
+
+ low = sign_extend_16 (addend);
+ tmp = addend - low;
+ high = sign_extend_16 (tmp >> 16);
+
+ if (tmp - (high << 16))
+ {
+ extra = 0x4000;
+ tmp -= 0x40000000;
+ high = sign_extend_16 (tmp >> 16);
+ }
+ else
+ extra = 0;
+
+ set_tok_reg (newtok[0], targreg);
+ set_tok_preg (newtok[2], basereg);
+
+ if (extra)
+ {
+ /* emit "ldah r, extra(r) */
+ set_tok_const (newtok[1], extra);
+ assemble_tokens ("ldah", newtok, 3, 0);
+ set_tok_preg (newtok[2], basereg = targreg);
+ }
+
+ if (high)
+ {
+ /* emit "ldah r, high(r) */
+ set_tok_const (newtok[1], high);
+ assemble_tokens ("ldah", newtok, 3, 0);
+ basereg = targreg;
+ set_tok_preg (newtok[2], basereg);
+ }
+
+ if ((low && !poffset) || (!poffset && basereg != targreg))
+ {
+ /* emit "lda r, low(base)" */
+ set_tok_const (newtok[1], low);
+ assemble_tokens ("lda", newtok, 3, 0);
+ basereg = targreg;
+ low = 0;
+ }
+
+ if (poffset)
+ set_tok_const (*poffset, low);
+ *pbasereg = basereg;
+ }
+
+ return emit_lituse;
+}
+
+/* The lda macro differs from the lda instruction in that it handles
+ most simple expressions, particularly symbol address loads and
+ large constants. */
+
+static void
+emit_lda (tok, ntok, unused)
+ const expressionS *tok;
+ int ntok;
+ const PTR unused ATTRIBUTE_UNUSED;
+{
+ int basereg;
+
+ if (ntok == 2)
+ basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
+ else
+ basereg = tok[2].X_add_number;
+
+ (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
+}
+
+/* The ldah macro differs from the ldah instruction in that it has $31
+ as an implied base register. */
+
+static void
+emit_ldah (tok, ntok, unused)
+ const expressionS *tok;
+ int ntok ATTRIBUTE_UNUSED;
+ const PTR unused ATTRIBUTE_UNUSED;
+{
+ expressionS newtok[3];
+
+ newtok[0] = tok[0];
+ newtok[1] = tok[1];
+ set_tok_preg (newtok[2], AXP_REG_ZERO);
+
+ assemble_tokens ("ldah", newtok, 3, 0);
+}
+
+/* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
+ etc. They differ from the real instructions in that they do simple
+ expressions like the lda macro. */
+
+static void
+emit_ir_load (tok, ntok, opname)
+ const expressionS *tok;
+ int ntok;
+ const PTR opname;
+{
+ int basereg;
+ long lituse;
+ expressionS newtok[3];
+ struct alpha_insn insn;
+
+ if (ntok == 2)
+ basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
+ else
+ basereg = tok[2].X_add_number;
+
+ lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
+ &newtok[1]);
+
+ newtok[0] = tok[0];
+ set_tok_preg (newtok[2], basereg);
+
+ assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
+
+ if (lituse)
+ {
+ assert (insn.nfixups < MAX_INSN_FIXUPS);
+ insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
+ insn.fixups[insn.nfixups].exp.X_op = O_absent;
+ insn.nfixups++;
+ insn.sequence = lituse;
+ }
+
+ emit_insn (&insn);
+}
+
+/* Handle fp register loads, and both integer and fp register stores.
+ Again, we handle simple expressions. */
+
+static void
+emit_loadstore (tok, ntok, opname)
+ const expressionS *tok;
+ int ntok;
+ const PTR opname;
+{
+ int basereg;
+ long lituse;
+ expressionS newtok[3];
+ struct alpha_insn insn;
+
+ if (ntok == 2)
+ basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
+ else
+ basereg = tok[2].X_add_number;
+
+ if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
+ {
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+
+ lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
+ }
+ else
+ {
+ newtok[1] = tok[1];
+ lituse = 0;
+ }
+
+ newtok[0] = tok[0];
+ set_tok_preg (newtok[2], basereg);
+
+ assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
+
+ if (lituse)
+ {
+ assert (insn.nfixups < MAX_INSN_FIXUPS);
+ insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
+ insn.fixups[insn.nfixups].exp.X_op = O_absent;
+ insn.nfixups++;
+ insn.sequence = lituse;
+ }
+
+ emit_insn (&insn);
+}
+
+/* Load a half-word or byte as an unsigned value. */
+
+static void
+emit_ldXu (tok, ntok, vlgsize)
+ const expressionS *tok;
+ int ntok;
+ const PTR vlgsize;
+{
+ if (alpha_target & AXP_OPCODE_BWX)
+ emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
+ else
+ {
+ expressionS newtok[3];
+ struct alpha_insn insn;
+ int basereg;
+ long lituse;
+
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+
+ if (ntok == 2)
+ basereg = (tok[1].X_op == O_constant
+ ? AXP_REG_ZERO : alpha_gp_register);
+ else
+ basereg = tok[2].X_add_number;
+
+ /* emit "lda $at, exp" */
+
+ lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
+
+ /* emit "ldq_u targ, 0($at)" */
+
+ newtok[0] = tok[0];
+ set_tok_const (newtok[1], 0);
+ set_tok_preg (newtok[2], basereg);
+ assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
+
+ if (lituse)
+ {
+ assert (insn.nfixups < MAX_INSN_FIXUPS);
+ insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
+ insn.fixups[insn.nfixups].exp.X_op = O_absent;
+ insn.nfixups++;
+ insn.sequence = lituse;
+ }
+
+ emit_insn (&insn);
+
+ /* emit "extXl targ, $at, targ" */
+
+ set_tok_reg (newtok[1], basereg);
+ newtok[2] = newtok[0];
+ assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
+
+ if (lituse)
+ {
+ assert (insn.nfixups < MAX_INSN_FIXUPS);
+ insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
+ insn.fixups[insn.nfixups].exp.X_op = O_absent;
+ insn.nfixups++;
+ insn.sequence = lituse;
+ }
+
+ emit_insn (&insn);
+ }
+}
+
+/* Load a half-word or byte as a signed value. */
+
+static void
+emit_ldX (tok, ntok, vlgsize)
+ const expressionS *tok;
+ int ntok;
+ const PTR vlgsize;
+{
+ emit_ldXu (tok, ntok, vlgsize);
+ assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
+}
+
+/* Load an integral value from an unaligned address as an unsigned
+ value. */
+
+static void
+emit_uldXu (tok, ntok, vlgsize)
+ const expressionS *tok;
+ int ntok;
+ const PTR vlgsize;
+{
+ long lgsize = (long) vlgsize;
+ expressionS newtok[3];
+
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+
+ /* emit "lda $at, exp" */
+
+ memcpy (newtok, tok, sizeof (expressionS) * ntok);
+ newtok[0].X_add_number = AXP_REG_AT;
+ assemble_tokens ("lda", newtok, ntok, 1);
+
+ /* emit "ldq_u $t9, 0($at)" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ set_tok_const (newtok[1], 0);
+ set_tok_preg (newtok[2], AXP_REG_AT);
+ assemble_tokens ("ldq_u", newtok, 3, 1);
+
+ /* emit "ldq_u $t10, size-1($at)" */
+
+ set_tok_reg (newtok[0], AXP_REG_T10);
+ set_tok_const (newtok[1], (1 << lgsize) - 1);
+ assemble_tokens ("ldq_u", newtok, 3, 1);
+
+ /* emit "extXl $t9, $at, $t9" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ set_tok_reg (newtok[1], AXP_REG_AT);
+ set_tok_reg (newtok[2], AXP_REG_T9);
+ assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
+
+ /* emit "extXh $t10, $at, $t10" */
+
+ set_tok_reg (newtok[0], AXP_REG_T10);
+ set_tok_reg (newtok[2], AXP_REG_T10);
+ assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
+
+ /* emit "or $t9, $t10, targ" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ set_tok_reg (newtok[1], AXP_REG_T10);
+ newtok[2] = tok[0];
+ assemble_tokens ("or", newtok, 3, 1);
+}
+
+/* Load an integral value from an unaligned address as a signed value.
+ Note that quads should get funneled to the unsigned load since we
+ don't have to do the sign extension. */
+
+static void
+emit_uldX (tok, ntok, vlgsize)
+ const expressionS *tok;
+ int ntok;
+ const PTR vlgsize;
+{
+ emit_uldXu (tok, ntok, vlgsize);
+ assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
+}
+
+/* Implement the ldil macro. */
+
+static void
+emit_ldil (tok, ntok, unused)
+ const expressionS *tok;
+ int ntok;
+ const PTR unused ATTRIBUTE_UNUSED;
+{
+ expressionS newtok[2];
+
+ memcpy (newtok, tok, sizeof (newtok));
+ newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
+
+ assemble_tokens ("lda", newtok, ntok, 1);
+}
+
+/* Store a half-word or byte. */
+
+static void
+emit_stX (tok, ntok, vlgsize)
+ const expressionS *tok;
+ int ntok;
+ const PTR vlgsize;
+{
+ int lgsize = (int) (long) vlgsize;
+
+ if (alpha_target & AXP_OPCODE_BWX)
+ emit_loadstore (tok, ntok, stX_op[lgsize]);
+ else
+ {
+ expressionS newtok[3];
+ struct alpha_insn insn;
+ int basereg;
+ long lituse;
+
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+
+ if (ntok == 2)
+ basereg = (tok[1].X_op == O_constant
+ ? AXP_REG_ZERO : alpha_gp_register);
+ else
+ basereg = tok[2].X_add_number;
+
+ /* emit "lda $at, exp" */
+
+ lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
+
+ /* emit "ldq_u $t9, 0($at)" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ set_tok_const (newtok[1], 0);
+ set_tok_preg (newtok[2], basereg);
+ assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
+
+ if (lituse)
+ {
+ assert (insn.nfixups < MAX_INSN_FIXUPS);
+ insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
+ insn.fixups[insn.nfixups].exp.X_op = O_absent;
+ insn.nfixups++;
+ insn.sequence = lituse;
+ }
+
+ emit_insn (&insn);
+
+ /* emit "insXl src, $at, $t10" */
+
+ newtok[0] = tok[0];
+ set_tok_reg (newtok[1], basereg);
+ set_tok_reg (newtok[2], AXP_REG_T10);
+ assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
+
+ if (lituse)
+ {
+ assert (insn.nfixups < MAX_INSN_FIXUPS);
+ insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
+ insn.fixups[insn.nfixups].exp.X_op = O_absent;
+ insn.nfixups++;
+ insn.sequence = lituse;
+ }
+
+ emit_insn (&insn);
+
+ /* emit "mskXl $t9, $at, $t9" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ newtok[2] = newtok[0];
+ assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
+
+ if (lituse)
+ {
+ assert (insn.nfixups < MAX_INSN_FIXUPS);
+ insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
+ insn.fixups[insn.nfixups].exp.X_op = O_absent;
+ insn.nfixups++;
+ insn.sequence = lituse;
+ }
+
+ emit_insn (&insn);
+
+ /* emit "or $t9, $t10, $t9" */
+
+ set_tok_reg (newtok[1], AXP_REG_T10);
+ assemble_tokens ("or", newtok, 3, 1);
+
+ /* emit "stq_u $t9, 0($at) */
+
+ set_tok_const(newtok[1], 0);
+ set_tok_preg (newtok[2], AXP_REG_AT);
+ assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
+
+ if (lituse)
+ {
+ assert (insn.nfixups < MAX_INSN_FIXUPS);
+ insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
+ insn.fixups[insn.nfixups].exp.X_op = O_absent;
+ insn.nfixups++;
+ insn.sequence = lituse;
+ }
+
+ emit_insn (&insn);
+ }
+}
+
+/* Store an integer to an unaligned address. */
+
+static void
+emit_ustX (tok, ntok, vlgsize)
+ const expressionS *tok;
+ int ntok;
+ const PTR vlgsize;
+{
+ int lgsize = (int) (long) vlgsize;
+ expressionS newtok[3];
+
+ /* emit "lda $at, exp" */
+
+ memcpy (newtok, tok, sizeof (expressionS) * ntok);
+ newtok[0].X_add_number = AXP_REG_AT;
+ assemble_tokens ("lda", newtok, ntok, 1);
+
+ /* emit "ldq_u $9, 0($at)" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ set_tok_const (newtok[1], 0);
+ set_tok_preg (newtok[2], AXP_REG_AT);
+ assemble_tokens ("ldq_u", newtok, 3, 1);
+
+ /* emit "ldq_u $10, size-1($at)" */
+
+ set_tok_reg (newtok[0], AXP_REG_T10);
+ set_tok_const (newtok[1], (1 << lgsize) - 1);
+ assemble_tokens ("ldq_u", newtok, 3, 1);
+
+ /* emit "insXl src, $at, $t11" */
+
+ newtok[0] = tok[0];
+ set_tok_reg (newtok[1], AXP_REG_AT);
+ set_tok_reg (newtok[2], AXP_REG_T11);
+ assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
+
+ /* emit "insXh src, $at, $t12" */
+
+ set_tok_reg (newtok[2], AXP_REG_T12);
+ assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
+
+ /* emit "mskXl $t9, $at, $t9" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ newtok[2] = newtok[0];
+ assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
+
+ /* emit "mskXh $t10, $at, $t10" */
+
+ set_tok_reg (newtok[0], AXP_REG_T10);
+ newtok[2] = newtok[0];
+ assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
+
+ /* emit "or $t9, $t11, $t9" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ set_tok_reg (newtok[1], AXP_REG_T11);
+ newtok[2] = newtok[0];
+ assemble_tokens ("or", newtok, 3, 1);
+
+ /* emit "or $t10, $t12, $t10" */
+
+ set_tok_reg (newtok[0], AXP_REG_T10);
+ set_tok_reg (newtok[1], AXP_REG_T12);
+ newtok[2] = newtok[0];
+ assemble_tokens ("or", newtok, 3, 1);
+
+ /* emit "stq_u $t9, 0($at)" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ set_tok_const (newtok[1], 0);
+ set_tok_preg (newtok[2], AXP_REG_AT);
+ assemble_tokens ("stq_u", newtok, 3, 1);
+
+ /* emit "stq_u $t10, size-1($at)" */
+
+ set_tok_reg (newtok[0], AXP_REG_T10);
+ set_tok_const (newtok[1], (1 << lgsize) - 1);
+ assemble_tokens ("stq_u", newtok, 3, 1);
+}
+
+/* Sign extend a half-word or byte. The 32-bit sign extend is
+ implemented as "addl $31, $r, $t" in the opcode table. */
+
+static void
+emit_sextX (tok, ntok, vlgsize)
+ const expressionS *tok;
+ int ntok;
+ const PTR vlgsize;
+{
+ long lgsize = (long) vlgsize;
+
+ if (alpha_target & AXP_OPCODE_BWX)
+ assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
+ else
+ {
+ int bitshift = 64 - 8 * (1 << lgsize);
+ expressionS newtok[3];
+
+ /* emit "sll src,bits,dst" */
+
+ newtok[0] = tok[0];
+ set_tok_const (newtok[1], bitshift);
+ newtok[2] = tok[ntok - 1];
+ assemble_tokens ("sll", newtok, 3, 1);
+
+ /* emit "sra dst,bits,dst" */
+
+ newtok[0] = newtok[2];
+ assemble_tokens ("sra", newtok, 3, 1);
+ }
+}
+
+/* Implement the division and modulus macros. */
+
+#ifdef OBJ_EVAX
+
+/* Make register usage like in normal procedure call.
+ Don't clobber PV and RA. */
+
+static void
+emit_division (tok, ntok, symname)
+ const expressionS *tok;
+ int ntok;
+ const PTR symname;
+{
+ /* DIVISION and MODULUS. Yech.
+
+ Convert
+ OP x,y,result
+ to
+ mov x,R16 # if x != R16
+ mov y,R17 # if y != R17
+ lda AT,__OP
+ jsr AT,(AT),0
+ mov R0,result
+
+ with appropriate optimizations if R0,R16,R17 are the registers
+ specified by the compiler. */
+
+ int xr, yr, rr;
+ symbolS *sym;
+ expressionS newtok[3];
+
+ xr = regno (tok[0].X_add_number);
+ yr = regno (tok[1].X_add_number);
+
+ if (ntok < 3)
+ rr = xr;
+ else
+ rr = regno (tok[2].X_add_number);
+
+ /* Move the operands into the right place. */
+ if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
+ {
+ /* They are in exactly the wrong order -- swap through AT. */
+
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+
+ set_tok_reg (newtok[0], AXP_REG_R16);
+ set_tok_reg (newtok[1], AXP_REG_AT);
+ assemble_tokens ("mov", newtok, 2, 1);
+
+ set_tok_reg (newtok[0], AXP_REG_R17);
+ set_tok_reg (newtok[1], AXP_REG_R16);
+ assemble_tokens ("mov", newtok, 2, 1);
+
+ set_tok_reg (newtok[0], AXP_REG_AT);
+ set_tok_reg (newtok[1], AXP_REG_R17);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+ else
+ {
+ if (yr == AXP_REG_R16)
+ {
+ set_tok_reg (newtok[0], AXP_REG_R16);
+ set_tok_reg (newtok[1], AXP_REG_R17);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+
+ if (xr != AXP_REG_R16)
+ {
+ set_tok_reg (newtok[0], xr);
+ set_tok_reg (newtok[1], AXP_REG_R16);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+
+ if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
+ {
+ set_tok_reg (newtok[0], yr);
+ set_tok_reg (newtok[1], AXP_REG_R17);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+ }
+
+ sym = symbol_find_or_make ((const char *) symname);
+
+ set_tok_reg (newtok[0], AXP_REG_AT);
+ set_tok_sym (newtok[1], sym, 0);
+ assemble_tokens ("lda", newtok, 2, 1);
+
+ /* Call the division routine. */
+ set_tok_reg (newtok[0], AXP_REG_AT);
+ set_tok_cpreg (newtok[1], AXP_REG_AT);
+ set_tok_const (newtok[2], 0);
+ assemble_tokens ("jsr", newtok, 3, 1);
+
+ /* Move the result to the right place. */
+ if (rr != AXP_REG_R0)
+ {
+ set_tok_reg (newtok[0], AXP_REG_R0);
+ set_tok_reg (newtok[1], rr);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+}
+
+#else /* !OBJ_EVAX */
+
+static void
+emit_division (tok, ntok, symname)
+ const expressionS *tok;
+ int ntok;
+ const PTR symname;
+{
+ /* DIVISION and MODULUS. Yech.
+ Convert
+ OP x,y,result
+ to
+ lda pv,__OP
+ mov x,t10
+ mov y,t11
+ jsr t9,(pv),__OP
+ mov t12,result
+
+ with appropriate optimizations if t10,t11,t12 are the registers
+ specified by the compiler. */
+
+ int xr, yr, rr;
+ symbolS *sym;
+ expressionS newtok[3];
+
+ xr = regno (tok[0].X_add_number);
+ yr = regno (tok[1].X_add_number);
+
+ if (ntok < 3)
+ rr = xr;
+ else
+ rr = regno (tok[2].X_add_number);
+
+ sym = symbol_find_or_make ((const char *) symname);
+
+ /* Move the operands into the right place. */
+ if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
+ {
+ /* They are in exactly the wrong order -- swap through AT. */
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+
+ set_tok_reg (newtok[0], AXP_REG_T10);
+ set_tok_reg (newtok[1], AXP_REG_AT);
+ assemble_tokens ("mov", newtok, 2, 1);
+
+ set_tok_reg (newtok[0], AXP_REG_T11);
+ set_tok_reg (newtok[1], AXP_REG_T10);
+ assemble_tokens ("mov", newtok, 2, 1);
+
+ set_tok_reg (newtok[0], AXP_REG_AT);
+ set_tok_reg (newtok[1], AXP_REG_T11);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+ else
+ {
+ if (yr == AXP_REG_T10)
+ {
+ set_tok_reg (newtok[0], AXP_REG_T10);
+ set_tok_reg (newtok[1], AXP_REG_T11);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+
+ if (xr != AXP_REG_T10)
+ {
+ set_tok_reg (newtok[0], xr);
+ set_tok_reg (newtok[1], AXP_REG_T10);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+
+ if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
+ {
+ set_tok_reg (newtok[0], yr);
+ set_tok_reg (newtok[1], AXP_REG_T11);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+ }
+
+ /* Call the division routine. */
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ set_tok_sym (newtok[1], sym, 0);
+ assemble_tokens ("jsr", newtok, 2, 1);
+
+ /* Reload the GP register. */
+#ifdef OBJ_AOUT
+FIXME
+#endif
+#if defined(OBJ_ECOFF) || defined(OBJ_ELF)
+ set_tok_reg (newtok[0], alpha_gp_register);
+ set_tok_const (newtok[1], 0);
+ set_tok_preg (newtok[2], AXP_REG_T9);
+ assemble_tokens ("ldgp", newtok, 3, 1);
+#endif
+
+ /* Move the result to the right place. */
+ if (rr != AXP_REG_T12)
+ {
+ set_tok_reg (newtok[0], AXP_REG_T12);
+ set_tok_reg (newtok[1], rr);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+}
+
+#endif /* !OBJ_EVAX */
+
+/* The jsr and jmp macros differ from their instruction counterparts
+ in that they can load the target address and default most
+ everything. */
+
+static void
+emit_jsrjmp (tok, ntok, vopname)
+ const expressionS *tok;
+ int ntok;
+ const PTR vopname;
+{
+ const char *opname = (const char *) vopname;
+ struct alpha_insn insn;
+ expressionS newtok[3];
+ int r, tokidx = 0;
+ long lituse = 0;
+
+ if (tokidx < ntok && tok[tokidx].X_op == O_register)
+ r = regno (tok[tokidx++].X_add_number);
+ else
+ r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
+
+ set_tok_reg (newtok[0], r);
+
+ if (tokidx < ntok &&
+ (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
+ r = regno (tok[tokidx++].X_add_number);
+#ifdef OBJ_EVAX
+ /* keep register if jsr $n.<sym> */
+#else
+ else
+ {
+ int basereg = alpha_gp_register;
+ lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
+ }
+#endif
+
+ set_tok_cpreg (newtok[1], r);
+
+#ifdef OBJ_EVAX
+ /* FIXME: Add hint relocs to BFD for evax. */
+#else
+ if (tokidx < ntok)
+ newtok[2] = tok[tokidx];
+ else
+#endif
+ set_tok_const (newtok[2], 0);
+
+ assemble_tokens_to_insn (opname, newtok, 3, &insn);
+
+ if (lituse)
+ {
+ assert (insn.nfixups < MAX_INSN_FIXUPS);
+ insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
+ insn.fixups[insn.nfixups].exp.X_op = O_absent;
+ insn.nfixups++;
+ insn.sequence = lituse;
+ }
+
+ emit_insn (&insn);
+}
+
+/* The ret and jcr instructions differ from their instruction
+ counterparts in that everything can be defaulted. */
+
+static void
+emit_retjcr (tok, ntok, vopname)
+ const expressionS *tok;
+ int ntok;
+ const PTR vopname;
+{
+ const char *opname = (const char *) vopname;
+ expressionS newtok[3];
+ int r, tokidx = 0;
+
+ if (tokidx < ntok && tok[tokidx].X_op == O_register)
+ r = regno (tok[tokidx++].X_add_number);
+ else
+ r = AXP_REG_ZERO;
+
+ set_tok_reg (newtok[0], r);
+
+ if (tokidx < ntok &&
+ (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
+ r = regno (tok[tokidx++].X_add_number);
+ else
+ r = AXP_REG_RA;
+
+ set_tok_cpreg (newtok[1], r);
+
+ if (tokidx < ntok)
+ newtok[2] = tok[tokidx];
+ else
+ set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
+
+ assemble_tokens (opname, newtok, 3, 0);
+}
+
+/* Assembler directives. */
+
+/* Handle the .text pseudo-op. This is like the usual one, but it
+ clears alpha_insn_label and restores auto alignment. */
+
+static void
+s_alpha_text (i)
+ int i;
+
+{
+#ifdef OBJ_ELF
+ obj_elf_text (i);
+#else
+ s_text (i);
+#endif
+ alpha_insn_label = NULL;
+ alpha_auto_align_on = 1;
+ alpha_current_align = 0;
+}
+
+/* Handle the .data pseudo-op. This is like the usual one, but it
+ clears alpha_insn_label and restores auto alignment. */
+
+static void
+s_alpha_data (i)
+ int i;
+{
+#ifdef OBJ_ELF
+ obj_elf_data (i);
+#else
+ s_data (i);
+#endif
+ alpha_insn_label = NULL;
+ alpha_auto_align_on = 1;
+ alpha_current_align = 0;
+}
+
+#if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
+
+/* Handle the OSF/1 and openVMS .comm pseudo quirks.
+ openVMS constructs a section for every common symbol. */
+
+static void
+s_alpha_comm (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ register char *name;
+ register char c;
+ register char *p;
+ offsetT temp;
+ register symbolS *symbolP;
+
+#ifdef OBJ_EVAX
+ segT current_section = now_seg;
+ int current_subsec = now_subseg;
+ segT new_seg;
+#endif
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ /* just after name is now '\0' */
+ p = input_line_pointer;
+ *p = c;
+
+ SKIP_WHITESPACE ();
+
+ /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ }
+ if ((temp = get_absolute_expression ()) < 0)
+ {
+ as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
+ ignore_rest_of_line ();
+ return;
+ }
+
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+
+#ifdef OBJ_EVAX
+ /* Make a section for the common symbol. */
+ new_seg = subseg_new (xstrdup (name), 0);
+#endif
+
+ *p = c;
+
+#ifdef OBJ_EVAX
+ /* alignment might follow */
+ if (*input_line_pointer == ',')
+ {
+ offsetT align;
+
+ input_line_pointer++;
+ align = get_absolute_expression ();
+ bfd_set_section_alignment (stdoutput, new_seg, align);
+ }
+#endif
+
+ if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
+ {
+ as_bad (_("Ignoring attempt to re-define symbol"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+#ifdef OBJ_EVAX
+ if (bfd_section_size (stdoutput, new_seg) > 0)
+ {
+ if (bfd_section_size (stdoutput, new_seg) != temp)
+ as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
+ S_GET_NAME (symbolP),
+ (long) bfd_section_size (stdoutput, new_seg),
+ (long) temp);
+ }
+#else
+ if (S_GET_VALUE (symbolP))
+ {
+ if (S_GET_VALUE (symbolP) != (valueT) temp)
+ as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
+ S_GET_NAME (symbolP),
+ (long) S_GET_VALUE (symbolP),
+ (long) temp);
+ }
+#endif
+ else
+ {
+#ifdef OBJ_EVAX
+ subseg_set (new_seg, 0);
+ p = frag_more (temp);
+ new_seg->flags |= SEC_IS_COMMON;
+ if (! S_IS_DEFINED (symbolP))
+ S_SET_SEGMENT (symbolP, new_seg);
+#else
+ S_SET_VALUE (symbolP, (valueT) temp);
+#endif
+ S_SET_EXTERNAL (symbolP);
+ }
+
+#ifdef OBJ_EVAX
+ subseg_set (current_section, current_subsec);
+#endif
+
+ know (symbol_get_frag (symbolP) == &zero_address_frag);
+
+ demand_empty_rest_of_line ();
+}
+
+#endif /* ! OBJ_ELF */
+
+#ifdef OBJ_ECOFF
+
+/* Handle the .rdata pseudo-op. This is like the usual one, but it
+ clears alpha_insn_label and restores auto alignment. */
+
+static void
+s_alpha_rdata (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ int temp;
+
+ temp = get_absolute_expression ();
+ subseg_new (".rdata", 0);
+ demand_empty_rest_of_line ();
+ alpha_insn_label = NULL;
+ alpha_auto_align_on = 1;
+ alpha_current_align = 0;
+}
+
+#endif
+
+#ifdef OBJ_ECOFF
+
+/* Handle the .sdata pseudo-op. This is like the usual one, but it
+ clears alpha_insn_label and restores auto alignment. */
+
+static void
+s_alpha_sdata (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ int temp;
+
+ temp = get_absolute_expression ();
+ subseg_new (".sdata", 0);
+ demand_empty_rest_of_line ();
+ alpha_insn_label = NULL;
+ alpha_auto_align_on = 1;
+ alpha_current_align = 0;
+}
+#endif
+
+#ifdef OBJ_ELF
+struct alpha_elf_frame_data
+{
+ symbolS *func_sym;
+ symbolS *func_end_sym;
+ symbolS *prologue_sym;
+ unsigned int mask;
+ unsigned int fmask;
+ int fp_regno;
+ int ra_regno;
+ offsetT frame_size;
+ offsetT mask_offset;
+ offsetT fmask_offset;
+
+ struct alpha_elf_frame_data *next;
+};
+
+static struct alpha_elf_frame_data *all_frame_data;
+static struct alpha_elf_frame_data **plast_frame_data = &all_frame_data;
+static struct alpha_elf_frame_data *cur_frame_data;
+
+/* Handle the .section pseudo-op. This is like the usual one, but it
+ clears alpha_insn_label and restores auto alignment. */
+
+static void
+s_alpha_section (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ obj_elf_section (ignore);
+
+ alpha_insn_label = NULL;
+ alpha_auto_align_on = 1;
+ alpha_current_align = 0;
+}
+
+static void
+s_alpha_ent (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ if (ECOFF_DEBUGGING)
+ ecoff_directive_ent (0);
+ else
+ {
+ char *name, name_end;
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ if (! is_name_beginner (*name))
+ {
+ as_warn (_(".ent directive has no name"));
+ *input_line_pointer = name_end;
+ }
+ else
+ {
+ symbolS *sym;
+
+ if (cur_frame_data)
+ as_warn (_("nested .ent directives"));
+
+ sym = symbol_find_or_make (name);
+ symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
+
+ cur_frame_data = calloc (1, sizeof (*cur_frame_data));
+ cur_frame_data->func_sym = sym;
+
+ /* Provide sensible defaults. */
+ cur_frame_data->fp_regno = 30; /* sp */
+ cur_frame_data->ra_regno = 26; /* ra */
+
+ *plast_frame_data = cur_frame_data;
+ plast_frame_data = &cur_frame_data->next;
+
+ /* The .ent directive is sometimes followed by a number. Not sure
+ what it really means, but ignore it. */
+ *input_line_pointer = name_end;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ }
+ if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
+ (void) get_absolute_expression ();
+ }
+ demand_empty_rest_of_line ();
+ }
+}
+
+static void
+s_alpha_end (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ if (ECOFF_DEBUGGING)
+ ecoff_directive_end (0);
+ else
+ {
+ char *name, name_end;
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ if (! is_name_beginner (*name))
+ {
+ as_warn (_(".end directive has no name"));
+ *input_line_pointer = name_end;
+ }
+ else
+ {
+ symbolS *sym;
+
+ sym = symbol_find (name);
+ if (!cur_frame_data)
+ as_warn (_(".end directive without matching .ent"));
+ else if (sym != cur_frame_data->func_sym)
+ as_warn (_(".end directive names different symbol than .ent"));
+
+ /* Create an expression to calculate the size of the function. */
+ if (sym && cur_frame_data)
+ {
+ OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
+ expressionS *exp = xmalloc (sizeof (expressionS));
+
+ obj->size = exp;
+ exp->X_op = O_subtract;
+ exp->X_add_symbol = symbol_temp_new_now ();
+ exp->X_op_symbol = sym;
+ exp->X_add_number = 0;
+
+ cur_frame_data->func_end_sym = exp->X_add_symbol;
+ }
+
+ cur_frame_data = NULL;
+
+ *input_line_pointer = name_end;
+ }
+ demand_empty_rest_of_line ();
+ }
+}
+
+static void
+s_alpha_mask (fp)
+ int fp;
+{
+ if (ECOFF_DEBUGGING)
+ {
+ if (fp)
+ ecoff_directive_fmask (0);
+ else
+ ecoff_directive_mask (0);
+ }
+ else
+ {
+ long val;
+ offsetT offset;
+
+ if (!cur_frame_data)
+ {
+ if (fp)
+ as_warn (_(".fmask outside of .ent"));
+ else
+ as_warn (_(".mask outside of .ent"));
+ discard_rest_of_line ();
+ return;
+ }
+
+ if (get_absolute_expression_and_terminator (&val) != ',')
+ {
+ if (fp)
+ as_warn (_("bad .fmask directive"));
+ else
+ as_warn (_("bad .mask directive"));
+ --input_line_pointer;
+ discard_rest_of_line ();
+ return;
+ }
+
+ offset = get_absolute_expression ();
+ demand_empty_rest_of_line ();
+
+ if (fp)
+ {
+ cur_frame_data->fmask = val;
+ cur_frame_data->fmask_offset = offset;
+ }
+ else
+ {
+ cur_frame_data->mask = val;
+ cur_frame_data->mask_offset = offset;
+ }
+ }
+}
+
+static void
+s_alpha_frame (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ if (ECOFF_DEBUGGING)
+ ecoff_directive_frame (0);
+ else
+ {
+ long val;
+
+ if (!cur_frame_data)
+ {
+ as_warn (_(".frame outside of .ent"));
+ discard_rest_of_line ();
+ return;
+ }
+
+ cur_frame_data->fp_regno = tc_get_register (1);
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer++ != ','
+ || get_absolute_expression_and_terminator (&val) != ',')
+ {
+ as_warn (_("bad .frame directive"));
+ --input_line_pointer;
+ discard_rest_of_line ();
+ return;
+ }
+ cur_frame_data->frame_size = val;
+
+ cur_frame_data->ra_regno = tc_get_register (0);
+
+ /* Next comes the "offset of saved $a0 from $sp". In gcc terms
+ this is current_function_pretend_args_size. There's no place
+ to put this value, so ignore it. */
+ s_ignore (42);
+ }
+}
+
+static void
+s_alpha_prologue (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ symbolS *sym;
+ int arg;
+
+ arg = get_absolute_expression ();
+ demand_empty_rest_of_line ();
+
+ if (ECOFF_DEBUGGING)
+ sym = ecoff_get_cur_proc_sym ();
+ else
+ sym = cur_frame_data ? cur_frame_data->func_sym : NULL;
+
+ if (sym == NULL)
+ {
+ as_bad (_(".prologue directive without a preceding .ent directive"));
+ return;
+ }
+
+ switch (arg)
+ {
+ case 0: /* No PV required. */
+ S_SET_OTHER (sym, STO_ALPHA_NOPV
+ | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
+ break;
+ case 1: /* Std GP load. */
+ S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
+ | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
+ break;
+ case 2: /* Non-std use of PV. */
+ break;
+
+ default:
+ as_bad (_("Invalid argument %d to .prologue."), arg);
+ break;
+ }
+
+ if (cur_frame_data)
+ cur_frame_data->prologue_sym = symbol_temp_new_now ();
+}
+
+static char *first_file_directive;
+
+static void
+s_alpha_file (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ /* Save the first .file directive we see, so that we can change our
+ minds about whether ecoff debugging should or shouldn't be enabled. */
+ if (alpha_flag_mdebug < 0 && ! first_file_directive)
+ {
+ char *start = input_line_pointer;
+ size_t len;
+
+ discard_rest_of_line ();
+
+ len = input_line_pointer - start;
+ first_file_directive = xmalloc (len + 1);
+ memcpy (first_file_directive, start, len);
+ first_file_directive[len] = '\0';
+
+ input_line_pointer = start;
+ }
+
+ if (ECOFF_DEBUGGING)
+ ecoff_directive_file (0);
+ else
+ dwarf2_directive_file (0);
+}
+
+static void
+s_alpha_loc (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (ECOFF_DEBUGGING)
+ ecoff_directive_loc (0);
+ else
+ dwarf2_directive_loc (0);
+}
+
+static void
+s_alpha_stab (n)
+ int n;
+{
+ /* If we've been undecided about mdebug, make up our minds in favour. */
+ if (alpha_flag_mdebug < 0)
+ {
+ segT sec = subseg_new (".mdebug", 0);
+ bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
+ bfd_set_section_alignment (stdoutput, sec, 3);
+
+ ecoff_read_begin_hook ();
+
+ if (first_file_directive)
+ {
+ char *save_ilp = input_line_pointer;
+ input_line_pointer = first_file_directive;
+ ecoff_directive_file (0);
+ input_line_pointer = save_ilp;
+ free (first_file_directive);
+ }
+
+ alpha_flag_mdebug = 1;
+ }
+ s_stab (n);
+}
+
+static void
+s_alpha_coff_wrapper (which)
+ int which;
+{
+ static void (* const fns[]) PARAMS ((int)) = {
+ ecoff_directive_begin,
+ ecoff_directive_bend,
+ ecoff_directive_def,
+ ecoff_directive_dim,
+ ecoff_directive_endef,
+ ecoff_directive_scl,
+ ecoff_directive_tag,
+ ecoff_directive_val,
+ };
+
+ assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
+
+ if (ECOFF_DEBUGGING)
+ (*fns[which]) (0);
+ else
+ {
+ as_bad (_("ECOFF debugging is disabled."));
+ ignore_rest_of_line ();
+ }
+}
+
+/* Called at the end of assembly. Here we emit unwind info for frames
+ unless the compiler has done it for us. */
+
+void
+alpha_elf_md_end (void)
+{
+ struct alpha_elf_frame_data *p;
+
+ if (cur_frame_data)
+ as_warn (_(".ent directive without matching .end"));
+
+ /* If someone has generated the unwind info themselves, great. */
+ if (bfd_get_section_by_name (stdoutput, ".eh_frame") != NULL)
+ return;
+
+ /* Generate .eh_frame data for the unwind directives specified. */
+ for (p = all_frame_data; p ; p = p->next)
+ if (p->prologue_sym)
+ {
+ /* Create a temporary symbol at the same location as our
+ function symbol. This prevents problems with globals. */
+ cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p->func_sym),
+ S_GET_VALUE (p->func_sym),
+ symbol_get_frag (p->func_sym)));
+
+ cfi_set_return_column (p->ra_regno);
+ cfi_add_CFA_def_cfa_register (30);
+ if (p->fp_regno != 30 || p->mask || p->fmask || p->frame_size)
+ {
+ unsigned int mask;
+ offsetT offset;
+
+ cfi_add_advance_loc (p->prologue_sym);
+
+ if (p->fp_regno != 30)
+ if (p->frame_size != 0)
+ cfi_add_CFA_def_cfa (p->fp_regno, p->frame_size);
+ else
+ cfi_add_CFA_def_cfa_register (p->fp_regno);
+ else if (p->frame_size != 0)
+ cfi_add_CFA_def_cfa_offset (p->frame_size);
+
+ mask = p->mask;
+ offset = p->mask_offset;
+
+ /* Recall that $26 is special-cased and stored first. */
+ if ((mask >> 26) & 1)
+ {
+ cfi_add_CFA_offset (26, offset);
+ offset += 8;
+ mask &= ~(1 << 26);
+ }
+ while (mask)
+ {
+ unsigned int i;
+ i = mask & -mask;
+ mask ^= i;
+ i = ffs (i) - 1;
+
+ cfi_add_CFA_offset (i, offset);
+ offset += 8;
+ }
+
+ mask = p->fmask;
+ offset = p->fmask_offset;
+ while (mask)
+ {
+ unsigned int i;
+ i = mask & -mask;
+ mask ^= i;
+ i = ffs (i) - 1;
+
+ cfi_add_CFA_offset (i + 32, offset);
+ offset += 8;
+ }
+ }
+
+ cfi_end_fde (p->func_end_sym);
+ }
+}
+
+static void
+s_alpha_usepv (int unused ATTRIBUTE_UNUSED)
+{
+ char *name, name_end;
+ char *which, which_end;
+ symbolS *sym;
+ int other;
+
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ if (! is_name_beginner (*name))
+ {
+ as_bad (_(".usepv directive has no name"));
+ *input_line_pointer = name_end;
+ ignore_rest_of_line ();
+ return;
+ }
+
+ sym = symbol_find_or_make (name);
+ *input_line_pointer++ = name_end;
+
+ if (name_end != ',')
+ {
+ as_bad (_(".usepv directive has no type"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ SKIP_WHITESPACE ();
+ which = input_line_pointer;
+ which_end = get_symbol_end ();
+
+ if (strcmp (which, "no") == 0)
+ other = STO_ALPHA_NOPV;
+ else if (strcmp (which, "std") == 0)
+ other = STO_ALPHA_STD_GPLOAD;
+ else
+ {
+ as_bad (_("unknown argument for .usepv"));
+ other = 0;
+ }
+
+ *input_line_pointer = which_end;
+ demand_empty_rest_of_line ();
+
+ S_SET_OTHER (sym, other | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
+}
+#endif /* OBJ_ELF */
+
+/* Standard calling conventions leaves the CFA at $30 on entry. */
+
+void
+alpha_cfi_frame_initial_instructions ()
+{
+ cfi_add_CFA_def_cfa_register (30);
+}
+
+#ifdef OBJ_EVAX
+
+/* Handle the section specific pseudo-op. */
+
+static void
+s_alpha_section (secid)
+ int secid;
+{
+ int temp;
+#define EVAX_SECTION_COUNT 5
+ static char *section_name[EVAX_SECTION_COUNT + 1] =
+ { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
+
+ if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
+ {
+ as_fatal (_("Unknown section directive"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+ temp = get_absolute_expression ();
+ subseg_new (section_name[secid], 0);
+ demand_empty_rest_of_line ();
+ alpha_insn_label = NULL;
+ alpha_auto_align_on = 1;
+ alpha_current_align = 0;
+}
+
+/* Parse .ent directives. */
+
+static void
+s_alpha_ent (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ symbolS *symbol;
+ expressionS symexpr;
+
+ alpha_evax_proc.pdsckind = 0;
+ alpha_evax_proc.framereg = -1;
+ alpha_evax_proc.framesize = 0;
+ alpha_evax_proc.rsa_offset = 0;
+ alpha_evax_proc.ra_save = AXP_REG_RA;
+ alpha_evax_proc.fp_save = -1;
+ alpha_evax_proc.imask = 0;
+ alpha_evax_proc.fmask = 0;
+ alpha_evax_proc.prologue = 0;
+ alpha_evax_proc.type = 0;
+
+ expression (&symexpr);
+
+ if (symexpr.X_op != O_symbol)
+ {
+ as_fatal (_(".ent directive has no symbol"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ symbol = make_expr_symbol (&symexpr);
+ symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
+ alpha_evax_proc.symbol = symbol;
+
+ demand_empty_rest_of_line ();
+}
+
+/* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
+
+static void
+s_alpha_frame (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ long val;
+
+ alpha_evax_proc.framereg = tc_get_register (1);
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer++ != ','
+ || get_absolute_expression_and_terminator (&val) != ',')
+ {
+ as_warn (_("Bad .frame directive 1./2. param"));
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ alpha_evax_proc.framesize = val;
+
+ (void) tc_get_register (1);
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer++ != ',')
+ {
+ as_warn (_("Bad .frame directive 3./4. param"));
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+ alpha_evax_proc.rsa_offset = get_absolute_expression ();
+}
+
+static void
+s_alpha_pdesc (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *name;
+ char name_end;
+ long val;
+ register char *p;
+ expressionS exp;
+ symbolS *entry_sym;
+ fixS *fixp;
+ segment_info_type *seginfo = seg_info (alpha_link_section);
+
+ if (now_seg != alpha_link_section)
+ {
+ as_bad (_(".pdesc directive not in link (.link) section"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if ((alpha_evax_proc.symbol == 0)
+ || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
+ {
+ as_fatal (_(".pdesc has no matching .ent"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ *symbol_get_obj (alpha_evax_proc.symbol) =
+ (valueT) seginfo->literal_pool_size;
+
+ expression (&exp);
+ if (exp.X_op != O_symbol)
+ {
+ as_warn (_(".pdesc directive has no entry symbol"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ entry_sym = make_expr_symbol (&exp);
+ /* Save bfd symbol of proc desc in function symbol. */
+ symbol_get_bfdsym (alpha_evax_proc.symbol)->udata.p
+ = symbol_get_bfdsym (entry_sym);
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer++ != ',')
+ {
+ as_warn (_("No comma after .pdesc <entryname>"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ if (strncmp (name, "stack", 5) == 0)
+ {
+ alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
+ }
+ else if (strncmp (name, "reg", 3) == 0)
+ {
+ alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
+ }
+ else if (strncmp (name, "null", 4) == 0)
+ {
+ alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
+ }
+ else
+ {
+ as_fatal (_("unknown procedure kind"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ *input_line_pointer = name_end;
+ demand_empty_rest_of_line ();
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ frag_align (3, 0, 0);
+ p = frag_more (16);
+ fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
+ fixp->fx_done = 1;
+ seginfo->literal_pool_size += 16;
+
+ *p = alpha_evax_proc.pdsckind
+ | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
+ *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
+
+ switch (alpha_evax_proc.pdsckind)
+ {
+ case PDSC_S_K_KIND_NULL:
+ *(p + 2) = 0;
+ *(p + 3) = 0;
+ break;
+ case PDSC_S_K_KIND_FP_REGISTER:
+ *(p + 2) = alpha_evax_proc.fp_save;
+ *(p + 3) = alpha_evax_proc.ra_save;
+ break;
+ case PDSC_S_K_KIND_FP_STACK:
+ md_number_to_chars (p + 2, (valueT) alpha_evax_proc.rsa_offset, 2);
+ break;
+ default: /* impossible */
+ break;
+ }
+
+ *(p + 4) = 0;
+ *(p + 5) = alpha_evax_proc.type & 0x0f;
+
+ /* Signature offset. */
+ md_number_to_chars (p + 6, (valueT) 0, 2);
+
+ fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
+
+ if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
+ return;
+
+ /* Add dummy fix to make add_to_link_pool work. */
+ p = frag_more (8);
+ fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
+ fixp->fx_done = 1;
+ seginfo->literal_pool_size += 8;
+
+ /* pdesc+16: Size. */
+ md_number_to_chars (p, (valueT) alpha_evax_proc.framesize, 4);
+
+ md_number_to_chars (p + 4, (valueT) 0, 2);
+
+ /* Entry length. */
+ md_number_to_chars (p + 6, alpha_evax_proc.prologue, 2);
+
+ if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
+ return;
+
+ /* Add dummy fix to make add_to_link_pool work. */
+ p = frag_more (8);
+ fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
+ fixp->fx_done = 1;
+ seginfo->literal_pool_size += 8;
+
+ /* pdesc+24: register masks. */
+
+ md_number_to_chars (p, alpha_evax_proc.imask, 4);
+ md_number_to_chars (p + 4, alpha_evax_proc.fmask, 4);
+}
+
+/* Support for crash debug on vms. */
+
+static void
+s_alpha_name (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ register char *p;
+ expressionS exp;
+ segment_info_type *seginfo = seg_info (alpha_link_section);
+
+ if (now_seg != alpha_link_section)
+ {
+ as_bad (_(".name directive not in link (.link) section"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ expression (&exp);
+ if (exp.X_op != O_symbol)
+ {
+ as_warn (_(".name directive has no symbol"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ demand_empty_rest_of_line ();
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ frag_align (3, 0, 0);
+ p = frag_more (8);
+ seginfo->literal_pool_size += 8;
+
+ fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
+}
+
+static void
+s_alpha_linkage (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ expressionS exp;
+ char *p;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ expression (&exp);
+ if (exp.X_op != O_symbol)
+ {
+ as_fatal (_("No symbol after .linkage"));
+ }
+ else
+ {
+ p = frag_more (LKP_S_K_SIZE);
+ memset (p, 0, LKP_S_K_SIZE);
+ fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
+ BFD_RELOC_ALPHA_LINKAGE);
+ }
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_alpha_code_address (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ expressionS exp;
+ char *p;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ expression (&exp);
+ if (exp.X_op != O_symbol)
+ {
+ as_fatal (_("No symbol after .code_address"));
+ }
+ else
+ {
+ p = frag_more (8);
+ memset (p, 0, 8);
+ fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
+ BFD_RELOC_ALPHA_CODEADDR);
+ }
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_alpha_fp_save (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+
+ alpha_evax_proc.fp_save = tc_get_register (1);
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_alpha_mask (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ long val;
+
+ if (get_absolute_expression_and_terminator (&val) != ',')
+ {
+ as_warn (_("Bad .mask directive"));
+ --input_line_pointer;
+ }
+ else
+ {
+ alpha_evax_proc.imask = val;
+ (void) get_absolute_expression ();
+ }
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_alpha_fmask (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ long val;
+
+ if (get_absolute_expression_and_terminator (&val) != ',')
+ {
+ as_warn (_("Bad .fmask directive"));
+ --input_line_pointer;
+ }
+ else
+ {
+ alpha_evax_proc.fmask = val;
+ (void) get_absolute_expression ();
+ }
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_alpha_end (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char c;
+
+ c = get_symbol_end ();
+ *input_line_pointer = c;
+ demand_empty_rest_of_line ();
+ alpha_evax_proc.symbol = 0;
+}
+
+static void
+s_alpha_file (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ symbolS *s;
+ int length;
+ static char case_hack[32];
+
+ sprintf (case_hack, "<CASE:%01d%01d>",
+ alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
+
+ s = symbol_find_or_make (case_hack);
+ symbol_get_bfdsym (s)->flags |= BSF_FILE;
+
+ get_absolute_expression ();
+ s = symbol_find_or_make (demand_copy_string (&length));
+ symbol_get_bfdsym (s)->flags |= BSF_FILE;
+ demand_empty_rest_of_line ();
+}
+#endif /* OBJ_EVAX */
+
+/* Handle the .gprel32 pseudo op. */
+
+static void
+s_alpha_gprel32 (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ expressionS e;
+ char *p;
+
+ SKIP_WHITESPACE ();
+ expression (&e);
+
+#ifdef OBJ_ELF
+ switch (e.X_op)
+ {
+ case O_constant:
+ e.X_add_symbol = section_symbol (absolute_section);
+ e.X_op = O_symbol;
+ /* FALLTHRU */
+ case O_symbol:
+ break;
+ default:
+ abort ();
+ }
+#else
+#ifdef OBJ_ECOFF
+ switch (e.X_op)
+ {
+ case O_constant:
+ e.X_add_symbol = section_symbol (absolute_section);
+ /* fall through */
+ case O_symbol:
+ e.X_op = O_subtract;
+ e.X_op_symbol = alpha_gp_symbol;
+ break;
+ default:
+ abort ();
+ }
+#endif
+#endif
+
+ if (alpha_auto_align_on && alpha_current_align < 2)
+ alpha_align (2, (char *) NULL, alpha_insn_label, 0);
+ if (alpha_current_align > 2)
+ alpha_current_align = 2;
+ alpha_insn_label = NULL;
+
+ p = frag_more (4);
+ memset (p, 0, 4);
+ fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
+ &e, 0, BFD_RELOC_GPREL32);
+}
+
+/* Handle floating point allocation pseudo-ops. This is like the
+ generic vresion, but it makes sure the current label, if any, is
+ correctly aligned. */
+
+static void
+s_alpha_float_cons (type)
+ int type;
+{
+ int log_size;
+
+ switch (type)
+ {
+ default:
+ case 'f':
+ case 'F':
+ log_size = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'G':
+ log_size = 3;
+ break;
+
+ case 'x':
+ case 'X':
+ case 'p':
+ case 'P':
+ log_size = 4;
+ break;
+ }
+
+ if (alpha_auto_align_on && alpha_current_align < log_size)
+ alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
+ if (alpha_current_align > log_size)
+ alpha_current_align = log_size;
+ alpha_insn_label = NULL;
+
+ float_cons (type);
+}
+
+/* Handle the .proc pseudo op. We don't really do much with it except
+ parse it. */
+
+static void
+s_alpha_proc (is_static)
+ int is_static ATTRIBUTE_UNUSED;
+{
+ char *name;
+ char c;
+ char *p;
+ symbolS *symbolP;
+ int temp;
+
+ /* Takes ".proc name,nargs" */
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ p = input_line_pointer;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ *p = 0;
+ as_warn (_("Expected comma after name \"%s\""), name);
+ *p = c;
+ temp = 0;
+ ignore_rest_of_line ();
+ }
+ else
+ {
+ input_line_pointer++;
+ temp = get_absolute_expression ();
+ }
+ /* *symbol_get_obj (symbolP) = (signed char) temp; */
+ as_warn (_("unhandled: .proc %s,%d"), name, temp);
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .set pseudo op. This is used to turn on and off most of
+ the assembler features. */
+
+static void
+s_alpha_set (x)
+ int x ATTRIBUTE_UNUSED;
+{
+ char *name, ch, *s;
+ int yesno = 1;
+
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ ch = get_symbol_end ();
+
+ s = name;
+ if (s[0] == 'n' && s[1] == 'o')
+ {
+ yesno = 0;
+ s += 2;
+ }
+ if (!strcmp ("reorder", s))
+ /* ignore */ ;
+ else if (!strcmp ("at", s))
+ alpha_noat_on = !yesno;
+ else if (!strcmp ("macro", s))
+ alpha_macros_on = yesno;
+ else if (!strcmp ("move", s))
+ /* ignore */ ;
+ else if (!strcmp ("volatile", s))
+ /* ignore */ ;
+ else
+ as_warn (_("Tried to .set unrecognized mode `%s'"), name);
+
+ *input_line_pointer = ch;
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .base pseudo op. This changes the assembler's notion of
+ the $gp register. */
+
+static void
+s_alpha_base (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+#if 0
+ if (first_32bit_quadrant)
+ {
+ /* not fatal, but it might not work in the end */
+ as_warn (_("File overrides no-base-register option."));
+ first_32bit_quadrant = 0;
+ }
+#endif
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '$')
+ { /* $rNN form */
+ input_line_pointer++;
+ if (*input_line_pointer == 'r')
+ input_line_pointer++;
+ }
+
+ alpha_gp_register = get_absolute_expression ();
+ if (alpha_gp_register < 0 || alpha_gp_register > 31)
+ {
+ alpha_gp_register = AXP_REG_GP;
+ as_warn (_("Bad base register, using $%d."), alpha_gp_register);
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .align pseudo-op. This aligns to a power of two. It
+ also adjusts any current instruction label. We treat this the same
+ way the MIPS port does: .align 0 turns off auto alignment. */
+
+static void
+s_alpha_align (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ int align;
+ char fill, *pfill;
+ long max_alignment = 15;
+
+ align = get_absolute_expression ();
+ if (align > max_alignment)
+ {
+ align = max_alignment;
+ as_bad (_("Alignment too large: %d. assumed"), align);
+ }
+ else if (align < 0)
+ {
+ as_warn (_("Alignment negative: 0 assumed"));
+ align = 0;
+ }
+
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ fill = get_absolute_expression ();
+ pfill = &fill;
+ }
+ else
+ pfill = NULL;
+
+ if (align != 0)
+ {
+ alpha_auto_align_on = 1;
+ alpha_align (align, pfill, alpha_insn_label, 1);
+ }
+ else
+ {
+ alpha_auto_align_on = 0;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Hook the normal string processor to reset known alignment. */
+
+static void
+s_alpha_stringer (terminate)
+ int terminate;
+{
+ alpha_current_align = 0;
+ alpha_insn_label = NULL;
+ stringer (terminate);
+}
+
+/* Hook the normal space processing to reset known alignment. */
+
+static void
+s_alpha_space (ignore)
+ int ignore;
+{
+ alpha_current_align = 0;
+ alpha_insn_label = NULL;
+ s_space (ignore);
+}
+
+/* Hook into cons for auto-alignment. */
+
+void
+alpha_cons_align (size)
+ int size;
+{
+ int log_size;
+
+ log_size = 0;
+ while ((size >>= 1) != 0)
+ ++log_size;
+
+ if (alpha_auto_align_on && alpha_current_align < log_size)
+ alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
+ if (alpha_current_align > log_size)
+ alpha_current_align = log_size;
+ alpha_insn_label = NULL;
+}
+
+/* Here come the .uword, .ulong, and .uquad explicitly unaligned
+ pseudos. We just turn off auto-alignment and call down to cons. */
+
+static void
+s_alpha_ucons (bytes)
+ int bytes;
+{
+ int hold = alpha_auto_align_on;
+ alpha_auto_align_on = 0;
+ cons (bytes);
+ alpha_auto_align_on = hold;
+}
+
+/* Switch the working cpu type. */
+
+static void
+s_alpha_arch (ignored)
+ int ignored ATTRIBUTE_UNUSED;
+{
+ char *name, ch;
+ const struct cpu_type *p;
+
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ ch = get_symbol_end ();
+
+ for (p = cpu_types; p->name; ++p)
+ if (strcmp (name, p->name) == 0)
+ {
+ alpha_target_name = p->name, alpha_target = p->flags;
+ goto found;
+ }
+ as_warn ("Unknown CPU identifier `%s'", name);
+
+found:
+ *input_line_pointer = ch;
+ demand_empty_rest_of_line ();
+}
+
+#ifdef DEBUG1
+/* print token expression with alpha specific extension. */
+
+static void
+alpha_print_token (f, exp)
+ FILE *f;
+ const expressionS *exp;
+{
+ switch (exp->X_op)
+ {
+ case O_cpregister:
+ putc (',', f);
+ /* FALLTHRU */
+ case O_pregister:
+ putc ('(', f);
+ {
+ expressionS nexp = *exp;
+ nexp.X_op = O_register;
+ print_expr (f, &nexp);
+ }
+ putc (')', f);
+ break;
+ default:
+ print_expr (f, exp);
+ break;
+ }
+}
+#endif
+
+/* The target specific pseudo-ops which we support. */
+
+const pseudo_typeS md_pseudo_table[] = {
+#ifdef OBJ_ECOFF
+ {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
+ {"rdata", s_alpha_rdata, 0},
+#endif
+ {"text", s_alpha_text, 0},
+ {"data", s_alpha_data, 0},
+#ifdef OBJ_ECOFF
+ {"sdata", s_alpha_sdata, 0},
+#endif
+#ifdef OBJ_ELF
+ {"section", s_alpha_section, 0},
+ {"section.s", s_alpha_section, 0},
+ {"sect", s_alpha_section, 0},
+ {"sect.s", s_alpha_section, 0},
+#endif
+#ifdef OBJ_EVAX
+ { "pdesc", s_alpha_pdesc, 0},
+ { "name", s_alpha_name, 0},
+ { "linkage", s_alpha_linkage, 0},
+ { "code_address", s_alpha_code_address, 0},
+ { "ent", s_alpha_ent, 0},
+ { "frame", s_alpha_frame, 0},
+ { "fp_save", s_alpha_fp_save, 0},
+ { "mask", s_alpha_mask, 0},
+ { "fmask", s_alpha_fmask, 0},
+ { "end", s_alpha_end, 0},
+ { "file", s_alpha_file, 0},
+ { "rdata", s_alpha_section, 1},
+ { "comm", s_alpha_comm, 0},
+ { "link", s_alpha_section, 3},
+ { "ctors", s_alpha_section, 4},
+ { "dtors", s_alpha_section, 5},
+#endif
+#ifdef OBJ_ELF
+ /* Frame related pseudos. */
+ {"ent", s_alpha_ent, 0},
+ {"end", s_alpha_end, 0},
+ {"mask", s_alpha_mask, 0},
+ {"fmask", s_alpha_mask, 1},
+ {"frame", s_alpha_frame, 0},
+ {"prologue", s_alpha_prologue, 0},
+ {"file", s_alpha_file, 5},
+ {"loc", s_alpha_loc, 9},
+ {"stabs", s_alpha_stab, 's'},
+ {"stabn", s_alpha_stab, 'n'},
+ {"usepv", s_alpha_usepv, 0},
+ /* COFF debugging related pseudos. */
+ {"begin", s_alpha_coff_wrapper, 0},
+ {"bend", s_alpha_coff_wrapper, 1},
+ {"def", s_alpha_coff_wrapper, 2},
+ {"dim", s_alpha_coff_wrapper, 3},
+ {"endef", s_alpha_coff_wrapper, 4},
+ {"scl", s_alpha_coff_wrapper, 5},
+ {"tag", s_alpha_coff_wrapper, 6},
+ {"val", s_alpha_coff_wrapper, 7},
+#else
+ {"prologue", s_ignore, 0},
+#endif
+ {"gprel32", s_alpha_gprel32, 0},
+ {"t_floating", s_alpha_float_cons, 'd'},
+ {"s_floating", s_alpha_float_cons, 'f'},
+ {"f_floating", s_alpha_float_cons, 'F'},
+ {"g_floating", s_alpha_float_cons, 'G'},
+ {"d_floating", s_alpha_float_cons, 'D'},
+
+ {"proc", s_alpha_proc, 0},
+ {"aproc", s_alpha_proc, 1},
+ {"set", s_alpha_set, 0},
+ {"reguse", s_ignore, 0},
+ {"livereg", s_ignore, 0},
+ {"base", s_alpha_base, 0}, /*??*/
+ {"option", s_ignore, 0},
+ {"aent", s_ignore, 0},
+ {"ugen", s_ignore, 0},
+ {"eflag", s_ignore, 0},
+
+ {"align", s_alpha_align, 0},
+ {"double", s_alpha_float_cons, 'd'},
+ {"float", s_alpha_float_cons, 'f'},
+ {"single", s_alpha_float_cons, 'f'},
+ {"ascii", s_alpha_stringer, 0},
+ {"asciz", s_alpha_stringer, 1},
+ {"string", s_alpha_stringer, 1},
+ {"space", s_alpha_space, 0},
+ {"skip", s_alpha_space, 0},
+ {"zero", s_alpha_space, 0},
+
+/* Unaligned data pseudos. */
+ {"uword", s_alpha_ucons, 2},
+ {"ulong", s_alpha_ucons, 4},
+ {"uquad", s_alpha_ucons, 8},
+
+#ifdef OBJ_ELF
+/* Dwarf wants these versions of unaligned. */
+ {"2byte", s_alpha_ucons, 2},
+ {"4byte", s_alpha_ucons, 4},
+ {"8byte", s_alpha_ucons, 8},
+#endif
+
+/* We don't do any optimizing, so we can safely ignore these. */
+ {"noalias", s_ignore, 0},
+ {"alias", s_ignore, 0},
+
+ {"arch", s_alpha_arch, 0},
+
+ {NULL, 0, 0},
+};
+
+/* Build a BFD section with its flags set appropriately for the .lita,
+ .lit8, or .lit4 sections. */
+
+static void
+create_literal_section (name, secp, symp)
+ const char *name;
+ segT *secp;
+ symbolS **symp;
+{
+ segT current_section = now_seg;
+ int current_subsec = now_subseg;
+ segT new_sec;
+
+ *secp = new_sec = subseg_new (name, 0);
+ subseg_set (current_section, current_subsec);
+ bfd_set_section_alignment (stdoutput, new_sec, 4);
+ bfd_set_section_flags (stdoutput, new_sec,
+ SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
+ | SEC_DATA);
+
+ S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
+}
+
+#ifdef OBJ_ECOFF
+
+/* @@@ GP selection voodoo. All of this seems overly complicated and
+ unnecessary; which is the primary reason it's for ECOFF only. */
+static inline void maybe_set_gp PARAMS ((asection *));
+
+static inline void
+maybe_set_gp (sec)
+ asection *sec;
+{
+ bfd_vma vma;
+ if (!sec)
+ return;
+ vma = bfd_get_section_vma (foo, sec);
+ if (vma && vma < alpha_gp_value)
+ alpha_gp_value = vma;
+}
+
+static void
+select_gp_value ()
+{
+ assert (alpha_gp_value == 0);
+
+ /* Get minus-one in whatever width... */
+ alpha_gp_value = 0;
+ alpha_gp_value--;
+
+ /* Select the smallest VMA of these existing sections. */
+ maybe_set_gp (alpha_lita_section);
+#if 0
+ /* These were disabled before -- should we use them? */
+ maybe_set_gp (sdata);
+ maybe_set_gp (lit8_sec);
+ maybe_set_gp (lit4_sec);
+#endif
+
+/* @@ Will a simple 0x8000 work here? If not, why not? */
+#define GP_ADJUSTMENT (0x8000 - 0x10)
+
+ alpha_gp_value += GP_ADJUSTMENT;
+
+ S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
+
+#ifdef DEBUG1
+ printf (_("Chose GP value of %lx\n"), alpha_gp_value);
+#endif
+}
+#endif /* OBJ_ECOFF */
+
+#ifdef OBJ_ELF
+/* Map 's' to SHF_ALPHA_GPREL. */
+
+int
+alpha_elf_section_letter (letter, ptr_msg)
+ int letter;
+ char **ptr_msg;
+{
+ if (letter == 's')
+ return SHF_ALPHA_GPREL;
+
+ *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
+ return -1;
+}
+
+/* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
+
+flagword
+alpha_elf_section_flags (flags, attr, type)
+ flagword flags;
+ int attr, type ATTRIBUTE_UNUSED;
+{
+ if (attr & SHF_ALPHA_GPREL)
+ flags |= SEC_SMALL_DATA;
+ return flags;
+}
+#endif /* OBJ_ELF */
+
+/* Called internally to handle all alignment needs. This takes care
+ of eliding calls to frag_align if'n the cached current alignment
+ says we've already got it, as well as taking care of the auto-align
+ feature wrt labels. */
+
+static void
+alpha_align (n, pfill, label, force)
+ int n;
+ char *pfill;
+ symbolS *label;
+ int force ATTRIBUTE_UNUSED;
+{
+ if (alpha_current_align >= n)
+ return;
+
+ if (pfill == NULL)
+ {
+ if (subseg_text_p (now_seg))
+ frag_align_code (n, 0);
+ else
+ frag_align (n, 0, 0);
+ }
+ else
+ frag_align (n, *pfill, 0);
+
+ alpha_current_align = n;
+
+ if (label != NULL && S_GET_SEGMENT (label) == now_seg)
+ {
+ symbol_set_frag (label, frag_now);
+ S_SET_VALUE (label, (valueT) frag_now_fix ());
+ }
+
+ record_alignment (now_seg, n);
+
+ /* ??? If alpha_flag_relax && force && elf, record the requested alignment
+ in a reloc for the linker to see. */
+}
+
+/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
+ of an rs_align_code fragment. */
+
+void
+alpha_handle_align (fragp)
+ fragS *fragp;
+{
+ static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f };
+ static char const nopunop[8] = {
+ 0x1f, 0x04, 0xff, 0x47,
+ 0x00, 0x00, 0xfe, 0x2f
+ };
+
+ int bytes, fix;
+ char *p;
+
+ if (fragp->fr_type != rs_align_code)
+ return;
+
+ bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
+ p = fragp->fr_literal + fragp->fr_fix;
+ fix = 0;
+
+ if (bytes & 3)
+ {
+ fix = bytes & 3;
+ memset (p, 0, fix);
+ p += fix;
+ bytes -= fix;
+ }
+
+ if (bytes & 4)
+ {
+ memcpy (p, unop, 4);
+ p += 4;
+ bytes -= 4;
+ fix += 4;
+ }
+
+ memcpy (p, nopunop, 8);
+
+ fragp->fr_fix += fix;
+ fragp->fr_var = 8;
+}
+
+/* The Alpha has support for some VAX floating point types, as well as for
+ IEEE floating point. We consider IEEE to be the primary floating point
+ format, and sneak in the VAX floating point support here. */
+#define md_atof vax_md_atof
+#include "config/atof-vax.c"
diff --git a/x/binutils/gas/config/tc-alpha.h b/x/binutils/gas/config/tc-alpha.h
new file mode 100644
index 0000000..939a14f
--- /dev/null
+++ b/x/binutils/gas/config/tc-alpha.h
@@ -0,0 +1,182 @@
+/* This file is tc-alpha.h
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+ Written by Ken Raeburn <raeburn@cygnus.com>.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_ALPHA
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#define WORKING_DOT_WORD
+
+#define TARGET_ARCH bfd_arch_alpha
+
+#ifdef TE_FreeBSD
+#define ELF_TARGET_FORMAT "elf64-alpha-freebsd"
+#endif
+#ifndef ELF_TARGET_FORMAT
+#define ELF_TARGET_FORMAT "elf64-alpha"
+#endif
+
+#define TARGET_FORMAT (OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
+ ? "ecoff-littlealpha" \
+ : OUTPUT_FLAVOR == bfd_target_elf_flavour \
+ ? ELF_TARGET_FORMAT \
+ : OUTPUT_FLAVOR == bfd_target_evax_flavour \
+ ? "vms-alpha" \
+ : "unknown-format")
+
+#define NEED_LITERAL_POOL
+#define REPEAT_CONS_EXPRESSIONS
+
+struct fix;
+struct alpha_reloc_tag;
+
+extern int alpha_force_relocation PARAMS ((struct fix *));
+extern int alpha_fix_adjustable PARAMS ((struct fix *));
+
+extern unsigned long alpha_gprmask, alpha_fprmask;
+extern valueT alpha_gp_value;
+
+#define TC_FORCE_RELOCATION(FIX) alpha_force_relocation (FIX)
+#define tc_fix_adjustable(FIX) alpha_fix_adjustable (FIX)
+#define RELOC_REQUIRES_SYMBOL
+
+/* Values passed to md_apply_fix3 don't include the symbol value. */
+#define MD_APPLY_SYM_VALUE(FIX) 0
+
+#define md_convert_frag(b,s,f) as_fatal ("alpha convert_frag\n")
+#define md_estimate_size_before_relax(f,s) \
+ (as_fatal ("estimate_size_before_relax called"),1)
+#define md_operand(x)
+
+#ifdef OBJ_EVAX
+
+/* This field keeps the symbols position in the link section. */
+#define OBJ_SYMFIELD_TYPE valueT
+
+#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) \
+ fix_new_exp (FRAG, OFF, (int)LEN, EXP, 0, \
+ LEN == 2 ? BFD_RELOC_16 \
+ : LEN == 4 ? BFD_RELOC_32 \
+ : LEN == 8 ? BFD_RELOC_64 \
+ : BFD_RELOC_ALPHA_LINKAGE);
+#endif
+
+#ifndef VMS
+#define TC_IMPLICIT_LCOMM_ALIGNMENT(size, align) \
+ do \
+ { \
+ align = 0; \
+ if (size > 1) \
+ { \
+ addressT temp = 1; \
+ while ((size & temp) == 0) \
+ ++align, temp <<= 1; \
+ } \
+ } \
+ while (0)
+#endif
+
+#define md_number_to_chars number_to_chars_littleendian
+
+extern int tc_get_register PARAMS ((int frame));
+extern void alpha_frob_ecoff_data PARAMS ((void));
+
+#define tc_frob_label(sym) alpha_define_label (sym)
+extern void alpha_define_label PARAMS ((symbolS *));
+
+#define md_cons_align(nbytes) alpha_cons_align (nbytes)
+extern void alpha_cons_align PARAMS ((int));
+
+#define HANDLE_ALIGN(fragp) alpha_handle_align (fragp)
+extern void alpha_handle_align PARAMS ((struct frag *));
+
+#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4 + 8)
+
+#ifdef OBJ_ECOFF
+#define tc_frob_file_before_adjust() alpha_frob_file_before_adjust ()
+extern void alpha_frob_file_before_adjust PARAMS ((void));
+#endif
+
+#define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs */
+
+#ifdef OBJ_ELF
+#define md_elf_section_letter alpha_elf_section_letter
+extern int alpha_elf_section_letter PARAMS ((int, char **));
+#define md_elf_section_flags alpha_elf_section_flags
+extern flagword alpha_elf_section_flags PARAMS ((flagword, int, int));
+#endif
+
+/* Whether to add support for explicit !relocation_op!sequence_number. At the
+ moment, only do this for ELF, though ECOFF could use it as well. */
+
+#ifdef OBJ_ELF
+#define RELOC_OP_P
+#endif
+
+/* Before the relocations are written, reorder them, so that user
+ supplied !lituse relocations follow the appropriate !literal
+ relocations. Also convert the gas-internal relocations to the
+ appropriate linker relocations. */
+#define tc_frob_file_before_fix() alpha_before_fix ()
+extern void alpha_before_fix PARAMS ((void));
+
+#ifdef OBJ_ELF
+#define md_end alpha_elf_md_end
+extern void alpha_elf_md_end PARAMS ((void));
+#endif
+
+/* New fields for supporting explicit relocations (such as !literal to mark
+ where a pointer is loaded from the global table, and !lituse_base to track
+ all of the normal uses of that pointer). */
+
+#define TC_FIX_TYPE struct alpha_fix_tag
+
+struct alpha_fix_tag
+{
+ struct fix *next_reloc; /* next !lituse or !gpdisp */
+ struct alpha_reloc_tag *info; /* other members with same sequence */
+};
+
+/* Initialize the TC_FIX_TYPE field. */
+#define TC_INIT_FIX_DATA(FIX) \
+do { \
+ FIX->tc_fix_data.next_reloc = (struct fix *) 0; \
+ FIX->tc_fix_data.info = (struct alpha_reloc_tag *) 0; \
+} while (0)
+
+/* Work with DEBUG5 to print fields in tc_fix_type. */
+#define TC_FIX_DATA_PRINT(STREAM, FIX) \
+do { \
+ if (FIX->tc_fix_data.info) \
+ fprintf (STREAM, "\tinfo = 0x%lx, next_reloc = 0x%lx\n", \
+ (long) FIX->tc_fix_data.info, \
+ (long) FIX->tc_fix_data.next_reloc); \
+} while (0)
+
+#define TARGET_USE_CFIPOP 1
+
+#define tc_cfi_frame_initial_instructions alpha_cfi_frame_initial_instructions
+extern void alpha_cfi_frame_initial_instructions(void);
+
+#define DWARF2_LINE_MIN_INSN_LENGTH 4
+#define DWARF2_DEFAULT_RETURN_COLUMN 26
+#define DWARF2_CIE_DATA_ALIGNMENT -8
diff --git a/x/binutils/gas/config/tc-arc.c b/x/binutils/gas/config/tc-arc.c
new file mode 100644
index 0000000..60cfa34
--- /dev/null
+++ b/x/binutils/gas/config/tc-arc.c
@@ -0,0 +1,2012 @@
+/* tc-arc.c -- Assembler for the ARC
+ Copyright 1994, 1995, 1997, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+ Contributed by Doug Evans (dje@cygnus.com).
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <stdio.h>
+#include "libiberty.h"
+#include "as.h"
+#include "struc-symbol.h"
+#include "safe-ctype.h"
+#include "subsegs.h"
+#include "opcode/arc.h"
+#include "../opcodes/arc-ext.h"
+#include "elf/arc.h"
+#include "dwarf2dbg.h"
+
+extern int arc_get_mach PARAMS ((char *));
+extern int arc_operand_type PARAMS ((int));
+extern int arc_insn_not_jl PARAMS ((arc_insn));
+extern int arc_limm_fixup_adjust PARAMS ((arc_insn));
+extern int arc_get_noshortcut_flag PARAMS ((void));
+extern int arc_set_ext_seg PARAMS ((void));
+extern void arc_code_symbol PARAMS ((expressionS *));
+
+static arc_insn arc_insert_operand PARAMS ((arc_insn,
+ const struct arc_operand *, int,
+ const struct arc_operand_value *,
+ offsetT, char *, unsigned int));
+static void arc_common PARAMS ((int));
+static void arc_extinst PARAMS ((int));
+static void arc_extoper PARAMS ((int));
+static void arc_option PARAMS ((int));
+static int get_arc_exp_reloc_type PARAMS ((int, int, expressionS *,
+ expressionS *));
+
+static void init_opcode_tables PARAMS ((int));
+
+const struct suffix_classes {
+ char *name;
+ int len;
+} suffixclass[] = {
+ { "SUFFIX_COND|SUFFIX_FLAG",23 },
+ { "SUFFIX_FLAG", 11 },
+ { "SUFFIX_COND", 11 },
+ { "SUFFIX_NONE", 11 }
+};
+
+#define MAXSUFFIXCLASS (sizeof (suffixclass) / sizeof (struct suffix_classes))
+
+const struct syntax_classes {
+ char *name;
+ int len;
+ int class;
+} syntaxclass[] = {
+ { "SYNTAX_3OP|OP1_MUST_BE_IMM", 26, SYNTAX_3OP|OP1_MUST_BE_IMM|SYNTAX_VALID },
+ { "OP1_MUST_BE_IMM|SYNTAX_3OP", 26, OP1_MUST_BE_IMM|SYNTAX_3OP|SYNTAX_VALID },
+ { "SYNTAX_2OP|OP1_IMM_IMPLIED", 26, SYNTAX_2OP|OP1_IMM_IMPLIED|SYNTAX_VALID },
+ { "OP1_IMM_IMPLIED|SYNTAX_2OP", 26, OP1_IMM_IMPLIED|SYNTAX_2OP|SYNTAX_VALID },
+ { "SYNTAX_3OP", 10, SYNTAX_3OP|SYNTAX_VALID },
+ { "SYNTAX_2OP", 10, SYNTAX_2OP|SYNTAX_VALID }
+};
+
+#define MAXSYNTAXCLASS (sizeof (syntaxclass) / sizeof (struct syntax_classes))
+
+const pseudo_typeS md_pseudo_table[] = {
+ { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */
+ { "comm", arc_common, 0 },
+ { "common", arc_common, 0 },
+ { "lcomm", arc_common, 1 },
+ { "lcommon", arc_common, 1 },
+ { "2byte", cons, 2 },
+ { "half", cons, 2 },
+ { "short", cons, 2 },
+ { "3byte", cons, 3 },
+ { "4byte", cons, 4 },
+ { "word", cons, 4 },
+ { "option", arc_option, 0 },
+ { "cpu", arc_option, 0 },
+ { "block", s_space, 0 },
+ { "extcondcode", arc_extoper, 0 },
+ { "extcoreregister", arc_extoper, 1 },
+ { "extauxregister", arc_extoper, 2 },
+ { "extinstruction", arc_extinst, 0 },
+ { NULL, 0, 0 },
+};
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful. */
+const char comment_chars[] = "#;";
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output */
+/* Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output. */
+/* Also note that comments started like this one will always
+ work if '/' isn't otherwise defined. */
+const char line_comment_chars[] = "#";
+
+const char line_separator_chars[] = "";
+
+/* Chars that can be used to separate mant from exp in floating point nums. */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant
+ As in 0f12.456 or 0d1.2345e12. */
+const char FLT_CHARS[] = "rRsSfFdD";
+
+/* Byte order. */
+extern int target_big_endian;
+const char *arc_target_format = DEFAULT_TARGET_FORMAT;
+static int byte_order = DEFAULT_BYTE_ORDER;
+
+static segT arcext_section;
+
+/* One of bfd_mach_arc_n. */
+static int arc_mach_type = bfd_mach_arc_6;
+
+/* Non-zero if the cpu type has been explicitly specified. */
+static int mach_type_specified_p = 0;
+
+/* Non-zero if opcode tables have been initialized.
+ A .option command must appear before any instructions. */
+static int cpu_tables_init_p = 0;
+
+static struct hash_control *arc_suffix_hash = NULL;
+
+const char *md_shortopts = "";
+struct option md_longopts[] = {
+#define OPTION_EB (OPTION_MD_BASE + 0)
+ { "EB", no_argument, NULL, OPTION_EB },
+#define OPTION_EL (OPTION_MD_BASE + 1)
+ { "EL", no_argument, NULL, OPTION_EL },
+#define OPTION_ARC5 (OPTION_MD_BASE + 2)
+ { "marc5", no_argument, NULL, OPTION_ARC5 },
+ { "pre-v6", no_argument, NULL, OPTION_ARC5 },
+#define OPTION_ARC6 (OPTION_MD_BASE + 3)
+ { "marc6", no_argument, NULL, OPTION_ARC6 },
+#define OPTION_ARC7 (OPTION_MD_BASE + 4)
+ { "marc7", no_argument, NULL, OPTION_ARC7 },
+#define OPTION_ARC8 (OPTION_MD_BASE + 5)
+ { "marc8", no_argument, NULL, OPTION_ARC8 },
+#define OPTION_ARC (OPTION_MD_BASE + 6)
+ { "marc", no_argument, NULL, OPTION_ARC },
+ { NULL, no_argument, NULL, 0 }
+};
+size_t md_longopts_size = sizeof (md_longopts);
+
+#define IS_SYMBOL_OPERAND(o) \
+ ((o) == 'b' || (o) == 'c' || (o) == 's' || (o) == 'o' || (o) == 'O')
+
+struct arc_operand_value *get_ext_suffix (char *s);
+
+/* Invocation line includes a switch not recognized by the base assembler.
+ See if it's a processor-specific option. */
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg ATTRIBUTE_UNUSED;
+{
+ switch (c)
+ {
+ case OPTION_ARC5:
+ arc_mach_type = bfd_mach_arc_5;
+ break;
+ case OPTION_ARC:
+ case OPTION_ARC6:
+ arc_mach_type = bfd_mach_arc_6;
+ break;
+ case OPTION_ARC7:
+ arc_mach_type = bfd_mach_arc_7;
+ break;
+ case OPTION_ARC8:
+ arc_mach_type = bfd_mach_arc_8;
+ break;
+ case OPTION_EB:
+ byte_order = BIG_ENDIAN;
+ arc_target_format = "elf32-bigarc";
+ break;
+ case OPTION_EL:
+ byte_order = LITTLE_ENDIAN;
+ arc_target_format = "elf32-littlearc";
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf (stream, "\
+ARC Options:\n\
+ -marc[5|6|7|8] select processor variant (default arc%d)\n\
+ -EB assemble code for a big endian cpu\n\
+ -EL assemble code for a little endian cpu\n", arc_mach_type + 5);
+}
+
+/* This function is called once, at assembler startup time. It should
+ set up all the tables, etc. that the MD part of the assembler will need.
+ Opcode selection is deferred until later because we might see a .option
+ command. */
+
+void
+md_begin ()
+{
+ /* The endianness can be chosen "at the factory". */
+ target_big_endian = byte_order == BIG_ENDIAN;
+
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
+ as_warn ("could not set architecture and machine");
+
+ /* This call is necessary because we need to initialize `arc_operand_map'
+ which may be needed before we see the first insn. */
+ arc_opcode_init_tables (arc_get_opcode_mach (arc_mach_type,
+ target_big_endian));
+}
+
+/* Initialize the various opcode and operand tables.
+ MACH is one of bfd_mach_arc_xxx. */
+static void
+init_opcode_tables (mach)
+ int mach;
+{
+ int i;
+ char *last;
+
+ if ((arc_suffix_hash = hash_new ()) == NULL)
+ as_fatal ("virtual memory exhausted");
+
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
+ as_warn ("could not set architecture and machine");
+
+ /* This initializes a few things in arc-opc.c that we need.
+ This must be called before the various arc_xxx_supported fns. */
+ arc_opcode_init_tables (arc_get_opcode_mach (mach, target_big_endian));
+
+ /* Only put the first entry of each equivalently named suffix in the
+ table. */
+ last = "";
+ for (i = 0; i < arc_suffixes_count; i++)
+ {
+ if (strcmp (arc_suffixes[i].name, last) != 0)
+ hash_insert (arc_suffix_hash, arc_suffixes[i].name, (PTR) (arc_suffixes + i));
+ last = arc_suffixes[i].name;
+ }
+
+ /* Since registers don't have a prefix, we put them in the symbol table so
+ they can't be used as symbols. This also simplifies argument parsing as
+ we can let gas parse registers for us. The recorded register number is
+ the address of the register's entry in arc_reg_names.
+
+ If the register name is already in the table, then the existing
+ definition is assumed to be from an .ExtCoreRegister pseudo-op. */
+
+ for (i = 0; i < arc_reg_names_count; i++)
+ {
+ if (symbol_find (arc_reg_names[i].name))
+ continue;
+ /* Use symbol_create here instead of symbol_new so we don't try to
+ output registers into the object file's symbol table. */
+ symbol_table_insert (symbol_create (arc_reg_names[i].name,
+ reg_section,
+ (int) &arc_reg_names[i],
+ &zero_address_frag));
+ }
+
+ /* Tell `.option' it's too late. */
+ cpu_tables_init_p = 1;
+}
+
+/* Insert an operand value into an instruction.
+ If REG is non-NULL, it is a register number and ignore VAL. */
+
+static arc_insn
+arc_insert_operand (insn, operand, mods, reg, val, file, line)
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ offsetT val;
+ char *file;
+ unsigned int line;
+{
+ if (operand->bits != 32)
+ {
+ long min, max;
+ offsetT test;
+
+ if ((operand->flags & ARC_OPERAND_SIGNED) != 0)
+ {
+ if ((operand->flags & ARC_OPERAND_SIGNOPT) != 0)
+ max = (1 << operand->bits) - 1;
+ else
+ max = (1 << (operand->bits - 1)) - 1;
+ min = - (1 << (operand->bits - 1));
+ }
+ else
+ {
+ max = (1 << operand->bits) - 1;
+ min = 0;
+ }
+
+ if ((operand->flags & ARC_OPERAND_NEGATIVE) != 0)
+ test = - val;
+ else
+ test = val;
+
+ if (test < (offsetT) min || test > (offsetT) max)
+ {
+ const char *err =
+ "operand out of range (%s not between %ld and %ld)";
+ char buf[100];
+
+ sprint_value (buf, test);
+ if (file == (char *) NULL)
+ as_warn (err, buf, min, max);
+ else
+ as_warn_where (file, line, err, buf, min, max);
+ }
+ }
+
+ if (operand->insert)
+ {
+ const char *errmsg;
+
+ errmsg = NULL;
+ insn = (*operand->insert) (insn, operand, mods, reg, (long) val, &errmsg);
+ if (errmsg != (const char *) NULL)
+ as_warn (errmsg);
+ }
+ else
+ insn |= (((long) val & ((1 << operand->bits) - 1))
+ << operand->shift);
+
+ return insn;
+}
+
+/* We need to keep a list of fixups. We can't simply generate them as
+ we go, because that would require us to first create the frag, and
+ that would screw up references to ``.''. */
+
+struct arc_fixup {
+ /* index into `arc_operands' */
+ int opindex;
+ expressionS exp;
+};
+
+#define MAX_FIXUPS 5
+
+#define MAX_SUFFIXES 5
+
+/* This routine is called for each instruction to be assembled. */
+
+void
+md_assemble (str)
+ char *str;
+{
+ const struct arc_opcode *opcode;
+ const struct arc_opcode *std_opcode;
+ struct arc_opcode *ext_opcode;
+ char *start;
+ const char *last_errmsg = 0;
+ arc_insn insn;
+ static int init_tables_p = 0;
+
+ /* Opcode table initialization is deferred until here because we have to
+ wait for a possible .option command. */
+ if (!init_tables_p)
+ {
+ init_opcode_tables (arc_mach_type);
+ init_tables_p = 1;
+ }
+
+ /* Skip leading white space. */
+ while (ISSPACE (*str))
+ str++;
+
+ /* The instructions are stored in lists hashed by the first letter (though
+ we needn't care how they're hashed). Get the first in the list. */
+
+ ext_opcode = arc_ext_opcodes;
+ std_opcode = arc_opcode_lookup_asm (str);
+
+ /* Keep looking until we find a match. */
+
+ start = str;
+ for (opcode = (ext_opcode ? ext_opcode : std_opcode);
+ opcode != NULL;
+ opcode = (ARC_OPCODE_NEXT_ASM (opcode)
+ ? ARC_OPCODE_NEXT_ASM (opcode)
+ : (ext_opcode ? ext_opcode = NULL, std_opcode : NULL)))
+ {
+ int past_opcode_p, fc, num_suffixes;
+ int fix_up_at = 0;
+ char *syn;
+ struct arc_fixup fixups[MAX_FIXUPS];
+ /* Used as a sanity check. If we need a limm reloc, make sure we ask
+ for an extra 4 bytes from frag_more. */
+ int limm_reloc_p;
+ int ext_suffix_p;
+ const struct arc_operand_value *insn_suffixes[MAX_SUFFIXES];
+
+ /* Is this opcode supported by the selected cpu? */
+ if (! arc_opcode_supported (opcode))
+ continue;
+
+ /* Scan the syntax string. If it doesn't match, try the next one. */
+
+ arc_opcode_init_insert ();
+ insn = opcode->value;
+ fc = 0;
+ past_opcode_p = 0;
+ num_suffixes = 0;
+ limm_reloc_p = 0;
+ ext_suffix_p = 0;
+
+ /* We don't check for (*str != '\0') here because we want to parse
+ any trailing fake arguments in the syntax string. */
+ for (str = start, syn = opcode->syntax; *syn != '\0';)
+ {
+ int mods;
+ const struct arc_operand *operand;
+
+ /* Non operand chars must match exactly. */
+ if (*syn != '%' || *++syn == '%')
+ {
+ /* Handle '+' specially as we want to allow "ld r0,[sp-4]". */
+ /* ??? The syntax has changed to [sp,-4]. */
+ if (0 && *syn == '+' && *str == '-')
+ {
+ /* Skip over syn's +, but leave str's - alone.
+ That makes the case identical to "ld r0,[sp+-4]". */
+ ++syn;
+ }
+ else if (*str == *syn)
+ {
+ if (*syn == ' ')
+ past_opcode_p = 1;
+ ++syn;
+ ++str;
+ }
+ else
+ break;
+ continue;
+ }
+
+ /* We have an operand. Pick out any modifiers. */
+ mods = 0;
+ while (ARC_MOD_P (arc_operands[arc_operand_map[(int) *syn]].flags))
+ {
+ mods |= arc_operands[arc_operand_map[(int) *syn]].flags & ARC_MOD_BITS;
+ ++syn;
+ }
+ operand = arc_operands + arc_operand_map[(int) *syn];
+ if (operand->fmt == 0)
+ as_fatal ("unknown syntax format character `%c'", *syn);
+
+ if (operand->flags & ARC_OPERAND_FAKE)
+ {
+ const char *errmsg = NULL;
+ if (operand->insert)
+ {
+ insn = (*operand->insert) (insn, operand, mods, NULL, 0, &errmsg);
+ if (errmsg != (const char *) NULL)
+ {
+ last_errmsg = errmsg;
+ if (operand->flags & ARC_OPERAND_ERROR)
+ {
+ as_bad (errmsg);
+ return;
+ }
+ else if (operand->flags & ARC_OPERAND_WARN)
+ as_warn (errmsg);
+ break;
+ }
+ if (limm_reloc_p
+ && (operand->flags && operand->flags & ARC_OPERAND_LIMM)
+ && (operand->flags &
+ (ARC_OPERAND_ABSOLUTE_BRANCH | ARC_OPERAND_ADDRESS)))
+ {
+ fixups[fix_up_at].opindex = arc_operand_map[operand->fmt];
+ }
+ }
+ ++syn;
+ }
+ /* Are we finished with suffixes? */
+ else if (!past_opcode_p)
+ {
+ int found;
+ char c;
+ char *s, *t;
+ const struct arc_operand_value *suf, *suffix_end;
+ const struct arc_operand_value *suffix = NULL;
+
+ if (!(operand->flags & ARC_OPERAND_SUFFIX))
+ abort ();
+
+ /* If we're at a space in the input string, we want to skip the
+ remaining suffixes. There may be some fake ones though, so
+ just go on to try the next one. */
+ if (*str == ' ')
+ {
+ ++syn;
+ continue;
+ }
+
+ s = str;
+ if (mods & ARC_MOD_DOT)
+ {
+ if (*s != '.')
+ break;
+ ++s;
+ }
+ else
+ {
+ /* This can happen in "b.nd foo" and we're currently looking
+ for "%q" (ie: a condition code suffix). */
+ if (*s == '.')
+ {
+ ++syn;
+ continue;
+ }
+ }
+
+ /* Pick the suffix out and look it up via the hash table. */
+ for (t = s; *t && ISALNUM (*t); ++t)
+ continue;
+ c = *t;
+ *t = '\0';
+ if ((suf = get_ext_suffix (s)))
+ ext_suffix_p = 1;
+ else
+ suf = hash_find (arc_suffix_hash, s);
+ if (!suf)
+ {
+ /* This can happen in "blle foo" and we're currently using
+ the template "b%q%.n %j". The "bl" insn occurs later in
+ the table so "lle" isn't an illegal suffix. */
+ *t = c;
+ break;
+ }
+
+ /* Is it the right type? Note that the same character is used
+ several times, so we have to examine all of them. This is
+ relatively efficient as equivalent entries are kept
+ together. If it's not the right type, don't increment `str'
+ so we try the next one in the series. */
+ found = 0;
+ if (ext_suffix_p && arc_operands[suf->type].fmt == *syn)
+ {
+ /* Insert the suffix's value into the insn. */
+ *t = c;
+ if (operand->insert)
+ insn = (*operand->insert) (insn, operand,
+ mods, NULL, suf->value,
+ NULL);
+ else
+ insn |= suf->value << operand->shift;
+
+ str = t;
+ found = 1;
+ }
+ else
+ {
+ *t = c;
+ suffix_end = arc_suffixes + arc_suffixes_count;
+ for (suffix = suf;
+ suffix < suffix_end && strcmp (suffix->name, suf->name) == 0;
+ ++suffix)
+ {
+ if (arc_operands[suffix->type].fmt == *syn)
+ {
+ /* Insert the suffix's value into the insn. */
+ if (operand->insert)
+ insn = (*operand->insert) (insn, operand,
+ mods, NULL, suffix->value,
+ NULL);
+ else
+ insn |= suffix->value << operand->shift;
+
+ str = t;
+ found = 1;
+ break;
+ }
+ }
+ }
+ ++syn;
+ if (!found)
+ /* Wrong type. Just go on to try next insn entry. */
+ ;
+ else
+ {
+ if (num_suffixes == MAX_SUFFIXES)
+ as_bad ("too many suffixes");
+ else
+ insn_suffixes[num_suffixes++] = suffix;
+ }
+ }
+ else
+ /* This is either a register or an expression of some kind. */
+ {
+ char *hold;
+ const struct arc_operand_value *reg = NULL;
+ long value = 0;
+ expressionS exp;
+
+ if (operand->flags & ARC_OPERAND_SUFFIX)
+ abort ();
+
+ /* Is there anything left to parse?
+ We don't check for this at the top because we want to parse
+ any trailing fake arguments in the syntax string. */
+ if (is_end_of_line[(unsigned char) *str])
+ break;
+
+ /* Parse the operand. */
+ hold = input_line_pointer;
+ input_line_pointer = str;
+ expression (&exp);
+ str = input_line_pointer;
+ input_line_pointer = hold;
+
+ if (exp.X_op == O_illegal)
+ as_bad ("illegal operand");
+ else if (exp.X_op == O_absent)
+ as_bad ("missing operand");
+ else if (exp.X_op == O_constant)
+ {
+ value = exp.X_add_number;
+ }
+ else if (exp.X_op == O_register)
+ {
+ reg = (struct arc_operand_value *) exp.X_add_number;
+ }
+#define IS_REG_DEST_OPERAND(o) ((o) == 'a')
+ else if (IS_REG_DEST_OPERAND (*syn))
+ as_bad ("symbol as destination register");
+ else
+ {
+ if (!strncmp (str, "@h30", 4))
+ {
+ arc_code_symbol (&exp);
+ str += 4;
+ }
+ /* We need to generate a fixup for this expression. */
+ if (fc >= MAX_FIXUPS)
+ as_fatal ("too many fixups");
+ fixups[fc].exp = exp;
+ /* We don't support shimm relocs. break here to force
+ the assembler to output a limm. */
+#define IS_REG_SHIMM_OFFSET(o) ((o) == 'd')
+ if (IS_REG_SHIMM_OFFSET (*syn))
+ break;
+ /* If this is a register constant (IE: one whose
+ register value gets stored as 61-63) then this
+ must be a limm. */
+ /* ??? This bit could use some cleaning up.
+ Referencing the format chars like this goes
+ against style. */
+ if (IS_SYMBOL_OPERAND (*syn))
+ {
+ const char *junk;
+ limm_reloc_p = 1;
+ /* Save this, we don't yet know what reloc to use. */
+ fix_up_at = fc;
+ /* Tell insert_reg we need a limm. This is
+ needed because the value at this point is
+ zero, a shimm. */
+ /* ??? We need a cleaner interface than this. */
+ (*arc_operands[arc_operand_map['Q']].insert)
+ (insn, operand, mods, reg, 0L, &junk);
+ }
+ else
+ fixups[fc].opindex = arc_operand_map[(int) *syn];
+ ++fc;
+ value = 0;
+ }
+
+ /* Insert the register or expression into the instruction. */
+ if (operand->insert)
+ {
+ const char *errmsg = NULL;
+ insn = (*operand->insert) (insn, operand, mods,
+ reg, (long) value, &errmsg);
+ if (errmsg != (const char *) NULL)
+ {
+ last_errmsg = errmsg;
+ if (operand->flags & ARC_OPERAND_ERROR)
+ {
+ as_bad (errmsg);
+ return;
+ }
+ else if (operand->flags & ARC_OPERAND_WARN)
+ as_warn (errmsg);
+ break;
+ }
+ }
+ else
+ insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
+
+ ++syn;
+ }
+ }
+
+ /* If we're at the end of the syntax string, we're done. */
+ /* FIXME: try to move this to a separate function. */
+ if (*syn == '\0')
+ {
+ int i;
+ char *f;
+ long limm, limm_p;
+
+ /* For the moment we assume a valid `str' can only contain blanks
+ now. IE: We needn't try again with a longer version of the
+ insn and it is assumed that longer versions of insns appear
+ before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
+
+ while (ISSPACE (*str))
+ ++str;
+
+ if (!is_end_of_line[(unsigned char) *str])
+ as_bad ("junk at end of line: `%s'", str);
+
+ /* Is there a limm value? */
+ limm_p = arc_opcode_limm_p (&limm);
+
+ /* Perform various error and warning tests. */
+
+ {
+ static int in_delay_slot_p = 0;
+ static int prev_insn_needs_cc_nop_p = 0;
+ /* delay slot type seen */
+ int delay_slot_type = ARC_DELAY_NONE;
+ /* conditional execution flag seen */
+ int conditional = 0;
+ /* 1 if condition codes are being set */
+ int cc_set_p = 0;
+ /* 1 if conditional branch, including `b' "branch always" */
+ int cond_branch_p = opcode->flags & ARC_OPCODE_COND_BRANCH;
+
+ for (i = 0; i < num_suffixes; ++i)
+ {
+ switch (arc_operands[insn_suffixes[i]->type].fmt)
+ {
+ case 'n':
+ delay_slot_type = insn_suffixes[i]->value;
+ break;
+ case 'q':
+ conditional = insn_suffixes[i]->value;
+ break;
+ case 'f':
+ cc_set_p = 1;
+ break;
+ }
+ }
+
+ /* Putting an insn with a limm value in a delay slot is supposed to
+ be legal, but let's warn the user anyway. Ditto for 8 byte
+ jumps with delay slots. */
+ if (in_delay_slot_p && limm_p)
+ as_warn ("8 byte instruction in delay slot");
+ if (delay_slot_type != ARC_DELAY_NONE
+ && limm_p && arc_insn_not_jl (insn)) /* except for jl addr */
+ as_warn ("8 byte jump instruction with delay slot");
+ in_delay_slot_p = (delay_slot_type != ARC_DELAY_NONE) && !limm_p;
+
+ /* Warn when a conditional branch immediately follows a set of
+ the condition codes. Note that this needn't be done if the
+ insn that sets the condition codes uses a limm. */
+ if (cond_branch_p && conditional != 0 /* 0 = "always" */
+ && prev_insn_needs_cc_nop_p && arc_mach_type == bfd_mach_arc_5)
+ as_warn ("conditional branch follows set of flags");
+ prev_insn_needs_cc_nop_p =
+ /* FIXME: ??? not required:
+ (delay_slot_type != ARC_DELAY_NONE) && */
+ cc_set_p && !limm_p;
+ }
+
+ /* Write out the instruction.
+ It is important to fetch enough space in one call to `frag_more'.
+ We use (f - frag_now->fr_literal) to compute where we are and we
+ don't want frag_now to change between calls. */
+ if (limm_p)
+ {
+ f = frag_more (8);
+ md_number_to_chars (f, insn, 4);
+ md_number_to_chars (f + 4, limm, 4);
+ dwarf2_emit_insn (8);
+ }
+ else if (limm_reloc_p)
+ {
+ /* We need a limm reloc, but the tables think we don't. */
+ abort ();
+ }
+ else
+ {
+ f = frag_more (4);
+ md_number_to_chars (f, insn, 4);
+ dwarf2_emit_insn (4);
+ }
+
+ /* Create any fixups. */
+ for (i = 0; i < fc; ++i)
+ {
+ int op_type, reloc_type;
+ expressionS exptmp;
+ const struct arc_operand *operand;
+
+ /* Create a fixup for this operand.
+ At this point we do not use a bfd_reloc_code_real_type for
+ operands residing in the insn, but instead just use the
+ operand index. This lets us easily handle fixups for any
+ operand type, although that is admittedly not a very exciting
+ feature. We pick a BFD reloc type in md_apply_fix3.
+
+ Limm values (4 byte immediate "constants") must be treated
+ normally because they're not part of the actual insn word
+ and thus the insertion routines don't handle them. */
+
+ if (arc_operands[fixups[i].opindex].flags & ARC_OPERAND_LIMM)
+ {
+ /* Modify the fixup addend as required by the cpu. */
+ fixups[i].exp.X_add_number += arc_limm_fixup_adjust (insn);
+ op_type = fixups[i].opindex;
+ /* FIXME: can we add this data to the operand table? */
+ if (op_type == arc_operand_map['L']
+ || op_type == arc_operand_map['s']
+ || op_type == arc_operand_map['o']
+ || op_type == arc_operand_map['O'])
+ reloc_type = BFD_RELOC_32;
+ else if (op_type == arc_operand_map['J'])
+ reloc_type = BFD_RELOC_ARC_B26;
+ else
+ abort ();
+ reloc_type = get_arc_exp_reloc_type (1, reloc_type,
+ &fixups[i].exp,
+ &exptmp);
+ }
+ else
+ {
+ op_type = get_arc_exp_reloc_type (0, fixups[i].opindex,
+ &fixups[i].exp, &exptmp);
+ reloc_type = op_type + (int) BFD_RELOC_UNUSED;
+ }
+ operand = &arc_operands[op_type];
+ fix_new_exp (frag_now,
+ ((f - frag_now->fr_literal)
+ + (operand->flags & ARC_OPERAND_LIMM ? 4 : 0)), 4,
+ &exptmp,
+ (operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0,
+ (bfd_reloc_code_real_type) reloc_type);
+ }
+
+ /* All done. */
+ return;
+ }
+
+ /* Try the next entry. */
+ }
+
+ if (NULL == last_errmsg)
+ as_bad ("bad instruction `%s'", start);
+ else
+ as_bad (last_errmsg);
+}
+
+static void
+arc_extoper (opertype)
+ int opertype;
+{
+ char *name;
+ char *mode;
+ char c;
+ char *p;
+ int imode = 0;
+ int number;
+ struct arc_ext_operand_value *ext_oper;
+ symbolS *symbolP;
+
+ segT old_sec;
+ int old_subsec;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ name = xstrdup (name);
+
+ p = name;
+ while (*p)
+ {
+ *p = TOLOWER (*p);
+ p++;
+ }
+
+ /* just after name is now '\0' */
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("expected comma after operand name");
+ ignore_rest_of_line ();
+ free (name);
+ return;
+ }
+
+ input_line_pointer++; /* skip ',' */
+ number = get_absolute_expression ();
+
+ if (number < 0)
+ {
+ as_bad ("negative operand number %d", number);
+ ignore_rest_of_line ();
+ free (name);
+ return;
+ }
+
+ if (opertype)
+ {
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("expected comma after register-number");
+ ignore_rest_of_line ();
+ free (name);
+ return;
+ }
+
+ input_line_pointer++; /* skip ',' */
+ mode = input_line_pointer;
+
+ if (!strncmp (mode, "r|w", 3))
+ {
+ imode = 0;
+ input_line_pointer += 3;
+ }
+ else
+ {
+ if (!strncmp (mode, "r", 1))
+ {
+ imode = ARC_REGISTER_READONLY;
+ input_line_pointer += 1;
+ }
+ else
+ {
+ if (strncmp (mode, "w", 1))
+ {
+ as_bad ("invalid mode");
+ ignore_rest_of_line ();
+ free (name);
+ return;
+ }
+ else
+ {
+ imode = ARC_REGISTER_WRITEONLY;
+ input_line_pointer += 1;
+ }
+ }
+ }
+ SKIP_WHITESPACE ();
+ if (1 == opertype)
+ {
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("expected comma after register-mode");
+ ignore_rest_of_line ();
+ free (name);
+ return;
+ }
+
+ input_line_pointer++; /* skip ',' */
+
+ if (!strncmp (input_line_pointer, "cannot_shortcut", 15))
+ {
+ imode |= arc_get_noshortcut_flag ();
+ input_line_pointer += 15;
+ }
+ else
+ {
+ if (strncmp (input_line_pointer, "can_shortcut", 12))
+ {
+ as_bad ("shortcut designator invalid");
+ ignore_rest_of_line ();
+ free (name);
+ return;
+ }
+ else
+ {
+ input_line_pointer += 12;
+ }
+ }
+ }
+ }
+
+ if ((opertype == 1) && number > 60)
+ {
+ as_bad ("core register value (%d) too large", number);
+ ignore_rest_of_line ();
+ free (name);
+ return;
+ }
+
+ if ((opertype == 0) && number > 31)
+ {
+ as_bad ("condition code value (%d) too large", number);
+ ignore_rest_of_line ();
+ free (name);
+ return;
+ }
+
+ ext_oper = (struct arc_ext_operand_value *) \
+ xmalloc (sizeof (struct arc_ext_operand_value));
+
+ if (opertype)
+ {
+ /* If the symbol already exists, point it at the new definition. */
+ if ((symbolP = symbol_find (name)))
+ {
+ if (S_GET_SEGMENT (symbolP) == reg_section)
+ S_SET_VALUE (symbolP, (int) &ext_oper->operand);
+ else
+ {
+ as_bad ("attempt to override symbol: %s", name);
+ ignore_rest_of_line ();
+ free (name);
+ free (ext_oper);
+ return;
+ }
+ }
+ else
+ {
+ /* If its not there, add it. */
+ symbol_table_insert (symbol_create (name, reg_section,
+ (int) &ext_oper->operand, &zero_address_frag));
+ }
+ }
+
+ ext_oper->operand.name = name;
+ ext_oper->operand.value = number;
+ ext_oper->operand.type = arc_operand_type (opertype);
+ ext_oper->operand.flags = imode;
+
+ ext_oper->next = arc_ext_operands;
+ arc_ext_operands = ext_oper;
+
+ /* OK, now that we know what this operand is, put a description in
+ the arc extension section of the output file. */
+
+ old_sec = now_seg;
+ old_subsec = now_subseg;
+
+ arc_set_ext_seg ();
+
+ switch (opertype)
+ {
+ case 0:
+ p = frag_more (1);
+ *p = 3 + strlen (name) + 1;
+ p = frag_more (1);
+ *p = EXT_COND_CODE;
+ p = frag_more (1);
+ *p = number;
+ p = frag_more (strlen (name) + 1);
+ strcpy (p, name);
+ break;
+ case 1:
+ p = frag_more (1);
+ *p = 3 + strlen (name) + 1;
+ p = frag_more (1);
+ *p = EXT_CORE_REGISTER;
+ p = frag_more (1);
+ *p = number;
+ p = frag_more (strlen (name) + 1);
+ strcpy (p, name);
+ break;
+ case 2:
+ p = frag_more (1);
+ *p = 6 + strlen (name) + 1;
+ p = frag_more (1);
+ *p = EXT_AUX_REGISTER;
+ p = frag_more (1);
+ *p = number >> 24 & 0xff;
+ p = frag_more (1);
+ *p = number >> 16 & 0xff;
+ p = frag_more (1);
+ *p = number >> 8 & 0xff;
+ p = frag_more (1);
+ *p = number & 0xff;
+ p = frag_more (strlen (name) + 1);
+ strcpy (p, name);
+ break;
+ default:
+ as_bad ("invalid opertype");
+ ignore_rest_of_line ();
+ free (name);
+ return;
+ break;
+ }
+
+ subseg_set (old_sec, old_subsec);
+
+ /* Enter all registers into the symbol table. */
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+arc_extinst (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ unsigned char syntax[129];
+ char *name;
+ char *p;
+ char c;
+ int suffixcode = -1;
+ int opcode, subopcode;
+ int i;
+ int class = 0;
+ int name_len;
+ struct arc_opcode *ext_op;
+
+ segT old_sec;
+ int old_subsec;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ name = xstrdup (name);
+ strcpy (syntax, name);
+ name_len = strlen (name);
+
+ /* just after name is now '\0' */
+ p = input_line_pointer;
+ *p = c;
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("expected comma after operand name");
+ ignore_rest_of_line ();
+ return;
+ }
+
+ input_line_pointer++; /* skip ',' */
+ opcode = get_absolute_expression ();
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("expected comma after opcode");
+ ignore_rest_of_line ();
+ return;
+ }
+
+ input_line_pointer++; /* skip ',' */
+ subopcode = get_absolute_expression ();
+
+ if (subopcode < 0)
+ {
+ as_bad ("negative subopcode %d", subopcode);
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (subopcode)
+ {
+ if (3 != opcode)
+ {
+ as_bad ("subcode value found when opcode not equal 0x03");
+ ignore_rest_of_line ();
+ return;
+ }
+ else
+ {
+ if (subopcode < 0x09 || subopcode == 0x3f)
+ {
+ as_bad ("invalid subopcode %d", subopcode);
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ }
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("expected comma after subopcode");
+ ignore_rest_of_line ();
+ return;
+ }
+
+ input_line_pointer++; /* skip ',' */
+
+ for (i = 0; i < (int) MAXSUFFIXCLASS; i++)
+ {
+ if (!strncmp (suffixclass[i].name,input_line_pointer, suffixclass[i].len))
+ {
+ suffixcode = i;
+ input_line_pointer += suffixclass[i].len;
+ break;
+ }
+ }
+
+ if (-1 == suffixcode)
+ {
+ as_bad ("invalid suffix class");
+ ignore_rest_of_line ();
+ return;
+ }
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("expected comma after suffix class");
+ ignore_rest_of_line ();
+ return;
+ }
+
+ input_line_pointer++; /* skip ',' */
+
+ for (i = 0; i < (int) MAXSYNTAXCLASS; i++)
+ {
+ if (!strncmp (syntaxclass[i].name,input_line_pointer, syntaxclass[i].len))
+ {
+ class = syntaxclass[i].class;
+ input_line_pointer += syntaxclass[i].len;
+ break;
+ }
+ }
+
+ if (0 == (SYNTAX_VALID & class))
+ {
+ as_bad ("invalid syntax class");
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if ((0x3 == opcode) & (class & SYNTAX_3OP))
+ {
+ as_bad ("opcode 0x3 and SYNTAX_3OP invalid");
+ ignore_rest_of_line ();
+ return;
+ }
+
+ switch (suffixcode)
+ {
+ case 0:
+ strcat (syntax, "%.q%.f ");
+ break;
+ case 1:
+ strcat (syntax, "%.f ");
+ break;
+ case 2:
+ strcat (syntax, "%.q ");
+ break;
+ case 3:
+ strcat (syntax, " ");
+ break;
+ default:
+ as_bad ("unknown suffix class");
+ ignore_rest_of_line ();
+ return;
+ break;
+ };
+
+ strcat (syntax, ((opcode == 0x3) ? "%a,%b" : ((class & SYNTAX_3OP) ? "%a,%b,%c" : "%b,%c")));
+ if (suffixcode < 2)
+ strcat (syntax, "%F");
+ strcat (syntax, "%S%L");
+
+ ext_op = (struct arc_opcode *) xmalloc (sizeof (struct arc_opcode));
+ ext_op->syntax = xstrdup (syntax);
+
+ ext_op->mask = I (-1) | ((0x3 == opcode) ? C (-1) : 0);
+ ext_op->value = I (opcode) | ((0x3 == opcode) ? C (subopcode) : 0);
+ ext_op->flags = class;
+ ext_op->next_asm = arc_ext_opcodes;
+ ext_op->next_dis = arc_ext_opcodes;
+ arc_ext_opcodes = ext_op;
+
+ /* OK, now that we know what this inst is, put a description in the
+ arc extension section of the output file. */
+
+ old_sec = now_seg;
+ old_subsec = now_subseg;
+
+ arc_set_ext_seg ();
+
+ p = frag_more (1);
+ *p = 5 + name_len + 1;
+ p = frag_more (1);
+ *p = EXT_INSTRUCTION;
+ p = frag_more (1);
+ *p = opcode;
+ p = frag_more (1);
+ *p = subopcode;
+ p = frag_more (1);
+ *p = (class & (OP1_MUST_BE_IMM | OP1_IMM_IMPLIED) ? IGNORE_FIRST_OPD : 0);
+ p = frag_more (name_len);
+ strncpy (p, syntax, name_len);
+ p = frag_more (1);
+ *p = '\0';
+
+ subseg_set (old_sec, old_subsec);
+
+ demand_empty_rest_of_line ();
+}
+
+int
+arc_set_ext_seg ()
+{
+ if (!arcext_section)
+ {
+ arcext_section = subseg_new (".arcextmap", 0);
+ bfd_set_section_flags (stdoutput, arcext_section,
+ SEC_READONLY | SEC_HAS_CONTENTS);
+ }
+ else
+ subseg_set (arcext_section, 0);
+ return 1;
+}
+
+static void
+arc_common (localScope)
+ int localScope;
+{
+ char *name;
+ char c;
+ char *p;
+ int align, size;
+ symbolS *symbolP;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ /* just after name is now '\0' */
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("expected comma after symbol name");
+ ignore_rest_of_line ();
+ return;
+ }
+
+ input_line_pointer++; /* skip ',' */
+ size = get_absolute_expression ();
+
+ if (size < 0)
+ {
+ as_bad ("negative symbol length");
+ ignore_rest_of_line ();
+ return;
+ }
+
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+
+ if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
+ {
+ as_bad ("ignoring attempt to re-define symbol");
+ ignore_rest_of_line ();
+ return;
+ }
+ if (((int) S_GET_VALUE (symbolP) != 0) \
+ && ((int) S_GET_VALUE (symbolP) != size))
+ {
+ as_warn ("length of symbol \"%s\" already %ld, ignoring %d",
+ S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
+ }
+ assert (symbolP->sy_frag == &zero_address_frag);
+
+ /* Now parse the alignment field. This field is optional for
+ local and global symbols. Default alignment is zero. */
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ align = get_absolute_expression ();
+ if (align < 0)
+ {
+ align = 0;
+ as_warn ("assuming symbol alignment of zero");
+ }
+ }
+ else
+ align = 0;
+
+ if (localScope != 0)
+ {
+ segT old_sec;
+ int old_subsec;
+ char *pfrag;
+
+ old_sec = now_seg;
+ old_subsec = now_subseg;
+ record_alignment (bss_section, align);
+ subseg_set (bss_section, 0); /* ??? subseg_set (bss_section, 1); ??? */
+
+ if (align)
+ /* Do alignment. */
+ frag_align (align, 0, 0);
+
+ /* Detach from old frag. */
+ if (S_GET_SEGMENT (symbolP) == bss_section)
+ symbolP->sy_frag->fr_symbol = NULL;
+
+ symbolP->sy_frag = frag_now;
+ pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
+ (offsetT) size, (char *) 0);
+ *pfrag = 0;
+
+ S_SET_SIZE (symbolP, size);
+ S_SET_SEGMENT (symbolP, bss_section);
+ S_CLEAR_EXTERNAL (symbolP);
+ symbolP->local = 1;
+ subseg_set (old_sec, old_subsec);
+ }
+ else
+ {
+ S_SET_VALUE (symbolP, (valueT) size);
+ S_SET_ALIGN (symbolP, align);
+ S_SET_EXTERNAL (symbolP);
+ S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
+ }
+
+ symbolP->bsym->flags |= BSF_OBJECT;
+
+ demand_empty_rest_of_line ();
+}
+
+/* Select the cpu we're assembling for. */
+
+static void
+arc_option (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ int mach;
+ char c;
+ char *cpu;
+
+ cpu = input_line_pointer;
+ c = get_symbol_end ();
+ mach = arc_get_mach (cpu);
+ *input_line_pointer = c;
+
+ /* If an instruction has already been seen, it's too late. */
+ if (cpu_tables_init_p)
+ {
+ as_bad ("\".option\" directive must appear before any instructions");
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (mach == -1)
+ goto bad_cpu;
+
+ if (mach_type_specified_p && mach != arc_mach_type)
+ {
+ as_bad ("\".option\" directive conflicts with initial definition");
+ ignore_rest_of_line ();
+ return;
+ }
+ else
+ {
+ /* The cpu may have been selected on the command line. */
+ if (mach != arc_mach_type)
+ as_warn ("\".option\" directive overrides command-line (default) value");
+ arc_mach_type = mach;
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
+ as_fatal ("could not set architecture and machine");
+ mach_type_specified_p = 1;
+ }
+ demand_empty_rest_of_line ();
+ return;
+
+ bad_cpu:
+ as_bad ("invalid identifier for \".option\"");
+ ignore_rest_of_line ();
+}
+
+/* Turn a string in input_line_pointer into a floating point constant
+ of type TYPE, and store the appropriate bytes in *LITP. The number
+ of LITTLENUMS emitted is stored in *SIZEP. An error message is
+ returned, or NULL on OK. */
+
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+char *
+md_atof (type, litP, sizeP)
+ int type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ prec = 4;
+ break;
+
+ default:
+ *sizeP = 0;
+ return "bad call to md_atof";
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+ for (wordP = words; prec--;)
+ {
+ md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+
+ return NULL;
+}
+
+/* Write a value out to the object file, using the appropriate
+ endianness. */
+
+void
+md_number_to_chars (buf, val, n)
+ char *buf;
+ valueT val;
+ int n;
+{
+ if (target_big_endian)
+ number_to_chars_bigendian (buf, val, n);
+ else
+ number_to_chars_littleendian (buf, val, n);
+}
+
+/* Round up a section size to the appropriate boundary. */
+
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+ int align = bfd_get_section_alignment (stdoutput, segment);
+
+ return ((size + (1 << align) - 1) & (-1 << align));
+}
+
+/* We don't have any form of relaxing. */
+
+int
+md_estimate_size_before_relax (fragp, seg)
+ fragS *fragp ATTRIBUTE_UNUSED;
+ asection *seg ATTRIBUTE_UNUSED;
+{
+ as_fatal (_("md_estimate_size_before_relax\n"));
+ return 1;
+}
+
+/* Convert a machine dependent frag. We never generate these. */
+
+void
+md_convert_frag (abfd, sec, fragp)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *sec ATTRIBUTE_UNUSED;
+ fragS *fragp ATTRIBUTE_UNUSED;
+{
+ as_fatal (_("md_convert_frag\n"));
+}
+
+void
+arc_code_symbol (expressionP)
+ expressionS *expressionP;
+{
+ if (expressionP->X_op == O_symbol && expressionP->X_add_number == 0)
+ {
+ expressionS two;
+ expressionP->X_op = O_right_shift;
+ expressionP->X_add_symbol->sy_value.X_op = O_constant;
+ two.X_op = O_constant;
+ two.X_add_symbol = two.X_op_symbol = NULL;
+ two.X_add_number = 2;
+ expressionP->X_op_symbol = make_expr_symbol (&two);
+ }
+ /* Allow %st(sym1-sym2) */
+ else if (expressionP->X_op == O_subtract
+ && expressionP->X_add_symbol != NULL
+ && expressionP->X_op_symbol != NULL
+ && expressionP->X_add_number == 0)
+ {
+ expressionS two;
+ expressionP->X_add_symbol = make_expr_symbol (expressionP);
+ expressionP->X_op = O_right_shift;
+ two.X_op = O_constant;
+ two.X_add_symbol = two.X_op_symbol = NULL;
+ two.X_add_number = 2;
+ expressionP->X_op_symbol = make_expr_symbol (&two);
+ }
+ else
+ {
+ as_bad ("expression too complex code symbol");
+ return;
+ }
+}
+
+/* Parse an operand that is machine-specific.
+
+ The ARC has a special %-op to adjust addresses so they're usable in
+ branches. The "st" is short for the STatus register.
+ ??? Later expand this to take a flags value too.
+
+ ??? We can't create new expression types so we map the %-op's onto the
+ existing syntax. This means that the user could use the chosen syntax
+ to achieve the same effect. */
+
+void
+md_operand (expressionP)
+ expressionS *expressionP;
+{
+ char *p = input_line_pointer;
+
+ if (*p == '%')
+ if (strncmp (p, "%st(", 4) == 0)
+ {
+ input_line_pointer += 4;
+ expression (expressionP);
+ if (*input_line_pointer != ')')
+ {
+ as_bad ("missing ')' in %%-op");
+ return;
+ }
+ ++input_line_pointer;
+ arc_code_symbol (expressionP);
+ }
+ else
+ {
+ /* It could be a register. */
+ int i, l;
+ struct arc_ext_operand_value *ext_oper = arc_ext_operands;
+ p++;
+
+ while (ext_oper)
+ {
+ l = strlen (ext_oper->operand.name);
+ if (!strncmp (p, ext_oper->operand.name, l) && !ISALNUM (*(p + l)))
+ {
+ input_line_pointer += l + 1;
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = (int) &ext_oper->operand;
+ return;
+ }
+ ext_oper = ext_oper->next;
+ }
+ for (i = 0; i < arc_reg_names_count; i++)
+ {
+ l = strlen (arc_reg_names[i].name);
+ if (!strncmp (p, arc_reg_names[i].name, l) && !ISALNUM (*(p + l)))
+ {
+ input_line_pointer += l + 1;
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = (int) &arc_reg_names[i];
+ break;
+ }
+ }
+ }
+}
+
+/* We have no need to default values of symbols.
+ We could catch register names here, but that is handled by inserting
+ them all in the symbol table to begin with. */
+
+symbolS *
+md_undefined_symbol (name)
+ char *name ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
+
+/* Functions concerning expressions. */
+
+/* Parse a .byte, .word, etc. expression.
+
+ Values for the status register are specified with %st(label).
+ `label' will be right shifted by 2. */
+
+void
+arc_parse_cons_expression (exp, nbytes)
+ expressionS *exp;
+ unsigned int nbytes ATTRIBUTE_UNUSED;
+{
+ char *p = input_line_pointer;
+ int code_symbol_fix = 0;
+
+ for (; ! is_end_of_line[(unsigned char) *p]; p++)
+ if (*p == '@' && !strncmp (p, "@h30", 4))
+ {
+ code_symbol_fix = 1;
+ strcpy (p, "; ");
+ }
+ expr (0, exp);
+ if (code_symbol_fix)
+ {
+ arc_code_symbol (exp);
+ input_line_pointer = p;
+ }
+}
+
+/* Record a fixup for a cons expression. */
+
+void
+arc_cons_fix_new (frag, where, nbytes, exp)
+ fragS *frag;
+ int where;
+ int nbytes;
+ expressionS *exp;
+{
+ if (nbytes == 4)
+ {
+ int reloc_type;
+ expressionS exptmp;
+
+ /* This may be a special ARC reloc (eg: %st()). */
+ reloc_type = get_arc_exp_reloc_type (1, BFD_RELOC_32, exp, &exptmp);
+ fix_new_exp (frag, where, nbytes, &exptmp, 0, reloc_type);
+ }
+ else
+ {
+ fix_new_exp (frag, where, nbytes, exp, 0,
+ nbytes == 2 ? BFD_RELOC_16
+ : nbytes == 8 ? BFD_RELOC_64
+ : BFD_RELOC_32);
+ }
+}
+
+/* Functions concerning relocs. */
+
+/* The location from which a PC relative jump should be calculated,
+ given a PC relative reloc. */
+
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ /* Return the address of the delay slot. */
+ return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
+}
+
+/* Compute the reloc type of an expression.
+ The possibly modified expression is stored in EXPNEW.
+
+ This is used to convert the expressions generated by the %-op's into
+ the appropriate operand type. It is called for both data in instructions
+ (operands) and data outside instructions (variables, debugging info, etc.).
+
+ Currently supported %-ops:
+
+ %st(symbol): represented as "symbol >> 2"
+ "st" is short for STatus as in the status register (pc)
+
+ DEFAULT_TYPE is the type to use if no special processing is required.
+
+ DATA_P is non-zero for data or limm values, zero for insn operands.
+ Remember that the opcode "insertion fns" cannot be used on data, they're
+ only for inserting operands into insns. They also can't be used for limm
+ values as the insertion routines don't handle limm values. When called for
+ insns we return fudged reloc types (real_value - BFD_RELOC_UNUSED). When
+ called for data or limm values we use real reloc types. */
+
+static int
+get_arc_exp_reloc_type (data_p, default_type, exp, expnew)
+ int data_p;
+ int default_type;
+ expressionS *exp;
+ expressionS *expnew;
+{
+ /* If the expression is "symbol >> 2" we must change it to just "symbol",
+ as fix_new_exp can't handle it. Similarly for (symbol - symbol) >> 2.
+ That's ok though. What's really going on here is that we're using
+ ">> 2" as a special syntax for specifying BFD_RELOC_ARC_B26. */
+
+ if (exp->X_op == O_right_shift
+ && exp->X_op_symbol != NULL
+ && exp->X_op_symbol->sy_value.X_op == O_constant
+ && exp->X_op_symbol->sy_value.X_add_number == 2
+ && exp->X_add_number == 0)
+ {
+ if (exp->X_add_symbol != NULL
+ && (exp->X_add_symbol->sy_value.X_op == O_constant
+ || exp->X_add_symbol->sy_value.X_op == O_symbol))
+ {
+ *expnew = *exp;
+ expnew->X_op = O_symbol;
+ expnew->X_op_symbol = NULL;
+ return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
+ }
+ else if (exp->X_add_symbol != NULL
+ && exp->X_add_symbol->sy_value.X_op == O_subtract)
+ {
+ *expnew = exp->X_add_symbol->sy_value;
+ return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
+ }
+ }
+
+ *expnew = *exp;
+ return default_type;
+}
+
+/* Apply a fixup to the object code. This is called for all the
+ fixups we generated by the call to fix_new_exp, above. In the call
+ above we used a reloc code which was the largest legal reloc code
+ plus the operand index. Here we undo that to recover the operand
+ index. At this point all symbol values should be fully resolved,
+ and we attempt to completely resolve the reloc. If we can not do
+ that, we determine the correct reloc code and put it back in the fixup. */
+
+void
+md_apply_fix3 (fixP, valP, seg)
+ fixS *fixP;
+ valueT * valP;
+ segT seg;
+{
+#if 0
+ char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+#endif
+ valueT value = * valP;
+
+ if (fixP->fx_addsy == (symbolS *) NULL)
+ fixP->fx_done = 1;
+
+ else if (fixP->fx_pcrel)
+ {
+ /* Hack around bfd_install_relocation brain damage. */
+ if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
+ value += md_pcrel_from (fixP);
+ }
+
+ /* We can't actually support subtracting a symbol. */
+ if (fixP->fx_subsy != NULL)
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
+
+ if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
+ {
+ int opindex;
+ const struct arc_operand *operand;
+ char *where;
+ arc_insn insn;
+
+ opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
+
+ operand = &arc_operands[opindex];
+
+ /* Fetch the instruction, insert the fully resolved operand
+ value, and stuff the instruction back again. */
+ where = fixP->fx_frag->fr_literal + fixP->fx_where;
+ if (target_big_endian)
+ insn = bfd_getb32 ((unsigned char *) where);
+ else
+ insn = bfd_getl32 ((unsigned char *) where);
+ insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
+ fixP->fx_file, fixP->fx_line);
+ if (target_big_endian)
+ bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ else
+ bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
+
+ if (fixP->fx_done)
+ {
+ /* Nothing else to do here. */
+ return;
+ }
+
+ /* Determine a BFD reloc value based on the operand information.
+ We are only prepared to turn a few of the operands into relocs.
+ !!! Note that we can't handle limm values here. Since we're using
+ implicit addends the addend must be inserted into the instruction,
+ however, the opcode insertion routines currently do nothing with
+ limm values. */
+ if (operand->fmt == 'B')
+ {
+ assert ((operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0
+ && operand->bits == 20
+ && operand->shift == 7);
+ fixP->fx_r_type = BFD_RELOC_ARC_B22_PCREL;
+ }
+ else if (operand->fmt == 'J')
+ {
+ assert ((operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH) != 0
+ && operand->bits == 24
+ && operand->shift == 32);
+ fixP->fx_r_type = BFD_RELOC_ARC_B26;
+ }
+ else if (operand->fmt == 'L')
+ {
+ assert ((operand->flags & ARC_OPERAND_LIMM) != 0
+ && operand->bits == 32
+ && operand->shift == 32);
+ fixP->fx_r_type = BFD_RELOC_32;
+ }
+ else
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ "unresolved expression that must be resolved");
+ fixP->fx_done = 1;
+ return;
+ }
+ }
+ else
+ {
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_8:
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 1);
+ break;
+ case BFD_RELOC_16:
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 2);
+ break;
+ case BFD_RELOC_32:
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 4);
+ break;
+#if 0
+ case BFD_RELOC_64:
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 8);
+ break;
+#endif
+ case BFD_RELOC_ARC_B26:
+ /* If !fixP->fx_done then `value' is an implicit addend.
+ We must shift it right by 2 in this case as well because the
+ linker performs the relocation and then adds this in (as opposed
+ to adding this in and then shifting right by 2). */
+ value >>= 2;
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 4);
+ break;
+ default:
+ abort ();
+ }
+ }
+}
+
+/* Translate internal representation of relocation info to BFD target
+ format. */
+
+arelent *
+tc_gen_reloc (section, fixP)
+ asection *section ATTRIBUTE_UNUSED;
+ fixS *fixP;
+{
+ arelent *reloc;
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+
+ reloc->sym_ptr_ptr = &fixP->fx_addsy->bsym;
+ reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
+ if (reloc->howto == (reloc_howto_type *) NULL)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ "internal error: can't export reloc type %d (`%s')",
+ fixP->fx_r_type,
+ bfd_get_reloc_code_name (fixP->fx_r_type));
+ return NULL;
+ }
+
+ assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
+
+ /* Set addend to account for PC being advanced one insn before the
+ target address is computed. */
+
+ reloc->addend = (fixP->fx_pcrel ? -4 : 0);
+
+ return reloc;
+}
diff --git a/x/binutils/gas/config/tc-arc.h b/x/binutils/gas/config/tc-arc.h
new file mode 100644
index 0000000..884d375
--- /dev/null
+++ b/x/binutils/gas/config/tc-arc.h
@@ -0,0 +1,74 @@
+/* tc-arc.h - Macros and type defines for the ARC.
+ Copyright 1994, 1995, 1997, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+ Contributed by Doug Evans (dje@cygnus.com).
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2,
+ or (at your option) any later version.
+
+ GAS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_ARC 1
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#define LOCAL_LABELS_FB 1
+
+#define TARGET_ARCH bfd_arch_arc
+
+#define DIFF_EXPR_OK
+#define REGISTER_PREFIX '%'
+
+#ifdef LITTLE_ENDIAN
+#undef LITTLE_ENDIAN
+#endif
+
+#ifdef BIG_ENDIAN
+#undef BIG_ENDIAN
+#endif
+
+#define LITTLE_ENDIAN 1234
+
+#define BIG_ENDIAN 4321
+
+/* The endianness of the target format may change based on command
+ line arguments. */
+extern const char *arc_target_format;
+#define DEFAULT_TARGET_FORMAT "elf32-littlearc"
+#define TARGET_FORMAT arc_target_format
+#define DEFAULT_BYTE_ORDER LITTLE_ENDIAN
+
+#define WORKING_DOT_WORD
+
+#define LISTING_HEADER "ARC GAS "
+
+/* The ARC needs to parse reloc specifiers in .word. */
+
+extern void arc_parse_cons_expression PARAMS ((struct expressionS *, unsigned));
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+arc_parse_cons_expression (EXP, NBYTES)
+
+extern void arc_cons_fix_new PARAMS ((struct frag *, int, int, struct expressionS *));
+#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \
+arc_cons_fix_new (FRAG, WHERE, NBYTES, EXP)
+
+#define DWARF2_LINE_MIN_INSN_LENGTH 4
+
+/* Values passed to md_apply_fix3 don't include the symbol value. */
+#define MD_APPLY_SYM_VALUE(FIX) 0
+
+/* No shared lib support, so we don't need to ensure externally
+ visible symbols can be overridden. */
+#define EXTERN_FORCE_RELOC 0
diff --git a/x/binutils/gas/config/tc-arm.c b/x/binutils/gas/config/tc-arm.c
new file mode 100644
index 0000000..2ed5196
--- /dev/null
+++ b/x/binutils/gas/config/tc-arm.c
@@ -0,0 +1,14300 @@
+/* tc-arm.c -- Assemble for the ARM
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+ Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+ Modified by David Taylor (dtaylor@armltd.co.uk)
+ Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
+ Cirrus coprocessor fixes by Petko Manolov (petkan@nucleusys.com)
+ Cirrus coprocessor fixes by Vladimir Ivanov (vladitx@nucleusys.com)
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <string.h>
+#define NO_RELOC 0
+#include "as.h"
+#include "safe-ctype.h"
+
+/* Need TARGET_CPU. */
+#include "config.h"
+#include "subsegs.h"
+#include "obstack.h"
+#include "symbols.h"
+#include "listing.h"
+
+#ifdef OBJ_ELF
+#include "elf/arm.h"
+#include "dwarf2dbg.h"
+#endif
+
+/* XXX Set this to 1 after the next binutils release */
+#define WARN_DEPRECATED 0
+
+/* The following bitmasks control CPU extensions: */
+#define ARM_EXT_V1 0x00000001 /* All processors (core set). */
+#define ARM_EXT_V2 0x00000002 /* Multiply instructions. */
+#define ARM_EXT_V2S 0x00000004 /* SWP instructions. */
+#define ARM_EXT_V3 0x00000008 /* MSR MRS. */
+#define ARM_EXT_V3M 0x00000010 /* Allow long multiplies. */
+#define ARM_EXT_V4 0x00000020 /* Allow half word loads. */
+#define ARM_EXT_V4T 0x00000040 /* Thumb v1. */
+#define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
+#define ARM_EXT_V5T 0x00000100 /* Thumb v2. */
+#define ARM_EXT_V5ExP 0x00000200 /* DSP core set. */
+#define ARM_EXT_V5E 0x00000400 /* DSP Double transfers. */
+#define ARM_EXT_V5J 0x00000800 /* Jazelle extension. */
+#define ARM_EXT_V6 0x00001000 /* ARM V6. */
+
+/* Co-processor space extensions. */
+#define ARM_CEXT_XSCALE 0x00800000 /* Allow MIA etc. */
+#define ARM_CEXT_MAVERICK 0x00400000 /* Use Cirrus/DSP coprocessor. */
+#define ARM_CEXT_IWMMXT 0x00200000 /* Intel Wireless MMX technology coprocessor. */
+
+/* Architectures are the sum of the base and extensions. The ARM ARM (rev E)
+ defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
+ ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE. To these we add
+ three more to cover cores prior to ARM6. Finally, there are cores which
+ implement further extensions in the co-processor space. */
+#define ARM_ARCH_V1 ARM_EXT_V1
+#define ARM_ARCH_V2 (ARM_ARCH_V1 | ARM_EXT_V2)
+#define ARM_ARCH_V2S (ARM_ARCH_V2 | ARM_EXT_V2S)
+#define ARM_ARCH_V3 (ARM_ARCH_V2S | ARM_EXT_V3)
+#define ARM_ARCH_V3M (ARM_ARCH_V3 | ARM_EXT_V3M)
+#define ARM_ARCH_V4xM (ARM_ARCH_V3 | ARM_EXT_V4)
+#define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_V4)
+#define ARM_ARCH_V4TxM (ARM_ARCH_V4xM | ARM_EXT_V4T)
+#define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_V4T)
+#define ARM_ARCH_V5xM (ARM_ARCH_V4xM | ARM_EXT_V5)
+#define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
+#define ARM_ARCH_V5TxM (ARM_ARCH_V5xM | ARM_EXT_V4T | ARM_EXT_V5T)
+#define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_V4T | ARM_EXT_V5T)
+#define ARM_ARCH_V5TExP (ARM_ARCH_V5T | ARM_EXT_V5ExP)
+#define ARM_ARCH_V5TE (ARM_ARCH_V5TExP | ARM_EXT_V5E)
+#define ARM_ARCH_V5TEJ (ARM_ARCH_V5TE | ARM_EXT_V5J)
+#define ARM_ARCH_V6 (ARM_ARCH_V5TEJ | ARM_EXT_V6)
+
+/* Processors with specific extensions in the co-processor space. */
+#define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_CEXT_XSCALE)
+#define ARM_ARCH_IWMMXT (ARM_ARCH_XSCALE | ARM_CEXT_IWMMXT)
+
+/* Some useful combinations: */
+#define ARM_ANY 0x0000ffff /* Any basic core. */
+#define ARM_ALL 0x00ffffff /* Any core + co-processor */
+#define CPROC_ANY 0x00ff0000 /* Any co-processor */
+#define FPU_ANY 0xff000000 /* Note this is ~ARM_ALL. */
+
+
+#define FPU_FPA_EXT_V1 0x80000000 /* Base FPA instruction set. */
+#define FPU_FPA_EXT_V2 0x40000000 /* LFM/SFM. */
+#define FPU_VFP_EXT_NONE 0x20000000 /* Use VFP word-ordering. */
+#define FPU_VFP_EXT_V1xD 0x10000000 /* Base VFP instruction set. */
+#define FPU_VFP_EXT_V1 0x08000000 /* Double-precision insns. */
+#define FPU_VFP_EXT_V2 0x04000000 /* ARM10E VFPr1. */
+#define FPU_MAVERICK 0x02000000 /* Cirrus Maverick. */
+#define FPU_NONE 0
+
+#define FPU_ARCH_FPE FPU_FPA_EXT_V1
+#define FPU_ARCH_FPA (FPU_ARCH_FPE | FPU_FPA_EXT_V2)
+
+#define FPU_ARCH_VFP FPU_VFP_EXT_NONE
+#define FPU_ARCH_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_NONE)
+#define FPU_ARCH_VFP_V1 (FPU_ARCH_VFP_V1xD | FPU_VFP_EXT_V1)
+#define FPU_ARCH_VFP_V2 (FPU_ARCH_VFP_V1 | FPU_VFP_EXT_V2)
+
+#define FPU_ARCH_MAVERICK FPU_MAVERICK
+
+enum arm_float_abi
+{
+ ARM_FLOAT_ABI_HARD,
+ ARM_FLOAT_ABI_SOFTFP,
+ ARM_FLOAT_ABI_SOFT
+};
+
+/* Types of processor to assemble for. */
+#define ARM_1 ARM_ARCH_V1
+#define ARM_2 ARM_ARCH_V2
+#define ARM_3 ARM_ARCH_V2S
+#define ARM_250 ARM_ARCH_V2S
+#define ARM_6 ARM_ARCH_V3
+#define ARM_7 ARM_ARCH_V3
+#define ARM_8 ARM_ARCH_V4
+#define ARM_9 ARM_ARCH_V4T
+#define ARM_STRONG ARM_ARCH_V4
+#define ARM_CPU_MASK 0x0000000f /* XXX? */
+
+#ifndef CPU_DEFAULT
+#if defined __XSCALE__
+#define CPU_DEFAULT (ARM_ARCH_XSCALE)
+#else
+#if defined __thumb__
+#define CPU_DEFAULT (ARM_ARCH_V5T)
+#else
+#define CPU_DEFAULT ARM_ANY
+#endif
+#endif
+#endif
+
+#ifdef TE_LINUX
+#define FPU_DEFAULT FPU_ARCH_FPA
+#endif
+
+#ifdef TE_NetBSD
+#ifdef OBJ_ELF
+#define FPU_DEFAULT FPU_ARCH_VFP /* Soft-float, but VFP order. */
+#else
+/* Legacy a.out format. */
+#define FPU_DEFAULT FPU_ARCH_FPA /* Soft-float, but FPA order. */
+#endif
+#endif
+
+/* For backwards compatibility we default to the FPA. */
+#ifndef FPU_DEFAULT
+#define FPU_DEFAULT FPU_ARCH_FPA
+#endif
+
+#define streq(a, b) (strcmp (a, b) == 0)
+#define skip_whitespace(str) while (*(str) == ' ') ++(str)
+
+static unsigned long cpu_variant;
+static int target_oabi = 0;
+
+/* Flags stored in private area of BFD structure. */
+static int uses_apcs_26 = FALSE;
+static int atpcs = FALSE;
+static int support_interwork = FALSE;
+static int uses_apcs_float = FALSE;
+static int pic_code = FALSE;
+
+/* Variables that we set while parsing command-line options. Once all
+ options have been read we re-process these values to set the real
+ assembly flags. */
+static int legacy_cpu = -1;
+static int legacy_fpu = -1;
+
+static int mcpu_cpu_opt = -1;
+static int mcpu_fpu_opt = -1;
+static int march_cpu_opt = -1;
+static int march_fpu_opt = -1;
+static int mfpu_opt = -1;
+static int mfloat_abi_opt = -1;
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful. */
+const char comment_chars[] = "@";
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output. */
+/* Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output. */
+/* Also note that comments like this one will always work. */
+const char line_comment_chars[] = "#";
+
+const char line_separator_chars[] = ";";
+
+/* Chars that can be used to separate mant
+ from exp in floating point numbers. */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant. */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+
+const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
+
+/* Prefix characters that indicate the start of an immediate
+ value. */
+#define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
+
+#ifdef OBJ_ELF
+/* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
+symbolS * GOT_symbol;
+#endif
+
+/* Size of relocation record. */
+const int md_reloc_size = 8;
+
+/* 0: assemble for ARM,
+ 1: assemble for Thumb,
+ 2: assemble for Thumb even though target CPU does not support thumb
+ instructions. */
+static int thumb_mode = 0;
+
+typedef struct arm_fix
+{
+ int thumb_mode;
+} arm_fix_data;
+
+struct arm_it
+{
+ const char * error;
+ unsigned long instruction;
+ int size;
+ struct
+ {
+ bfd_reloc_code_real_type type;
+ expressionS exp;
+ int pc_rel;
+ } reloc;
+};
+
+struct arm_it inst;
+
+enum asm_shift_index
+{
+ SHIFT_LSL = 0,
+ SHIFT_LSR,
+ SHIFT_ASR,
+ SHIFT_ROR,
+ SHIFT_RRX
+};
+
+struct asm_shift_properties
+{
+ enum asm_shift_index index;
+ unsigned long bit_field;
+ unsigned int allows_0 : 1;
+ unsigned int allows_32 : 1;
+};
+
+static const struct asm_shift_properties shift_properties [] =
+{
+ { SHIFT_LSL, 0, 1, 0},
+ { SHIFT_LSR, 0x20, 0, 1},
+ { SHIFT_ASR, 0x40, 0, 1},
+ { SHIFT_ROR, 0x60, 0, 0},
+ { SHIFT_RRX, 0x60, 0, 0}
+};
+
+struct asm_shift_name
+{
+ const char * name;
+ const struct asm_shift_properties * properties;
+};
+
+static const struct asm_shift_name shift_names [] =
+{
+ { "asl", shift_properties + SHIFT_LSL },
+ { "lsl", shift_properties + SHIFT_LSL },
+ { "lsr", shift_properties + SHIFT_LSR },
+ { "asr", shift_properties + SHIFT_ASR },
+ { "ror", shift_properties + SHIFT_ROR },
+ { "rrx", shift_properties + SHIFT_RRX },
+ { "ASL", shift_properties + SHIFT_LSL },
+ { "LSL", shift_properties + SHIFT_LSL },
+ { "LSR", shift_properties + SHIFT_LSR },
+ { "ASR", shift_properties + SHIFT_ASR },
+ { "ROR", shift_properties + SHIFT_ROR },
+ { "RRX", shift_properties + SHIFT_RRX }
+};
+
+/* Any kind of shift is accepted. */
+#define NO_SHIFT_RESTRICT 1
+/* The shift operand must be an immediate value, not a register. */
+#define SHIFT_IMMEDIATE 0
+/* The shift must be LSL or ASR and the operand must be an immediate. */
+#define SHIFT_LSL_OR_ASR_IMMEDIATE 2
+/* The shift must be ASR and the operand must be an immediate. */
+#define SHIFT_ASR_IMMEDIATE 3
+/* The shift must be LSL and the operand must be an immediate. */
+#define SHIFT_LSL_IMMEDIATE 4
+
+#define NUM_FLOAT_VALS 8
+
+const char * fp_const[] =
+{
+ "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
+};
+
+/* Number of littlenums required to hold an extended precision number. */
+#define MAX_LITTLENUMS 6
+
+LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
+
+#define FAIL (-1)
+#define SUCCESS (0)
+
+/* Whether a Co-processor load/store operation accepts write-back forms. */
+#define CP_WB_OK 1
+#define CP_NO_WB 0
+
+#define SUFF_S 1
+#define SUFF_D 2
+#define SUFF_E 3
+#define SUFF_P 4
+
+#define CP_T_X 0x00008000
+#define CP_T_Y 0x00400000
+#define CP_T_Pre 0x01000000
+#define CP_T_UD 0x00800000
+#define CP_T_WB 0x00200000
+
+#define CONDS_BIT 0x00100000
+#define LOAD_BIT 0x00100000
+
+#define DOUBLE_LOAD_FLAG 0x00000001
+
+struct asm_cond
+{
+ const char * template;
+ unsigned long value;
+};
+
+#define COND_ALWAYS 0xe0000000
+#define COND_MASK 0xf0000000
+
+static const struct asm_cond conds[] =
+{
+ {"eq", 0x00000000},
+ {"ne", 0x10000000},
+ {"cs", 0x20000000}, {"hs", 0x20000000},
+ {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
+ {"mi", 0x40000000},
+ {"pl", 0x50000000},
+ {"vs", 0x60000000},
+ {"vc", 0x70000000},
+ {"hi", 0x80000000},
+ {"ls", 0x90000000},
+ {"ge", 0xa0000000},
+ {"lt", 0xb0000000},
+ {"gt", 0xc0000000},
+ {"le", 0xd0000000},
+ {"al", 0xe0000000},
+ {"nv", 0xf0000000}
+};
+
+struct asm_psr
+{
+ const char *template;
+ bfd_boolean cpsr;
+ unsigned long field;
+};
+
+/* The bit that distinguishes CPSR and SPSR. */
+#define SPSR_BIT (1 << 22)
+
+/* How many bits to shift the PSR_xxx bits up by. */
+#define PSR_SHIFT 16
+
+#define PSR_c (1 << 0)
+#define PSR_x (1 << 1)
+#define PSR_s (1 << 2)
+#define PSR_f (1 << 3)
+
+static const struct asm_psr psrs[] =
+{
+ {"CPSR", TRUE, PSR_c | PSR_f},
+ {"CPSR_all", TRUE, PSR_c | PSR_f},
+ {"SPSR", FALSE, PSR_c | PSR_f},
+ {"SPSR_all", FALSE, PSR_c | PSR_f},
+ {"CPSR_flg", TRUE, PSR_f},
+ {"CPSR_f", TRUE, PSR_f},
+ {"SPSR_flg", FALSE, PSR_f},
+ {"SPSR_f", FALSE, PSR_f},
+ {"CPSR_c", TRUE, PSR_c},
+ {"CPSR_ctl", TRUE, PSR_c},
+ {"SPSR_c", FALSE, PSR_c},
+ {"SPSR_ctl", FALSE, PSR_c},
+ {"CPSR_x", TRUE, PSR_x},
+ {"CPSR_s", TRUE, PSR_s},
+ {"SPSR_x", FALSE, PSR_x},
+ {"SPSR_s", FALSE, PSR_s},
+ /* Combinations of flags. */
+ {"CPSR_fs", TRUE, PSR_f | PSR_s},
+ {"CPSR_fx", TRUE, PSR_f | PSR_x},
+ {"CPSR_fc", TRUE, PSR_f | PSR_c},
+ {"CPSR_sf", TRUE, PSR_s | PSR_f},
+ {"CPSR_sx", TRUE, PSR_s | PSR_x},
+ {"CPSR_sc", TRUE, PSR_s | PSR_c},
+ {"CPSR_xf", TRUE, PSR_x | PSR_f},
+ {"CPSR_xs", TRUE, PSR_x | PSR_s},
+ {"CPSR_xc", TRUE, PSR_x | PSR_c},
+ {"CPSR_cf", TRUE, PSR_c | PSR_f},
+ {"CPSR_cs", TRUE, PSR_c | PSR_s},
+ {"CPSR_cx", TRUE, PSR_c | PSR_x},
+ {"CPSR_fsx", TRUE, PSR_f | PSR_s | PSR_x},
+ {"CPSR_fsc", TRUE, PSR_f | PSR_s | PSR_c},
+ {"CPSR_fxs", TRUE, PSR_f | PSR_x | PSR_s},
+ {"CPSR_fxc", TRUE, PSR_f | PSR_x | PSR_c},
+ {"CPSR_fcs", TRUE, PSR_f | PSR_c | PSR_s},
+ {"CPSR_fcx", TRUE, PSR_f | PSR_c | PSR_x},
+ {"CPSR_sfx", TRUE, PSR_s | PSR_f | PSR_x},
+ {"CPSR_sfc", TRUE, PSR_s | PSR_f | PSR_c},
+ {"CPSR_sxf", TRUE, PSR_s | PSR_x | PSR_f},
+ {"CPSR_sxc", TRUE, PSR_s | PSR_x | PSR_c},
+ {"CPSR_scf", TRUE, PSR_s | PSR_c | PSR_f},
+ {"CPSR_scx", TRUE, PSR_s | PSR_c | PSR_x},
+ {"CPSR_xfs", TRUE, PSR_x | PSR_f | PSR_s},
+ {"CPSR_xfc", TRUE, PSR_x | PSR_f | PSR_c},
+ {"CPSR_xsf", TRUE, PSR_x | PSR_s | PSR_f},
+ {"CPSR_xsc", TRUE, PSR_x | PSR_s | PSR_c},
+ {"CPSR_xcf", TRUE, PSR_x | PSR_c | PSR_f},
+ {"CPSR_xcs", TRUE, PSR_x | PSR_c | PSR_s},
+ {"CPSR_cfs", TRUE, PSR_c | PSR_f | PSR_s},
+ {"CPSR_cfx", TRUE, PSR_c | PSR_f | PSR_x},
+ {"CPSR_csf", TRUE, PSR_c | PSR_s | PSR_f},
+ {"CPSR_csx", TRUE, PSR_c | PSR_s | PSR_x},
+ {"CPSR_cxf", TRUE, PSR_c | PSR_x | PSR_f},
+ {"CPSR_cxs", TRUE, PSR_c | PSR_x | PSR_s},
+ {"CPSR_fsxc", TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
+ {"CPSR_fscx", TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
+ {"CPSR_fxsc", TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
+ {"CPSR_fxcs", TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
+ {"CPSR_fcsx", TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
+ {"CPSR_fcxs", TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
+ {"CPSR_sfxc", TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
+ {"CPSR_sfcx", TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
+ {"CPSR_sxfc", TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
+ {"CPSR_sxcf", TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
+ {"CPSR_scfx", TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
+ {"CPSR_scxf", TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
+ {"CPSR_xfsc", TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
+ {"CPSR_xfcs", TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
+ {"CPSR_xsfc", TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
+ {"CPSR_xscf", TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
+ {"CPSR_xcfs", TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
+ {"CPSR_xcsf", TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
+ {"CPSR_cfsx", TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
+ {"CPSR_cfxs", TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
+ {"CPSR_csfx", TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
+ {"CPSR_csxf", TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
+ {"CPSR_cxfs", TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
+ {"CPSR_cxsf", TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
+ {"SPSR_fs", FALSE, PSR_f | PSR_s},
+ {"SPSR_fx", FALSE, PSR_f | PSR_x},
+ {"SPSR_fc", FALSE, PSR_f | PSR_c},
+ {"SPSR_sf", FALSE, PSR_s | PSR_f},
+ {"SPSR_sx", FALSE, PSR_s | PSR_x},
+ {"SPSR_sc", FALSE, PSR_s | PSR_c},
+ {"SPSR_xf", FALSE, PSR_x | PSR_f},
+ {"SPSR_xs", FALSE, PSR_x | PSR_s},
+ {"SPSR_xc", FALSE, PSR_x | PSR_c},
+ {"SPSR_cf", FALSE, PSR_c | PSR_f},
+ {"SPSR_cs", FALSE, PSR_c | PSR_s},
+ {"SPSR_cx", FALSE, PSR_c | PSR_x},
+ {"SPSR_fsx", FALSE, PSR_f | PSR_s | PSR_x},
+ {"SPSR_fsc", FALSE, PSR_f | PSR_s | PSR_c},
+ {"SPSR_fxs", FALSE, PSR_f | PSR_x | PSR_s},
+ {"SPSR_fxc", FALSE, PSR_f | PSR_x | PSR_c},
+ {"SPSR_fcs", FALSE, PSR_f | PSR_c | PSR_s},
+ {"SPSR_fcx", FALSE, PSR_f | PSR_c | PSR_x},
+ {"SPSR_sfx", FALSE, PSR_s | PSR_f | PSR_x},
+ {"SPSR_sfc", FALSE, PSR_s | PSR_f | PSR_c},
+ {"SPSR_sxf", FALSE, PSR_s | PSR_x | PSR_f},
+ {"SPSR_sxc", FALSE, PSR_s | PSR_x | PSR_c},
+ {"SPSR_scf", FALSE, PSR_s | PSR_c | PSR_f},
+ {"SPSR_scx", FALSE, PSR_s | PSR_c | PSR_x},
+ {"SPSR_xfs", FALSE, PSR_x | PSR_f | PSR_s},
+ {"SPSR_xfc", FALSE, PSR_x | PSR_f | PSR_c},
+ {"SPSR_xsf", FALSE, PSR_x | PSR_s | PSR_f},
+ {"SPSR_xsc", FALSE, PSR_x | PSR_s | PSR_c},
+ {"SPSR_xcf", FALSE, PSR_x | PSR_c | PSR_f},
+ {"SPSR_xcs", FALSE, PSR_x | PSR_c | PSR_s},
+ {"SPSR_cfs", FALSE, PSR_c | PSR_f | PSR_s},
+ {"SPSR_cfx", FALSE, PSR_c | PSR_f | PSR_x},
+ {"SPSR_csf", FALSE, PSR_c | PSR_s | PSR_f},
+ {"SPSR_csx", FALSE, PSR_c | PSR_s | PSR_x},
+ {"SPSR_cxf", FALSE, PSR_c | PSR_x | PSR_f},
+ {"SPSR_cxs", FALSE, PSR_c | PSR_x | PSR_s},
+ {"SPSR_fsxc", FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
+ {"SPSR_fscx", FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
+ {"SPSR_fxsc", FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
+ {"SPSR_fxcs", FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
+ {"SPSR_fcsx", FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
+ {"SPSR_fcxs", FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
+ {"SPSR_sfxc", FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
+ {"SPSR_sfcx", FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
+ {"SPSR_sxfc", FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
+ {"SPSR_sxcf", FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
+ {"SPSR_scfx", FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
+ {"SPSR_scxf", FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
+ {"SPSR_xfsc", FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
+ {"SPSR_xfcs", FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
+ {"SPSR_xsfc", FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
+ {"SPSR_xscf", FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
+ {"SPSR_xcfs", FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
+ {"SPSR_xcsf", FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
+ {"SPSR_cfsx", FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
+ {"SPSR_cfxs", FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
+ {"SPSR_csfx", FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
+ {"SPSR_csxf", FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
+ {"SPSR_cxfs", FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
+ {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
+};
+
+enum wreg_type
+ {
+ IWMMXT_REG_WR = 0,
+ IWMMXT_REG_WC = 1,
+ IWMMXT_REG_WR_OR_WC = 2,
+ IWMMXT_REG_WCG
+ };
+
+enum iwmmxt_insn_type
+{
+ check_rd,
+ check_wr,
+ check_wrwr,
+ check_wrwrwr,
+ check_wrwrwcg,
+ check_tbcst,
+ check_tmovmsk,
+ check_tmia,
+ check_tmcrr,
+ check_tmrrc,
+ check_tmcr,
+ check_tmrc,
+ check_tinsr,
+ check_textrc,
+ check_waligni,
+ check_textrm,
+ check_wshufh
+};
+
+enum vfp_dp_reg_pos
+{
+ VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
+};
+
+enum vfp_sp_reg_pos
+{
+ VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
+};
+
+enum vfp_ldstm_type
+{
+ VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
+};
+
+/* VFP system registers. */
+struct vfp_reg
+{
+ const char *name;
+ unsigned long regno;
+};
+
+static const struct vfp_reg vfp_regs[] =
+{
+ {"fpsid", 0x00000000},
+ {"FPSID", 0x00000000},
+ {"fpscr", 0x00010000},
+ {"FPSCR", 0x00010000},
+ {"fpexc", 0x00080000},
+ {"FPEXC", 0x00080000}
+};
+
+/* Structure for a hash table entry for a register. */
+struct reg_entry
+{
+ const char * name;
+ int number;
+ bfd_boolean builtin;
+};
+
+/* Some well known registers that we refer to directly elsewhere. */
+#define REG_SP 13
+#define REG_LR 14
+#define REG_PC 15
+
+#define wr_register(reg) ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
+#define wc_register(reg) ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
+#define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
+
+/* These are the standard names. Users can add aliases with .req.
+ and delete them with .unreq. */
+
+/* Integer Register Numbers. */
+static const struct reg_entry rn_table[] =
+{
+ {"r0", 0, TRUE}, {"r1", 1, TRUE}, {"r2", 2, TRUE}, {"r3", 3, TRUE},
+ {"r4", 4, TRUE}, {"r5", 5, TRUE}, {"r6", 6, TRUE}, {"r7", 7, TRUE},
+ {"r8", 8, TRUE}, {"r9", 9, TRUE}, {"r10", 10, TRUE}, {"r11", 11, TRUE},
+ {"r12", 12, TRUE}, {"r13", REG_SP, TRUE}, {"r14", REG_LR, TRUE}, {"r15", REG_PC, TRUE},
+ /* ATPCS Synonyms. */
+ {"a1", 0, TRUE}, {"a2", 1, TRUE}, {"a3", 2, TRUE}, {"a4", 3, TRUE},
+ {"v1", 4, TRUE}, {"v2", 5, TRUE}, {"v3", 6, TRUE}, {"v4", 7, TRUE},
+ {"v5", 8, TRUE}, {"v6", 9, TRUE}, {"v7", 10, TRUE}, {"v8", 11, TRUE},
+ /* Well-known aliases. */
+ {"wr", 7, TRUE}, {"sb", 9, TRUE}, {"sl", 10, TRUE}, {"fp", 11, TRUE},
+ {"ip", 12, TRUE}, {"sp", REG_SP, TRUE}, {"lr", REG_LR, TRUE}, {"pc", REG_PC, TRUE},
+ {NULL, 0, TRUE}
+};
+
+#define WR_PREFIX 0x200
+#define WC_PREFIX 0x400
+
+static const struct reg_entry iwmmxt_table[] =
+{
+ /* Intel Wireless MMX technology register names. */
+ { "wr0", 0x0 | WR_PREFIX, TRUE}, {"wr1", 0x1 | WR_PREFIX, TRUE},
+ { "wr2", 0x2 | WR_PREFIX, TRUE}, {"wr3", 0x3 | WR_PREFIX, TRUE},
+ { "wr4", 0x4 | WR_PREFIX, TRUE}, {"wr5", 0x5 | WR_PREFIX, TRUE},
+ { "wr6", 0x6 | WR_PREFIX, TRUE}, {"wr7", 0x7 | WR_PREFIX, TRUE},
+ { "wr8", 0x8 | WR_PREFIX, TRUE}, {"wr9", 0x9 | WR_PREFIX, TRUE},
+ { "wr10", 0xa | WR_PREFIX, TRUE}, {"wr11", 0xb | WR_PREFIX, TRUE},
+ { "wr12", 0xc | WR_PREFIX, TRUE}, {"wr13", 0xd | WR_PREFIX, TRUE},
+ { "wr14", 0xe | WR_PREFIX, TRUE}, {"wr15", 0xf | WR_PREFIX, TRUE},
+ { "wcid", 0x0 | WC_PREFIX, TRUE}, {"wcon", 0x1 | WC_PREFIX, TRUE},
+ {"wcssf", 0x2 | WC_PREFIX, TRUE}, {"wcasf", 0x3 | WC_PREFIX, TRUE},
+ {"wcgr0", 0x8 | WC_PREFIX, TRUE}, {"wcgr1", 0x9 | WC_PREFIX, TRUE},
+ {"wcgr2", 0xa | WC_PREFIX, TRUE}, {"wcgr3", 0xb | WC_PREFIX, TRUE},
+
+ { "wR0", 0x0 | WR_PREFIX, TRUE}, {"wR1", 0x1 | WR_PREFIX, TRUE},
+ { "wR2", 0x2 | WR_PREFIX, TRUE}, {"wR3", 0x3 | WR_PREFIX, TRUE},
+ { "wR4", 0x4 | WR_PREFIX, TRUE}, {"wR5", 0x5 | WR_PREFIX, TRUE},
+ { "wR6", 0x6 | WR_PREFIX, TRUE}, {"wR7", 0x7 | WR_PREFIX, TRUE},
+ { "wR8", 0x8 | WR_PREFIX, TRUE}, {"wR9", 0x9 | WR_PREFIX, TRUE},
+ { "wR10", 0xa | WR_PREFIX, TRUE}, {"wR11", 0xb | WR_PREFIX, TRUE},
+ { "wR12", 0xc | WR_PREFIX, TRUE}, {"wR13", 0xd | WR_PREFIX, TRUE},
+ { "wR14", 0xe | WR_PREFIX, TRUE}, {"wR15", 0xf | WR_PREFIX, TRUE},
+ { "wCID", 0x0 | WC_PREFIX, TRUE}, {"wCon", 0x1 | WC_PREFIX, TRUE},
+ {"wCSSF", 0x2 | WC_PREFIX, TRUE}, {"wCASF", 0x3 | WC_PREFIX, TRUE},
+ {"wCGR0", 0x8 | WC_PREFIX, TRUE}, {"wCGR1", 0x9 | WC_PREFIX, TRUE},
+ {"wCGR2", 0xa | WC_PREFIX, TRUE}, {"wCGR3", 0xb | WC_PREFIX, TRUE},
+ {NULL, 0, TRUE}
+};
+
+/* Co-processor Numbers. */
+static const struct reg_entry cp_table[] =
+{
+ {"p0", 0, TRUE}, {"p1", 1, TRUE}, {"p2", 2, TRUE}, {"p3", 3, TRUE},
+ {"p4", 4, TRUE}, {"p5", 5, TRUE}, {"p6", 6, TRUE}, {"p7", 7, TRUE},
+ {"p8", 8, TRUE}, {"p9", 9, TRUE}, {"p10", 10, TRUE}, {"p11", 11, TRUE},
+ {"p12", 12, TRUE}, {"p13", 13, TRUE}, {"p14", 14, TRUE}, {"p15", 15, TRUE},
+ {NULL, 0, TRUE}
+};
+
+/* Co-processor Register Numbers. */
+static const struct reg_entry cn_table[] =
+{
+ {"c0", 0, TRUE}, {"c1", 1, TRUE}, {"c2", 2, TRUE}, {"c3", 3, TRUE},
+ {"c4", 4, TRUE}, {"c5", 5, TRUE}, {"c6", 6, TRUE}, {"c7", 7, TRUE},
+ {"c8", 8, TRUE}, {"c9", 9, TRUE}, {"c10", 10, TRUE}, {"c11", 11, TRUE},
+ {"c12", 12, TRUE}, {"c13", 13, TRUE}, {"c14", 14, TRUE}, {"c15", 15, TRUE},
+ /* Not really valid, but kept for back-wards compatibility. */
+ {"cr0", 0, TRUE}, {"cr1", 1, TRUE}, {"cr2", 2, TRUE}, {"cr3", 3, TRUE},
+ {"cr4", 4, TRUE}, {"cr5", 5, TRUE}, {"cr6", 6, TRUE}, {"cr7", 7, TRUE},
+ {"cr8", 8, TRUE}, {"cr9", 9, TRUE}, {"cr10", 10, TRUE}, {"cr11", 11, TRUE},
+ {"cr12", 12, TRUE}, {"cr13", 13, TRUE}, {"cr14", 14, TRUE}, {"cr15", 15, TRUE},
+ {NULL, 0, TRUE}
+};
+
+/* FPA Registers. */
+static const struct reg_entry fn_table[] =
+{
+ {"f0", 0, TRUE}, {"f1", 1, TRUE}, {"f2", 2, TRUE}, {"f3", 3, TRUE},
+ {"f4", 4, TRUE}, {"f5", 5, TRUE}, {"f6", 6, TRUE}, {"f7", 7, TRUE},
+ {NULL, 0, TRUE}
+};
+
+/* VFP SP Registers. */
+static const struct reg_entry sn_table[] =
+{
+ {"s0", 0, TRUE}, {"s1", 1, TRUE}, {"s2", 2, TRUE}, {"s3", 3, TRUE},
+ {"s4", 4, TRUE}, {"s5", 5, TRUE}, {"s6", 6, TRUE}, {"s7", 7, TRUE},
+ {"s8", 8, TRUE}, {"s9", 9, TRUE}, {"s10", 10, TRUE}, {"s11", 11, TRUE},
+ {"s12", 12, TRUE}, {"s13", 13, TRUE}, {"s14", 14, TRUE}, {"s15", 15, TRUE},
+ {"s16", 16, TRUE}, {"s17", 17, TRUE}, {"s18", 18, TRUE}, {"s19", 19, TRUE},
+ {"s20", 20, TRUE}, {"s21", 21, TRUE}, {"s22", 22, TRUE}, {"s23", 23, TRUE},
+ {"s24", 24, TRUE}, {"s25", 25, TRUE}, {"s26", 26, TRUE}, {"s27", 27, TRUE},
+ {"s28", 28, TRUE}, {"s29", 29, TRUE}, {"s30", 30, TRUE}, {"s31", 31, TRUE},
+ {NULL, 0, TRUE}
+};
+
+/* VFP DP Registers. */
+static const struct reg_entry dn_table[] =
+{
+ {"d0", 0, TRUE}, {"d1", 1, TRUE}, {"d2", 2, TRUE}, {"d3", 3, TRUE},
+ {"d4", 4, TRUE}, {"d5", 5, TRUE}, {"d6", 6, TRUE}, {"d7", 7, TRUE},
+ {"d8", 8, TRUE}, {"d9", 9, TRUE}, {"d10", 10, TRUE}, {"d11", 11, TRUE},
+ {"d12", 12, TRUE}, {"d13", 13, TRUE}, {"d14", 14, TRUE}, {"d15", 15, TRUE},
+ {NULL, 0, TRUE}
+};
+
+/* Maverick DSP coprocessor registers. */
+static const struct reg_entry mav_mvf_table[] =
+{
+ {"mvf0", 0, TRUE}, {"mvf1", 1, TRUE}, {"mvf2", 2, TRUE}, {"mvf3", 3, TRUE},
+ {"mvf4", 4, TRUE}, {"mvf5", 5, TRUE}, {"mvf6", 6, TRUE}, {"mvf7", 7, TRUE},
+ {"mvf8", 8, TRUE}, {"mvf9", 9, TRUE}, {"mvf10", 10, TRUE}, {"mvf11", 11, TRUE},
+ {"mvf12", 12, TRUE}, {"mvf13", 13, TRUE}, {"mvf14", 14, TRUE}, {"mvf15", 15, TRUE},
+ {NULL, 0, TRUE}
+};
+
+static const struct reg_entry mav_mvd_table[] =
+{
+ {"mvd0", 0, TRUE}, {"mvd1", 1, TRUE}, {"mvd2", 2, TRUE}, {"mvd3", 3, TRUE},
+ {"mvd4", 4, TRUE}, {"mvd5", 5, TRUE}, {"mvd6", 6, TRUE}, {"mvd7", 7, TRUE},
+ {"mvd8", 8, TRUE}, {"mvd9", 9, TRUE}, {"mvd10", 10, TRUE}, {"mvd11", 11, TRUE},
+ {"mvd12", 12, TRUE}, {"mvd13", 13, TRUE}, {"mvd14", 14, TRUE}, {"mvd15", 15, TRUE},
+ {NULL, 0, TRUE}
+};
+
+static const struct reg_entry mav_mvfx_table[] =
+{
+ {"mvfx0", 0, TRUE}, {"mvfx1", 1, TRUE}, {"mvfx2", 2, TRUE}, {"mvfx3", 3, TRUE},
+ {"mvfx4", 4, TRUE}, {"mvfx5", 5, TRUE}, {"mvfx6", 6, TRUE}, {"mvfx7", 7, TRUE},
+ {"mvfx8", 8, TRUE}, {"mvfx9", 9, TRUE}, {"mvfx10", 10, TRUE}, {"mvfx11", 11, TRUE},
+ {"mvfx12", 12, TRUE}, {"mvfx13", 13, TRUE}, {"mvfx14", 14, TRUE}, {"mvfx15", 15, TRUE},
+ {NULL, 0, TRUE}
+};
+
+static const struct reg_entry mav_mvdx_table[] =
+{
+ {"mvdx0", 0, TRUE}, {"mvdx1", 1, TRUE}, {"mvdx2", 2, TRUE}, {"mvdx3", 3, TRUE},
+ {"mvdx4", 4, TRUE}, {"mvdx5", 5, TRUE}, {"mvdx6", 6, TRUE}, {"mvdx7", 7, TRUE},
+ {"mvdx8", 8, TRUE}, {"mvdx9", 9, TRUE}, {"mvdx10", 10, TRUE}, {"mvdx11", 11, TRUE},
+ {"mvdx12", 12, TRUE}, {"mvdx13", 13, TRUE}, {"mvdx14", 14, TRUE}, {"mvdx15", 15, TRUE},
+ {NULL, 0, TRUE}
+};
+
+static const struct reg_entry mav_mvax_table[] =
+{
+ {"mvax0", 0, TRUE}, {"mvax1", 1, TRUE}, {"mvax2", 2, TRUE}, {"mvax3", 3, TRUE},
+ {NULL, 0, TRUE}
+};
+
+static const struct reg_entry mav_dspsc_table[] =
+{
+ {"dspsc", 0, TRUE},
+ {NULL, 0, TRUE}
+};
+
+struct reg_map
+{
+ const struct reg_entry *names;
+ int max_regno;
+ struct hash_control *htab;
+ const char *expected;
+};
+
+struct reg_map all_reg_maps[] =
+{
+ {rn_table, 15, NULL, N_("ARM register expected")},
+ {cp_table, 15, NULL, N_("bad or missing co-processor number")},
+ {cn_table, 15, NULL, N_("co-processor register expected")},
+ {fn_table, 7, NULL, N_("FPA register expected")},
+ {sn_table, 31, NULL, N_("VFP single precision register expected")},
+ {dn_table, 15, NULL, N_("VFP double precision register expected")},
+ {mav_mvf_table, 15, NULL, N_("Maverick MVF register expected")},
+ {mav_mvd_table, 15, NULL, N_("Maverick MVD register expected")},
+ {mav_mvfx_table, 15, NULL, N_("Maverick MVFX register expected")},
+ {mav_mvdx_table, 15, NULL, N_("Maverick MVDX register expected")},
+ {mav_mvax_table, 3, NULL, N_("Maverick MVAX register expected")},
+ {mav_dspsc_table, 0, NULL, N_("Maverick DSPSC register expected")},
+ {iwmmxt_table, 23, NULL, N_("Intel Wireless MMX technology register expected")},
+};
+
+/* Enumeration matching entries in table above. */
+enum arm_reg_type
+{
+ REG_TYPE_RN = 0,
+#define REG_TYPE_FIRST REG_TYPE_RN
+ REG_TYPE_CP = 1,
+ REG_TYPE_CN = 2,
+ REG_TYPE_FN = 3,
+ REG_TYPE_SN = 4,
+ REG_TYPE_DN = 5,
+ REG_TYPE_MVF = 6,
+ REG_TYPE_MVD = 7,
+ REG_TYPE_MVFX = 8,
+ REG_TYPE_MVDX = 9,
+ REG_TYPE_MVAX = 10,
+ REG_TYPE_DSPSC = 11,
+ REG_TYPE_IWMMXT = 12,
+
+ REG_TYPE_MAX = 13
+};
+
+/* Functions called by parser. */
+/* ARM instructions. */
+static void do_arit PARAMS ((char *));
+static void do_cmp PARAMS ((char *));
+static void do_mov PARAMS ((char *));
+static void do_ldst PARAMS ((char *));
+static void do_ldstt PARAMS ((char *));
+static void do_ldmstm PARAMS ((char *));
+static void do_branch PARAMS ((char *));
+static void do_swi PARAMS ((char *));
+
+/* Pseudo Op codes. */
+static void do_adr PARAMS ((char *));
+static void do_adrl PARAMS ((char *));
+static void do_empty PARAMS ((char *));
+
+/* ARM v2. */
+static void do_mul PARAMS ((char *));
+static void do_mla PARAMS ((char *));
+
+/* ARM v2S. */
+static void do_swap PARAMS ((char *));
+
+/* ARM v3. */
+static void do_msr PARAMS ((char *));
+static void do_mrs PARAMS ((char *));
+
+/* ARM v3M. */
+static void do_mull PARAMS ((char *));
+
+/* ARM v4. */
+static void do_ldstv4 PARAMS ((char *));
+
+/* ARM v4T. */
+static void do_bx PARAMS ((char *));
+
+/* ARM v5T. */
+static void do_blx PARAMS ((char *));
+static void do_bkpt PARAMS ((char *));
+static void do_clz PARAMS ((char *));
+static void do_lstc2 PARAMS ((char *));
+static void do_cdp2 PARAMS ((char *));
+static void do_co_reg2 PARAMS ((char *));
+
+/* ARM v5TExP. */
+static void do_smla PARAMS ((char *));
+static void do_smlal PARAMS ((char *));
+static void do_smul PARAMS ((char *));
+static void do_qadd PARAMS ((char *));
+
+/* ARM v5TE. */
+static void do_pld PARAMS ((char *));
+static void do_ldrd PARAMS ((char *));
+static void do_co_reg2c PARAMS ((char *));
+
+/* ARM v5TEJ. */
+static void do_bxj PARAMS ((char *));
+
+/* ARM V6. */
+static void do_cps PARAMS ((char *));
+static void do_cpsi PARAMS ((char *));
+static void do_ldrex PARAMS ((char *));
+static void do_pkhbt PARAMS ((char *));
+static void do_pkhtb PARAMS ((char *));
+static void do_qadd16 PARAMS ((char *));
+static void do_rev PARAMS ((char *));
+static void do_rfe PARAMS ((char *));
+static void do_sxtah PARAMS ((char *));
+static void do_sxth PARAMS ((char *));
+static void do_setend PARAMS ((char *));
+static void do_smlad PARAMS ((char *));
+static void do_smlald PARAMS ((char *));
+static void do_smmul PARAMS ((char *));
+static void do_ssat PARAMS ((char *));
+static void do_usat PARAMS ((char *));
+static void do_srs PARAMS ((char *));
+static void do_ssat16 PARAMS ((char *));
+static void do_usat16 PARAMS ((char *));
+static void do_strex PARAMS ((char *));
+static void do_umaal PARAMS ((char *));
+
+static void do_cps_mode PARAMS ((char **));
+static void do_cps_flags PARAMS ((char **, int));
+static int do_endian_specifier PARAMS ((char *));
+static void do_pkh_core PARAMS ((char *, int));
+static void do_sat PARAMS ((char **, int));
+static void do_sat16 PARAMS ((char **, int));
+
+/* Coprocessor Instructions. */
+static void do_cdp PARAMS ((char *));
+static void do_lstc PARAMS ((char *));
+static void do_co_reg PARAMS ((char *));
+
+/* FPA instructions. */
+static void do_fpa_ctrl PARAMS ((char *));
+static void do_fpa_ldst PARAMS ((char *));
+static void do_fpa_ldmstm PARAMS ((char *));
+static void do_fpa_dyadic PARAMS ((char *));
+static void do_fpa_monadic PARAMS ((char *));
+static void do_fpa_cmp PARAMS ((char *));
+static void do_fpa_from_reg PARAMS ((char *));
+static void do_fpa_to_reg PARAMS ((char *));
+
+/* VFP instructions. */
+static void do_vfp_sp_monadic PARAMS ((char *));
+static void do_vfp_dp_monadic PARAMS ((char *));
+static void do_vfp_sp_dyadic PARAMS ((char *));
+static void do_vfp_dp_dyadic PARAMS ((char *));
+static void do_vfp_reg_from_sp PARAMS ((char *));
+static void do_vfp_sp_from_reg PARAMS ((char *));
+static void do_vfp_reg2_from_sp2 PARAMS ((char *));
+static void do_vfp_sp2_from_reg2 PARAMS ((char *));
+static void do_vfp_reg_from_dp PARAMS ((char *));
+static void do_vfp_reg2_from_dp PARAMS ((char *));
+static void do_vfp_dp_from_reg PARAMS ((char *));
+static void do_vfp_dp_from_reg2 PARAMS ((char *));
+static void do_vfp_reg_from_ctrl PARAMS ((char *));
+static void do_vfp_ctrl_from_reg PARAMS ((char *));
+static void do_vfp_sp_ldst PARAMS ((char *));
+static void do_vfp_dp_ldst PARAMS ((char *));
+static void do_vfp_sp_ldstmia PARAMS ((char *));
+static void do_vfp_sp_ldstmdb PARAMS ((char *));
+static void do_vfp_dp_ldstmia PARAMS ((char *));
+static void do_vfp_dp_ldstmdb PARAMS ((char *));
+static void do_vfp_xp_ldstmia PARAMS ((char *));
+static void do_vfp_xp_ldstmdb PARAMS ((char *));
+static void do_vfp_sp_compare_z PARAMS ((char *));
+static void do_vfp_dp_compare_z PARAMS ((char *));
+static void do_vfp_dp_sp_cvt PARAMS ((char *));
+static void do_vfp_sp_dp_cvt PARAMS ((char *));
+
+/* XScale. */
+static void do_xsc_mia PARAMS ((char *));
+static void do_xsc_mar PARAMS ((char *));
+static void do_xsc_mra PARAMS ((char *));
+
+/* Maverick. */
+static void do_mav_binops PARAMS ((char *, int, enum arm_reg_type,
+ enum arm_reg_type));
+static void do_mav_binops_1a PARAMS ((char *));
+static void do_mav_binops_1b PARAMS ((char *));
+static void do_mav_binops_1c PARAMS ((char *));
+static void do_mav_binops_1d PARAMS ((char *));
+static void do_mav_binops_1e PARAMS ((char *));
+static void do_mav_binops_1f PARAMS ((char *));
+static void do_mav_binops_1g PARAMS ((char *));
+static void do_mav_binops_1h PARAMS ((char *));
+static void do_mav_binops_1i PARAMS ((char *));
+static void do_mav_binops_1j PARAMS ((char *));
+static void do_mav_binops_1k PARAMS ((char *));
+static void do_mav_binops_1l PARAMS ((char *));
+static void do_mav_binops_1m PARAMS ((char *));
+static void do_mav_binops_1n PARAMS ((char *));
+static void do_mav_binops_1o PARAMS ((char *));
+static void do_mav_binops_2a PARAMS ((char *));
+static void do_mav_binops_2b PARAMS ((char *));
+static void do_mav_binops_2c PARAMS ((char *));
+static void do_mav_binops_3a PARAMS ((char *));
+static void do_mav_binops_3b PARAMS ((char *));
+static void do_mav_binops_3c PARAMS ((char *));
+static void do_mav_binops_3d PARAMS ((char *));
+static void do_mav_triple PARAMS ((char *, int, enum arm_reg_type,
+ enum arm_reg_type,
+ enum arm_reg_type));
+static void do_mav_triple_4a PARAMS ((char *));
+static void do_mav_triple_4b PARAMS ((char *));
+static void do_mav_triple_5a PARAMS ((char *));
+static void do_mav_triple_5b PARAMS ((char *));
+static void do_mav_triple_5c PARAMS ((char *));
+static void do_mav_triple_5d PARAMS ((char *));
+static void do_mav_triple_5e PARAMS ((char *));
+static void do_mav_triple_5f PARAMS ((char *));
+static void do_mav_triple_5g PARAMS ((char *));
+static void do_mav_triple_5h PARAMS ((char *));
+static void do_mav_quad PARAMS ((char *, int, enum arm_reg_type,
+ enum arm_reg_type,
+ enum arm_reg_type,
+ enum arm_reg_type));
+static void do_mav_quad_6a PARAMS ((char *));
+static void do_mav_quad_6b PARAMS ((char *));
+static void do_mav_dspsc_1 PARAMS ((char *));
+static void do_mav_dspsc_2 PARAMS ((char *));
+static void do_mav_shift PARAMS ((char *, enum arm_reg_type,
+ enum arm_reg_type));
+static void do_mav_shift_1 PARAMS ((char *));
+static void do_mav_shift_2 PARAMS ((char *));
+static void do_mav_ldst PARAMS ((char *, enum arm_reg_type));
+static void do_mav_ldst_1 PARAMS ((char *));
+static void do_mav_ldst_2 PARAMS ((char *));
+static void do_mav_ldst_3 PARAMS ((char *));
+static void do_mav_ldst_4 PARAMS ((char *));
+
+static int mav_reg_required_here PARAMS ((char **, int,
+ enum arm_reg_type));
+static int mav_parse_offset PARAMS ((char **, int *));
+
+static void fix_new_arm PARAMS ((fragS *, int, short, expressionS *,
+ int, int));
+static int arm_reg_parse PARAMS ((char **, struct hash_control *));
+static enum arm_reg_type arm_reg_parse_any PARAMS ((char *));
+static const struct asm_psr * arm_psr_parse PARAMS ((char **));
+static void symbol_locate PARAMS ((symbolS *, const char *, segT, valueT,
+ fragS *));
+static int add_to_lit_pool PARAMS ((void));
+static unsigned validate_immediate PARAMS ((unsigned));
+static unsigned validate_immediate_twopart PARAMS ((unsigned int,
+ unsigned int *));
+static int validate_offset_imm PARAMS ((unsigned int, int));
+static void opcode_select PARAMS ((int));
+static void end_of_line PARAMS ((char *));
+static int reg_required_here PARAMS ((char **, int));
+static int psr_required_here PARAMS ((char **));
+static int co_proc_number PARAMS ((char **));
+static int cp_opc_expr PARAMS ((char **, int, int));
+static int cp_reg_required_here PARAMS ((char **, int));
+static int fp_reg_required_here PARAMS ((char **, int));
+static int vfp_sp_reg_required_here PARAMS ((char **, enum vfp_sp_reg_pos));
+static int vfp_dp_reg_required_here PARAMS ((char **, enum vfp_dp_reg_pos));
+static void vfp_sp_ldstm PARAMS ((char *, enum vfp_ldstm_type));
+static void vfp_dp_ldstm PARAMS ((char *, enum vfp_ldstm_type));
+static long vfp_sp_reg_list PARAMS ((char **, enum vfp_sp_reg_pos));
+static long vfp_dp_reg_list PARAMS ((char **));
+static int vfp_psr_required_here PARAMS ((char **str));
+static const struct vfp_reg *vfp_psr_parse PARAMS ((char **str));
+static int cp_address_offset PARAMS ((char **));
+static int cp_address_required_here PARAMS ((char **, int));
+static int my_get_float_expression PARAMS ((char **));
+static int skip_past_comma PARAMS ((char **));
+static int walk_no_bignums PARAMS ((symbolS *));
+static int negate_data_op PARAMS ((unsigned long *, unsigned long));
+static int data_op2 PARAMS ((char **));
+static int fp_op2 PARAMS ((char **));
+static long reg_list PARAMS ((char **));
+static void thumb_load_store PARAMS ((char *, int, int));
+static int decode_shift PARAMS ((char **, int));
+static int ldst_extend PARAMS ((char **));
+static int ldst_extend_v4 PARAMS ((char **));
+static void thumb_add_sub PARAMS ((char *, int));
+static void insert_reg PARAMS ((const struct reg_entry *,
+ struct hash_control *));
+static void thumb_shift PARAMS ((char *, int));
+static void thumb_mov_compare PARAMS ((char *, int));
+static void build_arm_ops_hsh PARAMS ((void));
+static void set_constant_flonums PARAMS ((void));
+static valueT md_chars_to_number PARAMS ((char *, int));
+static void build_reg_hsh PARAMS ((struct reg_map *));
+static void insert_reg_alias PARAMS ((char *, int, struct hash_control *));
+static int create_register_alias PARAMS ((char *, char *));
+static void output_inst PARAMS ((const char *));
+static int accum0_required_here PARAMS ((char **));
+static int ld_mode_required_here PARAMS ((char **));
+static void do_branch25 PARAMS ((char *));
+static symbolS * find_real_start PARAMS ((symbolS *));
+#ifdef OBJ_ELF
+static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
+#endif
+
+static int wreg_required_here PARAMS ((char **, int, enum wreg_type));
+static void do_iwmmxt_byte_addr PARAMS ((char *));
+static void do_iwmmxt_tandc PARAMS ((char *));
+static void do_iwmmxt_tbcst PARAMS ((char *));
+static void do_iwmmxt_textrc PARAMS ((char *));
+static void do_iwmmxt_textrm PARAMS ((char *));
+static void do_iwmmxt_tinsr PARAMS ((char *));
+static void do_iwmmxt_tmcr PARAMS ((char *));
+static void do_iwmmxt_tmcrr PARAMS ((char *));
+static void do_iwmmxt_tmia PARAMS ((char *));
+static void do_iwmmxt_tmovmsk PARAMS ((char *));
+static void do_iwmmxt_tmrc PARAMS ((char *));
+static void do_iwmmxt_tmrrc PARAMS ((char *));
+static void do_iwmmxt_torc PARAMS ((char *));
+static void do_iwmmxt_waligni PARAMS ((char *));
+static void do_iwmmxt_wmov PARAMS ((char *));
+static void do_iwmmxt_word_addr PARAMS ((char *));
+static void do_iwmmxt_wrwr PARAMS ((char *));
+static void do_iwmmxt_wrwrwcg PARAMS ((char *));
+static void do_iwmmxt_wrwrwr PARAMS ((char *));
+static void do_iwmmxt_wshufh PARAMS ((char *));
+static void do_iwmmxt_wzero PARAMS ((char *));
+static int cp_byte_address_offset PARAMS ((char **));
+static int cp_byte_address_required_here PARAMS ((char **));
+
+/* ARM instructions take 4bytes in the object file, Thumb instructions
+ take 2: */
+#define INSN_SIZE 4
+
+/* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
+#define MAV_MODE1 0x100c
+
+/* "INSN<cond> X,Y" where X:bit16, Y:bit12. */
+#define MAV_MODE2 0x0c10
+
+/* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
+#define MAV_MODE3 0x100c
+
+/* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12. */
+#define MAV_MODE4 0x0c0010
+
+/* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0. */
+#define MAV_MODE5 0x00100c
+
+/* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0. */
+#define MAV_MODE6 0x00100c05
+
+struct asm_opcode
+{
+ /* Basic string to match. */
+ const char * template;
+
+ /* Basic instruction code. */
+ unsigned long value;
+
+ /* Offset into the template where the condition code (if any) will be.
+ If zero, then the instruction is never conditional. */
+ unsigned cond_offset;
+
+ /* Which architecture variant provides this instruction. */
+ unsigned long variant;
+
+ /* Function to call to parse args. */
+ void (* parms) PARAMS ((char *));
+};
+
+static const struct asm_opcode insns[] =
+{
+ /* Core ARM Instructions. */
+ {"and", 0xe0000000, 3, ARM_EXT_V1, do_arit},
+ {"ands", 0xe0100000, 3, ARM_EXT_V1, do_arit},
+ {"eor", 0xe0200000, 3, ARM_EXT_V1, do_arit},
+ {"eors", 0xe0300000, 3, ARM_EXT_V1, do_arit},
+ {"sub", 0xe0400000, 3, ARM_EXT_V1, do_arit},
+ {"subs", 0xe0500000, 3, ARM_EXT_V1, do_arit},
+ {"rsb", 0xe0600000, 3, ARM_EXT_V1, do_arit},
+ {"rsbs", 0xe0700000, 3, ARM_EXT_V1, do_arit},
+ {"add", 0xe0800000, 3, ARM_EXT_V1, do_arit},
+ {"adds", 0xe0900000, 3, ARM_EXT_V1, do_arit},
+ {"adc", 0xe0a00000, 3, ARM_EXT_V1, do_arit},
+ {"adcs", 0xe0b00000, 3, ARM_EXT_V1, do_arit},
+ {"sbc", 0xe0c00000, 3, ARM_EXT_V1, do_arit},
+ {"sbcs", 0xe0d00000, 3, ARM_EXT_V1, do_arit},
+ {"rsc", 0xe0e00000, 3, ARM_EXT_V1, do_arit},
+ {"rscs", 0xe0f00000, 3, ARM_EXT_V1, do_arit},
+ {"orr", 0xe1800000, 3, ARM_EXT_V1, do_arit},
+ {"orrs", 0xe1900000, 3, ARM_EXT_V1, do_arit},
+ {"bic", 0xe1c00000, 3, ARM_EXT_V1, do_arit},
+ {"bics", 0xe1d00000, 3, ARM_EXT_V1, do_arit},
+
+ {"tst", 0xe1100000, 3, ARM_EXT_V1, do_cmp},
+ {"tsts", 0xe1100000, 3, ARM_EXT_V1, do_cmp},
+ {"tstp", 0xe110f000, 3, ARM_EXT_V1, do_cmp},
+ {"teq", 0xe1300000, 3, ARM_EXT_V1, do_cmp},
+ {"teqs", 0xe1300000, 3, ARM_EXT_V1, do_cmp},
+ {"teqp", 0xe130f000, 3, ARM_EXT_V1, do_cmp},
+ {"cmp", 0xe1500000, 3, ARM_EXT_V1, do_cmp},
+ {"cmps", 0xe1500000, 3, ARM_EXT_V1, do_cmp},
+ {"cmpp", 0xe150f000, 3, ARM_EXT_V1, do_cmp},
+ {"cmn", 0xe1700000, 3, ARM_EXT_V1, do_cmp},
+ {"cmns", 0xe1700000, 3, ARM_EXT_V1, do_cmp},
+ {"cmnp", 0xe170f000, 3, ARM_EXT_V1, do_cmp},
+
+ {"mov", 0xe1a00000, 3, ARM_EXT_V1, do_mov},
+ {"movs", 0xe1b00000, 3, ARM_EXT_V1, do_mov},
+ {"mvn", 0xe1e00000, 3, ARM_EXT_V1, do_mov},
+ {"mvns", 0xe1f00000, 3, ARM_EXT_V1, do_mov},
+
+ {"ldr", 0xe4100000, 3, ARM_EXT_V1, do_ldst},
+ {"ldrb", 0xe4500000, 3, ARM_EXT_V1, do_ldst},
+ {"ldrt", 0xe4300000, 3, ARM_EXT_V1, do_ldstt},
+ {"ldrbt", 0xe4700000, 3, ARM_EXT_V1, do_ldstt},
+ {"str", 0xe4000000, 3, ARM_EXT_V1, do_ldst},
+ {"strb", 0xe4400000, 3, ARM_EXT_V1, do_ldst},
+ {"strt", 0xe4200000, 3, ARM_EXT_V1, do_ldstt},
+ {"strbt", 0xe4600000, 3, ARM_EXT_V1, do_ldstt},
+
+ {"stmia", 0xe8800000, 3, ARM_EXT_V1, do_ldmstm},
+ {"stmib", 0xe9800000, 3, ARM_EXT_V1, do_ldmstm},
+ {"stmda", 0xe8000000, 3, ARM_EXT_V1, do_ldmstm},
+ {"stmdb", 0xe9000000, 3, ARM_EXT_V1, do_ldmstm},
+ {"stmfd", 0xe9000000, 3, ARM_EXT_V1, do_ldmstm},
+ {"stmfa", 0xe9800000, 3, ARM_EXT_V1, do_ldmstm},
+ {"stmea", 0xe8800000, 3, ARM_EXT_V1, do_ldmstm},
+ {"stmed", 0xe8000000, 3, ARM_EXT_V1, do_ldmstm},
+
+ {"ldmia", 0xe8900000, 3, ARM_EXT_V1, do_ldmstm},
+ {"ldmib", 0xe9900000, 3, ARM_EXT_V1, do_ldmstm},
+ {"ldmda", 0xe8100000, 3, ARM_EXT_V1, do_ldmstm},
+ {"ldmdb", 0xe9100000, 3, ARM_EXT_V1, do_ldmstm},
+ {"ldmfd", 0xe8900000, 3, ARM_EXT_V1, do_ldmstm},
+ {"ldmfa", 0xe8100000, 3, ARM_EXT_V1, do_ldmstm},
+ {"ldmea", 0xe9100000, 3, ARM_EXT_V1, do_ldmstm},
+ {"ldmed", 0xe9900000, 3, ARM_EXT_V1, do_ldmstm},
+
+ {"swi", 0xef000000, 3, ARM_EXT_V1, do_swi},
+#ifdef TE_WINCE
+ /* XXX This is the wrong place to do this. Think multi-arch. */
+ {"bl", 0xeb000000, 2, ARM_EXT_V1, do_branch},
+ {"b", 0xea000000, 1, ARM_EXT_V1, do_branch},
+#else
+ {"bl", 0xebfffffe, 2, ARM_EXT_V1, do_branch},
+ {"b", 0xeafffffe, 1, ARM_EXT_V1, do_branch},
+#endif
+
+ /* Pseudo ops. */
+ {"adr", 0xe28f0000, 3, ARM_EXT_V1, do_adr},
+ {"adrl", 0xe28f0000, 3, ARM_EXT_V1, do_adrl},
+ {"nop", 0xe1a00000, 3, ARM_EXT_V1, do_empty},
+
+ /* ARM 2 multiplies. */
+ {"mul", 0xe0000090, 3, ARM_EXT_V2, do_mul},
+ {"muls", 0xe0100090, 3, ARM_EXT_V2, do_mul},
+ {"mla", 0xe0200090, 3, ARM_EXT_V2, do_mla},
+ {"mlas", 0xe0300090, 3, ARM_EXT_V2, do_mla},
+
+ /* Generic coprocessor instructions. */
+ {"cdp", 0xee000000, 3, ARM_EXT_V2, do_cdp},
+ {"ldc", 0xec100000, 3, ARM_EXT_V2, do_lstc},
+ {"ldcl", 0xec500000, 3, ARM_EXT_V2, do_lstc},
+ {"stc", 0xec000000, 3, ARM_EXT_V2, do_lstc},
+ {"stcl", 0xec400000, 3, ARM_EXT_V2, do_lstc},
+ {"mcr", 0xee000010, 3, ARM_EXT_V2, do_co_reg},
+ {"mrc", 0xee100010, 3, ARM_EXT_V2, do_co_reg},
+
+ /* ARM 3 - swp instructions. */
+ {"swp", 0xe1000090, 3, ARM_EXT_V2S, do_swap},
+ {"swpb", 0xe1400090, 3, ARM_EXT_V2S, do_swap},
+
+ /* ARM 6 Status register instructions. */
+ {"mrs", 0xe10f0000, 3, ARM_EXT_V3, do_mrs},
+ {"msr", 0xe120f000, 3, ARM_EXT_V3, do_msr},
+ /* ScottB: our code uses 0xe128f000 for msr.
+ NickC: but this is wrong because the bits 16 through 19 are
+ handled by the PSR_xxx defines above. */
+
+ /* ARM 7M long multiplies. */
+ {"smull", 0xe0c00090, 5, ARM_EXT_V3M, do_mull},
+ {"smulls", 0xe0d00090, 5, ARM_EXT_V3M, do_mull},
+ {"umull", 0xe0800090, 5, ARM_EXT_V3M, do_mull},
+ {"umulls", 0xe0900090, 5, ARM_EXT_V3M, do_mull},
+ {"smlal", 0xe0e00090, 5, ARM_EXT_V3M, do_mull},
+ {"smlals", 0xe0f00090, 5, ARM_EXT_V3M, do_mull},
+ {"umlal", 0xe0a00090, 5, ARM_EXT_V3M, do_mull},
+ {"umlals", 0xe0b00090, 5, ARM_EXT_V3M, do_mull},
+
+ /* ARM Architecture 4. */
+ {"ldrh", 0xe01000b0, 3, ARM_EXT_V4, do_ldstv4},
+ {"ldrsh", 0xe01000f0, 3, ARM_EXT_V4, do_ldstv4},
+ {"ldrsb", 0xe01000d0, 3, ARM_EXT_V4, do_ldstv4},
+ {"strh", 0xe00000b0, 3, ARM_EXT_V4, do_ldstv4},
+
+ /* ARM Architecture 4T. */
+ /* Note: bx (and blx) are required on V5, even if the processor does
+ not support Thumb. */
+ {"bx", 0xe12fff10, 2, ARM_EXT_V4T | ARM_EXT_V5, do_bx},
+
+ /* ARM Architecture 5T. */
+ /* Note: blx has 2 variants, so the .value is set dynamically.
+ Only one of the variants has conditional execution. */
+ {"blx", 0xe0000000, 3, ARM_EXT_V5, do_blx},
+ {"clz", 0xe16f0f10, 3, ARM_EXT_V5, do_clz},
+ {"bkpt", 0xe1200070, 0, ARM_EXT_V5, do_bkpt},
+ {"ldc2", 0xfc100000, 0, ARM_EXT_V5, do_lstc2},
+ {"ldc2l", 0xfc500000, 0, ARM_EXT_V5, do_lstc2},
+ {"stc2", 0xfc000000, 0, ARM_EXT_V5, do_lstc2},
+ {"stc2l", 0xfc400000, 0, ARM_EXT_V5, do_lstc2},
+ {"cdp2", 0xfe000000, 0, ARM_EXT_V5, do_cdp2},
+ {"mcr2", 0xfe000010, 0, ARM_EXT_V5, do_co_reg2},
+ {"mrc2", 0xfe100010, 0, ARM_EXT_V5, do_co_reg2},
+
+ /* ARM Architecture 5TExP. */
+ {"smlabb", 0xe1000080, 6, ARM_EXT_V5ExP, do_smla},
+ {"smlatb", 0xe10000a0, 6, ARM_EXT_V5ExP, do_smla},
+ {"smlabt", 0xe10000c0, 6, ARM_EXT_V5ExP, do_smla},
+ {"smlatt", 0xe10000e0, 6, ARM_EXT_V5ExP, do_smla},
+
+ {"smlawb", 0xe1200080, 6, ARM_EXT_V5ExP, do_smla},
+ {"smlawt", 0xe12000c0, 6, ARM_EXT_V5ExP, do_smla},
+
+ {"smlalbb", 0xe1400080, 7, ARM_EXT_V5ExP, do_smlal},
+ {"smlaltb", 0xe14000a0, 7, ARM_EXT_V5ExP, do_smlal},
+ {"smlalbt", 0xe14000c0, 7, ARM_EXT_V5ExP, do_smlal},
+ {"smlaltt", 0xe14000e0, 7, ARM_EXT_V5ExP, do_smlal},
+
+ {"smulbb", 0xe1600080, 6, ARM_EXT_V5ExP, do_smul},
+ {"smultb", 0xe16000a0, 6, ARM_EXT_V5ExP, do_smul},
+ {"smulbt", 0xe16000c0, 6, ARM_EXT_V5ExP, do_smul},
+ {"smultt", 0xe16000e0, 6, ARM_EXT_V5ExP, do_smul},
+
+ {"smulwb", 0xe12000a0, 6, ARM_EXT_V5ExP, do_smul},
+ {"smulwt", 0xe12000e0, 6, ARM_EXT_V5ExP, do_smul},
+
+ {"qadd", 0xe1000050, 4, ARM_EXT_V5ExP, do_qadd},
+ {"qdadd", 0xe1400050, 5, ARM_EXT_V5ExP, do_qadd},
+ {"qsub", 0xe1200050, 4, ARM_EXT_V5ExP, do_qadd},
+ {"qdsub", 0xe1600050, 5, ARM_EXT_V5ExP, do_qadd},
+
+ /* ARM Architecture 5TE. */
+ {"pld", 0xf450f000, 0, ARM_EXT_V5E, do_pld},
+ {"ldrd", 0xe00000d0, 3, ARM_EXT_V5E, do_ldrd},
+ {"strd", 0xe00000f0, 3, ARM_EXT_V5E, do_ldrd},
+
+ {"mcrr", 0xec400000, 4, ARM_EXT_V5E, do_co_reg2c},
+ {"mrrc", 0xec500000, 4, ARM_EXT_V5E, do_co_reg2c},
+
+ /* ARM Architecture 5TEJ. */
+ {"bxj", 0xe12fff20, 3, ARM_EXT_V5J, do_bxj},
+
+ /* ARM V6. */
+ { "cps", 0xf1020000, 0, ARM_EXT_V6, do_cps},
+ { "cpsie", 0xf1080000, 0, ARM_EXT_V6, do_cpsi},
+ { "cpsid", 0xf10C0000, 0, ARM_EXT_V6, do_cpsi},
+ { "ldrex", 0xe1900f9f, 5, ARM_EXT_V6, do_ldrex},
+ { "mcrr2", 0xfc400000, 0, ARM_EXT_V6, do_co_reg2c},
+ { "mrrc2", 0xfc500000, 0, ARM_EXT_V6, do_co_reg2c},
+ { "pkhbt", 0xe6800010, 5, ARM_EXT_V6, do_pkhbt},
+ { "pkhtb", 0xe6800050, 5, ARM_EXT_V6, do_pkhtb},
+ { "qadd16", 0xe6200f10, 6, ARM_EXT_V6, do_qadd16},
+ { "qadd8", 0xe6200f90, 5, ARM_EXT_V6, do_qadd16},
+ { "qaddsubx", 0xe6200f30, 8, ARM_EXT_V6, do_qadd16},
+ { "qsub16", 0xe6200f70, 6, ARM_EXT_V6, do_qadd16},
+ { "qsub8", 0xe6200ff0, 5, ARM_EXT_V6, do_qadd16},
+ { "qsubaddx", 0xe6200f50, 8, ARM_EXT_V6, do_qadd16},
+ { "sadd16", 0xe6100f10, 6, ARM_EXT_V6, do_qadd16},
+ { "sadd8", 0xe6100f90, 5, ARM_EXT_V6, do_qadd16},
+ { "saddsubx", 0xe6100f30, 8, ARM_EXT_V6, do_qadd16},
+ { "shadd16", 0xe6300f10, 7, ARM_EXT_V6, do_qadd16},
+ { "shadd8", 0xe6300f90, 6, ARM_EXT_V6, do_qadd16},
+ { "shaddsubx", 0xe6300f30, 9, ARM_EXT_V6, do_qadd16},
+ { "shsub16", 0xe6300f70, 7, ARM_EXT_V6, do_qadd16},
+ { "shsub8", 0xe6300ff0, 6, ARM_EXT_V6, do_qadd16},
+ { "shsubaddx", 0xe6300f50, 9, ARM_EXT_V6, do_qadd16},
+ { "ssub16", 0xe6100f70, 6, ARM_EXT_V6, do_qadd16},
+ { "ssub8", 0xe6100ff0, 5, ARM_EXT_V6, do_qadd16},
+ { "ssubaddx", 0xe6100f50, 8, ARM_EXT_V6, do_qadd16},
+ { "uadd16", 0xe6500f10, 6, ARM_EXT_V6, do_qadd16},
+ { "uadd8", 0xe6500f90, 5, ARM_EXT_V6, do_qadd16},
+ { "uaddsubx", 0xe6500f30, 8, ARM_EXT_V6, do_qadd16},
+ { "uhadd16", 0xe6700f10, 7, ARM_EXT_V6, do_qadd16},
+ { "uhadd8", 0xe6700f90, 6, ARM_EXT_V6, do_qadd16},
+ { "uhaddsubx", 0xe6700f30, 9, ARM_EXT_V6, do_qadd16},
+ { "uhsub16", 0xe6700f70, 7, ARM_EXT_V6, do_qadd16},
+ { "uhsub8", 0xe6700ff0, 6, ARM_EXT_V6, do_qadd16},
+ { "uhsubaddx", 0xe6700f50, 9, ARM_EXT_V6, do_qadd16},
+ { "uqadd16", 0xe6600f10, 7, ARM_EXT_V6, do_qadd16},
+ { "uqadd8", 0xe6600f90, 6, ARM_EXT_V6, do_qadd16},
+ { "uqaddsubx", 0xe6600f30, 9, ARM_EXT_V6, do_qadd16},
+ { "uqsub16", 0xe6600f70, 7, ARM_EXT_V6, do_qadd16},
+ { "uqsub8", 0xe6600ff0, 6, ARM_EXT_V6, do_qadd16},
+ { "uqsubaddx", 0xe6600f50, 9, ARM_EXT_V6, do_qadd16},
+ { "usub16", 0xe6500f70, 6, ARM_EXT_V6, do_qadd16},
+ { "usub8", 0xe6500ff0, 5, ARM_EXT_V6, do_qadd16},
+ { "usubaddx", 0xe6500f50, 8, ARM_EXT_V6, do_qadd16},
+ { "rev", 0xe6bf0f30, 3, ARM_EXT_V6, do_rev},
+ { "rev16", 0xe6bf0fb0, 5, ARM_EXT_V6, do_rev},
+ { "revsh", 0xe6ff0fb0, 5, ARM_EXT_V6, do_rev},
+ { "rfeia", 0xf8900a00, 0, ARM_EXT_V6, do_rfe},
+ { "rfeib", 0xf9900a00, 0, ARM_EXT_V6, do_rfe},
+ { "rfeda", 0xf8100a00, 0, ARM_EXT_V6, do_rfe},
+ { "rfedb", 0xf9100a00, 0, ARM_EXT_V6, do_rfe},
+ { "rfefd", 0xf8900a00, 0, ARM_EXT_V6, do_rfe},
+ { "rfefa", 0xf9900a00, 0, ARM_EXT_V6, do_rfe},
+ { "rfeea", 0xf8100a00, 0, ARM_EXT_V6, do_rfe},
+ { "rfeed", 0xf9100a00, 0, ARM_EXT_V6, do_rfe},
+ { "sxtah", 0xe6b00070, 5, ARM_EXT_V6, do_sxtah},
+ { "sxtab16", 0xe6800070, 7, ARM_EXT_V6, do_sxtah},
+ { "sxtab", 0xe6a00070, 5, ARM_EXT_V6, do_sxtah},
+ { "sxth", 0xe6bf0070, 4, ARM_EXT_V6, do_sxth},
+ { "sxtb16", 0xe68f0070, 6, ARM_EXT_V6, do_sxth},
+ { "sxtb", 0xe6af0070, 4, ARM_EXT_V6, do_sxth},
+ { "uxtah", 0xe6f00070, 5, ARM_EXT_V6, do_sxtah},
+ { "uxtab16", 0xe6c00070, 7, ARM_EXT_V6, do_sxtah},
+ { "uxtab", 0xe6e00070, 5, ARM_EXT_V6, do_sxtah},
+ { "uxth", 0xe6ff0070, 4, ARM_EXT_V6, do_sxth},
+ { "uxtb16", 0xe6cf0070, 6, ARM_EXT_V6, do_sxth},
+ { "uxtb", 0xe6ef0070, 4, ARM_EXT_V6, do_sxth},
+ { "sel", 0xe68000b0, 3, ARM_EXT_V6, do_qadd16},
+ { "setend", 0xf1010000, 0, ARM_EXT_V6, do_setend},
+ { "smlad", 0xe7000010, 5, ARM_EXT_V6, do_smlad},
+ { "smladx", 0xe7000030, 6, ARM_EXT_V6, do_smlad},
+ { "smlald", 0xe7400010, 6, ARM_EXT_V6, do_smlald},
+ { "smlaldx", 0xe7400030, 7, ARM_EXT_V6, do_smlald},
+ { "smlsd", 0xe7000050, 5, ARM_EXT_V6, do_smlad},
+ { "smlsdx", 0xe7000070, 6, ARM_EXT_V6, do_smlad},
+ { "smlsld", 0xe7400050, 6, ARM_EXT_V6, do_smlald},
+ { "smlsldx", 0xe7400070, 7, ARM_EXT_V6, do_smlald},
+ { "smmla", 0xe7500010, 5, ARM_EXT_V6, do_smlad},
+ { "smmlar", 0xe7500030, 6, ARM_EXT_V6, do_smlad},
+ { "smmls", 0xe75000d0, 5, ARM_EXT_V6, do_smlad},
+ { "smmlsr", 0xe75000f0, 6, ARM_EXT_V6, do_smlad},
+ { "smmul", 0xe750f010, 5, ARM_EXT_V6, do_smmul},
+ { "smmulr", 0xe750f030, 6, ARM_EXT_V6, do_smmul},
+ { "smuad", 0xe700f010, 5, ARM_EXT_V6, do_smmul},
+ { "smuadx", 0xe700f030, 6, ARM_EXT_V6, do_smmul},
+ { "smusd", 0xe700f050, 5, ARM_EXT_V6, do_smmul},
+ { "smusdx", 0xe700f070, 6, ARM_EXT_V6, do_smmul},
+ { "srsia", 0xf8cd0500, 0, ARM_EXT_V6, do_srs},
+ { "srsib", 0xf9cd0500, 0, ARM_EXT_V6, do_srs},
+ { "srsda", 0xf84d0500, 0, ARM_EXT_V6, do_srs},
+ { "srsdb", 0xf94d0500, 0, ARM_EXT_V6, do_srs},
+ { "ssat", 0xe6a00010, 4, ARM_EXT_V6, do_ssat},
+ { "ssat16", 0xe6a00f30, 6, ARM_EXT_V6, do_ssat16},
+ { "strex", 0xe1800f90, 5, ARM_EXT_V6, do_strex},
+ { "umaal", 0xe0400090, 5, ARM_EXT_V6, do_umaal},
+ { "usad8", 0xe780f010, 5, ARM_EXT_V6, do_smmul},
+ { "usada8", 0xe7800010, 6, ARM_EXT_V6, do_smlad},
+ { "usat", 0xe6e00010, 4, ARM_EXT_V6, do_usat},
+ { "usat16", 0xe6e00f30, 6, ARM_EXT_V6, do_usat16},
+
+ /* Core FPA instruction set (V1). */
+ {"wfs", 0xee200110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
+ {"rfs", 0xee300110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
+ {"wfc", 0xee400110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
+ {"rfc", 0xee500110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
+
+ {"ldfs", 0xec100100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
+ {"ldfd", 0xec108100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
+ {"ldfe", 0xec500100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
+ {"ldfp", 0xec508100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
+
+ {"stfs", 0xec000100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
+ {"stfd", 0xec008100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
+ {"stfe", 0xec400100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
+ {"stfp", 0xec408100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
+
+ {"mvfs", 0xee008100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mvfsp", 0xee008120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mvfsm", 0xee008140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mvfsz", 0xee008160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mvfd", 0xee008180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mvfdp", 0xee0081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mvfdm", 0xee0081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mvfdz", 0xee0081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mvfe", 0xee088100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mvfep", 0xee088120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mvfem", 0xee088140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mvfez", 0xee088160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+
+ {"mnfs", 0xee108100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mnfsp", 0xee108120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mnfsm", 0xee108140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mnfsz", 0xee108160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mnfd", 0xee108180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mnfdp", 0xee1081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mnfdm", 0xee1081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mnfdz", 0xee1081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mnfe", 0xee188100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mnfep", 0xee188120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mnfem", 0xee188140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"mnfez", 0xee188160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+
+ {"abss", 0xee208100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"abssp", 0xee208120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"abssm", 0xee208140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"abssz", 0xee208160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"absd", 0xee208180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"absdp", 0xee2081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"absdm", 0xee2081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"absdz", 0xee2081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"abse", 0xee288100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"absep", 0xee288120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"absem", 0xee288140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"absez", 0xee288160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+
+ {"rnds", 0xee308100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"rndsp", 0xee308120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"rndsm", 0xee308140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"rndsz", 0xee308160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"rndd", 0xee308180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"rnddp", 0xee3081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"rnddm", 0xee3081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"rnddz", 0xee3081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"rnde", 0xee388100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"rndep", 0xee388120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"rndem", 0xee388140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"rndez", 0xee388160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+
+ {"sqts", 0xee408100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sqtsp", 0xee408120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sqtsm", 0xee408140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sqtsz", 0xee408160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sqtd", 0xee408180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sqtdp", 0xee4081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sqtdm", 0xee4081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sqtdz", 0xee4081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sqte", 0xee488100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sqtep", 0xee488120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sqtem", 0xee488140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sqtez", 0xee488160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+
+ {"logs", 0xee508100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"logsp", 0xee508120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"logsm", 0xee508140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"logsz", 0xee508160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"logd", 0xee508180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"logdp", 0xee5081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"logdm", 0xee5081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"logdz", 0xee5081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"loge", 0xee588100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"logep", 0xee588120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"logem", 0xee588140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"logez", 0xee588160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+
+ {"lgns", 0xee608100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"lgnsp", 0xee608120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"lgnsm", 0xee608140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"lgnsz", 0xee608160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"lgnd", 0xee608180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"lgndp", 0xee6081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"lgndm", 0xee6081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"lgndz", 0xee6081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"lgne", 0xee688100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"lgnep", 0xee688120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"lgnem", 0xee688140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"lgnez", 0xee688160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+
+ {"exps", 0xee708100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"expsp", 0xee708120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"expsm", 0xee708140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"expsz", 0xee708160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"expd", 0xee708180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"expdp", 0xee7081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"expdm", 0xee7081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"expdz", 0xee7081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"expe", 0xee788100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"expep", 0xee788120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"expem", 0xee788140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"expdz", 0xee788160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+
+ {"sins", 0xee808100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sinsp", 0xee808120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sinsm", 0xee808140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sinsz", 0xee808160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sind", 0xee808180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sindp", 0xee8081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sindm", 0xee8081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sindz", 0xee8081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sine", 0xee888100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sinep", 0xee888120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sinem", 0xee888140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"sinez", 0xee888160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+
+ {"coss", 0xee908100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"cossp", 0xee908120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"cossm", 0xee908140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"cossz", 0xee908160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"cosd", 0xee908180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"cosdp", 0xee9081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"cosdm", 0xee9081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"cosdz", 0xee9081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"cose", 0xee988100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"cosep", 0xee988120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"cosem", 0xee988140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"cosez", 0xee988160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+
+ {"tans", 0xeea08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"tansp", 0xeea08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"tansm", 0xeea08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"tansz", 0xeea08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"tand", 0xeea08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"tandp", 0xeea081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"tandm", 0xeea081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"tandz", 0xeea081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"tane", 0xeea88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"tanep", 0xeea88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"tanem", 0xeea88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"tanez", 0xeea88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+
+ {"asns", 0xeeb08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"asnsp", 0xeeb08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"asnsm", 0xeeb08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"asnsz", 0xeeb08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"asnd", 0xeeb08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"asndp", 0xeeb081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"asndm", 0xeeb081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"asndz", 0xeeb081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"asne", 0xeeb88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"asnep", 0xeeb88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"asnem", 0xeeb88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"asnez", 0xeeb88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+
+ {"acss", 0xeec08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"acssp", 0xeec08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"acssm", 0xeec08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"acssz", 0xeec08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"acsd", 0xeec08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"acsdp", 0xeec081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"acsdm", 0xeec081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"acsdz", 0xeec081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"acse", 0xeec88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"acsep", 0xeec88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"acsem", 0xeec88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"acsez", 0xeec88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+
+ {"atns", 0xeed08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"atnsp", 0xeed08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"atnsm", 0xeed08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"atnsz", 0xeed08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"atnd", 0xeed08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"atndp", 0xeed081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"atndm", 0xeed081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"atndz", 0xeed081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"atne", 0xeed88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"atnep", 0xeed88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"atnem", 0xeed88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"atnez", 0xeed88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+
+ {"urds", 0xeee08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"urdsp", 0xeee08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"urdsm", 0xeee08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"urdsz", 0xeee08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"urdd", 0xeee08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"urddp", 0xeee081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"urddm", 0xeee081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"urddz", 0xeee081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"urde", 0xeee88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"urdep", 0xeee88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"urdem", 0xeee88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"urdez", 0xeee88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+
+ {"nrms", 0xeef08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"nrmsp", 0xeef08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"nrmsm", 0xeef08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"nrmsz", 0xeef08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"nrmd", 0xeef08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"nrmdp", 0xeef081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"nrmdm", 0xeef081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"nrmdz", 0xeef081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"nrme", 0xeef88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"nrmep", 0xeef88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"nrmem", 0xeef88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+ {"nrmez", 0xeef88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
+
+ {"adfs", 0xee000100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"adfsp", 0xee000120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"adfsm", 0xee000140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"adfsz", 0xee000160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"adfd", 0xee000180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"adfdp", 0xee0001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"adfdm", 0xee0001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"adfdz", 0xee0001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"adfe", 0xee080100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"adfep", 0xee080120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"adfem", 0xee080140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"adfez", 0xee080160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+
+ {"sufs", 0xee200100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"sufsp", 0xee200120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"sufsm", 0xee200140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"sufsz", 0xee200160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"sufd", 0xee200180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"sufdp", 0xee2001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"sufdm", 0xee2001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"sufdz", 0xee2001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"sufe", 0xee280100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"sufep", 0xee280120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"sufem", 0xee280140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"sufez", 0xee280160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+
+ {"rsfs", 0xee300100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rsfsp", 0xee300120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rsfsm", 0xee300140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rsfsz", 0xee300160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rsfd", 0xee300180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rsfdp", 0xee3001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rsfdm", 0xee3001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rsfdz", 0xee3001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rsfe", 0xee380100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rsfep", 0xee380120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rsfem", 0xee380140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rsfez", 0xee380160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+
+ {"mufs", 0xee100100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"mufsp", 0xee100120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"mufsm", 0xee100140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"mufsz", 0xee100160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"mufd", 0xee100180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"mufdp", 0xee1001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"mufdm", 0xee1001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"mufdz", 0xee1001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"mufe", 0xee180100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"mufep", 0xee180120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"mufem", 0xee180140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"mufez", 0xee180160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+
+ {"dvfs", 0xee400100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"dvfsp", 0xee400120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"dvfsm", 0xee400140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"dvfsz", 0xee400160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"dvfd", 0xee400180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"dvfdp", 0xee4001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"dvfdm", 0xee4001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"dvfdz", 0xee4001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"dvfe", 0xee480100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"dvfep", 0xee480120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"dvfem", 0xee480140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"dvfez", 0xee480160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+
+ {"rdfs", 0xee500100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rdfsp", 0xee500120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rdfsm", 0xee500140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rdfsz", 0xee500160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rdfd", 0xee500180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rdfdp", 0xee5001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rdfdm", 0xee5001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rdfdz", 0xee5001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rdfe", 0xee580100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rdfep", 0xee580120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rdfem", 0xee580140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rdfez", 0xee580160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+
+ {"pows", 0xee600100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"powsp", 0xee600120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"powsm", 0xee600140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"powsz", 0xee600160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"powd", 0xee600180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"powdp", 0xee6001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"powdm", 0xee6001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"powdz", 0xee6001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"powe", 0xee680100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"powep", 0xee680120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"powem", 0xee680140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"powez", 0xee680160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+
+ {"rpws", 0xee700100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rpwsp", 0xee700120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rpwsm", 0xee700140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rpwsz", 0xee700160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rpwd", 0xee700180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rpwdp", 0xee7001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rpwdm", 0xee7001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rpwdz", 0xee7001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rpwe", 0xee780100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rpwep", 0xee780120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rpwem", 0xee780140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rpwez", 0xee780160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+
+ {"rmfs", 0xee800100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rmfsp", 0xee800120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rmfsm", 0xee800140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rmfsz", 0xee800160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rmfd", 0xee800180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rmfdp", 0xee8001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rmfdm", 0xee8001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rmfdz", 0xee8001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rmfe", 0xee880100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rmfep", 0xee880120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rmfem", 0xee880140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"rmfez", 0xee880160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+
+ {"fmls", 0xee900100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fmlsp", 0xee900120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fmlsm", 0xee900140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fmlsz", 0xee900160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fmld", 0xee900180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fmldp", 0xee9001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fmldm", 0xee9001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fmldz", 0xee9001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fmle", 0xee980100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fmlep", 0xee980120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fmlem", 0xee980140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fmlez", 0xee980160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+
+ {"fdvs", 0xeea00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fdvsp", 0xeea00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fdvsm", 0xeea00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fdvsz", 0xeea00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fdvd", 0xeea00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fdvdp", 0xeea001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fdvdm", 0xeea001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fdvdz", 0xeea001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fdve", 0xeea80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fdvep", 0xeea80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fdvem", 0xeea80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"fdvez", 0xeea80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+
+ {"frds", 0xeeb00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"frdsp", 0xeeb00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"frdsm", 0xeeb00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"frdsz", 0xeeb00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"frdd", 0xeeb00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"frddp", 0xeeb001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"frddm", 0xeeb001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"frddz", 0xeeb001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"frde", 0xeeb80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"frdep", 0xeeb80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"frdem", 0xeeb80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"frdez", 0xeeb80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+
+ {"pols", 0xeec00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"polsp", 0xeec00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"polsm", 0xeec00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"polsz", 0xeec00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"pold", 0xeec00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"poldp", 0xeec001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"poldm", 0xeec001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"poldz", 0xeec001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"pole", 0xeec80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"polep", 0xeec80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"polem", 0xeec80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+ {"polez", 0xeec80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
+
+ {"cmf", 0xee90f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
+ {"cmfe", 0xeed0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
+ {"cnf", 0xeeb0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
+ {"cnfe", 0xeef0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
+ /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
+ not be an optional suffix, but part of the instruction. To be
+ compatible, we accept either. */
+ {"cmfe", 0xeed0f110, 4, FPU_FPA_EXT_V1, do_fpa_cmp},
+ {"cnfe", 0xeef0f110, 4, FPU_FPA_EXT_V1, do_fpa_cmp},
+
+ {"flts", 0xee000110, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
+ {"fltsp", 0xee000130, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
+ {"fltsm", 0xee000150, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
+ {"fltsz", 0xee000170, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
+ {"fltd", 0xee000190, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
+ {"fltdp", 0xee0001b0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
+ {"fltdm", 0xee0001d0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
+ {"fltdz", 0xee0001f0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
+ {"flte", 0xee080110, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
+ {"fltep", 0xee080130, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
+ {"fltem", 0xee080150, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
+ {"fltez", 0xee080170, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
+
+ /* The implementation of the FIX instruction is broken on some
+ assemblers, in that it accepts a precision specifier as well as a
+ rounding specifier, despite the fact that this is meaningless.
+ To be more compatible, we accept it as well, though of course it
+ does not set any bits. */
+ {"fix", 0xee100110, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
+ {"fixp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
+ {"fixm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
+ {"fixz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
+ {"fixsp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
+ {"fixsm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
+ {"fixsz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
+ {"fixdp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
+ {"fixdm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
+ {"fixdz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
+ {"fixep", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
+ {"fixem", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
+ {"fixez", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
+
+ /* Instructions that were new with the real FPA, call them V2. */
+ {"lfm", 0xec100200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
+ {"lfmfd", 0xec900200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
+ {"lfmea", 0xed100200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
+ {"sfm", 0xec000200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
+ {"sfmfd", 0xed000200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
+ {"sfmea", 0xec800200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
+
+ /* VFP V1xD (single precision). */
+ /* Moves and type conversions. */
+ {"fcpys", 0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
+ {"fmrs", 0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
+ {"fmsr", 0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
+ {"fmstat", 0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
+ {"fsitos", 0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
+ {"fuitos", 0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
+ {"ftosis", 0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
+ {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
+ {"ftouis", 0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
+ {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
+ {"fmrx", 0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
+ {"fmxr", 0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
+
+ /* Memory operations. */
+ {"flds", 0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
+ {"fsts", 0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
+ {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
+ {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
+ {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
+ {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
+ {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
+ {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
+ {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
+ {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
+ {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
+ {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
+ {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
+ {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
+ {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
+ {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
+ {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
+ {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
+
+ /* Monadic operations. */
+ {"fabss", 0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
+ {"fnegs", 0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
+ {"fsqrts", 0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
+
+ /* Dyadic operations. */
+ {"fadds", 0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
+ {"fsubs", 0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
+ {"fmuls", 0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
+ {"fdivs", 0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
+ {"fmacs", 0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
+ {"fmscs", 0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
+ {"fnmuls", 0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
+ {"fnmacs", 0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
+ {"fnmscs", 0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
+
+ /* Comparisons. */
+ {"fcmps", 0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
+ {"fcmpzs", 0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
+ {"fcmpes", 0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
+ {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
+
+ /* VFP V1 (Double precision). */
+ /* Moves and type conversions. */
+ {"fcpyd", 0xeeb00b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
+ {"fcvtds", 0xeeb70ac0, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
+ {"fcvtsd", 0xeeb70bc0, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
+ {"fmdhr", 0xee200b10, 5, FPU_VFP_EXT_V1, do_vfp_dp_from_reg},
+ {"fmdlr", 0xee000b10, 5, FPU_VFP_EXT_V1, do_vfp_dp_from_reg},
+ {"fmrdh", 0xee300b10, 5, FPU_VFP_EXT_V1, do_vfp_reg_from_dp},
+ {"fmrdl", 0xee100b10, 5, FPU_VFP_EXT_V1, do_vfp_reg_from_dp},
+ {"fsitod", 0xeeb80bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
+ {"fuitod", 0xeeb80b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
+ {"ftosid", 0xeebd0b40, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
+ {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
+ {"ftouid", 0xeebc0b40, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
+ {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
+
+ /* Memory operations. */
+ {"fldd", 0xed100b00, 4, FPU_VFP_EXT_V1, do_vfp_dp_ldst},
+ {"fstd", 0xed000b00, 4, FPU_VFP_EXT_V1, do_vfp_dp_ldst},
+ {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
+ {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
+ {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
+ {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
+ {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
+ {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
+ {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
+ {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
+
+ /* Monadic operations. */
+ {"fabsd", 0xeeb00bc0, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
+ {"fnegd", 0xeeb10b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
+ {"fsqrtd", 0xeeb10bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
+
+ /* Dyadic operations. */
+ {"faddd", 0xee300b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
+ {"fsubd", 0xee300b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
+ {"fmuld", 0xee200b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
+ {"fdivd", 0xee800b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
+ {"fmacd", 0xee000b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
+ {"fmscd", 0xee100b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
+ {"fnmuld", 0xee200b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
+ {"fnmacd", 0xee000b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
+ {"fnmscd", 0xee100b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
+
+ /* Comparisons. */
+ {"fcmpd", 0xeeb40b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
+ {"fcmpzd", 0xeeb50b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_compare_z},
+ {"fcmped", 0xeeb40bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
+ {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1, do_vfp_dp_compare_z},
+
+ /* VFP V2. */
+ {"fmsrr", 0xec400a10, 5, FPU_VFP_EXT_V2, do_vfp_sp2_from_reg2},
+ {"fmrrs", 0xec500a10, 5, FPU_VFP_EXT_V2, do_vfp_reg2_from_sp2},
+ {"fmdrr", 0xec400b10, 5, FPU_VFP_EXT_V2, do_vfp_dp_from_reg2},
+ {"fmrrd", 0xec500b10, 5, FPU_VFP_EXT_V2, do_vfp_reg2_from_dp},
+
+ /* Intel XScale extensions to ARM V5 ISA. (All use CP0). */
+ {"mia", 0xee200010, 3, ARM_CEXT_XSCALE, do_xsc_mia},
+ {"miaph", 0xee280010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
+ {"miabb", 0xee2c0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
+ {"miabt", 0xee2d0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
+ {"miatb", 0xee2e0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
+ {"miatt", 0xee2f0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
+ {"mar", 0xec400000, 3, ARM_CEXT_XSCALE, do_xsc_mar},
+ {"mra", 0xec500000, 3, ARM_CEXT_XSCALE, do_xsc_mra},
+
+ /* Intel Wireless MMX technology instructions. */
+ {"tandcb", 0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
+ {"tandch", 0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
+ {"tandcw", 0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
+ {"tbcstb", 0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
+ {"tbcsth", 0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
+ {"tbcstw", 0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
+ {"textrcb", 0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
+ {"textrch", 0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
+ {"textrcw", 0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
+ {"textrmub", 0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
+ {"textrmuh", 0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
+ {"textrmuw", 0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
+ {"textrmsb", 0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
+ {"textrmsh", 0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
+ {"textrmsw", 0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
+ {"tinsrb", 0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
+ {"tinsrh", 0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
+ {"tinsrw", 0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
+ {"tmcr", 0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
+ {"tmcrr", 0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
+ {"tmia", 0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
+ {"tmiaph", 0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
+ {"tmiabb", 0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
+ {"tmiabt", 0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
+ {"tmiatb", 0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
+ {"tmiatt", 0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
+ {"tmovmskb", 0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
+ {"tmovmskh", 0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
+ {"tmovmskw", 0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
+ {"tmrc", 0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
+ {"tmrrc", 0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
+ {"torcb", 0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
+ {"torch", 0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
+ {"torcw", 0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
+ {"waccb", 0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wacch", 0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"waccw", 0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"waddbss", 0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waddb", 0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waddbus", 0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waddhss", 0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waddh", 0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waddhus", 0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waddwss", 0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waddw", 0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waddwus", 0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waligni", 0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
+ {"walignr0", 0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"walignr1", 0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"walignr2", 0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"walignr3", 0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wand", 0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wandn", 0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wavg2b", 0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wavg2br", 0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wavg2h", 0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wavg2hr", 0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpeqb", 0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpeqh", 0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpeqw", 0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpgtub", 0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpgtuh", 0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpgtuw", 0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpgtsb", 0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpgtsh", 0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpgtsw", 0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wldrb", 0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
+ {"wldrh", 0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
+ {"wldrw", 0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
+ {"wldrd", 0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
+ {"wmacs", 0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmacsz", 0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmacu", 0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmacuz", 0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmadds", 0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmaddu", 0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmaxsb", 0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmaxsh", 0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmaxsw", 0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmaxub", 0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmaxuh", 0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmaxuw", 0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wminsb", 0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wminsh", 0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wminsw", 0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wminub", 0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wminuh", 0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wminuw", 0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmov", 0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
+ {"wmulsm", 0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmulsl", 0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmulum", 0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmulul", 0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wor", 0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wpackhss", 0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wpackhus", 0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wpackwss", 0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wpackwus", 0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wpackdss", 0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wpackdus", 0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wrorh", 0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wrorhg", 0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wrorw", 0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wrorwg", 0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wrord", 0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wrordg", 0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wsadb", 0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsadbz", 0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsadh", 0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsadhz", 0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wshufh", 0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
+ {"wsllh", 0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsllhg", 0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wsllw", 0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsllwg", 0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wslld", 0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wslldg", 0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wsrah", 0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsrahg", 0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wsraw", 0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsrawg", 0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wsrad", 0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsradg", 0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wsrlh", 0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsrlhg", 0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wsrlw", 0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsrlwg", 0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wsrld", 0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsrldg", 0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wstrb", 0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
+ {"wstrh", 0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
+ {"wstrw", 0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
+ {"wstrd", 0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
+ {"wsubbss", 0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsubb", 0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsubbus", 0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsubhss", 0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsubh", 0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsubhus", 0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsubwss", 0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsubw", 0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsubwus", 0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckihb", 0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wunpckihh", 0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wunpckihw", 0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckilb", 0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wunpckilh", 0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wunpckilw", 0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wxor", 0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wzero", 0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
+
+ /* Cirrus Maverick instructions. */
+ {"cfldrs", 0xec100400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_1},
+ {"cfldrd", 0xec500400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_2},
+ {"cfldr32", 0xec100500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_3},
+ {"cfldr64", 0xec500500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_4},
+ {"cfstrs", 0xec000400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_1},
+ {"cfstrd", 0xec400400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_2},
+ {"cfstr32", 0xec000500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_3},
+ {"cfstr64", 0xec400500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_4},
+ {"cfmvsr", 0xee000450, 6, ARM_CEXT_MAVERICK, do_mav_binops_2a},
+ {"cfmvrs", 0xee100450, 6, ARM_CEXT_MAVERICK, do_mav_binops_1a},
+ {"cfmvdlr", 0xee000410, 7, ARM_CEXT_MAVERICK, do_mav_binops_2b},
+ {"cfmvrdl", 0xee100410, 7, ARM_CEXT_MAVERICK, do_mav_binops_1b},
+ {"cfmvdhr", 0xee000430, 7, ARM_CEXT_MAVERICK, do_mav_binops_2b},
+ {"cfmvrdh", 0xee100430, 7, ARM_CEXT_MAVERICK, do_mav_binops_1b},
+ {"cfmv64lr", 0xee000510, 8, ARM_CEXT_MAVERICK, do_mav_binops_2c},
+ {"cfmvr64l", 0xee100510, 8, ARM_CEXT_MAVERICK, do_mav_binops_1c},
+ {"cfmv64hr", 0xee000530, 8, ARM_CEXT_MAVERICK, do_mav_binops_2c},
+ {"cfmvr64h", 0xee100530, 8, ARM_CEXT_MAVERICK, do_mav_binops_1c},
+ {"cfmval32", 0xee200440, 8, ARM_CEXT_MAVERICK, do_mav_binops_3a},
+ {"cfmv32al", 0xee100440, 8, ARM_CEXT_MAVERICK, do_mav_binops_3b},
+ {"cfmvam32", 0xee200460, 8, ARM_CEXT_MAVERICK, do_mav_binops_3a},
+ {"cfmv32am", 0xee100460, 8, ARM_CEXT_MAVERICK, do_mav_binops_3b},
+ {"cfmvah32", 0xee200480, 8, ARM_CEXT_MAVERICK, do_mav_binops_3a},
+ {"cfmv32ah", 0xee100480, 8, ARM_CEXT_MAVERICK, do_mav_binops_3b},
+ {"cfmva32", 0xee2004a0, 7, ARM_CEXT_MAVERICK, do_mav_binops_3a},
+ {"cfmv32a", 0xee1004a0, 7, ARM_CEXT_MAVERICK, do_mav_binops_3b},
+ {"cfmva64", 0xee2004c0, 7, ARM_CEXT_MAVERICK, do_mav_binops_3c},
+ {"cfmv64a", 0xee1004c0, 7, ARM_CEXT_MAVERICK, do_mav_binops_3d},
+ {"cfmvsc32", 0xee2004e0, 8, ARM_CEXT_MAVERICK, do_mav_dspsc_1},
+ {"cfmv32sc", 0xee1004e0, 8, ARM_CEXT_MAVERICK, do_mav_dspsc_2},
+ {"cfcpys", 0xee000400, 6, ARM_CEXT_MAVERICK, do_mav_binops_1d},
+ {"cfcpyd", 0xee000420, 6, ARM_CEXT_MAVERICK, do_mav_binops_1e},
+ {"cfcvtsd", 0xee000460, 7, ARM_CEXT_MAVERICK, do_mav_binops_1f},
+ {"cfcvtds", 0xee000440, 7, ARM_CEXT_MAVERICK, do_mav_binops_1g},
+ {"cfcvt32s", 0xee000480, 8, ARM_CEXT_MAVERICK, do_mav_binops_1h},
+ {"cfcvt32d", 0xee0004a0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1i},
+ {"cfcvt64s", 0xee0004c0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1j},
+ {"cfcvt64d", 0xee0004e0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1k},
+ {"cfcvts32", 0xee100580, 8, ARM_CEXT_MAVERICK, do_mav_binops_1l},
+ {"cfcvtd32", 0xee1005a0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1m},
+ {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
+ {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
+ {"cfrshl32", 0xee000550, 8, ARM_CEXT_MAVERICK, do_mav_triple_4a},
+ {"cfrshl64", 0xee000570, 8, ARM_CEXT_MAVERICK, do_mav_triple_4b},
+ {"cfsh32", 0xee000500, 6, ARM_CEXT_MAVERICK, do_mav_shift_1},
+ {"cfsh64", 0xee200500, 6, ARM_CEXT_MAVERICK, do_mav_shift_2},
+ {"cfcmps", 0xee100490, 6, ARM_CEXT_MAVERICK, do_mav_triple_5a},
+ {"cfcmpd", 0xee1004b0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5b},
+ {"cfcmp32", 0xee100590, 7, ARM_CEXT_MAVERICK, do_mav_triple_5c},
+ {"cfcmp64", 0xee1005b0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5d},
+ {"cfabss", 0xee300400, 6, ARM_CEXT_MAVERICK, do_mav_binops_1d},
+ {"cfabsd", 0xee300420, 6, ARM_CEXT_MAVERICK, do_mav_binops_1e},
+ {"cfnegs", 0xee300440, 6, ARM_CEXT_MAVERICK, do_mav_binops_1d},
+ {"cfnegd", 0xee300460, 6, ARM_CEXT_MAVERICK, do_mav_binops_1e},
+ {"cfadds", 0xee300480, 6, ARM_CEXT_MAVERICK, do_mav_triple_5e},
+ {"cfaddd", 0xee3004a0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5f},
+ {"cfsubs", 0xee3004c0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5e},
+ {"cfsubd", 0xee3004e0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5f},
+ {"cfmuls", 0xee100400, 6, ARM_CEXT_MAVERICK, do_mav_triple_5e},
+ {"cfmuld", 0xee100420, 6, ARM_CEXT_MAVERICK, do_mav_triple_5f},
+ {"cfabs32", 0xee300500, 7, ARM_CEXT_MAVERICK, do_mav_binops_1n},
+ {"cfabs64", 0xee300520, 7, ARM_CEXT_MAVERICK, do_mav_binops_1o},
+ {"cfneg32", 0xee300540, 7, ARM_CEXT_MAVERICK, do_mav_binops_1n},
+ {"cfneg64", 0xee300560, 7, ARM_CEXT_MAVERICK, do_mav_binops_1o},
+ {"cfadd32", 0xee300580, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
+ {"cfadd64", 0xee3005a0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5h},
+ {"cfsub32", 0xee3005c0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
+ {"cfsub64", 0xee3005e0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5h},
+ {"cfmul32", 0xee100500, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
+ {"cfmul64", 0xee100520, 7, ARM_CEXT_MAVERICK, do_mav_triple_5h},
+ {"cfmac32", 0xee100540, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
+ {"cfmsc32", 0xee100560, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
+ {"cfmadd32", 0xee000600, 8, ARM_CEXT_MAVERICK, do_mav_quad_6a},
+ {"cfmsub32", 0xee100600, 8, ARM_CEXT_MAVERICK, do_mav_quad_6a},
+ {"cfmadda32", 0xee200600, 9, ARM_CEXT_MAVERICK, do_mav_quad_6b},
+ {"cfmsuba32", 0xee300600, 9, ARM_CEXT_MAVERICK, do_mav_quad_6b},
+};
+
+/* Defines for various bits that we will want to toggle. */
+#define INST_IMMEDIATE 0x02000000
+#define OFFSET_REG 0x02000000
+#define HWOFFSET_IMM 0x00400000
+#define SHIFT_BY_REG 0x00000010
+#define PRE_INDEX 0x01000000
+#define INDEX_UP 0x00800000
+#define WRITE_BACK 0x00200000
+#define LDM_TYPE_2_OR_3 0x00400000
+
+#define LITERAL_MASK 0xf000f000
+#define OPCODE_MASK 0xfe1fffff
+#define V4_STR_BIT 0x00000020
+
+#define DATA_OP_SHIFT 21
+
+/* Codes to distinguish the arithmetic instructions. */
+#define OPCODE_AND 0
+#define OPCODE_EOR 1
+#define OPCODE_SUB 2
+#define OPCODE_RSB 3
+#define OPCODE_ADD 4
+#define OPCODE_ADC 5
+#define OPCODE_SBC 6
+#define OPCODE_RSC 7
+#define OPCODE_TST 8
+#define OPCODE_TEQ 9
+#define OPCODE_CMP 10
+#define OPCODE_CMN 11
+#define OPCODE_ORR 12
+#define OPCODE_MOV 13
+#define OPCODE_BIC 14
+#define OPCODE_MVN 15
+
+/* Thumb v1 (ARMv4T). */
+static void do_t_nop PARAMS ((char *));
+static void do_t_arit PARAMS ((char *));
+static void do_t_add PARAMS ((char *));
+static void do_t_asr PARAMS ((char *));
+static void do_t_branch9 PARAMS ((char *));
+static void do_t_branch12 PARAMS ((char *));
+static void do_t_branch23 PARAMS ((char *));
+static void do_t_bx PARAMS ((char *));
+static void do_t_compare PARAMS ((char *));
+static void do_t_ldmstm PARAMS ((char *));
+static void do_t_ldr PARAMS ((char *));
+static void do_t_ldrb PARAMS ((char *));
+static void do_t_ldrh PARAMS ((char *));
+static void do_t_lds PARAMS ((char *));
+static void do_t_lsl PARAMS ((char *));
+static void do_t_lsr PARAMS ((char *));
+static void do_t_mov PARAMS ((char *));
+static void do_t_push_pop PARAMS ((char *));
+static void do_t_str PARAMS ((char *));
+static void do_t_strb PARAMS ((char *));
+static void do_t_strh PARAMS ((char *));
+static void do_t_sub PARAMS ((char *));
+static void do_t_swi PARAMS ((char *));
+static void do_t_adr PARAMS ((char *));
+
+/* Thumb v2 (ARMv5T). */
+static void do_t_blx PARAMS ((char *));
+static void do_t_bkpt PARAMS ((char *));
+
+/* ARM V6. */
+static void do_t_cps PARAMS ((char *));
+static void do_t_cpy PARAMS ((char *));
+static void do_t_setend PARAMS ((char *));;
+
+#define T_OPCODE_MUL 0x4340
+#define T_OPCODE_TST 0x4200
+#define T_OPCODE_CMN 0x42c0
+#define T_OPCODE_NEG 0x4240
+#define T_OPCODE_MVN 0x43c0
+
+#define T_OPCODE_ADD_R3 0x1800
+#define T_OPCODE_SUB_R3 0x1a00
+#define T_OPCODE_ADD_HI 0x4400
+#define T_OPCODE_ADD_ST 0xb000
+#define T_OPCODE_SUB_ST 0xb080
+#define T_OPCODE_ADD_SP 0xa800
+#define T_OPCODE_ADD_PC 0xa000
+#define T_OPCODE_ADD_I8 0x3000
+#define T_OPCODE_SUB_I8 0x3800
+#define T_OPCODE_ADD_I3 0x1c00
+#define T_OPCODE_SUB_I3 0x1e00
+
+#define T_OPCODE_ASR_R 0x4100
+#define T_OPCODE_LSL_R 0x4080
+#define T_OPCODE_LSR_R 0x40c0
+#define T_OPCODE_ASR_I 0x1000
+#define T_OPCODE_LSL_I 0x0000
+#define T_OPCODE_LSR_I 0x0800
+
+#define T_OPCODE_MOV_I8 0x2000
+#define T_OPCODE_CMP_I8 0x2800
+#define T_OPCODE_CMP_LR 0x4280
+#define T_OPCODE_MOV_HR 0x4600
+#define T_OPCODE_CMP_HR 0x4500
+
+#define T_OPCODE_LDR_PC 0x4800
+#define T_OPCODE_LDR_SP 0x9800
+#define T_OPCODE_STR_SP 0x9000
+#define T_OPCODE_LDR_IW 0x6800
+#define T_OPCODE_STR_IW 0x6000
+#define T_OPCODE_LDR_IH 0x8800
+#define T_OPCODE_STR_IH 0x8000
+#define T_OPCODE_LDR_IB 0x7800
+#define T_OPCODE_STR_IB 0x7000
+#define T_OPCODE_LDR_RW 0x5800
+#define T_OPCODE_STR_RW 0x5000
+#define T_OPCODE_LDR_RH 0x5a00
+#define T_OPCODE_STR_RH 0x5200
+#define T_OPCODE_LDR_RB 0x5c00
+#define T_OPCODE_STR_RB 0x5400
+
+#define T_OPCODE_PUSH 0xb400
+#define T_OPCODE_POP 0xbc00
+
+#define T_OPCODE_BRANCH 0xe7fe
+
+static int thumb_reg PARAMS ((char ** str, int hi_lo));
+
+#define THUMB_SIZE 2 /* Size of thumb instruction. */
+#define THUMB_REG_LO 0x1
+#define THUMB_REG_HI 0x2
+#define THUMB_REG_ANY 0x3
+
+#define THUMB_H1 0x0080
+#define THUMB_H2 0x0040
+
+#define THUMB_ASR 0
+#define THUMB_LSL 1
+#define THUMB_LSR 2
+
+#define THUMB_MOVE 0
+#define THUMB_COMPARE 1
+#define THUMB_CPY 2
+
+#define THUMB_LOAD 0
+#define THUMB_STORE 1
+
+#define THUMB_PP_PC_LR 0x0100
+
+/* These three are used for immediate shifts, do not alter. */
+#define THUMB_WORD 2
+#define THUMB_HALFWORD 1
+#define THUMB_BYTE 0
+
+struct thumb_opcode
+{
+ /* Basic string to match. */
+ const char * template;
+
+ /* Basic instruction code. */
+ unsigned long value;
+
+ int size;
+
+ /* Which CPU variants this exists for. */
+ unsigned long variant;
+
+ /* Function to call to parse args. */
+ void (* parms) PARAMS ((char *));
+};
+
+static const struct thumb_opcode tinsns[] =
+{
+ /* Thumb v1 (ARMv4T). */
+ {"adc", 0x4140, 2, ARM_EXT_V4T, do_t_arit},
+ {"add", 0x0000, 2, ARM_EXT_V4T, do_t_add},
+ {"and", 0x4000, 2, ARM_EXT_V4T, do_t_arit},
+ {"asr", 0x0000, 2, ARM_EXT_V4T, do_t_asr},
+ {"b", T_OPCODE_BRANCH, 2, ARM_EXT_V4T, do_t_branch12},
+ {"beq", 0xd0fe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"bne", 0xd1fe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"bcs", 0xd2fe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"bhs", 0xd2fe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"bcc", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"bul", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"blo", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"bmi", 0xd4fe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"bpl", 0xd5fe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"bvs", 0xd6fe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"bvc", 0xd7fe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"bhi", 0xd8fe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"bls", 0xd9fe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"bge", 0xdafe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"blt", 0xdbfe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"bgt", 0xdcfe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"ble", 0xddfe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"bal", 0xdefe, 2, ARM_EXT_V4T, do_t_branch9},
+ {"bic", 0x4380, 2, ARM_EXT_V4T, do_t_arit},
+ {"bl", 0xf7fffffe, 4, ARM_EXT_V4T, do_t_branch23},
+ {"bx", 0x4700, 2, ARM_EXT_V4T, do_t_bx},
+ {"cmn", T_OPCODE_CMN, 2, ARM_EXT_V4T, do_t_arit},
+ {"cmp", 0x0000, 2, ARM_EXT_V4T, do_t_compare},
+ {"eor", 0x4040, 2, ARM_EXT_V4T, do_t_arit},
+ {"ldmia", 0xc800, 2, ARM_EXT_V4T, do_t_ldmstm},
+ {"ldr", 0x0000, 2, ARM_EXT_V4T, do_t_ldr},
+ {"ldrb", 0x0000, 2, ARM_EXT_V4T, do_t_ldrb},
+ {"ldrh", 0x0000, 2, ARM_EXT_V4T, do_t_ldrh},
+ {"ldrsb", 0x5600, 2, ARM_EXT_V4T, do_t_lds},
+ {"ldrsh", 0x5e00, 2, ARM_EXT_V4T, do_t_lds},
+ {"ldsb", 0x5600, 2, ARM_EXT_V4T, do_t_lds},
+ {"ldsh", 0x5e00, 2, ARM_EXT_V4T, do_t_lds},
+ {"lsl", 0x0000, 2, ARM_EXT_V4T, do_t_lsl},
+ {"lsr", 0x0000, 2, ARM_EXT_V4T, do_t_lsr},
+ {"mov", 0x0000, 2, ARM_EXT_V4T, do_t_mov},
+ {"mul", T_OPCODE_MUL, 2, ARM_EXT_V4T, do_t_arit},
+ {"mvn", T_OPCODE_MVN, 2, ARM_EXT_V4T, do_t_arit},
+ {"neg", T_OPCODE_NEG, 2, ARM_EXT_V4T, do_t_arit},
+ {"orr", 0x4300, 2, ARM_EXT_V4T, do_t_arit},
+ {"pop", 0xbc00, 2, ARM_EXT_V4T, do_t_push_pop},
+ {"push", 0xb400, 2, ARM_EXT_V4T, do_t_push_pop},
+ {"ror", 0x41c0, 2, ARM_EXT_V4T, do_t_arit},
+ {"sbc", 0x4180, 2, ARM_EXT_V4T, do_t_arit},
+ {"stmia", 0xc000, 2, ARM_EXT_V4T, do_t_ldmstm},
+ {"str", 0x0000, 2, ARM_EXT_V4T, do_t_str},
+ {"strb", 0x0000, 2, ARM_EXT_V4T, do_t_strb},
+ {"strh", 0x0000, 2, ARM_EXT_V4T, do_t_strh},
+ {"swi", 0xdf00, 2, ARM_EXT_V4T, do_t_swi},
+ {"sub", 0x0000, 2, ARM_EXT_V4T, do_t_sub},
+ {"tst", T_OPCODE_TST, 2, ARM_EXT_V4T, do_t_arit},
+ /* Pseudo ops: */
+ {"adr", 0x0000, 2, ARM_EXT_V4T, do_t_adr},
+ {"nop", 0x46C0, 2, ARM_EXT_V4T, do_t_nop}, /* mov r8,r8 */
+ /* Thumb v2 (ARMv5T). */
+ {"blx", 0, 0, ARM_EXT_V5T, do_t_blx},
+ {"bkpt", 0xbe00, 2, ARM_EXT_V5T, do_t_bkpt},
+
+ /* ARM V6. */
+ {"cpsie", 0xb660, 2, ARM_EXT_V6, do_t_cps},
+ {"cpsid", 0xb670, 2, ARM_EXT_V6, do_t_cps},
+ {"cpy", 0x4600, 2, ARM_EXT_V6, do_t_cpy},
+ {"rev", 0xba00, 2, ARM_EXT_V6, do_t_arit},
+ {"rev16", 0xba40, 2, ARM_EXT_V6, do_t_arit},
+ {"revsh", 0xbac0, 2, ARM_EXT_V6, do_t_arit},
+ {"setend", 0xb650, 2, ARM_EXT_V6, do_t_setend},
+ {"sxth", 0xb200, 2, ARM_EXT_V6, do_t_arit},
+ {"sxtb", 0xb240, 2, ARM_EXT_V6, do_t_arit},
+ {"uxth", 0xb280, 2, ARM_EXT_V6, do_t_arit},
+ {"uxtb", 0xb2c0, 2, ARM_EXT_V6, do_t_arit},
+};
+
+#define BAD_ARGS _("bad arguments to instruction")
+#define BAD_PC _("r15 not allowed here")
+#define BAD_COND _("instruction is not conditional")
+#define ERR_NO_ACCUM _("acc0 expected")
+
+static struct hash_control * arm_ops_hsh = NULL;
+static struct hash_control * arm_tops_hsh = NULL;
+static struct hash_control * arm_cond_hsh = NULL;
+static struct hash_control * arm_shift_hsh = NULL;
+static struct hash_control * arm_psr_hsh = NULL;
+
+/* This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+ pseudo-op name without dot
+ function to call to execute this pseudo-op
+ Integer arg to pass to the function. */
+
+static void s_req PARAMS ((int));
+static void s_unreq PARAMS ((int));
+static void s_align PARAMS ((int));
+static void s_bss PARAMS ((int));
+static void s_even PARAMS ((int));
+static void s_ltorg PARAMS ((int));
+static void s_arm PARAMS ((int));
+static void s_thumb PARAMS ((int));
+static void s_code PARAMS ((int));
+static void s_force_thumb PARAMS ((int));
+static void s_thumb_func PARAMS ((int));
+static void s_thumb_set PARAMS ((int));
+#ifdef OBJ_ELF
+static void s_arm_elf_cons PARAMS ((int));
+#endif
+
+static int my_get_expression PARAMS ((expressionS *, char **));
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ /* Never called because '.req' does not start a line. */
+ { "req", s_req, 0 },
+ { "unreq", s_unreq, 0 },
+ { "bss", s_bss, 0 },
+ { "align", s_align, 0 },
+ { "arm", s_arm, 0 },
+ { "thumb", s_thumb, 0 },
+ { "code", s_code, 0 },
+ { "force_thumb", s_force_thumb, 0 },
+ { "thumb_func", s_thumb_func, 0 },
+ { "thumb_set", s_thumb_set, 0 },
+ { "even", s_even, 0 },
+ { "ltorg", s_ltorg, 0 },
+ { "pool", s_ltorg, 0 },
+#ifdef OBJ_ELF
+ { "word", s_arm_elf_cons, 4 },
+ { "long", s_arm_elf_cons, 4 },
+#else
+ { "word", cons, 4},
+#endif
+ { "extend", float_cons, 'x' },
+ { "ldouble", float_cons, 'x' },
+ { "packed", float_cons, 'p' },
+ { 0, 0, 0 }
+};
+
+/* Other internal functions. */
+static int arm_parse_extension PARAMS ((char *, int *));
+static int arm_parse_cpu PARAMS ((char *));
+static int arm_parse_arch PARAMS ((char *));
+static int arm_parse_fpu PARAMS ((char *));
+static int arm_parse_float_abi PARAMS ((char *));
+#if 0 /* Suppressed - for now. */
+#if defined OBJ_COFF || defined OBJ_ELF
+static void arm_add_note PARAMS ((const char *, const char *, unsigned int));
+#endif
+#endif
+
+/* Stuff needed to resolve the label ambiguity
+ As:
+ ...
+ label: <insn>
+ may differ from:
+ ...
+ label:
+ <insn>
+*/
+
+symbolS * last_label_seen;
+static int label_is_thumb_function_name = FALSE;
+
+/* Literal Pool stuff. */
+
+#define MAX_LITERAL_POOL_SIZE 1024
+
+/* Literal pool structure. Held on a per-section
+ and per-sub-section basis. */
+typedef struct literal_pool
+{
+ expressionS literals [MAX_LITERAL_POOL_SIZE];
+ unsigned int next_free_entry;
+ unsigned int id;
+ symbolS * symbol;
+ segT section;
+ subsegT sub_section;
+ struct literal_pool * next;
+} literal_pool;
+
+/* Pointer to a linked list of literal pools. */
+literal_pool * list_of_pools = NULL;
+
+static literal_pool * find_literal_pool PARAMS ((void));
+static literal_pool * find_or_make_literal_pool PARAMS ((void));
+
+static literal_pool *
+find_literal_pool ()
+{
+ literal_pool * pool;
+
+ for (pool = list_of_pools; pool != NULL; pool = pool->next)
+ {
+ if (pool->section == now_seg
+ && pool->sub_section == now_subseg)
+ break;
+ }
+
+ return pool;
+}
+
+static literal_pool *
+find_or_make_literal_pool ()
+{
+ /* Next literal pool ID number. */
+ static unsigned int latest_pool_num = 1;
+ literal_pool * pool;
+
+ pool = find_literal_pool ();
+
+ if (pool == NULL)
+ {
+ /* Create a new pool. */
+ pool = (literal_pool *) xmalloc (sizeof (* pool));
+ if (! pool)
+ return NULL;
+
+ pool->next_free_entry = 0;
+ pool->section = now_seg;
+ pool->sub_section = now_subseg;
+ pool->next = list_of_pools;
+ pool->symbol = NULL;
+
+ /* Add it to the list. */
+ list_of_pools = pool;
+ }
+
+ /* New pools, and emptied pools, will have a NULL symbol. */
+ if (pool->symbol == NULL)
+ {
+ pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
+ (valueT) 0, &zero_address_frag);
+ pool->id = latest_pool_num ++;
+ }
+
+ /* Done. */
+ return pool;
+}
+
+/* Add the literal in the global 'inst'
+ structure to the relevent literal pool. */
+static int
+add_to_lit_pool ()
+{
+ literal_pool * pool;
+ unsigned int entry;
+
+ pool = find_or_make_literal_pool ();
+
+ /* Check if this literal value is already in the pool. */
+ for (entry = 0; entry < pool->next_free_entry; entry ++)
+ {
+ if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
+ && (inst.reloc.exp.X_op == O_constant)
+ && (pool->literals[entry].X_add_number
+ == inst.reloc.exp.X_add_number)
+ && (pool->literals[entry].X_unsigned
+ == inst.reloc.exp.X_unsigned))
+ break;
+
+ if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
+ && (inst.reloc.exp.X_op == O_symbol)
+ && (pool->literals[entry].X_add_number
+ == inst.reloc.exp.X_add_number)
+ && (pool->literals[entry].X_add_symbol
+ == inst.reloc.exp.X_add_symbol)
+ && (pool->literals[entry].X_op_symbol
+ == inst.reloc.exp.X_op_symbol))
+ break;
+ }
+
+ /* Do we need to create a new entry? */
+ if (entry == pool->next_free_entry)
+ {
+ if (entry >= MAX_LITERAL_POOL_SIZE)
+ {
+ inst.error = _("literal pool overflow");
+ return FAIL;
+ }
+
+ pool->literals[entry] = inst.reloc.exp;
+ pool->next_free_entry += 1;
+ }
+
+ inst.reloc.exp.X_op = O_symbol;
+ inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
+ inst.reloc.exp.X_add_symbol = pool->symbol;
+
+ return SUCCESS;
+}
+
+/* Can't use symbol_new here, so have to create a symbol and then at
+ a later date assign it a value. Thats what these functions do. */
+
+static void
+symbol_locate (symbolP, name, segment, valu, frag)
+ symbolS * symbolP;
+ const char * name; /* It is copied, the caller can modify. */
+ segT segment; /* Segment identifier (SEG_<something>). */
+ valueT valu; /* Symbol value. */
+ fragS * frag; /* Associated fragment. */
+{
+ unsigned int name_length;
+ char * preserved_copy_of_name;
+
+ name_length = strlen (name) + 1; /* +1 for \0. */
+ obstack_grow (&notes, name, name_length);
+ preserved_copy_of_name = obstack_finish (&notes);
+#ifdef STRIP_UNDERSCORE
+ if (preserved_copy_of_name[0] == '_')
+ preserved_copy_of_name++;
+#endif
+
+#ifdef tc_canonicalize_symbol_name
+ preserved_copy_of_name =
+ tc_canonicalize_symbol_name (preserved_copy_of_name);
+#endif
+
+ S_SET_NAME (symbolP, preserved_copy_of_name);
+
+ S_SET_SEGMENT (symbolP, segment);
+ S_SET_VALUE (symbolP, valu);
+ symbol_clear_list_pointers (symbolP);
+
+ symbol_set_frag (symbolP, frag);
+
+ /* Link to end of symbol chain. */
+ {
+ extern int symbol_table_frozen;
+ if (symbol_table_frozen)
+ abort ();
+ }
+
+ symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
+
+ obj_symbol_new_hook (symbolP);
+
+#ifdef tc_symbol_new_hook
+ tc_symbol_new_hook (symbolP);
+#endif
+
+#ifdef DEBUG_SYMS
+ verify_symbol_chain (symbol_rootP, symbol_lastP);
+#endif /* DEBUG_SYMS */
+}
+
+/* Check that an immediate is valid.
+ If so, convert it to the right format. */
+
+static unsigned int
+validate_immediate (val)
+ unsigned int val;
+{
+ unsigned int a;
+ unsigned int i;
+
+#define rotate_left(v, n) (v << n | v >> (32 - n))
+
+ for (i = 0; i < 32; i += 2)
+ if ((a = rotate_left (val, i)) <= 0xff)
+ return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
+
+ return FAIL;
+}
+
+/* Check to see if an immediate can be computed as two separate immediate
+ values, added together. We already know that this value cannot be
+ computed by just one ARM instruction. */
+
+static unsigned int
+validate_immediate_twopart (val, highpart)
+ unsigned int val;
+ unsigned int * highpart;
+{
+ unsigned int a;
+ unsigned int i;
+
+ for (i = 0; i < 32; i += 2)
+ if (((a = rotate_left (val, i)) & 0xff) != 0)
+ {
+ if (a & 0xff00)
+ {
+ if (a & ~ 0xffff)
+ continue;
+ * highpart = (a >> 8) | ((i + 24) << 7);
+ }
+ else if (a & 0xff0000)
+ {
+ if (a & 0xff000000)
+ continue;
+ * highpart = (a >> 16) | ((i + 16) << 7);
+ }
+ else
+ {
+ assert (a & 0xff000000);
+ * highpart = (a >> 24) | ((i + 8) << 7);
+ }
+
+ return (a & 0xff) | (i << 7);
+ }
+
+ return FAIL;
+}
+
+static int
+validate_offset_imm (val, hwse)
+ unsigned int val;
+ int hwse;
+{
+ if ((hwse && val > 255) || val > 4095)
+ return FAIL;
+ return val;
+}
+
+
+#ifdef OBJ_ELF
+/* This code is to handle mapping symbols as defined in the ARM ELF spec.
+ (This text is taken from version B-02 of the spec):
+
+ 4.4.7 Mapping and tagging symbols
+
+ A section of an ARM ELF file can contain a mixture of ARM code,
+ Thumb code, and data. There are inline transitions between code
+ and data at literal pool boundaries. There can also be inline
+ transitions between ARM code and Thumb code, for example in
+ ARM-Thumb inter-working veneers. Linkers, machine-level
+ debuggers, profiling tools, and disassembly tools need to map
+ images accurately. For example, setting an ARM breakpoint on a
+ Thumb location, or in a literal pool, can crash the program
+ being debugged, ruining the debugging session.
+
+ ARM ELF entities are mapped (see section 4.4.7.1 below) and
+ tagged (see section 4.4.7.2 below) using local symbols (with
+ binding STB_LOCAL). To assist consumers, mapping and tagging
+ symbols should be collated first in the symbol table, before
+ other symbols with binding STB_LOCAL.
+
+ To allow properly collated mapping and tagging symbols to be
+ skipped by consumers that have no interest in them, the first
+ such symbol should have the name $m and its st_value field equal
+ to the total number of mapping and tagging symbols (including
+ the $m) in the symbol table.
+
+ 4.4.7.1 Mapping symbols
+
+ $a Labels the first byte of a sequence of ARM instructions.
+ Its type is STT_FUNC.
+
+ $d Labels the first byte of a sequence of data items.
+ Its type is STT_OBJECT.
+
+ $t Labels the first byte of a sequence of Thumb instructions.
+ Its type is STT_FUNC.
+
+ This list of mapping symbols may be extended in the future.
+
+ Section-relative mapping symbols
+
+ Mapping symbols defined in a section define a sequence of
+ half-open address intervals that cover the address range of the
+ section. Each interval starts at the address defined by a
+ mapping symbol, and continues up to, but not including, the
+ address defined by the next (in address order) mapping symbol or
+ the end of the section. A corollary is that there must be a
+ mapping symbol defined at the beginning of each section.
+ Consumers can ignore the size of a section-relative mapping
+ symbol. Producers can set it to 0.
+
+ Absolute mapping symbols
+
+ Because of the need to crystallize a Thumb address with the
+ Thumb-bit set, absolute symbol of type STT_FUNC (symbols of type
+ STT_FUNC defined in section SHN_ABS) need to be mapped with $a
+ or $t.
+
+ The extent of a mapping symbol defined in SHN_ABS is [st_value,
+ st_value + st_size), or [st_value, st_value + 1) if st_size = 0,
+ where [x, y) denotes the half-open address range from x,
+ inclusive, to y, exclusive.
+
+ In the absence of a mapping symbol, a consumer can interpret a
+ function symbol with an odd value as the Thumb code address
+ obtained by clearing the least significant bit of the
+ value. This interpretation is deprecated, and it may not work in
+ the future.
+
+ Note - the Tagging symbols ($b, $f, $p $m) have been dropped from
+ the EABI (which is still under development), so they are not
+ implemented here. */
+
+static enum mstate mapstate = MAP_UNDEFINED;
+
+static void
+mapping_state (enum mstate state)
+{
+ symbolS * symbolP;
+ const char * symname;
+ int type;
+
+ if (mapstate == state)
+ /* The mapping symbol has already been emitted.
+ There is nothing else to do. */
+ return;
+
+ mapstate = state;
+
+ switch (state)
+ {
+ case MAP_DATA:
+ symname = "$d";
+ type = BSF_OBJECT;
+ break;
+ case MAP_ARM:
+ symname = "$a";
+ type = BSF_FUNCTION;
+ break;
+ case MAP_THUMB:
+ symname = "$t";
+ type = BSF_FUNCTION;
+ break;
+ case MAP_UNDEFINED:
+ return;
+ default:
+ abort ();
+ }
+
+ seg_info (now_seg)->tc_segment_info_data = state;
+
+ symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
+ symbol_table_insert (symbolP);
+ symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
+
+ switch (state)
+ {
+ case MAP_ARM:
+ THUMB_SET_FUNC (symbolP, 0);
+ ARM_SET_THUMB (symbolP, 0);
+ ARM_SET_INTERWORK (symbolP, support_interwork);
+ break;
+
+ case MAP_THUMB:
+ THUMB_SET_FUNC (symbolP, 1);
+ ARM_SET_THUMB (symbolP, 1);
+ ARM_SET_INTERWORK (symbolP, support_interwork);
+ break;
+
+ case MAP_DATA:
+ default:
+ return;
+ }
+}
+
+/* When we change sections we need to issue a new mapping symbol. */
+
+void
+arm_elf_change_section (void)
+{
+ flagword flags;
+
+ if (!SEG_NORMAL (now_seg))
+ return;
+
+ flags = bfd_get_section_flags (stdoutput, now_seg);
+
+ /* We can ignore sections that only contain debug info. */
+ if ((flags & SEC_ALLOC) == 0)
+ return;
+
+ mapstate = seg_info (now_seg)->tc_segment_info_data;
+}
+#else
+#define mapping_state(a)
+#endif /* OBJ_ELF */
+
+
+static void
+s_req (a)
+ int a ATTRIBUTE_UNUSED;
+{
+ as_bad (_("invalid syntax for .req directive"));
+}
+
+/* The .unreq directive deletes an alias which was previously defined
+ by .req. For example:
+
+ my_alias .req r11
+ .unreq my_alias */
+
+static void
+s_unreq (int a ATTRIBUTE_UNUSED)
+{
+ char *name;
+ char saved_char;
+
+ skip_whitespace (input_line_pointer);
+ name = input_line_pointer;
+
+ while (*input_line_pointer != 0
+ && *input_line_pointer != ' '
+ && *input_line_pointer != '\n')
+ ++input_line_pointer;
+
+ saved_char = *input_line_pointer;
+ *input_line_pointer = 0;
+
+ if (*name)
+ {
+ enum arm_reg_type req_type = arm_reg_parse_any (name);
+
+ if (req_type != REG_TYPE_MAX)
+ {
+ char *temp_name = name;
+ int req_no = arm_reg_parse (&temp_name, all_reg_maps[req_type].htab);
+
+ if (req_no != FAIL)
+ {
+ struct reg_entry *req_entry;
+
+ /* Check to see if this alias is a builtin one. */
+ req_entry = hash_delete (all_reg_maps[req_type].htab, name);
+
+ if (!req_entry)
+ as_bad (_("unreq: missing hash entry for \"%s\""), name);
+ else if (req_entry->builtin)
+ /* FIXME: We are deleting a built in register alias which
+ points to a const data structure, so we only need to
+ free up the memory used by the key in the hash table.
+ Unfortunately we have not recorded this value, so this
+ is a memory leak. */
+ /* FIXME: Should we issue a warning message ? */
+ ;
+ else
+ {
+ /* Deleting a user defined alias. We need to free the
+ key and the value, but fortunately the key is the same
+ as the value->name field. */
+ free ((char *) req_entry->name);
+ free (req_entry);
+ }
+ }
+ else
+ as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
+ }
+ else
+ as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
+ }
+ else
+ as_bad (_("invalid syntax for .unreq directive"));
+
+ *input_line_pointer = saved_char;
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_bss (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ /* We don't support putting frags in the BSS segment, we fake it by
+ marking in_bss, then looking at s_skip for clues. */
+ subseg_set (bss_section, 0);
+ demand_empty_rest_of_line ();
+ mapping_state (MAP_DATA);
+}
+
+static void
+s_even (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ /* Never make frag if expect extra pass. */
+ if (!need_pass_2)
+ frag_align (1, 0, 0);
+
+ record_alignment (now_seg, 1);
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_ltorg (ignored)
+ int ignored ATTRIBUTE_UNUSED;
+{
+ unsigned int entry;
+ literal_pool * pool;
+ char sym_name[20];
+
+ pool = find_literal_pool ();
+ if (pool == NULL
+ || pool->symbol == NULL
+ || pool->next_free_entry == 0)
+ return;
+
+ mapping_state (MAP_DATA);
+
+ /* Align pool as you have word accesses.
+ Only make a frag if we have to. */
+ if (!need_pass_2)
+ frag_align (2, 0, 0);
+
+ record_alignment (now_seg, 2);
+
+ sprintf (sym_name, "$$lit_\002%x", pool->id);
+
+ symbol_locate (pool->symbol, sym_name, now_seg,
+ (valueT) frag_now_fix (), frag_now);
+ symbol_table_insert (pool->symbol);
+
+ ARM_SET_THUMB (pool->symbol, thumb_mode);
+
+#if defined OBJ_COFF || defined OBJ_ELF
+ ARM_SET_INTERWORK (pool->symbol, support_interwork);
+#endif
+
+ for (entry = 0; entry < pool->next_free_entry; entry ++)
+ /* First output the expression in the instruction to the pool. */
+ emit_expr (&(pool->literals[entry]), 4); /* .word */
+
+ /* Mark the pool as empty. */
+ pool->next_free_entry = 0;
+ pool->symbol = NULL;
+}
+
+/* Same as s_align_ptwo but align 0 => align 2. */
+
+static void
+s_align (unused)
+ int unused ATTRIBUTE_UNUSED;
+{
+ register int temp;
+ register long temp_fill;
+ long max_alignment = 15;
+
+ temp = get_absolute_expression ();
+ if (temp > max_alignment)
+ as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
+ else if (temp < 0)
+ {
+ as_bad (_("alignment negative. 0 assumed."));
+ temp = 0;
+ }
+
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ temp_fill = get_absolute_expression ();
+ }
+ else
+ temp_fill = 0;
+
+ if (!temp)
+ temp = 2;
+
+ /* Only make a frag if we HAVE to. */
+ if (temp && !need_pass_2)
+ frag_align (temp, (int) temp_fill, 0);
+ demand_empty_rest_of_line ();
+
+ record_alignment (now_seg, temp);
+}
+
+static void
+s_force_thumb (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ /* If we are not already in thumb mode go into it, EVEN if
+ the target processor does not support thumb instructions.
+ This is used by gcc/config/arm/lib1funcs.asm for example
+ to compile interworking support functions even if the
+ target processor should not support interworking. */
+ if (! thumb_mode)
+ {
+ thumb_mode = 2;
+
+ record_alignment (now_seg, 1);
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_thumb_func (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (! thumb_mode)
+ opcode_select (16);
+
+ /* The following label is the name/address of the start of a Thumb function.
+ We need to know this for the interworking support. */
+ label_is_thumb_function_name = TRUE;
+
+ demand_empty_rest_of_line ();
+}
+
+/* Perform a .set directive, but also mark the alias as
+ being a thumb function. */
+
+static void
+s_thumb_set (equiv)
+ int equiv;
+{
+ /* XXX the following is a duplicate of the code for s_set() in read.c
+ We cannot just call that code as we need to get at the symbol that
+ is created. */
+ register char * name;
+ register char delim;
+ register char * end_name;
+ register symbolS * symbolP;
+
+ /* Especial apologies for the random logic:
+ This just grew, and could be parsed much more simply!
+ Dean - in haste. */
+ name = input_line_pointer;
+ delim = get_symbol_end ();
+ end_name = input_line_pointer;
+ *end_name = delim;
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != ',')
+ {
+ *end_name = 0;
+ as_bad (_("expected comma after name \"%s\""), name);
+ *end_name = delim;
+ ignore_rest_of_line ();
+ return;
+ }
+
+ input_line_pointer++;
+ *end_name = 0;
+
+ if (name[0] == '.' && name[1] == '\0')
+ {
+ /* XXX - this should not happen to .thumb_set. */
+ abort ();
+ }
+
+ if ((symbolP = symbol_find (name)) == NULL
+ && (symbolP = md_undefined_symbol (name)) == NULL)
+ {
+#ifndef NO_LISTING
+ /* When doing symbol listings, play games with dummy fragments living
+ outside the normal fragment chain to record the file and line info
+ for this symbol. */
+ if (listing & LISTING_SYMBOLS)
+ {
+ extern struct list_info_struct * listing_tail;
+ fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
+
+ memset (dummy_frag, 0, sizeof (fragS));
+ dummy_frag->fr_type = rs_fill;
+ dummy_frag->line = listing_tail;
+ symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
+ dummy_frag->fr_symbol = symbolP;
+ }
+ else
+#endif
+ symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
+
+#ifdef OBJ_COFF
+ /* "set" symbols are local unless otherwise specified. */
+ SF_SET_LOCAL (symbolP);
+#endif /* OBJ_COFF */
+ } /* Make a new symbol. */
+
+ symbol_table_insert (symbolP);
+
+ * end_name = delim;
+
+ if (equiv
+ && S_IS_DEFINED (symbolP)
+ && S_GET_SEGMENT (symbolP) != reg_section)
+ as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
+
+ pseudo_set (symbolP);
+
+ demand_empty_rest_of_line ();
+
+ /* XXX Now we come to the Thumb specific bit of code. */
+
+ THUMB_SET_FUNC (symbolP, 1);
+ ARM_SET_THUMB (symbolP, 1);
+#if defined OBJ_ELF || defined OBJ_COFF
+ ARM_SET_INTERWORK (symbolP, support_interwork);
+#endif
+}
+
+static void
+opcode_select (width)
+ int width;
+{
+ switch (width)
+ {
+ case 16:
+ if (! thumb_mode)
+ {
+ if (! (cpu_variant & ARM_EXT_V4T))
+ as_bad (_("selected processor does not support THUMB opcodes"));
+
+ thumb_mode = 1;
+ /* No need to force the alignment, since we will have been
+ coming from ARM mode, which is word-aligned. */
+ record_alignment (now_seg, 1);
+ }
+ mapping_state (MAP_THUMB);
+ break;
+
+ case 32:
+ if (thumb_mode)
+ {
+ if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
+ as_bad (_("selected processor does not support ARM opcodes"));
+
+ thumb_mode = 0;
+
+ if (!need_pass_2)
+ frag_align (2, 0, 0);
+
+ record_alignment (now_seg, 1);
+ }
+ mapping_state (MAP_ARM);
+ break;
+
+ default:
+ as_bad (_("invalid instruction size selected (%d)"), width);
+ }
+}
+
+static void
+s_arm (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ opcode_select (32);
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_thumb (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ opcode_select (16);
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_code (unused)
+ int unused ATTRIBUTE_UNUSED;
+{
+ register int temp;
+
+ temp = get_absolute_expression ();
+ switch (temp)
+ {
+ case 16:
+ case 32:
+ opcode_select (temp);
+ break;
+
+ default:
+ as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
+ }
+}
+
+static void
+end_of_line (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (*str != '\0' && !inst.error)
+ inst.error = _("garbage following instruction");
+}
+
+static int
+skip_past_comma (str)
+ char ** str;
+{
+ char * p = * str, c;
+ int comma = 0;
+
+ while ((c = *p) == ' ' || c == ',')
+ {
+ p++;
+ if (c == ',' && comma++)
+ return FAIL;
+ }
+
+ if (c == '\0')
+ return FAIL;
+
+ *str = p;
+ return comma ? SUCCESS : FAIL;
+}
+
+/* A standard register must be given at this point.
+ SHIFT is the place to put it in inst.instruction.
+ Restores input start point on error.
+ Returns the reg#, or FAIL. */
+
+static int
+reg_required_here (str, shift)
+ char ** str;
+ int shift;
+{
+ static char buff [128]; /* XXX */
+ int reg;
+ char * start = * str;
+
+ if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
+ {
+ if (shift >= 0)
+ inst.instruction |= reg << shift;
+ return reg;
+ }
+
+ /* Restore the start point, we may have got a reg of the wrong class. */
+ *str = start;
+
+ /* In the few cases where we might be able to accept something else
+ this error can be overridden. */
+ sprintf (buff, _("register expected, not '%.100s'"), start);
+ inst.error = buff;
+
+ return FAIL;
+}
+
+/* A Intel Wireless MMX technology register
+ must be given at this point.
+ Shift is the place to put it in inst.instruction.
+ Restores input start point on err.
+ Returns the reg#, or FAIL. */
+
+static int
+wreg_required_here (str, shift, reg_type)
+ char ** str;
+ int shift;
+ enum wreg_type reg_type;
+{
+ static char buff [128];
+ int reg;
+ char * start = *str;
+
+ if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_IWMMXT].htab)) != FAIL)
+ {
+ if (wr_register (reg)
+ && (reg_type == IWMMXT_REG_WR || reg_type == IWMMXT_REG_WR_OR_WC))
+ {
+ if (shift >= 0)
+ inst.instruction |= (reg ^ WR_PREFIX) << shift;
+ return reg;
+ }
+ else if (wc_register (reg)
+ && (reg_type == IWMMXT_REG_WC || reg_type == IWMMXT_REG_WR_OR_WC))
+ {
+ if (shift >= 0)
+ inst.instruction |= (reg ^ WC_PREFIX) << shift;
+ return reg;
+ }
+ else if ((wcg_register (reg) && reg_type == IWMMXT_REG_WCG))
+ {
+ if (shift >= 0)
+ inst.instruction |= ((reg ^ WC_PREFIX) - 8) << shift;
+ return reg;
+ }
+ }
+
+ /* Restore the start point, we may have got a reg of the wrong class. */
+ *str = start;
+
+ /* In the few cases where we might be able to accept
+ something else this error can be overridden. */
+ sprintf (buff, _("Intel Wireless MMX technology register expected, not '%.100s'"), start);
+ inst.error = buff;
+
+ return FAIL;
+}
+
+static const struct asm_psr *
+arm_psr_parse (ccp)
+ register char ** ccp;
+{
+ char * start = * ccp;
+ char c;
+ char * p;
+ const struct asm_psr * psr;
+
+ p = start;
+
+ /* Skip to the end of the next word in the input stream. */
+ do
+ {
+ c = *p++;
+ }
+ while (ISALPHA (c) || c == '_');
+
+ /* Terminate the word. */
+ *--p = 0;
+
+ /* CPSR's and SPSR's can now be lowercase. This is just a convenience
+ feature for ease of use and backwards compatibility. */
+ if (!strncmp (start, "cpsr", 4))
+ strncpy (start, "CPSR", 4);
+ else if (!strncmp (start, "spsr", 4))
+ strncpy (start, "SPSR", 4);
+
+ /* Now locate the word in the psr hash table. */
+ psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
+
+ /* Restore the input stream. */
+ *p = c;
+
+ /* If we found a valid match, advance the
+ stream pointer past the end of the word. */
+ *ccp = p;
+
+ return psr;
+}
+
+/* Parse the input looking for a PSR flag. */
+
+static int
+psr_required_here (str)
+ char ** str;
+{
+ char * start = * str;
+ const struct asm_psr * psr;
+
+ psr = arm_psr_parse (str);
+
+ if (psr)
+ {
+ /* If this is the SPSR that is being modified, set the R bit. */
+ if (! psr->cpsr)
+ inst.instruction |= SPSR_BIT;
+
+ /* Set the psr flags in the MSR instruction. */
+ inst.instruction |= psr->field << PSR_SHIFT;
+
+ return SUCCESS;
+ }
+
+ /* In the few cases where we might be able to accept
+ something else this error can be overridden. */
+ inst.error = _("flag for {c}psr instruction expected");
+
+ /* Restore the start point. */
+ *str = start;
+ return FAIL;
+}
+
+static int
+co_proc_number (str)
+ char **str;
+{
+ int processor, pchar;
+ char *start;
+
+ skip_whitespace (*str);
+ start = *str;
+
+ /* The data sheet seems to imply that just a number on its own is valid
+ here, but the RISC iX assembler seems to accept a prefix 'p'. We will
+ accept either. */
+ if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
+ == FAIL)
+ {
+ *str = start;
+
+ pchar = *(*str)++;
+ if (pchar >= '0' && pchar <= '9')
+ {
+ processor = pchar - '0';
+ if (**str >= '0' && **str <= '9')
+ {
+ processor = processor * 10 + *(*str)++ - '0';
+ if (processor > 15)
+ {
+ inst.error = _("illegal co-processor number");
+ return FAIL;
+ }
+ }
+ }
+ else
+ {
+ inst.error = _("bad or missing co-processor number");
+ return FAIL;
+ }
+ }
+
+ inst.instruction |= processor << 8;
+ return SUCCESS;
+}
+
+static int
+cp_opc_expr (str, where, length)
+ char ** str;
+ int where;
+ int length;
+{
+ expressionS expr;
+
+ skip_whitespace (* str);
+
+ memset (&expr, '\0', sizeof (expr));
+
+ if (my_get_expression (&expr, str))
+ return FAIL;
+ if (expr.X_op != O_constant)
+ {
+ inst.error = _("bad or missing expression");
+ return FAIL;
+ }
+
+ if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
+ {
+ inst.error = _("immediate co-processor expression too large");
+ return FAIL;
+ }
+
+ inst.instruction |= expr.X_add_number << where;
+ return SUCCESS;
+}
+
+static int
+cp_reg_required_here (str, where)
+ char ** str;
+ int where;
+{
+ int reg;
+ char * start = *str;
+
+ if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
+ {
+ inst.instruction |= reg << where;
+ return reg;
+ }
+
+ /* In the few cases where we might be able to accept something else
+ this error can be overridden. */
+ inst.error = _("co-processor register expected");
+
+ /* Restore the start point. */
+ *str = start;
+ return FAIL;
+}
+
+static int
+fp_reg_required_here (str, where)
+ char ** str;
+ int where;
+{
+ int reg;
+ char * start = * str;
+
+ if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
+ {
+ inst.instruction |= reg << where;
+ return reg;
+ }
+
+ /* In the few cases where we might be able to accept something else
+ this error can be overridden. */
+ inst.error = _("floating point register expected");
+
+ /* Restore the start point. */
+ *str = start;
+ return FAIL;
+}
+
+static int
+cp_address_offset (str)
+ char ** str;
+{
+ int offset;
+
+ skip_whitespace (* str);
+
+ if (! is_immediate_prefix (**str))
+ {
+ inst.error = _("immediate expression expected");
+ return FAIL;
+ }
+
+ (*str)++;
+
+ if (my_get_expression (& inst.reloc.exp, str))
+ return FAIL;
+
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ offset = inst.reloc.exp.X_add_number;
+
+ if (offset & 3)
+ {
+ inst.error = _("co-processor address must be word aligned");
+ return FAIL;
+ }
+
+ if (offset > 1023 || offset < -1023)
+ {
+ inst.error = _("offset too large");
+ return FAIL;
+ }
+
+ if (offset >= 0)
+ inst.instruction |= INDEX_UP;
+ else
+ offset = -offset;
+
+ inst.instruction |= offset >> 2;
+ }
+ else
+ inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
+
+ return SUCCESS;
+}
+
+static int
+cp_address_required_here (str, wb_ok)
+ char ** str;
+ int wb_ok;
+{
+ char * p = * str;
+ int pre_inc = 0;
+ int write_back = 0;
+
+ if (*p == '[')
+ {
+ int reg;
+
+ p++;
+ skip_whitespace (p);
+
+ if ((reg = reg_required_here (& p, 16)) == FAIL)
+ return FAIL;
+
+ skip_whitespace (p);
+
+ if (*p == ']')
+ {
+ p++;
+
+ skip_whitespace (p);
+
+ if (*p == '\0')
+ {
+ /* As an extension to the official ARM syntax we allow:
+
+ [Rn]
+
+ as a short hand for:
+
+ [Rn,#0] */
+ inst.instruction |= PRE_INDEX | INDEX_UP;
+ *str = p;
+ return SUCCESS;
+ }
+
+ if (skip_past_comma (& p) == FAIL)
+ {
+ inst.error = _("comma expected after closing square bracket");
+ return FAIL;
+ }
+
+ skip_whitespace (p);
+
+ if (*p == '#')
+ {
+ if (wb_ok)
+ {
+ /* [Rn], #expr */
+ write_back = WRITE_BACK;
+
+ if (reg == REG_PC)
+ {
+ inst.error = _("pc may not be used in post-increment");
+ return FAIL;
+ }
+
+ if (cp_address_offset (& p) == FAIL)
+ return FAIL;
+ }
+ else
+ pre_inc = PRE_INDEX | INDEX_UP;
+ }
+ else if (*p == '{')
+ {
+ int option;
+
+ /* [Rn], {<expr>} */
+ p++;
+
+ skip_whitespace (p);
+
+ if (my_get_expression (& inst.reloc.exp, & p))
+ return FAIL;
+
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ option = inst.reloc.exp.X_add_number;
+
+ if (option > 255 || option < 0)
+ {
+ inst.error = _("'option' field too large");
+ return FAIL;
+ }
+
+ skip_whitespace (p);
+
+ if (*p != '}')
+ {
+ inst.error = _("'}' expected at end of 'option' field");
+ return FAIL;
+ }
+ else
+ {
+ p++;
+ inst.instruction |= option;
+ inst.instruction |= INDEX_UP;
+ }
+ }
+ else
+ {
+ inst.error = _("non-constant expressions for 'option' field not supported");
+ return FAIL;
+ }
+ }
+ else
+ {
+ inst.error = _("# or { expected after comma");
+ return FAIL;
+ }
+ }
+ else
+ {
+ /* '['Rn, #expr']'[!] */
+
+ if (skip_past_comma (& p) == FAIL)
+ {
+ inst.error = _("pre-indexed expression expected");
+ return FAIL;
+ }
+
+ pre_inc = PRE_INDEX;
+
+ if (cp_address_offset (& p) == FAIL)
+ return FAIL;
+
+ skip_whitespace (p);
+
+ if (*p++ != ']')
+ {
+ inst.error = _("missing ]");
+ return FAIL;
+ }
+
+ skip_whitespace (p);
+
+ if (wb_ok && *p == '!')
+ {
+ if (reg == REG_PC)
+ {
+ inst.error = _("pc may not be used with write-back");
+ return FAIL;
+ }
+
+ p++;
+ write_back = WRITE_BACK;
+ }
+ }
+ }
+ else
+ {
+ if (my_get_expression (&inst.reloc.exp, &p))
+ return FAIL;
+
+ inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
+ inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
+ inst.reloc.pc_rel = 1;
+ inst.instruction |= (REG_PC << 16);
+ pre_inc = PRE_INDEX;
+ }
+
+ inst.instruction |= write_back | pre_inc;
+ *str = p;
+ return SUCCESS;
+}
+
+static int
+cp_byte_address_offset (str)
+ char ** str;
+{
+ int offset;
+
+ skip_whitespace (* str);
+
+ if (! is_immediate_prefix (**str))
+ {
+ inst.error = _("immediate expression expected");
+ return FAIL;
+ }
+
+ (*str)++;
+
+ if (my_get_expression (& inst.reloc.exp, str))
+ return FAIL;
+
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ offset = inst.reloc.exp.X_add_number;
+
+ if (offset > 255 || offset < -255)
+ {
+ inst.error = _("offset too large");
+ return FAIL;
+ }
+
+ if (offset >= 0)
+ inst.instruction |= INDEX_UP;
+ else
+ offset = -offset;
+
+ inst.instruction |= offset;
+ }
+ else
+ inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
+
+ return SUCCESS;
+}
+
+static int
+cp_byte_address_required_here (str)
+ char ** str;
+{
+ char * p = * str;
+ int pre_inc = 0;
+ int write_back = 0;
+
+ if (*p == '[')
+ {
+ int reg;
+
+ p++;
+ skip_whitespace (p);
+
+ if ((reg = reg_required_here (& p, 16)) == FAIL)
+ return FAIL;
+
+ skip_whitespace (p);
+
+ if (*p == ']')
+ {
+ p++;
+
+ if (skip_past_comma (& p) == SUCCESS)
+ {
+ /* [Rn], #expr */
+ write_back = WRITE_BACK;
+
+ if (reg == REG_PC)
+ {
+ inst.error = _("pc may not be used in post-increment");
+ return FAIL;
+ }
+
+ if (cp_byte_address_offset (& p) == FAIL)
+ return FAIL;
+ }
+ else
+ pre_inc = PRE_INDEX | INDEX_UP;
+ }
+ else
+ {
+ /* '['Rn, #expr']'[!] */
+
+ if (skip_past_comma (& p) == FAIL)
+ {
+ inst.error = _("pre-indexed expression expected");
+ return FAIL;
+ }
+
+ pre_inc = PRE_INDEX;
+
+ if (cp_byte_address_offset (& p) == FAIL)
+ return FAIL;
+
+ skip_whitespace (p);
+
+ if (*p++ != ']')
+ {
+ inst.error = _("missing ]");
+ return FAIL;
+ }
+
+ skip_whitespace (p);
+
+ if (*p == '!')
+ {
+ if (reg == REG_PC)
+ {
+ inst.error = _("pc may not be used with write-back");
+ return FAIL;
+ }
+
+ p++;
+ write_back = WRITE_BACK;
+ }
+ }
+ }
+ else
+ {
+ if (my_get_expression (&inst.reloc.exp, &p))
+ return FAIL;
+
+ inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
+ inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
+ inst.reloc.pc_rel = 1;
+ inst.instruction |= (REG_PC << 16);
+ pre_inc = PRE_INDEX;
+ }
+
+ inst.instruction |= write_back | pre_inc;
+ *str = p;
+ return SUCCESS;
+}
+
+static void
+do_empty (str)
+ char * str;
+{
+ /* Do nothing really. */
+ end_of_line (str);
+}
+
+static void
+do_mrs (str)
+ char *str;
+{
+ int skip = 0;
+
+ /* Only one syntax. */
+ skip_whitespace (str);
+
+ if (reg_required_here (&str, 12) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL)
+ {
+ inst.error = _("comma expected after register name");
+ return;
+ }
+
+ skip_whitespace (str);
+
+ if ( strcmp (str, "CPSR") == 0
+ || strcmp (str, "SPSR") == 0
+ /* Lower case versions for backwards compatibility. */
+ || strcmp (str, "cpsr") == 0
+ || strcmp (str, "spsr") == 0)
+ skip = 4;
+
+ /* This is for backwards compatibility with older toolchains. */
+ else if ( strcmp (str, "cpsr_all") == 0
+ || strcmp (str, "spsr_all") == 0)
+ skip = 8;
+ else
+ {
+ inst.error = _("CPSR or SPSR expected");
+ return;
+ }
+
+ if (* str == 's' || * str == 'S')
+ inst.instruction |= SPSR_BIT;
+ str += skip;
+
+ end_of_line (str);
+}
+
+/* Two possible forms:
+ "{C|S}PSR_<field>, Rm",
+ "{C|S}PSR_f, #expression". */
+
+static void
+do_msr (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ if (psr_required_here (& str) == FAIL)
+ return;
+
+ if (skip_past_comma (& str) == FAIL)
+ {
+ inst.error = _("comma missing after psr flags");
+ return;
+ }
+
+ skip_whitespace (str);
+
+ if (reg_required_here (& str, 0) != FAIL)
+ {
+ inst.error = NULL;
+ end_of_line (str);
+ return;
+ }
+
+ if (! is_immediate_prefix (* str))
+ {
+ inst.error =
+ _("only a register or immediate value can follow a psr flag");
+ return;
+ }
+
+ str ++;
+ inst.error = NULL;
+
+ if (my_get_expression (& inst.reloc.exp, & str))
+ {
+ inst.error =
+ _("only a register or immediate value can follow a psr flag");
+ return;
+ }
+
+#if 0 /* The first edition of the ARM architecture manual stated that
+ writing anything other than the flags with an immediate operation
+ had UNPREDICTABLE effects. This constraint was removed in the
+ second edition of the specification. */
+ if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
+ && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
+ {
+ inst.error = _("immediate value cannot be used to set this field");
+ return;
+ }
+#endif
+
+ inst.instruction |= INST_IMMEDIATE;
+
+ if (inst.reloc.exp.X_add_symbol)
+ {
+ inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
+ inst.reloc.pc_rel = 0;
+ }
+ else
+ {
+ unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
+
+ if (value == (unsigned) FAIL)
+ {
+ inst.error = _("invalid constant");
+ return;
+ }
+
+ inst.instruction |= value;
+ }
+
+ inst.error = NULL;
+ end_of_line (str);
+}
+
+/* Long Multiply Parser
+ UMULL RdLo, RdHi, Rm, Rs
+ SMULL RdLo, RdHi, Rm, Rs
+ UMLAL RdLo, RdHi, Rm, Rs
+ SMLAL RdLo, RdHi, Rm, Rs. */
+
+static void
+do_mull (str)
+ char * str;
+{
+ int rdlo, rdhi, rm, rs;
+
+ /* Only one format "rdlo, rdhi, rm, rs". */
+ skip_whitespace (str);
+
+ if ((rdlo = reg_required_here (&str, 12)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || (rdhi = reg_required_here (&str, 16)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 0)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ /* rdhi, rdlo and rm must all be different. */
+ if (rdlo == rdhi || rdlo == rm || rdhi == rm)
+ as_tsktsk (_("rdhi, rdlo and rm must all be different"));
+
+ if (skip_past_comma (&str) == FAIL
+ || (rs = reg_required_here (&str, 8)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_mul (str)
+ char * str;
+{
+ int rd, rm;
+
+ /* Only one format "rd, rm, rs". */
+ skip_whitespace (str);
+
+ if ((rd = reg_required_here (&str, 16)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (rd == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 0)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (rm == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ if (rm == rd)
+ as_tsktsk (_("rd and rm should be different in mul"));
+
+ if (skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 8)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (rm == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_mla (str)
+ char * str;
+{
+ int rd, rm;
+
+ /* Only one format "rd, rm, rs, rn". */
+ skip_whitespace (str);
+
+ if ((rd = reg_required_here (&str, 16)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (rd == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 0)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (rm == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ if (rm == rd)
+ as_tsktsk (_("rd and rm should be different in mla"));
+
+ if (skip_past_comma (&str) == FAIL
+ || (rd = reg_required_here (&str, 8)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 12)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (rd == REG_PC || rm == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+/* Expects *str -> the characters "acc0", possibly with leading blanks.
+ Advances *str to the next non-alphanumeric.
+ Returns 0, or else FAIL (in which case sets inst.error).
+
+ (In a future XScale, there may be accumulators other than zero.
+ At that time this routine and its callers can be upgraded to suit.) */
+
+static int
+accum0_required_here (str)
+ char ** str;
+{
+ static char buff [128]; /* Note the address is taken. Hence, static. */
+ char * p = * str;
+ char c;
+ int result = 0; /* The accum number. */
+
+ skip_whitespace (p);
+
+ *str = p; /* Advance caller's string pointer too. */
+ c = *p++;
+ while (ISALNUM (c))
+ c = *p++;
+
+ *--p = 0; /* Aap nul into input buffer at non-alnum. */
+
+ if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
+ {
+ sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
+ inst.error = buff;
+ result = FAIL;
+ }
+
+ *p = c; /* Unzap. */
+ *str = p; /* Caller's string pointer to after match. */
+ return result;
+}
+
+/* Expects **str -> after a comma. May be leading blanks.
+ Advances *str, recognizing a load mode, and setting inst.instruction.
+ Returns rn, or else FAIL (in which case may set inst.error
+ and not advance str)
+
+ Note: doesn't know Rd, so no err checks that require such knowledge. */
+
+static int
+ld_mode_required_here (string)
+ char ** string;
+{
+ char * str = * string;
+ int rn;
+ int pre_inc = 0;
+
+ skip_whitespace (str);
+
+ if (* str == '[')
+ {
+ str++;
+
+ skip_whitespace (str);
+
+ if ((rn = reg_required_here (& str, 16)) == FAIL)
+ return FAIL;
+
+ skip_whitespace (str);
+
+ if (* str == ']')
+ {
+ str ++;
+
+ if (skip_past_comma (& str) == SUCCESS)
+ {
+ /* [Rn],... (post inc) */
+ if (ldst_extend_v4 (&str) == FAIL)
+ return FAIL;
+ }
+ else /* [Rn] */
+ {
+ skip_whitespace (str);
+
+ if (* str == '!')
+ {
+ str ++;
+ inst.instruction |= WRITE_BACK;
+ }
+
+ inst.instruction |= INDEX_UP | HWOFFSET_IMM;
+ pre_inc = 1;
+ }
+ }
+ else /* [Rn,...] */
+ {
+ if (skip_past_comma (& str) == FAIL)
+ {
+ inst.error = _("pre-indexed expression expected");
+ return FAIL;
+ }
+
+ pre_inc = 1;
+
+ if (ldst_extend_v4 (&str) == FAIL)
+ return FAIL;
+
+ skip_whitespace (str);
+
+ if (* str ++ != ']')
+ {
+ inst.error = _("missing ]");
+ return FAIL;
+ }
+
+ skip_whitespace (str);
+
+ if (* str == '!')
+ {
+ str ++;
+ inst.instruction |= WRITE_BACK;
+ }
+ }
+ }
+ else if (* str == '=') /* ldr's "r,=label" syntax */
+ /* We should never reach here, because <text> = <expression> is
+ caught gas/read.c read_a_source_file() as a .set operation. */
+ return FAIL;
+ else /* PC +- 8 bit immediate offset. */
+ {
+ if (my_get_expression (& inst.reloc.exp, & str))
+ return FAIL;
+
+ inst.instruction |= HWOFFSET_IMM; /* The I bit. */
+ inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
+ inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
+ inst.reloc.pc_rel = 1;
+ inst.instruction |= (REG_PC << 16);
+
+ rn = REG_PC;
+ pre_inc = 1;
+ }
+
+ inst.instruction |= (pre_inc ? PRE_INDEX : 0);
+ * string = str;
+
+ return rn;
+}
+
+/* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
+ SMLAxy{cond} Rd,Rm,Rs,Rn
+ SMLAWy{cond} Rd,Rm,Rs,Rn
+ Error if any register is R15. */
+
+static void
+do_smla (str)
+ char * str;
+{
+ int rd, rm, rs, rn;
+
+ skip_whitespace (str);
+
+ if ((rd = reg_required_here (& str, 16)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || (rm = reg_required_here (& str, 0)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || (rs = reg_required_here (& str, 8)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || (rn = reg_required_here (& str, 12)) == FAIL)
+ inst.error = BAD_ARGS;
+
+ else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
+ inst.error = BAD_PC;
+
+ else
+ end_of_line (str);
+}
+
+/* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
+ SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
+ Error if any register is R15.
+ Warning if Rdlo == Rdhi. */
+
+static void
+do_smlal (str)
+ char * str;
+{
+ int rdlo, rdhi, rm, rs;
+
+ skip_whitespace (str);
+
+ if ((rdlo = reg_required_here (& str, 12)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || (rdhi = reg_required_here (& str, 16)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || (rm = reg_required_here (& str, 0)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || (rs = reg_required_here (& str, 8)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ if (rdlo == rdhi)
+ as_tsktsk (_("rdhi and rdlo must be different"));
+
+ end_of_line (str);
+}
+
+/* ARM V5E (El Segundo) signed-multiply (argument parse)
+ SMULxy{cond} Rd,Rm,Rs
+ Error if any register is R15. */
+
+static void
+do_smul (str)
+ char * str;
+{
+ int rd, rm, rs;
+
+ skip_whitespace (str);
+
+ if ((rd = reg_required_here (& str, 16)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || (rm = reg_required_here (& str, 0)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || (rs = reg_required_here (& str, 8)) == FAIL)
+ inst.error = BAD_ARGS;
+
+ else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
+ inst.error = BAD_PC;
+
+ else
+ end_of_line (str);
+}
+
+/* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
+ Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
+ Error if any register is R15. */
+
+static void
+do_qadd (str)
+ char * str;
+{
+ int rd, rm, rn;
+
+ skip_whitespace (str);
+
+ if ((rd = reg_required_here (& str, 12)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || (rm = reg_required_here (& str, 0)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || (rn = reg_required_here (& str, 16)) == FAIL)
+ inst.error = BAD_ARGS;
+
+ else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
+ inst.error = BAD_PC;
+
+ else
+ end_of_line (str);
+}
+
+/* ARM V5E (el Segundo)
+ MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
+ MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
+
+ These are equivalent to the XScale instructions MAR and MRA,
+ respectively, when coproc == 0, opcode == 0, and CRm == 0.
+
+ Result unpredicatable if Rd or Rn is R15. */
+
+static void
+do_co_reg2c (str)
+ char * str;
+{
+ int rd, rn;
+
+ skip_whitespace (str);
+
+ if (co_proc_number (& str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL
+ || cp_opc_expr (& str, 4, 4) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL
+ || (rd = reg_required_here (& str, 12)) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL
+ || (rn = reg_required_here (& str, 16)) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ /* Unpredictable result if rd or rn is R15. */
+ if (rd == REG_PC || rn == REG_PC)
+ as_tsktsk
+ (_("Warning: instruction unpredictable when using r15"));
+
+ if (skip_past_comma (& str) == FAIL
+ || cp_reg_required_here (& str, 0) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+/* ARM V5 count-leading-zeroes instruction (argument parse)
+ CLZ{<cond>} <Rd>, <Rm>
+ Condition defaults to COND_ALWAYS.
+ Error if Rd or Rm are R15. */
+
+static void
+do_clz (str)
+ char * str;
+{
+ int rd, rm;
+
+ skip_whitespace (str);
+
+ if (((rd = reg_required_here (& str, 12)) == FAIL)
+ || (skip_past_comma (& str) == FAIL)
+ || ((rm = reg_required_here (& str, 0)) == FAIL))
+ inst.error = BAD_ARGS;
+
+ else if (rd == REG_PC || rm == REG_PC )
+ inst.error = BAD_PC;
+
+ else
+ end_of_line (str);
+}
+
+/* ARM V5 (argument parse)
+ LDC2{L} <coproc>, <CRd>, <addressing mode>
+ STC2{L} <coproc>, <CRd>, <addressing mode>
+ Instruction is not conditional, and has 0xf in the condition field.
+ Otherwise, it's the same as LDC/STC. */
+
+static void
+do_lstc2 (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ if (co_proc_number (& str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ }
+ else if (skip_past_comma (& str) == FAIL
+ || cp_reg_required_here (& str, 12) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ }
+ else if (skip_past_comma (& str) == FAIL
+ || cp_address_required_here (&str, CP_WB_OK) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ }
+ else
+ end_of_line (str);
+}
+
+/* ARM V5 (argument parse)
+ CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
+ Instruction is not conditional, and has 0xf in the condition field.
+ Otherwise, it's the same as CDP. */
+
+static void
+do_cdp2 (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ if (co_proc_number (& str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL
+ || cp_opc_expr (& str, 20,4) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL
+ || cp_reg_required_here (& str, 12) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL
+ || cp_reg_required_here (& str, 16) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL
+ || cp_reg_required_here (& str, 0) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == SUCCESS)
+ {
+ if (cp_opc_expr (& str, 5, 3) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+ }
+
+ end_of_line (str);
+}
+
+/* ARM V5 (argument parse)
+ MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
+ MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
+ Instruction is not conditional, and has 0xf in the condition field.
+ Otherwise, it's the same as MCR/MRC. */
+
+static void
+do_co_reg2 (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ if (co_proc_number (& str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL
+ || cp_opc_expr (& str, 21, 3) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL
+ || reg_required_here (& str, 12) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL
+ || cp_reg_required_here (& str, 16) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL
+ || cp_reg_required_here (& str, 0) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == SUCCESS)
+ {
+ if (cp_opc_expr (& str, 5, 3) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+ }
+
+ end_of_line (str);
+}
+
+/* ARM v5TEJ. Jump to Jazelle code. */
+static void
+do_bxj (str)
+ char * str;
+{
+ int reg;
+
+ skip_whitespace (str);
+
+ if ((reg = reg_required_here (&str, 0)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ /* Note - it is not illegal to do a "bxj pc". Useless, but not illegal. */
+ if (reg == REG_PC)
+ as_tsktsk (_("use of r15 in bxj is not really useful"));
+
+ end_of_line (str);
+}
+
+/* ARM V6 umaal (argument parse). */
+
+static void
+do_umaal (str)
+ char *str;
+{
+
+ int rdlo, rdhi, rm, rs;
+
+ skip_whitespace (str);
+ if ((rdlo = reg_required_here (& str, 12)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || (rdhi = reg_required_here (& str, 16)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || (rm = reg_required_here (& str, 0)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || (rs = reg_required_here (& str, 8)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+/* ARM V6 strex (argument parse). */
+
+static void
+do_strex (str)
+ char *str;
+{
+ int rd, rm, rn;
+
+ /* Parse Rd, Rm,. */
+ skip_whitespace (str);
+ if ((rd = reg_required_here (& str, 12)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || (rm = reg_required_here (& str, 0)) == FAIL
+ || skip_past_comma (& str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ if (rd == REG_PC || rm == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+ if (rd == rm)
+ {
+ inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
+ return;
+ }
+
+ /* Skip past '['. */
+ if ((strlen (str) >= 1)
+ && strncmp (str, "[", 1) == 0)
+ str+=1;
+ skip_whitespace (str);
+
+ /* Parse Rn. */
+ if ((rn = reg_required_here (& str, 16)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ else if (rn == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+ if (rd == rn)
+ {
+ inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
+ return;
+ }
+ skip_whitespace (str);
+
+ /* Skip past ']'. */
+ if ((strlen (str) >= 1)
+ && strncmp (str, "]", 1) == 0)
+ str+=1;
+
+ end_of_line (str);
+}
+
+/* ARM V6 ssat (argument parse). */
+
+static void
+do_ssat (str)
+ char* str;
+{
+ do_sat (&str, /*bias=*/-1);
+ end_of_line (str);
+}
+
+/* ARM V6 usat (argument parse). */
+
+static void
+do_usat (str)
+ char* str;
+{
+ do_sat (&str, /*bias=*/0);
+ end_of_line (str);
+}
+
+static void
+do_sat (str, bias)
+ char **str;
+ int bias;
+{
+ int rd, rm;
+ expressionS expr;
+
+ skip_whitespace (*str);
+
+ /* Parse <Rd>, field. */
+ if ((rd = reg_required_here (str, 12)) == FAIL
+ || skip_past_comma (str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ if (rd == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ /* Parse #<immed>, field. */
+ if (is_immediate_prefix (**str))
+ (*str)++;
+ else
+ {
+ inst.error = _("immediate expression expected");
+ return;
+ }
+ if (my_get_expression (&expr, str))
+ {
+ inst.error = _("bad expression");
+ return;
+ }
+ if (expr.X_op != O_constant)
+ {
+ inst.error = _("constant expression expected");
+ return;
+ }
+ if (expr.X_add_number + bias < 0
+ || expr.X_add_number + bias > 31)
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+ inst.instruction |= (expr.X_add_number + bias) << 16;
+ if (skip_past_comma (str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ /* Parse <Rm> field. */
+ if ((rm = reg_required_here (str, 0)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ if (rm == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ if (skip_past_comma (str) == SUCCESS)
+ decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
+}
+
+/* ARM V6 ssat16 (argument parse). */
+
+static void
+do_ssat16 (str)
+ char *str;
+{
+ do_sat16 (&str, /*bias=*/-1);
+ end_of_line (str);
+}
+
+static void
+do_usat16 (str)
+ char *str;
+{
+ do_sat16 (&str, /*bias=*/0);
+ end_of_line (str);
+}
+
+static void
+do_sat16 (str, bias)
+ char **str;
+ int bias;
+{
+ int rd, rm;
+ expressionS expr;
+
+ skip_whitespace (*str);
+
+ /* Parse the <Rd> field. */
+ if ((rd = reg_required_here (str, 12)) == FAIL
+ || skip_past_comma (str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ if (rd == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ /* Parse #<immed>, field. */
+ if (is_immediate_prefix (**str))
+ (*str)++;
+ else
+ {
+ inst.error = _("immediate expression expected");
+ return;
+ }
+ if (my_get_expression (&expr, str))
+ {
+ inst.error = _("bad expression");
+ return;
+ }
+ if (expr.X_op != O_constant)
+ {
+ inst.error = _("constant expression expected");
+ return;
+ }
+ if (expr.X_add_number + bias < 0
+ || expr.X_add_number + bias > 15)
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+ inst.instruction |= (expr.X_add_number + bias) << 16;
+ if (skip_past_comma (str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ /* Parse <Rm> field. */
+ if ((rm = reg_required_here (str, 0)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ if (rm == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+}
+
+/* ARM V6 srs (argument parse). */
+
+static void
+do_srs (str)
+ char* str;
+{
+ char *exclam;
+ skip_whitespace (str);
+ exclam = strchr (str, '!');
+ if (exclam)
+ *exclam = '\0';
+ do_cps_mode (&str);
+ if (exclam)
+ *exclam = '!';
+ if (*str == '!')
+ {
+ inst.instruction |= WRITE_BACK;
+ str++;
+ }
+ end_of_line (str);
+}
+
+/* ARM V6 SMMUL (argument parse). */
+
+static void
+do_smmul (str)
+ char* str;
+{
+ int rd, rm, rs;
+
+ skip_whitespace (str);
+ if ((rd = reg_required_here (&str, 16)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 0)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (rs = reg_required_here (&str, 8)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (rd == REG_PC
+ || rm == REG_PC
+ || rs == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ end_of_line (str);
+
+}
+
+/* ARM V6 SMLALD (argument parse). */
+
+static void
+do_smlald (str)
+ char* str;
+{
+ int rdlo, rdhi, rm, rs;
+ skip_whitespace (str);
+ if ((rdlo = reg_required_here (&str, 12)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (rdhi = reg_required_here (&str, 16)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 0)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (rs = reg_required_here (&str, 8)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (rdlo == REG_PC
+ || rdhi == REG_PC
+ || rm == REG_PC
+ || rs == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+/* ARM V6 SMLAD (argument parse). Signed multiply accumulate dual.
+ smlad{x}{<cond>} Rd, Rm, Rs, Rn */
+
+static void
+do_smlad (str)
+ char *str;
+{
+ int rd, rm, rs, rn;
+
+ skip_whitespace (str);
+ if ((rd = reg_required_here (&str, 16)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 0)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (rs = reg_required_here (&str, 8)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (rn = reg_required_here (&str, 12)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (rd == REG_PC
+ || rn == REG_PC
+ || rs == REG_PC
+ || rm == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+/* ARM V6 SETEND (argument parse). Sets the E bit in the CPSR while
+ preserving the other bits.
+
+ setend <endian_specifier>, where <endian_specifier> is either
+ BE or LE. */
+
+static void
+do_setend (str)
+ char *str;
+{
+ if (do_endian_specifier (str))
+ inst.instruction |= 0x200;
+}
+
+/* Returns true if the endian-specifier indicates big-endianness. */
+
+static int
+do_endian_specifier (str)
+ char *str;
+{
+ int big_endian = 0;
+
+ skip_whitespace (str);
+ if (strlen (str) < 2)
+ inst.error = _("missing endian specifier");
+ else if (strncasecmp (str, "BE", 2) == 0)
+ {
+ str += 2;
+ big_endian = 1;
+ }
+ else if (strncasecmp (str, "LE", 2) == 0)
+ str += 2;
+ else
+ inst.error = _("valid endian specifiers are be or le");
+
+ end_of_line (str);
+
+ return big_endian;
+}
+
+/* ARM V6 SXTH.
+
+ SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
+ Condition defaults to COND_ALWAYS.
+ Error if any register uses R15. */
+
+static void
+do_sxth (str)
+ char *str;
+{
+ int rd, rm;
+ expressionS expr;
+ int rotation_clear_mask = 0xfffff3ff;
+ int rotation_eight_mask = 0x00000400;
+ int rotation_sixteen_mask = 0x00000800;
+ int rotation_twenty_four_mask = 0x00000c00;
+
+ skip_whitespace (str);
+ if ((rd = reg_required_here (&str, 12)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 0)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ else if (rd == REG_PC || rm == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ /* Zero out the rotation field. */
+ inst.instruction &= rotation_clear_mask;
+
+ /* Check for lack of optional rotation field. */
+ if (skip_past_comma (&str) == FAIL)
+ {
+ end_of_line (str);
+ return;
+ }
+
+ /* Move past 'ROR'. */
+ skip_whitespace (str);
+ if (strncasecmp (str, "ROR", 3) == 0)
+ str+=3;
+ else
+ {
+ inst.error = _("missing rotation field after comma");
+ return;
+ }
+
+ /* Get the immediate constant. */
+ skip_whitespace (str);
+ if (is_immediate_prefix (* str))
+ str++;
+ else
+ {
+ inst.error = _("immediate expression expected");
+ return;
+ }
+
+ if (my_get_expression (&expr, &str))
+ {
+ inst.error = _("bad expression");
+ return;
+ }
+
+ if (expr.X_op != O_constant)
+ {
+ inst.error = _("constant expression expected");
+ return;
+ }
+
+ switch (expr.X_add_number)
+ {
+ case 0:
+ /* Rotation field has already been zeroed. */
+ break;
+ case 8:
+ inst.instruction |= rotation_eight_mask;
+ break;
+
+ case 16:
+ inst.instruction |= rotation_sixteen_mask;
+ break;
+
+ case 24:
+ inst.instruction |= rotation_twenty_four_mask;
+ break;
+
+ default:
+ inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
+ break;
+ }
+
+ end_of_line (str);
+
+}
+
+/* ARM V6 SXTAH extracts a 16-bit value from a register, sign
+ extends it to 32-bits, and adds the result to a value in another
+ register. You can specify a rotation by 0, 8, 16, or 24 bits
+ before extracting the 16-bit value.
+ SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
+ Condition defaults to COND_ALWAYS.
+ Error if any register uses R15. */
+
+static void
+do_sxtah (str)
+ char *str;
+{
+ int rd, rn, rm;
+ expressionS expr;
+ int rotation_clear_mask = 0xfffff3ff;
+ int rotation_eight_mask = 0x00000400;
+ int rotation_sixteen_mask = 0x00000800;
+ int rotation_twenty_four_mask = 0x00000c00;
+
+ skip_whitespace (str);
+ if ((rd = reg_required_here (&str, 12)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (rn = reg_required_here (&str, 16)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 0)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ /* Zero out the rotation field. */
+ inst.instruction &= rotation_clear_mask;
+
+ /* Check for lack of optional rotation field. */
+ if (skip_past_comma (&str) == FAIL)
+ {
+ end_of_line (str);
+ return;
+ }
+
+ /* Move past 'ROR'. */
+ skip_whitespace (str);
+ if (strncasecmp (str, "ROR", 3) == 0)
+ str+=3;
+ else
+ {
+ inst.error = _("missing rotation field after comma");
+ return;
+ }
+
+ /* Get the immediate constant. */
+ skip_whitespace (str);
+ if (is_immediate_prefix (* str))
+ str++;
+ else
+ {
+ inst.error = _("immediate expression expected");
+ return;
+ }
+
+ if (my_get_expression (&expr, &str))
+ {
+ inst.error = _("bad expression");
+ return;
+ }
+
+ if (expr.X_op != O_constant)
+ {
+ inst.error = _("constant expression expected");
+ return;
+ }
+
+ switch (expr.X_add_number)
+ {
+ case 0:
+ /* Rotation field has already been zeroed. */
+ break;
+
+ case 8:
+ inst.instruction |= rotation_eight_mask;
+ break;
+
+ case 16:
+ inst.instruction |= rotation_sixteen_mask;
+ break;
+
+ case 24:
+ inst.instruction |= rotation_twenty_four_mask;
+ break;
+
+ default:
+ inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
+ break;
+ }
+
+ end_of_line (str);
+
+}
+
+
+/* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
+ word at the specified address and the following word
+ respectively.
+ Unconditionally executed.
+ Error if Rn is R15.
+*/
+
+static void
+do_rfe (str)
+ char *str;
+{
+ int rn;
+
+ skip_whitespace (str);
+
+ if ((rn = reg_required_here (&str, 16)) == FAIL)
+ return;
+
+ if (rn == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ skip_whitespace (str);
+
+ if (*str == '!')
+ {
+ inst.instruction |= WRITE_BACK;
+ str++;
+ }
+ end_of_line (str);
+}
+
+/* ARM V6 REV (Byte Reverse Word) reverses the byte order in a 32-bit
+ register (argument parse).
+ REV{<cond>} Rd, Rm.
+ Condition defaults to COND_ALWAYS.
+ Error if Rd or Rm are R15. */
+
+static void
+do_rev (str)
+ char* str;
+{
+ int rd, rm;
+
+ skip_whitespace (str);
+
+ if ((rd = reg_required_here (&str, 12)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 0)) == FAIL)
+ inst.error = BAD_ARGS;
+
+ else if (rd == REG_PC || rm == REG_PC)
+ inst.error = BAD_PC;
+
+ else
+ end_of_line (str);
+}
+
+/* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
+ QADD16{<cond>} <Rd>, <Rn>, <Rm>
+ Condition defaults to COND_ALWAYS.
+ Error if Rd, Rn or Rm are R15. */
+
+static void
+do_qadd16 (str)
+ char* str;
+{
+ int rd, rm, rn;
+
+ skip_whitespace (str);
+
+ if ((rd = reg_required_here (&str, 12)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (rn = reg_required_here (&str, 16)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 0)) == FAIL)
+ inst.error = BAD_ARGS;
+
+ else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
+ inst.error = BAD_PC;
+
+ else
+ end_of_line (str);
+}
+
+/* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
+ PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
+ Condition defaults to COND_ALWAYS.
+ Error if Rd, Rn or Rm are R15. */
+
+static void
+do_pkhbt (str)
+ char* str;
+{
+ do_pkh_core (str, SHIFT_LSL_IMMEDIATE);
+}
+
+/* ARM V6 PKHTB (Argument Parse). */
+
+static void
+do_pkhtb (str)
+ char* str;
+{
+ do_pkh_core (str, SHIFT_ASR_IMMEDIATE);
+}
+
+static void
+do_pkh_core (str, shift)
+ char* str;
+ int shift;
+{
+ int rd, rn, rm;
+
+ skip_whitespace (str);
+ if (((rd = reg_required_here (&str, 12)) == FAIL)
+ || (skip_past_comma (&str) == FAIL)
+ || ((rn = reg_required_here (&str, 16)) == FAIL)
+ || (skip_past_comma (&str) == FAIL)
+ || ((rm = reg_required_here (&str, 0)) == FAIL))
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ /* Check for optional shift immediate constant. */
+ if (skip_past_comma (&str) == FAIL)
+ {
+ if (shift == SHIFT_ASR_IMMEDIATE)
+ {
+ /* If the shift specifier is ommited, turn the instruction
+ into pkhbt rd, rm, rn. First, switch the instruction
+ code, and clear the rn and rm fields. */
+ inst.instruction &= 0xfff0f010;
+ /* Now, re-encode the registers. */
+ inst.instruction |= (rm << 16) | rn;
+ }
+ return;
+ }
+
+ decode_shift (&str, shift);
+}
+
+/* ARM V6 Load Register Exclusive instruction (argument parse).
+ LDREX{<cond>} <Rd, [<Rn>]
+ Condition defaults to COND_ALWAYS.
+ Error if Rd or Rn are R15.
+ See ARMARMv6 A4.1.27: LDREX. */
+
+
+static void
+do_ldrex (str)
+ char * str;
+{
+ int rd, rn;
+
+ skip_whitespace (str);
+
+ /* Parse Rd. */
+ if (((rd = reg_required_here (&str, 12)) == FAIL)
+ || (skip_past_comma (&str) == FAIL))
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ else if (rd == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+ skip_whitespace (str);
+
+ /* Skip past '['. */
+ if ((strlen (str) >= 1)
+ &&strncmp (str, "[", 1) == 0)
+ str+=1;
+ skip_whitespace (str);
+
+ /* Parse Rn. */
+ if ((rn = reg_required_here (&str, 16)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ else if (rn == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+ skip_whitespace (str);
+
+ /* Skip past ']'. */
+ if ((strlen (str) >= 1)
+ && strncmp (str, "]", 1) == 0)
+ str+=1;
+
+ end_of_line (str);
+}
+
+/* ARM V6 change processor state instruction (argument parse)
+ CPS, CPSIE, CSPID . */
+
+static void
+do_cps (str)
+ char * str;
+{
+ do_cps_mode (&str);
+ end_of_line (str);
+}
+
+static void
+do_cpsi (str)
+ char * str;
+{
+ do_cps_flags (&str, /*thumb_p=*/0);
+
+ if (skip_past_comma (&str) == SUCCESS)
+ {
+ skip_whitespace (str);
+ do_cps_mode (&str);
+ }
+ end_of_line (str);
+}
+
+static void
+do_cps_mode (str)
+ char **str;
+{
+ expressionS expr;
+
+ skip_whitespace (*str);
+
+ if (! is_immediate_prefix (**str))
+ {
+ inst.error = _("immediate expression expected");
+ return;
+ }
+
+ (*str)++; /* Strip off the immediate signifier. */
+ if (my_get_expression (&expr, str))
+ {
+ inst.error = _("bad expression");
+ return;
+ }
+
+ if (expr.X_op != O_constant)
+ {
+ inst.error = _("constant expression expected");
+ return;
+ }
+
+ /* The mode is a 5 bit field. Valid values are 0-31. */
+ if (((unsigned) expr.X_add_number) > 31
+ || (inst.reloc.exp.X_add_number) < 0)
+ {
+ inst.error = _("invalid constant");
+ return;
+ }
+
+ inst.instruction |= expr.X_add_number;
+}
+
+static void
+do_cps_flags (str, thumb_p)
+ char **str;
+ int thumb_p;
+{
+ struct cps_flag {
+ char character;
+ unsigned long arm_value;
+ unsigned long thumb_value;
+ };
+ static struct cps_flag flag_table[] = {
+ {'a', 0x100, 0x4 },
+ {'i', 0x080, 0x2 },
+ {'f', 0x040, 0x1 }
+ };
+
+ int saw_a_flag = 0;
+
+ skip_whitespace (*str);
+
+ /* Get the a, f and i flags. */
+ while (**str && **str != ',')
+ {
+ struct cps_flag *p;
+ struct cps_flag *q = flag_table + sizeof (flag_table)/sizeof (*p);
+ for (p = flag_table; p < q; ++p)
+ if (strncasecmp (*str, &p->character, 1) == 0)
+ {
+ inst.instruction |= (thumb_p ? p->thumb_value : p->arm_value);
+ saw_a_flag = 1;
+ break;
+ }
+ if (p == q)
+ {
+ inst.error = _("unrecognized flag");
+ return;
+ }
+ (*str)++;
+ }
+ if (!saw_a_flag)
+ inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
+}
+
+/* THUMB V5 breakpoint instruction (argument parse)
+ BKPT <immed_8>. */
+
+static void
+do_t_bkpt (str)
+ char * str;
+{
+ expressionS expr;
+ unsigned long number;
+
+ skip_whitespace (str);
+
+ /* Allow optional leading '#'. */
+ if (is_immediate_prefix (*str))
+ str ++;
+
+ memset (& expr, '\0', sizeof (expr));
+ if (my_get_expression (& expr, & str)
+ || (expr.X_op != O_constant
+ /* As a convenience we allow 'bkpt' without an operand. */
+ && expr.X_op != O_absent))
+ {
+ inst.error = _("bad expression");
+ return;
+ }
+
+ number = expr.X_add_number;
+
+ /* Check it fits an 8 bit unsigned. */
+ if (number != (number & 0xff))
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+
+ inst.instruction |= number;
+
+ end_of_line (str);
+}
+
+/* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
+ Expects inst.instruction is set for BLX(1).
+ Note: this is cloned from do_branch, and the reloc changed to be a
+ new one that can cope with setting one extra bit (the H bit). */
+
+static void
+do_branch25 (str)
+ char * str;
+{
+ if (my_get_expression (& inst.reloc.exp, & str))
+ return;
+
+#ifdef OBJ_ELF
+ {
+ char * save_in;
+
+ /* ScottB: February 5, 1998 */
+ /* Check to see of PLT32 reloc required for the instruction. */
+
+ /* arm_parse_reloc() works on input_line_pointer.
+ We actually want to parse the operands to the branch instruction
+ passed in 'str'. Save the input pointer and restore it later. */
+ save_in = input_line_pointer;
+ input_line_pointer = str;
+
+ if (inst.reloc.exp.X_op == O_symbol
+ && *str == '('
+ && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
+ {
+ inst.reloc.type = BFD_RELOC_ARM_PLT32;
+ inst.reloc.pc_rel = 0;
+ /* Modify str to point to after parsed operands, otherwise
+ end_of_line() will complain about the (PLT) left in str. */
+ str = input_line_pointer;
+ }
+ else
+ {
+ inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
+ inst.reloc.pc_rel = 1;
+ }
+
+ input_line_pointer = save_in;
+ }
+#else
+ inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
+ inst.reloc.pc_rel = 1;
+#endif /* OBJ_ELF */
+
+ end_of_line (str);
+}
+
+/* ARM V5 branch-link-exchange instruction (argument parse)
+ BLX <target_addr> ie BLX(1)
+ BLX{<condition>} <Rm> ie BLX(2)
+ Unfortunately, there are two different opcodes for this mnemonic.
+ So, the insns[].value is not used, and the code here zaps values
+ into inst.instruction.
+ Also, the <target_addr> can be 25 bits, hence has its own reloc. */
+
+static void
+do_blx (str)
+ char * str;
+{
+ char * mystr = str;
+ int rm;
+
+ skip_whitespace (mystr);
+ rm = reg_required_here (& mystr, 0);
+
+ /* The above may set inst.error. Ignore his opinion. */
+ inst.error = 0;
+
+ if (rm != FAIL)
+ {
+ /* Arg is a register.
+ Use the condition code our caller put in inst.instruction.
+ Pass ourselves off as a BX with a funny opcode. */
+ inst.instruction |= 0x012fff30;
+ do_bx (str);
+ }
+ else
+ {
+ /* This must be is BLX <target address>, no condition allowed. */
+ if (inst.instruction != COND_ALWAYS)
+ {
+ inst.error = BAD_COND;
+ return;
+ }
+
+ inst.instruction = 0xfafffffe;
+
+ /* Process like a B/BL, but with a different reloc.
+ Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
+ do_branch25 (str);
+ }
+}
+
+/* ARM V5 Thumb BLX (argument parse)
+ BLX <target_addr> which is BLX(1)
+ BLX <Rm> which is BLX(2)
+ Unfortunately, there are two different opcodes for this mnemonic.
+ So, the tinsns[].value is not used, and the code here zaps values
+ into inst.instruction. */
+
+static void
+do_t_blx (str)
+ char * str;
+{
+ char * mystr = str;
+ int rm;
+
+ skip_whitespace (mystr);
+ inst.instruction = 0x4780;
+
+ /* Note that this call is to the ARM register recognizer. BLX(2)
+ uses the ARM register space, not the Thumb one, so a call to
+ thumb_reg() would be wrong. */
+ rm = reg_required_here (& mystr, 3);
+ inst.error = 0;
+
+ if (rm != FAIL)
+ {
+ /* It's BLX(2). The .instruction was zapped with rm & is final. */
+ inst.size = 2;
+ }
+ else
+ {
+ /* No ARM register. This must be BLX(1). Change the .instruction. */
+ inst.instruction = 0xf7ffeffe;
+ inst.size = 4;
+
+ if (my_get_expression (& inst.reloc.exp, & mystr))
+ return;
+
+ inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX;
+ inst.reloc.pc_rel = 1;
+ }
+
+ end_of_line (mystr);
+}
+
+/* ARM V5 breakpoint instruction (argument parse)
+ BKPT <16 bit unsigned immediate>
+ Instruction is not conditional.
+ The bit pattern given in insns[] has the COND_ALWAYS condition,
+ and it is an error if the caller tried to override that. */
+
+static void
+do_bkpt (str)
+ char * str;
+{
+ expressionS expr;
+ unsigned long number;
+
+ skip_whitespace (str);
+
+ /* Allow optional leading '#'. */
+ if (is_immediate_prefix (* str))
+ str++;
+
+ memset (& expr, '\0', sizeof (expr));
+
+ if (my_get_expression (& expr, & str)
+ || (expr.X_op != O_constant
+ /* As a convenience we allow 'bkpt' without an operand. */
+ && expr.X_op != O_absent))
+ {
+ inst.error = _("bad expression");
+ return;
+ }
+
+ number = expr.X_add_number;
+
+ /* Check it fits a 16 bit unsigned. */
+ if (number != (number & 0xffff))
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+
+ /* Top 12 of 16 bits to bits 19:8. */
+ inst.instruction |= (number & 0xfff0) << 4;
+
+ /* Bottom 4 of 16 bits to bits 3:0. */
+ inst.instruction |= number & 0xf;
+
+ end_of_line (str);
+}
+
+/* THUMB CPS instruction (argument parse). */
+
+static void
+do_t_cps (str)
+ char *str;
+{
+ do_cps_flags (&str, /*thumb_p=*/1);
+ end_of_line (str);
+}
+
+/* THUMB CPY instruction (argument parse). */
+
+static void
+do_t_cpy (str)
+ char *str;
+{
+ thumb_mov_compare (str, THUMB_CPY);
+}
+
+/* THUMB SETEND instruction (argument parse). */
+
+static void
+do_t_setend (str)
+ char *str;
+{
+ if (do_endian_specifier (str))
+ inst.instruction |= 0x8;
+}
+
+static unsigned long check_iwmmxt_insn PARAMS ((char *, enum iwmmxt_insn_type, int));
+
+/* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate. */
+
+static unsigned long
+check_iwmmxt_insn (str, insn_type, immediate_size)
+ char * str;
+ enum iwmmxt_insn_type insn_type;
+ int immediate_size;
+{
+ int reg = 0;
+ const char * inst_error;
+ expressionS expr;
+ unsigned long number;
+
+ inst_error = inst.error;
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ skip_whitespace (str);
+
+ switch (insn_type)
+ {
+ case check_rd:
+ if ((reg = reg_required_here (&str, 12)) == FAIL)
+ return FAIL;
+ break;
+
+ case check_wr:
+ if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
+ return FAIL;
+ break;
+
+ case check_wrwr:
+ if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
+ return FAIL;
+ break;
+
+ case check_wrwrwr:
+ if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
+ return FAIL;
+ break;
+
+ case check_wrwrwcg:
+ if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
+ return FAIL;
+ break;
+
+ case check_tbcst:
+ if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL))
+ return FAIL;
+ break;
+
+ case check_tmovmsk:
+ if ((reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
+ return FAIL;
+ break;
+
+ case check_tmia:
+ if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 0) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL))
+ return FAIL;
+ break;
+
+ case check_tmcrr:
+ if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 16) == FAIL))
+ return FAIL;
+ break;
+
+ case check_tmrrc:
+ if ((reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 16) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
+ return FAIL;
+ break;
+
+ case check_tmcr:
+ if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL))
+ return FAIL;
+ break;
+
+ case check_tmrc:
+ if ((reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
+ return FAIL;
+ break;
+
+ case check_tinsr:
+ if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL))
+ return FAIL;
+ break;
+
+ case check_textrc:
+ if ((reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL))
+ return FAIL;
+ break;
+
+ case check_waligni:
+ if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL))
+ return FAIL;
+ break;
+
+ case check_textrm:
+ if ((reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL))
+ return FAIL;
+ break;
+
+ case check_wshufh:
+ if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL))
+ return FAIL;
+ break;
+ }
+
+ if (immediate_size == 0)
+ {
+ end_of_line (str);
+ inst.error = inst_error;
+ return reg;
+ }
+ else
+ {
+ skip_whitespace (str);
+
+ /* Allow optional leading '#'. */
+ if (is_immediate_prefix (* str))
+ str++;
+
+ memset (& expr, '\0', sizeof (expr));
+
+ if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
+ {
+ inst.error = _("bad or missing expression");
+ return FAIL;
+ }
+
+ number = expr.X_add_number;
+
+ if (number != (number & immediate_size))
+ {
+ inst.error = _("immediate value out of range");
+ return FAIL;
+ }
+ end_of_line (str);
+ inst.error = inst_error;
+ return number;
+ }
+}
+
+static void
+do_iwmmxt_byte_addr (str)
+ char * str;
+{
+ int op = (inst.instruction & 0x300) >> 8;
+ int reg;
+
+ inst.instruction &= ~0x300;
+ inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
+
+ skip_whitespace (str);
+
+ if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || cp_byte_address_required_here (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ }
+ else
+ end_of_line (str);
+
+ if (wc_register (reg))
+ {
+ as_bad (_("non-word size not supported with control register"));
+ inst.instruction |= 0xf0000100;
+ inst.instruction &= ~0x00400000;
+ }
+}
+
+static void
+do_iwmmxt_tandc (str)
+ char * str;
+{
+ int reg;
+
+ reg = check_iwmmxt_insn (str, check_rd, 0);
+
+ if (reg != REG_PC && !inst.error)
+ inst.error = _("only r15 allowed here");
+}
+
+static void
+do_iwmmxt_tbcst (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_tbcst, 0);
+}
+
+static void
+do_iwmmxt_textrc (str)
+ char * str;
+{
+ unsigned long number;
+
+ if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
+ return;
+
+ inst.instruction |= number & 0x7;
+}
+
+static void
+do_iwmmxt_textrm (str)
+ char * str;
+{
+ unsigned long number;
+
+ if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
+ return;
+
+ inst.instruction |= number & 0x7;
+}
+
+static void
+do_iwmmxt_tinsr (str)
+ char * str;
+{
+ unsigned long number;
+
+ if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
+ return;
+
+ inst.instruction |= number & 0x7;
+}
+
+static void
+do_iwmmxt_tmcr (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_tmcr, 0);
+}
+
+static void
+do_iwmmxt_tmcrr (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_tmcrr, 0);
+}
+
+static void
+do_iwmmxt_tmia (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_tmia, 0);
+}
+
+static void
+do_iwmmxt_tmovmsk (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_tmovmsk, 0);
+}
+
+static void
+do_iwmmxt_tmrc (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_tmrc, 0);
+}
+
+static void
+do_iwmmxt_tmrrc (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_tmrrc, 0);
+}
+
+static void
+do_iwmmxt_torc (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_rd, 0);
+}
+
+static void
+do_iwmmxt_waligni (str)
+ char * str;
+{
+ unsigned long number;
+
+ if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
+ return;
+
+ inst.instruction |= ((number & 0x7) << 20);
+}
+
+static void
+do_iwmmxt_wmov (str)
+ char * str;
+{
+ if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
+ return;
+
+ inst.instruction |= ((inst.instruction >> 16) & 0xf);
+}
+
+static void
+do_iwmmxt_word_addr (str)
+ char * str;
+{
+ int op = (inst.instruction & 0x300) >> 8;
+ int reg;
+
+ inst.instruction &= ~0x300;
+ inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
+
+ skip_whitespace (str);
+
+ if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || cp_address_required_here (& str, CP_WB_OK) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ }
+ else
+ end_of_line (str);
+
+ if (wc_register (reg))
+ {
+ if ((inst.instruction & COND_MASK) != COND_ALWAYS)
+ as_bad (_("conditional execution not supported with control register"));
+ if (op != 2)
+ as_bad (_("non-word size not supported with control register"));
+ inst.instruction |= 0xf0000100;
+ inst.instruction &= ~0x00400000;
+ }
+}
+
+static void
+do_iwmmxt_wrwr (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_wrwr, 0);
+}
+
+static void
+do_iwmmxt_wrwrwcg (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_wrwrwcg, 0);
+}
+
+static void
+do_iwmmxt_wrwrwr (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_wrwrwr, 0);
+}
+
+static void
+do_iwmmxt_wshufh (str)
+ char * str;
+{
+ unsigned long number;
+
+ if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
+ return;
+
+ inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
+}
+
+static void
+do_iwmmxt_wzero (str)
+ char * str;
+{
+ if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
+ return;
+
+ inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
+}
+
+/* Xscale multiply-accumulate (argument parse)
+ MIAcc acc0,Rm,Rs
+ MIAPHcc acc0,Rm,Rs
+ MIAxycc acc0,Rm,Rs. */
+
+static void
+do_xsc_mia (str)
+ char * str;
+{
+ int rs;
+ int rm;
+
+ if (accum0_required_here (& str) == FAIL)
+ inst.error = ERR_NO_ACCUM;
+
+ else if (skip_past_comma (& str) == FAIL
+ || (rm = reg_required_here (& str, 0)) == FAIL)
+ inst.error = BAD_ARGS;
+
+ else if (skip_past_comma (& str) == FAIL
+ || (rs = reg_required_here (& str, 12)) == FAIL)
+ inst.error = BAD_ARGS;
+
+ /* inst.instruction has now been zapped with both rm and rs. */
+ else if (rm == REG_PC || rs == REG_PC)
+ inst.error = BAD_PC; /* Undefined result if rm or rs is R15. */
+
+ else
+ end_of_line (str);
+}
+
+/* Xscale move-accumulator-register (argument parse)
+
+ MARcc acc0,RdLo,RdHi. */
+
+static void
+do_xsc_mar (str)
+ char * str;
+{
+ int rdlo, rdhi;
+
+ if (accum0_required_here (& str) == FAIL)
+ inst.error = ERR_NO_ACCUM;
+
+ else if (skip_past_comma (& str) == FAIL
+ || (rdlo = reg_required_here (& str, 12)) == FAIL)
+ inst.error = BAD_ARGS;
+
+ else if (skip_past_comma (& str) == FAIL
+ || (rdhi = reg_required_here (& str, 16)) == FAIL)
+ inst.error = BAD_ARGS;
+
+ /* inst.instruction has now been zapped with both rdlo and rdhi. */
+ else if (rdlo == REG_PC || rdhi == REG_PC)
+ inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
+
+ else
+ end_of_line (str);
+}
+
+/* Xscale move-register-accumulator (argument parse)
+
+ MRAcc RdLo,RdHi,acc0. */
+
+static void
+do_xsc_mra (str)
+ char * str;
+{
+ int rdlo;
+ int rdhi;
+
+ skip_whitespace (str);
+
+ if ((rdlo = reg_required_here (& str, 12)) == FAIL)
+ inst.error = BAD_ARGS;
+
+ else if (skip_past_comma (& str) == FAIL
+ || (rdhi = reg_required_here (& str, 16)) == FAIL)
+ inst.error = BAD_ARGS;
+
+ else if (skip_past_comma (& str) == FAIL
+ || accum0_required_here (& str) == FAIL)
+ inst.error = ERR_NO_ACCUM;
+
+ /* inst.instruction has now been zapped with both rdlo and rdhi. */
+ else if (rdlo == rdhi)
+ inst.error = BAD_ARGS; /* Undefined result if 2 writes to same reg. */
+
+ else if (rdlo == REG_PC || rdhi == REG_PC)
+ inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
+ else
+ end_of_line (str);
+}
+
+/* ARMv5TE: Preload-Cache
+
+ PLD <addr_mode>
+
+ Syntactically, like LDR with B=1, W=0, L=1. */
+
+static void
+do_pld (str)
+ char * str;
+{
+ int rd;
+
+ skip_whitespace (str);
+
+ if (* str != '[')
+ {
+ inst.error = _("'[' expected after PLD mnemonic");
+ return;
+ }
+
+ ++str;
+ skip_whitespace (str);
+
+ if ((rd = reg_required_here (& str, 16)) == FAIL)
+ return;
+
+ skip_whitespace (str);
+
+ if (*str == ']')
+ {
+ /* [Rn], ... ? */
+ ++str;
+ skip_whitespace (str);
+
+ /* Post-indexed addressing is not allowed with PLD. */
+ if (skip_past_comma (&str) == SUCCESS)
+ {
+ inst.error
+ = _("post-indexed expression used in preload instruction");
+ return;
+ }
+ else if (*str == '!') /* [Rn]! */
+ {
+ inst.error = _("writeback used in preload instruction");
+ ++str;
+ }
+ else /* [Rn] */
+ inst.instruction |= INDEX_UP | PRE_INDEX;
+ }
+ else /* [Rn, ...] */
+ {
+ if (skip_past_comma (& str) == FAIL)
+ {
+ inst.error = _("pre-indexed expression expected");
+ return;
+ }
+
+ if (ldst_extend (&str) == FAIL)
+ return;
+
+ skip_whitespace (str);
+
+ if (* str != ']')
+ {
+ inst.error = _("missing ]");
+ return;
+ }
+
+ ++ str;
+ skip_whitespace (str);
+
+ if (* str == '!') /* [Rn]! */
+ {
+ inst.error = _("writeback used in preload instruction");
+ ++ str;
+ }
+
+ inst.instruction |= PRE_INDEX;
+ }
+
+ end_of_line (str);
+}
+
+/* ARMv5TE load-consecutive (argument parse)
+ Mode is like LDRH.
+
+ LDRccD R, mode
+ STRccD R, mode. */
+
+static void
+do_ldrd (str)
+ char * str;
+{
+ int rd;
+ int rn;
+
+ skip_whitespace (str);
+
+ if ((rd = reg_required_here (& str, 12)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL
+ || (rn = ld_mode_required_here (& str)) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ /* inst.instruction has now been zapped with Rd and the addressing mode. */
+ if (rd & 1) /* Unpredictable result if Rd is odd. */
+ {
+ inst.error = _("destination register must be even");
+ return;
+ }
+
+ if (rd == REG_LR)
+ {
+ inst.error = _("r14 not allowed here");
+ return;
+ }
+
+ if (((rd == rn) || (rd + 1 == rn))
+ && ((inst.instruction & WRITE_BACK)
+ || (!(inst.instruction & PRE_INDEX))))
+ as_warn (_("pre/post-indexing used when modified address register is destination"));
+
+ /* For an index-register load, the index register must not overlap the
+ destination (even if not write-back). */
+ if ((inst.instruction & V4_STR_BIT) == 0
+ && (inst.instruction & HWOFFSET_IMM) == 0)
+ {
+ int rm = inst.instruction & 0x0000000f;
+
+ if (rm == rd || (rm == rd + 1))
+ as_warn (_("ldrd destination registers must not overlap index register"));
+ }
+
+ end_of_line (str);
+}
+
+/* Returns the index into fp_values of a floating point number,
+ or -1 if not in the table. */
+
+static int
+my_get_float_expression (str)
+ char ** str;
+{
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ char * save_in;
+ expressionS exp;
+ int i;
+ int j;
+
+ memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
+
+ /* Look for a raw floating point number. */
+ if ((save_in = atof_ieee (*str, 'x', words)) != NULL
+ && is_end_of_line[(unsigned char) *save_in])
+ {
+ for (i = 0; i < NUM_FLOAT_VALS; i++)
+ {
+ for (j = 0; j < MAX_LITTLENUMS; j++)
+ {
+ if (words[j] != fp_values[i][j])
+ break;
+ }
+
+ if (j == MAX_LITTLENUMS)
+ {
+ *str = save_in;
+ return i;
+ }
+ }
+ }
+
+ /* Try and parse a more complex expression, this will probably fail
+ unless the code uses a floating point prefix (eg "0f"). */
+ save_in = input_line_pointer;
+ input_line_pointer = *str;
+ if (expression (&exp) == absolute_section
+ && exp.X_op == O_big
+ && exp.X_add_number < 0)
+ {
+ /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
+ Ditto for 15. */
+ if (gen_to_words (words, 5, (long) 15) == 0)
+ {
+ for (i = 0; i < NUM_FLOAT_VALS; i++)
+ {
+ for (j = 0; j < MAX_LITTLENUMS; j++)
+ {
+ if (words[j] != fp_values[i][j])
+ break;
+ }
+
+ if (j == MAX_LITTLENUMS)
+ {
+ *str = input_line_pointer;
+ input_line_pointer = save_in;
+ return i;
+ }
+ }
+ }
+ }
+
+ *str = input_line_pointer;
+ input_line_pointer = save_in;
+ return -1;
+}
+
+/* Return TRUE if anything in the expression is a bignum. */
+
+static int
+walk_no_bignums (sp)
+ symbolS * sp;
+{
+ if (symbol_get_value_expression (sp)->X_op == O_big)
+ return 1;
+
+ if (symbol_get_value_expression (sp)->X_add_symbol)
+ {
+ return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
+ || (symbol_get_value_expression (sp)->X_op_symbol
+ && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
+ }
+
+ return 0;
+}
+
+static int in_my_get_expression = 0;
+
+static int
+my_get_expression (ep, str)
+ expressionS * ep;
+ char ** str;
+{
+ char * save_in;
+ segT seg;
+
+ save_in = input_line_pointer;
+ input_line_pointer = *str;
+ in_my_get_expression = 1;
+ seg = expression (ep);
+ in_my_get_expression = 0;
+
+ if (ep->X_op == O_illegal)
+ {
+ /* We found a bad expression in md_operand(). */
+ *str = input_line_pointer;
+ input_line_pointer = save_in;
+ return 1;
+ }
+
+#ifdef OBJ_AOUT
+ if (seg != absolute_section
+ && seg != text_section
+ && seg != data_section
+ && seg != bss_section
+ && seg != undefined_section)
+ {
+ inst.error = _("bad_segment");
+ *str = input_line_pointer;
+ input_line_pointer = save_in;
+ return 1;
+ }
+#endif
+
+ /* Get rid of any bignums now, so that we don't generate an error for which
+ we can't establish a line number later on. Big numbers are never valid
+ in instructions, which is where this routine is always called. */
+ if (ep->X_op == O_big
+ || (ep->X_add_symbol
+ && (walk_no_bignums (ep->X_add_symbol)
+ || (ep->X_op_symbol
+ && walk_no_bignums (ep->X_op_symbol)))))
+ {
+ inst.error = _("invalid constant");
+ *str = input_line_pointer;
+ input_line_pointer = save_in;
+ return 1;
+ }
+
+ *str = input_line_pointer;
+ input_line_pointer = save_in;
+ return 0;
+}
+
+/* We handle all bad expressions here, so that we can report the faulty
+ instruction in the error message. */
+void
+md_operand (expr)
+ expressionS *expr;
+{
+ if (in_my_get_expression)
+ {
+ expr->X_op = O_illegal;
+ if (inst.error == NULL)
+ inst.error = _("bad expression");
+ }
+}
+
+/* KIND indicates what kind of shifts are accepted. */
+
+static int
+decode_shift (str, kind)
+ char ** str;
+ int kind;
+{
+ const struct asm_shift_name * shift;
+ char * p;
+ char c;
+
+ skip_whitespace (* str);
+
+ for (p = * str; ISALPHA (* p); p ++)
+ ;
+
+ if (p == * str)
+ {
+ inst.error = _("shift expression expected");
+ return FAIL;
+ }
+
+ c = * p;
+ * p = '\0';
+ shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
+ * p = c;
+
+ if (shift == NULL)
+ {
+ inst.error = _("shift expression expected");
+ return FAIL;
+ }
+
+ assert (shift->properties->index == shift_properties[shift->properties->index].index);
+
+ if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
+ && shift->properties->index != SHIFT_LSL
+ && shift->properties->index != SHIFT_ASR)
+ {
+ inst.error = _("'LSL' or 'ASR' required");
+ return FAIL;
+ }
+ else if (kind == SHIFT_LSL_IMMEDIATE
+ && shift->properties->index != SHIFT_LSL)
+ {
+ inst.error = _("'LSL' required");
+ return FAIL;
+ }
+ else if (kind == SHIFT_ASR_IMMEDIATE
+ && shift->properties->index != SHIFT_ASR)
+ {
+ inst.error = _("'ASR' required");
+ return FAIL;
+ }
+
+ if (shift->properties->index == SHIFT_RRX)
+ {
+ * str = p;
+ inst.instruction |= shift->properties->bit_field;
+ return SUCCESS;
+ }
+
+ skip_whitespace (p);
+
+ if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
+ {
+ inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
+ * str = p;
+ return SUCCESS;
+ }
+ else if (! is_immediate_prefix (* p))
+ {
+ inst.error = (NO_SHIFT_RESTRICT
+ ? _("shift requires register or #expression")
+ : _("shift requires #expression"));
+ * str = p;
+ return FAIL;
+ }
+
+ inst.error = NULL;
+ p ++;
+
+ if (my_get_expression (& inst.reloc.exp, & p))
+ return FAIL;
+
+ /* Validate some simple #expressions. */
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ unsigned num = inst.reloc.exp.X_add_number;
+
+ /* Reject operations greater than 32. */
+ if (num > 32
+ /* Reject a shift of 0 unless the mode allows it. */
+ || (num == 0 && shift->properties->allows_0 == 0)
+ /* Reject a shift of 32 unless the mode allows it. */
+ || (num == 32 && shift->properties->allows_32 == 0)
+ )
+ {
+ /* As a special case we allow a shift of zero for
+ modes that do not support it to be recoded as an
+ logical shift left of zero (ie nothing). We warn
+ about this though. */
+ if (num == 0)
+ {
+ as_warn (_("shift of 0 ignored."));
+ shift = & shift_names[0];
+ assert (shift->properties->index == SHIFT_LSL);
+ }
+ else
+ {
+ inst.error = _("invalid immediate shift");
+ return FAIL;
+ }
+ }
+
+ /* Shifts of 32 are encoded as 0, for those shifts that
+ support it. */
+ if (num == 32)
+ num = 0;
+
+ inst.instruction |= (num << 7) | shift->properties->bit_field;
+ }
+ else
+ {
+ inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
+ inst.reloc.pc_rel = 0;
+ inst.instruction |= shift->properties->bit_field;
+ }
+
+ * str = p;
+ return SUCCESS;
+}
+
+/* Do those data_ops which can take a negative immediate constant
+ by altering the instruction. A bit of a hack really.
+ MOV <-> MVN
+ AND <-> BIC
+ ADC <-> SBC
+ by inverting the second operand, and
+ ADD <-> SUB
+ CMP <-> CMN
+ by negating the second operand. */
+
+static int
+negate_data_op (instruction, value)
+ unsigned long * instruction;
+ unsigned long value;
+{
+ int op, new_inst;
+ unsigned long negated, inverted;
+
+ negated = validate_immediate (-value);
+ inverted = validate_immediate (~value);
+
+ op = (*instruction >> DATA_OP_SHIFT) & 0xf;
+ switch (op)
+ {
+ /* First negates. */
+ case OPCODE_SUB: /* ADD <-> SUB */
+ new_inst = OPCODE_ADD;
+ value = negated;
+ break;
+
+ case OPCODE_ADD:
+ new_inst = OPCODE_SUB;
+ value = negated;
+ break;
+
+ case OPCODE_CMP: /* CMP <-> CMN */
+ new_inst = OPCODE_CMN;
+ value = negated;
+ break;
+
+ case OPCODE_CMN:
+ new_inst = OPCODE_CMP;
+ value = negated;
+ break;
+
+ /* Now Inverted ops. */
+ case OPCODE_MOV: /* MOV <-> MVN */
+ new_inst = OPCODE_MVN;
+ value = inverted;
+ break;
+
+ case OPCODE_MVN:
+ new_inst = OPCODE_MOV;
+ value = inverted;
+ break;
+
+ case OPCODE_AND: /* AND <-> BIC */
+ new_inst = OPCODE_BIC;
+ value = inverted;
+ break;
+
+ case OPCODE_BIC:
+ new_inst = OPCODE_AND;
+ value = inverted;
+ break;
+
+ case OPCODE_ADC: /* ADC <-> SBC */
+ new_inst = OPCODE_SBC;
+ value = inverted;
+ break;
+
+ case OPCODE_SBC:
+ new_inst = OPCODE_ADC;
+ value = inverted;
+ break;
+
+ /* We cannot do anything. */
+ default:
+ return FAIL;
+ }
+
+ if (value == (unsigned) FAIL)
+ return FAIL;
+
+ *instruction &= OPCODE_MASK;
+ *instruction |= new_inst << DATA_OP_SHIFT;
+ return value;
+}
+
+static int
+data_op2 (str)
+ char ** str;
+{
+ int value;
+ expressionS expr;
+
+ skip_whitespace (* str);
+
+ if (reg_required_here (str, 0) != FAIL)
+ {
+ if (skip_past_comma (str) == SUCCESS)
+ /* Shift operation on register. */
+ return decode_shift (str, NO_SHIFT_RESTRICT);
+
+ return SUCCESS;
+ }
+ else
+ {
+ /* Immediate expression. */
+ if (is_immediate_prefix (**str))
+ {
+ (*str)++;
+ inst.error = NULL;
+
+ if (my_get_expression (&inst.reloc.exp, str))
+ return FAIL;
+
+ if (inst.reloc.exp.X_add_symbol)
+ {
+ inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
+ inst.reloc.pc_rel = 0;
+ }
+ else
+ {
+ if (skip_past_comma (str) == SUCCESS)
+ {
+ /* #x, y -- ie explicit rotation by Y. */
+ if (my_get_expression (&expr, str))
+ return FAIL;
+
+ if (expr.X_op != O_constant)
+ {
+ inst.error = _("constant expression expected");
+ return FAIL;
+ }
+
+ /* Rotate must be a multiple of 2. */
+ if (((unsigned) expr.X_add_number) > 30
+ || (expr.X_add_number & 1) != 0
+ || ((unsigned) inst.reloc.exp.X_add_number) > 255)
+ {
+ inst.error = _("invalid constant");
+ return FAIL;
+ }
+ inst.instruction |= INST_IMMEDIATE;
+ inst.instruction |= inst.reloc.exp.X_add_number;
+ inst.instruction |= expr.X_add_number << 7;
+ return SUCCESS;
+ }
+
+ /* Implicit rotation, select a suitable one. */
+ value = validate_immediate (inst.reloc.exp.X_add_number);
+
+ if (value == FAIL)
+ {
+ /* Can't be done. Perhaps the code reads something like
+ "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
+ if ((value = negate_data_op (&inst.instruction,
+ inst.reloc.exp.X_add_number))
+ == FAIL)
+ {
+ inst.error = _("invalid constant");
+ return FAIL;
+ }
+ }
+
+ inst.instruction |= value;
+ }
+
+ inst.instruction |= INST_IMMEDIATE;
+ return SUCCESS;
+ }
+
+ (*str)++;
+ inst.error = _("register or shift expression expected");
+ return FAIL;
+ }
+}
+
+static int
+fp_op2 (str)
+ char ** str;
+{
+ skip_whitespace (* str);
+
+ if (fp_reg_required_here (str, 0) != FAIL)
+ return SUCCESS;
+ else
+ {
+ /* Immediate expression. */
+ if (*((*str)++) == '#')
+ {
+ int i;
+
+ inst.error = NULL;
+
+ skip_whitespace (* str);
+
+ /* First try and match exact strings, this is to guarantee
+ that some formats will work even for cross assembly. */
+
+ for (i = 0; fp_const[i]; i++)
+ {
+ if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
+ {
+ char *start = *str;
+
+ *str += strlen (fp_const[i]);
+ if (is_end_of_line[(unsigned char) **str])
+ {
+ inst.instruction |= i + 8;
+ return SUCCESS;
+ }
+ *str = start;
+ }
+ }
+
+ /* Just because we didn't get a match doesn't mean that the
+ constant isn't valid, just that it is in a format that we
+ don't automatically recognize. Try parsing it with
+ the standard expression routines. */
+ if ((i = my_get_float_expression (str)) >= 0)
+ {
+ inst.instruction |= i + 8;
+ return SUCCESS;
+ }
+
+ inst.error = _("invalid floating point immediate expression");
+ return FAIL;
+ }
+ inst.error =
+ _("floating point register or immediate expression expected");
+ return FAIL;
+ }
+}
+
+static void
+do_arit (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ if (reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 16) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || data_op2 (&str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_adr (str)
+ char * str;
+{
+ /* This is a pseudo-op of the form "adr rd, label" to be converted
+ into a relative address of the form "add rd, pc, #label-.-8". */
+ skip_whitespace (str);
+
+ if (reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || my_get_expression (&inst.reloc.exp, &str))
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ /* Frag hacking will turn this into a sub instruction if the offset turns
+ out to be negative. */
+ inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
+#ifndef TE_WINCE
+ inst.reloc.exp.X_add_number -= 8; /* PC relative adjust. */
+#endif
+ inst.reloc.pc_rel = 1;
+
+ end_of_line (str);
+}
+
+static void
+do_adrl (str)
+ char * str;
+{
+ /* This is a pseudo-op of the form "adrl rd, label" to be converted
+ into a relative address of the form:
+ add rd, pc, #low(label-.-8)"
+ add rd, rd, #high(label-.-8)" */
+
+ skip_whitespace (str);
+
+ if (reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || my_get_expression (&inst.reloc.exp, &str))
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+
+ return;
+ }
+
+ end_of_line (str);
+ /* Frag hacking will turn this into a sub instruction if the offset turns
+ out to be negative. */
+ inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
+#ifndef TE_WINCE
+ inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
+#endif
+ inst.reloc.pc_rel = 1;
+ inst.size = INSN_SIZE * 2;
+}
+
+static void
+do_cmp (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ if (reg_required_here (&str, 16) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || data_op2 (&str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_mov (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ if (reg_required_here (&str, 12) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || data_op2 (&str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static int
+ldst_extend (str)
+ char ** str;
+{
+ int add = INDEX_UP;
+
+ switch (**str)
+ {
+ case '#':
+ case '$':
+ (*str)++;
+ if (my_get_expression (& inst.reloc.exp, str))
+ return FAIL;
+
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ int value = inst.reloc.exp.X_add_number;
+
+ if (value < -4095 || value > 4095)
+ {
+ inst.error = _("address offset too large");
+ return FAIL;
+ }
+
+ if (value < 0)
+ {
+ value = -value;
+ add = 0;
+ }
+
+ inst.instruction |= add | value;
+ }
+ else
+ {
+ inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
+ inst.reloc.pc_rel = 0;
+ }
+ return SUCCESS;
+
+ case '-':
+ add = 0;
+ /* Fall through. */
+
+ case '+':
+ (*str)++;
+ /* Fall through. */
+
+ default:
+ if (reg_required_here (str, 0) == FAIL)
+ return FAIL;
+
+ inst.instruction |= add | OFFSET_REG;
+ if (skip_past_comma (str) == SUCCESS)
+ return decode_shift (str, SHIFT_IMMEDIATE);
+
+ return SUCCESS;
+ }
+}
+
+static void
+do_ldst (str)
+ char * str;
+{
+ int pre_inc = 0;
+ int conflict_reg;
+ int value;
+
+ skip_whitespace (str);
+
+ if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL)
+ {
+ inst.error = _("address expected");
+ return;
+ }
+
+ if (*str == '[')
+ {
+ int reg;
+
+ str++;
+
+ skip_whitespace (str);
+
+ if ((reg = reg_required_here (&str, 16)) == FAIL)
+ return;
+
+ /* Conflicts can occur on stores as well as loads. */
+ conflict_reg = (conflict_reg == reg);
+
+ skip_whitespace (str);
+
+ if (*str == ']')
+ {
+ str ++;
+
+ if (skip_past_comma (&str) == SUCCESS)
+ {
+ /* [Rn],... (post inc) */
+ if (ldst_extend (&str) == FAIL)
+ return;
+ if (conflict_reg)
+ as_warn (_("%s register same as write-back base"),
+ ((inst.instruction & LOAD_BIT)
+ ? _("destination") : _("source")));
+ }
+ else
+ {
+ /* [Rn] */
+ skip_whitespace (str);
+
+ if (*str == '!')
+ {
+ if (conflict_reg)
+ as_warn (_("%s register same as write-back base"),
+ ((inst.instruction & LOAD_BIT)
+ ? _("destination") : _("source")));
+ str++;
+ inst.instruction |= WRITE_BACK;
+ }
+
+ inst.instruction |= INDEX_UP;
+ pre_inc = 1;
+ }
+ }
+ else
+ {
+ /* [Rn,...] */
+ if (skip_past_comma (&str) == FAIL)
+ {
+ inst.error = _("pre-indexed expression expected");
+ return;
+ }
+
+ pre_inc = 1;
+ if (ldst_extend (&str) == FAIL)
+ return;
+
+ skip_whitespace (str);
+
+ if (*str++ != ']')
+ {
+ inst.error = _("missing ]");
+ return;
+ }
+
+ skip_whitespace (str);
+
+ if (*str == '!')
+ {
+ if (conflict_reg)
+ as_warn (_("%s register same as write-back base"),
+ ((inst.instruction & LOAD_BIT)
+ ? _("destination") : _("source")));
+ str++;
+ inst.instruction |= WRITE_BACK;
+ }
+ }
+ }
+ else if (*str == '=')
+ {
+ if ((inst.instruction & LOAD_BIT) == 0)
+ {
+ inst.error = _("invalid pseudo operation");
+ return;
+ }
+
+ /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
+ str++;
+
+ skip_whitespace (str);
+
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+
+ if (inst.reloc.exp.X_op != O_constant
+ && inst.reloc.exp.X_op != O_symbol)
+ {
+ inst.error = _("constant expression expected");
+ return;
+ }
+
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ value = validate_immediate (inst.reloc.exp.X_add_number);
+
+ if (value != FAIL)
+ {
+ /* This can be done with a mov instruction. */
+ inst.instruction &= LITERAL_MASK;
+ inst.instruction |= (INST_IMMEDIATE
+ | (OPCODE_MOV << DATA_OP_SHIFT));
+ inst.instruction |= value & 0xfff;
+ end_of_line (str);
+ return;
+ }
+
+ value = validate_immediate (~inst.reloc.exp.X_add_number);
+
+ if (value != FAIL)
+ {
+ /* This can be done with a mvn instruction. */
+ inst.instruction &= LITERAL_MASK;
+ inst.instruction |= (INST_IMMEDIATE
+ | (OPCODE_MVN << DATA_OP_SHIFT));
+ inst.instruction |= value & 0xfff;
+ end_of_line (str);
+ return;
+ }
+ }
+
+ /* Insert into literal pool. */
+ if (add_to_lit_pool () == FAIL)
+ {
+ if (!inst.error)
+ inst.error = _("literal pool insertion failed");
+ return;
+ }
+
+ /* Change the instruction exp to point to the pool. */
+ inst.reloc.type = BFD_RELOC_ARM_LITERAL;
+ inst.reloc.pc_rel = 1;
+ inst.instruction |= (REG_PC << 16);
+ pre_inc = 1;
+ }
+ else
+ {
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+
+ inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
+#ifndef TE_WINCE
+ /* PC rel adjust. */
+ inst.reloc.exp.X_add_number -= 8;
+#endif
+ inst.reloc.pc_rel = 1;
+ inst.instruction |= (REG_PC << 16);
+ pre_inc = 1;
+ }
+
+ inst.instruction |= (pre_inc ? PRE_INDEX : 0);
+ end_of_line (str);
+}
+
+static void
+do_ldstt (str)
+ char * str;
+{
+ int conflict_reg;
+
+ skip_whitespace (str);
+
+ if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL)
+ {
+ inst.error = _("address expected");
+ return;
+ }
+
+ if (*str == '[')
+ {
+ int reg;
+
+ str++;
+
+ skip_whitespace (str);
+
+ if ((reg = reg_required_here (&str, 16)) == FAIL)
+ return;
+
+ /* ldrt/strt always use post-indexed addressing, so if the base is
+ the same as Rd, we warn. */
+ if (conflict_reg == reg)
+ as_warn (_("%s register same as write-back base"),
+ ((inst.instruction & LOAD_BIT)
+ ? _("destination") : _("source")));
+
+ skip_whitespace (str);
+
+ if (*str == ']')
+ {
+ str ++;
+
+ if (skip_past_comma (&str) == SUCCESS)
+ {
+ /* [Rn],... (post inc) */
+ if (ldst_extend (&str) == FAIL)
+ return;
+ }
+ else
+ {
+ /* [Rn] */
+ skip_whitespace (str);
+
+ /* Skip a write-back '!'. */
+ if (*str == '!')
+ str++;
+
+ inst.instruction |= INDEX_UP;
+ }
+ }
+ else
+ {
+ inst.error = _("post-indexed expression expected");
+ return;
+ }
+ }
+ else
+ {
+ inst.error = _("post-indexed expression expected");
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static int
+ldst_extend_v4 (str)
+ char ** str;
+{
+ int add = INDEX_UP;
+
+ switch (**str)
+ {
+ case '#':
+ case '$':
+ (*str)++;
+ if (my_get_expression (& inst.reloc.exp, str))
+ return FAIL;
+
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ int value = inst.reloc.exp.X_add_number;
+
+ if (value < -255 || value > 255)
+ {
+ inst.error = _("address offset too large");
+ return FAIL;
+ }
+
+ if (value < 0)
+ {
+ value = -value;
+ add = 0;
+ }
+
+ /* Halfword and signextension instructions have the
+ immediate value split across bits 11..8 and bits 3..0. */
+ inst.instruction |= (add | HWOFFSET_IMM
+ | ((value >> 4) << 8) | (value & 0xF));
+ }
+ else
+ {
+ inst.instruction |= HWOFFSET_IMM;
+ inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
+ inst.reloc.pc_rel = 0;
+ }
+ return SUCCESS;
+
+ case '-':
+ add = 0;
+ /* Fall through. */
+
+ case '+':
+ (*str)++;
+ /* Fall through. */
+
+ default:
+ if (reg_required_here (str, 0) == FAIL)
+ return FAIL;
+
+ inst.instruction |= add;
+ return SUCCESS;
+ }
+}
+
+/* Halfword and signed-byte load/store operations. */
+static void
+do_ldstv4 (str)
+ char * str;
+{
+ int pre_inc = 0;
+ int conflict_reg;
+ int value;
+
+ skip_whitespace (str);
+
+ if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL)
+ {
+ inst.error = _("address expected");
+ return;
+ }
+
+ if (*str == '[')
+ {
+ int reg;
+
+ str++;
+
+ skip_whitespace (str);
+
+ if ((reg = reg_required_here (&str, 16)) == FAIL)
+ return;
+
+ /* Conflicts can occur on stores as well as loads. */
+ conflict_reg = (conflict_reg == reg);
+
+ skip_whitespace (str);
+
+ if (*str == ']')
+ {
+ str ++;
+
+ if (skip_past_comma (&str) == SUCCESS)
+ {
+ /* [Rn],... (post inc) */
+ if (ldst_extend_v4 (&str) == FAIL)
+ return;
+ if (conflict_reg)
+ as_warn (_("%s register same as write-back base"),
+ ((inst.instruction & LOAD_BIT)
+ ? _("destination") : _("source")));
+ }
+ else
+ {
+ /* [Rn] */
+ inst.instruction |= HWOFFSET_IMM;
+
+ skip_whitespace (str);
+
+ if (*str == '!')
+ {
+ if (conflict_reg)
+ as_warn (_("%s register same as write-back base"),
+ ((inst.instruction & LOAD_BIT)
+ ? _("destination") : _("source")));
+ str++;
+ inst.instruction |= WRITE_BACK;
+ }
+
+ inst.instruction |= INDEX_UP;
+ pre_inc = 1;
+ }
+ }
+ else
+ {
+ /* [Rn,...] */
+ if (skip_past_comma (&str) == FAIL)
+ {
+ inst.error = _("pre-indexed expression expected");
+ return;
+ }
+
+ pre_inc = 1;
+ if (ldst_extend_v4 (&str) == FAIL)
+ return;
+
+ skip_whitespace (str);
+
+ if (*str++ != ']')
+ {
+ inst.error = _("missing ]");
+ return;
+ }
+
+ skip_whitespace (str);
+
+ if (*str == '!')
+ {
+ if (conflict_reg)
+ as_warn (_("%s register same as write-back base"),
+ ((inst.instruction & LOAD_BIT)
+ ? _("destination") : _("source")));
+ str++;
+ inst.instruction |= WRITE_BACK;
+ }
+ }
+ }
+ else if (*str == '=')
+ {
+ if ((inst.instruction & LOAD_BIT) == 0)
+ {
+ inst.error = _("invalid pseudo operation");
+ return;
+ }
+
+ /* XXX Does this work correctly for half-word/byte ops? */
+ /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
+ str++;
+
+ skip_whitespace (str);
+
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+
+ if (inst.reloc.exp.X_op != O_constant
+ && inst.reloc.exp.X_op != O_symbol)
+ {
+ inst.error = _("constant expression expected");
+ return;
+ }
+
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ value = validate_immediate (inst.reloc.exp.X_add_number);
+
+ if (value != FAIL)
+ {
+ /* This can be done with a mov instruction. */
+ inst.instruction &= LITERAL_MASK;
+ inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
+ inst.instruction |= value & 0xfff;
+ end_of_line (str);
+ return;
+ }
+
+ value = validate_immediate (~ inst.reloc.exp.X_add_number);
+
+ if (value != FAIL)
+ {
+ /* This can be done with a mvn instruction. */
+ inst.instruction &= LITERAL_MASK;
+ inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
+ inst.instruction |= value & 0xfff;
+ end_of_line (str);
+ return;
+ }
+ }
+
+ /* Insert into literal pool. */
+ if (add_to_lit_pool () == FAIL)
+ {
+ if (!inst.error)
+ inst.error = _("literal pool insertion failed");
+ return;
+ }
+
+ /* Change the instruction exp to point to the pool. */
+ inst.instruction |= HWOFFSET_IMM;
+ inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
+ inst.reloc.pc_rel = 1;
+ inst.instruction |= (REG_PC << 16);
+ pre_inc = 1;
+ }
+ else
+ {
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+
+ inst.instruction |= HWOFFSET_IMM;
+ inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
+#ifndef TE_WINCE
+ /* PC rel adjust. */
+ inst.reloc.exp.X_add_number -= 8;
+#endif
+ inst.reloc.pc_rel = 1;
+ inst.instruction |= (REG_PC << 16);
+ pre_inc = 1;
+ }
+
+ inst.instruction |= (pre_inc ? PRE_INDEX : 0);
+ end_of_line (str);
+}
+
+static long
+reg_list (strp)
+ char ** strp;
+{
+ char * str = * strp;
+ long range = 0;
+ int another_range;
+
+ /* We come back here if we get ranges concatenated by '+' or '|'. */
+ do
+ {
+ another_range = 0;
+
+ if (*str == '{')
+ {
+ int in_range = 0;
+ int cur_reg = -1;
+
+ str++;
+ do
+ {
+ int reg;
+
+ skip_whitespace (str);
+
+ if ((reg = reg_required_here (& str, -1)) == FAIL)
+ return FAIL;
+
+ if (in_range)
+ {
+ int i;
+
+ if (reg <= cur_reg)
+ {
+ inst.error = _("bad range in register list");
+ return FAIL;
+ }
+
+ for (i = cur_reg + 1; i < reg; i++)
+ {
+ if (range & (1 << i))
+ as_tsktsk
+ (_("Warning: duplicated register (r%d) in register list"),
+ i);
+ else
+ range |= 1 << i;
+ }
+ in_range = 0;
+ }
+
+ if (range & (1 << reg))
+ as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
+ reg);
+ else if (reg <= cur_reg)
+ as_tsktsk (_("Warning: register range not in ascending order"));
+
+ range |= 1 << reg;
+ cur_reg = reg;
+ }
+ while (skip_past_comma (&str) != FAIL
+ || (in_range = 1, *str++ == '-'));
+ str--;
+ skip_whitespace (str);
+
+ if (*str++ != '}')
+ {
+ inst.error = _("missing `}'");
+ return FAIL;
+ }
+ }
+ else
+ {
+ expressionS expr;
+
+ if (my_get_expression (&expr, &str))
+ return FAIL;
+
+ if (expr.X_op == O_constant)
+ {
+ if (expr.X_add_number
+ != (expr.X_add_number & 0x0000ffff))
+ {
+ inst.error = _("invalid register mask");
+ return FAIL;
+ }
+
+ if ((range & expr.X_add_number) != 0)
+ {
+ int regno = range & expr.X_add_number;
+
+ regno &= -regno;
+ regno = (1 << regno) - 1;
+ as_tsktsk
+ (_("Warning: duplicated register (r%d) in register list"),
+ regno);
+ }
+
+ range |= expr.X_add_number;
+ }
+ else
+ {
+ if (inst.reloc.type != 0)
+ {
+ inst.error = _("expression too complex");
+ return FAIL;
+ }
+
+ memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
+ inst.reloc.type = BFD_RELOC_ARM_MULTI;
+ inst.reloc.pc_rel = 0;
+ }
+ }
+
+ skip_whitespace (str);
+
+ if (*str == '|' || *str == '+')
+ {
+ str++;
+ another_range = 1;
+ }
+ }
+ while (another_range);
+
+ *strp = str;
+ return range;
+}
+
+static void
+do_ldmstm (str)
+ char * str;
+{
+ int base_reg;
+ long range;
+
+ skip_whitespace (str);
+
+ if ((base_reg = reg_required_here (&str, 16)) == FAIL)
+ return;
+
+ if (base_reg == REG_PC)
+ {
+ inst.error = _("r15 not allowed as base register");
+ return;
+ }
+
+ skip_whitespace (str);
+
+ if (*str == '!')
+ {
+ inst.instruction |= WRITE_BACK;
+ str++;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || (range = reg_list (&str)) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (*str == '^')
+ {
+ str++;
+ inst.instruction |= LDM_TYPE_2_OR_3;
+ }
+
+ if (inst.instruction & WRITE_BACK)
+ {
+ /* Check for unpredictable uses of writeback. */
+ if (inst.instruction & LOAD_BIT)
+ {
+ /* Not allowed in LDM type 2. */
+ if ((inst.instruction & LDM_TYPE_2_OR_3)
+ && ((range & (1 << REG_PC)) == 0))
+ as_warn (_("writeback of base register is UNPREDICTABLE"));
+ /* Only allowed if base reg not in list for other types. */
+ else if (range & (1 << base_reg))
+ as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
+ }
+ else /* STM. */
+ {
+ /* Not allowed for type 2. */
+ if (inst.instruction & LDM_TYPE_2_OR_3)
+ as_warn (_("writeback of base register is UNPREDICTABLE"));
+ /* Only allowed if base reg not in list, or first in list. */
+ else if ((range & (1 << base_reg))
+ && (range & ((1 << base_reg) - 1)))
+ as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
+ }
+ }
+
+ inst.instruction |= range;
+ end_of_line (str);
+}
+
+static void
+do_swi (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ /* Allow optional leading '#'. */
+ if (is_immediate_prefix (*str))
+ str++;
+
+ if (my_get_expression (& inst.reloc.exp, & str))
+ return;
+
+ inst.reloc.type = BFD_RELOC_ARM_SWI;
+ inst.reloc.pc_rel = 0;
+ end_of_line (str);
+}
+
+static void
+do_swap (str)
+ char * str;
+{
+ int reg;
+
+ skip_whitespace (str);
+
+ if ((reg = reg_required_here (&str, 12)) == FAIL)
+ return;
+
+ if (reg == REG_PC)
+ {
+ inst.error = _("r15 not allowed in swap");
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || (reg = reg_required_here (&str, 0)) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (reg == REG_PC)
+ {
+ inst.error = _("r15 not allowed in swap");
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || *str++ != '[')
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ skip_whitespace (str);
+
+ if ((reg = reg_required_here (&str, 16)) == FAIL)
+ return;
+
+ if (reg == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ skip_whitespace (str);
+
+ if (*str++ != ']')
+ {
+ inst.error = _("missing ]");
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_branch (str)
+ char * str;
+{
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+
+#ifdef OBJ_ELF
+ {
+ char * save_in;
+
+ /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
+ required for the instruction. */
+
+ /* arm_parse_reloc () works on input_line_pointer.
+ We actually want to parse the operands to the branch instruction
+ passed in 'str'. Save the input pointer and restore it later. */
+ save_in = input_line_pointer;
+ input_line_pointer = str;
+ if (inst.reloc.exp.X_op == O_symbol
+ && *str == '('
+ && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
+ {
+ inst.reloc.type = BFD_RELOC_ARM_PLT32;
+ inst.reloc.pc_rel = 0;
+ /* Modify str to point to after parsed operands, otherwise
+ end_of_line() will complain about the (PLT) left in str. */
+ str = input_line_pointer;
+ }
+ else
+ {
+ inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
+ inst.reloc.pc_rel = 1;
+ }
+ input_line_pointer = save_in;
+ }
+#else
+ inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
+ inst.reloc.pc_rel = 1;
+#endif /* OBJ_ELF */
+
+ end_of_line (str);
+}
+
+static void
+do_bx (str)
+ char * str;
+{
+ int reg;
+
+ skip_whitespace (str);
+
+ if ((reg = reg_required_here (&str, 0)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
+ if (reg == REG_PC)
+ as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
+
+ end_of_line (str);
+}
+
+static void
+do_cdp (str)
+ char * str;
+{
+ /* Co-processor data operation.
+ Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
+ skip_whitespace (str);
+
+ if (co_proc_number (&str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_opc_expr (&str, 20,4) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_reg_required_here (&str, 12) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_reg_required_here (&str, 16) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_reg_required_here (&str, 0) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == SUCCESS)
+ {
+ if (cp_opc_expr (&str, 5, 3) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_lstc (str)
+ char * str;
+{
+ /* Co-processor register load/store.
+ Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
+
+ skip_whitespace (str);
+
+ if (co_proc_number (&str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_reg_required_here (&str, 12) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_address_required_here (&str, CP_WB_OK) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_co_reg (str)
+ char * str;
+{
+ /* Co-processor register transfer.
+ Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
+
+ skip_whitespace (str);
+
+ if (co_proc_number (&str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_opc_expr (&str, 21, 3) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_reg_required_here (&str, 16) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_reg_required_here (&str, 0) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == SUCCESS)
+ {
+ if (cp_opc_expr (&str, 5, 3) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_fpa_ctrl (str)
+ char * str;
+{
+ /* FP control registers.
+ Format: <WFS|RFS|WFC|RFC>{cond} Rn */
+
+ skip_whitespace (str);
+
+ if (reg_required_here (&str, 12) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_fpa_ldst (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ if (fp_reg_required_here (&str, 12) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_address_required_here (&str, CP_WB_OK) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_fpa_ldmstm (str)
+ char * str;
+{
+ int num_regs;
+
+ skip_whitespace (str);
+
+ if (fp_reg_required_here (&str, 12) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ /* Get Number of registers to transfer. */
+ if (skip_past_comma (&str) == FAIL
+ || my_get_expression (&inst.reloc.exp, &str))
+ {
+ if (! inst.error)
+ inst.error = _("constant expression expected");
+ return;
+ }
+
+ if (inst.reloc.exp.X_op != O_constant)
+ {
+ inst.error = _("constant value required for number of registers");
+ return;
+ }
+
+ num_regs = inst.reloc.exp.X_add_number;
+
+ if (num_regs < 1 || num_regs > 4)
+ {
+ inst.error = _("number of registers must be in the range [1:4]");
+ return;
+ }
+
+ switch (num_regs)
+ {
+ case 1:
+ inst.instruction |= CP_T_X;
+ break;
+ case 2:
+ inst.instruction |= CP_T_Y;
+ break;
+ case 3:
+ inst.instruction |= CP_T_Y | CP_T_X;
+ break;
+ case 4:
+ break;
+ default:
+ abort ();
+ }
+
+ if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format. */
+ {
+ int reg;
+ int write_back;
+ int offset;
+
+ /* The instruction specified "ea" or "fd", so we can only accept
+ [Rn]{!}. The instruction does not really support stacking or
+ unstacking, so we have to emulate these by setting appropriate
+ bits and offsets. */
+ if (skip_past_comma (&str) == FAIL
+ || *str != '[')
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ str++;
+ skip_whitespace (str);
+
+ if ((reg = reg_required_here (&str, 16)) == FAIL)
+ return;
+
+ skip_whitespace (str);
+
+ if (*str != ']')
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ str++;
+ if (*str == '!')
+ {
+ write_back = 1;
+ str++;
+ if (reg == REG_PC)
+ {
+ inst.error =
+ _("r15 not allowed as base register with write-back");
+ return;
+ }
+ }
+ else
+ write_back = 0;
+
+ if (inst.instruction & CP_T_Pre)
+ {
+ /* Pre-decrement. */
+ offset = 3 * num_regs;
+ if (write_back)
+ inst.instruction |= CP_T_WB;
+ }
+ else
+ {
+ /* Post-increment. */
+ if (write_back)
+ {
+ inst.instruction |= CP_T_WB;
+ offset = 3 * num_regs;
+ }
+ else
+ {
+ /* No write-back, so convert this into a standard pre-increment
+ instruction -- aesthetically more pleasing. */
+ inst.instruction |= CP_T_Pre | CP_T_UD;
+ offset = 0;
+ }
+ }
+
+ inst.instruction |= offset;
+ }
+ else if (skip_past_comma (&str) == FAIL
+ || cp_address_required_here (&str, CP_WB_OK) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_fpa_dyadic (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ if (fp_reg_required_here (&str, 12) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || fp_reg_required_here (&str, 16) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || fp_op2 (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_fpa_monadic (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ if (fp_reg_required_here (&str, 12) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || fp_op2 (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_fpa_cmp (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ if (fp_reg_required_here (&str, 16) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || fp_op2 (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_fpa_from_reg (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ if (fp_reg_required_here (&str, 16) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_fpa_to_reg (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ if (reg_required_here (&str, 12) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || fp_reg_required_here (&str, 0) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static int
+vfp_sp_reg_required_here (str, pos)
+ char **str;
+ enum vfp_sp_reg_pos pos;
+{
+ int reg;
+ char *start = *str;
+
+ if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
+ {
+ switch (pos)
+ {
+ case VFP_REG_Sd:
+ inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
+ break;
+
+ case VFP_REG_Sn:
+ inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
+ break;
+
+ case VFP_REG_Sm:
+ inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
+ break;
+
+ default:
+ abort ();
+ }
+ return reg;
+ }
+
+ /* In the few cases where we might be able to accept something else
+ this error can be overridden. */
+ inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
+
+ /* Restore the start point. */
+ *str = start;
+ return FAIL;
+}
+
+static int
+vfp_dp_reg_required_here (str, pos)
+ char **str;
+ enum vfp_dp_reg_pos pos;
+{
+ int reg;
+ char *start = *str;
+
+ if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
+ {
+ switch (pos)
+ {
+ case VFP_REG_Dd:
+ inst.instruction |= reg << 12;
+ break;
+
+ case VFP_REG_Dn:
+ inst.instruction |= reg << 16;
+ break;
+
+ case VFP_REG_Dm:
+ inst.instruction |= reg << 0;
+ break;
+
+ default:
+ abort ();
+ }
+ return reg;
+ }
+
+ /* In the few cases where we might be able to accept something else
+ this error can be overridden. */
+ inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
+
+ /* Restore the start point. */
+ *str = start;
+ return FAIL;
+}
+
+static void
+do_vfp_sp_monadic (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_dp_monadic (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_sp_dyadic (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_dp_dyadic (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_reg_from_sp (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (reg_required_here (&str, 12) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_reg2_from_sp2 (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 16) == FAIL
+ || skip_past_comma (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ /* We require exactly two consecutive SP registers. */
+ if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
+ {
+ if (! inst.error)
+ inst.error = _("only two consecutive VFP SP registers allowed here");
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_sp_from_reg (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_sp2_from_reg2 (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ /* We require exactly two consecutive SP registers. */
+ if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
+ {
+ if (! inst.error)
+ inst.error = _("only two consecutive VFP SP registers allowed here");
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 16) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_reg_from_dp (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (reg_required_here (&str, 12) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_reg2_from_dp (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (reg_required_here (&str, 12) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 16) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_dp_from_reg (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_dp_from_reg2 (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 16) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static const struct vfp_reg *
+vfp_psr_parse (str)
+ char **str;
+{
+ char *start = *str;
+ char c;
+ char *p;
+ const struct vfp_reg *vreg;
+
+ p = start;
+
+ /* Find the end of the current token. */
+ do
+ {
+ c = *p++;
+ }
+ while (ISALPHA (c));
+
+ /* Mark it. */
+ *--p = 0;
+
+ for (vreg = vfp_regs + 0;
+ vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
+ vreg++)
+ {
+ if (strcmp (start, vreg->name) == 0)
+ {
+ *p = c;
+ *str = p;
+ return vreg;
+ }
+ }
+
+ *p = c;
+ return NULL;
+}
+
+static int
+vfp_psr_required_here (str)
+ char **str;
+{
+ char *start = *str;
+ const struct vfp_reg *vreg;
+
+ vreg = vfp_psr_parse (str);
+
+ if (vreg)
+ {
+ inst.instruction |= vreg->regno;
+ return SUCCESS;
+ }
+
+ inst.error = _("VFP system register expected");
+
+ *str = start;
+ return FAIL;
+}
+
+static void
+do_vfp_reg_from_ctrl (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (reg_required_here (&str, 12) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || vfp_psr_required_here (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_ctrl_from_reg (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (vfp_psr_required_here (&str) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_sp_ldst (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_address_required_here (&str, CP_NO_WB) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_dp_ldst (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_address_required_here (&str, CP_NO_WB) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+/* Parse and encode a VFP SP register list, storing the initial
+ register in position POS and returning the range as the result. If
+ the string is invalid return FAIL (an invalid range). */
+static long
+vfp_sp_reg_list (str, pos)
+ char **str;
+ enum vfp_sp_reg_pos pos;
+{
+ long range = 0;
+ int base_reg = 0;
+ int new_base;
+ long base_bits = 0;
+ int count = 0;
+ long tempinst;
+ unsigned long mask = 0;
+ int warned = 0;
+
+ if (**str != '{')
+ return FAIL;
+
+ (*str)++;
+ skip_whitespace (*str);
+
+ tempinst = inst.instruction;
+
+ do
+ {
+ inst.instruction = 0;
+
+ if ((new_base = vfp_sp_reg_required_here (str, pos)) == FAIL)
+ return FAIL;
+
+ if (count == 0 || base_reg > new_base)
+ {
+ base_reg = new_base;
+ base_bits = inst.instruction;
+ }
+
+ if (mask & (1 << new_base))
+ {
+ inst.error = _("invalid register list");
+ return FAIL;
+ }
+
+ if ((mask >> new_base) != 0 && ! warned)
+ {
+ as_tsktsk (_("register list not in ascending order"));
+ warned = 1;
+ }
+
+ mask |= 1 << new_base;
+ count++;
+
+ skip_whitespace (*str);
+
+ if (**str == '-') /* We have the start of a range expression */
+ {
+ int high_range;
+
+ (*str)++;
+
+ if ((high_range
+ = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab))
+ == FAIL)
+ {
+ inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
+ return FAIL;
+ }
+
+ if (high_range <= new_base)
+ {
+ inst.error = _("register range not in ascending order");
+ return FAIL;
+ }
+
+ for (new_base++; new_base <= high_range; new_base++)
+ {
+ if (mask & (1 << new_base))
+ {
+ inst.error = _("invalid register list");
+ return FAIL;
+ }
+
+ mask |= 1 << new_base;
+ count++;
+ }
+ }
+ }
+ while (skip_past_comma (str) != FAIL);
+
+ if (**str != '}')
+ {
+ inst.error = _("invalid register list");
+ return FAIL;
+ }
+
+ (*str)++;
+
+ range = count;
+
+ /* Sanity check -- should have raised a parse error above. */
+ if (count == 0 || count > 32)
+ abort ();
+
+ /* Final test -- the registers must be consecutive. */
+ while (count--)
+ {
+ if ((mask & (1 << base_reg++)) == 0)
+ {
+ inst.error = _("non-contiguous register range");
+ return FAIL;
+ }
+ }
+
+ inst.instruction = tempinst | base_bits;
+ return range;
+}
+
+static long
+vfp_dp_reg_list (str)
+ char **str;
+{
+ long range = 0;
+ int base_reg = 0;
+ int new_base;
+ int count = 0;
+ long tempinst;
+ unsigned long mask = 0;
+ int warned = 0;
+
+ if (**str != '{')
+ return FAIL;
+
+ (*str)++;
+ skip_whitespace (*str);
+
+ tempinst = inst.instruction;
+
+ do
+ {
+ inst.instruction = 0;
+
+ if ((new_base = vfp_dp_reg_required_here (str, VFP_REG_Dd)) == FAIL)
+ return FAIL;
+
+ if (count == 0 || base_reg > new_base)
+ {
+ base_reg = new_base;
+ range = inst.instruction;
+ }
+
+ if (mask & (1 << new_base))
+ {
+ inst.error = _("invalid register list");
+ return FAIL;
+ }
+
+ if ((mask >> new_base) != 0 && ! warned)
+ {
+ as_tsktsk (_("register list not in ascending order"));
+ warned = 1;
+ }
+
+ mask |= 1 << new_base;
+ count++;
+
+ skip_whitespace (*str);
+
+ if (**str == '-') /* We have the start of a range expression */
+ {
+ int high_range;
+
+ (*str)++;
+
+ if ((high_range
+ = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab))
+ == FAIL)
+ {
+ inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
+ return FAIL;
+ }
+
+ if (high_range <= new_base)
+ {
+ inst.error = _("register range not in ascending order");
+ return FAIL;
+ }
+
+ for (new_base++; new_base <= high_range; new_base++)
+ {
+ if (mask & (1 << new_base))
+ {
+ inst.error = _("invalid register list");
+ return FAIL;
+ }
+
+ mask |= 1 << new_base;
+ count++;
+ }
+ }
+ }
+ while (skip_past_comma (str) != FAIL);
+
+ if (**str != '}')
+ {
+ inst.error = _("invalid register list");
+ return FAIL;
+ }
+
+ (*str)++;
+
+ range |= 2 * count;
+
+ /* Sanity check -- should have raised a parse error above. */
+ if (count == 0 || count > 16)
+ abort ();
+
+ /* Final test -- the registers must be consecutive. */
+ while (count--)
+ {
+ if ((mask & (1 << base_reg++)) == 0)
+ {
+ inst.error = _("non-contiguous register range");
+ return FAIL;
+ }
+ }
+
+ inst.instruction = tempinst;
+ return range;
+}
+
+static void
+vfp_sp_ldstm (str, ldstm_type)
+ char *str;
+ enum vfp_ldstm_type ldstm_type;
+{
+ long range;
+
+ skip_whitespace (str);
+
+ if (reg_required_here (&str, 16) == FAIL)
+ return;
+
+ skip_whitespace (str);
+
+ if (*str == '!')
+ {
+ inst.instruction |= WRITE_BACK;
+ str++;
+ }
+ else if (ldstm_type != VFP_LDSTMIA)
+ {
+ inst.error = _("this addressing mode requires base-register writeback");
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || (range = vfp_sp_reg_list (&str, VFP_REG_Sd)) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ inst.instruction |= range;
+ end_of_line (str);
+}
+
+static void
+vfp_dp_ldstm (str, ldstm_type)
+ char *str;
+ enum vfp_ldstm_type ldstm_type;
+{
+ long range;
+
+ skip_whitespace (str);
+
+ if (reg_required_here (&str, 16) == FAIL)
+ return;
+
+ skip_whitespace (str);
+
+ if (*str == '!')
+ {
+ inst.instruction |= WRITE_BACK;
+ str++;
+ }
+ else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
+ {
+ inst.error = _("this addressing mode requires base-register writeback");
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || (range = vfp_dp_reg_list (&str)) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
+ range += 1;
+
+ inst.instruction |= range;
+ end_of_line (str);
+}
+
+static void
+do_vfp_sp_ldstmia (str)
+ char *str;
+{
+ vfp_sp_ldstm (str, VFP_LDSTMIA);
+}
+
+static void
+do_vfp_sp_ldstmdb (str)
+ char *str;
+{
+ vfp_sp_ldstm (str, VFP_LDSTMDB);
+}
+
+static void
+do_vfp_dp_ldstmia (str)
+ char *str;
+{
+ vfp_dp_ldstm (str, VFP_LDSTMIA);
+}
+
+static void
+do_vfp_dp_ldstmdb (str)
+ char *str;
+{
+ vfp_dp_ldstm (str, VFP_LDSTMDB);
+}
+
+static void
+do_vfp_xp_ldstmia (str)
+ char *str;
+{
+ vfp_dp_ldstm (str, VFP_LDSTMIAX);
+}
+
+static void
+do_vfp_xp_ldstmdb (str)
+ char *str;
+{
+ vfp_dp_ldstm (str, VFP_LDSTMDBX);
+}
+
+static void
+do_vfp_sp_compare_z (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_dp_compare_z (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_dp_sp_cvt (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_vfp_sp_dp_cvt (str)
+ char *str;
+{
+ skip_whitespace (str);
+
+ if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+/* Thumb specific routines. */
+
+/* Parse and validate that a register is of the right form, this saves
+ repeated checking of this information in many similar cases.
+ Unlike the 32-bit case we do not insert the register into the opcode
+ here, since the position is often unknown until the full instruction
+ has been parsed. */
+
+static int
+thumb_reg (strp, hi_lo)
+ char ** strp;
+ int hi_lo;
+{
+ int reg;
+
+ if ((reg = reg_required_here (strp, -1)) == FAIL)
+ return FAIL;
+
+ switch (hi_lo)
+ {
+ case THUMB_REG_LO:
+ if (reg > 7)
+ {
+ inst.error = _("lo register required");
+ return FAIL;
+ }
+ break;
+
+ case THUMB_REG_HI:
+ if (reg < 8)
+ {
+ inst.error = _("hi register required");
+ return FAIL;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return reg;
+}
+
+/* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
+ was SUB. */
+
+static void
+thumb_add_sub (str, subtract)
+ char * str;
+ int subtract;
+{
+ int Rd, Rs, Rn = FAIL;
+
+ skip_whitespace (str);
+
+ if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
+ || skip_past_comma (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (is_immediate_prefix (*str))
+ {
+ Rs = Rd;
+ str++;
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ }
+ else
+ {
+ if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL)
+ {
+ /* Two operand format, shuffle the registers
+ and pretend there are 3. */
+ Rn = Rs;
+ Rs = Rd;
+ }
+ else if (is_immediate_prefix (*str))
+ {
+ str++;
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ }
+ else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
+ return;
+ }
+
+ /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
+ for the latter case, EXPR contains the immediate that was found. */
+ if (Rn != FAIL)
+ {
+ /* All register format. */
+ if (Rd > 7 || Rs > 7 || Rn > 7)
+ {
+ if (Rs != Rd)
+ {
+ inst.error = _("dest and source1 must be the same register");
+ return;
+ }
+
+ /* Can't do this for SUB. */
+ if (subtract)
+ {
+ inst.error = _("subtract valid only on lo regs");
+ return;
+ }
+
+ inst.instruction = (T_OPCODE_ADD_HI
+ | (Rd > 7 ? THUMB_H1 : 0)
+ | (Rn > 7 ? THUMB_H2 : 0));
+ inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
+ }
+ else
+ {
+ inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
+ inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
+ }
+ }
+ else
+ {
+ /* Immediate expression, now things start to get nasty. */
+
+ /* First deal with HI regs, only very restricted cases allowed:
+ Adjusting SP, and using PC or SP to get an address. */
+ if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
+ || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
+ {
+ inst.error = _("invalid Hi register with immediate");
+ return;
+ }
+
+ if (inst.reloc.exp.X_op != O_constant)
+ {
+ /* Value isn't known yet, all we can do is store all the fragments
+ we know about in the instruction and let the reloc hacking
+ work it all out. */
+ inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
+ }
+ else
+ {
+ int offset = inst.reloc.exp.X_add_number;
+
+ if (subtract)
+ offset = - offset;
+
+ if (offset < 0)
+ {
+ offset = - offset;
+ subtract = 1;
+
+ /* Quick check, in case offset is MIN_INT. */
+ if (offset < 0)
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+ }
+ /* Note - you cannot convert a subtract of 0 into an
+ add of 0 because the carry flag is set differently. */
+ else if (offset > 0)
+ subtract = 0;
+
+ if (Rd == REG_SP)
+ {
+ if (offset & ~0x1fc)
+ {
+ inst.error = _("invalid immediate value for stack adjust");
+ return;
+ }
+ inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
+ inst.instruction |= offset >> 2;
+ }
+ else if (Rs == REG_PC || Rs == REG_SP)
+ {
+ if (subtract
+ || (offset & ~0x3fc))
+ {
+ inst.error = _("invalid immediate for address calculation");
+ return;
+ }
+ inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
+ : T_OPCODE_ADD_SP);
+ inst.instruction |= (Rd << 8) | (offset >> 2);
+ }
+ else if (Rs == Rd)
+ {
+ if (offset & ~0xff)
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+ inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
+ inst.instruction |= (Rd << 8) | offset;
+ }
+ else
+ {
+ if (offset & ~0x7)
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+ inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
+ inst.instruction |= Rd | (Rs << 3) | (offset << 6);
+ }
+ }
+ }
+
+ end_of_line (str);
+}
+
+static void
+thumb_shift (str, shift)
+ char * str;
+ int shift;
+{
+ int Rd, Rs, Rn = FAIL;
+
+ skip_whitespace (str);
+
+ if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
+ || skip_past_comma (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (is_immediate_prefix (*str))
+ {
+ /* Two operand immediate format, set Rs to Rd. */
+ Rs = Rd;
+ str ++;
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ }
+ else
+ {
+ if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL)
+ {
+ /* Two operand format, shuffle the registers
+ and pretend there are 3. */
+ Rn = Rs;
+ Rs = Rd;
+ }
+ else if (is_immediate_prefix (*str))
+ {
+ str++;
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ }
+ else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
+ return;
+ }
+
+ /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
+ for the latter case, EXPR contains the immediate that was found. */
+
+ if (Rn != FAIL)
+ {
+ if (Rs != Rd)
+ {
+ inst.error = _("source1 and dest must be same register");
+ return;
+ }
+
+ switch (shift)
+ {
+ case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
+ case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
+ case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
+ }
+
+ inst.instruction |= Rd | (Rn << 3);
+ }
+ else
+ {
+ switch (shift)
+ {
+ case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
+ case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
+ case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
+ }
+
+ if (inst.reloc.exp.X_op != O_constant)
+ {
+ /* Value isn't known yet, create a dummy reloc and let reloc
+ hacking fix it up. */
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
+ }
+ else
+ {
+ unsigned shift_value = inst.reloc.exp.X_add_number;
+
+ if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
+ {
+ inst.error = _("invalid immediate for shift");
+ return;
+ }
+
+ /* Shifts of zero are handled by converting to LSL. */
+ if (shift_value == 0)
+ inst.instruction = T_OPCODE_LSL_I;
+
+ /* Shifts of 32 are encoded as a shift of zero. */
+ if (shift_value == 32)
+ shift_value = 0;
+
+ inst.instruction |= shift_value << 6;
+ }
+
+ inst.instruction |= Rd | (Rs << 3);
+ }
+
+ end_of_line (str);
+}
+
+static void
+thumb_mov_compare (str, move)
+ char * str;
+ int move;
+{
+ int Rd, Rs = FAIL;
+
+ skip_whitespace (str);
+
+ if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
+ || skip_past_comma (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (move != THUMB_CPY && is_immediate_prefix (*str))
+ {
+ str++;
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ }
+ else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
+ return;
+
+ if (Rs != FAIL)
+ {
+ if (move != THUMB_CPY && Rs < 8 && Rd < 8)
+ {
+ if (move == THUMB_MOVE)
+ /* A move of two lowregs is encoded as ADD Rd, Rs, #0
+ since a MOV instruction produces unpredictable results. */
+ inst.instruction = T_OPCODE_ADD_I3;
+ else
+ inst.instruction = T_OPCODE_CMP_LR;
+ inst.instruction |= Rd | (Rs << 3);
+ }
+ else
+ {
+ if (move == THUMB_MOVE)
+ inst.instruction = T_OPCODE_MOV_HR;
+ else if (move != THUMB_CPY)
+ inst.instruction = T_OPCODE_CMP_HR;
+
+ if (Rd > 7)
+ inst.instruction |= THUMB_H1;
+
+ if (Rs > 7)
+ inst.instruction |= THUMB_H2;
+
+ inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
+ }
+ }
+ else
+ {
+ if (Rd > 7)
+ {
+ inst.error = _("only lo regs allowed with immediate");
+ return;
+ }
+
+ if (move == THUMB_MOVE)
+ inst.instruction = T_OPCODE_MOV_I8;
+ else
+ inst.instruction = T_OPCODE_CMP_I8;
+
+ inst.instruction |= Rd << 8;
+
+ if (inst.reloc.exp.X_op != O_constant)
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
+ else
+ {
+ unsigned value = inst.reloc.exp.X_add_number;
+
+ if (value > 255)
+ {
+ inst.error = _("invalid immediate");
+ return;
+ }
+
+ inst.instruction |= value;
+ }
+ }
+
+ end_of_line (str);
+}
+
+static void
+thumb_load_store (str, load_store, size)
+ char * str;
+ int load_store;
+ int size;
+{
+ int Rd, Rb, Ro = FAIL;
+
+ skip_whitespace (str);
+
+ if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
+ || skip_past_comma (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (*str == '[')
+ {
+ str++;
+ if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) != FAIL)
+ {
+ if (is_immediate_prefix (*str))
+ {
+ str++;
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ }
+ else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
+ return;
+ }
+ else
+ {
+ inst.reloc.exp.X_op = O_constant;
+ inst.reloc.exp.X_add_number = 0;
+ }
+
+ if (*str != ']')
+ {
+ inst.error = _("expected ']'");
+ return;
+ }
+ str++;
+ }
+ else if (*str == '=')
+ {
+ if (load_store != THUMB_LOAD)
+ {
+ inst.error = _("invalid pseudo operation");
+ return;
+ }
+
+ /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
+ str++;
+
+ skip_whitespace (str);
+
+ if (my_get_expression (& inst.reloc.exp, & str))
+ return;
+
+ end_of_line (str);
+
+ if ( inst.reloc.exp.X_op != O_constant
+ && inst.reloc.exp.X_op != O_symbol)
+ {
+ inst.error = "Constant expression expected";
+ return;
+ }
+
+ if (inst.reloc.exp.X_op == O_constant
+ && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
+ {
+ /* This can be done with a mov instruction. */
+
+ inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
+ inst.instruction |= inst.reloc.exp.X_add_number;
+ return;
+ }
+
+ /* Insert into literal pool. */
+ if (add_to_lit_pool () == FAIL)
+ {
+ if (!inst.error)
+ inst.error = "literal pool insertion failed";
+ return;
+ }
+
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+ inst.reloc.pc_rel = 1;
+ inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
+ /* Adjust ARM pipeline offset to Thumb. */
+ inst.reloc.exp.X_add_number += 4;
+
+ return;
+ }
+ else
+ {
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+
+ inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
+ inst.reloc.pc_rel = 1;
+ inst.reloc.exp.X_add_number -= 4; /* Pipeline offset. */
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+ end_of_line (str);
+ return;
+ }
+
+ if (Rb == REG_PC || Rb == REG_SP)
+ {
+ if (size != THUMB_WORD)
+ {
+ inst.error = _("byte or halfword not valid for base register");
+ return;
+ }
+ else if (Rb == REG_PC && load_store != THUMB_LOAD)
+ {
+ inst.error = _("r15 based store not allowed");
+ return;
+ }
+ else if (Ro != FAIL)
+ {
+ inst.error = _("invalid base register for register offset");
+ return;
+ }
+
+ if (Rb == REG_PC)
+ inst.instruction = T_OPCODE_LDR_PC;
+ else if (load_store == THUMB_LOAD)
+ inst.instruction = T_OPCODE_LDR_SP;
+ else
+ inst.instruction = T_OPCODE_STR_SP;
+
+ inst.instruction |= Rd << 8;
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ unsigned offset = inst.reloc.exp.X_add_number;
+
+ if (offset & ~0x3fc)
+ {
+ inst.error = _("invalid offset");
+ return;
+ }
+
+ inst.instruction |= offset >> 2;
+ }
+ else
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+ }
+ else if (Rb > 7)
+ {
+ inst.error = _("invalid base register in load/store");
+ return;
+ }
+ else if (Ro == FAIL)
+ {
+ /* Immediate offset. */
+ if (size == THUMB_WORD)
+ inst.instruction = (load_store == THUMB_LOAD
+ ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
+ else if (size == THUMB_HALFWORD)
+ inst.instruction = (load_store == THUMB_LOAD
+ ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
+ else
+ inst.instruction = (load_store == THUMB_LOAD
+ ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
+
+ inst.instruction |= Rd | (Rb << 3);
+
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ unsigned offset = inst.reloc.exp.X_add_number;
+
+ if (offset & ~(0x1f << size))
+ {
+ inst.error = _("invalid offset");
+ return;
+ }
+ inst.instruction |= (offset >> size) << 6;
+ }
+ else
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+ }
+ else
+ {
+ /* Register offset. */
+ if (size == THUMB_WORD)
+ inst.instruction = (load_store == THUMB_LOAD
+ ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
+ else if (size == THUMB_HALFWORD)
+ inst.instruction = (load_store == THUMB_LOAD
+ ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
+ else
+ inst.instruction = (load_store == THUMB_LOAD
+ ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
+
+ inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
+ }
+
+ end_of_line (str);
+}
+
+/* A register must be given at this point.
+
+ Shift is the place to put it in inst.instruction.
+
+ Restores input start point on err.
+ Returns the reg#, or FAIL. */
+
+static int
+mav_reg_required_here (str, shift, regtype)
+ char ** str;
+ int shift;
+ enum arm_reg_type regtype;
+{
+ int reg;
+ char *start = *str;
+
+ if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
+ {
+ if (shift >= 0)
+ inst.instruction |= reg << shift;
+
+ return reg;
+ }
+
+ /* Restore the start point. */
+ *str = start;
+
+ /* In the few cases where we might be able to accept something else
+ this error can be overridden. */
+ inst.error = _(all_reg_maps[regtype].expected);
+
+ return FAIL;
+}
+
+/* Cirrus Maverick Instructions. */
+
+/* Wrapper functions. */
+
+static void
+do_mav_binops_1a (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
+}
+
+static void
+do_mav_binops_1b (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
+}
+
+static void
+do_mav_binops_1c (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
+}
+
+static void
+do_mav_binops_1d (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
+}
+
+static void
+do_mav_binops_1e (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
+}
+
+static void
+do_mav_binops_1f (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
+}
+
+static void
+do_mav_binops_1g (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
+}
+
+static void
+do_mav_binops_1h (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
+}
+
+static void
+do_mav_binops_1i (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
+}
+
+static void
+do_mav_binops_1j (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
+}
+
+static void
+do_mav_binops_1k (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
+}
+
+static void
+do_mav_binops_1l (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
+}
+
+static void
+do_mav_binops_1m (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
+}
+
+static void
+do_mav_binops_1n (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
+}
+
+static void
+do_mav_binops_1o (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
+}
+
+static void
+do_mav_binops_2a (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
+}
+
+static void
+do_mav_binops_2b (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
+}
+
+static void
+do_mav_binops_2c (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
+}
+
+static void
+do_mav_binops_3a (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
+}
+
+static void
+do_mav_binops_3b (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
+}
+
+static void
+do_mav_binops_3c (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
+}
+
+static void
+do_mav_binops_3d (str)
+ char * str;
+{
+ do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
+}
+
+static void
+do_mav_triple_4a (str)
+ char * str;
+{
+ do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
+}
+
+static void
+do_mav_triple_4b (str)
+ char * str;
+{
+ do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
+}
+
+static void
+do_mav_triple_5a (str)
+ char * str;
+{
+ do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
+}
+
+static void
+do_mav_triple_5b (str)
+ char * str;
+{
+ do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
+}
+
+static void
+do_mav_triple_5c (str)
+ char * str;
+{
+ do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
+}
+
+static void
+do_mav_triple_5d (str)
+ char * str;
+{
+ do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
+}
+
+static void
+do_mav_triple_5e (str)
+ char * str;
+{
+ do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
+}
+
+static void
+do_mav_triple_5f (str)
+ char * str;
+{
+ do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
+}
+
+static void
+do_mav_triple_5g (str)
+ char * str;
+{
+ do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
+}
+
+static void
+do_mav_triple_5h (str)
+ char * str;
+{
+ do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
+}
+
+static void
+do_mav_quad_6a (str)
+ char * str;
+{
+ do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
+ REG_TYPE_MVFX);
+}
+
+static void
+do_mav_quad_6b (str)
+ char * str;
+{
+ do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
+ REG_TYPE_MVFX);
+}
+
+/* cfmvsc32<cond> DSPSC,MVDX[15:0]. */
+static void
+do_mav_dspsc_1 (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ /* cfmvsc32. */
+ if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+
+ return;
+ }
+
+ end_of_line (str);
+}
+
+/* cfmv32sc<cond> MVDX[15:0],DSPSC. */
+static void
+do_mav_dspsc_2 (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ /* cfmv32sc. */
+ if (mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_mav_shift_1 (str)
+ char * str;
+{
+ do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
+}
+
+static void
+do_mav_shift_2 (str)
+ char * str;
+{
+ do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
+}
+
+static void
+do_mav_ldst_1 (str)
+ char * str;
+{
+ do_mav_ldst (str, REG_TYPE_MVF);
+}
+
+static void
+do_mav_ldst_2 (str)
+ char * str;
+{
+ do_mav_ldst (str, REG_TYPE_MVD);
+}
+
+static void
+do_mav_ldst_3 (str)
+ char * str;
+{
+ do_mav_ldst (str, REG_TYPE_MVFX);
+}
+
+static void
+do_mav_ldst_4 (str)
+ char * str;
+{
+ do_mav_ldst (str, REG_TYPE_MVDX);
+}
+
+/* Isnsn like "foo X,Y". */
+
+static void
+do_mav_binops (str, mode, reg0, reg1)
+ char * str;
+ int mode;
+ enum arm_reg_type reg0;
+ enum arm_reg_type reg1;
+{
+ int shift0, shift1;
+
+ shift0 = mode & 0xff;
+ shift1 = (mode >> 8) & 0xff;
+
+ skip_whitespace (str);
+
+ if (mav_reg_required_here (&str, shift0, reg0) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || mav_reg_required_here (&str, shift1, reg1) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ }
+ else
+ end_of_line (str);
+}
+
+/* Isnsn like "foo X,Y,Z". */
+
+static void
+do_mav_triple (str, mode, reg0, reg1, reg2)
+ char * str;
+ int mode;
+ enum arm_reg_type reg0;
+ enum arm_reg_type reg1;
+ enum arm_reg_type reg2;
+{
+ int shift0, shift1, shift2;
+
+ shift0 = mode & 0xff;
+ shift1 = (mode >> 8) & 0xff;
+ shift2 = (mode >> 16) & 0xff;
+
+ skip_whitespace (str);
+
+ if (mav_reg_required_here (&str, shift0, reg0) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || mav_reg_required_here (&str, shift1, reg1) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || mav_reg_required_here (&str, shift2, reg2) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ }
+ else
+ end_of_line (str);
+}
+
+/* Isnsn like "foo W,X,Y,Z".
+ where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
+
+static void
+do_mav_quad (str, mode, reg0, reg1, reg2, reg3)
+ char * str;
+ int mode;
+ enum arm_reg_type reg0;
+ enum arm_reg_type reg1;
+ enum arm_reg_type reg2;
+ enum arm_reg_type reg3;
+{
+ int shift0, shift1, shift2, shift3;
+
+ shift0= mode & 0xff;
+ shift1 = (mode >> 8) & 0xff;
+ shift2 = (mode >> 16) & 0xff;
+ shift3 = (mode >> 24) & 0xff;
+
+ skip_whitespace (str);
+
+ if (mav_reg_required_here (&str, shift0, reg0) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || mav_reg_required_here (&str, shift1, reg1) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || mav_reg_required_here (&str, shift2, reg2) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || mav_reg_required_here (&str, shift3, reg3) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ }
+ else
+ end_of_line (str);
+}
+
+/* Maverick shift immediate instructions.
+ cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
+ cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
+
+static void
+do_mav_shift (str, reg0, reg1)
+ char * str;
+ enum arm_reg_type reg0;
+ enum arm_reg_type reg1;
+{
+ int error;
+ int imm, neg = 0;
+
+ skip_whitespace (str);
+
+ error = 0;
+
+ if (mav_reg_required_here (&str, 12, reg0) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || mav_reg_required_here (&str, 16, reg1) == FAIL
+ || skip_past_comma (&str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ /* Calculate the immediate operand.
+ The operand is a 7bit signed number. */
+ skip_whitespace (str);
+
+ if (*str == '#')
+ ++str;
+
+ if (!ISDIGIT (*str) && *str != '-')
+ {
+ inst.error = _("expecting immediate, 7bit operand");
+ return;
+ }
+
+ if (*str == '-')
+ {
+ neg = 1;
+ ++str;
+ }
+
+ for (imm = 0; *str && ISDIGIT (*str); ++str)
+ imm = imm * 10 + *str - '0';
+
+ if (imm > 64)
+ {
+ inst.error = _("immediate out of range");
+ return;
+ }
+
+ /* Make negative imm's into 7bit signed numbers. */
+ if (neg)
+ {
+ imm = -imm;
+ imm &= 0x0000007f;
+ }
+
+ /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
+ Bits 5-7 of the insn should have bits 4-6 of the immediate.
+ Bit 4 should be 0. */
+ imm = (imm & 0xf) | ((imm & 0x70) << 1);
+
+ inst.instruction |= imm;
+ end_of_line (str);
+}
+
+static int
+mav_parse_offset (str, negative)
+ char ** str;
+ int *negative;
+{
+ char * p = *str;
+ int offset;
+
+ *negative = 0;
+
+ skip_whitespace (p);
+
+ if (*p == '#')
+ ++p;
+
+ if (*p == '-')
+ {
+ *negative = 1;
+ ++p;
+ }
+
+ if (!ISDIGIT (*p))
+ {
+ inst.error = _("offset expected");
+ return 0;
+ }
+
+ for (offset = 0; *p && ISDIGIT (*p); ++p)
+ offset = offset * 10 + *p - '0';
+
+ if (offset > 0xff)
+ {
+ inst.error = _("offset out of range");
+ return 0;
+ }
+
+ *str = p;
+
+ return *negative ? -offset : offset;
+}
+
+/* Maverick load/store instructions.
+ <insn><cond> CRd,[Rn,<offset>]{!}.
+ <insn><cond> CRd,[Rn],<offset>. */
+
+static void
+do_mav_ldst (str, reg0)
+ char * str;
+ enum arm_reg_type reg0;
+{
+ int offset, negative;
+
+ skip_whitespace (str);
+
+ if (mav_reg_required_here (&str, 12, reg0) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || *str++ != '['
+ || reg_required_here (&str, 16) == FAIL)
+ goto fail_ldst;
+
+ if (skip_past_comma (&str) == SUCCESS)
+ {
+ /* You are here: "<offset>]{!}". */
+ inst.instruction |= PRE_INDEX;
+
+ offset = mav_parse_offset (&str, &negative);
+
+ if (inst.error)
+ return;
+
+ if (*str++ != ']')
+ {
+ inst.error = _("missing ]");
+ return;
+ }
+
+ if (*str == '!')
+ {
+ inst.instruction |= WRITE_BACK;
+ ++str;
+ }
+ }
+ else
+ {
+ /* You are here: "], <offset>". */
+ if (*str++ != ']')
+ {
+ inst.error = _("missing ]");
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || (offset = mav_parse_offset (&str, &negative), inst.error))
+ goto fail_ldst;
+
+ inst.instruction |= CP_T_WB; /* Post indexed, set bit W. */
+ }
+
+ if (negative)
+ offset = -offset;
+ else
+ inst.instruction |= CP_T_UD; /* Positive, so set bit U. */
+
+ inst.instruction |= offset >> 2;
+ end_of_line (str);
+ return;
+
+fail_ldst:
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+}
+
+static void
+do_t_nop (str)
+ char * str;
+{
+ /* Do nothing. */
+ end_of_line (str);
+}
+
+/* Handle the Format 4 instructions that do not have equivalents in other
+ formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
+ BIC and MVN. */
+
+static void
+do_t_arit (str)
+ char * str;
+{
+ int Rd, Rs, Rn;
+
+ skip_whitespace (str);
+
+ if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (&str) != FAIL)
+ {
+ /* Three operand format not allowed for TST, CMN, NEG and MVN.
+ (It isn't allowed for CMP either, but that isn't handled by this
+ function.) */
+ if (inst.instruction == T_OPCODE_TST
+ || inst.instruction == T_OPCODE_CMN
+ || inst.instruction == T_OPCODE_NEG
+ || inst.instruction == T_OPCODE_MVN)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
+ return;
+
+ if (Rs != Rd)
+ {
+ inst.error = _("dest and source1 must be the same register");
+ return;
+ }
+ Rs = Rn;
+ }
+
+ if (inst.instruction == T_OPCODE_MUL
+ && Rs == Rd)
+ as_tsktsk (_("Rs and Rd must be different in MUL"));
+
+ inst.instruction |= Rd | (Rs << 3);
+ end_of_line (str);
+}
+
+static void
+do_t_add (str)
+ char * str;
+{
+ thumb_add_sub (str, 0);
+}
+
+static void
+do_t_asr (str)
+ char * str;
+{
+ thumb_shift (str, THUMB_ASR);
+}
+
+static void
+do_t_branch9 (str)
+ char * str;
+{
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
+ inst.reloc.pc_rel = 1;
+ end_of_line (str);
+}
+
+static void
+do_t_branch12 (str)
+ char * str;
+{
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
+ inst.reloc.pc_rel = 1;
+ end_of_line (str);
+}
+
+/* Find the real, Thumb encoded start of a Thumb function. */
+
+static symbolS *
+find_real_start (symbolP)
+ symbolS * symbolP;
+{
+ char * real_start;
+ const char * name = S_GET_NAME (symbolP);
+ symbolS * new_target;
+
+ /* This definition must agree with the one in gcc/config/arm/thumb.c. */
+#define STUB_NAME ".real_start_of"
+
+ if (name == NULL)
+ abort ();
+
+ /* Names that start with '.' are local labels, not function entry points.
+ The compiler may generate BL instructions to these labels because it
+ needs to perform a branch to a far away location. */
+ if (name[0] == '.')
+ return symbolP;
+
+ real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
+ sprintf (real_start, "%s%s", STUB_NAME, name);
+
+ new_target = symbol_find (real_start);
+
+ if (new_target == NULL)
+ {
+ as_warn ("Failed to find real start of function: %s\n", name);
+ new_target = symbolP;
+ }
+
+ free (real_start);
+
+ return new_target;
+}
+
+static void
+do_t_branch23 (str)
+ char * str;
+{
+ if (my_get_expression (& inst.reloc.exp, & str))
+ return;
+
+ inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
+ inst.reloc.pc_rel = 1;
+ end_of_line (str);
+
+ /* If the destination of the branch is a defined symbol which does not have
+ the THUMB_FUNC attribute, then we must be calling a function which has
+ the (interfacearm) attribute. We look for the Thumb entry point to that
+ function and change the branch to refer to that function instead. */
+ if ( inst.reloc.exp.X_op == O_symbol
+ && inst.reloc.exp.X_add_symbol != NULL
+ && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
+ && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
+ inst.reloc.exp.X_add_symbol =
+ find_real_start (inst.reloc.exp.X_add_symbol);
+}
+
+static void
+do_t_bx (str)
+ char * str;
+{
+ int reg;
+
+ skip_whitespace (str);
+
+ if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
+ return;
+
+ /* This sets THUMB_H2 from the top bit of reg. */
+ inst.instruction |= reg << 3;
+
+ /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
+ should cause the alignment to be checked once it is known. This is
+ because BX PC only works if the instruction is word aligned. */
+
+ end_of_line (str);
+}
+
+static void
+do_t_compare (str)
+ char * str;
+{
+ thumb_mov_compare (str, THUMB_COMPARE);
+}
+
+static void
+do_t_ldmstm (str)
+ char * str;
+{
+ int Rb;
+ long range;
+
+ skip_whitespace (str);
+
+ if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
+ return;
+
+ if (*str != '!')
+ as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
+ else
+ str++;
+
+ if (skip_past_comma (&str) == FAIL
+ || (range = reg_list (&str)) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (inst.reloc.type != BFD_RELOC_NONE)
+ {
+ /* This really doesn't seem worth it. */
+ inst.reloc.type = BFD_RELOC_NONE;
+ inst.error = _("expression too complex");
+ return;
+ }
+
+ if (range & ~0xff)
+ {
+ inst.error = _("only lo-regs valid in load/store multiple");
+ return;
+ }
+
+ inst.instruction |= (Rb << 8) | range;
+ end_of_line (str);
+}
+
+static void
+do_t_ldr (str)
+ char * str;
+{
+ thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
+}
+
+static void
+do_t_ldrb (str)
+ char * str;
+{
+ thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
+}
+
+static void
+do_t_ldrh (str)
+ char * str;
+{
+ thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
+}
+
+static void
+do_t_lds (str)
+ char * str;
+{
+ int Rd, Rb, Ro;
+
+ skip_whitespace (str);
+
+ if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || *str++ != '['
+ || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
+ || *str++ != ']')
+ {
+ if (! inst.error)
+ inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
+ return;
+ }
+
+ inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
+ end_of_line (str);
+}
+
+static void
+do_t_lsl (str)
+ char * str;
+{
+ thumb_shift (str, THUMB_LSL);
+}
+
+static void
+do_t_lsr (str)
+ char * str;
+{
+ thumb_shift (str, THUMB_LSR);
+}
+
+static void
+do_t_mov (str)
+ char * str;
+{
+ thumb_mov_compare (str, THUMB_MOVE);
+}
+
+static void
+do_t_push_pop (str)
+ char * str;
+{
+ long range;
+
+ skip_whitespace (str);
+
+ if ((range = reg_list (&str)) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (inst.reloc.type != BFD_RELOC_NONE)
+ {
+ /* This really doesn't seem worth it. */
+ inst.reloc.type = BFD_RELOC_NONE;
+ inst.error = _("expression too complex");
+ return;
+ }
+
+ if (range & ~0xff)
+ {
+ if ((inst.instruction == T_OPCODE_PUSH
+ && (range & ~0xff) == 1 << REG_LR)
+ || (inst.instruction == T_OPCODE_POP
+ && (range & ~0xff) == 1 << REG_PC))
+ {
+ inst.instruction |= THUMB_PP_PC_LR;
+ range &= 0xff;
+ }
+ else
+ {
+ inst.error = _("invalid register list to push/pop instruction");
+ return;
+ }
+ }
+
+ inst.instruction |= range;
+ end_of_line (str);
+}
+
+static void
+do_t_str (str)
+ char * str;
+{
+ thumb_load_store (str, THUMB_STORE, THUMB_WORD);
+}
+
+static void
+do_t_strb (str)
+ char * str;
+{
+ thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
+}
+
+static void
+do_t_strh (str)
+ char * str;
+{
+ thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
+}
+
+static void
+do_t_sub (str)
+ char * str;
+{
+ thumb_add_sub (str, 1);
+}
+
+static void
+do_t_swi (str)
+ char * str;
+{
+ skip_whitespace (str);
+
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+
+ inst.reloc.type = BFD_RELOC_ARM_SWI;
+ end_of_line (str);
+}
+
+static void
+do_t_adr (str)
+ char * str;
+{
+ int reg;
+
+ /* This is a pseudo-op of the form "adr rd, label" to be converted
+ into a relative address of the form "add rd, pc, #label-.-4". */
+ skip_whitespace (str);
+
+ /* Store Rd in temporary location inside instruction. */
+ if ((reg = reg_required_here (&str, 4)) == FAIL
+ || (reg > 7) /* For Thumb reg must be r0..r7. */
+ || skip_past_comma (&str) == FAIL
+ || my_get_expression (&inst.reloc.exp, &str))
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
+ inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
+ inst.reloc.pc_rel = 1;
+ inst.instruction |= REG_PC; /* Rd is already placed into the instruction. */
+
+ end_of_line (str);
+}
+
+static void
+insert_reg (r, htab)
+ const struct reg_entry *r;
+ struct hash_control *htab;
+{
+ int len = strlen (r->name) + 2;
+ char * buf = (char *) xmalloc (len);
+ char * buf2 = (char *) xmalloc (len);
+ int i = 0;
+
+#ifdef REGISTER_PREFIX
+ buf[i++] = REGISTER_PREFIX;
+#endif
+
+ strcpy (buf + i, r->name);
+
+ for (i = 0; buf[i]; i++)
+ buf2[i] = TOUPPER (buf[i]);
+
+ buf2[i] = '\0';
+
+ hash_insert (htab, buf, (PTR) r);
+ hash_insert (htab, buf2, (PTR) r);
+}
+
+static void
+build_reg_hsh (map)
+ struct reg_map *map;
+{
+ const struct reg_entry *r;
+
+ if ((map->htab = hash_new ()) == NULL)
+ as_fatal (_("virtual memory exhausted"));
+
+ for (r = map->names; r->name != NULL; r++)
+ insert_reg (r, map->htab);
+}
+
+static void
+insert_reg_alias (str, regnum, htab)
+ char *str;
+ int regnum;
+ struct hash_control *htab;
+{
+ const char *error;
+ struct reg_entry *new = xmalloc (sizeof (struct reg_entry));
+ const char *name = xmalloc (strlen (str) + 1);
+
+ strcpy ((char *) name, str);
+
+ new->name = name;
+ new->number = regnum;
+ new->builtin = FALSE;
+
+ error = hash_insert (htab, name, (PTR) new);
+ if (error)
+ {
+ as_bad (_("failed to create an alias for %s, reason: %s"),
+ str, error);
+ free ((char *) name);
+ free (new);
+ }
+}
+
+/* Look for the .req directive. This is of the form:
+
+ new_register_name .req existing_register_name
+
+ If we find one, or if it looks sufficiently like one that we want to
+ handle any error here, return non-zero. Otherwise return zero. */
+static int
+create_register_alias (newname, p)
+ char *newname;
+ char *p;
+{
+ char *q;
+ char c;
+
+ q = p;
+ skip_whitespace (q);
+
+ c = *p;
+ *p = '\0';
+
+ if (*q && !strncmp (q, ".req ", 5))
+ {
+ char *copy_of_str;
+ char *r;
+
+#ifdef IGNORE_OPCODE_CASE
+ newname = original_case_string;
+#endif
+ copy_of_str = newname;
+
+ q += 4;
+ skip_whitespace (q);
+
+ for (r = q; *r != '\0'; r++)
+ if (*r == ' ')
+ break;
+
+ if (r != q)
+ {
+ enum arm_reg_type new_type, old_type;
+ int old_regno;
+ char d = *r;
+
+ *r = '\0';
+ old_type = arm_reg_parse_any (q);
+ *r = d;
+
+ new_type = arm_reg_parse_any (newname);
+
+ if (new_type == REG_TYPE_MAX)
+ {
+ if (old_type != REG_TYPE_MAX)
+ {
+ old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
+ insert_reg_alias (newname, old_regno,
+ all_reg_maps[old_type].htab);
+ }
+ else
+ as_warn (_("register '%s' does not exist\n"), q);
+ }
+ else if (old_type == REG_TYPE_MAX)
+ {
+ as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
+ copy_of_str, q);
+ }
+ else
+ {
+ /* Do not warn about redefinitions to the same alias. */
+ if (new_type != old_type
+ || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
+ != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
+ as_warn (_("ignoring redefinition of register alias '%s'"),
+ copy_of_str);
+
+ }
+ }
+ else
+ as_warn (_("ignoring incomplete .req pseuso op"));
+
+ *p = c;
+ return 1;
+ }
+
+ *p = c;
+ return 0;
+}
+
+static void
+set_constant_flonums ()
+{
+ int i;
+
+ for (i = 0; i < NUM_FLOAT_VALS; i++)
+ if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
+ abort ();
+}
+
+/* Iterate over the base tables to create the instruction patterns. */
+static void
+build_arm_ops_hsh ()
+{
+ unsigned int i;
+ unsigned int j;
+ static struct obstack insn_obstack;
+
+ obstack_begin (&insn_obstack, 4000);
+
+ for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
+ {
+ const struct asm_opcode *insn = insns + i;
+
+ if (insn->cond_offset != 0)
+ {
+ /* Insn supports conditional execution. Build the varaints
+ and insert them in the hash table. */
+ for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
+ {
+ unsigned len = strlen (insn->template);
+ struct asm_opcode *new;
+ char *template;
+
+ new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
+ /* All condition codes are two characters. */
+ template = obstack_alloc (&insn_obstack, len + 3);
+
+ strncpy (template, insn->template, insn->cond_offset);
+ strcpy (template + insn->cond_offset, conds[j].template);
+ if (len > insn->cond_offset)
+ strcpy (template + insn->cond_offset + 2,
+ insn->template + insn->cond_offset);
+ new->template = template;
+ new->cond_offset = 0;
+ new->variant = insn->variant;
+ new->parms = insn->parms;
+ new->value = (insn->value & ~COND_MASK) | conds[j].value;
+
+ hash_insert (arm_ops_hsh, new->template, (PTR) new);
+ }
+ }
+ /* Finally, insert the unconditional insn in the table directly;
+ no need to build a copy. */
+ hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
+ }
+}
+
+#if 0 /* Suppressed - for now. */
+#if defined OBJ_ELF || defined OBJ_COFF
+
+#ifdef OBJ_ELF
+#define arm_Note Elf_External_Note
+#else
+typedef struct
+{
+ unsigned char namesz[4]; /* Size of entry's owner string. */
+ unsigned char descsz[4]; /* Size of the note descriptor. */
+ unsigned char type[4]; /* Interpretation of the descriptor. */
+ char name[1]; /* Start of the name+desc data. */
+} arm_Note;
+#endif
+
+/* The description is kept to a fix sized in order to make updating
+ it and merging it easier. */
+#define ARM_NOTE_DESCRIPTION_LENGTH 8
+
+static void
+arm_add_note (name, description, type)
+ const char * name;
+ const char * description;
+ unsigned int type;
+{
+ arm_Note note ATTRIBUTE_UNUSED;
+ char * p;
+ unsigned int name_len;
+
+ name_len = (strlen (name) + 1 + 3) & ~3;
+
+ p = frag_more (sizeof (note.namesz));
+ md_number_to_chars (p, (valueT) name_len, sizeof (note.namesz));
+
+ p = frag_more (sizeof (note.descsz));
+ md_number_to_chars (p, (valueT) ARM_NOTE_DESCRIPTION_LENGTH, sizeof (note.descsz));
+
+ p = frag_more (sizeof (note.type));
+ md_number_to_chars (p, (valueT) type, sizeof (note.type));
+
+ p = frag_more (name_len);
+ strcpy (p, name);
+
+ p = frag_more (ARM_NOTE_DESCRIPTION_LENGTH);
+ strncpy (p, description, ARM_NOTE_DESCRIPTION_LENGTH);
+ frag_align (2, 0, 0);
+}
+#endif
+#endif
+
+void
+md_begin ()
+{
+ unsigned mach;
+ unsigned int i;
+
+ if ( (arm_ops_hsh = hash_new ()) == NULL
+ || (arm_tops_hsh = hash_new ()) == NULL
+ || (arm_cond_hsh = hash_new ()) == NULL
+ || (arm_shift_hsh = hash_new ()) == NULL
+ || (arm_psr_hsh = hash_new ()) == NULL)
+ as_fatal (_("virtual memory exhausted"));
+
+ build_arm_ops_hsh ();
+ for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
+ hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
+ for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
+ hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
+ for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
+ hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
+ for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
+ hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
+
+ for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
+ build_reg_hsh (all_reg_maps + i);
+
+ set_constant_flonums ();
+
+ /* Set the cpu variant based on the command-line options. We prefer
+ -mcpu= over -march= if both are set (as for GCC); and we prefer
+ -mfpu= over any other way of setting the floating point unit.
+ Use of legacy options with new options are faulted. */
+ if (legacy_cpu != -1)
+ {
+ if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
+ as_bad (_("use of old and new-style options to set CPU type"));
+
+ mcpu_cpu_opt = legacy_cpu;
+ }
+ else if (mcpu_cpu_opt == -1)
+ mcpu_cpu_opt = march_cpu_opt;
+
+ if (legacy_fpu != -1)
+ {
+ if (mfpu_opt != -1)
+ as_bad (_("use of old and new-style options to set FPU type"));
+
+ mfpu_opt = legacy_fpu;
+ }
+ else if (mfpu_opt == -1)
+ {
+#if !(defined (TE_LINUX) || defined (TE_NetBSD))
+ /* Some environments specify a default FPU. If they don't, infer it
+ from the processor. */
+ if (mcpu_fpu_opt != -1)
+ mfpu_opt = mcpu_fpu_opt;
+ else
+ mfpu_opt = march_fpu_opt;
+#else
+ mfpu_opt = FPU_DEFAULT;
+#endif
+ }
+
+ if (mfpu_opt == -1)
+ {
+ if (mcpu_cpu_opt == -1)
+ mfpu_opt = FPU_DEFAULT;
+ else if (mcpu_cpu_opt & ARM_EXT_V5)
+ mfpu_opt = FPU_ARCH_VFP_V2;
+ else
+ mfpu_opt = FPU_ARCH_FPA;
+ }
+
+ if (mcpu_cpu_opt == -1)
+ mcpu_cpu_opt = CPU_DEFAULT;
+
+ cpu_variant = mcpu_cpu_opt | mfpu_opt;
+
+#if defined OBJ_COFF || defined OBJ_ELF
+ {
+ unsigned int flags = 0;
+
+ /* Set the flags in the private structure. */
+ if (uses_apcs_26) flags |= F_APCS26;
+ if (support_interwork) flags |= F_INTERWORK;
+ if (uses_apcs_float) flags |= F_APCS_FLOAT;
+ if (pic_code) flags |= F_PIC;
+ if ((cpu_variant & FPU_ANY) == FPU_NONE
+ || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only. */
+ {
+ flags |= F_SOFT_FLOAT;
+ }
+ switch (mfloat_abi_opt)
+ {
+ case ARM_FLOAT_ABI_SOFT:
+ case ARM_FLOAT_ABI_SOFTFP:
+ flags |= F_SOFT_FLOAT;
+ break;
+
+ case ARM_FLOAT_ABI_HARD:
+ if (flags & F_SOFT_FLOAT)
+ as_bad (_("hard-float conflicts with specified fpu"));
+ break;
+ }
+ /* Using VFP conventions (even if soft-float). */
+ if (cpu_variant & FPU_VFP_EXT_NONE) flags |= F_VFP_FLOAT;
+
+#if defined OBJ_ELF
+ if (cpu_variant & FPU_ARCH_MAVERICK)
+ flags |= EF_ARM_MAVERICK_FLOAT;
+#endif
+
+ bfd_set_private_flags (stdoutput, flags);
+
+ /* We have run out flags in the COFF header to encode the
+ status of ATPCS support, so instead we create a dummy,
+ empty, debug section called .arm.atpcs. */
+ if (atpcs)
+ {
+ asection * sec;
+
+ sec = bfd_make_section (stdoutput, ".arm.atpcs");
+
+ if (sec != NULL)
+ {
+ bfd_set_section_flags
+ (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
+ bfd_set_section_size (stdoutput, sec, 0);
+ bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
+ }
+ }
+ }
+#endif
+
+ /* Record the CPU type as well. */
+ switch (cpu_variant & ARM_CPU_MASK)
+ {
+ case ARM_2:
+ mach = bfd_mach_arm_2;
+ break;
+
+ case ARM_3: /* Also ARM_250. */
+ mach = bfd_mach_arm_2a;
+ break;
+
+ case ARM_6: /* Also ARM_7. */
+ mach = bfd_mach_arm_3;
+ break;
+
+ default:
+ mach = bfd_mach_arm_unknown;
+ break;
+ }
+
+ /* Catch special cases. */
+ if (cpu_variant & ARM_CEXT_IWMMXT)
+ mach = bfd_mach_arm_iWMMXt;
+ else if (cpu_variant & ARM_CEXT_XSCALE)
+ mach = bfd_mach_arm_XScale;
+ else if (cpu_variant & ARM_CEXT_MAVERICK)
+ mach = bfd_mach_arm_ep9312;
+ else if (cpu_variant & ARM_EXT_V5E)
+ mach = bfd_mach_arm_5TE;
+ else if (cpu_variant & ARM_EXT_V5)
+ {
+ if (cpu_variant & ARM_EXT_V4T)
+ mach = bfd_mach_arm_5T;
+ else
+ mach = bfd_mach_arm_5;
+ }
+ else if (cpu_variant & ARM_EXT_V4)
+ {
+ if (cpu_variant & ARM_EXT_V4T)
+ mach = bfd_mach_arm_4T;
+ else
+ mach = bfd_mach_arm_4;
+ }
+ else if (cpu_variant & ARM_EXT_V3M)
+ mach = bfd_mach_arm_3M;
+
+#if 0 /* Suppressed - for now. */
+#if defined (OBJ_ELF) || defined (OBJ_COFF)
+
+ /* Create a .note section to fully identify this arm binary. */
+
+#define NOTE_ARCH_STRING "arch: "
+
+#if defined OBJ_COFF && ! defined NT_VERSION
+#define NT_VERSION 1
+#define NT_ARCH 2
+#endif
+
+ {
+ segT current_seg = now_seg;
+ subsegT current_subseg = now_subseg;
+ asection * arm_arch;
+ const char * arch_string;
+
+ arm_arch = bfd_make_section_old_way (stdoutput, ARM_NOTE_SECTION);
+
+#ifdef OBJ_COFF
+ bfd_set_section_flags (stdoutput, arm_arch,
+ SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_LINK_ONCE \
+ | SEC_HAS_CONTENTS);
+#else
+ bfd_set_section_flags (stdoutput, arm_arch,
+ SEC_READONLY | SEC_HAS_CONTENTS);
+#endif
+ arm_arch->output_section = arm_arch;
+ subseg_set (arm_arch, 0);
+
+ switch (mach)
+ {
+ default:
+ case bfd_mach_arm_unknown: arch_string = "unknown"; break;
+ case bfd_mach_arm_2: arch_string = "armv2"; break;
+ case bfd_mach_arm_2a: arch_string = "armv2a"; break;
+ case bfd_mach_arm_3: arch_string = "armv3"; break;
+ case bfd_mach_arm_3M: arch_string = "armv3M"; break;
+ case bfd_mach_arm_4: arch_string = "armv4"; break;
+ case bfd_mach_arm_4T: arch_string = "armv4t"; break;
+ case bfd_mach_arm_5: arch_string = "armv5"; break;
+ case bfd_mach_arm_5T: arch_string = "armv5t"; break;
+ case bfd_mach_arm_5TE: arch_string = "armv5te"; break;
+ case bfd_mach_arm_XScale: arch_string = "XScale"; break;
+ case bfd_mach_arm_ep9312: arch_string = "ep9312"; break;
+ case bfd_mach_arm_iWMMXt: arch_string = "iWMMXt"; break;
+ }
+
+ arm_add_note (NOTE_ARCH_STRING, arch_string, NT_ARCH);
+
+ subseg_set (current_seg, current_subseg);
+ }
+#endif
+#endif /* Suppressed code. */
+
+ bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
+}
+
+/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
+ for use in the a.out file, and stores them in the array pointed to by buf.
+ This knows about the endian-ness of the target machine and does
+ THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
+ 2 (short) and 4 (long) Floating numbers are put out as a series of
+ LITTLENUMS (shorts, here at least). */
+
+void
+md_number_to_chars (buf, val, n)
+ char * buf;
+ valueT val;
+ int n;
+{
+ if (target_big_endian)
+ number_to_chars_bigendian (buf, val, n);
+ else
+ number_to_chars_littleendian (buf, val, n);
+}
+
+static valueT
+md_chars_to_number (buf, n)
+ char * buf;
+ int n;
+{
+ valueT result = 0;
+ unsigned char * where = (unsigned char *) buf;
+
+ if (target_big_endian)
+ {
+ while (n--)
+ {
+ result <<= 8;
+ result |= (*where++ & 255);
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ result <<= 8;
+ result |= (where[n] & 255);
+ }
+ }
+
+ return result;
+}
+
+/* Turn a string in input_line_pointer into a floating point constant
+ of type TYPE, and store the appropriate bytes in *LITP. The number
+ of LITTLENUMS emitted is stored in *SIZEP. An error message is
+ returned, or NULL on OK.
+
+ Note that fp constants aren't represent in the normal way on the ARM.
+ In big endian mode, things are as expected. However, in little endian
+ mode fp constants are big-endian word-wise, and little-endian byte-wise
+ within the words. For example, (double) 1.1 in big endian mode is
+ the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
+ the byte sequence 99 99 f1 3f 9a 99 99 99.
+
+ ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
+
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char * litP;
+ int * sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ char *t;
+ int i;
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("bad call to MD_ATOF()");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+ *sizeP = prec * 2;
+
+ if (target_big_endian)
+ {
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, (valueT) words[i], 2);
+ litP += 2;
+ }
+ }
+ else
+ {
+ if (cpu_variant & FPU_ARCH_VFP)
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litP, (valueT) words[i], 2);
+ litP += 2;
+ }
+ else
+ /* For a 4 byte float the order of elements in `words' is 1 0.
+ For an 8 byte float the order is 1 0 3 2. */
+ for (i = 0; i < prec; i += 2)
+ {
+ md_number_to_chars (litP, (valueT) words[i + 1], 2);
+ md_number_to_chars (litP + 2, (valueT) words[i], 2);
+ litP += 4;
+ }
+ }
+
+ return 0;
+}
+
+/* The knowledge of the PC's pipeline offset is built into the insns
+ themselves. */
+
+long
+md_pcrel_from (fixP)
+ fixS * fixP;
+{
+ if (fixP->fx_addsy
+ && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
+ && fixP->fx_subsy == NULL)
+ return 0;
+
+ if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
+ {
+ /* PC relative addressing on the Thumb is slightly odd
+ as the bottom two bits of the PC are forced to zero
+ for the calculation. */
+ return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
+ }
+
+#ifdef TE_WINCE
+ /* The pattern was adjusted to accommodate CE's off-by-one fixups,
+ so we un-adjust here to compensate for the accommodation. */
+ return fixP->fx_where + fixP->fx_frag->fr_address + 8;
+#else
+ return fixP->fx_where + fixP->fx_frag->fr_address;
+#endif
+}
+
+/* Round up a section size to the appropriate boundary. */
+
+valueT
+md_section_align (segment, size)
+ segT segment ATTRIBUTE_UNUSED;
+ valueT size;
+{
+#ifdef OBJ_ELF
+ return size;
+#else
+ /* Round all sects to multiple of 4. */
+ return (size + 3) & ~3;
+#endif
+}
+
+/* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
+ Otherwise we have no need to default values of symbols. */
+
+symbolS *
+md_undefined_symbol (name)
+ char * name ATTRIBUTE_UNUSED;
+{
+#ifdef OBJ_ELF
+ if (name[0] == '_' && name[1] == 'G'
+ && streq (name, GLOBAL_OFFSET_TABLE_NAME))
+ {
+ if (!GOT_symbol)
+ {
+ if (symbol_find (name))
+ as_bad ("GOT already in the symbol table");
+
+ GOT_symbol = symbol_new (name, undefined_section,
+ (valueT) 0, & zero_address_frag);
+ }
+
+ return GOT_symbol;
+ }
+#endif
+
+ return 0;
+}
+
+/* arm_reg_parse () := if it looks like a register, return its token and
+ advance the pointer. */
+
+static int
+arm_reg_parse (ccp, htab)
+ register char ** ccp;
+ struct hash_control *htab;
+{
+ char * start = * ccp;
+ char c;
+ char * p;
+ struct reg_entry * reg;
+
+#ifdef REGISTER_PREFIX
+ if (*start != REGISTER_PREFIX)
+ return FAIL;
+ p = start + 1;
+#else
+ p = start;
+#ifdef OPTIONAL_REGISTER_PREFIX
+ if (*p == OPTIONAL_REGISTER_PREFIX)
+ p++, start++;
+#endif
+#endif
+ if (!ISALPHA (*p) || !is_name_beginner (*p))
+ return FAIL;
+
+ c = *p++;
+ while (ISALPHA (c) || ISDIGIT (c) || c == '_')
+ c = *p++;
+
+ *--p = 0;
+ reg = (struct reg_entry *) hash_find (htab, start);
+ *p = c;
+
+ if (reg)
+ {
+ *ccp = p;
+ return reg->number;
+ }
+
+ return FAIL;
+}
+
+/* Search for the following register name in each of the possible reg name
+ tables. Return the classification if found, or REG_TYPE_MAX if not
+ present. */
+static enum arm_reg_type
+arm_reg_parse_any (cp)
+ char *cp;
+{
+ int i;
+
+ for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
+ if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
+ return (enum arm_reg_type) i;
+
+ return REG_TYPE_MAX;
+}
+
+void
+md_apply_fix3 (fixP, valP, seg)
+ fixS * fixP;
+ valueT * valP;
+ segT seg;
+{
+ offsetT value = * valP;
+ offsetT newval;
+ unsigned int newimm;
+ unsigned long temp;
+ int sign;
+ char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+ arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
+
+ assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
+
+ /* Note whether this will delete the relocation. */
+#if 0
+ /* Patch from REarnshaw to JDavis (disabled for the moment, since it
+ doesn't work fully.) */
+ if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
+ && !fixP->fx_pcrel)
+#else
+ if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
+#endif
+ fixP->fx_done = 1;
+
+ /* If this symbol is in a different section then we need to leave it for
+ the linker to deal with. Unfortunately, md_pcrel_from can't tell,
+ so we have to undo it's effects here. */
+ if (fixP->fx_pcrel)
+ {
+ if (fixP->fx_addsy != NULL
+ && S_IS_DEFINED (fixP->fx_addsy)
+ && S_GET_SEGMENT (fixP->fx_addsy) != seg)
+ {
+ if (target_oabi
+ && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
+ || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
+ ))
+ value = 0;
+ else
+ value += md_pcrel_from (fixP);
+ }
+ }
+
+ /* Remember value for emit_reloc. */
+ fixP->fx_addnumber = value;
+
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_ARM_IMMEDIATE:
+ newimm = validate_immediate (value);
+ temp = md_chars_to_number (buf, INSN_SIZE);
+
+ /* If the instruction will fail, see if we can fix things up by
+ changing the opcode. */
+ if (newimm == (unsigned int) FAIL
+ && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid constant (%lx) after fixup"),
+ (unsigned long) value);
+ break;
+ }
+
+ newimm |= (temp & 0xfffff000);
+ md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
+ fixP->fx_done = 1;
+ break;
+
+ case BFD_RELOC_ARM_ADRL_IMMEDIATE:
+ {
+ unsigned int highpart = 0;
+ unsigned int newinsn = 0xe1a00000; /* nop. */
+
+ newimm = validate_immediate (value);
+ temp = md_chars_to_number (buf, INSN_SIZE);
+
+ /* If the instruction will fail, see if we can fix things up by
+ changing the opcode. */
+ if (newimm == (unsigned int) FAIL
+ && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
+ {
+ /* No ? OK - try using two ADD instructions to generate
+ the value. */
+ newimm = validate_immediate_twopart (value, & highpart);
+
+ /* Yes - then make sure that the second instruction is
+ also an add. */
+ if (newimm != (unsigned int) FAIL)
+ newinsn = temp;
+ /* Still No ? Try using a negated value. */
+ else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
+ temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
+ /* Otherwise - give up. */
+ else
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("unable to compute ADRL instructions for PC offset of 0x%lx"),
+ (long) value);
+ break;
+ }
+
+ /* Replace the first operand in the 2nd instruction (which
+ is the PC) with the destination register. We have
+ already added in the PC in the first instruction and we
+ do not want to do it again. */
+ newinsn &= ~ 0xf0000;
+ newinsn |= ((newinsn & 0x0f000) << 4);
+ }
+
+ newimm |= (temp & 0xfffff000);
+ md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
+
+ highpart |= (newinsn & 0xfffff000);
+ md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
+ }
+ break;
+
+ case BFD_RELOC_ARM_OFFSET_IMM:
+ sign = value >= 0;
+
+ if (value < 0)
+ value = - value;
+
+ if (validate_offset_imm (value, 0) == FAIL)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("bad immediate value for offset (%ld)"),
+ (long) value);
+ break;
+ }
+
+ newval = md_chars_to_number (buf, INSN_SIZE);
+ newval &= 0xff7ff000;
+ newval |= value | (sign ? INDEX_UP : 0);
+ md_number_to_chars (buf, newval, INSN_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_OFFSET_IMM8:
+ case BFD_RELOC_ARM_HWLITERAL:
+ sign = value >= 0;
+
+ if (value < 0)
+ value = - value;
+
+ if (validate_offset_imm (value, 1) == FAIL)
+ {
+ if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid literal constant: pool needs to be closer"));
+ else
+ as_bad (_("bad immediate value for half-word offset (%ld)"),
+ (long) value);
+ break;
+ }
+
+ newval = md_chars_to_number (buf, INSN_SIZE);
+ newval &= 0xff7ff0f0;
+ newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
+ md_number_to_chars (buf, newval, INSN_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_LITERAL:
+ sign = value >= 0;
+
+ if (value < 0)
+ value = - value;
+
+ if (validate_offset_imm (value, 0) == FAIL)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid literal constant: pool needs to be closer"));
+ break;
+ }
+
+ newval = md_chars_to_number (buf, INSN_SIZE);
+ newval &= 0xff7ff000;
+ newval |= value | (sign ? INDEX_UP : 0);
+ md_number_to_chars (buf, newval, INSN_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_SHIFT_IMM:
+ newval = md_chars_to_number (buf, INSN_SIZE);
+ if (((unsigned long) value) > 32
+ || (value == 32
+ && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("shift expression is too large"));
+ break;
+ }
+
+ if (value == 0)
+ /* Shifts of zero must be done as lsl. */
+ newval &= ~0x60;
+ else if (value == 32)
+ value = 0;
+ newval &= 0xfffff07f;
+ newval |= (value & 0x1f) << 7;
+ md_number_to_chars (buf, newval, INSN_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_SWI:
+ if (arm_data->thumb_mode)
+ {
+ if (((unsigned long) value) > 0xff)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid swi expression"));
+ newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
+ newval |= value;
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ }
+ else
+ {
+ if (((unsigned long) value) > 0x00ffffff)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid swi expression"));
+ newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
+ newval |= value;
+ md_number_to_chars (buf, newval, INSN_SIZE);
+ }
+ break;
+
+ case BFD_RELOC_ARM_MULTI:
+ if (((unsigned long) value) > 0xffff)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid expression in load/store multiple"));
+ newval = value | md_chars_to_number (buf, INSN_SIZE);
+ md_number_to_chars (buf, newval, INSN_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_PCREL_BRANCH:
+ newval = md_chars_to_number (buf, INSN_SIZE);
+
+ /* Sign-extend a 24-bit number. */
+#define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
+
+#ifdef OBJ_ELF
+ if (! target_oabi)
+ value = fixP->fx_offset;
+#endif
+
+ /* We are going to store value (shifted right by two) in the
+ instruction, in a 24 bit, signed field. Thus we need to check
+ that none of the top 8 bits of the shifted value (top 7 bits of
+ the unshifted, unsigned value) are set, or that they are all set. */
+ if ((value & ~ ((offsetT) 0x1ffffff)) != 0
+ && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
+ {
+#ifdef OBJ_ELF
+ /* Normally we would be stuck at this point, since we cannot store
+ the absolute address that is the destination of the branch in the
+ 24 bits of the branch instruction. If however, we happen to know
+ that the destination of the branch is in the same section as the
+ branch instruction itself, then we can compute the relocation for
+ ourselves and not have to bother the linker with it.
+
+ FIXME: The tests for OBJ_ELF and ! target_oabi are only here
+ because I have not worked out how to do this for OBJ_COFF or
+ target_oabi. */
+ if (! target_oabi
+ && fixP->fx_addsy != NULL
+ && S_IS_DEFINED (fixP->fx_addsy)
+ && S_GET_SEGMENT (fixP->fx_addsy) == seg)
+ {
+ /* Get pc relative value to go into the branch. */
+ value = * valP;
+
+ /* Permit a backward branch provided that enough bits
+ are set. Allow a forwards branch, provided that
+ enough bits are clear. */
+ if ( (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
+ || (value & ~ ((offsetT) 0x1ffffff)) == 0)
+ fixP->fx_done = 1;
+ }
+
+ if (! fixP->fx_done)
+#endif
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("GAS can't handle same-section branch dest >= 0x04000000"));
+ }
+
+ value >>= 2;
+ value += SEXT24 (newval);
+
+ if ( (value & ~ ((offsetT) 0xffffff)) != 0
+ && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("out of range branch"));
+
+ newval = (value & 0x00ffffff) | (newval & 0xff000000);
+ md_number_to_chars (buf, newval, INSN_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_PCREL_BLX:
+ {
+ offsetT hbit;
+ newval = md_chars_to_number (buf, INSN_SIZE);
+
+#ifdef OBJ_ELF
+ if (! target_oabi)
+ value = fixP->fx_offset;
+#endif
+ hbit = (value >> 1) & 1;
+ value = (value >> 2) & 0x00ffffff;
+ value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
+ newval = value | (newval & 0xfe000000) | (hbit << 24);
+ md_number_to_chars (buf, newval, INSN_SIZE);
+ }
+ break;
+
+ case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ {
+ addressT diff = (newval & 0xff) << 1;
+ if (diff & 0x100)
+ diff |= ~0xff;
+
+ value += diff;
+ if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("branch out of range"));
+ newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
+ }
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ break;
+
+ case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ {
+ addressT diff = (newval & 0x7ff) << 1;
+ if (diff & 0x800)
+ diff |= ~0x7ff;
+
+ value += diff;
+ if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("branch out of range"));
+ newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
+ }
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ break;
+
+ case BFD_RELOC_THUMB_PCREL_BLX:
+ case BFD_RELOC_THUMB_PCREL_BRANCH23:
+ {
+ offsetT newval2;
+ addressT diff;
+
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
+ diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
+ if (diff & 0x400000)
+ diff |= ~0x3fffff;
+#ifdef OBJ_ELF
+ value = fixP->fx_offset;
+#endif
+ value += diff;
+
+ if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("branch with link out of range"));
+
+ newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
+ newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
+ if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
+ /* For a BLX instruction, make sure that the relocation is rounded up
+ to a word boundary. This follows the semantics of the instruction
+ which specifies that bit 1 of the target address will come from bit
+ 1 of the base address. */
+ newval2 = (newval2 + 1) & ~ 1;
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
+ }
+ break;
+
+ case BFD_RELOC_8:
+ if (fixP->fx_done || fixP->fx_pcrel)
+ md_number_to_chars (buf, value, 1);
+#ifdef OBJ_ELF
+ else if (!target_oabi)
+ {
+ value = fixP->fx_offset;
+ md_number_to_chars (buf, value, 1);
+ }
+#endif
+ break;
+
+ case BFD_RELOC_16:
+ if (fixP->fx_done || fixP->fx_pcrel)
+ md_number_to_chars (buf, value, 2);
+#ifdef OBJ_ELF
+ else if (!target_oabi)
+ {
+ value = fixP->fx_offset;
+ md_number_to_chars (buf, value, 2);
+ }
+#endif
+ break;
+
+#ifdef OBJ_ELF
+ case BFD_RELOC_ARM_GOT32:
+ case BFD_RELOC_ARM_GOTOFF:
+ md_number_to_chars (buf, 0, 4);
+ break;
+#endif
+
+ case BFD_RELOC_RVA:
+ case BFD_RELOC_32:
+ if (fixP->fx_done || fixP->fx_pcrel)
+ md_number_to_chars (buf, value, 4);
+#ifdef OBJ_ELF
+ else if (!target_oabi)
+ {
+ value = fixP->fx_offset;
+ md_number_to_chars (buf, value, 4);
+ }
+#endif
+ break;
+
+#ifdef OBJ_ELF
+ case BFD_RELOC_ARM_PLT32:
+ /* It appears the instruction is fully prepared at this point. */
+ break;
+#endif
+
+ case BFD_RELOC_ARM_CP_OFF_IMM:
+ sign = value >= 0;
+ if (value < -1023 || value > 1023 || (value & 3))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("illegal value for co-processor offset"));
+ if (value < 0)
+ value = -value;
+ newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
+ newval |= (value >> 2) | (sign ? INDEX_UP : 0);
+ md_number_to_chars (buf, newval, INSN_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_CP_OFF_IMM_S2:
+ sign = value >= 0;
+ if (value < -255 || value > 255)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Illegal value for co-processor offset"));
+ if (value < 0)
+ value = -value;
+ newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
+ newval |= value | (sign ? INDEX_UP : 0);
+ md_number_to_chars (buf, newval , INSN_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_THUMB_OFFSET:
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ /* Exactly what ranges, and where the offset is inserted depends
+ on the type of instruction, we can establish this from the
+ top 4 bits. */
+ switch (newval >> 12)
+ {
+ case 4: /* PC load. */
+ /* Thumb PC loads are somewhat odd, bit 1 of the PC is
+ forced to zero for these loads, so we will need to round
+ up the offset if the instruction address is not word
+ aligned (since the final address produced must be, and
+ we can only describe word-aligned immediate offsets). */
+
+ if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid offset, target not word aligned (0x%08X)"),
+ (unsigned int) (fixP->fx_frag->fr_address
+ + fixP->fx_where + value));
+
+ if ((value + 2) & ~0x3fe)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid offset, value too big (0x%08lX)"),
+ (long) value);
+
+ /* Round up, since pc will be rounded down. */
+ newval |= (value + 2) >> 2;
+ break;
+
+ case 9: /* SP load/store. */
+ if (value & ~0x3fc)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid offset, value too big (0x%08lX)"),
+ (long) value);
+ newval |= value >> 2;
+ break;
+
+ case 6: /* Word load/store. */
+ if (value & ~0x7c)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid offset, value too big (0x%08lX)"),
+ (long) value);
+ newval |= value << 4; /* 6 - 2. */
+ break;
+
+ case 7: /* Byte load/store. */
+ if (value & ~0x1f)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid offset, value too big (0x%08lX)"),
+ (long) value);
+ newval |= value << 6;
+ break;
+
+ case 8: /* Halfword load/store. */
+ if (value & ~0x3e)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid offset, value too big (0x%08lX)"),
+ (long) value);
+ newval |= value << 5; /* 6 - 1. */
+ break;
+
+ default:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ "Unable to process relocation for thumb opcode: %lx",
+ (unsigned long) newval);
+ break;
+ }
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_THUMB_ADD:
+ /* This is a complicated relocation, since we use it for all of
+ the following immediate relocations:
+
+ 3bit ADD/SUB
+ 8bit ADD/SUB
+ 9bit ADD/SUB SP word-aligned
+ 10bit ADD PC/SP word-aligned
+
+ The type of instruction being processed is encoded in the
+ instruction field:
+
+ 0x8000 SUB
+ 0x00F0 Rd
+ 0x000F Rs
+ */
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ {
+ int rd = (newval >> 4) & 0xf;
+ int rs = newval & 0xf;
+ int subtract = newval & 0x8000;
+
+ if (rd == REG_SP)
+ {
+ if (value & ~0x1fc)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid immediate for stack address calculation"));
+ newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
+ newval |= value >> 2;
+ }
+ else if (rs == REG_PC || rs == REG_SP)
+ {
+ if (subtract ||
+ value & ~0x3fc)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid immediate for address calculation (value = 0x%08lX)"),
+ (unsigned long) value);
+ newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
+ newval |= rd << 8;
+ newval |= value >> 2;
+ }
+ else if (rs == rd)
+ {
+ if (value & ~0xff)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid 8bit immediate"));
+ newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
+ newval |= (rd << 8) | value;
+ }
+ else
+ {
+ if (value & ~0x7)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid 3bit immediate"));
+ newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
+ newval |= rd | (rs << 3) | (value << 6);
+ }
+ }
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_THUMB_IMM:
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ switch (newval >> 11)
+ {
+ case 0x04: /* 8bit immediate MOV. */
+ case 0x05: /* 8bit immediate CMP. */
+ if (value < 0 || value > 255)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid immediate: %ld is too large"),
+ (long) value);
+ newval |= value;
+ break;
+
+ default:
+ abort ();
+ }
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_THUMB_SHIFT:
+ /* 5bit shift value (0..31). */
+ if (value < 0 || value > 31)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("illegal Thumb shift value: %ld"), (long) value);
+ newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
+ newval |= value << 6;
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ break;
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixP->fx_done = 0;
+ return;
+
+ case BFD_RELOC_NONE:
+ default:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("bad relocation fixup type (%d)"), fixP->fx_r_type);
+ }
+}
+
+/* Translate internal representation of relocation info to BFD target
+ format. */
+
+arelent *
+tc_gen_reloc (section, fixp)
+ asection * section ATTRIBUTE_UNUSED;
+ fixS * fixp;
+{
+ arelent * reloc;
+ bfd_reloc_code_real_type code;
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+
+ /* @@ Why fx_addnumber sometimes and fx_offset other times? */
+#ifndef OBJ_ELF
+ if (fixp->fx_pcrel == 0)
+ reloc->addend = fixp->fx_offset;
+ else
+ reloc->addend = fixp->fx_offset = reloc->address;
+#else /* OBJ_ELF */
+ reloc->addend = fixp->fx_offset;
+#endif
+
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_8:
+ if (fixp->fx_pcrel)
+ {
+ code = BFD_RELOC_8_PCREL;
+ break;
+ }
+
+ case BFD_RELOC_16:
+ if (fixp->fx_pcrel)
+ {
+ code = BFD_RELOC_16_PCREL;
+ break;
+ }
+
+ case BFD_RELOC_32:
+ if (fixp->fx_pcrel)
+ {
+ code = BFD_RELOC_32_PCREL;
+ break;
+ }
+
+ case BFD_RELOC_ARM_PCREL_BRANCH:
+ case BFD_RELOC_ARM_PCREL_BLX:
+ case BFD_RELOC_RVA:
+ case BFD_RELOC_THUMB_PCREL_BRANCH9:
+ case BFD_RELOC_THUMB_PCREL_BRANCH12:
+ case BFD_RELOC_THUMB_PCREL_BRANCH23:
+ case BFD_RELOC_THUMB_PCREL_BLX:
+ case BFD_RELOC_VTABLE_ENTRY:
+ case BFD_RELOC_VTABLE_INHERIT:
+ code = fixp->fx_r_type;
+ break;
+
+ case BFD_RELOC_ARM_LITERAL:
+ case BFD_RELOC_ARM_HWLITERAL:
+ /* If this is called then the a literal has
+ been referenced across a section boundary. */
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("literal referenced across section boundary"));
+ return NULL;
+
+#ifdef OBJ_ELF
+ case BFD_RELOC_ARM_GOT32:
+ case BFD_RELOC_ARM_GOTOFF:
+ case BFD_RELOC_ARM_PLT32:
+ code = fixp->fx_r_type;
+ break;
+#endif
+
+ case BFD_RELOC_ARM_IMMEDIATE:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("internal relocation (type: IMMEDIATE) not fixed up"));
+ return NULL;
+
+ case BFD_RELOC_ARM_ADRL_IMMEDIATE:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("ADRL used for a symbol not defined in the same file"));
+ return NULL;
+
+ case BFD_RELOC_ARM_OFFSET_IMM:
+ if (fixp->fx_addsy != NULL
+ && !S_IS_DEFINED (fixp->fx_addsy)
+ && S_IS_LOCAL (fixp->fx_addsy))
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("undefined local label `%s'"),
+ S_GET_NAME (fixp->fx_addsy));
+ return NULL;
+ }
+
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("internal_relocation (type: OFFSET_IMM) not fixed up"));
+ return NULL;
+
+ default:
+ {
+ char * type;
+
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
+ case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
+ case BFD_RELOC_ARM_SWI: type = "SWI"; break;
+ case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
+ case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
+ case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
+ case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
+ case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
+ case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
+ default: type = _("<unknown>"); break;
+ }
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("cannot represent %s relocation in this object file format"),
+ type);
+ return NULL;
+ }
+ }
+
+#ifdef OBJ_ELF
+ if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
+ && GOT_symbol
+ && fixp->fx_addsy == GOT_symbol)
+ {
+ code = BFD_RELOC_ARM_GOTPC;
+ reloc->addend = fixp->fx_offset = reloc->address;
+ }
+#endif
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+
+ if (reloc->howto == NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("cannot represent %s relocation in this object file format"),
+ bfd_get_reloc_code_name (code));
+ return NULL;
+ }
+
+ /* HACK: Since arm ELF uses Rel instead of Rela, encode the
+ vtable entry to be used in the relocation's section offset. */
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ reloc->address = fixp->fx_offset;
+
+ return reloc;
+}
+
+int
+md_estimate_size_before_relax (fragP, segtype)
+ fragS * fragP ATTRIBUTE_UNUSED;
+ segT segtype ATTRIBUTE_UNUSED;
+{
+ as_fatal (_("md_estimate_size_before_relax\n"));
+ return 1;
+}
+
+static void
+output_inst (str)
+ const char *str;
+{
+ char * to = NULL;
+
+ if (inst.error)
+ {
+ as_bad ("%s -- `%s'", inst.error, str);
+ return;
+ }
+
+ to = frag_more (inst.size);
+
+ if (thumb_mode && (inst.size > THUMB_SIZE))
+ {
+ assert (inst.size == (2 * THUMB_SIZE));
+ md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
+ md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
+ }
+ else if (inst.size > INSN_SIZE)
+ {
+ assert (inst.size == (2 * INSN_SIZE));
+ md_number_to_chars (to, inst.instruction, INSN_SIZE);
+ md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
+ }
+ else
+ md_number_to_chars (to, inst.instruction, inst.size);
+
+ if (inst.reloc.type != BFD_RELOC_NONE)
+ fix_new_arm (frag_now, to - frag_now->fr_literal,
+ inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
+ inst.reloc.type);
+
+#ifdef OBJ_ELF
+ dwarf2_emit_insn (inst.size);
+#endif
+}
+
+void
+md_assemble (str)
+ char * str;
+{
+ char c;
+ char *p;
+ char *start;
+
+ /* Align the instruction.
+ This may not be the right thing to do but ... */
+#if 0
+ arm_align (2, 0);
+#endif
+
+ /* Align the previous label if needed. */
+ if (last_label_seen != NULL)
+ {
+ symbol_set_frag (last_label_seen, frag_now);
+ S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
+ S_SET_SEGMENT (last_label_seen, now_seg);
+ }
+
+ memset (&inst, '\0', sizeof (inst));
+ inst.reloc.type = BFD_RELOC_NONE;
+
+ skip_whitespace (str);
+
+ /* Scan up to the end of the op-code, which must end in white space or
+ end of string. */
+ for (start = p = str; *p != '\0'; p++)
+ if (*p == ' ')
+ break;
+
+ if (p == str)
+ {
+ as_bad (_("no operator -- statement `%s'\n"), str);
+ return;
+ }
+
+ if (thumb_mode)
+ {
+ const struct thumb_opcode * opcode;
+
+ c = *p;
+ *p = '\0';
+ opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
+ *p = c;
+
+ if (opcode)
+ {
+ /* Check that this instruction is supported for this CPU. */
+ if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
+ {
+ as_bad (_("selected processor does not support `%s'"), str);
+ return;
+ }
+
+ mapping_state (MAP_THUMB);
+ inst.instruction = opcode->value;
+ inst.size = opcode->size;
+ (*opcode->parms) (p);
+ output_inst (str);
+ return;
+ }
+ }
+ else
+ {
+ const struct asm_opcode * opcode;
+
+ c = *p;
+ *p = '\0';
+ opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
+ *p = c;
+
+ if (opcode)
+ {
+ /* Check that this instruction is supported for this CPU. */
+ if ((opcode->variant & cpu_variant) == 0)
+ {
+ as_bad (_("selected processor does not support `%s'"), str);
+ return;
+ }
+
+ mapping_state (MAP_ARM);
+ inst.instruction = opcode->value;
+ inst.size = INSN_SIZE;
+ (*opcode->parms) (p);
+ output_inst (str);
+ return;
+ }
+ }
+
+ /* It wasn't an instruction, but it might be a register alias of the form
+ alias .req reg. */
+ if (create_register_alias (str, p))
+ return;
+
+ as_bad (_("bad instruction `%s'"), start);
+}
+
+/* md_parse_option
+ Invocation line includes a switch not recognized by the base assembler.
+ See if it's a processor-specific option.
+
+ This routine is somewhat complicated by the need for backwards
+ compatibility (since older releases of gcc can't be changed).
+ The new options try to make the interface as compatible as
+ possible with GCC.
+
+ New options (supported) are:
+
+ -mcpu=<cpu name> Assemble for selected processor
+ -march=<architecture name> Assemble for selected architecture
+ -mfpu=<fpu architecture> Assemble for selected FPU.
+ -EB/-mbig-endian Big-endian
+ -EL/-mlittle-endian Little-endian
+ -k Generate PIC code
+ -mthumb Start in Thumb mode
+ -mthumb-interwork Code supports ARM/Thumb interworking
+
+ For now we will also provide support for:
+
+ -mapcs-32 32-bit Program counter
+ -mapcs-26 26-bit Program counter
+ -macps-float Floats passed in FP registers
+ -mapcs-reentrant Reentrant code
+ -matpcs
+ (sometime these will probably be replaced with -mapcs=<list of options>
+ and -matpcs=<list of options>)
+
+ The remaining options are only supported for back-wards compatibility.
+ Cpu variants, the arm part is optional:
+ -m[arm]1 Currently not supported.
+ -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
+ -m[arm]3 Arm 3 processor
+ -m[arm]6[xx], Arm 6 processors
+ -m[arm]7[xx][t][[d]m] Arm 7 processors
+ -m[arm]8[10] Arm 8 processors
+ -m[arm]9[20][tdmi] Arm 9 processors
+ -mstrongarm[110[0]] StrongARM processors
+ -mxscale XScale processors
+ -m[arm]v[2345[t[e]]] Arm architectures
+ -mall All (except the ARM1)
+ FP variants:
+ -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
+ -mfpe-old (No float load/store multiples)
+ -mvfpxd VFP Single precision
+ -mvfp All VFP
+ -mno-fpu Disable all floating point instructions
+
+ The following CPU names are recognized:
+ arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
+ arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
+ arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
+ arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
+ arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
+ arm10t arm10e, arm1020t, arm1020e, arm10200e,
+ strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
+
+ */
+
+const char * md_shortopts = "m:k";
+
+#ifdef ARM_BI_ENDIAN
+#define OPTION_EB (OPTION_MD_BASE + 0)
+#define OPTION_EL (OPTION_MD_BASE + 1)
+#else
+#if TARGET_BYTES_BIG_ENDIAN
+#define OPTION_EB (OPTION_MD_BASE + 0)
+#else
+#define OPTION_EL (OPTION_MD_BASE + 1)
+#endif
+#endif
+
+struct option md_longopts[] =
+{
+#ifdef OPTION_EB
+ {"EB", no_argument, NULL, OPTION_EB},
+#endif
+#ifdef OPTION_EL
+ {"EL", no_argument, NULL, OPTION_EL},
+#endif
+ {NULL, no_argument, NULL, 0}
+};
+
+size_t md_longopts_size = sizeof (md_longopts);
+
+struct arm_option_table
+{
+ char *option; /* Option name to match. */
+ char *help; /* Help information. */
+ int *var; /* Variable to change. */
+ int value; /* What to change it to. */
+ char *deprecated; /* If non-null, print this message. */
+};
+
+struct arm_option_table arm_opts[] =
+{
+ {"k", N_("generate PIC code"), &pic_code, 1, NULL},
+ {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
+ {"mthumb-interwork", N_("support ARM/Thumb interworking"),
+ &support_interwork, 1, NULL},
+ {"moabi", N_("use old ABI (ELF only)"), &target_oabi, 1, NULL},
+ {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
+ {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
+ {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
+ 1, NULL},
+ {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
+ {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
+ {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
+ {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
+ NULL},
+
+ /* These are recognized by the assembler, but have no affect on code. */
+ {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
+ {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
+
+ /* DON'T add any new processors to this list -- we want the whole list
+ to go away... Add them to the processors table instead. */
+ {"marm1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
+ {"m1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
+ {"marm2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
+ {"m2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
+ {"marm250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
+ {"m250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
+ {"marm3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
+ {"m3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
+ {"marm6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
+ {"m6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
+ {"marm600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
+ {"m600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
+ {"marm610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
+ {"m610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
+ {"marm620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
+ {"m620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
+ {"marm7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
+ {"m7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
+ {"marm70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
+ {"m70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
+ {"marm700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
+ {"m700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
+ {"marm700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
+ {"m700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
+ {"marm710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
+ {"m710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
+ {"marm710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
+ {"m710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
+ {"marm720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
+ {"m720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
+ {"marm7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
+ {"m7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
+ {"marm7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
+ {"m7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
+ {"marm7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
+ {"m7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
+ {"marm7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
+ {"m7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
+ {"marm7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
+ {"m7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
+ {"marm7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
+ {"m7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
+ {"marm7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
+ {"m7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
+ {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
+ {"m7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
+ {"marm7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
+ {"m7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
+ {"marm7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
+ {"m7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
+ {"marm710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
+ {"m710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
+ {"marm720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
+ {"m720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
+ {"marm740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
+ {"m740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
+ {"marm8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
+ {"m8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
+ {"marm810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
+ {"m810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
+ {"marm9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
+ {"m9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
+ {"marm9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
+ {"m9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
+ {"marm920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
+ {"m920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
+ {"marm940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
+ {"m940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
+ {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
+ {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
+ N_("use -mcpu=strongarm110")},
+ {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
+ N_("use -mcpu=strongarm1100")},
+ {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
+ N_("use -mcpu=strongarm1110")},
+ {"mxscale", NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
+ {"miwmmxt", NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
+ {"mall", NULL, &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
+
+ /* Architecture variants -- don't add any more to this list either. */
+ {"mv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
+ {"marmv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
+ {"mv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
+ {"marmv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
+ {"mv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
+ {"marmv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
+ {"mv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
+ {"marmv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
+ {"mv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
+ {"marmv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
+ {"mv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
+ {"marmv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
+ {"mv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
+ {"marmv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
+ {"mv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
+ {"marmv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
+ {"mv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
+ {"marmv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
+
+ /* Floating point variants -- don't add any more to this list either. */
+ {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
+ {"mfpa10", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
+ {"mfpa11", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
+ {"mno-fpu", NULL, &legacy_fpu, 0,
+ N_("use either -mfpu=softfpa or -mfpu=softvfp")},
+
+ {NULL, NULL, NULL, 0, NULL}
+};
+
+struct arm_cpu_option_table
+{
+ char *name;
+ int value;
+ /* For some CPUs we assume an FPU unless the user explicitly sets
+ -mfpu=... */
+ int default_fpu;
+};
+
+/* This list should, at a minimum, contain all the cpu names
+ recognized by GCC. */
+static struct arm_cpu_option_table arm_cpus[] =
+{
+ {"all", ARM_ANY, FPU_ARCH_FPA},
+ {"arm1", ARM_ARCH_V1, FPU_ARCH_FPA},
+ {"arm2", ARM_ARCH_V2, FPU_ARCH_FPA},
+ {"arm250", ARM_ARCH_V2S, FPU_ARCH_FPA},
+ {"arm3", ARM_ARCH_V2S, FPU_ARCH_FPA},
+ {"arm6", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm60", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm600", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm610", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm620", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm7", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm7m", ARM_ARCH_V3M, FPU_ARCH_FPA},
+ {"arm7d", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm7dm", ARM_ARCH_V3M, FPU_ARCH_FPA},
+ {"arm7di", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm7dmi", ARM_ARCH_V3M, FPU_ARCH_FPA},
+ {"arm70", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm700", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm700i", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm710", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm710t", ARM_ARCH_V4T, FPU_ARCH_FPA},
+ {"arm720", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm720t", ARM_ARCH_V4T, FPU_ARCH_FPA},
+ {"arm740t", ARM_ARCH_V4T, FPU_ARCH_FPA},
+ {"arm710c", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm7100", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm7500", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm7500fe", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"arm7t", ARM_ARCH_V4T, FPU_ARCH_FPA},
+ {"arm7tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA},
+ {"arm8", ARM_ARCH_V4, FPU_ARCH_FPA},
+ {"arm810", ARM_ARCH_V4, FPU_ARCH_FPA},
+ {"strongarm", ARM_ARCH_V4, FPU_ARCH_FPA},
+ {"strongarm1", ARM_ARCH_V4, FPU_ARCH_FPA},
+ {"strongarm110", ARM_ARCH_V4, FPU_ARCH_FPA},
+ {"strongarm1100", ARM_ARCH_V4, FPU_ARCH_FPA},
+ {"strongarm1110", ARM_ARCH_V4, FPU_ARCH_FPA},
+ {"arm9", ARM_ARCH_V4T, FPU_ARCH_FPA},
+ {"arm920", ARM_ARCH_V4T, FPU_ARCH_FPA},
+ {"arm920t", ARM_ARCH_V4T, FPU_ARCH_FPA},
+ {"arm922t", ARM_ARCH_V4T, FPU_ARCH_FPA},
+ {"arm940t", ARM_ARCH_V4T, FPU_ARCH_FPA},
+ {"arm9tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA},
+ /* For V5 or later processors we default to using VFP; but the user
+ should really set the FPU type explicitly. */
+ {"arm9e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
+ {"arm9e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
+ {"arm926ej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2},
+ {"arm926ejs", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2},
+ {"arm946e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
+ {"arm946e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
+ {"arm966e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
+ {"arm966e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
+ {"arm10t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1},
+ {"arm10e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
+ {"arm1020", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
+ {"arm1020t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1},
+ {"arm1020e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
+ {"arm1026ejs", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
+ {"arm1136js", ARM_ARCH_V6, FPU_NONE},
+ {"arm1136jfs", ARM_ARCH_V6, FPU_ARCH_VFP_V2},
+ /* ??? XSCALE is really an architecture. */
+ {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
+ /* ??? iwmmxt is not a processor. */
+ {"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
+ {"i80200", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
+ /* Maverick */
+ {"ep9312", ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_ARCH_MAVERICK},
+ {NULL, 0, 0}
+};
+
+struct arm_arch_option_table
+{
+ char *name;
+ int value;
+ int default_fpu;
+};
+
+/* This list should, at a minimum, contain all the architecture names
+ recognized by GCC. */
+static struct arm_arch_option_table arm_archs[] =
+{
+ {"all", ARM_ANY, FPU_ARCH_FPA},
+ {"armv1", ARM_ARCH_V1, FPU_ARCH_FPA},
+ {"armv2", ARM_ARCH_V2, FPU_ARCH_FPA},
+ {"armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA},
+ {"armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA},
+ {"armv3", ARM_ARCH_V3, FPU_ARCH_FPA},
+ {"armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA},
+ {"armv4", ARM_ARCH_V4, FPU_ARCH_FPA},
+ {"armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA},
+ {"armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA},
+ {"armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA},
+ {"armv5", ARM_ARCH_V5, FPU_ARCH_VFP},
+ {"armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP},
+ {"armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP},
+ {"armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP},
+ {"armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP},
+ {"armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP},
+ {"armv6", ARM_ARCH_V6, FPU_ARCH_VFP},
+ {"armv6j", ARM_ARCH_V6, FPU_ARCH_VFP},
+ {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP},
+ {"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
+ {NULL, 0, 0}
+};
+
+/* ISA extensions in the co-processor space. */
+struct arm_arch_extension_table
+{
+ char *name;
+ int value;
+};
+
+static struct arm_arch_extension_table arm_extensions[] =
+{
+ {"maverick", ARM_CEXT_MAVERICK},
+ {"xscale", ARM_CEXT_XSCALE},
+ {"iwmmxt", ARM_CEXT_IWMMXT},
+ {NULL, 0}
+};
+
+struct arm_fpu_option_table
+{
+ char *name;
+ int value;
+};
+
+/* This list should, at a minimum, contain all the fpu names
+ recognized by GCC. */
+static struct arm_fpu_option_table arm_fpus[] =
+{
+ {"softfpa", FPU_NONE},
+ {"fpe", FPU_ARCH_FPE},
+ {"fpe2", FPU_ARCH_FPE},
+ {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
+ {"fpa", FPU_ARCH_FPA},
+ {"fpa10", FPU_ARCH_FPA},
+ {"fpa11", FPU_ARCH_FPA},
+ {"arm7500fe", FPU_ARCH_FPA},
+ {"softvfp", FPU_ARCH_VFP},
+ {"softvfp+vfp", FPU_ARCH_VFP_V2},
+ {"vfp", FPU_ARCH_VFP_V2},
+ {"vfp9", FPU_ARCH_VFP_V2},
+ {"vfp10", FPU_ARCH_VFP_V2},
+ {"vfp10-r0", FPU_ARCH_VFP_V1},
+ {"vfpxd", FPU_ARCH_VFP_V1xD},
+ {"arm1020t", FPU_ARCH_VFP_V1},
+ {"arm1020e", FPU_ARCH_VFP_V2},
+ {"arm1136jfs", FPU_ARCH_VFP_V2},
+ {"maverick", FPU_ARCH_MAVERICK},
+ {NULL, 0}
+};
+
+struct arm_float_abi_option_table
+{
+ char *name;
+ int value;
+};
+
+static struct arm_float_abi_option_table arm_float_abis[] =
+{
+ {"hard", ARM_FLOAT_ABI_HARD},
+ {"softfp", ARM_FLOAT_ABI_SOFTFP},
+ {"soft", ARM_FLOAT_ABI_SOFT},
+ {NULL, 0}
+};
+
+struct arm_long_option_table
+{
+ char *option; /* Substring to match. */
+ char *help; /* Help information. */
+ int (*func) PARAMS ((char *subopt)); /* Function to decode sub-option. */
+ char *deprecated; /* If non-null, print this message. */
+};
+
+static int
+arm_parse_extension (str, opt_p)
+ char *str;
+ int *opt_p;
+{
+ while (str != NULL && *str != 0)
+ {
+ struct arm_arch_extension_table *opt;
+ char *ext;
+ int optlen;
+
+ if (*str != '+')
+ {
+ as_bad (_("invalid architectural extension"));
+ return 0;
+ }
+
+ str++;
+ ext = strchr (str, '+');
+
+ if (ext != NULL)
+ optlen = ext - str;
+ else
+ optlen = strlen (str);
+
+ if (optlen == 0)
+ {
+ as_bad (_("missing architectural extension"));
+ return 0;
+ }
+
+ for (opt = arm_extensions; opt->name != NULL; opt++)
+ if (strncmp (opt->name, str, optlen) == 0)
+ {
+ *opt_p |= opt->value;
+ break;
+ }
+
+ if (opt->name == NULL)
+ {
+ as_bad (_("unknown architectural extnsion `%s'"), str);
+ return 0;
+ }
+
+ str = ext;
+ };
+
+ return 1;
+}
+
+static int
+arm_parse_cpu (str)
+ char *str;
+{
+ struct arm_cpu_option_table *opt;
+ char *ext = strchr (str, '+');
+ int optlen;
+
+ if (ext != NULL)
+ optlen = ext - str;
+ else
+ optlen = strlen (str);
+
+ if (optlen == 0)
+ {
+ as_bad (_("missing cpu name `%s'"), str);
+ return 0;
+ }
+
+ for (opt = arm_cpus; opt->name != NULL; opt++)
+ if (strncmp (opt->name, str, optlen) == 0)
+ {
+ mcpu_cpu_opt = opt->value;
+ mcpu_fpu_opt = opt->default_fpu;
+
+ if (ext != NULL)
+ return arm_parse_extension (ext, &mcpu_cpu_opt);
+
+ return 1;
+ }
+
+ as_bad (_("unknown cpu `%s'"), str);
+ return 0;
+}
+
+static int
+arm_parse_arch (str)
+ char *str;
+{
+ struct arm_arch_option_table *opt;
+ char *ext = strchr (str, '+');
+ int optlen;
+
+ if (ext != NULL)
+ optlen = ext - str;
+ else
+ optlen = strlen (str);
+
+ if (optlen == 0)
+ {
+ as_bad (_("missing architecture name `%s'"), str);
+ return 0;
+ }
+
+
+ for (opt = arm_archs; opt->name != NULL; opt++)
+ if (strcmp (opt->name, str) == 0)
+ {
+ march_cpu_opt = opt->value;
+ march_fpu_opt = opt->default_fpu;
+
+ if (ext != NULL)
+ return arm_parse_extension (ext, &march_cpu_opt);
+
+ return 1;
+ }
+
+ as_bad (_("unknown architecture `%s'\n"), str);
+ return 0;
+}
+
+static int
+arm_parse_fpu (str)
+ char *str;
+{
+ struct arm_fpu_option_table *opt;
+
+ for (opt = arm_fpus; opt->name != NULL; opt++)
+ if (strcmp (opt->name, str) == 0)
+ {
+ mfpu_opt = opt->value;
+ return 1;
+ }
+
+ as_bad (_("unknown floating point format `%s'\n"), str);
+ return 0;
+}
+
+static int
+arm_parse_float_abi (str)
+ char * str;
+{
+ struct arm_float_abi_option_table *opt;
+
+ for (opt = arm_float_abis; opt->name != NULL; opt++)
+ if (strcmp (opt->name, str) == 0)
+ {
+ mfloat_abi_opt = opt->value;
+ return 1;
+ }
+
+ as_bad (_("unknown floating point abi `%s'\n"), str);
+ return 0;
+}
+
+struct arm_long_option_table arm_long_opts[] =
+{
+ {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
+ arm_parse_cpu, NULL},
+ {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
+ arm_parse_arch, NULL},
+ {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
+ arm_parse_fpu, NULL},
+ {"mfloat-abi=", N_("<abi>\t assemble for floating point ABI <abi>"),
+ arm_parse_float_abi, NULL},
+ {NULL, NULL, 0, NULL}
+};
+
+int
+md_parse_option (c, arg)
+ int c;
+ char * arg;
+{
+ struct arm_option_table *opt;
+ struct arm_long_option_table *lopt;
+
+ switch (c)
+ {
+#ifdef OPTION_EB
+ case OPTION_EB:
+ target_big_endian = 1;
+ break;
+#endif
+
+#ifdef OPTION_EL
+ case OPTION_EL:
+ target_big_endian = 0;
+ break;
+#endif
+
+ case 'a':
+ /* Listing option. Just ignore these, we don't support additional
+ ones. */
+ return 0;
+
+ default:
+ for (opt = arm_opts; opt->option != NULL; opt++)
+ {
+ if (c == opt->option[0]
+ && ((arg == NULL && opt->option[1] == 0)
+ || strcmp (arg, opt->option + 1) == 0))
+ {
+#if WARN_DEPRECATED
+ /* If the option is deprecated, tell the user. */
+ if (opt->deprecated != NULL)
+ as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
+ arg ? arg : "", _(opt->deprecated));
+#endif
+
+ if (opt->var != NULL)
+ *opt->var = opt->value;
+
+ return 1;
+ }
+ }
+
+ for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
+ {
+ /* These options are expected to have an argument. */
+ if (c == lopt->option[0]
+ && arg != NULL
+ && strncmp (arg, lopt->option + 1,
+ strlen (lopt->option + 1)) == 0)
+ {
+#if WARN_DEPRECATED
+ /* If the option is deprecated, tell the user. */
+ if (lopt->deprecated != NULL)
+ as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
+ _(lopt->deprecated));
+#endif
+
+ /* Call the sup-option parser. */
+ return (*lopt->func)(arg + strlen (lopt->option) - 1);
+ }
+ }
+
+ as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : "");
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (fp)
+ FILE * fp;
+{
+ struct arm_option_table *opt;
+ struct arm_long_option_table *lopt;
+
+ fprintf (fp, _(" ARM-specific assembler options:\n"));
+
+ for (opt = arm_opts; opt->option != NULL; opt++)
+ if (opt->help != NULL)
+ fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
+
+ for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
+ if (lopt->help != NULL)
+ fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
+
+#ifdef OPTION_EB
+ fprintf (fp, _("\
+ -EB assemble code for a big-endian cpu\n"));
+#endif
+
+#ifdef OPTION_EL
+ fprintf (fp, _("\
+ -EL assemble code for a little-endian cpu\n"));
+#endif
+}
+
+/* We need to be able to fix up arbitrary expressions in some statements.
+ This is so that we can handle symbols that are an arbitrary distance from
+ the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
+ which returns part of an address in a form which will be valid for
+ a data instruction. We do this by pushing the expression into a symbol
+ in the expr_section, and creating a fix for that. */
+
+static void
+fix_new_arm (frag, where, size, exp, pc_rel, reloc)
+ fragS * frag;
+ int where;
+ short int size;
+ expressionS * exp;
+ int pc_rel;
+ int reloc;
+{
+ fixS * new_fix;
+ arm_fix_data * arm_data;
+
+ switch (exp->X_op)
+ {
+ case O_constant:
+ case O_symbol:
+ case O_add:
+ case O_subtract:
+ new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
+ break;
+
+ default:
+ new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
+ pc_rel, reloc);
+ break;
+ }
+
+ /* Mark whether the fix is to a THUMB instruction, or an ARM
+ instruction. */
+ arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
+ new_fix->tc_fix_data = (PTR) arm_data;
+ arm_data->thumb_mode = thumb_mode;
+}
+
+/* This fix_new is called by cons via TC_CONS_FIX_NEW. */
+
+void
+cons_fix_new_arm (frag, where, size, exp)
+ fragS * frag;
+ int where;
+ int size;
+ expressionS * exp;
+{
+ bfd_reloc_code_real_type type;
+ int pcrel = 0;
+
+ /* Pick a reloc.
+ FIXME: @@ Should look at CPU word size. */
+ switch (size)
+ {
+ case 1:
+ type = BFD_RELOC_8;
+ break;
+ case 2:
+ type = BFD_RELOC_16;
+ break;
+ case 4:
+ default:
+ type = BFD_RELOC_32;
+ break;
+ case 8:
+ type = BFD_RELOC_64;
+ break;
+ }
+
+ fix_new_exp (frag, where, (int) size, exp, pcrel, type);
+}
+
+/* A good place to do this, although this was probably not intended
+ for this kind of use. We need to dump the literal pool before
+ references are made to a null symbol pointer. */
+
+void
+arm_cleanup ()
+{
+ literal_pool * pool;
+
+ for (pool = list_of_pools; pool; pool = pool->next)
+ {
+ /* Put it at the end of the relevent section. */
+ subseg_set (pool->section, pool->sub_section);
+#ifdef OBJ_ELF
+ arm_elf_change_section ();
+#endif
+ s_ltorg (0);
+ }
+}
+
+void
+arm_start_line_hook ()
+{
+ last_label_seen = NULL;
+}
+
+void
+arm_frob_label (sym)
+ symbolS * sym;
+{
+ last_label_seen = sym;
+
+ ARM_SET_THUMB (sym, thumb_mode);
+
+#if defined OBJ_COFF || defined OBJ_ELF
+ ARM_SET_INTERWORK (sym, support_interwork);
+#endif
+
+ /* Note - do not allow local symbols (.Lxxx) to be labeled
+ as Thumb functions. This is because these labels, whilst
+ they exist inside Thumb code, are not the entry points for
+ possible ARM->Thumb calls. Also, these labels can be used
+ as part of a computed goto or switch statement. eg gcc
+ can generate code that looks like this:
+
+ ldr r2, [pc, .Laaa]
+ lsl r3, r3, #2
+ ldr r2, [r3, r2]
+ mov pc, r2
+
+ .Lbbb: .word .Lxxx
+ .Lccc: .word .Lyyy
+ ..etc...
+ .Laaa: .word Lbbb
+
+ The first instruction loads the address of the jump table.
+ The second instruction converts a table index into a byte offset.
+ The third instruction gets the jump address out of the table.
+ The fourth instruction performs the jump.
+
+ If the address stored at .Laaa is that of a symbol which has the
+ Thumb_Func bit set, then the linker will arrange for this address
+ to have the bottom bit set, which in turn would mean that the
+ address computation performed by the third instruction would end
+ up with the bottom bit set. Since the ARM is capable of unaligned
+ word loads, the instruction would then load the incorrect address
+ out of the jump table, and chaos would ensue. */
+ if (label_is_thumb_function_name
+ && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
+ && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
+ {
+ /* When the address of a Thumb function is taken the bottom
+ bit of that address should be set. This will allow
+ interworking between Arm and Thumb functions to work
+ correctly. */
+
+ THUMB_SET_FUNC (sym, 1);
+
+ label_is_thumb_function_name = FALSE;
+ }
+}
+
+/* Adjust the symbol table. This marks Thumb symbols as distinct from
+ ARM ones. */
+
+void
+arm_adjust_symtab ()
+{
+#ifdef OBJ_COFF
+ symbolS * sym;
+
+ for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
+ {
+ if (ARM_IS_THUMB (sym))
+ {
+ if (THUMB_IS_FUNC (sym))
+ {
+ /* Mark the symbol as a Thumb function. */
+ if ( S_GET_STORAGE_CLASS (sym) == C_STAT
+ || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
+ S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
+
+ else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
+ S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
+ else
+ as_bad (_("%s: unexpected function type: %d"),
+ S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
+ }
+ else switch (S_GET_STORAGE_CLASS (sym))
+ {
+ case C_EXT:
+ S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
+ break;
+ case C_STAT:
+ S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
+ break;
+ case C_LABEL:
+ S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
+ break;
+ default:
+ /* Do nothing. */
+ break;
+ }
+ }
+
+ if (ARM_IS_INTERWORK (sym))
+ coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
+ }
+#endif
+#ifdef OBJ_ELF
+ symbolS * sym;
+ char bind;
+
+ for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
+ {
+ if (ARM_IS_THUMB (sym))
+ {
+ elf_symbol_type * elf_sym;
+
+ elf_sym = elf_symbol (symbol_get_bfdsym (sym));
+ bind = ELF_ST_BIND (elf_sym);
+
+ /* If it's a .thumb_func, declare it as so,
+ otherwise tag label as .code 16. */
+ if (THUMB_IS_FUNC (sym))
+ elf_sym->internal_elf_sym.st_info =
+ ELF_ST_INFO (bind, STT_ARM_TFUNC);
+ else
+ elf_sym->internal_elf_sym.st_info =
+ ELF_ST_INFO (bind, STT_ARM_16BIT);
+ }
+ }
+#endif
+}
+
+int
+arm_data_in_code ()
+{
+ if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
+ {
+ *input_line_pointer = '/';
+ input_line_pointer += 5;
+ *input_line_pointer = 0;
+ return 1;
+ }
+
+ return 0;
+}
+
+char *
+arm_canonicalize_symbol_name (name)
+ char * name;
+{
+ int len;
+
+ if (thumb_mode && (len = strlen (name)) > 5
+ && streq (name + len - 5, "/data"))
+ *(name + len - 5) = 0;
+
+ return name;
+}
+
+#if defined OBJ_COFF || defined OBJ_ELF
+void
+arm_validate_fix (fixP)
+ fixS * fixP;
+{
+ /* If the destination of the branch is a defined symbol which does not have
+ the THUMB_FUNC attribute, then we must be calling a function which has
+ the (interfacearm) attribute. We look for the Thumb entry point to that
+ function and change the branch to refer to that function instead. */
+ if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
+ && fixP->fx_addsy != NULL
+ && S_IS_DEFINED (fixP->fx_addsy)
+ && ! THUMB_IS_FUNC (fixP->fx_addsy))
+ {
+ fixP->fx_addsy = find_real_start (fixP->fx_addsy);
+ }
+}
+#endif
+
+int
+arm_force_relocation (fixp)
+ struct fix * fixp;
+{
+#if defined (OBJ_COFF) && defined (TE_PE)
+ if (fixp->fx_r_type == BFD_RELOC_RVA)
+ return 1;
+#endif
+#ifdef OBJ_ELF
+ if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
+ || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
+ || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
+ || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
+ return 1;
+#endif
+
+ /* Resolve these relocations even if the symbol is extern or weak. */
+ if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
+ || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
+ || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
+ return 0;
+
+ return generic_force_reloc (fixp);
+}
+
+#ifdef OBJ_COFF
+/* This is a little hack to help the gas/arm/adrl.s test. It prevents
+ local labels from being added to the output symbol table when they
+ are used with the ADRL pseudo op. The ADRL relocation should always
+ be resolved before the binbary is emitted, so it is safe to say that
+ it is adjustable. */
+
+bfd_boolean
+arm_fix_adjustable (fixP)
+ fixS * fixP;
+{
+ if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
+ return 1;
+ return 0;
+}
+#endif
+
+#ifdef OBJ_ELF
+/* Relocations against Thumb function names must be left unadjusted,
+ so that the linker can use this information to correctly set the
+ bottom bit of their addresses. The MIPS version of this function
+ also prevents relocations that are mips-16 specific, but I do not
+ know why it does this.
+
+ FIXME:
+ There is one other problem that ought to be addressed here, but
+ which currently is not: Taking the address of a label (rather
+ than a function) and then later jumping to that address. Such
+ addresses also ought to have their bottom bit set (assuming that
+ they reside in Thumb code), but at the moment they will not. */
+
+bfd_boolean
+arm_fix_adjustable (fixP)
+ fixS * fixP;
+{
+ if (fixP->fx_addsy == NULL)
+ return 1;
+
+ if (THUMB_IS_FUNC (fixP->fx_addsy)
+ && fixP->fx_subsy == NULL)
+ return 0;
+
+ /* We need the symbol name for the VTABLE entries. */
+ if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+
+ /* Don't allow symbols to be discarded on GOT related relocs. */
+ if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
+ || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
+ || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF)
+ return 0;
+
+ return 1;
+}
+
+const char *
+elf32_arm_target_format ()
+{
+ if (target_big_endian)
+ {
+ if (target_oabi)
+ return "elf32-bigarm-oabi";
+ else
+ return "elf32-bigarm";
+ }
+ else
+ {
+ if (target_oabi)
+ return "elf32-littlearm-oabi";
+ else
+ return "elf32-littlearm";
+ }
+}
+
+void
+armelf_frob_symbol (symp, puntp)
+ symbolS * symp;
+ int * puntp;
+{
+ elf_frob_symbol (symp, puntp);
+}
+
+static bfd_reloc_code_real_type
+arm_parse_reloc ()
+{
+ char id [16];
+ char * ip;
+ unsigned int i;
+ static struct
+ {
+ char * str;
+ int len;
+ bfd_reloc_code_real_type reloc;
+ }
+ reloc_map[] =
+ {
+#define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
+ MAP ("(got)", BFD_RELOC_ARM_GOT32),
+ MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
+ /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
+ branch instructions generated by GCC for PLT relocs. */
+ MAP ("(plt)", BFD_RELOC_ARM_PLT32),
+ { NULL, 0, BFD_RELOC_UNUSED }
+#undef MAP
+ };
+
+ for (i = 0, ip = input_line_pointer;
+ i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
+ i++, ip++)
+ id[i] = TOLOWER (*ip);
+
+ for (i = 0; reloc_map[i].str; i++)
+ if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
+ break;
+
+ input_line_pointer += reloc_map[i].len;
+
+ return reloc_map[i].reloc;
+}
+
+static void
+s_arm_elf_cons (nbytes)
+ int nbytes;
+{
+ expressionS exp;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ if (is_it_end_of_statement ())
+ {
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+#ifdef md_cons_align
+ md_cons_align (nbytes);
+#endif
+
+ mapping_state (MAP_DATA);
+ do
+ {
+ bfd_reloc_code_real_type reloc;
+
+ expression (& exp);
+
+ if (exp.X_op == O_symbol
+ && * input_line_pointer == '('
+ && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
+ {
+ reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
+ int size = bfd_get_reloc_size (howto);
+
+ if (size > nbytes)
+ as_bad ("%s relocations do not fit in %d bytes",
+ howto->name, nbytes);
+ else
+ {
+ register char *p = frag_more ((int) nbytes);
+ int offset = nbytes - size;
+
+ fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
+ &exp, 0, reloc);
+ }
+ }
+ else
+ emit_expr (&exp, (unsigned int) nbytes);
+ }
+ while (*input_line_pointer++ == ',');
+
+ /* Put terminator back into stream. */
+ input_line_pointer --;
+ demand_empty_rest_of_line ();
+}
+
+#endif /* OBJ_ELF */
+
+/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
+ of an rs_align_code fragment. */
+
+void
+arm_handle_align (fragP)
+ fragS *fragP;
+{
+ static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
+ static char const thumb_noop[2] = { 0xc0, 0x46 };
+ static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
+ static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
+
+ int bytes, fix, noop_size;
+ char * p;
+ const char * noop;
+
+ if (fragP->fr_type != rs_align_code)
+ return;
+
+ bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
+ p = fragP->fr_literal + fragP->fr_fix;
+ fix = 0;
+
+ if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
+ bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
+
+ if (fragP->tc_frag_data)
+ {
+ if (target_big_endian)
+ noop = thumb_bigend_noop;
+ else
+ noop = thumb_noop;
+ noop_size = sizeof (thumb_noop);
+ }
+ else
+ {
+ if (target_big_endian)
+ noop = arm_bigend_noop;
+ else
+ noop = arm_noop;
+ noop_size = sizeof (arm_noop);
+ }
+
+ if (bytes & (noop_size - 1))
+ {
+ fix = bytes & (noop_size - 1);
+ memset (p, 0, fix);
+ p += fix;
+ bytes -= fix;
+ }
+
+ while (bytes >= noop_size)
+ {
+ memcpy (p, noop, noop_size);
+ p += noop_size;
+ bytes -= noop_size;
+ fix += noop_size;
+ }
+
+ fragP->fr_fix += fix;
+ fragP->fr_var = noop_size;
+}
+
+/* Called from md_do_align. Used to create an alignment
+ frag in a code section. */
+
+void
+arm_frag_align_code (n, max)
+ int n;
+ int max;
+{
+ char * p;
+
+ /* We assume that there will never be a requirement
+ to support alignments greater than 32 bytes. */
+ if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
+ as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
+
+ p = frag_var (rs_align_code,
+ MAX_MEM_FOR_RS_ALIGN_CODE,
+ 1,
+ (relax_substateT) max,
+ (symbolS *) NULL,
+ (offsetT) n,
+ (char *) NULL);
+ *p = 0;
+
+}
+
+/* Perform target specific initialisation of a frag. */
+
+void
+arm_init_frag (fragP)
+ fragS *fragP;
+{
+ /* Record whether this frag is in an ARM or a THUMB area. */
+ fragP->tc_frag_data = thumb_mode;
+}
diff --git a/x/binutils/gas/config/tc-arm.h b/x/binutils/gas/config/tc-arm.h
new file mode 100644
index 0000000..4e791a0
--- /dev/null
+++ b/x/binutils/gas/config/tc-arm.h
@@ -0,0 +1,211 @@
+/* This file is tc-arm.h
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004
+ Free Software Foundation, Inc.
+ Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+ Modified by David Taylor (dtaylor@armltd.co.uk)
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_ARM 1
+
+#ifndef TARGET_BYTES_BIG_ENDIAN
+#define TARGET_BYTES_BIG_ENDIAN 0
+#endif
+
+#define WORKING_DOT_WORD
+
+#define COFF_MAGIC ARMMAGIC
+#define TARGET_ARCH bfd_arch_arm
+
+#define AOUT_MACHTYPE 0
+
+#define DIFF_EXPR_OK
+
+#ifdef LITTLE_ENDIAN
+#undef LITTLE_ENDIAN
+#endif
+
+#ifdef BIG_ENDIAN
+#undef BIG_ENDIAN
+#endif
+
+#define LITTLE_ENDIAN 1234
+#define BIG_ENDIAN 4321
+
+struct fix;
+
+#if defined OBJ_AOUT
+# if defined TE_RISCIX
+# define TARGET_FORMAT "a.out-riscix"
+# elif defined TE_LINUX
+# define ARM_BI_ENDIAN
+# define TARGET_FORMAT "a.out-arm-linux"
+# elif defined TE_NetBSD
+# define TARGET_FORMAT "a.out-arm-netbsd"
+# else
+# define ARM_BI_ENDIAN
+# define TARGET_FORMAT (target_big_endian ? "a.out-arm-big" : "a.out-arm-little")
+# endif
+#elif defined OBJ_AIF
+# define TARGET_FORMAT "aif"
+#elif defined OBJ_COFF
+# define ARM_BI_ENDIAN
+# if defined TE_PE
+# if defined TE_EPOC
+# define TARGET_FORMAT (target_big_endian ? "epoc-pe-arm-big" : "epoc-pe-arm-little")
+# else
+# define TARGET_FORMAT (target_big_endian ? "pe-arm-big" : "pe-arm-little")
+# endif
+# else
+# define TARGET_FORMAT (target_big_endian ? "coff-arm-big" : "coff-arm-little")
+# endif
+#elif defined OBJ_ELF
+# define ARM_BI_ENDIAN
+# define TARGET_FORMAT elf32_arm_target_format ()
+#endif
+
+#define TC_FORCE_RELOCATION(FIX) arm_force_relocation (FIX)
+
+#define md_convert_frag(b, s, f) { as_fatal (_("arm convert_frag\n")); }
+
+#define md_cleanup() arm_cleanup ()
+
+#define md_start_line_hook() arm_start_line_hook ()
+
+#define tc_frob_label(S) arm_frob_label (S)
+
+/* We also need to mark assembler created symbols: */
+#define tc_frob_fake_label(S) arm_frob_label (S)
+
+/* NOTE: The fake label creation in stabs.c:s_stab_generic() has
+ deliberately not been updated to mark assembler created stabs
+ symbols as Thumb. */
+
+#define TC_FIX_TYPE PTR
+#define TC_INIT_FIX_DATA(FIX) ((FIX)->tc_fix_data = NULL)
+
+/* We need to keep some local information on symbols. */
+
+#define TC_SYMFIELD_TYPE unsigned int
+#define ARM_GET_FLAG(s) (*symbol_get_tc (s))
+#define ARM_SET_FLAG(s,v) (*symbol_get_tc (s) |= (v))
+#define ARM_RESET_FLAG(s,v) (*symbol_get_tc (s) &= ~(v))
+
+#define ARM_FLAG_THUMB (1 << 0) /* The symbol is a Thumb symbol rather than an Arm symbol. */
+#define ARM_FLAG_INTERWORK (1 << 1) /* The symbol is attached to code that supports interworking. */
+#define THUMB_FLAG_FUNC (1 << 2) /* The symbol is attached to the start of a Thumb function. */
+
+#define ARM_IS_THUMB(s) (ARM_GET_FLAG (s) & ARM_FLAG_THUMB)
+#define ARM_IS_INTERWORK(s) (ARM_GET_FLAG (s) & ARM_FLAG_INTERWORK)
+#define THUMB_IS_FUNC(s) (ARM_GET_FLAG (s) & THUMB_FLAG_FUNC)
+
+#define ARM_SET_THUMB(s,t) ((t) ? ARM_SET_FLAG (s, ARM_FLAG_THUMB) : ARM_RESET_FLAG (s, ARM_FLAG_THUMB))
+#define ARM_SET_INTERWORK(s,t) ((t) ? ARM_SET_FLAG (s, ARM_FLAG_INTERWORK) : ARM_RESET_FLAG (s, ARM_FLAG_INTERWORK))
+#define THUMB_SET_FUNC(s,t) ((t) ? ARM_SET_FLAG (s, THUMB_FLAG_FUNC) : ARM_RESET_FLAG (s, THUMB_FLAG_FUNC))
+
+#define TC_START_LABEL(C,STR) (c == ':' || (c == '/' && arm_data_in_code ()))
+#define tc_canonicalize_symbol_name(str) arm_canonicalize_symbol_name (str);
+#define obj_adjust_symtab() arm_adjust_symtab ()
+#define tc_aout_pre_write_hook(x) {;} /* not used */
+
+#define LISTING_HEADER "ARM GAS "
+
+#define OPTIONAL_REGISTER_PREFIX '%'
+
+#define LOCAL_LABEL(name) (name[0] == '.' && (name[1] == 'L'))
+#define LOCAL_LABELS_FB 1
+
+/* This expression evaluates to true if the relocation is for a local
+ object for which we still want to do the relocation at runtime.
+ False if we are willing to perform this relocation while building
+ the .o file. GOTOFF does not need to be checked here because it is
+ not pcrel. I am not sure if some of the others are ever used with
+ pcrel, but it is easier to be safe than sorry. */
+
+#define TC_FORCE_RELOCATION_LOCAL(FIX) \
+ (!(FIX)->fx_pcrel \
+ || (FIX)->fx_plt \
+ || (FIX)->fx_r_type == BFD_RELOC_ARM_GOT12 \
+ || (FIX)->fx_r_type == BFD_RELOC_ARM_GOT32 \
+ || (FIX)->fx_r_type == BFD_RELOC_32 \
+ || TC_FORCE_RELOCATION (FIX))
+
+#define TC_CONS_FIX_NEW cons_fix_new_arm
+
+#define MAX_MEM_FOR_RS_ALIGN_CODE 31
+
+/* For frags in code sections we need to record whether they contain
+ ARM code or THUMB code. This is that if they have to be aligned,
+ they can contain the correct type of no-op instruction. */
+#define TC_FRAG_TYPE int
+#define TC_FRAG_INIT(fragp) arm_init_frag (fragp)
+#define HANDLE_ALIGN(fragp) arm_handle_align (fragp)
+
+#define md_do_align(N, FILL, LEN, MAX, LABEL) \
+ if (FILL == NULL && (N) != 0 && ! need_pass_2 && subseg_text_p (now_seg)) \
+ { \
+ arm_frag_align_code (N, MAX); \
+ goto LABEL; \
+ }
+
+#ifdef OBJ_ELF
+# define DWARF2_LINE_MIN_INSN_LENGTH 2
+# define obj_frob_symbol(sym, punt) armelf_frob_symbol ((sym), & (punt))
+# define md_elf_section_change_hook() arm_elf_change_section ()
+# define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_"
+# define LOCAL_LABEL_PREFIX '.'
+# define TC_SEGMENT_INFO_TYPE enum mstate
+
+enum mstate
+{
+ MAP_UNDEFINED = 0, /* Must be zero, for seginfo in new sections. */
+ MAP_DATA,
+ MAP_ARM,
+ MAP_THUMB
+};
+
+#else /* Not OBJ_ELF. */
+#define GLOBAL_OFFSET_TABLE_NAME "__GLOBAL_OFFSET_TABLE_"
+#endif
+
+#if defined OBJ_ELF || defined OBJ_COFF
+
+# define EXTERN_FORCE_RELOC 1
+# define tc_fix_adjustable(FIX) arm_fix_adjustable (FIX)
+/* Values passed to md_apply_fix3 don't include the symbol value. */
+# define MD_APPLY_SYM_VALUE(FIX) 0
+# define TC_VALIDATE_FIX(FIX, SEGTYPE, LABEL) arm_validate_fix (FIX)
+
+#endif
+
+extern void arm_frag_align_code (int, int);
+extern void arm_validate_fix (struct fix *);
+extern const char * elf32_arm_target_format (void);
+extern void arm_elf_change_section (void);
+extern int arm_force_relocation (struct fix *);
+extern void arm_cleanup (void);
+extern void arm_start_line_hook (void);
+extern void arm_frob_label (symbolS *);
+extern int arm_data_in_code (void);
+extern char * arm_canonicalize_symbol_name (char *);
+extern void arm_adjust_symtab (void);
+extern void armelf_frob_symbol (symbolS *, int *);
+extern void cons_fix_new_arm (fragS *, int, int, expressionS *);
+extern void arm_init_frag (struct frag *);
+extern void arm_handle_align (struct frag *);
+extern bfd_boolean arm_fix_adjustable (struct fix *);
diff --git a/x/binutils/gas/config/tc-generic.c b/x/binutils/gas/config/tc-generic.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/x/binutils/gas/config/tc-generic.c
diff --git a/x/binutils/gas/config/tc-generic.h b/x/binutils/gas/config/tc-generic.h
new file mode 100644
index 0000000..f3b676b
--- /dev/null
+++ b/x/binutils/gas/config/tc-generic.h
@@ -0,0 +1,39 @@
+/* This file is tc-generic.h
+
+ Copyright 1987, 1991, 1992, 1995, 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with GAS; see the file COPYING. If not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ * This file is tc-generic.h and is intended to be a template for target cpu
+ * specific header files. It is my intent that this file compile. It is also
+ * my intent that this file grow into something that can be used as both a
+ * template for porting, and a stub for testing. xoxorich.
+ */
+
+#define TC_GENERIC 1
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+/*
+ * Local Variables:
+ * comment-column: 0
+ * fill-column: 131
+ * End:
+ */
+
+/* end of tc-generic.h */
diff --git a/x/binutils/gas/config/tc-i386.c b/x/binutils/gas/config/tc-i386.c
new file mode 100644
index 0000000..5de6a55
--- /dev/null
+++ b/x/binutils/gas/config/tc-i386.c
@@ -0,0 +1,6272 @@
+/* i386.c -- Assemble code for the Intel 80386
+ Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Intel 80386 machine specific gas.
+ Written by Eliot Dresselhaus (eliot@mgm.mit.edu).
+ x86_64 support by Jan Hubicka (jh@suse.cz)
+ VIA PadLock support by Michal Ludvig (mludvig@suse.cz)
+ Bugs & suggestions are completely welcome. This is free software.
+ Please help us make it better. */
+
+#include "as.h"
+#include "safe-ctype.h"
+#include "subsegs.h"
+#include "dwarf2dbg.h"
+#include "dw2gencfi.h"
+#include "opcode/i386.h"
+
+#ifndef REGISTER_WARNINGS
+#define REGISTER_WARNINGS 1
+#endif
+
+#ifndef INFER_ADDR_PREFIX
+#define INFER_ADDR_PREFIX 1
+#endif
+
+#ifndef SCALE1_WHEN_NO_INDEX
+/* Specifying a scale factor besides 1 when there is no index is
+ futile. eg. `mov (%ebx,2),%al' does exactly the same as
+ `mov (%ebx),%al'. To slavishly follow what the programmer
+ specified, set SCALE1_WHEN_NO_INDEX to 0. */
+#define SCALE1_WHEN_NO_INDEX 1
+#endif
+
+#ifndef DEFAULT_ARCH
+#define DEFAULT_ARCH "i386"
+#endif
+
+#ifndef INLINE
+#if __GNUC__ >= 2
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+#endif
+
+static INLINE unsigned int mode_from_disp_size PARAMS ((unsigned int));
+static INLINE int fits_in_signed_byte PARAMS ((offsetT));
+static INLINE int fits_in_unsigned_byte PARAMS ((offsetT));
+static INLINE int fits_in_unsigned_word PARAMS ((offsetT));
+static INLINE int fits_in_signed_word PARAMS ((offsetT));
+static INLINE int fits_in_unsigned_long PARAMS ((offsetT));
+static INLINE int fits_in_signed_long PARAMS ((offsetT));
+static int smallest_imm_type PARAMS ((offsetT));
+static offsetT offset_in_range PARAMS ((offsetT, int));
+static int add_prefix PARAMS ((unsigned int));
+static void set_code_flag PARAMS ((int));
+static void set_16bit_gcc_code_flag PARAMS ((int));
+static void set_intel_syntax PARAMS ((int));
+static void set_cpu_arch PARAMS ((int));
+static char *output_invalid PARAMS ((int c));
+static int i386_operand PARAMS ((char *operand_string));
+static int i386_intel_operand PARAMS ((char *operand_string, int got_a_float));
+static const reg_entry *parse_register PARAMS ((char *reg_string,
+ char **end_op));
+static char *parse_insn PARAMS ((char *, char *));
+static char *parse_operands PARAMS ((char *, const char *));
+static void swap_operands PARAMS ((void));
+static void optimize_imm PARAMS ((void));
+static void optimize_disp PARAMS ((void));
+static int match_template PARAMS ((void));
+static int check_string PARAMS ((void));
+static int process_suffix PARAMS ((void));
+static int check_byte_reg PARAMS ((void));
+static int check_long_reg PARAMS ((void));
+static int check_qword_reg PARAMS ((void));
+static int check_word_reg PARAMS ((void));
+static int finalize_imm PARAMS ((void));
+static int process_operands PARAMS ((void));
+static const seg_entry *build_modrm_byte PARAMS ((void));
+static void output_insn PARAMS ((void));
+static void output_branch PARAMS ((void));
+static void output_jump PARAMS ((void));
+static void output_interseg_jump PARAMS ((void));
+static void output_imm PARAMS ((fragS *insn_start_frag,
+ offsetT insn_start_off));
+static void output_disp PARAMS ((fragS *insn_start_frag,
+ offsetT insn_start_off));
+#ifndef I386COFF
+static void s_bss PARAMS ((int));
+#endif
+
+static const char *default_arch = DEFAULT_ARCH;
+
+/* 'md_assemble ()' gathers together information and puts it into a
+ i386_insn. */
+
+union i386_op
+ {
+ expressionS *disps;
+ expressionS *imms;
+ const reg_entry *regs;
+ };
+
+struct _i386_insn
+ {
+ /* TM holds the template for the insn were currently assembling. */
+ template tm;
+
+ /* SUFFIX holds the instruction mnemonic suffix if given.
+ (e.g. 'l' for 'movl') */
+ char suffix;
+
+ /* OPERANDS gives the number of given operands. */
+ unsigned int operands;
+
+ /* REG_OPERANDS, DISP_OPERANDS, MEM_OPERANDS, IMM_OPERANDS give the number
+ of given register, displacement, memory operands and immediate
+ operands. */
+ unsigned int reg_operands, disp_operands, mem_operands, imm_operands;
+
+ /* TYPES [i] is the type (see above #defines) which tells us how to
+ use OP[i] for the corresponding operand. */
+ unsigned int types[MAX_OPERANDS];
+
+ /* Displacement expression, immediate expression, or register for each
+ operand. */
+ union i386_op op[MAX_OPERANDS];
+
+ /* Flags for operands. */
+ unsigned int flags[MAX_OPERANDS];
+#define Operand_PCrel 1
+
+ /* Relocation type for operand */
+ enum bfd_reloc_code_real reloc[MAX_OPERANDS];
+
+ /* BASE_REG, INDEX_REG, and LOG2_SCALE_FACTOR are used to encode
+ the base index byte below. */
+ const reg_entry *base_reg;
+ const reg_entry *index_reg;
+ unsigned int log2_scale_factor;
+
+ /* SEG gives the seg_entries of this insn. They are zero unless
+ explicit segment overrides are given. */
+ const seg_entry *seg[2];
+
+ /* PREFIX holds all the given prefix opcodes (usually null).
+ PREFIXES is the number of prefix opcodes. */
+ unsigned int prefixes;
+ unsigned char prefix[MAX_PREFIXES];
+
+ /* RM and SIB are the modrm byte and the sib byte where the
+ addressing modes of this insn are encoded. */
+
+ modrm_byte rm;
+ rex_byte rex;
+ sib_byte sib;
+ };
+
+typedef struct _i386_insn i386_insn;
+
+/* List of chars besides those in app.c:symbol_chars that can start an
+ operand. Used to prevent the scrubber eating vital white-space. */
+#ifdef LEX_AT
+const char extra_symbol_chars[] = "*%-(@[";
+#else
+const char extra_symbol_chars[] = "*%-([";
+#endif
+
+#if (defined (TE_I386AIX) \
+ || ((defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) \
+ && !defined (TE_LINUX) \
+ && !defined (TE_FreeBSD) \
+ && !defined (TE_NetBSD)))
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful. */
+const char comment_chars[] = "#/";
+#define PREFIX_SEPARATOR '\\'
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output.
+ Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output.
+ Also note that comments started like this one will always work if
+ '/' isn't otherwise defined. */
+const char line_comment_chars[] = "#";
+
+#else
+/* Putting '/' here makes it impossible to use the divide operator.
+ However, we need it for compatibility with SVR4 systems. */
+const char comment_chars[] = "#";
+#define PREFIX_SEPARATOR '/'
+
+const char line_comment_chars[] = "/#";
+#endif
+
+const char line_separator_chars[] = ";";
+
+/* Chars that can be used to separate mant from exp in floating point
+ nums. */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant
+ As in 0f12.456
+ or 0d1.2345e12. */
+const char FLT_CHARS[] = "fFdDxX";
+
+/* Tables for lexical analysis. */
+static char mnemonic_chars[256];
+static char register_chars[256];
+static char operand_chars[256];
+static char identifier_chars[256];
+static char digit_chars[256];
+
+/* Lexical macros. */
+#define is_mnemonic_char(x) (mnemonic_chars[(unsigned char) x])
+#define is_operand_char(x) (operand_chars[(unsigned char) x])
+#define is_register_char(x) (register_chars[(unsigned char) x])
+#define is_space_char(x) ((x) == ' ')
+#define is_identifier_char(x) (identifier_chars[(unsigned char) x])
+#define is_digit_char(x) (digit_chars[(unsigned char) x])
+
+/* All non-digit non-letter characters that may occur in an operand. */
+static char operand_special_chars[] = "%$-+(,)*._~/<>|&^!:[@]";
+
+/* md_assemble() always leaves the strings it's passed unaltered. To
+ effect this we maintain a stack of saved characters that we've smashed
+ with '\0's (indicating end of strings for various sub-fields of the
+ assembler instruction). */
+static char save_stack[32];
+static char *save_stack_p;
+#define END_STRING_AND_SAVE(s) \
+ do { *save_stack_p++ = *(s); *(s) = '\0'; } while (0)
+#define RESTORE_END_STRING(s) \
+ do { *(s) = *--save_stack_p; } while (0)
+
+/* The instruction we're assembling. */
+static i386_insn i;
+
+/* Possible templates for current insn. */
+static const templates *current_templates;
+
+/* Per instruction expressionS buffers: 2 displacements & 2 immediate max. */
+static expressionS disp_expressions[2], im_expressions[2];
+
+/* Current operand we are working on. */
+static int this_operand;
+
+/* We support four different modes. FLAG_CODE variable is used to distinguish
+ these. */
+
+enum flag_code {
+ CODE_32BIT,
+ CODE_16BIT,
+ CODE_64BIT };
+#define NUM_FLAG_CODE ((int) CODE_64BIT + 1)
+
+static enum flag_code flag_code;
+static int use_rela_relocations = 0;
+
+/* The names used to print error messages. */
+static const char *flag_code_names[] =
+ {
+ "32",
+ "16",
+ "64"
+ };
+
+/* 1 for intel syntax,
+ 0 if att syntax. */
+static int intel_syntax = 0;
+
+/* 1 if register prefix % not required. */
+static int allow_naked_reg = 0;
+
+/* Used in 16 bit gcc mode to add an l suffix to call, ret, enter,
+ leave, push, and pop instructions so that gcc has the same stack
+ frame as in 32 bit mode. */
+static char stackop_size = '\0';
+
+/* Non-zero to optimize code alignment. */
+int optimize_align_code = 1;
+
+/* Non-zero to quieten some warnings. */
+static int quiet_warnings = 0;
+
+/* CPU name. */
+static const char *cpu_arch_name = NULL;
+
+/* CPU feature flags. */
+static unsigned int cpu_arch_flags = CpuUnknownFlags | CpuNo64;
+
+/* If set, conditional jumps are not automatically promoted to handle
+ larger than a byte offset. */
+static unsigned int no_cond_jump_promotion = 0;
+
+/* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
+symbolS *GOT_symbol;
+
+/* The dwarf2 return column, adjusted for 32 or 64 bit. */
+unsigned int x86_dwarf2_return_column;
+
+/* The dwarf2 data alignment, adjusted for 32 or 64 bit. */
+int x86_cie_data_alignment;
+
+/* Interface to relax_segment.
+ There are 3 major relax states for 386 jump insns because the
+ different types of jumps add different sizes to frags when we're
+ figuring out what sort of jump to choose to reach a given label. */
+
+/* Types. */
+#define UNCOND_JUMP 0
+#define COND_JUMP 1
+#define COND_JUMP86 2
+
+/* Sizes. */
+#define CODE16 1
+#define SMALL 0
+#define SMALL16 (SMALL | CODE16)
+#define BIG 2
+#define BIG16 (BIG | CODE16)
+
+#ifndef INLINE
+#ifdef __GNUC__
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+#endif
+
+#define ENCODE_RELAX_STATE(type, size) \
+ ((relax_substateT) (((type) << 2) | (size)))
+#define TYPE_FROM_RELAX_STATE(s) \
+ ((s) >> 2)
+#define DISP_SIZE_FROM_RELAX_STATE(s) \
+ ((((s) & 3) == BIG ? 4 : (((s) & 3) == BIG16 ? 2 : 1)))
+
+/* This table is used by relax_frag to promote short jumps to long
+ ones where necessary. SMALL (short) jumps may be promoted to BIG
+ (32 bit long) ones, and SMALL16 jumps to BIG16 (16 bit long). We
+ don't allow a short jump in a 32 bit code segment to be promoted to
+ a 16 bit offset jump because it's slower (requires data size
+ prefix), and doesn't work, unless the destination is in the bottom
+ 64k of the code segment (The top 16 bits of eip are zeroed). */
+
+const relax_typeS md_relax_table[] =
+{
+ /* The fields are:
+ 1) most positive reach of this state,
+ 2) most negative reach of this state,
+ 3) how many bytes this mode will have in the variable part of the frag
+ 4) which index into the table to try if we can't fit into this one. */
+
+ /* UNCOND_JUMP states. */
+ {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG)},
+ {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16)},
+ /* dword jmp adds 4 bytes to frag:
+ 0 extra opcode bytes, 4 displacement bytes. */
+ {0, 0, 4, 0},
+ /* word jmp adds 2 byte2 to frag:
+ 0 extra opcode bytes, 2 displacement bytes. */
+ {0, 0, 2, 0},
+
+ /* COND_JUMP states. */
+ {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG)},
+ {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG16)},
+ /* dword conditionals adds 5 bytes to frag:
+ 1 extra opcode byte, 4 displacement bytes. */
+ {0, 0, 5, 0},
+ /* word conditionals add 3 bytes to frag:
+ 1 extra opcode byte, 2 displacement bytes. */
+ {0, 0, 3, 0},
+
+ /* COND_JUMP86 states. */
+ {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG)},
+ {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG16)},
+ /* dword conditionals adds 5 bytes to frag:
+ 1 extra opcode byte, 4 displacement bytes. */
+ {0, 0, 5, 0},
+ /* word conditionals add 4 bytes to frag:
+ 1 displacement byte and a 3 byte long branch insn. */
+ {0, 0, 4, 0}
+};
+
+static const arch_entry cpu_arch[] = {
+ {"i8086", Cpu086 },
+ {"i186", Cpu086|Cpu186 },
+ {"i286", Cpu086|Cpu186|Cpu286 },
+ {"i386", Cpu086|Cpu186|Cpu286|Cpu386 },
+ {"i486", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486 },
+ {"i586", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuMMX },
+ {"i686", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX|CpuSSE },
+ {"pentium", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuMMX },
+ {"pentiumpro",Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX|CpuSSE },
+ {"pentium4", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2 },
+ {"k6", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX|Cpu3dnow },
+ {"athlon", Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuAthlon|CpuMMX|Cpu3dnow },
+ {"sledgehammer",Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuAthlon|CpuSledgehammer|CpuMMX|Cpu3dnow|CpuSSE|CpuSSE2 },
+ {NULL, 0 }
+};
+
+const pseudo_typeS md_pseudo_table[] =
+{
+#if !defined(OBJ_AOUT) && !defined(USE_ALIGN_PTWO)
+ {"align", s_align_bytes, 0},
+#else
+ {"align", s_align_ptwo, 0},
+#endif
+ {"arch", set_cpu_arch, 0},
+#ifndef I386COFF
+ {"bss", s_bss, 0},
+#endif
+ {"ffloat", float_cons, 'f'},
+ {"dfloat", float_cons, 'd'},
+ {"tfloat", float_cons, 'x'},
+ {"value", cons, 2},
+ {"noopt", s_ignore, 0},
+ {"optim", s_ignore, 0},
+ {"code16gcc", set_16bit_gcc_code_flag, CODE_16BIT},
+ {"code16", set_code_flag, CODE_16BIT},
+ {"code32", set_code_flag, CODE_32BIT},
+ {"code64", set_code_flag, CODE_64BIT},
+ {"intel_syntax", set_intel_syntax, 1},
+ {"att_syntax", set_intel_syntax, 0},
+ {"file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0},
+ {"loc", dwarf2_directive_loc, 0},
+ {0, 0, 0}
+};
+
+/* For interface with expression (). */
+extern char *input_line_pointer;
+
+/* Hash table for instruction mnemonic lookup. */
+static struct hash_control *op_hash;
+
+/* Hash table for register lookup. */
+static struct hash_control *reg_hash;
+
+void
+i386_align_code (fragP, count)
+ fragS *fragP;
+ int count;
+{
+ /* Various efficient no-op patterns for aligning code labels.
+ Note: Don't try to assemble the instructions in the comments.
+ 0L and 0w are not legal. */
+ static const char f32_1[] =
+ {0x90}; /* nop */
+ static const char f32_2[] =
+ {0x89,0xf6}; /* movl %esi,%esi */
+ static const char f32_3[] =
+ {0x8d,0x76,0x00}; /* leal 0(%esi),%esi */
+ static const char f32_4[] =
+ {0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */
+ static const char f32_5[] =
+ {0x90, /* nop */
+ 0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */
+ static const char f32_6[] =
+ {0x8d,0xb6,0x00,0x00,0x00,0x00}; /* leal 0L(%esi),%esi */
+ static const char f32_7[] =
+ {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */
+ static const char f32_8[] =
+ {0x90, /* nop */
+ 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */
+ static const char f32_9[] =
+ {0x89,0xf6, /* movl %esi,%esi */
+ 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
+ static const char f32_10[] =
+ {0x8d,0x76,0x00, /* leal 0(%esi),%esi */
+ 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
+ static const char f32_11[] =
+ {0x8d,0x74,0x26,0x00, /* leal 0(%esi,1),%esi */
+ 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
+ static const char f32_12[] =
+ {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */
+ 0x8d,0xbf,0x00,0x00,0x00,0x00}; /* leal 0L(%edi),%edi */
+ static const char f32_13[] =
+ {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */
+ 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
+ static const char f32_14[] =
+ {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00, /* leal 0L(%esi,1),%esi */
+ 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
+ static const char f32_15[] =
+ {0xeb,0x0d,0x90,0x90,0x90,0x90,0x90, /* jmp .+15; lotsa nops */
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90};
+ static const char f16_3[] =
+ {0x8d,0x74,0x00}; /* lea 0(%esi),%esi */
+ static const char f16_4[] =
+ {0x8d,0xb4,0x00,0x00}; /* lea 0w(%si),%si */
+ static const char f16_5[] =
+ {0x90, /* nop */
+ 0x8d,0xb4,0x00,0x00}; /* lea 0w(%si),%si */
+ static const char f16_6[] =
+ {0x89,0xf6, /* mov %si,%si */
+ 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */
+ static const char f16_7[] =
+ {0x8d,0x74,0x00, /* lea 0(%si),%si */
+ 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */
+ static const char f16_8[] =
+ {0x8d,0xb4,0x00,0x00, /* lea 0w(%si),%si */
+ 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */
+ static const char *const f32_patt[] = {
+ f32_1, f32_2, f32_3, f32_4, f32_5, f32_6, f32_7, f32_8,
+ f32_9, f32_10, f32_11, f32_12, f32_13, f32_14, f32_15
+ };
+ static const char *const f16_patt[] = {
+ f32_1, f32_2, f16_3, f16_4, f16_5, f16_6, f16_7, f16_8,
+ f32_15, f32_15, f32_15, f32_15, f32_15, f32_15, f32_15
+ };
+
+ if (count <= 0 || count > 15)
+ return;
+
+ /* The recommended way to pad 64bit code is to use NOPs preceded by
+ maximally four 0x66 prefixes. Balance the size of nops. */
+ if (flag_code == CODE_64BIT)
+ {
+ int i;
+ int nnops = (count + 3) / 4;
+ int len = count / nnops;
+ int remains = count - nnops * len;
+ int pos = 0;
+
+ for (i = 0; i < remains; i++)
+ {
+ memset (fragP->fr_literal + fragP->fr_fix + pos, 0x66, len);
+ fragP->fr_literal[fragP->fr_fix + pos + len] = 0x90;
+ pos += len + 1;
+ }
+ for (; i < nnops; i++)
+ {
+ memset (fragP->fr_literal + fragP->fr_fix + pos, 0x66, len - 1);
+ fragP->fr_literal[fragP->fr_fix + pos + len - 1] = 0x90;
+ pos += len;
+ }
+ }
+ else
+ if (flag_code == CODE_16BIT)
+ {
+ memcpy (fragP->fr_literal + fragP->fr_fix,
+ f16_patt[count - 1], count);
+ if (count > 8)
+ /* Adjust jump offset. */
+ fragP->fr_literal[fragP->fr_fix + 1] = count - 2;
+ }
+ else
+ memcpy (fragP->fr_literal + fragP->fr_fix,
+ f32_patt[count - 1], count);
+ fragP->fr_var = count;
+}
+
+static INLINE unsigned int
+mode_from_disp_size (t)
+ unsigned int t;
+{
+ return (t & Disp8) ? 1 : (t & (Disp16 | Disp32 | Disp32S)) ? 2 : 0;
+}
+
+static INLINE int
+fits_in_signed_byte (num)
+ offsetT num;
+{
+ return (num >= -128) && (num <= 127);
+}
+
+static INLINE int
+fits_in_unsigned_byte (num)
+ offsetT num;
+{
+ return (num & 0xff) == num;
+}
+
+static INLINE int
+fits_in_unsigned_word (num)
+ offsetT num;
+{
+ return (num & 0xffff) == num;
+}
+
+static INLINE int
+fits_in_signed_word (num)
+ offsetT num;
+{
+ return (-32768 <= num) && (num <= 32767);
+}
+static INLINE int
+fits_in_signed_long (num)
+ offsetT num ATTRIBUTE_UNUSED;
+{
+#ifndef BFD64
+ return 1;
+#else
+ return (!(((offsetT) -1 << 31) & num)
+ || (((offsetT) -1 << 31) & num) == ((offsetT) -1 << 31));
+#endif
+} /* fits_in_signed_long() */
+static INLINE int
+fits_in_unsigned_long (num)
+ offsetT num ATTRIBUTE_UNUSED;
+{
+#ifndef BFD64
+ return 1;
+#else
+ return (num & (((offsetT) 2 << 31) - 1)) == num;
+#endif
+} /* fits_in_unsigned_long() */
+
+static int
+smallest_imm_type (num)
+ offsetT num;
+{
+ if (cpu_arch_flags != (Cpu086 | Cpu186 | Cpu286 | Cpu386 | Cpu486 | CpuNo64))
+ {
+ /* This code is disabled on the 486 because all the Imm1 forms
+ in the opcode table are slower on the i486. They're the
+ versions with the implicitly specified single-position
+ displacement, which has another syntax if you really want to
+ use that form. */
+ if (num == 1)
+ return Imm1 | Imm8 | Imm8S | Imm16 | Imm32 | Imm32S | Imm64;
+ }
+ return (fits_in_signed_byte (num)
+ ? (Imm8S | Imm8 | Imm16 | Imm32 | Imm32S | Imm64)
+ : fits_in_unsigned_byte (num)
+ ? (Imm8 | Imm16 | Imm32 | Imm32S | Imm64)
+ : (fits_in_signed_word (num) || fits_in_unsigned_word (num))
+ ? (Imm16 | Imm32 | Imm32S | Imm64)
+ : fits_in_signed_long (num)
+ ? (Imm32 | Imm32S | Imm64)
+ : fits_in_unsigned_long (num)
+ ? (Imm32 | Imm64)
+ : Imm64);
+}
+
+static offsetT
+offset_in_range (val, size)
+ offsetT val;
+ int size;
+{
+ addressT mask;
+
+ switch (size)
+ {
+ case 1: mask = ((addressT) 1 << 8) - 1; break;
+ case 2: mask = ((addressT) 1 << 16) - 1; break;
+ case 4: mask = ((addressT) 2 << 31) - 1; break;
+#ifdef BFD64
+ case 8: mask = ((addressT) 2 << 63) - 1; break;
+#endif
+ default: abort ();
+ }
+
+ /* If BFD64, sign extend val. */
+ if (!use_rela_relocations)
+ if ((val & ~(((addressT) 2 << 31) - 1)) == 0)
+ val = (val ^ ((addressT) 1 << 31)) - ((addressT) 1 << 31);
+
+ if ((val & ~mask) != 0 && (val & ~mask) != ~mask)
+ {
+ char buf1[40], buf2[40];
+
+ sprint_value (buf1, val);
+ sprint_value (buf2, val & mask);
+ as_warn (_("%s shortened to %s"), buf1, buf2);
+ }
+ return val & mask;
+}
+
+/* Returns 0 if attempting to add a prefix where one from the same
+ class already exists, 1 if non rep/repne added, 2 if rep/repne
+ added. */
+static int
+add_prefix (prefix)
+ unsigned int prefix;
+{
+ int ret = 1;
+ int q;
+
+ if (prefix >= REX_OPCODE && prefix < REX_OPCODE + 16
+ && flag_code == CODE_64BIT)
+ q = REX_PREFIX;
+ else
+ switch (prefix)
+ {
+ default:
+ abort ();
+
+ case CS_PREFIX_OPCODE:
+ case DS_PREFIX_OPCODE:
+ case ES_PREFIX_OPCODE:
+ case FS_PREFIX_OPCODE:
+ case GS_PREFIX_OPCODE:
+ case SS_PREFIX_OPCODE:
+ q = SEG_PREFIX;
+ break;
+
+ case REPNE_PREFIX_OPCODE:
+ case REPE_PREFIX_OPCODE:
+ ret = 2;
+ /* fall thru */
+ case LOCK_PREFIX_OPCODE:
+ q = LOCKREP_PREFIX;
+ break;
+
+ case FWAIT_OPCODE:
+ q = WAIT_PREFIX;
+ break;
+
+ case ADDR_PREFIX_OPCODE:
+ q = ADDR_PREFIX;
+ break;
+
+ case DATA_PREFIX_OPCODE:
+ q = DATA_PREFIX;
+ break;
+ }
+
+ if (i.prefix[q] != 0)
+ {
+ as_bad (_("same type of prefix used twice"));
+ return 0;
+ }
+
+ i.prefixes += 1;
+ i.prefix[q] = prefix;
+ return ret;
+}
+
+static void
+set_code_flag (value)
+ int value;
+{
+ flag_code = value;
+ cpu_arch_flags &= ~(Cpu64 | CpuNo64);
+ cpu_arch_flags |= (flag_code == CODE_64BIT ? Cpu64 : CpuNo64);
+ if (value == CODE_64BIT && !(cpu_arch_flags & CpuSledgehammer))
+ {
+ as_bad (_("64bit mode not supported on this CPU."));
+ }
+ if (value == CODE_32BIT && !(cpu_arch_flags & Cpu386))
+ {
+ as_bad (_("32bit mode not supported on this CPU."));
+ }
+ stackop_size = '\0';
+}
+
+static void
+set_16bit_gcc_code_flag (new_code_flag)
+ int new_code_flag;
+{
+ flag_code = new_code_flag;
+ cpu_arch_flags &= ~(Cpu64 | CpuNo64);
+ cpu_arch_flags |= (flag_code == CODE_64BIT ? Cpu64 : CpuNo64);
+ stackop_size = 'l';
+}
+
+static void
+set_intel_syntax (syntax_flag)
+ int syntax_flag;
+{
+ /* Find out if register prefixing is specified. */
+ int ask_naked_reg = 0;
+
+ SKIP_WHITESPACE ();
+ if (!is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ char *string = input_line_pointer;
+ int e = get_symbol_end ();
+
+ if (strcmp (string, "prefix") == 0)
+ ask_naked_reg = 1;
+ else if (strcmp (string, "noprefix") == 0)
+ ask_naked_reg = -1;
+ else
+ as_bad (_("bad argument to syntax directive."));
+ *input_line_pointer = e;
+ }
+ demand_empty_rest_of_line ();
+
+ intel_syntax = syntax_flag;
+
+ if (ask_naked_reg == 0)
+ allow_naked_reg = (intel_syntax
+ && (bfd_get_symbol_leading_char (stdoutput) != '\0'));
+ else
+ allow_naked_reg = (ask_naked_reg < 0);
+}
+
+static void
+set_cpu_arch (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ SKIP_WHITESPACE ();
+
+ if (!is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ char *string = input_line_pointer;
+ int e = get_symbol_end ();
+ int i;
+
+ for (i = 0; cpu_arch[i].name; i++)
+ {
+ if (strcmp (string, cpu_arch[i].name) == 0)
+ {
+ cpu_arch_name = cpu_arch[i].name;
+ cpu_arch_flags = (cpu_arch[i].flags
+ | (flag_code == CODE_64BIT ? Cpu64 : CpuNo64));
+ break;
+ }
+ }
+ if (!cpu_arch[i].name)
+ as_bad (_("no such architecture: `%s'"), string);
+
+ *input_line_pointer = e;
+ }
+ else
+ as_bad (_("missing cpu architecture"));
+
+ no_cond_jump_promotion = 0;
+ if (*input_line_pointer == ','
+ && !is_end_of_line[(unsigned char) input_line_pointer[1]])
+ {
+ char *string = ++input_line_pointer;
+ int e = get_symbol_end ();
+
+ if (strcmp (string, "nojumps") == 0)
+ no_cond_jump_promotion = 1;
+ else if (strcmp (string, "jumps") == 0)
+ ;
+ else
+ as_bad (_("no such architecture modifier: `%s'"), string);
+
+ *input_line_pointer = e;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+unsigned long
+i386_mach ()
+{
+ if (!strcmp (default_arch, "x86_64"))
+ return bfd_mach_x86_64;
+ else if (!strcmp (default_arch, "i386"))
+ return bfd_mach_i386_i386;
+ else
+ as_fatal (_("Unknown architecture"));
+}
+
+void
+md_begin ()
+{
+ const char *hash_err;
+
+ /* Initialize op_hash hash table. */
+ op_hash = hash_new ();
+
+ {
+ const template *optab;
+ templates *core_optab;
+
+ /* Setup for loop. */
+ optab = i386_optab;
+ core_optab = (templates *) xmalloc (sizeof (templates));
+ core_optab->start = optab;
+
+ while (1)
+ {
+ ++optab;
+ if (optab->name == NULL
+ || strcmp (optab->name, (optab - 1)->name) != 0)
+ {
+ /* different name --> ship out current template list;
+ add to hash table; & begin anew. */
+ core_optab->end = optab;
+ hash_err = hash_insert (op_hash,
+ (optab - 1)->name,
+ (PTR) core_optab);
+ if (hash_err)
+ {
+ as_fatal (_("Internal Error: Can't hash %s: %s"),
+ (optab - 1)->name,
+ hash_err);
+ }
+ if (optab->name == NULL)
+ break;
+ core_optab = (templates *) xmalloc (sizeof (templates));
+ core_optab->start = optab;
+ }
+ }
+ }
+
+ /* Initialize reg_hash hash table. */
+ reg_hash = hash_new ();
+ {
+ const reg_entry *regtab;
+
+ for (regtab = i386_regtab;
+ regtab < i386_regtab + sizeof (i386_regtab) / sizeof (i386_regtab[0]);
+ regtab++)
+ {
+ hash_err = hash_insert (reg_hash, regtab->reg_name, (PTR) regtab);
+ if (hash_err)
+ as_fatal (_("Internal Error: Can't hash %s: %s"),
+ regtab->reg_name,
+ hash_err);
+ }
+ }
+
+ /* Fill in lexical tables: mnemonic_chars, operand_chars. */
+ {
+ int c;
+ char *p;
+
+ for (c = 0; c < 256; c++)
+ {
+ if (ISDIGIT (c))
+ {
+ digit_chars[c] = c;
+ mnemonic_chars[c] = c;
+ register_chars[c] = c;
+ operand_chars[c] = c;
+ }
+ else if (ISLOWER (c))
+ {
+ mnemonic_chars[c] = c;
+ register_chars[c] = c;
+ operand_chars[c] = c;
+ }
+ else if (ISUPPER (c))
+ {
+ mnemonic_chars[c] = TOLOWER (c);
+ register_chars[c] = mnemonic_chars[c];
+ operand_chars[c] = c;
+ }
+
+ if (ISALPHA (c) || ISDIGIT (c))
+ identifier_chars[c] = c;
+ else if (c >= 128)
+ {
+ identifier_chars[c] = c;
+ operand_chars[c] = c;
+ }
+ }
+
+#ifdef LEX_AT
+ identifier_chars['@'] = '@';
+#endif
+ digit_chars['-'] = '-';
+ identifier_chars['_'] = '_';
+ identifier_chars['.'] = '.';
+
+ for (p = operand_special_chars; *p != '\0'; p++)
+ operand_chars[(unsigned char) *p] = *p;
+ }
+
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ {
+ record_alignment (text_section, 2);
+ record_alignment (data_section, 2);
+ record_alignment (bss_section, 2);
+ }
+#endif
+
+ if (flag_code == CODE_64BIT)
+ {
+ x86_dwarf2_return_column = 16;
+ x86_cie_data_alignment = -8;
+ }
+ else
+ {
+ x86_dwarf2_return_column = 8;
+ x86_cie_data_alignment = -4;
+ }
+}
+
+void
+i386_print_statistics (file)
+ FILE *file;
+{
+ hash_print_statistics (file, "i386 opcode", op_hash);
+ hash_print_statistics (file, "i386 register", reg_hash);
+}
+
+#ifdef DEBUG386
+
+/* Debugging routines for md_assemble. */
+static void pi PARAMS ((char *, i386_insn *));
+static void pte PARAMS ((template *));
+static void pt PARAMS ((unsigned int));
+static void pe PARAMS ((expressionS *));
+static void ps PARAMS ((symbolS *));
+
+static void
+pi (line, x)
+ char *line;
+ i386_insn *x;
+{
+ unsigned int i;
+
+ fprintf (stdout, "%s: template ", line);
+ pte (&x->tm);
+ fprintf (stdout, " address: base %s index %s scale %x\n",
+ x->base_reg ? x->base_reg->reg_name : "none",
+ x->index_reg ? x->index_reg->reg_name : "none",
+ x->log2_scale_factor);
+ fprintf (stdout, " modrm: mode %x reg %x reg/mem %x\n",
+ x->rm.mode, x->rm.reg, x->rm.regmem);
+ fprintf (stdout, " sib: base %x index %x scale %x\n",
+ x->sib.base, x->sib.index, x->sib.scale);
+ fprintf (stdout, " rex: 64bit %x extX %x extY %x extZ %x\n",
+ (x->rex & REX_MODE64) != 0,
+ (x->rex & REX_EXTX) != 0,
+ (x->rex & REX_EXTY) != 0,
+ (x->rex & REX_EXTZ) != 0);
+ for (i = 0; i < x->operands; i++)
+ {
+ fprintf (stdout, " #%d: ", i + 1);
+ pt (x->types[i]);
+ fprintf (stdout, "\n");
+ if (x->types[i]
+ & (Reg | SReg2 | SReg3 | Control | Debug | Test | RegMMX | RegXMM))
+ fprintf (stdout, "%s\n", x->op[i].regs->reg_name);
+ if (x->types[i] & Imm)
+ pe (x->op[i].imms);
+ if (x->types[i] & Disp)
+ pe (x->op[i].disps);
+ }
+}
+
+static void
+pte (t)
+ template *t;
+{
+ unsigned int i;
+ fprintf (stdout, " %d operands ", t->operands);
+ fprintf (stdout, "opcode %x ", t->base_opcode);
+ if (t->extension_opcode != None)
+ fprintf (stdout, "ext %x ", t->extension_opcode);
+ if (t->opcode_modifier & D)
+ fprintf (stdout, "D");
+ if (t->opcode_modifier & W)
+ fprintf (stdout, "W");
+ fprintf (stdout, "\n");
+ for (i = 0; i < t->operands; i++)
+ {
+ fprintf (stdout, " #%d type ", i + 1);
+ pt (t->operand_types[i]);
+ fprintf (stdout, "\n");
+ }
+}
+
+static void
+pe (e)
+ expressionS *e;
+{
+ fprintf (stdout, " operation %d\n", e->X_op);
+ fprintf (stdout, " add_number %ld (%lx)\n",
+ (long) e->X_add_number, (long) e->X_add_number);
+ if (e->X_add_symbol)
+ {
+ fprintf (stdout, " add_symbol ");
+ ps (e->X_add_symbol);
+ fprintf (stdout, "\n");
+ }
+ if (e->X_op_symbol)
+ {
+ fprintf (stdout, " op_symbol ");
+ ps (e->X_op_symbol);
+ fprintf (stdout, "\n");
+ }
+}
+
+static void
+ps (s)
+ symbolS *s;
+{
+ fprintf (stdout, "%s type %s%s",
+ S_GET_NAME (s),
+ S_IS_EXTERNAL (s) ? "EXTERNAL " : "",
+ segment_name (S_GET_SEGMENT (s)));
+}
+
+struct type_name
+ {
+ unsigned int mask;
+ char *tname;
+ }
+
+static const type_names[] =
+{
+ { Reg8, "r8" },
+ { Reg16, "r16" },
+ { Reg32, "r32" },
+ { Reg64, "r64" },
+ { Imm8, "i8" },
+ { Imm8S, "i8s" },
+ { Imm16, "i16" },
+ { Imm32, "i32" },
+ { Imm32S, "i32s" },
+ { Imm64, "i64" },
+ { Imm1, "i1" },
+ { BaseIndex, "BaseIndex" },
+ { Disp8, "d8" },
+ { Disp16, "d16" },
+ { Disp32, "d32" },
+ { Disp32S, "d32s" },
+ { Disp64, "d64" },
+ { InOutPortReg, "InOutPortReg" },
+ { ShiftCount, "ShiftCount" },
+ { Control, "control reg" },
+ { Test, "test reg" },
+ { Debug, "debug reg" },
+ { FloatReg, "FReg" },
+ { FloatAcc, "FAcc" },
+ { SReg2, "SReg2" },
+ { SReg3, "SReg3" },
+ { Acc, "Acc" },
+ { JumpAbsolute, "Jump Absolute" },
+ { RegMMX, "rMMX" },
+ { RegXMM, "rXMM" },
+ { EsSeg, "es" },
+ { 0, "" }
+};
+
+static void
+pt (t)
+ unsigned int t;
+{
+ const struct type_name *ty;
+
+ for (ty = type_names; ty->mask; ty++)
+ if (t & ty->mask)
+ fprintf (stdout, "%s, ", ty->tname);
+ fflush (stdout);
+}
+
+#endif /* DEBUG386 */
+
+static bfd_reloc_code_real_type reloc
+ PARAMS ((int, int, int, bfd_reloc_code_real_type));
+
+static bfd_reloc_code_real_type
+reloc (size, pcrel, sign, other)
+ int size;
+ int pcrel;
+ int sign;
+ bfd_reloc_code_real_type other;
+{
+ if (other != NO_RELOC)
+ return other;
+
+ if (pcrel)
+ {
+ if (!sign)
+ as_bad (_("There are no unsigned pc-relative relocations"));
+ switch (size)
+ {
+ case 1: return BFD_RELOC_8_PCREL;
+ case 2: return BFD_RELOC_16_PCREL;
+ case 4: return BFD_RELOC_32_PCREL;
+ }
+ as_bad (_("can not do %d byte pc-relative relocation"), size);
+ }
+ else
+ {
+ if (sign)
+ switch (size)
+ {
+ case 4: return BFD_RELOC_X86_64_32S;
+ }
+ else
+ switch (size)
+ {
+ case 1: return BFD_RELOC_8;
+ case 2: return BFD_RELOC_16;
+ case 4: return BFD_RELOC_32;
+ case 8: return BFD_RELOC_64;
+ }
+ as_bad (_("can not do %s %d byte relocation"),
+ sign ? "signed" : "unsigned", size);
+ }
+
+ abort ();
+ return BFD_RELOC_NONE;
+}
+
+/* Here we decide which fixups can be adjusted to make them relative to
+ the beginning of the section instead of the symbol. Basically we need
+ to make sure that the dynamic relocations are done correctly, so in
+ some cases we force the original symbol to be used. */
+
+int
+tc_i386_fix_adjustable (fixP)
+ fixS *fixP ATTRIBUTE_UNUSED;
+{
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+ return 1;
+
+ /* Don't adjust pc-relative references to merge sections in 64-bit
+ mode. */
+ if (use_rela_relocations
+ && (S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0
+ && fixP->fx_pcrel)
+ return 0;
+
+ /* The x86_64 GOTPCREL are represented as 32bit PCrel relocations
+ and changed later by validate_fix. */
+ if (GOT_symbol && fixP->fx_subsy == GOT_symbol
+ && fixP->fx_r_type == BFD_RELOC_32_PCREL)
+ return 0;
+
+ /* adjust_reloc_syms doesn't know about the GOT. */
+ if (fixP->fx_r_type == BFD_RELOC_386_GOTOFF
+ || fixP->fx_r_type == BFD_RELOC_386_PLT32
+ || fixP->fx_r_type == BFD_RELOC_386_GOT32
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_GD
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_LDM
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_LDO_32
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_IE_32
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_IE
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_GOTIE
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_LE_32
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_LE
+ || fixP->fx_r_type == BFD_RELOC_X86_64_PLT32
+ || fixP->fx_r_type == BFD_RELOC_X86_64_GOT32
+ || fixP->fx_r_type == BFD_RELOC_X86_64_GOTPCREL
+ || fixP->fx_r_type == BFD_RELOC_X86_64_TLSGD
+ || fixP->fx_r_type == BFD_RELOC_X86_64_TLSLD
+ || fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF32
+ || fixP->fx_r_type == BFD_RELOC_X86_64_GOTTPOFF
+ || fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF32
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+#endif
+ return 1;
+}
+
+static int intel_float_operand PARAMS ((const char *mnemonic));
+
+static int
+intel_float_operand (mnemonic)
+ const char *mnemonic;
+{
+ if (mnemonic[0] == 'f' && mnemonic[1] == 'i')
+ return 2;
+
+ if (mnemonic[0] == 'f')
+ return 1;
+
+ return 0;
+}
+
+/* This is the guts of the machine-dependent assembler. LINE points to a
+ machine dependent instruction. This function is supposed to emit
+ the frags/bytes it assembles to. */
+
+void
+md_assemble (line)
+ char *line;
+{
+ int j;
+ char mnemonic[MAX_MNEM_SIZE];
+
+ /* Initialize globals. */
+ memset (&i, '\0', sizeof (i));
+ for (j = 0; j < MAX_OPERANDS; j++)
+ i.reloc[j] = NO_RELOC;
+ memset (disp_expressions, '\0', sizeof (disp_expressions));
+ memset (im_expressions, '\0', sizeof (im_expressions));
+ save_stack_p = save_stack;
+
+ /* First parse an instruction mnemonic & call i386_operand for the operands.
+ We assume that the scrubber has arranged it so that line[0] is the valid
+ start of a (possibly prefixed) mnemonic. */
+
+ line = parse_insn (line, mnemonic);
+ if (line == NULL)
+ return;
+
+ line = parse_operands (line, mnemonic);
+ if (line == NULL)
+ return;
+
+ /* Now we've parsed the mnemonic into a set of templates, and have the
+ operands at hand. */
+
+ /* All intel opcodes have reversed operands except for "bound" and
+ "enter". We also don't reverse intersegment "jmp" and "call"
+ instructions with 2 immediate operands so that the immediate segment
+ precedes the offset, as it does when in AT&T mode. "enter" and the
+ intersegment "jmp" and "call" instructions are the only ones that
+ have two immediate operands. */
+ if (intel_syntax && i.operands > 1
+ && (strcmp (mnemonic, "bound") != 0)
+ && !((i.types[0] & Imm) && (i.types[1] & Imm)))
+ swap_operands ();
+
+ if (i.imm_operands)
+ optimize_imm ();
+
+ if (i.disp_operands)
+ optimize_disp ();
+
+ /* Next, we find a template that matches the given insn,
+ making sure the overlap of the given operands types is consistent
+ with the template operand types. */
+
+ if (!match_template ())
+ return;
+
+ if (intel_syntax)
+ {
+ /* Undo SYSV386_COMPAT brokenness when in Intel mode. See i386.h */
+ if (SYSV386_COMPAT
+ && (i.tm.base_opcode & 0xfffffde0) == 0xdce0)
+ i.tm.base_opcode ^= FloatR;
+
+ /* Zap movzx and movsx suffix. The suffix may have been set from
+ "word ptr" or "byte ptr" on the source operand, but we'll use
+ the suffix later to choose the destination register. */
+ if ((i.tm.base_opcode & ~9) == 0x0fb6)
+ i.suffix = 0;
+ }
+
+ if (i.tm.opcode_modifier & FWait)
+ if (!add_prefix (FWAIT_OPCODE))
+ return;
+
+ /* Check string instruction segment overrides. */
+ if ((i.tm.opcode_modifier & IsString) != 0 && i.mem_operands != 0)
+ {
+ if (!check_string ())
+ return;
+ }
+
+ if (!process_suffix ())
+ return;
+
+ /* Make still unresolved immediate matches conform to size of immediate
+ given in i.suffix. */
+ if (!finalize_imm ())
+ return;
+
+ if (i.types[0] & Imm1)
+ i.imm_operands = 0; /* kludge for shift insns. */
+ if (i.types[0] & ImplicitRegister)
+ i.reg_operands--;
+ if (i.types[1] & ImplicitRegister)
+ i.reg_operands--;
+ if (i.types[2] & ImplicitRegister)
+ i.reg_operands--;
+
+ if (i.tm.opcode_modifier & ImmExt)
+ {
+ expressionS *exp;
+
+ if ((i.tm.cpu_flags & CpuPNI) && i.operands > 0)
+ {
+ /* These Intel Prescott New Instructions have the fixed
+ operands with an opcode suffix which is coded in the same
+ place as an 8-bit immediate field would be. Here we check
+ those operands and remove them afterwards. */
+ unsigned int x;
+
+ for (x = 0; x < i.operands; x++)
+ if (i.op[x].regs->reg_num != x)
+ as_bad (_("can't use register '%%%s' as operand %d in '%s'."),
+ i.op[x].regs->reg_name, x + 1, i.tm.name);
+ i.operands = 0;
+ }
+
+ /* These AMD 3DNow! and Intel Katmai New Instructions have an
+ opcode suffix which is coded in the same place as an 8-bit
+ immediate field would be. Here we fake an 8-bit immediate
+ operand from the opcode suffix stored in tm.extension_opcode. */
+
+ assert (i.imm_operands == 0 && i.operands <= 2 && 2 < MAX_OPERANDS);
+
+ exp = &im_expressions[i.imm_operands++];
+ i.op[i.operands].imms = exp;
+ i.types[i.operands++] = Imm8;
+ exp->X_op = O_constant;
+ exp->X_add_number = i.tm.extension_opcode;
+ i.tm.extension_opcode = None;
+ }
+
+ /* For insns with operands there are more diddles to do to the opcode. */
+ if (i.operands)
+ {
+ if (!process_operands ())
+ return;
+ }
+ else if (!quiet_warnings && (i.tm.opcode_modifier & Ugh) != 0)
+ {
+ /* UnixWare fsub no args is alias for fsubp, fadd -> faddp, etc. */
+ as_warn (_("translating to `%sp'"), i.tm.name);
+ }
+
+ /* Handle conversion of 'int $3' --> special int3 insn. */
+ if (i.tm.base_opcode == INT_OPCODE && i.op[0].imms->X_add_number == 3)
+ {
+ i.tm.base_opcode = INT3_OPCODE;
+ i.imm_operands = 0;
+ }
+
+ if ((i.tm.opcode_modifier & (Jump | JumpByte | JumpDword))
+ && i.op[0].disps->X_op == O_constant)
+ {
+ /* Convert "jmp constant" (and "call constant") to a jump (call) to
+ the absolute address given by the constant. Since ix86 jumps and
+ calls are pc relative, we need to generate a reloc. */
+ i.op[0].disps->X_add_symbol = &abs_symbol;
+ i.op[0].disps->X_op = O_symbol;
+ }
+
+ if ((i.tm.opcode_modifier & Rex64) != 0)
+ i.rex |= REX_MODE64;
+
+ /* For 8 bit registers we need an empty rex prefix. Also if the
+ instruction already has a prefix, we need to convert old
+ registers to new ones. */
+
+ if (((i.types[0] & Reg8) != 0
+ && (i.op[0].regs->reg_flags & RegRex64) != 0)
+ || ((i.types[1] & Reg8) != 0
+ && (i.op[1].regs->reg_flags & RegRex64) != 0)
+ || (((i.types[0] & Reg8) != 0 || (i.types[1] & Reg8) != 0)
+ && i.rex != 0))
+ {
+ int x;
+
+ i.rex |= REX_OPCODE;
+ for (x = 0; x < 2; x++)
+ {
+ /* Look for 8 bit operand that uses old registers. */
+ if ((i.types[x] & Reg8) != 0
+ && (i.op[x].regs->reg_flags & RegRex64) == 0)
+ {
+ /* In case it is "hi" register, give up. */
+ if (i.op[x].regs->reg_num > 3)
+ as_bad (_("can't encode register '%%%s' in an instruction requiring REX prefix.\n"),
+ i.op[x].regs->reg_name);
+
+ /* Otherwise it is equivalent to the extended register.
+ Since the encoding doesn't change this is merely
+ cosmetic cleanup for debug output. */
+
+ i.op[x].regs = i.op[x].regs + 8;
+ }
+ }
+ }
+
+ if (i.rex != 0)
+ add_prefix (REX_OPCODE | i.rex);
+
+ /* We are ready to output the insn. */
+ output_insn ();
+}
+
+static char *
+parse_insn (line, mnemonic)
+ char *line;
+ char *mnemonic;
+{
+ char *l = line;
+ char *token_start = l;
+ char *mnem_p;
+
+ /* Non-zero if we found a prefix only acceptable with string insns. */
+ const char *expecting_string_instruction = NULL;
+
+ while (1)
+ {
+ mnem_p = mnemonic;
+ while ((*mnem_p = mnemonic_chars[(unsigned char) *l]) != 0)
+ {
+ mnem_p++;
+ if (mnem_p >= mnemonic + MAX_MNEM_SIZE)
+ {
+ as_bad (_("no such instruction: `%s'"), token_start);
+ return NULL;
+ }
+ l++;
+ }
+ if (!is_space_char (*l)
+ && *l != END_OF_INSN
+ && *l != PREFIX_SEPARATOR
+ && *l != ',')
+ {
+ as_bad (_("invalid character %s in mnemonic"),
+ output_invalid (*l));
+ return NULL;
+ }
+ if (token_start == l)
+ {
+ if (*l == PREFIX_SEPARATOR)
+ as_bad (_("expecting prefix; got nothing"));
+ else
+ as_bad (_("expecting mnemonic; got nothing"));
+ return NULL;
+ }
+
+ /* Look up instruction (or prefix) via hash table. */
+ current_templates = hash_find (op_hash, mnemonic);
+
+ if (*l != END_OF_INSN
+ && (!is_space_char (*l) || l[1] != END_OF_INSN)
+ && current_templates
+ && (current_templates->start->opcode_modifier & IsPrefix))
+ {
+ /* If we are in 16-bit mode, do not allow addr16 or data16.
+ Similarly, in 32-bit mode, do not allow addr32 or data32. */
+ if ((current_templates->start->opcode_modifier & (Size16 | Size32))
+ && flag_code != CODE_64BIT
+ && (((current_templates->start->opcode_modifier & Size32) != 0)
+ ^ (flag_code == CODE_16BIT)))
+ {
+ as_bad (_("redundant %s prefix"),
+ current_templates->start->name);
+ return NULL;
+ }
+ /* Add prefix, checking for repeated prefixes. */
+ switch (add_prefix (current_templates->start->base_opcode))
+ {
+ case 0:
+ return NULL;
+ case 2:
+ expecting_string_instruction = current_templates->start->name;
+ break;
+ }
+ /* Skip past PREFIX_SEPARATOR and reset token_start. */
+ token_start = ++l;
+ }
+ else
+ break;
+ }
+
+ if (!current_templates)
+ {
+ /* See if we can get a match by trimming off a suffix. */
+ switch (mnem_p[-1])
+ {
+ case WORD_MNEM_SUFFIX:
+ case BYTE_MNEM_SUFFIX:
+ case QWORD_MNEM_SUFFIX:
+ i.suffix = mnem_p[-1];
+ mnem_p[-1] = '\0';
+ current_templates = hash_find (op_hash, mnemonic);
+ break;
+ case SHORT_MNEM_SUFFIX:
+ case LONG_MNEM_SUFFIX:
+ if (!intel_syntax)
+ {
+ i.suffix = mnem_p[-1];
+ mnem_p[-1] = '\0';
+ current_templates = hash_find (op_hash, mnemonic);
+ }
+ break;
+
+ /* Intel Syntax. */
+ case 'd':
+ if (intel_syntax)
+ {
+ if (intel_float_operand (mnemonic))
+ i.suffix = SHORT_MNEM_SUFFIX;
+ else
+ i.suffix = LONG_MNEM_SUFFIX;
+ mnem_p[-1] = '\0';
+ current_templates = hash_find (op_hash, mnemonic);
+ }
+ break;
+ }
+ if (!current_templates)
+ {
+ as_bad (_("no such instruction: `%s'"), token_start);
+ return NULL;
+ }
+ }
+
+ if (current_templates->start->opcode_modifier & (Jump | JumpByte))
+ {
+ /* Check for a branch hint. We allow ",pt" and ",pn" for
+ predict taken and predict not taken respectively.
+ I'm not sure that branch hints actually do anything on loop
+ and jcxz insns (JumpByte) for current Pentium4 chips. They
+ may work in the future and it doesn't hurt to accept them
+ now. */
+ if (l[0] == ',' && l[1] == 'p')
+ {
+ if (l[2] == 't')
+ {
+ if (!add_prefix (DS_PREFIX_OPCODE))
+ return NULL;
+ l += 3;
+ }
+ else if (l[2] == 'n')
+ {
+ if (!add_prefix (CS_PREFIX_OPCODE))
+ return NULL;
+ l += 3;
+ }
+ }
+ }
+ /* Any other comma loses. */
+ if (*l == ',')
+ {
+ as_bad (_("invalid character %s in mnemonic"),
+ output_invalid (*l));
+ return NULL;
+ }
+
+ /* Check if instruction is supported on specified architecture. */
+ if ((current_templates->start->cpu_flags & ~(Cpu64 | CpuNo64))
+ & ~(cpu_arch_flags & ~(Cpu64 | CpuNo64)))
+ {
+ as_warn (_("`%s' is not supported on `%s'"),
+ current_templates->start->name, cpu_arch_name);
+ }
+ else if ((Cpu386 & ~cpu_arch_flags) && (flag_code != CODE_16BIT))
+ {
+ as_warn (_("use .code16 to ensure correct addressing mode"));
+ }
+
+ /* Check for rep/repne without a string instruction. */
+ if (expecting_string_instruction
+ && !(current_templates->start->opcode_modifier & IsString))
+ {
+ as_bad (_("expecting string instruction after `%s'"),
+ expecting_string_instruction);
+ return NULL;
+ }
+
+ return l;
+}
+
+static char *
+parse_operands (l, mnemonic)
+ char *l;
+ const char *mnemonic;
+{
+ char *token_start;
+
+ /* 1 if operand is pending after ','. */
+ unsigned int expecting_operand = 0;
+
+ /* Non-zero if operand parens not balanced. */
+ unsigned int paren_not_balanced;
+
+ while (*l != END_OF_INSN)
+ {
+ /* Skip optional white space before operand. */
+ if (is_space_char (*l))
+ ++l;
+ if (!is_operand_char (*l) && *l != END_OF_INSN)
+ {
+ as_bad (_("invalid character %s before operand %d"),
+ output_invalid (*l),
+ i.operands + 1);
+ return NULL;
+ }
+ token_start = l; /* after white space */
+ paren_not_balanced = 0;
+ while (paren_not_balanced || *l != ',')
+ {
+ if (*l == END_OF_INSN)
+ {
+ if (paren_not_balanced)
+ {
+ if (!intel_syntax)
+ as_bad (_("unbalanced parenthesis in operand %d."),
+ i.operands + 1);
+ else
+ as_bad (_("unbalanced brackets in operand %d."),
+ i.operands + 1);
+ return NULL;
+ }
+ else
+ break; /* we are done */
+ }
+ else if (!is_operand_char (*l) && !is_space_char (*l))
+ {
+ as_bad (_("invalid character %s in operand %d"),
+ output_invalid (*l),
+ i.operands + 1);
+ return NULL;
+ }
+ if (!intel_syntax)
+ {
+ if (*l == '(')
+ ++paren_not_balanced;
+ if (*l == ')')
+ --paren_not_balanced;
+ }
+ else
+ {
+ if (*l == '[')
+ ++paren_not_balanced;
+ if (*l == ']')
+ --paren_not_balanced;
+ }
+ l++;
+ }
+ if (l != token_start)
+ { /* Yes, we've read in another operand. */
+ unsigned int operand_ok;
+ this_operand = i.operands++;
+ if (i.operands > MAX_OPERANDS)
+ {
+ as_bad (_("spurious operands; (%d operands/instruction max)"),
+ MAX_OPERANDS);
+ return NULL;
+ }
+ /* Now parse operand adding info to 'i' as we go along. */
+ END_STRING_AND_SAVE (l);
+
+ if (intel_syntax)
+ operand_ok =
+ i386_intel_operand (token_start,
+ intel_float_operand (mnemonic));
+ else
+ operand_ok = i386_operand (token_start);
+
+ RESTORE_END_STRING (l);
+ if (!operand_ok)
+ return NULL;
+ }
+ else
+ {
+ if (expecting_operand)
+ {
+ expecting_operand_after_comma:
+ as_bad (_("expecting operand after ','; got nothing"));
+ return NULL;
+ }
+ if (*l == ',')
+ {
+ as_bad (_("expecting operand before ','; got nothing"));
+ return NULL;
+ }
+ }
+
+ /* Now *l must be either ',' or END_OF_INSN. */
+ if (*l == ',')
+ {
+ if (*++l == END_OF_INSN)
+ {
+ /* Just skip it, if it's \n complain. */
+ goto expecting_operand_after_comma;
+ }
+ expecting_operand = 1;
+ }
+ }
+ return l;
+}
+
+static void
+swap_operands ()
+{
+ union i386_op temp_op;
+ unsigned int temp_type;
+ enum bfd_reloc_code_real temp_reloc;
+ int xchg1 = 0;
+ int xchg2 = 0;
+
+ if (i.operands == 2)
+ {
+ xchg1 = 0;
+ xchg2 = 1;
+ }
+ else if (i.operands == 3)
+ {
+ xchg1 = 0;
+ xchg2 = 2;
+ }
+ temp_type = i.types[xchg2];
+ i.types[xchg2] = i.types[xchg1];
+ i.types[xchg1] = temp_type;
+ temp_op = i.op[xchg2];
+ i.op[xchg2] = i.op[xchg1];
+ i.op[xchg1] = temp_op;
+ temp_reloc = i.reloc[xchg2];
+ i.reloc[xchg2] = i.reloc[xchg1];
+ i.reloc[xchg1] = temp_reloc;
+
+ if (i.mem_operands == 2)
+ {
+ const seg_entry *temp_seg;
+ temp_seg = i.seg[0];
+ i.seg[0] = i.seg[1];
+ i.seg[1] = temp_seg;
+ }
+}
+
+/* Try to ensure constant immediates are represented in the smallest
+ opcode possible. */
+static void
+optimize_imm ()
+{
+ char guess_suffix = 0;
+ int op;
+
+ if (i.suffix)
+ guess_suffix = i.suffix;
+ else if (i.reg_operands)
+ {
+ /* Figure out a suffix from the last register operand specified.
+ We can't do this properly yet, ie. excluding InOutPortReg,
+ but the following works for instructions with immediates.
+ In any case, we can't set i.suffix yet. */
+ for (op = i.operands; --op >= 0;)
+ if (i.types[op] & Reg)
+ {
+ if (i.types[op] & Reg8)
+ guess_suffix = BYTE_MNEM_SUFFIX;
+ else if (i.types[op] & Reg16)
+ guess_suffix = WORD_MNEM_SUFFIX;
+ else if (i.types[op] & Reg32)
+ guess_suffix = LONG_MNEM_SUFFIX;
+ else if (i.types[op] & Reg64)
+ guess_suffix = QWORD_MNEM_SUFFIX;
+ break;
+ }
+ }
+ else if ((flag_code == CODE_16BIT) ^ (i.prefix[DATA_PREFIX] != 0))
+ guess_suffix = WORD_MNEM_SUFFIX;
+
+ for (op = i.operands; --op >= 0;)
+ if (i.types[op] & Imm)
+ {
+ switch (i.op[op].imms->X_op)
+ {
+ case O_constant:
+ /* If a suffix is given, this operand may be shortened. */
+ switch (guess_suffix)
+ {
+ case LONG_MNEM_SUFFIX:
+ i.types[op] |= Imm32 | Imm64;
+ break;
+ case WORD_MNEM_SUFFIX:
+ i.types[op] |= Imm16 | Imm32S | Imm32 | Imm64;
+ break;
+ case BYTE_MNEM_SUFFIX:
+ i.types[op] |= Imm16 | Imm8 | Imm8S | Imm32S | Imm32 | Imm64;
+ break;
+ }
+
+ /* If this operand is at most 16 bits, convert it
+ to a signed 16 bit number before trying to see
+ whether it will fit in an even smaller size.
+ This allows a 16-bit operand such as $0xffe0 to
+ be recognised as within Imm8S range. */
+ if ((i.types[op] & Imm16)
+ && (i.op[op].imms->X_add_number & ~(offsetT) 0xffff) == 0)
+ {
+ i.op[op].imms->X_add_number =
+ (((i.op[op].imms->X_add_number & 0xffff) ^ 0x8000) - 0x8000);
+ }
+ if ((i.types[op] & Imm32)
+ && ((i.op[op].imms->X_add_number & ~(((offsetT) 2 << 31) - 1))
+ == 0))
+ {
+ i.op[op].imms->X_add_number = ((i.op[op].imms->X_add_number
+ ^ ((offsetT) 1 << 31))
+ - ((offsetT) 1 << 31));
+ }
+ i.types[op] |= smallest_imm_type (i.op[op].imms->X_add_number);
+
+ /* We must avoid matching of Imm32 templates when 64bit
+ only immediate is available. */
+ if (guess_suffix == QWORD_MNEM_SUFFIX)
+ i.types[op] &= ~Imm32;
+ break;
+
+ case O_absent:
+ case O_register:
+ abort ();
+
+ /* Symbols and expressions. */
+ default:
+ /* Convert symbolic operand to proper sizes for matching. */
+ switch (guess_suffix)
+ {
+ case QWORD_MNEM_SUFFIX:
+ i.types[op] = Imm64 | Imm32S;
+ break;
+ case LONG_MNEM_SUFFIX:
+ i.types[op] = Imm32 | Imm64;
+ break;
+ case WORD_MNEM_SUFFIX:
+ i.types[op] = Imm16 | Imm32 | Imm64;
+ break;
+ break;
+ case BYTE_MNEM_SUFFIX:
+ i.types[op] = Imm8 | Imm8S | Imm16 | Imm32S | Imm32;
+ break;
+ break;
+ }
+ break;
+ }
+ }
+}
+
+/* Try to use the smallest displacement type too. */
+static void
+optimize_disp ()
+{
+ int op;
+
+ for (op = i.operands; --op >= 0;)
+ if ((i.types[op] & Disp) && i.op[op].disps->X_op == O_constant)
+ {
+ offsetT disp = i.op[op].disps->X_add_number;
+
+ if (i.types[op] & Disp16)
+ {
+ /* We know this operand is at most 16 bits, so
+ convert to a signed 16 bit number before trying
+ to see whether it will fit in an even smaller
+ size. */
+
+ disp = (((disp & 0xffff) ^ 0x8000) - 0x8000);
+ }
+ else if (i.types[op] & Disp32)
+ {
+ /* We know this operand is at most 32 bits, so convert to a
+ signed 32 bit number before trying to see whether it will
+ fit in an even smaller size. */
+ disp &= (((offsetT) 2 << 31) - 1);
+ disp = (disp ^ ((offsetT) 1 << 31)) - ((addressT) 1 << 31);
+ }
+ if (flag_code == CODE_64BIT)
+ {
+ if (fits_in_signed_long (disp))
+ i.types[op] |= Disp32S;
+ if (fits_in_unsigned_long (disp))
+ i.types[op] |= Disp32;
+ }
+ if ((i.types[op] & (Disp32 | Disp32S | Disp16))
+ && fits_in_signed_byte (disp))
+ i.types[op] |= Disp8;
+ }
+}
+
+static int
+match_template ()
+{
+ /* Points to template once we've found it. */
+ const template *t;
+ unsigned int overlap0, overlap1, overlap2;
+ unsigned int found_reverse_match;
+ int suffix_check;
+
+#define MATCH(overlap, given, template) \
+ ((overlap & ~JumpAbsolute) \
+ && (((given) & (BaseIndex | JumpAbsolute)) \
+ == ((overlap) & (BaseIndex | JumpAbsolute))))
+
+ /* If given types r0 and r1 are registers they must be of the same type
+ unless the expected operand type register overlap is null.
+ Note that Acc in a template matches every size of reg. */
+#define CONSISTENT_REGISTER_MATCH(m0, g0, t0, m1, g1, t1) \
+ (((g0) & Reg) == 0 || ((g1) & Reg) == 0 \
+ || ((g0) & Reg) == ((g1) & Reg) \
+ || ((((m0) & Acc) ? Reg : (t0)) & (((m1) & Acc) ? Reg : (t1)) & Reg) == 0 )
+
+ overlap0 = 0;
+ overlap1 = 0;
+ overlap2 = 0;
+ found_reverse_match = 0;
+ suffix_check = (i.suffix == BYTE_MNEM_SUFFIX
+ ? No_bSuf
+ : (i.suffix == WORD_MNEM_SUFFIX
+ ? No_wSuf
+ : (i.suffix == SHORT_MNEM_SUFFIX
+ ? No_sSuf
+ : (i.suffix == LONG_MNEM_SUFFIX
+ ? No_lSuf
+ : (i.suffix == QWORD_MNEM_SUFFIX
+ ? No_qSuf
+ : (i.suffix == LONG_DOUBLE_MNEM_SUFFIX
+ ? No_xSuf : 0))))));
+
+ for (t = current_templates->start;
+ t < current_templates->end;
+ t++)
+ {
+ /* Must have right number of operands. */
+ if (i.operands != t->operands)
+ continue;
+
+ /* Check the suffix, except for some instructions in intel mode. */
+ if ((t->opcode_modifier & suffix_check)
+ && !(intel_syntax
+ && (t->opcode_modifier & IgnoreSize))
+ && !(intel_syntax
+ && t->base_opcode == 0xd9
+ && (t->extension_opcode == 5 /* 0xd9,5 "fldcw" */
+ || t->extension_opcode == 7))) /* 0xd9,7 "f{n}stcw" */
+ continue;
+
+ /* Do not verify operands when there are none. */
+ else if (!t->operands)
+ {
+ if (t->cpu_flags & ~cpu_arch_flags)
+ continue;
+ /* We've found a match; break out of loop. */
+ break;
+ }
+
+ overlap0 = i.types[0] & t->operand_types[0];
+ switch (t->operands)
+ {
+ case 1:
+ if (!MATCH (overlap0, i.types[0], t->operand_types[0]))
+ continue;
+ break;
+ case 2:
+ case 3:
+ overlap1 = i.types[1] & t->operand_types[1];
+ if (!MATCH (overlap0, i.types[0], t->operand_types[0])
+ || !MATCH (overlap1, i.types[1], t->operand_types[1])
+ || !CONSISTENT_REGISTER_MATCH (overlap0, i.types[0],
+ t->operand_types[0],
+ overlap1, i.types[1],
+ t->operand_types[1]))
+ {
+ /* Check if other direction is valid ... */
+ if ((t->opcode_modifier & (D | FloatD)) == 0)
+ continue;
+
+ /* Try reversing direction of operands. */
+ overlap0 = i.types[0] & t->operand_types[1];
+ overlap1 = i.types[1] & t->operand_types[0];
+ if (!MATCH (overlap0, i.types[0], t->operand_types[1])
+ || !MATCH (overlap1, i.types[1], t->operand_types[0])
+ || !CONSISTENT_REGISTER_MATCH (overlap0, i.types[0],
+ t->operand_types[1],
+ overlap1, i.types[1],
+ t->operand_types[0]))
+ {
+ /* Does not match either direction. */
+ continue;
+ }
+ /* found_reverse_match holds which of D or FloatDR
+ we've found. */
+ found_reverse_match = t->opcode_modifier & (D | FloatDR);
+ }
+ /* Found a forward 2 operand match here. */
+ else if (t->operands == 3)
+ {
+ /* Here we make use of the fact that there are no
+ reverse match 3 operand instructions, and all 3
+ operand instructions only need to be checked for
+ register consistency between operands 2 and 3. */
+ overlap2 = i.types[2] & t->operand_types[2];
+ if (!MATCH (overlap2, i.types[2], t->operand_types[2])
+ || !CONSISTENT_REGISTER_MATCH (overlap1, i.types[1],
+ t->operand_types[1],
+ overlap2, i.types[2],
+ t->operand_types[2]))
+
+ continue;
+ }
+ /* Found either forward/reverse 2 or 3 operand match here:
+ slip through to break. */
+ }
+ if (t->cpu_flags & ~cpu_arch_flags)
+ {
+ found_reverse_match = 0;
+ continue;
+ }
+ /* We've found a match; break out of loop. */
+ break;
+ }
+
+ if (t == current_templates->end)
+ {
+ /* We found no match. */
+ as_bad (_("suffix or operands invalid for `%s'"),
+ current_templates->start->name);
+ return 0;
+ }
+
+ if (!quiet_warnings)
+ {
+ if (!intel_syntax
+ && ((i.types[0] & JumpAbsolute)
+ != (t->operand_types[0] & JumpAbsolute)))
+ {
+ as_warn (_("indirect %s without `*'"), t->name);
+ }
+
+ if ((t->opcode_modifier & (IsPrefix | IgnoreSize))
+ == (IsPrefix | IgnoreSize))
+ {
+ /* Warn them that a data or address size prefix doesn't
+ affect assembly of the next line of code. */
+ as_warn (_("stand-alone `%s' prefix"), t->name);
+ }
+ }
+
+ /* Copy the template we found. */
+ i.tm = *t;
+ if (found_reverse_match)
+ {
+ /* If we found a reverse match we must alter the opcode
+ direction bit. found_reverse_match holds bits to change
+ (different for int & float insns). */
+
+ i.tm.base_opcode ^= found_reverse_match;
+
+ i.tm.operand_types[0] = t->operand_types[1];
+ i.tm.operand_types[1] = t->operand_types[0];
+ }
+
+ return 1;
+}
+
+static int
+check_string ()
+{
+ int mem_op = (i.types[0] & AnyMem) ? 0 : 1;
+ if ((i.tm.operand_types[mem_op] & EsSeg) != 0)
+ {
+ if (i.seg[0] != NULL && i.seg[0] != &es)
+ {
+ as_bad (_("`%s' operand %d must use `%%es' segment"),
+ i.tm.name,
+ mem_op + 1);
+ return 0;
+ }
+ /* There's only ever one segment override allowed per instruction.
+ This instruction possibly has a legal segment override on the
+ second operand, so copy the segment to where non-string
+ instructions store it, allowing common code. */
+ i.seg[0] = i.seg[1];
+ }
+ else if ((i.tm.operand_types[mem_op + 1] & EsSeg) != 0)
+ {
+ if (i.seg[1] != NULL && i.seg[1] != &es)
+ {
+ as_bad (_("`%s' operand %d must use `%%es' segment"),
+ i.tm.name,
+ mem_op + 2);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+process_suffix ()
+{
+ /* If matched instruction specifies an explicit instruction mnemonic
+ suffix, use it. */
+ if (i.tm.opcode_modifier & (Size16 | Size32 | Size64))
+ {
+ if (i.tm.opcode_modifier & Size16)
+ i.suffix = WORD_MNEM_SUFFIX;
+ else if (i.tm.opcode_modifier & Size64)
+ i.suffix = QWORD_MNEM_SUFFIX;
+ else
+ i.suffix = LONG_MNEM_SUFFIX;
+ }
+ else if (i.reg_operands)
+ {
+ /* If there's no instruction mnemonic suffix we try to invent one
+ based on register operands. */
+ if (!i.suffix)
+ {
+ /* We take i.suffix from the last register operand specified,
+ Destination register type is more significant than source
+ register type. */
+ int op;
+ for (op = i.operands; --op >= 0;)
+ if ((i.types[op] & Reg)
+ && !(i.tm.operand_types[op] & InOutPortReg))
+ {
+ i.suffix = ((i.types[op] & Reg8) ? BYTE_MNEM_SUFFIX :
+ (i.types[op] & Reg16) ? WORD_MNEM_SUFFIX :
+ (i.types[op] & Reg64) ? QWORD_MNEM_SUFFIX :
+ LONG_MNEM_SUFFIX);
+ break;
+ }
+ }
+ else if (i.suffix == BYTE_MNEM_SUFFIX)
+ {
+ if (!check_byte_reg ())
+ return 0;
+ }
+ else if (i.suffix == LONG_MNEM_SUFFIX)
+ {
+ if (!check_long_reg ())
+ return 0;
+ }
+ else if (i.suffix == QWORD_MNEM_SUFFIX)
+ {
+ if (!check_qword_reg ())
+ return 0;
+ }
+ else if (i.suffix == WORD_MNEM_SUFFIX)
+ {
+ if (!check_word_reg ())
+ return 0;
+ }
+ else if (intel_syntax && (i.tm.opcode_modifier & IgnoreSize))
+ /* Do nothing if the instruction is going to ignore the prefix. */
+ ;
+ else
+ abort ();
+ }
+ else if ((i.tm.opcode_modifier & DefaultSize) && !i.suffix)
+ {
+ i.suffix = stackop_size;
+ }
+
+ /* Change the opcode based on the operand size given by i.suffix;
+ We need not change things for byte insns. */
+
+ if (!i.suffix && (i.tm.opcode_modifier & W))
+ {
+ as_bad (_("no instruction mnemonic suffix given and no register operands; can't size instruction"));
+ return 0;
+ }
+
+ if (i.suffix && i.suffix != BYTE_MNEM_SUFFIX)
+ {
+ /* It's not a byte, select word/dword operation. */
+ if (i.tm.opcode_modifier & W)
+ {
+ if (i.tm.opcode_modifier & ShortForm)
+ i.tm.base_opcode |= 8;
+ else
+ i.tm.base_opcode |= 1;
+ }
+
+ /* Now select between word & dword operations via the operand
+ size prefix, except for instructions that will ignore this
+ prefix anyway. */
+ if (i.suffix != QWORD_MNEM_SUFFIX
+ && !(i.tm.opcode_modifier & IgnoreSize)
+ && ((i.suffix == LONG_MNEM_SUFFIX) == (flag_code == CODE_16BIT)
+ || (flag_code == CODE_64BIT
+ && (i.tm.opcode_modifier & JumpByte))))
+ {
+ unsigned int prefix = DATA_PREFIX_OPCODE;
+ if (i.tm.opcode_modifier & JumpByte) /* jcxz, loop */
+ prefix = ADDR_PREFIX_OPCODE;
+
+ if (!add_prefix (prefix))
+ return 0;
+ }
+
+ /* Set mode64 for an operand. */
+ if (i.suffix == QWORD_MNEM_SUFFIX
+ && flag_code == CODE_64BIT
+ && (i.tm.opcode_modifier & NoRex64) == 0)
+ i.rex |= REX_MODE64;
+
+ /* Size floating point instruction. */
+ if (i.suffix == LONG_MNEM_SUFFIX)
+ {
+ if (i.tm.opcode_modifier & FloatMF)
+ i.tm.base_opcode ^= 4;
+ }
+ }
+
+ return 1;
+}
+
+static int
+check_byte_reg ()
+{
+ int op;
+ for (op = i.operands; --op >= 0;)
+ {
+ /* If this is an eight bit register, it's OK. If it's the 16 or
+ 32 bit version of an eight bit register, we will just use the
+ low portion, and that's OK too. */
+ if (i.types[op] & Reg8)
+ continue;
+
+ /* movzx and movsx should not generate this warning. */
+ if (intel_syntax
+ && (i.tm.base_opcode == 0xfb7
+ || i.tm.base_opcode == 0xfb6
+ || i.tm.base_opcode == 0x63
+ || i.tm.base_opcode == 0xfbe
+ || i.tm.base_opcode == 0xfbf))
+ continue;
+
+ if ((i.types[op] & WordReg) && i.op[op].regs->reg_num < 4
+#if 0
+ /* Check that the template allows eight bit regs. This
+ kills insns such as `orb $1,%edx', which maybe should be
+ allowed. */
+ && (i.tm.operand_types[op] & (Reg8 | InOutPortReg))
+#endif
+ )
+ {
+ /* Prohibit these changes in the 64bit mode, since the
+ lowering is more complicated. */
+ if (flag_code == CODE_64BIT
+ && (i.tm.operand_types[op] & InOutPortReg) == 0)
+ {
+ as_bad (_("Incorrect register `%%%s' used with `%c' suffix"),
+ i.op[op].regs->reg_name,
+ i.suffix);
+ return 0;
+ }
+#if REGISTER_WARNINGS
+ if (!quiet_warnings
+ && (i.tm.operand_types[op] & InOutPortReg) == 0)
+ as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"),
+ (i.op[op].regs + (i.types[op] & Reg16
+ ? REGNAM_AL - REGNAM_AX
+ : REGNAM_AL - REGNAM_EAX))->reg_name,
+ i.op[op].regs->reg_name,
+ i.suffix);
+#endif
+ continue;
+ }
+ /* Any other register is bad. */
+ if (i.types[op] & (Reg | RegMMX | RegXMM
+ | SReg2 | SReg3
+ | Control | Debug | Test
+ | FloatReg | FloatAcc))
+ {
+ as_bad (_("`%%%s' not allowed with `%s%c'"),
+ i.op[op].regs->reg_name,
+ i.tm.name,
+ i.suffix);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+check_long_reg ()
+{
+ int op;
+
+ for (op = i.operands; --op >= 0;)
+ /* Reject eight bit registers, except where the template requires
+ them. (eg. movzb) */
+ if ((i.types[op] & Reg8) != 0
+ && (i.tm.operand_types[op] & (Reg16 | Reg32 | Acc)) != 0)
+ {
+ as_bad (_("`%%%s' not allowed with `%s%c'"),
+ i.op[op].regs->reg_name,
+ i.tm.name,
+ i.suffix);
+ return 0;
+ }
+ /* Warn if the e prefix on a general reg is missing. */
+ else if ((!quiet_warnings || flag_code == CODE_64BIT)
+ && (i.types[op] & Reg16) != 0
+ && (i.tm.operand_types[op] & (Reg32 | Acc)) != 0)
+ {
+ /* Prohibit these changes in the 64bit mode, since the
+ lowering is more complicated. */
+ if (flag_code == CODE_64BIT)
+ {
+ as_bad (_("Incorrect register `%%%s' used with `%c' suffix"),
+ i.op[op].regs->reg_name,
+ i.suffix);
+ return 0;
+ }
+#if REGISTER_WARNINGS
+ else
+ as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"),
+ (i.op[op].regs + REGNAM_EAX - REGNAM_AX)->reg_name,
+ i.op[op].regs->reg_name,
+ i.suffix);
+#endif
+ }
+ /* Warn if the r prefix on a general reg is missing. */
+ else if ((i.types[op] & Reg64) != 0
+ && (i.tm.operand_types[op] & (Reg32 | Acc)) != 0)
+ {
+ as_bad (_("Incorrect register `%%%s' used with `%c' suffix"),
+ i.op[op].regs->reg_name,
+ i.suffix);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+check_qword_reg ()
+{
+ int op;
+
+ for (op = i.operands; --op >= 0; )
+ /* Reject eight bit registers, except where the template requires
+ them. (eg. movzb) */
+ if ((i.types[op] & Reg8) != 0
+ && (i.tm.operand_types[op] & (Reg16 | Reg32 | Acc)) != 0)
+ {
+ as_bad (_("`%%%s' not allowed with `%s%c'"),
+ i.op[op].regs->reg_name,
+ i.tm.name,
+ i.suffix);
+ return 0;
+ }
+ /* Warn if the e prefix on a general reg is missing. */
+ else if (((i.types[op] & Reg16) != 0
+ || (i.types[op] & Reg32) != 0)
+ && (i.tm.operand_types[op] & (Reg32 | Acc)) != 0)
+ {
+ /* Prohibit these changes in the 64bit mode, since the
+ lowering is more complicated. */
+ as_bad (_("Incorrect register `%%%s' used with `%c' suffix"),
+ i.op[op].regs->reg_name,
+ i.suffix);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+check_word_reg ()
+{
+ int op;
+ for (op = i.operands; --op >= 0;)
+ /* Reject eight bit registers, except where the template requires
+ them. (eg. movzb) */
+ if ((i.types[op] & Reg8) != 0
+ && (i.tm.operand_types[op] & (Reg16 | Reg32 | Acc)) != 0)
+ {
+ as_bad (_("`%%%s' not allowed with `%s%c'"),
+ i.op[op].regs->reg_name,
+ i.tm.name,
+ i.suffix);
+ return 0;
+ }
+ /* Warn if the e prefix on a general reg is present. */
+ else if ((!quiet_warnings || flag_code == CODE_64BIT)
+ && (i.types[op] & Reg32) != 0
+ && (i.tm.operand_types[op] & (Reg16 | Acc)) != 0)
+ {
+ /* Prohibit these changes in the 64bit mode, since the
+ lowering is more complicated. */
+ if (flag_code == CODE_64BIT)
+ {
+ as_bad (_("Incorrect register `%%%s' used with `%c' suffix"),
+ i.op[op].regs->reg_name,
+ i.suffix);
+ return 0;
+ }
+ else
+#if REGISTER_WARNINGS
+ as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"),
+ (i.op[op].regs + REGNAM_AX - REGNAM_EAX)->reg_name,
+ i.op[op].regs->reg_name,
+ i.suffix);
+#endif
+ }
+ return 1;
+}
+
+static int
+finalize_imm ()
+{
+ unsigned int overlap0, overlap1, overlap2;
+
+ overlap0 = i.types[0] & i.tm.operand_types[0];
+ if ((overlap0 & (Imm8 | Imm8S | Imm16 | Imm32 | Imm32S))
+ && overlap0 != Imm8 && overlap0 != Imm8S
+ && overlap0 != Imm16 && overlap0 != Imm32S
+ && overlap0 != Imm32 && overlap0 != Imm64)
+ {
+ if (i.suffix)
+ {
+ overlap0 &= (i.suffix == BYTE_MNEM_SUFFIX
+ ? Imm8 | Imm8S
+ : (i.suffix == WORD_MNEM_SUFFIX
+ ? Imm16
+ : (i.suffix == QWORD_MNEM_SUFFIX
+ ? Imm64 | Imm32S
+ : Imm32)));
+ }
+ else if (overlap0 == (Imm16 | Imm32S | Imm32)
+ || overlap0 == (Imm16 | Imm32)
+ || overlap0 == (Imm16 | Imm32S))
+ {
+ overlap0 = ((flag_code == CODE_16BIT) ^ (i.prefix[DATA_PREFIX] != 0)
+ ? Imm16 : Imm32S);
+ }
+ if (overlap0 != Imm8 && overlap0 != Imm8S
+ && overlap0 != Imm16 && overlap0 != Imm32S
+ && overlap0 != Imm32 && overlap0 != Imm64)
+ {
+ as_bad (_("no instruction mnemonic suffix given; can't determine immediate size"));
+ return 0;
+ }
+ }
+ i.types[0] = overlap0;
+
+ overlap1 = i.types[1] & i.tm.operand_types[1];
+ if ((overlap1 & (Imm8 | Imm8S | Imm16 | Imm32S | Imm32))
+ && overlap1 != Imm8 && overlap1 != Imm8S
+ && overlap1 != Imm16 && overlap1 != Imm32S
+ && overlap1 != Imm32 && overlap1 != Imm64)
+ {
+ if (i.suffix)
+ {
+ overlap1 &= (i.suffix == BYTE_MNEM_SUFFIX
+ ? Imm8 | Imm8S
+ : (i.suffix == WORD_MNEM_SUFFIX
+ ? Imm16
+ : (i.suffix == QWORD_MNEM_SUFFIX
+ ? Imm64 | Imm32S
+ : Imm32)));
+ }
+ else if (overlap1 == (Imm16 | Imm32 | Imm32S)
+ || overlap1 == (Imm16 | Imm32)
+ || overlap1 == (Imm16 | Imm32S))
+ {
+ overlap1 = ((flag_code == CODE_16BIT) ^ (i.prefix[DATA_PREFIX] != 0)
+ ? Imm16 : Imm32S);
+ }
+ if (overlap1 != Imm8 && overlap1 != Imm8S
+ && overlap1 != Imm16 && overlap1 != Imm32S
+ && overlap1 != Imm32 && overlap1 != Imm64)
+ {
+ as_bad (_("no instruction mnemonic suffix given; can't determine immediate size %x %c"),overlap1, i.suffix);
+ return 0;
+ }
+ }
+ i.types[1] = overlap1;
+
+ overlap2 = i.types[2] & i.tm.operand_types[2];
+ assert ((overlap2 & Imm) == 0);
+ i.types[2] = overlap2;
+
+ return 1;
+}
+
+static int
+process_operands ()
+{
+ /* Default segment register this instruction will use for memory
+ accesses. 0 means unknown. This is only for optimizing out
+ unnecessary segment overrides. */
+ const seg_entry *default_seg = 0;
+
+ /* The imul $imm, %reg instruction is converted into
+ imul $imm, %reg, %reg, and the clr %reg instruction
+ is converted into xor %reg, %reg. */
+ if (i.tm.opcode_modifier & regKludge)
+ {
+ unsigned int first_reg_op = (i.types[0] & Reg) ? 0 : 1;
+ /* Pretend we saw the extra register operand. */
+ assert (i.op[first_reg_op + 1].regs == 0);
+ i.op[first_reg_op + 1].regs = i.op[first_reg_op].regs;
+ i.types[first_reg_op + 1] = i.types[first_reg_op];
+ i.reg_operands = 2;
+ }
+
+ if (i.tm.opcode_modifier & ShortForm)
+ {
+ /* The register or float register operand is in operand 0 or 1. */
+ unsigned int op = (i.types[0] & (Reg | FloatReg)) ? 0 : 1;
+ /* Register goes in low 3 bits of opcode. */
+ i.tm.base_opcode |= i.op[op].regs->reg_num;
+ if ((i.op[op].regs->reg_flags & RegRex) != 0)
+ i.rex |= REX_EXTZ;
+ if (!quiet_warnings && (i.tm.opcode_modifier & Ugh) != 0)
+ {
+ /* Warn about some common errors, but press on regardless.
+ The first case can be generated by gcc (<= 2.8.1). */
+ if (i.operands == 2)
+ {
+ /* Reversed arguments on faddp, fsubp, etc. */
+ as_warn (_("translating to `%s %%%s,%%%s'"), i.tm.name,
+ i.op[1].regs->reg_name,
+ i.op[0].regs->reg_name);
+ }
+ else
+ {
+ /* Extraneous `l' suffix on fp insn. */
+ as_warn (_("translating to `%s %%%s'"), i.tm.name,
+ i.op[0].regs->reg_name);
+ }
+ }
+ }
+ else if (i.tm.opcode_modifier & Modrm)
+ {
+ /* The opcode is completed (modulo i.tm.extension_opcode which
+ must be put into the modrm byte). Now, we make the modrm and
+ index base bytes based on all the info we've collected. */
+
+ default_seg = build_modrm_byte ();
+ }
+ else if (i.tm.opcode_modifier & (Seg2ShortForm | Seg3ShortForm))
+ {
+ if (i.tm.base_opcode == POP_SEG_SHORT
+ && i.op[0].regs->reg_num == 1)
+ {
+ as_bad (_("you can't `pop %%cs'"));
+ return 0;
+ }
+ i.tm.base_opcode |= (i.op[0].regs->reg_num << 3);
+ if ((i.op[0].regs->reg_flags & RegRex) != 0)
+ i.rex |= REX_EXTZ;
+ }
+ else if ((i.tm.base_opcode & ~(D | W)) == MOV_AX_DISP32)
+ {
+ default_seg = &ds;
+ }
+ else if ((i.tm.opcode_modifier & IsString) != 0)
+ {
+ /* For the string instructions that allow a segment override
+ on one of their operands, the default segment is ds. */
+ default_seg = &ds;
+ }
+
+ if (i.tm.base_opcode == 0x8d /* lea */ && i.seg[0] && !quiet_warnings)
+ as_warn (_("segment override on `lea' is ineffectual"));
+
+ /* If a segment was explicitly specified, and the specified segment
+ is not the default, use an opcode prefix to select it. If we
+ never figured out what the default segment is, then default_seg
+ will be zero at this point, and the specified segment prefix will
+ always be used. */
+ if ((i.seg[0]) && (i.seg[0] != default_seg))
+ {
+ if (!add_prefix (i.seg[0]->seg_prefix))
+ return 0;
+ }
+ return 1;
+}
+
+static const seg_entry *
+build_modrm_byte ()
+{
+ const seg_entry *default_seg = 0;
+
+ /* i.reg_operands MUST be the number of real register operands;
+ implicit registers do not count. */
+ if (i.reg_operands == 2)
+ {
+ unsigned int source, dest;
+ source = ((i.types[0]
+ & (Reg | RegMMX | RegXMM
+ | SReg2 | SReg3
+ | Control | Debug | Test))
+ ? 0 : 1);
+ dest = source + 1;
+
+ i.rm.mode = 3;
+ /* One of the register operands will be encoded in the i.tm.reg
+ field, the other in the combined i.tm.mode and i.tm.regmem
+ fields. If no form of this instruction supports a memory
+ destination operand, then we assume the source operand may
+ sometimes be a memory operand and so we need to store the
+ destination in the i.rm.reg field. */
+ if ((i.tm.operand_types[dest] & AnyMem) == 0)
+ {
+ i.rm.reg = i.op[dest].regs->reg_num;
+ i.rm.regmem = i.op[source].regs->reg_num;
+ if ((i.op[dest].regs->reg_flags & RegRex) != 0)
+ i.rex |= REX_EXTX;
+ if ((i.op[source].regs->reg_flags & RegRex) != 0)
+ i.rex |= REX_EXTZ;
+ }
+ else
+ {
+ i.rm.reg = i.op[source].regs->reg_num;
+ i.rm.regmem = i.op[dest].regs->reg_num;
+ if ((i.op[dest].regs->reg_flags & RegRex) != 0)
+ i.rex |= REX_EXTZ;
+ if ((i.op[source].regs->reg_flags & RegRex) != 0)
+ i.rex |= REX_EXTX;
+ }
+ }
+ else
+ { /* If it's not 2 reg operands... */
+ if (i.mem_operands)
+ {
+ unsigned int fake_zero_displacement = 0;
+ unsigned int op = ((i.types[0] & AnyMem)
+ ? 0
+ : (i.types[1] & AnyMem) ? 1 : 2);
+
+ default_seg = &ds;
+
+ if (i.base_reg == 0)
+ {
+ i.rm.mode = 0;
+ if (!i.disp_operands)
+ fake_zero_displacement = 1;
+ if (i.index_reg == 0)
+ {
+ /* Operand is just <disp> */
+ if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0)
+ && (flag_code != CODE_64BIT))
+ {
+ i.rm.regmem = NO_BASE_REGISTER_16;
+ i.types[op] &= ~Disp;
+ i.types[op] |= Disp16;
+ }
+ else if (flag_code != CODE_64BIT
+ || (i.prefix[ADDR_PREFIX] != 0))
+ {
+ i.rm.regmem = NO_BASE_REGISTER;
+ i.types[op] &= ~Disp;
+ i.types[op] |= Disp32;
+ }
+ else
+ {
+ /* 64bit mode overwrites the 32bit absolute
+ addressing by RIP relative addressing and
+ absolute addressing is encoded by one of the
+ redundant SIB forms. */
+ i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
+ i.sib.base = NO_BASE_REGISTER;
+ i.sib.index = NO_INDEX_REGISTER;
+ i.types[op] &= ~Disp;
+ i.types[op] |= Disp32S;
+ }
+ }
+ else /* !i.base_reg && i.index_reg */
+ {
+ i.sib.index = i.index_reg->reg_num;
+ i.sib.base = NO_BASE_REGISTER;
+ i.sib.scale = i.log2_scale_factor;
+ i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
+ i.types[op] &= ~Disp;
+ if (flag_code != CODE_64BIT)
+ i.types[op] |= Disp32; /* Must be 32 bit */
+ else
+ i.types[op] |= Disp32S;
+ if ((i.index_reg->reg_flags & RegRex) != 0)
+ i.rex |= REX_EXTY;
+ }
+ }
+ /* RIP addressing for 64bit mode. */
+ else if (i.base_reg->reg_type == BaseIndex)
+ {
+ i.rm.regmem = NO_BASE_REGISTER;
+ i.types[op] &= ~Disp;
+ i.types[op] |= Disp32S;
+ i.flags[op] = Operand_PCrel;
+ }
+ else if (i.base_reg->reg_type & Reg16)
+ {
+ switch (i.base_reg->reg_num)
+ {
+ case 3: /* (%bx) */
+ if (i.index_reg == 0)
+ i.rm.regmem = 7;
+ else /* (%bx,%si) -> 0, or (%bx,%di) -> 1 */
+ i.rm.regmem = i.index_reg->reg_num - 6;
+ break;
+ case 5: /* (%bp) */
+ default_seg = &ss;
+ if (i.index_reg == 0)
+ {
+ i.rm.regmem = 6;
+ if ((i.types[op] & Disp) == 0)
+ {
+ /* fake (%bp) into 0(%bp) */
+ i.types[op] |= Disp8;
+ fake_zero_displacement = 1;
+ }
+ }
+ else /* (%bp,%si) -> 2, or (%bp,%di) -> 3 */
+ i.rm.regmem = i.index_reg->reg_num - 6 + 2;
+ break;
+ default: /* (%si) -> 4 or (%di) -> 5 */
+ i.rm.regmem = i.base_reg->reg_num - 6 + 4;
+ }
+ i.rm.mode = mode_from_disp_size (i.types[op]);
+ }
+ else /* i.base_reg and 32/64 bit mode */
+ {
+ if (flag_code == CODE_64BIT
+ && (i.types[op] & Disp))
+ {
+ if (i.types[op] & Disp8)
+ i.types[op] = Disp8 | Disp32S;
+ else
+ i.types[op] = Disp32S;
+ }
+ i.rm.regmem = i.base_reg->reg_num;
+ if ((i.base_reg->reg_flags & RegRex) != 0)
+ i.rex |= REX_EXTZ;
+ i.sib.base = i.base_reg->reg_num;
+ /* x86-64 ignores REX prefix bit here to avoid decoder
+ complications. */
+ if ((i.base_reg->reg_num & 7) == EBP_REG_NUM)
+ {
+ default_seg = &ss;
+ if (i.disp_operands == 0)
+ {
+ fake_zero_displacement = 1;
+ i.types[op] |= Disp8;
+ }
+ }
+ else if (i.base_reg->reg_num == ESP_REG_NUM)
+ {
+ default_seg = &ss;
+ }
+ i.sib.scale = i.log2_scale_factor;
+ if (i.index_reg == 0)
+ {
+ /* <disp>(%esp) becomes two byte modrm with no index
+ register. We've already stored the code for esp
+ in i.rm.regmem ie. ESCAPE_TO_TWO_BYTE_ADDRESSING.
+ Any base register besides %esp will not use the
+ extra modrm byte. */
+ i.sib.index = NO_INDEX_REGISTER;
+#if !SCALE1_WHEN_NO_INDEX
+ /* Another case where we force the second modrm byte. */
+ if (i.log2_scale_factor)
+ i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
+#endif
+ }
+ else
+ {
+ i.sib.index = i.index_reg->reg_num;
+ i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
+ if ((i.index_reg->reg_flags & RegRex) != 0)
+ i.rex |= REX_EXTY;
+ }
+ i.rm.mode = mode_from_disp_size (i.types[op]);
+ }
+
+ if (fake_zero_displacement)
+ {
+ /* Fakes a zero displacement assuming that i.types[op]
+ holds the correct displacement size. */
+ expressionS *exp;
+
+ assert (i.op[op].disps == 0);
+ exp = &disp_expressions[i.disp_operands++];
+ i.op[op].disps = exp;
+ exp->X_op = O_constant;
+ exp->X_add_number = 0;
+ exp->X_add_symbol = (symbolS *) 0;
+ exp->X_op_symbol = (symbolS *) 0;
+ }
+ }
+
+ /* Fill in i.rm.reg or i.rm.regmem field with register operand
+ (if any) based on i.tm.extension_opcode. Again, we must be
+ careful to make sure that segment/control/debug/test/MMX
+ registers are coded into the i.rm.reg field. */
+ if (i.reg_operands)
+ {
+ unsigned int op =
+ ((i.types[0]
+ & (Reg | RegMMX | RegXMM
+ | SReg2 | SReg3
+ | Control | Debug | Test))
+ ? 0
+ : ((i.types[1]
+ & (Reg | RegMMX | RegXMM
+ | SReg2 | SReg3
+ | Control | Debug | Test))
+ ? 1
+ : 2));
+ /* If there is an extension opcode to put here, the register
+ number must be put into the regmem field. */
+ if (i.tm.extension_opcode != None)
+ {
+ i.rm.regmem = i.op[op].regs->reg_num;
+ if ((i.op[op].regs->reg_flags & RegRex) != 0)
+ i.rex |= REX_EXTZ;
+ }
+ else
+ {
+ i.rm.reg = i.op[op].regs->reg_num;
+ if ((i.op[op].regs->reg_flags & RegRex) != 0)
+ i.rex |= REX_EXTX;
+ }
+
+ /* Now, if no memory operand has set i.rm.mode = 0, 1, 2 we
+ must set it to 3 to indicate this is a register operand
+ in the regmem field. */
+ if (!i.mem_operands)
+ i.rm.mode = 3;
+ }
+
+ /* Fill in i.rm.reg field with extension opcode (if any). */
+ if (i.tm.extension_opcode != None)
+ i.rm.reg = i.tm.extension_opcode;
+ }
+ return default_seg;
+}
+
+static void
+output_branch ()
+{
+ char *p;
+ int code16;
+ int prefix;
+ relax_substateT subtype;
+ symbolS *sym;
+ offsetT off;
+
+ code16 = 0;
+ if (flag_code == CODE_16BIT)
+ code16 = CODE16;
+
+ prefix = 0;
+ if (i.prefix[DATA_PREFIX] != 0)
+ {
+ prefix = 1;
+ i.prefixes -= 1;
+ code16 ^= CODE16;
+ }
+ /* Pentium4 branch hints. */
+ if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE /* not taken */
+ || i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE /* taken */)
+ {
+ prefix++;
+ i.prefixes--;
+ }
+ if (i.prefix[REX_PREFIX] != 0)
+ {
+ prefix++;
+ i.prefixes--;
+ }
+
+ if (i.prefixes != 0 && !intel_syntax)
+ as_warn (_("skipping prefixes on this instruction"));
+
+ /* It's always a symbol; End frag & setup for relax.
+ Make sure there is enough room in this frag for the largest
+ instruction we may generate in md_convert_frag. This is 2
+ bytes for the opcode and room for the prefix and largest
+ displacement. */
+ frag_grow (prefix + 2 + 4);
+ /* Prefix and 1 opcode byte go in fr_fix. */
+ p = frag_more (prefix + 1);
+ if (i.prefix[DATA_PREFIX] != 0)
+ *p++ = DATA_PREFIX_OPCODE;
+ if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE
+ || i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE)
+ *p++ = i.prefix[SEG_PREFIX];
+ if (i.prefix[REX_PREFIX] != 0)
+ *p++ = i.prefix[REX_PREFIX];
+ *p = i.tm.base_opcode;
+
+ if ((unsigned char) *p == JUMP_PC_RELATIVE)
+ subtype = ENCODE_RELAX_STATE (UNCOND_JUMP, SMALL);
+ else if ((cpu_arch_flags & Cpu386) != 0)
+ subtype = ENCODE_RELAX_STATE (COND_JUMP, SMALL);
+ else
+ subtype = ENCODE_RELAX_STATE (COND_JUMP86, SMALL);
+ subtype |= code16;
+
+ sym = i.op[0].disps->X_add_symbol;
+ off = i.op[0].disps->X_add_number;
+
+ if (i.op[0].disps->X_op != O_constant
+ && i.op[0].disps->X_op != O_symbol)
+ {
+ /* Handle complex expressions. */
+ sym = make_expr_symbol (i.op[0].disps);
+ off = 0;
+ }
+
+ /* 1 possible extra opcode + 4 byte displacement go in var part.
+ Pass reloc in fr_var. */
+ frag_var (rs_machine_dependent, 5, i.reloc[0], subtype, sym, off, p);
+}
+
+static void
+output_jump ()
+{
+ char *p;
+ int size;
+ fixS *fixP;
+
+ if (i.tm.opcode_modifier & JumpByte)
+ {
+ /* This is a loop or jecxz type instruction. */
+ size = 1;
+ if (i.prefix[ADDR_PREFIX] != 0)
+ {
+ FRAG_APPEND_1_CHAR (ADDR_PREFIX_OPCODE);
+ i.prefixes -= 1;
+ }
+ /* Pentium4 branch hints. */
+ if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE /* not taken */
+ || i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE /* taken */)
+ {
+ FRAG_APPEND_1_CHAR (i.prefix[SEG_PREFIX]);
+ i.prefixes--;
+ }
+ }
+ else
+ {
+ int code16;
+
+ code16 = 0;
+ if (flag_code == CODE_16BIT)
+ code16 = CODE16;
+
+ if (i.prefix[DATA_PREFIX] != 0)
+ {
+ FRAG_APPEND_1_CHAR (DATA_PREFIX_OPCODE);
+ i.prefixes -= 1;
+ code16 ^= CODE16;
+ }
+
+ size = 4;
+ if (code16)
+ size = 2;
+ }
+
+ if (i.prefix[REX_PREFIX] != 0)
+ {
+ FRAG_APPEND_1_CHAR (i.prefix[REX_PREFIX]);
+ i.prefixes -= 1;
+ }
+
+ if (i.prefixes != 0 && !intel_syntax)
+ as_warn (_("skipping prefixes on this instruction"));
+
+ p = frag_more (1 + size);
+ *p++ = i.tm.base_opcode;
+
+ fixP = fix_new_exp (frag_now, p - frag_now->fr_literal, size,
+ i.op[0].disps, 1, reloc (size, 1, 1, i.reloc[0]));
+
+ /* All jumps handled here are signed, but don't use a signed limit
+ check for 32 and 16 bit jumps as we want to allow wrap around at
+ 4G and 64k respectively. */
+ if (size == 1)
+ fixP->fx_signed = 1;
+}
+
+static void
+output_interseg_jump ()
+{
+ char *p;
+ int size;
+ int prefix;
+ int code16;
+
+ code16 = 0;
+ if (flag_code == CODE_16BIT)
+ code16 = CODE16;
+
+ prefix = 0;
+ if (i.prefix[DATA_PREFIX] != 0)
+ {
+ prefix = 1;
+ i.prefixes -= 1;
+ code16 ^= CODE16;
+ }
+ if (i.prefix[REX_PREFIX] != 0)
+ {
+ prefix++;
+ i.prefixes -= 1;
+ }
+
+ size = 4;
+ if (code16)
+ size = 2;
+
+ if (i.prefixes != 0 && !intel_syntax)
+ as_warn (_("skipping prefixes on this instruction"));
+
+ /* 1 opcode; 2 segment; offset */
+ p = frag_more (prefix + 1 + 2 + size);
+
+ if (i.prefix[DATA_PREFIX] != 0)
+ *p++ = DATA_PREFIX_OPCODE;
+
+ if (i.prefix[REX_PREFIX] != 0)
+ *p++ = i.prefix[REX_PREFIX];
+
+ *p++ = i.tm.base_opcode;
+ if (i.op[1].imms->X_op == O_constant)
+ {
+ offsetT n = i.op[1].imms->X_add_number;
+
+ if (size == 2
+ && !fits_in_unsigned_word (n)
+ && !fits_in_signed_word (n))
+ {
+ as_bad (_("16-bit jump out of range"));
+ return;
+ }
+ md_number_to_chars (p, n, size);
+ }
+ else
+ fix_new_exp (frag_now, p - frag_now->fr_literal, size,
+ i.op[1].imms, 0, reloc (size, 0, 0, i.reloc[1]));
+ if (i.op[0].imms->X_op != O_constant)
+ as_bad (_("can't handle non absolute segment in `%s'"),
+ i.tm.name);
+ md_number_to_chars (p + size, (valueT) i.op[0].imms->X_add_number, 2);
+}
+
+static void
+output_insn ()
+{
+ fragS *insn_start_frag;
+ offsetT insn_start_off;
+
+ /* Tie dwarf2 debug info to the address at the start of the insn.
+ We can't do this after the insn has been output as the current
+ frag may have been closed off. eg. by frag_var. */
+ dwarf2_emit_insn (0);
+
+ insn_start_frag = frag_now;
+ insn_start_off = frag_now_fix ();
+
+ /* Output jumps. */
+ if (i.tm.opcode_modifier & Jump)
+ output_branch ();
+ else if (i.tm.opcode_modifier & (JumpByte | JumpDword))
+ output_jump ();
+ else if (i.tm.opcode_modifier & JumpInterSegment)
+ output_interseg_jump ();
+ else
+ {
+ /* Output normal instructions here. */
+ char *p;
+ unsigned char *q;
+
+ /* All opcodes on i386 have either 1 or 2 bytes, PadLock instructions
+ have 3 bytes. We may use one more higher byte to specify a prefix
+ the instruction requires. */
+ if ((i.tm.cpu_flags & CpuPadLock) != 0
+ && (i.tm.base_opcode & 0xff000000) != 0)
+ {
+ unsigned int prefix;
+ prefix = (i.tm.base_opcode >> 24) & 0xff;
+
+ if (prefix != REPE_PREFIX_OPCODE
+ || i.prefix[LOCKREP_PREFIX] != REPE_PREFIX_OPCODE)
+ add_prefix (prefix);
+ }
+ else
+ if ((i.tm.cpu_flags & CpuPadLock) == 0
+ && (i.tm.base_opcode & 0xff0000) != 0)
+ add_prefix ((i.tm.base_opcode >> 16) & 0xff);
+
+ /* The prefix bytes. */
+ for (q = i.prefix;
+ q < i.prefix + sizeof (i.prefix) / sizeof (i.prefix[0]);
+ q++)
+ {
+ if (*q)
+ {
+ p = frag_more (1);
+ md_number_to_chars (p, (valueT) *q, 1);
+ }
+ }
+
+ /* Now the opcode; be careful about word order here! */
+ if (fits_in_unsigned_byte (i.tm.base_opcode))
+ {
+ FRAG_APPEND_1_CHAR (i.tm.base_opcode);
+ }
+ else
+ {
+ if ((i.tm.cpu_flags & CpuPadLock) != 0)
+ {
+ p = frag_more (3);
+ *p++ = (i.tm.base_opcode >> 16) & 0xff;
+ }
+ else
+ p = frag_more (2);
+
+ /* Put out high byte first: can't use md_number_to_chars! */
+ *p++ = (i.tm.base_opcode >> 8) & 0xff;
+ *p = i.tm.base_opcode & 0xff;
+ }
+
+ /* Now the modrm byte and sib byte (if present). */
+ if (i.tm.opcode_modifier & Modrm)
+ {
+ p = frag_more (1);
+ md_number_to_chars (p,
+ (valueT) (i.rm.regmem << 0
+ | i.rm.reg << 3
+ | i.rm.mode << 6),
+ 1);
+ /* If i.rm.regmem == ESP (4)
+ && i.rm.mode != (Register mode)
+ && not 16 bit
+ ==> need second modrm byte. */
+ if (i.rm.regmem == ESCAPE_TO_TWO_BYTE_ADDRESSING
+ && i.rm.mode != 3
+ && !(i.base_reg && (i.base_reg->reg_type & Reg16) != 0))
+ {
+ p = frag_more (1);
+ md_number_to_chars (p,
+ (valueT) (i.sib.base << 0
+ | i.sib.index << 3
+ | i.sib.scale << 6),
+ 1);
+ }
+ }
+
+ if (i.disp_operands)
+ output_disp (insn_start_frag, insn_start_off);
+
+ if (i.imm_operands)
+ output_imm (insn_start_frag, insn_start_off);
+ }
+
+#ifdef DEBUG386
+ if (flag_debug)
+ {
+ pi (line, &i);
+ }
+#endif /* DEBUG386 */
+}
+
+static void
+output_disp (insn_start_frag, insn_start_off)
+ fragS *insn_start_frag;
+ offsetT insn_start_off;
+{
+ char *p;
+ unsigned int n;
+
+ for (n = 0; n < i.operands; n++)
+ {
+ if (i.types[n] & Disp)
+ {
+ if (i.op[n].disps->X_op == O_constant)
+ {
+ int size;
+ offsetT val;
+
+ size = 4;
+ if (i.types[n] & (Disp8 | Disp16 | Disp64))
+ {
+ size = 2;
+ if (i.types[n] & Disp8)
+ size = 1;
+ if (i.types[n] & Disp64)
+ size = 8;
+ }
+ val = offset_in_range (i.op[n].disps->X_add_number,
+ size);
+ p = frag_more (size);
+ md_number_to_chars (p, val, size);
+ }
+ else
+ {
+ enum bfd_reloc_code_real reloc_type;
+ int size = 4;
+ int sign = 0;
+ int pcrel = (i.flags[n] & Operand_PCrel) != 0;
+
+ /* The PC relative address is computed relative
+ to the instruction boundary, so in case immediate
+ fields follows, we need to adjust the value. */
+ if (pcrel && i.imm_operands)
+ {
+ int imm_size = 4;
+ unsigned int n1;
+
+ for (n1 = 0; n1 < i.operands; n1++)
+ if (i.types[n1] & Imm)
+ {
+ if (i.types[n1] & (Imm8 | Imm8S | Imm16 | Imm64))
+ {
+ imm_size = 2;
+ if (i.types[n1] & (Imm8 | Imm8S))
+ imm_size = 1;
+ if (i.types[n1] & Imm64)
+ imm_size = 8;
+ }
+ break;
+ }
+ /* We should find the immediate. */
+ if (n1 == i.operands)
+ abort ();
+ i.op[n].disps->X_add_number -= imm_size;
+ }
+
+ if (i.types[n] & Disp32S)
+ sign = 1;
+
+ if (i.types[n] & (Disp16 | Disp64))
+ {
+ size = 2;
+ if (i.types[n] & Disp64)
+ size = 8;
+ }
+
+ p = frag_more (size);
+ reloc_type = reloc (size, pcrel, sign, i.reloc[n]);
+ if (reloc_type == BFD_RELOC_32
+ && GOT_symbol
+ && GOT_symbol == i.op[n].disps->X_add_symbol
+ && (i.op[n].disps->X_op == O_symbol
+ || (i.op[n].disps->X_op == O_add
+ && ((symbol_get_value_expression
+ (i.op[n].disps->X_op_symbol)->X_op)
+ == O_subtract))))
+ {
+ offsetT add;
+
+ if (insn_start_frag == frag_now)
+ add = (p - frag_now->fr_literal) - insn_start_off;
+ else
+ {
+ fragS *fr;
+
+ add = insn_start_frag->fr_fix - insn_start_off;
+ for (fr = insn_start_frag->fr_next;
+ fr && fr != frag_now; fr = fr->fr_next)
+ add += fr->fr_fix;
+ add += p - frag_now->fr_literal;
+ }
+
+ /* We don't support dynamic linking on x86-64 yet. */
+ if (flag_code == CODE_64BIT)
+ abort ();
+ reloc_type = BFD_RELOC_386_GOTPC;
+ i.op[n].disps->X_add_number += add;
+ }
+ fix_new_exp (frag_now, p - frag_now->fr_literal, size,
+ i.op[n].disps, pcrel, reloc_type);
+ }
+ }
+ }
+}
+
+static void
+output_imm (insn_start_frag, insn_start_off)
+ fragS *insn_start_frag;
+ offsetT insn_start_off;
+{
+ char *p;
+ unsigned int n;
+
+ for (n = 0; n < i.operands; n++)
+ {
+ if (i.types[n] & Imm)
+ {
+ if (i.op[n].imms->X_op == O_constant)
+ {
+ int size;
+ offsetT val;
+
+ size = 4;
+ if (i.types[n] & (Imm8 | Imm8S | Imm16 | Imm64))
+ {
+ size = 2;
+ if (i.types[n] & (Imm8 | Imm8S))
+ size = 1;
+ else if (i.types[n] & Imm64)
+ size = 8;
+ }
+ val = offset_in_range (i.op[n].imms->X_add_number,
+ size);
+ p = frag_more (size);
+ md_number_to_chars (p, val, size);
+ }
+ else
+ {
+ /* Not absolute_section.
+ Need a 32-bit fixup (don't support 8bit
+ non-absolute imms). Try to support other
+ sizes ... */
+ enum bfd_reloc_code_real reloc_type;
+ int size = 4;
+ int sign = 0;
+
+ if ((i.types[n] & (Imm32S))
+ && i.suffix == QWORD_MNEM_SUFFIX)
+ sign = 1;
+ if (i.types[n] & (Imm8 | Imm8S | Imm16 | Imm64))
+ {
+ size = 2;
+ if (i.types[n] & (Imm8 | Imm8S))
+ size = 1;
+ if (i.types[n] & Imm64)
+ size = 8;
+ }
+
+ p = frag_more (size);
+ reloc_type = reloc (size, 0, sign, i.reloc[n]);
+
+ /* This is tough to explain. We end up with this one if we
+ * have operands that look like
+ * "_GLOBAL_OFFSET_TABLE_+[.-.L284]". The goal here is to
+ * obtain the absolute address of the GOT, and it is strongly
+ * preferable from a performance point of view to avoid using
+ * a runtime relocation for this. The actual sequence of
+ * instructions often look something like:
+ *
+ * call .L66
+ * .L66:
+ * popl %ebx
+ * addl $_GLOBAL_OFFSET_TABLE_+[.-.L66],%ebx
+ *
+ * The call and pop essentially return the absolute address
+ * of the label .L66 and store it in %ebx. The linker itself
+ * will ultimately change the first operand of the addl so
+ * that %ebx points to the GOT, but to keep things simple, the
+ * .o file must have this operand set so that it generates not
+ * the absolute address of .L66, but the absolute address of
+ * itself. This allows the linker itself simply treat a GOTPC
+ * relocation as asking for a pcrel offset to the GOT to be
+ * added in, and the addend of the relocation is stored in the
+ * operand field for the instruction itself.
+ *
+ * Our job here is to fix the operand so that it would add
+ * the correct offset so that %ebx would point to itself. The
+ * thing that is tricky is that .-.L66 will point to the
+ * beginning of the instruction, so we need to further modify
+ * the operand so that it will point to itself. There are
+ * other cases where you have something like:
+ *
+ * .long $_GLOBAL_OFFSET_TABLE_+[.-.L66]
+ *
+ * and here no correction would be required. Internally in
+ * the assembler we treat operands of this form as not being
+ * pcrel since the '.' is explicitly mentioned, and I wonder
+ * whether it would simplify matters to do it this way. Who
+ * knows. In earlier versions of the PIC patches, the
+ * pcrel_adjust field was used to store the correction, but
+ * since the expression is not pcrel, I felt it would be
+ * confusing to do it this way. */
+
+ if (reloc_type == BFD_RELOC_32
+ && GOT_symbol
+ && GOT_symbol == i.op[n].imms->X_add_symbol
+ && (i.op[n].imms->X_op == O_symbol
+ || (i.op[n].imms->X_op == O_add
+ && ((symbol_get_value_expression
+ (i.op[n].imms->X_op_symbol)->X_op)
+ == O_subtract))))
+ {
+ offsetT add;
+
+ if (insn_start_frag == frag_now)
+ add = (p - frag_now->fr_literal) - insn_start_off;
+ else
+ {
+ fragS *fr;
+
+ add = insn_start_frag->fr_fix - insn_start_off;
+ for (fr = insn_start_frag->fr_next;
+ fr && fr != frag_now; fr = fr->fr_next)
+ add += fr->fr_fix;
+ add += p - frag_now->fr_literal;
+ }
+
+ /* We don't support dynamic linking on x86-64 yet. */
+ if (flag_code == CODE_64BIT)
+ abort ();
+ reloc_type = BFD_RELOC_386_GOTPC;
+ i.op[n].imms->X_add_number += add;
+ }
+ fix_new_exp (frag_now, p - frag_now->fr_literal, size,
+ i.op[n].imms, 0, reloc_type);
+ }
+ }
+ }
+}
+
+#ifndef LEX_AT
+static char *lex_got PARAMS ((enum bfd_reloc_code_real *, int *));
+
+/* Parse operands of the form
+ <symbol>@GOTOFF+<nnn>
+ and similar .plt or .got references.
+
+ If we find one, set up the correct relocation in RELOC and copy the
+ input string, minus the `@GOTOFF' into a malloc'd buffer for
+ parsing by the calling routine. Return this buffer, and if ADJUST
+ is non-null set it to the length of the string we removed from the
+ input line. Otherwise return NULL. */
+static char *
+lex_got (reloc, adjust)
+ enum bfd_reloc_code_real *reloc;
+ int *adjust;
+{
+ static const char * const mode_name[NUM_FLAG_CODE] = { "32", "16", "64" };
+ static const struct {
+ const char *str;
+ const enum bfd_reloc_code_real rel[NUM_FLAG_CODE];
+ } gotrel[] = {
+ { "PLT", { BFD_RELOC_386_PLT32, 0, BFD_RELOC_X86_64_PLT32 } },
+ { "GOTOFF", { BFD_RELOC_386_GOTOFF, 0, 0 } },
+ { "GOTPCREL", { 0, 0, BFD_RELOC_X86_64_GOTPCREL } },
+ { "TLSGD", { BFD_RELOC_386_TLS_GD, 0, BFD_RELOC_X86_64_TLSGD } },
+ { "TLSLDM", { BFD_RELOC_386_TLS_LDM, 0, 0 } },
+ { "TLSLD", { 0, 0, BFD_RELOC_X86_64_TLSLD } },
+ { "GOTTPOFF", { BFD_RELOC_386_TLS_IE_32, 0, BFD_RELOC_X86_64_GOTTPOFF } },
+ { "TPOFF", { BFD_RELOC_386_TLS_LE_32, 0, BFD_RELOC_X86_64_TPOFF32 } },
+ { "NTPOFF", { BFD_RELOC_386_TLS_LE, 0, 0 } },
+ { "DTPOFF", { BFD_RELOC_386_TLS_LDO_32, 0, BFD_RELOC_X86_64_DTPOFF32 } },
+ { "GOTNTPOFF",{ BFD_RELOC_386_TLS_GOTIE, 0, 0 } },
+ { "INDNTPOFF",{ BFD_RELOC_386_TLS_IE, 0, 0 } },
+ { "GOT", { BFD_RELOC_386_GOT32, 0, BFD_RELOC_X86_64_GOT32 } }
+ };
+ char *cp;
+ unsigned int j;
+
+ for (cp = input_line_pointer; *cp != '@'; cp++)
+ if (is_end_of_line[(unsigned char) *cp])
+ return NULL;
+
+ for (j = 0; j < sizeof (gotrel) / sizeof (gotrel[0]); j++)
+ {
+ int len;
+
+ len = strlen (gotrel[j].str);
+ if (strncasecmp (cp + 1, gotrel[j].str, len) == 0)
+ {
+ if (gotrel[j].rel[(unsigned int) flag_code] != 0)
+ {
+ int first, second;
+ char *tmpbuf, *past_reloc;
+
+ *reloc = gotrel[j].rel[(unsigned int) flag_code];
+ if (adjust)
+ *adjust = len;
+
+ if (GOT_symbol == NULL)
+ GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
+
+ /* Replace the relocation token with ' ', so that
+ errors like foo@GOTOFF1 will be detected. */
+
+ /* The length of the first part of our input line. */
+ first = cp - input_line_pointer;
+
+ /* The second part goes from after the reloc token until
+ (and including) an end_of_line char. Don't use strlen
+ here as the end_of_line char may not be a NUL. */
+ past_reloc = cp + 1 + len;
+ for (cp = past_reloc; !is_end_of_line[(unsigned char) *cp++]; )
+ ;
+ second = cp - past_reloc;
+
+ /* Allocate and copy string. The trailing NUL shouldn't
+ be necessary, but be safe. */
+ tmpbuf = xmalloc (first + second + 2);
+ memcpy (tmpbuf, input_line_pointer, first);
+ tmpbuf[first] = ' ';
+ memcpy (tmpbuf + first + 1, past_reloc, second);
+ tmpbuf[first + second + 1] = '\0';
+ return tmpbuf;
+ }
+
+ as_bad (_("@%s reloc is not supported in %s bit mode"),
+ gotrel[j].str, mode_name[(unsigned int) flag_code]);
+ return NULL;
+ }
+ }
+
+ /* Might be a symbol version string. Don't as_bad here. */
+ return NULL;
+}
+
+/* x86_cons_fix_new is called via the expression parsing code when a
+ reloc is needed. We use this hook to get the correct .got reloc. */
+static enum bfd_reloc_code_real got_reloc = NO_RELOC;
+
+void
+x86_cons_fix_new (frag, off, len, exp)
+ fragS *frag;
+ unsigned int off;
+ unsigned int len;
+ expressionS *exp;
+{
+ enum bfd_reloc_code_real r = reloc (len, 0, 0, got_reloc);
+ got_reloc = NO_RELOC;
+ fix_new_exp (frag, off, len, exp, 0, r);
+}
+
+void
+x86_cons (exp, size)
+ expressionS *exp;
+ int size;
+{
+ if (size == 4)
+ {
+ /* Handle @GOTOFF and the like in an expression. */
+ char *save;
+ char *gotfree_input_line;
+ int adjust;
+
+ save = input_line_pointer;
+ gotfree_input_line = lex_got (&got_reloc, &adjust);
+ if (gotfree_input_line)
+ input_line_pointer = gotfree_input_line;
+
+ expression (exp);
+
+ if (gotfree_input_line)
+ {
+ /* expression () has merrily parsed up to the end of line,
+ or a comma - in the wrong buffer. Transfer how far
+ input_line_pointer has moved to the right buffer. */
+ input_line_pointer = (save
+ + (input_line_pointer - gotfree_input_line)
+ + adjust);
+ free (gotfree_input_line);
+ }
+ }
+ else
+ expression (exp);
+}
+#endif
+
+static int i386_immediate PARAMS ((char *));
+
+static int
+i386_immediate (imm_start)
+ char *imm_start;
+{
+ char *save_input_line_pointer;
+#ifndef LEX_AT
+ char *gotfree_input_line;
+#endif
+ segT exp_seg = 0;
+ expressionS *exp;
+
+ if (i.imm_operands == MAX_IMMEDIATE_OPERANDS)
+ {
+ as_bad (_("only 1 or 2 immediate operands are allowed"));
+ return 0;
+ }
+
+ exp = &im_expressions[i.imm_operands++];
+ i.op[this_operand].imms = exp;
+
+ if (is_space_char (*imm_start))
+ ++imm_start;
+
+ save_input_line_pointer = input_line_pointer;
+ input_line_pointer = imm_start;
+
+#ifndef LEX_AT
+ gotfree_input_line = lex_got (&i.reloc[this_operand], NULL);
+ if (gotfree_input_line)
+ input_line_pointer = gotfree_input_line;
+#endif
+
+ exp_seg = expression (exp);
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer)
+ as_bad (_("junk `%s' after expression"), input_line_pointer);
+
+ input_line_pointer = save_input_line_pointer;
+#ifndef LEX_AT
+ if (gotfree_input_line)
+ free (gotfree_input_line);
+#endif
+
+ if (exp->X_op == O_absent || exp->X_op == O_big)
+ {
+ /* Missing or bad expr becomes absolute 0. */
+ as_bad (_("missing or invalid immediate expression `%s' taken as 0"),
+ imm_start);
+ exp->X_op = O_constant;
+ exp->X_add_number = 0;
+ exp->X_add_symbol = (symbolS *) 0;
+ exp->X_op_symbol = (symbolS *) 0;
+ }
+ else if (exp->X_op == O_constant)
+ {
+ /* Size it properly later. */
+ i.types[this_operand] |= Imm64;
+ /* If BFD64, sign extend val. */
+ if (!use_rela_relocations)
+ if ((exp->X_add_number & ~(((addressT) 2 << 31) - 1)) == 0)
+ exp->X_add_number = (exp->X_add_number ^ ((addressT) 1 << 31)) - ((addressT) 1 << 31);
+ }
+#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
+ else if (OUTPUT_FLAVOR == bfd_target_aout_flavour
+ && exp_seg != absolute_section
+ && exp_seg != text_section
+ && exp_seg != data_section
+ && exp_seg != bss_section
+ && exp_seg != undefined_section
+ && !bfd_is_com_section (exp_seg))
+ {
+ as_bad (_("unimplemented segment %s in operand"), exp_seg->name);
+ return 0;
+ }
+#endif
+ else
+ {
+ /* This is an address. The size of the address will be
+ determined later, depending on destination register,
+ suffix, or the default for the section. */
+ i.types[this_operand] |= Imm8 | Imm16 | Imm32 | Imm32S | Imm64;
+ }
+
+ return 1;
+}
+
+static char *i386_scale PARAMS ((char *));
+
+static char *
+i386_scale (scale)
+ char *scale;
+{
+ offsetT val;
+ char *save = input_line_pointer;
+
+ input_line_pointer = scale;
+ val = get_absolute_expression ();
+
+ switch (val)
+ {
+ case 0:
+ case 1:
+ i.log2_scale_factor = 0;
+ break;
+ case 2:
+ i.log2_scale_factor = 1;
+ break;
+ case 4:
+ i.log2_scale_factor = 2;
+ break;
+ case 8:
+ i.log2_scale_factor = 3;
+ break;
+ default:
+ as_bad (_("expecting scale factor of 1, 2, 4, or 8: got `%s'"),
+ scale);
+ input_line_pointer = save;
+ return NULL;
+ }
+ if (i.log2_scale_factor != 0 && i.index_reg == 0)
+ {
+ as_warn (_("scale factor of %d without an index register"),
+ 1 << i.log2_scale_factor);
+#if SCALE1_WHEN_NO_INDEX
+ i.log2_scale_factor = 0;
+#endif
+ }
+ scale = input_line_pointer;
+ input_line_pointer = save;
+ return scale;
+}
+
+static int i386_displacement PARAMS ((char *, char *));
+
+static int
+i386_displacement (disp_start, disp_end)
+ char *disp_start;
+ char *disp_end;
+{
+ expressionS *exp;
+ segT exp_seg = 0;
+ char *save_input_line_pointer;
+#ifndef LEX_AT
+ char *gotfree_input_line;
+#endif
+ int bigdisp = Disp32;
+
+ if (flag_code == CODE_64BIT)
+ {
+ if (i.prefix[ADDR_PREFIX] == 0)
+ bigdisp = Disp64;
+ }
+ else if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0))
+ bigdisp = Disp16;
+ i.types[this_operand] |= bigdisp;
+
+ exp = &disp_expressions[i.disp_operands];
+ i.op[this_operand].disps = exp;
+ i.disp_operands++;
+ save_input_line_pointer = input_line_pointer;
+ input_line_pointer = disp_start;
+ END_STRING_AND_SAVE (disp_end);
+
+#ifndef GCC_ASM_O_HACK
+#define GCC_ASM_O_HACK 0
+#endif
+#if GCC_ASM_O_HACK
+ END_STRING_AND_SAVE (disp_end + 1);
+ if ((i.types[this_operand] & BaseIndex) != 0
+ && displacement_string_end[-1] == '+')
+ {
+ /* This hack is to avoid a warning when using the "o"
+ constraint within gcc asm statements.
+ For instance:
+
+ #define _set_tssldt_desc(n,addr,limit,type) \
+ __asm__ __volatile__ ( \
+ "movw %w2,%0\n\t" \
+ "movw %w1,2+%0\n\t" \
+ "rorl $16,%1\n\t" \
+ "movb %b1,4+%0\n\t" \
+ "movb %4,5+%0\n\t" \
+ "movb $0,6+%0\n\t" \
+ "movb %h1,7+%0\n\t" \
+ "rorl $16,%1" \
+ : "=o"(*(n)) : "q" (addr), "ri"(limit), "i"(type))
+
+ This works great except that the output assembler ends
+ up looking a bit weird if it turns out that there is
+ no offset. You end up producing code that looks like:
+
+ #APP
+ movw $235,(%eax)
+ movw %dx,2+(%eax)
+ rorl $16,%edx
+ movb %dl,4+(%eax)
+ movb $137,5+(%eax)
+ movb $0,6+(%eax)
+ movb %dh,7+(%eax)
+ rorl $16,%edx
+ #NO_APP
+
+ So here we provide the missing zero. */
+
+ *displacement_string_end = '0';
+ }
+#endif
+#ifndef LEX_AT
+ gotfree_input_line = lex_got (&i.reloc[this_operand], NULL);
+ if (gotfree_input_line)
+ input_line_pointer = gotfree_input_line;
+#endif
+
+ exp_seg = expression (exp);
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer)
+ as_bad (_("junk `%s' after expression"), input_line_pointer);
+#if GCC_ASM_O_HACK
+ RESTORE_END_STRING (disp_end + 1);
+#endif
+ RESTORE_END_STRING (disp_end);
+ input_line_pointer = save_input_line_pointer;
+#ifndef LEX_AT
+ if (gotfree_input_line)
+ free (gotfree_input_line);
+#endif
+
+ /* We do this to make sure that the section symbol is in
+ the symbol table. We will ultimately change the relocation
+ to be relative to the beginning of the section. */
+ if (i.reloc[this_operand] == BFD_RELOC_386_GOTOFF
+ || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL)
+ {
+ if (exp->X_op != O_symbol)
+ {
+ as_bad (_("bad expression used with @%s"),
+ (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL
+ ? "GOTPCREL"
+ : "GOTOFF"));
+ return 0;
+ }
+
+ if (S_IS_LOCAL (exp->X_add_symbol)
+ && S_GET_SEGMENT (exp->X_add_symbol) != undefined_section)
+ section_symbol (S_GET_SEGMENT (exp->X_add_symbol));
+ exp->X_op = O_subtract;
+ exp->X_op_symbol = GOT_symbol;
+ if (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL)
+ i.reloc[this_operand] = BFD_RELOC_32_PCREL;
+ else
+ i.reloc[this_operand] = BFD_RELOC_32;
+ }
+
+ if (exp->X_op == O_absent || exp->X_op == O_big)
+ {
+ /* Missing or bad expr becomes absolute 0. */
+ as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
+ disp_start);
+ exp->X_op = O_constant;
+ exp->X_add_number = 0;
+ exp->X_add_symbol = (symbolS *) 0;
+ exp->X_op_symbol = (symbolS *) 0;
+ }
+
+#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
+ if (exp->X_op != O_constant
+ && OUTPUT_FLAVOR == bfd_target_aout_flavour
+ && exp_seg != absolute_section
+ && exp_seg != text_section
+ && exp_seg != data_section
+ && exp_seg != bss_section
+ && exp_seg != undefined_section
+ && !bfd_is_com_section (exp_seg))
+ {
+ as_bad (_("unimplemented segment %s in operand"), exp_seg->name);
+ return 0;
+ }
+#endif
+ else if (flag_code == CODE_64BIT)
+ i.types[this_operand] |= Disp32S | Disp32;
+ return 1;
+}
+
+static int i386_index_check PARAMS ((const char *));
+
+/* Make sure the memory operand we've been dealt is valid.
+ Return 1 on success, 0 on a failure. */
+
+static int
+i386_index_check (operand_string)
+ const char *operand_string;
+{
+ int ok;
+#if INFER_ADDR_PREFIX
+ int fudged = 0;
+
+ tryprefix:
+#endif
+ ok = 1;
+ if (flag_code == CODE_64BIT)
+ {
+ if (i.prefix[ADDR_PREFIX] == 0)
+ {
+ /* 64bit checks. */
+ if ((i.base_reg
+ && ((i.base_reg->reg_type & Reg64) == 0)
+ && (i.base_reg->reg_type != BaseIndex
+ || i.index_reg))
+ || (i.index_reg
+ && ((i.index_reg->reg_type & (Reg64 | BaseIndex))
+ != (Reg64 | BaseIndex))))
+ ok = 0;
+ }
+ else
+ {
+ /* 32bit checks. */
+ if ((i.base_reg
+ && (i.base_reg->reg_type & (Reg32 | RegRex)) != Reg32)
+ || (i.index_reg
+ && ((i.index_reg->reg_type & (Reg32 | BaseIndex | RegRex))
+ != (Reg32 | BaseIndex))))
+ ok = 0;
+ }
+ }
+ else
+ {
+ if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0))
+ {
+ /* 16bit checks. */
+ if ((i.base_reg
+ && ((i.base_reg->reg_type & (Reg16 | BaseIndex | RegRex))
+ != (Reg16 | BaseIndex)))
+ || (i.index_reg
+ && (((i.index_reg->reg_type & (Reg16 | BaseIndex))
+ != (Reg16 | BaseIndex))
+ || !(i.base_reg
+ && i.base_reg->reg_num < 6
+ && i.index_reg->reg_num >= 6
+ && i.log2_scale_factor == 0))))
+ ok = 0;
+ }
+ else
+ {
+ /* 32bit checks. */
+ if ((i.base_reg
+ && (i.base_reg->reg_type & (Reg32 | RegRex)) != Reg32)
+ || (i.index_reg
+ && ((i.index_reg->reg_type & (Reg32 | BaseIndex | RegRex))
+ != (Reg32 | BaseIndex))))
+ ok = 0;
+ }
+ }
+ if (!ok)
+ {
+#if INFER_ADDR_PREFIX
+ if (flag_code != CODE_64BIT
+ && i.prefix[ADDR_PREFIX] == 0 && stackop_size != '\0')
+ {
+ i.prefix[ADDR_PREFIX] = ADDR_PREFIX_OPCODE;
+ i.prefixes += 1;
+ /* Change the size of any displacement too. At most one of
+ Disp16 or Disp32 is set.
+ FIXME. There doesn't seem to be any real need for separate
+ Disp16 and Disp32 flags. The same goes for Imm16 and Imm32.
+ Removing them would probably clean up the code quite a lot. */
+ if (i.types[this_operand] & (Disp16 | Disp32))
+ i.types[this_operand] ^= (Disp16 | Disp32);
+ fudged = 1;
+ goto tryprefix;
+ }
+ if (fudged)
+ as_bad (_("`%s' is not a valid base/index expression"),
+ operand_string);
+ else
+#endif
+ as_bad (_("`%s' is not a valid %s bit base/index expression"),
+ operand_string,
+ flag_code_names[flag_code]);
+ return 0;
+ }
+ return 1;
+}
+
+/* Parse OPERAND_STRING into the i386_insn structure I. Returns non-zero
+ on error. */
+
+static int
+i386_operand (operand_string)
+ char *operand_string;
+{
+ const reg_entry *r;
+ char *end_op;
+ char *op_string = operand_string;
+
+ if (is_space_char (*op_string))
+ ++op_string;
+
+ /* We check for an absolute prefix (differentiating,
+ for example, 'jmp pc_relative_label' from 'jmp *absolute_label'. */
+ if (*op_string == ABSOLUTE_PREFIX)
+ {
+ ++op_string;
+ if (is_space_char (*op_string))
+ ++op_string;
+ i.types[this_operand] |= JumpAbsolute;
+ }
+
+ /* Check if operand is a register. */
+ if ((*op_string == REGISTER_PREFIX || allow_naked_reg)
+ && (r = parse_register (op_string, &end_op)) != NULL)
+ {
+ /* Check for a segment override by searching for ':' after a
+ segment register. */
+ op_string = end_op;
+ if (is_space_char (*op_string))
+ ++op_string;
+ if (*op_string == ':' && (r->reg_type & (SReg2 | SReg3)))
+ {
+ switch (r->reg_num)
+ {
+ case 0:
+ i.seg[i.mem_operands] = &es;
+ break;
+ case 1:
+ i.seg[i.mem_operands] = &cs;
+ break;
+ case 2:
+ i.seg[i.mem_operands] = &ss;
+ break;
+ case 3:
+ i.seg[i.mem_operands] = &ds;
+ break;
+ case 4:
+ i.seg[i.mem_operands] = &fs;
+ break;
+ case 5:
+ i.seg[i.mem_operands] = &gs;
+ break;
+ }
+
+ /* Skip the ':' and whitespace. */
+ ++op_string;
+ if (is_space_char (*op_string))
+ ++op_string;
+
+ if (!is_digit_char (*op_string)
+ && !is_identifier_char (*op_string)
+ && *op_string != '('
+ && *op_string != ABSOLUTE_PREFIX)
+ {
+ as_bad (_("bad memory operand `%s'"), op_string);
+ return 0;
+ }
+ /* Handle case of %es:*foo. */
+ if (*op_string == ABSOLUTE_PREFIX)
+ {
+ ++op_string;
+ if (is_space_char (*op_string))
+ ++op_string;
+ i.types[this_operand] |= JumpAbsolute;
+ }
+ goto do_memory_reference;
+ }
+ if (*op_string)
+ {
+ as_bad (_("junk `%s' after register"), op_string);
+ return 0;
+ }
+ i.types[this_operand] |= r->reg_type & ~BaseIndex;
+ i.op[this_operand].regs = r;
+ i.reg_operands++;
+ }
+ else if (*op_string == REGISTER_PREFIX)
+ {
+ as_bad (_("bad register name `%s'"), op_string);
+ return 0;
+ }
+ else if (*op_string == IMMEDIATE_PREFIX)
+ {
+ ++op_string;
+ if (i.types[this_operand] & JumpAbsolute)
+ {
+ as_bad (_("immediate operand illegal with absolute jump"));
+ return 0;
+ }
+ if (!i386_immediate (op_string))
+ return 0;
+ }
+ else if (is_digit_char (*op_string)
+ || is_identifier_char (*op_string)
+ || *op_string == '(')
+ {
+ /* This is a memory reference of some sort. */
+ char *base_string;
+
+ /* Start and end of displacement string expression (if found). */
+ char *displacement_string_start;
+ char *displacement_string_end;
+
+ do_memory_reference:
+ if ((i.mem_operands == 1
+ && (current_templates->start->opcode_modifier & IsString) == 0)
+ || i.mem_operands == 2)
+ {
+ as_bad (_("too many memory references for `%s'"),
+ current_templates->start->name);
+ return 0;
+ }
+
+ /* Check for base index form. We detect the base index form by
+ looking for an ')' at the end of the operand, searching
+ for the '(' matching it, and finding a REGISTER_PREFIX or ','
+ after the '('. */
+ base_string = op_string + strlen (op_string);
+
+ --base_string;
+ if (is_space_char (*base_string))
+ --base_string;
+
+ /* If we only have a displacement, set-up for it to be parsed later. */
+ displacement_string_start = op_string;
+ displacement_string_end = base_string + 1;
+
+ if (*base_string == ')')
+ {
+ char *temp_string;
+ unsigned int parens_balanced = 1;
+ /* We've already checked that the number of left & right ()'s are
+ equal, so this loop will not be infinite. */
+ do
+ {
+ base_string--;
+ if (*base_string == ')')
+ parens_balanced++;
+ if (*base_string == '(')
+ parens_balanced--;
+ }
+ while (parens_balanced);
+
+ temp_string = base_string;
+
+ /* Skip past '(' and whitespace. */
+ ++base_string;
+ if (is_space_char (*base_string))
+ ++base_string;
+
+ if (*base_string == ','
+ || ((*base_string == REGISTER_PREFIX || allow_naked_reg)
+ && (i.base_reg = parse_register (base_string, &end_op)) != NULL))
+ {
+ displacement_string_end = temp_string;
+
+ i.types[this_operand] |= BaseIndex;
+
+ if (i.base_reg)
+ {
+ base_string = end_op;
+ if (is_space_char (*base_string))
+ ++base_string;
+ }
+
+ /* There may be an index reg or scale factor here. */
+ if (*base_string == ',')
+ {
+ ++base_string;
+ if (is_space_char (*base_string))
+ ++base_string;
+
+ if ((*base_string == REGISTER_PREFIX || allow_naked_reg)
+ && (i.index_reg = parse_register (base_string, &end_op)) != NULL)
+ {
+ base_string = end_op;
+ if (is_space_char (*base_string))
+ ++base_string;
+ if (*base_string == ',')
+ {
+ ++base_string;
+ if (is_space_char (*base_string))
+ ++base_string;
+ }
+ else if (*base_string != ')')
+ {
+ as_bad (_("expecting `,' or `)' after index register in `%s'"),
+ operand_string);
+ return 0;
+ }
+ }
+ else if (*base_string == REGISTER_PREFIX)
+ {
+ as_bad (_("bad register name `%s'"), base_string);
+ return 0;
+ }
+
+ /* Check for scale factor. */
+ if (*base_string != ')')
+ {
+ char *end_scale = i386_scale (base_string);
+
+ if (!end_scale)
+ return 0;
+
+ base_string = end_scale;
+ if (is_space_char (*base_string))
+ ++base_string;
+ if (*base_string != ')')
+ {
+ as_bad (_("expecting `)' after scale factor in `%s'"),
+ operand_string);
+ return 0;
+ }
+ }
+ else if (!i.index_reg)
+ {
+ as_bad (_("expecting index register or scale factor after `,'; got '%c'"),
+ *base_string);
+ return 0;
+ }
+ }
+ else if (*base_string != ')')
+ {
+ as_bad (_("expecting `,' or `)' after base register in `%s'"),
+ operand_string);
+ return 0;
+ }
+ }
+ else if (*base_string == REGISTER_PREFIX)
+ {
+ as_bad (_("bad register name `%s'"), base_string);
+ return 0;
+ }
+ }
+
+ /* If there's an expression beginning the operand, parse it,
+ assuming displacement_string_start and
+ displacement_string_end are meaningful. */
+ if (displacement_string_start != displacement_string_end)
+ {
+ if (!i386_displacement (displacement_string_start,
+ displacement_string_end))
+ return 0;
+ }
+
+ /* Special case for (%dx) while doing input/output op. */
+ if (i.base_reg
+ && i.base_reg->reg_type == (Reg16 | InOutPortReg)
+ && i.index_reg == 0
+ && i.log2_scale_factor == 0
+ && i.seg[i.mem_operands] == 0
+ && (i.types[this_operand] & Disp) == 0)
+ {
+ i.types[this_operand] = InOutPortReg;
+ return 1;
+ }
+
+ if (i386_index_check (operand_string) == 0)
+ return 0;
+ i.mem_operands++;
+ }
+ else
+ {
+ /* It's not a memory operand; argh! */
+ as_bad (_("invalid char %s beginning operand %d `%s'"),
+ output_invalid (*op_string),
+ this_operand + 1,
+ op_string);
+ return 0;
+ }
+ return 1; /* Normal return. */
+}
+
+/* md_estimate_size_before_relax()
+
+ Called just before relax() for rs_machine_dependent frags. The x86
+ assembler uses these frags to handle variable size jump
+ instructions.
+
+ Any symbol that is now undefined will not become defined.
+ Return the correct fr_subtype in the frag.
+ Return the initial "guess for variable size of frag" to caller.
+ The guess is actually the growth beyond the fixed part. Whatever
+ we do to grow the fixed or variable part contributes to our
+ returned value. */
+
+int
+md_estimate_size_before_relax (fragP, segment)
+ fragS *fragP;
+ segT segment;
+{
+ /* We've already got fragP->fr_subtype right; all we have to do is
+ check for un-relaxable symbols. On an ELF system, we can't relax
+ an externally visible symbol, because it may be overridden by a
+ shared library. */
+ if (S_GET_SEGMENT (fragP->fr_symbol) != segment
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+ || (OUTPUT_FLAVOR == bfd_target_elf_flavour
+ && (S_IS_EXTERNAL (fragP->fr_symbol)
+ || S_IS_WEAK (fragP->fr_symbol)))
+#endif
+ )
+ {
+ /* Symbol is undefined in this segment, or we need to keep a
+ reloc so that weak symbols can be overridden. */
+ int size = (fragP->fr_subtype & CODE16) ? 2 : 4;
+ enum bfd_reloc_code_real reloc_type;
+ unsigned char *opcode;
+ int old_fr_fix;
+
+ if (fragP->fr_var != NO_RELOC)
+ reloc_type = fragP->fr_var;
+ else if (size == 2)
+ reloc_type = BFD_RELOC_16_PCREL;
+ else
+ reloc_type = BFD_RELOC_32_PCREL;
+
+ old_fr_fix = fragP->fr_fix;
+ opcode = (unsigned char *) fragP->fr_opcode;
+
+ switch (TYPE_FROM_RELAX_STATE (fragP->fr_subtype))
+ {
+ case UNCOND_JUMP:
+ /* Make jmp (0xeb) a (d)word displacement jump. */
+ opcode[0] = 0xe9;
+ fragP->fr_fix += size;
+ fix_new (fragP, old_fr_fix, size,
+ fragP->fr_symbol,
+ fragP->fr_offset, 1,
+ reloc_type);
+ break;
+
+ case COND_JUMP86:
+ if (size == 2
+ && (!no_cond_jump_promotion || fragP->fr_var != NO_RELOC))
+ {
+ /* Negate the condition, and branch past an
+ unconditional jump. */
+ opcode[0] ^= 1;
+ opcode[1] = 3;
+ /* Insert an unconditional jump. */
+ opcode[2] = 0xe9;
+ /* We added two extra opcode bytes, and have a two byte
+ offset. */
+ fragP->fr_fix += 2 + 2;
+ fix_new (fragP, old_fr_fix + 2, 2,
+ fragP->fr_symbol,
+ fragP->fr_offset, 1,
+ reloc_type);
+ break;
+ }
+ /* Fall through. */
+
+ case COND_JUMP:
+ if (no_cond_jump_promotion && fragP->fr_var == NO_RELOC)
+ {
+ fixS *fixP;
+
+ fragP->fr_fix += 1;
+ fixP = fix_new (fragP, old_fr_fix, 1,
+ fragP->fr_symbol,
+ fragP->fr_offset, 1,
+ BFD_RELOC_8_PCREL);
+ fixP->fx_signed = 1;
+ break;
+ }
+
+ /* This changes the byte-displacement jump 0x7N
+ to the (d)word-displacement jump 0x0f,0x8N. */
+ opcode[1] = opcode[0] + 0x10;
+ opcode[0] = TWO_BYTE_OPCODE_ESCAPE;
+ /* We've added an opcode byte. */
+ fragP->fr_fix += 1 + size;
+ fix_new (fragP, old_fr_fix + 1, size,
+ fragP->fr_symbol,
+ fragP->fr_offset, 1,
+ reloc_type);
+ break;
+
+ default:
+ BAD_CASE (fragP->fr_subtype);
+ break;
+ }
+ frag_wane (fragP);
+ return fragP->fr_fix - old_fr_fix;
+ }
+
+ /* Guess size depending on current relax state. Initially the relax
+ state will correspond to a short jump and we return 1, because
+ the variable part of the frag (the branch offset) is one byte
+ long. However, we can relax a section more than once and in that
+ case we must either set fr_subtype back to the unrelaxed state,
+ or return the value for the appropriate branch. */
+ return md_relax_table[fragP->fr_subtype].rlx_length;
+}
+
+/* Called after relax() is finished.
+
+ In: Address of frag.
+ fr_type == rs_machine_dependent.
+ fr_subtype is what the address relaxed to.
+
+ Out: Any fixSs and constants are set up.
+ Caller will turn frag into a ".space 0". */
+
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ segT sec ATTRIBUTE_UNUSED;
+ fragS *fragP;
+{
+ unsigned char *opcode;
+ unsigned char *where_to_put_displacement = NULL;
+ offsetT target_address;
+ offsetT opcode_address;
+ unsigned int extension = 0;
+ offsetT displacement_from_opcode_start;
+
+ opcode = (unsigned char *) fragP->fr_opcode;
+
+ /* Address we want to reach in file space. */
+ target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
+
+ /* Address opcode resides at in file space. */
+ opcode_address = fragP->fr_address + fragP->fr_fix;
+
+ /* Displacement from opcode start to fill into instruction. */
+ displacement_from_opcode_start = target_address - opcode_address;
+
+ if ((fragP->fr_subtype & BIG) == 0)
+ {
+ /* Don't have to change opcode. */
+ extension = 1; /* 1 opcode + 1 displacement */
+ where_to_put_displacement = &opcode[1];
+ }
+ else
+ {
+ if (no_cond_jump_promotion
+ && TYPE_FROM_RELAX_STATE (fragP->fr_subtype) != UNCOND_JUMP)
+ as_warn_where (fragP->fr_file, fragP->fr_line, _("long jump required"));
+
+ switch (fragP->fr_subtype)
+ {
+ case ENCODE_RELAX_STATE (UNCOND_JUMP, BIG):
+ extension = 4; /* 1 opcode + 4 displacement */
+ opcode[0] = 0xe9;
+ where_to_put_displacement = &opcode[1];
+ break;
+
+ case ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16):
+ extension = 2; /* 1 opcode + 2 displacement */
+ opcode[0] = 0xe9;
+ where_to_put_displacement = &opcode[1];
+ break;
+
+ case ENCODE_RELAX_STATE (COND_JUMP, BIG):
+ case ENCODE_RELAX_STATE (COND_JUMP86, BIG):
+ extension = 5; /* 2 opcode + 4 displacement */
+ opcode[1] = opcode[0] + 0x10;
+ opcode[0] = TWO_BYTE_OPCODE_ESCAPE;
+ where_to_put_displacement = &opcode[2];
+ break;
+
+ case ENCODE_RELAX_STATE (COND_JUMP, BIG16):
+ extension = 3; /* 2 opcode + 2 displacement */
+ opcode[1] = opcode[0] + 0x10;
+ opcode[0] = TWO_BYTE_OPCODE_ESCAPE;
+ where_to_put_displacement = &opcode[2];
+ break;
+
+ case ENCODE_RELAX_STATE (COND_JUMP86, BIG16):
+ extension = 4;
+ opcode[0] ^= 1;
+ opcode[1] = 3;
+ opcode[2] = 0xe9;
+ where_to_put_displacement = &opcode[3];
+ break;
+
+ default:
+ BAD_CASE (fragP->fr_subtype);
+ break;
+ }
+ }
+
+ /* Now put displacement after opcode. */
+ md_number_to_chars ((char *) where_to_put_displacement,
+ (valueT) (displacement_from_opcode_start - extension),
+ DISP_SIZE_FROM_RELAX_STATE (fragP->fr_subtype));
+ fragP->fr_fix += extension;
+}
+
+/* Size of byte displacement jmp. */
+int md_short_jump_size = 2;
+
+/* Size of dword displacement jmp. */
+int md_long_jump_size = 5;
+
+/* Size of relocation record. */
+const int md_reloc_size = 8;
+
+void
+md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ addressT from_addr, to_addr;
+ fragS *frag ATTRIBUTE_UNUSED;
+ symbolS *to_symbol ATTRIBUTE_UNUSED;
+{
+ offsetT offset;
+
+ offset = to_addr - (from_addr + 2);
+ /* Opcode for byte-disp jump. */
+ md_number_to_chars (ptr, (valueT) 0xeb, 1);
+ md_number_to_chars (ptr + 1, (valueT) offset, 1);
+}
+
+void
+md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ addressT from_addr, to_addr;
+ fragS *frag ATTRIBUTE_UNUSED;
+ symbolS *to_symbol ATTRIBUTE_UNUSED;
+{
+ offsetT offset;
+
+ offset = to_addr - (from_addr + 5);
+ md_number_to_chars (ptr, (valueT) 0xe9, 1);
+ md_number_to_chars (ptr + 1, (valueT) offset, 4);
+}
+
+/* Apply a fixup (fixS) to segment data, once it has been determined
+ by our caller that we have all the info we need to fix it up.
+
+ On the 386, immediates, displacements, and data pointers are all in
+ the same (little-endian) format, so we don't need to care about which
+ we are handling. */
+
+void
+md_apply_fix3 (fixP, valP, seg)
+ /* The fix we're to put in. */
+ fixS *fixP;
+ /* Pointer to the value of the bits. */
+ valueT *valP;
+ /* Segment fix is from. */
+ segT seg ATTRIBUTE_UNUSED;
+{
+ char *p = fixP->fx_where + fixP->fx_frag->fr_literal;
+ valueT value = *valP;
+
+#if !defined (TE_Mach)
+ if (fixP->fx_pcrel)
+ {
+ switch (fixP->fx_r_type)
+ {
+ default:
+ break;
+
+ case BFD_RELOC_32:
+ fixP->fx_r_type = BFD_RELOC_32_PCREL;
+ break;
+ case BFD_RELOC_16:
+ fixP->fx_r_type = BFD_RELOC_16_PCREL;
+ break;
+ case BFD_RELOC_8:
+ fixP->fx_r_type = BFD_RELOC_8_PCREL;
+ break;
+ }
+ }
+
+ if (fixP->fx_addsy != NULL
+ && (fixP->fx_r_type == BFD_RELOC_32_PCREL
+ || fixP->fx_r_type == BFD_RELOC_16_PCREL
+ || fixP->fx_r_type == BFD_RELOC_8_PCREL)
+ && !use_rela_relocations)
+ {
+ /* This is a hack. There should be a better way to handle this.
+ This covers for the fact that bfd_install_relocation will
+ subtract the current location (for partial_inplace, PC relative
+ relocations); see more below. */
+#ifndef OBJ_AOUT
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour
+#ifdef TE_PE
+ || OUTPUT_FLAVOR == bfd_target_coff_flavour
+#endif
+ )
+ value += fixP->fx_where + fixP->fx_frag->fr_address;
+#endif
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ {
+ segT sym_seg = S_GET_SEGMENT (fixP->fx_addsy);
+
+ if ((sym_seg == seg
+ || (symbol_section_p (fixP->fx_addsy)
+ && sym_seg != absolute_section))
+ && !generic_force_reloc (fixP))
+ {
+ /* Yes, we add the values in twice. This is because
+ bfd_install_relocation subtracts them out again. I think
+ bfd_install_relocation is broken, but I don't dare change
+ it. FIXME. */
+ value += fixP->fx_where + fixP->fx_frag->fr_address;
+ }
+ }
+#endif
+#if defined (OBJ_COFF) && defined (TE_PE)
+ /* For some reason, the PE format does not store a section
+ address offset for a PC relative symbol. */
+ if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
+ value += md_pcrel_from (fixP);
+#endif
+ }
+
+ /* Fix a few things - the dynamic linker expects certain values here,
+ and we must not disappoint it. */
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour
+ && fixP->fx_addsy)
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_386_PLT32:
+ case BFD_RELOC_X86_64_PLT32:
+ /* Make the jump instruction point to the address of the operand. At
+ runtime we merely add the offset to the actual PLT entry. */
+ value = -4;
+ break;
+
+ case BFD_RELOC_386_TLS_GD:
+ case BFD_RELOC_386_TLS_LDM:
+ case BFD_RELOC_386_TLS_IE_32:
+ case BFD_RELOC_386_TLS_IE:
+ case BFD_RELOC_386_TLS_GOTIE:
+ case BFD_RELOC_X86_64_TLSGD:
+ case BFD_RELOC_X86_64_TLSLD:
+ case BFD_RELOC_X86_64_GOTTPOFF:
+ value = 0; /* Fully resolved at runtime. No addend. */
+ /* Fallthrough */
+ case BFD_RELOC_386_TLS_LE:
+ case BFD_RELOC_386_TLS_LDO_32:
+ case BFD_RELOC_386_TLS_LE_32:
+ case BFD_RELOC_X86_64_DTPOFF32:
+ case BFD_RELOC_X86_64_TPOFF32:
+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
+ break;
+
+ case BFD_RELOC_386_GOT32:
+ case BFD_RELOC_X86_64_GOT32:
+ value = 0; /* Fully resolved at runtime. No addend. */
+ break;
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixP->fx_done = 0;
+ return;
+
+ default:
+ break;
+ }
+#endif /* defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) */
+ *valP = value;
+#endif /* !defined (TE_Mach) */
+
+ /* Are we finished with this relocation now? */
+ if (fixP->fx_addsy == NULL)
+ fixP->fx_done = 1;
+ else if (use_rela_relocations)
+ {
+ fixP->fx_no_overflow = 1;
+ /* Remember value for tc_gen_reloc. */
+ fixP->fx_addnumber = value;
+ value = 0;
+ }
+
+ md_number_to_chars (p, value, fixP->fx_size);
+}
+
+#define MAX_LITTLENUMS 6
+
+/* Turn the string pointed to by litP into a floating point constant
+ of type TYPE, and emit the appropriate bytes. The number of
+ LITTLENUMS emitted is stored in *SIZEP. An error message is
+ returned, or NULL on OK. */
+
+char *
+md_atof (type, litP, sizeP)
+ int type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 5;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to md_atof ()");
+ }
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+ /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
+ the bigendian 386. */
+ for (wordP = words + prec - 1; prec--;)
+ {
+ md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ return 0;
+}
+
+char output_invalid_buf[8];
+
+static char *
+output_invalid (c)
+ int c;
+{
+ if (ISPRINT (c))
+ sprintf (output_invalid_buf, "'%c'", c);
+ else
+ sprintf (output_invalid_buf, "(0x%x)", (unsigned) c);
+ return output_invalid_buf;
+}
+
+/* REG_STRING starts *before* REGISTER_PREFIX. */
+
+static const reg_entry *
+parse_register (reg_string, end_op)
+ char *reg_string;
+ char **end_op;
+{
+ char *s = reg_string;
+ char *p;
+ char reg_name_given[MAX_REG_NAME_SIZE + 1];
+ const reg_entry *r;
+
+ /* Skip possible REGISTER_PREFIX and possible whitespace. */
+ if (*s == REGISTER_PREFIX)
+ ++s;
+
+ if (is_space_char (*s))
+ ++s;
+
+ p = reg_name_given;
+ while ((*p++ = register_chars[(unsigned char) *s]) != '\0')
+ {
+ if (p >= reg_name_given + MAX_REG_NAME_SIZE)
+ return (const reg_entry *) NULL;
+ s++;
+ }
+
+ /* For naked regs, make sure that we are not dealing with an identifier.
+ This prevents confusing an identifier like `eax_var' with register
+ `eax'. */
+ if (allow_naked_reg && identifier_chars[(unsigned char) *s])
+ return (const reg_entry *) NULL;
+
+ *end_op = s;
+
+ r = (const reg_entry *) hash_find (reg_hash, reg_name_given);
+
+ /* Handle floating point regs, allowing spaces in the (i) part. */
+ if (r == i386_regtab /* %st is first entry of table */)
+ {
+ if (is_space_char (*s))
+ ++s;
+ if (*s == '(')
+ {
+ ++s;
+ if (is_space_char (*s))
+ ++s;
+ if (*s >= '0' && *s <= '7')
+ {
+ r = &i386_float_regtab[*s - '0'];
+ ++s;
+ if (is_space_char (*s))
+ ++s;
+ if (*s == ')')
+ {
+ *end_op = s + 1;
+ return r;
+ }
+ }
+ /* We have "%st(" then garbage. */
+ return (const reg_entry *) NULL;
+ }
+ }
+
+ if (r != NULL
+ && (r->reg_flags & (RegRex64 | RegRex)) != 0
+ && flag_code != CODE_64BIT)
+ {
+ return (const reg_entry *) NULL;
+ }
+
+ return r;
+}
+
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+const char *md_shortopts = "kVQ:sqn";
+#else
+const char *md_shortopts = "qn";
+#endif
+
+struct option md_longopts[] = {
+#define OPTION_32 (OPTION_MD_BASE + 0)
+ {"32", no_argument, NULL, OPTION_32},
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+#define OPTION_64 (OPTION_MD_BASE + 1)
+ {"64", no_argument, NULL, OPTION_64},
+#endif
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof (md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg ATTRIBUTE_UNUSED;
+{
+ switch (c)
+ {
+ case 'n':
+ optimize_align_code = 0;
+ break;
+
+ case 'q':
+ quiet_warnings = 1;
+ break;
+
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+ /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
+ should be emitted or not. FIXME: Not implemented. */
+ case 'Q':
+ break;
+
+ /* -V: SVR4 argument to print version ID. */
+ case 'V':
+ print_version_id ();
+ break;
+
+ /* -k: Ignore for FreeBSD compatibility. */
+ case 'k':
+ break;
+
+ case 's':
+ /* -s: On i386 Solaris, this tells the native assembler to use
+ .stab instead of .stab.excl. We always use .stab anyhow. */
+ break;
+
+ case OPTION_64:
+ {
+ const char **list, **l;
+
+ list = bfd_target_list ();
+ for (l = list; *l != NULL; l++)
+ if (strcmp (*l, "elf64-x86-64") == 0)
+ {
+ default_arch = "x86_64";
+ break;
+ }
+ if (*l == NULL)
+ as_fatal (_("No compiled in support for x86_64"));
+ free (list);
+ }
+ break;
+#endif
+
+ case OPTION_32:
+ default_arch = "i386";
+ break;
+
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+ fprintf (stream, _("\
+ -Q ignored\n\
+ -V print assembler version number\n\
+ -k ignored\n\
+ -n Do not optimize code alignment\n\
+ -q quieten some warnings\n\
+ -s ignored\n"));
+#else
+ fprintf (stream, _("\
+ -n Do not optimize code alignment\n\
+ -q quieten some warnings\n"));
+#endif
+}
+
+#if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \
+ || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF))
+
+/* Pick the target format to use. */
+
+const char *
+i386_target_format ()
+{
+ if (!strcmp (default_arch, "x86_64"))
+ set_code_flag (CODE_64BIT);
+ else if (!strcmp (default_arch, "i386"))
+ set_code_flag (CODE_32BIT);
+ else
+ as_fatal (_("Unknown architecture"));
+ switch (OUTPUT_FLAVOR)
+ {
+#ifdef OBJ_MAYBE_AOUT
+ case bfd_target_aout_flavour:
+ return AOUT_TARGET_FORMAT;
+#endif
+#ifdef OBJ_MAYBE_COFF
+ case bfd_target_coff_flavour:
+ return "coff-i386";
+#endif
+#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
+ case bfd_target_elf_flavour:
+ {
+ if (flag_code == CODE_64BIT)
+ use_rela_relocations = 1;
+ return flag_code == CODE_64BIT ? "elf64-x86-64" : ELF_TARGET_FORMAT;
+ }
+#endif
+ default:
+ abort ();
+ return NULL;
+ }
+}
+
+#endif /* OBJ_MAYBE_ more than one */
+
+#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF))
+void i386_elf_emit_arch_note ()
+{
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour
+ && cpu_arch_name != NULL)
+ {
+ char *p;
+ asection *seg = now_seg;
+ subsegT subseg = now_subseg;
+ Elf_Internal_Note i_note;
+ Elf_External_Note e_note;
+ asection *note_secp;
+ int len;
+
+ /* Create the .note section. */
+ note_secp = subseg_new (".note", 0);
+ bfd_set_section_flags (stdoutput,
+ note_secp,
+ SEC_HAS_CONTENTS | SEC_READONLY);
+
+ /* Process the arch string. */
+ len = strlen (cpu_arch_name);
+
+ i_note.namesz = len + 1;
+ i_note.descsz = 0;
+ i_note.type = NT_ARCH;
+ p = frag_more (sizeof (e_note.namesz));
+ md_number_to_chars (p, (valueT) i_note.namesz, sizeof (e_note.namesz));
+ p = frag_more (sizeof (e_note.descsz));
+ md_number_to_chars (p, (valueT) i_note.descsz, sizeof (e_note.descsz));
+ p = frag_more (sizeof (e_note.type));
+ md_number_to_chars (p, (valueT) i_note.type, sizeof (e_note.type));
+ p = frag_more (len + 1);
+ strcpy (p, cpu_arch_name);
+
+ frag_align (2, 0, 0);
+
+ subseg_set (seg, subseg);
+ }
+}
+#endif
+
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ if (name[0] == GLOBAL_OFFSET_TABLE_NAME[0]
+ && name[1] == GLOBAL_OFFSET_TABLE_NAME[1]
+ && name[2] == GLOBAL_OFFSET_TABLE_NAME[2]
+ && strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0)
+ {
+ if (!GOT_symbol)
+ {
+ if (symbol_find (name))
+ as_bad (_("GOT already in symbol table"));
+ GOT_symbol = symbol_new (name, undefined_section,
+ (valueT) 0, &zero_address_frag);
+ };
+ return GOT_symbol;
+ }
+ return 0;
+}
+
+/* Round up a section size to the appropriate boundary. */
+
+valueT
+md_section_align (segment, size)
+ segT segment ATTRIBUTE_UNUSED;
+ valueT size;
+{
+#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
+ if (OUTPUT_FLAVOR == bfd_target_aout_flavour)
+ {
+ /* For a.out, force the section size to be aligned. If we don't do
+ this, BFD will align it for us, but it will not write out the
+ final bytes of the section. This may be a bug in BFD, but it is
+ easier to fix it here since that is how the other a.out targets
+ work. */
+ int align;
+
+ align = bfd_get_section_alignment (stdoutput, segment);
+ size = ((size + (1 << align) - 1) & ((valueT) -1 << align));
+ }
+#endif
+
+ return size;
+}
+
+/* On the i386, PC-relative offsets are relative to the start of the
+ next instruction. That is, the address of the offset, plus its
+ size, since the offset is always the last part of the insn. */
+
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
+}
+
+#ifndef I386COFF
+
+static void
+s_bss (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ int temp;
+
+ temp = get_absolute_expression ();
+ subseg_set (bss_section, (subsegT) temp);
+ demand_empty_rest_of_line ();
+}
+
+#endif
+
+void
+i386_validate_fix (fixp)
+ fixS *fixp;
+{
+ if (fixp->fx_subsy && fixp->fx_subsy == GOT_symbol)
+ {
+ /* GOTOFF relocation are nonsense in 64bit mode. */
+ if (fixp->fx_r_type == BFD_RELOC_32_PCREL)
+ {
+ if (flag_code != CODE_64BIT)
+ abort ();
+ fixp->fx_r_type = BFD_RELOC_X86_64_GOTPCREL;
+ }
+ else
+ {
+ if (flag_code == CODE_64BIT)
+ abort ();
+ fixp->fx_r_type = BFD_RELOC_386_GOTOFF;
+ }
+ fixp->fx_subsy = 0;
+ }
+}
+
+arelent *
+tc_gen_reloc (section, fixp)
+ asection *section ATTRIBUTE_UNUSED;
+ fixS *fixp;
+{
+ arelent *rel;
+ bfd_reloc_code_real_type code;
+
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_X86_64_PLT32:
+ case BFD_RELOC_X86_64_GOT32:
+ case BFD_RELOC_X86_64_GOTPCREL:
+ case BFD_RELOC_386_PLT32:
+ case BFD_RELOC_386_GOT32:
+ case BFD_RELOC_386_GOTOFF:
+ case BFD_RELOC_386_GOTPC:
+ case BFD_RELOC_386_TLS_GD:
+ case BFD_RELOC_386_TLS_LDM:
+ case BFD_RELOC_386_TLS_LDO_32:
+ case BFD_RELOC_386_TLS_IE_32:
+ case BFD_RELOC_386_TLS_IE:
+ case BFD_RELOC_386_TLS_GOTIE:
+ case BFD_RELOC_386_TLS_LE_32:
+ case BFD_RELOC_386_TLS_LE:
+ case BFD_RELOC_X86_64_32S:
+ case BFD_RELOC_X86_64_TLSGD:
+ case BFD_RELOC_X86_64_TLSLD:
+ case BFD_RELOC_X86_64_DTPOFF32:
+ case BFD_RELOC_X86_64_GOTTPOFF:
+ case BFD_RELOC_X86_64_TPOFF32:
+ case BFD_RELOC_RVA:
+ case BFD_RELOC_VTABLE_ENTRY:
+ case BFD_RELOC_VTABLE_INHERIT:
+ code = fixp->fx_r_type;
+ break;
+ default:
+ if (fixp->fx_pcrel)
+ {
+ switch (fixp->fx_size)
+ {
+ default:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("can not do %d byte pc-relative relocation"),
+ fixp->fx_size);
+ code = BFD_RELOC_32_PCREL;
+ break;
+ case 1: code = BFD_RELOC_8_PCREL; break;
+ case 2: code = BFD_RELOC_16_PCREL; break;
+ case 4: code = BFD_RELOC_32_PCREL; break;
+ }
+ }
+ else
+ {
+ switch (fixp->fx_size)
+ {
+ default:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("can not do %d byte relocation"),
+ fixp->fx_size);
+ code = BFD_RELOC_32;
+ break;
+ case 1: code = BFD_RELOC_8; break;
+ case 2: code = BFD_RELOC_16; break;
+ case 4: code = BFD_RELOC_32; break;
+#ifdef BFD64
+ case 8: code = BFD_RELOC_64; break;
+#endif
+ }
+ }
+ break;
+ }
+
+ if (code == BFD_RELOC_32
+ && GOT_symbol
+ && fixp->fx_addsy == GOT_symbol)
+ {
+ /* We don't support GOTPC on 64bit targets. */
+ if (flag_code == CODE_64BIT)
+ abort ();
+ code = BFD_RELOC_386_GOTPC;
+ }
+
+ rel = (arelent *) xmalloc (sizeof (arelent));
+ rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+
+ rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ if (!use_rela_relocations)
+ {
+ /* HACK: Since i386 ELF uses Rel instead of Rela, encode the
+ vtable entry to be used in the relocation's section offset. */
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ rel->address = fixp->fx_offset;
+
+ rel->addend = 0;
+ }
+ /* Use the rela in 64bit mode. */
+ else
+ {
+ if (!fixp->fx_pcrel)
+ rel->addend = fixp->fx_offset;
+ else
+ switch (code)
+ {
+ case BFD_RELOC_X86_64_PLT32:
+ case BFD_RELOC_X86_64_GOT32:
+ case BFD_RELOC_X86_64_GOTPCREL:
+ case BFD_RELOC_X86_64_TLSGD:
+ case BFD_RELOC_X86_64_TLSLD:
+ case BFD_RELOC_X86_64_GOTTPOFF:
+ rel->addend = fixp->fx_offset - fixp->fx_size;
+ break;
+ default:
+ rel->addend = (section->vma
+ - fixp->fx_size
+ + fixp->fx_addnumber
+ + md_pcrel_from (fixp));
+ break;
+ }
+ }
+
+ rel->howto = bfd_reloc_type_lookup (stdoutput, code);
+ if (rel->howto == NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("cannot represent relocation type %s"),
+ bfd_get_reloc_code_name (code));
+ /* Set howto to a garbage value so that we can keep going. */
+ rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
+ assert (rel->howto != NULL);
+ }
+
+ return rel;
+}
+
+
+/* Parse operands using Intel syntax. This implements a recursive descent
+ parser based on the BNF grammar published in Appendix B of the MASM 6.1
+ Programmer's Guide.
+
+ FIXME: We do not recognize the full operand grammar defined in the MASM
+ documentation. In particular, all the structure/union and
+ high-level macro operands are missing.
+
+ Uppercase words are terminals, lower case words are non-terminals.
+ Objects surrounded by double brackets '[[' ']]' are optional. Vertical
+ bars '|' denote choices. Most grammar productions are implemented in
+ functions called 'intel_<production>'.
+
+ Initial production is 'expr'.
+
+ addOp + | -
+
+ alpha [a-zA-Z]
+
+ byteRegister AL | AH | BL | BH | CL | CH | DL | DH
+
+ constant digits [[ radixOverride ]]
+
+ dataType BYTE | WORD | DWORD | QWORD | XWORD
+
+ digits decdigit
+ | digits decdigit
+ | digits hexdigit
+
+ decdigit [0-9]
+
+ e05 e05 addOp e06
+ | e06
+
+ e06 e06 mulOp e09
+ | e09
+
+ e09 OFFSET e10
+ | e09 PTR e10
+ | e09 : e10
+ | e10
+
+ e10 e10 [ expr ]
+ | e11
+
+ e11 ( expr )
+ | [ expr ]
+ | constant
+ | dataType
+ | id
+ | $
+ | register
+
+ => expr SHORT e05
+ | e05
+
+ gpRegister AX | EAX | BX | EBX | CX | ECX | DX | EDX
+ | BP | EBP | SP | ESP | DI | EDI | SI | ESI
+
+ hexdigit a | b | c | d | e | f
+ | A | B | C | D | E | F
+
+ id alpha
+ | id alpha
+ | id decdigit
+
+ mulOp * | / | MOD
+
+ quote " | '
+
+ register specialRegister
+ | gpRegister
+ | byteRegister
+
+ segmentRegister CS | DS | ES | FS | GS | SS
+
+ specialRegister CR0 | CR2 | CR3
+ | DR0 | DR1 | DR2 | DR3 | DR6 | DR7
+ | TR3 | TR4 | TR5 | TR6 | TR7
+
+ We simplify the grammar in obvious places (e.g., register parsing is
+ done by calling parse_register) and eliminate immediate left recursion
+ to implement a recursive-descent parser.
+
+ expr SHORT e05
+ | e05
+
+ e05 e06 e05'
+
+ e05' addOp e06 e05'
+ | Empty
+
+ e06 e09 e06'
+
+ e06' mulOp e09 e06'
+ | Empty
+
+ e09 OFFSET e10 e09'
+ | e10 e09'
+
+ e09' PTR e10 e09'
+ | : e10 e09'
+ | Empty
+
+ e10 e11 e10'
+
+ e10' [ expr ] e10'
+ | Empty
+
+ e11 ( expr )
+ | [ expr ]
+ | BYTE
+ | WORD
+ | DWORD
+ | QWORD
+ | XWORD
+ | .
+ | $
+ | register
+ | id
+ | constant */
+
+/* Parsing structure for the intel syntax parser. Used to implement the
+ semantic actions for the operand grammar. */
+struct intel_parser_s
+ {
+ char *op_string; /* The string being parsed. */
+ int got_a_float; /* Whether the operand is a float. */
+ int op_modifier; /* Operand modifier. */
+ int is_mem; /* 1 if operand is memory reference. */
+ const reg_entry *reg; /* Last register reference found. */
+ char *disp; /* Displacement string being built. */
+ };
+
+static struct intel_parser_s intel_parser;
+
+/* Token structure for parsing intel syntax. */
+struct intel_token
+ {
+ int code; /* Token code. */
+ const reg_entry *reg; /* Register entry for register tokens. */
+ char *str; /* String representation. */
+ };
+
+static struct intel_token cur_token, prev_token;
+
+/* Token codes for the intel parser. Since T_SHORT is already used
+ by COFF, undefine it first to prevent a warning. */
+#define T_NIL -1
+#define T_CONST 1
+#define T_REG 2
+#define T_BYTE 3
+#define T_WORD 4
+#define T_DWORD 5
+#define T_QWORD 6
+#define T_XWORD 7
+#undef T_SHORT
+#define T_SHORT 8
+#define T_OFFSET 9
+#define T_PTR 10
+#define T_ID 11
+
+/* Prototypes for intel parser functions. */
+static int intel_match_token PARAMS ((int code));
+static void intel_get_token PARAMS ((void));
+static void intel_putback_token PARAMS ((void));
+static int intel_expr PARAMS ((void));
+static int intel_e05 PARAMS ((void));
+static int intel_e05_1 PARAMS ((void));
+static int intel_e06 PARAMS ((void));
+static int intel_e06_1 PARAMS ((void));
+static int intel_e09 PARAMS ((void));
+static int intel_e09_1 PARAMS ((void));
+static int intel_e10 PARAMS ((void));
+static int intel_e10_1 PARAMS ((void));
+static int intel_e11 PARAMS ((void));
+
+static int
+i386_intel_operand (operand_string, got_a_float)
+ char *operand_string;
+ int got_a_float;
+{
+ int ret;
+ char *p;
+
+ /* Initialize token holders. */
+ cur_token.code = prev_token.code = T_NIL;
+ cur_token.reg = prev_token.reg = NULL;
+ cur_token.str = prev_token.str = NULL;
+
+ /* Initialize parser structure. */
+ p = intel_parser.op_string = (char *) malloc (strlen (operand_string) + 1);
+ if (p == NULL)
+ abort ();
+ strcpy (intel_parser.op_string, operand_string);
+ intel_parser.got_a_float = got_a_float;
+ intel_parser.op_modifier = -1;
+ intel_parser.is_mem = 0;
+ intel_parser.reg = NULL;
+ intel_parser.disp = (char *) malloc (strlen (operand_string) + 1);
+ if (intel_parser.disp == NULL)
+ abort ();
+ intel_parser.disp[0] = '\0';
+
+ /* Read the first token and start the parser. */
+ intel_get_token ();
+ ret = intel_expr ();
+
+ if (ret)
+ {
+ /* If we found a memory reference, hand it over to i386_displacement
+ to fill in the rest of the operand fields. */
+ if (intel_parser.is_mem)
+ {
+ if ((i.mem_operands == 1
+ && (current_templates->start->opcode_modifier & IsString) == 0)
+ || i.mem_operands == 2)
+ {
+ as_bad (_("too many memory references for '%s'"),
+ current_templates->start->name);
+ ret = 0;
+ }
+ else
+ {
+ char *s = intel_parser.disp;
+ i.mem_operands++;
+
+ /* Add the displacement expression. */
+ if (*s != '\0')
+ ret = i386_displacement (s, s + strlen (s));
+ if (ret)
+ ret = i386_index_check (operand_string);
+ }
+ }
+
+ /* Constant and OFFSET expressions are handled by i386_immediate. */
+ else if (intel_parser.op_modifier == OFFSET_FLAT
+ || intel_parser.reg == NULL)
+ ret = i386_immediate (intel_parser.disp);
+ }
+
+ free (p);
+ free (intel_parser.disp);
+
+ return ret;
+}
+
+/* expr SHORT e05
+ | e05 */
+static int
+intel_expr ()
+{
+ /* expr SHORT e05 */
+ if (cur_token.code == T_SHORT)
+ {
+ intel_parser.op_modifier = SHORT;
+ intel_match_token (T_SHORT);
+
+ return (intel_e05 ());
+ }
+
+ /* expr e05 */
+ else
+ return intel_e05 ();
+}
+
+/* e05 e06 e05'
+
+ e05' addOp e06 e05'
+ | Empty */
+static int
+intel_e05 ()
+{
+ return (intel_e06 () && intel_e05_1 ());
+}
+
+static int
+intel_e05_1 ()
+{
+ /* e05' addOp e06 e05' */
+ if (cur_token.code == '+' || cur_token.code == '-')
+ {
+ strcat (intel_parser.disp, cur_token.str);
+ intel_match_token (cur_token.code);
+
+ return (intel_e06 () && intel_e05_1 ());
+ }
+
+ /* e05' Empty */
+ else
+ return 1;
+}
+
+/* e06 e09 e06'
+
+ e06' mulOp e09 e06'
+ | Empty */
+static int
+intel_e06 ()
+{
+ return (intel_e09 () && intel_e06_1 ());
+}
+
+static int
+intel_e06_1 ()
+{
+ /* e06' mulOp e09 e06' */
+ if (cur_token.code == '*' || cur_token.code == '/')
+ {
+ strcat (intel_parser.disp, cur_token.str);
+ intel_match_token (cur_token.code);
+
+ return (intel_e09 () && intel_e06_1 ());
+ }
+
+ /* e06' Empty */
+ else
+ return 1;
+}
+
+/* e09 OFFSET e10 e09'
+ | e10 e09'
+
+ e09' PTR e10 e09'
+ | : e10 e09'
+ | Empty */
+static int
+intel_e09 ()
+{
+ /* e09 OFFSET e10 e09' */
+ if (cur_token.code == T_OFFSET)
+ {
+ intel_parser.is_mem = 0;
+ intel_parser.op_modifier = OFFSET_FLAT;
+ intel_match_token (T_OFFSET);
+
+ return (intel_e10 () && intel_e09_1 ());
+ }
+
+ /* e09 e10 e09' */
+ else
+ return (intel_e10 () && intel_e09_1 ());
+}
+
+static int
+intel_e09_1 ()
+{
+ /* e09' PTR e10 e09' */
+ if (cur_token.code == T_PTR)
+ {
+ if (prev_token.code == T_BYTE)
+ i.suffix = BYTE_MNEM_SUFFIX;
+
+ else if (prev_token.code == T_WORD)
+ {
+ if (intel_parser.got_a_float == 2) /* "fi..." */
+ i.suffix = SHORT_MNEM_SUFFIX;
+ else
+ i.suffix = WORD_MNEM_SUFFIX;
+ }
+
+ else if (prev_token.code == T_DWORD)
+ {
+ if (intel_parser.got_a_float == 1) /* "f..." */
+ i.suffix = SHORT_MNEM_SUFFIX;
+ else
+ i.suffix = LONG_MNEM_SUFFIX;
+ }
+
+ else if (prev_token.code == T_QWORD)
+ {
+ if (intel_parser.got_a_float == 1) /* "f..." */
+ i.suffix = LONG_MNEM_SUFFIX;
+ else
+ i.suffix = QWORD_MNEM_SUFFIX;
+ }
+
+ else if (prev_token.code == T_XWORD)
+ i.suffix = LONG_DOUBLE_MNEM_SUFFIX;
+
+ else
+ {
+ as_bad (_("Unknown operand modifier `%s'\n"), prev_token.str);
+ return 0;
+ }
+
+ intel_match_token (T_PTR);
+
+ return (intel_e10 () && intel_e09_1 ());
+ }
+
+ /* e09 : e10 e09' */
+ else if (cur_token.code == ':')
+ {
+ /* Mark as a memory operand only if it's not already known to be an
+ offset expression. */
+ if (intel_parser.op_modifier != OFFSET_FLAT)
+ intel_parser.is_mem = 1;
+
+ return (intel_match_token (':') && intel_e10 () && intel_e09_1 ());
+ }
+
+ /* e09' Empty */
+ else
+ return 1;
+}
+
+/* e10 e11 e10'
+
+ e10' [ expr ] e10'
+ | Empty */
+static int
+intel_e10 ()
+{
+ return (intel_e11 () && intel_e10_1 ());
+}
+
+static int
+intel_e10_1 ()
+{
+ /* e10' [ expr ] e10' */
+ if (cur_token.code == '[')
+ {
+ intel_match_token ('[');
+
+ /* Mark as a memory operand only if it's not already known to be an
+ offset expression. If it's an offset expression, we need to keep
+ the brace in. */
+ if (intel_parser.op_modifier != OFFSET_FLAT)
+ intel_parser.is_mem = 1;
+ else
+ strcat (intel_parser.disp, "[");
+
+ /* Add a '+' to the displacement string if necessary. */
+ if (*intel_parser.disp != '\0'
+ && *(intel_parser.disp + strlen (intel_parser.disp) - 1) != '+')
+ strcat (intel_parser.disp, "+");
+
+ if (intel_expr () && intel_match_token (']'))
+ {
+ /* Preserve brackets when the operand is an offset expression. */
+ if (intel_parser.op_modifier == OFFSET_FLAT)
+ strcat (intel_parser.disp, "]");
+
+ return intel_e10_1 ();
+ }
+ else
+ return 0;
+ }
+
+ /* e10' Empty */
+ else
+ return 1;
+}
+
+/* e11 ( expr )
+ | [ expr ]
+ | BYTE
+ | WORD
+ | DWORD
+ | QWORD
+ | XWORD
+ | $
+ | .
+ | register
+ | id
+ | constant */
+static int
+intel_e11 ()
+{
+ /* e11 ( expr ) */
+ if (cur_token.code == '(')
+ {
+ intel_match_token ('(');
+ strcat (intel_parser.disp, "(");
+
+ if (intel_expr () && intel_match_token (')'))
+ {
+ strcat (intel_parser.disp, ")");
+ return 1;
+ }
+ else
+ return 0;
+ }
+
+ /* e11 [ expr ] */
+ else if (cur_token.code == '[')
+ {
+ intel_match_token ('[');
+
+ /* Mark as a memory operand only if it's not already known to be an
+ offset expression. If it's an offset expression, we need to keep
+ the brace in. */
+ if (intel_parser.op_modifier != OFFSET_FLAT)
+ intel_parser.is_mem = 1;
+ else
+ strcat (intel_parser.disp, "[");
+
+ /* Operands for jump/call inside brackets denote absolute addresses. */
+ if (current_templates->start->opcode_modifier & Jump
+ || current_templates->start->opcode_modifier & JumpDword
+ || current_templates->start->opcode_modifier & JumpByte
+ || current_templates->start->opcode_modifier & JumpInterSegment)
+ i.types[this_operand] |= JumpAbsolute;
+
+ /* Add a '+' to the displacement string if necessary. */
+ if (*intel_parser.disp != '\0'
+ && *(intel_parser.disp + strlen (intel_parser.disp) - 1) != '+')
+ strcat (intel_parser.disp, "+");
+
+ if (intel_expr () && intel_match_token (']'))
+ {
+ /* Preserve brackets when the operand is an offset expression. */
+ if (intel_parser.op_modifier == OFFSET_FLAT)
+ strcat (intel_parser.disp, "]");
+
+ return 1;
+ }
+ else
+ return 0;
+ }
+
+ /* e11 BYTE
+ | WORD
+ | DWORD
+ | QWORD
+ | XWORD */
+ else if (cur_token.code == T_BYTE
+ || cur_token.code == T_WORD
+ || cur_token.code == T_DWORD
+ || cur_token.code == T_QWORD
+ || cur_token.code == T_XWORD)
+ {
+ intel_match_token (cur_token.code);
+
+ return 1;
+ }
+
+ /* e11 $
+ | . */
+ else if (cur_token.code == '$' || cur_token.code == '.')
+ {
+ strcat (intel_parser.disp, cur_token.str);
+ intel_match_token (cur_token.code);
+
+ /* Mark as a memory operand only if it's not already known to be an
+ offset expression. */
+ if (intel_parser.op_modifier != OFFSET_FLAT)
+ intel_parser.is_mem = 1;
+
+ return 1;
+ }
+
+ /* e11 register */
+ else if (cur_token.code == T_REG)
+ {
+ const reg_entry *reg = intel_parser.reg = cur_token.reg;
+
+ intel_match_token (T_REG);
+
+ /* Check for segment change. */
+ if (cur_token.code == ':')
+ {
+ if (reg->reg_type & (SReg2 | SReg3))
+ {
+ switch (reg->reg_num)
+ {
+ case 0:
+ i.seg[i.mem_operands] = &es;
+ break;
+ case 1:
+ i.seg[i.mem_operands] = &cs;
+ break;
+ case 2:
+ i.seg[i.mem_operands] = &ss;
+ break;
+ case 3:
+ i.seg[i.mem_operands] = &ds;
+ break;
+ case 4:
+ i.seg[i.mem_operands] = &fs;
+ break;
+ case 5:
+ i.seg[i.mem_operands] = &gs;
+ break;
+ }
+ }
+ else
+ {
+ as_bad (_("`%s' is not a valid segment register"), reg->reg_name);
+ return 0;
+ }
+ }
+
+ /* Not a segment register. Check for register scaling. */
+ else if (cur_token.code == '*')
+ {
+ if (!intel_parser.is_mem)
+ {
+ as_bad (_("Register scaling only allowed in memory operands."));
+ return 0;
+ }
+
+ /* What follows must be a valid scale. */
+ if (intel_match_token ('*')
+ && strchr ("01248", *cur_token.str))
+ {
+ i.index_reg = reg;
+ i.types[this_operand] |= BaseIndex;
+
+ /* Set the scale after setting the register (otherwise,
+ i386_scale will complain) */
+ i386_scale (cur_token.str);
+ intel_match_token (T_CONST);
+ }
+ else
+ {
+ as_bad (_("expecting scale factor of 1, 2, 4, or 8: got `%s'"),
+ cur_token.str);
+ return 0;
+ }
+ }
+
+ /* No scaling. If this is a memory operand, the register is either a
+ base register (first occurrence) or an index register (second
+ occurrence). */
+ else if (intel_parser.is_mem && !(reg->reg_type & (SReg2 | SReg3)))
+ {
+ if (i.base_reg && i.index_reg)
+ {
+ as_bad (_("Too many register references in memory operand.\n"));
+ return 0;
+ }
+
+ if (i.base_reg == NULL)
+ i.base_reg = reg;
+ else
+ i.index_reg = reg;
+
+ i.types[this_operand] |= BaseIndex;
+ }
+
+ /* Offset modifier. Add the register to the displacement string to be
+ parsed as an immediate expression after we're done. */
+ else if (intel_parser.op_modifier == OFFSET_FLAT)
+ strcat (intel_parser.disp, reg->reg_name);
+
+ /* It's neither base nor index nor offset. */
+ else
+ {
+ i.types[this_operand] |= reg->reg_type & ~BaseIndex;
+ i.op[this_operand].regs = reg;
+ i.reg_operands++;
+ }
+
+ /* Since registers are not part of the displacement string (except
+ when we're parsing offset operands), we may need to remove any
+ preceding '+' from the displacement string. */
+ if (*intel_parser.disp != '\0'
+ && intel_parser.op_modifier != OFFSET_FLAT)
+ {
+ char *s = intel_parser.disp;
+ s += strlen (s) - 1;
+ if (*s == '+')
+ *s = '\0';
+ }
+
+ return 1;
+ }
+
+ /* e11 id */
+ else if (cur_token.code == T_ID)
+ {
+ /* Add the identifier to the displacement string. */
+ strcat (intel_parser.disp, cur_token.str);
+ intel_match_token (T_ID);
+
+ /* The identifier represents a memory reference only if it's not
+ preceded by an offset modifier. */
+ if (intel_parser.op_modifier != OFFSET_FLAT)
+ intel_parser.is_mem = 1;
+
+ return 1;
+ }
+
+ /* e11 constant */
+ else if (cur_token.code == T_CONST
+ || cur_token.code == '-'
+ || cur_token.code == '+')
+ {
+ char *save_str;
+
+ /* Allow constants that start with `+' or `-'. */
+ if (cur_token.code == '-' || cur_token.code == '+')
+ {
+ strcat (intel_parser.disp, cur_token.str);
+ intel_match_token (cur_token.code);
+ if (cur_token.code != T_CONST)
+ {
+ as_bad (_("Syntax error. Expecting a constant. Got `%s'.\n"),
+ cur_token.str);
+ return 0;
+ }
+ }
+
+ save_str = (char *) malloc (strlen (cur_token.str) + 1);
+ if (save_str == NULL)
+ abort ();
+ strcpy (save_str, cur_token.str);
+
+ /* Get the next token to check for register scaling. */
+ intel_match_token (cur_token.code);
+
+ /* Check if this constant is a scaling factor for an index register. */
+ if (cur_token.code == '*')
+ {
+ if (intel_match_token ('*') && cur_token.code == T_REG)
+ {
+ if (!intel_parser.is_mem)
+ {
+ as_bad (_("Register scaling only allowed in memory operands."));
+ return 0;
+ }
+
+ /* The constant is followed by `* reg', so it must be
+ a valid scale. */
+ if (strchr ("01248", *save_str))
+ {
+ i.index_reg = cur_token.reg;
+ i.types[this_operand] |= BaseIndex;
+
+ /* Set the scale after setting the register (otherwise,
+ i386_scale will complain) */
+ i386_scale (save_str);
+ intel_match_token (T_REG);
+
+ /* Since registers are not part of the displacement
+ string, we may need to remove any preceding '+' from
+ the displacement string. */
+ if (*intel_parser.disp != '\0')
+ {
+ char *s = intel_parser.disp;
+ s += strlen (s) - 1;
+ if (*s == '+')
+ *s = '\0';
+ }
+
+ free (save_str);
+
+ return 1;
+ }
+ else
+ return 0;
+ }
+
+ /* The constant was not used for register scaling. Since we have
+ already consumed the token following `*' we now need to put it
+ back in the stream. */
+ else
+ intel_putback_token ();
+ }
+
+ /* Add the constant to the displacement string. */
+ strcat (intel_parser.disp, save_str);
+ free (save_str);
+
+ return 1;
+ }
+
+ as_bad (_("Unrecognized token '%s'"), cur_token.str);
+ return 0;
+}
+
+/* Match the given token against cur_token. If they match, read the next
+ token from the operand string. */
+static int
+intel_match_token (code)
+ int code;
+{
+ if (cur_token.code == code)
+ {
+ intel_get_token ();
+ return 1;
+ }
+ else
+ {
+ as_bad (_("Unexpected token `%s'\n"), cur_token.str);
+ return 0;
+ }
+}
+
+/* Read a new token from intel_parser.op_string and store it in cur_token. */
+static void
+intel_get_token ()
+{
+ char *end_op;
+ const reg_entry *reg;
+ struct intel_token new_token;
+
+ new_token.code = T_NIL;
+ new_token.reg = NULL;
+ new_token.str = NULL;
+
+ /* Free the memory allocated to the previous token and move
+ cur_token to prev_token. */
+ if (prev_token.str)
+ free (prev_token.str);
+
+ prev_token = cur_token;
+
+ /* Skip whitespace. */
+ while (is_space_char (*intel_parser.op_string))
+ intel_parser.op_string++;
+
+ /* Return an empty token if we find nothing else on the line. */
+ if (*intel_parser.op_string == '\0')
+ {
+ cur_token = new_token;
+ return;
+ }
+
+ /* The new token cannot be larger than the remainder of the operand
+ string. */
+ new_token.str = (char *) malloc (strlen (intel_parser.op_string) + 1);
+ if (new_token.str == NULL)
+ abort ();
+ new_token.str[0] = '\0';
+
+ if (strchr ("0123456789", *intel_parser.op_string))
+ {
+ char *p = new_token.str;
+ char *q = intel_parser.op_string;
+ new_token.code = T_CONST;
+
+ /* Allow any kind of identifier char to encompass floating point and
+ hexadecimal numbers. */
+ while (is_identifier_char (*q))
+ *p++ = *q++;
+ *p = '\0';
+
+ /* Recognize special symbol names [0-9][bf]. */
+ if (strlen (intel_parser.op_string) == 2
+ && (intel_parser.op_string[1] == 'b'
+ || intel_parser.op_string[1] == 'f'))
+ new_token.code = T_ID;
+ }
+
+ else if (strchr ("+-/*:[]()", *intel_parser.op_string))
+ {
+ new_token.code = *intel_parser.op_string;
+ new_token.str[0] = *intel_parser.op_string;
+ new_token.str[1] = '\0';
+ }
+
+ else if ((*intel_parser.op_string == REGISTER_PREFIX || allow_naked_reg)
+ && ((reg = parse_register (intel_parser.op_string, &end_op)) != NULL))
+ {
+ new_token.code = T_REG;
+ new_token.reg = reg;
+
+ if (*intel_parser.op_string == REGISTER_PREFIX)
+ {
+ new_token.str[0] = REGISTER_PREFIX;
+ new_token.str[1] = '\0';
+ }
+
+ strcat (new_token.str, reg->reg_name);
+ }
+
+ else if (is_identifier_char (*intel_parser.op_string))
+ {
+ char *p = new_token.str;
+ char *q = intel_parser.op_string;
+
+ /* A '.' or '$' followed by an identifier char is an identifier.
+ Otherwise, it's operator '.' followed by an expression. */
+ if ((*q == '.' || *q == '$') && !is_identifier_char (*(q + 1)))
+ {
+ new_token.code = *q;
+ new_token.str[0] = *q;
+ new_token.str[1] = '\0';
+ }
+ else
+ {
+ while (is_identifier_char (*q) || *q == '@')
+ *p++ = *q++;
+ *p = '\0';
+
+ if (strcasecmp (new_token.str, "BYTE") == 0)
+ new_token.code = T_BYTE;
+
+ else if (strcasecmp (new_token.str, "WORD") == 0)
+ new_token.code = T_WORD;
+
+ else if (strcasecmp (new_token.str, "DWORD") == 0)
+ new_token.code = T_DWORD;
+
+ else if (strcasecmp (new_token.str, "QWORD") == 0)
+ new_token.code = T_QWORD;
+
+ else if (strcasecmp (new_token.str, "XWORD") == 0)
+ new_token.code = T_XWORD;
+
+ else if (strcasecmp (new_token.str, "PTR") == 0)
+ new_token.code = T_PTR;
+
+ else if (strcasecmp (new_token.str, "SHORT") == 0)
+ new_token.code = T_SHORT;
+
+ else if (strcasecmp (new_token.str, "OFFSET") == 0)
+ {
+ new_token.code = T_OFFSET;
+
+ /* ??? This is not mentioned in the MASM grammar but gcc
+ makes use of it with -mintel-syntax. OFFSET may be
+ followed by FLAT: */
+ if (strncasecmp (q, " FLAT:", 6) == 0)
+ strcat (new_token.str, " FLAT:");
+ }
+
+ /* ??? This is not mentioned in the MASM grammar. */
+ else if (strcasecmp (new_token.str, "FLAT") == 0)
+ new_token.code = T_OFFSET;
+
+ else
+ new_token.code = T_ID;
+ }
+ }
+
+ else
+ as_bad (_("Unrecognized token `%s'\n"), intel_parser.op_string);
+
+ intel_parser.op_string += strlen (new_token.str);
+ cur_token = new_token;
+}
+
+/* Put cur_token back into the token stream and make cur_token point to
+ prev_token. */
+static void
+intel_putback_token ()
+{
+ intel_parser.op_string -= strlen (cur_token.str);
+ free (cur_token.str);
+ cur_token = prev_token;
+
+ /* Forget prev_token. */
+ prev_token.code = T_NIL;
+ prev_token.reg = NULL;
+ prev_token.str = NULL;
+}
+
+int
+tc_x86_regname_to_dw2regnum (const char *regname)
+{
+ unsigned int regnum;
+ unsigned int regnames_count;
+ char *regnames_32[] =
+ {
+ "eax", "ecx", "edx", "ebx",
+ "esp", "ebp", "esi", "edi",
+ "eip"
+ };
+ char *regnames_64[] =
+ {
+ "rax", "rbx", "rcx", "rdx",
+ "rdi", "rsi", "rbp", "rsp",
+ "r8", "r9", "r10", "r11",
+ "r12", "r13", "r14", "r15",
+ "rip"
+ };
+ char **regnames;
+
+ if (flag_code == CODE_64BIT)
+ {
+ regnames = regnames_64;
+ regnames_count = ARRAY_SIZE (regnames_64);
+ }
+ else
+ {
+ regnames = regnames_32;
+ regnames_count = ARRAY_SIZE (regnames_32);
+ }
+
+ for (regnum = 0; regnum < regnames_count; regnum++)
+ if (strcmp (regname, regnames[regnum]) == 0)
+ return regnum;
+
+ return -1;
+}
+
+void
+tc_x86_frame_initial_instructions (void)
+{
+ static unsigned int sp_regno;
+
+ if (!sp_regno)
+ sp_regno = tc_x86_regname_to_dw2regnum (flag_code == CODE_64BIT
+ ? "rsp" : "esp");
+
+ cfi_add_CFA_def_cfa (sp_regno, -x86_cie_data_alignment);
+ cfi_add_CFA_offset (x86_dwarf2_return_column, x86_cie_data_alignment);
+}
diff --git a/x/binutils/gas/config/tc-i386.h b/x/binutils/gas/config/tc-i386.h
new file mode 100644
index 0000000..14b522b
--- /dev/null
+++ b/x/binutils/gas/config/tc-i386.h
@@ -0,0 +1,503 @@
+/* tc-i386.h -- Header file for tc-i386.c
+ Copyright 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef TC_I386
+#define TC_I386 1
+
+#ifndef BFD_ASSEMBLER
+#error So, do you know what you are doing?
+#endif
+
+#ifdef ANSI_PROTOTYPES
+struct fix;
+#endif
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#ifdef TE_LYNX
+#define TARGET_FORMAT "coff-i386-lynx"
+#endif
+
+#define TARGET_ARCH bfd_arch_i386
+#define TARGET_MACH (i386_mach ())
+extern unsigned long i386_mach PARAMS ((void));
+
+#ifdef TE_FreeBSD
+#define AOUT_TARGET_FORMAT "a.out-i386-freebsd"
+#endif
+#ifdef TE_NetBSD
+#define AOUT_TARGET_FORMAT "a.out-i386-netbsd"
+#endif
+#ifdef TE_386BSD
+#define AOUT_TARGET_FORMAT "a.out-i386-bsd"
+#endif
+#ifdef TE_LINUX
+#define AOUT_TARGET_FORMAT "a.out-i386-linux"
+#endif
+#ifdef TE_Mach
+#define AOUT_TARGET_FORMAT "a.out-mach3"
+#endif
+#ifdef TE_DYNIX
+#define AOUT_TARGET_FORMAT "a.out-i386-dynix"
+#endif
+#ifndef AOUT_TARGET_FORMAT
+#define AOUT_TARGET_FORMAT "a.out-i386"
+#endif
+
+#ifdef TE_FreeBSD
+#define ELF_TARGET_FORMAT "elf32-i386-freebsd"
+#endif
+#ifndef ELF_TARGET_FORMAT
+#define ELF_TARGET_FORMAT "elf32-i386"
+#endif
+
+#if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \
+ || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF))
+extern const char *i386_target_format PARAMS ((void));
+#define TARGET_FORMAT i386_target_format ()
+#else
+#ifdef OBJ_ELF
+#define TARGET_FORMAT ELF_TARGET_FORMAT
+#endif
+#ifdef OBJ_AOUT
+#define TARGET_FORMAT AOUT_TARGET_FORMAT
+#endif
+#endif
+
+#if (defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF))
+#define md_end i386_elf_emit_arch_note
+extern void i386_elf_emit_arch_note PARAMS ((void));
+#endif
+
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
+
+#define LOCAL_LABELS_FB 1
+
+extern const char extra_symbol_chars[];
+#define tc_symbol_chars extra_symbol_chars
+
+#define MAX_OPERANDS 3 /* max operands per insn */
+#define MAX_IMMEDIATE_OPERANDS 2/* max immediates per insn (lcall, ljmp) */
+#define MAX_MEMORY_OPERANDS 2 /* max memory refs per insn (string ops) */
+
+/* Prefixes will be emitted in the order defined below.
+ WAIT_PREFIX must be the first prefix since FWAIT is really is an
+ instruction, and so must come before any prefixes. */
+#define WAIT_PREFIX 0
+#define LOCKREP_PREFIX 1
+#define ADDR_PREFIX 2
+#define DATA_PREFIX 3
+#define SEG_PREFIX 4
+#define REX_PREFIX 5 /* must come last. */
+#define MAX_PREFIXES 6 /* max prefixes per opcode */
+
+/* we define the syntax here (modulo base,index,scale syntax) */
+#define REGISTER_PREFIX '%'
+#define IMMEDIATE_PREFIX '$'
+#define ABSOLUTE_PREFIX '*'
+
+#define TWO_BYTE_OPCODE_ESCAPE 0x0f
+#define NOP_OPCODE (char) 0x90
+
+/* register numbers */
+#define EBP_REG_NUM 5
+#define ESP_REG_NUM 4
+
+/* modrm_byte.regmem for twobyte escape */
+#define ESCAPE_TO_TWO_BYTE_ADDRESSING ESP_REG_NUM
+/* index_base_byte.index for no index register addressing */
+#define NO_INDEX_REGISTER ESP_REG_NUM
+/* index_base_byte.base for no base register addressing */
+#define NO_BASE_REGISTER EBP_REG_NUM
+#define NO_BASE_REGISTER_16 6
+
+/* these are the instruction mnemonic suffixes. */
+#define WORD_MNEM_SUFFIX 'w'
+#define BYTE_MNEM_SUFFIX 'b'
+#define SHORT_MNEM_SUFFIX 's'
+#define LONG_MNEM_SUFFIX 'l'
+#define QWORD_MNEM_SUFFIX 'q'
+/* Intel Syntax */
+#define LONG_DOUBLE_MNEM_SUFFIX 'x'
+
+/* modrm.mode = REGMEM_FIELD_HAS_REG when a register is in there */
+#define REGMEM_FIELD_HAS_REG 0x3/* always = 0x3 */
+#define REGMEM_FIELD_HAS_MEM (~REGMEM_FIELD_HAS_REG)
+
+#define END_OF_INSN '\0'
+
+/* Intel Syntax */
+/* Values 0-4 map onto scale factor */
+#define BYTE_PTR 0
+#define WORD_PTR 1
+#define DWORD_PTR 2
+#define QWORD_PTR 3
+#define XWORD_PTR 4
+#define SHORT 5
+#define OFFSET_FLAT 6
+#define FLAT 7
+#define NONE_FOUND 8
+
+typedef struct
+{
+ /* instruction name sans width suffix ("mov" for movl insns) */
+ char *name;
+
+ /* how many operands */
+ unsigned int operands;
+
+ /* base_opcode is the fundamental opcode byte without optional
+ prefix(es). */
+ unsigned int base_opcode;
+
+ /* extension_opcode is the 3 bit extension for group <n> insns.
+ This field is also used to store the 8-bit opcode suffix for the
+ AMD 3DNow! instructions.
+ If this template has no extension opcode (the usual case) use None */
+ unsigned int extension_opcode;
+#define None 0xffff /* If no extension_opcode is possible. */
+
+ /* cpu feature flags */
+ unsigned int cpu_flags;
+#define Cpu086 0x1 /* Any old cpu will do, 0 does the same */
+#define Cpu186 0x2 /* i186 or better required */
+#define Cpu286 0x4 /* i286 or better required */
+#define Cpu386 0x8 /* i386 or better required */
+#define Cpu486 0x10 /* i486 or better required */
+#define Cpu586 0x20 /* i585 or better required */
+#define Cpu686 0x40 /* i686 or better required */
+#define CpuP4 0x80 /* Pentium4 or better required */
+#define CpuK6 0x100 /* AMD K6 or better required*/
+#define CpuAthlon 0x200 /* AMD Athlon or better required*/
+#define CpuSledgehammer 0x400 /* Sledgehammer or better required */
+#define CpuMMX 0x800 /* MMX support required */
+#define CpuSSE 0x1000 /* Streaming SIMD extensions required */
+#define CpuSSE2 0x2000 /* Streaming SIMD extensions 2 required */
+#define Cpu3dnow 0x4000 /* 3dnow! support required */
+#define CpuPNI 0x8000 /* Prescott New Instructions required */
+#define CpuPadLock 0x10000 /* VIA PadLock required */
+
+ /* These flags are set by gas depending on the flag_code. */
+#define Cpu64 0x4000000 /* 64bit support required */
+#define CpuNo64 0x8000000 /* Not supported in the 64bit mode */
+
+ /* The default value for unknown CPUs - enable all features to avoid problems. */
+#define CpuUnknownFlags (Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuSledgehammer|CpuMMX|CpuSSE|CpuSSE2|CpuPNI|Cpu3dnow|CpuK6|CpuAthlon|CpuPadLock)
+
+ /* the bits in opcode_modifier are used to generate the final opcode from
+ the base_opcode. These bits also are used to detect alternate forms of
+ the same instruction */
+ unsigned int opcode_modifier;
+
+ /* opcode_modifier bits: */
+#define W 0x1 /* set if operands can be words or dwords
+ encoded the canonical way */
+#define D 0x2 /* D = 0 if Reg --> Regmem;
+ D = 1 if Regmem --> Reg: MUST BE 0x2 */
+#define Modrm 0x4
+#define FloatR 0x8 /* src/dest swap for floats: MUST BE 0x8 */
+#define ShortForm 0x10 /* register is in low 3 bits of opcode */
+#define FloatMF 0x20 /* FP insn memory format bit, sized by 0x4 */
+#define Jump 0x40 /* special case for jump insns. */
+#define JumpDword 0x80 /* call and jump */
+#define JumpByte 0x100 /* loop and jecxz */
+#define JumpInterSegment 0x200 /* special case for intersegment leaps/calls */
+#define FloatD 0x400 /* direction for float insns: MUST BE 0x400 */
+#define Seg2ShortForm 0x800 /* encoding of load segment reg insns */
+#define Seg3ShortForm 0x1000 /* fs/gs segment register insns. */
+#define Size16 0x2000 /* needs size prefix if in 32-bit mode */
+#define Size32 0x4000 /* needs size prefix if in 16-bit mode */
+#define Size64 0x8000 /* needs size prefix if in 16-bit mode */
+#define IgnoreSize 0x10000 /* instruction ignores operand size prefix */
+#define DefaultSize 0x20000 /* default insn size depends on mode */
+#define No_bSuf 0x40000 /* b suffix on instruction illegal */
+#define No_wSuf 0x80000 /* w suffix on instruction illegal */
+#define No_lSuf 0x100000 /* l suffix on instruction illegal */
+#define No_sSuf 0x200000 /* s suffix on instruction illegal */
+#define No_qSuf 0x400000 /* q suffix on instruction illegal */
+#define No_xSuf 0x800000 /* x suffix on instruction illegal */
+#define FWait 0x1000000 /* instruction needs FWAIT */
+#define IsString 0x2000000 /* quick test for string instructions */
+#define regKludge 0x4000000 /* fake an extra reg operand for clr, imul */
+#define IsPrefix 0x8000000 /* opcode is a prefix */
+#define ImmExt 0x10000000 /* instruction has extension in 8 bit imm */
+#define NoRex64 0x20000000 /* instruction don't need Rex64 prefix. */
+#define Rex64 0x40000000 /* instruction require Rex64 prefix. */
+#define Ugh 0x80000000 /* deprecated fp insn, gets a warning */
+
+ /* operand_types[i] describes the type of operand i. This is made
+ by OR'ing together all of the possible type masks. (e.g.
+ 'operand_types[i] = Reg|Imm' specifies that operand i can be
+ either a register or an immediate operand. */
+ unsigned int operand_types[3];
+
+ /* operand_types[i] bits */
+ /* register */
+#define Reg8 0x1 /* 8 bit reg */
+#define Reg16 0x2 /* 16 bit reg */
+#define Reg32 0x4 /* 32 bit reg */
+#define Reg64 0x8 /* 64 bit reg */
+ /* immediate */
+#define Imm8 0x10 /* 8 bit immediate */
+#define Imm8S 0x20 /* 8 bit immediate sign extended */
+#define Imm16 0x40 /* 16 bit immediate */
+#define Imm32 0x80 /* 32 bit immediate */
+#define Imm32S 0x100 /* 32 bit immediate sign extended */
+#define Imm64 0x200 /* 64 bit immediate */
+#define Imm1 0x400 /* 1 bit immediate */
+ /* memory */
+#define BaseIndex 0x800
+ /* Disp8,16,32 are used in different ways, depending on the
+ instruction. For jumps, they specify the size of the PC relative
+ displacement, for baseindex type instructions, they specify the
+ size of the offset relative to the base register, and for memory
+ offset instructions such as `mov 1234,%al' they specify the size of
+ the offset relative to the segment base. */
+#define Disp8 0x1000 /* 8 bit displacement */
+#define Disp16 0x2000 /* 16 bit displacement */
+#define Disp32 0x4000 /* 32 bit displacement */
+#define Disp32S 0x8000 /* 32 bit signed displacement */
+#define Disp64 0x10000 /* 64 bit displacement */
+ /* specials */
+#define InOutPortReg 0x20000 /* register to hold in/out port addr = dx */
+#define ShiftCount 0x40000 /* register to hold shift cound = cl */
+#define Control 0x80000 /* Control register */
+#define Debug 0x100000 /* Debug register */
+#define Test 0x200000 /* Test register */
+#define FloatReg 0x400000 /* Float register */
+#define FloatAcc 0x800000 /* Float stack top %st(0) */
+#define SReg2 0x1000000 /* 2 bit segment register */
+#define SReg3 0x2000000 /* 3 bit segment register */
+#define Acc 0x4000000 /* Accumulator %al or %ax or %eax */
+#define JumpAbsolute 0x8000000
+#define RegMMX 0x10000000 /* MMX register */
+#define RegXMM 0x20000000 /* XMM registers in PIII */
+#define EsSeg 0x40000000 /* String insn operand with fixed es segment */
+
+ /* InvMem is for instructions with a modrm byte that only allow a
+ general register encoding in the i.tm.mode and i.tm.regmem fields,
+ eg. control reg moves. They really ought to support a memory form,
+ but don't, so we add an InvMem flag to the register operand to
+ indicate that it should be encoded in the i.tm.regmem field. */
+#define InvMem 0x80000000
+
+#define Reg (Reg8|Reg16|Reg32|Reg64) /* gen'l register */
+#define WordReg (Reg16|Reg32|Reg64)
+#define ImplicitRegister (InOutPortReg|ShiftCount|Acc|FloatAcc)
+#define Imm (Imm8|Imm8S|Imm16|Imm32S|Imm32|Imm64) /* gen'l immediate */
+#define EncImm (Imm8|Imm16|Imm32|Imm32S) /* Encodable gen'l immediate */
+#define Disp (Disp8|Disp16|Disp32|Disp32S|Disp64) /* General displacement */
+#define AnyMem (Disp8|Disp16|Disp32|Disp32S|BaseIndex|InvMem) /* General memory */
+ /* The following aliases are defined because the opcode table
+ carefully specifies the allowed memory types for each instruction.
+ At the moment we can only tell a memory reference size by the
+ instruction suffix, so there's not much point in defining Mem8,
+ Mem16, Mem32 and Mem64 opcode modifiers - We might as well just use
+ the suffix directly to check memory operands. */
+#define LLongMem AnyMem /* 64 bits (or more) */
+#define LongMem AnyMem /* 32 bit memory ref */
+#define ShortMem AnyMem /* 16 bit memory ref */
+#define WordMem AnyMem /* 16 or 32 bit memory ref */
+#define ByteMem AnyMem /* 8 bit memory ref */
+}
+template;
+
+/*
+ 'templates' is for grouping together 'template' structures for opcodes
+ of the same name. This is only used for storing the insns in the grand
+ ole hash table of insns.
+ The templates themselves start at START and range up to (but not including)
+ END.
+ */
+typedef struct
+{
+ const template *start;
+ const template *end;
+}
+templates;
+
+/* these are for register name --> number & type hash lookup */
+typedef struct
+{
+ char *reg_name;
+ unsigned int reg_type;
+ unsigned int reg_flags;
+#define RegRex 0x1 /* Extended register. */
+#define RegRex64 0x2 /* Extended 8 bit register. */
+ unsigned int reg_num;
+}
+reg_entry;
+
+typedef struct
+{
+ char *seg_name;
+ unsigned int seg_prefix;
+}
+seg_entry;
+
+/* 386 operand encoding bytes: see 386 book for details of this. */
+typedef struct
+{
+ unsigned int regmem; /* codes register or memory operand */
+ unsigned int reg; /* codes register operand (or extended opcode) */
+ unsigned int mode; /* how to interpret regmem & reg */
+}
+modrm_byte;
+
+/* x86-64 extension prefix. */
+typedef int rex_byte;
+#define REX_OPCODE 0x40
+
+/* Indicates 64 bit operand size. */
+#define REX_MODE64 8
+/* High extension to reg field of modrm byte. */
+#define REX_EXTX 4
+/* High extension to SIB index field. */
+#define REX_EXTY 2
+/* High extension to base field of modrm or SIB, or reg field of opcode. */
+#define REX_EXTZ 1
+
+/* 386 opcode byte to code indirect addressing. */
+typedef struct
+{
+ unsigned base;
+ unsigned index;
+ unsigned scale;
+}
+sib_byte;
+
+/* x86 arch names and features */
+typedef struct
+{
+ const char *name; /* arch name */
+ unsigned int flags; /* cpu feature flags */
+}
+arch_entry;
+
+/* The name of the global offset table generated by the compiler. Allow
+ this to be overridden if need be. */
+#ifndef GLOBAL_OFFSET_TABLE_NAME
+#define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_"
+#endif
+
+#ifndef LEX_AT
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) x86_cons (EXP, NBYTES)
+extern void x86_cons PARAMS ((expressionS *, int));
+
+#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) x86_cons_fix_new(FRAG, OFF, LEN, EXP)
+extern void x86_cons_fix_new
+ PARAMS ((fragS *, unsigned int, unsigned int, expressionS *));
+#endif
+
+#define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs */
+
+#define NO_RELOC BFD_RELOC_NONE
+
+void i386_validate_fix PARAMS ((struct fix *));
+#define TC_VALIDATE_FIX(FIX,SEGTYPE,SKIP) i386_validate_fix(FIX)
+
+#define tc_fix_adjustable(X) tc_i386_fix_adjustable(X)
+extern int tc_i386_fix_adjustable PARAMS ((struct fix *));
+
+/* Values passed to md_apply_fix3 don't include the symbol value. */
+#define MD_APPLY_SYM_VALUE(FIX) 0
+
+/* ELF wants external syms kept, as does PE COFF. */
+#if defined (TE_PE) && defined (STRICT_PE_FORMAT)
+#define EXTERN_FORCE_RELOC \
+ (OUTPUT_FLAVOR == bfd_target_elf_flavour \
+ || OUTPUT_FLAVOR == bfd_target_coff_flavour)
+#else
+#define EXTERN_FORCE_RELOC \
+ (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+#endif
+
+/* This expression evaluates to true if the relocation is for a local
+ object for which we still want to do the relocation at runtime.
+ False if we are willing to perform this relocation while building
+ the .o file. GOTOFF does not need to be checked here because it is
+ not pcrel. I am not sure if some of the others are ever used with
+ pcrel, but it is easier to be safe than sorry. */
+
+#define TC_FORCE_RELOCATION_LOCAL(FIX) \
+ (!(FIX)->fx_pcrel \
+ || (FIX)->fx_plt \
+ || (FIX)->fx_r_type == BFD_RELOC_386_PLT32 \
+ || (FIX)->fx_r_type == BFD_RELOC_386_GOT32 \
+ || (FIX)->fx_r_type == BFD_RELOC_386_GOTPC \
+ || TC_FORCE_RELOCATION (FIX))
+
+#define md_operand(x)
+
+extern const struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+
+extern int optimize_align_code;
+
+#define md_do_align(n, fill, len, max, around) \
+if ((n) \
+ && !need_pass_2 \
+ && optimize_align_code \
+ && (!(fill) \
+ || ((char)*(fill) == (char)0x90 && (len) == 1)) \
+ && subseg_text_p (now_seg)) \
+ { \
+ frag_align_code ((n), (max)); \
+ goto around; \
+ }
+
+#define MAX_MEM_FOR_RS_ALIGN_CODE 15
+
+extern void i386_align_code PARAMS ((fragS *, int));
+
+#define HANDLE_ALIGN(fragP) \
+if (fragP->fr_type == rs_align_code) \
+ i386_align_code (fragP, (fragP->fr_next->fr_address \
+ - fragP->fr_address \
+ - fragP->fr_fix));
+
+void i386_print_statistics PARAMS ((FILE *));
+#define tc_print_statistics i386_print_statistics
+
+#define md_number_to_chars number_to_chars_littleendian
+
+#ifdef SCO_ELF
+#define tc_init_after_args() sco_id ()
+extern void sco_id PARAMS ((void));
+#endif
+
+/* We want .cfi_* pseudo-ops for generating unwind info. */
+#define TARGET_USE_CFIPOP 1
+
+extern unsigned int x86_dwarf2_return_column;
+#define DWARF2_DEFAULT_RETURN_COLUMN x86_dwarf2_return_column
+
+extern int x86_cie_data_alignment;
+#define DWARF2_CIE_DATA_ALIGNMENT x86_cie_data_alignment
+
+#define tc_regname_to_dw2regnum tc_x86_regname_to_dw2regnum
+extern int tc_x86_regname_to_dw2regnum PARAMS ((const char *regname));
+
+#define tc_cfi_frame_initial_instructions tc_x86_frame_initial_instructions
+extern void tc_x86_frame_initial_instructions PARAMS ((void));
+
+#endif /* TC_I386 */
diff --git a/x/binutils/gas/config/tc-ia64.c b/x/binutils/gas/config/tc-ia64.c
new file mode 100644
index 0000000..f5526c9
--- /dev/null
+++ b/x/binutils/gas/config/tc-ia64.c
@@ -0,0 +1,11115 @@
+/* tc-ia64.c -- Assembler for the HP/Intel IA-64 architecture.
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/*
+ TODO:
+
+ - optional operands
+ - directives:
+ .eb
+ .estate
+ .lb
+ .popsection
+ .previous
+ .psr
+ .pushsection
+ - labels are wrong if automatic alignment is introduced
+ (e.g., checkout the second real10 definition in test-data.s)
+ - DV-related stuff:
+ <reg>.safe_across_calls and any other DV-related directives I don't
+ have documentation for.
+ verify mod-sched-brs reads/writes are checked/marked (and other
+ notes)
+
+ */
+
+#include "as.h"
+#include "safe-ctype.h"
+#include "dwarf2dbg.h"
+#include "subsegs.h"
+
+#include "opcode/ia64.h"
+
+#include "elf/ia64.h"
+
+#define NELEMS(a) ((int) (sizeof (a)/sizeof ((a)[0])))
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+#define NUM_SLOTS 4
+#define PREV_SLOT md.slot[(md.curr_slot + NUM_SLOTS - 1) % NUM_SLOTS]
+#define CURR_SLOT md.slot[md.curr_slot]
+
+#define O_pseudo_fixup (O_max + 1)
+
+enum special_section
+ {
+ /* IA-64 ABI section pseudo-ops. */
+ SPECIAL_SECTION_BSS = 0,
+ SPECIAL_SECTION_SBSS,
+ SPECIAL_SECTION_SDATA,
+ SPECIAL_SECTION_RODATA,
+ SPECIAL_SECTION_COMMENT,
+ SPECIAL_SECTION_UNWIND,
+ SPECIAL_SECTION_UNWIND_INFO,
+ /* HPUX specific section pseudo-ops. */
+ SPECIAL_SECTION_INIT_ARRAY,
+ SPECIAL_SECTION_FINI_ARRAY,
+ };
+
+enum reloc_func
+ {
+ FUNC_DTP_MODULE,
+ FUNC_DTP_RELATIVE,
+ FUNC_FPTR_RELATIVE,
+ FUNC_GP_RELATIVE,
+ FUNC_LT_RELATIVE,
+ FUNC_LT_RELATIVE_X,
+ FUNC_PC_RELATIVE,
+ FUNC_PLT_RELATIVE,
+ FUNC_SEC_RELATIVE,
+ FUNC_SEG_RELATIVE,
+ FUNC_TP_RELATIVE,
+ FUNC_LTV_RELATIVE,
+ FUNC_LT_FPTR_RELATIVE,
+ FUNC_LT_DTP_MODULE,
+ FUNC_LT_DTP_RELATIVE,
+ FUNC_LT_TP_RELATIVE,
+ FUNC_IPLT_RELOC,
+ };
+
+enum reg_symbol
+ {
+ REG_GR = 0,
+ REG_FR = (REG_GR + 128),
+ REG_AR = (REG_FR + 128),
+ REG_CR = (REG_AR + 128),
+ REG_P = (REG_CR + 128),
+ REG_BR = (REG_P + 64),
+ REG_IP = (REG_BR + 8),
+ REG_CFM,
+ REG_PR,
+ REG_PR_ROT,
+ REG_PSR,
+ REG_PSR_L,
+ REG_PSR_UM,
+ /* The following are pseudo-registers for use by gas only. */
+ IND_CPUID,
+ IND_DBR,
+ IND_DTR,
+ IND_ITR,
+ IND_IBR,
+ IND_MEM,
+ IND_MSR,
+ IND_PKR,
+ IND_PMC,
+ IND_PMD,
+ IND_RR,
+ /* The following pseudo-registers are used for unwind directives only: */
+ REG_PSP,
+ REG_PRIUNAT,
+ REG_NUM
+ };
+
+enum dynreg_type
+ {
+ DYNREG_GR = 0, /* dynamic general purpose register */
+ DYNREG_FR, /* dynamic floating point register */
+ DYNREG_PR, /* dynamic predicate register */
+ DYNREG_NUM_TYPES
+ };
+
+enum operand_match_result
+ {
+ OPERAND_MATCH,
+ OPERAND_OUT_OF_RANGE,
+ OPERAND_MISMATCH
+ };
+
+/* On the ia64, we can't know the address of a text label until the
+ instructions are packed into a bundle. To handle this, we keep
+ track of the list of labels that appear in front of each
+ instruction. */
+struct label_fix
+{
+ struct label_fix *next;
+ struct symbol *sym;
+};
+
+extern int target_big_endian;
+
+void (*ia64_number_to_chars) PARAMS ((char *, valueT, int));
+
+static void ia64_float_to_chars_bigendian
+ PARAMS ((char *, LITTLENUM_TYPE *, int));
+static void ia64_float_to_chars_littleendian
+ PARAMS ((char *, LITTLENUM_TYPE *, int));
+static void (*ia64_float_to_chars)
+ PARAMS ((char *, LITTLENUM_TYPE *, int));
+
+static struct hash_control *alias_hash;
+static struct hash_control *alias_name_hash;
+static struct hash_control *secalias_hash;
+static struct hash_control *secalias_name_hash;
+
+/* Characters which always start a comment. */
+const char comment_chars[] = "";
+
+/* Characters which start a comment at the beginning of a line. */
+const char line_comment_chars[] = "#";
+
+/* Characters which may be used to separate multiple commands on a
+ single line. */
+const char line_separator_chars[] = ";";
+
+/* Characters which are used to indicate an exponent in a floating
+ point number. */
+const char EXP_CHARS[] = "eE";
+
+/* Characters which mean that a number is a floating point constant,
+ as in 0d1.0. */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+/* ia64-specific option processing: */
+
+const char *md_shortopts = "m:N:x::";
+
+struct option md_longopts[] =
+ {
+#define OPTION_MCONSTANT_GP (OPTION_MD_BASE + 1)
+ {"mconstant-gp", no_argument, NULL, OPTION_MCONSTANT_GP},
+#define OPTION_MAUTO_PIC (OPTION_MD_BASE + 2)
+ {"mauto-pic", no_argument, NULL, OPTION_MAUTO_PIC}
+ };
+
+size_t md_longopts_size = sizeof (md_longopts);
+
+static struct
+ {
+ struct hash_control *pseudo_hash; /* pseudo opcode hash table */
+ struct hash_control *reg_hash; /* register name hash table */
+ struct hash_control *dynreg_hash; /* dynamic register hash table */
+ struct hash_control *const_hash; /* constant hash table */
+ struct hash_control *entry_hash; /* code entry hint hash table */
+
+ symbolS *regsym[REG_NUM];
+
+ /* If X_op is != O_absent, the registername for the instruction's
+ qualifying predicate. If NULL, p0 is assumed for instructions
+ that are predicatable. */
+ expressionS qp;
+
+ unsigned int
+ manual_bundling : 1,
+ debug_dv: 1,
+ detect_dv: 1,
+ explicit_mode : 1, /* which mode we're in */
+ default_explicit_mode : 1, /* which mode is the default */
+ mode_explicitly_set : 1, /* was the current mode explicitly set? */
+ auto_align : 1,
+ keep_pending_output : 1;
+
+ /* Each bundle consists of up to three instructions. We keep
+ track of four most recent instructions so we can correctly set
+ the end_of_insn_group for the last instruction in a bundle. */
+ int curr_slot;
+ int num_slots_in_use;
+ struct slot
+ {
+ unsigned int
+ end_of_insn_group : 1,
+ manual_bundling_on : 1,
+ manual_bundling_off : 1;
+ signed char user_template; /* user-selected template, if any */
+ unsigned char qp_regno; /* qualifying predicate */
+ /* This duplicates a good fraction of "struct fix" but we
+ can't use a "struct fix" instead since we can't call
+ fix_new_exp() until we know the address of the instruction. */
+ int num_fixups;
+ struct insn_fix
+ {
+ bfd_reloc_code_real_type code;
+ enum ia64_opnd opnd; /* type of operand in need of fix */
+ unsigned int is_pcrel : 1; /* is operand pc-relative? */
+ expressionS expr; /* the value to be inserted */
+ }
+ fixup[2]; /* at most two fixups per insn */
+ struct ia64_opcode *idesc;
+ struct label_fix *label_fixups;
+ struct label_fix *tag_fixups;
+ struct unw_rec_list *unwind_record; /* Unwind directive. */
+ expressionS opnd[6];
+ char *src_file;
+ unsigned int src_line;
+ struct dwarf2_line_info debug_line;
+ }
+ slot[NUM_SLOTS];
+
+ segT last_text_seg;
+
+ struct dynreg
+ {
+ struct dynreg *next; /* next dynamic register */
+ const char *name;
+ unsigned short base; /* the base register number */
+ unsigned short num_regs; /* # of registers in this set */
+ }
+ *dynreg[DYNREG_NUM_TYPES], in, loc, out, rot;
+
+ flagword flags; /* ELF-header flags */
+
+ struct mem_offset {
+ unsigned hint:1; /* is this hint currently valid? */
+ bfd_vma offset; /* mem.offset offset */
+ bfd_vma base; /* mem.offset base */
+ } mem_offset;
+
+ int path; /* number of alt. entry points seen */
+ const char **entry_labels; /* labels of all alternate paths in
+ the current DV-checking block. */
+ int maxpaths; /* size currently allocated for
+ entry_labels */
+ /* Support for hardware errata workarounds. */
+
+ /* Record data about the last three insn groups. */
+ struct group
+ {
+ /* B-step workaround.
+ For each predicate register, this is set if the corresponding insn
+ group conditionally sets this register with one of the affected
+ instructions. */
+ int p_reg_set[64];
+ /* B-step workaround.
+ For each general register, this is set if the corresponding insn
+ a) is conditional one one of the predicate registers for which
+ P_REG_SET is 1 in the corresponding entry of the previous group,
+ b) sets this general register with one of the affected
+ instructions. */
+ int g_reg_set_conditionally[128];
+ } last_groups[3];
+ int group_idx;
+
+ int pointer_size; /* size in bytes of a pointer */
+ int pointer_size_shift; /* shift size of a pointer for alignment */
+ }
+md;
+
+/* application registers: */
+
+#define AR_K0 0
+#define AR_K7 7
+#define AR_RSC 16
+#define AR_BSP 17
+#define AR_BSPSTORE 18
+#define AR_RNAT 19
+#define AR_UNAT 36
+#define AR_FPSR 40
+#define AR_ITC 44
+#define AR_PFS 64
+#define AR_LC 65
+
+static const struct
+ {
+ const char *name;
+ int regnum;
+ }
+ar[] =
+ {
+ {"ar.k0", 0}, {"ar.k1", 1}, {"ar.k2", 2}, {"ar.k3", 3},
+ {"ar.k4", 4}, {"ar.k5", 5}, {"ar.k6", 6}, {"ar.k7", 7},
+ {"ar.rsc", 16}, {"ar.bsp", 17},
+ {"ar.bspstore", 18}, {"ar.rnat", 19},
+ {"ar.fcr", 21}, {"ar.eflag", 24},
+ {"ar.csd", 25}, {"ar.ssd", 26},
+ {"ar.cflg", 27}, {"ar.fsr", 28},
+ {"ar.fir", 29}, {"ar.fdr", 30},
+ {"ar.ccv", 32}, {"ar.unat", 36},
+ {"ar.fpsr", 40}, {"ar.itc", 44},
+ {"ar.pfs", 64}, {"ar.lc", 65},
+ {"ar.ec", 66},
+ };
+
+#define CR_IPSR 16
+#define CR_ISR 17
+#define CR_IIP 19
+#define CR_IFA 20
+#define CR_ITIR 21
+#define CR_IIPA 22
+#define CR_IFS 23
+#define CR_IIM 24
+#define CR_IHA 25
+#define CR_IVR 65
+#define CR_TPR 66
+#define CR_EOI 67
+#define CR_IRR0 68
+#define CR_IRR3 71
+#define CR_LRR0 80
+#define CR_LRR1 81
+
+/* control registers: */
+static const struct
+ {
+ const char *name;
+ int regnum;
+ }
+cr[] =
+ {
+ {"cr.dcr", 0},
+ {"cr.itm", 1},
+ {"cr.iva", 2},
+ {"cr.pta", 8},
+ {"cr.gpta", 9},
+ {"cr.ipsr", 16},
+ {"cr.isr", 17},
+ {"cr.iip", 19},
+ {"cr.ifa", 20},
+ {"cr.itir", 21},
+ {"cr.iipa", 22},
+ {"cr.ifs", 23},
+ {"cr.iim", 24},
+ {"cr.iha", 25},
+ {"cr.lid", 64},
+ {"cr.ivr", 65},
+ {"cr.tpr", 66},
+ {"cr.eoi", 67},
+ {"cr.irr0", 68},
+ {"cr.irr1", 69},
+ {"cr.irr2", 70},
+ {"cr.irr3", 71},
+ {"cr.itv", 72},
+ {"cr.pmv", 73},
+ {"cr.cmcv", 74},
+ {"cr.lrr0", 80},
+ {"cr.lrr1", 81}
+ };
+
+#define PSR_MFL 4
+#define PSR_IC 13
+#define PSR_DFL 18
+#define PSR_CPL 32
+
+static const struct const_desc
+ {
+ const char *name;
+ valueT value;
+ }
+const_bits[] =
+ {
+ /* PSR constant masks: */
+
+ /* 0: reserved */
+ {"psr.be", ((valueT) 1) << 1},
+ {"psr.up", ((valueT) 1) << 2},
+ {"psr.ac", ((valueT) 1) << 3},
+ {"psr.mfl", ((valueT) 1) << 4},
+ {"psr.mfh", ((valueT) 1) << 5},
+ /* 6-12: reserved */
+ {"psr.ic", ((valueT) 1) << 13},
+ {"psr.i", ((valueT) 1) << 14},
+ {"psr.pk", ((valueT) 1) << 15},
+ /* 16: reserved */
+ {"psr.dt", ((valueT) 1) << 17},
+ {"psr.dfl", ((valueT) 1) << 18},
+ {"psr.dfh", ((valueT) 1) << 19},
+ {"psr.sp", ((valueT) 1) << 20},
+ {"psr.pp", ((valueT) 1) << 21},
+ {"psr.di", ((valueT) 1) << 22},
+ {"psr.si", ((valueT) 1) << 23},
+ {"psr.db", ((valueT) 1) << 24},
+ {"psr.lp", ((valueT) 1) << 25},
+ {"psr.tb", ((valueT) 1) << 26},
+ {"psr.rt", ((valueT) 1) << 27},
+ /* 28-31: reserved */
+ /* 32-33: cpl (current privilege level) */
+ {"psr.is", ((valueT) 1) << 34},
+ {"psr.mc", ((valueT) 1) << 35},
+ {"psr.it", ((valueT) 1) << 36},
+ {"psr.id", ((valueT) 1) << 37},
+ {"psr.da", ((valueT) 1) << 38},
+ {"psr.dd", ((valueT) 1) << 39},
+ {"psr.ss", ((valueT) 1) << 40},
+ /* 41-42: ri (restart instruction) */
+ {"psr.ed", ((valueT) 1) << 43},
+ {"psr.bn", ((valueT) 1) << 44},
+ };
+
+/* indirect register-sets/memory: */
+
+static const struct
+ {
+ const char *name;
+ int regnum;
+ }
+indirect_reg[] =
+ {
+ { "CPUID", IND_CPUID },
+ { "cpuid", IND_CPUID },
+ { "dbr", IND_DBR },
+ { "dtr", IND_DTR },
+ { "itr", IND_ITR },
+ { "ibr", IND_IBR },
+ { "msr", IND_MSR },
+ { "pkr", IND_PKR },
+ { "pmc", IND_PMC },
+ { "pmd", IND_PMD },
+ { "rr", IND_RR },
+ };
+
+/* Pseudo functions used to indicate relocation types (these functions
+ start with an at sign (@). */
+static struct
+ {
+ const char *name;
+ enum pseudo_type
+ {
+ PSEUDO_FUNC_NONE,
+ PSEUDO_FUNC_RELOC,
+ PSEUDO_FUNC_CONST,
+ PSEUDO_FUNC_REG,
+ PSEUDO_FUNC_FLOAT
+ }
+ type;
+ union
+ {
+ unsigned long ival;
+ symbolS *sym;
+ }
+ u;
+ }
+pseudo_func[] =
+ {
+ /* reloc pseudo functions (these must come first!): */
+ { "dtpmod", PSEUDO_FUNC_RELOC, { 0 } },
+ { "dtprel", PSEUDO_FUNC_RELOC, { 0 } },
+ { "fptr", PSEUDO_FUNC_RELOC, { 0 } },
+ { "gprel", PSEUDO_FUNC_RELOC, { 0 } },
+ { "ltoff", PSEUDO_FUNC_RELOC, { 0 } },
+ { "ltoffx", PSEUDO_FUNC_RELOC, { 0 } },
+ { "pcrel", PSEUDO_FUNC_RELOC, { 0 } },
+ { "pltoff", PSEUDO_FUNC_RELOC, { 0 } },
+ { "secrel", PSEUDO_FUNC_RELOC, { 0 } },
+ { "segrel", PSEUDO_FUNC_RELOC, { 0 } },
+ { "tprel", PSEUDO_FUNC_RELOC, { 0 } },
+ { "ltv", PSEUDO_FUNC_RELOC, { 0 } },
+ { "", 0, { 0 } }, /* placeholder for FUNC_LT_FPTR_RELATIVE */
+ { "", 0, { 0 } }, /* placeholder for FUNC_LT_DTP_MODULE */
+ { "", 0, { 0 } }, /* placeholder for FUNC_LT_DTP_RELATIVE */
+ { "", 0, { 0 } }, /* placeholder for FUNC_LT_TP_RELATIVE */
+ { "iplt", PSEUDO_FUNC_RELOC, { 0 } },
+
+ /* mbtype4 constants: */
+ { "alt", PSEUDO_FUNC_CONST, { 0xa } },
+ { "brcst", PSEUDO_FUNC_CONST, { 0x0 } },
+ { "mix", PSEUDO_FUNC_CONST, { 0x8 } },
+ { "rev", PSEUDO_FUNC_CONST, { 0xb } },
+ { "shuf", PSEUDO_FUNC_CONST, { 0x9 } },
+
+ /* fclass constants: */
+ { "nat", PSEUDO_FUNC_CONST, { 0x100 } },
+ { "qnan", PSEUDO_FUNC_CONST, { 0x080 } },
+ { "snan", PSEUDO_FUNC_CONST, { 0x040 } },
+ { "pos", PSEUDO_FUNC_CONST, { 0x001 } },
+ { "neg", PSEUDO_FUNC_CONST, { 0x002 } },
+ { "zero", PSEUDO_FUNC_CONST, { 0x004 } },
+ { "unorm", PSEUDO_FUNC_CONST, { 0x008 } },
+ { "norm", PSEUDO_FUNC_CONST, { 0x010 } },
+ { "inf", PSEUDO_FUNC_CONST, { 0x020 } },
+
+ { "natval", PSEUDO_FUNC_CONST, { 0x100 } }, /* old usage */
+
+ /* hint constants: */
+ { "pause", PSEUDO_FUNC_CONST, { 0x0 } },
+
+ /* unwind-related constants: */
+ { "svr4", PSEUDO_FUNC_CONST, { ELFOSABI_NONE } },
+ { "hpux", PSEUDO_FUNC_CONST, { ELFOSABI_HPUX } },
+ { "nt", PSEUDO_FUNC_CONST, { 2 } }, /* conflicts w/ELFOSABI_NETBSD */
+ { "linux", PSEUDO_FUNC_CONST, { ELFOSABI_LINUX } },
+ { "freebsd", PSEUDO_FUNC_CONST, { ELFOSABI_FREEBSD } },
+ { "openvms", PSEUDO_FUNC_CONST, { ELFOSABI_OPENVMS } },
+ { "nsk", PSEUDO_FUNC_CONST, { ELFOSABI_NSK } },
+
+ /* unwind-related registers: */
+ { "priunat",PSEUDO_FUNC_REG, { REG_PRIUNAT } }
+ };
+
+/* 41-bit nop opcodes (one per unit): */
+static const bfd_vma nop[IA64_NUM_UNITS] =
+ {
+ 0x0000000000LL, /* NIL => break 0 */
+ 0x0008000000LL, /* I-unit nop */
+ 0x0008000000LL, /* M-unit nop */
+ 0x4000000000LL, /* B-unit nop */
+ 0x0008000000LL, /* F-unit nop */
+ 0x0008000000LL, /* L-"unit" nop */
+ 0x0008000000LL, /* X-unit nop */
+ };
+
+/* Can't be `const' as it's passed to input routines (which have the
+ habit of setting temporary sentinels. */
+static char special_section_name[][20] =
+ {
+ {".bss"}, {".sbss"}, {".sdata"}, {".rodata"}, {".comment"},
+ {".IA_64.unwind"}, {".IA_64.unwind_info"},
+ {".init_array"}, {".fini_array"}
+ };
+
+static char *special_linkonce_name[] =
+ {
+ ".gnu.linkonce.ia64unw.", ".gnu.linkonce.ia64unwi."
+ };
+
+/* The best template for a particular sequence of up to three
+ instructions: */
+#define N IA64_NUM_TYPES
+static unsigned char best_template[N][N][N];
+#undef N
+
+/* Resource dependencies currently in effect */
+static struct rsrc {
+ int depind; /* dependency index */
+ const struct ia64_dependency *dependency; /* actual dependency */
+ unsigned specific:1, /* is this a specific bit/regno? */
+ link_to_qp_branch:1; /* will a branch on the same QP clear it?*/
+ int index; /* specific regno/bit within dependency */
+ int note; /* optional qualifying note (0 if none) */
+#define STATE_NONE 0
+#define STATE_STOP 1
+#define STATE_SRLZ 2
+ int insn_srlz; /* current insn serialization state */
+ int data_srlz; /* current data serialization state */
+ int qp_regno; /* qualifying predicate for this usage */
+ char *file; /* what file marked this dependency */
+ unsigned int line; /* what line marked this dependency */
+ struct mem_offset mem_offset; /* optional memory offset hint */
+ enum { CMP_NONE, CMP_OR, CMP_AND } cmp_type; /* OR or AND compare? */
+ int path; /* corresponding code entry index */
+} *regdeps = NULL;
+static int regdepslen = 0;
+static int regdepstotlen = 0;
+static const char *dv_mode[] = { "RAW", "WAW", "WAR" };
+static const char *dv_sem[] = { "none", "implied", "impliedf",
+ "data", "instr", "specific", "stop", "other" };
+static const char *dv_cmp_type[] = { "none", "OR", "AND" };
+
+/* Current state of PR mutexation */
+static struct qpmutex {
+ valueT prmask;
+ int path;
+} *qp_mutexes = NULL; /* QP mutex bitmasks */
+static int qp_mutexeslen = 0;
+static int qp_mutexestotlen = 0;
+static valueT qp_safe_across_calls = 0;
+
+/* Current state of PR implications */
+static struct qp_imply {
+ unsigned p1:6;
+ unsigned p2:6;
+ unsigned p2_branched:1;
+ int path;
+} *qp_implies = NULL;
+static int qp_implieslen = 0;
+static int qp_impliestotlen = 0;
+
+/* Keep track of static GR values so that indirect register usage can
+ sometimes be tracked. */
+static struct gr {
+ unsigned known:1;
+ int path;
+ valueT value;
+} gr_values[128] = {{ 1, 0, 0 }};
+
+/* Remember the alignment frag. */
+static fragS *align_frag;
+
+/* These are the routines required to output the various types of
+ unwind records. */
+
+/* A slot_number is a frag address plus the slot index (0-2). We use the
+ frag address here so that if there is a section switch in the middle of
+ a function, then instructions emitted to a different section are not
+ counted. Since there may be more than one frag for a function, this
+ means we also need to keep track of which frag this address belongs to
+ so we can compute inter-frag distances. This also nicely solves the
+ problem with nops emitted for align directives, which can't easily be
+ counted, but can easily be derived from frag sizes. */
+
+typedef struct unw_rec_list {
+ unwind_record r;
+ unsigned long slot_number;
+ fragS *slot_frag;
+ unsigned long next_slot_number;
+ fragS *next_slot_frag;
+ struct unw_rec_list *next;
+} unw_rec_list;
+
+#define SLOT_NUM_NOT_SET (unsigned)-1
+
+/* Linked list of saved prologue counts. A very poor
+ implementation of a map from label numbers to prologue counts. */
+typedef struct label_prologue_count
+{
+ struct label_prologue_count *next;
+ unsigned long label_number;
+ unsigned int prologue_count;
+} label_prologue_count;
+
+static struct
+{
+ /* Maintain a list of unwind entries for the current function. */
+ unw_rec_list *list;
+ unw_rec_list *tail;
+
+ /* Any unwind entires that should be attached to the current slot
+ that an insn is being constructed for. */
+ unw_rec_list *current_entry;
+
+ /* These are used to create the unwind table entry for this function. */
+ symbolS *proc_start;
+ symbolS *proc_end;
+ symbolS *info; /* pointer to unwind info */
+ symbolS *personality_routine;
+ segT saved_text_seg;
+ subsegT saved_text_subseg;
+ unsigned int force_unwind_entry : 1; /* force generation of unwind entry? */
+
+ /* TRUE if processing unwind directives in a prologue region. */
+ int prologue;
+ int prologue_mask;
+ unsigned int prologue_count; /* number of .prologues seen so far */
+ /* Prologue counts at previous .label_state directives. */
+ struct label_prologue_count * saved_prologue_counts;
+} unwind;
+
+typedef void (*vbyte_func) PARAMS ((int, char *, char *));
+
+/* Forward declarations: */
+static int ar_is_in_integer_unit PARAMS ((int regnum));
+static void set_section PARAMS ((char *name));
+static unsigned int set_regstack PARAMS ((unsigned int, unsigned int,
+ unsigned int, unsigned int));
+static void dot_align (int);
+static void dot_radix PARAMS ((int));
+static void dot_special_section PARAMS ((int));
+static void dot_proc PARAMS ((int));
+static void dot_fframe PARAMS ((int));
+static void dot_vframe PARAMS ((int));
+static void dot_vframesp PARAMS ((int));
+static void dot_vframepsp PARAMS ((int));
+static void dot_save PARAMS ((int));
+static void dot_restore PARAMS ((int));
+static void dot_restorereg PARAMS ((int));
+static void dot_restorereg_p PARAMS ((int));
+static void dot_handlerdata PARAMS ((int));
+static void dot_unwentry PARAMS ((int));
+static void dot_altrp PARAMS ((int));
+static void dot_savemem PARAMS ((int));
+static void dot_saveg PARAMS ((int));
+static void dot_savef PARAMS ((int));
+static void dot_saveb PARAMS ((int));
+static void dot_savegf PARAMS ((int));
+static void dot_spill PARAMS ((int));
+static void dot_spillreg PARAMS ((int));
+static void dot_spillmem PARAMS ((int));
+static void dot_spillreg_p PARAMS ((int));
+static void dot_spillmem_p PARAMS ((int));
+static void dot_label_state PARAMS ((int));
+static void dot_copy_state PARAMS ((int));
+static void dot_unwabi PARAMS ((int));
+static void dot_personality PARAMS ((int));
+static void dot_body PARAMS ((int));
+static void dot_prologue PARAMS ((int));
+static void dot_endp PARAMS ((int));
+static void dot_template PARAMS ((int));
+static void dot_regstk PARAMS ((int));
+static void dot_rot PARAMS ((int));
+static void dot_byteorder PARAMS ((int));
+static void dot_psr PARAMS ((int));
+static void dot_alias PARAMS ((int));
+static void dot_ln PARAMS ((int));
+static char *parse_section_name PARAMS ((void));
+static void dot_xdata PARAMS ((int));
+static void stmt_float_cons PARAMS ((int));
+static void stmt_cons_ua PARAMS ((int));
+static void dot_xfloat_cons PARAMS ((int));
+static void dot_xstringer PARAMS ((int));
+static void dot_xdata_ua PARAMS ((int));
+static void dot_xfloat_cons_ua PARAMS ((int));
+static void print_prmask PARAMS ((valueT mask));
+static void dot_pred_rel PARAMS ((int));
+static void dot_reg_val PARAMS ((int));
+static void dot_dv_mode PARAMS ((int));
+static void dot_entry PARAMS ((int));
+static void dot_mem_offset PARAMS ((int));
+static void add_unwind_entry PARAMS((unw_rec_list *ptr));
+static symbolS *declare_register PARAMS ((const char *name, int regnum));
+static void declare_register_set PARAMS ((const char *, int, int));
+static unsigned int operand_width PARAMS ((enum ia64_opnd));
+static enum operand_match_result operand_match PARAMS ((const struct ia64_opcode *idesc,
+ int index,
+ expressionS *e));
+static int parse_operand PARAMS ((expressionS *e));
+static struct ia64_opcode * parse_operands PARAMS ((struct ia64_opcode *));
+static int errata_nop_necessary_p PARAMS ((struct slot *, enum ia64_unit));
+static void build_insn PARAMS ((struct slot *, bfd_vma *));
+static void emit_one_bundle PARAMS ((void));
+static void fix_insn PARAMS ((fixS *, const struct ia64_operand *, valueT));
+static bfd_reloc_code_real_type ia64_gen_real_reloc_type PARAMS ((struct symbol *sym,
+ bfd_reloc_code_real_type r_type));
+static void insn_group_break PARAMS ((int, int, int));
+static void mark_resource PARAMS ((struct ia64_opcode *, const struct ia64_dependency *,
+ struct rsrc *, int depind, int path));
+static void add_qp_mutex PARAMS((valueT mask));
+static void add_qp_imply PARAMS((int p1, int p2));
+static void clear_qp_branch_flag PARAMS((valueT mask));
+static void clear_qp_mutex PARAMS((valueT mask));
+static void clear_qp_implies PARAMS((valueT p1_mask, valueT p2_mask));
+static int has_suffix_p PARAMS((const char *, const char *));
+static void clear_register_values PARAMS ((void));
+static void print_dependency PARAMS ((const char *action, int depind));
+static void instruction_serialization PARAMS ((void));
+static void data_serialization PARAMS ((void));
+static void remove_marked_resource PARAMS ((struct rsrc *));
+static int is_conditional_branch PARAMS ((struct ia64_opcode *));
+static int is_taken_branch PARAMS ((struct ia64_opcode *));
+static int is_interruption_or_rfi PARAMS ((struct ia64_opcode *));
+static int depends_on PARAMS ((int, struct ia64_opcode *));
+static int specify_resource PARAMS ((const struct ia64_dependency *,
+ struct ia64_opcode *, int, struct rsrc [], int, int));
+static int check_dv PARAMS((struct ia64_opcode *idesc));
+static void check_dependencies PARAMS((struct ia64_opcode *));
+static void mark_resources PARAMS((struct ia64_opcode *));
+static void update_dependencies PARAMS((struct ia64_opcode *));
+static void note_register_values PARAMS((struct ia64_opcode *));
+static int qp_mutex PARAMS ((int, int, int));
+static int resources_match PARAMS ((struct rsrc *, struct ia64_opcode *, int, int, int));
+static void output_vbyte_mem PARAMS ((int, char *, char *));
+static void count_output PARAMS ((int, char *, char *));
+static void output_R1_format PARAMS ((vbyte_func, unw_record_type, int));
+static void output_R2_format PARAMS ((vbyte_func, int, int, unsigned long));
+static void output_R3_format PARAMS ((vbyte_func, unw_record_type, unsigned long));
+static void output_P1_format PARAMS ((vbyte_func, int));
+static void output_P2_format PARAMS ((vbyte_func, int, int));
+static void output_P3_format PARAMS ((vbyte_func, unw_record_type, int));
+static void output_P4_format PARAMS ((vbyte_func, unsigned char *, unsigned long));
+static void output_P5_format PARAMS ((vbyte_func, int, unsigned long));
+static void output_P6_format PARAMS ((vbyte_func, unw_record_type, int));
+static void output_P7_format PARAMS ((vbyte_func, unw_record_type, unsigned long, unsigned long));
+static void output_P8_format PARAMS ((vbyte_func, unw_record_type, unsigned long));
+static void output_P9_format PARAMS ((vbyte_func, int, int));
+static void output_P10_format PARAMS ((vbyte_func, int, int));
+static void output_B1_format PARAMS ((vbyte_func, unw_record_type, unsigned long));
+static void output_B2_format PARAMS ((vbyte_func, unsigned long, unsigned long));
+static void output_B3_format PARAMS ((vbyte_func, unsigned long, unsigned long));
+static void output_B4_format PARAMS ((vbyte_func, unw_record_type, unsigned long));
+static char format_ab_reg PARAMS ((int, int));
+static void output_X1_format PARAMS ((vbyte_func, unw_record_type, int, int, unsigned long,
+ unsigned long));
+static void output_X2_format PARAMS ((vbyte_func, int, int, int, int, int, unsigned long));
+static void output_X3_format PARAMS ((vbyte_func, unw_record_type, int, int, int, unsigned long,
+ unsigned long));
+static void output_X4_format PARAMS ((vbyte_func, int, int, int, int, int, int, unsigned long));
+static unw_rec_list *output_endp PARAMS ((void));
+static unw_rec_list *output_prologue PARAMS ((void));
+static unw_rec_list *output_prologue_gr PARAMS ((unsigned int, unsigned int));
+static unw_rec_list *output_body PARAMS ((void));
+static unw_rec_list *output_mem_stack_f PARAMS ((unsigned int));
+static unw_rec_list *output_mem_stack_v PARAMS ((void));
+static unw_rec_list *output_psp_gr PARAMS ((unsigned int));
+static unw_rec_list *output_psp_sprel PARAMS ((unsigned int));
+static unw_rec_list *output_rp_when PARAMS ((void));
+static unw_rec_list *output_rp_gr PARAMS ((unsigned int));
+static unw_rec_list *output_rp_br PARAMS ((unsigned int));
+static unw_rec_list *output_rp_psprel PARAMS ((unsigned int));
+static unw_rec_list *output_rp_sprel PARAMS ((unsigned int));
+static unw_rec_list *output_pfs_when PARAMS ((void));
+static unw_rec_list *output_pfs_gr PARAMS ((unsigned int));
+static unw_rec_list *output_pfs_psprel PARAMS ((unsigned int));
+static unw_rec_list *output_pfs_sprel PARAMS ((unsigned int));
+static unw_rec_list *output_preds_when PARAMS ((void));
+static unw_rec_list *output_preds_gr PARAMS ((unsigned int));
+static unw_rec_list *output_preds_psprel PARAMS ((unsigned int));
+static unw_rec_list *output_preds_sprel PARAMS ((unsigned int));
+static unw_rec_list *output_fr_mem PARAMS ((unsigned int));
+static unw_rec_list *output_frgr_mem PARAMS ((unsigned int, unsigned int));
+static unw_rec_list *output_gr_gr PARAMS ((unsigned int, unsigned int));
+static unw_rec_list *output_gr_mem PARAMS ((unsigned int));
+static unw_rec_list *output_br_mem PARAMS ((unsigned int));
+static unw_rec_list *output_br_gr PARAMS ((unsigned int, unsigned int));
+static unw_rec_list *output_spill_base PARAMS ((unsigned int));
+static unw_rec_list *output_unat_when PARAMS ((void));
+static unw_rec_list *output_unat_gr PARAMS ((unsigned int));
+static unw_rec_list *output_unat_psprel PARAMS ((unsigned int));
+static unw_rec_list *output_unat_sprel PARAMS ((unsigned int));
+static unw_rec_list *output_lc_when PARAMS ((void));
+static unw_rec_list *output_lc_gr PARAMS ((unsigned int));
+static unw_rec_list *output_lc_psprel PARAMS ((unsigned int));
+static unw_rec_list *output_lc_sprel PARAMS ((unsigned int));
+static unw_rec_list *output_fpsr_when PARAMS ((void));
+static unw_rec_list *output_fpsr_gr PARAMS ((unsigned int));
+static unw_rec_list *output_fpsr_psprel PARAMS ((unsigned int));
+static unw_rec_list *output_fpsr_sprel PARAMS ((unsigned int));
+static unw_rec_list *output_priunat_when_gr PARAMS ((void));
+static unw_rec_list *output_priunat_when_mem PARAMS ((void));
+static unw_rec_list *output_priunat_gr PARAMS ((unsigned int));
+static unw_rec_list *output_priunat_psprel PARAMS ((unsigned int));
+static unw_rec_list *output_priunat_sprel PARAMS ((unsigned int));
+static unw_rec_list *output_bsp_when PARAMS ((void));
+static unw_rec_list *output_bsp_gr PARAMS ((unsigned int));
+static unw_rec_list *output_bsp_psprel PARAMS ((unsigned int));
+static unw_rec_list *output_bsp_sprel PARAMS ((unsigned int));
+static unw_rec_list *output_bspstore_when PARAMS ((void));
+static unw_rec_list *output_bspstore_gr PARAMS ((unsigned int));
+static unw_rec_list *output_bspstore_psprel PARAMS ((unsigned int));
+static unw_rec_list *output_bspstore_sprel PARAMS ((unsigned int));
+static unw_rec_list *output_rnat_when PARAMS ((void));
+static unw_rec_list *output_rnat_gr PARAMS ((unsigned int));
+static unw_rec_list *output_rnat_psprel PARAMS ((unsigned int));
+static unw_rec_list *output_rnat_sprel PARAMS ((unsigned int));
+static unw_rec_list *output_unwabi PARAMS ((unsigned long, unsigned long));
+static unw_rec_list *output_epilogue PARAMS ((unsigned long));
+static unw_rec_list *output_label_state PARAMS ((unsigned long));
+static unw_rec_list *output_copy_state PARAMS ((unsigned long));
+static unw_rec_list *output_spill_psprel PARAMS ((unsigned int, unsigned int, unsigned int));
+static unw_rec_list *output_spill_sprel PARAMS ((unsigned int, unsigned int, unsigned int));
+static unw_rec_list *output_spill_psprel_p PARAMS ((unsigned int, unsigned int, unsigned int,
+ unsigned int));
+static unw_rec_list *output_spill_sprel_p PARAMS ((unsigned int, unsigned int, unsigned int,
+ unsigned int));
+static unw_rec_list *output_spill_reg PARAMS ((unsigned int, unsigned int, unsigned int,
+ unsigned int));
+static unw_rec_list *output_spill_reg_p PARAMS ((unsigned int, unsigned int, unsigned int,
+ unsigned int, unsigned int));
+static void process_one_record PARAMS ((unw_rec_list *, vbyte_func));
+static void process_unw_records PARAMS ((unw_rec_list *, vbyte_func));
+static int calc_record_size PARAMS ((unw_rec_list *));
+static void set_imask PARAMS ((unw_rec_list *, unsigned long, unsigned long, unsigned int));
+static unsigned long slot_index PARAMS ((unsigned long, fragS *,
+ unsigned long, fragS *,
+ int));
+static unw_rec_list *optimize_unw_records PARAMS ((unw_rec_list *));
+static void fixup_unw_records PARAMS ((unw_rec_list *, int));
+static int convert_expr_to_ab_reg PARAMS ((expressionS *, unsigned int *, unsigned int *));
+static int convert_expr_to_xy_reg PARAMS ((expressionS *, unsigned int *, unsigned int *));
+static void generate_unwind_image PARAMS ((const char *));
+static unsigned int get_saved_prologue_count PARAMS ((unsigned long));
+static void save_prologue_count PARAMS ((unsigned long, unsigned int));
+static void free_saved_prologue_counts PARAMS ((void));
+
+/* Build the unwind section name by appending the (possibly stripped)
+ text section NAME to the unwind PREFIX. The resulting string
+ pointer is assigned to RESULT. The string is allocated on the
+ stack, so this must be a macro... */
+#define make_unw_section_name(special, text_name, result) \
+ { \
+ const char *_prefix = special_section_name[special]; \
+ const char *_suffix = text_name; \
+ size_t _prefix_len, _suffix_len; \
+ char *_result; \
+ if (strncmp (text_name, ".gnu.linkonce.t.", \
+ sizeof (".gnu.linkonce.t.") - 1) == 0) \
+ { \
+ _prefix = special_linkonce_name[special - SPECIAL_SECTION_UNWIND]; \
+ _suffix += sizeof (".gnu.linkonce.t.") - 1; \
+ } \
+ _prefix_len = strlen (_prefix), _suffix_len = strlen (_suffix); \
+ _result = alloca (_prefix_len + _suffix_len + 1); \
+ memcpy (_result, _prefix, _prefix_len); \
+ memcpy (_result + _prefix_len, _suffix, _suffix_len); \
+ _result[_prefix_len + _suffix_len] = '\0'; \
+ result = _result; \
+ } \
+while (0)
+
+/* Determine if application register REGNUM resides in the integer
+ unit (as opposed to the memory unit). */
+static int
+ar_is_in_integer_unit (reg)
+ int reg;
+{
+ reg -= REG_AR;
+
+ return (reg == 64 /* pfs */
+ || reg == 65 /* lc */
+ || reg == 66 /* ec */
+ /* ??? ias accepts and puts these in the integer unit. */
+ || (reg >= 112 && reg <= 127));
+}
+
+/* Switch to section NAME and create section if necessary. It's
+ rather ugly that we have to manipulate input_line_pointer but I
+ don't see any other way to accomplish the same thing without
+ changing obj-elf.c (which may be the Right Thing, in the end). */
+static void
+set_section (name)
+ char *name;
+{
+ char *saved_input_line_pointer;
+
+ saved_input_line_pointer = input_line_pointer;
+ input_line_pointer = name;
+ obj_elf_section (0);
+ input_line_pointer = saved_input_line_pointer;
+}
+
+/* Map 's' to SHF_IA_64_SHORT. */
+
+int
+ia64_elf_section_letter (letter, ptr_msg)
+ int letter;
+ char **ptr_msg;
+{
+ if (letter == 's')
+ return SHF_IA_64_SHORT;
+ else if (letter == 'o')
+ return SHF_LINK_ORDER;
+
+ *ptr_msg = _("Bad .section directive: want a,o,s,w,x,M,S,G,T in string");
+ return -1;
+}
+
+/* Map SHF_IA_64_SHORT to SEC_SMALL_DATA. */
+
+flagword
+ia64_elf_section_flags (flags, attr, type)
+ flagword flags;
+ int attr, type ATTRIBUTE_UNUSED;
+{
+ if (attr & SHF_IA_64_SHORT)
+ flags |= SEC_SMALL_DATA;
+ return flags;
+}
+
+int
+ia64_elf_section_type (str, len)
+ const char *str;
+ size_t len;
+{
+#define STREQ(s) ((len == sizeof (s) - 1) && (strncmp (str, s, sizeof (s) - 1) == 0))
+
+ if (STREQ (ELF_STRING_ia64_unwind_info))
+ return SHT_PROGBITS;
+
+ if (STREQ (ELF_STRING_ia64_unwind_info_once))
+ return SHT_PROGBITS;
+
+ if (STREQ (ELF_STRING_ia64_unwind))
+ return SHT_IA_64_UNWIND;
+
+ if (STREQ (ELF_STRING_ia64_unwind_once))
+ return SHT_IA_64_UNWIND;
+
+ if (STREQ ("unwind"))
+ return SHT_IA_64_UNWIND;
+
+ if (STREQ ("init_array"))
+ return SHT_INIT_ARRAY;
+
+ if (STREQ ("fini_array"))
+ return SHT_FINI_ARRAY;
+
+ return -1;
+#undef STREQ
+}
+
+static unsigned int
+set_regstack (ins, locs, outs, rots)
+ unsigned int ins, locs, outs, rots;
+{
+ /* Size of frame. */
+ unsigned int sof;
+
+ sof = ins + locs + outs;
+ if (sof > 96)
+ {
+ as_bad ("Size of frame exceeds maximum of 96 registers");
+ return 0;
+ }
+ if (rots > sof)
+ {
+ as_warn ("Size of rotating registers exceeds frame size");
+ return 0;
+ }
+ md.in.base = REG_GR + 32;
+ md.loc.base = md.in.base + ins;
+ md.out.base = md.loc.base + locs;
+
+ md.in.num_regs = ins;
+ md.loc.num_regs = locs;
+ md.out.num_regs = outs;
+ md.rot.num_regs = rots;
+ return sof;
+}
+
+void
+ia64_flush_insns ()
+{
+ struct label_fix *lfix;
+ segT saved_seg;
+ subsegT saved_subseg;
+ unw_rec_list *ptr;
+
+ if (!md.last_text_seg)
+ return;
+
+ saved_seg = now_seg;
+ saved_subseg = now_subseg;
+
+ subseg_set (md.last_text_seg, 0);
+
+ while (md.num_slots_in_use > 0)
+ emit_one_bundle (); /* force out queued instructions */
+
+ /* In case there are labels following the last instruction, resolve
+ those now: */
+ for (lfix = CURR_SLOT.label_fixups; lfix; lfix = lfix->next)
+ {
+ S_SET_VALUE (lfix->sym, frag_now_fix ());
+ symbol_set_frag (lfix->sym, frag_now);
+ }
+ CURR_SLOT.label_fixups = 0;
+ for (lfix = CURR_SLOT.tag_fixups; lfix; lfix = lfix->next)
+ {
+ S_SET_VALUE (lfix->sym, frag_now_fix ());
+ symbol_set_frag (lfix->sym, frag_now);
+ }
+ CURR_SLOT.tag_fixups = 0;
+
+ /* In case there are unwind directives following the last instruction,
+ resolve those now. We only handle prologue, body, and endp directives
+ here. Give an error for others. */
+ for (ptr = unwind.current_entry; ptr; ptr = ptr->next)
+ {
+ switch (ptr->r.type)
+ {
+ case prologue:
+ case prologue_gr:
+ case body:
+ case endp:
+ ptr->slot_number = (unsigned long) frag_more (0);
+ ptr->slot_frag = frag_now;
+ break;
+
+ /* Allow any record which doesn't have a "t" field (i.e.,
+ doesn't relate to a particular instruction). */
+ case unwabi:
+ case br_gr:
+ case copy_state:
+ case fr_mem:
+ case frgr_mem:
+ case gr_gr:
+ case gr_mem:
+ case label_state:
+ case rp_br:
+ case spill_base:
+ case spill_mask:
+ /* nothing */
+ break;
+
+ default:
+ as_bad (_("Unwind directive not followed by an instruction."));
+ break;
+ }
+ }
+ unwind.current_entry = NULL;
+
+ subseg_set (saved_seg, saved_subseg);
+
+ if (md.qp.X_op == O_register)
+ as_bad ("qualifying predicate not followed by instruction");
+}
+
+static void
+ia64_do_align (int nbytes)
+{
+ char *saved_input_line_pointer = input_line_pointer;
+
+ input_line_pointer = "";
+ s_align_bytes (nbytes);
+ input_line_pointer = saved_input_line_pointer;
+}
+
+void
+ia64_cons_align (nbytes)
+ int nbytes;
+{
+ if (md.auto_align)
+ {
+ char *saved_input_line_pointer = input_line_pointer;
+ input_line_pointer = "";
+ s_align_bytes (nbytes);
+ input_line_pointer = saved_input_line_pointer;
+ }
+}
+
+/* Output COUNT bytes to a memory location. */
+static unsigned char *vbyte_mem_ptr = NULL;
+
+void
+output_vbyte_mem (count, ptr, comment)
+ int count;
+ char *ptr;
+ char *comment ATTRIBUTE_UNUSED;
+{
+ int x;
+ if (vbyte_mem_ptr == NULL)
+ abort ();
+
+ if (count == 0)
+ return;
+ for (x = 0; x < count; x++)
+ *(vbyte_mem_ptr++) = ptr[x];
+}
+
+/* Count the number of bytes required for records. */
+static int vbyte_count = 0;
+void
+count_output (count, ptr, comment)
+ int count;
+ char *ptr ATTRIBUTE_UNUSED;
+ char *comment ATTRIBUTE_UNUSED;
+{
+ vbyte_count += count;
+}
+
+static void
+output_R1_format (f, rtype, rlen)
+ vbyte_func f;
+ unw_record_type rtype;
+ int rlen;
+{
+ int r = 0;
+ char byte;
+ if (rlen > 0x1f)
+ {
+ output_R3_format (f, rtype, rlen);
+ return;
+ }
+
+ if (rtype == body)
+ r = 1;
+ else if (rtype != prologue)
+ as_bad ("record type is not valid");
+
+ byte = UNW_R1 | (r << 5) | (rlen & 0x1f);
+ (*f) (1, &byte, NULL);
+}
+
+static void
+output_R2_format (f, mask, grsave, rlen)
+ vbyte_func f;
+ int mask, grsave;
+ unsigned long rlen;
+{
+ char bytes[20];
+ int count = 2;
+ mask = (mask & 0x0f);
+ grsave = (grsave & 0x7f);
+
+ bytes[0] = (UNW_R2 | (mask >> 1));
+ bytes[1] = (((mask & 0x01) << 7) | grsave);
+ count += output_leb128 (bytes + 2, rlen, 0);
+ (*f) (count, bytes, NULL);
+}
+
+static void
+output_R3_format (f, rtype, rlen)
+ vbyte_func f;
+ unw_record_type rtype;
+ unsigned long rlen;
+{
+ int r = 0, count;
+ char bytes[20];
+ if (rlen <= 0x1f)
+ {
+ output_R1_format (f, rtype, rlen);
+ return;
+ }
+
+ if (rtype == body)
+ r = 1;
+ else if (rtype != prologue)
+ as_bad ("record type is not valid");
+ bytes[0] = (UNW_R3 | r);
+ count = output_leb128 (bytes + 1, rlen, 0);
+ (*f) (count + 1, bytes, NULL);
+}
+
+static void
+output_P1_format (f, brmask)
+ vbyte_func f;
+ int brmask;
+{
+ char byte;
+ byte = UNW_P1 | (brmask & 0x1f);
+ (*f) (1, &byte, NULL);
+}
+
+static void
+output_P2_format (f, brmask, gr)
+ vbyte_func f;
+ int brmask;
+ int gr;
+{
+ char bytes[2];
+ brmask = (brmask & 0x1f);
+ bytes[0] = UNW_P2 | (brmask >> 1);
+ bytes[1] = (((brmask & 1) << 7) | gr);
+ (*f) (2, bytes, NULL);
+}
+
+static void
+output_P3_format (f, rtype, reg)
+ vbyte_func f;
+ unw_record_type rtype;
+ int reg;
+{
+ char bytes[2];
+ int r = 0;
+ reg = (reg & 0x7f);
+ switch (rtype)
+ {
+ case psp_gr:
+ r = 0;
+ break;
+ case rp_gr:
+ r = 1;
+ break;
+ case pfs_gr:
+ r = 2;
+ break;
+ case preds_gr:
+ r = 3;
+ break;
+ case unat_gr:
+ r = 4;
+ break;
+ case lc_gr:
+ r = 5;
+ break;
+ case rp_br:
+ r = 6;
+ break;
+ case rnat_gr:
+ r = 7;
+ break;
+ case bsp_gr:
+ r = 8;
+ break;
+ case bspstore_gr:
+ r = 9;
+ break;
+ case fpsr_gr:
+ r = 10;
+ break;
+ case priunat_gr:
+ r = 11;
+ break;
+ default:
+ as_bad ("Invalid record type for P3 format.");
+ }
+ bytes[0] = (UNW_P3 | (r >> 1));
+ bytes[1] = (((r & 1) << 7) | reg);
+ (*f) (2, bytes, NULL);
+}
+
+static void
+output_P4_format (f, imask, imask_size)
+ vbyte_func f;
+ unsigned char *imask;
+ unsigned long imask_size;
+{
+ imask[0] = UNW_P4;
+ (*f) (imask_size, imask, NULL);
+}
+
+static void
+output_P5_format (f, grmask, frmask)
+ vbyte_func f;
+ int grmask;
+ unsigned long frmask;
+{
+ char bytes[4];
+ grmask = (grmask & 0x0f);
+
+ bytes[0] = UNW_P5;
+ bytes[1] = ((grmask << 4) | ((frmask & 0x000f0000) >> 16));
+ bytes[2] = ((frmask & 0x0000ff00) >> 8);
+ bytes[3] = (frmask & 0x000000ff);
+ (*f) (4, bytes, NULL);
+}
+
+static void
+output_P6_format (f, rtype, rmask)
+ vbyte_func f;
+ unw_record_type rtype;
+ int rmask;
+{
+ char byte;
+ int r = 0;
+
+ if (rtype == gr_mem)
+ r = 1;
+ else if (rtype != fr_mem)
+ as_bad ("Invalid record type for format P6");
+ byte = (UNW_P6 | (r << 4) | (rmask & 0x0f));
+ (*f) (1, &byte, NULL);
+}
+
+static void
+output_P7_format (f, rtype, w1, w2)
+ vbyte_func f;
+ unw_record_type rtype;
+ unsigned long w1;
+ unsigned long w2;
+{
+ char bytes[20];
+ int count = 1;
+ int r = 0;
+ count += output_leb128 (bytes + 1, w1, 0);
+ switch (rtype)
+ {
+ case mem_stack_f:
+ r = 0;
+ count += output_leb128 (bytes + count, w2 >> 4, 0);
+ break;
+ case mem_stack_v:
+ r = 1;
+ break;
+ case spill_base:
+ r = 2;
+ break;
+ case psp_sprel:
+ r = 3;
+ break;
+ case rp_when:
+ r = 4;
+ break;
+ case rp_psprel:
+ r = 5;
+ break;
+ case pfs_when:
+ r = 6;
+ break;
+ case pfs_psprel:
+ r = 7;
+ break;
+ case preds_when:
+ r = 8;
+ break;
+ case preds_psprel:
+ r = 9;
+ break;
+ case lc_when:
+ r = 10;
+ break;
+ case lc_psprel:
+ r = 11;
+ break;
+ case unat_when:
+ r = 12;
+ break;
+ case unat_psprel:
+ r = 13;
+ break;
+ case fpsr_when:
+ r = 14;
+ break;
+ case fpsr_psprel:
+ r = 15;
+ break;
+ default:
+ break;
+ }
+ bytes[0] = (UNW_P7 | r);
+ (*f) (count, bytes, NULL);
+}
+
+static void
+output_P8_format (f, rtype, t)
+ vbyte_func f;
+ unw_record_type rtype;
+ unsigned long t;
+{
+ char bytes[20];
+ int r = 0;
+ int count = 2;
+ bytes[0] = UNW_P8;
+ switch (rtype)
+ {
+ case rp_sprel:
+ r = 1;
+ break;
+ case pfs_sprel:
+ r = 2;
+ break;
+ case preds_sprel:
+ r = 3;
+ break;
+ case lc_sprel:
+ r = 4;
+ break;
+ case unat_sprel:
+ r = 5;
+ break;
+ case fpsr_sprel:
+ r = 6;
+ break;
+ case bsp_when:
+ r = 7;
+ break;
+ case bsp_psprel:
+ r = 8;
+ break;
+ case bsp_sprel:
+ r = 9;
+ break;
+ case bspstore_when:
+ r = 10;
+ break;
+ case bspstore_psprel:
+ r = 11;
+ break;
+ case bspstore_sprel:
+ r = 12;
+ break;
+ case rnat_when:
+ r = 13;
+ break;
+ case rnat_psprel:
+ r = 14;
+ break;
+ case rnat_sprel:
+ r = 15;
+ break;
+ case priunat_when_gr:
+ r = 16;
+ break;
+ case priunat_psprel:
+ r = 17;
+ break;
+ case priunat_sprel:
+ r = 18;
+ break;
+ case priunat_when_mem:
+ r = 19;
+ break;
+ default:
+ break;
+ }
+ bytes[1] = r;
+ count += output_leb128 (bytes + 2, t, 0);
+ (*f) (count, bytes, NULL);
+}
+
+static void
+output_P9_format (f, grmask, gr)
+ vbyte_func f;
+ int grmask;
+ int gr;
+{
+ char bytes[3];
+ bytes[0] = UNW_P9;
+ bytes[1] = (grmask & 0x0f);
+ bytes[2] = (gr & 0x7f);
+ (*f) (3, bytes, NULL);
+}
+
+static void
+output_P10_format (f, abi, context)
+ vbyte_func f;
+ int abi;
+ int context;
+{
+ char bytes[3];
+ bytes[0] = UNW_P10;
+ bytes[1] = (abi & 0xff);
+ bytes[2] = (context & 0xff);
+ (*f) (3, bytes, NULL);
+}
+
+static void
+output_B1_format (f, rtype, label)
+ vbyte_func f;
+ unw_record_type rtype;
+ unsigned long label;
+{
+ char byte;
+ int r = 0;
+ if (label > 0x1f)
+ {
+ output_B4_format (f, rtype, label);
+ return;
+ }
+ if (rtype == copy_state)
+ r = 1;
+ else if (rtype != label_state)
+ as_bad ("Invalid record type for format B1");
+
+ byte = (UNW_B1 | (r << 5) | (label & 0x1f));
+ (*f) (1, &byte, NULL);
+}
+
+static void
+output_B2_format (f, ecount, t)
+ vbyte_func f;
+ unsigned long ecount;
+ unsigned long t;
+{
+ char bytes[20];
+ int count = 1;
+ if (ecount > 0x1f)
+ {
+ output_B3_format (f, ecount, t);
+ return;
+ }
+ bytes[0] = (UNW_B2 | (ecount & 0x1f));
+ count += output_leb128 (bytes + 1, t, 0);
+ (*f) (count, bytes, NULL);
+}
+
+static void
+output_B3_format (f, ecount, t)
+ vbyte_func f;
+ unsigned long ecount;
+ unsigned long t;
+{
+ char bytes[20];
+ int count = 1;
+ if (ecount <= 0x1f)
+ {
+ output_B2_format (f, ecount, t);
+ return;
+ }
+ bytes[0] = UNW_B3;
+ count += output_leb128 (bytes + 1, t, 0);
+ count += output_leb128 (bytes + count, ecount, 0);
+ (*f) (count, bytes, NULL);
+}
+
+static void
+output_B4_format (f, rtype, label)
+ vbyte_func f;
+ unw_record_type rtype;
+ unsigned long label;
+{
+ char bytes[20];
+ int r = 0;
+ int count = 1;
+ if (label <= 0x1f)
+ {
+ output_B1_format (f, rtype, label);
+ return;
+ }
+
+ if (rtype == copy_state)
+ r = 1;
+ else if (rtype != label_state)
+ as_bad ("Invalid record type for format B1");
+
+ bytes[0] = (UNW_B4 | (r << 3));
+ count += output_leb128 (bytes + 1, label, 0);
+ (*f) (count, bytes, NULL);
+}
+
+static char
+format_ab_reg (ab, reg)
+ int ab;
+ int reg;
+{
+ int ret;
+ ab = (ab & 3);
+ reg = (reg & 0x1f);
+ ret = (ab << 5) | reg;
+ return ret;
+}
+
+static void
+output_X1_format (f, rtype, ab, reg, t, w1)
+ vbyte_func f;
+ unw_record_type rtype;
+ int ab, reg;
+ unsigned long t;
+ unsigned long w1;
+{
+ char bytes[20];
+ int r = 0;
+ int count = 2;
+ bytes[0] = UNW_X1;
+
+ if (rtype == spill_sprel)
+ r = 1;
+ else if (rtype != spill_psprel)
+ as_bad ("Invalid record type for format X1");
+ bytes[1] = ((r << 7) | format_ab_reg (ab, reg));
+ count += output_leb128 (bytes + 2, t, 0);
+ count += output_leb128 (bytes + count, w1, 0);
+ (*f) (count, bytes, NULL);
+}
+
+static void
+output_X2_format (f, ab, reg, x, y, treg, t)
+ vbyte_func f;
+ int ab, reg;
+ int x, y, treg;
+ unsigned long t;
+{
+ char bytes[20];
+ int count = 3;
+ bytes[0] = UNW_X2;
+ bytes[1] = (((x & 1) << 7) | format_ab_reg (ab, reg));
+ bytes[2] = (((y & 1) << 7) | (treg & 0x7f));
+ count += output_leb128 (bytes + 3, t, 0);
+ (*f) (count, bytes, NULL);
+}
+
+static void
+output_X3_format (f, rtype, qp, ab, reg, t, w1)
+ vbyte_func f;
+ unw_record_type rtype;
+ int qp;
+ int ab, reg;
+ unsigned long t;
+ unsigned long w1;
+{
+ char bytes[20];
+ int r = 0;
+ int count = 3;
+ bytes[0] = UNW_X3;
+
+ if (rtype == spill_sprel_p)
+ r = 1;
+ else if (rtype != spill_psprel_p)
+ as_bad ("Invalid record type for format X3");
+ bytes[1] = ((r << 7) | (qp & 0x3f));
+ bytes[2] = format_ab_reg (ab, reg);
+ count += output_leb128 (bytes + 3, t, 0);
+ count += output_leb128 (bytes + count, w1, 0);
+ (*f) (count, bytes, NULL);
+}
+
+static void
+output_X4_format (f, qp, ab, reg, x, y, treg, t)
+ vbyte_func f;
+ int qp;
+ int ab, reg;
+ int x, y, treg;
+ unsigned long t;
+{
+ char bytes[20];
+ int count = 4;
+ bytes[0] = UNW_X4;
+ bytes[1] = (qp & 0x3f);
+ bytes[2] = (((x & 1) << 7) | format_ab_reg (ab, reg));
+ bytes[3] = (((y & 1) << 7) | (treg & 0x7f));
+ count += output_leb128 (bytes + 4, t, 0);
+ (*f) (count, bytes, NULL);
+}
+
+/* This function allocates a record list structure, and initializes fields. */
+
+static unw_rec_list *
+alloc_record (unw_record_type t)
+{
+ unw_rec_list *ptr;
+ ptr = xmalloc (sizeof (*ptr));
+ ptr->next = NULL;
+ ptr->slot_number = SLOT_NUM_NOT_SET;
+ ptr->r.type = t;
+ ptr->next_slot_number = 0;
+ ptr->next_slot_frag = 0;
+ return ptr;
+}
+
+/* Dummy unwind record used for calculating the length of the last prologue or
+ body region. */
+
+static unw_rec_list *
+output_endp ()
+{
+ unw_rec_list *ptr = alloc_record (endp);
+ return ptr;
+}
+
+static unw_rec_list *
+output_prologue ()
+{
+ unw_rec_list *ptr = alloc_record (prologue);
+ memset (&ptr->r.record.r.mask, 0, sizeof (ptr->r.record.r.mask));
+ return ptr;
+}
+
+static unw_rec_list *
+output_prologue_gr (saved_mask, reg)
+ unsigned int saved_mask;
+ unsigned int reg;
+{
+ unw_rec_list *ptr = alloc_record (prologue_gr);
+ memset (&ptr->r.record.r.mask, 0, sizeof (ptr->r.record.r.mask));
+ ptr->r.record.r.grmask = saved_mask;
+ ptr->r.record.r.grsave = reg;
+ return ptr;
+}
+
+static unw_rec_list *
+output_body ()
+{
+ unw_rec_list *ptr = alloc_record (body);
+ return ptr;
+}
+
+static unw_rec_list *
+output_mem_stack_f (size)
+ unsigned int size;
+{
+ unw_rec_list *ptr = alloc_record (mem_stack_f);
+ ptr->r.record.p.size = size;
+ return ptr;
+}
+
+static unw_rec_list *
+output_mem_stack_v ()
+{
+ unw_rec_list *ptr = alloc_record (mem_stack_v);
+ return ptr;
+}
+
+static unw_rec_list *
+output_psp_gr (gr)
+ unsigned int gr;
+{
+ unw_rec_list *ptr = alloc_record (psp_gr);
+ ptr->r.record.p.gr = gr;
+ return ptr;
+}
+
+static unw_rec_list *
+output_psp_sprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (psp_sprel);
+ ptr->r.record.p.spoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_rp_when ()
+{
+ unw_rec_list *ptr = alloc_record (rp_when);
+ return ptr;
+}
+
+static unw_rec_list *
+output_rp_gr (gr)
+ unsigned int gr;
+{
+ unw_rec_list *ptr = alloc_record (rp_gr);
+ ptr->r.record.p.gr = gr;
+ return ptr;
+}
+
+static unw_rec_list *
+output_rp_br (br)
+ unsigned int br;
+{
+ unw_rec_list *ptr = alloc_record (rp_br);
+ ptr->r.record.p.br = br;
+ return ptr;
+}
+
+static unw_rec_list *
+output_rp_psprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (rp_psprel);
+ ptr->r.record.p.pspoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_rp_sprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (rp_sprel);
+ ptr->r.record.p.spoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_pfs_when ()
+{
+ unw_rec_list *ptr = alloc_record (pfs_when);
+ return ptr;
+}
+
+static unw_rec_list *
+output_pfs_gr (gr)
+ unsigned int gr;
+{
+ unw_rec_list *ptr = alloc_record (pfs_gr);
+ ptr->r.record.p.gr = gr;
+ return ptr;
+}
+
+static unw_rec_list *
+output_pfs_psprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (pfs_psprel);
+ ptr->r.record.p.pspoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_pfs_sprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (pfs_sprel);
+ ptr->r.record.p.spoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_preds_when ()
+{
+ unw_rec_list *ptr = alloc_record (preds_when);
+ return ptr;
+}
+
+static unw_rec_list *
+output_preds_gr (gr)
+ unsigned int gr;
+{
+ unw_rec_list *ptr = alloc_record (preds_gr);
+ ptr->r.record.p.gr = gr;
+ return ptr;
+}
+
+static unw_rec_list *
+output_preds_psprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (preds_psprel);
+ ptr->r.record.p.pspoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_preds_sprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (preds_sprel);
+ ptr->r.record.p.spoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_fr_mem (mask)
+ unsigned int mask;
+{
+ unw_rec_list *ptr = alloc_record (fr_mem);
+ ptr->r.record.p.rmask = mask;
+ return ptr;
+}
+
+static unw_rec_list *
+output_frgr_mem (gr_mask, fr_mask)
+ unsigned int gr_mask;
+ unsigned int fr_mask;
+{
+ unw_rec_list *ptr = alloc_record (frgr_mem);
+ ptr->r.record.p.grmask = gr_mask;
+ ptr->r.record.p.frmask = fr_mask;
+ return ptr;
+}
+
+static unw_rec_list *
+output_gr_gr (mask, reg)
+ unsigned int mask;
+ unsigned int reg;
+{
+ unw_rec_list *ptr = alloc_record (gr_gr);
+ ptr->r.record.p.grmask = mask;
+ ptr->r.record.p.gr = reg;
+ return ptr;
+}
+
+static unw_rec_list *
+output_gr_mem (mask)
+ unsigned int mask;
+{
+ unw_rec_list *ptr = alloc_record (gr_mem);
+ ptr->r.record.p.rmask = mask;
+ return ptr;
+}
+
+static unw_rec_list *
+output_br_mem (unsigned int mask)
+{
+ unw_rec_list *ptr = alloc_record (br_mem);
+ ptr->r.record.p.brmask = mask;
+ return ptr;
+}
+
+static unw_rec_list *
+output_br_gr (save_mask, reg)
+ unsigned int save_mask;
+ unsigned int reg;
+{
+ unw_rec_list *ptr = alloc_record (br_gr);
+ ptr->r.record.p.brmask = save_mask;
+ ptr->r.record.p.gr = reg;
+ return ptr;
+}
+
+static unw_rec_list *
+output_spill_base (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (spill_base);
+ ptr->r.record.p.pspoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_unat_when ()
+{
+ unw_rec_list *ptr = alloc_record (unat_when);
+ return ptr;
+}
+
+static unw_rec_list *
+output_unat_gr (gr)
+ unsigned int gr;
+{
+ unw_rec_list *ptr = alloc_record (unat_gr);
+ ptr->r.record.p.gr = gr;
+ return ptr;
+}
+
+static unw_rec_list *
+output_unat_psprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (unat_psprel);
+ ptr->r.record.p.pspoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_unat_sprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (unat_sprel);
+ ptr->r.record.p.spoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_lc_when ()
+{
+ unw_rec_list *ptr = alloc_record (lc_when);
+ return ptr;
+}
+
+static unw_rec_list *
+output_lc_gr (gr)
+ unsigned int gr;
+{
+ unw_rec_list *ptr = alloc_record (lc_gr);
+ ptr->r.record.p.gr = gr;
+ return ptr;
+}
+
+static unw_rec_list *
+output_lc_psprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (lc_psprel);
+ ptr->r.record.p.pspoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_lc_sprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (lc_sprel);
+ ptr->r.record.p.spoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_fpsr_when ()
+{
+ unw_rec_list *ptr = alloc_record (fpsr_when);
+ return ptr;
+}
+
+static unw_rec_list *
+output_fpsr_gr (gr)
+ unsigned int gr;
+{
+ unw_rec_list *ptr = alloc_record (fpsr_gr);
+ ptr->r.record.p.gr = gr;
+ return ptr;
+}
+
+static unw_rec_list *
+output_fpsr_psprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (fpsr_psprel);
+ ptr->r.record.p.pspoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_fpsr_sprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (fpsr_sprel);
+ ptr->r.record.p.spoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_priunat_when_gr ()
+{
+ unw_rec_list *ptr = alloc_record (priunat_when_gr);
+ return ptr;
+}
+
+static unw_rec_list *
+output_priunat_when_mem ()
+{
+ unw_rec_list *ptr = alloc_record (priunat_when_mem);
+ return ptr;
+}
+
+static unw_rec_list *
+output_priunat_gr (gr)
+ unsigned int gr;
+{
+ unw_rec_list *ptr = alloc_record (priunat_gr);
+ ptr->r.record.p.gr = gr;
+ return ptr;
+}
+
+static unw_rec_list *
+output_priunat_psprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (priunat_psprel);
+ ptr->r.record.p.pspoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_priunat_sprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (priunat_sprel);
+ ptr->r.record.p.spoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_bsp_when ()
+{
+ unw_rec_list *ptr = alloc_record (bsp_when);
+ return ptr;
+}
+
+static unw_rec_list *
+output_bsp_gr (gr)
+ unsigned int gr;
+{
+ unw_rec_list *ptr = alloc_record (bsp_gr);
+ ptr->r.record.p.gr = gr;
+ return ptr;
+}
+
+static unw_rec_list *
+output_bsp_psprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (bsp_psprel);
+ ptr->r.record.p.pspoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_bsp_sprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (bsp_sprel);
+ ptr->r.record.p.spoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_bspstore_when ()
+{
+ unw_rec_list *ptr = alloc_record (bspstore_when);
+ return ptr;
+}
+
+static unw_rec_list *
+output_bspstore_gr (gr)
+ unsigned int gr;
+{
+ unw_rec_list *ptr = alloc_record (bspstore_gr);
+ ptr->r.record.p.gr = gr;
+ return ptr;
+}
+
+static unw_rec_list *
+output_bspstore_psprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (bspstore_psprel);
+ ptr->r.record.p.pspoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_bspstore_sprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (bspstore_sprel);
+ ptr->r.record.p.spoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_rnat_when ()
+{
+ unw_rec_list *ptr = alloc_record (rnat_when);
+ return ptr;
+}
+
+static unw_rec_list *
+output_rnat_gr (gr)
+ unsigned int gr;
+{
+ unw_rec_list *ptr = alloc_record (rnat_gr);
+ ptr->r.record.p.gr = gr;
+ return ptr;
+}
+
+static unw_rec_list *
+output_rnat_psprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (rnat_psprel);
+ ptr->r.record.p.pspoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_rnat_sprel (offset)
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (rnat_sprel);
+ ptr->r.record.p.spoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_unwabi (abi, context)
+ unsigned long abi;
+ unsigned long context;
+{
+ unw_rec_list *ptr = alloc_record (unwabi);
+ ptr->r.record.p.abi = abi;
+ ptr->r.record.p.context = context;
+ return ptr;
+}
+
+static unw_rec_list *
+output_epilogue (unsigned long ecount)
+{
+ unw_rec_list *ptr = alloc_record (epilogue);
+ ptr->r.record.b.ecount = ecount;
+ return ptr;
+}
+
+static unw_rec_list *
+output_label_state (unsigned long label)
+{
+ unw_rec_list *ptr = alloc_record (label_state);
+ ptr->r.record.b.label = label;
+ return ptr;
+}
+
+static unw_rec_list *
+output_copy_state (unsigned long label)
+{
+ unw_rec_list *ptr = alloc_record (copy_state);
+ ptr->r.record.b.label = label;
+ return ptr;
+}
+
+static unw_rec_list *
+output_spill_psprel (ab, reg, offset)
+ unsigned int ab;
+ unsigned int reg;
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (spill_psprel);
+ ptr->r.record.x.ab = ab;
+ ptr->r.record.x.reg = reg;
+ ptr->r.record.x.pspoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_spill_sprel (ab, reg, offset)
+ unsigned int ab;
+ unsigned int reg;
+ unsigned int offset;
+{
+ unw_rec_list *ptr = alloc_record (spill_sprel);
+ ptr->r.record.x.ab = ab;
+ ptr->r.record.x.reg = reg;
+ ptr->r.record.x.spoff = offset / 4;
+ return ptr;
+}
+
+static unw_rec_list *
+output_spill_psprel_p (ab, reg, offset, predicate)
+ unsigned int ab;
+ unsigned int reg;
+ unsigned int offset;
+ unsigned int predicate;
+{
+ unw_rec_list *ptr = alloc_record (spill_psprel_p);
+ ptr->r.record.x.ab = ab;
+ ptr->r.record.x.reg = reg;
+ ptr->r.record.x.pspoff = offset / 4;
+ ptr->r.record.x.qp = predicate;
+ return ptr;
+}
+
+static unw_rec_list *
+output_spill_sprel_p (ab, reg, offset, predicate)
+ unsigned int ab;
+ unsigned int reg;
+ unsigned int offset;
+ unsigned int predicate;
+{
+ unw_rec_list *ptr = alloc_record (spill_sprel_p);
+ ptr->r.record.x.ab = ab;
+ ptr->r.record.x.reg = reg;
+ ptr->r.record.x.spoff = offset / 4;
+ ptr->r.record.x.qp = predicate;
+ return ptr;
+}
+
+static unw_rec_list *
+output_spill_reg (ab, reg, targ_reg, xy)
+ unsigned int ab;
+ unsigned int reg;
+ unsigned int targ_reg;
+ unsigned int xy;
+{
+ unw_rec_list *ptr = alloc_record (spill_reg);
+ ptr->r.record.x.ab = ab;
+ ptr->r.record.x.reg = reg;
+ ptr->r.record.x.treg = targ_reg;
+ ptr->r.record.x.xy = xy;
+ return ptr;
+}
+
+static unw_rec_list *
+output_spill_reg_p (ab, reg, targ_reg, xy, predicate)
+ unsigned int ab;
+ unsigned int reg;
+ unsigned int targ_reg;
+ unsigned int xy;
+ unsigned int predicate;
+{
+ unw_rec_list *ptr = alloc_record (spill_reg_p);
+ ptr->r.record.x.ab = ab;
+ ptr->r.record.x.reg = reg;
+ ptr->r.record.x.treg = targ_reg;
+ ptr->r.record.x.xy = xy;
+ ptr->r.record.x.qp = predicate;
+ return ptr;
+}
+
+/* Given a unw_rec_list process the correct format with the
+ specified function. */
+
+static void
+process_one_record (ptr, f)
+ unw_rec_list *ptr;
+ vbyte_func f;
+{
+ unsigned long fr_mask, gr_mask;
+
+ switch (ptr->r.type)
+ {
+ /* This is a dummy record that takes up no space in the output. */
+ case endp:
+ break;
+
+ case gr_mem:
+ case fr_mem:
+ case br_mem:
+ case frgr_mem:
+ /* These are taken care of by prologue/prologue_gr. */
+ break;
+
+ case prologue_gr:
+ case prologue:
+ if (ptr->r.type == prologue_gr)
+ output_R2_format (f, ptr->r.record.r.grmask,
+ ptr->r.record.r.grsave, ptr->r.record.r.rlen);
+ else
+ output_R1_format (f, ptr->r.type, ptr->r.record.r.rlen);
+
+ /* Output descriptor(s) for union of register spills (if any). */
+ gr_mask = ptr->r.record.r.mask.gr_mem;
+ fr_mask = ptr->r.record.r.mask.fr_mem;
+ if (fr_mask)
+ {
+ if ((fr_mask & ~0xfUL) == 0)
+ output_P6_format (f, fr_mem, fr_mask);
+ else
+ {
+ output_P5_format (f, gr_mask, fr_mask);
+ gr_mask = 0;
+ }
+ }
+ if (gr_mask)
+ output_P6_format (f, gr_mem, gr_mask);
+ if (ptr->r.record.r.mask.br_mem)
+ output_P1_format (f, ptr->r.record.r.mask.br_mem);
+
+ /* output imask descriptor if necessary: */
+ if (ptr->r.record.r.mask.i)
+ output_P4_format (f, ptr->r.record.r.mask.i,
+ ptr->r.record.r.imask_size);
+ break;
+
+ case body:
+ output_R1_format (f, ptr->r.type, ptr->r.record.r.rlen);
+ break;
+ case mem_stack_f:
+ case mem_stack_v:
+ output_P7_format (f, ptr->r.type, ptr->r.record.p.t,
+ ptr->r.record.p.size);
+ break;
+ case psp_gr:
+ case rp_gr:
+ case pfs_gr:
+ case preds_gr:
+ case unat_gr:
+ case lc_gr:
+ case fpsr_gr:
+ case priunat_gr:
+ case bsp_gr:
+ case bspstore_gr:
+ case rnat_gr:
+ output_P3_format (f, ptr->r.type, ptr->r.record.p.gr);
+ break;
+ case rp_br:
+ output_P3_format (f, rp_br, ptr->r.record.p.br);
+ break;
+ case psp_sprel:
+ output_P7_format (f, psp_sprel, ptr->r.record.p.spoff, 0);
+ break;
+ case rp_when:
+ case pfs_when:
+ case preds_when:
+ case unat_when:
+ case lc_when:
+ case fpsr_when:
+ output_P7_format (f, ptr->r.type, ptr->r.record.p.t, 0);
+ break;
+ case rp_psprel:
+ case pfs_psprel:
+ case preds_psprel:
+ case unat_psprel:
+ case lc_psprel:
+ case fpsr_psprel:
+ case spill_base:
+ output_P7_format (f, ptr->r.type, ptr->r.record.p.pspoff, 0);
+ break;
+ case rp_sprel:
+ case pfs_sprel:
+ case preds_sprel:
+ case unat_sprel:
+ case lc_sprel:
+ case fpsr_sprel:
+ case priunat_sprel:
+ case bsp_sprel:
+ case bspstore_sprel:
+ case rnat_sprel:
+ output_P8_format (f, ptr->r.type, ptr->r.record.p.spoff);
+ break;
+ case gr_gr:
+ output_P9_format (f, ptr->r.record.p.grmask, ptr->r.record.p.gr);
+ break;
+ case br_gr:
+ output_P2_format (f, ptr->r.record.p.brmask, ptr->r.record.p.gr);
+ break;
+ case spill_mask:
+ as_bad ("spill_mask record unimplemented.");
+ break;
+ case priunat_when_gr:
+ case priunat_when_mem:
+ case bsp_when:
+ case bspstore_when:
+ case rnat_when:
+ output_P8_format (f, ptr->r.type, ptr->r.record.p.t);
+ break;
+ case priunat_psprel:
+ case bsp_psprel:
+ case bspstore_psprel:
+ case rnat_psprel:
+ output_P8_format (f, ptr->r.type, ptr->r.record.p.pspoff);
+ break;
+ case unwabi:
+ output_P10_format (f, ptr->r.record.p.abi, ptr->r.record.p.context);
+ break;
+ case epilogue:
+ output_B3_format (f, ptr->r.record.b.ecount, ptr->r.record.b.t);
+ break;
+ case label_state:
+ case copy_state:
+ output_B4_format (f, ptr->r.type, ptr->r.record.b.label);
+ break;
+ case spill_psprel:
+ output_X1_format (f, ptr->r.type, ptr->r.record.x.ab,
+ ptr->r.record.x.reg, ptr->r.record.x.t,
+ ptr->r.record.x.pspoff);
+ break;
+ case spill_sprel:
+ output_X1_format (f, ptr->r.type, ptr->r.record.x.ab,
+ ptr->r.record.x.reg, ptr->r.record.x.t,
+ ptr->r.record.x.spoff);
+ break;
+ case spill_reg:
+ output_X2_format (f, ptr->r.record.x.ab, ptr->r.record.x.reg,
+ ptr->r.record.x.xy >> 1, ptr->r.record.x.xy,
+ ptr->r.record.x.treg, ptr->r.record.x.t);
+ break;
+ case spill_psprel_p:
+ output_X3_format (f, ptr->r.type, ptr->r.record.x.qp,
+ ptr->r.record.x.ab, ptr->r.record.x.reg,
+ ptr->r.record.x.t, ptr->r.record.x.pspoff);
+ break;
+ case spill_sprel_p:
+ output_X3_format (f, ptr->r.type, ptr->r.record.x.qp,
+ ptr->r.record.x.ab, ptr->r.record.x.reg,
+ ptr->r.record.x.t, ptr->r.record.x.spoff);
+ break;
+ case spill_reg_p:
+ output_X4_format (f, ptr->r.record.x.qp, ptr->r.record.x.ab,
+ ptr->r.record.x.reg, ptr->r.record.x.xy >> 1,
+ ptr->r.record.x.xy, ptr->r.record.x.treg,
+ ptr->r.record.x.t);
+ break;
+ default:
+ as_bad ("record_type_not_valid");
+ break;
+ }
+}
+
+/* Given a unw_rec_list list, process all the records with
+ the specified function. */
+static void
+process_unw_records (list, f)
+ unw_rec_list *list;
+ vbyte_func f;
+{
+ unw_rec_list *ptr;
+ for (ptr = list; ptr; ptr = ptr->next)
+ process_one_record (ptr, f);
+}
+
+/* Determine the size of a record list in bytes. */
+static int
+calc_record_size (list)
+ unw_rec_list *list;
+{
+ vbyte_count = 0;
+ process_unw_records (list, count_output);
+ return vbyte_count;
+}
+
+/* Update IMASK bitmask to reflect the fact that one or more registers
+ of type TYPE are saved starting at instruction with index T. If N
+ bits are set in REGMASK, it is assumed that instructions T through
+ T+N-1 save these registers.
+
+ TYPE values:
+ 0: no save
+ 1: instruction saves next fp reg
+ 2: instruction saves next general reg
+ 3: instruction saves next branch reg */
+static void
+set_imask (region, regmask, t, type)
+ unw_rec_list *region;
+ unsigned long regmask;
+ unsigned long t;
+ unsigned int type;
+{
+ unsigned char *imask;
+ unsigned long imask_size;
+ unsigned int i;
+ int pos;
+
+ imask = region->r.record.r.mask.i;
+ imask_size = region->r.record.r.imask_size;
+ if (!imask)
+ {
+ imask_size = (region->r.record.r.rlen * 2 + 7) / 8 + 1;
+ imask = xmalloc (imask_size);
+ memset (imask, 0, imask_size);
+
+ region->r.record.r.imask_size = imask_size;
+ region->r.record.r.mask.i = imask;
+ }
+
+ i = (t / 4) + 1;
+ pos = 2 * (3 - t % 4);
+ while (regmask)
+ {
+ if (i >= imask_size)
+ {
+ as_bad ("Ignoring attempt to spill beyond end of region");
+ return;
+ }
+
+ imask[i] |= (type & 0x3) << pos;
+
+ regmask &= (regmask - 1);
+ pos -= 2;
+ if (pos < 0)
+ {
+ pos = 0;
+ ++i;
+ }
+ }
+}
+
+/* Return the number of instruction slots from FIRST_ADDR to SLOT_ADDR.
+ SLOT_FRAG is the frag containing SLOT_ADDR, and FIRST_FRAG is the frag
+ containing FIRST_ADDR. If BEFORE_RELAX, then we use worst-case estimates
+ for frag sizes. */
+
+unsigned long
+slot_index (slot_addr, slot_frag, first_addr, first_frag, before_relax)
+ unsigned long slot_addr;
+ fragS *slot_frag;
+ unsigned long first_addr;
+ fragS *first_frag;
+ int before_relax;
+{
+ unsigned long index = 0;
+
+ /* First time we are called, the initial address and frag are invalid. */
+ if (first_addr == 0)
+ return 0;
+
+ /* If the two addresses are in different frags, then we need to add in
+ the remaining size of this frag, and then the entire size of intermediate
+ frags. */
+ while (slot_frag != first_frag)
+ {
+ unsigned long start_addr = (unsigned long) &first_frag->fr_literal;
+
+ if (! before_relax)
+ {
+ /* We can get the final addresses only during and after
+ relaxation. */
+ if (first_frag->fr_next && first_frag->fr_next->fr_address)
+ index += 3 * ((first_frag->fr_next->fr_address
+ - first_frag->fr_address
+ - first_frag->fr_fix) >> 4);
+ }
+ else
+ /* We don't know what the final addresses will be. We try our
+ best to estimate. */
+ switch (first_frag->fr_type)
+ {
+ default:
+ break;
+
+ case rs_space:
+ as_fatal ("only constant space allocation is supported");
+ break;
+
+ case rs_align:
+ case rs_align_code:
+ case rs_align_test:
+ /* Take alignment into account. Assume the worst case
+ before relaxation. */
+ index += 3 * ((1 << first_frag->fr_offset) >> 4);
+ break;
+
+ case rs_org:
+ if (first_frag->fr_symbol)
+ {
+ as_fatal ("only constant offsets are supported");
+ break;
+ }
+ case rs_fill:
+ index += 3 * (first_frag->fr_offset >> 4);
+ break;
+ }
+
+ /* Add in the full size of the frag converted to instruction slots. */
+ index += 3 * (first_frag->fr_fix >> 4);
+ /* Subtract away the initial part before first_addr. */
+ index -= (3 * ((first_addr >> 4) - (start_addr >> 4))
+ + ((first_addr & 0x3) - (start_addr & 0x3)));
+
+ /* Move to the beginning of the next frag. */
+ first_frag = first_frag->fr_next;
+ first_addr = (unsigned long) &first_frag->fr_literal;
+ }
+
+ /* Add in the used part of the last frag. */
+ index += (3 * ((slot_addr >> 4) - (first_addr >> 4))
+ + ((slot_addr & 0x3) - (first_addr & 0x3)));
+ return index;
+}
+
+/* Optimize unwind record directives. */
+
+static unw_rec_list *
+optimize_unw_records (list)
+ unw_rec_list *list;
+{
+ if (!list)
+ return NULL;
+
+ /* If the only unwind record is ".prologue" or ".prologue" followed
+ by ".body", then we can optimize the unwind directives away. */
+ if (list->r.type == prologue
+ && (list->next->r.type == endp
+ || (list->next->r.type == body && list->next->next->r.type == endp)))
+ return NULL;
+
+ return list;
+}
+
+/* Given a complete record list, process any records which have
+ unresolved fields, (ie length counts for a prologue). After
+ this has been run, all necessary information should be available
+ within each record to generate an image. */
+
+static void
+fixup_unw_records (list, before_relax)
+ unw_rec_list *list;
+ int before_relax;
+{
+ unw_rec_list *ptr, *region = 0;
+ unsigned long first_addr = 0, rlen = 0, t;
+ fragS *first_frag = 0;
+
+ for (ptr = list; ptr; ptr = ptr->next)
+ {
+ if (ptr->slot_number == SLOT_NUM_NOT_SET)
+ as_bad (" Insn slot not set in unwind record.");
+ t = slot_index (ptr->slot_number, ptr->slot_frag,
+ first_addr, first_frag, before_relax);
+ switch (ptr->r.type)
+ {
+ case prologue:
+ case prologue_gr:
+ case body:
+ {
+ unw_rec_list *last;
+ int size;
+ unsigned long last_addr = 0;
+ fragS *last_frag = NULL;
+
+ first_addr = ptr->slot_number;
+ first_frag = ptr->slot_frag;
+ /* Find either the next body/prologue start, or the end of
+ the function, and determine the size of the region. */
+ for (last = ptr->next; last != NULL; last = last->next)
+ if (last->r.type == prologue || last->r.type == prologue_gr
+ || last->r.type == body || last->r.type == endp)
+ {
+ last_addr = last->slot_number;
+ last_frag = last->slot_frag;
+ break;
+ }
+ size = slot_index (last_addr, last_frag, first_addr, first_frag,
+ before_relax);
+ rlen = ptr->r.record.r.rlen = size;
+ if (ptr->r.type == body)
+ /* End of region. */
+ region = 0;
+ else
+ region = ptr;
+ break;
+ }
+ case epilogue:
+ ptr->r.record.b.t = rlen - 1 - t;
+ break;
+
+ case mem_stack_f:
+ case mem_stack_v:
+ case rp_when:
+ case pfs_when:
+ case preds_when:
+ case unat_when:
+ case lc_when:
+ case fpsr_when:
+ case priunat_when_gr:
+ case priunat_when_mem:
+ case bsp_when:
+ case bspstore_when:
+ case rnat_when:
+ ptr->r.record.p.t = t;
+ break;
+
+ case spill_reg:
+ case spill_sprel:
+ case spill_psprel:
+ case spill_reg_p:
+ case spill_sprel_p:
+ case spill_psprel_p:
+ ptr->r.record.x.t = t;
+ break;
+
+ case frgr_mem:
+ if (!region)
+ {
+ as_bad ("frgr_mem record before region record!\n");
+ return;
+ }
+ region->r.record.r.mask.fr_mem |= ptr->r.record.p.frmask;
+ region->r.record.r.mask.gr_mem |= ptr->r.record.p.grmask;
+ set_imask (region, ptr->r.record.p.frmask, t, 1);
+ set_imask (region, ptr->r.record.p.grmask, t, 2);
+ break;
+ case fr_mem:
+ if (!region)
+ {
+ as_bad ("fr_mem record before region record!\n");
+ return;
+ }
+ region->r.record.r.mask.fr_mem |= ptr->r.record.p.rmask;
+ set_imask (region, ptr->r.record.p.rmask, t, 1);
+ break;
+ case gr_mem:
+ if (!region)
+ {
+ as_bad ("gr_mem record before region record!\n");
+ return;
+ }
+ region->r.record.r.mask.gr_mem |= ptr->r.record.p.rmask;
+ set_imask (region, ptr->r.record.p.rmask, t, 2);
+ break;
+ case br_mem:
+ if (!region)
+ {
+ as_bad ("br_mem record before region record!\n");
+ return;
+ }
+ region->r.record.r.mask.br_mem |= ptr->r.record.p.brmask;
+ set_imask (region, ptr->r.record.p.brmask, t, 3);
+ break;
+
+ case gr_gr:
+ if (!region)
+ {
+ as_bad ("gr_gr record before region record!\n");
+ return;
+ }
+ set_imask (region, ptr->r.record.p.grmask, t, 2);
+ break;
+ case br_gr:
+ if (!region)
+ {
+ as_bad ("br_gr record before region record!\n");
+ return;
+ }
+ set_imask (region, ptr->r.record.p.brmask, t, 3);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+/* Estimate the size of a frag before relaxing. We only have one type of frag
+ to handle here, which is the unwind info frag. */
+
+int
+ia64_estimate_size_before_relax (fragS *frag,
+ asection *segtype ATTRIBUTE_UNUSED)
+{
+ unw_rec_list *list;
+ int len, size, pad;
+
+ /* ??? This code is identical to the first part of ia64_convert_frag. */
+ list = (unw_rec_list *) frag->fr_opcode;
+ fixup_unw_records (list, 0);
+
+ len = calc_record_size (list);
+ /* pad to pointer-size boundary. */
+ pad = len % md.pointer_size;
+ if (pad != 0)
+ len += md.pointer_size - pad;
+ /* Add 8 for the header + a pointer for the personality offset. */
+ size = len + 8 + md.pointer_size;
+
+ /* fr_var carries the max_chars that we created the fragment with.
+ We must, of course, have allocated enough memory earlier. */
+ assert (frag->fr_var >= size);
+
+ return frag->fr_fix + size;
+}
+
+/* This function converts a rs_machine_dependent variant frag into a
+ normal fill frag with the unwind image from the the record list. */
+void
+ia64_convert_frag (fragS *frag)
+{
+ unw_rec_list *list;
+ int len, size, pad;
+ valueT flag_value;
+
+ /* ??? This code is identical to ia64_estimate_size_before_relax. */
+ list = (unw_rec_list *) frag->fr_opcode;
+ fixup_unw_records (list, 0);
+
+ len = calc_record_size (list);
+ /* pad to pointer-size boundary. */
+ pad = len % md.pointer_size;
+ if (pad != 0)
+ len += md.pointer_size - pad;
+ /* Add 8 for the header + a pointer for the personality offset. */
+ size = len + 8 + md.pointer_size;
+
+ /* fr_var carries the max_chars that we created the fragment with.
+ We must, of course, have allocated enough memory earlier. */
+ assert (frag->fr_var >= size);
+
+ /* Initialize the header area. fr_offset is initialized with
+ unwind.personality_routine. */
+ if (frag->fr_offset)
+ {
+ if (md.flags & EF_IA_64_ABI64)
+ flag_value = (bfd_vma) 3 << 32;
+ else
+ /* 32-bit unwind info block. */
+ flag_value = (bfd_vma) 0x1003 << 32;
+ }
+ else
+ flag_value = 0;
+
+ md_number_to_chars (frag->fr_literal,
+ (((bfd_vma) 1 << 48) /* Version. */
+ | flag_value /* U & E handler flags. */
+ | (len / md.pointer_size)), /* Length. */
+ 8);
+
+ /* Skip the header. */
+ vbyte_mem_ptr = frag->fr_literal + 8;
+ process_unw_records (list, output_vbyte_mem);
+
+ /* Fill the padding bytes with zeros. */
+ if (pad != 0)
+ md_number_to_chars (frag->fr_literal + len + 8 - md.pointer_size + pad, 0,
+ md.pointer_size - pad);
+
+ frag->fr_fix += size;
+ frag->fr_type = rs_fill;
+ frag->fr_var = 0;
+ frag->fr_offset = 0;
+}
+
+static int
+convert_expr_to_ab_reg (e, ab, regp)
+ expressionS *e;
+ unsigned int *ab;
+ unsigned int *regp;
+{
+ unsigned int reg;
+
+ if (e->X_op != O_register)
+ return 0;
+
+ reg = e->X_add_number;
+ if (reg >= (REG_GR + 4) && reg <= (REG_GR + 7))
+ {
+ *ab = 0;
+ *regp = reg - REG_GR;
+ }
+ else if ((reg >= (REG_FR + 2) && reg <= (REG_FR + 5))
+ || (reg >= (REG_FR + 16) && reg <= (REG_FR + 31)))
+ {
+ *ab = 1;
+ *regp = reg - REG_FR;
+ }
+ else if (reg >= (REG_BR + 1) && reg <= (REG_BR + 5))
+ {
+ *ab = 2;
+ *regp = reg - REG_BR;
+ }
+ else
+ {
+ *ab = 3;
+ switch (reg)
+ {
+ case REG_PR: *regp = 0; break;
+ case REG_PSP: *regp = 1; break;
+ case REG_PRIUNAT: *regp = 2; break;
+ case REG_BR + 0: *regp = 3; break;
+ case REG_AR + AR_BSP: *regp = 4; break;
+ case REG_AR + AR_BSPSTORE: *regp = 5; break;
+ case REG_AR + AR_RNAT: *regp = 6; break;
+ case REG_AR + AR_UNAT: *regp = 7; break;
+ case REG_AR + AR_FPSR: *regp = 8; break;
+ case REG_AR + AR_PFS: *regp = 9; break;
+ case REG_AR + AR_LC: *regp = 10; break;
+
+ default:
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+convert_expr_to_xy_reg (e, xy, regp)
+ expressionS *e;
+ unsigned int *xy;
+ unsigned int *regp;
+{
+ unsigned int reg;
+
+ if (e->X_op != O_register)
+ return 0;
+
+ reg = e->X_add_number;
+
+ if (/* reg >= REG_GR && */ reg <= (REG_GR + 127))
+ {
+ *xy = 0;
+ *regp = reg - REG_GR;
+ }
+ else if (reg >= REG_FR && reg <= (REG_FR + 127))
+ {
+ *xy = 1;
+ *regp = reg - REG_FR;
+ }
+ else if (reg >= REG_BR && reg <= (REG_BR + 7))
+ {
+ *xy = 2;
+ *regp = reg - REG_BR;
+ }
+ else
+ return -1;
+ return 1;
+}
+
+static void
+dot_align (int arg)
+{
+ /* The current frag is an alignment frag. */
+ align_frag = frag_now;
+ s_align_bytes (arg);
+}
+
+static void
+dot_radix (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ int radix;
+
+ SKIP_WHITESPACE ();
+ radix = *input_line_pointer++;
+
+ if (radix != 'C' && !is_end_of_line[(unsigned char) radix])
+ {
+ as_bad ("Radix `%c' unsupported", *input_line_pointer);
+ ignore_rest_of_line ();
+ return;
+ }
+}
+
+/* .sbss, .bss etc. are macros that expand into ".section SECNAME". */
+static void
+dot_special_section (which)
+ int which;
+{
+ set_section ((char *) special_section_name[which]);
+}
+
+static void
+add_unwind_entry (ptr)
+ unw_rec_list *ptr;
+{
+ if (unwind.tail)
+ unwind.tail->next = ptr;
+ else
+ unwind.list = ptr;
+ unwind.tail = ptr;
+
+ /* The current entry can in fact be a chain of unwind entries. */
+ if (unwind.current_entry == NULL)
+ unwind.current_entry = ptr;
+}
+
+static void
+dot_fframe (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS e;
+
+ parse_operand (&e);
+
+ if (e.X_op != O_constant)
+ as_bad ("Operand to .fframe must be a constant");
+ else
+ add_unwind_entry (output_mem_stack_f (e.X_add_number));
+}
+
+static void
+dot_vframe (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS e;
+ unsigned reg;
+
+ parse_operand (&e);
+ reg = e.X_add_number - REG_GR;
+ if (e.X_op == O_register && reg < 128)
+ {
+ add_unwind_entry (output_mem_stack_v ());
+ if (! (unwind.prologue_mask & 2))
+ add_unwind_entry (output_psp_gr (reg));
+ }
+ else
+ as_bad ("First operand to .vframe must be a general register");
+}
+
+static void
+dot_vframesp (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS e;
+
+ parse_operand (&e);
+ if (e.X_op == O_constant)
+ {
+ add_unwind_entry (output_mem_stack_v ());
+ add_unwind_entry (output_psp_sprel (e.X_add_number));
+ }
+ else
+ as_bad ("Operand to .vframesp must be a constant (sp-relative offset)");
+}
+
+static void
+dot_vframepsp (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS e;
+
+ parse_operand (&e);
+ if (e.X_op == O_constant)
+ {
+ add_unwind_entry (output_mem_stack_v ());
+ add_unwind_entry (output_psp_sprel (e.X_add_number));
+ }
+ else
+ as_bad ("Operand to .vframepsp must be a constant (psp-relative offset)");
+}
+
+static void
+dot_save (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS e1, e2;
+ int sep;
+ int reg1, reg2;
+
+ sep = parse_operand (&e1);
+ if (sep != ',')
+ as_bad ("No second operand to .save");
+ sep = parse_operand (&e2);
+
+ reg1 = e1.X_add_number;
+ reg2 = e2.X_add_number - REG_GR;
+
+ /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
+ if (e1.X_op == O_register)
+ {
+ if (e2.X_op == O_register && reg2 >= 0 && reg2 < 128)
+ {
+ switch (reg1)
+ {
+ case REG_AR + AR_BSP:
+ add_unwind_entry (output_bsp_when ());
+ add_unwind_entry (output_bsp_gr (reg2));
+ break;
+ case REG_AR + AR_BSPSTORE:
+ add_unwind_entry (output_bspstore_when ());
+ add_unwind_entry (output_bspstore_gr (reg2));
+ break;
+ case REG_AR + AR_RNAT:
+ add_unwind_entry (output_rnat_when ());
+ add_unwind_entry (output_rnat_gr (reg2));
+ break;
+ case REG_AR + AR_UNAT:
+ add_unwind_entry (output_unat_when ());
+ add_unwind_entry (output_unat_gr (reg2));
+ break;
+ case REG_AR + AR_FPSR:
+ add_unwind_entry (output_fpsr_when ());
+ add_unwind_entry (output_fpsr_gr (reg2));
+ break;
+ case REG_AR + AR_PFS:
+ add_unwind_entry (output_pfs_when ());
+ if (! (unwind.prologue_mask & 4))
+ add_unwind_entry (output_pfs_gr (reg2));
+ break;
+ case REG_AR + AR_LC:
+ add_unwind_entry (output_lc_when ());
+ add_unwind_entry (output_lc_gr (reg2));
+ break;
+ case REG_BR:
+ add_unwind_entry (output_rp_when ());
+ if (! (unwind.prologue_mask & 8))
+ add_unwind_entry (output_rp_gr (reg2));
+ break;
+ case REG_PR:
+ add_unwind_entry (output_preds_when ());
+ if (! (unwind.prologue_mask & 1))
+ add_unwind_entry (output_preds_gr (reg2));
+ break;
+ case REG_PRIUNAT:
+ add_unwind_entry (output_priunat_when_gr ());
+ add_unwind_entry (output_priunat_gr (reg2));
+ break;
+ default:
+ as_bad ("First operand not a valid register");
+ }
+ }
+ else
+ as_bad (" Second operand not a valid register");
+ }
+ else
+ as_bad ("First operand not a register");
+}
+
+static void
+dot_restore (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS e1, e2;
+ unsigned long ecount; /* # of _additional_ regions to pop */
+ int sep;
+
+ sep = parse_operand (&e1);
+ if (e1.X_op != O_register || e1.X_add_number != REG_GR + 12)
+ {
+ as_bad ("First operand to .restore must be stack pointer (sp)");
+ return;
+ }
+
+ if (sep == ',')
+ {
+ parse_operand (&e2);
+ if (e2.X_op != O_constant || e2.X_add_number < 0)
+ {
+ as_bad ("Second operand to .restore must be a constant >= 0");
+ return;
+ }
+ ecount = e2.X_add_number;
+ }
+ else
+ ecount = unwind.prologue_count - 1;
+
+ if (ecount >= unwind.prologue_count)
+ {
+ as_bad ("Epilogue count of %lu exceeds number of nested prologues (%u)",
+ ecount + 1, unwind.prologue_count);
+ return;
+ }
+
+ add_unwind_entry (output_epilogue (ecount));
+
+ if (ecount < unwind.prologue_count)
+ unwind.prologue_count -= ecount + 1;
+ else
+ unwind.prologue_count = 0;
+}
+
+static void
+dot_restorereg (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ unsigned int ab, reg;
+ expressionS e;
+
+ parse_operand (&e);
+
+ if (!convert_expr_to_ab_reg (&e, &ab, &reg))
+ {
+ as_bad ("First operand to .restorereg must be a preserved register");
+ return;
+ }
+ add_unwind_entry (output_spill_reg (ab, reg, 0, 0));
+}
+
+static void
+dot_restorereg_p (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ unsigned int qp, ab, reg;
+ expressionS e1, e2;
+ int sep;
+
+ sep = parse_operand (&e1);
+ if (sep != ',')
+ {
+ as_bad ("No second operand to .restorereg.p");
+ return;
+ }
+
+ parse_operand (&e2);
+
+ qp = e1.X_add_number - REG_P;
+ if (e1.X_op != O_register || qp > 63)
+ {
+ as_bad ("First operand to .restorereg.p must be a predicate");
+ return;
+ }
+
+ if (!convert_expr_to_ab_reg (&e2, &ab, &reg))
+ {
+ as_bad ("Second operand to .restorereg.p must be a preserved register");
+ return;
+ }
+ add_unwind_entry (output_spill_reg_p (ab, reg, 0, 0, qp));
+}
+
+static void
+generate_unwind_image (text_name)
+ const char *text_name;
+{
+ int size, pad;
+ unw_rec_list *list;
+
+ /* Mark the end of the unwind info, so that we can compute the size of the
+ last unwind region. */
+ add_unwind_entry (output_endp ());
+
+ /* Force out pending instructions, to make sure all unwind records have
+ a valid slot_number field. */
+ ia64_flush_insns ();
+
+ /* Generate the unwind record. */
+ list = optimize_unw_records (unwind.list);
+ fixup_unw_records (list, 1);
+ size = calc_record_size (list);
+
+ if (size > 0 || unwind.force_unwind_entry)
+ {
+ unwind.force_unwind_entry = 0;
+ /* pad to pointer-size boundary. */
+ pad = size % md.pointer_size;
+ if (pad != 0)
+ size += md.pointer_size - pad;
+ /* Add 8 for the header + a pointer for the personality
+ offset. */
+ size += 8 + md.pointer_size;
+ }
+
+ /* If there are unwind records, switch sections, and output the info. */
+ if (size != 0)
+ {
+ char *sec_name;
+ expressionS exp;
+ bfd_reloc_code_real_type reloc;
+
+ make_unw_section_name (SPECIAL_SECTION_UNWIND_INFO, text_name, sec_name);
+ set_section (sec_name);
+ bfd_set_section_flags (stdoutput, now_seg,
+ SEC_LOAD | SEC_ALLOC | SEC_READONLY);
+
+ /* Make sure the section has 4 byte alignment for ILP32 and
+ 8 byte alignment for LP64. */
+ frag_align (md.pointer_size_shift, 0, 0);
+ record_alignment (now_seg, md.pointer_size_shift);
+
+ /* Set expression which points to start of unwind descriptor area. */
+ unwind.info = expr_build_dot ();
+
+ frag_var (rs_machine_dependent, size, size, 0, 0,
+ (offsetT) unwind.personality_routine, (char *) list);
+
+ /* Add the personality address to the image. */
+ if (unwind.personality_routine != 0)
+ {
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = unwind.personality_routine;
+ exp.X_add_number = 0;
+
+ if (md.flags & EF_IA_64_BE)
+ {
+ if (md.flags & EF_IA_64_ABI64)
+ reloc = BFD_RELOC_IA64_LTOFF_FPTR64MSB;
+ else
+ reloc = BFD_RELOC_IA64_LTOFF_FPTR32MSB;
+ }
+ else
+ {
+ if (md.flags & EF_IA_64_ABI64)
+ reloc = BFD_RELOC_IA64_LTOFF_FPTR64LSB;
+ else
+ reloc = BFD_RELOC_IA64_LTOFF_FPTR32LSB;
+ }
+
+ fix_new_exp (frag_now, frag_now_fix () - md.pointer_size,
+ md.pointer_size, &exp, 0, reloc);
+ unwind.personality_routine = 0;
+ }
+ }
+
+ free_saved_prologue_counts ();
+ unwind.list = unwind.tail = unwind.current_entry = NULL;
+}
+
+static void
+dot_handlerdata (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ const char *text_name = segment_name (now_seg);
+
+ /* If text section name starts with ".text" (which it should),
+ strip this prefix off. */
+ if (strcmp (text_name, ".text") == 0)
+ text_name = "";
+
+ unwind.force_unwind_entry = 1;
+
+ /* Remember which segment we're in so we can switch back after .endp */
+ unwind.saved_text_seg = now_seg;
+ unwind.saved_text_subseg = now_subseg;
+
+ /* Generate unwind info into unwind-info section and then leave that
+ section as the currently active one so dataXX directives go into
+ the language specific data area of the unwind info block. */
+ generate_unwind_image (text_name);
+ demand_empty_rest_of_line ();
+}
+
+static void
+dot_unwentry (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ unwind.force_unwind_entry = 1;
+ demand_empty_rest_of_line ();
+}
+
+static void
+dot_altrp (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS e;
+ unsigned reg;
+
+ parse_operand (&e);
+ reg = e.X_add_number - REG_BR;
+ if (e.X_op == O_register && reg < 8)
+ add_unwind_entry (output_rp_br (reg));
+ else
+ as_bad ("First operand not a valid branch register");
+}
+
+static void
+dot_savemem (psprel)
+ int psprel;
+{
+ expressionS e1, e2;
+ int sep;
+ int reg1, val;
+
+ sep = parse_operand (&e1);
+ if (sep != ',')
+ as_bad ("No second operand to .save%ssp", psprel ? "p" : "");
+ sep = parse_operand (&e2);
+
+ reg1 = e1.X_add_number;
+ val = e2.X_add_number;
+
+ /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
+ if (e1.X_op == O_register)
+ {
+ if (e2.X_op == O_constant)
+ {
+ switch (reg1)
+ {
+ case REG_AR + AR_BSP:
+ add_unwind_entry (output_bsp_when ());
+ add_unwind_entry ((psprel
+ ? output_bsp_psprel
+ : output_bsp_sprel) (val));
+ break;
+ case REG_AR + AR_BSPSTORE:
+ add_unwind_entry (output_bspstore_when ());
+ add_unwind_entry ((psprel
+ ? output_bspstore_psprel
+ : output_bspstore_sprel) (val));
+ break;
+ case REG_AR + AR_RNAT:
+ add_unwind_entry (output_rnat_when ());
+ add_unwind_entry ((psprel
+ ? output_rnat_psprel
+ : output_rnat_sprel) (val));
+ break;
+ case REG_AR + AR_UNAT:
+ add_unwind_entry (output_unat_when ());
+ add_unwind_entry ((psprel
+ ? output_unat_psprel
+ : output_unat_sprel) (val));
+ break;
+ case REG_AR + AR_FPSR:
+ add_unwind_entry (output_fpsr_when ());
+ add_unwind_entry ((psprel
+ ? output_fpsr_psprel
+ : output_fpsr_sprel) (val));
+ break;
+ case REG_AR + AR_PFS:
+ add_unwind_entry (output_pfs_when ());
+ add_unwind_entry ((psprel
+ ? output_pfs_psprel
+ : output_pfs_sprel) (val));
+ break;
+ case REG_AR + AR_LC:
+ add_unwind_entry (output_lc_when ());
+ add_unwind_entry ((psprel
+ ? output_lc_psprel
+ : output_lc_sprel) (val));
+ break;
+ case REG_BR:
+ add_unwind_entry (output_rp_when ());
+ add_unwind_entry ((psprel
+ ? output_rp_psprel
+ : output_rp_sprel) (val));
+ break;
+ case REG_PR:
+ add_unwind_entry (output_preds_when ());
+ add_unwind_entry ((psprel
+ ? output_preds_psprel
+ : output_preds_sprel) (val));
+ break;
+ case REG_PRIUNAT:
+ add_unwind_entry (output_priunat_when_mem ());
+ add_unwind_entry ((psprel
+ ? output_priunat_psprel
+ : output_priunat_sprel) (val));
+ break;
+ default:
+ as_bad ("First operand not a valid register");
+ }
+ }
+ else
+ as_bad (" Second operand not a valid constant");
+ }
+ else
+ as_bad ("First operand not a register");
+}
+
+static void
+dot_saveg (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS e1, e2;
+ int sep;
+ sep = parse_operand (&e1);
+ if (sep == ',')
+ parse_operand (&e2);
+
+ if (e1.X_op != O_constant)
+ as_bad ("First operand to .save.g must be a constant.");
+ else
+ {
+ int grmask = e1.X_add_number;
+ if (sep != ',')
+ add_unwind_entry (output_gr_mem (grmask));
+ else
+ {
+ int reg = e2.X_add_number - REG_GR;
+ if (e2.X_op == O_register && reg >= 0 && reg < 128)
+ add_unwind_entry (output_gr_gr (grmask, reg));
+ else
+ as_bad ("Second operand is an invalid register.");
+ }
+ }
+}
+
+static void
+dot_savef (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS e1;
+ int sep;
+ sep = parse_operand (&e1);
+
+ if (e1.X_op != O_constant)
+ as_bad ("Operand to .save.f must be a constant.");
+ else
+ add_unwind_entry (output_fr_mem (e1.X_add_number));
+}
+
+static void
+dot_saveb (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS e1, e2;
+ unsigned int reg;
+ unsigned char sep;
+ int brmask;
+
+ sep = parse_operand (&e1);
+ if (e1.X_op != O_constant)
+ {
+ as_bad ("First operand to .save.b must be a constant.");
+ return;
+ }
+ brmask = e1.X_add_number;
+
+ if (sep == ',')
+ {
+ sep = parse_operand (&e2);
+ reg = e2.X_add_number - REG_GR;
+ if (e2.X_op != O_register || reg > 127)
+ {
+ as_bad ("Second operand to .save.b must be a general register.");
+ return;
+ }
+ add_unwind_entry (output_br_gr (brmask, e2.X_add_number));
+ }
+ else
+ add_unwind_entry (output_br_mem (brmask));
+
+ if (!is_end_of_line[sep] && !is_it_end_of_statement ())
+ demand_empty_rest_of_line ();
+}
+
+static void
+dot_savegf (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS e1, e2;
+ int sep;
+ sep = parse_operand (&e1);
+ if (sep == ',')
+ parse_operand (&e2);
+
+ if (e1.X_op != O_constant || sep != ',' || e2.X_op != O_constant)
+ as_bad ("Both operands of .save.gf must be constants.");
+ else
+ {
+ int grmask = e1.X_add_number;
+ int frmask = e2.X_add_number;
+ add_unwind_entry (output_frgr_mem (grmask, frmask));
+ }
+}
+
+static void
+dot_spill (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS e;
+ unsigned char sep;
+
+ sep = parse_operand (&e);
+ if (!is_end_of_line[sep] && !is_it_end_of_statement ())
+ demand_empty_rest_of_line ();
+
+ if (e.X_op != O_constant)
+ as_bad ("Operand to .spill must be a constant");
+ else
+ add_unwind_entry (output_spill_base (e.X_add_number));
+}
+
+static void
+dot_spillreg (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ int sep, ab, xy, reg, treg;
+ expressionS e1, e2;
+
+ sep = parse_operand (&e1);
+ if (sep != ',')
+ {
+ as_bad ("No second operand to .spillreg");
+ return;
+ }
+
+ parse_operand (&e2);
+
+ if (!convert_expr_to_ab_reg (&e1, &ab, &reg))
+ {
+ as_bad ("First operand to .spillreg must be a preserved register");
+ return;
+ }
+
+ if (!convert_expr_to_xy_reg (&e2, &xy, &treg))
+ {
+ as_bad ("Second operand to .spillreg must be a register");
+ return;
+ }
+
+ add_unwind_entry (output_spill_reg (ab, reg, treg, xy));
+}
+
+static void
+dot_spillmem (psprel)
+ int psprel;
+{
+ expressionS e1, e2;
+ int sep, ab, reg;
+
+ sep = parse_operand (&e1);
+ if (sep != ',')
+ {
+ as_bad ("Second operand missing");
+ return;
+ }
+
+ parse_operand (&e2);
+
+ if (!convert_expr_to_ab_reg (&e1, &ab, &reg))
+ {
+ as_bad ("First operand to .spill%s must be a preserved register",
+ psprel ? "psp" : "sp");
+ return;
+ }
+
+ if (e2.X_op != O_constant)
+ {
+ as_bad ("Second operand to .spill%s must be a constant",
+ psprel ? "psp" : "sp");
+ return;
+ }
+
+ if (psprel)
+ add_unwind_entry (output_spill_psprel (ab, reg, e2.X_add_number));
+ else
+ add_unwind_entry (output_spill_sprel (ab, reg, e2.X_add_number));
+}
+
+static void
+dot_spillreg_p (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ int sep, ab, xy, reg, treg;
+ expressionS e1, e2, e3;
+ unsigned int qp;
+
+ sep = parse_operand (&e1);
+ if (sep != ',')
+ {
+ as_bad ("No second and third operand to .spillreg.p");
+ return;
+ }
+
+ sep = parse_operand (&e2);
+ if (sep != ',')
+ {
+ as_bad ("No third operand to .spillreg.p");
+ return;
+ }
+
+ parse_operand (&e3);
+
+ qp = e1.X_add_number - REG_P;
+
+ if (e1.X_op != O_register || qp > 63)
+ {
+ as_bad ("First operand to .spillreg.p must be a predicate");
+ return;
+ }
+
+ if (!convert_expr_to_ab_reg (&e2, &ab, &reg))
+ {
+ as_bad ("Second operand to .spillreg.p must be a preserved register");
+ return;
+ }
+
+ if (!convert_expr_to_xy_reg (&e3, &xy, &treg))
+ {
+ as_bad ("Third operand to .spillreg.p must be a register");
+ return;
+ }
+
+ add_unwind_entry (output_spill_reg_p (ab, reg, treg, xy, qp));
+}
+
+static void
+dot_spillmem_p (psprel)
+ int psprel;
+{
+ expressionS e1, e2, e3;
+ int sep, ab, reg;
+ unsigned int qp;
+
+ sep = parse_operand (&e1);
+ if (sep != ',')
+ {
+ as_bad ("Second operand missing");
+ return;
+ }
+
+ parse_operand (&e2);
+ if (sep != ',')
+ {
+ as_bad ("Second operand missing");
+ return;
+ }
+
+ parse_operand (&e3);
+
+ qp = e1.X_add_number - REG_P;
+ if (e1.X_op != O_register || qp > 63)
+ {
+ as_bad ("First operand to .spill%s_p must be a predicate",
+ psprel ? "psp" : "sp");
+ return;
+ }
+
+ if (!convert_expr_to_ab_reg (&e2, &ab, &reg))
+ {
+ as_bad ("Second operand to .spill%s_p must be a preserved register",
+ psprel ? "psp" : "sp");
+ return;
+ }
+
+ if (e3.X_op != O_constant)
+ {
+ as_bad ("Third operand to .spill%s_p must be a constant",
+ psprel ? "psp" : "sp");
+ return;
+ }
+
+ if (psprel)
+ add_unwind_entry (output_spill_psprel_p (ab, reg, e3.X_add_number, qp));
+ else
+ add_unwind_entry (output_spill_sprel_p (ab, reg, e3.X_add_number, qp));
+}
+
+static unsigned int
+get_saved_prologue_count (lbl)
+ unsigned long lbl;
+{
+ label_prologue_count *lpc = unwind.saved_prologue_counts;
+
+ while (lpc != NULL && lpc->label_number != lbl)
+ lpc = lpc->next;
+
+ if (lpc != NULL)
+ return lpc->prologue_count;
+
+ as_bad ("Missing .label_state %ld", lbl);
+ return 1;
+}
+
+static void
+save_prologue_count (lbl, count)
+ unsigned long lbl;
+ unsigned int count;
+{
+ label_prologue_count *lpc = unwind.saved_prologue_counts;
+
+ while (lpc != NULL && lpc->label_number != lbl)
+ lpc = lpc->next;
+
+ if (lpc != NULL)
+ lpc->prologue_count = count;
+ else
+ {
+ label_prologue_count *new_lpc = xmalloc (sizeof (* new_lpc));
+
+ new_lpc->next = unwind.saved_prologue_counts;
+ new_lpc->label_number = lbl;
+ new_lpc->prologue_count = count;
+ unwind.saved_prologue_counts = new_lpc;
+ }
+}
+
+static void
+free_saved_prologue_counts ()
+{
+ label_prologue_count *lpc = unwind.saved_prologue_counts;
+ label_prologue_count *next;
+
+ while (lpc != NULL)
+ {
+ next = lpc->next;
+ free (lpc);
+ lpc = next;
+ }
+
+ unwind.saved_prologue_counts = NULL;
+}
+
+static void
+dot_label_state (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS e;
+
+ parse_operand (&e);
+ if (e.X_op != O_constant)
+ {
+ as_bad ("Operand to .label_state must be a constant");
+ return;
+ }
+ add_unwind_entry (output_label_state (e.X_add_number));
+ save_prologue_count (e.X_add_number, unwind.prologue_count);
+}
+
+static void
+dot_copy_state (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS e;
+
+ parse_operand (&e);
+ if (e.X_op != O_constant)
+ {
+ as_bad ("Operand to .copy_state must be a constant");
+ return;
+ }
+ add_unwind_entry (output_copy_state (e.X_add_number));
+ unwind.prologue_count = get_saved_prologue_count (e.X_add_number);
+}
+
+static void
+dot_unwabi (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS e1, e2;
+ unsigned char sep;
+
+ sep = parse_operand (&e1);
+ if (sep != ',')
+ {
+ as_bad ("Second operand to .unwabi missing");
+ return;
+ }
+ sep = parse_operand (&e2);
+ if (!is_end_of_line[sep] && !is_it_end_of_statement ())
+ demand_empty_rest_of_line ();
+
+ if (e1.X_op != O_constant)
+ {
+ as_bad ("First operand to .unwabi must be a constant");
+ return;
+ }
+
+ if (e2.X_op != O_constant)
+ {
+ as_bad ("Second operand to .unwabi must be a constant");
+ return;
+ }
+
+ add_unwind_entry (output_unwabi (e1.X_add_number, e2.X_add_number));
+}
+
+static void
+dot_personality (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ char *name, *p, c;
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ p = input_line_pointer;
+ unwind.personality_routine = symbol_find_or_make (name);
+ unwind.force_unwind_entry = 1;
+ *p = c;
+ SKIP_WHITESPACE ();
+ demand_empty_rest_of_line ();
+}
+
+static void
+dot_proc (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ char *name, *p, c;
+ symbolS *sym;
+
+ unwind.proc_start = expr_build_dot ();
+ /* Parse names of main and alternate entry points and mark them as
+ function symbols: */
+ while (1)
+ {
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ p = input_line_pointer;
+ sym = symbol_find_or_make (name);
+ if (unwind.proc_start == 0)
+ {
+ unwind.proc_start = sym;
+ }
+ symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ break;
+ ++input_line_pointer;
+ }
+ demand_empty_rest_of_line ();
+ ia64_do_align (16);
+
+ unwind.prologue_count = 0;
+ unwind.list = unwind.tail = unwind.current_entry = NULL;
+ unwind.personality_routine = 0;
+}
+
+static void
+dot_body (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ unwind.prologue = 0;
+ unwind.prologue_mask = 0;
+
+ add_unwind_entry (output_body ());
+ demand_empty_rest_of_line ();
+}
+
+static void
+dot_prologue (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ unsigned char sep;
+ int mask = 0, grsave = 0;
+
+ if (!is_it_end_of_statement ())
+ {
+ expressionS e1, e2;
+ sep = parse_operand (&e1);
+ if (sep != ',')
+ as_bad ("No second operand to .prologue");
+ sep = parse_operand (&e2);
+ if (!is_end_of_line[sep] && !is_it_end_of_statement ())
+ demand_empty_rest_of_line ();
+
+ if (e1.X_op == O_constant)
+ {
+ mask = e1.X_add_number;
+
+ if (e2.X_op == O_constant)
+ grsave = e2.X_add_number;
+ else if (e2.X_op == O_register
+ && (grsave = e2.X_add_number - REG_GR) < 128)
+ ;
+ else
+ as_bad ("Second operand not a constant or general register");
+
+ add_unwind_entry (output_prologue_gr (mask, grsave));
+ }
+ else
+ as_bad ("First operand not a constant");
+ }
+ else
+ add_unwind_entry (output_prologue ());
+
+ unwind.prologue = 1;
+ unwind.prologue_mask = mask;
+ ++unwind.prologue_count;
+}
+
+static void
+dot_endp (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS e;
+ unsigned char *ptr;
+ int bytes_per_address;
+ long where;
+ segT saved_seg;
+ subsegT saved_subseg;
+ const char *sec_name, *text_name;
+ char *name, *p, c;
+ symbolS *sym;
+
+ if (unwind.saved_text_seg)
+ {
+ saved_seg = unwind.saved_text_seg;
+ saved_subseg = unwind.saved_text_subseg;
+ unwind.saved_text_seg = NULL;
+ }
+ else
+ {
+ saved_seg = now_seg;
+ saved_subseg = now_subseg;
+ }
+
+ /*
+ Use a slightly ugly scheme to derive the unwind section names from
+ the text section name:
+
+ text sect. unwind table sect.
+ name: name: comments:
+ ---------- ----------------- --------------------------------
+ .text .IA_64.unwind
+ .text.foo .IA_64.unwind.text.foo
+ .foo .IA_64.unwind.foo
+ .gnu.linkonce.t.foo
+ .gnu.linkonce.ia64unw.foo
+ _info .IA_64.unwind_info gas issues error message (ditto)
+ _infoFOO .IA_64.unwind_infoFOO gas issues error message (ditto)
+
+ This mapping is done so that:
+
+ (a) An object file with unwind info only in .text will use
+ unwind section names .IA_64.unwind and .IA_64.unwind_info.
+ This follows the letter of the ABI and also ensures backwards
+ compatibility with older toolchains.
+
+ (b) An object file with unwind info in multiple text sections
+ will use separate unwind sections for each text section.
+ This allows us to properly set the "sh_info" and "sh_link"
+ fields in SHT_IA_64_UNWIND as required by the ABI and also
+ lets GNU ld support programs with multiple segments
+ containing unwind info (as might be the case for certain
+ embedded applications).
+
+ (c) An error is issued if there would be a name clash.
+ */
+ text_name = segment_name (saved_seg);
+ if (strncmp (text_name, "_info", 5) == 0)
+ {
+ as_bad ("Illegal section name `%s' (causes unwind section name clash)",
+ text_name);
+ ignore_rest_of_line ();
+ return;
+ }
+ if (strcmp (text_name, ".text") == 0)
+ text_name = "";
+
+ insn_group_break (1, 0, 0);
+
+ /* If there wasn't a .handlerdata, we haven't generated an image yet. */
+ if (!unwind.info)
+ generate_unwind_image (text_name);
+
+ if (unwind.info || unwind.force_unwind_entry)
+ {
+ subseg_set (md.last_text_seg, 0);
+ unwind.proc_end = expr_build_dot ();
+
+ make_unw_section_name (SPECIAL_SECTION_UNWIND, text_name, sec_name);
+ set_section ((char *) sec_name);
+ bfd_set_section_flags (stdoutput, now_seg,
+ SEC_LOAD | SEC_ALLOC | SEC_READONLY);
+
+ /* Make sure that section has 4 byte alignment for ILP32 and
+ 8 byte alignment for LP64. */
+ record_alignment (now_seg, md.pointer_size_shift);
+
+ /* Need space for 3 pointers for procedure start, procedure end,
+ and unwind info. */
+ ptr = frag_more (3 * md.pointer_size);
+ where = frag_now_fix () - (3 * md.pointer_size);
+ bytes_per_address = bfd_arch_bits_per_address (stdoutput) / 8;
+
+ /* Issue the values of a) Proc Begin, b) Proc End, c) Unwind Record. */
+ e.X_op = O_pseudo_fixup;
+ e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym;
+ e.X_add_number = 0;
+ e.X_add_symbol = unwind.proc_start;
+ ia64_cons_fix_new (frag_now, where, bytes_per_address, &e);
+
+ e.X_op = O_pseudo_fixup;
+ e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym;
+ e.X_add_number = 0;
+ e.X_add_symbol = unwind.proc_end;
+ ia64_cons_fix_new (frag_now, where + bytes_per_address,
+ bytes_per_address, &e);
+
+ if (unwind.info)
+ {
+ e.X_op = O_pseudo_fixup;
+ e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym;
+ e.X_add_number = 0;
+ e.X_add_symbol = unwind.info;
+ ia64_cons_fix_new (frag_now, where + (bytes_per_address * 2),
+ bytes_per_address, &e);
+ }
+ else
+ md_number_to_chars (ptr + (bytes_per_address * 2), 0,
+ bytes_per_address);
+
+ }
+ subseg_set (saved_seg, saved_subseg);
+
+ /* Parse names of main and alternate entry points and set symbol sizes. */
+ while (1)
+ {
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ p = input_line_pointer;
+ sym = symbol_find (name);
+ if (sym && unwind.proc_start
+ && (symbol_get_bfdsym (sym)->flags & BSF_FUNCTION)
+ && S_GET_SIZE (sym) == 0 && symbol_get_obj (sym)->size == NULL)
+ {
+ fragS *fr = symbol_get_frag (unwind.proc_start);
+ fragS *frag = symbol_get_frag (sym);
+
+ /* Check whether the function label is at or beyond last
+ .proc directive. */
+ while (fr && fr != frag)
+ fr = fr->fr_next;
+ if (fr)
+ {
+ if (frag == frag_now && SEG_NORMAL (now_seg))
+ S_SET_SIZE (sym, frag_now_fix () - S_GET_VALUE (sym));
+ else
+ {
+ symbol_get_obj (sym)->size =
+ (expressionS *) xmalloc (sizeof (expressionS));
+ symbol_get_obj (sym)->size->X_op = O_subtract;
+ symbol_get_obj (sym)->size->X_add_symbol
+ = symbol_new (FAKE_LABEL_NAME, now_seg,
+ frag_now_fix (), frag_now);
+ symbol_get_obj (sym)->size->X_op_symbol = sym;
+ symbol_get_obj (sym)->size->X_add_number = 0;
+ }
+ }
+ }
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ break;
+ ++input_line_pointer;
+ }
+ demand_empty_rest_of_line ();
+ unwind.proc_start = unwind.proc_end = unwind.info = 0;
+}
+
+static void
+dot_template (template)
+ int template;
+{
+ CURR_SLOT.user_template = template;
+}
+
+static void
+dot_regstk (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ int ins, locs, outs, rots;
+
+ if (is_it_end_of_statement ())
+ ins = locs = outs = rots = 0;
+ else
+ {
+ ins = get_absolute_expression ();
+ if (*input_line_pointer++ != ',')
+ goto err;
+ locs = get_absolute_expression ();
+ if (*input_line_pointer++ != ',')
+ goto err;
+ outs = get_absolute_expression ();
+ if (*input_line_pointer++ != ',')
+ goto err;
+ rots = get_absolute_expression ();
+ }
+ set_regstack (ins, locs, outs, rots);
+ return;
+
+ err:
+ as_bad ("Comma expected");
+ ignore_rest_of_line ();
+}
+
+static void
+dot_rot (type)
+ int type;
+{
+ unsigned num_regs, num_alloced = 0;
+ struct dynreg **drpp, *dr;
+ int ch, base_reg = 0;
+ char *name, *start;
+ size_t len;
+
+ switch (type)
+ {
+ case DYNREG_GR: base_reg = REG_GR + 32; break;
+ case DYNREG_FR: base_reg = REG_FR + 32; break;
+ case DYNREG_PR: base_reg = REG_P + 16; break;
+ default: break;
+ }
+
+ /* First, remove existing names from hash table. */
+ for (dr = md.dynreg[type]; dr && dr->num_regs; dr = dr->next)
+ {
+ hash_delete (md.dynreg_hash, dr->name);
+ dr->num_regs = 0;
+ }
+
+ drpp = &md.dynreg[type];
+ while (1)
+ {
+ start = input_line_pointer;
+ ch = get_symbol_end ();
+ *input_line_pointer = ch;
+ len = (input_line_pointer - start);
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '[')
+ {
+ as_bad ("Expected '['");
+ goto err;
+ }
+ ++input_line_pointer; /* skip '[' */
+
+ num_regs = get_absolute_expression ();
+
+ if (*input_line_pointer++ != ']')
+ {
+ as_bad ("Expected ']'");
+ goto err;
+ }
+ SKIP_WHITESPACE ();
+
+ num_alloced += num_regs;
+ switch (type)
+ {
+ case DYNREG_GR:
+ if (num_alloced > md.rot.num_regs)
+ {
+ as_bad ("Used more than the declared %d rotating registers",
+ md.rot.num_regs);
+ goto err;
+ }
+ break;
+ case DYNREG_FR:
+ if (num_alloced > 96)
+ {
+ as_bad ("Used more than the available 96 rotating registers");
+ goto err;
+ }
+ break;
+ case DYNREG_PR:
+ if (num_alloced > 48)
+ {
+ as_bad ("Used more than the available 48 rotating registers");
+ goto err;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ name = obstack_alloc (&notes, len + 1);
+ memcpy (name, start, len);
+ name[len] = '\0';
+
+ if (!*drpp)
+ {
+ *drpp = obstack_alloc (&notes, sizeof (*dr));
+ memset (*drpp, 0, sizeof (*dr));
+ }
+
+ dr = *drpp;
+ dr->name = name;
+ dr->num_regs = num_regs;
+ dr->base = base_reg;
+ drpp = &dr->next;
+ base_reg += num_regs;
+
+ if (hash_insert (md.dynreg_hash, name, dr))
+ {
+ as_bad ("Attempt to redefine register set `%s'", name);
+ goto err;
+ }
+
+ if (*input_line_pointer != ',')
+ break;
+ ++input_line_pointer; /* skip comma */
+ SKIP_WHITESPACE ();
+ }
+ demand_empty_rest_of_line ();
+ return;
+
+ err:
+ ignore_rest_of_line ();
+}
+
+static void
+dot_byteorder (byteorder)
+ int byteorder;
+{
+ segment_info_type *seginfo = seg_info (now_seg);
+
+ if (byteorder == -1)
+ {
+ if (seginfo->tc_segment_info_data.endian == 0)
+ seginfo->tc_segment_info_data.endian
+ = TARGET_BYTES_BIG_ENDIAN ? 1 : 2;
+ byteorder = seginfo->tc_segment_info_data.endian == 1;
+ }
+ else
+ seginfo->tc_segment_info_data.endian = byteorder ? 1 : 2;
+
+ if (target_big_endian != byteorder)
+ {
+ target_big_endian = byteorder;
+ if (target_big_endian)
+ {
+ ia64_number_to_chars = number_to_chars_bigendian;
+ ia64_float_to_chars = ia64_float_to_chars_bigendian;
+ }
+ else
+ {
+ ia64_number_to_chars = number_to_chars_littleendian;
+ ia64_float_to_chars = ia64_float_to_chars_littleendian;
+ }
+ }
+}
+
+static void
+dot_psr (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ char *option;
+ int ch;
+
+ while (1)
+ {
+ option = input_line_pointer;
+ ch = get_symbol_end ();
+ if (strcmp (option, "lsb") == 0)
+ md.flags &= ~EF_IA_64_BE;
+ else if (strcmp (option, "msb") == 0)
+ md.flags |= EF_IA_64_BE;
+ else if (strcmp (option, "abi32") == 0)
+ md.flags &= ~EF_IA_64_ABI64;
+ else if (strcmp (option, "abi64") == 0)
+ md.flags |= EF_IA_64_ABI64;
+ else
+ as_bad ("Unknown psr option `%s'", option);
+ *input_line_pointer = ch;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ break;
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ }
+ demand_empty_rest_of_line ();
+}
+
+static void
+dot_ln (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ new_logical_line (0, get_absolute_expression ());
+ demand_empty_rest_of_line ();
+}
+
+static char *
+parse_section_name ()
+{
+ char *name;
+ int len;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '"')
+ {
+ as_bad ("Missing section name");
+ ignore_rest_of_line ();
+ return 0;
+ }
+ name = demand_copy_C_string (&len);
+ if (!name)
+ {
+ ignore_rest_of_line ();
+ return 0;
+ }
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("Comma expected after section name");
+ ignore_rest_of_line ();
+ return 0;
+ }
+ ++input_line_pointer; /* skip comma */
+ return name;
+}
+
+static void
+dot_xdata (size)
+ int size;
+{
+ char *name = parse_section_name ();
+ if (!name)
+ return;
+
+ md.keep_pending_output = 1;
+ set_section (name);
+ cons (size);
+ obj_elf_previous (0);
+ md.keep_pending_output = 0;
+}
+
+/* Why doesn't float_cons() call md_cons_align() the way cons() does? */
+
+static void
+stmt_float_cons (kind)
+ int kind;
+{
+ size_t alignment;
+
+ switch (kind)
+ {
+ case 'd':
+ alignment = 8;
+ break;
+
+ case 'x':
+ case 'X':
+ alignment = 16;
+ break;
+
+ case 'f':
+ default:
+ alignment = 4;
+ break;
+ }
+ ia64_do_align (alignment);
+ float_cons (kind);
+}
+
+static void
+stmt_cons_ua (size)
+ int size;
+{
+ int saved_auto_align = md.auto_align;
+
+ md.auto_align = 0;
+ cons (size);
+ md.auto_align = saved_auto_align;
+}
+
+static void
+dot_xfloat_cons (kind)
+ int kind;
+{
+ char *name = parse_section_name ();
+ if (!name)
+ return;
+
+ md.keep_pending_output = 1;
+ set_section (name);
+ stmt_float_cons (kind);
+ obj_elf_previous (0);
+ md.keep_pending_output = 0;
+}
+
+static void
+dot_xstringer (zero)
+ int zero;
+{
+ char *name = parse_section_name ();
+ if (!name)
+ return;
+
+ md.keep_pending_output = 1;
+ set_section (name);
+ stringer (zero);
+ obj_elf_previous (0);
+ md.keep_pending_output = 0;
+}
+
+static void
+dot_xdata_ua (size)
+ int size;
+{
+ int saved_auto_align = md.auto_align;
+ char *name = parse_section_name ();
+ if (!name)
+ return;
+
+ md.keep_pending_output = 1;
+ set_section (name);
+ md.auto_align = 0;
+ cons (size);
+ md.auto_align = saved_auto_align;
+ obj_elf_previous (0);
+ md.keep_pending_output = 0;
+}
+
+static void
+dot_xfloat_cons_ua (kind)
+ int kind;
+{
+ int saved_auto_align = md.auto_align;
+ char *name = parse_section_name ();
+ if (!name)
+ return;
+
+ md.keep_pending_output = 1;
+ set_section (name);
+ md.auto_align = 0;
+ stmt_float_cons (kind);
+ md.auto_align = saved_auto_align;
+ obj_elf_previous (0);
+ md.keep_pending_output = 0;
+}
+
+/* .reg.val <regname>,value */
+
+static void
+dot_reg_val (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS reg;
+
+ expression (&reg);
+ if (reg.X_op != O_register)
+ {
+ as_bad (_("Register name expected"));
+ ignore_rest_of_line ();
+ }
+ else if (*input_line_pointer++ != ',')
+ {
+ as_bad (_("Comma expected"));
+ ignore_rest_of_line ();
+ }
+ else
+ {
+ valueT value = get_absolute_expression ();
+ int regno = reg.X_add_number;
+ if (regno < REG_GR || regno > REG_GR + 128)
+ as_warn (_("Register value annotation ignored"));
+ else
+ {
+ gr_values[regno - REG_GR].known = 1;
+ gr_values[regno - REG_GR].value = value;
+ gr_values[regno - REG_GR].path = md.path;
+ }
+ }
+ demand_empty_rest_of_line ();
+}
+
+/* select dv checking mode
+ .auto
+ .explicit
+ .default
+
+ A stop is inserted when changing modes
+ */
+
+static void
+dot_dv_mode (type)
+ int type;
+{
+ if (md.manual_bundling)
+ as_warn (_("Directive invalid within a bundle"));
+
+ if (type == 'E' || type == 'A')
+ md.mode_explicitly_set = 0;
+ else
+ md.mode_explicitly_set = 1;
+
+ md.detect_dv = 1;
+ switch (type)
+ {
+ case 'A':
+ case 'a':
+ if (md.explicit_mode)
+ insn_group_break (1, 0, 0);
+ md.explicit_mode = 0;
+ break;
+ case 'E':
+ case 'e':
+ if (!md.explicit_mode)
+ insn_group_break (1, 0, 0);
+ md.explicit_mode = 1;
+ break;
+ default:
+ case 'd':
+ if (md.explicit_mode != md.default_explicit_mode)
+ insn_group_break (1, 0, 0);
+ md.explicit_mode = md.default_explicit_mode;
+ md.mode_explicitly_set = 0;
+ break;
+ }
+}
+
+static void
+print_prmask (mask)
+ valueT mask;
+{
+ int regno;
+ char *comma = "";
+ for (regno = 0; regno < 64; regno++)
+ {
+ if (mask & ((valueT) 1 << regno))
+ {
+ fprintf (stderr, "%s p%d", comma, regno);
+ comma = ",";
+ }
+ }
+}
+
+/*
+ .pred.rel.clear [p1 [,p2 [,...]]] (also .pred.rel "clear")
+ .pred.rel.imply p1, p2 (also .pred.rel "imply")
+ .pred.rel.mutex p1, p2 [,...] (also .pred.rel "mutex")
+ .pred.safe_across_calls p1 [, p2 [,...]]
+ */
+
+static void
+dot_pred_rel (type)
+ int type;
+{
+ valueT mask = 0;
+ int count = 0;
+ int p1 = -1, p2 = -1;
+
+ if (type == 0)
+ {
+ if (*input_line_pointer != '"')
+ {
+ as_bad (_("Missing predicate relation type"));
+ ignore_rest_of_line ();
+ return;
+ }
+ else
+ {
+ int len;
+ char *form = demand_copy_C_string (&len);
+ if (strcmp (form, "mutex") == 0)
+ type = 'm';
+ else if (strcmp (form, "clear") == 0)
+ type = 'c';
+ else if (strcmp (form, "imply") == 0)
+ type = 'i';
+ else
+ {
+ as_bad (_("Unrecognized predicate relation type"));
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ if (*input_line_pointer == ',')
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ }
+
+ SKIP_WHITESPACE ();
+ while (1)
+ {
+ valueT bit = 1;
+ int regno;
+
+ if (TOUPPER (*input_line_pointer) != 'P'
+ || (regno = atoi (++input_line_pointer)) < 0
+ || regno > 63)
+ {
+ as_bad (_("Predicate register expected"));
+ ignore_rest_of_line ();
+ return;
+ }
+ while (ISDIGIT (*input_line_pointer))
+ ++input_line_pointer;
+ if (p1 == -1)
+ p1 = regno;
+ else if (p2 == -1)
+ p2 = regno;
+ bit <<= regno;
+ if (mask & bit)
+ as_warn (_("Duplicate predicate register ignored"));
+ mask |= bit;
+ count++;
+ /* See if it's a range. */
+ if (*input_line_pointer == '-')
+ {
+ valueT stop = 1;
+ ++input_line_pointer;
+
+ if (TOUPPER (*input_line_pointer) != 'P'
+ || (regno = atoi (++input_line_pointer)) < 0
+ || regno > 63)
+ {
+ as_bad (_("Predicate register expected"));
+ ignore_rest_of_line ();
+ return;
+ }
+ while (ISDIGIT (*input_line_pointer))
+ ++input_line_pointer;
+ stop <<= regno;
+ if (bit >= stop)
+ {
+ as_bad (_("Bad register range"));
+ ignore_rest_of_line ();
+ return;
+ }
+ while (bit < stop)
+ {
+ bit <<= 1;
+ mask |= bit;
+ count++;
+ }
+ SKIP_WHITESPACE ();
+ }
+ if (*input_line_pointer != ',')
+ break;
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ }
+
+ switch (type)
+ {
+ case 'c':
+ if (count == 0)
+ mask = ~(valueT) 0;
+ clear_qp_mutex (mask);
+ clear_qp_implies (mask, (valueT) 0);
+ break;
+ case 'i':
+ if (count != 2 || p1 == -1 || p2 == -1)
+ as_bad (_("Predicate source and target required"));
+ else if (p1 == 0 || p2 == 0)
+ as_bad (_("Use of p0 is not valid in this context"));
+ else
+ add_qp_imply (p1, p2);
+ break;
+ case 'm':
+ if (count < 2)
+ {
+ as_bad (_("At least two PR arguments expected"));
+ break;
+ }
+ else if (mask & 1)
+ {
+ as_bad (_("Use of p0 is not valid in this context"));
+ break;
+ }
+ add_qp_mutex (mask);
+ break;
+ case 's':
+ /* note that we don't override any existing relations */
+ if (count == 0)
+ {
+ as_bad (_("At least one PR argument expected"));
+ break;
+ }
+ if (md.debug_dv)
+ {
+ fprintf (stderr, "Safe across calls: ");
+ print_prmask (mask);
+ fprintf (stderr, "\n");
+ }
+ qp_safe_across_calls = mask;
+ break;
+ }
+ demand_empty_rest_of_line ();
+}
+
+/* .entry label [, label [, ...]]
+ Hint to DV code that the given labels are to be considered entry points.
+ Otherwise, only global labels are considered entry points. */
+
+static void
+dot_entry (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ const char *err;
+ char *name;
+ int c;
+ symbolS *symbolP;
+
+ do
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+
+ err = hash_insert (md.entry_hash, S_GET_NAME (symbolP), (PTR) symbolP);
+ if (err)
+ as_fatal (_("Inserting \"%s\" into entry hint table failed: %s"),
+ name, err);
+
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ c = *input_line_pointer;
+ if (c == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\n')
+ c = '\n';
+ }
+ }
+ while (c == ',');
+
+ demand_empty_rest_of_line ();
+}
+
+/* .mem.offset offset, base
+ "base" is used to distinguish between offsets from a different base. */
+
+static void
+dot_mem_offset (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ md.mem_offset.hint = 1;
+ md.mem_offset.offset = get_absolute_expression ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Comma expected"));
+ ignore_rest_of_line ();
+ return;
+ }
+ ++input_line_pointer;
+ md.mem_offset.base = get_absolute_expression ();
+ demand_empty_rest_of_line ();
+}
+
+/* ia64-specific pseudo-ops: */
+const pseudo_typeS md_pseudo_table[] =
+ {
+ { "radix", dot_radix, 0 },
+ { "lcomm", s_lcomm_bytes, 1 },
+ { "bss", dot_special_section, SPECIAL_SECTION_BSS },
+ { "sbss", dot_special_section, SPECIAL_SECTION_SBSS },
+ { "sdata", dot_special_section, SPECIAL_SECTION_SDATA },
+ { "rodata", dot_special_section, SPECIAL_SECTION_RODATA },
+ { "comment", dot_special_section, SPECIAL_SECTION_COMMENT },
+ { "ia_64.unwind", dot_special_section, SPECIAL_SECTION_UNWIND },
+ { "ia_64.unwind_info", dot_special_section, SPECIAL_SECTION_UNWIND_INFO },
+ { "init_array", dot_special_section, SPECIAL_SECTION_INIT_ARRAY },
+ { "fini_array", dot_special_section, SPECIAL_SECTION_FINI_ARRAY },
+ { "proc", dot_proc, 0 },
+ { "body", dot_body, 0 },
+ { "prologue", dot_prologue, 0 },
+ { "endp", dot_endp, 0 },
+
+ { "fframe", dot_fframe, 0 },
+ { "vframe", dot_vframe, 0 },
+ { "vframesp", dot_vframesp, 0 },
+ { "vframepsp", dot_vframepsp, 0 },
+ { "save", dot_save, 0 },
+ { "restore", dot_restore, 0 },
+ { "restorereg", dot_restorereg, 0 },
+ { "restorereg.p", dot_restorereg_p, 0 },
+ { "handlerdata", dot_handlerdata, 0 },
+ { "unwentry", dot_unwentry, 0 },
+ { "altrp", dot_altrp, 0 },
+ { "savesp", dot_savemem, 0 },
+ { "savepsp", dot_savemem, 1 },
+ { "save.g", dot_saveg, 0 },
+ { "save.f", dot_savef, 0 },
+ { "save.b", dot_saveb, 0 },
+ { "save.gf", dot_savegf, 0 },
+ { "spill", dot_spill, 0 },
+ { "spillreg", dot_spillreg, 0 },
+ { "spillsp", dot_spillmem, 0 },
+ { "spillpsp", dot_spillmem, 1 },
+ { "spillreg.p", dot_spillreg_p, 0 },
+ { "spillsp.p", dot_spillmem_p, 0 },
+ { "spillpsp.p", dot_spillmem_p, 1 },
+ { "label_state", dot_label_state, 0 },
+ { "copy_state", dot_copy_state, 0 },
+ { "unwabi", dot_unwabi, 0 },
+ { "personality", dot_personality, 0 },
+#if 0
+ { "estate", dot_estate, 0 },
+#endif
+ { "mii", dot_template, 0x0 },
+ { "mli", dot_template, 0x2 }, /* old format, for compatibility */
+ { "mlx", dot_template, 0x2 },
+ { "mmi", dot_template, 0x4 },
+ { "mfi", dot_template, 0x6 },
+ { "mmf", dot_template, 0x7 },
+ { "mib", dot_template, 0x8 },
+ { "mbb", dot_template, 0x9 },
+ { "bbb", dot_template, 0xb },
+ { "mmb", dot_template, 0xc },
+ { "mfb", dot_template, 0xe },
+#if 0
+ { "lb", dot_scope, 0 },
+ { "le", dot_scope, 1 },
+#endif
+ { "align", dot_align, 0 },
+ { "regstk", dot_regstk, 0 },
+ { "rotr", dot_rot, DYNREG_GR },
+ { "rotf", dot_rot, DYNREG_FR },
+ { "rotp", dot_rot, DYNREG_PR },
+ { "lsb", dot_byteorder, 0 },
+ { "msb", dot_byteorder, 1 },
+ { "psr", dot_psr, 0 },
+ { "alias", dot_alias, 0 },
+ { "secalias", dot_alias, 1 },
+ { "ln", dot_ln, 0 }, /* source line info (for debugging) */
+
+ { "xdata1", dot_xdata, 1 },
+ { "xdata2", dot_xdata, 2 },
+ { "xdata4", dot_xdata, 4 },
+ { "xdata8", dot_xdata, 8 },
+ { "xreal4", dot_xfloat_cons, 'f' },
+ { "xreal8", dot_xfloat_cons, 'd' },
+ { "xreal10", dot_xfloat_cons, 'x' },
+ { "xreal16", dot_xfloat_cons, 'X' },
+ { "xstring", dot_xstringer, 0 },
+ { "xstringz", dot_xstringer, 1 },
+
+ /* unaligned versions: */
+ { "xdata2.ua", dot_xdata_ua, 2 },
+ { "xdata4.ua", dot_xdata_ua, 4 },
+ { "xdata8.ua", dot_xdata_ua, 8 },
+ { "xreal4.ua", dot_xfloat_cons_ua, 'f' },
+ { "xreal8.ua", dot_xfloat_cons_ua, 'd' },
+ { "xreal10.ua", dot_xfloat_cons_ua, 'x' },
+ { "xreal16.ua", dot_xfloat_cons_ua, 'X' },
+
+ /* annotations/DV checking support */
+ { "entry", dot_entry, 0 },
+ { "mem.offset", dot_mem_offset, 0 },
+ { "pred.rel", dot_pred_rel, 0 },
+ { "pred.rel.clear", dot_pred_rel, 'c' },
+ { "pred.rel.imply", dot_pred_rel, 'i' },
+ { "pred.rel.mutex", dot_pred_rel, 'm' },
+ { "pred.safe_across_calls", dot_pred_rel, 's' },
+ { "reg.val", dot_reg_val, 0 },
+ { "auto", dot_dv_mode, 'a' },
+ { "explicit", dot_dv_mode, 'e' },
+ { "default", dot_dv_mode, 'd' },
+
+ /* ??? These are needed to make gas/testsuite/gas/elf/ehopt.s work.
+ IA-64 aligns data allocation pseudo-ops by default, so we have to
+ tell it that these ones are supposed to be unaligned. Long term,
+ should rewrite so that only IA-64 specific data allocation pseudo-ops
+ are aligned by default. */
+ {"2byte", stmt_cons_ua, 2},
+ {"4byte", stmt_cons_ua, 4},
+ {"8byte", stmt_cons_ua, 8},
+
+ { NULL, 0, 0 }
+ };
+
+static const struct pseudo_opcode
+ {
+ const char *name;
+ void (*handler) (int);
+ int arg;
+ }
+pseudo_opcode[] =
+ {
+ /* these are more like pseudo-ops, but don't start with a dot */
+ { "data1", cons, 1 },
+ { "data2", cons, 2 },
+ { "data4", cons, 4 },
+ { "data8", cons, 8 },
+ { "data16", cons, 16 },
+ { "real4", stmt_float_cons, 'f' },
+ { "real8", stmt_float_cons, 'd' },
+ { "real10", stmt_float_cons, 'x' },
+ { "real16", stmt_float_cons, 'X' },
+ { "string", stringer, 0 },
+ { "stringz", stringer, 1 },
+
+ /* unaligned versions: */
+ { "data2.ua", stmt_cons_ua, 2 },
+ { "data4.ua", stmt_cons_ua, 4 },
+ { "data8.ua", stmt_cons_ua, 8 },
+ { "data16.ua", stmt_cons_ua, 16 },
+ { "real4.ua", float_cons, 'f' },
+ { "real8.ua", float_cons, 'd' },
+ { "real10.ua", float_cons, 'x' },
+ { "real16.ua", float_cons, 'X' },
+ };
+
+/* Declare a register by creating a symbol for it and entering it in
+ the symbol table. */
+
+static symbolS *
+declare_register (name, regnum)
+ const char *name;
+ int regnum;
+{
+ const char *err;
+ symbolS *sym;
+
+ sym = symbol_new (name, reg_section, regnum, &zero_address_frag);
+
+ err = hash_insert (md.reg_hash, S_GET_NAME (sym), (PTR) sym);
+ if (err)
+ as_fatal ("Inserting \"%s\" into register table failed: %s",
+ name, err);
+
+ return sym;
+}
+
+static void
+declare_register_set (prefix, num_regs, base_regnum)
+ const char *prefix;
+ int num_regs;
+ int base_regnum;
+{
+ char name[8];
+ int i;
+
+ for (i = 0; i < num_regs; ++i)
+ {
+ sprintf (name, "%s%u", prefix, i);
+ declare_register (name, base_regnum + i);
+ }
+}
+
+static unsigned int
+operand_width (opnd)
+ enum ia64_opnd opnd;
+{
+ const struct ia64_operand *odesc = &elf64_ia64_operands[opnd];
+ unsigned int bits = 0;
+ int i;
+
+ bits = 0;
+ for (i = 0; i < NELEMS (odesc->field) && odesc->field[i].bits; ++i)
+ bits += odesc->field[i].bits;
+
+ return bits;
+}
+
+static enum operand_match_result
+operand_match (idesc, index, e)
+ const struct ia64_opcode *idesc;
+ int index;
+ expressionS *e;
+{
+ enum ia64_opnd opnd = idesc->operands[index];
+ int bits, relocatable = 0;
+ struct insn_fix *fix;
+ bfd_signed_vma val;
+
+ switch (opnd)
+ {
+ /* constants: */
+
+ case IA64_OPND_AR_CCV:
+ if (e->X_op == O_register && e->X_add_number == REG_AR + 32)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_AR_CSD:
+ if (e->X_op == O_register && e->X_add_number == REG_AR + 25)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_AR_PFS:
+ if (e->X_op == O_register && e->X_add_number == REG_AR + 64)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_GR0:
+ if (e->X_op == O_register && e->X_add_number == REG_GR + 0)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_IP:
+ if (e->X_op == O_register && e->X_add_number == REG_IP)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_PR:
+ if (e->X_op == O_register && e->X_add_number == REG_PR)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_PR_ROT:
+ if (e->X_op == O_register && e->X_add_number == REG_PR_ROT)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_PSR:
+ if (e->X_op == O_register && e->X_add_number == REG_PSR)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_PSR_L:
+ if (e->X_op == O_register && e->X_add_number == REG_PSR_L)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_PSR_UM:
+ if (e->X_op == O_register && e->X_add_number == REG_PSR_UM)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_C1:
+ if (e->X_op == O_constant)
+ {
+ if (e->X_add_number == 1)
+ return OPERAND_MATCH;
+ else
+ return OPERAND_OUT_OF_RANGE;
+ }
+ break;
+
+ case IA64_OPND_C8:
+ if (e->X_op == O_constant)
+ {
+ if (e->X_add_number == 8)
+ return OPERAND_MATCH;
+ else
+ return OPERAND_OUT_OF_RANGE;
+ }
+ break;
+
+ case IA64_OPND_C16:
+ if (e->X_op == O_constant)
+ {
+ if (e->X_add_number == 16)
+ return OPERAND_MATCH;
+ else
+ return OPERAND_OUT_OF_RANGE;
+ }
+ break;
+
+ /* register operands: */
+
+ case IA64_OPND_AR3:
+ if (e->X_op == O_register && e->X_add_number >= REG_AR
+ && e->X_add_number < REG_AR + 128)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_B1:
+ case IA64_OPND_B2:
+ if (e->X_op == O_register && e->X_add_number >= REG_BR
+ && e->X_add_number < REG_BR + 8)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_CR3:
+ if (e->X_op == O_register && e->X_add_number >= REG_CR
+ && e->X_add_number < REG_CR + 128)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_F1:
+ case IA64_OPND_F2:
+ case IA64_OPND_F3:
+ case IA64_OPND_F4:
+ if (e->X_op == O_register && e->X_add_number >= REG_FR
+ && e->X_add_number < REG_FR + 128)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_P1:
+ case IA64_OPND_P2:
+ if (e->X_op == O_register && e->X_add_number >= REG_P
+ && e->X_add_number < REG_P + 64)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_R1:
+ case IA64_OPND_R2:
+ case IA64_OPND_R3:
+ if (e->X_op == O_register && e->X_add_number >= REG_GR
+ && e->X_add_number < REG_GR + 128)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_R3_2:
+ if (e->X_op == O_register && e->X_add_number >= REG_GR)
+ {
+ if (e->X_add_number < REG_GR + 4)
+ return OPERAND_MATCH;
+ else if (e->X_add_number < REG_GR + 128)
+ return OPERAND_OUT_OF_RANGE;
+ }
+ break;
+
+ /* indirect operands: */
+ case IA64_OPND_CPUID_R3:
+ case IA64_OPND_DBR_R3:
+ case IA64_OPND_DTR_R3:
+ case IA64_OPND_ITR_R3:
+ case IA64_OPND_IBR_R3:
+ case IA64_OPND_MSR_R3:
+ case IA64_OPND_PKR_R3:
+ case IA64_OPND_PMC_R3:
+ case IA64_OPND_PMD_R3:
+ case IA64_OPND_RR_R3:
+ if (e->X_op == O_index && e->X_op_symbol
+ && (S_GET_VALUE (e->X_op_symbol) - IND_CPUID
+ == opnd - IA64_OPND_CPUID_R3))
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_MR3:
+ if (e->X_op == O_index && !e->X_op_symbol)
+ return OPERAND_MATCH;
+ break;
+
+ /* immediate operands: */
+ case IA64_OPND_CNT2a:
+ case IA64_OPND_LEN4:
+ case IA64_OPND_LEN6:
+ bits = operand_width (idesc->operands[index]);
+ if (e->X_op == O_constant)
+ {
+ if ((bfd_vma) (e->X_add_number - 1) < ((bfd_vma) 1 << bits))
+ return OPERAND_MATCH;
+ else
+ return OPERAND_OUT_OF_RANGE;
+ }
+ break;
+
+ case IA64_OPND_CNT2b:
+ if (e->X_op == O_constant)
+ {
+ if ((bfd_vma) (e->X_add_number - 1) < 3)
+ return OPERAND_MATCH;
+ else
+ return OPERAND_OUT_OF_RANGE;
+ }
+ break;
+
+ case IA64_OPND_CNT2c:
+ val = e->X_add_number;
+ if (e->X_op == O_constant)
+ {
+ if ((val == 0 || val == 7 || val == 15 || val == 16))
+ return OPERAND_MATCH;
+ else
+ return OPERAND_OUT_OF_RANGE;
+ }
+ break;
+
+ case IA64_OPND_SOR:
+ /* SOR must be an integer multiple of 8 */
+ if (e->X_op == O_constant && e->X_add_number & 0x7)
+ return OPERAND_OUT_OF_RANGE;
+ case IA64_OPND_SOF:
+ case IA64_OPND_SOL:
+ if (e->X_op == O_constant)
+ {
+ if ((bfd_vma) e->X_add_number <= 96)
+ return OPERAND_MATCH;
+ else
+ return OPERAND_OUT_OF_RANGE;
+ }
+ break;
+
+ case IA64_OPND_IMMU62:
+ if (e->X_op == O_constant)
+ {
+ if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << 62))
+ return OPERAND_MATCH;
+ else
+ return OPERAND_OUT_OF_RANGE;
+ }
+ else
+ {
+ /* FIXME -- need 62-bit relocation type */
+ as_bad (_("62-bit relocation not yet implemented"));
+ }
+ break;
+
+ case IA64_OPND_IMMU64:
+ if (e->X_op == O_symbol || e->X_op == O_pseudo_fixup
+ || e->X_op == O_subtract)
+ {
+ fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
+ fix->code = BFD_RELOC_IA64_IMM64;
+ if (e->X_op != O_subtract)
+ {
+ fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code);
+ if (e->X_op == O_pseudo_fixup)
+ e->X_op = O_symbol;
+ }
+
+ fix->opnd = idesc->operands[index];
+ fix->expr = *e;
+ fix->is_pcrel = 0;
+ ++CURR_SLOT.num_fixups;
+ return OPERAND_MATCH;
+ }
+ else if (e->X_op == O_constant)
+ return OPERAND_MATCH;
+ break;
+
+ case IA64_OPND_CCNT5:
+ case IA64_OPND_CNT5:
+ case IA64_OPND_CNT6:
+ case IA64_OPND_CPOS6a:
+ case IA64_OPND_CPOS6b:
+ case IA64_OPND_CPOS6c:
+ case IA64_OPND_IMMU2:
+ case IA64_OPND_IMMU7a:
+ case IA64_OPND_IMMU7b:
+ case IA64_OPND_IMMU21:
+ case IA64_OPND_IMMU24:
+ case IA64_OPND_MBTYPE4:
+ case IA64_OPND_MHTYPE8:
+ case IA64_OPND_POS6:
+ bits = operand_width (idesc->operands[index]);
+ if (e->X_op == O_constant)
+ {
+ if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
+ return OPERAND_MATCH;
+ else
+ return OPERAND_OUT_OF_RANGE;
+ }
+ break;
+
+ case IA64_OPND_IMMU9:
+ bits = operand_width (idesc->operands[index]);
+ if (e->X_op == O_constant)
+ {
+ if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
+ {
+ int lobits = e->X_add_number & 0x3;
+ if (((bfd_vma) e->X_add_number & 0x3C) != 0 && lobits == 0)
+ e->X_add_number |= (bfd_vma) 0x3;
+ return OPERAND_MATCH;
+ }
+ else
+ return OPERAND_OUT_OF_RANGE;
+ }
+ break;
+
+ case IA64_OPND_IMM44:
+ /* least 16 bits must be zero */
+ if ((e->X_add_number & 0xffff) != 0)
+ /* XXX technically, this is wrong: we should not be issuing warning
+ messages until we're sure this instruction pattern is going to
+ be used! */
+ as_warn (_("lower 16 bits of mask ignored"));
+
+ if (e->X_op == O_constant)
+ {
+ if (((e->X_add_number >= 0
+ && (bfd_vma) e->X_add_number < ((bfd_vma) 1 << 44))
+ || (e->X_add_number < 0
+ && (bfd_vma) -e->X_add_number <= ((bfd_vma) 1 << 44))))
+ {
+ /* sign-extend */
+ if (e->X_add_number >= 0
+ && (e->X_add_number & ((bfd_vma) 1 << 43)) != 0)
+ {
+ e->X_add_number |= ~(((bfd_vma) 1 << 44) - 1);
+ }
+ return OPERAND_MATCH;
+ }
+ else
+ return OPERAND_OUT_OF_RANGE;
+ }
+ break;
+
+ case IA64_OPND_IMM17:
+ /* bit 0 is a don't care (pr0 is hardwired to 1) */
+ if (e->X_op == O_constant)
+ {
+ if (((e->X_add_number >= 0
+ && (bfd_vma) e->X_add_number < ((bfd_vma) 1 << 17))
+ || (e->X_add_number < 0
+ && (bfd_vma) -e->X_add_number <= ((bfd_vma) 1 << 17))))
+ {
+ /* sign-extend */
+ if (e->X_add_number >= 0
+ && (e->X_add_number & ((bfd_vma) 1 << 16)) != 0)
+ {
+ e->X_add_number |= ~(((bfd_vma) 1 << 17) - 1);
+ }
+ return OPERAND_MATCH;
+ }
+ else
+ return OPERAND_OUT_OF_RANGE;
+ }
+ break;
+
+ case IA64_OPND_IMM14:
+ case IA64_OPND_IMM22:
+ relocatable = 1;
+ case IA64_OPND_IMM1:
+ case IA64_OPND_IMM8:
+ case IA64_OPND_IMM8U4:
+ case IA64_OPND_IMM8M1:
+ case IA64_OPND_IMM8M1U4:
+ case IA64_OPND_IMM8M1U8:
+ case IA64_OPND_IMM9a:
+ case IA64_OPND_IMM9b:
+ bits = operand_width (idesc->operands[index]);
+ if (relocatable && (e->X_op == O_symbol
+ || e->X_op == O_subtract
+ || e->X_op == O_pseudo_fixup))
+ {
+ fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
+
+ if (idesc->operands[index] == IA64_OPND_IMM14)
+ fix->code = BFD_RELOC_IA64_IMM14;
+ else
+ fix->code = BFD_RELOC_IA64_IMM22;
+
+ if (e->X_op != O_subtract)
+ {
+ fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code);
+ if (e->X_op == O_pseudo_fixup)
+ e->X_op = O_symbol;
+ }
+
+ fix->opnd = idesc->operands[index];
+ fix->expr = *e;
+ fix->is_pcrel = 0;
+ ++CURR_SLOT.num_fixups;
+ return OPERAND_MATCH;
+ }
+ else if (e->X_op != O_constant
+ && ! (e->X_op == O_big && opnd == IA64_OPND_IMM8M1U8))
+ return OPERAND_MISMATCH;
+
+ if (opnd == IA64_OPND_IMM8M1U4)
+ {
+ /* Zero is not valid for unsigned compares that take an adjusted
+ constant immediate range. */
+ if (e->X_add_number == 0)
+ return OPERAND_OUT_OF_RANGE;
+
+ /* Sign-extend 32-bit unsigned numbers, so that the following range
+ checks will work. */
+ val = e->X_add_number;
+ if (((val & (~(bfd_vma) 0 << 32)) == 0)
+ && ((val & ((bfd_vma) 1 << 31)) != 0))
+ val = ((val << 32) >> 32);
+
+ /* Check for 0x100000000. This is valid because
+ 0x100000000-1 is the same as ((uint32_t) -1). */
+ if (val == ((bfd_signed_vma) 1 << 32))
+ return OPERAND_MATCH;
+
+ val = val - 1;
+ }
+ else if (opnd == IA64_OPND_IMM8M1U8)
+ {
+ /* Zero is not valid for unsigned compares that take an adjusted
+ constant immediate range. */
+ if (e->X_add_number == 0)
+ return OPERAND_OUT_OF_RANGE;
+
+ /* Check for 0x10000000000000000. */
+ if (e->X_op == O_big)
+ {
+ if (generic_bignum[0] == 0
+ && generic_bignum[1] == 0
+ && generic_bignum[2] == 0
+ && generic_bignum[3] == 0
+ && generic_bignum[4] == 1)
+ return OPERAND_MATCH;
+ else
+ return OPERAND_OUT_OF_RANGE;
+ }
+ else
+ val = e->X_add_number - 1;
+ }
+ else if (opnd == IA64_OPND_IMM8M1)
+ val = e->X_add_number - 1;
+ else if (opnd == IA64_OPND_IMM8U4)
+ {
+ /* Sign-extend 32-bit unsigned numbers, so that the following range
+ checks will work. */
+ val = e->X_add_number;
+ if (((val & (~(bfd_vma) 0 << 32)) == 0)
+ && ((val & ((bfd_vma) 1 << 31)) != 0))
+ val = ((val << 32) >> 32);
+ }
+ else
+ val = e->X_add_number;
+
+ if ((val >= 0 && (bfd_vma) val < ((bfd_vma) 1 << (bits - 1)))
+ || (val < 0 && (bfd_vma) -val <= ((bfd_vma) 1 << (bits - 1))))
+ return OPERAND_MATCH;
+ else
+ return OPERAND_OUT_OF_RANGE;
+
+ case IA64_OPND_INC3:
+ /* +/- 1, 4, 8, 16 */
+ val = e->X_add_number;
+ if (val < 0)
+ val = -val;
+ if (e->X_op == O_constant)
+ {
+ if ((val == 1 || val == 4 || val == 8 || val == 16))
+ return OPERAND_MATCH;
+ else
+ return OPERAND_OUT_OF_RANGE;
+ }
+ break;
+
+ case IA64_OPND_TGT25:
+ case IA64_OPND_TGT25b:
+ case IA64_OPND_TGT25c:
+ case IA64_OPND_TGT64:
+ if (e->X_op == O_symbol)
+ {
+ fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
+ if (opnd == IA64_OPND_TGT25)
+ fix->code = BFD_RELOC_IA64_PCREL21F;
+ else if (opnd == IA64_OPND_TGT25b)
+ fix->code = BFD_RELOC_IA64_PCREL21M;
+ else if (opnd == IA64_OPND_TGT25c)
+ fix->code = BFD_RELOC_IA64_PCREL21B;
+ else if (opnd == IA64_OPND_TGT64)
+ fix->code = BFD_RELOC_IA64_PCREL60B;
+ else
+ abort ();
+
+ fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code);
+ fix->opnd = idesc->operands[index];
+ fix->expr = *e;
+ fix->is_pcrel = 1;
+ ++CURR_SLOT.num_fixups;
+ return OPERAND_MATCH;
+ }
+ case IA64_OPND_TAG13:
+ case IA64_OPND_TAG13b:
+ switch (e->X_op)
+ {
+ case O_constant:
+ return OPERAND_MATCH;
+
+ case O_symbol:
+ fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
+ /* There are no external relocs for TAG13/TAG13b fields, so we
+ create a dummy reloc. This will not live past md_apply_fix3. */
+ fix->code = BFD_RELOC_UNUSED;
+ fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code);
+ fix->opnd = idesc->operands[index];
+ fix->expr = *e;
+ fix->is_pcrel = 1;
+ ++CURR_SLOT.num_fixups;
+ return OPERAND_MATCH;
+
+ default:
+ break;
+ }
+ break;
+
+ case IA64_OPND_LDXMOV:
+ fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
+ fix->code = BFD_RELOC_IA64_LDXMOV;
+ fix->opnd = idesc->operands[index];
+ fix->expr = *e;
+ fix->is_pcrel = 0;
+ ++CURR_SLOT.num_fixups;
+ return OPERAND_MATCH;
+
+ default:
+ break;
+ }
+ return OPERAND_MISMATCH;
+}
+
+static int
+parse_operand (e)
+ expressionS *e;
+{
+ int sep = '\0';
+
+ memset (e, 0, sizeof (*e));
+ e->X_op = O_absent;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '}')
+ expression (e);
+ sep = *input_line_pointer++;
+
+ if (sep == '}')
+ {
+ if (!md.manual_bundling)
+ as_warn ("Found '}' when manual bundling is off");
+ else
+ CURR_SLOT.manual_bundling_off = 1;
+ md.manual_bundling = 0;
+ sep = '\0';
+ }
+ return sep;
+}
+
+/* Returns the next entry in the opcode table that matches the one in
+ IDESC, and frees the entry in IDESC. If no matching entry is
+ found, NULL is returned instead. */
+
+static struct ia64_opcode *
+get_next_opcode (struct ia64_opcode *idesc)
+{
+ struct ia64_opcode *next = ia64_find_next_opcode (idesc);
+ ia64_free_opcode (idesc);
+ return next;
+}
+
+/* Parse the operands for the opcode and find the opcode variant that
+ matches the specified operands, or NULL if no match is possible. */
+
+static struct ia64_opcode *
+parse_operands (idesc)
+ struct ia64_opcode *idesc;
+{
+ int i = 0, highest_unmatched_operand, num_operands = 0, num_outputs = 0;
+ int error_pos, out_of_range_pos, curr_out_of_range_pos, sep = 0;
+ enum ia64_opnd expected_operand = IA64_OPND_NIL;
+ enum operand_match_result result;
+ char mnemonic[129];
+ char *first_arg = 0, *end, *saved_input_pointer;
+ unsigned int sof;
+
+ assert (strlen (idesc->name) <= 128);
+
+ strcpy (mnemonic, idesc->name);
+ if (idesc->operands[2] == IA64_OPND_SOF)
+ {
+ /* To make the common idiom "alloc loc?=ar.pfs,0,1,0,0" work, we
+ can't parse the first operand until we have parsed the
+ remaining operands of the "alloc" instruction. */
+ SKIP_WHITESPACE ();
+ first_arg = input_line_pointer;
+ end = strchr (input_line_pointer, '=');
+ if (!end)
+ {
+ as_bad ("Expected separator `='");
+ return 0;
+ }
+ input_line_pointer = end + 1;
+ ++i;
+ ++num_outputs;
+ }
+
+ for (; i < NELEMS (CURR_SLOT.opnd); ++i)
+ {
+ sep = parse_operand (CURR_SLOT.opnd + i);
+ if (CURR_SLOT.opnd[i].X_op == O_absent)
+ break;
+
+ ++num_operands;
+
+ if (sep != '=' && sep != ',')
+ break;
+
+ if (sep == '=')
+ {
+ if (num_outputs > 0)
+ as_bad ("Duplicate equal sign (=) in instruction");
+ else
+ num_outputs = i + 1;
+ }
+ }
+ if (sep != '\0')
+ {
+ as_bad ("Illegal operand separator `%c'", sep);
+ return 0;
+ }
+
+ if (idesc->operands[2] == IA64_OPND_SOF)
+ {
+ /* map alloc r1=ar.pfs,i,l,o,r to alloc r1=ar.pfs,(i+l+o),(i+l),r */
+ know (strcmp (idesc->name, "alloc") == 0);
+ if (num_operands == 5 /* first_arg not included in this count! */
+ && CURR_SLOT.opnd[2].X_op == O_constant
+ && CURR_SLOT.opnd[3].X_op == O_constant
+ && CURR_SLOT.opnd[4].X_op == O_constant
+ && CURR_SLOT.opnd[5].X_op == O_constant)
+ {
+ sof = set_regstack (CURR_SLOT.opnd[2].X_add_number,
+ CURR_SLOT.opnd[3].X_add_number,
+ CURR_SLOT.opnd[4].X_add_number,
+ CURR_SLOT.opnd[5].X_add_number);
+
+ /* now we can parse the first arg: */
+ saved_input_pointer = input_line_pointer;
+ input_line_pointer = first_arg;
+ sep = parse_operand (CURR_SLOT.opnd + 0);
+ if (sep != '=')
+ --num_outputs; /* force error */
+ input_line_pointer = saved_input_pointer;
+
+ CURR_SLOT.opnd[2].X_add_number = sof;
+ CURR_SLOT.opnd[3].X_add_number
+ = sof - CURR_SLOT.opnd[4].X_add_number;
+ CURR_SLOT.opnd[4] = CURR_SLOT.opnd[5];
+ }
+ }
+
+ highest_unmatched_operand = 0;
+ curr_out_of_range_pos = -1;
+ error_pos = 0;
+ expected_operand = idesc->operands[0];
+ for (; idesc; idesc = get_next_opcode (idesc))
+ {
+ if (num_outputs != idesc->num_outputs)
+ continue; /* mismatch in # of outputs */
+
+ CURR_SLOT.num_fixups = 0;
+
+ /* Try to match all operands. If we see an out-of-range operand,
+ then continue trying to match the rest of the operands, since if
+ the rest match, then this idesc will give the best error message. */
+
+ out_of_range_pos = -1;
+ for (i = 0; i < num_operands && idesc->operands[i]; ++i)
+ {
+ result = operand_match (idesc, i, CURR_SLOT.opnd + i);
+ if (result != OPERAND_MATCH)
+ {
+ if (result != OPERAND_OUT_OF_RANGE)
+ break;
+ if (out_of_range_pos < 0)
+ /* remember position of the first out-of-range operand: */
+ out_of_range_pos = i;
+ }
+ }
+
+ /* If we did not match all operands, or if at least one operand was
+ out-of-range, then this idesc does not match. Keep track of which
+ idesc matched the most operands before failing. If we have two
+ idescs that failed at the same position, and one had an out-of-range
+ operand, then prefer the out-of-range operand. Thus if we have
+ "add r0=0x1000000,r1" we get an error saying the constant is out
+ of range instead of an error saying that the constant should have been
+ a register. */
+
+ if (i != num_operands || out_of_range_pos >= 0)
+ {
+ if (i > highest_unmatched_operand
+ || (i == highest_unmatched_operand
+ && out_of_range_pos > curr_out_of_range_pos))
+ {
+ highest_unmatched_operand = i;
+ if (out_of_range_pos >= 0)
+ {
+ expected_operand = idesc->operands[out_of_range_pos];
+ error_pos = out_of_range_pos;
+ }
+ else
+ {
+ expected_operand = idesc->operands[i];
+ error_pos = i;
+ }
+ curr_out_of_range_pos = out_of_range_pos;
+ }
+ continue;
+ }
+
+ if (num_operands < NELEMS (idesc->operands)
+ && idesc->operands[num_operands])
+ continue; /* mismatch in number of arguments */
+
+ break;
+ }
+ if (!idesc)
+ {
+ if (expected_operand)
+ as_bad ("Operand %u of `%s' should be %s",
+ error_pos + 1, mnemonic,
+ elf64_ia64_operands[expected_operand].desc);
+ else
+ as_bad ("Operand mismatch");
+ return 0;
+ }
+ return idesc;
+}
+
+/* Keep track of state necessary to determine whether a NOP is necessary
+ to avoid an erratum in A and B step Itanium chips, and return 1 if we
+ detect a case where additional NOPs may be necessary. */
+static int
+errata_nop_necessary_p (slot, insn_unit)
+ struct slot *slot;
+ enum ia64_unit insn_unit;
+{
+ int i;
+ struct group *this_group = md.last_groups + md.group_idx;
+ struct group *prev_group = md.last_groups + (md.group_idx + 2) % 3;
+ struct ia64_opcode *idesc = slot->idesc;
+
+ /* Test whether this could be the first insn in a problematic sequence. */
+ if (insn_unit == IA64_UNIT_F)
+ {
+ for (i = 0; i < idesc->num_outputs; i++)
+ if (idesc->operands[i] == IA64_OPND_P1
+ || idesc->operands[i] == IA64_OPND_P2)
+ {
+ int regno = slot->opnd[i].X_add_number - REG_P;
+ /* Ignore invalid operands; they generate errors elsewhere. */
+ if (regno >= 64)
+ return 0;
+ this_group->p_reg_set[regno] = 1;
+ }
+ }
+
+ /* Test whether this could be the second insn in a problematic sequence. */
+ if (insn_unit == IA64_UNIT_M && slot->qp_regno > 0
+ && prev_group->p_reg_set[slot->qp_regno])
+ {
+ for (i = 0; i < idesc->num_outputs; i++)
+ if (idesc->operands[i] == IA64_OPND_R1
+ || idesc->operands[i] == IA64_OPND_R2
+ || idesc->operands[i] == IA64_OPND_R3)
+ {
+ int regno = slot->opnd[i].X_add_number - REG_GR;
+ /* Ignore invalid operands; they generate errors elsewhere. */
+ if (regno >= 128)
+ return 0;
+ if (strncmp (idesc->name, "add", 3) != 0
+ && strncmp (idesc->name, "sub", 3) != 0
+ && strncmp (idesc->name, "shladd", 6) != 0
+ && (idesc->flags & IA64_OPCODE_POSTINC) == 0)
+ this_group->g_reg_set_conditionally[regno] = 1;
+ }
+ }
+
+ /* Test whether this could be the third insn in a problematic sequence. */
+ for (i = 0; i < NELEMS (idesc->operands) && idesc->operands[i]; i++)
+ {
+ if (/* For fc, ptc, ptr, tak, thash, tpa, ttag, probe, ptr, ptc. */
+ idesc->operands[i] == IA64_OPND_R3
+ /* For mov indirect. */
+ || idesc->operands[i] == IA64_OPND_RR_R3
+ || idesc->operands[i] == IA64_OPND_DBR_R3
+ || idesc->operands[i] == IA64_OPND_IBR_R3
+ || idesc->operands[i] == IA64_OPND_PKR_R3
+ || idesc->operands[i] == IA64_OPND_PMC_R3
+ || idesc->operands[i] == IA64_OPND_PMD_R3
+ || idesc->operands[i] == IA64_OPND_MSR_R3
+ || idesc->operands[i] == IA64_OPND_CPUID_R3
+ /* For itr. */
+ || idesc->operands[i] == IA64_OPND_ITR_R3
+ || idesc->operands[i] == IA64_OPND_DTR_R3
+ /* Normal memory addresses (load, store, xchg, cmpxchg, etc.). */
+ || idesc->operands[i] == IA64_OPND_MR3)
+ {
+ int regno = slot->opnd[i].X_add_number - REG_GR;
+ /* Ignore invalid operands; they generate errors elsewhere. */
+ if (regno >= 128)
+ return 0;
+ if (idesc->operands[i] == IA64_OPND_R3)
+ {
+ if (strcmp (idesc->name, "fc") != 0
+ && strcmp (idesc->name, "tak") != 0
+ && strcmp (idesc->name, "thash") != 0
+ && strcmp (idesc->name, "tpa") != 0
+ && strcmp (idesc->name, "ttag") != 0
+ && strncmp (idesc->name, "ptr", 3) != 0
+ && strncmp (idesc->name, "ptc", 3) != 0
+ && strncmp (idesc->name, "probe", 5) != 0)
+ return 0;
+ }
+ if (prev_group->g_reg_set_conditionally[regno])
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void
+build_insn (slot, insnp)
+ struct slot *slot;
+ bfd_vma *insnp;
+{
+ const struct ia64_operand *odesc, *o2desc;
+ struct ia64_opcode *idesc = slot->idesc;
+ bfd_signed_vma insn, val;
+ const char *err;
+ int i;
+
+ insn = idesc->opcode | slot->qp_regno;
+
+ for (i = 0; i < NELEMS (idesc->operands) && idesc->operands[i]; ++i)
+ {
+ if (slot->opnd[i].X_op == O_register
+ || slot->opnd[i].X_op == O_constant
+ || slot->opnd[i].X_op == O_index)
+ val = slot->opnd[i].X_add_number;
+ else if (slot->opnd[i].X_op == O_big)
+ {
+ /* This must be the value 0x10000000000000000. */
+ assert (idesc->operands[i] == IA64_OPND_IMM8M1U8);
+ val = 0;
+ }
+ else
+ val = 0;
+
+ switch (idesc->operands[i])
+ {
+ case IA64_OPND_IMMU64:
+ *insnp++ = (val >> 22) & 0x1ffffffffffLL;
+ insn |= (((val & 0x7f) << 13) | (((val >> 7) & 0x1ff) << 27)
+ | (((val >> 16) & 0x1f) << 22) | (((val >> 21) & 0x1) << 21)
+ | (((val >> 63) & 0x1) << 36));
+ continue;
+
+ case IA64_OPND_IMMU62:
+ val &= 0x3fffffffffffffffULL;
+ if (val != slot->opnd[i].X_add_number)
+ as_warn (_("Value truncated to 62 bits"));
+ *insnp++ = (val >> 21) & 0x1ffffffffffLL;
+ insn |= (((val & 0xfffff) << 6) | (((val >> 20) & 0x1) << 36));
+ continue;
+
+ case IA64_OPND_TGT64:
+ val >>= 4;
+ *insnp++ = ((val >> 20) & 0x7fffffffffLL) << 2;
+ insn |= ((((val >> 59) & 0x1) << 36)
+ | (((val >> 0) & 0xfffff) << 13));
+ continue;
+
+ case IA64_OPND_AR3:
+ val -= REG_AR;
+ break;
+
+ case IA64_OPND_B1:
+ case IA64_OPND_B2:
+ val -= REG_BR;
+ break;
+
+ case IA64_OPND_CR3:
+ val -= REG_CR;
+ break;
+
+ case IA64_OPND_F1:
+ case IA64_OPND_F2:
+ case IA64_OPND_F3:
+ case IA64_OPND_F4:
+ val -= REG_FR;
+ break;
+
+ case IA64_OPND_P1:
+ case IA64_OPND_P2:
+ val -= REG_P;
+ break;
+
+ case IA64_OPND_R1:
+ case IA64_OPND_R2:
+ case IA64_OPND_R3:
+ case IA64_OPND_R3_2:
+ case IA64_OPND_CPUID_R3:
+ case IA64_OPND_DBR_R3:
+ case IA64_OPND_DTR_R3:
+ case IA64_OPND_ITR_R3:
+ case IA64_OPND_IBR_R3:
+ case IA64_OPND_MR3:
+ case IA64_OPND_MSR_R3:
+ case IA64_OPND_PKR_R3:
+ case IA64_OPND_PMC_R3:
+ case IA64_OPND_PMD_R3:
+ case IA64_OPND_RR_R3:
+ val -= REG_GR;
+ break;
+
+ default:
+ break;
+ }
+
+ odesc = elf64_ia64_operands + idesc->operands[i];
+ err = (*odesc->insert) (odesc, val, &insn);
+ if (err)
+ as_bad_where (slot->src_file, slot->src_line,
+ "Bad operand value: %s", err);
+ if (idesc->flags & IA64_OPCODE_PSEUDO)
+ {
+ if ((idesc->flags & IA64_OPCODE_F2_EQ_F3)
+ && odesc == elf64_ia64_operands + IA64_OPND_F3)
+ {
+ o2desc = elf64_ia64_operands + IA64_OPND_F2;
+ (*o2desc->insert) (o2desc, val, &insn);
+ }
+ if ((idesc->flags & IA64_OPCODE_LEN_EQ_64MCNT)
+ && (odesc == elf64_ia64_operands + IA64_OPND_CPOS6a
+ || odesc == elf64_ia64_operands + IA64_OPND_POS6))
+ {
+ o2desc = elf64_ia64_operands + IA64_OPND_LEN6;
+ (*o2desc->insert) (o2desc, 64 - val, &insn);
+ }
+ }
+ }
+ *insnp = insn;
+}
+
+static void
+emit_one_bundle ()
+{
+ unsigned int manual_bundling_on = 0, manual_bundling_off = 0;
+ unsigned int manual_bundling = 0;
+ enum ia64_unit required_unit, insn_unit = 0;
+ enum ia64_insn_type type[3], insn_type;
+ unsigned int template, orig_template;
+ bfd_vma insn[3] = { -1, -1, -1 };
+ struct ia64_opcode *idesc;
+ int end_of_insn_group = 0, user_template = -1;
+ int n, i, j, first, curr;
+ unw_rec_list *ptr, *last_ptr, *end_ptr;
+ bfd_vma t0 = 0, t1 = 0;
+ struct label_fix *lfix;
+ struct insn_fix *ifix;
+ char mnemonic[16];
+ fixS *fix;
+ char *f;
+
+ first = (md.curr_slot + NUM_SLOTS - md.num_slots_in_use) % NUM_SLOTS;
+ know (first >= 0 & first < NUM_SLOTS);
+ n = MIN (3, md.num_slots_in_use);
+
+ /* Determine template: user user_template if specified, best match
+ otherwise: */
+
+ if (md.slot[first].user_template >= 0)
+ user_template = template = md.slot[first].user_template;
+ else
+ {
+ /* Auto select appropriate template. */
+ memset (type, 0, sizeof (type));
+ curr = first;
+ for (i = 0; i < n; ++i)
+ {
+ if (md.slot[curr].label_fixups && i != 0)
+ break;
+ type[i] = md.slot[curr].idesc->type;
+ curr = (curr + 1) % NUM_SLOTS;
+ }
+ template = best_template[type[0]][type[1]][type[2]];
+ }
+
+ /* initialize instructions with appropriate nops: */
+ for (i = 0; i < 3; ++i)
+ insn[i] = nop[ia64_templ_desc[template].exec_unit[i]];
+
+ f = frag_more (16);
+
+ /* now fill in slots with as many insns as possible: */
+ curr = first;
+ idesc = md.slot[curr].idesc;
+ end_of_insn_group = 0;
+ for (i = 0; i < 3 && md.num_slots_in_use > 0; ++i)
+ {
+ /* If we have unwind records, we may need to update some now. */
+ ptr = md.slot[curr].unwind_record;
+ if (ptr)
+ {
+ /* Find the last prologue/body record in the list for the current
+ insn, and set the slot number for all records up to that point.
+ This needs to be done now, because prologue/body records refer to
+ the current point, not the point after the instruction has been
+ issued. This matters because there may have been nops emitted
+ meanwhile. Any non-prologue non-body record followed by a
+ prologue/body record must also refer to the current point. */
+ last_ptr = NULL;
+ end_ptr = md.slot[(curr + 1) % NUM_SLOTS].unwind_record;
+ for (; ptr != end_ptr; ptr = ptr->next)
+ if (ptr->r.type == prologue || ptr->r.type == prologue_gr
+ || ptr->r.type == body)
+ last_ptr = ptr;
+ if (last_ptr)
+ {
+ /* Make last_ptr point one after the last prologue/body
+ record. */
+ last_ptr = last_ptr->next;
+ for (ptr = md.slot[curr].unwind_record; ptr != last_ptr;
+ ptr = ptr->next)
+ {
+ ptr->slot_number = (unsigned long) f + i;
+ ptr->slot_frag = frag_now;
+ }
+ /* Remove the initialized records, so that we won't accidentally
+ update them again if we insert a nop and continue. */
+ md.slot[curr].unwind_record = last_ptr;
+ }
+ }
+
+ if (idesc->flags & IA64_OPCODE_SLOT2)
+ {
+ if (manual_bundling && i != 2)
+ as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
+ "`%s' must be last in bundle", idesc->name);
+ else
+ i = 2;
+ }
+ if (idesc->flags & IA64_OPCODE_LAST)
+ {
+ int required_slot;
+ unsigned int required_template;
+
+ /* If we need a stop bit after an M slot, our only choice is
+ template 5 (M;;MI). If we need a stop bit after a B
+ slot, our only choice is to place it at the end of the
+ bundle, because the only available templates are MIB,
+ MBB, BBB, MMB, and MFB. We don't handle anything other
+ than M and B slots because these are the only kind of
+ instructions that can have the IA64_OPCODE_LAST bit set. */
+ required_template = template;
+ switch (idesc->type)
+ {
+ case IA64_TYPE_M:
+ required_slot = 0;
+ required_template = 5;
+ break;
+
+ case IA64_TYPE_B:
+ required_slot = 2;
+ break;
+
+ default:
+ as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
+ "Internal error: don't know how to force %s to end"
+ "of instruction group", idesc->name);
+ required_slot = i;
+ break;
+ }
+ if (manual_bundling && i != required_slot)
+ as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
+ "`%s' must be last in instruction group",
+ idesc->name);
+ if (required_slot < i)
+ /* Can't fit this instruction. */
+ break;
+
+ i = required_slot;
+ if (required_template != template)
+ {
+ /* If we switch the template, we need to reset the NOPs
+ after slot i. The slot-types of the instructions ahead
+ of i never change, so we don't need to worry about
+ changing NOPs in front of this slot. */
+ for (j = i; j < 3; ++j)
+ insn[j] = nop[ia64_templ_desc[required_template].exec_unit[j]];
+ }
+ template = required_template;
+ }
+ if (curr != first && md.slot[curr].label_fixups)
+ {
+ if (manual_bundling_on)
+ as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
+ "Label must be first in a bundle");
+ /* This insn must go into the first slot of a bundle. */
+ break;
+ }
+
+ manual_bundling_on = md.slot[curr].manual_bundling_on;
+ manual_bundling_off = md.slot[curr].manual_bundling_off;
+
+ if (manual_bundling_on)
+ {
+ if (curr == first)
+ manual_bundling = 1;
+ else
+ break; /* need to start a new bundle */
+ }
+
+ if (end_of_insn_group && md.num_slots_in_use >= 1)
+ {
+ /* We need an instruction group boundary in the middle of a
+ bundle. See if we can switch to an other template with
+ an appropriate boundary. */
+
+ orig_template = template;
+ if (i == 1 && (user_template == 4
+ || (user_template < 0
+ && (ia64_templ_desc[template].exec_unit[0]
+ == IA64_UNIT_M))))
+ {
+ template = 5;
+ end_of_insn_group = 0;
+ }
+ else if (i == 2 && (user_template == 0
+ || (user_template < 0
+ && (ia64_templ_desc[template].exec_unit[1]
+ == IA64_UNIT_I)))
+ /* This test makes sure we don't switch the template if
+ the next instruction is one that needs to be first in
+ an instruction group. Since all those instructions are
+ in the M group, there is no way such an instruction can
+ fit in this bundle even if we switch the template. The
+ reason we have to check for this is that otherwise we
+ may end up generating "MI;;I M.." which has the deadly
+ effect that the second M instruction is no longer the
+ first in the bundle! --davidm 99/12/16 */
+ && (idesc->flags & IA64_OPCODE_FIRST) == 0)
+ {
+ template = 1;
+ end_of_insn_group = 0;
+ }
+ else if (curr != first)
+ /* can't fit this insn */
+ break;
+
+ if (template != orig_template)
+ /* if we switch the template, we need to reset the NOPs
+ after slot i. The slot-types of the instructions ahead
+ of i never change, so we don't need to worry about
+ changing NOPs in front of this slot. */
+ for (j = i; j < 3; ++j)
+ insn[j] = nop[ia64_templ_desc[template].exec_unit[j]];
+ }
+ required_unit = ia64_templ_desc[template].exec_unit[i];
+
+ /* resolve dynamic opcodes such as "break", "hint", and "nop": */
+ if (idesc->type == IA64_TYPE_DYN)
+ {
+ if ((strcmp (idesc->name, "nop") == 0)
+ || (strcmp (idesc->name, "hint") == 0)
+ || (strcmp (idesc->name, "break") == 0))
+ insn_unit = required_unit;
+ else if (strcmp (idesc->name, "chk.s") == 0)
+ {
+ insn_unit = IA64_UNIT_M;
+ if (required_unit == IA64_UNIT_I)
+ insn_unit = IA64_UNIT_I;
+ }
+ else
+ as_fatal ("emit_one_bundle: unexpected dynamic op");
+
+ sprintf (mnemonic, "%s.%c", idesc->name, "?imbf??"[insn_unit]);
+ ia64_free_opcode (idesc);
+ md.slot[curr].idesc = idesc = ia64_find_opcode (mnemonic);
+#if 0
+ know (!idesc->next); /* no resolved dynamic ops have collisions */
+#endif
+ }
+ else
+ {
+ insn_type = idesc->type;
+ insn_unit = IA64_UNIT_NIL;
+ switch (insn_type)
+ {
+ case IA64_TYPE_A:
+ if (required_unit == IA64_UNIT_I || required_unit == IA64_UNIT_M)
+ insn_unit = required_unit;
+ break;
+ case IA64_TYPE_X: insn_unit = IA64_UNIT_L; break;
+ case IA64_TYPE_I: insn_unit = IA64_UNIT_I; break;
+ case IA64_TYPE_M: insn_unit = IA64_UNIT_M; break;
+ case IA64_TYPE_B: insn_unit = IA64_UNIT_B; break;
+ case IA64_TYPE_F: insn_unit = IA64_UNIT_F; break;
+ default: break;
+ }
+ }
+
+ if (insn_unit != required_unit)
+ {
+ if (required_unit == IA64_UNIT_L
+ && insn_unit == IA64_UNIT_I
+ && !(idesc->flags & IA64_OPCODE_X_IN_MLX))
+ {
+ /* we got ourselves an MLX template but the current
+ instruction isn't an X-unit, or an I-unit instruction
+ that can go into the X slot of an MLX template. Duh. */
+ if (md.num_slots_in_use >= NUM_SLOTS)
+ {
+ as_bad_where (md.slot[curr].src_file,
+ md.slot[curr].src_line,
+ "`%s' can't go in X slot of "
+ "MLX template", idesc->name);
+ /* drop this insn so we don't livelock: */
+ --md.num_slots_in_use;
+ }
+ break;
+ }
+ continue; /* try next slot */
+ }
+
+ {
+ bfd_vma addr;
+
+ addr = frag_now->fr_address + frag_now_fix () - 16 + i;
+ dwarf2_gen_line_info (addr, &md.slot[curr].debug_line);
+ }
+
+ if (errata_nop_necessary_p (md.slot + curr, insn_unit))
+ as_warn (_("Additional NOP may be necessary to workaround Itanium processor A/B step errata"));
+
+ build_insn (md.slot + curr, insn + i);
+
+ ptr = md.slot[curr].unwind_record;
+ if (ptr)
+ {
+ /* Set slot numbers for all remaining unwind records belonging to the
+ current insn. There can not be any prologue/body unwind records
+ here. */
+ end_ptr = md.slot[(curr + 1) % NUM_SLOTS].unwind_record;
+ for (; ptr != end_ptr; ptr = ptr->next)
+ {
+ ptr->slot_number = (unsigned long) f + i;
+ ptr->slot_frag = frag_now;
+ }
+ md.slot[curr].unwind_record = NULL;
+ }
+
+ if (required_unit == IA64_UNIT_L)
+ {
+ know (i == 1);
+ /* skip one slot for long/X-unit instructions */
+ ++i;
+ }
+ --md.num_slots_in_use;
+
+ /* now is a good time to fix up the labels for this insn: */
+ for (lfix = md.slot[curr].label_fixups; lfix; lfix = lfix->next)
+ {
+ S_SET_VALUE (lfix->sym, frag_now_fix () - 16);
+ symbol_set_frag (lfix->sym, frag_now);
+ }
+ /* and fix up the tags also. */
+ for (lfix = md.slot[curr].tag_fixups; lfix; lfix = lfix->next)
+ {
+ S_SET_VALUE (lfix->sym, frag_now_fix () - 16 + i);
+ symbol_set_frag (lfix->sym, frag_now);
+ }
+
+ for (j = 0; j < md.slot[curr].num_fixups; ++j)
+ {
+ ifix = md.slot[curr].fixup + j;
+ fix = fix_new_exp (frag_now, frag_now_fix () - 16 + i, 8,
+ &ifix->expr, ifix->is_pcrel, ifix->code);
+ fix->tc_fix_data.opnd = ifix->opnd;
+ fix->fx_plt = (fix->fx_r_type == BFD_RELOC_IA64_PLTOFF22);
+ fix->fx_file = md.slot[curr].src_file;
+ fix->fx_line = md.slot[curr].src_line;
+ }
+
+ end_of_insn_group = md.slot[curr].end_of_insn_group;
+
+ if (end_of_insn_group)
+ {
+ md.group_idx = (md.group_idx + 1) % 3;
+ memset (md.last_groups + md.group_idx, 0, sizeof md.last_groups[0]);
+ }
+
+ /* clear slot: */
+ ia64_free_opcode (md.slot[curr].idesc);
+ memset (md.slot + curr, 0, sizeof (md.slot[curr]));
+ md.slot[curr].user_template = -1;
+
+ if (manual_bundling_off)
+ {
+ manual_bundling = 0;
+ break;
+ }
+ curr = (curr + 1) % NUM_SLOTS;
+ idesc = md.slot[curr].idesc;
+ }
+ if (manual_bundling)
+ {
+ if (md.num_slots_in_use > 0)
+ as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
+ "`%s' does not fit into %s template",
+ idesc->name, ia64_templ_desc[template].name);
+ else
+ as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
+ "Missing '}' at end of file");
+ }
+ know (md.num_slots_in_use < NUM_SLOTS);
+
+ t0 = end_of_insn_group | (template << 1) | (insn[0] << 5) | (insn[1] << 46);
+ t1 = ((insn[1] >> 18) & 0x7fffff) | (insn[2] << 23);
+
+ number_to_chars_littleendian (f + 0, t0, 8);
+ number_to_chars_littleendian (f + 8, t1, 8);
+
+ if (unwind.list)
+ {
+ unwind.list->next_slot_number = (unsigned long) f + 16;
+ unwind.list->next_slot_frag = frag_now;
+ }
+}
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+
+ switch (c)
+ {
+ /* Switches from the Intel assembler. */
+ case 'm':
+ if (strcmp (arg, "ilp64") == 0
+ || strcmp (arg, "lp64") == 0
+ || strcmp (arg, "p64") == 0)
+ {
+ md.flags |= EF_IA_64_ABI64;
+ }
+ else if (strcmp (arg, "ilp32") == 0)
+ {
+ md.flags &= ~EF_IA_64_ABI64;
+ }
+ else if (strcmp (arg, "le") == 0)
+ {
+ md.flags &= ~EF_IA_64_BE;
+ }
+ else if (strcmp (arg, "be") == 0)
+ {
+ md.flags |= EF_IA_64_BE;
+ }
+ else
+ return 0;
+ break;
+
+ case 'N':
+ if (strcmp (arg, "so") == 0)
+ {
+ /* Suppress signon message. */
+ }
+ else if (strcmp (arg, "pi") == 0)
+ {
+ /* Reject privileged instructions. FIXME */
+ }
+ else if (strcmp (arg, "us") == 0)
+ {
+ /* Allow union of signed and unsigned range. FIXME */
+ }
+ else if (strcmp (arg, "close_fcalls") == 0)
+ {
+ /* Do not resolve global function calls. */
+ }
+ else
+ return 0;
+ break;
+
+ case 'C':
+ /* temp[="prefix"] Insert temporary labels into the object file
+ symbol table prefixed by "prefix".
+ Default prefix is ":temp:".
+ */
+ break;
+
+ case 'a':
+ /* indirect=<tgt> Assume unannotated indirect branches behavior
+ according to <tgt> --
+ exit: branch out from the current context (default)
+ labels: all labels in context may be branch targets
+ */
+ if (strncmp (arg, "indirect=", 9) != 0)
+ return 0;
+ break;
+
+ case 'x':
+ /* -X conflicts with an ignored option, use -x instead */
+ md.detect_dv = 1;
+ if (!arg || strcmp (arg, "explicit") == 0)
+ {
+ /* set default mode to explicit */
+ md.default_explicit_mode = 1;
+ break;
+ }
+ else if (strcmp (arg, "auto") == 0)
+ {
+ md.default_explicit_mode = 0;
+ }
+ else if (strcmp (arg, "debug") == 0)
+ {
+ md.debug_dv = 1;
+ }
+ else if (strcmp (arg, "debugx") == 0)
+ {
+ md.default_explicit_mode = 1;
+ md.debug_dv = 1;
+ }
+ else
+ {
+ as_bad (_("Unrecognized option '-x%s'"), arg);
+ }
+ break;
+
+ case 'S':
+ /* nops Print nops statistics. */
+ break;
+
+ /* GNU specific switches for gcc. */
+ case OPTION_MCONSTANT_GP:
+ md.flags |= EF_IA_64_CONS_GP;
+ break;
+
+ case OPTION_MAUTO_PIC:
+ md.flags |= EF_IA_64_NOFUNCDESC_CONS_GP;
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fputs (_("\
+IA-64 options:\n\
+ --mconstant-gp mark output file as using the constant-GP model\n\
+ (sets ELF header flag EF_IA_64_CONS_GP)\n\
+ --mauto-pic mark output file as using the constant-GP model\n\
+ without function descriptors (sets ELF header flag\n\
+ EF_IA_64_NOFUNCDESC_CONS_GP)\n\
+ -milp32|-milp64|-mlp64|-mp64 select data model (default -mlp64)\n\
+ -mle | -mbe select little- or big-endian byte order (default -mle)\n\
+ -x | -xexplicit turn on dependency violation checking (default)\n\
+ -xauto automagically remove dependency violations\n\
+ -xdebug debug dependency violation checker\n"),
+ stream);
+}
+
+void
+ia64_after_parse_args ()
+{
+ if (debug_type == DEBUG_STABS)
+ as_fatal (_("--gstabs is not supported for ia64"));
+}
+
+/* Return true if TYPE fits in TEMPL at SLOT. */
+
+static int
+match (int templ, int type, int slot)
+{
+ enum ia64_unit unit;
+ int result;
+
+ unit = ia64_templ_desc[templ].exec_unit[slot];
+ switch (type)
+ {
+ case IA64_TYPE_DYN: result = 1; break; /* for nop and break */
+ case IA64_TYPE_A:
+ result = (unit == IA64_UNIT_I || unit == IA64_UNIT_M);
+ break;
+ case IA64_TYPE_X: result = (unit == IA64_UNIT_L); break;
+ case IA64_TYPE_I: result = (unit == IA64_UNIT_I); break;
+ case IA64_TYPE_M: result = (unit == IA64_UNIT_M); break;
+ case IA64_TYPE_B: result = (unit == IA64_UNIT_B); break;
+ case IA64_TYPE_F: result = (unit == IA64_UNIT_F); break;
+ default: result = 0; break;
+ }
+ return result;
+}
+
+/* Add a bit of extra goodness if a nop of type F or B would fit
+ in TEMPL at SLOT. */
+
+static inline int
+extra_goodness (int templ, int slot)
+{
+ if (slot == 1 && match (templ, IA64_TYPE_F, slot))
+ return 2;
+ if (slot == 2 && match (templ, IA64_TYPE_B, slot))
+ return 1;
+ return 0;
+}
+
+/* This function is called once, at assembler startup time. It sets
+ up all the tables, etc. that the MD part of the assembler will need
+ that can be determined before arguments are parsed. */
+void
+md_begin ()
+{
+ int i, j, k, t, total, ar_base, cr_base, goodness, best, regnum, ok;
+ const char *err;
+ char name[8];
+
+ md.auto_align = 1;
+ md.explicit_mode = md.default_explicit_mode;
+
+ bfd_set_section_alignment (stdoutput, text_section, 4);
+
+ /* Make sure function pointers get initialized. */
+ target_big_endian = -1;
+ dot_byteorder (TARGET_BYTES_BIG_ENDIAN);
+
+ alias_hash = hash_new ();
+ alias_name_hash = hash_new ();
+ secalias_hash = hash_new ();
+ secalias_name_hash = hash_new ();
+
+ pseudo_func[FUNC_DTP_MODULE].u.sym =
+ symbol_new (".<dtpmod>", undefined_section, FUNC_DTP_MODULE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_DTP_RELATIVE].u.sym =
+ symbol_new (".<dtprel>", undefined_section, FUNC_DTP_RELATIVE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_FPTR_RELATIVE].u.sym =
+ symbol_new (".<fptr>", undefined_section, FUNC_FPTR_RELATIVE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_GP_RELATIVE].u.sym =
+ symbol_new (".<gprel>", undefined_section, FUNC_GP_RELATIVE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_LT_RELATIVE].u.sym =
+ symbol_new (".<ltoff>", undefined_section, FUNC_LT_RELATIVE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_LT_RELATIVE_X].u.sym =
+ symbol_new (".<ltoffx>", undefined_section, FUNC_LT_RELATIVE_X,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_PC_RELATIVE].u.sym =
+ symbol_new (".<pcrel>", undefined_section, FUNC_PC_RELATIVE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_PLT_RELATIVE].u.sym =
+ symbol_new (".<pltoff>", undefined_section, FUNC_PLT_RELATIVE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_SEC_RELATIVE].u.sym =
+ symbol_new (".<secrel>", undefined_section, FUNC_SEC_RELATIVE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_SEG_RELATIVE].u.sym =
+ symbol_new (".<segrel>", undefined_section, FUNC_SEG_RELATIVE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_TP_RELATIVE].u.sym =
+ symbol_new (".<tprel>", undefined_section, FUNC_TP_RELATIVE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_LTV_RELATIVE].u.sym =
+ symbol_new (".<ltv>", undefined_section, FUNC_LTV_RELATIVE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_LT_FPTR_RELATIVE].u.sym =
+ symbol_new (".<ltoff.fptr>", undefined_section, FUNC_LT_FPTR_RELATIVE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_LT_DTP_MODULE].u.sym =
+ symbol_new (".<ltoff.dtpmod>", undefined_section, FUNC_LT_DTP_MODULE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_LT_DTP_RELATIVE].u.sym =
+ symbol_new (".<ltoff.dptrel>", undefined_section, FUNC_LT_DTP_RELATIVE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_LT_TP_RELATIVE].u.sym =
+ symbol_new (".<ltoff.tprel>", undefined_section, FUNC_LT_TP_RELATIVE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_IPLT_RELOC].u.sym =
+ symbol_new (".<iplt>", undefined_section, FUNC_IPLT_RELOC,
+ &zero_address_frag);
+
+ /* Compute the table of best templates. We compute goodness as a
+ base 4 value, in which each match counts for 3, each F counts
+ for 2, each B counts for 1. This should maximize the number of
+ F and B nops in the chosen bundles, which is good because these
+ pipelines are least likely to be overcommitted. */
+ for (i = 0; i < IA64_NUM_TYPES; ++i)
+ for (j = 0; j < IA64_NUM_TYPES; ++j)
+ for (k = 0; k < IA64_NUM_TYPES; ++k)
+ {
+ best = 0;
+ for (t = 0; t < NELEMS (ia64_templ_desc); ++t)
+ {
+ goodness = 0;
+ if (match (t, i, 0))
+ {
+ if (match (t, j, 1))
+ {
+ if (match (t, k, 2))
+ goodness = 3 + 3 + 3;
+ else
+ goodness = 3 + 3 + extra_goodness (t, 2);
+ }
+ else if (match (t, j, 2))
+ goodness = 3 + 3 + extra_goodness (t, 1);
+ else
+ {
+ goodness = 3;
+ goodness += extra_goodness (t, 1);
+ goodness += extra_goodness (t, 2);
+ }
+ }
+ else if (match (t, i, 1))
+ {
+ if (match (t, j, 2))
+ goodness = 3 + 3;
+ else
+ goodness = 3 + extra_goodness (t, 2);
+ }
+ else if (match (t, i, 2))
+ goodness = 3 + extra_goodness (t, 1);
+
+ if (goodness > best)
+ {
+ best = goodness;
+ best_template[i][j][k] = t;
+ }
+ }
+ }
+
+ for (i = 0; i < NUM_SLOTS; ++i)
+ md.slot[i].user_template = -1;
+
+ md.pseudo_hash = hash_new ();
+ for (i = 0; i < NELEMS (pseudo_opcode); ++i)
+ {
+ err = hash_insert (md.pseudo_hash, pseudo_opcode[i].name,
+ (void *) (pseudo_opcode + i));
+ if (err)
+ as_fatal ("ia64.md_begin: can't hash `%s': %s",
+ pseudo_opcode[i].name, err);
+ }
+
+ md.reg_hash = hash_new ();
+ md.dynreg_hash = hash_new ();
+ md.const_hash = hash_new ();
+ md.entry_hash = hash_new ();
+
+ /* general registers: */
+
+ total = 128;
+ for (i = 0; i < total; ++i)
+ {
+ sprintf (name, "r%d", i - REG_GR);
+ md.regsym[i] = declare_register (name, i);
+ }
+
+ /* floating point registers: */
+ total += 128;
+ for (; i < total; ++i)
+ {
+ sprintf (name, "f%d", i - REG_FR);
+ md.regsym[i] = declare_register (name, i);
+ }
+
+ /* application registers: */
+ total += 128;
+ ar_base = i;
+ for (; i < total; ++i)
+ {
+ sprintf (name, "ar%d", i - REG_AR);
+ md.regsym[i] = declare_register (name, i);
+ }
+
+ /* control registers: */
+ total += 128;
+ cr_base = i;
+ for (; i < total; ++i)
+ {
+ sprintf (name, "cr%d", i - REG_CR);
+ md.regsym[i] = declare_register (name, i);
+ }
+
+ /* predicate registers: */
+ total += 64;
+ for (; i < total; ++i)
+ {
+ sprintf (name, "p%d", i - REG_P);
+ md.regsym[i] = declare_register (name, i);
+ }
+
+ /* branch registers: */
+ total += 8;
+ for (; i < total; ++i)
+ {
+ sprintf (name, "b%d", i - REG_BR);
+ md.regsym[i] = declare_register (name, i);
+ }
+
+ md.regsym[REG_IP] = declare_register ("ip", REG_IP);
+ md.regsym[REG_CFM] = declare_register ("cfm", REG_CFM);
+ md.regsym[REG_PR] = declare_register ("pr", REG_PR);
+ md.regsym[REG_PR_ROT] = declare_register ("pr.rot", REG_PR_ROT);
+ md.regsym[REG_PSR] = declare_register ("psr", REG_PSR);
+ md.regsym[REG_PSR_L] = declare_register ("psr.l", REG_PSR_L);
+ md.regsym[REG_PSR_UM] = declare_register ("psr.um", REG_PSR_UM);
+
+ for (i = 0; i < NELEMS (indirect_reg); ++i)
+ {
+ regnum = indirect_reg[i].regnum;
+ md.regsym[regnum] = declare_register (indirect_reg[i].name, regnum);
+ }
+
+ /* define synonyms for application registers: */
+ for (i = REG_AR; i < REG_AR + NELEMS (ar); ++i)
+ md.regsym[i] = declare_register (ar[i - REG_AR].name,
+ REG_AR + ar[i - REG_AR].regnum);
+
+ /* define synonyms for control registers: */
+ for (i = REG_CR; i < REG_CR + NELEMS (cr); ++i)
+ md.regsym[i] = declare_register (cr[i - REG_CR].name,
+ REG_CR + cr[i - REG_CR].regnum);
+
+ declare_register ("gp", REG_GR + 1);
+ declare_register ("sp", REG_GR + 12);
+ declare_register ("rp", REG_BR + 0);
+
+ /* pseudo-registers used to specify unwind info: */
+ declare_register ("psp", REG_PSP);
+
+ declare_register_set ("ret", 4, REG_GR + 8);
+ declare_register_set ("farg", 8, REG_FR + 8);
+ declare_register_set ("fret", 8, REG_FR + 8);
+
+ for (i = 0; i < NELEMS (const_bits); ++i)
+ {
+ err = hash_insert (md.const_hash, const_bits[i].name,
+ (PTR) (const_bits + i));
+ if (err)
+ as_fatal ("Inserting \"%s\" into constant hash table failed: %s",
+ name, err);
+ }
+
+ /* Set the architecture and machine depending on defaults and command line
+ options. */
+ if (md.flags & EF_IA_64_ABI64)
+ ok = bfd_set_arch_mach (stdoutput, bfd_arch_ia64, bfd_mach_ia64_elf64);
+ else
+ ok = bfd_set_arch_mach (stdoutput, bfd_arch_ia64, bfd_mach_ia64_elf32);
+
+ if (! ok)
+ as_warn (_("Could not set architecture and machine"));
+
+ /* Set the pointer size and pointer shift size depending on md.flags */
+
+ if (md.flags & EF_IA_64_ABI64)
+ {
+ md.pointer_size = 8; /* pointers are 8 bytes */
+ md.pointer_size_shift = 3; /* alignment is 8 bytes = 2^2 */
+ }
+ else
+ {
+ md.pointer_size = 4; /* pointers are 4 bytes */
+ md.pointer_size_shift = 2; /* alignment is 4 bytes = 2^2 */
+ }
+
+ md.mem_offset.hint = 0;
+ md.path = 0;
+ md.maxpaths = 0;
+ md.entry_labels = NULL;
+}
+
+/* Set the elf type to 64 bit ABI by default. Cannot do this in md_begin
+ because that is called after md_parse_option which is where we do the
+ dynamic changing of md.flags based on -mlp64 or -milp32. Also, set the
+ default endianness. */
+
+void
+ia64_init (argc, argv)
+ int argc ATTRIBUTE_UNUSED;
+ char **argv ATTRIBUTE_UNUSED;
+{
+ md.flags = MD_FLAGS_DEFAULT;
+}
+
+/* Return a string for the target object file format. */
+
+const char *
+ia64_target_format ()
+{
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ {
+ if (md.flags & EF_IA_64_BE)
+ {
+ if (md.flags & EF_IA_64_ABI64)
+#if defined(TE_AIX50)
+ return "elf64-ia64-aix-big";
+#elif defined(TE_HPUX)
+ return "elf64-ia64-hpux-big";
+#else
+ return "elf64-ia64-big";
+#endif
+ else
+#if defined(TE_AIX50)
+ return "elf32-ia64-aix-big";
+#elif defined(TE_HPUX)
+ return "elf32-ia64-hpux-big";
+#else
+ return "elf32-ia64-big";
+#endif
+ }
+ else
+ {
+ if (md.flags & EF_IA_64_ABI64)
+#ifdef TE_AIX50
+ return "elf64-ia64-aix-little";
+#else
+ return "elf64-ia64-little";
+#endif
+ else
+#ifdef TE_AIX50
+ return "elf32-ia64-aix-little";
+#else
+ return "elf32-ia64-little";
+#endif
+ }
+ }
+ else
+ return "unknown-format";
+}
+
+void
+ia64_end_of_source ()
+{
+ /* terminate insn group upon reaching end of file: */
+ insn_group_break (1, 0, 0);
+
+ /* emits slots we haven't written yet: */
+ ia64_flush_insns ();
+
+ bfd_set_private_flags (stdoutput, md.flags);
+
+ md.mem_offset.hint = 0;
+}
+
+void
+ia64_start_line ()
+{
+ if (md.qp.X_op == O_register)
+ as_bad ("qualifying predicate not followed by instruction");
+ md.qp.X_op = O_absent;
+
+ if (ignore_input ())
+ return;
+
+ if (input_line_pointer[0] == ';' && input_line_pointer[-1] == ';')
+ {
+ if (md.detect_dv && !md.explicit_mode)
+ as_warn (_("Explicit stops are ignored in auto mode"));
+ else
+ insn_group_break (1, 0, 0);
+ }
+}
+
+/* This is a hook for ia64_frob_label, so that it can distinguish tags from
+ labels. */
+static int defining_tag = 0;
+
+int
+ia64_unrecognized_line (ch)
+ int ch;
+{
+ switch (ch)
+ {
+ case '(':
+ expression (&md.qp);
+ if (*input_line_pointer++ != ')')
+ {
+ as_bad ("Expected ')'");
+ return 0;
+ }
+ if (md.qp.X_op != O_register)
+ {
+ as_bad ("Qualifying predicate expected");
+ return 0;
+ }
+ if (md.qp.X_add_number < REG_P || md.qp.X_add_number >= REG_P + 64)
+ {
+ as_bad ("Predicate register expected");
+ return 0;
+ }
+ return 1;
+
+ case '{':
+ if (md.manual_bundling)
+ as_warn ("Found '{' when manual bundling is already turned on");
+ else
+ CURR_SLOT.manual_bundling_on = 1;
+ md.manual_bundling = 1;
+
+ /* Bundling is only acceptable in explicit mode
+ or when in default automatic mode. */
+ if (md.detect_dv && !md.explicit_mode)
+ {
+ if (!md.mode_explicitly_set
+ && !md.default_explicit_mode)
+ dot_dv_mode ('E');
+ else
+ as_warn (_("Found '{' after explicit switch to automatic mode"));
+ }
+ return 1;
+
+ case '}':
+ if (!md.manual_bundling)
+ as_warn ("Found '}' when manual bundling is off");
+ else
+ PREV_SLOT.manual_bundling_off = 1;
+ md.manual_bundling = 0;
+
+ /* switch back to automatic mode, if applicable */
+ if (md.detect_dv
+ && md.explicit_mode
+ && !md.mode_explicitly_set
+ && !md.default_explicit_mode)
+ dot_dv_mode ('A');
+
+ /* Allow '{' to follow on the same line. We also allow ";;", but that
+ happens automatically because ';' is an end of line marker. */
+ SKIP_WHITESPACE ();
+ if (input_line_pointer[0] == '{')
+ {
+ input_line_pointer++;
+ return ia64_unrecognized_line ('{');
+ }
+
+ demand_empty_rest_of_line ();
+ return 1;
+
+ case '[':
+ {
+ char *s;
+ char c;
+ symbolS *tag;
+ int temp;
+
+ if (md.qp.X_op == O_register)
+ {
+ as_bad ("Tag must come before qualifying predicate.");
+ return 0;
+ }
+
+ /* This implements just enough of read_a_source_file in read.c to
+ recognize labels. */
+ if (is_name_beginner (*input_line_pointer))
+ {
+ s = input_line_pointer;
+ c = get_symbol_end ();
+ }
+ else if (LOCAL_LABELS_FB
+ && ISDIGIT (*input_line_pointer))
+ {
+ temp = 0;
+ while (ISDIGIT (*input_line_pointer))
+ temp = (temp * 10) + *input_line_pointer++ - '0';
+ fb_label_instance_inc (temp);
+ s = fb_label_name (temp, 0);
+ c = *input_line_pointer;
+ }
+ else
+ {
+ s = NULL;
+ c = '\0';
+ }
+ if (c != ':')
+ {
+ /* Put ':' back for error messages' sake. */
+ *input_line_pointer++ = ':';
+ as_bad ("Expected ':'");
+ return 0;
+ }
+
+ defining_tag = 1;
+ tag = colon (s);
+ defining_tag = 0;
+ /* Put ':' back for error messages' sake. */
+ *input_line_pointer++ = ':';
+ if (*input_line_pointer++ != ']')
+ {
+ as_bad ("Expected ']'");
+ return 0;
+ }
+ if (! tag)
+ {
+ as_bad ("Tag name expected");
+ return 0;
+ }
+ return 1;
+ }
+
+ default:
+ break;
+ }
+
+ /* Not a valid line. */
+ return 0;
+}
+
+void
+ia64_frob_label (sym)
+ struct symbol *sym;
+{
+ struct label_fix *fix;
+
+ /* Tags need special handling since they are not bundle breaks like
+ labels. */
+ if (defining_tag)
+ {
+ fix = obstack_alloc (&notes, sizeof (*fix));
+ fix->sym = sym;
+ fix->next = CURR_SLOT.tag_fixups;
+ CURR_SLOT.tag_fixups = fix;
+
+ return;
+ }
+
+ if (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)
+ {
+ md.last_text_seg = now_seg;
+ fix = obstack_alloc (&notes, sizeof (*fix));
+ fix->sym = sym;
+ fix->next = CURR_SLOT.label_fixups;
+ CURR_SLOT.label_fixups = fix;
+
+ /* Keep track of how many code entry points we've seen. */
+ if (md.path == md.maxpaths)
+ {
+ md.maxpaths += 20;
+ md.entry_labels = (const char **)
+ xrealloc ((void *) md.entry_labels,
+ md.maxpaths * sizeof (char *));
+ }
+ md.entry_labels[md.path++] = S_GET_NAME (sym);
+ }
+}
+
+#ifdef TE_HPUX
+/* The HP-UX linker will give unresolved symbol errors for symbols
+ that are declared but unused. This routine removes declared,
+ unused symbols from an object. */
+int
+ia64_frob_symbol (sym)
+ struct symbol *sym;
+{
+ if ((S_GET_SEGMENT (sym) == &bfd_und_section && ! symbol_used_p (sym) &&
+ ELF_ST_VISIBILITY (S_GET_OTHER (sym)) == STV_DEFAULT)
+ || (S_GET_SEGMENT (sym) == &bfd_abs_section
+ && ! S_IS_EXTERNAL (sym)))
+ return 1;
+ return 0;
+}
+#endif
+
+void
+ia64_flush_pending_output ()
+{
+ if (!md.keep_pending_output
+ && bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)
+ {
+ /* ??? This causes many unnecessary stop bits to be emitted.
+ Unfortunately, it isn't clear if it is safe to remove this. */
+ insn_group_break (1, 0, 0);
+ ia64_flush_insns ();
+ }
+}
+
+/* Do ia64-specific expression optimization. All that's done here is
+ to transform index expressions that are either due to the indexing
+ of rotating registers or due to the indexing of indirect register
+ sets. */
+int
+ia64_optimize_expr (l, op, r)
+ expressionS *l;
+ operatorT op;
+ expressionS *r;
+{
+ unsigned num_regs;
+
+ if (op == O_index)
+ {
+ if (l->X_op == O_register && r->X_op == O_constant)
+ {
+ num_regs = (l->X_add_number >> 16);
+ if ((unsigned) r->X_add_number >= num_regs)
+ {
+ if (!num_regs)
+ as_bad ("No current frame");
+ else
+ as_bad ("Index out of range 0..%u", num_regs - 1);
+ r->X_add_number = 0;
+ }
+ l->X_add_number = (l->X_add_number & 0xffff) + r->X_add_number;
+ return 1;
+ }
+ else if (l->X_op == O_register && r->X_op == O_register)
+ {
+ if (l->X_add_number < IND_CPUID || l->X_add_number > IND_RR
+ || l->X_add_number == IND_MEM)
+ {
+ as_bad ("Indirect register set name expected");
+ l->X_add_number = IND_CPUID;
+ }
+ l->X_op = O_index;
+ l->X_op_symbol = md.regsym[l->X_add_number];
+ l->X_add_number = r->X_add_number;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int
+ia64_parse_name (name, e)
+ char *name;
+ expressionS *e;
+{
+ struct const_desc *cdesc;
+ struct dynreg *dr = 0;
+ unsigned int regnum;
+ struct symbol *sym;
+ char *end;
+
+ /* first see if NAME is a known register name: */
+ sym = hash_find (md.reg_hash, name);
+ if (sym)
+ {
+ e->X_op = O_register;
+ e->X_add_number = S_GET_VALUE (sym);
+ return 1;
+ }
+
+ cdesc = hash_find (md.const_hash, name);
+ if (cdesc)
+ {
+ e->X_op = O_constant;
+ e->X_add_number = cdesc->value;
+ return 1;
+ }
+
+ /* check for inN, locN, or outN: */
+ switch (name[0])
+ {
+ case 'i':
+ if (name[1] == 'n' && ISDIGIT (name[2]))
+ {
+ dr = &md.in;
+ name += 2;
+ }
+ break;
+
+ case 'l':
+ if (name[1] == 'o' && name[2] == 'c' && ISDIGIT (name[3]))
+ {
+ dr = &md.loc;
+ name += 3;
+ }
+ break;
+
+ case 'o':
+ if (name[1] == 'u' && name[2] == 't' && ISDIGIT (name[3]))
+ {
+ dr = &md.out;
+ name += 3;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (dr)
+ {
+ /* The name is inN, locN, or outN; parse the register number. */
+ regnum = strtoul (name, &end, 10);
+ if (end > name && *end == '\0')
+ {
+ if ((unsigned) regnum >= dr->num_regs)
+ {
+ if (!dr->num_regs)
+ as_bad ("No current frame");
+ else
+ as_bad ("Register number out of range 0..%u",
+ dr->num_regs - 1);
+ regnum = 0;
+ }
+ e->X_op = O_register;
+ e->X_add_number = dr->base + regnum;
+ return 1;
+ }
+ }
+
+ if ((dr = hash_find (md.dynreg_hash, name)))
+ {
+ /* We've got ourselves the name of a rotating register set.
+ Store the base register number in the low 16 bits of
+ X_add_number and the size of the register set in the top 16
+ bits. */
+ e->X_op = O_register;
+ e->X_add_number = dr->base | (dr->num_regs << 16);
+ return 1;
+ }
+ return 0;
+}
+
+/* Remove the '#' suffix that indicates a symbol as opposed to a register. */
+
+char *
+ia64_canonicalize_symbol_name (name)
+ char *name;
+{
+ size_t len = strlen (name);
+ if (len > 1 && name[len - 1] == '#')
+ name[len - 1] = '\0';
+ return name;
+}
+
+/* Return true if idesc is a conditional branch instruction. This excludes
+ the modulo scheduled branches, and br.ia. Mod-sched branches are excluded
+ because they always read/write resources regardless of the value of the
+ qualifying predicate. br.ia must always use p0, and hence is always
+ taken. Thus this function returns true for branches which can fall
+ through, and which use no resources if they do fall through. */
+
+static int
+is_conditional_branch (idesc)
+ struct ia64_opcode *idesc;
+{
+ /* br is a conditional branch. Everything that starts with br. except
+ br.ia, br.c{loop,top,exit}, and br.w{top,exit} is a conditional branch.
+ Everything that starts with brl is a conditional branch. */
+ return (idesc->name[0] == 'b' && idesc->name[1] == 'r'
+ && (idesc->name[2] == '\0'
+ || (idesc->name[2] == '.' && idesc->name[3] != 'i'
+ && idesc->name[3] != 'c' && idesc->name[3] != 'w')
+ || idesc->name[2] == 'l'
+ /* br.cond, br.call, br.clr */
+ || (idesc->name[2] == '.' && idesc->name[3] == 'c'
+ && (idesc->name[4] == 'a' || idesc->name[4] == 'o'
+ || (idesc->name[4] == 'l' && idesc->name[5] == 'r')))));
+}
+
+/* Return whether the given opcode is a taken branch. If there's any doubt,
+ returns zero. */
+
+static int
+is_taken_branch (idesc)
+ struct ia64_opcode *idesc;
+{
+ return ((is_conditional_branch (idesc) && CURR_SLOT.qp_regno == 0)
+ || strncmp (idesc->name, "br.ia", 5) == 0);
+}
+
+/* Return whether the given opcode is an interruption or rfi. If there's any
+ doubt, returns zero. */
+
+static int
+is_interruption_or_rfi (idesc)
+ struct ia64_opcode *idesc;
+{
+ if (strcmp (idesc->name, "rfi") == 0)
+ return 1;
+ return 0;
+}
+
+/* Returns the index of the given dependency in the opcode's list of chks, or
+ -1 if there is no dependency. */
+
+static int
+depends_on (depind, idesc)
+ int depind;
+ struct ia64_opcode *idesc;
+{
+ int i;
+ const struct ia64_opcode_dependency *dep = idesc->dependencies;
+ for (i = 0; i < dep->nchks; i++)
+ {
+ if (depind == DEP (dep->chks[i]))
+ return i;
+ }
+ return -1;
+}
+
+/* Determine a set of specific resources used for a particular resource
+ class. Returns the number of specific resources identified For those
+ cases which are not determinable statically, the resource returned is
+ marked nonspecific.
+
+ Meanings of value in 'NOTE':
+ 1) only read/write when the register number is explicitly encoded in the
+ insn.
+ 2) only read CFM when accessing a rotating GR, FR, or PR. mov pr only
+ accesses CFM when qualifying predicate is in the rotating region.
+ 3) general register value is used to specify an indirect register; not
+ determinable statically.
+ 4) only read the given resource when bits 7:0 of the indirect index
+ register value does not match the register number of the resource; not
+ determinable statically.
+ 5) all rules are implementation specific.
+ 6) only when both the index specified by the reader and the index specified
+ by the writer have the same value in bits 63:61; not determinable
+ statically.
+ 7) only access the specified resource when the corresponding mask bit is
+ set
+ 8) PSR.dfh is only read when these insns reference FR32-127. PSR.dfl is
+ only read when these insns reference FR2-31
+ 9) PSR.mfl is only written when these insns write FR2-31. PSR.mfh is only
+ written when these insns write FR32-127
+ 10) The PSR.bn bit is only accessed when one of GR16-31 is specified in the
+ instruction
+ 11) The target predicates are written independently of PR[qp], but source
+ registers are only read if PR[qp] is true. Since the state of PR[qp]
+ cannot statically be determined, all source registers are marked used.
+ 12) This insn only reads the specified predicate register when that
+ register is the PR[qp].
+ 13) This reference to ld-c only applies to teh GR whose value is loaded
+ with data returned from memory, not the post-incremented address register.
+ 14) The RSE resource includes the implementation-specific RSE internal
+ state resources. At least one (and possibly more) of these resources are
+ read by each instruction listed in IC:rse-readers. At least one (and
+ possibly more) of these resources are written by each insn listed in
+ IC:rse-writers.
+ 15+16) Represents reserved instructions, which the assembler does not
+ generate.
+
+ Memory resources (i.e. locations in memory) are *not* marked or tracked by
+ this code; there are no dependency violations based on memory access.
+*/
+
+#define MAX_SPECS 256
+#define DV_CHK 1
+#define DV_REG 0
+
+static int
+specify_resource (dep, idesc, type, specs, note, path)
+ const struct ia64_dependency *dep;
+ struct ia64_opcode *idesc;
+ int type; /* is this a DV chk or a DV reg? */
+ struct rsrc specs[MAX_SPECS]; /* returned specific resources */
+ int note; /* resource note for this insn's usage */
+ int path; /* which execution path to examine */
+{
+ int count = 0;
+ int i;
+ int rsrc_write = 0;
+ struct rsrc tmpl;
+
+ if (dep->mode == IA64_DV_WAW
+ || (dep->mode == IA64_DV_RAW && type == DV_REG)
+ || (dep->mode == IA64_DV_WAR && type == DV_CHK))
+ rsrc_write = 1;
+
+ /* template for any resources we identify */
+ tmpl.dependency = dep;
+ tmpl.note = note;
+ tmpl.insn_srlz = tmpl.data_srlz = 0;
+ tmpl.qp_regno = CURR_SLOT.qp_regno;
+ tmpl.link_to_qp_branch = 1;
+ tmpl.mem_offset.hint = 0;
+ tmpl.specific = 1;
+ tmpl.index = 0;
+ tmpl.cmp_type = CMP_NONE;
+
+#define UNHANDLED \
+as_warn (_("Unhandled dependency %s for %s (%s), note %d"), \
+dep->name, idesc->name, (rsrc_write?"write":"read"), note)
+#define KNOWN(REG) (gr_values[REG].known && gr_values[REG].path >= path)
+
+ /* we don't need to track these */
+ if (dep->semantics == IA64_DVS_NONE)
+ return 0;
+
+ switch (dep->specifier)
+ {
+ case IA64_RS_AR_K:
+ if (note == 1)
+ {
+ if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
+ {
+ int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
+ if (regno >= 0 && regno <= 7)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = regno;
+ }
+ }
+ }
+ else if (note == 0)
+ {
+ for (i = 0; i < 8; i++)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = i;
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_AR_UNAT:
+ /* This is a mov =AR or mov AR= instruction. */
+ if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
+ {
+ int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
+ if (regno == AR_UNAT)
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ else
+ {
+ /* This is a spill/fill, or other instruction that modifies the
+ unat register. */
+
+ /* Unless we can determine the specific bits used, mark the whole
+ thing; bits 8:3 of the memory address indicate the bit used in
+ UNAT. The .mem.offset hint may be used to eliminate a small
+ subset of conflicts. */
+ specs[count] = tmpl;
+ if (md.mem_offset.hint)
+ {
+ if (md.debug_dv)
+ fprintf (stderr, " Using hint for spill/fill\n");
+ /* The index isn't actually used, just set it to something
+ approximating the bit index. */
+ specs[count].index = (md.mem_offset.offset >> 3) & 0x3F;
+ specs[count].mem_offset.hint = 1;
+ specs[count].mem_offset.offset = md.mem_offset.offset;
+ specs[count++].mem_offset.base = md.mem_offset.base;
+ }
+ else
+ {
+ specs[count++].specific = 0;
+ }
+ }
+ break;
+
+ case IA64_RS_AR:
+ if (note == 1)
+ {
+ if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
+ {
+ int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
+ if ((regno >= 8 && regno <= 15)
+ || (regno >= 20 && regno <= 23)
+ || (regno >= 31 && regno <= 39)
+ || (regno >= 41 && regno <= 47)
+ || (regno >= 67 && regno <= 111))
+ {
+ specs[count] = tmpl;
+ specs[count++].index = regno;
+ }
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_ARb:
+ if (note == 1)
+ {
+ if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
+ {
+ int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
+ if ((regno >= 48 && regno <= 63)
+ || (regno >= 112 && regno <= 127))
+ {
+ specs[count] = tmpl;
+ specs[count++].index = regno;
+ }
+ }
+ }
+ else if (note == 0)
+ {
+ for (i = 48; i < 64; i++)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = i;
+ }
+ for (i = 112; i < 128; i++)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = i;
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_BR:
+ if (note != 1)
+ {
+ UNHANDLED;
+ }
+ else
+ {
+ if (rsrc_write)
+ {
+ for (i = 0; i < idesc->num_outputs; i++)
+ if (idesc->operands[i] == IA64_OPND_B1
+ || idesc->operands[i] == IA64_OPND_B2)
+ {
+ specs[count] = tmpl;
+ specs[count++].index =
+ CURR_SLOT.opnd[i].X_add_number - REG_BR;
+ }
+ }
+ else
+ {
+ for (i = idesc->num_outputs; i < NELEMS (idesc->operands); i++)
+ if (idesc->operands[i] == IA64_OPND_B1
+ || idesc->operands[i] == IA64_OPND_B2)
+ {
+ specs[count] = tmpl;
+ specs[count++].index =
+ CURR_SLOT.opnd[i].X_add_number - REG_BR;
+ }
+ }
+ }
+ break;
+
+ case IA64_RS_CPUID: /* four or more registers */
+ if (note == 3)
+ {
+ if (idesc->operands[!rsrc_write] == IA64_OPND_CPUID_R3)
+ {
+ int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
+ if (regno >= 0 && regno < NELEMS (gr_values)
+ && KNOWN (regno))
+ {
+ specs[count] = tmpl;
+ specs[count++].index = gr_values[regno].value & 0xFF;
+ }
+ else
+ {
+ specs[count] = tmpl;
+ specs[count++].specific = 0;
+ }
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_DBR: /* four or more registers */
+ if (note == 3)
+ {
+ if (idesc->operands[!rsrc_write] == IA64_OPND_DBR_R3)
+ {
+ int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
+ if (regno >= 0 && regno < NELEMS (gr_values)
+ && KNOWN (regno))
+ {
+ specs[count] = tmpl;
+ specs[count++].index = gr_values[regno].value & 0xFF;
+ }
+ else
+ {
+ specs[count] = tmpl;
+ specs[count++].specific = 0;
+ }
+ }
+ }
+ else if (note == 0 && !rsrc_write)
+ {
+ specs[count] = tmpl;
+ specs[count++].specific = 0;
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_IBR: /* four or more registers */
+ if (note == 3)
+ {
+ if (idesc->operands[!rsrc_write] == IA64_OPND_IBR_R3)
+ {
+ int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
+ if (regno >= 0 && regno < NELEMS (gr_values)
+ && KNOWN (regno))
+ {
+ specs[count] = tmpl;
+ specs[count++].index = gr_values[regno].value & 0xFF;
+ }
+ else
+ {
+ specs[count] = tmpl;
+ specs[count++].specific = 0;
+ }
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_MSR:
+ if (note == 5)
+ {
+ /* These are implementation specific. Force all references to
+ conflict with all other references. */
+ specs[count] = tmpl;
+ specs[count++].specific = 0;
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_PKR: /* 16 or more registers */
+ if (note == 3 || note == 4)
+ {
+ if (idesc->operands[!rsrc_write] == IA64_OPND_PKR_R3)
+ {
+ int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
+ if (regno >= 0 && regno < NELEMS (gr_values)
+ && KNOWN (regno))
+ {
+ if (note == 3)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = gr_values[regno].value & 0xFF;
+ }
+ else
+ for (i = 0; i < NELEMS (gr_values); i++)
+ {
+ /* Uses all registers *except* the one in R3. */
+ if ((unsigned)i != (gr_values[regno].value & 0xFF))
+ {
+ specs[count] = tmpl;
+ specs[count++].index = i;
+ }
+ }
+ }
+ else
+ {
+ specs[count] = tmpl;
+ specs[count++].specific = 0;
+ }
+ }
+ }
+ else if (note == 0)
+ {
+ /* probe et al. */
+ specs[count] = tmpl;
+ specs[count++].specific = 0;
+ }
+ break;
+
+ case IA64_RS_PMC: /* four or more registers */
+ if (note == 3)
+ {
+ if (idesc->operands[!rsrc_write] == IA64_OPND_PMC_R3
+ || (!rsrc_write && idesc->operands[1] == IA64_OPND_PMD_R3))
+
+ {
+ int index = ((idesc->operands[1] == IA64_OPND_R3 && !rsrc_write)
+ ? 1 : !rsrc_write);
+ int regno = CURR_SLOT.opnd[index].X_add_number - REG_GR;
+ if (regno >= 0 && regno < NELEMS (gr_values)
+ && KNOWN (regno))
+ {
+ specs[count] = tmpl;
+ specs[count++].index = gr_values[regno].value & 0xFF;
+ }
+ else
+ {
+ specs[count] = tmpl;
+ specs[count++].specific = 0;
+ }
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_PMD: /* four or more registers */
+ if (note == 3)
+ {
+ if (idesc->operands[!rsrc_write] == IA64_OPND_PMD_R3)
+ {
+ int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
+ if (regno >= 0 && regno < NELEMS (gr_values)
+ && KNOWN (regno))
+ {
+ specs[count] = tmpl;
+ specs[count++].index = gr_values[regno].value & 0xFF;
+ }
+ else
+ {
+ specs[count] = tmpl;
+ specs[count++].specific = 0;
+ }
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_RR: /* eight registers */
+ if (note == 6)
+ {
+ if (idesc->operands[!rsrc_write] == IA64_OPND_RR_R3)
+ {
+ int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
+ if (regno >= 0 && regno < NELEMS (gr_values)
+ && KNOWN (regno))
+ {
+ specs[count] = tmpl;
+ specs[count++].index = (gr_values[regno].value >> 61) & 0x7;
+ }
+ else
+ {
+ specs[count] = tmpl;
+ specs[count++].specific = 0;
+ }
+ }
+ }
+ else if (note == 0 && !rsrc_write)
+ {
+ specs[count] = tmpl;
+ specs[count++].specific = 0;
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_CR_IRR:
+ if (note == 0)
+ {
+ /* handle mov-from-CR-IVR; it's a read that writes CR[IRR] */
+ int regno = CURR_SLOT.opnd[1].X_add_number - REG_CR;
+ if (rsrc_write
+ && idesc->operands[1] == IA64_OPND_CR3
+ && regno == CR_IVR)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = CR_IRR0 + i;
+ }
+ }
+ }
+ else if (note == 1)
+ {
+ int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
+ if (idesc->operands[!rsrc_write] == IA64_OPND_CR3
+ && regno >= CR_IRR0
+ && regno <= CR_IRR3)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = regno;
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_CR_LRR:
+ if (note != 1)
+ {
+ UNHANDLED;
+ }
+ else
+ {
+ int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
+ if (idesc->operands[!rsrc_write] == IA64_OPND_CR3
+ && (regno == CR_LRR0 || regno == CR_LRR1))
+ {
+ specs[count] = tmpl;
+ specs[count++].index = regno;
+ }
+ }
+ break;
+
+ case IA64_RS_CR:
+ if (note == 1)
+ {
+ if (idesc->operands[!rsrc_write] == IA64_OPND_CR3)
+ {
+ specs[count] = tmpl;
+ specs[count++].index =
+ CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_FR:
+ case IA64_RS_FRb:
+ if (note != 1)
+ {
+ UNHANDLED;
+ }
+ else if (rsrc_write)
+ {
+ if (dep->specifier == IA64_RS_FRb
+ && idesc->operands[0] == IA64_OPND_F1)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = CURR_SLOT.opnd[0].X_add_number - REG_FR;
+ }
+ }
+ else
+ {
+ for (i = idesc->num_outputs; i < NELEMS (idesc->operands); i++)
+ {
+ if (idesc->operands[i] == IA64_OPND_F2
+ || idesc->operands[i] == IA64_OPND_F3
+ || idesc->operands[i] == IA64_OPND_F4)
+ {
+ specs[count] = tmpl;
+ specs[count++].index =
+ CURR_SLOT.opnd[i].X_add_number - REG_FR;
+ }
+ }
+ }
+ break;
+
+ case IA64_RS_GR:
+ if (note == 13)
+ {
+ /* This reference applies only to the GR whose value is loaded with
+ data returned from memory. */
+ specs[count] = tmpl;
+ specs[count++].index = CURR_SLOT.opnd[0].X_add_number - REG_GR;
+ }
+ else if (note == 1)
+ {
+ if (rsrc_write)
+ {
+ for (i = 0; i < idesc->num_outputs; i++)
+ if (idesc->operands[i] == IA64_OPND_R1
+ || idesc->operands[i] == IA64_OPND_R2
+ || idesc->operands[i] == IA64_OPND_R3)
+ {
+ specs[count] = tmpl;
+ specs[count++].index =
+ CURR_SLOT.opnd[i].X_add_number - REG_GR;
+ }
+ if (idesc->flags & IA64_OPCODE_POSTINC)
+ for (i = 0; i < NELEMS (idesc->operands); i++)
+ if (idesc->operands[i] == IA64_OPND_MR3)
+ {
+ specs[count] = tmpl;
+ specs[count++].index =
+ CURR_SLOT.opnd[i].X_add_number - REG_GR;
+ }
+ }
+ else
+ {
+ /* Look for anything that reads a GR. */
+ for (i = 0; i < NELEMS (idesc->operands); i++)
+ {
+ if (idesc->operands[i] == IA64_OPND_MR3
+ || idesc->operands[i] == IA64_OPND_CPUID_R3
+ || idesc->operands[i] == IA64_OPND_DBR_R3
+ || idesc->operands[i] == IA64_OPND_IBR_R3
+ || idesc->operands[i] == IA64_OPND_MSR_R3
+ || idesc->operands[i] == IA64_OPND_PKR_R3
+ || idesc->operands[i] == IA64_OPND_PMC_R3
+ || idesc->operands[i] == IA64_OPND_PMD_R3
+ || idesc->operands[i] == IA64_OPND_RR_R3
+ || ((i >= idesc->num_outputs)
+ && (idesc->operands[i] == IA64_OPND_R1
+ || idesc->operands[i] == IA64_OPND_R2
+ || idesc->operands[i] == IA64_OPND_R3
+ /* addl source register. */
+ || idesc->operands[i] == IA64_OPND_R3_2)))
+ {
+ specs[count] = tmpl;
+ specs[count++].index =
+ CURR_SLOT.opnd[i].X_add_number - REG_GR;
+ }
+ }
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ /* This is the same as IA64_RS_PRr, except that the register range is
+ from 1 - 15, and there are no rotating register reads/writes here. */
+ case IA64_RS_PR:
+ if (note == 0)
+ {
+ for (i = 1; i < 16; i++)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = i;
+ }
+ }
+ else if (note == 7)
+ {
+ valueT mask = 0;
+ /* Mark only those registers indicated by the mask. */
+ if (rsrc_write)
+ {
+ mask = CURR_SLOT.opnd[2].X_add_number;
+ for (i = 1; i < 16; i++)
+ if (mask & ((valueT) 1 << i))
+ {
+ specs[count] = tmpl;
+ specs[count++].index = i;
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ }
+ else if (note == 11) /* note 11 implies note 1 as well */
+ {
+ if (rsrc_write)
+ {
+ for (i = 0; i < idesc->num_outputs; i++)
+ {
+ if (idesc->operands[i] == IA64_OPND_P1
+ || idesc->operands[i] == IA64_OPND_P2)
+ {
+ int regno = CURR_SLOT.opnd[i].X_add_number - REG_P;
+ if (regno >= 1 && regno < 16)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = regno;
+ }
+ }
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ }
+ else if (note == 12)
+ {
+ if (CURR_SLOT.qp_regno >= 1 && CURR_SLOT.qp_regno < 16)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = CURR_SLOT.qp_regno;
+ }
+ }
+ else if (note == 1)
+ {
+ if (rsrc_write)
+ {
+ int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P;
+ int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P;
+ int or_andcm = strstr (idesc->name, "or.andcm") != NULL;
+ int and_orcm = strstr (idesc->name, "and.orcm") != NULL;
+
+ if ((idesc->operands[0] == IA64_OPND_P1
+ || idesc->operands[0] == IA64_OPND_P2)
+ && p1 >= 1 && p1 < 16)
+ {
+ specs[count] = tmpl;
+ specs[count].cmp_type =
+ (or_andcm ? CMP_OR : (and_orcm ? CMP_AND : CMP_NONE));
+ specs[count++].index = p1;
+ }
+ if ((idesc->operands[1] == IA64_OPND_P1
+ || idesc->operands[1] == IA64_OPND_P2)
+ && p2 >= 1 && p2 < 16)
+ {
+ specs[count] = tmpl;
+ specs[count].cmp_type =
+ (or_andcm ? CMP_AND : (and_orcm ? CMP_OR : CMP_NONE));
+ specs[count++].index = p2;
+ }
+ }
+ else
+ {
+ if (CURR_SLOT.qp_regno >= 1 && CURR_SLOT.qp_regno < 16)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = CURR_SLOT.qp_regno;
+ }
+ if (idesc->operands[1] == IA64_OPND_PR)
+ {
+ for (i = 1; i < 16; i++)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = i;
+ }
+ }
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ /* This is the general case for PRs. IA64_RS_PR and IA64_RS_PR63 are
+ simplified cases of this. */
+ case IA64_RS_PRr:
+ if (note == 0)
+ {
+ for (i = 16; i < 63; i++)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = i;
+ }
+ }
+ else if (note == 7)
+ {
+ valueT mask = 0;
+ /* Mark only those registers indicated by the mask. */
+ if (rsrc_write
+ && idesc->operands[0] == IA64_OPND_PR)
+ {
+ mask = CURR_SLOT.opnd[2].X_add_number;
+ if (mask & ((valueT) 1 << 16))
+ for (i = 16; i < 63; i++)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = i;
+ }
+ }
+ else if (rsrc_write
+ && idesc->operands[0] == IA64_OPND_PR_ROT)
+ {
+ for (i = 16; i < 63; i++)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = i;
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ }
+ else if (note == 11) /* note 11 implies note 1 as well */
+ {
+ if (rsrc_write)
+ {
+ for (i = 0; i < idesc->num_outputs; i++)
+ {
+ if (idesc->operands[i] == IA64_OPND_P1
+ || idesc->operands[i] == IA64_OPND_P2)
+ {
+ int regno = CURR_SLOT.opnd[i].X_add_number - REG_P;
+ if (regno >= 16 && regno < 63)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = regno;
+ }
+ }
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ }
+ else if (note == 12)
+ {
+ if (CURR_SLOT.qp_regno >= 16 && CURR_SLOT.qp_regno < 63)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = CURR_SLOT.qp_regno;
+ }
+ }
+ else if (note == 1)
+ {
+ if (rsrc_write)
+ {
+ int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P;
+ int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P;
+ int or_andcm = strstr (idesc->name, "or.andcm") != NULL;
+ int and_orcm = strstr (idesc->name, "and.orcm") != NULL;
+
+ if ((idesc->operands[0] == IA64_OPND_P1
+ || idesc->operands[0] == IA64_OPND_P2)
+ && p1 >= 16 && p1 < 63)
+ {
+ specs[count] = tmpl;
+ specs[count].cmp_type =
+ (or_andcm ? CMP_OR : (and_orcm ? CMP_AND : CMP_NONE));
+ specs[count++].index = p1;
+ }
+ if ((idesc->operands[1] == IA64_OPND_P1
+ || idesc->operands[1] == IA64_OPND_P2)
+ && p2 >= 16 && p2 < 63)
+ {
+ specs[count] = tmpl;
+ specs[count].cmp_type =
+ (or_andcm ? CMP_AND : (and_orcm ? CMP_OR : CMP_NONE));
+ specs[count++].index = p2;
+ }
+ }
+ else
+ {
+ if (CURR_SLOT.qp_regno >= 16 && CURR_SLOT.qp_regno < 63)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = CURR_SLOT.qp_regno;
+ }
+ if (idesc->operands[1] == IA64_OPND_PR)
+ {
+ for (i = 16; i < 63; i++)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = i;
+ }
+ }
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_PSR:
+ /* Verify that the instruction is using the PSR bit indicated in
+ dep->regindex. */
+ if (note == 0)
+ {
+ if (idesc->operands[!rsrc_write] == IA64_OPND_PSR_UM)
+ {
+ if (dep->regindex < 6)
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ else if (idesc->operands[!rsrc_write] == IA64_OPND_PSR)
+ {
+ if (dep->regindex < 32
+ || dep->regindex == 35
+ || dep->regindex == 36
+ || (!rsrc_write && dep->regindex == PSR_CPL))
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ else if (idesc->operands[!rsrc_write] == IA64_OPND_PSR_L)
+ {
+ if (dep->regindex < 32
+ || dep->regindex == 35
+ || dep->regindex == 36
+ || (rsrc_write && dep->regindex == PSR_CPL))
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ else
+ {
+ /* Several PSR bits have very specific dependencies. */
+ switch (dep->regindex)
+ {
+ default:
+ specs[count++] = tmpl;
+ break;
+ case PSR_IC:
+ if (rsrc_write)
+ {
+ specs[count++] = tmpl;
+ }
+ else
+ {
+ /* Only certain CR accesses use PSR.ic */
+ if (idesc->operands[0] == IA64_OPND_CR3
+ || idesc->operands[1] == IA64_OPND_CR3)
+ {
+ int index =
+ ((idesc->operands[0] == IA64_OPND_CR3)
+ ? 0 : 1);
+ int regno =
+ CURR_SLOT.opnd[index].X_add_number - REG_CR;
+
+ switch (regno)
+ {
+ default:
+ break;
+ case CR_ITIR:
+ case CR_IFS:
+ case CR_IIM:
+ case CR_IIP:
+ case CR_IPSR:
+ case CR_ISR:
+ case CR_IFA:
+ case CR_IHA:
+ case CR_IIPA:
+ specs[count++] = tmpl;
+ break;
+ }
+ }
+ }
+ break;
+ case PSR_CPL:
+ if (rsrc_write)
+ {
+ specs[count++] = tmpl;
+ }
+ else
+ {
+ /* Only some AR accesses use cpl */
+ if (idesc->operands[0] == IA64_OPND_AR3
+ || idesc->operands[1] == IA64_OPND_AR3)
+ {
+ int index =
+ ((idesc->operands[0] == IA64_OPND_AR3)
+ ? 0 : 1);
+ int regno =
+ CURR_SLOT.opnd[index].X_add_number - REG_AR;
+
+ if (regno == AR_ITC
+ || (index == 0
+ && (regno == AR_ITC
+ || regno == AR_RSC
+ || (regno >= AR_K0
+ && regno <= AR_K7))))
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ else
+ {
+ specs[count++] = tmpl;
+ }
+ break;
+ }
+ }
+ }
+ }
+ else if (note == 7)
+ {
+ valueT mask = 0;
+ if (idesc->operands[0] == IA64_OPND_IMMU24)
+ {
+ mask = CURR_SLOT.opnd[0].X_add_number;
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ if (mask & ((valueT) 1 << dep->regindex))
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ else if (note == 8)
+ {
+ int min = dep->regindex == PSR_DFL ? 2 : 32;
+ int max = dep->regindex == PSR_DFL ? 31 : 127;
+ /* dfh is read on FR32-127; dfl is read on FR2-31 */
+ for (i = 0; i < NELEMS (idesc->operands); i++)
+ {
+ if (idesc->operands[i] == IA64_OPND_F1
+ || idesc->operands[i] == IA64_OPND_F2
+ || idesc->operands[i] == IA64_OPND_F3
+ || idesc->operands[i] == IA64_OPND_F4)
+ {
+ int reg = CURR_SLOT.opnd[i].X_add_number - REG_FR;
+ if (reg >= min && reg <= max)
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ }
+ }
+ else if (note == 9)
+ {
+ int min = dep->regindex == PSR_MFL ? 2 : 32;
+ int max = dep->regindex == PSR_MFL ? 31 : 127;
+ /* mfh is read on writes to FR32-127; mfl is read on writes to
+ FR2-31 */
+ for (i = 0; i < idesc->num_outputs; i++)
+ {
+ if (idesc->operands[i] == IA64_OPND_F1)
+ {
+ int reg = CURR_SLOT.opnd[i].X_add_number - REG_FR;
+ if (reg >= min && reg <= max)
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ }
+ }
+ else if (note == 10)
+ {
+ for (i = 0; i < NELEMS (idesc->operands); i++)
+ {
+ if (idesc->operands[i] == IA64_OPND_R1
+ || idesc->operands[i] == IA64_OPND_R2
+ || idesc->operands[i] == IA64_OPND_R3)
+ {
+ int regno = CURR_SLOT.opnd[i].X_add_number - REG_GR;
+ if (regno >= 16 && regno <= 31)
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_AR_FPSR:
+ if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
+ {
+ int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
+ if (regno == AR_FPSR)
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ else
+ {
+ specs[count++] = tmpl;
+ }
+ break;
+
+ case IA64_RS_ARX:
+ /* Handle all AR[REG] resources */
+ if (note == 0 || note == 1)
+ {
+ int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
+ if (idesc->operands[!rsrc_write] == IA64_OPND_AR3
+ && regno == dep->regindex)
+ {
+ specs[count++] = tmpl;
+ }
+ /* other AR[REG] resources may be affected by AR accesses */
+ else if (idesc->operands[0] == IA64_OPND_AR3)
+ {
+ /* AR[] writes */
+ regno = CURR_SLOT.opnd[0].X_add_number - REG_AR;
+ switch (dep->regindex)
+ {
+ default:
+ break;
+ case AR_BSP:
+ case AR_RNAT:
+ if (regno == AR_BSPSTORE)
+ {
+ specs[count++] = tmpl;
+ }
+ case AR_RSC:
+ if (!rsrc_write &&
+ (regno == AR_BSPSTORE
+ || regno == AR_RNAT))
+ {
+ specs[count++] = tmpl;
+ }
+ break;
+ }
+ }
+ else if (idesc->operands[1] == IA64_OPND_AR3)
+ {
+ /* AR[] reads */
+ regno = CURR_SLOT.opnd[1].X_add_number - REG_AR;
+ switch (dep->regindex)
+ {
+ default:
+ break;
+ case AR_RSC:
+ if (regno == AR_BSPSTORE || regno == AR_RNAT)
+ {
+ specs[count++] = tmpl;
+ }
+ break;
+ }
+ }
+ else
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_CRX:
+ /* Handle all CR[REG] resources */
+ if (note == 0 || note == 1)
+ {
+ if (idesc->operands[!rsrc_write] == IA64_OPND_CR3)
+ {
+ int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
+ if (regno == dep->regindex)
+ {
+ specs[count++] = tmpl;
+ }
+ else if (!rsrc_write)
+ {
+ /* Reads from CR[IVR] affect other resources. */
+ if (regno == CR_IVR)
+ {
+ if ((dep->regindex >= CR_IRR0
+ && dep->regindex <= CR_IRR3)
+ || dep->regindex == CR_TPR)
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ }
+ }
+ else
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_INSERVICE:
+ /* look for write of EOI (67) or read of IVR (65) */
+ if ((idesc->operands[0] == IA64_OPND_CR3
+ && CURR_SLOT.opnd[0].X_add_number - REG_CR == CR_EOI)
+ || (idesc->operands[1] == IA64_OPND_CR3
+ && CURR_SLOT.opnd[1].X_add_number - REG_CR == CR_IVR))
+ {
+ specs[count++] = tmpl;
+ }
+ break;
+
+ case IA64_RS_GR0:
+ if (note == 1)
+ {
+ specs[count++] = tmpl;
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_CFM:
+ if (note != 2)
+ {
+ specs[count++] = tmpl;
+ }
+ else
+ {
+ /* Check if any of the registers accessed are in the rotating region.
+ mov to/from pr accesses CFM only when qp_regno is in the rotating
+ region */
+ for (i = 0; i < NELEMS (idesc->operands); i++)
+ {
+ if (idesc->operands[i] == IA64_OPND_R1
+ || idesc->operands[i] == IA64_OPND_R2
+ || idesc->operands[i] == IA64_OPND_R3)
+ {
+ int num = CURR_SLOT.opnd[i].X_add_number - REG_GR;
+ /* Assumes that md.rot.num_regs is always valid */
+ if (md.rot.num_regs > 0
+ && num > 31
+ && num < 31 + md.rot.num_regs)
+ {
+ specs[count] = tmpl;
+ specs[count++].specific = 0;
+ }
+ }
+ else if (idesc->operands[i] == IA64_OPND_F1
+ || idesc->operands[i] == IA64_OPND_F2
+ || idesc->operands[i] == IA64_OPND_F3
+ || idesc->operands[i] == IA64_OPND_F4)
+ {
+ int num = CURR_SLOT.opnd[i].X_add_number - REG_FR;
+ if (num > 31)
+ {
+ specs[count] = tmpl;
+ specs[count++].specific = 0;
+ }
+ }
+ else if (idesc->operands[i] == IA64_OPND_P1
+ || idesc->operands[i] == IA64_OPND_P2)
+ {
+ int num = CURR_SLOT.opnd[i].X_add_number - REG_P;
+ if (num > 15)
+ {
+ specs[count] = tmpl;
+ specs[count++].specific = 0;
+ }
+ }
+ }
+ if (CURR_SLOT.qp_regno > 15)
+ {
+ specs[count] = tmpl;
+ specs[count++].specific = 0;
+ }
+ }
+ break;
+
+ /* This is the same as IA64_RS_PRr, except simplified to account for
+ the fact that there is only one register. */
+ case IA64_RS_PR63:
+ if (note == 0)
+ {
+ specs[count++] = tmpl;
+ }
+ else if (note == 7)
+ {
+ valueT mask = 0;
+ if (idesc->operands[2] == IA64_OPND_IMM17)
+ mask = CURR_SLOT.opnd[2].X_add_number;
+ if (mask & ((valueT) 1 << 63))
+ specs[count++] = tmpl;
+ }
+ else if (note == 11)
+ {
+ if ((idesc->operands[0] == IA64_OPND_P1
+ && CURR_SLOT.opnd[0].X_add_number - REG_P == 63)
+ || (idesc->operands[1] == IA64_OPND_P2
+ && CURR_SLOT.opnd[1].X_add_number - REG_P == 63))
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ else if (note == 12)
+ {
+ if (CURR_SLOT.qp_regno == 63)
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ else if (note == 1)
+ {
+ if (rsrc_write)
+ {
+ int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P;
+ int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P;
+ int or_andcm = strstr (idesc->name, "or.andcm") != NULL;
+ int and_orcm = strstr (idesc->name, "and.orcm") != NULL;
+
+ if (p1 == 63
+ && (idesc->operands[0] == IA64_OPND_P1
+ || idesc->operands[0] == IA64_OPND_P2))
+ {
+ specs[count] = tmpl;
+ specs[count++].cmp_type =
+ (or_andcm ? CMP_OR : (and_orcm ? CMP_AND : CMP_NONE));
+ }
+ if (p2 == 63
+ && (idesc->operands[1] == IA64_OPND_P1
+ || idesc->operands[1] == IA64_OPND_P2))
+ {
+ specs[count] = tmpl;
+ specs[count++].cmp_type =
+ (or_andcm ? CMP_AND : (and_orcm ? CMP_OR : CMP_NONE));
+ }
+ }
+ else
+ {
+ if (CURR_SLOT.qp_regno == 63)
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ }
+ else
+ {
+ UNHANDLED;
+ }
+ break;
+
+ case IA64_RS_RSE:
+ /* FIXME we can identify some individual RSE written resources, but RSE
+ read resources have not yet been completely identified, so for now
+ treat RSE as a single resource */
+ if (strncmp (idesc->name, "mov", 3) == 0)
+ {
+ if (rsrc_write)
+ {
+ if (idesc->operands[0] == IA64_OPND_AR3
+ && CURR_SLOT.opnd[0].X_add_number - REG_AR == AR_BSPSTORE)
+ {
+ specs[count] = tmpl;
+ specs[count++].index = 0; /* IA64_RSE_BSPLOAD/RNATBITINDEX */
+ }
+ }
+ else
+ {
+ if (idesc->operands[0] == IA64_OPND_AR3)
+ {
+ if (CURR_SLOT.opnd[0].X_add_number - REG_AR == AR_BSPSTORE
+ || CURR_SLOT.opnd[0].X_add_number - REG_AR == AR_RNAT)
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ else if (idesc->operands[1] == IA64_OPND_AR3)
+ {
+ if (CURR_SLOT.opnd[1].X_add_number - REG_AR == AR_BSP
+ || CURR_SLOT.opnd[1].X_add_number - REG_AR == AR_BSPSTORE
+ || CURR_SLOT.opnd[1].X_add_number - REG_AR == AR_RNAT)
+ {
+ specs[count++] = tmpl;
+ }
+ }
+ }
+ }
+ else
+ {
+ specs[count++] = tmpl;
+ }
+ break;
+
+ case IA64_RS_ANY:
+ /* FIXME -- do any of these need to be non-specific? */
+ specs[count++] = tmpl;
+ break;
+
+ default:
+ as_bad (_("Unrecognized dependency specifier %d\n"), dep->specifier);
+ break;
+ }
+
+ return count;
+}
+
+/* Clear branch flags on marked resources. This breaks the link between the
+ QP of the marking instruction and a subsequent branch on the same QP. */
+
+static void
+clear_qp_branch_flag (mask)
+ valueT mask;
+{
+ int i;
+ for (i = 0; i < regdepslen; i++)
+ {
+ valueT bit = ((valueT) 1 << regdeps[i].qp_regno);
+ if ((bit & mask) != 0)
+ {
+ regdeps[i].link_to_qp_branch = 0;
+ }
+ }
+}
+
+/* MASK contains 2 and only 2 PRs which are mutually exclusive. Remove
+ any mutexes which contain one of the PRs and create new ones when
+ needed. */
+
+static int
+update_qp_mutex (valueT mask)
+{
+ int i;
+ int add = 0;
+
+ i = 0;
+ while (i < qp_mutexeslen)
+ {
+ if ((qp_mutexes[i].prmask & mask) != 0)
+ {
+ /* If it destroys and creates the same mutex, do nothing. */
+ if (qp_mutexes[i].prmask == mask
+ && qp_mutexes[i].path == md.path)
+ {
+ i++;
+ add = -1;
+ }
+ else
+ {
+ int keep = 0;
+
+ if (md.debug_dv)
+ {
+ fprintf (stderr, " Clearing mutex relation");
+ print_prmask (qp_mutexes[i].prmask);
+ fprintf (stderr, "\n");
+ }
+
+ /* Deal with the old mutex with more than 3+ PRs only if
+ the new mutex on the same execution path with it.
+
+ FIXME: The 3+ mutex support is incomplete.
+ dot_pred_rel () may be a better place to fix it. */
+ if (qp_mutexes[i].path == md.path)
+ {
+ /* If it is a proper subset of the mutex, create a
+ new mutex. */
+ if (add == 0
+ && (qp_mutexes[i].prmask & mask) == mask)
+ add = 1;
+
+ qp_mutexes[i].prmask &= ~mask;
+ if (qp_mutexes[i].prmask & (qp_mutexes[i].prmask - 1))
+ {
+ /* Modify the mutex if there are more than one
+ PR left. */
+ keep = 1;
+ i++;
+ }
+ }
+
+ if (keep == 0)
+ /* Remove the mutex. */
+ qp_mutexes[i] = qp_mutexes[--qp_mutexeslen];
+ }
+ }
+ else
+ ++i;
+ }
+
+ if (add == 1)
+ add_qp_mutex (mask);
+
+ return add;
+}
+
+/* Remove any mutexes which contain any of the PRs indicated in the mask.
+
+ Any changes to a PR clears the mutex relations which include that PR. */
+
+static void
+clear_qp_mutex (mask)
+ valueT mask;
+{
+ int i;
+
+ i = 0;
+ while (i < qp_mutexeslen)
+ {
+ if ((qp_mutexes[i].prmask & mask) != 0)
+ {
+ if (md.debug_dv)
+ {
+ fprintf (stderr, " Clearing mutex relation");
+ print_prmask (qp_mutexes[i].prmask);
+ fprintf (stderr, "\n");
+ }
+ qp_mutexes[i] = qp_mutexes[--qp_mutexeslen];
+ }
+ else
+ ++i;
+ }
+}
+
+/* Clear implies relations which contain PRs in the given masks.
+ P1_MASK indicates the source of the implies relation, while P2_MASK
+ indicates the implied PR. */
+
+static void
+clear_qp_implies (p1_mask, p2_mask)
+ valueT p1_mask;
+ valueT p2_mask;
+{
+ int i;
+
+ i = 0;
+ while (i < qp_implieslen)
+ {
+ if ((((valueT) 1 << qp_implies[i].p1) & p1_mask) != 0
+ || (((valueT) 1 << qp_implies[i].p2) & p2_mask) != 0)
+ {
+ if (md.debug_dv)
+ fprintf (stderr, "Clearing implied relation PR%d->PR%d\n",
+ qp_implies[i].p1, qp_implies[i].p2);
+ qp_implies[i] = qp_implies[--qp_implieslen];
+ }
+ else
+ ++i;
+ }
+}
+
+/* Add the PRs specified to the list of implied relations. */
+
+static void
+add_qp_imply (p1, p2)
+ int p1, p2;
+{
+ valueT mask;
+ valueT bit;
+ int i;
+
+ /* p0 is not meaningful here. */
+ if (p1 == 0 || p2 == 0)
+ abort ();
+
+ if (p1 == p2)
+ return;
+
+ /* If it exists already, ignore it. */
+ for (i = 0; i < qp_implieslen; i++)
+ {
+ if (qp_implies[i].p1 == p1
+ && qp_implies[i].p2 == p2
+ && qp_implies[i].path == md.path
+ && !qp_implies[i].p2_branched)
+ return;
+ }
+
+ if (qp_implieslen == qp_impliestotlen)
+ {
+ qp_impliestotlen += 20;
+ qp_implies = (struct qp_imply *)
+ xrealloc ((void *) qp_implies,
+ qp_impliestotlen * sizeof (struct qp_imply));
+ }
+ if (md.debug_dv)
+ fprintf (stderr, " Registering PR%d implies PR%d\n", p1, p2);
+ qp_implies[qp_implieslen].p1 = p1;
+ qp_implies[qp_implieslen].p2 = p2;
+ qp_implies[qp_implieslen].path = md.path;
+ qp_implies[qp_implieslen++].p2_branched = 0;
+
+ /* Add in the implied transitive relations; for everything that p2 implies,
+ make p1 imply that, too; for everything that implies p1, make it imply p2
+ as well. */
+ for (i = 0; i < qp_implieslen; i++)
+ {
+ if (qp_implies[i].p1 == p2)
+ add_qp_imply (p1, qp_implies[i].p2);
+ if (qp_implies[i].p2 == p1)
+ add_qp_imply (qp_implies[i].p1, p2);
+ }
+ /* Add in mutex relations implied by this implies relation; for each mutex
+ relation containing p2, duplicate it and replace p2 with p1. */
+ bit = (valueT) 1 << p1;
+ mask = (valueT) 1 << p2;
+ for (i = 0; i < qp_mutexeslen; i++)
+ {
+ if (qp_mutexes[i].prmask & mask)
+ add_qp_mutex ((qp_mutexes[i].prmask & ~mask) | bit);
+ }
+}
+
+/* Add the PRs specified in the mask to the mutex list; this means that only
+ one of the PRs can be true at any time. PR0 should never be included in
+ the mask. */
+
+static void
+add_qp_mutex (mask)
+ valueT mask;
+{
+ if (mask & 0x1)
+ abort ();
+
+ if (qp_mutexeslen == qp_mutexestotlen)
+ {
+ qp_mutexestotlen += 20;
+ qp_mutexes = (struct qpmutex *)
+ xrealloc ((void *) qp_mutexes,
+ qp_mutexestotlen * sizeof (struct qpmutex));
+ }
+ if (md.debug_dv)
+ {
+ fprintf (stderr, " Registering mutex on");
+ print_prmask (mask);
+ fprintf (stderr, "\n");
+ }
+ qp_mutexes[qp_mutexeslen].path = md.path;
+ qp_mutexes[qp_mutexeslen++].prmask = mask;
+}
+
+static int
+has_suffix_p (name, suffix)
+ const char *name;
+ const char *suffix;
+{
+ size_t namelen = strlen (name);
+ size_t sufflen = strlen (suffix);
+
+ if (namelen <= sufflen)
+ return 0;
+ return strcmp (name + namelen - sufflen, suffix) == 0;
+}
+
+static void
+clear_register_values ()
+{
+ int i;
+ if (md.debug_dv)
+ fprintf (stderr, " Clearing register values\n");
+ for (i = 1; i < NELEMS (gr_values); i++)
+ gr_values[i].known = 0;
+}
+
+/* Keep track of register values/changes which affect DV tracking.
+
+ optimization note: should add a flag to classes of insns where otherwise we
+ have to examine a group of strings to identify them. */
+
+static void
+note_register_values (idesc)
+ struct ia64_opcode *idesc;
+{
+ valueT qp_changemask = 0;
+ int i;
+
+ /* Invalidate values for registers being written to. */
+ for (i = 0; i < idesc->num_outputs; i++)
+ {
+ if (idesc->operands[i] == IA64_OPND_R1
+ || idesc->operands[i] == IA64_OPND_R2
+ || idesc->operands[i] == IA64_OPND_R3)
+ {
+ int regno = CURR_SLOT.opnd[i].X_add_number - REG_GR;
+ if (regno > 0 && regno < NELEMS (gr_values))
+ gr_values[regno].known = 0;
+ }
+ else if (idesc->operands[i] == IA64_OPND_R3_2)
+ {
+ int regno = CURR_SLOT.opnd[i].X_add_number - REG_GR;
+ if (regno > 0 && regno < 4)
+ gr_values[regno].known = 0;
+ }
+ else if (idesc->operands[i] == IA64_OPND_P1
+ || idesc->operands[i] == IA64_OPND_P2)
+ {
+ int regno = CURR_SLOT.opnd[i].X_add_number - REG_P;
+ qp_changemask |= (valueT) 1 << regno;
+ }
+ else if (idesc->operands[i] == IA64_OPND_PR)
+ {
+ if (idesc->operands[2] & (valueT) 0x10000)
+ qp_changemask = ~(valueT) 0x1FFFF | idesc->operands[2];
+ else
+ qp_changemask = idesc->operands[2];
+ break;
+ }
+ else if (idesc->operands[i] == IA64_OPND_PR_ROT)
+ {
+ if (idesc->operands[1] & ((valueT) 1 << 43))
+ qp_changemask = -((valueT) 1 << 44) | idesc->operands[1];
+ else
+ qp_changemask = idesc->operands[1];
+ qp_changemask &= ~(valueT) 0xFFFF;
+ break;
+ }
+ }
+
+ /* Always clear qp branch flags on any PR change. */
+ /* FIXME there may be exceptions for certain compares. */
+ clear_qp_branch_flag (qp_changemask);
+
+ /* Invalidate rotating registers on insns which affect RRBs in CFM. */
+ if (idesc->flags & IA64_OPCODE_MOD_RRBS)
+ {
+ qp_changemask |= ~(valueT) 0xFFFF;
+ if (strcmp (idesc->name, "clrrrb.pr") != 0)
+ {
+ for (i = 32; i < 32 + md.rot.num_regs; i++)
+ gr_values[i].known = 0;
+ }
+ clear_qp_mutex (qp_changemask);
+ clear_qp_implies (qp_changemask, qp_changemask);
+ }
+ /* After a call, all register values are undefined, except those marked
+ as "safe". */
+ else if (strncmp (idesc->name, "br.call", 6) == 0
+ || strncmp (idesc->name, "brl.call", 7) == 0)
+ {
+ /* FIXME keep GR values which are marked as "safe_across_calls" */
+ clear_register_values ();
+ clear_qp_mutex (~qp_safe_across_calls);
+ clear_qp_implies (~qp_safe_across_calls, ~qp_safe_across_calls);
+ clear_qp_branch_flag (~qp_safe_across_calls);
+ }
+ else if (is_interruption_or_rfi (idesc)
+ || is_taken_branch (idesc))
+ {
+ clear_register_values ();
+ clear_qp_mutex (~(valueT) 0);
+ clear_qp_implies (~(valueT) 0, ~(valueT) 0);
+ }
+ /* Look for mutex and implies relations. */
+ else if ((idesc->operands[0] == IA64_OPND_P1
+ || idesc->operands[0] == IA64_OPND_P2)
+ && (idesc->operands[1] == IA64_OPND_P1
+ || idesc->operands[1] == IA64_OPND_P2))
+ {
+ int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P;
+ int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P;
+ valueT p1mask = (p1 != 0) ? (valueT) 1 << p1 : 0;
+ valueT p2mask = (p2 != 0) ? (valueT) 1 << p2 : 0;
+
+ /* If both PRs are PR0, we can't really do anything. */
+ if (p1 == 0 && p2 == 0)
+ {
+ if (md.debug_dv)
+ fprintf (stderr, " Ignoring PRs due to inclusion of p0\n");
+ }
+ /* In general, clear mutexes and implies which include P1 or P2,
+ with the following exceptions. */
+ else if (has_suffix_p (idesc->name, ".or.andcm")
+ || has_suffix_p (idesc->name, ".and.orcm"))
+ {
+ clear_qp_implies (p2mask, p1mask);
+ }
+ else if (has_suffix_p (idesc->name, ".andcm")
+ || has_suffix_p (idesc->name, ".and"))
+ {
+ clear_qp_implies (0, p1mask | p2mask);
+ }
+ else if (has_suffix_p (idesc->name, ".orcm")
+ || has_suffix_p (idesc->name, ".or"))
+ {
+ clear_qp_mutex (p1mask | p2mask);
+ clear_qp_implies (p1mask | p2mask, 0);
+ }
+ else
+ {
+ int added = 0;
+
+ clear_qp_implies (p1mask | p2mask, p1mask | p2mask);
+
+ /* If one of the PRs is PR0, we call clear_qp_mutex. */
+ if (p1 == 0 || p2 == 0)
+ clear_qp_mutex (p1mask | p2mask);
+ else
+ added = update_qp_mutex (p1mask | p2mask);
+
+ if (CURR_SLOT.qp_regno == 0
+ || has_suffix_p (idesc->name, ".unc"))
+ {
+ if (added == 0 && p1 && p2)
+ add_qp_mutex (p1mask | p2mask);
+ if (CURR_SLOT.qp_regno != 0)
+ {
+ if (p1)
+ add_qp_imply (p1, CURR_SLOT.qp_regno);
+ if (p2)
+ add_qp_imply (p2, CURR_SLOT.qp_regno);
+ }
+ }
+ }
+ }
+ /* Look for mov imm insns into GRs. */
+ else if (idesc->operands[0] == IA64_OPND_R1
+ && (idesc->operands[1] == IA64_OPND_IMM22
+ || idesc->operands[1] == IA64_OPND_IMMU64)
+ && (strcmp (idesc->name, "mov") == 0
+ || strcmp (idesc->name, "movl") == 0))
+ {
+ int regno = CURR_SLOT.opnd[0].X_add_number - REG_GR;
+ if (regno > 0 && regno < NELEMS (gr_values))
+ {
+ gr_values[regno].known = 1;
+ gr_values[regno].value = CURR_SLOT.opnd[1].X_add_number;
+ gr_values[regno].path = md.path;
+ if (md.debug_dv)
+ {
+ fprintf (stderr, " Know gr%d = ", regno);
+ fprintf_vma (stderr, gr_values[regno].value);
+ fputs ("\n", stderr);
+ }
+ }
+ }
+ else
+ {
+ clear_qp_mutex (qp_changemask);
+ clear_qp_implies (qp_changemask, qp_changemask);
+ }
+}
+
+/* Return whether the given predicate registers are currently mutex. */
+
+static int
+qp_mutex (p1, p2, path)
+ int p1;
+ int p2;
+ int path;
+{
+ int i;
+ valueT mask;
+
+ if (p1 != p2)
+ {
+ mask = ((valueT) 1 << p1) | (valueT) 1 << p2;
+ for (i = 0; i < qp_mutexeslen; i++)
+ {
+ if (qp_mutexes[i].path >= path
+ && (qp_mutexes[i].prmask & mask) == mask)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Return whether the given resource is in the given insn's list of chks
+ Return 1 if the conflict is absolutely determined, 2 if it's a potential
+ conflict. */
+
+static int
+resources_match (rs, idesc, note, qp_regno, path)
+ struct rsrc *rs;
+ struct ia64_opcode *idesc;
+ int note;
+ int qp_regno;
+ int path;
+{
+ struct rsrc specs[MAX_SPECS];
+ int count;
+
+ /* If the marked resource's qp_regno and the given qp_regno are mutex,
+ we don't need to check. One exception is note 11, which indicates that
+ target predicates are written regardless of PR[qp]. */
+ if (qp_mutex (rs->qp_regno, qp_regno, path)
+ && note != 11)
+ return 0;
+
+ count = specify_resource (rs->dependency, idesc, DV_CHK, specs, note, path);
+ while (count-- > 0)
+ {
+ /* UNAT checking is a bit more specific than other resources */
+ if (rs->dependency->specifier == IA64_RS_AR_UNAT
+ && specs[count].mem_offset.hint
+ && rs->mem_offset.hint)
+ {
+ if (rs->mem_offset.base == specs[count].mem_offset.base)
+ {
+ if (((rs->mem_offset.offset >> 3) & 0x3F) ==
+ ((specs[count].mem_offset.offset >> 3) & 0x3F))
+ return 1;
+ else
+ continue;
+ }
+ }
+
+ /* Skip apparent PR write conflicts where both writes are an AND or both
+ writes are an OR. */
+ if (rs->dependency->specifier == IA64_RS_PR
+ || rs->dependency->specifier == IA64_RS_PRr
+ || rs->dependency->specifier == IA64_RS_PR63)
+ {
+ if (specs[count].cmp_type != CMP_NONE
+ && specs[count].cmp_type == rs->cmp_type)
+ {
+ if (md.debug_dv)
+ fprintf (stderr, " %s on parallel compare allowed (PR%d)\n",
+ dv_mode[rs->dependency->mode],
+ rs->dependency->specifier != IA64_RS_PR63 ?
+ specs[count].index : 63);
+ continue;
+ }
+ if (md.debug_dv)
+ fprintf (stderr,
+ " %s on parallel compare conflict %s vs %s on PR%d\n",
+ dv_mode[rs->dependency->mode],
+ dv_cmp_type[rs->cmp_type],
+ dv_cmp_type[specs[count].cmp_type],
+ rs->dependency->specifier != IA64_RS_PR63 ?
+ specs[count].index : 63);
+
+ }
+
+ /* If either resource is not specific, conservatively assume a conflict
+ */
+ if (!specs[count].specific || !rs->specific)
+ return 2;
+ else if (specs[count].index == rs->index)
+ return 1;
+ }
+#if 0
+ if (md.debug_dv)
+ fprintf (stderr, " No %s conflicts\n", rs->dependency->name);
+#endif
+
+ return 0;
+}
+
+/* Indicate an instruction group break; if INSERT_STOP is non-zero, then
+ insert a stop to create the break. Update all resource dependencies
+ appropriately. If QP_REGNO is non-zero, only apply the break to resources
+ which use the same QP_REGNO and have the link_to_qp_branch flag set.
+ If SAVE_CURRENT is non-zero, don't affect resources marked by the current
+ instruction. */
+
+static void
+insn_group_break (insert_stop, qp_regno, save_current)
+ int insert_stop;
+ int qp_regno;
+ int save_current;
+{
+ int i;
+
+ if (insert_stop && md.num_slots_in_use > 0)
+ PREV_SLOT.end_of_insn_group = 1;
+
+ if (md.debug_dv)
+ {
+ fprintf (stderr, " Insn group break%s",
+ (insert_stop ? " (w/stop)" : ""));
+ if (qp_regno != 0)
+ fprintf (stderr, " effective for QP=%d", qp_regno);
+ fprintf (stderr, "\n");
+ }
+
+ i = 0;
+ while (i < regdepslen)
+ {
+ const struct ia64_dependency *dep = regdeps[i].dependency;
+
+ if (qp_regno != 0
+ && regdeps[i].qp_regno != qp_regno)
+ {
+ ++i;
+ continue;
+ }
+
+ if (save_current
+ && CURR_SLOT.src_file == regdeps[i].file
+ && CURR_SLOT.src_line == regdeps[i].line)
+ {
+ ++i;
+ continue;
+ }
+
+ /* clear dependencies which are automatically cleared by a stop, or
+ those that have reached the appropriate state of insn serialization */
+ if (dep->semantics == IA64_DVS_IMPLIED
+ || dep->semantics == IA64_DVS_IMPLIEDF
+ || regdeps[i].insn_srlz == STATE_SRLZ)
+ {
+ print_dependency ("Removing", i);
+ regdeps[i] = regdeps[--regdepslen];
+ }
+ else
+ {
+ if (dep->semantics == IA64_DVS_DATA
+ || dep->semantics == IA64_DVS_INSTR
+ || dep->semantics == IA64_DVS_SPECIFIC)
+ {
+ if (regdeps[i].insn_srlz == STATE_NONE)
+ regdeps[i].insn_srlz = STATE_STOP;
+ if (regdeps[i].data_srlz == STATE_NONE)
+ regdeps[i].data_srlz = STATE_STOP;
+ }
+ ++i;
+ }
+ }
+}
+
+/* Add the given resource usage spec to the list of active dependencies. */
+
+static void
+mark_resource (idesc, dep, spec, depind, path)
+ struct ia64_opcode *idesc ATTRIBUTE_UNUSED;
+ const struct ia64_dependency *dep ATTRIBUTE_UNUSED;
+ struct rsrc *spec;
+ int depind;
+ int path;
+{
+ if (regdepslen == regdepstotlen)
+ {
+ regdepstotlen += 20;
+ regdeps = (struct rsrc *)
+ xrealloc ((void *) regdeps,
+ regdepstotlen * sizeof (struct rsrc));
+ }
+
+ regdeps[regdepslen] = *spec;
+ regdeps[regdepslen].depind = depind;
+ regdeps[regdepslen].path = path;
+ regdeps[regdepslen].file = CURR_SLOT.src_file;
+ regdeps[regdepslen].line = CURR_SLOT.src_line;
+
+ print_dependency ("Adding", regdepslen);
+
+ ++regdepslen;
+}
+
+static void
+print_dependency (action, depind)
+ const char *action;
+ int depind;
+{
+ if (md.debug_dv)
+ {
+ fprintf (stderr, " %s %s '%s'",
+ action, dv_mode[(regdeps[depind].dependency)->mode],
+ (regdeps[depind].dependency)->name);
+ if (regdeps[depind].specific && regdeps[depind].index != 0)
+ fprintf (stderr, " (%d)", regdeps[depind].index);
+ if (regdeps[depind].mem_offset.hint)
+ {
+ fputs (" ", stderr);
+ fprintf_vma (stderr, regdeps[depind].mem_offset.base);
+ fputs ("+", stderr);
+ fprintf_vma (stderr, regdeps[depind].mem_offset.offset);
+ }
+ fprintf (stderr, "\n");
+ }
+}
+
+static void
+instruction_serialization ()
+{
+ int i;
+ if (md.debug_dv)
+ fprintf (stderr, " Instruction serialization\n");
+ for (i = 0; i < regdepslen; i++)
+ if (regdeps[i].insn_srlz == STATE_STOP)
+ regdeps[i].insn_srlz = STATE_SRLZ;
+}
+
+static void
+data_serialization ()
+{
+ int i = 0;
+ if (md.debug_dv)
+ fprintf (stderr, " Data serialization\n");
+ while (i < regdepslen)
+ {
+ if (regdeps[i].data_srlz == STATE_STOP
+ /* Note: as of 991210, all "other" dependencies are cleared by a
+ data serialization. This might change with new tables */
+ || (regdeps[i].dependency)->semantics == IA64_DVS_OTHER)
+ {
+ print_dependency ("Removing", i);
+ regdeps[i] = regdeps[--regdepslen];
+ }
+ else
+ ++i;
+ }
+}
+
+/* Insert stops and serializations as needed to avoid DVs. */
+
+static void
+remove_marked_resource (rs)
+ struct rsrc *rs;
+{
+ switch (rs->dependency->semantics)
+ {
+ case IA64_DVS_SPECIFIC:
+ if (md.debug_dv)
+ fprintf (stderr, "Implementation-specific, assume worst case...\n");
+ /* ...fall through... */
+ case IA64_DVS_INSTR:
+ if (md.debug_dv)
+ fprintf (stderr, "Inserting instr serialization\n");
+ if (rs->insn_srlz < STATE_STOP)
+ insn_group_break (1, 0, 0);
+ if (rs->insn_srlz < STATE_SRLZ)
+ {
+ int oldqp = CURR_SLOT.qp_regno;
+ struct ia64_opcode *oldidesc = CURR_SLOT.idesc;
+ /* Manually jam a srlz.i insn into the stream */
+ CURR_SLOT.qp_regno = 0;
+ CURR_SLOT.idesc = ia64_find_opcode ("srlz.i");
+ instruction_serialization ();
+ md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS;
+ if (++md.num_slots_in_use >= NUM_SLOTS)
+ emit_one_bundle ();
+ CURR_SLOT.qp_regno = oldqp;
+ CURR_SLOT.idesc = oldidesc;
+ }
+ insn_group_break (1, 0, 0);
+ break;
+ case IA64_DVS_OTHER: /* as of rev2 (991220) of the DV tables, all
+ "other" types of DV are eliminated
+ by a data serialization */
+ case IA64_DVS_DATA:
+ if (md.debug_dv)
+ fprintf (stderr, "Inserting data serialization\n");
+ if (rs->data_srlz < STATE_STOP)
+ insn_group_break (1, 0, 0);
+ {
+ int oldqp = CURR_SLOT.qp_regno;
+ struct ia64_opcode *oldidesc = CURR_SLOT.idesc;
+ /* Manually jam a srlz.d insn into the stream */
+ CURR_SLOT.qp_regno = 0;
+ CURR_SLOT.idesc = ia64_find_opcode ("srlz.d");
+ data_serialization ();
+ md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS;
+ if (++md.num_slots_in_use >= NUM_SLOTS)
+ emit_one_bundle ();
+ CURR_SLOT.qp_regno = oldqp;
+ CURR_SLOT.idesc = oldidesc;
+ }
+ break;
+ case IA64_DVS_IMPLIED:
+ case IA64_DVS_IMPLIEDF:
+ if (md.debug_dv)
+ fprintf (stderr, "Inserting stop\n");
+ insn_group_break (1, 0, 0);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Check the resources used by the given opcode against the current dependency
+ list.
+
+ The check is run once for each execution path encountered. In this case,
+ a unique execution path is the sequence of instructions following a code
+ entry point, e.g. the following has three execution paths, one starting
+ at L0, one at L1, and one at L2.
+
+ L0: nop
+ L1: add
+ L2: add
+ br.ret
+*/
+
+static void
+check_dependencies (idesc)
+ struct ia64_opcode *idesc;
+{
+ const struct ia64_opcode_dependency *opdeps = idesc->dependencies;
+ int path;
+ int i;
+
+ /* Note that the number of marked resources may change within the
+ loop if in auto mode. */
+ i = 0;
+ while (i < regdepslen)
+ {
+ struct rsrc *rs = &regdeps[i];
+ const struct ia64_dependency *dep = rs->dependency;
+ int chkind;
+ int note;
+ int start_over = 0;
+
+ if (dep->semantics == IA64_DVS_NONE
+ || (chkind = depends_on (rs->depind, idesc)) == -1)
+ {
+ ++i;
+ continue;
+ }
+
+ note = NOTE (opdeps->chks[chkind]);
+
+ /* Check this resource against each execution path seen thus far. */
+ for (path = 0; path <= md.path; path++)
+ {
+ int matchtype;
+
+ /* If the dependency wasn't on the path being checked, ignore it. */
+ if (rs->path < path)
+ continue;
+
+ /* If the QP for this insn implies a QP which has branched, don't
+ bother checking. Ed. NOTE: I don't think this check is terribly
+ useful; what's the point of generating code which will only be
+ reached if its QP is zero?
+ This code was specifically inserted to handle the following code,
+ based on notes from Intel's DV checking code, where p1 implies p2.
+
+ mov r4 = 2
+ (p2) br.cond L
+ (p1) mov r4 = 7
+ */
+ if (CURR_SLOT.qp_regno != 0)
+ {
+ int skip = 0;
+ int implies;
+ for (implies = 0; implies < qp_implieslen; implies++)
+ {
+ if (qp_implies[implies].path >= path
+ && qp_implies[implies].p1 == CURR_SLOT.qp_regno
+ && qp_implies[implies].p2_branched)
+ {
+ skip = 1;
+ break;
+ }
+ }
+ if (skip)
+ continue;
+ }
+
+ if ((matchtype = resources_match (rs, idesc, note,
+ CURR_SLOT.qp_regno, path)) != 0)
+ {
+ char msg[1024];
+ char pathmsg[256] = "";
+ char indexmsg[256] = "";
+ int certain = (matchtype == 1 && CURR_SLOT.qp_regno == 0);
+
+ if (path != 0)
+ sprintf (pathmsg, " when entry is at label '%s'",
+ md.entry_labels[path - 1]);
+ if (rs->specific && rs->index != 0)
+ sprintf (indexmsg, ", specific resource number is %d",
+ rs->index);
+ sprintf (msg, "Use of '%s' %s %s dependency '%s' (%s)%s%s",
+ idesc->name,
+ (certain ? "violates" : "may violate"),
+ dv_mode[dep->mode], dep->name,
+ dv_sem[dep->semantics],
+ pathmsg, indexmsg);
+
+ if (md.explicit_mode)
+ {
+ as_warn ("%s", msg);
+ if (path < md.path)
+ as_warn (_("Only the first path encountering the conflict "
+ "is reported"));
+ as_warn_where (rs->file, rs->line,
+ _("This is the location of the "
+ "conflicting usage"));
+ /* Don't bother checking other paths, to avoid duplicating
+ the same warning */
+ break;
+ }
+ else
+ {
+ if (md.debug_dv)
+ fprintf (stderr, "%s @ %s:%d\n", msg, rs->file, rs->line);
+
+ remove_marked_resource (rs);
+
+ /* since the set of dependencies has changed, start over */
+ /* FIXME -- since we're removing dvs as we go, we
+ probably don't really need to start over... */
+ start_over = 1;
+ break;
+ }
+ }
+ }
+ if (start_over)
+ i = 0;
+ else
+ ++i;
+ }
+}
+
+/* Register new dependencies based on the given opcode. */
+
+static void
+mark_resources (idesc)
+ struct ia64_opcode *idesc;
+{
+ int i;
+ const struct ia64_opcode_dependency *opdeps = idesc->dependencies;
+ int add_only_qp_reads = 0;
+
+ /* A conditional branch only uses its resources if it is taken; if it is
+ taken, we stop following that path. The other branch types effectively
+ *always* write their resources. If it's not taken, register only QP
+ reads. */
+ if (is_conditional_branch (idesc) || is_interruption_or_rfi (idesc))
+ {
+ add_only_qp_reads = 1;
+ }
+
+ if (md.debug_dv)
+ fprintf (stderr, "Registering '%s' resource usage\n", idesc->name);
+
+ for (i = 0; i < opdeps->nregs; i++)
+ {
+ const struct ia64_dependency *dep;
+ struct rsrc specs[MAX_SPECS];
+ int note;
+ int path;
+ int count;
+
+ dep = ia64_find_dependency (opdeps->regs[i]);
+ note = NOTE (opdeps->regs[i]);
+
+ if (add_only_qp_reads
+ && !(dep->mode == IA64_DV_WAR
+ && (dep->specifier == IA64_RS_PR
+ || dep->specifier == IA64_RS_PRr
+ || dep->specifier == IA64_RS_PR63)))
+ continue;
+
+ count = specify_resource (dep, idesc, DV_REG, specs, note, md.path);
+
+#if 0
+ if (md.debug_dv && !count)
+ fprintf (stderr, " No %s %s usage found (path %d)\n",
+ dv_mode[dep->mode], dep->name, md.path);
+#endif
+
+ while (count-- > 0)
+ {
+ mark_resource (idesc, dep, &specs[count],
+ DEP (opdeps->regs[i]), md.path);
+ }
+
+ /* The execution path may affect register values, which may in turn
+ affect which indirect-access resources are accessed. */
+ switch (dep->specifier)
+ {
+ default:
+ break;
+ case IA64_RS_CPUID:
+ case IA64_RS_DBR:
+ case IA64_RS_IBR:
+ case IA64_RS_MSR:
+ case IA64_RS_PKR:
+ case IA64_RS_PMC:
+ case IA64_RS_PMD:
+ case IA64_RS_RR:
+ for (path = 0; path < md.path; path++)
+ {
+ count = specify_resource (dep, idesc, DV_REG, specs, note, path);
+ while (count-- > 0)
+ mark_resource (idesc, dep, &specs[count],
+ DEP (opdeps->regs[i]), path);
+ }
+ break;
+ }
+ }
+}
+
+/* Remove dependencies when they no longer apply. */
+
+static void
+update_dependencies (idesc)
+ struct ia64_opcode *idesc;
+{
+ int i;
+
+ if (strcmp (idesc->name, "srlz.i") == 0)
+ {
+ instruction_serialization ();
+ }
+ else if (strcmp (idesc->name, "srlz.d") == 0)
+ {
+ data_serialization ();
+ }
+ else if (is_interruption_or_rfi (idesc)
+ || is_taken_branch (idesc))
+ {
+ /* Although technically the taken branch doesn't clear dependencies
+ which require a srlz.[id], we don't follow the branch; the next
+ instruction is assumed to start with a clean slate. */
+ regdepslen = 0;
+ md.path = 0;
+ }
+ else if (is_conditional_branch (idesc)
+ && CURR_SLOT.qp_regno != 0)
+ {
+ int is_call = strstr (idesc->name, ".call") != NULL;
+
+ for (i = 0; i < qp_implieslen; i++)
+ {
+ /* If the conditional branch's predicate is implied by the predicate
+ in an existing dependency, remove that dependency. */
+ if (qp_implies[i].p2 == CURR_SLOT.qp_regno)
+ {
+ int depind = 0;
+ /* Note that this implied predicate takes a branch so that if
+ a later insn generates a DV but its predicate implies this
+ one, we can avoid the false DV warning. */
+ qp_implies[i].p2_branched = 1;
+ while (depind < regdepslen)
+ {
+ if (regdeps[depind].qp_regno == qp_implies[i].p1)
+ {
+ print_dependency ("Removing", depind);
+ regdeps[depind] = regdeps[--regdepslen];
+ }
+ else
+ ++depind;
+ }
+ }
+ }
+ /* Any marked resources which have this same predicate should be
+ cleared, provided that the QP hasn't been modified between the
+ marking instruction and the branch. */
+ if (is_call)
+ {
+ insn_group_break (0, CURR_SLOT.qp_regno, 1);
+ }
+ else
+ {
+ i = 0;
+ while (i < regdepslen)
+ {
+ if (regdeps[i].qp_regno == CURR_SLOT.qp_regno
+ && regdeps[i].link_to_qp_branch
+ && (regdeps[i].file != CURR_SLOT.src_file
+ || regdeps[i].line != CURR_SLOT.src_line))
+ {
+ /* Treat like a taken branch */
+ print_dependency ("Removing", i);
+ regdeps[i] = regdeps[--regdepslen];
+ }
+ else
+ ++i;
+ }
+ }
+ }
+}
+
+/* Examine the current instruction for dependency violations. */
+
+static int
+check_dv (idesc)
+ struct ia64_opcode *idesc;
+{
+ if (md.debug_dv)
+ {
+ fprintf (stderr, "Checking %s for violations (line %d, %d/%d)\n",
+ idesc->name, CURR_SLOT.src_line,
+ idesc->dependencies->nchks,
+ idesc->dependencies->nregs);
+ }
+
+ /* Look through the list of currently marked resources; if the current
+ instruction has the dependency in its chks list which uses that resource,
+ check against the specific resources used. */
+ check_dependencies (idesc);
+
+ /* Look up the instruction's regdeps (RAW writes, WAW writes, and WAR reads),
+ then add them to the list of marked resources. */
+ mark_resources (idesc);
+
+ /* There are several types of dependency semantics, and each has its own
+ requirements for being cleared
+
+ Instruction serialization (insns separated by interruption, rfi, or
+ writer + srlz.i + reader, all in separate groups) clears DVS_INSTR.
+
+ Data serialization (instruction serialization, or writer + srlz.d +
+ reader, where writer and srlz.d are in separate groups) clears
+ DVS_DATA. (This also clears DVS_OTHER, but that is not guaranteed to
+ always be the case).
+
+ Instruction group break (groups separated by stop, taken branch,
+ interruption or rfi) clears DVS_IMPLIED and DVS_IMPLIEDF.
+ */
+ update_dependencies (idesc);
+
+ /* Sometimes, knowing a register value allows us to avoid giving a false DV
+ warning. Keep track of as many as possible that are useful. */
+ note_register_values (idesc);
+
+ /* We don't need or want this anymore. */
+ md.mem_offset.hint = 0;
+
+ return 0;
+}
+
+/* Translate one line of assembly. Pseudo ops and labels do not show
+ here. */
+void
+md_assemble (str)
+ char *str;
+{
+ char *saved_input_line_pointer, *mnemonic;
+ const struct pseudo_opcode *pdesc;
+ struct ia64_opcode *idesc;
+ unsigned char qp_regno;
+ unsigned int flags;
+ int ch;
+
+ saved_input_line_pointer = input_line_pointer;
+ input_line_pointer = str;
+
+ /* extract the opcode (mnemonic): */
+
+ mnemonic = input_line_pointer;
+ ch = get_symbol_end ();
+ pdesc = (struct pseudo_opcode *) hash_find (md.pseudo_hash, mnemonic);
+ if (pdesc)
+ {
+ *input_line_pointer = ch;
+ (*pdesc->handler) (pdesc->arg);
+ goto done;
+ }
+
+ /* Find the instruction descriptor matching the arguments. */
+
+ idesc = ia64_find_opcode (mnemonic);
+ *input_line_pointer = ch;
+ if (!idesc)
+ {
+ as_bad ("Unknown opcode `%s'", mnemonic);
+ goto done;
+ }
+
+ idesc = parse_operands (idesc);
+ if (!idesc)
+ goto done;
+
+ /* Handle the dynamic ops we can handle now: */
+ if (idesc->type == IA64_TYPE_DYN)
+ {
+ if (strcmp (idesc->name, "add") == 0)
+ {
+ if (CURR_SLOT.opnd[2].X_op == O_register
+ && CURR_SLOT.opnd[2].X_add_number < 4)
+ mnemonic = "addl";
+ else
+ mnemonic = "adds";
+ ia64_free_opcode (idesc);
+ idesc = ia64_find_opcode (mnemonic);
+#if 0
+ know (!idesc->next);
+#endif
+ }
+ else if (strcmp (idesc->name, "mov") == 0)
+ {
+ enum ia64_opnd opnd1, opnd2;
+ int rop;
+
+ opnd1 = idesc->operands[0];
+ opnd2 = idesc->operands[1];
+ if (opnd1 == IA64_OPND_AR3)
+ rop = 0;
+ else if (opnd2 == IA64_OPND_AR3)
+ rop = 1;
+ else
+ abort ();
+ if (CURR_SLOT.opnd[rop].X_op == O_register
+ && ar_is_in_integer_unit (CURR_SLOT.opnd[rop].X_add_number))
+ mnemonic = "mov.i";
+ else
+ mnemonic = "mov.m";
+ ia64_free_opcode (idesc);
+ idesc = ia64_find_opcode (mnemonic);
+ while (idesc != NULL
+ && (idesc->operands[0] != opnd1
+ || idesc->operands[1] != opnd2))
+ idesc = get_next_opcode (idesc);
+ }
+ }
+
+ qp_regno = 0;
+ if (md.qp.X_op == O_register)
+ {
+ qp_regno = md.qp.X_add_number - REG_P;
+ md.qp.X_op = O_absent;
+ }
+
+ flags = idesc->flags;
+
+ if ((flags & IA64_OPCODE_FIRST) != 0)
+ {
+ /* The alignment frag has to end with a stop bit only if the
+ next instruction after the alignment directive has to be
+ the first instruction in an instruction group. */
+ if (align_frag)
+ {
+ while (align_frag->fr_type != rs_align_code)
+ {
+ align_frag = align_frag->fr_next;
+ if (!align_frag)
+ break;
+ }
+ /* align_frag can be NULL if there are directives in
+ between. */
+ if (align_frag && align_frag->fr_next == frag_now)
+ align_frag->tc_frag_data = 1;
+ }
+
+ insn_group_break (1, 0, 0);
+ }
+ align_frag = NULL;
+
+ if ((flags & IA64_OPCODE_NO_PRED) != 0 && qp_regno != 0)
+ {
+ as_bad ("`%s' cannot be predicated", idesc->name);
+ goto done;
+ }
+
+ /* Build the instruction. */
+ CURR_SLOT.qp_regno = qp_regno;
+ CURR_SLOT.idesc = idesc;
+ as_where (&CURR_SLOT.src_file, &CURR_SLOT.src_line);
+ dwarf2_where (&CURR_SLOT.debug_line);
+
+ /* Add unwind entry, if there is one. */
+ if (unwind.current_entry)
+ {
+ CURR_SLOT.unwind_record = unwind.current_entry;
+ unwind.current_entry = NULL;
+ }
+
+ /* Check for dependency violations. */
+ if (md.detect_dv)
+ check_dv (idesc);
+
+ md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS;
+ if (++md.num_slots_in_use >= NUM_SLOTS)
+ emit_one_bundle ();
+
+ if ((flags & IA64_OPCODE_LAST) != 0)
+ insn_group_break (1, 0, 0);
+
+ md.last_text_seg = now_seg;
+
+ done:
+ input_line_pointer = saved_input_line_pointer;
+}
+
+/* Called when symbol NAME cannot be found in the symbol table.
+ Should be used for dynamic valued symbols only. */
+
+symbolS *
+md_undefined_symbol (name)
+ char *name ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
+
+/* Called for any expression that can not be recognized. When the
+ function is called, `input_line_pointer' will point to the start of
+ the expression. */
+
+void
+md_operand (e)
+ expressionS *e;
+{
+ enum pseudo_type pseudo_type;
+ const char *name;
+ size_t len;
+ int ch, i;
+
+ switch (*input_line_pointer)
+ {
+ case '@':
+ /* Find what relocation pseudo-function we're dealing with. */
+ pseudo_type = 0;
+ ch = *++input_line_pointer;
+ for (i = 0; i < NELEMS (pseudo_func); ++i)
+ if (pseudo_func[i].name && pseudo_func[i].name[0] == ch)
+ {
+ len = strlen (pseudo_func[i].name);
+ if (strncmp (pseudo_func[i].name + 1,
+ input_line_pointer + 1, len - 1) == 0
+ && !is_part_of_name (input_line_pointer[len]))
+ {
+ input_line_pointer += len;
+ pseudo_type = pseudo_func[i].type;
+ break;
+ }
+ }
+ switch (pseudo_type)
+ {
+ case PSEUDO_FUNC_RELOC:
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '(')
+ {
+ as_bad ("Expected '('");
+ goto err;
+ }
+ /* Skip '('. */
+ ++input_line_pointer;
+ expression (e);
+ if (*input_line_pointer++ != ')')
+ {
+ as_bad ("Missing ')'");
+ goto err;
+ }
+ if (e->X_op != O_symbol)
+ {
+ if (e->X_op != O_pseudo_fixup)
+ {
+ as_bad ("Not a symbolic expression");
+ goto err;
+ }
+ if (i != FUNC_LT_RELATIVE)
+ {
+ as_bad ("Illegal combination of relocation functions");
+ goto err;
+ }
+ switch (S_GET_VALUE (e->X_op_symbol))
+ {
+ case FUNC_FPTR_RELATIVE:
+ i = FUNC_LT_FPTR_RELATIVE; break;
+ case FUNC_DTP_MODULE:
+ i = FUNC_LT_DTP_MODULE; break;
+ case FUNC_DTP_RELATIVE:
+ i = FUNC_LT_DTP_RELATIVE; break;
+ case FUNC_TP_RELATIVE:
+ i = FUNC_LT_TP_RELATIVE; break;
+ default:
+ as_bad ("Illegal combination of relocation functions");
+ goto err;
+ }
+ }
+ /* Make sure gas doesn't get rid of local symbols that are used
+ in relocs. */
+ e->X_op = O_pseudo_fixup;
+ e->X_op_symbol = pseudo_func[i].u.sym;
+ break;
+
+ case PSEUDO_FUNC_CONST:
+ e->X_op = O_constant;
+ e->X_add_number = pseudo_func[i].u.ival;
+ break;
+
+ case PSEUDO_FUNC_REG:
+ e->X_op = O_register;
+ e->X_add_number = pseudo_func[i].u.ival;
+ break;
+
+ default:
+ name = input_line_pointer - 1;
+ get_symbol_end ();
+ as_bad ("Unknown pseudo function `%s'", name);
+ goto err;
+ }
+ break;
+
+ case '[':
+ ++input_line_pointer;
+ expression (e);
+ if (*input_line_pointer != ']')
+ {
+ as_bad ("Closing bracket misssing");
+ goto err;
+ }
+ else
+ {
+ if (e->X_op != O_register)
+ as_bad ("Register expected as index");
+
+ ++input_line_pointer;
+ e->X_op = O_index;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return;
+
+ err:
+ ignore_rest_of_line ();
+}
+
+/* Return 1 if it's OK to adjust a reloc by replacing the symbol with
+ a section symbol plus some offset. For relocs involving @fptr(),
+ directives we don't want such adjustments since we need to have the
+ original symbol's name in the reloc. */
+int
+ia64_fix_adjustable (fix)
+ fixS *fix;
+{
+ /* Prevent all adjustments to global symbols */
+ if (S_IS_EXTERN (fix->fx_addsy) || S_IS_WEAK (fix->fx_addsy))
+ return 0;
+
+ switch (fix->fx_r_type)
+ {
+ case BFD_RELOC_IA64_FPTR64I:
+ case BFD_RELOC_IA64_FPTR32MSB:
+ case BFD_RELOC_IA64_FPTR32LSB:
+ case BFD_RELOC_IA64_FPTR64MSB:
+ case BFD_RELOC_IA64_FPTR64LSB:
+ case BFD_RELOC_IA64_LTOFF_FPTR22:
+ case BFD_RELOC_IA64_LTOFF_FPTR64I:
+ return 0;
+ default:
+ break;
+ }
+
+ return 1;
+}
+
+int
+ia64_force_relocation (fix)
+ fixS *fix;
+{
+ switch (fix->fx_r_type)
+ {
+ case BFD_RELOC_IA64_FPTR64I:
+ case BFD_RELOC_IA64_FPTR32MSB:
+ case BFD_RELOC_IA64_FPTR32LSB:
+ case BFD_RELOC_IA64_FPTR64MSB:
+ case BFD_RELOC_IA64_FPTR64LSB:
+
+ case BFD_RELOC_IA64_LTOFF22:
+ case BFD_RELOC_IA64_LTOFF64I:
+ case BFD_RELOC_IA64_LTOFF_FPTR22:
+ case BFD_RELOC_IA64_LTOFF_FPTR64I:
+ case BFD_RELOC_IA64_PLTOFF22:
+ case BFD_RELOC_IA64_PLTOFF64I:
+ case BFD_RELOC_IA64_PLTOFF64MSB:
+ case BFD_RELOC_IA64_PLTOFF64LSB:
+
+ case BFD_RELOC_IA64_LTOFF22X:
+ case BFD_RELOC_IA64_LDXMOV:
+ return 1;
+
+ default:
+ break;
+ }
+
+ return generic_force_reloc (fix);
+}
+
+/* Decide from what point a pc-relative relocation is relative to,
+ relative to the pc-relative fixup. Er, relatively speaking. */
+long
+ia64_pcrel_from_section (fix, sec)
+ fixS *fix;
+ segT sec;
+{
+ unsigned long off = fix->fx_frag->fr_address + fix->fx_where;
+
+ if (bfd_get_section_flags (stdoutput, sec) & SEC_CODE)
+ off &= ~0xfUL;
+
+ return off;
+}
+
+
+/* Used to emit section-relative relocs for the dwarf2 debug data. */
+void
+ia64_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
+{
+ expressionS expr;
+
+ expr.X_op = O_pseudo_fixup;
+ expr.X_op_symbol = pseudo_func[FUNC_SEC_RELATIVE].u.sym;
+ expr.X_add_number = 0;
+ expr.X_add_symbol = symbol;
+ emit_expr (&expr, size);
+}
+
+/* This is called whenever some data item (not an instruction) needs a
+ fixup. We pick the right reloc code depending on the byteorder
+ currently in effect. */
+void
+ia64_cons_fix_new (f, where, nbytes, exp)
+ fragS *f;
+ int where;
+ int nbytes;
+ expressionS *exp;
+{
+ bfd_reloc_code_real_type code;
+ fixS *fix;
+
+ switch (nbytes)
+ {
+ /* There are no reloc for 8 and 16 bit quantities, but we allow
+ them here since they will work fine as long as the expression
+ is fully defined at the end of the pass over the source file. */
+ case 1: code = BFD_RELOC_8; break;
+ case 2: code = BFD_RELOC_16; break;
+ case 4:
+ if (target_big_endian)
+ code = BFD_RELOC_IA64_DIR32MSB;
+ else
+ code = BFD_RELOC_IA64_DIR32LSB;
+ break;
+
+ case 8:
+ /* In 32-bit mode, data8 could mean function descriptors too. */
+ if (exp->X_op == O_pseudo_fixup
+ && exp->X_op_symbol
+ && S_GET_VALUE (exp->X_op_symbol) == FUNC_IPLT_RELOC
+ && !(md.flags & EF_IA_64_ABI64))
+ {
+ if (target_big_endian)
+ code = BFD_RELOC_IA64_IPLTMSB;
+ else
+ code = BFD_RELOC_IA64_IPLTLSB;
+ exp->X_op = O_symbol;
+ break;
+ }
+ else
+ {
+ if (target_big_endian)
+ code = BFD_RELOC_IA64_DIR64MSB;
+ else
+ code = BFD_RELOC_IA64_DIR64LSB;
+ break;
+ }
+
+ case 16:
+ if (exp->X_op == O_pseudo_fixup
+ && exp->X_op_symbol
+ && S_GET_VALUE (exp->X_op_symbol) == FUNC_IPLT_RELOC)
+ {
+ if (target_big_endian)
+ code = BFD_RELOC_IA64_IPLTMSB;
+ else
+ code = BFD_RELOC_IA64_IPLTLSB;
+ exp->X_op = O_symbol;
+ break;
+ }
+ /* FALLTHRU */
+
+ default:
+ as_bad ("Unsupported fixup size %d", nbytes);
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (exp->X_op == O_pseudo_fixup)
+ {
+ exp->X_op = O_symbol;
+ code = ia64_gen_real_reloc_type (exp->X_op_symbol, code);
+ /* ??? If code unchanged, unsupported. */
+ }
+
+ fix = fix_new_exp (f, where, nbytes, exp, 0, code);
+ /* We need to store the byte order in effect in case we're going
+ to fix an 8 or 16 bit relocation (for which there no real
+ relocs available). See md_apply_fix3(). */
+ fix->tc_fix_data.bigendian = target_big_endian;
+}
+
+/* Return the actual relocation we wish to associate with the pseudo
+ reloc described by SYM and R_TYPE. SYM should be one of the
+ symbols in the pseudo_func array, or NULL. */
+
+static bfd_reloc_code_real_type
+ia64_gen_real_reloc_type (sym, r_type)
+ struct symbol *sym;
+ bfd_reloc_code_real_type r_type;
+{
+ bfd_reloc_code_real_type new = 0;
+
+ if (sym == NULL)
+ {
+ return r_type;
+ }
+
+ switch (S_GET_VALUE (sym))
+ {
+ case FUNC_FPTR_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_IMM64: new = BFD_RELOC_IA64_FPTR64I; break;
+ case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_FPTR32MSB; break;
+ case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_FPTR32LSB; break;
+ case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_FPTR64MSB; break;
+ case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_FPTR64LSB; break;
+ default: break;
+ }
+ break;
+
+ case FUNC_GP_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_IMM22: new = BFD_RELOC_IA64_GPREL22; break;
+ case BFD_RELOC_IA64_IMM64: new = BFD_RELOC_IA64_GPREL64I; break;
+ case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_GPREL32MSB; break;
+ case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_GPREL32LSB; break;
+ case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_GPREL64MSB; break;
+ case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_GPREL64LSB; break;
+ default: break;
+ }
+ break;
+
+ case FUNC_LT_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_IMM22: new = BFD_RELOC_IA64_LTOFF22; break;
+ case BFD_RELOC_IA64_IMM64: new = BFD_RELOC_IA64_LTOFF64I; break;
+ default: break;
+ }
+ break;
+
+ case FUNC_LT_RELATIVE_X:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_IMM22: new = BFD_RELOC_IA64_LTOFF22X; break;
+ default: break;
+ }
+ break;
+
+ case FUNC_PC_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_IMM22: new = BFD_RELOC_IA64_PCREL22; break;
+ case BFD_RELOC_IA64_IMM64: new = BFD_RELOC_IA64_PCREL64I; break;
+ case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_PCREL32MSB; break;
+ case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_PCREL32LSB; break;
+ case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_PCREL64MSB; break;
+ case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_PCREL64LSB; break;
+ default: break;
+ }
+ break;
+
+ case FUNC_PLT_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_IMM22: new = BFD_RELOC_IA64_PLTOFF22; break;
+ case BFD_RELOC_IA64_IMM64: new = BFD_RELOC_IA64_PLTOFF64I; break;
+ case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_PLTOFF64MSB;break;
+ case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_PLTOFF64LSB;break;
+ default: break;
+ }
+ break;
+
+ case FUNC_SEC_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_SECREL32MSB;break;
+ case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_SECREL32LSB;break;
+ case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_SECREL64MSB;break;
+ case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_SECREL64LSB;break;
+ default: break;
+ }
+ break;
+
+ case FUNC_SEG_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_SEGREL32MSB;break;
+ case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_SEGREL32LSB;break;
+ case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_SEGREL64MSB;break;
+ case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_SEGREL64LSB;break;
+ default: break;
+ }
+ break;
+
+ case FUNC_LTV_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_LTV32MSB; break;
+ case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_LTV32LSB; break;
+ case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_LTV64MSB; break;
+ case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_LTV64LSB; break;
+ default: break;
+ }
+ break;
+
+ case FUNC_LT_FPTR_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_IMM22:
+ new = BFD_RELOC_IA64_LTOFF_FPTR22; break;
+ case BFD_RELOC_IA64_IMM64:
+ new = BFD_RELOC_IA64_LTOFF_FPTR64I; break;
+ default:
+ break;
+ }
+ break;
+
+ case FUNC_TP_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_IMM14:
+ new = BFD_RELOC_IA64_TPREL14; break;
+ case BFD_RELOC_IA64_IMM22:
+ new = BFD_RELOC_IA64_TPREL22; break;
+ case BFD_RELOC_IA64_IMM64:
+ new = BFD_RELOC_IA64_TPREL64I; break;
+ default:
+ break;
+ }
+ break;
+
+ case FUNC_LT_TP_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_IMM22:
+ new = BFD_RELOC_IA64_LTOFF_TPREL22; break;
+ default:
+ break;
+ }
+ break;
+
+ case FUNC_LT_DTP_MODULE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_IMM22:
+ new = BFD_RELOC_IA64_LTOFF_DTPMOD22; break;
+ default:
+ break;
+ }
+ break;
+
+ case FUNC_DTP_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_DIR64MSB:
+ new = BFD_RELOC_IA64_DTPREL64MSB; break;
+ case BFD_RELOC_IA64_DIR64LSB:
+ new = BFD_RELOC_IA64_DTPREL64LSB; break;
+ case BFD_RELOC_IA64_IMM14:
+ new = BFD_RELOC_IA64_DTPREL14; break;
+ case BFD_RELOC_IA64_IMM22:
+ new = BFD_RELOC_IA64_DTPREL22; break;
+ case BFD_RELOC_IA64_IMM64:
+ new = BFD_RELOC_IA64_DTPREL64I; break;
+ default:
+ break;
+ }
+ break;
+
+ case FUNC_LT_DTP_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_IMM22:
+ new = BFD_RELOC_IA64_LTOFF_DTPREL22; break;
+ default:
+ break;
+ }
+ break;
+
+ case FUNC_IPLT_RELOC:
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* Hmmmm. Should this ever occur? */
+ if (new)
+ return new;
+ else
+ return r_type;
+}
+
+/* Here is where generate the appropriate reloc for pseudo relocation
+ functions. */
+void
+ia64_validate_fix (fix)
+ fixS *fix;
+{
+ switch (fix->fx_r_type)
+ {
+ case BFD_RELOC_IA64_FPTR64I:
+ case BFD_RELOC_IA64_FPTR32MSB:
+ case BFD_RELOC_IA64_FPTR64LSB:
+ case BFD_RELOC_IA64_LTOFF_FPTR22:
+ case BFD_RELOC_IA64_LTOFF_FPTR64I:
+ if (fix->fx_offset != 0)
+ as_bad_where (fix->fx_file, fix->fx_line,
+ "No addend allowed in @fptr() relocation");
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+fix_insn (fix, odesc, value)
+ fixS *fix;
+ const struct ia64_operand *odesc;
+ valueT value;
+{
+ bfd_vma insn[3], t0, t1, control_bits;
+ const char *err;
+ char *fixpos;
+ long slot;
+
+ slot = fix->fx_where & 0x3;
+ fixpos = fix->fx_frag->fr_literal + (fix->fx_where - slot);
+
+ /* Bundles are always in little-endian byte order */
+ t0 = bfd_getl64 (fixpos);
+ t1 = bfd_getl64 (fixpos + 8);
+ control_bits = t0 & 0x1f;
+ insn[0] = (t0 >> 5) & 0x1ffffffffffLL;
+ insn[1] = ((t0 >> 46) & 0x3ffff) | ((t1 & 0x7fffff) << 18);
+ insn[2] = (t1 >> 23) & 0x1ffffffffffLL;
+
+ err = NULL;
+ if (odesc - elf64_ia64_operands == IA64_OPND_IMMU64)
+ {
+ insn[1] = (value >> 22) & 0x1ffffffffffLL;
+ insn[2] |= (((value & 0x7f) << 13)
+ | (((value >> 7) & 0x1ff) << 27)
+ | (((value >> 16) & 0x1f) << 22)
+ | (((value >> 21) & 0x1) << 21)
+ | (((value >> 63) & 0x1) << 36));
+ }
+ else if (odesc - elf64_ia64_operands == IA64_OPND_IMMU62)
+ {
+ if (value & ~0x3fffffffffffffffULL)
+ err = "integer operand out of range";
+ insn[1] = (value >> 21) & 0x1ffffffffffLL;
+ insn[2] |= (((value & 0xfffff) << 6) | (((value >> 20) & 0x1) << 36));
+ }
+ else if (odesc - elf64_ia64_operands == IA64_OPND_TGT64)
+ {
+ value >>= 4;
+ insn[1] = ((value >> 20) & 0x7fffffffffLL) << 2;
+ insn[2] |= ((((value >> 59) & 0x1) << 36)
+ | (((value >> 0) & 0xfffff) << 13));
+ }
+ else
+ err = (*odesc->insert) (odesc, value, insn + slot);
+
+ if (err)
+ as_bad_where (fix->fx_file, fix->fx_line, err);
+
+ t0 = control_bits | (insn[0] << 5) | (insn[1] << 46);
+ t1 = ((insn[1] >> 18) & 0x7fffff) | (insn[2] << 23);
+ number_to_chars_littleendian (fixpos + 0, t0, 8);
+ number_to_chars_littleendian (fixpos + 8, t1, 8);
+}
+
+/* Attempt to simplify or even eliminate a fixup. The return value is
+ ignored; perhaps it was once meaningful, but now it is historical.
+ To indicate that a fixup has been eliminated, set FIXP->FX_DONE.
+
+ If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry
+ (if possible). */
+
+void
+md_apply_fix3 (fix, valP, seg)
+ fixS *fix;
+ valueT *valP;
+ segT seg ATTRIBUTE_UNUSED;
+{
+ char *fixpos;
+ valueT value = *valP;
+
+ fixpos = fix->fx_frag->fr_literal + fix->fx_where;
+
+ if (fix->fx_pcrel)
+ {
+ switch (fix->fx_r_type)
+ {
+ case BFD_RELOC_IA64_DIR32MSB:
+ fix->fx_r_type = BFD_RELOC_IA64_PCREL32MSB;
+ break;
+
+ case BFD_RELOC_IA64_DIR32LSB:
+ fix->fx_r_type = BFD_RELOC_IA64_PCREL32LSB;
+ break;
+
+ case BFD_RELOC_IA64_DIR64MSB:
+ fix->fx_r_type = BFD_RELOC_IA64_PCREL64MSB;
+ break;
+
+ case BFD_RELOC_IA64_DIR64LSB:
+ fix->fx_r_type = BFD_RELOC_IA64_PCREL64LSB;
+ break;
+
+ default:
+ break;
+ }
+ }
+ if (fix->fx_addsy)
+ {
+ switch (fix->fx_r_type)
+ {
+ case BFD_RELOC_UNUSED:
+ /* This must be a TAG13 or TAG13b operand. There are no external
+ relocs defined for them, so we must give an error. */
+ as_bad_where (fix->fx_file, fix->fx_line,
+ "%s must have a constant value",
+ elf64_ia64_operands[fix->tc_fix_data.opnd].desc);
+ fix->fx_done = 1;
+ return;
+
+ case BFD_RELOC_IA64_TPREL14:
+ case BFD_RELOC_IA64_TPREL22:
+ case BFD_RELOC_IA64_TPREL64I:
+ case BFD_RELOC_IA64_LTOFF_TPREL22:
+ case BFD_RELOC_IA64_LTOFF_DTPMOD22:
+ case BFD_RELOC_IA64_DTPREL14:
+ case BFD_RELOC_IA64_DTPREL22:
+ case BFD_RELOC_IA64_DTPREL64I:
+ case BFD_RELOC_IA64_LTOFF_DTPREL22:
+ S_SET_THREAD_LOCAL (fix->fx_addsy);
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (fix->tc_fix_data.opnd == IA64_OPND_NIL)
+ {
+ if (fix->tc_fix_data.bigendian)
+ number_to_chars_bigendian (fixpos, value, fix->fx_size);
+ else
+ number_to_chars_littleendian (fixpos, value, fix->fx_size);
+ fix->fx_done = 1;
+ }
+ else
+ {
+ fix_insn (fix, elf64_ia64_operands + fix->tc_fix_data.opnd, value);
+ fix->fx_done = 1;
+ }
+}
+
+/* Generate the BFD reloc to be stuck in the object file from the
+ fixup used internally in the assembler. */
+
+arelent *
+tc_gen_reloc (sec, fixp)
+ asection *sec ATTRIBUTE_UNUSED;
+ fixS *fixp;
+{
+ arelent *reloc;
+
+ reloc = xmalloc (sizeof (*reloc));
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ reloc->addend = fixp->fx_offset;
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+
+ if (!reloc->howto)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ "Cannot represent %s relocation in object file",
+ bfd_get_reloc_code_name (fixp->fx_r_type));
+ }
+ return reloc;
+}
+
+/* Turn a string in input_line_pointer into a floating point constant
+ of type TYPE, and store the appropriate bytes in *LIT. The number
+ of LITTLENUMS emitted is stored in *SIZE. An error message is
+ returned, or NULL on OK. */
+
+#define MAX_LITTLENUMS 5
+
+char *
+md_atof (type, lit, size)
+ int type;
+ char *lit;
+ int *size;
+{
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ char *t;
+ int prec;
+
+ switch (type)
+ {
+ /* IEEE floats */
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ case 'p':
+ case 'P':
+ prec = 5;
+ break;
+
+ default:
+ *size = 0;
+ return "Bad call to MD_ATOF()";
+ }
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ (*ia64_float_to_chars) (lit, words, prec);
+
+ if (type == 'X')
+ {
+ /* It is 10 byte floating point with 6 byte padding. */
+ memset (&lit [10], 0, 6);
+ *size = 8 * sizeof (LITTLENUM_TYPE);
+ }
+ else
+ *size = prec * sizeof (LITTLENUM_TYPE);
+
+ return 0;
+}
+
+/* Handle ia64 specific semantics of the align directive. */
+
+void
+ia64_md_do_align (n, fill, len, max)
+ int n ATTRIBUTE_UNUSED;
+ const char *fill ATTRIBUTE_UNUSED;
+ int len ATTRIBUTE_UNUSED;
+ int max ATTRIBUTE_UNUSED;
+{
+ if (subseg_text_p (now_seg))
+ ia64_flush_insns ();
+}
+
+/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
+ of an rs_align_code fragment. */
+
+void
+ia64_handle_align (fragp)
+ fragS *fragp;
+{
+ /* Use mfi bundle of nops with no stop bits. */
+ static const unsigned char le_nop[]
+ = { 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00};
+ static const unsigned char le_nop_stop[]
+ = { 0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00};
+
+ int bytes;
+ char *p;
+ const unsigned char *nop;
+
+ if (fragp->fr_type != rs_align_code)
+ return;
+
+ /* Check if this frag has to end with a stop bit. */
+ nop = fragp->tc_frag_data ? le_nop_stop : le_nop;
+
+ bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
+ p = fragp->fr_literal + fragp->fr_fix;
+
+ /* If no paddings are needed, we check if we need a stop bit. */
+ if (!bytes && fragp->tc_frag_data)
+ {
+ if (fragp->fr_fix < 16)
+#if 1
+ /* FIXME: It won't work with
+ .align 16
+ alloc r32=ar.pfs,1,2,4,0
+ */
+ ;
+#else
+ as_bad_where (fragp->fr_file, fragp->fr_line,
+ _("Can't add stop bit to mark end of instruction group"));
+#endif
+ else
+ /* Bundles are always in little-endian byte order. Make sure
+ the previous bundle has the stop bit. */
+ *(p - 16) |= 1;
+ }
+
+ /* Make sure we are on a 16-byte boundary, in case someone has been
+ putting data into a text section. */
+ if (bytes & 15)
+ {
+ int fix = bytes & 15;
+ memset (p, 0, fix);
+ p += fix;
+ bytes -= fix;
+ fragp->fr_fix += fix;
+ }
+
+ /* Instruction bundles are always little-endian. */
+ memcpy (p, nop, 16);
+ fragp->fr_var = 16;
+}
+
+static void
+ia64_float_to_chars_bigendian (char *lit, LITTLENUM_TYPE *words,
+ int prec)
+{
+ while (prec--)
+ {
+ number_to_chars_bigendian (lit, (long) (*words++),
+ sizeof (LITTLENUM_TYPE));
+ lit += sizeof (LITTLENUM_TYPE);
+ }
+}
+
+static void
+ia64_float_to_chars_littleendian (char *lit, LITTLENUM_TYPE *words,
+ int prec)
+{
+ while (prec--)
+ {
+ number_to_chars_littleendian (lit, (long) (words[prec]),
+ sizeof (LITTLENUM_TYPE));
+ lit += sizeof (LITTLENUM_TYPE);
+ }
+}
+
+void
+ia64_elf_section_change_hook (void)
+{
+ dot_byteorder (-1);
+}
+
+/* Check if a label should be made global. */
+void
+ia64_check_label (symbolS *label)
+{
+ if (*input_line_pointer == ':')
+ {
+ S_SET_EXTERNAL (label);
+ input_line_pointer++;
+ }
+}
+
+/* Used to remember where .alias and .secalias directives are seen. We
+ will rename symbol and section names when we are about to output
+ the relocatable file. */
+struct alias
+{
+ char *file; /* The file where the directive is seen. */
+ unsigned int line; /* The line number the directive is at. */
+ const char *name; /* The orignale name of the symbol. */
+};
+
+/* Called for .alias and .secalias directives. If SECTION is 1, it is
+ .secalias. Otherwise, it is .alias. */
+static void
+dot_alias (int section)
+{
+ char *name, *alias;
+ char delim;
+ char *end_name;
+ int len;
+ const char *error_string;
+ struct alias *h;
+ const char *a;
+ struct hash_control *ahash, *nhash;
+ const char *kind;
+
+ name = input_line_pointer;
+ delim = get_symbol_end ();
+ end_name = input_line_pointer;
+ *end_name = delim;
+
+ if (name == end_name)
+ {
+ as_bad (_("expected symbol name"));
+ discard_rest_of_line ();
+ return;
+ }
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != ',')
+ {
+ *end_name = 0;
+ as_bad (_("expected comma after \"%s\""), name);
+ *end_name = delim;
+ ignore_rest_of_line ();
+ return;
+ }
+
+ input_line_pointer++;
+ *end_name = 0;
+
+ /* We call demand_copy_C_string to check if alias string is valid.
+ There should be a closing `"' and no `\0' in the string. */
+ alias = demand_copy_C_string (&len);
+ if (alias == NULL)
+ {
+ ignore_rest_of_line ();
+ return;
+ }
+
+ /* Make a copy of name string. */
+ len = strlen (name) + 1;
+ obstack_grow (&notes, name, len);
+ name = obstack_finish (&notes);
+
+ if (section)
+ {
+ kind = "section";
+ ahash = secalias_hash;
+ nhash = secalias_name_hash;
+ }
+ else
+ {
+ kind = "symbol";
+ ahash = alias_hash;
+ nhash = alias_name_hash;
+ }
+
+ /* Check if alias has been used before. */
+ h = (struct alias *) hash_find (ahash, alias);
+ if (h)
+ {
+ if (strcmp (h->name, name))
+ as_bad (_("`%s' is already the alias of %s `%s'"),
+ alias, kind, h->name);
+ goto out;
+ }
+
+ /* Check if name already has an alias. */
+ a = (const char *) hash_find (nhash, name);
+ if (a)
+ {
+ if (strcmp (a, alias))
+ as_bad (_("%s `%s' already has an alias `%s'"), kind, name, a);
+ goto out;
+ }
+
+ h = (struct alias *) xmalloc (sizeof (struct alias));
+ as_where (&h->file, &h->line);
+ h->name = name;
+
+ error_string = hash_jam (ahash, alias, (PTR) h);
+ if (error_string)
+ {
+ as_fatal (_("inserting \"%s\" into %s alias hash table failed: %s"),
+ alias, kind, error_string);
+ goto out;
+ }
+
+ error_string = hash_jam (nhash, name, (PTR) alias);
+ if (error_string)
+ {
+ as_fatal (_("inserting \"%s\" into %s name hash table failed: %s"),
+ alias, kind, error_string);
+out:
+ obstack_free (&notes, name);
+ obstack_free (&notes, alias);
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* It renames the original symbol name to its alias. */
+static void
+do_alias (const char *alias, PTR value)
+{
+ struct alias *h = (struct alias *) value;
+ symbolS *sym = symbol_find (h->name);
+
+ if (sym == NULL)
+ as_warn_where (h->file, h->line,
+ _("symbol `%s' aliased to `%s' is not used"),
+ h->name, alias);
+ else
+ S_SET_NAME (sym, (char *) alias);
+}
+
+/* Called from write_object_file. */
+void
+ia64_adjust_symtab (void)
+{
+ hash_traverse (alias_hash, do_alias);
+}
+
+/* It renames the original section name to its alias. */
+static void
+do_secalias (const char *alias, PTR value)
+{
+ struct alias *h = (struct alias *) value;
+ segT sec = bfd_get_section_by_name (stdoutput, h->name);
+
+ if (sec == NULL)
+ as_warn_where (h->file, h->line,
+ _("section `%s' aliased to `%s' is not used"),
+ h->name, alias);
+ else
+ sec->name = alias;
+}
+
+/* Called from write_object_file. */
+void
+ia64_frob_file (void)
+{
+ hash_traverse (secalias_hash, do_secalias);
+}
diff --git a/x/binutils/gas/config/tc-ia64.h b/x/binutils/gas/config/tc-ia64.h
new file mode 100644
index 0000000..dcc2c29
--- /dev/null
+++ b/x/binutils/gas/config/tc-ia64.h
@@ -0,0 +1,299 @@
+/* tc-ia64.h -- Header file for tc-ia64.c.
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "opcode/ia64.h"
+#include "elf/ia64.h"
+
+#define TC_IA64
+
+/* Linux is little endian by default. HPUX is big endian by default. */
+#ifdef TE_HPUX
+#define TARGET_BYTES_BIG_ENDIAN 1
+#define MD_FLAGS_DEFAULT EF_IA_64_BE
+#else
+#define TARGET_BYTES_BIG_ENDIAN 0
+#define MD_FLAGS_DEFAULT EF_IA_64_ABI64
+#endif /* TE_HPUX */
+
+extern void (*ia64_number_to_chars) PARAMS ((char *, valueT, int));
+#define md_number_to_chars (*ia64_number_to_chars)
+
+extern void ia64_elf_section_change_hook PARAMS ((void));
+#define md_elf_section_change_hook ia64_elf_section_change_hook
+
+/* We record the endian for this section. 0 means default, 1 means
+ big endian and 2 means little endian. */
+struct ia64_segment_info_type
+{
+ unsigned int endian : 2;
+};
+
+#define TC_SEGMENT_INFO_TYPE struct ia64_segment_info_type
+
+extern void ia64_adjust_symtab PARAMS ((void));
+#define tc_adjust_symtab() ia64_adjust_symtab ()
+
+extern void ia64_frob_file PARAMS ((void));
+#define tc_frob_file() ia64_frob_file ()
+
+/* We need to set the default object file format in ia64_init and not in
+ md_begin. This is because parse_args is called before md_begin, and we
+ do not want md_begin to wipe out the flag settings set by options parsed in
+ md_parse_args. */
+
+#define HOST_SPECIAL_INIT ia64_init
+extern void ia64_init PARAMS ((int, char **));
+
+#define TARGET_FORMAT ia64_target_format()
+extern const char *ia64_target_format PARAMS ((void));
+
+#define TARGET_ARCH bfd_arch_ia64
+#define DOUBLESLASH_LINE_COMMENTS /* allow //-style comments */
+
+#define NEED_LITERAL_POOL /* need gp literal pool */
+#define RELOC_REQUIRES_SYMBOL
+#define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs */
+#define NEED_INDEX_OPERATOR /* [ ] is index operator */
+
+#define QUOTES_IN_INSN /* allow `string "foo;bar"' */
+#define LEX_AT LEX_NAME /* allow `@' inside name */
+#define LEX_QM LEX_NAME /* allow `?' inside name */
+#define LEX_HASH LEX_END_NAME /* allow `#' ending a name */
+
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
+
+struct ia64_fix
+ {
+ int bigendian; /* byte order at fix location */
+ enum ia64_opnd opnd;
+ };
+
+extern void ia64_end_of_source PARAMS((void));
+extern void ia64_start_line PARAMS((void));
+extern int ia64_unrecognized_line PARAMS((int ch));
+extern void ia64_frob_label PARAMS((struct symbol *sym));
+#ifdef TE_HPUX
+extern int ia64_frob_symbol PARAMS((struct symbol *sym));
+#endif
+extern void ia64_flush_pending_output PARAMS((void));
+extern int ia64_parse_name (char *name, expressionS *e);
+extern int ia64_optimize_expr PARAMS((expressionS *l, operatorT op,
+ expressionS *r));
+extern void ia64_cons_align PARAMS((int));
+extern void ia64_flush_insns PARAMS((void));
+extern int ia64_fix_adjustable PARAMS((struct fix *fix));
+extern int ia64_force_relocation PARAMS((struct fix *));
+extern void ia64_cons_fix_new PARAMS ((fragS *f, int where, int nbytes,
+ expressionS *exp));
+extern void ia64_validate_fix PARAMS ((struct fix *fix));
+extern char * ia64_canonicalize_symbol_name PARAMS ((char *));
+extern int ia64_elf_section_letter PARAMS ((int, char **));
+extern flagword ia64_elf_section_flags PARAMS ((flagword, int, int));
+extern int ia64_elf_section_type PARAMS ((const char *, size_t len));
+extern long ia64_pcrel_from_section PARAMS ((struct fix *fix, segT sec));
+extern void ia64_md_do_align PARAMS ((int, const char *, int, int));
+extern void ia64_handle_align PARAMS ((fragS *f));
+extern void ia64_after_parse_args PARAMS ((void));
+extern void ia64_dwarf2_emit_offset PARAMS ((symbolS *, unsigned int));
+extern void ia64_check_label PARAMS ((symbolS *));
+extern int ia64_estimate_size_before_relax (fragS *, asection *);
+extern void ia64_convert_frag (fragS *);
+
+#define md_end() ia64_end_of_source ()
+#define md_start_line_hook() ia64_start_line ()
+#define tc_unrecognized_line(ch) ia64_unrecognized_line (ch)
+#define tc_frob_label(s) ia64_frob_label (s)
+#ifdef TE_HPUX
+#define tc_frob_symbol(s,p) p |= ia64_frob_symbol (s)
+#endif /* TE_HPUX */
+#define md_flush_pending_output() ia64_flush_pending_output ()
+#define md_parse_name(s,e,c) ia64_parse_name (s, e)
+#define tc_canonicalize_symbol_name(s) ia64_canonicalize_symbol_name (s)
+#define tc_canonicalize_section_name(s) ia64_canonicalize_symbol_name (s)
+#define md_optimize_expr(l,o,r) ia64_optimize_expr (l, o, r)
+#define md_cons_align(n) ia64_cons_align (n)
+#define TC_FORCE_RELOCATION(f) ia64_force_relocation (f)
+#define tc_fix_adjustable(f) ia64_fix_adjustable (f)
+#define MD_APPLY_SYM_VALUE(FIX) 0
+#define md_convert_frag(b,s,f) ia64_convert_frag (f)
+#define md_create_long_jump(p,f,t,fr,s) as_fatal ("ia64_create_long_jump")
+#define md_create_short_jump(p,f,t,fr,s) \
+ as_fatal ("ia64_create_short_jump")
+#define md_estimate_size_before_relax(f,s) \
+ ia64_estimate_size_before_relax(f,s)
+#define md_elf_section_letter ia64_elf_section_letter
+#define md_elf_section_flags ia64_elf_section_flags
+#define TC_FIX_TYPE struct ia64_fix
+#define TC_INIT_FIX_DATA(f) { f->tc_fix_data.opnd = 0; }
+#define TC_CONS_FIX_NEW(f,o,l,e) ia64_cons_fix_new (f, o, l, e)
+#define TC_VALIDATE_FIX(fix,seg,skip) ia64_validate_fix (fix)
+#define MD_PCREL_FROM_SECTION(fix,sec) ia64_pcrel_from_section (fix, sec)
+#define md_section_align(seg,size) (size)
+#define md_do_align(n,f,l,m,j) ia64_md_do_align (n,f,l,m)
+#define HANDLE_ALIGN(f) ia64_handle_align (f)
+#define md_elf_section_type(str,len) ia64_elf_section_type (str, len)
+#define md_after_parse_args() ia64_after_parse_args ()
+#define TC_DWARF2_EMIT_OFFSET ia64_dwarf2_emit_offset
+#define tc_check_label(l) ia64_check_label (l)
+
+/* Record if an alignment frag should end with a stop bit. */
+#define TC_FRAG_TYPE int
+#define TC_FRAG_INIT(FRAGP) do {(FRAGP)->tc_frag_data = 0;}while (0)
+
+#define MAX_MEM_FOR_RS_ALIGN_CODE (15 + 16)
+
+#define WORKING_DOT_WORD /* don't do broken word processing for now */
+
+#define DWARF2_LINE_MIN_INSN_LENGTH 1 /* so slot-multipliers can be 1 */
+
+/* This is the information required for unwind records in an ia64
+ object file. This is required by GAS and the compiler runtime. */
+
+/* These are the starting point masks for the various types of
+ unwind records. To create a record of type R3 for instance, one
+ starts by using the value UNW_R3 and or-ing in any other required values.
+ These values are also unique (in context), so they can be used to identify
+ the various record types as well. UNW_Bx and some UNW_Px do have the
+ same value, but Px can only occur in a prologue context, and Bx in
+ a body context. */
+
+#define UNW_R1 0x00
+#define UNW_R2 0x40
+#define UNW_R3 0x60
+#define UNW_P1 0x80
+#define UNW_P2 0xA0
+#define UNW_P3 0xB0
+#define UNW_P4 0xB8
+#define UNW_P5 0xB9
+#define UNW_P6 0xC0
+#define UNW_P7 0xE0
+#define UNW_P8 0xF0
+#define UNW_P9 0xF1
+#define UNW_P10 0xFF
+#define UNW_X1 0xF9
+#define UNW_X2 0xFA
+#define UNW_X3 0xFB
+#define UNW_X4 0xFC
+#define UNW_B1 0x80
+#define UNW_B2 0xC0
+#define UNW_B3 0xE0
+#define UNW_B4 0xF0
+
+/* These are all the various types of unwind records. */
+
+typedef enum
+{
+ prologue, prologue_gr, body, mem_stack_f, mem_stack_v, psp_gr, psp_sprel,
+ rp_when, rp_gr, rp_br, rp_psprel, rp_sprel, pfs_when, pfs_gr, pfs_psprel,
+ pfs_sprel, preds_when, preds_gr, preds_psprel, preds_sprel,
+ fr_mem, frgr_mem, gr_gr, gr_mem, br_mem, br_gr, spill_base, spill_mask,
+ unat_when, unat_gr, unat_psprel, unat_sprel, lc_when, lc_gr, lc_psprel,
+ lc_sprel, fpsr_when, fpsr_gr, fpsr_psprel, fpsr_sprel,
+ priunat_when_gr, priunat_when_mem, priunat_gr, priunat_psprel,
+ priunat_sprel, bsp_when, bsp_gr, bsp_psprel, bsp_sprel, bspstore_when,
+ bspstore_gr, bspstore_psprel, bspstore_sprel, rnat_when, rnat_gr,
+ rnat_psprel, rnat_sprel, epilogue, label_state, copy_state,
+ spill_psprel, spill_sprel, spill_reg, spill_psprel_p, spill_sprel_p,
+ spill_reg_p, unwabi, endp
+} unw_record_type;
+
+/* These structures declare the fields that can be used in each of the
+ 4 record formats, R, P, B and X. */
+
+typedef struct unw_r_record
+{
+ unsigned long rlen;
+ unsigned short grmask;
+ unsigned short grsave;
+ /* masks to represent the union of save.g, save.f, save.b, and
+ save.gf: */
+ unsigned long imask_size;
+ struct
+ {
+ unsigned char *i;
+ unsigned long fr_mem;
+ unsigned char gr_mem;
+ unsigned char br_mem;
+ } mask;
+} unw_r_record;
+
+typedef struct unw_p_record
+{
+ void *imask;
+ unsigned long t;
+ unsigned long size;
+ unsigned long spoff;
+ unsigned long br;
+ unsigned long pspoff;
+ unsigned short gr;
+ unsigned short rmask;
+ unsigned short grmask;
+ unsigned long frmask;
+ unsigned short brmask;
+ unsigned char abi;
+ unsigned char context;
+} unw_p_record;
+
+typedef struct unw_b_record
+{
+ unsigned long t;
+ unsigned long label;
+ unsigned short ecount;
+} unw_b_record;
+
+typedef struct unw_x_record
+{
+ unsigned long t;
+ unsigned long spoff;
+ unsigned long pspoff;
+ unsigned short reg;
+ unsigned short treg;
+ unsigned short qp;
+ unsigned short ab; /* Value of the AB field.. */
+ unsigned short xy; /* Value of the XY field.. */
+} unw_x_record;
+
+/* This structure is used to determine the specific record type and
+ its fields. */
+typedef struct unwind_record
+{
+ unw_record_type type;
+ union {
+ unw_r_record r;
+ unw_p_record p;
+ unw_b_record b;
+ unw_x_record x;
+ } record;
+} unwind_record;
+
+/* This expression evaluates to true if the relocation is for a local
+ object for which we still want to do the relocation at runtime.
+ False if we are willing to perform this relocation while building
+ the .o file. */
+
+/* If the reloc type is BFD_RELOC_UNUSED, then this is for a TAG13/TAG13b field
+ which has no external reloc, so we must resolve the value now. */
+
+#define TC_FORCE_RELOCATION_LOCAL(FIX) \
+ ((FIX)->fx_r_type != BFD_RELOC_UNUSED \
+ && (!(FIX)->fx_pcrel \
+ || (FIX)->fx_plt \
+ || TC_FORCE_RELOCATION (FIX)))
diff --git a/x/binutils/gas/config/tc-m68851.h b/x/binutils/gas/config/tc-m68851.h
new file mode 100644
index 0000000..870e881
--- /dev/null
+++ b/x/binutils/gas/config/tc-m68851.h
@@ -0,0 +1,303 @@
+/* This file is tc-m68851.h
+
+ Copyright 1987, 1988, 1989, 1990, 1991, 1992, 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ * pmmu.h
+ */
+
+/* I suppose we have to copyright this file. Someone on the net sent it
+ to us as part of the changes for the m68851 Memory Management Unit */
+
+/* Copyright (C) 1987 Free Software Foundation, Inc.
+
+ This file is part of Gas, the GNU Assembler.
+
+ The GNU assembler is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY. No author or distributor
+ accepts responsibility to anyone for the consequences of using it
+ or for whether it serves any particular purpose or works at all,
+ unless he says so in writing. Refer to the GNU Assembler General
+ Public License for full details.
+
+ Everyone is granted permission to copy, modify and redistribute
+ the GNU Assembler, but only under the conditions described in the
+ GNU Assembler General Public License. A copy of this license is
+ supposed to have been given to you along with the GNU Assembler
+ so you can know your rights and responsibilities. It should be
+ in a file named COPYING. Among other things, the copyright
+ notice and this notice must be preserved on all copies. */
+
+#ifdef m68851
+
+/*
+ I didn't use much imagination in choosing the
+ following codes, so many of them aren't very
+ mnemonic. -rab
+
+ P pmmu register
+ Possible values:
+ 000 TC Translation Control reg
+ 100 CAL Current Access Level
+ 101 VAL Validate Access Level
+ 110 SCC Stack Change Control
+ 111 AC Access Control
+
+ W wide pmmu registers
+ Possible values:
+ 001 DRP Dma Root Pointer
+ 010 SRP Supervisor Root Pointer
+ 011 CRP Cpu Root Pointer
+
+ f function code register
+ 0 SFC
+ 1 DFC
+
+ V VAL register only
+
+ X BADx, BACx
+ 100 BAD Breakpoint Acknowledge Data
+ 101 BAC Breakpoint Acknowledge Control
+
+ Y PSR
+ Z PCSR
+
+ | memory (modes 2-6, 7.*)
+
+ */
+
+/*
+ * these defines should be in m68k.c but
+ * i put them here to keep all the m68851 stuff
+ * together -rab
+ * JF--Make sure these #s don't clash with the ones in m68k.c
+ * That would be BAD.
+ */
+#define TC (FPS+1) /* 48 */
+#define DRP (TC+1) /* 49 */
+#define SRP (DRP+1) /* 50 */
+#define CRP (SRP+1) /* 51 */
+#define CAL (CRP+1) /* 52 */
+#define VAL (CAL+1) /* 53 */
+#define SCC (VAL+1) /* 54 */
+#define AC (SCC+1) /* 55 */
+#define BAD (AC+1) /* 56,57,58,59, 60,61,62,63 */
+#define BAC (BAD+8) /* 64,65,66,67, 68,69,70,71 */
+#define PSR (BAC+8) /* 72 */
+#define PCSR (PSR+1) /* 73 */
+
+/* name */ /* opcode */ /* match */ /* args */
+
+{"pbac", one(0xf0c7), one(0xffbf), "Bc"},
+{"pbacw", one(0xf087), one(0xffbf), "Bc"},
+{"pbas", one(0xf0c6), one(0xffbf), "Bc"},
+{"pbasw", one(0xf086), one(0xffbf), "Bc"},
+{"pbbc", one(0xf0c1), one(0xffbf), "Bc"},
+{"pbbcw", one(0xf081), one(0xffbf), "Bc"},
+{"pbbs", one(0xf0c0), one(0xffbf), "Bc"},
+{"pbbsw", one(0xf080), one(0xffbf), "Bc"},
+{"pbcc", one(0xf0cf), one(0xffbf), "Bc"},
+{"pbccw", one(0xf08f), one(0xffbf), "Bc"},
+{"pbcs", one(0xf0ce), one(0xffbf), "Bc"},
+{"pbcsw", one(0xf08e), one(0xffbf), "Bc"},
+{"pbgc", one(0xf0cd), one(0xffbf), "Bc"},
+{"pbgcw", one(0xf08d), one(0xffbf), "Bc"},
+{"pbgs", one(0xf0cc), one(0xffbf), "Bc"},
+{"pbgsw", one(0xf08c), one(0xffbf), "Bc"},
+{"pbic", one(0xf0cb), one(0xffbf), "Bc"},
+{"pbicw", one(0xf08b), one(0xffbf), "Bc"},
+{"pbis", one(0xf0ca), one(0xffbf), "Bc"},
+{"pbisw", one(0xf08a), one(0xffbf), "Bc"},
+{"pblc", one(0xf0c3), one(0xffbf), "Bc"},
+{"pblcw", one(0xf083), one(0xffbf), "Bc"},
+{"pbls", one(0xf0c2), one(0xffbf), "Bc"},
+{"pblsw", one(0xf082), one(0xffbf), "Bc"},
+{"pbsc", one(0xf0c5), one(0xffbf), "Bc"},
+{"pbscw", one(0xf085), one(0xffbf), "Bc"},
+{"pbss", one(0xf0c4), one(0xffbf), "Bc"},
+{"pbssw", one(0xf084), one(0xffbf), "Bc"},
+{"pbwc", one(0xf0c9), one(0xffbf), "Bc"},
+{"pbwcw", one(0xf089), one(0xffbf), "Bc"},
+{"pbws", one(0xf0c8), one(0xffbf), "Bc"},
+{"pbwsw", one(0xf088), one(0xffbf), "Bc"},
+
+{"pdbac", two(0xf048, 0x0007), two(0xfff8, 0xffff), "DsBw"},
+{"pdbas", two(0xf048, 0x0006), two(0xfff8, 0xffff), "DsBw"},
+{"pdbbc", two(0xf048, 0x0001), two(0xfff8, 0xffff), "DsBw"},
+{"pdbbs", two(0xf048, 0x0000), two(0xfff8, 0xffff), "DsBw"},
+{"pdbcc", two(0xf048, 0x000f), two(0xfff8, 0xffff), "DsBw"},
+{"pdbcs", two(0xf048, 0x000e), two(0xfff8, 0xffff), "DsBw"},
+{"pdbgc", two(0xf048, 0x000d), two(0xfff8, 0xffff), "DsBw"},
+{"pdbgs", two(0xf048, 0x000c), two(0xfff8, 0xffff), "DsBw"},
+{"pdbic", two(0xf048, 0x000b), two(0xfff8, 0xffff), "DsBw"},
+{"pdbis", two(0xf048, 0x000a), two(0xfff8, 0xffff), "DsBw"},
+{"pdblc", two(0xf048, 0x0003), two(0xfff8, 0xffff), "DsBw"},
+{"pdbls", two(0xf048, 0x0002), two(0xfff8, 0xffff), "DsBw"},
+{"pdbsc", two(0xf048, 0x0005), two(0xfff8, 0xffff), "DsBw"},
+{"pdbss", two(0xf048, 0x0004), two(0xfff8, 0xffff), "DsBw"},
+{"pdbwc", two(0xf048, 0x0009), two(0xfff8, 0xffff), "DsBw"},
+{"pdbws", two(0xf048, 0x0008), two(0xfff8, 0xffff), "DsBw"},
+
+{"pflusha", two(0xf000, 0x2400), two(0xffff, 0xffff), "" },
+
+{"pflush", two(0xf000, 0x3010), two(0xffc0, 0xfe10), "T3T9" },
+{"pflush", two(0xf000, 0x3810), two(0xffc0, 0xfe10), "T3T9&s" },
+{"pflush", two(0xf000, 0x3008), two(0xffc0, 0xfe18), "D3T9" },
+{"pflush", two(0xf000, 0x3808), two(0xffc0, 0xfe18), "D3T9&s" },
+{"pflush", two(0xf000, 0x3000), two(0xffc0, 0xfe1e), "f3T9" },
+{"pflush", two(0xf000, 0x3800), two(0xffc0, 0xfe1e), "f3T9&s" },
+
+{"pflushs", two(0xf000, 0x3410), two(0xfff8, 0xfe10), "T3T9" },
+{"pflushs", two(0xf000, 0x3c00), two(0xfff8, 0xfe00), "T3T9&s" },
+{"pflushs", two(0xf000, 0x3408), two(0xfff8, 0xfe18), "D3T9" },
+{"pflushs", two(0xf000, 0x3c08), two(0xfff8, 0xfe18), "D3T9&s" },
+{"pflushs", two(0xf000, 0x3400), two(0xfff8, 0xfe1e), "f3T9" },
+{"pflushs", two(0xf000, 0x3c00), two(0xfff8, 0xfe1e), "f3T9&s"},
+
+{"pflushr", two(0xf000, 0xa000), two(0xffc0, 0xffff), "|s" },
+
+{"ploadr", two(0xf000, 0x2210), two(0xffc0, 0xfff0), "T3&s" },
+{"ploadr", two(0xf000, 0x2208), two(0xffc0, 0xfff8), "D3&s" },
+{"ploadr", two(0xf000, 0x2200), two(0xffc0, 0xfffe), "f3&s" },
+{"ploadw", two(0xf000, 0x2010), two(0xffc0, 0xfff0), "T3&s" },
+{"ploadw", two(0xf000, 0x2008), two(0xffc0, 0xfff8), "D3&s" },
+{"ploadw", two(0xf000, 0x2000), two(0xffc0, 0xfffe), "f3&s" },
+
+ /* TC, CRP, DRP, SRP, CAL, VAL, SCC, AC */
+{"pmove", two(0xf000, 0x4000), two(0xffc0, 0xe3ff), "*sP8" },
+{"pmove", two(0xf000, 0x4200), two(0xffc0, 0xe3ff), "P8%s" },
+{"pmove", two(0xf000, 0x4000), two(0xffc0, 0xe3ff), "|sW8" },
+{"pmove", two(0xf000, 0x4200), two(0xffc0, 0xe3ff), "W8~s" },
+
+ /* BADx, BACx */
+{"pmove", two(0xf000, 0x6200), two(0xffc0, 0xe3e3), "*sX3" },
+{"pmove", two(0xf000, 0x6000), two(0xffc0, 0xe3e3), "X3%s" },
+
+ /* PSR, PCSR */
+ /* {"pmove", two(0xf000, 0x6100), two(oxffc0, oxffff), "*sZ8" }, */
+{"pmove", two(0xf000, 0x6000), two(0xffc0, 0xffff), "*sY8" },
+{"pmove", two(0xf000, 0x6200), two(0xffc0, 0xffff), "Y8%s" },
+{"pmove", two(0xf000, 0x6600), two(0xffc0, 0xffff), "Z8%s" },
+
+{"prestore", one(0xf140), one(0xffc0), "&s"},
+{"prestore", one(0xf158), one(0xfff8), "+s"},
+{"psave", one(0xf100), one(0xffc0), "&s"},
+{"psave", one(0xf100), one(0xffc0), "+s"},
+
+{"psac", two(0xf040, 0x0007), two(0xffc0, 0xffff), "@s"},
+{"psas", two(0xf040, 0x0006), two(0xffc0, 0xffff), "@s"},
+{"psbc", two(0xf040, 0x0001), two(0xffc0, 0xffff), "@s"},
+{"psbs", two(0xf040, 0x0000), two(0xffc0, 0xffff), "@s"},
+{"pscc", two(0xf040, 0x000f), two(0xffc0, 0xffff), "@s"},
+{"pscs", two(0xf040, 0x000e), two(0xffc0, 0xffff), "@s"},
+{"psgc", two(0xf040, 0x000d), two(0xffc0, 0xffff), "@s"},
+{"psgs", two(0xf040, 0x000c), two(0xffc0, 0xffff), "@s"},
+{"psic", two(0xf040, 0x000b), two(0xffc0, 0xffff), "@s"},
+{"psis", two(0xf040, 0x000a), two(0xffc0, 0xffff), "@s"},
+{"pslc", two(0xf040, 0x0003), two(0xffc0, 0xffff), "@s"},
+{"psls", two(0xf040, 0x0002), two(0xffc0, 0xffff), "@s"},
+{"pssc", two(0xf040, 0x0005), two(0xffc0, 0xffff), "@s"},
+{"psss", two(0xf040, 0x0004), two(0xffc0, 0xffff), "@s"},
+{"pswc", two(0xf040, 0x0009), two(0xffc0, 0xffff), "@s"},
+{"psws", two(0xf040, 0x0008), two(0xffc0, 0xffff), "@s"},
+
+{"ptestr", two(0xf000, 0x8210), two(0xffc0, 0xe3f0), "T3&sQ8" },
+{"ptestr", two(0xf000, 0x8310), two(0xffc0, 0xe310), "T3&sQ8A9" },
+{"ptestr", two(0xf000, 0x8208), two(0xffc0, 0xe3f8), "D3&sQ8" },
+{"ptestr", two(0xf000, 0x8308), two(0xffc0, 0xe318), "D3&sQ8A9" },
+{"ptestr", two(0xf000, 0x8200), two(0xffc0, 0xe3fe), "f3&sQ8" },
+{"ptestr", two(0xf000, 0x8300), two(0xffc0, 0xe31e), "f3&sQ8A9" },
+
+{"ptestw", two(0xf000, 0x8010), two(0xffc0, 0xe3f0), "T3&sQ8" },
+{"ptestw", two(0xf000, 0x8110), two(0xffc0, 0xe310), "T3&sQ8A9" },
+{"ptestw", two(0xf000, 0x8008), two(0xffc0, 0xe3f8), "D3&sQ8" },
+{"ptestw", two(0xf000, 0x8108), two(0xffc0, 0xe318), "D3&sQ8A9" },
+{"ptestw", two(0xf000, 0x8000), two(0xffc0, 0xe3fe), "f3&sQ8" },
+{"ptestw", two(0xf000, 0x8100), two(0xffc0, 0xe31e), "f3&sQ8A9" },
+
+{"ptrapacw", two(0xf07a, 0x0007), two(0xffff, 0xffff), "#w"},
+{"ptrapacl", two(0xf07b, 0x0007), two(0xffff, 0xffff), "#l"},
+{"ptrapac", two(0xf07c, 0x0007), two(0xffff, 0xffff), ""},
+
+{"ptrapasw", two(0xf07a, 0x0006), two(0xffff, 0xffff), "#w"},
+{"ptrapasl", two(0xf07b, 0x0006), two(0xffff, 0xffff), "#l"},
+{"ptrapas", two(0xf07c, 0x0006), two(0xffff, 0xffff), ""},
+
+{"ptrapbcw", two(0xf07a, 0x0001), two(0xffff, 0xffff), "#w"},
+{"ptrapbcl", two(0xf07b, 0x0001), two(0xffff, 0xffff), "#l"},
+{"ptrapbc", two(0xf07c, 0x0001), two(0xffff, 0xffff), ""},
+
+{"ptrapbsw", two(0xf07a, 0x0000), two(0xffff, 0xffff), "#w"},
+{"ptrapbsl", two(0xf07b, 0x0000), two(0xffff, 0xffff), "#l"},
+{"ptrapbs", two(0xf07c, 0x0000), two(0xffff, 0xffff), ""},
+
+{"ptrapccw", two(0xf07a, 0x000f), two(0xffff, 0xffff), "#w"},
+{"ptrapccl", two(0xf07b, 0x000f), two(0xffff, 0xffff), "#l"},
+{"ptrapcc", two(0xf07c, 0x000f), two(0xffff, 0xffff), ""},
+
+{"ptrapcsw", two(0xf07a, 0x000e), two(0xffff, 0xffff), "#w"},
+{"ptrapcsl", two(0xf07b, 0x000e), two(0xffff, 0xffff), "#l"},
+{"ptrapcs", two(0xf07c, 0x000e), two(0xffff, 0xffff), ""},
+
+{"ptrapgcw", two(0xf07a, 0x000d), two(0xffff, 0xffff), "#w"},
+{"ptrapgcl", two(0xf07b, 0x000d), two(0xffff, 0xffff), "#l"},
+{"ptrapgc", two(0xf07c, 0x000d), two(0xffff, 0xffff), ""},
+
+{"ptrapgsw", two(0xf07a, 0x000c), two(0xffff, 0xffff), "#w"},
+{"ptrapgsl", two(0xf07b, 0x000c), two(0xffff, 0xffff), "#l"},
+{"ptrapgs", two(0xf07c, 0x000c), two(0xffff, 0xffff), ""},
+
+{"ptrapicw", two(0xf07a, 0x000b), two(0xffff, 0xffff), "#w"},
+{"ptrapicl", two(0xf07b, 0x000b), two(0xffff, 0xffff), "#l"},
+{"ptrapic", two(0xf07c, 0x000b), two(0xffff, 0xffff), ""},
+
+{"ptrapisw", two(0xf07a, 0x000a), two(0xffff, 0xffff), "#w"},
+{"ptrapisl", two(0xf07b, 0x000a), two(0xffff, 0xffff), "#l"},
+{"ptrapis", two(0xf07c, 0x000a), two(0xffff, 0xffff), ""},
+
+{"ptraplcw", two(0xf07a, 0x0003), two(0xffff, 0xffff), "#w"},
+{"ptraplcl", two(0xf07b, 0x0003), two(0xffff, 0xffff), "#l"},
+{"ptraplc", two(0xf07c, 0x0003), two(0xffff, 0xffff), ""},
+
+{"ptraplsw", two(0xf07a, 0x0002), two(0xffff, 0xffff), "#w"},
+{"ptraplsl", two(0xf07b, 0x0002), two(0xffff, 0xffff), "#l"},
+{"ptrapls", two(0xf07c, 0x0002), two(0xffff, 0xffff), ""},
+
+{"ptrapscw", two(0xf07a, 0x0005), two(0xffff, 0xffff), "#w"},
+{"ptrapscl", two(0xf07b, 0x0005), two(0xffff, 0xffff), "#l"},
+{"ptrapsc", two(0xf07c, 0x0005), two(0xffff, 0xffff), ""},
+
+{"ptrapssw", two(0xf07a, 0x0004), two(0xffff, 0xffff), "#w"},
+{"ptrapssl", two(0xf07b, 0x0004), two(0xffff, 0xffff), "#l"},
+{"ptrapss", two(0xf07c, 0x0004), two(0xffff, 0xffff), ""},
+
+{"ptrapwcw", two(0xf07a, 0x0009), two(0xffff, 0xffff), "#w"},
+{"ptrapwcl", two(0xf07b, 0x0009), two(0xffff, 0xffff), "#l"},
+{"ptrapwc", two(0xf07c, 0x0009), two(0xffff, 0xffff), ""},
+
+{"ptrapwsw", two(0xf07a, 0x0008), two(0xffff, 0xffff), "#w"},
+{"ptrapwsl", two(0xf07b, 0x0008), two(0xffff, 0xffff), "#l"},
+{"ptrapws", two(0xf07c, 0x0008), two(0xffff, 0xffff), ""},
+
+{"pvalid", two(0xf000, 0x2800), two(0xffc0, 0xffff), "Vs&s"},
+{"pvalid", two(0xf000, 0x2c00), two(0xffc0, 0xfff8), "A3&s" },
+
+#endif /* m68851 */
diff --git a/x/binutils/gas/config/tc-mips.c b/x/binutils/gas/config/tc-mips.c
new file mode 100644
index 0000000..7b6cee8
--- /dev/null
+++ b/x/binutils/gas/config/tc-mips.c
@@ -0,0 +1,14431 @@
+/* tc-mips.c -- assemble code for a MIPS chip.
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+ 2003, 2004 Free Software Foundation, Inc.
+ Contributed by the OSF and Ralph Campbell.
+ Written by Keith Knowles and Ralph Campbell, working independently.
+ Modified for ECOFF and R4000 support by Ian Lance Taylor of Cygnus
+ Support.
+
+ This file is part of GAS.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+#include "config.h"
+#include "subsegs.h"
+#include "safe-ctype.h"
+
+#include <stdarg.h>
+
+#include "opcode/mips.h"
+#include "itbl-ops.h"
+#include "dwarf2dbg.h"
+
+#ifdef DEBUG
+#define DBG(x) printf x
+#else
+#define DBG(x)
+#endif
+
+#ifdef OBJ_MAYBE_ELF
+/* Clean up namespace so we can include obj-elf.h too. */
+static int mips_output_flavor (void);
+static int mips_output_flavor (void) { return OUTPUT_FLAVOR; }
+#undef OBJ_PROCESS_STAB
+#undef OUTPUT_FLAVOR
+#undef S_GET_ALIGN
+#undef S_GET_SIZE
+#undef S_SET_ALIGN
+#undef S_SET_SIZE
+#undef obj_frob_file
+#undef obj_frob_file_after_relocs
+#undef obj_frob_symbol
+#undef obj_pop_insert
+#undef obj_sec_sym_ok_for_reloc
+#undef OBJ_COPY_SYMBOL_ATTRIBUTES
+
+#include "obj-elf.h"
+/* Fix any of them that we actually care about. */
+#undef OUTPUT_FLAVOR
+#define OUTPUT_FLAVOR mips_output_flavor()
+#endif
+
+#if defined (OBJ_ELF)
+#include "elf/mips.h"
+#endif
+
+#ifndef ECOFF_DEBUGGING
+#define NO_ECOFF_DEBUGGING
+#define ECOFF_DEBUGGING 0
+#endif
+
+int mips_flag_mdebug = -1;
+
+/* Control generation of .pdr sections. Off by default on IRIX: the native
+ linker doesn't know about and discards them, but relocations against them
+ remain, leading to rld crashes. */
+#ifdef TE_IRIX
+int mips_flag_pdr = FALSE;
+#else
+int mips_flag_pdr = TRUE;
+#endif
+
+#include "ecoff.h"
+
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+static char *mips_regmask_frag;
+#endif
+
+#define ZERO 0
+#define AT 1
+#define TREG 24
+#define PIC_CALL_REG 25
+#define KT0 26
+#define KT1 27
+#define GP 28
+#define SP 29
+#define FP 30
+#define RA 31
+
+#define ILLEGAL_REG (32)
+
+/* Allow override of standard little-endian ECOFF format. */
+
+#ifndef ECOFF_LITTLE_FORMAT
+#define ECOFF_LITTLE_FORMAT "ecoff-littlemips"
+#endif
+
+extern int target_big_endian;
+
+/* The name of the readonly data section. */
+#define RDATA_SECTION_NAME (OUTPUT_FLAVOR == bfd_target_aout_flavour \
+ ? ".data" \
+ : OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
+ ? ".rdata" \
+ : OUTPUT_FLAVOR == bfd_target_coff_flavour \
+ ? ".rdata" \
+ : OUTPUT_FLAVOR == bfd_target_elf_flavour \
+ ? ".rodata" \
+ : (abort (), ""))
+
+/* The ABI to use. */
+enum mips_abi_level
+{
+ NO_ABI = 0,
+ O32_ABI,
+ O64_ABI,
+ N32_ABI,
+ N64_ABI,
+ EABI_ABI
+};
+
+/* MIPS ABI we are using for this output file. */
+static enum mips_abi_level mips_abi = NO_ABI;
+
+/* Whether or not we have code that can call pic code. */
+int mips_abicalls = FALSE;
+
+/* This is the set of options which may be modified by the .set
+ pseudo-op. We use a struct so that .set push and .set pop are more
+ reliable. */
+
+struct mips_set_options
+{
+ /* MIPS ISA (Instruction Set Architecture) level. This is set to -1
+ if it has not been initialized. Changed by `.set mipsN', and the
+ -mipsN command line option, and the default CPU. */
+ int isa;
+ /* Enabled Application Specific Extensions (ASEs). These are set to -1
+ if they have not been initialized. Changed by `.set <asename>', by
+ command line options, and based on the default architecture. */
+ int ase_mips3d;
+ int ase_mdmx;
+ /* Whether we are assembling for the mips16 processor. 0 if we are
+ not, 1 if we are, and -1 if the value has not been initialized.
+ Changed by `.set mips16' and `.set nomips16', and the -mips16 and
+ -nomips16 command line options, and the default CPU. */
+ int mips16;
+ /* Non-zero if we should not reorder instructions. Changed by `.set
+ reorder' and `.set noreorder'. */
+ int noreorder;
+ /* Non-zero if we should not permit the $at ($1) register to be used
+ in instructions. Changed by `.set at' and `.set noat'. */
+ int noat;
+ /* Non-zero if we should warn when a macro instruction expands into
+ more than one machine instruction. Changed by `.set nomacro' and
+ `.set macro'. */
+ int warn_about_macros;
+ /* Non-zero if we should not move instructions. Changed by `.set
+ move', `.set volatile', `.set nomove', and `.set novolatile'. */
+ int nomove;
+ /* Non-zero if we should not optimize branches by moving the target
+ of the branch into the delay slot. Actually, we don't perform
+ this optimization anyhow. Changed by `.set bopt' and `.set
+ nobopt'. */
+ int nobopt;
+ /* Non-zero if we should not autoextend mips16 instructions.
+ Changed by `.set autoextend' and `.set noautoextend'. */
+ int noautoextend;
+ /* Restrict general purpose registers and floating point registers
+ to 32 bit. This is initially determined when -mgp32 or -mfp32
+ is passed but can changed if the assembler code uses .set mipsN. */
+ int gp32;
+ int fp32;
+ /* MIPS architecture (CPU) type. Changed by .set arch=FOO, the -march
+ command line option, and the default CPU. */
+ int arch;
+};
+
+/* True if -mgp32 was passed. */
+static int file_mips_gp32 = -1;
+
+/* True if -mfp32 was passed. */
+static int file_mips_fp32 = -1;
+
+/* This is the struct we use to hold the current set of options. Note
+ that we must set the isa field to ISA_UNKNOWN and the ASE fields to
+ -1 to indicate that they have not been initialized. */
+
+static struct mips_set_options mips_opts =
+{
+ ISA_UNKNOWN, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, CPU_UNKNOWN
+};
+
+/* These variables are filled in with the masks of registers used.
+ The object format code reads them and puts them in the appropriate
+ place. */
+unsigned long mips_gprmask;
+unsigned long mips_cprmask[4];
+
+/* MIPS ISA we are using for this output file. */
+static int file_mips_isa = ISA_UNKNOWN;
+
+/* True if -mips16 was passed or implied by arguments passed on the
+ command line (e.g., by -march). */
+static int file_ase_mips16;
+
+/* True if -mips3d was passed or implied by arguments passed on the
+ command line (e.g., by -march). */
+static int file_ase_mips3d;
+
+/* True if -mdmx was passed or implied by arguments passed on the
+ command line (e.g., by -march). */
+static int file_ase_mdmx;
+
+/* The argument of the -march= flag. The architecture we are assembling. */
+static int file_mips_arch = CPU_UNKNOWN;
+static const char *mips_arch_string;
+
+/* The argument of the -mtune= flag. The architecture for which we
+ are optimizing. */
+static int mips_tune = CPU_UNKNOWN;
+static const char *mips_tune_string;
+
+/* True when generating 32-bit code for a 64-bit processor. */
+static int mips_32bitmode = 0;
+
+/* True if the given ABI requires 32-bit registers. */
+#define ABI_NEEDS_32BIT_REGS(ABI) ((ABI) == O32_ABI)
+
+/* Likewise 64-bit registers. */
+#define ABI_NEEDS_64BIT_REGS(ABI) \
+ ((ABI) == N32_ABI \
+ || (ABI) == N64_ABI \
+ || (ABI) == O64_ABI)
+
+/* Return true if ISA supports 64 bit gp register instructions. */
+#define ISA_HAS_64BIT_REGS(ISA) ( \
+ (ISA) == ISA_MIPS3 \
+ || (ISA) == ISA_MIPS4 \
+ || (ISA) == ISA_MIPS5 \
+ || (ISA) == ISA_MIPS64 \
+ || (ISA) == ISA_MIPS64R2 \
+ )
+
+/* Return true if ISA supports 64-bit right rotate (dror et al.)
+ instructions. */
+#define ISA_HAS_DROR(ISA) ( \
+ (ISA) == ISA_MIPS64R2 \
+ )
+
+/* Return true if ISA supports 32-bit right rotate (ror et al.)
+ instructions. */
+#define ISA_HAS_ROR(ISA) ( \
+ (ISA) == ISA_MIPS32R2 \
+ || (ISA) == ISA_MIPS64R2 \
+ )
+
+#define HAVE_32BIT_GPRS \
+ (mips_opts.gp32 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
+
+#define HAVE_32BIT_FPRS \
+ (mips_opts.fp32 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
+
+#define HAVE_64BIT_GPRS (! HAVE_32BIT_GPRS)
+#define HAVE_64BIT_FPRS (! HAVE_32BIT_FPRS)
+
+#define HAVE_NEWABI (mips_abi == N32_ABI || mips_abi == N64_ABI)
+
+#define HAVE_64BIT_OBJECTS (mips_abi == N64_ABI)
+
+/* We can only have 64bit addresses if the object file format
+ supports it. */
+#define HAVE_32BIT_ADDRESSES \
+ (HAVE_32BIT_GPRS \
+ || ((bfd_arch_bits_per_address (stdoutput) == 32 \
+ || ! HAVE_64BIT_OBJECTS) \
+ && mips_pic != EMBEDDED_PIC))
+
+#define HAVE_64BIT_ADDRESSES (! HAVE_32BIT_ADDRESSES)
+
+/* Addresses are loaded in different ways, depending on the address size
+ in use. The n32 ABI Documentation also mandates the use of additions
+ with overflow checking, but existing implementations don't follow it. */
+#define ADDRESS_ADD_INSN \
+ (HAVE_32BIT_ADDRESSES ? "addu" : "daddu")
+
+#define ADDRESS_ADDI_INSN \
+ (HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu")
+
+#define ADDRESS_LOAD_INSN \
+ (HAVE_32BIT_ADDRESSES ? "lw" : "ld")
+
+#define ADDRESS_STORE_INSN \
+ (HAVE_32BIT_ADDRESSES ? "sw" : "sd")
+
+/* Return true if the given CPU supports the MIPS16 ASE. */
+#define CPU_HAS_MIPS16(cpu) \
+ (strncmp (TARGET_CPU, "mips16", sizeof ("mips16") - 1) == 0 \
+ || strncmp (TARGET_CANONICAL, "mips-lsi-elf", sizeof ("mips-lsi-elf") - 1) == 0)
+
+/* Return true if the given CPU supports the MIPS3D ASE. */
+#define CPU_HAS_MIPS3D(cpu) ((cpu) == CPU_SB1 \
+ )
+
+/* Return true if the given CPU supports the MDMX ASE. */
+#define CPU_HAS_MDMX(cpu) (FALSE \
+ )
+
+/* True if CPU has a dror instruction. */
+#define CPU_HAS_DROR(CPU) ((CPU) == CPU_VR5400 || (CPU) == CPU_VR5500)
+
+/* True if CPU has a ror instruction. */
+#define CPU_HAS_ROR(CPU) CPU_HAS_DROR (CPU)
+
+/* True if mflo and mfhi can be immediately followed by instructions
+ which write to the HI and LO registers.
+
+ According to MIPS specifications, MIPS ISAs I, II, and III need
+ (at least) two instructions between the reads of HI/LO and
+ instructions which write them, and later ISAs do not. Contradicting
+ the MIPS specifications, some MIPS IV processor user manuals (e.g.
+ the UM for the NEC Vr5000) document needing the instructions between
+ HI/LO reads and writes, as well. Therefore, we declare only MIPS32,
+ MIPS64 and later ISAs to have the interlocks, plus any specific
+ earlier-ISA CPUs for which CPU documentation declares that the
+ instructions are really interlocked. */
+#define hilo_interlocks \
+ (mips_opts.isa == ISA_MIPS32 \
+ || mips_opts.isa == ISA_MIPS32R2 \
+ || mips_opts.isa == ISA_MIPS64 \
+ || mips_opts.isa == ISA_MIPS64R2 \
+ || mips_opts.arch == CPU_R4010 \
+ || mips_opts.arch == CPU_R10000 \
+ || mips_opts.arch == CPU_R12000 \
+ || mips_opts.arch == CPU_RM7000 \
+ || mips_opts.arch == CPU_SB1 \
+ || mips_opts.arch == CPU_VR5500 \
+ )
+
+/* Whether the processor uses hardware interlocks to protect reads
+ from the GPRs after they are loaded from memory, and thus does not
+ require nops to be inserted. This applies to instructions marked
+ INSN_LOAD_MEMORY_DELAY. These nops are only required at MIPS ISA
+ level I. */
+#define gpr_interlocks \
+ (mips_opts.isa != ISA_MIPS1 \
+ || mips_opts.arch == CPU_VR5400 \
+ || mips_opts.arch == CPU_VR5500 \
+ || mips_opts.arch == CPU_R3900)
+
+/* Whether the processor uses hardware interlocks to avoid delays
+ required by coprocessor instructions, and thus does not require
+ nops to be inserted. This applies to instructions marked
+ INSN_LOAD_COPROC_DELAY, INSN_COPROC_MOVE_DELAY, and to delays
+ between instructions marked INSN_WRITE_COND_CODE and ones marked
+ INSN_READ_COND_CODE. These nops are only required at MIPS ISA
+ levels I, II, and III. */
+/* Itbl support may require additional care here. */
+#define cop_interlocks \
+ ((mips_opts.isa != ISA_MIPS1 \
+ && mips_opts.isa != ISA_MIPS2 \
+ && mips_opts.isa != ISA_MIPS3) \
+ || mips_opts.arch == CPU_R4300 \
+ || mips_opts.arch == CPU_VR5400 \
+ || mips_opts.arch == CPU_VR5500 \
+ || mips_opts.arch == CPU_SB1 \
+ )
+
+/* Whether the processor uses hardware interlocks to protect reads
+ from coprocessor registers after they are loaded from memory, and
+ thus does not require nops to be inserted. This applies to
+ instructions marked INSN_COPROC_MEMORY_DELAY. These nops are only
+ requires at MIPS ISA level I. */
+#define cop_mem_interlocks (mips_opts.isa != ISA_MIPS1)
+
+/* Is this a mfhi or mflo instruction? */
+#define MF_HILO_INSN(PINFO) \
+ ((PINFO & INSN_READ_HI) || (PINFO & INSN_READ_LO))
+
+/* MIPS PIC level. */
+
+enum mips_pic_level mips_pic;
+
+/* 1 if we should generate 32 bit offsets from the $gp register in
+ SVR4_PIC mode. Currently has no meaning in other modes. */
+static int mips_big_got = 0;
+
+/* 1 if trap instructions should used for overflow rather than break
+ instructions. */
+static int mips_trap = 0;
+
+/* 1 if double width floating point constants should not be constructed
+ by assembling two single width halves into two single width floating
+ point registers which just happen to alias the double width destination
+ register. On some architectures this aliasing can be disabled by a bit
+ in the status register, and the setting of this bit cannot be determined
+ automatically at assemble time. */
+static int mips_disable_float_construction;
+
+/* Non-zero if any .set noreorder directives were used. */
+
+static int mips_any_noreorder;
+
+/* Non-zero if nops should be inserted when the register referenced in
+ an mfhi/mflo instruction is read in the next two instructions. */
+static int mips_7000_hilo_fix;
+
+/* The size of the small data section. */
+static unsigned int g_switch_value = 8;
+/* Whether the -G option was used. */
+static int g_switch_seen = 0;
+
+#define N_RMASK 0xc4
+#define N_VFP 0xd4
+
+/* If we can determine in advance that GP optimization won't be
+ possible, we can skip the relaxation stuff that tries to produce
+ GP-relative references. This makes delay slot optimization work
+ better.
+
+ This function can only provide a guess, but it seems to work for
+ gcc output. It needs to guess right for gcc, otherwise gcc
+ will put what it thinks is a GP-relative instruction in a branch
+ delay slot.
+
+ I don't know if a fix is needed for the SVR4_PIC mode. I've only
+ fixed it for the non-PIC mode. KR 95/04/07 */
+static int nopic_need_relax (symbolS *, int);
+
+/* handle of the OPCODE hash table */
+static struct hash_control *op_hash = NULL;
+
+/* The opcode hash table we use for the mips16. */
+static struct hash_control *mips16_op_hash = NULL;
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful */
+const char comment_chars[] = "#";
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output */
+/* Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output. */
+/* Also note that C style comments are always supported. */
+const char line_comment_chars[] = "#";
+
+/* This array holds machine specific line separator characters. */
+const char line_separator_chars[] = ";";
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
+ changed in read.c . Ideally it shouldn't have to know about it at all,
+ but nothing is ideal around here.
+ */
+
+static char *insn_error;
+
+static int auto_align = 1;
+
+/* When outputting SVR4 PIC code, the assembler needs to know the
+ offset in the stack frame from which to restore the $gp register.
+ This is set by the .cprestore pseudo-op, and saved in this
+ variable. */
+static offsetT mips_cprestore_offset = -1;
+
+/* Similar for NewABI PIC code, where $gp is callee-saved. NewABI has some
+ more optimizations, it can use a register value instead of a memory-saved
+ offset and even an other register than $gp as global pointer. */
+static offsetT mips_cpreturn_offset = -1;
+static int mips_cpreturn_register = -1;
+static int mips_gp_register = GP;
+static int mips_gprel_offset = 0;
+
+/* Whether mips_cprestore_offset has been set in the current function
+ (or whether it has already been warned about, if not). */
+static int mips_cprestore_valid = 0;
+
+/* This is the register which holds the stack frame, as set by the
+ .frame pseudo-op. This is needed to implement .cprestore. */
+static int mips_frame_reg = SP;
+
+/* Whether mips_frame_reg has been set in the current function
+ (or whether it has already been warned about, if not). */
+static int mips_frame_reg_valid = 0;
+
+/* To output NOP instructions correctly, we need to keep information
+ about the previous two instructions. */
+
+/* Whether we are optimizing. The default value of 2 means to remove
+ unneeded NOPs and swap branch instructions when possible. A value
+ of 1 means to not swap branches. A value of 0 means to always
+ insert NOPs. */
+static int mips_optimize = 2;
+
+/* Debugging level. -g sets this to 2. -gN sets this to N. -g0 is
+ equivalent to seeing no -g option at all. */
+static int mips_debug = 0;
+
+/* The previous instruction. */
+static struct mips_cl_insn prev_insn;
+
+/* The instruction before prev_insn. */
+static struct mips_cl_insn prev_prev_insn;
+
+/* If we don't want information for prev_insn or prev_prev_insn, we
+ point the insn_mo field at this dummy integer. */
+static const struct mips_opcode dummy_opcode = { NULL, NULL, 0, 0, 0, 0 };
+
+/* Non-zero if prev_insn is valid. */
+static int prev_insn_valid;
+
+/* The frag for the previous instruction. */
+static struct frag *prev_insn_frag;
+
+/* The offset into prev_insn_frag for the previous instruction. */
+static long prev_insn_where;
+
+/* The reloc type for the previous instruction, if any. */
+static bfd_reloc_code_real_type prev_insn_reloc_type[3];
+
+/* The reloc for the previous instruction, if any. */
+static fixS *prev_insn_fixp[3];
+
+/* Non-zero if the previous instruction was in a delay slot. */
+static int prev_insn_is_delay_slot;
+
+/* Non-zero if the previous instruction was in a .set noreorder. */
+static int prev_insn_unreordered;
+
+/* Non-zero if the previous instruction uses an extend opcode (if
+ mips16). */
+static int prev_insn_extended;
+
+/* Non-zero if the previous previous instruction was in a .set
+ noreorder. */
+static int prev_prev_insn_unreordered;
+
+/* If this is set, it points to a frag holding nop instructions which
+ were inserted before the start of a noreorder section. If those
+ nops turn out to be unnecessary, the size of the frag can be
+ decreased. */
+static fragS *prev_nop_frag;
+
+/* The number of nop instructions we created in prev_nop_frag. */
+static int prev_nop_frag_holds;
+
+/* The number of nop instructions that we know we need in
+ prev_nop_frag. */
+static int prev_nop_frag_required;
+
+/* The number of instructions we've seen since prev_nop_frag. */
+static int prev_nop_frag_since;
+
+/* For ECOFF and ELF, relocations against symbols are done in two
+ parts, with a HI relocation and a LO relocation. Each relocation
+ has only 16 bits of space to store an addend. This means that in
+ order for the linker to handle carries correctly, it must be able
+ to locate both the HI and the LO relocation. This means that the
+ relocations must appear in order in the relocation table.
+
+ In order to implement this, we keep track of each unmatched HI
+ relocation. We then sort them so that they immediately precede the
+ corresponding LO relocation. */
+
+struct mips_hi_fixup
+{
+ /* Next HI fixup. */
+ struct mips_hi_fixup *next;
+ /* This fixup. */
+ fixS *fixp;
+ /* The section this fixup is in. */
+ segT seg;
+};
+
+/* The list of unmatched HI relocs. */
+
+static struct mips_hi_fixup *mips_hi_fixup_list;
+
+/* The frag containing the last explicit relocation operator.
+ Null if explicit relocations have not been used. */
+
+static fragS *prev_reloc_op_frag;
+
+/* Map normal MIPS register numbers to mips16 register numbers. */
+
+#define X ILLEGAL_REG
+static const int mips32_to_16_reg_map[] =
+{
+ X, X, 2, 3, 4, 5, 6, 7,
+ X, X, X, X, X, X, X, X,
+ 0, 1, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X
+};
+#undef X
+
+/* Map mips16 register numbers to normal MIPS register numbers. */
+
+static const unsigned int mips16_to_32_reg_map[] =
+{
+ 16, 17, 2, 3, 4, 5, 6, 7
+};
+
+static int mips_fix_vr4120;
+
+/* We don't relax branches by default, since this causes us to expand
+ `la .l2 - .l1' if there's a branch between .l1 and .l2, because we
+ fail to compute the offset before expanding the macro to the most
+ efficient expansion. */
+
+static int mips_relax_branch;
+
+/* The expansion of many macros depends on the type of symbol that
+ they refer to. For example, when generating position-dependent code,
+ a macro that refers to a symbol may have two different expansions,
+ one which uses GP-relative addresses and one which uses absolute
+ addresses. When generating SVR4-style PIC, a macro may have
+ different expansions for local and global symbols.
+
+ We handle these situations by generating both sequences and putting
+ them in variant frags. In position-dependent code, the first sequence
+ will be the GP-relative one and the second sequence will be the
+ absolute one. In SVR4 PIC, the first sequence will be for global
+ symbols and the second will be for local symbols.
+
+ The frag's "subtype" is RELAX_ENCODE (FIRST, SECOND), where FIRST and
+ SECOND are the lengths of the two sequences in bytes. These fields
+ can be extracted using RELAX_FIRST() and RELAX_SECOND(). In addition,
+ the subtype has the following flags:
+
+ RELAX_USE_SECOND
+ Set if it has been decided that we should use the second
+ sequence instead of the first.
+
+ RELAX_SECOND_LONGER
+ Set in the first variant frag if the macro's second implementation
+ is longer than its first. This refers to the macro as a whole,
+ not an individual relaxation.
+
+ RELAX_NOMACRO
+ Set in the first variant frag if the macro appeared in a .set nomacro
+ block and if one alternative requires a warning but the other does not.
+
+ RELAX_DELAY_SLOT
+ Like RELAX_NOMACRO, but indicates that the macro appears in a branch
+ delay slot.
+
+ The frag's "opcode" points to the first fixup for relaxable code.
+
+ Relaxable macros are generated using a sequence such as:
+
+ relax_start (SYMBOL);
+ ... generate first expansion ...
+ relax_switch ();
+ ... generate second expansion ...
+ relax_end ();
+
+ The code and fixups for the unwanted alternative are discarded
+ by md_convert_frag. */
+#define RELAX_ENCODE(FIRST, SECOND) (((FIRST) << 8) | (SECOND))
+
+#define RELAX_FIRST(X) (((X) >> 8) & 0xff)
+#define RELAX_SECOND(X) ((X) & 0xff)
+#define RELAX_USE_SECOND 0x10000
+#define RELAX_SECOND_LONGER 0x20000
+#define RELAX_NOMACRO 0x40000
+#define RELAX_DELAY_SLOT 0x80000
+
+/* Branch without likely bit. If label is out of range, we turn:
+
+ beq reg1, reg2, label
+ delay slot
+
+ into
+
+ bne reg1, reg2, 0f
+ nop
+ j label
+ 0: delay slot
+
+ with the following opcode replacements:
+
+ beq <-> bne
+ blez <-> bgtz
+ bltz <-> bgez
+ bc1f <-> bc1t
+
+ bltzal <-> bgezal (with jal label instead of j label)
+
+ Even though keeping the delay slot instruction in the delay slot of
+ the branch would be more efficient, it would be very tricky to do
+ correctly, because we'd have to introduce a variable frag *after*
+ the delay slot instruction, and expand that instead. Let's do it
+ the easy way for now, even if the branch-not-taken case now costs
+ one additional instruction. Out-of-range branches are not supposed
+ to be common, anyway.
+
+ Branch likely. If label is out of range, we turn:
+
+ beql reg1, reg2, label
+ delay slot (annulled if branch not taken)
+
+ into
+
+ beql reg1, reg2, 1f
+ nop
+ beql $0, $0, 2f
+ nop
+ 1: j[al] label
+ delay slot (executed only if branch taken)
+ 2:
+
+ It would be possible to generate a shorter sequence by losing the
+ likely bit, generating something like:
+
+ bne reg1, reg2, 0f
+ nop
+ j[al] label
+ delay slot (executed only if branch taken)
+ 0:
+
+ beql -> bne
+ bnel -> beq
+ blezl -> bgtz
+ bgtzl -> blez
+ bltzl -> bgez
+ bgezl -> bltz
+ bc1fl -> bc1t
+ bc1tl -> bc1f
+
+ bltzall -> bgezal (with jal label instead of j label)
+ bgezall -> bltzal (ditto)
+
+
+ but it's not clear that it would actually improve performance. */
+#define RELAX_BRANCH_ENCODE(uncond, likely, link, toofar) \
+ ((relax_substateT) \
+ (0xc0000000 \
+ | ((toofar) ? 1 : 0) \
+ | ((link) ? 2 : 0) \
+ | ((likely) ? 4 : 0) \
+ | ((uncond) ? 8 : 0)))
+#define RELAX_BRANCH_P(i) (((i) & 0xf0000000) == 0xc0000000)
+#define RELAX_BRANCH_UNCOND(i) (((i) & 8) != 0)
+#define RELAX_BRANCH_LIKELY(i) (((i) & 4) != 0)
+#define RELAX_BRANCH_LINK(i) (((i) & 2) != 0)
+#define RELAX_BRANCH_TOOFAR(i) (((i) & 1) != 0)
+
+/* For mips16 code, we use an entirely different form of relaxation.
+ mips16 supports two versions of most instructions which take
+ immediate values: a small one which takes some small value, and a
+ larger one which takes a 16 bit value. Since branches also follow
+ this pattern, relaxing these values is required.
+
+ We can assemble both mips16 and normal MIPS code in a single
+ object. Therefore, we need to support this type of relaxation at
+ the same time that we support the relaxation described above. We
+ use the high bit of the subtype field to distinguish these cases.
+
+ The information we store for this type of relaxation is the
+ argument code found in the opcode file for this relocation, whether
+ the user explicitly requested a small or extended form, and whether
+ the relocation is in a jump or jal delay slot. That tells us the
+ size of the value, and how it should be stored. We also store
+ whether the fragment is considered to be extended or not. We also
+ store whether this is known to be a branch to a different section,
+ whether we have tried to relax this frag yet, and whether we have
+ ever extended a PC relative fragment because of a shift count. */
+#define RELAX_MIPS16_ENCODE(type, small, ext, dslot, jal_dslot) \
+ (0x80000000 \
+ | ((type) & 0xff) \
+ | ((small) ? 0x100 : 0) \
+ | ((ext) ? 0x200 : 0) \
+ | ((dslot) ? 0x400 : 0) \
+ | ((jal_dslot) ? 0x800 : 0))
+#define RELAX_MIPS16_P(i) (((i) & 0xc0000000) == 0x80000000)
+#define RELAX_MIPS16_TYPE(i) ((i) & 0xff)
+#define RELAX_MIPS16_USER_SMALL(i) (((i) & 0x100) != 0)
+#define RELAX_MIPS16_USER_EXT(i) (((i) & 0x200) != 0)
+#define RELAX_MIPS16_DSLOT(i) (((i) & 0x400) != 0)
+#define RELAX_MIPS16_JAL_DSLOT(i) (((i) & 0x800) != 0)
+#define RELAX_MIPS16_EXTENDED(i) (((i) & 0x1000) != 0)
+#define RELAX_MIPS16_MARK_EXTENDED(i) ((i) | 0x1000)
+#define RELAX_MIPS16_CLEAR_EXTENDED(i) ((i) &~ 0x1000)
+#define RELAX_MIPS16_LONG_BRANCH(i) (((i) & 0x2000) != 0)
+#define RELAX_MIPS16_MARK_LONG_BRANCH(i) ((i) | 0x2000)
+#define RELAX_MIPS16_CLEAR_LONG_BRANCH(i) ((i) &~ 0x2000)
+
+/* Is the given value a sign-extended 32-bit value? */
+#define IS_SEXT_32BIT_NUM(x) \
+ (((x) &~ (offsetT) 0x7fffffff) == 0 \
+ || (((x) &~ (offsetT) 0x7fffffff) == ~ (offsetT) 0x7fffffff))
+
+/* Is the given value a sign-extended 16-bit value? */
+#define IS_SEXT_16BIT_NUM(x) \
+ (((x) &~ (offsetT) 0x7fff) == 0 \
+ || (((x) &~ (offsetT) 0x7fff) == ~ (offsetT) 0x7fff))
+
+
+/* Global variables used when generating relaxable macros. See the
+ comment above RELAX_ENCODE for more details about how relaxation
+ is used. */
+static struct {
+ /* 0 if we're not emitting a relaxable macro.
+ 1 if we're emitting the first of the two relaxation alternatives.
+ 2 if we're emitting the second alternative. */
+ int sequence;
+
+ /* The first relaxable fixup in the current frag. (In other words,
+ the first fixup that refers to relaxable code.) */
+ fixS *first_fixup;
+
+ /* sizes[0] says how many bytes of the first alternative are stored in
+ the current frag. Likewise sizes[1] for the second alternative. */
+ unsigned int sizes[2];
+
+ /* The symbol on which the choice of sequence depends. */
+ symbolS *symbol;
+} mips_relax;
+
+/* Global variables used to decide whether a macro needs a warning. */
+static struct {
+ /* True if the macro is in a branch delay slot. */
+ bfd_boolean delay_slot_p;
+
+ /* For relaxable macros, sizes[0] is the length of the first alternative
+ in bytes and sizes[1] is the length of the second alternative.
+ For non-relaxable macros, both elements give the length of the
+ macro in bytes. */
+ unsigned int sizes[2];
+
+ /* The first variant frag for this macro. */
+ fragS *first_frag;
+} mips_macro_warning;
+
+/* Prototypes for static functions. */
+
+#define internalError() \
+ as_fatal (_("internal Error, line %d, %s"), __LINE__, __FILE__)
+
+enum mips_regclass { MIPS_GR_REG, MIPS_FP_REG, MIPS16_REG };
+
+static void append_insn
+ (struct mips_cl_insn *ip, expressionS *p, bfd_reloc_code_real_type *r);
+static void mips_no_prev_insn (int);
+static void mips16_macro_build
+ (expressionS *, const char *, const char *, va_list);
+static void load_register (int, expressionS *, int);
+static void macro_start (void);
+static void macro_end (void);
+static void macro (struct mips_cl_insn * ip);
+static void mips16_macro (struct mips_cl_insn * ip);
+#ifdef LOSING_COMPILER
+static void macro2 (struct mips_cl_insn * ip);
+#endif
+static void mips_ip (char *str, struct mips_cl_insn * ip);
+static void mips16_ip (char *str, struct mips_cl_insn * ip);
+static void mips16_immed
+ (char *, unsigned int, int, offsetT, bfd_boolean, bfd_boolean, bfd_boolean,
+ unsigned long *, bfd_boolean *, unsigned short *);
+static size_t my_getSmallExpression
+ (expressionS *, bfd_reloc_code_real_type *, char *);
+static void my_getExpression (expressionS *, char *);
+static void s_align (int);
+static void s_change_sec (int);
+static void s_change_section (int);
+static void s_cons (int);
+static void s_float_cons (int);
+static void s_mips_globl (int);
+static void s_option (int);
+static void s_mipsset (int);
+static void s_abicalls (int);
+static void s_cpload (int);
+static void s_cpsetup (int);
+static void s_cplocal (int);
+static void s_cprestore (int);
+static void s_cpreturn (int);
+static void s_gpvalue (int);
+static void s_gpword (int);
+static void s_gpdword (int);
+static void s_cpadd (int);
+static void s_insn (int);
+static void md_obj_begin (void);
+static void md_obj_end (void);
+static void s_mips_ent (int);
+static void s_mips_end (int);
+static void s_mips_frame (int);
+static void s_mips_mask (int reg_type);
+static void s_mips_stab (int);
+static void s_mips_weakext (int);
+static void s_mips_file (int);
+static void s_mips_loc (int);
+static bfd_boolean pic_need_relax (symbolS *, asection *);
+static int relaxed_branch_length (fragS *, asection *, int);
+static int validate_mips_insn (const struct mips_opcode *);
+
+/* Table and functions used to map between CPU/ISA names, and
+ ISA levels, and CPU numbers. */
+
+struct mips_cpu_info
+{
+ const char *name; /* CPU or ISA name. */
+ int is_isa; /* Is this an ISA? (If 0, a CPU.) */
+ int isa; /* ISA level. */
+ int cpu; /* CPU number (default CPU if ISA). */
+};
+
+static const struct mips_cpu_info *mips_parse_cpu (const char *, const char *);
+static const struct mips_cpu_info *mips_cpu_info_from_isa (int);
+static const struct mips_cpu_info *mips_cpu_info_from_arch (int);
+
+/* Pseudo-op table.
+
+ The following pseudo-ops from the Kane and Heinrich MIPS book
+ should be defined here, but are currently unsupported: .alias,
+ .galive, .gjaldef, .gjrlive, .livereg, .noalias.
+
+ The following pseudo-ops from the Kane and Heinrich MIPS book are
+ specific to the type of debugging information being generated, and
+ should be defined by the object format: .aent, .begin, .bend,
+ .bgnb, .end, .endb, .ent, .fmask, .frame, .loc, .mask, .verstamp,
+ .vreg.
+
+ The following pseudo-ops from the Kane and Heinrich MIPS book are
+ not MIPS CPU specific, but are also not specific to the object file
+ format. This file is probably the best place to define them, but
+ they are not currently supported: .asm0, .endr, .lab, .repeat,
+ .struct. */
+
+static const pseudo_typeS mips_pseudo_table[] =
+{
+ /* MIPS specific pseudo-ops. */
+ {"option", s_option, 0},
+ {"set", s_mipsset, 0},
+ {"rdata", s_change_sec, 'r'},
+ {"sdata", s_change_sec, 's'},
+ {"livereg", s_ignore, 0},
+ {"abicalls", s_abicalls, 0},
+ {"cpload", s_cpload, 0},
+ {"cpsetup", s_cpsetup, 0},
+ {"cplocal", s_cplocal, 0},
+ {"cprestore", s_cprestore, 0},
+ {"cpreturn", s_cpreturn, 0},
+ {"gpvalue", s_gpvalue, 0},
+ {"gpword", s_gpword, 0},
+ {"gpdword", s_gpdword, 0},
+ {"cpadd", s_cpadd, 0},
+ {"insn", s_insn, 0},
+
+ /* Relatively generic pseudo-ops that happen to be used on MIPS
+ chips. */
+ {"asciiz", stringer, 1},
+ {"bss", s_change_sec, 'b'},
+ {"err", s_err, 0},
+ {"half", s_cons, 1},
+ {"dword", s_cons, 3},
+ {"weakext", s_mips_weakext, 0},
+
+ /* These pseudo-ops are defined in read.c, but must be overridden
+ here for one reason or another. */
+ {"align", s_align, 0},
+ {"byte", s_cons, 0},
+ {"data", s_change_sec, 'd'},
+ {"double", s_float_cons, 'd'},
+ {"float", s_float_cons, 'f'},
+ {"globl", s_mips_globl, 0},
+ {"global", s_mips_globl, 0},
+ {"hword", s_cons, 1},
+ {"int", s_cons, 2},
+ {"long", s_cons, 2},
+ {"octa", s_cons, 4},
+ {"quad", s_cons, 3},
+ {"section", s_change_section, 0},
+ {"short", s_cons, 1},
+ {"single", s_float_cons, 'f'},
+ {"stabn", s_mips_stab, 'n'},
+ {"text", s_change_sec, 't'},
+ {"word", s_cons, 2},
+
+ { "extern", ecoff_directive_extern, 0},
+
+ { NULL, NULL, 0 },
+};
+
+static const pseudo_typeS mips_nonecoff_pseudo_table[] =
+{
+ /* These pseudo-ops should be defined by the object file format.
+ However, a.out doesn't support them, so we have versions here. */
+ {"aent", s_mips_ent, 1},
+ {"bgnb", s_ignore, 0},
+ {"end", s_mips_end, 0},
+ {"endb", s_ignore, 0},
+ {"ent", s_mips_ent, 0},
+ {"file", s_mips_file, 0},
+ {"fmask", s_mips_mask, 'F'},
+ {"frame", s_mips_frame, 0},
+ {"loc", s_mips_loc, 0},
+ {"mask", s_mips_mask, 'R'},
+ {"verstamp", s_ignore, 0},
+ { NULL, NULL, 0 },
+};
+
+extern void pop_insert (const pseudo_typeS *);
+
+void
+mips_pop_insert (void)
+{
+ pop_insert (mips_pseudo_table);
+ if (! ECOFF_DEBUGGING)
+ pop_insert (mips_nonecoff_pseudo_table);
+}
+
+/* Symbols labelling the current insn. */
+
+struct insn_label_list
+{
+ struct insn_label_list *next;
+ symbolS *label;
+};
+
+static struct insn_label_list *insn_labels;
+static struct insn_label_list *free_insn_labels;
+
+static void mips_clear_insn_labels (void);
+
+static inline void
+mips_clear_insn_labels (void)
+{
+ register struct insn_label_list **pl;
+
+ for (pl = &free_insn_labels; *pl != NULL; pl = &(*pl)->next)
+ ;
+ *pl = insn_labels;
+ insn_labels = NULL;
+}
+
+static char *expr_end;
+
+/* Expressions which appear in instructions. These are set by
+ mips_ip. */
+
+static expressionS imm_expr;
+static expressionS imm2_expr;
+static expressionS offset_expr;
+
+/* Relocs associated with imm_expr and offset_expr. */
+
+static bfd_reloc_code_real_type imm_reloc[3]
+ = {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
+static bfd_reloc_code_real_type offset_reloc[3]
+ = {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
+
+/* These are set by mips16_ip if an explicit extension is used. */
+
+static bfd_boolean mips16_small, mips16_ext;
+
+#ifdef OBJ_ELF
+/* The pdr segment for per procedure frame/regmask info. Not used for
+ ECOFF debugging. */
+
+static segT pdr_seg;
+#endif
+
+/* The default target format to use. */
+
+const char *
+mips_target_format (void)
+{
+ switch (OUTPUT_FLAVOR)
+ {
+ case bfd_target_aout_flavour:
+ return target_big_endian ? "a.out-mips-big" : "a.out-mips-little";
+ case bfd_target_ecoff_flavour:
+ return target_big_endian ? "ecoff-bigmips" : ECOFF_LITTLE_FORMAT;
+ case bfd_target_coff_flavour:
+ return "pe-mips";
+ case bfd_target_elf_flavour:
+#ifdef TE_TMIPS
+ /* This is traditional mips. */
+ return (target_big_endian
+ ? (HAVE_64BIT_OBJECTS
+ ? "elf64-tradbigmips"
+ : (HAVE_NEWABI
+ ? "elf32-ntradbigmips" : "elf32-tradbigmips"))
+ : (HAVE_64BIT_OBJECTS
+ ? "elf64-tradlittlemips"
+ : (HAVE_NEWABI
+ ? "elf32-ntradlittlemips" : "elf32-tradlittlemips")));
+#else
+ return (target_big_endian
+ ? (HAVE_64BIT_OBJECTS
+ ? "elf64-bigmips"
+ : (HAVE_NEWABI
+ ? "elf32-nbigmips" : "elf32-bigmips"))
+ : (HAVE_64BIT_OBJECTS
+ ? "elf64-littlemips"
+ : (HAVE_NEWABI
+ ? "elf32-nlittlemips" : "elf32-littlemips")));
+#endif
+ default:
+ abort ();
+ return NULL;
+ }
+}
+
+/* This function is called once, at assembler startup time. It should
+ set up all the tables, etc. that the MD part of the assembler will need. */
+
+void
+md_begin (void)
+{
+ register const char *retval = NULL;
+ int i = 0;
+ int broken = 0;
+
+ if (! bfd_set_arch_mach (stdoutput, bfd_arch_mips, file_mips_arch))
+ as_warn (_("Could not set architecture and machine"));
+
+ op_hash = hash_new ();
+
+ for (i = 0; i < NUMOPCODES;)
+ {
+ const char *name = mips_opcodes[i].name;
+
+ retval = hash_insert (op_hash, name, (void *) &mips_opcodes[i]);
+ if (retval != NULL)
+ {
+ fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
+ mips_opcodes[i].name, retval);
+ /* Probably a memory allocation problem? Give up now. */
+ as_fatal (_("Broken assembler. No assembly attempted."));
+ }
+ do
+ {
+ if (mips_opcodes[i].pinfo != INSN_MACRO)
+ {
+ if (!validate_mips_insn (&mips_opcodes[i]))
+ broken = 1;
+ }
+ ++i;
+ }
+ while ((i < NUMOPCODES) && !strcmp (mips_opcodes[i].name, name));
+ }
+
+ mips16_op_hash = hash_new ();
+
+ i = 0;
+ while (i < bfd_mips16_num_opcodes)
+ {
+ const char *name = mips16_opcodes[i].name;
+
+ retval = hash_insert (mips16_op_hash, name, (void *) &mips16_opcodes[i]);
+ if (retval != NULL)
+ as_fatal (_("internal: can't hash `%s': %s"),
+ mips16_opcodes[i].name, retval);
+ do
+ {
+ if (mips16_opcodes[i].pinfo != INSN_MACRO
+ && ((mips16_opcodes[i].match & mips16_opcodes[i].mask)
+ != mips16_opcodes[i].match))
+ {
+ fprintf (stderr, _("internal error: bad mips16 opcode: %s %s\n"),
+ mips16_opcodes[i].name, mips16_opcodes[i].args);
+ broken = 1;
+ }
+ ++i;
+ }
+ while (i < bfd_mips16_num_opcodes
+ && strcmp (mips16_opcodes[i].name, name) == 0);
+ }
+
+ if (broken)
+ as_fatal (_("Broken assembler. No assembly attempted."));
+
+ /* We add all the general register names to the symbol table. This
+ helps us detect invalid uses of them. */
+ for (i = 0; i < 32; i++)
+ {
+ char buf[5];
+
+ sprintf (buf, "$%d", i);
+ symbol_table_insert (symbol_new (buf, reg_section, i,
+ &zero_address_frag));
+ }
+ symbol_table_insert (symbol_new ("$ra", reg_section, RA,
+ &zero_address_frag));
+ symbol_table_insert (symbol_new ("$fp", reg_section, FP,
+ &zero_address_frag));
+ symbol_table_insert (symbol_new ("$sp", reg_section, SP,
+ &zero_address_frag));
+ symbol_table_insert (symbol_new ("$gp", reg_section, GP,
+ &zero_address_frag));
+ symbol_table_insert (symbol_new ("$at", reg_section, AT,
+ &zero_address_frag));
+ symbol_table_insert (symbol_new ("$kt0", reg_section, KT0,
+ &zero_address_frag));
+ symbol_table_insert (symbol_new ("$kt1", reg_section, KT1,
+ &zero_address_frag));
+ symbol_table_insert (symbol_new ("$zero", reg_section, ZERO,
+ &zero_address_frag));
+ symbol_table_insert (symbol_new ("$pc", reg_section, -1,
+ &zero_address_frag));
+
+ /* If we don't add these register names to the symbol table, they
+ may end up being added as regular symbols by operand(), and then
+ make it to the object file as undefined in case they're not
+ regarded as local symbols. They're local in o32, since `$' is a
+ local symbol prefix, but not in n32 or n64. */
+ for (i = 0; i < 8; i++)
+ {
+ char buf[6];
+
+ sprintf (buf, "$fcc%i", i);
+ symbol_table_insert (symbol_new (buf, reg_section, -1,
+ &zero_address_frag));
+ }
+
+ mips_no_prev_insn (FALSE);
+
+ mips_gprmask = 0;
+ mips_cprmask[0] = 0;
+ mips_cprmask[1] = 0;
+ mips_cprmask[2] = 0;
+ mips_cprmask[3] = 0;
+
+ /* set the default alignment for the text section (2**2) */
+ record_alignment (text_section, 2);
+
+ if (USE_GLOBAL_POINTER_OPT)
+ bfd_set_gp_size (stdoutput, g_switch_value);
+
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ {
+ /* On a native system, sections must be aligned to 16 byte
+ boundaries. When configured for an embedded ELF target, we
+ don't bother. */
+ if (strcmp (TARGET_OS, "elf") != 0)
+ {
+ (void) bfd_set_section_alignment (stdoutput, text_section, 4);
+ (void) bfd_set_section_alignment (stdoutput, data_section, 4);
+ (void) bfd_set_section_alignment (stdoutput, bss_section, 4);
+ }
+
+ /* Create a .reginfo section for register masks and a .mdebug
+ section for debugging information. */
+ {
+ segT seg;
+ subsegT subseg;
+ flagword flags;
+ segT sec;
+
+ seg = now_seg;
+ subseg = now_subseg;
+
+ /* The ABI says this section should be loaded so that the
+ running program can access it. However, we don't load it
+ if we are configured for an embedded target */
+ flags = SEC_READONLY | SEC_DATA;
+ if (strcmp (TARGET_OS, "elf") != 0)
+ flags |= SEC_ALLOC | SEC_LOAD;
+
+ if (mips_abi != N64_ABI)
+ {
+ sec = subseg_new (".reginfo", (subsegT) 0);
+
+ bfd_set_section_flags (stdoutput, sec, flags);
+ bfd_set_section_alignment (stdoutput, sec, HAVE_NEWABI ? 3 : 2);
+
+#ifdef OBJ_ELF
+ mips_regmask_frag = frag_more (sizeof (Elf32_External_RegInfo));
+#endif
+ }
+ else
+ {
+ /* The 64-bit ABI uses a .MIPS.options section rather than
+ .reginfo section. */
+ sec = subseg_new (".MIPS.options", (subsegT) 0);
+ bfd_set_section_flags (stdoutput, sec, flags);
+ bfd_set_section_alignment (stdoutput, sec, 3);
+
+#ifdef OBJ_ELF
+ /* Set up the option header. */
+ {
+ Elf_Internal_Options opthdr;
+ char *f;
+
+ opthdr.kind = ODK_REGINFO;
+ opthdr.size = (sizeof (Elf_External_Options)
+ + sizeof (Elf64_External_RegInfo));
+ opthdr.section = 0;
+ opthdr.info = 0;
+ f = frag_more (sizeof (Elf_External_Options));
+ bfd_mips_elf_swap_options_out (stdoutput, &opthdr,
+ (Elf_External_Options *) f);
+
+ mips_regmask_frag = frag_more (sizeof (Elf64_External_RegInfo));
+ }
+#endif
+ }
+
+ if (ECOFF_DEBUGGING)
+ {
+ sec = subseg_new (".mdebug", (subsegT) 0);
+ (void) bfd_set_section_flags (stdoutput, sec,
+ SEC_HAS_CONTENTS | SEC_READONLY);
+ (void) bfd_set_section_alignment (stdoutput, sec, 2);
+ }
+#ifdef OBJ_ELF
+ else if (OUTPUT_FLAVOR == bfd_target_elf_flavour && mips_flag_pdr)
+ {
+ pdr_seg = subseg_new (".pdr", (subsegT) 0);
+ (void) bfd_set_section_flags (stdoutput, pdr_seg,
+ SEC_READONLY | SEC_RELOC
+ | SEC_DEBUGGING);
+ (void) bfd_set_section_alignment (stdoutput, pdr_seg, 2);
+ }
+#endif
+
+ subseg_set (seg, subseg);
+ }
+ }
+
+ if (! ECOFF_DEBUGGING)
+ md_obj_begin ();
+}
+
+void
+md_mips_end (void)
+{
+ if (! ECOFF_DEBUGGING)
+ md_obj_end ();
+}
+
+void
+md_assemble (char *str)
+{
+ struct mips_cl_insn insn;
+ bfd_reloc_code_real_type unused_reloc[3]
+ = {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
+
+ imm_expr.X_op = O_absent;
+ imm2_expr.X_op = O_absent;
+ offset_expr.X_op = O_absent;
+ imm_reloc[0] = BFD_RELOC_UNUSED;
+ imm_reloc[1] = BFD_RELOC_UNUSED;
+ imm_reloc[2] = BFD_RELOC_UNUSED;
+ offset_reloc[0] = BFD_RELOC_UNUSED;
+ offset_reloc[1] = BFD_RELOC_UNUSED;
+ offset_reloc[2] = BFD_RELOC_UNUSED;
+
+ if (mips_opts.mips16)
+ mips16_ip (str, &insn);
+ else
+ {
+ mips_ip (str, &insn);
+ DBG ((_("returned from mips_ip(%s) insn_opcode = 0x%x\n"),
+ str, insn.insn_opcode));
+ }
+
+ if (insn_error)
+ {
+ as_bad ("%s `%s'", insn_error, str);
+ return;
+ }
+
+ if (insn.insn_mo->pinfo == INSN_MACRO)
+ {
+ macro_start ();
+ if (mips_opts.mips16)
+ mips16_macro (&insn);
+ else
+ macro (&insn);
+ macro_end ();
+ }
+ else
+ {
+ if (imm_expr.X_op != O_absent)
+ append_insn (&insn, &imm_expr, imm_reloc);
+ else if (offset_expr.X_op != O_absent)
+ append_insn (&insn, &offset_expr, offset_reloc);
+ else
+ append_insn (&insn, NULL, unused_reloc);
+ }
+}
+
+/* Return true if the given relocation might need a matching %lo().
+ Note that R_MIPS_GOT16 relocations only need a matching %lo() when
+ applied to local symbols. */
+
+static inline bfd_boolean
+reloc_needs_lo_p (bfd_reloc_code_real_type reloc)
+{
+ return (reloc == BFD_RELOC_HI16_S
+ || reloc == BFD_RELOC_MIPS_GOT16);
+}
+
+/* Return true if the given fixup is followed by a matching R_MIPS_LO16
+ relocation. */
+
+static inline bfd_boolean
+fixup_has_matching_lo_p (fixS *fixp)
+{
+ return (fixp->fx_next != NULL
+ && fixp->fx_next->fx_r_type == BFD_RELOC_LO16
+ && fixp->fx_addsy == fixp->fx_next->fx_addsy
+ && fixp->fx_offset == fixp->fx_next->fx_offset);
+}
+
+/* See whether instruction IP reads register REG. CLASS is the type
+ of register. */
+
+static int
+insn_uses_reg (struct mips_cl_insn *ip, unsigned int reg,
+ enum mips_regclass class)
+{
+ if (class == MIPS16_REG)
+ {
+ assert (mips_opts.mips16);
+ reg = mips16_to_32_reg_map[reg];
+ class = MIPS_GR_REG;
+ }
+
+ /* Don't report on general register ZERO, since it never changes. */
+ if (class == MIPS_GR_REG && reg == ZERO)
+ return 0;
+
+ if (class == MIPS_FP_REG)
+ {
+ assert (! mips_opts.mips16);
+ /* If we are called with either $f0 or $f1, we must check $f0.
+ This is not optimal, because it will introduce an unnecessary
+ NOP between "lwc1 $f0" and "swc1 $f1". To fix this we would
+ need to distinguish reading both $f0 and $f1 or just one of
+ them. Note that we don't have to check the other way,
+ because there is no instruction that sets both $f0 and $f1
+ and requires a delay. */
+ if ((ip->insn_mo->pinfo & INSN_READ_FPR_S)
+ && ((((ip->insn_opcode >> OP_SH_FS) & OP_MASK_FS) &~(unsigned)1)
+ == (reg &~ (unsigned) 1)))
+ return 1;
+ if ((ip->insn_mo->pinfo & INSN_READ_FPR_T)
+ && ((((ip->insn_opcode >> OP_SH_FT) & OP_MASK_FT) &~(unsigned)1)
+ == (reg &~ (unsigned) 1)))
+ return 1;
+ }
+ else if (! mips_opts.mips16)
+ {
+ if ((ip->insn_mo->pinfo & INSN_READ_GPR_S)
+ && ((ip->insn_opcode >> OP_SH_RS) & OP_MASK_RS) == reg)
+ return 1;
+ if ((ip->insn_mo->pinfo & INSN_READ_GPR_T)
+ && ((ip->insn_opcode >> OP_SH_RT) & OP_MASK_RT) == reg)
+ return 1;
+ }
+ else
+ {
+ if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_X)
+ && (mips16_to_32_reg_map[((ip->insn_opcode >> MIPS16OP_SH_RX)
+ & MIPS16OP_MASK_RX)]
+ == reg))
+ return 1;
+ if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_Y)
+ && (mips16_to_32_reg_map[((ip->insn_opcode >> MIPS16OP_SH_RY)
+ & MIPS16OP_MASK_RY)]
+ == reg))
+ return 1;
+ if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_Z)
+ && (mips16_to_32_reg_map[((ip->insn_opcode >> MIPS16OP_SH_MOVE32Z)
+ & MIPS16OP_MASK_MOVE32Z)]
+ == reg))
+ return 1;
+ if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_T) && reg == TREG)
+ return 1;
+ if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_SP) && reg == SP)
+ return 1;
+ if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_31) && reg == RA)
+ return 1;
+ if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_GPR_X)
+ && ((ip->insn_opcode >> MIPS16OP_SH_REGR32)
+ & MIPS16OP_MASK_REGR32) == reg)
+ return 1;
+ }
+
+ return 0;
+}
+
+/* This function returns true if modifying a register requires a
+ delay. */
+
+static int
+reg_needs_delay (unsigned int reg)
+{
+ unsigned long prev_pinfo;
+
+ prev_pinfo = prev_insn.insn_mo->pinfo;
+ if (! mips_opts.noreorder
+ && (((prev_pinfo & INSN_LOAD_MEMORY_DELAY)
+ && ! gpr_interlocks)
+ || ((prev_pinfo & INSN_LOAD_COPROC_DELAY)
+ && ! cop_interlocks)))
+ {
+ /* A load from a coprocessor or from memory. All load delays
+ delay the use of general register rt for one instruction. */
+ /* Itbl support may require additional care here. */
+ know (prev_pinfo & INSN_WRITE_GPR_T);
+ if (reg == ((prev_insn.insn_opcode >> OP_SH_RT) & OP_MASK_RT))
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Mark instruction labels in mips16 mode. This permits the linker to
+ handle them specially, such as generating jalx instructions when
+ needed. We also make them odd for the duration of the assembly, in
+ order to generate the right sort of code. We will make them even
+ in the adjust_symtab routine, while leaving them marked. This is
+ convenient for the debugger and the disassembler. The linker knows
+ to make them odd again. */
+
+static void
+mips16_mark_labels (void)
+{
+ if (mips_opts.mips16)
+ {
+ struct insn_label_list *l;
+ valueT val;
+
+ for (l = insn_labels; l != NULL; l = l->next)
+ {
+#ifdef OBJ_ELF
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ S_SET_OTHER (l->label, STO_MIPS16);
+#endif
+ val = S_GET_VALUE (l->label);
+ if ((val & 1) == 0)
+ S_SET_VALUE (l->label, val + 1);
+ }
+ }
+}
+
+/* End the current frag. Make it a variant frag and record the
+ relaxation info. */
+
+static void
+relax_close_frag (void)
+{
+ mips_macro_warning.first_frag = frag_now;
+ frag_var (rs_machine_dependent, 0, 0,
+ RELAX_ENCODE (mips_relax.sizes[0], mips_relax.sizes[1]),
+ mips_relax.symbol, 0, (char *) mips_relax.first_fixup);
+
+ memset (&mips_relax.sizes, 0, sizeof (mips_relax.sizes));
+ mips_relax.first_fixup = 0;
+}
+
+/* Start a new relaxation sequence whose expansion depends on SYMBOL.
+ See the comment above RELAX_ENCODE for more details. */
+
+static void
+relax_start (symbolS *symbol)
+{
+ assert (mips_relax.sequence == 0);
+ mips_relax.sequence = 1;
+ mips_relax.symbol = symbol;
+}
+
+/* Start generating the second version of a relaxable sequence.
+ See the comment above RELAX_ENCODE for more details. */
+
+static void
+relax_switch (void)
+{
+ assert (mips_relax.sequence == 1);
+ mips_relax.sequence = 2;
+}
+
+/* End the current relaxable sequence. */
+
+static void
+relax_end (void)
+{
+ assert (mips_relax.sequence == 2);
+ relax_close_frag ();
+ mips_relax.sequence = 0;
+}
+
+/* Output an instruction. IP is the instruction information.
+ ADDRESS_EXPR is an operand of the instruction to be used with
+ RELOC_TYPE. */
+
+static void
+append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
+ bfd_reloc_code_real_type *reloc_type)
+{
+ register unsigned long prev_pinfo, pinfo;
+ char *f;
+ fixS *fixp[3];
+ int nops = 0;
+ relax_stateT prev_insn_frag_type = 0;
+ bfd_boolean relaxed_branch = FALSE;
+ bfd_boolean force_new_frag = FALSE;
+
+ /* Mark instruction labels in mips16 mode. */
+ mips16_mark_labels ();
+
+ prev_pinfo = prev_insn.insn_mo->pinfo;
+ pinfo = ip->insn_mo->pinfo;
+
+ if (mips_relax.sequence != 2
+ && (!mips_opts.noreorder || prev_nop_frag != NULL))
+ {
+ int prev_prev_nop;
+
+ /* If the previous insn required any delay slots, see if we need
+ to insert a NOP or two. There are eight kinds of possible
+ hazards, of which an instruction can have at most one type.
+ (1) a load from memory delay
+ (2) a load from a coprocessor delay
+ (3) an unconditional branch delay
+ (4) a conditional branch delay
+ (5) a move to coprocessor register delay
+ (6) a load coprocessor register from memory delay
+ (7) a coprocessor condition code delay
+ (8) a HI/LO special register delay
+
+ There are a lot of optimizations we could do that we don't.
+ In particular, we do not, in general, reorder instructions.
+ If you use gcc with optimization, it will reorder
+ instructions and generally do much more optimization then we
+ do here; repeating all that work in the assembler would only
+ benefit hand written assembly code, and does not seem worth
+ it. */
+
+ /* This is how a NOP is emitted. */
+#define emit_nop() \
+ (mips_opts.mips16 \
+ ? md_number_to_chars (frag_more (2), 0x6500, 2) \
+ : md_number_to_chars (frag_more (4), 0, 4))
+
+ /* The previous insn might require a delay slot, depending upon
+ the contents of the current insn. */
+ if (! mips_opts.mips16
+ && (((prev_pinfo & INSN_LOAD_MEMORY_DELAY)
+ && ! gpr_interlocks)
+ || ((prev_pinfo & INSN_LOAD_COPROC_DELAY)
+ && ! cop_interlocks)))
+ {
+ /* A load from a coprocessor or from memory. All load
+ delays delay the use of general register rt for one
+ instruction. */
+ /* Itbl support may require additional care here. */
+ know (prev_pinfo & INSN_WRITE_GPR_T);
+ if (mips_optimize == 0
+ || insn_uses_reg (ip,
+ ((prev_insn.insn_opcode >> OP_SH_RT)
+ & OP_MASK_RT),
+ MIPS_GR_REG))
+ ++nops;
+ }
+ else if (! mips_opts.mips16
+ && (((prev_pinfo & INSN_COPROC_MOVE_DELAY)
+ && ! cop_interlocks)
+ || ((prev_pinfo & INSN_COPROC_MEMORY_DELAY)
+ && ! cop_mem_interlocks)))
+ {
+ /* A generic coprocessor delay. The previous instruction
+ modified a coprocessor general or control register. If
+ it modified a control register, we need to avoid any
+ coprocessor instruction (this is probably not always
+ required, but it sometimes is). If it modified a general
+ register, we avoid using that register.
+
+ This case is not handled very well. There is no special
+ knowledge of CP0 handling, and the coprocessors other
+ than the floating point unit are not distinguished at
+ all. */
+ /* Itbl support may require additional care here. FIXME!
+ Need to modify this to include knowledge about
+ user specified delays! */
+ if (prev_pinfo & INSN_WRITE_FPR_T)
+ {
+ if (mips_optimize == 0
+ || insn_uses_reg (ip,
+ ((prev_insn.insn_opcode >> OP_SH_FT)
+ & OP_MASK_FT),
+ MIPS_FP_REG))
+ ++nops;
+ }
+ else if (prev_pinfo & INSN_WRITE_FPR_S)
+ {
+ if (mips_optimize == 0
+ || insn_uses_reg (ip,
+ ((prev_insn.insn_opcode >> OP_SH_FS)
+ & OP_MASK_FS),
+ MIPS_FP_REG))
+ ++nops;
+ }
+ else
+ {
+ /* We don't know exactly what the previous instruction
+ does. If the current instruction uses a coprocessor
+ register, we must insert a NOP. If previous
+ instruction may set the condition codes, and the
+ current instruction uses them, we must insert two
+ NOPS. */
+ /* Itbl support may require additional care here. */
+ if (mips_optimize == 0
+ || ((prev_pinfo & INSN_WRITE_COND_CODE)
+ && (pinfo & INSN_READ_COND_CODE)))
+ nops += 2;
+ else if (pinfo & INSN_COP)
+ ++nops;
+ }
+ }
+ else if (! mips_opts.mips16
+ && (prev_pinfo & INSN_WRITE_COND_CODE)
+ && ! cop_interlocks)
+ {
+ /* The previous instruction sets the coprocessor condition
+ codes, but does not require a general coprocessor delay
+ (this means it is a floating point comparison
+ instruction). If this instruction uses the condition
+ codes, we need to insert a single NOP. */
+ /* Itbl support may require additional care here. */
+ if (mips_optimize == 0
+ || (pinfo & INSN_READ_COND_CODE))
+ ++nops;
+ }
+
+ /* If we're fixing up mfhi/mflo for the r7000 and the
+ previous insn was an mfhi/mflo and the current insn
+ reads the register that the mfhi/mflo wrote to, then
+ insert two nops. */
+
+ else if (mips_7000_hilo_fix
+ && MF_HILO_INSN (prev_pinfo)
+ && insn_uses_reg (ip, ((prev_insn.insn_opcode >> OP_SH_RD)
+ & OP_MASK_RD),
+ MIPS_GR_REG))
+ {
+ nops += 2;
+ }
+
+ /* If we're fixing up mfhi/mflo for the r7000 and the
+ 2nd previous insn was an mfhi/mflo and the current insn
+ reads the register that the mfhi/mflo wrote to, then
+ insert one nop. */
+
+ else if (mips_7000_hilo_fix
+ && MF_HILO_INSN (prev_prev_insn.insn_opcode)
+ && insn_uses_reg (ip, ((prev_prev_insn.insn_opcode >> OP_SH_RD)
+ & OP_MASK_RD),
+ MIPS_GR_REG))
+
+ {
+ ++nops;
+ }
+
+ else if (prev_pinfo & INSN_READ_LO)
+ {
+ /* The previous instruction reads the LO register; if the
+ current instruction writes to the LO register, we must
+ insert two NOPS. Some newer processors have interlocks.
+ Also the tx39's multiply instructions can be executed
+ immediately after a read from HI/LO (without the delay),
+ though the tx39's divide insns still do require the
+ delay. */
+ if (! (hilo_interlocks
+ || (mips_opts.arch == CPU_R3900 && (pinfo & INSN_MULT)))
+ && (mips_optimize == 0
+ || (pinfo & INSN_WRITE_LO)))
+ nops += 2;
+ /* Most mips16 branch insns don't have a delay slot.
+ If a read from LO is immediately followed by a branch
+ to a write to LO we have a read followed by a write
+ less than 2 insns away. We assume the target of
+ a branch might be a write to LO, and insert a nop
+ between a read and an immediately following branch. */
+ else if (mips_opts.mips16
+ && (mips_optimize == 0
+ || (pinfo & MIPS16_INSN_BRANCH)))
+ ++nops;
+ }
+ else if (prev_insn.insn_mo->pinfo & INSN_READ_HI)
+ {
+ /* The previous instruction reads the HI register; if the
+ current instruction writes to the HI register, we must
+ insert a NOP. Some newer processors have interlocks.
+ Also the note tx39's multiply above. */
+ if (! (hilo_interlocks
+ || (mips_opts.arch == CPU_R3900 && (pinfo & INSN_MULT)))
+ && (mips_optimize == 0
+ || (pinfo & INSN_WRITE_HI)))
+ nops += 2;
+ /* Most mips16 branch insns don't have a delay slot.
+ If a read from HI is immediately followed by a branch
+ to a write to HI we have a read followed by a write
+ less than 2 insns away. We assume the target of
+ a branch might be a write to HI, and insert a nop
+ between a read and an immediately following branch. */
+ else if (mips_opts.mips16
+ && (mips_optimize == 0
+ || (pinfo & MIPS16_INSN_BRANCH)))
+ ++nops;
+ }
+
+ /* If the previous instruction was in a noreorder section, then
+ we don't want to insert the nop after all. */
+ /* Itbl support may require additional care here. */
+ if (prev_insn_unreordered)
+ nops = 0;
+
+ /* There are two cases which require two intervening
+ instructions: 1) setting the condition codes using a move to
+ coprocessor instruction which requires a general coprocessor
+ delay and then reading the condition codes 2) reading the HI
+ or LO register and then writing to it (except on processors
+ which have interlocks). If we are not already emitting a NOP
+ instruction, we must check for these cases compared to the
+ instruction previous to the previous instruction. */
+ if ((! mips_opts.mips16
+ && (prev_prev_insn.insn_mo->pinfo & INSN_COPROC_MOVE_DELAY)
+ && (prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE)
+ && (pinfo & INSN_READ_COND_CODE)
+ && ! cop_interlocks)
+ || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_LO)
+ && (pinfo & INSN_WRITE_LO)
+ && ! (hilo_interlocks
+ || (mips_opts.arch == CPU_R3900 && (pinfo & INSN_MULT))))
+ || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
+ && (pinfo & INSN_WRITE_HI)
+ && ! (hilo_interlocks
+ || (mips_opts.arch == CPU_R3900 && (pinfo & INSN_MULT)))))
+ prev_prev_nop = 1;
+ else
+ prev_prev_nop = 0;
+
+ if (prev_prev_insn_unreordered)
+ prev_prev_nop = 0;
+
+ if (prev_prev_nop && nops == 0)
+ ++nops;
+
+ if (mips_fix_vr4120 && prev_insn.insn_mo->name)
+ {
+ /* We're out of bits in pinfo, so we must resort to string
+ ops here. Shortcuts are selected based on opcodes being
+ limited to the VR4120 instruction set. */
+ int min_nops = 0;
+ const char *pn = prev_insn.insn_mo->name;
+ const char *tn = ip->insn_mo->name;
+ if (strncmp(pn, "macc", 4) == 0
+ || strncmp(pn, "dmacc", 5) == 0)
+ {
+ /* Errata 21 - [D]DIV[U] after [D]MACC */
+ if (strstr (tn, "div"))
+ {
+ min_nops = 1;
+ }
+
+ /* Errata 23 - Continuous DMULT[U]/DMACC instructions */
+ if (pn[0] == 'd' /* dmacc */
+ && (strncmp(tn, "dmult", 5) == 0
+ || strncmp(tn, "dmacc", 5) == 0))
+ {
+ min_nops = 1;
+ }
+
+ /* Errata 24 - MT{LO,HI} after [D]MACC */
+ if (strcmp (tn, "mtlo") == 0
+ || strcmp (tn, "mthi") == 0)
+ {
+ min_nops = 1;
+ }
+
+ }
+ else if (strncmp(pn, "dmult", 5) == 0
+ && (strncmp(tn, "dmult", 5) == 0
+ || strncmp(tn, "dmacc", 5) == 0))
+ {
+ /* Here is the rest of errata 23. */
+ min_nops = 1;
+ }
+ if (nops < min_nops)
+ nops = min_nops;
+ }
+
+ /* If we are being given a nop instruction, don't bother with
+ one of the nops we would otherwise output. This will only
+ happen when a nop instruction is used with mips_optimize set
+ to 0. */
+ if (nops > 0
+ && ! mips_opts.noreorder
+ && ip->insn_opcode == (unsigned) (mips_opts.mips16 ? 0x6500 : 0))
+ --nops;
+
+ /* Now emit the right number of NOP instructions. */
+ if (nops > 0 && ! mips_opts.noreorder)
+ {
+ fragS *old_frag;
+ unsigned long old_frag_offset;
+ int i;
+ struct insn_label_list *l;
+
+ old_frag = frag_now;
+ old_frag_offset = frag_now_fix ();
+
+ for (i = 0; i < nops; i++)
+ emit_nop ();
+
+ if (listing)
+ {
+ listing_prev_line ();
+ /* We may be at the start of a variant frag. In case we
+ are, make sure there is enough space for the frag
+ after the frags created by listing_prev_line. The
+ argument to frag_grow here must be at least as large
+ as the argument to all other calls to frag_grow in
+ this file. We don't have to worry about being in the
+ middle of a variant frag, because the variants insert
+ all needed nop instructions themselves. */
+ frag_grow (40);
+ }
+
+ for (l = insn_labels; l != NULL; l = l->next)
+ {
+ valueT val;
+
+ assert (S_GET_SEGMENT (l->label) == now_seg);
+ symbol_set_frag (l->label, frag_now);
+ val = (valueT) frag_now_fix ();
+ /* mips16 text labels are stored as odd. */
+ if (mips_opts.mips16)
+ ++val;
+ S_SET_VALUE (l->label, val);
+ }
+
+#ifndef NO_ECOFF_DEBUGGING
+ if (ECOFF_DEBUGGING)
+ ecoff_fix_loc (old_frag, old_frag_offset);
+#endif
+ }
+ else if (prev_nop_frag != NULL)
+ {
+ /* We have a frag holding nops we may be able to remove. If
+ we don't need any nops, we can decrease the size of
+ prev_nop_frag by the size of one instruction. If we do
+ need some nops, we count them in prev_nops_required. */
+ if (prev_nop_frag_since == 0)
+ {
+ if (nops == 0)
+ {
+ prev_nop_frag->fr_fix -= mips_opts.mips16 ? 2 : 4;
+ --prev_nop_frag_holds;
+ }
+ else
+ prev_nop_frag_required += nops;
+ }
+ else
+ {
+ if (prev_prev_nop == 0)
+ {
+ prev_nop_frag->fr_fix -= mips_opts.mips16 ? 2 : 4;
+ --prev_nop_frag_holds;
+ }
+ else
+ ++prev_nop_frag_required;
+ }
+
+ if (prev_nop_frag_holds <= prev_nop_frag_required)
+ prev_nop_frag = NULL;
+
+ ++prev_nop_frag_since;
+
+ /* Sanity check: by the time we reach the second instruction
+ after prev_nop_frag, we should have used up all the nops
+ one way or another. */
+ assert (prev_nop_frag_since <= 1 || prev_nop_frag == NULL);
+ }
+ }
+
+ /* Record the frag type before frag_var. */
+ if (prev_insn_frag)
+ prev_insn_frag_type = prev_insn_frag->fr_type;
+
+ if (address_expr
+ && *reloc_type == BFD_RELOC_16_PCREL_S2
+ && (pinfo & INSN_UNCOND_BRANCH_DELAY || pinfo & INSN_COND_BRANCH_DELAY
+ || pinfo & INSN_COND_BRANCH_LIKELY)
+ && mips_relax_branch
+ /* Don't try branch relaxation within .set nomacro, or within
+ .set noat if we use $at for PIC computations. If it turns
+ out that the branch was out-of-range, we'll get an error. */
+ && !mips_opts.warn_about_macros
+ && !(mips_opts.noat && mips_pic != NO_PIC)
+ && !mips_opts.mips16)
+ {
+ relaxed_branch = TRUE;
+ f = frag_var (rs_machine_dependent,
+ relaxed_branch_length
+ (NULL, NULL,
+ (pinfo & INSN_UNCOND_BRANCH_DELAY) ? -1
+ : (pinfo & INSN_COND_BRANCH_LIKELY) ? 1 : 0), 4,
+ RELAX_BRANCH_ENCODE
+ (pinfo & INSN_UNCOND_BRANCH_DELAY,
+ pinfo & INSN_COND_BRANCH_LIKELY,
+ pinfo & INSN_WRITE_GPR_31,
+ 0),
+ address_expr->X_add_symbol,
+ address_expr->X_add_number,
+ 0);
+ *reloc_type = BFD_RELOC_UNUSED;
+ }
+ else if (*reloc_type > BFD_RELOC_UNUSED)
+ {
+ /* We need to set up a variant frag. */
+ assert (mips_opts.mips16 && address_expr != NULL);
+ f = frag_var (rs_machine_dependent, 4, 0,
+ RELAX_MIPS16_ENCODE (*reloc_type - BFD_RELOC_UNUSED,
+ mips16_small, mips16_ext,
+ (prev_pinfo
+ & INSN_UNCOND_BRANCH_DELAY),
+ (*prev_insn_reloc_type
+ == BFD_RELOC_MIPS16_JMP)),
+ make_expr_symbol (address_expr), 0, NULL);
+ }
+ else if (mips_opts.mips16
+ && ! ip->use_extend
+ && *reloc_type != BFD_RELOC_MIPS16_JMP)
+ {
+ /* Make sure there is enough room to swap this instruction with
+ a following jump instruction. */
+ frag_grow (6);
+ f = frag_more (2);
+ }
+ else
+ {
+ if (mips_opts.mips16
+ && mips_opts.noreorder
+ && (prev_pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
+ as_warn (_("extended instruction in delay slot"));
+
+ if (mips_relax.sequence)
+ {
+ /* If we've reached the end of this frag, turn it into a variant
+ frag and record the information for the instructions we've
+ written so far. */
+ if (frag_room () < 4)
+ relax_close_frag ();
+ mips_relax.sizes[mips_relax.sequence - 1] += 4;
+ }
+
+ if (mips_relax.sequence != 2)
+ mips_macro_warning.sizes[0] += 4;
+ if (mips_relax.sequence != 1)
+ mips_macro_warning.sizes[1] += 4;
+
+ f = frag_more (4);
+ }
+
+ fixp[0] = fixp[1] = fixp[2] = NULL;
+ if (address_expr != NULL && *reloc_type < BFD_RELOC_UNUSED)
+ {
+ if (address_expr->X_op == O_constant)
+ {
+ valueT tmp;
+
+ switch (*reloc_type)
+ {
+ case BFD_RELOC_32:
+ ip->insn_opcode |= address_expr->X_add_number;
+ break;
+
+ case BFD_RELOC_MIPS_HIGHEST:
+ tmp = (address_expr->X_add_number
+ + ((valueT) 0x8000 << 32) + 0x80008000) >> 16;
+ tmp >>= 16;
+ ip->insn_opcode |= (tmp >> 16) & 0xffff;
+ break;
+
+ case BFD_RELOC_MIPS_HIGHER:
+ tmp = (address_expr->X_add_number + 0x80008000) >> 16;
+ ip->insn_opcode |= (tmp >> 16) & 0xffff;
+ break;
+
+ case BFD_RELOC_HI16_S:
+ ip->insn_opcode |= ((address_expr->X_add_number + 0x8000)
+ >> 16) & 0xffff;
+ break;
+
+ case BFD_RELOC_HI16:
+ ip->insn_opcode |= (address_expr->X_add_number >> 16) & 0xffff;
+ break;
+
+ case BFD_RELOC_LO16:
+ case BFD_RELOC_MIPS_GOT_DISP:
+ ip->insn_opcode |= address_expr->X_add_number & 0xffff;
+ break;
+
+ case BFD_RELOC_MIPS_JMP:
+ if ((address_expr->X_add_number & 3) != 0)
+ as_bad (_("jump to misaligned address (0x%lx)"),
+ (unsigned long) address_expr->X_add_number);
+ if (address_expr->X_add_number & ~0xfffffff)
+ as_bad (_("jump address range overflow (0x%lx)"),
+ (unsigned long) address_expr->X_add_number);
+ ip->insn_opcode |= (address_expr->X_add_number >> 2) & 0x3ffffff;
+ break;
+
+ case BFD_RELOC_MIPS16_JMP:
+ if ((address_expr->X_add_number & 3) != 0)
+ as_bad (_("jump to misaligned address (0x%lx)"),
+ (unsigned long) address_expr->X_add_number);
+ if (address_expr->X_add_number & ~0xfffffff)
+ as_bad (_("jump address range overflow (0x%lx)"),
+ (unsigned long) address_expr->X_add_number);
+ ip->insn_opcode |=
+ (((address_expr->X_add_number & 0x7c0000) << 3)
+ | ((address_expr->X_add_number & 0xf800000) >> 7)
+ | ((address_expr->X_add_number & 0x3fffc) >> 2));
+ break;
+
+ case BFD_RELOC_16_PCREL_S2:
+ goto need_reloc;
+
+ default:
+ internalError ();
+ }
+ }
+ else
+ need_reloc:
+ {
+ reloc_howto_type *howto;
+ int i;
+
+ /* In a compound relocation, it is the final (outermost)
+ operator that determines the relocated field. */
+ for (i = 1; i < 3; i++)
+ if (reloc_type[i] == BFD_RELOC_UNUSED)
+ break;
+
+ howto = bfd_reloc_type_lookup (stdoutput, reloc_type[i - 1]);
+ fixp[0] = fix_new_exp (frag_now, f - frag_now->fr_literal,
+ bfd_get_reloc_size(howto),
+ address_expr,
+ reloc_type[0] == BFD_RELOC_16_PCREL_S2,
+ reloc_type[0]);
+
+ /* These relocations can have an addend that won't fit in
+ 4 octets for 64bit assembly. */
+ if (HAVE_64BIT_GPRS
+ && ! howto->partial_inplace
+ && (reloc_type[0] == BFD_RELOC_16
+ || reloc_type[0] == BFD_RELOC_32
+ || reloc_type[0] == BFD_RELOC_MIPS_JMP
+ || reloc_type[0] == BFD_RELOC_HI16_S
+ || reloc_type[0] == BFD_RELOC_LO16
+ || reloc_type[0] == BFD_RELOC_GPREL16
+ || reloc_type[0] == BFD_RELOC_MIPS_LITERAL
+ || reloc_type[0] == BFD_RELOC_GPREL32
+ || reloc_type[0] == BFD_RELOC_64
+ || reloc_type[0] == BFD_RELOC_CTOR
+ || reloc_type[0] == BFD_RELOC_MIPS_SUB
+ || reloc_type[0] == BFD_RELOC_MIPS_HIGHEST
+ || reloc_type[0] == BFD_RELOC_MIPS_HIGHER
+ || reloc_type[0] == BFD_RELOC_MIPS_SCN_DISP
+ || reloc_type[0] == BFD_RELOC_MIPS_REL16
+ || reloc_type[0] == BFD_RELOC_MIPS_RELGOT))
+ fixp[0]->fx_no_overflow = 1;
+
+ if (mips_relax.sequence)
+ {
+ if (mips_relax.first_fixup == 0)
+ mips_relax.first_fixup = fixp[0];
+ }
+ else if (reloc_needs_lo_p (*reloc_type))
+ {
+ struct mips_hi_fixup *hi_fixup;
+
+ /* Reuse the last entry if it already has a matching %lo. */
+ hi_fixup = mips_hi_fixup_list;
+ if (hi_fixup == 0
+ || !fixup_has_matching_lo_p (hi_fixup->fixp))
+ {
+ hi_fixup = ((struct mips_hi_fixup *)
+ xmalloc (sizeof (struct mips_hi_fixup)));
+ hi_fixup->next = mips_hi_fixup_list;
+ mips_hi_fixup_list = hi_fixup;
+ }
+ hi_fixup->fixp = fixp[0];
+ hi_fixup->seg = now_seg;
+ }
+
+ /* Add fixups for the second and third relocations, if given.
+ Note that the ABI allows the second relocation to be
+ against RSS_UNDEF, RSS_GP, RSS_GP0 or RSS_LOC. At the
+ moment we only use RSS_UNDEF, but we could add support
+ for the others if it ever becomes necessary. */
+ for (i = 1; i < 3; i++)
+ if (reloc_type[i] != BFD_RELOC_UNUSED)
+ {
+ address_expr->X_op = O_absent;
+ address_expr->X_add_symbol = 0;
+ address_expr->X_add_number = 0;
+
+ fixp[i] = fix_new_exp (frag_now, fixp[0]->fx_where,
+ fixp[0]->fx_size, address_expr,
+ FALSE, reloc_type[i]);
+ }
+ }
+ }
+
+ if (! mips_opts.mips16)
+ {
+ md_number_to_chars (f, ip->insn_opcode, 4);
+#ifdef OBJ_ELF
+ dwarf2_emit_insn (4);
+#endif
+ }
+ else if (*reloc_type == BFD_RELOC_MIPS16_JMP)
+ {
+ md_number_to_chars (f, ip->insn_opcode >> 16, 2);
+ md_number_to_chars (f + 2, ip->insn_opcode & 0xffff, 2);
+#ifdef OBJ_ELF
+ dwarf2_emit_insn (4);
+#endif
+ }
+ else
+ {
+ if (ip->use_extend)
+ {
+ md_number_to_chars (f, 0xf000 | ip->extend, 2);
+ f += 2;
+ }
+ md_number_to_chars (f, ip->insn_opcode, 2);
+#ifdef OBJ_ELF
+ dwarf2_emit_insn (ip->use_extend ? 4 : 2);
+#endif
+ }
+
+ /* Update the register mask information. */
+ if (! mips_opts.mips16)
+ {
+ if (pinfo & INSN_WRITE_GPR_D)
+ mips_gprmask |= 1 << ((ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD);
+ if ((pinfo & (INSN_WRITE_GPR_T | INSN_READ_GPR_T)) != 0)
+ mips_gprmask |= 1 << ((ip->insn_opcode >> OP_SH_RT) & OP_MASK_RT);
+ if (pinfo & INSN_READ_GPR_S)
+ mips_gprmask |= 1 << ((ip->insn_opcode >> OP_SH_RS) & OP_MASK_RS);
+ if (pinfo & INSN_WRITE_GPR_31)
+ mips_gprmask |= 1 << RA;
+ if (pinfo & INSN_WRITE_FPR_D)
+ mips_cprmask[1] |= 1 << ((ip->insn_opcode >> OP_SH_FD) & OP_MASK_FD);
+ if ((pinfo & (INSN_WRITE_FPR_S | INSN_READ_FPR_S)) != 0)
+ mips_cprmask[1] |= 1 << ((ip->insn_opcode >> OP_SH_FS) & OP_MASK_FS);
+ if ((pinfo & (INSN_WRITE_FPR_T | INSN_READ_FPR_T)) != 0)
+ mips_cprmask[1] |= 1 << ((ip->insn_opcode >> OP_SH_FT) & OP_MASK_FT);
+ if ((pinfo & INSN_READ_FPR_R) != 0)
+ mips_cprmask[1] |= 1 << ((ip->insn_opcode >> OP_SH_FR) & OP_MASK_FR);
+ if (pinfo & INSN_COP)
+ {
+ /* We don't keep enough information to sort these cases out.
+ The itbl support does keep this information however, although
+ we currently don't support itbl fprmats as part of the cop
+ instruction. May want to add this support in the future. */
+ }
+ /* Never set the bit for $0, which is always zero. */
+ mips_gprmask &= ~1 << 0;
+ }
+ else
+ {
+ if (pinfo & (MIPS16_INSN_WRITE_X | MIPS16_INSN_READ_X))
+ mips_gprmask |= 1 << ((ip->insn_opcode >> MIPS16OP_SH_RX)
+ & MIPS16OP_MASK_RX);
+ if (pinfo & (MIPS16_INSN_WRITE_Y | MIPS16_INSN_READ_Y))
+ mips_gprmask |= 1 << ((ip->insn_opcode >> MIPS16OP_SH_RY)
+ & MIPS16OP_MASK_RY);
+ if (pinfo & MIPS16_INSN_WRITE_Z)
+ mips_gprmask |= 1 << ((ip->insn_opcode >> MIPS16OP_SH_RZ)
+ & MIPS16OP_MASK_RZ);
+ if (pinfo & (MIPS16_INSN_WRITE_T | MIPS16_INSN_READ_T))
+ mips_gprmask |= 1 << TREG;
+ if (pinfo & (MIPS16_INSN_WRITE_SP | MIPS16_INSN_READ_SP))
+ mips_gprmask |= 1 << SP;
+ if (pinfo & (MIPS16_INSN_WRITE_31 | MIPS16_INSN_READ_31))
+ mips_gprmask |= 1 << RA;
+ if (pinfo & MIPS16_INSN_WRITE_GPR_Y)
+ mips_gprmask |= 1 << MIPS16OP_EXTRACT_REG32R (ip->insn_opcode);
+ if (pinfo & MIPS16_INSN_READ_Z)
+ mips_gprmask |= 1 << ((ip->insn_opcode >> MIPS16OP_SH_MOVE32Z)
+ & MIPS16OP_MASK_MOVE32Z);
+ if (pinfo & MIPS16_INSN_READ_GPR_X)
+ mips_gprmask |= 1 << ((ip->insn_opcode >> MIPS16OP_SH_REGR32)
+ & MIPS16OP_MASK_REGR32);
+ }
+
+ if (mips_relax.sequence != 2 && !mips_opts.noreorder)
+ {
+ /* Filling the branch delay slot is more complex. We try to
+ switch the branch with the previous instruction, which we can
+ do if the previous instruction does not set up a condition
+ that the branch tests and if the branch is not itself the
+ target of any branch. */
+ if ((pinfo & INSN_UNCOND_BRANCH_DELAY)
+ || (pinfo & INSN_COND_BRANCH_DELAY))
+ {
+ if (mips_optimize < 2
+ /* If we have seen .set volatile or .set nomove, don't
+ optimize. */
+ || mips_opts.nomove != 0
+ /* If we had to emit any NOP instructions, then we
+ already know we can not swap. */
+ || nops != 0
+ /* If we don't even know the previous insn, we can not
+ swap. */
+ || ! prev_insn_valid
+ /* If the previous insn is already in a branch delay
+ slot, then we can not swap. */
+ || prev_insn_is_delay_slot
+ /* If the previous previous insn was in a .set
+ noreorder, we can't swap. Actually, the MIPS
+ assembler will swap in this situation. However, gcc
+ configured -with-gnu-as will generate code like
+ .set noreorder
+ lw $4,XXX
+ .set reorder
+ INSN
+ bne $4,$0,foo
+ in which we can not swap the bne and INSN. If gcc is
+ not configured -with-gnu-as, it does not output the
+ .set pseudo-ops. We don't have to check
+ prev_insn_unreordered, because prev_insn_valid will
+ be 0 in that case. We don't want to use
+ prev_prev_insn_valid, because we do want to be able
+ to swap at the start of a function. */
+ || prev_prev_insn_unreordered
+ /* If the branch is itself the target of a branch, we
+ can not swap. We cheat on this; all we check for is
+ whether there is a label on this instruction. If
+ there are any branches to anything other than a
+ label, users must use .set noreorder. */
+ || insn_labels != NULL
+ /* If the previous instruction is in a variant frag
+ other than this branch's one, we cannot do the swap.
+ This does not apply to the mips16, which uses variant
+ frags for different purposes. */
+ || (! mips_opts.mips16
+ && prev_insn_frag_type == rs_machine_dependent)
+ /* If the branch reads the condition codes, we don't
+ even try to swap, because in the sequence
+ ctc1 $X,$31
+ INSN
+ INSN
+ bc1t LABEL
+ we can not swap, and I don't feel like handling that
+ case. */
+ || (! mips_opts.mips16
+ && (pinfo & INSN_READ_COND_CODE)
+ && ! cop_interlocks)
+ /* We can not swap with an instruction that requires a
+ delay slot, because the target of the branch might
+ interfere with that instruction. */
+ || (! mips_opts.mips16
+ && (prev_pinfo
+ /* Itbl support may require additional care here. */
+ & (INSN_LOAD_COPROC_DELAY
+ | INSN_COPROC_MOVE_DELAY
+ | INSN_WRITE_COND_CODE))
+ && ! cop_interlocks)
+ || (! (hilo_interlocks
+ || (mips_opts.arch == CPU_R3900 && (pinfo & INSN_MULT)))
+ && (prev_pinfo
+ & (INSN_READ_LO
+ | INSN_READ_HI)))
+ || (! mips_opts.mips16
+ && (prev_pinfo & INSN_LOAD_MEMORY_DELAY)
+ && ! gpr_interlocks)
+ || (! mips_opts.mips16
+ /* Itbl support may require additional care here. */
+ && (prev_pinfo & INSN_COPROC_MEMORY_DELAY)
+ && ! cop_mem_interlocks)
+ /* We can not swap with a branch instruction. */
+ || (prev_pinfo
+ & (INSN_UNCOND_BRANCH_DELAY
+ | INSN_COND_BRANCH_DELAY
+ | INSN_COND_BRANCH_LIKELY))
+ /* We do not swap with a trap instruction, since it
+ complicates trap handlers to have the trap
+ instruction be in a delay slot. */
+ || (prev_pinfo & INSN_TRAP)
+ /* If the branch reads a register that the previous
+ instruction sets, we can not swap. */
+ || (! mips_opts.mips16
+ && (prev_pinfo & INSN_WRITE_GPR_T)
+ && insn_uses_reg (ip,
+ ((prev_insn.insn_opcode >> OP_SH_RT)
+ & OP_MASK_RT),
+ MIPS_GR_REG))
+ || (! mips_opts.mips16
+ && (prev_pinfo & INSN_WRITE_GPR_D)
+ && insn_uses_reg (ip,
+ ((prev_insn.insn_opcode >> OP_SH_RD)
+ & OP_MASK_RD),
+ MIPS_GR_REG))
+ || (mips_opts.mips16
+ && (((prev_pinfo & MIPS16_INSN_WRITE_X)
+ && insn_uses_reg (ip,
+ ((prev_insn.insn_opcode
+ >> MIPS16OP_SH_RX)
+ & MIPS16OP_MASK_RX),
+ MIPS16_REG))
+ || ((prev_pinfo & MIPS16_INSN_WRITE_Y)
+ && insn_uses_reg (ip,
+ ((prev_insn.insn_opcode
+ >> MIPS16OP_SH_RY)
+ & MIPS16OP_MASK_RY),
+ MIPS16_REG))
+ || ((prev_pinfo & MIPS16_INSN_WRITE_Z)
+ && insn_uses_reg (ip,
+ ((prev_insn.insn_opcode
+ >> MIPS16OP_SH_RZ)
+ & MIPS16OP_MASK_RZ),
+ MIPS16_REG))
+ || ((prev_pinfo & MIPS16_INSN_WRITE_T)
+ && insn_uses_reg (ip, TREG, MIPS_GR_REG))
+ || ((prev_pinfo & MIPS16_INSN_WRITE_31)
+ && insn_uses_reg (ip, RA, MIPS_GR_REG))
+ || ((prev_pinfo & MIPS16_INSN_WRITE_GPR_Y)
+ && insn_uses_reg (ip,
+ MIPS16OP_EXTRACT_REG32R (prev_insn.
+ insn_opcode),
+ MIPS_GR_REG))))
+ /* If the branch writes a register that the previous
+ instruction sets, we can not swap (we know that
+ branches write only to RD or to $31). */
+ || (! mips_opts.mips16
+ && (prev_pinfo & INSN_WRITE_GPR_T)
+ && (((pinfo & INSN_WRITE_GPR_D)
+ && (((prev_insn.insn_opcode >> OP_SH_RT) & OP_MASK_RT)
+ == ((ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD)))
+ || ((pinfo & INSN_WRITE_GPR_31)
+ && (((prev_insn.insn_opcode >> OP_SH_RT)
+ & OP_MASK_RT)
+ == RA))))
+ || (! mips_opts.mips16
+ && (prev_pinfo & INSN_WRITE_GPR_D)
+ && (((pinfo & INSN_WRITE_GPR_D)
+ && (((prev_insn.insn_opcode >> OP_SH_RD) & OP_MASK_RD)
+ == ((ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD)))
+ || ((pinfo & INSN_WRITE_GPR_31)
+ && (((prev_insn.insn_opcode >> OP_SH_RD)
+ & OP_MASK_RD)
+ == RA))))
+ || (mips_opts.mips16
+ && (pinfo & MIPS16_INSN_WRITE_31)
+ && ((prev_pinfo & MIPS16_INSN_WRITE_31)
+ || ((prev_pinfo & MIPS16_INSN_WRITE_GPR_Y)
+ && (MIPS16OP_EXTRACT_REG32R (prev_insn.insn_opcode)
+ == RA))))
+ /* If the branch writes a register that the previous
+ instruction reads, we can not swap (we know that
+ branches only write to RD or to $31). */
+ || (! mips_opts.mips16
+ && (pinfo & INSN_WRITE_GPR_D)
+ && insn_uses_reg (&prev_insn,
+ ((ip->insn_opcode >> OP_SH_RD)
+ & OP_MASK_RD),
+ MIPS_GR_REG))
+ || (! mips_opts.mips16
+ && (pinfo & INSN_WRITE_GPR_31)
+ && insn_uses_reg (&prev_insn, RA, MIPS_GR_REG))
+ || (mips_opts.mips16
+ && (pinfo & MIPS16_INSN_WRITE_31)
+ && insn_uses_reg (&prev_insn, RA, MIPS_GR_REG))
+ /* If we are generating embedded PIC code, the branch
+ might be expanded into a sequence which uses $at, so
+ we can't swap with an instruction which reads it. */
+ || (mips_pic == EMBEDDED_PIC
+ && insn_uses_reg (&prev_insn, AT, MIPS_GR_REG))
+ /* If the previous previous instruction has a load
+ delay, and sets a register that the branch reads, we
+ can not swap. */
+ || (! mips_opts.mips16
+ /* Itbl support may require additional care here. */
+ && (((prev_prev_insn.insn_mo->pinfo & INSN_LOAD_COPROC_DELAY)
+ && ! cop_interlocks)
+ || ((prev_prev_insn.insn_mo->pinfo
+ & INSN_LOAD_MEMORY_DELAY)
+ && ! gpr_interlocks))
+ && insn_uses_reg (ip,
+ ((prev_prev_insn.insn_opcode >> OP_SH_RT)
+ & OP_MASK_RT),
+ MIPS_GR_REG))
+ /* If one instruction sets a condition code and the
+ other one uses a condition code, we can not swap. */
+ || ((pinfo & INSN_READ_COND_CODE)
+ && (prev_pinfo & INSN_WRITE_COND_CODE))
+ || ((pinfo & INSN_WRITE_COND_CODE)
+ && (prev_pinfo & INSN_READ_COND_CODE))
+ /* If the previous instruction uses the PC, we can not
+ swap. */
+ || (mips_opts.mips16
+ && (prev_pinfo & MIPS16_INSN_READ_PC))
+ /* If the previous instruction was extended, we can not
+ swap. */
+ || (mips_opts.mips16 && prev_insn_extended)
+ /* If the previous instruction had a fixup in mips16
+ mode, we can not swap. This normally means that the
+ previous instruction was a 4 byte branch anyhow. */
+ || (mips_opts.mips16 && prev_insn_fixp[0])
+ /* If the previous instruction is a sync, sync.l, or
+ sync.p, we can not swap. */
+ || (prev_pinfo & INSN_SYNC))
+ {
+ /* We could do even better for unconditional branches to
+ portions of this object file; we could pick up the
+ instruction at the destination, put it in the delay
+ slot, and bump the destination address. */
+ emit_nop ();
+ /* Update the previous insn information. */
+ prev_prev_insn = *ip;
+ prev_insn.insn_mo = &dummy_opcode;
+ }
+ else
+ {
+ /* It looks like we can actually do the swap. */
+ if (! mips_opts.mips16)
+ {
+ char *prev_f;
+ char temp[4];
+
+ prev_f = prev_insn_frag->fr_literal + prev_insn_where;
+ if (!relaxed_branch)
+ {
+ /* If this is not a relaxed branch, then just
+ swap the instructions. */
+ memcpy (temp, prev_f, 4);
+ memcpy (prev_f, f, 4);
+ memcpy (f, temp, 4);
+ }
+ else
+ {
+ /* If this is a relaxed branch, then we move the
+ instruction to be placed in the delay slot to
+ the current frag, shrinking the fixed part of
+ the originating frag. If the branch occupies
+ the tail of the latter, we move it backwards,
+ into the space freed by the moved instruction. */
+ f = frag_more (4);
+ memcpy (f, prev_f, 4);
+ prev_insn_frag->fr_fix -= 4;
+ if (prev_insn_frag->fr_type == rs_machine_dependent)
+ memmove (prev_f, prev_f + 4, prev_insn_frag->fr_var);
+ }
+
+ if (prev_insn_fixp[0])
+ {
+ prev_insn_fixp[0]->fx_frag = frag_now;
+ prev_insn_fixp[0]->fx_where = f - frag_now->fr_literal;
+ }
+ if (prev_insn_fixp[1])
+ {
+ prev_insn_fixp[1]->fx_frag = frag_now;
+ prev_insn_fixp[1]->fx_where = f - frag_now->fr_literal;
+ }
+ if (prev_insn_fixp[2])
+ {
+ prev_insn_fixp[2]->fx_frag = frag_now;
+ prev_insn_fixp[2]->fx_where = f - frag_now->fr_literal;
+ }
+ if (prev_insn_fixp[0] && HAVE_NEWABI
+ && prev_insn_frag != frag_now
+ && (prev_insn_fixp[0]->fx_r_type
+ == BFD_RELOC_MIPS_GOT_DISP
+ || (prev_insn_fixp[0]->fx_r_type
+ == BFD_RELOC_MIPS_CALL16)))
+ {
+ /* To avoid confusion in tc_gen_reloc, we must
+ ensure that this does not become a variant
+ frag. */
+ force_new_frag = TRUE;
+ }
+
+ if (!relaxed_branch)
+ {
+ if (fixp[0])
+ {
+ fixp[0]->fx_frag = prev_insn_frag;
+ fixp[0]->fx_where = prev_insn_where;
+ }
+ if (fixp[1])
+ {
+ fixp[1]->fx_frag = prev_insn_frag;
+ fixp[1]->fx_where = prev_insn_where;
+ }
+ if (fixp[2])
+ {
+ fixp[2]->fx_frag = prev_insn_frag;
+ fixp[2]->fx_where = prev_insn_where;
+ }
+ }
+ else if (prev_insn_frag->fr_type == rs_machine_dependent)
+ {
+ if (fixp[0])
+ fixp[0]->fx_where -= 4;
+ if (fixp[1])
+ fixp[1]->fx_where -= 4;
+ if (fixp[2])
+ fixp[2]->fx_where -= 4;
+ }
+ }
+ else
+ {
+ char *prev_f;
+ char temp[2];
+
+ assert (prev_insn_fixp[0] == NULL);
+ assert (prev_insn_fixp[1] == NULL);
+ assert (prev_insn_fixp[2] == NULL);
+ prev_f = prev_insn_frag->fr_literal + prev_insn_where;
+ memcpy (temp, prev_f, 2);
+ memcpy (prev_f, f, 2);
+ if (*reloc_type != BFD_RELOC_MIPS16_JMP)
+ {
+ assert (*reloc_type == BFD_RELOC_UNUSED);
+ memcpy (f, temp, 2);
+ }
+ else
+ {
+ memcpy (f, f + 2, 2);
+ memcpy (f + 2, temp, 2);
+ }
+ if (fixp[0])
+ {
+ fixp[0]->fx_frag = prev_insn_frag;
+ fixp[0]->fx_where = prev_insn_where;
+ }
+ if (fixp[1])
+ {
+ fixp[1]->fx_frag = prev_insn_frag;
+ fixp[1]->fx_where = prev_insn_where;
+ }
+ if (fixp[2])
+ {
+ fixp[2]->fx_frag = prev_insn_frag;
+ fixp[2]->fx_where = prev_insn_where;
+ }
+ }
+
+ /* Update the previous insn information; leave prev_insn
+ unchanged. */
+ prev_prev_insn = *ip;
+ }
+ prev_insn_is_delay_slot = 1;
+
+ /* If that was an unconditional branch, forget the previous
+ insn information. */
+ if (pinfo & INSN_UNCOND_BRANCH_DELAY)
+ {
+ prev_prev_insn.insn_mo = &dummy_opcode;
+ prev_insn.insn_mo = &dummy_opcode;
+ }
+
+ prev_insn_fixp[0] = NULL;
+ prev_insn_fixp[1] = NULL;
+ prev_insn_fixp[2] = NULL;
+ prev_insn_reloc_type[0] = BFD_RELOC_UNUSED;
+ prev_insn_reloc_type[1] = BFD_RELOC_UNUSED;
+ prev_insn_reloc_type[2] = BFD_RELOC_UNUSED;
+ prev_insn_extended = 0;
+ }
+ else if (pinfo & INSN_COND_BRANCH_LIKELY)
+ {
+ /* We don't yet optimize a branch likely. What we should do
+ is look at the target, copy the instruction found there
+ into the delay slot, and increment the branch to jump to
+ the next instruction. */
+ emit_nop ();
+ /* Update the previous insn information. */
+ prev_prev_insn = *ip;
+ prev_insn.insn_mo = &dummy_opcode;
+ prev_insn_fixp[0] = NULL;
+ prev_insn_fixp[1] = NULL;
+ prev_insn_fixp[2] = NULL;
+ prev_insn_reloc_type[0] = BFD_RELOC_UNUSED;
+ prev_insn_reloc_type[1] = BFD_RELOC_UNUSED;
+ prev_insn_reloc_type[2] = BFD_RELOC_UNUSED;
+ prev_insn_extended = 0;
+ }
+ else
+ {
+ /* Update the previous insn information. */
+ if (nops > 0)
+ prev_prev_insn.insn_mo = &dummy_opcode;
+ else
+ prev_prev_insn = prev_insn;
+ prev_insn = *ip;
+
+ /* Any time we see a branch, we always fill the delay slot
+ immediately; since this insn is not a branch, we know it
+ is not in a delay slot. */
+ prev_insn_is_delay_slot = 0;
+
+ prev_insn_fixp[0] = fixp[0];
+ prev_insn_fixp[1] = fixp[1];
+ prev_insn_fixp[2] = fixp[2];
+ prev_insn_reloc_type[0] = reloc_type[0];
+ prev_insn_reloc_type[1] = reloc_type[1];
+ prev_insn_reloc_type[2] = reloc_type[2];
+ if (mips_opts.mips16)
+ prev_insn_extended = (ip->use_extend
+ || *reloc_type > BFD_RELOC_UNUSED);
+ }
+
+ prev_prev_insn_unreordered = prev_insn_unreordered;
+ prev_insn_unreordered = 0;
+ prev_insn_frag = frag_now;
+ prev_insn_where = f - frag_now->fr_literal;
+ prev_insn_valid = 1;
+ }
+ else if (mips_relax.sequence != 2)
+ {
+ /* We need to record a bit of information even when we are not
+ reordering, in order to determine the base address for mips16
+ PC relative relocs. */
+ prev_prev_insn = prev_insn;
+ prev_insn = *ip;
+ prev_insn_reloc_type[0] = reloc_type[0];
+ prev_insn_reloc_type[1] = reloc_type[1];
+ prev_insn_reloc_type[2] = reloc_type[2];
+ prev_prev_insn_unreordered = prev_insn_unreordered;
+ prev_insn_unreordered = 1;
+ }
+
+ /* We just output an insn, so the next one doesn't have a label. */
+ mips_clear_insn_labels ();
+}
+
+/* This function forgets that there was any previous instruction or
+ label. If PRESERVE is non-zero, it remembers enough information to
+ know whether nops are needed before a noreorder section. */
+
+static void
+mips_no_prev_insn (int preserve)
+{
+ if (! preserve)
+ {
+ prev_insn.insn_mo = &dummy_opcode;
+ prev_prev_insn.insn_mo = &dummy_opcode;
+ prev_nop_frag = NULL;
+ prev_nop_frag_holds = 0;
+ prev_nop_frag_required = 0;
+ prev_nop_frag_since = 0;
+ }
+ prev_insn_valid = 0;
+ prev_insn_is_delay_slot = 0;
+ prev_insn_unreordered = 0;
+ prev_insn_extended = 0;
+ prev_insn_reloc_type[0] = BFD_RELOC_UNUSED;
+ prev_insn_reloc_type[1] = BFD_RELOC_UNUSED;
+ prev_insn_reloc_type[2] = BFD_RELOC_UNUSED;
+ prev_prev_insn_unreordered = 0;
+ mips_clear_insn_labels ();
+}
+
+/* This function must be called whenever we turn on noreorder or emit
+ something other than instructions. It inserts any NOPS which might
+ be needed by the previous instruction, and clears the information
+ kept for the previous instructions. The INSNS parameter is true if
+ instructions are to follow. */
+
+static void
+mips_emit_delays (bfd_boolean insns)
+{
+ if (! mips_opts.noreorder)
+ {
+ int nops;
+
+ nops = 0;
+ if ((! mips_opts.mips16
+ && ((prev_insn.insn_mo->pinfo
+ & (INSN_LOAD_COPROC_DELAY
+ | INSN_COPROC_MOVE_DELAY
+ | INSN_WRITE_COND_CODE))
+ && ! cop_interlocks))
+ || (! hilo_interlocks
+ && (prev_insn.insn_mo->pinfo
+ & (INSN_READ_LO
+ | INSN_READ_HI)))
+ || (! mips_opts.mips16
+ && (prev_insn.insn_mo->pinfo & INSN_LOAD_MEMORY_DELAY)
+ && ! gpr_interlocks)
+ || (! mips_opts.mips16
+ && (prev_insn.insn_mo->pinfo & INSN_COPROC_MEMORY_DELAY)
+ && ! cop_mem_interlocks))
+ {
+ /* Itbl support may require additional care here. */
+ ++nops;
+ if ((! mips_opts.mips16
+ && ((prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE)
+ && ! cop_interlocks))
+ || (! hilo_interlocks
+ && ((prev_insn.insn_mo->pinfo & INSN_READ_HI)
+ || (prev_insn.insn_mo->pinfo & INSN_READ_LO))))
+ ++nops;
+
+ if (prev_insn_unreordered)
+ nops = 0;
+ }
+ else if ((! mips_opts.mips16
+ && ((prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE)
+ && ! cop_interlocks))
+ || (! hilo_interlocks
+ && ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
+ || (prev_prev_insn.insn_mo->pinfo & INSN_READ_LO))))
+ {
+ /* Itbl support may require additional care here. */
+ if (! prev_prev_insn_unreordered)
+ ++nops;
+ }
+
+ if (mips_fix_vr4120 && prev_insn.insn_mo->name)
+ {
+ int min_nops = 0;
+ const char *pn = prev_insn.insn_mo->name;
+ if (strncmp(pn, "macc", 4) == 0
+ || strncmp(pn, "dmacc", 5) == 0
+ || strncmp(pn, "dmult", 5) == 0)
+ {
+ min_nops = 1;
+ }
+ if (nops < min_nops)
+ nops = min_nops;
+ }
+
+ if (nops > 0)
+ {
+ struct insn_label_list *l;
+
+ if (insns)
+ {
+ /* Record the frag which holds the nop instructions, so
+ that we can remove them if we don't need them. */
+ frag_grow (mips_opts.mips16 ? nops * 2 : nops * 4);
+ prev_nop_frag = frag_now;
+ prev_nop_frag_holds = nops;
+ prev_nop_frag_required = 0;
+ prev_nop_frag_since = 0;
+ }
+
+ for (; nops > 0; --nops)
+ emit_nop ();
+
+ if (insns)
+ {
+ /* Move on to a new frag, so that it is safe to simply
+ decrease the size of prev_nop_frag. */
+ frag_wane (frag_now);
+ frag_new (0);
+ }
+
+ for (l = insn_labels; l != NULL; l = l->next)
+ {
+ valueT val;
+
+ assert (S_GET_SEGMENT (l->label) == now_seg);
+ symbol_set_frag (l->label, frag_now);
+ val = (valueT) frag_now_fix ();
+ /* mips16 text labels are stored as odd. */
+ if (mips_opts.mips16)
+ ++val;
+ S_SET_VALUE (l->label, val);
+ }
+ }
+ }
+
+ /* Mark instruction labels in mips16 mode. */
+ if (insns)
+ mips16_mark_labels ();
+
+ mips_no_prev_insn (insns);
+}
+
+/* Set up global variables for the start of a new macro. */
+
+static void
+macro_start (void)
+{
+ memset (&mips_macro_warning.sizes, 0, sizeof (mips_macro_warning.sizes));
+ mips_macro_warning.delay_slot_p = (mips_opts.noreorder
+ && (prev_insn.insn_mo->pinfo
+ & (INSN_UNCOND_BRANCH_DELAY
+ | INSN_COND_BRANCH_DELAY
+ | INSN_COND_BRANCH_LIKELY)) != 0);
+}
+
+/* Given that a macro is longer than 4 bytes, return the appropriate warning
+ for it. Return null if no warning is needed. SUBTYPE is a bitmask of
+ RELAX_DELAY_SLOT and RELAX_NOMACRO. */
+
+static const char *
+macro_warning (relax_substateT subtype)
+{
+ if (subtype & RELAX_DELAY_SLOT)
+ return _("Macro instruction expanded into multiple instructions"
+ " in a branch delay slot");
+ else if (subtype & RELAX_NOMACRO)
+ return _("Macro instruction expanded into multiple instructions");
+ else
+ return 0;
+}
+
+/* Finish up a macro. Emit warnings as appropriate. */
+
+static void
+macro_end (void)
+{
+ if (mips_macro_warning.sizes[0] > 4 || mips_macro_warning.sizes[1] > 4)
+ {
+ relax_substateT subtype;
+
+ /* Set up the relaxation warning flags. */
+ subtype = 0;
+ if (mips_macro_warning.sizes[1] > mips_macro_warning.sizes[0])
+ subtype |= RELAX_SECOND_LONGER;
+ if (mips_opts.warn_about_macros)
+ subtype |= RELAX_NOMACRO;
+ if (mips_macro_warning.delay_slot_p)
+ subtype |= RELAX_DELAY_SLOT;
+
+ if (mips_macro_warning.sizes[0] > 4 && mips_macro_warning.sizes[1] > 4)
+ {
+ /* Either the macro has a single implementation or both
+ implementations are longer than 4 bytes. Emit the
+ warning now. */
+ const char *msg = macro_warning (subtype);
+ if (msg != 0)
+ as_warn (msg);
+ }
+ else
+ {
+ /* One implementation might need a warning but the other
+ definitely doesn't. */
+ mips_macro_warning.first_frag->fr_subtype |= subtype;
+ }
+ }
+}
+
+/* Build an instruction created by a macro expansion. This is passed
+ a pointer to the count of instructions created so far, an
+ expression, the name of the instruction to build, an operand format
+ string, and corresponding arguments. */
+
+static void
+macro_build (expressionS *ep, const char *name, const char *fmt, ...)
+{
+ struct mips_cl_insn insn;
+ bfd_reloc_code_real_type r[3];
+ va_list args;
+
+ va_start (args, fmt);
+
+ if (mips_opts.mips16)
+ {
+ mips16_macro_build (ep, name, fmt, args);
+ va_end (args);
+ return;
+ }
+
+ r[0] = BFD_RELOC_UNUSED;
+ r[1] = BFD_RELOC_UNUSED;
+ r[2] = BFD_RELOC_UNUSED;
+ insn.insn_mo = (struct mips_opcode *) hash_find (op_hash, name);
+ assert (insn.insn_mo);
+ assert (strcmp (name, insn.insn_mo->name) == 0);
+
+ /* Search until we get a match for NAME. */
+ while (1)
+ {
+ /* It is assumed here that macros will never generate
+ MDMX or MIPS-3D instructions. */
+ if (strcmp (fmt, insn.insn_mo->args) == 0
+ && insn.insn_mo->pinfo != INSN_MACRO
+ && OPCODE_IS_MEMBER (insn.insn_mo,
+ (mips_opts.isa
+ | (file_ase_mips16 ? INSN_MIPS16 : 0)),
+ mips_opts.arch)
+ && (mips_opts.arch != CPU_R4650 || (insn.insn_mo->pinfo & FP_D) == 0))
+ break;
+
+ ++insn.insn_mo;
+ assert (insn.insn_mo->name);
+ assert (strcmp (name, insn.insn_mo->name) == 0);
+ }
+
+ insn.insn_opcode = insn.insn_mo->match;
+ for (;;)
+ {
+ switch (*fmt++)
+ {
+ case '\0':
+ break;
+
+ case ',':
+ case '(':
+ case ')':
+ continue;
+
+ case '+':
+ switch (*fmt++)
+ {
+ case 'A':
+ case 'E':
+ insn.insn_opcode |= (va_arg (args, int)
+ & OP_MASK_SHAMT) << OP_SH_SHAMT;
+ continue;
+
+ case 'B':
+ case 'F':
+ /* Note that in the macro case, these arguments are already
+ in MSB form. (When handling the instruction in the
+ non-macro case, these arguments are sizes from which
+ MSB values must be calculated.) */
+ insn.insn_opcode |= (va_arg (args, int)
+ & OP_MASK_INSMSB) << OP_SH_INSMSB;
+ continue;
+
+ case 'C':
+ case 'G':
+ case 'H':
+ /* Note that in the macro case, these arguments are already
+ in MSBD form. (When handling the instruction in the
+ non-macro case, these arguments are sizes from which
+ MSBD values must be calculated.) */
+ insn.insn_opcode |= (va_arg (args, int)
+ & OP_MASK_EXTMSBD) << OP_SH_EXTMSBD;
+ continue;
+
+ default:
+ internalError ();
+ }
+ continue;
+
+ case 't':
+ case 'w':
+ case 'E':
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_RT;
+ continue;
+
+ case 'c':
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_CODE;
+ continue;
+
+ case 'T':
+ case 'W':
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_FT;
+ continue;
+
+ case 'd':
+ case 'G':
+ case 'K':
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_RD;
+ continue;
+
+ case 'U':
+ {
+ int tmp = va_arg (args, int);
+
+ insn.insn_opcode |= tmp << OP_SH_RT;
+ insn.insn_opcode |= tmp << OP_SH_RD;
+ continue;
+ }
+
+ case 'V':
+ case 'S':
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_FS;
+ continue;
+
+ case 'z':
+ continue;
+
+ case '<':
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_SHAMT;
+ continue;
+
+ case 'D':
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_FD;
+ continue;
+
+ case 'B':
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_CODE20;
+ continue;
+
+ case 'J':
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_CODE19;
+ continue;
+
+ case 'q':
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_CODE2;
+ continue;
+
+ case 'b':
+ case 's':
+ case 'r':
+ case 'v':
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_RS;
+ continue;
+
+ case 'i':
+ case 'j':
+ case 'o':
+ *r = (bfd_reloc_code_real_type) va_arg (args, int);
+ assert (*r == BFD_RELOC_GPREL16
+ || *r == BFD_RELOC_MIPS_LITERAL
+ || *r == BFD_RELOC_MIPS_HIGHER
+ || *r == BFD_RELOC_HI16_S
+ || *r == BFD_RELOC_LO16
+ || *r == BFD_RELOC_MIPS_GOT16
+ || *r == BFD_RELOC_MIPS_CALL16
+ || *r == BFD_RELOC_MIPS_GOT_DISP
+ || *r == BFD_RELOC_MIPS_GOT_PAGE
+ || *r == BFD_RELOC_MIPS_GOT_OFST
+ || *r == BFD_RELOC_MIPS_GOT_LO16
+ || *r == BFD_RELOC_MIPS_CALL_LO16
+ || (ep->X_op == O_subtract
+ && *r == BFD_RELOC_PCREL_LO16));
+ continue;
+
+ case 'u':
+ *r = (bfd_reloc_code_real_type) va_arg (args, int);
+ assert (ep != NULL
+ && (ep->X_op == O_constant
+ || (ep->X_op == O_symbol
+ && (*r == BFD_RELOC_MIPS_HIGHEST
+ || *r == BFD_RELOC_HI16_S
+ || *r == BFD_RELOC_HI16
+ || *r == BFD_RELOC_GPREL16
+ || *r == BFD_RELOC_MIPS_GOT_HI16
+ || *r == BFD_RELOC_MIPS_CALL_HI16))
+ || (ep->X_op == O_subtract
+ && *r == BFD_RELOC_PCREL_HI16_S)));
+ continue;
+
+ case 'p':
+ assert (ep != NULL);
+ /*
+ * This allows macro() to pass an immediate expression for
+ * creating short branches without creating a symbol.
+ * Note that the expression still might come from the assembly
+ * input, in which case the value is not checked for range nor
+ * is a relocation entry generated (yuck).
+ */
+ if (ep->X_op == O_constant)
+ {
+ insn.insn_opcode |= (ep->X_add_number >> 2) & 0xffff;
+ ep = NULL;
+ }
+ else
+ *r = BFD_RELOC_16_PCREL_S2;
+ continue;
+
+ case 'a':
+ assert (ep != NULL);
+ *r = BFD_RELOC_MIPS_JMP;
+ continue;
+
+ case 'C':
+ insn.insn_opcode |= va_arg (args, unsigned long);
+ continue;
+
+ default:
+ internalError ();
+ }
+ break;
+ }
+ va_end (args);
+ assert (*r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
+
+ append_insn (&insn, ep, r);
+}
+
+static void
+mips16_macro_build (expressionS *ep, const char *name, const char *fmt,
+ va_list args)
+{
+ struct mips_cl_insn insn;
+ bfd_reloc_code_real_type r[3]
+ = {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
+
+ insn.insn_mo = (struct mips_opcode *) hash_find (mips16_op_hash, name);
+ assert (insn.insn_mo);
+ assert (strcmp (name, insn.insn_mo->name) == 0);
+
+ while (strcmp (fmt, insn.insn_mo->args) != 0
+ || insn.insn_mo->pinfo == INSN_MACRO)
+ {
+ ++insn.insn_mo;
+ assert (insn.insn_mo->name);
+ assert (strcmp (name, insn.insn_mo->name) == 0);
+ }
+
+ insn.insn_opcode = insn.insn_mo->match;
+ insn.use_extend = FALSE;
+
+ for (;;)
+ {
+ int c;
+
+ c = *fmt++;
+ switch (c)
+ {
+ case '\0':
+ break;
+
+ case ',':
+ case '(':
+ case ')':
+ continue;
+
+ case 'y':
+ case 'w':
+ insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_RY;
+ continue;
+
+ case 'x':
+ case 'v':
+ insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_RX;
+ continue;
+
+ case 'z':
+ insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_RZ;
+ continue;
+
+ case 'Z':
+ insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_MOVE32Z;
+ continue;
+
+ case '0':
+ case 'S':
+ case 'P':
+ case 'R':
+ continue;
+
+ case 'X':
+ insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_REGR32;
+ continue;
+
+ case 'Y':
+ {
+ int regno;
+
+ regno = va_arg (args, int);
+ regno = ((regno & 7) << 2) | ((regno & 0x18) >> 3);
+ insn.insn_opcode |= regno << MIPS16OP_SH_REG32R;
+ }
+ continue;
+
+ case '<':
+ case '>':
+ case '4':
+ case '5':
+ case 'H':
+ case 'W':
+ case 'D':
+ case 'j':
+ case '8':
+ case 'V':
+ case 'C':
+ case 'U':
+ case 'k':
+ case 'K':
+ case 'p':
+ case 'q':
+ {
+ assert (ep != NULL);
+
+ if (ep->X_op != O_constant)
+ *r = (int) BFD_RELOC_UNUSED + c;
+ else
+ {
+ mips16_immed (NULL, 0, c, ep->X_add_number, FALSE, FALSE,
+ FALSE, &insn.insn_opcode, &insn.use_extend,
+ &insn.extend);
+ ep = NULL;
+ *r = BFD_RELOC_UNUSED;
+ }
+ }
+ continue;
+
+ case '6':
+ insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_IMM6;
+ continue;
+ }
+
+ break;
+ }
+
+ assert (*r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
+
+ append_insn (&insn, ep, r);
+}
+
+/*
+ * Generate a "jalr" instruction with a relocation hint to the called
+ * function. This occurs in NewABI PIC code.
+ */
+static void
+macro_build_jalr (expressionS *ep)
+{
+ char *f = NULL;
+
+ if (HAVE_NEWABI)
+ {
+ frag_grow (8);
+ f = frag_more (0);
+ }
+ macro_build (NULL, "jalr", "d,s", RA, PIC_CALL_REG);
+ if (HAVE_NEWABI)
+ fix_new_exp (frag_now, f - frag_now->fr_literal,
+ 4, ep, FALSE, BFD_RELOC_MIPS_JALR);
+}
+
+/*
+ * Generate a "lui" instruction.
+ */
+static void
+macro_build_lui (expressionS *ep, int regnum)
+{
+ expressionS high_expr;
+ struct mips_cl_insn insn;
+ bfd_reloc_code_real_type r[3]
+ = {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
+ const char *name = "lui";
+ const char *fmt = "t,u";
+
+ assert (! mips_opts.mips16);
+
+ high_expr = *ep;
+
+ if (high_expr.X_op == O_constant)
+ {
+ /* we can compute the instruction now without a relocation entry */
+ high_expr.X_add_number = ((high_expr.X_add_number + 0x8000)
+ >> 16) & 0xffff;
+ *r = BFD_RELOC_UNUSED;
+ }
+ else
+ {
+ assert (ep->X_op == O_symbol);
+ /* _gp_disp is a special case, used from s_cpload. */
+ assert (mips_pic == NO_PIC
+ || (! HAVE_NEWABI
+ && strcmp (S_GET_NAME (ep->X_add_symbol), "_gp_disp") == 0));
+ *r = BFD_RELOC_HI16_S;
+ }
+
+ insn.insn_mo = (struct mips_opcode *) hash_find (op_hash, name);
+ assert (insn.insn_mo);
+ assert (strcmp (name, insn.insn_mo->name) == 0);
+ assert (strcmp (fmt, insn.insn_mo->args) == 0);
+
+ insn.insn_opcode = insn.insn_mo->match | (regnum << OP_SH_RT);
+ if (*r == BFD_RELOC_UNUSED)
+ {
+ insn.insn_opcode |= high_expr.X_add_number;
+ append_insn (&insn, NULL, r);
+ }
+ else
+ append_insn (&insn, &high_expr, r);
+}
+
+/* Generate a sequence of instructions to do a load or store from a constant
+ offset off of a base register (breg) into/from a target register (treg),
+ using AT if necessary. */
+static void
+macro_build_ldst_constoffset (expressionS *ep, const char *op,
+ int treg, int breg, int dbl)
+{
+ assert (ep->X_op == O_constant);
+
+ /* Sign-extending 32-bit constants makes their handling easier. */
+ if (! dbl && ! ((ep->X_add_number & ~((bfd_vma) 0x7fffffff))
+ == ~((bfd_vma) 0x7fffffff)))
+ {
+ if (ep->X_add_number & ~((bfd_vma) 0xffffffff))
+ as_bad (_("constant too large"));
+
+ ep->X_add_number = (((ep->X_add_number & 0xffffffff) ^ 0x80000000)
+ - 0x80000000);
+ }
+
+ /* Right now, this routine can only handle signed 32-bit constants. */
+ if (! IS_SEXT_32BIT_NUM(ep->X_add_number + 0x8000))
+ as_warn (_("operand overflow"));
+
+ if (IS_SEXT_16BIT_NUM(ep->X_add_number))
+ {
+ /* Signed 16-bit offset will fit in the op. Easy! */
+ macro_build (ep, op, "t,o(b)", treg, BFD_RELOC_LO16, breg);
+ }
+ else
+ {
+ /* 32-bit offset, need multiple instructions and AT, like:
+ lui $tempreg,const_hi (BFD_RELOC_HI16_S)
+ addu $tempreg,$tempreg,$breg
+ <op> $treg,const_lo($tempreg) (BFD_RELOC_LO16)
+ to handle the complete offset. */
+ macro_build_lui (ep, AT);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", AT, AT, breg);
+ macro_build (ep, op, "t,o(b)", treg, BFD_RELOC_LO16, AT);
+
+ if (mips_opts.noat)
+ as_warn (_("Macro used $at after \".set noat\""));
+ }
+}
+
+/* set_at()
+ * Generates code to set the $at register to true (one)
+ * if reg is less than the immediate expression.
+ */
+static void
+set_at (int reg, int unsignedp)
+{
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= -0x8000
+ && imm_expr.X_add_number < 0x8000)
+ macro_build (&imm_expr, unsignedp ? "sltiu" : "slti", "t,r,j",
+ AT, reg, BFD_RELOC_LO16);
+ else
+ {
+ load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ macro_build (NULL, unsignedp ? "sltu" : "slt", "d,v,t", AT, reg, AT);
+ }
+}
+
+static void
+normalize_constant_expr (expressionS *ex)
+{
+ if (ex->X_op == O_constant && HAVE_32BIT_GPRS)
+ ex->X_add_number = (((ex->X_add_number & 0xffffffff) ^ 0x80000000)
+ - 0x80000000);
+}
+
+/* Warn if an expression is not a constant. */
+
+static void
+check_absolute_expr (struct mips_cl_insn *ip, expressionS *ex)
+{
+ if (ex->X_op == O_big)
+ as_bad (_("unsupported large constant"));
+ else if (ex->X_op != O_constant)
+ as_bad (_("Instruction %s requires absolute expression"), ip->insn_mo->name);
+
+ normalize_constant_expr (ex);
+}
+
+/* Count the leading zeroes by performing a binary chop. This is a
+ bulky bit of source, but performance is a LOT better for the
+ majority of values than a simple loop to count the bits:
+ for (lcnt = 0; (lcnt < 32); lcnt++)
+ if ((v) & (1 << (31 - lcnt)))
+ break;
+ However it is not code size friendly, and the gain will drop a bit
+ on certain cached systems.
+*/
+#define COUNT_TOP_ZEROES(v) \
+ (((v) & ~0xffff) == 0 \
+ ? ((v) & ~0xff) == 0 \
+ ? ((v) & ~0xf) == 0 \
+ ? ((v) & ~0x3) == 0 \
+ ? ((v) & ~0x1) == 0 \
+ ? !(v) \
+ ? 32 \
+ : 31 \
+ : 30 \
+ : ((v) & ~0x7) == 0 \
+ ? 29 \
+ : 28 \
+ : ((v) & ~0x3f) == 0 \
+ ? ((v) & ~0x1f) == 0 \
+ ? 27 \
+ : 26 \
+ : ((v) & ~0x7f) == 0 \
+ ? 25 \
+ : 24 \
+ : ((v) & ~0xfff) == 0 \
+ ? ((v) & ~0x3ff) == 0 \
+ ? ((v) & ~0x1ff) == 0 \
+ ? 23 \
+ : 22 \
+ : ((v) & ~0x7ff) == 0 \
+ ? 21 \
+ : 20 \
+ : ((v) & ~0x3fff) == 0 \
+ ? ((v) & ~0x1fff) == 0 \
+ ? 19 \
+ : 18 \
+ : ((v) & ~0x7fff) == 0 \
+ ? 17 \
+ : 16 \
+ : ((v) & ~0xffffff) == 0 \
+ ? ((v) & ~0xfffff) == 0 \
+ ? ((v) & ~0x3ffff) == 0 \
+ ? ((v) & ~0x1ffff) == 0 \
+ ? 15 \
+ : 14 \
+ : ((v) & ~0x7ffff) == 0 \
+ ? 13 \
+ : 12 \
+ : ((v) & ~0x3fffff) == 0 \
+ ? ((v) & ~0x1fffff) == 0 \
+ ? 11 \
+ : 10 \
+ : ((v) & ~0x7fffff) == 0 \
+ ? 9 \
+ : 8 \
+ : ((v) & ~0xfffffff) == 0 \
+ ? ((v) & ~0x3ffffff) == 0 \
+ ? ((v) & ~0x1ffffff) == 0 \
+ ? 7 \
+ : 6 \
+ : ((v) & ~0x7ffffff) == 0 \
+ ? 5 \
+ : 4 \
+ : ((v) & ~0x3fffffff) == 0 \
+ ? ((v) & ~0x1fffffff) == 0 \
+ ? 3 \
+ : 2 \
+ : ((v) & ~0x7fffffff) == 0 \
+ ? 1 \
+ : 0)
+
+/* load_register()
+ * This routine generates the least number of instructions necessary to load
+ * an absolute expression value into a register.
+ */
+static void
+load_register (int reg, expressionS *ep, int dbl)
+{
+ int freg;
+ expressionS hi32, lo32;
+
+ if (ep->X_op != O_big)
+ {
+ assert (ep->X_op == O_constant);
+
+ /* Sign-extending 32-bit constants makes their handling easier. */
+ if (! dbl && ! ((ep->X_add_number & ~((bfd_vma) 0x7fffffff))
+ == ~((bfd_vma) 0x7fffffff)))
+ {
+ if (ep->X_add_number & ~((bfd_vma) 0xffffffff))
+ as_bad (_("constant too large"));
+
+ ep->X_add_number = (((ep->X_add_number & 0xffffffff) ^ 0x80000000)
+ - 0x80000000);
+ }
+
+ if (IS_SEXT_16BIT_NUM (ep->X_add_number))
+ {
+ /* We can handle 16 bit signed values with an addiu to
+ $zero. No need to ever use daddiu here, since $zero and
+ the result are always correct in 32 bit mode. */
+ macro_build (ep, "addiu", "t,r,j", reg, 0, BFD_RELOC_LO16);
+ return;
+ }
+ else if (ep->X_add_number >= 0 && ep->X_add_number < 0x10000)
+ {
+ /* We can handle 16 bit unsigned values with an ori to
+ $zero. */
+ macro_build (ep, "ori", "t,r,i", reg, 0, BFD_RELOC_LO16);
+ return;
+ }
+ else if ((IS_SEXT_32BIT_NUM (ep->X_add_number)))
+ {
+ /* 32 bit values require an lui. */
+ macro_build (ep, "lui", "t,u", reg, BFD_RELOC_HI16);
+ if ((ep->X_add_number & 0xffff) != 0)
+ macro_build (ep, "ori", "t,r,i", reg, reg, BFD_RELOC_LO16);
+ return;
+ }
+ }
+
+ /* The value is larger than 32 bits. */
+
+ if (HAVE_32BIT_GPRS)
+ {
+ as_bad (_("Number (0x%lx) larger than 32 bits"),
+ (unsigned long) ep->X_add_number);
+ macro_build (ep, "addiu", "t,r,j", reg, 0, BFD_RELOC_LO16);
+ return;
+ }
+
+ if (ep->X_op != O_big)
+ {
+ hi32 = *ep;
+ hi32.X_add_number = (valueT) hi32.X_add_number >> 16;
+ hi32.X_add_number = (valueT) hi32.X_add_number >> 16;
+ hi32.X_add_number &= 0xffffffff;
+ lo32 = *ep;
+ lo32.X_add_number &= 0xffffffff;
+ }
+ else
+ {
+ assert (ep->X_add_number > 2);
+ if (ep->X_add_number == 3)
+ generic_bignum[3] = 0;
+ else if (ep->X_add_number > 4)
+ as_bad (_("Number larger than 64 bits"));
+ lo32.X_op = O_constant;
+ lo32.X_add_number = generic_bignum[0] + (generic_bignum[1] << 16);
+ hi32.X_op = O_constant;
+ hi32.X_add_number = generic_bignum[2] + (generic_bignum[3] << 16);
+ }
+
+ if (hi32.X_add_number == 0)
+ freg = 0;
+ else
+ {
+ int shift, bit;
+ unsigned long hi, lo;
+
+ if (hi32.X_add_number == (offsetT) 0xffffffff)
+ {
+ if ((lo32.X_add_number & 0xffff8000) == 0xffff8000)
+ {
+ macro_build (&lo32, "addiu", "t,r,j", reg, 0, BFD_RELOC_LO16);
+ return;
+ }
+ if (lo32.X_add_number & 0x80000000)
+ {
+ macro_build (&lo32, "lui", "t,u", reg, BFD_RELOC_HI16);
+ if (lo32.X_add_number & 0xffff)
+ macro_build (&lo32, "ori", "t,r,i", reg, reg, BFD_RELOC_LO16);
+ return;
+ }
+ }
+
+ /* Check for 16bit shifted constant. We know that hi32 is
+ non-zero, so start the mask on the first bit of the hi32
+ value. */
+ shift = 17;
+ do
+ {
+ unsigned long himask, lomask;
+
+ if (shift < 32)
+ {
+ himask = 0xffff >> (32 - shift);
+ lomask = (0xffff << shift) & 0xffffffff;
+ }
+ else
+ {
+ himask = 0xffff << (shift - 32);
+ lomask = 0;
+ }
+ if ((hi32.X_add_number & ~(offsetT) himask) == 0
+ && (lo32.X_add_number & ~(offsetT) lomask) == 0)
+ {
+ expressionS tmp;
+
+ tmp.X_op = O_constant;
+ if (shift < 32)
+ tmp.X_add_number = ((hi32.X_add_number << (32 - shift))
+ | (lo32.X_add_number >> shift));
+ else
+ tmp.X_add_number = hi32.X_add_number >> (shift - 32);
+ macro_build (&tmp, "ori", "t,r,i", reg, 0, BFD_RELOC_LO16);
+ macro_build (NULL, (shift >= 32) ? "dsll32" : "dsll", "d,w,<",
+ reg, reg, (shift >= 32) ? shift - 32 : shift);
+ return;
+ }
+ ++shift;
+ }
+ while (shift <= (64 - 16));
+
+ /* Find the bit number of the lowest one bit, and store the
+ shifted value in hi/lo. */
+ hi = (unsigned long) (hi32.X_add_number & 0xffffffff);
+ lo = (unsigned long) (lo32.X_add_number & 0xffffffff);
+ if (lo != 0)
+ {
+ bit = 0;
+ while ((lo & 1) == 0)
+ {
+ lo >>= 1;
+ ++bit;
+ }
+ lo |= (hi & (((unsigned long) 1 << bit) - 1)) << (32 - bit);
+ hi >>= bit;
+ }
+ else
+ {
+ bit = 32;
+ while ((hi & 1) == 0)
+ {
+ hi >>= 1;
+ ++bit;
+ }
+ lo = hi;
+ hi = 0;
+ }
+
+ /* Optimize if the shifted value is a (power of 2) - 1. */
+ if ((hi == 0 && ((lo + 1) & lo) == 0)
+ || (lo == 0xffffffff && ((hi + 1) & hi) == 0))
+ {
+ shift = COUNT_TOP_ZEROES ((unsigned int) hi32.X_add_number);
+ if (shift != 0)
+ {
+ expressionS tmp;
+
+ /* This instruction will set the register to be all
+ ones. */
+ tmp.X_op = O_constant;
+ tmp.X_add_number = (offsetT) -1;
+ macro_build (&tmp, "addiu", "t,r,j", reg, 0, BFD_RELOC_LO16);
+ if (bit != 0)
+ {
+ bit += shift;
+ macro_build (NULL, (bit >= 32) ? "dsll32" : "dsll", "d,w,<",
+ reg, reg, (bit >= 32) ? bit - 32 : bit);
+ }
+ macro_build (NULL, (shift >= 32) ? "dsrl32" : "dsrl", "d,w,<",
+ reg, reg, (shift >= 32) ? shift - 32 : shift);
+ return;
+ }
+ }
+
+ /* Sign extend hi32 before calling load_register, because we can
+ generally get better code when we load a sign extended value. */
+ if ((hi32.X_add_number & 0x80000000) != 0)
+ hi32.X_add_number |= ~(offsetT) 0xffffffff;
+ load_register (reg, &hi32, 0);
+ freg = reg;
+ }
+ if ((lo32.X_add_number & 0xffff0000) == 0)
+ {
+ if (freg != 0)
+ {
+ macro_build (NULL, "dsll32", "d,w,<", reg, freg, 0);
+ freg = reg;
+ }
+ }
+ else
+ {
+ expressionS mid16;
+
+ if ((freg == 0) && (lo32.X_add_number == (offsetT) 0xffffffff))
+ {
+ macro_build (&lo32, "lui", "t,u", reg, BFD_RELOC_HI16);
+ macro_build (NULL, "dsrl32", "d,w,<", reg, reg, 0);
+ return;
+ }
+
+ if (freg != 0)
+ {
+ macro_build (NULL, "dsll", "d,w,<", reg, freg, 16);
+ freg = reg;
+ }
+ mid16 = lo32;
+ mid16.X_add_number >>= 16;
+ macro_build (&mid16, "ori", "t,r,i", reg, freg, BFD_RELOC_LO16);
+ macro_build (NULL, "dsll", "d,w,<", reg, reg, 16);
+ freg = reg;
+ }
+ if ((lo32.X_add_number & 0xffff) != 0)
+ macro_build (&lo32, "ori", "t,r,i", reg, freg, BFD_RELOC_LO16);
+}
+
+/* Load an address into a register. */
+
+static void
+load_address (int reg, expressionS *ep, int *used_at)
+{
+ if (ep->X_op != O_constant
+ && ep->X_op != O_symbol)
+ {
+ as_bad (_("expression too complex"));
+ ep->X_op = O_constant;
+ }
+
+ if (ep->X_op == O_constant)
+ {
+ load_register (reg, ep, HAVE_64BIT_ADDRESSES);
+ return;
+ }
+
+ if (mips_pic == NO_PIC)
+ {
+ /* If this is a reference to a GP relative symbol, we want
+ addiu $reg,$gp,<sym> (BFD_RELOC_GPREL16)
+ Otherwise we want
+ lui $reg,<sym> (BFD_RELOC_HI16_S)
+ addiu $reg,$reg,<sym> (BFD_RELOC_LO16)
+ If we have an addend, we always use the latter form.
+
+ With 64bit address space and a usable $at we want
+ lui $reg,<sym> (BFD_RELOC_MIPS_HIGHEST)
+ lui $at,<sym> (BFD_RELOC_HI16_S)
+ daddiu $reg,<sym> (BFD_RELOC_MIPS_HIGHER)
+ daddiu $at,<sym> (BFD_RELOC_LO16)
+ dsll32 $reg,0
+ daddu $reg,$reg,$at
+
+ If $at is already in use, we use a path which is suboptimal
+ on superscalar processors.
+ lui $reg,<sym> (BFD_RELOC_MIPS_HIGHEST)
+ daddiu $reg,<sym> (BFD_RELOC_MIPS_HIGHER)
+ dsll $reg,16
+ daddiu $reg,<sym> (BFD_RELOC_HI16_S)
+ dsll $reg,16
+ daddiu $reg,<sym> (BFD_RELOC_LO16)
+ */
+ if (HAVE_64BIT_ADDRESSES)
+ {
+ /* ??? We don't provide a GP-relative alternative for these macros.
+ It used not to be possible with the original relaxation code,
+ but it could be done now. */
+
+ if (*used_at == 0 && ! mips_opts.noat)
+ {
+ macro_build (ep, "lui", "t,u", reg, BFD_RELOC_MIPS_HIGHEST);
+ macro_build (ep, "lui", "t,u", AT, BFD_RELOC_HI16_S);
+ macro_build (ep, "daddiu", "t,r,j", reg, reg,
+ BFD_RELOC_MIPS_HIGHER);
+ macro_build (ep, "daddiu", "t,r,j", AT, AT, BFD_RELOC_LO16);
+ macro_build (NULL, "dsll32", "d,w,<", reg, reg, 0);
+ macro_build (NULL, "daddu", "d,v,t", reg, reg, AT);
+ *used_at = 1;
+ }
+ else
+ {
+ macro_build (ep, "lui", "t,u", reg, BFD_RELOC_MIPS_HIGHEST);
+ macro_build (ep, "daddiu", "t,r,j", reg, reg,
+ BFD_RELOC_MIPS_HIGHER);
+ macro_build (NULL, "dsll", "d,w,<", reg, reg, 16);
+ macro_build (ep, "daddiu", "t,r,j", reg, reg, BFD_RELOC_HI16_S);
+ macro_build (NULL, "dsll", "d,w,<", reg, reg, 16);
+ macro_build (ep, "daddiu", "t,r,j", reg, reg, BFD_RELOC_LO16);
+ }
+ }
+ else
+ {
+ if ((valueT) ep->X_add_number <= MAX_GPREL_OFFSET
+ && ! nopic_need_relax (ep->X_add_symbol, 1))
+ {
+ relax_start (ep->X_add_symbol);
+ macro_build (ep, ADDRESS_ADDI_INSN, "t,r,j", reg,
+ mips_gp_register, BFD_RELOC_GPREL16);
+ relax_switch ();
+ }
+ macro_build_lui (ep, reg);
+ macro_build (ep, ADDRESS_ADDI_INSN, "t,r,j",
+ reg, reg, BFD_RELOC_LO16);
+ if (mips_relax.sequence)
+ relax_end ();
+ }
+ }
+ else if (mips_pic == SVR4_PIC && ! mips_big_got)
+ {
+ expressionS ex;
+
+ /* If this is a reference to an external symbol, we want
+ lw $reg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ Otherwise we want
+ lw $reg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $reg,$reg,<sym> (BFD_RELOC_LO16)
+ If there is a constant, it must be added in after.
+
+ If we have NewABI, we want
+ lw $reg,<sym+cst>($gp) (BFD_RELOC_MIPS_GOT_DISP)
+ unless we're referencing a global symbol with a non-zero
+ offset, in which case cst must be added separately. */
+ if (HAVE_NEWABI)
+ {
+ if (ep->X_add_number)
+ {
+ ex.X_add_number = ep->X_add_number;
+ ep->X_add_number = 0;
+ relax_start (ep->X_add_symbol);
+ macro_build (ep, ADDRESS_LOAD_INSN, "t,o(b)", reg,
+ BFD_RELOC_MIPS_GOT_DISP, mips_gp_register);
+ if (ex.X_add_number < -0x8000 || ex.X_add_number >= 0x8000)
+ as_bad (_("PIC code offset overflow (max 16 signed bits)"));
+ ex.X_op = O_constant;
+ macro_build (&ex, ADDRESS_ADDI_INSN, "t,r,j",
+ reg, reg, BFD_RELOC_LO16);
+ ep->X_add_number = ex.X_add_number;
+ relax_switch ();
+ }
+ macro_build (ep, ADDRESS_LOAD_INSN, "t,o(b)", reg,
+ BFD_RELOC_MIPS_GOT_DISP, mips_gp_register);
+ if (mips_relax.sequence)
+ relax_end ();
+ }
+ else
+ {
+ ex.X_add_number = ep->X_add_number;
+ ep->X_add_number = 0;
+ macro_build (ep, ADDRESS_LOAD_INSN, "t,o(b)", reg,
+ BFD_RELOC_MIPS_GOT16, mips_gp_register);
+ macro_build (NULL, "nop", "");
+ relax_start (ep->X_add_symbol);
+ relax_switch ();
+ macro_build (ep, ADDRESS_ADDI_INSN, "t,r,j", reg, reg,
+ BFD_RELOC_LO16);
+ relax_end ();
+
+ if (ex.X_add_number != 0)
+ {
+ if (ex.X_add_number < -0x8000 || ex.X_add_number >= 0x8000)
+ as_bad (_("PIC code offset overflow (max 16 signed bits)"));
+ ex.X_op = O_constant;
+ macro_build (&ex, ADDRESS_ADDI_INSN, "t,r,j",
+ reg, reg, BFD_RELOC_LO16);
+ }
+ }
+ }
+ else if (mips_pic == SVR4_PIC)
+ {
+ expressionS ex;
+
+ /* This is the large GOT case. If this is a reference to an
+ external symbol, we want
+ lui $reg,<sym> (BFD_RELOC_MIPS_GOT_HI16)
+ addu $reg,$reg,$gp
+ lw $reg,<sym>($reg) (BFD_RELOC_MIPS_GOT_LO16)
+
+ Otherwise, for a reference to a local symbol in old ABI, we want
+ lw $reg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $reg,$reg,<sym> (BFD_RELOC_LO16)
+ If there is a constant, it must be added in after.
+
+ In the NewABI, for local symbols, with or without offsets, we want:
+ lw $reg,<sym>($gp) (BFD_RELOC_MIPS_GOT_PAGE)
+ addiu $reg,$reg,<sym> (BFD_RELOC_MIPS_GOT_OFST)
+ */
+ if (HAVE_NEWABI)
+ {
+ ex.X_add_number = ep->X_add_number;
+ ep->X_add_number = 0;
+ relax_start (ep->X_add_symbol);
+ macro_build (ep, "lui", "t,u", reg, BFD_RELOC_MIPS_GOT_HI16);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ reg, reg, mips_gp_register);
+ macro_build (ep, ADDRESS_LOAD_INSN, "t,o(b)",
+ reg, BFD_RELOC_MIPS_GOT_LO16, reg);
+ if (ex.X_add_number < -0x8000 || ex.X_add_number >= 0x8000)
+ as_bad (_("PIC code offset overflow (max 16 signed bits)"));
+ else if (ex.X_add_number)
+ {
+ ex.X_op = O_constant;
+ macro_build (&ex, ADDRESS_ADDI_INSN, "t,r,j", reg, reg,
+ BFD_RELOC_LO16);
+ }
+
+ ep->X_add_number = ex.X_add_number;
+ relax_switch ();
+ macro_build (ep, ADDRESS_LOAD_INSN, "t,o(b)", reg,
+ BFD_RELOC_MIPS_GOT_PAGE, mips_gp_register);
+ macro_build (ep, ADDRESS_ADDI_INSN, "t,r,j", reg, reg,
+ BFD_RELOC_MIPS_GOT_OFST);
+ relax_end ();
+ }
+ else
+ {
+ ex.X_add_number = ep->X_add_number;
+ ep->X_add_number = 0;
+ relax_start (ep->X_add_symbol);
+ macro_build (ep, "lui", "t,u", reg, BFD_RELOC_MIPS_GOT_HI16);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ reg, reg, mips_gp_register);
+ macro_build (ep, ADDRESS_LOAD_INSN, "t,o(b)",
+ reg, BFD_RELOC_MIPS_GOT_LO16, reg);
+ relax_switch ();
+ if (reg_needs_delay (mips_gp_register))
+ {
+ /* We need a nop before loading from $gp. This special
+ check is required because the lui which starts the main
+ instruction stream does not refer to $gp, and so will not
+ insert the nop which may be required. */
+ macro_build (NULL, "nop", "");
+ }
+ macro_build (ep, ADDRESS_LOAD_INSN, "t,o(b)", reg,
+ BFD_RELOC_MIPS_GOT16, mips_gp_register);
+ macro_build (NULL, "nop", "");
+ macro_build (ep, ADDRESS_ADDI_INSN, "t,r,j", reg, reg,
+ BFD_RELOC_LO16);
+ relax_end ();
+
+ if (ex.X_add_number != 0)
+ {
+ if (ex.X_add_number < -0x8000 || ex.X_add_number >= 0x8000)
+ as_bad (_("PIC code offset overflow (max 16 signed bits)"));
+ ex.X_op = O_constant;
+ macro_build (&ex, ADDRESS_ADDI_INSN, "t,r,j", reg, reg,
+ BFD_RELOC_LO16);
+ }
+ }
+ }
+ else if (mips_pic == EMBEDDED_PIC)
+ {
+ /* We always do
+ addiu $reg,$gp,<sym> (BFD_RELOC_GPREL16)
+ */
+ macro_build (ep, ADDRESS_ADDI_INSN, "t,r,j",
+ reg, mips_gp_register, BFD_RELOC_GPREL16);
+ }
+ else
+ abort ();
+}
+
+/* Move the contents of register SOURCE into register DEST. */
+
+static void
+move_register (int dest, int source)
+{
+ macro_build (NULL, HAVE_32BIT_GPRS ? "addu" : "daddu", "d,v,t",
+ dest, source, 0);
+}
+
+/* Emit an SVR4 PIC sequence to load address LOCAL into DEST, where
+ LOCAL is the sum of a symbol and a 16-bit or 32-bit displacement.
+ The two alternatives are:
+
+ Global symbol Local sybmol
+ ------------- ------------
+ lw DEST,%got(SYMBOL) lw DEST,%got(SYMBOL + OFFSET)
+ ... ...
+ addiu DEST,DEST,OFFSET addiu DEST,DEST,%lo(SYMBOL + OFFSET)
+
+ load_got_offset emits the first instruction and add_got_offset
+ emits the second for a 16-bit offset or add_got_offset_hilo emits
+ a sequence to add a 32-bit offset using a scratch register. */
+
+static void
+load_got_offset (int dest, expressionS *local)
+{
+ expressionS global;
+
+ global = *local;
+ global.X_add_number = 0;
+
+ relax_start (local->X_add_symbol);
+ macro_build (&global, ADDRESS_LOAD_INSN, "t,o(b)", dest,
+ BFD_RELOC_MIPS_GOT16, mips_gp_register);
+ relax_switch ();
+ macro_build (local, ADDRESS_LOAD_INSN, "t,o(b)", dest,
+ BFD_RELOC_MIPS_GOT16, mips_gp_register);
+ relax_end ();
+}
+
+static void
+add_got_offset (int dest, expressionS *local)
+{
+ expressionS global;
+
+ global.X_op = O_constant;
+ global.X_op_symbol = NULL;
+ global.X_add_symbol = NULL;
+ global.X_add_number = local->X_add_number;
+
+ relax_start (local->X_add_symbol);
+ macro_build (&global, ADDRESS_ADDI_INSN, "t,r,j",
+ dest, dest, BFD_RELOC_LO16);
+ relax_switch ();
+ macro_build (local, ADDRESS_ADDI_INSN, "t,r,j", dest, dest, BFD_RELOC_LO16);
+ relax_end ();
+}
+
+static void
+add_got_offset_hilo (int dest, expressionS *local, int tmp)
+{
+ expressionS global;
+ int hold_mips_optimize;
+
+ global.X_op = O_constant;
+ global.X_op_symbol = NULL;
+ global.X_add_symbol = NULL;
+ global.X_add_number = local->X_add_number;
+
+ relax_start (local->X_add_symbol);
+ load_register (tmp, &global, HAVE_64BIT_ADDRESSES);
+ relax_switch ();
+ /* Set mips_optimize around the lui instruction to avoid
+ inserting an unnecessary nop after the lw. */
+ hold_mips_optimize = mips_optimize;
+ mips_optimize = 2;
+ macro_build_lui (&global, tmp);
+ mips_optimize = hold_mips_optimize;
+ macro_build (local, ADDRESS_ADDI_INSN, "t,r,j", tmp, tmp, BFD_RELOC_LO16);
+ relax_end ();
+
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", dest, dest, tmp);
+}
+
+/*
+ * Build macros
+ * This routine implements the seemingly endless macro or synthesized
+ * instructions and addressing modes in the mips assembly language. Many
+ * of these macros are simple and are similar to each other. These could
+ * probably be handled by some kind of table or grammar approach instead of
+ * this verbose method. Others are not simple macros but are more like
+ * optimizing code generation.
+ * One interesting optimization is when several store macros appear
+ * consecutively that would load AT with the upper half of the same address.
+ * The ensuing load upper instructions are ommited. This implies some kind
+ * of global optimization. We currently only optimize within a single macro.
+ * For many of the load and store macros if the address is specified as a
+ * constant expression in the first 64k of memory (ie ld $2,0x4000c) we
+ * first load register 'at' with zero and use it as the base register. The
+ * mips assembler simply uses register $zero. Just one tiny optimization
+ * we're missing.
+ */
+static void
+macro (struct mips_cl_insn *ip)
+{
+ register int treg, sreg, dreg, breg;
+ int tempreg;
+ int mask;
+ int used_at = 0;
+ expressionS expr1;
+ const char *s;
+ const char *s2;
+ const char *fmt;
+ int likely = 0;
+ int dbl = 0;
+ int coproc = 0;
+ int lr = 0;
+ int imm = 0;
+ int call = 0;
+ int off;
+ offsetT maxnum;
+ bfd_reloc_code_real_type r;
+ int hold_mips_optimize;
+
+ assert (! mips_opts.mips16);
+
+ treg = (ip->insn_opcode >> 16) & 0x1f;
+ dreg = (ip->insn_opcode >> 11) & 0x1f;
+ sreg = breg = (ip->insn_opcode >> 21) & 0x1f;
+ mask = ip->insn_mo->mask;
+
+ expr1.X_op = O_constant;
+ expr1.X_op_symbol = NULL;
+ expr1.X_add_symbol = NULL;
+ expr1.X_add_number = 1;
+
+ switch (mask)
+ {
+ case M_DABS:
+ dbl = 1;
+ case M_ABS:
+ /* bgez $a0,.+12
+ move v0,$a0
+ sub v0,$zero,$a0
+ */
+
+ mips_emit_delays (TRUE);
+ ++mips_opts.noreorder;
+ mips_any_noreorder = 1;
+
+ expr1.X_add_number = 8;
+ macro_build (&expr1, "bgez", "s,p", sreg);
+ if (dreg == sreg)
+ macro_build (NULL, "nop", "", 0);
+ else
+ move_register (dreg, sreg);
+ macro_build (NULL, dbl ? "dsub" : "sub", "d,v,t", dreg, 0, sreg);
+
+ --mips_opts.noreorder;
+ return;
+
+ case M_ADD_I:
+ s = "addi";
+ s2 = "add";
+ goto do_addi;
+ case M_ADDU_I:
+ s = "addiu";
+ s2 = "addu";
+ goto do_addi;
+ case M_DADD_I:
+ dbl = 1;
+ s = "daddi";
+ s2 = "dadd";
+ goto do_addi;
+ case M_DADDU_I:
+ dbl = 1;
+ s = "daddiu";
+ s2 = "daddu";
+ do_addi:
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= -0x8000
+ && imm_expr.X_add_number < 0x8000)
+ {
+ macro_build (&imm_expr, s, "t,r,j", treg, sreg, BFD_RELOC_LO16);
+ return;
+ }
+ load_register (AT, &imm_expr, dbl);
+ macro_build (NULL, s2, "d,v,t", treg, sreg, AT);
+ break;
+
+ case M_AND_I:
+ s = "andi";
+ s2 = "and";
+ goto do_bit;
+ case M_OR_I:
+ s = "ori";
+ s2 = "or";
+ goto do_bit;
+ case M_NOR_I:
+ s = "";
+ s2 = "nor";
+ goto do_bit;
+ case M_XOR_I:
+ s = "xori";
+ s2 = "xor";
+ do_bit:
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= 0
+ && imm_expr.X_add_number < 0x10000)
+ {
+ if (mask != M_NOR_I)
+ macro_build (&imm_expr, s, "t,r,i", treg, sreg, BFD_RELOC_LO16);
+ else
+ {
+ macro_build (&imm_expr, "ori", "t,r,i",
+ treg, sreg, BFD_RELOC_LO16);
+ macro_build (NULL, "nor", "d,v,t", treg, treg, 0);
+ }
+ return;
+ }
+
+ load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ macro_build (NULL, s2, "d,v,t", treg, sreg, AT);
+ break;
+
+ case M_BEQ_I:
+ s = "beq";
+ goto beq_i;
+ case M_BEQL_I:
+ s = "beql";
+ likely = 1;
+ goto beq_i;
+ case M_BNE_I:
+ s = "bne";
+ goto beq_i;
+ case M_BNEL_I:
+ s = "bnel";
+ likely = 1;
+ beq_i:
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ {
+ macro_build (&offset_expr, s, "s,t,p", sreg, 0);
+ return;
+ }
+ load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ macro_build (&offset_expr, s, "s,t,p", sreg, AT);
+ break;
+
+ case M_BGEL:
+ likely = 1;
+ case M_BGE:
+ if (treg == 0)
+ {
+ macro_build (&offset_expr, likely ? "bgezl" : "bgez", "s,p", sreg);
+ return;
+ }
+ if (sreg == 0)
+ {
+ macro_build (&offset_expr, likely ? "blezl" : "blez", "s,p", treg);
+ return;
+ }
+ macro_build (NULL, "slt", "d,v,t", AT, sreg, treg);
+ macro_build (&offset_expr, likely ? "beql" : "beq", "s,t,p", AT, 0);
+ break;
+
+ case M_BGTL_I:
+ likely = 1;
+ case M_BGT_I:
+ /* check for > max integer */
+ maxnum = 0x7fffffff;
+ if (HAVE_64BIT_GPRS && sizeof (maxnum) > 4)
+ {
+ maxnum <<= 16;
+ maxnum |= 0xffff;
+ maxnum <<= 16;
+ maxnum |= 0xffff;
+ }
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= maxnum
+ && (HAVE_32BIT_GPRS || sizeof (maxnum) > 4))
+ {
+ do_false:
+ /* result is always false */
+ if (! likely)
+ macro_build (NULL, "nop", "", 0);
+ else
+ macro_build (&offset_expr, "bnel", "s,t,p", 0, 0);
+ return;
+ }
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Unsupported large constant"));
+ ++imm_expr.X_add_number;
+ /* FALLTHROUGH */
+ case M_BGE_I:
+ case M_BGEL_I:
+ if (mask == M_BGEL_I)
+ likely = 1;
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ {
+ macro_build (&offset_expr, likely ? "bgezl" : "bgez", "s,p", sreg);
+ return;
+ }
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
+ {
+ macro_build (&offset_expr, likely ? "bgtzl" : "bgtz", "s,p", sreg);
+ return;
+ }
+ maxnum = 0x7fffffff;
+ if (HAVE_64BIT_GPRS && sizeof (maxnum) > 4)
+ {
+ maxnum <<= 16;
+ maxnum |= 0xffff;
+ maxnum <<= 16;
+ maxnum |= 0xffff;
+ }
+ maxnum = - maxnum - 1;
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number <= maxnum
+ && (HAVE_32BIT_GPRS || sizeof (maxnum) > 4))
+ {
+ do_true:
+ /* result is always true */
+ as_warn (_("Branch %s is always true"), ip->insn_mo->name);
+ macro_build (&offset_expr, "b", "p");
+ return;
+ }
+ set_at (sreg, 0);
+ macro_build (&offset_expr, likely ? "beql" : "beq", "s,t,p", AT, 0);
+ break;
+
+ case M_BGEUL:
+ likely = 1;
+ case M_BGEU:
+ if (treg == 0)
+ goto do_true;
+ if (sreg == 0)
+ {
+ macro_build (&offset_expr, likely ? "beql" : "beq",
+ "s,t,p", 0, treg);
+ return;
+ }
+ macro_build (NULL, "sltu", "d,v,t", AT, sreg, treg);
+ macro_build (&offset_expr, likely ? "beql" : "beq", "s,t,p", AT, 0);
+ break;
+
+ case M_BGTUL_I:
+ likely = 1;
+ case M_BGTU_I:
+ if (sreg == 0
+ || (HAVE_32BIT_GPRS
+ && imm_expr.X_op == O_constant
+ && imm_expr.X_add_number == (offsetT) 0xffffffff))
+ goto do_false;
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Unsupported large constant"));
+ ++imm_expr.X_add_number;
+ /* FALLTHROUGH */
+ case M_BGEU_I:
+ case M_BGEUL_I:
+ if (mask == M_BGEUL_I)
+ likely = 1;
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ goto do_true;
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
+ {
+ macro_build (&offset_expr, likely ? "bnel" : "bne",
+ "s,t,p", sreg, 0);
+ return;
+ }
+ set_at (sreg, 1);
+ macro_build (&offset_expr, likely ? "beql" : "beq", "s,t,p", AT, 0);
+ break;
+
+ case M_BGTL:
+ likely = 1;
+ case M_BGT:
+ if (treg == 0)
+ {
+ macro_build (&offset_expr, likely ? "bgtzl" : "bgtz", "s,p", sreg);
+ return;
+ }
+ if (sreg == 0)
+ {
+ macro_build (&offset_expr, likely ? "bltzl" : "bltz", "s,p", treg);
+ return;
+ }
+ macro_build (NULL, "slt", "d,v,t", AT, treg, sreg);
+ macro_build (&offset_expr, likely ? "bnel" : "bne", "s,t,p", AT, 0);
+ break;
+
+ case M_BGTUL:
+ likely = 1;
+ case M_BGTU:
+ if (treg == 0)
+ {
+ macro_build (&offset_expr, likely ? "bnel" : "bne",
+ "s,t,p", sreg, 0);
+ return;
+ }
+ if (sreg == 0)
+ goto do_false;
+ macro_build (NULL, "sltu", "d,v,t", AT, treg, sreg);
+ macro_build (&offset_expr, likely ? "bnel" : "bne", "s,t,p", AT, 0);
+ break;
+
+ case M_BLEL:
+ likely = 1;
+ case M_BLE:
+ if (treg == 0)
+ {
+ macro_build (&offset_expr, likely ? "blezl" : "blez", "s,p", sreg);
+ return;
+ }
+ if (sreg == 0)
+ {
+ macro_build (&offset_expr, likely ? "bgezl" : "bgez", "s,p", treg);
+ return;
+ }
+ macro_build (NULL, "slt", "d,v,t", AT, treg, sreg);
+ macro_build (&offset_expr, likely ? "beql" : "beq", "s,t,p", AT, 0);
+ break;
+
+ case M_BLEL_I:
+ likely = 1;
+ case M_BLE_I:
+ maxnum = 0x7fffffff;
+ if (HAVE_64BIT_GPRS && sizeof (maxnum) > 4)
+ {
+ maxnum <<= 16;
+ maxnum |= 0xffff;
+ maxnum <<= 16;
+ maxnum |= 0xffff;
+ }
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= maxnum
+ && (HAVE_32BIT_GPRS || sizeof (maxnum) > 4))
+ goto do_true;
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Unsupported large constant"));
+ ++imm_expr.X_add_number;
+ /* FALLTHROUGH */
+ case M_BLT_I:
+ case M_BLTL_I:
+ if (mask == M_BLTL_I)
+ likely = 1;
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ {
+ macro_build (&offset_expr, likely ? "bltzl" : "bltz", "s,p", sreg);
+ return;
+ }
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
+ {
+ macro_build (&offset_expr, likely ? "blezl" : "blez", "s,p", sreg);
+ return;
+ }
+ set_at (sreg, 0);
+ macro_build (&offset_expr, likely ? "bnel" : "bne", "s,t,p", AT, 0);
+ break;
+
+ case M_BLEUL:
+ likely = 1;
+ case M_BLEU:
+ if (treg == 0)
+ {
+ macro_build (&offset_expr, likely ? "beql" : "beq",
+ "s,t,p", sreg, 0);
+ return;
+ }
+ if (sreg == 0)
+ goto do_true;
+ macro_build (NULL, "sltu", "d,v,t", AT, treg, sreg);
+ macro_build (&offset_expr, likely ? "beql" : "beq", "s,t,p", AT, 0);
+ break;
+
+ case M_BLEUL_I:
+ likely = 1;
+ case M_BLEU_I:
+ if (sreg == 0
+ || (HAVE_32BIT_GPRS
+ && imm_expr.X_op == O_constant
+ && imm_expr.X_add_number == (offsetT) 0xffffffff))
+ goto do_true;
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Unsupported large constant"));
+ ++imm_expr.X_add_number;
+ /* FALLTHROUGH */
+ case M_BLTU_I:
+ case M_BLTUL_I:
+ if (mask == M_BLTUL_I)
+ likely = 1;
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ goto do_false;
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
+ {
+ macro_build (&offset_expr, likely ? "beql" : "beq",
+ "s,t,p", sreg, 0);
+ return;
+ }
+ set_at (sreg, 1);
+ macro_build (&offset_expr, likely ? "bnel" : "bne", "s,t,p", AT, 0);
+ break;
+
+ case M_BLTL:
+ likely = 1;
+ case M_BLT:
+ if (treg == 0)
+ {
+ macro_build (&offset_expr, likely ? "bltzl" : "bltz", "s,p", sreg);
+ return;
+ }
+ if (sreg == 0)
+ {
+ macro_build (&offset_expr, likely ? "bgtzl" : "bgtz", "s,p", treg);
+ return;
+ }
+ macro_build (NULL, "slt", "d,v,t", AT, sreg, treg);
+ macro_build (&offset_expr, likely ? "bnel" : "bne", "s,t,p", AT, 0);
+ break;
+
+ case M_BLTUL:
+ likely = 1;
+ case M_BLTU:
+ if (treg == 0)
+ goto do_false;
+ if (sreg == 0)
+ {
+ macro_build (&offset_expr, likely ? "bnel" : "bne",
+ "s,t,p", 0, treg);
+ return;
+ }
+ macro_build (NULL, "sltu", "d,v,t", AT, sreg, treg);
+ macro_build (&offset_expr, likely ? "bnel" : "bne", "s,t,p", AT, 0);
+ break;
+
+ case M_DEXT:
+ {
+ unsigned long pos;
+ unsigned long size;
+
+ if (imm_expr.X_op != O_constant || imm2_expr.X_op != O_constant)
+ {
+ as_bad (_("Unsupported large constant"));
+ pos = size = 1;
+ }
+ else
+ {
+ pos = (unsigned long) imm_expr.X_add_number;
+ size = (unsigned long) imm2_expr.X_add_number;
+ }
+
+ if (pos > 63)
+ {
+ as_bad (_("Improper position (%lu)"), pos);
+ pos = 1;
+ }
+ if (size == 0 || size > 64
+ || (pos + size - 1) > 63)
+ {
+ as_bad (_("Improper extract size (%lu, position %lu)"),
+ size, pos);
+ size = 1;
+ }
+
+ if (size <= 32 && pos < 32)
+ {
+ s = "dext";
+ fmt = "t,r,+A,+C";
+ }
+ else if (size <= 32)
+ {
+ s = "dextu";
+ fmt = "t,r,+E,+H";
+ }
+ else
+ {
+ s = "dextm";
+ fmt = "t,r,+A,+G";
+ }
+ macro_build ((expressionS *) NULL, s, fmt, treg, sreg, pos, size - 1);
+ }
+ return;
+
+ case M_DINS:
+ {
+ unsigned long pos;
+ unsigned long size;
+
+ if (imm_expr.X_op != O_constant || imm2_expr.X_op != O_constant)
+ {
+ as_bad (_("Unsupported large constant"));
+ pos = size = 1;
+ }
+ else
+ {
+ pos = (unsigned long) imm_expr.X_add_number;
+ size = (unsigned long) imm2_expr.X_add_number;
+ }
+
+ if (pos > 63)
+ {
+ as_bad (_("Improper position (%lu)"), pos);
+ pos = 1;
+ }
+ if (size == 0 || size > 64
+ || (pos + size - 1) > 63)
+ {
+ as_bad (_("Improper insert size (%lu, position %lu)"),
+ size, pos);
+ size = 1;
+ }
+
+ if (pos < 32 && (pos + size - 1) < 32)
+ {
+ s = "dins";
+ fmt = "t,r,+A,+B";
+ }
+ else if (pos >= 32)
+ {
+ s = "dinsu";
+ fmt = "t,r,+E,+F";
+ }
+ else
+ {
+ s = "dinsm";
+ fmt = "t,r,+A,+F";
+ }
+ macro_build ((expressionS *) NULL, s, fmt, treg, sreg, pos,
+ pos + size - 1);
+ }
+ return;
+
+ case M_DDIV_3:
+ dbl = 1;
+ case M_DIV_3:
+ s = "mflo";
+ goto do_div3;
+ case M_DREM_3:
+ dbl = 1;
+ case M_REM_3:
+ s = "mfhi";
+ do_div3:
+ if (treg == 0)
+ {
+ as_warn (_("Divide by zero."));
+ if (mips_trap)
+ macro_build (NULL, "teq", "s,t,q", 0, 0, 7);
+ else
+ macro_build (NULL, "break", "c", 7);
+ return;
+ }
+
+ mips_emit_delays (TRUE);
+ ++mips_opts.noreorder;
+ mips_any_noreorder = 1;
+ if (mips_trap)
+ {
+ macro_build (NULL, "teq", "s,t,q", treg, 0, 7);
+ macro_build (NULL, dbl ? "ddiv" : "div", "z,s,t", sreg, treg);
+ }
+ else
+ {
+ expr1.X_add_number = 8;
+ macro_build (&expr1, "bne", "s,t,p", treg, 0);
+ macro_build (NULL, dbl ? "ddiv" : "div", "z,s,t", sreg, treg);
+ macro_build (NULL, "break", "c", 7);
+ }
+ expr1.X_add_number = -1;
+ load_register (AT, &expr1, dbl);
+ expr1.X_add_number = mips_trap ? (dbl ? 12 : 8) : (dbl ? 20 : 16);
+ macro_build (&expr1, "bne", "s,t,p", treg, AT);
+ if (dbl)
+ {
+ expr1.X_add_number = 1;
+ load_register (AT, &expr1, dbl);
+ macro_build (NULL, "dsll32", "d,w,<", AT, AT, 31);
+ }
+ else
+ {
+ expr1.X_add_number = 0x80000000;
+ macro_build (&expr1, "lui", "t,u", AT, BFD_RELOC_HI16);
+ }
+ if (mips_trap)
+ {
+ macro_build (NULL, "teq", "s,t,q", sreg, AT, 6);
+ /* We want to close the noreorder block as soon as possible, so
+ that later insns are available for delay slot filling. */
+ --mips_opts.noreorder;
+ }
+ else
+ {
+ expr1.X_add_number = 8;
+ macro_build (&expr1, "bne", "s,t,p", sreg, AT);
+ macro_build (NULL, "nop", "", 0);
+
+ /* We want to close the noreorder block as soon as possible, so
+ that later insns are available for delay slot filling. */
+ --mips_opts.noreorder;
+
+ macro_build (NULL, "break", "c", 6);
+ }
+ macro_build (NULL, s, "d", dreg);
+ break;
+
+ case M_DIV_3I:
+ s = "div";
+ s2 = "mflo";
+ goto do_divi;
+ case M_DIVU_3I:
+ s = "divu";
+ s2 = "mflo";
+ goto do_divi;
+ case M_REM_3I:
+ s = "div";
+ s2 = "mfhi";
+ goto do_divi;
+ case M_REMU_3I:
+ s = "divu";
+ s2 = "mfhi";
+ goto do_divi;
+ case M_DDIV_3I:
+ dbl = 1;
+ s = "ddiv";
+ s2 = "mflo";
+ goto do_divi;
+ case M_DDIVU_3I:
+ dbl = 1;
+ s = "ddivu";
+ s2 = "mflo";
+ goto do_divi;
+ case M_DREM_3I:
+ dbl = 1;
+ s = "ddiv";
+ s2 = "mfhi";
+ goto do_divi;
+ case M_DREMU_3I:
+ dbl = 1;
+ s = "ddivu";
+ s2 = "mfhi";
+ do_divi:
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ {
+ as_warn (_("Divide by zero."));
+ if (mips_trap)
+ macro_build (NULL, "teq", "s,t,q", 0, 0, 7);
+ else
+ macro_build (NULL, "break", "c", 7);
+ return;
+ }
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
+ {
+ if (strcmp (s2, "mflo") == 0)
+ move_register (dreg, sreg);
+ else
+ move_register (dreg, 0);
+ return;
+ }
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number == -1
+ && s[strlen (s) - 1] != 'u')
+ {
+ if (strcmp (s2, "mflo") == 0)
+ {
+ macro_build (NULL, dbl ? "dneg" : "neg", "d,w", dreg, sreg);
+ }
+ else
+ move_register (dreg, 0);
+ return;
+ }
+
+ load_register (AT, &imm_expr, dbl);
+ macro_build (NULL, s, "z,s,t", sreg, AT);
+ macro_build (NULL, s2, "d", dreg);
+ break;
+
+ case M_DIVU_3:
+ s = "divu";
+ s2 = "mflo";
+ goto do_divu3;
+ case M_REMU_3:
+ s = "divu";
+ s2 = "mfhi";
+ goto do_divu3;
+ case M_DDIVU_3:
+ s = "ddivu";
+ s2 = "mflo";
+ goto do_divu3;
+ case M_DREMU_3:
+ s = "ddivu";
+ s2 = "mfhi";
+ do_divu3:
+ mips_emit_delays (TRUE);
+ ++mips_opts.noreorder;
+ mips_any_noreorder = 1;
+ if (mips_trap)
+ {
+ macro_build (NULL, "teq", "s,t,q", treg, 0, 7);
+ macro_build (NULL, s, "z,s,t", sreg, treg);
+ /* We want to close the noreorder block as soon as possible, so
+ that later insns are available for delay slot filling. */
+ --mips_opts.noreorder;
+ }
+ else
+ {
+ expr1.X_add_number = 8;
+ macro_build (&expr1, "bne", "s,t,p", treg, 0);
+ macro_build (NULL, s, "z,s,t", sreg, treg);
+
+ /* We want to close the noreorder block as soon as possible, so
+ that later insns are available for delay slot filling. */
+ --mips_opts.noreorder;
+ macro_build (NULL, "break", "c", 7);
+ }
+ macro_build (NULL, s2, "d", dreg);
+ return;
+
+ case M_DLCA_AB:
+ dbl = 1;
+ case M_LCA_AB:
+ call = 1;
+ goto do_la;
+ case M_DLA_AB:
+ dbl = 1;
+ case M_LA_AB:
+ do_la:
+ /* Load the address of a symbol into a register. If breg is not
+ zero, we then add a base register to it. */
+
+ if (dbl && HAVE_32BIT_GPRS)
+ as_warn (_("dla used to load 32-bit register"));
+
+ if (! dbl && HAVE_64BIT_OBJECTS)
+ as_warn (_("la used to load 64-bit address"));
+
+ if (offset_expr.X_op == O_constant
+ && offset_expr.X_add_number >= -0x8000
+ && offset_expr.X_add_number < 0x8000)
+ {
+ macro_build (&offset_expr,
+ (dbl || HAVE_64BIT_ADDRESSES) ? "daddiu" : "addiu",
+ "t,r,j", treg, sreg, BFD_RELOC_LO16);
+ return;
+ }
+
+ if (treg == breg)
+ {
+ tempreg = AT;
+ used_at = 1;
+ }
+ else
+ {
+ tempreg = treg;
+ used_at = 0;
+ }
+
+ /* When generating embedded PIC code, we permit expressions of
+ the form
+ la $treg,foo-bar
+ la $treg,foo-bar($breg)
+ where bar is an address in the current section. These are used
+ when getting the addresses of functions. We don't permit
+ X_add_number to be non-zero, because if the symbol is
+ external the relaxing code needs to know that any addend is
+ purely the offset to X_op_symbol. */
+ if (mips_pic == EMBEDDED_PIC
+ && offset_expr.X_op == O_subtract
+ && (symbol_constant_p (offset_expr.X_op_symbol)
+ ? S_GET_SEGMENT (offset_expr.X_op_symbol) == now_seg
+ : (symbol_equated_p (offset_expr.X_op_symbol)
+ && (S_GET_SEGMENT
+ (symbol_get_value_expression (offset_expr.X_op_symbol)
+ ->X_add_symbol)
+ == now_seg)))
+ && (offset_expr.X_add_number == 0
+ || OUTPUT_FLAVOR == bfd_target_elf_flavour))
+ {
+ if (breg == 0)
+ {
+ tempreg = treg;
+ used_at = 0;
+ macro_build (&offset_expr, "lui", "t,u",
+ tempreg, BFD_RELOC_PCREL_HI16_S);
+ }
+ else
+ {
+ macro_build (&offset_expr, "lui", "t,u",
+ tempreg, BFD_RELOC_PCREL_HI16_S);
+ macro_build (NULL,
+ (dbl || HAVE_64BIT_ADDRESSES) ? "daddu" : "addu",
+ "d,v,t", tempreg, tempreg, breg);
+ }
+ macro_build (&offset_expr,
+ (dbl || HAVE_64BIT_ADDRESSES) ? "daddiu" : "addiu",
+ "t,r,j", treg, tempreg, BFD_RELOC_PCREL_LO16);
+ if (! used_at)
+ return;
+ break;
+ }
+
+ if (offset_expr.X_op != O_symbol
+ && offset_expr.X_op != O_constant)
+ {
+ as_bad (_("expression too complex"));
+ offset_expr.X_op = O_constant;
+ }
+
+ if (offset_expr.X_op == O_constant)
+ load_register (tempreg, &offset_expr,
+ ((mips_pic == EMBEDDED_PIC || mips_pic == NO_PIC)
+ ? (dbl || HAVE_64BIT_ADDRESSES)
+ : HAVE_64BIT_ADDRESSES));
+ else if (mips_pic == NO_PIC)
+ {
+ /* If this is a reference to a GP relative symbol, we want
+ addiu $tempreg,$gp,<sym> (BFD_RELOC_GPREL16)
+ Otherwise we want
+ lui $tempreg,<sym> (BFD_RELOC_HI16_S)
+ addiu $tempreg,$tempreg,<sym> (BFD_RELOC_LO16)
+ If we have a constant, we need two instructions anyhow,
+ so we may as well always use the latter form.
+
+ With 64bit address space and a usable $at we want
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_HIGHEST)
+ lui $at,<sym> (BFD_RELOC_HI16_S)
+ daddiu $tempreg,<sym> (BFD_RELOC_MIPS_HIGHER)
+ daddiu $at,<sym> (BFD_RELOC_LO16)
+ dsll32 $tempreg,0
+ daddu $tempreg,$tempreg,$at
+
+ If $at is already in use, we use a path which is suboptimal
+ on superscalar processors.
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_HIGHEST)
+ daddiu $tempreg,<sym> (BFD_RELOC_MIPS_HIGHER)
+ dsll $tempreg,16
+ daddiu $tempreg,<sym> (BFD_RELOC_HI16_S)
+ dsll $tempreg,16
+ daddiu $tempreg,<sym> (BFD_RELOC_LO16)
+ */
+ if (HAVE_64BIT_ADDRESSES)
+ {
+ /* ??? We don't provide a GP-relative alternative for
+ these macros. It used not to be possible with the
+ original relaxation code, but it could be done now. */
+
+ if (used_at == 0 && ! mips_opts.noat)
+ {
+ macro_build (&offset_expr, "lui", "t,u",
+ tempreg, BFD_RELOC_MIPS_HIGHEST);
+ macro_build (&offset_expr, "lui", "t,u",
+ AT, BFD_RELOC_HI16_S);
+ macro_build (&offset_expr, "daddiu", "t,r,j",
+ tempreg, tempreg, BFD_RELOC_MIPS_HIGHER);
+ macro_build (&offset_expr, "daddiu", "t,r,j",
+ AT, AT, BFD_RELOC_LO16);
+ macro_build (NULL, "dsll32", "d,w,<", tempreg, tempreg, 0);
+ macro_build (NULL, "daddu", "d,v,t", tempreg, tempreg, AT);
+ used_at = 1;
+ }
+ else
+ {
+ macro_build (&offset_expr, "lui", "t,u",
+ tempreg, BFD_RELOC_MIPS_HIGHEST);
+ macro_build (&offset_expr, "daddiu", "t,r,j",
+ tempreg, tempreg, BFD_RELOC_MIPS_HIGHER);
+ macro_build (NULL, "dsll", "d,w,<", tempreg, tempreg, 16);
+ macro_build (&offset_expr, "daddiu", "t,r,j",
+ tempreg, tempreg, BFD_RELOC_HI16_S);
+ macro_build (NULL, "dsll", "d,w,<", tempreg, tempreg, 16);
+ macro_build (&offset_expr, "daddiu", "t,r,j",
+ tempreg, tempreg, BFD_RELOC_LO16);
+ }
+ }
+ else
+ {
+ if ((valueT) offset_expr.X_add_number <= MAX_GPREL_OFFSET
+ && ! nopic_need_relax (offset_expr.X_add_symbol, 1))
+ {
+ relax_start (offset_expr.X_add_symbol);
+ macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j",
+ tempreg, mips_gp_register, BFD_RELOC_GPREL16);
+ relax_switch ();
+ }
+ macro_build_lui (&offset_expr, tempreg);
+ macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j",
+ tempreg, tempreg, BFD_RELOC_LO16);
+ if (mips_relax.sequence)
+ relax_end ();
+ }
+ }
+ else if (mips_pic == SVR4_PIC && ! mips_big_got && ! HAVE_NEWABI)
+ {
+ int lw_reloc_type = (int) BFD_RELOC_MIPS_GOT16;
+
+ /* If this is a reference to an external symbol, and there
+ is no constant, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ or for lca or if tempreg is PIC_CALL_REG
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_CALL16)
+ For a local symbol, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $tempreg,$tempreg,<sym> (BFD_RELOC_LO16)
+
+ If we have a small constant, and this is a reference to
+ an external symbol, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $tempreg,$tempreg,<constant>
+ For a local symbol, we want the same instruction
+ sequence, but we output a BFD_RELOC_LO16 reloc on the
+ addiu instruction.
+
+ If we have a large constant, and this is a reference to
+ an external symbol, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ lui $at,<hiconstant>
+ addiu $at,$at,<loconstant>
+ addu $tempreg,$tempreg,$at
+ For a local symbol, we want the same instruction
+ sequence, but we output a BFD_RELOC_LO16 reloc on the
+ addiu instruction.
+ */
+
+ if (offset_expr.X_add_number == 0)
+ {
+ if (breg == 0 && (call || tempreg == PIC_CALL_REG))
+ lw_reloc_type = (int) BFD_RELOC_MIPS_CALL16;
+
+ relax_start (offset_expr.X_add_symbol);
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
+ lw_reloc_type, mips_gp_register);
+ if (breg != 0)
+ {
+ /* We're going to put in an addu instruction using
+ tempreg, so we may as well insert the nop right
+ now. */
+ macro_build (NULL, "nop", "");
+ }
+ relax_switch ();
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
+ tempreg, BFD_RELOC_MIPS_GOT16, mips_gp_register);
+ macro_build (NULL, "nop", "");
+ macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j",
+ tempreg, tempreg, BFD_RELOC_LO16);
+ relax_end ();
+ /* FIXME: If breg == 0, and the next instruction uses
+ $tempreg, then if this variant case is used an extra
+ nop will be generated. */
+ }
+ else if (offset_expr.X_add_number >= -0x8000
+ && offset_expr.X_add_number < 0x8000)
+ {
+ load_got_offset (tempreg, &offset_expr);
+ macro_build (NULL, "nop", "");
+ add_got_offset (tempreg, &offset_expr);
+ }
+ else
+ {
+ expr1.X_add_number = offset_expr.X_add_number;
+ offset_expr.X_add_number =
+ ((offset_expr.X_add_number + 0x8000) & 0xffff) - 0x8000;
+ load_got_offset (tempreg, &offset_expr);
+ offset_expr.X_add_number = expr1.X_add_number;
+ /* If we are going to add in a base register, and the
+ target register and the base register are the same,
+ then we are using AT as a temporary register. Since
+ we want to load the constant into AT, we add our
+ current AT (from the global offset table) and the
+ register into the register now, and pretend we were
+ not using a base register. */
+ if (breg == treg)
+ {
+ macro_build (NULL, "nop", "");
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ treg, AT, breg);
+ breg = 0;
+ tempreg = treg;
+ }
+ add_got_offset_hilo (tempreg, &offset_expr, AT);
+ used_at = 1;
+ }
+ }
+ else if (mips_pic == SVR4_PIC && ! mips_big_got && HAVE_NEWABI)
+ {
+ int add_breg_early = 0;
+
+ /* If this is a reference to an external, and there is no
+ constant, or local symbol (*), with or without a
+ constant, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT_DISP)
+ or for lca or if tempreg is PIC_CALL_REG
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_CALL16)
+
+ If we have a small constant, and this is a reference to
+ an external symbol, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT_DISP)
+ addiu $tempreg,$tempreg,<constant>
+
+ If we have a large constant, and this is a reference to
+ an external symbol, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT_DISP)
+ lui $at,<hiconstant>
+ addiu $at,$at,<loconstant>
+ addu $tempreg,$tempreg,$at
+
+ (*) Other assemblers seem to prefer GOT_PAGE/GOT_OFST for
+ local symbols, even though it introduces an additional
+ instruction. */
+
+ if (offset_expr.X_add_number)
+ {
+ expr1.X_add_number = offset_expr.X_add_number;
+ offset_expr.X_add_number = 0;
+
+ relax_start (offset_expr.X_add_symbol);
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
+ BFD_RELOC_MIPS_GOT_DISP, mips_gp_register);
+
+ if (expr1.X_add_number >= -0x8000
+ && expr1.X_add_number < 0x8000)
+ {
+ macro_build (&expr1, ADDRESS_ADDI_INSN, "t,r,j",
+ tempreg, tempreg, BFD_RELOC_LO16);
+ }
+ else if (IS_SEXT_32BIT_NUM (expr1.X_add_number + 0x8000))
+ {
+ int dreg;
+
+ /* If we are going to add in a base register, and the
+ target register and the base register are the same,
+ then we are using AT as a temporary register. Since
+ we want to load the constant into AT, we add our
+ current AT (from the global offset table) and the
+ register into the register now, and pretend we were
+ not using a base register. */
+ if (breg != treg)
+ dreg = tempreg;
+ else
+ {
+ assert (tempreg == AT);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ treg, AT, breg);
+ dreg = treg;
+ add_breg_early = 1;
+ }
+
+ load_register (AT, &expr1, HAVE_64BIT_ADDRESSES);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ dreg, dreg, AT);
+
+ used_at = 1;
+ }
+ else
+ as_bad (_("PIC code offset overflow (max 32 signed bits)"));
+
+ relax_switch ();
+ offset_expr.X_add_number = expr1.X_add_number;
+
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
+ BFD_RELOC_MIPS_GOT_DISP, mips_gp_register);
+ if (add_breg_early)
+ {
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ treg, tempreg, breg);
+ breg = 0;
+ tempreg = treg;
+ }
+ relax_end ();
+ }
+ else if (breg == 0 && (call || tempreg == PIC_CALL_REG))
+ {
+ relax_start (offset_expr.X_add_symbol);
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
+ BFD_RELOC_MIPS_CALL16, mips_gp_register);
+ relax_switch ();
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
+ BFD_RELOC_MIPS_GOT_DISP, mips_gp_register);
+ relax_end ();
+ }
+ else
+ {
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
+ BFD_RELOC_MIPS_GOT_DISP, mips_gp_register);
+ }
+ }
+ else if (mips_pic == SVR4_PIC && ! HAVE_NEWABI)
+ {
+ int gpdelay;
+ int lui_reloc_type = (int) BFD_RELOC_MIPS_GOT_HI16;
+ int lw_reloc_type = (int) BFD_RELOC_MIPS_GOT_LO16;
+ int local_reloc_type = (int) BFD_RELOC_MIPS_GOT16;
+
+ /* This is the large GOT case. If this is a reference to an
+ external symbol, and there is no constant, we want
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_GOT_HI16)
+ addu $tempreg,$tempreg,$gp
+ lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)
+ or for lca or if tempreg is PIC_CALL_REG
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_CALL_HI16)
+ addu $tempreg,$tempreg,$gp
+ lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_CALL_LO16)
+ For a local symbol, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $tempreg,$tempreg,<sym> (BFD_RELOC_LO16)
+
+ If we have a small constant, and this is a reference to
+ an external symbol, we want
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_GOT_HI16)
+ addu $tempreg,$tempreg,$gp
+ lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)
+ nop
+ addiu $tempreg,$tempreg,<constant>
+ For a local symbol, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $tempreg,$tempreg,<constant> (BFD_RELOC_LO16)
+
+ If we have a large constant, and this is a reference to
+ an external symbol, we want
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_GOT_HI16)
+ addu $tempreg,$tempreg,$gp
+ lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)
+ lui $at,<hiconstant>
+ addiu $at,$at,<loconstant>
+ addu $tempreg,$tempreg,$at
+ For a local symbol, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ lui $at,<hiconstant>
+ addiu $at,$at,<loconstant> (BFD_RELOC_LO16)
+ addu $tempreg,$tempreg,$at
+ */
+
+ expr1.X_add_number = offset_expr.X_add_number;
+ offset_expr.X_add_number = 0;
+ relax_start (offset_expr.X_add_symbol);
+ gpdelay = reg_needs_delay (mips_gp_register);
+ if (expr1.X_add_number == 0 && breg == 0
+ && (call || tempreg == PIC_CALL_REG))
+ {
+ lui_reloc_type = (int) BFD_RELOC_MIPS_CALL_HI16;
+ lw_reloc_type = (int) BFD_RELOC_MIPS_CALL_LO16;
+ }
+ macro_build (&offset_expr, "lui", "t,u", tempreg, lui_reloc_type);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ tempreg, tempreg, mips_gp_register);
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
+ tempreg, lw_reloc_type, tempreg);
+ if (expr1.X_add_number == 0)
+ {
+ if (breg != 0)
+ {
+ /* We're going to put in an addu instruction using
+ tempreg, so we may as well insert the nop right
+ now. */
+ macro_build (NULL, "nop", "");
+ }
+ }
+ else if (expr1.X_add_number >= -0x8000
+ && expr1.X_add_number < 0x8000)
+ {
+ macro_build (NULL, "nop", "");
+ macro_build (&expr1, ADDRESS_ADDI_INSN, "t,r,j",
+ tempreg, tempreg, BFD_RELOC_LO16);
+ }
+ else
+ {
+ int dreg;
+
+ /* If we are going to add in a base register, and the
+ target register and the base register are the same,
+ then we are using AT as a temporary register. Since
+ we want to load the constant into AT, we add our
+ current AT (from the global offset table) and the
+ register into the register now, and pretend we were
+ not using a base register. */
+ if (breg != treg)
+ dreg = tempreg;
+ else
+ {
+ assert (tempreg == AT);
+ macro_build (NULL, "nop", "");
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ treg, AT, breg);
+ dreg = treg;
+ }
+
+ load_register (AT, &expr1, HAVE_64BIT_ADDRESSES);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", dreg, dreg, AT);
+
+ used_at = 1;
+ }
+ offset_expr.X_add_number =
+ ((expr1.X_add_number + 0x8000) & 0xffff) - 0x8000;
+ relax_switch ();
+
+ if (gpdelay)
+ {
+ /* This is needed because this instruction uses $gp, but
+ the first instruction on the main stream does not. */
+ macro_build (NULL, "nop", "");
+ }
+
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
+ local_reloc_type, mips_gp_register);
+ if (expr1.X_add_number >= -0x8000
+ && expr1.X_add_number < 0x8000)
+ {
+ macro_build (NULL, "nop", "");
+ macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j",
+ tempreg, tempreg, BFD_RELOC_LO16);
+ /* FIXME: If add_number is 0, and there was no base
+ register, the external symbol case ended with a load,
+ so if the symbol turns out to not be external, and
+ the next instruction uses tempreg, an unnecessary nop
+ will be inserted. */
+ }
+ else
+ {
+ if (breg == treg)
+ {
+ /* We must add in the base register now, as in the
+ external symbol case. */
+ assert (tempreg == AT);
+ macro_build (NULL, "nop", "");
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ treg, AT, breg);
+ tempreg = treg;
+ /* We set breg to 0 because we have arranged to add
+ it in in both cases. */
+ breg = 0;
+ }
+
+ macro_build_lui (&expr1, AT);
+ macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j",
+ AT, AT, BFD_RELOC_LO16);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ tempreg, tempreg, AT);
+ }
+ relax_end ();
+ }
+ else if (mips_pic == SVR4_PIC && HAVE_NEWABI)
+ {
+ int lui_reloc_type = (int) BFD_RELOC_MIPS_GOT_HI16;
+ int lw_reloc_type = (int) BFD_RELOC_MIPS_GOT_LO16;
+ int add_breg_early = 0;
+
+ /* This is the large GOT case. If this is a reference to an
+ external symbol, and there is no constant, we want
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_GOT_HI16)
+ add $tempreg,$tempreg,$gp
+ lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)
+ or for lca or if tempreg is PIC_CALL_REG
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_CALL_HI16)
+ add $tempreg,$tempreg,$gp
+ lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_CALL_LO16)
+
+ If we have a small constant, and this is a reference to
+ an external symbol, we want
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_GOT_HI16)
+ add $tempreg,$tempreg,$gp
+ lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)
+ addi $tempreg,$tempreg,<constant>
+
+ If we have a large constant, and this is a reference to
+ an external symbol, we want
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_GOT_HI16)
+ addu $tempreg,$tempreg,$gp
+ lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)
+ lui $at,<hiconstant>
+ addi $at,$at,<loconstant>
+ add $tempreg,$tempreg,$at
+
+ If we have NewABI, and we know it's a local symbol, we want
+ lw $reg,<sym>($gp) (BFD_RELOC_MIPS_GOT_PAGE)
+ addiu $reg,$reg,<sym> (BFD_RELOC_MIPS_GOT_OFST)
+ otherwise we have to resort to GOT_HI16/GOT_LO16. */
+
+ relax_start (offset_expr.X_add_symbol);
+
+ expr1.X_add_number = offset_expr.X_add_number;
+ offset_expr.X_add_number = 0;
+
+ if (expr1.X_add_number == 0 && breg == 0
+ && (call || tempreg == PIC_CALL_REG))
+ {
+ lui_reloc_type = (int) BFD_RELOC_MIPS_CALL_HI16;
+ lw_reloc_type = (int) BFD_RELOC_MIPS_CALL_LO16;
+ }
+ macro_build (&offset_expr, "lui", "t,u", tempreg, lui_reloc_type);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ tempreg, tempreg, mips_gp_register);
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
+ tempreg, lw_reloc_type, tempreg);
+
+ if (expr1.X_add_number == 0)
+ ;
+ else if (expr1.X_add_number >= -0x8000
+ && expr1.X_add_number < 0x8000)
+ {
+ macro_build (&expr1, ADDRESS_ADDI_INSN, "t,r,j",
+ tempreg, tempreg, BFD_RELOC_LO16);
+ }
+ else if (IS_SEXT_32BIT_NUM (expr1.X_add_number + 0x8000))
+ {
+ int dreg;
+
+ /* If we are going to add in a base register, and the
+ target register and the base register are the same,
+ then we are using AT as a temporary register. Since
+ we want to load the constant into AT, we add our
+ current AT (from the global offset table) and the
+ register into the register now, and pretend we were
+ not using a base register. */
+ if (breg != treg)
+ dreg = tempreg;
+ else
+ {
+ assert (tempreg == AT);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ treg, AT, breg);
+ dreg = treg;
+ add_breg_early = 1;
+ }
+
+ load_register (AT, &expr1, HAVE_64BIT_ADDRESSES);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", dreg, dreg, AT);
+
+ used_at = 1;
+ }
+ else
+ as_bad (_("PIC code offset overflow (max 32 signed bits)"));
+
+ relax_switch ();
+ offset_expr.X_add_number = expr1.X_add_number;
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
+ BFD_RELOC_MIPS_GOT_PAGE, mips_gp_register);
+ macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j", tempreg,
+ tempreg, BFD_RELOC_MIPS_GOT_OFST);
+ if (add_breg_early)
+ {
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ treg, tempreg, breg);
+ breg = 0;
+ tempreg = treg;
+ }
+ relax_end ();
+ }
+ else if (mips_pic == EMBEDDED_PIC)
+ {
+ /* We use
+ addiu $tempreg,$gp,<sym> (BFD_RELOC_GPREL16)
+ */
+ macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j", tempreg,
+ mips_gp_register, BFD_RELOC_GPREL16);
+ }
+ else
+ abort ();
+
+ if (breg != 0)
+ {
+ char *s;
+
+ if (mips_pic == EMBEDDED_PIC || mips_pic == NO_PIC)
+ s = (dbl || HAVE_64BIT_ADDRESSES) ? "daddu" : "addu";
+ else
+ s = ADDRESS_ADD_INSN;
+
+ macro_build (NULL, s, "d,v,t", treg, tempreg, breg);
+ }
+
+ if (! used_at)
+ return;
+
+ break;
+
+ case M_J_A:
+ /* The j instruction may not be used in PIC code, since it
+ requires an absolute address. We convert it to a b
+ instruction. */
+ if (mips_pic == NO_PIC)
+ macro_build (&offset_expr, "j", "a");
+ else
+ macro_build (&offset_expr, "b", "p");
+ return;
+
+ /* The jal instructions must be handled as macros because when
+ generating PIC code they expand to multi-instruction
+ sequences. Normally they are simple instructions. */
+ case M_JAL_1:
+ dreg = RA;
+ /* Fall through. */
+ case M_JAL_2:
+ if (mips_pic == NO_PIC
+ || mips_pic == EMBEDDED_PIC)
+ macro_build (NULL, "jalr", "d,s", dreg, sreg);
+ else if (mips_pic == SVR4_PIC)
+ {
+ if (sreg != PIC_CALL_REG)
+ as_warn (_("MIPS PIC call to register other than $25"));
+
+ macro_build (NULL, "jalr", "d,s", dreg, sreg);
+ if (! HAVE_NEWABI)
+ {
+ if (mips_cprestore_offset < 0)
+ as_warn (_("No .cprestore pseudo-op used in PIC code"));
+ else
+ {
+ if (! mips_frame_reg_valid)
+ {
+ as_warn (_("No .frame pseudo-op used in PIC code"));
+ /* Quiet this warning. */
+ mips_frame_reg_valid = 1;
+ }
+ if (! mips_cprestore_valid)
+ {
+ as_warn (_("No .cprestore pseudo-op used in PIC code"));
+ /* Quiet this warning. */
+ mips_cprestore_valid = 1;
+ }
+ expr1.X_add_number = mips_cprestore_offset;
+ macro_build_ldst_constoffset (&expr1, ADDRESS_LOAD_INSN,
+ mips_gp_register,
+ mips_frame_reg,
+ HAVE_64BIT_ADDRESSES);
+ }
+ }
+ }
+ else
+ abort ();
+
+ return;
+
+ case M_JAL_A:
+ if (mips_pic == NO_PIC)
+ macro_build (&offset_expr, "jal", "a");
+ else if (mips_pic == SVR4_PIC)
+ {
+ /* If this is a reference to an external symbol, and we are
+ using a small GOT, we want
+ lw $25,<sym>($gp) (BFD_RELOC_MIPS_CALL16)
+ nop
+ jalr $ra,$25
+ nop
+ lw $gp,cprestore($sp)
+ The cprestore value is set using the .cprestore
+ pseudo-op. If we are using a big GOT, we want
+ lui $25,<sym> (BFD_RELOC_MIPS_CALL_HI16)
+ addu $25,$25,$gp
+ lw $25,<sym>($25) (BFD_RELOC_MIPS_CALL_LO16)
+ nop
+ jalr $ra,$25
+ nop
+ lw $gp,cprestore($sp)
+ If the symbol is not external, we want
+ lw $25,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $25,$25,<sym> (BFD_RELOC_LO16)
+ jalr $ra,$25
+ nop
+ lw $gp,cprestore($sp)
+
+ For NewABI, we use the same CALL16 or CALL_HI16/CALL_LO16
+ sequences above, minus nops, unless the symbol is local,
+ which enables us to use GOT_PAGE/GOT_OFST (big got) or
+ GOT_DISP. */
+ if (HAVE_NEWABI)
+ {
+ if (! mips_big_got)
+ {
+ relax_start (offset_expr.X_add_symbol);
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
+ PIC_CALL_REG, BFD_RELOC_MIPS_CALL16,
+ mips_gp_register);
+ relax_switch ();
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
+ PIC_CALL_REG, BFD_RELOC_MIPS_GOT_DISP,
+ mips_gp_register);
+ relax_end ();
+ }
+ else
+ {
+ relax_start (offset_expr.X_add_symbol);
+ macro_build (&offset_expr, "lui", "t,u", PIC_CALL_REG,
+ BFD_RELOC_MIPS_CALL_HI16);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", PIC_CALL_REG,
+ PIC_CALL_REG, mips_gp_register);
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
+ PIC_CALL_REG, BFD_RELOC_MIPS_CALL_LO16,
+ PIC_CALL_REG);
+ relax_switch ();
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
+ PIC_CALL_REG, BFD_RELOC_MIPS_GOT_PAGE,
+ mips_gp_register);
+ macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j",
+ PIC_CALL_REG, PIC_CALL_REG,
+ BFD_RELOC_MIPS_GOT_OFST);
+ relax_end ();
+ }
+
+ macro_build_jalr (&offset_expr);
+ }
+ else
+ {
+ relax_start (offset_expr.X_add_symbol);
+ if (! mips_big_got)
+ {
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
+ PIC_CALL_REG, BFD_RELOC_MIPS_CALL16,
+ mips_gp_register);
+ macro_build (NULL, "nop", "");
+ relax_switch ();
+ }
+ else
+ {
+ int gpdelay;
+
+ gpdelay = reg_needs_delay (mips_gp_register);
+ macro_build (&offset_expr, "lui", "t,u", PIC_CALL_REG,
+ BFD_RELOC_MIPS_CALL_HI16);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", PIC_CALL_REG,
+ PIC_CALL_REG, mips_gp_register);
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
+ PIC_CALL_REG, BFD_RELOC_MIPS_CALL_LO16,
+ PIC_CALL_REG);
+ macro_build (NULL, "nop", "");
+ relax_switch ();
+ if (gpdelay)
+ macro_build (NULL, "nop", "");
+ }
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
+ PIC_CALL_REG, BFD_RELOC_MIPS_GOT16,
+ mips_gp_register);
+ macro_build (NULL, "nop", "");
+ macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j",
+ PIC_CALL_REG, PIC_CALL_REG, BFD_RELOC_LO16);
+ relax_end ();
+ macro_build_jalr (&offset_expr);
+
+ if (mips_cprestore_offset < 0)
+ as_warn (_("No .cprestore pseudo-op used in PIC code"));
+ else
+ {
+ if (! mips_frame_reg_valid)
+ {
+ as_warn (_("No .frame pseudo-op used in PIC code"));
+ /* Quiet this warning. */
+ mips_frame_reg_valid = 1;
+ }
+ if (! mips_cprestore_valid)
+ {
+ as_warn (_("No .cprestore pseudo-op used in PIC code"));
+ /* Quiet this warning. */
+ mips_cprestore_valid = 1;
+ }
+ if (mips_opts.noreorder)
+ macro_build (NULL, "nop", "");
+ expr1.X_add_number = mips_cprestore_offset;
+ macro_build_ldst_constoffset (&expr1, ADDRESS_LOAD_INSN,
+ mips_gp_register,
+ mips_frame_reg,
+ HAVE_64BIT_ADDRESSES);
+ }
+ }
+ }
+ else if (mips_pic == EMBEDDED_PIC)
+ {
+ macro_build (&offset_expr, "bal", "p");
+ /* The linker may expand the call to a longer sequence which
+ uses $at, so we must break rather than return. */
+ break;
+ }
+ else
+ abort ();
+
+ return;
+
+ case M_LB_AB:
+ s = "lb";
+ goto ld;
+ case M_LBU_AB:
+ s = "lbu";
+ goto ld;
+ case M_LH_AB:
+ s = "lh";
+ goto ld;
+ case M_LHU_AB:
+ s = "lhu";
+ goto ld;
+ case M_LW_AB:
+ s = "lw";
+ goto ld;
+ case M_LWC0_AB:
+ s = "lwc0";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ld;
+ case M_LWC1_AB:
+ s = "lwc1";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ld;
+ case M_LWC2_AB:
+ s = "lwc2";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ld;
+ case M_LWC3_AB:
+ s = "lwc3";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ld;
+ case M_LWL_AB:
+ s = "lwl";
+ lr = 1;
+ goto ld;
+ case M_LWR_AB:
+ s = "lwr";
+ lr = 1;
+ goto ld;
+ case M_LDC1_AB:
+ if (mips_opts.arch == CPU_R4650)
+ {
+ as_bad (_("opcode not supported on this processor"));
+ return;
+ }
+ s = "ldc1";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ld;
+ case M_LDC2_AB:
+ s = "ldc2";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ld;
+ case M_LDC3_AB:
+ s = "ldc3";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ld;
+ case M_LDL_AB:
+ s = "ldl";
+ lr = 1;
+ goto ld;
+ case M_LDR_AB:
+ s = "ldr";
+ lr = 1;
+ goto ld;
+ case M_LL_AB:
+ s = "ll";
+ goto ld;
+ case M_LLD_AB:
+ s = "lld";
+ goto ld;
+ case M_LWU_AB:
+ s = "lwu";
+ ld:
+ if (breg == treg || coproc || lr)
+ {
+ tempreg = AT;
+ used_at = 1;
+ }
+ else
+ {
+ tempreg = treg;
+ used_at = 0;
+ }
+ goto ld_st;
+ case M_SB_AB:
+ s = "sb";
+ goto st;
+ case M_SH_AB:
+ s = "sh";
+ goto st;
+ case M_SW_AB:
+ s = "sw";
+ goto st;
+ case M_SWC0_AB:
+ s = "swc0";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto st;
+ case M_SWC1_AB:
+ s = "swc1";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto st;
+ case M_SWC2_AB:
+ s = "swc2";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto st;
+ case M_SWC3_AB:
+ s = "swc3";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto st;
+ case M_SWL_AB:
+ s = "swl";
+ goto st;
+ case M_SWR_AB:
+ s = "swr";
+ goto st;
+ case M_SC_AB:
+ s = "sc";
+ goto st;
+ case M_SCD_AB:
+ s = "scd";
+ goto st;
+ case M_SDC1_AB:
+ if (mips_opts.arch == CPU_R4650)
+ {
+ as_bad (_("opcode not supported on this processor"));
+ return;
+ }
+ s = "sdc1";
+ coproc = 1;
+ /* Itbl support may require additional care here. */
+ goto st;
+ case M_SDC2_AB:
+ s = "sdc2";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto st;
+ case M_SDC3_AB:
+ s = "sdc3";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto st;
+ case M_SDL_AB:
+ s = "sdl";
+ goto st;
+ case M_SDR_AB:
+ s = "sdr";
+ st:
+ tempreg = AT;
+ used_at = 1;
+ ld_st:
+ /* Itbl support may require additional care here. */
+ if (mask == M_LWC1_AB
+ || mask == M_SWC1_AB
+ || mask == M_LDC1_AB
+ || mask == M_SDC1_AB
+ || mask == M_L_DAB
+ || mask == M_S_DAB)
+ fmt = "T,o(b)";
+ else if (coproc)
+ fmt = "E,o(b)";
+ else
+ fmt = "t,o(b)";
+
+ /* Sign-extending 32-bit constants makes their handling easier.
+ The HAVE_64BIT_GPRS... part is due to the linux kernel hack
+ described below. */
+ if ((! HAVE_64BIT_ADDRESSES
+ && (! HAVE_64BIT_GPRS && offset_expr.X_op == O_constant))
+ && (offset_expr.X_op == O_constant)
+ && ! ((offset_expr.X_add_number & ~((bfd_vma) 0x7fffffff))
+ == ~((bfd_vma) 0x7fffffff)))
+ {
+ if (offset_expr.X_add_number & ~((bfd_vma) 0xffffffff))
+ as_bad (_("constant too large"));
+
+ offset_expr.X_add_number = (((offset_expr.X_add_number & 0xffffffff)
+ ^ 0x80000000) - 0x80000000);
+ }
+
+ /* For embedded PIC, we allow loads where the offset is calculated
+ by subtracting a symbol in the current segment from an unknown
+ symbol, relative to a base register, e.g.:
+ <op> $treg, <sym>-<localsym>($breg)
+ This is used by the compiler for switch statements. */
+ if (mips_pic == EMBEDDED_PIC
+ && offset_expr.X_op == O_subtract
+ && (symbol_constant_p (offset_expr.X_op_symbol)
+ ? S_GET_SEGMENT (offset_expr.X_op_symbol) == now_seg
+ : (symbol_equated_p (offset_expr.X_op_symbol)
+ && (S_GET_SEGMENT
+ (symbol_get_value_expression (offset_expr.X_op_symbol)
+ ->X_add_symbol)
+ == now_seg)))
+ && breg != 0
+ && (offset_expr.X_add_number == 0
+ || OUTPUT_FLAVOR == bfd_target_elf_flavour))
+ {
+ /* For this case, we output the instructions:
+ lui $tempreg,<sym> (BFD_RELOC_PCREL_HI16_S)
+ addiu $tempreg,$tempreg,$breg
+ <op> $treg,<sym>($tempreg) (BFD_RELOC_PCREL_LO16)
+ If the relocation would fit entirely in 16 bits, it would be
+ nice to emit:
+ <op> $treg,<sym>($breg) (BFD_RELOC_PCREL_LO16)
+ instead, but that seems quite difficult. */
+ macro_build (&offset_expr, "lui", "t,u", tempreg,
+ BFD_RELOC_PCREL_HI16_S);
+ macro_build (NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
+ ? "addu" : "daddu"),
+ "d,v,t", tempreg, tempreg, breg);
+ macro_build (&offset_expr, s, fmt, treg,
+ BFD_RELOC_PCREL_LO16, tempreg);
+ if (! used_at)
+ return;
+ break;
+ }
+
+ if (offset_expr.X_op != O_constant
+ && offset_expr.X_op != O_symbol)
+ {
+ as_bad (_("expression too complex"));
+ offset_expr.X_op = O_constant;
+ }
+
+ /* A constant expression in PIC code can be handled just as it
+ is in non PIC code. */
+ if (mips_pic == NO_PIC
+ || offset_expr.X_op == O_constant)
+ {
+ /* If this is a reference to a GP relative symbol, and there
+ is no base register, we want
+ <op> $treg,<sym>($gp) (BFD_RELOC_GPREL16)
+ Otherwise, if there is no base register, we want
+ lui $tempreg,<sym> (BFD_RELOC_HI16_S)
+ <op> $treg,<sym>($tempreg) (BFD_RELOC_LO16)
+ If we have a constant, we need two instructions anyhow,
+ so we always use the latter form.
+
+ If we have a base register, and this is a reference to a
+ GP relative symbol, we want
+ addu $tempreg,$breg,$gp
+ <op> $treg,<sym>($tempreg) (BFD_RELOC_GPREL16)
+ Otherwise we want
+ lui $tempreg,<sym> (BFD_RELOC_HI16_S)
+ addu $tempreg,$tempreg,$breg
+ <op> $treg,<sym>($tempreg) (BFD_RELOC_LO16)
+ With a constant we always use the latter case.
+
+ With 64bit address space and no base register and $at usable,
+ we want
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_HIGHEST)
+ lui $at,<sym> (BFD_RELOC_HI16_S)
+ daddiu $tempreg,<sym> (BFD_RELOC_MIPS_HIGHER)
+ dsll32 $tempreg,0
+ daddu $tempreg,$at
+ <op> $treg,<sym>($tempreg) (BFD_RELOC_LO16)
+ If we have a base register, we want
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_HIGHEST)
+ lui $at,<sym> (BFD_RELOC_HI16_S)
+ daddiu $tempreg,<sym> (BFD_RELOC_MIPS_HIGHER)
+ daddu $at,$breg
+ dsll32 $tempreg,0
+ daddu $tempreg,$at
+ <op> $treg,<sym>($tempreg) (BFD_RELOC_LO16)
+
+ Without $at we can't generate the optimal path for superscalar
+ processors here since this would require two temporary registers.
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_HIGHEST)
+ daddiu $tempreg,<sym> (BFD_RELOC_MIPS_HIGHER)
+ dsll $tempreg,16
+ daddiu $tempreg,<sym> (BFD_RELOC_HI16_S)
+ dsll $tempreg,16
+ <op> $treg,<sym>($tempreg) (BFD_RELOC_LO16)
+ If we have a base register, we want
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_HIGHEST)
+ daddiu $tempreg,<sym> (BFD_RELOC_MIPS_HIGHER)
+ dsll $tempreg,16
+ daddiu $tempreg,<sym> (BFD_RELOC_HI16_S)
+ dsll $tempreg,16
+ daddu $tempreg,$tempreg,$breg
+ <op> $treg,<sym>($tempreg) (BFD_RELOC_LO16)
+
+ If we have 64-bit addresses, as an optimization, for
+ addresses which are 32-bit constants (e.g. kseg0/kseg1
+ addresses) we fall back to the 32-bit address generation
+ mechanism since it is more efficient. Note that due to
+ the signed offset used by memory operations, the 32-bit
+ range is shifted down by 32768 here. This code should
+ probably attempt to generate 64-bit constants more
+ efficiently in general.
+
+ As an extension for architectures with 64-bit registers,
+ we don't truncate 64-bit addresses given as literal
+ constants down to 32 bits, to support existing practice
+ in the mips64 Linux (the kernel), that compiles source
+ files with -mabi=64, assembling them as o32 or n32 (with
+ -Wa,-32 or -Wa,-n32). This is not beautiful, but since
+ the whole kernel is loaded into a memory region that is
+ addressable with sign-extended 32-bit addresses, it is
+ wasteful to compute the upper 32 bits of every
+ non-literal address, that takes more space and time.
+ Some day this should probably be implemented as an
+ assembler option, such that the kernel doesn't have to
+ use such ugly hacks, even though it will still have to
+ end up converting the binary to ELF32 for a number of
+ platforms whose boot loaders don't support ELF64
+ binaries. */
+ if ((HAVE_64BIT_ADDRESSES
+ && ! (offset_expr.X_op == O_constant
+ && IS_SEXT_32BIT_NUM (offset_expr.X_add_number + 0x8000)))
+ || (HAVE_64BIT_GPRS
+ && offset_expr.X_op == O_constant
+ && ! IS_SEXT_32BIT_NUM (offset_expr.X_add_number + 0x8000)))
+ {
+ /* ??? We don't provide a GP-relative alternative for
+ these macros. It used not to be possible with the
+ original relaxation code, but it could be done now. */
+
+ if (used_at == 0 && ! mips_opts.noat)
+ {
+ macro_build (&offset_expr, "lui", "t,u", tempreg,
+ BFD_RELOC_MIPS_HIGHEST);
+ macro_build (&offset_expr, "lui", "t,u", AT,
+ BFD_RELOC_HI16_S);
+ macro_build (&offset_expr, "daddiu", "t,r,j", tempreg,
+ tempreg, BFD_RELOC_MIPS_HIGHER);
+ if (breg != 0)
+ macro_build (NULL, "daddu", "d,v,t", AT, AT, breg);
+ macro_build (NULL, "dsll32", "d,w,<", tempreg, tempreg, 0);
+ macro_build (NULL, "daddu", "d,v,t", tempreg, tempreg, AT);
+ macro_build (&offset_expr, s, fmt, treg, BFD_RELOC_LO16,
+ tempreg);
+ used_at = 1;
+ }
+ else
+ {
+ macro_build (&offset_expr, "lui", "t,u", tempreg,
+ BFD_RELOC_MIPS_HIGHEST);
+ macro_build (&offset_expr, "daddiu", "t,r,j", tempreg,
+ tempreg, BFD_RELOC_MIPS_HIGHER);
+ macro_build (NULL, "dsll", "d,w,<", tempreg, tempreg, 16);
+ macro_build (&offset_expr, "daddiu", "t,r,j", tempreg,
+ tempreg, BFD_RELOC_HI16_S);
+ macro_build (NULL, "dsll", "d,w,<", tempreg, tempreg, 16);
+ if (breg != 0)
+ macro_build (NULL, "daddu", "d,v,t",
+ tempreg, tempreg, breg);
+ macro_build (&offset_expr, s, fmt, treg,
+ BFD_RELOC_LO16, tempreg);
+ }
+
+ return;
+ }
+
+ if (offset_expr.X_op == O_constant
+ && ! IS_SEXT_32BIT_NUM (offset_expr.X_add_number + 0x8000))
+ as_bad (_("load/store address overflow (max 32 bits)"));
+
+ if (breg == 0)
+ {
+ if ((valueT) offset_expr.X_add_number <= MAX_GPREL_OFFSET
+ && ! nopic_need_relax (offset_expr.X_add_symbol, 1))
+ {
+ relax_start (offset_expr.X_add_symbol);
+ macro_build (&offset_expr, s, fmt, treg, BFD_RELOC_GPREL16,
+ mips_gp_register);
+ relax_switch ();
+ used_at = 0;
+ }
+ macro_build_lui (&offset_expr, tempreg);
+ macro_build (&offset_expr, s, fmt, treg,
+ BFD_RELOC_LO16, tempreg);
+ if (mips_relax.sequence)
+ relax_end ();
+ }
+ else
+ {
+ if ((valueT) offset_expr.X_add_number <= MAX_GPREL_OFFSET
+ && ! nopic_need_relax (offset_expr.X_add_symbol, 1))
+ {
+ relax_start (offset_expr.X_add_symbol);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ tempreg, breg, mips_gp_register);
+ macro_build (&offset_expr, s, fmt, treg,
+ BFD_RELOC_GPREL16, tempreg);
+ relax_switch ();
+ }
+ macro_build_lui (&offset_expr, tempreg);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ tempreg, tempreg, breg);
+ macro_build (&offset_expr, s, fmt, treg,
+ BFD_RELOC_LO16, tempreg);
+ if (mips_relax.sequence)
+ relax_end ();
+ }
+ }
+ else if (mips_pic == SVR4_PIC && ! mips_big_got)
+ {
+ int lw_reloc_type = (int) BFD_RELOC_MIPS_GOT16;
+
+ /* If this is a reference to an external symbol, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ <op> $treg,0($tempreg)
+ Otherwise we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $tempreg,$tempreg,<sym> (BFD_RELOC_LO16)
+ <op> $treg,0($tempreg)
+
+ For NewABI, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT_PAGE)
+ <op> $treg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_OFST)
+
+ If there is a base register, we add it to $tempreg before
+ the <op>. If there is a constant, we stick it in the
+ <op> instruction. We don't handle constants larger than
+ 16 bits, because we have no way to load the upper 16 bits
+ (actually, we could handle them for the subset of cases
+ in which we are not using $at). */
+ assert (offset_expr.X_op == O_symbol);
+ if (HAVE_NEWABI)
+ {
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
+ BFD_RELOC_MIPS_GOT_PAGE, mips_gp_register);
+ if (breg != 0)
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ tempreg, tempreg, breg);
+ macro_build (&offset_expr, s, fmt, treg,
+ BFD_RELOC_MIPS_GOT_OFST, tempreg);
+
+ if (! used_at)
+ return;
+
+ break;
+ }
+ expr1.X_add_number = offset_expr.X_add_number;
+ offset_expr.X_add_number = 0;
+ if (expr1.X_add_number < -0x8000
+ || expr1.X_add_number >= 0x8000)
+ as_bad (_("PIC code offset overflow (max 16 signed bits)"));
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
+ lw_reloc_type, mips_gp_register);
+ macro_build (NULL, "nop", "");
+ relax_start (offset_expr.X_add_symbol);
+ relax_switch ();
+ macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j", tempreg,
+ tempreg, BFD_RELOC_LO16);
+ relax_end ();
+ if (breg != 0)
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ tempreg, tempreg, breg);
+ macro_build (&expr1, s, fmt, treg, BFD_RELOC_LO16, tempreg);
+ }
+ else if (mips_pic == SVR4_PIC && ! HAVE_NEWABI)
+ {
+ int gpdelay;
+
+ /* If this is a reference to an external symbol, we want
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_GOT_HI16)
+ addu $tempreg,$tempreg,$gp
+ lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)
+ <op> $treg,0($tempreg)
+ Otherwise we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $tempreg,$tempreg,<sym> (BFD_RELOC_LO16)
+ <op> $treg,0($tempreg)
+ If there is a base register, we add it to $tempreg before
+ the <op>. If there is a constant, we stick it in the
+ <op> instruction. We don't handle constants larger than
+ 16 bits, because we have no way to load the upper 16 bits
+ (actually, we could handle them for the subset of cases
+ in which we are not using $at). */
+ assert (offset_expr.X_op == O_symbol);
+ expr1.X_add_number = offset_expr.X_add_number;
+ offset_expr.X_add_number = 0;
+ if (expr1.X_add_number < -0x8000
+ || expr1.X_add_number >= 0x8000)
+ as_bad (_("PIC code offset overflow (max 16 signed bits)"));
+ gpdelay = reg_needs_delay (mips_gp_register);
+ relax_start (offset_expr.X_add_symbol);
+ macro_build (&offset_expr, "lui", "t,u", tempreg,
+ BFD_RELOC_MIPS_GOT_HI16);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", tempreg, tempreg,
+ mips_gp_register);
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
+ BFD_RELOC_MIPS_GOT_LO16, tempreg);
+ relax_switch ();
+ if (gpdelay)
+ macro_build (NULL, "nop", "");
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
+ BFD_RELOC_MIPS_GOT16, mips_gp_register);
+ macro_build (NULL, "nop", "");
+ macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j", tempreg,
+ tempreg, BFD_RELOC_LO16);
+ relax_end ();
+
+ if (breg != 0)
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ tempreg, tempreg, breg);
+ macro_build (&expr1, s, fmt, treg, BFD_RELOC_LO16, tempreg);
+ }
+ else if (mips_pic == SVR4_PIC && HAVE_NEWABI)
+ {
+ /* If this is a reference to an external symbol, we want
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_GOT_HI16)
+ add $tempreg,$tempreg,$gp
+ lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)
+ <op> $treg,<ofst>($tempreg)
+ Otherwise, for local symbols, we want:
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT_PAGE)
+ <op> $treg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_OFST) */
+ assert (offset_expr.X_op == O_symbol);
+ expr1.X_add_number = offset_expr.X_add_number;
+ offset_expr.X_add_number = 0;
+ if (expr1.X_add_number < -0x8000
+ || expr1.X_add_number >= 0x8000)
+ as_bad (_("PIC code offset overflow (max 16 signed bits)"));
+ relax_start (offset_expr.X_add_symbol);
+ macro_build (&offset_expr, "lui", "t,u", tempreg,
+ BFD_RELOC_MIPS_GOT_HI16);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", tempreg, tempreg,
+ mips_gp_register);
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
+ BFD_RELOC_MIPS_GOT_LO16, tempreg);
+ if (breg != 0)
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ tempreg, tempreg, breg);
+ macro_build (&expr1, s, fmt, treg, BFD_RELOC_LO16, tempreg);
+
+ relax_switch ();
+ offset_expr.X_add_number = expr1.X_add_number;
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
+ BFD_RELOC_MIPS_GOT_PAGE, mips_gp_register);
+ if (breg != 0)
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ tempreg, tempreg, breg);
+ macro_build (&offset_expr, s, fmt, treg,
+ BFD_RELOC_MIPS_GOT_OFST, tempreg);
+ relax_end ();
+ }
+ else if (mips_pic == EMBEDDED_PIC)
+ {
+ /* If there is no base register, we want
+ <op> $treg,<sym>($gp) (BFD_RELOC_GPREL16)
+ If there is a base register, we want
+ addu $tempreg,$breg,$gp
+ <op> $treg,<sym>($tempreg) (BFD_RELOC_GPREL16)
+ */
+ assert (offset_expr.X_op == O_symbol);
+ if (breg == 0)
+ {
+ macro_build (&offset_expr, s, fmt, treg, BFD_RELOC_GPREL16,
+ mips_gp_register);
+ used_at = 0;
+ }
+ else
+ {
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ tempreg, breg, mips_gp_register);
+ macro_build (&offset_expr, s, fmt, treg,
+ BFD_RELOC_GPREL16, tempreg);
+ }
+ }
+ else
+ abort ();
+
+ if (! used_at)
+ return;
+
+ break;
+
+ case M_LI:
+ case M_LI_S:
+ load_register (treg, &imm_expr, 0);
+ return;
+
+ case M_DLI:
+ load_register (treg, &imm_expr, 1);
+ return;
+
+ case M_LI_SS:
+ if (imm_expr.X_op == O_constant)
+ {
+ load_register (AT, &imm_expr, 0);
+ macro_build (NULL, "mtc1", "t,G", AT, treg);
+ break;
+ }
+ else
+ {
+ assert (offset_expr.X_op == O_symbol
+ && strcmp (segment_name (S_GET_SEGMENT
+ (offset_expr.X_add_symbol)),
+ ".lit4") == 0
+ && offset_expr.X_add_number == 0);
+ macro_build (&offset_expr, "lwc1", "T,o(b)", treg,
+ BFD_RELOC_MIPS_LITERAL, mips_gp_register);
+ return;
+ }
+
+ case M_LI_D:
+ /* Check if we have a constant in IMM_EXPR. If the GPRs are 64 bits
+ wide, IMM_EXPR is the entire value. Otherwise IMM_EXPR is the high
+ order 32 bits of the value and the low order 32 bits are either
+ zero or in OFFSET_EXPR. */
+ if (imm_expr.X_op == O_constant || imm_expr.X_op == O_big)
+ {
+ if (HAVE_64BIT_GPRS)
+ load_register (treg, &imm_expr, 1);
+ else
+ {
+ int hreg, lreg;
+
+ if (target_big_endian)
+ {
+ hreg = treg;
+ lreg = treg + 1;
+ }
+ else
+ {
+ hreg = treg + 1;
+ lreg = treg;
+ }
+
+ if (hreg <= 31)
+ load_register (hreg, &imm_expr, 0);
+ if (lreg <= 31)
+ {
+ if (offset_expr.X_op == O_absent)
+ move_register (lreg, 0);
+ else
+ {
+ assert (offset_expr.X_op == O_constant);
+ load_register (lreg, &offset_expr, 0);
+ }
+ }
+ }
+ return;
+ }
+
+ /* We know that sym is in the .rdata section. First we get the
+ upper 16 bits of the address. */
+ if (mips_pic == NO_PIC)
+ {
+ macro_build_lui (&offset_expr, AT);
+ }
+ else if (mips_pic == SVR4_PIC)
+ {
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", AT,
+ BFD_RELOC_MIPS_GOT16, mips_gp_register);
+ }
+ else if (mips_pic == EMBEDDED_PIC)
+ {
+ /* For embedded PIC we pick up the entire address off $gp in
+ a single instruction. */
+ macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j", AT,
+ mips_gp_register, BFD_RELOC_GPREL16);
+ offset_expr.X_op = O_constant;
+ offset_expr.X_add_number = 0;
+ }
+ else
+ abort ();
+
+ /* Now we load the register(s). */
+ if (HAVE_64BIT_GPRS)
+ macro_build (&offset_expr, "ld", "t,o(b)", treg, BFD_RELOC_LO16, AT);
+ else
+ {
+ macro_build (&offset_expr, "lw", "t,o(b)", treg, BFD_RELOC_LO16, AT);
+ if (treg != RA)
+ {
+ /* FIXME: How in the world do we deal with the possible
+ overflow here? */
+ offset_expr.X_add_number += 4;
+ macro_build (&offset_expr, "lw", "t,o(b)",
+ treg + 1, BFD_RELOC_LO16, AT);
+ }
+ }
+ break;
+
+ case M_LI_DD:
+ /* Check if we have a constant in IMM_EXPR. If the FPRs are 64 bits
+ wide, IMM_EXPR is the entire value and the GPRs are known to be 64
+ bits wide as well. Otherwise IMM_EXPR is the high order 32 bits of
+ the value and the low order 32 bits are either zero or in
+ OFFSET_EXPR. */
+ if (imm_expr.X_op == O_constant || imm_expr.X_op == O_big)
+ {
+ load_register (AT, &imm_expr, HAVE_64BIT_FPRS);
+ if (HAVE_64BIT_FPRS)
+ {
+ assert (HAVE_64BIT_GPRS);
+ macro_build (NULL, "dmtc1", "t,S", AT, treg);
+ }
+ else
+ {
+ macro_build (NULL, "mtc1", "t,G", AT, treg + 1);
+ if (offset_expr.X_op == O_absent)
+ macro_build (NULL, "mtc1", "t,G", 0, treg);
+ else
+ {
+ assert (offset_expr.X_op == O_constant);
+ load_register (AT, &offset_expr, 0);
+ macro_build (NULL, "mtc1", "t,G", AT, treg);
+ }
+ }
+ break;
+ }
+
+ assert (offset_expr.X_op == O_symbol
+ && offset_expr.X_add_number == 0);
+ s = segment_name (S_GET_SEGMENT (offset_expr.X_add_symbol));
+ if (strcmp (s, ".lit8") == 0)
+ {
+ if (mips_opts.isa != ISA_MIPS1)
+ {
+ macro_build (&offset_expr, "ldc1", "T,o(b)", treg,
+ BFD_RELOC_MIPS_LITERAL, mips_gp_register);
+ return;
+ }
+ breg = mips_gp_register;
+ r = BFD_RELOC_MIPS_LITERAL;
+ goto dob;
+ }
+ else
+ {
+ assert (strcmp (s, RDATA_SECTION_NAME) == 0);
+ if (mips_pic == SVR4_PIC)
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", AT,
+ BFD_RELOC_MIPS_GOT16, mips_gp_register);
+ else
+ {
+ /* FIXME: This won't work for a 64 bit address. */
+ macro_build_lui (&offset_expr, AT);
+ }
+
+ if (mips_opts.isa != ISA_MIPS1)
+ {
+ macro_build (&offset_expr, "ldc1", "T,o(b)",
+ treg, BFD_RELOC_LO16, AT);
+ break;
+ }
+ breg = AT;
+ r = BFD_RELOC_LO16;
+ goto dob;
+ }
+
+ case M_L_DOB:
+ if (mips_opts.arch == CPU_R4650)
+ {
+ as_bad (_("opcode not supported on this processor"));
+ return;
+ }
+ /* Even on a big endian machine $fn comes before $fn+1. We have
+ to adjust when loading from memory. */
+ r = BFD_RELOC_LO16;
+ dob:
+ assert (mips_opts.isa == ISA_MIPS1);
+ macro_build (&offset_expr, "lwc1", "T,o(b)",
+ target_big_endian ? treg + 1 : treg, r, breg);
+ /* FIXME: A possible overflow which I don't know how to deal
+ with. */
+ offset_expr.X_add_number += 4;
+ macro_build (&offset_expr, "lwc1", "T,o(b)",
+ target_big_endian ? treg : treg + 1, r, breg);
+
+ if (breg != AT)
+ return;
+ break;
+
+ case M_L_DAB:
+ /*
+ * The MIPS assembler seems to check for X_add_number not
+ * being double aligned and generating:
+ * lui at,%hi(foo+1)
+ * addu at,at,v1
+ * addiu at,at,%lo(foo+1)
+ * lwc1 f2,0(at)
+ * lwc1 f3,4(at)
+ * But, the resulting address is the same after relocation so why
+ * generate the extra instruction?
+ */
+ if (mips_opts.arch == CPU_R4650)
+ {
+ as_bad (_("opcode not supported on this processor"));
+ return;
+ }
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ if (mips_opts.isa != ISA_MIPS1)
+ {
+ s = "ldc1";
+ goto ld;
+ }
+
+ s = "lwc1";
+ fmt = "T,o(b)";
+ goto ldd_std;
+
+ case M_S_DAB:
+ if (mips_opts.arch == CPU_R4650)
+ {
+ as_bad (_("opcode not supported on this processor"));
+ return;
+ }
+
+ if (mips_opts.isa != ISA_MIPS1)
+ {
+ s = "sdc1";
+ goto st;
+ }
+
+ s = "swc1";
+ fmt = "T,o(b)";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ldd_std;
+
+ case M_LD_AB:
+ if (HAVE_64BIT_GPRS)
+ {
+ s = "ld";
+ goto ld;
+ }
+
+ s = "lw";
+ fmt = "t,o(b)";
+ goto ldd_std;
+
+ case M_SD_AB:
+ if (HAVE_64BIT_GPRS)
+ {
+ s = "sd";
+ goto st;
+ }
+
+ s = "sw";
+ fmt = "t,o(b)";
+
+ ldd_std:
+ /* We do _not_ bother to allow embedded PIC (symbol-local_symbol)
+ loads for the case of doing a pair of loads to simulate an 'ld'.
+ This is not currently done by the compiler, and assembly coders
+ writing embedded-pic code can cope. */
+
+ if (offset_expr.X_op != O_symbol
+ && offset_expr.X_op != O_constant)
+ {
+ as_bad (_("expression too complex"));
+ offset_expr.X_op = O_constant;
+ }
+
+ /* Even on a big endian machine $fn comes before $fn+1. We have
+ to adjust when loading from memory. We set coproc if we must
+ load $fn+1 first. */
+ /* Itbl support may require additional care here. */
+ if (! target_big_endian)
+ coproc = 0;
+
+ if (mips_pic == NO_PIC
+ || offset_expr.X_op == O_constant)
+ {
+ /* If this is a reference to a GP relative symbol, we want
+ <op> $treg,<sym>($gp) (BFD_RELOC_GPREL16)
+ <op> $treg+1,<sym>+4($gp) (BFD_RELOC_GPREL16)
+ If we have a base register, we use this
+ addu $at,$breg,$gp
+ <op> $treg,<sym>($at) (BFD_RELOC_GPREL16)
+ <op> $treg+1,<sym>+4($at) (BFD_RELOC_GPREL16)
+ If this is not a GP relative symbol, we want
+ lui $at,<sym> (BFD_RELOC_HI16_S)
+ <op> $treg,<sym>($at) (BFD_RELOC_LO16)
+ <op> $treg+1,<sym>+4($at) (BFD_RELOC_LO16)
+ If there is a base register, we add it to $at after the
+ lui instruction. If there is a constant, we always use
+ the last case. */
+ if ((valueT) offset_expr.X_add_number > MAX_GPREL_OFFSET
+ || nopic_need_relax (offset_expr.X_add_symbol, 1))
+ used_at = 1;
+ else
+ {
+ relax_start (offset_expr.X_add_symbol);
+ if (breg == 0)
+ {
+ tempreg = mips_gp_register;
+ used_at = 0;
+ }
+ else
+ {
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ AT, breg, mips_gp_register);
+ tempreg = AT;
+ used_at = 1;
+ }
+
+ /* Itbl support may require additional care here. */
+ macro_build (&offset_expr, s, fmt, coproc ? treg + 1 : treg,
+ BFD_RELOC_GPREL16, tempreg);
+ offset_expr.X_add_number += 4;
+
+ /* Set mips_optimize to 2 to avoid inserting an
+ undesired nop. */
+ hold_mips_optimize = mips_optimize;
+ mips_optimize = 2;
+ /* Itbl support may require additional care here. */
+ macro_build (&offset_expr, s, fmt, coproc ? treg : treg + 1,
+ BFD_RELOC_GPREL16, tempreg);
+ mips_optimize = hold_mips_optimize;
+
+ relax_switch ();
+
+ /* We just generated two relocs. When tc_gen_reloc
+ handles this case, it will skip the first reloc and
+ handle the second. The second reloc already has an
+ extra addend of 4, which we added above. We must
+ subtract it out, and then subtract another 4 to make
+ the first reloc come out right. The second reloc
+ will come out right because we are going to add 4 to
+ offset_expr when we build its instruction below.
+
+ If we have a symbol, then we don't want to include
+ the offset, because it will wind up being included
+ when we generate the reloc. */
+
+ if (offset_expr.X_op == O_constant)
+ offset_expr.X_add_number -= 8;
+ else
+ {
+ offset_expr.X_add_number = -4;
+ offset_expr.X_op = O_constant;
+ }
+ }
+ macro_build_lui (&offset_expr, AT);
+ if (breg != 0)
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", AT, breg, AT);
+ /* Itbl support may require additional care here. */
+ macro_build (&offset_expr, s, fmt, coproc ? treg + 1 : treg,
+ BFD_RELOC_LO16, AT);
+ /* FIXME: How do we handle overflow here? */
+ offset_expr.X_add_number += 4;
+ /* Itbl support may require additional care here. */
+ macro_build (&offset_expr, s, fmt, coproc ? treg : treg + 1,
+ BFD_RELOC_LO16, AT);
+ if (mips_relax.sequence)
+ relax_end ();
+ }
+ else if (mips_pic == SVR4_PIC && ! mips_big_got)
+ {
+ /* If this is a reference to an external symbol, we want
+ lw $at,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ <op> $treg,0($at)
+ <op> $treg+1,4($at)
+ Otherwise we want
+ lw $at,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ <op> $treg,<sym>($at) (BFD_RELOC_LO16)
+ <op> $treg+1,<sym>+4($at) (BFD_RELOC_LO16)
+ If there is a base register we add it to $at before the
+ lwc1 instructions. If there is a constant we include it
+ in the lwc1 instructions. */
+ used_at = 1;
+ expr1.X_add_number = offset_expr.X_add_number;
+ if (expr1.X_add_number < -0x8000
+ || expr1.X_add_number >= 0x8000 - 4)
+ as_bad (_("PIC code offset overflow (max 16 signed bits)"));
+ load_got_offset (AT, &offset_expr);
+ macro_build (NULL, "nop", "");
+ if (breg != 0)
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", AT, breg, AT);
+
+ /* Set mips_optimize to 2 to avoid inserting an undesired
+ nop. */
+ hold_mips_optimize = mips_optimize;
+ mips_optimize = 2;
+
+ /* Itbl support may require additional care here. */
+ relax_start (offset_expr.X_add_symbol);
+ macro_build (&expr1, s, fmt, coproc ? treg + 1 : treg,
+ BFD_RELOC_LO16, AT);
+ expr1.X_add_number += 4;
+ macro_build (&expr1, s, fmt, coproc ? treg : treg + 1,
+ BFD_RELOC_LO16, AT);
+ relax_switch ();
+ macro_build (&offset_expr, s, fmt, coproc ? treg + 1 : treg,
+ BFD_RELOC_LO16, AT);
+ offset_expr.X_add_number += 4;
+ macro_build (&offset_expr, s, fmt, coproc ? treg : treg + 1,
+ BFD_RELOC_LO16, AT);
+ relax_end ();
+
+ mips_optimize = hold_mips_optimize;
+ }
+ else if (mips_pic == SVR4_PIC)
+ {
+ int gpdelay;
+
+ /* If this is a reference to an external symbol, we want
+ lui $at,<sym> (BFD_RELOC_MIPS_GOT_HI16)
+ addu $at,$at,$gp
+ lw $at,<sym>($at) (BFD_RELOC_MIPS_GOT_LO16)
+ nop
+ <op> $treg,0($at)
+ <op> $treg+1,4($at)
+ Otherwise we want
+ lw $at,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ <op> $treg,<sym>($at) (BFD_RELOC_LO16)
+ <op> $treg+1,<sym>+4($at) (BFD_RELOC_LO16)
+ If there is a base register we add it to $at before the
+ lwc1 instructions. If there is a constant we include it
+ in the lwc1 instructions. */
+ used_at = 1;
+ expr1.X_add_number = offset_expr.X_add_number;
+ offset_expr.X_add_number = 0;
+ if (expr1.X_add_number < -0x8000
+ || expr1.X_add_number >= 0x8000 - 4)
+ as_bad (_("PIC code offset overflow (max 16 signed bits)"));
+ gpdelay = reg_needs_delay (mips_gp_register);
+ relax_start (offset_expr.X_add_symbol);
+ macro_build (&offset_expr, "lui", "t,u",
+ AT, BFD_RELOC_MIPS_GOT_HI16);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ AT, AT, mips_gp_register);
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
+ AT, BFD_RELOC_MIPS_GOT_LO16, AT);
+ macro_build (NULL, "nop", "");
+ if (breg != 0)
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", AT, breg, AT);
+ /* Itbl support may require additional care here. */
+ macro_build (&expr1, s, fmt, coproc ? treg + 1 : treg,
+ BFD_RELOC_LO16, AT);
+ expr1.X_add_number += 4;
+
+ /* Set mips_optimize to 2 to avoid inserting an undesired
+ nop. */
+ hold_mips_optimize = mips_optimize;
+ mips_optimize = 2;
+ /* Itbl support may require additional care here. */
+ macro_build (&expr1, s, fmt, coproc ? treg : treg + 1,
+ BFD_RELOC_LO16, AT);
+ mips_optimize = hold_mips_optimize;
+ expr1.X_add_number -= 4;
+
+ relax_switch ();
+ offset_expr.X_add_number = expr1.X_add_number;
+ if (gpdelay)
+ macro_build (NULL, "nop", "");
+ macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", AT,
+ BFD_RELOC_MIPS_GOT16, mips_gp_register);
+ macro_build (NULL, "nop", "");
+ if (breg != 0)
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", AT, breg, AT);
+ /* Itbl support may require additional care here. */
+ macro_build (&offset_expr, s, fmt, coproc ? treg + 1 : treg,
+ BFD_RELOC_LO16, AT);
+ offset_expr.X_add_number += 4;
+
+ /* Set mips_optimize to 2 to avoid inserting an undesired
+ nop. */
+ hold_mips_optimize = mips_optimize;
+ mips_optimize = 2;
+ /* Itbl support may require additional care here. */
+ macro_build (&offset_expr, s, fmt, coproc ? treg : treg + 1,
+ BFD_RELOC_LO16, AT);
+ mips_optimize = hold_mips_optimize;
+ relax_end ();
+ }
+ else if (mips_pic == EMBEDDED_PIC)
+ {
+ /* If there is no base register, we use
+ <op> $treg,<sym>($gp) (BFD_RELOC_GPREL16)
+ <op> $treg+1,<sym>+4($gp) (BFD_RELOC_GPREL16)
+ If we have a base register, we use
+ addu $at,$breg,$gp
+ <op> $treg,<sym>($at) (BFD_RELOC_GPREL16)
+ <op> $treg+1,<sym>+4($at) (BFD_RELOC_GPREL16)
+ */
+ if (breg == 0)
+ {
+ tempreg = mips_gp_register;
+ used_at = 0;
+ }
+ else
+ {
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
+ AT, breg, mips_gp_register);
+ tempreg = AT;
+ used_at = 1;
+ }
+
+ /* Itbl support may require additional care here. */
+ macro_build (&offset_expr, s, fmt, coproc ? treg + 1 : treg,
+ BFD_RELOC_GPREL16, tempreg);
+ offset_expr.X_add_number += 4;
+ /* Itbl support may require additional care here. */
+ macro_build (&offset_expr, s, fmt, coproc ? treg : treg + 1,
+ BFD_RELOC_GPREL16, tempreg);
+ }
+ else
+ abort ();
+
+ if (! used_at)
+ return;
+
+ break;
+
+ case M_LD_OB:
+ s = "lw";
+ goto sd_ob;
+ case M_SD_OB:
+ s = "sw";
+ sd_ob:
+ assert (HAVE_32BIT_ADDRESSES);
+ macro_build (&offset_expr, s, "t,o(b)", treg, BFD_RELOC_LO16, breg);
+ offset_expr.X_add_number += 4;
+ macro_build (&offset_expr, s, "t,o(b)", treg + 1, BFD_RELOC_LO16, breg);
+ return;
+
+ /* New code added to support COPZ instructions.
+ This code builds table entries out of the macros in mip_opcodes.
+ R4000 uses interlocks to handle coproc delays.
+ Other chips (like the R3000) require nops to be inserted for delays.
+
+ FIXME: Currently, we require that the user handle delays.
+ In order to fill delay slots for non-interlocked chips,
+ we must have a way to specify delays based on the coprocessor.
+ Eg. 4 cycles if load coproc reg from memory, 1 if in cache, etc.
+ What are the side-effects of the cop instruction?
+ What cache support might we have and what are its effects?
+ Both coprocessor & memory require delays. how long???
+ What registers are read/set/modified?
+
+ If an itbl is provided to interpret cop instructions,
+ this knowledge can be encoded in the itbl spec. */
+
+ case M_COP0:
+ s = "c0";
+ goto copz;
+ case M_COP1:
+ s = "c1";
+ goto copz;
+ case M_COP2:
+ s = "c2";
+ goto copz;
+ case M_COP3:
+ s = "c3";
+ copz:
+ /* For now we just do C (same as Cz). The parameter will be
+ stored in insn_opcode by mips_ip. */
+ macro_build (NULL, s, "C", ip->insn_opcode);
+ return;
+
+ case M_MOVE:
+ move_register (dreg, sreg);
+ return;
+
+#ifdef LOSING_COMPILER
+ default:
+ /* Try and see if this is a new itbl instruction.
+ This code builds table entries out of the macros in mip_opcodes.
+ FIXME: For now we just assemble the expression and pass it's
+ value along as a 32-bit immediate.
+ We may want to have the assembler assemble this value,
+ so that we gain the assembler's knowledge of delay slots,
+ symbols, etc.
+ Would it be more efficient to use mask (id) here? */
+ if (itbl_have_entries
+ && (immed_expr = itbl_assemble (ip->insn_mo->name, "")))
+ {
+ s = ip->insn_mo->name;
+ s2 = "cop3";
+ coproc = ITBL_DECODE_PNUM (immed_expr);;
+ macro_build (&immed_expr, s, "C");
+ return;
+ }
+ macro2 (ip);
+ return;
+ }
+ if (mips_opts.noat)
+ as_warn (_("Macro used $at after \".set noat\""));
+}
+
+static void
+macro2 (struct mips_cl_insn *ip)
+{
+ register int treg, sreg, dreg, breg;
+ int tempreg;
+ int mask;
+ int used_at;
+ expressionS expr1;
+ const char *s;
+ const char *s2;
+ const char *fmt;
+ int likely = 0;
+ int dbl = 0;
+ int coproc = 0;
+ int lr = 0;
+ int imm = 0;
+ int off;
+ offsetT maxnum;
+ bfd_reloc_code_real_type r;
+
+ treg = (ip->insn_opcode >> 16) & 0x1f;
+ dreg = (ip->insn_opcode >> 11) & 0x1f;
+ sreg = breg = (ip->insn_opcode >> 21) & 0x1f;
+ mask = ip->insn_mo->mask;
+
+ expr1.X_op = O_constant;
+ expr1.X_op_symbol = NULL;
+ expr1.X_add_symbol = NULL;
+ expr1.X_add_number = 1;
+
+ switch (mask)
+ {
+#endif /* LOSING_COMPILER */
+
+ case M_DMUL:
+ dbl = 1;
+ case M_MUL:
+ macro_build (NULL, dbl ? "dmultu" : "multu", "s,t", sreg, treg);
+ macro_build (NULL, "mflo", "d", dreg);
+ return;
+
+ case M_DMUL_I:
+ dbl = 1;
+ case M_MUL_I:
+ /* The MIPS assembler some times generates shifts and adds. I'm
+ not trying to be that fancy. GCC should do this for us
+ anyway. */
+ load_register (AT, &imm_expr, dbl);
+ macro_build (NULL, dbl ? "dmult" : "mult", "s,t", sreg, AT);
+ macro_build (NULL, "mflo", "d", dreg);
+ break;
+
+ case M_DMULO_I:
+ dbl = 1;
+ case M_MULO_I:
+ imm = 1;
+ goto do_mulo;
+
+ case M_DMULO:
+ dbl = 1;
+ case M_MULO:
+ do_mulo:
+ mips_emit_delays (TRUE);
+ ++mips_opts.noreorder;
+ mips_any_noreorder = 1;
+ if (imm)
+ load_register (AT, &imm_expr, dbl);
+ macro_build (NULL, dbl ? "dmult" : "mult", "s,t", sreg, imm ? AT : treg);
+ macro_build (NULL, "mflo", "d", dreg);
+ macro_build (NULL, dbl ? "dsra32" : "sra", "d,w,<", dreg, dreg, RA);
+ macro_build (NULL, "mfhi", "d", AT);
+ if (mips_trap)
+ macro_build (NULL, "tne", "s,t,q", dreg, AT, 6);
+ else
+ {
+ expr1.X_add_number = 8;
+ macro_build (&expr1, "beq", "s,t,p", dreg, AT);
+ macro_build (NULL, "nop", "", 0);
+ macro_build (NULL, "break", "c", 6);
+ }
+ --mips_opts.noreorder;
+ macro_build (NULL, "mflo", "d", dreg);
+ break;
+
+ case M_DMULOU_I:
+ dbl = 1;
+ case M_MULOU_I:
+ imm = 1;
+ goto do_mulou;
+
+ case M_DMULOU:
+ dbl = 1;
+ case M_MULOU:
+ do_mulou:
+ mips_emit_delays (TRUE);
+ ++mips_opts.noreorder;
+ mips_any_noreorder = 1;
+ if (imm)
+ load_register (AT, &imm_expr, dbl);
+ macro_build (NULL, dbl ? "dmultu" : "multu", "s,t",
+ sreg, imm ? AT : treg);
+ macro_build (NULL, "mfhi", "d", AT);
+ macro_build (NULL, "mflo", "d", dreg);
+ if (mips_trap)
+ macro_build (NULL, "tne", "s,t,q", AT, 0, 6);
+ else
+ {
+ expr1.X_add_number = 8;
+ macro_build (&expr1, "beq", "s,t,p", AT, 0);
+ macro_build (NULL, "nop", "", 0);
+ macro_build (NULL, "break", "c", 6);
+ }
+ --mips_opts.noreorder;
+ break;
+
+ case M_DROL:
+ if (ISA_HAS_DROR (mips_opts.isa) || CPU_HAS_DROR (mips_opts.arch))
+ {
+ if (dreg == sreg)
+ {
+ tempreg = AT;
+ used_at = 1;
+ }
+ else
+ {
+ tempreg = dreg;
+ used_at = 0;
+ }
+ macro_build (NULL, "dnegu", "d,w", tempreg, treg);
+ macro_build (NULL, "drorv", "d,t,s", dreg, sreg, tempreg);
+ if (used_at)
+ break;
+ return;
+ }
+ macro_build (NULL, "dsubu", "d,v,t", AT, 0, treg);
+ macro_build (NULL, "dsrlv", "d,t,s", AT, sreg, AT);
+ macro_build (NULL, "dsllv", "d,t,s", dreg, sreg, treg);
+ macro_build (NULL, "or", "d,v,t", dreg, dreg, AT);
+ break;
+
+ case M_ROL:
+ if (ISA_HAS_ROR (mips_opts.isa) || CPU_HAS_ROR (mips_opts.arch))
+ {
+ if (dreg == sreg)
+ {
+ tempreg = AT;
+ used_at = 1;
+ }
+ else
+ {
+ tempreg = dreg;
+ used_at = 0;
+ }
+ macro_build (NULL, "negu", "d,w", tempreg, treg);
+ macro_build (NULL, "rorv", "d,t,s", dreg, sreg, tempreg);
+ if (used_at)
+ break;
+ return;
+ }
+ macro_build (NULL, "subu", "d,v,t", AT, 0, treg);
+ macro_build (NULL, "srlv", "d,t,s", AT, sreg, AT);
+ macro_build (NULL, "sllv", "d,t,s", dreg, sreg, treg);
+ macro_build (NULL, "or", "d,v,t", dreg, dreg, AT);
+ break;
+
+ case M_DROL_I:
+ {
+ unsigned int rot;
+ char *l, *r;
+
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Improper rotate count"));
+ rot = imm_expr.X_add_number & 0x3f;
+ if (ISA_HAS_DROR (mips_opts.isa) || CPU_HAS_DROR (mips_opts.arch))
+ {
+ rot = (64 - rot) & 0x3f;
+ if (rot >= 32)
+ macro_build (NULL, "dror32", "d,w,<", dreg, sreg, rot - 32);
+ else
+ macro_build (NULL, "dror", "d,w,<", dreg, sreg, rot);
+ return;
+ }
+ if (rot == 0)
+ {
+ macro_build (NULL, "dsrl", "d,w,<", dreg, sreg, 0);
+ return;
+ }
+ l = (rot < 0x20) ? "dsll" : "dsll32";
+ r = ((0x40 - rot) < 0x20) ? "dsrl" : "dsrl32";
+ rot &= 0x1f;
+ macro_build (NULL, l, "d,w,<", AT, sreg, rot);
+ macro_build (NULL, r, "d,w,<", dreg, sreg, (0x20 - rot) & 0x1f);
+ macro_build (NULL, "or", "d,v,t", dreg, dreg, AT);
+ }
+ break;
+
+ case M_ROL_I:
+ {
+ unsigned int rot;
+
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Improper rotate count"));
+ rot = imm_expr.X_add_number & 0x1f;
+ if (ISA_HAS_ROR (mips_opts.isa) || CPU_HAS_ROR (mips_opts.arch))
+ {
+ macro_build (NULL, "ror", "d,w,<", dreg, sreg, (32 - rot) & 0x1f);
+ return;
+ }
+ if (rot == 0)
+ {
+ macro_build (NULL, "srl", "d,w,<", dreg, sreg, 0);
+ return;
+ }
+ macro_build (NULL, "sll", "d,w,<", AT, sreg, rot);
+ macro_build (NULL, "srl", "d,w,<", dreg, sreg, (0x20 - rot) & 0x1f);
+ macro_build (NULL, "or", "d,v,t", dreg, dreg, AT);
+ }
+ break;
+
+ case M_DROR:
+ if (ISA_HAS_DROR (mips_opts.isa) || CPU_HAS_DROR (mips_opts.arch))
+ {
+ macro_build (NULL, "drorv", "d,t,s", dreg, sreg, treg);
+ return;
+ }
+ macro_build (NULL, "dsubu", "d,v,t", AT, 0, treg);
+ macro_build (NULL, "dsllv", "d,t,s", AT, sreg, AT);
+ macro_build (NULL, "dsrlv", "d,t,s", dreg, sreg, treg);
+ macro_build (NULL, "or", "d,v,t", dreg, dreg, AT);
+ break;
+
+ case M_ROR:
+ if (ISA_HAS_ROR (mips_opts.isa) || CPU_HAS_ROR (mips_opts.arch))
+ {
+ macro_build (NULL, "rorv", "d,t,s", dreg, sreg, treg);
+ return;
+ }
+ macro_build (NULL, "subu", "d,v,t", AT, 0, treg);
+ macro_build (NULL, "sllv", "d,t,s", AT, sreg, AT);
+ macro_build (NULL, "srlv", "d,t,s", dreg, sreg, treg);
+ macro_build (NULL, "or", "d,v,t", dreg, dreg, AT);
+ break;
+
+ case M_DROR_I:
+ {
+ unsigned int rot;
+ char *l, *r;
+
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Improper rotate count"));
+ rot = imm_expr.X_add_number & 0x3f;
+ if (ISA_HAS_DROR (mips_opts.isa) || CPU_HAS_DROR (mips_opts.arch))
+ {
+ if (rot >= 32)
+ macro_build (NULL, "dror32", "d,w,<", dreg, sreg, rot - 32);
+ else
+ macro_build (NULL, "dror", "d,w,<", dreg, sreg, rot);
+ return;
+ }
+ if (rot == 0)
+ {
+ macro_build (NULL, "dsrl", "d,w,<", dreg, sreg, 0);
+ return;
+ }
+ r = (rot < 0x20) ? "dsrl" : "dsrl32";
+ l = ((0x40 - rot) < 0x20) ? "dsll" : "dsll32";
+ rot &= 0x1f;
+ macro_build (NULL, r, "d,w,<", AT, sreg, rot);
+ macro_build (NULL, l, "d,w,<", dreg, sreg, (0x20 - rot) & 0x1f);
+ macro_build (NULL, "or", "d,v,t", dreg, dreg, AT);
+ }
+ break;
+
+ case M_ROR_I:
+ {
+ unsigned int rot;
+
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Improper rotate count"));
+ rot = imm_expr.X_add_number & 0x1f;
+ if (ISA_HAS_ROR (mips_opts.isa) || CPU_HAS_ROR (mips_opts.arch))
+ {
+ macro_build (NULL, "ror", "d,w,<", dreg, sreg, rot);
+ return;
+ }
+ if (rot == 0)
+ {
+ macro_build (NULL, "srl", "d,w,<", dreg, sreg, 0);
+ return;
+ }
+ macro_build (NULL, "srl", "d,w,<", AT, sreg, rot);
+ macro_build (NULL, "sll", "d,w,<", dreg, sreg, (0x20 - rot) & 0x1f);
+ macro_build (NULL, "or", "d,v,t", dreg, dreg, AT);
+ }
+ break;
+
+ case M_S_DOB:
+ if (mips_opts.arch == CPU_R4650)
+ {
+ as_bad (_("opcode not supported on this processor"));
+ return;
+ }
+ assert (mips_opts.isa == ISA_MIPS1);
+ /* Even on a big endian machine $fn comes before $fn+1. We have
+ to adjust when storing to memory. */
+ macro_build (&offset_expr, "swc1", "T,o(b)",
+ target_big_endian ? treg + 1 : treg, BFD_RELOC_LO16, breg);
+ offset_expr.X_add_number += 4;
+ macro_build (&offset_expr, "swc1", "T,o(b)",
+ target_big_endian ? treg : treg + 1, BFD_RELOC_LO16, breg);
+ return;
+
+ case M_SEQ:
+ if (sreg == 0)
+ macro_build (&expr1, "sltiu", "t,r,j", dreg, treg, BFD_RELOC_LO16);
+ else if (treg == 0)
+ macro_build (&expr1, "sltiu", "t,r,j", dreg, sreg, BFD_RELOC_LO16);
+ else
+ {
+ macro_build (NULL, "xor", "d,v,t", dreg, sreg, treg);
+ macro_build (&expr1, "sltiu", "t,r,j", dreg, dreg, BFD_RELOC_LO16);
+ }
+ return;
+
+ case M_SEQ_I:
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ {
+ macro_build (&expr1, "sltiu", "t,r,j", dreg, sreg, BFD_RELOC_LO16);
+ return;
+ }
+ if (sreg == 0)
+ {
+ as_warn (_("Instruction %s: result is always false"),
+ ip->insn_mo->name);
+ move_register (dreg, 0);
+ return;
+ }
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= 0
+ && imm_expr.X_add_number < 0x10000)
+ {
+ macro_build (&imm_expr, "xori", "t,r,i", dreg, sreg, BFD_RELOC_LO16);
+ used_at = 0;
+ }
+ else if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number > -0x8000
+ && imm_expr.X_add_number < 0)
+ {
+ imm_expr.X_add_number = -imm_expr.X_add_number;
+ macro_build (&imm_expr, HAVE_32BIT_GPRS ? "addiu" : "daddiu",
+ "t,r,j", dreg, sreg, BFD_RELOC_LO16);
+ used_at = 0;
+ }
+ else
+ {
+ load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ macro_build (NULL, "xor", "d,v,t", dreg, sreg, AT);
+ used_at = 1;
+ }
+ macro_build (&expr1, "sltiu", "t,r,j", dreg, dreg, BFD_RELOC_LO16);
+ if (used_at)
+ break;
+ return;
+
+ case M_SGE: /* sreg >= treg <==> not (sreg < treg) */
+ s = "slt";
+ goto sge;
+ case M_SGEU:
+ s = "sltu";
+ sge:
+ macro_build (NULL, s, "d,v,t", dreg, sreg, treg);
+ macro_build (&expr1, "xori", "t,r,i", dreg, dreg, BFD_RELOC_LO16);
+ return;
+
+ case M_SGE_I: /* sreg >= I <==> not (sreg < I) */
+ case M_SGEU_I:
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= -0x8000
+ && imm_expr.X_add_number < 0x8000)
+ {
+ macro_build (&imm_expr, mask == M_SGE_I ? "slti" : "sltiu", "t,r,j",
+ dreg, sreg, BFD_RELOC_LO16);
+ used_at = 0;
+ }
+ else
+ {
+ load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ macro_build (NULL, mask == M_SGE_I ? "slt" : "sltu", "d,v,t",
+ dreg, sreg, AT);
+ used_at = 1;
+ }
+ macro_build (&expr1, "xori", "t,r,i", dreg, dreg, BFD_RELOC_LO16);
+ if (used_at)
+ break;
+ return;
+
+ case M_SGT: /* sreg > treg <==> treg < sreg */
+ s = "slt";
+ goto sgt;
+ case M_SGTU:
+ s = "sltu";
+ sgt:
+ macro_build (NULL, s, "d,v,t", dreg, treg, sreg);
+ return;
+
+ case M_SGT_I: /* sreg > I <==> I < sreg */
+ s = "slt";
+ goto sgti;
+ case M_SGTU_I:
+ s = "sltu";
+ sgti:
+ load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ macro_build (NULL, s, "d,v,t", dreg, AT, sreg);
+ break;
+
+ case M_SLE: /* sreg <= treg <==> treg >= sreg <==> not (treg < sreg) */
+ s = "slt";
+ goto sle;
+ case M_SLEU:
+ s = "sltu";
+ sle:
+ macro_build (NULL, s, "d,v,t", dreg, treg, sreg);
+ macro_build (&expr1, "xori", "t,r,i", dreg, dreg, BFD_RELOC_LO16);
+ return;
+
+ case M_SLE_I: /* sreg <= I <==> I >= sreg <==> not (I < sreg) */
+ s = "slt";
+ goto slei;
+ case M_SLEU_I:
+ s = "sltu";
+ slei:
+ load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ macro_build (NULL, s, "d,v,t", dreg, AT, sreg);
+ macro_build (&expr1, "xori", "t,r,i", dreg, dreg, BFD_RELOC_LO16);
+ break;
+
+ case M_SLT_I:
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= -0x8000
+ && imm_expr.X_add_number < 0x8000)
+ {
+ macro_build (&imm_expr, "slti", "t,r,j", dreg, sreg, BFD_RELOC_LO16);
+ return;
+ }
+ load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ macro_build (NULL, "slt", "d,v,t", dreg, sreg, AT);
+ break;
+
+ case M_SLTU_I:
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= -0x8000
+ && imm_expr.X_add_number < 0x8000)
+ {
+ macro_build (&imm_expr, "sltiu", "t,r,j", dreg, sreg,
+ BFD_RELOC_LO16);
+ return;
+ }
+ load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ macro_build (NULL, "sltu", "d,v,t", dreg, sreg, AT);
+ break;
+
+ case M_SNE:
+ if (sreg == 0)
+ macro_build (NULL, "sltu", "d,v,t", dreg, 0, treg);
+ else if (treg == 0)
+ macro_build (NULL, "sltu", "d,v,t", dreg, 0, sreg);
+ else
+ {
+ macro_build (NULL, "xor", "d,v,t", dreg, sreg, treg);
+ macro_build (NULL, "sltu", "d,v,t", dreg, 0, dreg);
+ }
+ return;
+
+ case M_SNE_I:
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ {
+ macro_build (NULL, "sltu", "d,v,t", dreg, 0, sreg);
+ return;
+ }
+ if (sreg == 0)
+ {
+ as_warn (_("Instruction %s: result is always true"),
+ ip->insn_mo->name);
+ macro_build (&expr1, HAVE_32BIT_GPRS ? "addiu" : "daddiu", "t,r,j",
+ dreg, 0, BFD_RELOC_LO16);
+ return;
+ }
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= 0
+ && imm_expr.X_add_number < 0x10000)
+ {
+ macro_build (&imm_expr, "xori", "t,r,i", dreg, sreg, BFD_RELOC_LO16);
+ used_at = 0;
+ }
+ else if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number > -0x8000
+ && imm_expr.X_add_number < 0)
+ {
+ imm_expr.X_add_number = -imm_expr.X_add_number;
+ macro_build (&imm_expr, HAVE_32BIT_GPRS ? "addiu" : "daddiu",
+ "t,r,j", dreg, sreg, BFD_RELOC_LO16);
+ used_at = 0;
+ }
+ else
+ {
+ load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ macro_build (NULL, "xor", "d,v,t", dreg, sreg, AT);
+ used_at = 1;
+ }
+ macro_build (NULL, "sltu", "d,v,t", dreg, 0, dreg);
+ if (used_at)
+ break;
+ return;
+
+ case M_DSUB_I:
+ dbl = 1;
+ case M_SUB_I:
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number > -0x8000
+ && imm_expr.X_add_number <= 0x8000)
+ {
+ imm_expr.X_add_number = -imm_expr.X_add_number;
+ macro_build (&imm_expr, dbl ? "daddi" : "addi", "t,r,j",
+ dreg, sreg, BFD_RELOC_LO16);
+ return;
+ }
+ load_register (AT, &imm_expr, dbl);
+ macro_build (NULL, dbl ? "dsub" : "sub", "d,v,t", dreg, sreg, AT);
+ break;
+
+ case M_DSUBU_I:
+ dbl = 1;
+ case M_SUBU_I:
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number > -0x8000
+ && imm_expr.X_add_number <= 0x8000)
+ {
+ imm_expr.X_add_number = -imm_expr.X_add_number;
+ macro_build (&imm_expr, dbl ? "daddiu" : "addiu", "t,r,j",
+ dreg, sreg, BFD_RELOC_LO16);
+ return;
+ }
+ load_register (AT, &imm_expr, dbl);
+ macro_build (NULL, dbl ? "dsubu" : "subu", "d,v,t", dreg, sreg, AT);
+ break;
+
+ case M_TEQ_I:
+ s = "teq";
+ goto trap;
+ case M_TGE_I:
+ s = "tge";
+ goto trap;
+ case M_TGEU_I:
+ s = "tgeu";
+ goto trap;
+ case M_TLT_I:
+ s = "tlt";
+ goto trap;
+ case M_TLTU_I:
+ s = "tltu";
+ goto trap;
+ case M_TNE_I:
+ s = "tne";
+ trap:
+ load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ macro_build (NULL, s, "s,t", sreg, AT);
+ break;
+
+ case M_TRUNCWS:
+ case M_TRUNCWD:
+ assert (mips_opts.isa == ISA_MIPS1);
+ sreg = (ip->insn_opcode >> 11) & 0x1f; /* floating reg */
+ dreg = (ip->insn_opcode >> 06) & 0x1f; /* floating reg */
+
+ /*
+ * Is the double cfc1 instruction a bug in the mips assembler;
+ * or is there a reason for it?
+ */
+ mips_emit_delays (TRUE);
+ ++mips_opts.noreorder;
+ mips_any_noreorder = 1;
+ macro_build (NULL, "cfc1", "t,G", treg, RA);
+ macro_build (NULL, "cfc1", "t,G", treg, RA);
+ macro_build (NULL, "nop", "");
+ expr1.X_add_number = 3;
+ macro_build (&expr1, "ori", "t,r,i", AT, treg, BFD_RELOC_LO16);
+ expr1.X_add_number = 2;
+ macro_build (&expr1, "xori", "t,r,i", AT, AT, BFD_RELOC_LO16);
+ macro_build (NULL, "ctc1", "t,G", AT, RA);
+ macro_build (NULL, "nop", "");
+ macro_build (NULL, mask == M_TRUNCWD ? "cvt.w.d" : "cvt.w.s", "D,S",
+ dreg, sreg);
+ macro_build (NULL, "ctc1", "t,G", treg, RA);
+ macro_build (NULL, "nop", "");
+ --mips_opts.noreorder;
+ break;
+
+ case M_ULH:
+ s = "lb";
+ goto ulh;
+ case M_ULHU:
+ s = "lbu";
+ ulh:
+ if (offset_expr.X_add_number >= 0x7fff)
+ as_bad (_("operand overflow"));
+ if (! target_big_endian)
+ ++offset_expr.X_add_number;
+ macro_build (&offset_expr, s, "t,o(b)", AT, BFD_RELOC_LO16, breg);
+ if (! target_big_endian)
+ --offset_expr.X_add_number;
+ else
+ ++offset_expr.X_add_number;
+ macro_build (&offset_expr, "lbu", "t,o(b)", treg, BFD_RELOC_LO16, breg);
+ macro_build (NULL, "sll", "d,w,<", AT, AT, 8);
+ macro_build (NULL, "or", "d,v,t", treg, treg, AT);
+ break;
+
+ case M_ULD:
+ s = "ldl";
+ s2 = "ldr";
+ off = 7;
+ goto ulw;
+ case M_ULW:
+ s = "lwl";
+ s2 = "lwr";
+ off = 3;
+ ulw:
+ if (offset_expr.X_add_number >= 0x8000 - off)
+ as_bad (_("operand overflow"));
+ if (treg != breg)
+ tempreg = treg;
+ else
+ tempreg = AT;
+ if (! target_big_endian)
+ offset_expr.X_add_number += off;
+ macro_build (&offset_expr, s, "t,o(b)", tempreg, BFD_RELOC_LO16, breg);
+ if (! target_big_endian)
+ offset_expr.X_add_number -= off;
+ else
+ offset_expr.X_add_number += off;
+ macro_build (&offset_expr, s2, "t,o(b)", tempreg, BFD_RELOC_LO16, breg);
+
+ /* If necessary, move the result in tempreg the final destination. */
+ if (treg == tempreg)
+ return;
+ /* Protect second load's delay slot. */
+ if (!gpr_interlocks)
+ macro_build (NULL, "nop", "");
+ move_register (treg, tempreg);
+ break;
+
+ case M_ULD_A:
+ s = "ldl";
+ s2 = "ldr";
+ off = 7;
+ goto ulwa;
+ case M_ULW_A:
+ s = "lwl";
+ s2 = "lwr";
+ off = 3;
+ ulwa:
+ used_at = 1;
+ load_address (AT, &offset_expr, &used_at);
+ if (breg != 0)
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", AT, AT, breg);
+ if (! target_big_endian)
+ expr1.X_add_number = off;
+ else
+ expr1.X_add_number = 0;
+ macro_build (&expr1, s, "t,o(b)", treg, BFD_RELOC_LO16, AT);
+ if (! target_big_endian)
+ expr1.X_add_number = 0;
+ else
+ expr1.X_add_number = off;
+ macro_build (&expr1, s2, "t,o(b)", treg, BFD_RELOC_LO16, AT);
+ break;
+
+ case M_ULH_A:
+ case M_ULHU_A:
+ used_at = 1;
+ load_address (AT, &offset_expr, &used_at);
+ if (breg != 0)
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", AT, AT, breg);
+ if (target_big_endian)
+ expr1.X_add_number = 0;
+ macro_build (&expr1, mask == M_ULH_A ? "lb" : "lbu", "t,o(b)",
+ treg, BFD_RELOC_LO16, AT);
+ if (target_big_endian)
+ expr1.X_add_number = 1;
+ else
+ expr1.X_add_number = 0;
+ macro_build (&expr1, "lbu", "t,o(b)", AT, BFD_RELOC_LO16, AT);
+ macro_build (NULL, "sll", "d,w,<", treg, treg, 8);
+ macro_build (NULL, "or", "d,v,t", treg, treg, AT);
+ break;
+
+ case M_USH:
+ if (offset_expr.X_add_number >= 0x7fff)
+ as_bad (_("operand overflow"));
+ if (target_big_endian)
+ ++offset_expr.X_add_number;
+ macro_build (&offset_expr, "sb", "t,o(b)", treg, BFD_RELOC_LO16, breg);
+ macro_build (NULL, "srl", "d,w,<", AT, treg, 8);
+ if (target_big_endian)
+ --offset_expr.X_add_number;
+ else
+ ++offset_expr.X_add_number;
+ macro_build (&offset_expr, "sb", "t,o(b)", AT, BFD_RELOC_LO16, breg);
+ break;
+
+ case M_USD:
+ s = "sdl";
+ s2 = "sdr";
+ off = 7;
+ goto usw;
+ case M_USW:
+ s = "swl";
+ s2 = "swr";
+ off = 3;
+ usw:
+ if (offset_expr.X_add_number >= 0x8000 - off)
+ as_bad (_("operand overflow"));
+ if (! target_big_endian)
+ offset_expr.X_add_number += off;
+ macro_build (&offset_expr, s, "t,o(b)", treg, BFD_RELOC_LO16, breg);
+ if (! target_big_endian)
+ offset_expr.X_add_number -= off;
+ else
+ offset_expr.X_add_number += off;
+ macro_build (&offset_expr, s2, "t,o(b)", treg, BFD_RELOC_LO16, breg);
+ return;
+
+ case M_USD_A:
+ s = "sdl";
+ s2 = "sdr";
+ off = 7;
+ goto uswa;
+ case M_USW_A:
+ s = "swl";
+ s2 = "swr";
+ off = 3;
+ uswa:
+ used_at = 1;
+ load_address (AT, &offset_expr, &used_at);
+ if (breg != 0)
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", AT, AT, breg);
+ if (! target_big_endian)
+ expr1.X_add_number = off;
+ else
+ expr1.X_add_number = 0;
+ macro_build (&expr1, s, "t,o(b)", treg, BFD_RELOC_LO16, AT);
+ if (! target_big_endian)
+ expr1.X_add_number = 0;
+ else
+ expr1.X_add_number = off;
+ macro_build (&expr1, s2, "t,o(b)", treg, BFD_RELOC_LO16, AT);
+ break;
+
+ case M_USH_A:
+ used_at = 1;
+ load_address (AT, &offset_expr, &used_at);
+ if (breg != 0)
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", AT, AT, breg);
+ if (! target_big_endian)
+ expr1.X_add_number = 0;
+ macro_build (&expr1, "sb", "t,o(b)", treg, BFD_RELOC_LO16, AT);
+ macro_build (NULL, "srl", "d,w,<", treg, treg, 8);
+ if (! target_big_endian)
+ expr1.X_add_number = 1;
+ else
+ expr1.X_add_number = 0;
+ macro_build (&expr1, "sb", "t,o(b)", treg, BFD_RELOC_LO16, AT);
+ if (! target_big_endian)
+ expr1.X_add_number = 0;
+ else
+ expr1.X_add_number = 1;
+ macro_build (&expr1, "lbu", "t,o(b)", AT, BFD_RELOC_LO16, AT);
+ macro_build (NULL, "sll", "d,w,<", treg, treg, 8);
+ macro_build (NULL, "or", "d,v,t", treg, treg, AT);
+ break;
+
+ default:
+ /* FIXME: Check if this is one of the itbl macros, since they
+ are added dynamically. */
+ as_bad (_("Macro %s not implemented yet"), ip->insn_mo->name);
+ break;
+ }
+ if (mips_opts.noat)
+ as_warn (_("Macro used $at after \".set noat\""));
+}
+
+/* Implement macros in mips16 mode. */
+
+static void
+mips16_macro (struct mips_cl_insn *ip)
+{
+ int mask;
+ int xreg, yreg, zreg, tmp;
+ expressionS expr1;
+ int dbl;
+ const char *s, *s2, *s3;
+
+ mask = ip->insn_mo->mask;
+
+ xreg = (ip->insn_opcode >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
+ yreg = (ip->insn_opcode >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY;
+ zreg = (ip->insn_opcode >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
+
+ expr1.X_op = O_constant;
+ expr1.X_op_symbol = NULL;
+ expr1.X_add_symbol = NULL;
+ expr1.X_add_number = 1;
+
+ dbl = 0;
+
+ switch (mask)
+ {
+ default:
+ internalError ();
+
+ case M_DDIV_3:
+ dbl = 1;
+ case M_DIV_3:
+ s = "mflo";
+ goto do_div3;
+ case M_DREM_3:
+ dbl = 1;
+ case M_REM_3:
+ s = "mfhi";
+ do_div3:
+ mips_emit_delays (TRUE);
+ ++mips_opts.noreorder;
+ mips_any_noreorder = 1;
+ macro_build (NULL, dbl ? "ddiv" : "div", "0,x,y", xreg, yreg);
+ expr1.X_add_number = 2;
+ macro_build (&expr1, "bnez", "x,p", yreg);
+ macro_build (NULL, "break", "6", 7);
+
+ /* FIXME: The normal code checks for of -1 / -0x80000000 here,
+ since that causes an overflow. We should do that as well,
+ but I don't see how to do the comparisons without a temporary
+ register. */
+ --mips_opts.noreorder;
+ macro_build (NULL, s, "x", zreg);
+ break;
+
+ case M_DIVU_3:
+ s = "divu";
+ s2 = "mflo";
+ goto do_divu3;
+ case M_REMU_3:
+ s = "divu";
+ s2 = "mfhi";
+ goto do_divu3;
+ case M_DDIVU_3:
+ s = "ddivu";
+ s2 = "mflo";
+ goto do_divu3;
+ case M_DREMU_3:
+ s = "ddivu";
+ s2 = "mfhi";
+ do_divu3:
+ mips_emit_delays (TRUE);
+ ++mips_opts.noreorder;
+ mips_any_noreorder = 1;
+ macro_build (NULL, s, "0,x,y", xreg, yreg);
+ expr1.X_add_number = 2;
+ macro_build (&expr1, "bnez", "x,p", yreg);
+ macro_build (NULL, "break", "6", 7);
+ --mips_opts.noreorder;
+ macro_build (NULL, s2, "x", zreg);
+ break;
+
+ case M_DMUL:
+ dbl = 1;
+ case M_MUL:
+ macro_build (NULL, dbl ? "dmultu" : "multu", "x,y", xreg, yreg);
+ macro_build (NULL, "mflo", "x", zreg);
+ return;
+
+ case M_DSUBU_I:
+ dbl = 1;
+ goto do_subu;
+ case M_SUBU_I:
+ do_subu:
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Unsupported large constant"));
+ imm_expr.X_add_number = -imm_expr.X_add_number;
+ macro_build (&imm_expr, dbl ? "daddiu" : "addiu", "y,x,4", yreg, xreg);
+ break;
+
+ case M_SUBU_I_2:
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Unsupported large constant"));
+ imm_expr.X_add_number = -imm_expr.X_add_number;
+ macro_build (&imm_expr, "addiu", "x,k", xreg);
+ break;
+
+ case M_DSUBU_I_2:
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Unsupported large constant"));
+ imm_expr.X_add_number = -imm_expr.X_add_number;
+ macro_build (&imm_expr, "daddiu", "y,j", yreg);
+ break;
+
+ case M_BEQ:
+ s = "cmp";
+ s2 = "bteqz";
+ goto do_branch;
+ case M_BNE:
+ s = "cmp";
+ s2 = "btnez";
+ goto do_branch;
+ case M_BLT:
+ s = "slt";
+ s2 = "btnez";
+ goto do_branch;
+ case M_BLTU:
+ s = "sltu";
+ s2 = "btnez";
+ goto do_branch;
+ case M_BLE:
+ s = "slt";
+ s2 = "bteqz";
+ goto do_reverse_branch;
+ case M_BLEU:
+ s = "sltu";
+ s2 = "bteqz";
+ goto do_reverse_branch;
+ case M_BGE:
+ s = "slt";
+ s2 = "bteqz";
+ goto do_branch;
+ case M_BGEU:
+ s = "sltu";
+ s2 = "bteqz";
+ goto do_branch;
+ case M_BGT:
+ s = "slt";
+ s2 = "btnez";
+ goto do_reverse_branch;
+ case M_BGTU:
+ s = "sltu";
+ s2 = "btnez";
+
+ do_reverse_branch:
+ tmp = xreg;
+ xreg = yreg;
+ yreg = tmp;
+
+ do_branch:
+ macro_build (NULL, s, "x,y", xreg, yreg);
+ macro_build (&offset_expr, s2, "p");
+ break;
+
+ case M_BEQ_I:
+ s = "cmpi";
+ s2 = "bteqz";
+ s3 = "x,U";
+ goto do_branch_i;
+ case M_BNE_I:
+ s = "cmpi";
+ s2 = "btnez";
+ s3 = "x,U";
+ goto do_branch_i;
+ case M_BLT_I:
+ s = "slti";
+ s2 = "btnez";
+ s3 = "x,8";
+ goto do_branch_i;
+ case M_BLTU_I:
+ s = "sltiu";
+ s2 = "btnez";
+ s3 = "x,8";
+ goto do_branch_i;
+ case M_BLE_I:
+ s = "slti";
+ s2 = "btnez";
+ s3 = "x,8";
+ goto do_addone_branch_i;
+ case M_BLEU_I:
+ s = "sltiu";
+ s2 = "btnez";
+ s3 = "x,8";
+ goto do_addone_branch_i;
+ case M_BGE_I:
+ s = "slti";
+ s2 = "bteqz";
+ s3 = "x,8";
+ goto do_branch_i;
+ case M_BGEU_I:
+ s = "sltiu";
+ s2 = "bteqz";
+ s3 = "x,8";
+ goto do_branch_i;
+ case M_BGT_I:
+ s = "slti";
+ s2 = "bteqz";
+ s3 = "x,8";
+ goto do_addone_branch_i;
+ case M_BGTU_I:
+ s = "sltiu";
+ s2 = "bteqz";
+ s3 = "x,8";
+
+ do_addone_branch_i:
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Unsupported large constant"));
+ ++imm_expr.X_add_number;
+
+ do_branch_i:
+ macro_build (&imm_expr, s, s3, xreg);
+ macro_build (&offset_expr, s2, "p");
+ break;
+
+ case M_ABS:
+ expr1.X_add_number = 0;
+ macro_build (&expr1, "slti", "x,8", yreg);
+ if (xreg != yreg)
+ move_register (xreg, yreg);
+ expr1.X_add_number = 2;
+ macro_build (&expr1, "bteqz", "p");
+ macro_build (NULL, "neg", "x,w", xreg, xreg);
+ }
+}
+
+/* For consistency checking, verify that all bits are specified either
+ by the match/mask part of the instruction definition, or by the
+ operand list. */
+static int
+validate_mips_insn (const struct mips_opcode *opc)
+{
+ const char *p = opc->args;
+ char c;
+ unsigned long used_bits = opc->mask;
+
+ if ((used_bits & opc->match) != opc->match)
+ {
+ as_bad (_("internal: bad mips opcode (mask error): %s %s"),
+ opc->name, opc->args);
+ return 0;
+ }
+#define USE_BITS(mask,shift) (used_bits |= ((mask) << (shift)))
+ while (*p)
+ switch (c = *p++)
+ {
+ case ',': break;
+ case '(': break;
+ case ')': break;
+ case '+':
+ switch (c = *p++)
+ {
+ case 'A': USE_BITS (OP_MASK_SHAMT, OP_SH_SHAMT); break;
+ case 'B': USE_BITS (OP_MASK_INSMSB, OP_SH_INSMSB); break;
+ case 'C': USE_BITS (OP_MASK_EXTMSBD, OP_SH_EXTMSBD); break;
+ case 'D': USE_BITS (OP_MASK_RD, OP_SH_RD);
+ USE_BITS (OP_MASK_SEL, OP_SH_SEL); break;
+ case 'E': USE_BITS (OP_MASK_SHAMT, OP_SH_SHAMT); break;
+ case 'F': USE_BITS (OP_MASK_INSMSB, OP_SH_INSMSB); break;
+ case 'G': USE_BITS (OP_MASK_EXTMSBD, OP_SH_EXTMSBD); break;
+ case 'H': USE_BITS (OP_MASK_EXTMSBD, OP_SH_EXTMSBD); break;
+ case 'I': break;
+ default:
+ as_bad (_("internal: bad mips opcode (unknown extension operand type `+%c'): %s %s"),
+ c, opc->name, opc->args);
+ return 0;
+ }
+ break;
+ case '<': USE_BITS (OP_MASK_SHAMT, OP_SH_SHAMT); break;
+ case '>': USE_BITS (OP_MASK_SHAMT, OP_SH_SHAMT); break;
+ case 'A': break;
+ case 'B': USE_BITS (OP_MASK_CODE20, OP_SH_CODE20); break;
+ case 'C': USE_BITS (OP_MASK_COPZ, OP_SH_COPZ); break;
+ case 'D': USE_BITS (OP_MASK_FD, OP_SH_FD); break;
+ case 'E': USE_BITS (OP_MASK_RT, OP_SH_RT); break;
+ case 'F': break;
+ case 'G': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
+ case 'H': USE_BITS (OP_MASK_SEL, OP_SH_SEL); break;
+ case 'I': break;
+ case 'J': USE_BITS (OP_MASK_CODE19, OP_SH_CODE19); break;
+ case 'K': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
+ case 'L': break;
+ case 'M': USE_BITS (OP_MASK_CCC, OP_SH_CCC); break;
+ case 'N': USE_BITS (OP_MASK_BCC, OP_SH_BCC); break;
+ case 'O': USE_BITS (OP_MASK_ALN, OP_SH_ALN); break;
+ case 'Q': USE_BITS (OP_MASK_VSEL, OP_SH_VSEL);
+ USE_BITS (OP_MASK_FT, OP_SH_FT); break;
+ case 'R': USE_BITS (OP_MASK_FR, OP_SH_FR); break;
+ case 'S': USE_BITS (OP_MASK_FS, OP_SH_FS); break;
+ case 'T': USE_BITS (OP_MASK_FT, OP_SH_FT); break;
+ case 'V': USE_BITS (OP_MASK_FS, OP_SH_FS); break;
+ case 'W': USE_BITS (OP_MASK_FT, OP_SH_FT); break;
+ case 'X': USE_BITS (OP_MASK_FD, OP_SH_FD); break;
+ case 'Y': USE_BITS (OP_MASK_FS, OP_SH_FS); break;
+ case 'Z': USE_BITS (OP_MASK_FT, OP_SH_FT); break;
+ case 'a': USE_BITS (OP_MASK_TARGET, OP_SH_TARGET); break;
+ case 'b': USE_BITS (OP_MASK_RS, OP_SH_RS); break;
+ case 'c': USE_BITS (OP_MASK_CODE, OP_SH_CODE); break;
+ case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
+ case 'f': break;
+ case 'h': USE_BITS (OP_MASK_PREFX, OP_SH_PREFX); break;
+ case 'i': USE_BITS (OP_MASK_IMMEDIATE, OP_SH_IMMEDIATE); break;
+ case 'j': USE_BITS (OP_MASK_DELTA, OP_SH_DELTA); break;
+ case 'k': USE_BITS (OP_MASK_CACHE, OP_SH_CACHE); break;
+ case 'l': break;
+ case 'o': USE_BITS (OP_MASK_DELTA, OP_SH_DELTA); break;
+ case 'p': USE_BITS (OP_MASK_DELTA, OP_SH_DELTA); break;
+ case 'q': USE_BITS (OP_MASK_CODE2, OP_SH_CODE2); break;
+ case 'r': USE_BITS (OP_MASK_RS, OP_SH_RS); break;
+ case 's': USE_BITS (OP_MASK_RS, OP_SH_RS); break;
+ case 't': USE_BITS (OP_MASK_RT, OP_SH_RT); break;
+ case 'u': USE_BITS (OP_MASK_IMMEDIATE, OP_SH_IMMEDIATE); break;
+ case 'v': USE_BITS (OP_MASK_RS, OP_SH_RS); break;
+ case 'w': USE_BITS (OP_MASK_RT, OP_SH_RT); break;
+ case 'x': break;
+ case 'z': break;
+ case 'P': USE_BITS (OP_MASK_PERFREG, OP_SH_PERFREG); break;
+ case 'U': USE_BITS (OP_MASK_RD, OP_SH_RD);
+ USE_BITS (OP_MASK_RT, OP_SH_RT); break;
+ case 'e': USE_BITS (OP_MASK_VECBYTE, OP_SH_VECBYTE); break;
+ case '%': USE_BITS (OP_MASK_VECALIGN, OP_SH_VECALIGN); break;
+ case '[': break;
+ case ']': break;
+ default:
+ as_bad (_("internal: bad mips opcode (unknown operand type `%c'): %s %s"),
+ c, opc->name, opc->args);
+ return 0;
+ }
+#undef USE_BITS
+ if (used_bits != 0xffffffff)
+ {
+ as_bad (_("internal: bad mips opcode (bits 0x%lx undefined): %s %s"),
+ ~used_bits & 0xffffffff, opc->name, opc->args);
+ return 0;
+ }
+ return 1;
+}
+
+/* This routine assembles an instruction into its binary format. As a
+ side effect, it sets one of the global variables imm_reloc or
+ offset_reloc to the type of relocation to do if one of the operands
+ is an address expression. */
+
+static void
+mips_ip (char *str, struct mips_cl_insn *ip)
+{
+ char *s;
+ const char *args;
+ char c = 0;
+ struct mips_opcode *insn;
+ char *argsStart;
+ unsigned int regno;
+ unsigned int lastregno = 0;
+ unsigned int lastpos = 0;
+ unsigned int limlo, limhi;
+ char *s_reset;
+ char save_c = 0;
+
+ insn_error = NULL;
+
+ /* If the instruction contains a '.', we first try to match an instruction
+ including the '.'. Then we try again without the '.'. */
+ insn = NULL;
+ for (s = str; *s != '\0' && !ISSPACE (*s); ++s)
+ continue;
+
+ /* If we stopped on whitespace, then replace the whitespace with null for
+ the call to hash_find. Save the character we replaced just in case we
+ have to re-parse the instruction. */
+ if (ISSPACE (*s))
+ {
+ save_c = *s;
+ *s++ = '\0';
+ }
+
+ insn = (struct mips_opcode *) hash_find (op_hash, str);
+
+ /* If we didn't find the instruction in the opcode table, try again, but
+ this time with just the instruction up to, but not including the
+ first '.'. */
+ if (insn == NULL)
+ {
+ /* Restore the character we overwrite above (if any). */
+ if (save_c)
+ *(--s) = save_c;
+
+ /* Scan up to the first '.' or whitespace. */
+ for (s = str;
+ *s != '\0' && *s != '.' && !ISSPACE (*s);
+ ++s)
+ continue;
+
+ /* If we did not find a '.', then we can quit now. */
+ if (*s != '.')
+ {
+ insn_error = "unrecognized opcode";
+ return;
+ }
+
+ /* Lookup the instruction in the hash table. */
+ *s++ = '\0';
+ if ((insn = (struct mips_opcode *) hash_find (op_hash, str)) == NULL)
+ {
+ insn_error = "unrecognized opcode";
+ return;
+ }
+ }
+
+ argsStart = s;
+ for (;;)
+ {
+ bfd_boolean ok;
+
+ assert (strcmp (insn->name, str) == 0);
+
+ if (OPCODE_IS_MEMBER (insn,
+ (mips_opts.isa
+ | (file_ase_mips16 ? INSN_MIPS16 : 0)
+ | (mips_opts.ase_mdmx ? INSN_MDMX : 0)
+ | (mips_opts.ase_mips3d ? INSN_MIPS3D : 0)),
+ mips_opts.arch))
+ ok = TRUE;
+ else
+ ok = FALSE;
+
+ if (insn->pinfo != INSN_MACRO)
+ {
+ if (mips_opts.arch == CPU_R4650 && (insn->pinfo & FP_D) != 0)
+ ok = FALSE;
+ }
+
+ if (! ok)
+ {
+ if (insn + 1 < &mips_opcodes[NUMOPCODES]
+ && strcmp (insn->name, insn[1].name) == 0)
+ {
+ ++insn;
+ continue;
+ }
+ else
+ {
+ if (!insn_error)
+ {
+ static char buf[100];
+ sprintf (buf,
+ _("opcode not supported on this processor: %s (%s)"),
+ mips_cpu_info_from_arch (mips_opts.arch)->name,
+ mips_cpu_info_from_isa (mips_opts.isa)->name);
+ insn_error = buf;
+ }
+ if (save_c)
+ *(--s) = save_c;
+ return;
+ }
+ }
+
+ ip->insn_mo = insn;
+ ip->insn_opcode = insn->match;
+ insn_error = NULL;
+ for (args = insn->args;; ++args)
+ {
+ int is_mdmx;
+
+ s += strspn (s, " \t");
+ is_mdmx = 0;
+ switch (*args)
+ {
+ case '\0': /* end of args */
+ if (*s == '\0')
+ return;
+ break;
+
+ case ',':
+ if (*s++ == *args)
+ continue;
+ s--;
+ switch (*++args)
+ {
+ case 'r':
+ case 'v':
+ ip->insn_opcode |= lastregno << OP_SH_RS;
+ continue;
+
+ case 'w':
+ ip->insn_opcode |= lastregno << OP_SH_RT;
+ continue;
+
+ case 'W':
+ ip->insn_opcode |= lastregno << OP_SH_FT;
+ continue;
+
+ case 'V':
+ ip->insn_opcode |= lastregno << OP_SH_FS;
+ continue;
+ }
+ break;
+
+ case '(':
+ /* Handle optional base register.
+ Either the base register is omitted or
+ we must have a left paren. */
+ /* This is dependent on the next operand specifier
+ is a base register specification. */
+ assert (args[1] == 'b' || args[1] == '5'
+ || args[1] == '-' || args[1] == '4');
+ if (*s == '\0')
+ return;
+
+ case ')': /* these must match exactly */
+ case '[':
+ case ']':
+ if (*s++ == *args)
+ continue;
+ break;
+
+ case '+': /* Opcode extension character. */
+ switch (*++args)
+ {
+ case 'A': /* ins/ext position, becomes LSB. */
+ limlo = 0;
+ limhi = 31;
+ goto do_lsb;
+ case 'E':
+ limlo = 32;
+ limhi = 63;
+ goto do_lsb;
+do_lsb:
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number < limlo
+ || (unsigned long) imm_expr.X_add_number > limhi)
+ {
+ as_bad (_("Improper position (%lu)"),
+ (unsigned long) imm_expr.X_add_number);
+ imm_expr.X_add_number = limlo;
+ }
+ lastpos = imm_expr.X_add_number;
+ ip->insn_opcode |= (imm_expr.X_add_number
+ & OP_MASK_SHAMT) << OP_SH_SHAMT;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'B': /* ins size, becomes MSB. */
+ limlo = 1;
+ limhi = 32;
+ goto do_msb;
+ case 'F':
+ limlo = 33;
+ limhi = 64;
+ goto do_msb;
+do_msb:
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ /* Check for negative input so that small negative numbers
+ will not succeed incorrectly. The checks against
+ (pos+size) transitively check "size" itself,
+ assuming that "pos" is reasonable. */
+ if ((long) imm_expr.X_add_number < 0
+ || ((unsigned long) imm_expr.X_add_number
+ + lastpos) < limlo
+ || ((unsigned long) imm_expr.X_add_number
+ + lastpos) > limhi)
+ {
+ as_bad (_("Improper insert size (%lu, position %lu)"),
+ (unsigned long) imm_expr.X_add_number,
+ (unsigned long) lastpos);
+ imm_expr.X_add_number = limlo - lastpos;
+ }
+ ip->insn_opcode |= ((lastpos + imm_expr.X_add_number - 1)
+ & OP_MASK_INSMSB) << OP_SH_INSMSB;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'C': /* ext size, becomes MSBD. */
+ limlo = 1;
+ limhi = 32;
+ goto do_msbd;
+ case 'G':
+ limlo = 33;
+ limhi = 64;
+ goto do_msbd;
+ case 'H':
+ limlo = 33;
+ limhi = 64;
+ goto do_msbd;
+do_msbd:
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ /* Check for negative input so that small negative numbers
+ will not succeed incorrectly. The checks against
+ (pos+size) transitively check "size" itself,
+ assuming that "pos" is reasonable. */
+ if ((long) imm_expr.X_add_number < 0
+ || ((unsigned long) imm_expr.X_add_number
+ + lastpos) < limlo
+ || ((unsigned long) imm_expr.X_add_number
+ + lastpos) > limhi)
+ {
+ as_bad (_("Improper extract size (%lu, position %lu)"),
+ (unsigned long) imm_expr.X_add_number,
+ (unsigned long) lastpos);
+ imm_expr.X_add_number = limlo - lastpos;
+ }
+ ip->insn_opcode |= ((imm_expr.X_add_number - 1)
+ & OP_MASK_EXTMSBD) << OP_SH_EXTMSBD;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'D':
+ /* +D is for disassembly only; never match. */
+ break;
+
+ case 'I':
+ /* "+I" is like "I", except that imm2_expr is used. */
+ my_getExpression (&imm2_expr, s);
+ if (imm2_expr.X_op != O_big
+ && imm2_expr.X_op != O_constant)
+ insn_error = _("absolute expression required");
+ normalize_constant_expr (&imm2_expr);
+ s = expr_end;
+ continue;
+
+ default:
+ as_bad (_("internal: bad mips opcode (unknown extension operand type `+%c'): %s %s"),
+ *args, insn->name, insn->args);
+ /* Further processing is fruitless. */
+ return;
+ }
+ break;
+
+ case '<': /* must be at least one digit */
+ /*
+ * According to the manual, if the shift amount is greater
+ * than 31 or less than 0, then the shift amount should be
+ * mod 32. In reality the mips assembler issues an error.
+ * We issue a warning and mask out all but the low 5 bits.
+ */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number > 31)
+ {
+ as_warn (_("Improper shift amount (%lu)"),
+ (unsigned long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= OP_MASK_SHAMT;
+ }
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_SHAMT;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case '>': /* shift amount minus 32 */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number < 32
+ || (unsigned long) imm_expr.X_add_number > 63)
+ break;
+ ip->insn_opcode |= (imm_expr.X_add_number - 32) << OP_SH_SHAMT;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'k': /* cache code */
+ case 'h': /* prefx code */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number > 31)
+ {
+ as_warn (_("Invalid value for `%s' (%lu)"),
+ ip->insn_mo->name,
+ (unsigned long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= 0x1f;
+ }
+ if (*args == 'k')
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_CACHE;
+ else
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_PREFX;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'c': /* break code */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number > 1023)
+ {
+ as_warn (_("Illegal break code (%lu)"),
+ (unsigned long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= OP_MASK_CODE;
+ }
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_CODE;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'q': /* lower break code */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number > 1023)
+ {
+ as_warn (_("Illegal lower break code (%lu)"),
+ (unsigned long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= OP_MASK_CODE2;
+ }
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_CODE2;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'B': /* 20-bit syscall/break code. */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number > OP_MASK_CODE20)
+ as_warn (_("Illegal 20-bit code (%lu)"),
+ (unsigned long) imm_expr.X_add_number);
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_CODE20;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'C': /* Coprocessor code */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number >= (1 << 25))
+ {
+ as_warn (_("Coproccesor code > 25 bits (%lu)"),
+ (unsigned long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= ((1 << 25) - 1);
+ }
+ ip->insn_opcode |= imm_expr.X_add_number;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'J': /* 19-bit wait code. */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number > OP_MASK_CODE19)
+ as_warn (_("Illegal 19-bit code (%lu)"),
+ (unsigned long) imm_expr.X_add_number);
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_CODE19;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'P': /* Performance register */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if (imm_expr.X_add_number != 0 && imm_expr.X_add_number != 1)
+ {
+ as_warn (_("Invalid performance register (%lu)"),
+ (unsigned long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= OP_MASK_PERFREG;
+ }
+ ip->insn_opcode |= (imm_expr.X_add_number << OP_SH_PERFREG);
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'b': /* base register */
+ case 'd': /* destination register */
+ case 's': /* source register */
+ case 't': /* target register */
+ case 'r': /* both target and source */
+ case 'v': /* both dest and source */
+ case 'w': /* both dest and target */
+ case 'E': /* coprocessor target register */
+ case 'G': /* coprocessor destination register */
+ case 'K': /* 'rdhwr' destination register */
+ case 'x': /* ignore register name */
+ case 'z': /* must be zero register */
+ case 'U': /* destination register (clo/clz). */
+ s_reset = s;
+ if (s[0] == '$')
+ {
+
+ if (ISDIGIT (s[1]))
+ {
+ ++s;
+ regno = 0;
+ do
+ {
+ regno *= 10;
+ regno += *s - '0';
+ ++s;
+ }
+ while (ISDIGIT (*s));
+ if (regno > 31)
+ as_bad (_("Invalid register number (%d)"), regno);
+ }
+ else if (*args == 'E' || *args == 'G' || *args == 'K')
+ goto notreg;
+ else
+ {
+ if (s[1] == 'r' && s[2] == 'a')
+ {
+ s += 3;
+ regno = RA;
+ }
+ else if (s[1] == 'f' && s[2] == 'p')
+ {
+ s += 3;
+ regno = FP;
+ }
+ else if (s[1] == 's' && s[2] == 'p')
+ {
+ s += 3;
+ regno = SP;
+ }
+ else if (s[1] == 'g' && s[2] == 'p')
+ {
+ s += 3;
+ regno = GP;
+ }
+ else if (s[1] == 'a' && s[2] == 't')
+ {
+ s += 3;
+ regno = AT;
+ }
+ else if (s[1] == 'k' && s[2] == 't' && s[3] == '0')
+ {
+ s += 4;
+ regno = KT0;
+ }
+ else if (s[1] == 'k' && s[2] == 't' && s[3] == '1')
+ {
+ s += 4;
+ regno = KT1;
+ }
+ else if (s[1] == 'z' && s[2] == 'e' && s[3] == 'r' && s[4] == 'o')
+ {
+ s += 5;
+ regno = ZERO;
+ }
+ else if (itbl_have_entries)
+ {
+ char *p, *n;
+ unsigned long r;
+
+ p = s + 1; /* advance past '$' */
+ n = itbl_get_field (&p); /* n is name */
+
+ /* See if this is a register defined in an
+ itbl entry. */
+ if (itbl_get_reg_val (n, &r))
+ {
+ /* Get_field advances to the start of
+ the next field, so we need to back
+ rack to the end of the last field. */
+ if (p)
+ s = p - 1;
+ else
+ s = strchr (s, '\0');
+ regno = r;
+ }
+ else
+ goto notreg;
+ }
+ else
+ goto notreg;
+ }
+ if (regno == AT
+ && ! mips_opts.noat
+ && *args != 'E'
+ && *args != 'G'
+ && *args != 'K')
+ as_warn (_("Used $at without \".set noat\""));
+ c = *args;
+ if (*s == ' ')
+ ++s;
+ if (args[1] != *s)
+ {
+ if (c == 'r' || c == 'v' || c == 'w')
+ {
+ regno = lastregno;
+ s = s_reset;
+ ++args;
+ }
+ }
+ /* 'z' only matches $0. */
+ if (c == 'z' && regno != 0)
+ break;
+
+ /* Now that we have assembled one operand, we use the args string
+ * to figure out where it goes in the instruction. */
+ switch (c)
+ {
+ case 'r':
+ case 's':
+ case 'v':
+ case 'b':
+ ip->insn_opcode |= regno << OP_SH_RS;
+ break;
+ case 'd':
+ case 'G':
+ case 'K':
+ ip->insn_opcode |= regno << OP_SH_RD;
+ break;
+ case 'U':
+ ip->insn_opcode |= regno << OP_SH_RD;
+ ip->insn_opcode |= regno << OP_SH_RT;
+ break;
+ case 'w':
+ case 't':
+ case 'E':
+ ip->insn_opcode |= regno << OP_SH_RT;
+ break;
+ case 'x':
+ /* This case exists because on the r3000 trunc
+ expands into a macro which requires a gp
+ register. On the r6000 or r4000 it is
+ assembled into a single instruction which
+ ignores the register. Thus the insn version
+ is MIPS_ISA2 and uses 'x', and the macro
+ version is MIPS_ISA1 and uses 't'. */
+ break;
+ case 'z':
+ /* This case is for the div instruction, which
+ acts differently if the destination argument
+ is $0. This only matches $0, and is checked
+ outside the switch. */
+ break;
+ case 'D':
+ /* Itbl operand; not yet implemented. FIXME ?? */
+ break;
+ /* What about all other operands like 'i', which
+ can be specified in the opcode table? */
+ }
+ lastregno = regno;
+ continue;
+ }
+ notreg:
+ switch (*args++)
+ {
+ case 'r':
+ case 'v':
+ ip->insn_opcode |= lastregno << OP_SH_RS;
+ continue;
+ case 'w':
+ ip->insn_opcode |= lastregno << OP_SH_RT;
+ continue;
+ }
+ break;
+
+ case 'O': /* MDMX alignment immediate constant. */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number > OP_MASK_ALN)
+ {
+ as_warn ("Improper align amount (%ld), using low bits",
+ (long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= OP_MASK_ALN;
+ }
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_ALN;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'Q': /* MDMX vector, element sel, or const. */
+ if (s[0] != '$')
+ {
+ /* MDMX Immediate. */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number > OP_MASK_FT)
+ {
+ as_warn (_("Invalid MDMX Immediate (%ld)"),
+ (long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= OP_MASK_FT;
+ }
+ imm_expr.X_add_number &= OP_MASK_FT;
+ if (ip->insn_opcode & (OP_MASK_VSEL << OP_SH_VSEL))
+ ip->insn_opcode |= MDMX_FMTSEL_IMM_QH << OP_SH_VSEL;
+ else
+ ip->insn_opcode |= MDMX_FMTSEL_IMM_OB << OP_SH_VSEL;
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_FT;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+ }
+ /* Not MDMX Immediate. Fall through. */
+ case 'X': /* MDMX destination register. */
+ case 'Y': /* MDMX source register. */
+ case 'Z': /* MDMX target register. */
+ is_mdmx = 1;
+ case 'D': /* floating point destination register */
+ case 'S': /* floating point source register */
+ case 'T': /* floating point target register */
+ case 'R': /* floating point source register */
+ case 'V':
+ case 'W':
+ s_reset = s;
+ /* Accept $fN for FP and MDMX register numbers, and in
+ addition accept $vN for MDMX register numbers. */
+ if ((s[0] == '$' && s[1] == 'f' && ISDIGIT (s[2]))
+ || (is_mdmx != 0 && s[0] == '$' && s[1] == 'v'
+ && ISDIGIT (s[2])))
+ {
+ s += 2;
+ regno = 0;
+ do
+ {
+ regno *= 10;
+ regno += *s - '0';
+ ++s;
+ }
+ while (ISDIGIT (*s));
+
+ if (regno > 31)
+ as_bad (_("Invalid float register number (%d)"), regno);
+
+ if ((regno & 1) != 0
+ && HAVE_32BIT_FPRS
+ && ! (strcmp (str, "mtc1") == 0
+ || strcmp (str, "mfc1") == 0
+ || strcmp (str, "lwc1") == 0
+ || strcmp (str, "swc1") == 0
+ || strcmp (str, "l.s") == 0
+ || strcmp (str, "s.s") == 0))
+ as_warn (_("Float register should be even, was %d"),
+ regno);
+
+ c = *args;
+ if (*s == ' ')
+ ++s;
+ if (args[1] != *s)
+ {
+ if (c == 'V' || c == 'W')
+ {
+ regno = lastregno;
+ s = s_reset;
+ ++args;
+ }
+ }
+ switch (c)
+ {
+ case 'D':
+ case 'X':
+ ip->insn_opcode |= regno << OP_SH_FD;
+ break;
+ case 'V':
+ case 'S':
+ case 'Y':
+ ip->insn_opcode |= regno << OP_SH_FS;
+ break;
+ case 'Q':
+ /* This is like 'Z', but also needs to fix the MDMX
+ vector/scalar select bits. Note that the
+ scalar immediate case is handled above. */
+ if (*s == '[')
+ {
+ int is_qh = (ip->insn_opcode & (1 << OP_SH_VSEL));
+ int max_el = (is_qh ? 3 : 7);
+ s++;
+ my_getExpression(&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ s = expr_end;
+ if (imm_expr.X_add_number > max_el)
+ as_bad(_("Bad element selector %ld"),
+ (long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= max_el;
+ ip->insn_opcode |= (imm_expr.X_add_number
+ << (OP_SH_VSEL +
+ (is_qh ? 2 : 1)));
+ if (*s != ']')
+ as_warn(_("Expecting ']' found '%s'"), s);
+ else
+ s++;
+ }
+ else
+ {
+ if (ip->insn_opcode & (OP_MASK_VSEL << OP_SH_VSEL))
+ ip->insn_opcode |= (MDMX_FMTSEL_VEC_QH
+ << OP_SH_VSEL);
+ else
+ ip->insn_opcode |= (MDMX_FMTSEL_VEC_OB <<
+ OP_SH_VSEL);
+ }
+ /* Fall through */
+ case 'W':
+ case 'T':
+ case 'Z':
+ ip->insn_opcode |= regno << OP_SH_FT;
+ break;
+ case 'R':
+ ip->insn_opcode |= regno << OP_SH_FR;
+ break;
+ }
+ lastregno = regno;
+ continue;
+ }
+
+ switch (*args++)
+ {
+ case 'V':
+ ip->insn_opcode |= lastregno << OP_SH_FS;
+ continue;
+ case 'W':
+ ip->insn_opcode |= lastregno << OP_SH_FT;
+ continue;
+ }
+ break;
+
+ case 'I':
+ my_getExpression (&imm_expr, s);
+ if (imm_expr.X_op != O_big
+ && imm_expr.X_op != O_constant)
+ insn_error = _("absolute expression required");
+ normalize_constant_expr (&imm_expr);
+ s = expr_end;
+ continue;
+
+ case 'A':
+ my_getExpression (&offset_expr, s);
+ *imm_reloc = BFD_RELOC_32;
+ s = expr_end;
+ continue;
+
+ case 'F':
+ case 'L':
+ case 'f':
+ case 'l':
+ {
+ int f64;
+ int using_gprs;
+ char *save_in;
+ char *err;
+ unsigned char temp[8];
+ int len;
+ unsigned int length;
+ segT seg;
+ subsegT subseg;
+ char *p;
+
+ /* These only appear as the last operand in an
+ instruction, and every instruction that accepts
+ them in any variant accepts them in all variants.
+ This means we don't have to worry about backing out
+ any changes if the instruction does not match.
+
+ The difference between them is the size of the
+ floating point constant and where it goes. For 'F'
+ and 'L' the constant is 64 bits; for 'f' and 'l' it
+ is 32 bits. Where the constant is placed is based
+ on how the MIPS assembler does things:
+ F -- .rdata
+ L -- .lit8
+ f -- immediate value
+ l -- .lit4
+
+ The .lit4 and .lit8 sections are only used if
+ permitted by the -G argument.
+
+ When generating embedded PIC code, we use the
+ .lit8 section but not the .lit4 section (we can do
+ .lit4 inline easily; we need to put .lit8
+ somewhere in the data segment, and using .lit8
+ permits the linker to eventually combine identical
+ .lit8 entries).
+
+ The code below needs to know whether the target register
+ is 32 or 64 bits wide. It relies on the fact 'f' and
+ 'F' are used with GPR-based instructions and 'l' and
+ 'L' are used with FPR-based instructions. */
+
+ f64 = *args == 'F' || *args == 'L';
+ using_gprs = *args == 'F' || *args == 'f';
+
+ save_in = input_line_pointer;
+ input_line_pointer = s;
+ err = md_atof (f64 ? 'd' : 'f', (char *) temp, &len);
+ length = len;
+ s = input_line_pointer;
+ input_line_pointer = save_in;
+ if (err != NULL && *err != '\0')
+ {
+ as_bad (_("Bad floating point constant: %s"), err);
+ memset (temp, '\0', sizeof temp);
+ length = f64 ? 8 : 4;
+ }
+
+ assert (length == (unsigned) (f64 ? 8 : 4));
+
+ if (*args == 'f'
+ || (*args == 'l'
+ && (! USE_GLOBAL_POINTER_OPT
+ || mips_pic == EMBEDDED_PIC
+ || g_switch_value < 4
+ || (temp[0] == 0 && temp[1] == 0)
+ || (temp[2] == 0 && temp[3] == 0))))
+ {
+ imm_expr.X_op = O_constant;
+ if (! target_big_endian)
+ imm_expr.X_add_number = bfd_getl32 (temp);
+ else
+ imm_expr.X_add_number = bfd_getb32 (temp);
+ }
+ else if (length > 4
+ && ! mips_disable_float_construction
+ /* Constants can only be constructed in GPRs and
+ copied to FPRs if the GPRs are at least as wide
+ as the FPRs. Force the constant into memory if
+ we are using 64-bit FPRs but the GPRs are only
+ 32 bits wide. */
+ && (using_gprs
+ || ! (HAVE_64BIT_FPRS && HAVE_32BIT_GPRS))
+ && ((temp[0] == 0 && temp[1] == 0)
+ || (temp[2] == 0 && temp[3] == 0))
+ && ((temp[4] == 0 && temp[5] == 0)
+ || (temp[6] == 0 && temp[7] == 0)))
+ {
+ /* The value is simple enough to load with a couple of
+ instructions. If using 32-bit registers, set
+ imm_expr to the high order 32 bits and offset_expr to
+ the low order 32 bits. Otherwise, set imm_expr to
+ the entire 64 bit constant. */
+ if (using_gprs ? HAVE_32BIT_GPRS : HAVE_32BIT_FPRS)
+ {
+ imm_expr.X_op = O_constant;
+ offset_expr.X_op = O_constant;
+ if (! target_big_endian)
+ {
+ imm_expr.X_add_number = bfd_getl32 (temp + 4);
+ offset_expr.X_add_number = bfd_getl32 (temp);
+ }
+ else
+ {
+ imm_expr.X_add_number = bfd_getb32 (temp);
+ offset_expr.X_add_number = bfd_getb32 (temp + 4);
+ }
+ if (offset_expr.X_add_number == 0)
+ offset_expr.X_op = O_absent;
+ }
+ else if (sizeof (imm_expr.X_add_number) > 4)
+ {
+ imm_expr.X_op = O_constant;
+ if (! target_big_endian)
+ imm_expr.X_add_number = bfd_getl64 (temp);
+ else
+ imm_expr.X_add_number = bfd_getb64 (temp);
+ }
+ else
+ {
+ imm_expr.X_op = O_big;
+ imm_expr.X_add_number = 4;
+ if (! target_big_endian)
+ {
+ generic_bignum[0] = bfd_getl16 (temp);
+ generic_bignum[1] = bfd_getl16 (temp + 2);
+ generic_bignum[2] = bfd_getl16 (temp + 4);
+ generic_bignum[3] = bfd_getl16 (temp + 6);
+ }
+ else
+ {
+ generic_bignum[0] = bfd_getb16 (temp + 6);
+ generic_bignum[1] = bfd_getb16 (temp + 4);
+ generic_bignum[2] = bfd_getb16 (temp + 2);
+ generic_bignum[3] = bfd_getb16 (temp);
+ }
+ }
+ }
+ else
+ {
+ const char *newname;
+ segT new_seg;
+
+ /* Switch to the right section. */
+ seg = now_seg;
+ subseg = now_subseg;
+ switch (*args)
+ {
+ default: /* unused default case avoids warnings. */
+ case 'L':
+ newname = RDATA_SECTION_NAME;
+ if ((USE_GLOBAL_POINTER_OPT && g_switch_value >= 8)
+ || mips_pic == EMBEDDED_PIC)
+ newname = ".lit8";
+ break;
+ case 'F':
+ if (mips_pic == EMBEDDED_PIC)
+ newname = ".lit8";
+ else
+ newname = RDATA_SECTION_NAME;
+ break;
+ case 'l':
+ assert (!USE_GLOBAL_POINTER_OPT
+ || g_switch_value >= 4);
+ newname = ".lit4";
+ break;
+ }
+ new_seg = subseg_new (newname, (subsegT) 0);
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ bfd_set_section_flags (stdoutput, new_seg,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_READONLY
+ | SEC_DATA));
+ frag_align (*args == 'l' ? 2 : 3, 0, 0);
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour
+ && strcmp (TARGET_OS, "elf") != 0)
+ record_alignment (new_seg, 4);
+ else
+ record_alignment (new_seg, *args == 'l' ? 2 : 3);
+ if (seg == now_seg)
+ as_bad (_("Can't use floating point insn in this section"));
+
+ /* Set the argument to the current address in the
+ section. */
+ offset_expr.X_op = O_symbol;
+ offset_expr.X_add_symbol =
+ symbol_new ("L0\001", now_seg,
+ (valueT) frag_now_fix (), frag_now);
+ offset_expr.X_add_number = 0;
+
+ /* Put the floating point number into the section. */
+ p = frag_more ((int) length);
+ memcpy (p, temp, length);
+
+ /* Switch back to the original section. */
+ subseg_set (seg, subseg);
+ }
+ }
+ continue;
+
+ case 'i': /* 16 bit unsigned immediate */
+ case 'j': /* 16 bit signed immediate */
+ *imm_reloc = BFD_RELOC_LO16;
+ if (my_getSmallExpression (&imm_expr, imm_reloc, s) == 0)
+ {
+ int more;
+ offsetT minval, maxval;
+
+ more = (insn + 1 < &mips_opcodes[NUMOPCODES]
+ && strcmp (insn->name, insn[1].name) == 0);
+
+ /* If the expression was written as an unsigned number,
+ only treat it as signed if there are no more
+ alternatives. */
+ if (more
+ && *args == 'j'
+ && sizeof (imm_expr.X_add_number) <= 4
+ && imm_expr.X_op == O_constant
+ && imm_expr.X_add_number < 0
+ && imm_expr.X_unsigned
+ && HAVE_64BIT_GPRS)
+ break;
+
+ /* For compatibility with older assemblers, we accept
+ 0x8000-0xffff as signed 16-bit numbers when only
+ signed numbers are allowed. */
+ if (*args == 'i')
+ minval = 0, maxval = 0xffff;
+ else if (more)
+ minval = -0x8000, maxval = 0x7fff;
+ else
+ minval = -0x8000, maxval = 0xffff;
+
+ if (imm_expr.X_op != O_constant
+ || imm_expr.X_add_number < minval
+ || imm_expr.X_add_number > maxval)
+ {
+ if (more)
+ break;
+ if (imm_expr.X_op == O_constant
+ || imm_expr.X_op == O_big)
+ as_bad (_("expression out of range"));
+ }
+ }
+ s = expr_end;
+ continue;
+
+ case 'o': /* 16 bit offset */
+ /* Check whether there is only a single bracketed expression
+ left. If so, it must be the base register and the
+ constant must be zero. */
+ if (*s == '(' && strchr (s + 1, '(') == 0)
+ {
+ offset_expr.X_op = O_constant;
+ offset_expr.X_add_number = 0;
+ continue;
+ }
+
+ /* If this value won't fit into a 16 bit offset, then go
+ find a macro that will generate the 32 bit offset
+ code pattern. */
+ if (my_getSmallExpression (&offset_expr, offset_reloc, s) == 0
+ && (offset_expr.X_op != O_constant
+ || offset_expr.X_add_number >= 0x8000
+ || offset_expr.X_add_number < -0x8000))
+ break;
+
+ s = expr_end;
+ continue;
+
+ case 'p': /* pc relative offset */
+ *offset_reloc = BFD_RELOC_16_PCREL_S2;
+ my_getExpression (&offset_expr, s);
+ s = expr_end;
+ continue;
+
+ case 'u': /* upper 16 bits */
+ if (my_getSmallExpression (&imm_expr, imm_reloc, s) == 0
+ && imm_expr.X_op == O_constant
+ && (imm_expr.X_add_number < 0
+ || imm_expr.X_add_number >= 0x10000))
+ as_bad (_("lui expression not in range 0..65535"));
+ s = expr_end;
+ continue;
+
+ case 'a': /* 26 bit address */
+ my_getExpression (&offset_expr, s);
+ s = expr_end;
+ *offset_reloc = BFD_RELOC_MIPS_JMP;
+ continue;
+
+ case 'N': /* 3 bit branch condition code */
+ case 'M': /* 3 bit compare condition code */
+ if (strncmp (s, "$fcc", 4) != 0)
+ break;
+ s += 4;
+ regno = 0;
+ do
+ {
+ regno *= 10;
+ regno += *s - '0';
+ ++s;
+ }
+ while (ISDIGIT (*s));
+ if (regno > 7)
+ as_bad (_("Invalid condition code register $fcc%d"), regno);
+ if ((strcmp(str + strlen(str) - 3, ".ps") == 0
+ || strcmp(str + strlen(str) - 5, "any2f") == 0
+ || strcmp(str + strlen(str) - 5, "any2t") == 0)
+ && (regno & 1) != 0)
+ as_warn(_("Condition code register should be even for %s, was %d"),
+ str, regno);
+ if ((strcmp(str + strlen(str) - 5, "any4f") == 0
+ || strcmp(str + strlen(str) - 5, "any4t") == 0)
+ && (regno & 3) != 0)
+ as_warn(_("Condition code register should be 0 or 4 for %s, was %d"),
+ str, regno);
+ if (*args == 'N')
+ ip->insn_opcode |= regno << OP_SH_BCC;
+ else
+ ip->insn_opcode |= regno << OP_SH_CCC;
+ continue;
+
+ case 'H':
+ if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
+ s += 2;
+ if (ISDIGIT (*s))
+ {
+ c = 0;
+ do
+ {
+ c *= 10;
+ c += *s - '0';
+ ++s;
+ }
+ while (ISDIGIT (*s));
+ }
+ else
+ c = 8; /* Invalid sel value. */
+
+ if (c > 7)
+ as_bad (_("invalid coprocessor sub-selection value (0-7)"));
+ ip->insn_opcode |= c;
+ continue;
+
+ case 'e':
+ /* Must be at least one digit. */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+
+ if ((unsigned long) imm_expr.X_add_number
+ > (unsigned long) OP_MASK_VECBYTE)
+ {
+ as_bad (_("bad byte vector index (%ld)"),
+ (long) imm_expr.X_add_number);
+ imm_expr.X_add_number = 0;
+ }
+
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_VECBYTE;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case '%':
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+
+ if ((unsigned long) imm_expr.X_add_number
+ > (unsigned long) OP_MASK_VECALIGN)
+ {
+ as_bad (_("bad byte vector index (%ld)"),
+ (long) imm_expr.X_add_number);
+ imm_expr.X_add_number = 0;
+ }
+
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_VECALIGN;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ default:
+ as_bad (_("bad char = '%c'\n"), *args);
+ internalError ();
+ }
+ break;
+ }
+ /* Args don't match. */
+ if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
+ !strcmp (insn->name, insn[1].name))
+ {
+ ++insn;
+ s = argsStart;
+ insn_error = _("illegal operands");
+ continue;
+ }
+ if (save_c)
+ *(--s) = save_c;
+ insn_error = _("illegal operands");
+ return;
+ }
+}
+
+/* This routine assembles an instruction into its binary format when
+ assembling for the mips16. As a side effect, it sets one of the
+ global variables imm_reloc or offset_reloc to the type of
+ relocation to do if one of the operands is an address expression.
+ It also sets mips16_small and mips16_ext if the user explicitly
+ requested a small or extended instruction. */
+
+static void
+mips16_ip (char *str, struct mips_cl_insn *ip)
+{
+ char *s;
+ const char *args;
+ struct mips_opcode *insn;
+ char *argsstart;
+ unsigned int regno;
+ unsigned int lastregno = 0;
+ char *s_reset;
+
+ insn_error = NULL;
+
+ mips16_small = FALSE;
+ mips16_ext = FALSE;
+
+ for (s = str; ISLOWER (*s); ++s)
+ ;
+ switch (*s)
+ {
+ case '\0':
+ break;
+
+ case ' ':
+ *s++ = '\0';
+ break;
+
+ case '.':
+ if (s[1] == 't' && s[2] == ' ')
+ {
+ *s = '\0';
+ mips16_small = TRUE;
+ s += 3;
+ break;
+ }
+ else if (s[1] == 'e' && s[2] == ' ')
+ {
+ *s = '\0';
+ mips16_ext = TRUE;
+ s += 3;
+ break;
+ }
+ /* Fall through. */
+ default:
+ insn_error = _("unknown opcode");
+ return;
+ }
+
+ if (mips_opts.noautoextend && ! mips16_ext)
+ mips16_small = TRUE;
+
+ if ((insn = (struct mips_opcode *) hash_find (mips16_op_hash, str)) == NULL)
+ {
+ insn_error = _("unrecognized opcode");
+ return;
+ }
+
+ argsstart = s;
+ for (;;)
+ {
+ assert (strcmp (insn->name, str) == 0);
+
+ ip->insn_mo = insn;
+ ip->insn_opcode = insn->match;
+ ip->use_extend = FALSE;
+ imm_expr.X_op = O_absent;
+ imm_reloc[0] = BFD_RELOC_UNUSED;
+ imm_reloc[1] = BFD_RELOC_UNUSED;
+ imm_reloc[2] = BFD_RELOC_UNUSED;
+ imm2_expr.X_op = O_absent;
+ offset_expr.X_op = O_absent;
+ offset_reloc[0] = BFD_RELOC_UNUSED;
+ offset_reloc[1] = BFD_RELOC_UNUSED;
+ offset_reloc[2] = BFD_RELOC_UNUSED;
+ for (args = insn->args; 1; ++args)
+ {
+ int c;
+
+ if (*s == ' ')
+ ++s;
+
+ /* In this switch statement we call break if we did not find
+ a match, continue if we did find a match, or return if we
+ are done. */
+
+ c = *args;
+ switch (c)
+ {
+ case '\0':
+ if (*s == '\0')
+ {
+ /* Stuff the immediate value in now, if we can. */
+ if (imm_expr.X_op == O_constant
+ && *imm_reloc > BFD_RELOC_UNUSED
+ && insn->pinfo != INSN_MACRO)
+ {
+ mips16_immed (NULL, 0, *imm_reloc - BFD_RELOC_UNUSED,
+ imm_expr.X_add_number, TRUE, mips16_small,
+ mips16_ext, &ip->insn_opcode,
+ &ip->use_extend, &ip->extend);
+ imm_expr.X_op = O_absent;
+ *imm_reloc = BFD_RELOC_UNUSED;
+ }
+
+ return;
+ }
+ break;
+
+ case ',':
+ if (*s++ == c)
+ continue;
+ s--;
+ switch (*++args)
+ {
+ case 'v':
+ ip->insn_opcode |= lastregno << MIPS16OP_SH_RX;
+ continue;
+ case 'w':
+ ip->insn_opcode |= lastregno << MIPS16OP_SH_RY;
+ continue;
+ }
+ break;
+
+ case '(':
+ case ')':
+ if (*s++ == c)
+ continue;
+ break;
+
+ case 'v':
+ case 'w':
+ if (s[0] != '$')
+ {
+ if (c == 'v')
+ ip->insn_opcode |= lastregno << MIPS16OP_SH_RX;
+ else
+ ip->insn_opcode |= lastregno << MIPS16OP_SH_RY;
+ ++args;
+ continue;
+ }
+ /* Fall through. */
+ case 'x':
+ case 'y':
+ case 'z':
+ case 'Z':
+ case '0':
+ case 'S':
+ case 'R':
+ case 'X':
+ case 'Y':
+ if (s[0] != '$')
+ break;
+ s_reset = s;
+ if (ISDIGIT (s[1]))
+ {
+ ++s;
+ regno = 0;
+ do
+ {
+ regno *= 10;
+ regno += *s - '0';
+ ++s;
+ }
+ while (ISDIGIT (*s));
+ if (regno > 31)
+ {
+ as_bad (_("invalid register number (%d)"), regno);
+ regno = 2;
+ }
+ }
+ else
+ {
+ if (s[1] == 'r' && s[2] == 'a')
+ {
+ s += 3;
+ regno = RA;
+ }
+ else if (s[1] == 'f' && s[2] == 'p')
+ {
+ s += 3;
+ regno = FP;
+ }
+ else if (s[1] == 's' && s[2] == 'p')
+ {
+ s += 3;
+ regno = SP;
+ }
+ else if (s[1] == 'g' && s[2] == 'p')
+ {
+ s += 3;
+ regno = GP;
+ }
+ else if (s[1] == 'a' && s[2] == 't')
+ {
+ s += 3;
+ regno = AT;
+ }
+ else if (s[1] == 'k' && s[2] == 't' && s[3] == '0')
+ {
+ s += 4;
+ regno = KT0;
+ }
+ else if (s[1] == 'k' && s[2] == 't' && s[3] == '1')
+ {
+ s += 4;
+ regno = KT1;
+ }
+ else if (s[1] == 'z' && s[2] == 'e' && s[3] == 'r' && s[4] == 'o')
+ {
+ s += 5;
+ regno = ZERO;
+ }
+ else
+ break;
+ }
+
+ if (*s == ' ')
+ ++s;
+ if (args[1] != *s)
+ {
+ if (c == 'v' || c == 'w')
+ {
+ regno = mips16_to_32_reg_map[lastregno];
+ s = s_reset;
+ ++args;
+ }
+ }
+
+ switch (c)
+ {
+ case 'x':
+ case 'y':
+ case 'z':
+ case 'v':
+ case 'w':
+ case 'Z':
+ regno = mips32_to_16_reg_map[regno];
+ break;
+
+ case '0':
+ if (regno != 0)
+ regno = ILLEGAL_REG;
+ break;
+
+ case 'S':
+ if (regno != SP)
+ regno = ILLEGAL_REG;
+ break;
+
+ case 'R':
+ if (regno != RA)
+ regno = ILLEGAL_REG;
+ break;
+
+ case 'X':
+ case 'Y':
+ if (regno == AT && ! mips_opts.noat)
+ as_warn (_("used $at without \".set noat\""));
+ break;
+
+ default:
+ internalError ();
+ }
+
+ if (regno == ILLEGAL_REG)
+ break;
+
+ switch (c)
+ {
+ case 'x':
+ case 'v':
+ ip->insn_opcode |= regno << MIPS16OP_SH_RX;
+ break;
+ case 'y':
+ case 'w':
+ ip->insn_opcode |= regno << MIPS16OP_SH_RY;
+ break;
+ case 'z':
+ ip->insn_opcode |= regno << MIPS16OP_SH_RZ;
+ break;
+ case 'Z':
+ ip->insn_opcode |= regno << MIPS16OP_SH_MOVE32Z;
+ case '0':
+ case 'S':
+ case 'R':
+ break;
+ case 'X':
+ ip->insn_opcode |= regno << MIPS16OP_SH_REGR32;
+ break;
+ case 'Y':
+ regno = ((regno & 7) << 2) | ((regno & 0x18) >> 3);
+ ip->insn_opcode |= regno << MIPS16OP_SH_REG32R;
+ break;
+ default:
+ internalError ();
+ }
+
+ lastregno = regno;
+ continue;
+
+ case 'P':
+ if (strncmp (s, "$pc", 3) == 0)
+ {
+ s += 3;
+ continue;
+ }
+ break;
+
+ case '<':
+ case '>':
+ case '[':
+ case ']':
+ case '4':
+ case '5':
+ case 'H':
+ case 'W':
+ case 'D':
+ case 'j':
+ case '8':
+ case 'V':
+ case 'C':
+ case 'U':
+ case 'k':
+ case 'K':
+ if (s[0] == '%'
+ && strncmp (s + 1, "gprel(", sizeof "gprel(" - 1) == 0)
+ {
+ /* This is %gprel(SYMBOL). We need to read SYMBOL,
+ and generate the appropriate reloc. If the text
+ inside %gprel is not a symbol name with an
+ optional offset, then we generate a normal reloc
+ and will probably fail later. */
+ my_getExpression (&imm_expr, s + sizeof "%gprel" - 1);
+ if (imm_expr.X_op == O_symbol)
+ {
+ mips16_ext = TRUE;
+ *imm_reloc = BFD_RELOC_MIPS16_GPREL;
+ s = expr_end;
+ ip->use_extend = TRUE;
+ ip->extend = 0;
+ continue;
+ }
+ }
+ else
+ {
+ /* Just pick up a normal expression. */
+ my_getExpression (&imm_expr, s);
+ }
+
+ if (imm_expr.X_op == O_register)
+ {
+ /* What we thought was an expression turned out to
+ be a register. */
+
+ if (s[0] == '(' && args[1] == '(')
+ {
+ /* It looks like the expression was omitted
+ before a register indirection, which means
+ that the expression is implicitly zero. We
+ still set up imm_expr, so that we handle
+ explicit extensions correctly. */
+ imm_expr.X_op = O_constant;
+ imm_expr.X_add_number = 0;
+ *imm_reloc = (int) BFD_RELOC_UNUSED + c;
+ continue;
+ }
+
+ break;
+ }
+
+ /* We need to relax this instruction. */
+ *imm_reloc = (int) BFD_RELOC_UNUSED + c;
+ s = expr_end;
+ continue;
+
+ case 'p':
+ case 'q':
+ case 'A':
+ case 'B':
+ case 'E':
+ /* We use offset_reloc rather than imm_reloc for the PC
+ relative operands. This lets macros with both
+ immediate and address operands work correctly. */
+ my_getExpression (&offset_expr, s);
+
+ if (offset_expr.X_op == O_register)
+ break;
+
+ /* We need to relax this instruction. */
+ *offset_reloc = (int) BFD_RELOC_UNUSED + c;
+ s = expr_end;
+ continue;
+
+ case '6': /* break code */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number > 63)
+ {
+ as_warn (_("Invalid value for `%s' (%lu)"),
+ ip->insn_mo->name,
+ (unsigned long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= 0x3f;
+ }
+ ip->insn_opcode |= imm_expr.X_add_number << MIPS16OP_SH_IMM6;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'a': /* 26 bit address */
+ my_getExpression (&offset_expr, s);
+ s = expr_end;
+ *offset_reloc = BFD_RELOC_MIPS16_JMP;
+ ip->insn_opcode <<= 16;
+ continue;
+
+ case 'l': /* register list for entry macro */
+ case 'L': /* register list for exit macro */
+ {
+ int mask;
+
+ if (c == 'l')
+ mask = 0;
+ else
+ mask = 7 << 3;
+ while (*s != '\0')
+ {
+ int freg, reg1, reg2;
+
+ while (*s == ' ' || *s == ',')
+ ++s;
+ if (*s != '$')
+ {
+ as_bad (_("can't parse register list"));
+ break;
+ }
+ ++s;
+ if (*s != 'f')
+ freg = 0;
+ else
+ {
+ freg = 1;
+ ++s;
+ }
+ reg1 = 0;
+ while (ISDIGIT (*s))
+ {
+ reg1 *= 10;
+ reg1 += *s - '0';
+ ++s;
+ }
+ if (*s == ' ')
+ ++s;
+ if (*s != '-')
+ reg2 = reg1;
+ else
+ {
+ ++s;
+ if (*s != '$')
+ break;
+ ++s;
+ if (freg)
+ {
+ if (*s == 'f')
+ ++s;
+ else
+ {
+ as_bad (_("invalid register list"));
+ break;
+ }
+ }
+ reg2 = 0;
+ while (ISDIGIT (*s))
+ {
+ reg2 *= 10;
+ reg2 += *s - '0';
+ ++s;
+ }
+ }
+ if (freg && reg1 == 0 && reg2 == 0 && c == 'L')
+ {
+ mask &= ~ (7 << 3);
+ mask |= 5 << 3;
+ }
+ else if (freg && reg1 == 0 && reg2 == 1 && c == 'L')
+ {
+ mask &= ~ (7 << 3);
+ mask |= 6 << 3;
+ }
+ else if (reg1 == 4 && reg2 >= 4 && reg2 <= 7 && c != 'L')
+ mask |= (reg2 - 3) << 3;
+ else if (reg1 == 16 && reg2 >= 16 && reg2 <= 17)
+ mask |= (reg2 - 15) << 1;
+ else if (reg1 == RA && reg2 == RA)
+ mask |= 1;
+ else
+ {
+ as_bad (_("invalid register list"));
+ break;
+ }
+ }
+ /* The mask is filled in in the opcode table for the
+ benefit of the disassembler. We remove it before
+ applying the actual mask. */
+ ip->insn_opcode &= ~ ((7 << 3) << MIPS16OP_SH_IMM6);
+ ip->insn_opcode |= mask << MIPS16OP_SH_IMM6;
+ }
+ continue;
+
+ case 'e': /* extend code */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number > 0x7ff)
+ {
+ as_warn (_("Invalid value for `%s' (%lu)"),
+ ip->insn_mo->name,
+ (unsigned long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= 0x7ff;
+ }
+ ip->insn_opcode |= imm_expr.X_add_number;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ default:
+ internalError ();
+ }
+ break;
+ }
+
+ /* Args don't match. */
+ if (insn + 1 < &mips16_opcodes[bfd_mips16_num_opcodes] &&
+ strcmp (insn->name, insn[1].name) == 0)
+ {
+ ++insn;
+ s = argsstart;
+ continue;
+ }
+
+ insn_error = _("illegal operands");
+
+ return;
+ }
+}
+
+/* This structure holds information we know about a mips16 immediate
+ argument type. */
+
+struct mips16_immed_operand
+{
+ /* The type code used in the argument string in the opcode table. */
+ int type;
+ /* The number of bits in the short form of the opcode. */
+ int nbits;
+ /* The number of bits in the extended form of the opcode. */
+ int extbits;
+ /* The amount by which the short form is shifted when it is used;
+ for example, the sw instruction has a shift count of 2. */
+ int shift;
+ /* The amount by which the short form is shifted when it is stored
+ into the instruction code. */
+ int op_shift;
+ /* Non-zero if the short form is unsigned. */
+ int unsp;
+ /* Non-zero if the extended form is unsigned. */
+ int extu;
+ /* Non-zero if the value is PC relative. */
+ int pcrel;
+};
+
+/* The mips16 immediate operand types. */
+
+static const struct mips16_immed_operand mips16_immed_operands[] =
+{
+ { '<', 3, 5, 0, MIPS16OP_SH_RZ, 1, 1, 0 },
+ { '>', 3, 5, 0, MIPS16OP_SH_RX, 1, 1, 0 },
+ { '[', 3, 6, 0, MIPS16OP_SH_RZ, 1, 1, 0 },
+ { ']', 3, 6, 0, MIPS16OP_SH_RX, 1, 1, 0 },
+ { '4', 4, 15, 0, MIPS16OP_SH_IMM4, 0, 0, 0 },
+ { '5', 5, 16, 0, MIPS16OP_SH_IMM5, 1, 0, 0 },
+ { 'H', 5, 16, 1, MIPS16OP_SH_IMM5, 1, 0, 0 },
+ { 'W', 5, 16, 2, MIPS16OP_SH_IMM5, 1, 0, 0 },
+ { 'D', 5, 16, 3, MIPS16OP_SH_IMM5, 1, 0, 0 },
+ { 'j', 5, 16, 0, MIPS16OP_SH_IMM5, 0, 0, 0 },
+ { '8', 8, 16, 0, MIPS16OP_SH_IMM8, 1, 0, 0 },
+ { 'V', 8, 16, 2, MIPS16OP_SH_IMM8, 1, 0, 0 },
+ { 'C', 8, 16, 3, MIPS16OP_SH_IMM8, 1, 0, 0 },
+ { 'U', 8, 16, 0, MIPS16OP_SH_IMM8, 1, 1, 0 },
+ { 'k', 8, 16, 0, MIPS16OP_SH_IMM8, 0, 0, 0 },
+ { 'K', 8, 16, 3, MIPS16OP_SH_IMM8, 0, 0, 0 },
+ { 'p', 8, 16, 0, MIPS16OP_SH_IMM8, 0, 0, 1 },
+ { 'q', 11, 16, 0, MIPS16OP_SH_IMM8, 0, 0, 1 },
+ { 'A', 8, 16, 2, MIPS16OP_SH_IMM8, 1, 0, 1 },
+ { 'B', 5, 16, 3, MIPS16OP_SH_IMM5, 1, 0, 1 },
+ { 'E', 5, 16, 2, MIPS16OP_SH_IMM5, 1, 0, 1 }
+};
+
+#define MIPS16_NUM_IMMED \
+ (sizeof mips16_immed_operands / sizeof mips16_immed_operands[0])
+
+/* Handle a mips16 instruction with an immediate value. This or's the
+ small immediate value into *INSN. It sets *USE_EXTEND to indicate
+ whether an extended value is needed; if one is needed, it sets
+ *EXTEND to the value. The argument type is TYPE. The value is VAL.
+ If SMALL is true, an unextended opcode was explicitly requested.
+ If EXT is true, an extended opcode was explicitly requested. If
+ WARN is true, warn if EXT does not match reality. */
+
+static void
+mips16_immed (char *file, unsigned int line, int type, offsetT val,
+ bfd_boolean warn, bfd_boolean small, bfd_boolean ext,
+ unsigned long *insn, bfd_boolean *use_extend,
+ unsigned short *extend)
+{
+ register const struct mips16_immed_operand *op;
+ int mintiny, maxtiny;
+ bfd_boolean needext;
+
+ op = mips16_immed_operands;
+ while (op->type != type)
+ {
+ ++op;
+ assert (op < mips16_immed_operands + MIPS16_NUM_IMMED);
+ }
+
+ if (op->unsp)
+ {
+ if (type == '<' || type == '>' || type == '[' || type == ']')
+ {
+ mintiny = 1;
+ maxtiny = 1 << op->nbits;
+ }
+ else
+ {
+ mintiny = 0;
+ maxtiny = (1 << op->nbits) - 1;
+ }
+ }
+ else
+ {
+ mintiny = - (1 << (op->nbits - 1));
+ maxtiny = (1 << (op->nbits - 1)) - 1;
+ }
+
+ /* Branch offsets have an implicit 0 in the lowest bit. */
+ if (type == 'p' || type == 'q')
+ val /= 2;
+
+ if ((val & ((1 << op->shift) - 1)) != 0
+ || val < (mintiny << op->shift)
+ || val > (maxtiny << op->shift))
+ needext = TRUE;
+ else
+ needext = FALSE;
+
+ if (warn && ext && ! needext)
+ as_warn_where (file, line,
+ _("extended operand requested but not required"));
+ if (small && needext)
+ as_bad_where (file, line, _("invalid unextended operand value"));
+
+ if (small || (! ext && ! needext))
+ {
+ int insnval;
+
+ *use_extend = FALSE;
+ insnval = ((val >> op->shift) & ((1 << op->nbits) - 1));
+ insnval <<= op->op_shift;
+ *insn |= insnval;
+ }
+ else
+ {
+ long minext, maxext;
+ int extval;
+
+ if (op->extu)
+ {
+ minext = 0;
+ maxext = (1 << op->extbits) - 1;
+ }
+ else
+ {
+ minext = - (1 << (op->extbits - 1));
+ maxext = (1 << (op->extbits - 1)) - 1;
+ }
+ if (val < minext || val > maxext)
+ as_bad_where (file, line,
+ _("operand value out of range for instruction"));
+
+ *use_extend = TRUE;
+ if (op->extbits == 16)
+ {
+ extval = ((val >> 11) & 0x1f) | (val & 0x7e0);
+ val &= 0x1f;
+ }
+ else if (op->extbits == 15)
+ {
+ extval = ((val >> 11) & 0xf) | (val & 0x7f0);
+ val &= 0xf;
+ }
+ else
+ {
+ extval = ((val & 0x1f) << 6) | (val & 0x20);
+ val = 0;
+ }
+
+ *extend = (unsigned short) extval;
+ *insn |= val;
+ }
+}
+
+static const struct percent_op_match
+{
+ const char *str;
+ bfd_reloc_code_real_type reloc;
+} percent_op[] =
+{
+ {"%lo", BFD_RELOC_LO16},
+#ifdef OBJ_ELF
+ {"%call_hi", BFD_RELOC_MIPS_CALL_HI16},
+ {"%call_lo", BFD_RELOC_MIPS_CALL_LO16},
+ {"%call16", BFD_RELOC_MIPS_CALL16},
+ {"%got_disp", BFD_RELOC_MIPS_GOT_DISP},
+ {"%got_page", BFD_RELOC_MIPS_GOT_PAGE},
+ {"%got_ofst", BFD_RELOC_MIPS_GOT_OFST},
+ {"%got_hi", BFD_RELOC_MIPS_GOT_HI16},
+ {"%got_lo", BFD_RELOC_MIPS_GOT_LO16},
+ {"%got", BFD_RELOC_MIPS_GOT16},
+ {"%gp_rel", BFD_RELOC_GPREL16},
+ {"%half", BFD_RELOC_16},
+ {"%highest", BFD_RELOC_MIPS_HIGHEST},
+ {"%higher", BFD_RELOC_MIPS_HIGHER},
+ {"%neg", BFD_RELOC_MIPS_SUB},
+#endif
+ {"%hi", BFD_RELOC_HI16_S}
+};
+
+
+/* Return true if *STR points to a relocation operator. When returning true,
+ move *STR over the operator and store its relocation code in *RELOC.
+ Leave both *STR and *RELOC alone when returning false. */
+
+static bfd_boolean
+parse_relocation (char **str, bfd_reloc_code_real_type *reloc)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE (percent_op); i++)
+ if (strncasecmp (*str, percent_op[i].str, strlen (percent_op[i].str)) == 0)
+ {
+ *str += strlen (percent_op[i].str);
+ *reloc = percent_op[i].reloc;
+
+ /* Check whether the output BFD supports this relocation.
+ If not, issue an error and fall back on something safe. */
+ if (!bfd_reloc_type_lookup (stdoutput, percent_op[i].reloc))
+ {
+ as_bad ("relocation %s isn't supported by the current ABI",
+ percent_op[i].str);
+ *reloc = BFD_RELOC_LO16;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/* Parse string STR as a 16-bit relocatable operand. Store the
+ expression in *EP and the relocations in the array starting
+ at RELOC. Return the number of relocation operators used.
+
+ On exit, EXPR_END points to the first character after the expression.
+ If no relocation operators are used, RELOC[0] is set to BFD_RELOC_LO16. */
+
+static size_t
+my_getSmallExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
+ char *str)
+{
+ bfd_reloc_code_real_type reversed_reloc[3];
+ size_t reloc_index, i;
+ int crux_depth, str_depth;
+ char *crux;
+
+ /* Search for the start of the main expression, recoding relocations
+ in REVERSED_RELOC. End the loop with CRUX pointing to the start
+ of the main expression and with CRUX_DEPTH containing the number
+ of open brackets at that point. */
+ reloc_index = -1;
+ str_depth = 0;
+ do
+ {
+ reloc_index++;
+ crux = str;
+ crux_depth = str_depth;
+
+ /* Skip over whitespace and brackets, keeping count of the number
+ of brackets. */
+ while (*str == ' ' || *str == '\t' || *str == '(')
+ if (*str++ == '(')
+ str_depth++;
+ }
+ while (*str == '%'
+ && reloc_index < (HAVE_NEWABI ? 3 : 1)
+ && parse_relocation (&str, &reversed_reloc[reloc_index]));
+
+ my_getExpression (ep, crux);
+ str = expr_end;
+
+ /* Match every open bracket. */
+ while (crux_depth > 0 && (*str == ')' || *str == ' ' || *str == '\t'))
+ if (*str++ == ')')
+ crux_depth--;
+
+ if (crux_depth > 0)
+ as_bad ("unclosed '('");
+
+ expr_end = str;
+
+ if (reloc_index == 0)
+ reloc[0] = BFD_RELOC_LO16;
+ else
+ {
+ prev_reloc_op_frag = frag_now;
+ for (i = 0; i < reloc_index; i++)
+ reloc[i] = reversed_reloc[reloc_index - 1 - i];
+ }
+
+ return reloc_index;
+}
+
+static void
+my_getExpression (expressionS *ep, char *str)
+{
+ char *save_in;
+ valueT val;
+
+ save_in = input_line_pointer;
+ input_line_pointer = str;
+ expression (ep);
+ expr_end = input_line_pointer;
+ input_line_pointer = save_in;
+
+ /* If we are in mips16 mode, and this is an expression based on `.',
+ then we bump the value of the symbol by 1 since that is how other
+ text symbols are handled. We don't bother to handle complex
+ expressions, just `.' plus or minus a constant. */
+ if (mips_opts.mips16
+ && ep->X_op == O_symbol
+ && strcmp (S_GET_NAME (ep->X_add_symbol), FAKE_LABEL_NAME) == 0
+ && S_GET_SEGMENT (ep->X_add_symbol) == now_seg
+ && symbol_get_frag (ep->X_add_symbol) == frag_now
+ && symbol_constant_p (ep->X_add_symbol)
+ && (val = S_GET_VALUE (ep->X_add_symbol)) == frag_now_fix ())
+ S_SET_VALUE (ep->X_add_symbol, val + 1);
+}
+
+/* Turn a string in input_line_pointer into a floating point constant
+ of type TYPE, and store the appropriate bytes in *LITP. The number
+ of LITTLENUMS emitted is stored in *SIZEP. An error message is
+ returned, or NULL on OK. */
+
+char *
+md_atof (int type, char *litP, int *sizeP)
+{
+ int prec;
+ LITTLENUM_TYPE words[4];
+ char *t;
+ int i;
+
+ switch (type)
+ {
+ case 'f':
+ prec = 2;
+ break;
+
+ case 'd':
+ prec = 4;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("bad call to md_atof");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * 2;
+
+ if (! target_big_endian)
+ {
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litP, words[i], 2);
+ litP += 2;
+ }
+ }
+ else
+ {
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, words[i], 2);
+ litP += 2;
+ }
+ }
+
+ return NULL;
+}
+
+void
+md_number_to_chars (char *buf, valueT val, int n)
+{
+ if (target_big_endian)
+ number_to_chars_bigendian (buf, val, n);
+ else
+ number_to_chars_littleendian (buf, val, n);
+}
+
+#ifdef OBJ_ELF
+static int support_64bit_objects(void)
+{
+ const char **list, **l;
+ int yes;
+
+ list = bfd_target_list ();
+ for (l = list; *l != NULL; l++)
+#ifdef TE_TMIPS
+ /* This is traditional mips */
+ if (strcmp (*l, "elf64-tradbigmips") == 0
+ || strcmp (*l, "elf64-tradlittlemips") == 0)
+#else
+ if (strcmp (*l, "elf64-bigmips") == 0
+ || strcmp (*l, "elf64-littlemips") == 0)
+#endif
+ break;
+ yes = (*l != NULL);
+ free (list);
+ return yes;
+}
+#endif /* OBJ_ELF */
+
+const char *md_shortopts = "O::g::G:";
+
+struct option md_longopts[] =
+{
+ /* Options which specify architecture. */
+#define OPTION_ARCH_BASE (OPTION_MD_BASE)
+#define OPTION_MARCH (OPTION_ARCH_BASE + 0)
+ {"march", required_argument, NULL, OPTION_MARCH},
+#define OPTION_MTUNE (OPTION_ARCH_BASE + 1)
+ {"mtune", required_argument, NULL, OPTION_MTUNE},
+#define OPTION_MIPS1 (OPTION_ARCH_BASE + 2)
+ {"mips0", no_argument, NULL, OPTION_MIPS1},
+ {"mips1", no_argument, NULL, OPTION_MIPS1},
+#define OPTION_MIPS2 (OPTION_ARCH_BASE + 3)
+ {"mips2", no_argument, NULL, OPTION_MIPS2},
+#define OPTION_MIPS3 (OPTION_ARCH_BASE + 4)
+ {"mips3", no_argument, NULL, OPTION_MIPS3},
+#define OPTION_MIPS4 (OPTION_ARCH_BASE + 5)
+ {"mips4", no_argument, NULL, OPTION_MIPS4},
+#define OPTION_MIPS5 (OPTION_ARCH_BASE + 6)
+ {"mips5", no_argument, NULL, OPTION_MIPS5},
+#define OPTION_MIPS32 (OPTION_ARCH_BASE + 7)
+ {"mips32", no_argument, NULL, OPTION_MIPS32},
+#define OPTION_MIPS64 (OPTION_ARCH_BASE + 8)
+ {"mips64", no_argument, NULL, OPTION_MIPS64},
+#define OPTION_MIPS32R2 (OPTION_ARCH_BASE + 9)
+ {"mips32r2", no_argument, NULL, OPTION_MIPS32R2},
+#define OPTION_MIPS64R2 (OPTION_ARCH_BASE + 10)
+ {"mips64r2", no_argument, NULL, OPTION_MIPS64R2},
+
+ /* Options which specify Application Specific Extensions (ASEs). */
+#define OPTION_ASE_BASE (OPTION_ARCH_BASE + 11)
+#define OPTION_MIPS16 (OPTION_ASE_BASE + 0)
+ {"mips16", no_argument, NULL, OPTION_MIPS16},
+#define OPTION_NO_MIPS16 (OPTION_ASE_BASE + 1)
+ {"no-mips16", no_argument, NULL, OPTION_NO_MIPS16},
+#define OPTION_MIPS3D (OPTION_ASE_BASE + 2)
+ {"mips3d", no_argument, NULL, OPTION_MIPS3D},
+#define OPTION_NO_MIPS3D (OPTION_ASE_BASE + 3)
+ {"no-mips3d", no_argument, NULL, OPTION_NO_MIPS3D},
+#define OPTION_MDMX (OPTION_ASE_BASE + 4)
+ {"mdmx", no_argument, NULL, OPTION_MDMX},
+#define OPTION_NO_MDMX (OPTION_ASE_BASE + 5)
+ {"no-mdmx", no_argument, NULL, OPTION_NO_MDMX},
+
+ /* Old-style architecture options. Don't add more of these. */
+#define OPTION_COMPAT_ARCH_BASE (OPTION_ASE_BASE + 6)
+#define OPTION_M4650 (OPTION_COMPAT_ARCH_BASE + 0)
+ {"m4650", no_argument, NULL, OPTION_M4650},
+#define OPTION_NO_M4650 (OPTION_COMPAT_ARCH_BASE + 1)
+ {"no-m4650", no_argument, NULL, OPTION_NO_M4650},
+#define OPTION_M4010 (OPTION_COMPAT_ARCH_BASE + 2)
+ {"m4010", no_argument, NULL, OPTION_M4010},
+#define OPTION_NO_M4010 (OPTION_COMPAT_ARCH_BASE + 3)
+ {"no-m4010", no_argument, NULL, OPTION_NO_M4010},
+#define OPTION_M4100 (OPTION_COMPAT_ARCH_BASE + 4)
+ {"m4100", no_argument, NULL, OPTION_M4100},
+#define OPTION_NO_M4100 (OPTION_COMPAT_ARCH_BASE + 5)
+ {"no-m4100", no_argument, NULL, OPTION_NO_M4100},
+#define OPTION_M3900 (OPTION_COMPAT_ARCH_BASE + 6)
+ {"m3900", no_argument, NULL, OPTION_M3900},
+#define OPTION_NO_M3900 (OPTION_COMPAT_ARCH_BASE + 7)
+ {"no-m3900", no_argument, NULL, OPTION_NO_M3900},
+
+ /* Options which enable bug fixes. */
+#define OPTION_FIX_BASE (OPTION_COMPAT_ARCH_BASE + 8)
+#define OPTION_M7000_HILO_FIX (OPTION_FIX_BASE + 0)
+ {"mfix7000", no_argument, NULL, OPTION_M7000_HILO_FIX},
+#define OPTION_MNO_7000_HILO_FIX (OPTION_FIX_BASE + 1)
+ {"no-fix-7000", no_argument, NULL, OPTION_MNO_7000_HILO_FIX},
+ {"mno-fix7000", no_argument, NULL, OPTION_MNO_7000_HILO_FIX},
+#define OPTION_FIX_VR4120 (OPTION_FIX_BASE + 2)
+#define OPTION_NO_FIX_VR4120 (OPTION_FIX_BASE + 3)
+ {"mfix-vr4120", no_argument, NULL, OPTION_FIX_VR4120},
+ {"mno-fix-vr4120", no_argument, NULL, OPTION_NO_FIX_VR4120},
+
+ /* Miscellaneous options. */
+#define OPTION_MISC_BASE (OPTION_FIX_BASE + 4)
+#define OPTION_MEMBEDDED_PIC (OPTION_MISC_BASE + 0)
+ {"membedded-pic", no_argument, NULL, OPTION_MEMBEDDED_PIC},
+#define OPTION_TRAP (OPTION_MISC_BASE + 1)
+ {"trap", no_argument, NULL, OPTION_TRAP},
+ {"no-break", no_argument, NULL, OPTION_TRAP},
+#define OPTION_BREAK (OPTION_MISC_BASE + 2)
+ {"break", no_argument, NULL, OPTION_BREAK},
+ {"no-trap", no_argument, NULL, OPTION_BREAK},
+#define OPTION_EB (OPTION_MISC_BASE + 3)
+ {"EB", no_argument, NULL, OPTION_EB},
+#define OPTION_EL (OPTION_MISC_BASE + 4)
+ {"EL", no_argument, NULL, OPTION_EL},
+#define OPTION_FP32 (OPTION_MISC_BASE + 5)
+ {"mfp32", no_argument, NULL, OPTION_FP32},
+#define OPTION_GP32 (OPTION_MISC_BASE + 6)
+ {"mgp32", no_argument, NULL, OPTION_GP32},
+#define OPTION_CONSTRUCT_FLOATS (OPTION_MISC_BASE + 7)
+ {"construct-floats", no_argument, NULL, OPTION_CONSTRUCT_FLOATS},
+#define OPTION_NO_CONSTRUCT_FLOATS (OPTION_MISC_BASE + 8)
+ {"no-construct-floats", no_argument, NULL, OPTION_NO_CONSTRUCT_FLOATS},
+#define OPTION_FP64 (OPTION_MISC_BASE + 9)
+ {"mfp64", no_argument, NULL, OPTION_FP64},
+#define OPTION_GP64 (OPTION_MISC_BASE + 10)
+ {"mgp64", no_argument, NULL, OPTION_GP64},
+#define OPTION_RELAX_BRANCH (OPTION_MISC_BASE + 11)
+#define OPTION_NO_RELAX_BRANCH (OPTION_MISC_BASE + 12)
+ {"relax-branch", no_argument, NULL, OPTION_RELAX_BRANCH},
+ {"no-relax-branch", no_argument, NULL, OPTION_NO_RELAX_BRANCH},
+
+ /* ELF-specific options. */
+#ifdef OBJ_ELF
+#define OPTION_ELF_BASE (OPTION_MISC_BASE + 13)
+#define OPTION_CALL_SHARED (OPTION_ELF_BASE + 0)
+ {"KPIC", no_argument, NULL, OPTION_CALL_SHARED},
+ {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
+#define OPTION_NON_SHARED (OPTION_ELF_BASE + 1)
+ {"non_shared", no_argument, NULL, OPTION_NON_SHARED},
+#define OPTION_XGOT (OPTION_ELF_BASE + 2)
+ {"xgot", no_argument, NULL, OPTION_XGOT},
+#define OPTION_MABI (OPTION_ELF_BASE + 3)
+ {"mabi", required_argument, NULL, OPTION_MABI},
+#define OPTION_32 (OPTION_ELF_BASE + 4)
+ {"32", no_argument, NULL, OPTION_32},
+#define OPTION_N32 (OPTION_ELF_BASE + 5)
+ {"n32", no_argument, NULL, OPTION_N32},
+#define OPTION_64 (OPTION_ELF_BASE + 6)
+ {"64", no_argument, NULL, OPTION_64},
+#define OPTION_MDEBUG (OPTION_ELF_BASE + 7)
+ {"mdebug", no_argument, NULL, OPTION_MDEBUG},
+#define OPTION_NO_MDEBUG (OPTION_ELF_BASE + 8)
+ {"no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG},
+#define OPTION_PDR (OPTION_ELF_BASE + 9)
+ {"mpdr", no_argument, NULL, OPTION_PDR},
+#define OPTION_NO_PDR (OPTION_ELF_BASE + 10)
+ {"mno-pdr", no_argument, NULL, OPTION_NO_PDR},
+#endif /* OBJ_ELF */
+
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof (md_longopts);
+
+/* Set STRING_PTR (either &mips_arch_string or &mips_tune_string) to
+ NEW_VALUE. Warn if another value was already specified. Note:
+ we have to defer parsing the -march and -mtune arguments in order
+ to handle 'from-abi' correctly, since the ABI might be specified
+ in a later argument. */
+
+static void
+mips_set_option_string (const char **string_ptr, const char *new_value)
+{
+ if (*string_ptr != 0 && strcasecmp (*string_ptr, new_value) != 0)
+ as_warn (_("A different %s was already specified, is now %s"),
+ string_ptr == &mips_arch_string ? "-march" : "-mtune",
+ new_value);
+
+ *string_ptr = new_value;
+}
+
+int
+md_parse_option (int c, char *arg)
+{
+ switch (c)
+ {
+ case OPTION_CONSTRUCT_FLOATS:
+ mips_disable_float_construction = 0;
+ break;
+
+ case OPTION_NO_CONSTRUCT_FLOATS:
+ mips_disable_float_construction = 1;
+ break;
+
+ case OPTION_TRAP:
+ mips_trap = 1;
+ break;
+
+ case OPTION_BREAK:
+ mips_trap = 0;
+ break;
+
+ case OPTION_EB:
+ target_big_endian = 1;
+ break;
+
+ case OPTION_EL:
+ target_big_endian = 0;
+ break;
+
+ case 'O':
+ if (arg && arg[1] == '0')
+ mips_optimize = 1;
+ else
+ mips_optimize = 2;
+ break;
+
+ case 'g':
+ if (arg == NULL)
+ mips_debug = 2;
+ else
+ mips_debug = atoi (arg);
+ /* When the MIPS assembler sees -g or -g2, it does not do
+ optimizations which limit full symbolic debugging. We take
+ that to be equivalent to -O0. */
+ if (mips_debug == 2)
+ mips_optimize = 1;
+ break;
+
+ case OPTION_MIPS1:
+ file_mips_isa = ISA_MIPS1;
+ break;
+
+ case OPTION_MIPS2:
+ file_mips_isa = ISA_MIPS2;
+ break;
+
+ case OPTION_MIPS3:
+ file_mips_isa = ISA_MIPS3;
+ break;
+
+ case OPTION_MIPS4:
+ file_mips_isa = ISA_MIPS4;
+ break;
+
+ case OPTION_MIPS5:
+ file_mips_isa = ISA_MIPS5;
+ break;
+
+ case OPTION_MIPS32:
+ file_mips_isa = ISA_MIPS32;
+ break;
+
+ case OPTION_MIPS32R2:
+ file_mips_isa = ISA_MIPS32R2;
+ break;
+
+ case OPTION_MIPS64R2:
+ file_mips_isa = ISA_MIPS64R2;
+ break;
+
+ case OPTION_MIPS64:
+ file_mips_isa = ISA_MIPS64;
+ break;
+
+ case OPTION_MTUNE:
+ mips_set_option_string (&mips_tune_string, arg);
+ break;
+
+ case OPTION_MARCH:
+ mips_set_option_string (&mips_arch_string, arg);
+ break;
+
+ case OPTION_M4650:
+ mips_set_option_string (&mips_arch_string, "4650");
+ mips_set_option_string (&mips_tune_string, "4650");
+ break;
+
+ case OPTION_NO_M4650:
+ break;
+
+ case OPTION_M4010:
+ mips_set_option_string (&mips_arch_string, "4010");
+ mips_set_option_string (&mips_tune_string, "4010");
+ break;
+
+ case OPTION_NO_M4010:
+ break;
+
+ case OPTION_M4100:
+ mips_set_option_string (&mips_arch_string, "4100");
+ mips_set_option_string (&mips_tune_string, "4100");
+ break;
+
+ case OPTION_NO_M4100:
+ break;
+
+ case OPTION_M3900:
+ mips_set_option_string (&mips_arch_string, "3900");
+ mips_set_option_string (&mips_tune_string, "3900");
+ break;
+
+ case OPTION_NO_M3900:
+ break;
+
+ case OPTION_MDMX:
+ mips_opts.ase_mdmx = 1;
+ break;
+
+ case OPTION_NO_MDMX:
+ mips_opts.ase_mdmx = 0;
+ break;
+
+ case OPTION_MIPS16:
+ mips_opts.mips16 = 1;
+ mips_no_prev_insn (FALSE);
+ break;
+
+ case OPTION_NO_MIPS16:
+ mips_opts.mips16 = 0;
+ mips_no_prev_insn (FALSE);
+ break;
+
+ case OPTION_MIPS3D:
+ mips_opts.ase_mips3d = 1;
+ break;
+
+ case OPTION_NO_MIPS3D:
+ mips_opts.ase_mips3d = 0;
+ break;
+
+ case OPTION_MEMBEDDED_PIC:
+ mips_pic = EMBEDDED_PIC;
+ if (USE_GLOBAL_POINTER_OPT && g_switch_seen)
+ {
+ as_bad (_("-G may not be used with embedded PIC code"));
+ return 0;
+ }
+ g_switch_value = 0x7fffffff;
+ break;
+
+ case OPTION_FIX_VR4120:
+ mips_fix_vr4120 = 1;
+ break;
+
+ case OPTION_NO_FIX_VR4120:
+ mips_fix_vr4120 = 0;
+ break;
+
+ case OPTION_RELAX_BRANCH:
+ mips_relax_branch = 1;
+ break;
+
+ case OPTION_NO_RELAX_BRANCH:
+ mips_relax_branch = 0;
+ break;
+
+#ifdef OBJ_ELF
+ /* When generating ELF code, we permit -KPIC and -call_shared to
+ select SVR4_PIC, and -non_shared to select no PIC. This is
+ intended to be compatible with Irix 5. */
+ case OPTION_CALL_SHARED:
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+ {
+ as_bad (_("-call_shared is supported only for ELF format"));
+ return 0;
+ }
+ mips_pic = SVR4_PIC;
+ mips_abicalls = TRUE;
+ if (g_switch_seen && g_switch_value != 0)
+ {
+ as_bad (_("-G may not be used with SVR4 PIC code"));
+ return 0;
+ }
+ g_switch_value = 0;
+ break;
+
+ case OPTION_NON_SHARED:
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+ {
+ as_bad (_("-non_shared is supported only for ELF format"));
+ return 0;
+ }
+ mips_pic = NO_PIC;
+ mips_abicalls = FALSE;
+ break;
+
+ /* The -xgot option tells the assembler to use 32 offsets when
+ accessing the got in SVR4_PIC mode. It is for Irix
+ compatibility. */
+ case OPTION_XGOT:
+ mips_big_got = 1;
+ break;
+#endif /* OBJ_ELF */
+
+ case 'G':
+ if (! USE_GLOBAL_POINTER_OPT)
+ {
+ as_bad (_("-G is not supported for this configuration"));
+ return 0;
+ }
+ else if (mips_pic == SVR4_PIC || mips_pic == EMBEDDED_PIC)
+ {
+ as_bad (_("-G may not be used with SVR4 or embedded PIC code"));
+ return 0;
+ }
+ else
+ g_switch_value = atoi (arg);
+ g_switch_seen = 1;
+ break;
+
+#ifdef OBJ_ELF
+ /* The -32, -n32 and -64 options are shortcuts for -mabi=32, -mabi=n32
+ and -mabi=64. */
+ case OPTION_32:
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+ {
+ as_bad (_("-32 is supported for ELF format only"));
+ return 0;
+ }
+ mips_abi = O32_ABI;
+ break;
+
+ case OPTION_N32:
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+ {
+ as_bad (_("-n32 is supported for ELF format only"));
+ return 0;
+ }
+ mips_abi = N32_ABI;
+ break;
+
+ case OPTION_64:
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+ {
+ as_bad (_("-64 is supported for ELF format only"));
+ return 0;
+ }
+ mips_abi = N64_ABI;
+ if (! support_64bit_objects())
+ as_fatal (_("No compiled in support for 64 bit object file format"));
+ break;
+#endif /* OBJ_ELF */
+
+ case OPTION_GP32:
+ file_mips_gp32 = 1;
+ break;
+
+ case OPTION_GP64:
+ file_mips_gp32 = 0;
+ break;
+
+ case OPTION_FP32:
+ file_mips_fp32 = 1;
+ break;
+
+ case OPTION_FP64:
+ file_mips_fp32 = 0;
+ break;
+
+#ifdef OBJ_ELF
+ case OPTION_MABI:
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+ {
+ as_bad (_("-mabi is supported for ELF format only"));
+ return 0;
+ }
+ if (strcmp (arg, "32") == 0)
+ mips_abi = O32_ABI;
+ else if (strcmp (arg, "o64") == 0)
+ mips_abi = O64_ABI;
+ else if (strcmp (arg, "n32") == 0)
+ mips_abi = N32_ABI;
+ else if (strcmp (arg, "64") == 0)
+ {
+ mips_abi = N64_ABI;
+ if (! support_64bit_objects())
+ as_fatal (_("No compiled in support for 64 bit object file "
+ "format"));
+ }
+ else if (strcmp (arg, "eabi") == 0)
+ mips_abi = EABI_ABI;
+ else
+ {
+ as_fatal (_("invalid abi -mabi=%s"), arg);
+ return 0;
+ }
+ break;
+#endif /* OBJ_ELF */
+
+ case OPTION_M7000_HILO_FIX:
+ mips_7000_hilo_fix = TRUE;
+ break;
+
+ case OPTION_MNO_7000_HILO_FIX:
+ mips_7000_hilo_fix = FALSE;
+ break;
+
+#ifdef OBJ_ELF
+ case OPTION_MDEBUG:
+ mips_flag_mdebug = TRUE;
+ break;
+
+ case OPTION_NO_MDEBUG:
+ mips_flag_mdebug = FALSE;
+ break;
+
+ case OPTION_PDR:
+ mips_flag_pdr = TRUE;
+ break;
+
+ case OPTION_NO_PDR:
+ mips_flag_pdr = FALSE;
+ break;
+#endif /* OBJ_ELF */
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Set up globals to generate code for the ISA or processor
+ described by INFO. */
+
+static void
+mips_set_architecture (const struct mips_cpu_info *info)
+{
+ if (info != 0)
+ {
+ file_mips_arch = info->cpu;
+ mips_opts.arch = info->cpu;
+ mips_opts.isa = info->isa;
+ }
+}
+
+
+/* Likewise for tuning. */
+
+static void
+mips_set_tune (const struct mips_cpu_info *info)
+{
+ if (info != 0)
+ mips_tune = info->cpu;
+}
+
+
+void
+mips_after_parse_args (void)
+{
+ const struct mips_cpu_info *arch_info = 0;
+ const struct mips_cpu_info *tune_info = 0;
+
+ /* GP relative stuff not working for PE */
+ if (strncmp (TARGET_OS, "pe", 2) == 0
+ && g_switch_value != 0)
+ {
+ if (g_switch_seen)
+ as_bad (_("-G not supported in this configuration."));
+ g_switch_value = 0;
+ }
+
+ if (mips_abi == NO_ABI)
+ mips_abi = MIPS_DEFAULT_ABI;
+
+ /* The following code determines the architecture and register size.
+ Similar code was added to GCC 3.3 (see override_options() in
+ config/mips/mips.c). The GAS and GCC code should be kept in sync
+ as much as possible. */
+
+ if (mips_arch_string != 0)
+ arch_info = mips_parse_cpu ("-march", mips_arch_string);
+
+ if (file_mips_isa != ISA_UNKNOWN)
+ {
+ /* Handle -mipsN. At this point, file_mips_isa contains the
+ ISA level specified by -mipsN, while arch_info->isa contains
+ the -march selection (if any). */
+ if (arch_info != 0)
+ {
+ /* -march takes precedence over -mipsN, since it is more descriptive.
+ There's no harm in specifying both as long as the ISA levels
+ are the same. */
+ if (file_mips_isa != arch_info->isa)
+ as_bad (_("-%s conflicts with the other architecture options, which imply -%s"),
+ mips_cpu_info_from_isa (file_mips_isa)->name,
+ mips_cpu_info_from_isa (arch_info->isa)->name);
+ }
+ else
+ arch_info = mips_cpu_info_from_isa (file_mips_isa);
+ }
+
+ if (arch_info == 0)
+ arch_info = mips_parse_cpu ("default CPU", MIPS_CPU_STRING_DEFAULT);
+
+ if (ABI_NEEDS_64BIT_REGS (mips_abi) && !ISA_HAS_64BIT_REGS (arch_info->isa))
+ as_bad ("-march=%s is not compatible with the selected ABI",
+ arch_info->name);
+
+ mips_set_architecture (arch_info);
+
+ /* Optimize for file_mips_arch, unless -mtune selects a different processor. */
+ if (mips_tune_string != 0)
+ tune_info = mips_parse_cpu ("-mtune", mips_tune_string);
+
+ if (tune_info == 0)
+ mips_set_tune (arch_info);
+ else
+ mips_set_tune (tune_info);
+
+ if (file_mips_gp32 >= 0)
+ {
+ /* The user specified the size of the integer registers. Make sure
+ it agrees with the ABI and ISA. */
+ if (file_mips_gp32 == 0 && !ISA_HAS_64BIT_REGS (mips_opts.isa))
+ as_bad (_("-mgp64 used with a 32-bit processor"));
+ else if (file_mips_gp32 == 1 && ABI_NEEDS_64BIT_REGS (mips_abi))
+ as_bad (_("-mgp32 used with a 64-bit ABI"));
+ else if (file_mips_gp32 == 0 && ABI_NEEDS_32BIT_REGS (mips_abi))
+ as_bad (_("-mgp64 used with a 32-bit ABI"));
+ }
+ else
+ {
+ /* Infer the integer register size from the ABI and processor.
+ Restrict ourselves to 32-bit registers if that's all the
+ processor has, or if the ABI cannot handle 64-bit registers. */
+ file_mips_gp32 = (ABI_NEEDS_32BIT_REGS (mips_abi)
+ || !ISA_HAS_64BIT_REGS (mips_opts.isa));
+ }
+
+ /* ??? GAS treats single-float processors as though they had 64-bit
+ float registers (although it complains when double-precision
+ instructions are used). As things stand, saying they have 32-bit
+ registers would lead to spurious "register must be even" messages.
+ So here we assume float registers are always the same size as
+ integer ones, unless the user says otherwise. */
+ if (file_mips_fp32 < 0)
+ file_mips_fp32 = file_mips_gp32;
+
+ /* End of GCC-shared inference code. */
+
+ /* This flag is set when we have a 64-bit capable CPU but use only
+ 32-bit wide registers. Note that EABI does not use it. */
+ if (ISA_HAS_64BIT_REGS (mips_opts.isa)
+ && ((mips_abi == NO_ABI && file_mips_gp32 == 1)
+ || mips_abi == O32_ABI))
+ mips_32bitmode = 1;
+
+ if (mips_opts.isa == ISA_MIPS1 && mips_trap)
+ as_bad (_("trap exception not supported at ISA 1"));
+
+ /* If the selected architecture includes support for ASEs, enable
+ generation of code for them. */
+ if (mips_opts.mips16 == -1)
+ mips_opts.mips16 = (CPU_HAS_MIPS16 (file_mips_arch)) ? 1 : 0;
+ if (mips_opts.ase_mips3d == -1)
+ mips_opts.ase_mips3d = (CPU_HAS_MIPS3D (file_mips_arch)) ? 1 : 0;
+ if (mips_opts.ase_mdmx == -1)
+ mips_opts.ase_mdmx = (CPU_HAS_MDMX (file_mips_arch)) ? 1 : 0;
+
+ file_mips_isa = mips_opts.isa;
+ file_ase_mips16 = mips_opts.mips16;
+ file_ase_mips3d = mips_opts.ase_mips3d;
+ file_ase_mdmx = mips_opts.ase_mdmx;
+ mips_opts.gp32 = file_mips_gp32;
+ mips_opts.fp32 = file_mips_fp32;
+
+ if (mips_flag_mdebug < 0)
+ {
+#ifdef OBJ_MAYBE_ECOFF
+ if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour)
+ mips_flag_mdebug = 1;
+ else
+#endif /* OBJ_MAYBE_ECOFF */
+ mips_flag_mdebug = 0;
+ }
+}
+
+void
+mips_init_after_args (void)
+{
+ /* initialize opcodes */
+ bfd_mips_num_opcodes = bfd_mips_num_builtin_opcodes;
+ mips_opcodes = (struct mips_opcode *) mips_builtin_opcodes;
+}
+
+long
+md_pcrel_from (fixS *fixP)
+{
+ valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_16_PCREL_S2:
+ case BFD_RELOC_MIPS_JMP:
+ /* Return the address of the delay slot. */
+ return addr + 4;
+ default:
+ return addr;
+ }
+}
+
+/* This is called before the symbol table is processed. In order to
+ work with gcc when using mips-tfile, we must keep all local labels.
+ However, in other cases, we want to discard them. If we were
+ called with -g, but we didn't see any debugging information, it may
+ mean that gcc is smuggling debugging information through to
+ mips-tfile, in which case we must generate all local labels. */
+
+void
+mips_frob_file_before_adjust (void)
+{
+#ifndef NO_ECOFF_DEBUGGING
+ if (ECOFF_DEBUGGING
+ && mips_debug != 0
+ && ! ecoff_debugging_seen)
+ flag_keep_locals = 1;
+#endif
+}
+
+/* Sort any unmatched HI16_S relocs so that they immediately precede
+ the corresponding LO reloc. This is called before md_apply_fix3 and
+ tc_gen_reloc. Unmatched HI16_S relocs can only be generated by
+ explicit use of the %hi modifier. */
+
+void
+mips_frob_file (void)
+{
+ struct mips_hi_fixup *l;
+
+ for (l = mips_hi_fixup_list; l != NULL; l = l->next)
+ {
+ segment_info_type *seginfo;
+ int pass;
+
+ assert (reloc_needs_lo_p (l->fixp->fx_r_type));
+
+ /* If a GOT16 relocation turns out to be against a global symbol,
+ there isn't supposed to be a matching LO. */
+ if (l->fixp->fx_r_type == BFD_RELOC_MIPS_GOT16
+ && !pic_need_relax (l->fixp->fx_addsy, l->seg))
+ continue;
+
+ /* Check quickly whether the next fixup happens to be a matching %lo. */
+ if (fixup_has_matching_lo_p (l->fixp))
+ continue;
+
+ /* Look through the fixups for this segment for a matching %lo.
+ When we find one, move the %hi just in front of it. We do
+ this in two passes. In the first pass, we try to find a
+ unique %lo. In the second pass, we permit multiple %hi
+ relocs for a single %lo (this is a GNU extension). */
+ seginfo = seg_info (l->seg);
+ for (pass = 0; pass < 2; pass++)
+ {
+ fixS *f, *prev;
+
+ prev = NULL;
+ for (f = seginfo->fix_root; f != NULL; f = f->fx_next)
+ {
+ /* Check whether this is a %lo fixup which matches l->fixp. */
+ if (f->fx_r_type == BFD_RELOC_LO16
+ && f->fx_addsy == l->fixp->fx_addsy
+ && f->fx_offset == l->fixp->fx_offset
+ && (pass == 1
+ || prev == NULL
+ || !reloc_needs_lo_p (prev->fx_r_type)
+ || !fixup_has_matching_lo_p (prev)))
+ {
+ fixS **pf;
+
+ /* Move l->fixp before f. */
+ for (pf = &seginfo->fix_root;
+ *pf != l->fixp;
+ pf = &(*pf)->fx_next)
+ assert (*pf != NULL);
+
+ *pf = l->fixp->fx_next;
+
+ l->fixp->fx_next = f;
+ if (prev == NULL)
+ seginfo->fix_root = l->fixp;
+ else
+ prev->fx_next = l->fixp;
+
+ break;
+ }
+
+ prev = f;
+ }
+
+ if (f != NULL)
+ break;
+
+#if 0 /* GCC code motion plus incomplete dead code elimination
+ can leave a %hi without a %lo. */
+ if (pass == 1)
+ as_warn_where (l->fixp->fx_file, l->fixp->fx_line,
+ _("Unmatched %%hi reloc"));
+#endif
+ }
+ }
+}
+
+/* When generating embedded PIC code we need to use a special
+ relocation to represent the difference of two symbols in the .text
+ section (switch tables use a difference of this sort). See
+ include/coff/mips.h for details. This macro checks whether this
+ fixup requires the special reloc. */
+#define SWITCH_TABLE(fixp) \
+ ((fixp)->fx_r_type == BFD_RELOC_32 \
+ && OUTPUT_FLAVOR != bfd_target_elf_flavour \
+ && (fixp)->fx_addsy != NULL \
+ && (fixp)->fx_subsy != NULL \
+ && S_GET_SEGMENT ((fixp)->fx_addsy) == text_section \
+ && S_GET_SEGMENT ((fixp)->fx_subsy) == text_section)
+
+/* When generating embedded PIC code we must keep all PC relative
+ relocations, in case the linker has to relax a call. We also need
+ to keep relocations for switch table entries.
+
+ We may have combined relocations without symbols in the N32/N64 ABI.
+ We have to prevent gas from dropping them. */
+
+int
+mips_force_relocation (fixS *fixp)
+{
+ if (generic_force_reloc (fixp))
+ return 1;
+
+ if (HAVE_NEWABI
+ && S_GET_SEGMENT (fixp->fx_addsy) == bfd_abs_section_ptr
+ && (fixp->fx_r_type == BFD_RELOC_MIPS_SUB
+ || fixp->fx_r_type == BFD_RELOC_HI16_S
+ || fixp->fx_r_type == BFD_RELOC_LO16))
+ return 1;
+
+ return (mips_pic == EMBEDDED_PIC
+ && (fixp->fx_pcrel
+ || SWITCH_TABLE (fixp)
+ || fixp->fx_r_type == BFD_RELOC_PCREL_HI16_S
+ || fixp->fx_r_type == BFD_RELOC_PCREL_LO16));
+}
+
+/* This hook is called before a fix is simplified. We don't really
+ decide whether to skip a fix here. Rather, we turn global symbols
+ used as branch targets into local symbols, such that they undergo
+ simplification. We can only do this if the symbol is defined and
+ it is in the same section as the branch. If this doesn't hold, we
+ emit a better error message than just saying the relocation is not
+ valid for the selected object format.
+
+ FIXP is the fix-up we're going to try to simplify, SEG is the
+ segment in which the fix up occurs. The return value should be
+ non-zero to indicate the fix-up is valid for further
+ simplifications. */
+
+int
+mips_validate_fix (struct fix *fixP, asection *seg)
+{
+ /* There's a lot of discussion on whether it should be possible to
+ use R_MIPS_PC16 to represent branch relocations. The outcome
+ seems to be that it can, but gas/bfd are very broken in creating
+ RELA relocations for this, so for now we only accept branches to
+ symbols in the same section. Anything else is of dubious value,
+ since there's no guarantee that at link time the symbol would be
+ in range. Even for branches to local symbols this is arguably
+ wrong, since it we assume the symbol is not going to be
+ overridden, which should be possible per ELF library semantics,
+ but then, there isn't a dynamic relocation that could be used to
+ this effect, and the target would likely be out of range as well.
+
+ Unfortunately, it seems that there is too much code out there
+ that relies on branches to symbols that are global to be resolved
+ as if they were local, like the IRIX tools do, so we do it as
+ well, but with a warning so that people are reminded to fix their
+ code. If we ever get back to using R_MIPS_PC16 for branch
+ targets, this entire block should go away (and probably the
+ whole function). */
+
+ if (fixP->fx_r_type == BFD_RELOC_16_PCREL_S2
+ && (((OUTPUT_FLAVOR == bfd_target_ecoff_flavour
+ || OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ && mips_pic != EMBEDDED_PIC)
+ || bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16_PCREL_S2) == NULL)
+ && fixP->fx_addsy)
+ {
+ if (! S_IS_DEFINED (fixP->fx_addsy))
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Cannot branch to undefined symbol."));
+ /* Avoid any further errors about this fixup. */
+ fixP->fx_done = 1;
+ }
+ else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Cannot branch to symbol in another section."));
+ fixP->fx_done = 1;
+ }
+ else if (S_IS_EXTERNAL (fixP->fx_addsy))
+ {
+ symbolS *sym = fixP->fx_addsy;
+
+ if (mips_pic == SVR4_PIC)
+ as_warn_where (fixP->fx_file, fixP->fx_line,
+ _("Pretending global symbol used as branch target is local."));
+
+ fixP->fx_addsy = symbol_create (S_GET_NAME (sym),
+ S_GET_SEGMENT (sym),
+ S_GET_VALUE (sym),
+ symbol_get_frag (sym));
+ copy_symbol_attributes (fixP->fx_addsy, sym);
+ S_CLEAR_EXTERNAL (fixP->fx_addsy);
+ assert (symbol_resolved_p (sym));
+ symbol_mark_resolved (fixP->fx_addsy);
+ }
+ }
+
+ return 1;
+}
+
+/* Apply a fixup to the object file. */
+
+void
+md_apply_fix3 (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
+{
+ bfd_byte *buf;
+ long insn;
+ static int previous_fx_r_type = 0;
+ reloc_howto_type *howto;
+
+ /* We ignore generic BFD relocations we don't know about. */
+ howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
+ if (! howto)
+ return;
+
+ assert (fixP->fx_size == 4
+ || fixP->fx_r_type == BFD_RELOC_16
+ || fixP->fx_r_type == BFD_RELOC_64
+ || fixP->fx_r_type == BFD_RELOC_CTOR
+ || fixP->fx_r_type == BFD_RELOC_MIPS_SUB
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY);
+
+ buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where);
+
+ /* We are not done if this is a composite relocation to set up gp. */
+ if (fixP->fx_addsy == NULL && ! fixP->fx_pcrel
+ && !(fixP->fx_r_type == BFD_RELOC_MIPS_SUB
+ || (fixP->fx_r_type == BFD_RELOC_64
+ && (previous_fx_r_type == BFD_RELOC_GPREL32
+ || previous_fx_r_type == BFD_RELOC_GPREL16))
+ || (previous_fx_r_type == BFD_RELOC_MIPS_SUB
+ && (fixP->fx_r_type == BFD_RELOC_HI16_S
+ || fixP->fx_r_type == BFD_RELOC_LO16))))
+ fixP->fx_done = 1;
+ previous_fx_r_type = fixP->fx_r_type;
+
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_MIPS_JMP:
+ case BFD_RELOC_MIPS_SHIFT5:
+ case BFD_RELOC_MIPS_SHIFT6:
+ case BFD_RELOC_MIPS_GOT_DISP:
+ case BFD_RELOC_MIPS_GOT_PAGE:
+ case BFD_RELOC_MIPS_GOT_OFST:
+ case BFD_RELOC_MIPS_SUB:
+ case BFD_RELOC_MIPS_INSERT_A:
+ case BFD_RELOC_MIPS_INSERT_B:
+ case BFD_RELOC_MIPS_DELETE:
+ case BFD_RELOC_MIPS_HIGHEST:
+ case BFD_RELOC_MIPS_HIGHER:
+ case BFD_RELOC_MIPS_SCN_DISP:
+ case BFD_RELOC_MIPS_REL16:
+ case BFD_RELOC_MIPS_RELGOT:
+ case BFD_RELOC_MIPS_JALR:
+ case BFD_RELOC_HI16:
+ case BFD_RELOC_HI16_S:
+ case BFD_RELOC_GPREL16:
+ case BFD_RELOC_MIPS_LITERAL:
+ case BFD_RELOC_MIPS_CALL16:
+ case BFD_RELOC_MIPS_GOT16:
+ case BFD_RELOC_GPREL32:
+ case BFD_RELOC_MIPS_GOT_HI16:
+ case BFD_RELOC_MIPS_GOT_LO16:
+ case BFD_RELOC_MIPS_CALL_HI16:
+ case BFD_RELOC_MIPS_CALL_LO16:
+ case BFD_RELOC_MIPS16_GPREL:
+ if (fixP->fx_pcrel)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Invalid PC relative reloc"));
+ /* Nothing needed to do. The value comes from the reloc entry */
+ break;
+
+ case BFD_RELOC_MIPS16_JMP:
+ /* We currently always generate a reloc against a symbol, which
+ means that we don't want an addend even if the symbol is
+ defined. */
+ *valP = 0;
+ break;
+
+ case BFD_RELOC_PCREL_HI16_S:
+ /* The addend for this is tricky if it is internal, so we just
+ do everything here rather than in bfd_install_relocation. */
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour && !fixP->fx_done)
+ break;
+ if (fixP->fx_addsy
+ && (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_SECTION_SYM) == 0)
+ {
+ /* For an external symbol adjust by the address to make it
+ pcrel_offset. We use the address of the RELLO reloc
+ which follows this one. */
+ *valP += (fixP->fx_next->fx_frag->fr_address
+ + fixP->fx_next->fx_where);
+ }
+ *valP = ((*valP + 0x8000) >> 16) & 0xffff;
+ if (target_big_endian)
+ buf += 2;
+ md_number_to_chars (buf, *valP, 2);
+ break;
+
+ case BFD_RELOC_PCREL_LO16:
+ /* The addend for this is tricky if it is internal, so we just
+ do everything here rather than in bfd_install_relocation. */
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour && !fixP->fx_done)
+ break;
+ if (fixP->fx_addsy
+ && (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_SECTION_SYM) == 0)
+ *valP += fixP->fx_frag->fr_address + fixP->fx_where;
+ if (target_big_endian)
+ buf += 2;
+ md_number_to_chars (buf, *valP, 2);
+ break;
+
+ case BFD_RELOC_64:
+ /* This is handled like BFD_RELOC_32, but we output a sign
+ extended value if we are only 32 bits. */
+ if (fixP->fx_done
+ || (mips_pic == EMBEDDED_PIC && SWITCH_TABLE (fixP)))
+ {
+ if (8 <= sizeof (valueT))
+ md_number_to_chars (buf, *valP, 8);
+ else
+ {
+ valueT hiv;
+
+ if ((*valP & 0x80000000) != 0)
+ hiv = 0xffffffff;
+ else
+ hiv = 0;
+ md_number_to_chars ((char *)(buf + target_big_endian ? 4 : 0),
+ *valP, 4);
+ md_number_to_chars ((char *)(buf + target_big_endian ? 0 : 4),
+ hiv, 4);
+ }
+ }
+ break;
+
+ case BFD_RELOC_RVA:
+ case BFD_RELOC_32:
+ /* If we are deleting this reloc entry, we must fill in the
+ value now. This can happen if we have a .word which is not
+ resolved when it appears but is later defined. We also need
+ to fill in the value if this is an embedded PIC switch table
+ entry. */
+ if (fixP->fx_done
+ || (mips_pic == EMBEDDED_PIC && SWITCH_TABLE (fixP)))
+ md_number_to_chars (buf, *valP, 4);
+ break;
+
+ case BFD_RELOC_16:
+ /* If we are deleting this reloc entry, we must fill in the
+ value now. */
+ assert (fixP->fx_size == 2);
+ if (fixP->fx_done)
+ md_number_to_chars (buf, *valP, 2);
+ break;
+
+ case BFD_RELOC_LO16:
+ /* When handling an embedded PIC switch statement, we can wind
+ up deleting a LO16 reloc. See the 'o' case in mips_ip. */
+ if (fixP->fx_done)
+ {
+ if (*valP + 0x8000 > 0xffff)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ if (target_big_endian)
+ buf += 2;
+ md_number_to_chars (buf, *valP, 2);
+ }
+ break;
+
+ case BFD_RELOC_16_PCREL_S2:
+ if ((*valP & 0x3) != 0)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Branch to odd address (%lx)"), (long) *valP);
+
+ /*
+ * We need to save the bits in the instruction since fixup_segment()
+ * might be deleting the relocation entry (i.e., a branch within
+ * the current segment).
+ */
+ if (! fixP->fx_done)
+ break;
+
+ /* update old instruction data */
+ if (target_big_endian)
+ insn = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+ else
+ insn = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
+
+ if (*valP + 0x20000 <= 0x3ffff)
+ {
+ insn |= (*valP >> 2) & 0xffff;
+ md_number_to_chars (buf, insn, 4);
+ }
+ else if (mips_pic == NO_PIC
+ && fixP->fx_done
+ && fixP->fx_frag->fr_address >= text_section->vma
+ && (fixP->fx_frag->fr_address
+ < text_section->vma + text_section->_raw_size)
+ && ((insn & 0xffff0000) == 0x10000000 /* beq $0,$0 */
+ || (insn & 0xffff0000) == 0x04010000 /* bgez $0 */
+ || (insn & 0xffff0000) == 0x04110000)) /* bgezal $0 */
+ {
+ /* The branch offset is too large. If this is an
+ unconditional branch, and we are not generating PIC code,
+ we can convert it to an absolute jump instruction. */
+ if ((insn & 0xffff0000) == 0x04110000) /* bgezal $0 */
+ insn = 0x0c000000; /* jal */
+ else
+ insn = 0x08000000; /* j */
+ fixP->fx_r_type = BFD_RELOC_MIPS_JMP;
+ fixP->fx_done = 0;
+ fixP->fx_addsy = section_symbol (text_section);
+ *valP += md_pcrel_from (fixP);
+ md_number_to_chars (buf, insn, 4);
+ }
+ else
+ {
+ /* If we got here, we have branch-relaxation disabled,
+ and there's nothing we can do to fix this instruction
+ without turning it into a longer sequence. */
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Branch out of range"));
+ }
+ break;
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ fixP->fx_done = 0;
+ if (fixP->fx_addsy
+ && !S_IS_DEFINED (fixP->fx_addsy)
+ && !S_IS_WEAK (fixP->fx_addsy))
+ S_SET_WEAK (fixP->fx_addsy);
+ break;
+
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixP->fx_done = 0;
+ break;
+
+ default:
+ internalError ();
+ }
+
+ /* Remember value for tc_gen_reloc. */
+ fixP->fx_addnumber = *valP;
+}
+
+#if 0
+void
+printInsn (unsigned long oc)
+{
+ const struct mips_opcode *p;
+ int treg, sreg, dreg, shamt;
+ short imm;
+ const char *args;
+ int i;
+
+ for (i = 0; i < NUMOPCODES; ++i)
+ {
+ p = &mips_opcodes[i];
+ if (((oc & p->mask) == p->match) && (p->pinfo != INSN_MACRO))
+ {
+ printf ("%08lx %s\t", oc, p->name);
+ treg = (oc >> 16) & 0x1f;
+ sreg = (oc >> 21) & 0x1f;
+ dreg = (oc >> 11) & 0x1f;
+ shamt = (oc >> 6) & 0x1f;
+ imm = oc;
+ for (args = p->args;; ++args)
+ {
+ switch (*args)
+ {
+ case '\0':
+ printf ("\n");
+ break;
+
+ case ',':
+ case '(':
+ case ')':
+ printf ("%c", *args);
+ continue;
+
+ case 'r':
+ assert (treg == sreg);
+ printf ("$%d,$%d", treg, sreg);
+ continue;
+
+ case 'd':
+ case 'G':
+ printf ("$%d", dreg);
+ continue;
+
+ case 't':
+ case 'E':
+ printf ("$%d", treg);
+ continue;
+
+ case 'k':
+ printf ("0x%x", treg);
+ continue;
+
+ case 'b':
+ case 's':
+ printf ("$%d", sreg);
+ continue;
+
+ case 'a':
+ printf ("0x%08lx", oc & 0x1ffffff);
+ continue;
+
+ case 'i':
+ case 'j':
+ case 'o':
+ case 'u':
+ printf ("%d", imm);
+ continue;
+
+ case '<':
+ case '>':
+ printf ("$%d", shamt);
+ continue;
+
+ default:
+ internalError ();
+ }
+ break;
+ }
+ return;
+ }
+ }
+ printf (_("%08lx UNDEFINED\n"), oc);
+}
+#endif
+
+static symbolS *
+get_symbol (void)
+{
+ int c;
+ char *name;
+ symbolS *p;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ p = (symbolS *) symbol_find_or_make (name);
+ *input_line_pointer = c;
+ return p;
+}
+
+/* Align the current frag to a given power of two. The MIPS assembler
+ also automatically adjusts any preceding label. */
+
+static void
+mips_align (int to, int fill, symbolS *label)
+{
+ mips_emit_delays (FALSE);
+ frag_align (to, fill, 0);
+ record_alignment (now_seg, to);
+ if (label != NULL)
+ {
+ assert (S_GET_SEGMENT (label) == now_seg);
+ symbol_set_frag (label, frag_now);
+ S_SET_VALUE (label, (valueT) frag_now_fix ());
+ }
+}
+
+/* Align to a given power of two. .align 0 turns off the automatic
+ alignment used by the data creating pseudo-ops. */
+
+static void
+s_align (int x ATTRIBUTE_UNUSED)
+{
+ register int temp;
+ register long temp_fill;
+ long max_alignment = 15;
+
+ /*
+
+ o Note that the assembler pulls down any immediately preceding label
+ to the aligned address.
+ o It's not documented but auto alignment is reinstated by
+ a .align pseudo instruction.
+ o Note also that after auto alignment is turned off the mips assembler
+ issues an error on attempt to assemble an improperly aligned data item.
+ We don't.
+
+ */
+
+ temp = get_absolute_expression ();
+ if (temp > max_alignment)
+ as_bad (_("Alignment too large: %d. assumed."), temp = max_alignment);
+ else if (temp < 0)
+ {
+ as_warn (_("Alignment negative: 0 assumed."));
+ temp = 0;
+ }
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ temp_fill = get_absolute_expression ();
+ }
+ else
+ temp_fill = 0;
+ if (temp)
+ {
+ auto_align = 1;
+ mips_align (temp, (int) temp_fill,
+ insn_labels != NULL ? insn_labels->label : NULL);
+ }
+ else
+ {
+ auto_align = 0;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+void
+mips_flush_pending_output (void)
+{
+ mips_emit_delays (FALSE);
+ mips_clear_insn_labels ();
+}
+
+static void
+s_change_sec (int sec)
+{
+ segT seg;
+
+ /* When generating embedded PIC code, we only use the .text, .lit8,
+ .sdata and .sbss sections. We change the .data and .rdata
+ pseudo-ops to use .sdata. */
+ if (mips_pic == EMBEDDED_PIC
+ && (sec == 'd' || sec == 'r'))
+ sec = 's';
+
+#ifdef OBJ_ELF
+ /* The ELF backend needs to know that we are changing sections, so
+ that .previous works correctly. We could do something like check
+ for an obj_section_change_hook macro, but that might be confusing
+ as it would not be appropriate to use it in the section changing
+ functions in read.c, since obj-elf.c intercepts those. FIXME:
+ This should be cleaner, somehow. */
+ obj_elf_section_change_hook ();
+#endif
+
+ mips_emit_delays (FALSE);
+ switch (sec)
+ {
+ case 't':
+ s_text (0);
+ break;
+ case 'd':
+ s_data (0);
+ break;
+ case 'b':
+ subseg_set (bss_section, (subsegT) get_absolute_expression ());
+ demand_empty_rest_of_line ();
+ break;
+
+ case 'r':
+ if (USE_GLOBAL_POINTER_OPT)
+ {
+ seg = subseg_new (RDATA_SECTION_NAME,
+ (subsegT) get_absolute_expression ());
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ {
+ bfd_set_section_flags (stdoutput, seg,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_READONLY
+ | SEC_RELOC
+ | SEC_DATA));
+ if (strcmp (TARGET_OS, "elf") != 0)
+ record_alignment (seg, 4);
+ }
+ demand_empty_rest_of_line ();
+ }
+ else
+ {
+ as_bad (_("No read only data section in this object file format"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+ break;
+
+ case 's':
+ if (USE_GLOBAL_POINTER_OPT)
+ {
+ seg = subseg_new (".sdata", (subsegT) get_absolute_expression ());
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ {
+ bfd_set_section_flags (stdoutput, seg,
+ SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_DATA);
+ if (strcmp (TARGET_OS, "elf") != 0)
+ record_alignment (seg, 4);
+ }
+ demand_empty_rest_of_line ();
+ break;
+ }
+ else
+ {
+ as_bad (_("Global pointers not supported; recompile -G 0"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+ }
+
+ auto_align = 1;
+}
+
+void
+s_change_section (int ignore ATTRIBUTE_UNUSED)
+{
+#ifdef OBJ_ELF
+ char *section_name;
+ char c;
+ char next_c = 0;
+ int section_type;
+ int section_flag;
+ int section_entry_size;
+ int section_alignment;
+
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+ return;
+
+ section_name = input_line_pointer;
+ c = get_symbol_end ();
+ if (c)
+ next_c = *(input_line_pointer + 1);
+
+ /* Do we have .section Name<,"flags">? */
+ if (c != ',' || (c == ',' && next_c == '"'))
+ {
+ /* just after name is now '\0'. */
+ *input_line_pointer = c;
+ input_line_pointer = section_name;
+ obj_elf_section (ignore);
+ return;
+ }
+ input_line_pointer++;
+
+ /* Do we have .section Name<,type><,flag><,entry_size><,alignment> */
+ if (c == ',')
+ section_type = get_absolute_expression ();
+ else
+ section_type = 0;
+ if (*input_line_pointer++ == ',')
+ section_flag = get_absolute_expression ();
+ else
+ section_flag = 0;
+ if (*input_line_pointer++ == ',')
+ section_entry_size = get_absolute_expression ();
+ else
+ section_entry_size = 0;
+ if (*input_line_pointer++ == ',')
+ section_alignment = get_absolute_expression ();
+ else
+ section_alignment = 0;
+
+ section_name = xstrdup (section_name);
+
+ /* When using the generic form of .section (as implemented by obj-elf.c),
+ there's no way to set the section type to SHT_MIPS_DWARF. Users have
+ traditionally had to fall back on the more common @progbits instead.
+
+ There's nothing really harmful in this, since bfd will correct
+ SHT_PROGBITS to SHT_MIPS_DWARF before writing out the file. But it
+ means that, for backwards compatibiltiy, the special_section entries
+ for dwarf sections must use SHT_PROGBITS rather than SHT_MIPS_DWARF.
+
+ Even so, we shouldn't force users of the MIPS .section syntax to
+ incorrectly label the sections as SHT_PROGBITS. The best compromise
+ seems to be to map SHT_MIPS_DWARF to SHT_PROGBITS before calling the
+ generic type-checking code. */
+ if (section_type == SHT_MIPS_DWARF)
+ section_type = SHT_PROGBITS;
+
+ obj_elf_change_section (section_name, section_type, section_flag,
+ section_entry_size, 0, 0, 0);
+
+ if (now_seg->name != section_name)
+ free (section_name);
+#endif /* OBJ_ELF */
+}
+
+void
+mips_enable_auto_align (void)
+{
+ auto_align = 1;
+}
+
+static void
+s_cons (int log_size)
+{
+ symbolS *label;
+
+ label = insn_labels != NULL ? insn_labels->label : NULL;
+ mips_emit_delays (FALSE);
+ if (log_size > 0 && auto_align)
+ mips_align (log_size, 0, label);
+ mips_clear_insn_labels ();
+ cons (1 << log_size);
+}
+
+static void
+s_float_cons (int type)
+{
+ symbolS *label;
+
+ label = insn_labels != NULL ? insn_labels->label : NULL;
+
+ mips_emit_delays (FALSE);
+
+ if (auto_align)
+ {
+ if (type == 'd')
+ mips_align (3, 0, label);
+ else
+ mips_align (2, 0, label);
+ }
+
+ mips_clear_insn_labels ();
+
+ float_cons (type);
+}
+
+/* Handle .globl. We need to override it because on Irix 5 you are
+ permitted to say
+ .globl foo .text
+ where foo is an undefined symbol, to mean that foo should be
+ considered to be the address of a function. */
+
+static void
+s_mips_globl (int x ATTRIBUTE_UNUSED)
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+ flagword flag;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+
+ /* On Irix 5, every global symbol that is not explicitly labelled as
+ being a function is apparently labelled as being an object. */
+ flag = BSF_OBJECT;
+
+ if (! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ char *secname;
+ asection *sec;
+
+ secname = input_line_pointer;
+ c = get_symbol_end ();
+ sec = bfd_get_section_by_name (stdoutput, secname);
+ if (sec == NULL)
+ as_bad (_("%s: no such section"), secname);
+ *input_line_pointer = c;
+
+ if (sec != NULL && (sec->flags & SEC_CODE) != 0)
+ flag = BSF_FUNCTION;
+ }
+
+ symbol_get_bfdsym (symbolP)->flags |= flag;
+
+ S_SET_EXTERNAL (symbolP);
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_option (int x ATTRIBUTE_UNUSED)
+{
+ char *opt;
+ char c;
+
+ opt = input_line_pointer;
+ c = get_symbol_end ();
+
+ if (*opt == 'O')
+ {
+ /* FIXME: What does this mean? */
+ }
+ else if (strncmp (opt, "pic", 3) == 0)
+ {
+ int i;
+
+ i = atoi (opt + 3);
+ if (i == 0)
+ mips_pic = NO_PIC;
+ else if (i == 2)
+ {
+ mips_pic = SVR4_PIC;
+ mips_abicalls = TRUE;
+ }
+ else
+ as_bad (_(".option pic%d not supported"), i);
+
+ if (USE_GLOBAL_POINTER_OPT && mips_pic == SVR4_PIC)
+ {
+ if (g_switch_seen && g_switch_value != 0)
+ as_warn (_("-G may not be used with SVR4 PIC code"));
+ g_switch_value = 0;
+ bfd_set_gp_size (stdoutput, 0);
+ }
+ }
+ else
+ as_warn (_("Unrecognized option \"%s\""), opt);
+
+ *input_line_pointer = c;
+ demand_empty_rest_of_line ();
+}
+
+/* This structure is used to hold a stack of .set values. */
+
+struct mips_option_stack
+{
+ struct mips_option_stack *next;
+ struct mips_set_options options;
+};
+
+static struct mips_option_stack *mips_opts_stack;
+
+/* Handle the .set pseudo-op. */
+
+static void
+s_mipsset (int x ATTRIBUTE_UNUSED)
+{
+ char *name = input_line_pointer, ch;
+
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ ch = *input_line_pointer;
+ *input_line_pointer = '\0';
+
+ if (strcmp (name, "reorder") == 0)
+ {
+ if (mips_opts.noreorder && prev_nop_frag != NULL)
+ {
+ /* If we still have pending nops, we can discard them. The
+ usual nop handling will insert any that are still
+ needed. */
+ prev_nop_frag->fr_fix -= (prev_nop_frag_holds
+ * (mips_opts.mips16 ? 2 : 4));
+ prev_nop_frag = NULL;
+ }
+ mips_opts.noreorder = 0;
+ }
+ else if (strcmp (name, "noreorder") == 0)
+ {
+ mips_emit_delays (TRUE);
+ mips_opts.noreorder = 1;
+ mips_any_noreorder = 1;
+ }
+ else if (strcmp (name, "at") == 0)
+ {
+ mips_opts.noat = 0;
+ }
+ else if (strcmp (name, "noat") == 0)
+ {
+ mips_opts.noat = 1;
+ }
+ else if (strcmp (name, "macro") == 0)
+ {
+ mips_opts.warn_about_macros = 0;
+ }
+ else if (strcmp (name, "nomacro") == 0)
+ {
+ if (mips_opts.noreorder == 0)
+ as_bad (_("`noreorder' must be set before `nomacro'"));
+ mips_opts.warn_about_macros = 1;
+ }
+ else if (strcmp (name, "move") == 0 || strcmp (name, "novolatile") == 0)
+ {
+ mips_opts.nomove = 0;
+ }
+ else if (strcmp (name, "nomove") == 0 || strcmp (name, "volatile") == 0)
+ {
+ mips_opts.nomove = 1;
+ }
+ else if (strcmp (name, "bopt") == 0)
+ {
+ mips_opts.nobopt = 0;
+ }
+ else if (strcmp (name, "nobopt") == 0)
+ {
+ mips_opts.nobopt = 1;
+ }
+ else if (strcmp (name, "mips16") == 0
+ || strcmp (name, "MIPS-16") == 0)
+ mips_opts.mips16 = 1;
+ else if (strcmp (name, "nomips16") == 0
+ || strcmp (name, "noMIPS-16") == 0)
+ mips_opts.mips16 = 0;
+ else if (strcmp (name, "mips3d") == 0)
+ mips_opts.ase_mips3d = 1;
+ else if (strcmp (name, "nomips3d") == 0)
+ mips_opts.ase_mips3d = 0;
+ else if (strcmp (name, "mdmx") == 0)
+ mips_opts.ase_mdmx = 1;
+ else if (strcmp (name, "nomdmx") == 0)
+ mips_opts.ase_mdmx = 0;
+ else if (strncmp (name, "mips", 4) == 0 || strncmp (name, "arch=", 5) == 0)
+ {
+ int reset = 0;
+
+ /* Permit the user to change the ISA and architecture on the fly.
+ Needless to say, misuse can cause serious problems. */
+ if (strcmp (name, "mips0") == 0)
+ {
+ reset = 1;
+ mips_opts.isa = file_mips_isa;
+ }
+ else if (strcmp (name, "mips1") == 0)
+ mips_opts.isa = ISA_MIPS1;
+ else if (strcmp (name, "mips2") == 0)
+ mips_opts.isa = ISA_MIPS2;
+ else if (strcmp (name, "mips3") == 0)
+ mips_opts.isa = ISA_MIPS3;
+ else if (strcmp (name, "mips4") == 0)
+ mips_opts.isa = ISA_MIPS4;
+ else if (strcmp (name, "mips5") == 0)
+ mips_opts.isa = ISA_MIPS5;
+ else if (strcmp (name, "mips32") == 0)
+ mips_opts.isa = ISA_MIPS32;
+ else if (strcmp (name, "mips32r2") == 0)
+ mips_opts.isa = ISA_MIPS32R2;
+ else if (strcmp (name, "mips64") == 0)
+ mips_opts.isa = ISA_MIPS64;
+ else if (strcmp (name, "mips64r2") == 0)
+ mips_opts.isa = ISA_MIPS64R2;
+ else if (strcmp (name, "arch=default") == 0)
+ {
+ reset = 1;
+ mips_opts.arch = file_mips_arch;
+ mips_opts.isa = file_mips_isa;
+ }
+ else if (strncmp (name, "arch=", 5) == 0)
+ {
+ const struct mips_cpu_info *p;
+
+ p = mips_parse_cpu("internal use", name + 5);
+ if (!p)
+ as_bad (_("unknown architecture %s"), name + 5);
+ else
+ {
+ mips_opts.arch = p->cpu;
+ mips_opts.isa = p->isa;
+ }
+ }
+ else
+ as_bad (_("unknown ISA level %s"), name + 4);
+
+ switch (mips_opts.isa)
+ {
+ case 0:
+ break;
+ case ISA_MIPS1:
+ case ISA_MIPS2:
+ case ISA_MIPS32:
+ case ISA_MIPS32R2:
+ mips_opts.gp32 = 1;
+ mips_opts.fp32 = 1;
+ break;
+ case ISA_MIPS3:
+ case ISA_MIPS4:
+ case ISA_MIPS5:
+ case ISA_MIPS64:
+ case ISA_MIPS64R2:
+ mips_opts.gp32 = 0;
+ mips_opts.fp32 = 0;
+ break;
+ default:
+ as_bad (_("unknown ISA level %s"), name + 4);
+ break;
+ }
+ if (reset)
+ {
+ mips_opts.gp32 = file_mips_gp32;
+ mips_opts.fp32 = file_mips_fp32;
+ }
+ }
+ else if (strcmp (name, "autoextend") == 0)
+ mips_opts.noautoextend = 0;
+ else if (strcmp (name, "noautoextend") == 0)
+ mips_opts.noautoextend = 1;
+ else if (strcmp (name, "push") == 0)
+ {
+ struct mips_option_stack *s;
+
+ s = (struct mips_option_stack *) xmalloc (sizeof *s);
+ s->next = mips_opts_stack;
+ s->options = mips_opts;
+ mips_opts_stack = s;
+ }
+ else if (strcmp (name, "pop") == 0)
+ {
+ struct mips_option_stack *s;
+
+ s = mips_opts_stack;
+ if (s == NULL)
+ as_bad (_(".set pop with no .set push"));
+ else
+ {
+ /* If we're changing the reorder mode we need to handle
+ delay slots correctly. */
+ if (s->options.noreorder && ! mips_opts.noreorder)
+ mips_emit_delays (TRUE);
+ else if (! s->options.noreorder && mips_opts.noreorder)
+ {
+ if (prev_nop_frag != NULL)
+ {
+ prev_nop_frag->fr_fix -= (prev_nop_frag_holds
+ * (mips_opts.mips16 ? 2 : 4));
+ prev_nop_frag = NULL;
+ }
+ }
+
+ mips_opts = s->options;
+ mips_opts_stack = s->next;
+ free (s);
+ }
+ }
+ else
+ {
+ as_warn (_("Tried to set unrecognized symbol: %s\n"), name);
+ }
+ *input_line_pointer = ch;
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .abicalls pseudo-op. I believe this is equivalent to
+ .option pic2. It means to generate SVR4 PIC calls. */
+
+static void
+s_abicalls (int ignore ATTRIBUTE_UNUSED)
+{
+ mips_pic = SVR4_PIC;
+ mips_abicalls = TRUE;
+ if (USE_GLOBAL_POINTER_OPT)
+ {
+ if (g_switch_seen && g_switch_value != 0)
+ as_warn (_("-G may not be used with SVR4 PIC code"));
+ g_switch_value = 0;
+ }
+ bfd_set_gp_size (stdoutput, 0);
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .cpload pseudo-op. This is used when generating SVR4
+ PIC code. It sets the $gp register for the function based on the
+ function address, which is in the register named in the argument.
+ This uses a relocation against _gp_disp, which is handled specially
+ by the linker. The result is:
+ lui $gp,%hi(_gp_disp)
+ addiu $gp,$gp,%lo(_gp_disp)
+ addu $gp,$gp,.cpload argument
+ The .cpload argument is normally $25 == $t9. */
+
+static void
+s_cpload (int ignore ATTRIBUTE_UNUSED)
+{
+ expressionS ex;
+
+ /* If we are not generating SVR4 PIC code, or if this is NewABI code,
+ .cpload is ignored. */
+ if (mips_pic != SVR4_PIC || HAVE_NEWABI)
+ {
+ s_ignore (0);
+ return;
+ }
+
+ /* .cpload should be in a .set noreorder section. */
+ if (mips_opts.noreorder == 0)
+ as_warn (_(".cpload not in noreorder section"));
+
+ ex.X_op = O_symbol;
+ ex.X_add_symbol = symbol_find_or_make ("_gp_disp");
+ ex.X_op_symbol = NULL;
+ ex.X_add_number = 0;
+
+ /* In ELF, this symbol is implicitly an STT_OBJECT symbol. */
+ symbol_get_bfdsym (ex.X_add_symbol)->flags |= BSF_OBJECT;
+
+ macro_start ();
+ macro_build_lui (&ex, mips_gp_register);
+ macro_build (&ex, "addiu", "t,r,j", mips_gp_register,
+ mips_gp_register, BFD_RELOC_LO16);
+ macro_build (NULL, "addu", "d,v,t", mips_gp_register,
+ mips_gp_register, tc_get_register (0));
+ macro_end ();
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .cpsetup pseudo-op defined for NewABI PIC code. The syntax is:
+ .cpsetup $reg1, offset|$reg2, label
+
+ If offset is given, this results in:
+ sd $gp, offset($sp)
+ lui $gp, %hi(%neg(%gp_rel(label)))
+ addiu $gp, $gp, %lo(%neg(%gp_rel(label)))
+ daddu $gp, $gp, $reg1
+
+ If $reg2 is given, this results in:
+ daddu $reg2, $gp, $0
+ lui $gp, %hi(%neg(%gp_rel(label)))
+ addiu $gp, $gp, %lo(%neg(%gp_rel(label)))
+ daddu $gp, $gp, $reg1
+ $reg1 is normally $25 == $t9. */
+static void
+s_cpsetup (int ignore ATTRIBUTE_UNUSED)
+{
+ expressionS ex_off;
+ expressionS ex_sym;
+ int reg1;
+ char *f;
+
+ /* If we are not generating SVR4 PIC code, .cpsetup is ignored.
+ We also need NewABI support. */
+ if (mips_pic != SVR4_PIC || ! HAVE_NEWABI)
+ {
+ s_ignore (0);
+ return;
+ }
+
+ reg1 = tc_get_register (0);
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing argument separator ',' for .cpsetup"));
+ return;
+ }
+ else
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '$')
+ {
+ mips_cpreturn_register = tc_get_register (0);
+ mips_cpreturn_offset = -1;
+ }
+ else
+ {
+ mips_cpreturn_offset = get_absolute_expression ();
+ mips_cpreturn_register = -1;
+ }
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing argument separator ',' for .cpsetup"));
+ return;
+ }
+ else
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ expression (&ex_sym);
+
+ macro_start ();
+ if (mips_cpreturn_register == -1)
+ {
+ ex_off.X_op = O_constant;
+ ex_off.X_add_symbol = NULL;
+ ex_off.X_op_symbol = NULL;
+ ex_off.X_add_number = mips_cpreturn_offset;
+
+ macro_build (&ex_off, "sd", "t,o(b)", mips_gp_register,
+ BFD_RELOC_LO16, SP);
+ }
+ else
+ macro_build (NULL, "daddu", "d,v,t", mips_cpreturn_register,
+ mips_gp_register, 0);
+
+ /* Ensure there's room for the next two instructions, so that `f'
+ doesn't end up with an address in the wrong frag. */
+ frag_grow (8);
+ f = frag_more (0);
+ macro_build (&ex_sym, "lui", "t,u", mips_gp_register, BFD_RELOC_GPREL16);
+ fix_new (frag_now, f - frag_now->fr_literal,
+ 8, NULL, 0, 0, BFD_RELOC_MIPS_SUB);
+ fix_new (frag_now, f - frag_now->fr_literal,
+ 4, NULL, 0, 0, BFD_RELOC_HI16_S);
+
+ f = frag_more (0);
+ macro_build (&ex_sym, "addiu", "t,r,j", mips_gp_register,
+ mips_gp_register, BFD_RELOC_GPREL16);
+ fix_new (frag_now, f - frag_now->fr_literal,
+ 8, NULL, 0, 0, BFD_RELOC_MIPS_SUB);
+ fix_new (frag_now, f - frag_now->fr_literal,
+ 4, NULL, 0, 0, BFD_RELOC_LO16);
+
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", mips_gp_register,
+ mips_gp_register, reg1);
+ macro_end ();
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_cplocal (int ignore ATTRIBUTE_UNUSED)
+{
+ /* If we are not generating SVR4 PIC code, or if this is not NewABI code,
+ .cplocal is ignored. */
+ if (mips_pic != SVR4_PIC || ! HAVE_NEWABI)
+ {
+ s_ignore (0);
+ return;
+ }
+
+ mips_gp_register = tc_get_register (0);
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .cprestore pseudo-op. This stores $gp into a given
+ offset from $sp. The offset is remembered, and after making a PIC
+ call $gp is restored from that location. */
+
+static void
+s_cprestore (int ignore ATTRIBUTE_UNUSED)
+{
+ expressionS ex;
+
+ /* If we are not generating SVR4 PIC code, or if this is NewABI code,
+ .cprestore is ignored. */
+ if (mips_pic != SVR4_PIC || HAVE_NEWABI)
+ {
+ s_ignore (0);
+ return;
+ }
+
+ mips_cprestore_offset = get_absolute_expression ();
+ mips_cprestore_valid = 1;
+
+ ex.X_op = O_constant;
+ ex.X_add_symbol = NULL;
+ ex.X_op_symbol = NULL;
+ ex.X_add_number = mips_cprestore_offset;
+
+ macro_start ();
+ macro_build_ldst_constoffset (&ex, ADDRESS_STORE_INSN, mips_gp_register,
+ SP, HAVE_64BIT_ADDRESSES);
+ macro_end ();
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .cpreturn pseudo-op defined for NewABI PIC code. If an offset
+ was given in the preceding .cpsetup, it results in:
+ ld $gp, offset($sp)
+
+ If a register $reg2 was given there, it results in:
+ daddu $gp, $reg2, $0
+ */
+static void
+s_cpreturn (int ignore ATTRIBUTE_UNUSED)
+{
+ expressionS ex;
+
+ /* If we are not generating SVR4 PIC code, .cpreturn is ignored.
+ We also need NewABI support. */
+ if (mips_pic != SVR4_PIC || ! HAVE_NEWABI)
+ {
+ s_ignore (0);
+ return;
+ }
+
+ macro_start ();
+ if (mips_cpreturn_register == -1)
+ {
+ ex.X_op = O_constant;
+ ex.X_add_symbol = NULL;
+ ex.X_op_symbol = NULL;
+ ex.X_add_number = mips_cpreturn_offset;
+
+ macro_build (&ex, "ld", "t,o(b)", mips_gp_register, BFD_RELOC_LO16, SP);
+ }
+ else
+ macro_build (NULL, "daddu", "d,v,t", mips_gp_register,
+ mips_cpreturn_register, 0);
+ macro_end ();
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .gpvalue pseudo-op. This is used when generating NewABI PIC
+ code. It sets the offset to use in gp_rel relocations. */
+
+static void
+s_gpvalue (int ignore ATTRIBUTE_UNUSED)
+{
+ /* If we are not generating SVR4 PIC code, .gpvalue is ignored.
+ We also need NewABI support. */
+ if (mips_pic != SVR4_PIC || ! HAVE_NEWABI)
+ {
+ s_ignore (0);
+ return;
+ }
+
+ mips_gprel_offset = get_absolute_expression ();
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .gpword pseudo-op. This is used when generating PIC
+ code. It generates a 32 bit GP relative reloc. */
+
+static void
+s_gpword (int ignore ATTRIBUTE_UNUSED)
+{
+ symbolS *label;
+ expressionS ex;
+ char *p;
+
+ /* When not generating PIC code, this is treated as .word. */
+ if (mips_pic != SVR4_PIC)
+ {
+ s_cons (2);
+ return;
+ }
+
+ label = insn_labels != NULL ? insn_labels->label : NULL;
+ mips_emit_delays (TRUE);
+ if (auto_align)
+ mips_align (2, 0, label);
+ mips_clear_insn_labels ();
+
+ expression (&ex);
+
+ if (ex.X_op != O_symbol || ex.X_add_number != 0)
+ {
+ as_bad (_("Unsupported use of .gpword"));
+ ignore_rest_of_line ();
+ }
+
+ p = frag_more (4);
+ md_number_to_chars (p, 0, 4);
+ fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &ex, FALSE,
+ BFD_RELOC_GPREL32);
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_gpdword (int ignore ATTRIBUTE_UNUSED)
+{
+ symbolS *label;
+ expressionS ex;
+ char *p;
+
+ /* When not generating PIC code, this is treated as .dword. */
+ if (mips_pic != SVR4_PIC)
+ {
+ s_cons (3);
+ return;
+ }
+
+ label = insn_labels != NULL ? insn_labels->label : NULL;
+ mips_emit_delays (TRUE);
+ if (auto_align)
+ mips_align (3, 0, label);
+ mips_clear_insn_labels ();
+
+ expression (&ex);
+
+ if (ex.X_op != O_symbol || ex.X_add_number != 0)
+ {
+ as_bad (_("Unsupported use of .gpdword"));
+ ignore_rest_of_line ();
+ }
+
+ p = frag_more (8);
+ md_number_to_chars (p, 0, 8);
+ fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &ex, FALSE,
+ BFD_RELOC_GPREL32);
+
+ /* GPREL32 composed with 64 gives a 64-bit GP offset. */
+ ex.X_op = O_absent;
+ ex.X_add_symbol = 0;
+ ex.X_add_number = 0;
+ fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &ex, FALSE,
+ BFD_RELOC_64);
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .cpadd pseudo-op. This is used when dealing with switch
+ tables in SVR4 PIC code. */
+
+static void
+s_cpadd (int ignore ATTRIBUTE_UNUSED)
+{
+ int reg;
+
+ /* This is ignored when not generating SVR4 PIC code. */
+ if (mips_pic != SVR4_PIC)
+ {
+ s_ignore (0);
+ return;
+ }
+
+ /* Add $gp to the register named as an argument. */
+ macro_start ();
+ reg = tc_get_register (0);
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", reg, reg, mips_gp_register);
+ macro_end ();
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .insn pseudo-op. This marks instruction labels in
+ mips16 mode. This permits the linker to handle them specially,
+ such as generating jalx instructions when needed. We also make
+ them odd for the duration of the assembly, in order to generate the
+ right sort of code. We will make them even in the adjust_symtab
+ routine, while leaving them marked. This is convenient for the
+ debugger and the disassembler. The linker knows to make them odd
+ again. */
+
+static void
+s_insn (int ignore ATTRIBUTE_UNUSED)
+{
+ mips16_mark_labels ();
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .stabn directive. We need these in order to mark a label
+ as being a mips16 text label correctly. Sometimes the compiler
+ will emit a label, followed by a .stabn, and then switch sections.
+ If the label and .stabn are in mips16 mode, then the label is
+ really a mips16 text label. */
+
+static void
+s_mips_stab (int type)
+{
+ if (type == 'n')
+ mips16_mark_labels ();
+
+ s_stab (type);
+}
+
+/* Handle the .weakext pseudo-op as defined in Kane and Heinrich.
+ */
+
+static void
+s_mips_weakext (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+ expressionS exp;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ S_SET_WEAK (symbolP);
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+
+ if (! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ if (S_IS_DEFINED (symbolP))
+ {
+ as_bad ("ignoring attempt to redefine symbol %s",
+ S_GET_NAME (symbolP));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ }
+
+ expression (&exp);
+ if (exp.X_op != O_symbol)
+ {
+ as_bad ("bad .weakext directive");
+ ignore_rest_of_line ();
+ return;
+ }
+ symbol_set_value_expression (symbolP, &exp);
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Parse a register string into a number. Called from the ECOFF code
+ to parse .frame. The argument is non-zero if this is the frame
+ register, so that we can record it in mips_frame_reg. */
+
+int
+tc_get_register (int frame)
+{
+ int reg;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer++ != '$')
+ {
+ as_warn (_("expected `$'"));
+ reg = ZERO;
+ }
+ else if (ISDIGIT (*input_line_pointer))
+ {
+ reg = get_absolute_expression ();
+ if (reg < 0 || reg >= 32)
+ {
+ as_warn (_("Bad register number"));
+ reg = ZERO;
+ }
+ }
+ else
+ {
+ if (strncmp (input_line_pointer, "ra", 2) == 0)
+ {
+ reg = RA;
+ input_line_pointer += 2;
+ }
+ else if (strncmp (input_line_pointer, "fp", 2) == 0)
+ {
+ reg = FP;
+ input_line_pointer += 2;
+ }
+ else if (strncmp (input_line_pointer, "sp", 2) == 0)
+ {
+ reg = SP;
+ input_line_pointer += 2;
+ }
+ else if (strncmp (input_line_pointer, "gp", 2) == 0)
+ {
+ reg = GP;
+ input_line_pointer += 2;
+ }
+ else if (strncmp (input_line_pointer, "at", 2) == 0)
+ {
+ reg = AT;
+ input_line_pointer += 2;
+ }
+ else if (strncmp (input_line_pointer, "kt0", 3) == 0)
+ {
+ reg = KT0;
+ input_line_pointer += 3;
+ }
+ else if (strncmp (input_line_pointer, "kt1", 3) == 0)
+ {
+ reg = KT1;
+ input_line_pointer += 3;
+ }
+ else if (strncmp (input_line_pointer, "zero", 4) == 0)
+ {
+ reg = ZERO;
+ input_line_pointer += 4;
+ }
+ else
+ {
+ as_warn (_("Unrecognized register name"));
+ reg = ZERO;
+ while (ISALNUM(*input_line_pointer))
+ input_line_pointer++;
+ }
+ }
+ if (frame)
+ {
+ mips_frame_reg = reg != 0 ? reg : SP;
+ mips_frame_reg_valid = 1;
+ mips_cprestore_valid = 0;
+ }
+ return reg;
+}
+
+valueT
+md_section_align (asection *seg, valueT addr)
+{
+ int align = bfd_get_section_alignment (stdoutput, seg);
+
+#ifdef OBJ_ELF
+ /* We don't need to align ELF sections to the full alignment.
+ However, Irix 5 may prefer that we align them at least to a 16
+ byte boundary. We don't bother to align the sections if we are
+ targeted for an embedded system. */
+ if (strcmp (TARGET_OS, "elf") == 0)
+ return addr;
+ if (align > 4)
+ align = 4;
+#endif
+
+ return ((addr + (1 << align) - 1) & (-1 << align));
+}
+
+/* Utility routine, called from above as well. If called while the
+ input file is still being read, it's only an approximation. (For
+ example, a symbol may later become defined which appeared to be
+ undefined earlier.) */
+
+static int
+nopic_need_relax (symbolS *sym, int before_relaxing)
+{
+ if (sym == 0)
+ return 0;
+
+ if (USE_GLOBAL_POINTER_OPT && g_switch_value > 0)
+ {
+ const char *symname;
+ int change;
+
+ /* Find out whether this symbol can be referenced off the $gp
+ register. It can be if it is smaller than the -G size or if
+ it is in the .sdata or .sbss section. Certain symbols can
+ not be referenced off the $gp, although it appears as though
+ they can. */
+ symname = S_GET_NAME (sym);
+ if (symname != (const char *) NULL
+ && (strcmp (symname, "eprol") == 0
+ || strcmp (symname, "etext") == 0
+ || strcmp (symname, "_gp") == 0
+ || strcmp (symname, "edata") == 0
+ || strcmp (symname, "_fbss") == 0
+ || strcmp (symname, "_fdata") == 0
+ || strcmp (symname, "_ftext") == 0
+ || strcmp (symname, "end") == 0
+ || strcmp (symname, "_gp_disp") == 0))
+ change = 1;
+ else if ((! S_IS_DEFINED (sym) || S_IS_COMMON (sym))
+ && (0
+#ifndef NO_ECOFF_DEBUGGING
+ || (symbol_get_obj (sym)->ecoff_extern_size != 0
+ && (symbol_get_obj (sym)->ecoff_extern_size
+ <= g_switch_value))
+#endif
+ /* We must defer this decision until after the whole
+ file has been read, since there might be a .extern
+ after the first use of this symbol. */
+ || (before_relaxing
+#ifndef NO_ECOFF_DEBUGGING
+ && symbol_get_obj (sym)->ecoff_extern_size == 0
+#endif
+ && S_GET_VALUE (sym) == 0)
+ || (S_GET_VALUE (sym) != 0
+ && S_GET_VALUE (sym) <= g_switch_value)))
+ change = 0;
+ else
+ {
+ const char *segname;
+
+ segname = segment_name (S_GET_SEGMENT (sym));
+ assert (strcmp (segname, ".lit8") != 0
+ && strcmp (segname, ".lit4") != 0);
+ change = (strcmp (segname, ".sdata") != 0
+ && strcmp (segname, ".sbss") != 0
+ && strncmp (segname, ".sdata.", 7) != 0
+ && strncmp (segname, ".gnu.linkonce.s.", 16) != 0);
+ }
+ return change;
+ }
+ else
+ /* We are not optimizing for the $gp register. */
+ return 1;
+}
+
+
+/* Return true if the given symbol should be considered local for SVR4 PIC. */
+
+static bfd_boolean
+pic_need_relax (symbolS *sym, asection *segtype)
+{
+ asection *symsec;
+ bfd_boolean linkonce;
+
+ /* Handle the case of a symbol equated to another symbol. */
+ while (symbol_equated_reloc_p (sym))
+ {
+ symbolS *n;
+
+ /* It's possible to get a loop here in a badly written
+ program. */
+ n = symbol_get_value_expression (sym)->X_add_symbol;
+ if (n == sym)
+ break;
+ sym = n;
+ }
+
+ symsec = S_GET_SEGMENT (sym);
+
+ /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
+ linkonce = FALSE;
+ if (symsec != segtype && ! S_IS_LOCAL (sym))
+ {
+ if ((bfd_get_section_flags (stdoutput, symsec) & SEC_LINK_ONCE)
+ != 0)
+ linkonce = TRUE;
+
+ /* The GNU toolchain uses an extension for ELF: a section
+ beginning with the magic string .gnu.linkonce is a linkonce
+ section. */
+ if (strncmp (segment_name (symsec), ".gnu.linkonce",
+ sizeof ".gnu.linkonce" - 1) == 0)
+ linkonce = TRUE;
+ }
+
+ /* This must duplicate the test in adjust_reloc_syms. */
+ return (symsec != &bfd_und_section
+ && symsec != &bfd_abs_section
+ && ! bfd_is_com_section (symsec)
+ && !linkonce
+#ifdef OBJ_ELF
+ /* A global or weak symbol is treated as external. */
+ && (OUTPUT_FLAVOR != bfd_target_elf_flavour
+ || (! S_IS_WEAK (sym)
+ && (! S_IS_EXTERNAL (sym)
+ || mips_pic == EMBEDDED_PIC)))
+#endif
+ );
+}
+
+
+/* Given a mips16 variant frag FRAGP, return non-zero if it needs an
+ extended opcode. SEC is the section the frag is in. */
+
+static int
+mips16_extended_frag (fragS *fragp, asection *sec, long stretch)
+{
+ int type;
+ register const struct mips16_immed_operand *op;
+ offsetT val;
+ int mintiny, maxtiny;
+ segT symsec;
+ fragS *sym_frag;
+
+ if (RELAX_MIPS16_USER_SMALL (fragp->fr_subtype))
+ return 0;
+ if (RELAX_MIPS16_USER_EXT (fragp->fr_subtype))
+ return 1;
+
+ type = RELAX_MIPS16_TYPE (fragp->fr_subtype);
+ op = mips16_immed_operands;
+ while (op->type != type)
+ {
+ ++op;
+ assert (op < mips16_immed_operands + MIPS16_NUM_IMMED);
+ }
+
+ if (op->unsp)
+ {
+ if (type == '<' || type == '>' || type == '[' || type == ']')
+ {
+ mintiny = 1;
+ maxtiny = 1 << op->nbits;
+ }
+ else
+ {
+ mintiny = 0;
+ maxtiny = (1 << op->nbits) - 1;
+ }
+ }
+ else
+ {
+ mintiny = - (1 << (op->nbits - 1));
+ maxtiny = (1 << (op->nbits - 1)) - 1;
+ }
+
+ sym_frag = symbol_get_frag (fragp->fr_symbol);
+ val = S_GET_VALUE (fragp->fr_symbol);
+ symsec = S_GET_SEGMENT (fragp->fr_symbol);
+
+ if (op->pcrel)
+ {
+ addressT addr;
+
+ /* We won't have the section when we are called from
+ mips_relax_frag. However, we will always have been called
+ from md_estimate_size_before_relax first. If this is a
+ branch to a different section, we mark it as such. If SEC is
+ NULL, and the frag is not marked, then it must be a branch to
+ the same section. */
+ if (sec == NULL)
+ {
+ if (RELAX_MIPS16_LONG_BRANCH (fragp->fr_subtype))
+ return 1;
+ }
+ else
+ {
+ /* Must have been called from md_estimate_size_before_relax. */
+ if (symsec != sec)
+ {
+ fragp->fr_subtype =
+ RELAX_MIPS16_MARK_LONG_BRANCH (fragp->fr_subtype);
+
+ /* FIXME: We should support this, and let the linker
+ catch branches and loads that are out of range. */
+ as_bad_where (fragp->fr_file, fragp->fr_line,
+ _("unsupported PC relative reference to different section"));
+
+ return 1;
+ }
+ if (fragp != sym_frag && sym_frag->fr_address == 0)
+ /* Assume non-extended on the first relaxation pass.
+ The address we have calculated will be bogus if this is
+ a forward branch to another frag, as the forward frag
+ will have fr_address == 0. */
+ return 0;
+ }
+
+ /* In this case, we know for sure that the symbol fragment is in
+ the same section. If the relax_marker of the symbol fragment
+ differs from the relax_marker of this fragment, we have not
+ yet adjusted the symbol fragment fr_address. We want to add
+ in STRETCH in order to get a better estimate of the address.
+ This particularly matters because of the shift bits. */
+ if (stretch != 0
+ && sym_frag->relax_marker != fragp->relax_marker)
+ {
+ fragS *f;
+
+ /* Adjust stretch for any alignment frag. Note that if have
+ been expanding the earlier code, the symbol may be
+ defined in what appears to be an earlier frag. FIXME:
+ This doesn't handle the fr_subtype field, which specifies
+ a maximum number of bytes to skip when doing an
+ alignment. */
+ for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
+ {
+ if (f->fr_type == rs_align || f->fr_type == rs_align_code)
+ {
+ if (stretch < 0)
+ stretch = - ((- stretch)
+ & ~ ((1 << (int) f->fr_offset) - 1));
+ else
+ stretch &= ~ ((1 << (int) f->fr_offset) - 1);
+ if (stretch == 0)
+ break;
+ }
+ }
+ if (f != NULL)
+ val += stretch;
+ }
+
+ addr = fragp->fr_address + fragp->fr_fix;
+
+ /* The base address rules are complicated. The base address of
+ a branch is the following instruction. The base address of a
+ PC relative load or add is the instruction itself, but if it
+ is in a delay slot (in which case it can not be extended) use
+ the address of the instruction whose delay slot it is in. */
+ if (type == 'p' || type == 'q')
+ {
+ addr += 2;
+
+ /* If we are currently assuming that this frag should be
+ extended, then, the current address is two bytes
+ higher. */
+ if (RELAX_MIPS16_EXTENDED (fragp->fr_subtype))
+ addr += 2;
+
+ /* Ignore the low bit in the target, since it will be set
+ for a text label. */
+ if ((val & 1) != 0)
+ --val;
+ }
+ else if (RELAX_MIPS16_JAL_DSLOT (fragp->fr_subtype))
+ addr -= 4;
+ else if (RELAX_MIPS16_DSLOT (fragp->fr_subtype))
+ addr -= 2;
+
+ val -= addr & ~ ((1 << op->shift) - 1);
+
+ /* Branch offsets have an implicit 0 in the lowest bit. */
+ if (type == 'p' || type == 'q')
+ val /= 2;
+
+ /* If any of the shifted bits are set, we must use an extended
+ opcode. If the address depends on the size of this
+ instruction, this can lead to a loop, so we arrange to always
+ use an extended opcode. We only check this when we are in
+ the main relaxation loop, when SEC is NULL. */
+ if ((val & ((1 << op->shift) - 1)) != 0 && sec == NULL)
+ {
+ fragp->fr_subtype =
+ RELAX_MIPS16_MARK_LONG_BRANCH (fragp->fr_subtype);
+ return 1;
+ }
+
+ /* If we are about to mark a frag as extended because the value
+ is precisely maxtiny + 1, then there is a chance of an
+ infinite loop as in the following code:
+ la $4,foo
+ .skip 1020
+ .align 2
+ foo:
+ In this case when the la is extended, foo is 0x3fc bytes
+ away, so the la can be shrunk, but then foo is 0x400 away, so
+ the la must be extended. To avoid this loop, we mark the
+ frag as extended if it was small, and is about to become
+ extended with a value of maxtiny + 1. */
+ if (val == ((maxtiny + 1) << op->shift)
+ && ! RELAX_MIPS16_EXTENDED (fragp->fr_subtype)
+ && sec == NULL)
+ {
+ fragp->fr_subtype =
+ RELAX_MIPS16_MARK_LONG_BRANCH (fragp->fr_subtype);
+ return 1;
+ }
+ }
+ else if (symsec != absolute_section && sec != NULL)
+ as_bad_where (fragp->fr_file, fragp->fr_line, _("unsupported relocation"));
+
+ if ((val & ((1 << op->shift) - 1)) != 0
+ || val < (mintiny << op->shift)
+ || val > (maxtiny << op->shift))
+ return 1;
+ else
+ return 0;
+}
+
+/* Compute the length of a branch sequence, and adjust the
+ RELAX_BRANCH_TOOFAR bit accordingly. If FRAGP is NULL, the
+ worst-case length is computed, with UPDATE being used to indicate
+ whether an unconditional (-1), branch-likely (+1) or regular (0)
+ branch is to be computed. */
+static int
+relaxed_branch_length (fragS *fragp, asection *sec, int update)
+{
+ bfd_boolean toofar;
+ int length;
+
+ if (fragp
+ && S_IS_DEFINED (fragp->fr_symbol)
+ && sec == S_GET_SEGMENT (fragp->fr_symbol))
+ {
+ addressT addr;
+ offsetT val;
+
+ val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset;
+
+ addr = fragp->fr_address + fragp->fr_fix + 4;
+
+ val -= addr;
+
+ toofar = val < - (0x8000 << 2) || val >= (0x8000 << 2);
+ }
+ else if (fragp)
+ /* If the symbol is not defined or it's in a different segment,
+ assume the user knows what's going on and emit a short
+ branch. */
+ toofar = FALSE;
+ else
+ toofar = TRUE;
+
+ if (fragp && update && toofar != RELAX_BRANCH_TOOFAR (fragp->fr_subtype))
+ fragp->fr_subtype
+ = RELAX_BRANCH_ENCODE (RELAX_BRANCH_UNCOND (fragp->fr_subtype),
+ RELAX_BRANCH_LIKELY (fragp->fr_subtype),
+ RELAX_BRANCH_LINK (fragp->fr_subtype),
+ toofar);
+
+ length = 4;
+ if (toofar)
+ {
+ if (fragp ? RELAX_BRANCH_LIKELY (fragp->fr_subtype) : (update > 0))
+ length += 8;
+
+ if (mips_pic != NO_PIC)
+ {
+ /* Additional space for PIC loading of target address. */
+ length += 8;
+ if (mips_opts.isa == ISA_MIPS1)
+ /* Additional space for $at-stabilizing nop. */
+ length += 4;
+ }
+
+ /* If branch is conditional. */
+ if (fragp ? !RELAX_BRANCH_UNCOND (fragp->fr_subtype) : (update >= 0))
+ length += 8;
+ }
+
+ return length;
+}
+
+/* Estimate the size of a frag before relaxing. Unless this is the
+ mips16, we are not really relaxing here, and the final size is
+ encoded in the subtype information. For the mips16, we have to
+ decide whether we are using an extended opcode or not. */
+
+int
+md_estimate_size_before_relax (fragS *fragp, asection *segtype)
+{
+ int change;
+
+ if (RELAX_BRANCH_P (fragp->fr_subtype))
+ {
+
+ fragp->fr_var = relaxed_branch_length (fragp, segtype, FALSE);
+
+ return fragp->fr_var;
+ }
+
+ if (RELAX_MIPS16_P (fragp->fr_subtype))
+ /* We don't want to modify the EXTENDED bit here; it might get us
+ into infinite loops. We change it only in mips_relax_frag(). */
+ return (RELAX_MIPS16_EXTENDED (fragp->fr_subtype) ? 4 : 2);
+
+ if (mips_pic == NO_PIC)
+ change = nopic_need_relax (fragp->fr_symbol, 0);
+ else if (mips_pic == SVR4_PIC)
+ change = pic_need_relax (fragp->fr_symbol, segtype);
+ else
+ abort ();
+
+ if (change)
+ {
+ fragp->fr_subtype |= RELAX_USE_SECOND;
+ return -RELAX_FIRST (fragp->fr_subtype);
+ }
+ else
+ return -RELAX_SECOND (fragp->fr_subtype);
+}
+
+/* This is called to see whether a reloc against a defined symbol
+ should be converted into a reloc against a section. Don't adjust
+ MIPS16 jump relocations, so we don't have to worry about the format
+ of the offset in the .o file. Don't adjust relocations against
+ mips16 symbols, so that the linker can find them if it needs to set
+ up a stub. */
+
+int
+mips_fix_adjustable (fixS *fixp)
+{
+ if (fixp->fx_r_type == BFD_RELOC_MIPS16_JMP)
+ return 0;
+
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+
+ if (fixp->fx_addsy == NULL)
+ return 1;
+
+#ifdef OBJ_ELF
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour
+ && S_GET_OTHER (fixp->fx_addsy) == STO_MIPS16
+ && fixp->fx_subsy == NULL)
+ return 0;
+#endif
+
+ return 1;
+}
+
+/* Translate internal representation of relocation info to BFD target
+ format. */
+
+arelent **
+tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
+{
+ static arelent *retval[4];
+ arelent *reloc;
+ bfd_reloc_code_real_type code;
+
+ memset (retval, 0, sizeof(retval));
+ reloc = retval[0] = (arelent *) xcalloc (1, sizeof (arelent));
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+
+ if (mips_pic == EMBEDDED_PIC
+ && SWITCH_TABLE (fixp))
+ {
+ /* For a switch table entry we use a special reloc. The addend
+ is actually the difference between the reloc address and the
+ subtrahend. */
+ reloc->addend = reloc->address - S_GET_VALUE (fixp->fx_subsy);
+ if (OUTPUT_FLAVOR != bfd_target_ecoff_flavour)
+ as_fatal (_("Double check fx_r_type in tc-mips.c:tc_gen_reloc"));
+ fixp->fx_r_type = BFD_RELOC_GPREL32;
+ }
+ else if (fixp->fx_pcrel)
+ {
+ bfd_vma pcrel_address;
+
+ /* Set PCREL_ADDRESS to this relocation's "PC". The PC for high
+ high-part relocs is the address of the low-part reloc. */
+ if (fixp->fx_r_type == BFD_RELOC_PCREL_HI16_S)
+ {
+ assert (fixp->fx_next != NULL
+ && fixp->fx_next->fx_r_type == BFD_RELOC_PCREL_LO16);
+ pcrel_address = (fixp->fx_next->fx_where
+ + fixp->fx_next->fx_frag->fr_address);
+ }
+ else
+ pcrel_address = reloc->address;
+
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ {
+ /* At this point, fx_addnumber is "symbol offset - pcrel_address".
+ Relocations want only the symbol offset. */
+ reloc->addend = fixp->fx_addnumber + pcrel_address;
+ }
+ else if (fixp->fx_r_type == BFD_RELOC_PCREL_LO16
+ || fixp->fx_r_type == BFD_RELOC_PCREL_HI16_S)
+ {
+ /* We use a special addend for an internal RELLO or RELHI reloc. */
+ if (symbol_section_p (fixp->fx_addsy))
+ reloc->addend = pcrel_address - S_GET_VALUE (fixp->fx_subsy);
+ else
+ reloc->addend = fixp->fx_addnumber + pcrel_address;
+ }
+ else
+ {
+ if (OUTPUT_FLAVOR != bfd_target_aout_flavour)
+ /* A gruesome hack which is a result of the gruesome gas reloc
+ handling. */
+ reloc->addend = pcrel_address;
+ else
+ reloc->addend = -pcrel_address;
+ }
+ }
+ else
+ reloc->addend = fixp->fx_addnumber;
+
+ /* Since the old MIPS ELF ABI uses Rel instead of Rela, encode the vtable
+ entry to be used in the relocation's section offset. */
+ if (! HAVE_NEWABI && fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ {
+ reloc->address = reloc->addend;
+ reloc->addend = 0;
+ }
+
+ /* Since DIFF_EXPR_OK is defined in tc-mips.h, it is possible that
+ fixup_segment converted a non-PC relative reloc into a PC
+ relative reloc. In such a case, we need to convert the reloc
+ code. */
+ code = fixp->fx_r_type;
+ if (fixp->fx_pcrel)
+ {
+ switch (code)
+ {
+ case BFD_RELOC_8:
+ code = BFD_RELOC_8_PCREL;
+ break;
+ case BFD_RELOC_16:
+ code = BFD_RELOC_16_PCREL;
+ break;
+ case BFD_RELOC_32:
+ code = BFD_RELOC_32_PCREL;
+ break;
+ case BFD_RELOC_64:
+ code = BFD_RELOC_64_PCREL;
+ break;
+ case BFD_RELOC_8_PCREL:
+ case BFD_RELOC_16_PCREL:
+ case BFD_RELOC_32_PCREL:
+ case BFD_RELOC_64_PCREL:
+ case BFD_RELOC_16_PCREL_S2:
+ case BFD_RELOC_PCREL_HI16_S:
+ case BFD_RELOC_PCREL_LO16:
+ break;
+ default:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Cannot make %s relocation PC relative"),
+ bfd_get_reloc_code_name (code));
+ }
+ }
+
+ /* To support a PC relative reloc when generating embedded PIC code
+ for ECOFF, we use a Cygnus extension. We check for that here to
+ make sure that we don't let such a reloc escape normally. */
+ if ((OUTPUT_FLAVOR == bfd_target_ecoff_flavour
+ || OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ && code == BFD_RELOC_16_PCREL_S2
+ && mips_pic != EMBEDDED_PIC)
+ reloc->howto = NULL;
+ else
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+
+ if (reloc->howto == NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Can not represent %s relocation in this object file format"),
+ bfd_get_reloc_code_name (code));
+ retval[0] = NULL;
+ }
+
+ return retval;
+}
+
+/* Relax a machine dependent frag. This returns the amount by which
+ the current size of the frag should change. */
+
+int
+mips_relax_frag (asection *sec, fragS *fragp, long stretch)
+{
+ if (RELAX_BRANCH_P (fragp->fr_subtype))
+ {
+ offsetT old_var = fragp->fr_var;
+
+ fragp->fr_var = relaxed_branch_length (fragp, sec, TRUE);
+
+ return fragp->fr_var - old_var;
+ }
+
+ if (! RELAX_MIPS16_P (fragp->fr_subtype))
+ return 0;
+
+ if (mips16_extended_frag (fragp, NULL, stretch))
+ {
+ if (RELAX_MIPS16_EXTENDED (fragp->fr_subtype))
+ return 0;
+ fragp->fr_subtype = RELAX_MIPS16_MARK_EXTENDED (fragp->fr_subtype);
+ return 2;
+ }
+ else
+ {
+ if (! RELAX_MIPS16_EXTENDED (fragp->fr_subtype))
+ return 0;
+ fragp->fr_subtype = RELAX_MIPS16_CLEAR_EXTENDED (fragp->fr_subtype);
+ return -2;
+ }
+
+ return 0;
+}
+
+/* Convert a machine dependent frag. */
+
+void
+md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
+{
+ if (RELAX_BRANCH_P (fragp->fr_subtype))
+ {
+ bfd_byte *buf;
+ unsigned long insn;
+ expressionS exp;
+ fixS *fixp;
+
+ buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix;
+
+ if (target_big_endian)
+ insn = bfd_getb32 (buf);
+ else
+ insn = bfd_getl32 (buf);
+
+ if (!RELAX_BRANCH_TOOFAR (fragp->fr_subtype))
+ {
+ /* We generate a fixup instead of applying it right now
+ because, if there are linker relaxations, we're going to
+ need the relocations. */
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = fragp->fr_symbol;
+ exp.X_add_number = fragp->fr_offset;
+
+ fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
+ 4, &exp, 1,
+ BFD_RELOC_16_PCREL_S2);
+ fixp->fx_file = fragp->fr_file;
+ fixp->fx_line = fragp->fr_line;
+
+ md_number_to_chars (buf, insn, 4);
+ buf += 4;
+ }
+ else
+ {
+ int i;
+
+ as_warn_where (fragp->fr_file, fragp->fr_line,
+ _("relaxed out-of-range branch into a jump"));
+
+ if (RELAX_BRANCH_UNCOND (fragp->fr_subtype))
+ goto uncond;
+
+ if (!RELAX_BRANCH_LIKELY (fragp->fr_subtype))
+ {
+ /* Reverse the branch. */
+ switch ((insn >> 28) & 0xf)
+ {
+ case 4:
+ /* bc[0-3][tf]l? and bc1any[24][ft] instructions can
+ have the condition reversed by tweaking a single
+ bit, and their opcodes all have 0x4???????. */
+ assert ((insn & 0xf1000000) == 0x41000000);
+ insn ^= 0x00010000;
+ break;
+
+ case 0:
+ /* bltz 0x04000000 bgez 0x04010000
+ bltzal 0x04100000 bgezal 0x04110000 */
+ assert ((insn & 0xfc0e0000) == 0x04000000);
+ insn ^= 0x00010000;
+ break;
+
+ case 1:
+ /* beq 0x10000000 bne 0x14000000
+ blez 0x18000000 bgtz 0x1c000000 */
+ insn ^= 0x04000000;
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ if (RELAX_BRANCH_LINK (fragp->fr_subtype))
+ {
+ /* Clear the and-link bit. */
+ assert ((insn & 0xfc1c0000) == 0x04100000);
+
+ /* bltzal 0x04100000 bgezal 0x04110000
+ bltzall 0x04120000 bgezall 0x04130000 */
+ insn &= ~0x00100000;
+ }
+
+ /* Branch over the branch (if the branch was likely) or the
+ full jump (not likely case). Compute the offset from the
+ current instruction to branch to. */
+ if (RELAX_BRANCH_LIKELY (fragp->fr_subtype))
+ i = 16;
+ else
+ {
+ /* How many bytes in instructions we've already emitted? */
+ i = buf - (bfd_byte *)fragp->fr_literal - fragp->fr_fix;
+ /* How many bytes in instructions from here to the end? */
+ i = fragp->fr_var - i;
+ }
+ /* Convert to instruction count. */
+ i >>= 2;
+ /* Branch counts from the next instruction. */
+ i--;
+ insn |= i;
+ /* Branch over the jump. */
+ md_number_to_chars (buf, insn, 4);
+ buf += 4;
+
+ /* Nop */
+ md_number_to_chars (buf, 0, 4);
+ buf += 4;
+
+ if (RELAX_BRANCH_LIKELY (fragp->fr_subtype))
+ {
+ /* beql $0, $0, 2f */
+ insn = 0x50000000;
+ /* Compute the PC offset from the current instruction to
+ the end of the variable frag. */
+ /* How many bytes in instructions we've already emitted? */
+ i = buf - (bfd_byte *)fragp->fr_literal - fragp->fr_fix;
+ /* How many bytes in instructions from here to the end? */
+ i = fragp->fr_var - i;
+ /* Convert to instruction count. */
+ i >>= 2;
+ /* Don't decrement i, because we want to branch over the
+ delay slot. */
+
+ insn |= i;
+ md_number_to_chars (buf, insn, 4);
+ buf += 4;
+
+ md_number_to_chars (buf, 0, 4);
+ buf += 4;
+ }
+
+ uncond:
+ if (mips_pic == NO_PIC)
+ {
+ /* j or jal. */
+ insn = (RELAX_BRANCH_LINK (fragp->fr_subtype)
+ ? 0x0c000000 : 0x08000000);
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = fragp->fr_symbol;
+ exp.X_add_number = fragp->fr_offset;
+
+ fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
+ 4, &exp, 0, BFD_RELOC_MIPS_JMP);
+ fixp->fx_file = fragp->fr_file;
+ fixp->fx_line = fragp->fr_line;
+
+ md_number_to_chars (buf, insn, 4);
+ buf += 4;
+ }
+ else
+ {
+ /* lw/ld $at, <sym>($gp) R_MIPS_GOT16 */
+ insn = HAVE_64BIT_ADDRESSES ? 0xdf810000 : 0x8f810000;
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = fragp->fr_symbol;
+ exp.X_add_number = fragp->fr_offset;
+
+ if (fragp->fr_offset)
+ {
+ exp.X_add_symbol = make_expr_symbol (&exp);
+ exp.X_add_number = 0;
+ }
+
+ fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
+ 4, &exp, 0, BFD_RELOC_MIPS_GOT16);
+ fixp->fx_file = fragp->fr_file;
+ fixp->fx_line = fragp->fr_line;
+
+ md_number_to_chars (buf, insn, 4);
+ buf += 4;
+
+ if (mips_opts.isa == ISA_MIPS1)
+ {
+ /* nop */
+ md_number_to_chars (buf, 0, 4);
+ buf += 4;
+ }
+
+ /* d/addiu $at, $at, <sym> R_MIPS_LO16 */
+ insn = HAVE_64BIT_ADDRESSES ? 0x64210000 : 0x24210000;
+
+ fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
+ 4, &exp, 0, BFD_RELOC_LO16);
+ fixp->fx_file = fragp->fr_file;
+ fixp->fx_line = fragp->fr_line;
+
+ md_number_to_chars (buf, insn, 4);
+ buf += 4;
+
+ /* j(al)r $at. */
+ if (RELAX_BRANCH_LINK (fragp->fr_subtype))
+ insn = 0x0020f809;
+ else
+ insn = 0x00200008;
+
+ md_number_to_chars (buf, insn, 4);
+ buf += 4;
+ }
+ }
+
+ assert (buf == (bfd_byte *)fragp->fr_literal
+ + fragp->fr_fix + fragp->fr_var);
+
+ fragp->fr_fix += fragp->fr_var;
+
+ return;
+ }
+
+ if (RELAX_MIPS16_P (fragp->fr_subtype))
+ {
+ int type;
+ register const struct mips16_immed_operand *op;
+ bfd_boolean small, ext;
+ offsetT val;
+ bfd_byte *buf;
+ unsigned long insn;
+ bfd_boolean use_extend;
+ unsigned short extend;
+
+ type = RELAX_MIPS16_TYPE (fragp->fr_subtype);
+ op = mips16_immed_operands;
+ while (op->type != type)
+ ++op;
+
+ if (RELAX_MIPS16_EXTENDED (fragp->fr_subtype))
+ {
+ small = FALSE;
+ ext = TRUE;
+ }
+ else
+ {
+ small = TRUE;
+ ext = FALSE;
+ }
+
+ resolve_symbol_value (fragp->fr_symbol);
+ val = S_GET_VALUE (fragp->fr_symbol);
+ if (op->pcrel)
+ {
+ addressT addr;
+
+ addr = fragp->fr_address + fragp->fr_fix;
+
+ /* The rules for the base address of a PC relative reloc are
+ complicated; see mips16_extended_frag. */
+ if (type == 'p' || type == 'q')
+ {
+ addr += 2;
+ if (ext)
+ addr += 2;
+ /* Ignore the low bit in the target, since it will be
+ set for a text label. */
+ if ((val & 1) != 0)
+ --val;
+ }
+ else if (RELAX_MIPS16_JAL_DSLOT (fragp->fr_subtype))
+ addr -= 4;
+ else if (RELAX_MIPS16_DSLOT (fragp->fr_subtype))
+ addr -= 2;
+
+ addr &= ~ (addressT) ((1 << op->shift) - 1);
+ val -= addr;
+
+ /* Make sure the section winds up with the alignment we have
+ assumed. */
+ if (op->shift > 0)
+ record_alignment (asec, op->shift);
+ }
+
+ if (ext
+ && (RELAX_MIPS16_JAL_DSLOT (fragp->fr_subtype)
+ || RELAX_MIPS16_DSLOT (fragp->fr_subtype)))
+ as_warn_where (fragp->fr_file, fragp->fr_line,
+ _("extended instruction in delay slot"));
+
+ buf = (bfd_byte *) (fragp->fr_literal + fragp->fr_fix);
+
+ if (target_big_endian)
+ insn = bfd_getb16 (buf);
+ else
+ insn = bfd_getl16 (buf);
+
+ mips16_immed (fragp->fr_file, fragp->fr_line, type, val,
+ RELAX_MIPS16_USER_EXT (fragp->fr_subtype),
+ small, ext, &insn, &use_extend, &extend);
+
+ if (use_extend)
+ {
+ md_number_to_chars (buf, 0xf000 | extend, 2);
+ fragp->fr_fix += 2;
+ buf += 2;
+ }
+
+ md_number_to_chars (buf, insn, 2);
+ fragp->fr_fix += 2;
+ buf += 2;
+ }
+ else
+ {
+ int first, second;
+ fixS *fixp;
+
+ first = RELAX_FIRST (fragp->fr_subtype);
+ second = RELAX_SECOND (fragp->fr_subtype);
+ fixp = (fixS *) fragp->fr_opcode;
+
+ /* Possibly emit a warning if we've chosen the longer option. */
+ if (((fragp->fr_subtype & RELAX_USE_SECOND) != 0)
+ == ((fragp->fr_subtype & RELAX_SECOND_LONGER) != 0))
+ {
+ const char *msg = macro_warning (fragp->fr_subtype);
+ if (msg != 0)
+ as_warn_where (fragp->fr_file, fragp->fr_line, msg);
+ }
+
+ /* Go through all the fixups for the first sequence. Disable them
+ (by marking them as done) if we're going to use the second
+ sequence instead. */
+ while (fixp
+ && fixp->fx_frag == fragp
+ && fixp->fx_where < fragp->fr_fix - second)
+ {
+ if (fragp->fr_subtype & RELAX_USE_SECOND)
+ fixp->fx_done = 1;
+ fixp = fixp->fx_next;
+ }
+
+ /* Go through the fixups for the second sequence. Disable them if
+ we're going to use the first sequence, otherwise adjust their
+ addresses to account for the relaxation. */
+ while (fixp && fixp->fx_frag == fragp)
+ {
+ if (fragp->fr_subtype & RELAX_USE_SECOND)
+ fixp->fx_where -= first;
+ else
+ fixp->fx_done = 1;
+ fixp = fixp->fx_next;
+ }
+
+ /* Now modify the frag contents. */
+ if (fragp->fr_subtype & RELAX_USE_SECOND)
+ {
+ char *start;
+
+ start = fragp->fr_literal + fragp->fr_fix - first - second;
+ memmove (start, start + first, second);
+ fragp->fr_fix -= first;
+ }
+ else
+ fragp->fr_fix -= second;
+ }
+}
+
+#ifdef OBJ_ELF
+
+/* This function is called after the relocs have been generated.
+ We've been storing mips16 text labels as odd. Here we convert them
+ back to even for the convenience of the debugger. */
+
+void
+mips_frob_file_after_relocs (void)
+{
+ asymbol **syms;
+ unsigned int count, i;
+
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+ return;
+
+ syms = bfd_get_outsymbols (stdoutput);
+ count = bfd_get_symcount (stdoutput);
+ for (i = 0; i < count; i++, syms++)
+ {
+ if (elf_symbol (*syms)->internal_elf_sym.st_other == STO_MIPS16
+ && ((*syms)->value & 1) != 0)
+ {
+ (*syms)->value &= ~1;
+ /* If the symbol has an odd size, it was probably computed
+ incorrectly, so adjust that as well. */
+ if ((elf_symbol (*syms)->internal_elf_sym.st_size & 1) != 0)
+ ++elf_symbol (*syms)->internal_elf_sym.st_size;
+ }
+ }
+}
+
+#endif
+
+/* This function is called whenever a label is defined. It is used
+ when handling branch delays; if a branch has a label, we assume we
+ can not move it. */
+
+void
+mips_define_label (symbolS *sym)
+{
+ struct insn_label_list *l;
+
+ if (free_insn_labels == NULL)
+ l = (struct insn_label_list *) xmalloc (sizeof *l);
+ else
+ {
+ l = free_insn_labels;
+ free_insn_labels = l->next;
+ }
+
+ l->label = sym;
+ l->next = insn_labels;
+ insn_labels = l;
+}
+
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+
+/* Some special processing for a MIPS ELF file. */
+
+void
+mips_elf_final_processing (void)
+{
+ /* Write out the register information. */
+ if (mips_abi != N64_ABI)
+ {
+ Elf32_RegInfo s;
+
+ s.ri_gprmask = mips_gprmask;
+ s.ri_cprmask[0] = mips_cprmask[0];
+ s.ri_cprmask[1] = mips_cprmask[1];
+ s.ri_cprmask[2] = mips_cprmask[2];
+ s.ri_cprmask[3] = mips_cprmask[3];
+ /* The gp_value field is set by the MIPS ELF backend. */
+
+ bfd_mips_elf32_swap_reginfo_out (stdoutput, &s,
+ ((Elf32_External_RegInfo *)
+ mips_regmask_frag));
+ }
+ else
+ {
+ Elf64_Internal_RegInfo s;
+
+ s.ri_gprmask = mips_gprmask;
+ s.ri_pad = 0;
+ s.ri_cprmask[0] = mips_cprmask[0];
+ s.ri_cprmask[1] = mips_cprmask[1];
+ s.ri_cprmask[2] = mips_cprmask[2];
+ s.ri_cprmask[3] = mips_cprmask[3];
+ /* The gp_value field is set by the MIPS ELF backend. */
+
+ bfd_mips_elf64_swap_reginfo_out (stdoutput, &s,
+ ((Elf64_External_RegInfo *)
+ mips_regmask_frag));
+ }
+
+ /* Set the MIPS ELF flag bits. FIXME: There should probably be some
+ sort of BFD interface for this. */
+ if (mips_any_noreorder)
+ elf_elfheader (stdoutput)->e_flags |= EF_MIPS_NOREORDER;
+ if (mips_pic != NO_PIC)
+ {
+ elf_elfheader (stdoutput)->e_flags |= EF_MIPS_PIC;
+ elf_elfheader (stdoutput)->e_flags |= EF_MIPS_CPIC;
+ }
+ if (mips_abicalls)
+ elf_elfheader (stdoutput)->e_flags |= EF_MIPS_CPIC;
+
+ /* Set MIPS ELF flags for ASEs. */
+ if (file_ase_mips16)
+ elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_M16;
+#if 0 /* XXX FIXME */
+ if (file_ase_mips3d)
+ elf_elfheader (stdoutput)->e_flags |= ???;
+#endif
+ if (file_ase_mdmx)
+ elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_MDMX;
+
+ /* Set the MIPS ELF ABI flags. */
+ if (mips_abi == O32_ABI && USE_E_MIPS_ABI_O32)
+ elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_O32;
+ else if (mips_abi == O64_ABI)
+ elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_O64;
+ else if (mips_abi == EABI_ABI)
+ {
+ if (!file_mips_gp32)
+ elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_EABI64;
+ else
+ elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_EABI32;
+ }
+ else if (mips_abi == N32_ABI)
+ elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ABI2;
+
+ /* Nothing to do for N64_ABI. */
+
+ if (mips_32bitmode)
+ elf_elfheader (stdoutput)->e_flags |= EF_MIPS_32BITMODE;
+}
+
+#endif /* OBJ_ELF || OBJ_MAYBE_ELF */
+
+typedef struct proc {
+ symbolS *isym;
+ unsigned long reg_mask;
+ unsigned long reg_offset;
+ unsigned long fpreg_mask;
+ unsigned long fpreg_offset;
+ unsigned long frame_offset;
+ unsigned long frame_reg;
+ unsigned long pc_reg;
+} procS;
+
+static procS cur_proc;
+static procS *cur_proc_ptr;
+static int numprocs;
+
+/* Fill in an rs_align_code fragment. */
+
+void
+mips_handle_align (fragS *fragp)
+{
+ if (fragp->fr_type != rs_align_code)
+ return;
+
+ if (mips_opts.mips16)
+ {
+ static const unsigned char be_nop[] = { 0x65, 0x00 };
+ static const unsigned char le_nop[] = { 0x00, 0x65 };
+
+ int bytes;
+ char *p;
+
+ bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
+ p = fragp->fr_literal + fragp->fr_fix;
+
+ if (bytes & 1)
+ {
+ *p++ = 0;
+ fragp->fr_fix++;
+ }
+
+ memcpy (p, (target_big_endian ? be_nop : le_nop), 2);
+ fragp->fr_var = 2;
+ }
+
+ /* For mips32, a nop is a zero, which we trivially get by doing nothing. */
+}
+
+static void
+md_obj_begin (void)
+{
+}
+
+static void
+md_obj_end (void)
+{
+ /* check for premature end, nesting errors, etc */
+ if (cur_proc_ptr)
+ as_warn (_("missing .end at end of assembly"));
+}
+
+static long
+get_number (void)
+{
+ int negative = 0;
+ long val = 0;
+
+ if (*input_line_pointer == '-')
+ {
+ ++input_line_pointer;
+ negative = 1;
+ }
+ if (!ISDIGIT (*input_line_pointer))
+ as_bad (_("expected simple number"));
+ if (input_line_pointer[0] == '0')
+ {
+ if (input_line_pointer[1] == 'x')
+ {
+ input_line_pointer += 2;
+ while (ISXDIGIT (*input_line_pointer))
+ {
+ val <<= 4;
+ val |= hex_value (*input_line_pointer++);
+ }
+ return negative ? -val : val;
+ }
+ else
+ {
+ ++input_line_pointer;
+ while (ISDIGIT (*input_line_pointer))
+ {
+ val <<= 3;
+ val |= *input_line_pointer++ - '0';
+ }
+ return negative ? -val : val;
+ }
+ }
+ if (!ISDIGIT (*input_line_pointer))
+ {
+ printf (_(" *input_line_pointer == '%c' 0x%02x\n"),
+ *input_line_pointer, *input_line_pointer);
+ as_warn (_("invalid number"));
+ return -1;
+ }
+ while (ISDIGIT (*input_line_pointer))
+ {
+ val *= 10;
+ val += *input_line_pointer++ - '0';
+ }
+ return negative ? -val : val;
+}
+
+/* The .file directive; just like the usual .file directive, but there
+ is an initial number which is the ECOFF file index. In the non-ECOFF
+ case .file implies DWARF-2. */
+
+static void
+s_mips_file (int x ATTRIBUTE_UNUSED)
+{
+ static int first_file_directive = 0;
+
+ if (ECOFF_DEBUGGING)
+ {
+ get_number ();
+ s_app_file (0);
+ }
+ else
+ {
+ char *filename;
+
+ filename = dwarf2_directive_file (0);
+
+ /* Versions of GCC up to 3.1 start files with a ".file"
+ directive even for stabs output. Make sure that this
+ ".file" is handled. Note that you need a version of GCC
+ after 3.1 in order to support DWARF-2 on MIPS. */
+ if (filename != NULL && ! first_file_directive)
+ {
+ (void) new_logical_line (filename, -1);
+ s_app_file_string (filename);
+ }
+ first_file_directive = 1;
+ }
+}
+
+/* The .loc directive, implying DWARF-2. */
+
+static void
+s_mips_loc (int x ATTRIBUTE_UNUSED)
+{
+ if (!ECOFF_DEBUGGING)
+ dwarf2_directive_loc (0);
+}
+
+/* The .end directive. */
+
+static void
+s_mips_end (int x ATTRIBUTE_UNUSED)
+{
+ symbolS *p;
+
+ /* Following functions need their own .frame and .cprestore directives. */
+ mips_frame_reg_valid = 0;
+ mips_cprestore_valid = 0;
+
+ if (!is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ p = get_symbol ();
+ demand_empty_rest_of_line ();
+ }
+ else
+ p = NULL;
+
+ if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) == 0)
+ as_warn (_(".end not in text section"));
+
+ if (!cur_proc_ptr)
+ {
+ as_warn (_(".end directive without a preceding .ent directive."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (p != NULL)
+ {
+ assert (S_GET_NAME (p));
+ if (strcmp (S_GET_NAME (p), S_GET_NAME (cur_proc_ptr->isym)))
+ as_warn (_(".end symbol does not match .ent symbol."));
+
+ if (debug_type == DEBUG_STABS)
+ stabs_generate_asm_endfunc (S_GET_NAME (p),
+ S_GET_NAME (p));
+ }
+ else
+ as_warn (_(".end directive missing or unknown symbol"));
+
+#ifdef OBJ_ELF
+ /* Generate a .pdr section. */
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour && ! ECOFF_DEBUGGING
+ && mips_flag_pdr)
+ {
+ segT saved_seg = now_seg;
+ subsegT saved_subseg = now_subseg;
+ valueT dot;
+ expressionS exp;
+ char *fragp;
+
+ dot = frag_now_fix ();
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ assert (pdr_seg);
+ subseg_set (pdr_seg, 0);
+
+ /* Write the symbol. */
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = p;
+ exp.X_add_number = 0;
+ emit_expr (&exp, 4);
+
+ fragp = frag_more (7 * 4);
+
+ md_number_to_chars (fragp, cur_proc_ptr->reg_mask, 4);
+ md_number_to_chars (fragp + 4, cur_proc_ptr->reg_offset, 4);
+ md_number_to_chars (fragp + 8, cur_proc_ptr->fpreg_mask, 4);
+ md_number_to_chars (fragp + 12, cur_proc_ptr->fpreg_offset, 4);
+ md_number_to_chars (fragp + 16, cur_proc_ptr->frame_offset, 4);
+ md_number_to_chars (fragp + 20, cur_proc_ptr->frame_reg, 4);
+ md_number_to_chars (fragp + 24, cur_proc_ptr->pc_reg, 4);
+
+ subseg_set (saved_seg, saved_subseg);
+ }
+#endif /* OBJ_ELF */
+
+ cur_proc_ptr = NULL;
+}
+
+/* The .aent and .ent directives. */
+
+static void
+s_mips_ent (int aent)
+{
+ symbolS *symbolP;
+
+ symbolP = get_symbol ();
+ if (*input_line_pointer == ',')
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ if (ISDIGIT (*input_line_pointer)
+ || *input_line_pointer == '-')
+ get_number ();
+
+ if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) == 0)
+ as_warn (_(".ent or .aent not in text section."));
+
+ if (!aent && cur_proc_ptr)
+ as_warn (_("missing .end"));
+
+ if (!aent)
+ {
+ /* This function needs its own .frame and .cprestore directives. */
+ mips_frame_reg_valid = 0;
+ mips_cprestore_valid = 0;
+
+ cur_proc_ptr = &cur_proc;
+ memset (cur_proc_ptr, '\0', sizeof (procS));
+
+ cur_proc_ptr->isym = symbolP;
+
+ symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION;
+
+ ++numprocs;
+
+ if (debug_type == DEBUG_STABS)
+ stabs_generate_asm_func (S_GET_NAME (symbolP),
+ S_GET_NAME (symbolP));
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .frame directive. If the mdebug section is present (IRIX 5 native)
+ then ecoff.c (ecoff_directive_frame) is used. For embedded targets,
+ s_mips_frame is used so that we can set the PDR information correctly.
+ We can't use the ecoff routines because they make reference to the ecoff
+ symbol table (in the mdebug section). */
+
+static void
+s_mips_frame (int ignore ATTRIBUTE_UNUSED)
+{
+#ifdef OBJ_ELF
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour && ! ECOFF_DEBUGGING)
+ {
+ long val;
+
+ if (cur_proc_ptr == (procS *) NULL)
+ {
+ as_warn (_(".frame outside of .ent"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ cur_proc_ptr->frame_reg = tc_get_register (1);
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer++ != ','
+ || get_absolute_expression_and_terminator (&val) != ',')
+ {
+ as_warn (_("Bad .frame directive"));
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ cur_proc_ptr->frame_offset = val;
+ cur_proc_ptr->pc_reg = tc_get_register (0);
+
+ demand_empty_rest_of_line ();
+ }
+ else
+#endif /* OBJ_ELF */
+ s_ignore (ignore);
+}
+
+/* The .fmask and .mask directives. If the mdebug section is present
+ (IRIX 5 native) then ecoff.c (ecoff_directive_mask) is used. For
+ embedded targets, s_mips_mask is used so that we can set the PDR
+ information correctly. We can't use the ecoff routines because they
+ make reference to the ecoff symbol table (in the mdebug section). */
+
+static void
+s_mips_mask (int reg_type)
+{
+#ifdef OBJ_ELF
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour && ! ECOFF_DEBUGGING)
+ {
+ long mask, off;
+
+ if (cur_proc_ptr == (procS *) NULL)
+ {
+ as_warn (_(".mask/.fmask outside of .ent"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (get_absolute_expression_and_terminator (&mask) != ',')
+ {
+ as_warn (_("Bad .mask/.fmask directive"));
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ off = get_absolute_expression ();
+
+ if (reg_type == 'F')
+ {
+ cur_proc_ptr->fpreg_mask = mask;
+ cur_proc_ptr->fpreg_offset = off;
+ }
+ else
+ {
+ cur_proc_ptr->reg_mask = mask;
+ cur_proc_ptr->reg_offset = off;
+ }
+
+ demand_empty_rest_of_line ();
+ }
+ else
+#endif /* OBJ_ELF */
+ s_ignore (reg_type);
+}
+
+/* The .loc directive. */
+
+#if 0
+static void
+s_loc (int x)
+{
+ symbolS *symbolP;
+ int lineno;
+ int addroff;
+
+ assert (now_seg == text_section);
+
+ lineno = get_number ();
+ addroff = frag_now_fix ();
+
+ symbolP = symbol_new ("", N_SLINE, addroff, frag_now);
+ S_SET_TYPE (symbolP, N_SLINE);
+ S_SET_OTHER (symbolP, 0);
+ S_SET_DESC (symbolP, lineno);
+ symbolP->sy_segment = now_seg;
+}
+#endif
+
+/* A table describing all the processors gas knows about. Names are
+ matched in the order listed.
+
+ To ease comparison, please keep this table in the same order as
+ gcc's mips_cpu_info_table[]. */
+static const struct mips_cpu_info mips_cpu_info_table[] =
+{
+ /* Entries for generic ISAs */
+ { "mips1", 1, ISA_MIPS1, CPU_R3000 },
+ { "mips2", 1, ISA_MIPS2, CPU_R6000 },
+ { "mips3", 1, ISA_MIPS3, CPU_R4000 },
+ { "mips4", 1, ISA_MIPS4, CPU_R8000 },
+ { "mips5", 1, ISA_MIPS5, CPU_MIPS5 },
+ { "mips32", 1, ISA_MIPS32, CPU_MIPS32 },
+ { "mips32r2", 1, ISA_MIPS32R2, CPU_MIPS32R2 },
+ { "mips64", 1, ISA_MIPS64, CPU_MIPS64 },
+ { "mips64r2", 1, ISA_MIPS64R2, CPU_MIPS64R2 },
+
+ /* MIPS I */
+ { "r3000", 0, ISA_MIPS1, CPU_R3000 },
+ { "r2000", 0, ISA_MIPS1, CPU_R3000 },
+ { "r3900", 0, ISA_MIPS1, CPU_R3900 },
+
+ /* MIPS II */
+ { "r6000", 0, ISA_MIPS2, CPU_R6000 },
+
+ /* MIPS III */
+ { "r4000", 0, ISA_MIPS3, CPU_R4000 },
+ { "r4010", 0, ISA_MIPS2, CPU_R4010 },
+ { "vr4100", 0, ISA_MIPS3, CPU_VR4100 },
+ { "vr4111", 0, ISA_MIPS3, CPU_R4111 },
+ { "vr4120", 0, ISA_MIPS3, CPU_VR4120 },
+ { "vr4130", 0, ISA_MIPS3, CPU_VR4120 },
+ { "vr4181", 0, ISA_MIPS3, CPU_R4111 },
+ { "vr4300", 0, ISA_MIPS3, CPU_R4300 },
+ { "r4400", 0, ISA_MIPS3, CPU_R4400 },
+ { "r4600", 0, ISA_MIPS3, CPU_R4600 },
+ { "orion", 0, ISA_MIPS3, CPU_R4600 },
+ { "r4650", 0, ISA_MIPS3, CPU_R4650 },
+
+ /* MIPS IV */
+ { "r8000", 0, ISA_MIPS4, CPU_R8000 },
+ { "r10000", 0, ISA_MIPS4, CPU_R10000 },
+ { "r12000", 0, ISA_MIPS4, CPU_R12000 },
+ { "vr5000", 0, ISA_MIPS4, CPU_R5000 },
+ { "vr5400", 0, ISA_MIPS4, CPU_VR5400 },
+ { "vr5500", 0, ISA_MIPS4, CPU_VR5500 },
+ { "rm5200", 0, ISA_MIPS4, CPU_R5000 },
+ { "rm5230", 0, ISA_MIPS4, CPU_R5000 },
+ { "rm5231", 0, ISA_MIPS4, CPU_R5000 },
+ { "rm5261", 0, ISA_MIPS4, CPU_R5000 },
+ { "rm5721", 0, ISA_MIPS4, CPU_R5000 },
+ { "rm7000", 0, ISA_MIPS4, CPU_RM7000 },
+ { "rm9000", 0, ISA_MIPS4, CPU_RM7000 },
+
+ /* MIPS 32 */
+ { "4kc", 0, ISA_MIPS32, CPU_MIPS32 },
+ { "4km", 0, ISA_MIPS32, CPU_MIPS32 },
+ { "4kp", 0, ISA_MIPS32, CPU_MIPS32 },
+
+ /* MIPS 64 */
+ { "5kc", 0, ISA_MIPS64, CPU_MIPS64 },
+ { "20kc", 0, ISA_MIPS64, CPU_MIPS64 },
+
+ /* Broadcom SB-1 CPU core */
+ { "sb1", 0, ISA_MIPS64, CPU_SB1 },
+
+ /* End marker */
+ { NULL, 0, 0, 0 }
+};
+
+
+/* Return true if GIVEN is the same as CANONICAL, or if it is CANONICAL
+ with a final "000" replaced by "k". Ignore case.
+
+ Note: this function is shared between GCC and GAS. */
+
+static bfd_boolean
+mips_strict_matching_cpu_name_p (const char *canonical, const char *given)
+{
+ while (*given != 0 && TOLOWER (*given) == TOLOWER (*canonical))
+ given++, canonical++;
+
+ return ((*given == 0 && *canonical == 0)
+ || (strcmp (canonical, "000") == 0 && strcasecmp (given, "k") == 0));
+}
+
+
+/* Return true if GIVEN matches CANONICAL, where GIVEN is a user-supplied
+ CPU name. We've traditionally allowed a lot of variation here.
+
+ Note: this function is shared between GCC and GAS. */
+
+static bfd_boolean
+mips_matching_cpu_name_p (const char *canonical, const char *given)
+{
+ /* First see if the name matches exactly, or with a final "000"
+ turned into "k". */
+ if (mips_strict_matching_cpu_name_p (canonical, given))
+ return TRUE;
+
+ /* If not, try comparing based on numerical designation alone.
+ See if GIVEN is an unadorned number, or 'r' followed by a number. */
+ if (TOLOWER (*given) == 'r')
+ given++;
+ if (!ISDIGIT (*given))
+ return FALSE;
+
+ /* Skip over some well-known prefixes in the canonical name,
+ hoping to find a number there too. */
+ if (TOLOWER (canonical[0]) == 'v' && TOLOWER (canonical[1]) == 'r')
+ canonical += 2;
+ else if (TOLOWER (canonical[0]) == 'r' && TOLOWER (canonical[1]) == 'm')
+ canonical += 2;
+ else if (TOLOWER (canonical[0]) == 'r')
+ canonical += 1;
+
+ return mips_strict_matching_cpu_name_p (canonical, given);
+}
+
+
+/* Parse an option that takes the name of a processor as its argument.
+ OPTION is the name of the option and CPU_STRING is the argument.
+ Return the corresponding processor enumeration if the CPU_STRING is
+ recognized, otherwise report an error and return null.
+
+ A similar function exists in GCC. */
+
+static const struct mips_cpu_info *
+mips_parse_cpu (const char *option, const char *cpu_string)
+{
+ const struct mips_cpu_info *p;
+
+ /* 'from-abi' selects the most compatible architecture for the given
+ ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit ABIs. For the
+ EABIs, we have to decide whether we're using the 32-bit or 64-bit
+ version. Look first at the -mgp options, if given, otherwise base
+ the choice on MIPS_DEFAULT_64BIT.
+
+ Treat NO_ABI like the EABIs. One reason to do this is that the
+ plain 'mips' and 'mips64' configs have 'from-abi' as their default
+ architecture. This code picks MIPS I for 'mips' and MIPS III for
+ 'mips64', just as we did in the days before 'from-abi'. */
+ if (strcasecmp (cpu_string, "from-abi") == 0)
+ {
+ if (ABI_NEEDS_32BIT_REGS (mips_abi))
+ return mips_cpu_info_from_isa (ISA_MIPS1);
+
+ if (ABI_NEEDS_64BIT_REGS (mips_abi))
+ return mips_cpu_info_from_isa (ISA_MIPS3);
+
+ if (file_mips_gp32 >= 0)
+ return mips_cpu_info_from_isa (file_mips_gp32 ? ISA_MIPS1 : ISA_MIPS3);
+
+ return mips_cpu_info_from_isa (MIPS_DEFAULT_64BIT
+ ? ISA_MIPS3
+ : ISA_MIPS1);
+ }
+
+ /* 'default' has traditionally been a no-op. Probably not very useful. */
+ if (strcasecmp (cpu_string, "default") == 0)
+ return 0;
+
+ for (p = mips_cpu_info_table; p->name != 0; p++)
+ if (mips_matching_cpu_name_p (p->name, cpu_string))
+ return p;
+
+ as_bad ("Bad value (%s) for %s", cpu_string, option);
+ return 0;
+}
+
+/* Return the canonical processor information for ISA (a member of the
+ ISA_MIPS* enumeration). */
+
+static const struct mips_cpu_info *
+mips_cpu_info_from_isa (int isa)
+{
+ int i;
+
+ for (i = 0; mips_cpu_info_table[i].name != NULL; i++)
+ if (mips_cpu_info_table[i].is_isa
+ && isa == mips_cpu_info_table[i].isa)
+ return (&mips_cpu_info_table[i]);
+
+ return NULL;
+}
+
+static const struct mips_cpu_info *
+mips_cpu_info_from_arch (int arch)
+{
+ int i;
+
+ for (i = 0; mips_cpu_info_table[i].name != NULL; i++)
+ if (arch == mips_cpu_info_table[i].cpu)
+ return (&mips_cpu_info_table[i]);
+
+ return NULL;
+}
+
+static void
+show (FILE *stream, const char *string, int *col_p, int *first_p)
+{
+ if (*first_p)
+ {
+ fprintf (stream, "%24s", "");
+ *col_p = 24;
+ }
+ else
+ {
+ fprintf (stream, ", ");
+ *col_p += 2;
+ }
+
+ if (*col_p + strlen (string) > 72)
+ {
+ fprintf (stream, "\n%24s", "");
+ *col_p = 24;
+ }
+
+ fprintf (stream, "%s", string);
+ *col_p += strlen (string);
+
+ *first_p = 0;
+}
+
+void
+md_show_usage (FILE *stream)
+{
+ int column, first;
+ size_t i;
+
+ fprintf (stream, _("\
+MIPS options:\n\
+-membedded-pic generate embedded position independent code\n\
+-EB generate big endian output\n\
+-EL generate little endian output\n\
+-g, -g2 do not remove unneeded NOPs or swap branches\n\
+-G NUM allow referencing objects up to NUM bytes\n\
+ implicitly with the gp register [default 8]\n"));
+ fprintf (stream, _("\
+-mips1 generate MIPS ISA I instructions\n\
+-mips2 generate MIPS ISA II instructions\n\
+-mips3 generate MIPS ISA III instructions\n\
+-mips4 generate MIPS ISA IV instructions\n\
+-mips5 generate MIPS ISA V instructions\n\
+-mips32 generate MIPS32 ISA instructions\n\
+-mips32r2 generate MIPS32 release 2 ISA instructions\n\
+-mips64 generate MIPS64 ISA instructions\n\
+-mips64r2 generate MIPS64 release 2 ISA instructions\n\
+-march=CPU/-mtune=CPU generate code/schedule for CPU, where CPU is one of:\n"));
+
+ first = 1;
+
+ for (i = 0; mips_cpu_info_table[i].name != NULL; i++)
+ show (stream, mips_cpu_info_table[i].name, &column, &first);
+ show (stream, "from-abi", &column, &first);
+ fputc ('\n', stream);
+
+ fprintf (stream, _("\
+-mCPU equivalent to -march=CPU -mtune=CPU. Deprecated.\n\
+-no-mCPU don't generate code specific to CPU.\n\
+ For -mCPU and -no-mCPU, CPU must be one of:\n"));
+
+ first = 1;
+
+ show (stream, "3900", &column, &first);
+ show (stream, "4010", &column, &first);
+ show (stream, "4100", &column, &first);
+ show (stream, "4650", &column, &first);
+ fputc ('\n', stream);
+
+ fprintf (stream, _("\
+-mips16 generate mips16 instructions\n\
+-no-mips16 do not generate mips16 instructions\n"));
+ fprintf (stream, _("\
+-mfix-vr4120 work around certain VR4120 errata\n\
+-mgp32 use 32-bit GPRs, regardless of the chosen ISA\n\
+-mfp32 use 32-bit FPRs, regardless of the chosen ISA\n\
+-O0 remove unneeded NOPs, do not swap branches\n\
+-O remove unneeded NOPs and swap branches\n\
+--[no-]construct-floats [dis]allow floating point values to be constructed\n\
+--trap, --no-break trap exception on div by 0 and mult overflow\n\
+--break, --no-trap break exception on div by 0 and mult overflow\n"));
+#ifdef OBJ_ELF
+ fprintf (stream, _("\
+-KPIC, -call_shared generate SVR4 position independent code\n\
+-non_shared do not generate position independent code\n\
+-xgot assume a 32 bit GOT\n\
+-mpdr, -mno-pdr enable/disable creation of .pdr sections\n\
+-mabi=ABI create ABI conformant object file for:\n"));
+
+ first = 1;
+
+ show (stream, "32", &column, &first);
+ show (stream, "o64", &column, &first);
+ show (stream, "n32", &column, &first);
+ show (stream, "64", &column, &first);
+ show (stream, "eabi", &column, &first);
+
+ fputc ('\n', stream);
+
+ fprintf (stream, _("\
+-32 create o32 ABI object file (default)\n\
+-n32 create n32 ABI object file\n\
+-64 create 64 ABI object file\n"));
+#endif
+}
+
+enum dwarf2_format
+mips_dwarf2_format (void)
+{
+ if (mips_abi == N64_ABI)
+ {
+#ifdef TE_IRIX
+ return dwarf2_format_64bit_irix;
+#else
+ return dwarf2_format_64bit;
+#endif
+ }
+ else
+ return dwarf2_format_32bit;
+}
+
+int
+mips_dwarf2_addr_size (void)
+{
+ if (mips_abi == N64_ABI)
+ return 8;
+ else
+ return 4;
+}
diff --git a/x/binutils/gas/config/tc-mips.h b/x/binutils/gas/config/tc-mips.h
new file mode 100644
index 0000000..46a7653
--- /dev/null
+++ b/x/binutils/gas/config/tc-mips.h
@@ -0,0 +1,188 @@
+/* tc-mips.h -- header file for tc-mips.c.
+ Copyright 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
+ Contributed by the OSF and Ralph Campbell.
+ Written by Keith Knowles and Ralph Campbell, working independently.
+ Modified for ECOFF support by Ian Lance Taylor of Cygnus Support.
+
+ This file is part of GAS.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef TC_MIPS
+#define TC_MIPS
+
+struct frag;
+struct expressionS;
+
+/* Default to big endian. */
+#ifndef TARGET_BYTES_BIG_ENDIAN
+#define TARGET_BYTES_BIG_ENDIAN 1
+#endif
+
+#define TARGET_ARCH bfd_arch_mips
+
+#define WORKING_DOT_WORD 1
+#define OLD_FLOAT_READS
+#define REPEAT_CONS_EXPRESSIONS
+#define RELOC_EXPANSION_POSSIBLE
+#define MAX_RELOC_EXPANSION 3
+#define LOCAL_LABELS_FB 1
+
+/* Maximum symbol offset that can be encoded in a BFD_RELOC_GPREL16
+ relocation. */
+#define MAX_GPREL_OFFSET (0x7FF0)
+
+#define md_relax_frag(segment, fragp, stretch) \
+ mips_relax_frag(segment, fragp, stretch)
+extern int mips_relax_frag (asection *, struct frag *, long);
+
+#define md_undefined_symbol(name) (0)
+#define md_operand(x)
+
+extern void mips_handle_align (struct frag *);
+#define HANDLE_ALIGN(fragp) mips_handle_align (fragp)
+
+#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 2)
+
+/* We permit PC relative difference expressions when generating
+ embedded PIC code. */
+#define DIFF_EXPR_OK
+
+/* Tell assembler that we have an itbl_mips.h header file to include. */
+#define HAVE_ITBL_CPU
+
+/* The endianness of the target format may change based on command
+ line arguments. */
+#define TARGET_FORMAT mips_target_format()
+extern const char *mips_target_format (void);
+
+/* MIPS PIC level. */
+
+enum mips_pic_level
+{
+ /* Do not generate PIC code. */
+ NO_PIC,
+
+ /* Generate PIC code as in the SVR4 MIPS ABI. */
+ SVR4_PIC,
+
+ /* Generate PIC code without using a global offset table: the data
+ segment has a maximum size of 64K, all data references are off
+ the $gp register, and all text references are PC relative. This
+ is used on some embedded systems. */
+ EMBEDDED_PIC
+};
+
+extern enum mips_pic_level mips_pic;
+
+struct mips_cl_insn
+{
+ unsigned long insn_opcode;
+ const struct mips_opcode *insn_mo;
+ /* The next two fields are used when generating mips16 code. */
+ bfd_boolean use_extend;
+ unsigned short extend;
+};
+
+extern int tc_get_register (int frame);
+
+#define md_after_parse_args() mips_after_parse_args()
+extern void mips_after_parse_args (void);
+
+#define tc_init_after_args() mips_init_after_args()
+extern void mips_init_after_args (void);
+
+#define md_parse_long_option(arg) mips_parse_long_option (arg)
+extern int mips_parse_long_option (const char *);
+
+#define tc_frob_label(sym) mips_define_label (sym)
+extern void mips_define_label (symbolS *);
+
+#define tc_frob_file_before_adjust() mips_frob_file_before_adjust ()
+extern void mips_frob_file_before_adjust (void);
+
+#define tc_frob_file_before_fix() mips_frob_file ()
+extern void mips_frob_file (void);
+
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+#define tc_frob_file_after_relocs mips_frob_file_after_relocs
+extern void mips_frob_file_after_relocs (void);
+#endif
+
+#define tc_fix_adjustable(fixp) mips_fix_adjustable (fixp)
+extern int mips_fix_adjustable (struct fix *);
+
+/* Values passed to md_apply_fix3 don't include symbol values. */
+#define MD_APPLY_SYM_VALUE(FIX) 0
+
+/* Global syms must not be resolved, to support ELF shared libraries.
+ When generating embedded code, we don't have shared libs. */
+#define EXTERN_FORCE_RELOC \
+ (OUTPUT_FLAVOR == bfd_target_elf_flavour \
+ && mips_pic != EMBEDDED_PIC)
+
+/* When generating embedded PIC code we must keep PC relative
+ relocations. */
+#define TC_FORCE_RELOCATION(FIX) mips_force_relocation (FIX)
+extern int mips_force_relocation (struct fix *);
+
+#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEG) \
+ (! SEG_NORMAL (SEG) || mips_force_relocation (FIX))
+
+/* We use this to turn branches to global symbols into branches to
+ local symbols, so that they can be simplified. */
+#define TC_VALIDATE_FIX(fixp, this_segment, skip_label) \
+ do \
+ if (! mips_validate_fix ((fixp), (this_segment))) \
+ goto skip_label; \
+ while (0)
+extern int mips_validate_fix (struct fix *, asection *);
+
+/* Register mask variables. These are set by the MIPS assembly code
+ and used by ECOFF and possibly other object file formats. */
+extern unsigned long mips_gprmask;
+extern unsigned long mips_cprmask[4];
+
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+
+#define elf_tc_final_processing mips_elf_final_processing
+extern void mips_elf_final_processing (void);
+
+#endif
+
+extern void md_mips_end (void);
+#define md_end() md_mips_end()
+
+#define USE_GLOBAL_POINTER_OPT (OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
+ || OUTPUT_FLAVOR == bfd_target_coff_flavour \
+ || OUTPUT_FLAVOR == bfd_target_elf_flavour)
+
+extern void mips_pop_insert (void);
+#define md_pop_insert() mips_pop_insert()
+
+extern void mips_flush_pending_output (void);
+#define md_flush_pending_output mips_flush_pending_output
+
+extern void mips_enable_auto_align (void);
+#define md_elf_section_change_hook() mips_enable_auto_align()
+
+extern enum dwarf2_format mips_dwarf2_format (void);
+#define DWARF2_FORMAT() mips_dwarf2_format ()
+
+#define DWARF2_ADDR_SIZE(bfd) mips_dwarf2_addr_size ()
+
+#endif /* TC_MIPS */
diff --git a/x/binutils/gas/config/tc-ppc.c b/x/binutils/gas/config/tc-ppc.c
new file mode 100644
index 0000000..66366a5
--- /dev/null
+++ b/x/binutils/gas/config/tc-ppc.c
@@ -0,0 +1,6063 @@
+/* tc-ppc.c -- Assemble for the PowerPC or POWER (RS/6000)
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+ 2004 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <stdio.h>
+#include "as.h"
+#include "safe-ctype.h"
+#include "subsegs.h"
+#include "dw2gencfi.h"
+#include "opcode/ppc.h"
+
+#ifdef OBJ_ELF
+#include "elf/ppc.h"
+#include "dwarf2dbg.h"
+#endif
+
+#ifdef TE_PE
+#include "coff/pe.h"
+#endif
+
+/* This is the assembler for the PowerPC or POWER (RS/6000) chips. */
+
+/* Tell the main code what the endianness is. */
+extern int target_big_endian;
+
+/* Whether or not, we've set target_big_endian. */
+static int set_target_endian = 0;
+
+/* Whether to use user friendly register names. */
+#ifndef TARGET_REG_NAMES_P
+#ifdef TE_PE
+#define TARGET_REG_NAMES_P TRUE
+#else
+#define TARGET_REG_NAMES_P FALSE
+#endif
+#endif
+
+/* Macros for calculating LO, HI, HA, HIGHER, HIGHERA, HIGHEST,
+ HIGHESTA. */
+
+/* #lo(value) denotes the least significant 16 bits of the indicated. */
+#define PPC_LO(v) ((v) & 0xffff)
+
+/* #hi(value) denotes bits 16 through 31 of the indicated value. */
+#define PPC_HI(v) (((v) >> 16) & 0xffff)
+
+/* #ha(value) denotes the high adjusted value: bits 16 through 31 of
+ the indicated value, compensating for #lo() being treated as a
+ signed number. */
+#define PPC_HA(v) PPC_HI ((v) + 0x8000)
+
+/* #higher(value) denotes bits 32 through 47 of the indicated value. */
+#define PPC_HIGHER(v) (((v) >> 16 >> 16) & 0xffff)
+
+/* #highera(value) denotes bits 32 through 47 of the indicated value,
+ compensating for #lo() being treated as a signed number. */
+#define PPC_HIGHERA(v) PPC_HIGHER ((v) + 0x8000)
+
+/* #highest(value) denotes bits 48 through 63 of the indicated value. */
+#define PPC_HIGHEST(v) (((v) >> 24 >> 24) & 0xffff)
+
+/* #highesta(value) denotes bits 48 through 63 of the indicated value,
+ compensating for #lo being treated as a signed number. */
+#define PPC_HIGHESTA(v) PPC_HIGHEST ((v) + 0x8000)
+
+#define SEX16(val) ((((val) & 0xffff) ^ 0x8000) - 0x8000)
+
+static bfd_boolean reg_names_p = TARGET_REG_NAMES_P;
+
+static bfd_boolean register_name PARAMS ((expressionS *));
+static void ppc_set_cpu PARAMS ((void));
+static unsigned long ppc_insert_operand
+ PARAMS ((unsigned long insn, const struct powerpc_operand *operand,
+ offsetT val, char *file, unsigned int line));
+static void ppc_macro PARAMS ((char *str, const struct powerpc_macro *macro));
+static void ppc_byte PARAMS ((int));
+
+#if defined (OBJ_XCOFF) || defined (OBJ_ELF)
+static int ppc_is_toc_sym PARAMS ((symbolS *sym));
+static void ppc_tc PARAMS ((int));
+static void ppc_machine PARAMS ((int));
+#endif
+
+#ifdef OBJ_XCOFF
+static void ppc_comm PARAMS ((int));
+static void ppc_bb PARAMS ((int));
+static void ppc_bc PARAMS ((int));
+static void ppc_bf PARAMS ((int));
+static void ppc_biei PARAMS ((int));
+static void ppc_bs PARAMS ((int));
+static void ppc_eb PARAMS ((int));
+static void ppc_ec PARAMS ((int));
+static void ppc_ef PARAMS ((int));
+static void ppc_es PARAMS ((int));
+static void ppc_csect PARAMS ((int));
+static void ppc_change_csect PARAMS ((symbolS *, offsetT));
+static void ppc_function PARAMS ((int));
+static void ppc_extern PARAMS ((int));
+static void ppc_lglobl PARAMS ((int));
+static void ppc_section PARAMS ((int));
+static void ppc_named_section PARAMS ((int));
+static void ppc_stabx PARAMS ((int));
+static void ppc_rename PARAMS ((int));
+static void ppc_toc PARAMS ((int));
+static void ppc_xcoff_cons PARAMS ((int));
+static void ppc_vbyte PARAMS ((int));
+#endif
+
+#ifdef OBJ_ELF
+static bfd_reloc_code_real_type ppc_elf_suffix PARAMS ((char **, expressionS *));
+static void ppc_elf_cons PARAMS ((int));
+static void ppc_elf_rdata PARAMS ((int));
+static void ppc_elf_lcomm PARAMS ((int));
+static void ppc_elf_validate_fix PARAMS ((fixS *, segT));
+static void ppc_apuinfo_section_add PARAMS ((unsigned int apu, unsigned int version));
+#endif
+
+#ifdef TE_PE
+static void ppc_set_current_section PARAMS ((segT));
+static void ppc_previous PARAMS ((int));
+static void ppc_pdata PARAMS ((int));
+static void ppc_ydata PARAMS ((int));
+static void ppc_reldata PARAMS ((int));
+static void ppc_rdata PARAMS ((int));
+static void ppc_ualong PARAMS ((int));
+static void ppc_znop PARAMS ((int));
+static void ppc_pe_comm PARAMS ((int));
+static void ppc_pe_section PARAMS ((int));
+static void ppc_pe_function PARAMS ((int));
+static void ppc_pe_tocd PARAMS ((int));
+#endif
+
+/* Generic assembler global variables which must be defined by all
+ targets. */
+
+#ifdef OBJ_ELF
+/* This string holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful. The macro
+ tc_comment_chars points to this. We use this, rather than the
+ usual comment_chars, so that we can switch for Solaris conventions. */
+static const char ppc_solaris_comment_chars[] = "#!";
+static const char ppc_eabi_comment_chars[] = "#";
+
+#ifdef TARGET_SOLARIS_COMMENT
+const char *ppc_comment_chars = ppc_solaris_comment_chars;
+#else
+const char *ppc_comment_chars = ppc_eabi_comment_chars;
+#endif
+#else
+const char comment_chars[] = "#";
+#endif
+
+/* Characters which start a comment at the beginning of a line. */
+const char line_comment_chars[] = "#";
+
+/* Characters which may be used to separate multiple commands on a
+ single line. */
+const char line_separator_chars[] = ";";
+
+/* Characters which are used to indicate an exponent in a floating
+ point number. */
+const char EXP_CHARS[] = "eE";
+
+/* Characters which mean that a number is a floating point constant,
+ as in 0d1.0. */
+const char FLT_CHARS[] = "dD";
+
+/* '+' and '-' can be used as postfix predicate predictors for conditional
+ branches. So they need to be accepted as symbol characters. */
+const char ppc_symbol_chars[] = "+-";
+
+/* The dwarf2 data alignment, adjusted for 32 or 64 bit. */
+int ppc_cie_data_alignment;
+
+/* The target specific pseudo-ops which we support. */
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ /* Pseudo-ops which must be overridden. */
+ { "byte", ppc_byte, 0 },
+
+#ifdef OBJ_XCOFF
+ /* Pseudo-ops specific to the RS/6000 XCOFF format. Some of these
+ legitimately belong in the obj-*.c file. However, XCOFF is based
+ on COFF, and is only implemented for the RS/6000. We just use
+ obj-coff.c, and add what we need here. */
+ { "comm", ppc_comm, 0 },
+ { "lcomm", ppc_comm, 1 },
+ { "bb", ppc_bb, 0 },
+ { "bc", ppc_bc, 0 },
+ { "bf", ppc_bf, 0 },
+ { "bi", ppc_biei, 0 },
+ { "bs", ppc_bs, 0 },
+ { "csect", ppc_csect, 0 },
+ { "data", ppc_section, 'd' },
+ { "eb", ppc_eb, 0 },
+ { "ec", ppc_ec, 0 },
+ { "ef", ppc_ef, 0 },
+ { "ei", ppc_biei, 1 },
+ { "es", ppc_es, 0 },
+ { "extern", ppc_extern, 0 },
+ { "function", ppc_function, 0 },
+ { "lglobl", ppc_lglobl, 0 },
+ { "rename", ppc_rename, 0 },
+ { "section", ppc_named_section, 0 },
+ { "stabx", ppc_stabx, 0 },
+ { "text", ppc_section, 't' },
+ { "toc", ppc_toc, 0 },
+ { "long", ppc_xcoff_cons, 2 },
+ { "llong", ppc_xcoff_cons, 3 },
+ { "word", ppc_xcoff_cons, 1 },
+ { "short", ppc_xcoff_cons, 1 },
+ { "vbyte", ppc_vbyte, 0 },
+#endif
+
+#ifdef OBJ_ELF
+ { "llong", ppc_elf_cons, 8 },
+ { "quad", ppc_elf_cons, 8 },
+ { "long", ppc_elf_cons, 4 },
+ { "word", ppc_elf_cons, 2 },
+ { "short", ppc_elf_cons, 2 },
+ { "rdata", ppc_elf_rdata, 0 },
+ { "rodata", ppc_elf_rdata, 0 },
+ { "lcomm", ppc_elf_lcomm, 0 },
+#endif
+
+#ifdef TE_PE
+ /* Pseudo-ops specific to the Windows NT PowerPC PE (coff) format. */
+ { "previous", ppc_previous, 0 },
+ { "pdata", ppc_pdata, 0 },
+ { "ydata", ppc_ydata, 0 },
+ { "reldata", ppc_reldata, 0 },
+ { "rdata", ppc_rdata, 0 },
+ { "ualong", ppc_ualong, 0 },
+ { "znop", ppc_znop, 0 },
+ { "comm", ppc_pe_comm, 0 },
+ { "lcomm", ppc_pe_comm, 1 },
+ { "section", ppc_pe_section, 0 },
+ { "function", ppc_pe_function,0 },
+ { "tocd", ppc_pe_tocd, 0 },
+#endif
+
+#if defined (OBJ_XCOFF) || defined (OBJ_ELF)
+ { "tc", ppc_tc, 0 },
+ { "machine", ppc_machine, 0 },
+#endif
+
+ { NULL, NULL, 0 }
+};
+
+
+/* Predefined register names if -mregnames (or default for Windows NT).
+ In general, there are lots of them, in an attempt to be compatible
+ with a number of other Windows NT assemblers. */
+
+/* Structure to hold information about predefined registers. */
+struct pd_reg
+ {
+ char *name;
+ int value;
+ };
+
+/* List of registers that are pre-defined:
+
+ Each general register has predefined names of the form:
+ 1. r<reg_num> which has the value <reg_num>.
+ 2. r.<reg_num> which has the value <reg_num>.
+
+ Each floating point register has predefined names of the form:
+ 1. f<reg_num> which has the value <reg_num>.
+ 2. f.<reg_num> which has the value <reg_num>.
+
+ Each vector unit register has predefined names of the form:
+ 1. v<reg_num> which has the value <reg_num>.
+ 2. v.<reg_num> which has the value <reg_num>.
+
+ Each condition register has predefined names of the form:
+ 1. cr<reg_num> which has the value <reg_num>.
+ 2. cr.<reg_num> which has the value <reg_num>.
+
+ There are individual registers as well:
+ sp or r.sp has the value 1
+ rtoc or r.toc has the value 2
+ fpscr has the value 0
+ xer has the value 1
+ lr has the value 8
+ ctr has the value 9
+ pmr has the value 0
+ dar has the value 19
+ dsisr has the value 18
+ dec has the value 22
+ sdr1 has the value 25
+ srr0 has the value 26
+ srr1 has the value 27
+
+ The table is sorted. Suitable for searching by a binary search. */
+
+static const struct pd_reg pre_defined_registers[] =
+{
+ { "cr.0", 0 }, /* Condition Registers */
+ { "cr.1", 1 },
+ { "cr.2", 2 },
+ { "cr.3", 3 },
+ { "cr.4", 4 },
+ { "cr.5", 5 },
+ { "cr.6", 6 },
+ { "cr.7", 7 },
+
+ { "cr0", 0 },
+ { "cr1", 1 },
+ { "cr2", 2 },
+ { "cr3", 3 },
+ { "cr4", 4 },
+ { "cr5", 5 },
+ { "cr6", 6 },
+ { "cr7", 7 },
+
+ { "ctr", 9 },
+
+ { "dar", 19 }, /* Data Access Register */
+ { "dec", 22 }, /* Decrementer */
+ { "dsisr", 18 }, /* Data Storage Interrupt Status Register */
+
+ { "f.0", 0 }, /* Floating point registers */
+ { "f.1", 1 },
+ { "f.10", 10 },
+ { "f.11", 11 },
+ { "f.12", 12 },
+ { "f.13", 13 },
+ { "f.14", 14 },
+ { "f.15", 15 },
+ { "f.16", 16 },
+ { "f.17", 17 },
+ { "f.18", 18 },
+ { "f.19", 19 },
+ { "f.2", 2 },
+ { "f.20", 20 },
+ { "f.21", 21 },
+ { "f.22", 22 },
+ { "f.23", 23 },
+ { "f.24", 24 },
+ { "f.25", 25 },
+ { "f.26", 26 },
+ { "f.27", 27 },
+ { "f.28", 28 },
+ { "f.29", 29 },
+ { "f.3", 3 },
+ { "f.30", 30 },
+ { "f.31", 31 },
+ { "f.4", 4 },
+ { "f.5", 5 },
+ { "f.6", 6 },
+ { "f.7", 7 },
+ { "f.8", 8 },
+ { "f.9", 9 },
+
+ { "f0", 0 },
+ { "f1", 1 },
+ { "f10", 10 },
+ { "f11", 11 },
+ { "f12", 12 },
+ { "f13", 13 },
+ { "f14", 14 },
+ { "f15", 15 },
+ { "f16", 16 },
+ { "f17", 17 },
+ { "f18", 18 },
+ { "f19", 19 },
+ { "f2", 2 },
+ { "f20", 20 },
+ { "f21", 21 },
+ { "f22", 22 },
+ { "f23", 23 },
+ { "f24", 24 },
+ { "f25", 25 },
+ { "f26", 26 },
+ { "f27", 27 },
+ { "f28", 28 },
+ { "f29", 29 },
+ { "f3", 3 },
+ { "f30", 30 },
+ { "f31", 31 },
+ { "f4", 4 },
+ { "f5", 5 },
+ { "f6", 6 },
+ { "f7", 7 },
+ { "f8", 8 },
+ { "f9", 9 },
+
+ { "fpscr", 0 },
+
+ { "lr", 8 }, /* Link Register */
+
+ { "pmr", 0 },
+
+ { "r.0", 0 }, /* General Purpose Registers */
+ { "r.1", 1 },
+ { "r.10", 10 },
+ { "r.11", 11 },
+ { "r.12", 12 },
+ { "r.13", 13 },
+ { "r.14", 14 },
+ { "r.15", 15 },
+ { "r.16", 16 },
+ { "r.17", 17 },
+ { "r.18", 18 },
+ { "r.19", 19 },
+ { "r.2", 2 },
+ { "r.20", 20 },
+ { "r.21", 21 },
+ { "r.22", 22 },
+ { "r.23", 23 },
+ { "r.24", 24 },
+ { "r.25", 25 },
+ { "r.26", 26 },
+ { "r.27", 27 },
+ { "r.28", 28 },
+ { "r.29", 29 },
+ { "r.3", 3 },
+ { "r.30", 30 },
+ { "r.31", 31 },
+ { "r.4", 4 },
+ { "r.5", 5 },
+ { "r.6", 6 },
+ { "r.7", 7 },
+ { "r.8", 8 },
+ { "r.9", 9 },
+
+ { "r.sp", 1 }, /* Stack Pointer */
+
+ { "r.toc", 2 }, /* Pointer to the table of contents */
+
+ { "r0", 0 }, /* More general purpose registers */
+ { "r1", 1 },
+ { "r10", 10 },
+ { "r11", 11 },
+ { "r12", 12 },
+ { "r13", 13 },
+ { "r14", 14 },
+ { "r15", 15 },
+ { "r16", 16 },
+ { "r17", 17 },
+ { "r18", 18 },
+ { "r19", 19 },
+ { "r2", 2 },
+ { "r20", 20 },
+ { "r21", 21 },
+ { "r22", 22 },
+ { "r23", 23 },
+ { "r24", 24 },
+ { "r25", 25 },
+ { "r26", 26 },
+ { "r27", 27 },
+ { "r28", 28 },
+ { "r29", 29 },
+ { "r3", 3 },
+ { "r30", 30 },
+ { "r31", 31 },
+ { "r4", 4 },
+ { "r5", 5 },
+ { "r6", 6 },
+ { "r7", 7 },
+ { "r8", 8 },
+ { "r9", 9 },
+
+ { "rtoc", 2 }, /* Table of contents */
+
+ { "sdr1", 25 }, /* Storage Description Register 1 */
+
+ { "sp", 1 },
+
+ { "srr0", 26 }, /* Machine Status Save/Restore Register 0 */
+ { "srr1", 27 }, /* Machine Status Save/Restore Register 1 */
+
+ { "v.0", 0 }, /* Vector registers */
+ { "v.1", 1 },
+ { "v.10", 10 },
+ { "v.11", 11 },
+ { "v.12", 12 },
+ { "v.13", 13 },
+ { "v.14", 14 },
+ { "v.15", 15 },
+ { "v.16", 16 },
+ { "v.17", 17 },
+ { "v.18", 18 },
+ { "v.19", 19 },
+ { "v.2", 2 },
+ { "v.20", 20 },
+ { "v.21", 21 },
+ { "v.22", 22 },
+ { "v.23", 23 },
+ { "v.24", 24 },
+ { "v.25", 25 },
+ { "v.26", 26 },
+ { "v.27", 27 },
+ { "v.28", 28 },
+ { "v.29", 29 },
+ { "v.3", 3 },
+ { "v.30", 30 },
+ { "v.31", 31 },
+ { "v.4", 4 },
+ { "v.5", 5 },
+ { "v.6", 6 },
+ { "v.7", 7 },
+ { "v.8", 8 },
+ { "v.9", 9 },
+
+ { "v0", 0 },
+ { "v1", 1 },
+ { "v10", 10 },
+ { "v11", 11 },
+ { "v12", 12 },
+ { "v13", 13 },
+ { "v14", 14 },
+ { "v15", 15 },
+ { "v16", 16 },
+ { "v17", 17 },
+ { "v18", 18 },
+ { "v19", 19 },
+ { "v2", 2 },
+ { "v20", 20 },
+ { "v21", 21 },
+ { "v22", 22 },
+ { "v23", 23 },
+ { "v24", 24 },
+ { "v25", 25 },
+ { "v26", 26 },
+ { "v27", 27 },
+ { "v28", 28 },
+ { "v29", 29 },
+ { "v3", 3 },
+ { "v30", 30 },
+ { "v31", 31 },
+ { "v4", 4 },
+ { "v5", 5 },
+ { "v6", 6 },
+ { "v7", 7 },
+ { "v8", 8 },
+ { "v9", 9 },
+
+ { "xer", 1 },
+
+};
+
+#define REG_NAME_CNT (sizeof (pre_defined_registers) / sizeof (struct pd_reg))
+
+/* Given NAME, find the register number associated with that name, return
+ the integer value associated with the given name or -1 on failure. */
+
+static int reg_name_search
+ PARAMS ((const struct pd_reg *, int, const char * name));
+
+static int
+reg_name_search (regs, regcount, name)
+ const struct pd_reg *regs;
+ int regcount;
+ const char *name;
+{
+ int middle, low, high;
+ int cmp;
+
+ low = 0;
+ high = regcount - 1;
+
+ do
+ {
+ middle = (low + high) / 2;
+ cmp = strcasecmp (name, regs[middle].name);
+ if (cmp < 0)
+ high = middle - 1;
+ else if (cmp > 0)
+ low = middle + 1;
+ else
+ return regs[middle].value;
+ }
+ while (low <= high);
+
+ return -1;
+}
+
+/*
+ * Summary of register_name.
+ *
+ * in: Input_line_pointer points to 1st char of operand.
+ *
+ * out: A expressionS.
+ * The operand may have been a register: in this case, X_op == O_register,
+ * X_add_number is set to the register number, and truth is returned.
+ * Input_line_pointer->(next non-blank) char after operand, or is in its
+ * original state.
+ */
+
+static bfd_boolean
+register_name (expressionP)
+ expressionS *expressionP;
+{
+ int reg_number;
+ char *name;
+ char *start;
+ char c;
+
+ /* Find the spelling of the operand. */
+ start = name = input_line_pointer;
+ if (name[0] == '%' && ISALPHA (name[1]))
+ name = ++input_line_pointer;
+
+ else if (!reg_names_p || !ISALPHA (name[0]))
+ return FALSE;
+
+ c = get_symbol_end ();
+ reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT, name);
+
+ /* Put back the delimiting char. */
+ *input_line_pointer = c;
+
+ /* Look to see if it's in the register table. */
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = reg_number;
+
+ /* Make the rest nice. */
+ expressionP->X_add_symbol = NULL;
+ expressionP->X_op_symbol = NULL;
+ return TRUE;
+ }
+
+ /* Reset the line as if we had not done anything. */
+ input_line_pointer = start;
+ return FALSE;
+}
+
+/* This function is called for each symbol seen in an expression. It
+ handles the special parsing which PowerPC assemblers are supposed
+ to use for condition codes. */
+
+/* Whether to do the special parsing. */
+static bfd_boolean cr_operand;
+
+/* Names to recognize in a condition code. This table is sorted. */
+static const struct pd_reg cr_names[] =
+{
+ { "cr0", 0 },
+ { "cr1", 1 },
+ { "cr2", 2 },
+ { "cr3", 3 },
+ { "cr4", 4 },
+ { "cr5", 5 },
+ { "cr6", 6 },
+ { "cr7", 7 },
+ { "eq", 2 },
+ { "gt", 1 },
+ { "lt", 0 },
+ { "so", 3 },
+ { "un", 3 }
+};
+
+/* Parsing function. This returns non-zero if it recognized an
+ expression. */
+
+int
+ppc_parse_name (name, expr)
+ const char *name;
+ expressionS *expr;
+{
+ int val;
+
+ if (! cr_operand)
+ return 0;
+
+ val = reg_name_search (cr_names, sizeof cr_names / sizeof cr_names[0],
+ name);
+ if (val < 0)
+ return 0;
+
+ expr->X_op = O_constant;
+ expr->X_add_number = val;
+
+ return 1;
+}
+
+/* Local variables. */
+
+/* The type of processor we are assembling for. This is one or more
+ of the PPC_OPCODE flags defined in opcode/ppc.h. */
+static unsigned long ppc_cpu = 0;
+
+/* Whether to target xcoff64/elf64. */
+static unsigned int ppc_obj64 = BFD_DEFAULT_TARGET_SIZE == 64;
+
+/* Opcode hash table. */
+static struct hash_control *ppc_hash;
+
+/* Macro hash table. */
+static struct hash_control *ppc_macro_hash;
+
+#ifdef OBJ_ELF
+/* What type of shared library support to use. */
+static enum { SHLIB_NONE, SHLIB_PIC, SHLIB_MRELOCATABLE } shlib = SHLIB_NONE;
+
+/* Flags to set in the elf header. */
+static flagword ppc_flags = 0;
+
+/* Whether this is Solaris or not. */
+#ifdef TARGET_SOLARIS_COMMENT
+#define SOLARIS_P TRUE
+#else
+#define SOLARIS_P FALSE
+#endif
+
+static bfd_boolean msolaris = SOLARIS_P;
+#endif
+
+#ifdef OBJ_XCOFF
+
+/* The RS/6000 assembler uses the .csect pseudo-op to generate code
+ using a bunch of different sections. These assembler sections,
+ however, are all encompassed within the .text or .data sections of
+ the final output file. We handle this by using different
+ subsegments within these main segments. */
+
+/* Next subsegment to allocate within the .text segment. */
+static subsegT ppc_text_subsegment = 2;
+
+/* Linked list of csects in the text section. */
+static symbolS *ppc_text_csects;
+
+/* Next subsegment to allocate within the .data segment. */
+static subsegT ppc_data_subsegment = 2;
+
+/* Linked list of csects in the data section. */
+static symbolS *ppc_data_csects;
+
+/* The current csect. */
+static symbolS *ppc_current_csect;
+
+/* The RS/6000 assembler uses a TOC which holds addresses of functions
+ and variables. Symbols are put in the TOC with the .tc pseudo-op.
+ A special relocation is used when accessing TOC entries. We handle
+ the TOC as a subsegment within the .data segment. We set it up if
+ we see a .toc pseudo-op, and save the csect symbol here. */
+static symbolS *ppc_toc_csect;
+
+/* The first frag in the TOC subsegment. */
+static fragS *ppc_toc_frag;
+
+/* The first frag in the first subsegment after the TOC in the .data
+ segment. NULL if there are no subsegments after the TOC. */
+static fragS *ppc_after_toc_frag;
+
+/* The current static block. */
+static symbolS *ppc_current_block;
+
+/* The COFF debugging section; set by md_begin. This is not the
+ .debug section, but is instead the secret BFD section which will
+ cause BFD to set the section number of a symbol to N_DEBUG. */
+static asection *ppc_coff_debug_section;
+
+#endif /* OBJ_XCOFF */
+
+#ifdef TE_PE
+
+/* Various sections that we need for PE coff support. */
+static segT ydata_section;
+static segT pdata_section;
+static segT reldata_section;
+static segT rdata_section;
+static segT tocdata_section;
+
+/* The current section and the previous section. See ppc_previous. */
+static segT ppc_previous_section;
+static segT ppc_current_section;
+
+#endif /* TE_PE */
+
+#ifdef OBJ_ELF
+symbolS *GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE" */
+#define PPC_APUINFO_ISEL 0x40
+#define PPC_APUINFO_PMR 0x41
+#define PPC_APUINFO_RFMCI 0x42
+#define PPC_APUINFO_CACHELCK 0x43
+#define PPC_APUINFO_SPE 0x100
+#define PPC_APUINFO_EFS 0x101
+#define PPC_APUINFO_BRLOCK 0x102
+
+/*
+ * We keep a list of APUinfo
+ */
+unsigned long *ppc_apuinfo_list;
+unsigned int ppc_apuinfo_num;
+unsigned int ppc_apuinfo_num_alloc;
+#endif /* OBJ_ELF */
+
+#ifdef OBJ_ELF
+const char *const md_shortopts = "b:l:usm:K:VQ:";
+#else
+const char *const md_shortopts = "um:";
+#endif
+const struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+const size_t md_longopts_size = sizeof (md_longopts);
+
+
+/* Handle -m options that set cpu type, and .machine arg. */
+
+static int
+parse_cpu (const char *arg)
+{
+ /* -mpwrx and -mpwr2 mean to assemble for the IBM POWER/2
+ (RIOS2). */
+ if (strcmp (arg, "pwrx") == 0 || strcmp (arg, "pwr2") == 0)
+ ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_32;
+ /* -mpwr means to assemble for the IBM POWER (RIOS1). */
+ else if (strcmp (arg, "pwr") == 0)
+ ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_32;
+ /* -m601 means to assemble for the PowerPC 601, which includes
+ instructions that are holdovers from the Power. */
+ else if (strcmp (arg, "601") == 0)
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_601 | PPC_OPCODE_32);
+ /* -mppc, -mppc32, -m603, and -m604 mean to assemble for the
+ PowerPC 603/604. */
+ else if (strcmp (arg, "ppc") == 0
+ || strcmp (arg, "ppc32") == 0
+ || strcmp (arg, "603") == 0
+ || strcmp (arg, "604") == 0)
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32;
+ /* -m403 and -m405 mean to assemble for the PowerPC 403/405. */
+ else if (strcmp (arg, "403") == 0
+ || strcmp (arg, "405") == 0)
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_403 | PPC_OPCODE_32);
+ else if (strcmp (arg, "440") == 0)
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32
+ | PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI);
+ else if (strcmp (arg, "7400") == 0
+ || strcmp (arg, "7410") == 0
+ || strcmp (arg, "7450") == 0
+ || strcmp (arg, "7455") == 0)
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_ALTIVEC | PPC_OPCODE_32);
+ else if (strcmp (arg, "altivec") == 0)
+ {
+ if (ppc_cpu == 0)
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC;
+ else
+ ppc_cpu |= PPC_OPCODE_ALTIVEC;
+ }
+ else if (strcmp (arg, "e500") == 0 || strcmp (arg, "e500x2") == 0)
+ {
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
+ | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
+ | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
+ | PPC_OPCODE_RFMCI);
+ }
+ else if (strcmp (arg, "spe") == 0)
+ {
+ if (ppc_cpu == 0)
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_SPE | PPC_OPCODE_EFS;
+ else
+ ppc_cpu |= PPC_OPCODE_SPE;
+ }
+ /* -mppc64 and -m620 mean to assemble for the 64-bit PowerPC
+ 620. */
+ else if (strcmp (arg, "ppc64") == 0 || strcmp (arg, "620") == 0)
+ {
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
+ }
+ else if (strcmp (arg, "ppc64bridge") == 0)
+ {
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_64_BRIDGE | PPC_OPCODE_64);
+ }
+ /* -mbooke/-mbooke32 mean enable 32-bit BookE support. */
+ else if (strcmp (arg, "booke") == 0 || strcmp (arg, "booke32") == 0)
+ {
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32;
+ }
+ /* -mbooke64 means enable 64-bit BookE support. */
+ else if (strcmp (arg, "booke64") == 0)
+ {
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE
+ | PPC_OPCODE_BOOKE64 | PPC_OPCODE_64);
+ }
+ else if (strcmp (arg, "power4") == 0)
+ {
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_64 | PPC_OPCODE_POWER4);
+ }
+ /* -mcom means assemble for the common intersection between Power
+ and PowerPC. At present, we just allow the union, rather
+ than the intersection. */
+ else if (strcmp (arg, "com") == 0)
+ ppc_cpu = PPC_OPCODE_COMMON | PPC_OPCODE_32;
+ /* -many means to assemble for any architecture (PWR/PWRX/PPC). */
+ else if (strcmp (arg, "any") == 0)
+ ppc_cpu |= PPC_OPCODE_ANY;
+ else
+ return 0;
+
+ return 1;
+}
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case 'u':
+ /* -u means that any undefined symbols should be treated as
+ external, which is the default for gas anyhow. */
+ break;
+
+#ifdef OBJ_ELF
+ case 'l':
+ /* Solaris as takes -le (presumably for little endian). For completeness
+ sake, recognize -be also. */
+ if (strcmp (arg, "e") == 0)
+ {
+ target_big_endian = 0;
+ set_target_endian = 1;
+ }
+ else
+ return 0;
+
+ break;
+
+ case 'b':
+ if (strcmp (arg, "e") == 0)
+ {
+ target_big_endian = 1;
+ set_target_endian = 1;
+ }
+ else
+ return 0;
+
+ break;
+
+ case 'K':
+ /* Recognize -K PIC. */
+ if (strcmp (arg, "PIC") == 0 || strcmp (arg, "pic") == 0)
+ {
+ shlib = SHLIB_PIC;
+ ppc_flags |= EF_PPC_RELOCATABLE_LIB;
+ }
+ else
+ return 0;
+
+ break;
+#endif
+
+ /* a64 and a32 determine whether to use XCOFF64 or XCOFF32. */
+ case 'a':
+ if (strcmp (arg, "64") == 0)
+ {
+#ifdef BFD64
+ ppc_obj64 = 1;
+#else
+ as_fatal (_("%s unsupported"), "-a64");
+#endif
+ }
+ else if (strcmp (arg, "32") == 0)
+ ppc_obj64 = 0;
+ else
+ return 0;
+ break;
+
+ case 'm':
+ if (parse_cpu (arg))
+ ;
+
+ else if (strcmp (arg, "regnames") == 0)
+ reg_names_p = TRUE;
+
+ else if (strcmp (arg, "no-regnames") == 0)
+ reg_names_p = FALSE;
+
+#ifdef OBJ_ELF
+ /* -mrelocatable/-mrelocatable-lib -- warn about initializations
+ that require relocation. */
+ else if (strcmp (arg, "relocatable") == 0)
+ {
+ shlib = SHLIB_MRELOCATABLE;
+ ppc_flags |= EF_PPC_RELOCATABLE;
+ }
+
+ else if (strcmp (arg, "relocatable-lib") == 0)
+ {
+ shlib = SHLIB_MRELOCATABLE;
+ ppc_flags |= EF_PPC_RELOCATABLE_LIB;
+ }
+
+ /* -memb, set embedded bit. */
+ else if (strcmp (arg, "emb") == 0)
+ ppc_flags |= EF_PPC_EMB;
+
+ /* -mlittle/-mbig set the endianess. */
+ else if (strcmp (arg, "little") == 0
+ || strcmp (arg, "little-endian") == 0)
+ {
+ target_big_endian = 0;
+ set_target_endian = 1;
+ }
+
+ else if (strcmp (arg, "big") == 0 || strcmp (arg, "big-endian") == 0)
+ {
+ target_big_endian = 1;
+ set_target_endian = 1;
+ }
+
+ else if (strcmp (arg, "solaris") == 0)
+ {
+ msolaris = TRUE;
+ ppc_comment_chars = ppc_solaris_comment_chars;
+ }
+
+ else if (strcmp (arg, "no-solaris") == 0)
+ {
+ msolaris = FALSE;
+ ppc_comment_chars = ppc_eabi_comment_chars;
+ }
+#endif
+ else
+ {
+ as_bad (_("invalid switch -m%s"), arg);
+ return 0;
+ }
+ break;
+
+#ifdef OBJ_ELF
+ /* -V: SVR4 argument to print version ID. */
+ case 'V':
+ print_version_id ();
+ break;
+
+ /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
+ should be emitted or not. FIXME: Not implemented. */
+ case 'Q':
+ break;
+
+ /* Solaris takes -s to specify that .stabs go in a .stabs section,
+ rather than .stabs.excl, which is ignored by the linker.
+ FIXME: Not implemented. */
+ case 's':
+ if (arg)
+ return 0;
+
+ break;
+#endif
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf (stream, _("\
+PowerPC options:\n\
+-a32 generate ELF32/XCOFF32\n\
+-a64 generate ELF64/XCOFF64\n\
+-u ignored\n\
+-mpwrx, -mpwr2 generate code for POWER/2 (RIOS2)\n\
+-mpwr generate code for POWER (RIOS1)\n\
+-m601 generate code for PowerPC 601\n\
+-mppc, -mppc32, -m603, -m604\n\
+ generate code for PowerPC 603/604\n\
+-m403, -m405 generate code for PowerPC 403/405\n\
+-m440 generate code for PowerPC 440\n\
+-m7400, -m7410, -m7450, -m7455\n\
+ generate code For PowerPC 7400/7410/7450/7455\n"));
+ fprintf (stream, _("\
+-mppc64, -m620 generate code for PowerPC 620/625/630\n\
+-mppc64bridge generate code for PowerPC 64, including bridge insns\n\
+-mbooke64 generate code for 64-bit PowerPC BookE\n\
+-mbooke, mbooke32 generate code for 32-bit PowerPC BookE\n\
+-mpower4 generate code for Power4 architecture\n\
+-mcom generate code Power/PowerPC common instructions\n\
+-many generate code for any architecture (PWR/PWRX/PPC)\n"));
+ fprintf (stream, _("\
+-maltivec generate code for AltiVec\n\
+-me500, -me500x2 generate code for Motorola e500 core complex\n\
+-mspe generate code for Motorola SPE instructions\n\
+-mregnames Allow symbolic names for registers\n\
+-mno-regnames Do not allow symbolic names for registers\n"));
+#ifdef OBJ_ELF
+ fprintf (stream, _("\
+-mrelocatable support for GCC's -mrelocatble option\n\
+-mrelocatable-lib support for GCC's -mrelocatble-lib option\n\
+-memb set PPC_EMB bit in ELF flags\n\
+-mlittle, -mlittle-endian, -l, -le\n\
+ generate code for a little endian machine\n\
+-mbig, -mbig-endian, -b, -be\n\
+ generate code for a big endian machine\n\
+-msolaris generate code for Solaris\n\
+-mno-solaris do not generate code for Solaris\n\
+-V print assembler version number\n\
+-Qy, -Qn ignored\n"));
+#endif
+}
+
+/* Set ppc_cpu if it is not already set. */
+
+static void
+ppc_set_cpu ()
+{
+ const char *default_os = TARGET_OS;
+ const char *default_cpu = TARGET_CPU;
+
+ if ((ppc_cpu & ~PPC_OPCODE_ANY) == 0)
+ {
+ if (ppc_obj64)
+ ppc_cpu |= PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
+ else if (strncmp (default_os, "aix", 3) == 0
+ && default_os[3] >= '4' && default_os[3] <= '9')
+ ppc_cpu |= PPC_OPCODE_COMMON | PPC_OPCODE_32;
+ else if (strncmp (default_os, "aix3", 4) == 0)
+ ppc_cpu |= PPC_OPCODE_POWER | PPC_OPCODE_32;
+ else if (strcmp (default_cpu, "rs6000") == 0)
+ ppc_cpu |= PPC_OPCODE_POWER | PPC_OPCODE_32;
+ else if (strncmp (default_cpu, "powerpc", 7) == 0)
+ {
+ if (default_cpu[7] == '6' && default_cpu[8] == '4')
+ ppc_cpu |= PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
+ else
+ ppc_cpu |= PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32;
+ }
+ else
+ as_fatal (_("Unknown default cpu = %s, os = %s"),
+ default_cpu, default_os);
+ }
+}
+
+/* Figure out the BFD architecture to use. */
+
+enum bfd_architecture
+ppc_arch ()
+{
+ const char *default_cpu = TARGET_CPU;
+ ppc_set_cpu ();
+
+ if ((ppc_cpu & PPC_OPCODE_PPC) != 0)
+ return bfd_arch_powerpc;
+ else if ((ppc_cpu & PPC_OPCODE_POWER) != 0)
+ return bfd_arch_rs6000;
+ else if ((ppc_cpu & (PPC_OPCODE_COMMON | PPC_OPCODE_ANY)) != 0)
+ {
+ if (strcmp (default_cpu, "rs6000") == 0)
+ return bfd_arch_rs6000;
+ else if (strncmp (default_cpu, "powerpc", 7) == 0)
+ return bfd_arch_powerpc;
+ }
+
+ as_fatal (_("Neither Power nor PowerPC opcodes were selected."));
+ return bfd_arch_unknown;
+}
+
+unsigned long
+ppc_mach ()
+{
+ if (ppc_obj64)
+ return bfd_mach_ppc64;
+ else if (ppc_arch () == bfd_arch_rs6000)
+ return bfd_mach_rs6k;
+ else
+ return bfd_mach_ppc;
+}
+
+extern char*
+ppc_target_format ()
+{
+#ifdef OBJ_COFF
+#ifdef TE_PE
+ return target_big_endian ? "pe-powerpc" : "pe-powerpcle";
+#elif TE_POWERMAC
+ return "xcoff-powermac";
+#else
+# ifdef TE_AIX5
+ return (ppc_obj64 ? "aix5coff64-rs6000" : "aixcoff-rs6000");
+# else
+ return (ppc_obj64 ? "aixcoff64-rs6000" : "aixcoff-rs6000");
+# endif
+#endif
+#endif
+#ifdef OBJ_ELF
+ return (target_big_endian
+ ? (ppc_obj64 ? "elf64-powerpc" : "elf32-powerpc")
+ : (ppc_obj64 ? "elf64-powerpcle" : "elf32-powerpcle"));
+#endif
+}
+
+/* Insert opcodes and macros into hash tables. Called at startup and
+ for .cpu pseudo. */
+
+static void
+ppc_setup_opcodes (void)
+{
+ register const struct powerpc_opcode *op;
+ const struct powerpc_opcode *op_end;
+ const struct powerpc_macro *macro;
+ const struct powerpc_macro *macro_end;
+ bfd_boolean dup_insn = FALSE;
+
+ if (ppc_hash != NULL)
+ hash_die (ppc_hash);
+ if (ppc_macro_hash != NULL)
+ hash_die (ppc_macro_hash);
+
+ /* Insert the opcodes into a hash table. */
+ ppc_hash = hash_new ();
+
+ op_end = powerpc_opcodes + powerpc_num_opcodes;
+ for (op = powerpc_opcodes; op < op_end; op++)
+ {
+ know ((op->opcode & op->mask) == op->opcode);
+
+ if ((op->flags & ppc_cpu & ~(PPC_OPCODE_32 | PPC_OPCODE_64)) != 0
+ && ((op->flags & (PPC_OPCODE_32 | PPC_OPCODE_64)) == 0
+ || ((op->flags & (PPC_OPCODE_32 | PPC_OPCODE_64))
+ == (ppc_cpu & (PPC_OPCODE_32 | PPC_OPCODE_64)))
+ || (ppc_cpu & PPC_OPCODE_64_BRIDGE) != 0)
+ /* Certain instructions (eg: extsw) do not exist in the
+ 32-bit BookE instruction set, but they do exist in the
+ 64-bit BookE instruction set, and other PPC instruction
+ sets. Check to see if the opcode has the BOOKE64 flag set.
+ If it does make sure that the target CPU is not the BookE32. */
+ && ((op->flags & PPC_OPCODE_BOOKE64) == 0
+ || (ppc_cpu & PPC_OPCODE_BOOKE64) == PPC_OPCODE_BOOKE64
+ || (ppc_cpu & PPC_OPCODE_BOOKE) == 0)
+ && ((op->flags & (PPC_OPCODE_POWER4 | PPC_OPCODE_NOPOWER4)) == 0
+ || ((op->flags & PPC_OPCODE_POWER4)
+ == (ppc_cpu & PPC_OPCODE_POWER4))))
+ {
+ const char *retval;
+
+ retval = hash_insert (ppc_hash, op->name, (PTR) op);
+ if (retval != NULL)
+ {
+ /* Ignore Power duplicates for -m601. */
+ if ((ppc_cpu & PPC_OPCODE_601) != 0
+ && (op->flags & PPC_OPCODE_POWER) != 0)
+ continue;
+
+ as_bad (_("Internal assembler error for instruction %s"),
+ op->name);
+ dup_insn = TRUE;
+ }
+ }
+ }
+
+ if ((ppc_cpu & PPC_OPCODE_ANY) != 0)
+ for (op = powerpc_opcodes; op < op_end; op++)
+ hash_insert (ppc_hash, op->name, (PTR) op);
+
+ /* Insert the macros into a hash table. */
+ ppc_macro_hash = hash_new ();
+
+ macro_end = powerpc_macros + powerpc_num_macros;
+ for (macro = powerpc_macros; macro < macro_end; macro++)
+ {
+ if ((macro->flags & ppc_cpu) != 0)
+ {
+ const char *retval;
+
+ retval = hash_insert (ppc_macro_hash, macro->name, (PTR) macro);
+ if (retval != (const char *) NULL)
+ {
+ as_bad (_("Internal assembler error for macro %s"), macro->name);
+ dup_insn = TRUE;
+ }
+ }
+ }
+
+ if (dup_insn)
+ abort ();
+}
+
+/* This function is called when the assembler starts up. It is called
+ after the options have been parsed and the output file has been
+ opened. */
+
+void
+md_begin ()
+{
+ ppc_set_cpu ();
+
+ ppc_cie_data_alignment = ppc_obj64 ? -8 : -4;
+
+#ifdef OBJ_ELF
+ /* Set the ELF flags if desired. */
+ if (ppc_flags && !msolaris)
+ bfd_set_private_flags (stdoutput, ppc_flags);
+#endif
+
+ ppc_setup_opcodes ();
+
+ /* Tell the main code what the endianness is if it is not overridden
+ by the user. */
+ if (!set_target_endian)
+ {
+ set_target_endian = 1;
+ target_big_endian = PPC_BIG_ENDIAN;
+ }
+
+#ifdef OBJ_XCOFF
+ ppc_coff_debug_section = coff_section_from_bfd_index (stdoutput, N_DEBUG);
+
+ /* Create dummy symbols to serve as initial csects. This forces the
+ text csects to precede the data csects. These symbols will not
+ be output. */
+ ppc_text_csects = symbol_make ("dummy\001");
+ symbol_get_tc (ppc_text_csects)->within = ppc_text_csects;
+ ppc_data_csects = symbol_make ("dummy\001");
+ symbol_get_tc (ppc_data_csects)->within = ppc_data_csects;
+#endif
+
+#ifdef TE_PE
+
+ ppc_current_section = text_section;
+ ppc_previous_section = 0;
+
+#endif
+}
+
+void
+ppc_cleanup ()
+{
+#ifdef OBJ_ELF
+ if (ppc_apuinfo_list == NULL)
+ return;
+
+ /* Ok, so write the section info out. We have this layout:
+
+ byte data what
+ ---- ---- ----
+ 0 8 length of "APUinfo\0"
+ 4 (n*4) number of APU's (4 bytes each)
+ 8 2 note type 2
+ 12 "APUinfo\0" name
+ 20 APU#1 first APU's info
+ 24 APU#2 second APU's info
+ ... ...
+ */
+ {
+ char *p;
+ asection *seg = now_seg;
+ subsegT subseg = now_subseg;
+ asection *apuinfo_secp = (asection *) NULL;
+ unsigned int i;
+
+ /* Create the .PPC.EMB.apuinfo section. */
+ apuinfo_secp = subseg_new (".PPC.EMB.apuinfo", 0);
+ bfd_set_section_flags (stdoutput,
+ apuinfo_secp,
+ SEC_HAS_CONTENTS | SEC_READONLY);
+
+ p = frag_more (4);
+ md_number_to_chars (p, (valueT) 8, 4);
+
+ p = frag_more (4);
+ md_number_to_chars (p, (valueT) ppc_apuinfo_num * 4, 4);
+
+ p = frag_more (4);
+ md_number_to_chars (p, (valueT) 2, 4);
+
+ p = frag_more (8);
+ strcpy (p, "APUinfo");
+
+ for (i = 0; i < ppc_apuinfo_num; i++)
+ {
+ p = frag_more (4);
+ md_number_to_chars (p, (valueT) ppc_apuinfo_list[i], 4);
+ }
+
+ frag_align (2, 0, 0);
+
+ /* We probably can't restore the current segment, for there likely
+ isn't one yet... */
+ if (seg && subseg)
+ subseg_set (seg, subseg);
+ }
+#endif
+}
+
+/* Insert an operand value into an instruction. */
+
+static unsigned long
+ppc_insert_operand (insn, operand, val, file, line)
+ unsigned long insn;
+ const struct powerpc_operand *operand;
+ offsetT val;
+ char *file;
+ unsigned int line;
+{
+ if (operand->bits != 32)
+ {
+ long min, max;
+ offsetT test;
+
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+ {
+ if ((operand->flags & PPC_OPERAND_SIGNOPT) != 0)
+ max = (1 << operand->bits) - 1;
+ else
+ max = (1 << (operand->bits - 1)) - 1;
+ min = - (1 << (operand->bits - 1));
+
+ if (!ppc_obj64)
+ {
+ /* Some people write 32 bit hex constants with the sign
+ extension done by hand. This shouldn't really be
+ valid, but, to permit this code to assemble on a 64
+ bit host, we sign extend the 32 bit value. */
+ if (val > 0
+ && (val & (offsetT) 0x80000000) != 0
+ && (val & (offsetT) 0xffffffff) == val)
+ {
+ val -= 0x80000000;
+ val -= 0x80000000;
+ }
+ }
+ }
+ else
+ {
+ max = (1 << operand->bits) - 1;
+ min = 0;
+ }
+
+ if ((operand->flags & PPC_OPERAND_NEGATIVE) != 0)
+ test = - val;
+ else
+ test = val;
+
+ if (test < (offsetT) min || test > (offsetT) max)
+ {
+ const char *err =
+ _("operand out of range (%s not between %ld and %ld)");
+ char buf[100];
+
+ sprint_value (buf, test);
+ as_bad_where (file, line, err, buf, min, max);
+ }
+ }
+
+ if (operand->insert)
+ {
+ const char *errmsg;
+
+ errmsg = NULL;
+ insn = (*operand->insert) (insn, (long) val, ppc_cpu, &errmsg);
+ if (errmsg != (const char *) NULL)
+ as_bad_where (file, line, errmsg);
+ }
+ else
+ insn |= (((long) val & ((1 << operand->bits) - 1))
+ << operand->shift);
+
+ return insn;
+}
+
+
+#ifdef OBJ_ELF
+/* Parse @got, etc. and return the desired relocation. */
+static bfd_reloc_code_real_type
+ppc_elf_suffix (str_p, exp_p)
+ char **str_p;
+ expressionS *exp_p;
+{
+ struct map_bfd {
+ char *string;
+ unsigned int length : 8;
+ unsigned int valid32 : 1;
+ unsigned int valid64 : 1;
+ unsigned int reloc;
+ };
+
+ char ident[20];
+ char *str = *str_p;
+ char *str2;
+ int ch;
+ int len;
+ const struct map_bfd *ptr;
+
+#define MAP(str, reloc) { str, sizeof (str) - 1, 1, 1, reloc }
+#define MAP32(str, reloc) { str, sizeof (str) - 1, 1, 0, reloc }
+#define MAP64(str, reloc) { str, sizeof (str) - 1, 0, 1, reloc }
+
+ static const struct map_bfd mapping[] = {
+ MAP ("l", BFD_RELOC_LO16),
+ MAP ("h", BFD_RELOC_HI16),
+ MAP ("ha", BFD_RELOC_HI16_S),
+ MAP ("brtaken", BFD_RELOC_PPC_B16_BRTAKEN),
+ MAP ("brntaken", BFD_RELOC_PPC_B16_BRNTAKEN),
+ MAP ("got", BFD_RELOC_16_GOTOFF),
+ MAP ("got@l", BFD_RELOC_LO16_GOTOFF),
+ MAP ("got@h", BFD_RELOC_HI16_GOTOFF),
+ MAP ("got@ha", BFD_RELOC_HI16_S_GOTOFF),
+ MAP ("plt@l", BFD_RELOC_LO16_PLTOFF),
+ MAP ("plt@h", BFD_RELOC_HI16_PLTOFF),
+ MAP ("plt@ha", BFD_RELOC_HI16_S_PLTOFF),
+ MAP ("copy", BFD_RELOC_PPC_COPY),
+ MAP ("globdat", BFD_RELOC_PPC_GLOB_DAT),
+ MAP ("sectoff", BFD_RELOC_16_BASEREL),
+ MAP ("sectoff@l", BFD_RELOC_LO16_BASEREL),
+ MAP ("sectoff@h", BFD_RELOC_HI16_BASEREL),
+ MAP ("sectoff@ha", BFD_RELOC_HI16_S_BASEREL),
+ MAP ("tls", BFD_RELOC_PPC_TLS),
+ MAP ("dtpmod", BFD_RELOC_PPC_DTPMOD),
+ MAP ("dtprel", BFD_RELOC_PPC_DTPREL),
+ MAP ("dtprel@l", BFD_RELOC_PPC_DTPREL16_LO),
+ MAP ("dtprel@h", BFD_RELOC_PPC_DTPREL16_HI),
+ MAP ("dtprel@ha", BFD_RELOC_PPC_DTPREL16_HA),
+ MAP ("tprel", BFD_RELOC_PPC_TPREL),
+ MAP ("tprel@l", BFD_RELOC_PPC_TPREL16_LO),
+ MAP ("tprel@h", BFD_RELOC_PPC_TPREL16_HI),
+ MAP ("tprel@ha", BFD_RELOC_PPC_TPREL16_HA),
+ MAP ("got@tlsgd", BFD_RELOC_PPC_GOT_TLSGD16),
+ MAP ("got@tlsgd@l", BFD_RELOC_PPC_GOT_TLSGD16_LO),
+ MAP ("got@tlsgd@h", BFD_RELOC_PPC_GOT_TLSGD16_HI),
+ MAP ("got@tlsgd@ha", BFD_RELOC_PPC_GOT_TLSGD16_HA),
+ MAP ("got@tlsld", BFD_RELOC_PPC_GOT_TLSLD16),
+ MAP ("got@tlsld@l", BFD_RELOC_PPC_GOT_TLSLD16_LO),
+ MAP ("got@tlsld@h", BFD_RELOC_PPC_GOT_TLSLD16_HI),
+ MAP ("got@tlsld@ha", BFD_RELOC_PPC_GOT_TLSLD16_HA),
+ MAP ("got@dtprel", BFD_RELOC_PPC_GOT_DTPREL16),
+ MAP ("got@dtprel@l", BFD_RELOC_PPC_GOT_DTPREL16_LO),
+ MAP ("got@dtprel@h", BFD_RELOC_PPC_GOT_DTPREL16_HI),
+ MAP ("got@dtprel@ha", BFD_RELOC_PPC_GOT_DTPREL16_HA),
+ MAP ("got@tprel", BFD_RELOC_PPC_GOT_TPREL16),
+ MAP ("got@tprel@l", BFD_RELOC_PPC_GOT_TPREL16_LO),
+ MAP ("got@tprel@h", BFD_RELOC_PPC_GOT_TPREL16_HI),
+ MAP ("got@tprel@ha", BFD_RELOC_PPC_GOT_TPREL16_HA),
+ MAP32 ("fixup", BFD_RELOC_CTOR),
+ MAP32 ("plt", BFD_RELOC_24_PLT_PCREL),
+ MAP32 ("pltrel24", BFD_RELOC_24_PLT_PCREL),
+ MAP32 ("local24pc", BFD_RELOC_PPC_LOCAL24PC),
+ MAP32 ("local", BFD_RELOC_PPC_LOCAL24PC),
+ MAP32 ("pltrel", BFD_RELOC_32_PLT_PCREL),
+ MAP32 ("sdarel", BFD_RELOC_GPREL16),
+ MAP32 ("naddr", BFD_RELOC_PPC_EMB_NADDR32),
+ MAP32 ("naddr16", BFD_RELOC_PPC_EMB_NADDR16),
+ MAP32 ("naddr@l", BFD_RELOC_PPC_EMB_NADDR16_LO),
+ MAP32 ("naddr@h", BFD_RELOC_PPC_EMB_NADDR16_HI),
+ MAP32 ("naddr@ha", BFD_RELOC_PPC_EMB_NADDR16_HA),
+ MAP32 ("sdai16", BFD_RELOC_PPC_EMB_SDAI16),
+ MAP32 ("sda2rel", BFD_RELOC_PPC_EMB_SDA2REL),
+ MAP32 ("sda2i16", BFD_RELOC_PPC_EMB_SDA2I16),
+ MAP32 ("sda21", BFD_RELOC_PPC_EMB_SDA21),
+ MAP32 ("mrkref", BFD_RELOC_PPC_EMB_MRKREF),
+ MAP32 ("relsect", BFD_RELOC_PPC_EMB_RELSEC16),
+ MAP32 ("relsect@l", BFD_RELOC_PPC_EMB_RELST_LO),
+ MAP32 ("relsect@h", BFD_RELOC_PPC_EMB_RELST_HI),
+ MAP32 ("relsect@ha", BFD_RELOC_PPC_EMB_RELST_HA),
+ MAP32 ("bitfld", BFD_RELOC_PPC_EMB_BIT_FLD),
+ MAP32 ("relsda", BFD_RELOC_PPC_EMB_RELSDA),
+ MAP32 ("xgot", BFD_RELOC_PPC_TOC16),
+ MAP64 ("higher", BFD_RELOC_PPC64_HIGHER),
+ MAP64 ("highera", BFD_RELOC_PPC64_HIGHER_S),
+ MAP64 ("highest", BFD_RELOC_PPC64_HIGHEST),
+ MAP64 ("highesta", BFD_RELOC_PPC64_HIGHEST_S),
+ MAP64 ("tocbase", BFD_RELOC_PPC64_TOC),
+ MAP64 ("toc", BFD_RELOC_PPC_TOC16),
+ MAP64 ("toc@l", BFD_RELOC_PPC64_TOC16_LO),
+ MAP64 ("toc@h", BFD_RELOC_PPC64_TOC16_HI),
+ MAP64 ("toc@ha", BFD_RELOC_PPC64_TOC16_HA),
+ MAP64 ("dtprel@higher", BFD_RELOC_PPC64_DTPREL16_HIGHER),
+ MAP64 ("dtprel@highera", BFD_RELOC_PPC64_DTPREL16_HIGHERA),
+ MAP64 ("dtprel@highest", BFD_RELOC_PPC64_DTPREL16_HIGHEST),
+ MAP64 ("dtprel@highesta", BFD_RELOC_PPC64_DTPREL16_HIGHESTA),
+ MAP64 ("tprel@higher", BFD_RELOC_PPC64_TPREL16_HIGHER),
+ MAP64 ("tprel@highera", BFD_RELOC_PPC64_TPREL16_HIGHERA),
+ MAP64 ("tprel@highest", BFD_RELOC_PPC64_TPREL16_HIGHEST),
+ MAP64 ("tprel@highesta", BFD_RELOC_PPC64_TPREL16_HIGHESTA),
+ { (char *) 0, 0, 0, 0, BFD_RELOC_UNUSED }
+ };
+
+ if (*str++ != '@')
+ return BFD_RELOC_UNUSED;
+
+ for (ch = *str, str2 = ident;
+ (str2 < ident + sizeof (ident) - 1
+ && (ISALNUM (ch) || ch == '@'));
+ ch = *++str)
+ {
+ *str2++ = TOLOWER (ch);
+ }
+
+ *str2 = '\0';
+ len = str2 - ident;
+
+ ch = ident[0];
+ for (ptr = &mapping[0]; ptr->length > 0; ptr++)
+ if (ch == ptr->string[0]
+ && len == ptr->length
+ && memcmp (ident, ptr->string, ptr->length) == 0
+ && (ppc_obj64 ? ptr->valid64 : ptr->valid32))
+ {
+ int reloc = ptr->reloc;
+
+ if (!ppc_obj64)
+ if (exp_p->X_add_number != 0
+ && (reloc == (int) BFD_RELOC_16_GOTOFF
+ || reloc == (int) BFD_RELOC_LO16_GOTOFF
+ || reloc == (int) BFD_RELOC_HI16_GOTOFF
+ || reloc == (int) BFD_RELOC_HI16_S_GOTOFF))
+ as_warn (_("identifier+constant@got means identifier@got+constant"));
+
+ /* Now check for identifier@suffix+constant. */
+ if (*str == '-' || *str == '+')
+ {
+ char *orig_line = input_line_pointer;
+ expressionS new_exp;
+
+ input_line_pointer = str;
+ expression (&new_exp);
+ if (new_exp.X_op == O_constant)
+ {
+ exp_p->X_add_number += new_exp.X_add_number;
+ str = input_line_pointer;
+ }
+
+ if (&input_line_pointer != str_p)
+ input_line_pointer = orig_line;
+ }
+ *str_p = str;
+
+ if (reloc == (int) BFD_RELOC_PPC64_TOC
+ && exp_p->X_op == O_symbol
+ && strcmp (S_GET_NAME (exp_p->X_add_symbol), ".TOC.") == 0)
+ {
+ /* Change the symbol so that the dummy .TOC. symbol can be
+ omitted from the object file. */
+ exp_p->X_add_symbol = &abs_symbol;
+ }
+
+ return (bfd_reloc_code_real_type) reloc;
+ }
+
+ return BFD_RELOC_UNUSED;
+}
+
+/* Like normal .long/.short/.word, except support @got, etc.
+ Clobbers input_line_pointer, checks end-of-line. */
+static void
+ppc_elf_cons (nbytes)
+ register int nbytes; /* 1=.byte, 2=.word, 4=.long, 8=.llong. */
+{
+ expressionS exp;
+ bfd_reloc_code_real_type reloc;
+
+ if (is_it_end_of_statement ())
+ {
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ do
+ {
+ expression (&exp);
+ if (exp.X_op == O_symbol
+ && *input_line_pointer == '@'
+ && (reloc = ppc_elf_suffix (&input_line_pointer,
+ &exp)) != BFD_RELOC_UNUSED)
+ {
+ reloc_howto_type *reloc_howto;
+ int size;
+
+ reloc_howto = bfd_reloc_type_lookup (stdoutput, reloc);
+ size = bfd_get_reloc_size (reloc_howto);
+
+ if (size > nbytes)
+ {
+ as_bad (_("%s relocations do not fit in %d bytes\n"),
+ reloc_howto->name, nbytes);
+ }
+ else
+ {
+ char *p;
+ int offset;
+
+ p = frag_more (nbytes);
+ offset = 0;
+ if (target_big_endian)
+ offset = nbytes - size;
+ fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
+ &exp, 0, reloc);
+ }
+ }
+ else
+ emit_expr (&exp, (unsigned int) nbytes);
+ }
+ while (*input_line_pointer++ == ',');
+
+ /* Put terminator back into stream. */
+ input_line_pointer--;
+ demand_empty_rest_of_line ();
+}
+
+/* Solaris pseduo op to change to the .rodata section. */
+static void
+ppc_elf_rdata (xxx)
+ int xxx;
+{
+ char *save_line = input_line_pointer;
+ static char section[] = ".rodata\n";
+
+ /* Just pretend this is .section .rodata */
+ input_line_pointer = section;
+ obj_elf_section (xxx);
+
+ input_line_pointer = save_line;
+}
+
+/* Pseudo op to make file scope bss items. */
+static void
+ppc_elf_lcomm (xxx)
+ int xxx ATTRIBUTE_UNUSED;
+{
+ register char *name;
+ register char c;
+ register char *p;
+ offsetT size;
+ register symbolS *symbolP;
+ offsetT align;
+ segT old_sec;
+ int old_subsec;
+ char *pfrag;
+ int align2;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ /* just after name is now '\0'. */
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after symbol-name: rest of line ignored."));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ input_line_pointer++; /* skip ',' */
+ if ((size = get_absolute_expression ()) < 0)
+ {
+ as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
+ ignore_rest_of_line ();
+ return;
+ }
+
+ /* The third argument to .lcomm is the alignment. */
+ if (*input_line_pointer != ',')
+ align = 8;
+ else
+ {
+ ++input_line_pointer;
+ align = get_absolute_expression ();
+ if (align <= 0)
+ {
+ as_warn (_("ignoring bad alignment"));
+ align = 8;
+ }
+ }
+
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+
+ if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
+ {
+ as_bad (_("Ignoring attempt to re-define symbol `%s'."),
+ S_GET_NAME (symbolP));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
+ {
+ as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
+ S_GET_NAME (symbolP),
+ (long) S_GET_VALUE (symbolP),
+ (long) size);
+
+ ignore_rest_of_line ();
+ return;
+ }
+
+ /* Allocate_bss. */
+ old_sec = now_seg;
+ old_subsec = now_subseg;
+ if (align)
+ {
+ /* Convert to a power of 2 alignment. */
+ for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2);
+ if (align != 1)
+ {
+ as_bad (_("Common alignment not a power of 2"));
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ else
+ align2 = 0;
+
+ record_alignment (bss_section, align2);
+ subseg_set (bss_section, 0);
+ if (align2)
+ frag_align (align2, 0, 0);
+ if (S_GET_SEGMENT (symbolP) == bss_section)
+ symbol_get_frag (symbolP)->fr_symbol = 0;
+ symbol_set_frag (symbolP, frag_now);
+ pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
+ (char *) 0);
+ *pfrag = 0;
+ S_SET_SIZE (symbolP, size);
+ S_SET_SEGMENT (symbolP, bss_section);
+ subseg_set (old_sec, old_subsec);
+ demand_empty_rest_of_line ();
+}
+
+/* Validate any relocations emitted for -mrelocatable, possibly adding
+ fixups for word relocations in writable segments, so we can adjust
+ them at runtime. */
+static void
+ppc_elf_validate_fix (fixp, seg)
+ fixS *fixp;
+ segT seg;
+{
+ if (fixp->fx_done || fixp->fx_pcrel)
+ return;
+
+ switch (shlib)
+ {
+ case SHLIB_NONE:
+ case SHLIB_PIC:
+ return;
+
+ case SHLIB_MRELOCATABLE:
+ if (fixp->fx_r_type <= BFD_RELOC_UNUSED
+ && fixp->fx_r_type != BFD_RELOC_16_GOTOFF
+ && fixp->fx_r_type != BFD_RELOC_HI16_GOTOFF
+ && fixp->fx_r_type != BFD_RELOC_LO16_GOTOFF
+ && fixp->fx_r_type != BFD_RELOC_HI16_S_GOTOFF
+ && fixp->fx_r_type != BFD_RELOC_16_BASEREL
+ && fixp->fx_r_type != BFD_RELOC_LO16_BASEREL
+ && fixp->fx_r_type != BFD_RELOC_HI16_BASEREL
+ && fixp->fx_r_type != BFD_RELOC_HI16_S_BASEREL
+ && (seg->flags & SEC_LOAD) != 0
+ && strcmp (segment_name (seg), ".got2") != 0
+ && strcmp (segment_name (seg), ".dtors") != 0
+ && strcmp (segment_name (seg), ".ctors") != 0
+ && strcmp (segment_name (seg), ".fixup") != 0
+ && strcmp (segment_name (seg), ".gcc_except_table") != 0
+ && strcmp (segment_name (seg), ".eh_frame") != 0
+ && strcmp (segment_name (seg), ".ex_shared") != 0)
+ {
+ if ((seg->flags & (SEC_READONLY | SEC_CODE)) != 0
+ || fixp->fx_r_type != BFD_RELOC_CTOR)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Relocation cannot be done when using -mrelocatable"));
+ }
+ }
+ return;
+ }
+}
+
+/* Prevent elf_frob_file_before_adjust removing a weak undefined
+ function descriptor sym if the corresponding code sym is used. */
+
+void
+ppc_frob_file_before_adjust ()
+{
+ symbolS *symp;
+
+ if (!ppc_obj64)
+ return;
+
+ for (symp = symbol_rootP; symp; symp = symbol_next (symp))
+ {
+ const char *name;
+ char *dotname;
+ symbolS *dotsym;
+ size_t len;
+
+ name = S_GET_NAME (symp);
+ if (name[0] == '.')
+ continue;
+
+ if (! S_IS_WEAK (symp)
+ || S_IS_DEFINED (symp))
+ continue;
+
+ len = strlen (name) + 1;
+ dotname = xmalloc (len + 1);
+ dotname[0] = '.';
+ memcpy (dotname + 1, name, len);
+ dotsym = symbol_find (dotname);
+ free (dotname);
+ if (dotsym != NULL && (symbol_used_p (dotsym)
+ || symbol_used_in_reloc_p (dotsym)))
+ {
+ symbol_mark_used (symp);
+ }
+ }
+
+ /* Don't emit .TOC. symbol. */
+ symp = symbol_find (".TOC.");
+ if (symp != NULL)
+ symbol_remove (symp, &symbol_rootP, &symbol_lastP);
+}
+#endif /* OBJ_ELF */
+
+#ifdef TE_PE
+
+/*
+ * Summary of parse_toc_entry.
+ *
+ * in: Input_line_pointer points to the '[' in one of:
+ *
+ * [toc] [tocv] [toc32] [toc64]
+ *
+ * Anything else is an error of one kind or another.
+ *
+ * out:
+ * return value: success or failure
+ * toc_kind: kind of toc reference
+ * input_line_pointer:
+ * success: first char after the ']'
+ * failure: unchanged
+ *
+ * settings:
+ *
+ * [toc] - rv == success, toc_kind = default_toc
+ * [tocv] - rv == success, toc_kind = data_in_toc
+ * [toc32] - rv == success, toc_kind = must_be_32
+ * [toc64] - rv == success, toc_kind = must_be_64
+ *
+ */
+
+enum toc_size_qualifier
+{
+ default_toc, /* The toc cell constructed should be the system default size */
+ data_in_toc, /* This is a direct reference to a toc cell */
+ must_be_32, /* The toc cell constructed must be 32 bits wide */
+ must_be_64 /* The toc cell constructed must be 64 bits wide */
+};
+
+static int
+parse_toc_entry (toc_kind)
+ enum toc_size_qualifier *toc_kind;
+{
+ char *start;
+ char *toc_spec;
+ char c;
+ enum toc_size_qualifier t;
+
+ /* Save the input_line_pointer. */
+ start = input_line_pointer;
+
+ /* Skip over the '[' , and whitespace. */
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+
+ /* Find the spelling of the operand. */
+ toc_spec = input_line_pointer;
+ c = get_symbol_end ();
+
+ if (strcmp (toc_spec, "toc") == 0)
+ {
+ t = default_toc;
+ }
+ else if (strcmp (toc_spec, "tocv") == 0)
+ {
+ t = data_in_toc;
+ }
+ else if (strcmp (toc_spec, "toc32") == 0)
+ {
+ t = must_be_32;
+ }
+ else if (strcmp (toc_spec, "toc64") == 0)
+ {
+ t = must_be_64;
+ }
+ else
+ {
+ as_bad (_("syntax error: invalid toc specifier `%s'"), toc_spec);
+ *input_line_pointer = c;
+ input_line_pointer = start;
+ return 0;
+ }
+
+ /* Now find the ']'. */
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE (); /* leading whitespace could be there. */
+ c = *input_line_pointer++; /* input_line_pointer->past char in c. */
+
+ if (c != ']')
+ {
+ as_bad (_("syntax error: expected `]', found `%c'"), c);
+ input_line_pointer = start;
+ return 0;
+ }
+
+ *toc_kind = t;
+ return 1;
+}
+#endif
+
+
+#ifdef OBJ_ELF
+#define APUID(a,v) ((((a) & 0xffff) << 16) | ((v) & 0xffff))
+static void
+ppc_apuinfo_section_add (apu, version)
+ unsigned int apu, version;
+{
+ unsigned int i;
+
+ /* Check we don't already exist. */
+ for (i = 0; i < ppc_apuinfo_num; i++)
+ if (ppc_apuinfo_list[i] == APUID (apu, version))
+ return;
+
+ if (ppc_apuinfo_num == ppc_apuinfo_num_alloc)
+ {
+ if (ppc_apuinfo_num_alloc == 0)
+ {
+ ppc_apuinfo_num_alloc = 4;
+ ppc_apuinfo_list = (unsigned long *)
+ xmalloc (sizeof (unsigned long) * ppc_apuinfo_num_alloc);
+ }
+ else
+ {
+ ppc_apuinfo_num_alloc += 4;
+ ppc_apuinfo_list = (unsigned long *) xrealloc (ppc_apuinfo_list,
+ sizeof (unsigned long) * ppc_apuinfo_num_alloc);
+ }
+ }
+ ppc_apuinfo_list[ppc_apuinfo_num++] = APUID (apu, version);
+}
+#undef APUID
+#endif
+
+
+/* We need to keep a list of fixups. We can't simply generate them as
+ we go, because that would require us to first create the frag, and
+ that would screw up references to ``.''. */
+
+struct ppc_fixup
+{
+ expressionS exp;
+ int opindex;
+ bfd_reloc_code_real_type reloc;
+};
+
+#define MAX_INSN_FIXUPS (5)
+
+/* This routine is called for each instruction to be assembled. */
+
+void
+md_assemble (str)
+ char *str;
+{
+ char *s;
+ const struct powerpc_opcode *opcode;
+ unsigned long insn;
+ const unsigned char *opindex_ptr;
+ int skip_optional;
+ int need_paren;
+ int next_opindex;
+ struct ppc_fixup fixups[MAX_INSN_FIXUPS];
+ int fc;
+ char *f;
+ int i;
+#ifdef OBJ_ELF
+ bfd_reloc_code_real_type reloc;
+#endif
+
+ /* Get the opcode. */
+ for (s = str; *s != '\0' && ! ISSPACE (*s); s++)
+ ;
+ if (*s != '\0')
+ *s++ = '\0';
+
+ /* Look up the opcode in the hash table. */
+ opcode = (const struct powerpc_opcode *) hash_find (ppc_hash, str);
+ if (opcode == (const struct powerpc_opcode *) NULL)
+ {
+ const struct powerpc_macro *macro;
+
+ macro = (const struct powerpc_macro *) hash_find (ppc_macro_hash, str);
+ if (macro == (const struct powerpc_macro *) NULL)
+ as_bad (_("Unrecognized opcode: `%s'"), str);
+ else
+ ppc_macro (s, macro);
+
+ return;
+ }
+
+ insn = opcode->opcode;
+
+ str = s;
+ while (ISSPACE (*str))
+ ++str;
+
+ /* PowerPC operands are just expressions. The only real issue is
+ that a few operand types are optional. All cases which might use
+ an optional operand separate the operands only with commas (in some
+ cases parentheses are used, as in ``lwz 1,0(1)'' but such cases never
+ have optional operands). Most instructions with optional operands
+ have only one. Those that have more than one optional operand can
+ take either all their operands or none. So, before we start seriously
+ parsing the operands, we check to see if we have optional operands,
+ and if we do, we count the number of commas to see which operands
+ have been omitted. */
+ skip_optional = 0;
+ for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
+ {
+ const struct powerpc_operand *operand;
+
+ operand = &powerpc_operands[*opindex_ptr];
+ if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
+ {
+ unsigned int opcount;
+ unsigned int num_operands_expected;
+ unsigned int i;
+
+ /* There is an optional operand. Count the number of
+ commas in the input line. */
+ if (*str == '\0')
+ opcount = 0;
+ else
+ {
+ opcount = 1;
+ s = str;
+ while ((s = strchr (s, ',')) != (char *) NULL)
+ {
+ ++opcount;
+ ++s;
+ }
+ }
+
+ /* Compute the number of expected operands.
+ Do not count fake operands. */
+ for (num_operands_expected = 0, i = 0; opcode->operands[i]; i ++)
+ if ((powerpc_operands [opcode->operands[i]].flags & PPC_OPERAND_FAKE) == 0)
+ ++ num_operands_expected;
+
+ /* If there are fewer operands in the line then are called
+ for by the instruction, we want to skip the optional
+ operands. */
+ if (opcount < num_operands_expected)
+ skip_optional = 1;
+
+ break;
+ }
+ }
+
+ /* Gather the operands. */
+ need_paren = 0;
+ next_opindex = 0;
+ fc = 0;
+ for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
+ {
+ const struct powerpc_operand *operand;
+ const char *errmsg;
+ char *hold;
+ expressionS ex;
+ char endc;
+
+ if (next_opindex == 0)
+ operand = &powerpc_operands[*opindex_ptr];
+ else
+ {
+ operand = &powerpc_operands[next_opindex];
+ next_opindex = 0;
+ }
+ errmsg = NULL;
+
+ /* If this is a fake operand, then we do not expect anything
+ from the input. */
+ if ((operand->flags & PPC_OPERAND_FAKE) != 0)
+ {
+ insn = (*operand->insert) (insn, 0L, ppc_cpu, &errmsg);
+ if (errmsg != (const char *) NULL)
+ as_bad (errmsg);
+ continue;
+ }
+
+ /* If this is an optional operand, and we are skipping it, just
+ insert a zero. */
+ if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
+ && skip_optional)
+ {
+ if (operand->insert)
+ {
+ insn = (*operand->insert) (insn, 0L, ppc_cpu, &errmsg);
+ if (errmsg != (const char *) NULL)
+ as_bad (errmsg);
+ }
+ if ((operand->flags & PPC_OPERAND_NEXT) != 0)
+ next_opindex = *opindex_ptr + 1;
+ continue;
+ }
+
+ /* Gather the operand. */
+ hold = input_line_pointer;
+ input_line_pointer = str;
+
+#ifdef TE_PE
+ if (*input_line_pointer == '[')
+ {
+ /* We are expecting something like the second argument here:
+ *
+ * lwz r4,[toc].GS.0.static_int(rtoc)
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * The argument following the `]' must be a symbol name, and the
+ * register must be the toc register: 'rtoc' or '2'
+ *
+ * The effect is to 0 as the displacement field
+ * in the instruction, and issue an IMAGE_REL_PPC_TOCREL16 (or
+ * the appropriate variation) reloc against it based on the symbol.
+ * The linker will build the toc, and insert the resolved toc offset.
+ *
+ * Note:
+ * o The size of the toc entry is currently assumed to be
+ * 32 bits. This should not be assumed to be a hard coded
+ * number.
+ * o In an effort to cope with a change from 32 to 64 bits,
+ * there are also toc entries that are specified to be
+ * either 32 or 64 bits:
+ * lwz r4,[toc32].GS.0.static_int(rtoc)
+ * lwz r4,[toc64].GS.0.static_int(rtoc)
+ * These demand toc entries of the specified size, and the
+ * instruction probably requires it.
+ */
+
+ int valid_toc;
+ enum toc_size_qualifier toc_kind;
+ bfd_reloc_code_real_type toc_reloc;
+
+ /* Go parse off the [tocXX] part. */
+ valid_toc = parse_toc_entry (&toc_kind);
+
+ if (!valid_toc)
+ {
+ /* Note: message has already been issued.
+ FIXME: what sort of recovery should we do?
+ demand_rest_of_line (); return; ? */
+ }
+
+ /* Now get the symbol following the ']'. */
+ expression (&ex);
+
+ switch (toc_kind)
+ {
+ case default_toc:
+ /* In this case, we may not have seen the symbol yet,
+ since it is allowed to appear on a .extern or .globl
+ or just be a label in the .data section. */
+ toc_reloc = BFD_RELOC_PPC_TOC16;
+ break;
+ case data_in_toc:
+ /* 1. The symbol must be defined and either in the toc
+ section, or a global.
+ 2. The reloc generated must have the TOCDEFN flag set
+ in upper bit mess of the reloc type.
+ FIXME: It's a little confusing what the tocv
+ qualifier can be used for. At the very least, I've
+ seen three uses, only one of which I'm sure I can
+ explain. */
+ if (ex.X_op == O_symbol)
+ {
+ assert (ex.X_add_symbol != NULL);
+ if (symbol_get_bfdsym (ex.X_add_symbol)->section
+ != tocdata_section)
+ {
+ as_bad (_("[tocv] symbol is not a toc symbol"));
+ }
+ }
+
+ toc_reloc = BFD_RELOC_PPC_TOC16;
+ break;
+ case must_be_32:
+ /* FIXME: these next two specifically specify 32/64 bit
+ toc entries. We don't support them today. Is this
+ the right way to say that? */
+ toc_reloc = BFD_RELOC_UNUSED;
+ as_bad (_("Unimplemented toc32 expression modifier"));
+ break;
+ case must_be_64:
+ /* FIXME: see above. */
+ toc_reloc = BFD_RELOC_UNUSED;
+ as_bad (_("Unimplemented toc64 expression modifier"));
+ break;
+ default:
+ fprintf (stderr,
+ _("Unexpected return value [%d] from parse_toc_entry!\n"),
+ toc_kind);
+ abort ();
+ break;
+ }
+
+ /* We need to generate a fixup for this expression. */
+ if (fc >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+
+ fixups[fc].reloc = toc_reloc;
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = *opindex_ptr;
+ ++fc;
+
+ /* Ok. We've set up the fixup for the instruction. Now make it
+ look like the constant 0 was found here. */
+ ex.X_unsigned = 1;
+ ex.X_op = O_constant;
+ ex.X_add_number = 0;
+ ex.X_add_symbol = NULL;
+ ex.X_op_symbol = NULL;
+ }
+
+ else
+#endif /* TE_PE */
+ {
+ if (! register_name (&ex))
+ {
+ if ((operand->flags & PPC_OPERAND_CR) != 0)
+ cr_operand = TRUE;
+ expression (&ex);
+ cr_operand = FALSE;
+ }
+ }
+
+ str = input_line_pointer;
+ input_line_pointer = hold;
+
+ if (ex.X_op == O_illegal)
+ as_bad (_("illegal operand"));
+ else if (ex.X_op == O_absent)
+ as_bad (_("missing operand"));
+ else if (ex.X_op == O_register)
+ {
+ insn = ppc_insert_operand (insn, operand, ex.X_add_number,
+ (char *) NULL, 0);
+ }
+ else if (ex.X_op == O_constant)
+ {
+#ifdef OBJ_ELF
+ /* Allow @HA, @L, @H on constants. */
+ char *orig_str = str;
+
+ if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
+ switch (reloc)
+ {
+ default:
+ str = orig_str;
+ break;
+
+ case BFD_RELOC_LO16:
+ /* X_unsigned is the default, so if the user has done
+ something which cleared it, we always produce a
+ signed value. */
+ if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
+ ex.X_add_number &= 0xffff;
+ else
+ ex.X_add_number = SEX16 (ex.X_add_number);
+ break;
+
+ case BFD_RELOC_HI16:
+ if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
+ ex.X_add_number = PPC_HI (ex.X_add_number);
+ else
+ ex.X_add_number = SEX16 (PPC_HI (ex.X_add_number));
+ break;
+
+ case BFD_RELOC_HI16_S:
+ if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
+ ex.X_add_number = PPC_HA (ex.X_add_number);
+ else
+ ex.X_add_number = SEX16 (PPC_HA (ex.X_add_number));
+ break;
+
+ case BFD_RELOC_PPC64_HIGHER:
+ if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
+ ex.X_add_number = PPC_HIGHER (ex.X_add_number);
+ else
+ ex.X_add_number = SEX16 (PPC_HIGHER (ex.X_add_number));
+ break;
+
+ case BFD_RELOC_PPC64_HIGHER_S:
+ if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
+ ex.X_add_number = PPC_HIGHERA (ex.X_add_number);
+ else
+ ex.X_add_number = SEX16 (PPC_HIGHERA (ex.X_add_number));
+ break;
+
+ case BFD_RELOC_PPC64_HIGHEST:
+ if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
+ ex.X_add_number = PPC_HIGHEST (ex.X_add_number);
+ else
+ ex.X_add_number = SEX16 (PPC_HIGHEST (ex.X_add_number));
+ break;
+
+ case BFD_RELOC_PPC64_HIGHEST_S:
+ if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
+ ex.X_add_number = PPC_HIGHESTA (ex.X_add_number);
+ else
+ ex.X_add_number = SEX16 (PPC_HIGHESTA (ex.X_add_number));
+ break;
+ }
+#endif /* OBJ_ELF */
+ insn = ppc_insert_operand (insn, operand, ex.X_add_number,
+ (char *) NULL, 0);
+ }
+#ifdef OBJ_ELF
+ else if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
+ {
+ /* Some TLS tweaks. */
+ switch (reloc)
+ {
+ default:
+ break;
+ case BFD_RELOC_PPC_TLS:
+ insn = ppc_insert_operand (insn, operand, ppc_obj64 ? 13 : 2,
+ (char *) NULL, 0);
+ break;
+ /* We'll only use the 32 (or 64) bit form of these relocations
+ in constants. Instructions get the 16 bit form. */
+ case BFD_RELOC_PPC_DTPREL:
+ reloc = BFD_RELOC_PPC_DTPREL16;
+ break;
+ case BFD_RELOC_PPC_TPREL:
+ reloc = BFD_RELOC_PPC_TPREL16;
+ break;
+ }
+
+ /* For the absolute forms of branches, convert the PC
+ relative form back into the absolute. */
+ if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
+ {
+ switch (reloc)
+ {
+ case BFD_RELOC_PPC_B26:
+ reloc = BFD_RELOC_PPC_BA26;
+ break;
+ case BFD_RELOC_PPC_B16:
+ reloc = BFD_RELOC_PPC_BA16;
+ break;
+ case BFD_RELOC_PPC_B16_BRTAKEN:
+ reloc = BFD_RELOC_PPC_BA16_BRTAKEN;
+ break;
+ case BFD_RELOC_PPC_B16_BRNTAKEN:
+ reloc = BFD_RELOC_PPC_BA16_BRNTAKEN;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (ppc_obj64
+ && (operand->flags & (PPC_OPERAND_DS | PPC_OPERAND_DQ)) != 0)
+ {
+ switch (reloc)
+ {
+ case BFD_RELOC_16:
+ reloc = BFD_RELOC_PPC64_ADDR16_DS;
+ break;
+ case BFD_RELOC_LO16:
+ reloc = BFD_RELOC_PPC64_ADDR16_LO_DS;
+ break;
+ case BFD_RELOC_16_GOTOFF:
+ reloc = BFD_RELOC_PPC64_GOT16_DS;
+ break;
+ case BFD_RELOC_LO16_GOTOFF:
+ reloc = BFD_RELOC_PPC64_GOT16_LO_DS;
+ break;
+ case BFD_RELOC_LO16_PLTOFF:
+ reloc = BFD_RELOC_PPC64_PLT16_LO_DS;
+ break;
+ case BFD_RELOC_16_BASEREL:
+ reloc = BFD_RELOC_PPC64_SECTOFF_DS;
+ break;
+ case BFD_RELOC_LO16_BASEREL:
+ reloc = BFD_RELOC_PPC64_SECTOFF_LO_DS;
+ break;
+ case BFD_RELOC_PPC_TOC16:
+ reloc = BFD_RELOC_PPC64_TOC16_DS;
+ break;
+ case BFD_RELOC_PPC64_TOC16_LO:
+ reloc = BFD_RELOC_PPC64_TOC16_LO_DS;
+ break;
+ case BFD_RELOC_PPC64_PLTGOT16:
+ reloc = BFD_RELOC_PPC64_PLTGOT16_DS;
+ break;
+ case BFD_RELOC_PPC64_PLTGOT16_LO:
+ reloc = BFD_RELOC_PPC64_PLTGOT16_LO_DS;
+ break;
+ case BFD_RELOC_PPC_DTPREL16:
+ reloc = BFD_RELOC_PPC64_DTPREL16_DS;
+ break;
+ case BFD_RELOC_PPC_DTPREL16_LO:
+ reloc = BFD_RELOC_PPC64_DTPREL16_LO_DS;
+ break;
+ case BFD_RELOC_PPC_TPREL16:
+ reloc = BFD_RELOC_PPC64_TPREL16_DS;
+ break;
+ case BFD_RELOC_PPC_TPREL16_LO:
+ reloc = BFD_RELOC_PPC64_TPREL16_LO_DS;
+ break;
+ case BFD_RELOC_PPC_GOT_DTPREL16:
+ case BFD_RELOC_PPC_GOT_DTPREL16_LO:
+ case BFD_RELOC_PPC_GOT_TPREL16:
+ case BFD_RELOC_PPC_GOT_TPREL16_LO:
+ break;
+ default:
+ as_bad (_("unsupported relocation for DS offset field"));
+ break;
+ }
+ }
+
+ /* We need to generate a fixup for this expression. */
+ if (fc >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = 0;
+ fixups[fc].reloc = reloc;
+ ++fc;
+ }
+#endif /* OBJ_ELF */
+
+ else
+ {
+ /* We need to generate a fixup for this expression. */
+ if (fc >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = *opindex_ptr;
+ fixups[fc].reloc = BFD_RELOC_UNUSED;
+ ++fc;
+ }
+
+ if (need_paren)
+ {
+ endc = ')';
+ need_paren = 0;
+ }
+ else if ((operand->flags & PPC_OPERAND_PARENS) != 0)
+ {
+ endc = '(';
+ need_paren = 1;
+ }
+ else
+ endc = ',';
+
+ /* The call to expression should have advanced str past any
+ whitespace. */
+ if (*str != endc
+ && (endc != ',' || *str != '\0'))
+ {
+ as_bad (_("syntax error; found `%c' but expected `%c'"), *str, endc);
+ break;
+ }
+
+ if (*str != '\0')
+ ++str;
+ }
+
+ while (ISSPACE (*str))
+ ++str;
+
+ if (*str != '\0')
+ as_bad (_("junk at end of line: `%s'"), str);
+
+#ifdef OBJ_ELF
+ /* Do we need/want a APUinfo section? */
+ if (ppc_cpu & (PPC_OPCODE_SPE
+ | PPC_OPCODE_ISEL | PPC_OPCODE_EFS
+ | PPC_OPCODE_BRLOCK | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
+ | PPC_OPCODE_RFMCI))
+ {
+ /* These are all version "1". */
+ if (opcode->flags & PPC_OPCODE_SPE)
+ ppc_apuinfo_section_add (PPC_APUINFO_SPE, 1);
+ if (opcode->flags & PPC_OPCODE_ISEL)
+ ppc_apuinfo_section_add (PPC_APUINFO_ISEL, 1);
+ if (opcode->flags & PPC_OPCODE_EFS)
+ ppc_apuinfo_section_add (PPC_APUINFO_EFS, 1);
+ if (opcode->flags & PPC_OPCODE_BRLOCK)
+ ppc_apuinfo_section_add (PPC_APUINFO_BRLOCK, 1);
+ if (opcode->flags & PPC_OPCODE_PMR)
+ ppc_apuinfo_section_add (PPC_APUINFO_PMR, 1);
+ if (opcode->flags & PPC_OPCODE_CACHELCK)
+ ppc_apuinfo_section_add (PPC_APUINFO_CACHELCK, 1);
+ if (opcode->flags & PPC_OPCODE_RFMCI)
+ ppc_apuinfo_section_add (PPC_APUINFO_RFMCI, 1);
+ }
+#endif
+
+ /* Write out the instruction. */
+ f = frag_more (4);
+ md_number_to_chars (f, insn, 4);
+
+#ifdef OBJ_ELF
+ dwarf2_emit_insn (4);
+#endif
+
+ /* Create any fixups. At this point we do not use a
+ bfd_reloc_code_real_type, but instead just use the
+ BFD_RELOC_UNUSED plus the operand index. This lets us easily
+ handle fixups for any operand type, although that is admittedly
+ not a very exciting feature. We pick a BFD reloc type in
+ md_apply_fix3. */
+ for (i = 0; i < fc; i++)
+ {
+ const struct powerpc_operand *operand;
+
+ operand = &powerpc_operands[fixups[i].opindex];
+ if (fixups[i].reloc != BFD_RELOC_UNUSED)
+ {
+ reloc_howto_type *reloc_howto;
+ int size;
+ int offset;
+ fixS *fixP;
+
+ reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
+ if (!reloc_howto)
+ abort ();
+
+ size = bfd_get_reloc_size (reloc_howto);
+ offset = target_big_endian ? (4 - size) : 0;
+
+ if (size < 1 || size > 4)
+ abort ();
+
+ fixP = fix_new_exp (frag_now,
+ f - frag_now->fr_literal + offset,
+ size,
+ &fixups[i].exp,
+ reloc_howto->pc_relative,
+ fixups[i].reloc);
+
+ /* Turn off complaints that the addend is too large for things like
+ foo+100000@ha. */
+ switch (fixups[i].reloc)
+ {
+ case BFD_RELOC_16_GOTOFF:
+ case BFD_RELOC_PPC_TOC16:
+ case BFD_RELOC_LO16:
+ case BFD_RELOC_HI16:
+ case BFD_RELOC_HI16_S:
+#ifdef OBJ_ELF
+ case BFD_RELOC_PPC64_HIGHER:
+ case BFD_RELOC_PPC64_HIGHER_S:
+ case BFD_RELOC_PPC64_HIGHEST:
+ case BFD_RELOC_PPC64_HIGHEST_S:
+#endif
+ fixP->fx_no_overflow = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ fix_new_exp (frag_now,
+ f - frag_now->fr_literal,
+ 4,
+ &fixups[i].exp,
+ (operand->flags & PPC_OPERAND_RELATIVE) != 0,
+ ((bfd_reloc_code_real_type)
+ (fixups[i].opindex + (int) BFD_RELOC_UNUSED)));
+ }
+}
+
+/* Handle a macro. Gather all the operands, transform them as
+ described by the macro, and call md_assemble recursively. All the
+ operands are separated by commas; we don't accept parentheses
+ around operands here. */
+
+static void
+ppc_macro (str, macro)
+ char *str;
+ const struct powerpc_macro *macro;
+{
+ char *operands[10];
+ unsigned int count;
+ char *s;
+ unsigned int len;
+ const char *format;
+ int arg;
+ char *send;
+ char *complete;
+
+ /* Gather the users operands into the operands array. */
+ count = 0;
+ s = str;
+ while (1)
+ {
+ if (count >= sizeof operands / sizeof operands[0])
+ break;
+ operands[count++] = s;
+ s = strchr (s, ',');
+ if (s == (char *) NULL)
+ break;
+ *s++ = '\0';
+ }
+
+ if (count != macro->operands)
+ {
+ as_bad (_("wrong number of operands"));
+ return;
+ }
+
+ /* Work out how large the string must be (the size is unbounded
+ because it includes user input). */
+ len = 0;
+ format = macro->format;
+ while (*format != '\0')
+ {
+ if (*format != '%')
+ {
+ ++len;
+ ++format;
+ }
+ else
+ {
+ arg = strtol (format + 1, &send, 10);
+ know (send != format && arg >= 0 && arg < count);
+ len += strlen (operands[arg]);
+ format = send;
+ }
+ }
+
+ /* Put the string together. */
+ complete = s = (char *) alloca (len + 1);
+ format = macro->format;
+ while (*format != '\0')
+ {
+ if (*format != '%')
+ *s++ = *format++;
+ else
+ {
+ arg = strtol (format + 1, &send, 10);
+ strcpy (s, operands[arg]);
+ s += strlen (s);
+ format = send;
+ }
+ }
+ *s = '\0';
+
+ /* Assemble the constructed instruction. */
+ md_assemble (complete);
+}
+
+#ifdef OBJ_ELF
+/* For ELF, add support for SHF_EXCLUDE and SHT_ORDERED. */
+
+int
+ppc_section_letter (letter, ptr_msg)
+ int letter;
+ char **ptr_msg;
+{
+ if (letter == 'e')
+ return SHF_EXCLUDE;
+
+ *ptr_msg = _("Bad .section directive: want a,e,w,x,M,S,G,T in string");
+ return -1;
+}
+
+int
+ppc_section_word (str, len)
+ char *str;
+ size_t len;
+{
+ if (len == 7 && strncmp (str, "exclude", 7) == 0)
+ return SHF_EXCLUDE;
+
+ return -1;
+}
+
+int
+ppc_section_type (str, len)
+ char *str;
+ size_t len;
+{
+ if (len == 7 && strncmp (str, "ordered", 7) == 0)
+ return SHT_ORDERED;
+
+ return -1;
+}
+
+int
+ppc_section_flags (flags, attr, type)
+ int flags;
+ int attr;
+ int type;
+{
+ if (type == SHT_ORDERED)
+ flags |= SEC_ALLOC | SEC_LOAD | SEC_SORT_ENTRIES;
+
+ if (attr & SHF_EXCLUDE)
+ flags |= SEC_EXCLUDE;
+
+ return flags;
+}
+#endif /* OBJ_ELF */
+
+
+/* Pseudo-op handling. */
+
+/* The .byte pseudo-op. This is similar to the normal .byte
+ pseudo-op, but it can also take a single ASCII string. */
+
+static void
+ppc_byte (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (*input_line_pointer != '\"')
+ {
+ cons (1);
+ return;
+ }
+
+ /* Gather characters. A real double quote is doubled. Unusual
+ characters are not permitted. */
+ ++input_line_pointer;
+ while (1)
+ {
+ char c;
+
+ c = *input_line_pointer++;
+
+ if (c == '\"')
+ {
+ if (*input_line_pointer != '\"')
+ break;
+ ++input_line_pointer;
+ }
+
+ FRAG_APPEND_1_CHAR (c);
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+#ifdef OBJ_XCOFF
+
+/* XCOFF specific pseudo-op handling. */
+
+/* This is set if we are creating a .stabx symbol, since we don't want
+ to handle symbol suffixes for such symbols. */
+static bfd_boolean ppc_stab_symbol;
+
+/* The .comm and .lcomm pseudo-ops for XCOFF. XCOFF puts common
+ symbols in the .bss segment as though they were local common
+ symbols, and uses a different smclas. The native Aix 4.3.3 assembler
+ aligns .comm and .lcomm to 4 bytes. */
+
+static void
+ppc_comm (lcomm)
+ int lcomm;
+{
+ asection *current_seg = now_seg;
+ subsegT current_subseg = now_subseg;
+ char *name;
+ char endc;
+ char *end_name;
+ offsetT size;
+ offsetT align;
+ symbolS *lcomm_sym = NULL;
+ symbolS *sym;
+ char *pfrag;
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+ end_name = input_line_pointer;
+ *end_name = endc;
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing size"));
+ ignore_rest_of_line ();
+ return;
+ }
+ ++input_line_pointer;
+
+ size = get_absolute_expression ();
+ if (size < 0)
+ {
+ as_bad (_("negative size"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (! lcomm)
+ {
+ /* The third argument to .comm is the alignment. */
+ if (*input_line_pointer != ',')
+ align = 2;
+ else
+ {
+ ++input_line_pointer;
+ align = get_absolute_expression ();
+ if (align <= 0)
+ {
+ as_warn (_("ignoring bad alignment"));
+ align = 2;
+ }
+ }
+ }
+ else
+ {
+ char *lcomm_name;
+ char lcomm_endc;
+
+ if (size <= 4)
+ align = 2;
+ else
+ align = 3;
+
+ /* The third argument to .lcomm appears to be the real local
+ common symbol to create. References to the symbol named in
+ the first argument are turned into references to the third
+ argument. */
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing real symbol name"));
+ ignore_rest_of_line ();
+ return;
+ }
+ ++input_line_pointer;
+
+ lcomm_name = input_line_pointer;
+ lcomm_endc = get_symbol_end ();
+
+ lcomm_sym = symbol_find_or_make (lcomm_name);
+
+ *input_line_pointer = lcomm_endc;
+ }
+
+ *end_name = '\0';
+ sym = symbol_find_or_make (name);
+ *end_name = endc;
+
+ if (S_IS_DEFINED (sym)
+ || S_GET_VALUE (sym) != 0)
+ {
+ as_bad (_("attempt to redefine symbol"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ record_alignment (bss_section, align);
+
+ if (! lcomm
+ || ! S_IS_DEFINED (lcomm_sym))
+ {
+ symbolS *def_sym;
+ offsetT def_size;
+
+ if (! lcomm)
+ {
+ def_sym = sym;
+ def_size = size;
+ S_SET_EXTERNAL (sym);
+ }
+ else
+ {
+ symbol_get_tc (lcomm_sym)->output = 1;
+ def_sym = lcomm_sym;
+ def_size = 0;
+ }
+
+ subseg_set (bss_section, 1);
+ frag_align (align, 0, 0);
+
+ symbol_set_frag (def_sym, frag_now);
+ pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, def_sym,
+ def_size, (char *) NULL);
+ *pfrag = 0;
+ S_SET_SEGMENT (def_sym, bss_section);
+ symbol_get_tc (def_sym)->align = align;
+ }
+ else if (lcomm)
+ {
+ /* Align the size of lcomm_sym. */
+ symbol_get_frag (lcomm_sym)->fr_offset =
+ ((symbol_get_frag (lcomm_sym)->fr_offset + (1 << align) - 1)
+ &~ ((1 << align) - 1));
+ if (align > symbol_get_tc (lcomm_sym)->align)
+ symbol_get_tc (lcomm_sym)->align = align;
+ }
+
+ if (lcomm)
+ {
+ /* Make sym an offset from lcomm_sym. */
+ S_SET_SEGMENT (sym, bss_section);
+ symbol_set_frag (sym, symbol_get_frag (lcomm_sym));
+ S_SET_VALUE (sym, symbol_get_frag (lcomm_sym)->fr_offset);
+ symbol_get_frag (lcomm_sym)->fr_offset += size;
+ }
+
+ subseg_set (current_seg, current_subseg);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .csect pseudo-op. This switches us into a different
+ subsegment. The first argument is a symbol whose value is the
+ start of the .csect. In COFF, csect symbols get special aux
+ entries defined by the x_csect field of union internal_auxent. The
+ optional second argument is the alignment (the default is 2). */
+
+static void
+ppc_csect (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *name;
+ char endc;
+ symbolS *sym;
+ offsetT align;
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ sym = symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ if (S_GET_NAME (sym)[0] == '\0')
+ {
+ /* An unnamed csect is assumed to be [PR]. */
+ symbol_get_tc (sym)->class = XMC_PR;
+ }
+
+ align = 2;
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ align = get_absolute_expression ();
+ }
+
+ ppc_change_csect (sym, align);
+
+ demand_empty_rest_of_line ();
+}
+
+/* Change to a different csect. */
+
+static void
+ppc_change_csect (sym, align)
+ symbolS *sym;
+ offsetT align;
+{
+ if (S_IS_DEFINED (sym))
+ subseg_set (S_GET_SEGMENT (sym), symbol_get_tc (sym)->subseg);
+ else
+ {
+ symbolS **list_ptr;
+ int after_toc;
+ int hold_chunksize;
+ symbolS *list;
+ int is_code;
+ segT sec;
+
+ /* This is a new csect. We need to look at the symbol class to
+ figure out whether it should go in the text section or the
+ data section. */
+ after_toc = 0;
+ is_code = 0;
+ switch (symbol_get_tc (sym)->class)
+ {
+ case XMC_PR:
+ case XMC_RO:
+ case XMC_DB:
+ case XMC_GL:
+ case XMC_XO:
+ case XMC_SV:
+ case XMC_TI:
+ case XMC_TB:
+ S_SET_SEGMENT (sym, text_section);
+ symbol_get_tc (sym)->subseg = ppc_text_subsegment;
+ ++ppc_text_subsegment;
+ list_ptr = &ppc_text_csects;
+ is_code = 1;
+ break;
+ case XMC_RW:
+ case XMC_TC0:
+ case XMC_TC:
+ case XMC_DS:
+ case XMC_UA:
+ case XMC_BS:
+ case XMC_UC:
+ if (ppc_toc_csect != NULL
+ && (symbol_get_tc (ppc_toc_csect)->subseg + 1
+ == ppc_data_subsegment))
+ after_toc = 1;
+ S_SET_SEGMENT (sym, data_section);
+ symbol_get_tc (sym)->subseg = ppc_data_subsegment;
+ ++ppc_data_subsegment;
+ list_ptr = &ppc_data_csects;
+ break;
+ default:
+ abort ();
+ }
+
+ /* We set the obstack chunk size to a small value before
+ changing subsegments, so that we don't use a lot of memory
+ space for what may be a small section. */
+ hold_chunksize = chunksize;
+ chunksize = 64;
+
+ sec = subseg_new (segment_name (S_GET_SEGMENT (sym)),
+ symbol_get_tc (sym)->subseg);
+
+ chunksize = hold_chunksize;
+
+ if (after_toc)
+ ppc_after_toc_frag = frag_now;
+
+ record_alignment (sec, align);
+ if (is_code)
+ frag_align_code (align, 0);
+ else
+ frag_align (align, 0, 0);
+
+ symbol_set_frag (sym, frag_now);
+ S_SET_VALUE (sym, (valueT) frag_now_fix ());
+
+ symbol_get_tc (sym)->align = align;
+ symbol_get_tc (sym)->output = 1;
+ symbol_get_tc (sym)->within = sym;
+
+ for (list = *list_ptr;
+ symbol_get_tc (list)->next != (symbolS *) NULL;
+ list = symbol_get_tc (list)->next)
+ ;
+ symbol_get_tc (list)->next = sym;
+
+ symbol_remove (sym, &symbol_rootP, &symbol_lastP);
+ symbol_append (sym, symbol_get_tc (list)->within, &symbol_rootP,
+ &symbol_lastP);
+ }
+
+ ppc_current_csect = sym;
+}
+
+/* This function handles the .text and .data pseudo-ops. These
+ pseudo-ops aren't really used by XCOFF; we implement them for the
+ convenience of people who aren't used to XCOFF. */
+
+static void
+ppc_section (type)
+ int type;
+{
+ const char *name;
+ symbolS *sym;
+
+ if (type == 't')
+ name = ".text[PR]";
+ else if (type == 'd')
+ name = ".data[RW]";
+ else
+ abort ();
+
+ sym = symbol_find_or_make (name);
+
+ ppc_change_csect (sym, 2);
+
+ demand_empty_rest_of_line ();
+}
+
+/* This function handles the .section pseudo-op. This is mostly to
+ give an error, since XCOFF only supports .text, .data and .bss, but
+ we do permit the user to name the text or data section. */
+
+static void
+ppc_named_section (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *user_name;
+ const char *real_name;
+ char c;
+ symbolS *sym;
+
+ user_name = input_line_pointer;
+ c = get_symbol_end ();
+
+ if (strcmp (user_name, ".text") == 0)
+ real_name = ".text[PR]";
+ else if (strcmp (user_name, ".data") == 0)
+ real_name = ".data[RW]";
+ else
+ {
+ as_bad (_("The XCOFF file format does not support arbitrary sections"));
+ *input_line_pointer = c;
+ ignore_rest_of_line ();
+ return;
+ }
+
+ *input_line_pointer = c;
+
+ sym = symbol_find_or_make (real_name);
+
+ ppc_change_csect (sym, 2);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .extern pseudo-op. We create an undefined symbol. */
+
+static void
+ppc_extern (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *name;
+ char endc;
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ (void) symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .lglobl pseudo-op. Keep the symbol in the symbol table. */
+
+static void
+ppc_lglobl (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *name;
+ char endc;
+ symbolS *sym;
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ sym = symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ symbol_get_tc (sym)->output = 1;
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .rename pseudo-op. The RS/6000 assembler can rename symbols,
+ although I don't know why it bothers. */
+
+static void
+ppc_rename (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *name;
+ char endc;
+ symbolS *sym;
+ int len;
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ sym = symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing rename string"));
+ ignore_rest_of_line ();
+ return;
+ }
+ ++input_line_pointer;
+
+ symbol_get_tc (sym)->real_name = demand_copy_C_string (&len);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .stabx pseudo-op. This is similar to a normal .stabs
+ pseudo-op, but slightly different. A sample is
+ .stabx "main:F-1",.main,142,0
+ The first argument is the symbol name to create. The second is the
+ value, and the third is the storage class. The fourth seems to be
+ always zero, and I am assuming it is the type. */
+
+static void
+ppc_stabx (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *name;
+ int len;
+ symbolS *sym;
+ expressionS exp;
+
+ name = demand_copy_C_string (&len);
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing value"));
+ return;
+ }
+ ++input_line_pointer;
+
+ ppc_stab_symbol = TRUE;
+ sym = symbol_make (name);
+ ppc_stab_symbol = FALSE;
+
+ symbol_get_tc (sym)->real_name = name;
+
+ (void) expression (&exp);
+
+ switch (exp.X_op)
+ {
+ case O_illegal:
+ case O_absent:
+ case O_big:
+ as_bad (_("illegal .stabx expression; zero assumed"));
+ exp.X_add_number = 0;
+ /* Fall through. */
+ case O_constant:
+ S_SET_VALUE (sym, (valueT) exp.X_add_number);
+ symbol_set_frag (sym, &zero_address_frag);
+ break;
+
+ case O_symbol:
+ if (S_GET_SEGMENT (exp.X_add_symbol) == undefined_section)
+ symbol_set_value_expression (sym, &exp);
+ else
+ {
+ S_SET_VALUE (sym,
+ exp.X_add_number + S_GET_VALUE (exp.X_add_symbol));
+ symbol_set_frag (sym, symbol_get_frag (exp.X_add_symbol));
+ }
+ break;
+
+ default:
+ /* The value is some complex expression. This will probably
+ fail at some later point, but this is probably the right
+ thing to do here. */
+ symbol_set_value_expression (sym, &exp);
+ break;
+ }
+
+ S_SET_SEGMENT (sym, ppc_coff_debug_section);
+ symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing class"));
+ return;
+ }
+ ++input_line_pointer;
+
+ S_SET_STORAGE_CLASS (sym, get_absolute_expression ());
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing type"));
+ return;
+ }
+ ++input_line_pointer;
+
+ S_SET_DATA_TYPE (sym, get_absolute_expression ());
+
+ symbol_get_tc (sym)->output = 1;
+
+ if (S_GET_STORAGE_CLASS (sym) == C_STSYM) {
+
+ symbol_get_tc (sym)->within = ppc_current_block;
+
+ /* In this case :
+
+ .bs name
+ .stabx "z",arrays_,133,0
+ .es
+
+ .comm arrays_,13768,3
+
+ resolve_symbol_value will copy the exp's "within" into sym's when the
+ offset is 0. Since this seems to be corner case problem,
+ only do the correction for storage class C_STSYM. A better solution
+ would be to have the tc field updated in ppc_symbol_new_hook. */
+
+ if (exp.X_op == O_symbol)
+ {
+ symbol_get_tc (exp.X_add_symbol)->within = ppc_current_block;
+ }
+ }
+
+ if (exp.X_op != O_symbol
+ || ! S_IS_EXTERNAL (exp.X_add_symbol)
+ || S_GET_SEGMENT (exp.X_add_symbol) != bss_section)
+ ppc_frob_label (sym);
+ else
+ {
+ symbol_remove (sym, &symbol_rootP, &symbol_lastP);
+ symbol_append (sym, exp.X_add_symbol, &symbol_rootP, &symbol_lastP);
+ if (symbol_get_tc (ppc_current_csect)->within == exp.X_add_symbol)
+ symbol_get_tc (ppc_current_csect)->within = sym;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .function pseudo-op. This takes several arguments. The first
+ argument seems to be the external name of the symbol. The second
+ argument seems to be the label for the start of the function. gcc
+ uses the same name for both. I have no idea what the third and
+ fourth arguments are meant to be. The optional fifth argument is
+ an expression for the size of the function. In COFF this symbol
+ gets an aux entry like that used for a csect. */
+
+static void
+ppc_function (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *name;
+ char endc;
+ char *s;
+ symbolS *ext_sym;
+ symbolS *lab_sym;
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ /* Ignore any [PR] suffix. */
+ name = ppc_canonicalize_symbol_name (name);
+ s = strchr (name, '[');
+ if (s != (char *) NULL
+ && strcmp (s + 1, "PR]") == 0)
+ *s = '\0';
+
+ ext_sym = symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing symbol name"));
+ ignore_rest_of_line ();
+ return;
+ }
+ ++input_line_pointer;
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ lab_sym = symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ if (ext_sym != lab_sym)
+ {
+ expressionS exp;
+
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = lab_sym;
+ exp.X_op_symbol = NULL;
+ exp.X_add_number = 0;
+ exp.X_unsigned = 0;
+ symbol_set_value_expression (ext_sym, &exp);
+ }
+
+ if (symbol_get_tc (ext_sym)->class == -1)
+ symbol_get_tc (ext_sym)->class = XMC_PR;
+ symbol_get_tc (ext_sym)->output = 1;
+
+ if (*input_line_pointer == ',')
+ {
+ expressionS ignore;
+
+ /* Ignore the third argument. */
+ ++input_line_pointer;
+ expression (&ignore);
+ if (*input_line_pointer == ',')
+ {
+ /* Ignore the fourth argument. */
+ ++input_line_pointer;
+ expression (&ignore);
+ if (*input_line_pointer == ',')
+ {
+ /* The fifth argument is the function size. */
+ ++input_line_pointer;
+ symbol_get_tc (ext_sym)->size = symbol_new ("L0\001",
+ absolute_section,
+ (valueT) 0,
+ &zero_address_frag);
+ pseudo_set (symbol_get_tc (ext_sym)->size);
+ }
+ }
+ }
+
+ S_SET_DATA_TYPE (ext_sym, DT_FCN << N_BTSHFT);
+ SF_SET_FUNCTION (ext_sym);
+ SF_SET_PROCESS (ext_sym);
+ coff_add_linesym (ext_sym);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .bf pseudo-op. This is just like a COFF C_FCN symbol named
+ ".bf". If the pseudo op .bi was seen before .bf, patch the .bi sym
+ with the correct line number */
+
+static symbolS *saved_bi_sym = 0;
+
+static void
+ppc_bf (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ symbolS *sym;
+
+ sym = symbol_make (".bf");
+ S_SET_SEGMENT (sym, text_section);
+ symbol_set_frag (sym, frag_now);
+ S_SET_VALUE (sym, frag_now_fix ());
+ S_SET_STORAGE_CLASS (sym, C_FCN);
+
+ coff_line_base = get_absolute_expression ();
+
+ S_SET_NUMBER_AUXILIARY (sym, 1);
+ SA_SET_SYM_LNNO (sym, coff_line_base);
+
+ /* Line number for bi. */
+ if (saved_bi_sym)
+ {
+ S_SET_VALUE (saved_bi_sym, coff_n_line_nos);
+ saved_bi_sym = 0;
+ }
+
+
+ symbol_get_tc (sym)->output = 1;
+
+ ppc_frob_label (sym);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .ef pseudo-op. This is just like a COFF C_FCN symbol named
+ ".ef", except that the line number is absolute, not relative to the
+ most recent ".bf" symbol. */
+
+static void
+ppc_ef (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ symbolS *sym;
+
+ sym = symbol_make (".ef");
+ S_SET_SEGMENT (sym, text_section);
+ symbol_set_frag (sym, frag_now);
+ S_SET_VALUE (sym, frag_now_fix ());
+ S_SET_STORAGE_CLASS (sym, C_FCN);
+ S_SET_NUMBER_AUXILIARY (sym, 1);
+ SA_SET_SYM_LNNO (sym, get_absolute_expression ());
+ symbol_get_tc (sym)->output = 1;
+
+ ppc_frob_label (sym);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .bi and .ei pseudo-ops. These take a string argument and
+ generates a C_BINCL or C_EINCL symbol, which goes at the start of
+ the symbol list. The value of .bi will be know when the next .bf
+ is encountered. */
+
+static void
+ppc_biei (ei)
+ int ei;
+{
+ static symbolS *last_biei;
+
+ char *name;
+ int len;
+ symbolS *sym;
+ symbolS *look;
+
+ name = demand_copy_C_string (&len);
+
+ /* The value of these symbols is actually file offset. Here we set
+ the value to the index into the line number entries. In
+ ppc_frob_symbols we set the fix_line field, which will cause BFD
+ to do the right thing. */
+
+ sym = symbol_make (name);
+ /* obj-coff.c currently only handles line numbers correctly in the
+ .text section. */
+ S_SET_SEGMENT (sym, text_section);
+ S_SET_VALUE (sym, coff_n_line_nos);
+ symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
+
+ S_SET_STORAGE_CLASS (sym, ei ? C_EINCL : C_BINCL);
+ symbol_get_tc (sym)->output = 1;
+
+ /* Save bi. */
+ if (ei)
+ saved_bi_sym = 0;
+ else
+ saved_bi_sym = sym;
+
+ for (look = last_biei ? last_biei : symbol_rootP;
+ (look != (symbolS *) NULL
+ && (S_GET_STORAGE_CLASS (look) == C_FILE
+ || S_GET_STORAGE_CLASS (look) == C_BINCL
+ || S_GET_STORAGE_CLASS (look) == C_EINCL));
+ look = symbol_next (look))
+ ;
+ if (look != (symbolS *) NULL)
+ {
+ symbol_remove (sym, &symbol_rootP, &symbol_lastP);
+ symbol_insert (sym, look, &symbol_rootP, &symbol_lastP);
+ last_biei = sym;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .bs pseudo-op. This generates a C_BSTAT symbol named ".bs".
+ There is one argument, which is a csect symbol. The value of the
+ .bs symbol is the index of this csect symbol. */
+
+static void
+ppc_bs (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *name;
+ char endc;
+ symbolS *csect;
+ symbolS *sym;
+
+ if (ppc_current_block != NULL)
+ as_bad (_("nested .bs blocks"));
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ csect = symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ sym = symbol_make (".bs");
+ S_SET_SEGMENT (sym, now_seg);
+ S_SET_STORAGE_CLASS (sym, C_BSTAT);
+ symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
+ symbol_get_tc (sym)->output = 1;
+
+ symbol_get_tc (sym)->within = csect;
+
+ ppc_frob_label (sym);
+
+ ppc_current_block = sym;
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .es pseudo-op. Generate a C_ESTART symbol named .es. */
+
+static void
+ppc_es (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ symbolS *sym;
+
+ if (ppc_current_block == NULL)
+ as_bad (_(".es without preceding .bs"));
+
+ sym = symbol_make (".es");
+ S_SET_SEGMENT (sym, now_seg);
+ S_SET_STORAGE_CLASS (sym, C_ESTAT);
+ symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
+ symbol_get_tc (sym)->output = 1;
+
+ ppc_frob_label (sym);
+
+ ppc_current_block = NULL;
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .bb pseudo-op. Generate a C_BLOCK symbol named .bb, with a
+ line number. */
+
+static void
+ppc_bb (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ symbolS *sym;
+
+ sym = symbol_make (".bb");
+ S_SET_SEGMENT (sym, text_section);
+ symbol_set_frag (sym, frag_now);
+ S_SET_VALUE (sym, frag_now_fix ());
+ S_SET_STORAGE_CLASS (sym, C_BLOCK);
+
+ S_SET_NUMBER_AUXILIARY (sym, 1);
+ SA_SET_SYM_LNNO (sym, get_absolute_expression ());
+
+ symbol_get_tc (sym)->output = 1;
+
+ SF_SET_PROCESS (sym);
+
+ ppc_frob_label (sym);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .eb pseudo-op. Generate a C_BLOCK symbol named .eb, with a
+ line number. */
+
+static void
+ppc_eb (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ symbolS *sym;
+
+ sym = symbol_make (".eb");
+ S_SET_SEGMENT (sym, text_section);
+ symbol_set_frag (sym, frag_now);
+ S_SET_VALUE (sym, frag_now_fix ());
+ S_SET_STORAGE_CLASS (sym, C_BLOCK);
+ S_SET_NUMBER_AUXILIARY (sym, 1);
+ SA_SET_SYM_LNNO (sym, get_absolute_expression ());
+ symbol_get_tc (sym)->output = 1;
+
+ SF_SET_PROCESS (sym);
+
+ ppc_frob_label (sym);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .bc pseudo-op. This just creates a C_BCOMM symbol with a
+ specified name. */
+
+static void
+ppc_bc (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *name;
+ int len;
+ symbolS *sym;
+
+ name = demand_copy_C_string (&len);
+ sym = symbol_make (name);
+ S_SET_SEGMENT (sym, ppc_coff_debug_section);
+ symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
+ S_SET_STORAGE_CLASS (sym, C_BCOMM);
+ S_SET_VALUE (sym, 0);
+ symbol_get_tc (sym)->output = 1;
+
+ ppc_frob_label (sym);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .ec pseudo-op. This just creates a C_ECOMM symbol. */
+
+static void
+ppc_ec (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ symbolS *sym;
+
+ sym = symbol_make (".ec");
+ S_SET_SEGMENT (sym, ppc_coff_debug_section);
+ symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
+ S_SET_STORAGE_CLASS (sym, C_ECOMM);
+ S_SET_VALUE (sym, 0);
+ symbol_get_tc (sym)->output = 1;
+
+ ppc_frob_label (sym);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .toc pseudo-op. Switch to the .toc subsegment. */
+
+static void
+ppc_toc (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (ppc_toc_csect != (symbolS *) NULL)
+ subseg_set (data_section, symbol_get_tc (ppc_toc_csect)->subseg);
+ else
+ {
+ subsegT subseg;
+ symbolS *sym;
+ symbolS *list;
+
+ subseg = ppc_data_subsegment;
+ ++ppc_data_subsegment;
+
+ subseg_new (segment_name (data_section), subseg);
+ ppc_toc_frag = frag_now;
+
+ sym = symbol_find_or_make ("TOC[TC0]");
+ symbol_set_frag (sym, frag_now);
+ S_SET_SEGMENT (sym, data_section);
+ S_SET_VALUE (sym, (valueT) frag_now_fix ());
+ symbol_get_tc (sym)->subseg = subseg;
+ symbol_get_tc (sym)->output = 1;
+ symbol_get_tc (sym)->within = sym;
+
+ ppc_toc_csect = sym;
+
+ for (list = ppc_data_csects;
+ symbol_get_tc (list)->next != (symbolS *) NULL;
+ list = symbol_get_tc (list)->next)
+ ;
+ symbol_get_tc (list)->next = sym;
+
+ symbol_remove (sym, &symbol_rootP, &symbol_lastP);
+ symbol_append (sym, symbol_get_tc (list)->within, &symbol_rootP,
+ &symbol_lastP);
+ }
+
+ ppc_current_csect = ppc_toc_csect;
+
+ demand_empty_rest_of_line ();
+}
+
+/* The AIX assembler automatically aligns the operands of a .long or
+ .short pseudo-op, and we want to be compatible. */
+
+static void
+ppc_xcoff_cons (log_size)
+ int log_size;
+{
+ frag_align (log_size, 0, 0);
+ record_alignment (now_seg, log_size);
+ cons (1 << log_size);
+}
+
+static void
+ppc_vbyte (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ expressionS exp;
+ int byte_count;
+
+ (void) expression (&exp);
+
+ if (exp.X_op != O_constant)
+ {
+ as_bad (_("non-constant byte count"));
+ return;
+ }
+
+ byte_count = exp.X_add_number;
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing value"));
+ return;
+ }
+
+ ++input_line_pointer;
+ cons (byte_count);
+}
+
+#endif /* OBJ_XCOFF */
+#if defined (OBJ_XCOFF) || defined (OBJ_ELF)
+
+/* The .tc pseudo-op. This is used when generating either XCOFF or
+ ELF. This takes two or more arguments.
+
+ When generating XCOFF output, the first argument is the name to
+ give to this location in the toc; this will be a symbol with class
+ TC. The rest of the arguments are N-byte values to actually put at
+ this location in the TOC; often there is just one more argument, a
+ relocatable symbol reference. The size of the value to store
+ depends on target word size. A 32-bit target uses 4-byte values, a
+ 64-bit target uses 8-byte values.
+
+ When not generating XCOFF output, the arguments are the same, but
+ the first argument is simply ignored. */
+
+static void
+ppc_tc (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+#ifdef OBJ_XCOFF
+
+ /* Define the TOC symbol name. */
+ {
+ char *name;
+ char endc;
+ symbolS *sym;
+
+ if (ppc_toc_csect == (symbolS *) NULL
+ || ppc_toc_csect != ppc_current_csect)
+ {
+ as_bad (_(".tc not in .toc section"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ sym = symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ if (S_IS_DEFINED (sym))
+ {
+ symbolS *label;
+
+ label = symbol_get_tc (ppc_current_csect)->within;
+ if (symbol_get_tc (label)->class != XMC_TC0)
+ {
+ as_bad (_(".tc with no label"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ S_SET_SEGMENT (label, S_GET_SEGMENT (sym));
+ symbol_set_frag (label, symbol_get_frag (sym));
+ S_SET_VALUE (label, S_GET_VALUE (sym));
+
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+
+ return;
+ }
+
+ S_SET_SEGMENT (sym, now_seg);
+ symbol_set_frag (sym, frag_now);
+ S_SET_VALUE (sym, (valueT) frag_now_fix ());
+ symbol_get_tc (sym)->class = XMC_TC;
+ symbol_get_tc (sym)->output = 1;
+
+ ppc_frob_label (sym);
+ }
+
+#endif /* OBJ_XCOFF */
+#ifdef OBJ_ELF
+ int align;
+
+ /* Skip the TOC symbol name. */
+ while (is_part_of_name (*input_line_pointer)
+ || *input_line_pointer == '['
+ || *input_line_pointer == ']'
+ || *input_line_pointer == '{'
+ || *input_line_pointer == '}')
+ ++input_line_pointer;
+
+ /* Align to a four/eight byte boundary. */
+ align = ppc_obj64 ? 3 : 2;
+ frag_align (align, 0, 0);
+ record_alignment (now_seg, align);
+#endif /* OBJ_ELF */
+
+ if (*input_line_pointer != ',')
+ demand_empty_rest_of_line ();
+ else
+ {
+ ++input_line_pointer;
+ cons (ppc_obj64 ? 8 : 4);
+ }
+}
+
+/* Pseudo-op .machine. */
+
+static void
+ppc_machine (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *cpu_string;
+#define MAX_HISTORY 100
+ static unsigned long *cpu_history;
+ static int curr_hist;
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer == '"')
+ {
+ int len;
+ cpu_string = demand_copy_C_string (&len);
+ }
+ else
+ {
+ char c;
+ cpu_string = input_line_pointer;
+ c = get_symbol_end ();
+ cpu_string = xstrdup (cpu_string);
+ *input_line_pointer = c;
+ }
+
+ if (cpu_string != NULL)
+ {
+ unsigned long old_cpu = ppc_cpu;
+ char *p;
+
+ for (p = cpu_string; *p != 0; p++)
+ *p = TOLOWER (*p);
+
+ if (strcmp (cpu_string, "push") == 0)
+ {
+ if (cpu_history == NULL)
+ cpu_history = xmalloc (MAX_HISTORY * sizeof (*cpu_history));
+
+ if (curr_hist >= MAX_HISTORY)
+ as_bad (_(".machine stack overflow"));
+ else
+ cpu_history[curr_hist++] = ppc_cpu;
+ }
+ else if (strcmp (cpu_string, "pop") == 0)
+ {
+ if (curr_hist <= 0)
+ as_bad (_(".machine stack underflow"));
+ else
+ ppc_cpu = cpu_history[--curr_hist];
+ }
+ else if (parse_cpu (cpu_string))
+ ;
+ else
+ as_bad (_("invalid machine `%s'"), cpu_string);
+
+ if (ppc_cpu != old_cpu)
+ ppc_setup_opcodes ();
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* See whether a symbol is in the TOC section. */
+
+static int
+ppc_is_toc_sym (sym)
+ symbolS *sym;
+{
+#ifdef OBJ_XCOFF
+ return symbol_get_tc (sym)->class == XMC_TC;
+#endif
+#ifdef OBJ_ELF
+ const char *sname = segment_name (S_GET_SEGMENT (sym));
+ if (ppc_obj64)
+ return strcmp (sname, ".toc") == 0;
+ else
+ return strcmp (sname, ".got") == 0;
+#endif
+}
+#endif /* defined (OBJ_XCOFF) || defined (OBJ_ELF) */
+
+#ifdef TE_PE
+
+/* Pseudo-ops specific to the Windows NT PowerPC PE (coff) format. */
+
+/* Set the current section. */
+static void
+ppc_set_current_section (new)
+ segT new;
+{
+ ppc_previous_section = ppc_current_section;
+ ppc_current_section = new;
+}
+
+/* pseudo-op: .previous
+ behaviour: toggles the current section with the previous section.
+ errors: None
+ warnings: "No previous section" */
+
+static void
+ppc_previous (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ symbolS *tmp;
+
+ if (ppc_previous_section == NULL)
+ {
+ as_warn (_("No previous section to return to. Directive ignored."));
+ return;
+ }
+
+ subseg_set (ppc_previous_section, 0);
+
+ ppc_set_current_section (ppc_previous_section);
+}
+
+/* pseudo-op: .pdata
+ behaviour: predefined read only data section
+ double word aligned
+ errors: None
+ warnings: None
+ initial: .section .pdata "adr3"
+ a - don't know -- maybe a misprint
+ d - initialized data
+ r - readable
+ 3 - double word aligned (that would be 4 byte boundary)
+
+ commentary:
+ Tag index tables (also known as the function table) for exception
+ handling, debugging, etc. */
+
+static void
+ppc_pdata (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (pdata_section == 0)
+ {
+ pdata_section = subseg_new (".pdata", 0);
+
+ bfd_set_section_flags (stdoutput, pdata_section,
+ (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_READONLY | SEC_DATA ));
+
+ bfd_set_section_alignment (stdoutput, pdata_section, 2);
+ }
+ else
+ {
+ pdata_section = subseg_new (".pdata", 0);
+ }
+ ppc_set_current_section (pdata_section);
+}
+
+/* pseudo-op: .ydata
+ behaviour: predefined read only data section
+ double word aligned
+ errors: None
+ warnings: None
+ initial: .section .ydata "drw3"
+ a - don't know -- maybe a misprint
+ d - initialized data
+ r - readable
+ 3 - double word aligned (that would be 4 byte boundary)
+ commentary:
+ Tag tables (also known as the scope table) for exception handling,
+ debugging, etc. */
+
+static void
+ppc_ydata (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (ydata_section == 0)
+ {
+ ydata_section = subseg_new (".ydata", 0);
+ bfd_set_section_flags (stdoutput, ydata_section,
+ (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_READONLY | SEC_DATA ));
+
+ bfd_set_section_alignment (stdoutput, ydata_section, 3);
+ }
+ else
+ {
+ ydata_section = subseg_new (".ydata", 0);
+ }
+ ppc_set_current_section (ydata_section);
+}
+
+/* pseudo-op: .reldata
+ behaviour: predefined read write data section
+ double word aligned (4-byte)
+ FIXME: relocation is applied to it
+ FIXME: what's the difference between this and .data?
+ errors: None
+ warnings: None
+ initial: .section .reldata "drw3"
+ d - initialized data
+ r - readable
+ w - writeable
+ 3 - double word aligned (that would be 8 byte boundary)
+
+ commentary:
+ Like .data, but intended to hold data subject to relocation, such as
+ function descriptors, etc. */
+
+static void
+ppc_reldata (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (reldata_section == 0)
+ {
+ reldata_section = subseg_new (".reldata", 0);
+
+ bfd_set_section_flags (stdoutput, reldata_section,
+ (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_DATA));
+
+ bfd_set_section_alignment (stdoutput, reldata_section, 2);
+ }
+ else
+ {
+ reldata_section = subseg_new (".reldata", 0);
+ }
+ ppc_set_current_section (reldata_section);
+}
+
+/* pseudo-op: .rdata
+ behaviour: predefined read only data section
+ double word aligned
+ errors: None
+ warnings: None
+ initial: .section .rdata "dr3"
+ d - initialized data
+ r - readable
+ 3 - double word aligned (that would be 4 byte boundary) */
+
+static void
+ppc_rdata (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (rdata_section == 0)
+ {
+ rdata_section = subseg_new (".rdata", 0);
+ bfd_set_section_flags (stdoutput, rdata_section,
+ (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_READONLY | SEC_DATA ));
+
+ bfd_set_section_alignment (stdoutput, rdata_section, 2);
+ }
+ else
+ {
+ rdata_section = subseg_new (".rdata", 0);
+ }
+ ppc_set_current_section (rdata_section);
+}
+
+/* pseudo-op: .ualong
+ behaviour: much like .int, with the exception that no alignment is
+ performed.
+ FIXME: test the alignment statement
+ errors: None
+ warnings: None */
+
+static void
+ppc_ualong (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ /* Try for long. */
+ cons (4);
+}
+
+/* pseudo-op: .znop <symbol name>
+ behaviour: Issue a nop instruction
+ Issue a IMAGE_REL_PPC_IFGLUE relocation against it, using
+ the supplied symbol name.
+ errors: None
+ warnings: Missing symbol name */
+
+static void
+ppc_znop (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ unsigned long insn;
+ const struct powerpc_opcode *opcode;
+ expressionS ex;
+ char *f;
+ symbolS *sym;
+ char *symbol_name;
+ char c;
+ char *name;
+ unsigned int exp;
+ flagword flags;
+ asection *sec;
+
+ /* Strip out the symbol name. */
+ symbol_name = input_line_pointer;
+ c = get_symbol_end ();
+
+ name = xmalloc (input_line_pointer - symbol_name + 1);
+ strcpy (name, symbol_name);
+
+ sym = symbol_find_or_make (name);
+
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+
+ /* Look up the opcode in the hash table. */
+ opcode = (const struct powerpc_opcode *) hash_find (ppc_hash, "nop");
+
+ /* Stick in the nop. */
+ insn = opcode->opcode;
+
+ /* Write out the instruction. */
+ f = frag_more (4);
+ md_number_to_chars (f, insn, 4);
+ fix_new (frag_now,
+ f - frag_now->fr_literal,
+ 4,
+ sym,
+ 0,
+ 0,
+ BFD_RELOC_16_GOT_PCREL);
+
+}
+
+/* pseudo-op:
+ behaviour:
+ errors:
+ warnings: */
+
+static void
+ppc_pe_comm (lcomm)
+ int lcomm;
+{
+ register char *name;
+ register char c;
+ register char *p;
+ offsetT temp;
+ register symbolS *symbolP;
+ offsetT align;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ /* just after name is now '\0'. */
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after symbol-name: rest of line ignored."));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ input_line_pointer++; /* skip ',' */
+ if ((temp = get_absolute_expression ()) < 0)
+ {
+ as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (! lcomm)
+ {
+ /* The third argument to .comm is the alignment. */
+ if (*input_line_pointer != ',')
+ align = 3;
+ else
+ {
+ ++input_line_pointer;
+ align = get_absolute_expression ();
+ if (align <= 0)
+ {
+ as_warn (_("ignoring bad alignment"));
+ align = 3;
+ }
+ }
+ }
+
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+
+ *p = c;
+ if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
+ {
+ as_bad (_("Ignoring attempt to re-define symbol `%s'."),
+ S_GET_NAME (symbolP));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (S_GET_VALUE (symbolP))
+ {
+ if (S_GET_VALUE (symbolP) != (valueT) temp)
+ as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
+ S_GET_NAME (symbolP),
+ (long) S_GET_VALUE (symbolP),
+ (long) temp);
+ }
+ else
+ {
+ S_SET_VALUE (symbolP, (valueT) temp);
+ S_SET_EXTERNAL (symbolP);
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/*
+ * implement the .section pseudo op:
+ * .section name {, "flags"}
+ * ^ ^
+ * | +--- optional flags: 'b' for bss
+ * | 'i' for info
+ * +-- section name 'l' for lib
+ * 'n' for noload
+ * 'o' for over
+ * 'w' for data
+ * 'd' (apparently m88k for data)
+ * 'x' for text
+ * But if the argument is not a quoted string, treat it as a
+ * subsegment number.
+ *
+ * FIXME: this is a copy of the section processing from obj-coff.c, with
+ * additions/changes for the moto-pas assembler support. There are three
+ * categories:
+ *
+ * FIXME: I just noticed this. This doesn't work at all really. It it
+ * setting bits that bfd probably neither understands or uses. The
+ * correct approach (?) will have to incorporate extra fields attached
+ * to the section to hold the system specific stuff. (krk)
+ *
+ * Section Contents:
+ * 'a' - unknown - referred to in documentation, but no definition supplied
+ * 'c' - section has code
+ * 'd' - section has initialized data
+ * 'u' - section has uninitialized data
+ * 'i' - section contains directives (info)
+ * 'n' - section can be discarded
+ * 'R' - remove section at link time
+ *
+ * Section Protection:
+ * 'r' - section is readable
+ * 'w' - section is writeable
+ * 'x' - section is executable
+ * 's' - section is sharable
+ *
+ * Section Alignment:
+ * '0' - align to byte boundary
+ * '1' - align to halfword undary
+ * '2' - align to word boundary
+ * '3' - align to doubleword boundary
+ * '4' - align to quadword boundary
+ * '5' - align to 32 byte boundary
+ * '6' - align to 64 byte boundary
+ *
+ */
+
+void
+ppc_pe_section (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ /* Strip out the section name. */
+ char *section_name;
+ char c;
+ char *name;
+ unsigned int exp;
+ flagword flags;
+ segT sec;
+ int align;
+
+ section_name = input_line_pointer;
+ c = get_symbol_end ();
+
+ name = xmalloc (input_line_pointer - section_name + 1);
+ strcpy (name, section_name);
+
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+
+ exp = 0;
+ flags = SEC_NO_FLAGS;
+
+ if (strcmp (name, ".idata$2") == 0)
+ {
+ align = 0;
+ }
+ else if (strcmp (name, ".idata$3") == 0)
+ {
+ align = 0;
+ }
+ else if (strcmp (name, ".idata$4") == 0)
+ {
+ align = 2;
+ }
+ else if (strcmp (name, ".idata$5") == 0)
+ {
+ align = 2;
+ }
+ else if (strcmp (name, ".idata$6") == 0)
+ {
+ align = 1;
+ }
+ else
+ /* Default alignment to 16 byte boundary. */
+ align = 4;
+
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '"')
+ exp = get_absolute_expression ();
+ else
+ {
+ ++input_line_pointer;
+ while (*input_line_pointer != '"'
+ && ! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ switch (*input_line_pointer)
+ {
+ /* Section Contents */
+ case 'a': /* unknown */
+ as_bad (_("Unsupported section attribute -- 'a'"));
+ break;
+ case 'c': /* code section */
+ flags |= SEC_CODE;
+ break;
+ case 'd': /* section has initialized data */
+ flags |= SEC_DATA;
+ break;
+ case 'u': /* section has uninitialized data */
+ /* FIXME: This is IMAGE_SCN_CNT_UNINITIALIZED_DATA
+ in winnt.h */
+ flags |= SEC_ROM;
+ break;
+ case 'i': /* section contains directives (info) */
+ /* FIXME: This is IMAGE_SCN_LNK_INFO
+ in winnt.h */
+ flags |= SEC_HAS_CONTENTS;
+ break;
+ case 'n': /* section can be discarded */
+ flags &=~ SEC_LOAD;
+ break;
+ case 'R': /* Remove section at link time */
+ flags |= SEC_NEVER_LOAD;
+ break;
+
+ /* Section Protection */
+ case 'r': /* section is readable */
+ flags |= IMAGE_SCN_MEM_READ;
+ break;
+ case 'w': /* section is writeable */
+ flags |= IMAGE_SCN_MEM_WRITE;
+ break;
+ case 'x': /* section is executable */
+ flags |= IMAGE_SCN_MEM_EXECUTE;
+ break;
+ case 's': /* section is sharable */
+ flags |= IMAGE_SCN_MEM_SHARED;
+ break;
+
+ /* Section Alignment */
+ case '0': /* align to byte boundary */
+ flags |= IMAGE_SCN_ALIGN_1BYTES;
+ align = 0;
+ break;
+ case '1': /* align to halfword boundary */
+ flags |= IMAGE_SCN_ALIGN_2BYTES;
+ align = 1;
+ break;
+ case '2': /* align to word boundary */
+ flags |= IMAGE_SCN_ALIGN_4BYTES;
+ align = 2;
+ break;
+ case '3': /* align to doubleword boundary */
+ flags |= IMAGE_SCN_ALIGN_8BYTES;
+ align = 3;
+ break;
+ case '4': /* align to quadword boundary */
+ flags |= IMAGE_SCN_ALIGN_16BYTES;
+ align = 4;
+ break;
+ case '5': /* align to 32 byte boundary */
+ flags |= IMAGE_SCN_ALIGN_32BYTES;
+ align = 5;
+ break;
+ case '6': /* align to 64 byte boundary */
+ flags |= IMAGE_SCN_ALIGN_64BYTES;
+ align = 6;
+ break;
+
+ default:
+ as_bad (_("unknown section attribute '%c'"),
+ *input_line_pointer);
+ break;
+ }
+ ++input_line_pointer;
+ }
+ if (*input_line_pointer == '"')
+ ++input_line_pointer;
+ }
+ }
+
+ sec = subseg_new (name, (subsegT) exp);
+
+ ppc_set_current_section (sec);
+
+ if (flags != SEC_NO_FLAGS)
+ {
+ if (! bfd_set_section_flags (stdoutput, sec, flags))
+ as_bad (_("error setting flags for \"%s\": %s"),
+ bfd_section_name (stdoutput, sec),
+ bfd_errmsg (bfd_get_error ()));
+ }
+
+ bfd_set_section_alignment (stdoutput, sec, align);
+
+}
+
+static void
+ppc_pe_function (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *name;
+ char endc;
+ symbolS *ext_sym;
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ ext_sym = symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ S_SET_DATA_TYPE (ext_sym, DT_FCN << N_BTSHFT);
+ SF_SET_FUNCTION (ext_sym);
+ SF_SET_PROCESS (ext_sym);
+ coff_add_linesym (ext_sym);
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+ppc_pe_tocd (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (tocdata_section == 0)
+ {
+ tocdata_section = subseg_new (".tocd", 0);
+ /* FIXME: section flags won't work. */
+ bfd_set_section_flags (stdoutput, tocdata_section,
+ (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_READONLY | SEC_DATA));
+
+ bfd_set_section_alignment (stdoutput, tocdata_section, 2);
+ }
+ else
+ {
+ rdata_section = subseg_new (".tocd", 0);
+ }
+
+ ppc_set_current_section (tocdata_section);
+
+ demand_empty_rest_of_line ();
+}
+
+/* Don't adjust TOC relocs to use the section symbol. */
+
+int
+ppc_pe_fix_adjustable (fix)
+ fixS *fix;
+{
+ return fix->fx_r_type != BFD_RELOC_PPC_TOC16;
+}
+
+#endif
+
+#ifdef OBJ_XCOFF
+
+/* XCOFF specific symbol and file handling. */
+
+/* Canonicalize the symbol name. We use the to force the suffix, if
+ any, to use square brackets, and to be in upper case. */
+
+char *
+ppc_canonicalize_symbol_name (name)
+ char *name;
+{
+ char *s;
+
+ if (ppc_stab_symbol)
+ return name;
+
+ for (s = name; *s != '\0' && *s != '{' && *s != '['; s++)
+ ;
+ if (*s != '\0')
+ {
+ char brac;
+
+ if (*s == '[')
+ brac = ']';
+ else
+ {
+ *s = '[';
+ brac = '}';
+ }
+
+ for (s++; *s != '\0' && *s != brac; s++)
+ *s = TOUPPER (*s);
+
+ if (*s == '\0' || s[1] != '\0')
+ as_bad (_("bad symbol suffix"));
+
+ *s = ']';
+ }
+
+ return name;
+}
+
+/* Set the class of a symbol based on the suffix, if any. This is
+ called whenever a new symbol is created. */
+
+void
+ppc_symbol_new_hook (sym)
+ symbolS *sym;
+{
+ struct ppc_tc_sy *tc;
+ const char *s;
+
+ tc = symbol_get_tc (sym);
+ tc->next = NULL;
+ tc->output = 0;
+ tc->class = -1;
+ tc->real_name = NULL;
+ tc->subseg = 0;
+ tc->align = 0;
+ tc->size = NULL;
+ tc->within = NULL;
+
+ if (ppc_stab_symbol)
+ return;
+
+ s = strchr (S_GET_NAME (sym), '[');
+ if (s == (const char *) NULL)
+ {
+ /* There is no suffix. */
+ return;
+ }
+
+ ++s;
+
+ switch (s[0])
+ {
+ case 'B':
+ if (strcmp (s, "BS]") == 0)
+ tc->class = XMC_BS;
+ break;
+ case 'D':
+ if (strcmp (s, "DB]") == 0)
+ tc->class = XMC_DB;
+ else if (strcmp (s, "DS]") == 0)
+ tc->class = XMC_DS;
+ break;
+ case 'G':
+ if (strcmp (s, "GL]") == 0)
+ tc->class = XMC_GL;
+ break;
+ case 'P':
+ if (strcmp (s, "PR]") == 0)
+ tc->class = XMC_PR;
+ break;
+ case 'R':
+ if (strcmp (s, "RO]") == 0)
+ tc->class = XMC_RO;
+ else if (strcmp (s, "RW]") == 0)
+ tc->class = XMC_RW;
+ break;
+ case 'S':
+ if (strcmp (s, "SV]") == 0)
+ tc->class = XMC_SV;
+ break;
+ case 'T':
+ if (strcmp (s, "TC]") == 0)
+ tc->class = XMC_TC;
+ else if (strcmp (s, "TI]") == 0)
+ tc->class = XMC_TI;
+ else if (strcmp (s, "TB]") == 0)
+ tc->class = XMC_TB;
+ else if (strcmp (s, "TC0]") == 0 || strcmp (s, "T0]") == 0)
+ tc->class = XMC_TC0;
+ break;
+ case 'U':
+ if (strcmp (s, "UA]") == 0)
+ tc->class = XMC_UA;
+ else if (strcmp (s, "UC]") == 0)
+ tc->class = XMC_UC;
+ break;
+ case 'X':
+ if (strcmp (s, "XO]") == 0)
+ tc->class = XMC_XO;
+ break;
+ }
+
+ if (tc->class == -1)
+ as_bad (_("Unrecognized symbol suffix"));
+}
+
+/* Set the class of a label based on where it is defined. This
+ handles symbols without suffixes. Also, move the symbol so that it
+ follows the csect symbol. */
+
+void
+ppc_frob_label (sym)
+ symbolS *sym;
+{
+ if (ppc_current_csect != (symbolS *) NULL)
+ {
+ if (symbol_get_tc (sym)->class == -1)
+ symbol_get_tc (sym)->class = symbol_get_tc (ppc_current_csect)->class;
+
+ symbol_remove (sym, &symbol_rootP, &symbol_lastP);
+ symbol_append (sym, symbol_get_tc (ppc_current_csect)->within,
+ &symbol_rootP, &symbol_lastP);
+ symbol_get_tc (ppc_current_csect)->within = sym;
+ }
+}
+
+/* This variable is set by ppc_frob_symbol if any absolute symbols are
+ seen. It tells ppc_adjust_symtab whether it needs to look through
+ the symbols. */
+
+static bfd_boolean ppc_saw_abs;
+
+/* Change the name of a symbol just before writing it out. Set the
+ real name if the .rename pseudo-op was used. Otherwise, remove any
+ class suffix. Return 1 if the symbol should not be included in the
+ symbol table. */
+
+int
+ppc_frob_symbol (sym)
+ symbolS *sym;
+{
+ static symbolS *ppc_last_function;
+ static symbolS *set_end;
+
+ /* Discard symbols that should not be included in the output symbol
+ table. */
+ if (! symbol_used_in_reloc_p (sym)
+ && ((symbol_get_bfdsym (sym)->flags & BSF_SECTION_SYM) != 0
+ || (! S_IS_EXTERNAL (sym)
+ && ! symbol_get_tc (sym)->output
+ && S_GET_STORAGE_CLASS (sym) != C_FILE)))
+ return 1;
+
+ /* This one will disappear anyway. Don't make a csect sym for it. */
+ if (sym == abs_section_sym)
+ return 1;
+
+ if (symbol_get_tc (sym)->real_name != (char *) NULL)
+ S_SET_NAME (sym, symbol_get_tc (sym)->real_name);
+ else
+ {
+ const char *name;
+ const char *s;
+
+ name = S_GET_NAME (sym);
+ s = strchr (name, '[');
+ if (s != (char *) NULL)
+ {
+ unsigned int len;
+ char *snew;
+
+ len = s - name;
+ snew = xmalloc (len + 1);
+ memcpy (snew, name, len);
+ snew[len] = '\0';
+
+ S_SET_NAME (sym, snew);
+ }
+ }
+
+ if (set_end != (symbolS *) NULL)
+ {
+ SA_SET_SYM_ENDNDX (set_end, sym);
+ set_end = NULL;
+ }
+
+ if (SF_GET_FUNCTION (sym))
+ {
+ if (ppc_last_function != (symbolS *) NULL)
+ as_bad (_("two .function pseudo-ops with no intervening .ef"));
+ ppc_last_function = sym;
+ if (symbol_get_tc (sym)->size != (symbolS *) NULL)
+ {
+ resolve_symbol_value (symbol_get_tc (sym)->size);
+ SA_SET_SYM_FSIZE (sym,
+ (long) S_GET_VALUE (symbol_get_tc (sym)->size));
+ }
+ }
+ else if (S_GET_STORAGE_CLASS (sym) == C_FCN
+ && strcmp (S_GET_NAME (sym), ".ef") == 0)
+ {
+ if (ppc_last_function == (symbolS *) NULL)
+ as_bad (_(".ef with no preceding .function"));
+ else
+ {
+ set_end = ppc_last_function;
+ ppc_last_function = NULL;
+
+ /* We don't have a C_EFCN symbol, but we need to force the
+ COFF backend to believe that it has seen one. */
+ coff_last_function = NULL;
+ }
+ }
+
+ if (! S_IS_EXTERNAL (sym)
+ && (symbol_get_bfdsym (sym)->flags & BSF_SECTION_SYM) == 0
+ && S_GET_STORAGE_CLASS (sym) != C_FILE
+ && S_GET_STORAGE_CLASS (sym) != C_FCN
+ && S_GET_STORAGE_CLASS (sym) != C_BLOCK
+ && S_GET_STORAGE_CLASS (sym) != C_BSTAT
+ && S_GET_STORAGE_CLASS (sym) != C_ESTAT
+ && S_GET_STORAGE_CLASS (sym) != C_BINCL
+ && S_GET_STORAGE_CLASS (sym) != C_EINCL
+ && S_GET_SEGMENT (sym) != ppc_coff_debug_section)
+ S_SET_STORAGE_CLASS (sym, C_HIDEXT);
+
+ if (S_GET_STORAGE_CLASS (sym) == C_EXT
+ || S_GET_STORAGE_CLASS (sym) == C_HIDEXT)
+ {
+ int i;
+ union internal_auxent *a;
+
+ /* Create a csect aux. */
+ i = S_GET_NUMBER_AUXILIARY (sym);
+ S_SET_NUMBER_AUXILIARY (sym, i + 1);
+ a = &coffsymbol (symbol_get_bfdsym (sym))->native[i + 1].u.auxent;
+ if (symbol_get_tc (sym)->class == XMC_TC0)
+ {
+ /* This is the TOC table. */
+ know (strcmp (S_GET_NAME (sym), "TOC") == 0);
+ a->x_csect.x_scnlen.l = 0;
+ a->x_csect.x_smtyp = (2 << 3) | XTY_SD;
+ }
+ else if (symbol_get_tc (sym)->subseg != 0)
+ {
+ /* This is a csect symbol. x_scnlen is the size of the
+ csect. */
+ if (symbol_get_tc (sym)->next == (symbolS *) NULL)
+ a->x_csect.x_scnlen.l = (bfd_section_size (stdoutput,
+ S_GET_SEGMENT (sym))
+ - S_GET_VALUE (sym));
+ else
+ {
+ resolve_symbol_value (symbol_get_tc (sym)->next);
+ a->x_csect.x_scnlen.l = (S_GET_VALUE (symbol_get_tc (sym)->next)
+ - S_GET_VALUE (sym));
+ }
+ a->x_csect.x_smtyp = (symbol_get_tc (sym)->align << 3) | XTY_SD;
+ }
+ else if (S_GET_SEGMENT (sym) == bss_section)
+ {
+ /* This is a common symbol. */
+ a->x_csect.x_scnlen.l = symbol_get_frag (sym)->fr_offset;
+ a->x_csect.x_smtyp = (symbol_get_tc (sym)->align << 3) | XTY_CM;
+ if (S_IS_EXTERNAL (sym))
+ symbol_get_tc (sym)->class = XMC_RW;
+ else
+ symbol_get_tc (sym)->class = XMC_BS;
+ }
+ else if (S_GET_SEGMENT (sym) == absolute_section)
+ {
+ /* This is an absolute symbol. The csect will be created by
+ ppc_adjust_symtab. */
+ ppc_saw_abs = TRUE;
+ a->x_csect.x_smtyp = XTY_LD;
+ if (symbol_get_tc (sym)->class == -1)
+ symbol_get_tc (sym)->class = XMC_XO;
+ }
+ else if (! S_IS_DEFINED (sym))
+ {
+ /* This is an external symbol. */
+ a->x_csect.x_scnlen.l = 0;
+ a->x_csect.x_smtyp = XTY_ER;
+ }
+ else if (symbol_get_tc (sym)->class == XMC_TC)
+ {
+ symbolS *next;
+
+ /* This is a TOC definition. x_scnlen is the size of the
+ TOC entry. */
+ next = symbol_next (sym);
+ while (symbol_get_tc (next)->class == XMC_TC0)
+ next = symbol_next (next);
+ if (next == (symbolS *) NULL
+ || symbol_get_tc (next)->class != XMC_TC)
+ {
+ if (ppc_after_toc_frag == (fragS *) NULL)
+ a->x_csect.x_scnlen.l = (bfd_section_size (stdoutput,
+ data_section)
+ - S_GET_VALUE (sym));
+ else
+ a->x_csect.x_scnlen.l = (ppc_after_toc_frag->fr_address
+ - S_GET_VALUE (sym));
+ }
+ else
+ {
+ resolve_symbol_value (next);
+ a->x_csect.x_scnlen.l = (S_GET_VALUE (next)
+ - S_GET_VALUE (sym));
+ }
+ a->x_csect.x_smtyp = (2 << 3) | XTY_SD;
+ }
+ else
+ {
+ symbolS *csect;
+
+ /* This is a normal symbol definition. x_scnlen is the
+ symbol index of the containing csect. */
+ if (S_GET_SEGMENT (sym) == text_section)
+ csect = ppc_text_csects;
+ else if (S_GET_SEGMENT (sym) == data_section)
+ csect = ppc_data_csects;
+ else
+ abort ();
+
+ /* Skip the initial dummy symbol. */
+ csect = symbol_get_tc (csect)->next;
+
+ if (csect == (symbolS *) NULL)
+ {
+ as_warn (_("warning: symbol %s has no csect"), S_GET_NAME (sym));
+ a->x_csect.x_scnlen.l = 0;
+ }
+ else
+ {
+ while (symbol_get_tc (csect)->next != (symbolS *) NULL)
+ {
+ resolve_symbol_value (symbol_get_tc (csect)->next);
+ if (S_GET_VALUE (symbol_get_tc (csect)->next)
+ > S_GET_VALUE (sym))
+ break;
+ csect = symbol_get_tc (csect)->next;
+ }
+
+ a->x_csect.x_scnlen.p =
+ coffsymbol (symbol_get_bfdsym (csect))->native;
+ coffsymbol (symbol_get_bfdsym (sym))->native[i + 1].fix_scnlen =
+ 1;
+ }
+ a->x_csect.x_smtyp = XTY_LD;
+ }
+
+ a->x_csect.x_parmhash = 0;
+ a->x_csect.x_snhash = 0;
+ if (symbol_get_tc (sym)->class == -1)
+ a->x_csect.x_smclas = XMC_PR;
+ else
+ a->x_csect.x_smclas = symbol_get_tc (sym)->class;
+ a->x_csect.x_stab = 0;
+ a->x_csect.x_snstab = 0;
+
+ /* Don't let the COFF backend resort these symbols. */
+ symbol_get_bfdsym (sym)->flags |= BSF_NOT_AT_END;
+ }
+ else if (S_GET_STORAGE_CLASS (sym) == C_BSTAT)
+ {
+ /* We want the value to be the symbol index of the referenced
+ csect symbol. BFD will do that for us if we set the right
+ flags. */
+ asymbol *bsym = symbol_get_bfdsym (symbol_get_tc (sym)->within);
+ combined_entry_type *c = coffsymbol (bsym)->native;
+
+ S_SET_VALUE (sym, (valueT) (size_t) c);
+ coffsymbol (symbol_get_bfdsym (sym))->native->fix_value = 1;
+ }
+ else if (S_GET_STORAGE_CLASS (sym) == C_STSYM)
+ {
+ symbolS *block;
+ symbolS *csect;
+
+ /* The value is the offset from the enclosing csect. */
+ block = symbol_get_tc (sym)->within;
+ csect = symbol_get_tc (block)->within;
+ resolve_symbol_value (csect);
+ S_SET_VALUE (sym, S_GET_VALUE (sym) - S_GET_VALUE (csect));
+ }
+ else if (S_GET_STORAGE_CLASS (sym) == C_BINCL
+ || S_GET_STORAGE_CLASS (sym) == C_EINCL)
+ {
+ /* We want the value to be a file offset into the line numbers.
+ BFD will do that for us if we set the right flags. We have
+ already set the value correctly. */
+ coffsymbol (symbol_get_bfdsym (sym))->native->fix_line = 1;
+ }
+
+ return 0;
+}
+
+/* Adjust the symbol table. This creates csect symbols for all
+ absolute symbols. */
+
+void
+ppc_adjust_symtab ()
+{
+ symbolS *sym;
+
+ if (! ppc_saw_abs)
+ return;
+
+ for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
+ {
+ symbolS *csect;
+ int i;
+ union internal_auxent *a;
+
+ if (S_GET_SEGMENT (sym) != absolute_section)
+ continue;
+
+ csect = symbol_create (".abs[XO]", absolute_section,
+ S_GET_VALUE (sym), &zero_address_frag);
+ symbol_get_bfdsym (csect)->value = S_GET_VALUE (sym);
+ S_SET_STORAGE_CLASS (csect, C_HIDEXT);
+ i = S_GET_NUMBER_AUXILIARY (csect);
+ S_SET_NUMBER_AUXILIARY (csect, i + 1);
+ a = &coffsymbol (symbol_get_bfdsym (csect))->native[i + 1].u.auxent;
+ a->x_csect.x_scnlen.l = 0;
+ a->x_csect.x_smtyp = XTY_SD;
+ a->x_csect.x_parmhash = 0;
+ a->x_csect.x_snhash = 0;
+ a->x_csect.x_smclas = XMC_XO;
+ a->x_csect.x_stab = 0;
+ a->x_csect.x_snstab = 0;
+
+ symbol_insert (csect, sym, &symbol_rootP, &symbol_lastP);
+
+ i = S_GET_NUMBER_AUXILIARY (sym);
+ a = &coffsymbol (symbol_get_bfdsym (sym))->native[i].u.auxent;
+ a->x_csect.x_scnlen.p = coffsymbol (symbol_get_bfdsym (csect))->native;
+ coffsymbol (symbol_get_bfdsym (sym))->native[i].fix_scnlen = 1;
+ }
+
+ ppc_saw_abs = FALSE;
+}
+
+/* Set the VMA for a section. This is called on all the sections in
+ turn. */
+
+void
+ppc_frob_section (sec)
+ asection *sec;
+{
+ static bfd_vma vma = 0;
+
+ vma = md_section_align (sec, vma);
+ bfd_set_section_vma (stdoutput, sec, vma);
+ vma += bfd_section_size (stdoutput, sec);
+}
+
+#endif /* OBJ_XCOFF */
+
+/* Turn a string in input_line_pointer into a floating point constant
+ of type TYPE, and store the appropriate bytes in *LITP. The number
+ of LITTLENUMS emitted is stored in *SIZEP. An error message is
+ returned, or NULL on OK. */
+
+char *
+md_atof (type, litp, sizep)
+ int type;
+ char *litp;
+ int *sizep;
+{
+ int prec;
+ LITTLENUM_TYPE words[4];
+ char *t;
+ int i;
+
+ switch (type)
+ {
+ case 'f':
+ prec = 2;
+ break;
+
+ case 'd':
+ prec = 4;
+ break;
+
+ default:
+ *sizep = 0;
+ return _("bad call to md_atof");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizep = prec * 2;
+
+ if (target_big_endian)
+ {
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litp, (valueT) words[i], 2);
+ litp += 2;
+ }
+ }
+ else
+ {
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litp, (valueT) words[i], 2);
+ litp += 2;
+ }
+ }
+
+ return NULL;
+}
+
+/* Write a value out to the object file, using the appropriate
+ endianness. */
+
+void
+md_number_to_chars (buf, val, n)
+ char *buf;
+ valueT val;
+ int n;
+{
+ if (target_big_endian)
+ number_to_chars_bigendian (buf, val, n);
+ else
+ number_to_chars_littleendian (buf, val, n);
+}
+
+/* Align a section (I don't know why this is machine dependent). */
+
+valueT
+md_section_align (seg, addr)
+ asection *seg;
+ valueT addr;
+{
+ int align = bfd_get_section_alignment (stdoutput, seg);
+
+ return ((addr + (1 << align) - 1) & (-1 << align));
+}
+
+/* We don't have any form of relaxing. */
+
+int
+md_estimate_size_before_relax (fragp, seg)
+ fragS *fragp ATTRIBUTE_UNUSED;
+ asection *seg ATTRIBUTE_UNUSED;
+{
+ abort ();
+ return 0;
+}
+
+/* Convert a machine dependent frag. We never generate these. */
+
+void
+md_convert_frag (abfd, sec, fragp)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *sec ATTRIBUTE_UNUSED;
+ fragS *fragp ATTRIBUTE_UNUSED;
+{
+ abort ();
+}
+
+/* We have no need to default values of symbols. */
+
+symbolS *
+md_undefined_symbol (name)
+ char *name ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
+
+/* Functions concerning relocs. */
+
+/* The location from which a PC relative jump should be calculated,
+ given a PC relative reloc. */
+
+long
+md_pcrel_from_section (fixp, sec)
+ fixS *fixp;
+ segT sec ATTRIBUTE_UNUSED;
+{
+ return fixp->fx_frag->fr_address + fixp->fx_where;
+}
+
+#ifdef OBJ_XCOFF
+
+/* This is called to see whether a fixup should be adjusted to use a
+ section symbol. We take the opportunity to change a fixup against
+ a symbol in the TOC subsegment into a reloc against the
+ corresponding .tc symbol. */
+
+int
+ppc_fix_adjustable (fix)
+ fixS *fix;
+{
+ valueT val = resolve_symbol_value (fix->fx_addsy);
+ segT symseg = S_GET_SEGMENT (fix->fx_addsy);
+ TC_SYMFIELD_TYPE *tc;
+
+ if (symseg == absolute_section)
+ return 0;
+
+ if (ppc_toc_csect != (symbolS *) NULL
+ && fix->fx_addsy != ppc_toc_csect
+ && symseg == data_section
+ && val >= ppc_toc_frag->fr_address
+ && (ppc_after_toc_frag == (fragS *) NULL
+ || val < ppc_after_toc_frag->fr_address))
+ {
+ symbolS *sy;
+
+ for (sy = symbol_next (ppc_toc_csect);
+ sy != (symbolS *) NULL;
+ sy = symbol_next (sy))
+ {
+ TC_SYMFIELD_TYPE *sy_tc = symbol_get_tc (sy);
+
+ if (sy_tc->class == XMC_TC0)
+ continue;
+ if (sy_tc->class != XMC_TC)
+ break;
+ if (val == resolve_symbol_value (sy))
+ {
+ fix->fx_addsy = sy;
+ fix->fx_addnumber = val - ppc_toc_frag->fr_address;
+ return 0;
+ }
+ }
+
+ as_bad_where (fix->fx_file, fix->fx_line,
+ _("symbol in .toc does not match any .tc"));
+ }
+
+ /* Possibly adjust the reloc to be against the csect. */
+ tc = symbol_get_tc (fix->fx_addsy);
+ if (tc->subseg == 0
+ && tc->class != XMC_TC0
+ && tc->class != XMC_TC
+ && symseg != bss_section
+ /* Don't adjust if this is a reloc in the toc section. */
+ && (symseg != data_section
+ || ppc_toc_csect == NULL
+ || val < ppc_toc_frag->fr_address
+ || (ppc_after_toc_frag != NULL
+ && val >= ppc_after_toc_frag->fr_address)))
+ {
+ symbolS *csect;
+ symbolS *next_csect;
+
+ if (symseg == text_section)
+ csect = ppc_text_csects;
+ else if (symseg == data_section)
+ csect = ppc_data_csects;
+ else
+ abort ();
+
+ /* Skip the initial dummy symbol. */
+ csect = symbol_get_tc (csect)->next;
+
+ if (csect != (symbolS *) NULL)
+ {
+ while ((next_csect = symbol_get_tc (csect)->next) != (symbolS *) NULL
+ && (symbol_get_frag (next_csect)->fr_address <= val))
+ {
+ /* If the csect address equals the symbol value, then we
+ have to look through the full symbol table to see
+ whether this is the csect we want. Note that we will
+ only get here if the csect has zero length. */
+ if (symbol_get_frag (csect)->fr_address == val
+ && S_GET_VALUE (csect) == val)
+ {
+ symbolS *scan;
+
+ for (scan = symbol_next (csect);
+ scan != NULL;
+ scan = symbol_next (scan))
+ {
+ if (symbol_get_tc (scan)->subseg != 0)
+ break;
+ if (scan == fix->fx_addsy)
+ break;
+ }
+
+ /* If we found the symbol before the next csect
+ symbol, then this is the csect we want. */
+ if (scan == fix->fx_addsy)
+ break;
+ }
+
+ csect = next_csect;
+ }
+
+ fix->fx_offset += val - symbol_get_frag (csect)->fr_address;
+ fix->fx_addsy = csect;
+ }
+ return 0;
+ }
+
+ /* Adjust a reloc against a .lcomm symbol to be against the base
+ .lcomm. */
+ if (symseg == bss_section
+ && ! S_IS_EXTERNAL (fix->fx_addsy))
+ {
+ symbolS *sy = symbol_get_frag (fix->fx_addsy)->fr_symbol;
+
+ fix->fx_offset += val - resolve_symbol_value (sy);
+ fix->fx_addsy = sy;
+ }
+
+ return 0;
+}
+
+/* A reloc from one csect to another must be kept. The assembler
+ will, of course, keep relocs between sections, and it will keep
+ absolute relocs, but we need to force it to keep PC relative relocs
+ between two csects in the same section. */
+
+int
+ppc_force_relocation (fix)
+ fixS *fix;
+{
+ /* At this point fix->fx_addsy should already have been converted to
+ a csect symbol. If the csect does not include the fragment, then
+ we need to force the relocation. */
+ if (fix->fx_pcrel
+ && fix->fx_addsy != NULL
+ && symbol_get_tc (fix->fx_addsy)->subseg != 0
+ && ((symbol_get_frag (fix->fx_addsy)->fr_address
+ > fix->fx_frag->fr_address)
+ || (symbol_get_tc (fix->fx_addsy)->next != NULL
+ && (symbol_get_frag (symbol_get_tc (fix->fx_addsy)->next)->fr_address
+ <= fix->fx_frag->fr_address))))
+ return 1;
+
+ return generic_force_reloc (fix);
+}
+
+#endif /* OBJ_XCOFF */
+
+#ifdef OBJ_ELF
+/* If this function returns non-zero, it guarantees that a relocation
+ will be emitted for a fixup. */
+
+int
+ppc_force_relocation (fix)
+ fixS *fix;
+{
+ /* Branch prediction relocations must force a relocation, as must
+ the vtable description relocs. */
+ switch (fix->fx_r_type)
+ {
+ case BFD_RELOC_PPC_B16_BRTAKEN:
+ case BFD_RELOC_PPC_B16_BRNTAKEN:
+ case BFD_RELOC_PPC_BA16_BRTAKEN:
+ case BFD_RELOC_PPC_BA16_BRNTAKEN:
+ case BFD_RELOC_PPC64_TOC:
+ return 1;
+ default:
+ break;
+ }
+
+ if (fix->fx_r_type >= BFD_RELOC_PPC_TLS
+ && fix->fx_r_type <= BFD_RELOC_PPC64_DTPREL16_HIGHESTA)
+ return 1;
+
+ return generic_force_reloc (fix);
+}
+
+int
+ppc_fix_adjustable (fix)
+ fixS *fix;
+{
+ return (fix->fx_r_type != BFD_RELOC_16_GOTOFF
+ && fix->fx_r_type != BFD_RELOC_LO16_GOTOFF
+ && fix->fx_r_type != BFD_RELOC_HI16_GOTOFF
+ && fix->fx_r_type != BFD_RELOC_HI16_S_GOTOFF
+ && fix->fx_r_type != BFD_RELOC_GPREL16
+ && fix->fx_r_type != BFD_RELOC_VTABLE_INHERIT
+ && fix->fx_r_type != BFD_RELOC_VTABLE_ENTRY
+ && !(fix->fx_r_type >= BFD_RELOC_PPC_TLS
+ && fix->fx_r_type <= BFD_RELOC_PPC64_DTPREL16_HIGHESTA)
+ && (fix->fx_pcrel
+ || (fix->fx_subsy != NULL
+ && (S_GET_SEGMENT (fix->fx_subsy)
+ == S_GET_SEGMENT (fix->fx_addsy)))
+ || S_IS_LOCAL (fix->fx_addsy)));
+}
+#endif
+
+/* Apply a fixup to the object code. This is called for all the
+ fixups we generated by the call to fix_new_exp, above. In the call
+ above we used a reloc code which was the largest legal reloc code
+ plus the operand index. Here we undo that to recover the operand
+ index. At this point all symbol values should be fully resolved,
+ and we attempt to completely resolve the reloc. If we can not do
+ that, we determine the correct reloc code and put it back in the
+ fixup. */
+
+void
+md_apply_fix3 (fixP, valP, seg)
+ fixS *fixP;
+ valueT * valP;
+ segT seg ATTRIBUTE_UNUSED;
+{
+ valueT value = * valP;
+
+#ifdef OBJ_ELF
+ if (fixP->fx_addsy != NULL)
+ {
+ /* Hack around bfd_install_relocation brain damage. */
+ if (fixP->fx_pcrel)
+ value += fixP->fx_frag->fr_address + fixP->fx_where;
+ }
+ else
+ fixP->fx_done = 1;
+#else
+ /* FIXME FIXME FIXME: The value we are passed in *valP includes
+ the symbol values. Since we are using BFD_ASSEMBLER, if we are
+ doing this relocation the code in write.c is going to call
+ bfd_install_relocation, which is also going to use the symbol
+ value. That means that if the reloc is fully resolved we want to
+ use *valP since bfd_install_relocation is not being used.
+ However, if the reloc is not fully resolved we do not want to use
+ *valP, and must use fx_offset instead. However, if the reloc
+ is PC relative, we do want to use *valP since it includes the
+ result of md_pcrel_from. This is confusing. */
+ if (fixP->fx_addsy == (symbolS *) NULL)
+ fixP->fx_done = 1;
+
+ else if (fixP->fx_pcrel)
+ ;
+
+ else
+ value = fixP->fx_offset;
+#endif
+
+ if (fixP->fx_subsy != (symbolS *) NULL)
+ {
+ /* We can't actually support subtracting a symbol. */
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
+ }
+
+ if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
+ {
+ int opindex;
+ const struct powerpc_operand *operand;
+ char *where;
+ unsigned long insn;
+
+ opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
+
+ operand = &powerpc_operands[opindex];
+
+#ifdef OBJ_XCOFF
+ /* An instruction like `lwz 9,sym(30)' when `sym' is not a TOC symbol
+ does not generate a reloc. It uses the offset of `sym' within its
+ csect. Other usages, such as `.long sym', generate relocs. This
+ is the documented behaviour of non-TOC symbols. */
+ if ((operand->flags & PPC_OPERAND_PARENS) != 0
+ && operand->bits == 16
+ && operand->shift == 0
+ && (operand->insert == NULL || ppc_obj64)
+ && fixP->fx_addsy != NULL
+ && symbol_get_tc (fixP->fx_addsy)->subseg != 0
+ && symbol_get_tc (fixP->fx_addsy)->class != XMC_TC
+ && symbol_get_tc (fixP->fx_addsy)->class != XMC_TC0
+ && S_GET_SEGMENT (fixP->fx_addsy) != bss_section)
+ {
+ value = fixP->fx_offset;
+ fixP->fx_done = 1;
+ }
+#endif
+
+ /* Fetch the instruction, insert the fully resolved operand
+ value, and stuff the instruction back again. */
+ where = fixP->fx_frag->fr_literal + fixP->fx_where;
+ if (target_big_endian)
+ insn = bfd_getb32 ((unsigned char *) where);
+ else
+ insn = bfd_getl32 ((unsigned char *) where);
+ insn = ppc_insert_operand (insn, operand, (offsetT) value,
+ fixP->fx_file, fixP->fx_line);
+ if (target_big_endian)
+ bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ else
+ bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
+
+ if (fixP->fx_done)
+ /* Nothing else to do here. */
+ return;
+
+ assert (fixP->fx_addsy != NULL);
+
+ /* Determine a BFD reloc value based on the operand information.
+ We are only prepared to turn a few of the operands into
+ relocs. */
+ if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
+ && operand->bits == 26
+ && operand->shift == 0)
+ fixP->fx_r_type = BFD_RELOC_PPC_B26;
+ else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
+ && operand->bits == 16
+ && operand->shift == 0)
+ {
+ fixP->fx_r_type = BFD_RELOC_PPC_B16;
+#ifdef OBJ_XCOFF
+ fixP->fx_size = 2;
+ if (target_big_endian)
+ fixP->fx_where += 2;
+#endif
+ }
+ else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
+ && operand->bits == 26
+ && operand->shift == 0)
+ fixP->fx_r_type = BFD_RELOC_PPC_BA26;
+ else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
+ && operand->bits == 16
+ && operand->shift == 0)
+ {
+ fixP->fx_r_type = BFD_RELOC_PPC_BA16;
+#ifdef OBJ_XCOFF
+ fixP->fx_size = 2;
+ if (target_big_endian)
+ fixP->fx_where += 2;
+#endif
+ }
+#if defined (OBJ_XCOFF) || defined (OBJ_ELF)
+ else if ((operand->flags & PPC_OPERAND_PARENS) != 0
+ && operand->bits == 16
+ && operand->shift == 0)
+ {
+ if (ppc_is_toc_sym (fixP->fx_addsy))
+ {
+ fixP->fx_r_type = BFD_RELOC_PPC_TOC16;
+#ifdef OBJ_ELF
+ if (ppc_obj64
+ && (operand->flags & PPC_OPERAND_DS) != 0)
+ fixP->fx_r_type = BFD_RELOC_PPC64_TOC16_DS;
+#endif
+ }
+ else
+ {
+ fixP->fx_r_type = BFD_RELOC_16;
+#ifdef OBJ_ELF
+ if (ppc_obj64
+ && (operand->flags & PPC_OPERAND_DS) != 0)
+ fixP->fx_r_type = BFD_RELOC_PPC64_ADDR16_DS;
+#endif
+ }
+ fixP->fx_size = 2;
+ if (target_big_endian)
+ fixP->fx_where += 2;
+ }
+#endif /* defined (OBJ_XCOFF) || defined (OBJ_ELF) */
+ else
+ {
+ char *sfile;
+ unsigned int sline;
+
+ /* Use expr_symbol_where to see if this is an expression
+ symbol. */
+ if (expr_symbol_where (fixP->fx_addsy, &sfile, &sline))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("unresolved expression that must be resolved"));
+ else
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("unsupported relocation against %s"),
+ S_GET_NAME (fixP->fx_addsy));
+ fixP->fx_done = 1;
+ return;
+ }
+ }
+ else
+ {
+#ifdef OBJ_ELF
+ ppc_elf_validate_fix (fixP, seg);
+#endif
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_CTOR:
+ if (ppc_obj64)
+ goto ctor64;
+ /* fall through */
+
+ case BFD_RELOC_32:
+ if (fixP->fx_pcrel)
+ fixP->fx_r_type = BFD_RELOC_32_PCREL;
+ /* fall through */
+
+ case BFD_RELOC_RVA:
+ case BFD_RELOC_32_PCREL:
+ case BFD_RELOC_PPC_EMB_NADDR32:
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 4);
+ break;
+
+ case BFD_RELOC_64:
+ ctor64:
+ if (fixP->fx_pcrel)
+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
+ /* fall through */
+
+ case BFD_RELOC_64_PCREL:
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 8);
+ break;
+
+ case BFD_RELOC_LO16:
+ case BFD_RELOC_16:
+ case BFD_RELOC_GPREL16:
+ case BFD_RELOC_16_GOT_PCREL:
+ case BFD_RELOC_16_GOTOFF:
+ case BFD_RELOC_LO16_GOTOFF:
+ case BFD_RELOC_HI16_GOTOFF:
+ case BFD_RELOC_HI16_S_GOTOFF:
+ case BFD_RELOC_16_BASEREL:
+ case BFD_RELOC_LO16_BASEREL:
+ case BFD_RELOC_HI16_BASEREL:
+ case BFD_RELOC_HI16_S_BASEREL:
+ case BFD_RELOC_PPC_EMB_NADDR16:
+ case BFD_RELOC_PPC_EMB_NADDR16_LO:
+ case BFD_RELOC_PPC_EMB_NADDR16_HI:
+ case BFD_RELOC_PPC_EMB_NADDR16_HA:
+ case BFD_RELOC_PPC_EMB_SDAI16:
+ case BFD_RELOC_PPC_EMB_SDA2REL:
+ case BFD_RELOC_PPC_EMB_SDA2I16:
+ case BFD_RELOC_PPC_EMB_RELSEC16:
+ case BFD_RELOC_PPC_EMB_RELST_LO:
+ case BFD_RELOC_PPC_EMB_RELST_HI:
+ case BFD_RELOC_PPC_EMB_RELST_HA:
+ case BFD_RELOC_PPC_EMB_RELSDA:
+ case BFD_RELOC_PPC_TOC16:
+#ifdef OBJ_ELF
+ case BFD_RELOC_PPC64_TOC16_LO:
+ case BFD_RELOC_PPC64_TOC16_HI:
+ case BFD_RELOC_PPC64_TOC16_HA:
+#endif
+ if (fixP->fx_pcrel)
+ {
+ if (fixP->fx_addsy != NULL)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("cannot emit PC relative %s relocation against %s"),
+ bfd_get_reloc_code_name (fixP->fx_r_type),
+ S_GET_NAME (fixP->fx_addsy));
+ else
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("cannot emit PC relative %s relocation"),
+ bfd_get_reloc_code_name (fixP->fx_r_type));
+ }
+
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 2);
+ break;
+
+ /* This case happens when you write, for example,
+ lis %r3,(L1-L2)@ha
+ where L1 and L2 are defined later. */
+ case BFD_RELOC_HI16:
+ if (fixP->fx_pcrel)
+ abort ();
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ PPC_HI (value), 2);
+ break;
+
+ case BFD_RELOC_HI16_S:
+ if (fixP->fx_pcrel)
+ abort ();
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ PPC_HA (value), 2);
+ break;
+
+#ifdef OBJ_ELF
+ case BFD_RELOC_PPC64_HIGHER:
+ if (fixP->fx_pcrel)
+ abort ();
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ PPC_HIGHER (value), 2);
+ break;
+
+ case BFD_RELOC_PPC64_HIGHER_S:
+ if (fixP->fx_pcrel)
+ abort ();
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ PPC_HIGHERA (value), 2);
+ break;
+
+ case BFD_RELOC_PPC64_HIGHEST:
+ if (fixP->fx_pcrel)
+ abort ();
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ PPC_HIGHEST (value), 2);
+ break;
+
+ case BFD_RELOC_PPC64_HIGHEST_S:
+ if (fixP->fx_pcrel)
+ abort ();
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ PPC_HIGHESTA (value), 2);
+ break;
+
+ case BFD_RELOC_PPC64_ADDR16_DS:
+ case BFD_RELOC_PPC64_ADDR16_LO_DS:
+ case BFD_RELOC_PPC64_GOT16_DS:
+ case BFD_RELOC_PPC64_GOT16_LO_DS:
+ case BFD_RELOC_PPC64_PLT16_LO_DS:
+ case BFD_RELOC_PPC64_SECTOFF_DS:
+ case BFD_RELOC_PPC64_SECTOFF_LO_DS:
+ case BFD_RELOC_PPC64_TOC16_DS:
+ case BFD_RELOC_PPC64_TOC16_LO_DS:
+ case BFD_RELOC_PPC64_PLTGOT16_DS:
+ case BFD_RELOC_PPC64_PLTGOT16_LO_DS:
+ if (fixP->fx_pcrel)
+ abort ();
+ {
+ unsigned char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
+ unsigned long val, mask;
+
+ if (target_big_endian)
+ val = bfd_getb32 (where - 2);
+ else
+ val = bfd_getl32 (where);
+ mask = 0xfffc;
+ /* lq insns reserve the four lsbs. */
+ if ((ppc_cpu & PPC_OPCODE_POWER4) != 0
+ && (val & (0x3f << 26)) == (56u << 26))
+ mask = 0xfff0;
+ val |= value & mask;
+ if (target_big_endian)
+ bfd_putb16 ((bfd_vma) val, where);
+ else
+ bfd_putl16 ((bfd_vma) val, where);
+ }
+ break;
+
+ case BFD_RELOC_PPC_B16_BRTAKEN:
+ case BFD_RELOC_PPC_B16_BRNTAKEN:
+ case BFD_RELOC_PPC_BA16_BRTAKEN:
+ case BFD_RELOC_PPC_BA16_BRNTAKEN:
+ break;
+
+ case BFD_RELOC_PPC_TLS:
+ case BFD_RELOC_PPC_DTPMOD:
+ case BFD_RELOC_PPC_TPREL16:
+ case BFD_RELOC_PPC_TPREL16_LO:
+ case BFD_RELOC_PPC_TPREL16_HI:
+ case BFD_RELOC_PPC_TPREL16_HA:
+ case BFD_RELOC_PPC_TPREL:
+ case BFD_RELOC_PPC_DTPREL16:
+ case BFD_RELOC_PPC_DTPREL16_LO:
+ case BFD_RELOC_PPC_DTPREL16_HI:
+ case BFD_RELOC_PPC_DTPREL16_HA:
+ case BFD_RELOC_PPC_DTPREL:
+ case BFD_RELOC_PPC_GOT_TLSGD16:
+ case BFD_RELOC_PPC_GOT_TLSGD16_LO:
+ case BFD_RELOC_PPC_GOT_TLSGD16_HI:
+ case BFD_RELOC_PPC_GOT_TLSGD16_HA:
+ case BFD_RELOC_PPC_GOT_TLSLD16:
+ case BFD_RELOC_PPC_GOT_TLSLD16_LO:
+ case BFD_RELOC_PPC_GOT_TLSLD16_HI:
+ case BFD_RELOC_PPC_GOT_TLSLD16_HA:
+ case BFD_RELOC_PPC_GOT_TPREL16:
+ case BFD_RELOC_PPC_GOT_TPREL16_LO:
+ case BFD_RELOC_PPC_GOT_TPREL16_HI:
+ case BFD_RELOC_PPC_GOT_TPREL16_HA:
+ case BFD_RELOC_PPC_GOT_DTPREL16:
+ case BFD_RELOC_PPC_GOT_DTPREL16_LO:
+ case BFD_RELOC_PPC_GOT_DTPREL16_HI:
+ case BFD_RELOC_PPC_GOT_DTPREL16_HA:
+ case BFD_RELOC_PPC64_TPREL16_DS:
+ case BFD_RELOC_PPC64_TPREL16_LO_DS:
+ case BFD_RELOC_PPC64_TPREL16_HIGHER:
+ case BFD_RELOC_PPC64_TPREL16_HIGHERA:
+ case BFD_RELOC_PPC64_TPREL16_HIGHEST:
+ case BFD_RELOC_PPC64_TPREL16_HIGHESTA:
+ case BFD_RELOC_PPC64_DTPREL16_DS:
+ case BFD_RELOC_PPC64_DTPREL16_LO_DS:
+ case BFD_RELOC_PPC64_DTPREL16_HIGHER:
+ case BFD_RELOC_PPC64_DTPREL16_HIGHERA:
+ case BFD_RELOC_PPC64_DTPREL16_HIGHEST:
+ case BFD_RELOC_PPC64_DTPREL16_HIGHESTA:
+ break;
+#endif
+ /* Because SDA21 modifies the register field, the size is set to 4
+ bytes, rather than 2, so offset it here appropriately. */
+ case BFD_RELOC_PPC_EMB_SDA21:
+ if (fixP->fx_pcrel)
+ abort ();
+
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where
+ + ((target_big_endian) ? 2 : 0),
+ value, 2);
+ break;
+
+ case BFD_RELOC_8:
+ if (fixP->fx_pcrel)
+ {
+ /* This can occur if there is a bug in the input assembler, eg:
+ ".byte <undefined_symbol> - ." */
+ if (fixP->fx_addsy)
+ as_bad (_("Unable to handle reference to symbol %s"),
+ S_GET_NAME (fixP->fx_addsy));
+ else
+ as_bad (_("Unable to resolve expression"));
+ fixP->fx_done = 1;
+ }
+ else
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 1);
+ break;
+
+ case BFD_RELOC_24_PLT_PCREL:
+ case BFD_RELOC_PPC_LOCAL24PC:
+ if (!fixP->fx_pcrel && !fixP->fx_done)
+ abort ();
+
+ if (fixP->fx_done)
+ {
+ char *where;
+ unsigned long insn;
+
+ /* Fetch the instruction, insert the fully resolved operand
+ value, and stuff the instruction back again. */
+ where = fixP->fx_frag->fr_literal + fixP->fx_where;
+ if (target_big_endian)
+ insn = bfd_getb32 ((unsigned char *) where);
+ else
+ insn = bfd_getl32 ((unsigned char *) where);
+ if ((value & 3) != 0)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("must branch to an address a multiple of 4"));
+ if ((offsetT) value < -0x40000000
+ || (offsetT) value >= 0x40000000)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("@local or @plt branch destination is too far away, %ld bytes"),
+ (long) value);
+ insn = insn | (value & 0x03fffffc);
+ if (target_big_endian)
+ bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ else
+ bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
+ }
+ break;
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ fixP->fx_done = 0;
+ if (fixP->fx_addsy
+ && !S_IS_DEFINED (fixP->fx_addsy)
+ && !S_IS_WEAK (fixP->fx_addsy))
+ S_SET_WEAK (fixP->fx_addsy);
+ break;
+
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixP->fx_done = 0;
+ break;
+
+#ifdef OBJ_ELF
+ /* Generated by reference to `sym@tocbase'. The sym is
+ ignored by the linker. */
+ case BFD_RELOC_PPC64_TOC:
+ fixP->fx_done = 0;
+ break;
+#endif
+ default:
+ fprintf (stderr,
+ _("Gas failure, reloc value %d\n"), fixP->fx_r_type);
+ fflush (stderr);
+ abort ();
+ }
+ }
+
+#ifdef OBJ_ELF
+ fixP->fx_addnumber = value;
+#else
+ if (fixP->fx_r_type != BFD_RELOC_PPC_TOC16)
+ fixP->fx_addnumber = 0;
+ else
+ {
+#ifdef TE_PE
+ fixP->fx_addnumber = 0;
+#else
+ /* We want to use the offset within the data segment of the
+ symbol, not the actual VMA of the symbol. */
+ fixP->fx_addnumber =
+ - bfd_get_section_vma (stdoutput, S_GET_SEGMENT (fixP->fx_addsy));
+#endif
+ }
+#endif
+}
+
+/* Generate a reloc for a fixup. */
+
+arelent *
+tc_gen_reloc (seg, fixp)
+ asection *seg ATTRIBUTE_UNUSED;
+ fixS *fixp;
+{
+ arelent *reloc;
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+ if (reloc->howto == (reloc_howto_type *) NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("reloc %d not supported by object file format"),
+ (int) fixp->fx_r_type);
+ return NULL;
+ }
+ reloc->addend = fixp->fx_addnumber;
+
+ return reloc;
+}
+
+void
+ppc_cfi_frame_initial_instructions ()
+{
+ cfi_add_CFA_def_cfa (1, 0);
+}
+
+int
+tc_ppc_regname_to_dw2regnum (const char *regname)
+{
+ unsigned int regnum = -1;
+ unsigned int i;
+ const char *p;
+ char *q;
+ static struct { char *name; int dw2regnum; } regnames[] =
+ {
+ { "sp", 1 }, { "r.sp", 1 }, { "rtoc", 2 }, { "r.toc", 2 },
+ { "mq", 64 }, { "lr", 65 }, { "ctr", 66 }, { "ap", 67 },
+ { "cc", 68 }, { "xer", 76 }, { "vrsave", 109 }, { "vscr", 110 },
+ { "spe_acc", 111 }, { "spefscr", 112 }
+ };
+
+ for (i = 0; i < ARRAY_SIZE (regnames); ++i)
+ if (strcmp (regnames[i].name, regname) == 0)
+ return regnames[i].dw2regnum;
+
+ if (regname[0] == 'r' || regname[0] == 'f' || regname[0] == 'v')
+ {
+ p = regname + 1 + (regname[1] == '.');
+ regnum = strtoul (p, &q, 10);
+ if (p == q || *q || regnum >= 32)
+ return -1;
+ if (regname[0] == 'f')
+ regnum += 32;
+ else if (regname[0] == 'v')
+ regnum += 77;
+ }
+ else if (regname[0] == 'c' && regname[1] == 'r')
+ {
+ p = regname + 2 + (regname[2] == '.');
+ if (p[0] < '0' || p[0] > '7' || p[1])
+ return -1;
+ regnum = p[0] - '0' + 68;
+ }
+ return regnum;
+}
diff --git a/x/binutils/gas/config/tc-ppc.h b/x/binutils/gas/config/tc-ppc.h
new file mode 100644
index 0000000..0844f84
--- /dev/null
+++ b/x/binutils/gas/config/tc-ppc.h
@@ -0,0 +1,269 @@
+/* tc-ppc.h -- Header file for tc-ppc.c.
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_PPC
+
+#ifdef ANSI_PROTOTYPES
+struct fix;
+#endif
+
+/* Set the endianness we are using. Default to big endian. */
+#ifndef TARGET_BYTES_BIG_ENDIAN
+#define TARGET_BYTES_BIG_ENDIAN 1
+#endif
+
+#ifndef BFD_ASSEMBLER
+ #error PowerPC support requires BFD_ASSEMBLER
+#endif
+
+/* If OBJ_COFF is defined, and TE_PE is not defined, we are assembling
+ XCOFF for AIX or PowerMac. If TE_PE is defined, we are assembling
+ COFF for Windows NT. */
+
+#ifdef OBJ_COFF
+#ifndef TE_PE
+#define OBJ_XCOFF
+#endif
+#endif
+
+/* The target BFD architecture. */
+#define TARGET_ARCH (ppc_arch ())
+#define TARGET_MACH (ppc_mach ())
+extern enum bfd_architecture ppc_arch PARAMS ((void));
+extern unsigned long ppc_mach PARAMS ((void));
+
+/* Whether or not the target is big endian */
+extern int target_big_endian;
+
+/* The target BFD format. */
+#define TARGET_FORMAT (ppc_target_format ())
+extern char *ppc_target_format PARAMS ((void));
+
+/* Permit temporary numeric labels. */
+#define LOCAL_LABELS_FB 1
+
+/* $ is used to refer to the current location. */
+#define DOLLAR_DOT
+
+/* Strings do not use backslash escapes under COFF. */
+#ifdef OBJ_COFF
+#define NO_STRING_ESCAPES
+#endif
+
+#ifdef OBJ_ELF
+#define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs */
+#endif
+
+#if TARGET_BYTES_BIG_ENDIAN
+#define PPC_BIG_ENDIAN 1
+#else
+#define PPC_BIG_ENDIAN 0
+#endif
+
+/* We don't need to handle .word strangely. */
+#define WORKING_DOT_WORD
+
+#define MAX_MEM_FOR_RS_ALIGN_CODE 4
+#define HANDLE_ALIGN(FRAGP) \
+ if ((FRAGP)->fr_type == rs_align_code) \
+ { \
+ valueT count = ((FRAGP)->fr_next->fr_address \
+ - ((FRAGP)->fr_address + (FRAGP)->fr_fix)); \
+ if (count != 0 && (count & 3) == 0) \
+ { \
+ unsigned char *dest = (FRAGP)->fr_literal + (FRAGP)->fr_fix; \
+ \
+ (FRAGP)->fr_var = 4; \
+ if (target_big_endian) \
+ { \
+ *dest++ = 0x60; \
+ *dest++ = 0; \
+ *dest++ = 0; \
+ *dest++ = 0; \
+ } \
+ else \
+ { \
+ *dest++ = 0; \
+ *dest++ = 0; \
+ *dest++ = 0; \
+ *dest++ = 0x60; \
+ } \
+ } \
+ }
+
+
+#ifdef TE_PE
+
+/* Question marks are permitted in symbol names. */
+#define LEX_QM 1
+
+/* Don't adjust TOC relocs. */
+#define tc_fix_adjustable(FIX) ppc_pe_fix_adjustable (FIX)
+extern int ppc_pe_fix_adjustable PARAMS ((struct fix *));
+
+#endif
+
+#ifdef OBJ_XCOFF
+
+/* Declarations needed when generating XCOFF code. XCOFF is an
+ extension of COFF, used only on the RS/6000. Rather than create an
+ obj-xcoff, we just use obj-coff, and handle the extensions here in
+ tc-ppc. */
+
+/* We need to keep some information for symbols. */
+struct ppc_tc_sy
+{
+ /* We keep a few linked lists of symbols. */
+ symbolS *next;
+ /* Non-zero if the symbol should be output. The RS/6000 assembler
+ only outputs symbols that are external or are mentioned in a
+ .globl or .lglobl statement. */
+ int output;
+ /* The symbol class. */
+ int class;
+ /* The real name, if the symbol was renamed. */
+ char *real_name;
+ /* For a csect symbol, the subsegment we are using. This is zero
+ for symbols that are not csects. */
+ subsegT subseg;
+ /* For a csect or common symbol, the alignment to use. */
+ int align;
+ /* For a function symbol, a symbol whose value is the size. The
+ field is NULL if there is no size. */
+ symbolS *size;
+ /* For a csect symbol, the last symbol which has been defined in
+ this csect, or NULL if none have been defined so far. For a .bs
+ symbol, the referenced csect symbol. */
+ symbolS *within;
+};
+
+#define TC_SYMFIELD_TYPE struct ppc_tc_sy
+
+/* We need an additional auxent for function symbols. */
+#define OBJ_COFF_MAX_AUXENTRIES 2
+
+/* Square and curly brackets are permitted in symbol names. */
+#define LEX_BR 3
+
+/* Canonicalize the symbol name. */
+#define tc_canonicalize_symbol_name(name) ppc_canonicalize_symbol_name (name)
+extern char *ppc_canonicalize_symbol_name PARAMS ((char *));
+
+/* Get the symbol class from the name. */
+#define tc_symbol_new_hook(sym) ppc_symbol_new_hook (sym)
+extern void ppc_symbol_new_hook PARAMS ((symbolS *));
+
+/* Set the symbol class of a label based on the csect. */
+#define tc_frob_label(sym) ppc_frob_label (sym)
+extern void ppc_frob_label PARAMS ((symbolS *));
+
+/* TOC relocs requires special handling. */
+#define tc_fix_adjustable(FIX) ppc_fix_adjustable (FIX)
+extern int ppc_fix_adjustable PARAMS ((struct fix *));
+
+/* We need to set the section VMA. */
+#define tc_frob_section(sec) ppc_frob_section (sec)
+extern void ppc_frob_section PARAMS ((asection *));
+
+/* Finish up the symbol. */
+#define tc_frob_symbol(sym, punt) punt = ppc_frob_symbol (sym)
+extern int ppc_frob_symbol PARAMS ((symbolS *));
+
+/* Finish up the entire symtab. */
+#define tc_adjust_symtab() ppc_adjust_symtab ()
+extern void ppc_adjust_symtab PARAMS ((void));
+
+/* We also need to copy, in particular, the class of the symbol,
+ over what obj-coff would otherwise have copied. */
+#define OBJ_COPY_SYMBOL_ATTRIBUTES(dest,src) \
+do { \
+ if (SF_GET_GET_SEGMENT (dest)) \
+ S_SET_SEGMENT (dest, S_GET_SEGMENT (src)); \
+ symbol_get_tc (dest)->size = symbol_get_tc (src)->size; \
+ symbol_get_tc (dest)->align = symbol_get_tc (src)->align; \
+ symbol_get_tc (dest)->class = symbol_get_tc (src)->class; \
+ symbol_get_tc (dest)->within = symbol_get_tc (src)->within; \
+} while (0)
+
+#endif /* OBJ_XCOFF */
+
+extern const char ppc_symbol_chars[];
+#define tc_symbol_chars ppc_symbol_chars
+
+#ifdef OBJ_ELF
+
+/* Support for SHF_EXCLUDE and SHT_ORDERED */
+extern int ppc_section_letter PARAMS ((int, char **));
+extern int ppc_section_type PARAMS ((char *, size_t));
+extern int ppc_section_word PARAMS ((char *, size_t));
+extern int ppc_section_flags PARAMS ((int, int, int));
+
+#define md_elf_section_letter(LETTER, PTR_MSG) ppc_section_letter (LETTER, PTR_MSG)
+#define md_elf_section_type(STR, LEN) ppc_section_type (STR, LEN)
+#define md_elf_section_word(STR, LEN) ppc_section_word (STR, LEN)
+#define md_elf_section_flags(FLAGS, ATTR, TYPE) ppc_section_flags (FLAGS, ATTR, TYPE)
+
+#define tc_comment_chars ppc_comment_chars
+extern const char *ppc_comment_chars;
+
+/* Keep relocations relative to the GOT, or non-PC relative. */
+#define tc_fix_adjustable(FIX) ppc_fix_adjustable (FIX)
+extern int ppc_fix_adjustable PARAMS ((struct fix *));
+
+/* Values passed to md_apply_fix3 don't include symbol values. */
+#define MD_APPLY_SYM_VALUE(FIX) 0
+
+#define tc_frob_file_before_adjust ppc_frob_file_before_adjust
+extern void ppc_frob_file_before_adjust PARAMS ((void));
+
+#endif /* OBJ_ELF */
+
+#if defined (OBJ_ELF) || defined (OBJ_XCOFF)
+#define TC_FORCE_RELOCATION(FIX) ppc_force_relocation (FIX)
+extern int ppc_force_relocation PARAMS ((struct fix *));
+#endif
+
+/* call md_pcrel_from_section, not md_pcrel_from */
+#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section(FIX, SEC)
+extern long md_pcrel_from_section PARAMS ((struct fix *, segT));
+
+#define md_parse_name(name, exp, c) ppc_parse_name (name, exp)
+extern int ppc_parse_name PARAMS ((const char *, struct expressionS *));
+
+#define md_operand(x)
+
+#define md_cleanup() ppc_cleanup ()
+ extern void ppc_cleanup PARAMS ((void));
+
+#define TARGET_USE_CFIPOP 1
+
+#define tc_cfi_frame_initial_instructions ppc_cfi_frame_initial_instructions
+extern void ppc_cfi_frame_initial_instructions PARAMS ((void));
+
+#define tc_regname_to_dw2regnum tc_ppc_regname_to_dw2regnum
+extern int tc_ppc_regname_to_dw2regnum PARAMS ((const char *regname));
+
+extern int ppc_cie_data_alignment;
+
+#define DWARF2_LINE_MIN_INSN_LENGTH 4
+#define DWARF2_DEFAULT_RETURN_COLUMN 0x41
+#define DWARF2_CIE_DATA_ALIGNMENT ppc_cie_data_alignment
diff --git a/x/binutils/gas/config/tc-s390.c b/x/binutils/gas/config/tc-s390.c
new file mode 100644
index 0000000..4fafbec
--- /dev/null
+++ b/x/binutils/gas/config/tc-s390.c
@@ -0,0 +1,2311 @@
+/* tc-s390.c -- Assemble for the S390
+ Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <stdio.h>
+#include "as.h"
+#include "safe-ctype.h"
+#include "subsegs.h"
+#include "struc-symbol.h"
+#include "dwarf2dbg.h"
+#include "dw2gencfi.h"
+
+#include "opcode/s390.h"
+#include "elf/s390.h"
+
+/* The default architecture. */
+#ifndef DEFAULT_ARCH
+#define DEFAULT_ARCH "s390"
+#endif
+static char *default_arch = DEFAULT_ARCH;
+/* Either 32 or 64, selects file format. */
+static int s390_arch_size = 0;
+
+static unsigned int current_mode_mask = 0;
+static unsigned int current_cpu = -1U;
+
+/* Whether to use user friendly register names. Default is TRUE. */
+#ifndef TARGET_REG_NAMES_P
+#define TARGET_REG_NAMES_P TRUE
+#endif
+
+static bfd_boolean reg_names_p = TARGET_REG_NAMES_P;
+
+/* Set to TRUE if we want to warn about zero base/index registers. */
+static bfd_boolean warn_areg_zero = FALSE;
+
+/* Generic assembler global variables which must be defined by all
+ targets. */
+
+const char comment_chars[] = "#";
+
+/* Characters which start a comment at the beginning of a line. */
+const char line_comment_chars[] = "#";
+
+/* Characters which may be used to separate multiple commands on a
+ single line. */
+const char line_separator_chars[] = ";";
+
+/* Characters which are used to indicate an exponent in a floating
+ point number. */
+const char EXP_CHARS[] = "eE";
+
+/* Characters which mean that a number is a floating point constant,
+ as in 0d1.0. */
+const char FLT_CHARS[] = "dD";
+
+/* The dwarf2 data alignment, adjusted for 32 or 64 bit. */
+int s390_cie_data_alignment;
+
+/* The target specific pseudo-ops which we support. */
+
+/* Define the prototypes for the pseudo-ops */
+static void s390_byte PARAMS ((int));
+static void s390_elf_cons PARAMS ((int));
+static void s390_bss PARAMS ((int));
+static void s390_insn PARAMS ((int));
+static void s390_literals PARAMS ((int));
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ { "align", s_align_bytes, 0 },
+ /* Pseudo-ops which must be defined. */
+ { "bss", s390_bss, 0 },
+ { "insn", s390_insn, 0 },
+ /* Pseudo-ops which must be overridden. */
+ { "byte", s390_byte, 0 },
+ { "short", s390_elf_cons, 2 },
+ { "long", s390_elf_cons, 4 },
+ { "quad", s390_elf_cons, 8 },
+ { "ltorg", s390_literals, 0 },
+ { "string", stringer, 2 },
+ { NULL, NULL, 0 }
+};
+
+
+/* Structure to hold information about predefined registers. */
+struct pd_reg
+ {
+ char *name;
+ int value;
+ };
+
+/* List of registers that are pre-defined:
+
+ Each access register has a predefined name of the form:
+ a<reg_num> which has the value <reg_num>.
+
+ Each control register has a predefined name of the form:
+ c<reg_num> which has the value <reg_num>.
+
+ Each general register has a predefined name of the form:
+ r<reg_num> which has the value <reg_num>.
+
+ Each floating point register a has predefined name of the form:
+ f<reg_num> which has the value <reg_num>.
+
+ There are individual registers as well:
+ sp has the value 15
+ lit has the value 12
+
+ The table is sorted. Suitable for searching by a binary search. */
+
+static const struct pd_reg pre_defined_registers[] =
+{
+ { "a0", 0 }, /* Access registers */
+ { "a1", 1 },
+ { "a10", 10 },
+ { "a11", 11 },
+ { "a12", 12 },
+ { "a13", 13 },
+ { "a14", 14 },
+ { "a15", 15 },
+ { "a2", 2 },
+ { "a3", 3 },
+ { "a4", 4 },
+ { "a5", 5 },
+ { "a6", 6 },
+ { "a7", 7 },
+ { "a8", 8 },
+ { "a9", 9 },
+
+ { "c0", 0 }, /* Control registers */
+ { "c1", 1 },
+ { "c10", 10 },
+ { "c11", 11 },
+ { "c12", 12 },
+ { "c13", 13 },
+ { "c14", 14 },
+ { "c15", 15 },
+ { "c2", 2 },
+ { "c3", 3 },
+ { "c4", 4 },
+ { "c5", 5 },
+ { "c6", 6 },
+ { "c7", 7 },
+ { "c8", 8 },
+ { "c9", 9 },
+
+ { "f0", 0 }, /* Floating point registers */
+ { "f1", 1 },
+ { "f10", 10 },
+ { "f11", 11 },
+ { "f12", 12 },
+ { "f13", 13 },
+ { "f14", 14 },
+ { "f15", 15 },
+ { "f2", 2 },
+ { "f3", 3 },
+ { "f4", 4 },
+ { "f5", 5 },
+ { "f6", 6 },
+ { "f7", 7 },
+ { "f8", 8 },
+ { "f9", 9 },
+
+ { "lit", 13 }, /* Pointer to literal pool */
+
+ { "r0", 0 }, /* General purpose registers */
+ { "r1", 1 },
+ { "r10", 10 },
+ { "r11", 11 },
+ { "r12", 12 },
+ { "r13", 13 },
+ { "r14", 14 },
+ { "r15", 15 },
+ { "r2", 2 },
+ { "r3", 3 },
+ { "r4", 4 },
+ { "r5", 5 },
+ { "r6", 6 },
+ { "r7", 7 },
+ { "r8", 8 },
+ { "r9", 9 },
+
+ { "sp", 15 }, /* Stack pointer */
+
+};
+
+#define REG_NAME_CNT (sizeof (pre_defined_registers) / sizeof (struct pd_reg))
+
+static int reg_name_search
+ PARAMS ((const struct pd_reg *, int, const char *));
+static bfd_boolean register_name PARAMS ((expressionS *));
+static void init_default_arch PARAMS ((void));
+static void s390_insert_operand
+ PARAMS ((unsigned char *, const struct s390_operand *, offsetT, char *,
+ unsigned int));
+static char *md_gather_operands
+ PARAMS ((char *, unsigned char *, const struct s390_opcode *));
+
+/* Given NAME, find the register number associated with that name, return
+ the integer value associated with the given name or -1 on failure. */
+
+static int
+reg_name_search (regs, regcount, name)
+ const struct pd_reg *regs;
+ int regcount;
+ const char *name;
+{
+ int middle, low, high;
+ int cmp;
+
+ low = 0;
+ high = regcount - 1;
+
+ do
+ {
+ middle = (low + high) / 2;
+ cmp = strcasecmp (name, regs[middle].name);
+ if (cmp < 0)
+ high = middle - 1;
+ else if (cmp > 0)
+ low = middle + 1;
+ else
+ return regs[middle].value;
+ }
+ while (low <= high);
+
+ return -1;
+}
+
+
+/*
+ * Summary of register_name().
+ *
+ * in: Input_line_pointer points to 1st char of operand.
+ *
+ * out: A expressionS.
+ * The operand may have been a register: in this case, X_op == O_register,
+ * X_add_number is set to the register number, and truth is returned.
+ * Input_line_pointer->(next non-blank) char after operand, or is in its
+ * original state.
+ */
+
+static bfd_boolean
+register_name (expressionP)
+ expressionS *expressionP;
+{
+ int reg_number;
+ char *name;
+ char *start;
+ char c;
+
+ /* Find the spelling of the operand. */
+ start = name = input_line_pointer;
+ if (name[0] == '%' && ISALPHA (name[1]))
+ name = ++input_line_pointer;
+ else
+ return FALSE;
+
+ c = get_symbol_end ();
+ reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT, name);
+
+ /* Put back the delimiting char. */
+ *input_line_pointer = c;
+
+ /* Look to see if it's in the register table. */
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = reg_number;
+
+ /* Make the rest nice. */
+ expressionP->X_add_symbol = NULL;
+ expressionP->X_op_symbol = NULL;
+ return TRUE;
+ }
+
+ /* Reset the line as if we had not done anything. */
+ input_line_pointer = start;
+ return FALSE;
+}
+
+/* Local variables. */
+
+/* Opformat hash table. */
+static struct hash_control *s390_opformat_hash;
+
+/* Opcode hash table. */
+static struct hash_control *s390_opcode_hash;
+
+/* Flags to set in the elf header */
+static flagword s390_flags = 0;
+
+symbolS *GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
+
+#ifndef WORKING_DOT_WORD
+const int md_short_jump_size = 4;
+const int md_long_jump_size = 4;
+#endif
+
+const char *md_shortopts = "A:m:kVQ:";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof (md_longopts);
+
+/* Initialize the default opcode arch and word size from the default
+ architecture name if not specified by an option. */
+static void
+init_default_arch ()
+{
+ if (strcmp (default_arch, "s390") == 0)
+ {
+ if (s390_arch_size == 0)
+ s390_arch_size = 32;
+ }
+ else if (strcmp (default_arch, "s390x") == 0)
+ {
+ if (s390_arch_size == 0)
+ s390_arch_size = 64;
+ }
+ else
+ as_fatal ("Invalid default architecture, broken assembler.");
+
+ if (current_mode_mask == 0)
+ {
+ if (s390_arch_size == 32)
+ current_mode_mask = 1 << S390_OPCODE_ESA;
+ else
+ current_mode_mask = 1 << S390_OPCODE_ZARCH;
+ }
+ if (current_cpu == -1U)
+ {
+ if (current_mode_mask == (1 << S390_OPCODE_ESA))
+ current_cpu = S390_OPCODE_G5;
+ else
+ current_cpu = S390_OPCODE_Z900;
+ }
+}
+
+/* Called by TARGET_FORMAT. */
+const char *
+s390_target_format ()
+{
+ /* We don't get a chance to initialize anything before we're called,
+ so handle that now. */
+ init_default_arch ();
+
+ return s390_arch_size == 64 ? "elf64-s390" : "elf32-s390";
+}
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ /* -k: Ignore for FreeBSD compatibility. */
+ case 'k':
+ break;
+ case 'm':
+ if (arg != NULL && strcmp (arg, "regnames") == 0)
+ reg_names_p = TRUE;
+
+ else if (arg != NULL && strcmp (arg, "no-regnames") == 0)
+ reg_names_p = FALSE;
+
+ else if (arg != NULL && strcmp (arg, "warn-areg-zero") == 0)
+ warn_areg_zero = TRUE;
+
+ else if (arg != NULL && strcmp (arg, "31") == 0)
+ s390_arch_size = 32;
+
+ else if (arg != NULL && strcmp (arg, "64") == 0)
+ s390_arch_size = 64;
+
+ else if (arg != NULL && strcmp (arg, "esa") == 0)
+ current_mode_mask = 1 << S390_OPCODE_ESA;
+
+ else if (arg != NULL && strcmp (arg, "zarch") == 0)
+ current_mode_mask = 1 << S390_OPCODE_ZARCH;
+
+ else if (arg != NULL && strncmp (arg, "arch=", 5) == 0)
+ {
+ if (strcmp (arg + 5, "g5") == 0)
+ current_cpu = S390_OPCODE_G5;
+ else if (strcmp (arg + 5, "g6") == 0)
+ current_cpu = S390_OPCODE_G6;
+ else if (strcmp (arg + 5, "z900") == 0)
+ current_cpu = S390_OPCODE_Z900;
+ else if (strcmp (arg + 5, "z990") == 0)
+ current_cpu = S390_OPCODE_Z990;
+ else
+ {
+ as_bad (_("invalid switch -m%s"), arg);
+ return 0;
+ }
+ }
+
+ else
+ {
+ as_bad (_("invalid switch -m%s"), arg);
+ return 0;
+ }
+ break;
+
+ case 'A':
+ /* Option -A is deprecated. Still available for compatibility. */
+ if (arg != NULL && strcmp (arg, "esa") == 0)
+ current_cpu = S390_OPCODE_G5;
+ else if (arg != NULL && strcmp (arg, "esame") == 0)
+ current_cpu = S390_OPCODE_Z900;
+ else
+ as_bad ("invalid architecture -A%s", arg);
+ break;
+
+ /* -V: SVR4 argument to print version ID. */
+ case 'V':
+ print_version_id ();
+ break;
+
+ /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
+ should be emitted or not. FIXME: Not implemented. */
+ case 'Q':
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf (stream, _("\
+ S390 options:\n\
+ -mregnames Allow symbolic names for registers\n\
+ -mwarn-areg-zero Warn about zero base/index registers\n\
+ -mno-regnames Do not allow symbolic names for registers\n\
+ -m31 Set file format to 31 bit format\n\
+ -m64 Set file format to 64 bit format\n"));
+ fprintf (stream, _("\
+ -V print assembler version number\n\
+ -Qy, -Qn ignored\n"));
+}
+
+/* This function is called when the assembler starts up. It is called
+ after the options have been parsed and the output file has been
+ opened. */
+
+void
+md_begin ()
+{
+ register const struct s390_opcode *op;
+ const struct s390_opcode *op_end;
+ bfd_boolean dup_insn = FALSE;
+ const char *retval;
+
+ /* Give a warning if the combination -m64-bit and -Aesa is used. */
+ if (s390_arch_size == 64 && current_cpu < S390_OPCODE_Z900)
+ as_warn ("The 64 bit file format is used without esame instructions.");
+
+ s390_cie_data_alignment = -s390_arch_size / 8;
+
+ /* Set the ELF flags if desired. */
+ if (s390_flags)
+ bfd_set_private_flags (stdoutput, s390_flags);
+
+ /* Insert the opcode formats into a hash table. */
+ s390_opformat_hash = hash_new ();
+
+ op_end = s390_opformats + s390_num_opformats;
+ for (op = s390_opformats; op < op_end; op++)
+ {
+ retval = hash_insert (s390_opformat_hash, op->name, (PTR) op);
+ if (retval != (const char *) NULL)
+ {
+ as_bad (_("Internal assembler error for instruction format %s"),
+ op->name);
+ dup_insn = TRUE;
+ }
+ }
+
+ /* Insert the opcodes into a hash table. */
+ s390_opcode_hash = hash_new ();
+
+ op_end = s390_opcodes + s390_num_opcodes;
+ for (op = s390_opcodes; op < op_end; op++)
+ if (op->min_cpu <= current_cpu)
+ {
+ retval = hash_insert (s390_opcode_hash, op->name, (PTR) op);
+ if (retval != (const char *) NULL)
+ {
+ as_bad (_("Internal assembler error for instruction %s"),
+ op->name);
+ dup_insn = TRUE;
+ }
+ while (op < op_end - 1 && strcmp (op->name, op[1].name) == 0)
+ op++;
+ }
+
+ if (dup_insn)
+ abort ();
+
+ record_alignment (text_section, 2);
+ record_alignment (data_section, 2);
+ record_alignment (bss_section, 2);
+
+}
+
+/* Called after all assembly has been done. */
+void
+s390_md_end ()
+{
+ if (s390_arch_size == 64)
+ bfd_set_arch_mach (stdoutput, bfd_arch_s390, bfd_mach_s390_64);
+ else
+ bfd_set_arch_mach (stdoutput, bfd_arch_s390, bfd_mach_s390_31);
+}
+
+/* Insert an operand value into an instruction. */
+
+static void
+s390_insert_operand (insn, operand, val, file, line)
+ unsigned char *insn;
+ const struct s390_operand *operand;
+ offsetT val;
+ char *file;
+ unsigned int line;
+{
+ addressT uval;
+ int offset;
+
+ if (operand->flags & (S390_OPERAND_SIGNED|S390_OPERAND_PCREL))
+ {
+ offsetT min, max;
+
+ max = ((offsetT) 1 << (operand->bits - 1)) - 1;
+ min = - ((offsetT) 1 << (operand->bits - 1));
+ /* Halve PCREL operands. */
+ if (operand->flags & S390_OPERAND_PCREL)
+ val >>= 1;
+ /* Check for underflow / overflow. */
+ if (val < min || val > max)
+ {
+ const char *err =
+ "operand out of range (%s not between %ld and %ld)";
+ char buf[100];
+
+ if (operand->flags & S390_OPERAND_PCREL)
+ {
+ val <<= 1;
+ min <<= 1;
+ max <<= 1;
+ }
+ sprint_value (buf, val);
+ if (file == (char *) NULL)
+ as_bad (err, buf, (int) min, (int) max);
+ else
+ as_bad_where (file, line, err, buf, (int) min, (int) max);
+ return;
+ }
+ /* val is ok, now restrict it to operand->bits bits. */
+ uval = (addressT) val & ((((addressT) 1 << (operand->bits-1)) << 1) - 1);
+ /* val is restrict, now check for special case. */
+ if (operand->bits == 20 && operand->shift == 20)
+ uval = (uval >> 12) | ((uval & 0xfff) << 8);
+ }
+ else
+ {
+ addressT min, max;
+
+ max = (((addressT) 1 << (operand->bits - 1)) << 1) - 1;
+ min = (offsetT) 0;
+ uval = (addressT) val;
+ /* Length x in an instructions has real length x+1. */
+ if (operand->flags & S390_OPERAND_LENGTH)
+ uval--;
+ /* Check for underflow / overflow. */
+ if (uval < min || uval > max)
+ {
+ const char *err =
+ "operand out of range (%s not between %ld and %ld)";
+ char buf[100];
+
+ if (operand->flags & S390_OPERAND_LENGTH)
+ {
+ uval++;
+ min++;
+ max++;
+ }
+ sprint_value (buf, uval);
+ if (file == (char *) NULL)
+ as_bad (err, buf, (int) min, (int) max);
+ else
+ as_bad_where (file, line, err, buf, (int) min, (int) max);
+ return;
+ }
+ }
+
+ /* Insert fragments of the operand byte for byte. */
+ offset = operand->shift + operand->bits;
+ uval <<= (-offset) & 7;
+ insn += (offset - 1) / 8;
+ while (uval != 0)
+ {
+ *insn-- |= uval;
+ uval >>= 8;
+ }
+}
+
+struct map_tls
+ {
+ char *string;
+ int length;
+ bfd_reloc_code_real_type reloc;
+ };
+
+static bfd_reloc_code_real_type s390_tls_suffix
+ PARAMS ((char **, expressionS *));
+
+/* Parse tls marker and return the desired relocation. */
+static bfd_reloc_code_real_type
+s390_tls_suffix (str_p, exp_p)
+ char **str_p;
+ expressionS *exp_p;
+{
+ static struct map_tls mapping[] =
+ {
+ { "tls_load", 8, BFD_RELOC_390_TLS_LOAD },
+ { "tls_gdcall", 10, BFD_RELOC_390_TLS_GDCALL },
+ { "tls_ldcall", 10, BFD_RELOC_390_TLS_LDCALL },
+ { NULL, 0, BFD_RELOC_UNUSED }
+ };
+ struct map_tls *ptr;
+ char *orig_line;
+ char *str;
+ char *ident;
+ int len;
+
+ str = *str_p;
+ if (*str++ != ':')
+ return BFD_RELOC_UNUSED;
+
+ ident = str;
+ while (ISIDNUM (*str))
+ str++;
+ len = str - ident;
+ if (*str++ != ':')
+ return BFD_RELOC_UNUSED;
+
+ orig_line = input_line_pointer;
+ input_line_pointer = str;
+ expression (exp_p);
+ str = input_line_pointer;
+ if (&input_line_pointer != str_p)
+ input_line_pointer = orig_line;
+
+ if (exp_p->X_op != O_symbol)
+ return BFD_RELOC_UNUSED;
+
+ for (ptr = &mapping[0]; ptr->length > 0; ptr++)
+ if (len == ptr->length
+ && strncasecmp (ident, ptr->string, ptr->length) == 0)
+ {
+ /* Found a matching tls suffix. */
+ *str_p = str;
+ return ptr->reloc;
+ }
+ return BFD_RELOC_UNUSED;
+}
+
+/* Structure used to hold suffixes. */
+typedef enum
+ {
+ ELF_SUFFIX_NONE = 0,
+ ELF_SUFFIX_GOT,
+ ELF_SUFFIX_PLT,
+ ELF_SUFFIX_GOTENT,
+ ELF_SUFFIX_GOTOFF,
+ ELF_SUFFIX_GOTPLT,
+ ELF_SUFFIX_PLTOFF,
+ ELF_SUFFIX_TLS_GD,
+ ELF_SUFFIX_TLS_GOTIE,
+ ELF_SUFFIX_TLS_IE,
+ ELF_SUFFIX_TLS_LDM,
+ ELF_SUFFIX_TLS_LDO,
+ ELF_SUFFIX_TLS_LE
+ }
+elf_suffix_type;
+
+struct map_bfd
+ {
+ char *string;
+ int length;
+ elf_suffix_type suffix;
+ };
+
+static elf_suffix_type s390_elf_suffix PARAMS ((char **, expressionS *));
+static int s390_exp_compare PARAMS ((expressionS *exp1, expressionS *exp2));
+static elf_suffix_type s390_lit_suffix
+ PARAMS ((char **, expressionS *, elf_suffix_type));
+
+
+/* Parse @got/@plt/@gotoff. and return the desired relocation. */
+static elf_suffix_type
+s390_elf_suffix (str_p, exp_p)
+ char **str_p;
+ expressionS *exp_p;
+{
+ static struct map_bfd mapping[] =
+ {
+ { "got", 3, ELF_SUFFIX_GOT },
+ { "got12", 5, ELF_SUFFIX_GOT },
+ { "plt", 3, ELF_SUFFIX_PLT },
+ { "gotent", 6, ELF_SUFFIX_GOTENT },
+ { "gotoff", 6, ELF_SUFFIX_GOTOFF },
+ { "gotplt", 6, ELF_SUFFIX_GOTPLT },
+ { "pltoff", 6, ELF_SUFFIX_PLTOFF },
+ { "tlsgd", 5, ELF_SUFFIX_TLS_GD },
+ { "gotntpoff", 9, ELF_SUFFIX_TLS_GOTIE },
+ { "indntpoff", 9, ELF_SUFFIX_TLS_IE },
+ { "tlsldm", 6, ELF_SUFFIX_TLS_LDM },
+ { "dtpoff", 6, ELF_SUFFIX_TLS_LDO },
+ { "ntpoff", 6, ELF_SUFFIX_TLS_LE },
+ { NULL, 0, ELF_SUFFIX_NONE }
+ };
+
+ struct map_bfd *ptr;
+ char *str = *str_p;
+ char *ident;
+ int len;
+
+ if (*str++ != '@')
+ return ELF_SUFFIX_NONE;
+
+ ident = str;
+ while (ISALNUM (*str))
+ str++;
+ len = str - ident;
+
+ for (ptr = &mapping[0]; ptr->length > 0; ptr++)
+ if (len == ptr->length
+ && strncasecmp (ident, ptr->string, ptr->length) == 0)
+ {
+ if (exp_p->X_add_number != 0)
+ as_warn (_("identifier+constant@%s means identifier@%s+constant"),
+ ptr->string, ptr->string);
+ /* Now check for identifier@suffix+constant. */
+ if (*str == '-' || *str == '+')
+ {
+ char *orig_line = input_line_pointer;
+ expressionS new_exp;
+
+ input_line_pointer = str;
+ expression (&new_exp);
+
+ switch (new_exp.X_op)
+ {
+ case O_constant: /* X_add_number (a constant expression). */
+ exp_p->X_add_number += new_exp.X_add_number;
+ str = input_line_pointer;
+ break;
+ case O_symbol: /* X_add_symbol + X_add_number. */
+ /* this case is used for e.g. xyz@PLT+.Label. */
+ exp_p->X_add_number += new_exp.X_add_number;
+ exp_p->X_op_symbol = new_exp.X_add_symbol;
+ exp_p->X_op = O_add;
+ str = input_line_pointer;
+ break;
+ case O_uminus: /* (- X_add_symbol) + X_add_number. */
+ /* this case is used for e.g. xyz@PLT-.Label. */
+ exp_p->X_add_number += new_exp.X_add_number;
+ exp_p->X_op_symbol = new_exp.X_add_symbol;
+ exp_p->X_op = O_subtract;
+ str = input_line_pointer;
+ break;
+ default:
+ break;
+ }
+
+ /* If s390_elf_suffix has not been called with
+ &input_line_pointer as first parameter, we have
+ clobbered the input_line_pointer. We have to
+ undo that. */
+ if (&input_line_pointer != str_p)
+ input_line_pointer = orig_line;
+ }
+ *str_p = str;
+ return ptr->suffix;
+ }
+
+ return BFD_RELOC_UNUSED;
+}
+
+/* Structure used to hold a literal pool entry. */
+struct s390_lpe
+ {
+ struct s390_lpe *next;
+ expressionS ex;
+ FLONUM_TYPE floatnum; /* used if X_op == O_big && X_add_number <= 0 */
+ LITTLENUM_TYPE bignum[4]; /* used if X_op == O_big && X_add_number > 0 */
+ int nbytes;
+ bfd_reloc_code_real_type reloc;
+ symbolS *sym;
+ };
+
+static struct s390_lpe *lpe_free_list = NULL;
+static struct s390_lpe *lpe_list = NULL;
+static struct s390_lpe *lpe_list_tail = NULL;
+static symbolS *lp_sym = NULL;
+static int lp_count = 0;
+static int lpe_count = 0;
+
+static int
+s390_exp_compare (exp1, exp2)
+ expressionS *exp1;
+ expressionS *exp2;
+{
+ if (exp1->X_op != exp2->X_op)
+ return 0;
+
+ switch (exp1->X_op)
+ {
+ case O_constant: /* X_add_number must be equal. */
+ case O_register:
+ return exp1->X_add_number == exp2->X_add_number;
+
+ case O_big:
+ as_bad (_("Can't handle O_big in s390_exp_compare"));
+
+ case O_symbol: /* X_add_symbol & X_add_number must be equal. */
+ case O_symbol_rva:
+ case O_uminus:
+ case O_bit_not:
+ case O_logical_not:
+ return (exp1->X_add_symbol == exp2->X_add_symbol)
+ && (exp1->X_add_number == exp2->X_add_number);
+
+ case O_multiply: /* X_add_symbol,X_op_symbol&X_add_number must be equal. */
+ case O_divide:
+ case O_modulus:
+ case O_left_shift:
+ case O_right_shift:
+ case O_bit_inclusive_or:
+ case O_bit_or_not:
+ case O_bit_exclusive_or:
+ case O_bit_and:
+ case O_add:
+ case O_subtract:
+ case O_eq:
+ case O_ne:
+ case O_lt:
+ case O_le:
+ case O_ge:
+ case O_gt:
+ case O_logical_and:
+ case O_logical_or:
+ return (exp1->X_add_symbol == exp2->X_add_symbol)
+ && (exp1->X_op_symbol == exp2->X_op_symbol)
+ && (exp1->X_add_number == exp2->X_add_number);
+ default:
+ return 0;
+ }
+}
+
+/* Test for @lit and if its present make an entry in the literal pool and
+ modify the current expression to be an offset into the literal pool. */
+static elf_suffix_type
+s390_lit_suffix (str_p, exp_p, suffix)
+ char **str_p;
+ expressionS *exp_p;
+ elf_suffix_type suffix;
+{
+ bfd_reloc_code_real_type reloc;
+ char tmp_name[64];
+ char *str = *str_p;
+ char *ident;
+ struct s390_lpe *lpe;
+ int nbytes, len;
+
+ if (*str++ != ':')
+ return suffix; /* No modification. */
+
+ /* We look for a suffix of the form "@lit1", "@lit2", "@lit4" or "@lit8". */
+ ident = str;
+ while (ISALNUM (*str))
+ str++;
+ len = str - ident;
+ if (len != 4 || strncasecmp (ident, "lit", 3) != 0
+ || (ident[3]!='1' && ident[3]!='2' && ident[3]!='4' && ident[3]!='8'))
+ return suffix; /* no modification */
+ nbytes = ident[3] - '0';
+
+ reloc = BFD_RELOC_UNUSED;
+ if (suffix == ELF_SUFFIX_GOT)
+ {
+ if (nbytes == 2)
+ reloc = BFD_RELOC_390_GOT16;
+ else if (nbytes == 4)
+ reloc = BFD_RELOC_32_GOT_PCREL;
+ else if (nbytes == 8)
+ reloc = BFD_RELOC_390_GOT64;
+ }
+ else if (suffix == ELF_SUFFIX_PLT)
+ {
+ if (nbytes == 4)
+ reloc = BFD_RELOC_390_PLT32;
+ else if (nbytes == 8)
+ reloc = BFD_RELOC_390_PLT64;
+ }
+
+ if (suffix != ELF_SUFFIX_NONE && reloc == BFD_RELOC_UNUSED)
+ as_bad (_("Invalid suffix for literal pool entry"));
+
+ /* Search the pool if the new entry is a duplicate. */
+ if (exp_p->X_op == O_big)
+ {
+ /* Special processing for big numbers. */
+ for (lpe = lpe_list; lpe != NULL; lpe = lpe->next)
+ {
+ if (lpe->ex.X_op == O_big)
+ {
+ if (exp_p->X_add_number <= 0 && lpe->ex.X_add_number <= 0)
+ {
+ if (memcmp (&generic_floating_point_number, &lpe->floatnum,
+ sizeof (FLONUM_TYPE)) == 0)
+ break;
+ }
+ else if (exp_p->X_add_number == lpe->ex.X_add_number)
+ {
+ if (memcmp (generic_bignum, lpe->bignum,
+ sizeof (LITTLENUM_TYPE)*exp_p->X_add_number) == 0)
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Processing for 'normal' data types. */
+ for (lpe = lpe_list; lpe != NULL; lpe = lpe->next)
+ if (lpe->nbytes == nbytes && lpe->reloc == reloc
+ && s390_exp_compare (exp_p, &lpe->ex) != 0)
+ break;
+ }
+
+ if (lpe == NULL)
+ {
+ /* A new literal. */
+ if (lpe_free_list != NULL)
+ {
+ lpe = lpe_free_list;
+ lpe_free_list = lpe_free_list->next;
+ }
+ else
+ {
+ lpe = (struct s390_lpe *) xmalloc (sizeof (struct s390_lpe));
+ }
+
+ lpe->ex = *exp_p;
+
+ if (exp_p->X_op == O_big)
+ {
+ if (exp_p->X_add_number <= 0)
+ lpe->floatnum = generic_floating_point_number;
+ else if (exp_p->X_add_number <= 4)
+ memcpy (lpe->bignum, generic_bignum,
+ exp_p->X_add_number * sizeof (LITTLENUM_TYPE));
+ else
+ as_bad (_("Big number is too big"));
+ }
+
+ lpe->nbytes = nbytes;
+ lpe->reloc = reloc;
+ /* Literal pool name defined ? */
+ if (lp_sym == NULL)
+ {
+ sprintf (tmp_name, ".L\001%i", lp_count);
+ lp_sym = symbol_make (tmp_name);
+ }
+
+ /* Make name for literal pool entry. */
+ sprintf (tmp_name, ".L\001%i\002%i", lp_count, lpe_count);
+ lpe_count++;
+ lpe->sym = symbol_make (tmp_name);
+
+ /* Add to literal pool list. */
+ lpe->next = NULL;
+ if (lpe_list_tail != NULL)
+ {
+ lpe_list_tail->next = lpe;
+ lpe_list_tail = lpe;
+ }
+ else
+ lpe_list = lpe_list_tail = lpe;
+ }
+
+ /* Now change exp_p to the offset into the literal pool.
+ Thats the expression: .L^Ax^By-.L^Ax */
+ exp_p->X_add_symbol = lpe->sym;
+ exp_p->X_op_symbol = lp_sym;
+ exp_p->X_op = O_subtract;
+ exp_p->X_add_number = 0;
+
+ *str_p = str;
+
+ /* We change the suffix type to ELF_SUFFIX_NONE, because
+ the difference of two local labels is just a number. */
+ return ELF_SUFFIX_NONE;
+}
+
+/* Like normal .long/.short/.word, except support @got, etc.
+ clobbers input_line_pointer, checks end-of-line. */
+static void
+s390_elf_cons (nbytes)
+ register int nbytes; /* 1=.byte, 2=.word, 4=.long */
+{
+ expressionS exp;
+ elf_suffix_type suffix;
+
+ if (is_it_end_of_statement ())
+ {
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ do
+ {
+ expression (&exp);
+
+ if (exp.X_op == O_symbol
+ && *input_line_pointer == '@'
+ && (suffix = s390_elf_suffix (&input_line_pointer, &exp)) != ELF_SUFFIX_NONE)
+ {
+ bfd_reloc_code_real_type reloc;
+ reloc_howto_type *reloc_howto;
+ int size;
+ char *where;
+
+ if (nbytes == 2)
+ {
+ static bfd_reloc_code_real_type tab2[] =
+ {
+ BFD_RELOC_UNUSED, /* ELF_SUFFIX_NONE */
+ BFD_RELOC_390_GOT16, /* ELF_SUFFIX_GOT */
+ BFD_RELOC_UNUSED, /* ELF_SUFFIX_PLT */
+ BFD_RELOC_UNUSED, /* ELF_SUFFIX_GOTENT */
+ BFD_RELOC_16_GOTOFF, /* ELF_SUFFIX_GOTOFF */
+ BFD_RELOC_UNUSED, /* ELF_SUFFIX_GOTPLT */
+ BFD_RELOC_390_PLTOFF16, /* ELF_SUFFIX_PLTOFF */
+ BFD_RELOC_UNUSED, /* ELF_SUFFIX_TLS_GD */
+ BFD_RELOC_UNUSED, /* ELF_SUFFIX_TLS_GOTIE */
+ BFD_RELOC_UNUSED, /* ELF_SUFFIX_TLS_IE */
+ BFD_RELOC_UNUSED, /* ELF_SUFFIX_TLS_LDM */
+ BFD_RELOC_UNUSED, /* ELF_SUFFIX_TLS_LDO */
+ BFD_RELOC_UNUSED /* ELF_SUFFIX_TLS_LE */
+ };
+ reloc = tab2[suffix];
+ }
+ else if (nbytes == 4)
+ {
+ static bfd_reloc_code_real_type tab4[] =
+ {
+ BFD_RELOC_UNUSED, /* ELF_SUFFIX_NONE */
+ BFD_RELOC_32_GOT_PCREL, /* ELF_SUFFIX_GOT */
+ BFD_RELOC_390_PLT32, /* ELF_SUFFIX_PLT */
+ BFD_RELOC_UNUSED, /* ELF_SUFFIX_GOTENT */
+ BFD_RELOC_32_GOTOFF, /* ELF_SUFFIX_GOTOFF */
+ BFD_RELOC_390_GOTPLT32, /* ELF_SUFFIX_GOTPLT */
+ BFD_RELOC_390_PLTOFF32, /* ELF_SUFFIX_PLTOFF */
+ BFD_RELOC_390_TLS_GD32, /* ELF_SUFFIX_TLS_GD */
+ BFD_RELOC_390_TLS_GOTIE32, /* ELF_SUFFIX_TLS_GOTIE */
+ BFD_RELOC_390_TLS_IE32, /* ELF_SUFFIX_TLS_IE */
+ BFD_RELOC_390_TLS_LDM32, /* ELF_SUFFIX_TLS_LDM */
+ BFD_RELOC_390_TLS_LDO32, /* ELF_SUFFIX_TLS_LDO */
+ BFD_RELOC_390_TLS_LE32 /* ELF_SUFFIX_TLS_LE */
+ };
+ reloc = tab4[suffix];
+ }
+ else if (nbytes == 8)
+ {
+ static bfd_reloc_code_real_type tab8[] =
+ {
+ BFD_RELOC_UNUSED, /* ELF_SUFFIX_NONE */
+ BFD_RELOC_390_GOT64, /* ELF_SUFFIX_GOT */
+ BFD_RELOC_390_PLT64, /* ELF_SUFFIX_PLT */
+ BFD_RELOC_UNUSED, /* ELF_SUFFIX_GOTENT */
+ BFD_RELOC_390_GOTOFF64, /* ELF_SUFFIX_GOTOFF */
+ BFD_RELOC_390_GOTPLT64, /* ELF_SUFFIX_GOTPLT */
+ BFD_RELOC_390_PLTOFF64, /* ELF_SUFFIX_PLTOFF */
+ BFD_RELOC_390_TLS_GD64, /* ELF_SUFFIX_TLS_GD */
+ BFD_RELOC_390_TLS_GOTIE64, /* ELF_SUFFIX_TLS_GOTIE */
+ BFD_RELOC_390_TLS_IE64, /* ELF_SUFFIX_TLS_IE */
+ BFD_RELOC_390_TLS_LDM64, /* ELF_SUFFIX_TLS_LDM */
+ BFD_RELOC_390_TLS_LDO64, /* ELF_SUFFIX_TLS_LDO */
+ BFD_RELOC_390_TLS_LE64 /* ELF_SUFFIX_TLS_LE */
+ };
+ reloc = tab8[suffix];
+ }
+ else
+ reloc = BFD_RELOC_UNUSED;
+
+ if (reloc != BFD_RELOC_UNUSED
+ && (reloc_howto = bfd_reloc_type_lookup (stdoutput, reloc)))
+ {
+ size = bfd_get_reloc_size (reloc_howto);
+ if (size > nbytes)
+ as_bad (_("%s relocations do not fit in %d bytes"),
+ reloc_howto->name, nbytes);
+ where = frag_more (nbytes);
+ md_number_to_chars (where, 0, size);
+ /* To make fixup_segment do the pc relative conversion the
+ pcrel parameter on the fix_new_exp call needs to be FALSE. */
+ fix_new_exp (frag_now, where - frag_now->fr_literal,
+ size, &exp, FALSE, reloc);
+ }
+ else
+ as_bad (_("relocation not applicable"));
+ }
+ else
+ emit_expr (&exp, (unsigned int) nbytes);
+ }
+ while (*input_line_pointer++ == ',');
+
+ input_line_pointer--; /* Put terminator back into stream. */
+ demand_empty_rest_of_line ();
+}
+
+/* We need to keep a list of fixups. We can't simply generate them as
+ we go, because that would require us to first create the frag, and
+ that would screw up references to ``.''. */
+
+struct s390_fixup
+ {
+ expressionS exp;
+ int opindex;
+ bfd_reloc_code_real_type reloc;
+ };
+
+#define MAX_INSN_FIXUPS (4)
+
+/* This routine is called for each instruction to be assembled. */
+
+static char *
+md_gather_operands (str, insn, opcode)
+ char *str;
+ unsigned char *insn;
+ const struct s390_opcode *opcode;
+{
+ struct s390_fixup fixups[MAX_INSN_FIXUPS];
+ const struct s390_operand *operand;
+ const unsigned char *opindex_ptr;
+ expressionS ex;
+ elf_suffix_type suffix;
+ bfd_reloc_code_real_type reloc;
+ int skip_optional;
+ int parentheses;
+ char *f;
+ int fc, i;
+
+ while (ISSPACE (*str))
+ str++;
+
+ parentheses = 0;
+ skip_optional = 0;
+
+ /* Gather the operands. */
+ fc = 0;
+ for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
+ {
+ char *hold;
+
+ operand = s390_operands + *opindex_ptr;
+
+ if (skip_optional && (operand->flags & S390_OPERAND_INDEX))
+ {
+ /* We do an early skip. For D(X,B) constructions the index
+ register is skipped (X is optional). For D(L,B) the base
+ register will be the skipped operand, because L is NOT
+ optional. */
+ skip_optional = 0;
+ continue;
+ }
+
+ /* Gather the operand. */
+ hold = input_line_pointer;
+ input_line_pointer = str;
+
+ /* Parse the operand. */
+ if (! register_name (&ex))
+ expression (&ex);
+
+ str = input_line_pointer;
+ input_line_pointer = hold;
+
+ /* Write the operand to the insn. */
+ if (ex.X_op == O_illegal)
+ as_bad (_("illegal operand"));
+ else if (ex.X_op == O_absent)
+ as_bad (_("missing operand"));
+ else if (ex.X_op == O_register || ex.X_op == O_constant)
+ {
+ s390_lit_suffix (&str, &ex, ELF_SUFFIX_NONE);
+
+ if (ex.X_op != O_register && ex.X_op != O_constant)
+ {
+ /* We need to generate a fixup for the
+ expression returned by s390_lit_suffix. */
+ if (fc >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = *opindex_ptr;
+ fixups[fc].reloc = BFD_RELOC_UNUSED;
+ ++fc;
+ }
+ else
+ {
+ if ((operand->flags & S390_OPERAND_INDEX)
+ && ex.X_add_number == 0
+ && warn_areg_zero)
+ as_warn ("index register specified but zero");
+ if ((operand->flags & S390_OPERAND_BASE)
+ && ex.X_add_number == 0
+ && warn_areg_zero)
+ as_warn ("base register specified but zero");
+ s390_insert_operand (insn, operand, ex.X_add_number, NULL, 0);
+ }
+ }
+ else
+ {
+ suffix = s390_elf_suffix (&str, &ex);
+ suffix = s390_lit_suffix (&str, &ex, suffix);
+ reloc = BFD_RELOC_UNUSED;
+
+ if (suffix == ELF_SUFFIX_GOT)
+ {
+ if ((operand->flags & S390_OPERAND_DISP) &&
+ (operand->bits == 12))
+ reloc = BFD_RELOC_390_GOT12;
+ else if ((operand->flags & S390_OPERAND_DISP) &&
+ (operand->bits == 20))
+ reloc = BFD_RELOC_390_GOT20;
+ else if ((operand->flags & S390_OPERAND_SIGNED)
+ && (operand->bits == 16))
+ reloc = BFD_RELOC_390_GOT16;
+ else if ((operand->flags & S390_OPERAND_PCREL)
+ && (operand->bits == 32))
+ reloc = BFD_RELOC_390_GOTENT;
+ }
+ else if (suffix == ELF_SUFFIX_PLT)
+ {
+ if ((operand->flags & S390_OPERAND_PCREL)
+ && (operand->bits == 16))
+ reloc = BFD_RELOC_390_PLT16DBL;
+ else if ((operand->flags & S390_OPERAND_PCREL)
+ && (operand->bits == 32))
+ reloc = BFD_RELOC_390_PLT32DBL;
+ }
+ else if (suffix == ELF_SUFFIX_GOTENT)
+ {
+ if ((operand->flags & S390_OPERAND_PCREL)
+ && (operand->bits == 32))
+ reloc = BFD_RELOC_390_GOTENT;
+ }
+ else if (suffix == ELF_SUFFIX_GOTOFF)
+ {
+ if ((operand->flags & S390_OPERAND_SIGNED)
+ && (operand->bits == 16))
+ reloc = BFD_RELOC_16_GOTOFF;
+ }
+ else if (suffix == ELF_SUFFIX_PLTOFF)
+ {
+ if ((operand->flags & S390_OPERAND_SIGNED)
+ && (operand->bits == 16))
+ reloc = BFD_RELOC_390_PLTOFF16;
+ }
+ else if (suffix == ELF_SUFFIX_GOTPLT)
+ {
+ if ((operand->flags & S390_OPERAND_DISP)
+ && (operand->bits == 12))
+ reloc = BFD_RELOC_390_GOTPLT12;
+ else if ((operand->flags & S390_OPERAND_SIGNED)
+ && (operand->bits == 16))
+ reloc = BFD_RELOC_390_GOTPLT16;
+ else if ((operand->flags & S390_OPERAND_PCREL)
+ && (operand->bits == 32))
+ reloc = BFD_RELOC_390_GOTPLTENT;
+ }
+ else if (suffix == ELF_SUFFIX_TLS_GOTIE)
+ {
+ if ((operand->flags & S390_OPERAND_DISP)
+ && (operand->bits == 12))
+ reloc = BFD_RELOC_390_TLS_GOTIE12;
+ else if ((operand->flags & S390_OPERAND_DISP)
+ && (operand->bits == 20))
+ reloc = BFD_RELOC_390_TLS_GOTIE20;
+ }
+ else if (suffix == ELF_SUFFIX_TLS_IE)
+ {
+ if ((operand->flags & S390_OPERAND_PCREL)
+ && (operand->bits == 32))
+ reloc = BFD_RELOC_390_TLS_IEENT;
+ }
+
+ if (suffix != ELF_SUFFIX_NONE && reloc == BFD_RELOC_UNUSED)
+ as_bad (_("invalid operand suffix"));
+ /* We need to generate a fixup of type 'reloc' for this
+ expression. */
+ if (fc >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = *opindex_ptr;
+ fixups[fc].reloc = reloc;
+ ++fc;
+ }
+
+ /* Check the next character. The call to expression has advanced
+ str past any whitespace. */
+ if (operand->flags & S390_OPERAND_DISP)
+ {
+ /* After a displacement a block in parentheses can start. */
+ if (*str != '(')
+ {
+ /* Check if parenthesized block can be skipped. If the next
+ operand is neiter an optional operand nor a base register
+ then we have a syntax error. */
+ operand = s390_operands + *(++opindex_ptr);
+ if (!(operand->flags & (S390_OPERAND_INDEX|S390_OPERAND_BASE)))
+ as_bad (_("syntax error; missing '(' after displacement"));
+
+ /* Ok, skip all operands until S390_OPERAND_BASE. */
+ while (!(operand->flags & S390_OPERAND_BASE))
+ operand = s390_operands + *(++opindex_ptr);
+
+ /* If there is a next operand it must be separated by a comma. */
+ if (opindex_ptr[1] != '\0')
+ {
+ if (*str++ != ',')
+ as_bad (_("syntax error; expected ,"));
+ }
+ }
+ else
+ {
+ /* We found an opening parentheses. */
+ str++;
+ for (f = str; *f != '\0'; f++)
+ if (*f == ',' || *f == ')')
+ break;
+ /* If there is no comma until the closing parentheses OR
+ there is a comma right after the opening parentheses,
+ we have to skip optional operands. */
+ if (*f == ',' && f == str)
+ {
+ /* comma directly after '(' ? */
+ skip_optional = 1;
+ str++;
+ }
+ else
+ skip_optional = (*f != ',');
+ }
+ }
+ else if (operand->flags & S390_OPERAND_BASE)
+ {
+ /* After the base register the parenthesed block ends. */
+ if (*str++ != ')')
+ as_bad (_("syntax error; missing ')' after base register"));
+ skip_optional = 0;
+ /* If there is a next operand it must be separated by a comma. */
+ if (opindex_ptr[1] != '\0')
+ {
+ if (*str++ != ',')
+ as_bad (_("syntax error; expected ,"));
+ }
+ }
+ else
+ {
+ /* We can find an 'early' closing parentheses in e.g. D(L) instead
+ of D(L,B). In this case the base register has to be skipped. */
+ if (*str == ')')
+ {
+ operand = s390_operands + *(++opindex_ptr);
+
+ if (!(operand->flags & S390_OPERAND_BASE))
+ as_bad (_("syntax error; ')' not allowed here"));
+ str++;
+ }
+ /* If there is a next operand it must be separated by a comma. */
+ if (opindex_ptr[1] != '\0')
+ {
+ if (*str++ != ',')
+ as_bad (_("syntax error; expected ,"));
+ }
+ }
+ }
+
+ while (ISSPACE (*str))
+ ++str;
+
+ /* Check for tls instruction marker. */
+ reloc = s390_tls_suffix (&str, &ex);
+ if (reloc != BFD_RELOC_UNUSED)
+ {
+ /* We need to generate a fixup of type 'reloc' for this
+ instruction. */
+ if (fc >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = -1;
+ fixups[fc].reloc = reloc;
+ ++fc;
+ }
+
+ if (*str != '\0')
+ {
+ char *linefeed;
+
+ if ((linefeed = strchr (str, '\n')) != NULL)
+ *linefeed = '\0';
+ as_bad (_("junk at end of line: `%s'"), str);
+ if (linefeed != NULL)
+ *linefeed = '\n';
+ }
+
+ /* Write out the instruction. */
+ f = frag_more (opcode->oplen);
+ memcpy (f, insn, opcode->oplen);
+ dwarf2_emit_insn (opcode->oplen);
+
+ /* Create any fixups. At this point we do not use a
+ bfd_reloc_code_real_type, but instead just use the
+ BFD_RELOC_UNUSED plus the operand index. This lets us easily
+ handle fixups for any operand type, although that is admittedly
+ not a very exciting feature. We pick a BFD reloc type in
+ md_apply_fix3. */
+ for (i = 0; i < fc; i++)
+ {
+
+ if (fixups[i].opindex < 0)
+ {
+ /* Create tls instruction marker relocation. */
+ fix_new_exp (frag_now, f - frag_now->fr_literal, opcode->oplen,
+ &fixups[i].exp, 0, fixups[i].reloc);
+ continue;
+ }
+
+ operand = s390_operands + fixups[i].opindex;
+
+ if (fixups[i].reloc != BFD_RELOC_UNUSED)
+ {
+ reloc_howto_type *reloc_howto;
+ fixS *fixP;
+ int size;
+
+ reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
+ if (!reloc_howto)
+ abort ();
+
+ size = bfd_get_reloc_size (reloc_howto);
+
+ if (size < 1 || size > 4)
+ abort ();
+
+ fixP = fix_new_exp (frag_now,
+ f - frag_now->fr_literal + (operand->shift/8),
+ size, &fixups[i].exp, reloc_howto->pc_relative,
+ fixups[i].reloc);
+ /* Turn off overflow checking in fixup_segment. This is necessary
+ because fixup_segment will signal an overflow for large 4 byte
+ quantities for GOT12 relocations. */
+ if ( fixups[i].reloc == BFD_RELOC_390_GOT12
+ || fixups[i].reloc == BFD_RELOC_390_GOT20
+ || fixups[i].reloc == BFD_RELOC_390_GOT16)
+ fixP->fx_no_overflow = 1;
+ }
+ else
+ fix_new_exp (frag_now, f - frag_now->fr_literal, 4, &fixups[i].exp,
+ (operand->flags & S390_OPERAND_PCREL) != 0,
+ ((bfd_reloc_code_real_type)
+ (fixups[i].opindex + (int) BFD_RELOC_UNUSED)));
+ }
+ return str;
+}
+
+/* This routine is called for each instruction to be assembled. */
+
+void
+md_assemble (str)
+ char *str;
+{
+ const struct s390_opcode *opcode;
+ unsigned char insn[6];
+ char *s;
+
+ /* Get the opcode. */
+ for (s = str; *s != '\0' && ! ISSPACE (*s); s++)
+ ;
+ if (*s != '\0')
+ *s++ = '\0';
+
+ /* Look up the opcode in the hash table. */
+ opcode = (struct s390_opcode *) hash_find (s390_opcode_hash, str);
+ if (opcode == (const struct s390_opcode *) NULL)
+ {
+ as_bad (_("Unrecognized opcode: `%s'"), str);
+ return;
+ }
+ else if (!(opcode->modes & current_mode_mask))
+ {
+ as_bad ("Opcode %s not available in this mode", str);
+ return;
+ }
+ memcpy (insn, opcode->opcode, sizeof (insn));
+ md_gather_operands (s, insn, opcode);
+}
+
+#ifndef WORKING_DOT_WORD
+/* Handle long and short jumps. We don't support these */
+void
+md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ addressT from_addr, to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ abort ();
+}
+
+void
+md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ addressT from_addr, to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ abort ();
+}
+#endif
+
+void
+s390_bss (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ /* We don't support putting frags in the BSS segment, we fake it
+ by marking in_bss, then looking at s_skip for clues. */
+
+ subseg_set (bss_section, 0);
+ demand_empty_rest_of_line ();
+}
+
+/* Pseudo-op handling. */
+
+void
+s390_insn (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ expressionS exp;
+ const struct s390_opcode *opformat;
+ unsigned char insn[6];
+ char *s;
+
+ /* Get the opcode format. */
+ s = input_line_pointer;
+ while (*s != '\0' && *s != ',' && ! ISSPACE (*s))
+ s++;
+ if (*s != ',')
+ as_bad (_("Invalid .insn format\n"));
+ *s++ = '\0';
+
+ /* Look up the opcode in the hash table. */
+ opformat = (struct s390_opcode *)
+ hash_find (s390_opformat_hash, input_line_pointer);
+ if (opformat == (const struct s390_opcode *) NULL)
+ {
+ as_bad (_("Unrecognized opcode format: `%s'"), input_line_pointer);
+ return;
+ }
+ input_line_pointer = s;
+ expression (&exp);
+ if (exp.X_op == O_constant)
+ {
+ if ( ( opformat->oplen == 6
+ && exp.X_add_number >= 0
+ && (addressT) exp.X_add_number < (1ULL << 48))
+ || ( opformat->oplen == 4
+ && exp.X_add_number >= 0
+ && (addressT) exp.X_add_number < (1ULL << 32))
+ || ( opformat->oplen == 2
+ && exp.X_add_number >= 0
+ && (addressT) exp.X_add_number < (1ULL << 16)))
+ md_number_to_chars (insn, exp.X_add_number, opformat->oplen);
+ else
+ as_bad (_("Invalid .insn format\n"));
+ }
+ else if (exp.X_op == O_big)
+ {
+ if (exp.X_add_number > 0
+ && opformat->oplen == 6
+ && generic_bignum[3] == 0)
+ {
+ md_number_to_chars (insn, generic_bignum[2], 2);
+ md_number_to_chars (&insn[2], generic_bignum[1], 2);
+ md_number_to_chars (&insn[4], generic_bignum[0], 2);
+ }
+ else
+ as_bad (_("Invalid .insn format\n"));
+ }
+ else
+ as_bad (_("second operand of .insn not a constant\n"));
+
+ if (strcmp (opformat->name, "e") != 0 && *input_line_pointer++ != ',')
+ as_bad (_("missing comma after insn constant\n"));
+
+ if ((s = strchr (input_line_pointer, '\n')) != NULL)
+ *s = '\0';
+ input_line_pointer = md_gather_operands (input_line_pointer, insn,
+ opformat);
+ if (s != NULL)
+ *s = '\n';
+ demand_empty_rest_of_line ();
+}
+
+/* The .byte pseudo-op. This is similar to the normal .byte
+ pseudo-op, but it can also take a single ASCII string. */
+
+static void
+s390_byte (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (*input_line_pointer != '\"')
+ {
+ cons (1);
+ return;
+ }
+
+ /* Gather characters. A real double quote is doubled. Unusual
+ characters are not permitted. */
+ ++input_line_pointer;
+ while (1)
+ {
+ char c;
+
+ c = *input_line_pointer++;
+
+ if (c == '\"')
+ {
+ if (*input_line_pointer != '\"')
+ break;
+ ++input_line_pointer;
+ }
+
+ FRAG_APPEND_1_CHAR (c);
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .ltorg pseudo-op.This emits all literals defined since the last
+ .ltorg or the invocation of gas. Literals are defined with the
+ @lit suffix. */
+
+static void
+s390_literals (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ struct s390_lpe *lpe;
+
+ if (lp_sym == NULL || lpe_count == 0)
+ return; /* Nothing to be done. */
+
+ /* Emit symbol for start of literal pool. */
+ S_SET_SEGMENT (lp_sym, now_seg);
+ S_SET_VALUE (lp_sym, (valueT) frag_now_fix ());
+ lp_sym->sy_frag = frag_now;
+
+ while (lpe_list)
+ {
+ lpe = lpe_list;
+ lpe_list = lpe_list->next;
+ S_SET_SEGMENT (lpe->sym, now_seg);
+ S_SET_VALUE (lpe->sym, (valueT) frag_now_fix ());
+ lpe->sym->sy_frag = frag_now;
+
+ /* Emit literal pool entry. */
+ if (lpe->reloc != BFD_RELOC_UNUSED)
+ {
+ reloc_howto_type *reloc_howto =
+ bfd_reloc_type_lookup (stdoutput, lpe->reloc);
+ int size = bfd_get_reloc_size (reloc_howto);
+ char *where;
+
+ if (size > lpe->nbytes)
+ as_bad (_("%s relocations do not fit in %d bytes"),
+ reloc_howto->name, lpe->nbytes);
+ where = frag_more (lpe->nbytes);
+ md_number_to_chars (where, 0, size);
+ fix_new_exp (frag_now, where - frag_now->fr_literal,
+ size, &lpe->ex, reloc_howto->pc_relative, lpe->reloc);
+ }
+ else
+ {
+ if (lpe->ex.X_op == O_big)
+ {
+ if (lpe->ex.X_add_number <= 0)
+ generic_floating_point_number = lpe->floatnum;
+ else
+ memcpy (generic_bignum, lpe->bignum,
+ lpe->ex.X_add_number * sizeof (LITTLENUM_TYPE));
+ }
+ emit_expr (&lpe->ex, lpe->nbytes);
+ }
+
+ lpe->next = lpe_free_list;
+ lpe_free_list = lpe;
+ }
+ lpe_list_tail = NULL;
+ lp_sym = NULL;
+ lp_count++;
+ lpe_count = 0;
+}
+
+/* Turn a string in input_line_pointer into a floating point constant
+ of type type, and store the appropriate bytes in *litp. The number
+ of LITTLENUMS emitted is stored in *sizep . An error message is
+ returned, or NULL on OK. */
+
+char *
+md_atof (type, litp, sizep)
+ int type;
+ char *litp;
+ int *sizep;
+{
+ int prec;
+ LITTLENUM_TYPE words[4];
+ char *t;
+ int i;
+
+ switch (type)
+ {
+ case 'f':
+ prec = 2;
+ break;
+
+ case 'd':
+ prec = 4;
+ break;
+
+ default:
+ *sizep = 0;
+ return "bad call to md_atof";
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizep = prec * 2;
+
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litp, (valueT) words[i], 2);
+ litp += 2;
+ }
+
+ return NULL;
+}
+
+/* Align a section (I don't know why this is machine dependent). */
+
+valueT
+md_section_align (seg, addr)
+ asection *seg;
+ valueT addr;
+{
+ int align = bfd_get_section_alignment (stdoutput, seg);
+
+ return ((addr + (1 << align) - 1) & (-1 << align));
+}
+
+/* We don't have any form of relaxing. */
+
+int
+md_estimate_size_before_relax (fragp, seg)
+ fragS *fragp ATTRIBUTE_UNUSED;
+ asection *seg ATTRIBUTE_UNUSED;
+{
+ abort ();
+ return 0;
+}
+
+/* Convert a machine dependent frag. We never generate these. */
+
+void
+md_convert_frag (abfd, sec, fragp)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *sec ATTRIBUTE_UNUSED;
+ fragS *fragp ATTRIBUTE_UNUSED;
+{
+ abort ();
+}
+
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ if (*name == '_' && *(name + 1) == 'G'
+ && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
+ {
+ if (!GOT_symbol)
+ {
+ if (symbol_find (name))
+ as_bad (_("GOT already in symbol table"));
+ GOT_symbol = symbol_new (name, undefined_section,
+ (valueT) 0, &zero_address_frag);
+ }
+ return GOT_symbol;
+ }
+ return 0;
+}
+
+/* Functions concerning relocs. */
+
+/* The location from which a PC relative jump should be calculated,
+ given a PC relative reloc. */
+
+long
+md_pcrel_from_section (fixp, sec)
+ fixS *fixp;
+ segT sec ATTRIBUTE_UNUSED;
+{
+ return fixp->fx_frag->fr_address + fixp->fx_where;
+}
+
+/* Here we decide which fixups can be adjusted to make them relative to
+ the beginning of the section instead of the symbol. Basically we need
+ to make sure that the dynamic relocations are done correctly, so in
+ some cases we force the original symbol to be used. */
+int
+tc_s390_fix_adjustable (fixP)
+ fixS *fixP;
+{
+ /* Don't adjust references to merge sections. */
+ if ((S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0)
+ return 0;
+ /* adjust_reloc_syms doesn't know about the GOT. */
+ if ( fixP->fx_r_type == BFD_RELOC_16_GOTOFF
+ || fixP->fx_r_type == BFD_RELOC_32_GOTOFF
+ || fixP->fx_r_type == BFD_RELOC_390_GOTOFF64
+ || fixP->fx_r_type == BFD_RELOC_390_PLTOFF16
+ || fixP->fx_r_type == BFD_RELOC_390_PLTOFF32
+ || fixP->fx_r_type == BFD_RELOC_390_PLTOFF64
+ || fixP->fx_r_type == BFD_RELOC_390_PLT16DBL
+ || fixP->fx_r_type == BFD_RELOC_390_PLT32
+ || fixP->fx_r_type == BFD_RELOC_390_PLT32DBL
+ || fixP->fx_r_type == BFD_RELOC_390_PLT64
+ || fixP->fx_r_type == BFD_RELOC_390_GOT12
+ || fixP->fx_r_type == BFD_RELOC_390_GOT20
+ || fixP->fx_r_type == BFD_RELOC_390_GOT16
+ || fixP->fx_r_type == BFD_RELOC_32_GOT_PCREL
+ || fixP->fx_r_type == BFD_RELOC_390_GOT64
+ || fixP->fx_r_type == BFD_RELOC_390_GOTENT
+ || fixP->fx_r_type == BFD_RELOC_390_GOTPLT12
+ || fixP->fx_r_type == BFD_RELOC_390_GOTPLT16
+ || fixP->fx_r_type == BFD_RELOC_390_GOTPLT20
+ || fixP->fx_r_type == BFD_RELOC_390_GOTPLT32
+ || fixP->fx_r_type == BFD_RELOC_390_GOTPLT64
+ || fixP->fx_r_type == BFD_RELOC_390_GOTPLTENT
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_LOAD
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_GDCALL
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_LDCALL
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_GD32
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_GD64
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_GOTIE12
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_GOTIE20
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_GOTIE32
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_GOTIE64
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_LDM32
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_LDM64
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_IE32
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_IE64
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_IEENT
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_LE32
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_LE64
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_LDO32
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_LDO64
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_DTPMOD
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_DTPOFF
+ || fixP->fx_r_type == BFD_RELOC_390_TLS_TPOFF
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+ return 1;
+}
+
+/* Return true if we must always emit a reloc for a type and false if
+ there is some hope of resolving it at assembly time. */
+int
+tc_s390_force_relocation (fixp)
+ struct fix *fixp;
+{
+ /* Ensure we emit a relocation for every reference to the global
+ offset table or to the procedure link table. */
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_390_GOT12:
+ case BFD_RELOC_390_GOT20:
+ case BFD_RELOC_32_GOT_PCREL:
+ case BFD_RELOC_32_GOTOFF:
+ case BFD_RELOC_390_GOTOFF64:
+ case BFD_RELOC_390_PLTOFF16:
+ case BFD_RELOC_390_PLTOFF32:
+ case BFD_RELOC_390_PLTOFF64:
+ case BFD_RELOC_390_GOTPC:
+ case BFD_RELOC_390_GOT16:
+ case BFD_RELOC_390_GOTPCDBL:
+ case BFD_RELOC_390_GOT64:
+ case BFD_RELOC_390_GOTENT:
+ case BFD_RELOC_390_PLT32:
+ case BFD_RELOC_390_PLT16DBL:
+ case BFD_RELOC_390_PLT32DBL:
+ case BFD_RELOC_390_PLT64:
+ case BFD_RELOC_390_GOTPLT12:
+ case BFD_RELOC_390_GOTPLT16:
+ case BFD_RELOC_390_GOTPLT20:
+ case BFD_RELOC_390_GOTPLT32:
+ case BFD_RELOC_390_GOTPLT64:
+ case BFD_RELOC_390_GOTPLTENT:
+ return 1;
+ default:
+ break;;
+ }
+
+ return generic_force_reloc (fixp);
+}
+
+/* Apply a fixup to the object code. This is called for all the
+ fixups we generated by the call to fix_new_exp, above. In the call
+ above we used a reloc code which was the largest legal reloc code
+ plus the operand index. Here we undo that to recover the operand
+ index. At this point all symbol values should be fully resolved,
+ and we attempt to completely resolve the reloc. If we can not do
+ that, we determine the correct reloc code and put it back in the
+ fixup. */
+
+void
+md_apply_fix3 (fixP, valP, seg)
+ fixS *fixP;
+ valueT *valP;
+ segT seg ATTRIBUTE_UNUSED;
+{
+ char *where;
+ valueT value = *valP;
+
+ where = fixP->fx_frag->fr_literal + fixP->fx_where;
+
+ if (fixP->fx_subsy != NULL)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ "cannot emit relocation %s against subsy symbol %s",
+ bfd_get_reloc_code_name (fixP->fx_r_type),
+ S_GET_NAME (fixP->fx_subsy));
+
+ if (fixP->fx_addsy != NULL)
+ {
+ if (fixP->fx_pcrel)
+ value += fixP->fx_frag->fr_address + fixP->fx_where;
+ }
+ else
+ fixP->fx_done = 1;
+
+ if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
+ {
+ const struct s390_operand *operand;
+ int opindex;
+
+ opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
+ operand = &s390_operands[opindex];
+
+ if (fixP->fx_done)
+ {
+ /* Insert the fully resolved operand value. */
+ s390_insert_operand (where, operand, (offsetT) value,
+ fixP->fx_file, fixP->fx_line);
+ return;
+ }
+
+ /* Determine a BFD reloc value based on the operand information.
+ We are only prepared to turn a few of the operands into
+ relocs. */
+ fixP->fx_offset = value;
+ if (operand->bits == 12 && operand->shift == 20)
+ {
+ fixP->fx_size = 2;
+ fixP->fx_where += 2;
+ fixP->fx_r_type = BFD_RELOC_390_12;
+ }
+ else if (operand->bits == 12 && operand->shift == 36)
+ {
+ fixP->fx_size = 2;
+ fixP->fx_where += 4;
+ fixP->fx_r_type = BFD_RELOC_390_12;
+ }
+ else if (operand->bits == 20 && operand->shift == 20)
+ {
+ fixP->fx_size = 2;
+ fixP->fx_where += 2;
+ fixP->fx_r_type = BFD_RELOC_390_20;
+ }
+ else if (operand->bits == 8 && operand->shift == 8)
+ {
+ fixP->fx_size = 1;
+ fixP->fx_where += 1;
+ fixP->fx_r_type = BFD_RELOC_8;
+ }
+ else if (operand->bits == 16 && operand->shift == 16)
+ {
+ fixP->fx_size = 2;
+ fixP->fx_where += 2;
+ if (operand->flags & S390_OPERAND_PCREL)
+ {
+ fixP->fx_r_type = BFD_RELOC_390_PC16DBL;
+ fixP->fx_offset += 2;
+ }
+ else
+ fixP->fx_r_type = BFD_RELOC_16;
+ }
+ else if (operand->bits == 32 && operand->shift == 16
+ && (operand->flags & S390_OPERAND_PCREL))
+ {
+ fixP->fx_size = 4;
+ fixP->fx_where += 2;
+ fixP->fx_offset += 2;
+ fixP->fx_r_type = BFD_RELOC_390_PC32DBL;
+ }
+ else
+ {
+ char *sfile;
+ unsigned int sline;
+
+ /* Use expr_symbol_where to see if this is an expression
+ symbol. */
+ if (expr_symbol_where (fixP->fx_addsy, &sfile, &sline))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("unresolved expression that must be resolved"));
+ else
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("unsupported relocation type"));
+ fixP->fx_done = 1;
+ return;
+ }
+ }
+ else
+ {
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_8:
+ if (fixP->fx_pcrel)
+ abort ();
+ if (fixP->fx_done)
+ md_number_to_chars (where, value, 1);
+ break;
+ case BFD_RELOC_390_12:
+ case BFD_RELOC_390_GOT12:
+ case BFD_RELOC_390_GOTPLT12:
+ if (fixP->fx_done)
+ {
+ unsigned short mop;
+
+ mop = bfd_getb16 ((unsigned char *) where);
+ mop |= (unsigned short) (value & 0xfff);
+ bfd_putb16 ((bfd_vma) mop, (unsigned char *) where);
+ }
+ break;
+
+ case BFD_RELOC_390_20:
+ case BFD_RELOC_390_GOT20:
+ case BFD_RELOC_390_GOTPLT20:
+ if (fixP->fx_done)
+ {
+ unsigned int mop;
+ mop = bfd_getb32 ((unsigned char *) where);
+ mop |= (unsigned int) ((value & 0xfff) << 8 |
+ (value & 0xff000) >> 12);
+ bfd_putb32 ((bfd_vma) mop, (unsigned char *) where);
+ }
+ break;
+
+ case BFD_RELOC_16:
+ case BFD_RELOC_GPREL16:
+ case BFD_RELOC_16_GOT_PCREL:
+ case BFD_RELOC_16_GOTOFF:
+ if (fixP->fx_pcrel)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ "cannot emit PC relative %s relocation%s%s",
+ bfd_get_reloc_code_name (fixP->fx_r_type),
+ fixP->fx_addsy != NULL ? " against " : "",
+ (fixP->fx_addsy != NULL
+ ? S_GET_NAME (fixP->fx_addsy)
+ : ""));
+ if (fixP->fx_done)
+ md_number_to_chars (where, value, 2);
+ break;
+ case BFD_RELOC_390_GOT16:
+ case BFD_RELOC_390_PLTOFF16:
+ case BFD_RELOC_390_GOTPLT16:
+ if (fixP->fx_done)
+ md_number_to_chars (where, value, 2);
+ break;
+ case BFD_RELOC_390_PC16DBL:
+ case BFD_RELOC_390_PLT16DBL:
+ value += 2;
+ if (fixP->fx_done)
+ md_number_to_chars (where, (offsetT) value >> 1, 2);
+ break;
+
+ case BFD_RELOC_32:
+ if (fixP->fx_pcrel)
+ fixP->fx_r_type = BFD_RELOC_32_PCREL;
+ else
+ fixP->fx_r_type = BFD_RELOC_32;
+ if (fixP->fx_done)
+ md_number_to_chars (where, value, 4);
+ break;
+ case BFD_RELOC_32_PCREL:
+ case BFD_RELOC_32_BASEREL:
+ fixP->fx_r_type = BFD_RELOC_32_PCREL;
+ if (fixP->fx_done)
+ md_number_to_chars (where, value, 4);
+ break;
+ case BFD_RELOC_32_GOT_PCREL:
+ case BFD_RELOC_390_PLTOFF32:
+ case BFD_RELOC_390_PLT32:
+ case BFD_RELOC_390_GOTPLT32:
+ if (fixP->fx_done)
+ md_number_to_chars (where, value, 4);
+ break;
+ case BFD_RELOC_390_PC32DBL:
+ case BFD_RELOC_390_PLT32DBL:
+ case BFD_RELOC_390_GOTPCDBL:
+ case BFD_RELOC_390_GOTENT:
+ case BFD_RELOC_390_GOTPLTENT:
+ value += 2;
+ if (fixP->fx_done)
+ md_number_to_chars (where, (offsetT) value >> 1, 4);
+ break;
+
+ case BFD_RELOC_32_GOTOFF:
+ if (fixP->fx_done)
+ md_number_to_chars (where, value, sizeof (int));
+ break;
+
+ case BFD_RELOC_390_GOTOFF64:
+ if (fixP->fx_done)
+ md_number_to_chars (where, value, 8);
+ break;
+
+ case BFD_RELOC_390_GOT64:
+ case BFD_RELOC_390_PLTOFF64:
+ case BFD_RELOC_390_PLT64:
+ case BFD_RELOC_390_GOTPLT64:
+ if (fixP->fx_done)
+ md_number_to_chars (where, value, 8);
+ break;
+
+ case BFD_RELOC_64:
+ if (fixP->fx_pcrel)
+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
+ else
+ fixP->fx_r_type = BFD_RELOC_64;
+ if (fixP->fx_done)
+ md_number_to_chars (where, value, 8);
+ break;
+
+ case BFD_RELOC_64_PCREL:
+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
+ if (fixP->fx_done)
+ md_number_to_chars (where, value, 8);
+ break;
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixP->fx_done = 0;
+ return;
+
+ case BFD_RELOC_390_TLS_LOAD:
+ case BFD_RELOC_390_TLS_GDCALL:
+ case BFD_RELOC_390_TLS_LDCALL:
+ case BFD_RELOC_390_TLS_GD32:
+ case BFD_RELOC_390_TLS_GD64:
+ case BFD_RELOC_390_TLS_GOTIE12:
+ case BFD_RELOC_390_TLS_GOTIE20:
+ case BFD_RELOC_390_TLS_GOTIE32:
+ case BFD_RELOC_390_TLS_GOTIE64:
+ case BFD_RELOC_390_TLS_LDM32:
+ case BFD_RELOC_390_TLS_LDM64:
+ case BFD_RELOC_390_TLS_IE32:
+ case BFD_RELOC_390_TLS_IE64:
+ case BFD_RELOC_390_TLS_LE32:
+ case BFD_RELOC_390_TLS_LE64:
+ case BFD_RELOC_390_TLS_LDO32:
+ case BFD_RELOC_390_TLS_LDO64:
+ case BFD_RELOC_390_TLS_DTPMOD:
+ case BFD_RELOC_390_TLS_DTPOFF:
+ case BFD_RELOC_390_TLS_TPOFF:
+ /* Fully resolved at link time. */
+ break;
+ case BFD_RELOC_390_TLS_IEENT:
+ /* Fully resolved at link time. */
+ value += 2;
+ break;
+
+ default:
+ {
+ const char *reloc_name = bfd_get_reloc_code_name (fixP->fx_r_type);
+
+ if (reloc_name != NULL)
+ fprintf (stderr, "Gas failure, reloc type %s\n", reloc_name);
+ else
+ fprintf (stderr, "Gas failure, reloc type #%i\n", fixP->fx_r_type);
+ fflush (stderr);
+ abort ();
+ }
+ }
+
+ fixP->fx_offset = value;
+ }
+}
+
+/* Generate a reloc for a fixup. */
+
+arelent *
+tc_gen_reloc (seg, fixp)
+ asection *seg ATTRIBUTE_UNUSED;
+ fixS *fixp;
+{
+ bfd_reloc_code_real_type code;
+ arelent *reloc;
+
+ code = fixp->fx_r_type;
+ if (GOT_symbol && fixp->fx_addsy == GOT_symbol)
+ {
+ if ( (s390_arch_size == 32 && code == BFD_RELOC_32_PCREL)
+ || (s390_arch_size == 64 && code == BFD_RELOC_64_PCREL))
+ code = BFD_RELOC_390_GOTPC;
+ if (code == BFD_RELOC_390_PC32DBL)
+ code = BFD_RELOC_390_GOTPCDBL;
+ }
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+ if (reloc->howto == NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("cannot represent relocation type %s"),
+ bfd_get_reloc_code_name (code));
+ /* Set howto to a garbage value so that we can keep going. */
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
+ assert (reloc->howto != NULL);
+ }
+ reloc->addend = fixp->fx_offset;
+
+ return reloc;
+}
+
+void
+s390_cfi_frame_initial_instructions ()
+{
+ cfi_add_CFA_def_cfa (15, s390_arch_size == 64 ? 160 : 96);
+}
+
+int
+tc_s390_regname_to_dw2regnum (const char *regname)
+{
+ int regnum = -1;
+
+ if (regname[0] != 'c' && regname[0] != 'a')
+ {
+ regnum = reg_name_search (pre_defined_registers, REG_NAME_CNT, regname);
+ if (regname[0] == 'f' && regnum != -1)
+ regnum += 16;
+ }
+ else if (strcmp (regname, "ap") == 0)
+ regnum = 32;
+ else if (strcmp (regname, "cc") == 0)
+ regnum = 33;
+ return regnum;
+}
diff --git a/x/binutils/gas/config/tc-s390.h b/x/binutils/gas/config/tc-s390.h
new file mode 100644
index 0000000..fe55e15
--- /dev/null
+++ b/x/binutils/gas/config/tc-s390.h
@@ -0,0 +1,102 @@
+/* tc-s390.h -- Header file for tc-s390.c.
+ Copyright 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+ Written by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_S390
+
+#ifdef ANSI_PROTOTYPES
+struct fix;
+#endif
+
+#ifndef BFD_ASSEMBLER
+ #error S390 support requires BFD_ASSEMBLER
+#endif
+
+#define TC_FORCE_RELOCATION(FIX) tc_s390_force_relocation(FIX)
+extern int tc_s390_force_relocation PARAMS ((struct fix *));
+
+/* Don't resolve foo@PLT-bar to offset@PLT. */
+#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEG) \
+ (! SEG_NORMAL (SEG) || TC_FORCE_RELOCATION (FIX))
+
+#define tc_fix_adjustable(X) tc_s390_fix_adjustable(X)
+extern int tc_s390_fix_adjustable PARAMS ((struct fix *));
+
+/* Values passed to md_apply_fix3 don't include symbol values. */
+#define MD_APPLY_SYM_VALUE(FIX) 0
+
+/* The target BFD architecture. */
+#define TARGET_ARCH bfd_arch_s390
+extern enum bfd_architecture s390_arch PARAMS ((void));
+
+/* The target BFD format. */
+#define TARGET_FORMAT s390_target_format()
+extern const char *s390_target_format PARAMS ((void));
+
+/* Set the endianness we are using. */
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+/* Whether or not the target is big endian */
+extern int target_big_endian;
+
+/* Permit temporary numeric labels. */
+#define LOCAL_LABELS_FB 1
+
+/* $ is used to refer to the current location. */
+/* #define DOLLAR_DOT */
+
+/* We need to be able to make relocations involving the difference of
+ two symbols. This includes the difference of two symbols when
+ one of them is undefined (this comes up in PIC code generation).
+ */
+#define UNDEFINED_DIFFERENCE_OK
+
+/* foo-. gets turned into PC relative relocs */
+#define DIFF_EXPR_OK
+
+/* We don't need to handle .word strangely. */
+#define WORKING_DOT_WORD
+
+#define md_number_to_chars number_to_chars_bigendian
+
+#define NOP_OPCODE 0x07
+
+/* call md_pcrel_from_section, not md_pcrel_from */
+#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section(FIX, SEC)
+extern long md_pcrel_from_section PARAMS ((struct fix *, segT));
+
+#define md_operand(x)
+
+extern void s390_md_end PARAMS ((void));
+#define md_end() s390_md_end ()
+
+#define TARGET_USE_CFIPOP 1
+
+#define tc_cfi_frame_initial_instructions s390_cfi_frame_initial_instructions
+extern void s390_cfi_frame_initial_instructions PARAMS ((void));
+
+#define tc_regname_to_dw2regnum tc_s390_regname_to_dw2regnum
+extern int tc_s390_regname_to_dw2regnum PARAMS ((const char *regname));
+
+extern int s390_cie_data_alignment;
+
+#define DWARF2_LINE_MIN_INSN_LENGTH 1
+#define DWARF2_DEFAULT_RETURN_COLUMN 14
+#define DWARF2_CIE_DATA_ALIGNMENT s390_cie_data_alignment
diff --git a/x/binutils/gas/config/tc-sh.c b/x/binutils/gas/config/tc-sh.c
new file mode 100644
index 0000000..1361cb8
--- /dev/null
+++ b/x/binutils/gas/config/tc-sh.c
@@ -0,0 +1,4054 @@
+/* tc-sh.c -- Assemble code for the Hitachi Super-H
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* Written By Steve Chamberlain <sac@cygnus.com> */
+
+#include <stdio.h>
+#include "as.h"
+#include "bfd.h"
+#include "subsegs.h"
+#define DEFINE_TABLE
+#include "opcodes/sh-opc.h"
+#include "safe-ctype.h"
+#include "struc-symbol.h"
+
+#ifdef OBJ_ELF
+#include "elf/sh.h"
+#endif
+
+#include "dwarf2dbg.h"
+
+typedef struct
+ {
+ sh_arg_type type;
+ int reg;
+ expressionS immediate;
+ }
+sh_operand_info;
+
+const char comment_chars[] = "!";
+const char line_separator_chars[] = ";";
+const char line_comment_chars[] = "!#";
+
+static void s_uses PARAMS ((int));
+
+static void sh_count_relocs PARAMS ((bfd *, segT, PTR));
+static void sh_frob_section PARAMS ((bfd *, segT, PTR));
+
+static void s_uacons PARAMS ((int));
+static sh_opcode_info *find_cooked_opcode PARAMS ((char **));
+static unsigned int assemble_ppi PARAMS ((char *, sh_opcode_info *));
+static void little PARAMS ((int));
+static void big PARAMS ((int));
+static int parse_reg PARAMS ((char *, int *, int *));
+static char *parse_exp PARAMS ((char *, sh_operand_info *));
+static char *parse_at PARAMS ((char *, sh_operand_info *));
+static void get_operand PARAMS ((char **, sh_operand_info *));
+static char *get_operands
+ PARAMS ((sh_opcode_info *, char *, sh_operand_info *));
+static sh_opcode_info *get_specific
+ PARAMS ((sh_opcode_info *, sh_operand_info *));
+static void insert PARAMS ((char *, int, int, sh_operand_info *));
+static void build_relax PARAMS ((sh_opcode_info *, sh_operand_info *));
+static char *insert_loop_bounds PARAMS ((char *, sh_operand_info *));
+static unsigned int build_Mytes
+ PARAMS ((sh_opcode_info *, sh_operand_info *));
+
+#ifdef OBJ_ELF
+static void sh_elf_cons PARAMS ((int));
+
+inline static int sh_PIC_related_p PARAMS ((symbolS *));
+static int sh_check_fixup PARAMS ((expressionS *, bfd_reloc_code_real_type *));
+inline static char *sh_end_of_match PARAMS ((char *, char *));
+
+symbolS *GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
+#endif
+
+static void
+big (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (! target_big_endian)
+ as_bad (_("directive .big encountered when option -big required"));
+
+ /* Stop further messages. */
+ target_big_endian = 1;
+}
+
+static void
+little (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (target_big_endian)
+ as_bad (_("directive .little encountered when option -little required"));
+
+ /* Stop further messages. */
+ target_big_endian = 0;
+}
+
+/* This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+ pseudo-op name without dot
+ function to call to execute this pseudo-op
+ Integer arg to pass to the function. */
+
+const pseudo_typeS md_pseudo_table[] =
+{
+#ifdef OBJ_ELF
+ {"long", sh_elf_cons, 4},
+ {"int", sh_elf_cons, 4},
+ {"word", sh_elf_cons, 2},
+ {"short", sh_elf_cons, 2},
+#else
+ {"int", cons, 4},
+ {"word", cons, 2},
+#endif /* OBJ_ELF */
+ {"big", big, 0},
+ {"form", listing_psize, 0},
+ {"little", little, 0},
+ {"heading", listing_title, 0},
+ {"import", s_ignore, 0},
+ {"page", listing_eject, 0},
+ {"program", s_ignore, 0},
+ {"uses", s_uses, 0},
+ {"uaword", s_uacons, 2},
+ {"ualong", s_uacons, 4},
+ {"uaquad", s_uacons, 8},
+ {"2byte", s_uacons, 2},
+ {"4byte", s_uacons, 4},
+ {"8byte", s_uacons, 8},
+#ifdef BFD_ASSEMBLER
+ {"file", dwarf2_directive_file, 0 },
+ {"loc", dwarf2_directive_loc, 0 },
+#endif
+#ifdef HAVE_SH64
+ {"mode", s_sh64_mode, 0 },
+
+ /* Have the old name too. */
+ {"isa", s_sh64_mode, 0 },
+
+ /* Assert that the right ABI is used. */
+ {"abi", s_sh64_abi, 0 },
+
+ { "vtable_inherit", sh64_vtable_inherit, 0 },
+ { "vtable_entry", sh64_vtable_entry, 0 },
+#endif /* HAVE_SH64 */
+ {0, 0, 0}
+};
+
+/*int md_reloc_size; */
+
+int sh_relax; /* set if -relax seen */
+
+/* Whether -small was seen. */
+
+int sh_small;
+
+/* Whether -dsp was seen. */
+
+static int sh_dsp;
+
+/* The bit mask of architectures that could
+ accomodate the insns seen so far. */
+static int valid_arch;
+
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant. */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+#define C(a,b) ENCODE_RELAX(a,b)
+
+#define ENCODE_RELAX(what,length) (((what) << 4) + (length))
+#define GET_WHAT(x) ((x>>4))
+
+/* These are the three types of relaxable instrction. */
+/* These are the types of relaxable instructions; except for END which is
+ a marker. */
+#define COND_JUMP 1
+#define COND_JUMP_DELAY 2
+#define UNCOND_JUMP 3
+
+#ifdef HAVE_SH64
+
+/* A 16-bit (times four) pc-relative operand, at most expanded to 32 bits. */
+#define SH64PCREL16_32 4
+/* A 16-bit (times four) pc-relative operand, at most expanded to 64 bits. */
+#define SH64PCREL16_64 5
+
+/* Variants of the above for adjusting the insn to PTA or PTB according to
+ the label. */
+#define SH64PCREL16PT_32 6
+#define SH64PCREL16PT_64 7
+
+/* A MOVI expansion, expanding to at most 32 or 64 bits. */
+#define MOVI_IMM_32 8
+#define MOVI_IMM_32_PCREL 9
+#define MOVI_IMM_64 10
+#define MOVI_IMM_64_PCREL 11
+#define END 12
+
+#else /* HAVE_SH64 */
+
+#define END 4
+
+#endif /* HAVE_SH64 */
+
+#define UNDEF_DISP 0
+#define COND8 1
+#define COND12 2
+#define COND32 3
+#define UNDEF_WORD_DISP 4
+
+#define UNCOND12 1
+#define UNCOND32 2
+
+#ifdef HAVE_SH64
+#define UNDEF_SH64PCREL 0
+#define SH64PCREL16 1
+#define SH64PCREL32 2
+#define SH64PCREL48 3
+#define SH64PCREL64 4
+#define SH64PCRELPLT 5
+
+#define UNDEF_MOVI 0
+#define MOVI_16 1
+#define MOVI_32 2
+#define MOVI_48 3
+#define MOVI_64 4
+#define MOVI_PLT 5
+#define MOVI_GOTOFF 6
+#define MOVI_GOTPC 7
+#endif /* HAVE_SH64 */
+
+/* Branch displacements are from the address of the branch plus
+ four, thus all minimum and maximum values have 4 added to them. */
+#define COND8_F 258
+#define COND8_M -252
+#define COND8_LENGTH 2
+
+/* There is one extra instruction before the branch, so we must add
+ two more bytes to account for it. */
+#define COND12_F 4100
+#define COND12_M -4090
+#define COND12_LENGTH 6
+
+#define COND12_DELAY_LENGTH 4
+
+/* ??? The minimum and maximum values are wrong, but this does not matter
+ since this relocation type is not supported yet. */
+#define COND32_F (1<<30)
+#define COND32_M -(1<<30)
+#define COND32_LENGTH 14
+
+#define UNCOND12_F 4098
+#define UNCOND12_M -4092
+#define UNCOND12_LENGTH 2
+
+/* ??? The minimum and maximum values are wrong, but this does not matter
+ since this relocation type is not supported yet. */
+#define UNCOND32_F (1<<30)
+#define UNCOND32_M -(1<<30)
+#define UNCOND32_LENGTH 14
+
+#ifdef HAVE_SH64
+/* The trivial expansion of a SH64PCREL16 relaxation is just a "PT label,
+ TRd" as is the current insn, so no extra length. Note that the "reach"
+ is calculated from the address *after* that insn, but the offset in the
+ insn is calculated from the beginning of the insn. We also need to
+ take into account the implicit 1 coded as the "A" in PTA when counting
+ forward. If PTB reaches an odd address, we trap that as an error
+ elsewhere, so we don't have to have different relaxation entries. We
+ don't add a one to the negative range, since PTB would then have the
+ farthest backward-reaching value skipped, not generated at relaxation. */
+#define SH64PCREL16_F (32767 * 4 - 4 + 1)
+#define SH64PCREL16_M (-32768 * 4 - 4)
+#define SH64PCREL16_LENGTH 0
+
+/* The next step is to change that PT insn into
+ MOVI ((label - datalabel Ln) >> 16) & 65535, R25
+ SHORI (label - datalabel Ln) & 65535, R25
+ Ln:
+ PTREL R25,TRd
+ which means two extra insns, 8 extra bytes. This is the limit for the
+ 32-bit ABI.
+
+ The expressions look a bit bad since we have to adjust this to avoid overflow on a
+ 32-bit host. */
+#define SH64PCREL32_F ((((long) 1 << 30) - 1) * 2 + 1 - 4)
+#define SH64PCREL32_LENGTH (2 * 4)
+
+/* Similarly, we just change the MOVI and add a SHORI for the 48-bit
+ expansion. */
+#if BFD_HOST_64BIT_LONG
+/* The "reach" type is long, so we can only do this for a 64-bit-long
+ host. */
+#define SH64PCREL32_M (((long) -1 << 30) * 2 - 4)
+#define SH64PCREL48_F ((((long) 1 << 47) - 1) - 4)
+#define SH64PCREL48_M (((long) -1 << 47) - 4)
+#define SH64PCREL48_LENGTH (3 * 4)
+#else
+/* If the host does not have 64-bit longs, just make this state identical
+ in reach to the 32-bit state. Note that we have a slightly incorrect
+ reach, but the correct one above will overflow a 32-bit number. */
+#define SH64PCREL32_M (((long) -1 << 30) * 2)
+#define SH64PCREL48_F SH64PCREL32_F
+#define SH64PCREL48_M SH64PCREL32_M
+#define SH64PCREL48_LENGTH (3 * 4)
+#endif /* BFD_HOST_64BIT_LONG */
+
+/* And similarly for the 64-bit expansion; a MOVI + SHORI + SHORI + SHORI
+ + PTREL sequence. */
+#define SH64PCREL64_LENGTH (4 * 4)
+
+/* For MOVI, we make the MOVI + SHORI... expansion you can see in the
+ SH64PCREL expansions. The PCREL one is similar, but the other has no
+ pc-relative reach; it must be fully expanded in
+ shmedia_md_estimate_size_before_relax. */
+#define MOVI_16_LENGTH 0
+#define MOVI_16_F (32767 - 4)
+#define MOVI_16_M (-32768 - 4)
+#define MOVI_32_LENGTH 4
+#define MOVI_32_F ((((long) 1 << 30) - 1) * 2 + 1 - 4)
+#define MOVI_48_LENGTH 8
+
+#if BFD_HOST_64BIT_LONG
+/* The "reach" type is long, so we can only do this for a 64-bit-long
+ host. */
+#define MOVI_32_M (((long) -1 << 30) * 2 - 4)
+#define MOVI_48_F ((((long) 1 << 47) - 1) - 4)
+#define MOVI_48_M (((long) -1 << 47) - 4)
+#else
+/* If the host does not have 64-bit longs, just make this state identical
+ in reach to the 32-bit state. Note that we have a slightly incorrect
+ reach, but the correct one above will overflow a 32-bit number. */
+#define MOVI_32_M (((long) -1 << 30) * 2)
+#define MOVI_48_F MOVI_32_F
+#define MOVI_48_M MOVI_32_M
+#endif /* BFD_HOST_64BIT_LONG */
+
+#define MOVI_64_LENGTH 12
+#endif /* HAVE_SH64 */
+
+#define EMPTY { 0, 0, 0, 0 }
+
+const relax_typeS md_relax_table[C (END, 0)] = {
+ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+
+ EMPTY,
+ /* C (COND_JUMP, COND8) */
+ { COND8_F, COND8_M, COND8_LENGTH, C (COND_JUMP, COND12) },
+ /* C (COND_JUMP, COND12) */
+ { COND12_F, COND12_M, COND12_LENGTH, C (COND_JUMP, COND32), },
+ /* C (COND_JUMP, COND32) */
+ { COND32_F, COND32_M, COND32_LENGTH, 0, },
+ /* C (COND_JUMP, UNDEF_WORD_DISP) */
+ { 0, 0, COND32_LENGTH, 0, },
+ EMPTY, EMPTY, EMPTY,
+ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+
+ EMPTY,
+ /* C (COND_JUMP_DELAY, COND8) */
+ { COND8_F, COND8_M, COND8_LENGTH, C (COND_JUMP_DELAY, COND12) },
+ /* C (COND_JUMP_DELAY, COND12) */
+ { COND12_F, COND12_M, COND12_DELAY_LENGTH, C (COND_JUMP_DELAY, COND32), },
+ /* C (COND_JUMP_DELAY, COND32) */
+ { COND32_F, COND32_M, COND32_LENGTH, 0, },
+ /* C (COND_JUMP_DELAY, UNDEF_WORD_DISP) */
+ { 0, 0, COND32_LENGTH, 0, },
+ EMPTY, EMPTY, EMPTY,
+ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+
+ EMPTY,
+ /* C (UNCOND_JUMP, UNCOND12) */
+ { UNCOND12_F, UNCOND12_M, UNCOND12_LENGTH, C (UNCOND_JUMP, UNCOND32), },
+ /* C (UNCOND_JUMP, UNCOND32) */
+ { UNCOND32_F, UNCOND32_M, UNCOND32_LENGTH, 0, },
+ EMPTY,
+ /* C (UNCOND_JUMP, UNDEF_WORD_DISP) */
+ { 0, 0, UNCOND32_LENGTH, 0, },
+ EMPTY, EMPTY, EMPTY,
+ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+
+#ifdef HAVE_SH64
+ /* C (SH64PCREL16_32, SH64PCREL16) */
+ EMPTY,
+ { SH64PCREL16_F, SH64PCREL16_M, SH64PCREL16_LENGTH, C (SH64PCREL16_32, SH64PCREL32) },
+ /* C (SH64PCREL16_32, SH64PCREL32) */
+ { 0, 0, SH64PCREL32_LENGTH, 0 },
+ EMPTY, EMPTY,
+ /* C (SH64PCREL16_32, SH64PCRELPLT) */
+ { 0, 0, SH64PCREL32_LENGTH, 0 },
+ EMPTY, EMPTY,
+ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+
+ /* C (SH64PCREL16_64, SH64PCREL16) */
+ EMPTY,
+ { SH64PCREL16_F, SH64PCREL16_M, SH64PCREL16_LENGTH, C (SH64PCREL16_64, SH64PCREL32) },
+ /* C (SH64PCREL16_64, SH64PCREL32) */
+ { SH64PCREL32_F, SH64PCREL32_M, SH64PCREL32_LENGTH, C (SH64PCREL16_64, SH64PCREL48) },
+ /* C (SH64PCREL16_64, SH64PCREL48) */
+ { SH64PCREL48_F, SH64PCREL48_M, SH64PCREL48_LENGTH, C (SH64PCREL16_64, SH64PCREL64) },
+ /* C (SH64PCREL16_64, SH64PCREL64) */
+ { 0, 0, SH64PCREL64_LENGTH, 0 },
+ /* C (SH64PCREL16_64, SH64PCRELPLT) */
+ { 0, 0, SH64PCREL64_LENGTH, 0 },
+ EMPTY, EMPTY,
+ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+
+ /* C (SH64PCREL16PT_32, SH64PCREL16) */
+ EMPTY,
+ { SH64PCREL16_F, SH64PCREL16_M, SH64PCREL16_LENGTH, C (SH64PCREL16PT_32, SH64PCREL32) },
+ /* C (SH64PCREL16PT_32, SH64PCREL32) */
+ { 0, 0, SH64PCREL32_LENGTH, 0 },
+ EMPTY, EMPTY,
+ /* C (SH64PCREL16PT_32, SH64PCRELPLT) */
+ { 0, 0, SH64PCREL32_LENGTH, 0 },
+ EMPTY, EMPTY,
+ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+
+ /* C (SH64PCREL16PT_64, SH64PCREL16) */
+ EMPTY,
+ { SH64PCREL16_F, SH64PCREL16_M, SH64PCREL16_LENGTH, C (SH64PCREL16PT_64, SH64PCREL32) },
+ /* C (SH64PCREL16PT_64, SH64PCREL32) */
+ { SH64PCREL32_F,
+ SH64PCREL32_M,
+ SH64PCREL32_LENGTH,
+ C (SH64PCREL16PT_64, SH64PCREL48) },
+ /* C (SH64PCREL16PT_64, SH64PCREL48) */
+ { SH64PCREL48_F, SH64PCREL48_M, SH64PCREL48_LENGTH, C (SH64PCREL16PT_64, SH64PCREL64) },
+ /* C (SH64PCREL16PT_64, SH64PCREL64) */
+ { 0, 0, SH64PCREL64_LENGTH, 0 },
+ /* C (SH64PCREL16PT_64, SH64PCRELPLT) */
+ { 0, 0, SH64PCREL64_LENGTH, 0},
+ EMPTY, EMPTY,
+ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+
+ /* C (MOVI_IMM_32, UNDEF_MOVI) */
+ { 0, 0, MOVI_32_LENGTH, 0 },
+ /* C (MOVI_IMM_32, MOVI_16) */
+ { MOVI_16_F, MOVI_16_M, MOVI_16_LENGTH, C (MOVI_IMM_32, MOVI_32) },
+ /* C (MOVI_IMM_32, MOVI_32) */
+ { MOVI_32_F, MOVI_32_M, MOVI_32_LENGTH, 0 },
+ EMPTY, EMPTY, EMPTY,
+ /* C (MOVI_IMM_32, MOVI_GOTOFF) */
+ { 0, 0, MOVI_32_LENGTH, 0 },
+ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+
+ /* C (MOVI_IMM_32_PCREL, MOVI_16) */
+ EMPTY,
+ { MOVI_16_F, MOVI_16_M, MOVI_16_LENGTH, C (MOVI_IMM_32_PCREL, MOVI_32) },
+ /* C (MOVI_IMM_32_PCREL, MOVI_32) */
+ { 0, 0, MOVI_32_LENGTH, 0 },
+ EMPTY, EMPTY,
+ /* C (MOVI_IMM_32_PCREL, MOVI_PLT) */
+ { 0, 0, MOVI_32_LENGTH, 0 },
+ EMPTY,
+ /* C (MOVI_IMM_32_PCREL, MOVI_GOTPC) */
+ { 0, 0, MOVI_32_LENGTH, 0 },
+ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+
+ /* C (MOVI_IMM_64, UNDEF_MOVI) */
+ { 0, 0, MOVI_64_LENGTH, 0 },
+ /* C (MOVI_IMM_64, MOVI_16) */
+ { MOVI_16_F, MOVI_16_M, MOVI_16_LENGTH, C (MOVI_IMM_64, MOVI_32) },
+ /* C (MOVI_IMM_64, MOVI_32) */
+ { MOVI_32_F, MOVI_32_M, MOVI_32_LENGTH, C (MOVI_IMM_64, MOVI_48) },
+ /* C (MOVI_IMM_64, MOVI_48) */
+ { MOVI_48_F, MOVI_48_M, MOVI_48_LENGTH, C (MOVI_IMM_64, MOVI_64) },
+ /* C (MOVI_IMM_64, MOVI_64) */
+ { 0, 0, MOVI_64_LENGTH, 0 },
+ EMPTY,
+ /* C (MOVI_IMM_64, MOVI_GOTOFF) */
+ { 0, 0, MOVI_64_LENGTH, 0 },
+ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+
+ /* C (MOVI_IMM_64_PCREL, MOVI_16) */
+ EMPTY,
+ { MOVI_16_F, MOVI_16_M, MOVI_16_LENGTH, C (MOVI_IMM_64_PCREL, MOVI_32) },
+ /* C (MOVI_IMM_64_PCREL, MOVI_32) */
+ { MOVI_32_F, MOVI_32_M, MOVI_32_LENGTH, C (MOVI_IMM_64_PCREL, MOVI_48) },
+ /* C (MOVI_IMM_64_PCREL, MOVI_48) */
+ { MOVI_48_F, MOVI_48_M, MOVI_48_LENGTH, C (MOVI_IMM_64_PCREL, MOVI_64) },
+ /* C (MOVI_IMM_64_PCREL, MOVI_64) */
+ { 0, 0, MOVI_64_LENGTH, 0 },
+ /* C (MOVI_IMM_64_PCREL, MOVI_PLT) */
+ { 0, 0, MOVI_64_LENGTH, 0 },
+ EMPTY,
+ /* C (MOVI_IMM_64_PCREL, MOVI_GOTPC) */
+ { 0, 0, MOVI_64_LENGTH, 0 },
+ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+
+#endif /* HAVE_SH64 */
+
+};
+
+#undef EMPTY
+
+static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
+
+
+#ifdef OBJ_ELF
+/* Determinet whether the symbol needs any kind of PIC relocation. */
+
+inline static int
+sh_PIC_related_p (sym)
+ symbolS *sym;
+{
+ expressionS *exp;
+
+ if (! sym)
+ return 0;
+
+ if (sym == GOT_symbol)
+ return 1;
+
+#ifdef HAVE_SH64
+ if (sh_PIC_related_p (*symbol_get_tc (sym)))
+ return 1;
+#endif
+
+ exp = symbol_get_value_expression (sym);
+
+ return (exp->X_op == O_PIC_reloc
+ || sh_PIC_related_p (exp->X_add_symbol)
+ || sh_PIC_related_p (exp->X_op_symbol));
+}
+
+/* Determine the relocation type to be used to represent the
+ expression, that may be rearranged. */
+
+static int
+sh_check_fixup (main_exp, r_type_p)
+ expressionS *main_exp;
+ bfd_reloc_code_real_type *r_type_p;
+{
+ expressionS *exp = main_exp;
+
+ /* This is here for backward-compatibility only. GCC used to generated:
+
+ f@PLT + . - (.LPCS# + 2)
+
+ but we'd rather be able to handle this as a PIC-related reference
+ plus/minus a symbol. However, gas' parser gives us:
+
+ O_subtract (O_add (f@PLT, .), .LPCS#+2)
+
+ so we attempt to transform this into:
+
+ O_subtract (f@PLT, O_subtract (.LPCS#+2, .))
+
+ which we can handle simply below. */
+ if (exp->X_op == O_subtract)
+ {
+ if (sh_PIC_related_p (exp->X_op_symbol))
+ return 1;
+
+ exp = symbol_get_value_expression (exp->X_add_symbol);
+
+ if (exp && sh_PIC_related_p (exp->X_op_symbol))
+ return 1;
+
+ if (exp && exp->X_op == O_add
+ && sh_PIC_related_p (exp->X_add_symbol))
+ {
+ symbolS *sym = exp->X_add_symbol;
+
+ exp->X_op = O_subtract;
+ exp->X_add_symbol = main_exp->X_op_symbol;
+
+ main_exp->X_op_symbol = main_exp->X_add_symbol;
+ main_exp->X_add_symbol = sym;
+
+ main_exp->X_add_number += exp->X_add_number;
+ exp->X_add_number = 0;
+ }
+
+ exp = main_exp;
+ }
+ else if (exp->X_op == O_add && sh_PIC_related_p (exp->X_op_symbol))
+ return 1;
+
+ if (exp->X_op == O_symbol || exp->X_op == O_add || exp->X_op == O_subtract)
+ {
+#ifdef HAVE_SH64
+ if (exp->X_add_symbol
+ && (exp->X_add_symbol == GOT_symbol
+ || (GOT_symbol
+ && *symbol_get_tc (exp->X_add_symbol) == GOT_symbol)))
+ {
+ switch (*r_type_p)
+ {
+ case BFD_RELOC_SH_IMM_LOW16:
+ *r_type_p = BFD_RELOC_SH_GOTPC_LOW16;
+ break;
+
+ case BFD_RELOC_SH_IMM_MEDLOW16:
+ *r_type_p = BFD_RELOC_SH_GOTPC_MEDLOW16;
+ break;
+
+ case BFD_RELOC_SH_IMM_MEDHI16:
+ *r_type_p = BFD_RELOC_SH_GOTPC_MEDHI16;
+ break;
+
+ case BFD_RELOC_SH_IMM_HI16:
+ *r_type_p = BFD_RELOC_SH_GOTPC_HI16;
+ break;
+
+ case BFD_RELOC_NONE:
+ case BFD_RELOC_UNUSED:
+ *r_type_p = BFD_RELOC_SH_GOTPC;
+ break;
+
+ default:
+ abort ();
+ }
+ return 0;
+ }
+#else
+ if (exp->X_add_symbol && exp->X_add_symbol == GOT_symbol)
+ {
+ *r_type_p = BFD_RELOC_SH_GOTPC;
+ return 0;
+ }
+#endif
+ exp = symbol_get_value_expression (exp->X_add_symbol);
+ if (! exp)
+ return 0;
+ }
+
+ if (exp->X_op == O_PIC_reloc)
+ {
+#ifdef HAVE_SH64
+ switch (*r_type_p)
+ {
+ case BFD_RELOC_NONE:
+ case BFD_RELOC_UNUSED:
+ *r_type_p = exp->X_md;
+ break;
+
+ case BFD_RELOC_SH_IMM_LOW16:
+ switch (exp->X_md)
+ {
+ case BFD_RELOC_32_GOTOFF:
+ *r_type_p = BFD_RELOC_SH_GOTOFF_LOW16;
+ break;
+
+ case BFD_RELOC_SH_GOTPLT32:
+ *r_type_p = BFD_RELOC_SH_GOTPLT_LOW16;
+ break;
+
+ case BFD_RELOC_32_GOT_PCREL:
+ *r_type_p = BFD_RELOC_SH_GOT_LOW16;
+ break;
+
+ case BFD_RELOC_32_PLT_PCREL:
+ *r_type_p = BFD_RELOC_SH_PLT_LOW16;
+ break;
+
+ default:
+ abort ();
+ }
+ break;
+
+ case BFD_RELOC_SH_IMM_MEDLOW16:
+ switch (exp->X_md)
+ {
+ case BFD_RELOC_32_GOTOFF:
+ *r_type_p = BFD_RELOC_SH_GOTOFF_MEDLOW16;
+ break;
+
+ case BFD_RELOC_SH_GOTPLT32:
+ *r_type_p = BFD_RELOC_SH_GOTPLT_MEDLOW16;
+ break;
+
+ case BFD_RELOC_32_GOT_PCREL:
+ *r_type_p = BFD_RELOC_SH_GOT_MEDLOW16;
+ break;
+
+ case BFD_RELOC_32_PLT_PCREL:
+ *r_type_p = BFD_RELOC_SH_PLT_MEDLOW16;
+ break;
+
+ default:
+ abort ();
+ }
+ break;
+
+ case BFD_RELOC_SH_IMM_MEDHI16:
+ switch (exp->X_md)
+ {
+ case BFD_RELOC_32_GOTOFF:
+ *r_type_p = BFD_RELOC_SH_GOTOFF_MEDHI16;
+ break;
+
+ case BFD_RELOC_SH_GOTPLT32:
+ *r_type_p = BFD_RELOC_SH_GOTPLT_MEDHI16;
+ break;
+
+ case BFD_RELOC_32_GOT_PCREL:
+ *r_type_p = BFD_RELOC_SH_GOT_MEDHI16;
+ break;
+
+ case BFD_RELOC_32_PLT_PCREL:
+ *r_type_p = BFD_RELOC_SH_PLT_MEDHI16;
+ break;
+
+ default:
+ abort ();
+ }
+ break;
+
+ case BFD_RELOC_SH_IMM_HI16:
+ switch (exp->X_md)
+ {
+ case BFD_RELOC_32_GOTOFF:
+ *r_type_p = BFD_RELOC_SH_GOTOFF_HI16;
+ break;
+
+ case BFD_RELOC_SH_GOTPLT32:
+ *r_type_p = BFD_RELOC_SH_GOTPLT_HI16;
+ break;
+
+ case BFD_RELOC_32_GOT_PCREL:
+ *r_type_p = BFD_RELOC_SH_GOT_HI16;
+ break;
+
+ case BFD_RELOC_32_PLT_PCREL:
+ *r_type_p = BFD_RELOC_SH_PLT_HI16;
+ break;
+
+ default:
+ abort ();
+ }
+ break;
+
+ default:
+ abort ();
+ }
+#else
+ *r_type_p = exp->X_md;
+#endif
+ if (exp == main_exp)
+ exp->X_op = O_symbol;
+ else
+ {
+ main_exp->X_add_symbol = exp->X_add_symbol;
+ main_exp->X_add_number += exp->X_add_number;
+ }
+ }
+ else
+ return (sh_PIC_related_p (exp->X_add_symbol)
+ || sh_PIC_related_p (exp->X_op_symbol));
+
+ return 0;
+}
+
+/* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
+
+void
+sh_cons_fix_new (frag, off, size, exp)
+ fragS *frag;
+ int off, size;
+ expressionS *exp;
+{
+ bfd_reloc_code_real_type r_type = BFD_RELOC_UNUSED;
+
+ if (sh_check_fixup (exp, &r_type))
+ as_bad (_("Invalid PIC expression."));
+
+ if (r_type == BFD_RELOC_UNUSED)
+ switch (size)
+ {
+ case 1:
+ r_type = BFD_RELOC_8;
+ break;
+
+ case 2:
+ r_type = BFD_RELOC_16;
+ break;
+
+ case 4:
+ r_type = BFD_RELOC_32;
+ break;
+
+#ifdef HAVE_SH64
+ case 8:
+ r_type = BFD_RELOC_64;
+ break;
+#endif
+
+ default:
+ goto error;
+ }
+ else if (size != 4)
+ {
+ error:
+ as_bad (_("unsupported BFD relocation size %u"), size);
+ r_type = BFD_RELOC_UNUSED;
+ }
+
+ fix_new_exp (frag, off, size, exp, 0, r_type);
+}
+
+/* The regular cons() function, that reads constants, doesn't support
+ suffixes such as @GOT, @GOTOFF and @PLT, that generate
+ machine-specific relocation types. So we must define it here. */
+/* Clobbers input_line_pointer, checks end-of-line. */
+static void
+sh_elf_cons (nbytes)
+ register int nbytes; /* 1=.byte, 2=.word, 4=.long */
+{
+ expressionS exp;
+
+#ifdef HAVE_SH64
+
+ /* Update existing range to include a previous insn, if there was one. */
+ sh64_update_contents_mark (true);
+
+ /* We need to make sure the contents type is set to data. */
+ sh64_flag_output ();
+
+#endif /* HAVE_SH64 */
+
+ if (is_it_end_of_statement ())
+ {
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ do
+ {
+ expression (&exp);
+ emit_expr (&exp, (unsigned int) nbytes);
+ }
+ while (*input_line_pointer++ == ',');
+
+ input_line_pointer--; /* Put terminator back into stream. */
+ if (*input_line_pointer == '#' || *input_line_pointer == '!')
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer++]);
+ }
+ else
+ demand_empty_rest_of_line ();
+}
+#endif /* OBJ_ELF */
+
+
+/* This function is called once, at assembler startup time. This should
+ set up all the tables, etc that the MD part of the assembler needs. */
+
+void
+md_begin ()
+{
+ sh_opcode_info *opcode;
+ char *prev_name = "";
+ int target_arch;
+
+ target_arch = arch_sh1_up & ~(sh_dsp ? arch_sh3e_up : arch_sh_dsp_up);
+ valid_arch = target_arch;
+
+#ifdef HAVE_SH64
+ shmedia_md_begin ();
+#endif
+
+ opcode_hash_control = hash_new ();
+
+ /* Insert unique names into hash table. */
+ for (opcode = sh_table; opcode->name; opcode++)
+ {
+ if (strcmp (prev_name, opcode->name))
+ {
+ if (! (opcode->arch & target_arch))
+ continue;
+ prev_name = opcode->name;
+ hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
+ }
+ else
+ {
+ /* Make all the opcodes with the same name point to the same
+ string. */
+ opcode->name = prev_name;
+ }
+ }
+}
+
+static int reg_m;
+static int reg_n;
+static int reg_x, reg_y;
+static int reg_efg;
+static int reg_b;
+
+#define IDENT_CHAR(c) (ISALNUM (c) || (c) == '_')
+
+/* Try to parse a reg name. Return the number of chars consumed. */
+
+static int
+parse_reg (src, mode, reg)
+ char *src;
+ int *mode;
+ int *reg;
+{
+ char l0 = TOLOWER (src[0]);
+ char l1 = l0 ? TOLOWER (src[1]) : 0;
+
+ /* We use ! IDENT_CHAR for the next character after the register name, to
+ make sure that we won't accidentally recognize a symbol name such as
+ 'sram' or sr_ram as being a reference to the register 'sr'. */
+
+ if (l0 == 'r')
+ {
+ if (l1 == '1')
+ {
+ if (src[2] >= '0' && src[2] <= '5'
+ && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = A_REG_N;
+ *reg = 10 + src[2] - '0';
+ return 3;
+ }
+ }
+ if (l1 >= '0' && l1 <= '9'
+ && ! IDENT_CHAR ((unsigned char) src[2]))
+ {
+ *mode = A_REG_N;
+ *reg = (l1 - '0');
+ return 2;
+ }
+ if (l1 >= '0' && l1 <= '7' && strncasecmp (&src[2], "_bank", 5) == 0
+ && ! IDENT_CHAR ((unsigned char) src[7]))
+ {
+ *mode = A_REG_B;
+ *reg = (l1 - '0');
+ return 7;
+ }
+
+ if (l1 == 'e' && ! IDENT_CHAR ((unsigned char) src[2]))
+ {
+ *mode = A_RE;
+ return 2;
+ }
+ if (l1 == 's' && ! IDENT_CHAR ((unsigned char) src[2]))
+ {
+ *mode = A_RS;
+ return 2;
+ }
+ }
+
+ if (l0 == 'a')
+ {
+ if (l1 == '0')
+ {
+ if (! IDENT_CHAR ((unsigned char) src[2]))
+ {
+ *mode = DSP_REG_N;
+ *reg = A_A0_NUM;
+ return 2;
+ }
+ if (TOLOWER (src[2]) == 'g' && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = DSP_REG_N;
+ *reg = A_A0G_NUM;
+ return 3;
+ }
+ }
+ if (l1 == '1')
+ {
+ if (! IDENT_CHAR ((unsigned char) src[2]))
+ {
+ *mode = DSP_REG_N;
+ *reg = A_A1_NUM;
+ return 2;
+ }
+ if (TOLOWER (src[2]) == 'g' && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = DSP_REG_N;
+ *reg = A_A1G_NUM;
+ return 3;
+ }
+ }
+
+ if (l1 == 'x' && src[2] >= '0' && src[2] <= '1'
+ && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = A_REG_N;
+ *reg = 4 + (l1 - '0');
+ return 3;
+ }
+ if (l1 == 'y' && src[2] >= '0' && src[2] <= '1'
+ && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = A_REG_N;
+ *reg = 6 + (l1 - '0');
+ return 3;
+ }
+ if (l1 == 's' && src[2] >= '0' && src[2] <= '3'
+ && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ int n = l1 - '0';
+
+ *mode = A_REG_N;
+ *reg = n | ((~n & 2) << 1);
+ return 3;
+ }
+ }
+
+ if (l0 == 'i' && l1 && ! IDENT_CHAR ((unsigned char) src[2]))
+ {
+ if (l1 == 's')
+ {
+ *mode = A_REG_N;
+ *reg = 8;
+ return 2;
+ }
+ if (l1 == 'x')
+ {
+ *mode = A_REG_N;
+ *reg = 8;
+ return 2;
+ }
+ if (l1 == 'y')
+ {
+ *mode = A_REG_N;
+ *reg = 9;
+ return 2;
+ }
+ }
+
+ if (l0 == 'x' && l1 >= '0' && l1 <= '1'
+ && ! IDENT_CHAR ((unsigned char) src[2]))
+ {
+ *mode = DSP_REG_N;
+ *reg = A_X0_NUM + l1 - '0';
+ return 2;
+ }
+
+ if (l0 == 'y' && l1 >= '0' && l1 <= '1'
+ && ! IDENT_CHAR ((unsigned char) src[2]))
+ {
+ *mode = DSP_REG_N;
+ *reg = A_Y0_NUM + l1 - '0';
+ return 2;
+ }
+
+ if (l0 == 'm' && l1 >= '0' && l1 <= '1'
+ && ! IDENT_CHAR ((unsigned char) src[2]))
+ {
+ *mode = DSP_REG_N;
+ *reg = l1 == '0' ? A_M0_NUM : A_M1_NUM;
+ return 2;
+ }
+
+ if (l0 == 's'
+ && l1 == 's'
+ && TOLOWER (src[2]) == 'r' && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = A_SSR;
+ return 3;
+ }
+
+ if (l0 == 's' && l1 == 'p' && TOLOWER (src[2]) == 'c'
+ && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = A_SPC;
+ return 3;
+ }
+
+ if (l0 == 's' && l1 == 'g' && TOLOWER (src[2]) == 'r'
+ && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = A_SGR;
+ return 3;
+ }
+
+ if (l0 == 'd' && l1 == 's' && TOLOWER (src[2]) == 'r'
+ && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = A_DSR;
+ return 3;
+ }
+
+ if (l0 == 'd' && l1 == 'b' && TOLOWER (src[2]) == 'r'
+ && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = A_DBR;
+ return 3;
+ }
+
+ if (l0 == 's' && l1 == 'r' && ! IDENT_CHAR ((unsigned char) src[2]))
+ {
+ *mode = A_SR;
+ return 2;
+ }
+
+ if (l0 == 's' && l1 == 'p' && ! IDENT_CHAR ((unsigned char) src[2]))
+ {
+ *mode = A_REG_N;
+ *reg = 15;
+ return 2;
+ }
+
+ if (l0 == 'p' && l1 == 'r' && ! IDENT_CHAR ((unsigned char) src[2]))
+ {
+ *mode = A_PR;
+ return 2;
+ }
+ if (l0 == 'p' && l1 == 'c' && ! IDENT_CHAR ((unsigned char) src[2]))
+ {
+ /* Don't use A_DISP_PC here - that would accept stuff like 'mova pc,r0'
+ and use an uninitialized immediate. */
+ *mode = A_PC;
+ return 2;
+ }
+ if (l0 == 'g' && l1 == 'b' && TOLOWER (src[2]) == 'r'
+ && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = A_GBR;
+ return 3;
+ }
+ if (l0 == 'v' && l1 == 'b' && TOLOWER (src[2]) == 'r'
+ && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = A_VBR;
+ return 3;
+ }
+
+ if (l0 == 'm' && l1 == 'a' && TOLOWER (src[2]) == 'c'
+ && ! IDENT_CHAR ((unsigned char) src[4]))
+ {
+ if (TOLOWER (src[3]) == 'l')
+ {
+ *mode = A_MACL;
+ return 4;
+ }
+ if (TOLOWER (src[3]) == 'h')
+ {
+ *mode = A_MACH;
+ return 4;
+ }
+ }
+ if (l0 == 'm' && l1 == 'o' && TOLOWER (src[2]) == 'd'
+ && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = A_MOD;
+ return 3;
+ }
+ if (l0 == 'f' && l1 == 'r')
+ {
+ if (src[2] == '1')
+ {
+ if (src[3] >= '0' && src[3] <= '5'
+ && ! IDENT_CHAR ((unsigned char) src[4]))
+ {
+ *mode = F_REG_N;
+ *reg = 10 + src[3] - '0';
+ return 4;
+ }
+ }
+ if (src[2] >= '0' && src[2] <= '9'
+ && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = F_REG_N;
+ *reg = (src[2] - '0');
+ return 3;
+ }
+ }
+ if (l0 == 'd' && l1 == 'r')
+ {
+ if (src[2] == '1')
+ {
+ if (src[3] >= '0' && src[3] <= '4' && ! ((src[3] - '0') & 1)
+ && ! IDENT_CHAR ((unsigned char) src[4]))
+ {
+ *mode = D_REG_N;
+ *reg = 10 + src[3] - '0';
+ return 4;
+ }
+ }
+ if (src[2] >= '0' && src[2] <= '8' && ! ((src[2] - '0') & 1)
+ && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = D_REG_N;
+ *reg = (src[2] - '0');
+ return 3;
+ }
+ }
+ if (l0 == 'x' && l1 == 'd')
+ {
+ if (src[2] == '1')
+ {
+ if (src[3] >= '0' && src[3] <= '4' && ! ((src[3] - '0') & 1)
+ && ! IDENT_CHAR ((unsigned char) src[4]))
+ {
+ *mode = X_REG_N;
+ *reg = 11 + src[3] - '0';
+ return 4;
+ }
+ }
+ if (src[2] >= '0' && src[2] <= '8' && ! ((src[2] - '0') & 1)
+ && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = X_REG_N;
+ *reg = (src[2] - '0') + 1;
+ return 3;
+ }
+ }
+ if (l0 == 'f' && l1 == 'v')
+ {
+ if (src[2] == '1'&& src[3] == '2' && ! IDENT_CHAR ((unsigned char) src[4]))
+ {
+ *mode = V_REG_N;
+ *reg = 12;
+ return 4;
+ }
+ if ((src[2] == '0' || src[2] == '4' || src[2] == '8')
+ && ! IDENT_CHAR ((unsigned char) src[3]))
+ {
+ *mode = V_REG_N;
+ *reg = (src[2] - '0');
+ return 3;
+ }
+ }
+ if (l0 == 'f' && l1 == 'p' && TOLOWER (src[2]) == 'u'
+ && TOLOWER (src[3]) == 'l'
+ && ! IDENT_CHAR ((unsigned char) src[4]))
+ {
+ *mode = FPUL_N;
+ return 4;
+ }
+
+ if (l0 == 'f' && l1 == 'p' && TOLOWER (src[2]) == 's'
+ && TOLOWER (src[3]) == 'c'
+ && TOLOWER (src[4]) == 'r' && ! IDENT_CHAR ((unsigned char) src[5]))
+ {
+ *mode = FPSCR_N;
+ return 5;
+ }
+
+ if (l0 == 'x' && l1 == 'm' && TOLOWER (src[2]) == 't'
+ && TOLOWER (src[3]) == 'r'
+ && TOLOWER (src[4]) == 'x' && ! IDENT_CHAR ((unsigned char) src[5]))
+ {
+ *mode = XMTRX_M4;
+ return 5;
+ }
+
+ return 0;
+}
+
+static char *
+parse_exp (s, op)
+ char *s;
+ sh_operand_info *op;
+{
+ char *save;
+ char *new;
+
+ save = input_line_pointer;
+ input_line_pointer = s;
+ expression (&op->immediate);
+ if (op->immediate.X_op == O_absent)
+ as_bad (_("missing operand"));
+#ifdef OBJ_ELF
+ else if (op->immediate.X_op == O_PIC_reloc
+ || sh_PIC_related_p (op->immediate.X_add_symbol)
+ || sh_PIC_related_p (op->immediate.X_op_symbol))
+ as_bad (_("misplaced PIC operand"));
+#endif
+ new = input_line_pointer;
+ input_line_pointer = save;
+ return new;
+}
+
+/* The many forms of operand:
+
+ Rn Register direct
+ @Rn Register indirect
+ @Rn+ Autoincrement
+ @-Rn Autodecrement
+ @(disp:4,Rn)
+ @(disp:8,GBR)
+ @(disp:8,PC)
+
+ @(R0,Rn)
+ @(R0,GBR)
+
+ disp:8
+ disp:12
+ #imm8
+ pr, gbr, vbr, macl, mach
+ */
+
+static char *
+parse_at (src, op)
+ char *src;
+ sh_operand_info *op;
+{
+ int len;
+ int mode;
+ src++;
+ if (src[0] == '-')
+ {
+ /* Must be predecrement. */
+ src++;
+
+ len = parse_reg (src, &mode, &(op->reg));
+ if (mode != A_REG_N)
+ as_bad (_("illegal register after @-"));
+
+ op->type = A_DEC_N;
+ src += len;
+ }
+ else if (src[0] == '(')
+ {
+ /* Could be @(disp, rn), @(disp, gbr), @(disp, pc), @(r0, gbr) or
+ @(r0, rn). */
+ src++;
+ len = parse_reg (src, &mode, &(op->reg));
+ if (len && mode == A_REG_N)
+ {
+ src += len;
+ if (op->reg != 0)
+ {
+ as_bad (_("must be @(r0,...)"));
+ }
+ if (src[0] == ',')
+ {
+ src++;
+ /* Now can be rn or gbr. */
+ len = parse_reg (src, &mode, &(op->reg));
+ }
+ else
+ {
+ len = 0;
+ }
+ if (len)
+ {
+ if (mode == A_GBR)
+ {
+ op->type = A_R0_GBR;
+ }
+ else if (mode == A_REG_N)
+ {
+ op->type = A_IND_R0_REG_N;
+ }
+ else
+ {
+ as_bad (_("syntax error in @(r0,...)"));
+ }
+ }
+ else
+ {
+ as_bad (_("syntax error in @(r0...)"));
+ }
+ }
+ else
+ {
+ /* Must be an @(disp,.. thing). */
+ src = parse_exp (src, op);
+ if (src[0] == ',')
+ src++;
+ /* Now can be rn, gbr or pc. */
+ len = parse_reg (src, &mode, &op->reg);
+ if (len)
+ {
+ if (mode == A_REG_N)
+ {
+ op->type = A_DISP_REG_N;
+ }
+ else if (mode == A_GBR)
+ {
+ op->type = A_DISP_GBR;
+ }
+ else if (mode == A_PC)
+ {
+ /* We want @(expr, pc) to uniformly address . + expr,
+ no matter if expr is a constant, or a more complex
+ expression, e.g. sym-. or sym1-sym2.
+ However, we also used to accept @(sym,pc)
+ as adressing sym, i.e. meaning the same as plain sym.
+ Some existing code does use the @(sym,pc) syntax, so
+ we give it the old semantics for now, but warn about
+ its use, so that users have some time to fix their code.
+
+ Note that due to this backward compatibility hack,
+ we'll get unexpected results when @(offset, pc) is used,
+ and offset is a symbol that is set later to an an address
+ difference, or an external symbol that is set to an
+ address difference in another source file, so we want to
+ eventually remove it. */
+ if (op->immediate.X_op == O_symbol)
+ {
+ op->type = A_DISP_PC;
+ as_warn (_("Deprecated syntax."));
+ }
+ else
+ {
+ op->type = A_DISP_PC_ABS;
+ /* Such operands don't get corrected for PC==.+4, so
+ make the correction here. */
+ op->immediate.X_add_number -= 4;
+ }
+ }
+ else
+ {
+ as_bad (_("syntax error in @(disp,[Rn, gbr, pc])"));
+ }
+ }
+ else
+ {
+ as_bad (_("syntax error in @(disp,[Rn, gbr, pc])"));
+ }
+ }
+ src += len;
+ if (src[0] != ')')
+ as_bad (_("expecting )"));
+ else
+ src++;
+ }
+ else
+ {
+ src += parse_reg (src, &mode, &(op->reg));
+ if (mode != A_REG_N)
+ as_bad (_("illegal register after @"));
+
+ if (src[0] == '+')
+ {
+ char l0, l1;
+
+ src++;
+ l0 = TOLOWER (src[0]);
+ l1 = TOLOWER (src[1]);
+
+ if ((l0 == 'r' && l1 == '8')
+ || (l0 == 'i' && (l1 == 'x' || l1 == 's')))
+ {
+ src += 2;
+ op->type = A_PMOD_N;
+ }
+ else if ( (l0 == 'r' && l1 == '9')
+ || (l0 == 'i' && l1 == 'y'))
+ {
+ src += 2;
+ op->type = A_PMODY_N;
+ }
+ else
+ op->type = A_INC_N;
+ }
+ else
+ op->type = A_IND_N;
+ }
+ return src;
+}
+
+static void
+get_operand (ptr, op)
+ char **ptr;
+ sh_operand_info *op;
+{
+ char *src = *ptr;
+ int mode = -1;
+ unsigned int len;
+
+ if (src[0] == '#')
+ {
+ src++;
+ *ptr = parse_exp (src, op);
+ op->type = A_IMM;
+ return;
+ }
+
+ else if (src[0] == '@')
+ {
+ *ptr = parse_at (src, op);
+ return;
+ }
+ len = parse_reg (src, &mode, &(op->reg));
+ if (len)
+ {
+ *ptr = src + len;
+ op->type = mode;
+ return;
+ }
+ else
+ {
+ /* Not a reg, the only thing left is a displacement. */
+ *ptr = parse_exp (src, op);
+ op->type = A_DISP_PC;
+ return;
+ }
+}
+
+static char *
+get_operands (info, args, operand)
+ sh_opcode_info *info;
+ char *args;
+ sh_operand_info *operand;
+{
+ char *ptr = args;
+ if (info->arg[0])
+ {
+ /* The pre-processor will eliminate whitespace in front of '@'
+ after the first argument; we may be called multiple times
+ from assemble_ppi, so don't insist on finding whitespace here. */
+ if (*ptr == ' ')
+ ptr++;
+
+ get_operand (&ptr, operand + 0);
+ if (info->arg[1])
+ {
+ if (*ptr == ',')
+ {
+ ptr++;
+ }
+ get_operand (&ptr, operand + 1);
+ /* ??? Hack: psha/pshl have a varying operand number depending on
+ the type of the first operand. We handle this by having the
+ three-operand version first and reducing the number of operands
+ parsed to two if we see that the first operand is an immediate.
+ This works because no insn with three operands has an immediate
+ as first operand. */
+ if (info->arg[2] && operand[0].type != A_IMM)
+ {
+ if (*ptr == ',')
+ {
+ ptr++;
+ }
+ get_operand (&ptr, operand + 2);
+ }
+ else
+ {
+ operand[2].type = 0;
+ }
+ }
+ else
+ {
+ operand[1].type = 0;
+ operand[2].type = 0;
+ }
+ }
+ else
+ {
+ operand[0].type = 0;
+ operand[1].type = 0;
+ operand[2].type = 0;
+ }
+ return ptr;
+}
+
+/* Passed a pointer to a list of opcodes which use different
+ addressing modes, return the opcode which matches the opcodes
+ provided. */
+
+static sh_opcode_info *
+get_specific (opcode, operands)
+ sh_opcode_info *opcode;
+ sh_operand_info *operands;
+{
+ sh_opcode_info *this_try = opcode;
+ char *name = opcode->name;
+ int n = 0;
+
+ while (opcode->name)
+ {
+ this_try = opcode++;
+ if (this_try->name != name)
+ {
+ /* We've looked so far down the table that we've run out of
+ opcodes with the same name. */
+ return 0;
+ }
+
+ /* Look at both operands needed by the opcodes and provided by
+ the user - since an arg test will often fail on the same arg
+ again and again, we'll try and test the last failing arg the
+ first on each opcode try. */
+ for (n = 0; this_try->arg[n]; n++)
+ {
+ sh_operand_info *user = operands + n;
+ sh_arg_type arg = this_try->arg[n];
+
+ switch (arg)
+ {
+ case A_DISP_PC:
+ if (user->type == A_DISP_PC_ABS)
+ break;
+ /* Fall through. */
+ case A_IMM:
+ case A_BDISP12:
+ case A_BDISP8:
+ case A_DISP_GBR:
+ case A_MACH:
+ case A_PR:
+ case A_MACL:
+ if (user->type != arg)
+ goto fail;
+ break;
+ case A_R0:
+ /* opcode needs r0 */
+ if (user->type != A_REG_N || user->reg != 0)
+ goto fail;
+ break;
+ case A_R0_GBR:
+ if (user->type != A_R0_GBR || user->reg != 0)
+ goto fail;
+ break;
+ case F_FR0:
+ if (user->type != F_REG_N || user->reg != 0)
+ goto fail;
+ break;
+
+ case A_REG_N:
+ case A_INC_N:
+ case A_DEC_N:
+ case A_IND_N:
+ case A_IND_R0_REG_N:
+ case A_DISP_REG_N:
+ case F_REG_N:
+ case D_REG_N:
+ case X_REG_N:
+ case V_REG_N:
+ case FPUL_N:
+ case FPSCR_N:
+ case A_PMOD_N:
+ case A_PMODY_N:
+ case DSP_REG_N:
+ /* Opcode needs rn */
+ if (user->type != arg)
+ goto fail;
+ reg_n = user->reg;
+ break;
+ case DX_REG_N:
+ if (user->type != D_REG_N && user->type != X_REG_N)
+ goto fail;
+ reg_n = user->reg;
+ break;
+ case A_GBR:
+ case A_SR:
+ case A_VBR:
+ case A_DSR:
+ case A_MOD:
+ case A_RE:
+ case A_RS:
+ case A_SSR:
+ case A_SPC:
+ case A_SGR:
+ case A_DBR:
+ if (user->type != arg)
+ goto fail;
+ break;
+
+ case A_REG_B:
+ if (user->type != arg)
+ goto fail;
+ reg_b = user->reg;
+ break;
+
+ case A_REG_M:
+ case A_INC_M:
+ case A_DEC_M:
+ case A_IND_M:
+ case A_IND_R0_REG_M:
+ case A_DISP_REG_M:
+ case DSP_REG_M:
+ /* Opcode needs rn */
+ if (user->type != arg - A_REG_M + A_REG_N)
+ goto fail;
+ reg_m = user->reg;
+ break;
+
+ case DSP_REG_X:
+ if (user->type != DSP_REG_N)
+ goto fail;
+ switch (user->reg)
+ {
+ case A_X0_NUM:
+ reg_x = 0;
+ break;
+ case A_X1_NUM:
+ reg_x = 1;
+ break;
+ case A_A0_NUM:
+ reg_x = 2;
+ break;
+ case A_A1_NUM:
+ reg_x = 3;
+ break;
+ default:
+ goto fail;
+ }
+ break;
+
+ case DSP_REG_Y:
+ if (user->type != DSP_REG_N)
+ goto fail;
+ switch (user->reg)
+ {
+ case A_Y0_NUM:
+ reg_y = 0;
+ break;
+ case A_Y1_NUM:
+ reg_y = 1;
+ break;
+ case A_M0_NUM:
+ reg_y = 2;
+ break;
+ case A_M1_NUM:
+ reg_y = 3;
+ break;
+ default:
+ goto fail;
+ }
+ break;
+
+ case DSP_REG_E:
+ if (user->type != DSP_REG_N)
+ goto fail;
+ switch (user->reg)
+ {
+ case A_X0_NUM:
+ reg_efg = 0 << 10;
+ break;
+ case A_X1_NUM:
+ reg_efg = 1 << 10;
+ break;
+ case A_Y0_NUM:
+ reg_efg = 2 << 10;
+ break;
+ case A_A1_NUM:
+ reg_efg = 3 << 10;
+ break;
+ default:
+ goto fail;
+ }
+ break;
+
+ case DSP_REG_F:
+ if (user->type != DSP_REG_N)
+ goto fail;
+ switch (user->reg)
+ {
+ case A_Y0_NUM:
+ reg_efg |= 0 << 8;
+ break;
+ case A_Y1_NUM:
+ reg_efg |= 1 << 8;
+ break;
+ case A_X0_NUM:
+ reg_efg |= 2 << 8;
+ break;
+ case A_A1_NUM:
+ reg_efg |= 3 << 8;
+ break;
+ default:
+ goto fail;
+ }
+ break;
+
+ case DSP_REG_G:
+ if (user->type != DSP_REG_N)
+ goto fail;
+ switch (user->reg)
+ {
+ case A_M0_NUM:
+ reg_efg |= 0 << 2;
+ break;
+ case A_M1_NUM:
+ reg_efg |= 1 << 2;
+ break;
+ case A_A0_NUM:
+ reg_efg |= 2 << 2;
+ break;
+ case A_A1_NUM:
+ reg_efg |= 3 << 2;
+ break;
+ default:
+ goto fail;
+ }
+ break;
+
+ case A_A0:
+ if (user->type != DSP_REG_N || user->reg != A_A0_NUM)
+ goto fail;
+ break;
+ case A_X0:
+ if (user->type != DSP_REG_N || user->reg != A_X0_NUM)
+ goto fail;
+ break;
+ case A_X1:
+ if (user->type != DSP_REG_N || user->reg != A_X1_NUM)
+ goto fail;
+ break;
+ case A_Y0:
+ if (user->type != DSP_REG_N || user->reg != A_Y0_NUM)
+ goto fail;
+ break;
+ case A_Y1:
+ if (user->type != DSP_REG_N || user->reg != A_Y1_NUM)
+ goto fail;
+ break;
+
+ case F_REG_M:
+ case D_REG_M:
+ case X_REG_M:
+ case V_REG_M:
+ case FPUL_M:
+ case FPSCR_M:
+ /* Opcode needs rn */
+ if (user->type != arg - F_REG_M + F_REG_N)
+ goto fail;
+ reg_m = user->reg;
+ break;
+ case DX_REG_M:
+ if (user->type != D_REG_N && user->type != X_REG_N)
+ goto fail;
+ reg_m = user->reg;
+ break;
+ case XMTRX_M4:
+ if (user->type != XMTRX_M4)
+ goto fail;
+ reg_m = 4;
+ break;
+
+ default:
+ printf (_("unhandled %d\n"), arg);
+ goto fail;
+ }
+ }
+ if ( !(valid_arch & this_try->arch))
+ goto fail;
+ valid_arch &= this_try->arch;
+ return this_try;
+ fail:
+ ;
+ }
+
+ return 0;
+}
+
+static void
+insert (where, how, pcrel, op)
+ char *where;
+ int how;
+ int pcrel;
+ sh_operand_info *op;
+{
+ fix_new_exp (frag_now,
+ where - frag_now->fr_literal,
+ 2,
+ &op->immediate,
+ pcrel,
+ how);
+}
+
+static void
+build_relax (opcode, op)
+ sh_opcode_info *opcode;
+ sh_operand_info *op;
+{
+ int high_byte = target_big_endian ? 0 : 1;
+ char *p;
+
+ if (opcode->arg[0] == A_BDISP8)
+ {
+ int what = (opcode->nibbles[1] & 4) ? COND_JUMP_DELAY : COND_JUMP;
+ p = frag_var (rs_machine_dependent,
+ md_relax_table[C (what, COND32)].rlx_length,
+ md_relax_table[C (what, COND8)].rlx_length,
+ C (what, 0),
+ op->immediate.X_add_symbol,
+ op->immediate.X_add_number,
+ 0);
+ p[high_byte] = (opcode->nibbles[0] << 4) | (opcode->nibbles[1]);
+ }
+ else if (opcode->arg[0] == A_BDISP12)
+ {
+ p = frag_var (rs_machine_dependent,
+ md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_length,
+ md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_length,
+ C (UNCOND_JUMP, 0),
+ op->immediate.X_add_symbol,
+ op->immediate.X_add_number,
+ 0);
+ p[high_byte] = (opcode->nibbles[0] << 4);
+ }
+
+}
+
+/* Insert ldrs & ldre with fancy relocations that relaxation can recognize. */
+
+static char *
+insert_loop_bounds (output, operand)
+ char *output;
+ sh_operand_info *operand;
+{
+ char *name;
+ symbolS *end_sym;
+
+ /* Since the low byte of the opcode will be overwritten by the reloc, we
+ can just stash the high byte into both bytes and ignore endianness. */
+ output[0] = 0x8c;
+ output[1] = 0x8c;
+ insert (output, BFD_RELOC_SH_LOOP_START, 1, operand);
+ insert (output, BFD_RELOC_SH_LOOP_END, 1, operand + 1);
+
+ if (sh_relax)
+ {
+ static int count = 0;
+
+ /* If the last loop insn is a two-byte-insn, it is in danger of being
+ swapped with the insn after it. To prevent this, create a new
+ symbol - complete with SH_LABEL reloc - after the last loop insn.
+ If the last loop insn is four bytes long, the symbol will be
+ right in the middle, but four byte insns are not swapped anyways. */
+ /* A REPEAT takes 6 bytes. The SH has a 32 bit address space.
+ Hence a 9 digit number should be enough to count all REPEATs. */
+ name = alloca (11);
+ sprintf (name, "_R%x", count++ & 0x3fffffff);
+ end_sym = symbol_new (name, undefined_section, 0, &zero_address_frag);
+ /* Make this a local symbol. */
+#ifdef OBJ_COFF
+ SF_SET_LOCAL (end_sym);
+#endif /* OBJ_COFF */
+ symbol_table_insert (end_sym);
+ end_sym->sy_value = operand[1].immediate;
+ end_sym->sy_value.X_add_number += 2;
+ fix_new (frag_now, frag_now_fix (), 2, end_sym, 0, 1, BFD_RELOC_SH_LABEL);
+ }
+
+ output = frag_more (2);
+ output[0] = 0x8e;
+ output[1] = 0x8e;
+ insert (output, BFD_RELOC_SH_LOOP_START, 1, operand);
+ insert (output, BFD_RELOC_SH_LOOP_END, 1, operand + 1);
+
+ return frag_more (2);
+}
+
+/* Now we know what sort of opcodes it is, let's build the bytes. */
+
+static unsigned int
+build_Mytes (opcode, operand)
+ sh_opcode_info *opcode;
+ sh_operand_info *operand;
+{
+ int index;
+ char nbuf[4];
+ char *output = frag_more (2);
+ unsigned int size = 2;
+ int low_byte = target_big_endian ? 1 : 0;
+ nbuf[0] = 0;
+ nbuf[1] = 0;
+ nbuf[2] = 0;
+ nbuf[3] = 0;
+
+ for (index = 0; index < 4; index++)
+ {
+ sh_nibble_type i = opcode->nibbles[index];
+ if (i < 16)
+ {
+ nbuf[index] = i;
+ }
+ else
+ {
+ switch (i)
+ {
+ case REG_N:
+ nbuf[index] = reg_n;
+ break;
+ case REG_M:
+ nbuf[index] = reg_m;
+ break;
+ case SDT_REG_N:
+ if (reg_n < 2 || reg_n > 5)
+ as_bad (_("Invalid register: 'r%d'"), reg_n);
+ nbuf[index] = (reg_n & 3) | 4;
+ break;
+ case REG_NM:
+ nbuf[index] = reg_n | (reg_m >> 2);
+ break;
+ case REG_B:
+ nbuf[index] = reg_b | 0x08;
+ break;
+ case IMM0_4BY4:
+ insert (output + low_byte, BFD_RELOC_SH_IMM4BY4, 0, operand);
+ break;
+ case IMM0_4BY2:
+ insert (output + low_byte, BFD_RELOC_SH_IMM4BY2, 0, operand);
+ break;
+ case IMM0_4:
+ insert (output + low_byte, BFD_RELOC_SH_IMM4, 0, operand);
+ break;
+ case IMM1_4BY4:
+ insert (output + low_byte, BFD_RELOC_SH_IMM4BY4, 0, operand + 1);
+ break;
+ case IMM1_4BY2:
+ insert (output + low_byte, BFD_RELOC_SH_IMM4BY2, 0, operand + 1);
+ break;
+ case IMM1_4:
+ insert (output + low_byte, BFD_RELOC_SH_IMM4, 0, operand + 1);
+ break;
+ case IMM0_8BY4:
+ insert (output + low_byte, BFD_RELOC_SH_IMM8BY4, 0, operand);
+ break;
+ case IMM0_8BY2:
+ insert (output + low_byte, BFD_RELOC_SH_IMM8BY2, 0, operand);
+ break;
+ case IMM0_8:
+ insert (output + low_byte, BFD_RELOC_SH_IMM8, 0, operand);
+ break;
+ case IMM1_8BY4:
+ insert (output + low_byte, BFD_RELOC_SH_IMM8BY4, 0, operand + 1);
+ break;
+ case IMM1_8BY2:
+ insert (output + low_byte, BFD_RELOC_SH_IMM8BY2, 0, operand + 1);
+ break;
+ case IMM1_8:
+ insert (output + low_byte, BFD_RELOC_SH_IMM8, 0, operand + 1);
+ break;
+ case PCRELIMM_8BY4:
+ insert (output, BFD_RELOC_SH_PCRELIMM8BY4,
+ operand->type != A_DISP_PC_ABS, operand);
+ break;
+ case PCRELIMM_8BY2:
+ insert (output, BFD_RELOC_SH_PCRELIMM8BY2,
+ operand->type != A_DISP_PC_ABS, operand);
+ break;
+ case REPEAT:
+ output = insert_loop_bounds (output, operand);
+ nbuf[index] = opcode->nibbles[3];
+ operand += 2;
+ break;
+ default:
+ printf (_("failed for %d\n"), i);
+ }
+ }
+ }
+ if (!target_big_endian)
+ {
+ output[1] = (nbuf[0] << 4) | (nbuf[1]);
+ output[0] = (nbuf[2] << 4) | (nbuf[3]);
+ }
+ else
+ {
+ output[0] = (nbuf[0] << 4) | (nbuf[1]);
+ output[1] = (nbuf[2] << 4) | (nbuf[3]);
+ }
+ return size;
+}
+
+/* Find an opcode at the start of *STR_P in the hash table, and set
+ *STR_P to the first character after the last one read. */
+
+static sh_opcode_info *
+find_cooked_opcode (str_p)
+ char **str_p;
+{
+ char *str = *str_p;
+ unsigned char *op_start;
+ unsigned char *op_end;
+ char name[20];
+ int nlen = 0;
+
+ /* Drop leading whitespace. */
+ while (*str == ' ')
+ str++;
+
+ /* Find the op code end.
+ The pre-processor will eliminate whitespace in front of
+ any '@' after the first argument; we may be called from
+ assemble_ppi, so the opcode might be terminated by an '@'. */
+ for (op_start = op_end = (unsigned char *) (str);
+ *op_end
+ && nlen < 20
+ && !is_end_of_line[*op_end] && *op_end != ' ' && *op_end != '@';
+ op_end++)
+ {
+ unsigned char c = op_start[nlen];
+
+ /* The machine independent code will convert CMP/EQ into cmp/EQ
+ because it thinks the '/' is the end of the symbol. Moreover,
+ all but the first sub-insn is a parallel processing insn won't
+ be capitalized. Instead of hacking up the machine independent
+ code, we just deal with it here. */
+ c = TOLOWER (c);
+ name[nlen] = c;
+ nlen++;
+ }
+
+ name[nlen] = 0;
+ *str_p = op_end;
+
+ if (nlen == 0)
+ as_bad (_("can't find opcode "));
+
+ return (sh_opcode_info *) hash_find (opcode_hash_control, name);
+}
+
+/* Assemble a parallel processing insn. */
+#define DDT_BASE 0xf000 /* Base value for double data transfer insns */
+
+static unsigned int
+assemble_ppi (op_end, opcode)
+ char *op_end;
+ sh_opcode_info *opcode;
+{
+ int movx = 0;
+ int movy = 0;
+ int cond = 0;
+ int field_b = 0;
+ char *output;
+ int move_code;
+ unsigned int size;
+
+ for (;;)
+ {
+ sh_operand_info operand[3];
+
+ /* Some insn ignore one or more register fields, e.g. psts machl,a0.
+ Make sure we encode a defined insn pattern. */
+ reg_x = 0;
+ reg_y = 0;
+ reg_n = 0;
+
+ if (opcode->arg[0] != A_END)
+ op_end = get_operands (opcode, op_end, operand);
+ opcode = get_specific (opcode, operand);
+ if (opcode == 0)
+ {
+ /* Couldn't find an opcode which matched the operands. */
+ char *where = frag_more (2);
+ size = 2;
+
+ where[0] = 0x0;
+ where[1] = 0x0;
+ as_bad (_("invalid operands for opcode"));
+ return size;
+ }
+
+ if (opcode->nibbles[0] != PPI)
+ as_bad (_("insn can't be combined with parallel processing insn"));
+
+ switch (opcode->nibbles[1])
+ {
+
+ case NOPX:
+ if (movx)
+ as_bad (_("multiple movx specifications"));
+ movx = DDT_BASE;
+ break;
+ case NOPY:
+ if (movy)
+ as_bad (_("multiple movy specifications"));
+ movy = DDT_BASE;
+ break;
+
+ case MOVX:
+ if (movx)
+ as_bad (_("multiple movx specifications"));
+ if (reg_n < 4 || reg_n > 5)
+ as_bad (_("invalid movx address register"));
+ if (opcode->nibbles[2] & 8)
+ {
+ if (reg_m == A_A1_NUM)
+ movx = 1 << 7;
+ else if (reg_m != A_A0_NUM)
+ as_bad (_("invalid movx dsp register"));
+ }
+ else
+ {
+ if (reg_x > 1)
+ as_bad (_("invalid movx dsp register"));
+ movx = reg_x << 7;
+ }
+ movx += ((reg_n - 4) << 9) + (opcode->nibbles[2] << 2) + DDT_BASE;
+ break;
+
+ case MOVY:
+ if (movy)
+ as_bad (_("multiple movy specifications"));
+ if (opcode->nibbles[2] & 8)
+ {
+ /* Bit 3 in nibbles[2] is intended for bit 4 of the opcode,
+ so add 8 more. */
+ movy = 8;
+ if (reg_m == A_A1_NUM)
+ movy += 1 << 6;
+ else if (reg_m != A_A0_NUM)
+ as_bad (_("invalid movy dsp register"));
+ }
+ else
+ {
+ if (reg_y > 1)
+ as_bad (_("invalid movy dsp register"));
+ movy = reg_y << 6;
+ }
+ if (reg_n < 6 || reg_n > 7)
+ as_bad (_("invalid movy address register"));
+ movy += ((reg_n - 6) << 8) + opcode->nibbles[2] + DDT_BASE;
+ break;
+
+ case PSH:
+ if (operand[0].immediate.X_op != O_constant)
+ as_bad (_("dsp immediate shift value not constant"));
+ field_b = ((opcode->nibbles[2] << 12)
+ | (operand[0].immediate.X_add_number & 127) << 4
+ | reg_n);
+ break;
+ case PPI3:
+ if (field_b)
+ as_bad (_("multiple parallel processing specifications"));
+ field_b = ((opcode->nibbles[2] << 12) + (opcode->nibbles[3] << 8)
+ + (reg_x << 6) + (reg_y << 4) + reg_n);
+ break;
+ case PDC:
+ if (cond)
+ as_bad (_("multiple condition specifications"));
+ cond = opcode->nibbles[2] << 8;
+ if (*op_end)
+ goto skip_cond_check;
+ break;
+ case PPIC:
+ if (field_b)
+ as_bad (_("multiple parallel processing specifications"));
+ field_b = ((opcode->nibbles[2] << 12) + (opcode->nibbles[3] << 8)
+ + cond + (reg_x << 6) + (reg_y << 4) + reg_n);
+ cond = 0;
+ break;
+ case PMUL:
+ if (field_b)
+ {
+ if ((field_b & 0xef00) != 0xa100)
+ as_bad (_("insn cannot be combined with pmuls"));
+ field_b -= 0x8100;
+ switch (field_b & 0xf)
+ {
+ case A_X0_NUM:
+ field_b += 0 - A_X0_NUM;
+ break;
+ case A_Y0_NUM:
+ field_b += 1 - A_Y0_NUM;
+ break;
+ case A_A0_NUM:
+ field_b += 2 - A_A0_NUM;
+ break;
+ case A_A1_NUM:
+ field_b += 3 - A_A1_NUM;
+ break;
+ default:
+ as_bad (_("bad padd / psub pmuls output operand"));
+ }
+ /* Generate warning if the destination register for padd / psub
+ and pmuls is the same ( only for A0 or A1 ).
+ If the last nibble is 1010 then A0 is used in both
+ padd / psub and pmuls. If it is 1111 then A1 is used
+ as destination register in both padd / psub and pmuls. */
+
+ if ((((field_b | reg_efg) & 0x000F) == 0x000A)
+ || (((field_b | reg_efg) & 0x000F) == 0x000F))
+ as_warn (_("destination register is same for parallel insns"));
+ }
+ field_b += 0x4000 + reg_efg;
+ break;
+ default:
+ abort ();
+ }
+ if (cond)
+ {
+ as_bad (_("condition not followed by conditionalizable insn"));
+ cond = 0;
+ }
+ if (! *op_end)
+ break;
+ skip_cond_check:
+ opcode = find_cooked_opcode (&op_end);
+ if (opcode == NULL)
+ {
+ (as_bad
+ (_("unrecognized characters at end of parallel processing insn")));
+ break;
+ }
+ }
+
+ move_code = movx | movy;
+ if (field_b)
+ {
+ /* Parallel processing insn. */
+ unsigned long ppi_code = (movx | movy | 0xf800) << 16 | field_b;
+
+ output = frag_more (4);
+ size = 4;
+ if (! target_big_endian)
+ {
+ output[3] = ppi_code >> 8;
+ output[2] = ppi_code;
+ }
+ else
+ {
+ output[2] = ppi_code >> 8;
+ output[3] = ppi_code;
+ }
+ move_code |= 0xf800;
+ }
+ else
+ {
+ /* Just a double data transfer. */
+ output = frag_more (2);
+ size = 2;
+ }
+ if (! target_big_endian)
+ {
+ output[1] = move_code >> 8;
+ output[0] = move_code;
+ }
+ else
+ {
+ output[0] = move_code >> 8;
+ output[1] = move_code;
+ }
+ return size;
+}
+
+/* This is the guts of the machine-dependent assembler. STR points to a
+ machine dependent instruction. This function is supposed to emit
+ the frags/bytes it assembles to. */
+
+void
+md_assemble (str)
+ char *str;
+{
+ unsigned char *op_end;
+ sh_operand_info operand[3];
+ sh_opcode_info *opcode;
+ unsigned int size = 0;
+
+#ifdef HAVE_SH64
+ if (sh64_isa_mode == sh64_isa_shmedia)
+ {
+ shmedia_md_assemble (str);
+ return;
+ }
+ else
+ {
+ /* If we've seen pseudo-directives, make sure any emitted data or
+ frags are marked as data. */
+ if (seen_insn == false)
+ {
+ sh64_update_contents_mark (true);
+ sh64_set_contents_type (CRT_SH5_ISA16);
+ }
+
+ seen_insn = true;
+ }
+#endif /* HAVE_SH64 */
+
+ opcode = find_cooked_opcode (&str);
+ op_end = str;
+
+ if (opcode == NULL)
+ {
+ as_bad (_("unknown opcode"));
+ return;
+ }
+
+ if (sh_relax
+ && ! seg_info (now_seg)->tc_segment_info_data.in_code)
+ {
+ /* Output a CODE reloc to tell the linker that the following
+ bytes are instructions, not data. */
+ fix_new (frag_now, frag_now_fix (), 2, &abs_symbol, 0, 0,
+ BFD_RELOC_SH_CODE);
+ seg_info (now_seg)->tc_segment_info_data.in_code = 1;
+ }
+
+ if (opcode->nibbles[0] == PPI)
+ {
+ size = assemble_ppi (op_end, opcode);
+ }
+ else
+ {
+ if (opcode->arg[0] == A_BDISP12
+ || opcode->arg[0] == A_BDISP8)
+ {
+ parse_exp (op_end + 1, &operand[0]);
+ build_relax (opcode, &operand[0]);
+ }
+ else
+ {
+ if (opcode->arg[0] == A_END)
+ {
+ /* Ignore trailing whitespace. If there is any, it has already
+ been compressed to a single space. */
+ if (*op_end == ' ')
+ op_end++;
+ }
+ else
+ {
+ op_end = get_operands (opcode, op_end, operand);
+ }
+ opcode = get_specific (opcode, operand);
+
+ if (opcode == 0)
+ {
+ /* Couldn't find an opcode which matched the operands. */
+ char *where = frag_more (2);
+ size = 2;
+
+ where[0] = 0x0;
+ where[1] = 0x0;
+ as_bad (_("invalid operands for opcode"));
+ }
+ else
+ {
+ if (*op_end)
+ as_bad (_("excess operands: '%s'"), op_end);
+
+ size = build_Mytes (opcode, operand);
+ }
+ }
+ }
+
+#ifdef BFD_ASSEMBLER
+ dwarf2_emit_insn (size);
+#endif
+}
+
+/* This routine is called each time a label definition is seen. It
+ emits a BFD_RELOC_SH_LABEL reloc if necessary. */
+
+void
+sh_frob_label ()
+{
+ static fragS *last_label_frag;
+ static int last_label_offset;
+
+ if (sh_relax
+ && seg_info (now_seg)->tc_segment_info_data.in_code)
+ {
+ int offset;
+
+ offset = frag_now_fix ();
+ if (frag_now != last_label_frag
+ || offset != last_label_offset)
+ {
+ fix_new (frag_now, offset, 2, &abs_symbol, 0, 0, BFD_RELOC_SH_LABEL);
+ last_label_frag = frag_now;
+ last_label_offset = offset;
+ }
+ }
+}
+
+/* This routine is called when the assembler is about to output some
+ data. It emits a BFD_RELOC_SH_DATA reloc if necessary. */
+
+void
+sh_flush_pending_output ()
+{
+ if (sh_relax
+ && seg_info (now_seg)->tc_segment_info_data.in_code)
+ {
+ fix_new (frag_now, frag_now_fix (), 2, &abs_symbol, 0, 0,
+ BFD_RELOC_SH_DATA);
+ seg_info (now_seg)->tc_segment_info_data.in_code = 0;
+ }
+}
+
+symbolS *
+md_undefined_symbol (name)
+ char *name ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
+
+#ifdef OBJ_COFF
+#ifndef BFD_ASSEMBLER
+
+void
+tc_crawl_symbol_chain (headers)
+ object_headers *headers ATTRIBUTE_UNUSED;
+{
+ printf (_("call to tc_crawl_symbol_chain \n"));
+}
+
+void
+tc_headers_hook (headers)
+ object_headers *headers ATTRIBUTE_UNUSED;
+{
+ printf (_("call to tc_headers_hook \n"));
+}
+
+#endif
+#endif
+
+/* Various routines to kill one day. */
+/* Equal to MAX_PRECISION in atof-ieee.c. */
+#define MAX_LITTLENUMS 6
+
+/* Turn a string in input_line_pointer into a floating point constant
+ of type TYPE, and store the appropriate bytes in *LITP. The number
+ of LITTLENUMS emitted is stored in *SIZEP . An error message is
+ returned, or NULL on OK. */
+
+char *
+md_atof (type, litP, sizeP)
+ int type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[4];
+ char *t;
+ int i;
+
+ switch (type)
+ {
+ case 'f':
+ prec = 2;
+ break;
+
+ case 'd':
+ prec = 4;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("bad call to md_atof");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * 2;
+
+ if (! target_big_endian)
+ {
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litP, (valueT) words[i], 2);
+ litP += 2;
+ }
+ }
+ else
+ {
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, (valueT) words[i], 2);
+ litP += 2;
+ }
+ }
+
+ return NULL;
+}
+
+/* Handle the .uses pseudo-op. This pseudo-op is used just before a
+ call instruction. It refers to a label of the instruction which
+ loads the register which the call uses. We use it to generate a
+ special reloc for the linker. */
+
+static void
+s_uses (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ expressionS ex;
+
+ if (! sh_relax)
+ as_warn (_(".uses pseudo-op seen when not relaxing"));
+
+ expression (&ex);
+
+ if (ex.X_op != O_symbol || ex.X_add_number != 0)
+ {
+ as_bad (_("bad .uses format"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ fix_new_exp (frag_now, frag_now_fix (), 2, &ex, 1, BFD_RELOC_SH_USES);
+
+ demand_empty_rest_of_line ();
+}
+
+const char *md_shortopts = "";
+struct option md_longopts[] =
+{
+#define OPTION_RELAX (OPTION_MD_BASE)
+#define OPTION_BIG (OPTION_MD_BASE + 1)
+#define OPTION_LITTLE (OPTION_BIG + 1)
+#define OPTION_SMALL (OPTION_LITTLE + 1)
+#define OPTION_DSP (OPTION_SMALL + 1)
+
+ {"relax", no_argument, NULL, OPTION_RELAX},
+ {"big", no_argument, NULL, OPTION_BIG},
+ {"little", no_argument, NULL, OPTION_LITTLE},
+ {"small", no_argument, NULL, OPTION_SMALL},
+ {"dsp", no_argument, NULL, OPTION_DSP},
+#ifdef HAVE_SH64
+#define OPTION_ISA (OPTION_DSP + 1)
+#define OPTION_ABI (OPTION_ISA + 1)
+#define OPTION_NO_MIX (OPTION_ABI + 1)
+#define OPTION_SHCOMPACT_CONST_CRANGE (OPTION_NO_MIX + 1)
+#define OPTION_NO_EXPAND (OPTION_SHCOMPACT_CONST_CRANGE + 1)
+#define OPTION_PT32 (OPTION_NO_EXPAND + 1)
+ {"isa", required_argument, NULL, OPTION_ISA},
+ {"abi", required_argument, NULL, OPTION_ABI},
+ {"no-mix", no_argument, NULL, OPTION_NO_MIX},
+ {"shcompact-const-crange", no_argument, NULL, OPTION_SHCOMPACT_CONST_CRANGE},
+ {"no-expand", no_argument, NULL, OPTION_NO_EXPAND},
+ {"expand-pt32", no_argument, NULL, OPTION_PT32},
+#endif /* HAVE_SH64 */
+
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof (md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg ATTRIBUTE_UNUSED;
+{
+ switch (c)
+ {
+ case OPTION_RELAX:
+ sh_relax = 1;
+ break;
+
+ case OPTION_BIG:
+ target_big_endian = 1;
+ break;
+
+ case OPTION_LITTLE:
+ target_big_endian = 0;
+ break;
+
+ case OPTION_SMALL:
+ sh_small = 1;
+ break;
+
+ case OPTION_DSP:
+ sh_dsp = 1;
+ break;
+
+#ifdef HAVE_SH64
+ case OPTION_ISA:
+ if (strcasecmp (arg, "shmedia") == 0)
+ {
+ if (sh64_isa_mode == sh64_isa_shcompact)
+ as_bad (_("Invalid combination: --isa=SHcompact with --isa=SHmedia"));
+ sh64_isa_mode = sh64_isa_shmedia;
+ }
+ else if (strcasecmp (arg, "shcompact") == 0)
+ {
+ if (sh64_isa_mode == sh64_isa_shmedia)
+ as_bad (_("Invalid combination: --isa=SHmedia with --isa=SHcompact"));
+ if (sh64_abi == sh64_abi_64)
+ as_bad (_("Invalid combination: --abi=64 with --isa=SHcompact"));
+ sh64_isa_mode = sh64_isa_shcompact;
+ }
+ else
+ as_bad ("Invalid argument to --isa option: %s", arg);
+ break;
+
+ case OPTION_ABI:
+ if (strcmp (arg, "32") == 0)
+ {
+ if (sh64_abi == sh64_abi_64)
+ as_bad (_("Invalid combination: --abi=32 with --abi=64"));
+ sh64_abi = sh64_abi_32;
+ }
+ else if (strcmp (arg, "64") == 0)
+ {
+ if (sh64_abi == sh64_abi_32)
+ as_bad (_("Invalid combination: --abi=64 with --abi=32"));
+ if (sh64_isa_mode == sh64_isa_shcompact)
+ as_bad (_("Invalid combination: --isa=SHcompact with --abi=64"));
+ sh64_abi = sh64_abi_64;
+ }
+ else
+ as_bad ("Invalid argument to --abi option: %s", arg);
+ break;
+
+ case OPTION_NO_MIX:
+ sh64_mix = false;
+ break;
+
+ case OPTION_SHCOMPACT_CONST_CRANGE:
+ sh64_shcompact_const_crange = true;
+ break;
+
+ case OPTION_NO_EXPAND:
+ sh64_expand = false;
+ break;
+
+ case OPTION_PT32:
+ sh64_pt32 = true;
+ break;
+#endif /* HAVE_SH64 */
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf (stream, _("\
+SH options:\n\
+-little generate little endian code\n\
+-big generate big endian code\n\
+-relax alter jump instructions for long displacements\n\
+-small align sections to 4 byte boundaries, not 16\n\
+-dsp enable sh-dsp insns, and disable sh3e / sh4 insns.\n"));
+#ifdef HAVE_SH64
+ fprintf (stream, _("\
+-isa=[shmedia set default instruction set for SH64\n\
+ | SHmedia\n\
+ | shcompact\n\
+ | SHcompact]\n\
+-abi=[32|64] set size of expanded SHmedia operands and object\n\
+ file type\n\
+-shcompact-const-crange emit code-range descriptors for constants in\n\
+ SHcompact code sections\n\
+-no-mix disallow SHmedia code in the same section as\n\
+ constants and SHcompact code\n\
+-no-expand do not expand MOVI, PT, PTA or PTB instructions\n\
+-expand-pt32 with -abi=64, expand PT, PTA and PTB instructions\n\
+ to 32 bits only"));
+#endif /* HAVE_SH64 */
+}
+
+/* This struct is used to pass arguments to sh_count_relocs through
+ bfd_map_over_sections. */
+
+struct sh_count_relocs
+{
+ /* Symbol we are looking for. */
+ symbolS *sym;
+ /* Count of relocs found. */
+ int count;
+};
+
+/* Count the number of fixups in a section which refer to a particular
+ symbol. When using BFD_ASSEMBLER, this is called via
+ bfd_map_over_sections. */
+
+static void
+sh_count_relocs (abfd, sec, data)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ segT sec;
+ PTR data;
+{
+ struct sh_count_relocs *info = (struct sh_count_relocs *) data;
+ segment_info_type *seginfo;
+ symbolS *sym;
+ fixS *fix;
+
+ seginfo = seg_info (sec);
+ if (seginfo == NULL)
+ return;
+
+ sym = info->sym;
+ for (fix = seginfo->fix_root; fix != NULL; fix = fix->fx_next)
+ {
+ if (fix->fx_addsy == sym)
+ {
+ ++info->count;
+ fix->fx_tcbit = 1;
+ }
+ }
+}
+
+/* Handle the count relocs for a particular section. When using
+ BFD_ASSEMBLER, this is called via bfd_map_over_sections. */
+
+static void
+sh_frob_section (abfd, sec, ignore)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ segT sec;
+ PTR ignore ATTRIBUTE_UNUSED;
+{
+ segment_info_type *seginfo;
+ fixS *fix;
+
+ seginfo = seg_info (sec);
+ if (seginfo == NULL)
+ return;
+
+ for (fix = seginfo->fix_root; fix != NULL; fix = fix->fx_next)
+ {
+ symbolS *sym;
+ bfd_vma val;
+ fixS *fscan;
+ struct sh_count_relocs info;
+
+ if (fix->fx_r_type != BFD_RELOC_SH_USES)
+ continue;
+
+ /* The BFD_RELOC_SH_USES reloc should refer to a defined local
+ symbol in the same section. */
+ sym = fix->fx_addsy;
+ if (sym == NULL
+ || fix->fx_subsy != NULL
+ || fix->fx_addnumber != 0
+ || S_GET_SEGMENT (sym) != sec
+#if ! defined (BFD_ASSEMBLER) && defined (OBJ_COFF)
+ || S_GET_STORAGE_CLASS (sym) == C_EXT
+#endif
+ || S_IS_EXTERNAL (sym))
+ {
+ as_warn_where (fix->fx_file, fix->fx_line,
+ _(".uses does not refer to a local symbol in the same section"));
+ continue;
+ }
+
+ /* Look through the fixups again, this time looking for one
+ at the same location as sym. */
+ val = S_GET_VALUE (sym);
+ for (fscan = seginfo->fix_root;
+ fscan != NULL;
+ fscan = fscan->fx_next)
+ if (val == fscan->fx_frag->fr_address + fscan->fx_where
+ && fscan->fx_r_type != BFD_RELOC_SH_ALIGN
+ && fscan->fx_r_type != BFD_RELOC_SH_CODE
+ && fscan->fx_r_type != BFD_RELOC_SH_DATA
+ && fscan->fx_r_type != BFD_RELOC_SH_LABEL)
+ break;
+ if (fscan == NULL)
+ {
+ as_warn_where (fix->fx_file, fix->fx_line,
+ _("can't find fixup pointed to by .uses"));
+ continue;
+ }
+
+ if (fscan->fx_tcbit)
+ {
+ /* We've already done this one. */
+ continue;
+ }
+
+ /* The variable fscan should also be a fixup to a local symbol
+ in the same section. */
+ sym = fscan->fx_addsy;
+ if (sym == NULL
+ || fscan->fx_subsy != NULL
+ || fscan->fx_addnumber != 0
+ || S_GET_SEGMENT (sym) != sec
+#if ! defined (BFD_ASSEMBLER) && defined (OBJ_COFF)
+ || S_GET_STORAGE_CLASS (sym) == C_EXT
+#endif
+ || S_IS_EXTERNAL (sym))
+ {
+ as_warn_where (fix->fx_file, fix->fx_line,
+ _(".uses target does not refer to a local symbol in the same section"));
+ continue;
+ }
+
+ /* Now we look through all the fixups of all the sections,
+ counting the number of times we find a reference to sym. */
+ info.sym = sym;
+ info.count = 0;
+#ifdef BFD_ASSEMBLER
+ bfd_map_over_sections (stdoutput, sh_count_relocs, (PTR) &info);
+#else
+ {
+ int iscan;
+
+ for (iscan = SEG_E0; iscan < SEG_UNKNOWN; iscan++)
+ sh_count_relocs ((bfd *) NULL, iscan, (PTR) &info);
+ }
+#endif
+
+ if (info.count < 1)
+ abort ();
+
+ /* Generate a BFD_RELOC_SH_COUNT fixup at the location of sym.
+ We have already adjusted the value of sym to include the
+ fragment address, so we undo that adjustment here. */
+ subseg_change (sec, 0);
+ fix_new (fscan->fx_frag,
+ S_GET_VALUE (sym) - fscan->fx_frag->fr_address,
+ 4, &abs_symbol, info.count, 0, BFD_RELOC_SH_COUNT);
+ }
+}
+
+/* This function is called after the symbol table has been completed,
+ but before the relocs or section contents have been written out.
+ If we have seen any .uses pseudo-ops, they point to an instruction
+ which loads a register with the address of a function. We look
+ through the fixups to find where the function address is being
+ loaded from. We then generate a COUNT reloc giving the number of
+ times that function address is referred to. The linker uses this
+ information when doing relaxing, to decide when it can eliminate
+ the stored function address entirely. */
+
+void
+sh_frob_file ()
+{
+#ifdef HAVE_SH64
+ shmedia_frob_file_before_adjust ();
+#endif
+
+ if (! sh_relax)
+ return;
+
+#ifdef BFD_ASSEMBLER
+ bfd_map_over_sections (stdoutput, sh_frob_section, (PTR) NULL);
+#else
+ {
+ int iseg;
+
+ for (iseg = SEG_E0; iseg < SEG_UNKNOWN; iseg++)
+ sh_frob_section ((bfd *) NULL, iseg, (PTR) NULL);
+ }
+#endif
+}
+
+/* Called after relaxing. Set the correct sizes of the fragments, and
+ create relocs so that md_apply_fix3 will fill in the correct values. */
+
+void
+md_convert_frag (headers, seg, fragP)
+#ifdef BFD_ASSEMBLER
+ bfd *headers ATTRIBUTE_UNUSED;
+#else
+ object_headers *headers ATTRIBUTE_UNUSED;
+#endif
+ segT seg;
+ fragS *fragP;
+{
+ int donerelax = 0;
+
+ switch (fragP->fr_subtype)
+ {
+ case C (COND_JUMP, COND8):
+ case C (COND_JUMP_DELAY, COND8):
+ subseg_change (seg, 0);
+ fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset,
+ 1, BFD_RELOC_SH_PCDISP8BY2);
+ fragP->fr_fix += 2;
+ fragP->fr_var = 0;
+ break;
+
+ case C (UNCOND_JUMP, UNCOND12):
+ subseg_change (seg, 0);
+ fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset,
+ 1, BFD_RELOC_SH_PCDISP12BY2);
+ fragP->fr_fix += 2;
+ fragP->fr_var = 0;
+ break;
+
+ case C (UNCOND_JUMP, UNCOND32):
+ case C (UNCOND_JUMP, UNDEF_WORD_DISP):
+ if (fragP->fr_symbol == NULL)
+ as_bad_where (fragP->fr_file, fragP->fr_line,
+ _("displacement overflows 12-bit field"));
+ else if (S_IS_DEFINED (fragP->fr_symbol))
+ as_bad_where (fragP->fr_file, fragP->fr_line,
+ _("displacement to defined symbol %s overflows 12-bit field"),
+ S_GET_NAME (fragP->fr_symbol));
+ else
+ as_bad_where (fragP->fr_file, fragP->fr_line,
+ _("displacement to undefined symbol %s overflows 12-bit field"),
+ S_GET_NAME (fragP->fr_symbol));
+ /* Stabilize this frag, so we don't trip an assert. */
+ fragP->fr_fix += fragP->fr_var;
+ fragP->fr_var = 0;
+ break;
+
+ case C (COND_JUMP, COND12):
+ case C (COND_JUMP_DELAY, COND12):
+ /* A bcond won't fit, so turn it into a b!cond; bra disp; nop. */
+ /* I found that a relax failure for gcc.c-torture/execute/930628-1.c
+ was due to gas incorrectly relaxing an out-of-range conditional
+ branch with delay slot. It turned:
+ bf.s L6 (slot mov.l r12,@(44,r0))
+ into:
+
+2c: 8f 01 a0 8b bf.s 32 <_main+32> (slot bra L6)
+30: 00 09 nop
+32: 10 cb mov.l r12,@(44,r0)
+ Therefore, branches with delay slots have to be handled
+ differently from ones without delay slots. */
+ {
+ unsigned char *buffer =
+ (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
+ int highbyte = target_big_endian ? 0 : 1;
+ int lowbyte = target_big_endian ? 1 : 0;
+ int delay = fragP->fr_subtype == C (COND_JUMP_DELAY, COND12);
+
+ /* Toggle the true/false bit of the bcond. */
+ buffer[highbyte] ^= 0x2;
+
+ /* If this is a delayed branch, we may not put the bra in the
+ slot. So we change it to a non-delayed branch, like that:
+ b! cond slot_label; bra disp; slot_label: slot_insn
+ ??? We should try if swapping the conditional branch and
+ its delay-slot insn already makes the branch reach. */
+
+ /* Build a relocation to six / four bytes farther on. */
+ subseg_change (seg, 0);
+ fix_new (fragP, fragP->fr_fix, 2,
+#ifdef BFD_ASSEMBLER
+ section_symbol (seg),
+#else
+ seg_info (seg)->dot,
+#endif
+ fragP->fr_address + fragP->fr_fix + (delay ? 4 : 6),
+ 1, BFD_RELOC_SH_PCDISP8BY2);
+
+ /* Set up a jump instruction. */
+ buffer[highbyte + 2] = 0xa0;
+ buffer[lowbyte + 2] = 0;
+ fix_new (fragP, fragP->fr_fix + 2, 2, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_SH_PCDISP12BY2);
+
+ if (delay)
+ {
+ buffer[highbyte] &= ~0x4; /* Removes delay slot from branch. */
+ fragP->fr_fix += 4;
+ }
+ else
+ {
+ /* Fill in a NOP instruction. */
+ buffer[highbyte + 4] = 0x0;
+ buffer[lowbyte + 4] = 0x9;
+
+ fragP->fr_fix += 6;
+ }
+ fragP->fr_var = 0;
+ donerelax = 1;
+ }
+ break;
+
+ case C (COND_JUMP, COND32):
+ case C (COND_JUMP_DELAY, COND32):
+ case C (COND_JUMP, UNDEF_WORD_DISP):
+ case C (COND_JUMP_DELAY, UNDEF_WORD_DISP):
+ if (fragP->fr_symbol == NULL)
+ as_bad_where (fragP->fr_file, fragP->fr_line,
+ _("displacement overflows 8-bit field"));
+ else if (S_IS_DEFINED (fragP->fr_symbol))
+ as_bad_where (fragP->fr_file, fragP->fr_line,
+ _("displacement to defined symbol %s overflows 8-bit field"),
+ S_GET_NAME (fragP->fr_symbol));
+ else
+ as_bad_where (fragP->fr_file, fragP->fr_line,
+ _("displacement to undefined symbol %s overflows 8-bit field "),
+ S_GET_NAME (fragP->fr_symbol));
+ /* Stabilize this frag, so we don't trip an assert. */
+ fragP->fr_fix += fragP->fr_var;
+ fragP->fr_var = 0;
+ break;
+
+ default:
+#ifdef HAVE_SH64
+ shmedia_md_convert_frag (headers, seg, fragP, true);
+#else
+ abort ();
+#endif
+ }
+
+ if (donerelax && !sh_relax)
+ as_warn_where (fragP->fr_file, fragP->fr_line,
+ _("overflow in branch to %s; converted into longer instruction sequence"),
+ (fragP->fr_symbol != NULL
+ ? S_GET_NAME (fragP->fr_symbol)
+ : ""));
+}
+
+valueT
+md_section_align (seg, size)
+ segT seg ATTRIBUTE_UNUSED;
+ valueT size;
+{
+#ifdef BFD_ASSEMBLER
+#ifdef OBJ_ELF
+ return size;
+#else /* ! OBJ_ELF */
+ return ((size + (1 << bfd_get_section_alignment (stdoutput, seg)) - 1)
+ & (-1 << bfd_get_section_alignment (stdoutput, seg)));
+#endif /* ! OBJ_ELF */
+#else /* ! BFD_ASSEMBLER */
+ return ((size + (1 << section_alignment[(int) seg]) - 1)
+ & (-1 << section_alignment[(int) seg]));
+#endif /* ! BFD_ASSEMBLER */
+}
+
+/* This static variable is set by s_uacons to tell sh_cons_align that
+ the expession does not need to be aligned. */
+
+static int sh_no_align_cons = 0;
+
+/* This handles the unaligned space allocation pseudo-ops, such as
+ .uaword. .uaword is just like .word, but the value does not need
+ to be aligned. */
+
+static void
+s_uacons (bytes)
+ int bytes;
+{
+ /* Tell sh_cons_align not to align this value. */
+ sh_no_align_cons = 1;
+ cons (bytes);
+}
+
+/* If a .word, et. al., pseud-op is seen, warn if the value is not
+ aligned correctly. Note that this can cause warnings to be issued
+ when assembling initialized structured which were declared with the
+ packed attribute. FIXME: Perhaps we should require an option to
+ enable this warning? */
+
+void
+sh_cons_align (nbytes)
+ int nbytes;
+{
+ int nalign;
+ char *p;
+
+ if (sh_no_align_cons)
+ {
+ /* This is an unaligned pseudo-op. */
+ sh_no_align_cons = 0;
+ return;
+ }
+
+ nalign = 0;
+ while ((nbytes & 1) == 0)
+ {
+ ++nalign;
+ nbytes >>= 1;
+ }
+
+ if (nalign == 0)
+ return;
+
+ if (now_seg == absolute_section)
+ {
+ if ((abs_section_offset & ((1 << nalign) - 1)) != 0)
+ as_warn (_("misaligned data"));
+ return;
+ }
+
+ p = frag_var (rs_align_test, 1, 1, (relax_substateT) 0,
+ (symbolS *) NULL, (offsetT) nalign, (char *) NULL);
+
+ record_alignment (now_seg, nalign);
+}
+
+/* When relaxing, we need to output a reloc for any .align directive
+ that requests alignment to a four byte boundary or larger. This is
+ also where we check for misaligned data. */
+
+void
+sh_handle_align (frag)
+ fragS *frag;
+{
+ int bytes = frag->fr_next->fr_address - frag->fr_address - frag->fr_fix;
+
+ if (frag->fr_type == rs_align_code)
+ {
+ static const unsigned char big_nop_pattern[] = { 0x00, 0x09 };
+ static const unsigned char little_nop_pattern[] = { 0x09, 0x00 };
+
+ char *p = frag->fr_literal + frag->fr_fix;
+
+ if (bytes & 1)
+ {
+ *p++ = 0;
+ bytes--;
+ frag->fr_fix += 1;
+ }
+
+ if (target_big_endian)
+ {
+ memcpy (p, big_nop_pattern, sizeof big_nop_pattern);
+ frag->fr_var = sizeof big_nop_pattern;
+ }
+ else
+ {
+ memcpy (p, little_nop_pattern, sizeof little_nop_pattern);
+ frag->fr_var = sizeof little_nop_pattern;
+ }
+ }
+ else if (frag->fr_type == rs_align_test)
+ {
+ if (bytes != 0)
+ as_warn_where (frag->fr_file, frag->fr_line, _("misaligned data"));
+ }
+
+ if (sh_relax
+ && (frag->fr_type == rs_align
+ || frag->fr_type == rs_align_code)
+ && frag->fr_address + frag->fr_fix > 0
+ && frag->fr_offset > 1
+ && now_seg != bss_section)
+ fix_new (frag, frag->fr_fix, 2, &abs_symbol, frag->fr_offset, 0,
+ BFD_RELOC_SH_ALIGN);
+}
+
+/* This macro decides whether a particular reloc is an entry in a
+ switch table. It is used when relaxing, because the linker needs
+ to know about all such entries so that it can adjust them if
+ necessary. */
+
+#ifdef BFD_ASSEMBLER
+#define SWITCH_TABLE_CONS(fix) (0)
+#else
+#define SWITCH_TABLE_CONS(fix) \
+ ((fix)->fx_r_type == 0 \
+ && ((fix)->fx_size == 2 \
+ || (fix)->fx_size == 1 \
+ || (fix)->fx_size == 4))
+#endif
+
+#define SWITCH_TABLE(fix) \
+ ((fix)->fx_addsy != NULL \
+ && (fix)->fx_subsy != NULL \
+ && S_GET_SEGMENT ((fix)->fx_addsy) == text_section \
+ && S_GET_SEGMENT ((fix)->fx_subsy) == text_section \
+ && ((fix)->fx_r_type == BFD_RELOC_32 \
+ || (fix)->fx_r_type == BFD_RELOC_16 \
+ || (fix)->fx_r_type == BFD_RELOC_8 \
+ || SWITCH_TABLE_CONS (fix)))
+
+/* See whether we need to force a relocation into the output file.
+ This is used to force out switch and PC relative relocations when
+ relaxing. */
+
+int
+sh_force_relocation (fix)
+ fixS *fix;
+{
+
+ if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY
+ || fix->fx_r_type == BFD_RELOC_SH_LOOP_START
+ || fix->fx_r_type == BFD_RELOC_SH_LOOP_END)
+ return 1;
+
+ if (! sh_relax)
+ return 0;
+
+ return (fix->fx_pcrel
+ || SWITCH_TABLE (fix)
+ || fix->fx_r_type == BFD_RELOC_SH_COUNT
+ || fix->fx_r_type == BFD_RELOC_SH_ALIGN
+ || fix->fx_r_type == BFD_RELOC_SH_CODE
+ || fix->fx_r_type == BFD_RELOC_SH_DATA
+#ifdef HAVE_SH64
+ || fix->fx_r_type == BFD_RELOC_SH_SHMEDIA_CODE
+#endif
+ || fix->fx_r_type == BFD_RELOC_SH_LABEL);
+}
+
+#ifdef OBJ_ELF
+boolean
+sh_fix_adjustable (fixP)
+ fixS *fixP;
+{
+
+ if (fixP->fx_addsy == NULL)
+ return 1;
+
+ if (fixP->fx_r_type == BFD_RELOC_SH_PCDISP8BY2
+ || fixP->fx_r_type == BFD_RELOC_SH_PCDISP12BY2
+ || fixP->fx_r_type == BFD_RELOC_SH_PCRELIMM8BY2
+ || fixP->fx_r_type == BFD_RELOC_SH_PCRELIMM8BY4
+ || fixP->fx_r_type == BFD_RELOC_8_PCREL
+ || fixP->fx_r_type == BFD_RELOC_SH_SWITCH16
+ || fixP->fx_r_type == BFD_RELOC_SH_SWITCH32)
+ return 1;
+
+ if (! TC_RELOC_RTSYM_LOC_FIXUP (fixP)
+ || fixP->fx_r_type == BFD_RELOC_RVA)
+ return 0;
+
+ /* We need the symbol name for the VTABLE entries */
+ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+
+ return 1;
+}
+
+void
+sh_elf_final_processing ()
+{
+ int val;
+
+ /* Set file-specific flags to indicate if this code needs
+ a processor with the sh-dsp / sh3e ISA to execute. */
+#ifdef HAVE_SH64
+ /* SH5 and above don't know about the valid_arch arch_sh* bits defined
+ in sh-opc.h, so check SH64 mode before checking valid_arch. */
+ if (sh64_isa_mode != sh64_isa_unspecified)
+ val = EF_SH5;
+ else
+#endif /* HAVE_SH64 */
+ if (valid_arch & arch_sh1)
+ val = EF_SH1;
+ else if (valid_arch & arch_sh2)
+ val = EF_SH2;
+ else if (valid_arch & arch_sh_dsp)
+ val = EF_SH_DSP;
+ else if (valid_arch & arch_sh3)
+ val = EF_SH3;
+ else if (valid_arch & arch_sh3_dsp)
+ val = EF_SH_DSP;
+ else if (valid_arch & arch_sh3e)
+ val = EF_SH3E;
+ else if (valid_arch & arch_sh4)
+ val = EF_SH4;
+ else
+ abort ();
+
+ elf_elfheader (stdoutput)->e_flags &= ~EF_SH_MACH_MASK;
+ elf_elfheader (stdoutput)->e_flags |= val;
+}
+#endif
+
+/* Apply a fixup to the object file. */
+
+void
+md_apply_fix3 (fixP, valP, seg)
+ fixS * fixP;
+ valueT * valP;
+ segT seg ATTRIBUTE_UNUSED;
+{
+ char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+ int lowbyte = target_big_endian ? 1 : 0;
+ int highbyte = target_big_endian ? 0 : 1;
+ long val = (long) *valP;
+ long max, min;
+ int shift;
+
+#ifdef BFD_ASSEMBLER
+ /* A difference between two symbols, the second of which is in the
+ current section, is transformed in a PC-relative relocation to
+ the other symbol. We have to adjust the relocation type here. */
+ if (fixP->fx_pcrel)
+ {
+ switch (fixP->fx_r_type)
+ {
+ default:
+ break;
+
+ case BFD_RELOC_32:
+ fixP->fx_r_type = BFD_RELOC_32_PCREL;
+ break;
+
+ /* Currently, we only support 32-bit PCREL relocations.
+ We'd need a new reloc type to handle 16_PCREL, and
+ 8_PCREL is already taken for R_SH_SWITCH8, which
+ apparently does something completely different than what
+ we need. FIXME. */
+ case BFD_RELOC_16:
+ bfd_set_error (bfd_error_bad_value);
+ return;
+
+ case BFD_RELOC_8:
+ bfd_set_error (bfd_error_bad_value);
+ return;
+ }
+ }
+
+ /* The function adjust_reloc_syms won't convert a reloc against a weak
+ symbol into a reloc against a section, but bfd_install_relocation
+ will screw up if the symbol is defined, so we have to adjust val here
+ to avoid the screw up later.
+
+ For ordinary relocs, this does not happen for ELF, since for ELF,
+ bfd_install_relocation uses the "special function" field of the
+ howto, and does not execute the code that needs to be undone, as long
+ as the special function does not return bfd_reloc_continue.
+ It can happen for GOT- and PLT-type relocs the way they are
+ described in elf32-sh.c as they use bfd_elf_generic_reloc, but it
+ doesn't matter here since those relocs don't use VAL; see below. */
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour
+ && fixP->fx_addsy != NULL
+ && S_IS_WEAK (fixP->fx_addsy))
+ val -= S_GET_VALUE (fixP->fx_addsy);
+#endif
+
+#ifndef BFD_ASSEMBLER
+ if (fixP->fx_r_type == 0)
+ {
+ if (fixP->fx_size == 2)
+ fixP->fx_r_type = BFD_RELOC_16;
+ else if (fixP->fx_size == 4)
+ fixP->fx_r_type = BFD_RELOC_32;
+ else if (fixP->fx_size == 1)
+ fixP->fx_r_type = BFD_RELOC_8;
+ else
+ abort ();
+ }
+#endif
+
+ max = min = 0;
+ shift = 0;
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_SH_IMM4:
+ max = 0xf;
+ *buf = (*buf & 0xf0) | (val & 0xf);
+ break;
+
+ case BFD_RELOC_SH_IMM4BY2:
+ max = 0xf;
+ shift = 1;
+ *buf = (*buf & 0xf0) | ((val >> 1) & 0xf);
+ break;
+
+ case BFD_RELOC_SH_IMM4BY4:
+ max = 0xf;
+ shift = 2;
+ *buf = (*buf & 0xf0) | ((val >> 2) & 0xf);
+ break;
+
+ case BFD_RELOC_SH_IMM8BY2:
+ max = 0xff;
+ shift = 1;
+ *buf = val >> 1;
+ break;
+
+ case BFD_RELOC_SH_IMM8BY4:
+ max = 0xff;
+ shift = 2;
+ *buf = val >> 2;
+ break;
+
+ case BFD_RELOC_8:
+ case BFD_RELOC_SH_IMM8:
+ /* Sometimes the 8 bit value is sign extended (e.g., add) and
+ sometimes it is not (e.g., and). We permit any 8 bit value.
+ Note that adding further restrictions may invalidate
+ reasonable looking assembly code, such as ``and -0x1,r0''. */
+ max = 0xff;
+ min = -0xff;
+ *buf++ = val;
+ break;
+
+ case BFD_RELOC_SH_PCRELIMM8BY4:
+ /* The lower two bits of the PC are cleared before the
+ displacement is added in. We can assume that the destination
+ is on a 4 byte bounday. If this instruction is also on a 4
+ byte boundary, then we want
+ (target - here) / 4
+ and target - here is a multiple of 4.
+ Otherwise, we are on a 2 byte boundary, and we want
+ (target - (here - 2)) / 4
+ and target - here is not a multiple of 4. Computing
+ (target - (here - 2)) / 4 == (target - here + 2) / 4
+ works for both cases, since in the first case the addition of
+ 2 will be removed by the division. target - here is in the
+ variable val. */
+ val = (val + 2) / 4;
+ if (val & ~0xff)
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far"));
+ buf[lowbyte] = val;
+ break;
+
+ case BFD_RELOC_SH_PCRELIMM8BY2:
+ val /= 2;
+ if (val & ~0xff)
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far"));
+ buf[lowbyte] = val;
+ break;
+
+ case BFD_RELOC_SH_PCDISP8BY2:
+ val /= 2;
+ if (val < -0x80 || val > 0x7f)
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far"));
+ buf[lowbyte] = val;
+ break;
+
+ case BFD_RELOC_SH_PCDISP12BY2:
+ val /= 2;
+ if (val < -0x800 || val > 0x7ff)
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far"));
+ buf[lowbyte] = val & 0xff;
+ buf[highbyte] |= (val >> 8) & 0xf;
+ break;
+
+ case BFD_RELOC_32:
+ case BFD_RELOC_32_PCREL:
+ md_number_to_chars (buf, val, 4);
+ break;
+
+ case BFD_RELOC_16:
+ md_number_to_chars (buf, val, 2);
+ break;
+
+ case BFD_RELOC_SH_USES:
+ /* Pass the value into sh_coff_reloc_mangle. */
+ fixP->fx_addnumber = val;
+ break;
+
+ case BFD_RELOC_SH_COUNT:
+ case BFD_RELOC_SH_ALIGN:
+ case BFD_RELOC_SH_CODE:
+ case BFD_RELOC_SH_DATA:
+ case BFD_RELOC_SH_LABEL:
+ /* Nothing to do here. */
+ break;
+
+ case BFD_RELOC_SH_LOOP_START:
+ case BFD_RELOC_SH_LOOP_END:
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixP->fx_done = 0;
+ return;
+
+#ifdef OBJ_ELF
+ case BFD_RELOC_32_PLT_PCREL:
+ /* Make the jump instruction point to the address of the operand. At
+ runtime we merely add the offset to the actual PLT entry. */
+ * valP = 0xfffffffc;
+ val = fixP->fx_addnumber;
+ if (fixP->fx_subsy)
+ val -= S_GET_VALUE (fixP->fx_subsy);
+ md_number_to_chars (buf, val, 4);
+ break;
+
+ case BFD_RELOC_SH_GOTPC:
+ /* This is tough to explain. We end up with this one if we have
+ operands that look like "_GLOBAL_OFFSET_TABLE_+[.-.L284]".
+ The goal here is to obtain the absolute address of the GOT,
+ and it is strongly preferable from a performance point of
+ view to avoid using a runtime relocation for this. There are
+ cases where you have something like:
+
+ .long _GLOBAL_OFFSET_TABLE_+[.-.L66]
+
+ and here no correction would be required. Internally in the
+ assembler we treat operands of this form as not being pcrel
+ since the '.' is explicitly mentioned, and I wonder whether
+ it would simplify matters to do it this way. Who knows. In
+ earlier versions of the PIC patches, the pcrel_adjust field
+ was used to store the correction, but since the expression is
+ not pcrel, I felt it would be confusing to do it this way. */
+ * valP -= 1;
+ md_number_to_chars (buf, val, 4);
+ break;
+
+ case BFD_RELOC_32_GOT_PCREL:
+ case BFD_RELOC_SH_GOTPLT32:
+ * valP = 0; /* Fully resolved at runtime. No addend. */
+ md_number_to_chars (buf, 0, 4);
+ break;
+
+ case BFD_RELOC_32_GOTOFF:
+ md_number_to_chars (buf, val, 4);
+ break;
+#endif
+
+ default:
+#ifdef HAVE_SH64
+ shmedia_md_apply_fix3 (fixP, valP);
+ return;
+#else
+ abort ();
+#endif
+ }
+
+ if (shift != 0)
+ {
+ if ((val & ((1 << shift) - 1)) != 0)
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("misaligned offset"));
+ if (val >= 0)
+ val >>= shift;
+ else
+ val = ((val >> shift)
+ | ((long) -1 & ~ ((long) -1 >> shift)));
+ }
+ if (max != 0 && (val < min || val > max))
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("offset out of range"));
+
+ if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
+ fixP->fx_done = 1;
+}
+
+/* Called just before address relaxation. Return the length
+ by which a fragment must grow to reach it's destination. */
+
+int
+md_estimate_size_before_relax (fragP, segment_type)
+ register fragS *fragP;
+ register segT segment_type;
+{
+ int what;
+
+ switch (fragP->fr_subtype)
+ {
+ default:
+#ifdef HAVE_SH64
+ return shmedia_md_estimate_size_before_relax (fragP, segment_type);
+#else
+ abort ();
+#endif
+
+
+ case C (UNCOND_JUMP, UNDEF_DISP):
+ /* Used to be a branch to somewhere which was unknown. */
+ if (!fragP->fr_symbol)
+ {
+ fragP->fr_subtype = C (UNCOND_JUMP, UNCOND12);
+ }
+ else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
+ {
+ fragP->fr_subtype = C (UNCOND_JUMP, UNCOND12);
+ }
+ else
+ {
+ fragP->fr_subtype = C (UNCOND_JUMP, UNDEF_WORD_DISP);
+ }
+ break;
+
+ case C (COND_JUMP, UNDEF_DISP):
+ case C (COND_JUMP_DELAY, UNDEF_DISP):
+ what = GET_WHAT (fragP->fr_subtype);
+ /* Used to be a branch to somewhere which was unknown. */
+ if (fragP->fr_symbol
+ && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
+ {
+ /* Got a symbol and it's defined in this segment, become byte
+ sized - maybe it will fix up. */
+ fragP->fr_subtype = C (what, COND8);
+ }
+ else if (fragP->fr_symbol)
+ {
+ /* Its got a segment, but its not ours, so it will always be long. */
+ fragP->fr_subtype = C (what, UNDEF_WORD_DISP);
+ }
+ else
+ {
+ /* We know the abs value. */
+ fragP->fr_subtype = C (what, COND8);
+ }
+ break;
+
+ case C (UNCOND_JUMP, UNCOND12):
+ case C (UNCOND_JUMP, UNCOND32):
+ case C (UNCOND_JUMP, UNDEF_WORD_DISP):
+ case C (COND_JUMP, COND8):
+ case C (COND_JUMP, COND12):
+ case C (COND_JUMP, COND32):
+ case C (COND_JUMP, UNDEF_WORD_DISP):
+ case C (COND_JUMP_DELAY, COND8):
+ case C (COND_JUMP_DELAY, COND12):
+ case C (COND_JUMP_DELAY, COND32):
+ case C (COND_JUMP_DELAY, UNDEF_WORD_DISP):
+ /* When relaxing a section for the second time, we don't need to
+ do anything besides return the current size. */
+ break;
+ }
+
+ fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length;
+ return fragP->fr_var;
+}
+
+/* Put number into target byte order. */
+
+void
+md_number_to_chars (ptr, use, nbytes)
+ char *ptr;
+ valueT use;
+ int nbytes;
+{
+#ifdef HAVE_SH64
+ /* We might need to set the contents type to data. */
+ sh64_flag_output ();
+#endif
+
+ if (! target_big_endian)
+ number_to_chars_littleendian (ptr, use, nbytes);
+ else
+ number_to_chars_bigendian (ptr, use, nbytes);
+}
+
+/* This version is used in obj-coff.c when not using BFD_ASSEMBLER.
+ eg for the sh-hms target. */
+
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address + 2;
+}
+
+long
+md_pcrel_from_section (fixP, sec)
+ fixS *fixP;
+ segT sec;
+{
+ if (fixP->fx_addsy != (symbolS *) NULL
+ && (! S_IS_DEFINED (fixP->fx_addsy)
+ || S_IS_EXTERN (fixP->fx_addsy)
+ || S_IS_WEAK (fixP->fx_addsy)
+ || S_GET_SEGMENT (fixP->fx_addsy) != sec))
+ {
+ /* The symbol is undefined (or is defined but not in this section,
+ or we're not sure about it being the final definition). Let the
+ linker figure it out. We need to adjust the subtraction of a
+ symbol to the position of the relocated data, though. */
+ return fixP->fx_subsy ? fixP->fx_where + fixP->fx_frag->fr_address : 0;
+ }
+
+ return md_pcrel_from (fixP);
+}
+
+#ifdef OBJ_COFF
+
+int
+tc_coff_sizemachdep (frag)
+ fragS *frag;
+{
+ return md_relax_table[frag->fr_subtype].rlx_length;
+}
+
+#endif /* OBJ_COFF */
+
+#ifndef BFD_ASSEMBLER
+#ifdef OBJ_COFF
+
+/* Map BFD relocs to SH COFF relocs. */
+
+struct reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc;
+ int sh_reloc;
+};
+
+static const struct reloc_map coff_reloc_map[] =
+{
+ { BFD_RELOC_32, R_SH_IMM32 },
+ { BFD_RELOC_16, R_SH_IMM16 },
+ { BFD_RELOC_8, R_SH_IMM8 },
+ { BFD_RELOC_SH_PCDISP8BY2, R_SH_PCDISP8BY2 },
+ { BFD_RELOC_SH_PCDISP12BY2, R_SH_PCDISP },
+ { BFD_RELOC_SH_IMM4, R_SH_IMM4 },
+ { BFD_RELOC_SH_IMM4BY2, R_SH_IMM4BY2 },
+ { BFD_RELOC_SH_IMM4BY4, R_SH_IMM4BY4 },
+ { BFD_RELOC_SH_IMM8, R_SH_IMM8 },
+ { BFD_RELOC_SH_IMM8BY2, R_SH_IMM8BY2 },
+ { BFD_RELOC_SH_IMM8BY4, R_SH_IMM8BY4 },
+ { BFD_RELOC_SH_PCRELIMM8BY2, R_SH_PCRELIMM8BY2 },
+ { BFD_RELOC_SH_PCRELIMM8BY4, R_SH_PCRELIMM8BY4 },
+ { BFD_RELOC_8_PCREL, R_SH_SWITCH8 },
+ { BFD_RELOC_SH_SWITCH16, R_SH_SWITCH16 },
+ { BFD_RELOC_SH_SWITCH32, R_SH_SWITCH32 },
+ { BFD_RELOC_SH_USES, R_SH_USES },
+ { BFD_RELOC_SH_COUNT, R_SH_COUNT },
+ { BFD_RELOC_SH_ALIGN, R_SH_ALIGN },
+ { BFD_RELOC_SH_CODE, R_SH_CODE },
+ { BFD_RELOC_SH_DATA, R_SH_DATA },
+ { BFD_RELOC_SH_LABEL, R_SH_LABEL },
+ { BFD_RELOC_UNUSED, 0 }
+};
+
+/* Adjust a reloc for the SH. This is similar to the generic code,
+ but does some minor tweaking. */
+
+void
+sh_coff_reloc_mangle (seg, fix, intr, paddr)
+ segment_info_type *seg;
+ fixS *fix;
+ struct internal_reloc *intr;
+ unsigned int paddr;
+{
+ symbolS *symbol_ptr = fix->fx_addsy;
+ symbolS *dot;
+
+ intr->r_vaddr = paddr + fix->fx_frag->fr_address + fix->fx_where;
+
+ if (! SWITCH_TABLE (fix))
+ {
+ const struct reloc_map *rm;
+
+ for (rm = coff_reloc_map; rm->bfd_reloc != BFD_RELOC_UNUSED; rm++)
+ if (rm->bfd_reloc == (bfd_reloc_code_real_type) fix->fx_r_type)
+ break;
+ if (rm->bfd_reloc == BFD_RELOC_UNUSED)
+ as_bad_where (fix->fx_file, fix->fx_line,
+ _("Can not represent %s relocation in this object file format"),
+ bfd_get_reloc_code_name (fix->fx_r_type));
+ intr->r_type = rm->sh_reloc;
+ intr->r_offset = 0;
+ }
+ else
+ {
+ know (sh_relax);
+
+ if (fix->fx_r_type == BFD_RELOC_16)
+ intr->r_type = R_SH_SWITCH16;
+ else if (fix->fx_r_type == BFD_RELOC_8)
+ intr->r_type = R_SH_SWITCH8;
+ else if (fix->fx_r_type == BFD_RELOC_32)
+ intr->r_type = R_SH_SWITCH32;
+ else
+ abort ();
+
+ /* For a switch reloc, we set r_offset to the difference between
+ the reloc address and the subtrahend. When the linker is
+ doing relaxing, it can use the determine the starting and
+ ending points of the switch difference expression. */
+ intr->r_offset = intr->r_vaddr - S_GET_VALUE (fix->fx_subsy);
+ }
+
+ /* PC relative relocs are always against the current section. */
+ if (symbol_ptr == NULL)
+ {
+ switch (fix->fx_r_type)
+ {
+ case BFD_RELOC_SH_PCRELIMM8BY2:
+ case BFD_RELOC_SH_PCRELIMM8BY4:
+ case BFD_RELOC_SH_PCDISP8BY2:
+ case BFD_RELOC_SH_PCDISP12BY2:
+ case BFD_RELOC_SH_USES:
+ symbol_ptr = seg->dot;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (fix->fx_r_type == BFD_RELOC_SH_USES)
+ {
+ /* We can't store the offset in the object file, since this
+ reloc does not take up any space, so we store it in r_offset.
+ The fx_addnumber field was set in md_apply_fix3. */
+ intr->r_offset = fix->fx_addnumber;
+ }
+ else if (fix->fx_r_type == BFD_RELOC_SH_COUNT)
+ {
+ /* We can't store the count in the object file, since this reloc
+ does not take up any space, so we store it in r_offset. The
+ fx_offset field was set when the fixup was created in
+ sh_coff_frob_file. */
+ intr->r_offset = fix->fx_offset;
+ /* This reloc is always absolute. */
+ symbol_ptr = NULL;
+ }
+ else if (fix->fx_r_type == BFD_RELOC_SH_ALIGN)
+ {
+ /* Store the alignment in the r_offset field. */
+ intr->r_offset = fix->fx_offset;
+ /* This reloc is always absolute. */
+ symbol_ptr = NULL;
+ }
+ else if (fix->fx_r_type == BFD_RELOC_SH_CODE
+ || fix->fx_r_type == BFD_RELOC_SH_DATA
+ || fix->fx_r_type == BFD_RELOC_SH_LABEL)
+ {
+ /* These relocs are always absolute. */
+ symbol_ptr = NULL;
+ }
+
+ /* Turn the segment of the symbol into an offset. */
+ if (symbol_ptr != NULL)
+ {
+ dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
+ if (dot != NULL)
+ intr->r_symndx = dot->sy_number;
+ else
+ intr->r_symndx = symbol_ptr->sy_number;
+ }
+ else
+ intr->r_symndx = -1;
+}
+
+#endif /* OBJ_COFF */
+#endif /* ! BFD_ASSEMBLER */
+
+#ifdef BFD_ASSEMBLER
+
+/* Create a reloc. */
+
+arelent *
+tc_gen_reloc (section, fixp)
+ asection *section ATTRIBUTE_UNUSED;
+ fixS *fixp;
+{
+ arelent *rel;
+ bfd_reloc_code_real_type r_type;
+
+ rel = (arelent *) xmalloc (sizeof (arelent));
+ rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+ rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
+
+ if (fixp->fx_subsy
+ && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
+ {
+ fixp->fx_addnumber -= S_GET_VALUE (fixp->fx_subsy);
+ fixp->fx_subsy = 0;
+ }
+
+ r_type = fixp->fx_r_type;
+
+ if (SWITCH_TABLE (fixp))
+ {
+ rel->addend = rel->address - S_GET_VALUE (fixp->fx_subsy);
+ if (r_type == BFD_RELOC_16)
+ r_type = BFD_RELOC_SH_SWITCH16;
+ else if (r_type == BFD_RELOC_8)
+ r_type = BFD_RELOC_8_PCREL;
+ else if (r_type == BFD_RELOC_32)
+ r_type = BFD_RELOC_SH_SWITCH32;
+ else
+ abort ();
+ }
+ else if (r_type == BFD_RELOC_SH_USES)
+ rel->addend = fixp->fx_addnumber;
+ else if (r_type == BFD_RELOC_SH_COUNT)
+ rel->addend = fixp->fx_offset;
+ else if (r_type == BFD_RELOC_SH_ALIGN)
+ rel->addend = fixp->fx_offset;
+ else if (r_type == BFD_RELOC_VTABLE_INHERIT
+ || r_type == BFD_RELOC_VTABLE_ENTRY)
+ rel->addend = fixp->fx_offset;
+ else if (r_type == BFD_RELOC_SH_LOOP_START
+ || r_type == BFD_RELOC_SH_LOOP_END)
+ rel->addend = fixp->fx_offset;
+ else if (r_type == BFD_RELOC_SH_LABEL && fixp->fx_pcrel)
+ {
+ rel->addend = 0;
+ rel->address = rel->addend = fixp->fx_offset;
+ }
+#ifdef HAVE_SH64
+ else if (shmedia_init_reloc (rel, fixp))
+ ;
+#endif
+ else if (fixp->fx_pcrel)
+ rel->addend = fixp->fx_addnumber;
+ else if (r_type == BFD_RELOC_32 || r_type == BFD_RELOC_32_GOTOFF)
+ rel->addend = fixp->fx_addnumber;
+ else
+ rel->addend = 0;
+
+ rel->howto = bfd_reloc_type_lookup (stdoutput, r_type);
+ if (rel->howto == NULL || fixp->fx_subsy)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Cannot represent relocation type %s"),
+ bfd_get_reloc_code_name (r_type));
+ /* Set howto to a garbage value so that we can keep going. */
+ rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
+ assert (rel->howto != NULL);
+ }
+
+ return rel;
+}
+
+#ifdef OBJ_ELF
+inline static char *
+sh_end_of_match (cont, what)
+ char *cont, *what;
+{
+ int len = strlen (what);
+
+ if (strncasecmp (cont, what, strlen (what)) == 0
+ && ! is_part_of_name (cont[len]))
+ return cont + len;
+
+ return NULL;
+}
+
+int
+sh_parse_name (name, exprP, nextcharP)
+ char const *name;
+ expressionS *exprP;
+ char *nextcharP;
+{
+ char *next = input_line_pointer;
+ char *next_end;
+ int reloc_type;
+ segT segment;
+
+ exprP->X_op_symbol = NULL;
+
+ if (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0)
+ {
+ if (! GOT_symbol)
+ GOT_symbol = symbol_find_or_make (name);
+
+ exprP->X_add_symbol = GOT_symbol;
+ no_suffix:
+ /* If we have an absolute symbol or a reg, then we know its
+ value now. */
+ segment = S_GET_SEGMENT (exprP->X_add_symbol);
+ if (segment == absolute_section)
+ {
+ exprP->X_op = O_constant;
+ exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
+ exprP->X_add_symbol = NULL;
+ }
+ else if (segment == reg_section)
+ {
+ exprP->X_op = O_register;
+ exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
+ exprP->X_add_symbol = NULL;
+ }
+ else
+ {
+ exprP->X_op = O_symbol;
+ exprP->X_add_number = 0;
+ }
+
+ return 1;
+ }
+
+ exprP->X_add_symbol = symbol_find_or_make (name);
+
+ if (*nextcharP != '@')
+ goto no_suffix;
+ else if ((next_end = sh_end_of_match (next + 1, "GOTOFF")))
+ reloc_type = BFD_RELOC_32_GOTOFF;
+ else if ((next_end = sh_end_of_match (next + 1, "GOTPLT")))
+ reloc_type = BFD_RELOC_SH_GOTPLT32;
+ else if ((next_end = sh_end_of_match (next + 1, "GOT")))
+ reloc_type = BFD_RELOC_32_GOT_PCREL;
+ else if ((next_end = sh_end_of_match (next + 1, "PLT")))
+ reloc_type = BFD_RELOC_32_PLT_PCREL;
+ else
+ goto no_suffix;
+
+ *input_line_pointer = *nextcharP;
+ input_line_pointer = next_end;
+ *nextcharP = *input_line_pointer;
+ *input_line_pointer = '\0';
+
+ exprP->X_op = O_PIC_reloc;
+ exprP->X_add_number = 0;
+ exprP->X_md = reloc_type;
+
+ return 1;
+}
+#endif
+#endif /* BFD_ASSEMBLER */
diff --git a/x/binutils/gas/config/tc-sh.h b/x/binutils/gas/config/tc-sh.h
new file mode 100644
index 0000000..ffe948a
--- /dev/null
+++ b/x/binutils/gas/config/tc-sh.h
@@ -0,0 +1,232 @@
+/* This file is tc-sh.h
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#define TC_SH
+
+#define TARGET_ARCH bfd_arch_sh
+
+#if ANSI_PROTOTYPES
+struct segment_info_struct;
+struct internal_reloc;
+#endif
+
+/* Whether -relax was used. */
+extern int sh_relax;
+
+/* Whether -small was used. */
+extern int sh_small;
+
+/* Don't try to break words. */
+#define WORKING_DOT_WORD
+
+/* All SH instructions are multiples of 16 bits. */
+#define DWARF2_LINE_MIN_INSN_LENGTH 2
+
+/* We require .long, et. al., to be aligned correctly. */
+#define md_cons_align(nbytes) sh_cons_align (nbytes)
+extern void sh_cons_align PARAMS ((int));
+
+/* When relaxing, we need to generate relocations for alignment
+ directives. */
+#define HANDLE_ALIGN(frag) sh_handle_align (frag)
+extern void sh_handle_align PARAMS ((fragS *));
+
+#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 2)
+
+/* We need to force out some relocations when relaxing. */
+#define TC_FORCE_RELOCATION(fix) sh_force_relocation (fix)
+
+/* The type fixS is defined (to struct fix) in write.h, but write.h uses
+ definitions from this file. To avoid problems with including write.h
+ after the "right" definitions, don't; just forward-declare struct fix
+ here. */
+struct fix;
+extern int sh_force_relocation PARAMS ((struct fix *));
+
+#ifdef OBJ_ELF
+#define obj_fix_adjustable(fixP) sh_fix_adjustable(fixP)
+struct fix;
+extern boolean sh_fix_adjustable PARAMS ((struct fix *));
+
+/* This arranges for gas/write.c to not apply a relocation if
+ obj_fix_adjustable() says it is not adjustable. */
+/* ??? fixups with symbols in SEC_MERGE sections are marked with
+ obj_fix_adjustable and have a non-section symbol, as in
+ "vwxyz"+1 in execute/string-opt-6.c . Maybe the test of
+ (symbol_used_in_reloc_p should be done in the machine-independent code. */
+#define TC_FIX_ADJUSTABLE(fixP) \
+ (! symbol_used_in_reloc_p (fixP->fx_addsy) && obj_fix_adjustable (fixP))
+#endif
+
+#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC)
+extern long md_pcrel_from_section PARAMS ((struct fix *, segT));
+
+#define IGNORE_NONSTANDARD_ESCAPES
+
+#define LISTING_HEADER \
+ (!target_big_endian \
+ ? "Hitachi Super-H GAS Little Endian" : "Hitachi Super-H GAS Big Endian")
+
+#define md_operand(x)
+
+extern const struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+
+/* We record, for each section, whether we have most recently output a
+ CODE reloc or a DATA reloc. */
+struct sh_segment_info_type
+{
+ int in_code : 1;
+};
+#define TC_SEGMENT_INFO_TYPE struct sh_segment_info_type
+
+/* We call a routine to emit a reloc for a label, so that the linker
+ can align loads and stores without crossing a label. */
+extern void sh_frob_label PARAMS ((void));
+#define tc_frob_label(sym) sh_frob_label ()
+
+/* We call a routine to flush pending output in order to output a DATA
+ reloc when required. */
+extern void sh_flush_pending_output PARAMS ((void));
+#define md_flush_pending_output() sh_flush_pending_output ()
+
+#ifdef BFD_ASSEMBLER
+#define tc_frob_file_before_adjust sh_frob_file
+#else
+#define tc_frob_file sh_frob_file
+#endif
+extern void sh_frob_file PARAMS ((void));
+
+#ifdef OBJ_COFF
+/* COFF specific definitions. */
+
+#define DO_NOT_STRIP 0
+
+/* This macro translates between an internal fix and an coff reloc type */
+#define TC_COFF_FIX2RTYPE(fix) ((fix)->fx_r_type)
+
+#define BFD_ARCH TARGET_ARCH
+
+#define COFF_MAGIC (!target_big_endian ? SH_ARCH_MAGIC_LITTLE : SH_ARCH_MAGIC_BIG)
+
+/* We need to write out relocs which have not been completed. */
+#define TC_COUNT_RELOC(fix) ((fix)->fx_addsy != NULL)
+
+#define TC_RELOC_MANGLE(seg, fix, int, paddr) \
+ sh_coff_reloc_mangle ((seg), (fix), (int), (paddr))
+extern void sh_coff_reloc_mangle
+ PARAMS ((struct segment_info_struct *, struct fix *,
+ struct internal_reloc *, unsigned int));
+
+#define tc_coff_symbol_emit_hook(a) ; /* not used */
+
+#define NEED_FX_R_TYPE 1
+
+#define TC_KEEP_FX_OFFSET 1
+
+#define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep(frag)
+extern int tc_coff_sizemachdep PARAMS ((fragS *));
+
+#ifdef BFD_ASSEMBLER
+#define SEG_NAME(SEG) segment_name (SEG)
+#else
+#define SEG_NAME(SEG) obj_segment_name (SEG)
+#endif
+
+/* We align most sections to a 16 byte boundary. */
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \
+ (strncmp (SEG_NAME (SEG), ".stabstr", 8) == 0 \
+ ? 0 \
+ : ((strncmp (SEG_NAME (SEG), ".stab", 5) == 0 \
+ || strcmp (SEG_NAME (SEG), ".ctors") == 0 \
+ || strcmp (SEG_NAME (SEG), ".dtors") == 0) \
+ ? 2 \
+ : (sh_small ? 2 : 4)))
+
+#endif /* OBJ_COFF */
+
+#ifdef OBJ_ELF
+/* ELF specific definitions. */
+
+/* Whether or not the target is big endian */
+extern int target_big_endian;
+#ifdef TE_LINUX
+#define TARGET_FORMAT (!target_big_endian ? "elf32-sh-linux" : "elf32-shbig-linux")
+#elif defined(TE_NetBSD)
+#define TARGET_FORMAT (!target_big_endian ? "elf32-shl-nbsd" : "elf32-sh-nbsd")
+#else
+#define TARGET_FORMAT (!target_big_endian ? "elf32-shl" : "elf32-sh")
+#endif
+
+#define elf_tc_final_processing sh_elf_final_processing
+extern void sh_elf_final_processing PARAMS ((void));
+
+#define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs */
+
+#define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_"
+
+/* This is the relocation type for direct references to
+ GLOBAL_OFFSET_TABLE. It comes up in complicated expressions such
+ as _GLOBAL_OFFSET_TABLE_+[.-.L284], which cannot be expressed
+ normally with the regular expressions. The fixup specified here
+ when used at runtime implies that we should add the address of the
+ GOT to the specified location, and as a result we have simplified
+ the expression into something we can use. */
+#define TC_RELOC_GLOBAL_OFFSET_TABLE BFD_RELOC_SH_GOTPC
+
+/* This expression evaluates to false if the relocation is for a local object
+ for which we still want to do the relocation at runtime. True if we
+ are willing to perform this relocation while building the .o file.
+ This is only used for pcrel relocations, so GOTOFF does not need to be
+ checked here. I am not sure if some of the others are ever used with
+ pcrel, but it is easier to be safe than sorry.
+
+ We can't resolve references to the GOT or the PLT when creating the
+ object file, since these tables are only created by the linker.
+ Also, if the symbol is global, weak, common or not defined, the
+ assembler can't compute the appropriate reloc, since its location
+ can only be determined at link time. */
+
+#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \
+ ((FIX)->fx_r_type != BFD_RELOC_32_PLT_PCREL \
+ && (FIX)->fx_r_type != BFD_RELOC_32_GOT_PCREL \
+ && (FIX)->fx_r_type != BFD_RELOC_SH_GOTPC \
+ && ((FIX)->fx_addsy == NULL \
+ || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \
+ && ! S_IS_WEAK ((FIX)->fx_addsy) \
+ && S_IS_DEFINED ((FIX)->fx_addsy) \
+ && ! S_IS_COMMON ((FIX)->fx_addsy))))
+
+#define md_parse_name(name, exprP, nextcharP) \
+ sh_parse_name ((name), (exprP), (nextcharP))
+int sh_parse_name PARAMS ((char const *name,
+ expressionS *exprP,
+ char *nextchar));
+
+#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP) \
+ sh_cons_fix_new ((FRAG), (OFF), (LEN), (EXP))
+void sh_cons_fix_new PARAMS ((fragS *, int, int, expressionS *));
+
+/* This is used to construct expressions out of @GOTOFF, @PLT and @GOT
+ symbols. The relocation type is stored in X_md. */
+#define O_PIC_reloc O_md1
+
+#endif /* OBJ_ELF */
diff --git a/x/binutils/gas/config/tc-sparc.c b/x/binutils/gas/config/tc-sparc.c
new file mode 100644
index 0000000..ba6b4ed
--- /dev/null
+++ b/x/binutils/gas/config/tc-sparc.c
@@ -0,0 +1,4555 @@
+/* tc-sparc.c -- Assemble for the SPARC
+ Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with GAS; see the file COPYING. If not, write
+ to the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+
+#include "as.h"
+#include "safe-ctype.h"
+#include "subsegs.h"
+
+#include "opcode/sparc.h"
+#include "dw2gencfi.h"
+
+#ifdef OBJ_ELF
+#include "elf/sparc.h"
+#include "dwarf2dbg.h"
+#endif
+
+/* Some ancient Sun C compilers would not take such hex constants as
+ unsigned, and would end up sign-extending them to form an offsetT,
+ so use these constants instead. */
+#define U0xffffffff ((((unsigned long) 1 << 16) << 16) - 1)
+#define U0x80000000 ((((unsigned long) 1 << 16) << 15))
+
+static struct sparc_arch *lookup_arch PARAMS ((char *));
+static void init_default_arch PARAMS ((void));
+static int sparc_ip PARAMS ((char *, const struct sparc_opcode **));
+static int in_signed_range PARAMS ((bfd_signed_vma, bfd_signed_vma));
+static int in_unsigned_range PARAMS ((bfd_vma, bfd_vma));
+static int in_bitfield_range PARAMS ((bfd_signed_vma, bfd_signed_vma));
+static int sparc_ffs PARAMS ((unsigned int));
+static void synthetize_setuw PARAMS ((const struct sparc_opcode *));
+static void synthetize_setsw PARAMS ((const struct sparc_opcode *));
+static void synthetize_setx PARAMS ((const struct sparc_opcode *));
+static bfd_vma BSR PARAMS ((bfd_vma, int));
+static int cmp_reg_entry PARAMS ((const PTR, const PTR));
+static int parse_keyword_arg PARAMS ((int (*) (const char *), char **, int *));
+static int parse_const_expr_arg PARAMS ((char **, int *));
+static int get_expression PARAMS ((char *str));
+
+/* Default architecture. */
+/* ??? The default value should be V8, but sparclite support was added
+ by making it the default. GCC now passes -Asparclite, so maybe sometime in
+ the future we can set this to V8. */
+#ifndef DEFAULT_ARCH
+#define DEFAULT_ARCH "sparclite"
+#endif
+static char *default_arch = DEFAULT_ARCH;
+
+/* Non-zero if the initial values of `max_architecture' and `sparc_arch_size'
+ have been set. */
+static int default_init_p;
+
+/* Current architecture. We don't bump up unless necessary. */
+static enum sparc_opcode_arch_val current_architecture = SPARC_OPCODE_ARCH_V6;
+
+/* The maximum architecture level we can bump up to.
+ In a 32 bit environment, don't allow bumping up to v9 by default.
+ The native assembler works this way. The user is required to pass
+ an explicit argument before we'll create v9 object files. However, if
+ we don't see any v9 insns, a v8plus object file is not created. */
+static enum sparc_opcode_arch_val max_architecture;
+
+/* Either 32 or 64, selects file format. */
+static int sparc_arch_size;
+/* Initial (default) value, recorded separately in case a user option
+ changes the value before md_show_usage is called. */
+static int default_arch_size;
+
+#ifdef OBJ_ELF
+/* The currently selected v9 memory model. Currently only used for
+ ELF. */
+static enum { MM_TSO, MM_PSO, MM_RMO } sparc_memory_model = MM_RMO;
+#endif
+
+static int architecture_requested;
+static int warn_on_bump;
+
+/* If warn_on_bump and the needed architecture is higher than this
+ architecture, issue a warning. */
+static enum sparc_opcode_arch_val warn_after_architecture;
+
+/* Non-zero if as should generate error if an undeclared g[23] register
+ has been used in -64. */
+static int no_undeclared_regs;
+
+/* Non-zero if we should try to relax jumps and calls. */
+static int sparc_relax;
+
+/* Non-zero if we are generating PIC code. */
+int sparc_pic_code;
+
+/* Non-zero if we should give an error when misaligned data is seen. */
+static int enforce_aligned_data;
+
+extern int target_big_endian;
+
+static int target_little_endian_data;
+
+/* Symbols for global registers on v9. */
+static symbolS *globals[8];
+
+/* The dwarf2 data alignment, adjusted for 32 or 64 bit. */
+int sparc_cie_data_alignment;
+
+/* V9 and 86x have big and little endian data, but instructions are always big
+ endian. The sparclet has bi-endian support but both data and insns have
+ the same endianness. Global `target_big_endian' is used for data.
+ The following macro is used for instructions. */
+#ifndef INSN_BIG_ENDIAN
+#define INSN_BIG_ENDIAN (target_big_endian \
+ || default_arch_type == sparc86x \
+ || SPARC_OPCODE_ARCH_V9_P (max_architecture))
+#endif
+
+/* Handle of the OPCODE hash table. */
+static struct hash_control *op_hash;
+
+static int log2 PARAMS ((int));
+static void s_data1 PARAMS ((void));
+static void s_seg PARAMS ((int));
+static void s_proc PARAMS ((int));
+static void s_reserve PARAMS ((int));
+static void s_common PARAMS ((int));
+static void s_empty PARAMS ((int));
+static void s_uacons PARAMS ((int));
+static void s_ncons PARAMS ((int));
+#ifdef OBJ_ELF
+static void s_register PARAMS ((int));
+#endif
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ {"align", s_align_bytes, 0}, /* Defaulting is invalid (0). */
+ {"common", s_common, 0},
+ {"empty", s_empty, 0},
+ {"global", s_globl, 0},
+ {"half", cons, 2},
+ {"nword", s_ncons, 0},
+ {"optim", s_ignore, 0},
+ {"proc", s_proc, 0},
+ {"reserve", s_reserve, 0},
+ {"seg", s_seg, 0},
+ {"skip", s_space, 0},
+ {"word", cons, 4},
+ {"xword", cons, 8},
+ {"uahalf", s_uacons, 2},
+ {"uaword", s_uacons, 4},
+ {"uaxword", s_uacons, 8},
+#ifdef OBJ_ELF
+ /* These are specific to sparc/svr4. */
+ {"2byte", s_uacons, 2},
+ {"4byte", s_uacons, 4},
+ {"8byte", s_uacons, 8},
+ {"register", s_register, 0},
+#endif
+ {NULL, 0, 0},
+};
+
+/* Size of relocation record. */
+const int md_reloc_size = 12;
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful. */
+const char comment_chars[] = "!"; /* JF removed '|' from
+ comment_chars. */
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output. */
+/* Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output. */
+/* Also note that comments started like this one will always
+ work if '/' isn't otherwise defined. */
+const char line_comment_chars[] = "#";
+
+const char line_separator_chars[] = ";";
+
+/* Chars that can be used to separate mant from exp in floating point
+ nums. */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant.
+ As in 0f12.456
+ or 0d1.2345e12 */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
+ changed in read.c. Ideally it shouldn't have to know about it at all,
+ but nothing is ideal around here. */
+
+#define isoctal(c) ((unsigned) ((c) - '0') < '8')
+
+struct sparc_it
+ {
+ char *error;
+ unsigned long opcode;
+ struct nlist *nlistp;
+ expressionS exp;
+ expressionS exp2;
+ int pcrel;
+ bfd_reloc_code_real_type reloc;
+ };
+
+struct sparc_it the_insn, set_insn;
+
+static void output_insn
+ PARAMS ((const struct sparc_opcode *, struct sparc_it *));
+
+/* Table of arguments to -A.
+ The sparc_opcode_arch table in sparc-opc.c is insufficient and incorrect
+ for this use. That table is for opcodes only. This table is for opcodes
+ and file formats. */
+
+enum sparc_arch_types {v6, v7, v8, sparclet, sparclite, sparc86x, v8plus,
+ v8plusa, v9, v9a, v9b, v9_64};
+
+static struct sparc_arch {
+ char *name;
+ char *opcode_arch;
+ enum sparc_arch_types arch_type;
+ /* Default word size, as specified during configuration.
+ A value of zero means can't be used to specify default architecture. */
+ int default_arch_size;
+ /* Allowable arg to -A? */
+ int user_option_p;
+} sparc_arch_table[] = {
+ { "v6", "v6", v6, 0, 1 },
+ { "v7", "v7", v7, 0, 1 },
+ { "v8", "v8", v8, 32, 1 },
+ { "sparclet", "sparclet", sparclet, 32, 1 },
+ { "sparclite", "sparclite", sparclite, 32, 1 },
+ { "sparc86x", "sparclite", sparc86x, 32, 1 },
+ { "v8plus", "v9", v9, 0, 1 },
+ { "v8plusa", "v9a", v9, 0, 1 },
+ { "v8plusb", "v9b", v9, 0, 1 },
+ { "v9", "v9", v9, 0, 1 },
+ { "v9a", "v9a", v9, 0, 1 },
+ { "v9b", "v9b", v9, 0, 1 },
+ /* This exists to allow configure.in/Makefile.in to pass one
+ value to specify both the default machine and default word size. */
+ { "v9-64", "v9", v9, 64, 0 },
+ { NULL, NULL, v8, 0, 0 }
+};
+
+/* Variant of default_arch */
+static enum sparc_arch_types default_arch_type;
+
+static struct sparc_arch *
+lookup_arch (name)
+ char *name;
+{
+ struct sparc_arch *sa;
+
+ for (sa = &sparc_arch_table[0]; sa->name != NULL; sa++)
+ if (strcmp (sa->name, name) == 0)
+ break;
+ if (sa->name == NULL)
+ return NULL;
+ return sa;
+}
+
+/* Initialize the default opcode arch and word size from the default
+ architecture name. */
+
+static void
+init_default_arch ()
+{
+ struct sparc_arch *sa = lookup_arch (default_arch);
+
+ if (sa == NULL
+ || sa->default_arch_size == 0)
+ as_fatal (_("Invalid default architecture, broken assembler."));
+
+ max_architecture = sparc_opcode_lookup_arch (sa->opcode_arch);
+ if (max_architecture == SPARC_OPCODE_ARCH_BAD)
+ as_fatal (_("Bad opcode table, broken assembler."));
+ default_arch_size = sparc_arch_size = sa->default_arch_size;
+ default_init_p = 1;
+ default_arch_type = sa->arch_type;
+}
+
+/* Called by TARGET_FORMAT. */
+
+const char *
+sparc_target_format ()
+{
+ /* We don't get a chance to initialize anything before we're called,
+ so handle that now. */
+ if (! default_init_p)
+ init_default_arch ();
+
+#ifdef OBJ_AOUT
+#ifdef TE_NetBSD
+ return "a.out-sparc-netbsd";
+#else
+#ifdef TE_SPARCAOUT
+ if (target_big_endian)
+ return "a.out-sunos-big";
+ else if (default_arch_type == sparc86x && target_little_endian_data)
+ return "a.out-sunos-big";
+ else
+ return "a.out-sparc-little";
+#else
+ return "a.out-sunos-big";
+#endif
+#endif
+#endif
+
+#ifdef OBJ_BOUT
+ return "b.out.big";
+#endif
+
+#ifdef OBJ_COFF
+#ifdef TE_LYNX
+ return "coff-sparc-lynx";
+#else
+ return "coff-sparc";
+#endif
+#endif
+
+#ifdef OBJ_ELF
+ return sparc_arch_size == 64 ? "elf64-sparc" : "elf32-sparc";
+#endif
+
+ abort ();
+}
+
+/* md_parse_option
+ * Invocation line includes a switch not recognized by the base assembler.
+ * See if it's a processor-specific option. These are:
+ *
+ * -bump
+ * Warn on architecture bumps. See also -A.
+ *
+ * -Av6, -Av7, -Av8, -Asparclite, -Asparclet
+ * Standard 32 bit architectures.
+ * -Av9, -Av9a, -Av9b
+ * Sparc64 in either a 32 or 64 bit world (-32/-64 says which).
+ * This used to only mean 64 bits, but properly specifying it
+ * complicated gcc's ASM_SPECs, so now opcode selection is
+ * specified orthogonally to word size (except when specifying
+ * the default, but that is an internal implementation detail).
+ * -Av8plus, -Av8plusa, -Av8plusb
+ * Same as -Av9{,a,b}.
+ * -xarch=v8plus, -xarch=v8plusa, -xarch=v8plusb
+ * Same as -Av8plus{,a,b} -32, for compatibility with Sun's
+ * assembler.
+ * -xarch=v9, -xarch=v9a, -xarch=v9b
+ * Same as -Av9{,a,b} -64, for compatibility with Sun's
+ * assembler.
+ *
+ * Select the architecture and possibly the file format.
+ * Instructions or features not supported by the selected
+ * architecture cause fatal errors.
+ *
+ * The default is to start at v6, and bump the architecture up
+ * whenever an instruction is seen at a higher level. In 32 bit
+ * environments, v9 is not bumped up to, the user must pass
+ * -Av8plus{,a,b}.
+ *
+ * If -bump is specified, a warning is printing when bumping to
+ * higher levels.
+ *
+ * If an architecture is specified, all instructions must match
+ * that architecture. Any higher level instructions are flagged
+ * as errors. Note that in the 32 bit environment specifying
+ * -Av8plus does not automatically create a v8plus object file, a
+ * v9 insn must be seen.
+ *
+ * If both an architecture and -bump are specified, the
+ * architecture starts at the specified level, but bumps are
+ * warnings. Note that we can't set `current_architecture' to
+ * the requested level in this case: in the 32 bit environment,
+ * we still must avoid creating v8plus object files unless v9
+ * insns are seen.
+ *
+ * Note:
+ * Bumping between incompatible architectures is always an
+ * error. For example, from sparclite to v9.
+ */
+
+#ifdef OBJ_ELF
+const char *md_shortopts = "A:K:VQ:sq";
+#else
+#ifdef OBJ_AOUT
+const char *md_shortopts = "A:k";
+#else
+const char *md_shortopts = "A:";
+#endif
+#endif
+struct option md_longopts[] = {
+#define OPTION_BUMP (OPTION_MD_BASE)
+ {"bump", no_argument, NULL, OPTION_BUMP},
+#define OPTION_SPARC (OPTION_MD_BASE + 1)
+ {"sparc", no_argument, NULL, OPTION_SPARC},
+#define OPTION_XARCH (OPTION_MD_BASE + 2)
+ {"xarch", required_argument, NULL, OPTION_XARCH},
+#ifdef OBJ_ELF
+#define OPTION_32 (OPTION_MD_BASE + 3)
+ {"32", no_argument, NULL, OPTION_32},
+#define OPTION_64 (OPTION_MD_BASE + 4)
+ {"64", no_argument, NULL, OPTION_64},
+#define OPTION_TSO (OPTION_MD_BASE + 5)
+ {"TSO", no_argument, NULL, OPTION_TSO},
+#define OPTION_PSO (OPTION_MD_BASE + 6)
+ {"PSO", no_argument, NULL, OPTION_PSO},
+#define OPTION_RMO (OPTION_MD_BASE + 7)
+ {"RMO", no_argument, NULL, OPTION_RMO},
+#endif
+#ifdef SPARC_BIENDIAN
+#define OPTION_LITTLE_ENDIAN (OPTION_MD_BASE + 8)
+ {"EL", no_argument, NULL, OPTION_LITTLE_ENDIAN},
+#define OPTION_BIG_ENDIAN (OPTION_MD_BASE + 9)
+ {"EB", no_argument, NULL, OPTION_BIG_ENDIAN},
+#endif
+#define OPTION_ENFORCE_ALIGNED_DATA (OPTION_MD_BASE + 10)
+ {"enforce-aligned-data", no_argument, NULL, OPTION_ENFORCE_ALIGNED_DATA},
+#define OPTION_LITTLE_ENDIAN_DATA (OPTION_MD_BASE + 11)
+ {"little-endian-data", no_argument, NULL, OPTION_LITTLE_ENDIAN_DATA},
+#ifdef OBJ_ELF
+#define OPTION_NO_UNDECLARED_REGS (OPTION_MD_BASE + 12)
+ {"no-undeclared-regs", no_argument, NULL, OPTION_NO_UNDECLARED_REGS},
+#define OPTION_UNDECLARED_REGS (OPTION_MD_BASE + 13)
+ {"undeclared-regs", no_argument, NULL, OPTION_UNDECLARED_REGS},
+#endif
+#define OPTION_RELAX (OPTION_MD_BASE + 14)
+ {"relax", no_argument, NULL, OPTION_RELAX},
+#define OPTION_NO_RELAX (OPTION_MD_BASE + 15)
+ {"no-relax", no_argument, NULL, OPTION_NO_RELAX},
+ {NULL, no_argument, NULL, 0}
+};
+
+size_t md_longopts_size = sizeof (md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ /* We don't get a chance to initialize anything before we're called,
+ so handle that now. */
+ if (! default_init_p)
+ init_default_arch ();
+
+ switch (c)
+ {
+ case OPTION_BUMP:
+ warn_on_bump = 1;
+ warn_after_architecture = SPARC_OPCODE_ARCH_V6;
+ break;
+
+ case OPTION_XARCH:
+#ifdef OBJ_ELF
+ if (strncmp (arg, "v9", 2) != 0)
+ md_parse_option (OPTION_32, NULL);
+ else
+ md_parse_option (OPTION_64, NULL);
+#endif
+ /* Fall through. */
+
+ case 'A':
+ {
+ struct sparc_arch *sa;
+ enum sparc_opcode_arch_val opcode_arch;
+
+ sa = lookup_arch (arg);
+ if (sa == NULL
+ || ! sa->user_option_p)
+ {
+ if (c == OPTION_XARCH)
+ as_bad (_("invalid architecture -xarch=%s"), arg);
+ else
+ as_bad (_("invalid architecture -A%s"), arg);
+ return 0;
+ }
+
+ opcode_arch = sparc_opcode_lookup_arch (sa->opcode_arch);
+ if (opcode_arch == SPARC_OPCODE_ARCH_BAD)
+ as_fatal (_("Bad opcode table, broken assembler."));
+
+ max_architecture = opcode_arch;
+ architecture_requested = 1;
+ }
+ break;
+
+ case OPTION_SPARC:
+ /* Ignore -sparc, used by SunOS make default .s.o rule. */
+ break;
+
+ case OPTION_ENFORCE_ALIGNED_DATA:
+ enforce_aligned_data = 1;
+ break;
+
+#ifdef SPARC_BIENDIAN
+ case OPTION_LITTLE_ENDIAN:
+ target_big_endian = 0;
+ if (default_arch_type != sparclet)
+ as_fatal ("This target does not support -EL");
+ break;
+ case OPTION_LITTLE_ENDIAN_DATA:
+ target_little_endian_data = 1;
+ target_big_endian = 0;
+ if (default_arch_type != sparc86x
+ && default_arch_type != v9)
+ as_fatal ("This target does not support --little-endian-data");
+ break;
+ case OPTION_BIG_ENDIAN:
+ target_big_endian = 1;
+ break;
+#endif
+
+#ifdef OBJ_AOUT
+ case 'k':
+ sparc_pic_code = 1;
+ break;
+#endif
+
+#ifdef OBJ_ELF
+ case OPTION_32:
+ case OPTION_64:
+ {
+ const char **list, **l;
+
+ sparc_arch_size = c == OPTION_32 ? 32 : 64;
+ list = bfd_target_list ();
+ for (l = list; *l != NULL; l++)
+ {
+ if (sparc_arch_size == 32)
+ {
+ if (strcmp (*l, "elf32-sparc") == 0)
+ break;
+ }
+ else
+ {
+ if (strcmp (*l, "elf64-sparc") == 0)
+ break;
+ }
+ }
+ if (*l == NULL)
+ as_fatal (_("No compiled in support for %d bit object file format"),
+ sparc_arch_size);
+ free (list);
+ }
+ break;
+
+ case OPTION_TSO:
+ sparc_memory_model = MM_TSO;
+ break;
+
+ case OPTION_PSO:
+ sparc_memory_model = MM_PSO;
+ break;
+
+ case OPTION_RMO:
+ sparc_memory_model = MM_RMO;
+ break;
+
+ case 'V':
+ print_version_id ();
+ break;
+
+ case 'Q':
+ /* Qy - do emit .comment
+ Qn - do not emit .comment. */
+ break;
+
+ case 's':
+ /* Use .stab instead of .stab.excl. */
+ break;
+
+ case 'q':
+ /* quick -- Native assembler does fewer checks. */
+ break;
+
+ case 'K':
+ if (strcmp (arg, "PIC") != 0)
+ as_warn (_("Unrecognized option following -K"));
+ else
+ sparc_pic_code = 1;
+ break;
+
+ case OPTION_NO_UNDECLARED_REGS:
+ no_undeclared_regs = 1;
+ break;
+
+ case OPTION_UNDECLARED_REGS:
+ no_undeclared_regs = 0;
+ break;
+#endif
+
+ case OPTION_RELAX:
+ sparc_relax = 1;
+ break;
+
+ case OPTION_NO_RELAX:
+ sparc_relax = 0;
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ const struct sparc_arch *arch;
+ int column;
+
+ /* We don't get a chance to initialize anything before we're called,
+ so handle that now. */
+ if (! default_init_p)
+ init_default_arch ();
+
+ fprintf (stream, _("SPARC options:\n"));
+ column = 0;
+ for (arch = &sparc_arch_table[0]; arch->name; arch++)
+ {
+ if (!arch->user_option_p)
+ continue;
+ if (arch != &sparc_arch_table[0])
+ fprintf (stream, " | ");
+ if (column + strlen (arch->name) > 70)
+ {
+ column = 0;
+ fputc ('\n', stream);
+ }
+ column += 5 + 2 + strlen (arch->name);
+ fprintf (stream, "-A%s", arch->name);
+ }
+ for (arch = &sparc_arch_table[0]; arch->name; arch++)
+ {
+ if (!arch->user_option_p)
+ continue;
+ fprintf (stream, " | ");
+ if (column + strlen (arch->name) > 65)
+ {
+ column = 0;
+ fputc ('\n', stream);
+ }
+ column += 5 + 7 + strlen (arch->name);
+ fprintf (stream, "-xarch=%s", arch->name);
+ }
+ fprintf (stream, _("\n\
+ specify variant of SPARC architecture\n\
+-bump warn when assembler switches architectures\n\
+-sparc ignored\n\
+--enforce-aligned-data force .long, etc., to be aligned correctly\n\
+-relax relax jumps and branches (default)\n\
+-no-relax avoid changing any jumps and branches\n"));
+#ifdef OBJ_AOUT
+ fprintf (stream, _("\
+-k generate PIC\n"));
+#endif
+#ifdef OBJ_ELF
+ fprintf (stream, _("\
+-32 create 32 bit object file\n\
+-64 create 64 bit object file\n"));
+ fprintf (stream, _("\
+ [default is %d]\n"), default_arch_size);
+ fprintf (stream, _("\
+-TSO use Total Store Ordering\n\
+-PSO use Partial Store Ordering\n\
+-RMO use Relaxed Memory Ordering\n"));
+ fprintf (stream, _("\
+ [default is %s]\n"), (default_arch_size == 64) ? "RMO" : "TSO");
+ fprintf (stream, _("\
+-KPIC generate PIC\n\
+-V print assembler version number\n\
+-undeclared-regs ignore application global register usage without\n\
+ appropriate .register directive (default)\n\
+-no-undeclared-regs force error on application global register usage\n\
+ without appropriate .register directive\n\
+-q ignored\n\
+-Qy, -Qn ignored\n\
+-s ignored\n"));
+#endif
+#ifdef SPARC_BIENDIAN
+ fprintf (stream, _("\
+-EL generate code for a little endian machine\n\
+-EB generate code for a big endian machine\n\
+--little-endian-data generate code for a machine having big endian\n\
+ instructions and little endian data.\n"));
+#endif
+}
+
+/* Native operand size opcode translation. */
+struct
+ {
+ char *name;
+ char *name32;
+ char *name64;
+ } native_op_table[] =
+{
+ {"ldn", "ld", "ldx"},
+ {"ldna", "lda", "ldxa"},
+ {"stn", "st", "stx"},
+ {"stna", "sta", "stxa"},
+ {"slln", "sll", "sllx"},
+ {"srln", "srl", "srlx"},
+ {"sran", "sra", "srax"},
+ {"casn", "cas", "casx"},
+ {"casna", "casa", "casxa"},
+ {"clrn", "clr", "clrx"},
+ {NULL, NULL, NULL},
+};
+
+/* sparc64 privileged registers. */
+
+struct priv_reg_entry
+{
+ char *name;
+ int regnum;
+};
+
+struct priv_reg_entry priv_reg_table[] =
+{
+ {"tpc", 0},
+ {"tnpc", 1},
+ {"tstate", 2},
+ {"tt", 3},
+ {"tick", 4},
+ {"tba", 5},
+ {"pstate", 6},
+ {"tl", 7},
+ {"pil", 8},
+ {"cwp", 9},
+ {"cansave", 10},
+ {"canrestore", 11},
+ {"cleanwin", 12},
+ {"otherwin", 13},
+ {"wstate", 14},
+ {"fq", 15},
+ {"ver", 31},
+ {"", -1}, /* End marker. */
+};
+
+/* v9a specific asrs. */
+
+struct priv_reg_entry v9a_asr_table[] =
+{
+ {"tick_cmpr", 23},
+ {"sys_tick_cmpr", 25},
+ {"sys_tick", 24},
+ {"softint", 22},
+ {"set_softint", 20},
+ {"pic", 17},
+ {"pcr", 16},
+ {"gsr", 19},
+ {"dcr", 18},
+ {"clear_softint", 21},
+ {"", -1}, /* End marker. */
+};
+
+static int
+cmp_reg_entry (parg, qarg)
+ const PTR parg;
+ const PTR qarg;
+{
+ const struct priv_reg_entry *p = (const struct priv_reg_entry *) parg;
+ const struct priv_reg_entry *q = (const struct priv_reg_entry *) qarg;
+
+ return strcmp (q->name, p->name);
+}
+
+/* This function is called once, at assembler startup time. It should
+ set up all the tables, etc. that the MD part of the assembler will
+ need. */
+
+void
+md_begin ()
+{
+ register const char *retval = NULL;
+ int lose = 0;
+ register unsigned int i = 0;
+
+ /* We don't get a chance to initialize anything before md_parse_option
+ is called, and it may not be called, so handle default initialization
+ now if not already done. */
+ if (! default_init_p)
+ init_default_arch ();
+
+ sparc_cie_data_alignment = sparc_arch_size == 64 ? -8 : -4;
+ op_hash = hash_new ();
+
+ while (i < (unsigned int) sparc_num_opcodes)
+ {
+ const char *name = sparc_opcodes[i].name;
+ retval = hash_insert (op_hash, name, (PTR) &sparc_opcodes[i]);
+ if (retval != NULL)
+ {
+ as_bad (_("Internal error: can't hash `%s': %s\n"),
+ sparc_opcodes[i].name, retval);
+ lose = 1;
+ }
+ do
+ {
+ if (sparc_opcodes[i].match & sparc_opcodes[i].lose)
+ {
+ as_bad (_("Internal error: losing opcode: `%s' \"%s\"\n"),
+ sparc_opcodes[i].name, sparc_opcodes[i].args);
+ lose = 1;
+ }
+ ++i;
+ }
+ while (i < (unsigned int) sparc_num_opcodes
+ && !strcmp (sparc_opcodes[i].name, name));
+ }
+
+ for (i = 0; native_op_table[i].name; i++)
+ {
+ const struct sparc_opcode *insn;
+ char *name = ((sparc_arch_size == 32)
+ ? native_op_table[i].name32
+ : native_op_table[i].name64);
+ insn = (struct sparc_opcode *) hash_find (op_hash, name);
+ if (insn == NULL)
+ {
+ as_bad (_("Internal error: can't find opcode `%s' for `%s'\n"),
+ name, native_op_table[i].name);
+ lose = 1;
+ }
+ else
+ {
+ retval = hash_insert (op_hash, native_op_table[i].name, (PTR) insn);
+ if (retval != NULL)
+ {
+ as_bad (_("Internal error: can't hash `%s': %s\n"),
+ sparc_opcodes[i].name, retval);
+ lose = 1;
+ }
+ }
+ }
+
+ if (lose)
+ as_fatal (_("Broken assembler. No assembly attempted."));
+
+ qsort (priv_reg_table, sizeof (priv_reg_table) / sizeof (priv_reg_table[0]),
+ sizeof (priv_reg_table[0]), cmp_reg_entry);
+
+ /* If -bump, record the architecture level at which we start issuing
+ warnings. The behaviour is different depending upon whether an
+ architecture was explicitly specified. If it wasn't, we issue warnings
+ for all upwards bumps. If it was, we don't start issuing warnings until
+ we need to bump beyond the requested architecture or when we bump between
+ conflicting architectures. */
+
+ if (warn_on_bump
+ && architecture_requested)
+ {
+ /* `max_architecture' records the requested architecture.
+ Issue warnings if we go above it. */
+ warn_after_architecture = max_architecture;
+
+ /* Find the highest architecture level that doesn't conflict with
+ the requested one. */
+ for (max_architecture = SPARC_OPCODE_ARCH_MAX;
+ max_architecture > warn_after_architecture;
+ --max_architecture)
+ if (! SPARC_OPCODE_CONFLICT_P (max_architecture,
+ warn_after_architecture))
+ break;
+ }
+}
+
+/* Called after all assembly has been done. */
+
+void
+sparc_md_end ()
+{
+ unsigned long mach = bfd_mach_sparc;
+
+ if (sparc_arch_size == 64)
+ switch (current_architecture)
+ {
+ case SPARC_OPCODE_ARCH_V9A: mach = bfd_mach_sparc_v9a; break;
+ case SPARC_OPCODE_ARCH_V9B: mach = bfd_mach_sparc_v9b; break;
+ default: mach = bfd_mach_sparc_v9; break;
+ }
+ else
+ switch (current_architecture)
+ {
+ case SPARC_OPCODE_ARCH_SPARCLET: mach = bfd_mach_sparc_sparclet; break;
+ case SPARC_OPCODE_ARCH_V9: mach = bfd_mach_sparc_v8plus; break;
+ case SPARC_OPCODE_ARCH_V9A: mach = bfd_mach_sparc_v8plusa; break;
+ case SPARC_OPCODE_ARCH_V9B: mach = bfd_mach_sparc_v8plusb; break;
+ /* The sparclite is treated like a normal sparc. Perhaps it shouldn't
+ be but for now it is (since that's the way it's always been
+ treated). */
+ default: break;
+ }
+ bfd_set_arch_mach (stdoutput, bfd_arch_sparc, mach);
+}
+
+/* Return non-zero if VAL is in the range -(MAX+1) to MAX. */
+
+static INLINE int
+in_signed_range (val, max)
+ bfd_signed_vma val, max;
+{
+ if (max <= 0)
+ abort ();
+ /* Sign-extend the value from the architecture word size, so that
+ 0xffffffff is always considered -1 on sparc32. */
+ if (sparc_arch_size == 32)
+ {
+ bfd_signed_vma sign = (bfd_signed_vma) 1 << 31;
+ val = ((val & U0xffffffff) ^ sign) - sign;
+ }
+ if (val > max)
+ return 0;
+ if (val < ~max)
+ return 0;
+ return 1;
+}
+
+/* Return non-zero if VAL is in the range 0 to MAX. */
+
+static INLINE int
+in_unsigned_range (val, max)
+ bfd_vma val, max;
+{
+ if (val > max)
+ return 0;
+ return 1;
+}
+
+/* Return non-zero if VAL is in the range -(MAX/2+1) to MAX.
+ (e.g. -15 to +31). */
+
+static INLINE int
+in_bitfield_range (val, max)
+ bfd_signed_vma val, max;
+{
+ if (max <= 0)
+ abort ();
+ if (val > max)
+ return 0;
+ if (val < ~(max >> 1))
+ return 0;
+ return 1;
+}
+
+static int
+sparc_ffs (mask)
+ unsigned int mask;
+{
+ int i;
+
+ if (mask == 0)
+ return -1;
+
+ for (i = 0; (mask & 1) == 0; ++i)
+ mask >>= 1;
+ return i;
+}
+
+/* Implement big shift right. */
+static bfd_vma
+BSR (val, amount)
+ bfd_vma val;
+ int amount;
+{
+ if (sizeof (bfd_vma) <= 4 && amount >= 32)
+ as_fatal (_("Support for 64-bit arithmetic not compiled in."));
+ return val >> amount;
+}
+
+/* For communication between sparc_ip and get_expression. */
+static char *expr_end;
+
+/* Values for `special_case'.
+ Instructions that require wierd handling because they're longer than
+ 4 bytes. */
+#define SPECIAL_CASE_NONE 0
+#define SPECIAL_CASE_SET 1
+#define SPECIAL_CASE_SETSW 2
+#define SPECIAL_CASE_SETX 3
+/* FIXME: sparc-opc.c doesn't have necessary "S" trigger to enable this. */
+#define SPECIAL_CASE_FDIV 4
+
+/* Bit masks of various insns. */
+#define NOP_INSN 0x01000000
+#define OR_INSN 0x80100000
+#define XOR_INSN 0x80180000
+#define FMOVS_INSN 0x81A00020
+#define SETHI_INSN 0x01000000
+#define SLLX_INSN 0x81281000
+#define SRA_INSN 0x81380000
+
+/* The last instruction to be assembled. */
+static const struct sparc_opcode *last_insn;
+/* The assembled opcode of `last_insn'. */
+static unsigned long last_opcode;
+
+/* Handle the set and setuw synthetic instructions. */
+
+static void
+synthetize_setuw (insn)
+ const struct sparc_opcode *insn;
+{
+ int need_hi22_p = 0;
+ int rd = (the_insn.opcode & RD (~0)) >> 25;
+
+ if (the_insn.exp.X_op == O_constant)
+ {
+ if (SPARC_OPCODE_ARCH_V9_P (max_architecture))
+ {
+ if (sizeof (offsetT) > 4
+ && (the_insn.exp.X_add_number < 0
+ || the_insn.exp.X_add_number > (offsetT) U0xffffffff))
+ as_warn (_("set: number not in 0..4294967295 range"));
+ }
+ else
+ {
+ if (sizeof (offsetT) > 4
+ && (the_insn.exp.X_add_number < -(offsetT) U0x80000000
+ || the_insn.exp.X_add_number > (offsetT) U0xffffffff))
+ as_warn (_("set: number not in -2147483648..4294967295 range"));
+ the_insn.exp.X_add_number = (int) the_insn.exp.X_add_number;
+ }
+ }
+
+ /* See if operand is absolute and small; skip sethi if so. */
+ if (the_insn.exp.X_op != O_constant
+ || the_insn.exp.X_add_number >= (1 << 12)
+ || the_insn.exp.X_add_number < -(1 << 12))
+ {
+ the_insn.opcode = (SETHI_INSN | RD (rd)
+ | ((the_insn.exp.X_add_number >> 10)
+ & (the_insn.exp.X_op == O_constant
+ ? 0x3fffff : 0)));
+ the_insn.reloc = (the_insn.exp.X_op != O_constant
+ ? BFD_RELOC_HI22 : BFD_RELOC_NONE);
+ output_insn (insn, &the_insn);
+ need_hi22_p = 1;
+ }
+
+ /* See if operand has no low-order bits; skip OR if so. */
+ if (the_insn.exp.X_op != O_constant
+ || (need_hi22_p && (the_insn.exp.X_add_number & 0x3FF) != 0)
+ || ! need_hi22_p)
+ {
+ the_insn.opcode = (OR_INSN | (need_hi22_p ? RS1 (rd) : 0)
+ | RD (rd) | IMMED
+ | (the_insn.exp.X_add_number
+ & (the_insn.exp.X_op != O_constant
+ ? 0 : need_hi22_p ? 0x3ff : 0x1fff)));
+ the_insn.reloc = (the_insn.exp.X_op != O_constant
+ ? BFD_RELOC_LO10 : BFD_RELOC_NONE);
+ output_insn (insn, &the_insn);
+ }
+}
+
+/* Handle the setsw synthetic instruction. */
+
+static void
+synthetize_setsw (insn)
+ const struct sparc_opcode *insn;
+{
+ int low32, rd, opc;
+
+ rd = (the_insn.opcode & RD (~0)) >> 25;
+
+ if (the_insn.exp.X_op != O_constant)
+ {
+ synthetize_setuw (insn);
+
+ /* Need to sign extend it. */
+ the_insn.opcode = (SRA_INSN | RS1 (rd) | RD (rd));
+ the_insn.reloc = BFD_RELOC_NONE;
+ output_insn (insn, &the_insn);
+ return;
+ }
+
+ if (sizeof (offsetT) > 4
+ && (the_insn.exp.X_add_number < -(offsetT) U0x80000000
+ || the_insn.exp.X_add_number > (offsetT) U0xffffffff))
+ as_warn (_("setsw: number not in -2147483648..4294967295 range"));
+
+ low32 = the_insn.exp.X_add_number;
+
+ if (low32 >= 0)
+ {
+ synthetize_setuw (insn);
+ return;
+ }
+
+ opc = OR_INSN;
+
+ the_insn.reloc = BFD_RELOC_NONE;
+ /* See if operand is absolute and small; skip sethi if so. */
+ if (low32 < -(1 << 12))
+ {
+ the_insn.opcode = (SETHI_INSN | RD (rd)
+ | (((~the_insn.exp.X_add_number) >> 10) & 0x3fffff));
+ output_insn (insn, &the_insn);
+ low32 = 0x1c00 | (low32 & 0x3ff);
+ opc = RS1 (rd) | XOR_INSN;
+ }
+
+ the_insn.opcode = (opc | RD (rd) | IMMED
+ | (low32 & 0x1fff));
+ output_insn (insn, &the_insn);
+}
+
+/* Handle the setsw synthetic instruction. */
+
+static void
+synthetize_setx (insn)
+ const struct sparc_opcode *insn;
+{
+ int upper32, lower32;
+ int tmpreg = (the_insn.opcode & RS1 (~0)) >> 14;
+ int dstreg = (the_insn.opcode & RD (~0)) >> 25;
+ int upper_dstreg;
+ int need_hh22_p = 0, need_hm10_p = 0, need_hi22_p = 0, need_lo10_p = 0;
+ int need_xor10_p = 0;
+
+#define SIGNEXT32(x) ((((x) & U0xffffffff) ^ U0x80000000) - U0x80000000)
+ lower32 = SIGNEXT32 (the_insn.exp.X_add_number);
+ upper32 = SIGNEXT32 (BSR (the_insn.exp.X_add_number, 32));
+#undef SIGNEXT32
+
+ upper_dstreg = tmpreg;
+ /* The tmp reg should not be the dst reg. */
+ if (tmpreg == dstreg)
+ as_warn (_("setx: temporary register same as destination register"));
+
+ /* ??? Obviously there are other optimizations we can do
+ (e.g. sethi+shift for 0x1f0000000) and perhaps we shouldn't be
+ doing some of these. Later. If you do change things, try to
+ change all of this to be table driven as well. */
+ /* What to output depends on the number if it's constant.
+ Compute that first, then output what we've decided upon. */
+ if (the_insn.exp.X_op != O_constant)
+ {
+ if (sparc_arch_size == 32)
+ {
+ /* When arch size is 32, we want setx to be equivalent
+ to setuw for anything but constants. */
+ the_insn.exp.X_add_number &= 0xffffffff;
+ synthetize_setuw (insn);
+ return;
+ }
+ need_hh22_p = need_hm10_p = need_hi22_p = need_lo10_p = 1;
+ lower32 = 0;
+ upper32 = 0;
+ }
+ else
+ {
+ /* Reset X_add_number, we've extracted it as upper32/lower32.
+ Otherwise fixup_segment will complain about not being able to
+ write an 8 byte number in a 4 byte field. */
+ the_insn.exp.X_add_number = 0;
+
+ /* Only need hh22 if `or' insn can't handle constant. */
+ if (upper32 < -(1 << 12) || upper32 >= (1 << 12))
+ need_hh22_p = 1;
+
+ /* Does bottom part (after sethi) have bits? */
+ if ((need_hh22_p && (upper32 & 0x3ff) != 0)
+ /* No hh22, but does upper32 still have bits we can't set
+ from lower32? */
+ || (! need_hh22_p && upper32 != 0 && upper32 != -1))
+ need_hm10_p = 1;
+
+ /* If the lower half is all zero, we build the upper half directly
+ into the dst reg. */
+ if (lower32 != 0
+ /* Need lower half if number is zero or 0xffffffff00000000. */
+ || (! need_hh22_p && ! need_hm10_p))
+ {
+ /* No need for sethi if `or' insn can handle constant. */
+ if (lower32 < -(1 << 12) || lower32 >= (1 << 12)
+ /* Note that we can't use a negative constant in the `or'
+ insn unless the upper 32 bits are all ones. */
+ || (lower32 < 0 && upper32 != -1)
+ || (lower32 >= 0 && upper32 == -1))
+ need_hi22_p = 1;
+
+ if (need_hi22_p && upper32 == -1)
+ need_xor10_p = 1;
+
+ /* Does bottom part (after sethi) have bits? */
+ else if ((need_hi22_p && (lower32 & 0x3ff) != 0)
+ /* No sethi. */
+ || (! need_hi22_p && (lower32 & 0x1fff) != 0)
+ /* Need `or' if we didn't set anything else. */
+ || (! need_hi22_p && ! need_hh22_p && ! need_hm10_p))
+ need_lo10_p = 1;
+ }
+ else
+ /* Output directly to dst reg if lower 32 bits are all zero. */
+ upper_dstreg = dstreg;
+ }
+
+ if (!upper_dstreg && dstreg)
+ as_warn (_("setx: illegal temporary register g0"));
+
+ if (need_hh22_p)
+ {
+ the_insn.opcode = (SETHI_INSN | RD (upper_dstreg)
+ | ((upper32 >> 10) & 0x3fffff));
+ the_insn.reloc = (the_insn.exp.X_op != O_constant
+ ? BFD_RELOC_SPARC_HH22 : BFD_RELOC_NONE);
+ output_insn (insn, &the_insn);
+ }
+
+ if (need_hi22_p)
+ {
+ the_insn.opcode = (SETHI_INSN | RD (dstreg)
+ | (((need_xor10_p ? ~lower32 : lower32)
+ >> 10) & 0x3fffff));
+ the_insn.reloc = (the_insn.exp.X_op != O_constant
+ ? BFD_RELOC_SPARC_LM22 : BFD_RELOC_NONE);
+ output_insn (insn, &the_insn);
+ }
+
+ if (need_hm10_p)
+ {
+ the_insn.opcode = (OR_INSN
+ | (need_hh22_p ? RS1 (upper_dstreg) : 0)
+ | RD (upper_dstreg)
+ | IMMED
+ | (upper32 & (need_hh22_p ? 0x3ff : 0x1fff)));
+ the_insn.reloc = (the_insn.exp.X_op != O_constant
+ ? BFD_RELOC_SPARC_HM10 : BFD_RELOC_NONE);
+ output_insn (insn, &the_insn);
+ }
+
+ if (need_lo10_p)
+ {
+ /* FIXME: One nice optimization to do here is to OR the low part
+ with the highpart if hi22 isn't needed and the low part is
+ positive. */
+ the_insn.opcode = (OR_INSN | (need_hi22_p ? RS1 (dstreg) : 0)
+ | RD (dstreg)
+ | IMMED
+ | (lower32 & (need_hi22_p ? 0x3ff : 0x1fff)));
+ the_insn.reloc = (the_insn.exp.X_op != O_constant
+ ? BFD_RELOC_LO10 : BFD_RELOC_NONE);
+ output_insn (insn, &the_insn);
+ }
+
+ /* If we needed to build the upper part, shift it into place. */
+ if (need_hh22_p || need_hm10_p)
+ {
+ the_insn.opcode = (SLLX_INSN | RS1 (upper_dstreg) | RD (upper_dstreg)
+ | IMMED | 32);
+ the_insn.reloc = BFD_RELOC_NONE;
+ output_insn (insn, &the_insn);
+ }
+
+ /* To get -1 in upper32, we do sethi %hi(~x), r; xor r, -0x400 | x, r. */
+ if (need_xor10_p)
+ {
+ the_insn.opcode = (XOR_INSN | RS1 (dstreg) | RD (dstreg) | IMMED
+ | 0x1c00 | (lower32 & 0x3ff));
+ the_insn.reloc = BFD_RELOC_NONE;
+ output_insn (insn, &the_insn);
+ }
+
+ /* If we needed to build both upper and lower parts, OR them together. */
+ else if ((need_hh22_p || need_hm10_p) && (need_hi22_p || need_lo10_p))
+ {
+ the_insn.opcode = (OR_INSN | RS1 (dstreg) | RS2 (upper_dstreg)
+ | RD (dstreg));
+ the_insn.reloc = BFD_RELOC_NONE;
+ output_insn (insn, &the_insn);
+ }
+}
+
+/* Main entry point to assemble one instruction. */
+
+void
+md_assemble (str)
+ char *str;
+{
+ const struct sparc_opcode *insn;
+ int special_case;
+
+ know (str);
+ special_case = sparc_ip (str, &insn);
+
+ /* We warn about attempts to put a floating point branch in a delay slot,
+ unless the delay slot has been annulled. */
+ if (insn != NULL
+ && last_insn != NULL
+ && (insn->flags & F_FBR) != 0
+ && (last_insn->flags & F_DELAYED) != 0
+ /* ??? This test isn't completely accurate. We assume anything with
+ F_{UNBR,CONDBR,FBR} set is annullable. */
+ && ((last_insn->flags & (F_UNBR | F_CONDBR | F_FBR)) == 0
+ || (last_opcode & ANNUL) == 0))
+ as_warn (_("FP branch in delay slot"));
+
+ /* SPARC before v9 requires a nop instruction between a floating
+ point instruction and a floating point branch. We insert one
+ automatically, with a warning. */
+ if (max_architecture < SPARC_OPCODE_ARCH_V9
+ && insn != NULL
+ && last_insn != NULL
+ && (insn->flags & F_FBR) != 0
+ && (last_insn->flags & F_FLOAT) != 0)
+ {
+ struct sparc_it nop_insn;
+
+ nop_insn.opcode = NOP_INSN;
+ nop_insn.reloc = BFD_RELOC_NONE;
+ output_insn (insn, &nop_insn);
+ as_warn (_("FP branch preceded by FP instruction; NOP inserted"));
+ }
+
+ switch (special_case)
+ {
+ case SPECIAL_CASE_NONE:
+ /* Normal insn. */
+ output_insn (insn, &the_insn);
+ break;
+
+ case SPECIAL_CASE_SETSW:
+ synthetize_setsw (insn);
+ break;
+
+ case SPECIAL_CASE_SET:
+ synthetize_setuw (insn);
+ break;
+
+ case SPECIAL_CASE_SETX:
+ synthetize_setx (insn);
+ break;
+
+ case SPECIAL_CASE_FDIV:
+ {
+ int rd = (the_insn.opcode >> 25) & 0x1f;
+
+ output_insn (insn, &the_insn);
+
+ /* According to information leaked from Sun, the "fdiv" instructions
+ on early SPARC machines would produce incorrect results sometimes.
+ The workaround is to add an fmovs of the destination register to
+ itself just after the instruction. This was true on machines
+ with Weitek 1165 float chips, such as the Sun-4/260 and /280. */
+ assert (the_insn.reloc == BFD_RELOC_NONE);
+ the_insn.opcode = FMOVS_INSN | rd | RD (rd);
+ output_insn (insn, &the_insn);
+ return;
+ }
+
+ default:
+ as_fatal (_("failed special case insn sanity check"));
+ }
+}
+
+/* Subroutine of md_assemble to do the actual parsing. */
+
+static int
+sparc_ip (str, pinsn)
+ char *str;
+ const struct sparc_opcode **pinsn;
+{
+ char *error_message = "";
+ char *s;
+ const char *args;
+ char c;
+ const struct sparc_opcode *insn;
+ char *argsStart;
+ unsigned long opcode;
+ unsigned int mask = 0;
+ int match = 0;
+ int comma = 0;
+ int v9_arg_p;
+ int special_case = SPECIAL_CASE_NONE;
+
+ s = str;
+ if (ISLOWER (*s))
+ {
+ do
+ ++s;
+ while (ISLOWER (*s) || ISDIGIT (*s));
+ }
+
+ switch (*s)
+ {
+ case '\0':
+ break;
+
+ case ',':
+ comma = 1;
+ /* Fall through. */
+
+ case ' ':
+ *s++ = '\0';
+ break;
+
+ default:
+ as_fatal (_("Unknown opcode: `%s'"), str);
+ }
+ insn = (struct sparc_opcode *) hash_find (op_hash, str);
+ *pinsn = insn;
+ if (insn == NULL)
+ {
+ as_bad (_("Unknown opcode: `%s'"), str);
+ return special_case;
+ }
+ if (comma)
+ {
+ *--s = ',';
+ }
+
+ argsStart = s;
+ for (;;)
+ {
+ opcode = insn->match;
+ memset (&the_insn, '\0', sizeof (the_insn));
+ the_insn.reloc = BFD_RELOC_NONE;
+ v9_arg_p = 0;
+
+ /* Build the opcode, checking as we go to make sure that the
+ operands match. */
+ for (args = insn->args;; ++args)
+ {
+ switch (*args)
+ {
+ case 'K':
+ {
+ int kmask = 0;
+
+ /* Parse a series of masks. */
+ if (*s == '#')
+ {
+ while (*s == '#')
+ {
+ int mask;
+
+ if (! parse_keyword_arg (sparc_encode_membar, &s,
+ &mask))
+ {
+ error_message = _(": invalid membar mask name");
+ goto error;
+ }
+ kmask |= mask;
+ while (*s == ' ')
+ ++s;
+ if (*s == '|' || *s == '+')
+ ++s;
+ while (*s == ' ')
+ ++s;
+ }
+ }
+ else
+ {
+ if (! parse_const_expr_arg (&s, &kmask))
+ {
+ error_message = _(": invalid membar mask expression");
+ goto error;
+ }
+ if (kmask < 0 || kmask > 127)
+ {
+ error_message = _(": invalid membar mask number");
+ goto error;
+ }
+ }
+
+ opcode |= MEMBAR (kmask);
+ continue;
+ }
+
+ case '3':
+ {
+ int smask = 0;
+
+ if (! parse_const_expr_arg (&s, &smask))
+ {
+ error_message = _(": invalid siam mode expression");
+ goto error;
+ }
+ if (smask < 0 || smask > 7)
+ {
+ error_message = _(": invalid siam mode number");
+ goto error;
+ }
+ opcode |= smask;
+ continue;
+ }
+
+ case '*':
+ {
+ int fcn = 0;
+
+ /* Parse a prefetch function. */
+ if (*s == '#')
+ {
+ if (! parse_keyword_arg (sparc_encode_prefetch, &s, &fcn))
+ {
+ error_message = _(": invalid prefetch function name");
+ goto error;
+ }
+ }
+ else
+ {
+ if (! parse_const_expr_arg (&s, &fcn))
+ {
+ error_message = _(": invalid prefetch function expression");
+ goto error;
+ }
+ if (fcn < 0 || fcn > 31)
+ {
+ error_message = _(": invalid prefetch function number");
+ goto error;
+ }
+ }
+ opcode |= RD (fcn);
+ continue;
+ }
+
+ case '!':
+ case '?':
+ /* Parse a sparc64 privileged register. */
+ if (*s == '%')
+ {
+ struct priv_reg_entry *p = priv_reg_table;
+ unsigned int len = 9999999; /* Init to make gcc happy. */
+
+ s += 1;
+ while (p->name[0] > s[0])
+ p++;
+ while (p->name[0] == s[0])
+ {
+ len = strlen (p->name);
+ if (strncmp (p->name, s, len) == 0)
+ break;
+ p++;
+ }
+ if (p->name[0] != s[0])
+ {
+ error_message = _(": unrecognizable privileged register");
+ goto error;
+ }
+ if (*args == '?')
+ opcode |= (p->regnum << 14);
+ else
+ opcode |= (p->regnum << 25);
+ s += len;
+ continue;
+ }
+ else
+ {
+ error_message = _(": unrecognizable privileged register");
+ goto error;
+ }
+
+ case '_':
+ case '/':
+ /* Parse a v9a/v9b ancillary state register. */
+ if (*s == '%')
+ {
+ struct priv_reg_entry *p = v9a_asr_table;
+ unsigned int len = 9999999; /* Init to make gcc happy. */
+
+ s += 1;
+ while (p->name[0] > s[0])
+ p++;
+ while (p->name[0] == s[0])
+ {
+ len = strlen (p->name);
+ if (strncmp (p->name, s, len) == 0)
+ break;
+ p++;
+ }
+ if (p->name[0] != s[0])
+ {
+ error_message = _(": unrecognizable v9a or v9b ancillary state register");
+ goto error;
+ }
+ if (*args == '/' && (p->regnum == 20 || p->regnum == 21))
+ {
+ error_message = _(": rd on write only ancillary state register");
+ goto error;
+ }
+ if (p->regnum >= 24
+ && (insn->architecture
+ & SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A)))
+ {
+ /* %sys_tick and %sys_tick_cmpr are v9bnotv9a */
+ error_message = _(": unrecognizable v9a ancillary state register");
+ goto error;
+ }
+ if (*args == '/')
+ opcode |= (p->regnum << 14);
+ else
+ opcode |= (p->regnum << 25);
+ s += len;
+ continue;
+ }
+ else
+ {
+ error_message = _(": unrecognizable v9a or v9b ancillary state register");
+ goto error;
+ }
+
+ case 'M':
+ case 'm':
+ if (strncmp (s, "%asr", 4) == 0)
+ {
+ s += 4;
+
+ if (ISDIGIT (*s))
+ {
+ long num = 0;
+
+ while (ISDIGIT (*s))
+ {
+ num = num * 10 + *s - '0';
+ ++s;
+ }
+
+ if (current_architecture >= SPARC_OPCODE_ARCH_V9)
+ {
+ if (num < 16 || 31 < num)
+ {
+ error_message = _(": asr number must be between 16 and 31");
+ goto error;
+ }
+ }
+ else
+ {
+ if (num < 0 || 31 < num)
+ {
+ error_message = _(": asr number must be between 0 and 31");
+ goto error;
+ }
+ }
+
+ opcode |= (*args == 'M' ? RS1 (num) : RD (num));
+ continue;
+ }
+ else
+ {
+ error_message = _(": expecting %asrN");
+ goto error;
+ }
+ } /* if %asr */
+ break;
+
+ case 'I':
+ the_insn.reloc = BFD_RELOC_SPARC_11;
+ goto immediate;
+
+ case 'j':
+ the_insn.reloc = BFD_RELOC_SPARC_10;
+ goto immediate;
+
+ case 'X':
+ /* V8 systems don't understand BFD_RELOC_SPARC_5. */
+ if (SPARC_OPCODE_ARCH_V9_P (max_architecture))
+ the_insn.reloc = BFD_RELOC_SPARC_5;
+ else
+ the_insn.reloc = BFD_RELOC_SPARC13;
+ /* These fields are unsigned, but for upward compatibility,
+ allow negative values as well. */
+ goto immediate;
+
+ case 'Y':
+ /* V8 systems don't understand BFD_RELOC_SPARC_6. */
+ if (SPARC_OPCODE_ARCH_V9_P (max_architecture))
+ the_insn.reloc = BFD_RELOC_SPARC_6;
+ else
+ the_insn.reloc = BFD_RELOC_SPARC13;
+ /* These fields are unsigned, but for upward compatibility,
+ allow negative values as well. */
+ goto immediate;
+
+ case 'k':
+ the_insn.reloc = /* RELOC_WDISP2_14 */ BFD_RELOC_SPARC_WDISP16;
+ the_insn.pcrel = 1;
+ goto immediate;
+
+ case 'G':
+ the_insn.reloc = BFD_RELOC_SPARC_WDISP19;
+ the_insn.pcrel = 1;
+ goto immediate;
+
+ case 'N':
+ if (*s == 'p' && s[1] == 'n')
+ {
+ s += 2;
+ continue;
+ }
+ break;
+
+ case 'T':
+ if (*s == 'p' && s[1] == 't')
+ {
+ s += 2;
+ continue;
+ }
+ break;
+
+ case 'z':
+ if (*s == ' ')
+ {
+ ++s;
+ }
+ if (strncmp (s, "%icc", 4) == 0)
+ {
+ s += 4;
+ continue;
+ }
+ break;
+
+ case 'Z':
+ if (*s == ' ')
+ {
+ ++s;
+ }
+ if (strncmp (s, "%xcc", 4) == 0)
+ {
+ s += 4;
+ continue;
+ }
+ break;
+
+ case '6':
+ if (*s == ' ')
+ {
+ ++s;
+ }
+ if (strncmp (s, "%fcc0", 5) == 0)
+ {
+ s += 5;
+ continue;
+ }
+ break;
+
+ case '7':
+ if (*s == ' ')
+ {
+ ++s;
+ }
+ if (strncmp (s, "%fcc1", 5) == 0)
+ {
+ s += 5;
+ continue;
+ }
+ break;
+
+ case '8':
+ if (*s == ' ')
+ {
+ ++s;
+ }
+ if (strncmp (s, "%fcc2", 5) == 0)
+ {
+ s += 5;
+ continue;
+ }
+ break;
+
+ case '9':
+ if (*s == ' ')
+ {
+ ++s;
+ }
+ if (strncmp (s, "%fcc3", 5) == 0)
+ {
+ s += 5;
+ continue;
+ }
+ break;
+
+ case 'P':
+ if (strncmp (s, "%pc", 3) == 0)
+ {
+ s += 3;
+ continue;
+ }
+ break;
+
+ case 'W':
+ if (strncmp (s, "%tick", 5) == 0)
+ {
+ s += 5;
+ continue;
+ }
+ break;
+
+ case '\0': /* End of args. */
+ if (s[0] == ',' && s[1] == '%')
+ {
+ static const struct tls_ops {
+ /* The name as it appears in assembler. */
+ char *name;
+ /* strlen (name), precomputed for speed */
+ int len;
+ /* The reloc this pseudo-op translates to. */
+ int reloc;
+ /* 1 if call. */
+ int call;
+ } tls_ops[] = {
+ { "tgd_add", 7, BFD_RELOC_SPARC_TLS_GD_ADD, 0 },
+ { "tgd_call", 8, BFD_RELOC_SPARC_TLS_GD_CALL, 1 },
+ { "tldm_add", 8, BFD_RELOC_SPARC_TLS_LDM_ADD, 0 },
+ { "tldm_call", 9, BFD_RELOC_SPARC_TLS_LDM_CALL, 1 },
+ { "tldo_add", 8, BFD_RELOC_SPARC_TLS_LDO_ADD, 0 },
+ { "tie_ldx", 7, BFD_RELOC_SPARC_TLS_IE_LDX, 0 },
+ { "tie_ld", 6, BFD_RELOC_SPARC_TLS_IE_LD, 0 },
+ { "tie_add", 7, BFD_RELOC_SPARC_TLS_IE_ADD, 0 }
+ };
+ const struct tls_ops *o;
+ char *s1;
+ int npar = 0;
+
+ for (o = tls_ops; o->name; o++)
+ if (strncmp (s + 2, o->name, o->len) == 0)
+ break;
+ if (o->name == NULL)
+ break;
+
+ if (s[o->len + 2] != '(')
+ {
+ as_bad (_("Illegal operands: %%%s requires arguments in ()"), o->name);
+ return special_case;
+ }
+
+ if (! o->call && the_insn.reloc != BFD_RELOC_NONE)
+ {
+ as_bad (_("Illegal operands: %%%s cannot be used together with other relocs in the insn ()"),
+ o->name);
+ return special_case;
+ }
+
+ if (o->call
+ && (the_insn.reloc != BFD_RELOC_32_PCREL_S2
+ || the_insn.exp.X_add_number != 0
+ || the_insn.exp.X_add_symbol
+ != symbol_find_or_make ("__tls_get_addr")))
+ {
+ as_bad (_("Illegal operands: %%%s can be only used with call __tls_get_addr"),
+ o->name);
+ return special_case;
+ }
+
+ the_insn.reloc = o->reloc;
+ memset (&the_insn.exp, 0, sizeof (the_insn.exp));
+ s += o->len + 3;
+
+ for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++)
+ if (*s1 == '(')
+ npar++;
+ else if (*s1 == ')')
+ {
+ if (!npar)
+ break;
+ npar--;
+ }
+
+ if (*s1 != ')')
+ {
+ as_bad (_("Illegal operands: %%%s requires arguments in ()"), o->name);
+ return special_case;
+ }
+
+ *s1 = '\0';
+ (void) get_expression (s);
+ *s1 = ')';
+ s = s1 + 1;
+ }
+ if (*s == '\0')
+ match = 1;
+ break;
+
+ case '+':
+ if (*s == '+')
+ {
+ ++s;
+ continue;
+ }
+ if (*s == '-')
+ {
+ continue;
+ }
+ break;
+
+ case '[': /* These must match exactly. */
+ case ']':
+ case ',':
+ case ' ':
+ if (*s++ == *args)
+ continue;
+ break;
+
+ case '#': /* Must be at least one digit. */
+ if (ISDIGIT (*s++))
+ {
+ while (ISDIGIT (*s))
+ {
+ ++s;
+ }
+ continue;
+ }
+ break;
+
+ case 'C': /* Coprocessor state register. */
+ if (strncmp (s, "%csr", 4) == 0)
+ {
+ s += 4;
+ continue;
+ }
+ break;
+
+ case 'b': /* Next operand is a coprocessor register. */
+ case 'c':
+ case 'D':
+ if (*s++ == '%' && *s++ == 'c' && ISDIGIT (*s))
+ {
+ mask = *s++;
+ if (ISDIGIT (*s))
+ {
+ mask = 10 * (mask - '0') + (*s++ - '0');
+ if (mask >= 32)
+ {
+ break;
+ }
+ }
+ else
+ {
+ mask -= '0';
+ }
+ switch (*args)
+ {
+
+ case 'b':
+ opcode |= mask << 14;
+ continue;
+
+ case 'c':
+ opcode |= mask;
+ continue;
+
+ case 'D':
+ opcode |= mask << 25;
+ continue;
+ }
+ }
+ break;
+
+ case 'r': /* next operand must be a register */
+ case 'O':
+ case '1':
+ case '2':
+ case 'd':
+ if (*s++ == '%')
+ {
+ switch (c = *s++)
+ {
+
+ case 'f': /* frame pointer */
+ if (*s++ == 'p')
+ {
+ mask = 0x1e;
+ break;
+ }
+ goto error;
+
+ case 'g': /* global register */
+ c = *s++;
+ if (isoctal (c))
+ {
+ mask = c - '0';
+ break;
+ }
+ goto error;
+
+ case 'i': /* in register */
+ c = *s++;
+ if (isoctal (c))
+ {
+ mask = c - '0' + 24;
+ break;
+ }
+ goto error;
+
+ case 'l': /* local register */
+ c = *s++;
+ if (isoctal (c))
+ {
+ mask = (c - '0' + 16);
+ break;
+ }
+ goto error;
+
+ case 'o': /* out register */
+ c = *s++;
+ if (isoctal (c))
+ {
+ mask = (c - '0' + 8);
+ break;
+ }
+ goto error;
+
+ case 's': /* stack pointer */
+ if (*s++ == 'p')
+ {
+ mask = 0xe;
+ break;
+ }
+ goto error;
+
+ case 'r': /* any register */
+ if (!ISDIGIT ((c = *s++)))
+ {
+ goto error;
+ }
+ /* FALLTHROUGH */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (ISDIGIT (*s))
+ {
+ if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
+ {
+ goto error;
+ }
+ }
+ else
+ {
+ c -= '0';
+ }
+ mask = c;
+ break;
+
+ default:
+ goto error;
+ }
+
+ if ((mask & ~1) == 2 && sparc_arch_size == 64
+ && no_undeclared_regs && ! globals[mask])
+ as_bad (_("detected global register use not covered by .register pseudo-op"));
+
+ /* Got the register, now figure out where
+ it goes in the opcode. */
+ switch (*args)
+ {
+ case '1':
+ opcode |= mask << 14;
+ continue;
+
+ case '2':
+ opcode |= mask;
+ continue;
+
+ case 'd':
+ opcode |= mask << 25;
+ continue;
+
+ case 'r':
+ opcode |= (mask << 25) | (mask << 14);
+ continue;
+
+ case 'O':
+ opcode |= (mask << 25) | (mask << 0);
+ continue;
+ }
+ }
+ break;
+
+ case 'e': /* next operand is a floating point register */
+ case 'v':
+ case 'V':
+
+ case 'f':
+ case 'B':
+ case 'R':
+
+ case 'g':
+ case 'H':
+ case 'J':
+ {
+ char format;
+
+ if (*s++ == '%'
+ && ((format = *s) == 'f')
+ && ISDIGIT (*++s))
+ {
+ for (mask = 0; ISDIGIT (*s); ++s)
+ {
+ mask = 10 * mask + (*s - '0');
+ } /* read the number */
+
+ if ((*args == 'v'
+ || *args == 'B'
+ || *args == 'H')
+ && (mask & 1))
+ {
+ break;
+ } /* register must be even numbered */
+
+ if ((*args == 'V'
+ || *args == 'R'
+ || *args == 'J')
+ && (mask & 3))
+ {
+ break;
+ } /* register must be multiple of 4 */
+
+ if (mask >= 64)
+ {
+ if (SPARC_OPCODE_ARCH_V9_P (max_architecture))
+ error_message = _(": There are only 64 f registers; [0-63]");
+ else
+ error_message = _(": There are only 32 f registers; [0-31]");
+ goto error;
+ } /* on error */
+ else if (mask >= 32)
+ {
+ if (SPARC_OPCODE_ARCH_V9_P (max_architecture))
+ {
+ if (*args == 'e' || *args == 'f' || *args == 'g')
+ {
+ error_message
+ = _(": There are only 32 single precision f registers; [0-31]");
+ goto error;
+ }
+ v9_arg_p = 1;
+ mask -= 31; /* wrap high bit */
+ }
+ else
+ {
+ error_message = _(": There are only 32 f registers; [0-31]");
+ goto error;
+ }
+ }
+ }
+ else
+ {
+ break;
+ } /* if not an 'f' register. */
+
+ switch (*args)
+ {
+ case 'v':
+ case 'V':
+ case 'e':
+ opcode |= RS1 (mask);
+ continue;
+
+ case 'f':
+ case 'B':
+ case 'R':
+ opcode |= RS2 (mask);
+ continue;
+
+ case 'g':
+ case 'H':
+ case 'J':
+ opcode |= RD (mask);
+ continue;
+ } /* Pack it in. */
+
+ know (0);
+ break;
+ } /* float arg */
+
+ case 'F':
+ if (strncmp (s, "%fsr", 4) == 0)
+ {
+ s += 4;
+ continue;
+ }
+ break;
+
+ case '0': /* 64 bit immediate (set, setsw, setx insn) */
+ the_insn.reloc = BFD_RELOC_NONE; /* reloc handled elsewhere */
+ goto immediate;
+
+ case 'l': /* 22 bit PC relative immediate */
+ the_insn.reloc = BFD_RELOC_SPARC_WDISP22;
+ the_insn.pcrel = 1;
+ goto immediate;
+
+ case 'L': /* 30 bit immediate */
+ the_insn.reloc = BFD_RELOC_32_PCREL_S2;
+ the_insn.pcrel = 1;
+ goto immediate;
+
+ case 'h':
+ case 'n': /* 22 bit immediate */
+ the_insn.reloc = BFD_RELOC_SPARC22;
+ goto immediate;
+
+ case 'i': /* 13 bit immediate */
+ the_insn.reloc = BFD_RELOC_SPARC13;
+
+ /* fallthrough */
+
+ immediate:
+ if (*s == ' ')
+ s++;
+
+ {
+ char *s1;
+ char *op_arg = NULL;
+ expressionS op_exp;
+ bfd_reloc_code_real_type old_reloc = the_insn.reloc;
+
+ /* Check for %hi, etc. */
+ if (*s == '%')
+ {
+ static const struct ops {
+ /* The name as it appears in assembler. */
+ char *name;
+ /* strlen (name), precomputed for speed */
+ int len;
+ /* The reloc this pseudo-op translates to. */
+ int reloc;
+ /* Non-zero if for v9 only. */
+ int v9_p;
+ /* Non-zero if can be used in pc-relative contexts. */
+ int pcrel_p;/*FIXME:wip*/
+ } ops[] = {
+ /* hix/lox must appear before hi/lo so %hix won't be
+ mistaken for %hi. */
+ { "hix", 3, BFD_RELOC_SPARC_HIX22, 1, 0 },
+ { "lox", 3, BFD_RELOC_SPARC_LOX10, 1, 0 },
+ { "hi", 2, BFD_RELOC_HI22, 0, 1 },
+ { "lo", 2, BFD_RELOC_LO10, 0, 1 },
+ { "hh", 2, BFD_RELOC_SPARC_HH22, 1, 1 },
+ { "hm", 2, BFD_RELOC_SPARC_HM10, 1, 1 },
+ { "lm", 2, BFD_RELOC_SPARC_LM22, 1, 1 },
+ { "h44", 3, BFD_RELOC_SPARC_H44, 1, 0 },
+ { "m44", 3, BFD_RELOC_SPARC_M44, 1, 0 },
+ { "l44", 3, BFD_RELOC_SPARC_L44, 1, 0 },
+ { "uhi", 3, BFD_RELOC_SPARC_HH22, 1, 0 },
+ { "ulo", 3, BFD_RELOC_SPARC_HM10, 1, 0 },
+ { "tgd_hi22", 8, BFD_RELOC_SPARC_TLS_GD_HI22, 0, 0 },
+ { "tgd_lo10", 8, BFD_RELOC_SPARC_TLS_GD_LO10, 0, 0 },
+ { "tldm_hi22", 9, BFD_RELOC_SPARC_TLS_LDM_HI22, 0, 0 },
+ { "tldm_lo10", 9, BFD_RELOC_SPARC_TLS_LDM_LO10, 0, 0 },
+ { "tldo_hix22", 10, BFD_RELOC_SPARC_TLS_LDO_HIX22, 0,
+ 0 },
+ { "tldo_lox10", 10, BFD_RELOC_SPARC_TLS_LDO_LOX10, 0,
+ 0 },
+ { "tie_hi22", 8, BFD_RELOC_SPARC_TLS_IE_HI22, 0, 0 },
+ { "tie_lo10", 8, BFD_RELOC_SPARC_TLS_IE_LO10, 0, 0 },
+ { "tle_hix22", 9, BFD_RELOC_SPARC_TLS_LE_HIX22, 0, 0 },
+ { "tle_lox10", 9, BFD_RELOC_SPARC_TLS_LE_LOX10, 0, 0 },
+ { NULL, 0, 0, 0, 0 }
+ };
+ const struct ops *o;
+
+ for (o = ops; o->name; o++)
+ if (strncmp (s + 1, o->name, o->len) == 0)
+ break;
+ if (o->name == NULL)
+ break;
+
+ if (s[o->len + 1] != '(')
+ {
+ as_bad (_("Illegal operands: %%%s requires arguments in ()"), o->name);
+ return special_case;
+ }
+
+ op_arg = o->name;
+ the_insn.reloc = o->reloc;
+ s += o->len + 2;
+ v9_arg_p = o->v9_p;
+ }
+
+ /* Note that if the get_expression() fails, we will still
+ have created U entries in the symbol table for the
+ 'symbols' in the input string. Try not to create U
+ symbols for registers, etc. */
+
+ /* This stuff checks to see if the expression ends in
+ +%reg. If it does, it removes the register from
+ the expression, and re-sets 's' to point to the
+ right place. */
+
+ if (op_arg)
+ {
+ int npar = 0;
+
+ for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++)
+ if (*s1 == '(')
+ npar++;
+ else if (*s1 == ')')
+ {
+ if (!npar)
+ break;
+ npar--;
+ }
+
+ if (*s1 != ')')
+ {
+ as_bad (_("Illegal operands: %%%s requires arguments in ()"), op_arg);
+ return special_case;
+ }
+
+ *s1 = '\0';
+ (void) get_expression (s);
+ *s1 = ')';
+ s = s1 + 1;
+ if (*s == ',' || *s == ']' || !*s)
+ continue;
+ if (*s != '+' && *s != '-')
+ {
+ as_bad (_("Illegal operands: Can't do arithmetics other than + and - involving %%%s()"), op_arg);
+ return special_case;
+ }
+ *s1 = '0';
+ s = s1;
+ op_exp = the_insn.exp;
+ memset (&the_insn.exp, 0, sizeof (the_insn.exp));
+ }
+
+ for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++)
+ ;
+
+ if (s1 != s && ISDIGIT (s1[-1]))
+ {
+ if (s1[-2] == '%' && s1[-3] == '+')
+ s1 -= 3;
+ else if (strchr ("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+')
+ s1 -= 4;
+ else
+ s1 = NULL;
+ if (s1)
+ {
+ *s1 = '\0';
+ if (op_arg && s1 == s + 1)
+ the_insn.exp.X_op = O_absent;
+ else
+ (void) get_expression (s);
+ *s1 = '+';
+ if (op_arg)
+ *s = ')';
+ s = s1;
+ }
+ }
+ else
+ s1 = NULL;
+
+ if (!s1)
+ {
+ (void) get_expression (s);
+ if (op_arg)
+ *s = ')';
+ s = expr_end;
+ }
+
+ if (op_arg)
+ {
+ the_insn.exp2 = the_insn.exp;
+ the_insn.exp = op_exp;
+ if (the_insn.exp2.X_op == O_absent)
+ the_insn.exp2.X_op = O_illegal;
+ else if (the_insn.exp.X_op == O_absent)
+ {
+ the_insn.exp = the_insn.exp2;
+ the_insn.exp2.X_op = O_illegal;
+ }
+ else if (the_insn.exp.X_op == O_constant)
+ {
+ valueT val = the_insn.exp.X_add_number;
+ switch (the_insn.reloc)
+ {
+ default:
+ break;
+
+ case BFD_RELOC_SPARC_HH22:
+ val = BSR (val, 32);
+ /* Fall through. */
+
+ case BFD_RELOC_SPARC_LM22:
+ case BFD_RELOC_HI22:
+ val = (val >> 10) & 0x3fffff;
+ break;
+
+ case BFD_RELOC_SPARC_HM10:
+ val = BSR (val, 32);
+ /* Fall through. */
+
+ case BFD_RELOC_LO10:
+ val &= 0x3ff;
+ break;
+
+ case BFD_RELOC_SPARC_H44:
+ val >>= 22;
+ val &= 0x3fffff;
+ break;
+
+ case BFD_RELOC_SPARC_M44:
+ val >>= 12;
+ val &= 0x3ff;
+ break;
+
+ case BFD_RELOC_SPARC_L44:
+ val &= 0xfff;
+ break;
+
+ case BFD_RELOC_SPARC_HIX22:
+ val = ~val;
+ val = (val >> 10) & 0x3fffff;
+ break;
+
+ case BFD_RELOC_SPARC_LOX10:
+ val = (val & 0x3ff) | 0x1c00;
+ break;
+ }
+ the_insn.exp = the_insn.exp2;
+ the_insn.exp.X_add_number += val;
+ the_insn.exp2.X_op = O_illegal;
+ the_insn.reloc = old_reloc;
+ }
+ else if (the_insn.exp2.X_op != O_constant)
+ {
+ as_bad (_("Illegal operands: Can't add non-constant expression to %%%s()"), op_arg);
+ return special_case;
+ }
+ else
+ {
+ if (old_reloc != BFD_RELOC_SPARC13
+ || the_insn.reloc != BFD_RELOC_LO10
+ || sparc_arch_size != 64
+ || sparc_pic_code)
+ {
+ as_bad (_("Illegal operands: Can't do arithmetics involving %%%s() of a relocatable symbol"), op_arg);
+ return special_case;
+ }
+ the_insn.reloc = BFD_RELOC_SPARC_OLO10;
+ }
+ }
+ }
+ /* Check for constants that don't require emitting a reloc. */
+ if (the_insn.exp.X_op == O_constant
+ && the_insn.exp.X_add_symbol == 0
+ && the_insn.exp.X_op_symbol == 0)
+ {
+ /* For pc-relative call instructions, we reject
+ constants to get better code. */
+ if (the_insn.pcrel
+ && the_insn.reloc == BFD_RELOC_32_PCREL_S2
+ && in_signed_range (the_insn.exp.X_add_number, 0x3fff))
+ {
+ error_message = _(": PC-relative operand can't be a constant");
+ goto error;
+ }
+
+ if (the_insn.reloc >= BFD_RELOC_SPARC_TLS_GD_HI22
+ && the_insn.reloc <= BFD_RELOC_SPARC_TLS_TPOFF64)
+ {
+ error_message = _(": TLS operand can't be a constant");
+ goto error;
+ }
+
+ /* Constants that won't fit are checked in md_apply_fix3
+ and bfd_install_relocation.
+ ??? It would be preferable to install the constants
+ into the insn here and save having to create a fixS
+ for each one. There already exists code to handle
+ all the various cases (e.g. in md_apply_fix3 and
+ bfd_install_relocation) so duplicating all that code
+ here isn't right. */
+ }
+
+ continue;
+
+ case 'a':
+ if (*s++ == 'a')
+ {
+ opcode |= ANNUL;
+ continue;
+ }
+ break;
+
+ case 'A':
+ {
+ int asi = 0;
+
+ /* Parse an asi. */
+ if (*s == '#')
+ {
+ if (! parse_keyword_arg (sparc_encode_asi, &s, &asi))
+ {
+ error_message = _(": invalid ASI name");
+ goto error;
+ }
+ }
+ else
+ {
+ if (! parse_const_expr_arg (&s, &asi))
+ {
+ error_message = _(": invalid ASI expression");
+ goto error;
+ }
+ if (asi < 0 || asi > 255)
+ {
+ error_message = _(": invalid ASI number");
+ goto error;
+ }
+ }
+ opcode |= ASI (asi);
+ continue;
+ } /* Alternate space. */
+
+ case 'p':
+ if (strncmp (s, "%psr", 4) == 0)
+ {
+ s += 4;
+ continue;
+ }
+ break;
+
+ case 'q': /* Floating point queue. */
+ if (strncmp (s, "%fq", 3) == 0)
+ {
+ s += 3;
+ continue;
+ }
+ break;
+
+ case 'Q': /* Coprocessor queue. */
+ if (strncmp (s, "%cq", 3) == 0)
+ {
+ s += 3;
+ continue;
+ }
+ break;
+
+ case 'S':
+ if (strcmp (str, "set") == 0
+ || strcmp (str, "setuw") == 0)
+ {
+ special_case = SPECIAL_CASE_SET;
+ continue;
+ }
+ else if (strcmp (str, "setsw") == 0)
+ {
+ special_case = SPECIAL_CASE_SETSW;
+ continue;
+ }
+ else if (strcmp (str, "setx") == 0)
+ {
+ special_case = SPECIAL_CASE_SETX;
+ continue;
+ }
+ else if (strncmp (str, "fdiv", 4) == 0)
+ {
+ special_case = SPECIAL_CASE_FDIV;
+ continue;
+ }
+ break;
+
+ case 'o':
+ if (strncmp (s, "%asi", 4) != 0)
+ break;
+ s += 4;
+ continue;
+
+ case 's':
+ if (strncmp (s, "%fprs", 5) != 0)
+ break;
+ s += 5;
+ continue;
+
+ case 'E':
+ if (strncmp (s, "%ccr", 4) != 0)
+ break;
+ s += 4;
+ continue;
+
+ case 't':
+ if (strncmp (s, "%tbr", 4) != 0)
+ break;
+ s += 4;
+ continue;
+
+ case 'w':
+ if (strncmp (s, "%wim", 4) != 0)
+ break;
+ s += 4;
+ continue;
+
+ case 'x':
+ {
+ char *push = input_line_pointer;
+ expressionS e;
+
+ input_line_pointer = s;
+ expression (&e);
+ if (e.X_op == O_constant)
+ {
+ int n = e.X_add_number;
+ if (n != e.X_add_number || (n & ~0x1ff) != 0)
+ as_bad (_("OPF immediate operand out of range (0-0x1ff)"));
+ else
+ opcode |= e.X_add_number << 5;
+ }
+ else
+ as_bad (_("non-immediate OPF operand, ignored"));
+ s = input_line_pointer;
+ input_line_pointer = push;
+ continue;
+ }
+
+ case 'y':
+ if (strncmp (s, "%y", 2) != 0)
+ break;
+ s += 2;
+ continue;
+
+ case 'u':
+ case 'U':
+ {
+ /* Parse a sparclet cpreg. */
+ int cpreg;
+ if (! parse_keyword_arg (sparc_encode_sparclet_cpreg, &s, &cpreg))
+ {
+ error_message = _(": invalid cpreg name");
+ goto error;
+ }
+ opcode |= (*args == 'U' ? RS1 (cpreg) : RD (cpreg));
+ continue;
+ }
+
+ default:
+ as_fatal (_("failed sanity check."));
+ } /* switch on arg code. */
+
+ /* Break out of for() loop. */
+ break;
+ } /* For each arg that we expect. */
+
+ error:
+ if (match == 0)
+ {
+ /* Args don't match. */
+ if (&insn[1] - sparc_opcodes < sparc_num_opcodes
+ && (insn->name == insn[1].name
+ || !strcmp (insn->name, insn[1].name)))
+ {
+ ++insn;
+ s = argsStart;
+ continue;
+ }
+ else
+ {
+ as_bad (_("Illegal operands%s"), error_message);
+ return special_case;
+ }
+ }
+ else
+ {
+ /* We have a match. Now see if the architecture is OK. */
+ int needed_arch_mask = insn->architecture;
+
+ if (v9_arg_p)
+ {
+ needed_arch_mask &=
+ ~(SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9) - 1);
+ if (! needed_arch_mask)
+ needed_arch_mask =
+ SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9);
+ }
+
+ if (needed_arch_mask
+ & SPARC_OPCODE_SUPPORTED (current_architecture))
+ /* OK. */
+ ;
+ /* Can we bump up the architecture? */
+ else if (needed_arch_mask
+ & SPARC_OPCODE_SUPPORTED (max_architecture))
+ {
+ enum sparc_opcode_arch_val needed_architecture =
+ sparc_ffs (SPARC_OPCODE_SUPPORTED (max_architecture)
+ & needed_arch_mask);
+
+ assert (needed_architecture <= SPARC_OPCODE_ARCH_MAX);
+ if (warn_on_bump
+ && needed_architecture > warn_after_architecture)
+ {
+ as_warn (_("architecture bumped from \"%s\" to \"%s\" on \"%s\""),
+ sparc_opcode_archs[current_architecture].name,
+ sparc_opcode_archs[needed_architecture].name,
+ str);
+ warn_after_architecture = needed_architecture;
+ }
+ current_architecture = needed_architecture;
+ }
+ /* Conflict. */
+ /* ??? This seems to be a bit fragile. What if the next entry in
+ the opcode table is the one we want and it is supported?
+ It is possible to arrange the table today so that this can't
+ happen but what about tomorrow? */
+ else
+ {
+ int arch, printed_one_p = 0;
+ char *p;
+ char required_archs[SPARC_OPCODE_ARCH_MAX * 16];
+
+ /* Create a list of the architectures that support the insn. */
+ needed_arch_mask &= ~SPARC_OPCODE_SUPPORTED (max_architecture);
+ p = required_archs;
+ arch = sparc_ffs (needed_arch_mask);
+ while ((1 << arch) <= needed_arch_mask)
+ {
+ if ((1 << arch) & needed_arch_mask)
+ {
+ if (printed_one_p)
+ *p++ = '|';
+ strcpy (p, sparc_opcode_archs[arch].name);
+ p += strlen (p);
+ printed_one_p = 1;
+ }
+ ++arch;
+ }
+
+ as_bad (_("Architecture mismatch on \"%s\"."), str);
+ as_tsktsk (_(" (Requires %s; requested architecture is %s.)"),
+ required_archs,
+ sparc_opcode_archs[max_architecture].name);
+ return special_case;
+ }
+ } /* If no match. */
+
+ break;
+ } /* Forever looking for a match. */
+
+ the_insn.opcode = opcode;
+ return special_case;
+}
+
+/* Parse an argument that can be expressed as a keyword.
+ (eg: #StoreStore or %ccfr).
+ The result is a boolean indicating success.
+ If successful, INPUT_POINTER is updated. */
+
+static int
+parse_keyword_arg (lookup_fn, input_pointerP, valueP)
+ int (*lookup_fn) PARAMS ((const char *));
+ char **input_pointerP;
+ int *valueP;
+{
+ int value;
+ char c, *p, *q;
+
+ p = *input_pointerP;
+ for (q = p + (*p == '#' || *p == '%');
+ ISALNUM (*q) || *q == '_';
+ ++q)
+ continue;
+ c = *q;
+ *q = 0;
+ value = (*lookup_fn) (p);
+ *q = c;
+ if (value == -1)
+ return 0;
+ *valueP = value;
+ *input_pointerP = q;
+ return 1;
+}
+
+/* Parse an argument that is a constant expression.
+ The result is a boolean indicating success. */
+
+static int
+parse_const_expr_arg (input_pointerP, valueP)
+ char **input_pointerP;
+ int *valueP;
+{
+ char *save = input_line_pointer;
+ expressionS exp;
+
+ input_line_pointer = *input_pointerP;
+ /* The next expression may be something other than a constant
+ (say if we're not processing the right variant of the insn).
+ Don't call expression unless we're sure it will succeed as it will
+ signal an error (which we want to defer until later). */
+ /* FIXME: It might be better to define md_operand and have it recognize
+ things like %asi, etc. but continuing that route through to the end
+ is a lot of work. */
+ if (*input_line_pointer == '%')
+ {
+ input_line_pointer = save;
+ return 0;
+ }
+ expression (&exp);
+ *input_pointerP = input_line_pointer;
+ input_line_pointer = save;
+ if (exp.X_op != O_constant)
+ return 0;
+ *valueP = exp.X_add_number;
+ return 1;
+}
+
+/* Subroutine of sparc_ip to parse an expression. */
+
+static int
+get_expression (str)
+ char *str;
+{
+ char *save_in;
+ segT seg;
+
+ save_in = input_line_pointer;
+ input_line_pointer = str;
+ seg = expression (&the_insn.exp);
+ if (seg != absolute_section
+ && seg != text_section
+ && seg != data_section
+ && seg != bss_section
+ && seg != undefined_section)
+ {
+ the_insn.error = _("bad segment");
+ expr_end = input_line_pointer;
+ input_line_pointer = save_in;
+ return 1;
+ }
+ expr_end = input_line_pointer;
+ input_line_pointer = save_in;
+ return 0;
+}
+
+/* Subroutine of md_assemble to output one insn. */
+
+static void
+output_insn (insn, the_insn)
+ const struct sparc_opcode *insn;
+ struct sparc_it *the_insn;
+{
+ char *toP = frag_more (4);
+
+ /* Put out the opcode. */
+ if (INSN_BIG_ENDIAN)
+ number_to_chars_bigendian (toP, (valueT) the_insn->opcode, 4);
+ else
+ number_to_chars_littleendian (toP, (valueT) the_insn->opcode, 4);
+
+ /* Put out the symbol-dependent stuff. */
+ if (the_insn->reloc != BFD_RELOC_NONE)
+ {
+ fixS *fixP = fix_new_exp (frag_now, /* Which frag. */
+ (toP - frag_now->fr_literal), /* Where. */
+ 4, /* Size. */
+ &the_insn->exp,
+ the_insn->pcrel,
+ the_insn->reloc);
+ /* Turn off overflow checking in fixup_segment. We'll do our
+ own overflow checking in md_apply_fix3. This is necessary because
+ the insn size is 4 and fixup_segment will signal an overflow for
+ large 8 byte quantities. */
+ fixP->fx_no_overflow = 1;
+ if (the_insn->reloc == BFD_RELOC_SPARC_OLO10)
+ fixP->tc_fix_data = the_insn->exp2.X_add_number;
+ }
+
+ last_insn = insn;
+ last_opcode = the_insn->opcode;
+
+#ifdef OBJ_ELF
+ dwarf2_emit_insn (4);
+#endif
+}
+
+/* This is identical to the md_atof in m68k.c. I think this is right,
+ but I'm not sure.
+
+ Turn a string in input_line_pointer into a floating point constant
+ of type TYPE, and store the appropriate bytes in *LITP. The number
+ of LITTLENUMS emitted is stored in *SIZEP. An error message is
+ returned, or NULL on OK. */
+
+/* Equal to MAX_PRECISION in atof-ieee.c. */
+#define MAX_LITTLENUMS 6
+
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int i, prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ char *t;
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to MD_ATOF()");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+
+ if (target_big_endian)
+ {
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, (valueT) words[i],
+ sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ }
+ else
+ {
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litP, (valueT) words[i],
+ sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ }
+
+ return 0;
+}
+
+/* Write a value out to the object file, using the appropriate
+ endianness. */
+
+void
+md_number_to_chars (buf, val, n)
+ char *buf;
+ valueT val;
+ int n;
+{
+ if (target_big_endian)
+ number_to_chars_bigendian (buf, val, n);
+ else if (target_little_endian_data
+ && ((n == 4 || n == 2) && ~now_seg->flags & SEC_ALLOC))
+ /* Output debug words, which are not in allocated sections, as big
+ endian. */
+ number_to_chars_bigendian (buf, val, n);
+ else if (target_little_endian_data || ! target_big_endian)
+ number_to_chars_littleendian (buf, val, n);
+}
+
+/* Apply a fixS to the frags, now that we know the value it ought to
+ hold. */
+
+void
+md_apply_fix3 (fixP, valP, segment)
+ fixS *fixP;
+ valueT *valP;
+ segT segment ATTRIBUTE_UNUSED;
+{
+ char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+ offsetT val = * (offsetT *) valP;
+ long insn;
+
+ assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
+
+ fixP->fx_addnumber = val; /* Remember value for emit_reloc. */
+
+#ifdef OBJ_ELF
+ /* SPARC ELF relocations don't use an addend in the data field. */
+ if (fixP->fx_addsy != NULL)
+ return;
+#endif
+
+ /* This is a hack. There should be a better way to
+ handle this. Probably in terms of howto fields, once
+ we can look at these fixups in terms of howtos. */
+ if (fixP->fx_r_type == BFD_RELOC_32_PCREL_S2 && fixP->fx_addsy)
+ val += fixP->fx_where + fixP->fx_frag->fr_address;
+
+#ifdef OBJ_AOUT
+ /* FIXME: More ridiculous gas reloc hacking. If we are going to
+ generate a reloc, then we just want to let the reloc addend set
+ the value. We do not want to also stuff the addend into the
+ object file. Including the addend in the object file works when
+ doing a static link, because the linker will ignore the object
+ file contents. However, the dynamic linker does not ignore the
+ object file contents. */
+ if (fixP->fx_addsy != NULL
+ && fixP->fx_r_type != BFD_RELOC_32_PCREL_S2)
+ val = 0;
+
+ /* When generating PIC code, we do not want an addend for a reloc
+ against a local symbol. We adjust fx_addnumber to cancel out the
+ value already included in val, and to also cancel out the
+ adjustment which bfd_install_relocation will create. */
+ if (sparc_pic_code
+ && fixP->fx_r_type != BFD_RELOC_32_PCREL_S2
+ && fixP->fx_addsy != NULL
+ && ! S_IS_COMMON (fixP->fx_addsy)
+ && symbol_section_p (fixP->fx_addsy))
+ fixP->fx_addnumber -= 2 * S_GET_VALUE (fixP->fx_addsy);
+
+ /* When generating PIC code, we need to fiddle to get
+ bfd_install_relocation to do the right thing for a PC relative
+ reloc against a local symbol which we are going to keep. */
+ if (sparc_pic_code
+ && fixP->fx_r_type == BFD_RELOC_32_PCREL_S2
+ && fixP->fx_addsy != NULL
+ && (S_IS_EXTERNAL (fixP->fx_addsy)
+ || S_IS_WEAK (fixP->fx_addsy))
+ && S_IS_DEFINED (fixP->fx_addsy)
+ && ! S_IS_COMMON (fixP->fx_addsy))
+ {
+ val = 0;
+ fixP->fx_addnumber -= 2 * S_GET_VALUE (fixP->fx_addsy);
+ }
+#endif
+
+ /* If this is a data relocation, just output VAL. */
+
+ if (fixP->fx_r_type == BFD_RELOC_16
+ || fixP->fx_r_type == BFD_RELOC_SPARC_UA16)
+ {
+ md_number_to_chars (buf, val, 2);
+ }
+ else if (fixP->fx_r_type == BFD_RELOC_32
+ || fixP->fx_r_type == BFD_RELOC_SPARC_UA32
+ || fixP->fx_r_type == BFD_RELOC_SPARC_REV32)
+ {
+ md_number_to_chars (buf, val, 4);
+ }
+ else if (fixP->fx_r_type == BFD_RELOC_64
+ || fixP->fx_r_type == BFD_RELOC_SPARC_UA64)
+ {
+ md_number_to_chars (buf, val, 8);
+ }
+ else if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ {
+ fixP->fx_done = 0;
+ return;
+ }
+ else
+ {
+ /* It's a relocation against an instruction. */
+
+ if (INSN_BIG_ENDIAN)
+ insn = bfd_getb32 ((unsigned char *) buf);
+ else
+ insn = bfd_getl32 ((unsigned char *) buf);
+
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_32_PCREL_S2:
+ val = val >> 2;
+ /* FIXME: This increment-by-one deserves a comment of why it's
+ being done! */
+ if (! sparc_pic_code
+ || fixP->fx_addsy == NULL
+ || symbol_section_p (fixP->fx_addsy))
+ ++val;
+
+ insn |= val & 0x3fffffff;
+
+ /* See if we have a delay slot. */
+ if (sparc_relax && fixP->fx_where + 8 <= fixP->fx_frag->fr_fix)
+ {
+#define G0 0
+#define O7 15
+#define XCC (2 << 20)
+#define COND(x) (((x)&0xf)<<25)
+#define CONDA COND(0x8)
+#define INSN_BPA (F2(0,1) | CONDA | BPRED | XCC)
+#define INSN_BA (F2(0,2) | CONDA)
+#define INSN_OR F3(2, 0x2, 0)
+#define INSN_NOP F2(0,4)
+
+ long delay;
+
+ /* If the instruction is a call with either:
+ restore
+ arithmetic instruction with rd == %o7
+ where rs1 != %o7 and rs2 if it is register != %o7
+ then we can optimize if the call destination is near
+ by changing the call into a branch always. */
+ if (INSN_BIG_ENDIAN)
+ delay = bfd_getb32 ((unsigned char *) buf + 4);
+ else
+ delay = bfd_getl32 ((unsigned char *) buf + 4);
+ if ((insn & OP (~0)) != OP (1) || (delay & OP (~0)) != OP (2))
+ break;
+ if ((delay & OP3 (~0)) != OP3 (0x3d) /* Restore. */
+ && ((delay & OP3 (0x28)) != 0 /* Arithmetic. */
+ || ((delay & RD (~0)) != RD (O7))))
+ break;
+ if ((delay & RS1 (~0)) == RS1 (O7)
+ || ((delay & F3I (~0)) == 0
+ && (delay & RS2 (~0)) == RS2 (O7)))
+ break;
+ /* Ensure the branch will fit into simm22. */
+ if ((val & 0x3fe00000)
+ && (val & 0x3fe00000) != 0x3fe00000)
+ break;
+ /* Check if the arch is v9 and branch will fit
+ into simm19. */
+ if (((val & 0x3c0000) == 0
+ || (val & 0x3c0000) == 0x3c0000)
+ && (sparc_arch_size == 64
+ || current_architecture >= SPARC_OPCODE_ARCH_V9))
+ /* ba,pt %xcc */
+ insn = INSN_BPA | (val & 0x7ffff);
+ else
+ /* ba */
+ insn = INSN_BA | (val & 0x3fffff);
+ if (fixP->fx_where >= 4
+ && ((delay & (0xffffffff ^ RS1 (~0)))
+ == (INSN_OR | RD (O7) | RS2 (G0))))
+ {
+ long setter;
+ int reg;
+
+ if (INSN_BIG_ENDIAN)
+ setter = bfd_getb32 ((unsigned char *) buf - 4);
+ else
+ setter = bfd_getl32 ((unsigned char *) buf - 4);
+ if ((setter & (0xffffffff ^ RD (~0)))
+ != (INSN_OR | RS1 (O7) | RS2 (G0)))
+ break;
+ /* The sequence was
+ or %o7, %g0, %rN
+ call foo
+ or %rN, %g0, %o7
+
+ If call foo was replaced with ba, replace
+ or %rN, %g0, %o7 with nop. */
+ reg = (delay & RS1 (~0)) >> 14;
+ if (reg != ((setter & RD (~0)) >> 25)
+ || reg == G0 || reg == O7)
+ break;
+
+ if (INSN_BIG_ENDIAN)
+ bfd_putb32 (INSN_NOP, (unsigned char *) buf + 4);
+ else
+ bfd_putl32 (INSN_NOP, (unsigned char *) buf + 4);
+ }
+ }
+ break;
+
+ case BFD_RELOC_SPARC_11:
+ if (! in_signed_range (val, 0x7ff))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ insn |= val & 0x7ff;
+ break;
+
+ case BFD_RELOC_SPARC_10:
+ if (! in_signed_range (val, 0x3ff))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ insn |= val & 0x3ff;
+ break;
+
+ case BFD_RELOC_SPARC_7:
+ if (! in_bitfield_range (val, 0x7f))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ insn |= val & 0x7f;
+ break;
+
+ case BFD_RELOC_SPARC_6:
+ if (! in_bitfield_range (val, 0x3f))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ insn |= val & 0x3f;
+ break;
+
+ case BFD_RELOC_SPARC_5:
+ if (! in_bitfield_range (val, 0x1f))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ insn |= val & 0x1f;
+ break;
+
+ case BFD_RELOC_SPARC_WDISP16:
+ /* FIXME: simplify. */
+ if (((val > 0) && (val & ~0x3fffc))
+ || ((val < 0) && (~(val - 1) & ~0x3fffc)))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ /* FIXME: The +1 deserves a comment. */
+ val = (val >> 2) + 1;
+ insn |= ((val & 0xc000) << 6) | (val & 0x3fff);
+ break;
+
+ case BFD_RELOC_SPARC_WDISP19:
+ /* FIXME: simplify. */
+ if (((val > 0) && (val & ~0x1ffffc))
+ || ((val < 0) && (~(val - 1) & ~0x1ffffc)))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ /* FIXME: The +1 deserves a comment. */
+ val = (val >> 2) + 1;
+ insn |= val & 0x7ffff;
+ break;
+
+ case BFD_RELOC_SPARC_HH22:
+ val = BSR (val, 32);
+ /* Fall through. */
+
+ case BFD_RELOC_SPARC_LM22:
+ case BFD_RELOC_HI22:
+ if (!fixP->fx_addsy)
+ insn |= (val >> 10) & 0x3fffff;
+ else
+ /* FIXME: Need comment explaining why we do this. */
+ insn &= ~0xffff;
+ break;
+
+ case BFD_RELOC_SPARC22:
+ if (val & ~0x003fffff)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ insn |= (val & 0x3fffff);
+ break;
+
+ case BFD_RELOC_SPARC_HM10:
+ val = BSR (val, 32);
+ /* Fall through. */
+
+ case BFD_RELOC_LO10:
+ if (!fixP->fx_addsy)
+ insn |= val & 0x3ff;
+ else
+ /* FIXME: Need comment explaining why we do this. */
+ insn &= ~0xff;
+ break;
+
+ case BFD_RELOC_SPARC_OLO10:
+ val &= 0x3ff;
+ val += fixP->tc_fix_data;
+ /* Fall through. */
+
+ case BFD_RELOC_SPARC13:
+ if (! in_signed_range (val, 0x1fff))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ insn |= val & 0x1fff;
+ break;
+
+ case BFD_RELOC_SPARC_WDISP22:
+ val = (val >> 2) + 1;
+ /* Fall through. */
+ case BFD_RELOC_SPARC_BASE22:
+ insn |= val & 0x3fffff;
+ break;
+
+ case BFD_RELOC_SPARC_H44:
+ if (!fixP->fx_addsy)
+ {
+ bfd_vma tval = val;
+ tval >>= 22;
+ insn |= tval & 0x3fffff;
+ }
+ break;
+
+ case BFD_RELOC_SPARC_M44:
+ if (!fixP->fx_addsy)
+ insn |= (val >> 12) & 0x3ff;
+ break;
+
+ case BFD_RELOC_SPARC_L44:
+ if (!fixP->fx_addsy)
+ insn |= val & 0xfff;
+ break;
+
+ case BFD_RELOC_SPARC_HIX22:
+ if (!fixP->fx_addsy)
+ {
+ val ^= ~(offsetT) 0;
+ insn |= (val >> 10) & 0x3fffff;
+ }
+ break;
+
+ case BFD_RELOC_SPARC_LOX10:
+ if (!fixP->fx_addsy)
+ insn |= 0x1c00 | (val & 0x3ff);
+ break;
+
+ case BFD_RELOC_NONE:
+ default:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("bad or unhandled relocation type: 0x%02x"),
+ fixP->fx_r_type);
+ break;
+ }
+
+ if (INSN_BIG_ENDIAN)
+ bfd_putb32 (insn, (unsigned char *) buf);
+ else
+ bfd_putl32 (insn, (unsigned char *) buf);
+ }
+
+ /* Are we finished with this relocation now? */
+ if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
+ fixP->fx_done = 1;
+}
+
+/* Translate internal representation of relocation info to BFD target
+ format. */
+
+arelent **
+tc_gen_reloc (section, fixp)
+ asection *section ATTRIBUTE_UNUSED;
+ fixS *fixp;
+{
+ static arelent *relocs[3];
+ arelent *reloc;
+ bfd_reloc_code_real_type code;
+
+ relocs[0] = reloc = (arelent *) xmalloc (sizeof (arelent));
+ relocs[1] = NULL;
+
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_16:
+ case BFD_RELOC_32:
+ case BFD_RELOC_HI22:
+ case BFD_RELOC_LO10:
+ case BFD_RELOC_32_PCREL_S2:
+ case BFD_RELOC_SPARC13:
+ case BFD_RELOC_SPARC22:
+ case BFD_RELOC_SPARC_BASE13:
+ case BFD_RELOC_SPARC_WDISP16:
+ case BFD_RELOC_SPARC_WDISP19:
+ case BFD_RELOC_SPARC_WDISP22:
+ case BFD_RELOC_64:
+ case BFD_RELOC_SPARC_5:
+ case BFD_RELOC_SPARC_6:
+ case BFD_RELOC_SPARC_7:
+ case BFD_RELOC_SPARC_10:
+ case BFD_RELOC_SPARC_11:
+ case BFD_RELOC_SPARC_HH22:
+ case BFD_RELOC_SPARC_HM10:
+ case BFD_RELOC_SPARC_LM22:
+ case BFD_RELOC_SPARC_PC_HH22:
+ case BFD_RELOC_SPARC_PC_HM10:
+ case BFD_RELOC_SPARC_PC_LM22:
+ case BFD_RELOC_SPARC_H44:
+ case BFD_RELOC_SPARC_M44:
+ case BFD_RELOC_SPARC_L44:
+ case BFD_RELOC_SPARC_HIX22:
+ case BFD_RELOC_SPARC_LOX10:
+ case BFD_RELOC_SPARC_REV32:
+ case BFD_RELOC_SPARC_OLO10:
+ case BFD_RELOC_SPARC_UA16:
+ case BFD_RELOC_SPARC_UA32:
+ case BFD_RELOC_SPARC_UA64:
+ case BFD_RELOC_8_PCREL:
+ case BFD_RELOC_16_PCREL:
+ case BFD_RELOC_32_PCREL:
+ case BFD_RELOC_64_PCREL:
+ case BFD_RELOC_SPARC_PLT32:
+ case BFD_RELOC_SPARC_PLT64:
+ case BFD_RELOC_VTABLE_ENTRY:
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_SPARC_TLS_GD_HI22:
+ case BFD_RELOC_SPARC_TLS_GD_LO10:
+ case BFD_RELOC_SPARC_TLS_GD_ADD:
+ case BFD_RELOC_SPARC_TLS_GD_CALL:
+ case BFD_RELOC_SPARC_TLS_LDM_HI22:
+ case BFD_RELOC_SPARC_TLS_LDM_LO10:
+ case BFD_RELOC_SPARC_TLS_LDM_ADD:
+ case BFD_RELOC_SPARC_TLS_LDM_CALL:
+ case BFD_RELOC_SPARC_TLS_LDO_HIX22:
+ case BFD_RELOC_SPARC_TLS_LDO_LOX10:
+ case BFD_RELOC_SPARC_TLS_LDO_ADD:
+ case BFD_RELOC_SPARC_TLS_IE_HI22:
+ case BFD_RELOC_SPARC_TLS_IE_LO10:
+ case BFD_RELOC_SPARC_TLS_IE_LD:
+ case BFD_RELOC_SPARC_TLS_IE_LDX:
+ case BFD_RELOC_SPARC_TLS_IE_ADD:
+ case BFD_RELOC_SPARC_TLS_LE_HIX22:
+ case BFD_RELOC_SPARC_TLS_LE_LOX10:
+ case BFD_RELOC_SPARC_TLS_DTPOFF32:
+ case BFD_RELOC_SPARC_TLS_DTPOFF64:
+ code = fixp->fx_r_type;
+ break;
+ default:
+ abort ();
+ return NULL;
+ }
+
+#if defined (OBJ_ELF) || defined (OBJ_AOUT)
+ /* If we are generating PIC code, we need to generate a different
+ set of relocs. */
+
+#ifdef OBJ_ELF
+#define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
+#else
+#define GOT_NAME "__GLOBAL_OFFSET_TABLE_"
+#endif
+
+ /* This code must be parallel to the OBJ_ELF tc_fix_adjustable. */
+
+ if (sparc_pic_code)
+ {
+ switch (code)
+ {
+ case BFD_RELOC_32_PCREL_S2:
+ if (generic_force_reloc (fixp))
+ code = BFD_RELOC_SPARC_WPLT30;
+ break;
+ case BFD_RELOC_HI22:
+ if (fixp->fx_addsy != NULL
+ && strcmp (S_GET_NAME (fixp->fx_addsy), GOT_NAME) == 0)
+ code = BFD_RELOC_SPARC_PC22;
+ else
+ code = BFD_RELOC_SPARC_GOT22;
+ break;
+ case BFD_RELOC_LO10:
+ if (fixp->fx_addsy != NULL
+ && strcmp (S_GET_NAME (fixp->fx_addsy), GOT_NAME) == 0)
+ code = BFD_RELOC_SPARC_PC10;
+ else
+ code = BFD_RELOC_SPARC_GOT10;
+ break;
+ case BFD_RELOC_SPARC13:
+ code = BFD_RELOC_SPARC_GOT13;
+ break;
+ default:
+ break;
+ }
+ }
+#endif /* defined (OBJ_ELF) || defined (OBJ_AOUT) */
+
+ if (code == BFD_RELOC_SPARC_OLO10)
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_LO10);
+ else
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+ if (reloc->howto == 0)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("internal error: can't export reloc type %d (`%s')"),
+ fixp->fx_r_type, bfd_get_reloc_code_name (code));
+ xfree (reloc);
+ relocs[0] = NULL;
+ return relocs;
+ }
+
+ /* @@ Why fx_addnumber sometimes and fx_offset other times? */
+#ifdef OBJ_AOUT
+
+ if (reloc->howto->pc_relative == 0
+ || code == BFD_RELOC_SPARC_PC10
+ || code == BFD_RELOC_SPARC_PC22)
+ reloc->addend = fixp->fx_addnumber;
+ else if (sparc_pic_code
+ && fixp->fx_r_type == BFD_RELOC_32_PCREL_S2
+ && fixp->fx_addsy != NULL
+ && (S_IS_EXTERNAL (fixp->fx_addsy)
+ || S_IS_WEAK (fixp->fx_addsy))
+ && S_IS_DEFINED (fixp->fx_addsy)
+ && ! S_IS_COMMON (fixp->fx_addsy))
+ reloc->addend = fixp->fx_addnumber;
+ else
+ reloc->addend = fixp->fx_offset - reloc->address;
+
+#else /* elf or coff */
+
+ if (code != BFD_RELOC_32_PCREL_S2
+ && code != BFD_RELOC_SPARC_WDISP22
+ && code != BFD_RELOC_SPARC_WDISP16
+ && code != BFD_RELOC_SPARC_WDISP19
+ && code != BFD_RELOC_SPARC_WPLT30
+ && code != BFD_RELOC_SPARC_TLS_GD_CALL
+ && code != BFD_RELOC_SPARC_TLS_LDM_CALL)
+ reloc->addend = fixp->fx_addnumber;
+ else if (symbol_section_p (fixp->fx_addsy))
+ reloc->addend = (section->vma
+ + fixp->fx_addnumber
+ + md_pcrel_from (fixp));
+ else
+ reloc->addend = fixp->fx_offset;
+#endif
+
+ /* We expand R_SPARC_OLO10 to R_SPARC_LO10 and R_SPARC_13
+ on the same location. */
+ if (code == BFD_RELOC_SPARC_OLO10)
+ {
+ relocs[1] = reloc = (arelent *) xmalloc (sizeof (arelent));
+ relocs[2] = NULL;
+
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr
+ = symbol_get_bfdsym (section_symbol (absolute_section));
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_SPARC13);
+ reloc->addend = fixp->tc_fix_data;
+ }
+
+ return relocs;
+}
+
+/* We have no need to default values of symbols. */
+
+symbolS *
+md_undefined_symbol (name)
+ char *name ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
+
+/* Round up a section size to the appropriate boundary. */
+
+valueT
+md_section_align (segment, size)
+ segT segment ATTRIBUTE_UNUSED;
+ valueT size;
+{
+#ifndef OBJ_ELF
+ /* This is not right for ELF; a.out wants it, and COFF will force
+ the alignment anyways. */
+ valueT align = ((valueT) 1
+ << (valueT) bfd_get_section_alignment (stdoutput, segment));
+ valueT newsize;
+
+ /* Turn alignment value into a mask. */
+ align--;
+ newsize = (size + align) & ~align;
+ return newsize;
+#else
+ return size;
+#endif
+}
+
+/* Exactly what point is a PC-relative offset relative TO?
+ On the sparc, they're relative to the address of the offset, plus
+ its size. This gets us to the following instruction.
+ (??? Is this right? FIXME-SOON) */
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ long ret;
+
+ ret = fixP->fx_where + fixP->fx_frag->fr_address;
+ if (! sparc_pic_code
+ || fixP->fx_addsy == NULL
+ || symbol_section_p (fixP->fx_addsy))
+ ret += fixP->fx_size;
+ return ret;
+}
+
+/* Return log2 (VALUE), or -1 if VALUE is not an exact positive power
+ of two. */
+
+static int
+log2 (value)
+ int value;
+{
+ int shift;
+
+ if (value <= 0)
+ return -1;
+
+ for (shift = 0; (value & 1) == 0; value >>= 1)
+ ++shift;
+
+ return (value == 1) ? shift : -1;
+}
+
+/* Sort of like s_lcomm. */
+
+#ifndef OBJ_ELF
+static int max_alignment = 15;
+#endif
+
+static void
+s_reserve (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *name;
+ char *p;
+ char c;
+ int align;
+ int size;
+ int temp;
+ symbolS *symbolP;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after name"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ ++input_line_pointer;
+
+ if ((size = get_absolute_expression ()) < 0)
+ {
+ as_bad (_("BSS length (%d.) <0! Ignored."), size);
+ ignore_rest_of_line ();
+ return;
+ } /* Bad length. */
+
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+
+ if (strncmp (input_line_pointer, ",\"bss\"", 6) != 0
+ && strncmp (input_line_pointer, ",\".bss\"", 7) != 0)
+ {
+ as_bad (_("bad .reserve segment -- expected BSS segment"));
+ return;
+ }
+
+ if (input_line_pointer[2] == '.')
+ input_line_pointer += 7;
+ else
+ input_line_pointer += 6;
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\n')
+ {
+ as_bad (_("missing alignment"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ align = (int) get_absolute_expression ();
+
+#ifndef OBJ_ELF
+ if (align > max_alignment)
+ {
+ align = max_alignment;
+ as_warn (_("alignment too large; assuming %d"), align);
+ }
+#endif
+
+ if (align < 0)
+ {
+ as_bad (_("negative alignment"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (align != 0)
+ {
+ temp = log2 (align);
+ if (temp < 0)
+ {
+ as_bad (_("alignment not a power of 2"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ align = temp;
+ }
+
+ record_alignment (bss_section, align);
+ }
+ else
+ align = 0;
+
+ if (!S_IS_DEFINED (symbolP)
+#ifdef OBJ_AOUT
+ && S_GET_OTHER (symbolP) == 0
+ && S_GET_DESC (symbolP) == 0
+#endif
+ )
+ {
+ if (! need_pass_2)
+ {
+ char *pfrag;
+ segT current_seg = now_seg;
+ subsegT current_subseg = now_subseg;
+
+ /* Switch to bss. */
+ subseg_set (bss_section, 1);
+
+ if (align)
+ /* Do alignment. */
+ frag_align (align, 0, 0);
+
+ /* Detach from old frag. */
+ if (S_GET_SEGMENT (symbolP) == bss_section)
+ symbol_get_frag (symbolP)->fr_symbol = NULL;
+
+ symbol_set_frag (symbolP, frag_now);
+ pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
+ (offsetT) size, (char *) 0);
+ *pfrag = 0;
+
+ S_SET_SEGMENT (symbolP, bss_section);
+
+ subseg_set (current_seg, current_subseg);
+
+#ifdef OBJ_ELF
+ S_SET_SIZE (symbolP, size);
+#endif
+ }
+ }
+ else
+ {
+ as_warn ("Ignoring attempt to re-define symbol %s",
+ S_GET_NAME (symbolP));
+ } /* if not redefining. */
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_common (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *name;
+ char c;
+ char *p;
+ offsetT temp, size;
+ symbolS *symbolP;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ /* Just after name is now '\0'. */
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after symbol-name"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ /* Skip ','. */
+ input_line_pointer++;
+
+ if ((temp = get_absolute_expression ()) < 0)
+ {
+ as_bad (_(".COMMon length (%lu) out of range ignored"),
+ (unsigned long) temp);
+ ignore_rest_of_line ();
+ return;
+ }
+ size = temp;
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+ if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
+ {
+ as_bad (_("Ignoring attempt to re-define symbol"));
+ ignore_rest_of_line ();
+ return;
+ }
+ if (S_GET_VALUE (symbolP) != 0)
+ {
+ if (S_GET_VALUE (symbolP) != (valueT) size)
+ {
+ as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
+ S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), (long) size);
+ }
+ }
+ else
+ {
+#ifndef OBJ_ELF
+ S_SET_VALUE (symbolP, (valueT) size);
+ S_SET_EXTERNAL (symbolP);
+#endif
+ }
+ know (symbol_get_frag (symbolP) == &zero_address_frag);
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after common length"));
+ ignore_rest_of_line ();
+ return;
+ }
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '"')
+ {
+ temp = get_absolute_expression ();
+
+#ifndef OBJ_ELF
+ if (temp > max_alignment)
+ {
+ temp = max_alignment;
+ as_warn (_("alignment too large; assuming %d"), temp);
+ }
+#endif
+
+ if (temp < 0)
+ {
+ as_bad (_("negative alignment"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+#ifdef OBJ_ELF
+ if (symbol_get_obj (symbolP)->local)
+ {
+ segT old_sec;
+ int old_subsec;
+ char *p;
+ int align;
+
+ old_sec = now_seg;
+ old_subsec = now_subseg;
+
+ if (temp == 0)
+ align = 0;
+ else
+ align = log2 (temp);
+
+ if (align < 0)
+ {
+ as_bad (_("alignment not a power of 2"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ record_alignment (bss_section, align);
+ subseg_set (bss_section, 0);
+ if (align)
+ frag_align (align, 0, 0);
+ if (S_GET_SEGMENT (symbolP) == bss_section)
+ symbol_get_frag (symbolP)->fr_symbol = 0;
+ symbol_set_frag (symbolP, frag_now);
+ p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
+ (offsetT) size, (char *) 0);
+ *p = 0;
+ S_SET_SEGMENT (symbolP, bss_section);
+ S_CLEAR_EXTERNAL (symbolP);
+ S_SET_SIZE (symbolP, size);
+ subseg_set (old_sec, old_subsec);
+ }
+ else
+#endif /* OBJ_ELF */
+ {
+ allocate_common:
+ S_SET_VALUE (symbolP, (valueT) size);
+#ifdef OBJ_ELF
+ S_SET_ALIGN (symbolP, temp);
+ S_SET_SIZE (symbolP, size);
+#endif
+ S_SET_EXTERNAL (symbolP);
+ S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
+ }
+ }
+ else
+ {
+ input_line_pointer++;
+ /* @@ Some use the dot, some don't. Can we get some consistency?? */
+ if (*input_line_pointer == '.')
+ input_line_pointer++;
+ /* @@ Some say data, some say bss. */
+ if (strncmp (input_line_pointer, "bss\"", 4)
+ && strncmp (input_line_pointer, "data\"", 5))
+ {
+ while (*--input_line_pointer != '"')
+ ;
+ input_line_pointer--;
+ goto bad_common_segment;
+ }
+ while (*input_line_pointer++ != '"')
+ ;
+ goto allocate_common;
+ }
+
+#ifdef BFD_ASSEMBLER
+ symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
+#endif
+
+ demand_empty_rest_of_line ();
+ return;
+
+ {
+ bad_common_segment:
+ p = input_line_pointer;
+ while (*p && *p != '\n')
+ p++;
+ c = *p;
+ *p = '\0';
+ as_bad (_("bad .common segment %s"), input_line_pointer + 1);
+ *p = c;
+ input_line_pointer = p;
+ ignore_rest_of_line ();
+ return;
+ }
+}
+
+/* Handle the .empty pseudo-op. This suppresses the warnings about
+ invalid delay slot usage. */
+
+static void
+s_empty (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ /* The easy way to implement is to just forget about the last
+ instruction. */
+ last_insn = NULL;
+}
+
+static void
+s_seg (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+
+ if (strncmp (input_line_pointer, "\"text\"", 6) == 0)
+ {
+ input_line_pointer += 6;
+ s_text (0);
+ return;
+ }
+ if (strncmp (input_line_pointer, "\"data\"", 6) == 0)
+ {
+ input_line_pointer += 6;
+ s_data (0);
+ return;
+ }
+ if (strncmp (input_line_pointer, "\"data1\"", 7) == 0)
+ {
+ input_line_pointer += 7;
+ s_data1 ();
+ return;
+ }
+ if (strncmp (input_line_pointer, "\"bss\"", 5) == 0)
+ {
+ input_line_pointer += 5;
+ /* We only support 2 segments -- text and data -- for now, so
+ things in the "bss segment" will have to go into data for now.
+ You can still allocate SEG_BSS stuff with .lcomm or .reserve. */
+ subseg_set (data_section, 255); /* FIXME-SOMEDAY. */
+ return;
+ }
+ as_bad (_("Unknown segment type"));
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_data1 ()
+{
+ subseg_set (data_section, 1);
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_proc (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ ++input_line_pointer;
+ }
+ ++input_line_pointer;
+}
+
+/* This static variable is set by s_uacons to tell sparc_cons_align
+ that the expression does not need to be aligned. */
+
+static int sparc_no_align_cons = 0;
+
+/* This static variable is set by sparc_cons to emit requested types
+ of relocations in cons_fix_new_sparc. */
+
+static const char *sparc_cons_special_reloc;
+
+/* This handles the unaligned space allocation pseudo-ops, such as
+ .uaword. .uaword is just like .word, but the value does not need
+ to be aligned. */
+
+static void
+s_uacons (bytes)
+ int bytes;
+{
+ /* Tell sparc_cons_align not to align this value. */
+ sparc_no_align_cons = 1;
+ cons (bytes);
+ sparc_no_align_cons = 0;
+}
+
+/* This handles the native word allocation pseudo-op .nword.
+ For sparc_arch_size 32 it is equivalent to .word, for
+ sparc_arch_size 64 it is equivalent to .xword. */
+
+static void
+s_ncons (bytes)
+ int bytes ATTRIBUTE_UNUSED;
+{
+ cons (sparc_arch_size == 32 ? 4 : 8);
+}
+
+#ifdef OBJ_ELF
+/* Handle the SPARC ELF .register pseudo-op. This sets the binding of a
+ global register.
+ The syntax is:
+
+ .register %g[2367],{#scratch|symbolname|#ignore}
+*/
+
+static void
+s_register (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char c;
+ int reg;
+ int flags;
+ const char *regname;
+
+ if (input_line_pointer[0] != '%'
+ || input_line_pointer[1] != 'g'
+ || ((input_line_pointer[2] & ~1) != '2'
+ && (input_line_pointer[2] & ~1) != '6')
+ || input_line_pointer[3] != ',')
+ as_bad (_("register syntax is .register %%g[2367],{#scratch|symbolname|#ignore}"));
+ reg = input_line_pointer[2] - '0';
+ input_line_pointer += 4;
+
+ if (*input_line_pointer == '#')
+ {
+ ++input_line_pointer;
+ regname = input_line_pointer;
+ c = get_symbol_end ();
+ if (strcmp (regname, "scratch") && strcmp (regname, "ignore"))
+ as_bad (_("register syntax is .register %%g[2367],{#scratch|symbolname|#ignore}"));
+ if (regname[0] == 'i')
+ regname = NULL;
+ else
+ regname = "";
+ }
+ else
+ {
+ regname = input_line_pointer;
+ c = get_symbol_end ();
+ }
+ if (sparc_arch_size == 64)
+ {
+ if (globals[reg])
+ {
+ if ((regname && globals[reg] != (symbolS *) 1
+ && strcmp (S_GET_NAME (globals[reg]), regname))
+ || ((regname != NULL) ^ (globals[reg] != (symbolS *) 1)))
+ as_bad (_("redefinition of global register"));
+ }
+ else
+ {
+ if (regname == NULL)
+ globals[reg] = (symbolS *) 1;
+ else
+ {
+ if (*regname)
+ {
+ if (symbol_find (regname))
+ as_bad (_("Register symbol %s already defined."),
+ regname);
+ }
+ globals[reg] = symbol_make (regname);
+ flags = symbol_get_bfdsym (globals[reg])->flags;
+ if (! *regname)
+ flags = flags & ~(BSF_GLOBAL|BSF_LOCAL|BSF_WEAK);
+ if (! (flags & (BSF_GLOBAL|BSF_LOCAL|BSF_WEAK)))
+ flags |= BSF_GLOBAL;
+ symbol_get_bfdsym (globals[reg])->flags = flags;
+ S_SET_VALUE (globals[reg], (valueT) reg);
+ S_SET_ALIGN (globals[reg], reg);
+ S_SET_SIZE (globals[reg], 0);
+ /* Although we actually want undefined_section here,
+ we have to use absolute_section, because otherwise
+ generic as code will make it a COM section.
+ We fix this up in sparc_adjust_symtab. */
+ S_SET_SEGMENT (globals[reg], absolute_section);
+ S_SET_OTHER (globals[reg], 0);
+ elf_symbol (symbol_get_bfdsym (globals[reg]))
+ ->internal_elf_sym.st_info =
+ ELF_ST_INFO(STB_GLOBAL, STT_REGISTER);
+ elf_symbol (symbol_get_bfdsym (globals[reg]))
+ ->internal_elf_sym.st_shndx = SHN_UNDEF;
+ }
+ }
+ }
+
+ *input_line_pointer = c;
+
+ demand_empty_rest_of_line ();
+}
+
+/* Adjust the symbol table. We set undefined sections for STT_REGISTER
+ symbols which need it. */
+
+void
+sparc_adjust_symtab ()
+{
+ symbolS *sym;
+
+ for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
+ {
+ if (ELF_ST_TYPE (elf_symbol (symbol_get_bfdsym (sym))
+ ->internal_elf_sym.st_info) != STT_REGISTER)
+ continue;
+
+ if (ELF_ST_TYPE (elf_symbol (symbol_get_bfdsym (sym))
+ ->internal_elf_sym.st_shndx != SHN_UNDEF))
+ continue;
+
+ S_SET_SEGMENT (sym, undefined_section);
+ }
+}
+#endif
+
+/* If the --enforce-aligned-data option is used, we require .word,
+ et. al., to be aligned correctly. We do it by setting up an
+ rs_align_code frag, and checking in HANDLE_ALIGN to make sure that
+ no unexpected alignment was introduced.
+
+ The SunOS and Solaris native assemblers enforce aligned data by
+ default. We don't want to do that, because gcc can deliberately
+ generate misaligned data if the packed attribute is used. Instead,
+ we permit misaligned data by default, and permit the user to set an
+ option to check for it. */
+
+void
+sparc_cons_align (nbytes)
+ int nbytes;
+{
+ int nalign;
+ char *p;
+
+ /* Only do this if we are enforcing aligned data. */
+ if (! enforce_aligned_data)
+ return;
+
+ /* Don't align if this is an unaligned pseudo-op. */
+ if (sparc_no_align_cons)
+ return;
+
+ nalign = log2 (nbytes);
+ if (nalign == 0)
+ return;
+
+ assert (nalign > 0);
+
+ if (now_seg == absolute_section)
+ {
+ if ((abs_section_offset & ((1 << nalign) - 1)) != 0)
+ as_bad (_("misaligned data"));
+ return;
+ }
+
+ p = frag_var (rs_align_test, 1, 1, (relax_substateT) 0,
+ (symbolS *) NULL, (offsetT) nalign, (char *) NULL);
+
+ record_alignment (now_seg, nalign);
+}
+
+/* This is called from HANDLE_ALIGN in tc-sparc.h. */
+
+void
+sparc_handle_align (fragp)
+ fragS *fragp;
+{
+ int count, fix;
+ char *p;
+
+ count = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
+
+ switch (fragp->fr_type)
+ {
+ case rs_align_test:
+ if (count != 0)
+ as_bad_where (fragp->fr_file, fragp->fr_line, _("misaligned data"));
+ break;
+
+ case rs_align_code:
+ p = fragp->fr_literal + fragp->fr_fix;
+ fix = 0;
+
+ if (count & 3)
+ {
+ fix = count & 3;
+ memset (p, 0, fix);
+ p += fix;
+ count -= fix;
+ }
+
+ if (SPARC_OPCODE_ARCH_V9_P (max_architecture) && count > 8)
+ {
+ unsigned wval = (0x30680000 | count >> 2); /* ba,a,pt %xcc, 1f */
+ if (INSN_BIG_ENDIAN)
+ number_to_chars_bigendian (p, wval, 4);
+ else
+ number_to_chars_littleendian (p, wval, 4);
+ p += 4;
+ count -= 4;
+ fix += 4;
+ }
+
+ if (INSN_BIG_ENDIAN)
+ number_to_chars_bigendian (p, 0x01000000, 4);
+ else
+ number_to_chars_littleendian (p, 0x01000000, 4);
+
+ fragp->fr_fix += fix;
+ fragp->fr_var = 4;
+ break;
+
+ default:
+ break;
+ }
+}
+
+#ifdef OBJ_ELF
+/* Some special processing for a Sparc ELF file. */
+
+void
+sparc_elf_final_processing ()
+{
+ /* Set the Sparc ELF flag bits. FIXME: There should probably be some
+ sort of BFD interface for this. */
+ if (sparc_arch_size == 64)
+ {
+ switch (sparc_memory_model)
+ {
+ case MM_RMO:
+ elf_elfheader (stdoutput)->e_flags |= EF_SPARCV9_RMO;
+ break;
+ case MM_PSO:
+ elf_elfheader (stdoutput)->e_flags |= EF_SPARCV9_PSO;
+ break;
+ default:
+ break;
+ }
+ }
+ else if (current_architecture >= SPARC_OPCODE_ARCH_V9)
+ elf_elfheader (stdoutput)->e_flags |= EF_SPARC_32PLUS;
+ if (current_architecture == SPARC_OPCODE_ARCH_V9A)
+ elf_elfheader (stdoutput)->e_flags |= EF_SPARC_SUN_US1;
+ else if (current_architecture == SPARC_OPCODE_ARCH_V9B)
+ elf_elfheader (stdoutput)->e_flags |= EF_SPARC_SUN_US1|EF_SPARC_SUN_US3;
+}
+
+void
+sparc_cons (exp, size)
+ expressionS *exp;
+ int size;
+{
+ char *save;
+
+ SKIP_WHITESPACE ();
+ sparc_cons_special_reloc = NULL;
+ save = input_line_pointer;
+ if (input_line_pointer[0] == '%'
+ && input_line_pointer[1] == 'r'
+ && input_line_pointer[2] == '_')
+ {
+ if (strncmp (input_line_pointer + 3, "disp", 4) == 0)
+ {
+ input_line_pointer += 7;
+ sparc_cons_special_reloc = "disp";
+ }
+ else if (strncmp (input_line_pointer + 3, "plt", 3) == 0)
+ {
+ if (size != 4 && size != 8)
+ as_bad (_("Illegal operands: %%r_plt in %d-byte data field"), size);
+ else
+ {
+ input_line_pointer += 6;
+ sparc_cons_special_reloc = "plt";
+ }
+ }
+ else if (strncmp (input_line_pointer + 3, "tls_dtpoff", 10) == 0)
+ {
+ if (size != 4 && size != 8)
+ as_bad (_("Illegal operands: %%r_tls_dtpoff in %d-byte data field"), size);
+ else
+ {
+ input_line_pointer += 13;
+ sparc_cons_special_reloc = "tls_dtpoff";
+ }
+ }
+ if (sparc_cons_special_reloc)
+ {
+ int bad = 0;
+
+ switch (size)
+ {
+ case 1:
+ if (*input_line_pointer != '8')
+ bad = 1;
+ input_line_pointer--;
+ break;
+ case 2:
+ if (input_line_pointer[0] != '1' || input_line_pointer[1] != '6')
+ bad = 1;
+ break;
+ case 4:
+ if (input_line_pointer[0] != '3' || input_line_pointer[1] != '2')
+ bad = 1;
+ break;
+ case 8:
+ if (input_line_pointer[0] != '6' || input_line_pointer[1] != '4')
+ bad = 1;
+ break;
+ default:
+ bad = 1;
+ break;
+ }
+
+ if (bad)
+ {
+ as_bad (_("Illegal operands: Only %%r_%s%d allowed in %d-byte data fields"),
+ sparc_cons_special_reloc, size * 8, size);
+ }
+ else
+ {
+ input_line_pointer += 2;
+ if (*input_line_pointer != '(')
+ {
+ as_bad (_("Illegal operands: %%r_%s%d requires arguments in ()"),
+ sparc_cons_special_reloc, size * 8);
+ bad = 1;
+ }
+ }
+
+ if (bad)
+ {
+ input_line_pointer = save;
+ sparc_cons_special_reloc = NULL;
+ }
+ else
+ {
+ int c;
+ char *end = ++input_line_pointer;
+ int npar = 0;
+
+ while (! is_end_of_line[(c = *end)])
+ {
+ if (c == '(')
+ npar++;
+ else if (c == ')')
+ {
+ if (!npar)
+ break;
+ npar--;
+ }
+ end++;
+ }
+
+ if (c != ')')
+ as_bad (_("Illegal operands: %%r_%s%d requires arguments in ()"),
+ sparc_cons_special_reloc, size * 8);
+ else
+ {
+ *end = '\0';
+ expression (exp);
+ *end = c;
+ if (input_line_pointer != end)
+ {
+ as_bad (_("Illegal operands: %%r_%s%d requires arguments in ()"),
+ sparc_cons_special_reloc, size * 8);
+ }
+ else
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ c = *input_line_pointer;
+ if (! is_end_of_line[c] && c != ',')
+ as_bad (_("Illegal operands: garbage after %%r_%s%d()"),
+ sparc_cons_special_reloc, size * 8);
+ }
+ }
+ }
+ }
+ }
+ if (sparc_cons_special_reloc == NULL)
+ expression (exp);
+}
+
+#endif
+
+/* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
+ reloc for a cons. We could use the definition there, except that
+ we want to handle little endian relocs specially. */
+
+void
+cons_fix_new_sparc (frag, where, nbytes, exp)
+ fragS *frag;
+ int where;
+ unsigned int nbytes;
+ expressionS *exp;
+{
+ bfd_reloc_code_real_type r;
+
+ r = (nbytes == 1 ? BFD_RELOC_8 :
+ (nbytes == 2 ? BFD_RELOC_16 :
+ (nbytes == 4 ? BFD_RELOC_32 : BFD_RELOC_64)));
+
+ if (target_little_endian_data
+ && nbytes == 4
+ && now_seg->flags & SEC_ALLOC)
+ r = BFD_RELOC_SPARC_REV32;
+
+ if (sparc_cons_special_reloc)
+ {
+ if (*sparc_cons_special_reloc == 'd')
+ switch (nbytes)
+ {
+ case 1: r = BFD_RELOC_8_PCREL; break;
+ case 2: r = BFD_RELOC_16_PCREL; break;
+ case 4: r = BFD_RELOC_32_PCREL; break;
+ case 8: r = BFD_RELOC_64_PCREL; break;
+ default: abort ();
+ }
+ else if (*sparc_cons_special_reloc == 'p')
+ switch (nbytes)
+ {
+ case 4: r = BFD_RELOC_SPARC_PLT32; break;
+ case 8: r = BFD_RELOC_SPARC_PLT64; break;
+ }
+ else
+ switch (nbytes)
+ {
+ case 4: r = BFD_RELOC_SPARC_TLS_DTPOFF32; break;
+ case 8: r = BFD_RELOC_SPARC_TLS_DTPOFF64; break;
+ }
+ }
+ else if (sparc_no_align_cons)
+ {
+ switch (nbytes)
+ {
+ case 2: r = BFD_RELOC_SPARC_UA16; break;
+ case 4: r = BFD_RELOC_SPARC_UA32; break;
+ case 8: r = BFD_RELOC_SPARC_UA64; break;
+ default: abort ();
+ }
+ }
+
+ fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
+ sparc_cons_special_reloc = NULL;
+}
+
+void
+sparc_cfi_frame_initial_instructions ()
+{
+ cfi_add_CFA_def_cfa (14, sparc_arch_size == 64 ? 0x7ff : 0);
+}
+
+int
+sparc_regname_to_dw2regnum (const char *regname)
+{
+ char *p, *q;
+
+ if (!regname[0])
+ return -1;
+
+ q = "goli";
+ p = strchr (q, regname[0]);
+ if (p)
+ {
+ if (regname[1] < '0' || regname[1] > '8' || regname[2])
+ return -1;
+ return (p - q) * 8 + regname[1] - '0';
+ }
+ if (regname[0] == 's' && regname[1] == 'p' && !regname[2])
+ return 14;
+ if (regname[0] == 'f' && regname[1] == 'p' && !regname[2])
+ return 30;
+ if (regname[0] == 'f' || regname[0] == 'r')
+ {
+ unsigned int regnum;
+
+ regnum = strtoul (regname + 1, &q, 10);
+ if (p == q || *q)
+ return -1;
+ if (regnum >= ((regname[0] == 'f'
+ && SPARC_OPCODE_ARCH_V9_P (max_architecture))
+ ? 64 : 32))
+ return -1;
+ if (regname[0] == 'f')
+ {
+ regnum += 32;
+ if (regnum >= 64 && (regnum & 1))
+ return -1;
+ }
+ return regnum;
+ }
+ return -1;
+}
+
+void
+sparc_cfi_emit_pcrel_expr (expressionS *exp, unsigned int nbytes)
+{
+ sparc_cons_special_reloc = "disp";
+ sparc_no_align_cons = 1;
+ emit_expr (exp, nbytes);
+ sparc_no_align_cons = 0;
+ sparc_cons_special_reloc = NULL;
+}
diff --git a/x/binutils/gas/config/tc-sparc.h b/x/binutils/gas/config/tc-sparc.h
new file mode 100644
index 0000000..e99222b
--- /dev/null
+++ b/x/binutils/gas/config/tc-sparc.h
@@ -0,0 +1,194 @@
+/* tc-sparc.h - Macros and type defines for the sparc.
+ Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2,
+ or (at your option) any later version.
+
+ GAS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with GAS; see the file COPYING. If not, write
+ to the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef TC_SPARC
+#define TC_SPARC 1
+
+#ifdef ANSI_PROTOTYPES
+struct frag;
+#endif
+
+/* This is used to set the default value for `target_big_endian'. */
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#define LOCAL_LABELS_FB 1
+
+#define TARGET_ARCH bfd_arch_sparc
+
+extern const char *sparc_target_format PARAMS ((void));
+#define TARGET_FORMAT sparc_target_format ()
+
+#define RELOC_EXPANSION_POSSIBLE
+#define MAX_RELOC_EXPANSION 2
+
+#if 0
+#ifdef TE_SPARCAOUT
+/* Bi-endian support may eventually be unconditional, but until things are
+ working well it's only provided for targets that need it. */
+#define SPARC_BIENDIAN
+#endif
+#endif
+/* Make it unconditional and check if -EL is valid after option parsing */
+#define SPARC_BIENDIAN
+
+#define WORKING_DOT_WORD
+
+#define md_convert_frag(b,s,f) \
+ as_fatal (_("sparc convert_frag\n"))
+#define md_estimate_size_before_relax(f,s) \
+ (as_fatal (_("estimate_size_before_relax called")), 1)
+
+#define LISTING_HEADER "SPARC GAS "
+
+extern int sparc_pic_code;
+
+/* We require .word, et. al., to be aligned correctly. */
+#define md_cons_align(nbytes) sparc_cons_align (nbytes)
+extern void sparc_cons_align PARAMS ((int));
+
+#define HANDLE_ALIGN(fragp) sparc_handle_align (fragp)
+extern void sparc_handle_align PARAMS ((struct frag *));
+
+#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4 + 4)
+
+/* I know that "call 0" fails in sparc-coff if this doesn't return 1. I
+ don't know about other relocation types, or other formats, yet. */
+#ifdef OBJ_COFF
+#define TC_FORCE_RELOCATION_ABS(FIX) \
+ ((FIX)->fx_r_type == BFD_RELOC_32_PCREL_S2 \
+ || TC_FORCE_RELOCATION (FIX))
+
+#define RELOC_REQUIRES_SYMBOL
+#endif
+
+#ifdef OBJ_AOUT
+/* This expression evaluates to true if the relocation is for a local
+ object for which we still want to do the relocation at runtime.
+ False if we are willing to perform this relocation while building
+ the .o file. */
+
+#define TC_FORCE_RELOCATION_LOCAL(FIX) \
+ (!(FIX)->fx_pcrel \
+ || (FIX)->fx_plt \
+ || (sparc_pic_code \
+ && S_IS_EXTERNAL ((FIX)->fx_addsy)) \
+ || TC_FORCE_RELOCATION (FIX))
+#endif
+
+#ifdef OBJ_ELF
+/* Don't turn certain relocs into relocations against sections. This
+ is required for the dynamic linker to operate properly. When
+ generating PIC, we need to keep any non PC relative reloc. The PIC
+ part of this test must be parallel to the code in tc_gen_reloc which
+ converts relocations to GOT relocations. */
+#define tc_fix_adjustable(FIX) \
+ ((FIX)->fx_r_type != BFD_RELOC_VTABLE_INHERIT \
+ && (FIX)->fx_r_type != BFD_RELOC_VTABLE_ENTRY \
+ && ((FIX)->fx_r_type < BFD_RELOC_SPARC_TLS_GD_HI22 \
+ || (FIX)->fx_r_type > BFD_RELOC_SPARC_TLS_TPOFF64) \
+ && (! sparc_pic_code \
+ || ((FIX)->fx_r_type != BFD_RELOC_HI22 \
+ && (FIX)->fx_r_type != BFD_RELOC_LO10 \
+ && (FIX)->fx_r_type != BFD_RELOC_SPARC13 \
+ && ((FIX)->fx_r_type != BFD_RELOC_32_PCREL_S2 \
+ || !generic_force_reloc (FIX)) \
+ && ((FIX)->fx_pcrel \
+ || ((FIX)->fx_subsy != NULL \
+ && (S_GET_SEGMENT ((FIX)->fx_subsy) \
+ == S_GET_SEGMENT ((FIX)->fx_addsy))) \
+ || S_IS_LOCAL ((FIX)->fx_addsy)))))
+
+/* Values passed to md_apply_fix3 don't include the symbol value. */
+#define MD_APPLY_SYM_VALUE(FIX) 0
+
+/* Finish up the entire symtab. */
+#define tc_adjust_symtab() sparc_adjust_symtab ()
+extern void sparc_adjust_symtab PARAMS ((void));
+#endif
+
+#ifdef OBJ_AOUT
+/* When generating PIC code, we must not adjust any reloc which will
+ turn into a reloc against the global offset table, nor any reloc
+ which we will need if a symbol is overridden. */
+#define tc_fix_adjustable(FIX) \
+ (! sparc_pic_code \
+ || ((FIX)->fx_pcrel \
+ && ((FIX)->fx_addsy == NULL \
+ || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \
+ && ! S_IS_WEAK ((FIX)->fx_addsy)))) \
+ || (FIX)->fx_r_type == BFD_RELOC_16 \
+ || (FIX)->fx_r_type == BFD_RELOC_32)
+#endif
+
+#define elf_tc_final_processing sparc_elf_final_processing
+extern void sparc_elf_final_processing PARAMS ((void));
+
+#define md_operand(x)
+
+extern void sparc_md_end PARAMS ((void));
+#define md_end() sparc_md_end ()
+
+#endif
+
+#ifdef OBJ_ELF
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) sparc_cons (EXP, NBYTES)
+extern void sparc_cons PARAMS ((expressionS *, int));
+#endif
+
+#define TC_CONS_FIX_NEW cons_fix_new_sparc
+extern void cons_fix_new_sparc
+ PARAMS ((struct frag *, int, unsigned int, struct expressionS *));
+
+#define TC_FIX_TYPE valueT
+
+#define TC_INIT_FIX_DATA(X) \
+ do \
+ { \
+ (X)->tc_fix_data = 0; \
+ } \
+ while (0)
+
+#define TC_FIX_DATA_PRINT(FILE, FIX) \
+ do \
+ { \
+ fprintf ((FILE), "addend2=%ld\n", \
+ (unsigned long) (FIX)->tc_fix_data); \
+ } \
+ while (0)
+
+#define TARGET_USE_CFIPOP 1
+
+#define tc_cfi_frame_initial_instructions sparc_cfi_frame_initial_instructions
+extern void sparc_cfi_frame_initial_instructions PARAMS ((void));
+
+#define tc_regname_to_dw2regnum sparc_regname_to_dw2regnum
+extern int sparc_regname_to_dw2regnum PARAMS ((const char *regname));
+
+#define tc_cfi_emit_pcrel_expr sparc_cfi_emit_pcrel_expr
+extern void sparc_cfi_emit_pcrel_expr PARAMS ((expressionS *, unsigned int));
+
+extern int sparc_cie_data_alignment;
+
+#define DWARF2_LINE_MIN_INSN_LENGTH 4
+#define DWARF2_DEFAULT_RETURN_COLUMN 15
+#define DWARF2_CIE_DATA_ALIGNMENT sparc_cie_data_alignment
+
+/* end of tc-sparc.h */
diff --git a/x/binutils/gas/config/tc-tic30.c b/x/binutils/gas/config/tc-tic30.c
new file mode 100644
index 0000000..1258b13
--- /dev/null
+++ b/x/binutils/gas/config/tc-tic30.c
@@ -0,0 +1,1881 @@
+/* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Texas Instruments TMS320C30 machine specific gas.
+ Written by Steven Haworth (steve@pm.cse.rmit.edu.au).
+ Bugs & suggestions are completely welcome. This is free software.
+ Please help us make it better. */
+
+#include "as.h"
+#include "safe-ctype.h"
+#include "opcode/tic30.h"
+
+/* Put here all non-digit non-letter charcters that may occur in an
+ operand. */
+static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
+static char *ordinal_names[] = {
+ "first", "second", "third", "fourth", "fifth"
+};
+
+const int md_reloc_size = 0;
+
+const char comment_chars[] = ";";
+const char line_comment_chars[] = "*";
+const char line_separator_chars[] = "";
+
+const char *md_shortopts = "";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+
+size_t md_longopts_size = sizeof (md_longopts);
+
+/* Chars that mean this number is a floating point constant. */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "fFdDxX";
+
+/* Chars that can be used to separate mant from exp in floating point
+ nums. */
+const char EXP_CHARS[] = "eE";
+
+/* tables for lexical analysis */
+static char opcode_chars[256];
+static char register_chars[256];
+static char operand_chars[256];
+static char space_chars[256];
+static char identifier_chars[256];
+static char digit_chars[256];
+
+/* lexical macros */
+#define is_opcode_char(x) (opcode_chars[(unsigned char) x])
+#define is_operand_char(x) (operand_chars[(unsigned char) x])
+#define is_register_char(x) (register_chars[(unsigned char) x])
+#define is_space_char(x) (space_chars[(unsigned char) x])
+#define is_identifier_char(x) (identifier_chars[(unsigned char) x])
+#define is_digit_char(x) (digit_chars[(unsigned char) x])
+
+const pseudo_typeS md_pseudo_table[] = {
+ {0, 0, 0}
+};
+
+#undef USE_STDOUT
+#define USE_STDOUT 1
+
+#ifdef USE_STDARG
+
+#include <stdarg.h>
+
+int
+debug (const char *string, ...)
+{
+ if (flag_debug)
+ {
+ va_list argptr;
+ char str[100];
+
+ va_start (argptr, string);
+ vsprintf (str, string, argptr);
+ if (str[0] == '\0')
+ return (0);
+ va_end (argptr);
+ fputs (str, USE_STDOUT ? stdout : stderr);
+ return strlen (str);
+ }
+ else
+ return 0;
+}
+#else
+int
+debug (string, va_alist)
+ const char *string;
+ va_dcl
+{
+ if (flag_debug)
+ {
+ va_list argptr;
+ char str[100];
+ int cnt;
+
+ va_start (argptr, string);
+ cnt = vsprintf (str, string, argptr);
+ if (str[0] == NULL)
+ return (0);
+ va_end (argptr);
+ fputs (str, USE_STDOUT ? stdout : stderr);
+ return (cnt);
+ }
+ else
+ return 0;
+}
+#endif
+
+/* hash table for opcode lookup */
+static struct hash_control *op_hash;
+/* hash table for parallel opcode lookup */
+static struct hash_control *parop_hash;
+/* hash table for register lookup */
+static struct hash_control *reg_hash;
+/* hash table for indirect addressing lookup */
+static struct hash_control *ind_hash;
+
+void
+md_begin ()
+{
+ const char *hash_err;
+ debug ("In md_begin()\n");
+ op_hash = hash_new ();
+ {
+ const template *current_optab = tic30_optab;
+ for (; current_optab < tic30_optab_end; current_optab++)
+ {
+ hash_err = hash_insert (op_hash, current_optab->name, (char *) current_optab);
+ if (hash_err)
+ as_fatal ("Internal Error: Can't Hash %s: %s", current_optab->name, hash_err);
+ }
+ }
+ parop_hash = hash_new ();
+ {
+ const partemplate *current_parop = tic30_paroptab;
+ for (; current_parop < tic30_paroptab_end; current_parop++)
+ {
+ hash_err = hash_insert (parop_hash, current_parop->name, (char *) current_parop);
+ if (hash_err)
+ as_fatal ("Internal Error: Can't Hash %s: %s", current_parop->name, hash_err);
+ }
+ }
+ reg_hash = hash_new ();
+ {
+ const reg *current_reg = tic30_regtab;
+ for (; current_reg < tic30_regtab_end; current_reg++)
+ {
+ hash_err = hash_insert (reg_hash, current_reg->name, (char *) current_reg);
+ if (hash_err)
+ as_fatal ("Internal Error: Can't Hash %s: %s", current_reg->name, hash_err);
+ }
+ }
+ ind_hash = hash_new ();
+ {
+ const ind_addr_type *current_ind = tic30_indaddr_tab;
+ for (; current_ind < tic30_indaddrtab_end; current_ind++)
+ {
+ hash_err = hash_insert (ind_hash, current_ind->syntax, (char *) current_ind);
+ if (hash_err)
+ as_fatal ("Internal Error: Can't Hash %s: %s", current_ind->syntax, hash_err);
+ }
+ }
+ /* fill in lexical tables: opcode_chars, operand_chars, space_chars */
+ {
+ register int c;
+ register char *p;
+
+ for (c = 0; c < 256; c++)
+ {
+ if (ISLOWER (c) || ISDIGIT (c))
+ {
+ opcode_chars[c] = c;
+ register_chars[c] = c;
+ }
+ else if (ISUPPER (c))
+ {
+ opcode_chars[c] = TOLOWER (c);
+ register_chars[c] = opcode_chars[c];
+ }
+ else if (c == ')' || c == '(')
+ {
+ register_chars[c] = c;
+ }
+ if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c))
+ operand_chars[c] = c;
+ if (ISDIGIT (c) || c == '-')
+ digit_chars[c] = c;
+ if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c))
+ identifier_chars[c] = c;
+ if (c == ' ' || c == '\t')
+ space_chars[c] = c;
+ if (c == '_')
+ opcode_chars[c] = c;
+ }
+ for (p = operand_special_chars; *p != '\0'; p++)
+ operand_chars[(unsigned char) *p] = *p;
+ }
+}
+
+/* Address Mode OR values */
+#define AM_Register 0x00000000
+#define AM_Direct 0x00200000
+#define AM_Indirect 0x00400000
+#define AM_Immediate 0x00600000
+#define AM_NotReq 0xFFFFFFFF
+
+/* PC Relative OR values */
+#define PC_Register 0x00000000
+#define PC_Relative 0x02000000
+
+typedef struct {
+ unsigned op_type;
+ struct {
+ int resolved;
+ unsigned address;
+ char *label;
+ expressionS direct_expr;
+ } direct;
+ struct {
+ unsigned mod;
+ int ARnum;
+ unsigned char disp;
+ } indirect;
+ struct {
+ unsigned opcode;
+ } reg;
+ struct {
+ int resolved;
+ int decimal_found;
+ float f_number;
+ int s_number;
+ unsigned int u_number;
+ char *label;
+ expressionS imm_expr;
+ } immediate;
+} operand;
+
+int tic30_parallel_insn PARAMS ((char *));
+operand *tic30_operand PARAMS ((char *));
+char *tic30_find_parallel_insn PARAMS ((char *, char *));
+
+template *opcode;
+
+struct tic30_insn {
+ template *tm; /* Template of current instruction */
+ unsigned opcode; /* Final opcode */
+ int operands; /* Number of given operands */
+ /* Type of operand given in instruction */
+ operand *operand_type[MAX_OPERANDS];
+ unsigned addressing_mode; /* Final addressing mode of instruction */
+};
+
+struct tic30_insn insn;
+static int found_parallel_insn;
+
+void
+md_assemble (line)
+ char *line;
+{
+ template *opcode;
+ char *current_posn;
+ char *token_start;
+ char save_char;
+ int count;
+
+ debug ("In md_assemble() with argument %s\n", line);
+ memset (&insn, '\0', sizeof (insn));
+ if (found_parallel_insn)
+ {
+ debug ("Line is second part of parallel instruction\n\n");
+ found_parallel_insn = 0;
+ return;
+ }
+ if ((current_posn = tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
+ current_posn = line;
+ else
+ found_parallel_insn = 1;
+ while (is_space_char (*current_posn))
+ current_posn++;
+ token_start = current_posn;
+ if (!is_opcode_char (*current_posn))
+ {
+ as_bad ("Invalid character %s in opcode", output_invalid (*current_posn));
+ return;
+ }
+ /* Check if instruction is a parallel instruction by seeing if the first
+ character is a q. */
+ if (*token_start == 'q')
+ {
+ if (tic30_parallel_insn (token_start))
+ {
+ if (found_parallel_insn)
+ free (token_start);
+ return;
+ }
+ }
+ while (is_opcode_char (*current_posn))
+ current_posn++;
+ { /* Find instruction */
+ save_char = *current_posn;
+ *current_posn = '\0';
+ opcode = (template *) hash_find (op_hash, token_start);
+ if (opcode)
+ {
+ debug ("Found instruction %s\n", opcode->name);
+ insn.tm = opcode;
+ }
+ else
+ {
+ debug ("Didn't find insn\n");
+ as_bad ("Unknown TMS320C30 instruction: %s", token_start);
+ return;
+ }
+ *current_posn = save_char;
+ }
+ if (*current_posn != END_OF_INSN)
+ { /* Find operands */
+ int paren_not_balanced;
+ int expecting_operand = 0;
+ int this_operand;
+ do
+ {
+ /* skip optional white space before operand */
+ while (!is_operand_char (*current_posn) && *current_posn != END_OF_INSN)
+ {
+ if (!is_space_char (*current_posn))
+ {
+ as_bad ("Invalid character %s before %s operand",
+ output_invalid (*current_posn),
+ ordinal_names[insn.operands]);
+ return;
+ }
+ current_posn++;
+ }
+ token_start = current_posn; /* after white space */
+ paren_not_balanced = 0;
+ while (paren_not_balanced || *current_posn != ',')
+ {
+ if (*current_posn == END_OF_INSN)
+ {
+ if (paren_not_balanced)
+ {
+ as_bad ("Unbalanced parenthesis in %s operand.",
+ ordinal_names[insn.operands]);
+ return;
+ }
+ else
+ break; /* we are done */
+ }
+ else if (!is_operand_char (*current_posn) && !is_space_char (*current_posn))
+ {
+ as_bad ("Invalid character %s in %s operand",
+ output_invalid (*current_posn),
+ ordinal_names[insn.operands]);
+ return;
+ }
+ if (*current_posn == '(')
+ ++paren_not_balanced;
+ if (*current_posn == ')')
+ --paren_not_balanced;
+ current_posn++;
+ }
+ if (current_posn != token_start)
+ { /* yes, we've read in another operand */
+ this_operand = insn.operands++;
+ if (insn.operands > MAX_OPERANDS)
+ {
+ as_bad ("Spurious operands; (%d operands/instruction max)",
+ MAX_OPERANDS);
+ return;
+ }
+ /* now parse operand adding info to 'insn' as we go along */
+ save_char = *current_posn;
+ *current_posn = '\0';
+ insn.operand_type[this_operand] = tic30_operand (token_start);
+ *current_posn = save_char;
+ if (insn.operand_type[this_operand] == NULL)
+ return;
+ }
+ else
+ {
+ if (expecting_operand)
+ {
+ as_bad ("Expecting operand after ','; got nothing");
+ return;
+ }
+ if (*current_posn == ',')
+ {
+ as_bad ("Expecting operand before ','; got nothing");
+ return;
+ }
+ }
+ /* now *current_posn must be either ',' or END_OF_INSN */
+ if (*current_posn == ',')
+ {
+ if (*++current_posn == END_OF_INSN)
+ { /* just skip it, if it's \n complain */
+ as_bad ("Expecting operand after ','; got nothing");
+ return;
+ }
+ expecting_operand = 1;
+ }
+ }
+ while (*current_posn != END_OF_INSN); /* until we get end of insn */
+ }
+ debug ("Number of operands found: %d\n", insn.operands);
+ /* Check that number of operands is correct */
+ if (insn.operands != insn.tm->operands)
+ {
+ int i;
+ int numops = insn.tm->operands;
+ /* If operands are not the same, then see if any of the operands are not
+ required. Then recheck with number of given operands. If they are still not
+ the same, then give an error, otherwise carry on. */
+ for (i = 0; i < insn.tm->operands; i++)
+ if (insn.tm->operand_types[i] & NotReq)
+ numops--;
+ if (insn.operands != numops)
+ {
+ as_bad ("Incorrect number of operands given");
+ return;
+ }
+ }
+ insn.addressing_mode = AM_NotReq;
+ for (count = 0; count < insn.operands; count++)
+ {
+ if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
+ {
+ debug ("Operand %d matches\n", count + 1);
+ /* If instruction has two operands and has an AddressMode modifier then set
+ addressing mode type for instruction */
+ if (insn.tm->opcode_modifier == AddressMode)
+ {
+ int addr_insn = 0;
+ /* Store instruction uses the second operand for the address mode. */
+ if ((insn.tm->operand_types[1] & (Indirect | Direct)) == (Indirect | Direct))
+ addr_insn = 1;
+ if (insn.operand_type[addr_insn]->op_type & (AllReg))
+ insn.addressing_mode = AM_Register;
+ else if (insn.operand_type[addr_insn]->op_type & Direct)
+ insn.addressing_mode = AM_Direct;
+ else if (insn.operand_type[addr_insn]->op_type & Indirect)
+ insn.addressing_mode = AM_Indirect;
+ else
+ insn.addressing_mode = AM_Immediate;
+ }
+ }
+ else
+ {
+ as_bad ("The %s operand doesn't match", ordinal_names[count]);
+ return;
+ }
+ }
+ /* Now set the addressing mode for 3 operand instructions. */
+ if ((insn.tm->operand_types[0] & op3T1) && (insn.tm->operand_types[1] & op3T2))
+ {
+ /* Set the addressing mode to the values used for 2 operand instructions in the
+ G addressing field of the opcode. */
+ char *p;
+ switch (insn.operand_type[0]->op_type)
+ {
+ case Rn:
+ case ARn:
+ case DPReg:
+ case OtherReg:
+ if (insn.operand_type[1]->op_type & (AllReg))
+ insn.addressing_mode = AM_Register;
+ else if (insn.operand_type[1]->op_type & Indirect)
+ insn.addressing_mode = AM_Direct;
+ else
+ {
+ /* Shouldn't make it to this stage */
+ as_bad ("Incompatible first and second operands in instruction");
+ return;
+ }
+ break;
+ case Indirect:
+ if (insn.operand_type[1]->op_type & (AllReg))
+ insn.addressing_mode = AM_Indirect;
+ else if (insn.operand_type[1]->op_type & Indirect)
+ insn.addressing_mode = AM_Immediate;
+ else
+ {
+ /* Shouldn't make it to this stage */
+ as_bad ("Incompatible first and second operands in instruction");
+ return;
+ }
+ break;
+ }
+ /* Now make up the opcode for the 3 operand instructions. As in parallel
+ instructions, there will be no unresolved values, so they can be fully formed
+ and added to the frag table. */
+ insn.opcode = insn.tm->base_opcode;
+ if (insn.operand_type[0]->op_type & Indirect)
+ {
+ insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
+ insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
+ }
+ else
+ insn.opcode |= (insn.operand_type[0]->reg.opcode);
+ if (insn.operand_type[1]->op_type & Indirect)
+ {
+ insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
+ insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
+ }
+ else
+ insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
+ if (insn.operands == 3)
+ insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
+ insn.opcode |= insn.addressing_mode;
+ p = frag_more (INSN_SIZE);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ { /* Not a three operand instruction */
+ char *p;
+ int am_insn = -1;
+ insn.opcode = insn.tm->base_opcode;
+ /* Create frag for instruction - all instructions are 4 bytes long. */
+ p = frag_more (INSN_SIZE);
+ if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
+ {
+ insn.opcode |= insn.addressing_mode;
+ if (insn.addressing_mode == AM_Indirect)
+ {
+ /* Determine which operand gives the addressing mode */
+ if (insn.operand_type[0]->op_type & Indirect)
+ am_insn = 0;
+ if ((insn.operands > 1) && (insn.operand_type[1]->op_type & Indirect))
+ am_insn = 1;
+ insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
+ insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
+ insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
+ if (insn.operands > 1)
+ insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if (insn.addressing_mode == AM_Register)
+ {
+ insn.opcode |= (insn.operand_type[0]->reg.opcode);
+ if (insn.operands > 1)
+ insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if (insn.addressing_mode == AM_Direct)
+ {
+ if (insn.operand_type[0]->op_type & Direct)
+ am_insn = 0;
+ if ((insn.operands > 1) && (insn.operand_type[1]->op_type & Direct))
+ am_insn = 1;
+ if (insn.operands > 1)
+ insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
+ if (insn.operand_type[am_insn]->direct.resolved == 1)
+ {
+ /* Resolved values can be placed straight into instruction word, and output */
+ insn.opcode |= (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ { /* Unresolved direct addressing mode instruction */
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[am_insn]->direct.direct_expr, 0, 0);
+ }
+ }
+ else if (insn.addressing_mode == AM_Immediate)
+ {
+ if (insn.operand_type[0]->immediate.resolved == 1)
+ {
+ char *keeploc;
+ int size;
+ if (insn.operands > 1)
+ insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
+ switch (insn.tm->imm_arg_type)
+ {
+ case Imm_Float:
+ debug ("Floating point first operand\n");
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ keeploc = input_line_pointer;
+ input_line_pointer = insn.operand_type[0]->immediate.label;
+ if (md_atof ('f', p + 2, &size) != 0)
+ {
+ as_bad ("invalid short form floating point immediate operand");
+ return;
+ }
+ input_line_pointer = keeploc;
+ break;
+ case Imm_UInt:
+ debug ("Unsigned int first operand\n");
+ if (insn.operand_type[0]->immediate.decimal_found)
+ as_warn ("rounding down first operand float to unsigned int");
+ if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
+ as_warn ("only lower 16-bits of first operand are used");
+ insn.opcode |= (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ break;
+ case Imm_SInt:
+ debug ("Int first operand\n");
+ if (insn.operand_type[0]->immediate.decimal_found)
+ as_warn ("rounding down first operand float to signed int");
+ if (insn.operand_type[0]->immediate.s_number < -32768 ||
+ insn.operand_type[0]->immediate.s_number > 32767)
+ {
+ as_bad ("first operand is too large for 16-bit signed int");
+ return;
+ }
+ insn.opcode |= (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ break;
+ }
+ }
+ else
+ { /* Unresolved immediate label */
+ if (insn.operands > 1)
+ insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
+ }
+ }
+ }
+ else if (insn.tm->opcode_modifier == PCRel)
+ {
+ /* Conditional Branch and Call instructions */
+ if ((insn.tm->operand_types[0] & (AllReg | Disp)) == (AllReg | Disp))
+ {
+ if (insn.operand_type[0]->op_type & (AllReg))
+ {
+ insn.opcode |= (insn.operand_type[0]->reg.opcode);
+ insn.opcode |= PC_Register;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ insn.opcode |= PC_Relative;
+ if (insn.operand_type[0]->immediate.resolved == 1)
+ {
+ insn.opcode |= (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[0]->immediate.imm_expr, 1, 0);
+ }
+ }
+ }
+ else if ((insn.tm->operand_types[0] & ARn) == ARn)
+ {
+ /* Decrement and Branch instructions */
+ insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
+ if (insn.operand_type[1]->op_type & (AllReg))
+ {
+ insn.opcode |= (insn.operand_type[1]->reg.opcode);
+ insn.opcode |= PC_Register;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if (insn.operand_type[1]->immediate.resolved == 1)
+ {
+ if (insn.operand_type[0]->immediate.decimal_found)
+ {
+ as_bad ("first operand is floating point");
+ return;
+ }
+ if (insn.operand_type[0]->immediate.s_number < -32768 ||
+ insn.operand_type[0]->immediate.s_number > 32767)
+ {
+ as_bad ("first operand is too large for 16-bit signed int");
+ return;
+ }
+ insn.opcode |= (insn.operand_type[1]->immediate.s_number);
+ insn.opcode |= PC_Relative;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ insn.opcode |= PC_Relative;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2, &insn.operand_type[1]->immediate.imm_expr, 1, 0);
+ }
+ }
+ }
+ else if (insn.tm->operand_types[0] == IVector)
+ {
+ /* Trap instructions */
+ if (insn.operand_type[0]->op_type & IVector)
+ insn.opcode |= (insn.operand_type[0]->immediate.u_number);
+ else
+ { /* Shouldn't get here */
+ as_bad ("interrupt vector for trap instruction out of range");
+ return;
+ }
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if (insn.tm->opcode_modifier == StackOp || insn.tm->opcode_modifier == Rotate)
+ {
+ /* Push, Pop and Rotate instructions */
+ insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if ((insn.tm->operand_types[0] & (Abs24 | Direct)) == (Abs24 | Direct))
+ {
+ /* LDP Instruction needs to be tested for before the next section */
+ if (insn.operand_type[0]->op_type & Direct)
+ {
+ if (insn.operand_type[0]->direct.resolved == 1)
+ {
+ /* Direct addressing uses lower 8 bits of direct address */
+ insn.opcode |= (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ fixS *fix;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
+ /* Ensure that the assembler doesn't complain about fitting a 24-bit
+ address into 8 bits. */
+ fix->fx_no_overflow = 1;
+ }
+ }
+ else
+ {
+ if (insn.operand_type[0]->immediate.resolved == 1)
+ {
+ /* Immediate addressing uses upper 8 bits of address */
+ if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
+ {
+ as_bad ("LDP instruction needs a 24-bit operand");
+ return;
+ }
+ insn.opcode |= ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ fixS *fix;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
+ fix->fx_no_overflow = 1;
+ }
+ }
+ }
+ else if (insn.tm->operand_types[0] & (Imm24))
+ {
+ /* Unconditional Branch and Call instructions */
+ if (insn.operand_type[0]->immediate.resolved == 1)
+ {
+ if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
+ as_warn ("first operand is too large for a 24-bit displacement");
+ insn.opcode |= (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
+ }
+ }
+ else if (insn.tm->operand_types[0] & NotReq)
+ {
+ /* Check for NOP instruction without arguments. */
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if (insn.tm->operands == 0)
+ {
+ /* Check for instructions without operands. */
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ }
+ debug ("Addressing mode: %08X\n", insn.addressing_mode);
+ {
+ int i;
+ for (i = 0; i < insn.operands; i++)
+ {
+ if (insn.operand_type[i]->immediate.label)
+ free (insn.operand_type[i]->immediate.label);
+ free (insn.operand_type[i]);
+ }
+ }
+ debug ("Final opcode: %08X\n", insn.opcode);
+ debug ("\n");
+}
+
+struct tic30_par_insn {
+ partemplate *tm; /* Template of current parallel instruction */
+ int operands[2]; /* Number of given operands for each insn */
+ /* Type of operand given in instruction */
+ operand *operand_type[2][MAX_OPERANDS];
+ int swap_operands; /* Whether to swap operands around. */
+ unsigned p_field; /* Value of p field in multiply add/sub instructions */
+ unsigned opcode; /* Final opcode */
+};
+
+struct tic30_par_insn p_insn;
+
+int
+tic30_parallel_insn (char *token)
+{
+ static partemplate *p_opcode;
+ char *current_posn = token;
+ char *token_start;
+ char save_char;
+
+ debug ("In tic30_parallel_insn with %s\n", token);
+ memset (&p_insn, '\0', sizeof (p_insn));
+ while (is_opcode_char (*current_posn))
+ current_posn++;
+ { /* Find instruction */
+ save_char = *current_posn;
+ *current_posn = '\0';
+ p_opcode = (partemplate *) hash_find (parop_hash, token);
+ if (p_opcode)
+ {
+ debug ("Found instruction %s\n", p_opcode->name);
+ p_insn.tm = p_opcode;
+ }
+ else
+ {
+ char first_opcode[6] =
+ {0};
+ char second_opcode[6] =
+ {0};
+ int i;
+ int current_opcode = -1;
+ int char_ptr = 0;
+
+ for (i = 0; i < strlen (token); i++)
+ {
+ char ch = *(token + i);
+ if (ch == '_' && current_opcode == -1)
+ {
+ current_opcode = 0;
+ continue;
+ }
+ if (ch == '_' && current_opcode == 0)
+ {
+ current_opcode = 1;
+ char_ptr = 0;
+ continue;
+ }
+ switch (current_opcode)
+ {
+ case 0:
+ first_opcode[char_ptr++] = ch;
+ break;
+ case 1:
+ second_opcode[char_ptr++] = ch;
+ break;
+ }
+ }
+ debug ("first_opcode = %s\n", first_opcode);
+ debug ("second_opcode = %s\n", second_opcode);
+ sprintf (token, "q_%s_%s", second_opcode, first_opcode);
+ p_opcode = (partemplate *) hash_find (parop_hash, token);
+ if (p_opcode)
+ {
+ debug ("Found instruction %s\n", p_opcode->name);
+ p_insn.tm = p_opcode;
+ p_insn.swap_operands = 1;
+ }
+ else
+ return 0;
+ }
+ *current_posn = save_char;
+ }
+ { /* Find operands */
+ int paren_not_balanced;
+ int expecting_operand = 0;
+ int found_separator = 0;
+ do
+ {
+ /* skip optional white space before operand */
+ while (!is_operand_char (*current_posn) && *current_posn != END_OF_INSN)
+ {
+ if (!is_space_char (*current_posn) && *current_posn != PARALLEL_SEPARATOR)
+ {
+ as_bad ("Invalid character %s before %s operand",
+ output_invalid (*current_posn),
+ ordinal_names[insn.operands]);
+ return 1;
+ }
+ if (*current_posn == PARALLEL_SEPARATOR)
+ found_separator = 1;
+ current_posn++;
+ }
+ token_start = current_posn; /* after white space */
+ paren_not_balanced = 0;
+ while (paren_not_balanced || *current_posn != ',')
+ {
+ if (*current_posn == END_OF_INSN)
+ {
+ if (paren_not_balanced)
+ {
+ as_bad ("Unbalanced parenthesis in %s operand.",
+ ordinal_names[insn.operands]);
+ return 1;
+ }
+ else
+ break; /* we are done */
+ }
+ else if (*current_posn == PARALLEL_SEPARATOR)
+ {
+ while (is_space_char (*(current_posn - 1)))
+ current_posn--;
+ break;
+ }
+ else if (!is_operand_char (*current_posn) && !is_space_char (*current_posn))
+ {
+ as_bad ("Invalid character %s in %s operand",
+ output_invalid (*current_posn),
+ ordinal_names[insn.operands]);
+ return 1;
+ }
+ if (*current_posn == '(')
+ ++paren_not_balanced;
+ if (*current_posn == ')')
+ --paren_not_balanced;
+ current_posn++;
+ }
+ if (current_posn != token_start)
+ { /* yes, we've read in another operand */
+ p_insn.operands[found_separator]++;
+ if (p_insn.operands[found_separator] > MAX_OPERANDS)
+ {
+ as_bad ("Spurious operands; (%d operands/instruction max)",
+ MAX_OPERANDS);
+ return 1;
+ }
+ /* now parse operand adding info to 'insn' as we go along */
+ save_char = *current_posn;
+ *current_posn = '\0';
+ p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
+ tic30_operand (token_start);
+ *current_posn = save_char;
+ if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
+ return 1;
+ }
+ else
+ {
+ if (expecting_operand)
+ {
+ as_bad ("Expecting operand after ','; got nothing");
+ return 1;
+ }
+ if (*current_posn == ',')
+ {
+ as_bad ("Expecting operand before ','; got nothing");
+ return 1;
+ }
+ }
+ /* now *current_posn must be either ',' or END_OF_INSN */
+ if (*current_posn == ',')
+ {
+ if (*++current_posn == END_OF_INSN)
+ { /* just skip it, if it's \n complain */
+ as_bad ("Expecting operand after ','; got nothing");
+ return 1;
+ }
+ expecting_operand = 1;
+ }
+ }
+ while (*current_posn != END_OF_INSN); /* until we get end of insn */
+ }
+ if (p_insn.swap_operands)
+ {
+ int temp_num, i;
+ operand *temp_op;
+
+ temp_num = p_insn.operands[0];
+ p_insn.operands[0] = p_insn.operands[1];
+ p_insn.operands[1] = temp_num;
+ for (i = 0; i < MAX_OPERANDS; i++)
+ {
+ temp_op = p_insn.operand_type[0][i];
+ p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
+ p_insn.operand_type[1][i] = temp_op;
+ }
+ }
+ if (p_insn.operands[0] != p_insn.tm->operands_1)
+ {
+ as_bad ("incorrect number of operands given in the first instruction");
+ return 1;
+ }
+ if (p_insn.operands[1] != p_insn.tm->operands_2)
+ {
+ as_bad ("incorrect number of operands given in the second instruction");
+ return 1;
+ }
+ debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
+ debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
+ { /* Now check if operands are correct */
+ int count;
+ int num_rn = 0;
+ int num_ind = 0;
+ for (count = 0; count < 2; count++)
+ {
+ int i;
+ for (i = 0; i < p_insn.operands[count]; i++)
+ {
+ if ((p_insn.operand_type[count][i]->op_type &
+ p_insn.tm->operand_types[count][i]) == 0)
+ {
+ as_bad ("%s instruction, operand %d doesn't match", ordinal_names[count], i + 1);
+ return 1;
+ }
+ /* Get number of R register and indirect reference contained within the first
+ two operands of each instruction. This is required for the multiply
+ parallel instructions which require two R registers and two indirect
+ references, but not in any particular place. */
+ if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
+ num_rn++;
+ else if ((p_insn.operand_type[count][i]->op_type & Indirect) && i < 2)
+ num_ind++;
+ }
+ }
+ if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn)) == (Indirect | Rn))
+ {
+ /* Check for the multiply instructions */
+ if (num_rn != 2)
+ {
+ as_bad ("incorrect format for multiply parallel instruction");
+ return 1;
+ }
+ if (num_ind != 2)
+ { /* Shouldn't get here */
+ as_bad ("incorrect format for multiply parallel instruction");
+ return 1;
+ }
+ if ((p_insn.operand_type[0][2]->reg.opcode != 0x00) &&
+ (p_insn.operand_type[0][2]->reg.opcode != 0x01))
+ {
+ as_bad ("destination for multiply can only be R0 or R1");
+ return 1;
+ }
+ if ((p_insn.operand_type[1][2]->reg.opcode != 0x02) &&
+ (p_insn.operand_type[1][2]->reg.opcode != 0x03))
+ {
+ as_bad ("destination for add/subtract can only be R2 or R3");
+ return 1;
+ }
+ /* Now determine the P field for the instruction */
+ if (p_insn.operand_type[0][0]->op_type & Indirect)
+ {
+ if (p_insn.operand_type[0][1]->op_type & Indirect)
+ p_insn.p_field = 0x00000000; /* Ind * Ind, Rn +/- Rn */
+ else if (p_insn.operand_type[1][0]->op_type & Indirect)
+ p_insn.p_field = 0x01000000; /* Ind * Rn, Ind +/- Rn */
+ else
+ p_insn.p_field = 0x03000000; /* Ind * Rn, Rn +/- Ind */
+ }
+ else
+ {
+ if (p_insn.operand_type[0][1]->op_type & Rn)
+ p_insn.p_field = 0x02000000; /* Rn * Rn, Ind +/- Ind */
+ else if (p_insn.operand_type[1][0]->op_type & Indirect)
+ {
+ operand *temp;
+ p_insn.p_field = 0x01000000; /* Rn * Ind, Ind +/- Rn */
+ /* Need to swap the two multiply operands around so that everything is in
+ its place for the opcode makeup ie so Ind * Rn, Ind +/- Rn */
+ temp = p_insn.operand_type[0][0];
+ p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
+ p_insn.operand_type[0][1] = temp;
+ }
+ else
+ {
+ operand *temp;
+ p_insn.p_field = 0x03000000; /* Rn * Ind, Rn +/- Ind */
+ temp = p_insn.operand_type[0][0];
+ p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
+ p_insn.operand_type[0][1] = temp;
+ }
+ }
+ }
+ }
+ debug ("P field: %08X\n", p_insn.p_field);
+ /* Finalise opcode. This is easier for parallel instructions as they have to be
+ fully resolved, there are no memory addresses allowed, except through indirect
+ addressing, so there are no labels to resolve. */
+ {
+ p_insn.opcode = p_insn.tm->base_opcode;
+ switch (p_insn.tm->oporder)
+ {
+ case OO_4op1:
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
+ break;
+ case OO_4op2:
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
+ if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
+ as_warn ("loading the same register in parallel operation");
+ break;
+ case OO_4op3:
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
+ break;
+ case OO_5op1:
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
+ p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
+ break;
+ case OO_5op2:
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
+ p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
+ break;
+ case OO_PField:
+ p_insn.opcode |= p_insn.p_field;
+ if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
+ p_insn.opcode |= 0x00800000;
+ if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
+ p_insn.opcode |= 0x00400000;
+ switch (p_insn.p_field)
+ {
+ case 0x00000000:
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
+ break;
+ case 0x01000000:
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
+ break;
+ case 0x02000000:
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
+ break;
+ case 0x03000000:
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
+ break;
+ }
+ break;
+ }
+ } /* Opcode is finalised at this point for all parallel instructions. */
+ { /* Output opcode */
+ char *p;
+ p = frag_more (INSN_SIZE);
+ md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
+ }
+ {
+ int i, j;
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < p_insn.operands[i]; j++)
+ free (p_insn.operand_type[i][j]);
+ }
+ debug ("Final opcode: %08X\n", p_insn.opcode);
+ debug ("\n");
+ return 1;
+}
+
+operand *
+tic30_operand (token)
+ char *token;
+{
+ int count;
+ char ind_buffer[strlen (token)];
+ operand *current_op;
+
+ debug ("In tic30_operand with %s\n", token);
+ current_op = (operand *) malloc (sizeof (operand));
+ memset (current_op, '\0', sizeof (operand));
+ if (*token == DIRECT_REFERENCE)
+ {
+ char *token_posn = token + 1;
+ int direct_label = 0;
+ debug ("Found direct reference\n");
+ while (*token_posn)
+ {
+ if (!is_digit_char (*token_posn))
+ direct_label = 1;
+ token_posn++;
+ }
+ if (direct_label)
+ {
+ char *save_input_line_pointer;
+ segT retval;
+ debug ("Direct reference is a label\n");
+ current_op->direct.label = token + 1;
+ save_input_line_pointer = input_line_pointer;
+ input_line_pointer = token + 1;
+ debug ("Current input_line_pointer: %s\n", input_line_pointer);
+ retval = expression (&current_op->direct.direct_expr);
+ debug ("Expression type: %d\n", current_op->direct.direct_expr.X_op);
+ debug ("Expression addnum: %d\n", current_op->direct.direct_expr.X_add_number);
+ debug ("Segment: %d\n", retval);
+ input_line_pointer = save_input_line_pointer;
+ if (current_op->direct.direct_expr.X_op == O_constant)
+ {
+ current_op->direct.address = current_op->direct.direct_expr.X_add_number;
+ current_op->direct.resolved = 1;
+ }
+ }
+ else
+ {
+ debug ("Direct reference is a number\n");
+ current_op->direct.address = atoi (token + 1);
+ current_op->direct.resolved = 1;
+ }
+ current_op->op_type = Direct;
+ }
+ else if (*token == INDIRECT_REFERENCE)
+ { /* Indirect reference operand */
+ int found_ar = 0;
+ int found_disp = 0;
+ int ar_number = -1;
+ int disp_number = 0;
+ int buffer_posn = 1;
+ ind_addr_type *ind_addr_op;
+ debug ("Found indirect reference\n");
+ ind_buffer[0] = *token;
+ for (count = 1; count < strlen (token); count++)
+ { /* Strip operand */
+ ind_buffer[buffer_posn] = TOLOWER (*(token + count));
+ if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A') &&
+ (*(token + count) == 'r' || *(token + count) == 'R'))
+ {
+ /* AR reference is found, so get its number and remove it from the buffer
+ so it can pass through hash_find() */
+ if (found_ar)
+ {
+ as_bad ("More than one AR register found in indirect reference");
+ return NULL;
+ }
+ if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
+ {
+ as_bad ("Illegal AR register in indirect reference");
+ return NULL;
+ }
+ ar_number = *(token + count + 1) - '0';
+ found_ar = 1;
+ count++;
+ }
+ if (*(token + count) == '(')
+ {
+ /* Parenthesis found, so check if a displacement value is inside. If so, get
+ the value and remove it from the buffer. */
+ if (is_digit_char (*(token + count + 1)))
+ {
+ char disp[10];
+ int disp_posn = 0;
+
+ if (found_disp)
+ {
+ as_bad ("More than one displacement found in indirect reference");
+ return NULL;
+ }
+ count++;
+ while (*(token + count) != ')')
+ {
+ if (!is_digit_char (*(token + count)))
+ {
+ as_bad ("Invalid displacement in indirect reference");
+ return NULL;
+ }
+ disp[disp_posn++] = *(token + (count++));
+ }
+ disp[disp_posn] = '\0';
+ disp_number = atoi (disp);
+ count--;
+ found_disp = 1;
+ }
+ }
+ buffer_posn++;
+ }
+ ind_buffer[buffer_posn] = '\0';
+ if (!found_ar)
+ {
+ as_bad ("AR register not found in indirect reference");
+ return NULL;
+ }
+ ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
+ if (ind_addr_op)
+ {
+ debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
+ if (ind_addr_op->displacement == IMPLIED_DISP)
+ {
+ found_disp = 1;
+ disp_number = 1;
+ }
+ else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
+ {
+ /* Maybe an implied displacement of 1 again */
+ as_bad ("required displacement wasn't given in indirect reference");
+ return 0;
+ }
+ }
+ else
+ {
+ as_bad ("illegal indirect reference");
+ return NULL;
+ }
+ if (found_disp && (disp_number < 0 || disp_number > 255))
+ {
+ as_bad ("displacement must be an unsigned 8-bit number");
+ return NULL;
+ }
+ current_op->indirect.mod = ind_addr_op->modfield;
+ current_op->indirect.disp = disp_number;
+ current_op->indirect.ARnum = ar_number;
+ current_op->op_type = Indirect;
+ }
+ else
+ {
+ reg *regop = (reg *) hash_find (reg_hash, token);
+ if (regop)
+ {
+ debug ("Found register operand: %s\n", regop->name);
+ if (regop->regtype == REG_ARn)
+ current_op->op_type = ARn;
+ else if (regop->regtype == REG_Rn)
+ current_op->op_type = Rn;
+ else if (regop->regtype == REG_DP)
+ current_op->op_type = DPReg;
+ else
+ current_op->op_type = OtherReg;
+ current_op->reg.opcode = regop->opcode;
+ }
+ else
+ {
+ if (!is_digit_char (*token) || *(token + 1) == 'x' || strchr (token, 'h'))
+ {
+ char *save_input_line_pointer;
+ segT retval;
+ debug ("Probably a label: %s\n", token);
+ current_op->immediate.label = (char *) malloc (strlen (token) + 1);
+ strcpy (current_op->immediate.label, token);
+ current_op->immediate.label[strlen (token)] = '\0';
+ save_input_line_pointer = input_line_pointer;
+ input_line_pointer = token;
+ debug ("Current input_line_pointer: %s\n", input_line_pointer);
+ retval = expression (&current_op->immediate.imm_expr);
+ debug ("Expression type: %d\n", current_op->immediate.imm_expr.X_op);
+ debug ("Expression addnum: %d\n", current_op->immediate.imm_expr.X_add_number);
+ debug ("Segment: %d\n", retval);
+ input_line_pointer = save_input_line_pointer;
+ if (current_op->immediate.imm_expr.X_op == O_constant)
+ {
+ current_op->immediate.s_number = current_op->immediate.imm_expr.X_add_number;
+ current_op->immediate.u_number = (unsigned int) current_op->immediate.imm_expr.X_add_number;
+ current_op->immediate.resolved = 1;
+ }
+ }
+ else
+ {
+ unsigned count;
+ debug ("Found a number or displacement\n");
+ for (count = 0; count < strlen (token); count++)
+ if (*(token + count) == '.')
+ current_op->immediate.decimal_found = 1;
+ current_op->immediate.label = (char *) malloc (strlen (token) + 1);
+ strcpy (current_op->immediate.label, token);
+ current_op->immediate.label[strlen (token)] = '\0';
+ current_op->immediate.f_number = (float) atof (token);
+ current_op->immediate.s_number = (int) atoi (token);
+ current_op->immediate.u_number = (unsigned int) atoi (token);
+ current_op->immediate.resolved = 1;
+ }
+ current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
+ if (current_op->immediate.u_number >= 0 && current_op->immediate.u_number <= 31)
+ current_op->op_type |= IVector;
+ }
+ }
+ return current_op;
+}
+
+/* next_line points to the next line after the current instruction (current_line).
+ Search for the parallel bars, and if found, merge two lines into internal syntax
+ for a parallel instruction:
+ q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
+ By this stage, all comments are scrubbed, and only the bare lines are given.
+ */
+
+#define NONE 0
+#define START_OPCODE 1
+#define END_OPCODE 2
+#define START_OPERANDS 3
+#define END_OPERANDS 4
+
+char *
+tic30_find_parallel_insn (current_line, next_line)
+ char *current_line;
+ char *next_line;
+{
+ int found_parallel = 0;
+ char first_opcode[256];
+ char second_opcode[256];
+ char first_operands[256];
+ char second_operands[256];
+ char *parallel_insn;
+
+ debug ("In tic30_find_parallel_insn()\n");
+ while (!is_end_of_line[(unsigned char) *next_line])
+ {
+ if (*next_line == PARALLEL_SEPARATOR && *(next_line + 1) == PARALLEL_SEPARATOR)
+ {
+ found_parallel = 1;
+ next_line++;
+ break;
+ }
+ next_line++;
+ }
+ if (!found_parallel)
+ return NULL;
+ debug ("Found a parallel instruction\n");
+ {
+ int i;
+ char *opcode, *operands, *line;
+
+ for (i = 0; i < 2; i++)
+ {
+ if (i == 0)
+ {
+ opcode = &first_opcode[0];
+ operands = &first_operands[0];
+ line = current_line;
+ }
+ else
+ {
+ opcode = &second_opcode[0];
+ operands = &second_operands[0];
+ line = next_line;
+ }
+ {
+ int search_status = NONE;
+ int char_ptr = 0;
+ char c;
+
+ while (!is_end_of_line[(unsigned char) (c = *line)])
+ {
+ if (is_opcode_char (c) && search_status == NONE)
+ {
+ opcode[char_ptr++] = TOLOWER (c);
+ search_status = START_OPCODE;
+ }
+ else if (is_opcode_char (c) && search_status == START_OPCODE)
+ {
+ opcode[char_ptr++] = TOLOWER (c);
+ }
+ else if (!is_opcode_char (c) && search_status == START_OPCODE)
+ {
+ opcode[char_ptr] = '\0';
+ char_ptr = 0;
+ search_status = END_OPCODE;
+ }
+ else if (is_operand_char (c) && search_status == START_OPERANDS)
+ {
+ operands[char_ptr++] = c;
+ }
+ if (is_operand_char (c) && search_status == END_OPCODE)
+ {
+ operands[char_ptr++] = c;
+ search_status = START_OPERANDS;
+ }
+ line++;
+ }
+ if (search_status != START_OPERANDS)
+ return NULL;
+ operands[char_ptr] = '\0';
+ }
+ }
+ }
+ parallel_insn = (char *) malloc (strlen (first_opcode) + strlen (first_operands) +
+ strlen (second_opcode) + strlen (second_operands) + 8);
+ sprintf (parallel_insn, "q_%s_%s %s | %s", first_opcode, second_opcode, first_operands, second_operands);
+ debug ("parallel insn = %s\n", parallel_insn);
+ return parallel_insn;
+}
+
+#undef NONE
+#undef START_OPCODE
+#undef END_OPCODE
+#undef START_OPERANDS
+#undef END_OPERANDS
+
+/* In order to get gas to ignore any | chars at the start of a line,
+ this function returns true if a | is found in a line. */
+
+int
+tic30_unrecognized_line (c)
+ int c;
+{
+ debug ("In tc_unrecognized_line\n");
+ return (c == PARALLEL_SEPARATOR);
+}
+
+int
+md_estimate_size_before_relax (fragP, segment)
+ fragS *fragP;
+ segT segment;
+{
+ debug ("In md_estimate_size_before_relax()\n");
+ return 0;
+}
+
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd *abfd;
+ segT sec;
+ register fragS *fragP;
+{
+ debug ("In md_convert_frag()\n");
+}
+
+void
+md_apply_fix3 (fixP, valP, seg)
+ fixS *fixP;
+ valueT *valP;
+ segT seg ATTRIBUTE_UNUSED;
+{
+ valueT value = *valP;
+
+ debug ("In md_apply_fix() with value = %ld\n", (long) value);
+ debug ("Values in fixP\n");
+ debug ("fx_size = %d\n", fixP->fx_size);
+ debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
+ debug ("fx_where = %d\n", fixP->fx_where);
+ debug ("fx_offset = %d\n", (int) fixP->fx_offset);
+ {
+ char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
+
+ value /= INSN_SIZE;
+ if (fixP->fx_size == 1)
+ /* Special fix for LDP instruction. */
+ value = (value & 0x00FF0000) >> 16;
+
+ debug ("new value = %ld\n", (long) value);
+ md_number_to_chars (buf, value, fixP->fx_size);
+ }
+
+ if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
+ fixP->fx_done = 1;
+}
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ int i;
+
+ debug ("In md_parse_option()\n");
+ for (i = 0; i < c; i++)
+ {
+ printf ("%c\n", arg[c]);
+ }
+ return 0;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ debug ("In md_show_usage()\n");
+}
+
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ debug ("In md_undefined_symbol()\n");
+ return (symbolS *) 0;
+}
+
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+ debug ("In md_section_align() segment = %d and size = %d\n", segment, size);
+ size = (size + 3) / 4;
+ size *= 4;
+ debug ("New size value = %d\n", size);
+ return size;
+}
+
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ int offset;
+
+ debug ("In md_pcrel_from()\n");
+ debug ("fx_where = %d\n", fixP->fx_where);
+ debug ("fx_size = %d\n", fixP->fx_size);
+ /* Find the opcode that represents the current instruction in the fr_literal
+ storage area, and check bit 21. Bit 21 contains whether the current instruction
+ is a delayed one or not, and then set the offset value appropriately. */
+ if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
+ offset = 3;
+ else
+ offset = 1;
+ debug ("offset = %d\n", offset);
+ /* PC Relative instructions have a format:
+ displacement = Label - (PC + offset)
+ This function returns PC + offset where:
+ fx_where - fx_size = PC
+ INSN_SIZE * offset = offset number of instructions
+ */
+ return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
+}
+
+char *
+md_atof (what_statement_type, literalP, sizeP)
+ int what_statement_type;
+ char *literalP;
+ int *sizeP;
+{
+ int prec;
+ char *token;
+ char keepval;
+ unsigned long value;
+ /* char *atof_ieee (); */
+ float float_value;
+ debug ("In md_atof()\n");
+ debug ("precision = %c\n", what_statement_type);
+ debug ("literal = %s\n", literalP);
+ debug ("line = ");
+ token = input_line_pointer;
+ while (!is_end_of_line[(unsigned char) *input_line_pointer]
+ && (*input_line_pointer != ','))
+ {
+ debug ("%c", *input_line_pointer);
+ input_line_pointer++;
+ }
+ keepval = *input_line_pointer;
+ *input_line_pointer = '\0';
+ debug ("\n");
+ float_value = (float) atof (token);
+ *input_line_pointer = keepval;
+ debug ("float_value = %f\n", float_value);
+ switch (what_statement_type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ default:
+ *sizeP = 0;
+ return "Bad call to MD_ATOF()";
+ }
+ if (float_value == 0.0)
+ {
+ value = (prec == 2) ? 0x00008000L : 0x80000000L;
+ }
+ else
+ {
+ unsigned long exp, sign, mant, tmsfloat;
+ tmsfloat = *((long *) &float_value);
+ sign = tmsfloat & 0x80000000;
+ mant = tmsfloat & 0x007FFFFF;
+ exp = tmsfloat & 0x7F800000;
+ exp <<= 1;
+ if (exp == 0xFF000000)
+ {
+ if (mant == 0)
+ value = 0x7F7FFFFF;
+ else if (sign == 0)
+ value = 0x7F7FFFFF;
+ else
+ value = 0x7F800000;
+ }
+ else
+ {
+ exp -= 0x7F000000;
+ if (sign)
+ {
+ mant = mant & 0x007FFFFF;
+ mant = -mant;
+ mant = mant & 0x00FFFFFF;
+ if (mant == 0)
+ {
+ mant |= 0x00800000;
+ exp = (long) exp - 0x01000000;
+ }
+ }
+ tmsfloat = exp | mant;
+ value = tmsfloat;
+ }
+ if (prec == 2)
+ {
+ long exp, mant;
+
+ if (tmsfloat == 0x80000000)
+ {
+ value = 0x8000;
+ }
+ else
+ {
+ value = 0;
+ exp = (tmsfloat & 0xFF000000);
+ exp >>= 24;
+ mant = tmsfloat & 0x007FFFFF;
+ if (tmsfloat & 0x00800000)
+ {
+ mant |= 0xFF000000;
+ mant += 0x00000800;
+ mant >>= 12;
+ mant |= 0x00000800;
+ mant &= 0x0FFF;
+ if (exp > 7)
+ value = 0x7800;
+ }
+ else
+ {
+ mant |= 0x00800000;
+ mant += 0x00000800;
+ exp += (mant >> 24);
+ mant >>= 12;
+ mant &= 0x07FF;
+ if (exp > 7)
+ value = 0x77FF;
+ }
+ if (exp < -8)
+ value = 0x8000;
+ if (value == 0)
+ {
+ mant = (exp << 12) | mant;
+ value = mant & 0xFFFF;
+ }
+ }
+ }
+ }
+ md_number_to_chars (literalP, value, prec);
+ *sizeP = prec;
+ return 0;
+}
+
+void
+md_number_to_chars (buf, val, n)
+ char *buf;
+ valueT val;
+ int n;
+{
+ debug ("In md_number_to_chars()\n");
+ number_to_chars_bigendian (buf, val, n);
+ /* number_to_chars_littleendian(buf,val,n); */
+}
+
+#define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
+#define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
+
+arelent *
+tc_gen_reloc (section, fixP)
+ asection *section;
+ fixS *fixP;
+{
+ arelent *rel;
+ bfd_reloc_code_real_type code = 0;
+
+ debug ("In tc_gen_reloc()\n");
+ debug ("fixP.size = %d\n", fixP->fx_size);
+ debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
+ debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
+ switch (F (fixP->fx_size, fixP->fx_pcrel))
+ {
+ MAP (1, 0, BFD_RELOC_TIC30_LDP);
+ MAP (2, 0, BFD_RELOC_16);
+ MAP (3, 0, BFD_RELOC_24);
+ MAP (2, 1, BFD_RELOC_16_PCREL);
+ MAP (4, 0, BFD_RELOC_32);
+ default:
+ as_bad ("Can not do %d byte %srelocation", fixP->fx_size,
+ fixP->fx_pcrel ? "pc-relative " : "");
+ }
+#undef MAP
+#undef F
+
+ rel = (arelent *) xmalloc (sizeof (arelent));
+ assert (rel != 0);
+ rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
+ rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
+ if (fixP->fx_pcrel)
+ rel->addend = fixP->fx_addnumber;
+ else
+ rel->addend = 0;
+ rel->howto = bfd_reloc_type_lookup (stdoutput, code);
+ if (!rel->howto)
+ {
+ const char *name;
+ name = S_GET_NAME (fixP->fx_addsy);
+ if (name == NULL)
+ name = "<unknown>";
+ as_fatal ("Cannot generate relocation type for symbol %s, code %s", name, bfd_get_reloc_code_name (code));
+ }
+ return rel;
+}
+
+void
+tc_aout_pre_write_hook ()
+{
+ debug ("In tc_aout_pre_write_hook()\n");
+}
+
+void
+md_operand (expressionP)
+ expressionS *expressionP;
+{
+ debug ("In md_operand()\n");
+}
+
+char output_invalid_buf[8];
+
+char *
+output_invalid (c)
+ char c;
+{
+ if (ISPRINT (c))
+ sprintf (output_invalid_buf, "'%c'", c);
+ else
+ sprintf (output_invalid_buf, "(0x%x)", (unsigned) c);
+ return output_invalid_buf;
+}
diff --git a/x/binutils/gas/config/tc-tic30.h b/x/binutils/gas/config/tc-tic30.h
new file mode 100644
index 0000000..d55c870
--- /dev/null
+++ b/x/binutils/gas/config/tc-tic30.h
@@ -0,0 +1,55 @@
+/* tc-tic30.h -- Header file for tc-tic30.c
+ Copyright 1998, 2000 Free Software Foundation, Inc.
+ Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef _TC_TIC30_H_
+#define _TC_TIC30_H_
+
+#define TC_TIC30 1
+
+#ifdef OBJ_AOUT
+#define TARGET_FORMAT "a.out-tic30"
+#endif
+
+#define TARGET_ARCH bfd_arch_tic30
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#define WORKING_DOT_WORD
+
+char *output_invalid PARAMS ((int c));
+
+#define END_OF_INSN '\0'
+#define MAX_OPERANDS 6
+#define DIRECT_REFERENCE '@'
+#define INDIRECT_REFERENCE '*'
+#define PARALLEL_SEPARATOR '|'
+#define INSN_SIZE 4
+
+/* Define this to 1 if you want the debug output to be on stdout,
+ otherwise stderr will be used. If stderr is used, there will be a
+ better synchronisation with the as_bad outputs, but you can't
+ capture the output. */
+#define USE_STDOUT 0
+
+#define tc_unrecognized_line tic30_unrecognized_line
+
+extern int tic30_unrecognized_line PARAMS ((int));
+
+#endif
diff --git a/x/binutils/gas/config/tc-v850.c b/x/binutils/gas/config/tc-v850.c
new file mode 100644
index 0000000..e1e5475
--- /dev/null
+++ b/x/binutils/gas/config/tc-v850.c
@@ -0,0 +1,2434 @@
+/* tc-v850.c -- Assembler code for the NEC V850
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "as.h"
+#include "safe-ctype.h"
+#include "subsegs.h"
+#include "opcode/v850.h"
+#include "dwarf2dbg.h"
+
+/* Sign-extend a 16-bit number. */
+#define SEXT16(x) ((((x) & 0xffff) ^ (~0x7fff)) + 0x8000)
+
+/* Temporarily holds the reloc in a cons expression. */
+static bfd_reloc_code_real_type hold_cons_reloc = BFD_RELOC_UNUSED;
+
+/* Set to TRUE if we want to be pedantic about signed overflows. */
+static boolean warn_signed_overflows = FALSE;
+static boolean warn_unsigned_overflows = FALSE;
+
+/* Indicates the target BFD machine number. */
+static int machine = -1;
+
+/* Indicates the target processor(s) for the assemble. */
+static int processor_mask = -1;
+
+/* Structure to hold information about predefined registers. */
+struct reg_name {
+ const char *name;
+ int value;
+};
+
+/* Generic assembler global variables which must be defined by all
+ targets. */
+
+/* Characters which always start a comment. */
+const char comment_chars[] = "#";
+
+/* Characters which start a comment at the beginning of a line. */
+const char line_comment_chars[] = ";#";
+
+/* Characters which may be used to separate multiple commands on a
+ single line. */
+const char line_separator_chars[] = ";";
+
+/* Characters which are used to indicate an exponent in a floating
+ point number. */
+const char EXP_CHARS[] = "eE";
+
+/* Characters which mean that a number is a floating point constant,
+ as in 0d1.0. */
+const char FLT_CHARS[] = "dD";
+
+const relax_typeS md_relax_table[] = {
+ /* Conditional branches. */
+ {0xff, -0x100, 2, 1},
+ {0x1fffff, -0x200000, 6, 0},
+ /* Unconditional branches. */
+ {0xff, -0x100, 2, 3},
+ {0x1fffff, -0x200000, 4, 0},
+};
+
+/* Fixups. */
+#define MAX_INSN_FIXUPS (5)
+struct v850_fixup {
+ expressionS exp;
+ int opindex;
+ bfd_reloc_code_real_type reloc;
+};
+
+struct v850_fixup fixups[MAX_INSN_FIXUPS];
+static int fc;
+
+struct v850_seg_entry
+{
+ segT s;
+ const char *name;
+ flagword flags;
+};
+
+struct v850_seg_entry v850_seg_table[] =
+{
+ { NULL, ".sdata",
+ SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS
+ | SEC_SMALL_DATA },
+ { NULL, ".tdata",
+ SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS },
+ { NULL, ".zdata",
+ SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS },
+ { NULL, ".sbss",
+ SEC_ALLOC | SEC_SMALL_DATA },
+ { NULL, ".tbss",
+ SEC_ALLOC },
+ { NULL, ".zbss",
+ SEC_ALLOC},
+ { NULL, ".rosdata",
+ SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | SEC_DATA
+ | SEC_HAS_CONTENTS | SEC_SMALL_DATA },
+ { NULL, ".rozdata",
+ SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | SEC_DATA
+ | SEC_HAS_CONTENTS },
+ { NULL, ".scommon",
+ SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS
+ | SEC_SMALL_DATA | SEC_IS_COMMON },
+ { NULL, ".tcommon",
+ SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS
+ | SEC_IS_COMMON },
+ { NULL, ".zcommon",
+ SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS
+ | SEC_IS_COMMON },
+ { NULL, ".call_table_data",
+ SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS },
+ { NULL, ".call_table_text",
+ SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | SEC_CODE
+ | SEC_HAS_CONTENTS},
+ { NULL, ".bss",
+ SEC_ALLOC }
+};
+
+#define SDATA_SECTION 0
+#define TDATA_SECTION 1
+#define ZDATA_SECTION 2
+#define SBSS_SECTION 3
+#define TBSS_SECTION 4
+#define ZBSS_SECTION 5
+#define ROSDATA_SECTION 6
+#define ROZDATA_SECTION 7
+#define SCOMMON_SECTION 8
+#define TCOMMON_SECTION 9
+#define ZCOMMON_SECTION 10
+#define CALL_TABLE_DATA_SECTION 11
+#define CALL_TABLE_TEXT_SECTION 12
+#define BSS_SECTION 13
+
+static void do_v850_seg PARAMS ((int, subsegT));
+
+static void
+do_v850_seg (i, sub)
+ int i;
+ subsegT sub;
+{
+ struct v850_seg_entry *seg = v850_seg_table + i;
+
+ obj_elf_section_change_hook ();
+ if (seg->s != NULL)
+ {
+ subseg_set (seg->s, sub);
+ }
+ else
+ {
+ seg->s = subseg_new (seg->name, sub);
+ bfd_set_section_flags (stdoutput, seg->s, seg->flags);
+ if ((seg->flags & SEC_LOAD) == 0)
+ seg_info (seg->s)->bss = 1;
+ }
+}
+
+static void v850_seg PARAMS ((int i));
+
+static void
+v850_seg (i)
+ int i;
+{
+ subsegT sub = get_absolute_expression ();
+
+ do_v850_seg (i, sub);
+ demand_empty_rest_of_line ();
+}
+
+static void v850_offset PARAMS ((int));
+
+static void
+v850_offset (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ int temp = get_absolute_expression ();
+
+ temp -= frag_now_fix ();
+
+ if (temp > 0)
+ (void) frag_more (temp);
+
+ demand_empty_rest_of_line ();
+}
+
+/* Copied from obj_elf_common() in gas/config/obj-elf.c. */
+
+static void v850_comm PARAMS ((int));
+
+static void
+v850_comm (area)
+ int area;
+{
+ char *name;
+ char c;
+ char *p;
+ int temp;
+ unsigned int size;
+ symbolS *symbolP;
+ int have_align;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ /* Just after name is now '\0'. */
+ p = input_line_pointer;
+ *p = c;
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after symbol-name"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ /* Skip ','. */
+ input_line_pointer++;
+
+ if ((temp = get_absolute_expression ()) < 0)
+ {
+ /* xgettext:c-format */
+ as_bad (_(".COMMon length (%d.) < 0! Ignored."), temp);
+ ignore_rest_of_line ();
+ return;
+ }
+
+ size = temp;
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+
+ if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
+ {
+ as_bad (_("Ignoring attempt to re-define symbol"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (S_GET_VALUE (symbolP) != 0)
+ {
+ if (S_GET_VALUE (symbolP) != size)
+ {
+ /* xgettext:c-format */
+ as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."),
+ S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
+ }
+ }
+
+ know (symbol_get_frag (symbolP) == &zero_address_frag);
+
+ if (*input_line_pointer != ',')
+ have_align = 0;
+ else
+ {
+ have_align = 1;
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ }
+
+ if (! have_align || *input_line_pointer != '"')
+ {
+ if (! have_align)
+ temp = 0;
+ else
+ {
+ temp = get_absolute_expression ();
+
+ if (temp < 0)
+ {
+ temp = 0;
+ as_warn (_("Common alignment negative; 0 assumed"));
+ }
+ }
+
+ if (symbol_get_obj (symbolP)->local)
+ {
+ segT old_sec;
+ int old_subsec;
+ char *pfrag;
+ int align;
+ flagword applicable;
+
+ old_sec = now_seg;
+ old_subsec = now_subseg;
+
+ applicable = bfd_applicable_section_flags (stdoutput);
+
+ applicable &= SEC_ALLOC;
+
+ switch (area)
+ {
+ case SCOMMON_SECTION:
+ do_v850_seg (SBSS_SECTION, 0);
+ break;
+
+ case ZCOMMON_SECTION:
+ do_v850_seg (ZBSS_SECTION, 0);
+ break;
+
+ case TCOMMON_SECTION:
+ do_v850_seg (TBSS_SECTION, 0);
+ break;
+ }
+
+ if (temp)
+ {
+ /* Convert to a power of 2 alignment. */
+ for (align = 0; (temp & 1) == 0; temp >>= 1, ++align)
+ ;
+
+ if (temp != 1)
+ {
+ as_bad (_("Common alignment not a power of 2"));
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ else
+ align = 0;
+
+ record_alignment (now_seg, align);
+
+ if (align)
+ frag_align (align, 0, 0);
+
+ switch (area)
+ {
+ case SCOMMON_SECTION:
+ if (S_GET_SEGMENT (symbolP) == v850_seg_table[SBSS_SECTION].s)
+ symbol_get_frag (symbolP)->fr_symbol = 0;
+ break;
+
+ case ZCOMMON_SECTION:
+ if (S_GET_SEGMENT (symbolP) == v850_seg_table[ZBSS_SECTION].s)
+ symbol_get_frag (symbolP)->fr_symbol = 0;
+ break;
+
+ case TCOMMON_SECTION:
+ if (S_GET_SEGMENT (symbolP) == v850_seg_table[TBSS_SECTION].s)
+ symbol_get_frag (symbolP)->fr_symbol = 0;
+ break;
+
+ default:
+ abort ();
+ }
+
+ symbol_set_frag (symbolP, frag_now);
+ pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
+ (offsetT) size, (char *) 0);
+ *pfrag = 0;
+ S_SET_SIZE (symbolP, size);
+
+ switch (area)
+ {
+ case SCOMMON_SECTION:
+ S_SET_SEGMENT (symbolP, v850_seg_table[SBSS_SECTION].s);
+ break;
+
+ case ZCOMMON_SECTION:
+ S_SET_SEGMENT (symbolP, v850_seg_table[ZBSS_SECTION].s);
+ break;
+
+ case TCOMMON_SECTION:
+ S_SET_SEGMENT (symbolP, v850_seg_table[TBSS_SECTION].s);
+ break;
+
+ default:
+ abort ();
+ }
+
+ S_CLEAR_EXTERNAL (symbolP);
+ obj_elf_section_change_hook ();
+ subseg_set (old_sec, old_subsec);
+ }
+ else
+ {
+ allocate_common:
+ S_SET_VALUE (symbolP, (valueT) size);
+ S_SET_ALIGN (symbolP, temp);
+ S_SET_EXTERNAL (symbolP);
+
+ switch (area)
+ {
+ case SCOMMON_SECTION:
+ case ZCOMMON_SECTION:
+ case TCOMMON_SECTION:
+ do_v850_seg (area, 0);
+ S_SET_SEGMENT (symbolP, v850_seg_table[area].s);
+ break;
+
+ default:
+ abort ();
+ }
+ }
+ }
+ else
+ {
+ input_line_pointer++;
+
+ /* @@ Some use the dot, some don't. Can we get some consistency?? */
+ if (*input_line_pointer == '.')
+ input_line_pointer++;
+
+ /* @@ Some say data, some say bss. */
+ if (strncmp (input_line_pointer, "bss\"", 4)
+ && strncmp (input_line_pointer, "data\"", 5))
+ {
+ while (*--input_line_pointer != '"')
+ ;
+ input_line_pointer--;
+ goto bad_common_segment;
+ }
+ while (*input_line_pointer++ != '"')
+ ;
+ goto allocate_common;
+ }
+
+ symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
+
+ demand_empty_rest_of_line ();
+ return;
+
+ {
+ bad_common_segment:
+ p = input_line_pointer;
+ while (*p && *p != '\n')
+ p++;
+ c = *p;
+ *p = '\0';
+ as_bad (_("bad .common segment %s"), input_line_pointer + 1);
+ *p = c;
+ input_line_pointer = p;
+ ignore_rest_of_line ();
+ return;
+ }
+}
+
+static void set_machine PARAMS ((int));
+
+static void
+set_machine (number)
+ int number;
+{
+ machine = number;
+ bfd_set_arch_mach (stdoutput, TARGET_ARCH, machine);
+
+ switch (machine)
+ {
+ case 0: processor_mask = PROCESSOR_V850; break;
+ case bfd_mach_v850e: processor_mask = PROCESSOR_V850E; break;
+ case bfd_mach_v850ea: processor_mask = PROCESSOR_V850EA; break;
+ }
+}
+
+/* The target specific pseudo-ops which we support. */
+const pseudo_typeS md_pseudo_table[] = {
+ { "sdata", v850_seg, SDATA_SECTION },
+ { "tdata", v850_seg, TDATA_SECTION },
+ { "zdata", v850_seg, ZDATA_SECTION },
+ { "sbss", v850_seg, SBSS_SECTION },
+ { "tbss", v850_seg, TBSS_SECTION },
+ { "zbss", v850_seg, ZBSS_SECTION },
+ { "rosdata", v850_seg, ROSDATA_SECTION },
+ { "rozdata", v850_seg, ROZDATA_SECTION },
+ { "bss", v850_seg, BSS_SECTION },
+ { "offset", v850_offset, 0 },
+ { "word", cons, 4 },
+ { "zcomm", v850_comm, ZCOMMON_SECTION },
+ { "scomm", v850_comm, SCOMMON_SECTION },
+ { "tcomm", v850_comm, TCOMMON_SECTION },
+ { "v850", set_machine, 0 },
+ { "call_table_data", v850_seg, CALL_TABLE_DATA_SECTION },
+ { "call_table_text", v850_seg, CALL_TABLE_TEXT_SECTION },
+ { "v850e", set_machine, bfd_mach_v850e },
+ { "v850ea", set_machine, bfd_mach_v850ea },
+ { "file", dwarf2_directive_file, 0 },
+ { "loc", dwarf2_directive_loc, 0 },
+ { NULL, NULL, 0 }
+};
+
+/* Opcode hash table. */
+static struct hash_control *v850_hash;
+
+/* This table is sorted. Suitable for searching by a binary search. */
+static const struct reg_name pre_defined_registers[] = {
+ { "ep", 30 }, /* ep - element ptr */
+ { "gp", 4 }, /* gp - global ptr */
+ { "hp", 2 }, /* hp - handler stack ptr */
+ { "lp", 31 }, /* lp - link ptr */
+ { "r0", 0 },
+ { "r1", 1 },
+ { "r10", 10 },
+ { "r11", 11 },
+ { "r12", 12 },
+ { "r13", 13 },
+ { "r14", 14 },
+ { "r15", 15 },
+ { "r16", 16 },
+ { "r17", 17 },
+ { "r18", 18 },
+ { "r19", 19 },
+ { "r2", 2 },
+ { "r20", 20 },
+ { "r21", 21 },
+ { "r22", 22 },
+ { "r23", 23 },
+ { "r24", 24 },
+ { "r25", 25 },
+ { "r26", 26 },
+ { "r27", 27 },
+ { "r28", 28 },
+ { "r29", 29 },
+ { "r3", 3 },
+ { "r30", 30 },
+ { "r31", 31 },
+ { "r4", 4 },
+ { "r5", 5 },
+ { "r6", 6 },
+ { "r7", 7 },
+ { "r8", 8 },
+ { "r9", 9 },
+ { "sp", 3 }, /* sp - stack ptr */
+ { "tp", 5 }, /* tp - text ptr */
+ { "zero", 0 },
+};
+
+#define REG_NAME_CNT \
+ (sizeof (pre_defined_registers) / sizeof (struct reg_name))
+
+static const struct reg_name system_registers[] = {
+ { "ctbp", 20 },
+ { "ctpc", 16 },
+ { "ctpsw", 17 },
+ { "dbpc", 18 },
+ { "dbpsw", 19 },
+ { "ecr", 4 },
+ { "eipc", 0 },
+ { "eipsw", 1 },
+ { "fepc", 2 },
+ { "fepsw", 3 },
+ { "psw", 5 },
+};
+
+#define SYSREG_NAME_CNT \
+ (sizeof (system_registers) / sizeof (struct reg_name))
+
+static const struct reg_name system_list_registers[] = {
+ {"PS", 5 },
+ {"SR", 0 + 1}
+};
+
+#define SYSREGLIST_NAME_CNT \
+ (sizeof (system_list_registers) / sizeof (struct reg_name))
+
+static const struct reg_name cc_names[] = {
+ { "c", 0x1 },
+ { "e", 0x2 },
+ { "ge", 0xe },
+ { "gt", 0xf },
+ { "h", 0xb },
+ { "l", 0x1 },
+ { "le", 0x7 },
+ { "lt", 0x6 },
+ { "n", 0x4 },
+ { "nc", 0x9 },
+ { "ne", 0xa },
+ { "nh", 0x3 },
+ { "nl", 0x9 },
+ { "ns", 0xc },
+ { "nv", 0x8 },
+ { "nz", 0xa },
+ { "p", 0xc },
+ { "s", 0x4 },
+ { "sa", 0xd },
+ { "t", 0x5 },
+ { "v", 0x0 },
+ { "z", 0x2 },
+};
+
+#define CC_NAME_CNT \
+ (sizeof (cc_names) / sizeof (struct reg_name))
+
+/* Do a binary search of the given register table to see if NAME is a
+ valid regiter name. Return the register number from the array on
+ success, or -1 on failure. */
+
+static int reg_name_search
+ PARAMS ((const struct reg_name *, int, const char *, boolean));
+
+static int
+reg_name_search (regs, regcount, name, accept_numbers)
+ const struct reg_name *regs;
+ int regcount;
+ const char *name;
+ boolean accept_numbers;
+{
+ int middle, low, high;
+ int cmp;
+ symbolS *symbolP;
+
+ /* If the register name is a symbol, then evaluate it. */
+ if ((symbolP = symbol_find (name)) != NULL)
+ {
+ /* If the symbol is an alias for another name then use that.
+ If the symbol is an alias for a number, then return the number. */
+ if (symbol_equated_p (symbolP))
+ {
+ name
+ = S_GET_NAME (symbol_get_value_expression (symbolP)->X_add_symbol);
+ }
+ else if (accept_numbers)
+ {
+ int reg = S_GET_VALUE (symbolP);
+
+ if (reg >= 0 && reg <= 31)
+ return reg;
+ }
+
+ /* Otherwise drop through and try parsing name normally. */
+ }
+
+ low = 0;
+ high = regcount - 1;
+
+ do
+ {
+ middle = (low + high) / 2;
+ cmp = strcasecmp (name, regs[middle].name);
+ if (cmp < 0)
+ high = middle - 1;
+ else if (cmp > 0)
+ low = middle + 1;
+ else
+ return regs[middle].value;
+ }
+ while (low <= high);
+ return -1;
+}
+
+/* Summary of register_name().
+ *
+ * in: Input_line_pointer points to 1st char of operand.
+ *
+ * out: An expressionS.
+ * The operand may have been a register: in this case, X_op == O_register,
+ * X_add_number is set to the register number, and truth is returned.
+ * Input_line_pointer->(next non-blank) char after operand, or is in
+ * its original state. */
+
+static boolean register_name PARAMS ((expressionS *));
+
+static boolean
+register_name (expressionP)
+ expressionS *expressionP;
+{
+ int reg_number;
+ char *name;
+ char *start;
+ char c;
+
+ /* Find the spelling of the operand. */
+ start = name = input_line_pointer;
+
+ c = get_symbol_end ();
+
+ reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT,
+ name, FALSE);
+
+ /* Put back the delimiting char. */
+ *input_line_pointer = c;
+
+ /* Look to see if it's in the register table. */
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = reg_number;
+
+ /* Make the rest nice. */
+ expressionP->X_add_symbol = NULL;
+ expressionP->X_op_symbol = NULL;
+
+ return true;
+ }
+ else
+ {
+ /* Reset the line as if we had not done anything. */
+ input_line_pointer = start;
+
+ return false;
+ }
+}
+
+/* Summary of system_register_name().
+ *
+ * in: INPUT_LINE_POINTER points to 1st char of operand.
+ * EXPRESSIONP points to an expression structure to be filled in.
+ * ACCEPT_NUMBERS is true iff numerical register names may be used.
+ * ACCEPT_LIST_NAMES is true iff the special names PS and SR may be
+ * accepted.
+ *
+ * out: An expressionS structure in expressionP.
+ * The operand may have been a register: in this case, X_op == O_register,
+ * X_add_number is set to the register number, and truth is returned.
+ * Input_line_pointer->(next non-blank) char after operand, or is in
+ * its original state. */
+
+static boolean system_register_name PARAMS ((expressionS *, boolean, boolean));
+
+static boolean
+system_register_name (expressionP, accept_numbers, accept_list_names)
+ expressionS *expressionP;
+ boolean accept_numbers;
+ boolean accept_list_names;
+{
+ int reg_number;
+ char *name;
+ char *start;
+ char c;
+
+ /* Find the spelling of the operand. */
+ start = name = input_line_pointer;
+
+ c = get_symbol_end ();
+ reg_number = reg_name_search (system_registers, SYSREG_NAME_CNT, name,
+ accept_numbers);
+
+ /* Put back the delimiting char. */
+ *input_line_pointer = c;
+
+ if (reg_number < 0
+ && accept_numbers)
+ {
+ /* Reset input_line pointer. */
+ input_line_pointer = start;
+
+ if (ISDIGIT (*input_line_pointer))
+ {
+ reg_number = strtol (input_line_pointer, &input_line_pointer, 10);
+
+ /* Make sure that the register number is allowable. */
+ if (reg_number < 0
+ || (reg_number > 5 && reg_number < 16)
+ || reg_number > 20)
+ {
+ reg_number = -1;
+ }
+ }
+ else if (accept_list_names)
+ {
+ c = get_symbol_end ();
+ reg_number = reg_name_search (system_list_registers,
+ SYSREGLIST_NAME_CNT, name, FALSE);
+
+ /* Put back the delimiting char. */
+ *input_line_pointer = c;
+ }
+ }
+
+ /* Look to see if it's in the register table. */
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = reg_number;
+
+ /* Make the rest nice. */
+ expressionP->X_add_symbol = NULL;
+ expressionP->X_op_symbol = NULL;
+
+ return true;
+ }
+ else
+ {
+ /* Reset the line as if we had not done anything. */
+ input_line_pointer = start;
+
+ return false;
+ }
+}
+
+/* Summary of cc_name().
+ *
+ * in: INPUT_LINE_POINTER points to 1st char of operand.
+ *
+ * out: An expressionS.
+ * The operand may have been a register: in this case, X_op == O_register,
+ * X_add_number is set to the register number, and truth is returned.
+ * Input_line_pointer->(next non-blank) char after operand, or is in
+ * its original state. */
+
+static boolean cc_name PARAMS ((expressionS *));
+
+static boolean
+cc_name (expressionP)
+ expressionS *expressionP;
+{
+ int reg_number;
+ char *name;
+ char *start;
+ char c;
+
+ /* Find the spelling of the operand. */
+ start = name = input_line_pointer;
+
+ c = get_symbol_end ();
+ reg_number = reg_name_search (cc_names, CC_NAME_CNT, name, FALSE);
+
+ /* Put back the delimiting char. */
+ *input_line_pointer = c;
+
+ /* Look to see if it's in the register table. */
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_constant;
+ expressionP->X_add_number = reg_number;
+
+ /* Make the rest nice. */
+ expressionP->X_add_symbol = NULL;
+ expressionP->X_op_symbol = NULL;
+
+ return true;
+ }
+ else
+ {
+ /* Reset the line as if we had not done anything. */
+ input_line_pointer = start;
+
+ return false;
+ }
+}
+
+static void skip_white_space PARAMS ((void));
+
+static void
+skip_white_space ()
+{
+ while (*input_line_pointer == ' '
+ || *input_line_pointer == '\t')
+ ++input_line_pointer;
+}
+
+/* Summary of parse_register_list ().
+ *
+ * in: INPUT_LINE_POINTER points to 1st char of a list of registers.
+ * INSN is the partially constructed instruction.
+ * OPERAND is the operand being inserted.
+ *
+ * out: NULL if the parse completed successfully, otherwise a
+ * pointer to an error message is returned. If the parse
+ * completes the correct bit fields in the instruction
+ * will be filled in.
+ *
+ * Parses register lists with the syntax:
+ *
+ * { rX }
+ * { rX, rY }
+ * { rX - rY }
+ * { rX - rY, rZ }
+ * etc
+ *
+ * and also parses constant epxressions whoes bits indicate the
+ * registers in the lists. The LSB in the expression refers to
+ * the lowest numbered permissable register in the register list,
+ * and so on upwards. System registers are considered to be very
+ * high numbers. */
+
+static char *parse_register_list
+ PARAMS ((unsigned long *, const struct v850_operand *));
+
+static char *
+parse_register_list (insn, operand)
+ unsigned long *insn;
+ const struct v850_operand *operand;
+{
+ static int type1_regs[32] = {
+ 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24
+ };
+ static int type2_regs[32] = {
+ 19, 18, 17, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 30, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24
+ };
+ static int type3_regs[32] = {
+ 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 14, 15, 13, 12, 7, 6, 5, 4, 11, 10, 9, 8
+ };
+ int *regs;
+ expressionS exp;
+
+ /* Select a register array to parse. */
+ switch (operand->shift)
+ {
+ case 0xffe00001: regs = type1_regs; break;
+ case 0xfff8000f: regs = type2_regs; break;
+ case 0xfff8001f: regs = type3_regs; break;
+ default:
+ as_bad (_("unknown operand shift: %x\n"), operand->shift);
+ return _("internal failure in parse_register_list");
+ }
+
+ skip_white_space ();
+
+ /* If the expression starts with a curly brace it is a register list.
+ Otherwise it is a constant expression, whoes bits indicate which
+ registers are to be included in the list. */
+
+ if (*input_line_pointer != '{')
+ {
+ int reg;
+ int i;
+
+ expression (&exp);
+
+ if (exp.X_op != O_constant)
+ return _("constant expression or register list expected");
+
+ if (regs == type1_regs)
+ {
+ if (exp.X_add_number & 0xFFFFF000)
+ return _("high bits set in register list expression");
+
+ for (reg = 20; reg < 32; reg++)
+ if (exp.X_add_number & (1 << (reg - 20)))
+ {
+ for (i = 0; i < 32; i++)
+ if (regs[i] == reg)
+ *insn |= (1 << i);
+ }
+ }
+ else if (regs == type2_regs)
+ {
+ if (exp.X_add_number & 0xFFFE0000)
+ return _("high bits set in register list expression");
+
+ for (reg = 1; reg < 16; reg++)
+ if (exp.X_add_number & (1 << (reg - 1)))
+ {
+ for (i = 0; i < 32; i++)
+ if (regs[i] == reg)
+ *insn |= (1 << i);
+ }
+
+ if (exp.X_add_number & (1 << 15))
+ *insn |= (1 << 3);
+
+ if (exp.X_add_number & (1 << 16))
+ *insn |= (1 << 19);
+ }
+ else /* regs == type3_regs */
+ {
+ if (exp.X_add_number & 0xFFFE0000)
+ return _("high bits set in register list expression");
+
+ for (reg = 16; reg < 32; reg++)
+ if (exp.X_add_number & (1 << (reg - 16)))
+ {
+ for (i = 0; i < 32; i++)
+ if (regs[i] == reg)
+ *insn |= (1 << i);
+ }
+
+ if (exp.X_add_number & (1 << 16))
+ *insn |= (1 << 19);
+ }
+
+ return NULL;
+ }
+
+ input_line_pointer++;
+
+ /* Parse the register list until a terminator (closing curly brace or
+ new-line) is found. */
+ for (;;)
+ {
+ if (register_name (&exp))
+ {
+ int i;
+
+ /* Locate the given register in the list, and if it is there,
+ insert the corresponding bit into the instruction. */
+ for (i = 0; i < 32; i++)
+ {
+ if (regs[i] == exp.X_add_number)
+ {
+ *insn |= (1 << i);
+ break;
+ }
+ }
+
+ if (i == 32)
+ {
+ return _("illegal register included in list");
+ }
+ }
+ else if (system_register_name (&exp, true, true))
+ {
+ if (regs == type1_regs)
+ {
+ return _("system registers cannot be included in list");
+ }
+ else if (exp.X_add_number == 5)
+ {
+ if (regs == type2_regs)
+ return _("PSW cannot be included in list");
+ else
+ *insn |= 0x8;
+ }
+ else if (exp.X_add_number < 4)
+ *insn |= 0x80000;
+ else
+ return _("High value system registers cannot be included in list");
+ }
+ else if (*input_line_pointer == '}')
+ {
+ input_line_pointer++;
+ break;
+ }
+ else if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ continue;
+ }
+ else if (*input_line_pointer == '-')
+ {
+ /* We have encountered a range of registers: rX - rY. */
+ int j;
+ expressionS exp2;
+
+ /* Skip the dash. */
+ ++input_line_pointer;
+
+ /* Get the second register in the range. */
+ if (! register_name (&exp2))
+ {
+ return _("second register should follow dash in register list");
+ exp2.X_add_number = exp.X_add_number;
+ }
+
+ /* Add the rest of the registers in the range. */
+ for (j = exp.X_add_number + 1; j <= exp2.X_add_number; j++)
+ {
+ int i;
+
+ /* Locate the given register in the list, and if it is there,
+ insert the corresponding bit into the instruction. */
+ for (i = 0; i < 32; i++)
+ {
+ if (regs[i] == j)
+ {
+ *insn |= (1 << i);
+ break;
+ }
+ }
+
+ if (i == 32)
+ return _("illegal register included in list");
+ }
+ }
+ else
+ {
+ break;
+ }
+
+ skip_white_space ();
+ }
+
+ return NULL;
+}
+
+const char *md_shortopts = "m:";
+
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+
+size_t md_longopts_size = sizeof (md_longopts);
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf (stream, _(" V850 options:\n"));
+ fprintf (stream, _(" -mwarn-signed-overflow Warn if signed immediate values overflow\n"));
+ fprintf (stream, _(" -mwarn-unsigned-overflow Warn if unsigned immediate values overflow\n"));
+ fprintf (stream, _(" -mv850 The code is targeted at the v850\n"));
+ fprintf (stream, _(" -mv850e The code is targeted at the v850e\n"));
+ fprintf (stream, _(" -mv850ea The code is targeted at the v850ea\n"));
+ fprintf (stream, _(" -mv850any The code is generic, despite any processor specific instructions\n"));
+}
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ if (c != 'm')
+ {
+ if (c != 'a')
+ /* xgettext:c-format */
+ fprintf (stderr, _("unknown command line option: -%c%s\n"), c, arg);
+ return 0;
+ }
+
+ if (strcmp (arg, "warn-signed-overflow") == 0)
+ {
+ warn_signed_overflows = TRUE;
+ }
+ else if (strcmp (arg, "warn-unsigned-overflow") == 0)
+ {
+ warn_unsigned_overflows = TRUE;
+ }
+ else if (strcmp (arg, "v850") == 0)
+ {
+ machine = 0;
+ processor_mask = PROCESSOR_V850;
+ }
+ else if (strcmp (arg, "v850e") == 0)
+ {
+ machine = bfd_mach_v850e;
+ processor_mask = PROCESSOR_V850E;
+ }
+ else if (strcmp (arg, "v850ea") == 0)
+ {
+ machine = bfd_mach_v850ea;
+ processor_mask = PROCESSOR_V850EA;
+ }
+ else if (strcmp (arg, "v850any") == 0)
+ {
+ /* Tell the world that this is for any v850 chip. */
+ machine = 0;
+
+ /* But support instructions for the extended versions. */
+ processor_mask = PROCESSOR_V850EA;
+ }
+ else
+ {
+ /* xgettext:c-format */
+ fprintf (stderr, _("unknown command line option: -%c%s\n"), c, arg);
+ return 0;
+ }
+
+ return 1;
+}
+
+symbolS *
+md_undefined_symbol (name)
+ char *name ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
+
+char *
+md_atof (type, litp, sizep)
+ int type;
+ char *litp;
+ int *sizep;
+{
+ int prec;
+ LITTLENUM_TYPE words[4];
+ char *t;
+ int i;
+
+ switch (type)
+ {
+ case 'f':
+ prec = 2;
+ break;
+
+ case 'd':
+ prec = 4;
+ break;
+
+ default:
+ *sizep = 0;
+ return _("bad call to md_atof");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizep = prec * 2;
+
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litp, (valueT) words[i], 2);
+ litp += 2;
+ }
+
+ return NULL;
+}
+
+/* Very gross. */
+
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *sec;
+ fragS *fragP;
+{
+ subseg_change (sec, 0);
+
+ /* In range conditional or unconditional branch. */
+ if (fragP->fr_subtype == 0 || fragP->fr_subtype == 2)
+ {
+ fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int)fragP->fr_opcode);
+ fragP->fr_fix += 2;
+ }
+ /* Out of range conditional branch. Emit a branch around a jump. */
+ else if (fragP->fr_subtype == 1)
+ {
+ unsigned char *buffer =
+ (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
+
+ /* Reverse the condition of the first branch. */
+ buffer[0] ^= 0x08;
+ /* Mask off all the displacement bits. */
+ buffer[0] &= 0x8f;
+ buffer[1] &= 0x07;
+ /* Now set the displacement bits so that we branch
+ around the unconditional branch. */
+ buffer[0] |= 0x30;
+
+ /* Now create the unconditional branch + fixup to the final
+ target. */
+ md_number_to_chars (buffer + 2, 0x00000780, 4);
+ fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_UNUSED +
+ (int) fragP->fr_opcode + 1);
+ fragP->fr_fix += 6;
+ }
+ /* Out of range unconditional branch. Emit a jump. */
+ else if (fragP->fr_subtype == 3)
+ {
+ md_number_to_chars (fragP->fr_fix + fragP->fr_literal, 0x00000780, 4);
+ fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_UNUSED +
+ (int) fragP->fr_opcode + 1);
+ fragP->fr_fix += 4;
+ }
+ else
+ abort ();
+}
+
+valueT
+md_section_align (seg, addr)
+ asection *seg;
+ valueT addr;
+{
+ int align = bfd_get_section_alignment (stdoutput, seg);
+ return ((addr + (1 << align) - 1) & (-1 << align));
+}
+
+void
+md_begin ()
+{
+ char *prev_name = "";
+ register const struct v850_opcode *op;
+
+ if (strncmp (TARGET_CPU, "v850ea", 6) == 0)
+ {
+ if (machine == -1)
+ machine = bfd_mach_v850ea;
+
+ if (processor_mask == -1)
+ processor_mask = PROCESSOR_V850EA;
+ }
+ else if (strncmp (TARGET_CPU, "v850e", 5) == 0)
+ {
+ if (machine == -1)
+ machine = bfd_mach_v850e;
+
+ if (processor_mask == -1)
+ processor_mask = PROCESSOR_V850E;
+ }
+ else if (strncmp (TARGET_CPU, "v850", 4) == 0)
+ {
+ if (machine == -1)
+ machine = 0;
+
+ if (processor_mask == -1)
+ processor_mask = PROCESSOR_V850;
+ }
+ else
+ /* xgettext:c-format */
+ as_bad (_("Unable to determine default target processor from string: %s"),
+ TARGET_CPU);
+
+ v850_hash = hash_new ();
+
+ /* Insert unique names into hash table. The V850 instruction set
+ has many identical opcode names that have different opcodes based
+ on the operands. This hash table then provides a quick index to
+ the first opcode with a particular name in the opcode table. */
+
+ op = v850_opcodes;
+ while (op->name)
+ {
+ if (strcmp (prev_name, op->name))
+ {
+ prev_name = (char *) op->name;
+ hash_insert (v850_hash, op->name, (char *) op);
+ }
+ op++;
+ }
+
+ v850_seg_table[BSS_SECTION].s = bss_section;
+ bfd_set_arch_mach (stdoutput, TARGET_ARCH, machine);
+}
+
+static bfd_reloc_code_real_type handle_ctoff
+ PARAMS ((const struct v850_operand *));
+
+static bfd_reloc_code_real_type
+handle_ctoff (operand)
+ const struct v850_operand *operand;
+{
+ if (operand == NULL)
+ return BFD_RELOC_V850_CALLT_16_16_OFFSET;
+
+ if (operand->bits != 6
+ || operand->shift != 0)
+ {
+ as_bad (_("ctoff() relocation used on an instruction which does not support it"));
+ return BFD_RELOC_64; /* Used to indicate an error condition. */
+ }
+
+ return BFD_RELOC_V850_CALLT_6_7_OFFSET;
+}
+
+static bfd_reloc_code_real_type handle_sdaoff
+ PARAMS ((const struct v850_operand *));
+
+static bfd_reloc_code_real_type
+handle_sdaoff (operand)
+ const struct v850_operand *operand;
+{
+ if (operand == NULL)
+ return BFD_RELOC_V850_SDA_16_16_OFFSET;
+
+ if (operand->bits == 15 && operand->shift == 17)
+ return BFD_RELOC_V850_SDA_15_16_OFFSET;
+
+ if (operand->bits == -1)
+ return BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET;
+
+ if (operand->bits != 16
+ || operand->shift != 16)
+ {
+ as_bad (_("sdaoff() relocation used on an instruction which does not support it"));
+ return BFD_RELOC_64; /* Used to indicate an error condition. */
+ }
+
+ return BFD_RELOC_V850_SDA_16_16_OFFSET;
+}
+
+static bfd_reloc_code_real_type handle_zdaoff
+ PARAMS ((const struct v850_operand *));
+
+static bfd_reloc_code_real_type
+handle_zdaoff (operand)
+ const struct v850_operand *operand;
+{
+ if (operand == NULL)
+ return BFD_RELOC_V850_ZDA_16_16_OFFSET;
+
+ if (operand->bits == 15 && operand->shift == 17)
+ return BFD_RELOC_V850_ZDA_15_16_OFFSET;
+
+ if (operand->bits == -1)
+ return BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET;
+
+ if (operand->bits != 16
+ || operand->shift != 16)
+ {
+ as_bad (_("zdaoff() relocation used on an instruction which does not support it"));
+ /* Used to indicate an error condition. */
+ return BFD_RELOC_64;
+ }
+
+ return BFD_RELOC_V850_ZDA_16_16_OFFSET;
+}
+
+static bfd_reloc_code_real_type handle_tdaoff
+ PARAMS ((const struct v850_operand *));
+
+static bfd_reloc_code_real_type
+handle_tdaoff (operand)
+ const struct v850_operand *operand;
+{
+ if (operand == NULL)
+ /* Data item, not an instruction. */
+ return BFD_RELOC_V850_TDA_7_7_OFFSET;
+
+ if (operand->bits == 6 && operand->shift == 1)
+ /* sld.w/sst.w, operand: D8_6 */
+ return BFD_RELOC_V850_TDA_6_8_OFFSET;
+
+ if (operand->bits == 4 && operand->insert != NULL)
+ /* sld.hu, operand: D5-4 */
+ return BFD_RELOC_V850_TDA_4_5_OFFSET;
+
+ if (operand->bits == 4 && operand->insert == NULL)
+ /* sld.bu, operand: D4 */
+ return BFD_RELOC_V850_TDA_4_4_OFFSET;
+
+ if (operand->bits == 16 && operand->shift == 16)
+ /* set1 & chums, operands: D16 */
+ return BFD_RELOC_V850_TDA_16_16_OFFSET;
+
+ if (operand->bits != 7)
+ {
+ as_bad (_("tdaoff() relocation used on an instruction which does not support it"));
+ /* Used to indicate an error condition. */
+ return BFD_RELOC_64;
+ }
+
+ return operand->insert != NULL
+ ? BFD_RELOC_V850_TDA_7_8_OFFSET /* sld.h/sst.h, operand: D8_7 */
+ : BFD_RELOC_V850_TDA_7_7_OFFSET; /* sld.b/sst.b, opreand: D7 */
+}
+
+/* Warning: The code in this function relies upon the definitions
+ in the v850_operands[] array (defined in opcodes/v850-opc.c)
+ matching the hard coded values contained herein. */
+
+static bfd_reloc_code_real_type v850_reloc_prefix
+ PARAMS ((const struct v850_operand *));
+
+static bfd_reloc_code_real_type
+v850_reloc_prefix (operand)
+ const struct v850_operand *operand;
+{
+ boolean paren_skipped = false;
+
+ /* Skip leading opening parenthesis. */
+ if (*input_line_pointer == '(')
+ {
+ ++input_line_pointer;
+ paren_skipped = true;
+ }
+
+#define CHECK_(name, reloc) \
+ if (strncmp (input_line_pointer, name "(", strlen (name) + 1) == 0) \
+ { \
+ input_line_pointer += strlen (name); \
+ return reloc; \
+ }
+
+ CHECK_ ("hi0", BFD_RELOC_HI16 );
+ CHECK_ ("hi", BFD_RELOC_HI16_S );
+ CHECK_ ("lo", BFD_RELOC_LO16 );
+ CHECK_ ("sdaoff", handle_sdaoff (operand));
+ CHECK_ ("zdaoff", handle_zdaoff (operand));
+ CHECK_ ("tdaoff", handle_tdaoff (operand));
+ CHECK_ ("hilo", BFD_RELOC_32 );
+ CHECK_ ("ctoff", handle_ctoff (operand) );
+
+ /* Restore skipped parenthesis. */
+ if (paren_skipped)
+ --input_line_pointer;
+
+ return BFD_RELOC_UNUSED;
+}
+
+/* Insert an operand value into an instruction. */
+
+static unsigned long v850_insert_operand
+ PARAMS ((unsigned long, const struct v850_operand *, offsetT, char *,
+ unsigned int, char *));
+
+static unsigned long
+v850_insert_operand (insn, operand, val, file, line, str)
+ unsigned long insn;
+ const struct v850_operand *operand;
+ offsetT val;
+ char *file;
+ unsigned int line;
+ char *str;
+{
+ if (operand->insert)
+ {
+ const char *message = NULL;
+
+ insn = operand->insert (insn, val, &message);
+ if (message != NULL)
+ {
+ if ((operand->flags & V850_OPERAND_SIGNED)
+ && ! warn_signed_overflows
+ && strstr (message, "out of range") != NULL)
+ {
+ /* Skip warning... */
+ }
+ else if ((operand->flags & V850_OPERAND_SIGNED) == 0
+ && ! warn_unsigned_overflows
+ && strstr (message, "out of range") != NULL)
+ {
+ /* Skip warning... */
+ }
+ else if (str)
+ {
+ if (file == (char *) NULL)
+ as_warn ("%s: %s", str, message);
+ else
+ as_warn_where (file, line, "%s: %s", str, message);
+ }
+ else
+ {
+ if (file == (char *) NULL)
+ as_warn (message);
+ else
+ as_warn_where (file, line, message);
+ }
+ }
+ }
+ else
+ {
+ if (operand->bits != 32)
+ {
+ long min, max;
+
+ if ((operand->flags & V850_OPERAND_SIGNED) != 0)
+ {
+ if (! warn_signed_overflows)
+ max = (1 << operand->bits) - 1;
+ else
+ max = (1 << (operand->bits - 1)) - 1;
+
+ min = -(1 << (operand->bits - 1));
+ }
+ else
+ {
+ max = (1 << operand->bits) - 1;
+
+ if (! warn_unsigned_overflows)
+ min = -(1 << (operand->bits - 1));
+ else
+ min = 0;
+ }
+
+ if (val < (offsetT) min || val > (offsetT) max)
+ {
+ /* xgettext:c-format */
+ const char *err =
+ _("operand out of range (%s not between %ld and %ld)");
+ char buf[100];
+
+ /* Restore min and mix to expected values for decimal ranges. */
+ if ((operand->flags & V850_OPERAND_SIGNED)
+ && ! warn_signed_overflows)
+ max = (1 << (operand->bits - 1)) - 1;
+
+ if (! (operand->flags & V850_OPERAND_SIGNED)
+ && ! warn_unsigned_overflows)
+ min = 0;
+
+ if (str)
+ {
+ sprintf (buf, "%s: ", str);
+
+ sprint_value (buf + strlen (buf), val);
+ }
+ else
+ sprint_value (buf, val);
+
+ if (file == (char *) NULL)
+ as_warn (err, buf, min, max);
+ else
+ as_warn_where (file, line, err, buf, min, max);
+ }
+ }
+
+ insn |= (((long) val & ((1 << operand->bits) - 1)) << operand->shift);
+ }
+
+ return insn;
+}
+
+static char copy_of_instruction[128];
+
+void
+md_assemble (str)
+ char *str;
+{
+ char *s;
+ char *start_of_operands;
+ struct v850_opcode *opcode;
+ struct v850_opcode *next_opcode;
+ const unsigned char *opindex_ptr;
+ int next_opindex;
+ int relaxable = 0;
+ unsigned long insn;
+ unsigned long insn_size;
+ char *f;
+ int i;
+ int match;
+ boolean extra_data_after_insn = false;
+ unsigned extra_data_len = 0;
+ unsigned long extra_data = 0;
+ char *saved_input_line_pointer;
+
+ strncpy (copy_of_instruction, str, sizeof (copy_of_instruction) - 1);
+
+ /* Get the opcode. */
+ for (s = str; *s != '\0' && ! ISSPACE (*s); s++)
+ continue;
+
+ if (*s != '\0')
+ *s++ = '\0';
+
+ /* Find the first opcode with the proper name. */
+ opcode = (struct v850_opcode *) hash_find (v850_hash, str);
+ if (opcode == NULL)
+ {
+ /* xgettext:c-format */
+ as_bad (_("Unrecognized opcode: `%s'"), str);
+ ignore_rest_of_line ();
+ return;
+ }
+
+ str = s;
+ while (ISSPACE (*str))
+ ++str;
+
+ start_of_operands = str;
+
+ saved_input_line_pointer = input_line_pointer;
+
+ for (;;)
+ {
+ const char *errmsg = NULL;
+
+ match = 0;
+
+ if ((opcode->processors & processor_mask) == 0)
+ {
+ errmsg = _("Target processor does not support this instruction.");
+ goto error;
+ }
+
+ relaxable = 0;
+ fc = 0;
+ next_opindex = 0;
+ insn = opcode->opcode;
+ extra_data_after_insn = false;
+
+ input_line_pointer = str = start_of_operands;
+
+ for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
+ {
+ const struct v850_operand *operand;
+ char *hold;
+ expressionS ex;
+ bfd_reloc_code_real_type reloc;
+
+ if (next_opindex == 0)
+ {
+ operand = &v850_operands[*opindex_ptr];
+ }
+ else
+ {
+ operand = &v850_operands[next_opindex];
+ next_opindex = 0;
+ }
+
+ errmsg = NULL;
+
+ while (*str == ' ' || *str == ',' || *str == '[' || *str == ']')
+ ++str;
+
+ if (operand->flags & V850_OPERAND_RELAX)
+ relaxable = 1;
+
+ /* Gather the operand. */
+ hold = input_line_pointer;
+ input_line_pointer = str;
+
+ /* lo(), hi(), hi0(), etc... */
+ if ((reloc = v850_reloc_prefix (operand)) != BFD_RELOC_UNUSED)
+ {
+ /* This is a fake reloc, used to indicate an error condition. */
+ if (reloc == BFD_RELOC_64)
+ {
+ match = 1;
+ goto error;
+ }
+
+ expression (&ex);
+
+ if (ex.X_op == O_constant)
+ {
+ switch (reloc)
+ {
+ case BFD_RELOC_V850_ZDA_16_16_OFFSET:
+ /* To cope with "not1 7, zdaoff(0xfffff006)[r0]"
+ and the like. */
+ /* Fall through. */
+
+ case BFD_RELOC_LO16:
+ {
+ /* Truncate, then sign extend the value. */
+ ex.X_add_number = SEXT16 (ex.X_add_number);
+ break;
+ }
+
+ case BFD_RELOC_HI16:
+ {
+ /* Truncate, then sign extend the value. */
+ ex.X_add_number = SEXT16 (ex.X_add_number >> 16);
+ break;
+ }
+
+ case BFD_RELOC_HI16_S:
+ {
+ /* Truncate, then sign extend the value. */
+ int temp = (ex.X_add_number >> 16) & 0xffff;
+
+ temp += (ex.X_add_number >> 15) & 1;
+
+ ex.X_add_number = SEXT16 (temp);
+ break;
+ }
+
+ case BFD_RELOC_32:
+ if ((operand->flags & V850E_IMMEDIATE32) == 0)
+ {
+ errmsg = _("immediate operand is too large");
+ goto error;
+ }
+
+ extra_data_after_insn = true;
+ extra_data_len = 4;
+ extra_data = ex.X_add_number;
+ ex.X_add_number = 0;
+ break;
+
+ default:
+ fprintf (stderr, "reloc: %d\n", reloc);
+ as_bad (_("AAARG -> unhandled constant reloc"));
+ break;
+ }
+
+ if (fc > MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = *opindex_ptr;
+ fixups[fc].reloc = reloc;
+ fc++;
+ }
+ else
+ {
+ if (reloc == BFD_RELOC_32)
+ {
+ if ((operand->flags & V850E_IMMEDIATE32) == 0)
+ {
+ errmsg = _("immediate operand is too large");
+ goto error;
+ }
+
+ extra_data_after_insn = true;
+ extra_data_len = 4;
+ extra_data = ex.X_add_number;
+ }
+
+ if (fc > MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = *opindex_ptr;
+ fixups[fc].reloc = reloc;
+ fc++;
+ }
+ }
+ else
+ {
+ errmsg = NULL;
+
+ if ((operand->flags & V850_OPERAND_REG) != 0)
+ {
+ if (!register_name (&ex))
+ {
+ errmsg = _("invalid register name");
+ }
+ else if ((operand->flags & V850_NOT_R0)
+ && ex.X_add_number == 0)
+ {
+ errmsg = _("register r0 cannot be used here");
+
+ /* Force an error message to be generated by
+ skipping over any following potential matches
+ for this opcode. */
+ opcode += 3;
+ }
+ }
+ else if ((operand->flags & V850_OPERAND_SRG) != 0)
+ {
+ if (!system_register_name (&ex, true, false))
+ {
+ errmsg = _("invalid system register name");
+ }
+ }
+ else if ((operand->flags & V850_OPERAND_EP) != 0)
+ {
+ char *start = input_line_pointer;
+ char c = get_symbol_end ();
+
+ if (strcmp (start, "ep") != 0 && strcmp (start, "r30") != 0)
+ {
+ /* Put things back the way we found them. */
+ *input_line_pointer = c;
+ input_line_pointer = start;
+ errmsg = _("expected EP register");
+ goto error;
+ }
+
+ *input_line_pointer = c;
+ str = input_line_pointer;
+ input_line_pointer = hold;
+
+ while (*str == ' ' || *str == ','
+ || *str == '[' || *str == ']')
+ ++str;
+ continue;
+ }
+ else if ((operand->flags & V850_OPERAND_CC) != 0)
+ {
+ if (!cc_name (&ex))
+ {
+ errmsg = _("invalid condition code name");
+ }
+ }
+ else if (operand->flags & V850E_PUSH_POP)
+ {
+ errmsg = parse_register_list (&insn, operand);
+
+ /* The parse_register_list() function has already done
+ everything, so fake a dummy expression. */
+ ex.X_op = O_constant;
+ ex.X_add_number = 0;
+ }
+ else if (operand->flags & V850E_IMMEDIATE16)
+ {
+ expression (&ex);
+
+ if (ex.X_op != O_constant)
+ errmsg = _("constant expression expected");
+ else if (ex.X_add_number & 0xffff0000)
+ {
+ if (ex.X_add_number & 0xffff)
+ errmsg = _("constant too big to fit into instruction");
+ else if ((insn & 0x001fffc0) == 0x00130780)
+ ex.X_add_number >>= 16;
+ else
+ errmsg = _("constant too big to fit into instruction");
+ }
+
+ extra_data_after_insn = true;
+ extra_data_len = 2;
+ extra_data = ex.X_add_number;
+ ex.X_add_number = 0;
+ }
+ else if (operand->flags & V850E_IMMEDIATE32)
+ {
+ expression (&ex);
+
+ if (ex.X_op != O_constant)
+ errmsg = _("constant expression expected");
+
+ extra_data_after_insn = true;
+ extra_data_len = 4;
+ extra_data = ex.X_add_number;
+ ex.X_add_number = 0;
+ }
+ else if (register_name (&ex)
+ && (operand->flags & V850_OPERAND_REG) == 0)
+ {
+ char c;
+ int exists = 0;
+
+ /* It is possible that an alias has been defined that
+ matches a register name. For example the code may
+ include a ".set ZERO, 0" directive, which matches
+ the register name "zero". Attempt to reparse the
+ field as an expression, and only complain if we
+ cannot generate a constant. */
+
+ input_line_pointer = str;
+
+ c = get_symbol_end ();
+
+ if (symbol_find (str) != NULL)
+ exists = 1;
+
+ *input_line_pointer = c;
+ input_line_pointer = str;
+
+ expression (&ex);
+
+ if (ex.X_op != O_constant)
+ {
+ /* If this register is actually occuring too early on
+ the parsing of the instruction, (because another
+ field is missing) then report this. */
+ if (opindex_ptr[1] != 0
+ && (v850_operands[opindex_ptr[1]].flags
+ & V850_OPERAND_REG))
+ errmsg = _("syntax error: value is missing before the register name");
+ else
+ errmsg = _("syntax error: register not expected");
+
+ /* If we created a symbol in the process of this
+ test then delete it now, so that it will not
+ be output with the real symbols... */
+ if (exists == 0
+ && ex.X_op == O_symbol)
+ symbol_remove (ex.X_add_symbol,
+ &symbol_rootP, &symbol_lastP);
+ }
+ }
+ else if (system_register_name (&ex, false, false)
+ && (operand->flags & V850_OPERAND_SRG) == 0)
+ {
+ errmsg = _("syntax error: system register not expected");
+ }
+ else if (cc_name (&ex)
+ && (operand->flags & V850_OPERAND_CC) == 0)
+ {
+ errmsg = _("syntax error: condition code not expected");
+ }
+ else
+ {
+ expression (&ex);
+ /* Special case:
+ If we are assembling a MOV instruction (or a CALLT.... :-)
+ and the immediate value does not fit into the bits
+ available then create a fake error so that the next MOV
+ instruction will be selected. This one has a 32 bit
+ immediate field. */
+
+ if (((insn & 0x07e0) == 0x0200)
+ && ex.X_op == O_constant
+ && (ex.X_add_number < (-(1 << (operand->bits - 1)))
+ || ex.X_add_number > ((1 << (operand->bits - 1)) - 1)))
+ errmsg = _("immediate operand is too large");
+ }
+
+ if (errmsg)
+ goto error;
+
+#if 0
+ fprintf (stderr,
+ " insn: %x, operand %d, op: %d, add_number: %d\n",
+ insn, opindex_ptr - opcode->operands,
+ ex.X_op, ex.X_add_number);
+#endif
+
+ switch (ex.X_op)
+ {
+ case O_illegal:
+ errmsg = _("illegal operand");
+ goto error;
+ case O_absent:
+ errmsg = _("missing operand");
+ goto error;
+ case O_register:
+ if ((operand->flags
+ & (V850_OPERAND_REG | V850_OPERAND_SRG)) == 0)
+ {
+ errmsg = _("invalid operand");
+ goto error;
+ }
+ insn = v850_insert_operand (insn, operand, ex.X_add_number,
+ (char *) NULL, 0,
+ copy_of_instruction);
+ break;
+
+ case O_constant:
+ insn = v850_insert_operand (insn, operand, ex.X_add_number,
+ (char *) NULL, 0,
+ copy_of_instruction);
+ break;
+
+ default:
+ /* We need to generate a fixup for this expression. */
+ if (fc >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = *opindex_ptr;
+ fixups[fc].reloc = BFD_RELOC_UNUSED;
+ ++fc;
+ break;
+ }
+ }
+
+ str = input_line_pointer;
+ input_line_pointer = hold;
+
+ while (*str == ' ' || *str == ',' || *str == '[' || *str == ']'
+ || *str == ')')
+ ++str;
+ }
+ match = 1;
+
+ error:
+ if (match == 0)
+ {
+ next_opcode = opcode + 1;
+ if (next_opcode->name != NULL
+ && strcmp (next_opcode->name, opcode->name) == 0)
+ {
+ opcode = next_opcode;
+
+ /* Skip versions that are not supported by the target
+ processor. */
+ if ((opcode->processors & processor_mask) == 0)
+ goto error;
+
+ continue;
+ }
+
+ as_bad ("%s: %s", copy_of_instruction, errmsg);
+
+ if (*input_line_pointer == ']')
+ ++input_line_pointer;
+
+ ignore_rest_of_line ();
+ input_line_pointer = saved_input_line_pointer;
+ return;
+ }
+ break;
+ }
+
+ while (ISSPACE (*str))
+ ++str;
+
+ if (*str != '\0')
+ /* xgettext:c-format */
+ as_bad (_("junk at end of line: `%s'"), str);
+
+ input_line_pointer = str;
+
+ /* Tie dwarf2 debug info to the address at the start of the insn.
+ We can't do this after the insn has been output as the current
+ frag may have been closed off. eg. by frag_var. */
+ dwarf2_emit_insn (0);
+
+ /* Write out the instruction. */
+
+ if (relaxable && fc > 0)
+ {
+ insn_size = 2;
+ fc = 0;
+
+ if (!strcmp (opcode->name, "br"))
+ {
+ f = frag_var (rs_machine_dependent, 4, 2, 2,
+ fixups[0].exp.X_add_symbol,
+ fixups[0].exp.X_add_number,
+ (char *) fixups[0].opindex);
+ md_number_to_chars (f, insn, insn_size);
+ md_number_to_chars (f + 2, 0, 2);
+ }
+ else
+ {
+ f = frag_var (rs_machine_dependent, 6, 4, 0,
+ fixups[0].exp.X_add_symbol,
+ fixups[0].exp.X_add_number,
+ (char *) fixups[0].opindex);
+ md_number_to_chars (f, insn, insn_size);
+ md_number_to_chars (f + 2, 0, 4);
+ }
+ }
+ else
+ {
+ /* Four byte insns have an opcode with the two high bits on. */
+ if ((insn & 0x0600) == 0x0600)
+ insn_size = 4;
+ else
+ insn_size = 2;
+
+ /* Special case: 32 bit MOV. */
+ if ((insn & 0xffe0) == 0x0620)
+ insn_size = 2;
+
+ f = frag_more (insn_size);
+ md_number_to_chars (f, insn, insn_size);
+
+ if (extra_data_after_insn)
+ {
+ f = frag_more (extra_data_len);
+ md_number_to_chars (f, extra_data, extra_data_len);
+
+ extra_data_after_insn = false;
+ }
+ }
+
+ /* Create any fixups. At this point we do not use a
+ bfd_reloc_code_real_type, but instead just use the
+ BFD_RELOC_UNUSED plus the operand index. This lets us easily
+ handle fixups for any operand type, although that is admittedly
+ not a very exciting feature. We pick a BFD reloc type in
+ md_apply_fix3. */
+ for (i = 0; i < fc; i++)
+ {
+ const struct v850_operand *operand;
+ bfd_reloc_code_real_type reloc;
+
+ operand = &v850_operands[fixups[i].opindex];
+
+ reloc = fixups[i].reloc;
+
+ if (reloc != BFD_RELOC_UNUSED)
+ {
+ reloc_howto_type *reloc_howto =
+ bfd_reloc_type_lookup (stdoutput, reloc);
+ int size;
+ int address;
+ fixS *fixP;
+
+ if (!reloc_howto)
+ abort ();
+
+ size = bfd_get_reloc_size (reloc_howto);
+
+ /* XXX This will abort on an R_V850_8 reloc -
+ is this reloc actually used? */
+ if (size != 2 && size != 4)
+ abort ();
+
+ address = (f - frag_now->fr_literal) + insn_size - size;
+
+ if (reloc == BFD_RELOC_32)
+ address += 2;
+
+ fixP = fix_new_exp (frag_now, address, size,
+ &fixups[i].exp,
+ reloc_howto->pc_relative,
+ reloc);
+
+ switch (reloc)
+ {
+ case BFD_RELOC_LO16:
+ case BFD_RELOC_HI16:
+ case BFD_RELOC_HI16_S:
+ fixP->fx_no_overflow = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ fix_new_exp (frag_now,
+ f - frag_now->fr_literal, 4,
+ & fixups[i].exp,
+ 1 /* FIXME: V850_OPERAND_RELATIVE ??? */,
+ (bfd_reloc_code_real_type) (fixups[i].opindex
+ + (int) BFD_RELOC_UNUSED));
+ }
+ }
+
+ input_line_pointer = saved_input_line_pointer;
+}
+
+/* If while processing a fixup, a reloc really needs to be created
+ then it is done here. */
+
+arelent *
+tc_gen_reloc (seg, fixp)
+ asection *seg ATTRIBUTE_UNUSED;
+ fixS *fixp;
+{
+ arelent *reloc;
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+
+ if (reloc->howto == (reloc_howto_type *) NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ /* xgettext:c-format */
+ _("reloc %d not supported by object file format"),
+ (int) fixp->fx_r_type);
+
+ xfree (reloc);
+
+ return NULL;
+ }
+
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
+ reloc->addend = fixp->fx_offset;
+ else
+ reloc->addend = fixp->fx_addnumber;
+
+ return reloc;
+}
+
+/* Return current size of variable part of frag. */
+
+int
+md_estimate_size_before_relax (fragp, seg)
+ fragS *fragp;
+ asection *seg ATTRIBUTE_UNUSED;
+{
+ if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
+ abort ();
+
+ return md_relax_table[fragp->fr_subtype].rlx_length;
+}
+
+long
+v850_pcrel_from_section (fixp, section)
+ fixS *fixp;
+ segT section;
+{
+ /* If the symbol is undefined, or in a section other than our own,
+ or it is weak (in which case it may well be in another section,
+ then let the linker figure it out. */
+ if (fixp->fx_addsy != (symbolS *) NULL
+ && (! S_IS_DEFINED (fixp->fx_addsy)
+ || S_IS_WEAK (fixp->fx_addsy)
+ || (S_GET_SEGMENT (fixp->fx_addsy) != section)))
+ return 0;
+
+ return fixp->fx_frag->fr_address + fixp->fx_where;
+}
+
+void
+md_apply_fix3 (fixP, valueP, seg)
+ fixS *fixP;
+ valueT *valueP;
+ segT seg ATTRIBUTE_UNUSED;
+{
+ valueT value = * valueP;
+ char *where;
+
+ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ {
+ fixP->fx_done = 0;
+ return;
+ }
+
+ if (fixP->fx_addsy == (symbolS *) NULL)
+ fixP->fx_done = 1;
+
+ else if (fixP->fx_pcrel)
+ ;
+
+ else
+ {
+ value = fixP->fx_offset;
+ if (fixP->fx_subsy != (symbolS *) NULL)
+ {
+ if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
+ value -= S_GET_VALUE (fixP->fx_subsy);
+ else
+ {
+ /* We don't actually support subtracting a symbol. */
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("expression too complex"));
+ }
+ }
+ }
+
+ if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
+ {
+ int opindex;
+ const struct v850_operand *operand;
+ unsigned long insn;
+
+ opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
+ operand = &v850_operands[opindex];
+
+ /* Fetch the instruction, insert the fully resolved operand
+ value, and stuff the instruction back again.
+
+ Note the instruction has been stored in little endian
+ format! */
+ where = fixP->fx_frag->fr_literal + fixP->fx_where;
+
+ insn = bfd_getl32 ((unsigned char *) where);
+ insn = v850_insert_operand (insn, operand, (offsetT) value,
+ fixP->fx_file, fixP->fx_line, NULL);
+ bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
+
+ if (fixP->fx_done)
+ /* Nothing else to do here. */
+ return;
+
+ /* Determine a BFD reloc value based on the operand information.
+ We are only prepared to turn a few of the operands into relocs. */
+
+ if (operand->bits == 22)
+ fixP->fx_r_type = BFD_RELOC_V850_22_PCREL;
+ else if (operand->bits == 9)
+ fixP->fx_r_type = BFD_RELOC_V850_9_PCREL;
+ else
+ {
+#if 0
+ fprintf (stderr, "bits: %d, insn: %x\n", operand->bits, insn);
+#endif
+
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("unresolved expression that must be resolved"));
+ fixP->fx_done = 1;
+ return;
+ }
+ }
+ else if (fixP->fx_done)
+ {
+ /* We still have to insert the value into memory! */
+ where = fixP->fx_frag->fr_literal + fixP->fx_where;
+
+ if (fixP->fx_size == 1)
+ *where = value & 0xff;
+ else if (fixP->fx_size == 2)
+ bfd_putl16 (value & 0xffff, (unsigned char *) where);
+ else if (fixP->fx_size == 4)
+ bfd_putl32 (value, (unsigned char *) where);
+ }
+
+ fixP->fx_addnumber = value;
+}
+
+/* Parse a cons expression. We have to handle hi(), lo(), etc
+ on the v850. */
+
+void
+parse_cons_expression_v850 (exp)
+ expressionS *exp;
+{
+ /* See if there's a reloc prefix like hi() we have to handle. */
+ hold_cons_reloc = v850_reloc_prefix (NULL);
+
+ /* Do normal expression parsing. */
+ expression (exp);
+}
+
+/* Create a fixup for a cons expression. If parse_cons_expression_v850
+ found a reloc prefix, then we use that reloc, else we choose an
+ appropriate one based on the size of the expression. */
+
+void
+cons_fix_new_v850 (frag, where, size, exp)
+ fragS *frag;
+ int where;
+ int size;
+ expressionS *exp;
+{
+ if (hold_cons_reloc == BFD_RELOC_UNUSED)
+ {
+ if (size == 4)
+ hold_cons_reloc = BFD_RELOC_32;
+ if (size == 2)
+ hold_cons_reloc = BFD_RELOC_16;
+ if (size == 1)
+ hold_cons_reloc = BFD_RELOC_8;
+ }
+
+ if (exp != NULL)
+ fix_new_exp (frag, where, size, exp, 0, hold_cons_reloc);
+ else
+ fix_new (frag, where, size, NULL, 0, 0, hold_cons_reloc);
+
+ hold_cons_reloc = BFD_RELOC_UNUSED;
+}
+
+boolean
+v850_fix_adjustable (fixP)
+ fixS *fixP;
+{
+ if (fixP->fx_addsy == NULL)
+ return 1;
+
+ /* Prevent all adjustments to global symbols. */
+ if (S_IS_EXTERN (fixP->fx_addsy))
+ return 0;
+
+ /* Similarly for weak symbols. */
+ if (S_IS_WEAK (fixP->fx_addsy))
+ return 0;
+
+ /* Don't adjust function names. */
+ if (S_IS_FUNCTION (fixP->fx_addsy))
+ return 0;
+
+ /* We need the symbol name for the VTABLE entries. */
+ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+
+ return 1;
+}
+
+int
+v850_force_relocation (fixP)
+ struct fix *fixP;
+{
+ if (fixP->fx_addsy && S_IS_WEAK (fixP->fx_addsy))
+ return 1;
+
+ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 1;
+
+ return 0;
+}
diff --git a/x/binutils/gas/config/tc-v850.h b/x/binutils/gas/config/tc-v850.h
new file mode 100644
index 0000000..8257428
--- /dev/null
+++ b/x/binutils/gas/config/tc-v850.h
@@ -0,0 +1,98 @@
+/* tc-v850.h -- Header file for tc-v850.c.
+ Copyright 1996, 1997, 1998, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_V850
+
+#include "elf/v850.h"
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#ifndef BFD_ASSEMBLER
+ #error V850 support requires BFD_ASSEMBLER
+#endif
+
+/* The target BFD architecture. */
+#define TARGET_ARCH bfd_arch_v850
+
+/* The target BFD format. */
+#define TARGET_FORMAT "elf32-v850"
+
+#define md_operand(x)
+
+#define obj_fix_adjustable(fixP) v850_fix_adjustable(fixP)
+extern boolean v850_fix_adjustable PARAMS ((struct fix *));
+
+#define TC_FORCE_RELOCATION(fixp) v850_force_relocation(fixp)
+extern int v850_force_relocation PARAMS ((struct fix *));
+
+#ifdef OBJ_ELF
+/* This arranges for gas/write.c to not apply a relocation if
+ obj_fix_adjustable() says it is not adjustable. */
+#define TC_FIX_ADJUSTABLE(fixP) obj_fix_adjustable (fixP)
+#endif
+
+/* Permit temporary numeric labels. */
+#define LOCAL_LABELS_FB 1
+
+#define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs. */
+
+/* We don't need to handle .word strangely. */
+#define WORKING_DOT_WORD
+
+#define md_number_to_chars number_to_chars_littleendian
+
+/* We need to handle lo(), hi(), etc etc in .hword, .word, etc
+ directives, so we have to parse "cons" expressions ourselves. */
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_cons_expression_v850 (EXP)
+extern void parse_cons_expression_v850 PARAMS ((expressionS *));
+
+#define TC_CONS_FIX_NEW cons_fix_new_v850
+extern void cons_fix_new_v850 PARAMS ((fragS *, int, int, expressionS *));
+
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+extern const struct relax_type md_relax_table[];
+
+/* This section must be in the small data area (pointed to by GP). */
+#define SHF_V850_GPREL 0x10000000
+/* This section must be in the tiny data area (pointed to by EP). */
+#define SHF_V850_EPREL 0x20000000
+/* This section must be in the zero data area (pointed to by R0). */
+#define SHF_V850_R0REL 0x40000000
+
+#define ELF_TC_SPECIAL_SECTIONS \
+ { ".sdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_GPREL }, \
+ { ".rosdata", SHT_PROGBITS, SHF_ALLOC + SHF_V850_GPREL }, \
+ { ".sbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_GPREL }, \
+ { ".scommon", SHT_V850_SCOMMON, SHF_ALLOC + SHF_WRITE + SHF_V850_GPREL }, \
+ { ".tdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_EPREL }, \
+ { ".tbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_EPREL }, \
+ { ".tcommon", SHT_V850_TCOMMON, SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL }, \
+ { ".zdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL }, \
+ { ".rozdata", SHT_PROGBITS, SHF_ALLOC + SHF_V850_R0REL }, \
+ { ".zbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL }, \
+ { ".zcommon", SHT_V850_ZCOMMON, SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL }, \
+ { ".call_table_data", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, \
+ { ".call_table_text", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_EXECINSTR },
+
+#define MD_PCREL_FROM_SECTION(fixP,section) v850_pcrel_from_section (fixP, section)
+extern long v850_pcrel_from_section PARAMS ((struct fix *, asection *));
+
+#define DWARF2_LINE_MIN_INSN_LENGTH 2
diff --git a/x/binutils/gas/config/tc-z8k.c b/x/binutils/gas/config/tc-z8k.c
new file mode 100644
index 0000000..f5b05a6
--- /dev/null
+++ b/x/binutils/gas/config/tc-z8k.c
@@ -0,0 +1,1566 @@
+/* tc-z8k.c -- Assemble code for the Zilog Z800n
+ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Written By Steve Chamberlain <sac@cygnus.com>. */
+
+#define DEFINE_TABLE
+#include <stdio.h>
+
+#include "as.h"
+#include "bfd.h"
+#include "safe-ctype.h"
+#include "opcodes/z8k-opc.h"
+
+const char comment_chars[] = "!";
+const char line_comment_chars[] = "#";
+const char line_separator_chars[] = ";";
+
+extern int machine;
+extern int coff_flags;
+int segmented_mode;
+const int md_reloc_size;
+
+void cons ();
+
+void
+s_segm ()
+{
+ segmented_mode = 1;
+ machine = bfd_mach_z8001;
+ coff_flags = F_Z8001;
+}
+
+void
+s_unseg ()
+{
+ segmented_mode = 0;
+ machine = bfd_mach_z8002;
+ coff_flags = F_Z8002;
+}
+
+static void
+even ()
+{
+ frag_align (1, 0, 0);
+ record_alignment (now_seg, 1);
+}
+
+void obj_coff_section ();
+
+int
+tohex (c)
+ int c;
+{
+ if (ISDIGIT (c))
+ return c - '0';
+ if (ISLOWER (c))
+ return c - 'a' + 10;
+ return c - 'A' + 10;
+}
+
+void
+sval ()
+{
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\'')
+ {
+ int c;
+ input_line_pointer++;
+ c = *input_line_pointer++;
+ while (c != '\'')
+ {
+ if (c == '%')
+ {
+ c = (tohex (input_line_pointer[0]) << 4)
+ | tohex (input_line_pointer[1]);
+ input_line_pointer += 2;
+ }
+ FRAG_APPEND_1_CHAR (c);
+ c = *input_line_pointer++;
+ }
+ demand_empty_rest_of_line ();
+ }
+}
+
+/* This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+ pseudo-op name without dot
+ function to call to execute this pseudo-op
+ Integer arg to pass to the function
+ */
+
+const pseudo_typeS md_pseudo_table[] = {
+ {"int" , cons , 2},
+ {"data.b" , cons , 1},
+ {"data.w" , cons , 2},
+ {"data.l" , cons , 4},
+ {"form" , listing_psize , 0},
+ {"heading", listing_title , 0},
+ {"import" , s_ignore , 0},
+ {"page" , listing_eject , 0},
+ {"program", s_ignore , 0},
+ {"z8001" , s_segm , 0},
+ {"z8002" , s_unseg , 0},
+
+ {"segm" , s_segm , 0},
+ {"unsegm" , s_unseg , 0},
+ {"unseg" , s_unseg , 0},
+ {"name" , s_app_file , 0},
+ {"global" , s_globl , 0},
+ {"wval" , cons , 2},
+ {"lval" , cons , 4},
+ {"bval" , cons , 1},
+ {"sval" , sval , 0},
+ {"rsect" , obj_coff_section, 0},
+ {"sect" , obj_coff_section, 0},
+ {"block" , s_space , 0},
+ {"even" , even , 0},
+ {0 , 0 , 0}
+};
+
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant.
+ As in 0f12.456
+ or 0d1.2345e12 */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+/* Opcode mnemonics. */
+static struct hash_control *opcode_hash_control;
+
+void
+md_begin ()
+{
+ opcode_entry_type *opcode;
+ char *prev_name = "";
+ int idx = 0;
+
+ opcode_hash_control = hash_new ();
+
+ for (opcode = z8k_table; opcode->name; opcode++)
+ {
+ /* Only enter unique codes into the table. */
+ if (strcmp (opcode->name, prev_name))
+ {
+ hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
+ idx++;
+ }
+ opcode->idx = idx;
+ prev_name = opcode->name;
+ }
+
+ /* Default to z8002. */
+ s_unseg ();
+
+ /* Insert the pseudo ops, too. */
+ for (idx = 0; md_pseudo_table[idx].poc_name; idx++)
+ {
+ opcode_entry_type *fake_opcode;
+ fake_opcode = (opcode_entry_type *) malloc (sizeof (opcode_entry_type));
+ fake_opcode->name = md_pseudo_table[idx].poc_name;
+ fake_opcode->func = (void *) (md_pseudo_table + idx);
+ fake_opcode->opcode = 250;
+ hash_insert (opcode_hash_control, fake_opcode->name, fake_opcode);
+ }
+
+ linkrelax = 1;
+}
+
+struct z8k_exp {
+ char *e_beg;
+ char *e_end;
+ expressionS e_exp;
+};
+
+typedef struct z8k_op {
+ /* 'b','w','r','q'. */
+ char regsize;
+
+ /* 0 .. 15. */
+ unsigned int reg;
+
+ int mode;
+
+ /* Any other register associated with the mode. */
+ unsigned int x_reg;
+
+ /* Any expression. */
+ expressionS exp;
+} op_type;
+
+static expressionS *da_operand;
+static expressionS *imm_operand;
+
+int reg[16];
+int the_cc;
+int the_ctrl;
+int the_flags;
+int the_interrupt;
+
+char *
+whatreg (reg, src)
+ int *reg;
+ char *src;
+{
+ if (ISDIGIT (src[1]))
+ {
+ *reg = (src[0] - '0') * 10 + src[1] - '0';
+ return src + 2;
+ }
+ else
+ {
+ *reg = (src[0] - '0');
+ return src + 1;
+ }
+}
+
+/* Parse operands
+
+ rh0-rh7, rl0-rl7
+ r0-r15
+ rr0-rr14
+ rq0--rq12
+ WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
+ r0l,r0h,..r7l,r7h
+ @WREG
+ @WREG+
+ @-WREG
+ #const
+*/
+
+/* Try to parse a reg name. Return a pointer to the first character
+ in SRC after the reg name. */
+
+char *
+parse_reg (src, mode, reg)
+ char *src;
+ int *mode;
+ unsigned int *reg;
+{
+ char *res = 0;
+ char regno;
+
+ if (src[0] == 's' && src[1] == 'p' && (src[2] == 0 || src[2] == ','))
+ {
+ if (segmented_mode)
+ {
+ *mode = CLASS_REG_LONG;
+ *reg = 14;
+ }
+ else
+ {
+ *mode = CLASS_REG_WORD;
+ *reg = 15;
+ }
+ return src + 2;
+ }
+ if (src[0] == 'r')
+ {
+ if (src[1] == 'r')
+ {
+ if (src[2] < '0' || src[2] > '9')
+ return res; /* Assume no register name but a label starting with 'rr'. */
+ *mode = CLASS_REG_LONG;
+ res = whatreg (reg, src + 2);
+ regno = *reg;
+ if (regno > 14)
+ as_warn (_("register rr%d, out of range."), regno);
+ }
+ else if (src[1] == 'h')
+ {
+ if (src[2] < '0' || src[2] > '9')
+ return res; /* Assume no register name but a label starting with 'rh'. */
+ *mode = CLASS_REG_BYTE;
+ res = whatreg (reg, src + 2);
+ regno = *reg;
+ if (regno > 7)
+ as_warn (_("register rh%d, out of range."), regno);
+ }
+ else if (src[1] == 'l')
+ {
+ if (src[2] < '0' || src[2] > '9')
+ return res; /* Assume no register name but a label starting with 'rl'. */
+ *mode = CLASS_REG_BYTE;
+ res = whatreg (reg, src + 2);
+ regno = *reg;
+ if (regno > 7)
+ as_warn (_("register rl%d, out of range."), regno);
+ *reg += 8;
+ }
+ else if (src[1] == 'q')
+ {
+ if (src[2] < '0' || src[2] > '9')
+ return res; /* Assume no register name but a label starting with 'rq'. */
+ *mode = CLASS_REG_QUAD;
+ res = whatreg (reg, src + 2);
+ regno = *reg;
+ if (regno > 12)
+ as_warn (_("register rq%d, out of range."), regno);
+ }
+ else
+ {
+ if (src[1] < '0' || src[1] > '9')
+ return res; /* Assume no register name but a label starting with 'r'. */
+ *mode = CLASS_REG_WORD;
+ res = whatreg (reg, src + 1);
+ regno = *reg;
+ if (regno > 15)
+ as_warn (_("register r%d, out of range."), regno);
+ }
+ }
+ return res;
+}
+
+char *
+parse_exp (s, op)
+ char *s;
+ expressionS *op;
+{
+ char *save = input_line_pointer;
+ char *new;
+
+ input_line_pointer = s;
+ expression (op);
+ if (op->X_op == O_absent)
+ as_bad (_("missing operand"));
+ new = input_line_pointer;
+ input_line_pointer = save;
+ return new;
+}
+
+/* The many forms of operand:
+
+ <rb>
+ <r>
+ <rr>
+ <rq>
+ @r
+ #exp
+ exp
+ exp(r)
+ r(#exp)
+ r(r)
+ */
+
+static char *
+checkfor (ptr, what)
+ char *ptr;
+ char what;
+{
+ if (*ptr == what)
+ ptr++;
+ else
+ as_bad (_("expected %c"), what);
+
+ return ptr;
+}
+
+/* Make sure the mode supplied is the size of a word. */
+
+static void
+regword (mode, string)
+ int mode;
+ char *string;
+{
+ int ok;
+
+ ok = CLASS_REG_WORD;
+ if (ok != mode)
+ {
+ as_bad (_("register is wrong size for a word %s"), string);
+ }
+}
+
+/* Make sure the mode supplied is the size of an address. */
+
+static void
+regaddr (mode, string)
+ int mode;
+ char *string;
+{
+ int ok;
+
+ ok = segmented_mode ? CLASS_REG_LONG : CLASS_REG_WORD;
+ if (ok != mode)
+ {
+ as_bad (_("register is wrong size for address %s"), string);
+ }
+}
+
+struct ctrl_names {
+ int value;
+ char *name;
+};
+
+struct ctrl_names ctrl_table[] = {
+ { 0x2, "fcw" },
+ { 0x3, "refresh" },
+ { 0x4, "psapseg" },
+ { 0x5, "psapoff" },
+ { 0x5, "psap" },
+ { 0x6, "nspseg" },
+ { 0x7, "nspoff" },
+ { 0x7, "nsp" },
+ { 0 , 0 }
+};
+
+static void
+get_ctrl_operand (ptr, mode, dst)
+ char **ptr;
+ struct z8k_op *mode;
+ unsigned int dst ATTRIBUTE_UNUSED;
+{
+ char *src = *ptr;
+ int i;
+
+ while (*src == ' ')
+ src++;
+
+ mode->mode = CLASS_CTRL;
+ for (i = 0; ctrl_table[i].name; i++)
+ {
+ int j;
+
+ for (j = 0; ctrl_table[i].name[j]; j++)
+ {
+ if (ctrl_table[i].name[j] != src[j])
+ goto fail;
+ }
+ the_ctrl = ctrl_table[i].value;
+ *ptr = src + j;
+ return;
+ fail:
+ ;
+ }
+ the_ctrl = 0;
+ return;
+}
+
+struct flag_names {
+ int value;
+ char *name;
+
+};
+
+struct flag_names flag_table[] = {
+ { 0x1, "p" },
+ { 0x1, "v" },
+ { 0x2, "s" },
+ { 0x4, "z" },
+ { 0x8, "c" },
+ { 0x0, "+" },
+ { 0, 0 }
+};
+
+static void
+get_flags_operand (ptr, mode, dst)
+ char **ptr;
+ struct z8k_op *mode;
+ unsigned int dst ATTRIBUTE_UNUSED;
+{
+ char *src = *ptr;
+ int i;
+ int j;
+
+ while (*src == ' ')
+ src++;
+
+ mode->mode = CLASS_FLAGS;
+ the_flags = 0;
+ for (j = 0; j <= 9; j++)
+ {
+ if (!src[j])
+ goto done;
+ for (i = 0; flag_table[i].name; i++)
+ {
+ if (flag_table[i].name[0] == src[j])
+ {
+ the_flags = the_flags | flag_table[i].value;
+ goto match;
+ }
+ }
+ goto done;
+ match:
+ ;
+ }
+ done:
+ *ptr = src + j;
+ return;
+}
+
+struct interrupt_names {
+ int value;
+ char *name;
+
+};
+
+struct interrupt_names intr_table[] = {
+ { 0x1, "nvi" },
+ { 0x2, "vi" },
+ { 0x3, "both" },
+ { 0x3, "all" },
+ { 0, 0 }
+};
+
+static void
+get_interrupt_operand (ptr, mode, dst)
+ char **ptr;
+ struct z8k_op *mode;
+ unsigned int dst ATTRIBUTE_UNUSED;
+{
+ char *src = *ptr;
+ int i;
+
+ while (*src == ' ')
+ src++;
+
+ mode->mode = CLASS_IMM;
+ for (i = 0; intr_table[i].name; i++)
+ {
+ int j;
+
+ for (j = 0; intr_table[i].name[j]; j++)
+ {
+ if (intr_table[i].name[j] != src[j])
+ goto fail;
+ }
+ the_interrupt = intr_table[i].value;
+ *ptr = src + j;
+ return;
+ fail:
+ ;
+ }
+ the_interrupt = 0x0;
+ return;
+}
+
+struct cc_names {
+ int value;
+ char *name;
+
+};
+
+struct cc_names table[] = {
+ { 0x0, "f" },
+ { 0x1, "lt" },
+ { 0x2, "le" },
+ { 0x3, "ule" },
+ { 0x4, "ov" },
+ { 0x4, "pe" },
+ { 0x5, "mi" },
+ { 0x6, "eq" },
+ { 0x6, "z" },
+ { 0x7, "c" },
+ { 0x7, "ult" },
+ { 0x8, "t" },
+ { 0x9, "ge" },
+ { 0xa, "gt" },
+ { 0xb, "ugt" },
+ { 0xc, "nov" },
+ { 0xc, "po" },
+ { 0xd, "pl" },
+ { 0xe, "ne" },
+ { 0xe, "nz" },
+ { 0xf, "nc" },
+ { 0xf, "uge" },
+ { 0 , 0 }
+};
+
+static void
+get_cc_operand (ptr, mode, dst)
+ char **ptr;
+ struct z8k_op *mode;
+ unsigned int dst ATTRIBUTE_UNUSED;
+{
+ char *src = *ptr;
+ int i;
+
+ while (*src == ' ')
+ src++;
+
+ mode->mode = CLASS_CC;
+ for (i = 0; table[i].name; i++)
+ {
+ int j;
+
+ for (j = 0; table[i].name[j]; j++)
+ {
+ if (table[i].name[j] != src[j])
+ goto fail;
+ }
+ the_cc = table[i].value;
+ *ptr = src + j;
+ return;
+ fail:
+ ;
+ }
+ the_cc = 0x8;
+}
+
+static void
+get_operand (ptr, mode, dst)
+ char **ptr;
+ struct z8k_op *mode;
+ unsigned int dst ATTRIBUTE_UNUSED;
+{
+ char *src = *ptr;
+ char *end;
+
+ mode->mode = 0;
+
+ while (*src == ' ')
+ src++;
+ if (*src == '#')
+ {
+ mode->mode = CLASS_IMM;
+ imm_operand = &(mode->exp);
+ src = parse_exp (src + 1, &(mode->exp));
+ }
+ else if (*src == '@')
+ {
+ int d;
+
+ mode->mode = CLASS_IR;
+ src = parse_reg (src + 1, &d, &mode->reg);
+ }
+ else
+ {
+ int regn;
+
+ end = parse_reg (src, &mode->mode, &regn);
+
+ if (end)
+ {
+ int nw, nr;
+
+ src = end;
+ if (*src == '(')
+ {
+ src++;
+ end = parse_reg (src, &nw, &nr);
+ if (end)
+ {
+ /* Got Ra(Rb). */
+ src = end;
+
+ if (*src != ')')
+ as_bad (_("Missing ) in ra(rb)"));
+ else
+ src++;
+
+ regaddr (mode->mode, "ra(rb) ra");
+#if 0
+ regword (mode->mode, "ra(rb) rb");
+#endif
+ mode->mode = CLASS_BX;
+ mode->reg = regn;
+ mode->x_reg = nr;
+ reg[ARG_RX] = nr;
+ }
+ else
+ {
+ /* Got Ra(disp). */
+ if (*src == '#')
+ src++;
+ src = parse_exp (src, &(mode->exp));
+ src = checkfor (src, ')');
+ mode->mode = CLASS_BA;
+ mode->reg = regn;
+ mode->x_reg = 0;
+ imm_operand = &(mode->exp);
+ }
+ }
+ else
+ {
+ mode->reg = regn;
+ mode->x_reg = 0;
+ }
+ }
+ else
+ {
+ /* No initial reg. */
+ src = parse_exp (src, &(mode->exp));
+ if (*src == '(')
+ {
+ src++;
+ end = parse_reg (src, &(mode->mode), &regn);
+ regword (mode->mode, "addr(Ra) ra");
+ mode->mode = CLASS_X;
+ mode->reg = regn;
+ mode->x_reg = 0;
+ da_operand = &(mode->exp);
+ src = checkfor (end, ')');
+ }
+ else
+ {
+ /* Just an address. */
+ mode->mode = CLASS_DA;
+ mode->reg = 0;
+ mode->x_reg = 0;
+ da_operand = &(mode->exp);
+ }
+ }
+ }
+ *ptr = src;
+}
+
+static char *
+get_operands (opcode, op_end, operand)
+ opcode_entry_type *opcode;
+ char *op_end;
+ op_type *operand;
+{
+ char *ptr = op_end;
+ char *savptr;
+
+ switch (opcode->noperands)
+ {
+ case 0:
+ operand[0].mode = 0;
+ operand[1].mode = 0;
+ break;
+
+ case 1:
+ ptr++;
+ if (opcode->arg_info[0] == CLASS_CC)
+ {
+ get_cc_operand (&ptr, operand + 0, 0);
+ }
+ else if (opcode->arg_info[0] == CLASS_FLAGS)
+ {
+ get_flags_operand (&ptr, operand + 0, 0);
+ }
+ else if (opcode->arg_info[0] == (CLASS_IMM + (ARG_IMM2)))
+ {
+ get_interrupt_operand (&ptr, operand + 0, 0);
+ }
+ else
+ {
+ get_operand (&ptr, operand + 0, 0);
+ }
+ operand[1].mode = 0;
+ break;
+
+ case 2:
+ ptr++;
+ savptr = ptr;
+ if (opcode->arg_info[0] == CLASS_CC)
+ {
+ get_cc_operand (&ptr, operand + 0, 0);
+ }
+ else if (opcode->arg_info[0] == CLASS_CTRL)
+ {
+ get_ctrl_operand (&ptr, operand + 0, 0);
+ if (the_ctrl == 0)
+ {
+ ptr = savptr;
+ get_operand (&ptr, operand + 0, 0);
+ if (ptr == 0)
+ return NULL;
+ if (*ptr == ',')
+ ptr++;
+ get_ctrl_operand (&ptr, operand + 1, 1);
+ return ptr;
+ }
+ }
+ else
+ {
+ get_operand (&ptr, operand + 0, 0);
+ }
+ if (ptr == 0)
+ return NULL;
+ if (*ptr == ',')
+ ptr++;
+ get_operand (&ptr, operand + 1, 1);
+ break;
+
+ case 3:
+ ptr++;
+ get_operand (&ptr, operand + 0, 0);
+ if (*ptr == ',')
+ ptr++;
+ get_operand (&ptr, operand + 1, 1);
+ if (*ptr == ',')
+ ptr++;
+ get_operand (&ptr, operand + 2, 2);
+ break;
+
+ case 4:
+ ptr++;
+ get_operand (&ptr, operand + 0, 0);
+ if (*ptr == ',')
+ ptr++;
+ get_operand (&ptr, operand + 1, 1);
+ if (*ptr == ',')
+ ptr++;
+ get_operand (&ptr, operand + 2, 2);
+ if (*ptr == ',')
+ ptr++;
+ get_cc_operand (&ptr, operand + 3, 3);
+ break;
+
+ default:
+ abort ();
+ }
+
+ return ptr;
+}
+
+/* Passed a pointer to a list of opcodes which use different
+ addressing modes. Return the opcode which matches the opcodes
+ provided. */
+
+static opcode_entry_type *
+get_specific (opcode, operands)
+ opcode_entry_type *opcode;
+ op_type *operands;
+
+{
+ opcode_entry_type *this_try = opcode;
+ int found = 0;
+ unsigned int noperands = opcode->noperands;
+
+ int this_index = opcode->idx;
+
+ while (this_index == opcode->idx && !found)
+ {
+ unsigned int i;
+
+ this_try = opcode++;
+ for (i = 0; i < noperands; i++)
+ {
+ unsigned int mode = operands[i].mode;
+
+ if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK))
+ {
+ /* It could be an pc rel operand, if this is a da mode
+ and we like disps, then insert it. */
+
+ if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP)
+ {
+ /* This is the case. */
+ operands[i].mode = CLASS_DISP;
+ }
+ else if (mode == CLASS_BA && this_try->arg_info[i])
+ {
+ /* Can't think of a way to turn what we've been
+ given into something that's OK. */
+ goto fail;
+ }
+ else if (this_try->arg_info[i] & CLASS_PR)
+ {
+ if (mode == CLASS_REG_LONG && segmented_mode)
+ {
+ /* OK. */
+ }
+ else if (mode == CLASS_REG_WORD && !segmented_mode)
+ {
+ /* OK. */
+ }
+ else
+ goto fail;
+ }
+ else
+ goto fail;
+ }
+ switch (mode & CLASS_MASK)
+ {
+ default:
+ break;
+ case CLASS_X:
+ case CLASS_IR:
+ case CLASS_BA:
+ case CLASS_BX:
+ case CLASS_DISP:
+ case CLASS_REG:
+ case CLASS_REG_WORD:
+ case CLASS_REG_BYTE:
+ case CLASS_REG_QUAD:
+ case CLASS_REG_LONG:
+ case CLASS_REGN0:
+ reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
+ break;
+ }
+ }
+
+ found = 1;
+ fail:
+ ;
+ }
+ if (found)
+ return this_try;
+ else
+ return 0;
+}
+
+#if 0 /* Not used. */
+static void
+check_operand (operand, width, string)
+ struct z8k_op *operand;
+ unsigned int width;
+ char *string;
+{
+ if (operand->exp.X_add_symbol == 0
+ && operand->exp.X_op_symbol == 0)
+ {
+
+ /* No symbol involved, let's look at offset, it's dangerous if
+ any of the high bits are not 0 or ff's, find out by oring or
+ anding with the width and seeing if the answer is 0 or all
+ fs. */
+ if ((operand->exp.X_add_number & ~width) != 0 &&
+ (operand->exp.X_add_number | width) != (~0))
+ {
+ as_warn (_("operand %s0x%x out of range."),
+ string, operand->exp.X_add_number);
+ }
+ }
+
+}
+#endif
+
+static char buffer[20];
+
+static void
+newfix (ptr, type, operand)
+ int ptr;
+ int type;
+ expressionS *operand;
+{
+ if (operand->X_add_symbol
+ || operand->X_op_symbol
+ || operand->X_add_number)
+ {
+ fix_new_exp (frag_now,
+ ptr,
+ 1,
+ operand,
+ 0,
+ type);
+ }
+}
+
+static char *
+apply_fix (ptr, type, operand, size)
+ char *ptr;
+ int type;
+ expressionS *operand;
+ int size;
+{
+ int n = operand->X_add_number;
+
+ newfix ((ptr - buffer) / 2, type, operand);
+ switch (size)
+ {
+ case 8: /* 8 nibbles == 32 bits. */
+ *ptr++ = n >> 28;
+ *ptr++ = n >> 24;
+ *ptr++ = n >> 20;
+ *ptr++ = n >> 16;
+ case 4: /* 4 nibbles == 16 bits. */
+ *ptr++ = n >> 12;
+ *ptr++ = n >> 8;
+ case 2:
+ *ptr++ = n >> 4;
+ case 1:
+ *ptr++ = n >> 0;
+ break;
+ }
+ return ptr;
+}
+
+/* Now we know what sort of opcodes it is. Let's build the bytes. */
+
+#define INSERT(x,y) *x++ = y>>24; *x++ = y>> 16; *x++=y>>8; *x++ =y;
+
+static void
+build_bytes (this_try, operand)
+ opcode_entry_type *this_try;
+ struct z8k_op *operand ATTRIBUTE_UNUSED;
+{
+ char *output_ptr = buffer;
+ int c;
+ int nib;
+ int nibble;
+ unsigned int *class_ptr;
+
+ frag_wane (frag_now);
+ frag_new (0);
+
+ memset (buffer, 20, 0);
+ class_ptr = this_try->byte_info;
+
+ for (nibble = 0; (c = *class_ptr++); nibble++)
+ {
+
+ switch (c & CLASS_MASK)
+ {
+ default:
+ abort ();
+
+ case CLASS_ADDRESS:
+ /* Direct address, we don't cope with the SS mode right now. */
+ if (segmented_mode)
+ {
+ /* da_operand->X_add_number |= 0x80000000; -- Now set at relocation time. */
+ output_ptr = apply_fix (output_ptr, R_IMM32, da_operand, 8);
+ }
+ else
+ {
+ output_ptr = apply_fix (output_ptr, R_IMM16, da_operand, 4);
+ }
+ da_operand = 0;
+ break;
+ case CLASS_DISP8:
+ /* pc rel 8 bit */
+ output_ptr = apply_fix (output_ptr, R_JR, da_operand, 2);
+ da_operand = 0;
+ break;
+
+ case CLASS_0DISP7:
+ /* pc rel 7 bit */
+ *output_ptr = 0;
+ output_ptr = apply_fix (output_ptr, R_DISP7, da_operand, 2);
+ da_operand = 0;
+ break;
+
+ case CLASS_1DISP7:
+ /* pc rel 7 bit */
+ *output_ptr = 0x80;
+ output_ptr = apply_fix (output_ptr, R_DISP7, da_operand, 2);
+ output_ptr[-2] = 0x8;
+ da_operand = 0;
+ break;
+
+ case CLASS_BIT_1OR2:
+ *output_ptr = c & 0xf;
+ if (imm_operand)
+ {
+ if (imm_operand->X_add_number == 2)
+ *output_ptr |= 2;
+ else if (imm_operand->X_add_number != 1)
+ as_bad (_("immediate must be 1 or 2"));
+ }
+ else
+ as_bad (_("immediate 1 or 2 expected"));
+ output_ptr++;
+ break;
+ case CLASS_CC:
+ *output_ptr++ = the_cc;
+ break;
+ case CLASS_0CCC:
+ *output_ptr++ = the_ctrl;
+ break;
+ case CLASS_1CCC:
+ *output_ptr++ = the_ctrl | 0x8;
+ break;
+ case CLASS_00II:
+ *output_ptr++ = (~the_interrupt & 0x3);
+ break;
+ case CLASS_01II:
+ *output_ptr++ = (~the_interrupt & 0x3) | 0x4;
+ break;
+ case CLASS_FLAGS:
+ *output_ptr++ = the_flags;
+ break;
+ case CLASS_BIT:
+ *output_ptr++ = c & 0xf;
+ break;
+ case CLASS_REGN0:
+ if (reg[c & 0xf] == 0)
+ as_bad (_("can't use R0 here"));
+ /* Fall through. */
+ case CLASS_REG:
+ case CLASS_REG_BYTE:
+ case CLASS_REG_WORD:
+ case CLASS_REG_LONG:
+ case CLASS_REG_QUAD:
+ /* Insert bit mattern of right reg. */
+ *output_ptr++ = reg[c & 0xf];
+ break;
+ case CLASS_DISP:
+ switch (c & ARG_MASK)
+ {
+ case ARG_DISP12:
+ output_ptr = apply_fix (output_ptr, R_CALLR, da_operand, 4);
+ break;
+ case ARG_DISP16:
+ output_ptr = apply_fix (output_ptr, R_REL16, da_operand, 4);
+ break;
+ default:
+ output_ptr = apply_fix (output_ptr, R_IMM16, da_operand, 4);
+ }
+ da_operand = 0;
+ break;
+
+ case CLASS_IMM:
+ {
+ nib = 0;
+ switch (c & ARG_MASK)
+ {
+ case ARG_IMM4:
+ output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
+ break;
+ case ARG_IMM4M1:
+ imm_operand->X_add_number--;
+ output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
+ break;
+ case ARG_IMMNMINUS1:
+ imm_operand->X_add_number--;
+ output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
+ break;
+ case ARG_NIM8:
+ imm_operand->X_add_number = -imm_operand->X_add_number;
+ case ARG_IMM8:
+ output_ptr = apply_fix (output_ptr, R_IMM8, imm_operand, 2);
+ break;
+ case ARG_IMM16:
+ output_ptr = apply_fix (output_ptr, R_IMM16, imm_operand, 4);
+ break;
+
+ case ARG_IMM32:
+ output_ptr = apply_fix (output_ptr, R_IMM32, imm_operand, 8);
+ break;
+
+ default:
+ abort ();
+ }
+ }
+ }
+ }
+
+ /* Copy from the nibble buffer into the frag. */
+ {
+ int length = (output_ptr - buffer) / 2;
+ char *src = buffer;
+ char *fragp = frag_more (length);
+
+ while (src < output_ptr)
+ {
+ *fragp = (src[0] << 4) | src[1];
+ src += 2;
+ fragp++;
+ }
+ }
+}
+
+/* This is the guts of the machine-dependent assembler. STR points to a
+ machine dependent instruction. This function is supposed to emit
+ the frags/bytes it assembles to. */
+
+void
+md_assemble (str)
+ char *str;
+{
+ char c;
+ char *op_start;
+ char *op_end;
+ struct z8k_op operand[3];
+ opcode_entry_type *opcode;
+ opcode_entry_type *prev_opcode;
+
+ /* Drop leading whitespace. */
+ while (*str == ' ')
+ str++;
+
+ /* Find the op code end. */
+ for (op_start = op_end = str;
+ *op_end != 0 && *op_end != ' ';
+ op_end++)
+ ;
+
+ if (op_end == op_start)
+ {
+ as_bad (_("can't find opcode "));
+ }
+ c = *op_end;
+
+ *op_end = 0;
+
+ opcode = (opcode_entry_type *) hash_find (opcode_hash_control, op_start);
+
+ if (opcode == NULL)
+ {
+ as_bad (_("unknown opcode"));
+ return;
+ }
+
+ if (opcode->opcode == 250)
+ {
+ /* Was really a pseudo op. */
+
+ pseudo_typeS *p;
+ char oc;
+
+ char *old = input_line_pointer;
+ *op_end = c;
+
+ input_line_pointer = op_end;
+
+ oc = *old;
+ *old = '\n';
+ while (*input_line_pointer == ' ')
+ input_line_pointer++;
+ p = (pseudo_typeS *) (opcode->func);
+
+ (p->poc_handler) (p->poc_val);
+ input_line_pointer = old;
+ *old = oc;
+ }
+ else
+ {
+ input_line_pointer = get_operands (opcode, op_end, operand);
+ prev_opcode = opcode;
+
+ opcode = get_specific (opcode, operand);
+
+ if (opcode == 0)
+ {
+ /* Couldn't find an opcode which matched the operands. */
+ char *where = frag_more (2);
+
+ where[0] = 0x0;
+ where[1] = 0x0;
+
+ as_bad (_("Can't find opcode to match operands"));
+ return;
+ }
+
+ build_bytes (opcode, operand);
+ }
+}
+
+void
+tc_crawl_symbol_chain (headers)
+ object_headers *headers ATTRIBUTE_UNUSED;
+{
+ printf (_("call to tc_crawl_symbol_chain \n"));
+}
+
+symbolS *
+md_undefined_symbol (name)
+ char *name ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
+
+void
+tc_headers_hook (headers)
+ object_headers *headers ATTRIBUTE_UNUSED;
+{
+ printf (_("call to tc_headers_hook \n"));
+}
+
+/* Various routines to kill one day. */
+/* Equal to MAX_PRECISION in atof-ieee.c. */
+#define MAX_LITTLENUMS 6
+
+/* Turn a string in input_line_pointer into a floating point constant
+ of type TYPE, and store the appropriate bytes in *LITP. The number
+ of LITTLENUMS emitted is stored in *SIZEP. An error message is
+ returned, or NULL on OK. */
+
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+ char *atof_ieee ();
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to MD_ATOF()");
+ }
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+ for (wordP = words; prec--;)
+ {
+ md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ return 0;
+}
+
+CONST char *md_shortopts = "z:";
+
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+
+size_t md_longopts_size = sizeof (md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case 'z':
+ if (!strcmp (arg, "8001"))
+ s_segm ();
+ else if (!strcmp (arg, "8002"))
+ s_unseg ();
+ else
+ {
+ as_bad (_("invalid architecture -z%s"), arg);
+ return 0;
+ }
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf (stream, _("\
+Z8K options:\n\
+-z8001 generate segmented code\n\
+-z8002 generate unsegmented code\n"));
+}
+
+void
+tc_aout_fix_to_chars ()
+{
+ printf (_("call to tc_aout_fix_to_chars \n"));
+ abort ();
+}
+
+void
+md_convert_frag (headers, seg, fragP)
+ object_headers *headers ATTRIBUTE_UNUSED;
+ segT seg ATTRIBUTE_UNUSED;
+ fragS *fragP ATTRIBUTE_UNUSED;
+{
+ printf (_("call to md_convert_frag \n"));
+ abort ();
+}
+
+valueT
+md_section_align (seg, size)
+ segT seg;
+ valueT size;
+{
+ return ((size + (1 << section_alignment[(int) seg]) - 1)
+ & (-1 << section_alignment[(int) seg]));
+
+}
+
+void
+md_apply_fix3 (fixP, valP, segment)
+ fixS *fixP;
+ valueT * valP;
+ segT segment ATTRIBUTE_UNUSED;
+{
+ long val = * (long *) valP;
+ char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+
+ switch (fixP->fx_r_type)
+ {
+ case R_IMM4L:
+ buf[0] = (buf[0] & 0xf0) | ((buf[0] + val) & 0xf);
+ break;
+
+ case R_JR:
+
+ *buf++ = val;
+#if 0
+ if (val != 0)
+ abort ();
+#endif
+ break;
+
+ case R_DISP7:
+
+ *buf++ += val;
+#if 0
+ if (val != 0)
+ abort ();
+#endif
+ break;
+
+ case R_IMM8:
+ buf[0] += val;
+ break;
+ case R_IMM16:
+ *buf++ = (val >> 8);
+ *buf++ = val;
+ break;
+ case R_IMM32:
+ *buf++ = (val >> 24);
+ *buf++ = (val >> 16);
+ *buf++ = (val >> 8);
+ *buf++ = val;
+ break;
+#if 0
+ case R_DA | R_SEG:
+ *buf++ = (val >> 16);
+ *buf++ = 0x00;
+ *buf++ = (val >> 8);
+ *buf++ = val;
+ break;
+#endif
+
+ case 0:
+ md_number_to_chars (buf, val, fixP->fx_size);
+ break;
+
+ default:
+ abort ();
+ }
+
+ if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
+ fixP->fx_done = 1;
+}
+
+int
+md_estimate_size_before_relax (fragP, segment_type)
+ register fragS *fragP ATTRIBUTE_UNUSED;
+ register segT segment_type ATTRIBUTE_UNUSED;
+{
+ printf (_("call tomd_estimate_size_before_relax \n"));
+ abort ();
+}
+
+/* Put number into target byte order. */
+
+void
+md_number_to_chars (ptr, use, nbytes)
+ char *ptr;
+ valueT use;
+ int nbytes;
+{
+ number_to_chars_bigendian (ptr, use, nbytes);
+}
+
+long
+md_pcrel_from (fixP)
+ fixS *fixP ATTRIBUTE_UNUSED;
+{
+ abort ();
+}
+
+void
+tc_coff_symbol_emit_hook (s)
+ symbolS *s ATTRIBUTE_UNUSED;
+{
+}
+
+void
+tc_reloc_mangle (fix_ptr, intr, base)
+ fixS *fix_ptr;
+ struct internal_reloc *intr;
+ bfd_vma base;
+
+{
+ symbolS *symbol_ptr;
+
+ if (fix_ptr->fx_addsy
+ && fix_ptr->fx_subsy)
+ {
+ symbolS *add = fix_ptr->fx_addsy;
+ symbolS *sub = fix_ptr->fx_subsy;
+
+ if (S_GET_SEGMENT (add) != S_GET_SEGMENT (sub))
+ as_bad (_("Can't subtract symbols in different sections %s %s"),
+ S_GET_NAME (add), S_GET_NAME (sub));
+ else
+ {
+ int diff = S_GET_VALUE (add) - S_GET_VALUE (sub);
+
+ fix_ptr->fx_addsy = 0;
+ fix_ptr->fx_subsy = 0;
+ fix_ptr->fx_offset += diff;
+ }
+ }
+ symbol_ptr = fix_ptr->fx_addsy;
+
+ /* If this relocation is attached to a symbol then it's ok
+ to output it. */
+ if (fix_ptr->fx_r_type == 0)
+ {
+ /* cons likes to create reloc32's whatever the size of the reloc. */
+ switch (fix_ptr->fx_size)
+ {
+ case 2:
+ intr->r_type = R_IMM16;
+ break;
+ case 1:
+ intr->r_type = R_IMM8;
+ break;
+ case 4:
+ intr->r_type = R_IMM32;
+ break;
+ default:
+ abort ();
+ }
+ }
+ else
+ intr->r_type = fix_ptr->fx_r_type;
+
+ intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
+ intr->r_offset = fix_ptr->fx_offset;
+
+ if (symbol_ptr)
+ intr->r_symndx = symbol_ptr->sy_number;
+ else
+ intr->r_symndx = -1;
+}
diff --git a/x/binutils/gas/config/tc-z8k.h b/x/binutils/gas/config/tc-z8k.h
new file mode 100644
index 0000000..d1899e1
--- /dev/null
+++ b/x/binutils/gas/config/tc-z8k.h
@@ -0,0 +1,53 @@
+/* This file is tc-z8k.h
+ Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1995, 1997, 1998,
+ 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_Z8K
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#if ANSI_PROTOTYPES
+struct internal_reloc;
+#endif
+
+#define WORKING_DOT_WORD
+
+#ifndef BFD_ASSEMBLER
+#define LOCAL_LABEL(x) 0
+#endif
+
+/* This macro translates between an internal fix and an coff reloc type */
+#define TC_COFF_FIX2RTYPE(fixP) abort ();
+
+#define BFD_ARCH bfd_arch_z8k
+#define COFF_MAGIC 0x8000
+#define TC_COUNT_RELOC(x) (1)
+#define IGNORE_NONSTANDARD_ESCAPES
+
+#define TC_RELOC_MANGLE(s,a,b,c) tc_reloc_mangle(a,b,c)
+extern void tc_reloc_mangle
+ PARAMS ((struct fix *, struct internal_reloc *, bfd_vma));
+
+#define DO_NOT_STRIP 0
+#define LISTING_HEADER "Zilog Z8000 GAS "
+#define NEED_FX_R_TYPE 1
+#define RELOC_32 1234
+
+#define md_operand(x)
diff --git a/x/binutils/gas/config/te-386bsd.h b/x/binutils/gas/config/te-386bsd.h
new file mode 100644
index 0000000..da2d692
--- /dev/null
+++ b/x/binutils/gas/config/te-386bsd.h
@@ -0,0 +1,33 @@
+/* te-386bsd.h -- 386BSD target environment declarations.
+ Copyright 1987, 1990, 1991, 1992, 1993, 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TE_386BSD 1
+
+#include "obj-format.h"
+
+/*
+ * Local Variables:
+ * comment-column: 0
+ * fill-column: 131
+ * End:
+ */
+
+/* end of te-386bsd.h */
diff --git a/x/binutils/gas/config/te-aux.h b/x/binutils/gas/config/te-aux.h
new file mode 100644
index 0000000..38445d9
--- /dev/null
+++ b/x/binutils/gas/config/te-aux.h
@@ -0,0 +1,17 @@
+#define TE_AUX
+
+/* From obj-coff.h:
+ This internal_lineno crap is to stop namespace pollution from the
+ bfd internal coff headerfile. */
+#define internal_lineno bfd_internal_lineno
+#include "coff/aux-coff.h" /* override bits in coff/internal.h */
+#undef internal_lineno
+
+#define COFF_NOLOAD_PROBLEM
+#define KEEP_RELOC_INFO
+
+#include "obj-format.h"
+
+#ifndef LOCAL_LABELS_FB
+#define LOCAL_LABELS_FB 1
+#endif
diff --git a/x/binutils/gas/config/te-freebsd.h b/x/binutils/gas/config/te-freebsd.h
new file mode 100644
index 0000000..6992561
--- /dev/null
+++ b/x/binutils/gas/config/te-freebsd.h
@@ -0,0 +1,30 @@
+/* te-freebsd.h -- FreeBSD target environment declarations.
+ Copyright 2000 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Target environment for FreeBSD. It is the same as the generic
+ target, except that it arranges via the TE_FreeBSD define to
+ suppress the use of "/" as a comment character. Some code in the
+ FreeBSD kernel uses "/" to mean division. (What a concept!) */
+#define TE_FreeBSD 1
+
+#define LOCAL_LABELS_DOLLAR 1
+#define LOCAL_LABELS_FB 1
+
+#include "obj-format.h"
diff --git a/x/binutils/gas/config/te-generic.h b/x/binutils/gas/config/te-generic.h
new file mode 100644
index 0000000..400a576
--- /dev/null
+++ b/x/binutils/gas/config/te-generic.h
@@ -0,0 +1,22 @@
+/*
+ * This file is te-generic.h and is intended to be a template for
+ * target environment specific header files.
+ *
+ * It is my intent that this file will evolve into a file suitable for config,
+ * compile, and copying as an aid for testing and porting. xoxorich.
+ */
+
+/* Added these, because if we don't know what we're targeting we may
+ need an assembler version of libgcc, and that will use local
+ labels. */
+#define LOCAL_LABELS_DOLLAR 1
+#define LOCAL_LABELS_FB 1
+
+/* these define interfaces */
+#ifdef OBJ_HEADER
+#include OBJ_HEADER
+#else
+#include "obj-format.h"
+#endif
+
+/* end of te-generic.h */
diff --git a/x/binutils/gas/config/te-linux.h b/x/binutils/gas/config/te-linux.h
new file mode 100644
index 0000000..c235a7a
--- /dev/null
+++ b/x/binutils/gas/config/te-linux.h
@@ -0,0 +1,4 @@
+#define TE_LINUX
+#define LOCAL_LABELS_FB 1
+
+#include "obj-format.h"
diff --git a/x/binutils/gas/config/te-multi.h b/x/binutils/gas/config/te-multi.h
new file mode 100644
index 0000000..b8eda45
--- /dev/null
+++ b/x/binutils/gas/config/te-multi.h
@@ -0,0 +1,22 @@
+/*
+ * This file is te-generic.h and is intended to be a template for
+ * target environment specific header files.
+ *
+ * It is my intent that this file will evolve into a file suitable for config,
+ * compile, and copying as an aid for testing and porting. xoxorich.
+ */
+
+/* Added these, because if we don't know what we're targetting we may
+ need an assembler version of libgcc, and that will use local
+ labels. */
+#define LOCAL_LABELS_DOLLAR 1
+#define LOCAL_LABELS_FB 1
+
+/* these define interfaces */
+#ifdef OBJ_HEADER
+#include OBJ_HEADER
+#else
+#include "obj-format.h"
+#endif
+
+/* end of te-generic.h */
diff --git a/x/binutils/gas/config/te-nbsd.h b/x/binutils/gas/config/te-nbsd.h
new file mode 100644
index 0000000..cb8dc09
--- /dev/null
+++ b/x/binutils/gas/config/te-nbsd.h
@@ -0,0 +1,24 @@
+/* te-nbsd.h -- NetBSD target environment declarations.
+ Copyright 1987, 1990, 1991, 1992, 1994, 1998, 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TE_NetBSD 1
+#define LOCAL_LABELS_FB 1
+#include "obj-format.h"
diff --git a/x/binutils/gas/config/te-pe.h b/x/binutils/gas/config/te-pe.h
new file mode 100644
index 0000000..b3e0764
--- /dev/null
+++ b/x/binutils/gas/config/te-pe.h
@@ -0,0 +1,7 @@
+#define TE_PE
+#define LEX_AT (LEX_BEGIN_NAME | LEX_NAME) /* Can have @'s inside labels. */
+
+/* The PE format supports long section names. */
+#define COFF_LONG_SECTION_NAMES
+
+#include "obj-format.h"
diff --git a/x/binutils/gas/config/te-ppcnw.h b/x/binutils/gas/config/te-ppcnw.h
new file mode 100644
index 0000000..1337591
--- /dev/null
+++ b/x/binutils/gas/config/te-ppcnw.h
@@ -0,0 +1,32 @@
+/* te-ppcnw.h -- Power PC running Netware environment declarations.
+ Copyright 1994, 1995, 2000 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Added these, because if we don't know what we're targeting we may
+ need an assembler version of libgcc, and that will use local
+ labels. */
+#define LOCAL_LABELS_DOLLAR 1
+#define LOCAL_LABELS_FB 1
+
+/* these define interfaces */
+#include "obj-format.h"
+
+/* gcc uses escape sequences for ppc/netware. */
+
+#undef NO_STRING_ESCAPES
diff --git a/x/binutils/gas/config/te-sparcaout.h b/x/binutils/gas/config/te-sparcaout.h
new file mode 100644
index 0000000..edd3766
--- /dev/null
+++ b/x/binutils/gas/config/te-sparcaout.h
@@ -0,0 +1,22 @@
+/* te-sparcaout.h -- embedded sparc-aout target environment declarations.
+ Copyright 1996, 2000 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TE_SPARCAOUT 1
+#include "obj-format.h"
diff --git a/x/binutils/gas/config/te-svr4.h b/x/binutils/gas/config/te-svr4.h
new file mode 100644
index 0000000..7217ee1
--- /dev/null
+++ b/x/binutils/gas/config/te-svr4.h
@@ -0,0 +1,4 @@
+#define TE_SVR4
+#define LOCAL_LABELS_FB 1
+
+#include "obj-format.h"
diff --git a/x/binutils/gas/config/te-sysv32.h b/x/binutils/gas/config/te-sysv32.h
new file mode 100644
index 0000000..c60728a
--- /dev/null
+++ b/x/binutils/gas/config/te-sysv32.h
@@ -0,0 +1,6 @@
+/* Remove leading underscore from the gcc generated symbol names. */
+#define STRIP_UNDERSCORE
+
+#include "obj-format.h"
+
+/* end of te-sysv32.h */
diff --git a/x/binutils/gas/config/te-tmips.h b/x/binutils/gas/config/te-tmips.h
new file mode 100644
index 0000000..2fc6fd9
--- /dev/null
+++ b/x/binutils/gas/config/te-tmips.h
@@ -0,0 +1,40 @@
+/* Traditional MIPS targets
+ Copyright 2000 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file is te-tmips.h and is intended to provide support for
+ traditional mips targets like mips-dde-sysv4.2MP (Supermax ) ,
+ mips-sni-sysv4* (Sinix) etc. The base for this file is te-generic.h.
+ Created by Koundinya.K < kk@ddeorg.soft.net > with the help of
+ Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>. */
+
+/* Added these, because if we don't know what we're targeting we may
+ need an assembler version of libgcc, and that will use local
+ labels. */
+
+#define TE_TMIPS 1
+#define LOCAL_LABELS_DOLLAR 1
+#define LOCAL_LABELS_FB 1
+
+/* these define interfaces */
+#ifdef OBJ_HEADER
+#include OBJ_HEADER
+#else
+#include "obj-format.h"
+#endif
diff --git a/x/binutils/gas/configure b/x/binutils/gas/configure
new file mode 100755
index 0000000..e66abca
--- /dev/null
+++ b/x/binutils/gas/configure
@@ -0,0 +1,12362 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete. It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="as.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE LN_S RANLIB ac_ct_RANLIB LIBTOOL WARN_CFLAGS GDBINIT cgen_cpu_prefix extra_objects target_cpu_type obj_format te_file install_tooldir atof BFDLIB OPCODES_LIB BFDVER_H ALL_OBJ_DEPS YACC LEX LEXLIB LEX_OUTPUT_ROOT CPP EGREP ALLOCA USE_NLS MSGFMT GMSGFMT XGETTEXT USE_INCLUDED_LIBINTL CATALOGS CATOBJEXT DATADIRNAME GMOFILES INSTOBJEXT INTLDEPS INTLLIBS INTLOBJS POFILES POSUB INCLUDE_LOCALE_H GT_NO GT_YES MKINSTALLDIRS l MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LIBM LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_option in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval "enable_$ac_feature=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_$ac_feature='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_$ac_package='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/-/_/g'`
+ eval "with_$ac_package=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+ eval "$ac_envvar='$ac_optarg'"
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+ localstatedir libdir includedir oldincludedir infodir mandir
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+ { (exit 1); exit 1; }; }
+ else
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+ fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+ cat <<_ACEOF
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --infodir=DIR info documentation [PREFIX/info]
+ --mandir=DIR man documentation [PREFIX/man]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+ --target=TARGET configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors
+ --enable-shared=PKGS build shared libraries default=yes
+ --enable-static=PKGS build static libraries default=yes
+ --enable-fast-install=PKGS optimize for fast installation default=yes
+ --disable-libtool-lock avoid locking (might break parallel builds)
+ --enable-bfd-assembler use BFD back end for writing object files
+ targets alternative target configurations besides the primary
+ --enable-commonbfdlib build shared BFD/opcodes/libiberty library
+ --enable-build-warnings Enable build-time compiler warnings if gcc is used
+ --disable-nls do not use Native Language Support
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-gnu-ld assume the C compiler uses GNU ld default=no
+ --with-pic try to use only PIC/non-PIC objects default=use both
+ --with-included-gettext use the GNU gettext library included here
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
+ headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ ac_popdir=`pwd`
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d $ac_dir || continue
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+ cd $ac_dir
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_srcdir/configure.gnu; then
+ echo
+ $SHELL $ac_srcdir/configure.gnu --help=recursive
+ elif test -f $ac_srcdir/configure; then
+ echo
+ $SHELL $ac_srcdir/configure --help=recursive
+ elif test -f $ac_srcdir/configure.ac ||
+ test -f $ac_srcdir/configure.in; then
+ echo
+ $ac_configure --help
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi
+ cd "$ac_popdir"
+ done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+ cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+ # Get rid of the leading space.
+ ac_sep=" "
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+{
+ (set) 2>&1 |
+ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ sed -n \
+ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+ ;;
+ *)
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+}
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ sed "/^$/d" confdefs.h | sort
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core &&
+ rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+ ' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . $cache_file;;
+ *) . ./$cache_file;;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+ eval ac_new_val="\$ac_env_${ac_var}_value"
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in .. $srcdir/..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f $ac_dir/shtool; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in .. $srcdir/.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in .. $srcdir/.." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+ { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+ { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+ ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+ { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+ { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+ ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking target system type" >&5
+echo $ECHO_N "checking target system type... $ECHO_C" >&6
+if test "${ac_cv_target+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_target_alias=$target_alias
+test "x$ac_cv_target_alias" = "x" &&
+ ac_cv_target_alias=$ac_cv_host_alias
+ac_cv_target=`$ac_config_sub $ac_cv_target_alias` ||
+ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_target" >&5
+echo "${ECHO_T}$ac_cv_target" >&6
+target=$ac_cv_target
+target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_CC" && break
+done
+
+ CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+ "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+ (eval $ac_link_default) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Find the output, starting from the most likely. This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+ ;;
+ conftest.$ac_ext )
+ # This is the source file.
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ # FIXME: I believe we export ac_cv_exeext for Libtool,
+ # but it would be cool to find out if it's true. Does anybody
+ # maintain Libtool? --akim.
+ export ac_cv_exeext
+ break;;
+ * )
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ export ac_cv_exeext
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std1 is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std1. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C. Since we use `exit',
+# in C++ we need to declare it. In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+ choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ for ac_declaration in \
+ '' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
+fi
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for library containing strerror" >&5
+echo $ECHO_N "checking for library containing strerror... $ECHO_C" >&6
+if test "${ac_cv_search_strerror+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+ac_cv_search_strerror=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strerror ();
+int
+main ()
+{
+strerror ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_strerror="none required"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_strerror" = no; then
+ for ac_lib in cposix; do
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strerror ();
+int
+main ()
+{
+strerror ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_strerror="-l$ac_lib"
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_strerror" >&5
+echo "${ECHO_T}$ac_cv_search_strerror" >&6
+if test "$ac_cv_search_strerror" != no; then
+ test "$ac_cv_search_strerror" = "none required" || LIBS="$ac_cv_search_strerror $LIBS"
+
+fi
+
+
+BFD_VERSION=`sed -n -e 's/^.._INIT_AUTOMAKE.*,[ ]*\([^ ]*\)[ ]*).*/\1/p' < ${srcdir}/../bfd/configure.in`
+am__api_version="1.8"
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL=$ac_install_sh
+ fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&5
+echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,$program_prefix,;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$,$program_suffix,;$program_transform_name"
+# Double any \ or $. echo might interpret backslashes.
+# By default was `s,x,x', remove it if useless.
+cat <<\_ACEOF >conftest.sed
+s/[\\$]/&&/g;s/;s,x,x,$//
+_ACEOF
+program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
+rm conftest.sed
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+ # Keeping the `.' argument allows $(mkdir_p) to be used without
+ # argument. Indeed, we sometimes output rules like
+ # $(mkdir_p) $(somedir)
+ # where $(somedir) is conditionally defined.
+ # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more
+ # expensive solution, as it forces Make to start a sub-shell.)
+ mkdir_p='mkdir -p -- .'
+else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ for d in ./-p ./--version;
+ do
+ test -d $d && rmdir $d
+ done
+ # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+ if test -f "$ac_aux_dir/mkinstalldirs"; then
+ mkdir_p='$(mkinstalldirs)'
+ else
+ mkdir_p='$(install_sh) -d'
+ fi
+fi
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$AWK" && break
+done
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.make <<\_ACEOF
+all:
+ @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ SET_MAKE=
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+DEPDIR="${am__leading_dot}deps"
+
+ ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+
+
+echo "$as_me:$LINENO: result: $_am_result" >&5
+echo "${ECHO_T}$_am_result" >&6
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+ enableval="$enable_dependency_tracking"
+
+fi;
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+
+
+if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+ test -f $srcdir/config.status; then
+ { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE=gas
+ VERSION=${BFD_VERSION}
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_STRIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ STRIP=$ac_ct_STRIP
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+
+
+depcc="$CC" am_compiler_list=
+
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+
+
+if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=yes
+fi;
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi;
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval="$enable_fast_install"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_fast_install=yes
+fi;
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi;
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo "$as_me:$LINENO: checking for ld used by GCC" >&5
+echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
+else
+ echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
+fi
+if test "${lt_cv_path_LD+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+ { (exit 1); exit 1; }; }
+echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+if test "${lt_cv_prog_gnu_ld+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ lt_cv_prog_gnu_ld=yes
+else
+ lt_cv_prog_gnu_ld=no
+fi
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
+echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6
+if test "${lt_cv_ld_reload_flag+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
+echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6
+reload_flag=$lt_cv_ld_reload_flag
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
+echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6
+if test "${lt_cv_path_NM+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/${ac_tool_prefix}nm
+ if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ else
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi
+fi
+
+NM="$lt_cv_path_NM"
+echo "$as_me:$LINENO: result: $NM" >&5
+echo "${ECHO_T}$NM" >&6
+
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+ echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+echo "$as_me:$LINENO: checking how to recognise dependant libraries" >&5
+echo $ECHO_N "checking how to recognise dependant libraries... $ECHO_C" >&6
+if test "${lt_cv_deplibs_check_method+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi4*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin* | mingw* |pw32*)
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ case "$host_os" in
+ rhapsody* | darwin1.012)
+ lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System'
+ ;;
+ *) # Darwin 1.3 on
+ lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
+ ;;
+ esac
+ ;;
+
+freebsd* )
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20*|hpux11*)
+ case $host_cpu in
+ hppa*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ esac
+ ;;
+
+irix5* | irix6*)
+ case $host_os in
+ irix5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"
+ ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ case $host_cpu in
+ alpha* | mips* | hppa* | i*86 | powerpc* | sparc* | ia64* )
+ lt_cv_deplibs_check_method=pass_all ;;
+ *)
+ # glibc up to 2.1.1 does not perform some relocations on ARM
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'
+ fi
+ ;;
+
+newsos6)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+osf3* | osf4* | osf5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sco3.2v5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+
+sysv5uw[78]* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ case $host_vendor in
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ esac
+ ;;
+esac
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
+echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+
+
+
+
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
+echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $MAGIC_CMD in
+ /*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ ac_save_MAGIC_CMD="$MAGIC_CMD"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="/usr/bin:$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ MAGIC_CMD="$ac_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ echo "$as_me:$LINENO: checking for file" >&5
+echo $ECHO_N "checking for file... $ECHO_C" >&6
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $MAGIC_CMD in
+ /*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ ac_save_MAGIC_CMD="$MAGIC_CMD"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="/usr/bin:$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ MAGIC_CMD="$ac_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ RANLIB=$ac_ct_RANLIB
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_STRIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ STRIP=$ac_ct_STRIP
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval="$enable_libtool_lock"
+
+fi;
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+
+# Check whether --with-pic or --without-pic was given.
+if test "${with_pic+set}" = set; then
+ withval="$with_pic"
+ pic_mode="$withval"
+else
+ pic_mode=default
+fi;
+test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic"
+test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 3794 "configure"' > conftest.$ac_ext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ case "`/usr/bin/file conftest.o`" in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
+echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6
+if test "${lt_cv_cc_needs_belf+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ lt_cv_cc_needs_belf=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+lt_cv_cc_needs_belf=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
+echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+
+esac
+
+
+# Save cache, so that ltconfig can load it
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+ (set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+} |
+ sed '
+ t clear
+ : clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+AR="$AR" LTCC="$CC" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \
+AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \
+objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \
+deplibs_check_method="$deplibs_check_method" file_magic_cmd="$file_magic_cmd" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \
+|| { { echo "$as_me:$LINENO: error: libtool configure failed" >&5
+echo "$as_me: error: libtool configure failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . $cache_file;;
+ *) . ./$cache_file;;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh $ac_aux_dir/ltcf-c.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+
+
+
+
+
+user_bfd_gas=
+# Check whether --enable-bfd-assembler or --disable-bfd-assembler was given.
+if test "${enable_bfd_assembler+set}" = set; then
+ enableval="$enable_bfd_assembler"
+ case "${enableval}" in
+ yes) need_bfd=yes user_bfd_gas=yes ;;
+ no) user_bfd_gas=no ;;
+ *) { { echo "$as_me:$LINENO: error: bad value ${enableval} given for bfd-assembler option" >&5
+echo "$as_me: error: bad value ${enableval} given for bfd-assembler option" >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+fi; # Check whether --enable-targets or --disable-targets was given.
+if test "${enable_targets+set}" = set; then
+ enableval="$enable_targets"
+ case "${enableval}" in
+ yes | "") { { echo "$as_me:$LINENO: error: enable-targets option must specify target names or 'all'" >&5
+echo "$as_me: error: enable-targets option must specify target names or 'all'" >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ no) enable_targets= ;;
+ *) enable_targets=$enableval ;;
+esac
+fi; # Check whether --enable-commonbfdlib or --disable-commonbfdlib was given.
+if test "${enable_commonbfdlib+set}" = set; then
+ enableval="$enable_commonbfdlib"
+ case "${enableval}" in
+ yes) commonbfdlib=true ;;
+ no) commonbfdlib=false ;;
+ *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for BFD commonbfdlib option" >&5
+echo "$as_me: error: bad value ${enableval} for BFD commonbfdlib option" >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+fi;
+using_cgen=no
+
+build_warnings="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
+# Check whether --enable-build-warnings or --disable-build-warnings was given.
+if test "${enable_build_warnings+set}" = set; then
+ enableval="$enable_build_warnings"
+ case "${enableval}" in
+ yes) ;;
+ no) build_warnings="-w";;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${build_warnings} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${t} ${build_warnings}";;
+ *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then
+ echo "Setting warning flags = $build_warnings" 6>&1
+fi
+fi; WARN_CFLAGS=""
+if test "x${build_warnings}" != x -a "x$GCC" = xyes ; then
+ WARN_CFLAGS="${build_warnings}"
+fi
+
+
+# Generate a header file
+ ac_config_headers="$ac_config_headers config.h:config.in"
+
+
+# If we are on a DOS filesystem, we must use gdb.ini rather than
+# .gdbinit.
+case "${host}" in
+ *-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-windows*)
+ GDBINIT="gdb.ini"
+ ac_config_files="$ac_config_files gdb.ini:gdbinit.in"
+
+ ;;
+ *)
+ GDBINIT=".gdbinit"
+ ac_config_files="$ac_config_files .gdbinit:gdbinit.in"
+
+ ;;
+esac
+
+
+te_file=generic
+
+# Makefile target for installing gas in $(tooldir)/bin.
+install_tooldir=install-exec-tooldir
+
+canon_targets=""
+all_targets=no
+if test -n "$enable_targets" ; then
+ for t in `echo $enable_targets | sed 's/,/ /g'`; do
+ if test $t = "all"; then
+ all_targets=yes
+ continue
+ fi
+ result=`$ac_config_sub $t 2>/dev/null`
+ if test -n "$result" ; then
+ canon_targets="$canon_targets $result"
+# else
+# # Permit "all", etc. We don't support it yet though.
+# canon_targets="$canon_targets $t"
+ fi
+ done
+ _gas_uniq_list="$canon_targets"
+_gas_uniq_newlist=""
+for _gas_uniq_i in _gas_uniq_dummy $_gas_uniq_list ; do
+ case $_gas_uniq_i in
+ _gas_uniq_dummy) ;;
+ *) case " $_gas_uniq_newlist " in
+ *" $_gas_uniq_i "*) ;;
+ *) _gas_uniq_newlist="$_gas_uniq_newlist $_gas_uniq_i" ;;
+ esac ;;
+ esac
+done
+canon_targets=$_gas_uniq_newlist
+
+fi
+
+emulations=""
+
+for this_target in $target $canon_targets ; do
+
+ eval `echo $this_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/cpu=\1 vendor=\2 os=\3/'`
+
+ # check for architecture variants
+ arch=
+ endian=
+ case ${cpu} in
+ am33_2.0) cpu_type=mn10300 endian=little ;;
+ alpha*) cpu_type=alpha ;;
+ arm*b|xscale*b|strongarm*b) cpu_type=arm endian=big ;;
+ arm*|xscale*|strongarm*) cpu_type=arm endian=little ;;
+ c4x*) cpu_type=tic4x ;;
+ hppa*) cpu_type=hppa ;;
+ i[3-7]86) cpu_type=i386 arch=i386;;
+ x86_64) cpu_type=i386 arch=x86_64;;
+ ia64) cpu_type=ia64 ;;
+ ip2k) cpu_type=ip2k endian=big ;;
+ iq2000) cpu_type=iq2000 endian=big ;;
+ m6811|m6812|m68hc12) cpu_type=m68hc11 ;;
+ m680[012346]0) cpu_type=m68k ;;
+ m68008) cpu_type=m68k ;;
+ m683??) cpu_type=m68k ;;
+ m5200) cpu_type=m68k ;;
+ m8*) cpu_type=m88k ;;
+ mips*el) cpu_type=mips endian=little ;;
+ mips*) cpu_type=mips endian=big ;;
+ or32*) cpu_type=or32 endian=big ;;
+ pjl*) cpu_type=pj endian=little ;;
+ pj*) cpu_type=pj endian=big ;;
+ powerpc*le*) cpu_type=ppc endian=little ;;
+ powerpc*) cpu_type=ppc endian=big ;;
+ rs6000*) cpu_type=ppc ;;
+ s390x*) cpu_type=s390 arch=s390x ;;
+ s390*) cpu_type=s390 arch=s390 ;;
+ sh5*) cpu_type=sh64 endian=big ;;
+ sh5le*) cpu_type=sh64 endian=little ;;
+ sh64*) cpu_type=sh64 endian=big ;;
+ sh64le*) cpu_type=sh64 endian=little ;;
+ sh*le) cpu_type=sh endian=little ;;
+ sh*) cpu_type=sh endian=big ;;
+ sparclite*) cpu_type=sparc arch=sparclite ;;
+ sparclet*) cpu_type=sparc arch=sparclet ;;
+ sparc64*) cpu_type=sparc arch=v9-64 ;;
+ sparc86x*) cpu_type=sparc arch=sparc86x ;;
+ sparc*) cpu_type=sparc arch=sparclite ;; # ??? See tc-sparc.c.
+ v850*) cpu_type=v850 ;;
+ xtensa*) cpu_type=xtensa arch=xtensa ;;
+ m32r) cpu_type=m32r target_cpu=m32r endian=big ;;
+ m32rle) cpu_type=m32r target_cpu=m32r endian=little ;;
+ *) cpu_type=${cpu} ;;
+ esac
+
+ if test ${this_target} = $target ; then
+ target_cpu_type=${cpu_type}
+ elif test ${target_cpu_type} != ${cpu_type} ; then
+ continue
+ fi
+
+ generic_target=${cpu_type}-$vendor-$os
+ dev=no
+ bfd_gas=no
+ em=generic
+
+ # assign object format
+ case ${generic_target} in
+ a29k-*-coff) fmt=coff ;;
+ a29k-amd-udi) fmt=coff ;;
+ a29k-amd-ebmon) fmt=coff ;;
+ a29k-nyu-sym1) fmt=coff ;;
+ a29k-*-rtems*) fmt=coff ;;
+ a29k-*-vxworks*) fmt=coff ;;
+
+ alpha*-*-*vms*) fmt=evax ;;
+ alpha*-*-netware*) fmt=ecoff ;;
+ alpha*-*-osf*) fmt=ecoff ;;
+ alpha*-*-linuxecoff*) fmt=ecoff ;;
+ alpha*-*-linux-gnu*) fmt=elf em=linux ;;
+ alpha*-*-netbsd*) fmt=elf em=nbsd ;;
+ alpha*-*-openbsd*) fmt=elf em=obsd ;;
+
+ # cpu_type for am33_2.0 is set to mn10300
+ mn10300-*-linux*) fmt=elf bfd_gas=yes em=linux ;;
+
+ arc-*-elf*) fmt=elf ;;
+
+ arm-*-aout) fmt=aout ;;
+ arm-*-coff | thumb-*-coff) fmt=coff ;;
+ arm-*-rtems* | thumb-*-rtems*) fmt=elf ;;
+ arm-*-elf | thumb-*-elf) fmt=elf ;;
+ arm-*-kaos*) fmt=elf ;;
+ arm*-*-conix*) fmt=elf ;;
+ arm-*-linux*aout*) fmt=aout em=linux ;;
+ arm*-*-linux-gnu*) fmt=elf em=linux ;;
+ arm*-*-uclinux*) fmt=elf em=linux ;;
+ arm-*-netbsdelf*) fmt=elf em=nbsd ;;
+ arm-*-*n*bsd*) fmt=aout em=nbsd ;;
+ arm-**-nto*) fmt=elf ;;
+ arm-*-oabi | thumb-*-oabi) fmt=elf ;;
+ arm-epoc-pe | thumb-epoc-pe) fmt=coff em=epoc-pe ;;
+ arm-wince-pe | arm-*-wince) fmt=coff em=wince-pe ;;
+ arm-*-pe | thumb-*-pe) fmt=coff em=pe ;;
+ arm-*-riscix*) fmt=aout em=riscix ;;
+
+ avr-*-*) fmt=elf ;;
+
+ cris-*-linux-gnu*) fmt=multi bfd_gas=yes em=linux ;;
+ cris-*-*) fmt=multi bfd_gas=yes ;;
+
+ d10v-*-*) fmt=elf ;;
+ d30v-*-*) fmt=elf ;;
+ dlx-*-*) fmt=elf ;;
+
+ fr30-*-*) fmt=elf ;;
+ frv-*-*linux*) fmt=elf em=linux;;
+ frv-*-*) fmt=elf ;;
+
+ hppa-*-linux*) case ${cpu} in
+ hppa*64*) fmt=elf em=hppalinux64;;
+ hppa*) fmt=elf em=linux;;
+ esac ;;
+ hppa-*-*elf*) fmt=elf em=hppa ;;
+ hppa-*-lites*) fmt=elf em=hppa ;;
+ hppa-*-netbsd*) fmt=elf em=nbsd ;;
+ hppa-*-openbsd*) fmt=elf em=hppa ;;
+ hppa-*-osf*) fmt=som em=hppa ;;
+ hppa-*-rtems*) fmt=elf em=hppa ;;
+ hppa-*-hpux11*) case ${cpu} in
+ hppa*64*) fmt=elf em=hppa64 ;;
+ hppa*) fmt=som em=hppa ;;
+ esac ;;
+ hppa-*-hpux*) fmt=som em=hppa ;;
+ hppa-*-mpeix*) fmt=som em=hppa ;;
+ hppa-*-bsd*) fmt=som em=hppa ;;
+ hppa-*-hiux*) fmt=som em=hppa ;;
+
+ h8300-*-rtems*) fmt=coff ;;
+ h8300-*-coff) fmt=coff ;;
+ h8300-*-elf) fmt=elf ;;
+ h8500-*-rtems*) fmt=coff ;;
+ h8500-*-coff) fmt=coff ;;
+
+ i370-*-elf* | i370-*-linux*) fmt=elf ;;
+ i386-ibm-aix*) fmt=coff em=i386aix ;;
+ i386-sequent-bsd*) fmt=aout em=dynix ;;
+ i386-*-beospe*) fmt=coff em=pe ;;
+ i386-*-beos*) fmt=elf ;;
+ i386-*-coff) fmt=coff ;;
+ i386-*-elf) fmt=elf ;;
+ i386-*-kaos*) fmt=elf ;;
+ i386-*-bsd*) fmt=aout em=386bsd ;;
+ i386-*-netbsd0.8) fmt=aout em=386bsd ;;
+ i386-*-netbsdpe*) fmt=coff em=pe ;;
+ i386-*-netbsd*-gnu* | \
+ i386-*-knetbsd*-gnu | \
+ i386-*-netbsdelf*) fmt=elf em=nbsd ;;
+ i386-*-*n*bsd*) case ${cpu} in
+ x86_64) fmt=elf em=nbsd ;;
+ *) fmt=aout em=nbsd ;;
+ esac ;;
+ i386-*-linux*aout*) fmt=aout em=linux ;;
+ i386-*-linux*oldld) fmt=aout em=linux ;;
+ i386-*-linux*coff*) fmt=coff em=linux ;;
+ i386-*-linux-gnu*) fmt=elf em=linux ;;
+ x86_64-*-linux-gnu*) fmt=elf em=linux ;;
+ i386-*-lynxos*) fmt=coff em=lynx ;;
+ i386-*-sysv[45]*) fmt=elf ;;
+ i386-*-solaris*) fmt=elf ;;
+ i386-*-freebsdaout*) fmt=aout em=386bsd ;;
+ i386-*-freebsd[12].*) fmt=aout em=386bsd ;;
+ i386-*-freebsd[12]) fmt=aout em=386bsd ;;
+ i386-*-freebsd* | i386-*-kfreebsd*-gnu)
+ fmt=elf em=freebsd ;;
+ i386-*-sysv*) fmt=coff ;;
+ i386-*-sco3.2v5*coff) fmt=coff ;;
+ i386-*-isc*) fmt=coff ;;
+ i386-*-sco3.2v5*) fmt=elf
+ if test ${this_target} = $target; then
+
+cat >>confdefs.h <<\_ACEOF
+#define SCO_ELF 1
+_ACEOF
+
+ fi ;;
+ i386-*-sco3.2*) fmt=coff ;;
+ i386-*-vsta) fmt=aout ;;
+ i386-*-msdosdjgpp* \
+ | i386-*-go32* \
+ | i386-go32-rtems*) fmt=coff em=go32
+
+cat >>confdefs.h <<\_ACEOF
+#define STRICTCOFF 1
+_ACEOF
+ ;;
+ i386-*-rtemself*) fmt=elf ;;
+ i386-*-rtemscoff*) fmt=coff ;;
+ i386-*-rtems*) fmt=elf ;;
+ i386-*-gnu*) fmt=elf ;;
+ i386-*-mach*) fmt=aout em=mach ;;
+ i386-*-msdos*) fmt=aout ;;
+ i386-*-moss*) fmt=elf ;;
+ i386-*-pe) fmt=coff em=pe ;;
+ i386-*-cygwin*) fmt=coff em=pe ;;
+ i386-*-interix*) fmt=coff em=interix ;;
+ i386-*-mingw32*) fmt=coff em=pe ;;
+ i386-*-nto-qnx*) fmt=elf ;;
+ i386-*-*nt*) fmt=coff em=pe ;;
+ i386-*-chaos) fmt=elf ;;
+
+ i860-*-*) fmt=elf endian=little
+ { echo "$as_me:$LINENO: WARNING: GAS support for ${generic_target} is preliminary and a work in progress" >&5
+echo "$as_me: WARNING: GAS support for ${generic_target} is preliminary and a work in progress" >&2;} ;;
+ i960-*-bout) fmt=bout ;;
+ i960-*-coff) fmt=coff em=ic960 ;;
+ i960-*-rtems*) fmt=coff em=ic960 ;;
+ i960-*-nindy*) fmt=bout ;;
+ i960-*-vxworks5.0) fmt=bout ;;
+ i960-*-vxworks5.*) fmt=coff em=ic960 ;;
+ i960-*-vxworks*) fmt=bout ;;
+ i960-*-elf*) fmt=elf ;;
+
+ ia64-*-elf*) fmt=elf ;;
+ ia64-*-aix*) fmt=elf em=ia64aix ;;
+ ia64-*-linux-gnu*) fmt=elf em=linux ;;
+ ia64-*-hpux*) fmt=elf em=hpux ;;
+ ia64-*-netbsd*) fmt=elf em=nbsd ;;
+
+ ip2k-*-*) fmt=elf ;;
+
+ iq2000-*-elf) fmt=elf bfd_gas=yes ;;
+
+ m32r-*-elf*) fmt=elf ;;
+ m32r-*-linux*) fmt=elf em=linux;;
+
+ m68hc11-*-* | m6811-*-*) fmt=elf ;;
+ m68hc12-*-* | m6812-*-*) fmt=elf ;;
+
+ m68k-*-vxworks*) fmt=aout em=sun3 ;;
+ m68k-ericsson-ose) fmt=aout em=sun3 ;;
+ m68k-*-sunos*) fmt=aout em=sun3 ;;
+ m68k-motorola-sysv*) fmt=coff em=delta ;;
+ m68k-bull-sysv3*) fmt=coff em=dpx2 ;;
+ m68k-apollo-*) fmt=coff em=apollo ;;
+ m68k-*-elf*) fmt=elf ;;
+ m68k-*-sysv4*) fmt=elf em=svr4 ;;
+ m68k-*-sysv*) fmt=coff ;;
+ m68k-*-coff | m68k-*-rtemscoff*) fmt=coff ;;
+ m68k-*-rtems*) fmt=elf ;;
+ m68k-*-hpux*) fmt=hp300 em=hp300 ;;
+ m68k-*-linux*aout*) fmt=aout em=linux ;;
+ m68k-*-linux-gnu*) fmt=elf em=linux ;;
+ m68k-*-uclinux*) fmt=elf ;;
+ m68k-*-gnu*) fmt=elf ;;
+ m68k-*-lynxos*) fmt=coff em=lynx ;;
+ m68k-*-netbsdelf*) fmt=elf em=nbsd ;;
+ m68k-*-netbsd*) fmt=aout em=nbsd bfd_gas=yes ;;
+ m68k-*-openbsd*) fmt=aout em=nbsd bfd_gas=yes ;;
+ m68k-apple-aux*) fmt=coff em=aux ;;
+ m68k-*-psos*) fmt=elf em=psos;;
+
+ m88k-motorola-sysv3*) fmt=coff em=delt88 ;;
+ m88k-*-coff*) fmt=coff ;;
+
+ mcore-*-elf) fmt=elf ;;
+ mcore-*-pe) fmt=coff em=pe bfd_gas=yes ;;
+
+ # don't change em like *-*-bsd does
+ mips-dec-openbsd*) fmt=elf endian=little ;;
+ mips-sony-bsd*) fmt=ecoff ;;
+ mips-*-bsd*)
+ { { echo "$as_me:$LINENO: error: Unknown vendor for mips-bsd configuration." >&5
+echo "$as_me: error: Unknown vendor for mips-bsd configuration." >&2;}
+ { (exit 1); exit 1; }; } ;;
+ mips-*-ultrix*) fmt=ecoff endian=little ;;
+ mips-*-osf*) fmt=ecoff endian=little ;;
+ mips-*-ecoff*) fmt=ecoff ;;
+ mips-*-pe*) fmt=coff endian=little em=pe ;;
+ mips-*-irix6*) fmt=elf em=irix ;;
+ mips-*-irix5*) fmt=elf em=irix ;;
+ mips-*-irix*) fmt=ecoff em=irix ;;
+ mips-*-lnews*) fmt=ecoff em=lnews ;;
+ mips-*-riscos*) fmt=ecoff ;;
+ mips*-*-linux*) fmt=elf em=tmips ;;
+ mips-*-sysv4*MP* | mips-*-gnu*) fmt=elf em=tmips ;;
+ mips-*-sysv*) fmt=ecoff ;;
+ mips-*-elf* | mips-*-rtems*) fmt=elf ;;
+ mips-*-netbsd*) fmt=elf ;;
+ mips-*-openbsd*) fmt=elf ;;
+
+ mmix-*-*) fmt=elf ;;
+ mn10200-*-*) fmt=elf ;;
+ mn10300-*-*) fmt=elf ;;
+ msp430-*-*) fmt=elf ;;
+ openrisc-*-*) fmt=elf ;;
+ or32-*-rtems*) fmt=elf ;;
+ or32-*-coff) fmt=coff ;;
+ or32-*-elf) fmt=elf ;;
+ pj*) fmt=elf ;;
+
+ ppc-*-pe | ppc-*-cygwin*) fmt=coff em=pe ;;
+ ppc-*-winnt*) fmt=coff em=pe ;;
+ ppc-*-aix5.[01]) fmt=coff em=aix5 ;;
+ ppc-*-aix5.*) fmt=coff em=aix5
+
+cat >>confdefs.h <<\_ACEOF
+#define AIX_WEAK_SUPPORT 1
+_ACEOF
+
+ ;;
+ ppc-*-aix*) fmt=coff ;;
+ ppc-*-beos*) fmt=coff ;;
+ ppc-*-*n*bsd* | ppc-*-elf*) fmt=elf ;;
+ ppc-*-eabi* | ppc-*-sysv4*) fmt=elf ;;
+ ppc-*-linux-gnu*) fmt=elf em=linux
+ case "$endian" in
+ big) ;;
+ *) { { echo "$as_me:$LINENO: error: GNU/Linux must be configured big endian" >&5
+echo "$as_me: error: GNU/Linux must be configured big endian" >&2;}
+ { (exit 1); exit 1; }; } ;;
+ esac ;;
+ ppc-*-solaris*) fmt=elf
+ if test ${this_target} = $target; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TARGET_SOLARIS_COMMENT 1
+_ACEOF
+
+ fi
+ if test x${endian} = xbig; then
+ { { echo "$as_me:$LINENO: error: Solaris must be configured little endian" >&5
+echo "$as_me: error: Solaris must be configured little endian" >&2;}
+ { (exit 1); exit 1; }; }
+ fi ;;
+ ppc-*-rtems*) fmt=elf ;;
+ ppc-*-macos* | ppc-*-mpw*) fmt=coff em=macos ;;
+ ppc-*-netware*) fmt=elf em=ppcnw ;;
+ ppc-**-nto*) fmt=elf ;;
+ ppc-*-kaos*) fmt=elf ;;
+
+ s390x-*-linux-gnu*) fmt=elf em=linux ;;
+ s390-*-linux-gnu*) fmt=elf em=linux ;;
+
+ sh*-*-linux*) fmt=elf em=linux
+ case ${cpu} in
+ sh*eb) endian=big ;;
+ *) endian=little ;;
+ esac ;;
+ sh5*-*-netbsd*) fmt=elf em=nbsd ;;
+ sh64*-*-netbsd*) fmt=elf em=nbsd ;;
+ sh*-*-netbsdelf*) fmt=elf em=nbsd ;;
+ sh-*-elf*) fmt=elf ;;
+ sh-*-coff*) fmt=coff ;;
+ sh-*-nto*) fmt=elf ;;
+ sh-*-pe*) fmt=coff em=pe bfd_gas=yes endian=little ;;
+ sh-*-rtemscoff*) fmt=coff ;;
+ sh-*-rtems*) fmt=elf ;;
+ sh-*-kaos*) fmt=elf ;;
+ shle*-*-kaos*) fmt=elf ;;
+ sh64-*-elf*) fmt=elf ;;
+
+ ns32k-pc532-mach*) fmt=aout em=pc532mach ;;
+ ns32k-pc532-ux*) fmt=aout em=pc532mach ;;
+ ns32k-pc532-lites*) fmt=aout em=nbsd532 ;;
+ ns32k-*-*n*bsd*) fmt=aout em=nbsd532 ;;
+
+ sparc-*-rtemsaout*) fmt=aout ;;
+ sparc-*-rtemself*) fmt=elf ;;
+ sparc-*-rtems*) fmt=elf ;;
+ sparc-*-sunos4*) fmt=aout em=sun3 ;;
+ sparc-*-aout | sparc*-*-vxworks*) fmt=aout em=sparcaout ;;
+ sparc-*-coff) fmt=coff ;;
+ sparc-*-linux*aout*) fmt=aout em=linux ;;
+ sparc-*-linux-gnu*) fmt=elf em=linux ;;
+ sparc-*-lynxos*) fmt=coff em=lynx ;;
+ sparc-fujitsu-none) fmt=aout ;;
+ sparc-*-elf) fmt=elf ;;
+ sparc-*-sysv4*) fmt=elf ;;
+ sparc-*-solaris*) fmt=elf ;;
+ sparc-*-netbsdelf*) fmt=elf em=nbsd ;;
+ sparc-*-*n*bsd*) case ${cpu} in
+ sparc64) fmt=elf em=nbsd ;;
+ *) fmt=aout em=nbsd ;;
+ esac ;;
+ strongarm-*-coff) fmt=coff ;;
+ strongarm-*-elf) fmt=elf ;;
+ strongarm-*-kaos*) fmt=elf ;;
+ xscale-*-coff) fmt=coff ;;
+ xscale-*-elf) fmt=elf ;;
+
+ tic30-*-*aout*) fmt=aout bfd_gas=yes ;;
+ tic30-*-*coff*) fmt=coff bfd_gas=yes ;;
+ tic4x-*-* | c4x-*-*) fmt=coff bfd_gas=yes ;;
+ tic54x-*-* | c54x*-*-*) fmt=coff bfd_gas=yes need_libm=yes;;
+ tic80-*-*) fmt=coff ;;
+
+ v850-*-*) fmt=elf ;;
+ v850e-*-*) fmt=elf ;;
+ v850ea-*-*) fmt=elf ;;
+
+ vax-*-netbsdelf*) fmt=elf em=nbsd ;;
+ vax-*-netbsd*) fmt=aout em=nbsd ;;
+ vax-*-bsd* | vax-*-ultrix*) fmt=aout ;;
+ vax-*-linux-gnu*) fmt=elf em=linux bfd_gas=yes ;;
+ vax-*-vms) fmt=vms ;;
+
+ w65-*-*) fmt=coff ;;
+
+ xstormy16-*-*) fmt=elf ;;
+
+ xtensa-*-*) fmt=elf ;;
+
+ z8k-*-coff | z8k-*-sim) fmt=coff ;;
+
+ *-*-aout | *-*-scout) fmt=aout ;;
+ *-*-freebsd* | *-*-kfreebsd*-gnu) fmt=elf em=freebsd ;;
+ *-*-nindy*) fmt=bout ;;
+ *-*-bsd*) fmt=aout em=sun3 ;;
+ *-*-generic) fmt=generic ;;
+ *-*-xray | *-*-hms) fmt=coff ;;
+ *-*-sim) fmt=coff ;;
+ *-*-elf | *-*-sysv4* | *-*-solaris*) fmt=elf dev=yes ;;
+ *-*-aros*) fmt=elf em=linux bfd_gas=yes ;;
+ *-*-vxworks | *-*-windiss) fmt=elf ;;
+ *-*-netware) fmt=elf ;;
+ esac
+
+ if test ${this_target} = $target ; then
+ endian_def=
+ if test x${endian} = xbig; then
+ endian_def=1
+ elif test x${endian} = xlittle; then
+ endian_def=0
+ fi
+ if test x${endian_def} != x; then
+
+cat >>confdefs.h <<_ACEOF
+#define TARGET_BYTES_BIG_ENDIAN $endian_def
+_ACEOF
+
+ fi
+ fi
+
+ case ${cpu_type}-${fmt} in
+ alpha*-* | arm-* | i386-* | ia64*-* | mips-* | ns32k-* \
+ | pdp11-* | ppc-* | sparc-* | strongarm-* | xscale-* \
+ | *-elf | *-ecoff | *-som)
+ bfd_gas=yes ;;
+ esac
+
+# Other random stuff.
+
+ case ${cpu_type} in
+ mips)
+ # Set mips_cpu to the name of the default CPU.
+ case ${target_cpu} in
+ mips | mipsbe | mipseb | mipsle | mipsel | mips64 | mips64el)
+ mips_cpu=from-abi
+ ;;
+ mipsisa32 | mipsisa32el)
+ mips_cpu=mips32
+ ;;
+ mipsisa32r2 | mipsisa32r2el)
+ mips_cpu=mips32r2
+ ;;
+ mipsisa64 | mipsisa64el)
+ mips_cpu=mips64
+ ;;
+ mipsisa64r2 | mipsisa64r2el)
+ mips_cpu=mips64r2
+ ;;
+ mipstx39 | mipstx39el)
+ mips_cpu=r3900
+ ;;
+ mips64vr | mips64vrel)
+ mips_cpu=vr4100
+ ;;
+ mipsisa32r2* | mipsisa64r2*)
+ mips_cpu=`echo $target_cpu | sed -e 's/[a-z]*..r2//' -e 's/el$//'`
+ ;;
+ mips64* | mipsisa64* | mipsisa32*)
+ mips_cpu=`echo $target_cpu | sed -e 's/[a-z]*..//' -e 's/el$//'`
+ ;;
+ *)
+ { { echo "$as_me:$LINENO: error: $target_cpu isn't a supported MIPS CPU name" >&5
+echo "$as_me: error: $target_cpu isn't a supported MIPS CPU name" >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ esac
+ # See whether it's appropriate to set E_MIPS_ABI_O32 for o32
+ # binaries. It's a GNU extension that some OSes don't understand.
+ # The value only matters on ELF targets.
+ case ${target} in
+ *-*-irix*)
+ use_e_mips_abi_o32=0
+ ;;
+ *)
+ use_e_mips_abi_o32=1
+ ;;
+ esac
+ # Decide whether to generate 32-bit or 64-bit code by default.
+ # Used to resolve -march=from-abi when an embedded ABI is selected.
+ case ${target} in
+ mips64*-*-* | mipsisa64*-*-*)
+ mips_default_64bit=1
+ ;;
+ *)
+ mips_default_64bit=0
+ ;;
+ esac
+ # Decide which ABI to target by default.
+ case ${target} in
+ mips64*-linux* | mips-sgi-irix6*)
+ mips_default_abi=N32_ABI
+ ;;
+ mips*-linux*)
+ mips_default_abi=O32_ABI
+ ;;
+ *)
+ mips_default_abi=NO_ABI
+ ;;
+ esac
+
+cat >>confdefs.h <<_ACEOF
+#define MIPS_CPU_STRING_DEFAULT "$mips_cpu"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define USE_E_MIPS_ABI_O32 $use_e_mips_abi_o32
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define MIPS_DEFAULT_64BIT $mips_default_64bit
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define MIPS_DEFAULT_ABI $mips_default_abi
+_ACEOF
+
+ ;;
+ esac
+
+ # Do we need the opcodes library?
+ case ${cpu_type} in
+ vax | i386 | tic30)
+ ;;
+
+ *)
+ need_opcodes=yes
+
+ case "${enable_shared}" in
+ yes) shared_opcodes=true ;;
+ *opcodes*) shared_opcodes=true ;;
+ *) shared_opcodes=false ;;
+ esac
+ if test "${shared_opcodes}" = "true"; then
+ # A shared libopcodes must be linked against libbfd.
+ need_bfd=yes
+ fi
+ ;;
+ esac
+
+ # Any other special object files needed ?
+ case ${cpu_type} in
+ fr30 | ip2k | iq2000 | m32r | openrisc)
+ using_cgen=yes
+ ;;
+
+ frv)
+ using_cgen=yes
+ ;;
+ m68k)
+ case ${extra_objects} in
+ *m68k-parse.o*) ;;
+ *) extra_objects="$extra_objects m68k-parse.o" ;;
+ esac
+ ;;
+
+ mips)
+ echo ${extra_objects} | grep -s "itbl-parse.o"
+ if test $? -ne 0 ; then
+ extra_objects="$extra_objects itbl-parse.o"
+ fi
+
+ echo ${extra_objects} | grep -s "itbl-lex.o"
+ if test $? -ne 0 ; then
+ extra_objects="$extra_objects itbl-lex.o"
+ fi
+
+ echo ${extra_objects} | grep -s "itbl-ops.o"
+ if test $? -ne 0 ; then
+ extra_objects="$extra_objects itbl-ops.o"
+ fi
+ ;;
+
+ i386 | s390 | sparc)
+ if test $this_target = $target ; then
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_ARCH "${arch}"
+_ACEOF
+
+ fi
+ ;;
+
+ xstormy16)
+ using_cgen=yes
+ ;;
+
+ xtensa)
+ echo ${extra_objects} | grep -s "xtensa-relax.o"
+ if test $? -ne 0 ; then
+ extra_objects="$extra_objects xtensa-relax.o"
+ fi
+ ;;
+
+ *)
+ ;;
+ esac
+
+ if test $using_cgen = yes ; then
+ case "x${extra_objects}" in
+ *cgen.o*) ;;
+ *) extra_objects="$extra_objects cgen.o" ;;
+ esac
+ fi
+
+# See if we really can support this configuration with the emulation code.
+
+ if test $this_target = $target ; then
+ primary_bfd_gas=$bfd_gas
+ obj_format=$fmt
+ te_file=$em
+
+ if test $bfd_gas = no ; then
+ # Can't support other configurations this way.
+ break
+ fi
+ elif test $bfd_gas = no ; then
+ # Can't support this configuration.
+ break
+ fi
+
+# From target name and format, produce a list of supported emulations.
+
+ case ${generic_target}-${fmt} in
+ mips-*-irix5*-*) emulation="mipsbelf mipslelf mipself mipsbecoff mipslecoff mipsecoff" ;;
+ mips*-*-linux*-*) case "$endian" in
+ big) emulation="mipsbelf mipslelf mipself" ;;
+ *) emulation="mipslelf mipsbelf mipself" ;;
+ esac ;;
+ mips-*-lnews*-ecoff) ;;
+ mips-*-*-ecoff) case "$endian" in
+ big) emulation="mipsbecoff mipslecoff mipsecoff" ;;
+ *) emulation="mipslecoff mipsbecoff mipsecoff" ;;
+ esac ;;
+ mips-*-*-elf) case "$endian" in
+ big) emulation="mipsbelf mipslelf mipself" ;;
+ *) emulation="mipslelf mipsbelf mipself" ;;
+ esac ;;
+ mips-*-sysv4*MP*-*) emulation="mipsbelf mipslelf mipself mipsbecoff mipslecoff mipsecoff" ;;
+ # i386-pc-pe-coff != i386-pc-coff.
+ i386-*-pe-coff) ;;
+ # Uncommenting the next line will turn on support for i386 AOUT
+ # for the default linux configuration
+ # i386-*-linux*-elf) emulation="i386elf i386aout" ;;
+ #
+ i386-*-aout) emulation="i386aout" ;;
+ i386-*-coff) emulation="i386coff" ;;
+ i386-*-elf) emulation="i386elf" ;;
+
+ # Always all formats. The first stated emulation becomes the default.
+ cris-*-*aout*) emulation="crisaout criself" ;;
+ cris-*-*) emulation="criself crisaout" ;;
+ esac
+
+ emulations="$emulations $emulation"
+
+done
+
+# Turn on all targets if possible
+if test ${all_targets} = "yes"; then
+ case ${target_cpu_type} in
+ i386)
+ case ${obj_format} in
+ aout)
+ emulations="$emulations i386coff i386elf"
+ ;;
+ coff)
+ emulations="$emulations i386aout i386elf"
+ ;;
+ elf)
+ emulations="$emulations i386aout i386coff"
+ ;;
+ esac
+ ;;
+ esac
+fi
+
+# Assign floating point type. Most processors with FP support
+# IEEE FP. On those that don't support FP at all, usually IEEE
+# is emulated.
+case ${target_cpu} in
+ vax | tahoe ) atof=${target_cpu} ;;
+ pdp11) atof=vax ;;
+ *) atof=ieee ;;
+esac
+
+case "${obj_format}" in
+ "") { { echo "$as_me:$LINENO: error: GAS does not know what format to use for target ${target}" >&5
+echo "$as_me: error: GAS does not know what format to use for target ${target}" >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+
+# Unfortunately the cpu in cpu-opc.h file isn't always $(TARGET_CPU).
+cgen_cpu_prefix=""
+if test $using_cgen = yes ; then
+ case ${target_cpu} in
+ *) cgen_cpu_prefix=${target_cpu} ;;
+ esac
+
+
+cat >>confdefs.h <<\_ACEOF
+#define USING_CGEN 1
+_ACEOF
+
+fi
+
+
+if test ! -r ${srcdir}/config/tc-${target_cpu_type}.c; then
+ { { echo "$as_me:$LINENO: error: GAS does not support target CPU ${target_cpu_type}" >&5
+echo "$as_me: error: GAS does not support target CPU ${target_cpu_type}" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+if test ! -r ${srcdir}/config/obj-${obj_format}.c; then
+ { { echo "$as_me:$LINENO: error: GAS does not have support for object file format ${obj_format}" >&5
+echo "$as_me: error: GAS does not have support for object file format ${obj_format}" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+case ${user_bfd_gas}-${primary_bfd_gas} in
+ yes-yes | no-no)
+ # We didn't override user's choice.
+ ;;
+ no-yes)
+ { echo "$as_me:$LINENO: WARNING: Use of BFD is required for ${target}; overriding config options." >&5
+echo "$as_me: WARNING: Use of BFD is required for ${target}; overriding config options." >&2;}
+ ;;
+ no-preferred)
+ primary_bfd_gas=no
+ ;;
+ *-preferred)
+ primary_bfd_gas=yes
+ ;;
+ yes-*)
+ primary_bfd_gas=yes
+ ;;
+ -*)
+ # User specified nothing.
+ ;;
+esac
+
+# Some COFF configurations want these random other flags set.
+case ${obj_format} in
+ coff)
+ case ${target_cpu_type} in
+ i386)
+cat >>confdefs.h <<\_ACEOF
+#define I386COFF 1
+_ACEOF
+ ;;
+ m68k)
+cat >>confdefs.h <<\_ACEOF
+#define M68KCOFF 1
+_ACEOF
+ ;;
+ m88k)
+cat >>confdefs.h <<\_ACEOF
+#define M88KCOFF 1
+_ACEOF
+ ;;
+ esac
+ ;;
+esac
+
+# Getting this done right is going to be a bitch. Each configuration specified
+# with --enable-targets=... should be checked for environment, format, cpu, and
+# bfd_gas setting.
+#
+# For each configuration, the necessary object file support code must be linked
+# in. This might be only one, it might be up to four. The necessary emulation
+# code needs to be provided, too.
+#
+# And then there's "--enable-targets=all"....
+#
+# For now, just always do it for MIPS ELF or ECOFF configurations. Sigh.
+
+formats="${obj_format}"
+emfiles=""
+EMULATIONS=""
+_gas_uniq_list="$emulations"
+_gas_uniq_newlist=""
+for _gas_uniq_i in _gas_uniq_dummy $_gas_uniq_list ; do
+ case $_gas_uniq_i in
+ _gas_uniq_dummy) ;;
+ *) case " $_gas_uniq_newlist " in
+ *" $_gas_uniq_i "*) ;;
+ *) _gas_uniq_newlist="$_gas_uniq_newlist $_gas_uniq_i" ;;
+ esac ;;
+ esac
+done
+emulations=$_gas_uniq_newlist
+
+for em in . $emulations ; do
+ case $em in
+ .) continue ;;
+ mipsbelf | mipslelf | mipself)
+ fmt=elf file=mipself ;;
+ mipsbecoff | mipslecoff | mipsecoff)
+ fmt=ecoff file=mipsecoff ;;
+ *coff)
+ fmt=coff file=$em ;;
+ *aout)
+ fmt=aout file=$em ;;
+ *elf)
+ fmt=elf file=$em ;;
+ esac
+ formats="$formats $fmt"
+ emfiles="$emfiles e-$file.o"
+ EMULATIONS="$EMULATIONS &$em,"
+done
+_gas_uniq_list="$formats"
+_gas_uniq_newlist=""
+for _gas_uniq_i in _gas_uniq_dummy $_gas_uniq_list ; do
+ case $_gas_uniq_i in
+ _gas_uniq_dummy) ;;
+ *) case " $_gas_uniq_newlist " in
+ *" $_gas_uniq_i "*) ;;
+ *) _gas_uniq_newlist="$_gas_uniq_newlist $_gas_uniq_i" ;;
+ esac ;;
+ esac
+done
+formats=$_gas_uniq_newlist
+
+_gas_uniq_list="$emfiles"
+_gas_uniq_newlist=""
+for _gas_uniq_i in _gas_uniq_dummy $_gas_uniq_list ; do
+ case $_gas_uniq_i in
+ _gas_uniq_dummy) ;;
+ *) case " $_gas_uniq_newlist " in
+ *" $_gas_uniq_i "*) ;;
+ *) _gas_uniq_newlist="$_gas_uniq_newlist $_gas_uniq_i" ;;
+ esac ;;
+ esac
+done
+emfiles=$_gas_uniq_newlist
+
+if test `set . $formats ; shift ; echo $#` -gt 1 ; then
+ for fmt in $formats ; do
+ case $fmt in
+ aout)
+cat >>confdefs.h <<\_ACEOF
+#define OBJ_MAYBE_AOUT 1
+_ACEOF
+ ;;
+ bout)
+cat >>confdefs.h <<\_ACEOF
+#define OBJ_MAYBE_BOUT 1
+_ACEOF
+ ;;
+ coff)
+cat >>confdefs.h <<\_ACEOF
+#define OBJ_MAYBE_COFF 1
+_ACEOF
+ ;;
+ ecoff)
+cat >>confdefs.h <<\_ACEOF
+#define OBJ_MAYBE_ECOFF 1
+_ACEOF
+ ;;
+ elf)
+cat >>confdefs.h <<\_ACEOF
+#define OBJ_MAYBE_ELF 1
+_ACEOF
+ ;;
+ generic)
+cat >>confdefs.h <<\_ACEOF
+#define OBJ_MAYBE_GENERIC 1
+_ACEOF
+ ;;
+ hp300)
+cat >>confdefs.h <<\_ACEOF
+#define OBJ_MAYBE_HP300 1
+_ACEOF
+ ;;
+ ieee)
+cat >>confdefs.h <<\_ACEOF
+#define OBJ_MAYBE_IEEE 1
+_ACEOF
+ ;;
+ som)
+cat >>confdefs.h <<\_ACEOF
+#define OBJ_MAYBE_SOM 1
+_ACEOF
+ ;;
+ vms)
+cat >>confdefs.h <<\_ACEOF
+#define OBJ_MAYBE_VMS 1
+_ACEOF
+ ;;
+ esac
+ extra_objects="$extra_objects obj-$fmt.o"
+ done
+ obj_format=multi
+fi
+if test `set . $emfiles ; shift ; echo $#` -gt 0 ; then
+ DEFAULT_EMULATION=`set . $emulations ; echo $2`
+ # e-mips* has more than one emulation per file, e-i386* has just one at the
+ # moment. If only one emulation is specified, then don't define
+ # USE_EMULATIONS or include any of the e-files as they will only be bloat.
+ case "${obj_format}${emfiles}" in
+ multi* | *mips*)
+ extra_objects="$extra_objects $emfiles"
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_EMULATIONS 1
+_ACEOF
+ ;;
+ esac
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define EMULATIONS $EMULATIONS
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_EMULATION "$DEFAULT_EMULATION"
+_ACEOF
+
+
+case ${primary_bfd_gas}-${target_cpu_type}-${obj_format} in
+ yes-*-coff) need_bfd=yes ;;
+ no-*-coff) need_bfd=yes
+
+cat >>confdefs.h <<\_ACEOF
+#define MANY_SEGMENTS 1
+_ACEOF
+ ;;
+esac
+
+reject_dev_configs=yes
+
+case ${reject_dev_configs}-${dev} in
+ yes-yes) # Oops.
+ { { echo "$as_me:$LINENO: error: GAS does not support the ${generic_target} configuration." >&5
+echo "$as_me: error: GAS does not support the ${generic_target} configuration." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+esac
+
+
+
+
+
+
+
+case "${primary_bfd_gas}" in
+ yes)
+cat >>confdefs.h <<\_ACEOF
+#define BFD_ASSEMBLER 1
+_ACEOF
+
+ need_bfd=yes ;;
+esac
+
+# do we need the opcodes library?
+case "${need_opcodes}" in
+yes)
+ OPCODES_LIB=../opcodes/libopcodes.la
+ ;;
+esac
+
+case "${need_bfd}" in
+yes)
+ BFDLIB=../bfd/libbfd.la
+ BFDVER_H=../bfd/bfdver.h
+ ALL_OBJ_DEPS="$ALL_OBJ_DEPS"' ../bfd/bfd.h $(INCDIR)/symcat.h'
+ ;;
+esac
+
+
+
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define TARGET_ALIAS "${target_alias}"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define TARGET_CANONICAL "${target}"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define TARGET_CPU "${target_cpu}"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define TARGET_VENDOR "${target_vendor}"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define TARGET_OS "${target_os}"
+_ACEOF
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_CC" && break
+done
+
+ CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+ "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std1 is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std1. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C. Since we use `exit',
+# in C++ we need to declare it. In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+ choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ for ac_declaration in \
+ '' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
+fi
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+for ac_prog in 'bison -y' byacc
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_YACC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_YACC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+ echo "$as_me:$LINENO: result: $YACC" >&5
+echo "${ECHO_T}$YACC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+for ac_prog in flex lex
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_LEX+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LEX="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+LEX=$ac_cv_prog_LEX
+if test -n "$LEX"; then
+ echo "$as_me:$LINENO: result: $LEX" >&5
+echo "${ECHO_T}$LEX" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$LEX" && break
+done
+test -n "$LEX" || LEX=":"
+
+if test -z "$LEXLIB"
+then
+ echo "$as_me:$LINENO: checking for yywrap in -lfl" >&5
+echo $ECHO_N "checking for yywrap in -lfl... $ECHO_C" >&6
+if test "${ac_cv_lib_fl_yywrap+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lfl $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char yywrap ();
+int
+main ()
+{
+yywrap ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_fl_yywrap=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_fl_yywrap=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_fl_yywrap" >&5
+echo "${ECHO_T}$ac_cv_lib_fl_yywrap" >&6
+if test $ac_cv_lib_fl_yywrap = yes; then
+ LEXLIB="-lfl"
+else
+ echo "$as_me:$LINENO: checking for yywrap in -ll" >&5
+echo $ECHO_N "checking for yywrap in -ll... $ECHO_C" >&6
+if test "${ac_cv_lib_l_yywrap+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ll $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char yywrap ();
+int
+main ()
+{
+yywrap ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_l_yywrap=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_l_yywrap=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_l_yywrap" >&5
+echo "${ECHO_T}$ac_cv_lib_l_yywrap" >&6
+if test $ac_cv_lib_l_yywrap = yes; then
+ LEXLIB="-ll"
+fi
+
+fi
+
+fi
+
+if test "x$LEX" != "x:"; then
+ echo "$as_me:$LINENO: checking lex output file root" >&5
+echo $ECHO_N "checking lex output file root... $ECHO_C" >&6
+if test "${ac_cv_prog_lex_root+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # The minimal lex program is just a single line: %%. But some broken lexes
+# (Solaris, I think it was) want two %% lines, so accommodate them.
+cat >conftest.l <<_ACEOF
+%%
+%%
+_ACEOF
+{ (eval echo "$as_me:$LINENO: \"$LEX conftest.l\"") >&5
+ (eval $LEX conftest.l) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+if test -f lex.yy.c; then
+ ac_cv_prog_lex_root=lex.yy
+elif test -f lexyy.c; then
+ ac_cv_prog_lex_root=lexyy
+else
+ { { echo "$as_me:$LINENO: error: cannot find output from $LEX; giving up" >&5
+echo "$as_me: error: cannot find output from $LEX; giving up" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_lex_root" >&5
+echo "${ECHO_T}$ac_cv_prog_lex_root" >&6
+rm -f conftest.l
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+echo "$as_me:$LINENO: checking whether yytext is a pointer" >&5
+echo $ECHO_N "checking whether yytext is a pointer... $ECHO_C" >&6
+if test "${ac_cv_prog_lex_yytext_pointer+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # POSIX says lex can declare yytext either as a pointer or an array; the
+# default is implementation-dependent. Figure out which it is, since
+# not all implementations provide the %pointer and %array declarations.
+ac_cv_prog_lex_yytext_pointer=no
+echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c
+ac_save_LIBS=$LIBS
+LIBS="$LIBS $LEXLIB"
+cat >conftest.$ac_ext <<_ACEOF
+`cat $LEX_OUTPUT_ROOT.c`
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_lex_yytext_pointer=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_save_LIBS
+rm -f "${LEX_OUTPUT_ROOT}.c"
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_lex_yytext_pointer" >&5
+echo "${ECHO_T}$ac_cv_prog_lex_yytext_pointer" >&6
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define YYTEXT_POINTER 1
+_ACEOF
+
+fi
+
+fi
+if test "$LEX" = :; then
+ LEX=${am_missing_run}flex
+fi
+
+ALL_LINGUAS="fr tr es"
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ RANLIB=$ac_ct_RANLIB
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this. */
+ typedef int charset[2];
+ const charset x;
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *ccp;
+ char **p;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ ccp = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++ccp;
+ p = (char**) ccp;
+ ccp = (char const *const *) p;
+ { /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ }
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_const=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for inline" >&5
+echo $ECHO_N "checking for inline... $ECHO_C" >&6
+if test "${ac_cv_c_inline+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
+echo "${ECHO_T}$ac_cv_c_inline" >&6
+
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+echo "$as_me:$LINENO: checking for off_t" >&5
+echo $ECHO_N "checking for off_t... $ECHO_C" >&6
+if test "${ac_cv_type_off_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((off_t *) 0)
+ return 0;
+if (sizeof (off_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_off_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_off_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
+echo "${ECHO_T}$ac_cv_type_off_t" >&6
+if test $ac_cv_type_off_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define off_t long
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for size_t" >&5
+echo $ECHO_N "checking for size_t... $ECHO_C" >&6
+if test "${ac_cv_type_size_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((size_t *) 0)
+ return 0;
+if (sizeof (size_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_size_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_size_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+echo "${ECHO_T}$ac_cv_type_size_t" >&6
+if test $ac_cv_type_size_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned
+_ACEOF
+
+fi
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo "$as_me:$LINENO: checking for working alloca.h" >&5
+echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6
+if test "${ac_cv_working_alloca_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_working_alloca_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_working_alloca_h=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5
+echo "${ECHO_T}$ac_cv_working_alloca_h" >&6
+if test $ac_cv_working_alloca_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA_H 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for alloca" >&5
+echo $ECHO_N "checking for alloca... $ECHO_C" >&6
+if test "${ac_cv_func_alloca_works+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_alloca_works=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_alloca_works=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5
+echo "${ECHO_T}$ac_cv_func_alloca_works" >&6
+
+if test $ac_cv_func_alloca_works = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA 1
+_ACEOF
+
+else
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble. Some versions do not even contain alloca or
+# contain a buggy version. If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=alloca.$ac_objext
+
+cat >>confdefs.h <<\_ACEOF
+#define C_ALLOCA 1
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5
+echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6
+if test "${ac_cv_os_cray+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "webecray" >/dev/null 2>&1; then
+ ac_cv_os_cray=yes
+else
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5
+echo "${ECHO_T}$ac_cv_os_cray" >&6
+if test $ac_cv_os_cray = yes; then
+ for ac_func in _getb67 GETB67 getb67; do
+ as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+ break
+fi
+
+ done
+fi
+
+echo "$as_me:$LINENO: checking stack direction for C alloca" >&5
+echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6
+if test "${ac_cv_c_stack_direction+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+int
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+
+int
+main ()
+{
+ exit (find_stack_direction () < 0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_stack_direction=1
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5
+echo "${ECHO_T}$ac_cv_c_stack_direction" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+
+
+for ac_header in stdlib.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists. ##
+## ------------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_func in getpagesize
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+echo "$as_me:$LINENO: checking for working mmap" >&5
+echo $ECHO_N "checking for working mmap... $ECHO_C" >&6
+if test "${ac_cv_func_mmap_fixed_mapped+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+/* malloc might have been renamed as rpl_malloc. */
+#undef malloc
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the file system buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propagated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#if !STDC_HEADERS && !HAVE_STDLIB_H
+char *malloc ();
+#endif
+
+/* This mess was copied from the GNU getpagesize.h. */
+#if !HAVE_GETPAGESIZE
+/* Assume that all systems that can run configure have sys/param.h. */
+# if !HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# if HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+int
+main ()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize ();
+
+ /* First, make a file with some known garbage in it. */
+ data = (char *) malloc (pagesize);
+ if (!data)
+ exit (1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand ();
+ umask (0);
+ fd = creat ("conftest.mmap", 0600);
+ if (fd < 0)
+ exit (1);
+ if (write (fd, data, pagesize) != pagesize)
+ exit (1);
+ close (fd);
+
+ /* Next, try to mmap the file at a fixed address which already has
+ something else allocated at it. If we can, also make sure that
+ we see the same garbage. */
+ fd = open ("conftest.mmap", O_RDWR);
+ if (fd < 0)
+ exit (1);
+ data2 = (char *) malloc (2 * pagesize);
+ if (!data2)
+ exit (1);
+ data2 += (pagesize - ((long) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit (1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit (1);
+
+ /* Finally, make sure that changes to the mapped area do not
+ percolate back to the file as seen by read(). (This is a bug on
+ some variants of i386 svr4.0.) */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = (char *) malloc (pagesize);
+ if (!data3)
+ exit (1);
+ if (read (fd, data3, pagesize) != pagesize)
+ exit (1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit (1);
+ close (fd);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_mmap_fixed_mapped" >&5
+echo "${ECHO_T}$ac_cv_func_mmap_fixed_mapped" >&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MMAP 1
+_ACEOF
+
+fi
+rm -f conftest.mmap
+
+
+
+
+
+
+
+
+
+
+
+for ac_header in argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists. ##
+## ------------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+
+
+
+
+
+
+for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+
+for ac_func in stpcpy
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STPCPY 1
+_ACEOF
+
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ echo "$as_me:$LINENO: checking for LC_MESSAGES" >&5
+echo $ECHO_N "checking for LC_MESSAGES... $ECHO_C" >&6
+if test "${am_cv_val_LC_MESSAGES+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <locale.h>
+int
+main ()
+{
+return LC_MESSAGES
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ am_cv_val_LC_MESSAGES=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+am_cv_val_LC_MESSAGES=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $am_cv_val_LC_MESSAGES" >&5
+echo "${ECHO_T}$am_cv_val_LC_MESSAGES" >&6
+ if test $am_cv_val_LC_MESSAGES = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LC_MESSAGES 1
+_ACEOF
+
+ fi
+ fi
+ echo "$as_me:$LINENO: checking whether NLS is requested" >&5
+echo $ECHO_N "checking whether NLS is requested... $ECHO_C" >&6
+ # Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+ enableval="$enable_nls"
+ USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi;
+ echo "$as_me:$LINENO: result: $USE_NLS" >&5
+echo "${ECHO_T}$USE_NLS" >&6
+
+
+ USE_INCLUDED_LIBINTL=no
+
+ if test "$USE_NLS" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define ENABLE_NLS 1
+_ACEOF
+
+ echo "$as_me:$LINENO: checking whether included gettext is requested" >&5
+echo $ECHO_N "checking whether included gettext is requested... $ECHO_C" >&6
+
+# Check whether --with-included-gettext or --without-included-gettext was given.
+if test "${with_included_gettext+set}" = set; then
+ withval="$with_included_gettext"
+ nls_cv_force_use_gnu_gettext=$withval
+else
+ nls_cv_force_use_gnu_gettext=no
+fi;
+ echo "$as_me:$LINENO: result: $nls_cv_force_use_gnu_gettext" >&5
+echo "${ECHO_T}$nls_cv_force_use_gnu_gettext" >&6
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ if test "${ac_cv_header_libintl_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for libintl.h" >&5
+echo $ECHO_N "checking for libintl.h... $ECHO_C" >&6
+if test "${ac_cv_header_libintl_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_libintl_h" >&5
+echo "${ECHO_T}$ac_cv_header_libintl_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking libintl.h usability" >&5
+echo $ECHO_N "checking libintl.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <libintl.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking libintl.h presence" >&5
+echo $ECHO_N "checking libintl.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <libintl.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: libintl.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: libintl.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: libintl.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: libintl.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: libintl.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: libintl.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: libintl.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: libintl.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: libintl.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: libintl.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: libintl.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: libintl.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: libintl.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: libintl.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: libintl.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: libintl.h: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists. ##
+## ------------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for libintl.h" >&5
+echo $ECHO_N "checking for libintl.h... $ECHO_C" >&6
+if test "${ac_cv_header_libintl_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_libintl_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_libintl_h" >&5
+echo "${ECHO_T}$ac_cv_header_libintl_h" >&6
+
+fi
+if test $ac_cv_header_libintl_h = yes; then
+ echo "$as_me:$LINENO: checking for gettext in libc" >&5
+echo $ECHO_N "checking for gettext in libc... $ECHO_C" >&6
+if test "${gt_cv_func_gettext_libc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <libintl.h>
+int
+main ()
+{
+return (int) gettext ("")
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gt_cv_func_gettext_libc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gt_cv_func_gettext_libc=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $gt_cv_func_gettext_libc" >&5
+echo "${ECHO_T}$gt_cv_func_gettext_libc" >&6
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ echo "$as_me:$LINENO: checking for bindtextdomain in -lintl" >&5
+echo $ECHO_N "checking for bindtextdomain in -lintl... $ECHO_C" >&6
+if test "${ac_cv_lib_intl_bindtextdomain+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char bindtextdomain ();
+int
+main ()
+{
+bindtextdomain ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_intl_bindtextdomain=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_intl_bindtextdomain=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_intl_bindtextdomain" >&5
+echo "${ECHO_T}$ac_cv_lib_intl_bindtextdomain" >&6
+if test $ac_cv_lib_intl_bindtextdomain = yes; then
+ echo "$as_me:$LINENO: checking for gettext in libintl" >&5
+echo $ECHO_N "checking for gettext in libintl... $ECHO_C" >&6
+if test "${gt_cv_func_gettext_libintl+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+return (int) gettext ("")
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gt_cv_func_gettext_libintl=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gt_cv_func_gettext_libintl=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $gt_cv_func_gettext_libintl" >&5
+echo "${ECHO_T}$gt_cv_func_gettext_libintl" >&6
+fi
+
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GETTEXT 1
+_ACEOF
+
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_MSGFMT+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$as_me:$LINENO: result: $MSGFMT" >&5
+echo "${ECHO_T}$MSGFMT" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+ if test "$MSGFMT" != "no"; then
+
+for ac_func in dcgettext
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GMSGFMT+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $GMSGFMT in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT=$ac_cv_path_GMSGFMT
+
+if test -n "$GMSGFMT"; then
+ echo "$as_me:$LINENO: result: $GMSGFMT" >&5
+echo "${ECHO_T}$GMSGFMT" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_XGETTEXT+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$as_me:$LINENO: result: $XGETTEXT" >&5
+echo "${ECHO_T}$XGETTEXT" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ CATOBJEXT=.gmo
+ DATADIRNAME=share
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+CATOBJEXT=.mo
+ DATADIRNAME=lib
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ INSTOBJEXT=.mo
+ fi
+ fi
+
+fi
+
+
+
+
+ if test "$CATOBJEXT" = "NONE"; then
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ INTLOBJS="\$(GETTOBJS)"
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_MSGFMT+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$as_me:$LINENO: result: $MSGFMT" >&5
+echo "${ECHO_T}$MSGFMT" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GMSGFMT+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $GMSGFMT in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT=$ac_cv_path_GMSGFMT
+
+if test -n "$GMSGFMT"; then
+ echo "$as_me:$LINENO: result: $GMSGFMT" >&5
+echo "${ECHO_T}$GMSGFMT" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_XGETTEXT+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$as_me:$LINENO: result: $XGETTEXT" >&5
+echo "${ECHO_T}$XGETTEXT" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ if test "$XGETTEXT" != ":"; then
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ echo "$as_me:$LINENO: result: found xgettext programs is not GNU xgettext; ignore it" >&5
+echo "${ECHO_T}found xgettext programs is not GNU xgettext; ignore it" >&6
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ echo "$as_me:$LINENO: checking for catalogs to be installed" >&5
+echo $ECHO_N "checking for catalogs to be installed... $ECHO_C" >&6
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ echo "$as_me:$LINENO: result: $LINGUAS" >&5
+echo "${ECHO_T}$LINGUAS" >&6
+ fi
+
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+
+
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ if test "${ac_cv_header_linux_version_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for linux/version.h" >&5
+echo $ECHO_N "checking for linux/version.h... $ECHO_C" >&6
+if test "${ac_cv_header_linux_version_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_linux_version_h" >&5
+echo "${ECHO_T}$ac_cv_header_linux_version_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking linux/version.h usability" >&5
+echo $ECHO_N "checking linux/version.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <linux/version.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking linux/version.h presence" >&5
+echo $ECHO_N "checking linux/version.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <linux/version.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: linux/version.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: linux/version.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: linux/version.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: linux/version.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: linux/version.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: linux/version.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: linux/version.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: linux/version.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: linux/version.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: linux/version.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: linux/version.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: linux/version.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: linux/version.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: linux/version.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: linux/version.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: linux/version.h: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists. ##
+## ------------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for linux/version.h" >&5
+echo $ECHO_N "checking for linux/version.h... $ECHO_C" >&6
+if test "${ac_cv_header_linux_version_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_linux_version_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_linux_version_h" >&5
+echo "${ECHO_T}$ac_cv_header_linux_version_h" >&6
+
+fi
+if test $ac_cv_header_linux_version_h = yes; then
+ msgformat=linux
+else
+ msgformat=xopen
+fi
+
+
+
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+
+
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+
+
+ l=
+
+
+ if test -f $srcdir/po/POTFILES.in; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+
+
+echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+ USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi;
+ echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5
+echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_header in string.h stdlib.h memory.h strings.h unistd.h stdarg.h varargs.h errno.h sys/types.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists. ##
+## ------------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# Put this here so that autoconf's "cross-compiling" message doesn't confuse
+# people who are not cross-compiling but are compiling cross-assemblers.
+echo "$as_me:$LINENO: checking whether compiling a cross-assembler" >&5
+echo $ECHO_N "checking whether compiling a cross-assembler... $ECHO_C" >&6
+if test "${host}" = "${target}"; then
+ cross_gas=no
+else
+ cross_gas=yes
+
+cat >>confdefs.h <<\_ACEOF
+#define CROSS_COMPILE 1
+_ACEOF
+
+fi
+echo "$as_me:$LINENO: result: $cross_gas" >&5
+echo "${ECHO_T}$cross_gas" >&6
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo "$as_me:$LINENO: checking for working alloca.h" >&5
+echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6
+if test "${ac_cv_working_alloca_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_working_alloca_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_working_alloca_h=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5
+echo "${ECHO_T}$ac_cv_working_alloca_h" >&6
+if test $ac_cv_working_alloca_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA_H 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for alloca" >&5
+echo $ECHO_N "checking for alloca... $ECHO_C" >&6
+if test "${ac_cv_func_alloca_works+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_alloca_works=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_alloca_works=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5
+echo "${ECHO_T}$ac_cv_func_alloca_works" >&6
+
+if test $ac_cv_func_alloca_works = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA 1
+_ACEOF
+
+else
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble. Some versions do not even contain alloca or
+# contain a buggy version. If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=alloca.$ac_objext
+
+cat >>confdefs.h <<\_ACEOF
+#define C_ALLOCA 1
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5
+echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6
+if test "${ac_cv_os_cray+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "webecray" >/dev/null 2>&1; then
+ ac_cv_os_cray=yes
+else
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5
+echo "${ECHO_T}$ac_cv_os_cray" >&6
+if test $ac_cv_os_cray = yes; then
+ for ac_func in _getb67 GETB67 getb67; do
+ as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+ break
+fi
+
+ done
+fi
+
+echo "$as_me:$LINENO: checking stack direction for C alloca" >&5
+echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6
+if test "${ac_cv_c_stack_direction+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+int
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+
+int
+main ()
+{
+ exit (find_stack_direction () < 0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_stack_direction=1
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5
+echo "${ECHO_T}$ac_cv_c_stack_direction" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+echo "$as_me:$LINENO: checking for inline" >&5
+echo $ECHO_N "checking for inline... $ECHO_C" >&6
+if test "${ac_cv_c_inline+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
+echo "${ECHO_T}$ac_cv_c_inline" >&6
+
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+
+# VMS doesn't have unlink.
+
+
+for ac_func in unlink remove
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ break
+fi
+done
+
+
+# Some systems don't have sbrk().
+
+for ac_func in sbrk
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# do we need the math library?
+case "${need_libm}" in
+yes)
+ LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32*)
+ # These system don't have libm
+ ;;
+*-ncr-sysv4.3*)
+ echo "$as_me:$LINENO: checking for _mwvalidcheckl in -lmw" >&5
+echo $ECHO_N "checking for _mwvalidcheckl in -lmw... $ECHO_C" >&6
+if test "${ac_cv_lib_mw__mwvalidcheckl+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmw $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char _mwvalidcheckl ();
+int
+main ()
+{
+_mwvalidcheckl ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_mw__mwvalidcheckl=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_mw__mwvalidcheckl=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_mw__mwvalidcheckl" >&5
+echo "${ECHO_T}$ac_cv_lib_mw__mwvalidcheckl" >&6
+if test $ac_cv_lib_mw__mwvalidcheckl = yes; then
+ LIBM="-lmw"
+fi
+
+ echo "$as_me:$LINENO: checking for main in -lm" >&5
+echo $ECHO_N "checking for main in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_main+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+main ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_m_main=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_main" >&5
+echo "${ECHO_T}$ac_cv_lib_m_main" >&6
+if test $ac_cv_lib_m_main = yes; then
+ LIBM="$LIBM -lm"
+fi
+
+ ;;
+*)
+ echo "$as_me:$LINENO: checking for main in -lm" >&5
+echo $ECHO_N "checking for main in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_main+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+main ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_m_main=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_main" >&5
+echo "${ECHO_T}$ac_cv_lib_m_main" >&6
+if test $ac_cv_lib_m_main = yes; then
+ LIBM="-lm"
+fi
+
+ ;;
+esac
+
+
+ ;;
+esac
+
+# Some non-ANSI preprocessors botch requoting inside strings. That's bad
+# enough, but on some of those systems, the assert macro relies on requoting
+# working properly!
+echo "$as_me:$LINENO: checking for working assert macro" >&5
+echo $ECHO_N "checking for working assert macro... $ECHO_C" >&6
+if test "${gas_cv_assert_ok+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <assert.h>
+#include <stdio.h>
+int
+main ()
+{
+
+/* check for requoting problems */
+static int a, b, c, d;
+static char *s;
+assert (!strcmp(s, "foo bar baz quux"));
+/* check for newline handling */
+assert (a == b
+ || c == d);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gas_cv_assert_ok=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gas_cv_assert_ok=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $gas_cv_assert_ok" >&5
+echo "${ECHO_T}$gas_cv_assert_ok" >&6
+test $gas_cv_assert_ok = yes ||
+cat >>confdefs.h <<\_ACEOF
+#define BROKEN_ASSERT 1
+_ACEOF
+
+
+
+# On some systems, the system header files may not declare malloc, realloc,
+# and free. There are places where gas needs these functions to have been
+# declared -- such as when taking their addresses.
+gas_test_headers="
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+"
+
+echo "$as_me:$LINENO: checking whether declaration is required for strstr" >&5
+echo $ECHO_N "checking whether declaration is required for strstr... $ECHO_C" >&6
+if test "${gas_cv_decl_needed_strstr+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$gas_test_headers
+int
+main ()
+{
+
+typedef char *(*f)();
+f x;
+x = (f) strstr;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gas_cv_decl_needed_strstr=no
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gas_cv_decl_needed_strstr=yes
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $gas_cv_decl_needed_strstr" >&5
+echo "${ECHO_T}$gas_cv_decl_needed_strstr" >&6
+if test $gas_cv_decl_needed_strstr = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NEED_DECLARATION_STRSTR 1
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking whether declaration is required for malloc" >&5
+echo $ECHO_N "checking whether declaration is required for malloc... $ECHO_C" >&6
+if test "${gas_cv_decl_needed_malloc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$gas_test_headers
+int
+main ()
+{
+
+typedef char *(*f)();
+f x;
+x = (f) malloc;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gas_cv_decl_needed_malloc=no
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gas_cv_decl_needed_malloc=yes
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $gas_cv_decl_needed_malloc" >&5
+echo "${ECHO_T}$gas_cv_decl_needed_malloc" >&6
+if test $gas_cv_decl_needed_malloc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NEED_DECLARATION_MALLOC 1
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking whether declaration is required for free" >&5
+echo $ECHO_N "checking whether declaration is required for free... $ECHO_C" >&6
+if test "${gas_cv_decl_needed_free+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$gas_test_headers
+int
+main ()
+{
+
+typedef void (*f)();
+f x;
+x = (f) free;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gas_cv_decl_needed_free=no
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gas_cv_decl_needed_free=yes
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $gas_cv_decl_needed_free" >&5
+echo "${ECHO_T}$gas_cv_decl_needed_free" >&6
+if test $gas_cv_decl_needed_free = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NEED_DECLARATION_FREE 1
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking whether declaration is required for sbrk" >&5
+echo $ECHO_N "checking whether declaration is required for sbrk... $ECHO_C" >&6
+if test "${gas_cv_decl_needed_sbrk+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$gas_test_headers
+int
+main ()
+{
+
+typedef char *(*f)();
+f x;
+x = (f) sbrk;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gas_cv_decl_needed_sbrk=no
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gas_cv_decl_needed_sbrk=yes
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $gas_cv_decl_needed_sbrk" >&5
+echo "${ECHO_T}$gas_cv_decl_needed_sbrk" >&6
+if test $gas_cv_decl_needed_sbrk = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NEED_DECLARATION_SBRK 1
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking whether declaration is required for environ" >&5
+echo $ECHO_N "checking whether declaration is required for environ... $ECHO_C" >&6
+if test "${gas_cv_decl_needed_environ+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$gas_test_headers
+int
+main ()
+{
+
+typedef char **f;
+f x;
+x = (f) environ;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gas_cv_decl_needed_environ=no
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gas_cv_decl_needed_environ=yes
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $gas_cv_decl_needed_environ" >&5
+echo "${ECHO_T}$gas_cv_decl_needed_environ" >&6
+if test $gas_cv_decl_needed_environ = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NEED_DECLARATION_ENVIRON 1
+_ACEOF
+
+fi
+
+
+# Does errno.h declare errno, or do we have to add a separate declaration
+# for it?
+
+echo "$as_me:$LINENO: checking whether declaration is required for errno" >&5
+echo $ECHO_N "checking whether declaration is required for errno... $ECHO_C" >&6
+if test "${gas_cv_decl_needed_errno+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+int
+main ()
+{
+
+typedef int f;
+f x;
+x = (f) errno;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gas_cv_decl_needed_errno=no
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gas_cv_decl_needed_errno=yes
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $gas_cv_decl_needed_errno" >&5
+echo "${ECHO_T}$gas_cv_decl_needed_errno" >&6
+if test $gas_cv_decl_needed_errno = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NEED_DECLARATION_ERRNO 1
+_ACEOF
+
+fi
+
+
+
+
+ ac_config_files="$ac_config_files Makefile doc/Makefile po/Makefile.in:po/Make-in"
+
+ ac_config_commands="$ac_config_commands default"
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+ (set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+} |
+ sed '
+ t clear
+ : clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[ ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[ ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_i=`echo "$ac_i" |
+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+ # 2. Add them.
+ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling. Logging --version etc. is OK.
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.59,
+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "x$1" : 'x\([^=]*\)='`
+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ -*)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ *) # This is not an option, so the user has probably given explicit
+ # arguments.
+ ac_option=$1
+ ac_need_defaults=false;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --vers* | -V )
+ echo "$ac_cs_version"; exit 0 ;;
+ --he | --h)
+ # Conflict between --help and --header
+ { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ echo "$ac_cs_usage"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1" ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+#
+# INIT-COMMANDS section.
+#
+
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+target_cpu_type=${target_cpu_type}
+ cgen_cpu_prefix=${cgen_cpu_prefix}
+ obj_format=${obj_format}
+ te_file=${te_file}
+
+_ACEOF
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+ case "$ac_config_target" in
+ # Handling of arguments.
+ "gdb.ini" ) CONFIG_FILES="$CONFIG_FILES gdb.ini:gdbinit.in" ;;
+ ".gdbinit" ) CONFIG_FILES="$CONFIG_FILES .gdbinit:gdbinit.in" ;;
+ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+ "po/Makefile.in" ) CONFIG_FILES="$CONFIG_FILES po/Makefile.in:po/Make-in" ;;
+ "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "default" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
+ "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h:config.in" ;;
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./confstat$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+ # Protect against being on the right side of a sed subst in config.status.
+ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@target@,$target,;t t
+s,@target_cpu@,$target_cpu,;t t
+s,@target_vendor@,$target_vendor,;t t
+s,@target_os@,$target_os,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@CYGPATH_W@,$CYGPATH_W,;t t
+s,@PACKAGE@,$PACKAGE,;t t
+s,@VERSION@,$VERSION,;t t
+s,@ACLOCAL@,$ACLOCAL,;t t
+s,@AUTOCONF@,$AUTOCONF,;t t
+s,@AUTOMAKE@,$AUTOMAKE,;t t
+s,@AUTOHEADER@,$AUTOHEADER,;t t
+s,@MAKEINFO@,$MAKEINFO,;t t
+s,@AMTAR@,$AMTAR,;t t
+s,@install_sh@,$install_sh,;t t
+s,@STRIP@,$STRIP,;t t
+s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
+s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
+s,@mkdir_p@,$mkdir_p,;t t
+s,@AWK@,$AWK,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@am__leading_dot@,$am__leading_dot,;t t
+s,@DEPDIR@,$DEPDIR,;t t
+s,@am__include@,$am__include,;t t
+s,@am__quote@,$am__quote,;t t
+s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t
+s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
+s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
+s,@CCDEPMODE@,$CCDEPMODE,;t t
+s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
+s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
+s,@LN_S@,$LN_S,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@LIBTOOL@,$LIBTOOL,;t t
+s,@WARN_CFLAGS@,$WARN_CFLAGS,;t t
+s,@GDBINIT@,$GDBINIT,;t t
+s,@cgen_cpu_prefix@,$cgen_cpu_prefix,;t t
+s,@extra_objects@,$extra_objects,;t t
+s,@target_cpu_type@,$target_cpu_type,;t t
+s,@obj_format@,$obj_format,;t t
+s,@te_file@,$te_file,;t t
+s,@install_tooldir@,$install_tooldir,;t t
+s,@atof@,$atof,;t t
+s,@BFDLIB@,$BFDLIB,;t t
+s,@OPCODES_LIB@,$OPCODES_LIB,;t t
+s,@BFDVER_H@,$BFDVER_H,;t t
+s,@ALL_OBJ_DEPS@,$ALL_OBJ_DEPS,;t t
+s,@YACC@,$YACC,;t t
+s,@LEX@,$LEX,;t t
+s,@LEXLIB@,$LEXLIB,;t t
+s,@LEX_OUTPUT_ROOT@,$LEX_OUTPUT_ROOT,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@ALLOCA@,$ALLOCA,;t t
+s,@USE_NLS@,$USE_NLS,;t t
+s,@MSGFMT@,$MSGFMT,;t t
+s,@GMSGFMT@,$GMSGFMT,;t t
+s,@XGETTEXT@,$XGETTEXT,;t t
+s,@USE_INCLUDED_LIBINTL@,$USE_INCLUDED_LIBINTL,;t t
+s,@CATALOGS@,$CATALOGS,;t t
+s,@CATOBJEXT@,$CATOBJEXT,;t t
+s,@DATADIRNAME@,$DATADIRNAME,;t t
+s,@GMOFILES@,$GMOFILES,;t t
+s,@INSTOBJEXT@,$INSTOBJEXT,;t t
+s,@INTLDEPS@,$INTLDEPS,;t t
+s,@INTLLIBS@,$INTLLIBS,;t t
+s,@INTLOBJS@,$INTLOBJS,;t t
+s,@POFILES@,$POFILES,;t t
+s,@POSUB@,$POSUB,;t t
+s,@INCLUDE_LOCALE_H@,$INCLUDE_LOCALE_H,;t t
+s,@GT_NO@,$GT_NO,;t t
+s,@GT_YES@,$GT_YES,;t t
+s,@MKINSTALLDIRS@,$MKINSTALLDIRS,;t t
+s,@l@,$l,;t t
+s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t
+s,@MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t
+s,@MAINT@,$MAINT,;t t
+s,@LIBM@,$LIBM,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+ cat >>$CONFIG_STATUS <<\_ACEOF
+ # Split the substitutions into bite-sized pieces for seds with
+ # small command number limits, like on Digital OSF/1 and HP-UX.
+ ac_max_sed_lines=48
+ ac_sed_frag=1 # Number of current file.
+ ac_beg=1 # First line for current file.
+ ac_end=$ac_max_sed_lines # Line after last line for current file.
+ ac_more_lines=:
+ ac_sed_cmds=
+ while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ else
+ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ fi
+ if test ! -s $tmp/subs.frag; then
+ ac_more_lines=false
+ else
+ # The purpose of the label and of the branching condition is to
+ # speed up the sed processing (if there are no `@' at all, there
+ # is no need to browse any of the substitutions).
+ # These are the two extra sed commands mentioned above.
+ (echo ':t
+ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+ fi
+ ac_sed_frag=`expr $ac_sed_frag + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_lines`
+ fi
+ done
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+ fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+ esac
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ configure_input=
+ else
+ configure_input="$ac_file. "
+ fi
+ configure_input=$configure_input"Generated from `echo $ac_file_in |
+ sed 's,.*/,,'` by configure."
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+ rm -f $tmp/stdin
+ if test x"$ac_file" != x-; then
+ mv $tmp/out $ac_file
+ else
+ cat $tmp/out
+ rm -f $tmp/out
+ fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='[ ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ # Do quote $f, to prevent DOS paths from being IFS'd.
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+ # Remove the trailing spaces.
+ sed 's/[ ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h. The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status. Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless. Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo ' :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+ # Write a limited-size here document to $tmp/defines.sed.
+ echo ' cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#define' lines.
+ echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/defines.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+ rm -f conftest.defines
+ mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo ' fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+ # Write a limited-size here document to $tmp/undefs.sed.
+ echo ' cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#undef'
+ echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+ rm -f conftest.undefs
+ mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ echo "/* Generated by configure. */" >$tmp/config.h
+ else
+ echo "/* $ac_file. Generated by configure. */" >$tmp/config.h
+ fi
+ cat $tmp/in >>$tmp/config.h
+ rm -f $tmp/in
+ if test x"$ac_file" != x-; then
+ if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+ { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ rm -f $ac_file
+ mv $tmp/config.h $ac_file
+ fi
+ else
+ cat $tmp/config.h
+ rm -f $tmp/config.h
+ fi
+# Compute $ac_file's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $ac_file | $ac_file:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
+$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X$ac_file : 'X\(//\)[^/]' \| \
+ X$ac_file : 'X\(//\)$' \| \
+ X$ac_file : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X$ac_file |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_COMMANDS section.
+#
+for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
+ ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
+ ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_dest" : 'X\(//\)[^/]' \| \
+ X"$ac_dest" : 'X\(//\)$' \| \
+ X"$ac_dest" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+ { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+echo "$as_me: executing $ac_dest commands" >&6;}
+ case $ac_dest in
+ depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # So let's grep whole file.
+ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+ dirpart=`(dirname "$mf") 2>/dev/null ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue
+ # Extract the definition of DEP_FILES from the Makefile without
+ # running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+ # We invoke sed twice because it is the simplest approach to
+ # changing $(DEPDIR) to its actual value in the expansion.
+ for file in `sed -n '
+ /^DEP_FILES = .*\\\\$/ {
+ s/^DEP_FILES = //
+ :loop
+ s/\\\\$//
+ p
+ n
+ /\\\\$/ b loop
+ p
+ }
+ /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`(dirname "$file") 2>/dev/null ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p $dirpart/$fdir
+ else
+ as_dir=$dirpart/$fdir
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
+echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+ ;;
+ default ) rm -f targ-cpu.c targ-cpu.h obj-format.h obj-format.c targ-env.h atof-targ.c itbl-cpu.h
+ echo '#include "tc-'"${target_cpu_type}"'.h"' > targ-cpu.h
+ echo '#include "obj-'"${obj_format}"'.h"' > obj-format.h
+ echo '#include "te-'"${te_file}"'.h"' > targ-env.h
+ echo '#include "itbl-'"${target_cpu_type}"'.h"' > itbl-cpu.h
+ if test "x$cgen_cpu_prefix" != x ; then
+ echo '#include "opcodes/'"${cgen_cpu_prefix}"'-desc.h"' > cgen-desc.h
+ fi
+
+ sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile ;;
+ esac
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/x/binutils/gas/configure.in b/x/binutils/gas/configure.in
new file mode 100644
index 0000000..f7d0acb
--- /dev/null
+++ b/x/binutils/gas/configure.in
@@ -0,0 +1,1084 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl
+dnl And be careful when changing it! If you must add tests with square
+dnl brackets, be sure changequote invocations surround it.
+dnl
+dnl
+dnl v2.5 needed for --bindir et al
+AC_PREREQ(2.57)
+AC_INIT(as.h)
+
+dnl Autoconf 2.57 will find the aux dir without this. However, unless
+dnl we specify this explicitly, automake-1.7 will assume that ylwrap is in
+dnl gas/ instead of gas/../.
+AC_CONFIG_AUX_DIR(..)
+AC_CANONICAL_SYSTEM
+AC_ISC_POSIX
+
+changequote(,)dnl
+BFD_VERSION=`sed -n -e 's/^.._INIT_AUTOMAKE.*,[ ]*\([^ ]*\)[ ]*).*/\1/p' < ${srcdir}/../bfd/configure.in`
+changequote([,])dnl
+AM_INIT_AUTOMAKE(gas, ${BFD_VERSION})
+
+AM_PROG_LIBTOOL
+
+user_bfd_gas=
+AC_ARG_ENABLE(bfd-assembler,
+[ --enable-bfd-assembler use BFD back end for writing object files],
+[case "${enableval}" in
+ yes) need_bfd=yes user_bfd_gas=yes ;;
+ no) user_bfd_gas=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} given for bfd-assembler option) ;;
+esac])dnl
+AC_ARG_ENABLE(targets,
+[ targets alternative target configurations besides the primary],
+[case "${enableval}" in
+ yes | "") AC_ERROR(enable-targets option must specify target names or 'all')
+ ;;
+ no) enable_targets= ;;
+ *) enable_targets=$enableval ;;
+esac])dnl
+AC_ARG_ENABLE(commonbfdlib,
+[ --enable-commonbfdlib build shared BFD/opcodes/libiberty library],
+[case "${enableval}" in
+ yes) commonbfdlib=true ;;
+ no) commonbfdlib=false ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for BFD commonbfdlib option]) ;;
+esac])dnl
+
+using_cgen=no
+
+build_warnings="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
+AC_ARG_ENABLE(build-warnings,
+[ --enable-build-warnings Enable build-time compiler warnings if gcc is used],
+[case "${enableval}" in
+ yes) ;;
+ no) build_warnings="-w";;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${build_warnings} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${t} ${build_warnings}";;
+ *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then
+ echo "Setting warning flags = $build_warnings" 6>&1
+fi])dnl
+WARN_CFLAGS=""
+if test "x${build_warnings}" != x -a "x$GCC" = xyes ; then
+ WARN_CFLAGS="${build_warnings}"
+fi
+AC_SUBST(WARN_CFLAGS)
+
+# Generate a header file
+AM_CONFIG_HEADER(config.h:config.in)
+
+# If we are on a DOS filesystem, we must use gdb.ini rather than
+# .gdbinit.
+case "${host}" in
+ *-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-windows*)
+ GDBINIT="gdb.ini"
+ AC_CONFIG_FILES(gdb.ini:gdbinit.in)
+ ;;
+ *)
+ GDBINIT=".gdbinit"
+ AC_CONFIG_FILES(.gdbinit:gdbinit.in)
+ ;;
+esac
+AC_SUBST(GDBINIT)
+
+te_file=generic
+
+# Makefile target for installing gas in $(tooldir)/bin.
+install_tooldir=install-exec-tooldir
+
+canon_targets=""
+all_targets=no
+if test -n "$enable_targets" ; then
+ for t in `echo $enable_targets | sed 's/,/ /g'`; do
+ if test $t = "all"; then
+ all_targets=yes
+ continue
+ fi
+ result=`$ac_config_sub $t 2>/dev/null`
+ if test -n "$result" ; then
+ canon_targets="$canon_targets $result"
+# else
+# # Permit "all", etc. We don't support it yet though.
+# canon_targets="$canon_targets $t"
+ fi
+ done
+ GAS_UNIQ(canon_targets)
+fi
+
+emulations=""
+
+for this_target in $target $canon_targets ; do
+
+changequote(,)dnl
+ eval `echo $this_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/cpu=\1 vendor=\2 os=\3/'`
+changequote([,])dnl
+
+ # check for architecture variants
+ arch=
+ endian=
+ case ${cpu} in
+ am33_2.0) cpu_type=mn10300 endian=little ;;
+ alpha*) cpu_type=alpha ;;
+ arm*b|xscale*b|strongarm*b) cpu_type=arm endian=big ;;
+ arm*|xscale*|strongarm*) cpu_type=arm endian=little ;;
+ c4x*) cpu_type=tic4x ;;
+ hppa*) cpu_type=hppa ;;
+changequote(,)dnl
+ i[3-7]86) cpu_type=i386 arch=i386;;
+ x86_64) cpu_type=i386 arch=x86_64;;
+ ia64) cpu_type=ia64 ;;
+ ip2k) cpu_type=ip2k endian=big ;;
+ iq2000) cpu_type=iq2000 endian=big ;;
+ m6811|m6812|m68hc12) cpu_type=m68hc11 ;;
+ m680[012346]0) cpu_type=m68k ;;
+changequote([,])dnl
+ m68008) cpu_type=m68k ;;
+ m683??) cpu_type=m68k ;;
+ m5200) cpu_type=m68k ;;
+ m8*) cpu_type=m88k ;;
+ mips*el) cpu_type=mips endian=little ;;
+ mips*) cpu_type=mips endian=big ;;
+ or32*) cpu_type=or32 endian=big ;;
+ pjl*) cpu_type=pj endian=little ;;
+ pj*) cpu_type=pj endian=big ;;
+ powerpc*le*) cpu_type=ppc endian=little ;;
+ powerpc*) cpu_type=ppc endian=big ;;
+ rs6000*) cpu_type=ppc ;;
+ s390x*) cpu_type=s390 arch=s390x ;;
+ s390*) cpu_type=s390 arch=s390 ;;
+ sh5*) cpu_type=sh64 endian=big ;;
+ sh5le*) cpu_type=sh64 endian=little ;;
+ sh64*) cpu_type=sh64 endian=big ;;
+ sh64le*) cpu_type=sh64 endian=little ;;
+ sh*le) cpu_type=sh endian=little ;;
+ sh*) cpu_type=sh endian=big ;;
+ sparclite*) cpu_type=sparc arch=sparclite ;;
+ sparclet*) cpu_type=sparc arch=sparclet ;;
+ sparc64*) cpu_type=sparc arch=v9-64 ;;
+ sparc86x*) cpu_type=sparc arch=sparc86x ;;
+ sparc*) cpu_type=sparc arch=sparclite ;; # ??? See tc-sparc.c.
+ v850*) cpu_type=v850 ;;
+ xtensa*) cpu_type=xtensa arch=xtensa ;;
+ m32r) cpu_type=m32r target_cpu=m32r endian=big ;;
+ m32rle) cpu_type=m32r target_cpu=m32r endian=little ;;
+ *) cpu_type=${cpu} ;;
+ esac
+
+ if test ${this_target} = $target ; then
+ target_cpu_type=${cpu_type}
+ elif test ${target_cpu_type} != ${cpu_type} ; then
+ continue
+ fi
+
+ generic_target=${cpu_type}-$vendor-$os
+ dev=no
+ bfd_gas=no
+ em=generic
+
+ # assign object format
+ case ${generic_target} in
+ a29k-*-coff) fmt=coff ;;
+ a29k-amd-udi) fmt=coff ;;
+ a29k-amd-ebmon) fmt=coff ;;
+ a29k-nyu-sym1) fmt=coff ;;
+ a29k-*-rtems*) fmt=coff ;;
+ a29k-*-vxworks*) fmt=coff ;;
+
+ alpha*-*-*vms*) fmt=evax ;;
+ alpha*-*-netware*) fmt=ecoff ;;
+ alpha*-*-osf*) fmt=ecoff ;;
+ alpha*-*-linuxecoff*) fmt=ecoff ;;
+ alpha*-*-linux-gnu*) fmt=elf em=linux ;;
+ alpha*-*-netbsd*) fmt=elf em=nbsd ;;
+ alpha*-*-openbsd*) fmt=elf em=obsd ;;
+
+ # cpu_type for am33_2.0 is set to mn10300
+ mn10300-*-linux*) fmt=elf bfd_gas=yes em=linux ;;
+
+ arc-*-elf*) fmt=elf ;;
+
+ arm-*-aout) fmt=aout ;;
+ arm-*-coff | thumb-*-coff) fmt=coff ;;
+ arm-*-rtems* | thumb-*-rtems*) fmt=elf ;;
+ arm-*-elf | thumb-*-elf) fmt=elf ;;
+ arm-*-kaos*) fmt=elf ;;
+ arm*-*-conix*) fmt=elf ;;
+ arm-*-linux*aout*) fmt=aout em=linux ;;
+ arm*-*-linux-gnu*) fmt=elf em=linux ;;
+ arm*-*-uclinux*) fmt=elf em=linux ;;
+ arm-*-netbsdelf*) fmt=elf em=nbsd ;;
+ arm-*-*n*bsd*) fmt=aout em=nbsd ;;
+ arm-**-nto*) fmt=elf ;;
+ arm-*-oabi | thumb-*-oabi) fmt=elf ;;
+ arm-epoc-pe | thumb-epoc-pe) fmt=coff em=epoc-pe ;;
+ arm-wince-pe | arm-*-wince) fmt=coff em=wince-pe ;;
+ arm-*-pe | thumb-*-pe) fmt=coff em=pe ;;
+ arm-*-riscix*) fmt=aout em=riscix ;;
+
+ avr-*-*) fmt=elf ;;
+
+ cris-*-linux-gnu*) fmt=multi bfd_gas=yes em=linux ;;
+ cris-*-*) fmt=multi bfd_gas=yes ;;
+
+ d10v-*-*) fmt=elf ;;
+ d30v-*-*) fmt=elf ;;
+ dlx-*-*) fmt=elf ;;
+
+ fr30-*-*) fmt=elf ;;
+ frv-*-*linux*) fmt=elf em=linux;;
+ frv-*-*) fmt=elf ;;
+
+ hppa-*-linux*) case ${cpu} in
+ hppa*64*) fmt=elf em=hppalinux64;;
+ hppa*) fmt=elf em=linux;;
+ esac ;;
+ hppa-*-*elf*) fmt=elf em=hppa ;;
+ hppa-*-lites*) fmt=elf em=hppa ;;
+ hppa-*-netbsd*) fmt=elf em=nbsd ;;
+ hppa-*-openbsd*) fmt=elf em=hppa ;;
+ hppa-*-osf*) fmt=som em=hppa ;;
+ hppa-*-rtems*) fmt=elf em=hppa ;;
+ hppa-*-hpux11*) case ${cpu} in
+ hppa*64*) fmt=elf em=hppa64 ;;
+ hppa*) fmt=som em=hppa ;;
+ esac ;;
+ hppa-*-hpux*) fmt=som em=hppa ;;
+ hppa-*-mpeix*) fmt=som em=hppa ;;
+ hppa-*-bsd*) fmt=som em=hppa ;;
+ hppa-*-hiux*) fmt=som em=hppa ;;
+
+ h8300-*-rtems*) fmt=coff ;;
+ h8300-*-coff) fmt=coff ;;
+ h8300-*-elf) fmt=elf ;;
+ h8500-*-rtems*) fmt=coff ;;
+ h8500-*-coff) fmt=coff ;;
+
+ i370-*-elf* | i370-*-linux*) fmt=elf ;;
+ i386-ibm-aix*) fmt=coff em=i386aix ;;
+ i386-sequent-bsd*) fmt=aout em=dynix ;;
+ i386-*-beospe*) fmt=coff em=pe ;;
+ i386-*-beos*) fmt=elf ;;
+ i386-*-coff) fmt=coff ;;
+ i386-*-elf) fmt=elf ;;
+ i386-*-kaos*) fmt=elf ;;
+ i386-*-bsd*) fmt=aout em=386bsd ;;
+ i386-*-netbsd0.8) fmt=aout em=386bsd ;;
+ i386-*-netbsdpe*) fmt=coff em=pe ;;
+ i386-*-netbsd*-gnu* | \
+ i386-*-knetbsd*-gnu | \
+ i386-*-netbsdelf*) fmt=elf em=nbsd ;;
+ i386-*-*n*bsd*) case ${cpu} in
+ x86_64) fmt=elf em=nbsd ;;
+ *) fmt=aout em=nbsd ;;
+ esac ;;
+ i386-*-linux*aout*) fmt=aout em=linux ;;
+ i386-*-linux*oldld) fmt=aout em=linux ;;
+ i386-*-linux*coff*) fmt=coff em=linux ;;
+ i386-*-linux-gnu*) fmt=elf em=linux ;;
+ x86_64-*-linux-gnu*) fmt=elf em=linux ;;
+ i386-*-lynxos*) fmt=coff em=lynx ;;
+changequote(,)dnl
+ i386-*-sysv[45]*) fmt=elf ;;
+ i386-*-solaris*) fmt=elf ;;
+ i386-*-freebsdaout*) fmt=aout em=386bsd ;;
+ i386-*-freebsd[12].*) fmt=aout em=386bsd ;;
+ i386-*-freebsd[12]) fmt=aout em=386bsd ;;
+changequote([,])dnl
+ i386-*-freebsd* | i386-*-kfreebsd*-gnu)
+ fmt=elf em=freebsd ;;
+ i386-*-sysv*) fmt=coff ;;
+ i386-*-sco3.2v5*coff) fmt=coff ;;
+ i386-*-isc*) fmt=coff ;;
+ i386-*-sco3.2v5*) fmt=elf
+ if test ${this_target} = $target; then
+ AC_DEFINE(SCO_ELF, 1, [Define if defaulting to ELF on SCO 5.])
+ fi ;;
+ i386-*-sco3.2*) fmt=coff ;;
+ i386-*-vsta) fmt=aout ;;
+ i386-*-msdosdjgpp* \
+ | i386-*-go32* \
+ | i386-go32-rtems*) fmt=coff em=go32
+ AC_DEFINE(STRICTCOFF, 1, [Using strict COFF?]) ;;
+ i386-*-rtemself*) fmt=elf ;;
+ i386-*-rtemscoff*) fmt=coff ;;
+ i386-*-rtems*) fmt=elf ;;
+ i386-*-gnu*) fmt=elf ;;
+ i386-*-mach*) fmt=aout em=mach ;;
+ i386-*-msdos*) fmt=aout ;;
+ i386-*-moss*) fmt=elf ;;
+ i386-*-pe) fmt=coff em=pe ;;
+ i386-*-cygwin*) fmt=coff em=pe ;;
+ i386-*-interix*) fmt=coff em=interix ;;
+ i386-*-mingw32*) fmt=coff em=pe ;;
+ i386-*-nto-qnx*) fmt=elf ;;
+ i386-*-*nt*) fmt=coff em=pe ;;
+ i386-*-chaos) fmt=elf ;;
+
+ i860-*-*) fmt=elf endian=little
+ AC_MSG_WARN(GAS support for ${generic_target} is preliminary and a work in progress) ;;
+ i960-*-bout) fmt=bout ;;
+ i960-*-coff) fmt=coff em=ic960 ;;
+ i960-*-rtems*) fmt=coff em=ic960 ;;
+ i960-*-nindy*) fmt=bout ;;
+ i960-*-vxworks5.0) fmt=bout ;;
+ i960-*-vxworks5.*) fmt=coff em=ic960 ;;
+ i960-*-vxworks*) fmt=bout ;;
+ i960-*-elf*) fmt=elf ;;
+
+ ia64-*-elf*) fmt=elf ;;
+ ia64-*-aix*) fmt=elf em=ia64aix ;;
+ ia64-*-linux-gnu*) fmt=elf em=linux ;;
+ ia64-*-hpux*) fmt=elf em=hpux ;;
+ ia64-*-netbsd*) fmt=elf em=nbsd ;;
+
+ ip2k-*-*) fmt=elf ;;
+
+ iq2000-*-elf) fmt=elf bfd_gas=yes ;;
+
+ m32r-*-elf*) fmt=elf ;;
+ m32r-*-linux*) fmt=elf em=linux;;
+
+ m68hc11-*-* | m6811-*-*) fmt=elf ;;
+ m68hc12-*-* | m6812-*-*) fmt=elf ;;
+
+ m68k-*-vxworks*) fmt=aout em=sun3 ;;
+ m68k-ericsson-ose) fmt=aout em=sun3 ;;
+ m68k-*-sunos*) fmt=aout em=sun3 ;;
+ m68k-motorola-sysv*) fmt=coff em=delta ;;
+ m68k-bull-sysv3*) fmt=coff em=dpx2 ;;
+ m68k-apollo-*) fmt=coff em=apollo ;;
+ m68k-*-elf*) fmt=elf ;;
+ m68k-*-sysv4*) fmt=elf em=svr4 ;;
+ m68k-*-sysv*) fmt=coff ;;
+ m68k-*-coff | m68k-*-rtemscoff*) fmt=coff ;;
+ m68k-*-rtems*) fmt=elf ;;
+ m68k-*-hpux*) fmt=hp300 em=hp300 ;;
+ m68k-*-linux*aout*) fmt=aout em=linux ;;
+ m68k-*-linux-gnu*) fmt=elf em=linux ;;
+ m68k-*-uclinux*) fmt=elf ;;
+ m68k-*-gnu*) fmt=elf ;;
+ m68k-*-lynxos*) fmt=coff em=lynx ;;
+ m68k-*-netbsdelf*) fmt=elf em=nbsd ;;
+ m68k-*-netbsd*) fmt=aout em=nbsd bfd_gas=yes ;;
+ m68k-*-openbsd*) fmt=aout em=nbsd bfd_gas=yes ;;
+ m68k-apple-aux*) fmt=coff em=aux ;;
+ m68k-*-psos*) fmt=elf em=psos;;
+
+ m88k-motorola-sysv3*) fmt=coff em=delt88 ;;
+ m88k-*-coff*) fmt=coff ;;
+
+ mcore-*-elf) fmt=elf ;;
+ mcore-*-pe) fmt=coff em=pe bfd_gas=yes ;;
+
+ # don't change em like *-*-bsd does
+ mips-dec-openbsd*) fmt=elf endian=little ;;
+ mips-sony-bsd*) fmt=ecoff ;;
+ mips-*-bsd*)
+ AC_MSG_ERROR(Unknown vendor for mips-bsd configuration.) ;;
+ mips-*-ultrix*) fmt=ecoff endian=little ;;
+ mips-*-osf*) fmt=ecoff endian=little ;;
+ mips-*-ecoff*) fmt=ecoff ;;
+ mips-*-pe*) fmt=coff endian=little em=pe ;;
+ mips-*-irix6*) fmt=elf em=irix ;;
+ mips-*-irix5*) fmt=elf em=irix ;;
+ mips-*-irix*) fmt=ecoff em=irix ;;
+ mips-*-lnews*) fmt=ecoff em=lnews ;;
+ mips-*-riscos*) fmt=ecoff ;;
+ mips*-*-linux*) fmt=elf em=tmips ;;
+ mips-*-sysv4*MP* | mips-*-gnu*) fmt=elf em=tmips ;;
+ mips-*-sysv*) fmt=ecoff ;;
+ mips-*-elf* | mips-*-rtems*) fmt=elf ;;
+ mips-*-netbsd*) fmt=elf ;;
+ mips-*-openbsd*) fmt=elf ;;
+
+ mmix-*-*) fmt=elf ;;
+ mn10200-*-*) fmt=elf ;;
+ mn10300-*-*) fmt=elf ;;
+ msp430-*-*) fmt=elf ;;
+ openrisc-*-*) fmt=elf ;;
+ or32-*-rtems*) fmt=elf ;;
+ or32-*-coff) fmt=coff ;;
+ or32-*-elf) fmt=elf ;;
+ pj*) fmt=elf ;;
+
+ ppc-*-pe | ppc-*-cygwin*) fmt=coff em=pe ;;
+ ppc-*-winnt*) fmt=coff em=pe ;;
+changequote(,)dnl
+ ppc-*-aix5.[01]) fmt=coff em=aix5 ;;
+changequote([,])dnl
+ ppc-*-aix5.*) fmt=coff em=aix5
+ AC_DEFINE(AIX_WEAK_SUPPORT, 1,
+ [Define if using AIX 5.2 value for C_WEAKEXT.])
+ ;;
+ ppc-*-aix*) fmt=coff ;;
+ ppc-*-beos*) fmt=coff ;;
+ ppc-*-*n*bsd* | ppc-*-elf*) fmt=elf ;;
+ ppc-*-eabi* | ppc-*-sysv4*) fmt=elf ;;
+ ppc-*-linux-gnu*) fmt=elf em=linux
+ case "$endian" in
+ big) ;;
+ *) AC_MSG_ERROR(GNU/Linux must be configured big endian) ;;
+ esac ;;
+ ppc-*-solaris*) fmt=elf
+ if test ${this_target} = $target; then
+ AC_DEFINE(TARGET_SOLARIS_COMMENT, 1,
+ [Define if default target is PowerPC Solaris.])
+ fi
+ if test x${endian} = xbig; then
+ AC_MSG_ERROR(Solaris must be configured little endian)
+ fi ;;
+ ppc-*-rtems*) fmt=elf ;;
+ ppc-*-macos* | ppc-*-mpw*) fmt=coff em=macos ;;
+ ppc-*-netware*) fmt=elf em=ppcnw ;;
+ ppc-**-nto*) fmt=elf ;;
+ ppc-*-kaos*) fmt=elf ;;
+
+ s390x-*-linux-gnu*) fmt=elf em=linux ;;
+ s390-*-linux-gnu*) fmt=elf em=linux ;;
+
+ sh*-*-linux*) fmt=elf em=linux
+ case ${cpu} in
+ sh*eb) endian=big ;;
+ *) endian=little ;;
+ esac ;;
+ sh5*-*-netbsd*) fmt=elf em=nbsd ;;
+ sh64*-*-netbsd*) fmt=elf em=nbsd ;;
+ sh*-*-netbsdelf*) fmt=elf em=nbsd ;;
+ sh-*-elf*) fmt=elf ;;
+ sh-*-coff*) fmt=coff ;;
+ sh-*-nto*) fmt=elf ;;
+ sh-*-pe*) fmt=coff em=pe bfd_gas=yes endian=little ;;
+ sh-*-rtemscoff*) fmt=coff ;;
+ sh-*-rtems*) fmt=elf ;;
+ sh-*-kaos*) fmt=elf ;;
+ shle*-*-kaos*) fmt=elf ;;
+ sh64-*-elf*) fmt=elf ;;
+
+ ns32k-pc532-mach*) fmt=aout em=pc532mach ;;
+ ns32k-pc532-ux*) fmt=aout em=pc532mach ;;
+ ns32k-pc532-lites*) fmt=aout em=nbsd532 ;;
+ ns32k-*-*n*bsd*) fmt=aout em=nbsd532 ;;
+
+ sparc-*-rtemsaout*) fmt=aout ;;
+ sparc-*-rtemself*) fmt=elf ;;
+ sparc-*-rtems*) fmt=elf ;;
+ sparc-*-sunos4*) fmt=aout em=sun3 ;;
+ sparc-*-aout | sparc*-*-vxworks*) fmt=aout em=sparcaout ;;
+ sparc-*-coff) fmt=coff ;;
+ sparc-*-linux*aout*) fmt=aout em=linux ;;
+ sparc-*-linux-gnu*) fmt=elf em=linux ;;
+ sparc-*-lynxos*) fmt=coff em=lynx ;;
+ sparc-fujitsu-none) fmt=aout ;;
+ sparc-*-elf) fmt=elf ;;
+ sparc-*-sysv4*) fmt=elf ;;
+ sparc-*-solaris*) fmt=elf ;;
+ sparc-*-netbsdelf*) fmt=elf em=nbsd ;;
+ sparc-*-*n*bsd*) case ${cpu} in
+ sparc64) fmt=elf em=nbsd ;;
+ *) fmt=aout em=nbsd ;;
+ esac ;;
+ strongarm-*-coff) fmt=coff ;;
+ strongarm-*-elf) fmt=elf ;;
+ strongarm-*-kaos*) fmt=elf ;;
+ xscale-*-coff) fmt=coff ;;
+ xscale-*-elf) fmt=elf ;;
+
+ tic30-*-*aout*) fmt=aout bfd_gas=yes ;;
+ tic30-*-*coff*) fmt=coff bfd_gas=yes ;;
+ tic4x-*-* | c4x-*-*) fmt=coff bfd_gas=yes ;;
+ tic54x-*-* | c54x*-*-*) fmt=coff bfd_gas=yes need_libm=yes;;
+ tic80-*-*) fmt=coff ;;
+
+ v850-*-*) fmt=elf ;;
+ v850e-*-*) fmt=elf ;;
+ v850ea-*-*) fmt=elf ;;
+
+ vax-*-netbsdelf*) fmt=elf em=nbsd ;;
+ vax-*-netbsd*) fmt=aout em=nbsd ;;
+ vax-*-bsd* | vax-*-ultrix*) fmt=aout ;;
+ vax-*-linux-gnu*) fmt=elf em=linux bfd_gas=yes ;;
+ vax-*-vms) fmt=vms ;;
+
+ w65-*-*) fmt=coff ;;
+
+ xstormy16-*-*) fmt=elf ;;
+
+ xtensa-*-*) fmt=elf ;;
+
+ z8k-*-coff | z8k-*-sim) fmt=coff ;;
+
+ *-*-aout | *-*-scout) fmt=aout ;;
+ *-*-freebsd* | *-*-kfreebsd*-gnu) fmt=elf em=freebsd ;;
+ *-*-nindy*) fmt=bout ;;
+ *-*-bsd*) fmt=aout em=sun3 ;;
+ *-*-generic) fmt=generic ;;
+ *-*-xray | *-*-hms) fmt=coff ;;
+ *-*-sim) fmt=coff ;;
+ *-*-elf | *-*-sysv4* | *-*-solaris*) fmt=elf dev=yes ;;
+ *-*-aros*) fmt=elf em=linux bfd_gas=yes ;;
+ *-*-vxworks | *-*-windiss) fmt=elf ;;
+ *-*-netware) fmt=elf ;;
+ esac
+
+ if test ${this_target} = $target ; then
+ endian_def=
+ if test x${endian} = xbig; then
+ endian_def=1
+ elif test x${endian} = xlittle; then
+ endian_def=0
+ fi
+ if test x${endian_def} != x; then
+ AC_DEFINE_UNQUOTED(TARGET_BYTES_BIG_ENDIAN, $endian_def,
+ [Define as 1 if big endian.])
+ fi
+ fi
+
+ case ${cpu_type}-${fmt} in
+ alpha*-* | arm-* | i386-* | ia64*-* | mips-* | ns32k-* \
+ | pdp11-* | ppc-* | sparc-* | strongarm-* | xscale-* \
+ | *-elf | *-ecoff | *-som)
+ bfd_gas=yes ;;
+ esac
+
+# Other random stuff.
+
+ case ${cpu_type} in
+ mips)
+ # Set mips_cpu to the name of the default CPU.
+ case ${target_cpu} in
+ mips | mipsbe | mipseb | mipsle | mipsel | mips64 | mips64el)
+ mips_cpu=from-abi
+ ;;
+ mipsisa32 | mipsisa32el)
+ mips_cpu=mips32
+ ;;
+ mipsisa32r2 | mipsisa32r2el)
+ mips_cpu=mips32r2
+ ;;
+ mipsisa64 | mipsisa64el)
+ mips_cpu=mips64
+ ;;
+ mipsisa64r2 | mipsisa64r2el)
+ mips_cpu=mips64r2
+ ;;
+ mipstx39 | mipstx39el)
+ mips_cpu=r3900
+ ;;
+ mips64vr | mips64vrel)
+ mips_cpu=vr4100
+ ;;
+ mipsisa32r2* | mipsisa64r2*)
+changequote(,)dnl
+ mips_cpu=`echo $target_cpu | sed -e 's/[a-z]*..r2//' -e 's/el$//'`
+changequote([,])dnl
+ ;;
+ mips64* | mipsisa64* | mipsisa32*)
+changequote(,)dnl
+ mips_cpu=`echo $target_cpu | sed -e 's/[a-z]*..//' -e 's/el$//'`
+changequote([,])dnl
+ ;;
+ *)
+ AC_ERROR($target_cpu isn't a supported MIPS CPU name)
+ ;;
+ esac
+ # See whether it's appropriate to set E_MIPS_ABI_O32 for o32
+ # binaries. It's a GNU extension that some OSes don't understand.
+ # The value only matters on ELF targets.
+ case ${target} in
+ *-*-irix*)
+ use_e_mips_abi_o32=0
+ ;;
+ *)
+ use_e_mips_abi_o32=1
+ ;;
+ esac
+ # Decide whether to generate 32-bit or 64-bit code by default.
+ # Used to resolve -march=from-abi when an embedded ABI is selected.
+ case ${target} in
+ mips64*-*-* | mipsisa64*-*-*)
+ mips_default_64bit=1
+ ;;
+ *)
+ mips_default_64bit=0
+ ;;
+ esac
+ # Decide which ABI to target by default.
+ case ${target} in
+ mips64*-linux* | mips-sgi-irix6*)
+ mips_default_abi=N32_ABI
+ ;;
+ mips*-linux*)
+ mips_default_abi=O32_ABI
+ ;;
+ *)
+ mips_default_abi=NO_ABI
+ ;;
+ esac
+ AC_DEFINE_UNQUOTED(MIPS_CPU_STRING_DEFAULT, "$mips_cpu",
+ [Default CPU for MIPS targets. ])
+ AC_DEFINE_UNQUOTED(USE_E_MIPS_ABI_O32, $use_e_mips_abi_o32,
+ [Allow use of E_MIPS_ABI_O32 on MIPS targets. ])
+ AC_DEFINE_UNQUOTED(MIPS_DEFAULT_64BIT, $mips_default_64bit,
+ [Generate 64-bit code by default on MIPS targets. ])
+ AC_DEFINE_UNQUOTED(MIPS_DEFAULT_ABI, $mips_default_abi,
+ [Choose a default ABI for MIPS targets. ])
+ ;;
+ esac
+
+ # Do we need the opcodes library?
+ case ${cpu_type} in
+ vax | i386 | tic30)
+ ;;
+
+ *)
+ need_opcodes=yes
+
+ case "${enable_shared}" in
+ yes) shared_opcodes=true ;;
+ *opcodes*) shared_opcodes=true ;;
+ *) shared_opcodes=false ;;
+ esac
+ if test "${shared_opcodes}" = "true"; then
+ # A shared libopcodes must be linked against libbfd.
+ need_bfd=yes
+ fi
+ ;;
+ esac
+
+ # Any other special object files needed ?
+ case ${cpu_type} in
+ fr30 | ip2k | iq2000 | m32r | openrisc)
+ using_cgen=yes
+ ;;
+
+ frv)
+ using_cgen=yes
+ ;;
+ m68k)
+ case ${extra_objects} in
+ *m68k-parse.o*) ;;
+ *) extra_objects="$extra_objects m68k-parse.o" ;;
+ esac
+ ;;
+
+ mips)
+ echo ${extra_objects} | grep -s "itbl-parse.o"
+ if test $? -ne 0 ; then
+ extra_objects="$extra_objects itbl-parse.o"
+ fi
+
+ echo ${extra_objects} | grep -s "itbl-lex.o"
+ if test $? -ne 0 ; then
+ extra_objects="$extra_objects itbl-lex.o"
+ fi
+
+ echo ${extra_objects} | grep -s "itbl-ops.o"
+ if test $? -ne 0 ; then
+ extra_objects="$extra_objects itbl-ops.o"
+ fi
+ ;;
+
+ i386 | s390 | sparc)
+ if test $this_target = $target ; then
+ AC_DEFINE_UNQUOTED(DEFAULT_ARCH, "${arch}", [Default architecture.])
+ fi
+ ;;
+
+ xstormy16)
+ using_cgen=yes
+ ;;
+
+ xtensa)
+ echo ${extra_objects} | grep -s "xtensa-relax.o"
+ if test $? -ne 0 ; then
+ extra_objects="$extra_objects xtensa-relax.o"
+ fi
+ ;;
+
+ *)
+ ;;
+ esac
+
+ if test $using_cgen = yes ; then
+ case "x${extra_objects}" in
+ *cgen.o*) ;;
+ *) extra_objects="$extra_objects cgen.o" ;;
+ esac
+ fi
+
+# See if we really can support this configuration with the emulation code.
+
+ if test $this_target = $target ; then
+ primary_bfd_gas=$bfd_gas
+ obj_format=$fmt
+ te_file=$em
+
+ if test $bfd_gas = no ; then
+ # Can't support other configurations this way.
+ break
+ fi
+ elif test $bfd_gas = no ; then
+ # Can't support this configuration.
+ break
+ fi
+
+# From target name and format, produce a list of supported emulations.
+
+ case ${generic_target}-${fmt} in
+ mips-*-irix5*-*) emulation="mipsbelf mipslelf mipself mipsbecoff mipslecoff mipsecoff" ;;
+ mips*-*-linux*-*) case "$endian" in
+ big) emulation="mipsbelf mipslelf mipself" ;;
+ *) emulation="mipslelf mipsbelf mipself" ;;
+ esac ;;
+ mips-*-lnews*-ecoff) ;;
+ mips-*-*-ecoff) case "$endian" in
+ big) emulation="mipsbecoff mipslecoff mipsecoff" ;;
+ *) emulation="mipslecoff mipsbecoff mipsecoff" ;;
+ esac ;;
+ mips-*-*-elf) case "$endian" in
+ big) emulation="mipsbelf mipslelf mipself" ;;
+ *) emulation="mipslelf mipsbelf mipself" ;;
+ esac ;;
+ mips-*-sysv4*MP*-*) emulation="mipsbelf mipslelf mipself mipsbecoff mipslecoff mipsecoff" ;;
+ # i386-pc-pe-coff != i386-pc-coff.
+ i386-*-pe-coff) ;;
+ # Uncommenting the next line will turn on support for i386 AOUT
+ # for the default linux configuration
+ # i386-*-linux*-elf) emulation="i386elf i386aout" ;;
+ #
+ i386-*-aout) emulation="i386aout" ;;
+ i386-*-coff) emulation="i386coff" ;;
+ i386-*-elf) emulation="i386elf" ;;
+
+ # Always all formats. The first stated emulation becomes the default.
+ cris-*-*aout*) emulation="crisaout criself" ;;
+ cris-*-*) emulation="criself crisaout" ;;
+ esac
+
+ emulations="$emulations $emulation"
+
+done
+
+# Turn on all targets if possible
+if test ${all_targets} = "yes"; then
+ case ${target_cpu_type} in
+ i386)
+ case ${obj_format} in
+ aout)
+ emulations="$emulations i386coff i386elf"
+ ;;
+ coff)
+ emulations="$emulations i386aout i386elf"
+ ;;
+ elf)
+ emulations="$emulations i386aout i386coff"
+ ;;
+ esac
+ ;;
+ esac
+fi
+
+# Assign floating point type. Most processors with FP support
+# IEEE FP. On those that don't support FP at all, usually IEEE
+# is emulated.
+case ${target_cpu} in
+ vax | tahoe ) atof=${target_cpu} ;;
+ pdp11) atof=vax ;;
+ *) atof=ieee ;;
+esac
+
+case "${obj_format}" in
+ "") AC_MSG_ERROR(GAS does not know what format to use for target ${target}) ;;
+esac
+
+# Unfortunately the cpu in cpu-opc.h file isn't always $(TARGET_CPU).
+cgen_cpu_prefix=""
+if test $using_cgen = yes ; then
+ case ${target_cpu} in
+ *) cgen_cpu_prefix=${target_cpu} ;;
+ esac
+ AC_SUBST(cgen_cpu_prefix)
+ AC_DEFINE(USING_CGEN, 1, [Using cgen code?])
+fi
+
+dnl
+dnl Make sure the desired support files exist.
+dnl
+
+if test ! -r ${srcdir}/config/tc-${target_cpu_type}.c; then
+ AC_MSG_ERROR(GAS does not support target CPU ${target_cpu_type})
+fi
+
+if test ! -r ${srcdir}/config/obj-${obj_format}.c; then
+ AC_MSG_ERROR(GAS does not have support for object file format ${obj_format})
+fi
+
+case ${user_bfd_gas}-${primary_bfd_gas} in
+ yes-yes | no-no)
+ # We didn't override user's choice.
+ ;;
+ no-yes)
+ AC_MSG_WARN(Use of BFD is required for ${target}; overriding config options.)
+ ;;
+ no-preferred)
+ primary_bfd_gas=no
+ ;;
+ *-preferred)
+ primary_bfd_gas=yes
+ ;;
+ yes-*)
+ primary_bfd_gas=yes
+ ;;
+ -*)
+ # User specified nothing.
+ ;;
+esac
+
+# Some COFF configurations want these random other flags set.
+case ${obj_format} in
+ coff)
+ case ${target_cpu_type} in
+ i386) AC_DEFINE(I386COFF, 1, [Using i386 COFF?]) ;;
+ m68k) AC_DEFINE(M68KCOFF, 1, [Using m68k COFF?]) ;;
+ m88k) AC_DEFINE(M88KCOFF, 1, [Using m88k COFF?]) ;;
+ esac
+ ;;
+esac
+
+# Getting this done right is going to be a bitch. Each configuration specified
+# with --enable-targets=... should be checked for environment, format, cpu, and
+# bfd_gas setting.
+#
+# For each configuration, the necessary object file support code must be linked
+# in. This might be only one, it might be up to four. The necessary emulation
+# code needs to be provided, too.
+#
+# And then there's "--enable-targets=all"....
+#
+# For now, just always do it for MIPS ELF or ECOFF configurations. Sigh.
+
+formats="${obj_format}"
+emfiles=""
+EMULATIONS=""
+GAS_UNIQ(emulations)
+for em in . $emulations ; do
+ case $em in
+ .) continue ;;
+ mipsbelf | mipslelf | mipself)
+ fmt=elf file=mipself ;;
+ mipsbecoff | mipslecoff | mipsecoff)
+ fmt=ecoff file=mipsecoff ;;
+ *coff)
+ fmt=coff file=$em ;;
+ *aout)
+ fmt=aout file=$em ;;
+ *elf)
+ fmt=elf file=$em ;;
+ esac
+ formats="$formats $fmt"
+ emfiles="$emfiles e-$file.o"
+ EMULATIONS="$EMULATIONS &$em,"
+done
+GAS_UNIQ(formats)
+GAS_UNIQ(emfiles)
+if test `set . $formats ; shift ; echo $#` -gt 1 ; then
+ for fmt in $formats ; do
+ case $fmt in
+ aout) AC_DEFINE(OBJ_MAYBE_AOUT, 1, [a.out support?]) ;;
+ bout) AC_DEFINE(OBJ_MAYBE_BOUT, 1, [b.out support?]) ;;
+ coff) AC_DEFINE(OBJ_MAYBE_COFF, 1, [COFF support?]) ;;
+ ecoff) AC_DEFINE(OBJ_MAYBE_ECOFF, 1, [ECOFF support?]) ;;
+ elf) AC_DEFINE(OBJ_MAYBE_ELF, 1, [ELF support?]) ;;
+ generic) AC_DEFINE(OBJ_MAYBE_GENERIC, 1, [generic support?]) ;;
+ hp300) AC_DEFINE(OBJ_MAYBE_HP300, 1, [HP300 support?]) ;;
+ ieee) AC_DEFINE(OBJ_MAYBE_IEEE, 1, [IEEE support?]) ;;
+ som) AC_DEFINE(OBJ_MAYBE_SOM, 1, [SOM support?]) ;;
+ vms) AC_DEFINE(OBJ_MAYBE_VMS, 1, [VMS support?]) ;;
+ esac
+ extra_objects="$extra_objects obj-$fmt.o"
+ done
+ obj_format=multi
+fi
+if test `set . $emfiles ; shift ; echo $#` -gt 0 ; then
+ DEFAULT_EMULATION=`set . $emulations ; echo $2`
+ # e-mips* has more than one emulation per file, e-i386* has just one at the
+ # moment. If only one emulation is specified, then don't define
+ # USE_EMULATIONS or include any of the e-files as they will only be bloat.
+ case "${obj_format}${emfiles}" in
+ multi* | *mips*)
+ extra_objects="$extra_objects $emfiles"
+ AC_DEFINE(USE_EMULATIONS, 1, [Use emulation support?]) ;;
+ esac
+fi
+AC_SUBST(extra_objects)
+AC_DEFINE_UNQUOTED(EMULATIONS, $EMULATIONS, [Supported emulations.])
+AC_DEFINE_UNQUOTED(DEFAULT_EMULATION, "$DEFAULT_EMULATION",
+ [Default emulation.])
+
+case ${primary_bfd_gas}-${target_cpu_type}-${obj_format} in
+ yes-*-coff) need_bfd=yes ;;
+ no-*-coff) need_bfd=yes
+ AC_DEFINE(MANY_SEGMENTS, 1, [old COFF support?]) ;;
+esac
+
+reject_dev_configs=yes
+
+case ${reject_dev_configs}-${dev} in
+ yes-yes) # Oops.
+ AC_MSG_ERROR(GAS does not support the ${generic_target} configuration.)
+ ;;
+esac
+
+AC_SUBST(target_cpu_type)
+AC_SUBST(obj_format)
+AC_SUBST(te_file)
+AC_SUBST(install_tooldir)
+AC_SUBST(atof)
+dnl AC_SUBST(emulation)
+
+case "${primary_bfd_gas}" in
+ yes) AC_DEFINE(BFD_ASSEMBLER, 1, [Use BFD interface?])
+ need_bfd=yes ;;
+esac
+
+# do we need the opcodes library?
+case "${need_opcodes}" in
+yes)
+ OPCODES_LIB=../opcodes/libopcodes.la
+ ;;
+esac
+
+case "${need_bfd}" in
+yes)
+ BFDLIB=../bfd/libbfd.la
+ BFDVER_H=../bfd/bfdver.h
+ ALL_OBJ_DEPS="$ALL_OBJ_DEPS"' ../bfd/bfd.h $(INCDIR)/symcat.h'
+ ;;
+esac
+
+AC_SUBST(BFDLIB)
+AC_SUBST(OPCODES_LIB)
+
+AC_SUBST(BFDVER_H)
+AC_SUBST(ALL_OBJ_DEPS)
+
+AC_DEFINE_UNQUOTED(TARGET_ALIAS, "${target_alias}", [Target alias.])
+AC_DEFINE_UNQUOTED(TARGET_CANONICAL, "${target}", [Canonical target.])
+AC_DEFINE_UNQUOTED(TARGET_CPU, "${target_cpu}", [Target CPU.])
+AC_DEFINE_UNQUOTED(TARGET_VENDOR, "${target_vendor}", [Target vendor.])
+AC_DEFINE_UNQUOTED(TARGET_OS, "${target_os}", [Target OS.])
+
+AC_PROG_CC
+
+AC_PROG_YACC
+AM_PROG_LEX
+
+ALL_LINGUAS="fr tr es"
+CY_GNU_GETTEXT
+
+AM_MAINTAINER_MODE
+AC_EXEEXT
+
+AC_CHECK_HEADERS(string.h stdlib.h memory.h strings.h unistd.h stdarg.h varargs.h errno.h sys/types.h)
+
+# Put this here so that autoconf's "cross-compiling" message doesn't confuse
+# people who are not cross-compiling but are compiling cross-assemblers.
+AC_MSG_CHECKING(whether compiling a cross-assembler)
+if test "${host}" = "${target}"; then
+ cross_gas=no
+else
+ cross_gas=yes
+ AC_DEFINE(CROSS_COMPILE, 1, [Compiling cross-assembler?])
+fi
+AC_MSG_RESULT($cross_gas)
+
+dnl ansidecl.h will deal with const
+dnl AC_CONST
+AC_FUNC_ALLOCA
+AC_C_INLINE
+
+# VMS doesn't have unlink.
+AC_CHECK_FUNCS(unlink remove, break)
+
+# Some systems don't have sbrk().
+AC_CHECK_FUNCS(sbrk)
+
+# do we need the math library?
+case "${need_libm}" in
+yes)
+ AC_CHECK_LIBM
+ AC_SUBST(LIBM)
+ ;;
+esac
+
+# Some non-ANSI preprocessors botch requoting inside strings. That's bad
+# enough, but on some of those systems, the assert macro relies on requoting
+# working properly!
+GAS_WORKING_ASSERT
+
+# On some systems, the system header files may not declare malloc, realloc,
+# and free. There are places where gas needs these functions to have been
+# declared -- such as when taking their addresses.
+gas_test_headers="
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+"
+GAS_CHECK_DECL_NEEDED(strstr, f, char *(*f)(), $gas_test_headers)
+GAS_CHECK_DECL_NEEDED(malloc, f, char *(*f)(), $gas_test_headers)
+GAS_CHECK_DECL_NEEDED(free, f, void (*f)(), $gas_test_headers)
+GAS_CHECK_DECL_NEEDED(sbrk, f, char *(*f)(), $gas_test_headers)
+GAS_CHECK_DECL_NEEDED(environ, f, char **f, $gas_test_headers)
+
+# Does errno.h declare errno, or do we have to add a separate declaration
+# for it?
+GAS_CHECK_DECL_NEEDED(errno, f, int f, [
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+])
+
+dnl This must come last.
+
+dnl We used to make symlinks to files in the source directory, but now
+dnl we just use the right name for .c files, and create .h files in
+dnl the build directory which include the right .h file. Make sure
+dnl the old symlinks don't exist, so that a reconfigure in an existing
+dnl directory behaves reasonably.
+
+AC_CONFIG_FILES(Makefile doc/Makefile po/Makefile.in:po/Make-in)
+AC_CONFIG_COMMANDS([default],
+[rm -f targ-cpu.c targ-cpu.h obj-format.h obj-format.c targ-env.h atof-targ.c itbl-cpu.h
+ echo '#include "tc-'"${target_cpu_type}"'.h"' > targ-cpu.h
+ echo '#include "obj-'"${obj_format}"'.h"' > obj-format.h
+ echo '#include "te-'"${te_file}"'.h"' > targ-env.h
+ echo '#include "itbl-'"${target_cpu_type}"'.h"' > itbl-cpu.h
+ if test "x$cgen_cpu_prefix" != x ; then
+ echo '#include "opcodes/'"${cgen_cpu_prefix}"'-desc.h"' > cgen-desc.h
+ fi
+
+ sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile],
+[target_cpu_type=${target_cpu_type}
+ cgen_cpu_prefix=${cgen_cpu_prefix}
+ obj_format=${obj_format}
+ te_file=${te_file}])
+
+AC_OUTPUT
diff --git a/x/binutils/gas/debug.c b/x/binutils/gas/debug.c
new file mode 100644
index 0000000..7d10387
--- /dev/null
+++ b/x/binutils/gas/debug.c
@@ -0,0 +1,104 @@
+/* This file is debug.c
+ Copyright 1987, 1988, 1989, 1990, 1991, 1992, 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Routines for debug use only. */
+
+#include "as.h"
+#include "subsegs.h"
+
+dmp_frags ()
+{
+ frchainS *chp;
+ char *p;
+
+ for (chp = frchain_root; chp; chp = chp->frch_next)
+ {
+ switch (chp->frch_seg)
+ {
+ case SEG_DATA:
+ p = "Data";
+ break;
+ case SEG_TEXT:
+ p = "Text";
+ break;
+ default:
+ p = "???";
+ break;
+ }
+ printf ("\nSEGMENT %s %d\n", p, chp->frch_subseg);
+ dmp_frag (chp->frch_root, "\t");
+ }
+}
+
+dmp_frag (fp, indent)
+ struct frag *fp;
+ char *indent;
+{
+ for (; fp; fp = fp->fr_next)
+ {
+ printf ("%sFRAGMENT @ 0x%x\n", indent, fp);
+ switch (fp->fr_type)
+ {
+ case rs_align:
+ printf ("%srs_align(%d)\n", indent, fp->fr_offset);
+ break;
+ case rs_fill:
+ printf ("%srs_fill(%d)\n", indent, fp->fr_offset);
+ printf ("%s", indent);
+ var_chars (fp, fp->fr_var + fp->fr_fix);
+ printf ("%s\t repeated %d times,", indent, fp->fr_offset);
+ printf (" fixed length if # chars == 0)\n");
+ break;
+ case rs_org:
+ printf ("%srs_org(%d+sym @0x%x)\n", indent,
+ fp->fr_offset, fp->fr_symbol);
+ printf ("%sfill with ", indent);
+ var_chars (fp, 1);
+ printf ("\n");
+ break;
+ case rs_machine_dependent:
+ printf ("%smachine_dep\n", indent);
+ break;
+ default:
+ printf ("%sunknown type\n", indent);
+ break;
+ }
+ printf ("%saddr=%d(0x%x)\n", indent, fp->fr_address, fp->fr_address);
+ printf ("%sfr_fix=%d\n", indent, fp->fr_fix);
+ printf ("%sfr_var=%d\n", indent, fp->fr_var);
+ printf ("%sfr_offset=%d\n", indent, fp->fr_offset);
+ printf ("%schars @ 0x%x\n", indent, fp->fr_literal);
+ printf ("\n");
+ }
+}
+
+var_chars (fp, n)
+ struct frag *fp;
+ int n;
+{
+ unsigned char *p;
+
+ for (p = (unsigned char *) fp->fr_literal; n; n--, p++)
+ {
+ printf ("%02x ", *p);
+ }
+}
+
+/* end of debug.c */
diff --git a/x/binutils/gas/dep-in.sed b/x/binutils/gas/dep-in.sed
new file mode 100644
index 0000000..2e2717c
--- /dev/null
+++ b/x/binutils/gas/dep-in.sed
@@ -0,0 +1,53 @@
+:loop
+/\\$/N
+/\\$/b loop
+
+s! \.\./! !g
+s!@INCDIR@!$(INCDIR)!g
+s!@TOPDIR@/include!$(INCDIR)!g
+s!@BFDDIR@!$(BFDDIR)!g
+s!@TOPDIR@/bfd!$(BFDDIR)!g
+s!@SRCDIR@/config!$(srcdir)/config!g
+s!@SRCDIR@/\.\./opcodes!$(srcdir)/../opcodes!g
+s!@TOPDIR@/opcodes!$(srcdir)/../opcodes!g
+s!@SRCDIR@/!!g
+s!\.\./bfd/bfdver\.h!$(BFDVER_H)!g
+s! \$(srcdir)/config/te-generic\.h!!g
+s! \.\./bfd/bfd\.h!!g
+s! itbl-cpu\.h!!g
+s! itbl-parse\.h!!g
+s! \.\./intl/libintl\.h!!g
+
+s! \$(INCDIR)/bin-bugs\.h!!g
+s! \$(INCDIR)/ansidecl\.h!!g
+s! \$(INCDIR)/libiberty\.h!!g
+s! \$(INCDIR)/progress\.h!!g
+s! \$(INCDIR)/fopen-[^ ]*\.h!!g
+s! obj-format\.h!!g
+s! targ-cpu\.h!!g
+s! targ-env\.h!!g
+s! as\.h!!g
+s! asintl\.h!!g
+s! bignum\.h!!g
+s! bit_fix\.h!!g
+s! config\.h!!g
+s! emul\.h!!g
+s! expr\.h!!g
+s! flonum\.h!!g
+s! frags\.h!!g
+s! hash\.h!!g
+s! listing\.h!!g
+s! obj\.h!!g
+s! read\.h!!g
+s! symbols\.h!!g
+s! tc\.h!!g
+s! write\.h!!g
+
+s/\\\n */ /g
+
+s/ *$//
+s/ */ /g
+/:$/d
+
+s/\(.\{50\}[^ ]*\) /\1 \\\
+ /g
diff --git a/x/binutils/gas/depend.c b/x/binutils/gas/depend.c
new file mode 100644
index 0000000..127c819
--- /dev/null
+++ b/x/binutils/gas/depend.c
@@ -0,0 +1,206 @@
+/* depend.c - Handle dependency tracking.
+ Copyright 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+
+/* The file to write to, or NULL if no dependencies being kept. */
+static char * dep_file = NULL;
+
+struct dependency
+ {
+ char * file;
+ struct dependency * next;
+ };
+
+/* All the files we depend on. */
+static struct dependency * dep_chain = NULL;
+
+/* Current column in output file. */
+static int column = 0;
+
+static int quote_string_for_make (FILE *, char *);
+static void wrap_output (FILE *, char *, int);
+
+/* Number of columns allowable. */
+#define MAX_COLUMNS 72
+
+/* Start saving dependencies, to be written to FILENAME. If this is
+ never called, then dependency tracking is simply skipped. */
+
+void
+start_dependencies (char *filename)
+{
+ dep_file = filename;
+}
+
+/* Noticed a new filename, so try to register it. */
+
+void
+register_dependency (char *filename)
+{
+ struct dependency *dep;
+
+ if (dep_file == NULL)
+ return;
+
+ for (dep = dep_chain; dep != NULL; dep = dep->next)
+ {
+ if (!strcmp (filename, dep->file))
+ return;
+ }
+
+ dep = (struct dependency *) xmalloc (sizeof (struct dependency));
+ dep->file = xstrdup (filename);
+ dep->next = dep_chain;
+ dep_chain = dep;
+}
+
+/* Quote a file name the way `make' wants it, and print it to FILE.
+ If FILE is NULL, do no printing, but return the length of the
+ quoted string.
+
+ This code is taken from gcc with only minor changes. */
+
+static int
+quote_string_for_make (FILE *file, char *src)
+{
+ char *p = src;
+ int i = 0;
+
+ for (;;)
+ {
+ char c = *p++;
+
+ switch (c)
+ {
+ case '\0':
+ case ' ':
+ case '\t':
+ {
+ /* GNU make uses a weird quoting scheme for white space.
+ A space or tab preceded by 2N+1 backslashes represents
+ N backslashes followed by space; a space or tab
+ preceded by 2N backslashes represents N backslashes at
+ the end of a file name; and backslashes in other
+ contexts should not be doubled. */
+ char *q;
+
+ for (q = p - 1; src < q && q[-1] == '\\'; q--)
+ {
+ if (file)
+ putc ('\\', file);
+ i++;
+ }
+ }
+ if (!c)
+ return i;
+ if (file)
+ putc ('\\', file);
+ i++;
+ goto ordinary_char;
+
+ case '$':
+ if (file)
+ putc (c, file);
+ i++;
+ /* Fall through. This can mishandle things like "$(" but
+ there's no easy fix. */
+ default:
+ ordinary_char:
+ /* This can mishandle characters in the string "\0\n%*?[\\~";
+ exactly which chars are mishandled depends on the `make' version.
+ We know of no portable solution for this;
+ even GNU make 3.76.1 doesn't solve the problem entirely.
+ (Also, '\0' is mishandled due to our calling conventions.) */
+ if (file)
+ putc (c, file);
+ i++;
+ break;
+ }
+ }
+}
+
+/* Append some output to the file, keeping track of columns and doing
+ wrapping as necessary. */
+
+static void
+wrap_output (FILE *f, char *string, int spacer)
+{
+ int len = quote_string_for_make (NULL, string);
+
+ if (len == 0)
+ return;
+
+ if (column
+ && (MAX_COLUMNS
+ - 1 /* spacer */
+ - 2 /* ` \' */
+ < column + len))
+ {
+ fprintf (f, " \\\n ");
+ column = 0;
+ if (spacer == ' ')
+ spacer = '\0';
+ }
+
+ if (spacer == ' ')
+ {
+ putc (spacer, f);
+ ++column;
+ }
+
+ quote_string_for_make (f, string);
+ column += len;
+
+ if (spacer == ':')
+ {
+ putc (spacer, f);
+ ++column;
+ }
+}
+
+/* Print dependency file. */
+
+void
+print_dependencies (void)
+{
+ FILE *f;
+ struct dependency *dep;
+
+ if (dep_file == NULL)
+ return;
+
+ f = fopen (dep_file, FOPEN_WT);
+ if (f == NULL)
+ {
+ as_warn (_("can't open `%s' for writing"), dep_file);
+ return;
+ }
+
+ column = 0;
+ wrap_output (f, out_file_name, ':');
+ for (dep = dep_chain; dep != NULL; dep = dep->next)
+ wrap_output (f, dep->file, ' ');
+
+ putc ('\n', f);
+
+ if (fclose (f))
+ as_warn (_("can't close `%s'"), dep_file);
+}
diff --git a/x/binutils/gas/doc/Makefile.am b/x/binutils/gas/doc/Makefile.am
new file mode 100644
index 0000000..7f0f805
--- /dev/null
+++ b/x/binutils/gas/doc/Makefile.am
@@ -0,0 +1,100 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = 1.8 cygnus
+
+# What version of the manual you want; "all" includes everything
+CONFIG=all
+
+# Options to extract the man page from as.texinfo
+MANCONF = -Dman
+
+TEXI2POD = perl $(top_srcdir)/../etc/texi2pod.pl
+
+POD2MAN = pod2man --center="GNU Development Tools" \
+ --release="binutils-$(VERSION)" --section=1
+
+man_MANS = as.1
+
+info_TEXINFOS = as.texinfo
+
+asconfig.texi: $(CONFIG).texi
+ rm -f asconfig.texi
+ ln -s $(srcdir)/$(CONFIG).texi ./asconfig.texi >/dev/null 2>&1 \
+ || ln $(srcdir)/$(CONFIG).texi ./asconfig.texi >/dev/null 2>&1 \
+ || cp $(srcdir)/$(CONFIG).texi ./asconfig.texi
+
+CPU_DOCS = \
+ c-a29k.texi \
+ c-alpha.texi \
+ c-arc.texi \
+ c-arm.texi \
+ c-d10v.texi \
+ c-cris.texi \
+ c-h8300.texi \
+ c-h8500.texi \
+ c-hppa.texi \
+ c-i370.texi \
+ c-i386.texi \
+ c-i860.texi \
+ c-i960.texi \
+ c-ip2k.texi \
+ c-m32r.texi \
+ c-m68hc11.texi \
+ c-m68k.texi \
+ c-m88k.texi \
+ c-mips.texi \
+ c-mmix.texi \
+ c-msp430.texi \
+ c-ns32k.texi \
+ c-pdp11.texi \
+ c-pj.texi \
+ c-ppc.texi \
+ c-sh.texi \
+ c-sh64.texi \
+ c-sparc.texi \
+ c-tic54x.texi \
+ c-vax.texi \
+ c-v850.texi \
+ c-xtensa.texi \
+ c-z8k.texi
+
+gasver.texi: Makefile
+ rm -f $@
+ echo '@set VERSION $(VERSION)' > $@
+
+as.info: $(srcdir)/as.texinfo asconfig.texi gasver.texi $(CPU_DOCS)
+as.dvi: $(srcdir)/as.texinfo asconfig.texi gasver.texi $(CPU_DOCS)
+
+# We want install to imply install-info as per GNU standards, despite the
+# cygnus option.
+install-data-local: install-info
+
+# This one isn't ready for prime time yet. Not even a little bit.
+
+noinst_TEXINFOS = internals.texi
+
+DISTCLEANFILES = asconfig.texi
+
+MAINTAINERCLEANFILES = gasver.texi
+
+BASEDIR = $(srcdir)/../..
+BFDDIR = $(BASEDIR)/bfd
+
+CONFIG_STATUS_DEPENDENCIES = $(BFDDIR)/configure.in
+
+# Maintenance
+
+# We need it for the taz target in ../../Makefile.in.
+info: $(MANS)
+
+# Build the man page from the texinfo file
+# The sed command removes the no-adjust Nroff command so that
+# the man output looks standard.
+as.1: $(srcdir)/as.texinfo asconfig.texi gasver.texi $(CPU_DOCS)
+ touch $@
+ -$(TEXI2POD) $(MANCONF) < $(srcdir)/as.texinfo > as.pod
+ -($(POD2MAN) as.pod | \
+ sed -e '/^.if n .na/d' > $@.T$$$$ && \
+ mv -f $@.T$$$$ $@) || \
+ (rm -f $@.T$$$$ && exit 1)
+ rm -f as.pod
diff --git a/x/binutils/gas/doc/Makefile.in b/x/binutils/gas/doc/Makefile.in
new file mode 100644
index 0000000..0c6a1b0
--- /dev/null
+++ b/x/binutils/gas/doc/Makefile.in
@@ -0,0 +1,608 @@
+# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = doc
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/../libtool.m4 $(top_srcdir)/../gettext.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+depcomp =
+am__depfiles_maybe =
+SOURCES =
+DIST_SOURCES =
+INFO_DEPS = $(srcdir)/as.info
+TEXINFO_TEX = $(top_srcdir)/../texinfo/texinfo.tex
+am__TEXINFO_TEX_DIR = $(top_srcdir)/../texinfo
+DVIS = as.dvi
+PDFS = as.pdf
+PSS = as.ps
+HTMLS = as.html
+TEXINFOS = as.texinfo
+TEXI2DVI = `if test -f $(top_srcdir)/../texinfo/util/texi2dvi; then \
+ echo $(top_srcdir)/../texinfo/util/texi2dvi; \
+ else \
+ echo texi2dvi; \
+ fi`
+TEXI2PDF = $(TEXI2DVI) --pdf --batch
+MAKEINFOHTML = $(MAKEINFO) --html
+AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
+DVIPS = dvips
+man1dir = $(mandir)/man1
+am__installdirs = "$(DESTDIR)$(man1dir)"
+NROFF = nroff
+MANS = $(man_MANS)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALL_OBJ_DEPS = @ALL_OBJ_DEPS@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BFDVER_H = @BFDVER_H@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GDBINIT = @GDBINIT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+OBJEXT = @OBJEXT@
+OPCODES_LIB = @OPCODES_LIB@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+YACC = @YACC@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+atof = @atof@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+cgen_cpu_prefix = @cgen_cpu_prefix@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+extra_objects = @extra_objects@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+install_tooldir = @install_tooldir@
+l = @l@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+obj_format = @obj_format@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_cpu_type = @target_cpu_type@
+target_os = @target_os@
+target_vendor = @target_vendor@
+te_file = @te_file@
+AUTOMAKE_OPTIONS = 1.8 cygnus
+
+# What version of the manual you want; "all" includes everything
+CONFIG = all
+
+# Options to extract the man page from as.texinfo
+MANCONF = -Dman
+TEXI2POD = perl $(top_srcdir)/../etc/texi2pod.pl
+POD2MAN = pod2man --center="GNU Development Tools" \
+ --release="binutils-$(VERSION)" --section=1
+
+man_MANS = as.1
+info_TEXINFOS = as.texinfo
+CPU_DOCS = \
+ c-a29k.texi \
+ c-alpha.texi \
+ c-arc.texi \
+ c-arm.texi \
+ c-d10v.texi \
+ c-cris.texi \
+ c-h8300.texi \
+ c-h8500.texi \
+ c-hppa.texi \
+ c-i370.texi \
+ c-i386.texi \
+ c-i860.texi \
+ c-i960.texi \
+ c-ip2k.texi \
+ c-m32r.texi \
+ c-m68hc11.texi \
+ c-m68k.texi \
+ c-m88k.texi \
+ c-mips.texi \
+ c-mmix.texi \
+ c-msp430.texi \
+ c-ns32k.texi \
+ c-pdp11.texi \
+ c-pj.texi \
+ c-ppc.texi \
+ c-sh.texi \
+ c-sh64.texi \
+ c-sparc.texi \
+ c-tic54x.texi \
+ c-vax.texi \
+ c-v850.texi \
+ c-xtensa.texi \
+ c-z8k.texi
+
+
+# This one isn't ready for prime time yet. Not even a little bit.
+noinst_TEXINFOS = internals.texi
+DISTCLEANFILES = asconfig.texi
+MAINTAINERCLEANFILES = gasver.texi
+BASEDIR = $(srcdir)/../..
+BFDDIR = $(BASEDIR)/bfd
+CONFIG_STATUS_DEPENDENCIES = $(BFDDIR)/configure.in
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .dvi .html .info .pdf .ps .texinfo
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign doc/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+
+.texinfo.info:
+ restore=: && \
+ backupdir="$(am__leading_dot)am$$$$" && \
+ am__cwd=`pwd` && cd $(srcdir) && \
+ rm -rf $$backupdir && mkdir $$backupdir && \
+ for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
+ if test -f $$f; then \
+ mv $$f $$backupdir; \
+ restore=mv; \
+ fi; \
+ done; \
+ cd "$$am__cwd"; \
+ if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $@ $<; \
+ then \
+ rc=0; \
+ cd $(srcdir); \
+ else \
+ rc=$$?; \
+ cd $(srcdir) && \
+ $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
+ fi; \
+ rm -rf $$backupdir; \
+ exit $$rc
+
+.texinfo.dvi:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2DVI) $<
+
+.texinfo.pdf:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2PDF) $<
+
+.texinfo.html:
+ $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $@ $<
+ if test ! -d $@ && test -d $(@:.html=); then \
+ mv $(@:.html=) $@; else :; fi
+$(srcdir)/as.info: as.texinfo
+as.pdf: as.texinfo
+as.html: as.texinfo
+.dvi.ps:
+ $(DVIPS) -o $@ $<
+
+uninstall-info-am:
+ $(PRE_UNINSTALL)
+ @if (install-info --version && \
+ install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
+ install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
+ done; \
+ else :; fi
+ @$(NORMAL_UNINSTALL)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
+ (if cd "$(DESTDIR)$(infodir)"; then \
+ echo " rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9])"; \
+ rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
+ else :; fi); \
+ done
+
+dist-info: $(INFO_DEPS)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ case $$base in \
+ $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$base; then d=.; else d=$(srcdir); fi; \
+ for file in $$d/$$base*; do \
+ relfile=`expr "$$file" : "$$d/\(.*\)"`; \
+ test -f $(distdir)/$$relfile || \
+ cp -p $$file $(distdir)/$$relfile; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -rf as.aux as.cp as.cps as.fn as.fns as.ky as.log as.pg as.pgs as.tmp \
+ as.toc as.tp as.tps as.vr as.vrs as.dvi as.pdf as.ps as.html
+
+maintainer-clean-aminfo:
+ @list='$(INFO_DEPS)'; for i in $$list; do \
+ i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
+ echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
+ rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
+ done
+
+clean-info: mostlyclean-aminfo
+install-man1: $(man1_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man1dir)" || $(mkdir_p) "$(DESTDIR)$(man1dir)"
+ @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 1*) ;; \
+ *) ext='1' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \
+ done
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 1*) ;; \
+ *) ext='1' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \
+ rm -f "$(DESTDIR)$(man1dir)/$$inst"; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+check-am:
+check: check-am
+all-am: Makefile $(MANS)
+installdirs:
+ for dir in "$(DESTDIR)$(man1dir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f $(CONFIG_CLEAN_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool
+
+dvi: dvi-am
+
+dvi-am: $(DVIS)
+
+html: html-am
+
+html-am: $(HTMLS)
+
+info-am: $(INFO_DEPS)
+
+install-data-am: install-data-local install-man
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ test -z "$(infodir)" || $(mkdir_p) "$(DESTDIR)$(infodir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
+ $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
+ if test -f $$ifile; then \
+ relfile=`echo "$$ifile" | sed 's|^.*/||'`; \
+ echo " $(INSTALL_DATA) '$$ifile' '$(DESTDIR)$(infodir)/$$relfile'"; \
+ $(INSTALL_DATA) "$$ifile" "$(DESTDIR)$(infodir)/$$relfile"; \
+ else : ; fi; \
+ done; \
+ done
+ @$(POST_INSTALL)
+ @if (install-info --version && \
+ install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
+ install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
+ done; \
+ else : ; fi
+install-man: install-man1
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-aminfo \
+ maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-aminfo mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am: $(PDFS)
+
+ps: ps-am
+
+ps-am: $(PSS)
+
+uninstall-am: uninstall-man
+
+uninstall-man: uninstall-man1
+
+.PHONY: all all-am check check-am clean clean-generic clean-info \
+ clean-libtool dist-info distclean distclean-generic \
+ distclean-libtool dvi dvi-am html html-am info info-am install \
+ install-am install-data install-data-am install-data-local \
+ install-exec install-exec-am install-info install-info-am \
+ install-man install-man1 install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-aminfo maintainer-clean-generic mostlyclean \
+ mostlyclean-aminfo mostlyclean-generic mostlyclean-libtool pdf \
+ pdf-am ps ps-am uninstall uninstall-am uninstall-info-am \
+ uninstall-man uninstall-man1
+
+
+asconfig.texi: $(CONFIG).texi
+ rm -f asconfig.texi
+ ln -s $(srcdir)/$(CONFIG).texi ./asconfig.texi >/dev/null 2>&1 \
+ || ln $(srcdir)/$(CONFIG).texi ./asconfig.texi >/dev/null 2>&1 \
+ || cp $(srcdir)/$(CONFIG).texi ./asconfig.texi
+
+gasver.texi: Makefile
+ rm -f $@
+ echo '@set VERSION $(VERSION)' > $@
+
+as.info: $(srcdir)/as.texinfo asconfig.texi gasver.texi $(CPU_DOCS)
+as.dvi: $(srcdir)/as.texinfo asconfig.texi gasver.texi $(CPU_DOCS)
+
+# We want install to imply install-info as per GNU standards, despite the
+# cygnus option.
+install-data-local: install-info
+
+# Maintenance
+
+# We need it for the taz target in ../../Makefile.in.
+info: $(MANS)
+
+# Build the man page from the texinfo file
+# The sed command removes the no-adjust Nroff command so that
+# the man output looks standard.
+as.1: $(srcdir)/as.texinfo asconfig.texi gasver.texi $(CPU_DOCS)
+ touch $@
+ -$(TEXI2POD) $(MANCONF) < $(srcdir)/as.texinfo > as.pod
+ -($(POD2MAN) as.pod | \
+ sed -e '/^.if n .na/d' > $@.T$$$$ && \
+ mv -f $@.T$$$$ $@) || \
+ (rm -f $@.T$$$$ && exit 1)
+ rm -f as.pod
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/x/binutils/gas/doc/all.texi b/x/binutils/gas/doc/all.texi
new file mode 100644
index 0000000..4e302ce
--- /dev/null
+++ b/x/binutils/gas/doc/all.texi
@@ -0,0 +1,87 @@
+@c Copyright 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, 2002
+@c Free Software Foundation, Inc.
+@c This file is part of the documentation for the GAS manual
+
+@c Configuration settings for all-inclusive version of manual
+
+@c switches:------------------------------------------------------------
+@c Properties of the manual
+@c ========================
+@c Discuss all architectures?
+@set ALL-ARCH
+@c A generic form of manual (not tailored to specific target)?
+@set GENERIC
+@c Include text on assembler internals?
+@clear INTERNALS
+@c Many object formats supported in this config?
+@set MULTI-OBJ
+
+@c Object formats of interest
+@c ==========================
+@set AOUT
+@set BOUT
+@set COFF
+@set ELF
+@set SOM
+
+@c CPUs of interest
+@c ================
+@set A29K
+@set ALPHA
+@set ARC
+@set ARM
+@set CRIS
+@set D10V
+@set D30V
+@set H8/300
+@set H8/500
+@set HPPA
+@set I370
+@set I80386
+@set I860
+@set I960
+@set IP2K
+@set M32R
+@set M68HC11
+@set M680X0
+@set M880X0
+@set MCORE
+@set MIPS
+@set MMIX
+@set MSP430
+@set PDP11
+@set PJ
+@set PPC
+@set SH
+@set SPARC
+@set TIC54X
+@set V850
+@set VAX
+@set VXWORKS
+@set XTENSA
+@set Z8000
+
+@c Does this version of the assembler use the difference-table kluge?
+@set DIFF-TBL-KLUGE
+
+@c Do all machines described use IEEE floating point?
+@clear IEEEFLOAT
+
+@c Is a word 32 bits, or 16?
+@clear W32
+@set W16
+
+@c Do symbols have different characters than usual?
+@clear SPECIAL-SYMS
+
+@c strings:------------------------------------------------------------
+@c Name of the assembler:
+@set AS as
+@c Name of C compiler:
+@set GCC gcc
+@c Name of linker:
+@set LD ld
+@c Text for target machine (best not used in generic case; but just in case...)
+@set TARGET machine specific
+@c Name of object format NOT SET in generic version
+@clear OBJ-NAME
diff --git a/x/binutils/gas/doc/as.1 b/x/binutils/gas/doc/as.1
new file mode 100644
index 0000000..e16cbe9
--- /dev/null
+++ b/x/binutils/gas/doc/as.1
@@ -0,0 +1,970 @@
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. | will give a
+.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to
+.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C'
+.\" expand to `' in nroff, nothing in troff, for use with C<>.
+.tr \(*W-|\(bv\*(Tr
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.\"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "AS 1"
+.TH AS 1 "2004-05-17" "binutils-2.15" "GNU Development Tools"
+.SH "NAME"
+AS \- the portable GNU assembler.
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+as [\fB\-a\fR[\fBcdhlns\fR][=\fIfile\fR]] [\fB\-D\fR] [\fB\-\-defsym\fR \fIsym\fR=\fIval\fR]
+ [\fB\-f\fR] [\fB\-\-gstabs\fR] [\fB\-\-gstabs+\fR] [\fB\-\-gdwarf2\fR] [\fB\-\-help\fR]
+ [\fB\-I\fR \fIdir\fR] [\fB\-J\fR] [\fB\-K\fR] [\fB\-L\fR]
+ [\fB\-\-listing\-lhs\-width\fR=\fI\s-1NUM\s0\fR] [\fB\-\-listing\-lhs\-width2\fR=\fI\s-1NUM\s0\fR]
+ [\fB\-\-listing\-rhs\-width\fR=\fI\s-1NUM\s0\fR] [\fB\-\-listing\-cont\-lines\fR=\fI\s-1NUM\s0\fR]
+ [\fB\-\-keep\-locals\fR] [\fB\-o\fR \fIobjfile\fR] [\fB\-R\fR] [\fB\-\-statistics\fR] [\fB\-v\fR]
+ [\fB\-version\fR] [\fB\-\-version\fR] [\fB\-W\fR] [\fB\-\-warn\fR] [\fB\-\-fatal\-warnings\fR]
+ [\fB\-w\fR] [\fB\-x\fR] [\fB\-Z\fR] [\fB\-\-target\-help\fR] [\fItarget-options\fR]
+ [\fB\-\-\fR|\fIfiles\fR ...]
+.PP
+\&\fITarget Alpha options:\fR
+ [\fB\-m\fR\fIcpu\fR]
+ [\fB\-mdebug\fR | \fB\-no\-mdebug\fR]
+ [\fB\-relax\fR] [\fB\-g\fR] [\fB\-G\fR\fIsize\fR]
+ [\fB\-F\fR] [\fB\-32addr\fR]
+.PP
+\&\fITarget \s-1ARC\s0 options:\fR
+ [\fB\-marc[5|6|7|8]\fR]
+ [\fB\-EB\fR|\fB\-EL\fR]
+.PP
+\&\fITarget \s-1ARM\s0 options:\fR
+ [\fB\-mcpu\fR=\fIprocessor\fR[+\fIextension\fR...]]
+ [\fB\-march\fR=\fIarchitecture\fR[+\fIextension\fR...]]
+ [\fB\-mfpu\fR=\fIfloating-point-format\fR]
+ [\fB\-mfloat\-abi\fR=\fIabi\fR]
+ [\fB\-mthumb\fR]
+ [\fB\-EB\fR|\fB\-EL\fR]
+ [\fB\-mapcs\-32\fR|\fB\-mapcs\-26\fR|\fB\-mapcs\-float\fR|
+ \fB\-mapcs\-reentrant\fR]
+ [\fB\-mthumb\-interwork\fR] [\fB\-moabi\fR] [\fB\-k\fR]
+.PP
+\&\fITarget \s-1CRIS\s0 options:\fR
+ [\fB\-\-underscore\fR | \fB\-\-no\-underscore\fR]
+ [\fB\-\-pic\fR] [\fB\-N\fR]
+ [\fB\-\-emulation=criself\fR | \fB\-\-emulation=crisaout\fR]
+.PP
+\&\fITarget D10V options:\fR
+ [\fB\-O\fR]
+.PP
+\&\fITarget D30V options:\fR
+ [\fB\-O\fR|\fB\-n\fR|\fB\-N\fR]
+.PP
+\&\fITarget i386 options:\fR
+ [\fB\-\-32\fR|\fB\-\-64\fR] [\fB\-n\fR]
+.PP
+\&\fITarget i960 options:\fR
+ [\fB\-ACA\fR|\fB\-ACA_A\fR|\fB\-ACB\fR|\fB\-ACC\fR|\fB\-AKA\fR|\fB\-AKB\fR|
+ \fB\-AKC\fR|\fB\-AMC\fR]
+ [\fB\-b\fR] [\fB\-no\-relax\fR]
+.PP
+\&\fITarget \s-1IP2K\s0 options:\fR
+ [\fB\-mip2022\fR|\fB\-mip2022ext\fR]
+.PP
+\&\fITarget M32R options:\fR
+ [\fB\-\-m32rx\fR|\fB\-\-[no\-]warn\-explicit\-parallel\-conflicts\fR|
+ \fB\-\-W[n]p\fR]
+.PP
+\&\fITarget M680X0 options:\fR
+ [\fB\-l\fR] [\fB\-m68000\fR|\fB\-m68010\fR|\fB\-m68020\fR|...]
+.PP
+\&\fITarget M68HC11 options:\fR
+ [\fB\-m68hc11\fR|\fB\-m68hc12\fR|\fB\-m68hcs12\fR]
+ [\fB\-mshort\fR|\fB\-mlong\fR]
+ [\fB\-mshort\-double\fR|\fB\-mlong\-double\fR]
+ [\fB\-\-force\-long\-branchs\fR] [\fB\-\-short\-branchs\fR]
+ [\fB\-\-strict\-direct\-mode\fR] [\fB\-\-print\-insn\-syntax\fR]
+ [\fB\-\-print\-opcodes\fR] [\fB\-\-generate\-example\fR]
+.PP
+\&\fITarget \s-1MCORE\s0 options:\fR
+ [\fB\-jsri2bsr\fR] [\fB\-sifilter\fR] [\fB\-relax\fR]
+ [\fB\-mcpu=[210|340]\fR]
+.PP
+\&\fITarget \s-1MIPS\s0 options:\fR
+ [\fB\-nocpp\fR] [\fB\-EL\fR] [\fB\-EB\fR] [\fB\-O\fR[\fIoptimization level\fR]]
+ [\fB\-g\fR[\fIdebug level\fR]] [\fB\-G\fR \fInum\fR] [\fB\-KPIC\fR] [\fB\-call_shared\fR]
+ [\fB\-non_shared\fR] [\fB\-xgot\fR] [\fB\-\-membedded\-pic\fR]
+ [\fB\-mabi\fR=\fI\s-1ABI\s0\fR] [\fB\-32\fR] [\fB\-n32\fR] [\fB\-64\fR] [\fB\-mfp32\fR] [\fB\-mgp32\fR]
+ [\fB\-march\fR=\fI\s-1CPU\s0\fR] [\fB\-mtune\fR=\fI\s-1CPU\s0\fR] [\fB\-mips1\fR] [\fB\-mips2\fR]
+ [\fB\-mips3\fR] [\fB\-mips4\fR] [\fB\-mips5\fR] [\fB\-mips32\fR] [\fB\-mips32r2\fR]
+ [\fB\-mips64\fR] [\fB\-mips64r2\fR]
+ [\fB\-construct\-floats\fR] [\fB\-no\-construct\-floats\fR]
+ [\fB\-trap\fR] [\fB\-no\-break\fR] [\fB\-break\fR] [\fB\-no\-trap\fR]
+ [\fB\-mfix7000\fR] [\fB\-mno\-fix7000\fR]
+ [\fB\-mips16\fR] [\fB\-no\-mips16\fR]
+ [\fB\-mips3d\fR] [\fB\-no\-mips3d\fR]
+ [\fB\-mdmx\fR] [\fB\-no\-mdmx\fR]
+ [\fB\-mdebug\fR] [\fB\-no\-mdebug\fR]
+ [\fB\-mpdr\fR] [\fB\-mno\-pdr\fR]
+.PP
+\&\fITarget \s-1MMIX\s0 options:\fR
+ [\fB\-\-fixed\-special\-register\-names\fR] [\fB\-\-globalize\-symbols\fR]
+ [\fB\-\-gnu\-syntax\fR] [\fB\-\-relax\fR] [\fB\-\-no\-predefined\-symbols\fR]
+ [\fB\-\-no\-expand\fR] [\fB\-\-no\-merge\-gregs\fR] [\fB\-x\fR]
+ [\fB\-\-linker\-allocated\-gregs\fR]
+.PP
+\&\fITarget \s-1PDP11\s0 options:\fR
+ [\fB\-mpic\fR|\fB\-mno\-pic\fR] [\fB\-mall\fR] [\fB\-mno\-extensions\fR]
+ [\fB\-m\fR\fIextension\fR|\fB\-mno\-\fR\fIextension\fR]
+ [\fB\-m\fR\fIcpu\fR] [\fB\-m\fR\fImachine\fR]
+.PP
+\&\fITarget picoJava options:\fR
+ [\fB\-mb\fR|\fB\-me\fR]
+.PP
+\&\fITarget PowerPC options:\fR
+ [\fB\-mpwrx\fR|\fB\-mpwr2\fR|\fB\-mpwr\fR|\fB\-m601\fR|\fB\-mppc\fR|\fB\-mppc32\fR|\fB\-m603\fR|\fB\-m604\fR|
+ \fB\-m403\fR|\fB\-m405\fR|\fB\-mppc64\fR|\fB\-m620\fR|\fB\-mppc64bridge\fR|\fB\-mbooke\fR|
+ \fB\-mbooke32\fR|\fB\-mbooke64\fR]
+ [\fB\-mcom\fR|\fB\-many\fR|\fB\-maltivec\fR] [\fB\-memb\fR]
+ [\fB\-mregnames\fR|\fB\-mno\-regnames\fR]
+ [\fB\-mrelocatable\fR|\fB\-mrelocatable\-lib\fR]
+ [\fB\-mlittle\fR|\fB\-mlittle\-endian\fR|\fB\-mbig\fR|\fB\-mbig\-endian\fR]
+ [\fB\-msolaris\fR|\fB\-mno\-solaris\fR]
+.PP
+\&\fITarget \s-1SPARC\s0 options:\fR
+ [\fB\-Av6\fR|\fB\-Av7\fR|\fB\-Av8\fR|\fB\-Asparclet\fR|\fB\-Asparclite\fR
+ \fB\-Av8plus\fR|\fB\-Av8plusa\fR|\fB\-Av9\fR|\fB\-Av9a\fR]
+ [\fB\-xarch=v8plus\fR|\fB\-xarch=v8plusa\fR] [\fB\-bump\fR]
+ [\fB\-32\fR|\fB\-64\fR]
+.PP
+\&\fITarget \s-1TIC54X\s0 options:\fR
+ [\fB\-mcpu=54[123589]\fR|\fB\-mcpu=54[56]lp\fR] [\fB\-mfar\-mode\fR|\fB\-mf\fR]
+ [\fB\-merrors\-to\-file\fR \fI<filename>\fR|\fB\-me\fR \fI<filename>\fR]
+.PP
+\&\fITarget Xtensa options:\fR
+ [\fB\-\-[no\-]density\fR] [\fB\-\-[no\-]relax\fR] [\fB\-\-[no\-]generics\fR]
+ [\fB\-\-[no\-]text\-section\-literals\fR]
+ [\fB\-\-[no\-]target\-align\fR] [\fB\-\-[no\-]longcalls\fR]
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\s-1GNU\s0 \fBas\fR is really a family of assemblers.
+If you use (or have used) the \s-1GNU\s0 assembler on one architecture, you
+should find a fairly similar environment when you use it on another
+architecture. Each version has much in common with the others,
+including object file formats, most assembler directives (often called
+\&\fIpseudo-ops\fR) and assembler syntax.
+.PP
+\&\fBas\fR is primarily intended to assemble the output of the
+\&\s-1GNU\s0 C compiler \f(CW\*(C`gcc\*(C'\fR for use by the linker
+\&\f(CW\*(C`ld\*(C'\fR. Nevertheless, we've tried to make \fBas\fR
+assemble correctly everything that other assemblers for the same
+machine would assemble.
+Any exceptions are documented explicitly.
+This doesn't mean \fBas\fR always uses the same syntax as another
+assembler for the same architecture; for example, we know of several
+incompatible versions of 680x0 assembly language syntax.
+.PP
+Each time you run \fBas\fR it assembles exactly one source
+program. The source program is made up of one or more files.
+(The standard input is also a file.)
+.PP
+You give \fBas\fR a command line that has zero or more input file
+names. The input files are read (from left file name to right). A
+command line argument (in any position) that has no special meaning
+is taken to be an input file name.
+.PP
+If you give \fBas\fR no file names it attempts to read one input file
+from the \fBas\fR standard input, which is normally your terminal. You
+may have to type \fBctl-D\fR to tell \fBas\fR there is no more program
+to assemble.
+.PP
+Use \fB\-\-\fR if you need to explicitly name the standard input file
+in your command line.
+.PP
+If the source is empty, \fBas\fR produces a small, empty object
+file.
+.PP
+\&\fBas\fR may write warnings and error messages to the standard error
+file (usually your terminal). This should not happen when a compiler
+runs \fBas\fR automatically. Warnings report an assumption made so
+that \fBas\fR could keep assembling a flawed program; errors report a
+grave problem that stops the assembly.
+.PP
+If you are invoking \fBas\fR via the \s-1GNU\s0 C compiler,
+you can use the \fB\-Wa\fR option to pass arguments through to the assembler.
+The assembler arguments must be separated from each other (and the \fB\-Wa\fR)
+by commas. For example:
+.PP
+.Vb 1
+\& gcc -c -g -O -Wa,-alh,-L file.c
+.Ve
+.PP
+This passes two options to the assembler: \fB\-alh\fR (emit a listing to
+standard output with high-level and assembly source) and \fB\-L\fR (retain
+local symbols in the symbol table).
+.PP
+Usually you do not need to use this \fB\-Wa\fR mechanism, since many compiler
+command-line options are automatically passed to the assembler by the compiler.
+(You can call the \s-1GNU\s0 compiler driver with the \fB\-v\fR option to see
+precisely what options it passes to each compilation pass, including the
+assembler.)
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+.IP "\fB\-a[cdhlmns]\fR" 4
+.IX Item "-a[cdhlmns]"
+Turn on listings, in any of a variety of ways:
+.RS 4
+.IP "\fB\-ac\fR" 4
+.IX Item "-ac"
+omit false conditionals
+.IP "\fB\-ad\fR" 4
+.IX Item "-ad"
+omit debugging directives
+.IP "\fB\-ah\fR" 4
+.IX Item "-ah"
+include high-level source
+.IP "\fB\-al\fR" 4
+.IX Item "-al"
+include assembly
+.IP "\fB\-am\fR" 4
+.IX Item "-am"
+include macro expansions
+.IP "\fB\-an\fR" 4
+.IX Item "-an"
+omit forms processing
+.IP "\fB\-as\fR" 4
+.IX Item "-as"
+include symbols
+.IP "\fB=file\fR" 4
+.IX Item "=file"
+set the name of the listing file
+.RE
+.RS 4
+.Sp
+You may combine these options; for example, use \fB\-aln\fR for assembly
+listing without forms processing. The \fB=file\fR option, if used, must be
+the last one. By itself, \fB\-a\fR defaults to \fB\-ahls\fR.
+.RE
+.IP "\fB\-D\fR" 4
+.IX Item "-D"
+Ignored. This option is accepted for script compatibility with calls to
+other assemblers.
+.IP "\fB\-\-defsym\fR \fIsym\fR\fB=\fR\fIvalue\fR" 4
+.IX Item "--defsym sym=value"
+Define the symbol \fIsym\fR to be \fIvalue\fR before assembling the input file.
+\&\fIvalue\fR must be an integer constant. As in C, a leading \fB0x\fR
+indicates a hexadecimal value, and a leading \fB0\fR indicates an octal value.
+.IP "\fB\-f\fR" 4
+.IX Item "-f"
+``fast''\-\-\-skip whitespace and comment preprocessing (assume source is
+compiler output).
+.IP "\fB\-\-gstabs\fR" 4
+.IX Item "--gstabs"
+Generate stabs debugging information for each assembler line. This
+may help debugging assembler code, if the debugger can handle it.
+.IP "\fB\-\-gstabs+\fR" 4
+.IX Item "--gstabs+"
+Generate stabs debugging information for each assembler line, with \s-1GNU\s0
+extensions that probably only gdb can handle, and that could make other
+debuggers crash or refuse to read your program. This
+may help debugging assembler code. Currently the only \s-1GNU\s0 extension is
+the location of the current working directory at assembling time.
+.IP "\fB\-\-gdwarf2\fR" 4
+.IX Item "--gdwarf2"
+Generate \s-1DWARF2\s0 debugging information for each assembler line. This
+may help debugging assembler code, if the debugger can handle it. Note\-\-\-this
+option is only supported by some targets, not all of them.
+.IP "\fB\-\-help\fR" 4
+.IX Item "--help"
+Print a summary of the command line options and exit.
+.IP "\fB\-\-target\-help\fR" 4
+.IX Item "--target-help"
+Print a summary of all target specific options and exit.
+.IP "\fB\-I\fR \fIdir\fR" 4
+.IX Item "-I dir"
+Add directory \fIdir\fR to the search list for \f(CW\*(C`.include\*(C'\fR directives.
+.IP "\fB\-J\fR" 4
+.IX Item "-J"
+Don't warn about signed overflow.
+.IP "\fB\-K\fR" 4
+.IX Item "-K"
+Issue warnings when difference tables altered for long displacements.
+.IP "\fB\-L\fR" 4
+.IX Item "-L"
+.PD 0
+.IP "\fB\-\-keep\-locals\fR" 4
+.IX Item "--keep-locals"
+.PD
+Keep (in the symbol table) local symbols. On traditional a.out systems
+these start with \fBL\fR, but different systems have different local
+label prefixes.
+.IP "\fB\-\-listing\-lhs\-width=\fR\fInumber\fR" 4
+.IX Item "--listing-lhs-width=number"
+Set the maximum width, in words, of the output data column for an assembler
+listing to \fInumber\fR.
+.IP "\fB\-\-listing\-lhs\-width2=\fR\fInumber\fR" 4
+.IX Item "--listing-lhs-width2=number"
+Set the maximum width, in words, of the output data column for continuation
+lines in an assembler listing to \fInumber\fR.
+.IP "\fB\-\-listing\-rhs\-width=\fR\fInumber\fR" 4
+.IX Item "--listing-rhs-width=number"
+Set the maximum width of an input source line, as displayed in a listing, to
+\&\fInumber\fR bytes.
+.IP "\fB\-\-listing\-cont\-lines=\fR\fInumber\fR" 4
+.IX Item "--listing-cont-lines=number"
+Set the maximum number of lines printed in a listing for a single line of input
+to \fInumber\fR + 1.
+.IP "\fB\-o\fR \fIobjfile\fR" 4
+.IX Item "-o objfile"
+Name the object-file output from \fBas\fR \fIobjfile\fR.
+.IP "\fB\-R\fR" 4
+.IX Item "-R"
+Fold the data section into the text section.
+.IP "\fB\-\-statistics\fR" 4
+.IX Item "--statistics"
+Print the maximum space (in bytes) and total time (in seconds) used by
+assembly.
+.IP "\fB\-\-strip\-local\-absolute\fR" 4
+.IX Item "--strip-local-absolute"
+Remove local absolute symbols from the outgoing symbol table.
+.IP "\fB\-v\fR" 4
+.IX Item "-v"
+.PD 0
+.IP "\fB\-version\fR" 4
+.IX Item "-version"
+.PD
+Print the \fBas\fR version.
+.IP "\fB\-\-version\fR" 4
+.IX Item "--version"
+Print the \fBas\fR version and exit.
+.IP "\fB\-W\fR" 4
+.IX Item "-W"
+.PD 0
+.IP "\fB\-\-no\-warn\fR" 4
+.IX Item "--no-warn"
+.PD
+Suppress warning messages.
+.IP "\fB\-\-fatal\-warnings\fR" 4
+.IX Item "--fatal-warnings"
+Treat warnings as errors.
+.IP "\fB\-\-warn\fR" 4
+.IX Item "--warn"
+Don't suppress warning messages or treat them as errors.
+.IP "\fB\-w\fR" 4
+.IX Item "-w"
+Ignored.
+.IP "\fB\-x\fR" 4
+.IX Item "-x"
+Ignored.
+.IP "\fB\-Z\fR" 4
+.IX Item "-Z"
+Generate an object file even after errors.
+.IP "\fB\-\- |\fR \fIfiles\fR \fB...\fR" 4
+.IX Item "-- | files ..."
+Standard input, or source files to assemble.
+.PP
+The following options are available when as is configured for
+an \s-1ARC\s0 processor.
+.IP "\fB\-marc[5|6|7|8]\fR" 4
+.IX Item "-marc[5|6|7|8]"
+This option selects the core processor variant.
+.IP "\fB\-EB | \-EL\fR" 4
+.IX Item "-EB | -EL"
+Select either big-endian (\-EB) or little-endian (\-EL) output.
+.PP
+The following options are available when as is configured for the \s-1ARM\s0
+processor family.
+.IP "\fB\-mcpu=\fR\fIprocessor\fR\fB[+\fR\fIextension\fR\fB...]\fR" 4
+.IX Item "-mcpu=processor[+extension...]"
+Specify which \s-1ARM\s0 processor variant is the target.
+.IP "\fB\-march=\fR\fIarchitecture\fR\fB[+\fR\fIextension\fR\fB...]\fR" 4
+.IX Item "-march=architecture[+extension...]"
+Specify which \s-1ARM\s0 architecture variant is used by the target.
+.IP "\fB\-mfpu=\fR\fIfloating-point-format\fR" 4
+.IX Item "-mfpu=floating-point-format"
+Select which Floating Point architecture is the target.
+.IP "\fB\-mfloat\-abi=\fR\fIabi\fR" 4
+.IX Item "-mfloat-abi=abi"
+Select which floating point \s-1ABI\s0 is in use.
+.IP "\fB\-mthumb\fR" 4
+.IX Item "-mthumb"
+Enable Thumb only instruction decoding.
+.IP "\fB\-mapcs\-32 | \-mapcs\-26 | \-mapcs\-float | \-mapcs\-reentrant | \-moabi\fR" 4
+.IX Item "-mapcs-32 | -mapcs-26 | -mapcs-float | -mapcs-reentrant | -moabi"
+Select which procedure calling convention is in use.
+.IP "\fB\-EB | \-EL\fR" 4
+.IX Item "-EB | -EL"
+Select either big-endian (\-EB) or little-endian (\-EL) output.
+.IP "\fB\-mthumb\-interwork\fR" 4
+.IX Item "-mthumb-interwork"
+Specify that the code has been generated with interworking between Thumb and
+\&\s-1ARM\s0 code in mind.
+.IP "\fB\-k\fR" 4
+.IX Item "-k"
+Specify that \s-1PIC\s0 code has been generated.
+.PP
+See the info pages for documentation of the CRIS-specific options.
+.PP
+The following options are available when as is configured for
+a D10V processor.
+.IP "\fB\-O\fR" 4
+.IX Item "-O"
+Optimize output by parallelizing instructions.
+.PP
+The following options are available when as is configured for a D30V
+processor.
+.IP "\fB\-O\fR" 4
+.IX Item "-O"
+Optimize output by parallelizing instructions.
+.IP "\fB\-n\fR" 4
+.IX Item "-n"
+Warn when nops are generated.
+.IP "\fB\-N\fR" 4
+.IX Item "-N"
+Warn when a nop after a 32\-bit multiply instruction is generated.
+.PP
+The following options are available when as is configured for the
+Intel 80960 processor.
+.IP "\fB\-ACA | \-ACA_A | \-ACB | \-ACC | \-AKA | \-AKB | \-AKC | \-AMC\fR" 4
+.IX Item "-ACA | -ACA_A | -ACB | -ACC | -AKA | -AKB | -AKC | -AMC"
+Specify which variant of the 960 architecture is the target.
+.IP "\fB\-b\fR" 4
+.IX Item "-b"
+Add code to collect statistics about branches taken.
+.IP "\fB\-no\-relax\fR" 4
+.IX Item "-no-relax"
+Do not alter compare-and-branch instructions for long displacements;
+error if necessary.
+.PP
+The following options are available when as is configured for the
+Ubicom \s-1IP2K\s0 series.
+.IP "\fB\-mip2022ext\fR" 4
+.IX Item "-mip2022ext"
+Specifies that the extended \s-1IP2022\s0 instructions are allowed.
+.IP "\fB\-mip2022\fR" 4
+.IX Item "-mip2022"
+Restores the default behaviour, which restricts the permitted instructions to
+just the basic \s-1IP2022\s0 ones.
+.PP
+The following options are available when as is configured for the
+Renesas M32R (formerly Mitsubishi M32R) series.
+.IP "\fB\-\-m32rx\fR" 4
+.IX Item "--m32rx"
+Specify which processor in the M32R family is the target. The default
+is normally the M32R, but this option changes it to the M32RX.
+.IP "\fB\-\-warn\-explicit\-parallel\-conflicts or \-\-Wp\fR" 4
+.IX Item "--warn-explicit-parallel-conflicts or --Wp"
+Produce warning messages when questionable parallel constructs are
+encountered.
+.IP "\fB\-\-no\-warn\-explicit\-parallel\-conflicts or \-\-Wnp\fR" 4
+.IX Item "--no-warn-explicit-parallel-conflicts or --Wnp"
+Do not produce warning messages when questionable parallel constructs are
+encountered.
+.PP
+The following options are available when as is configured for the
+Motorola 68000 series.
+.IP "\fB\-l\fR" 4
+.IX Item "-l"
+Shorten references to undefined symbols, to one word instead of two.
+.IP "\fB\-m68000 | \-m68008 | \-m68010 | \-m68020 | \-m68030\fR" 4
+.IX Item "-m68000 | -m68008 | -m68010 | -m68020 | -m68030"
+.PD 0
+.IP "\fB| \-m68040 | \-m68060 | \-m68302 | \-m68331 | \-m68332\fR" 4
+.IX Item "| -m68040 | -m68060 | -m68302 | -m68331 | -m68332"
+.IP "\fB| \-m68333 | \-m68340 | \-mcpu32 | \-m5200\fR" 4
+.IX Item "| -m68333 | -m68340 | -mcpu32 | -m5200"
+.PD
+Specify what processor in the 68000 family is the target. The default
+is normally the 68020, but this can be changed at configuration time.
+.IP "\fB\-m68881 | \-m68882 | \-mno\-68881 | \-mno\-68882\fR" 4
+.IX Item "-m68881 | -m68882 | -mno-68881 | -mno-68882"
+The target machine does (or does not) have a floating-point coprocessor.
+The default is to assume a coprocessor for 68020, 68030, and cpu32. Although
+the basic 68000 is not compatible with the 68881, a combination of the
+two can be specified, since it's possible to do emulation of the
+coprocessor instructions with the main processor.
+.IP "\fB\-m68851 | \-mno\-68851\fR" 4
+.IX Item "-m68851 | -mno-68851"
+The target machine does (or does not) have a memory-management
+unit coprocessor. The default is to assume an \s-1MMU\s0 for 68020 and up.
+.PP
+For details about the \s-1PDP\-11\s0 machine dependent features options,
+see \f(CW@ref\fR{PDP\-11\-Options}.
+.IP "\fB\-mpic | \-mno\-pic\fR" 4
+.IX Item "-mpic | -mno-pic"
+Generate position-independent (or position\-dependent) code. The
+default is \fB\-mpic\fR.
+.IP "\fB\-mall\fR" 4
+.IX Item "-mall"
+.PD 0
+.IP "\fB\-mall\-extensions\fR" 4
+.IX Item "-mall-extensions"
+.PD
+Enable all instruction set extensions. This is the default.
+.IP "\fB\-mno\-extensions\fR" 4
+.IX Item "-mno-extensions"
+Disable all instruction set extensions.
+.IP "\fB\-m\fR\fIextension\fR \fB| \-mno\-\fR\fIextension\fR" 4
+.IX Item "-mextension | -mno-extension"
+Enable (or disable) a particular instruction set extension.
+.IP "\fB\-m\fR\fIcpu\fR" 4
+.IX Item "-mcpu"
+Enable the instruction set extensions supported by a particular \s-1CPU\s0, and
+disable all other extensions.
+.IP "\fB\-m\fR\fImachine\fR" 4
+.IX Item "-mmachine"
+Enable the instruction set extensions supported by a particular machine
+model, and disable all other extensions.
+.PP
+The following options are available when as is configured for
+a picoJava processor.
+.IP "\fB\-mb\fR" 4
+.IX Item "-mb"
+Generate ``big endian'' format output.
+.IP "\fB\-ml\fR" 4
+.IX Item "-ml"
+Generate ``little endian'' format output.
+.PP
+The following options are available when as is configured for the
+Motorola 68HC11 or 68HC12 series.
+.IP "\fB\-m68hc11 | \-m68hc12 | \-m68hcs12\fR" 4
+.IX Item "-m68hc11 | -m68hc12 | -m68hcs12"
+Specify what processor is the target. The default is
+defined by the configuration option when building the assembler.
+.IP "\fB\-mshort\fR" 4
+.IX Item "-mshort"
+Specify to use the 16\-bit integer \s-1ABI\s0.
+.IP "\fB\-mlong\fR" 4
+.IX Item "-mlong"
+Specify to use the 32\-bit integer \s-1ABI\s0.
+.IP "\fB\-mshort\-double\fR" 4
+.IX Item "-mshort-double"
+Specify to use the 32\-bit double \s-1ABI\s0.
+.IP "\fB\-mlong\-double\fR" 4
+.IX Item "-mlong-double"
+Specify to use the 64\-bit double \s-1ABI\s0.
+.IP "\fB\-\-force\-long\-branchs\fR" 4
+.IX Item "--force-long-branchs"
+Relative branches are turned into absolute ones. This concerns
+conditional branches, unconditional branches and branches to a
+sub routine.
+.IP "\fB\-S | \-\-short\-branchs\fR" 4
+.IX Item "-S | --short-branchs"
+Do not turn relative branchs into absolute ones
+when the offset is out of range.
+.IP "\fB\-\-strict\-direct\-mode\fR" 4
+.IX Item "--strict-direct-mode"
+Do not turn the direct addressing mode into extended addressing mode
+when the instruction does not support direct addressing mode.
+.IP "\fB\-\-print\-insn\-syntax\fR" 4
+.IX Item "--print-insn-syntax"
+Print the syntax of instruction in case of error.
+.IP "\fB\-\-print\-opcodes\fR" 4
+.IX Item "--print-opcodes"
+print the list of instructions with syntax and then exit.
+.IP "\fB\-\-generate\-example\fR" 4
+.IX Item "--generate-example"
+print an example of instruction for each possible instruction and then exit.
+This option is only useful for testing \fBas\fR.
+.PP
+The following options are available when \fBas\fR is configured
+for the \s-1SPARC\s0 architecture:
+.IP "\fB\-Av6 | \-Av7 | \-Av8 | \-Asparclet | \-Asparclite\fR" 4
+.IX Item "-Av6 | -Av7 | -Av8 | -Asparclet | -Asparclite"
+.PD 0
+.IP "\fB\-Av8plus | \-Av8plusa | \-Av9 | \-Av9a\fR" 4
+.IX Item "-Av8plus | -Av8plusa | -Av9 | -Av9a"
+.PD
+Explicitly select a variant of the \s-1SPARC\s0 architecture.
+.Sp
+\&\fB\-Av8plus\fR and \fB\-Av8plusa\fR select a 32 bit environment.
+\&\fB\-Av9\fR and \fB\-Av9a\fR select a 64 bit environment.
+.Sp
+\&\fB\-Av8plusa\fR and \fB\-Av9a\fR enable the \s-1SPARC\s0 V9 instruction set with
+UltraSPARC extensions.
+.IP "\fB\-xarch=v8plus | \-xarch=v8plusa\fR" 4
+.IX Item "-xarch=v8plus | -xarch=v8plusa"
+For compatibility with the Solaris v9 assembler. These options are
+equivalent to \-Av8plus and \-Av8plusa, respectively.
+.IP "\fB\-bump\fR" 4
+.IX Item "-bump"
+Warn when the assembler switches to another architecture.
+.PP
+The following options are available when as is configured for the 'c54x
+architecture.
+.IP "\fB\-mfar\-mode\fR" 4
+.IX Item "-mfar-mode"
+Enable extended addressing mode. All addresses and relocations will assume
+extended addressing (usually 23 bits).
+.IP "\fB\-mcpu=\fR\fI\s-1CPU_VERSION\s0\fR" 4
+.IX Item "-mcpu=CPU_VERSION"
+Sets the \s-1CPU\s0 version being compiled for.
+.IP "\fB\-merrors\-to\-file\fR \fI\s-1FILENAME\s0\fR" 4
+.IX Item "-merrors-to-file FILENAME"
+Redirect error output to a file, for broken systems which don't support such
+behaviour in the shell.
+.PP
+The following options are available when as is configured for
+a \s-1MIPS\s0 processor.
+.IP "\fB\-G\fR \fInum\fR" 4
+.IX Item "-G num"
+This option sets the largest size of an object that can be referenced
+implicitly with the \f(CW\*(C`gp\*(C'\fR register. It is only accepted for targets that
+use \s-1ECOFF\s0 format, such as a DECstation running Ultrix. The default value is 8.
+.IP "\fB\-EB\fR" 4
+.IX Item "-EB"
+Generate ``big endian'' format output.
+.IP "\fB\-EL\fR" 4
+.IX Item "-EL"
+Generate ``little endian'' format output.
+.IP "\fB\-mips1\fR" 4
+.IX Item "-mips1"
+.PD 0
+.IP "\fB\-mips2\fR" 4
+.IX Item "-mips2"
+.IP "\fB\-mips3\fR" 4
+.IX Item "-mips3"
+.IP "\fB\-mips4\fR" 4
+.IX Item "-mips4"
+.IP "\fB\-mips5\fR" 4
+.IX Item "-mips5"
+.IP "\fB\-mips32\fR" 4
+.IX Item "-mips32"
+.IP "\fB\-mips32r2\fR" 4
+.IX Item "-mips32r2"
+.IP "\fB\-mips64\fR" 4
+.IX Item "-mips64"
+.IP "\fB\-mips64r2\fR" 4
+.IX Item "-mips64r2"
+.PD
+Generate code for a particular \s-1MIPS\s0 Instruction Set Architecture level.
+\&\fB\-mips1\fR is an alias for \fB\-march=r3000\fR, \fB\-mips2\fR is an
+alias for \fB\-march=r6000\fR, \fB\-mips3\fR is an alias for
+\&\fB\-march=r4000\fR and \fB\-mips4\fR is an alias for \fB\-march=r8000\fR.
+\&\fB\-mips5\fR, \fB\-mips32\fR, \fB\-mips32r2\fR, \fB\-mips64\fR, and
+\&\fB\-mips64r2\fR
+correspond to generic
+\&\fB\s-1MIPS\s0 V\fR, \fB\s-1MIPS32\s0\fR, \fB\s-1MIPS32\s0 Release 2\fR, \fB\s-1MIPS64\s0\fR,
+and \fB\s-1MIPS64\s0 Release 2\fR
+\&\s-1ISA\s0 processors, respectively.
+.IP "\fB\-march=\fR\fI\s-1CPU\s0\fR" 4
+.IX Item "-march=CPU"
+Generate code for a particular \s-1MIPS\s0 cpu.
+.IP "\fB\-mtune=\fR\fIcpu\fR" 4
+.IX Item "-mtune=cpu"
+Schedule and tune for a particular \s-1MIPS\s0 cpu.
+.IP "\fB\-mfix7000\fR" 4
+.IX Item "-mfix7000"
+.PD 0
+.IP "\fB\-mno\-fix7000\fR" 4
+.IX Item "-mno-fix7000"
+.PD
+Cause nops to be inserted if the read of the destination register
+of an mfhi or mflo instruction occurs in the following two instructions.
+.IP "\fB\-mdebug\fR" 4
+.IX Item "-mdebug"
+.PD 0
+.IP "\fB\-no\-mdebug\fR" 4
+.IX Item "-no-mdebug"
+.PD
+Cause stabs-style debugging output to go into an ECOFF-style .mdebug
+section instead of the standard \s-1ELF\s0 .stabs sections.
+.IP "\fB\-mpdr\fR" 4
+.IX Item "-mpdr"
+.PD 0
+.IP "\fB\-mno\-pdr\fR" 4
+.IX Item "-mno-pdr"
+.PD
+Control generation of \f(CW\*(C`.pdr\*(C'\fR sections.
+.IP "\fB\-mgp32\fR" 4
+.IX Item "-mgp32"
+.PD 0
+.IP "\fB\-mfp32\fR" 4
+.IX Item "-mfp32"
+.PD
+The register sizes are normally inferred from the \s-1ISA\s0 and \s-1ABI\s0, but these
+flags force a certain group of registers to be treated as 32 bits wide at
+all times. \fB\-mgp32\fR controls the size of general-purpose registers
+and \fB\-mfp32\fR controls the size of floating-point registers.
+.IP "\fB\-mips16\fR" 4
+.IX Item "-mips16"
+.PD 0
+.IP "\fB\-no\-mips16\fR" 4
+.IX Item "-no-mips16"
+.PD
+Generate code for the \s-1MIPS\s0 16 processor. This is equivalent to putting
+\&\f(CW\*(C`.set mips16\*(C'\fR at the start of the assembly file. \fB\-no\-mips16\fR
+turns off this option.
+.IP "\fB\-mips3d\fR" 4
+.IX Item "-mips3d"
+.PD 0
+.IP "\fB\-no\-mips3d\fR" 4
+.IX Item "-no-mips3d"
+.PD
+Generate code for the \s-1MIPS\-3D\s0 Application Specific Extension.
+This tells the assembler to accept \s-1MIPS\-3D\s0 instructions.
+\&\fB\-no\-mips3d\fR turns off this option.
+.IP "\fB\-mdmx\fR" 4
+.IX Item "-mdmx"
+.PD 0
+.IP "\fB\-no\-mdmx\fR" 4
+.IX Item "-no-mdmx"
+.PD
+Generate code for the \s-1MDMX\s0 Application Specific Extension.
+This tells the assembler to accept \s-1MDMX\s0 instructions.
+\&\fB\-no\-mdmx\fR turns off this option.
+.IP "\fB\-\-construct\-floats\fR" 4
+.IX Item "--construct-floats"
+.PD 0
+.IP "\fB\-\-no\-construct\-floats\fR" 4
+.IX Item "--no-construct-floats"
+.PD
+The \fB\-\-no\-construct\-floats\fR option disables the construction of
+double width floating point constants by loading the two halves of the
+value into the two single width floating point registers that make up
+the double width register. By default \fB\-\-construct\-floats\fR is
+selected, allowing construction of these floating point constants.
+.IP "\fB\-\-emulation=\fR\fIname\fR" 4
+.IX Item "--emulation=name"
+This option causes \fBas\fR to emulate \fBas\fR configured
+for some other target, in all respects, including output format (choosing
+between \s-1ELF\s0 and \s-1ECOFF\s0 only), handling of pseudo-opcodes which may generate
+debugging information or store symbol table information, and default
+endianness. The available configuration names are: \fBmipsecoff\fR,
+\&\fBmipself\fR, \fBmipslecoff\fR, \fBmipsbecoff\fR, \fBmipslelf\fR,
+\&\fBmipsbelf\fR. The first two do not alter the default endianness from that
+of the primary target for which the assembler was configured; the others change
+the default to little\- or big-endian as indicated by the \fBb\fR or \fBl\fR
+in the name. Using \fB\-EB\fR or \fB\-EL\fR will override the endianness
+selection in any case.
+.Sp
+This option is currently supported only when the primary target
+\&\fBas\fR is configured for is a \s-1MIPS\s0 \s-1ELF\s0 or \s-1ECOFF\s0 target.
+Furthermore, the primary target or others specified with
+\&\fB\-\-enable\-targets=...\fR at configuration time must include support for
+the other format, if both are to be available. For example, the Irix 5
+configuration includes support for both.
+.Sp
+Eventually, this option will support more configurations, with more
+fine-grained control over the assembler's behavior, and will be supported for
+more processors.
+.IP "\fB\-nocpp\fR" 4
+.IX Item "-nocpp"
+\&\fBas\fR ignores this option. It is accepted for compatibility with
+the native tools.
+.IP "\fB\-\-trap\fR" 4
+.IX Item "--trap"
+.PD 0
+.IP "\fB\-\-no\-trap\fR" 4
+.IX Item "--no-trap"
+.IP "\fB\-\-break\fR" 4
+.IX Item "--break"
+.IP "\fB\-\-no\-break\fR" 4
+.IX Item "--no-break"
+.PD
+Control how to deal with multiplication overflow and division by zero.
+\&\fB\-\-trap\fR or \fB\-\-no\-break\fR (which are synonyms) take a trap exception
+(and only work for Instruction Set Architecture level 2 and higher);
+\&\fB\-\-break\fR or \fB\-\-no\-trap\fR (also synonyms, and the default) take a
+break exception.
+.IP "\fB\-n\fR" 4
+.IX Item "-n"
+When this option is used, \fBas\fR will issue a warning every
+time it generates a nop instruction from a macro.
+.PP
+The following options are available when as is configured for
+an MCore processor.
+.IP "\fB\-jsri2bsr\fR" 4
+.IX Item "-jsri2bsr"
+.PD 0
+.IP "\fB\-nojsri2bsr\fR" 4
+.IX Item "-nojsri2bsr"
+.PD
+Enable or disable the \s-1JSRI\s0 to \s-1BSR\s0 transformation. By default this is enabled.
+The command line option \fB\-nojsri2bsr\fR can be used to disable it.
+.IP "\fB\-sifilter\fR" 4
+.IX Item "-sifilter"
+.PD 0
+.IP "\fB\-nosifilter\fR" 4
+.IX Item "-nosifilter"
+.PD
+Enable or disable the silicon filter behaviour. By default this is disabled.
+The default can be overridden by the \fB\-sifilter\fR command line option.
+.IP "\fB\-relax\fR" 4
+.IX Item "-relax"
+Alter jump instructions for long displacements.
+.IP "\fB\-mcpu=[210|340]\fR" 4
+.IX Item "-mcpu=[210|340]"
+Select the cpu type on the target hardware. This controls which instructions
+can be assembled.
+.IP "\fB\-EB\fR" 4
+.IX Item "-EB"
+Assemble for a big endian target.
+.IP "\fB\-EL\fR" 4
+.IX Item "-EL"
+Assemble for a little endian target.
+.PP
+See the info pages for documentation of the MMIX-specific options.
+.PP
+The following options are available when as is configured for
+an Xtensa processor.
+.IP "\fB\-\-density | \-\-no\-density\fR" 4
+.IX Item "--density | --no-density"
+Enable or disable use of instructions from the Xtensa code density
+option. This is enabled by default when the Xtensa processor supports
+the code density option.
+.IP "\fB\-\-relax | \-\-no\-relax\fR" 4
+.IX Item "--relax | --no-relax"
+Enable or disable instruction relaxation. This is enabled by default.
+Note: In the current implementation, these options also control whether
+assembler optimizations are performed, making these options equivalent
+to \fB\-\-generics\fR and \fB\-\-no\-generics\fR.
+.IP "\fB\-\-generics | \-\-no\-generics\fR" 4
+.IX Item "--generics | --no-generics"
+Enable or disable all assembler transformations of Xtensa instructions.
+The default is \fB\-\-generics\fR;
+\&\fB\-\-no\-generics\fR should be used only in the rare cases when the
+instructions must be exactly as specified in the assembly source.
+.IP "\fB\-\-text\-section\-literals | \-\-no\-text\-section\-literals\fR" 4
+.IX Item "--text-section-literals | --no-text-section-literals"
+With \fB\-\-text\-section\-literals\fR, literal pools are interspersed
+in the text section. The default is
+\&\fB\-\-no\-text\-section\-literals\fR, which places literals in a
+separate section in the output file.
+.IP "\fB\-\-target\-align | \-\-no\-target\-align\fR" 4
+.IX Item "--target-align | --no-target-align"
+Enable or disable automatic alignment to reduce branch penalties at the
+expense of some code density. The default is \fB\-\-target\-align\fR.
+.IP "\fB\-\-longcalls | \-\-no\-longcalls\fR" 4
+.IX Item "--longcalls | --no-longcalls"
+Enable or disable transformation of call instructions to allow calls
+across a greater range of addresses. The default is
+\&\fB\-\-no\-longcalls\fR.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIgcc\fR\|(1), \fIld\fR\|(1), and the Info entries for \fIbinutils\fR and \fIld\fR.
+.SH "COPYRIGHT"
+.IX Header "COPYRIGHT"
+Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001, 2002 Free Software Foundation, Inc.
+.PP
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.1
+or any later version published by the Free Software Foundation;
+with no Invariant Sections, with no Front-Cover Texts, and with no
+Back-Cover Texts. A copy of the license is included in the
+section entitled ``\s-1GNU\s0 Free Documentation License''.
diff --git a/x/binutils/gas/doc/as.texinfo b/x/binutils/gas/doc/as.texinfo
new file mode 100644
index 0000000..d9d23df
--- /dev/null
+++ b/x/binutils/gas/doc/as.texinfo
@@ -0,0 +1,6449 @@
+\input texinfo @c -*-Texinfo-*-
+@c Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+@c 2001, 2002, 2003, 2004
+@c Free Software Foundation, Inc.
+@c UPDATE!! On future updates--
+@c (1) check for new machine-dep cmdline options in
+@c md_parse_option definitions in config/tc-*.c
+@c (2) for platform-specific directives, examine md_pseudo_op
+@c in config/tc-*.c
+@c (3) for object-format specific directives, examine obj_pseudo_op
+@c in config/obj-*.c
+@c (4) portable directives in potable[] in read.c
+@c %**start of header
+@setfilename as.info
+@c ---config---
+@macro gcctabopt{body}
+@code{\body\}
+@end macro
+@c defaults, config file may override:
+@set have-stabs
+@c ---
+@c man begin NAME
+@c ---
+@include asconfig.texi
+@include gasver.texi
+@c ---
+@c man end
+@c ---
+@c common OR combinations of conditions
+@ifset COFF
+@set COFF-ELF
+@end ifset
+@ifset ELF
+@set COFF-ELF
+@end ifset
+@ifset AOUT
+@set aout-bout
+@end ifset
+@ifset ARM/Thumb
+@set ARM
+@end ifset
+@ifset BOUT
+@set aout-bout
+@end ifset
+@ifset H8/300
+@set H8
+@end ifset
+@ifset H8/500
+@set H8
+@end ifset
+@ifset SH
+@set H8
+@end ifset
+@ifset HPPA
+@set abnormal-separator
+@end ifset
+@c ------------
+@ifset GENERIC
+@settitle Using @value{AS}
+@end ifset
+@ifclear GENERIC
+@settitle Using @value{AS} (@value{TARGET})
+@end ifclear
+@setchapternewpage odd
+@c %**end of header
+
+@c @smallbook
+@c @set SMALL
+@c WARE! Some of the machine-dependent sections contain tables of machine
+@c instructions. Except in multi-column format, these tables look silly.
+@c Unfortunately, Texinfo doesn't have a general-purpose multi-col format, so
+@c the multi-col format is faked within @example sections.
+@c
+@c Again unfortunately, the natural size that fits on a page, for these tables,
+@c is different depending on whether or not smallbook is turned on.
+@c This matters, because of order: text flow switches columns at each page
+@c break.
+@c
+@c The format faked in this source works reasonably well for smallbook,
+@c not well for the default large-page format. This manual expects that if you
+@c turn on @smallbook, you will also uncomment the "@set SMALL" to enable the
+@c tables in question. You can turn on one without the other at your
+@c discretion, of course.
+@ifinfo
+@set SMALL
+@c the insn tables look just as silly in info files regardless of smallbook,
+@c might as well show 'em anyways.
+@end ifinfo
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* As: (as). The GNU assembler.
+* Gas: (as). The GNU assembler.
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@finalout
+@syncodeindex ky cp
+
+@ifinfo
+This file documents the GNU Assembler "@value{AS}".
+
+@c man begin COPYRIGHT
+Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1
+or any later version published by the Free Software Foundation;
+with no Invariant Sections, with no Front-Cover Texts, and with no
+Back-Cover Texts. A copy of the license is included in the
+section entitled ``GNU Free Documentation License''.
+
+@c man end
+
+@ignore
+Permission is granted to process this file through Tex and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+@end ifinfo
+
+@titlepage
+@title Using @value{AS}
+@subtitle The @sc{gnu} Assembler
+@ifclear GENERIC
+@subtitle for the @value{TARGET} family
+@end ifclear
+@sp 1
+@subtitle Version @value{VERSION}
+@sp 1
+@sp 13
+The Free Software Foundation Inc. thanks The Nice Computer
+Company of Australia for loaning Dean Elsner to write the
+first (Vax) version of @command{as} for Project @sc{gnu}.
+The proprietors, management and staff of TNCCA thank FSF for
+distracting the boss while they got some work
+done.
+@sp 3
+@author Dean Elsner, Jay Fenlason & friends
+@page
+@tex
+{\parskip=0pt
+\hfill {\it Using {\tt @value{AS}}}\par
+\hfill Edited by Cygnus Support\par
+}
+%"boxit" macro for figures:
+%Modified from Knuth's ``boxit'' macro from TeXbook (answer to exercise 21.3)
+\gdef\boxit#1#2{\vbox{\hrule\hbox{\vrule\kern3pt
+ \vbox{\parindent=0pt\parskip=0pt\hsize=#1\kern3pt\strut\hfil
+#2\hfil\strut\kern3pt}\kern3pt\vrule}\hrule}}%box with visible outline
+\gdef\ibox#1#2{\hbox to #1{#2\hfil}\kern8pt}% invisible box
+@end tex
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.1
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, with no Front-Cover Texts, and with no
+ Back-Cover Texts. A copy of the license is included in the
+ section entitled ``GNU Free Documentation License''.
+
+@end titlepage
+
+@ifnottex
+@node Top
+@top Using @value{AS}
+
+This file is a user guide to the @sc{gnu} assembler @command{@value{AS}} version
+@value{VERSION}.
+@ifclear GENERIC
+This version of the file describes @command{@value{AS}} configured to generate
+code for @value{TARGET} architectures.
+@end ifclear
+
+This document is distributed under the terms of the GNU Free
+Documentation License. A copy of the license is included in the
+section entitled ``GNU Free Documentation License''.
+
+@menu
+* Overview:: Overview
+* Invoking:: Command-Line Options
+* Syntax:: Syntax
+* Sections:: Sections and Relocation
+* Symbols:: Symbols
+* Expressions:: Expressions
+* Pseudo Ops:: Assembler Directives
+* Machine Dependencies:: Machine Dependent Features
+* Reporting Bugs:: Reporting Bugs
+* Acknowledgements:: Who Did What
+* GNU Free Documentation License:: GNU Free Documentation License
+* Index:: Index
+@end menu
+@end ifnottex
+
+@node Overview
+@chapter Overview
+@iftex
+This manual is a user guide to the @sc{gnu} assembler @command{@value{AS}}.
+@ifclear GENERIC
+This version of the manual describes @command{@value{AS}} configured to generate
+code for @value{TARGET} architectures.
+@end ifclear
+@end iftex
+
+@cindex invocation summary
+@cindex option summary
+@cindex summary of options
+Here is a brief summary of how to invoke @command{@value{AS}}. For details,
+@pxref{Invoking,,Command-Line Options}.
+
+@c man title AS the portable GNU assembler.
+
+@ignore
+@c man begin SEEALSO
+gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
+@c man end
+@end ignore
+
+@c We don't use deffn and friends for the following because they seem
+@c to be limited to one line for the header.
+@smallexample
+@c man begin SYNOPSIS
+@value{AS} [@b{-a}[@b{cdhlns}][=@var{file}]] [@b{-D}] [@b{--defsym} @var{sym}=@var{val}]
+ [@b{-f}] [@b{--gstabs}] [@b{--gstabs+}] [@b{--gdwarf2}] [@b{--help}]
+ [@b{-I} @var{dir}] [@b{-J}] [@b{-K}] [@b{-L}]
+ [@b{--listing-lhs-width}=@var{NUM}] [@b{--listing-lhs-width2}=@var{NUM}]
+ [@b{--listing-rhs-width}=@var{NUM}] [@b{--listing-cont-lines}=@var{NUM}]
+ [@b{--keep-locals}] [@b{-o} @var{objfile}] [@b{-R}] [@b{--statistics}] [@b{-v}]
+ [@b{-version}] [@b{--version}] [@b{-W}] [@b{--warn}] [@b{--fatal-warnings}]
+ [@b{-w}] [@b{-x}] [@b{-Z}] [@b{--target-help}] [@var{target-options}]
+ [@b{--}|@var{files} @dots{}]
+@c
+@c Target dependent options are listed below. Keep the list sorted.
+@c Add an empty line for separation.
+@ifset A29K
+@c am29k has no machine-dependent assembler options
+@end ifset
+@ifset ALPHA
+
+@emph{Target Alpha options:}
+ [@b{-m@var{cpu}}]
+ [@b{-mdebug} | @b{-no-mdebug}]
+ [@b{-relax}] [@b{-g}] [@b{-G@var{size}}]
+ [@b{-F}] [@b{-32addr}]
+@end ifset
+@ifset ARC
+
+@emph{Target ARC options:}
+ [@b{-marc[5|6|7|8]}]
+ [@b{-EB}|@b{-EL}]
+@end ifset
+@ifset ARM
+
+@emph{Target ARM options:}
+@c Don't document the deprecated options
+ [@b{-mcpu}=@var{processor}[+@var{extension}@dots{}]]
+ [@b{-march}=@var{architecture}[+@var{extension}@dots{}]]
+ [@b{-mfpu}=@var{floating-point-format}]
+ [@b{-mfloat-abi}=@var{abi}]
+ [@b{-mthumb}]
+ [@b{-EB}|@b{-EL}]
+ [@b{-mapcs-32}|@b{-mapcs-26}|@b{-mapcs-float}|
+ @b{-mapcs-reentrant}]
+ [@b{-mthumb-interwork}] [@b{-moabi}] [@b{-k}]
+@end ifset
+@ifset CRIS
+
+@emph{Target CRIS options:}
+ [@b{--underscore} | @b{--no-underscore}]
+ [@b{--pic}] [@b{-N}]
+ [@b{--emulation=criself} | @b{--emulation=crisaout}]
+@c Deprecated -- deliberately not documented.
+@c [@b{-h}] [@b{-H}]
+@end ifset
+@ifset D10V
+
+@emph{Target D10V options:}
+ [@b{-O}]
+@end ifset
+@ifset D30V
+
+@emph{Target D30V options:}
+ [@b{-O}|@b{-n}|@b{-N}]
+@end ifset
+@ifset H8
+@c Renesas family chips have no machine-dependent assembler options
+@end ifset
+@ifset HPPA
+@c HPPA has no machine-dependent assembler options (yet).
+@end ifset
+@ifset I80386
+
+@emph{Target i386 options:}
+ [@b{--32}|@b{--64}] [@b{-n}]
+@end ifset
+@ifset I960
+
+@emph{Target i960 options:}
+@c see md_parse_option in tc-i960.c
+ [@b{-ACA}|@b{-ACA_A}|@b{-ACB}|@b{-ACC}|@b{-AKA}|@b{-AKB}|
+ @b{-AKC}|@b{-AMC}]
+ [@b{-b}] [@b{-no-relax}]
+@end ifset
+@ifset IA64
+
+@emph{Target IA-64 options:}
+ [@b{-mconstant-gp}|@b{-mauto-pic}]
+ [@b{-milp32}|@b{-milp64}|@b{-mlp64}|@b{-mp64}]
+ [@b{-mle}|@b{mbe}]
+ [@b{-x}|@b{-xexplicit}] [@b{-xauto}] [@b{-xdebug}]
+@end ifset
+@ifset IP2K
+
+@emph{Target IP2K options:}
+ [@b{-mip2022}|@b{-mip2022ext}]
+@end ifset
+@ifset M32R
+
+@emph{Target M32R options:}
+ [@b{--m32rx}|@b{--[no-]warn-explicit-parallel-conflicts}|
+ @b{--W[n]p}]
+@end ifset
+@ifset M680X0
+
+@emph{Target M680X0 options:}
+ [@b{-l}] [@b{-m68000}|@b{-m68010}|@b{-m68020}|@dots{}]
+@end ifset
+@ifset M68HC11
+
+@emph{Target M68HC11 options:}
+ [@b{-m68hc11}|@b{-m68hc12}|@b{-m68hcs12}]
+ [@b{-mshort}|@b{-mlong}]
+ [@b{-mshort-double}|@b{-mlong-double}]
+ [@b{--force-long-branchs}] [@b{--short-branchs}]
+ [@b{--strict-direct-mode}] [@b{--print-insn-syntax}]
+ [@b{--print-opcodes}] [@b{--generate-example}]
+@end ifset
+@ifset MCORE
+
+@emph{Target MCORE options:}
+ [@b{-jsri2bsr}] [@b{-sifilter}] [@b{-relax}]
+ [@b{-mcpu=[210|340]}]
+@end ifset
+@ifset MIPS
+
+@emph{Target MIPS options:}
+ [@b{-nocpp}] [@b{-EL}] [@b{-EB}] [@b{-O}[@var{optimization level}]]
+ [@b{-g}[@var{debug level}]] [@b{-G} @var{num}] [@b{-KPIC}] [@b{-call_shared}]
+ [@b{-non_shared}] [@b{-xgot}] [@b{--membedded-pic}]
+ [@b{-mabi}=@var{ABI}] [@b{-32}] [@b{-n32}] [@b{-64}] [@b{-mfp32}] [@b{-mgp32}]
+ [@b{-march}=@var{CPU}] [@b{-mtune}=@var{CPU}] [@b{-mips1}] [@b{-mips2}]
+ [@b{-mips3}] [@b{-mips4}] [@b{-mips5}] [@b{-mips32}] [@b{-mips32r2}]
+ [@b{-mips64}] [@b{-mips64r2}]
+ [@b{-construct-floats}] [@b{-no-construct-floats}]
+ [@b{-trap}] [@b{-no-break}] [@b{-break}] [@b{-no-trap}]
+ [@b{-mfix7000}] [@b{-mno-fix7000}]
+ [@b{-mips16}] [@b{-no-mips16}]
+ [@b{-mips3d}] [@b{-no-mips3d}]
+ [@b{-mdmx}] [@b{-no-mdmx}]
+ [@b{-mdebug}] [@b{-no-mdebug}]
+ [@b{-mpdr}] [@b{-mno-pdr}]
+@end ifset
+@ifset MMIX
+
+@emph{Target MMIX options:}
+ [@b{--fixed-special-register-names}] [@b{--globalize-symbols}]
+ [@b{--gnu-syntax}] [@b{--relax}] [@b{--no-predefined-symbols}]
+ [@b{--no-expand}] [@b{--no-merge-gregs}] [@b{-x}]
+ [@b{--linker-allocated-gregs}]
+@end ifset
+@ifset PDP11
+
+@emph{Target PDP11 options:}
+ [@b{-mpic}|@b{-mno-pic}] [@b{-mall}] [@b{-mno-extensions}]
+ [@b{-m}@var{extension}|@b{-mno-}@var{extension}]
+ [@b{-m}@var{cpu}] [@b{-m}@var{machine}]
+@end ifset
+@ifset PJ
+
+@emph{Target picoJava options:}
+ [@b{-mb}|@b{-me}]
+@end ifset
+@ifset PPC
+
+@emph{Target PowerPC options:}
+ [@b{-mpwrx}|@b{-mpwr2}|@b{-mpwr}|@b{-m601}|@b{-mppc}|@b{-mppc32}|@b{-m603}|@b{-m604}|
+ @b{-m403}|@b{-m405}|@b{-mppc64}|@b{-m620}|@b{-mppc64bridge}|@b{-mbooke}|
+ @b{-mbooke32}|@b{-mbooke64}]
+ [@b{-mcom}|@b{-many}|@b{-maltivec}] [@b{-memb}]
+ [@b{-mregnames}|@b{-mno-regnames}]
+ [@b{-mrelocatable}|@b{-mrelocatable-lib}]
+ [@b{-mlittle}|@b{-mlittle-endian}|@b{-mbig}|@b{-mbig-endian}]
+ [@b{-msolaris}|@b{-mno-solaris}]
+@end ifset
+@ifset SPARC
+
+@emph{Target SPARC options:}
+@c The order here is important. See c-sparc.texi.
+ [@b{-Av6}|@b{-Av7}|@b{-Av8}|@b{-Asparclet}|@b{-Asparclite}
+ @b{-Av8plus}|@b{-Av8plusa}|@b{-Av9}|@b{-Av9a}]
+ [@b{-xarch=v8plus}|@b{-xarch=v8plusa}] [@b{-bump}]
+ [@b{-32}|@b{-64}]
+@end ifset
+@ifset TIC54X
+
+@emph{Target TIC54X options:}
+ [@b{-mcpu=54[123589]}|@b{-mcpu=54[56]lp}] [@b{-mfar-mode}|@b{-mf}]
+ [@b{-merrors-to-file} @var{<filename>}|@b{-me} @var{<filename>}]
+@end ifset
+@ifset Z8000
+@c Z8000 has no machine-dependent assembler options
+@end ifset
+@ifset XTENSA
+
+@emph{Target Xtensa options:}
+ [@b{--[no-]density}] [@b{--[no-]relax}] [@b{--[no-]generics}]
+ [@b{--[no-]text-section-literals}]
+ [@b{--[no-]target-align}] [@b{--[no-]longcalls}]
+@end ifset
+@c man end
+@end smallexample
+
+@c man begin OPTIONS
+
+@table @gcctabopt
+@item -a[cdhlmns]
+Turn on listings, in any of a variety of ways:
+
+@table @gcctabopt
+@item -ac
+omit false conditionals
+
+@item -ad
+omit debugging directives
+
+@item -ah
+include high-level source
+
+@item -al
+include assembly
+
+@item -am
+include macro expansions
+
+@item -an
+omit forms processing
+
+@item -as
+include symbols
+
+@item =file
+set the name of the listing file
+@end table
+
+You may combine these options; for example, use @samp{-aln} for assembly
+listing without forms processing. The @samp{=file} option, if used, must be
+the last one. By itself, @samp{-a} defaults to @samp{-ahls}.
+
+@item -D
+Ignored. This option is accepted for script compatibility with calls to
+other assemblers.
+
+@item --defsym @var{sym}=@var{value}
+Define the symbol @var{sym} to be @var{value} before assembling the input file.
+@var{value} must be an integer constant. As in C, a leading @samp{0x}
+indicates a hexadecimal value, and a leading @samp{0} indicates an octal value.
+
+@item -f
+``fast''---skip whitespace and comment preprocessing (assume source is
+compiler output).
+
+@item --gstabs
+Generate stabs debugging information for each assembler line. This
+may help debugging assembler code, if the debugger can handle it.
+
+@item --gstabs+
+Generate stabs debugging information for each assembler line, with GNU
+extensions that probably only gdb can handle, and that could make other
+debuggers crash or refuse to read your program. This
+may help debugging assembler code. Currently the only GNU extension is
+the location of the current working directory at assembling time.
+
+@item --gdwarf2
+Generate DWARF2 debugging information for each assembler line. This
+may help debugging assembler code, if the debugger can handle it. Note---this
+option is only supported by some targets, not all of them.
+
+@item --help
+Print a summary of the command line options and exit.
+
+@item --target-help
+Print a summary of all target specific options and exit.
+
+@item -I @var{dir}
+Add directory @var{dir} to the search list for @code{.include} directives.
+
+@item -J
+Don't warn about signed overflow.
+
+@item -K
+@ifclear DIFF-TBL-KLUGE
+This option is accepted but has no effect on the @value{TARGET} family.
+@end ifclear
+@ifset DIFF-TBL-KLUGE
+Issue warnings when difference tables altered for long displacements.
+@end ifset
+
+@item -L
+@itemx --keep-locals
+Keep (in the symbol table) local symbols. On traditional a.out systems
+these start with @samp{L}, but different systems have different local
+label prefixes.
+
+@item --listing-lhs-width=@var{number}
+Set the maximum width, in words, of the output data column for an assembler
+listing to @var{number}.
+
+@item --listing-lhs-width2=@var{number}
+Set the maximum width, in words, of the output data column for continuation
+lines in an assembler listing to @var{number}.
+
+@item --listing-rhs-width=@var{number}
+Set the maximum width of an input source line, as displayed in a listing, to
+@var{number} bytes.
+
+@item --listing-cont-lines=@var{number}
+Set the maximum number of lines printed in a listing for a single line of input
+to @var{number} + 1.
+
+@item -o @var{objfile}
+Name the object-file output from @command{@value{AS}} @var{objfile}.
+
+@item -R
+Fold the data section into the text section.
+
+@item --statistics
+Print the maximum space (in bytes) and total time (in seconds) used by
+assembly.
+
+@item --strip-local-absolute
+Remove local absolute symbols from the outgoing symbol table.
+
+@item -v
+@itemx -version
+Print the @command{as} version.
+
+@item --version
+Print the @command{as} version and exit.
+
+@item -W
+@itemx --no-warn
+Suppress warning messages.
+
+@item --fatal-warnings
+Treat warnings as errors.
+
+@item --warn
+Don't suppress warning messages or treat them as errors.
+
+@item -w
+Ignored.
+
+@item -x
+Ignored.
+
+@item -Z
+Generate an object file even after errors.
+
+@item -- | @var{files} @dots{}
+Standard input, or source files to assemble.
+
+@end table
+
+@ifset ARC
+The following options are available when @value{AS} is configured for
+an ARC processor.
+
+@table @gcctabopt
+@item -marc[5|6|7|8]
+This option selects the core processor variant.
+@item -EB | -EL
+Select either big-endian (-EB) or little-endian (-EL) output.
+@end table
+@end ifset
+
+@ifset ARM
+The following options are available when @value{AS} is configured for the ARM
+processor family.
+
+@table @gcctabopt
+@item -mcpu=@var{processor}[+@var{extension}@dots{}]
+Specify which ARM processor variant is the target.
+@item -march=@var{architecture}[+@var{extension}@dots{}]
+Specify which ARM architecture variant is used by the target.
+@item -mfpu=@var{floating-point-format}
+Select which Floating Point architecture is the target.
+@item -mfloat-abi=@var{abi}
+Select which floating point ABI is in use.
+@item -mthumb
+Enable Thumb only instruction decoding.
+@item -mapcs-32 | -mapcs-26 | -mapcs-float | -mapcs-reentrant | -moabi
+Select which procedure calling convention is in use.
+@item -EB | -EL
+Select either big-endian (-EB) or little-endian (-EL) output.
+@item -mthumb-interwork
+Specify that the code has been generated with interworking between Thumb and
+ARM code in mind.
+@item -k
+Specify that PIC code has been generated.
+@end table
+@end ifset
+
+@ifset CRIS
+See the info pages for documentation of the CRIS-specific options.
+@end ifset
+
+@ifset D10V
+The following options are available when @value{AS} is configured for
+a D10V processor.
+@table @gcctabopt
+@cindex D10V optimization
+@cindex optimization, D10V
+@item -O
+Optimize output by parallelizing instructions.
+@end table
+@end ifset
+
+@ifset D30V
+The following options are available when @value{AS} is configured for a D30V
+processor.
+@table @gcctabopt
+@cindex D30V optimization
+@cindex optimization, D30V
+@item -O
+Optimize output by parallelizing instructions.
+
+@cindex D30V nops
+@item -n
+Warn when nops are generated.
+
+@cindex D30V nops after 32-bit multiply
+@item -N
+Warn when a nop after a 32-bit multiply instruction is generated.
+@end table
+@end ifset
+
+@ifset I960
+The following options are available when @value{AS} is configured for the
+Intel 80960 processor.
+
+@table @gcctabopt
+@item -ACA | -ACA_A | -ACB | -ACC | -AKA | -AKB | -AKC | -AMC
+Specify which variant of the 960 architecture is the target.
+
+@item -b
+Add code to collect statistics about branches taken.
+
+@item -no-relax
+Do not alter compare-and-branch instructions for long displacements;
+error if necessary.
+
+@end table
+@end ifset
+
+@ifset IP2K
+The following options are available when @value{AS} is configured for the
+Ubicom IP2K series.
+
+@table @gcctabopt
+
+@item -mip2022ext
+Specifies that the extended IP2022 instructions are allowed.
+
+@item -mip2022
+Restores the default behaviour, which restricts the permitted instructions to
+just the basic IP2022 ones.
+
+@end table
+@end ifset
+
+@ifset M32R
+The following options are available when @value{AS} is configured for the
+Renesas M32R (formerly Mitsubishi M32R) series.
+
+@table @gcctabopt
+
+@item --m32rx
+Specify which processor in the M32R family is the target. The default
+is normally the M32R, but this option changes it to the M32RX.
+
+@item --warn-explicit-parallel-conflicts or --Wp
+Produce warning messages when questionable parallel constructs are
+encountered.
+
+@item --no-warn-explicit-parallel-conflicts or --Wnp
+Do not produce warning messages when questionable parallel constructs are
+encountered.
+
+@end table
+@end ifset
+
+@ifset M680X0
+The following options are available when @value{AS} is configured for the
+Motorola 68000 series.
+
+@table @gcctabopt
+
+@item -l
+Shorten references to undefined symbols, to one word instead of two.
+
+@item -m68000 | -m68008 | -m68010 | -m68020 | -m68030
+@itemx | -m68040 | -m68060 | -m68302 | -m68331 | -m68332
+@itemx | -m68333 | -m68340 | -mcpu32 | -m5200
+Specify what processor in the 68000 family is the target. The default
+is normally the 68020, but this can be changed at configuration time.
+
+@item -m68881 | -m68882 | -mno-68881 | -mno-68882
+The target machine does (or does not) have a floating-point coprocessor.
+The default is to assume a coprocessor for 68020, 68030, and cpu32. Although
+the basic 68000 is not compatible with the 68881, a combination of the
+two can be specified, since it's possible to do emulation of the
+coprocessor instructions with the main processor.
+
+@item -m68851 | -mno-68851
+The target machine does (or does not) have a memory-management
+unit coprocessor. The default is to assume an MMU for 68020 and up.
+
+@end table
+@end ifset
+
+@ifset PDP11
+
+For details about the PDP-11 machine dependent features options,
+see @ref{PDP-11-Options}.
+
+@table @gcctabopt
+@item -mpic | -mno-pic
+Generate position-independent (or position-dependent) code. The
+default is @option{-mpic}.
+
+@item -mall
+@itemx -mall-extensions
+Enable all instruction set extensions. This is the default.
+
+@item -mno-extensions
+Disable all instruction set extensions.
+
+@item -m@var{extension} | -mno-@var{extension}
+Enable (or disable) a particular instruction set extension.
+
+@item -m@var{cpu}
+Enable the instruction set extensions supported by a particular CPU, and
+disable all other extensions.
+
+@item -m@var{machine}
+Enable the instruction set extensions supported by a particular machine
+model, and disable all other extensions.
+@end table
+
+@end ifset
+
+@ifset PJ
+The following options are available when @value{AS} is configured for
+a picoJava processor.
+
+@table @gcctabopt
+
+@cindex PJ endianness
+@cindex endianness, PJ
+@cindex big endian output, PJ
+@item -mb
+Generate ``big endian'' format output.
+
+@cindex little endian output, PJ
+@item -ml
+Generate ``little endian'' format output.
+
+@end table
+@end ifset
+
+@ifset M68HC11
+The following options are available when @value{AS} is configured for the
+Motorola 68HC11 or 68HC12 series.
+
+@table @gcctabopt
+
+@item -m68hc11 | -m68hc12 | -m68hcs12
+Specify what processor is the target. The default is
+defined by the configuration option when building the assembler.
+
+@item -mshort
+Specify to use the 16-bit integer ABI.
+
+@item -mlong
+Specify to use the 32-bit integer ABI.
+
+@item -mshort-double
+Specify to use the 32-bit double ABI.
+
+@item -mlong-double
+Specify to use the 64-bit double ABI.
+
+@item --force-long-branchs
+Relative branches are turned into absolute ones. This concerns
+conditional branches, unconditional branches and branches to a
+sub routine.
+
+@item -S | --short-branchs
+Do not turn relative branchs into absolute ones
+when the offset is out of range.
+
+@item --strict-direct-mode
+Do not turn the direct addressing mode into extended addressing mode
+when the instruction does not support direct addressing mode.
+
+@item --print-insn-syntax
+Print the syntax of instruction in case of error.
+
+@item --print-opcodes
+print the list of instructions with syntax and then exit.
+
+@item --generate-example
+print an example of instruction for each possible instruction and then exit.
+This option is only useful for testing @command{@value{AS}}.
+
+@end table
+@end ifset
+
+@ifset SPARC
+The following options are available when @command{@value{AS}} is configured
+for the SPARC architecture:
+
+@table @gcctabopt
+@item -Av6 | -Av7 | -Av8 | -Asparclet | -Asparclite
+@itemx -Av8plus | -Av8plusa | -Av9 | -Av9a
+Explicitly select a variant of the SPARC architecture.
+
+@samp{-Av8plus} and @samp{-Av8plusa} select a 32 bit environment.
+@samp{-Av9} and @samp{-Av9a} select a 64 bit environment.
+
+@samp{-Av8plusa} and @samp{-Av9a} enable the SPARC V9 instruction set with
+UltraSPARC extensions.
+
+@item -xarch=v8plus | -xarch=v8plusa
+For compatibility with the Solaris v9 assembler. These options are
+equivalent to -Av8plus and -Av8plusa, respectively.
+
+@item -bump
+Warn when the assembler switches to another architecture.
+@end table
+@end ifset
+
+@ifset TIC54X
+The following options are available when @value{AS} is configured for the 'c54x
+architecture.
+
+@table @gcctabopt
+@item -mfar-mode
+Enable extended addressing mode. All addresses and relocations will assume
+extended addressing (usually 23 bits).
+@item -mcpu=@var{CPU_VERSION}
+Sets the CPU version being compiled for.
+@item -merrors-to-file @var{FILENAME}
+Redirect error output to a file, for broken systems which don't support such
+behaviour in the shell.
+@end table
+@end ifset
+
+@ifset MIPS
+The following options are available when @value{AS} is configured for
+a @sc{mips} processor.
+
+@table @gcctabopt
+@item -G @var{num}
+This option sets the largest size of an object that can be referenced
+implicitly with the @code{gp} register. It is only accepted for targets that
+use ECOFF format, such as a DECstation running Ultrix. The default value is 8.
+
+@cindex MIPS endianness
+@cindex endianness, MIPS
+@cindex big endian output, MIPS
+@item -EB
+Generate ``big endian'' format output.
+
+@cindex little endian output, MIPS
+@item -EL
+Generate ``little endian'' format output.
+
+@cindex MIPS ISA
+@item -mips1
+@itemx -mips2
+@itemx -mips3
+@itemx -mips4
+@itemx -mips5
+@itemx -mips32
+@itemx -mips32r2
+@itemx -mips64
+@itemx -mips64r2
+Generate code for a particular @sc{mips} Instruction Set Architecture level.
+@samp{-mips1} is an alias for @samp{-march=r3000}, @samp{-mips2} is an
+alias for @samp{-march=r6000}, @samp{-mips3} is an alias for
+@samp{-march=r4000} and @samp{-mips4} is an alias for @samp{-march=r8000}.
+@samp{-mips5}, @samp{-mips32}, @samp{-mips32r2}, @samp{-mips64}, and
+@samp{-mips64r2}
+correspond to generic
+@samp{MIPS V}, @samp{MIPS32}, @samp{MIPS32 Release 2}, @samp{MIPS64},
+and @samp{MIPS64 Release 2}
+ISA processors, respectively.
+
+@item -march=@var{CPU}
+Generate code for a particular @sc{mips} cpu.
+
+@item -mtune=@var{cpu}
+Schedule and tune for a particular @sc{mips} cpu.
+
+@item -mfix7000
+@itemx -mno-fix7000
+Cause nops to be inserted if the read of the destination register
+of an mfhi or mflo instruction occurs in the following two instructions.
+
+@item -mdebug
+@itemx -no-mdebug
+Cause stabs-style debugging output to go into an ECOFF-style .mdebug
+section instead of the standard ELF .stabs sections.
+
+@item -mpdr
+@itemx -mno-pdr
+Control generation of @code{.pdr} sections.
+
+@item -mgp32
+@itemx -mfp32
+The register sizes are normally inferred from the ISA and ABI, but these
+flags force a certain group of registers to be treated as 32 bits wide at
+all times. @samp{-mgp32} controls the size of general-purpose registers
+and @samp{-mfp32} controls the size of floating-point registers.
+
+@item -mips16
+@itemx -no-mips16
+Generate code for the MIPS 16 processor. This is equivalent to putting
+@code{.set mips16} at the start of the assembly file. @samp{-no-mips16}
+turns off this option.
+
+@item -mips3d
+@itemx -no-mips3d
+Generate code for the MIPS-3D Application Specific Extension.
+This tells the assembler to accept MIPS-3D instructions.
+@samp{-no-mips3d} turns off this option.
+
+@item -mdmx
+@itemx -no-mdmx
+Generate code for the MDMX Application Specific Extension.
+This tells the assembler to accept MDMX instructions.
+@samp{-no-mdmx} turns off this option.
+
+@item --construct-floats
+@itemx --no-construct-floats
+The @samp{--no-construct-floats} option disables the construction of
+double width floating point constants by loading the two halves of the
+value into the two single width floating point registers that make up
+the double width register. By default @samp{--construct-floats} is
+selected, allowing construction of these floating point constants.
+
+@cindex emulation
+@item --emulation=@var{name}
+This option causes @command{@value{AS}} to emulate @command{@value{AS}} configured
+for some other target, in all respects, including output format (choosing
+between ELF and ECOFF only), handling of pseudo-opcodes which may generate
+debugging information or store symbol table information, and default
+endianness. The available configuration names are: @samp{mipsecoff},
+@samp{mipself}, @samp{mipslecoff}, @samp{mipsbecoff}, @samp{mipslelf},
+@samp{mipsbelf}. The first two do not alter the default endianness from that
+of the primary target for which the assembler was configured; the others change
+the default to little- or big-endian as indicated by the @samp{b} or @samp{l}
+in the name. Using @samp{-EB} or @samp{-EL} will override the endianness
+selection in any case.
+
+This option is currently supported only when the primary target
+@command{@value{AS}} is configured for is a @sc{mips} ELF or ECOFF target.
+Furthermore, the primary target or others specified with
+@samp{--enable-targets=@dots{}} at configuration time must include support for
+the other format, if both are to be available. For example, the Irix 5
+configuration includes support for both.
+
+Eventually, this option will support more configurations, with more
+fine-grained control over the assembler's behavior, and will be supported for
+more processors.
+
+@item -nocpp
+@command{@value{AS}} ignores this option. It is accepted for compatibility with
+the native tools.
+
+@item --trap
+@itemx --no-trap
+@itemx --break
+@itemx --no-break
+Control how to deal with multiplication overflow and division by zero.
+@samp{--trap} or @samp{--no-break} (which are synonyms) take a trap exception
+(and only work for Instruction Set Architecture level 2 and higher);
+@samp{--break} or @samp{--no-trap} (also synonyms, and the default) take a
+break exception.
+
+@item -n
+When this option is used, @command{@value{AS}} will issue a warning every
+time it generates a nop instruction from a macro.
+@end table
+@end ifset
+
+@ifset MCORE
+The following options are available when @value{AS} is configured for
+an MCore processor.
+
+@table @gcctabopt
+@item -jsri2bsr
+@itemx -nojsri2bsr
+Enable or disable the JSRI to BSR transformation. By default this is enabled.
+The command line option @samp{-nojsri2bsr} can be used to disable it.
+
+@item -sifilter
+@itemx -nosifilter
+Enable or disable the silicon filter behaviour. By default this is disabled.
+The default can be overridden by the @samp{-sifilter} command line option.
+
+@item -relax
+Alter jump instructions for long displacements.
+
+@item -mcpu=[210|340]
+Select the cpu type on the target hardware. This controls which instructions
+can be assembled.
+
+@item -EB
+Assemble for a big endian target.
+
+@item -EL
+Assemble for a little endian target.
+
+@end table
+@end ifset
+
+@ifset MMIX
+See the info pages for documentation of the MMIX-specific options.
+@end ifset
+
+@ifset XTENSA
+The following options are available when @value{AS} is configured for
+an Xtensa processor.
+
+@table @gcctabopt
+@item --density | --no-density
+Enable or disable use of instructions from the Xtensa code density
+option. This is enabled by default when the Xtensa processor supports
+the code density option.
+
+@item --relax | --no-relax
+Enable or disable instruction relaxation. This is enabled by default.
+Note: In the current implementation, these options also control whether
+assembler optimizations are performed, making these options equivalent
+to @option{--generics} and @option{--no-generics}.
+
+@item --generics | --no-generics
+Enable or disable all assembler transformations of Xtensa instructions.
+The default is @option{--generics};
+@option{--no-generics} should be used only in the rare cases when the
+instructions must be exactly as specified in the assembly source.
+
+@item --text-section-literals | --no-text-section-literals
+With @option{--text-@-section-@-literals}, literal pools are interspersed
+in the text section. The default is
+@option{--no-@-text-@-section-@-literals}, which places literals in a
+separate section in the output file.
+
+@item --target-align | --no-target-align
+Enable or disable automatic alignment to reduce branch penalties at the
+expense of some code density. The default is @option{--target-@-align}.
+
+@item --longcalls | --no-longcalls
+Enable or disable transformation of call instructions to allow calls
+across a greater range of addresses. The default is
+@option{--no-@-longcalls}.
+@end table
+@end ifset
+
+@c man end
+
+@menu
+* Manual:: Structure of this Manual
+* GNU Assembler:: The GNU Assembler
+* Object Formats:: Object File Formats
+* Command Line:: Command Line
+* Input Files:: Input Files
+* Object:: Output (Object) File
+* Errors:: Error and Warning Messages
+@end menu
+
+@node Manual
+@section Structure of this Manual
+
+@cindex manual, structure and purpose
+This manual is intended to describe what you need to know to use
+@sc{gnu} @command{@value{AS}}. We cover the syntax expected in source files, including
+notation for symbols, constants, and expressions; the directives that
+@command{@value{AS}} understands; and of course how to invoke @command{@value{AS}}.
+
+@ifclear GENERIC
+We also cover special features in the @value{TARGET}
+configuration of @command{@value{AS}}, including assembler directives.
+@end ifclear
+@ifset GENERIC
+This manual also describes some of the machine-dependent features of
+various flavors of the assembler.
+@end ifset
+
+@cindex machine instructions (not covered)
+On the other hand, this manual is @emph{not} intended as an introduction
+to programming in assembly language---let alone programming in general!
+In a similar vein, we make no attempt to introduce the machine
+architecture; we do @emph{not} describe the instruction set, standard
+mnemonics, registers or addressing modes that are standard to a
+particular architecture.
+@ifset GENERIC
+You may want to consult the manufacturer's
+machine architecture manual for this information.
+@end ifset
+@ifclear GENERIC
+@ifset H8/300
+For information on the H8/300 machine instruction set, see @cite{H8/300
+Series Programming Manual}. For the H8/300H, see @cite{H8/300H Series
+Programming Manual} (Renesas).
+@end ifset
+@ifset H8/500
+For information on the H8/500 machine instruction set, see @cite{H8/500
+Series Programming Manual} (Renesas M21T001).
+@end ifset
+@ifset SH
+For information on the Renesas (formerly Hitachi) / SuperH SH machine instruction set,
+see @cite{SH-Microcomputer User's Manual} (Renesas) or
+@cite{SH-4 32-bit CPU Core Architecture} (SuperH) and
+@cite{SuperH (SH) 64-Bit RISC Series} (SuperH).
+@end ifset
+@ifset Z8000
+For information on the Z8000 machine instruction set, see @cite{Z8000 CPU Technical Manual}
+@end ifset
+@end ifclear
+
+@c I think this is premature---doc@cygnus.com, 17jan1991
+@ignore
+Throughout this manual, we assume that you are running @dfn{GNU},
+the portable operating system from the @dfn{Free Software
+Foundation, Inc.}. This restricts our attention to certain kinds of
+computer (in particular, the kinds of computers that @sc{gnu} can run on);
+once this assumption is granted examples and definitions need less
+qualification.
+
+@command{@value{AS}} is part of a team of programs that turn a high-level
+human-readable series of instructions into a low-level
+computer-readable series of instructions. Different versions of
+@command{@value{AS}} are used for different kinds of computer.
+@end ignore
+
+@c There used to be a section "Terminology" here, which defined
+@c "contents", "byte", "word", and "long". Defining "word" to any
+@c particular size is confusing when the .word directive may generate 16
+@c bits on one machine and 32 bits on another; in general, for the user
+@c version of this manual, none of these terms seem essential to define.
+@c They were used very little even in the former draft of the manual;
+@c this draft makes an effort to avoid them (except in names of
+@c directives).
+
+@node GNU Assembler
+@section The GNU Assembler
+
+@c man begin DESCRIPTION
+
+@sc{gnu} @command{as} is really a family of assemblers.
+@ifclear GENERIC
+This manual describes @command{@value{AS}}, a member of that family which is
+configured for the @value{TARGET} architectures.
+@end ifclear
+If you use (or have used) the @sc{gnu} assembler on one architecture, you
+should find a fairly similar environment when you use it on another
+architecture. Each version has much in common with the others,
+including object file formats, most assembler directives (often called
+@dfn{pseudo-ops}) and assembler syntax.@refill
+
+@cindex purpose of @sc{gnu} assembler
+@command{@value{AS}} is primarily intended to assemble the output of the
+@sc{gnu} C compiler @code{@value{GCC}} for use by the linker
+@code{@value{LD}}. Nevertheless, we've tried to make @command{@value{AS}}
+assemble correctly everything that other assemblers for the same
+machine would assemble.
+@ifset VAX
+Any exceptions are documented explicitly (@pxref{Machine Dependencies}).
+@end ifset
+@ifset M680X0
+@c This remark should appear in generic version of manual; assumption
+@c here is that generic version sets M680x0.
+This doesn't mean @command{@value{AS}} always uses the same syntax as another
+assembler for the same architecture; for example, we know of several
+incompatible versions of 680x0 assembly language syntax.
+@end ifset
+
+@c man end
+
+Unlike older assemblers, @command{@value{AS}} is designed to assemble a source
+program in one pass of the source file. This has a subtle impact on the
+@kbd{.org} directive (@pxref{Org,,@code{.org}}).
+
+@node Object Formats
+@section Object File Formats
+
+@cindex object file format
+The @sc{gnu} assembler can be configured to produce several alternative
+object file formats. For the most part, this does not affect how you
+write assembly language programs; but directives for debugging symbols
+are typically different in different file formats. @xref{Symbol
+Attributes,,Symbol Attributes}.
+@ifclear GENERIC
+@ifclear MULTI-OBJ
+For the @value{TARGET} target, @command{@value{AS}} is configured to produce
+@value{OBJ-NAME} format object files.
+@end ifclear
+@c The following should exhaust all configs that set MULTI-OBJ, ideally
+@ifset A29K
+On the @value{TARGET}, @command{@value{AS}} can be configured to produce either
+@code{a.out} or COFF format object files.
+@end ifset
+@ifset I960
+On the @value{TARGET}, @command{@value{AS}} can be configured to produce either
+@code{b.out} or COFF format object files.
+@end ifset
+@ifset HPPA
+On the @value{TARGET}, @command{@value{AS}} can be configured to produce either
+SOM or ELF format object files.
+@end ifset
+@end ifclear
+
+@node Command Line
+@section Command Line
+
+@cindex command line conventions
+
+After the program name @command{@value{AS}}, the command line may contain
+options and file names. Options may appear in any order, and may be
+before, after, or between file names. The order of file names is
+significant.
+
+@cindex standard input, as input file
+@kindex --
+@file{--} (two hyphens) by itself names the standard input file
+explicitly, as one of the files for @command{@value{AS}} to assemble.
+
+@cindex options, command line
+Except for @samp{--} any command line argument that begins with a
+hyphen (@samp{-}) is an option. Each option changes the behavior of
+@command{@value{AS}}. No option changes the way another option works. An
+option is a @samp{-} followed by one or more letters; the case of
+the letter is important. All options are optional.
+
+Some options expect exactly one file name to follow them. The file
+name may either immediately follow the option's letter (compatible
+with older assemblers) or it may be the next command argument (@sc{gnu}
+standard). These two command lines are equivalent:
+
+@smallexample
+@value{AS} -o my-object-file.o mumble.s
+@value{AS} -omy-object-file.o mumble.s
+@end smallexample
+
+@node Input Files
+@section Input Files
+
+@cindex input
+@cindex source program
+@cindex files, input
+We use the phrase @dfn{source program}, abbreviated @dfn{source}, to
+describe the program input to one run of @command{@value{AS}}. The program may
+be in one or more files; how the source is partitioned into files
+doesn't change the meaning of the source.
+
+@c I added "con" prefix to "catenation" just to prove I can overcome my
+@c APL training... doc@cygnus.com
+The source program is a concatenation of the text in all the files, in the
+order specified.
+
+@c man begin DESCRIPTION
+Each time you run @command{@value{AS}} it assembles exactly one source
+program. The source program is made up of one or more files.
+(The standard input is also a file.)
+
+You give @command{@value{AS}} a command line that has zero or more input file
+names. The input files are read (from left file name to right). A
+command line argument (in any position) that has no special meaning
+is taken to be an input file name.
+
+If you give @command{@value{AS}} no file names it attempts to read one input file
+from the @command{@value{AS}} standard input, which is normally your terminal. You
+may have to type @key{ctl-D} to tell @command{@value{AS}} there is no more program
+to assemble.
+
+Use @samp{--} if you need to explicitly name the standard input file
+in your command line.
+
+If the source is empty, @command{@value{AS}} produces a small, empty object
+file.
+
+@c man end
+
+@subheading Filenames and Line-numbers
+
+@cindex input file linenumbers
+@cindex line numbers, in input files
+There are two ways of locating a line in the input file (or files) and
+either may be used in reporting error messages. One way refers to a line
+number in a physical file; the other refers to a line number in a
+``logical'' file. @xref{Errors, ,Error and Warning Messages}.
+
+@dfn{Physical files} are those files named in the command line given
+to @command{@value{AS}}.
+
+@dfn{Logical files} are simply names declared explicitly by assembler
+directives; they bear no relation to physical files. Logical file names help
+error messages reflect the original source file, when @command{@value{AS}} source
+is itself synthesized from other files. @command{@value{AS}} understands the
+@samp{#} directives emitted by the @code{@value{GCC}} preprocessor. See also
+@ref{File,,@code{.file}}.
+
+@node Object
+@section Output (Object) File
+
+@cindex object file
+@cindex output file
+@kindex a.out
+@kindex .o
+Every time you run @command{@value{AS}} it produces an output file, which is
+your assembly language program translated into numbers. This file
+is the object file. Its default name is
+@ifclear BOUT
+@code{a.out}.
+@end ifclear
+@ifset BOUT
+@ifset GENERIC
+@code{a.out}, or
+@end ifset
+@code{b.out} when @command{@value{AS}} is configured for the Intel 80960.
+@end ifset
+You can give it another name by using the @option{-o} option. Conventionally,
+object file names end with @file{.o}. The default name is used for historical
+reasons: older assemblers were capable of assembling self-contained programs
+directly into a runnable program. (For some formats, this isn't currently
+possible, but it can be done for the @code{a.out} format.)
+
+@cindex linker
+@kindex ld
+The object file is meant for input to the linker @code{@value{LD}}. It contains
+assembled program code, information to help @code{@value{LD}} integrate
+the assembled program into a runnable file, and (optionally) symbolic
+information for the debugger.
+
+@c link above to some info file(s) like the description of a.out.
+@c don't forget to describe @sc{gnu} info as well as Unix lossage.
+
+@node Errors
+@section Error and Warning Messages
+
+@c man begin DESCRIPTION
+
+@cindex error messages
+@cindex warning messages
+@cindex messages from assembler
+@command{@value{AS}} may write warnings and error messages to the standard error
+file (usually your terminal). This should not happen when a compiler
+runs @command{@value{AS}} automatically. Warnings report an assumption made so
+that @command{@value{AS}} could keep assembling a flawed program; errors report a
+grave problem that stops the assembly.
+
+@c man end
+
+@cindex format of warning messages
+Warning messages have the format
+
+@smallexample
+file_name:@b{NNN}:Warning Message Text
+@end smallexample
+
+@noindent
+@cindex line numbers, in warnings/errors
+(where @b{NNN} is a line number). If a logical file name has been given
+(@pxref{File,,@code{.file}}) it is used for the filename, otherwise the name of
+the current input file is used. If a logical line number was given
+@ifset GENERIC
+(@pxref{Line,,@code{.line}})
+@end ifset
+@ifclear GENERIC
+@ifclear A29K
+(@pxref{Line,,@code{.line}})
+@end ifclear
+@ifset A29K
+(@pxref{Ln,,@code{.ln}})
+@end ifset
+@end ifclear
+then it is used to calculate the number printed,
+otherwise the actual line in the current source file is printed. The
+message text is intended to be self explanatory (in the grand Unix
+tradition).
+
+@cindex format of error messages
+Error messages have the format
+@smallexample
+file_name:@b{NNN}:FATAL:Error Message Text
+@end smallexample
+The file name and line number are derived as for warning
+messages. The actual message text may be rather less explanatory
+because many of them aren't supposed to happen.
+
+@node Invoking
+@chapter Command-Line Options
+
+@cindex options, all versions of assembler
+This chapter describes command-line options available in @emph{all}
+versions of the @sc{gnu} assembler; @pxref{Machine Dependencies}, for options specific
+@ifclear GENERIC
+to the @value{TARGET} target.
+@end ifclear
+@ifset GENERIC
+to particular machine architectures.
+@end ifset
+
+@c man begin DESCRIPTION
+
+If you are invoking @command{@value{AS}} via the @sc{gnu} C compiler,
+you can use the @samp{-Wa} option to pass arguments through to the assembler.
+The assembler arguments must be separated from each other (and the @samp{-Wa})
+by commas. For example:
+
+@smallexample
+gcc -c -g -O -Wa,-alh,-L file.c
+@end smallexample
+
+@noindent
+This passes two options to the assembler: @samp{-alh} (emit a listing to
+standard output with high-level and assembly source) and @samp{-L} (retain
+local symbols in the symbol table).
+
+Usually you do not need to use this @samp{-Wa} mechanism, since many compiler
+command-line options are automatically passed to the assembler by the compiler.
+(You can call the @sc{gnu} compiler driver with the @samp{-v} option to see
+precisely what options it passes to each compilation pass, including the
+assembler.)
+
+@c man end
+
+@menu
+* a:: -a[cdhlns] enable listings
+* D:: -D for compatibility
+* f:: -f to work faster
+* I:: -I for .include search path
+@ifclear DIFF-TBL-KLUGE
+* K:: -K for compatibility
+@end ifclear
+@ifset DIFF-TBL-KLUGE
+* K:: -K for difference tables
+@end ifset
+
+* L:: -L to retain local labels
+* listing:: --listing-XXX to configure listing output
+* M:: -M or --mri to assemble in MRI compatibility mode
+* MD:: --MD for dependency tracking
+* o:: -o to name the object file
+* R:: -R to join data and text sections
+* statistics:: --statistics to see statistics about assembly
+* traditional-format:: --traditional-format for compatible output
+* v:: -v to announce version
+* W:: -W, --no-warn, --warn, --fatal-warnings to control warnings
+* Z:: -Z to make object file even after errors
+@end menu
+
+@node a
+@section Enable Listings: @option{-a[cdhlns]}
+
+@kindex -a
+@kindex -ac
+@kindex -ad
+@kindex -ah
+@kindex -al
+@kindex -an
+@kindex -as
+@cindex listings, enabling
+@cindex assembly listings, enabling
+
+These options enable listing output from the assembler. By itself,
+@samp{-a} requests high-level, assembly, and symbols listing.
+You can use other letters to select specific options for the list:
+@samp{-ah} requests a high-level language listing,
+@samp{-al} requests an output-program assembly listing, and
+@samp{-as} requests a symbol table listing.
+High-level listings require that a compiler debugging option like
+@samp{-g} be used, and that assembly listings (@samp{-al}) be requested
+also.
+
+Use the @samp{-ac} option to omit false conditionals from a listing. Any lines
+which are not assembled because of a false @code{.if} (or @code{.ifdef}, or any
+other conditional), or a true @code{.if} followed by an @code{.else}, will be
+omitted from the listing.
+
+Use the @samp{-ad} option to omit debugging directives from the
+listing.
+
+Once you have specified one of these options, you can further control
+listing output and its appearance using the directives @code{.list},
+@code{.nolist}, @code{.psize}, @code{.eject}, @code{.title}, and
+@code{.sbttl}.
+The @samp{-an} option turns off all forms processing.
+If you do not request listing output with one of the @samp{-a} options, the
+listing-control directives have no effect.
+
+The letters after @samp{-a} may be combined into one option,
+@emph{e.g.}, @samp{-aln}.
+
+Note if the assembler source is coming from the standard input (eg because it
+is being created by @code{@value{GCC}} and the @samp{-pipe} command line switch
+is being used) then the listing will not contain any comments or preprocessor
+directives. This is because the listing code buffers input source lines from
+stdin only after they have been preprocessed by the assembler. This reduces
+memory usage and makes the code more efficient.
+
+@node D
+@section @option{-D}
+
+@kindex -D
+This option has no effect whatsoever, but it is accepted to make it more
+likely that scripts written for other assemblers also work with
+@command{@value{AS}}.
+
+@node f
+@section Work Faster: @option{-f}
+
+@kindex -f
+@cindex trusted compiler
+@cindex faster processing (@option{-f})
+@samp{-f} should only be used when assembling programs written by a
+(trusted) compiler. @samp{-f} stops the assembler from doing whitespace
+and comment preprocessing on
+the input file(s) before assembling them. @xref{Preprocessing,
+,Preprocessing}.
+
+@quotation
+@emph{Warning:} if you use @samp{-f} when the files actually need to be
+preprocessed (if they contain comments, for example), @command{@value{AS}} does
+not work correctly.
+@end quotation
+
+@node I
+@section @code{.include} Search Path: @option{-I} @var{path}
+
+@kindex -I @var{path}
+@cindex paths for @code{.include}
+@cindex search path for @code{.include}
+@cindex @code{include} directive search path
+Use this option to add a @var{path} to the list of directories
+@command{@value{AS}} searches for files specified in @code{.include}
+directives (@pxref{Include,,@code{.include}}). You may use @option{-I} as
+many times as necessary to include a variety of paths. The current
+working directory is always searched first; after that, @command{@value{AS}}
+searches any @samp{-I} directories in the same order as they were
+specified (left to right) on the command line.
+
+@node K
+@section Difference Tables: @option{-K}
+
+@kindex -K
+@ifclear DIFF-TBL-KLUGE
+On the @value{TARGET} family, this option is allowed, but has no effect. It is
+permitted for compatibility with the @sc{gnu} assembler on other platforms,
+where it can be used to warn when the assembler alters the machine code
+generated for @samp{.word} directives in difference tables. The @value{TARGET}
+family does not have the addressing limitations that sometimes lead to this
+alteration on other platforms.
+@end ifclear
+
+@ifset DIFF-TBL-KLUGE
+@cindex difference tables, warning
+@cindex warning for altered difference tables
+@command{@value{AS}} sometimes alters the code emitted for directives of the form
+@samp{.word @var{sym1}-@var{sym2}}; @pxref{Word,,@code{.word}}.
+You can use the @samp{-K} option if you want a warning issued when this
+is done.
+@end ifset
+
+@node L
+@section Include Local Labels: @option{-L}
+
+@kindex -L
+@cindex local labels, retaining in output
+Labels beginning with @samp{L} (upper case only) are called @dfn{local
+labels}. @xref{Symbol Names}. Normally you do not see such labels when
+debugging, because they are intended for the use of programs (like
+compilers) that compose assembler programs, not for your notice.
+Normally both @command{@value{AS}} and @code{@value{LD}} discard such labels, so you do not
+normally debug with them.
+
+This option tells @command{@value{AS}} to retain those @samp{L@dots{}} symbols
+in the object file. Usually if you do this you also tell the linker
+@code{@value{LD}} to preserve symbols whose names begin with @samp{L}.
+
+By default, a local label is any label beginning with @samp{L}, but each
+target is allowed to redefine the local label prefix.
+@ifset HPPA
+On the HPPA local labels begin with @samp{L$}.
+@end ifset
+
+@node listing
+@section Configuring listing output: @option{--listing}
+
+The listing feature of the assembler can be enabled via the command line switch
+@samp{-a} (@pxref{a}). This feature combines the input source file(s) with a
+hex dump of the corresponding locations in the output object file, and displays
+them as a listing file. The format of this listing can be controlled by pseudo
+ops inside the assembler source (@pxref{List} @pxref{Title} @pxref{Sbttl}
+@pxref{Psize} @pxref{Eject}) and also by the following switches:
+
+@table @gcctabopt
+@item --listing-lhs-width=@samp{number}
+@kindex --listing-lhs-width
+@cindex Width of first line disassembly output
+Sets the maximum width, in words, of the first line of the hex byte dump. This
+dump appears on the left hand side of the listing output.
+
+@item --listing-lhs-width2=@samp{number}
+@kindex --listing-lhs-width2
+@cindex Width of continuation lines of disassembly output
+Sets the maximum width, in words, of any further lines of the hex byte dump for
+a given input source line. If this value is not specified, it defaults to being
+the same as the value specified for @samp{--listing-lhs-width}. If neither
+switch is used the default is to one.
+
+@item --listing-rhs-width=@samp{number}
+@kindex --listing-rhs-width
+@cindex Width of source line output
+Sets the maximum width, in characters, of the source line that is displayed
+alongside the hex dump. The default value for this parameter is 100. The
+source line is displayed on the right hand side of the listing output.
+
+@item --listing-cont-lines=@samp{number}
+@kindex --listing-cont-lines
+@cindex Maximum number of continuation lines
+Sets the maximum number of continuation lines of hex dump that will be
+displayed for a given single line of source input. The default value is 4.
+@end table
+
+@node M
+@section Assemble in MRI Compatibility Mode: @option{-M}
+
+@kindex -M
+@cindex MRI compatibility mode
+The @option{-M} or @option{--mri} option selects MRI compatibility mode. This
+changes the syntax and pseudo-op handling of @command{@value{AS}} to make it
+compatible with the @code{ASM68K} or the @code{ASM960} (depending upon the
+configured target) assembler from Microtec Research. The exact nature of the
+MRI syntax will not be documented here; see the MRI manuals for more
+information. Note in particular that the handling of macros and macro
+arguments is somewhat different. The purpose of this option is to permit
+assembling existing MRI assembler code using @command{@value{AS}}.
+
+The MRI compatibility is not complete. Certain operations of the MRI assembler
+depend upon its object file format, and can not be supported using other object
+file formats. Supporting these would require enhancing each object file format
+individually. These are:
+
+@itemize @bullet
+@item global symbols in common section
+
+The m68k MRI assembler supports common sections which are merged by the linker.
+Other object file formats do not support this. @command{@value{AS}} handles
+common sections by treating them as a single common symbol. It permits local
+symbols to be defined within a common section, but it can not support global
+symbols, since it has no way to describe them.
+
+@item complex relocations
+
+The MRI assemblers support relocations against a negated section address, and
+relocations which combine the start addresses of two or more sections. These
+are not support by other object file formats.
+
+@item @code{END} pseudo-op specifying start address
+
+The MRI @code{END} pseudo-op permits the specification of a start address.
+This is not supported by other object file formats. The start address may
+instead be specified using the @option{-e} option to the linker, or in a linker
+script.
+
+@item @code{IDNT}, @code{.ident} and @code{NAME} pseudo-ops
+
+The MRI @code{IDNT}, @code{.ident} and @code{NAME} pseudo-ops assign a module
+name to the output file. This is not supported by other object file formats.
+
+@item @code{ORG} pseudo-op
+
+The m68k MRI @code{ORG} pseudo-op begins an absolute section at a given
+address. This differs from the usual @command{@value{AS}} @code{.org} pseudo-op,
+which changes the location within the current section. Absolute sections are
+not supported by other object file formats. The address of a section may be
+assigned within a linker script.
+@end itemize
+
+There are some other features of the MRI assembler which are not supported by
+@command{@value{AS}}, typically either because they are difficult or because they
+seem of little consequence. Some of these may be supported in future releases.
+
+@itemize @bullet
+
+@item EBCDIC strings
+
+EBCDIC strings are not supported.
+
+@item packed binary coded decimal
+
+Packed binary coded decimal is not supported. This means that the @code{DC.P}
+and @code{DCB.P} pseudo-ops are not supported.
+
+@item @code{FEQU} pseudo-op
+
+The m68k @code{FEQU} pseudo-op is not supported.
+
+@item @code{NOOBJ} pseudo-op
+
+The m68k @code{NOOBJ} pseudo-op is not supported.
+
+@item @code{OPT} branch control options
+
+The m68k @code{OPT} branch control options---@code{B}, @code{BRS}, @code{BRB},
+@code{BRL}, and @code{BRW}---are ignored. @command{@value{AS}} automatically
+relaxes all branches, whether forward or backward, to an appropriate size, so
+these options serve no purpose.
+
+@item @code{OPT} list control options
+
+The following m68k @code{OPT} list control options are ignored: @code{C},
+@code{CEX}, @code{CL}, @code{CRE}, @code{E}, @code{G}, @code{I}, @code{M},
+@code{MEX}, @code{MC}, @code{MD}, @code{X}.
+
+@item other @code{OPT} options
+
+The following m68k @code{OPT} options are ignored: @code{NEST}, @code{O},
+@code{OLD}, @code{OP}, @code{P}, @code{PCO}, @code{PCR}, @code{PCS}, @code{R}.
+
+@item @code{OPT} @code{D} option is default
+
+The m68k @code{OPT} @code{D} option is the default, unlike the MRI assembler.
+@code{OPT NOD} may be used to turn it off.
+
+@item @code{XREF} pseudo-op.
+
+The m68k @code{XREF} pseudo-op is ignored.
+
+@item @code{.debug} pseudo-op
+
+The i960 @code{.debug} pseudo-op is not supported.
+
+@item @code{.extended} pseudo-op
+
+The i960 @code{.extended} pseudo-op is not supported.
+
+@item @code{.list} pseudo-op.
+
+The various options of the i960 @code{.list} pseudo-op are not supported.
+
+@item @code{.optimize} pseudo-op
+
+The i960 @code{.optimize} pseudo-op is not supported.
+
+@item @code{.output} pseudo-op
+
+The i960 @code{.output} pseudo-op is not supported.
+
+@item @code{.setreal} pseudo-op
+
+The i960 @code{.setreal} pseudo-op is not supported.
+
+@end itemize
+
+@node MD
+@section Dependency Tracking: @option{--MD}
+
+@kindex --MD
+@cindex dependency tracking
+@cindex make rules
+
+@command{@value{AS}} can generate a dependency file for the file it creates. This
+file consists of a single rule suitable for @code{make} describing the
+dependencies of the main source file.
+
+The rule is written to the file named in its argument.
+
+This feature is used in the automatic updating of makefiles.
+
+@node o
+@section Name the Object File: @option{-o}
+
+@kindex -o
+@cindex naming object file
+@cindex object file name
+There is always one object file output when you run @command{@value{AS}}. By
+default it has the name
+@ifset GENERIC
+@ifset I960
+@file{a.out} (or @file{b.out}, for Intel 960 targets only).
+@end ifset
+@ifclear I960
+@file{a.out}.
+@end ifclear
+@end ifset
+@ifclear GENERIC
+@ifset I960
+@file{b.out}.
+@end ifset
+@ifclear I960
+@file{a.out}.
+@end ifclear
+@end ifclear
+You use this option (which takes exactly one filename) to give the
+object file a different name.
+
+Whatever the object file is called, @command{@value{AS}} overwrites any
+existing file of the same name.
+
+@node R
+@section Join Data and Text Sections: @option{-R}
+
+@kindex -R
+@cindex data and text sections, joining
+@cindex text and data sections, joining
+@cindex joining text and data sections
+@cindex merging text and data sections
+@option{-R} tells @command{@value{AS}} to write the object file as if all
+data-section data lives in the text section. This is only done at
+the very last moment: your binary data are the same, but data
+section parts are relocated differently. The data section part of
+your object file is zero bytes long because all its bytes are
+appended to the text section. (@xref{Sections,,Sections and Relocation}.)
+
+When you specify @option{-R} it would be possible to generate shorter
+address displacements (because we do not have to cross between text and
+data section). We refrain from doing this simply for compatibility with
+older versions of @command{@value{AS}}. In future, @option{-R} may work this way.
+
+@ifset COFF-ELF
+When @command{@value{AS}} is configured for COFF or ELF output,
+this option is only useful if you use sections named @samp{.text} and
+@samp{.data}.
+@end ifset
+
+@ifset HPPA
+@option{-R} is not supported for any of the HPPA targets. Using
+@option{-R} generates a warning from @command{@value{AS}}.
+@end ifset
+
+@node statistics
+@section Display Assembly Statistics: @option{--statistics}
+
+@kindex --statistics
+@cindex statistics, about assembly
+@cindex time, total for assembly
+@cindex space used, maximum for assembly
+Use @samp{--statistics} to display two statistics about the resources used by
+@command{@value{AS}}: the maximum amount of space allocated during the assembly
+(in bytes), and the total execution time taken for the assembly (in @sc{cpu}
+seconds).
+
+@node traditional-format
+@section Compatible Output: @option{--traditional-format}
+
+@kindex --traditional-format
+For some targets, the output of @command{@value{AS}} is different in some ways
+from the output of some existing assembler. This switch requests
+@command{@value{AS}} to use the traditional format instead.
+
+For example, it disables the exception frame optimizations which
+@command{@value{AS}} normally does by default on @code{@value{GCC}} output.
+
+@node v
+@section Announce Version: @option{-v}
+
+@kindex -v
+@kindex -version
+@cindex assembler version
+@cindex version of assembler
+You can find out what version of as is running by including the
+option @samp{-v} (which you can also spell as @samp{-version}) on the
+command line.
+
+@node W
+@section Control Warnings: @option{-W}, @option{--warn}, @option{--no-warn}, @option{--fatal-warnings}
+
+@command{@value{AS}} should never give a warning or error message when
+assembling compiler output. But programs written by people often
+cause @command{@value{AS}} to give a warning that a particular assumption was
+made. All such warnings are directed to the standard error file.
+
+@kindex -W
+@kindex --no-warn
+@cindex suppressing warnings
+@cindex warnings, suppressing
+If you use the @option{-W} and @option{--no-warn} options, no warnings are issued.
+This only affects the warning messages: it does not change any particular of
+how @command{@value{AS}} assembles your file. Errors, which stop the assembly,
+are still reported.
+
+@kindex --fatal-warnings
+@cindex errors, caused by warnings
+@cindex warnings, causing error
+If you use the @option{--fatal-warnings} option, @command{@value{AS}} considers
+files that generate warnings to be in error.
+
+@kindex --warn
+@cindex warnings, switching on
+You can switch these options off again by specifying @option{--warn}, which
+causes warnings to be output as usual.
+
+@node Z
+@section Generate Object File in Spite of Errors: @option{-Z}
+@cindex object file, after errors
+@cindex errors, continuing after
+After an error message, @command{@value{AS}} normally produces no output. If for
+some reason you are interested in object file output even after
+@command{@value{AS}} gives an error message on your program, use the @samp{-Z}
+option. If there are any errors, @command{@value{AS}} continues anyways, and
+writes an object file after a final warning message of the form @samp{@var{n}
+errors, @var{m} warnings, generating bad object file.}
+
+@node Syntax
+@chapter Syntax
+
+@cindex machine-independent syntax
+@cindex syntax, machine-independent
+This chapter describes the machine-independent syntax allowed in a
+source file. @command{@value{AS}} syntax is similar to what many other
+assemblers use; it is inspired by the BSD 4.2
+@ifclear VAX
+assembler.
+@end ifclear
+@ifset VAX
+assembler, except that @command{@value{AS}} does not assemble Vax bit-fields.
+@end ifset
+
+@menu
+* Preprocessing:: Preprocessing
+* Whitespace:: Whitespace
+* Comments:: Comments
+* Symbol Intro:: Symbols
+* Statements:: Statements
+* Constants:: Constants
+@end menu
+
+@node Preprocessing
+@section Preprocessing
+
+@cindex preprocessing
+The @command{@value{AS}} internal preprocessor:
+@itemize @bullet
+@cindex whitespace, removed by preprocessor
+@item
+adjusts and removes extra whitespace. It leaves one space or tab before
+the keywords on a line, and turns any other whitespace on the line into
+a single space.
+
+@cindex comments, removed by preprocessor
+@item
+removes all comments, replacing them with a single space, or an
+appropriate number of newlines.
+
+@cindex constants, converted by preprocessor
+@item
+converts character constants into the appropriate numeric values.
+@end itemize
+
+It does not do macro processing, include file handling, or
+anything else you may get from your C compiler's preprocessor. You can
+do include file processing with the @code{.include} directive
+(@pxref{Include,,@code{.include}}). You can use the @sc{gnu} C compiler driver
+to get other ``CPP'' style preprocessing by giving the input file a
+@samp{.S} suffix. @xref{Overall Options,, Options Controlling the Kind of
+Output, gcc.info, Using GNU CC}.
+
+Excess whitespace, comments, and character constants
+cannot be used in the portions of the input text that are not
+preprocessed.
+
+@cindex turning preprocessing on and off
+@cindex preprocessing, turning on and off
+@kindex #NO_APP
+@kindex #APP
+If the first line of an input file is @code{#NO_APP} or if you use the
+@samp{-f} option, whitespace and comments are not removed from the input file.
+Within an input file, you can ask for whitespace and comment removal in
+specific portions of the by putting a line that says @code{#APP} before the
+text that may contain whitespace or comments, and putting a line that says
+@code{#NO_APP} after this text. This feature is mainly intend to support
+@code{asm} statements in compilers whose output is otherwise free of comments
+and whitespace.
+
+@node Whitespace
+@section Whitespace
+
+@cindex whitespace
+@dfn{Whitespace} is one or more blanks or tabs, in any order.
+Whitespace is used to separate symbols, and to make programs neater for
+people to read. Unless within character constants
+(@pxref{Characters,,Character Constants}), any whitespace means the same
+as exactly one space.
+
+@node Comments
+@section Comments
+
+@cindex comments
+There are two ways of rendering comments to @command{@value{AS}}. In both
+cases the comment is equivalent to one space.
+
+Anything from @samp{/*} through the next @samp{*/} is a comment.
+This means you may not nest these comments.
+
+@smallexample
+/*
+ The only way to include a newline ('\n') in a comment
+ is to use this sort of comment.
+*/
+
+/* This sort of comment does not nest. */
+@end smallexample
+
+@cindex line comment character
+Anything from the @dfn{line comment} character to the next newline
+is considered a comment and is ignored. The line comment character is
+@ifset A29K
+@samp{;} for the AMD 29K family;
+@end ifset
+@ifset ARC
+@samp{;} on the ARC;
+@end ifset
+@ifset ARM
+@samp{@@} on the ARM;
+@end ifset
+@ifset H8/300
+@samp{;} for the H8/300 family;
+@end ifset
+@ifset H8/500
+@samp{!} for the H8/500 family;
+@end ifset
+@ifset HPPA
+@samp{;} for the HPPA;
+@end ifset
+@ifset I80386
+@samp{#} on the i386 and x86-64;
+@end ifset
+@ifset I960
+@samp{#} on the i960;
+@end ifset
+@ifset PDP11
+@samp{;} for the PDP-11;
+@end ifset
+@ifset PJ
+@samp{;} for picoJava;
+@end ifset
+@ifset PPC
+@samp{#} for Motorola PowerPC;
+@end ifset
+@ifset SH
+@samp{!} for the Renesas / SuperH SH;
+@end ifset
+@ifset SPARC
+@samp{!} on the SPARC;
+@end ifset
+@ifset IP2K
+@samp{#} on the ip2k;
+@end ifset
+@ifset M32R
+@samp{#} on the m32r;
+@end ifset
+@ifset M680X0
+@samp{|} on the 680x0;
+@end ifset
+@ifset M68HC11
+@samp{#} on the 68HC11 and 68HC12;
+@end ifset
+@ifset M880X0
+@samp{;} on the M880x0;
+@end ifset
+@ifset VAX
+@samp{#} on the Vax;
+@end ifset
+@ifset Z8000
+@samp{!} for the Z8000;
+@end ifset
+@ifset V850
+@samp{#} on the V850;
+@end ifset
+@ifset XTENSA
+@samp{#} for Xtensa systems;
+@end ifset
+see @ref{Machine Dependencies}. @refill
+@c FIXME What about i860?
+
+@ifset GENERIC
+On some machines there are two different line comment characters. One
+character only begins a comment if it is the first non-whitespace character on
+a line, while the other always begins a comment.
+@end ifset
+
+@ifset V850
+The V850 assembler also supports a double dash as starting a comment that
+extends to the end of the line.
+
+@samp{--};
+@end ifset
+
+@kindex #
+@cindex lines starting with @code{#}
+@cindex logical line numbers
+To be compatible with past assemblers, lines that begin with @samp{#} have a
+special interpretation. Following the @samp{#} should be an absolute
+expression (@pxref{Expressions}): the logical line number of the @emph{next}
+line. Then a string (@pxref{Strings,, Strings}) is allowed: if present it is a
+new logical file name. The rest of the line, if any, should be whitespace.
+
+If the first non-whitespace characters on the line are not numeric,
+the line is ignored. (Just like a comment.)
+
+@smallexample
+ # This is an ordinary comment.
+# 42-6 "new_file_name" # New logical file name
+ # This is logical line # 36.
+@end smallexample
+This feature is deprecated, and may disappear from future versions
+of @command{@value{AS}}.
+
+@node Symbol Intro
+@section Symbols
+
+@cindex characters used in symbols
+@ifclear SPECIAL-SYMS
+A @dfn{symbol} is one or more characters chosen from the set of all
+letters (both upper and lower case), digits and the three characters
+@samp{_.$}.
+@end ifclear
+@ifset SPECIAL-SYMS
+@ifclear GENERIC
+@ifset H8
+A @dfn{symbol} is one or more characters chosen from the set of all
+letters (both upper and lower case), digits and the three characters
+@samp{._$}. (Save that, on the H8/300 only, you may not use @samp{$} in
+symbol names.)
+@end ifset
+@end ifclear
+@end ifset
+@ifset GENERIC
+On most machines, you can also use @code{$} in symbol names; exceptions
+are noted in @ref{Machine Dependencies}.
+@end ifset
+No symbol may begin with a digit. Case is significant.
+There is no length limit: all characters are significant. Symbols are
+delimited by characters not in that set, or by the beginning of a file
+(since the source program must end with a newline, the end of a file is
+not a possible symbol delimiter). @xref{Symbols}.
+@cindex length of symbols
+
+@node Statements
+@section Statements
+
+@cindex statements, structure of
+@cindex line separator character
+@cindex statement separator character
+@ifclear GENERIC
+@ifclear abnormal-separator
+A @dfn{statement} ends at a newline character (@samp{\n}) or at a
+semicolon (@samp{;}). The newline or semicolon is considered part of
+the preceding statement. Newlines and semicolons within character
+constants are an exception: they do not end statements.
+@end ifclear
+@ifset abnormal-separator
+@ifset A29K
+A @dfn{statement} ends at a newline character (@samp{\n}) or an ``at''
+sign (@samp{@@}). The newline or at sign is considered part of the
+preceding statement. Newlines and at signs within character constants
+are an exception: they do not end statements.
+@end ifset
+@ifset HPPA
+A @dfn{statement} ends at a newline character (@samp{\n}) or an exclamation
+point (@samp{!}). The newline or exclamation point is considered part of the
+preceding statement. Newlines and exclamation points within character
+constants are an exception: they do not end statements.
+@end ifset
+@ifset H8
+A @dfn{statement} ends at a newline character (@samp{\n}); or (for the
+H8/300) a dollar sign (@samp{$}); or (for the
+Renesas-SH or the
+H8/500) a semicolon
+(@samp{;}). The newline or separator character is considered part of
+the preceding statement. Newlines and separators within character
+constants are an exception: they do not end statements.
+@end ifset
+@end ifset
+@end ifclear
+@ifset GENERIC
+A @dfn{statement} ends at a newline character (@samp{\n}) or line
+separator character. (The line separator is usually @samp{;}, unless
+this conflicts with the comment character; @pxref{Machine Dependencies}.) The
+newline or separator character is considered part of the preceding
+statement. Newlines and separators within character constants are an
+exception: they do not end statements.
+@end ifset
+
+@cindex newline, required at file end
+@cindex EOF, newline must precede
+It is an error to end any statement with end-of-file: the last
+character of any input file should be a newline.@refill
+
+An empty statement is allowed, and may include whitespace. It is ignored.
+
+@cindex instructions and directives
+@cindex directives and instructions
+@c "key symbol" is not used elsewhere in the document; seems pedantic to
+@c @defn{} it in that case, as was done previously... doc@cygnus.com,
+@c 13feb91.
+A statement begins with zero or more labels, optionally followed by a
+key symbol which determines what kind of statement it is. The key
+symbol determines the syntax of the rest of the statement. If the
+symbol begins with a dot @samp{.} then the statement is an assembler
+directive: typically valid for any computer. If the symbol begins with
+a letter the statement is an assembly language @dfn{instruction}: it
+assembles into a machine language instruction.
+@ifset GENERIC
+Different versions of @command{@value{AS}} for different computers
+recognize different instructions. In fact, the same symbol may
+represent a different instruction in a different computer's assembly
+language.@refill
+@end ifset
+
+@cindex @code{:} (label)
+@cindex label (@code{:})
+A label is a symbol immediately followed by a colon (@code{:}).
+Whitespace before a label or after a colon is permitted, but you may not
+have whitespace between a label's symbol and its colon. @xref{Labels}.
+
+@ifset HPPA
+For HPPA targets, labels need not be immediately followed by a colon, but
+the definition of a label must begin in column zero. This also implies that
+only one label may be defined on each line.
+@end ifset
+
+@smallexample
+label: .directive followed by something
+another_label: # This is an empty statement.
+ instruction operand_1, operand_2, @dots{}
+@end smallexample
+
+@node Constants
+@section Constants
+
+@cindex constants
+A constant is a number, written so that its value is known by
+inspection, without knowing any context. Like this:
+@smallexample
+@group
+.byte 74, 0112, 092, 0x4A, 0X4a, 'J, '\J # All the same value.
+.ascii "Ring the bell\7" # A string constant.
+.octa 0x123456789abcdef0123456789ABCDEF0 # A bignum.
+.float 0f-314159265358979323846264338327\
+95028841971.693993751E-40 # - pi, a flonum.
+@end group
+@end smallexample
+
+@menu
+* Characters:: Character Constants
+* Numbers:: Number Constants
+@end menu
+
+@node Characters
+@subsection Character Constants
+
+@cindex character constants
+@cindex constants, character
+There are two kinds of character constants. A @dfn{character} stands
+for one character in one byte and its value may be used in
+numeric expressions. String constants (properly called string
+@emph{literals}) are potentially many bytes and their values may not be
+used in arithmetic expressions.
+
+@menu
+* Strings:: Strings
+* Chars:: Characters
+@end menu
+
+@node Strings
+@subsubsection Strings
+
+@cindex string constants
+@cindex constants, string
+A @dfn{string} is written between double-quotes. It may contain
+double-quotes or null characters. The way to get special characters
+into a string is to @dfn{escape} these characters: precede them with
+a backslash @samp{\} character. For example @samp{\\} represents
+one backslash: the first @code{\} is an escape which tells
+@command{@value{AS}} to interpret the second character literally as a backslash
+(which prevents @command{@value{AS}} from recognizing the second @code{\} as an
+escape character). The complete list of escapes follows.
+
+@cindex escape codes, character
+@cindex character escape codes
+@table @kbd
+@c @item \a
+@c Mnemonic for ACKnowledge; for ASCII this is octal code 007.
+@c
+@cindex @code{\b} (backspace character)
+@cindex backspace (@code{\b})
+@item \b
+Mnemonic for backspace; for ASCII this is octal code 010.
+
+@c @item \e
+@c Mnemonic for EOText; for ASCII this is octal code 004.
+@c
+@cindex @code{\f} (formfeed character)
+@cindex formfeed (@code{\f})
+@item \f
+Mnemonic for FormFeed; for ASCII this is octal code 014.
+
+@cindex @code{\n} (newline character)
+@cindex newline (@code{\n})
+@item \n
+Mnemonic for newline; for ASCII this is octal code 012.
+
+@c @item \p
+@c Mnemonic for prefix; for ASCII this is octal code 033, usually known as @code{escape}.
+@c
+@cindex @code{\r} (carriage return character)
+@cindex carriage return (@code{\r})
+@item \r
+Mnemonic for carriage-Return; for ASCII this is octal code 015.
+
+@c @item \s
+@c Mnemonic for space; for ASCII this is octal code 040. Included for compliance with
+@c other assemblers.
+@c
+@cindex @code{\t} (tab)
+@cindex tab (@code{\t})
+@item \t
+Mnemonic for horizontal Tab; for ASCII this is octal code 011.
+
+@c @item \v
+@c Mnemonic for Vertical tab; for ASCII this is octal code 013.
+@c @item \x @var{digit} @var{digit} @var{digit}
+@c A hexadecimal character code. The numeric code is 3 hexadecimal digits.
+@c
+@cindex @code{\@var{ddd}} (octal character code)
+@cindex octal character code (@code{\@var{ddd}})
+@item \ @var{digit} @var{digit} @var{digit}
+An octal character code. The numeric code is 3 octal digits.
+For compatibility with other Unix systems, 8 and 9 are accepted as digits:
+for example, @code{\008} has the value 010, and @code{\009} the value 011.
+
+@cindex @code{\@var{xd...}} (hex character code)
+@cindex hex character code (@code{\@var{xd...}})
+@item \@code{x} @var{hex-digits...}
+A hex character code. All trailing hex digits are combined. Either upper or
+lower case @code{x} works.
+
+@cindex @code{\\} (@samp{\} character)
+@cindex backslash (@code{\\})
+@item \\
+Represents one @samp{\} character.
+
+@c @item \'
+@c Represents one @samp{'} (accent acute) character.
+@c This is needed in single character literals
+@c (@xref{Characters,,Character Constants}.) to represent
+@c a @samp{'}.
+@c
+@cindex @code{\"} (doublequote character)
+@cindex doublequote (@code{\"})
+@item \"
+Represents one @samp{"} character. Needed in strings to represent
+this character, because an unescaped @samp{"} would end the string.
+
+@item \ @var{anything-else}
+Any other character when escaped by @kbd{\} gives a warning, but
+assembles as if the @samp{\} was not present. The idea is that if
+you used an escape sequence you clearly didn't want the literal
+interpretation of the following character. However @command{@value{AS}} has no
+other interpretation, so @command{@value{AS}} knows it is giving you the wrong
+code and warns you of the fact.
+@end table
+
+Which characters are escapable, and what those escapes represent,
+varies widely among assemblers. The current set is what we think
+the BSD 4.2 assembler recognizes, and is a subset of what most C
+compilers recognize. If you are in doubt, do not use an escape
+sequence.
+
+@node Chars
+@subsubsection Characters
+
+@cindex single character constant
+@cindex character, single
+@cindex constant, single character
+A single character may be written as a single quote immediately
+followed by that character. The same escapes apply to characters as
+to strings. So if you want to write the character backslash, you
+must write @kbd{'\\} where the first @code{\} escapes the second
+@code{\}. As you can see, the quote is an acute accent, not a
+grave accent. A newline
+@ifclear GENERIC
+@ifclear abnormal-separator
+(or semicolon @samp{;})
+@end ifclear
+@ifset abnormal-separator
+@ifset A29K
+(or at sign @samp{@@})
+@end ifset
+@ifset H8
+(or dollar sign @samp{$}, for the H8/300; or semicolon @samp{;} for the
+Renesas SH or H8/500)
+@end ifset
+@end ifset
+@end ifclear
+immediately following an acute accent is taken as a literal character
+and does not count as the end of a statement. The value of a character
+constant in a numeric expression is the machine's byte-wide code for
+that character. @command{@value{AS}} assumes your character code is ASCII:
+@kbd{'A} means 65, @kbd{'B} means 66, and so on. @refill
+
+@node Numbers
+@subsection Number Constants
+
+@cindex constants, number
+@cindex number constants
+@command{@value{AS}} distinguishes three kinds of numbers according to how they
+are stored in the target machine. @emph{Integers} are numbers that
+would fit into an @code{int} in the C language. @emph{Bignums} are
+integers, but they are stored in more than 32 bits. @emph{Flonums}
+are floating point numbers, described below.
+
+@menu
+* Integers:: Integers
+* Bignums:: Bignums
+* Flonums:: Flonums
+@ifclear GENERIC
+@ifset I960
+* Bit Fields:: Bit Fields
+@end ifset
+@end ifclear
+@end menu
+
+@node Integers
+@subsubsection Integers
+@cindex integers
+@cindex constants, integer
+
+@cindex binary integers
+@cindex integers, binary
+A binary integer is @samp{0b} or @samp{0B} followed by zero or more of
+the binary digits @samp{01}.
+
+@cindex octal integers
+@cindex integers, octal
+An octal integer is @samp{0} followed by zero or more of the octal
+digits (@samp{01234567}).
+
+@cindex decimal integers
+@cindex integers, decimal
+A decimal integer starts with a non-zero digit followed by zero or
+more digits (@samp{0123456789}).
+
+@cindex hexadecimal integers
+@cindex integers, hexadecimal
+A hexadecimal integer is @samp{0x} or @samp{0X} followed by one or
+more hexadecimal digits chosen from @samp{0123456789abcdefABCDEF}.
+
+Integers have the usual values. To denote a negative integer, use
+the prefix operator @samp{-} discussed under expressions
+(@pxref{Prefix Ops,,Prefix Operators}).
+
+@node Bignums
+@subsubsection Bignums
+
+@cindex bignums
+@cindex constants, bignum
+A @dfn{bignum} has the same syntax and semantics as an integer
+except that the number (or its negative) takes more than 32 bits to
+represent in binary. The distinction is made because in some places
+integers are permitted while bignums are not.
+
+@node Flonums
+@subsubsection Flonums
+@cindex flonums
+@cindex floating point numbers
+@cindex constants, floating point
+
+@cindex precision, floating point
+A @dfn{flonum} represents a floating point number. The translation is
+indirect: a decimal floating point number from the text is converted by
+@command{@value{AS}} to a generic binary floating point number of more than
+sufficient precision. This generic floating point number is converted
+to a particular computer's floating point format (or formats) by a
+portion of @command{@value{AS}} specialized to that computer.
+
+A flonum is written by writing (in order)
+@itemize @bullet
+@item
+The digit @samp{0}.
+@ifset HPPA
+(@samp{0} is optional on the HPPA.)
+@end ifset
+
+@item
+A letter, to tell @command{@value{AS}} the rest of the number is a flonum.
+@ifset GENERIC
+@kbd{e} is recommended. Case is not important.
+@ignore
+@c FIXME: verify if flonum syntax really this vague for most cases
+(Any otherwise illegal letter works here, but that might be changed. Vax BSD
+4.2 assembler seems to allow any of @samp{defghDEFGH}.)
+@end ignore
+
+On the H8/300, H8/500,
+Renesas / SuperH SH,
+and AMD 29K architectures, the letter must be
+one of the letters @samp{DFPRSX} (in upper or lower case).
+
+On the ARC, the letter must be one of the letters @samp{DFRS}
+(in upper or lower case).
+
+On the Intel 960 architecture, the letter must be
+one of the letters @samp{DFT} (in upper or lower case).
+
+On the HPPA architecture, the letter must be @samp{E} (upper case only).
+@end ifset
+@ifclear GENERIC
+@ifset A29K
+One of the letters @samp{DFPRSX} (in upper or lower case).
+@end ifset
+@ifset ARC
+One of the letters @samp{DFRS} (in upper or lower case).
+@end ifset
+@ifset H8
+One of the letters @samp{DFPRSX} (in upper or lower case).
+@end ifset
+@ifset HPPA
+The letter @samp{E} (upper case only).
+@end ifset
+@ifset I960
+One of the letters @samp{DFT} (in upper or lower case).
+@end ifset
+@end ifclear
+
+@item
+An optional sign: either @samp{+} or @samp{-}.
+
+@item
+An optional @dfn{integer part}: zero or more decimal digits.
+
+@item
+An optional @dfn{fractional part}: @samp{.} followed by zero
+or more decimal digits.
+
+@item
+An optional exponent, consisting of:
+
+@itemize @bullet
+@item
+An @samp{E} or @samp{e}.
+@c I can't find a config where "EXP_CHARS" is other than 'eE', but in
+@c principle this can perfectly well be different on different targets.
+@item
+Optional sign: either @samp{+} or @samp{-}.
+@item
+One or more decimal digits.
+@end itemize
+
+@end itemize
+
+At least one of the integer part or the fractional part must be
+present. The floating point number has the usual base-10 value.
+
+@command{@value{AS}} does all processing using integers. Flonums are computed
+independently of any floating point hardware in the computer running
+@command{@value{AS}}.
+
+@ifclear GENERIC
+@ifset I960
+@c Bit fields are written as a general facility but are also controlled
+@c by a conditional-compilation flag---which is as of now (21mar91)
+@c turned on only by the i960 config of GAS.
+@node Bit Fields
+@subsubsection Bit Fields
+
+@cindex bit fields
+@cindex constants, bit field
+You can also define numeric constants as @dfn{bit fields}.
+specify two numbers separated by a colon---
+@example
+@var{mask}:@var{value}
+@end example
+@noindent
+@command{@value{AS}} applies a bitwise @sc{and} between @var{mask} and
+@var{value}.
+
+The resulting number is then packed
+@ifset GENERIC
+@c this conditional paren in case bit fields turned on elsewhere than 960
+(in host-dependent byte order)
+@end ifset
+into a field whose width depends on which assembler directive has the
+bit-field as its argument. Overflow (a result from the bitwise and
+requiring more binary digits to represent) is not an error; instead,
+more constants are generated, of the specified width, beginning with the
+least significant digits.@refill
+
+The directives @code{.byte}, @code{.hword}, @code{.int}, @code{.long},
+@code{.short}, and @code{.word} accept bit-field arguments.
+@end ifset
+@end ifclear
+
+@node Sections
+@chapter Sections and Relocation
+@cindex sections
+@cindex relocation
+
+@menu
+* Secs Background:: Background
+* Ld Sections:: Linker Sections
+* As Sections:: Assembler Internal Sections
+* Sub-Sections:: Sub-Sections
+* bss:: bss Section
+@end menu
+
+@node Secs Background
+@section Background
+
+Roughly, a section is a range of addresses, with no gaps; all data
+``in'' those addresses is treated the same for some particular purpose.
+For example there may be a ``read only'' section.
+
+@cindex linker, and assembler
+@cindex assembler, and linker
+The linker @code{@value{LD}} reads many object files (partial programs) and
+combines their contents to form a runnable program. When @command{@value{AS}}
+emits an object file, the partial program is assumed to start at address 0.
+@code{@value{LD}} assigns the final addresses for the partial program, so that
+different partial programs do not overlap. This is actually an
+oversimplification, but it suffices to explain how @command{@value{AS}} uses
+sections.
+
+@code{@value{LD}} moves blocks of bytes of your program to their run-time
+addresses. These blocks slide to their run-time addresses as rigid
+units; their length does not change and neither does the order of bytes
+within them. Such a rigid unit is called a @emph{section}. Assigning
+run-time addresses to sections is called @dfn{relocation}. It includes
+the task of adjusting mentions of object-file addresses so they refer to
+the proper run-time addresses.
+@ifset H8
+For the H8/300 and H8/500,
+and for the Renesas / SuperH SH,
+@command{@value{AS}} pads sections if needed to
+ensure they end on a word (sixteen bit) boundary.
+@end ifset
+
+@cindex standard assembler sections
+An object file written by @command{@value{AS}} has at least three sections, any
+of which may be empty. These are named @dfn{text}, @dfn{data} and
+@dfn{bss} sections.
+
+@ifset COFF-ELF
+@ifset GENERIC
+When it generates COFF or ELF output,
+@end ifset
+@command{@value{AS}} can also generate whatever other named sections you specify
+using the @samp{.section} directive (@pxref{Section,,@code{.section}}).
+If you do not use any directives that place output in the @samp{.text}
+or @samp{.data} sections, these sections still exist, but are empty.
+@end ifset
+
+@ifset HPPA
+@ifset GENERIC
+When @command{@value{AS}} generates SOM or ELF output for the HPPA,
+@end ifset
+@command{@value{AS}} can also generate whatever other named sections you
+specify using the @samp{.space} and @samp{.subspace} directives. See
+@cite{HP9000 Series 800 Assembly Language Reference Manual}
+(HP 92432-90001) for details on the @samp{.space} and @samp{.subspace}
+assembler directives.
+
+@ifset SOM
+Additionally, @command{@value{AS}} uses different names for the standard
+text, data, and bss sections when generating SOM output. Program text
+is placed into the @samp{$CODE$} section, data into @samp{$DATA$}, and
+BSS into @samp{$BSS$}.
+@end ifset
+@end ifset
+
+Within the object file, the text section starts at address @code{0}, the
+data section follows, and the bss section follows the data section.
+
+@ifset HPPA
+When generating either SOM or ELF output files on the HPPA, the text
+section starts at address @code{0}, the data section at address
+@code{0x4000000}, and the bss section follows the data section.
+@end ifset
+
+To let @code{@value{LD}} know which data changes when the sections are
+relocated, and how to change that data, @command{@value{AS}} also writes to the
+object file details of the relocation needed. To perform relocation
+@code{@value{LD}} must know, each time an address in the object
+file is mentioned:
+@itemize @bullet
+@item
+Where in the object file is the beginning of this reference to
+an address?
+@item
+How long (in bytes) is this reference?
+@item
+Which section does the address refer to? What is the numeric value of
+@display
+(@var{address}) @minus{} (@var{start-address of section})?
+@end display
+@item
+Is the reference to an address ``Program-Counter relative''?
+@end itemize
+
+@cindex addresses, format of
+@cindex section-relative addressing
+In fact, every address @command{@value{AS}} ever uses is expressed as
+@display
+(@var{section}) + (@var{offset into section})
+@end display
+@noindent
+Further, most expressions @command{@value{AS}} computes have this section-relative
+nature.
+@ifset SOM
+(For some object formats, such as SOM for the HPPA, some expressions are
+symbol-relative instead.)
+@end ifset
+
+In this manual we use the notation @{@var{secname} @var{N}@} to mean ``offset
+@var{N} into section @var{secname}.''
+
+Apart from text, data and bss sections you need to know about the
+@dfn{absolute} section. When @code{@value{LD}} mixes partial programs,
+addresses in the absolute section remain unchanged. For example, address
+@code{@{absolute 0@}} is ``relocated'' to run-time address 0 by
+@code{@value{LD}}. Although the linker never arranges two partial programs'
+data sections with overlapping addresses after linking, @emph{by definition}
+their absolute sections must overlap. Address @code{@{absolute@ 239@}} in one
+part of a program is always the same address when the program is running as
+address @code{@{absolute@ 239@}} in any other part of the program.
+
+The idea of sections is extended to the @dfn{undefined} section. Any
+address whose section is unknown at assembly time is by definition
+rendered @{undefined @var{U}@}---where @var{U} is filled in later.
+Since numbers are always defined, the only way to generate an undefined
+address is to mention an undefined symbol. A reference to a named
+common block would be such a symbol: its value is unknown at assembly
+time so it has section @emph{undefined}.
+
+By analogy the word @emph{section} is used to describe groups of sections in
+the linked program. @code{@value{LD}} puts all partial programs' text
+sections in contiguous addresses in the linked program. It is
+customary to refer to the @emph{text section} of a program, meaning all
+the addresses of all partial programs' text sections. Likewise for
+data and bss sections.
+
+Some sections are manipulated by @code{@value{LD}}; others are invented for
+use of @command{@value{AS}} and have no meaning except during assembly.
+
+@node Ld Sections
+@section Linker Sections
+@code{@value{LD}} deals with just four kinds of sections, summarized below.
+
+@table @strong
+
+@ifset COFF-ELF
+@cindex named sections
+@cindex sections, named
+@item named sections
+@end ifset
+@ifset aout-bout
+@cindex text section
+@cindex data section
+@itemx text section
+@itemx data section
+@end ifset
+These sections hold your program. @command{@value{AS}} and @code{@value{LD}} treat them as
+separate but equal sections. Anything you can say of one section is
+true of another.
+@c @ifset aout-bout
+When the program is running, however, it is
+customary for the text section to be unalterable. The
+text section is often shared among processes: it contains
+instructions, constants and the like. The data section of a running
+program is usually alterable: for example, C variables would be stored
+in the data section.
+@c @end ifset
+
+@cindex bss section
+@item bss section
+This section contains zeroed bytes when your program begins running. It
+is used to hold uninitialized variables or common storage. The length of
+each partial program's bss section is important, but because it starts
+out containing zeroed bytes there is no need to store explicit zero
+bytes in the object file. The bss section was invented to eliminate
+those explicit zeros from object files.
+
+@cindex absolute section
+@item absolute section
+Address 0 of this section is always ``relocated'' to runtime address 0.
+This is useful if you want to refer to an address that @code{@value{LD}} must
+not change when relocating. In this sense we speak of absolute
+addresses being ``unrelocatable'': they do not change during relocation.
+
+@cindex undefined section
+@item undefined section
+This ``section'' is a catch-all for address references to objects not in
+the preceding sections.
+@c FIXME: ref to some other doc on obj-file formats could go here.
+@end table
+
+@cindex relocation example
+An idealized example of three relocatable sections follows.
+@ifset COFF-ELF
+The example uses the traditional section names @samp{.text} and @samp{.data}.
+@end ifset
+Memory addresses are on the horizontal axis.
+
+@c TEXI2ROFF-KILL
+@ifnottex
+@c END TEXI2ROFF-KILL
+@smallexample
+ +-----+----+--+
+partial program # 1: |ttttt|dddd|00|
+ +-----+----+--+
+
+ text data bss
+ seg. seg. seg.
+
+ +---+---+---+
+partial program # 2: |TTT|DDD|000|
+ +---+---+---+
+
+ +--+---+-----+--+----+---+-----+~~
+linked program: | |TTT|ttttt| |dddd|DDD|00000|
+ +--+---+-----+--+----+---+-----+~~
+
+ addresses: 0 @dots{}
+@end smallexample
+@c TEXI2ROFF-KILL
+@end ifnottex
+@need 5000
+@tex
+\bigskip
+\line{\it Partial program \#1: \hfil}
+\line{\ibox{2.5cm}{\tt text}\ibox{2cm}{\tt data}\ibox{1cm}{\tt bss}\hfil}
+\line{\boxit{2.5cm}{\tt ttttt}\boxit{2cm}{\tt dddd}\boxit{1cm}{\tt 00}\hfil}
+
+\line{\it Partial program \#2: \hfil}
+\line{\ibox{1cm}{\tt text}\ibox{1.5cm}{\tt data}\ibox{1cm}{\tt bss}\hfil}
+\line{\boxit{1cm}{\tt TTT}\boxit{1.5cm}{\tt DDDD}\boxit{1cm}{\tt 000}\hfil}
+
+\line{\it linked program: \hfil}
+\line{\ibox{.5cm}{}\ibox{1cm}{\tt text}\ibox{2.5cm}{}\ibox{.75cm}{}\ibox{2cm}{\tt data}\ibox{1.5cm}{}\ibox{2cm}{\tt bss}\hfil}
+\line{\boxit{.5cm}{}\boxit{1cm}{\tt TTT}\boxit{2.5cm}{\tt
+ttttt}\boxit{.75cm}{}\boxit{2cm}{\tt dddd}\boxit{1.5cm}{\tt
+DDDD}\boxit{2cm}{\tt 00000}\ \dots\hfil}
+
+\line{\it addresses: \hfil}
+\line{0\dots\hfil}
+
+@end tex
+@c END TEXI2ROFF-KILL
+
+@node As Sections
+@section Assembler Internal Sections
+
+@cindex internal assembler sections
+@cindex sections in messages, internal
+These sections are meant only for the internal use of @command{@value{AS}}. They
+have no meaning at run-time. You do not really need to know about these
+sections for most purposes; but they can be mentioned in @command{@value{AS}}
+warning messages, so it might be helpful to have an idea of their
+meanings to @command{@value{AS}}. These sections are used to permit the
+value of every expression in your assembly language program to be a
+section-relative address.
+
+@table @b
+@cindex assembler internal logic error
+@item ASSEMBLER-INTERNAL-LOGIC-ERROR!
+An internal assembler logic error has been found. This means there is a
+bug in the assembler.
+
+@cindex expr (internal section)
+@item expr section
+The assembler stores complex expression internally as combinations of
+symbols. When it needs to represent an expression as a symbol, it puts
+it in the expr section.
+@c FIXME item debug
+@c FIXME item transfer[t] vector preload
+@c FIXME item transfer[t] vector postload
+@c FIXME item register
+@end table
+
+@node Sub-Sections
+@section Sub-Sections
+
+@cindex numbered subsections
+@cindex grouping data
+@ifset aout-bout
+Assembled bytes
+@ifset COFF-ELF
+conventionally
+@end ifset
+fall into two sections: text and data.
+@end ifset
+You may have separate groups of
+@ifset GENERIC
+data in named sections
+@end ifset
+@ifclear GENERIC
+@ifclear aout-bout
+data in named sections
+@end ifclear
+@ifset aout-bout
+text or data
+@end ifset
+@end ifclear
+that you want to end up near to each other in the object file, even though they
+are not contiguous in the assembler source. @command{@value{AS}} allows you to
+use @dfn{subsections} for this purpose. Within each section, there can be
+numbered subsections with values from 0 to 8192. Objects assembled into the
+same subsection go into the object file together with other objects in the same
+subsection. For example, a compiler might want to store constants in the text
+section, but might not want to have them interspersed with the program being
+assembled. In this case, the compiler could issue a @samp{.text 0} before each
+section of code being output, and a @samp{.text 1} before each group of
+constants being output.
+
+Subsections are optional. If you do not use subsections, everything
+goes in subsection number zero.
+
+@ifset GENERIC
+Each subsection is zero-padded up to a multiple of four bytes.
+(Subsections may be padded a different amount on different flavors
+of @command{@value{AS}}.)
+@end ifset
+@ifclear GENERIC
+@ifset H8
+On the H8/300 and H8/500 platforms, each subsection is zero-padded to a word
+boundary (two bytes).
+The same is true on the Renesas SH.
+@end ifset
+@ifset I960
+@c FIXME section padding (alignment)?
+@c Rich Pixley says padding here depends on target obj code format; that
+@c doesn't seem particularly useful to say without further elaboration,
+@c so for now I say nothing about it. If this is a generic BFD issue,
+@c these paragraphs might need to vanish from this manual, and be
+@c discussed in BFD chapter of binutils (or some such).
+@end ifset
+@ifset A29K
+On the AMD 29K family, no particular padding is added to section or
+subsection sizes; @value{AS} forces no alignment on this platform.
+@end ifset
+@end ifclear
+
+Subsections appear in your object file in numeric order, lowest numbered
+to highest. (All this to be compatible with other people's assemblers.)
+The object file contains no representation of subsections; @code{@value{LD}} and
+other programs that manipulate object files see no trace of them.
+They just see all your text subsections as a text section, and all your
+data subsections as a data section.
+
+To specify which subsection you want subsequent statements assembled
+into, use a numeric argument to specify it, in a @samp{.text
+@var{expression}} or a @samp{.data @var{expression}} statement.
+@ifset COFF-ELF
+@ifset GENERIC
+When generating COFF or ELF output, you
+@end ifset
+@ifclear GENERIC
+You
+@end ifclear
+can also use an extra subsection
+argument with arbitrary named sections: @samp{.section @var{name},
+@var{expression}}.
+@end ifset
+@var{Expression} should be an absolute expression.
+(@xref{Expressions}.) If you just say @samp{.text} then @samp{.text 0}
+is assumed. Likewise @samp{.data} means @samp{.data 0}. Assembly
+begins in @code{text 0}. For instance:
+@smallexample
+.text 0 # The default subsection is text 0 anyway.
+.ascii "This lives in the first text subsection. *"
+.text 1
+.ascii "But this lives in the second text subsection."
+.data 0
+.ascii "This lives in the data section,"
+.ascii "in the first data subsection."
+.text 0
+.ascii "This lives in the first text section,"
+.ascii "immediately following the asterisk (*)."
+@end smallexample
+
+Each section has a @dfn{location counter} incremented by one for every byte
+assembled into that section. Because subsections are merely a convenience
+restricted to @command{@value{AS}} there is no concept of a subsection location
+counter. There is no way to directly manipulate a location counter---but the
+@code{.align} directive changes it, and any label definition captures its
+current value. The location counter of the section where statements are being
+assembled is said to be the @dfn{active} location counter.
+
+@node bss
+@section bss Section
+
+@cindex bss section
+@cindex common variable storage
+The bss section is used for local common variable storage.
+You may allocate address space in the bss section, but you may
+not dictate data to load into it before your program executes. When
+your program starts running, all the contents of the bss
+section are zeroed bytes.
+
+The @code{.lcomm} pseudo-op defines a symbol in the bss section; see
+@ref{Lcomm,,@code{.lcomm}}.
+
+The @code{.comm} pseudo-op may be used to declare a common symbol, which is
+another form of uninitialized symbol; see @xref{Comm,,@code{.comm}}.
+
+@ifset GENERIC
+When assembling for a target which supports multiple sections, such as ELF or
+COFF, you may switch into the @code{.bss} section and define symbols as usual;
+see @ref{Section,,@code{.section}}. You may only assemble zero values into the
+section. Typically the section will only contain symbol definitions and
+@code{.skip} directives (@pxref{Skip,,@code{.skip}}).
+@end ifset
+
+@node Symbols
+@chapter Symbols
+
+@cindex symbols
+Symbols are a central concept: the programmer uses symbols to name
+things, the linker uses symbols to link, and the debugger uses symbols
+to debug.
+
+@quotation
+@cindex debuggers, and symbol order
+@emph{Warning:} @command{@value{AS}} does not place symbols in the object file in
+the same order they were declared. This may break some debuggers.
+@end quotation
+
+@menu
+* Labels:: Labels
+* Setting Symbols:: Giving Symbols Other Values
+* Symbol Names:: Symbol Names
+* Dot:: The Special Dot Symbol
+* Symbol Attributes:: Symbol Attributes
+@end menu
+
+@node Labels
+@section Labels
+
+@cindex labels
+A @dfn{label} is written as a symbol immediately followed by a colon
+@samp{:}. The symbol then represents the current value of the
+active location counter, and is, for example, a suitable instruction
+operand. You are warned if you use the same symbol to represent two
+different locations: the first definition overrides any other
+definitions.
+
+@ifset HPPA
+On the HPPA, the usual form for a label need not be immediately followed by a
+colon, but instead must start in column zero. Only one label may be defined on
+a single line. To work around this, the HPPA version of @command{@value{AS}} also
+provides a special directive @code{.label} for defining labels more flexibly.
+@end ifset
+
+@node Setting Symbols
+@section Giving Symbols Other Values
+
+@cindex assigning values to symbols
+@cindex symbol values, assigning
+A symbol can be given an arbitrary value by writing a symbol, followed
+by an equals sign @samp{=}, followed by an expression
+(@pxref{Expressions}). This is equivalent to using the @code{.set}
+directive. @xref{Set,,@code{.set}}.
+
+@node Symbol Names
+@section Symbol Names
+
+@cindex symbol names
+@cindex names, symbol
+@ifclear SPECIAL-SYMS
+Symbol names begin with a letter or with one of @samp{._}. On most
+machines, you can also use @code{$} in symbol names; exceptions are
+noted in @ref{Machine Dependencies}. That character may be followed by any
+string of digits, letters, dollar signs (unless otherwise noted in
+@ref{Machine Dependencies}), and underscores.
+@end ifclear
+@ifset A29K
+For the AMD 29K family, @samp{?} is also allowed in the
+body of a symbol name, though not at its beginning.
+@end ifset
+
+@ifset SPECIAL-SYMS
+@ifset H8
+Symbol names begin with a letter or with one of @samp{._}. On the
+Renesas SH or the H8/500, you can also use @code{$} in symbol names. That
+character may be followed by any string of digits, letters, dollar signs (save
+on the H8/300), and underscores.
+@end ifset
+@end ifset
+
+Case of letters is significant: @code{foo} is a different symbol name
+than @code{Foo}.
+
+Each symbol has exactly one name. Each name in an assembly language program
+refers to exactly one symbol. You may use that symbol name any number of times
+in a program.
+
+@subheading Local Symbol Names
+
+@cindex local symbol names
+@cindex symbol names, local
+@cindex temporary symbol names
+@cindex symbol names, temporary
+Local symbols help compilers and programmers use names temporarily.
+They create symbols which are guaranteed to be unique over the entire scope of
+the input source code and which can be referred to by a simple notation.
+To define a local symbol, write a label of the form @samp{@b{N}:} (where @b{N}
+represents any positive integer). To refer to the most recent previous
+definition of that symbol write @samp{@b{N}b}, using the same number as when
+you defined the label. To refer to the next definition of a local label, write
+@samp{@b{N}f}--- The @samp{b} stands for``backwards'' and the @samp{f} stands
+for ``forwards''.
+
+There is no restriction on how you can use these labels, and you can reuse them
+too. So that it is possible to repeatedly define the same local label (using
+the same number @samp{@b{N}}), although you can only refer to the most recently
+defined local label of that number (for a backwards reference) or the next
+definition of a specific local label for a forward reference. It is also worth
+noting that the first 10 local labels (@samp{@b{0:}}@dots{}@samp{@b{9:}}) are
+implemented in a slightly more efficient manner than the others.
+
+Here is an example:
+
+@smallexample
+1: branch 1f
+2: branch 1b
+1: branch 2f
+2: branch 1b
+@end smallexample
+
+Which is the equivalent of:
+
+@smallexample
+label_1: branch label_3
+label_2: branch label_1
+label_3: branch label_4
+label_4: branch label_3
+@end smallexample
+
+Local symbol names are only a notational device. They are immediately
+transformed into more conventional symbol names before the assembler uses them.
+The symbol names stored in the symbol table, appearing in error messages and
+optionally emitted to the object file. The names are constructed using these
+parts:
+
+@table @code
+@item L
+All local labels begin with @samp{L}. Normally both @command{@value{AS}} and
+@code{@value{LD}} forget symbols that start with @samp{L}. These labels are
+used for symbols you are never intended to see. If you use the
+@samp{-L} option then @command{@value{AS}} retains these symbols in the
+object file. If you also instruct @code{@value{LD}} to retain these symbols,
+you may use them in debugging.
+
+@item @var{number}
+This is the number that was used in the local label definition. So if the
+label is written @samp{55:} then the number is @samp{55}.
+
+@item @kbd{C-B}
+This unusual character is included so you do not accidentally invent a symbol
+of the same name. The character has ASCII value of @samp{\002} (control-B).
+
+@item @emph{ordinal number}
+This is a serial number to keep the labels distinct. The first definition of
+@samp{0:} gets the number @samp{1}. The 15th definition of @samp{0:} gets the
+number @samp{15}, and so on. Likewise the first definition of @samp{1:} gets
+the number @samp{1} and its 15th defintion gets @samp{15} as well.
+@end table
+
+So for example, the first @code{1:} is named @code{L1@kbd{C-B}1}, the 44th
+@code{3:} is named @code{L3@kbd{C-B}44}.
+
+@subheading Dollar Local Labels
+@cindex dollar local symbols
+
+@code{@value{AS}} also supports an even more local form of local labels called
+dollar labels. These labels go out of scope (ie they become undefined) as soon
+as a non-local label is defined. Thus they remain valid for only a small
+region of the input source code. Normal local labels, by contrast, remain in
+scope for the entire file, or until they are redefined by another occurrence of
+the same local label.
+
+Dollar labels are defined in exactly the same way as ordinary local labels,
+except that instead of being terminated by a colon, they are terminated by a
+dollar sign. eg @samp{@b{55$}}.
+
+They can also be distinguished from ordinary local labels by their transformed
+name which uses ASCII character @samp{\001} (control-A) as the magic character
+to distinguish them from ordinary labels. Thus the 5th defintion of @samp{6$}
+is named @samp{L6@kbd{C-A}5}.
+
+@node Dot
+@section The Special Dot Symbol
+
+@cindex dot (symbol)
+@cindex @code{.} (symbol)
+@cindex current address
+@cindex location counter
+The special symbol @samp{.} refers to the current address that
+@command{@value{AS}} is assembling into. Thus, the expression @samp{melvin:
+.long .} defines @code{melvin} to contain its own address.
+Assigning a value to @code{.} is treated the same as a @code{.org}
+directive. Thus, the expression @samp{.=.+4} is the same as saying
+@ifclear no-space-dir
+@samp{.space 4}.
+@end ifclear
+@ifset no-space-dir
+@ifset A29K
+@samp{.block 4}.
+@end ifset
+@end ifset
+
+@node Symbol Attributes
+@section Symbol Attributes
+
+@cindex symbol attributes
+@cindex attributes, symbol
+Every symbol has, as well as its name, the attributes ``Value'' and
+``Type''. Depending on output format, symbols can also have auxiliary
+attributes.
+@ifset INTERNALS
+The detailed definitions are in @file{a.out.h}.
+@end ifset
+
+If you use a symbol without defining it, @command{@value{AS}} assumes zero for
+all these attributes, and probably won't warn you. This makes the
+symbol an externally defined symbol, which is generally what you
+would want.
+
+@menu
+* Symbol Value:: Value
+* Symbol Type:: Type
+@ifset aout-bout
+@ifset GENERIC
+* a.out Symbols:: Symbol Attributes: @code{a.out}
+@end ifset
+@ifclear GENERIC
+@ifclear BOUT
+* a.out Symbols:: Symbol Attributes: @code{a.out}
+@end ifclear
+@ifset BOUT
+* a.out Symbols:: Symbol Attributes: @code{a.out}, @code{b.out}
+@end ifset
+@end ifclear
+@end ifset
+@ifset COFF
+* COFF Symbols:: Symbol Attributes for COFF
+@end ifset
+@ifset SOM
+* SOM Symbols:: Symbol Attributes for SOM
+@end ifset
+@end menu
+
+@node Symbol Value
+@subsection Value
+
+@cindex value of a symbol
+@cindex symbol value
+The value of a symbol is (usually) 32 bits. For a symbol which labels a
+location in the text, data, bss or absolute sections the value is the
+number of addresses from the start of that section to the label.
+Naturally for text, data and bss sections the value of a symbol changes
+as @code{@value{LD}} changes section base addresses during linking. Absolute
+symbols' values do not change during linking: that is why they are
+called absolute.
+
+The value of an undefined symbol is treated in a special way. If it is
+0 then the symbol is not defined in this assembler source file, and
+@code{@value{LD}} tries to determine its value from other files linked into the
+same program. You make this kind of symbol simply by mentioning a symbol
+name without defining it. A non-zero value represents a @code{.comm}
+common declaration. The value is how much common storage to reserve, in
+bytes (addresses). The symbol refers to the first address of the
+allocated storage.
+
+@node Symbol Type
+@subsection Type
+
+@cindex type of a symbol
+@cindex symbol type
+The type attribute of a symbol contains relocation (section)
+information, any flag settings indicating that a symbol is external, and
+(optionally), other information for linkers and debuggers. The exact
+format depends on the object-code output format in use.
+
+@ifset aout-bout
+@ifclear GENERIC
+@ifset BOUT
+@c The following avoids a "widow" subsection title. @group would be
+@c better if it were available outside examples.
+@need 1000
+@node a.out Symbols
+@subsection Symbol Attributes: @code{a.out}, @code{b.out}
+
+@cindex @code{b.out} symbol attributes
+@cindex symbol attributes, @code{b.out}
+These symbol attributes appear only when @command{@value{AS}} is configured for
+one of the Berkeley-descended object output formats---@code{a.out} or
+@code{b.out}.
+
+@end ifset
+@ifclear BOUT
+@node a.out Symbols
+@subsection Symbol Attributes: @code{a.out}
+
+@cindex @code{a.out} symbol attributes
+@cindex symbol attributes, @code{a.out}
+
+@end ifclear
+@end ifclear
+@ifset GENERIC
+@node a.out Symbols
+@subsection Symbol Attributes: @code{a.out}
+
+@cindex @code{a.out} symbol attributes
+@cindex symbol attributes, @code{a.out}
+
+@end ifset
+@menu
+* Symbol Desc:: Descriptor
+* Symbol Other:: Other
+@end menu
+
+@node Symbol Desc
+@subsubsection Descriptor
+
+@cindex descriptor, of @code{a.out} symbol
+This is an arbitrary 16-bit value. You may establish a symbol's
+descriptor value by using a @code{.desc} statement
+(@pxref{Desc,,@code{.desc}}). A descriptor value means nothing to
+@command{@value{AS}}.
+
+@node Symbol Other
+@subsubsection Other
+
+@cindex other attribute, of @code{a.out} symbol
+This is an arbitrary 8-bit value. It means nothing to @command{@value{AS}}.
+@end ifset
+
+@ifset COFF
+@node COFF Symbols
+@subsection Symbol Attributes for COFF
+
+@cindex COFF symbol attributes
+@cindex symbol attributes, COFF
+
+The COFF format supports a multitude of auxiliary symbol attributes;
+like the primary symbol attributes, they are set between @code{.def} and
+@code{.endef} directives.
+
+@subsubsection Primary Attributes
+
+@cindex primary attributes, COFF symbols
+The symbol name is set with @code{.def}; the value and type,
+respectively, with @code{.val} and @code{.type}.
+
+@subsubsection Auxiliary Attributes
+
+@cindex auxiliary attributes, COFF symbols
+The @command{@value{AS}} directives @code{.dim}, @code{.line}, @code{.scl},
+@code{.size}, and @code{.tag} can generate auxiliary symbol table
+information for COFF.
+@end ifset
+
+@ifset SOM
+@node SOM Symbols
+@subsection Symbol Attributes for SOM
+
+@cindex SOM symbol attributes
+@cindex symbol attributes, SOM
+
+The SOM format for the HPPA supports a multitude of symbol attributes set with
+the @code{.EXPORT} and @code{.IMPORT} directives.
+
+The attributes are described in @cite{HP9000 Series 800 Assembly
+Language Reference Manual} (HP 92432-90001) under the @code{IMPORT} and
+@code{EXPORT} assembler directive documentation.
+@end ifset
+
+@node Expressions
+@chapter Expressions
+
+@cindex expressions
+@cindex addresses
+@cindex numeric values
+An @dfn{expression} specifies an address or numeric value.
+Whitespace may precede and/or follow an expression.
+
+The result of an expression must be an absolute number, or else an offset into
+a particular section. If an expression is not absolute, and there is not
+enough information when @command{@value{AS}} sees the expression to know its
+section, a second pass over the source program might be necessary to interpret
+the expression---but the second pass is currently not implemented.
+@command{@value{AS}} aborts with an error message in this situation.
+
+@menu
+* Empty Exprs:: Empty Expressions
+* Integer Exprs:: Integer Expressions
+@end menu
+
+@node Empty Exprs
+@section Empty Expressions
+
+@cindex empty expressions
+@cindex expressions, empty
+An empty expression has no value: it is just whitespace or null.
+Wherever an absolute expression is required, you may omit the
+expression, and @command{@value{AS}} assumes a value of (absolute) 0. This
+is compatible with other assemblers.
+
+@node Integer Exprs
+@section Integer Expressions
+
+@cindex integer expressions
+@cindex expressions, integer
+An @dfn{integer expression} is one or more @emph{arguments} delimited
+by @emph{operators}.
+
+@menu
+* Arguments:: Arguments
+* Operators:: Operators
+* Prefix Ops:: Prefix Operators
+* Infix Ops:: Infix Operators
+@end menu
+
+@node Arguments
+@subsection Arguments
+
+@cindex expression arguments
+@cindex arguments in expressions
+@cindex operands in expressions
+@cindex arithmetic operands
+@dfn{Arguments} are symbols, numbers or subexpressions. In other
+contexts arguments are sometimes called ``arithmetic operands''. In
+this manual, to avoid confusing them with the ``instruction operands'' of
+the machine language, we use the term ``argument'' to refer to parts of
+expressions only, reserving the word ``operand'' to refer only to machine
+instruction operands.
+
+Symbols are evaluated to yield @{@var{section} @var{NNN}@} where
+@var{section} is one of text, data, bss, absolute,
+or undefined. @var{NNN} is a signed, 2's complement 32 bit
+integer.
+
+Numbers are usually integers.
+
+A number can be a flonum or bignum. In this case, you are warned
+that only the low order 32 bits are used, and @command{@value{AS}} pretends
+these 32 bits are an integer. You may write integer-manipulating
+instructions that act on exotic constants, compatible with other
+assemblers.
+
+@cindex subexpressions
+Subexpressions are a left parenthesis @samp{(} followed by an integer
+expression, followed by a right parenthesis @samp{)}; or a prefix
+operator followed by an argument.
+
+@node Operators
+@subsection Operators
+
+@cindex operators, in expressions
+@cindex arithmetic functions
+@cindex functions, in expressions
+@dfn{Operators} are arithmetic functions, like @code{+} or @code{%}. Prefix
+operators are followed by an argument. Infix operators appear
+between their arguments. Operators may be preceded and/or followed by
+whitespace.
+
+@node Prefix Ops
+@subsection Prefix Operator
+
+@cindex prefix operators
+@command{@value{AS}} has the following @dfn{prefix operators}. They each take
+one argument, which must be absolute.
+
+@c the tex/end tex stuff surrounding this small table is meant to make
+@c it align, on the printed page, with the similar table in the next
+@c section (which is inside an enumerate).
+@tex
+\global\advance\leftskip by \itemindent
+@end tex
+
+@table @code
+@item -
+@dfn{Negation}. Two's complement negation.
+@item ~
+@dfn{Complementation}. Bitwise not.
+@end table
+
+@tex
+\global\advance\leftskip by -\itemindent
+@end tex
+
+@node Infix Ops
+@subsection Infix Operators
+
+@cindex infix operators
+@cindex operators, permitted arguments
+@dfn{Infix operators} take two arguments, one on either side. Operators
+have precedence, but operations with equal precedence are performed left
+to right. Apart from @code{+} or @option{-}, both arguments must be
+absolute, and the result is absolute.
+
+@enumerate
+@cindex operator precedence
+@cindex precedence of operators
+
+@item
+Highest Precedence
+
+@table @code
+@item *
+@dfn{Multiplication}.
+
+@item /
+@dfn{Division}. Truncation is the same as the C operator @samp{/}
+
+@item %
+@dfn{Remainder}.
+
+@item <
+@itemx <<
+@dfn{Shift Left}. Same as the C operator @samp{<<}.
+
+@item >
+@itemx >>
+@dfn{Shift Right}. Same as the C operator @samp{>>}.
+@end table
+
+@item
+Intermediate precedence
+
+@table @code
+@item |
+
+@dfn{Bitwise Inclusive Or}.
+
+@item &
+@dfn{Bitwise And}.
+
+@item ^
+@dfn{Bitwise Exclusive Or}.
+
+@item !
+@dfn{Bitwise Or Not}.
+@end table
+
+@item
+Low Precedence
+
+@table @code
+@cindex addition, permitted arguments
+@cindex plus, permitted arguments
+@cindex arguments for addition
+@item +
+@dfn{Addition}. If either argument is absolute, the result has the section of
+the other argument. You may not add together arguments from different
+sections.
+
+@cindex subtraction, permitted arguments
+@cindex minus, permitted arguments
+@cindex arguments for subtraction
+@item -
+@dfn{Subtraction}. If the right argument is absolute, the
+result has the section of the left argument.
+If both arguments are in the same section, the result is absolute.
+You may not subtract arguments from different sections.
+@c FIXME is there still something useful to say about undefined - undefined ?
+
+@cindex comparison expressions
+@cindex expressions, comparison
+@item ==
+@dfn{Is Equal To}
+@item <>
+@dfn{Is Not Equal To}
+@item <
+@dfn{Is Less Than}
+@itemx >
+@dfn{Is Greater Than}
+@itemx >=
+@dfn{Is Greater Than Or Equal To}
+@itemx <=
+@dfn{Is Less Than Or Equal To}
+
+The comparison operators can be used as infix operators. A true results has a
+value of -1 whereas a false result has a value of 0. Note, these operators
+perform signed comparisons.
+@end table
+
+@item Lowest Precedence
+
+@table @code
+@item &&
+@dfn{Logical And}.
+
+@item ||
+@dfn{Logical Or}.
+
+These two logical operations can be used to combine the results of sub
+expressions. Note, unlike the comparison operators a true result returns a
+value of 1 but a false results does still return 0. Also note that the logical
+or operator has a slightly lower precedence than logical and.
+
+@end table
+@end enumerate
+
+In short, it's only meaningful to add or subtract the @emph{offsets} in an
+address; you can only have a defined section in one of the two arguments.
+
+@node Pseudo Ops
+@chapter Assembler Directives
+
+@cindex directives, machine independent
+@cindex pseudo-ops, machine independent
+@cindex machine independent directives
+All assembler directives have names that begin with a period (@samp{.}).
+The rest of the name is letters, usually in lower case.
+
+This chapter discusses directives that are available regardless of the
+target machine configuration for the @sc{gnu} assembler.
+@ifset GENERIC
+Some machine configurations provide additional directives.
+@xref{Machine Dependencies}.
+@end ifset
+@ifclear GENERIC
+@ifset machine-directives
+@xref{Machine Dependencies} for additional directives.
+@end ifset
+@end ifclear
+
+@menu
+* Abort:: @code{.abort}
+@ifset COFF
+* ABORT:: @code{.ABORT}
+@end ifset
+
+* Align:: @code{.align @var{abs-expr} , @var{abs-expr}}
+* Ascii:: @code{.ascii "@var{string}"}@dots{}
+* Asciz:: @code{.asciz "@var{string}"}@dots{}
+* Balign:: @code{.balign @var{abs-expr} , @var{abs-expr}}
+* Byte:: @code{.byte @var{expressions}}
+* Comm:: @code{.comm @var{symbol} , @var{length} }
+
+* CFI directives:: @code{.cfi_startproc}, @code{.cfi_endproc}, etc.
+
+* Data:: @code{.data @var{subsection}}
+@ifset COFF
+* Def:: @code{.def @var{name}}
+@end ifset
+@ifset aout-bout
+* Desc:: @code{.desc @var{symbol}, @var{abs-expression}}
+@end ifset
+@ifset COFF
+* Dim:: @code{.dim}
+@end ifset
+
+* Double:: @code{.double @var{flonums}}
+* Eject:: @code{.eject}
+* Else:: @code{.else}
+* Elseif:: @code{.elseif}
+* End:: @code{.end}
+@ifset COFF
+* Endef:: @code{.endef}
+@end ifset
+
+* Endfunc:: @code{.endfunc}
+* Endif:: @code{.endif}
+* Equ:: @code{.equ @var{symbol}, @var{expression}}
+* Equiv:: @code{.equiv @var{symbol}, @var{expression}}
+* Err:: @code{.err}
+* Exitm:: @code{.exitm}
+* Extern:: @code{.extern}
+* Fail:: @code{.fail}
+@ifclear no-file-dir
+* File:: @code{.file @var{string}}
+@end ifclear
+
+* Fill:: @code{.fill @var{repeat} , @var{size} , @var{value}}
+* Float:: @code{.float @var{flonums}}
+* Func:: @code{.func}
+* Global:: @code{.global @var{symbol}}, @code{.globl @var{symbol}}
+@ifset ELF
+* Hidden:: @code{.hidden @var{names}}
+@end ifset
+
+* hword:: @code{.hword @var{expressions}}
+* Ident:: @code{.ident}
+* If:: @code{.if @var{absolute expression}}
+* Incbin:: @code{.incbin "@var{file}"[,@var{skip}[,@var{count}]]}
+* Include:: @code{.include "@var{file}"}
+* Int:: @code{.int @var{expressions}}
+@ifset ELF
+* Internal:: @code{.internal @var{names}}
+@end ifset
+
+* Irp:: @code{.irp @var{symbol},@var{values}}@dots{}
+* Irpc:: @code{.irpc @var{symbol},@var{values}}@dots{}
+* Lcomm:: @code{.lcomm @var{symbol} , @var{length}}
+* Lflags:: @code{.lflags}
+@ifclear no-line-dir
+* Line:: @code{.line @var{line-number}}
+@end ifclear
+
+* Ln:: @code{.ln @var{line-number}}
+* Linkonce:: @code{.linkonce [@var{type}]}
+* List:: @code{.list}
+* Long:: @code{.long @var{expressions}}
+@ignore
+* Lsym:: @code{.lsym @var{symbol}, @var{expression}}
+@end ignore
+
+* Macro:: @code{.macro @var{name} @var{args}}@dots{}
+* MRI:: @code{.mri @var{val}}
+* Nolist:: @code{.nolist}
+* Octa:: @code{.octa @var{bignums}}
+* Org:: @code{.org @var{new-lc} , @var{fill}}
+* P2align:: @code{.p2align @var{abs-expr} , @var{abs-expr}}
+@ifset ELF
+* PopSection:: @code{.popsection}
+* Previous:: @code{.previous}
+@end ifset
+
+* Print:: @code{.print @var{string}}
+@ifset ELF
+* Protected:: @code{.protected @var{names}}
+@end ifset
+
+* Psize:: @code{.psize @var{lines}, @var{columns}}
+* Purgem:: @code{.purgem @var{name}}
+@ifset ELF
+* PushSection:: @code{.pushsection @var{name}}
+@end ifset
+
+* Quad:: @code{.quad @var{bignums}}
+* Rept:: @code{.rept @var{count}}
+* Sbttl:: @code{.sbttl "@var{subheading}"}
+@ifset COFF
+* Scl:: @code{.scl @var{class}}
+@end ifset
+@ifset COFF-ELF
+* Section:: @code{.section @var{name}}
+@end ifset
+
+* Set:: @code{.set @var{symbol}, @var{expression}}
+* Short:: @code{.short @var{expressions}}
+* Single:: @code{.single @var{flonums}}
+@ifset COFF-ELF
+* Size:: @code{.size [@var{name} , @var{expression}]}
+@end ifset
+
+* Skip:: @code{.skip @var{size} , @var{fill}}
+* Sleb128:: @code{.sleb128 @var{expressions}}
+* Space:: @code{.space @var{size} , @var{fill}}
+@ifset have-stabs
+* Stab:: @code{.stabd, .stabn, .stabs}
+@end ifset
+
+* String:: @code{.string "@var{str}"}
+* Struct:: @code{.struct @var{expression}}
+@ifset ELF
+* SubSection:: @code{.subsection}
+* Symver:: @code{.symver @var{name},@var{name2@@nodename}}
+@end ifset
+
+@ifset COFF
+* Tag:: @code{.tag @var{structname}}
+@end ifset
+
+* Text:: @code{.text @var{subsection}}
+* Title:: @code{.title "@var{heading}"}
+@ifset COFF-ELF
+* Type:: @code{.type <@var{int} | @var{name} , @var{type description}>}
+@end ifset
+
+* Uleb128:: @code{.uleb128 @var{expressions}}
+@ifset COFF
+* Val:: @code{.val @var{addr}}
+@end ifset
+
+@ifset ELF
+* Version:: @code{.version "@var{string}"}
+* VTableEntry:: @code{.vtable_entry @var{table}, @var{offset}}
+* VTableInherit:: @code{.vtable_inherit @var{child}, @var{parent}}
+* Weak:: @code{.weak @var{names}}
+@end ifset
+
+* Word:: @code{.word @var{expressions}}
+* Deprecated:: Deprecated Directives
+@end menu
+
+@node Abort
+@section @code{.abort}
+
+@cindex @code{abort} directive
+@cindex stopping the assembly
+This directive stops the assembly immediately. It is for
+compatibility with other assemblers. The original idea was that the
+assembly language source would be piped into the assembler. If the sender
+of the source quit, it could use this directive tells @command{@value{AS}} to
+quit also. One day @code{.abort} will not be supported.
+
+@ifset COFF
+@node ABORT
+@section @code{.ABORT}
+
+@cindex @code{ABORT} directive
+When producing COFF output, @command{@value{AS}} accepts this directive as a
+synonym for @samp{.abort}.
+
+@ifset BOUT
+When producing @code{b.out} output, @command{@value{AS}} accepts this directive,
+but ignores it.
+@end ifset
+@end ifset
+
+@node Align
+@section @code{.align @var{abs-expr}, @var{abs-expr}, @var{abs-expr}}
+
+@cindex padding the location counter
+@cindex @code{align} directive
+Pad the location counter (in the current subsection) to a particular storage
+boundary. The first expression (which must be absolute) is the alignment
+required, as described below.
+
+The second expression (also absolute) gives the fill value to be stored in the
+padding bytes. It (and the comma) may be omitted. If it is omitted, the
+padding bytes are normally zero. However, on some systems, if the section is
+marked as containing code and the fill value is omitted, the space is filled
+with no-op instructions.
+
+The third expression is also absolute, and is also optional. If it is present,
+it is the maximum number of bytes that should be skipped by this alignment
+directive. If doing the alignment would require skipping more bytes than the
+specified maximum, then the alignment is not done at all. You can omit the
+fill value (the second argument) entirely by simply using two commas after the
+required alignment; this can be useful if you want the alignment to be filled
+with no-op instructions when appropriate.
+
+The way the required alignment is specified varies from system to system.
+For the a29k, arc, hppa, i386 using ELF, i860, iq2000, m68k, m88k, or32,
+s390, sparc, tic4x, tic80 and xtensa, the first expression is the
+alignment request in bytes. For example @samp{.align 8} advances
+the location counter until it is a multiple of 8. If the location counter
+is already a multiple of 8, no change is needed. For the tic54x, the
+first expression is the alignment request in words.
+
+For other systems, including the i386 using a.out format, and the arm and
+strongarm, it is the
+number of low-order zero bits the location counter must have after
+advancement. For example @samp{.align 3} advances the location
+counter until it a multiple of 8. If the location counter is already a
+multiple of 8, no change is needed.
+
+This inconsistency is due to the different behaviors of the various
+native assemblers for these systems which GAS must emulate.
+GAS also provides @code{.balign} and @code{.p2align} directives,
+described later, which have a consistent behavior across all
+architectures (but are specific to GAS).
+
+@node Ascii
+@section @code{.ascii "@var{string}"}@dots{}
+
+@cindex @code{ascii} directive
+@cindex string literals
+@code{.ascii} expects zero or more string literals (@pxref{Strings})
+separated by commas. It assembles each string (with no automatic
+trailing zero byte) into consecutive addresses.
+
+@node Asciz
+@section @code{.asciz "@var{string}"}@dots{}
+
+@cindex @code{asciz} directive
+@cindex zero-terminated strings
+@cindex null-terminated strings
+@code{.asciz} is just like @code{.ascii}, but each string is followed by
+a zero byte. The ``z'' in @samp{.asciz} stands for ``zero''.
+
+@node Balign
+@section @code{.balign[wl] @var{abs-expr}, @var{abs-expr}, @var{abs-expr}}
+
+@cindex padding the location counter given number of bytes
+@cindex @code{balign} directive
+Pad the location counter (in the current subsection) to a particular
+storage boundary. The first expression (which must be absolute) is the
+alignment request in bytes. For example @samp{.balign 8} advances
+the location counter until it is a multiple of 8. If the location counter
+is already a multiple of 8, no change is needed.
+
+The second expression (also absolute) gives the fill value to be stored in the
+padding bytes. It (and the comma) may be omitted. If it is omitted, the
+padding bytes are normally zero. However, on some systems, if the section is
+marked as containing code and the fill value is omitted, the space is filled
+with no-op instructions.
+
+The third expression is also absolute, and is also optional. If it is present,
+it is the maximum number of bytes that should be skipped by this alignment
+directive. If doing the alignment would require skipping more bytes than the
+specified maximum, then the alignment is not done at all. You can omit the
+fill value (the second argument) entirely by simply using two commas after the
+required alignment; this can be useful if you want the alignment to be filled
+with no-op instructions when appropriate.
+
+@cindex @code{balignw} directive
+@cindex @code{balignl} directive
+The @code{.balignw} and @code{.balignl} directives are variants of the
+@code{.balign} directive. The @code{.balignw} directive treats the fill
+pattern as a two byte word value. The @code{.balignl} directives treats the
+fill pattern as a four byte longword value. For example, @code{.balignw
+4,0x368d} will align to a multiple of 4. If it skips two bytes, they will be
+filled in with the value 0x368d (the exact placement of the bytes depends upon
+the endianness of the processor). If it skips 1 or 3 bytes, the fill value is
+undefined.
+
+@node Byte
+@section @code{.byte @var{expressions}}
+
+@cindex @code{byte} directive
+@cindex integers, one byte
+@code{.byte} expects zero or more expressions, separated by commas.
+Each expression is assembled into the next byte.
+
+@node Comm
+@section @code{.comm @var{symbol} , @var{length} }
+
+@cindex @code{comm} directive
+@cindex symbol, common
+@code{.comm} declares a common symbol named @var{symbol}. When linking, a
+common symbol in one object file may be merged with a defined or common symbol
+of the same name in another object file. If @code{@value{LD}} does not see a
+definition for the symbol--just one or more common symbols--then it will
+allocate @var{length} bytes of uninitialized memory. @var{length} must be an
+absolute expression. If @code{@value{LD}} sees multiple common symbols with
+the same name, and they do not all have the same size, it will allocate space
+using the largest size.
+
+@ifset ELF
+When using ELF, the @code{.comm} directive takes an optional third argument.
+This is the desired alignment of the symbol, specified as a byte boundary (for
+example, an alignment of 16 means that the least significant 4 bits of the
+address should be zero). The alignment must be an absolute expression, and it
+must be a power of two. If @code{@value{LD}} allocates uninitialized memory
+for the common symbol, it will use the alignment when placing the symbol. If
+no alignment is specified, @command{@value{AS}} will set the alignment to the
+largest power of two less than or equal to the size of the symbol, up to a
+maximum of 16.
+@end ifset
+
+@ifset HPPA
+The syntax for @code{.comm} differs slightly on the HPPA. The syntax is
+@samp{@var{symbol} .comm, @var{length}}; @var{symbol} is optional.
+@end ifset
+
+@node CFI directives
+@section @code{.cfi_startproc}
+@cindex @code{cfi_startproc} directive
+@code{.cfi_startproc} is used at the beginning of each function that
+should have an entry in @code{.eh_frame}. It initializes some internal
+data structures and emits architecture dependent initial CFI instructions.
+Don't forget to close the function by
+@code{.cfi_endproc}.
+
+@section @code{.cfi_endproc}
+@cindex @code{cfi_endproc} directive
+@code{.cfi_endproc} is used at the end of a function where it closes its
+unwind entry previously opened by
+@code{.cfi_startproc}. and emits it to @code{.eh_frame}.
+
+@section @code{.cfi_def_cfa @var{register}, @var{offset}}
+@code{.cfi_def_cfa} defines a rule for computing CFA as: @i{take
+address from @var{register} and add @var{offset} to it}.
+
+@section @code{.cfi_def_cfa_register @var{register}}
+@code{.cfi_def_cfa_register} modifies a rule for computing CFA. From
+now on @var{register} will be used instead of the old one. Offset
+remains the same.
+
+@section @code{.cfi_def_cfa_offset @var{offset}}
+@code{.cfi_def_cfa_offset} modifies a rule for computing CFA. Register
+remains the same, but @var{offset} is new. Note that it is the
+absolute offset that will be added to a defined register to compute
+CFA address.
+
+@section @code{.cfi_adjust_cfa_offset @var{offset}}
+Same as @code{.cfi_def_cfa_offset} but @var{offset} is a relative
+value that is added/substracted from the previous offset.
+
+@section @code{.cfi_offset @var{register}, @var{offset}}
+Previous value of @var{register} is saved at offset @var{offset} from
+CFA.
+
+@section @code{.cfi_rel_offset @var{register}, @var{offset}}
+Previous value of @var{register} is saved at offset @var{offset} from
+the current CFA register. This is transformed to @code{.cfi_offset}
+using the known displacement of the CFA register from the CFA.
+This is often easier to use, because the number will match the
+code it's annotating.
+
+@section @code{.cfi_window_save}
+SPARC register window has been saved.
+
+@section @code{.cfi_escape} @var{expression}[, @dots{}]
+Allows the user to add arbitrary bytes to the unwind info. One
+might use this to add OS-specific CFI opcodes, or generic CFI
+opcodes that GAS does not yet support.
+
+@node Data
+@section @code{.data @var{subsection}}
+
+@cindex @code{data} directive
+@code{.data} tells @command{@value{AS}} to assemble the following statements onto the
+end of the data subsection numbered @var{subsection} (which is an
+absolute expression). If @var{subsection} is omitted, it defaults
+to zero.
+
+@ifset COFF
+@node Def
+@section @code{.def @var{name}}
+
+@cindex @code{def} directive
+@cindex COFF symbols, debugging
+@cindex debugging COFF symbols
+Begin defining debugging information for a symbol @var{name}; the
+definition extends until the @code{.endef} directive is encountered.
+@ifset BOUT
+
+This directive is only observed when @command{@value{AS}} is configured for COFF
+format output; when producing @code{b.out}, @samp{.def} is recognized,
+but ignored.
+@end ifset
+@end ifset
+
+@ifset aout-bout
+@node Desc
+@section @code{.desc @var{symbol}, @var{abs-expression}}
+
+@cindex @code{desc} directive
+@cindex COFF symbol descriptor
+@cindex symbol descriptor, COFF
+This directive sets the descriptor of the symbol (@pxref{Symbol Attributes})
+to the low 16 bits of an absolute expression.
+
+@ifset COFF
+The @samp{.desc} directive is not available when @command{@value{AS}} is
+configured for COFF output; it is only for @code{a.out} or @code{b.out}
+object format. For the sake of compatibility, @command{@value{AS}} accepts
+it, but produces no output, when configured for COFF.
+@end ifset
+@end ifset
+
+@ifset COFF
+@node Dim
+@section @code{.dim}
+
+@cindex @code{dim} directive
+@cindex COFF auxiliary symbol information
+@cindex auxiliary symbol information, COFF
+This directive is generated by compilers to include auxiliary debugging
+information in the symbol table. It is only permitted inside
+@code{.def}/@code{.endef} pairs.
+@ifset BOUT
+
+@samp{.dim} is only meaningful when generating COFF format output; when
+@command{@value{AS}} is generating @code{b.out}, it accepts this directive but
+ignores it.
+@end ifset
+@end ifset
+
+@node Double
+@section @code{.double @var{flonums}}
+
+@cindex @code{double} directive
+@cindex floating point numbers (double)
+@code{.double} expects zero or more flonums, separated by commas. It
+assembles floating point numbers.
+@ifset GENERIC
+The exact kind of floating point numbers emitted depends on how
+@command{@value{AS}} is configured. @xref{Machine Dependencies}.
+@end ifset
+@ifclear GENERIC
+@ifset IEEEFLOAT
+On the @value{TARGET} family @samp{.double} emits 64-bit floating-point numbers
+in @sc{ieee} format.
+@end ifset
+@end ifclear
+
+@node Eject
+@section @code{.eject}
+
+@cindex @code{eject} directive
+@cindex new page, in listings
+@cindex page, in listings
+@cindex listing control: new page
+Force a page break at this point, when generating assembly listings.
+
+@node Else
+@section @code{.else}
+
+@cindex @code{else} directive
+@code{.else} is part of the @command{@value{AS}} support for conditional
+assembly; @pxref{If,,@code{.if}}. It marks the beginning of a section
+of code to be assembled if the condition for the preceding @code{.if}
+was false.
+
+@node Elseif
+@section @code{.elseif}
+
+@cindex @code{elseif} directive
+@code{.elseif} is part of the @command{@value{AS}} support for conditional
+assembly; @pxref{If,,@code{.if}}. It is shorthand for beginning a new
+@code{.if} block that would otherwise fill the entire @code{.else} section.
+
+@node End
+@section @code{.end}
+
+@cindex @code{end} directive
+@code{.end} marks the end of the assembly file. @command{@value{AS}} does not
+process anything in the file past the @code{.end} directive.
+
+@ifset COFF
+@node Endef
+@section @code{.endef}
+
+@cindex @code{endef} directive
+This directive flags the end of a symbol definition begun with
+@code{.def}.
+@ifset BOUT
+
+@samp{.endef} is only meaningful when generating COFF format output; if
+@command{@value{AS}} is configured to generate @code{b.out}, it accepts this
+directive but ignores it.
+@end ifset
+@end ifset
+
+@node Endfunc
+@section @code{.endfunc}
+@cindex @code{endfunc} directive
+@code{.endfunc} marks the end of a function specified with @code{.func}.
+
+@node Endif
+@section @code{.endif}
+
+@cindex @code{endif} directive
+@code{.endif} is part of the @command{@value{AS}} support for conditional assembly;
+it marks the end of a block of code that is only assembled
+conditionally. @xref{If,,@code{.if}}.
+
+@node Equ
+@section @code{.equ @var{symbol}, @var{expression}}
+
+@cindex @code{equ} directive
+@cindex assigning values to symbols
+@cindex symbols, assigning values to
+This directive sets the value of @var{symbol} to @var{expression}.
+It is synonymous with @samp{.set}; @pxref{Set,,@code{.set}}.
+
+@ifset HPPA
+The syntax for @code{equ} on the HPPA is
+@samp{@var{symbol} .equ @var{expression}}.
+@end ifset
+
+@node Equiv
+@section @code{.equiv @var{symbol}, @var{expression}}
+@cindex @code{equiv} directive
+The @code{.equiv} directive is like @code{.equ} and @code{.set}, except that
+the assembler will signal an error if @var{symbol} is already defined. Note a
+symbol which has been referenced but not actually defined is considered to be
+undefined.
+
+Except for the contents of the error message, this is roughly equivalent to
+@smallexample
+.ifdef SYM
+.err
+.endif
+.equ SYM,VAL
+@end smallexample
+
+@node Err
+@section @code{.err}
+@cindex @code{err} directive
+If @command{@value{AS}} assembles a @code{.err} directive, it will print an error
+message and, unless the @option{-Z} option was used, it will not generate an
+object file. This can be used to signal error an conditionally compiled code.
+
+@node Exitm
+@section @code{.exitm}
+Exit early from the current macro definition. @xref{Macro}.
+
+@node Extern
+@section @code{.extern}
+
+@cindex @code{extern} directive
+@code{.extern} is accepted in the source program---for compatibility
+with other assemblers---but it is ignored. @command{@value{AS}} treats
+all undefined symbols as external.
+
+@node Fail
+@section @code{.fail @var{expression}}
+
+@cindex @code{fail} directive
+Generates an error or a warning. If the value of the @var{expression} is 500
+or more, @command{@value{AS}} will print a warning message. If the value is less
+than 500, @command{@value{AS}} will print an error message. The message will
+include the value of @var{expression}. This can occasionally be useful inside
+complex nested macros or conditional assembly.
+
+@ifclear no-file-dir
+@node File
+@section @code{.file @var{string}}
+
+@cindex @code{file} directive
+@cindex logical file name
+@cindex file name, logical
+@code{.file} tells @command{@value{AS}} that we are about to start a new logical
+file. @var{string} is the new file name. In general, the filename is
+recognized whether or not it is surrounded by quotes @samp{"}; but if you wish
+to specify an empty file name, you must give the quotes--@code{""}. This
+statement may go away in future: it is only recognized to be compatible with
+old @command{@value{AS}} programs.
+@ifset A29K
+In some configurations of @command{@value{AS}}, @code{.file} has already been
+removed to avoid conflicts with other assemblers. @xref{Machine Dependencies}.
+@end ifset
+@end ifclear
+
+@node Fill
+@section @code{.fill @var{repeat} , @var{size} , @var{value}}
+
+@cindex @code{fill} directive
+@cindex writing patterns in memory
+@cindex patterns, writing in memory
+@var{repeat}, @var{size} and @var{value} are absolute expressions.
+This emits @var{repeat} copies of @var{size} bytes. @var{Repeat}
+may be zero or more. @var{Size} may be zero or more, but if it is
+more than 8, then it is deemed to have the value 8, compatible with
+other people's assemblers. The contents of each @var{repeat} bytes
+is taken from an 8-byte number. The highest order 4 bytes are
+zero. The lowest order 4 bytes are @var{value} rendered in the
+byte-order of an integer on the computer @command{@value{AS}} is assembling for.
+Each @var{size} bytes in a repetition is taken from the lowest order
+@var{size} bytes of this number. Again, this bizarre behavior is
+compatible with other people's assemblers.
+
+@var{size} and @var{value} are optional.
+If the second comma and @var{value} are absent, @var{value} is
+assumed zero. If the first comma and following tokens are absent,
+@var{size} is assumed to be 1.
+
+@node Float
+@section @code{.float @var{flonums}}
+
+@cindex floating point numbers (single)
+@cindex @code{float} directive
+This directive assembles zero or more flonums, separated by commas. It
+has the same effect as @code{.single}.
+@ifset GENERIC
+The exact kind of floating point numbers emitted depends on how
+@command{@value{AS}} is configured.
+@xref{Machine Dependencies}.
+@end ifset
+@ifclear GENERIC
+@ifset IEEEFLOAT
+On the @value{TARGET} family, @code{.float} emits 32-bit floating point numbers
+in @sc{ieee} format.
+@end ifset
+@end ifclear
+
+@node Func
+@section @code{.func @var{name}[,@var{label}]}
+@cindex @code{func} directive
+@code{.func} emits debugging information to denote function @var{name}, and
+is ignored unless the file is assembled with debugging enabled.
+Only @samp{--gstabs[+]} is currently supported.
+@var{label} is the entry point of the function and if omitted @var{name}
+prepended with the @samp{leading char} is used.
+@samp{leading char} is usually @code{_} or nothing, depending on the target.
+All functions are currently defined to have @code{void} return type.
+The function must be terminated with @code{.endfunc}.
+
+@node Global
+@section @code{.global @var{symbol}}, @code{.globl @var{symbol}}
+
+@cindex @code{global} directive
+@cindex symbol, making visible to linker
+@code{.global} makes the symbol visible to @code{@value{LD}}. If you define
+@var{symbol} in your partial program, its value is made available to
+other partial programs that are linked with it. Otherwise,
+@var{symbol} takes its attributes from a symbol of the same name
+from another file linked into the same program.
+
+Both spellings (@samp{.globl} and @samp{.global}) are accepted, for
+compatibility with other assemblers.
+
+@ifset HPPA
+On the HPPA, @code{.global} is not always enough to make it accessible to other
+partial programs. You may need the HPPA-only @code{.EXPORT} directive as well.
+@xref{HPPA Directives,, HPPA Assembler Directives}.
+@end ifset
+
+@ifset ELF
+@node Hidden
+@section @code{.hidden @var{names}}
+
+@cindex @code{hidden} directive
+@cindex visibility
+This one of the ELF visibility directives. The other two are
+@code{.internal} (@pxref{Internal,,@code{.internal}}) and
+@code{.protected} (@pxref{Protected,,@code{.protected}}).
+
+This directive overrides the named symbols default visibility (which is set by
+their binding: local, global or weak). The directive sets the visibility to
+@code{hidden} which means that the symbols are not visible to other components.
+Such symbols are always considered to be @code{protected} as well.
+@end ifset
+
+@node hword
+@section @code{.hword @var{expressions}}
+
+@cindex @code{hword} directive
+@cindex integers, 16-bit
+@cindex numbers, 16-bit
+@cindex sixteen bit integers
+This expects zero or more @var{expressions}, and emits
+a 16 bit number for each.
+
+@ifset GENERIC
+This directive is a synonym for @samp{.short}; depending on the target
+architecture, it may also be a synonym for @samp{.word}.
+@end ifset
+@ifclear GENERIC
+@ifset W32
+This directive is a synonym for @samp{.short}.
+@end ifset
+@ifset W16
+This directive is a synonym for both @samp{.short} and @samp{.word}.
+@end ifset
+@end ifclear
+
+@node Ident
+@section @code{.ident}
+
+@cindex @code{ident} directive
+This directive is used by some assemblers to place tags in object files.
+@command{@value{AS}} simply accepts the directive for source-file
+compatibility with such assemblers, but does not actually emit anything
+for it.
+
+@node If
+@section @code{.if @var{absolute expression}}
+
+@cindex conditional assembly
+@cindex @code{if} directive
+@code{.if} marks the beginning of a section of code which is only
+considered part of the source program being assembled if the argument
+(which must be an @var{absolute expression}) is non-zero. The end of
+the conditional section of code must be marked by @code{.endif}
+(@pxref{Endif,,@code{.endif}}); optionally, you may include code for the
+alternative condition, flagged by @code{.else} (@pxref{Else,,@code{.else}}).
+If you have several conditions to check, @code{.elseif} may be used to avoid
+nesting blocks if/else within each subsequent @code{.else} block.
+
+The following variants of @code{.if} are also supported:
+@table @code
+@cindex @code{ifdef} directive
+@item .ifdef @var{symbol}
+Assembles the following section of code if the specified @var{symbol}
+has been defined. Note a symbol which has been referenced but not yet defined
+is considered to be undefined.
+
+@cindex @code{ifc} directive
+@item .ifc @var{string1},@var{string2}
+Assembles the following section of code if the two strings are the same. The
+strings may be optionally quoted with single quotes. If they are not quoted,
+the first string stops at the first comma, and the second string stops at the
+end of the line. Strings which contain whitespace should be quoted. The
+string comparison is case sensitive.
+
+@cindex @code{ifeq} directive
+@item .ifeq @var{absolute expression}
+Assembles the following section of code if the argument is zero.
+
+@cindex @code{ifeqs} directive
+@item .ifeqs @var{string1},@var{string2}
+Another form of @code{.ifc}. The strings must be quoted using double quotes.
+
+@cindex @code{ifge} directive
+@item .ifge @var{absolute expression}
+Assembles the following section of code if the argument is greater than or
+equal to zero.
+
+@cindex @code{ifgt} directive
+@item .ifgt @var{absolute expression}
+Assembles the following section of code if the argument is greater than zero.
+
+@cindex @code{ifle} directive
+@item .ifle @var{absolute expression}
+Assembles the following section of code if the argument is less than or equal
+to zero.
+
+@cindex @code{iflt} directive
+@item .iflt @var{absolute expression}
+Assembles the following section of code if the argument is less than zero.
+
+@cindex @code{ifnc} directive
+@item .ifnc @var{string1},@var{string2}.
+Like @code{.ifc}, but the sense of the test is reversed: this assembles the
+following section of code if the two strings are not the same.
+
+@cindex @code{ifndef} directive
+@cindex @code{ifnotdef} directive
+@item .ifndef @var{symbol}
+@itemx .ifnotdef @var{symbol}
+Assembles the following section of code if the specified @var{symbol}
+has not been defined. Both spelling variants are equivalent. Note a symbol
+which has been referenced but not yet defined is considered to be undefined.
+
+@cindex @code{ifne} directive
+@item .ifne @var{absolute expression}
+Assembles the following section of code if the argument is not equal to zero
+(in other words, this is equivalent to @code{.if}).
+
+@cindex @code{ifnes} directive
+@item .ifnes @var{string1},@var{string2}
+Like @code{.ifeqs}, but the sense of the test is reversed: this assembles the
+following section of code if the two strings are not the same.
+@end table
+
+@node Incbin
+@section @code{.incbin "@var{file}"[,@var{skip}[,@var{count}]]}
+
+@cindex @code{incbin} directive
+@cindex binary files, including
+The @code{incbin} directive includes @var{file} verbatim at the current
+location. You can control the search paths used with the @samp{-I} command-line
+option (@pxref{Invoking,,Command-Line Options}). Quotation marks are required
+around @var{file}.
+
+The @var{skip} argument skips a number of bytes from the start of the
+@var{file}. The @var{count} argument indicates the maximum number of bytes to
+read. Note that the data is not aligned in any way, so it is the user's
+responsibility to make sure that proper alignment is provided both before and
+after the @code{incbin} directive.
+
+@node Include
+@section @code{.include "@var{file}"}
+
+@cindex @code{include} directive
+@cindex supporting files, including
+@cindex files, including
+This directive provides a way to include supporting files at specified
+points in your source program. The code from @var{file} is assembled as
+if it followed the point of the @code{.include}; when the end of the
+included file is reached, assembly of the original file continues. You
+can control the search paths used with the @samp{-I} command-line option
+(@pxref{Invoking,,Command-Line Options}). Quotation marks are required
+around @var{file}.
+
+@node Int
+@section @code{.int @var{expressions}}
+
+@cindex @code{int} directive
+@cindex integers, 32-bit
+Expect zero or more @var{expressions}, of any section, separated by commas.
+For each expression, emit a number that, at run time, is the value of that
+expression. The byte order and bit size of the number depends on what kind
+of target the assembly is for.
+
+@ifclear GENERIC
+@ifset H8
+On the H8/500 and most forms of the H8/300, @code{.int} emits 16-bit
+integers. On the H8/300H and the Renesas SH, however, @code{.int} emits
+32-bit integers.
+@end ifset
+@end ifclear
+
+@ifset ELF
+@node Internal
+@section @code{.internal @var{names}}
+
+@cindex @code{internal} directive
+@cindex visibility
+This one of the ELF visibility directives. The other two are
+@code{.hidden} (@pxref{Hidden,,@code{.hidden}}) and
+@code{.protected} (@pxref{Protected,,@code{.protected}}).
+
+This directive overrides the named symbols default visibility (which is set by
+their binding: local, global or weak). The directive sets the visibility to
+@code{internal} which means that the symbols are considered to be @code{hidden}
+(i.e., not visible to other components), and that some extra, processor specific
+processing must also be performed upon the symbols as well.
+@end ifset
+
+@node Irp
+@section @code{.irp @var{symbol},@var{values}}@dots{}
+
+@cindex @code{irp} directive
+Evaluate a sequence of statements assigning different values to @var{symbol}.
+The sequence of statements starts at the @code{.irp} directive, and is
+terminated by an @code{.endr} directive. For each @var{value}, @var{symbol} is
+set to @var{value}, and the sequence of statements is assembled. If no
+@var{value} is listed, the sequence of statements is assembled once, with
+@var{symbol} set to the null string. To refer to @var{symbol} within the
+sequence of statements, use @var{\symbol}.
+
+For example, assembling
+
+@example
+ .irp param,1,2,3
+ move d\param,sp@@-
+ .endr
+@end example
+
+is equivalent to assembling
+
+@example
+ move d1,sp@@-
+ move d2,sp@@-
+ move d3,sp@@-
+@end example
+
+@node Irpc
+@section @code{.irpc @var{symbol},@var{values}}@dots{}
+
+@cindex @code{irpc} directive
+Evaluate a sequence of statements assigning different values to @var{symbol}.
+The sequence of statements starts at the @code{.irpc} directive, and is
+terminated by an @code{.endr} directive. For each character in @var{value},
+@var{symbol} is set to the character, and the sequence of statements is
+assembled. If no @var{value} is listed, the sequence of statements is
+assembled once, with @var{symbol} set to the null string. To refer to
+@var{symbol} within the sequence of statements, use @var{\symbol}.
+
+For example, assembling
+
+@example
+ .irpc param,123
+ move d\param,sp@@-
+ .endr
+@end example
+
+is equivalent to assembling
+
+@example
+ move d1,sp@@-
+ move d2,sp@@-
+ move d3,sp@@-
+@end example
+
+@node Lcomm
+@section @code{.lcomm @var{symbol} , @var{length}}
+
+@cindex @code{lcomm} directive
+@cindex local common symbols
+@cindex symbols, local common
+Reserve @var{length} (an absolute expression) bytes for a local common
+denoted by @var{symbol}. The section and value of @var{symbol} are
+those of the new local common. The addresses are allocated in the bss
+section, so that at run-time the bytes start off zeroed. @var{Symbol}
+is not declared global (@pxref{Global,,@code{.global}}), so is normally
+not visible to @code{@value{LD}}.
+
+@ifset GENERIC
+Some targets permit a third argument to be used with @code{.lcomm}. This
+argument specifies the desired alignment of the symbol in the bss section.
+@end ifset
+
+@ifset HPPA
+The syntax for @code{.lcomm} differs slightly on the HPPA. The syntax is
+@samp{@var{symbol} .lcomm, @var{length}}; @var{symbol} is optional.
+@end ifset
+
+@node Lflags
+@section @code{.lflags}
+
+@cindex @code{lflags} directive (ignored)
+@command{@value{AS}} accepts this directive, for compatibility with other
+assemblers, but ignores it.
+
+@ifclear no-line-dir
+@node Line
+@section @code{.line @var{line-number}}
+
+@cindex @code{line} directive
+@end ifclear
+@ifset no-line-dir
+@node Ln
+@section @code{.ln @var{line-number}}
+
+@cindex @code{ln} directive
+@end ifset
+@cindex logical line number
+@ifset aout-bout
+Change the logical line number. @var{line-number} must be an absolute
+expression. The next line has that logical line number. Therefore any other
+statements on the current line (after a statement separator character) are
+reported as on logical line number @var{line-number} @minus{} 1. One day
+@command{@value{AS}} will no longer support this directive: it is recognized only
+for compatibility with existing assembler programs.
+
+@ifset GENERIC
+@ifset A29K
+@emph{Warning:} In the AMD29K configuration of @value{AS}, this command is
+not available; use the synonym @code{.ln} in that context.
+@end ifset
+@end ifset
+@end ifset
+
+@ifclear no-line-dir
+Even though this is a directive associated with the @code{a.out} or
+@code{b.out} object-code formats, @command{@value{AS}} still recognizes it
+when producing COFF output, and treats @samp{.line} as though it
+were the COFF @samp{.ln} @emph{if} it is found outside a
+@code{.def}/@code{.endef} pair.
+
+Inside a @code{.def}, @samp{.line} is, instead, one of the directives
+used by compilers to generate auxiliary symbol information for
+debugging.
+@end ifclear
+
+@node Linkonce
+@section @code{.linkonce [@var{type}]}
+@cindex COMDAT
+@cindex @code{linkonce} directive
+@cindex common sections
+Mark the current section so that the linker only includes a single copy of it.
+This may be used to include the same section in several different object files,
+but ensure that the linker will only include it once in the final output file.
+The @code{.linkonce} pseudo-op must be used for each instance of the section.
+Duplicate sections are detected based on the section name, so it should be
+unique.
+
+This directive is only supported by a few object file formats; as of this
+writing, the only object file format which supports it is the Portable
+Executable format used on Windows NT.
+
+The @var{type} argument is optional. If specified, it must be one of the
+following strings. For example:
+@smallexample
+.linkonce same_size
+@end smallexample
+Not all types may be supported on all object file formats.
+
+@table @code
+@item discard
+Silently discard duplicate sections. This is the default.
+
+@item one_only
+Warn if there are duplicate sections, but still keep only one copy.
+
+@item same_size
+Warn if any of the duplicates have different sizes.
+
+@item same_contents
+Warn if any of the duplicates do not have exactly the same contents.
+@end table
+
+@node Ln
+@section @code{.ln @var{line-number}}
+
+@cindex @code{ln} directive
+@ifclear no-line-dir
+@samp{.ln} is a synonym for @samp{.line}.
+@end ifclear
+@ifset no-line-dir
+Tell @command{@value{AS}} to change the logical line number. @var{line-number}
+must be an absolute expression. The next line has that logical
+line number, so any other statements on the current line (after a
+statement separator character @code{;}) are reported as on logical
+line number @var{line-number} @minus{} 1.
+@ifset BOUT
+
+This directive is accepted, but ignored, when @command{@value{AS}} is
+configured for @code{b.out}; its effect is only associated with COFF
+output format.
+@end ifset
+@end ifset
+
+@node MRI
+@section @code{.mri @var{val}}
+
+@cindex @code{mri} directive
+@cindex MRI mode, temporarily
+If @var{val} is non-zero, this tells @command{@value{AS}} to enter MRI mode. If
+@var{val} is zero, this tells @command{@value{AS}} to exit MRI mode. This change
+affects code assembled until the next @code{.mri} directive, or until the end
+of the file. @xref{M, MRI mode, MRI mode}.
+
+@node List
+@section @code{.list}
+
+@cindex @code{list} directive
+@cindex listing control, turning on
+Control (in conjunction with the @code{.nolist} directive) whether or
+not assembly listings are generated. These two directives maintain an
+internal counter (which is zero initially). @code{.list} increments the
+counter, and @code{.nolist} decrements it. Assembly listings are
+generated whenever the counter is greater than zero.
+
+By default, listings are disabled. When you enable them (with the
+@samp{-a} command line option; @pxref{Invoking,,Command-Line Options}),
+the initial value of the listing counter is one.
+
+@node Long
+@section @code{.long @var{expressions}}
+
+@cindex @code{long} directive
+@code{.long} is the same as @samp{.int}, @pxref{Int,,@code{.int}}.
+
+@ignore
+@c no one seems to know what this is for or whether this description is
+@c what it really ought to do
+@node Lsym
+@section @code{.lsym @var{symbol}, @var{expression}}
+
+@cindex @code{lsym} directive
+@cindex symbol, not referenced in assembly
+@code{.lsym} creates a new symbol named @var{symbol}, but does not put it in
+the hash table, ensuring it cannot be referenced by name during the
+rest of the assembly. This sets the attributes of the symbol to be
+the same as the expression value:
+@smallexample
+@var{other} = @var{descriptor} = 0
+@var{type} = @r{(section of @var{expression})}
+@var{value} = @var{expression}
+@end smallexample
+@noindent
+The new symbol is not flagged as external.
+@end ignore
+
+@node Macro
+@section @code{.macro}
+
+@cindex macros
+The commands @code{.macro} and @code{.endm} allow you to define macros that
+generate assembly output. For example, this definition specifies a macro
+@code{sum} that puts a sequence of numbers into memory:
+
+@example
+ .macro sum from=0, to=5
+ .long \from
+ .if \to-\from
+ sum "(\from+1)",\to
+ .endif
+ .endm
+@end example
+
+@noindent
+With that definition, @samp{SUM 0,5} is equivalent to this assembly input:
+
+@example
+ .long 0
+ .long 1
+ .long 2
+ .long 3
+ .long 4
+ .long 5
+@end example
+
+@ftable @code
+@item .macro @var{macname}
+@itemx .macro @var{macname} @var{macargs} @dots{}
+@cindex @code{macro} directive
+Begin the definition of a macro called @var{macname}. If your macro
+definition requires arguments, specify their names after the macro name,
+separated by commas or spaces. You can supply a default value for any
+macro argument by following the name with @samp{=@var{deflt}}. For
+example, these are all valid @code{.macro} statements:
+
+@table @code
+@item .macro comm
+Begin the definition of a macro called @code{comm}, which takes no
+arguments.
+
+@item .macro plus1 p, p1
+@itemx .macro plus1 p p1
+Either statement begins the definition of a macro called @code{plus1},
+which takes two arguments; within the macro definition, write
+@samp{\p} or @samp{\p1} to evaluate the arguments.
+
+@item .macro reserve_str p1=0 p2
+Begin the definition of a macro called @code{reserve_str}, with two
+arguments. The first argument has a default value, but not the second.
+After the definition is complete, you can call the macro either as
+@samp{reserve_str @var{a},@var{b}} (with @samp{\p1} evaluating to
+@var{a} and @samp{\p2} evaluating to @var{b}), or as @samp{reserve_str
+,@var{b}} (with @samp{\p1} evaluating as the default, in this case
+@samp{0}, and @samp{\p2} evaluating to @var{b}).
+@end table
+
+When you call a macro, you can specify the argument values either by
+position, or by keyword. For example, @samp{sum 9,17} is equivalent to
+@samp{sum to=17, from=9}.
+
+@item .endm
+@cindex @code{endm} directive
+Mark the end of a macro definition.
+
+@item .exitm
+@cindex @code{exitm} directive
+Exit early from the current macro definition.
+
+@cindex number of macros executed
+@cindex macros, count executed
+@item \@@
+@command{@value{AS}} maintains a counter of how many macros it has
+executed in this pseudo-variable; you can copy that number to your
+output with @samp{\@@}, but @emph{only within a macro definition}.
+
+@ignore
+@item LOCAL @var{name} [ , @dots{} ]
+@emph{Warning: @code{LOCAL} is only available if you select ``alternate
+macro syntax'' with @samp{-a} or @samp{--alternate}.} @xref{Alternate,,
+Alternate macro syntax}.
+
+Generate a string replacement for each of the @var{name} arguments, and
+replace any instances of @var{name} in each macro expansion. The
+replacement string is unique in the assembly, and different for each
+separate macro expansion. @code{LOCAL} allows you to write macros that
+define symbols, without fear of conflict between separate macro expansions.
+@end ignore
+@end ftable
+
+@node Nolist
+@section @code{.nolist}
+
+@cindex @code{nolist} directive
+@cindex listing control, turning off
+Control (in conjunction with the @code{.list} directive) whether or
+not assembly listings are generated. These two directives maintain an
+internal counter (which is zero initially). @code{.list} increments the
+counter, and @code{.nolist} decrements it. Assembly listings are
+generated whenever the counter is greater than zero.
+
+@node Octa
+@section @code{.octa @var{bignums}}
+
+@c FIXME: double size emitted for "octa" on i960, others? Or warn?
+@cindex @code{octa} directive
+@cindex integer, 16-byte
+@cindex sixteen byte integer
+This directive expects zero or more bignums, separated by commas. For each
+bignum, it emits a 16-byte integer.
+
+The term ``octa'' comes from contexts in which a ``word'' is two bytes;
+hence @emph{octa}-word for 16 bytes.
+
+@node Org
+@section @code{.org @var{new-lc} , @var{fill}}
+
+@cindex @code{org} directive
+@cindex location counter, advancing
+@cindex advancing location counter
+@cindex current address, advancing
+Advance the location counter of the current section to
+@var{new-lc}. @var{new-lc} is either an absolute expression or an
+expression with the same section as the current subsection. That is,
+you can't use @code{.org} to cross sections: if @var{new-lc} has the
+wrong section, the @code{.org} directive is ignored. To be compatible
+with former assemblers, if the section of @var{new-lc} is absolute,
+@command{@value{AS}} issues a warning, then pretends the section of @var{new-lc}
+is the same as the current subsection.
+
+@code{.org} may only increase the location counter, or leave it
+unchanged; you cannot use @code{.org} to move the location counter
+backwards.
+
+@c double negative used below "not undefined" because this is a specific
+@c reference to "undefined" (as SEG_UNKNOWN is called in this manual)
+@c section. doc@cygnus.com 18feb91
+Because @command{@value{AS}} tries to assemble programs in one pass, @var{new-lc}
+may not be undefined. If you really detest this restriction we eagerly await
+a chance to share your improved assembler.
+
+Beware that the origin is relative to the start of the section, not
+to the start of the subsection. This is compatible with other
+people's assemblers.
+
+When the location counter (of the current subsection) is advanced, the
+intervening bytes are filled with @var{fill} which should be an
+absolute expression. If the comma and @var{fill} are omitted,
+@var{fill} defaults to zero.
+
+@node P2align
+@section @code{.p2align[wl] @var{abs-expr}, @var{abs-expr}, @var{abs-expr}}
+
+@cindex padding the location counter given a power of two
+@cindex @code{p2align} directive
+Pad the location counter (in the current subsection) to a particular
+storage boundary. The first expression (which must be absolute) is the
+number of low-order zero bits the location counter must have after
+advancement. For example @samp{.p2align 3} advances the location
+counter until it a multiple of 8. If the location counter is already a
+multiple of 8, no change is needed.
+
+The second expression (also absolute) gives the fill value to be stored in the
+padding bytes. It (and the comma) may be omitted. If it is omitted, the
+padding bytes are normally zero. However, on some systems, if the section is
+marked as containing code and the fill value is omitted, the space is filled
+with no-op instructions.
+
+The third expression is also absolute, and is also optional. If it is present,
+it is the maximum number of bytes that should be skipped by this alignment
+directive. If doing the alignment would require skipping more bytes than the
+specified maximum, then the alignment is not done at all. You can omit the
+fill value (the second argument) entirely by simply using two commas after the
+required alignment; this can be useful if you want the alignment to be filled
+with no-op instructions when appropriate.
+
+@cindex @code{p2alignw} directive
+@cindex @code{p2alignl} directive
+The @code{.p2alignw} and @code{.p2alignl} directives are variants of the
+@code{.p2align} directive. The @code{.p2alignw} directive treats the fill
+pattern as a two byte word value. The @code{.p2alignl} directives treats the
+fill pattern as a four byte longword value. For example, @code{.p2alignw
+2,0x368d} will align to a multiple of 4. If it skips two bytes, they will be
+filled in with the value 0x368d (the exact placement of the bytes depends upon
+the endianness of the processor). If it skips 1 or 3 bytes, the fill value is
+undefined.
+
+@ifset ELF
+@node Previous
+@section @code{.previous}
+
+@cindex @code{previous} directive
+@cindex Section Stack
+This is one of the ELF section stack manipulation directives. The others are
+@code{.section} (@pxref{Section}), @code{.subsection} (@pxref{SubSection}),
+@code{.pushsection} (@pxref{PushSection}), and @code{.popsection}
+(@pxref{PopSection}).
+
+This directive swaps the current section (and subsection) with most recently
+referenced section (and subsection) prior to this one. Multiple
+@code{.previous} directives in a row will flip between two sections (and their
+subsections).
+
+In terms of the section stack, this directive swaps the current section with
+the top section on the section stack.
+@end ifset
+
+@ifset ELF
+@node PopSection
+@section @code{.popsection}
+
+@cindex @code{popsection} directive
+@cindex Section Stack
+This is one of the ELF section stack manipulation directives. The others are
+@code{.section} (@pxref{Section}), @code{.subsection} (@pxref{SubSection}),
+@code{.pushsection} (@pxref{PushSection}), and @code{.previous}
+(@pxref{Previous}).
+
+This directive replaces the current section (and subsection) with the top
+section (and subsection) on the section stack. This section is popped off the
+stack.
+@end ifset
+
+@node Print
+@section @code{.print @var{string}}
+
+@cindex @code{print} directive
+@command{@value{AS}} will print @var{string} on the standard output during
+assembly. You must put @var{string} in double quotes.
+
+@ifset ELF
+@node Protected
+@section @code{.protected @var{names}}
+
+@cindex @code{protected} directive
+@cindex visibility
+This one of the ELF visibility directives. The other two are
+@code{.hidden} (@pxref{Hidden}) and @code{.internal} (@pxref{Internal}).
+
+This directive overrides the named symbols default visibility (which is set by
+their binding: local, global or weak). The directive sets the visibility to
+@code{protected} which means that any references to the symbols from within the
+components that defines them must be resolved to the definition in that
+component, even if a definition in another component would normally preempt
+this.
+@end ifset
+
+@node Psize
+@section @code{.psize @var{lines} , @var{columns}}
+
+@cindex @code{psize} directive
+@cindex listing control: paper size
+@cindex paper size, for listings
+Use this directive to declare the number of lines---and, optionally, the
+number of columns---to use for each page, when generating listings.
+
+If you do not use @code{.psize}, listings use a default line-count
+of 60. You may omit the comma and @var{columns} specification; the
+default width is 200 columns.
+
+@command{@value{AS}} generates formfeeds whenever the specified number of
+lines is exceeded (or whenever you explicitly request one, using
+@code{.eject}).
+
+If you specify @var{lines} as @code{0}, no formfeeds are generated save
+those explicitly specified with @code{.eject}.
+
+@node Purgem
+@section @code{.purgem @var{name}}
+
+@cindex @code{purgem} directive
+Undefine the macro @var{name}, so that later uses of the string will not be
+expanded. @xref{Macro}.
+
+@ifset ELF
+@node PushSection
+@section @code{.pushsection @var{name} , @var{subsection}}
+
+@cindex @code{pushsection} directive
+@cindex Section Stack
+This is one of the ELF section stack manipulation directives. The others are
+@code{.section} (@pxref{Section}), @code{.subsection} (@pxref{SubSection}),
+@code{.popsection} (@pxref{PopSection}), and @code{.previous}
+(@pxref{Previous}).
+
+This directive is a synonym for @code{.section}. It pushes the current section
+(and subsection) onto the top of the section stack, and then replaces the
+current section and subsection with @code{name} and @code{subsection}.
+@end ifset
+
+@node Quad
+@section @code{.quad @var{bignums}}
+
+@cindex @code{quad} directive
+@code{.quad} expects zero or more bignums, separated by commas. For
+each bignum, it emits
+@ifclear bignum-16
+an 8-byte integer. If the bignum won't fit in 8 bytes, it prints a
+warning message; and just takes the lowest order 8 bytes of the bignum.
+@cindex eight-byte integer
+@cindex integer, 8-byte
+
+The term ``quad'' comes from contexts in which a ``word'' is two bytes;
+hence @emph{quad}-word for 8 bytes.
+@end ifclear
+@ifset bignum-16
+a 16-byte integer. If the bignum won't fit in 16 bytes, it prints a
+warning message; and just takes the lowest order 16 bytes of the bignum.
+@cindex sixteen-byte integer
+@cindex integer, 16-byte
+@end ifset
+
+@node Rept
+@section @code{.rept @var{count}}
+
+@cindex @code{rept} directive
+Repeat the sequence of lines between the @code{.rept} directive and the next
+@code{.endr} directive @var{count} times.
+
+For example, assembling
+
+@example
+ .rept 3
+ .long 0
+ .endr
+@end example
+
+is equivalent to assembling
+
+@example
+ .long 0
+ .long 0
+ .long 0
+@end example
+
+@node Sbttl
+@section @code{.sbttl "@var{subheading}"}
+
+@cindex @code{sbttl} directive
+@cindex subtitles for listings
+@cindex listing control: subtitle
+Use @var{subheading} as the title (third line, immediately after the
+title line) when generating assembly listings.
+
+This directive affects subsequent pages, as well as the current page if
+it appears within ten lines of the top of a page.
+
+@ifset COFF
+@node Scl
+@section @code{.scl @var{class}}
+
+@cindex @code{scl} directive
+@cindex symbol storage class (COFF)
+@cindex COFF symbol storage class
+Set the storage-class value for a symbol. This directive may only be
+used inside a @code{.def}/@code{.endef} pair. Storage class may flag
+whether a symbol is static or external, or it may record further
+symbolic debugging information.
+@ifset BOUT
+
+The @samp{.scl} directive is primarily associated with COFF output; when
+configured to generate @code{b.out} output format, @command{@value{AS}}
+accepts this directive but ignores it.
+@end ifset
+@end ifset
+
+@ifset COFF-ELF
+@node Section
+@section @code{.section @var{name}}
+
+@cindex named section
+Use the @code{.section} directive to assemble the following code into a section
+named @var{name}.
+
+This directive is only supported for targets that actually support arbitrarily
+named sections; on @code{a.out} targets, for example, it is not accepted, even
+with a standard @code{a.out} section name.
+
+@ifset COFF
+@ifset ELF
+@c only print the extra heading if both COFF and ELF are set
+@subheading COFF Version
+@end ifset
+
+@cindex @code{section} directive (COFF version)
+For COFF targets, the @code{.section} directive is used in one of the following
+ways:
+
+@smallexample
+.section @var{name}[, "@var{flags}"]
+.section @var{name}[, @var{subsegment}]
+@end smallexample
+
+If the optional argument is quoted, it is taken as flags to use for the
+section. Each flag is a single character. The following flags are recognized:
+@table @code
+@item b
+bss section (uninitialized data)
+@item n
+section is not loaded
+@item w
+writable section
+@item d
+data section
+@item r
+read-only section
+@item x
+executable section
+@item s
+shared section (meaningful for PE targets)
+@item a
+ignored. (For compatibility with the ELF version)
+@end table
+
+If no flags are specified, the default flags depend upon the section name. If
+the section name is not recognized, the default will be for the section to be
+loaded and writable. Note the @code{n} and @code{w} flags remove attributes
+from the section, rather than adding them, so if they are used on their own it
+will be as if no flags had been specified at all.
+
+If the optional argument to the @code{.section} directive is not quoted, it is
+taken as a subsegment number (@pxref{Sub-Sections}).
+@end ifset
+
+@ifset ELF
+@ifset COFF
+@c only print the extra heading if both COFF and ELF are set
+@subheading ELF Version
+@end ifset
+
+@cindex Section Stack
+This is one of the ELF section stack manipulation directives. The others are
+@code{.subsection} (@pxref{SubSection}), @code{.pushsection}
+(@pxref{PushSection}), @code{.popsection} (@pxref{PopSection}), and
+@code{.previous} (@pxref{Previous}).
+
+@cindex @code{section} directive (ELF version)
+For ELF targets, the @code{.section} directive is used like this:
+
+@smallexample
+.section @var{name} [, "@var{flags}"[, @@@var{type}[, @@@var{entsize}]]]
+@end smallexample
+
+The optional @var{flags} argument is a quoted string which may contain any
+combination of the following characters:
+@table @code
+@item a
+section is allocatable
+@item w
+section is writable
+@item x
+section is executable
+@item M
+section is mergeable
+@item S
+section contains zero terminated strings
+@end table
+
+The optional @var{type} argument may contain one of the following constants:
+@table @code
+@item @@progbits
+section contains data
+@item @@nobits
+section does not contain data (i.e., section only occupies space)
+@end table
+
+Note on targets where the @code{@@} character is the start of a comment (eg
+ARM) then another character is used instead. For example the ARM port uses the
+@code{%} character.
+
+If @var{flags} contains @code{M} flag, @var{type} argument must be specified
+as well as @var{entsize} argument. Sections with @code{M} flag but not
+@code{S} flag must contain fixed size constants, each @var{entsize} octets
+long. Sections with both @code{M} and @code{S} must contain zero terminated
+strings where each character is @var{entsize} bytes long. The linker may remove
+duplicates within sections with the same name, same entity size and same flags.
+
+If no flags are specified, the default flags depend upon the section name. If
+the section name is not recognized, the default will be for the section to have
+none of the above flags: it will not be allocated in memory, nor writable, nor
+executable. The section will contain data.
+
+For ELF targets, the assembler supports another type of @code{.section}
+directive for compatibility with the Solaris assembler:
+
+@smallexample
+.section "@var{name}"[, @var{flags}...]
+@end smallexample
+
+Note that the section name is quoted. There may be a sequence of comma
+separated flags:
+@table @code
+@item #alloc
+section is allocatable
+@item #write
+section is writable
+@item #execinstr
+section is executable
+@end table
+
+This directive replaces the current section and subsection. The replaced
+section and subsection are pushed onto the section stack. See the contents of
+the gas testsuite directory @code{gas/testsuite/gas/elf} for some examples of
+how this directive and the other section stack directives work.
+@end ifset
+@end ifset
+
+@node Set
+@section @code{.set @var{symbol}, @var{expression}}
+
+@cindex @code{set} directive
+@cindex symbol value, setting
+Set the value of @var{symbol} to @var{expression}. This
+changes @var{symbol}'s value and type to conform to
+@var{expression}. If @var{symbol} was flagged as external, it remains
+flagged (@pxref{Symbol Attributes}).
+
+You may @code{.set} a symbol many times in the same assembly.
+
+If you @code{.set} a global symbol, the value stored in the object
+file is the last value stored into it.
+
+@ifset HPPA
+The syntax for @code{set} on the HPPA is
+@samp{@var{symbol} .set @var{expression}}.
+@end ifset
+
+@node Short
+@section @code{.short @var{expressions}}
+
+@cindex @code{short} directive
+@ifset GENERIC
+@code{.short} is normally the same as @samp{.word}.
+@xref{Word,,@code{.word}}.
+
+In some configurations, however, @code{.short} and @code{.word} generate
+numbers of different lengths; @pxref{Machine Dependencies}.
+@end ifset
+@ifclear GENERIC
+@ifset W16
+@code{.short} is the same as @samp{.word}. @xref{Word,,@code{.word}}.
+@end ifset
+@ifset W32
+This expects zero or more @var{expressions}, and emits
+a 16 bit number for each.
+@end ifset
+@end ifclear
+
+@node Single
+@section @code{.single @var{flonums}}
+
+@cindex @code{single} directive
+@cindex floating point numbers (single)
+This directive assembles zero or more flonums, separated by commas. It
+has the same effect as @code{.float}.
+@ifset GENERIC
+The exact kind of floating point numbers emitted depends on how
+@command{@value{AS}} is configured. @xref{Machine Dependencies}.
+@end ifset
+@ifclear GENERIC
+@ifset IEEEFLOAT
+On the @value{TARGET} family, @code{.single} emits 32-bit floating point
+numbers in @sc{ieee} format.
+@end ifset
+@end ifclear
+
+@ifset COFF-ELF
+@node Size
+@section @code{.size}
+
+This directive is used to set the size associated with a symbol.
+
+@ifset COFF
+@ifset ELF
+@c only print the extra heading if both COFF and ELF are set
+@subheading COFF Version
+@end ifset
+
+@cindex @code{size} directive (COFF version)
+For COFF targets, the @code{.size} directive is only permitted inside
+@code{.def}/@code{.endef} pairs. It is used like this:
+
+@smallexample
+.size @var{expression}
+@end smallexample
+
+@ifset BOUT
+@samp{.size} is only meaningful when generating COFF format output; when
+@command{@value{AS}} is generating @code{b.out}, it accepts this directive but
+ignores it.
+@end ifset
+@end ifset
+
+@ifset ELF
+@ifset COFF
+@c only print the extra heading if both COFF and ELF are set
+@subheading ELF Version
+@end ifset
+
+@cindex @code{size} directive (ELF version)
+For ELF targets, the @code{.size} directive is used like this:
+
+@smallexample
+.size @var{name} , @var{expression}
+@end smallexample
+
+This directive sets the size associated with a symbol @var{name}.
+The size in bytes is computed from @var{expression} which can make use of label
+arithmetic. This directive is typically used to set the size of function
+symbols.
+@end ifset
+@end ifset
+
+@node Sleb128
+@section @code{.sleb128 @var{expressions}}
+
+@cindex @code{sleb128} directive
+@var{sleb128} stands for ``signed little endian base 128.'' This is a
+compact, variable length representation of numbers used by the DWARF
+symbolic debugging format. @xref{Uleb128,@code{.uleb128}}.
+
+@ifclear no-space-dir
+@node Skip
+@section @code{.skip @var{size} , @var{fill}}
+
+@cindex @code{skip} directive
+@cindex filling memory
+This directive emits @var{size} bytes, each of value @var{fill}. Both
+@var{size} and @var{fill} are absolute expressions. If the comma and
+@var{fill} are omitted, @var{fill} is assumed to be zero. This is the same as
+@samp{.space}.
+
+@node Space
+@section @code{.space @var{size} , @var{fill}}
+
+@cindex @code{space} directive
+@cindex filling memory
+This directive emits @var{size} bytes, each of value @var{fill}. Both
+@var{size} and @var{fill} are absolute expressions. If the comma
+and @var{fill} are omitted, @var{fill} is assumed to be zero. This is the same
+as @samp{.skip}.
+
+@ifset HPPA
+@quotation
+@emph{Warning:} @code{.space} has a completely different meaning for HPPA
+targets; use @code{.block} as a substitute. See @cite{HP9000 Series 800
+Assembly Language Reference Manual} (HP 92432-90001) for the meaning of the
+@code{.space} directive. @xref{HPPA Directives,,HPPA Assembler Directives},
+for a summary.
+@end quotation
+@end ifset
+@end ifclear
+
+@ifset A29K
+@ifclear GENERIC
+@node Space
+@section @code{.space}
+@cindex @code{space} directive
+@end ifclear
+On the AMD 29K, this directive is ignored; it is accepted for
+compatibility with other AMD 29K assemblers.
+
+@quotation
+@emph{Warning:} In most versions of the @sc{gnu} assembler, the directive
+@code{.space} has the effect of @code{.block} @xref{Machine Dependencies}.
+@end quotation
+@end ifset
+
+@ifset have-stabs
+@node Stab
+@section @code{.stabd, .stabn, .stabs}
+
+@cindex symbolic debuggers, information for
+@cindex @code{stab@var{x}} directives
+There are three directives that begin @samp{.stab}.
+All emit symbols (@pxref{Symbols}), for use by symbolic debuggers.
+The symbols are not entered in the @command{@value{AS}} hash table: they
+cannot be referenced elsewhere in the source file.
+Up to five fields are required:
+
+@table @var
+@item string
+This is the symbol's name. It may contain any character except
+@samp{\000}, so is more general than ordinary symbol names. Some
+debuggers used to code arbitrarily complex structures into symbol names
+using this field.
+
+@item type
+An absolute expression. The symbol's type is set to the low 8 bits of
+this expression. Any bit pattern is permitted, but @code{@value{LD}}
+and debuggers choke on silly bit patterns.
+
+@item other
+An absolute expression. The symbol's ``other'' attribute is set to the
+low 8 bits of this expression.
+
+@item desc
+An absolute expression. The symbol's descriptor is set to the low 16
+bits of this expression.
+
+@item value
+An absolute expression which becomes the symbol's value.
+@end table
+
+If a warning is detected while reading a @code{.stabd}, @code{.stabn},
+or @code{.stabs} statement, the symbol has probably already been created;
+you get a half-formed symbol in your object file. This is
+compatible with earlier assemblers!
+
+@table @code
+@cindex @code{stabd} directive
+@item .stabd @var{type} , @var{other} , @var{desc}
+
+The ``name'' of the symbol generated is not even an empty string.
+It is a null pointer, for compatibility. Older assemblers used a
+null pointer so they didn't waste space in object files with empty
+strings.
+
+The symbol's value is set to the location counter,
+relocatably. When your program is linked, the value of this symbol
+is the address of the location counter when the @code{.stabd} was
+assembled.
+
+@cindex @code{stabn} directive
+@item .stabn @var{type} , @var{other} , @var{desc} , @var{value}
+The name of the symbol is set to the empty string @code{""}.
+
+@cindex @code{stabs} directive
+@item .stabs @var{string} , @var{type} , @var{other} , @var{desc} , @var{value}
+All five fields are specified.
+@end table
+@end ifset
+@c end have-stabs
+
+@node String
+@section @code{.string} "@var{str}"
+
+@cindex string, copying to object file
+@cindex @code{string} directive
+
+Copy the characters in @var{str} to the object file. You may specify more than
+one string to copy, separated by commas. Unless otherwise specified for a
+particular machine, the assembler marks the end of each string with a 0 byte.
+You can use any of the escape sequences described in @ref{Strings,,Strings}.
+
+@node Struct
+@section @code{.struct @var{expression}}
+
+@cindex @code{struct} directive
+Switch to the absolute section, and set the section offset to @var{expression},
+which must be an absolute expression. You might use this as follows:
+@smallexample
+ .struct 0
+field1:
+ .struct field1 + 4
+field2:
+ .struct field2 + 4
+field3:
+@end smallexample
+This would define the symbol @code{field1} to have the value 0, the symbol
+@code{field2} to have the value 4, and the symbol @code{field3} to have the
+value 8. Assembly would be left in the absolute section, and you would need to
+use a @code{.section} directive of some sort to change to some other section
+before further assembly.
+
+@ifset ELF
+@node SubSection
+@section @code{.subsection @var{name}}
+
+@cindex @code{subsection} directive
+@cindex Section Stack
+This is one of the ELF section stack manipulation directives. The others are
+@code{.section} (@pxref{Section}), @code{.pushsection} (@pxref{PushSection}),
+@code{.popsection} (@pxref{PopSection}), and @code{.previous}
+(@pxref{Previous}).
+
+This directive replaces the current subsection with @code{name}. The current
+section is not changed. The replaced subsection is put onto the section stack
+in place of the then current top of stack subsection.
+@end ifset
+
+@ifset ELF
+@node Symver
+@section @code{.symver}
+@cindex @code{symver} directive
+@cindex symbol versioning
+@cindex versions of symbols
+Use the @code{.symver} directive to bind symbols to specific version nodes
+within a source file. This is only supported on ELF platforms, and is
+typically used when assembling files to be linked into a shared library.
+There are cases where it may make sense to use this in objects to be bound
+into an application itself so as to override a versioned symbol from a
+shared library.
+
+For ELF targets, the @code{.symver} directive can be used like this:
+@smallexample
+.symver @var{name}, @var{name2@@nodename}
+@end smallexample
+If the symbol @var{name} is defined within the file
+being assembled, the @code{.symver} directive effectively creates a symbol
+alias with the name @var{name2@@nodename}, and in fact the main reason that we
+just don't try and create a regular alias is that the @var{@@} character isn't
+permitted in symbol names. The @var{name2} part of the name is the actual name
+of the symbol by which it will be externally referenced. The name @var{name}
+itself is merely a name of convenience that is used so that it is possible to
+have definitions for multiple versions of a function within a single source
+file, and so that the compiler can unambiguously know which version of a
+function is being mentioned. The @var{nodename} portion of the alias should be
+the name of a node specified in the version script supplied to the linker when
+building a shared library. If you are attempting to override a versioned
+symbol from a shared library, then @var{nodename} should correspond to the
+nodename of the symbol you are trying to override.
+
+If the symbol @var{name} is not defined within the file being assembled, all
+references to @var{name} will be changed to @var{name2@@nodename}. If no
+reference to @var{name} is made, @var{name2@@nodename} will be removed from the
+symbol table.
+
+Another usage of the @code{.symver} directive is:
+@smallexample
+.symver @var{name}, @var{name2@@@@nodename}
+@end smallexample
+In this case, the symbol @var{name} must exist and be defined within
+the file being assembled. It is similar to @var{name2@@nodename}. The
+difference is @var{name2@@@@nodename} will also be used to resolve
+references to @var{name2} by the linker.
+
+The third usage of the @code{.symver} directive is:
+@smallexample
+.symver @var{name}, @var{name2@@@@@@nodename}
+@end smallexample
+When @var{name} is not defined within the
+file being assembled, it is treated as @var{name2@@nodename}. When
+@var{name} is defined within the file being assembled, the symbol
+name, @var{name}, will be changed to @var{name2@@@@nodename}.
+@end ifset
+
+@ifset COFF
+@node Tag
+@section @code{.tag @var{structname}}
+
+@cindex COFF structure debugging
+@cindex structure debugging, COFF
+@cindex @code{tag} directive
+This directive is generated by compilers to include auxiliary debugging
+information in the symbol table. It is only permitted inside
+@code{.def}/@code{.endef} pairs. Tags are used to link structure
+definitions in the symbol table with instances of those structures.
+@ifset BOUT
+
+@samp{.tag} is only used when generating COFF format output; when
+@command{@value{AS}} is generating @code{b.out}, it accepts this directive but
+ignores it.
+@end ifset
+@end ifset
+
+@node Text
+@section @code{.text @var{subsection}}
+
+@cindex @code{text} directive
+Tells @command{@value{AS}} to assemble the following statements onto the end of
+the text subsection numbered @var{subsection}, which is an absolute
+expression. If @var{subsection} is omitted, subsection number zero
+is used.
+
+@node Title
+@section @code{.title "@var{heading}"}
+
+@cindex @code{title} directive
+@cindex listing control: title line
+Use @var{heading} as the title (second line, immediately after the
+source file name and pagenumber) when generating assembly listings.
+
+This directive affects subsequent pages, as well as the current page if
+it appears within ten lines of the top of a page.
+
+@ifset COFF-ELF
+@node Type
+@section @code{.type}
+
+This directive is used to set the type of a symbol.
+
+@ifset COFF
+@ifset ELF
+@c only print the extra heading if both COFF and ELF are set
+@subheading COFF Version
+@end ifset
+
+@cindex COFF symbol type
+@cindex symbol type, COFF
+@cindex @code{type} directive (COFF version)
+For COFF targets, this directive is permitted only within
+@code{.def}/@code{.endef} pairs. It is used like this:
+
+@smallexample
+.type @var{int}
+@end smallexample
+
+This records the integer @var{int} as the type attribute of a symbol table
+entry.
+
+@ifset BOUT
+@samp{.type} is associated only with COFF format output; when
+@command{@value{AS}} is configured for @code{b.out} output, it accepts this
+directive but ignores it.
+@end ifset
+@end ifset
+
+@ifset ELF
+@ifset COFF
+@c only print the extra heading if both COFF and ELF are set
+@subheading ELF Version
+@end ifset
+
+@cindex ELF symbol type
+@cindex symbol type, ELF
+@cindex @code{type} directive (ELF version)
+For ELF targets, the @code{.type} directive is used like this:
+
+@smallexample
+.type @var{name} , @var{type description}
+@end smallexample
+
+This sets the type of symbol @var{name} to be either a
+function symbol or an object symbol. There are five different syntaxes
+supported for the @var{type description} field, in order to provide
+compatibility with various other assemblers. The syntaxes supported are:
+
+@smallexample
+ .type <name>,#function
+ .type <name>,#object
+
+ .type <name>,@@function
+ .type <name>,@@object
+
+ .type <name>,%function
+ .type <name>,%object
+
+ .type <name>,"function"
+ .type <name>,"object"
+
+ .type <name> STT_FUNCTION
+ .type <name> STT_OBJECT
+@end smallexample
+@end ifset
+@end ifset
+
+@node Uleb128
+@section @code{.uleb128 @var{expressions}}
+
+@cindex @code{uleb128} directive
+@var{uleb128} stands for ``unsigned little endian base 128.'' This is a
+compact, variable length representation of numbers used by the DWARF
+symbolic debugging format. @xref{Sleb128,@code{.sleb128}}.
+
+@ifset COFF
+@node Val
+@section @code{.val @var{addr}}
+
+@cindex @code{val} directive
+@cindex COFF value attribute
+@cindex value attribute, COFF
+This directive, permitted only within @code{.def}/@code{.endef} pairs,
+records the address @var{addr} as the value attribute of a symbol table
+entry.
+@ifset BOUT
+
+@samp{.val} is used only for COFF output; when @command{@value{AS}} is
+configured for @code{b.out}, it accepts this directive but ignores it.
+@end ifset
+@end ifset
+
+@ifset ELF
+@node Version
+@section @code{.version "@var{string}"}
+
+@cindex @code{version} directive
+This directive creates a @code{.note} section and places into it an ELF
+formatted note of type NT_VERSION. The note's name is set to @code{string}.
+@end ifset
+
+@ifset ELF
+@node VTableEntry
+@section @code{.vtable_entry @var{table}, @var{offset}}
+
+@cindex @code{vtable_entry}
+This directive finds or creates a symbol @code{table} and creates a
+@code{VTABLE_ENTRY} relocation for it with an addend of @code{offset}.
+
+@node VTableInherit
+@section @code{.vtable_inherit @var{child}, @var{parent}}
+
+@cindex @code{vtable_inherit}
+This directive finds the symbol @code{child} and finds or creates the symbol
+@code{parent} and then creates a @code{VTABLE_INHERIT} relocation for the
+parent whose addend is the value of the child symbol. As a special case the
+parent name of @code{0} is treated as refering the @code{*ABS*} section.
+@end ifset
+
+@ifset ELF
+@node Weak
+@section @code{.weak @var{names}}
+
+@cindex @code{weak} directive
+This directive sets the weak attribute on the comma separated list of symbol
+@code{names}. If the symbols do not already exist, they will be created.
+@end ifset
+
+@node Word
+@section @code{.word @var{expressions}}
+
+@cindex @code{word} directive
+This directive expects zero or more @var{expressions}, of any section,
+separated by commas.
+@ifclear GENERIC
+@ifset W32
+For each expression, @command{@value{AS}} emits a 32-bit number.
+@end ifset
+@ifset W16
+For each expression, @command{@value{AS}} emits a 16-bit number.
+@end ifset
+@end ifclear
+@ifset GENERIC
+
+The size of the number emitted, and its byte order,
+depend on what target computer the assembly is for.
+@end ifset
+
+@c on amd29k, i960, sparc the "special treatment to support compilers" doesn't
+@c happen---32-bit addressability, period; no long/short jumps.
+@ifset DIFF-TBL-KLUGE
+@cindex difference tables altered
+@cindex altered difference tables
+@quotation
+@emph{Warning: Special Treatment to support Compilers}
+@end quotation
+
+@ifset GENERIC
+Machines with a 32-bit address space, but that do less than 32-bit
+addressing, require the following special treatment. If the machine of
+interest to you does 32-bit addressing (or doesn't require it;
+@pxref{Machine Dependencies}), you can ignore this issue.
+
+@end ifset
+In order to assemble compiler output into something that works,
+@command{@value{AS}} occasionally does strange things to @samp{.word} directives.
+Directives of the form @samp{.word sym1-sym2} are often emitted by
+compilers as part of jump tables. Therefore, when @command{@value{AS}} assembles a
+directive of the form @samp{.word sym1-sym2}, and the difference between
+@code{sym1} and @code{sym2} does not fit in 16 bits, @command{@value{AS}}
+creates a @dfn{secondary jump table}, immediately before the next label.
+This secondary jump table is preceded by a short-jump to the
+first byte after the secondary table. This short-jump prevents the flow
+of control from accidentally falling into the new table. Inside the
+table is a long-jump to @code{sym2}. The original @samp{.word}
+contains @code{sym1} minus the address of the long-jump to
+@code{sym2}.
+
+If there were several occurrences of @samp{.word sym1-sym2} before the
+secondary jump table, all of them are adjusted. If there was a
+@samp{.word sym3-sym4}, that also did not fit in sixteen bits, a
+long-jump to @code{sym4} is included in the secondary jump table,
+and the @code{.word} directives are adjusted to contain @code{sym3}
+minus the address of the long-jump to @code{sym4}; and so on, for as many
+entries in the original jump table as necessary.
+
+@ifset INTERNALS
+@emph{This feature may be disabled by compiling @command{@value{AS}} with the
+@samp{-DWORKING_DOT_WORD} option.} This feature is likely to confuse
+assembly language programmers.
+@end ifset
+@end ifset
+@c end DIFF-TBL-KLUGE
+
+@node Deprecated
+@section Deprecated Directives
+
+@cindex deprecated directives
+@cindex obsolescent directives
+One day these directives won't work.
+They are included for compatibility with older assemblers.
+@table @t
+@item .abort
+@item .line
+@end table
+
+@ifset GENERIC
+@node Machine Dependencies
+@chapter Machine Dependent Features
+
+@cindex machine dependencies
+The machine instruction sets are (almost by definition) different on
+each machine where @command{@value{AS}} runs. Floating point representations
+vary as well, and @command{@value{AS}} often supports a few additional
+directives or command-line options for compatibility with other
+assemblers on a particular platform. Finally, some versions of
+@command{@value{AS}} support special pseudo-instructions for branch
+optimization.
+
+This chapter discusses most of these differences, though it does not
+include details on any machine's instruction set. For details on that
+subject, see the hardware manufacturer's manual.
+
+@menu
+@ifset A29K
+* AMD29K-Dependent:: AMD 29K Dependent Features
+@end ifset
+@ifset ALPHA
+* Alpha-Dependent:: Alpha Dependent Features
+@end ifset
+@ifset ARC
+* ARC-Dependent:: ARC Dependent Features
+@end ifset
+@ifset ARM
+* ARM-Dependent:: ARM Dependent Features
+@end ifset
+@ifset CRIS
+* CRIS-Dependent:: CRIS Dependent Features
+@end ifset
+@ifset D10V
+* D10V-Dependent:: D10V Dependent Features
+@end ifset
+@ifset D30V
+* D30V-Dependent:: D30V Dependent Features
+@end ifset
+@ifset H8/300
+* H8/300-Dependent:: Renesas H8/300 Dependent Features
+@end ifset
+@ifset H8/500
+* H8/500-Dependent:: Renesas H8/500 Dependent Features
+@end ifset
+@ifset HPPA
+* HPPA-Dependent:: HPPA Dependent Features
+@end ifset
+@ifset I370
+* ESA/390-Dependent:: IBM ESA/390 Dependent Features
+@end ifset
+@ifset I80386
+* i386-Dependent:: Intel 80386 and AMD x86-64 Dependent Features
+@end ifset
+@ifset I860
+* i860-Dependent:: Intel 80860 Dependent Features
+@end ifset
+@ifset I960
+* i960-Dependent:: Intel 80960 Dependent Features
+@end ifset
+@ifset IP2K
+* IP2K-Dependent:: IP2K Dependent Features
+@end ifset
+@ifset M32R
+* M32R-Dependent:: M32R Dependent Features
+@end ifset
+@ifset M680X0
+* M68K-Dependent:: M680x0 Dependent Features
+@end ifset
+@ifset M68HC11
+* M68HC11-Dependent:: M68HC11 and 68HC12 Dependent Features
+@end ifset
+@ifset M880X0
+* M88K-Dependent:: M880x0 Dependent Features
+@end ifset
+@ifset MIPS
+* MIPS-Dependent:: MIPS Dependent Features
+@end ifset
+@ifset MMIX
+* MMIX-Dependent:: MMIX Dependent Features
+@end ifset
+@ifset MSP430
+* MSP430-Dependent:: MSP430 Dependent Features
+@end ifset
+@ifset SH
+* SH-Dependent:: Renesas / SuperH SH Dependent Features
+* SH64-Dependent:: SuperH SH64 Dependent Features
+@end ifset
+@ifset PDP11
+* PDP-11-Dependent:: PDP-11 Dependent Features
+@end ifset
+@ifset PJ
+* PJ-Dependent:: picoJava Dependent Features
+@end ifset
+@ifset PPC
+* PPC-Dependent:: PowerPC Dependent Features
+@end ifset
+@ifset SPARC
+* Sparc-Dependent:: SPARC Dependent Features
+@end ifset
+@ifset TIC54X
+* TIC54X-Dependent:: TI TMS320C54x Dependent Features
+@end ifset
+@ifset V850
+* V850-Dependent:: V850 Dependent Features
+@end ifset
+@ifset XTENSA
+* Xtensa-Dependent:: Xtensa Dependent Features
+@end ifset
+@ifset Z8000
+* Z8000-Dependent:: Z8000 Dependent Features
+@end ifset
+@ifset VAX
+* Vax-Dependent:: VAX Dependent Features
+@end ifset
+@end menu
+
+@lowersections
+@end ifset
+
+@c The following major nodes are *sections* in the GENERIC version, *chapters*
+@c in single-cpu versions. This is mainly achieved by @lowersections. There is a
+@c peculiarity: to preserve cross-references, there must be a node called
+@c "Machine Dependencies". Hence the conditional nodenames in each
+@c major node below. Node defaulting in makeinfo requires adjacency of
+@c node and sectioning commands; hence the repetition of @chapter BLAH
+@c in both conditional blocks.
+
+@ifset A29K
+@include c-a29k.texi
+@end ifset
+
+@ifset ALPHA
+@include c-alpha.texi
+@end ifset
+
+@ifset ARC
+@include c-arc.texi
+@end ifset
+
+@ifset ARM
+@include c-arm.texi
+@end ifset
+
+@ifset CRIS
+@include c-cris.texi
+@end ifset
+
+@ifset Renesas-all
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter Machine Dependent Features
+
+The machine instruction sets are different on each Renesas chip family,
+and there are also some syntax differences among the families. This
+chapter describes the specific @command{@value{AS}} features for each
+family.
+
+@menu
+* H8/300-Dependent:: Renesas H8/300 Dependent Features
+* H8/500-Dependent:: Renesas H8/500 Dependent Features
+* SH-Dependent:: Renesas SH Dependent Features
+@end menu
+@lowersections
+@end ifclear
+@end ifset
+
+@ifset D10V
+@include c-d10v.texi
+@end ifset
+
+@ifset D30V
+@include c-d30v.texi
+@end ifset
+
+@ifset H8/300
+@include c-h8300.texi
+@end ifset
+
+@ifset H8/500
+@include c-h8500.texi
+@end ifset
+
+@ifset HPPA
+@include c-hppa.texi
+@end ifset
+
+@ifset I370
+@include c-i370.texi
+@end ifset
+
+@ifset I80386
+@include c-i386.texi
+@end ifset
+
+@ifset I860
+@include c-i860.texi
+@end ifset
+
+@ifset I960
+@include c-i960.texi
+@end ifset
+
+@ifset IA64
+@include c-ia64.texi
+@end ifset
+
+@ifset IP2K
+@include c-ip2k.texi
+@end ifset
+
+@ifset M32R
+@include c-m32r.texi
+@end ifset
+
+@ifset M680X0
+@include c-m68k.texi
+@end ifset
+
+@ifset M68HC11
+@include c-m68hc11.texi
+@end ifset
+
+@ifset M880X0
+@include c-m88k.texi
+@end ifset
+
+@ifset MIPS
+@include c-mips.texi
+@end ifset
+
+@ifset MMIX
+@include c-mmix.texi
+@end ifset
+
+@ifset MSP430
+@include c-msp430.texi
+@end ifset
+
+@ifset NS32K
+@include c-ns32k.texi
+@end ifset
+
+@ifset PDP11
+@include c-pdp11.texi
+@end ifset
+
+@ifset PJ
+@include c-pj.texi
+@end ifset
+
+@ifset PPC
+@include c-ppc.texi
+@end ifset
+
+@ifset SH
+@include c-sh.texi
+@include c-sh64.texi
+@end ifset
+
+@ifset SPARC
+@include c-sparc.texi
+@end ifset
+
+@ifset TIC54X
+@include c-tic54x.texi
+@end ifset
+
+@ifset Z8000
+@include c-z8k.texi
+@end ifset
+
+@ifset VAX
+@include c-vax.texi
+@end ifset
+
+@ifset V850
+@include c-v850.texi
+@end ifset
+
+@ifset XTENSA
+@include c-xtensa.texi
+@end ifset
+
+@ifset GENERIC
+@c reverse effect of @down at top of generic Machine-Dep chapter
+@raisesections
+@end ifset
+
+@node Reporting Bugs
+@chapter Reporting Bugs
+@cindex bugs in assembler
+@cindex reporting bugs in assembler
+
+Your bug reports play an essential role in making @command{@value{AS}} reliable.
+
+Reporting a bug may help you by bringing a solution to your problem, or it may
+not. But in any case the principal function of a bug report is to help the
+entire community by making the next version of @command{@value{AS}} work better.
+Bug reports are your contribution to the maintenance of @command{@value{AS}}.
+
+In order for a bug report to serve its purpose, you must include the
+information that enables us to fix the bug.
+
+@menu
+* Bug Criteria:: Have you found a bug?
+* Bug Reporting:: How to report bugs
+@end menu
+
+@node Bug Criteria
+@section Have You Found a Bug?
+@cindex bug criteria
+
+If you are not sure whether you have found a bug, here are some guidelines:
+
+@itemize @bullet
+@cindex fatal signal
+@cindex assembler crash
+@cindex crash of assembler
+@item
+If the assembler gets a fatal signal, for any input whatever, that is a
+@command{@value{AS}} bug. Reliable assemblers never crash.
+
+@cindex error on valid input
+@item
+If @command{@value{AS}} produces an error message for valid input, that is a bug.
+
+@cindex invalid input
+@item
+If @command{@value{AS}} does not produce an error message for invalid input, that
+is a bug. However, you should note that your idea of ``invalid input'' might
+be our idea of ``an extension'' or ``support for traditional practice''.
+
+@item
+If you are an experienced user of assemblers, your suggestions for improvement
+of @command{@value{AS}} are welcome in any case.
+@end itemize
+
+@node Bug Reporting
+@section How to Report Bugs
+@cindex bug reports
+@cindex assembler bugs, reporting
+
+A number of companies and individuals offer support for @sc{gnu} products. If
+you obtained @command{@value{AS}} from a support organization, we recommend you
+contact that organization first.
+
+You can find contact information for many support companies and
+individuals in the file @file{etc/SERVICE} in the @sc{gnu} Emacs
+distribution.
+
+In any event, we also recommend that you send bug reports for @command{@value{AS}}
+to @samp{bug-binutils@@gnu.org}.
+
+The fundamental principle of reporting bugs usefully is this:
+@strong{report all the facts}. If you are not sure whether to state a
+fact or leave it out, state it!
+
+Often people omit facts because they think they know what causes the problem
+and assume that some details do not matter. Thus, you might assume that the
+name of a symbol you use in an example does not matter. Well, probably it does
+not, but one cannot be sure. Perhaps the bug is a stray memory reference which
+happens to fetch from the location where that name is stored in memory;
+perhaps, if the name were different, the contents of that location would fool
+the assembler into doing the right thing despite the bug. Play it safe and
+give a specific, complete example. That is the easiest thing for you to do,
+and the most helpful.
+
+Keep in mind that the purpose of a bug report is to enable us to fix the bug if
+it is new to us. Therefore, always write your bug reports on the assumption
+that the bug has not been reported previously.
+
+Sometimes people give a few sketchy facts and ask, ``Does this ring a
+bell?'' This cannot help us fix a bug, so it is basically useless. We
+respond by asking for enough details to enable us to investigate.
+You might as well expedite matters by sending them to begin with.
+
+To enable us to fix the bug, you should include all these things:
+
+@itemize @bullet
+@item
+The version of @command{@value{AS}}. @command{@value{AS}} announces it if you start
+it with the @samp{--version} argument.
+
+Without this, we will not know whether there is any point in looking for
+the bug in the current version of @command{@value{AS}}.
+
+@item
+Any patches you may have applied to the @command{@value{AS}} source.
+
+@item
+The type of machine you are using, and the operating system name and
+version number.
+
+@item
+What compiler (and its version) was used to compile @command{@value{AS}}---e.g.
+``@code{gcc-2.7}''.
+
+@item
+The command arguments you gave the assembler to assemble your example and
+observe the bug. To guarantee you will not omit something important, list them
+all. A copy of the Makefile (or the output from make) is sufficient.
+
+If we were to try to guess the arguments, we would probably guess wrong
+and then we might not encounter the bug.
+
+@item
+A complete input file that will reproduce the bug. If the bug is observed when
+the assembler is invoked via a compiler, send the assembler source, not the
+high level language source. Most compilers will produce the assembler source
+when run with the @samp{-S} option. If you are using @code{@value{GCC}}, use
+the options @samp{-v --save-temps}; this will save the assembler source in a
+file with an extension of @file{.s}, and also show you exactly how
+@command{@value{AS}} is being run.
+
+@item
+A description of what behavior you observe that you believe is
+incorrect. For example, ``It gets a fatal signal.''
+
+Of course, if the bug is that @command{@value{AS}} gets a fatal signal, then we
+will certainly notice it. But if the bug is incorrect output, we might not
+notice unless it is glaringly wrong. You might as well not give us a chance to
+make a mistake.
+
+Even if the problem you experience is a fatal signal, you should still say so
+explicitly. Suppose something strange is going on, such as, your copy of
+@command{@value{AS}} is out of synch, or you have encountered a bug in the C
+library on your system. (This has happened!) Your copy might crash and ours
+would not. If you told us to expect a crash, then when ours fails to crash, we
+would know that the bug was not happening for us. If you had not told us to
+expect a crash, then we would not be able to draw any conclusion from our
+observations.
+
+@item
+If you wish to suggest changes to the @command{@value{AS}} source, send us context
+diffs, as generated by @code{diff} with the @samp{-u}, @samp{-c}, or @samp{-p}
+option. Always send diffs from the old file to the new file. If you even
+discuss something in the @command{@value{AS}} source, refer to it by context, not
+by line number.
+
+The line numbers in our development sources will not match those in your
+sources. Your line numbers would convey no useful information to us.
+@end itemize
+
+Here are some things that are not necessary:
+
+@itemize @bullet
+@item
+A description of the envelope of the bug.
+
+Often people who encounter a bug spend a lot of time investigating
+which changes to the input file will make the bug go away and which
+changes will not affect it.
+
+This is often time consuming and not very useful, because the way we
+will find the bug is by running a single example under the debugger
+with breakpoints, not by pure deduction from a series of examples.
+We recommend that you save your time for something else.
+
+Of course, if you can find a simpler example to report @emph{instead}
+of the original one, that is a convenience for us. Errors in the
+output will be easier to spot, running under the debugger will take
+less time, and so on.
+
+However, simplification is not vital; if you do not want to do this,
+report the bug anyway and send us the entire test case you used.
+
+@item
+A patch for the bug.
+
+A patch for the bug does help us if it is a good one. But do not omit
+the necessary information, such as the test case, on the assumption that
+a patch is all we need. We might see problems with your patch and decide
+to fix the problem another way, or we might not understand it at all.
+
+Sometimes with a program as complicated as @command{@value{AS}} it is very hard to
+construct an example that will make the program follow a certain path through
+the code. If you do not send us the example, we will not be able to construct
+one, so we will not be able to verify that the bug is fixed.
+
+And if we cannot understand what bug you are trying to fix, or why your
+patch should be an improvement, we will not install it. A test case will
+help us to understand.
+
+@item
+A guess about what the bug is or what it depends on.
+
+Such guesses are usually wrong. Even we cannot guess right about such
+things without first using the debugger to find the facts.
+@end itemize
+
+@node Acknowledgements
+@chapter Acknowledgements
+
+If you have contributed to @command{@value{AS}} and your name isn't listed here,
+it is not meant as a slight. We just don't know about it. Send mail to the
+maintainer, and we'll correct the situation. Currently
+@c (January 1994),
+the maintainer is Ken Raeburn (email address @code{raeburn@@cygnus.com}).
+
+Dean Elsner wrote the original @sc{gnu} assembler for the VAX.@footnote{Any
+more details?}
+
+Jay Fenlason maintained GAS for a while, adding support for GDB-specific debug
+information and the 68k series machines, most of the preprocessing pass, and
+extensive changes in @file{messages.c}, @file{input-file.c}, @file{write.c}.
+
+K. Richard Pixley maintained GAS for a while, adding various enhancements and
+many bug fixes, including merging support for several processors, breaking GAS
+up to handle multiple object file format back ends (including heavy rewrite,
+testing, an integration of the coff and b.out back ends), adding configuration
+including heavy testing and verification of cross assemblers and file splits
+and renaming, converted GAS to strictly ANSI C including full prototypes, added
+support for m680[34]0 and cpu32, did considerable work on i960 including a COFF
+port (including considerable amounts of reverse engineering), a SPARC opcode
+file rewrite, DECstation, rs6000, and hp300hpux host ports, updated ``know''
+assertions and made them work, much other reorganization, cleanup, and lint.
+
+Ken Raeburn wrote the high-level BFD interface code to replace most of the code
+in format-specific I/O modules.
+
+The original VMS support was contributed by David L. Kashtan. Eric Youngdale
+has done much work with it since.
+
+The Intel 80386 machine description was written by Eliot Dresselhaus.
+
+Minh Tran-Le at IntelliCorp contributed some AIX 386 support.
+
+The Motorola 88k machine description was contributed by Devon Bowen of Buffalo
+University and Torbjorn Granlund of the Swedish Institute of Computer Science.
+
+Keith Knowles at the Open Software Foundation wrote the original MIPS back end
+(@file{tc-mips.c}, @file{tc-mips.h}), and contributed Rose format support
+(which hasn't been merged in yet). Ralph Campbell worked with the MIPS code to
+support a.out format.
+
+Support for the Zilog Z8k and Renesas H8/300 and H8/500 processors (tc-z8k,
+tc-h8300, tc-h8500), and IEEE 695 object file format (obj-ieee), was written by
+Steve Chamberlain of Cygnus Support. Steve also modified the COFF back end to
+use BFD for some low-level operations, for use with the H8/300 and AMD 29k
+targets.
+
+John Gilmore built the AMD 29000 support, added @code{.include} support, and
+simplified the configuration of which versions accept which directives. He
+updated the 68k machine description so that Motorola's opcodes always produced
+fixed-size instructions (e.g., @code{jsr}), while synthetic instructions
+remained shrinkable (@code{jbsr}). John fixed many bugs, including true tested
+cross-compilation support, and one bug in relaxation that took a week and
+required the proverbial one-bit fix.
+
+Ian Lance Taylor of Cygnus Support merged the Motorola and MIT syntax for the
+68k, completed support for some COFF targets (68k, i386 SVR3, and SCO Unix),
+added support for MIPS ECOFF and ELF targets, wrote the initial RS/6000 and
+PowerPC assembler, and made a few other minor patches.
+
+Steve Chamberlain made @command{@value{AS}} able to generate listings.
+
+Hewlett-Packard contributed support for the HP9000/300.
+
+Jeff Law wrote GAS and BFD support for the native HPPA object format (SOM)
+along with a fairly extensive HPPA testsuite (for both SOM and ELF object
+formats). This work was supported by both the Center for Software Science at
+the University of Utah and Cygnus Support.
+
+Support for ELF format files has been worked on by Mark Eichin of Cygnus
+Support (original, incomplete implementation for SPARC), Pete Hoogenboom and
+Jeff Law at the University of Utah (HPPA mainly), Michael Meissner of the Open
+Software Foundation (i386 mainly), and Ken Raeburn of Cygnus Support (sparc,
+and some initial 64-bit support).
+
+Linas Vepstas added GAS support for the ESA/390 ``IBM 370'' architecture.
+
+Richard Henderson rewrote the Alpha assembler. Klaus Kaempf wrote GAS and BFD
+support for openVMS/Alpha.
+
+Timothy Wall, Michael Hayes, and Greg Smart contributed to the various tic*
+flavors.
+
+David Heine, Sterling Augustine, Bob Wilson and John Ruttenberg from Tensilica,
+Inc. added support for Xtensa processors.
+
+Several engineers at Cygnus Support have also provided many small bug fixes and
+configuration enhancements.
+
+Many others have contributed large or small bugfixes and enhancements. If
+you have contributed significant work and are not mentioned on this list, and
+want to be, let us know. Some of the history has been lost; we are not
+intentionally leaving anyone out.
+
+@include fdl.texi
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@contents
+@bye
+@c Local Variables:
+@c fill-column: 79
+@c End:
diff --git a/x/binutils/gas/doc/c-alpha.texi b/x/binutils/gas/doc/c-alpha.texi
new file mode 100644
index 0000000..0aee06b
--- /dev/null
+++ b/x/binutils/gas/doc/c-alpha.texi
@@ -0,0 +1,466 @@
+@c Copyright 2002
+@c Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+
+@ifset GENERIC
+@page
+@node Alpha-Dependent
+@chapter Alpha Dependent Features
+@end ifset
+
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter Alpha Dependent Features
+@end ifclear
+
+@cindex Alpha support
+@menu
+* Alpha Notes:: Notes
+* Alpha Options:: Options
+* Alpha Syntax:: Syntax
+* Alpha Floating Point:: Floating Point
+* Alpha Directives:: Alpha Machine Directives
+* Alpha Opcodes:: Opcodes
+@end menu
+
+@node Alpha Notes
+@section Notes
+@cindex Alpha notes
+@cindex notes for Alpha
+
+The documentation here is primarily for the ELF object format.
+@code{@value{AS}} also supports the ECOFF and EVAX formats, but
+features specific to these formats are not yet documented.
+
+@node Alpha Options
+@section Options
+@cindex Alpha options
+@cindex options for Alpha
+
+@table @option
+@cindex @code{-m@var{cpu}} command line option, Alpha
+@item -m@var{cpu}
+This option specifies the target processor. If an attempt is made to
+assemble an instruction which will not execute on the target processor,
+the assembler may either expand the instruction as a macro or issue an
+error message. This option is equivalent to the @code{.arch} directive.
+
+The following processor names are recognized:
+@code{21064},
+@code{21064a},
+@code{21066},
+@code{21068},
+@code{21164},
+@code{21164a},
+@code{21164pc},
+@code{21264},
+@code{21264a},
+@code{21264b},
+@code{ev4},
+@code{ev5},
+@code{lca45},
+@code{ev5},
+@code{ev56},
+@code{pca56},
+@code{ev6},
+@code{ev67},
+@code{ev68}.
+The special name @code{all} may be used to allow the assembler to accept
+instructions valid for any Alpha processor.
+
+In order to support existing practice in OSF/1 with respect to @code{.arch},
+and existing practice within @command{MILO} (the Linux ARC bootloader), the
+numbered processor names (e.g.@: 21064) enable the processor-specific PALcode
+instructions, while the ``electro-vlasic'' names (e.g.@: @code{ev4}) do not.
+
+@cindex @code{-mdebug} command line option, Alpha
+@cindex @code{-no-mdebug} command line option, Alpha
+@item -mdebug
+@itemx -no-mdebug
+Enables or disables the generation of @code{.mdebug} encapsulation for
+stabs directives and procedure descriptors. The default is to automatically
+enable @code{.mdebug} when the first stabs directive is seen.
+
+@cindex @code{-relax} command line option, Alpha
+@item -relax
+This option forces all relocations to be put into the object file, instead
+of saving space and resolving some relocations at assembly time. Note that
+this option does not propagate all symbol arithmetic into the object file,
+because not all symbol arithmetic can be represented. However, the option
+can still be useful in specific applications.
+
+@cindex @code{-g} command line option, Alpha
+@item -g
+This option is used when the compiler generates debug information. When
+@command{gcc} is using @command{mips-tfile} to generate debug
+information for ECOFF, local labels must be passed through to the object
+file. Otherwise this option has no effect.
+
+@cindex @code{-G} command line option, Alpha
+@item -G@var{size}
+A local common symbol larger than @var{size} is placed in @code{.bss},
+while smaller symbols are placed in @code{.sbss}.
+
+@cindex @code{-F} command line option, Alpha
+@cindex @code{-32addr} command line option, Alpha
+@item -F
+@itemx -32addr
+These options are ignored for backward compatibility.
+@end table
+
+@cindex Alpha Syntax
+@node Alpha Syntax
+@section Syntax
+The assembler syntax closely follow the Alpha Reference Manual;
+assembler directives and general syntax closely follow the OSF/1 and
+OpenVMS syntax, with a few differences for ELF.
+
+@menu
+* Alpha-Chars:: Special Characters
+* Alpha-Regs:: Register Names
+* Alpha-Relocs:: Relocations
+@end menu
+
+@node Alpha-Chars
+@subsection Special Characters
+
+@cindex line comment character, Alpha
+@cindex Alpha line comment character
+@samp{#} is the line comment character.
+
+@cindex line separator, Alpha
+@cindex statement separator, Alpha
+@cindex Alpha line separator
+@samp{;} can be used instead of a newline to separate statements.
+
+@node Alpha-Regs
+@subsection Register Names
+@cindex Alpha registers
+@cindex register names, Alpha
+
+The 32 integer registers are referred to as @samp{$@var{n}} or
+@samp{$r@var{n}}. In addition, registers 15, 28, 29, and 30 may
+be referred to by the symbols @samp{$fp}, @samp{$at}, @samp{$gp},
+and @samp{$sp} respectively.
+
+The 32 floating-point registers are referred to as @samp{$f@var{n}}.
+
+@node Alpha-Relocs
+@subsection Relocations
+@cindex Alpha relocations
+@cindex relocations, Alpha
+
+Some of these relocations are available for ECOFF, but mostly
+only for ELF. They are modeled after the relocation format
+introduced in Digital Unix 4.0, but there are additions.
+
+The format is @samp{!@var{tag}} or @samp{!@var{tag}!@var{number}}
+where @var{tag} is the name of the relocation. In some cases
+@var{number} is used to relate specific instructions.
+
+The relocation is placed at the end of the instruction like so:
+
+@example
+ldah $0,a($29) !gprelhigh
+lda $0,a($0) !gprellow
+ldq $1,b($29) !literal!100
+ldl $2,0($1) !lituse_base!100
+@end example
+
+@table @code
+@item !literal
+@itemx !literal!@var{N}
+Used with an @code{ldq} instruction to load the address of a symbol
+from the GOT.
+
+A sequence number @var{N} is optional, and if present is used to pair
+@code{lituse} relocations with this @code{literal} relocation. The
+@code{lituse} relocations are used by the linker to optimize the code
+based on the final location of the symbol.
+
+Note that these optimizations are dependent on the data flow of the
+program. Therefore, if @emph{any} @code{lituse} is paired with a
+@code{literal} relocation, then @emph{all} uses of the register set by
+the @code{literal} instruction must also be marked with @code{lituse}
+relocations. This is because the original @code{literal} instruction
+may be deleted or transformed into another instruction.
+
+Also note that there may be a one-to-many relationship between
+@code{literal} and @code{lituse}, but not a many-to-one. That is, if
+there are two code paths that load up the same address and feed the
+value to a single use, then the use may not use a @code{lituse}
+relocation.
+
+@item !lituse_base!@var{N}
+Used with any memory format instruction (e.g.@: @code{ldl}) to indicate
+that the literal is used for an address load. The offset field of the
+instruction must be zero. During relaxation, the code may be altered
+to use a gp-relative load.
+
+@item !lituse_jsr!@var{N}
+Used with a register branch format instruction (e.g.@: @code{jsr}) to
+indicate that the literal is used for a call. During relaxation, the
+code may be altered to use a direct branch (e.g.@: @code{bsr}).
+
+@item !lituse_bytoff!@var{N}
+Used with a byte mask instruction (e.g.@: @code{extbl}) to indicate
+that only the low 3 bits of the address are relevant. During relaxation,
+the code may be altered to use an immediate instead of a register shift.
+
+@item !lituse_addr!@var{N}
+Used with any other instruction to indicate that the original address
+is in fact used, and the original @code{ldq} instruction may not be
+altered or deleted. This is useful in conjunction with @code{lituse_jsr}
+to test whether a weak symbol is defined.
+
+@example
+ldq $27,foo($29) !literal!1
+beq $27,is_undef !lituse_addr!1
+jsr $26,($27),foo !lituse_jsr!1
+@end example
+
+@item !lituse_tlsgd!@var{N}
+Used with a register branch format instruction to indicate that the
+literal is the call to @code{__tls_get_addr} used to compute the
+address of the thread-local storage variable whose descriptor was
+loaded with @code{!tlsgd!@var{N}}.
+
+@item !lituse_tlsldm!@var{N}
+Used with a register branch format instruction to indicate that the
+literal is the call to @code{__tls_get_addr} used to compute the
+address of the base of the thread-local storage block for the current
+module. The descriptor for the module must have been loaded with
+@code{!tlsldm!@var{N}}.
+
+@item !gpdisp!@var{N}
+Used with @code{ldah} and @code{lda} to load the GP from the current
+address, a-la the @code{ldgp} macro. The source register for the
+@code{ldah} instruction must contain the address of the @code{ldah}
+instruction. There must be exactly one @code{lda} instruction paired
+with the @code{ldah} instruction, though it may appear anywhere in
+the instruction stream. The immediate operands must be zero.
+
+@example
+bsr $26,foo
+ldah $29,0($26) !gpdisp!1
+lda $29,0($29) !gpdisp!1
+@end example
+
+@item !gprelhigh
+Used with an @code{ldah} instruction to add the high 16 bits of a
+32-bit displacement from the GP.
+
+@item !gprellow
+Used with any memory format instruction to add the low 16 bits of a
+32-bit displacement from the GP.
+
+@item !gprel
+Used with any memory format instruction to add a 16-bit displacement
+from the GP.
+
+@item !samegp
+Used with any branch format instruction to skip the GP load at the
+target address. The referenced symbol must have the same GP as the
+source object file, and it must be declared to either not use @code{$27}
+or perform a standard GP load in the first two instructions via the
+@code{.prologue} directive.
+
+@item !tlsgd
+@itemx !tlsgd!@var{N}
+Used with an @code{lda} instruction to load the address of a TLS
+descriptor for a symbol in the GOT.
+
+The sequence number @var{N} is optional, and if present it used to
+pair the descriptor load with both the @code{literal} loading the
+address of the @code{__tls_get_addr} function and the @code{lituse_tlsgd}
+marking the call to that function.
+
+For proper relaxation, both the @code{tlsgd}, @code{literal} and
+@code{lituse} relocations must be in the same extended basic block.
+That is, the relocation with the lowest address must be executed
+first at runtime.
+
+@item !tlsldm
+@itemx !tlsldm!@var{N}
+Used with an @code{lda} instruction to load the address of a TLS
+descriptor for the current module in the GOT.
+
+Similar in other respects to @code{tlsgd}.
+
+@item !gotdtprel
+Used with an @code{ldq} instruction to load the offset of the TLS
+symbol within its module's thread-local storage block. Also known
+as the dynamic thread pointer offset or dtp-relative offset.
+
+@item !dtprelhi
+@itemx !dtprello
+@itemx !dtprel
+Like @code{gprel} relocations except they compute dtp-relative offsets.
+
+@item !gottprel
+Used with an @code{ldq} instruction to load the offset of the TLS
+symbol from the thread pointer. Also known as the tp-relative offset.
+
+@item !tprelhi
+@itemx !tprello
+@itemx !tprel
+Like @code{gprel} relocations except they compute tp-relative offsets.
+@end table
+
+@node Alpha Floating Point
+@section Floating Point
+@cindex floating point, Alpha (@sc{ieee})
+@cindex Alpha floating point (@sc{ieee})
+The Alpha family uses both @sc{ieee} and VAX floating-point numbers.
+
+@node Alpha Directives
+@section Alpha Assembler Directives
+
+@command{@value{AS}} for the Alpha supports many additional directives for
+compatibility with the native assembler. This section describes them only
+briefly.
+
+@cindex Alpha-only directives
+These are the additional directives in @code{@value{AS}} for the Alpha:
+
+@table @code
+@item .arch @var{cpu}
+Specifies the target processor. This is equivalent to the
+@option{-m@var{cpu}} command-line option. @xref{Alpha Options, Options},
+for a list of values for @var{cpu}.
+
+@item .ent @var{function}[, @var{n}]
+Mark the beginning of @var{function}. An optional number may follow for
+compatibility with the OSF/1 assembler, but is ignored. When generating
+@code{.mdebug} information, this will create a procedure descriptor for
+the function. In ELF, it will mark the symbol as a function a-la the
+generic @code{.type} directive.
+
+@item .end @var{function}
+Mark the end of @var{function}. In ELF, it will set the size of the symbol
+a-la the generic @code{.size} directive.
+
+@item .mask @var{mask}, @var{offset}
+Indicate which of the integer registers are saved in the current
+function's stack frame. @var{mask} is interpreted a bit mask in which
+bit @var{n} set indicates that register @var{n} is saved. The registers
+are saved in a block located @var{offset} bytes from the @dfn{canonical
+frame address} (CFA) which is the value of the stack pointer on entry to
+the function. The registers are saved sequentially, except that the
+return address register (normally @code{$26}) is saved first.
+
+This and the other directives that describe the stack frame are
+currently only used when generating @code{.mdebug} information. They
+may in the future be used to generate DWARF2 @code{.debug_frame} unwind
+information for hand written assembly.
+
+@item .fmask @var{mask}, @var{offset}
+Indicate which of the floating-point registers are saved in the current
+stack frame. The @var{mask} and @var{offset} parameters are interpreted
+as with @code{.mask}.
+
+@item .frame @var{framereg}, @var{frameoffset}, @var{retreg}[, @var{argoffset}]
+Describes the shape of the stack frame. The frame pointer in use is
+@var{framereg}; normally this is either @code{$fp} or @code{$sp}. The
+frame pointer is @var{frameoffset} bytes below the CFA. The return
+address is initially located in @var{retreg} until it is saved as
+indicated in @code{.mask}. For compatibility with OSF/1 an optional
+@var{argoffset} parameter is accepted and ignored. It is believed to
+indicate the offset from the CFA to the saved argument registers.
+
+@item .prologue @var{n}
+Indicate that the stack frame is set up and all registers have been
+spilled. The argument @var{n} indicates whether and how the function
+uses the incoming @dfn{procedure vector} (the address of the called
+function) in @code{$27}. 0 indicates that @code{$27} is not used; 1
+indicates that the first two instructions of the function use @code{$27}
+to perform a load of the GP register; 2 indicates that @code{$27} is
+used in some non-standard way and so the linker cannot elide the load of
+the procedure vector during relaxation.
+
+@item .usepv @var{function}, @var{which}
+Used to indicate the use of the @code{$27} register, similar to
+@code{.prologue}, but without the other semantics of needing to
+be inside an open @code{.ent}/@code{.end} block.
+
+The @var{which} argument should be either @code{no}, indicating that
+@code{$27} is not used, or @code{std}, indicating that the first two
+instructions of the function perform a GP load.
+
+One might use this directive instead of @code{.prologue} if you are
+also using dwarf2 CFI directives.
+
+@item .gprel32 @var{expression}
+Computes the difference between the address in @var{expression} and the
+GP for the current object file, and stores it in 4 bytes. In addition
+to being smaller than a full 8 byte address, this also does not require
+a dynamic relocation when used in a shared library.
+
+@item .t_floating @var{expression}
+Stores @var{expression} as an @sc{ieee} double precision value.
+
+@item .s_floating @var{expression}
+Stores @var{expression} as an @sc{ieee} single precision value.
+
+@item .f_floating @var{expression}
+Stores @var{expression} as a VAX F format value.
+
+@item .g_floating @var{expression}
+Stores @var{expression} as a VAX G format value.
+
+@item .d_floating @var{expression}
+Stores @var{expression} as a VAX D format value.
+
+@item .set @var{feature}
+Enables or disables various assembler features. Using the positive
+name of the feature enables while using @samp{no@var{feature}} disables.
+
+@table @code
+@item at
+Indicates that macro expansions may clobber the @dfn{assembler
+temporary} (@code{$at} or @code{$28}) register. Some macros may not be
+expanded without this and will generate an error message if @code{noat}
+is in effect. When @code{at} is in effect, a warning will be generated
+if @code{$at} is used by the programmer.
+
+@item macro
+Enables the expansion of macro instructions. Note that variants of real
+instructions, such as @code{br label} vs @code{br $31,label} are
+considered alternate forms and not macros.
+
+@item move
+@itemx reorder
+@itemx volatile
+These control whether and how the assembler may re-order instructions.
+Accepted for compatibility with the OSF/1 assembler, but @command{@value{AS}}
+does not do instruction scheduling, so these features are ignored.
+@end table
+@end table
+
+The following directives are recognized for compatibility with the OSF/1
+assembler but are ignored.
+
+@example
+.proc .aproc
+.reguse .livereg
+.option .aent
+.ugen .eflag
+.alias .noalias
+@end example
+
+@node Alpha Opcodes
+@section Opcodes
+For detailed information on the Alpha machine instruction set, see the
+@c Attempt to work around a very overfull hbox.
+@iftex
+Alpha Architecture Handbook located at
+@smallfonts
+@example
+ftp://ftp.digital.com/pub/Digital/info/semiconductor/literature/alphaahb.pdf
+@end example
+@textfonts
+@end iftex
+@ifnottex
+@uref{ftp://ftp.digital.com/pub/Digital/info/semiconductor/literature/alphaahb.pdf,Alpha Architecture Handbook}.
+@end ifnottex
diff --git a/x/binutils/gas/doc/c-arc.texi b/x/binutils/gas/doc/c-arc.texi
new file mode 100644
index 0000000..700a01d
--- /dev/null
+++ b/x/binutils/gas/doc/c-arc.texi
@@ -0,0 +1,207 @@
+@c Copyright 2000, 2001 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+
+@ifset GENERIC
+@page
+@node ARC-Dependent
+@chapter ARC Dependent Features
+@end ifset
+
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter ARC Dependent Features
+@end ifclear
+
+@set ARC_CORE_DEFAULT 6
+
+@cindex ARC support
+@menu
+* ARC Options:: Options
+* ARC Syntax:: Syntax
+* ARC Floating Point:: Floating Point
+* ARC Directives:: ARC Machine Directives
+* ARC Opcodes:: Opcodes
+@end menu
+
+
+@node ARC Options
+@section Options
+@cindex ARC options (none)
+@cindex options for ARC (none)
+
+@table @code
+
+@cindex @code{-marc[5|6|7|8]} command line option, ARC
+@item -marc[5|6|7|8]
+This option selects the core processor variant. Using
+@code{-marc} is the same as @code{-marc@value{ARC_CORE_DEFAULT}}, which
+is also the default.
+
+@table @code
+
+@cindex @code{arc5} arc5, ARC
+@item arc5
+Base instruction set.
+
+@cindex @code{arc6} arc6, ARC
+@item arc6
+Jump-and-link (jl) instruction. No requirement of an instruction between
+setting flags and conditional jump. For example:
+
+@smallexample
+ mov.f r0,r1
+ beq foo
+@end smallexample
+
+@cindex @code{arc7} arc7, ARC
+@item arc7
+Break (brk) and sleep (sleep) instructions.
+
+@cindex @code{arc8} arc8, ARC
+@item arc8
+Software interrupt (swi) instruction.
+
+@end table
+
+Note: the @code{.option} directive can to be used to select a core
+variant from within assembly code.
+
+@cindex @code{-EB} command line option, ARC
+@item -EB
+This option specifies that the output generated by the assembler should
+be marked as being encoded for a big-endian processor.
+
+@cindex @code{-EL} command line option, ARC
+@item -EL
+This option specifies that the output generated by the assembler should
+be marked as being encoded for a little-endian processor - this is the
+default.
+
+@end table
+
+
+@node ARC Syntax
+@section Syntax
+@menu
+* ARC-Chars:: Special Characters
+* ARC-Regs:: Register Names
+@end menu
+
+@node ARC-Chars
+@subsection Special Characters
+
+@cindex ARC special characters
+@cindex special characters, ARC
+*TODO*
+
+@node ARC-Regs
+@subsection Register Names
+
+@cindex ARC register names
+@cindex register names, ARC
+*TODO*
+
+
+@node ARC Floating Point
+@section Floating Point
+
+@cindex floating point, ARC (@sc{ieee})
+@cindex ARC floating point (@sc{ieee})
+The ARC core does not currently have hardware floating point
+support. Software floating point support is provided by @code{GCC}
+and uses @sc{ieee} floating-point numbers.
+
+
+@node ARC Directives
+@section ARC Machine Directives
+
+@cindex machine directives, ARC
+@cindex ARC machine directives
+The ARC version of @code{@value{AS}} supports the following additional
+machine directives:
+
+@table @code
+
+@cindex @code{2byte} directive, ARC
+@item .2byte @var{expressions}
+*TODO*
+
+@cindex @code{3byte} directive, ARC
+@item .3byte @var{expressions}
+*TODO*
+
+@cindex @code{4byte} directive, ARC
+@item .4byte @var{expressions}
+*TODO*
+
+@cindex @code{extAuxRegister} directive, ARC
+@item .extAuxRegister @var{name},@var{address},@var{mode}
+*TODO*
+
+@smallexample
+ .extAuxRegister mulhi,0x12,w
+@end smallexample
+
+@cindex @code{extCondCode} directive, ARC
+@item .extCondCode @var{suffix},@var{value}
+*TODO*
+
+@smallexample
+ .extCondCode is_busy,0x14
+@end smallexample
+
+@cindex @code{extCoreRegister} directive, ARC
+@item .extCoreRegister @var{name},@var{regnum},@var{mode},@var{shortcut}
+*TODO*
+
+@smallexample
+ .extCoreRegister mlo,57,r,can_shortcut
+@end smallexample
+
+@cindex @code{extInstruction} directive, ARC
+@item .extInstruction @var{name},@var{opcode},@var{subopcode},@var{suffixclass},@var{syntaxclass}
+*TODO*
+
+@smallexample
+ .extInstruction mul64,0x14,0x0,SUFFIX_COND,SYNTAX_3OP|OP1_MUST_BE_IMM
+@end smallexample
+
+@cindex @code{half} directive, ARC
+@item .half @var{expressions}
+*TODO*
+
+@cindex @code{long} directive, ARC
+@item .long @var{expressions}
+*TODO*
+
+@cindex @code{option} directive, ARC
+@item .option @var{arc|arc5|arc6|arc7|arc8}
+The @code{.option} directive must be followed by the desired core
+version. Again @code{arc} is an alias for
+@code{arc@value{ARC_CORE_DEFAULT}}.
+
+Note: the @code{.option} directive overrides the command line option
+@code{-marc}; a warning is emitted when the version is not consistent
+between the two - even for the implicit default core version
+(arc@value{ARC_CORE_DEFAULT}).
+
+@cindex @code{short} directive, ARC
+@item .short @var{expressions}
+*TODO*
+
+@cindex @code{word} directive, ARC
+@item .word @var{expressions}
+*TODO*
+
+@end table
+
+
+@node ARC Opcodes
+@section Opcodes
+
+@cindex ARC opcodes
+@cindex opcodes for ARC
+
+For information on the ARC instruction set, see @cite{ARC Programmers
+Reference Manual}, ARC Cores Ltd.
diff --git a/x/binutils/gas/doc/c-arm.texi b/x/binutils/gas/doc/c-arm.texi
new file mode 100644
index 0000000..23cd7bb
--- /dev/null
+++ b/x/binutils/gas/doc/c-arm.texi
@@ -0,0 +1,490 @@
+@c Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003
+@c Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+
+@ifset GENERIC
+@page
+@node ARM-Dependent
+@chapter ARM Dependent Features
+@end ifset
+
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter ARM Dependent Features
+@end ifclear
+
+@cindex ARM support
+@cindex Thumb support
+@menu
+* ARM Options:: Options
+* ARM Syntax:: Syntax
+* ARM Floating Point:: Floating Point
+* ARM Directives:: ARM Machine Directives
+* ARM Opcodes:: Opcodes
+* ARM Mapping Symbols:: Mapping Symbols
+@end menu
+
+@node ARM Options
+@section Options
+@cindex ARM options (none)
+@cindex options for ARM (none)
+
+@table @code
+
+@cindex @code{-mcpu=} command line option, ARM
+@item -mcpu=@var{processor}[+@var{extension}@dots{}]
+This option specifies the target processor. The assembler will issue an
+error message if an attempt is made to assemble an instruction which
+will not execute on the target processor. The following processor names are
+recognized:
+@code{arm1},
+@code{arm2},
+@code{arm250},
+@code{arm3},
+@code{arm6},
+@code{arm60},
+@code{arm600},
+@code{arm610},
+@code{arm620},
+@code{arm7},
+@code{arm7m},
+@code{arm7d},
+@code{arm7dm},
+@code{arm7di},
+@code{arm7dmi},
+@code{arm70},
+@code{arm700},
+@code{arm700i},
+@code{arm710},
+@code{arm710t},
+@code{arm720},
+@code{arm720t},
+@code{arm740t},
+@code{arm710c},
+@code{arm7100},
+@code{arm7500},
+@code{arm7500fe},
+@code{arm7t},
+@code{arm7tdmi},
+@code{arm8},
+@code{arm810},
+@code{strongarm},
+@code{strongarm1},
+@code{strongarm110},
+@code{strongarm1100},
+@code{strongarm1110},
+@code{arm9},
+@code{arm920},
+@code{arm920t},
+@code{arm922t},
+@code{arm940t},
+@code{arm9tdmi},
+@code{arm9e},
+@code{arm926e},
+@code{arm926ejs},
+@code{arm946e-r0},
+@code{arm946e},
+@code{arm966e-r0},
+@code{arm966e},
+@code{arm10t},
+@code{arm10e},
+@code{arm1020},
+@code{arm1020t},
+@code{arm1020e},
+@code{arm1026ejs},
+@code{arm1136js},
+@code{arm1136jfs},
+@code{ep9312} (ARM920 with Cirrus Maverick coprocessor),
+@code{i80200} (Intel XScale processor)
+@code{iwmmxt} (Intel(r) XScale processor with Wireless MMX(tm) technology coprocessor)
+and
+@code{xscale}.
+The special name @code{all} may be used to allow the
+assembler to accept instructions valid for any ARM processor.
+
+In addition to the basic instruction set, the assembler can be told to
+accept various extension mnemonics that extend the processor using the
+co-processor instruction space. For example, @code{-mcpu=arm920+maverick}
+is equivalent to specifying @code{-mcpu=ep9312}. The following extensions
+are currently supported:
+@code{+maverick}
+@code{+iwmmxt}
+and
+@code{+xscale}.
+
+@cindex @code{-march=} command line option, ARM
+@item -march=@var{architecture}[+@var{extension}@dots{}]
+This option specifies the target architecture. The assembler will issue
+an error message if an attempt is made to assemble an instruction which
+will not execute on the target architecture. The following architecture
+names are recognized:
+@code{armv1},
+@code{armv2},
+@code{armv2a},
+@code{armv2s},
+@code{armv3},
+@code{armv3m},
+@code{armv4},
+@code{armv4xm},
+@code{armv4t},
+@code{armv4txm},
+@code{armv5},
+@code{armv5t},
+@code{armv5txm},
+@code{armv5te},
+@code{armv5texp},
+@code{armv6},
+@code{armv6j},
+@code{iwmmxt}
+and
+@code{xscale}.
+If both @code{-mcpu} and
+@code{-march} are specified, the assembler will use
+the setting for @code{-mcpu}.
+
+The architecture option can be extended with the same instruction set
+extension options as the @code{-mcpu} option.
+
+@cindex @code{-mfpu=} command line option, ARM
+@item -mfpu=@var{floating-point-format}
+
+This option specifies the floating point format to assemble for. The
+assembler will issue an error message if an attempt is made to assemble
+an instruction which will not execute on the target floating point unit.
+The following format options are recognized:
+@code{softfpa},
+@code{fpe},
+@code{fpe2},
+@code{fpe3},
+@code{fpa},
+@code{fpa10},
+@code{fpa11},
+@code{arm7500fe},
+@code{softvfp},
+@code{softvfp+vfp},
+@code{vfp},
+@code{vfp10},
+@code{vfp10-r0},
+@code{vfp9},
+@code{vfpxd},
+@code{arm1020t},
+@code{arm1020e},
+@code{arm1136jfs}
+and
+@code{maverick}.
+
+In addition to determining which instructions are assembled, this option
+also affects the way in which the @code{.double} assembler directive behaves
+when assembling little-endian code.
+
+The default is dependent on the processor selected. For Architecture 5 or
+later, the default is to assembler for VFP instructions; for earlier
+architectures the default is to assemble for FPA instructions.
+
+@cindex @code{-mthumb} command line option, ARM
+@item -mthumb
+This option specifies that the assembler should start assembling Thumb
+instructions; that is, it should behave as though the file starts with a
+@code{.code 16} directive.
+
+@cindex @code{-mthumb-interwork} command line option, ARM
+@item -mthumb-interwork
+This option specifies that the output generated by the assembler should
+be marked as supporting interworking.
+
+@cindex @code{-mapcs} command line option, ARM
+@item -mapcs @code{[26|32]}
+This option specifies that the output generated by the assembler should
+be marked as supporting the indicated version of the Arm Procedure.
+Calling Standard.
+
+@cindex @code{-matpcs} command line option, ARM
+@item -matpcs
+This option specifies that the output generated by the assembler should
+be marked as supporting the Arm/Thumb Procedure Calling Standard. If
+enabled this option will cause the assembler to create an empty
+debugging section in the object file called .arm.atpcs. Debuggers can
+use this to determine the ABI being used by.
+
+@cindex @code{-mapcs-float} command line option, ARM
+@item -mapcs-float
+This indicates the floating point variant of the APCS should be
+used. In this variant floating point arguments are passed in FP
+registers rather than integer registers.
+
+@cindex @code{-mapcs-reentrant} command line option, ARM
+@item -mapcs-reentrant
+This indicates that the reentrant variant of the APCS should be used.
+This variant supports position independent code.
+
+@cindex @code{-mfloat-abi=} command line option, ARM
+@item -mfloat-abi=@var{abi}
+This option specifies that the output generated by the assembler should be
+marked as using specified floating point ABI.
+The following values are recognized:
+@code{soft},
+@code{softfp}
+and
+@code{hard}.
+
+@cindex @code{-EB} command line option, ARM
+@item -EB
+This option specifies that the output generated by the assembler should
+be marked as being encoded for a big-endian processor.
+
+@cindex @code{-EL} command line option, ARM
+@item -EL
+This option specifies that the output generated by the assembler should
+be marked as being encoded for a little-endian processor.
+
+@cindex @code{-k} command line option, ARM
+@cindex PIC code generation for ARM
+@item -k
+This option specifies that the output of the assembler should be marked
+as position-independent code (PIC).
+
+@cindex @code{-moabi} command line option, ARM
+@item -moabi
+This indicates that the code should be assembled using the old ARM ELF
+conventions, based on a beta release release of the ARM-ELF
+specifications, rather than the default conventions which are based on
+the final release of the ARM-ELF specifications.
+
+@end table
+
+
+@node ARM Syntax
+@section Syntax
+@menu
+* ARM-Chars:: Special Characters
+* ARM-Regs:: Register Names
+@end menu
+
+@node ARM-Chars
+@subsection Special Characters
+
+@cindex line comment character, ARM
+@cindex ARM line comment character
+The presence of a @samp{@@} on a line indicates the start of a comment
+that extends to the end of the current line. If a @samp{#} appears as
+the first character of a line, the whole line is treated as a comment.
+
+@cindex line separator, ARM
+@cindex statement separator, ARM
+@cindex ARM line separator
+The @samp{;} character can be used instead of a newline to separate
+statements.
+
+@cindex immediate character, ARM
+@cindex ARM immediate character
+Either @samp{#} or @samp{$} can be used to indicate immediate operands.
+
+@cindex identifiers, ARM
+@cindex ARM identifiers
+*TODO* Explain about /data modifier on symbols.
+
+@node ARM-Regs
+@subsection Register Names
+
+@cindex ARM register names
+@cindex register names, ARM
+*TODO* Explain about ARM register naming, and the predefined names.
+
+@node ARM Floating Point
+@section Floating Point
+
+@cindex floating point, ARM (@sc{ieee})
+@cindex ARM floating point (@sc{ieee})
+The ARM family uses @sc{ieee} floating-point numbers.
+
+
+
+@node ARM Directives
+@section ARM Machine Directives
+
+@cindex machine directives, ARM
+@cindex ARM machine directives
+@table @code
+
+@cindex @code{align} directive, ARM
+@item .align @var{expression} [, @var{expression}]
+This is the generic @var{.align} directive. For the ARM however if the
+first argument is zero (ie no alignment is needed) the assembler will
+behave as if the argument had been 2 (ie pad to the next four byte
+boundary). This is for compatibility with ARM's own assembler.
+
+@cindex @code{req} directive, ARM
+@item @var{name} .req @var{register name}
+This creates an alias for @var{register name} called @var{name}. For
+example:
+
+@smallexample
+ foo .req r0
+@end smallexample
+
+@cindex @code{unreq} directive, ARM
+@item .unreq @var{alias-name}
+This undefines a register alias which was previously defined using the
+@code{req} directive. For example:
+
+@smallexample
+ foo .req r0
+ .unreq foo
+@end smallexample
+
+An error occurs if the name is undefined. Note - this pseudo op can
+be used to delete builtin in register name aliases (eg 'r0'). This
+should only be done if it is really necessary.
+
+@cindex @code{code} directive, ARM
+@item .code @code{[16|32]}
+This directive selects the instruction set being generated. The value 16
+selects Thumb, with the value 32 selecting ARM.
+
+@cindex @code{thumb} directive, ARM
+@item .thumb
+This performs the same action as @var{.code 16}.
+
+@cindex @code{arm} directive, ARM
+@item .arm
+This performs the same action as @var{.code 32}.
+
+@cindex @code{force_thumb} directive, ARM
+@item .force_thumb
+This directive forces the selection of Thumb instructions, even if the
+target processor does not support those instructions
+
+@cindex @code{thumb_func} directive, ARM
+@item .thumb_func
+This directive specifies that the following symbol is the name of a
+Thumb encoded function. This information is necessary in order to allow
+the assembler and linker to generate correct code for interworking
+between Arm and Thumb instructions and should be used even if
+interworking is not going to be performed. The presence of this
+directive also implies @code{.thumb}
+
+@cindex @code{thumb_set} directive, ARM
+@item .thumb_set
+This performs the equivalent of a @code{.set} directive in that it
+creates a symbol which is an alias for another symbol (possibly not yet
+defined). This directive also has the added property in that it marks
+the aliased symbol as being a thumb function entry point, in the same
+way that the @code{.thumb_func} directive does.
+
+@cindex @code{.ltorg} directive, ARM
+@item .ltorg
+This directive causes the current contents of the literal pool to be
+dumped into the current section (which is assumed to be the .text
+section) at the current location (aligned to a word boundary).
+@code{GAS} maintains a separate literal pool for each section and each
+sub-section. The @code{.ltorg} directive will only affect the literal
+pool of the current section and sub-section. At the end of assembly
+all remaining, un-empty literal pools will automatically be dumped.
+
+Note - older versions of @code{GAS} would dump the current literal
+pool any time a section change occurred. This is no longer done, since
+it prevents accurate control of the placement of literal pools.
+
+@cindex @code{.pool} directive, ARM
+@item .pool
+This is a synonym for .ltorg.
+
+@end table
+
+@node ARM Opcodes
+@section Opcodes
+
+@cindex ARM opcodes
+@cindex opcodes for ARM
+@code{@value{AS}} implements all the standard ARM opcodes. It also
+implements several pseudo opcodes, including several synthetic load
+instructions.
+
+@table @code
+
+@cindex @code{NOP} pseudo op, ARM
+@item NOP
+@smallexample
+ nop
+@end smallexample
+
+This pseudo op will always evaluate to a legal ARM instruction that does
+nothing. Currently it will evaluate to MOV r0, r0.
+
+@cindex @code{LDR reg,=<label>} pseudo op, ARM
+@item LDR
+@smallexample
+ ldr <register> , = <expression>
+@end smallexample
+
+If expression evaluates to a numeric constant then a MOV or MVN
+instruction will be used in place of the LDR instruction, if the
+constant can be generated by either of these instructions. Otherwise
+the constant will be placed into the nearest literal pool (if it not
+already there) and a PC relative LDR instruction will be generated.
+
+@cindex @code{ADR reg,<label>} pseudo op, ARM
+@item ADR
+@smallexample
+ adr <register> <label>
+@end smallexample
+
+This instruction will load the address of @var{label} into the indicated
+register. The instruction will evaluate to a PC relative ADD or SUB
+instruction depending upon where the label is located. If the label is
+out of range, or if it is not defined in the same file (and section) as
+the ADR instruction, then an error will be generated. This instruction
+will not make use of the literal pool.
+
+@cindex @code{ADRL reg,<label>} pseudo op, ARM
+@item ADRL
+@smallexample
+ adrl <register> <label>
+@end smallexample
+
+This instruction will load the address of @var{label} into the indicated
+register. The instruction will evaluate to one or two PC relative ADD
+or SUB instructions depending upon where the label is located. If a
+second instruction is not needed a NOP instruction will be generated in
+its place, so that this instruction is always 8 bytes long.
+
+If the label is out of range, or if it is not defined in the same file
+(and section) as the ADRL instruction, then an error will be generated.
+This instruction will not make use of the literal pool.
+
+@end table
+
+For information on the ARM or Thumb instruction sets, see @cite{ARM
+Software Development Toolkit Reference Manual}, Advanced RISC Machines
+Ltd.
+
+@node ARM Mapping Symbols
+@section Mapping Symbols
+
+The ARM ELF specification requires that special symbols be inserted
+into object files to mark certain features:
+
+@table @code
+
+@cindex @code{$a}
+@item $a
+At the start of a region of code containing ARM instructions.
+
+@cindex @code{$t}
+@item $t
+At the start of a region of code containing THUMB instructions.
+
+@cindex @code{$d}
+@item $d
+At the start of a region of data.
+
+@end table
+
+The assembler will automatically insert these symbols for you - there
+is no need to code them yourself. Support for tagging symbols ($b,
+$f, $p and $m) which is also mentioned in the current ARM ELF
+specification is not implemented. This is because they have been
+dropped from the new EABI and so tools cannot rely upon their
+presence.
+
diff --git a/x/binutils/gas/doc/c-i386.texi b/x/binutils/gas/doc/c-i386.texi
new file mode 100644
index 0000000..f0047f9
--- /dev/null
+++ b/x/binutils/gas/doc/c-i386.texi
@@ -0,0 +1,755 @@
+@c Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001
+@c Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node i386-Dependent
+@chapter 80386 Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter 80386 Dependent Features
+@end ifclear
+
+@cindex i386 support
+@cindex i80306 support
+@cindex x86-64 support
+
+The i386 version @code{@value{AS}} supports both the original Intel 386
+architecture in both 16 and 32-bit mode as well as AMD x86-64 architecture
+extending the Intel architecture to 64-bits.
+
+@menu
+* i386-Options:: Options
+* i386-Syntax:: AT&T Syntax versus Intel Syntax
+* i386-Mnemonics:: Instruction Naming
+* i386-Regs:: Register Naming
+* i386-Prefixes:: Instruction Prefixes
+* i386-Memory:: Memory References
+* i386-Jumps:: Handling of Jump Instructions
+* i386-Float:: Floating Point
+* i386-SIMD:: Intel's MMX and AMD's 3DNow! SIMD Operations
+* i386-16bit:: Writing 16-bit Code
+* i386-Arch:: Specifying an x86 CPU architecture
+* i386-Bugs:: AT&T Syntax bugs
+* i386-Notes:: Notes
+@end menu
+
+@node i386-Options
+@section Options
+
+@cindex options for i386
+@cindex options for x86-64
+@cindex i386 options
+@cindex x86-64 options
+
+The i386 version of @code{@value{AS}} has a few machine
+dependent options:
+
+@table @code
+@cindex @samp{--32} option, i386
+@cindex @samp{--32} option, x86-64
+@cindex @samp{--64} option, i386
+@cindex @samp{--64} option, x86-64
+@item --32 | --64
+Select the word size, either 32 bits or 64 bits. Selecting 32-bit
+implies Intel i386 architecture, while 64-bit implies AMD x86-64
+architecture.
+
+These options are only available with the ELF object file format, and
+require that the necessary BFD support has been included (on a 32-bit
+platform you have to add --enable-64-bit-bfd to configure enable 64-bit
+usage and use x86-64 as target platform).
+
+@item -n
+By default, x86 GAS replaces multiple nop instructions used for
+alignment within code sections with multi-byte nop instructions such
+as leal 0(%esi,1),%esi. This switch disables the optimization.
+@end table
+
+@node i386-Syntax
+@section AT&T Syntax versus Intel Syntax
+
+@cindex i386 intel_syntax pseudo op
+@cindex intel_syntax pseudo op, i386
+@cindex i386 att_syntax pseudo op
+@cindex att_syntax pseudo op, i386
+@cindex i386 syntax compatibility
+@cindex syntax compatibility, i386
+@cindex x86-64 intel_syntax pseudo op
+@cindex intel_syntax pseudo op, x86-64
+@cindex x86-64 att_syntax pseudo op
+@cindex att_syntax pseudo op, x86-64
+@cindex x86-64 syntax compatibility
+@cindex syntax compatibility, x86-64
+
+@code{@value{AS}} now supports assembly using Intel assembler syntax.
+@code{.intel_syntax} selects Intel mode, and @code{.att_syntax} switches
+back to the usual AT&T mode for compatibility with the output of
+@code{@value{GCC}}. Either of these directives may have an optional
+argument, @code{prefix}, or @code{noprefix} specifying whether registers
+require a @samp{%} prefix. AT&T System V/386 assembler syntax is quite
+different from Intel syntax. We mention these differences because
+almost all 80386 documents use Intel syntax. Notable differences
+between the two syntaxes are:
+
+@cindex immediate operands, i386
+@cindex i386 immediate operands
+@cindex register operands, i386
+@cindex i386 register operands
+@cindex jump/call operands, i386
+@cindex i386 jump/call operands
+@cindex operand delimiters, i386
+
+@cindex immediate operands, x86-64
+@cindex x86-64 immediate operands
+@cindex register operands, x86-64
+@cindex x86-64 register operands
+@cindex jump/call operands, x86-64
+@cindex x86-64 jump/call operands
+@cindex operand delimiters, x86-64
+@itemize @bullet
+@item
+AT&T immediate operands are preceded by @samp{$}; Intel immediate
+operands are undelimited (Intel @samp{push 4} is AT&T @samp{pushl $4}).
+AT&T register operands are preceded by @samp{%}; Intel register operands
+are undelimited. AT&T absolute (as opposed to PC relative) jump/call
+operands are prefixed by @samp{*}; they are undelimited in Intel syntax.
+
+@cindex i386 source, destination operands
+@cindex source, destination operands; i386
+@cindex x86-64 source, destination operands
+@cindex source, destination operands; x86-64
+@item
+AT&T and Intel syntax use the opposite order for source and destination
+operands. Intel @samp{add eax, 4} is @samp{addl $4, %eax}. The
+@samp{source, dest} convention is maintained for compatibility with
+previous Unix assemblers. Note that instructions with more than one
+source operand, such as the @samp{enter} instruction, do @emph{not} have
+reversed order. @ref{i386-Bugs}.
+
+@cindex mnemonic suffixes, i386
+@cindex sizes operands, i386
+@cindex i386 size suffixes
+@cindex mnemonic suffixes, x86-64
+@cindex sizes operands, x86-64
+@cindex x86-64 size suffixes
+@item
+In AT&T syntax the size of memory operands is determined from the last
+character of the instruction mnemonic. Mnemonic suffixes of @samp{b},
+@samp{w}, @samp{l} and @samp{q} specify byte (8-bit), word (16-bit), long
+(32-bit) and quadruple word (64-bit) memory references. Intel syntax accomplishes
+this by prefixing memory operands (@emph{not} the instruction mnemonics) with
+@samp{byte ptr}, @samp{word ptr}, @samp{dword ptr} and @samp{qword ptr}. Thus,
+Intel @samp{mov al, byte ptr @var{foo}} is @samp{movb @var{foo}, %al} in AT&T
+syntax.
+
+@cindex return instructions, i386
+@cindex i386 jump, call, return
+@cindex return instructions, x86-64
+@cindex x86-64 jump, call, return
+@item
+Immediate form long jumps and calls are
+@samp{lcall/ljmp $@var{section}, $@var{offset}} in AT&T syntax; the
+Intel syntax is
+@samp{call/jmp far @var{section}:@var{offset}}. Also, the far return
+instruction
+is @samp{lret $@var{stack-adjust}} in AT&T syntax; Intel syntax is
+@samp{ret far @var{stack-adjust}}.
+
+@cindex sections, i386
+@cindex i386 sections
+@cindex sections, x86-64
+@cindex x86-64 sections
+@item
+The AT&T assembler does not provide support for multiple section
+programs. Unix style systems expect all programs to be single sections.
+@end itemize
+
+@node i386-Mnemonics
+@section Instruction Naming
+
+@cindex i386 instruction naming
+@cindex instruction naming, i386
+@cindex x86-64 instruction naming
+@cindex instruction naming, x86-64
+
+Instruction mnemonics are suffixed with one character modifiers which
+specify the size of operands. The letters @samp{b}, @samp{w}, @samp{l}
+and @samp{q} specify byte, word, long and quadruple word operands. If
+no suffix is specified by an instruction then @code{@value{AS}} tries to
+fill in the missing suffix based on the destination register operand
+(the last one by convention). Thus, @samp{mov %ax, %bx} is equivalent
+to @samp{movw %ax, %bx}; also, @samp{mov $1, %bx} is equivalent to
+@samp{movw $1, bx}. Note that this is incompatible with the AT&T Unix
+assembler which assumes that a missing mnemonic suffix implies long
+operand size. (This incompatibility does not affect compiler output
+since compilers always explicitly specify the mnemonic suffix.)
+
+Almost all instructions have the same names in AT&T and Intel format.
+There are a few exceptions. The sign extend and zero extend
+instructions need two sizes to specify them. They need a size to
+sign/zero extend @emph{from} and a size to zero extend @emph{to}. This
+is accomplished by using two instruction mnemonic suffixes in AT&T
+syntax. Base names for sign extend and zero extend are
+@samp{movs@dots{}} and @samp{movz@dots{}} in AT&T syntax (@samp{movsx}
+and @samp{movzx} in Intel syntax). The instruction mnemonic suffixes
+are tacked on to this base name, the @emph{from} suffix before the
+@emph{to} suffix. Thus, @samp{movsbl %al, %edx} is AT&T syntax for
+``move sign extend @emph{from} %al @emph{to} %edx.'' Possible suffixes,
+thus, are @samp{bl} (from byte to long), @samp{bw} (from byte to word),
+@samp{wl} (from word to long), @samp{bq} (from byte to quadruple word),
+@samp{wq} (from word to quadruple word), and @samp{lq} (from long to
+quadruple word).
+
+@cindex conversion instructions, i386
+@cindex i386 conversion instructions
+@cindex conversion instructions, x86-64
+@cindex x86-64 conversion instructions
+The Intel-syntax conversion instructions
+
+@itemize @bullet
+@item
+@samp{cbw} --- sign-extend byte in @samp{%al} to word in @samp{%ax},
+
+@item
+@samp{cwde} --- sign-extend word in @samp{%ax} to long in @samp{%eax},
+
+@item
+@samp{cwd} --- sign-extend word in @samp{%ax} to long in @samp{%dx:%ax},
+
+@item
+@samp{cdq} --- sign-extend dword in @samp{%eax} to quad in @samp{%edx:%eax},
+
+@item
+@samp{cdqe} --- sign-extend dword in @samp{%eax} to quad in @samp{%rax}
+(x86-64 only),
+
+@item
+@samp{cdo} --- sign-extend quad in @samp{%rax} to octuple in
+@samp{%rdx:%rax} (x86-64 only),
+@end itemize
+
+@noindent
+are called @samp{cbtw}, @samp{cwtl}, @samp{cwtd}, @samp{cltd}, @samp{cltq}, and
+@samp{cqto} in AT&T naming. @code{@value{AS}} accepts either naming for these
+instructions.
+
+@cindex jump instructions, i386
+@cindex call instructions, i386
+@cindex jump instructions, x86-64
+@cindex call instructions, x86-64
+Far call/jump instructions are @samp{lcall} and @samp{ljmp} in
+AT&T syntax, but are @samp{call far} and @samp{jump far} in Intel
+convention.
+
+@node i386-Regs
+@section Register Naming
+
+@cindex i386 registers
+@cindex registers, i386
+@cindex x86-64 registers
+@cindex registers, x86-64
+Register operands are always prefixed with @samp{%}. The 80386 registers
+consist of
+
+@itemize @bullet
+@item
+the 8 32-bit registers @samp{%eax} (the accumulator), @samp{%ebx},
+@samp{%ecx}, @samp{%edx}, @samp{%edi}, @samp{%esi}, @samp{%ebp} (the
+frame pointer), and @samp{%esp} (the stack pointer).
+
+@item
+the 8 16-bit low-ends of these: @samp{%ax}, @samp{%bx}, @samp{%cx},
+@samp{%dx}, @samp{%di}, @samp{%si}, @samp{%bp}, and @samp{%sp}.
+
+@item
+the 8 8-bit registers: @samp{%ah}, @samp{%al}, @samp{%bh},
+@samp{%bl}, @samp{%ch}, @samp{%cl}, @samp{%dh}, and @samp{%dl} (These
+are the high-bytes and low-bytes of @samp{%ax}, @samp{%bx},
+@samp{%cx}, and @samp{%dx})
+
+@item
+the 6 section registers @samp{%cs} (code section), @samp{%ds}
+(data section), @samp{%ss} (stack section), @samp{%es}, @samp{%fs},
+and @samp{%gs}.
+
+@item
+the 3 processor control registers @samp{%cr0}, @samp{%cr2}, and
+@samp{%cr3}.
+
+@item
+the 6 debug registers @samp{%db0}, @samp{%db1}, @samp{%db2},
+@samp{%db3}, @samp{%db6}, and @samp{%db7}.
+
+@item
+the 2 test registers @samp{%tr6} and @samp{%tr7}.
+
+@item
+the 8 floating point register stack @samp{%st} or equivalently
+@samp{%st(0)}, @samp{%st(1)}, @samp{%st(2)}, @samp{%st(3)},
+@samp{%st(4)}, @samp{%st(5)}, @samp{%st(6)}, and @samp{%st(7)}.
+These registers are overloaded by 8 MMX registers @samp{%mm0},
+@samp{%mm1}, @samp{%mm2}, @samp{%mm3}, @samp{%mm4}, @samp{%mm5},
+@samp{%mm6} and @samp{%mm7}.
+
+@item
+the 8 SSE registers registers @samp{%xmm0}, @samp{%xmm1}, @samp{%xmm2},
+@samp{%xmm3}, @samp{%xmm4}, @samp{%xmm5}, @samp{%xmm6} and @samp{%xmm7}.
+@end itemize
+
+The AMD x86-64 architecture extends the register set by:
+
+@itemize @bullet
+@item
+enhancing the 8 32-bit registers to 64-bit: @samp{%rax} (the
+accumulator), @samp{%rbx}, @samp{%rcx}, @samp{%rdx}, @samp{%rdi},
+@samp{%rsi}, @samp{%rbp} (the frame pointer), @samp{%rsp} (the stack
+pointer)
+
+@item
+the 8 extended registers @samp{%r8}--@samp{%r15}.
+
+@item
+the 8 32-bit low ends of the extended registers: @samp{%r8d}--@samp{%r15d}
+
+@item
+the 8 16-bit low ends of the extended registers: @samp{%r8w}--@samp{%r15w}
+
+@item
+the 8 8-bit low ends of the extended registers: @samp{%r8b}--@samp{%r15b}
+
+@item
+the 4 8-bit registers: @samp{%sil}, @samp{%dil}, @samp{%bpl}, @samp{%spl}.
+
+@item
+the 8 debug registers: @samp{%db8}--@samp{%db15}.
+
+@item
+the 8 SSE registers: @samp{%xmm8}--@samp{%xmm15}.
+@end itemize
+
+@node i386-Prefixes
+@section Instruction Prefixes
+
+@cindex i386 instruction prefixes
+@cindex instruction prefixes, i386
+@cindex prefixes, i386
+Instruction prefixes are used to modify the following instruction. They
+are used to repeat string instructions, to provide section overrides, to
+perform bus lock operations, and to change operand and address sizes.
+(Most instructions that normally operate on 32-bit operands will use
+16-bit operands if the instruction has an ``operand size'' prefix.)
+Instruction prefixes are best written on the same line as the instruction
+they act upon. For example, the @samp{scas} (scan string) instruction is
+repeated with:
+
+@smallexample
+ repne scas %es:(%edi),%al
+@end smallexample
+
+You may also place prefixes on the lines immediately preceding the
+instruction, but this circumvents checks that @code{@value{AS}} does
+with prefixes, and will not work with all prefixes.
+
+Here is a list of instruction prefixes:
+
+@cindex section override prefixes, i386
+@itemize @bullet
+@item
+Section override prefixes @samp{cs}, @samp{ds}, @samp{ss}, @samp{es},
+@samp{fs}, @samp{gs}. These are automatically added by specifying
+using the @var{section}:@var{memory-operand} form for memory references.
+
+@cindex size prefixes, i386
+@item
+Operand/Address size prefixes @samp{data16} and @samp{addr16}
+change 32-bit operands/addresses into 16-bit operands/addresses,
+while @samp{data32} and @samp{addr32} change 16-bit ones (in a
+@code{.code16} section) into 32-bit operands/addresses. These prefixes
+@emph{must} appear on the same line of code as the instruction they
+modify. For example, in a 16-bit @code{.code16} section, you might
+write:
+
+@smallexample
+ addr32 jmpl *(%ebx)
+@end smallexample
+
+@cindex bus lock prefixes, i386
+@cindex inhibiting interrupts, i386
+@item
+The bus lock prefix @samp{lock} inhibits interrupts during execution of
+the instruction it precedes. (This is only valid with certain
+instructions; see a 80386 manual for details).
+
+@cindex coprocessor wait, i386
+@item
+The wait for coprocessor prefix @samp{wait} waits for the coprocessor to
+complete the current instruction. This should never be needed for the
+80386/80387 combination.
+
+@cindex repeat prefixes, i386
+@item
+The @samp{rep}, @samp{repe}, and @samp{repne} prefixes are added
+to string instructions to make them repeat @samp{%ecx} times (@samp{%cx}
+times if the current address size is 16-bits).
+@cindex REX prefixes, i386
+@item
+The @samp{rex} family of prefixes is used by x86-64 to encode
+extensions to i386 instruction set. The @samp{rex} prefix has four
+bits --- an operand size overwrite (@code{64}) used to change operand size
+from 32-bit to 64-bit and X, Y and Z extensions bits used to extend the
+register set.
+
+You may write the @samp{rex} prefixes directly. The @samp{rex64xyz}
+instruction emits @samp{rex} prefix with all the bits set. By omitting
+the @code{64}, @code{x}, @code{y} or @code{z} you may write other
+prefixes as well. Normally, there is no need to write the prefixes
+explicitly, since gas will automatically generate them based on the
+instruction operands.
+@end itemize
+
+@node i386-Memory
+@section Memory References
+
+@cindex i386 memory references
+@cindex memory references, i386
+@cindex x86-64 memory references
+@cindex memory references, x86-64
+An Intel syntax indirect memory reference of the form
+
+@smallexample
+@var{section}:[@var{base} + @var{index}*@var{scale} + @var{disp}]
+@end smallexample
+
+@noindent
+is translated into the AT&T syntax
+
+@smallexample
+@var{section}:@var{disp}(@var{base}, @var{index}, @var{scale})
+@end smallexample
+
+@noindent
+where @var{base} and @var{index} are the optional 32-bit base and
+index registers, @var{disp} is the optional displacement, and
+@var{scale}, taking the values 1, 2, 4, and 8, multiplies @var{index}
+to calculate the address of the operand. If no @var{scale} is
+specified, @var{scale} is taken to be 1. @var{section} specifies the
+optional section register for the memory operand, and may override the
+default section register (see a 80386 manual for section register
+defaults). Note that section overrides in AT&T syntax @emph{must}
+be preceded by a @samp{%}. If you specify a section override which
+coincides with the default section register, @code{@value{AS}} does @emph{not}
+output any section register override prefixes to assemble the given
+instruction. Thus, section overrides can be specified to emphasize which
+section register is used for a given memory operand.
+
+Here are some examples of Intel and AT&T style memory references:
+
+@table @asis
+@item AT&T: @samp{-4(%ebp)}, Intel: @samp{[ebp - 4]}
+@var{base} is @samp{%ebp}; @var{disp} is @samp{-4}. @var{section} is
+missing, and the default section is used (@samp{%ss} for addressing with
+@samp{%ebp} as the base register). @var{index}, @var{scale} are both missing.
+
+@item AT&T: @samp{foo(,%eax,4)}, Intel: @samp{[foo + eax*4]}
+@var{index} is @samp{%eax} (scaled by a @var{scale} 4); @var{disp} is
+@samp{foo}. All other fields are missing. The section register here
+defaults to @samp{%ds}.
+
+@item AT&T: @samp{foo(,1)}; Intel @samp{[foo]}
+This uses the value pointed to by @samp{foo} as a memory operand.
+Note that @var{base} and @var{index} are both missing, but there is only
+@emph{one} @samp{,}. This is a syntactic exception.
+
+@item AT&T: @samp{%gs:foo}; Intel @samp{gs:foo}
+This selects the contents of the variable @samp{foo} with section
+register @var{section} being @samp{%gs}.
+@end table
+
+Absolute (as opposed to PC relative) call and jump operands must be
+prefixed with @samp{*}. If no @samp{*} is specified, @code{@value{AS}}
+always chooses PC relative addressing for jump/call labels.
+
+Any instruction that has a memory operand, but no register operand,
+@emph{must} specify its size (byte, word, long, or quadruple) with an
+instruction mnemonic suffix (@samp{b}, @samp{w}, @samp{l} or @samp{q},
+respectively).
+
+The x86-64 architecture adds an RIP (instruction pointer relative)
+addressing. This addressing mode is specified by using @samp{rip} as a
+base register. Only constant offsets are valid. For example:
+
+@table @asis
+@item AT&T: @samp{1234(%rip)}, Intel: @samp{[rip + 1234]}
+Points to the address 1234 bytes past the end of the current
+instruction.
+
+@item AT&T: @samp{symbol(%rip)}, Intel: @samp{[rip + symbol]}
+Points to the @code{symbol} in RIP relative way, this is shorter than
+the default absolute addressing.
+@end table
+
+Other addressing modes remain unchanged in x86-64 architecture, except
+registers used are 64-bit instead of 32-bit.
+
+@node i386-Jumps
+@section Handling of Jump Instructions
+
+@cindex jump optimization, i386
+@cindex i386 jump optimization
+@cindex jump optimization, x86-64
+@cindex x86-64 jump optimization
+Jump instructions are always optimized to use the smallest possible
+displacements. This is accomplished by using byte (8-bit) displacement
+jumps whenever the target is sufficiently close. If a byte displacement
+is insufficient a long displacement is used. We do not support
+word (16-bit) displacement jumps in 32-bit mode (i.e. prefixing the jump
+instruction with the @samp{data16} instruction prefix), since the 80386
+insists upon masking @samp{%eip} to 16 bits after the word displacement
+is added. (See also @pxref{i386-Arch})
+
+Note that the @samp{jcxz}, @samp{jecxz}, @samp{loop}, @samp{loopz},
+@samp{loope}, @samp{loopnz} and @samp{loopne} instructions only come in byte
+displacements, so that if you use these instructions (@code{@value{GCC}} does
+not use them) you may get an error message (and incorrect code). The AT&T
+80386 assembler tries to get around this problem by expanding @samp{jcxz foo}
+to
+
+@smallexample
+ jcxz cx_zero
+ jmp cx_nonzero
+cx_zero: jmp foo
+cx_nonzero:
+@end smallexample
+
+@node i386-Float
+@section Floating Point
+
+@cindex i386 floating point
+@cindex floating point, i386
+@cindex x86-64 floating point
+@cindex floating point, x86-64
+All 80387 floating point types except packed BCD are supported.
+(BCD support may be added without much difficulty). These data
+types are 16-, 32-, and 64- bit integers, and single (32-bit),
+double (64-bit), and extended (80-bit) precision floating point.
+Each supported type has an instruction mnemonic suffix and a constructor
+associated with it. Instruction mnemonic suffixes specify the operand's
+data type. Constructors build these data types into memory.
+
+@cindex @code{float} directive, i386
+@cindex @code{single} directive, i386
+@cindex @code{double} directive, i386
+@cindex @code{tfloat} directive, i386
+@cindex @code{float} directive, x86-64
+@cindex @code{single} directive, x86-64
+@cindex @code{double} directive, x86-64
+@cindex @code{tfloat} directive, x86-64
+@itemize @bullet
+@item
+Floating point constructors are @samp{.float} or @samp{.single},
+@samp{.double}, and @samp{.tfloat} for 32-, 64-, and 80-bit formats.
+These correspond to instruction mnemonic suffixes @samp{s}, @samp{l},
+and @samp{t}. @samp{t} stands for 80-bit (ten byte) real. The 80387
+only supports this format via the @samp{fldt} (load 80-bit real to stack
+top) and @samp{fstpt} (store 80-bit real and pop stack) instructions.
+
+@cindex @code{word} directive, i386
+@cindex @code{long} directive, i386
+@cindex @code{int} directive, i386
+@cindex @code{quad} directive, i386
+@cindex @code{word} directive, x86-64
+@cindex @code{long} directive, x86-64
+@cindex @code{int} directive, x86-64
+@cindex @code{quad} directive, x86-64
+@item
+Integer constructors are @samp{.word}, @samp{.long} or @samp{.int}, and
+@samp{.quad} for the 16-, 32-, and 64-bit integer formats. The
+corresponding instruction mnemonic suffixes are @samp{s} (single),
+@samp{l} (long), and @samp{q} (quad). As with the 80-bit real format,
+the 64-bit @samp{q} format is only present in the @samp{fildq} (load
+quad integer to stack top) and @samp{fistpq} (store quad integer and pop
+stack) instructions.
+@end itemize
+
+Register to register operations should not use instruction mnemonic suffixes.
+@samp{fstl %st, %st(1)} will give a warning, and be assembled as if you
+wrote @samp{fst %st, %st(1)}, since all register to register operations
+use 80-bit floating point operands. (Contrast this with @samp{fstl %st, mem},
+which converts @samp{%st} from 80-bit to 64-bit floating point format,
+then stores the result in the 4 byte location @samp{mem})
+
+@node i386-SIMD
+@section Intel's MMX and AMD's 3DNow! SIMD Operations
+
+@cindex MMX, i386
+@cindex 3DNow!, i386
+@cindex SIMD, i386
+@cindex MMX, x86-64
+@cindex 3DNow!, x86-64
+@cindex SIMD, x86-64
+
+@code{@value{AS}} supports Intel's MMX instruction set (SIMD
+instructions for integer data), available on Intel's Pentium MMX
+processors and Pentium II processors, AMD's K6 and K6-2 processors,
+Cyrix' M2 processor, and probably others. It also supports AMD's 3DNow!
+instruction set (SIMD instructions for 32-bit floating point data)
+available on AMD's K6-2 processor and possibly others in the future.
+
+Currently, @code{@value{AS}} does not support Intel's floating point
+SIMD, Katmai (KNI).
+
+The eight 64-bit MMX operands, also used by 3DNow!, are called @samp{%mm0},
+@samp{%mm1}, ... @samp{%mm7}. They contain eight 8-bit integers, four
+16-bit integers, two 32-bit integers, one 64-bit integer, or two 32-bit
+floating point values. The MMX registers cannot be used at the same time
+as the floating point stack.
+
+See Intel and AMD documentation, keeping in mind that the operand order in
+instructions is reversed from the Intel syntax.
+
+@node i386-16bit
+@section Writing 16-bit Code
+
+@cindex i386 16-bit code
+@cindex 16-bit code, i386
+@cindex real-mode code, i386
+@cindex @code{code16gcc} directive, i386
+@cindex @code{code16} directive, i386
+@cindex @code{code32} directive, i386
+@cindex @code{code64} directive, i386
+@cindex @code{code64} directive, x86-64
+While @code{@value{AS}} normally writes only ``pure'' 32-bit i386 code
+or 64-bit x86-64 code depending on the default configuration,
+it also supports writing code to run in real mode or in 16-bit protected
+mode code segments. To do this, put a @samp{.code16} or
+@samp{.code16gcc} directive before the assembly language instructions to
+be run in 16-bit mode. You can switch @code{@value{AS}} back to writing
+normal 32-bit code with the @samp{.code32} directive.
+
+@samp{.code16gcc} provides experimental support for generating 16-bit
+code from gcc, and differs from @samp{.code16} in that @samp{call},
+@samp{ret}, @samp{enter}, @samp{leave}, @samp{push}, @samp{pop},
+@samp{pusha}, @samp{popa}, @samp{pushf}, and @samp{popf} instructions
+default to 32-bit size. This is so that the stack pointer is
+manipulated in the same way over function calls, allowing access to
+function parameters at the same stack offsets as in 32-bit mode.
+@samp{.code16gcc} also automatically adds address size prefixes where
+necessary to use the 32-bit addressing modes that gcc generates.
+
+The code which @code{@value{AS}} generates in 16-bit mode will not
+necessarily run on a 16-bit pre-80386 processor. To write code that
+runs on such a processor, you must refrain from using @emph{any} 32-bit
+constructs which require @code{@value{AS}} to output address or operand
+size prefixes.
+
+Note that writing 16-bit code instructions by explicitly specifying a
+prefix or an instruction mnemonic suffix within a 32-bit code section
+generates different machine instructions than those generated for a
+16-bit code segment. In a 32-bit code section, the following code
+generates the machine opcode bytes @samp{66 6a 04}, which pushes the
+value @samp{4} onto the stack, decrementing @samp{%esp} by 2.
+
+@smallexample
+ pushw $4
+@end smallexample
+
+The same code in a 16-bit code section would generate the machine
+opcode bytes @samp{6a 04} (ie. without the operand size prefix), which
+is correct since the processor default operand size is assumed to be 16
+bits in a 16-bit code section.
+
+@node i386-Bugs
+@section AT&T Syntax bugs
+
+The UnixWare assembler, and probably other AT&T derived ix86 Unix
+assemblers, generate floating point instructions with reversed source
+and destination registers in certain cases. Unfortunately, gcc and
+possibly many other programs use this reversed syntax, so we're stuck
+with it.
+
+For example
+
+@smallexample
+ fsub %st,%st(3)
+@end smallexample
+@noindent
+results in @samp{%st(3)} being updated to @samp{%st - %st(3)} rather
+than the expected @samp{%st(3) - %st}. This happens with all the
+non-commutative arithmetic floating point operations with two register
+operands where the source register is @samp{%st} and the destination
+register is @samp{%st(i)}.
+
+@node i386-Arch
+@section Specifying CPU Architecture
+
+@cindex arch directive, i386
+@cindex i386 arch directive
+@cindex arch directive, x86-64
+@cindex x86-64 arch directive
+
+@code{@value{AS}} may be told to assemble for a particular CPU
+architecture with the @code{.arch @var{cpu_type}} directive. This
+directive enables a warning when gas detects an instruction that is not
+supported on the CPU specified. The choices for @var{cpu_type} are:
+
+@multitable @columnfractions .20 .20 .20 .20
+@item @samp{i8086} @tab @samp{i186} @tab @samp{i286} @tab @samp{i386}
+@item @samp{i486} @tab @samp{i586} @tab @samp{i686} @tab @samp{pentium}
+@item @samp{pentiumpro} @tab @samp{pentium4} @tab @samp{k6} @tab @samp{athlon}
+@item @samp{sledgehammer}
+@end multitable
+
+Apart from the warning, there are only two other effects on
+@code{@value{AS}} operation; Firstly, if you specify a CPU other than
+@samp{i486}, then shift by one instructions such as @samp{sarl $1, %eax}
+will automatically use a two byte opcode sequence. The larger three
+byte opcode sequence is used on the 486 (and when no architecture is
+specified) because it executes faster on the 486. Note that you can
+explicitly request the two byte opcode by writing @samp{sarl %eax}.
+Secondly, if you specify @samp{i8086}, @samp{i186}, or @samp{i286},
+@emph{and} @samp{.code16} or @samp{.code16gcc} then byte offset
+conditional jumps will be promoted when necessary to a two instruction
+sequence consisting of a conditional jump of the opposite sense around
+an unconditional jump to the target.
+
+Following the CPU architecture, you may specify @samp{jumps} or
+@samp{nojumps} to control automatic promotion of conditional jumps.
+@samp{jumps} is the default, and enables jump promotion; All external
+jumps will be of the long variety, and file-local jumps will be promoted
+as necessary. (@pxref{i386-Jumps}) @samp{nojumps} leaves external
+conditional jumps as byte offset jumps, and warns about file-local
+conditional jumps that @code{@value{AS}} promotes.
+Unconditional jumps are treated as for @samp{jumps}.
+
+For example
+
+@smallexample
+ .arch i8086,nojumps
+@end smallexample
+
+@node i386-Notes
+@section Notes
+
+@cindex i386 @code{mul}, @code{imul} instructions
+@cindex @code{mul} instruction, i386
+@cindex @code{imul} instruction, i386
+@cindex @code{mul} instruction, x86-64
+@cindex @code{imul} instruction, x86-64
+There is some trickery concerning the @samp{mul} and @samp{imul}
+instructions that deserves mention. The 16-, 32-, 64- and 128-bit expanding
+multiplies (base opcode @samp{0xf6}; extension 4 for @samp{mul} and 5
+for @samp{imul}) can be output only in the one operand form. Thus,
+@samp{imul %ebx, %eax} does @emph{not} select the expanding multiply;
+the expanding multiply would clobber the @samp{%edx} register, and this
+would confuse @code{@value{GCC}} output. Use @samp{imul %ebx} to get the
+64-bit product in @samp{%edx:%eax}.
+
+We have added a two operand form of @samp{imul} when the first operand
+is an immediate mode expression and the second operand is a register.
+This is just a shorthand, so that, multiplying @samp{%eax} by 69, for
+example, can be done with @samp{imul $69, %eax} rather than @samp{imul
+$69, %eax, %eax}.
+
diff --git a/x/binutils/gas/doc/c-ia64.texi b/x/binutils/gas/doc/c-ia64.texi
new file mode 100644
index 0000000..b62c05e
--- /dev/null
+++ b/x/binutils/gas/doc/c-ia64.texi
@@ -0,0 +1,157 @@
+@c Copyright 2002
+@c Free Software Foundation, Inc.
+@c Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+
+@ifset GENERIC
+@page
+@node IA-64-Dependent
+@chapter IA-64 Dependent Features
+@end ifset
+
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter IA-64 Dependent Features
+@end ifclear
+
+@cindex IA-64 support
+@menu
+* IA-64 Options:: Options
+* IA-64 Syntax:: Syntax
+@c * IA-64 Floating Point:: Floating Point // to be written
+@c * IA-64 Directives:: IA-64 Machine Directives // to be written
+* IA-64 Opcodes:: Opcodes
+@end menu
+
+@node IA-64 Options
+@section Options
+@cindex IA-64 options
+@cindex options for IA-64
+
+@table @option
+@cindex @code{-mconstant-gp} command line option, IA-64
+
+@item -mconstant-gp
+This option instructs the assembler to mark the resulting object file
+as using the ``constant GP'' model. With this model, it is assumed
+that the entire program uses a single global pointer (GP) value. Note
+that this option does not in any fashion affect the machine code
+emitted by the assembler. All it does is turn on the EF_IA_64_CONS_GP
+flag in the ELF file header.
+
+@item -mauto-pic
+This option instructs the assembler to mark the resulting object file
+as using the ``constant GP without function descriptor'' data model.
+This model is like the ``constant GP'' model, except that it
+additionally does away with function descriptors. What this means is
+that the address of a function refers directly to the function's code
+entry-point. Normally, such an address would refer to a function
+descriptor, which contains both the code entry-point and the GP-value
+needed by the function. Note that this option does not in any fashion
+affect the machine code emitted by the assembler. All it does is
+turn on the EF_IA_64_NOFUNCDESC_CONS_GP flag in the ELF file header.
+
+@item -milp32
+@item -milp64
+@item -mlp64
+@item -mp64
+These options select the data model. The assembler defaults to @code{-mlp64}
+(LP64 data model).
+
+@item -mle
+@item -mbe
+These options select the byte order. The @code{-mle} option selects little-endian
+byte order (default) and @code{-mbe} selects big-endian byte order. Note that
+IA-64 machine code always uses little-endian byte order.
+
+@item -x
+@item -xexplicit
+These options turn on dependency violation checking. This checking is turned on by
+default.
+
+@item -xauto
+This option instructs the assembler to automatically insert stop bits where necessary
+to remove dependency violations.
+
+@item -xdebug
+This turns on debug output intended to help tracking down bugs in the dependency
+violation checker.
+
+@end table
+
+@cindex IA-64 Syntax
+@node IA-64 Syntax
+@section Syntax
+The assembler syntax closely follows the IA-64 Assembly Language
+Reference Guide.
+
+@menu
+* IA-64-Chars:: Special Characters
+* IA-64-Regs:: Register Names
+* IA-64-Bits:: Bit Names
+* IA-64-Relocs:: Relocations
+@end menu
+
+@node IA-64-Chars
+@subsection Special Characters
+
+@cindex line comment character, IA-64
+@cindex IA-64 line comment character
+@samp{//} is the line comment token.
+
+@cindex line separator, IA-64
+@cindex statement separator, IA-64
+@cindex IA-64 line separator
+@samp{;} can be used instead of a newline to separate statements.
+
+@node IA-64-Regs
+@subsection Register Names
+@cindex IA-64 registers
+@cindex register names, IA-64
+
+The 128 integer registers are referred to as @samp{r@var{n}}.
+The 128 floating-point registers are referred to as @samp{f@var{n}}.
+The 128 application registers are referred to as @samp{ar@var{n}}.
+The 128 control registers are referred to as @samp{cr@var{n}}.
+The 64 one-bit predicate registers are referred to as @samp{p@var{n}}.
+The 8 branch registers are referred to as @samp{b@var{n}}.
+In addition, the assembler defines a number of aliases:
+@samp{gp} (@samp{r1}), @samp{sp} (@samp{r12}), @samp{rp} (@samp{b0}),
+@samp{ret0} (@samp{r8}), @samp{ret1} (@samp{r9}), @samp{ret2} (@samp{r10}),
+@samp{ret3} (@samp{r9}), @samp{farg@var{n}} (@samp{f8+@var{n}}), and
+@samp{fret@var{n}} (@samp{f8+@var{n}}).
+
+For convenience, the assembler also defines aliases for all named application
+and control registers. For example, @samp{ar.bsp} refers to the register
+backing store pointer (@samp{ar17}). Similarly, @samp{cr.eoi} refers to
+the end-of-interrupt register (@samp{cr67}).
+
+@node IA-64-Bits
+@subsection IA-64 Processor-Status-Register (PSR) Bit Names
+@cindex IA-64 Processor-status-Register bit names
+@cindex PSR bits
+@cindex bit names, IA-64
+
+The assembler defines bit masks for each of the bits in the IA-64
+processor status register. For example, @samp{psr.ic} corresponds to
+a value of 0x2000. These masks are primarily intended for use with
+the @sample{ssm}/@sample{sum} and @sample{rsm}/@sample{rum}
+instructions, but they can be used anywhere else where an integer
+constant is expected.
+
+@node IA-64 Opcodes
+@section Opcodes
+For detailed information on the IA-64 machine instruction set, see the
+@c Attempt to work around a very overfull hbox.
+@iftex
+IA-64 Assembly Language Reference Guide available at
+@smallfonts
+@example
+http://developer.intel.com/design/itanium/arch_spec.htm
+@end example
+@textfonts
+@end iftex
+@ifnottex
+@uref{http://developer.intel.com/design/itanium/arch_spec.htm,IA-64 Architecture Handbook}.
+@end ifnottex
diff --git a/x/binutils/gas/doc/c-mips.texi b/x/binutils/gas/doc/c-mips.texi
new file mode 100644
index 0000000..1375230
--- /dev/null
+++ b/x/binutils/gas/doc/c-mips.texi
@@ -0,0 +1,377 @@
+@c Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1999, 2000, 2001,
+@c 2002, 2003, 2004
+@c Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node MIPS-Dependent
+@chapter MIPS Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter MIPS Dependent Features
+@end ifclear
+
+@cindex MIPS processor
+@sc{gnu} @code{@value{AS}} for @sc{mips} architectures supports several
+different @sc{mips} processors, and MIPS ISA levels I through V, MIPS32,
+and MIPS64. For information about the @sc{mips} instruction set, see
+@cite{MIPS RISC Architecture}, by Kane and Heindrich (Prentice-Hall).
+For an overview of @sc{mips} assembly conventions, see ``Appendix D:
+Assembly Language Programming'' in the same work.
+
+@menu
+* MIPS Opts:: Assembler options
+* MIPS Object:: ECOFF object code
+* MIPS Stabs:: Directives for debugging information
+* MIPS ISA:: Directives to override the ISA level
+* MIPS autoextend:: Directives for extending MIPS 16 bit instructions
+* MIPS insn:: Directive to mark data as an instruction
+* MIPS option stack:: Directives to save and restore options
+* MIPS ASE instruction generation overrides:: Directives to control
+ generation of MIPS ASE instructions
+@end menu
+
+@node MIPS Opts
+@section Assembler options
+
+The @sc{mips} configurations of @sc{gnu} @code{@value{AS}} support these
+special options:
+
+@table @code
+@cindex @code{-G} option (MIPS)
+@item -G @var{num}
+This option sets the largest size of an object that can be referenced
+implicitly with the @code{gp} register. It is only accepted for targets
+that use @sc{ecoff} format. The default value is 8.
+
+@cindex @code{-EB} option (MIPS)
+@cindex @code{-EL} option (MIPS)
+@cindex MIPS big-endian output
+@cindex MIPS little-endian output
+@cindex big-endian output, MIPS
+@cindex little-endian output, MIPS
+@item -EB
+@itemx -EL
+Any @sc{mips} configuration of @code{@value{AS}} can select big-endian or
+little-endian output at run time (unlike the other @sc{gnu} development
+tools, which must be configured for one or the other). Use @samp{-EB}
+to select big-endian output, and @samp{-EL} for little-endian.
+
+@cindex MIPS architecture options
+@item -mips1
+@itemx -mips2
+@itemx -mips3
+@itemx -mips4
+@itemx -mips5
+@itemx -mips32
+@itemx -mips32r2
+@itemx -mips64
+@itemx -mips64r2
+Generate code for a particular MIPS Instruction Set Architecture level.
+@samp{-mips1} corresponds to the @sc{r2000} and @sc{r3000} processors,
+@samp{-mips2} to the @sc{r6000} processor, @samp{-mips3} to the
+@sc{r4000} processor, and @samp{-mips4} to the @sc{r8000} and
+@sc{r10000} processors. @samp{-mips5}, @samp{-mips32}, @samp{-mips32r2},
+@samp{-mips64}, and @samp{-mips64r2}
+correspond to generic
+@sc{MIPS V}, @sc{MIPS32}, @sc{MIPS32 Release 2}, @sc{MIPS64},
+and @sc{MIPS64 Release 2}
+ISA processors, respectively. You can also switch
+instruction sets during the assembly; see @ref{MIPS ISA, Directives to
+override the ISA level}.
+
+@item -mgp32
+@itemx -mfp32
+Some macros have different expansions for 32-bit and 64-bit registers.
+The register sizes are normally inferred from the ISA and ABI, but these
+flags force a certain group of registers to be treated as 32 bits wide at
+all times. @samp{-mgp32} controls the size of general-purpose registers
+and @samp{-mfp32} controls the size of floating-point registers.
+
+On some MIPS variants there is a 32-bit mode flag; when this flag is
+set, 64-bit instructions generate a trap. Also, some 32-bit OSes only
+save the 32-bit registers on a context switch, so it is essential never
+to use the 64-bit registers.
+
+@item -mgp64
+Assume that 64-bit general purpose registers are available. This is
+provided in the interests of symmetry with -gp32.
+
+@item -mips16
+@itemx -no-mips16
+Generate code for the MIPS 16 processor. This is equivalent to putting
+@samp{.set mips16} at the start of the assembly file. @samp{-no-mips16}
+turns off this option.
+
+@item -mips3d
+@itemx -no-mips3d
+Generate code for the MIPS-3D Application Specific Extension.
+This tells the assembler to accept MIPS-3D instructions.
+@samp{-no-mips3d} turns off this option.
+
+@item -mdmx
+@itemx -no-mdmx
+Generate code for the MDMX Application Specific Extension.
+This tells the assembler to accept MDMX instructions.
+@samp{-no-mdmx} turns off this option.
+
+@item -mfix7000
+@itemx -mno-fix7000
+Cause nops to be inserted if the read of the destination register
+of an mfhi or mflo instruction occurs in the following two instructions.
+
+@item -mfix-vr4120
+@itemx -no-mfix-vr4120
+Insert nops to work around certain VR4120 errata. This option is
+intended to be used on GCC-generated code: it is not designed to catch
+all problems in hand-written assembler code.
+
+@item -m4010
+@itemx -no-m4010
+Generate code for the LSI @sc{r4010} chip. This tells the assembler to
+accept the @sc{r4010} specific instructions (@samp{addciu}, @samp{ffc},
+etc.), and to not schedule @samp{nop} instructions around accesses to
+the @samp{HI} and @samp{LO} registers. @samp{-no-m4010} turns off this
+option.
+
+@item -m4650
+@itemx -no-m4650
+Generate code for the MIPS @sc{r4650} chip. This tells the assembler to accept
+the @samp{mad} and @samp{madu} instruction, and to not schedule @samp{nop}
+instructions around accesses to the @samp{HI} and @samp{LO} registers.
+@samp{-no-m4650} turns off this option.
+
+@itemx -m3900
+@itemx -no-m3900
+@itemx -m4100
+@itemx -no-m4100
+For each option @samp{-m@var{nnnn}}, generate code for the MIPS
+@sc{r@var{nnnn}} chip. This tells the assembler to accept instructions
+specific to that chip, and to schedule for that chip's hazards.
+
+@item -march=@var{cpu}
+Generate code for a particular MIPS cpu. It is exactly equivalent to
+@samp{-m@var{cpu}}, except that there are more value of @var{cpu}
+understood. Valid @var{cpu} value are:
+
+@quotation
+2000,
+3000,
+3900,
+4000,
+4010,
+4100,
+4111,
+vr4120,
+vr4130,
+vr4181,
+4300,
+4400,
+4600,
+4650,
+5000,
+rm5200,
+rm5230,
+rm5231,
+rm5261,
+rm5721,
+vr5400,
+vr5500,
+6000,
+rm7000,
+8000,
+rm9000,
+10000,
+12000,
+mips32-4k,
+sb1
+@end quotation
+
+@item -mtune=@var{cpu}
+Schedule and tune for a particular MIPS cpu. Valid @var{cpu} values are
+identical to @samp{-march=@var{cpu}}.
+
+@item -mabi=@var{abi}
+Record which ABI the source code uses. The recognized arguments
+are: @samp{32}, @samp{n32}, @samp{o64}, @samp{64} and @samp{eabi}.
+
+@cindex @code{-nocpp} ignored (MIPS)
+@item -nocpp
+This option is ignored. It is accepted for command-line compatibility with
+other assemblers, which use it to turn off C style preprocessing. With
+@sc{gnu} @code{@value{AS}}, there is no need for @samp{-nocpp}, because the
+@sc{gnu} assembler itself never runs the C preprocessor.
+
+@item --construct-floats
+@itemx --no-construct-floats
+@cindex --construct-floats
+@cindex --no-construct-floats
+The @code{--no-construct-floats} option disables the construction of
+double width floating point constants by loading the two halves of the
+value into the two single width floating point registers that make up
+the double width register. This feature is useful if the processor
+support the FR bit in its status register, and this bit is known (by
+the programmer) to be set. This bit prevents the aliasing of the double
+width register by the single width registers.
+
+By default @code{--construct-floats} is selected, allowing construction
+of these floating point constants.
+
+@item --trap
+@itemx --no-break
+@c FIXME! (1) reflect these options (next item too) in option summaries;
+@c (2) stop teasing, say _which_ instructions expanded _how_.
+@code{@value{AS}} automatically macro expands certain division and
+multiplication instructions to check for overflow and division by zero. This
+option causes @code{@value{AS}} to generate code to take a trap exception
+rather than a break exception when an error is detected. The trap instructions
+are only supported at Instruction Set Architecture level 2 and higher.
+
+@item --break
+@itemx --no-trap
+Generate code to take a break exception rather than a trap exception when an
+error is detected. This is the default.
+
+@item -mpdr
+@itemx -mno-pdr
+Control generation of @code{.pdr} sections. Off by default on IRIX, on
+elsewhere.
+@end table
+
+@node MIPS Object
+@section MIPS ECOFF object code
+
+@cindex ECOFF sections
+@cindex MIPS ECOFF sections
+Assembling for a @sc{mips} @sc{ecoff} target supports some additional sections
+besides the usual @code{.text}, @code{.data} and @code{.bss}. The
+additional sections are @code{.rdata}, used for read-only data,
+@code{.sdata}, used for small data, and @code{.sbss}, used for small
+common objects.
+
+@cindex small objects, MIPS ECOFF
+@cindex @code{gp} register, MIPS
+When assembling for @sc{ecoff}, the assembler uses the @code{$gp} (@code{$28})
+register to form the address of a ``small object''. Any object in the
+@code{.sdata} or @code{.sbss} sections is considered ``small'' in this sense.
+For external objects, or for objects in the @code{.bss} section, you can use
+the @code{@value{GCC}} @samp{-G} option to control the size of objects addressed via
+@code{$gp}; the default value is 8, meaning that a reference to any object
+eight bytes or smaller uses @code{$gp}. Passing @samp{-G 0} to
+@code{@value{AS}} prevents it from using the @code{$gp} register on the basis
+of object size (but the assembler uses @code{$gp} for objects in @code{.sdata}
+or @code{sbss} in any case). The size of an object in the @code{.bss} section
+is set by the @code{.comm} or @code{.lcomm} directive that defines it. The
+size of an external object may be set with the @code{.extern} directive. For
+example, @samp{.extern sym,4} declares that the object at @code{sym} is 4 bytes
+in length, whie leaving @code{sym} otherwise undefined.
+
+Using small @sc{ecoff} objects requires linker support, and assumes that the
+@code{$gp} register is correctly initialized (normally done automatically by
+the startup code). @sc{mips} @sc{ecoff} assembly code must not modify the
+@code{$gp} register.
+
+@node MIPS Stabs
+@section Directives for debugging information
+
+@cindex MIPS debugging directives
+@sc{mips} @sc{ecoff} @code{@value{AS}} supports several directives used for
+generating debugging information which are not support by traditional @sc{mips}
+assemblers. These are @code{.def}, @code{.endef}, @code{.dim}, @code{.file},
+@code{.scl}, @code{.size}, @code{.tag}, @code{.type}, @code{.val},
+@code{.stabd}, @code{.stabn}, and @code{.stabs}. The debugging information
+generated by the three @code{.stab} directives can only be read by @sc{gdb},
+not by traditional @sc{mips} debuggers (this enhancement is required to fully
+support C++ debugging). These directives are primarily used by compilers, not
+assembly language programmers!
+
+@node MIPS ISA
+@section Directives to override the ISA level
+
+@cindex MIPS ISA override
+@kindex @code{.set mips@var{n}}
+@sc{gnu} @code{@value{AS}} supports an additional directive to change
+the @sc{mips} Instruction Set Architecture level on the fly: @code{.set
+mips@var{n}}. @var{n} should be a number from 0 to 5, or 32, 32r2, 64
+or 64r2.
+The values other than 0 make the assembler accept instructions
+for the corresponding @sc{isa} level, from that point on in the
+assembly. @code{.set mips@var{n}} affects not only which instructions
+are permitted, but also how certain macros are expanded. @code{.set
+mips0} restores the @sc{isa} level to its original level: either the
+level you selected with command line options, or the default for your
+configuration. You can use this feature to permit specific @sc{r4000}
+instructions while assembling in 32 bit mode. Use this directive with
+care!
+
+The directive @samp{.set mips16} puts the assembler into MIPS 16 mode,
+in which it will assemble instructions for the MIPS 16 processor. Use
+@samp{.set nomips16} to return to normal 32 bit mode.
+
+Traditional @sc{mips} assemblers do not support this directive.
+
+@node MIPS autoextend
+@section Directives for extending MIPS 16 bit instructions
+
+@kindex @code{.set autoextend}
+@kindex @code{.set noautoextend}
+By default, MIPS 16 instructions are automatically extended to 32 bits
+when necessary. The directive @samp{.set noautoextend} will turn this
+off. When @samp{.set noautoextend} is in effect, any 32 bit instruction
+must be explicitly extended with the @samp{.e} modifier (e.g.,
+@samp{li.e $4,1000}). The directive @samp{.set autoextend} may be used
+to once again automatically extend instructions when necessary.
+
+This directive is only meaningful when in MIPS 16 mode. Traditional
+@sc{mips} assemblers do not support this directive.
+
+@node MIPS insn
+@section Directive to mark data as an instruction
+
+@kindex @code{.insn}
+The @code{.insn} directive tells @code{@value{AS}} that the following
+data is actually instructions. This makes a difference in MIPS 16 mode:
+when loading the address of a label which precedes instructions,
+@code{@value{AS}} automatically adds 1 to the value, so that jumping to
+the loaded address will do the right thing.
+
+@node MIPS option stack
+@section Directives to save and restore options
+
+@cindex MIPS option stack
+@kindex @code{.set push}
+@kindex @code{.set pop}
+The directives @code{.set push} and @code{.set pop} may be used to save
+and restore the current settings for all the options which are
+controlled by @code{.set}. The @code{.set push} directive saves the
+current settings on a stack. The @code{.set pop} directive pops the
+stack and restores the settings.
+
+These directives can be useful inside an macro which must change an
+option such as the ISA level or instruction reordering but does not want
+to change the state of the code which invoked the macro.
+
+Traditional @sc{mips} assemblers do not support these directives.
+
+@node MIPS ASE instruction generation overrides
+@section Directives to control generation of MIPS ASE instructions
+
+@cindex MIPS MIPS-3D instruction generation override
+@kindex @code{.set mips3d}
+@kindex @code{.set nomips3d}
+The directive @code{.set mips3d} makes the assembler accept instructions
+from the MIPS-3D Application Specific Extension from that point on
+in the assembly. The @code{.set nomips3d} directive prevents MIPS-3D
+instructions from being accepted.
+
+@cindex MIPS MDMX instruction generation override
+@kindex @code{.set mdmx}
+@kindex @code{.set nomdmx}
+The directive @code{.set mdmx} makes the assembler accept instructions
+from the MDMX Application Specific Extension from that point on
+in the assembly. The @code{.set nomdmx} directive prevents MDMX
+instructions from being accepted.
+
+Traditional @sc{mips} assemblers do not support these directives.
diff --git a/x/binutils/gas/doc/c-ppc.texi b/x/binutils/gas/doc/c-ppc.texi
new file mode 100644
index 0000000..be90e33
--- /dev/null
+++ b/x/binutils/gas/doc/c-ppc.texi
@@ -0,0 +1,126 @@
+@c Copyright 2001, 2002
+@c Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node PPC-Dependent
+@chapter PowerPC Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter PowerPC Dependent Features
+@end ifclear
+
+@cindex PowerPC support
+@menu
+* PowerPC-Opts:: Options
+* PowerPC-Pseudo:: PowerPC Assembler Directives
+@end menu
+
+@node PowerPC-Opts
+@section Options
+
+@cindex options for PowerPC
+@cindex PowerPC options
+@cindex architectures, PowerPC
+@cindex PowerPC architectures
+The PowerPC chip family includes several successive levels, using the same
+core instruction set, but including a few additional instructions at
+each level. There are exceptions to this however. For details on what
+instructions each variant supports, please see the chip's architecture
+reference manual.
+
+The following table lists all available PowerPC options.
+
+@table @code
+@item -mpwrx | -mpwr2
+Generate code for POWER/2 (RIOS2).
+
+@item -mpwr
+Generate code for POWER (RIOS1)
+
+@item -m601
+Generate code for PowerPC 601.
+
+@item -mppc, -mppc32, -m603, -m604
+Generate code for PowerPC 603/604.
+
+@item -m403, -m405
+Generate code for PowerPC 403/405.
+
+@item -m440
+Generate code for PowerPC 440. BookE and some 405 instructions.
+
+@item -m7400, -m7410, -m7450, -m7455
+Generate code for PowerPC 7400/7410/7450/7455.
+
+@item -mppc64, -m620
+Generate code for PowerPC 620/625/630.
+
+@item -mppc64bridge
+Generate code for PowerPC 64, including bridge insns.
+
+@item -mbooke64
+Generate code for 64-bit BookE.
+
+@item -mbooke, mbooke32
+Generate code for 32-bit BookE.
+
+@item -maltivec
+Generate code for processors with AltiVec instructions.
+
+@item -mpower4
+Generate code for Power4 architecture.
+
+@item -mcom
+Generate code Power/PowerPC common instructions.
+
+@item -many
+Generate code for any architecture (PWR/PWRX/PPC).
+
+@item -mregnames
+Allow symbolic names for registers.
+
+@item -mno-regnames
+Do not allow symbolic names for registers.
+
+@item -mrelocatable
+Support for GCC's -mrelocatble option.
+
+@item -mrelocatable-lib
+Support for GCC's -mrelocatble-lib option.
+
+@item -memb
+Set PPC_EMB bit in ELF flags.
+
+@item -mlittle, -mlittle-endian
+Generate code for a little endian machine.
+
+@item -mbig, -mbig-endian
+Generate code for a big endian machine.
+
+@item -msolaris
+Generate code for Solaris.
+
+@item -mno-solaris
+Do not generate code for Solaris.
+@end table
+
+
+@node PowerPC-Pseudo
+@section PowerPC Assembler Directives
+
+@cindex directives for PowerPC
+@cindex PowerPC directives
+A number of assembler directives are available for PowerPC. The
+following table is far from complete.
+
+@table @code
+@item .machine "string"
+This directive allows you to change the machine for which code is
+generated. @code{"string"} may be any of the -m cpu selection options
+(without the -m) enclosed in double quotes, @code{"push"}, or
+@code{"pop"}. @code{.machine "push"} saves the currently selected
+cpu, which may be restored with @code{.machine "pop"}.
+@end table
diff --git a/x/binutils/gas/doc/c-sh.texi b/x/binutils/gas/doc/c-sh.texi
new file mode 100644
index 0000000..b08f325
--- /dev/null
+++ b/x/binutils/gas/doc/c-sh.texi
@@ -0,0 +1,327 @@
+@c Copyright 1991, 1992, 1993, 1994, 1995, 1997, 2001, 2004
+@c Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@page
+@node SH-Dependent
+@chapter Renesas / SuperH SH Dependent Features
+
+@cindex SH support
+@menu
+* SH Options:: Options
+* SH Syntax:: Syntax
+* SH Floating Point:: Floating Point
+* SH Directives:: SH Machine Directives
+* SH Opcodes:: Opcodes
+@end menu
+
+@node SH Options
+@section Options
+
+@cindex SH options
+@cindex options, SH
+@code{@value{AS}} has following command-line options for the Renesas
+(formerly Hitachi) / SuperH SH family.
+
+@table @code
+@kindex -little
+@kindex -big
+@kindex -relax
+@kindex -small
+@kindex -dsp
+@kindex -renesas
+
+@item -little
+Generate little endian code.
+
+@item -big
+Generate big endian code.
+
+@item -relax
+Alter jump instructions for long displacements.
+
+@item -small
+Align sections to 4 byte boundaries, not 16.
+
+@item -dsp
+Enable sh-dsp insns, and disable sh3e / sh4 insns.
+
+@item -renesas
+Disable optimization with section symbol for compatibility with
+Renesas assembler.
+
+@item -isa=sh4 | sh4a
+Specify the sh4 or sh4a instruction set.
+@item -isa=dsp
+Enable sh-dsp insns, and disable sh3e / sh4 insns.
+@item -isa=fp
+Enable sh2e, sh3e, sh4, and sh4a insn sets.
+@item -isa=all
+Enable sh1, sh2, sh2e, sh3, sh3e, sh4, sh4a, and sh-dsp insn sets.
+
+@end table
+
+@node SH Syntax
+@section Syntax
+
+@menu
+* SH-Chars:: Special Characters
+* SH-Regs:: Register Names
+* SH-Addressing:: Addressing Modes
+@end menu
+
+@node SH-Chars
+@subsection Special Characters
+
+@cindex line comment character, SH
+@cindex SH line comment character
+@samp{!} is the line comment character.
+
+@cindex line separator, SH
+@cindex statement separator, SH
+@cindex SH line separator
+You can use @samp{;} instead of a newline to separate statements.
+
+@cindex symbol names, @samp{$} in
+@cindex @code{$} in symbol names
+Since @samp{$} has no special meaning, you may use it in symbol names.
+
+@node SH-Regs
+@subsection Register Names
+
+@cindex SH registers
+@cindex registers, SH
+You can use the predefined symbols @samp{r0}, @samp{r1}, @samp{r2},
+@samp{r3}, @samp{r4}, @samp{r5}, @samp{r6}, @samp{r7}, @samp{r8},
+@samp{r9}, @samp{r10}, @samp{r11}, @samp{r12}, @samp{r13}, @samp{r14},
+and @samp{r15} to refer to the SH registers.
+
+The SH also has these control registers:
+
+@table @code
+@item pr
+procedure register (holds return address)
+
+@item pc
+program counter
+
+@item mach
+@itemx macl
+high and low multiply accumulator registers
+
+@item sr
+status register
+
+@item gbr
+global base register
+
+@item vbr
+vector base register (for interrupt vectors)
+@end table
+
+@node SH-Addressing
+@subsection Addressing Modes
+
+@cindex addressing modes, SH
+@cindex SH addressing modes
+@code{@value{AS}} understands the following addressing modes for the SH.
+@code{R@var{n}} in the following refers to any of the numbered
+registers, but @emph{not} the control registers.
+
+@table @code
+@item R@var{n}
+Register direct
+
+@item @@R@var{n}
+Register indirect
+
+@item @@-R@var{n}
+Register indirect with pre-decrement
+
+@item @@R@var{n}+
+Register indirect with post-increment
+
+@item @@(@var{disp}, R@var{n})
+Register indirect with displacement
+
+@item @@(R0, R@var{n})
+Register indexed
+
+@item @@(@var{disp}, GBR)
+@code{GBR} offset
+
+@item @@(R0, GBR)
+GBR indexed
+
+@item @var{addr}
+@itemx @@(@var{disp}, PC)
+PC relative address (for branch or for addressing memory). The
+@code{@value{AS}} implementation allows you to use the simpler form
+@var{addr} anywhere a PC relative address is called for; the alternate
+form is supported for compatibility with other assemblers.
+
+@item #@var{imm}
+Immediate data
+@end table
+
+@node SH Floating Point
+@section Floating Point
+
+@cindex floating point, SH (@sc{ieee})
+@cindex SH floating point (@sc{ieee})
+SH2E, SH3E and SH4 groups have on-chip floating-point unit (FPU). Other
+SH groups can use @code{.float} directive to generate @sc{ieee}
+floating-point numbers.
+
+SH2E and SH3E support single-precision floating point calculations as
+well as entirely PCAPI compatible emulation of double-precision
+floating point calculations. SH2E and SH3E instructions are a subset of
+the floating point calculations conforming to the IEEE754 standard.
+
+In addition to single-precision and double-precision floating-point
+operation capability, the on-chip FPU of SH4 has a 128-bit graphic
+engine that enables 32-bit floating-point data to be processed 128
+bits at a time. It also supports 4 * 4 array operations and inner
+product operations. Also, a superscalar architecture is employed that
+enables simultaneous execution of two instructions (including FPU
+instructions), providing performance of up to twice that of
+conventional architectures at the same frequency.
+
+@node SH Directives
+@section SH Machine Directives
+
+@cindex SH machine directives
+@cindex machine directives, SH
+@cindex @code{uaword} directive, SH
+@cindex @code{ualong} directive, SH
+
+@table @code
+@item uaword
+@itemx ualong
+@code{@value{AS}} will issue a warning when a misaligned @code{.word} or
+@code{.long} directive is used. You may use @code{.uaword} or
+@code{.ualong} to indicate that the value is intentionally misaligned.
+@end table
+
+@node SH Opcodes
+@section Opcodes
+
+@cindex SH opcode summary
+@cindex opcode summary, SH
+@cindex mnemonics, SH
+@cindex instruction summary, SH
+For detailed information on the SH machine instruction set, see
+@cite{SH-Microcomputer User's Manual} (Renesas) or
+@cite{SH-4 32-bit CPU Core Architecture} (SuperH) and
+@cite{SuperH (SH) 64-Bit RISC Series} (SuperH).
+
+@code{@value{AS}} implements all the standard SH opcodes. No additional
+pseudo-instructions are needed on this family. Note, however, that
+because @code{@value{AS}} supports a simpler form of PC-relative
+addressing, you may simply write (for example)
+
+@example
+mov.l bar,r0
+@end example
+
+@noindent
+where other assemblers might require an explicit displacement to
+@code{bar} from the program counter:
+
+@example
+mov.l @@(@var{disp}, PC)
+@end example
+
+@ifset SMALL
+@c this table, due to the multi-col faking and hardcoded order, looks silly
+@c except in smallbook. See comments below "@set SMALL" near top of this file.
+
+Here is a summary of SH opcodes:
+
+@page
+@smallexample
+@i{Legend:}
+Rn @r{a numbered register}
+Rm @r{another numbered register}
+#imm @r{immediate data}
+disp @r{displacement}
+disp8 @r{8-bit displacement}
+disp12 @r{12-bit displacement}
+
+add #imm,Rn lds.l @@Rn+,PR
+add Rm,Rn mac.w @@Rm+,@@Rn+
+addc Rm,Rn mov #imm,Rn
+addv Rm,Rn mov Rm,Rn
+and #imm,R0 mov.b Rm,@@(R0,Rn)
+and Rm,Rn mov.b Rm,@@-Rn
+and.b #imm,@@(R0,GBR) mov.b Rm,@@Rn
+bf disp8 mov.b @@(disp,Rm),R0
+bra disp12 mov.b @@(disp,GBR),R0
+bsr disp12 mov.b @@(R0,Rm),Rn
+bt disp8 mov.b @@Rm+,Rn
+clrmac mov.b @@Rm,Rn
+clrt mov.b R0,@@(disp,Rm)
+cmp/eq #imm,R0 mov.b R0,@@(disp,GBR)
+cmp/eq Rm,Rn mov.l Rm,@@(disp,Rn)
+cmp/ge Rm,Rn mov.l Rm,@@(R0,Rn)
+cmp/gt Rm,Rn mov.l Rm,@@-Rn
+cmp/hi Rm,Rn mov.l Rm,@@Rn
+cmp/hs Rm,Rn mov.l @@(disp,Rn),Rm
+cmp/pl Rn mov.l @@(disp,GBR),R0
+cmp/pz Rn mov.l @@(disp,PC),Rn
+cmp/str Rm,Rn mov.l @@(R0,Rm),Rn
+div0s Rm,Rn mov.l @@Rm+,Rn
+div0u mov.l @@Rm,Rn
+div1 Rm,Rn mov.l R0,@@(disp,GBR)
+exts.b Rm,Rn mov.w Rm,@@(R0,Rn)
+exts.w Rm,Rn mov.w Rm,@@-Rn
+extu.b Rm,Rn mov.w Rm,@@Rn
+extu.w Rm,Rn mov.w @@(disp,Rm),R0
+jmp @@Rn mov.w @@(disp,GBR),R0
+jsr @@Rn mov.w @@(disp,PC),Rn
+ldc Rn,GBR mov.w @@(R0,Rm),Rn
+ldc Rn,SR mov.w @@Rm+,Rn
+ldc Rn,VBR mov.w @@Rm,Rn
+ldc.l @@Rn+,GBR mov.w R0,@@(disp,Rm)
+ldc.l @@Rn+,SR mov.w R0,@@(disp,GBR)
+ldc.l @@Rn+,VBR mova @@(disp,PC),R0
+lds Rn,MACH movt Rn
+lds Rn,MACL muls Rm,Rn
+lds Rn,PR mulu Rm,Rn
+lds.l @@Rn+,MACH neg Rm,Rn
+lds.l @@Rn+,MACL negc Rm,Rn
+@page
+nop stc VBR,Rn
+not Rm,Rn stc.l GBR,@@-Rn
+or #imm,R0 stc.l SR,@@-Rn
+or Rm,Rn stc.l VBR,@@-Rn
+or.b #imm,@@(R0,GBR) sts MACH,Rn
+rotcl Rn sts MACL,Rn
+rotcr Rn sts PR,Rn
+rotl Rn sts.l MACH,@@-Rn
+rotr Rn sts.l MACL,@@-Rn
+rte sts.l PR,@@-Rn
+rts sub Rm,Rn
+sett subc Rm,Rn
+shal Rn subv Rm,Rn
+shar Rn swap.b Rm,Rn
+shll Rn swap.w Rm,Rn
+shll16 Rn tas.b @@Rn
+shll2 Rn trapa #imm
+shll8 Rn tst #imm,R0
+shlr Rn tst Rm,Rn
+shlr16 Rn tst.b #imm,@@(R0,GBR)
+shlr2 Rn xor #imm,R0
+shlr8 Rn xor Rm,Rn
+sleep xor.b #imm,@@(R0,GBR)
+stc GBR,Rn xtrct Rm,Rn
+stc SR,Rn
+@end smallexample
+@end ifset
+
+@ifset Renesas-all
+@ifclear GENERIC
+@raisesections
+@end ifclear
+@end ifset
+
diff --git a/x/binutils/gas/doc/c-sparc.texi b/x/binutils/gas/doc/c-sparc.texi
new file mode 100644
index 0000000..c34950e
--- /dev/null
+++ b/x/binutils/gas/doc/c-sparc.texi
@@ -0,0 +1,195 @@
+@c Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1999
+@c Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node Sparc-Dependent
+@chapter SPARC Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter SPARC Dependent Features
+@end ifclear
+
+@cindex SPARC support
+@menu
+* Sparc-Opts:: Options
+* Sparc-Aligned-Data:: Option to enforce aligned data
+* Sparc-Float:: Floating Point
+* Sparc-Directives:: Sparc Machine Directives
+@end menu
+
+@node Sparc-Opts
+@section Options
+
+@cindex options for SPARC
+@cindex SPARC options
+@cindex architectures, SPARC
+@cindex SPARC architectures
+The SPARC chip family includes several successive levels, using the same
+core instruction set, but including a few additional instructions at
+each level. There are exceptions to this however. For details on what
+instructions each variant supports, please see the chip's architecture
+reference manual.
+
+By default, @code{@value{AS}} assumes the core instruction set (SPARC
+v6), but ``bumps'' the architecture level as needed: it switches to
+successively higher architectures as it encounters instructions that
+only exist in the higher levels.
+
+If not configured for SPARC v9 (@code{sparc64-*-*}) GAS will not bump
+passed sparclite by default, an option must be passed to enable the
+v9 instructions.
+
+GAS treats sparclite as being compatible with v8, unless an architecture
+is explicitly requested. SPARC v9 is always incompatible with sparclite.
+
+@c The order here is the same as the order of enum sparc_opcode_arch_val
+@c to give the user a sense of the order of the "bumping".
+
+@table @code
+@kindex -Av6
+@kindex Av7
+@kindex -Av8
+@kindex -Asparclet
+@kindex -Asparclite
+@kindex -Av9
+@kindex -Av9a
+@item -Av6 | -Av7 | -Av8 | -Asparclet | -Asparclite
+@itemx -Av8plus | -Av8plusa | -Av9 | -Av9a
+Use one of the @samp{-A} options to select one of the SPARC
+architectures explicitly. If you select an architecture explicitly,
+@code{@value{AS}} reports a fatal error if it encounters an instruction
+or feature requiring an incompatible or higher level.
+
+@samp{-Av8plus} and @samp{-Av8plusa} select a 32 bit environment.
+
+@samp{-Av9} and @samp{-Av9a} select a 64 bit environment and are not
+available unless GAS is explicitly configured with 64 bit environment
+support.
+
+@samp{-Av8plusa} and @samp{-Av9a} enable the SPARC V9 instruction set with
+UltraSPARC extensions.
+
+@item -xarch=v8plus | -xarch=v8plusa
+For compatibility with the Solaris v9 assembler. These options are
+equivalent to -Av8plus and -Av8plusa, respectively.
+
+@item -bump
+Warn whenever it is necessary to switch to another level.
+If an architecture level is explicitly requested, GAS will not issue
+warnings until that level is reached, and will then bump the level
+as required (except between incompatible levels).
+
+@item -32 | -64
+Select the word size, either 32 bits or 64 bits.
+These options are only available with the ELF object file format,
+and require that the necessary BFD support has been included.
+@end table
+
+@node Sparc-Aligned-Data
+@section Enforcing aligned data
+
+@cindex data alignment on SPARC
+@cindex SPARC data alignment
+SPARC GAS normally permits data to be misaligned. For example, it
+permits the @code{.long} pseudo-op to be used on a byte boundary.
+However, the native SunOS and Solaris assemblers issue an error when
+they see misaligned data.
+
+@kindex --enforce-aligned-data
+You can use the @code{--enforce-aligned-data} option to make SPARC GAS
+also issue an error about misaligned data, just as the SunOS and Solaris
+assemblers do.
+
+The @code{--enforce-aligned-data} option is not the default because gcc
+issues misaligned data pseudo-ops when it initializes certain packed
+data structures (structures defined using the @code{packed} attribute).
+You may have to assemble with GAS in order to initialize packed data
+structures in your own code.
+
+@ignore
+@c FIXME: (sparc) Fill in "syntax" section!
+@c subsection syntax
+I don't know anything about Sparc syntax. Someone who does
+will have to write this section.
+@end ignore
+
+@node Sparc-Float
+@section Floating Point
+
+@cindex floating point, SPARC (@sc{ieee})
+@cindex SPARC floating point (@sc{ieee})
+The Sparc uses @sc{ieee} floating-point numbers.
+
+@node Sparc-Directives
+@section Sparc Machine Directives
+
+@cindex SPARC machine directives
+@cindex machine directives, SPARC
+The Sparc version of @code{@value{AS}} supports the following additional
+machine directives:
+
+@table @code
+@cindex @code{align} directive, SPARC
+@item .align
+This must be followed by the desired alignment in bytes.
+
+@cindex @code{common} directive, SPARC
+@item .common
+This must be followed by a symbol name, a positive number, and
+@code{"bss"}. This behaves somewhat like @code{.comm}, but the
+syntax is different.
+
+@cindex @code{half} directive, SPARC
+@item .half
+This is functionally identical to @code{.short}.
+
+@cindex @code{nword} directive, SPARC
+@item .nword
+On the Sparc, the @code{.nword} directive produces native word sized value,
+ie. if assembling with -32 it is equivalent to @code{.word}, if assembling
+with -64 it is equivalent to @code{.xword}.
+
+@cindex @code{proc} directive, SPARC
+@item .proc
+This directive is ignored. Any text following it on the same
+line is also ignored.
+
+@cindex @code{register} directive, SPARC
+@item .register
+This directive declares use of a global application or system register.
+It must be followed by a register name %g2, %g3, %g6 or %g7, comma and
+the symbol name for that register. If symbol name is @code{#scratch},
+it is a scratch register, if it is @code{#ignore}, it just suppresses any
+errors about using undeclared global register, but does not emit any
+information about it into the object file. This can be useful e.g. if you
+save the register before use and restore it after.
+
+@cindex @code{reserve} directive, SPARC
+@item .reserve
+This must be followed by a symbol name, a positive number, and
+@code{"bss"}. This behaves somewhat like @code{.lcomm}, but the
+syntax is different.
+
+@cindex @code{seg} directive, SPARC
+@item .seg
+This must be followed by @code{"text"}, @code{"data"}, or
+@code{"data1"}. It behaves like @code{.text}, @code{.data}, or
+@code{.data 1}.
+
+@cindex @code{skip} directive, SPARC
+@item .skip
+This is functionally identical to the @code{.space} directive.
+
+@cindex @code{word} directive, SPARC
+@item .word
+On the Sparc, the @code{.word} directive produces 32 bit values,
+instead of the 16 bit values it produces on many other machines.
+
+@cindex @code{xword} directive, SPARC
+@item .xword
+On the Sparc V9 processor, the @code{.xword} directive produces
+64 bit values.
+@end table
diff --git a/x/binutils/gas/doc/c-v850.texi b/x/binutils/gas/doc/c-v850.texi
new file mode 100644
index 0000000..4b36461
--- /dev/null
+++ b/x/binutils/gas/doc/c-v850.texi
@@ -0,0 +1,363 @@
+@c Copyright 1997 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+
+@node V850-Dependent
+@chapter v850 Dependent Features
+
+@cindex V850 support
+@menu
+* V850 Options:: Options
+* V850 Syntax:: Syntax
+* V850 Floating Point:: Floating Point
+* V850 Directives:: V850 Machine Directives
+* V850 Opcodes:: Opcodes
+@end menu
+
+@node V850 Options
+@section Options
+@cindex V850 options (none)
+@cindex options for V850 (none)
+@code{@value{AS}} supports the following additional command-line options
+for the V850 processor family:
+
+@cindex command line options, V850
+@cindex V850 command line options
+@table @code
+
+@cindex @code{-wsigned_overflow} command line option, V850
+@item -wsigned_overflow
+Causes warnings to be produced when signed immediate values overflow the
+space available for then within their opcodes. By default this option
+is disabled as it is possible to receive spurious warnings due to using
+exact bit patterns as immediate constants.
+
+@cindex @code{-wunsigned_overflow} command line option, V850
+@item -wunsigned_overflow
+Causes warnings to be produced when unsigned immediate values overflow
+the space available for then within their opcodes. By default this
+option is disabled as it is possible to receive spurious warnings due to
+using exact bit patterns as immediate constants.
+
+@cindex @code{-mv850} command line option, V850
+@item -mv850
+Specifies that the assembled code should be marked as being targeted at
+the V850 processor. This allows the linker to detect attempts to link
+such code with code assembled for other processors.
+
+@cindex @code{-mv850e} command line option, V850
+@item -mv850e
+Specifies that the assembled code should be marked as being targeted at
+the V850E processor. This allows the linker to detect attempts to link
+such code with code assembled for other processors.
+
+@cindex @code{-mv850any} command line option, V850
+@item -mv850any
+Specifies that the assembled code should be marked as being targeted at
+the V850 processor but support instructions that are specific to the
+extended variants of the process. This allows the production of
+binaries that contain target specific code, but which are also intended
+to be used in a generic fashion. For example libgcc.a contains generic
+routines used by the code produced by GCC for all versions of the v850
+architecture, together with support routines only used by the V850E
+architecture.
+
+@end table
+
+
+@node V850 Syntax
+@section Syntax
+@menu
+* V850-Chars:: Special Characters
+* V850-Regs:: Register Names
+@end menu
+
+@node V850-Chars
+@subsection Special Characters
+
+@cindex line comment character, V850
+@cindex V850 line comment character
+@samp{#} is the line comment character.
+@node V850-Regs
+@subsection Register Names
+
+@cindex V850 register names
+@cindex register names, V850
+@code{@value{AS}} supports the following names for registers:
+@table @code
+@cindex @code{zero} register, V850
+@item general register 0
+r0, zero
+@item general register 1
+r1
+@item general register 2
+r2, hp
+@cindex @code{sp} register, V850
+@item general register 3
+r3, sp
+@cindex @code{gp} register, V850
+@item general register 4
+r4, gp
+@cindex @code{tp} register, V850
+@item general register 5
+r5, tp
+@item general register 6
+r6
+@item general register 7
+r7
+@item general register 8
+r8
+@item general register 9
+r9
+@item general register 10
+r10
+@item general register 11
+r11
+@item general register 12
+r12
+@item general register 13
+r13
+@item general register 14
+r14
+@item general register 15
+r15
+@item general register 16
+r16
+@item general register 17
+r17
+@item general register 18
+r18
+@item general register 19
+r19
+@item general register 20
+r20
+@item general register 21
+r21
+@item general register 22
+r22
+@item general register 23
+r23
+@item general register 24
+r24
+@item general register 25
+r25
+@item general register 26
+r26
+@item general register 27
+r27
+@item general register 28
+r28
+@item general register 29
+r29
+@cindex @code{ep} register, V850
+@item general register 30
+r30, ep
+@cindex @code{lp} register, V850
+@item general register 31
+r31, lp
+@cindex @code{eipc} register, V850
+@item system register 0
+eipc
+@cindex @code{eipsw} register, V850
+@item system register 1
+eipsw
+@cindex @code{fepc} register, V850
+@item system register 2
+fepc
+@cindex @code{fepsw} register, V850
+@item system register 3
+fepsw
+@cindex @code{ecr} register, V850
+@item system register 4
+ecr
+@cindex @code{psw} register, V850
+@item system register 5
+psw
+@cindex @code{ctpc} register, V850
+@item system register 16
+ctpc
+@cindex @code{ctpsw} register, V850
+@item system register 17
+ctpsw
+@cindex @code{dbpc} register, V850
+@item system register 18
+dbpc
+@cindex @code{dbpsw} register, V850
+@item system register 19
+dbpsw
+@cindex @code{ctbp} register, V850
+@item system register 20
+ctbp
+@end table
+
+@node V850 Floating Point
+@section Floating Point
+
+@cindex floating point, V850 (@sc{ieee})
+@cindex V850 floating point (@sc{ieee})
+The V850 family uses @sc{ieee} floating-point numbers.
+
+@node V850 Directives
+@section V850 Machine Directives
+
+@cindex machine directives, V850
+@cindex V850 machine directives
+@table @code
+@cindex @code{offset} directive, V850
+@item .offset @var{<expression>}
+Moves the offset into the current section to the specified amount.
+
+@cindex @code{section} directive, V850
+@item .section "name", <type>
+This is an extension to the standard .section directive. It sets the
+current section to be <type> and creates an alias for this section
+called "name".
+
+@cindex @code{.v850} directive, V850
+@item .v850
+Specifies that the assembled code should be marked as being targeted at
+the V850 processor. This allows the linker to detect attempts to link
+such code with code assembled for other processors.
+
+@cindex @code{.v850e} directive, V850
+@item .v850e
+Specifies that the assembled code should be marked as being targeted at
+the V850E processor. This allows the linker to detect attempts to link
+such code with code assembled for other processors.
+
+@end table
+
+@node V850 Opcodes
+@section Opcodes
+
+@cindex V850 opcodes
+@cindex opcodes for V850
+@code{@value{AS}} implements all the standard V850 opcodes.
+
+@code{@value{AS}} also implements the following pseudo ops:
+
+@table @code
+
+@cindex @code{hi0} pseudo-op, V850
+@item hi0()
+Computes the higher 16 bits of the given expression and stores it into
+the immediate operand field of the given instruction. For example:
+
+ @samp{mulhi hi0(here - there), r5, r6}
+
+computes the difference between the address of labels 'here' and
+'there', takes the upper 16 bits of this difference, shifts it down 16
+bits and then mutliplies it by the lower 16 bits in register 5, putting
+the result into register 6.
+
+@cindex @code{lo} pseudo-op, V850
+@item lo()
+Computes the lower 16 bits of the given expression and stores it into
+the immediate operand field of the given instruction. For example:
+
+ @samp{addi lo(here - there), r5, r6}
+
+computes the difference between the address of labels 'here' and
+'there', takes the lower 16 bits of this difference and adds it to
+register 5, putting the result into register 6.
+
+@cindex @code{hi} pseudo-op, V850
+@item hi()
+Computes the higher 16 bits of the given expression and then adds the
+value of the most significant bit of the lower 16 bits of the expression
+and stores the result into the immediate operand field of the given
+instruction. For example the following code can be used to compute the
+address of the label 'here' and store it into register 6:
+
+ @samp{movhi hi(here), r0, r6}
+ @samp{movea lo(here), r6, r6}
+
+The reason for this special behaviour is that movea performs a sign
+extention on its immediate operand. So for example if the address of
+'here' was 0xFFFFFFFF then without the special behaviour of the hi()
+pseudo-op the movhi instruction would put 0xFFFF0000 into r6, then the
+movea instruction would takes its immediate operand, 0xFFFF, sign extend
+it to 32 bits, 0xFFFFFFFF, and then add it into r6 giving 0xFFFEFFFF
+which is wrong (the fifth nibble is E). With the hi() pseudo op adding
+in the top bit of the lo() pseudo op, the movhi instruction actually
+stores 0 into r6 (0xFFFF + 1 = 0x0000), so that the movea instruction
+stores 0xFFFFFFFF into r6 - the right value.
+
+@cindex @code{hilo} pseudo-op, V850
+@item hilo()
+Computes the 32 bit value of the given expression and stores it into
+the immediate operand field of the given instruction (which must be a
+mov instruction). For example:
+
+ @samp{mov hilo(here), r6}
+
+computes the absolute address of label 'here' and puts the result into
+register 6.
+
+@cindex @code{sdaoff} pseudo-op, V850
+@item sdaoff()
+Computes the offset of the named variable from the start of the Small
+Data Area (whoes address is held in register 4, the GP register) and
+stores the result as a 16 bit signed value in the immediate operand
+field of the given instruction. For example:
+
+ @samp{ld.w sdaoff(_a_variable)[gp],r6}
+
+loads the contents of the location pointed to by the label '_a_variable'
+into register 6, provided that the label is located somewhere within +/-
+32K of the address held in the GP register. [Note the linker assumes
+that the GP register contains a fixed address set to the address of the
+label called '__gp'. This can either be set up automatically by the
+linker, or specifically set by using the @samp{--defsym __gp=<value>}
+command line option].
+
+@cindex @code{tdaoff} pseudo-op, V850
+@item tdaoff()
+Computes the offset of the named variable from the start of the Tiny
+Data Area (whoes address is held in register 30, the EP register) and
+stores the result as a 4,5, 7 or 8 bit unsigned value in the immediate
+operand field of the given instruction. For example:
+
+ @samp{sld.w tdaoff(_a_variable)[ep],r6}
+
+loads the contents of the location pointed to by the label '_a_variable'
+into register 6, provided that the label is located somewhere within +256
+bytes of the address held in the EP register. [Note the linker assumes
+that the EP register contains a fixed address set to the address of the
+label called '__ep'. This can either be set up automatically by the
+linker, or specifically set by using the @samp{--defsym __ep=<value>}
+command line option].
+
+@cindex @code{zdaoff} pseudo-op, V850
+@item zdaoff()
+Computes the offset of the named variable from address 0 and stores the
+result as a 16 bit signed value in the immediate operand field of the
+given instruction. For example:
+
+ @samp{movea zdaoff(_a_variable),zero,r6}
+
+puts the address of the label '_a_variable' into register 6, assuming
+that the label is somewhere within the first 32K of memory. (Strictly
+speaking it also possible to access the last 32K of memory as well, as
+the offsets are signed).
+
+@cindex @code{ctoff} pseudo-op, V850
+@item ctoff()
+Computes the offset of the named variable from the start of the Call
+Table Area (whoes address is helg in system register 20, the CTBP
+register) and stores the result a 6 or 16 bit unsigned value in the
+immediate field of then given instruction or piece of data. For
+example:
+
+ @samp{callt ctoff(table_func1)}
+
+will put the call the function whoes address is held in the call table
+at the location labeled 'table_func1'.
+
+@end table
+
+
+For information on the V850 instruction set, see @cite{V850
+Family 32-/16-Bit single-Chip Microcontroller Architecture Manual} from NEC.
+Ltd.
+
diff --git a/x/binutils/gas/doc/c-z8k.texi b/x/binutils/gas/doc/c-z8k.texi
new file mode 100644
index 0000000..d98adea
--- /dev/null
+++ b/x/binutils/gas/doc/c-z8k.texi
@@ -0,0 +1,380 @@
+@c Copyright 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node Z8000-Dependent
+@chapter Z8000 Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter Z8000 Dependent Features
+@end ifclear
+
+@cindex Z8000 support
+The Z8000 @value{AS} supports both members of the Z8000 family: the
+unsegmented Z8002, with 16 bit addresses, and the segmented Z8001 with
+24 bit addresses.
+
+When the assembler is in unsegmented mode (specified with the
+@code{unsegm} directive), an address takes up one word (16 bit)
+sized register. When the assembler is in segmented mode (specified with
+the @code{segm} directive), a 24-bit address takes up a long (32 bit)
+register. @xref{Z8000 Directives,,Assembler Directives for the Z8000},
+for a list of other Z8000 specific assembler directives.
+
+@menu
+* Z8000 Options:: No special command-line options for Z8000
+* Z8000 Syntax:: Assembler syntax for the Z8000
+* Z8000 Directives:: Special directives for the Z8000
+* Z8000 Opcodes:: Opcodes
+@end menu
+
+@node Z8000 Options
+@section Options
+
+@cindex Z8000 options
+@cindex options, Z8000
+@code{@value{AS}} has no additional command-line options for the Zilog
+Z8000 family.
+
+@node Z8000 Syntax
+@section Syntax
+@menu
+* Z8000-Chars:: Special Characters
+* Z8000-Regs:: Register Names
+* Z8000-Addressing:: Addressing Modes
+@end menu
+
+@node Z8000-Chars
+@subsection Special Characters
+
+@cindex line comment character, Z8000
+@cindex Z8000 line comment character
+@samp{!} is the line comment character.
+
+@cindex line separator, Z8000
+@cindex statement separator, Z8000
+@cindex Z8000 line separator
+You can use @samp{;} instead of a newline to separate statements.
+
+@node Z8000-Regs
+@subsection Register Names
+
+@cindex Z8000 registers
+@cindex registers, Z8000
+The Z8000 has sixteen 16 bit registers, numbered 0 to 15. You can refer
+to different sized groups of registers by register number, with the
+prefix @samp{r} for 16 bit registers, @samp{rr} for 32 bit registers and
+@samp{rq} for 64 bit registers. You can also refer to the contents of
+the first eight (of the sixteen 16 bit registers) by bytes. They are
+named @samp{r@var{n}h} and @samp{r@var{n}l}.
+
+@smallexample
+@exdent @emph{byte registers}
+r0l r0h r1h r1l r2h r2l r3h r3l
+r4h r4l r5h r5l r6h r6l r7h r7l
+
+@exdent @emph{word registers}
+r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15
+
+@exdent @emph{long word registers}
+rr0 rr2 rr4 rr6 rr8 rr10 rr12 rr14
+
+@exdent @emph{quad word registers}
+rq0 rq4 rq8 rq12
+@end smallexample
+
+@node Z8000-Addressing
+@subsection Addressing Modes
+
+@cindex addressing modes, Z8000
+@cindex Z800 addressing modes
+@value{AS} understands the following addressing modes for the Z8000:
+
+@table @code
+@item r@var{n}
+Register direct
+
+@item @@r@var{n}
+Indirect register
+
+@item @var{addr}
+Direct: the 16 bit or 24 bit address (depending on whether the assembler
+is in segmented or unsegmented mode) of the operand is in the instruction.
+
+@item address(r@var{n})
+Indexed: the 16 or 24 bit address is added to the 16 bit register to produce
+the final address in memory of the operand.
+
+@item r@var{n}(#@var{imm})
+Base Address: the 16 or 24 bit register is added to the 16 bit sign
+extended immediate displacement to produce the final address in memory
+of the operand.
+
+@item r@var{n}(r@var{m})
+Base Index: the 16 or 24 bit register r@var{n} is added to the sign
+extended 16 bit index register r@var{m} to produce the final address in
+memory of the operand.
+
+@item #@var{xx}
+Immediate data @var{xx}.
+@end table
+
+@node Z8000 Directives
+@section Assembler Directives for the Z8000
+
+@cindex Z8000 directives
+@cindex directives, Z8000
+The Z8000 port of @value{AS} includes these additional assembler directives,
+for compatibility with other Z8000 assemblers. As shown, these do not
+begin with @samp{.} (unlike the ordinary @value{AS} directives).
+
+@table @code
+@kindex segm
+@item segm
+Generates code for the segmented Z8001.
+
+@kindex unsegm
+@item unsegm
+Generates code for the unsegmented Z8002.
+
+@kindex name
+@item name
+Synonym for @code{.file}
+
+@kindex global
+@item global
+Synonym for @code{.global}
+
+@kindex wval
+@item wval
+Synonym for @code{.word}
+
+@kindex lval
+@item lval
+Synonym for @code{.long}
+
+@kindex bval
+@item bval
+Synonym for @code{.byte}
+
+@kindex sval
+@item sval
+Assemble a string. @code{sval} expects one string literal, delimited by
+single quotes. It assembles each byte of the string into consecutive
+addresses. You can use the escape sequence @samp{%@var{xx}} (where
+@var{xx} represents a two-digit hexadecimal number) to represent the
+character whose @sc{ascii} value is @var{xx}. Use this feature to
+describe single quote and other characters that may not appear in string
+literals as themselves. For example, the C statement @w{@samp{char *a =
+"he said \"it's 50% off\"";}} is represented in Z8000 assembly language
+(shown with the assembler output in hex at the left) as
+
+@iftex
+@begingroup
+@let@nonarrowing=@comment
+@end iftex
+@smallexample
+68652073 sval 'he said %22it%27s 50%25 off%22%00'
+61696420
+22697427
+73203530
+25206F66
+662200
+@end smallexample
+@iftex
+@endgroup
+@end iftex
+
+@kindex rsect
+@item rsect
+synonym for @code{.section}
+
+@kindex block
+@item block
+synonym for @code{.space}
+
+@kindex even
+@item even
+special case of @code{.align}; aligns output to even byte boundary.
+@end table
+
+@node Z8000 Opcodes
+@section Opcodes
+
+@cindex Z8000 opcode summary
+@cindex opcode summary, Z8000
+@cindex mnemonics, Z8000
+@cindex instruction summary, Z8000
+For detailed information on the Z8000 machine instruction set, see
+@cite{Z8000 Technical Manual}.
+
+@ifset SMALL
+@c this table, due to the multi-col faking and hardcoded order, looks silly
+@c except in smallbook. See comments below "@set SMALL" near top of this file.
+
+The following table summarizes the opcodes and their arguments:
+@iftex
+@begingroup
+@let@nonarrowing=@comment
+@end iftex
+@smallexample
+
+ rs @r{16 bit source register}
+ rd @r{16 bit destination register}
+ rbs @r{8 bit source register}
+ rbd @r{8 bit destination register}
+ rrs @r{32 bit source register}
+ rrd @r{32 bit destination register}
+ rqs @r{64 bit source register}
+ rqd @r{64 bit destination register}
+ addr @r{16/24 bit address}
+ imm @r{immediate data}
+
+adc rd,rs clrb addr cpsir @@rd,@@rs,rr,cc
+adcb rbd,rbs clrb addr(rd) cpsirb @@rd,@@rs,rr,cc
+add rd,@@rs clrb rbd dab rbd
+add rd,addr com @@rd dbjnz rbd,disp7
+add rd,addr(rs) com addr dec @@rd,imm4m1
+add rd,imm16 com addr(rd) dec addr(rd),imm4m1
+add rd,rs com rd dec addr,imm4m1
+addb rbd,@@rs comb @@rd dec rd,imm4m1
+addb rbd,addr comb addr decb @@rd,imm4m1
+addb rbd,addr(rs) comb addr(rd) decb addr(rd),imm4m1
+addb rbd,imm8 comb rbd decb addr,imm4m1
+addb rbd,rbs comflg flags decb rbd,imm4m1
+addl rrd,@@rs cp @@rd,imm16 di i2
+addl rrd,addr cp addr(rd),imm16 div rrd,@@rs
+addl rrd,addr(rs) cp addr,imm16 div rrd,addr
+addl rrd,imm32 cp rd,@@rs div rrd,addr(rs)
+addl rrd,rrs cp rd,addr div rrd,imm16
+and rd,@@rs cp rd,addr(rs) div rrd,rs
+and rd,addr cp rd,imm16 divl rqd,@@rs
+and rd,addr(rs) cp rd,rs divl rqd,addr
+and rd,imm16 cpb @@rd,imm8 divl rqd,addr(rs)
+and rd,rs cpb addr(rd),imm8 divl rqd,imm32
+andb rbd,@@rs cpb addr,imm8 divl rqd,rrs
+andb rbd,addr cpb rbd,@@rs djnz rd,disp7
+andb rbd,addr(rs) cpb rbd,addr ei i2
+andb rbd,imm8 cpb rbd,addr(rs) ex rd,@@rs
+andb rbd,rbs cpb rbd,imm8 ex rd,addr
+bit @@rd,imm4 cpb rbd,rbs ex rd,addr(rs)
+bit addr(rd),imm4 cpd rd,@@rs,rr,cc ex rd,rs
+bit addr,imm4 cpdb rbd,@@rs,rr,cc exb rbd,@@rs
+bit rd,imm4 cpdr rd,@@rs,rr,cc exb rbd,addr
+bit rd,rs cpdrb rbd,@@rs,rr,cc exb rbd,addr(rs)
+bitb @@rd,imm4 cpi rd,@@rs,rr,cc exb rbd,rbs
+bitb addr(rd),imm4 cpib rbd,@@rs,rr,cc ext0e imm8
+bitb addr,imm4 cpir rd,@@rs,rr,cc ext0f imm8
+bitb rbd,imm4 cpirb rbd,@@rs,rr,cc ext8e imm8
+bitb rbd,rs cpl rrd,@@rs ext8f imm8
+bpt cpl rrd,addr exts rrd
+call @@rd cpl rrd,addr(rs) extsb rd
+call addr cpl rrd,imm32 extsl rqd
+call addr(rd) cpl rrd,rrs halt
+calr disp12 cpsd @@rd,@@rs,rr,cc in rd,@@rs
+clr @@rd cpsdb @@rd,@@rs,rr,cc in rd,imm16
+clr addr cpsdr @@rd,@@rs,rr,cc inb rbd,@@rs
+clr addr(rd) cpsdrb @@rd,@@rs,rr,cc inb rbd,imm16
+clr rd cpsi @@rd,@@rs,rr,cc inc @@rd,imm4m1
+clrb @@rd cpsib @@rd,@@rs,rr,cc inc addr(rd),imm4m1
+inc addr,imm4m1 ldb rbd,rs(rx) mult rrd,addr(rs)
+inc rd,imm4m1 ldb rd(imm16),rbs mult rrd,imm16
+incb @@rd,imm4m1 ldb rd(rx),rbs mult rrd,rs
+incb addr(rd),imm4m1 ldctl ctrl,rs multl rqd,@@rs
+incb addr,imm4m1 ldctl rd,ctrl multl rqd,addr
+incb rbd,imm4m1 ldd @@rs,@@rd,rr multl rqd,addr(rs)
+ind @@rd,@@rs,ra lddb @@rs,@@rd,rr multl rqd,imm32
+indb @@rd,@@rs,rba lddr @@rs,@@rd,rr multl rqd,rrs
+inib @@rd,@@rs,ra lddrb @@rs,@@rd,rr neg @@rd
+inibr @@rd,@@rs,ra ldi @@rd,@@rs,rr neg addr
+iret ldib @@rd,@@rs,rr neg addr(rd)
+jp cc,@@rd ldir @@rd,@@rs,rr neg rd
+jp cc,addr ldirb @@rd,@@rs,rr negb @@rd
+jp cc,addr(rd) ldk rd,imm4 negb addr
+jr cc,disp8 ldl @@rd,rrs negb addr(rd)
+ld @@rd,imm16 ldl addr(rd),rrs negb rbd
+ld @@rd,rs ldl addr,rrs nop
+ld addr(rd),imm16 ldl rd(imm16),rrs or rd,@@rs
+ld addr(rd),rs ldl rd(rx),rrs or rd,addr
+ld addr,imm16 ldl rrd,@@rs or rd,addr(rs)
+ld addr,rs ldl rrd,addr or rd,imm16
+ld rd(imm16),rs ldl rrd,addr(rs) or rd,rs
+ld rd(rx),rs ldl rrd,imm32 orb rbd,@@rs
+ld rd,@@rs ldl rrd,rrs orb rbd,addr
+ld rd,addr ldl rrd,rs(imm16) orb rbd,addr(rs)
+ld rd,addr(rs) ldl rrd,rs(rx) orb rbd,imm8
+ld rd,imm16 ldm @@rd,rs,n orb rbd,rbs
+ld rd,rs ldm addr(rd),rs,n out @@rd,rs
+ld rd,rs(imm16) ldm addr,rs,n out imm16,rs
+ld rd,rs(rx) ldm rd,@@rs,n outb @@rd,rbs
+lda rd,addr ldm rd,addr(rs),n outb imm16,rbs
+lda rd,addr(rs) ldm rd,addr,n outd @@rd,@@rs,ra
+lda rd,rs(imm16) ldps @@rs outdb @@rd,@@rs,rba
+lda rd,rs(rx) ldps addr outib @@rd,@@rs,ra
+ldar rd,disp16 ldps addr(rs) outibr @@rd,@@rs,ra
+ldb @@rd,imm8 ldr disp16,rs pop @@rd,@@rs
+ldb @@rd,rbs ldr rd,disp16 pop addr(rd),@@rs
+ldb addr(rd),imm8 ldrb disp16,rbs pop addr,@@rs
+ldb addr(rd),rbs ldrb rbd,disp16 pop rd,@@rs
+ldb addr,imm8 ldrl disp16,rrs popl @@rd,@@rs
+ldb addr,rbs ldrl rrd,disp16 popl addr(rd),@@rs
+ldb rbd,@@rs mbit popl addr,@@rs
+ldb rbd,addr mreq rd popl rrd,@@rs
+ldb rbd,addr(rs) mres push @@rd,@@rs
+ldb rbd,imm8 mset push @@rd,addr
+ldb rbd,rbs mult rrd,@@rs push @@rd,addr(rs)
+ldb rbd,rs(imm16) mult rrd,addr push @@rd,imm16
+push @@rd,rs set addr,imm4 subl rrd,imm32
+pushl @@rd,@@rs set rd,imm4 subl rrd,rrs
+pushl @@rd,addr set rd,rs tcc cc,rd
+pushl @@rd,addr(rs) setb @@rd,imm4 tccb cc,rbd
+pushl @@rd,rrs setb addr(rd),imm4 test @@rd
+res @@rd,imm4 setb addr,imm4 test addr
+res addr(rd),imm4 setb rbd,imm4 test addr(rd)
+res addr,imm4 setb rbd,rs test rd
+res rd,imm4 setflg imm4 testb @@rd
+res rd,rs sinb rbd,imm16 testb addr
+resb @@rd,imm4 sinb rd,imm16 testb addr(rd)
+resb addr(rd),imm4 sind @@rd,@@rs,ra testb rbd
+resb addr,imm4 sindb @@rd,@@rs,rba testl @@rd
+resb rbd,imm4 sinib @@rd,@@rs,ra testl addr
+resb rbd,rs sinibr @@rd,@@rs,ra testl addr(rd)
+resflg imm4 sla rd,imm8 testl rrd
+ret cc slab rbd,imm8 trdb @@rd,@@rs,rba
+rl rd,imm1or2 slal rrd,imm8 trdrb @@rd,@@rs,rba
+rlb rbd,imm1or2 sll rd,imm8 trib @@rd,@@rs,rbr
+rlc rd,imm1or2 sllb rbd,imm8 trirb @@rd,@@rs,rbr
+rlcb rbd,imm1or2 slll rrd,imm8 trtdrb @@ra,@@rb,rbr
+rldb rbb,rba sout imm16,rs trtib @@ra,@@rb,rr
+rr rd,imm1or2 soutb imm16,rbs trtirb @@ra,@@rb,rbr
+rrb rbd,imm1or2 soutd @@rd,@@rs,ra trtrb @@ra,@@rb,rbr
+rrc rd,imm1or2 soutdb @@rd,@@rs,rba tset @@rd
+rrcb rbd,imm1or2 soutib @@rd,@@rs,ra tset addr
+rrdb rbb,rba soutibr @@rd,@@rs,ra tset addr(rd)
+rsvd36 sra rd,imm8 tset rd
+rsvd38 srab rbd,imm8 tsetb @@rd
+rsvd78 sral rrd,imm8 tsetb addr
+rsvd7e srl rd,imm8 tsetb addr(rd)
+rsvd9d srlb rbd,imm8 tsetb rbd
+rsvd9f srll rrd,imm8 xor rd,@@rs
+rsvdb9 sub rd,@@rs xor rd,addr
+rsvdbf sub rd,addr xor rd,addr(rs)
+sbc rd,rs sub rd,addr(rs) xor rd,imm16
+sbcb rbd,rbs sub rd,imm16 xor rd,rs
+sc imm8 sub rd,rs xorb rbd,@@rs
+sda rd,rs subb rbd,@@rs xorb rbd,addr
+sdab rbd,rs subb rbd,addr xorb rbd,addr(rs)
+sdal rrd,rs subb rbd,addr(rs) xorb rbd,imm8
+sdl rd,rs subb rbd,imm8 xorb rbd,rbs
+sdlb rbd,rs subb rbd,rbs xorb rbd,rbs
+sdll rrd,rs subl rrd,@@rs
+set @@rd,imm4 subl rrd,addr
+set addr(rd),imm4 subl rrd,addr(rs)
+@end smallexample
+@iftex
+@endgroup
+@end iftex
+@end ifset
+
diff --git a/x/binutils/gas/doc/gasp.texi b/x/binutils/gas/doc/gasp.texi
new file mode 100644
index 0000000..889e997
--- /dev/null
+++ b/x/binutils/gas/doc/gasp.texi
@@ -0,0 +1,1456 @@
+\input texinfo @c -*- Texinfo -*-
+@setfilename gasp.info
+@c
+@c This file documents the assembly preprocessor "GASP"
+@c
+@c Copyright 1994, 1995, 2000, 2002 Free Software Foundation, Inc.
+@c
+@c Permission is granted to copy, distribute and/or modify this document
+@c under the terms of the GNU Free Documentation License, Version 1.1
+@c or any later version published by the Free Software Foundation;
+@c with no Invariant Sections, with no Front-Cover Texts, and with no
+@c Back-Cover Texts. A copy of the license is included in the
+@c section entitled "GNU Free Documentation License".
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* gasp: (gasp). The GNU Assembler Preprocessor
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@syncodeindex ky cp
+@syncodeindex fn cp
+
+@finalout
+@setchapternewpage odd
+@settitle GASP
+@titlepage
+@c FIXME boring title
+@title GASP, an assembly preprocessor
+@subtitle for GASP version 1
+@sp 1
+@subtitle March 1994
+@author Roland Pesch
+@page
+
+@tex
+{\parskip=0pt \hfill Cygnus Support\par
+}
+@end tex
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1994, 1995, 2000, 2002 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.1
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, with no Front-Cover Texts, and with no
+ Back-Cover Texts. A copy of the license is included in the
+ section entitled "GNU Free Documentation License".
+
+@end titlepage
+
+@ifinfo
+Copyright @copyright{} 1994, 1995, 2000, 2002 Free Software Foundation, Inc.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries a copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+@end ignore
+
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.1
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, with no Front-Cover Texts, and with no
+ Back-Cover Texts. A copy of the license is included in the
+ section entitled "GNU Free Documentation License".
+
+
+@node Top
+@top GASP
+
+GASP is a preprocessor for assembly programs.
+
+This file describes version 1 of GASP.
+
+Steve Chamberlain wrote GASP; Roland Pesch wrote this manual.
+
+@menu
+* Overview:: What is GASP?
+* Invoking GASP:: Command line options.
+* Commands:: Preprocessor commands.
+* GNU Free Documentation License:: GNU Free Documentation License
+* Index:: Index.
+@end menu
+@end ifinfo
+
+@node Overview
+@chapter What is GASP?
+
+The primary purpose of the @sc{gnu} assembler is to assemble the output of
+other programs---notably compilers. When you have to hand-code
+specialized routines in assembly, that means the @sc{gnu} assembler is
+an unfriendly processor: it has no directives for macros, conditionals,
+or many other conveniences that you might expect.
+
+In some cases you can simply use the C preprocessor, or a generalized
+preprocessor like @sc{m4}; but this can be awkward, since none of these
+things are designed with assembly in mind.
+
+@sc{gasp} fills this need. It is expressly designed to provide the
+facilities you need with hand-coded assembly code. Implementing it as a
+preprocessor, rather than part of the assembler, allows the maximum
+flexibility: you can use it with hand-coded assembly, without paying a
+penalty of added complexity in the assembler you use for compiler
+output.
+
+@emph{Note} The use of @sc{gasp} has now been deprecated. Anything
+that it could do can now be done by the macro facilities built into
+@sc{gas} itself. At some point in the future the @sc{gasp} sources will
+be removed entirely from the binutils distribution.
+
+Here is a small example to give the flavor of @sc{gasp}. This input to
+@sc{gasp}
+
+@cartouche
+@example
+ .MACRO saveregs from=8 to=14
+count .ASSIGNA \from
+ ! save r\from..r\to
+ .AWHILE \&count LE \to
+ mov r\&count,@@-sp
+count .ASSIGNA \&count + 1
+ .AENDW
+ .ENDM
+
+ saveregs from=12
+
+bar: mov #H'dead+10,r0
+foo .SDATAC "hello"<10>
+ .END
+@end example
+@end cartouche
+
+@noindent
+generates this assembly program:
+
+@cartouche
+@example
+ ! save r12..r14
+ mov r12,@@-sp
+ mov r13,@@-sp
+ mov r14,@@-sp
+
+bar: mov #57005+10,r0
+foo: .byte 6,104,101,108,108,111,10
+@end example
+@end cartouche
+
+@node Invoking GASP
+@chapter Command Line Options
+
+@c FIXME! Or is there a simpler way, calling from GAS option?
+The simplest way to use @sc{gasp} is to run it as a filter and assemble
+its output. In Unix and its ilk, you can do this, for example:
+
+@c FIXME! GASP filename suffix convention?
+@example
+$ gasp prog.asm | as -o prog.o
+@end example
+
+Naturally, there are also a few command-line options to allow you to
+request variations on this basic theme. Here is the full set of
+possibilities for the @sc{gasp} command line.
+
+@example
+gasp [ -a | --alternate ]
+ [ -c @var{char} | --commentchar @var{char} ]
+ [ -d | --debug ] [ -h | --help ] [ -M | --mri ]
+ [ -o @var{outfile} | --output @var{outfile} ]
+ [ -p | --print ] [ -s | --copysource ]
+ [ -u | --unreasonable ] [ -v | --version ]
+ @var{infile} @dots{}
+@end example
+
+@ftable @code
+@item @var{infile} @dots{}
+@c FIXME! Why not stdin as default infile?
+The input file names. You must specify at least one input file; if you
+specify more, @sc{gasp} preprocesses them all, concatenating the output
+in the order you list the @var{infile} arguments.
+
+Mark the end of each input file with the preprocessor command
+@code{.END}. @xref{Other Commands,, Miscellaneous commands}.
+
+@item -a
+@itemx --alternate
+Use alternative macro syntax. @xref{Alternate,, Alternate macro
+syntax}, for a discussion of how this syntax differs from the default
+@sc{gasp} syntax.
+
+@cindex comment character, changing
+@cindex semicolon, as comment
+@cindex exclamation mark, as comment
+@cindex shriek, as comment
+@cindex bang, as comment
+@cindex @code{!} default comment char
+@cindex @code{;} as comment char
+@item -c '@var{char}'
+@itemx --commentchar '@var{char}'
+Use @var{char} as the comment character. The default comment character
+is @samp{!}. For example, to use a semicolon as the comment character,
+specify @w{@samp{-c ';'}} on the @sc{gasp} command line. Since
+assembler command characters often have special significance to command
+shells, it is a good idea to quote or escape @var{char} when you specify
+a comment character.
+
+For the sake of simplicity, all examples in this manual use the default
+comment character @samp{!}.
+
+@item -d
+@itemx --debug
+Show debugging statistics. In this version of @sc{gasp}, this option
+produces statistics about the string buffers that @sc{gasp} allocates
+internally. For each defined buffersize @var{s}, @sc{gasp} shows the
+number of strings @var{n} that it allocated, with a line like this:
+
+@example
+strings size @var{s} : @var{n}
+@end example
+
+@noindent
+@sc{gasp} displays these statistics on the standard error stream, when
+done preprocessing.
+
+@item -h
+@itemx --help
+Display a summary of the @sc{gasp} command line options.
+
+@item -M
+@itemx --mri
+Use MRI compatibility mode. Using this option causes @sc{gasp} to
+accept the syntax and pseudo-ops used by the Microtec Research
+@code{ASM68K} assembler.
+
+@item -o @var{outfile}
+@itemx --output @var{outfile}
+Write the output in a file called @var{outfile}. If you do not use the
+@samp{-o} option, @sc{gasp} writes its output on the standard output
+stream.
+
+@item -p
+@itemx --print
+Print line numbers. @sc{gasp} obeys this option @emph{only} if you also
+specify @samp{-s} to copy source lines to its output. With @samp{-s
+-p}, @sc{gasp} displays the line number of each source line copied
+(immediately after the comment character at the beginning of the line).
+
+@item -s
+@itemx --copysource
+Copy the source lines to the output file. Use this option
+to see the effect of each preprocessor line on the @sc{gasp} output.
+@sc{gasp} places a comment character (@samp{!} by default) at
+the beginning of each source line it copies, so that you can use this
+option and still assemble the result.
+
+@item -u
+@itemx --unreasonable
+Bypass ``unreasonable expansion'' limit. Since you can define @sc{gasp}
+macros inside other macro definitions, the preprocessor normally
+includes a sanity check. If your program requires more than 1,000
+nested expansions, @sc{gasp} normally exits with an error message. Use
+this option to turn off this check, allowing unlimited nested
+expansions.
+
+@item -v
+@itemx --version
+Display the @sc{gasp} version number.
+@end ftable
+
+@node Commands
+@chapter Preprocessor Commands
+
+@sc{gasp} commands have a straightforward syntax that fits in well with
+assembly conventions. In general, a command extends for a line, and may
+have up to three fields: an optional label, the command itself, and
+optional arguments to the command. You can write commands in upper or
+lower case, though this manual shows them in upper case. @xref{Syntax
+Details,, Details of the GASP syntax}, for more information.
+
+@menu
+* Conditionals::
+* Loops::
+* Variables::
+* Macros::
+* Data::
+* Listings::
+* Other Commands::
+* Syntax Details::
+* Alternate::
+@end menu
+
+@node Conditionals
+@section Conditional assembly
+
+The conditional-assembly directives allow you to include or exclude
+portions of an assembly depending on how a pair of expressions, or a
+pair of strings, compare.
+
+The overall structure of conditionals is familiar from many other
+contexts. @code{.AIF} marks the start of a conditional, and precedes
+assembly for the case when the condition is true. An optional
+@code{.AELSE} precedes assembly for the converse case, and an
+@code{.AENDI} marks the end of the condition.
+
+@c FIXME! Why doesn't -u turn off this check?
+You may nest conditionals up to a depth of 100; @sc{gasp} rejects
+nesting beyond that, because it may indicate a bug in your macro
+structure.
+
+@c FIXME! Why isn't there something like cpp's -D option? Conditionals
+@c would be much more useful if there were.
+Conditionals are primarily useful inside macro definitions, where you
+often need different effects depending on argument values.
+@xref{Macros,, Defining your own directives}, for details about defining
+macros.
+
+@ftable @code
+@item .AIF @var{expra} @var{cmp} @var{exprb}
+@itemx .AIF "@var{stra}" @var{cmp} "@var{strb}"
+
+The governing condition goes on the same line as the @code{.AIF}
+preprocessor command. You may compare either two strings, or two
+expressions.
+
+When you compare strings, only two conditional @var{cmp} comparison
+operators are available: @samp{EQ} (true if @var{stra} and @var{strb}
+are identical), and @samp{NE} (the opposite).
+
+When you compare two expressions, @emph{both expressions must be
+absolute} (@pxref{Expressions,, Arithmetic expressions in GASP}). You
+can use these @var{cmp} comparison operators with expressions:
+
+@ftable @code
+@item EQ
+Are @var{expra} and @var{exprb} equal? (For strings, are @var{stra} and
+@var{strb} identical?)
+
+@item NE
+Are @var{expra} and @var{exprb} different? (For strings, are @var{stra}
+and @var{strb} different?
+
+@item LT
+Is @var{expra} less than @var{exprb}? (Not allowed for strings.)
+
+@item LE
+Is @var{expra} less than or equal to @var{exprb}? (Not allowed for strings.)
+
+@item GT
+Is @var{expra} greater than @var{exprb}? (Not allowed for strings.)
+
+@item GE
+Is @var{expra} greater than or equal to @var{exprb}? (Not allowed for
+strings.)
+@end ftable
+
+@item .AELSE
+Marks the start of assembly code to be included if the condition fails.
+Optional, and only allowed within a conditional (between @code{.AIF} and
+@code{.AENDI}).
+
+@item .AENDI
+Marks the end of a conditional assembly.
+@end ftable
+
+@node Loops
+@section Repetitive sections of assembly
+
+Two preprocessor directives allow you to repeatedly issue copies of the
+same block of assembly code.
+
+@ftable @code
+@item .AREPEAT @var{aexp}
+@itemx .AENDR
+If you simply need to repeat the same block of assembly over and over a
+fixed number of times, sandwich one instance of the repeated block
+between @code{.AREPEAT} and @code{.AENDR}. Specify the number of
+copies as @var{aexp} (which must be an absolute expression). For
+example, this repeats two assembly statements three times in succession:
+
+@cartouche
+@example
+ .AREPEAT 3
+ rotcl r2
+ div1 r0,r1
+ .AENDR
+@end example
+@end cartouche
+
+@item .AWHILE @var{expra} @var{cmp} @var{exprb}
+@itemx .AENDW
+@itemx .AWHILE @var{stra} @var{cmp} @var{strb}
+@itemx .AENDW
+To repeat a block of assembly depending on a conditional test, rather
+than repeating it for a specific number of times, use @code{.AWHILE}.
+@code{.AENDW} marks the end of the repeated block. The conditional
+comparison works exactly the same way as for @code{.AIF}, with the same
+comparison operators (@pxref{Conditionals,, Conditional assembly}).
+
+Since the terms of the comparison must be absolute expression,
+@code{.AWHILE} is primarily useful within macros. @xref{Macros,,
+Defining your own directives}.
+@end ftable
+
+@cindex loops, breaking out of
+@cindex breaking out of loops
+You can use the @code{.EXITM} preprocessor directive to break out of
+loops early (as well as to break out of macros). @xref{Macros,,
+Defining your own directives}.
+
+@node Variables
+@section Preprocessor variables
+
+You can use variables in @sc{gasp} to represent strings, registers, or
+the results of expressions.
+
+You must distinguish two kinds of variables:
+@enumerate
+@item
+Variables defined with @code{.EQU} or @code{.ASSIGN}. To evaluate this
+kind of variable in your assembly output, simply mention its name. For
+example, these two lines define and use a variable @samp{eg}:
+
+@cartouche
+@example
+eg .EQU FLIP-64
+ @dots{}
+ mov.l eg,r0
+@end example
+@end cartouche
+
+@emph{Do not use} this kind of variable in conditional expressions or
+while loops; @sc{gasp} only evaluates these variables when writing
+assembly output.
+
+@item
+Variables for use during preprocessing. You can define these
+with @code{.ASSIGNC} or @code{.ASSIGNA}. To evaluate this
+kind of variable, write @samp{\&} before the variable name; for example,
+
+@cartouche
+@example
+opcit .ASSIGNA 47
+ @dots{}
+ .AWHILE \&opcit GT 0
+ @dots{}
+ .AENDW
+@end example
+@end cartouche
+
+@sc{gasp} treats macro arguments almost the same way, but to evaluate
+them you use the prefix @samp{\} rather than @samp{\&}.
+@xref{Macros,, Defining your own directives}.
+@end enumerate
+
+@ftable @code
+@item @var{pvar} .EQU @var{expr}
+@c FIXME! Anything to beware of re GAS directive of same name?
+Assign preprocessor variable @var{pvar} the value of the expression
+@var{expr}. There are no restrictions on redefinition; use @samp{.EQU}
+with the same @var{pvar} as often as you find it convenient.
+
+@item @var{pvar} .ASSIGN @var{expr}
+Almost the same as @code{.EQU}, save that you may not redefine
+@var{pvar} using @code{.ASSIGN} once it has a value.
+@c FIXME!! Supposed to work this way, apparently, but on 9feb94 works
+@c just like .EQU
+
+@item @var{pvar} .ASSIGNA @var{aexpr}
+Define a variable with a numeric value, for use during preprocessing.
+@var{aexpr} must be an absolute expression. You can redefine variables
+with @code{.ASSIGNA} at any time.
+
+@item @var{pvar} .ASSIGNC "@var{str}"
+Define a variable with a string value, for use during preprocessing.
+You can redefine variables with @code{.ASSIGNC} at any time.
+
+@item @var{pvar} .REG (@var{register})
+Use @code{.REG} to define a variable that represents a register. In
+particular, @var{register} is @emph{not evaluated} as an expression.
+You may use @code{.REG} at will to redefine register variables.
+@end ftable
+
+All these directives accept the variable name in the ``label'' position,
+that is at the left margin. You may specify a colon after the variable
+name if you wish; the first example above could have started @samp{eg:}
+with the same effect.
+
+@c pagebreak makes for better aesthetics---ensures macro and expansion together
+@page
+@node Macros
+@section Defining your own directives
+
+The commands @code{.MACRO} and @code{.ENDM} allow you to define macros
+that generate assembly output. You can use these macros with a syntax
+similar to built-in @sc{gasp} or assembler directives. For example,
+this definition specifies a macro @code{SUM} that adds together a range of
+consecutive registers:
+
+@cartouche
+@example
+ .MACRO SUM FROM=0, TO=9
+ ! \FROM \TO
+ mov r\FROM,r10
+COUNT .ASSIGNA \FROM+1
+ .AWHILE \&COUNT LE \TO
+ add r\&COUNT,r10
+COUNT .ASSIGNA \&COUNT+1
+ .AENDW
+ .ENDM
+@end example
+@end cartouche
+
+@noindent
+With that definition, @samp{SUM 0,5} generates this assembly output:
+
+@cartouche
+@example
+ ! 0 5
+ mov r0,r10
+ add r1,r10
+ add r2,r10
+ add r3,r10
+ add r4,r10
+ add r5,r10
+@end example
+@end cartouche
+
+@ftable @code
+@item .MACRO @var{macname}
+@itemx .MACRO @var{macname} @var{macargs} @dots{}
+Begin the definition of a macro called @var{macname}. If your macro
+definition requires arguments, specify their names after the macro name,
+separated by commas or spaces. You can supply a default value for any
+macro argument by following the name with @samp{=@var{deflt}}. For
+example, these are all valid @code{.MACRO} statements:
+
+@table @code
+@item .MACRO COMM
+Begin the definition of a macro called @code{COMM}, which takes no
+arguments.
+
+@item .MACRO PLUS1 P, P1
+@itemx .MACRO PLUS1 P P1
+Either statement begins the definition of a macro called @code{PLUS1},
+which takes two arguments; within the macro definition, write
+@samp{\P} or @samp{\P1} to evaluate the arguments.
+
+@item .MACRO RESERVE_STR P1=0 P2
+Begin the definition of a macro called @code{RESERVE_STR}, with two
+arguments. The first argument has a default value, but not the second.
+After the definition is complete, you can call the macro either as
+@samp{RESERVE_STR @var{a},@var{b}} (with @samp{\P1} evaluating to
+@var{a} and @samp{\P2} evaluating to @var{b}), or as @samp{RESERVE_STR
+,@var{b}} (with @samp{\P1} evaluating as the default, in this case
+@samp{0}, and @samp{\P2} evaluating to @var{b}).
+@end table
+
+When you call a macro, you can specify the argument values either by
+position, or by keyword. For example, @samp{SUM 9,17} is equivalent to
+@samp{SUM TO=17, FROM=9}. Macro arguments are preprocessor variables
+similar to the variables you define with @samp{.ASSIGNA} or
+@samp{.ASSIGNC}; in particular, you can use them in conditionals or for
+loop control. (The only difference is the prefix you write to evaluate
+the variable: for a macro argument, write @samp{\@var{argname}}, but for
+a preprocessor variable, write @samp{\&@var{varname}}.)
+
+@item @var{name} .MACRO
+@itemx @var{name} .MACRO ( @var{macargs} @dots{} )
+@c FIXME check: I think no error _and_ no args recognized if I use form
+@c NAME .MACRO ARG ARG
+An alternative form of introducing a macro definition: specify the macro
+name in the label position, and the arguments (if any) between
+parentheses after the name. Defaulting rules and usage work the same
+way as for the other macro definition syntax.
+
+@item .ENDM
+Mark the end of a macro definition.
+
+@item .EXITM
+Exit early from the current macro definition, @code{.AREPEAT} loop, or
+@code{.AWHILE} loop.
+
+@cindex number of macros executed
+@cindex macros, count executed
+@item \@@
+@sc{gasp} maintains a counter of how many macros it has
+executed in this pseudo-variable; you can copy that number to your
+output with @samp{\@@}, but @emph{only within a macro definition}.
+
+@item LOCAL @var{name} [ , @dots{} ]
+@emph{Warning: @code{LOCAL} is only available if you select ``alternate
+macro syntax'' with @samp{-a} or @samp{--alternate}.} @xref{Alternate,,
+Alternate macro syntax}.
+
+Generate a string replacement for each of the @var{name} arguments, and
+replace any instances of @var{name} in each macro expansion. The
+replacement string is unique in the assembly, and different for each
+separate macro expansion. @code{LOCAL} allows you to write macros that
+define symbols, without fear of conflict between separate macro expansions.
+@end ftable
+
+@node Data
+@section Data output
+
+In assembly code, you often need to specify working areas of memory;
+depending on the application, you may want to initialize such memory or
+not. @sc{gasp} provides preprocessor directives to help you avoid
+repetitive coding for both purposes.
+
+You can use labels as usual to mark the data areas.
+
+@menu
+* Initialized::
+* Uninitialized::
+@end menu
+
+@node Initialized
+@subsection Initialized data
+
+These are the @sc{gasp} directives for initialized data, and the standard
+@sc{gnu} assembler directives they expand to:
+
+@ftable @code
+@item .DATA @var{expr}, @var{expr}, @dots{}
+@itemx .DATA.B @var{expr}, @var{expr}, @dots{}
+@itemx .DATA.W @var{expr}, @var{expr}, @dots{}
+@itemx .DATA.L @var{expr}, @var{expr}, @dots{}
+Evaluate arithmetic expressions @var{expr}, and emit the corresponding
+@code{as} directive (labelled with @var{lab}). The unqualified
+@code{.DATA} emits @samp{.long}; @code{.DATA.B} emits @samp{.byte};
+@code{.DATA.W} emits @samp{.short}; and @code{.DATA.L} emits
+@samp{.long}.
+
+For example, @samp{foo .DATA 1,2,3} emits @samp{foo: .long 1,2,3}.
+
+@item .DATAB @var{repeat}, @var{expr}
+@itemx .DATAB.B @var{repeat}, @var{expr}
+@itemx .DATAB.W @var{repeat}, @var{expr}
+@itemx .DATAB.L @var{repeat}, @var{expr}
+@c FIXME! Looks like gasp accepts and ignores args after 2nd.
+Make @code{as} emit @var{repeat} copies of the value of the expression
+@var{expr} (using the @code{as} directive @code{.fill}).
+@samp{.DATAB.B} repeats one-byte values; @samp{.DATAB.W} repeats
+two-byte values; and @samp{.DATAB.L} repeats four-byte values.
+@samp{.DATAB} without a suffix repeats four-byte values, just like
+@samp{.DATAB.L}.
+
+@c FIXME! Allowing zero might be useful for edge conditions in macros.
+@var{repeat} must be an absolute expression with a positive value.
+
+@item .SDATA "@var{str}" @dots{}
+String data. Emits a concatenation of bytes, precisely as you specify
+them (in particular, @emph{nothing is added to mark the end} of the
+string). @xref{Constants,, String and numeric constants}, for details
+about how to write strings. @code{.SDATA} concatenates multiple
+arguments, making it easy to switch between string representations. You
+can use commas to separate the individual arguments for clarity, if you
+choose.
+
+@item .SDATAB @var{repeat}, "@var{str}" @dots{}
+Repeated string data. The first argument specifies how many copies of
+the string to emit; the remaining arguments specify the string, in the
+same way as the arguments to @code{.SDATA}.
+
+@item .SDATAZ "@var{str}" @dots{}
+Zero-terminated string data. Just like @code{.SDATA}, except that
+@code{.SDATAZ} writes a zero byte at the end of the string.
+
+@item .SDATAC "@var{str}" @dots{}
+Count-prefixed string data. Just like @code{.SDATA}, except that
+@sc{gasp} precedes the string with a leading one-byte count. For
+example, @samp{.SDATAC "HI"} generates @samp{.byte 2,72,73}. Since the
+count field is only one byte, you can only use @code{.SDATAC} for
+strings less than 256 bytes in length.
+@end ftable
+
+@node Uninitialized
+@subsection Uninitialized data
+
+@c FIXME! .space different on some platforms, notably HPPA. Config?
+Use the @code{.RES}, @code{.SRES}, @code{.SRESC}, and @code{.SRESZ}
+directives to reserve memory and leave it uninitialized. @sc{gasp}
+resolves these directives to appropriate calls of the @sc{gnu}
+@code{as} @code{.space} directive.
+
+@ftable @code
+@item .RES @var{count}
+@itemx .RES.B @var{count}
+@itemx .RES.W @var{count}
+@itemx .RES.L @var{count}
+Reserve room for @var{count} uninitialized elements of data. The
+suffix specifies the size of each element: @code{.RES.B} reserves
+@var{count} bytes, @code{.RES.W} reserves @var{count} pairs of bytes,
+and @code{.RES.L} reserves @var{count} quartets. @code{.RES} without a
+suffix is equivalent to @code{.RES.L}.
+
+@item .SRES @var{count}
+@itemx .SRES.B @var{count}
+@itemx .SRES.W @var{count}
+@itemx .SRES.L @var{count}
+@c FIXME! This is boring. Shouldn't it at least have a different
+@c default size? (e.g. the "S" suggests "string", for which .B
+@c would be more appropriate)
+@code{.SRES} is a synonym for @samp{.RES}.
+
+@item .SRESC @var{count}
+@itemx .SRESC.B @var{count}
+@itemx .SRESC.W @var{count}
+@itemx .SRESC.L @var{count}
+Like @code{.SRES}, but reserves space for @code{@var{count}+1} elements.
+
+@item .SRESZ @var{count}
+@itemx .SRESZ.B @var{count}
+@itemx .SRESZ.W @var{count}
+@itemx .SRESZ.L @var{count}
+Like @code{.SRES}, but reserves space for @code{@var{count}+1} elements.
+@end ftable
+
+@node Listings
+@section Assembly listing control
+
+The @sc{gasp} listing-control directives correspond to
+related @sc{gnu} @code{as} directives.
+
+@ftable @code
+@item .PRINT LIST
+@itemx .PRINT NOLIST
+Print control. This directive emits the @sc{gnu} @code{as} directive
+@code{.list} or @code{.nolist}, according to its argument. @xref{List,,
+@code{.list}, as.info, Using as}, for details on how these directives
+interact.
+
+@item .FORM LIN=@var{ln}
+@itemx .FORM COL=@var{cols}
+@itemx .FORM LIN=@var{ln} COL=@var{cols}
+Specify the page size for assembly listings: @var{ln} represents the
+number of lines, and @var{cols} the number of columns. You may specify
+either page dimension independently, or both together. If you do not
+specify the number of lines, @sc{gasp} assumes 60 lines; if you do not
+specify the number of columns, @sc{gasp} assumes 132 columns.
+(Any values you may have specified in previous instances of @code{.FORM}
+do @emph{not} carry over as defaults.) Emits the @code{.psize}
+assembler directive.
+
+@item .HEADING @var{string}
+Specify @var{string} as the title of your assembly listings. Emits
+@samp{.title "@var{string}"}.
+
+@item .PAGE
+Force a new page in assembly listings. Emits @samp{.eject}.
+@end ftable
+
+@node Other Commands
+@section Miscellaneous commands
+
+@ftable @code
+@item .ALTERNATE
+Use the alternate macro syntax henceforth in the assembly.
+@xref{Alternate,, Alternate macro syntax}.
+
+@item .ORG
+@c FIXME! This is very strange, since _GAS_ understands .org
+This command is recognized, but not yet implemented. @sc{gasp}
+generates an error message for programs that use @code{.ORG}.
+
+@item .RADIX @var{s}
+@c FIXME no test cases in testsuite/gasp
+@sc{gasp} understands numbers in any of base two, eight, ten, or
+sixteen. You can encode the base explicitly in any numeric constant
+(@pxref{Constants,, String and numeric constants}). If you write
+numbers without an explicit indication of the base, the most recent
+@samp{.RADIX @var{s}} command determines how they are interpreted.
+@var{s} is a single letter, one of the following:
+
+@table @code
+@item .RADIX B
+Base 2.
+
+@item .RADIX Q
+Base 8.
+
+@item .RADIX D
+Base 10. This is the original default radix.
+
+@item .RADIX H
+Base 16.
+@end table
+
+You may specify the argument @var{s} in lower case (any of @samp{bqdh})
+with the same effects.
+
+@item .EXPORT @var{name}
+@itemx .GLOBAL @var{name}
+@c FIXME! No test cases in testsuite/gasp
+Declare @var{name} global (emits @samp{.global @var{name}}). The two
+directives are synonymous.
+
+@item .PROGRAM
+No effect: @sc{gasp} accepts this directive, and silently ignores it.
+
+@item .END
+Mark end of each preprocessor file. @sc{gasp} issues a warning if it
+reaches end of file without seeing this command.
+
+@item .INCLUDE "@var{str}"
+Preprocess the file named by @var{str}, as if its contents appeared
+where the @code{.INCLUDE} directive does. @sc{gasp} imposes a maximum
+limit of 30 stacked include files, as a sanity check.
+@c FIXME! Why is include depth not affected by -u?
+
+@item .ALIGN @var{size}
+@c FIXME! Why is this not utterly pointless?
+Evaluate the absolute expression @var{size}, and emit the assembly
+instruction @samp{.align @var{size}} using the result.
+@end ftable
+
+@node Syntax Details
+@section Details of the GASP syntax
+
+Since @sc{gasp} is meant to work with assembly code, its statement
+syntax has no surprises for the assembly programmer.
+
+@cindex whitespace
+@emph{Whitespace} (blanks or tabs; @emph{not} newline) is partially
+significant, in that it delimits up to three fields in a line. The
+amount of whitespace does not matter; you may line up fields in separate
+lines if you wish, but @sc{gasp} does not require that.
+
+@cindex fields of @sc{gasp} source line
+@cindex label field
+The @emph{first field}, an optional @dfn{label}, must be flush left in a
+line (with no leading whitespace) if it appears at all. You may use a
+colon after the label if you wish; @sc{gasp} neither requires the colon
+nor objects to it (but will not include it as part of the label name).
+
+@cindex directive field
+The @emph{second field}, which must appear after some whitespace,
+contains a @sc{gasp} or assembly @dfn{directive}.
+
+@cindex argument fields
+Any @emph{further fields} on a line are @dfn{arguments} to the
+directive; you can separate them from one another using either commas or
+whitespace.
+
+@menu
+* Markers::
+* Constants::
+* Symbols::
+* Expressions::
+* String Builtins::
+@end menu
+
+@node Markers
+@subsection Special syntactic markers
+
+@sc{gasp} recognizes a few special markers: to delimit comments, to
+continue a statement on the next line, to separate symbols from other
+characters, and to copy text to the output literally. (One other
+special marker, @samp{\@@}, works only within macro definitions;
+@pxref{Macros,, Defining your own directives}.)
+
+@cindex comments
+The trailing part of any @sc{gasp} source line may be a @dfn{comment}.
+A comment begins with the first unquoted comment character (@samp{!} by
+default), or an escaped or doubled comment character (@samp{\!} or
+@samp{!!} by default), and extends to the end of a line. You can
+specify what comment character to use with the @samp{-c} option
+(@pxref{Invoking GASP,, Command Line Options}). The two kinds of
+comment markers lead to slightly different treatment:
+
+@table @code
+@item !
+A single, un-escaped comment character generates an assembly comment in
+the @sc{gasp} output. @sc{gasp} evaluates any preprocessor variables
+(macro arguments, or variables defined with @code{.ASSIGNA} or
+@code{.ASSIGNC}) present. For example, a macro that begins like this
+
+@example
+ .MACRO SUM FROM=0, TO=9
+ ! \FROM \TO
+@end example
+
+@noindent
+issues as the first line of output a comment that records the
+values you used to call the macro.
+
+@c comments, preprocessor-only
+@c preprocessor-only comments
+@c GASP-only comments
+@item \!
+@itemx !!
+Either an escaped comment character, or a double comment character,
+marks a @sc{gasp} source comment. @sc{gasp} does not copy such comments
+to the assembly output.
+@end table
+
+@cindex continuation character
+@kindex +
+To @emph{continue a statement} on the next line of the file, begin the
+second line with the character @samp{+}.
+
+@cindex literal copy to output
+@cindex copying literally to output
+@cindex preprocessing, avoiding
+@cindex avoiding preprocessing
+Occasionally you may want to prevent @sc{gasp} from preprocessing some
+particular bit of text. To @emph{copy literally} from the @sc{gasp}
+source to its output, place @samp{\(} before the string to copy, and
+@samp{)} at the end. For example, write @samp{\(\!)} if you need the
+characters @samp{\!} in your assembly output.
+
+@cindex symbol separator
+@cindex text, separating from symbols
+@cindex symbols, separating from text
+To @emph{separate a preprocessor variable} from text to appear
+immediately after its value, write a single quote (@code{'}). For
+example, @samp{.SDATA "\P'1"} writes a string built by concatenating the
+value of @code{P} and the digit @samp{1}. (You cannot achieve this by
+writing just @samp{\P1}, since @samp{P1} is itself a valid name for a
+preprocessor variable.)
+
+@node Constants
+@subsection String and numeric constants
+
+There are two ways of writing @dfn{string constants} in @sc{gasp}: as
+literal text, and by numeric byte value. Specify a string literal
+between double quotes (@code{"@var{str}"}). Specify an individual
+numeric byte value as an absolute expression between angle brackets
+(@code{<@var{expr}>}. Directives that output strings allow you to
+specify any number of either kind of value, in whatever order is
+convenient, and concatenate the result. (Alternate syntax mode
+introduces a number of alternative string notations; @pxref{Alternate,,
+Alternate macro syntax}.)
+
+@c Details of numeric notation, e.g. base prefixes
+You can write @dfn{numeric constants} either in a specific base, or in
+whatever base is currently selected (either 10, or selected by the most
+recent @code{.RADIX}).
+
+To write a number in a @emph{specific base}, use the pattern
+@code{@var{s}'@var{ddd}}: a base specifier character @var{s}, followed
+by a single quote followed by digits @var{ddd}. The base specifier
+character matches those you can specify with @code{.RADIX}: @samp{B} for
+base 2, @samp{Q} for base 8, @samp{D} for base 10, and @samp{H} for base
+16. (You can write this character in lower case if you prefer.)
+
+You can write floating point constants using the same syntax recognised
+by GAS @ref{Flonums,,Flonums,as,The GNU Assembler.}. A constraint is
+that these constants will be interpreted as decimal values irrespective
+of the currently selected base.
+
+@c FIXME! What are rules for recognizing number in deflt base? Whatever
+@c is left over after parsing other things??
+
+@node Symbols
+@subsection Symbols
+
+@sc{gasp} recognizes symbol names that start with any alphabetic character,
+@samp{_}, or @samp{$}, and continue with any of the same characters or
+with digits. Label names follow the same rules.
+
+@node Expressions
+@subsection Arithmetic expressions in GASP
+
+@cindex absolute expressions
+@cindex relocatable expressions
+There are two kinds of expressions, depending on their result:
+@dfn{absolute} expressions, which resolve to a constant (that is, they
+do not involve any values unknown to @sc{gasp}), and @dfn{relocatable}
+expressions, which must reduce to the form
+
+@example
+@var{addsym}+@var{const}-@var{subsym}
+@end example
+
+@noindent
+where @var{addsym} and @var{subsym} are assembly symbols of unknown
+value, and @var{const} is a constant.
+
+Arithmetic for @sc{gasp} expressions follows very similar rules to C.
+You can use parentheses to change precedence; otherwise, arithmetic
+primitives have decreasing precedence in the order of the following
+list.
+
+@enumerate
+@item
+Single-argument @code{+} (identity), @code{-} (arithmetic opposite), or
+@code{~} (bitwise negation). @emph{The argument must be an absolute
+expression.}
+
+@item
+@code{*} (multiplication) and @code{/} (division). @emph{Both arguments
+must be absolute expressions.}
+
+@item
+@code{+} (addition) and @code{-} (subtraction). @emph{At least one argument
+must be absolute.}
+@c FIXME! Actually, subtraction doesn't check for this.
+
+@item
+@code{&} (bitwise and). @emph{Both arguments must be absolute.}
+
+@item
+@c FIXME! I agree ~ is a better notation than ^ for xor, but is the
+@c improvement worth differing from C?
+@code{|} (bitwise or) and @code{~} (bitwise exclusive or; @code{^} in
+C). @emph{Both arguments must be absolute.}
+@end enumerate
+
+@node String Builtins
+@subsection String primitives
+
+You can use these primitives to manipulate strings (in the argument
+field of @sc{gasp} statements):
+
+@ftable @code
+@item .LEN("@var{str}")
+Calculate the length of string @code{"@var{str}"}, as an absolute
+expression. For example, @samp{.RES.B .LEN("sample")} reserves six
+bytes of memory.
+
+@item .INSTR("@var{string}", "@var{seg}", @var{ix})
+Search for the first occurrence of @var{seg} after position @var{ix} of
+@var{string}. For example, @samp{.INSTR("ABCDEFG", "CDE", 0)} evaluates
+to the absolute result @code{2}.
+
+The result is @code{-1} if @var{seg} does not occur in @var{string}
+after position @var{ix}.
+
+@item .SUBSTR("@var{string}",@var{start},@var{len})
+The substring of @var{string} beginning at byte number @var{start} and
+extending for @var{len} bytes.
+@end ftable
+
+@node Alternate
+@section Alternate macro syntax
+
+If you specify @samp{-a} or @samp{--alternate} on the @sc{gasp} command
+line, the preprocessor uses somewhat different syntax. This syntax is
+reminiscent of the syntax of Phar Lap macro assembler, but it
+is @emph{not} meant to be a full emulation of Phar Lap or similar
+assemblers. In particular, @sc{gasp} does not support directives such
+as @code{DB} and @code{IRP}, even in alternate syntax mode.
+
+In particular, @samp{-a} (or @samp{--alternate}) elicits these
+differences:
+
+@table @emph
+@item Preprocessor directives
+You can use @sc{gasp} preprocessor directives without a leading @samp{.}
+dot. For example, you can write @samp{SDATA} with the same effect as
+@samp{.SDATA}.
+
+@item LOCAL
+One additional directive, @code{LOCAL}, is available. @xref{Macros,,
+Defining your own directives}, for an explanation of how to use
+@code{LOCAL}.
+
+@need 2000
+@item String delimiters
+You can write strings delimited in these other ways besides
+@code{"@var{string}"}:
+
+@table @code
+@item '@var{string}'
+You can delimit strings with single-quote charaters.
+
+@item <@var{string}>
+You can delimit strings with matching angle brackets.
+@end table
+
+@item single-character string escape
+To include any single character literally in a string (even if the
+character would otherwise have some special meaning), you can prefix the
+character with @samp{!} (an exclamation mark). For example, you can
+write @samp{<4.3 !> 5.4!!>} to get the literal text @samp{4.3 > 5.4!}.
+
+@item Expression results as strings
+You can write @samp{%@var{expr}} to evaluate the expression @var{expr}
+and use the result as a string.
+@end table
+
+@node GNU Free Documentation License
+@chapter GNU Free Documentation License
+
+ GNU Free Documentation License
+
+ Version 1.1, March 2000
+
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+0. PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+written document "free" in the sense of freedom: to assure everyone
+the effective freedom to copy and redistribute it, with or without
+modifying it, either commercially or noncommercially. Secondarily,
+this License preserves for the author and publisher a way to get
+credit for their work, while not being considered responsible for
+modifications made by others.
+
+This License is a kind of "copyleft", which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+
+1. APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work that contains a
+notice placed by the copyright holder saying it can be distributed
+under the terms of this License. The "Document", below, refers to any
+such manual or work. Any member of the public is a licensee, and is
+addressed as "you".
+
+A "Modified Version" of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A "Secondary Section" is a named appendix or a front-matter section of
+the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall subject
+(or to related matters) and contains nothing that could fall directly
+within that overall subject. (For example, if the Document is in part a
+textbook of mathematics, a Secondary Section may not explain any
+mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The "Invariant Sections" are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License.
+
+The "Cover Texts" are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License.
+
+A "Transparent" copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, whose contents can be viewed and edited directly and
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup has been designed to thwart or discourage
+subsequent modification by readers is not Transparent. A copy that is
+not "Transparent" is called "Opaque".
+
+Examples of suitable formats for Transparent copies include plain
+ASCII without markup, Texinfo input format, LaTeX input format, SGML
+or XML using a publicly available DTD, and standard-conforming simple
+HTML designed for human modification. Opaque formats include
+PostScript, PDF, proprietary formats that can be read and edited only
+by proprietary word processors, SGML or XML for which the DTD and/or
+processing tools are not generally available, and the
+machine-generated HTML produced by some word processors for output
+purposes only.
+
+The "Title Page" means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, "Title Page" means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+
+2. VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+
+3. COPYING IN QUANTITY
+
+If you publish printed copies of the Document numbering more than 100,
+and the Document's license notice requires Cover Texts, you must enclose
+the copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a publicly-accessible computer-network location containing a complete
+Transparent copy of the Document, free of added material, which the
+general network-using public has access to download anonymously at no
+charge using public-standard network protocols. If you use the latter
+option, you must take reasonably prudent steps, when you begin
+distribution of Opaque copies in quantity, to ensure that this
+Transparent copy will remain thus accessible at the stated location
+until at least one year after the last time you distribute an Opaque
+copy (directly or through your agents or retailers) of that edition to
+the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+
+4. MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+A. Use in the Title Page (and on the covers, if any) a title distinct
+ from that of the Document, and from those of previous versions
+ (which should, if there were any, be listed in the History section
+ of the Document). You may use the same title as a previous version
+ if the original publisher of that version gives permission.
+B. List on the Title Page, as authors, one or more persons or entities
+ responsible for authorship of the modifications in the Modified
+ Version, together with at least five of the principal authors of the
+ Document (all of its principal authors, if it has less than five).
+C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+D. Preserve all the copyright notices of the Document.
+E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+F. Include, immediately after the copyright notices, a license notice
+ giving the public permission to use the Modified Version under the
+ terms of this License, in the form shown in the Addendum below.
+G. Preserve in that license notice the full lists of Invariant Sections
+ and required Cover Texts given in the Document's license notice.
+H. Include an unaltered copy of this License.
+I. Preserve the section entitled "History", and its title, and add to
+ it an item stating at least the title, year, new authors, and
+ publisher of the Modified Version as given on the Title Page. If
+ there is no section entitled "History" in the Document, create one
+ stating the title, year, authors, and publisher of the Document as
+ given on its Title Page, then add an item describing the Modified
+ Version as stated in the previous sentence.
+J. Preserve the network location, if any, given in the Document for
+ public access to a Transparent copy of the Document, and likewise
+ the network locations given in the Document for previous versions
+ it was based on. These may be placed in the "History" section.
+ You may omit a network location for a work that was published at
+ least four years before the Document itself, or if the original
+ publisher of the version it refers to gives permission.
+K. In any section entitled "Acknowledgements" or "Dedications",
+ preserve the section's title, and preserve in the section all the
+ substance and tone of each of the contributor acknowledgements
+ and/or dedications given therein.
+L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section titles.
+M. Delete any section entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+N. Do not retitle any existing section as "Endorsements"
+ or to conflict in title with any Invariant Section.
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section entitled "Endorsements", provided it contains
+nothing but endorsements of your Modified Version by various
+parties--for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+
+5. COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections entitled "History"
+in the various original documents, forming one section entitled
+"History"; likewise combine any sections entitled "Acknowledgements",
+and any sections entitled "Dedications". You must delete all sections
+entitled "Endorsements."
+
+
+6. COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+
+7. AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, does not as a whole count as a Modified Version
+of the Document, provided no compilation copyright is claimed for the
+compilation. Such a compilation is called an "aggregate", and this
+License does not apply to the other self-contained works thus compiled
+with the Document, on account of their being thus compiled, if they
+are not themselves derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one quarter
+of the entire aggregate, the Document's Cover Texts may be placed on
+covers that surround only the Document within the aggregate.
+Otherwise they must appear on covers around the whole aggregate.
+
+
+8. TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License provided that you also include the
+original English version of this License. In case of a disagreement
+between the translation and the original English version of this
+License, the original English version will prevail.
+
+
+9. TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document except
+as expressly provided for under this License. Any other attempt to
+copy, modify, sublicense or distribute the Document is void, and will
+automatically terminate your rights under this License. However,
+parties who have received copies, or rights, from you under this
+License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+
+10. FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns. See
+http://www.gnu.org/copyleft/.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License "or any later version" applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation.
+
+
+ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+@smallexample
+ Copyright (c) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.1
+ or any later version published by the Free Software Foundation;
+ with the Invariant Sections being LIST THEIR TITLES, with the
+ Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+ A copy of the license is included in the section entitled "GNU
+ Free Documentation License".
+@end smallexample
+
+If you have no Invariant Sections, write "with no Invariant Sections"
+instead of saying which ones are invariant. If you have no
+Front-Cover Texts, write "no Front-Cover Texts" instead of
+"Front-Cover Texts being LIST"; likewise for Back-Cover Texts.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@contents
+@bye
diff --git a/x/binutils/gas/doc/gasver.texi b/x/binutils/gas/doc/gasver.texi
new file mode 100644
index 0000000..3610a96
--- /dev/null
+++ b/x/binutils/gas/doc/gasver.texi
@@ -0,0 +1 @@
+@set VERSION 2.15
diff --git a/x/binutils/gas/doc/h8.texi b/x/binutils/gas/doc/h8.texi
new file mode 100644
index 0000000..6eb02f8
--- /dev/null
+++ b/x/binutils/gas/doc/h8.texi
@@ -0,0 +1,26 @@
+@clear ALL-ARCH
+@clear GENERIC
+@clear INTERNALS
+@clear MULTI-OBJ
+@clear AOUT
+@clear BOUT
+@set COFF
+@clear ELF
+@set Renesas-all
+@set H8/300
+@set H8/500
+@set SH
+@clear DIFF-TBL-KLUGE
+@set IEEEFLOAT
+@clear W32
+@set W16
+@set SPECIAL-SYMS
+@set AS as
+@set GCC gcc
+@set LD ld
+@set TARGET H8/300 and H8/500
+@set TARGET H8/300, H8/500, and Renesas SH
+@set OBJ-NAME COFF
+@c
+@clear have-stabs
+@set abnormal-separator
diff --git a/x/binutils/gas/doc/internals.texi b/x/binutils/gas/doc/internals.texi
new file mode 100644
index 0000000..6719bbf
--- /dev/null
+++ b/x/binutils/gas/doc/internals.texi
@@ -0,0 +1,1948 @@
+\input texinfo
+@c Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+@c 2001, 2002, 2003
+@c Free Software Foundation, Inc.
+@setfilename internals.info
+@node Top
+@top Assembler Internals
+@raisesections
+@cindex internals
+
+This chapter describes the internals of the assembler. It is incomplete, but
+it may help a bit.
+
+This chapter is not updated regularly, and it may be out of date.
+
+@menu
+* GAS versions:: GAS versions
+* Data types:: Data types
+* GAS processing:: What GAS does when it runs
+* Porting GAS:: Porting GAS
+* Relaxation:: Relaxation
+* Broken words:: Broken words
+* Internal functions:: Internal functions
+* Test suite:: Test suite
+@end menu
+
+@node GAS versions
+@section GAS versions
+
+GAS has acquired layers of code over time. The original GAS only supported the
+a.out object file format, with three sections. Support for multiple sections
+has been added in two different ways.
+
+The preferred approach is to use the version of GAS created when the symbol
+@code{BFD_ASSEMBLER} is defined. The other versions of GAS are documented for
+historical purposes, and to help anybody who has to debug code written for
+them.
+
+The type @code{segT} is used to represent a section in code which must work
+with all versions of GAS.
+
+@menu
+* Original GAS:: Original GAS version
+* MANY_SEGMENTS:: MANY_SEGMENTS gas version
+* BFD_ASSEMBLER:: BFD_ASSEMBLER gas version
+@end menu
+
+@node Original GAS
+@subsection Original GAS
+
+The original GAS only supported the a.out object file format with three
+sections: @samp{.text}, @samp{.data}, and @samp{.bss}. This is the version of
+GAS that is compiled if neither @code{BFD_ASSEMBLER} nor @code{MANY_SEGMENTS}
+is defined. This version of GAS is still used for the m68k-aout target, and
+perhaps others.
+
+This version of GAS should not be used for any new development.
+
+There is still code that is specific to this version of GAS, notably in
+@file{write.c}. There is no way for this code to loop through all the
+sections; it simply looks at global variables like @code{text_frag_root} and
+@code{data_frag_root}.
+
+The type @code{segT} is an enum.
+
+@node MANY_SEGMENTS
+@subsection MANY_SEGMENTS gas version
+@cindex MANY_SEGMENTS
+
+The @code{MANY_SEGMENTS} version of gas is only used for COFF. It uses the BFD
+library, but it writes out all the data itself using @code{bfd_write}. This
+version of gas supports up to 40 normal sections. The section names are stored
+in the @code{seg_name} array. Other information is stored in the
+@code{segment_info} array.
+
+The type @code{segT} is an enum. Code that wants to examine all the sections
+can use a @code{segT} variable as loop index from @code{SEG_E0} up to but not
+including @code{SEG_UNKNOWN}.
+
+Most of the code specific to this version of GAS is in the file
+@file{config/obj-coff.c}, in the portion of that file that is compiled when
+@code{BFD_ASSEMBLER} is not defined.
+
+This version of GAS is still used for several COFF targets.
+
+@node BFD_ASSEMBLER
+@subsection BFD_ASSEMBLER gas version
+@cindex BFD_ASSEMBLER
+
+The preferred version of GAS is the @code{BFD_ASSEMBLER} version. In this
+version of GAS, the output file is a normal BFD, and the BFD routines are used
+to generate the output.
+
+@code{BFD_ASSEMBLER} will automatically be used for certain targets, including
+those that use the ELF, ECOFF, and SOM object file formats, and also all Alpha,
+MIPS, PowerPC, and SPARC targets. You can force the use of
+@code{BFD_ASSEMBLER} for other targets with the configure option
+@samp{--enable-bfd-assembler}; however, it has not been tested for many
+targets, and can not be assumed to work.
+
+@node Data types
+@section Data types
+@cindex internals, data types
+
+This section describes some fundamental GAS data types.
+
+@menu
+* Symbols:: The symbolS structure
+* Expressions:: The expressionS structure
+* Fixups:: The fixS structure
+* Frags:: The fragS structure
+@end menu
+
+@node Symbols
+@subsection Symbols
+@cindex internals, symbols
+@cindex symbols, internal
+@cindex symbolS structure
+
+The definition for the symbol structure, @code{symbolS}, is located in
+@file{struc-symbol.h}.
+
+In general, the fields of this structure may not be referred to directly.
+Instead, you must use one of the accessor functions defined in @file{symbol.h}.
+These accessor functions should work for any GAS version.
+
+Symbol structures contain the following fields:
+
+@table @code
+@item sy_value
+This is an @code{expressionS} that describes the value of the symbol. It might
+refer to one or more other symbols; if so, its true value may not be known
+until @code{resolve_symbol_value} is called with @var{finalize_syms} non-zero
+in @code{write_object_file}.
+
+The expression is often simply a constant. Before @code{resolve_symbol_value}
+is called with @var{finalize_syms} set, the value is the offset from the frag
+(@pxref{Frags}). Afterward, the frag address has been added in.
+
+@item sy_resolved
+This field is non-zero if the symbol's value has been completely resolved. It
+is used during the final pass over the symbol table.
+
+@item sy_resolving
+This field is used to detect loops while resolving the symbol's value.
+
+@item sy_used_in_reloc
+This field is non-zero if the symbol is used by a relocation entry. If a local
+symbol is used in a relocation entry, it must be possible to redirect those
+relocations to other symbols, or this symbol cannot be removed from the final
+symbol list.
+
+@item sy_next
+@itemx sy_previous
+These pointers to other @code{symbolS} structures describe a singly or doubly
+linked list. (If @code{SYMBOLS_NEED_BACKPOINTERS} is not defined, the
+@code{sy_previous} field will be omitted; @code{SYMBOLS_NEED_BACKPOINTERS} is
+always defined if @code{BFD_ASSEMBLER}.) These fields should be accessed with
+the @code{symbol_next} and @code{symbol_previous} macros.
+
+@item sy_frag
+This points to the frag (@pxref{Frags}) that this symbol is attached to.
+
+@item sy_used
+Whether the symbol is used as an operand or in an expression. Note: Not all of
+the backends keep this information accurate; backends which use this bit are
+responsible for setting it when a symbol is used in backend routines.
+
+@item sy_mri_common
+Whether the symbol is an MRI common symbol created by the @code{COMMON}
+pseudo-op when assembling in MRI mode.
+
+@item bsym
+If @code{BFD_ASSEMBLER} is defined, this points to the BFD @code{asymbol} that
+will be used in writing the object file.
+
+@item sy_name_offset
+(Only used if @code{BFD_ASSEMBLER} is not defined.) This is the position of
+the symbol's name in the string table of the object file. On some formats,
+this will start at position 4, with position 0 reserved for unnamed symbols.
+This field is not used until @code{write_object_file} is called.
+
+@item sy_symbol
+(Only used if @code{BFD_ASSEMBLER} is not defined.) This is the
+format-specific symbol structure, as it would be written into the object file.
+
+@item sy_number
+(Only used if @code{BFD_ASSEMBLER} is not defined.) This is a 24-bit symbol
+number, for use in constructing relocation table entries.
+
+@item sy_obj
+This format-specific data is of type @code{OBJ_SYMFIELD_TYPE}. If no macro by
+that name is defined in @file{obj-format.h}, this field is not defined.
+
+@item sy_tc
+This processor-specific data is of type @code{TC_SYMFIELD_TYPE}. If no macro
+by that name is defined in @file{targ-cpu.h}, this field is not defined.
+
+@end table
+
+Here is a description of the accessor functions. These should be used rather
+than referring to the fields of @code{symbolS} directly.
+
+@table @code
+@item S_SET_VALUE
+@cindex S_SET_VALUE
+Set the symbol's value.
+
+@item S_GET_VALUE
+@cindex S_GET_VALUE
+Get the symbol's value. This will cause @code{resolve_symbol_value} to be
+called if necessary.
+
+@item S_SET_SEGMENT
+@cindex S_SET_SEGMENT
+Set the section of the symbol.
+
+@item S_GET_SEGMENT
+@cindex S_GET_SEGMENT
+Get the symbol's section.
+
+@item S_GET_NAME
+@cindex S_GET_NAME
+Get the name of the symbol.
+
+@item S_SET_NAME
+@cindex S_SET_NAME
+Set the name of the symbol.
+
+@item S_IS_EXTERNAL
+@cindex S_IS_EXTERNAL
+Return non-zero if the symbol is externally visible.
+
+@item S_IS_EXTERN
+@cindex S_IS_EXTERN
+A synonym for @code{S_IS_EXTERNAL}. Don't use it.
+
+@item S_IS_WEAK
+@cindex S_IS_WEAK
+Return non-zero if the symbol is weak.
+
+@item S_IS_COMMON
+@cindex S_IS_COMMON
+Return non-zero if this is a common symbol. Common symbols are sometimes
+represented as undefined symbols with a value, in which case this function will
+not be reliable.
+
+@item S_IS_DEFINED
+@cindex S_IS_DEFINED
+Return non-zero if this symbol is defined. This function is not reliable when
+called on a common symbol.
+
+@item S_IS_DEBUG
+@cindex S_IS_DEBUG
+Return non-zero if this is a debugging symbol.
+
+@item S_IS_LOCAL
+@cindex S_IS_LOCAL
+Return non-zero if this is a local assembler symbol which should not be
+included in the final symbol table. Note that this is not the opposite of
+@code{S_IS_EXTERNAL}. The @samp{-L} assembler option affects the return value
+of this function.
+
+@item S_SET_EXTERNAL
+@cindex S_SET_EXTERNAL
+Mark the symbol as externally visible.
+
+@item S_CLEAR_EXTERNAL
+@cindex S_CLEAR_EXTERNAL
+Mark the symbol as not externally visible.
+
+@item S_SET_WEAK
+@cindex S_SET_WEAK
+Mark the symbol as weak.
+
+@item S_GET_TYPE
+@item S_GET_DESC
+@item S_GET_OTHER
+@cindex S_GET_TYPE
+@cindex S_GET_DESC
+@cindex S_GET_OTHER
+Get the @code{type}, @code{desc}, and @code{other} fields of the symbol. These
+are only defined for object file formats for which they make sense (primarily
+a.out).
+
+@item S_SET_TYPE
+@item S_SET_DESC
+@item S_SET_OTHER
+@cindex S_SET_TYPE
+@cindex S_SET_DESC
+@cindex S_SET_OTHER
+Set the @code{type}, @code{desc}, and @code{other} fields of the symbol. These
+are only defined for object file formats for which they make sense (primarily
+a.out).
+
+@item S_GET_SIZE
+@cindex S_GET_SIZE
+Get the size of a symbol. This is only defined for object file formats for
+which it makes sense (primarily ELF).
+
+@item S_SET_SIZE
+@cindex S_SET_SIZE
+Set the size of a symbol. This is only defined for object file formats for
+which it makes sense (primarily ELF).
+
+@item symbol_get_value_expression
+@cindex symbol_get_value_expression
+Get a pointer to an @code{expressionS} structure which represents the value of
+the symbol as an expression.
+
+@item symbol_set_value_expression
+@cindex symbol_set_value_expression
+Set the value of a symbol to an expression.
+
+@item symbol_set_frag
+@cindex symbol_set_frag
+Set the frag where a symbol is defined.
+
+@item symbol_get_frag
+@cindex symbol_get_frag
+Get the frag where a symbol is defined.
+
+@item symbol_mark_used
+@cindex symbol_mark_used
+Mark a symbol as having been used in an expression.
+
+@item symbol_clear_used
+@cindex symbol_clear_used
+Clear the mark indicating that a symbol was used in an expression.
+
+@item symbol_used_p
+@cindex symbol_used_p
+Return whether a symbol was used in an expression.
+
+@item symbol_mark_used_in_reloc
+@cindex symbol_mark_used_in_reloc
+Mark a symbol as having been used by a relocation.
+
+@item symbol_clear_used_in_reloc
+@cindex symbol_clear_used_in_reloc
+Clear the mark indicating that a symbol was used in a relocation.
+
+@item symbol_used_in_reloc_p
+@cindex symbol_used_in_reloc_p
+Return whether a symbol was used in a relocation.
+
+@item symbol_mark_mri_common
+@cindex symbol_mark_mri_common
+Mark a symbol as an MRI common symbol.
+
+@item symbol_clear_mri_common
+@cindex symbol_clear_mri_common
+Clear the mark indicating that a symbol is an MRI common symbol.
+
+@item symbol_mri_common_p
+@cindex symbol_mri_common_p
+Return whether a symbol is an MRI common symbol.
+
+@item symbol_mark_written
+@cindex symbol_mark_written
+Mark a symbol as having been written.
+
+@item symbol_clear_written
+@cindex symbol_clear_written
+Clear the mark indicating that a symbol was written.
+
+@item symbol_written_p
+@cindex symbol_written_p
+Return whether a symbol was written.
+
+@item symbol_mark_resolved
+@cindex symbol_mark_resolved
+Mark a symbol as having been resolved.
+
+@item symbol_resolved_p
+@cindex symbol_resolved_p
+Return whether a symbol has been resolved.
+
+@item symbol_section_p
+@cindex symbol_section_p
+Return whether a symbol is a section symbol.
+
+@item symbol_equated_p
+@cindex symbol_equated_p
+Return whether a symbol is equated to another symbol.
+
+@item symbol_constant_p
+@cindex symbol_constant_p
+Return whether a symbol has a constant value, including being an offset within
+some frag.
+
+@item symbol_get_bfdsym
+@cindex symbol_get_bfdsym
+Return the BFD symbol associated with a symbol.
+
+@item symbol_set_bfdsym
+@cindex symbol_set_bfdsym
+Set the BFD symbol associated with a symbol.
+
+@item symbol_get_obj
+@cindex symbol_get_obj
+Return a pointer to the @code{OBJ_SYMFIELD_TYPE} field of a symbol.
+
+@item symbol_set_obj
+@cindex symbol_set_obj
+Set the @code{OBJ_SYMFIELD_TYPE} field of a symbol.
+
+@item symbol_get_tc
+@cindex symbol_get_tc
+Return a pointer to the @code{TC_SYMFIELD_TYPE} field of a symbol.
+
+@item symbol_set_tc
+@cindex symbol_set_tc
+Set the @code{TC_SYMFIELD_TYPE} field of a symbol.
+
+@end table
+
+When @code{BFD_ASSEMBLER} is defined, GAS attempts to store local
+symbols--symbols which will not be written to the output file--using a
+different structure, @code{struct local_symbol}. This structure can only
+represent symbols whose value is an offset within a frag.
+
+Code outside of the symbol handler will always deal with @code{symbolS}
+structures and use the accessor functions. The accessor functions correctly
+deal with local symbols. @code{struct local_symbol} is much smaller than
+@code{symbolS} (which also automatically creates a bfd @code{asymbol}
+structure), so this saves space when assembling large files.
+
+The first field of @code{symbolS} is @code{bsym}, the pointer to the BFD
+symbol. The first field of @code{struct local_symbol} is a pointer which is
+always set to NULL. This is how the symbol accessor functions can distinguish
+local symbols from ordinary symbols. The symbol accessor functions
+automatically convert a local symbol into an ordinary symbol when necessary.
+
+@node Expressions
+@subsection Expressions
+@cindex internals, expressions
+@cindex expressions, internal
+@cindex expressionS structure
+
+Expressions are stored in an @code{expressionS} structure. The structure is
+defined in @file{expr.h}.
+
+@cindex expression
+The macro @code{expression} will create an @code{expressionS} structure based
+on the text found at the global variable @code{input_line_pointer}.
+
+@cindex make_expr_symbol
+@cindex expr_symbol_where
+A single @code{expressionS} structure can represent a single operation.
+Complex expressions are formed by creating @dfn{expression symbols} and
+combining them in @code{expressionS} structures. An expression symbol is
+created by calling @code{make_expr_symbol}. An expression symbol should
+naturally never appear in a symbol table, and the implementation of
+@code{S_IS_LOCAL} (@pxref{Symbols}) reflects that. The function
+@code{expr_symbol_where} returns non-zero if a symbol is an expression symbol,
+and also returns the file and line for the expression which caused it to be
+created.
+
+The @code{expressionS} structure has two symbol fields, a number field, an
+operator field, and a field indicating whether the number is unsigned.
+
+The operator field is of type @code{operatorT}, and describes how to interpret
+the other fields; see the definition in @file{expr.h} for the possibilities.
+
+An @code{operatorT} value of @code{O_big} indicates either a floating point
+number, stored in the global variable @code{generic_floating_point_number}, or
+an integer too large to store in an @code{offsetT} type, stored in the global
+array @code{generic_bignum}. This rather inflexible approach makes it
+impossible to use floating point numbers or large expressions in complex
+expressions.
+
+@node Fixups
+@subsection Fixups
+@cindex internals, fixups
+@cindex fixups
+@cindex fixS structure
+
+A @dfn{fixup} is basically anything which can not be resolved in the first
+pass. Sometimes a fixup can be resolved by the end of the assembly; if not,
+the fixup becomes a relocation entry in the object file.
+
+@cindex fix_new
+@cindex fix_new_exp
+A fixup is created by a call to @code{fix_new} or @code{fix_new_exp}. Both
+take a frag (@pxref{Frags}), a position within the frag, a size, an indication
+of whether the fixup is PC relative, and a type. In a @code{BFD_ASSEMBLER}
+GAS, the type is nominally a @code{bfd_reloc_code_real_type}, but several
+targets use other type codes to represent fixups that can not be described as
+relocations.
+
+The @code{fixS} structure has a number of fields, several of which are obsolete
+or are only used by a particular target. The important fields are:
+
+@table @code
+@item fx_frag
+The frag (@pxref{Frags}) this fixup is in.
+
+@item fx_where
+The location within the frag where the fixup occurs.
+
+@item fx_addsy
+The symbol this fixup is against. Typically, the value of this symbol is added
+into the object contents. This may be NULL.
+
+@item fx_subsy
+The value of this symbol is subtracted from the object contents. This is
+normally NULL.
+
+@item fx_offset
+A number which is added into the fixup.
+
+@item fx_addnumber
+Some CPU backends use this field to convey information between
+@code{md_apply_fix3} and @code{tc_gen_reloc}. The machine independent code does
+not use it.
+
+@item fx_next
+The next fixup in the section.
+
+@item fx_r_type
+The type of the fixup. This field is only defined if @code{BFD_ASSEMBLER}, or
+if the target defines @code{NEED_FX_R_TYPE}.
+
+@item fx_size
+The size of the fixup. This is mostly used for error checking.
+
+@item fx_pcrel
+Whether the fixup is PC relative.
+
+@item fx_done
+Non-zero if the fixup has been applied, and no relocation entry needs to be
+generated.
+
+@item fx_file
+@itemx fx_line
+The file and line where the fixup was created.
+
+@item tc_fix_data
+This has the type @code{TC_FIX_TYPE}, and is only defined if the target defines
+that macro.
+@end table
+
+@node Frags
+@subsection Frags
+@cindex internals, frags
+@cindex frags
+@cindex fragS structure.
+
+The @code{fragS} structure is defined in @file{as.h}. Each frag represents a
+portion of the final object file. As GAS reads the source file, it creates
+frags to hold the data that it reads. At the end of the assembly the frags and
+fixups are processed to produce the final contents.
+
+@table @code
+@item fr_address
+The address of the frag. This is not set until the assembler rescans the list
+of all frags after the entire input file is parsed. The function
+@code{relax_segment} fills in this field.
+
+@item fr_next
+Pointer to the next frag in this (sub)section.
+
+@item fr_fix
+Fixed number of characters we know we're going to emit to the output file. May
+be zero.
+
+@item fr_var
+Variable number of characters we may output, after the initial @code{fr_fix}
+characters. May be zero.
+
+@item fr_offset
+The interpretation of this field is controlled by @code{fr_type}. Generally,
+if @code{fr_var} is non-zero, this is a repeat count: the @code{fr_var}
+characters are output @code{fr_offset} times.
+
+@item line
+Holds line number info when an assembler listing was requested.
+
+@item fr_type
+Relaxation state. This field indicates the interpretation of @code{fr_offset},
+@code{fr_symbol} and the variable-length tail of the frag, as well as the
+treatment it gets in various phases of processing. It does not affect the
+initial @code{fr_fix} characters; they are always supposed to be output
+verbatim (fixups aside). See below for specific values this field can have.
+
+@item fr_subtype
+Relaxation substate. If the macro @code{md_relax_frag} isn't defined, this is
+assumed to be an index into @code{TC_GENERIC_RELAX_TABLE} for the generic
+relaxation code to process (@pxref{Relaxation}). If @code{md_relax_frag} is
+defined, this field is available for any use by the CPU-specific code.
+
+@item fr_symbol
+This normally indicates the symbol to use when relaxing the frag according to
+@code{fr_type}.
+
+@item fr_opcode
+Points to the lowest-addressed byte of the opcode, for use in relaxation.
+
+@item tc_frag_data
+Target specific fragment data of type TC_FRAG_TYPE.
+Only present if @code{TC_FRAG_TYPE} is defined.
+
+@item fr_file
+@itemx fr_line
+The file and line where this frag was last modified.
+
+@item fr_literal
+Declared as a one-character array, this last field grows arbitrarily large to
+hold the actual contents of the frag.
+@end table
+
+These are the possible relaxation states, provided in the enumeration type
+@code{relax_stateT}, and the interpretations they represent for the other
+fields:
+
+@table @code
+@item rs_align
+@itemx rs_align_code
+The start of the following frag should be aligned on some boundary. In this
+frag, @code{fr_offset} is the logarithm (base 2) of the alignment in bytes.
+(For example, if alignment on an 8-byte boundary were desired, @code{fr_offset}
+would have a value of 3.) The variable characters indicate the fill pattern to
+be used. The @code{fr_subtype} field holds the maximum number of bytes to skip
+when doing this alignment. If more bytes are needed, the alignment is not
+done. An @code{fr_subtype} value of 0 means no maximum, which is the normal
+case. Target backends can use @code{rs_align_code} to handle certain types of
+alignment differently.
+
+@item rs_broken_word
+This indicates that ``broken word'' processing should be done (@pxref{Broken
+words}). If broken word processing is not necessary on the target machine,
+this enumerator value will not be defined.
+
+@item rs_cfa
+This state is used to implement exception frame optimizations. The
+@code{fr_symbol} is an expression symbol for the subtraction which may be
+relaxed. The @code{fr_opcode} field holds the frag for the preceding command
+byte. The @code{fr_offset} field holds the offset within that frag. The
+@code{fr_subtype} field is used during relaxation to hold the current size of
+the frag.
+
+@item rs_fill
+The variable characters are to be repeated @code{fr_offset} times. If
+@code{fr_offset} is 0, this frag has a length of @code{fr_fix}. Most frags
+have this type.
+
+@item rs_leb128
+This state is used to implement the DWARF ``little endian base 128''
+variable length number format. The @code{fr_symbol} is always an expression
+symbol, as constant expressions are emitted directly. The @code{fr_offset}
+field is used during relaxation to hold the previous size of the number so
+that we can determine if the fragment changed size.
+
+@item rs_machine_dependent
+Displacement relaxation is to be done on this frag. The target is indicated by
+@code{fr_symbol} and @code{fr_offset}, and @code{fr_subtype} indicates the
+particular machine-specific addressing mode desired. @xref{Relaxation}.
+
+@item rs_org
+The start of the following frag should be pushed back to some specific offset
+within the section. (Some assemblers use the value as an absolute address; GAS
+does not handle final absolute addresses, but rather requires that the linker
+set them.) The offset is given by @code{fr_symbol} and @code{fr_offset}; one
+character from the variable-length tail is used as the fill character.
+@end table
+
+@cindex frchainS structure
+A chain of frags is built up for each subsection. The data structure
+describing a chain is called a @code{frchainS}, and contains the following
+fields:
+
+@table @code
+@item frch_root
+Points to the first frag in the chain. May be NULL if there are no frags in
+this chain.
+@item frch_last
+Points to the last frag in the chain, or NULL if there are none.
+@item frch_next
+Next in the list of @code{frchainS} structures.
+@item frch_seg
+Indicates the section this frag chain belongs to.
+@item frch_subseg
+Subsection (subsegment) number of this frag chain.
+@item fix_root, fix_tail
+(Defined only if @code{BFD_ASSEMBLER} is defined). Point to first and last
+@code{fixS} structures associated with this subsection.
+@item frch_obstack
+Not currently used. Intended to be used for frag allocation for this
+subsection. This should reduce frag generation caused by switching sections.
+@item frch_frag_now
+The current frag for this subsegment.
+@end table
+
+A @code{frchainS} corresponds to a subsection; each section has a list of
+@code{frchainS} records associated with it. In most cases, only one subsection
+of each section is used, so the list will only be one element long, but any
+processing of frag chains should be prepared to deal with multiple chains per
+section.
+
+After the input files have been completely processed, and no more frags are to
+be generated, the frag chains are joined into one per section for further
+processing. After this point, it is safe to operate on one chain per section.
+
+The assembler always has a current frag, named @code{frag_now}. More space is
+allocated for the current frag using the @code{frag_more} function; this
+returns a pointer to the amount of requested space. The function
+@code{frag_room} says by how much the current frag can be extended.
+Relaxing is done using variant frags allocated by @code{frag_var}
+or @code{frag_variant} (@pxref{Relaxation}).
+
+@node GAS processing
+@section What GAS does when it runs
+@cindex internals, overview
+
+This is a quick look at what an assembler run looks like.
+
+@itemize @bullet
+@item
+The assembler initializes itself by calling various init routines.
+
+@item
+For each source file, the @code{read_a_source_file} function reads in the file
+and parses it. The global variable @code{input_line_pointer} points to the
+current text; it is guaranteed to be correct up to the end of the line, but not
+farther.
+
+@item
+For each line, the assembler passes labels to the @code{colon} function, and
+isolates the first word. If it looks like a pseudo-op, the word is looked up
+in the pseudo-op hash table @code{po_hash} and dispatched to a pseudo-op
+routine. Otherwise, the target dependent @code{md_assemble} routine is called
+to parse the instruction.
+
+@item
+When pseudo-ops or instructions output data, they add it to a frag, calling
+@code{frag_more} to get space to store it in.
+
+@item
+Pseudo-ops and instructions can also output fixups created by @code{fix_new} or
+@code{fix_new_exp}.
+
+@item
+For certain targets, instructions can create variant frags which are used to
+store relaxation information (@pxref{Relaxation}).
+
+@item
+When the input file is finished, the @code{write_object_file} routine is
+called. It assigns addresses to all the frags (@code{relax_segment}), resolves
+all the fixups (@code{fixup_segment}), resolves all the symbol values (using
+@code{resolve_symbol_value}), and finally writes out the file (in the
+@code{BFD_ASSEMBLER} case, this is done by simply calling @code{bfd_close}).
+@end itemize
+
+@node Porting GAS
+@section Porting GAS
+@cindex porting
+
+Each GAS target specifies two main things: the CPU file and the object format
+file. Two main switches in the @file{configure.in} file handle this. The
+first switches on CPU type to set the shell variable @code{cpu_type}. The
+second switches on the entire target to set the shell variable @code{fmt}.
+
+The configure script uses the value of @code{cpu_type} to select two files in
+the @file{config} directory: @file{tc-@var{CPU}.c} and @file{tc-@var{CPU}.h}.
+The configuration process will create a file named @file{targ-cpu.h} in the
+build directory which includes @file{tc-@var{CPU}.h}.
+
+The configure script also uses the value of @code{fmt} to select two files:
+@file{obj-@var{fmt}.c} and @file{obj-@var{fmt}.h}. The configuration process
+will create a file named @file{obj-format.h} in the build directory which
+includes @file{obj-@var{fmt}.h}.
+
+You can also set the emulation in the configure script by setting the @code{em}
+variable. Normally the default value of @samp{generic} is fine. The
+configuration process will create a file named @file{targ-env.h} in the build
+directory which includes @file{te-@var{em}.h}.
+
+There is a special case for COFF. For historical reason, the GNU COFF
+assembler doesn't follow the documented behavior on certain debug symbols for
+the compatibility with other COFF assemblers. A port can define
+@code{STRICTCOFF} in the configure script to make the GNU COFF assembler
+to follow the documented behavior.
+
+Porting GAS to a new CPU requires writing the @file{tc-@var{CPU}} files.
+Porting GAS to a new object file format requires writing the
+@file{obj-@var{fmt}} files. There is sometimes some interaction between these
+two files, but it is normally minimal.
+
+The best approach is, of course, to copy existing files. The documentation
+below assumes that you are looking at existing files to see usage details.
+
+These interfaces have grown over time, and have never been carefully thought
+out or designed. Nothing about the interfaces described here is cast in stone.
+It is possible that they will change from one version of the assembler to the
+next. Also, new macros are added all the time as they are needed.
+
+@menu
+* CPU backend:: Writing a CPU backend
+* Object format backend:: Writing an object format backend
+* Emulations:: Writing emulation files
+@end menu
+
+@node CPU backend
+@subsection Writing a CPU backend
+@cindex CPU backend
+@cindex @file{tc-@var{CPU}}
+
+The CPU backend files are the heart of the assembler. They are the only parts
+of the assembler which actually know anything about the instruction set of the
+processor.
+
+You must define a reasonably small list of macros and functions in the CPU
+backend files. You may define a large number of additional macros in the CPU
+backend files, not all of which are documented here. You must, of course,
+define macros in the @file{.h} file, which is included by every assembler
+source file. You may define the functions as macros in the @file{.h} file, or
+as functions in the @file{.c} file.
+
+@table @code
+@item TC_@var{CPU}
+@cindex TC_@var{CPU}
+By convention, you should define this macro in the @file{.h} file. For
+example, @file{tc-m68k.h} defines @code{TC_M68K}. You might have to use this
+if it is necessary to add CPU specific code to the object format file.
+
+@item TARGET_FORMAT
+This macro is the BFD target name to use when creating the output file. This
+will normally depend upon the @code{OBJ_@var{FMT}} macro.
+
+@item TARGET_ARCH
+This macro is the BFD architecture to pass to @code{bfd_set_arch_mach}.
+
+@item TARGET_MACH
+This macro is the BFD machine number to pass to @code{bfd_set_arch_mach}. If
+it is not defined, GAS will use 0.
+
+@item TARGET_BYTES_BIG_ENDIAN
+You should define this macro to be non-zero if the target is big endian, and
+zero if the target is little endian.
+
+@item md_shortopts
+@itemx md_longopts
+@itemx md_longopts_size
+@itemx md_parse_option
+@itemx md_show_usage
+@itemx md_after_parse_args
+@cindex md_shortopts
+@cindex md_longopts
+@cindex md_longopts_size
+@cindex md_parse_option
+@cindex md_show_usage
+@cindex md_after_parse_args
+GAS uses these variables and functions during option processing.
+@code{md_shortopts} is a @code{const char *} which GAS adds to the machine
+independent string passed to @code{getopt}. @code{md_longopts} is a
+@code{struct option []} which GAS adds to the machine independent long options
+passed to @code{getopt}; you may use @code{OPTION_MD_BASE}, defined in
+@file{as.h}, as the start of a set of long option indices, if necessary.
+@code{md_longopts_size} is a @code{size_t} holding the size @code{md_longopts}.
+GAS will call @code{md_parse_option} whenever @code{getopt} returns an
+unrecognized code, presumably indicating a special code value which appears in
+@code{md_longopts}. GAS will call @code{md_show_usage} when a usage message is
+printed; it should print a description of the machine specific options.
+@code{md_after_pase_args}, if defined, is called after all options are
+processed, to let the backend override settings done by the generic option
+parsing.
+
+@item md_begin
+@cindex md_begin
+GAS will call this function at the start of the assembly, after the command
+line arguments have been parsed and all the machine independent initializations
+have been completed.
+
+@item md_cleanup
+@cindex md_cleanup
+If you define this macro, GAS will call it at the end of each input file.
+
+@item md_assemble
+@cindex md_assemble
+GAS will call this function for each input line which does not contain a
+pseudo-op. The argument is a null terminated string. The function should
+assemble the string as an instruction with operands. Normally
+@code{md_assemble} will do this by calling @code{frag_more} and writing out
+some bytes (@pxref{Frags}). @code{md_assemble} will call @code{fix_new} to
+create fixups as needed (@pxref{Fixups}). Targets which need to do special
+purpose relaxation will call @code{frag_var}.
+
+@item md_pseudo_table
+@cindex md_pseudo_table
+This is a const array of type @code{pseudo_typeS}. It is a mapping from
+pseudo-op names to functions. You should use this table to implement
+pseudo-ops which are specific to the CPU.
+
+@item tc_conditional_pseudoop
+@cindex tc_conditional_pseudoop
+If this macro is defined, GAS will call it with a @code{pseudo_typeS} argument.
+It should return non-zero if the pseudo-op is a conditional which controls
+whether code is assembled, such as @samp{.if}. GAS knows about the normal
+conditional pseudo-ops, and you should normally not have to define this macro.
+
+@item comment_chars
+@cindex comment_chars
+This is a null terminated @code{const char} array of characters which start a
+comment.
+
+@item tc_comment_chars
+@cindex tc_comment_chars
+If this macro is defined, GAS will use it instead of @code{comment_chars}.
+
+@item tc_symbol_chars
+@cindex tc_symbol_chars
+If this macro is defined, it is a pointer to a null terminated list of
+characters which may appear in an operand. GAS already assumes that all
+alphanumberic characters, and @samp{$}, @samp{.}, and @samp{_} may appear in an
+operand (see @samp{symbol_chars} in @file{app.c}). This macro may be defined
+to treat additional characters as appearing in an operand. This affects the
+way in which GAS removes whitespace before passing the string to
+@samp{md_assemble}.
+
+@item line_comment_chars
+@cindex line_comment_chars
+This is a null terminated @code{const char} array of characters which start a
+comment when they appear at the start of a line.
+
+@item line_separator_chars
+@cindex line_separator_chars
+This is a null terminated @code{const char} array of characters which separate
+lines (null and newline are such characters by default, and need not be
+listed in this array). Note that line_separator_chars do not separate lines
+if found in a comment, such as after a character in line_comment_chars or
+comment_chars.
+
+@item EXP_CHARS
+@cindex EXP_CHARS
+This is a null terminated @code{const char} array of characters which may be
+used as the exponent character in a floating point number. This is normally
+@code{"eE"}.
+
+@item FLT_CHARS
+@cindex FLT_CHARS
+This is a null terminated @code{const char} array of characters which may be
+used to indicate a floating point constant. A zero followed by one of these
+characters is assumed to be followed by a floating point number; thus they
+operate the way that @code{0x} is used to indicate a hexadecimal constant.
+Usually this includes @samp{r} and @samp{f}.
+
+@item LEX_AT
+@cindex LEX_AT
+You may define this macro to the lexical type of the @kbd{@@} character. The
+default is zero.
+
+Lexical types are a combination of @code{LEX_NAME} and @code{LEX_BEGIN_NAME},
+both defined in @file{read.h}. @code{LEX_NAME} indicates that the character
+may appear in a name. @code{LEX_BEGIN_NAME} indicates that the character may
+appear at the beginning of a name.
+
+@item LEX_BR
+@cindex LEX_BR
+You may define this macro to the lexical type of the brace characters @kbd{@{},
+@kbd{@}}, @kbd{[}, and @kbd{]}. The default value is zero.
+
+@item LEX_PCT
+@cindex LEX_PCT
+You may define this macro to the lexical type of the @kbd{%} character. The
+default value is zero.
+
+@item LEX_QM
+@cindex LEX_QM
+You may define this macro to the lexical type of the @kbd{?} character. The
+default value it zero.
+
+@item LEX_DOLLAR
+@cindex LEX_DOLLAR
+You may define this macro to the lexical type of the @kbd{$} character. The
+default value is @code{LEX_NAME | LEX_BEGIN_NAME}.
+
+@item NUMBERS_WITH_SUFFIX
+@cindex NUMBERS_WITH_SUFFIX
+When this macro is defined to be non-zero, the parser allows the radix of a
+constant to be indicated with a suffix. Valid suffixes are binary (B),
+octal (Q), and hexadecimal (H). Case is not significant.
+
+@item SINGLE_QUOTE_STRINGS
+@cindex SINGLE_QUOTE_STRINGS
+If you define this macro, GAS will treat single quotes as string delimiters.
+Normally only double quotes are accepted as string delimiters.
+
+@item NO_STRING_ESCAPES
+@cindex NO_STRING_ESCAPES
+If you define this macro, GAS will not permit escape sequences in a string.
+
+@item ONLY_STANDARD_ESCAPES
+@cindex ONLY_STANDARD_ESCAPES
+If you define this macro, GAS will warn about the use of nonstandard escape
+sequences in a string.
+
+@item md_start_line_hook
+@cindex md_start_line_hook
+If you define this macro, GAS will call it at the start of each line.
+
+@item LABELS_WITHOUT_COLONS
+@cindex LABELS_WITHOUT_COLONS
+If you define this macro, GAS will assume that any text at the start of a line
+is a label, even if it does not have a colon.
+
+@item TC_START_LABEL
+@itemx TC_START_LABEL_WITHOUT_COLON
+@cindex TC_START_LABEL
+You may define this macro to control what GAS considers to be a label. The
+default definition is to accept any name followed by a colon character.
+
+@item TC_START_LABEL_WITHOUT_COLON
+@cindex TC_START_LABEL_WITHOUT_COLON
+Same as TC_START_LABEL, but should be used instead of TC_START_LABEL when
+LABELS_WITHOUT_COLONS is defined.
+
+@item NO_PSEUDO_DOT
+@cindex NO_PSEUDO_DOT
+If you define this macro, GAS will not require pseudo-ops to start with a
+@kbd{.} character.
+
+@item TC_EQUAL_IN_INSN
+@cindex TC_EQUAL_IN_INSN
+If you define this macro, it should return nonzero if the instruction is
+permitted to contain an @kbd{=} character. GAS will call it with two
+arguments, the character before the @kbd{=} character, and the value of
+@code{input_line_pointer} at that point. GAS uses this macro to decide if a
+@kbd{=} is an assignment or an instruction.
+
+@item TC_EOL_IN_INSN
+@cindex TC_EOL_IN_INSN
+If you define this macro, it should return nonzero if the current input line
+pointer should be treated as the end of a line.
+
+@item TC_CASE_SENSITIVE
+@cindex TC_CASE_SENSITIVE
+Define this macro if instruction mnemonics and pseudos are case sensitive.
+The default is to have it undefined giving case insensitive names.
+
+@item md_parse_name
+@cindex md_parse_name
+If this macro is defined, GAS will call it for any symbol found in an
+expression. You can define this to handle special symbols in a special way.
+If a symbol always has a certain value, you should normally enter it in the
+symbol table, perhaps using @code{reg_section}.
+
+@item md_undefined_symbol
+@cindex md_undefined_symbol
+GAS will call this function when a symbol table lookup fails, before it
+creates a new symbol. Typically this would be used to supply symbols whose
+name or value changes dynamically, possibly in a context sensitive way.
+Predefined symbols with fixed values, such as register names or condition
+codes, are typically entered directly into the symbol table when @code{md_begin}
+is called. One argument is passed, a @code{char *} for the symbol.
+
+@item md_operand
+@cindex md_operand
+GAS will call this function with one argument, an @code{expressionS}
+pointer, for any expression that can not be recognized. When the function
+is called, @code{input_line_pointer} will point to the start of the
+expression.
+
+@item tc_unrecognized_line
+@cindex tc_unrecognized_line
+If you define this macro, GAS will call it when it finds a line that it can not
+parse.
+
+@item md_do_align
+@cindex md_do_align
+You may define this macro to handle an alignment directive. GAS will call it
+when the directive is seen in the input file. For example, the i386 backend
+uses this to generate efficient nop instructions of varying lengths, depending
+upon the number of bytes that the alignment will skip.
+
+@item HANDLE_ALIGN
+@cindex HANDLE_ALIGN
+You may define this macro to do special handling for an alignment directive.
+GAS will call it at the end of the assembly.
+
+@item TC_IMPLICIT_LCOMM_ALIGNMENT (@var{size}, @var{p2var})
+@cindex TC_IMPLICIT_LCOMM_ALIGNMENT
+An @code{.lcomm} directive with no explicit alignment parameter will use this
+macro to set @var{p2var} to the alignment that a request for @var{size} bytes
+will have. The alignment is expressed as a power of two. If no alignment
+should take place, the macro definition should do nothing. Some targets define
+a @code{.bss} directive that is also affected by this macro. The default
+definition will set @var{p2var} to the truncated power of two of sizes up to
+eight bytes.
+
+@item md_flush_pending_output
+@cindex md_flush_pending_output
+If you define this macro, GAS will call it each time it skips any space because of a
+space filling or alignment or data allocation pseudo-op.
+
+@item TC_PARSE_CONS_EXPRESSION
+@cindex TC_PARSE_CONS_EXPRESSION
+You may define this macro to parse an expression used in a data allocation
+pseudo-op such as @code{.word}. You can use this to recognize relocation
+directives that may appear in such directives.
+
+@item BITFIELD_CONS_EXPRESSION
+@cindex BITFIELD_CONS_EXPRESSION
+If you define this macro, GAS will recognize bitfield instructions in data
+allocation pseudo-ops, as used on the i960.
+
+@item REPEAT_CONS_EXPRESSION
+@cindex REPEAT_CONS_EXPRESSION
+If you define this macro, GAS will recognize repeat counts in data allocation
+pseudo-ops, as used on the MIPS.
+
+@item md_cons_align
+@cindex md_cons_align
+You may define this macro to do any special alignment before a data allocation
+pseudo-op.
+
+@item TC_CONS_FIX_NEW
+@cindex TC_CONS_FIX_NEW
+You may define this macro to generate a fixup for a data allocation pseudo-op.
+
+@item TC_INIT_FIX_DATA (@var{fixp})
+@cindex TC_INIT_FIX_DATA
+A C statement to initialize the target specific fields of fixup @var{fixp}.
+These fields are defined with the @code{TC_FIX_TYPE} macro.
+
+@item TC_FIX_DATA_PRINT (@var{stream}, @var{fixp})
+@cindex TC_FIX_DATA_PRINT
+A C statement to output target specific debugging information for
+fixup @var{fixp} to @var{stream}. This macro is called by @code{print_fixup}.
+
+@item TC_FRAG_INIT (@var{fragp})
+@cindex TC_FRAG_INIT
+A C statement to initialize the target specific fields of frag @var{fragp}.
+These fields are defined with the @code{TC_FRAG_TYPE} macro.
+
+@item md_number_to_chars
+@cindex md_number_to_chars
+This should just call either @code{number_to_chars_bigendian} or
+@code{number_to_chars_littleendian}, whichever is appropriate. On targets like
+the MIPS which support options to change the endianness, which function to call
+is a runtime decision. On other targets, @code{md_number_to_chars} can be a
+simple macro.
+
+@item md_atof (@var{type},@var{litP},@var{sizeP})
+@cindex md_atof
+This function is called to convert an ASCII string into a floating point value
+in format used by the CPU. It takes three arguments. The first is @var{type}
+which is a byte describing the type of floating point number to be created.
+Possible values are @var{'f'} or @var{'s'} for single precision, @var{'d'} or
+@var{'r'} for double precision and @var{'x'} or @var{'p'} for extended
+precision. Either lower or upper case versions of these letters can be used.
+
+The second parameter is @var{litP} which is a pointer to a byte array where the
+converted value should be stored. The third argument is @var{sizeP}, which is
+a pointer to a integer that should be filled in with the number of
+@var{LITTLENUM}s emitted into the byte array. (@var{LITTLENUM} is defined in
+gas/bignum.h). The function should return NULL upon success or an error string
+upon failure.
+
+@item TC_LARGEST_EXPONENT_IS_NORMAL
+@cindex TC_LARGEST_EXPONENT_IS_NORMAL (@var{precision})
+This macro is used only by @file{atof-ieee.c}. It should evaluate to true
+if floats of the given precision use the largest exponent for normal numbers
+instead of NaNs and infinities. @var{precision} is @samp{F_PRECISION} for
+single precision, @samp{D_PRECISION} for double precision, or
+@samp{X_PRECISION} for extended double precision.
+
+The macro has a default definition which returns 0 for all cases.
+
+@item md_reloc_size
+@cindex md_reloc_size
+This variable is only used in the original version of gas (not
+@code{BFD_ASSEMBLER} and not @code{MANY_SEGMENTS}). It holds the size of a
+relocation entry.
+
+@item WORKING_DOT_WORD
+@itemx md_short_jump_size
+@itemx md_long_jump_size
+@itemx md_create_short_jump
+@itemx md_create_long_jump
+@itemx TC_CHECK_ADJUSTED_BROKEN_DOT_WORD
+@cindex WORKING_DOT_WORD
+@cindex md_short_jump_size
+@cindex md_long_jump_size
+@cindex md_create_short_jump
+@cindex md_create_long_jump
+@cindex TC_CHECK_ADJUSTED_BROKEN_DOT_WORD
+If @code{WORKING_DOT_WORD} is defined, GAS will not do broken word processing
+(@pxref{Broken words}). Otherwise, you should set @code{md_short_jump_size} to
+the size of a short jump (a jump that is just long enough to jump around a
+number of long jumps) and @code{md_long_jump_size} to the size of a long jump
+(a jump that can go anywhere in the function). You should define
+@code{md_create_short_jump} to create a short jump around a number of long
+jumps, and define @code{md_create_long_jump} to create a long jump.
+If defined, the macro TC_CHECK_ADJUSTED_BROKEN_DOT_WORD will be called for each
+adjusted word just before the word is output. The macro takes two arguments,
+an @code{addressT} with the adjusted word and a pointer to the current
+@code{struct broken_word}.
+
+@item md_estimate_size_before_relax
+@cindex md_estimate_size_before_relax
+This function returns an estimate of the size of a @code{rs_machine_dependent}
+frag before any relaxing is done. It may also create any necessary
+relocations.
+
+@item md_relax_frag
+@cindex md_relax_frag
+This macro may be defined to relax a frag. GAS will call this with the
+segment, the frag, and the change in size of all previous frags;
+@code{md_relax_frag} should return the change in size of the frag.
+@xref{Relaxation}.
+
+@item TC_GENERIC_RELAX_TABLE
+@cindex TC_GENERIC_RELAX_TABLE
+If you do not define @code{md_relax_frag}, you may define
+@code{TC_GENERIC_RELAX_TABLE} as a table of @code{relax_typeS} structures. The
+machine independent code knows how to use such a table to relax PC relative
+references. See @file{tc-m68k.c} for an example. @xref{Relaxation}.
+
+@item md_prepare_relax_scan
+@cindex md_prepare_relax_scan
+If defined, it is a C statement that is invoked prior to scanning
+the relax table.
+
+@item LINKER_RELAXING_SHRINKS_ONLY
+@cindex LINKER_RELAXING_SHRINKS_ONLY
+If you define this macro, and the global variable @samp{linkrelax} is set
+(because of a command line option, or unconditionally in @code{md_begin}), a
+@samp{.align} directive will cause extra space to be allocated. The linker can
+then discard this space when relaxing the section.
+
+@item TC_LINKRELAX_FIXUP (@var{segT})
+@cindex TC_LINKRELAX_FIXUP
+If defined, this macro allows control over whether fixups for a
+given section will be processed when the @var{linkrelax} variable is
+set. The macro is given the N_TYPE bits for the section in its
+@var{segT} argument. If the macro evaluates to a non-zero value
+then the fixups will be converted into relocs, otherwise they will
+be passed to @var{md_apply_fix3} as normal.
+
+@item md_convert_frag
+@cindex md_convert_frag
+GAS will call this for each rs_machine_dependent fragment.
+The instruction is completed using the data from the relaxation pass.
+It may also create any necessary relocations.
+@xref{Relaxation}.
+
+@item TC_FINALIZE_SYMS_BEFORE_SIZE_SEG
+@cindex TC_FINALIZE_SYMS_BEFORE_SIZE_SEG
+Specifies the value to be assigned to @code{finalize_syms} before the function
+@code{size_segs} is called. Since @code{size_segs} calls @code{cvt_frag_to_fill}
+which can call @code{md_convert_frag}, this constant governs whether the symbols
+accessed in @code{md_convert_frag} will be fully resolved. In particular it
+governs whether local symbols will have been resolved, and had their frag
+information removed. Depending upon the processing performed by
+@code{md_convert_frag} the frag information may or may not be necessary, as may
+the resolved values of the symbols. The default value is 1.
+
+@item TC_VALIDATE_FIX (@var{fixP}, @var{seg}, @var{skip})
+@cindex TC_VALIDATE_FIX
+This macro is evaluated for each fixup (when @var{linkrelax} is not set).
+It may be used to change the fixup in @code{struct fix *@var{fixP}} before
+the generic code sees it, or to fully process the fixup. In the latter case,
+a @code{goto @var{skip}} will bypass the generic code.
+
+@item md_apply_fix3 (@var{fixP}, @var{valP}, @var{seg})
+@cindex md_apply_fix3
+GAS will call this for each fixup that passes the @code{TC_VALIDATE_FIX} test
+when @var{linkrelax} is not set. It should store the correct value in the
+object file. @code{struct fix *@var{fixP}} is the fixup @code{md_apply_fix3}
+is operating on. @code{valueT *@var{valP}} is the value to store into the
+object files, or at least is the generic code's best guess. Specifically,
+*@var{valP} is the value of the fixup symbol, perhaps modified by
+@code{MD_APPLY_SYM_VALUE}, plus @code{@var{fixP}->fx_offset} (symbol addend),
+less @code{MD_PCREL_FROM_SECTION} for pc-relative fixups.
+@code{segT @var{seg}} is the section the fix is in.
+@code{fixup_segment} performs a generic overflow check on *@var{valP} after
+@code{md_apply_fix3} returns. If the overflow check is relevant for the target
+machine, then @code{md_apply_fix3} should modify *@var{valP}, typically to the
+value stored in the object file.
+
+@item TC_FORCE_RELOCATION (@var{fix})
+@cindex TC_FORCE_RELOCATION
+If this macro returns non-zero, it guarantees that a relocation will be emitted
+even when the value can be resolved locally, as @code{fixup_segment} tries to
+reduce the number of relocations emitted. For example, a fixup expression
+against an absolute symbol will normally not require a reloc. If undefined,
+a default of @w{@code{(S_FORCE_RELOC ((@var{fix})->fx_addsy))}} is used.
+
+@item TC_FORCE_RELOCATION_ABS (@var{fix})
+@cindex TC_FORCE_RELOCATION_ABS
+Like @code{TC_FORCE_RELOCATION}, but used only for fixup expressions against an
+absolute symbol. If undefined, @code{TC_FORCE_RELOCATION} will be used.
+
+@item TC_FORCE_RELOCATION_LOCAL (@var{fix})
+@cindex TC_FORCE_RELOCATION_LOCAL
+Like @code{TC_FORCE_RELOCATION}, but used only for fixup expressions against a
+symbol in the current section. If undefined, fixups that are not
+@code{fx_pcrel} or @code{fx_plt} or for which @code{TC_FORCE_RELOCATION}
+returns non-zero, will emit relocs.
+
+@item TC_FORCE_RELOCATION_SUB_SAME (@var{fix}, @var{seg})
+@cindex TC_FORCE_RELOCATION_SUB_SAME
+This macro controls resolution of fixup expressions involving the
+difference of two symbols in the same section. If this macro returns zero,
+the subtrahend will be resolved and @code{fx_subsy} set to @code{NULL} for
+@code{md_apply_fix3}. If undefined, the default of
+@w{@code{! SEG_NORMAL (@var{seg}) || TC_FORCE_RELOCATION (@var{fix})}} will
+be used.
+
+@item TC_FORCE_RELOCATION_SUB_ABS (@var{fix})
+@cindex TC_FORCE_RELOCATION_SUB_ABS
+Like @code{TC_FORCE_RELOCATION_SUB_SAME}, but used when the subtrahend is an
+absolute symbol. If the macro is undefined a default of @code{0} is used.
+
+@item TC_FORCE_RELOCATION_SUB_LOCAL (@var{fix})
+@cindex TC_FORCE_RELOCATION_SUB_LOCAL
+Like @code{TC_FORCE_RELOCATION_SUB_ABS}, but the subtrahend is a symbol in the
+same section as the fixup.
+
+@item TC_VALIDATE_FIX_SUB (@var{fix})
+@cindex TC_VALIDATE_FIX_SUB
+This macro is evaluated for any fixup with a @code{fx_subsy} that
+@code{fixup_segment} cannot reduce to a number. If the macro returns
+@code{false} an error will be reported.
+
+@item MD_APPLY_SYM_VALUE (@var{fix})
+@cindex MD_APPLY_SYM_VALUE
+This macro controls whether the symbol value becomes part of the value passed
+to @code{md_apply_fix3}. If the macro is undefined, or returns non-zero, the
+symbol value will be included. For ELF, a suitable definition might simply be
+@code{0}, because ELF relocations don't include the symbol value in the addend.
+
+@item S_FORCE_RELOC (@var{sym}, @var{strict})
+@cindex S_FORCE_RELOC
+This macro (or function, for @code{BFD_ASSEMBLER} gas) returns true for symbols
+that should not be reduced to section symbols or eliminated from expressions,
+because they may be overridden by the linker. ie. for symbols that are
+undefined or common, and when @var{strict} is set, weak, or global (for ELF
+assemblers that support ELF shared library linking semantics).
+
+@item EXTERN_FORCE_RELOC
+@cindex EXTERN_FORCE_RELOC
+This macro controls whether @code{S_FORCE_RELOC} returns true for global
+symbols. If undefined, the default is @code{true} for ELF assemblers, and
+@code{false} for non-ELF.
+
+@item tc_gen_reloc
+@cindex tc_gen_reloc
+A @code{BFD_ASSEMBLER} GAS will call this to generate a reloc. GAS will pass
+the resulting reloc to @code{bfd_install_relocation}. This currently works
+poorly, as @code{bfd_install_relocation} often does the wrong thing, and
+instances of @code{tc_gen_reloc} have been written to work around the problems,
+which in turns makes it difficult to fix @code{bfd_install_relocation}.
+
+@item RELOC_EXPANSION_POSSIBLE
+@cindex RELOC_EXPANSION_POSSIBLE
+If you define this macro, it means that @code{tc_gen_reloc} may return multiple
+relocation entries for a single fixup. In this case, the return value of
+@code{tc_gen_reloc} is a pointer to a null terminated array.
+
+@item MAX_RELOC_EXPANSION
+@cindex MAX_RELOC_EXPANSION
+You must define this if @code{RELOC_EXPANSION_POSSIBLE} is defined; it
+indicates the largest number of relocs which @code{tc_gen_reloc} may return for
+a single fixup.
+
+@item tc_fix_adjustable
+@cindex tc_fix_adjustable
+You may define this macro to indicate whether a fixup against a locally defined
+symbol should be adjusted to be against the section symbol. It should return a
+non-zero value if the adjustment is acceptable.
+
+@item MD_PCREL_FROM_SECTION (@var{fixp}, @var{section})
+@cindex MD_PCREL_FROM_SECTION
+If you define this macro, it should return the position from which the PC
+relative adjustment for a PC relative fixup should be made. On many
+processors, the base of a PC relative instruction is the next instruction,
+so this macro would return the length of an instruction, plus the address of
+the PC relative fixup. The latter can be calculated as
+@var{fixp}->fx_where + @var{fixp}->fx_frag->fr_address .
+
+@item md_pcrel_from
+@cindex md_pcrel_from
+This is the default value of @code{MD_PCREL_FROM_SECTION}. The difference is
+that @code{md_pcrel_from} does not take a section argument.
+
+@item tc_frob_label
+@cindex tc_frob_label
+If you define this macro, GAS will call it each time a label is defined.
+
+@item md_section_align
+@cindex md_section_align
+GAS will call this function for each section at the end of the assembly, to
+permit the CPU backend to adjust the alignment of a section. The function
+must take two arguments, a @code{segT} for the section and a @code{valueT}
+for the size of the section, and return a @code{valueT} for the rounded
+size.
+
+@item md_macro_start
+@cindex md_macro_start
+If defined, GAS will call this macro when it starts to include a macro
+expansion. @code{macro_nest} indicates the current macro nesting level, which
+includes the one being expanded.
+
+@item md_macro_info
+@cindex md_macro_info
+If defined, GAS will call this macro after the macro expansion has been
+included in the input and after parsing the macro arguments. The single
+argument is a pointer to the macro processing's internal representation of the
+macro (macro_entry *), which includes expansion of the formal arguments.
+
+@item md_macro_end
+@cindex md_macro_end
+Complement to md_macro_start. If defined, it is called when finished
+processing an inserted macro expansion, just before decrementing macro_nest.
+
+@item DOUBLEBAR_PARALLEL
+@cindex DOUBLEBAR_PARALLEL
+Affects the preprocessor so that lines containing '||' don't have their
+whitespace stripped following the double bar. This is useful for targets that
+implement parallel instructions.
+
+@item KEEP_WHITE_AROUND_COLON
+@cindex KEEP_WHITE_AROUND_COLON
+Normally, whitespace is compressed and removed when, in the presence of the
+colon, the adjoining tokens can be distinguished. This option affects the
+preprocessor so that whitespace around colons is preserved. This is useful
+when colons might be removed from the input after preprocessing but before
+assembling, so that adjoining tokens can still be distinguished if there is
+whitespace, or concatenated if there is not.
+
+@item tc_frob_section
+@cindex tc_frob_section
+If you define this macro, a @code{BFD_ASSEMBLER} GAS will call it for each
+section at the end of the assembly.
+
+@item tc_frob_file_before_adjust
+@cindex tc_frob_file_before_adjust
+If you define this macro, GAS will call it after the symbol values are
+resolved, but before the fixups have been changed from local symbols to section
+symbols.
+
+@item tc_frob_symbol
+@cindex tc_frob_symbol
+If you define this macro, GAS will call it for each symbol. You can indicate
+that the symbol should not be included in the object file by defining this
+macro to set its second argument to a non-zero value.
+
+@item tc_frob_file
+@cindex tc_frob_file
+If you define this macro, GAS will call it after the symbol table has been
+completed, but before the relocations have been generated.
+
+@item tc_frob_file_after_relocs
+If you define this macro, GAS will call it after the relocs have been
+generated.
+
+@item md_post_relax_hook
+If you define this macro, GAS will call it after relaxing and sizing the
+segments.
+
+@item LISTING_HEADER
+A string to use on the header line of a listing. The default value is simply
+@code{"GAS LISTING"}.
+
+@item LISTING_WORD_SIZE
+The number of bytes to put into a word in a listing. This affects the way the
+bytes are clumped together in the listing. For example, a value of 2 might
+print @samp{1234 5678} where a value of 1 would print @samp{12 34 56 78}. The
+default value is 4.
+
+@item LISTING_LHS_WIDTH
+The number of words of data to print on the first line of a listing for a
+particular source line, where each word is @code{LISTING_WORD_SIZE} bytes. The
+default value is 1.
+
+@item LISTING_LHS_WIDTH_SECOND
+Like @code{LISTING_LHS_WIDTH}, but applying to the second and subsequent line
+of the data printed for a particular source line. The default value is 1.
+
+@item LISTING_LHS_CONT_LINES
+The maximum number of continuation lines to print in a listing for a particular
+source line. The default value is 4.
+
+@item LISTING_RHS_WIDTH
+The maximum number of characters to print from one line of the input file. The
+default value is 100.
+
+@item TC_COFF_SECTION_DEFAULT_ATTRIBUTES
+@cindex TC_COFF_SECTION_DEFAULT_ATTRIBUTES
+The COFF @code{.section} directive will use the value of this macro to set
+a new section's attributes when a directive has no valid flags or when the
+flag is @code{w}. The default value of the macro is @code{SEC_LOAD | SEC_DATA}.
+
+@item DWARF2_FORMAT ()
+@cindex DWARF2_FORMAT
+If you define this, it should return one of @code{dwarf2_format_32bit},
+@code{dwarf2_format_64bit}, or @code{dwarf2_format_64bit_irix} to indicate
+the size of internal DWARF section offsets and the format of the DWARF initial
+length fields. When @code{dwarf2_format_32bit} is returned, the initial
+length field will be 4 bytes long and section offsets are 32 bits in size.
+For @code{dwarf2_format_64bit} and @code{dwarf2_format_64bit_irix}, section
+offsets are 64 bits in size, but the initial length field differs. An 8 byte
+initial length is indicated by @code{dwarf2_format_64bit_irix} and
+@code{dwarf2_format_64bit} indicates a 12 byte initial length field in
+which the first four bytes are 0xffffffff and the next 8 bytes are
+the section's length.
+
+If you don't define this, @code{dwarf2_format_32bit} will be used as
+the default.
+
+This define only affects @code{.debug_info} and @code{.debug_line}
+sections generated by the assembler. DWARF 2 sections generated by
+other tools will be unaffected by this setting.
+
+@item DWARF2_ADDR_SIZE (@var{bfd})
+@cindex DWARF2_ADDR_SIZE
+It should return the size of an address, as it should be represented in
+debugging info. If you don't define this macro, the default definition uses
+the number of bits per address, as defined in @var{bfd}, divided by 8.
+
+@end table
+
+@node Object format backend
+@subsection Writing an object format backend
+@cindex object format backend
+@cindex @file{obj-@var{fmt}}
+
+As with the CPU backend, the object format backend must define a few things,
+and may define some other things. The interface to the object format backend
+is generally simpler; most of the support for an object file format consists of
+defining a number of pseudo-ops.
+
+The object format @file{.h} file must include @file{targ-cpu.h}.
+
+This section will only define the @code{BFD_ASSEMBLER} version of GAS. It is
+impossible to support a new object file format using any other version anyhow,
+as the original GAS version only supports a.out, and the @code{MANY_SEGMENTS}
+GAS version only supports COFF.
+
+@table @code
+@item OBJ_@var{format}
+@cindex OBJ_@var{format}
+By convention, you should define this macro in the @file{.h} file. For
+example, @file{obj-elf.h} defines @code{OBJ_ELF}. You might have to use this
+if it is necessary to add object file format specific code to the CPU file.
+
+@item obj_begin
+If you define this macro, GAS will call it at the start of the assembly, after
+the command line arguments have been parsed and all the machine independent
+initializations have been completed.
+
+@item obj_app_file
+@cindex obj_app_file
+If you define this macro, GAS will invoke it when it sees a @code{.file}
+pseudo-op or a @samp{#} line as used by the C preprocessor.
+
+@item OBJ_COPY_SYMBOL_ATTRIBUTES
+@cindex OBJ_COPY_SYMBOL_ATTRIBUTES
+You should define this macro to copy object format specific information from
+one symbol to another. GAS will call it when one symbol is equated to
+another.
+
+@item obj_sec_sym_ok_for_reloc
+@cindex obj_sec_sym_ok_for_reloc
+You may define this macro to indicate that it is OK to use a section symbol in
+a relocation entry. If it is not, GAS will define a new symbol at the start
+of a section.
+
+@item EMIT_SECTION_SYMBOLS
+@cindex EMIT_SECTION_SYMBOLS
+You should define this macro with a zero value if you do not want to include
+section symbols in the output symbol table. The default value for this macro
+is one.
+
+@item obj_adjust_symtab
+@cindex obj_adjust_symtab
+If you define this macro, GAS will invoke it just before setting the symbol
+table of the output BFD. For example, the COFF support uses this macro to
+generate a @code{.file} symbol if none was generated previously.
+
+@item SEPARATE_STAB_SECTIONS
+@cindex SEPARATE_STAB_SECTIONS
+You may define this macro to a nonzero value to indicate that stabs should be
+placed in separate sections, as in ELF.
+
+@item INIT_STAB_SECTION
+@cindex INIT_STAB_SECTION
+You may define this macro to initialize the stabs section in the output file.
+
+@item OBJ_PROCESS_STAB
+@cindex OBJ_PROCESS_STAB
+You may define this macro to do specific processing on a stabs entry.
+
+@item obj_frob_section
+@cindex obj_frob_section
+If you define this macro, GAS will call it for each section at the end of the
+assembly.
+
+@item obj_frob_file_before_adjust
+@cindex obj_frob_file_before_adjust
+If you define this macro, GAS will call it after the symbol values are
+resolved, but before the fixups have been changed from local symbols to section
+symbols.
+
+@item obj_frob_symbol
+@cindex obj_frob_symbol
+If you define this macro, GAS will call it for each symbol. You can indicate
+that the symbol should not be included in the object file by defining this
+macro to set its second argument to a non-zero value.
+
+@item obj_frob_file
+@cindex obj_frob_file
+If you define this macro, GAS will call it after the symbol table has been
+completed, but before the relocations have been generated.
+
+@item obj_frob_file_after_relocs
+If you define this macro, GAS will call it after the relocs have been
+generated.
+
+@item SET_SECTION_RELOCS (@var{sec}, @var{relocs}, @var{n})
+@cindex SET_SECTION_RELOCS
+If you define this, it will be called after the relocations have been set for
+the section @var{sec}. The list of relocations is in @var{relocs}, and the
+number of relocations is in @var{n}. This is only used with
+@code{BFD_ASSEMBLER}.
+@end table
+
+@node Emulations
+@subsection Writing emulation files
+
+Normally you do not have to write an emulation file. You can just use
+@file{te-generic.h}.
+
+If you do write your own emulation file, it must include @file{obj-format.h}.
+
+An emulation file will often define @code{TE_@var{EM}}; this may then be used
+in other files to change the output.
+
+@node Relaxation
+@section Relaxation
+@cindex relaxation
+
+@dfn{Relaxation} is a generic term used when the size of some instruction or
+data depends upon the value of some symbol or other data.
+
+GAS knows to relax a particular type of PC relative relocation using a table.
+You can also define arbitrarily complex forms of relaxation yourself.
+
+@menu
+* Relaxing with a table:: Relaxing with a table
+* General relaxing:: General relaxing
+@end menu
+
+@node Relaxing with a table
+@subsection Relaxing with a table
+
+If you do not define @code{md_relax_frag}, and you do define
+@code{TC_GENERIC_RELAX_TABLE}, GAS will relax @code{rs_machine_dependent} frags
+based on the frag subtype and the displacement to some specified target
+address. The basic idea is that several machines have different addressing
+modes for instructions that can specify different ranges of values, with
+successive modes able to access wider ranges, including the entirety of the
+previous range. Smaller ranges are assumed to be more desirable (perhaps the
+instruction requires one word instead of two or three); if this is not the
+case, don't describe the smaller-range, inferior mode.
+
+The @code{fr_subtype} field of a frag is an index into a CPU-specific
+relaxation table. That table entry indicates the range of values that can be
+stored, the number of bytes that will have to be added to the frag to
+accommodate the addressing mode, and the index of the next entry to examine if
+the value to be stored is outside the range accessible by the current
+addressing mode. The @code{fr_symbol} field of the frag indicates what symbol
+is to be accessed; the @code{fr_offset} field is added in.
+
+If the @code{TC_PCREL_ADJUST} macro is defined, which currently should only happen
+for the NS32k family, the @code{TC_PCREL_ADJUST} macro is called on the frag to
+compute an adjustment to be made to the displacement.
+
+The value fitted by the relaxation code is always assumed to be a displacement
+from the current frag. (More specifically, from @code{fr_fix} bytes into the
+frag.)
+@ignore
+This seems kinda silly. What about fitting small absolute values? I suppose
+@code{md_assemble} is supposed to take care of that, but if the operand is a
+difference between symbols, it might not be able to, if the difference was not
+computable yet.
+@end ignore
+
+The end of the relaxation sequence is indicated by a ``next'' value of 0. This
+means that the first entry in the table can't be used.
+
+For some configurations, the linker can do relaxing within a section of an
+object file. If call instructions of various sizes exist, the linker can
+determine which should be used in each instance, when a symbol's value is
+resolved. In order for the linker to avoid wasting space and having to insert
+no-op instructions, it must be able to expand or shrink the section contents
+while still preserving intra-section references and meeting alignment
+requirements.
+
+For the i960 using b.out format, no expansion is done; instead, each
+@samp{.align} directive causes extra space to be allocated, enough that when
+the linker is relaxing a section and removing unneeded space, it can discard
+some or all of this extra padding and cause the following data to be correctly
+aligned.
+
+For the H8/300, I think the linker expands calls that can't reach, and doesn't
+worry about alignment issues; the cpu probably never needs any significant
+alignment beyond the instruction size.
+
+The relaxation table type contains these fields:
+
+@table @code
+@item long rlx_forward
+Forward reach, must be non-negative.
+@item long rlx_backward
+Backward reach, must be zero or negative.
+@item rlx_length
+Length in bytes of this addressing mode.
+@item rlx_more
+Index of the next-longer relax state, or zero if there is no next relax state.
+@end table
+
+The relaxation is done in @code{relax_segment} in @file{write.c}. The
+difference in the length fields between the original mode and the one finally
+chosen by the relaxing code is taken as the size by which the current frag will
+be increased in size. For example, if the initial relaxing mode has a length
+of 2 bytes, and because of the size of the displacement, it gets upgraded to a
+mode with a size of 6 bytes, it is assumed that the frag will grow by 4 bytes.
+(The initial two bytes should have been part of the fixed portion of the frag,
+since it is already known that they will be output.) This growth must be
+effected by @code{md_convert_frag}; it should increase the @code{fr_fix} field
+by the appropriate size, and fill in the appropriate bytes of the frag.
+(Enough space for the maximum growth should have been allocated in the call to
+frag_var as the second argument.)
+
+If relocation records are needed, they should be emitted by
+@code{md_estimate_size_before_relax}. This function should examine the target
+symbol of the supplied frag and correct the @code{fr_subtype} of the frag if
+needed. When this function is called, if the symbol has not yet been defined,
+it will not become defined later; however, its value may still change if the
+section it is in gets relaxed.
+
+Usually, if the symbol is in the same section as the frag (given by the
+@var{sec} argument), the narrowest likely relaxation mode is stored in
+@code{fr_subtype}, and that's that.
+
+If the symbol is undefined, or in a different section (and therefore movable
+to an arbitrarily large distance), the largest available relaxation mode is
+specified, @code{fix_new} is called to produce the relocation record,
+@code{fr_fix} is increased to include the relocated field (remember, this
+storage was allocated when @code{frag_var} was called), and @code{frag_wane} is
+called to convert the frag to an @code{rs_fill} frag with no variant part.
+Sometimes changing addressing modes may also require rewriting the instruction.
+It can be accessed via @code{fr_opcode} or @code{fr_fix}.
+
+If you generate frags separately for the basic insn opcode and any relaxable
+operands, do not call @code{fix_new} thinking you can emit fixups for the
+opcode field from the relaxable frag. It is not guaranteed to be the same frag.
+If you need to emit fixups for the opcode field from inspection of the
+relaxable frag, then you need to generate a common frag for both the basic
+opcode and relaxable fields, or you need to provide the frag for the opcode to
+pass to @code{fix_new}. The latter can be done for example by defining
+@code{TC_FRAG_TYPE} to include a pointer to it and defining @code{TC_FRAG_INIT}
+to set the pointer.
+
+Sometimes @code{fr_var} is increased instead, and @code{frag_wane} is not
+called. I'm not sure, but I think this is to keep @code{fr_fix} referring to
+an earlier byte, and @code{fr_subtype} set to @code{rs_machine_dependent} so
+that @code{md_convert_frag} will get called.
+
+@node General relaxing
+@subsection General relaxing
+
+If using a simple table is not suitable, you may implement arbitrarily complex
+relaxation semantics yourself. For example, the MIPS backend uses this to emit
+different instruction sequences depending upon the size of the symbol being
+accessed.
+
+When you assemble an instruction that may need relaxation, you should allocate
+a frag using @code{frag_var} or @code{frag_variant} with a type of
+@code{rs_machine_dependent}. You should store some sort of information in the
+@code{fr_subtype} field so that you can figure out what to do with the frag
+later.
+
+When GAS reaches the end of the input file, it will look through the frags and
+work out their final sizes.
+
+GAS will first call @code{md_estimate_size_before_relax} on each
+@code{rs_machine_dependent} frag. This function must return an estimated size
+for the frag.
+
+GAS will then loop over the frags, calling @code{md_relax_frag} on each
+@code{rs_machine_dependent} frag. This function should return the change in
+size of the frag. GAS will keep looping over the frags until none of the frags
+changes size.
+
+@node Broken words
+@section Broken words
+@cindex internals, broken words
+@cindex broken words
+
+Some compilers, including GCC, will sometimes emit switch tables specifying
+16-bit @code{.word} displacements to branch targets, and branch instructions
+that load entries from that table to compute the target address. If this is
+done on a 32-bit machine, there is a chance (at least with really large
+functions) that the displacement will not fit in 16 bits. The assembler
+handles this using a concept called @dfn{broken words}. This idea is well
+named, since there is an implied promise that the 16-bit field will in fact
+hold the specified displacement.
+
+If broken word processing is enabled, and a situation like this is encountered,
+the assembler will insert a jump instruction into the instruction stream, close
+enough to be reached with the 16-bit displacement. This jump instruction will
+transfer to the real desired target address. Thus, as long as the @code{.word}
+value really is used as a displacement to compute an address to jump to, the
+net effect will be correct (minus a very small efficiency cost). If
+@code{.word} directives with label differences for values are used for other
+purposes, however, things may not work properly. For targets which use broken
+words, the @samp{-K} option will warn when a broken word is discovered.
+
+The broken word code is turned off by the @code{WORKING_DOT_WORD} macro. It
+isn't needed if @code{.word} emits a value large enough to contain an address
+(or, more correctly, any possible difference between two addresses).
+
+@node Internal functions
+@section Internal functions
+
+This section describes basic internal functions used by GAS.
+
+@menu
+* Warning and error messages:: Warning and error messages
+* Hash tables:: Hash tables
+@end menu
+
+@node Warning and error messages
+@subsection Warning and error messages
+
+@deftypefun @{@} int had_warnings (void)
+@deftypefunx @{@} int had_errors (void)
+Returns non-zero if any warnings or errors, respectively, have been printed
+during this invocation.
+@end deftypefun
+
+@deftypefun @{@} void as_perror (const char *@var{gripe}, const char *@var{filename})
+Displays a BFD or system error, then clears the error status.
+@end deftypefun
+
+@deftypefun @{@} void as_tsktsk (const char *@var{format}, ...)
+@deftypefunx @{@} void as_warn (const char *@var{format}, ...)
+@deftypefunx @{@} void as_bad (const char *@var{format}, ...)
+@deftypefunx @{@} void as_fatal (const char *@var{format}, ...)
+These functions display messages about something amiss with the input file, or
+internal problems in the assembler itself. The current file name and line
+number are printed, followed by the supplied message, formatted using
+@code{vfprintf}, and a final newline.
+
+An error indicated by @code{as_bad} will result in a non-zero exit status when
+the assembler has finished. Calling @code{as_fatal} will result in immediate
+termination of the assembler process.
+@end deftypefun
+
+@deftypefun @{@} void as_warn_where (char *@var{file}, unsigned int @var{line}, const char *@var{format}, ...)
+@deftypefunx @{@} void as_bad_where (char *@var{file}, unsigned int @var{line}, const char *@var{format}, ...)
+These variants permit specification of the file name and line number, and are
+used when problems are detected when reprocessing information saved away when
+processing some earlier part of the file. For example, fixups are processed
+after all input has been read, but messages about fixups should refer to the
+original filename and line number that they are applicable to.
+@end deftypefun
+
+@deftypefun @{@} void fprint_value (FILE *@var{file}, valueT @var{val})
+@deftypefunx @{@} void sprint_value (char *@var{buf}, valueT @var{val})
+These functions are helpful for converting a @code{valueT} value into printable
+format, in case it's wider than modes that @code{*printf} can handle. If the
+type is narrow enough, a decimal number will be produced; otherwise, it will be
+in hexadecimal. The value itself is not examined to make this determination.
+@end deftypefun
+
+@node Hash tables
+@subsection Hash tables
+@cindex hash tables
+
+@deftypefun @{@} @{struct hash_control *@} hash_new (void)
+Creates the hash table control structure.
+@end deftypefun
+
+@deftypefun @{@} void hash_die (struct hash_control *)
+Destroy a hash table.
+@end deftypefun
+
+@deftypefun @{@} PTR hash_delete (struct hash_control *, const char *)
+Deletes entry from the hash table, returns the value it had.
+@end deftypefun
+
+@deftypefun @{@} PTR hash_replace (struct hash_control *, const char *, PTR)
+Updates the value for an entry already in the table, returning the old value.
+If no entry was found, just returns NULL.
+@end deftypefun
+
+@deftypefun @{@} @{const char *@} hash_insert (struct hash_control *, const char *, PTR)
+Inserting a value already in the table is an error.
+Returns an error message or NULL.
+@end deftypefun
+
+@deftypefun @{@} @{const char *@} hash_jam (struct hash_control *, const char *, PTR)
+Inserts if the value isn't already present, updates it if it is.
+@end deftypefun
+
+@node Test suite
+@section Test suite
+@cindex test suite
+
+The test suite is kind of lame for most processors. Often it only checks to
+see if a couple of files can be assembled without the assembler reporting any
+errors. For more complete testing, write a test which either examines the
+assembler listing, or runs @code{objdump} and examines its output. For the
+latter, the TCL procedure @code{run_dump_test} may come in handy. It takes the
+base name of a file, and looks for @file{@var{file}.d}. This file should
+contain as its initial lines a set of variable settings in @samp{#} comments,
+in the form:
+
+@example
+ #@var{varname}: @var{value}
+@end example
+
+The @var{varname} may be @code{objdump}, @code{nm}, or @code{as}, in which case
+it specifies the options to be passed to the specified programs. Exactly one
+of @code{objdump} or @code{nm} must be specified, as that also specifies which
+program to run after the assembler has finished. If @var{varname} is
+@code{source}, it specifies the name of the source file; otherwise,
+@file{@var{file}.s} is used. If @var{varname} is @code{name}, it specifies the
+name of the test to be used in the @code{pass} or @code{fail} messages.
+
+The non-commented parts of the file are interpreted as regular expressions, one
+per line. Blank lines in the @code{objdump} or @code{nm} output are skipped,
+as are blank lines in the @code{.d} file; the other lines are tested to see if
+the regular expression matches the program output. If it does not, the test
+fails.
+
+Note that this means the tests must be modified if the @code{objdump} output
+style is changed.
+
+@bye
+@c Local Variables:
+@c fill-column: 79
+@c End:
diff --git a/x/binutils/gas/dw2gencfi.c b/x/binutils/gas/dw2gencfi.c
new file mode 100644
index 0000000..ff0aa35
--- /dev/null
+++ b/x/binutils/gas/dw2gencfi.c
@@ -0,0 +1,1042 @@
+/* dw2gencfi.c - Support for generating Dwarf2 CFI information.
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Michal Ludvig <mludvig@suse.cz>
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+#include "dw2gencfi.h"
+
+
+/* We re-use DWARF2_LINE_MIN_INSN_LENGTH for the code alignment field
+ of the CIE. Default to 1 if not otherwise specified. */
+#ifndef DWARF2_LINE_MIN_INSN_LENGTH
+# define DWARF2_LINE_MIN_INSN_LENGTH 1
+#endif
+
+/* If TARGET_USE_CFIPOP is defined, it is required that the target
+ provide the following definitions. Otherwise provide them to
+ allow compilation to continue. */
+#ifndef TARGET_USE_CFIPOP
+# ifndef DWARF2_DEFAULT_RETURN_COLUMN
+# define DWARF2_DEFAULT_RETURN_COLUMN 0
+# endif
+# ifndef DWARF2_CIE_DATA_ALIGNMENT
+# define DWARF2_CIE_DATA_ALIGNMENT 1
+# endif
+#endif
+
+#ifndef EH_FRAME_ALIGNMENT
+# ifdef BFD_ASSEMBLER
+# define EH_FRAME_ALIGNMENT (bfd_get_arch_size (stdoutput) == 64 ? 3 : 2)
+# else
+# define EH_FRAME_ALIGNMENT 2
+# endif
+#endif
+
+#ifndef tc_cfi_frame_initial_instructions
+# define tc_cfi_frame_initial_instructions() ((void)0)
+#endif
+
+
+struct cfi_insn_data
+{
+ struct cfi_insn_data *next;
+ int insn;
+ union {
+ struct {
+ unsigned reg;
+ offsetT offset;
+ } ri;
+
+ struct {
+ unsigned reg1;
+ unsigned reg2;
+ } rr;
+
+ unsigned r;
+ offsetT i;
+
+ struct {
+ symbolS *lab1;
+ symbolS *lab2;
+ } ll;
+
+ struct cfi_escape_data {
+ struct cfi_escape_data *next;
+ expressionS exp;
+ } *esc;
+ } u;
+};
+
+struct fde_entry
+{
+ struct fde_entry *next;
+ symbolS *start_address;
+ symbolS *end_address;
+ struct cfi_insn_data *data;
+ struct cfi_insn_data **last;
+ unsigned int return_column;
+};
+
+struct cie_entry
+{
+ struct cie_entry *next;
+ symbolS *start_address;
+ unsigned int return_column;
+ struct cfi_insn_data *first, *last;
+};
+
+
+/* Current open FDE entry. */
+static struct fde_entry *cur_fde_data;
+static symbolS *last_address;
+static offsetT cur_cfa_offset;
+
+/* List of FDE entries. */
+static struct fde_entry *all_fde_data;
+static struct fde_entry **last_fde_data = &all_fde_data;
+
+/* List of CIEs so that they could be reused. */
+static struct cie_entry *cie_root;
+
+/* Stack of old CFI data, for save/restore. */
+struct cfa_save_data
+{
+ struct cfa_save_data *next;
+ offsetT cfa_offset;
+};
+
+static struct cfa_save_data *cfa_save_stack;
+
+/* Construct a new FDE structure and add it to the end of the fde list. */
+
+static struct fde_entry *
+alloc_fde_entry (void)
+{
+ struct fde_entry *fde = xcalloc (1, sizeof (struct fde_entry));
+
+ cur_fde_data = fde;
+ *last_fde_data = fde;
+ last_fde_data = &fde->next;
+
+ fde->last = &fde->data;
+ fde->return_column = DWARF2_DEFAULT_RETURN_COLUMN;
+
+ return fde;
+}
+
+/* The following functions are available for a backend to construct its
+ own unwind information, usually from legacy unwind directives. */
+
+/* Construct a new INSN structure and add it to the end of the insn list
+ for the currently active FDE. */
+
+static struct cfi_insn_data *
+alloc_cfi_insn_data (void)
+{
+ struct cfi_insn_data *insn = xcalloc (1, sizeof (struct cfi_insn_data));
+
+ *cur_fde_data->last = insn;
+ cur_fde_data->last = &insn->next;
+
+ return insn;
+}
+
+/* Construct a new FDE structure that begins at LABEL. */
+
+void
+cfi_new_fde (symbolS *label)
+{
+ struct fde_entry *fde = alloc_fde_entry ();
+ fde->start_address = label;
+ last_address = label;
+}
+
+/* End the currently open FDE. */
+
+void
+cfi_end_fde (symbolS *label)
+{
+ cur_fde_data->end_address = label;
+ cur_fde_data = NULL;
+}
+
+/* Set the return column for the current FDE. */
+
+void
+cfi_set_return_column (unsigned regno)
+{
+ cur_fde_data->return_column = regno;
+}
+
+/* Universal functions to store new instructions. */
+
+static void
+cfi_add_CFA_insn(int insn)
+{
+ struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
+
+ insn_ptr->insn = insn;
+}
+
+static void
+cfi_add_CFA_insn_reg (int insn, unsigned regno)
+{
+ struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
+
+ insn_ptr->insn = insn;
+ insn_ptr->u.r = regno;
+}
+
+static void
+cfi_add_CFA_insn_offset (int insn, offsetT offset)
+{
+ struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
+
+ insn_ptr->insn = insn;
+ insn_ptr->u.i = offset;
+}
+
+static void
+cfi_add_CFA_insn_reg_reg (int insn, unsigned reg1, unsigned reg2)
+{
+ struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
+
+ insn_ptr->insn = insn;
+ insn_ptr->u.rr.reg1 = reg1;
+ insn_ptr->u.rr.reg2 = reg2;
+}
+
+static void
+cfi_add_CFA_insn_reg_offset (int insn, unsigned regno, offsetT offset)
+{
+ struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
+
+ insn_ptr->insn = insn;
+ insn_ptr->u.ri.reg = regno;
+ insn_ptr->u.ri.offset = offset;
+}
+
+/* Add a CFI insn to advance the PC from the last address to LABEL. */
+
+void
+cfi_add_advance_loc (symbolS *label)
+{
+ struct cfi_insn_data *insn = alloc_cfi_insn_data ();
+
+ insn->insn = DW_CFA_advance_loc;
+ insn->u.ll.lab1 = last_address;
+ insn->u.ll.lab2 = label;
+
+ last_address = label;
+}
+
+/* Add a DW_CFA_offset record to the CFI data. */
+
+void
+cfi_add_CFA_offset (unsigned regno, offsetT offset)
+{
+ unsigned int abs_data_align;
+
+ cfi_add_CFA_insn_reg_offset (DW_CFA_offset, regno, offset);
+
+ abs_data_align = (DWARF2_CIE_DATA_ALIGNMENT < 0
+ ? -DWARF2_CIE_DATA_ALIGNMENT : DWARF2_CIE_DATA_ALIGNMENT);
+ if (offset % abs_data_align)
+ as_bad (_("register save offset not a multiple of %u"), abs_data_align);
+}
+
+/* Add a DW_CFA_def_cfa record to the CFI data. */
+
+void
+cfi_add_CFA_def_cfa (unsigned regno, offsetT offset)
+{
+ cfi_add_CFA_insn_reg_offset (DW_CFA_def_cfa, regno, offset);
+ cur_cfa_offset = offset;
+}
+
+/* Add a DW_CFA_register record to the CFI data. */
+
+void
+cfi_add_CFA_register (unsigned reg1, unsigned reg2)
+{
+ cfi_add_CFA_insn_reg_reg (DW_CFA_register, reg1, reg2);
+}
+
+/* Add a DW_CFA_def_cfa_register record to the CFI data. */
+
+void
+cfi_add_CFA_def_cfa_register (unsigned regno)
+{
+ cfi_add_CFA_insn_reg (DW_CFA_def_cfa_register, regno);
+}
+
+/* Add a DW_CFA_def_cfa_offset record to the CFI data. */
+
+void
+cfi_add_CFA_def_cfa_offset (offsetT offset)
+{
+ cfi_add_CFA_insn_offset (DW_CFA_def_cfa_offset, offset);
+ cur_cfa_offset = offset;
+}
+
+void
+cfi_add_CFA_restore (unsigned regno)
+{
+ cfi_add_CFA_insn_reg (DW_CFA_restore, regno);
+}
+
+void
+cfi_add_CFA_undefined (unsigned regno)
+{
+ cfi_add_CFA_insn_reg (DW_CFA_undefined, regno);
+}
+
+void
+cfi_add_CFA_same_value (unsigned regno)
+{
+ cfi_add_CFA_insn_reg (DW_CFA_same_value, regno);
+}
+
+void
+cfi_add_CFA_remember_state (void)
+{
+ struct cfa_save_data *p;
+
+ cfi_add_CFA_insn (DW_CFA_remember_state);
+
+ p = xmalloc (sizeof (*p));
+ p->cfa_offset = cur_cfa_offset;
+ p->next = cfa_save_stack;
+ cfa_save_stack = p;
+}
+
+void
+cfi_add_CFA_restore_state (void)
+{
+ struct cfa_save_data *p;
+
+ cfi_add_CFA_insn (DW_CFA_restore_state);
+
+ p = cfa_save_stack;
+ if (p)
+ {
+ cur_cfa_offset = p->cfa_offset;
+ cfa_save_stack = p->next;
+ free (p);
+ }
+}
+
+
+/* Parse CFI assembler directives. */
+
+static void dot_cfi (int);
+static void dot_cfi_escape (int);
+static void dot_cfi_startproc (int);
+static void dot_cfi_endproc (int);
+
+/* Fake CFI type; outside the byte range of any real CFI insn. */
+#define CFI_adjust_cfa_offset 0x100
+#define CFI_return_column 0x101
+#define CFI_rel_offset 0x102
+#define CFI_escape 0x103
+
+const pseudo_typeS cfi_pseudo_table[] =
+ {
+ { "cfi_startproc", dot_cfi_startproc, 0 },
+ { "cfi_endproc", dot_cfi_endproc, 0 },
+ { "cfi_def_cfa", dot_cfi, DW_CFA_def_cfa },
+ { "cfi_def_cfa_register", dot_cfi, DW_CFA_def_cfa_register },
+ { "cfi_def_cfa_offset", dot_cfi, DW_CFA_def_cfa_offset },
+ { "cfi_adjust_cfa_offset", dot_cfi, CFI_adjust_cfa_offset },
+ { "cfi_offset", dot_cfi, DW_CFA_offset },
+ { "cfi_rel_offset", dot_cfi, CFI_rel_offset },
+ { "cfi_register", dot_cfi, DW_CFA_register },
+ { "cfi_return_column", dot_cfi, CFI_return_column },
+ { "cfi_restore", dot_cfi, DW_CFA_restore },
+ { "cfi_undefined", dot_cfi, DW_CFA_undefined },
+ { "cfi_same_value", dot_cfi, DW_CFA_same_value },
+ { "cfi_remember_state", dot_cfi, DW_CFA_remember_state },
+ { "cfi_restore_state", dot_cfi, DW_CFA_restore_state },
+ { "cfi_window_save", dot_cfi, DW_CFA_GNU_window_save },
+ { "cfi_escape", dot_cfi_escape, 0 },
+ { NULL, NULL, 0 }
+ };
+
+static void
+cfi_parse_separator (void)
+{
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ input_line_pointer++;
+ else
+ as_bad (_("missing separator"));
+}
+
+static unsigned
+cfi_parse_reg (void)
+{
+ int regno;
+ expressionS exp;
+
+#ifdef tc_regname_to_dw2regnum
+ SKIP_WHITESPACE ();
+ if (is_name_beginner (*input_line_pointer)
+ || (*input_line_pointer == '%'
+ && is_name_beginner (*++input_line_pointer)))
+ {
+ char *name, c;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ if ((regno = tc_regname_to_dw2regnum (name)) < 0)
+ {
+ as_bad (_("bad register expression"));
+ regno = 0;
+ }
+
+ *input_line_pointer = c;
+ return regno;
+ }
+#endif
+
+ expression (&exp);
+ switch (exp.X_op)
+ {
+ case O_register:
+ case O_constant:
+ regno = exp.X_add_number;
+ break;
+
+ default:
+ as_bad (_("bad register expression"));
+ regno = 0;
+ break;
+ }
+
+ return regno;
+}
+
+static offsetT
+cfi_parse_const (void)
+{
+ return get_absolute_expression ();
+}
+
+static void
+dot_cfi (int arg)
+{
+ offsetT offset;
+ unsigned reg1, reg2;
+
+ if (!cur_fde_data)
+ {
+ as_bad (_("CFI instruction used without previous .cfi_startproc"));
+ return;
+ }
+
+ /* If the last address was not at the current PC, advance to current. */
+ if (symbol_get_frag (last_address) != frag_now
+ || S_GET_VALUE (last_address) != frag_now_fix ())
+ cfi_add_advance_loc (symbol_temp_new_now ());
+
+ switch (arg)
+ {
+ case DW_CFA_offset:
+ reg1 = cfi_parse_reg ();
+ cfi_parse_separator ();
+ offset = cfi_parse_const ();
+ cfi_add_CFA_offset (reg1, offset);
+ break;
+
+ case CFI_rel_offset:
+ reg1 = cfi_parse_reg ();
+ cfi_parse_separator ();
+ offset = cfi_parse_const ();
+ cfi_add_CFA_offset (reg1, offset - cur_cfa_offset);
+ break;
+
+ case DW_CFA_def_cfa:
+ reg1 = cfi_parse_reg ();
+ cfi_parse_separator ();
+ offset = cfi_parse_const ();
+ cfi_add_CFA_def_cfa (reg1, offset);
+ break;
+
+ case DW_CFA_register:
+ reg1 = cfi_parse_reg ();
+ cfi_parse_separator ();
+ reg2 = cfi_parse_reg ();
+ cfi_add_CFA_register (reg1, reg2);
+ break;
+
+ case DW_CFA_def_cfa_register:
+ reg1 = cfi_parse_reg ();
+ cfi_add_CFA_def_cfa_register (reg1);
+ break;
+
+ case DW_CFA_def_cfa_offset:
+ offset = cfi_parse_const ();
+ cfi_add_CFA_def_cfa_offset (offset);
+ break;
+
+ case CFI_adjust_cfa_offset:
+ offset = cfi_parse_const ();
+ cfi_add_CFA_def_cfa_offset (cur_cfa_offset + offset);
+ break;
+
+ case DW_CFA_restore:
+ reg1 = cfi_parse_reg ();
+ cfi_add_CFA_restore (reg1);
+ break;
+
+ case DW_CFA_undefined:
+ reg1 = cfi_parse_reg ();
+ cfi_add_CFA_undefined (reg1);
+ break;
+
+ case DW_CFA_same_value:
+ reg1 = cfi_parse_reg ();
+ cfi_add_CFA_same_value (reg1);
+ break;
+
+ case CFI_return_column:
+ reg1 = cfi_parse_reg ();
+ cfi_set_return_column (reg1);
+ break;
+
+ case DW_CFA_remember_state:
+ cfi_add_CFA_remember_state ();
+ break;
+
+ case DW_CFA_restore_state:
+ cfi_add_CFA_restore_state ();
+ break;
+
+ case DW_CFA_GNU_window_save:
+ cfi_add_CFA_insn (DW_CFA_GNU_window_save);
+ break;
+
+ default:
+ abort ();
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+dot_cfi_escape (int ignored ATTRIBUTE_UNUSED)
+{
+ struct cfi_escape_data *head, **tail, *e;
+ struct cfi_insn_data *insn;
+
+ if (!cur_fde_data)
+ {
+ as_bad (_("CFI instruction used without previous .cfi_startproc"));
+ return;
+ }
+
+ /* If the last address was not at the current PC, advance to current. */
+ if (symbol_get_frag (last_address) != frag_now
+ || S_GET_VALUE (last_address) != frag_now_fix ())
+ cfi_add_advance_loc (symbol_temp_new_now ());
+
+ tail = &head;
+ do
+ {
+ e = xmalloc (sizeof (*e));
+ do_parse_cons_expression (&e->exp, 1);
+ *tail = e;
+ tail = &e->next;
+ }
+ while (*input_line_pointer++ == ',');
+ *tail = NULL;
+
+ insn = alloc_cfi_insn_data ();
+ insn->insn = CFI_escape;
+ insn->u.esc = head;
+}
+
+static void
+dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED)
+{
+ int simple = 0;
+
+ if (cur_fde_data)
+ {
+ as_bad (_("previous CFI entry not closed (missing .cfi_endproc)"));
+ return;
+ }
+
+ cfi_new_fde (symbol_temp_new_now ());
+
+ SKIP_WHITESPACE ();
+ if (is_name_beginner (*input_line_pointer))
+ {
+ char *name, c;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ if (strcmp (name, "simple") == 0)
+ {
+ simple = 1;
+ *input_line_pointer = c;
+ }
+ else
+ input_line_pointer = name;
+ }
+ demand_empty_rest_of_line ();
+
+ if (!simple)
+ tc_cfi_frame_initial_instructions ();
+}
+
+static void
+dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED)
+{
+ if (! cur_fde_data)
+ {
+ as_bad (_(".cfi_endproc without corresponding .cfi_startproc"));
+ return;
+ }
+
+ cfi_end_fde (symbol_temp_new_now ());
+}
+
+
+/* Emit a single byte into the current segment. */
+
+static inline void
+out_one (int byte)
+{
+ FRAG_APPEND_1_CHAR (byte);
+}
+
+/* Emit a two-byte word into the current segment. */
+
+static inline void
+out_two (int data)
+{
+ md_number_to_chars (frag_more (2), data, 2);
+}
+
+/* Emit a four byte word into the current segment. */
+
+static inline void
+out_four (int data)
+{
+ md_number_to_chars (frag_more (4), data, 4);
+}
+
+/* Emit an unsigned "little-endian base 128" number. */
+
+static void
+out_uleb128 (addressT value)
+{
+ output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);
+}
+
+/* Emit an unsigned "little-endian base 128" number. */
+
+static void
+out_sleb128 (offsetT value)
+{
+ output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1);
+}
+
+static void
+output_cfi_insn (struct cfi_insn_data *insn)
+{
+ offsetT offset;
+ unsigned int regno;
+
+ switch (insn->insn)
+ {
+ case DW_CFA_advance_loc:
+ {
+ symbolS *from = insn->u.ll.lab1;
+ symbolS *to = insn->u.ll.lab2;
+
+ if (symbol_get_frag (to) == symbol_get_frag (from))
+ {
+ addressT delta = S_GET_VALUE (to) - S_GET_VALUE (from);
+ addressT scaled = delta / DWARF2_LINE_MIN_INSN_LENGTH;
+
+ if (scaled <= 0x3F)
+ out_one (DW_CFA_advance_loc + scaled);
+ else if (delta <= 0xFF)
+ {
+ out_one (DW_CFA_advance_loc1);
+ out_one (delta);
+ }
+ else if (delta <= 0xFFFF)
+ {
+ out_one (DW_CFA_advance_loc2);
+ out_two (delta);
+ }
+ else
+ {
+ out_one (DW_CFA_advance_loc4);
+ out_four (delta);
+ }
+ }
+ else
+ {
+ expressionS exp;
+
+ exp.X_op = O_subtract;
+ exp.X_add_symbol = to;
+ exp.X_op_symbol = from;
+ exp.X_add_number = 0;
+
+ /* The code in ehopt.c expects that one byte of the encoding
+ is already allocated to the frag. This comes from the way
+ that it scans the .eh_frame section looking first for the
+ .byte DW_CFA_advance_loc4. */
+ frag_more (1);
+
+ frag_var (rs_cfa, 4, 0, DWARF2_LINE_MIN_INSN_LENGTH << 3,
+ make_expr_symbol (&exp), frag_now_fix () - 1,
+ (char *) frag_now);
+ }
+ }
+ break;
+
+ case DW_CFA_def_cfa:
+ offset = insn->u.ri.offset;
+ if (offset < 0)
+ {
+ out_one (DW_CFA_def_cfa_sf);
+ out_uleb128 (insn->u.ri.reg);
+ out_uleb128 (offset);
+ }
+ else
+ {
+ out_one (DW_CFA_def_cfa);
+ out_uleb128 (insn->u.ri.reg);
+ out_uleb128 (offset);
+ }
+ break;
+
+ case DW_CFA_def_cfa_register:
+ case DW_CFA_undefined:
+ case DW_CFA_same_value:
+ out_one (insn->insn);
+ out_uleb128 (insn->u.r);
+ break;
+
+ case DW_CFA_def_cfa_offset:
+ offset = insn->u.i;
+ if (offset < 0)
+ {
+ out_one (DW_CFA_def_cfa_offset_sf);
+ out_sleb128 (offset);
+ }
+ else
+ {
+ out_one (DW_CFA_def_cfa_offset);
+ out_uleb128 (offset);
+ }
+ break;
+
+ case DW_CFA_restore:
+ regno = insn->u.r;
+ if (regno <= 0x3F)
+ {
+ out_one (DW_CFA_restore + regno);
+ }
+ else
+ {
+ out_one (DW_CFA_restore_extended);
+ out_uleb128 (regno);
+ }
+ break;
+
+ case DW_CFA_offset:
+ regno = insn->u.ri.reg;
+ offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
+ if (offset < 0)
+ {
+ out_one (DW_CFA_offset_extended_sf);
+ out_uleb128 (regno);
+ out_sleb128 (offset);
+ }
+ else if (regno <= 0x3F)
+ {
+ out_one (DW_CFA_offset + regno);
+ out_uleb128 (offset);
+ }
+ else
+ {
+ out_one (DW_CFA_offset_extended);
+ out_uleb128 (regno);
+ out_uleb128 (offset);
+ }
+ break;
+
+ case DW_CFA_register:
+ out_one (DW_CFA_register);
+ out_uleb128 (insn->u.rr.reg1);
+ out_uleb128 (insn->u.rr.reg2);
+ break;
+
+ case DW_CFA_remember_state:
+ case DW_CFA_restore_state:
+ out_one (insn->insn);
+ break;
+
+ case DW_CFA_GNU_window_save:
+ out_one (DW_CFA_GNU_window_save);
+ break;
+
+ case CFI_escape:
+ {
+ struct cfi_escape_data *e;
+ for (e = insn->u.esc; e ; e = e->next)
+ emit_expr (&e->exp, 1);
+ break;
+ }
+
+ default:
+ abort ();
+ }
+}
+
+static void
+output_cie (struct cie_entry *cie)
+{
+ symbolS *after_size_address, *end_address;
+ expressionS exp;
+ struct cfi_insn_data *i;
+
+ cie->start_address = symbol_temp_new_now ();
+ after_size_address = symbol_temp_make ();
+ end_address = symbol_temp_make ();
+
+ exp.X_op = O_subtract;
+ exp.X_add_symbol = end_address;
+ exp.X_op_symbol = after_size_address;
+ exp.X_add_number = 0;
+
+ emit_expr (&exp, 4); /* Length */
+ symbol_set_value_now (after_size_address);
+ out_four (0); /* CIE id */
+ out_one (DW_CIE_VERSION); /* Version */
+ out_one ('z'); /* Augmentation */
+ out_one ('R');
+ out_one (0);
+ out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH); /* Code alignment */
+ out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment */
+ out_one (cie->return_column); /* Return column */
+ out_uleb128 (1); /* Augmentation size */
+#if defined DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
+ out_one (DW_EH_PE_pcrel | DW_EH_PE_sdata4);
+#else
+ out_one (DW_EH_PE_sdata4);
+#endif
+
+ if (cie->first)
+ for (i = cie->first; i != cie->last; i = i->next)
+ output_cfi_insn (i);
+
+ frag_align (2, 0, 0);
+ symbol_set_value_now (end_address);
+}
+
+static void
+output_fde (struct fde_entry *fde, struct cie_entry *cie,
+ struct cfi_insn_data *first, int align)
+{
+ symbolS *after_size_address, *end_address;
+ expressionS exp;
+
+ after_size_address = symbol_temp_make ();
+ end_address = symbol_temp_make ();
+
+ exp.X_op = O_subtract;
+ exp.X_add_symbol = end_address;
+ exp.X_op_symbol = after_size_address;
+ exp.X_add_number = 0;
+ emit_expr (&exp, 4); /* Length */
+ symbol_set_value_now (after_size_address);
+
+ exp.X_add_symbol = after_size_address;
+ exp.X_op_symbol = cie->start_address;
+ emit_expr (&exp, 4); /* CIE offset */
+
+#ifdef DIFF_EXPR_OK
+ exp.X_add_symbol = fde->start_address;
+ exp.X_op_symbol = symbol_temp_new_now ();
+ emit_expr (&exp, 4); /* Code offset */
+#else
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = fde->start_address;
+ exp.X_op_symbol = NULL;
+#ifdef tc_cfi_emit_pcrel_expr
+ tc_cfi_emit_pcrel_expr (&exp, 4); /* Code offset */
+#else
+ emit_expr (&exp, 4); /* Code offset */
+#endif
+ exp.X_op = O_subtract;
+#endif
+
+ exp.X_add_symbol = fde->end_address;
+ exp.X_op_symbol = fde->start_address; /* Code length */
+ emit_expr (&exp, 4);
+
+ out_uleb128 (0); /* Augmentation size */
+
+ for (; first; first = first->next)
+ output_cfi_insn (first);
+
+ frag_align (align, 0, 0);
+ symbol_set_value_now (end_address);
+}
+
+static struct cie_entry *
+select_cie_for_fde (struct fde_entry *fde, struct cfi_insn_data **pfirst)
+{
+ struct cfi_insn_data *i, *j;
+ struct cie_entry *cie;
+
+ for (cie = cie_root; cie; cie = cie->next)
+ {
+ if (cie->return_column != fde->return_column)
+ continue;
+ for (i = cie->first, j = fde->data;
+ i != cie->last && j != NULL;
+ i = i->next, j = j->next)
+ {
+ if (i->insn != j->insn)
+ goto fail;
+ switch (i->insn)
+ {
+ case DW_CFA_advance_loc:
+ /* We reached the first advance in the FDE, but did not
+ reach the end of the CIE list. */
+ goto fail;
+
+ case DW_CFA_offset:
+ case DW_CFA_def_cfa:
+ if (i->u.ri.reg != j->u.ri.reg)
+ goto fail;
+ if (i->u.ri.offset != j->u.ri.offset)
+ goto fail;
+ break;
+
+ case DW_CFA_register:
+ if (i->u.rr.reg1 != j->u.rr.reg1)
+ goto fail;
+ if (i->u.rr.reg2 != j->u.rr.reg2)
+ goto fail;
+ break;
+
+ case DW_CFA_def_cfa_register:
+ case DW_CFA_restore:
+ case DW_CFA_undefined:
+ case DW_CFA_same_value:
+ if (i->u.r != j->u.r)
+ goto fail;
+ break;
+
+ case DW_CFA_def_cfa_offset:
+ if (i->u.i != j->u.i)
+ goto fail;
+ break;
+
+ case CFI_escape:
+ /* Don't bother matching these for now. */
+ goto fail;
+
+ default:
+ abort ();
+ }
+ }
+
+ /* Success if we reached the end of the CIE list, and we've either
+ run out of FDE entries or we've encountered an advance. */
+ if (i == cie->last && (!j || j->insn == DW_CFA_advance_loc))
+ {
+ *pfirst = j;
+ return cie;
+ }
+
+ fail:;
+ }
+
+ cie = xmalloc (sizeof (struct cie_entry));
+ cie->next = cie_root;
+ cie_root = cie;
+ cie->return_column = fde->return_column;
+ cie->first = fde->data;
+
+ for (i = cie->first; i ; i = i->next)
+ if (i->insn == DW_CFA_advance_loc)
+ break;
+
+ cie->last = i;
+ *pfirst = i;
+
+ output_cie (cie);
+
+ return cie;
+}
+
+void
+cfi_finish (void)
+{
+ segT cfi_seg;
+ struct fde_entry *fde;
+ int save_flag_traditional_format;
+
+ if (cur_fde_data)
+ {
+ as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
+ cur_fde_data->end_address = cur_fde_data->start_address;
+ }
+
+ if (all_fde_data == 0)
+ return;
+
+ /* Open .eh_frame section. */
+ cfi_seg = subseg_new (".eh_frame", 0);
+#ifdef BFD_ASSEMBLER
+ bfd_set_section_flags (stdoutput, cfi_seg,
+ SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_READONLY);
+#endif
+ subseg_set (cfi_seg, 0);
+ record_alignment (cfi_seg, EH_FRAME_ALIGNMENT);
+
+ /* Make sure check_eh_frame doesn't do anything with our output. */
+ save_flag_traditional_format = flag_traditional_format;
+ flag_traditional_format = 1;
+
+ for (fde = all_fde_data; fde ; fde = fde->next)
+ {
+ struct cfi_insn_data *first;
+ struct cie_entry *cie;
+
+ cie = select_cie_for_fde (fde, &first);
+ output_fde (fde, cie, first, fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
+ }
+
+ flag_traditional_format = save_flag_traditional_format;
+}
diff --git a/x/binutils/gas/dw2gencfi.h b/x/binutils/gas/dw2gencfi.h
new file mode 100644
index 0000000..75b6ec2
--- /dev/null
+++ b/x/binutils/gas/dw2gencfi.h
@@ -0,0 +1,52 @@
+/* dw2gencfi.h - Support for generating Dwarf2 CFI information.
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Michal Ludvig <mludvig@suse.cz>
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef DW2GENCFI_H
+#define DW2GENCFI_H
+
+#include "elf/dwarf2.h"
+
+struct symbol;
+
+extern const pseudo_typeS cfi_pseudo_table[];
+
+/* cfi_finish() is called at the end of file. It will complain if
+ the last CFI wasn't properly closed by .cfi_endproc. */
+extern void cfi_finish (void);
+
+/* Entry points for backends to add unwind information. */
+extern void cfi_new_fde (struct symbol *);
+extern void cfi_end_fde (struct symbol *);
+extern void cfi_set_return_column (unsigned);
+extern void cfi_add_advance_loc (struct symbol *);
+
+extern void cfi_add_CFA_offset (unsigned, offsetT);
+extern void cfi_add_CFA_def_cfa (unsigned, offsetT);
+extern void cfi_add_CFA_register (unsigned, unsigned);
+extern void cfi_add_CFA_def_cfa_register (unsigned);
+extern void cfi_add_CFA_def_cfa_offset (offsetT);
+extern void cfi_add_CFA_restore (unsigned);
+extern void cfi_add_CFA_undefined (unsigned);
+extern void cfi_add_CFA_same_value (unsigned);
+extern void cfi_add_CFA_remember_state (void);
+extern void cfi_add_CFA_restore_state (void);
+
+#endif /* DW2GENCFI_H */
diff --git a/x/binutils/gas/dwarf2dbg.c b/x/binutils/gas/dwarf2dbg.c
new file mode 100644
index 0000000..3336453
--- /dev/null
+++ b/x/binutils/gas/dwarf2dbg.c
@@ -0,0 +1,1464 @@
+/* dwarf2dbg.c - DWARF2 debug support
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Logical line numbers can be controlled by the compiler via the
+ following two directives:
+
+ .file FILENO "file.c"
+ .loc FILENO LINENO [COLUMN]
+
+ FILENO is the filenumber. */
+
+#include "ansidecl.h"
+#include "as.h"
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#else
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifndef INT_MAX
+#define INT_MAX (int) (((unsigned) (-1)) >> 1)
+#endif
+#endif
+
+#include "dwarf2dbg.h"
+#include <filenames.h>
+
+#ifndef DWARF2_FORMAT
+# define DWARF2_FORMAT() dwarf2_format_32bit
+#endif
+
+#ifndef DWARF2_ADDR_SIZE
+# define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8)
+#endif
+
+#ifdef BFD_ASSEMBLER
+
+#include "subsegs.h"
+
+#include "elf/dwarf2.h"
+
+/* Since we can't generate the prolog until the body is complete, we
+ use three different subsegments for .debug_line: one holding the
+ prolog, one for the directory and filename info, and one for the
+ body ("statement program"). */
+#define DL_PROLOG 0
+#define DL_FILES 1
+#define DL_BODY 2
+
+/* First special line opcde - leave room for the standard opcodes.
+ Note: If you want to change this, you'll have to update the
+ "standard_opcode_lengths" table that is emitted below in
+ dwarf2_finish(). */
+#define DWARF2_LINE_OPCODE_BASE 10
+
+#ifndef DWARF2_LINE_BASE
+ /* Minimum line offset in a special line info. opcode. This value
+ was chosen to give a reasonable range of values. */
+# define DWARF2_LINE_BASE -5
+#endif
+
+/* Range of line offsets in a special line info. opcode. */
+#ifndef DWARF2_LINE_RANGE
+# define DWARF2_LINE_RANGE 14
+#endif
+
+#ifndef DWARF2_LINE_MIN_INSN_LENGTH
+ /* Define the architecture-dependent minimum instruction length (in
+ bytes). This value should be rather too small than too big. */
+# define DWARF2_LINE_MIN_INSN_LENGTH 1
+#endif
+
+/* Flag that indicates the initial value of the is_stmt_start flag.
+ In the present implementation, we do not mark any lines as
+ the beginning of a source statement, because that information
+ is not made available by the GCC front-end. */
+#define DWARF2_LINE_DEFAULT_IS_STMT 1
+
+/* Given a special op, return the line skip amount. */
+#define SPECIAL_LINE(op) \
+ (((op) - DWARF2_LINE_OPCODE_BASE)%DWARF2_LINE_RANGE + DWARF2_LINE_BASE)
+
+/* Given a special op, return the address skip amount (in units of
+ DWARF2_LINE_MIN_INSN_LENGTH. */
+#define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)
+
+/* The maximum address skip amount that can be encoded with a special op. */
+#define MAX_SPECIAL_ADDR_DELTA SPECIAL_ADDR(255)
+
+struct line_entry {
+ struct line_entry *next;
+ fragS *frag;
+ addressT frag_ofs;
+ struct dwarf2_line_info loc;
+};
+
+struct line_subseg {
+ struct line_subseg *next;
+ subsegT subseg;
+ struct line_entry *head;
+ struct line_entry **ptail;
+};
+
+struct line_seg {
+ struct line_seg *next;
+ segT seg;
+ struct line_subseg *head;
+ symbolS *text_start;
+ symbolS *text_end;
+};
+
+/* Collects data for all line table entries during assembly. */
+static struct line_seg *all_segs;
+
+struct file_entry {
+ const char *filename;
+ unsigned int dir;
+};
+
+/* Table of files used by .debug_line. */
+static struct file_entry *files;
+static unsigned int files_in_use;
+static unsigned int files_allocated;
+
+/* Table of directories used by .debug_line. */
+static char **dirs;
+static unsigned int dirs_in_use;
+static unsigned int dirs_allocated;
+
+/* TRUE when we've seen a .loc directive recently. Used to avoid
+ doing work when there's nothing to do. */
+static bfd_boolean loc_directive_seen;
+
+/* Current location as indicated by the most recent .loc directive. */
+static struct dwarf2_line_info current;
+
+/* The size of an address on the target. */
+static unsigned int sizeof_address;
+
+static struct line_subseg *get_line_subseg (segT, subsegT);
+static unsigned int get_filenum (const char *, unsigned int);
+static struct frag *first_frag_for_seg (segT);
+static struct frag *last_frag_for_seg (segT);
+static void out_byte (int);
+static void out_opcode (int);
+static void out_two (int);
+static void out_four (int);
+static void out_abbrev (int, int);
+static void out_uleb128 (addressT);
+static offsetT get_frag_fix (fragS *);
+static void out_set_addr (segT, fragS *, addressT);
+static int size_inc_line_addr (int, addressT);
+static void emit_inc_line_addr (int, addressT, char *, int);
+static void out_inc_line_addr (int, addressT);
+static void relax_inc_line_addr (int, segT, fragS *, addressT,
+ fragS *, addressT);
+static void process_entries (segT, struct line_entry *);
+static void out_file_list (void);
+static void out_debug_line (segT);
+static void out_debug_aranges (segT, segT);
+static void out_debug_abbrev (segT);
+static void out_debug_info (segT, segT, segT);
+
+#ifndef TC_DWARF2_EMIT_OFFSET
+# define TC_DWARF2_EMIT_OFFSET generic_dwarf2_emit_offset
+static void generic_dwarf2_emit_offset (symbolS *, unsigned int);
+
+/* Create an offset to .dwarf2_*. */
+
+static void
+generic_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
+{
+ expressionS expr;
+
+ expr.X_op = O_symbol;
+ expr.X_add_symbol = symbol;
+ expr.X_add_number = 0;
+ emit_expr (&expr, size);
+}
+#endif
+
+/* Find or create an entry for SEG+SUBSEG in ALL_SEGS. */
+
+static struct line_subseg *
+get_line_subseg (segT seg, subsegT subseg)
+{
+ static segT last_seg;
+ static subsegT last_subseg;
+ static struct line_subseg *last_line_subseg;
+
+ struct line_seg *s;
+ struct line_subseg **pss, *ss;
+
+ if (seg == last_seg && subseg == last_subseg)
+ return last_line_subseg;
+
+ for (s = all_segs; s; s = s->next)
+ if (s->seg == seg)
+ goto found_seg;
+
+ s = (struct line_seg *) xmalloc (sizeof (*s));
+ s->next = all_segs;
+ s->seg = seg;
+ s->head = NULL;
+ all_segs = s;
+
+ found_seg:
+ for (pss = &s->head; (ss = *pss) != NULL ; pss = &ss->next)
+ {
+ if (ss->subseg == subseg)
+ goto found_subseg;
+ if (ss->subseg > subseg)
+ break;
+ }
+
+ ss = (struct line_subseg *) xmalloc (sizeof (*ss));
+ ss->next = *pss;
+ ss->subseg = subseg;
+ ss->head = NULL;
+ ss->ptail = &ss->head;
+ *pss = ss;
+
+ found_subseg:
+ last_seg = seg;
+ last_subseg = subseg;
+ last_line_subseg = ss;
+
+ return ss;
+}
+
+/* Record an entry for LOC occurring at OFS within the current fragment. */
+
+void
+dwarf2_gen_line_info (addressT ofs, struct dwarf2_line_info *loc)
+{
+ struct line_subseg *ss;
+ struct line_entry *e;
+ static unsigned int line = -1;
+ static unsigned int filenum = -1;
+
+ /* Early out for as-yet incomplete location information. */
+ if (loc->filenum == 0 || loc->line == 0)
+ return;
+
+ /* Don't emit sequences of line symbols for the same line when the
+ symbols apply to assembler code. It is necessary to emit
+ duplicate line symbols when a compiler asks for them, because GDB
+ uses them to determine the end of the prologue. */
+ if (debug_type == DEBUG_DWARF2
+ && line == loc->line && filenum == loc->filenum)
+ return;
+
+ line = loc->line;
+ filenum = loc->filenum;
+
+ e = (struct line_entry *) xmalloc (sizeof (*e));
+ e->next = NULL;
+ e->frag = frag_now;
+ e->frag_ofs = ofs;
+ e->loc = *loc;
+
+ ss = get_line_subseg (now_seg, now_subseg);
+ *ss->ptail = e;
+ ss->ptail = &e->next;
+}
+
+void
+dwarf2_where (struct dwarf2_line_info *line)
+{
+ if (debug_type == DEBUG_DWARF2)
+ {
+ char *filename;
+ as_where (&filename, &line->line);
+ line->filenum = get_filenum (filename, 0);
+ line->column = 0;
+ line->flags = DWARF2_FLAG_BEGIN_STMT;
+ }
+ else
+ *line = current;
+}
+
+/* Called for each machine instruction, or relatively atomic group of
+ machine instructions (ie built-in macro). The instruction or group
+ is SIZE bytes in length. If dwarf2 line number generation is called
+ for, emit a line statement appropriately. */
+
+void
+dwarf2_emit_insn (int size)
+{
+ struct dwarf2_line_info loc;
+
+ if (loc_directive_seen)
+ {
+ /* Use the last location established by a .loc directive, not
+ the value returned by dwarf2_where(). That calls as_where()
+ which will return either the logical input file name (foo.c)
+ or the physical input file name (foo.s) and not the file name
+ specified in the most recent .loc directive (eg foo.h). */
+ loc = current;
+
+ /* Unless we generate DWARF2 debugging information for each
+ assembler line, we only emit one line symbol for one LOC. */
+ if (debug_type != DEBUG_DWARF2)
+ loc_directive_seen = FALSE;
+ }
+ else if (debug_type != DEBUG_DWARF2)
+ return;
+ else
+ dwarf2_where (& loc);
+
+ dwarf2_gen_line_info (frag_now_fix () - size, &loc);
+}
+
+/* Get a .debug_line file number for FILENAME. If NUM is nonzero,
+ allocate it on that file table slot, otherwise return the first
+ empty one. */
+
+static unsigned int
+get_filenum (const char *filename, unsigned int num)
+{
+ static unsigned int last_used, last_used_dir_len;
+ const char *file;
+ size_t dir_len;
+ unsigned int i, dir;
+
+ if (num == 0 && last_used)
+ {
+ if (! files[last_used].dir
+ && strcmp (filename, files[last_used].filename) == 0)
+ return last_used;
+ if (files[last_used].dir
+ && strncmp (filename, dirs[files[last_used].dir],
+ last_used_dir_len) == 0
+ && IS_DIR_SEPARATOR (filename [last_used_dir_len])
+ && strcmp (filename + last_used_dir_len + 1,
+ files[last_used].filename) == 0)
+ return last_used;
+ }
+
+ file = lbasename (filename);
+ /* Don't make empty string from / or A: from A:/ . */
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ if (file <= filename + 3)
+ file = filename;
+#else
+ if (file == filename + 1)
+ file = filename;
+#endif
+ dir_len = file - filename;
+
+ dir = 0;
+ if (dir_len)
+ {
+ --dir_len;
+ for (dir = 1; dir < dirs_in_use; ++dir)
+ if (strncmp (filename, dirs[dir], dir_len) == 0
+ && dirs[dir][dir_len] == '\0')
+ break;
+
+ if (dir >= dirs_in_use)
+ {
+ if (dir >= dirs_allocated)
+ {
+ dirs_allocated = dir + 32;
+ dirs = (char **)
+ xrealloc (dirs, (dir + 32) * sizeof (const char *));
+ }
+
+ dirs[dir] = xmalloc (dir_len + 1);
+ memcpy (dirs[dir], filename, dir_len);
+ dirs[dir][dir_len] = '\0';
+ dirs_in_use = dir + 1;
+ }
+ }
+
+ if (num == 0)
+ {
+ for (i = 1; i < files_in_use; ++i)
+ if (files[i].dir == dir
+ && files[i].filename
+ && strcmp (file, files[i].filename) == 0)
+ {
+ last_used = i;
+ last_used_dir_len = dir_len;
+ return i;
+ }
+ }
+ else
+ i = num;
+
+ if (i >= files_allocated)
+ {
+ unsigned int old = files_allocated;
+
+ files_allocated = i + 32;
+ files = (struct file_entry *)
+ xrealloc (files, (i + 32) * sizeof (struct file_entry));
+
+ memset (files + old, 0, (i + 32 - old) * sizeof (struct file_entry));
+ }
+
+ files[i].filename = num ? file : xstrdup (file);
+ files[i].dir = dir;
+ files_in_use = i + 1;
+ last_used = i;
+ last_used_dir_len = dir_len;
+
+ return i;
+}
+
+/* Handle two forms of .file directive:
+ - Pass .file "source.c" to s_app_file
+ - Handle .file 1 "source.c" by adding an entry to the DWARF-2 file table
+
+ If an entry is added to the file table, return a pointer to the filename. */
+
+char *
+dwarf2_directive_file (int dummy ATTRIBUTE_UNUSED)
+{
+ offsetT num;
+ char *filename;
+ int filename_len;
+
+ /* Continue to accept a bare string and pass it off. */
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '"')
+ {
+ s_app_file (0);
+ return NULL;
+ }
+
+ num = get_absolute_expression ();
+ filename = demand_copy_C_string (&filename_len);
+ demand_empty_rest_of_line ();
+
+ if (num < 1)
+ {
+ as_bad (_("file number less than one"));
+ return NULL;
+ }
+
+ if (num < (int) files_in_use && files[num].filename != 0)
+ {
+ as_bad (_("file number %ld already allocated"), (long) num);
+ return NULL;
+ }
+
+ get_filenum (filename, num);
+
+ return filename;
+}
+
+void
+dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
+{
+ offsetT filenum, line, column;
+
+ filenum = get_absolute_expression ();
+ SKIP_WHITESPACE ();
+ line = get_absolute_expression ();
+ SKIP_WHITESPACE ();
+ column = get_absolute_expression ();
+ demand_empty_rest_of_line ();
+
+ if (filenum < 1)
+ {
+ as_bad (_("file number less than one"));
+ return;
+ }
+ if (filenum >= (int) files_in_use || files[filenum].filename == 0)
+ {
+ as_bad (_("unassigned file number %ld"), (long) filenum);
+ return;
+ }
+
+ current.filenum = filenum;
+ current.line = line;
+ current.column = column;
+ current.flags = DWARF2_FLAG_BEGIN_STMT;
+
+ loc_directive_seen = TRUE;
+
+#ifndef NO_LISTING
+ if (listing)
+ {
+ if (files[filenum].dir)
+ {
+ size_t dir_len = strlen (dirs[files[filenum].dir]);
+ size_t file_len = strlen (files[filenum].filename);
+ char *cp = (char *) alloca (dir_len + 1 + file_len + 1);
+
+ memcpy (cp, dirs[files[filenum].dir], dir_len);
+ cp[dir_len] = '/';
+ memcpy (cp + dir_len + 1, files[filenum].filename, file_len);
+ cp[dir_len + file_len + 1] = '\0';
+ listing_source_file (cp);
+ }
+ else
+ listing_source_file (files[filenum].filename);
+ listing_source_line (line);
+ }
+#endif
+}
+
+static struct frag *
+first_frag_for_seg (segT seg)
+{
+ frchainS *f, *first = NULL;
+
+ for (f = frchain_root; f; f = f->frch_next)
+ if (f->frch_seg == seg
+ && (! first || first->frch_subseg > f->frch_subseg))
+ first = f;
+
+ return first ? first->frch_root : NULL;
+}
+
+static struct frag *
+last_frag_for_seg (segT seg)
+{
+ frchainS *f, *last = NULL;
+
+ for (f = frchain_root; f; f = f->frch_next)
+ if (f->frch_seg == seg
+ && (! last || last->frch_subseg < f->frch_subseg))
+ last= f;
+
+ return last ? last->frch_last : NULL;
+}
+
+/* Emit a single byte into the current segment. */
+
+static inline void
+out_byte (int byte)
+{
+ FRAG_APPEND_1_CHAR (byte);
+}
+
+/* Emit a statement program opcode into the current segment. */
+
+static inline void
+out_opcode (int opc)
+{
+ out_byte (opc);
+}
+
+/* Emit a two-byte word into the current segment. */
+
+static inline void
+out_two (int data)
+{
+ md_number_to_chars (frag_more (2), data, 2);
+}
+
+/* Emit a four byte word into the current segment. */
+
+static inline void
+out_four (int data)
+{
+ md_number_to_chars (frag_more (4), data, 4);
+}
+
+/* Emit an unsigned "little-endian base 128" number. */
+
+static void
+out_uleb128 (addressT value)
+{
+ output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);
+}
+
+/* Emit a tuple for .debug_abbrev. */
+
+static inline void
+out_abbrev (int name, int form)
+{
+ out_uleb128 (name);
+ out_uleb128 (form);
+}
+
+/* Get the size of a fragment. */
+
+static offsetT
+get_frag_fix (fragS *frag)
+{
+ frchainS *fr;
+
+ if (frag->fr_next)
+ return frag->fr_fix;
+
+ /* If a fragment is the last in the chain, special measures must be
+ taken to find its size before relaxation, since it may be pending
+ on some subsegment chain. */
+ for (fr = frchain_root; fr; fr = fr->frch_next)
+ if (fr->frch_last == frag)
+ return (char *) obstack_next_free (&fr->frch_obstack) - frag->fr_literal;
+
+ abort ();
+}
+
+/* Set an absolute address (may result in a relocation entry). */
+
+static void
+out_set_addr (segT seg, fragS *frag, addressT ofs)
+{
+ expressionS expr;
+ symbolS *sym;
+
+ sym = symbol_temp_new (seg, ofs, frag);
+
+ out_opcode (DW_LNS_extended_op);
+ out_uleb128 (sizeof_address + 1);
+
+ out_opcode (DW_LNE_set_address);
+ expr.X_op = O_symbol;
+ expr.X_add_symbol = sym;
+ expr.X_add_number = 0;
+ emit_expr (&expr, sizeof_address);
+}
+
+#if DWARF2_LINE_MIN_INSN_LENGTH > 1
+static void scale_addr_delta (addressT *);
+
+static void
+scale_addr_delta (addressT *addr_delta)
+{
+ static int printed_this = 0;
+ if (*addr_delta % DWARF2_LINE_MIN_INSN_LENGTH != 0)
+ {
+ if (!printed_this)
+ as_bad("unaligned opcodes detected in executable segment");
+ printed_this = 1;
+ }
+ *addr_delta /= DWARF2_LINE_MIN_INSN_LENGTH;
+}
+#else
+#define scale_addr_delta(A)
+#endif
+
+/* Encode a pair of line and address skips as efficiently as possible.
+ Note that the line skip is signed, whereas the address skip is unsigned.
+
+ The following two routines *must* be kept in sync. This is
+ enforced by making emit_inc_line_addr abort if we do not emit
+ exactly the expected number of bytes. */
+
+static int
+size_inc_line_addr (int line_delta, addressT addr_delta)
+{
+ unsigned int tmp, opcode;
+ int len = 0;
+
+ /* Scale the address delta by the minimum instruction length. */
+ scale_addr_delta (&addr_delta);
+
+ /* INT_MAX is a signal that this is actually a DW_LNE_end_sequence.
+ We cannot use special opcodes here, since we want the end_sequence
+ to emit the matrix entry. */
+ if (line_delta == INT_MAX)
+ {
+ if (addr_delta == MAX_SPECIAL_ADDR_DELTA)
+ len = 1;
+ else
+ len = 1 + sizeof_leb128 (addr_delta, 0);
+ return len + 3;
+ }
+
+ /* Bias the line delta by the base. */
+ tmp = line_delta - DWARF2_LINE_BASE;
+
+ /* If the line increment is out of range of a special opcode, we
+ must encode it with DW_LNS_advance_line. */
+ if (tmp >= DWARF2_LINE_RANGE)
+ {
+ len = 1 + sizeof_leb128 (line_delta, 1);
+ line_delta = 0;
+ tmp = 0 - DWARF2_LINE_BASE;
+ }
+
+ /* Bias the opcode by the special opcode base. */
+ tmp += DWARF2_LINE_OPCODE_BASE;
+
+ /* Avoid overflow when addr_delta is large. */
+ if (addr_delta < 256 + MAX_SPECIAL_ADDR_DELTA)
+ {
+ /* Try using a special opcode. */
+ opcode = tmp + addr_delta * DWARF2_LINE_RANGE;
+ if (opcode <= 255)
+ return len + 1;
+
+ /* Try using DW_LNS_const_add_pc followed by special op. */
+ opcode = tmp + (addr_delta - MAX_SPECIAL_ADDR_DELTA) * DWARF2_LINE_RANGE;
+ if (opcode <= 255)
+ return len + 2;
+ }
+
+ /* Otherwise use DW_LNS_advance_pc. */
+ len += 1 + sizeof_leb128 (addr_delta, 0);
+
+ /* DW_LNS_copy or special opcode. */
+ len += 1;
+
+ return len;
+}
+
+static void
+emit_inc_line_addr (int line_delta, addressT addr_delta, char *p, int len)
+{
+ unsigned int tmp, opcode;
+ int need_copy = 0;
+ char *end = p + len;
+
+ /* Scale the address delta by the minimum instruction length. */
+ scale_addr_delta (&addr_delta);
+
+ /* INT_MAX is a signal that this is actually a DW_LNE_end_sequence.
+ We cannot use special opcodes here, since we want the end_sequence
+ to emit the matrix entry. */
+ if (line_delta == INT_MAX)
+ {
+ if (addr_delta == MAX_SPECIAL_ADDR_DELTA)
+ *p++ = DW_LNS_const_add_pc;
+ else
+ {
+ *p++ = DW_LNS_advance_pc;
+ p += output_leb128 (p, addr_delta, 0);
+ }
+
+ *p++ = DW_LNS_extended_op;
+ *p++ = 1;
+ *p++ = DW_LNE_end_sequence;
+ goto done;
+ }
+
+ /* Bias the line delta by the base. */
+ tmp = line_delta - DWARF2_LINE_BASE;
+
+ /* If the line increment is out of range of a special opcode, we
+ must encode it with DW_LNS_advance_line. */
+ if (tmp >= DWARF2_LINE_RANGE)
+ {
+ *p++ = DW_LNS_advance_line;
+ p += output_leb128 (p, line_delta, 1);
+
+ /* Prettier, I think, to use DW_LNS_copy instead of a
+ "line +0, addr +0" special opcode. */
+ if (addr_delta == 0)
+ {
+ *p++ = DW_LNS_copy;
+ goto done;
+ }
+
+ line_delta = 0;
+ tmp = 0 - DWARF2_LINE_BASE;
+ need_copy = 1;
+ }
+
+ /* Bias the opcode by the special opcode base. */
+ tmp += DWARF2_LINE_OPCODE_BASE;
+
+ /* Avoid overflow when addr_delta is large. */
+ if (addr_delta < 256 + MAX_SPECIAL_ADDR_DELTA)
+ {
+ /* Try using a special opcode. */
+ opcode = tmp + addr_delta * DWARF2_LINE_RANGE;
+ if (opcode <= 255)
+ {
+ *p++ = opcode;
+ goto done;
+ }
+
+ /* Try using DW_LNS_const_add_pc followed by special op. */
+ opcode = tmp + (addr_delta - MAX_SPECIAL_ADDR_DELTA) * DWARF2_LINE_RANGE;
+ if (opcode <= 255)
+ {
+ *p++ = DW_LNS_const_add_pc;
+ *p++ = opcode;
+ goto done;
+ }
+ }
+
+ /* Otherwise use DW_LNS_advance_pc. */
+ *p++ = DW_LNS_advance_pc;
+ p += output_leb128 (p, addr_delta, 0);
+
+ if (need_copy)
+ *p++ = DW_LNS_copy;
+ else
+ *p++ = tmp;
+
+ done:
+ assert (p == end);
+}
+
+/* Handy routine to combine calls to the above two routines. */
+
+static void
+out_inc_line_addr (int line_delta, addressT addr_delta)
+{
+ int len = size_inc_line_addr (line_delta, addr_delta);
+ emit_inc_line_addr (line_delta, addr_delta, frag_more (len), len);
+}
+
+/* Generate a variant frag that we can use to relax address/line
+ increments between fragments of the target segment. */
+
+static void
+relax_inc_line_addr (int line_delta, segT seg,
+ fragS *to_frag, addressT to_ofs,
+ fragS *from_frag, addressT from_ofs)
+{
+ symbolS *to_sym, *from_sym;
+ expressionS expr;
+ int max_chars;
+
+ to_sym = symbol_temp_new (seg, to_ofs, to_frag);
+ from_sym = symbol_temp_new (seg, from_ofs, from_frag);
+
+ expr.X_op = O_subtract;
+ expr.X_add_symbol = to_sym;
+ expr.X_op_symbol = from_sym;
+ expr.X_add_number = 0;
+
+ /* The maximum size of the frag is the line delta with a maximum
+ sized address delta. */
+ max_chars = size_inc_line_addr (line_delta, -DWARF2_LINE_MIN_INSN_LENGTH);
+
+ frag_var (rs_dwarf2dbg, max_chars, max_chars, 1,
+ make_expr_symbol (&expr), line_delta, NULL);
+}
+
+/* The function estimates the size of a rs_dwarf2dbg variant frag
+ based on the current values of the symbols. It is called before
+ the relaxation loop. We set fr_subtype to the expected length. */
+
+int
+dwarf2dbg_estimate_size_before_relax (fragS *frag)
+{
+ offsetT addr_delta;
+ int size;
+
+ addr_delta = resolve_symbol_value (frag->fr_symbol);
+ size = size_inc_line_addr (frag->fr_offset, addr_delta);
+
+ frag->fr_subtype = size;
+
+ return size;
+}
+
+/* This function relaxes a rs_dwarf2dbg variant frag based on the
+ current values of the symbols. fr_subtype is the current length
+ of the frag. This returns the change in frag length. */
+
+int
+dwarf2dbg_relax_frag (fragS *frag)
+{
+ int old_size, new_size;
+
+ old_size = frag->fr_subtype;
+ new_size = dwarf2dbg_estimate_size_before_relax (frag);
+
+ return new_size - old_size;
+}
+
+/* This function converts a rs_dwarf2dbg variant frag into a normal
+ fill frag. This is called after all relaxation has been done.
+ fr_subtype will be the desired length of the frag. */
+
+void
+dwarf2dbg_convert_frag (fragS *frag)
+{
+ offsetT addr_diff;
+
+ addr_diff = resolve_symbol_value (frag->fr_symbol);
+
+ /* fr_var carries the max_chars that we created the fragment with.
+ fr_subtype carries the current expected length. We must, of
+ course, have allocated enough memory earlier. */
+ assert (frag->fr_var >= (int) frag->fr_subtype);
+
+ emit_inc_line_addr (frag->fr_offset, addr_diff,
+ frag->fr_literal + frag->fr_fix, frag->fr_subtype);
+
+ frag->fr_fix += frag->fr_subtype;
+ frag->fr_type = rs_fill;
+ frag->fr_var = 0;
+ frag->fr_offset = 0;
+}
+
+/* Generate .debug_line content for the chain of line number entries
+ beginning at E, for segment SEG. */
+
+static void
+process_entries (segT seg, struct line_entry *e)
+{
+ unsigned filenum = 1;
+ unsigned line = 1;
+ unsigned column = 0;
+ unsigned flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_BEGIN_STMT : 0;
+ fragS *frag = NULL;
+ fragS *last_frag;
+ addressT frag_ofs = 0;
+ addressT last_frag_ofs;
+ struct line_entry *next;
+
+ while (e)
+ {
+ int changed = 0;
+
+ if (filenum != e->loc.filenum)
+ {
+ filenum = e->loc.filenum;
+ out_opcode (DW_LNS_set_file);
+ out_uleb128 (filenum);
+ changed = 1;
+ }
+
+ if (column != e->loc.column)
+ {
+ column = e->loc.column;
+ out_opcode (DW_LNS_set_column);
+ out_uleb128 (column);
+ changed = 1;
+ }
+
+ if ((e->loc.flags ^ flags) & DWARF2_FLAG_BEGIN_STMT)
+ {
+ flags = e->loc.flags;
+ out_opcode (DW_LNS_negate_stmt);
+ changed = 1;
+ }
+
+ if (e->loc.flags & DWARF2_FLAG_BEGIN_BLOCK)
+ {
+ out_opcode (DW_LNS_set_basic_block);
+ changed = 1;
+ }
+
+ /* Don't try to optimize away redundant entries; gdb wants two
+ entries for a function where the code starts on the same line as
+ the {, and there's no way to identify that case here. Trust gcc
+ to optimize appropriately. */
+ if (1 /* line != e->loc.line || changed */)
+ {
+ int line_delta = e->loc.line - line;
+ if (frag == NULL)
+ {
+ out_set_addr (seg, e->frag, e->frag_ofs);
+ out_inc_line_addr (line_delta, 0);
+ }
+ else if (frag == e->frag)
+ out_inc_line_addr (line_delta, e->frag_ofs - frag_ofs);
+ else
+ relax_inc_line_addr (line_delta, seg, e->frag, e->frag_ofs,
+ frag, frag_ofs);
+
+ frag = e->frag;
+ frag_ofs = e->frag_ofs;
+ line = e->loc.line;
+ }
+ else if (frag == NULL)
+ {
+ out_set_addr (seg, e->frag, e->frag_ofs);
+ frag = e->frag;
+ frag_ofs = e->frag_ofs;
+ }
+
+ next = e->next;
+ free (e);
+ e = next;
+ }
+
+ /* Emit a DW_LNE_end_sequence for the end of the section. */
+ last_frag = last_frag_for_seg (seg);
+ last_frag_ofs = get_frag_fix (last_frag);
+ if (frag == last_frag)
+ out_inc_line_addr (INT_MAX, last_frag_ofs - frag_ofs);
+ else
+ relax_inc_line_addr (INT_MAX, seg, last_frag, last_frag_ofs,
+ frag, frag_ofs);
+}
+
+/* Emit the directory and file tables for .debug_line. */
+
+static void
+out_file_list (void)
+{
+ size_t size;
+ char *cp;
+ unsigned int i;
+
+ /* Emit directory list. */
+ for (i = 1; i < dirs_in_use; ++i)
+ {
+ size = strlen (dirs[i]) + 1;
+ cp = frag_more (size);
+ memcpy (cp, dirs[i], size);
+ }
+ /* Terminate it. */
+ out_byte ('\0');
+
+ for (i = 1; i < files_in_use; ++i)
+ {
+ if (files[i].filename == NULL)
+ {
+ as_bad (_("unassigned file number %ld"), (long) i);
+ /* Prevent a crash later, particularly for file 1. */
+ files[i].filename = "";
+ continue;
+ }
+
+ size = strlen (files[i].filename) + 1;
+ cp = frag_more (size);
+ memcpy (cp, files[i].filename, size);
+
+ out_uleb128 (files[i].dir); /* directory number */
+ out_uleb128 (0); /* last modification timestamp */
+ out_uleb128 (0); /* filesize */
+ }
+
+ /* Terminate filename list. */
+ out_byte (0);
+}
+
+/* Emit the collected .debug_line data. */
+
+static void
+out_debug_line (segT line_seg)
+{
+ expressionS expr;
+ symbolS *line_start;
+ symbolS *prologue_end;
+ symbolS *line_end;
+ struct line_seg *s;
+ enum dwarf2_format d2f;
+ int sizeof_offset;
+
+ subseg_set (line_seg, 0);
+
+ line_start = symbol_temp_new_now ();
+ prologue_end = symbol_temp_make ();
+ line_end = symbol_temp_make ();
+
+ /* Total length of the information for this compilation unit. */
+ expr.X_op = O_subtract;
+ expr.X_add_symbol = line_end;
+ expr.X_op_symbol = line_start;
+
+ d2f = DWARF2_FORMAT ();
+ if (d2f == dwarf2_format_32bit)
+ {
+ expr.X_add_number = -4;
+ emit_expr (&expr, 4);
+ sizeof_offset = 4;
+ }
+ else if (d2f == dwarf2_format_64bit)
+ {
+ expr.X_add_number = -12;
+ out_four (-1);
+ emit_expr (&expr, 8);
+ sizeof_offset = 8;
+ }
+ else if (d2f == dwarf2_format_64bit_irix)
+ {
+ expr.X_add_number = -8;
+ emit_expr (&expr, 8);
+ sizeof_offset = 8;
+ }
+ else
+ {
+ as_fatal (_("internal error: unknown dwarf2 format"));
+ }
+
+ /* Version. */
+ out_two (2);
+
+ /* Length of the prologue following this length. */
+ expr.X_op = O_subtract;
+ expr.X_add_symbol = prologue_end;
+ expr.X_op_symbol = line_start;
+ expr.X_add_number = - (4 + 2 + 4);
+ emit_expr (&expr, sizeof_offset);
+
+ /* Parameters of the state machine. */
+ out_byte (DWARF2_LINE_MIN_INSN_LENGTH);
+ out_byte (DWARF2_LINE_DEFAULT_IS_STMT);
+ out_byte (DWARF2_LINE_BASE);
+ out_byte (DWARF2_LINE_RANGE);
+ out_byte (DWARF2_LINE_OPCODE_BASE);
+
+ /* Standard opcode lengths. */
+ out_byte (0); /* DW_LNS_copy */
+ out_byte (1); /* DW_LNS_advance_pc */
+ out_byte (1); /* DW_LNS_advance_line */
+ out_byte (1); /* DW_LNS_set_file */
+ out_byte (1); /* DW_LNS_set_column */
+ out_byte (0); /* DW_LNS_negate_stmt */
+ out_byte (0); /* DW_LNS_set_basic_block */
+ out_byte (0); /* DW_LNS_const_add_pc */
+ out_byte (1); /* DW_LNS_fixed_advance_pc */
+
+ out_file_list ();
+
+ symbol_set_value_now (prologue_end);
+
+ /* For each section, emit a statement program. */
+ for (s = all_segs; s; s = s->next)
+ process_entries (s->seg, s->head->head);
+
+ symbol_set_value_now (line_end);
+}
+
+/* Emit data for .debug_aranges. */
+
+static void
+out_debug_aranges (segT aranges_seg, segT info_seg)
+{
+ unsigned int addr_size = sizeof_address;
+ addressT size, skip;
+ struct line_seg *s;
+ expressionS expr;
+ char *p;
+
+ size = 4 + 2 + 4 + 1 + 1;
+
+ skip = 2 * addr_size - (size & (2 * addr_size - 1));
+ if (skip == 2 * addr_size)
+ skip = 0;
+ size += skip;
+
+ for (s = all_segs; s; s = s->next)
+ size += 2 * addr_size;
+
+ size += 2 * addr_size;
+
+ subseg_set (aranges_seg, 0);
+
+ /* Length of the compilation unit. */
+ out_four (size - 4);
+
+ /* Version. */
+ out_two (2);
+
+ /* Offset to .debug_info. */
+ /* ??? sizeof_offset */
+ TC_DWARF2_EMIT_OFFSET (section_symbol (info_seg), 4);
+
+ /* Size of an address (offset portion). */
+ out_byte (addr_size);
+
+ /* Size of a segment descriptor. */
+ out_byte (0);
+
+ /* Align the header. */
+ if (skip)
+ frag_align (ffs (2 * addr_size) - 1, 0, 0);
+
+ for (s = all_segs; s; s = s->next)
+ {
+ fragS *frag;
+ symbolS *beg, *end;
+
+ frag = first_frag_for_seg (s->seg);
+ beg = symbol_temp_new (s->seg, 0, frag);
+ s->text_start = beg;
+
+ frag = last_frag_for_seg (s->seg);
+ end = symbol_temp_new (s->seg, get_frag_fix (frag), frag);
+ s->text_end = end;
+
+ expr.X_op = O_symbol;
+ expr.X_add_symbol = beg;
+ expr.X_add_number = 0;
+ emit_expr (&expr, addr_size);
+
+ expr.X_op = O_subtract;
+ expr.X_add_symbol = end;
+ expr.X_op_symbol = beg;
+ expr.X_add_number = 0;
+ emit_expr (&expr, addr_size);
+ }
+
+ p = frag_more (2 * addr_size);
+ md_number_to_chars (p, 0, addr_size);
+ md_number_to_chars (p + addr_size, 0, addr_size);
+}
+
+/* Emit data for .debug_abbrev. Note that this must be kept in
+ sync with out_debug_info below. */
+
+static void
+out_debug_abbrev (segT abbrev_seg)
+{
+ subseg_set (abbrev_seg, 0);
+
+ out_uleb128 (1);
+ out_uleb128 (DW_TAG_compile_unit);
+ out_byte (DW_CHILDREN_no);
+ out_abbrev (DW_AT_stmt_list, DW_FORM_data4);
+ if (all_segs->next == NULL)
+ {
+ out_abbrev (DW_AT_low_pc, DW_FORM_addr);
+ out_abbrev (DW_AT_high_pc, DW_FORM_addr);
+ }
+ out_abbrev (DW_AT_name, DW_FORM_string);
+ out_abbrev (DW_AT_comp_dir, DW_FORM_string);
+ out_abbrev (DW_AT_producer, DW_FORM_string);
+ out_abbrev (DW_AT_language, DW_FORM_data2);
+ out_abbrev (0, 0);
+
+ /* Terminate the abbreviations for this compilation unit. */
+ out_byte (0);
+}
+
+/* Emit a description of this compilation unit for .debug_info. */
+
+static void
+out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg)
+{
+ char producer[128];
+ char *comp_dir;
+ expressionS expr;
+ symbolS *info_start;
+ symbolS *info_end;
+ char *p;
+ int len;
+ enum dwarf2_format d2f;
+ int sizeof_offset;
+
+ subseg_set (info_seg, 0);
+
+ info_start = symbol_temp_new_now ();
+ info_end = symbol_temp_make ();
+
+ /* Compilation Unit length. */
+ expr.X_op = O_subtract;
+ expr.X_add_symbol = info_end;
+ expr.X_op_symbol = info_start;
+
+ d2f = DWARF2_FORMAT ();
+ if (d2f == dwarf2_format_32bit)
+ {
+ expr.X_add_number = -4;
+ emit_expr (&expr, 4);
+ sizeof_offset = 4;
+ }
+ else if (d2f == dwarf2_format_64bit)
+ {
+ expr.X_add_number = -12;
+ out_four (-1);
+ emit_expr (&expr, 8);
+ sizeof_offset = 8;
+ }
+ else if (d2f == dwarf2_format_64bit_irix)
+ {
+ expr.X_add_number = -8;
+ emit_expr (&expr, 8);
+ sizeof_offset = 8;
+ }
+ else
+ {
+ as_fatal (_("internal error: unknown dwarf2 format"));
+ }
+
+ /* DWARF version. */
+ out_two (2);
+
+ /* .debug_abbrev offset */
+ TC_DWARF2_EMIT_OFFSET (section_symbol (abbrev_seg), sizeof_offset);
+
+ /* Target address size. */
+ out_byte (sizeof_address);
+
+ /* DW_TAG_compile_unit DIE abbrev */
+ out_uleb128 (1);
+
+ /* DW_AT_stmt_list */
+ /* ??? sizeof_offset */
+ TC_DWARF2_EMIT_OFFSET (section_symbol (line_seg), 4);
+
+ /* These two attributes may only be emitted if all of the code is
+ contiguous. Multiple sections are not that. */
+ if (all_segs->next == NULL)
+ {
+ /* DW_AT_low_pc */
+ expr.X_op = O_symbol;
+ expr.X_add_symbol = all_segs->text_start;
+ expr.X_add_number = 0;
+ emit_expr (&expr, sizeof_address);
+
+ /* DW_AT_high_pc */
+ expr.X_op = O_symbol;
+ expr.X_add_symbol = all_segs->text_end;
+ expr.X_add_number = 0;
+ emit_expr (&expr, sizeof_address);
+ }
+
+ /* DW_AT_name. We don't have the actual file name that was present
+ on the command line, so assume files[1] is the main input file.
+ We're not supposed to get called unless at least one line number
+ entry was emitted, so this should always be defined. */
+ if (!files || files_in_use < 1)
+ abort ();
+ if (files[1].dir)
+ {
+ len = strlen (dirs[files[1].dir]);
+ p = frag_more (len + 1);
+ memcpy (p, dirs[files[1].dir], len);
+ p[len] = '/';
+ }
+ len = strlen (files[1].filename) + 1;
+ p = frag_more (len);
+ memcpy (p, files[1].filename, len);
+
+ /* DW_AT_comp_dir */
+ comp_dir = getpwd ();
+ len = strlen (comp_dir) + 1;
+ p = frag_more (len);
+ memcpy (p, comp_dir, len);
+
+ /* DW_AT_producer */
+ sprintf (producer, "GNU AS %s", VERSION);
+ len = strlen (producer) + 1;
+ p = frag_more (len);
+ memcpy (p, producer, len);
+
+ /* DW_AT_language. Yes, this is probably not really MIPS, but the
+ dwarf2 draft has no standard code for assembler. */
+ out_two (DW_LANG_Mips_Assembler);
+
+ symbol_set_value_now (info_end);
+}
+
+void
+dwarf2_finish (void)
+{
+ segT line_seg;
+ struct line_seg *s;
+
+ /* We don't need to do anything unless:
+ - Some debug information was recorded via .file/.loc
+ - or, we are generating DWARF2 information ourself (--gdwarf2)
+ - or, there is a user-provided .debug_info section which could
+ reference the file table in the .debug_line section we generate
+ below. */
+ if (all_segs == NULL
+ && debug_type != DEBUG_DWARF2
+ && bfd_get_section_by_name (stdoutput, ".debug_info") == NULL)
+ return;
+
+ /* Calculate the size of an address for the target machine. */
+ sizeof_address = DWARF2_ADDR_SIZE (stdoutput);
+
+ /* Create and switch to the line number section. */
+ line_seg = subseg_new (".debug_line", 0);
+ bfd_set_section_flags (stdoutput, line_seg, SEC_READONLY);
+
+ /* For each subsection, chain the debug entries together. */
+ for (s = all_segs; s; s = s->next)
+ {
+ struct line_subseg *ss = s->head;
+ struct line_entry **ptail = ss->ptail;
+
+ while ((ss = ss->next) != NULL)
+ {
+ *ptail = ss->head;
+ ptail = ss->ptail;
+ }
+ }
+
+ out_debug_line (line_seg);
+
+ /* If this is assembler generated line info, we need .debug_info
+ and .debug_abbrev sections as well. */
+ if (all_segs != NULL && debug_type == DEBUG_DWARF2)
+ {
+ segT abbrev_seg;
+ segT info_seg;
+ segT aranges_seg;
+
+ info_seg = subseg_new (".debug_info", 0);
+ abbrev_seg = subseg_new (".debug_abbrev", 0);
+ aranges_seg = subseg_new (".debug_aranges", 0);
+
+ bfd_set_section_flags (stdoutput, info_seg, SEC_READONLY);
+ bfd_set_section_flags (stdoutput, abbrev_seg, SEC_READONLY);
+ bfd_set_section_flags (stdoutput, aranges_seg, SEC_READONLY);
+
+ record_alignment (aranges_seg, ffs (2 * sizeof_address) - 1);
+
+ out_debug_aranges (aranges_seg, info_seg);
+ out_debug_abbrev (abbrev_seg);
+ out_debug_info (info_seg, abbrev_seg, line_seg);
+ }
+}
+
+#else
+void
+dwarf2_finish ()
+{
+}
+
+int
+dwarf2dbg_estimate_size_before_relax (frag)
+ fragS *frag ATTRIBUTE_UNUSED;
+{
+ as_fatal (_("dwarf2 is not supported for this object file format"));
+ return 0;
+}
+
+int
+dwarf2dbg_relax_frag (frag)
+ fragS *frag ATTRIBUTE_UNUSED;
+{
+ as_fatal (_("dwarf2 is not supported for this object file format"));
+ return 0;
+}
+
+void
+dwarf2dbg_convert_frag (frag)
+ fragS *frag ATTRIBUTE_UNUSED;
+{
+ as_fatal (_("dwarf2 is not supported for this object file format"));
+}
+
+void
+dwarf2_emit_insn (size)
+ int size ATTRIBUTE_UNUSED;
+{
+}
+
+char *
+dwarf2_directive_file (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ s_app_file (0);
+ return NULL;
+}
+
+void
+dwarf2_directive_loc (dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ as_fatal (_("dwarf2 is not supported for this object file format"));
+}
+#endif /* BFD_ASSEMBLER */
diff --git a/x/binutils/gas/dwarf2dbg.h b/x/binutils/gas/dwarf2dbg.h
new file mode 100644
index 0000000..fe8bf27
--- /dev/null
+++ b/x/binutils/gas/dwarf2dbg.h
@@ -0,0 +1,84 @@
+/* dwarf2dbg.h - DWARF2 debug support
+ Copyright 1999, 2000 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef AS_DWARF2DBG_H
+#define AS_DWARF2DBG_H
+
+#include "as.h"
+
+#define DWARF2_FLAG_BEGIN_STMT (1 << 0) /* beginning of statement */
+#define DWARF2_FLAG_BEGIN_BLOCK (1 << 1) /* beginning of basic block */
+
+struct dwarf2_line_info {
+ unsigned int filenum;
+ unsigned int line;
+ unsigned int column;
+ unsigned int flags;
+};
+
+/* Implements the .file FILENO "FILENAME" directive. FILENO can be 0
+ to indicate that no file number has been assigned. All real file
+ number must be >0. */
+extern char *dwarf2_directive_file (int dummy);
+
+/* Implements the .loc FILENO LINENO [COLUMN] directive. FILENO is
+ the file number, LINENO the line number and the (optional) COLUMN
+ the column of the source code that the following instruction
+ corresponds to. FILENO can be 0 to indicate that the filename
+ specified by the textually most recent .file directive should be
+ used. */
+extern void dwarf2_directive_loc (int dummy);
+
+/* Returns the current source information. If .file directives have
+ been encountered, the info for the corresponding source file is
+ returned. Otherwise, the info for the assembly source file is
+ returned. */
+extern void dwarf2_where (struct dwarf2_line_info *l);
+
+/* This function generates .debug_line info based on the address and
+ source information passed in the arguments. ADDR should be the
+ frag-relative offset of the instruction the information is for and
+ L is the source information that should be associated with that
+ address. */
+extern void dwarf2_gen_line_info (addressT addr, struct dwarf2_line_info *l);
+
+/* Must be called for each generated instruction. */
+extern void dwarf2_emit_insn (int);
+
+extern void dwarf2_finish (void);
+
+extern int dwarf2dbg_estimate_size_before_relax (fragS *);
+extern int dwarf2dbg_relax_frag (fragS *);
+extern void dwarf2dbg_convert_frag (fragS *);
+
+/* An enumeration which describes the sizes of offsets (to DWARF sections)
+ and the mechanism by which the size is indicated. */
+enum dwarf2_format {
+ /* 32-bit format: the initial length field is 4 bytes long. */
+ dwarf2_format_32bit,
+ /* DWARF3 64-bit format: the representation of the initial length
+ (of a DWARF section) is 0xffffffff (4 bytes) followed by eight
+ bytes indicating the actual length. */
+ dwarf2_format_64bit,
+ /* SGI extension to DWARF2: The initial length is eight bytes. */
+ dwarf2_format_64bit_irix
+};
+
+#endif /* AS_DWARF2DBG_H */
diff --git a/x/binutils/gas/ecoff.c b/x/binutils/gas/ecoff.c
new file mode 100644
index 0000000..1de823e
--- /dev/null
+++ b/x/binutils/gas/ecoff.c
@@ -0,0 +1,5236 @@
+/* ECOFF debugging support.
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+ This file was put together by Ian Lance Taylor <ian@cygnus.com>. A
+ good deal of it comes directly from mips-tfile.c, by Michael
+ Meissner <meissner@osf.org>.
+
+ This file is part of GAS.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+
+/* This file is compiled conditionally for those targets which use
+ ECOFF debugging information (e.g., MIPS ECOFF, MIPS ELF, Alpha
+ ECOFF). */
+
+#include "ecoff.h"
+
+#ifdef ECOFF_DEBUGGING
+
+#include "coff/internal.h"
+#include "coff/symconst.h"
+#include "aout/stab_gnu.h"
+
+#include "safe-ctype.h"
+
+/* Why isn't this in coff/sym.h? */
+#define ST_RFDESCAPE 0xfff
+
+/* This file constructs the information used by the ECOFF debugging
+ format. It just builds a large block of data.
+
+ We support both ECOFF style debugging and stabs debugging (the
+ stabs symbols are encapsulated in ECOFF symbols). This should let
+ us handle anything the compiler might throw at us. */
+
+/* Here is a brief description of the MIPS ECOFF symbol table, by
+ Michael Meissner. The MIPS symbol table has the following pieces:
+
+ Symbolic Header
+ |
+ +-- Auxiliary Symbols
+ |
+ +-- Dense number table
+ |
+ +-- Optimizer Symbols
+ |
+ +-- External Strings
+ |
+ +-- External Symbols
+ |
+ +-- Relative file descriptors
+ |
+ +-- File table
+ |
+ +-- Procedure table
+ |
+ +-- Line number table
+ |
+ +-- Local Strings
+ |
+ +-- Local Symbols
+
+ The symbolic header points to each of the other tables, and also
+ contains the number of entries. It also contains a magic number
+ and MIPS compiler version number, such as 2.0.
+
+ The auxiliary table is a series of 32 bit integers, that are
+ referenced as needed from the local symbol table. Unlike standard
+ COFF, the aux. information does not follow the symbol that uses
+ it, but rather is a separate table. In theory, this would allow
+ the MIPS compilers to collapse duplicate aux. entries, but I've not
+ noticed this happening with the 1.31 compiler suite. The different
+ types of aux. entries are:
+
+ 1) dnLow: Low bound on array dimension.
+
+ 2) dnHigh: High bound on array dimension.
+
+ 3) isym: Index to the local symbol which is the start of the
+ function for the end of function first aux. entry.
+
+ 4) width: Width of structures and bitfields.
+
+ 5) count: Count of ranges for variant part.
+
+ 6) rndx: A relative index into the symbol table. The relative
+ index field has two parts: rfd which is a pointer into the
+ relative file index table or ST_RFDESCAPE which says the next
+ aux. entry is the file number, and index: which is the pointer
+ into the local symbol within a given file table. This is for
+ things like references to types defined in another file.
+
+ 7) Type information: This is like the COFF type bits, except it
+ is 32 bits instead of 16; they still have room to add new
+ basic types; and they can handle more than 6 levels of array,
+ pointer, function, etc. Each type information field contains
+ the following structure members:
+
+ a) fBitfield: a bit that says this is a bitfield, and the
+ size in bits follows as the next aux. entry.
+
+ b) continued: a bit that says the next aux. entry is a
+ continuation of the current type information (in case
+ there are more than 6 levels of array/ptr/function).
+
+ c) bt: an integer containing the base type before adding
+ array, pointer, function, etc. qualifiers. The
+ current base types that I have documentation for are:
+
+ btNil -- undefined
+ btAdr -- address - integer same size as ptr
+ btChar -- character
+ btUChar -- unsigned character
+ btShort -- short
+ btUShort -- unsigned short
+ btInt -- int
+ btUInt -- unsigned int
+ btLong -- long
+ btULong -- unsigned long
+ btFloat -- float (real)
+ btDouble -- Double (real)
+ btStruct -- Structure (Record)
+ btUnion -- Union (variant)
+ btEnum -- Enumerated
+ btTypedef -- defined via a typedef isymRef
+ btRange -- subrange of int
+ btSet -- pascal sets
+ btComplex -- fortran complex
+ btDComplex -- fortran double complex
+ btIndirect -- forward or unnamed typedef
+ btFixedDec -- Fixed Decimal
+ btFloatDec -- Float Decimal
+ btString -- Varying Length Character String
+ btBit -- Aligned Bit String
+ btPicture -- Picture
+ btVoid -- Void (MIPS cc revision >= 2.00)
+
+ d) tq0 - tq5: type qualifier fields as needed. The
+ current type qualifier fields I have documentation for
+ are:
+
+ tqNil -- no more qualifiers
+ tqPtr -- pointer
+ tqProc -- procedure
+ tqArray -- array
+ tqFar -- 8086 far pointers
+ tqVol -- volatile
+
+ The dense number table is used in the front ends, and disappears by
+ the time the .o is created.
+
+ With the 1.31 compiler suite, the optimization symbols don't seem
+ to be used as far as I can tell.
+
+ The linker is the first entity that creates the relative file
+ descriptor table, and I believe it is used so that the individual
+ file table pointers don't have to be rewritten when the objects are
+ merged together into the program file.
+
+ Unlike COFF, the basic symbol & string tables are split into
+ external and local symbols/strings. The relocation information
+ only goes off of the external symbol table, and the debug
+ information only goes off of the internal symbol table. The
+ external symbols can have links to an appropriate file index and
+ symbol within the file to give it the appropriate type information.
+ Because of this, the external symbols are actually larger than the
+ internal symbols (to contain the link information), and contain the
+ local symbol structure as a member, though this member is not the
+ first member of the external symbol structure (!). I suspect this
+ split is to make strip easier to deal with.
+
+ Each file table has offsets for where the line numbers, local
+ strings, local symbols, and procedure table starts from within the
+ global tables, and the indexs are reset to 0 for each of those
+ tables for the file.
+
+ The procedure table contains the binary equivalents of the .ent
+ (start of the function address), .frame (what register is the
+ virtual frame pointer, constant offset from the register to obtain
+ the VFP, and what register holds the return address), .mask/.fmask
+ (bitmask of saved registers, and where the first register is stored
+ relative to the VFP) assembler directives. It also contains the
+ low and high bounds of the line numbers if debugging is turned on.
+
+ The line number table is a compressed form of the normal COFF line
+ table. Each line number entry is either 1 or 3 bytes long, and
+ contains a signed delta from the previous line, and an unsigned
+ count of the number of instructions this statement takes.
+
+ The local symbol table contains the following fields:
+
+ 1) iss: index to the local string table giving the name of the
+ symbol.
+
+ 2) value: value of the symbol (address, register number, etc.).
+
+ 3) st: symbol type. The current symbol types are:
+
+ stNil -- Nuthin' special
+ stGlobal -- external symbol
+ stStatic -- static
+ stParam -- procedure argument
+ stLocal -- local variable
+ stLabel -- label
+ stProc -- External Procedure
+ stBlock -- beginning of block
+ stEnd -- end (of anything)
+ stMember -- member (of anything)
+ stTypedef -- type definition
+ stFile -- file name
+ stRegReloc -- register relocation
+ stForward -- forwarding address
+ stStaticProc -- Static procedure
+ stConstant -- const
+
+ 4) sc: storage class. The current storage classes are:
+
+ scText -- text symbol
+ scData -- initialized data symbol
+ scBss -- un-initialized data symbol
+ scRegister -- value of symbol is register number
+ scAbs -- value of symbol is absolute
+ scUndefined -- who knows?
+ scCdbLocal -- variable's value is IN se->va.??
+ scBits -- this is a bit field
+ scCdbSystem -- value is IN debugger's address space
+ scRegImage -- register value saved on stack
+ scInfo -- symbol contains debugger information
+ scUserStruct -- addr in struct user for current process
+ scSData -- load time only small data
+ scSBss -- load time only small common
+ scRData -- load time only read only data
+ scVar -- Var parameter (fortranpascal)
+ scCommon -- common variable
+ scSCommon -- small common
+ scVarRegister -- Var parameter in a register
+ scVariant -- Variant record
+ scSUndefined -- small undefined(external) data
+ scInit -- .init section symbol
+
+ 5) index: pointer to a local symbol or aux. entry.
+
+ For the following program:
+
+ #include <stdio.h>
+
+ main(){
+ printf("Hello World!\n");
+ return 0;
+ }
+
+ Mips-tdump produces the following information:
+
+ Global file header:
+ magic number 0x162
+ # sections 2
+ timestamp 645311799, Wed Jun 13 17:16:39 1990
+ symbolic header offset 284
+ symbolic header size 96
+ optional header 56
+ flags 0x0
+
+ Symbolic header, magic number = 0x7009, vstamp = 1.31:
+
+ Info Offset Number Bytes
+ ==== ====== ====== =====
+
+ Line numbers 380 4 4 [13]
+ Dense numbers 0 0 0
+ Procedures Tables 384 1 52
+ Local Symbols 436 16 192
+ Optimization Symbols 0 0 0
+ Auxiliary Symbols 628 39 156
+ Local Strings 784 80 80
+ External Strings 864 144 144
+ File Tables 1008 2 144
+ Relative Files 0 0 0
+ External Symbols 1152 20 320
+
+ File #0, "hello2.c"
+
+ Name index = 1 Readin = No
+ Merge = No Endian = LITTLE
+ Debug level = G2 Language = C
+ Adr = 0x00000000
+
+ Info Start Number Size Offset
+ ==== ===== ====== ==== ======
+ Local strings 0 15 15 784
+ Local symbols 0 6 72 436
+ Line numbers 0 13 13 380
+ Optimization symbols 0 0 0 0
+ Procedures 0 1 52 384
+ Auxiliary symbols 0 14 56 628
+ Relative Files 0 0 0 0
+
+ There are 6 local symbols, starting at 436
+
+ Symbol# 0: "hello2.c"
+ End+1 symbol = 6
+ String index = 1
+ Storage class = Text Index = 6
+ Symbol type = File Value = 0
+
+ Symbol# 1: "main"
+ End+1 symbol = 5
+ Type = int
+ String index = 10
+ Storage class = Text Index = 12
+ Symbol type = Proc Value = 0
+
+ Symbol# 2: ""
+ End+1 symbol = 4
+ String index = 0
+ Storage class = Text Index = 4
+ Symbol type = Block Value = 8
+
+ Symbol# 3: ""
+ First symbol = 2
+ String index = 0
+ Storage class = Text Index = 2
+ Symbol type = End Value = 28
+
+ Symbol# 4: "main"
+ First symbol = 1
+ String index = 10
+ Storage class = Text Index = 1
+ Symbol type = End Value = 52
+
+ Symbol# 5: "hello2.c"
+ First symbol = 0
+ String index = 1
+ Storage class = Text Index = 0
+ Symbol type = End Value = 0
+
+ There are 14 auxiliary table entries, starting at 628.
+
+ * #0 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #1 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
+ * #2 8, [ 8/ 0], [ 2 0:0 0:0:0:0:0:0]
+ * #3 16, [ 16/ 0], [ 4 0:0 0:0:0:0:0:0]
+ * #4 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
+ * #5 32, [ 32/ 0], [ 8 0:0 0:0:0:0:0:0]
+ * #6 40, [ 40/ 0], [10 0:0 0:0:0:0:0:0]
+ * #7 44, [ 44/ 0], [11 0:0 0:0:0:0:0:0]
+ * #8 12, [ 12/ 0], [ 3 0:0 0:0:0:0:0:0]
+ * #9 20, [ 20/ 0], [ 5 0:0 0:0:0:0:0:0]
+ * #10 28, [ 28/ 0], [ 7 0:0 0:0:0:0:0:0]
+ * #11 36, [ 36/ 0], [ 9 0:0 0:0:0:0:0:0]
+ #12 5, [ 5/ 0], [ 1 1:0 0:0:0:0:0:0]
+ #13 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
+
+ There are 1 procedure descriptor entries, starting at 0.
+
+ Procedure descriptor 0:
+ Name index = 10 Name = "main"
+ .mask 0x80000000,-4 .fmask 0x00000000,0
+ .frame $29,24,$31
+ Opt. start = -1 Symbols start = 1
+ First line # = 3 Last line # = 6
+ Line Offset = 0 Address = 0x00000000
+
+ There are 4 bytes holding line numbers, starting at 380.
+ Line 3, delta 0, count 2
+ Line 4, delta 1, count 3
+ Line 5, delta 1, count 2
+ Line 6, delta 1, count 6
+
+ File #1, "/usr/include/stdio.h"
+
+ Name index = 1 Readin = No
+ Merge = Yes Endian = LITTLE
+ Debug level = G2 Language = C
+ Adr = 0x00000000
+
+ Info Start Number Size Offset
+ ==== ===== ====== ==== ======
+ Local strings 15 65 65 799
+ Local symbols 6 10 120 508
+ Line numbers 0 0 0 380
+ Optimization symbols 0 0 0 0
+ Procedures 1 0 0 436
+ Auxiliary symbols 14 25 100 684
+ Relative Files 0 0 0 0
+
+ There are 10 local symbols, starting at 442
+
+ Symbol# 0: "/usr/include/stdio.h"
+ End+1 symbol = 10
+ String index = 1
+ Storage class = Text Index = 10
+ Symbol type = File Value = 0
+
+ Symbol# 1: "_iobuf"
+ End+1 symbol = 9
+ String index = 22
+ Storage class = Info Index = 9
+ Symbol type = Block Value = 20
+
+ Symbol# 2: "_cnt"
+ Type = int
+ String index = 29
+ Storage class = Info Index = 4
+ Symbol type = Member Value = 0
+
+ Symbol# 3: "_ptr"
+ Type = ptr to char
+ String index = 34
+ Storage class = Info Index = 15
+ Symbol type = Member Value = 32
+
+ Symbol# 4: "_base"
+ Type = ptr to char
+ String index = 39
+ Storage class = Info Index = 16
+ Symbol type = Member Value = 64
+
+ Symbol# 5: "_bufsiz"
+ Type = int
+ String index = 45
+ Storage class = Info Index = 4
+ Symbol type = Member Value = 96
+
+ Symbol# 6: "_flag"
+ Type = short
+ String index = 53
+ Storage class = Info Index = 3
+ Symbol type = Member Value = 128
+
+ Symbol# 7: "_file"
+ Type = char
+ String index = 59
+ Storage class = Info Index = 2
+ Symbol type = Member Value = 144
+
+ Symbol# 8: ""
+ First symbol = 1
+ String index = 0
+ Storage class = Info Index = 1
+ Symbol type = End Value = 0
+
+ Symbol# 9: "/usr/include/stdio.h"
+ First symbol = 0
+ String index = 1
+ Storage class = Text Index = 0
+ Symbol type = End Value = 0
+
+ There are 25 auxiliary table entries, starting at 642.
+
+ * #14 -1, [4095/1048575], [63 1:1 f:f:f:f:f:f]
+ #15 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
+ #16 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
+ * #17 196656, [ 48/ 48], [12 0:0 3:0:0:0:0:0]
+ * #18 8191, [4095/ 1], [63 1:1 0:0:0:0:f:1]
+ * #19 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
+ * #20 20479, [4095/ 4], [63 1:1 0:0:0:0:f:4]
+ * #21 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
+ * #22 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #23 2, [ 2/ 0], [ 0 0:1 0:0:0:0:0:0]
+ * #24 160, [ 160/ 0], [40 0:0 0:0:0:0:0:0]
+ * #25 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #26 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #27 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #28 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #29 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #30 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #31 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #32 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #33 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #34 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #35 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #36 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #37 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #38 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+
+ There are 0 procedure descriptor entries, starting at 1.
+
+ There are 20 external symbols, starting at 1152
+
+ Symbol# 0: "_iob"
+ Type = array [3 {160}] of struct _iobuf { ifd = 1, index = 1 }
+ String index = 0 Ifd = 1
+ Storage class = Nil Index = 17
+ Symbol type = Global Value = 60
+
+ Symbol# 1: "fopen"
+ String index = 5 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 2: "fdopen"
+ String index = 11 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 3: "freopen"
+ String index = 18 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 4: "popen"
+ String index = 26 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 5: "tmpfile"
+ String index = 32 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 6: "ftell"
+ String index = 40 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 7: "rewind"
+ String index = 46 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 8: "setbuf"
+ String index = 53 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 9: "setbuffer"
+ String index = 60 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 10: "setlinebuf"
+ String index = 70 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 11: "fgets"
+ String index = 81 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 12: "gets"
+ String index = 87 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 13: "ctermid"
+ String index = 92 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 14: "cuserid"
+ String index = 100 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 15: "tempnam"
+ String index = 108 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 16: "tmpnam"
+ String index = 116 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 17: "sprintf"
+ String index = 123 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 18: "main"
+ Type = int
+ String index = 131 Ifd = 0
+ Storage class = Text Index = 1
+ Symbol type = Proc Value = 0
+
+ Symbol# 19: "printf"
+ String index = 136 Ifd = 0
+ Storage class = Undefined Index = 1048575
+ Symbol type = Proc Value = 0
+
+ The following auxiliary table entries were unused:
+
+ #0 0 0x00000000 void
+ #2 8 0x00000008 char
+ #3 16 0x00000010 short
+ #4 24 0x00000018 int
+ #5 32 0x00000020 long
+ #6 40 0x00000028 float
+ #7 44 0x0000002c double
+ #8 12 0x0000000c unsigned char
+ #9 20 0x00000014 unsigned short
+ #10 28 0x0000001c unsigned int
+ #11 36 0x00000024 unsigned long
+ #14 0 0x00000000 void
+ #15 24 0x00000018 int
+ #19 32 0x00000020 long
+ #20 40 0x00000028 float
+ #21 44 0x0000002c double
+ #22 12 0x0000000c unsigned char
+ #23 20 0x00000014 unsigned short
+ #24 28 0x0000001c unsigned int
+ #25 36 0x00000024 unsigned long
+ #26 48 0x00000030 struct no name { ifd = -1, index = 1048575 }
+*/
+
+/* Redefinition of of storage classes as an enumeration for better
+ debugging. */
+
+typedef enum sc {
+ sc_Nil = scNil, /* no storage class */
+ sc_Text = scText, /* text symbol */
+ sc_Data = scData, /* initialized data symbol */
+ sc_Bss = scBss, /* un-initialized data symbol */
+ sc_Register = scRegister, /* value of symbol is register number */
+ sc_Abs = scAbs, /* value of symbol is absolute */
+ sc_Undefined = scUndefined, /* who knows? */
+ sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */
+ sc_Bits = scBits, /* this is a bit field */
+ sc_CdbSystem = scCdbSystem, /* value is IN CDB's address space */
+ sc_RegImage = scRegImage, /* register value saved on stack */
+ sc_Info = scInfo, /* symbol contains debugger information */
+ sc_UserStruct = scUserStruct, /* addr in struct user for current process */
+ sc_SData = scSData, /* load time only small data */
+ sc_SBss = scSBss, /* load time only small common */
+ sc_RData = scRData, /* load time only read only data */
+ sc_Var = scVar, /* Var parameter (fortran,pascal) */
+ sc_Common = scCommon, /* common variable */
+ sc_SCommon = scSCommon, /* small common */
+ sc_VarRegister = scVarRegister, /* Var parameter in a register */
+ sc_Variant = scVariant, /* Variant record */
+ sc_SUndefined = scSUndefined, /* small undefined(external) data */
+ sc_Init = scInit, /* .init section symbol */
+ sc_Max = scMax /* Max storage class+1 */
+} sc_t;
+
+/* Redefinition of symbol type. */
+
+typedef enum st {
+ st_Nil = stNil, /* Nuthin' special */
+ st_Global = stGlobal, /* external symbol */
+ st_Static = stStatic, /* static */
+ st_Param = stParam, /* procedure argument */
+ st_Local = stLocal, /* local variable */
+ st_Label = stLabel, /* label */
+ st_Proc = stProc, /* " " Procedure */
+ st_Block = stBlock, /* beginning of block */
+ st_End = stEnd, /* end (of anything) */
+ st_Member = stMember, /* member (of anything - struct/union/enum */
+ st_Typedef = stTypedef, /* type definition */
+ st_File = stFile, /* file name */
+ st_RegReloc = stRegReloc, /* register relocation */
+ st_Forward = stForward, /* forwarding address */
+ st_StaticProc = stStaticProc, /* load time only static procs */
+ st_Constant = stConstant, /* const */
+ st_Str = stStr, /* string */
+ st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */
+ st_Expr = stExpr, /* 2+2 vs. 4 */
+ st_Type = stType, /* post-coercion SER */
+ st_Max = stMax /* max type+1 */
+} st_t;
+
+/* Redefinition of type qualifiers. */
+
+typedef enum tq {
+ tq_Nil = tqNil, /* bt is what you see */
+ tq_Ptr = tqPtr, /* pointer */
+ tq_Proc = tqProc, /* procedure */
+ tq_Array = tqArray, /* duh */
+ tq_Far = tqFar, /* longer addressing - 8086/8 land */
+ tq_Vol = tqVol, /* volatile */
+ tq_Max = tqMax /* Max type qualifier+1 */
+} tq_t;
+
+/* Redefinition of basic types. */
+
+typedef enum bt {
+ bt_Nil = btNil, /* undefined */
+ bt_Adr = btAdr, /* address - integer same size as pointer */
+ bt_Char = btChar, /* character */
+ bt_UChar = btUChar, /* unsigned character */
+ bt_Short = btShort, /* short */
+ bt_UShort = btUShort, /* unsigned short */
+ bt_Int = btInt, /* int */
+ bt_UInt = btUInt, /* unsigned int */
+ bt_Long = btLong, /* long */
+ bt_ULong = btULong, /* unsigned long */
+ bt_Float = btFloat, /* float (real) */
+ bt_Double = btDouble, /* Double (real) */
+ bt_Struct = btStruct, /* Structure (Record) */
+ bt_Union = btUnion, /* Union (variant) */
+ bt_Enum = btEnum, /* Enumerated */
+ bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */
+ bt_Range = btRange, /* subrange of int */
+ bt_Set = btSet, /* pascal sets */
+ bt_Complex = btComplex, /* fortran complex */
+ bt_DComplex = btDComplex, /* fortran double complex */
+ bt_Indirect = btIndirect, /* forward or unnamed typedef */
+ bt_FixedDec = btFixedDec, /* Fixed Decimal */
+ bt_FloatDec = btFloatDec, /* Float Decimal */
+ bt_String = btString, /* Varying Length Character String */
+ bt_Bit = btBit, /* Aligned Bit String */
+ bt_Picture = btPicture, /* Picture */
+ bt_Void = btVoid, /* Void */
+ bt_Max = btMax /* Max basic type+1 */
+} bt_t;
+
+#define N_TQ itqMax
+
+/* States for whether to hash type or not. */
+typedef enum hash_state {
+ hash_no = 0, /* Don't hash type */
+ hash_yes = 1, /* OK to hash type, or use previous hash */
+ hash_record = 2 /* OK to record hash, but don't use prev. */
+} hash_state_t;
+
+/* Types of different sized allocation requests. */
+enum alloc_type {
+ alloc_type_none, /* dummy value */
+ alloc_type_scope, /* nested scopes linked list */
+ alloc_type_vlinks, /* glue linking pages in varray */
+ alloc_type_shash, /* string hash element */
+ alloc_type_thash, /* type hash element */
+ alloc_type_tag, /* struct/union/tag element */
+ alloc_type_forward, /* element to hold unknown tag */
+ alloc_type_thead, /* head of type hash list */
+ alloc_type_varray, /* general varray allocation */
+ alloc_type_lineno, /* line number list */
+ alloc_type_last /* last+1 element for array bounds */
+};
+
+/* Types of auxiliary type information. */
+enum aux_type {
+ aux_tir, /* TIR type information */
+ aux_rndx, /* relative index into symbol table */
+ aux_dnLow, /* low dimension */
+ aux_dnHigh, /* high dimension */
+ aux_isym, /* symbol table index (end of proc) */
+ aux_iss, /* index into string space (not used) */
+ aux_width, /* width for non-default sized struc fields */
+ aux_count /* count of ranges for variant arm */
+};
+
+/* Structures to provide n-number of virtual arrays, each of which can
+ grow linearly, and which are written in the object file as
+ sequential pages. On systems with a BSD malloc, the
+ MAX_CLUSTER_PAGES should be 1 less than a power of two, since
+ malloc adds it's overhead, and rounds up to the next power of 2.
+ Pages are linked together via a linked list.
+
+ If PAGE_SIZE is > 4096, the string length in the shash_t structure
+ can't be represented (assuming there are strings > 4096 bytes). */
+
+/* FIXME: Yes, there can be such strings while emitting C++ class debug
+ info. Templates are the offender here, the test case in question
+ having a mangled class name of
+
+ t7rb_tree4Z4xkeyZt4pair2ZC4xkeyZt7xsocket1Z4UserZt9select1st2Zt4pair\
+ 2ZC4xkeyZt7xsocket1Z4UserZ4xkeyZt4less1Z4xkey
+
+ Repeat that a couple dozen times while listing the class members and
+ you've got strings over 4k. Hack around this for now by increasing
+ the page size. A proper solution would abandon this structure scheme
+ certainly for very large strings, and possibly entirely. */
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE (8*1024) /* size of varray pages */
+#endif
+
+#define PAGE_USIZE ((unsigned long) PAGE_SIZE)
+
+#ifndef MAX_CLUSTER_PAGES /* # pages to get from system */
+#define MAX_CLUSTER_PAGES 63
+#endif
+
+/* Linked list connecting separate page allocations. */
+typedef struct vlinks {
+ struct vlinks *prev; /* previous set of pages */
+ struct vlinks *next; /* next set of pages */
+ union page *datum; /* start of page */
+ unsigned long start_index; /* starting index # of page */
+} vlinks_t;
+
+/* Virtual array header. */
+typedef struct varray {
+ vlinks_t *first; /* first page link */
+ vlinks_t *last; /* last page link */
+ unsigned long num_allocated; /* # objects allocated */
+ unsigned short object_size; /* size in bytes of each object */
+ unsigned short objects_per_page; /* # objects that can fit on a page */
+ unsigned short objects_last_page; /* # objects allocated on last page */
+} varray_t;
+
+#ifndef MALLOC_CHECK
+#define OBJECTS_PER_PAGE(type) (PAGE_SIZE / sizeof (type))
+#else
+#define OBJECTS_PER_PAGE(type) ((sizeof (type) > 1) ? 1 : PAGE_SIZE)
+#endif
+
+#define INIT_VARRAY(type) { /* macro to initialize a varray */ \
+ (vlinks_t *)0, /* first */ \
+ (vlinks_t *)0, /* last */ \
+ 0, /* num_allocated */ \
+ sizeof (type), /* object_size */ \
+ OBJECTS_PER_PAGE (type), /* objects_per_page */ \
+ OBJECTS_PER_PAGE (type), /* objects_last_page */ \
+}
+
+/* Master type for indexes within the symbol table. */
+typedef unsigned long symint_t;
+
+/* Linked list support for nested scopes (file, block, structure, etc.). */
+typedef struct scope {
+ struct scope *prev; /* previous scope level */
+ struct scope *free; /* free list pointer */
+ struct localsym *lsym; /* pointer to local symbol node */
+ st_t type; /* type of the node */
+} scope_t;
+
+/* For a local symbol we store a gas symbol as well as the debugging
+ information we generate. The gas symbol will be NULL if this is
+ only a debugging symbol. */
+typedef struct localsym {
+ const char *name; /* symbol name */
+ symbolS *as_sym; /* symbol as seen by gas */
+ bfd_vma addend; /* addend to as_sym value */
+ struct efdr *file_ptr; /* file pointer */
+ struct ecoff_proc *proc_ptr; /* proc pointer */
+ struct localsym *begin_ptr; /* symbol at start of block */
+ struct ecoff_aux *index_ptr; /* index value to be filled in */
+ struct forward *forward_ref; /* forward references to this symbol */
+ long sym_index; /* final symbol index */
+ EXTR ecoff_sym; /* ECOFF debugging symbol */
+} localsym_t;
+
+/* For aux information we keep the type and the data. */
+typedef struct ecoff_aux {
+ enum aux_type type; /* aux type */
+ AUXU data; /* aux data */
+} aux_t;
+
+/* For a procedure we store the gas symbol as well as the PDR
+ debugging information. */
+typedef struct ecoff_proc {
+ localsym_t *sym; /* associated symbol */
+ PDR pdr; /* ECOFF debugging info */
+} proc_t;
+
+/* Number of proc_t structures allocated. */
+static unsigned long proc_cnt;
+
+/* Forward reference list for tags referenced, but not yet defined. */
+typedef struct forward {
+ struct forward *next; /* next forward reference */
+ struct forward *free; /* free list pointer */
+ aux_t *ifd_ptr; /* pointer to store file index */
+ aux_t *index_ptr; /* pointer to store symbol index */
+} forward_t;
+
+/* Linked list support for tags. The first tag in the list is always
+ the current tag for that block. */
+typedef struct tag {
+ struct tag *free; /* free list pointer */
+ struct shash *hash_ptr; /* pointer to the hash table head */
+ struct tag *same_name; /* tag with same name in outer scope */
+ struct tag *same_block; /* next tag defined in the same block. */
+ struct forward *forward_ref; /* list of forward references */
+ bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */
+ symint_t ifd; /* file # tag defined in */
+ localsym_t *sym; /* file's local symbols */
+} tag_t;
+
+/* Head of a block's linked list of tags. */
+typedef struct thead {
+ struct thead *prev; /* previous block */
+ struct thead *free; /* free list pointer */
+ struct tag *first_tag; /* first tag in block defined */
+} thead_t;
+
+/* Union containing pointers to each the small structures which are freed up. */
+typedef union small_free {
+ scope_t *f_scope; /* scope structure */
+ thead_t *f_thead; /* tag head structure */
+ tag_t *f_tag; /* tag element structure */
+ forward_t *f_forward; /* forward tag reference */
+} small_free_t;
+
+/* String hash table entry. */
+
+typedef struct shash {
+ char *string; /* string we are hashing */
+ symint_t indx; /* index within string table */
+ EXTR *esym_ptr; /* global symbol pointer */
+ localsym_t *sym_ptr; /* local symbol pointer */
+ localsym_t *end_ptr; /* symbol pointer to end block */
+ tag_t *tag_ptr; /* tag pointer */
+ proc_t *proc_ptr; /* procedure descriptor pointer */
+} shash_t;
+
+/* Type hash table support. The size of the hash table must fit
+ within a page with the other extended file descriptor information.
+ Because unique types which are hashed are fewer in number than
+ strings, we use a smaller hash value. */
+
+#define HASHBITS 30
+
+#ifndef THASH_SIZE
+#define THASH_SIZE 113
+#endif
+
+typedef struct thash {
+ struct thash *next; /* next hash value */
+ AUXU type; /* type we are hashing */
+ symint_t indx; /* index within string table */
+} thash_t;
+
+/* Extended file descriptor that contains all of the support necessary
+ to add things to each file separately. */
+typedef struct efdr {
+ FDR fdr; /* File header to be written out */
+ FDR *orig_fdr; /* original file header */
+ char *name; /* filename */
+ int fake; /* whether this is faked .file */
+ symint_t void_type; /* aux. pointer to 'void' type */
+ symint_t int_type; /* aux. pointer to 'int' type */
+ scope_t *cur_scope; /* current nested scopes */
+ symint_t file_index; /* current file number */
+ int nested_scopes; /* # nested scopes */
+ varray_t strings; /* local strings */
+ varray_t symbols; /* local symbols */
+ varray_t procs; /* procedures */
+ varray_t aux_syms; /* auxiliary symbols */
+ struct efdr *next_file; /* next file descriptor */
+ /* string/type hash tables */
+ struct hash_control *str_hash; /* string hash table */
+ thash_t *thash_head[THASH_SIZE];
+} efdr_t;
+
+/* Pre-initialized extended file structure. */
+static const efdr_t init_file = {
+ { /* FDR structure */
+ 0, /* adr: memory address of beginning of file */
+ 0, /* rss: file name (of source, if known) */
+ 0, /* issBase: file's string space */
+ 0, /* cbSs: number of bytes in the ss */
+ 0, /* isymBase: beginning of symbols */
+ 0, /* csym: count file's of symbols */
+ 0, /* ilineBase: file's line symbols */
+ 0, /* cline: count of file's line symbols */
+ 0, /* ioptBase: file's optimization entries */
+ 0, /* copt: count of file's optimization entries */
+ 0, /* ipdFirst: start of procedures for this file */
+ 0, /* cpd: count of procedures for this file */
+ 0, /* iauxBase: file's auxiliary entries */
+ 0, /* caux: count of file's auxiliary entries */
+ 0, /* rfdBase: index into the file indirect table */
+ 0, /* crfd: count file indirect entries */
+ langC, /* lang: language for this file */
+ 1, /* fMerge: whether this file can be merged */
+ 0, /* fReadin: true if read in (not just created) */
+ TARGET_BYTES_BIG_ENDIAN, /* fBigendian: if 1, compiled on big endian machine */
+ GLEVEL_2, /* glevel: level this file was compiled with */
+ 0, /* reserved: reserved for future use */
+ 0, /* cbLineOffset: byte offset from header for this file ln's */
+ 0, /* cbLine: size of lines for this file */
+ },
+
+ (FDR *)0, /* orig_fdr: original file header pointer */
+ (char *)0, /* name: pointer to filename */
+ 0, /* fake: whether this is a faked .file */
+ 0, /* void_type: ptr to aux node for void type */
+ 0, /* int_type: ptr to aux node for int type */
+ (scope_t *)0, /* cur_scope: current scope being processed */
+ 0, /* file_index: current file # */
+ 0, /* nested_scopes: # nested scopes */
+ INIT_VARRAY (char), /* strings: local string varray */
+ INIT_VARRAY (localsym_t), /* symbols: local symbols varray */
+ INIT_VARRAY (proc_t), /* procs: procedure varray */
+ INIT_VARRAY (aux_t), /* aux_syms: auxiliary symbols varray */
+
+ (struct efdr *)0, /* next_file: next file structure */
+
+ (struct hash_control *)0, /* str_hash: string hash table */
+ { 0 }, /* thash_head: type hash table */
+};
+
+static efdr_t *first_file; /* first file descriptor */
+static efdr_t **last_file_ptr = &first_file; /* file descriptor tail */
+
+/* Line number information is kept in a list until the assembly is
+ finished. */
+typedef struct lineno_list {
+ struct lineno_list *next; /* next element in list */
+ efdr_t *file; /* file this line is in */
+ proc_t *proc; /* procedure this line is in */
+ fragS *frag; /* fragment this line number is in */
+ unsigned long paddr; /* offset within fragment */
+ long lineno; /* actual line number */
+} lineno_list_t;
+
+static lineno_list_t *first_lineno;
+static lineno_list_t *last_lineno;
+static lineno_list_t **last_lineno_ptr = &first_lineno;
+
+/* Sometimes there will be some .loc statements before a .ent. We
+ keep them in this list so that we can fill in the procedure pointer
+ after we see the .ent. */
+static lineno_list_t *noproc_lineno;
+
+/* Union of various things that are held in pages. */
+typedef union page {
+ char byte [ PAGE_SIZE ];
+ unsigned char ubyte [ PAGE_SIZE ];
+ efdr_t file [ PAGE_SIZE / sizeof (efdr_t) ];
+ FDR ofile [ PAGE_SIZE / sizeof (FDR) ];
+ proc_t proc [ PAGE_SIZE / sizeof (proc_t) ];
+ localsym_t sym [ PAGE_SIZE / sizeof (localsym_t) ];
+ aux_t aux [ PAGE_SIZE / sizeof (aux_t) ];
+ DNR dense [ PAGE_SIZE / sizeof (DNR) ];
+ scope_t scope [ PAGE_SIZE / sizeof (scope_t) ];
+ vlinks_t vlinks [ PAGE_SIZE / sizeof (vlinks_t) ];
+ shash_t shash [ PAGE_SIZE / sizeof (shash_t) ];
+ thash_t thash [ PAGE_SIZE / sizeof (thash_t) ];
+ tag_t tag [ PAGE_SIZE / sizeof (tag_t) ];
+ forward_t forward [ PAGE_SIZE / sizeof (forward_t) ];
+ thead_t thead [ PAGE_SIZE / sizeof (thead_t) ];
+ lineno_list_t lineno [ PAGE_SIZE / sizeof (lineno_list_t) ];
+} page_type;
+
+/* Structure holding allocation information for small sized structures. */
+typedef struct alloc_info {
+ char *alloc_name; /* name of this allocation type (must be first) */
+ page_type *cur_page; /* current page being allocated from */
+ small_free_t free_list; /* current free list if any */
+ int unallocated; /* number of elements unallocated on page */
+ int total_alloc; /* total number of allocations */
+ int total_free; /* total number of frees */
+ int total_pages; /* total number of pages allocated */
+} alloc_info_t;
+
+/* Type information collected together. */
+typedef struct type_info {
+ bt_t basic_type; /* basic type */
+ int orig_type; /* original COFF-based type */
+ int num_tq; /* # type qualifiers */
+ int num_dims; /* # dimensions */
+ int num_sizes; /* # sizes */
+ int extra_sizes; /* # extra sizes not tied with dims */
+ tag_t * tag_ptr; /* tag pointer */
+ int bitfield; /* symbol is a bitfield */
+ tq_t type_qualifiers[N_TQ]; /* type qualifiers (ptr, func, array)*/
+ symint_t dimensions [N_TQ]; /* dimensions for each array */
+ symint_t sizes [N_TQ+2]; /* sizes of each array slice + size of
+ struct/union/enum + bitfield size */
+} type_info_t;
+
+/* Pre-initialized type_info struct. */
+static const type_info_t type_info_init = {
+ bt_Nil, /* basic type */
+ T_NULL, /* original COFF-based type */
+ 0, /* # type qualifiers */
+ 0, /* # dimensions */
+ 0, /* # sizes */
+ 0, /* sizes not tied with dims */
+ NULL, /* ptr to tag */
+ 0, /* bitfield */
+ { /* type qualifiers */
+ tq_Nil,
+ tq_Nil,
+ tq_Nil,
+ tq_Nil,
+ tq_Nil,
+ tq_Nil,
+ },
+ { /* dimensions */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ },
+ { /* sizes */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ },
+};
+
+/* Global hash table for the tags table and global table for file
+ descriptors. */
+
+static varray_t file_desc = INIT_VARRAY (efdr_t);
+
+static struct hash_control *tag_hash;
+
+/* Static types for int and void. Also, remember the last function's
+ type (which is set up when we encounter the declaration for the
+ function, and used when the end block for the function is emitted. */
+
+static type_info_t int_type_info;
+static type_info_t void_type_info;
+static type_info_t last_func_type_info;
+static symbolS *last_func_sym_value;
+
+/* Convert COFF basic type to ECOFF basic type. The T_NULL type
+ really should use bt_Void, but this causes the current ecoff GDB to
+ issue unsupported type messages, and the Ultrix 4.00 dbx (aka MIPS
+ 2.0) doesn't understand it, even though the compiler generates it.
+ Maybe this will be fixed in 2.10 or 2.20 of the MIPS compiler
+ suite, but for now go with what works.
+
+ It would make sense for the .type and .scl directives to use the
+ ECOFF numbers directly, rather than using the COFF numbers and
+ mapping them. Unfortunately, this is historically what mips-tfile
+ expects, and changing gcc now would be a considerable pain (the
+ native compiler generates debugging information internally, rather
+ than via the assembler, so it will never use .type or .scl). */
+
+static const bt_t map_coff_types[] = {
+ bt_Nil, /* T_NULL */
+ bt_Nil, /* T_ARG */
+ bt_Char, /* T_CHAR */
+ bt_Short, /* T_SHORT */
+ bt_Int, /* T_INT */
+ bt_Long, /* T_LONG */
+ bt_Float, /* T_FLOAT */
+ bt_Double, /* T_DOUBLE */
+ bt_Struct, /* T_STRUCT */
+ bt_Union, /* T_UNION */
+ bt_Enum, /* T_ENUM */
+ bt_Enum, /* T_MOE */
+ bt_UChar, /* T_UCHAR */
+ bt_UShort, /* T_USHORT */
+ bt_UInt, /* T_UINT */
+ bt_ULong /* T_ULONG */
+};
+
+/* Convert COFF storage class to ECOFF storage class. */
+static const sc_t map_coff_storage[] = {
+ sc_Nil, /* 0: C_NULL */
+ sc_Abs, /* 1: C_AUTO auto var */
+ sc_Undefined, /* 2: C_EXT external */
+ sc_Data, /* 3: C_STAT static */
+ sc_Register, /* 4: C_REG register */
+ sc_Undefined, /* 5: C_EXTDEF ??? */
+ sc_Text, /* 6: C_LABEL label */
+ sc_Text, /* 7: C_ULABEL user label */
+ sc_Info, /* 8: C_MOS member of struct */
+ sc_Abs, /* 9: C_ARG argument */
+ sc_Info, /* 10: C_STRTAG struct tag */
+ sc_Info, /* 11: C_MOU member of union */
+ sc_Info, /* 12: C_UNTAG union tag */
+ sc_Info, /* 13: C_TPDEF typedef */
+ sc_Data, /* 14: C_USTATIC ??? */
+ sc_Info, /* 15: C_ENTAG enum tag */
+ sc_Info, /* 16: C_MOE member of enum */
+ sc_Register, /* 17: C_REGPARM register parameter */
+ sc_Bits, /* 18; C_FIELD bitfield */
+ sc_Nil, /* 19 */
+ sc_Nil, /* 20 */
+ sc_Nil, /* 21 */
+ sc_Nil, /* 22 */
+ sc_Nil, /* 23 */
+ sc_Nil, /* 24 */
+ sc_Nil, /* 25 */
+ sc_Nil, /* 26 */
+ sc_Nil, /* 27 */
+ sc_Nil, /* 28 */
+ sc_Nil, /* 29 */
+ sc_Nil, /* 30 */
+ sc_Nil, /* 31 */
+ sc_Nil, /* 32 */
+ sc_Nil, /* 33 */
+ sc_Nil, /* 34 */
+ sc_Nil, /* 35 */
+ sc_Nil, /* 36 */
+ sc_Nil, /* 37 */
+ sc_Nil, /* 38 */
+ sc_Nil, /* 39 */
+ sc_Nil, /* 40 */
+ sc_Nil, /* 41 */
+ sc_Nil, /* 42 */
+ sc_Nil, /* 43 */
+ sc_Nil, /* 44 */
+ sc_Nil, /* 45 */
+ sc_Nil, /* 46 */
+ sc_Nil, /* 47 */
+ sc_Nil, /* 48 */
+ sc_Nil, /* 49 */
+ sc_Nil, /* 50 */
+ sc_Nil, /* 51 */
+ sc_Nil, /* 52 */
+ sc_Nil, /* 53 */
+ sc_Nil, /* 54 */
+ sc_Nil, /* 55 */
+ sc_Nil, /* 56 */
+ sc_Nil, /* 57 */
+ sc_Nil, /* 58 */
+ sc_Nil, /* 59 */
+ sc_Nil, /* 60 */
+ sc_Nil, /* 61 */
+ sc_Nil, /* 62 */
+ sc_Nil, /* 63 */
+ sc_Nil, /* 64 */
+ sc_Nil, /* 65 */
+ sc_Nil, /* 66 */
+ sc_Nil, /* 67 */
+ sc_Nil, /* 68 */
+ sc_Nil, /* 69 */
+ sc_Nil, /* 70 */
+ sc_Nil, /* 71 */
+ sc_Nil, /* 72 */
+ sc_Nil, /* 73 */
+ sc_Nil, /* 74 */
+ sc_Nil, /* 75 */
+ sc_Nil, /* 76 */
+ sc_Nil, /* 77 */
+ sc_Nil, /* 78 */
+ sc_Nil, /* 79 */
+ sc_Nil, /* 80 */
+ sc_Nil, /* 81 */
+ sc_Nil, /* 82 */
+ sc_Nil, /* 83 */
+ sc_Nil, /* 84 */
+ sc_Nil, /* 85 */
+ sc_Nil, /* 86 */
+ sc_Nil, /* 87 */
+ sc_Nil, /* 88 */
+ sc_Nil, /* 89 */
+ sc_Nil, /* 90 */
+ sc_Nil, /* 91 */
+ sc_Nil, /* 92 */
+ sc_Nil, /* 93 */
+ sc_Nil, /* 94 */
+ sc_Nil, /* 95 */
+ sc_Nil, /* 96 */
+ sc_Nil, /* 97 */
+ sc_Nil, /* 98 */
+ sc_Nil, /* 99 */
+ sc_Text, /* 100: C_BLOCK block start/end */
+ sc_Text, /* 101: C_FCN function start/end */
+ sc_Info, /* 102: C_EOS end of struct/union/enum */
+ sc_Nil, /* 103: C_FILE file start */
+ sc_Nil, /* 104: C_LINE line number */
+ sc_Nil, /* 105: C_ALIAS combined type info */
+ sc_Nil, /* 106: C_HIDDEN ??? */
+};
+
+/* Convert COFF storage class to ECOFF symbol type. */
+static const st_t map_coff_sym_type[] = {
+ st_Nil, /* 0: C_NULL */
+ st_Local, /* 1: C_AUTO auto var */
+ st_Global, /* 2: C_EXT external */
+ st_Static, /* 3: C_STAT static */
+ st_Local, /* 4: C_REG register */
+ st_Global, /* 5: C_EXTDEF ??? */
+ st_Label, /* 6: C_LABEL label */
+ st_Label, /* 7: C_ULABEL user label */
+ st_Member, /* 8: C_MOS member of struct */
+ st_Param, /* 9: C_ARG argument */
+ st_Block, /* 10: C_STRTAG struct tag */
+ st_Member, /* 11: C_MOU member of union */
+ st_Block, /* 12: C_UNTAG union tag */
+ st_Typedef, /* 13: C_TPDEF typedef */
+ st_Static, /* 14: C_USTATIC ??? */
+ st_Block, /* 15: C_ENTAG enum tag */
+ st_Member, /* 16: C_MOE member of enum */
+ st_Param, /* 17: C_REGPARM register parameter */
+ st_Member, /* 18; C_FIELD bitfield */
+ st_Nil, /* 19 */
+ st_Nil, /* 20 */
+ st_Nil, /* 21 */
+ st_Nil, /* 22 */
+ st_Nil, /* 23 */
+ st_Nil, /* 24 */
+ st_Nil, /* 25 */
+ st_Nil, /* 26 */
+ st_Nil, /* 27 */
+ st_Nil, /* 28 */
+ st_Nil, /* 29 */
+ st_Nil, /* 30 */
+ st_Nil, /* 31 */
+ st_Nil, /* 32 */
+ st_Nil, /* 33 */
+ st_Nil, /* 34 */
+ st_Nil, /* 35 */
+ st_Nil, /* 36 */
+ st_Nil, /* 37 */
+ st_Nil, /* 38 */
+ st_Nil, /* 39 */
+ st_Nil, /* 40 */
+ st_Nil, /* 41 */
+ st_Nil, /* 42 */
+ st_Nil, /* 43 */
+ st_Nil, /* 44 */
+ st_Nil, /* 45 */
+ st_Nil, /* 46 */
+ st_Nil, /* 47 */
+ st_Nil, /* 48 */
+ st_Nil, /* 49 */
+ st_Nil, /* 50 */
+ st_Nil, /* 51 */
+ st_Nil, /* 52 */
+ st_Nil, /* 53 */
+ st_Nil, /* 54 */
+ st_Nil, /* 55 */
+ st_Nil, /* 56 */
+ st_Nil, /* 57 */
+ st_Nil, /* 58 */
+ st_Nil, /* 59 */
+ st_Nil, /* 60 */
+ st_Nil, /* 61 */
+ st_Nil, /* 62 */
+ st_Nil, /* 63 */
+ st_Nil, /* 64 */
+ st_Nil, /* 65 */
+ st_Nil, /* 66 */
+ st_Nil, /* 67 */
+ st_Nil, /* 68 */
+ st_Nil, /* 69 */
+ st_Nil, /* 70 */
+ st_Nil, /* 71 */
+ st_Nil, /* 72 */
+ st_Nil, /* 73 */
+ st_Nil, /* 74 */
+ st_Nil, /* 75 */
+ st_Nil, /* 76 */
+ st_Nil, /* 77 */
+ st_Nil, /* 78 */
+ st_Nil, /* 79 */
+ st_Nil, /* 80 */
+ st_Nil, /* 81 */
+ st_Nil, /* 82 */
+ st_Nil, /* 83 */
+ st_Nil, /* 84 */
+ st_Nil, /* 85 */
+ st_Nil, /* 86 */
+ st_Nil, /* 87 */
+ st_Nil, /* 88 */
+ st_Nil, /* 89 */
+ st_Nil, /* 90 */
+ st_Nil, /* 91 */
+ st_Nil, /* 92 */
+ st_Nil, /* 93 */
+ st_Nil, /* 94 */
+ st_Nil, /* 95 */
+ st_Nil, /* 96 */
+ st_Nil, /* 97 */
+ st_Nil, /* 98 */
+ st_Nil, /* 99 */
+ st_Block, /* 100: C_BLOCK block start/end */
+ st_Proc, /* 101: C_FCN function start/end */
+ st_End, /* 102: C_EOS end of struct/union/enum */
+ st_File, /* 103: C_FILE file start */
+ st_Nil, /* 104: C_LINE line number */
+ st_Nil, /* 105: C_ALIAS combined type info */
+ st_Nil, /* 106: C_HIDDEN ??? */
+};
+
+/* Keep track of different sized allocation requests. */
+static alloc_info_t alloc_counts[(int) alloc_type_last];
+
+/* Record whether we have seen any debugging information. */
+int ecoff_debugging_seen = 0;
+
+/* Various statics. */
+static efdr_t *cur_file_ptr = (efdr_t *) 0; /* current file desc. header */
+static proc_t *cur_proc_ptr = (proc_t *) 0; /* current procedure header */
+static proc_t *first_proc_ptr = (proc_t *) 0; /* first procedure header */
+static thead_t *top_tag_head = (thead_t *) 0; /* top level tag head */
+static thead_t *cur_tag_head = (thead_t *) 0; /* current tag head */
+#ifdef ECOFF_DEBUG
+static int debug = 0; /* trace functions */
+#endif
+static int stabs_seen = 0; /* != 0 if stabs have been seen */
+
+static int current_file_idx;
+static const char *current_stabs_filename;
+
+/* Pseudo symbol to use when putting stabs into the symbol table. */
+#ifndef STABS_SYMBOL
+#define STABS_SYMBOL "@stabs"
+#endif
+
+static char stabs_symbol[] = STABS_SYMBOL;
+
+/* Prototypes for functions defined in this file. */
+
+static void add_varray_page (varray_t *vp);
+static symint_t add_string (varray_t *vp,
+ struct hash_control *hash_tbl,
+ const char *str,
+ shash_t **ret_hash);
+static localsym_t *add_ecoff_symbol (const char *str, st_t type,
+ sc_t storage, symbolS *sym,
+ bfd_vma addend, symint_t value,
+ symint_t indx);
+static symint_t add_aux_sym_symint (symint_t aux_word);
+static symint_t add_aux_sym_rndx (int file_index, symint_t sym_index);
+static symint_t add_aux_sym_tir (type_info_t *t,
+ hash_state_t state,
+ thash_t **hash_tbl);
+static tag_t *get_tag (const char *tag, localsym_t *sym, bt_t basic_type);
+static void add_unknown_tag (tag_t *ptag);
+static void add_procedure (char *func);
+static void add_file (const char *file_name, int indx, int fake);
+#ifdef ECOFF_DEBUG
+static char *sc_to_string (sc_t storage_class);
+static char *st_to_string (st_t symbol_type);
+#endif
+static void mark_stabs (int);
+static char *ecoff_add_bytes (char **buf, char **bufend,
+ char *bufptr, unsigned long need);
+static unsigned long ecoff_padding_adjust
+ (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
+ unsigned long offset, char **bufptrptr);
+static unsigned long ecoff_build_lineno
+ (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
+ unsigned long offset, long *linecntptr);
+static unsigned long ecoff_build_symbols
+ (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
+ unsigned long offset);
+static unsigned long ecoff_build_procs
+ (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
+ unsigned long offset);
+static unsigned long ecoff_build_aux
+ (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
+ unsigned long offset);
+static unsigned long ecoff_build_strings (char **buf, char **bufend,
+ unsigned long offset,
+ varray_t *vp);
+static unsigned long ecoff_build_ss
+ (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
+ unsigned long offset);
+static unsigned long ecoff_build_fdr
+ (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
+ unsigned long offset);
+static void ecoff_setup_ext (void);
+static page_type *allocate_cluster (unsigned long npages);
+static page_type *allocate_page (void);
+static scope_t *allocate_scope (void);
+static void free_scope (scope_t *ptr);
+static vlinks_t *allocate_vlinks (void);
+static shash_t *allocate_shash (void);
+static thash_t *allocate_thash (void);
+static tag_t *allocate_tag (void);
+static void free_tag (tag_t *ptr);
+static forward_t *allocate_forward (void);
+static thead_t *allocate_thead (void);
+static void free_thead (thead_t *ptr);
+static lineno_list_t *allocate_lineno_list (void);
+
+/* This function should be called when the assembler starts up. */
+
+void
+ecoff_read_begin_hook (void)
+{
+ tag_hash = hash_new ();
+ top_tag_head = allocate_thead ();
+ top_tag_head->first_tag = (tag_t *) NULL;
+ top_tag_head->free = (thead_t *) NULL;
+ top_tag_head->prev = cur_tag_head;
+ cur_tag_head = top_tag_head;
+}
+
+/* This function should be called when a symbol is created. */
+
+void
+ecoff_symbol_new_hook (symbolS *symbolP)
+{
+ OBJ_SYMFIELD_TYPE *obj;
+
+ /* Make sure that we have a file pointer, but only if we have seen a
+ file. If we haven't seen a file, then this is a probably special
+ symbol created by md_begin which may required special handling at
+ some point. Creating a dummy file with a dummy name is certainly
+ wrong. */
+ if (cur_file_ptr == (efdr_t *) NULL
+ && seen_at_least_1_file ())
+ add_file ((const char *) NULL, 0, 1);
+ obj = symbol_get_obj (symbolP);
+ obj->ecoff_file = cur_file_ptr;
+ obj->ecoff_symbol = NULL;
+ obj->ecoff_extern_size = 0;
+}
+
+/* Add a page to a varray object. */
+
+static void
+add_varray_page (varray_t *vp /* varray to add page to */)
+{
+ vlinks_t *new_links = allocate_vlinks ();
+
+#ifdef MALLOC_CHECK
+ if (vp->object_size > 1)
+ new_links->datum = (page_type *) xcalloc (1, vp->object_size);
+ else
+#endif
+ new_links->datum = allocate_page ();
+
+ alloc_counts[(int) alloc_type_varray].total_alloc++;
+ alloc_counts[(int) alloc_type_varray].total_pages++;
+
+ new_links->start_index = vp->num_allocated;
+ vp->objects_last_page = 0;
+
+ if (vp->first == (vlinks_t *) NULL) /* first allocation? */
+ vp->first = vp->last = new_links;
+ else
+ { /* 2nd or greater allocation */
+ new_links->prev = vp->last;
+ vp->last->next = new_links;
+ vp->last = new_links;
+ }
+}
+
+/* Add a string (and null pad) to one of the string tables. */
+
+static symint_t
+add_string (varray_t *vp, /* string obstack */
+ struct hash_control *hash_tbl, /* ptr to hash table */
+ const char *str, /* string */
+ shash_t **ret_hash /* return hash pointer */)
+{
+ register unsigned long len = strlen (str);
+ register shash_t *hash_ptr;
+
+ if (len >= PAGE_USIZE)
+ as_fatal (_("string too big (%lu bytes)"), len);
+
+ hash_ptr = (shash_t *) hash_find (hash_tbl, str);
+ if (hash_ptr == (shash_t *) NULL)
+ {
+ register const char *err;
+
+ if (vp->objects_last_page + len >= PAGE_USIZE)
+ {
+ vp->num_allocated =
+ ((vp->num_allocated + PAGE_USIZE - 1) / PAGE_USIZE) * PAGE_USIZE;
+ add_varray_page (vp);
+ }
+
+ hash_ptr = allocate_shash ();
+ hash_ptr->indx = vp->num_allocated;
+
+ hash_ptr->string = &vp->last->datum->byte[vp->objects_last_page];
+
+ vp->objects_last_page += len + 1;
+ vp->num_allocated += len + 1;
+
+ strcpy (hash_ptr->string, str);
+
+ err = hash_insert (hash_tbl, str, (char *) hash_ptr);
+ if (err)
+ as_fatal (_("inserting \"%s\" into string hash table: %s"),
+ str, err);
+ }
+
+ if (ret_hash != (shash_t **) NULL)
+ *ret_hash = hash_ptr;
+
+ return hash_ptr->indx;
+}
+
+/* Add debugging information for a symbol. */
+
+static localsym_t *
+add_ecoff_symbol (const char *str, /* symbol name */
+ st_t type, /* symbol type */
+ sc_t storage, /* storage class */
+ symbolS *sym_value, /* associated symbol. */
+ bfd_vma addend, /* addend to sym_value. */
+ symint_t value, /* value of symbol */
+ symint_t indx /* index to local/aux. syms */)
+{
+ localsym_t *psym;
+ register scope_t *pscope;
+ register thead_t *ptag_head;
+ register tag_t *ptag;
+ register tag_t *ptag_next;
+ register varray_t *vp;
+ register int scope_delta = 0;
+ shash_t *hash_ptr = (shash_t *) NULL;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ as_fatal (_("no current file pointer"));
+
+ vp = &cur_file_ptr->symbols;
+
+ if (vp->objects_last_page == vp->objects_per_page)
+ add_varray_page (vp);
+
+ psym = &vp->last->datum->sym[vp->objects_last_page++];
+
+ if (str == (const char *) NULL && sym_value != (symbolS *) NULL)
+ psym->name = S_GET_NAME (sym_value);
+ else
+ psym->name = str;
+ psym->as_sym = sym_value;
+ if (sym_value != (symbolS *) NULL)
+ symbol_get_obj (sym_value)->ecoff_symbol = psym;
+ psym->addend = addend;
+ psym->file_ptr = cur_file_ptr;
+ psym->proc_ptr = cur_proc_ptr;
+ psym->begin_ptr = (localsym_t *) NULL;
+ psym->index_ptr = (aux_t *) NULL;
+ psym->forward_ref = (forward_t *) NULL;
+ psym->sym_index = -1;
+ memset (&psym->ecoff_sym, 0, sizeof (EXTR));
+ psym->ecoff_sym.asym.value = value;
+ psym->ecoff_sym.asym.st = (unsigned) type;
+ psym->ecoff_sym.asym.sc = (unsigned) storage;
+ psym->ecoff_sym.asym.index = indx;
+
+ /* If there is an associated symbol, we wait until the end of the
+ assembly before deciding where to put the name (it may be just an
+ external symbol). Otherwise, this is just a debugging symbol and
+ the name should go with the current file. */
+ if (sym_value == (symbolS *) NULL)
+ psym->ecoff_sym.asym.iss = ((str == (const char *) NULL)
+ ? 0
+ : add_string (&cur_file_ptr->strings,
+ cur_file_ptr->str_hash,
+ str,
+ &hash_ptr));
+
+ ++vp->num_allocated;
+
+ if (ECOFF_IS_STAB (&psym->ecoff_sym.asym))
+ return psym;
+
+ /* Save the symbol within the hash table if this is a static
+ item, and it has a name. */
+ if (hash_ptr != (shash_t *) NULL
+ && (type == st_Global || type == st_Static || type == st_Label
+ || type == st_Proc || type == st_StaticProc))
+ hash_ptr->sym_ptr = psym;
+
+ /* push or pop a scope if appropriate. */
+ switch (type)
+ {
+ default:
+ break;
+
+ case st_File: /* beginning of file */
+ case st_Proc: /* procedure */
+ case st_StaticProc: /* static procedure */
+ case st_Block: /* begin scope */
+ pscope = allocate_scope ();
+ pscope->prev = cur_file_ptr->cur_scope;
+ pscope->lsym = psym;
+ pscope->type = type;
+ cur_file_ptr->cur_scope = pscope;
+
+ if (type != st_File)
+ scope_delta = 1;
+
+ /* For every block type except file, struct, union, or
+ enumeration blocks, push a level on the tag stack. We omit
+ file types, so that tags can span file boundaries. */
+ if (type != st_File && storage != sc_Info)
+ {
+ ptag_head = allocate_thead ();
+ ptag_head->first_tag = 0;
+ ptag_head->prev = cur_tag_head;
+ cur_tag_head = ptag_head;
+ }
+ break;
+
+ case st_End:
+ pscope = cur_file_ptr->cur_scope;
+ if (pscope == (scope_t *) NULL)
+ as_fatal (_("too many st_End's"));
+ else
+ {
+ st_t begin_type = (st_t) pscope->lsym->ecoff_sym.asym.st;
+
+ psym->begin_ptr = pscope->lsym;
+
+ if (begin_type != st_File)
+ scope_delta = -1;
+
+ /* Except for file, structure, union, or enumeration end
+ blocks remove all tags created within this scope. */
+ if (begin_type != st_File && storage != sc_Info)
+ {
+ ptag_head = cur_tag_head;
+ cur_tag_head = ptag_head->prev;
+
+ for (ptag = ptag_head->first_tag;
+ ptag != (tag_t *) NULL;
+ ptag = ptag_next)
+ {
+ if (ptag->forward_ref != (forward_t *) NULL)
+ add_unknown_tag (ptag);
+
+ ptag_next = ptag->same_block;
+ ptag->hash_ptr->tag_ptr = ptag->same_name;
+ free_tag (ptag);
+ }
+
+ free_thead (ptag_head);
+ }
+
+ cur_file_ptr->cur_scope = pscope->prev;
+
+ /* block begin gets next sym #. This is set when we know
+ the symbol index value. */
+
+ /* Functions push two or more aux words as follows:
+ 1st word: index+1 of the end symbol (filled in later).
+ 2nd word: type of the function (plus any aux words needed).
+ Also, tie the external pointer back to the function begin symbol. */
+ if (begin_type != st_File && begin_type != st_Block)
+ {
+ symint_t ty;
+ varray_t *svp = &cur_file_ptr->aux_syms;
+
+ pscope->lsym->ecoff_sym.asym.index = add_aux_sym_symint (0);
+ pscope->lsym->index_ptr =
+ &svp->last->datum->aux[svp->objects_last_page - 1];
+ ty = add_aux_sym_tir (&last_func_type_info,
+ hash_no,
+ &cur_file_ptr->thash_head[0]);
+
+/* This seems to be unnecessary. I'm not even sure what it is
+ * intended to do. It's from mips-tfile.
+ * if (last_func_sym_value != (symbolS *) NULL)
+ * {
+ * last_func_sym_value->ifd = cur_file_ptr->file_index;
+ * last_func_sym_value->index = ty;
+ * }
+ */
+ }
+
+ free_scope (pscope);
+ }
+ }
+
+ cur_file_ptr->nested_scopes += scope_delta;
+
+#ifdef ECOFF_DEBUG
+ if (debug && type != st_File
+ && (debug > 2 || type == st_Block || type == st_End
+ || type == st_Proc || type == st_StaticProc))
+ {
+ char *sc_str = sc_to_string (storage);
+ char *st_str = st_to_string (type);
+ int depth = cur_file_ptr->nested_scopes + (scope_delta < 0);
+
+ fprintf (stderr,
+ "\tlsym\tv= %10ld, depth= %2d, sc= %-12s",
+ value, depth, sc_str);
+
+ if (str_start && str_end_p1 - str_start > 0)
+ fprintf (stderr, " st= %-11s name= %.*s\n",
+ st_str, str_end_p1 - str_start, str_start);
+ else
+ {
+ unsigned long len = strlen (st_str);
+ fprintf (stderr, " st= %.*s\n", len - 1, st_str);
+ }
+ }
+#endif
+
+ return psym;
+}
+
+/* Add an auxiliary symbol (passing a symint). This is actually used
+ for integral aux types, not just symints. */
+
+static symint_t
+add_aux_sym_symint (symint_t aux_word /* auxiliary information word */)
+{
+ register varray_t *vp;
+ register aux_t *aux_ptr;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ as_fatal (_("no current file pointer"));
+
+ vp = &cur_file_ptr->aux_syms;
+
+ if (vp->objects_last_page == vp->objects_per_page)
+ add_varray_page (vp);
+
+ aux_ptr = &vp->last->datum->aux[vp->objects_last_page++];
+ aux_ptr->type = aux_isym;
+ aux_ptr->data.isym = aux_word;
+
+ return vp->num_allocated++;
+}
+
+/* Add an auxiliary symbol (passing a file/symbol index combo). */
+
+static symint_t
+add_aux_sym_rndx (int file_index, symint_t sym_index)
+{
+ register varray_t *vp;
+ register aux_t *aux_ptr;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ as_fatal (_("no current file pointer"));
+
+ vp = &cur_file_ptr->aux_syms;
+
+ if (vp->objects_last_page == vp->objects_per_page)
+ add_varray_page (vp);
+
+ aux_ptr = &vp->last->datum->aux[vp->objects_last_page++];
+ aux_ptr->type = aux_rndx;
+ aux_ptr->data.rndx.rfd = file_index;
+ aux_ptr->data.rndx.index = sym_index;
+
+ return vp->num_allocated++;
+}
+
+/* Add an auxiliary symbol (passing the basic type and possibly
+ type qualifiers). */
+
+static symint_t
+add_aux_sym_tir (type_info_t *t, /* current type information */
+ hash_state_t state, /* whether to hash type or not */
+ thash_t **hash_tbl /* pointer to hash table to use */)
+{
+ register varray_t *vp;
+ register aux_t *aux_ptr;
+ static AUXU init_aux;
+ symint_t ret;
+ int i;
+ AUXU aux;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ as_fatal (_("no current file pointer"));
+
+ vp = &cur_file_ptr->aux_syms;
+
+ aux = init_aux;
+ aux.ti.bt = (int) t->basic_type;
+ aux.ti.continued = 0;
+ aux.ti.fBitfield = t->bitfield;
+
+ aux.ti.tq0 = (int) t->type_qualifiers[0];
+ aux.ti.tq1 = (int) t->type_qualifiers[1];
+ aux.ti.tq2 = (int) t->type_qualifiers[2];
+ aux.ti.tq3 = (int) t->type_qualifiers[3];
+ aux.ti.tq4 = (int) t->type_qualifiers[4];
+ aux.ti.tq5 = (int) t->type_qualifiers[5];
+
+ /* For anything that adds additional information, we must not hash,
+ so check here, and reset our state. */
+
+ if (state != hash_no
+ && (t->type_qualifiers[0] == tq_Array
+ || t->type_qualifiers[1] == tq_Array
+ || t->type_qualifiers[2] == tq_Array
+ || t->type_qualifiers[3] == tq_Array
+ || t->type_qualifiers[4] == tq_Array
+ || t->type_qualifiers[5] == tq_Array
+ || t->basic_type == bt_Struct
+ || t->basic_type == bt_Union
+ || t->basic_type == bt_Enum
+ || t->bitfield
+ || t->num_dims > 0))
+ state = hash_no;
+
+ /* See if we can hash this type, and save some space, but some types
+ can't be hashed (because they contain arrays or continuations),
+ and others can be put into the hash list, but cannot use existing
+ types because other aux entries precede this one. */
+
+ if (state != hash_no)
+ {
+ register thash_t *hash_ptr;
+ register symint_t hi;
+
+ hi = aux.isym & ((1 << HASHBITS) - 1);
+ hi %= THASH_SIZE;
+
+ for (hash_ptr = hash_tbl[hi];
+ hash_ptr != (thash_t *)0;
+ hash_ptr = hash_ptr->next)
+ {
+ if (aux.isym == hash_ptr->type.isym)
+ break;
+ }
+
+ if (hash_ptr != (thash_t *) NULL && state == hash_yes)
+ return hash_ptr->indx;
+
+ if (hash_ptr == (thash_t *) NULL)
+ {
+ hash_ptr = allocate_thash ();
+ hash_ptr->next = hash_tbl[hi];
+ hash_ptr->type = aux;
+ hash_ptr->indx = vp->num_allocated;
+ hash_tbl[hi] = hash_ptr;
+ }
+ }
+
+ /* Everything is set up, add the aux symbol. */
+ if (vp->objects_last_page == vp->objects_per_page)
+ add_varray_page (vp);
+
+ aux_ptr = &vp->last->datum->aux[vp->objects_last_page++];
+ aux_ptr->type = aux_tir;
+ aux_ptr->data = aux;
+
+ ret = vp->num_allocated++;
+
+ /* Add bitfield length if it exists.
+
+ NOTE: Mips documentation claims bitfield goes at the end of the
+ AUX record, but the DECstation compiler emits it here.
+ (This would only make a difference for enum bitfields.)
+
+ Also note: We use the last size given since gcc may emit 2
+ for an enum bitfield. */
+
+ if (t->bitfield)
+ (void) add_aux_sym_symint ((symint_t) t->sizes[t->num_sizes - 1]);
+
+ /* Add tag information if needed. Structure, union, and enum
+ references add 2 aux symbols: a [file index, symbol index]
+ pointer to the structure type, and the current file index. */
+
+ if (t->basic_type == bt_Struct
+ || t->basic_type == bt_Union
+ || t->basic_type == bt_Enum)
+ {
+ register symint_t file_index = t->tag_ptr->ifd;
+ register localsym_t *sym = t->tag_ptr->sym;
+ register forward_t *forward_ref = allocate_forward ();
+
+ if (sym != (localsym_t *) NULL)
+ {
+ forward_ref->next = sym->forward_ref;
+ sym->forward_ref = forward_ref;
+ }
+ else
+ {
+ forward_ref->next = t->tag_ptr->forward_ref;
+ t->tag_ptr->forward_ref = forward_ref;
+ }
+
+ (void) add_aux_sym_rndx (ST_RFDESCAPE, indexNil);
+ forward_ref->index_ptr
+ = &vp->last->datum->aux[vp->objects_last_page - 1];
+
+ (void) add_aux_sym_symint (file_index);
+ forward_ref->ifd_ptr
+ = &vp->last->datum->aux[vp->objects_last_page - 1];
+ }
+
+ /* Add information about array bounds if they exist. */
+ for (i = 0; i < t->num_dims; i++)
+ {
+ (void) add_aux_sym_rndx (ST_RFDESCAPE,
+ cur_file_ptr->int_type);
+
+ (void) add_aux_sym_symint (cur_file_ptr->file_index); /* file index*/
+ (void) add_aux_sym_symint ((symint_t) 0); /* low bound */
+ (void) add_aux_sym_symint (t->dimensions[i] - 1); /* high bound*/
+ (void) add_aux_sym_symint ((t->dimensions[i] == 0) /* stride */
+ ? 0
+ : (t->sizes[i] * 8) / t->dimensions[i]);
+ };
+
+ /* NOTE: Mips documentation claims that the bitfield width goes here.
+ But it needs to be emitted earlier. */
+
+ return ret;
+}
+
+/* Add a tag to the tag table (unless it already exists). */
+
+static tag_t *
+get_tag (const char *tag, /* tag name */
+ localsym_t *sym, /* tag start block */
+ bt_t basic_type /* bt_Struct, bt_Union, or bt_Enum */)
+{
+ shash_t *hash_ptr;
+ const char *err;
+ tag_t *tag_ptr;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ as_fatal (_("no current file pointer"));
+
+ hash_ptr = (shash_t *) hash_find (tag_hash, tag);
+
+ if (hash_ptr != (shash_t *) NULL
+ && hash_ptr->tag_ptr != (tag_t *) NULL)
+ {
+ tag_ptr = hash_ptr->tag_ptr;
+ if (sym != (localsym_t *) NULL)
+ {
+ tag_ptr->basic_type = basic_type;
+ tag_ptr->ifd = cur_file_ptr->file_index;
+ tag_ptr->sym = sym;
+ }
+ return tag_ptr;
+ }
+
+ if (hash_ptr == (shash_t *) NULL)
+ {
+ char *perm;
+
+ perm = xstrdup (tag);
+ hash_ptr = allocate_shash ();
+ err = hash_insert (tag_hash, perm, (char *) hash_ptr);
+ if (err)
+ as_fatal (_("inserting \"%s\" into tag hash table: %s"),
+ tag, err);
+ hash_ptr->string = perm;
+ }
+
+ tag_ptr = allocate_tag ();
+ tag_ptr->forward_ref = (forward_t *) NULL;
+ tag_ptr->hash_ptr = hash_ptr;
+ tag_ptr->same_name = hash_ptr->tag_ptr;
+ tag_ptr->basic_type = basic_type;
+ tag_ptr->sym = sym;
+ tag_ptr->ifd = ((sym == (localsym_t *) NULL)
+ ? (symint_t) -1
+ : cur_file_ptr->file_index);
+ tag_ptr->same_block = cur_tag_head->first_tag;
+
+ cur_tag_head->first_tag = tag_ptr;
+ hash_ptr->tag_ptr = tag_ptr;
+
+ return tag_ptr;
+}
+
+/* Add an unknown {struct, union, enum} tag. */
+
+static void
+add_unknown_tag (tag_t *ptag /* pointer to tag information */)
+{
+ shash_t *hash_ptr = ptag->hash_ptr;
+ char *name = hash_ptr->string;
+ localsym_t *sym;
+ forward_t **pf;
+
+#ifdef ECOFF_DEBUG
+ if (debug > 1)
+ {
+ char *agg_type = "{unknown aggregate type}";
+ switch (ptag->basic_type)
+ {
+ case bt_Struct: agg_type = "struct"; break;
+ case bt_Union: agg_type = "union"; break;
+ case bt_Enum: agg_type = "enum"; break;
+ default: break;
+ }
+
+ fprintf (stderr, "unknown %s %.*s found\n", agg_type,
+ hash_ptr->len, name_start);
+ }
+#endif
+
+ sym = add_ecoff_symbol (name,
+ st_Block,
+ sc_Info,
+ (symbolS *) NULL,
+ (bfd_vma) 0,
+ (symint_t) 0,
+ (symint_t) 0);
+
+ (void) add_ecoff_symbol (name,
+ st_End,
+ sc_Info,
+ (symbolS *) NULL,
+ (bfd_vma) 0,
+ (symint_t) 0,
+ (symint_t) 0);
+
+ for (pf = &sym->forward_ref; *pf != (forward_t *) NULL; pf = &(*pf)->next)
+ ;
+ *pf = ptag->forward_ref;
+}
+
+/* Add a procedure to the current file's list of procedures, and record
+ this is the current procedure. */
+
+static void
+add_procedure (char *func /* func name */)
+{
+ register varray_t *vp;
+ register proc_t *new_proc_ptr;
+ symbolS *sym;
+
+#ifdef ECOFF_DEBUG
+ if (debug)
+ fputc ('\n', stderr);
+#endif
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ as_fatal (_("no current file pointer"));
+
+ vp = &cur_file_ptr->procs;
+
+ if (vp->objects_last_page == vp->objects_per_page)
+ add_varray_page (vp);
+
+ cur_proc_ptr = new_proc_ptr = &vp->last->datum->proc[vp->objects_last_page++];
+
+ if (first_proc_ptr == (proc_t *) NULL)
+ first_proc_ptr = new_proc_ptr;
+
+ vp->num_allocated++;
+
+ new_proc_ptr->pdr.isym = -1;
+ new_proc_ptr->pdr.iline = -1;
+ new_proc_ptr->pdr.lnLow = -1;
+ new_proc_ptr->pdr.lnHigh = -1;
+
+ /* Set the BSF_FUNCTION flag for the symbol. */
+ sym = symbol_find_or_make (func);
+ symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
+
+ /* Push the start of the function. */
+ new_proc_ptr->sym = add_ecoff_symbol ((const char *) NULL, st_Proc, sc_Text,
+ sym, (bfd_vma) 0, (symint_t) 0,
+ (symint_t) 0);
+
+ ++proc_cnt;
+
+ /* Fill in the linenos preceding the .ent, if any. */
+ if (noproc_lineno != (lineno_list_t *) NULL)
+ {
+ lineno_list_t *l;
+
+ for (l = noproc_lineno; l != (lineno_list_t *) NULL; l = l->next)
+ l->proc = new_proc_ptr;
+ *last_lineno_ptr = noproc_lineno;
+ while (*last_lineno_ptr != NULL)
+ {
+ last_lineno = *last_lineno_ptr;
+ last_lineno_ptr = &last_lineno->next;
+ }
+ noproc_lineno = (lineno_list_t *) NULL;
+ }
+}
+
+symbolS *
+ecoff_get_cur_proc_sym (void)
+{
+ return (cur_proc_ptr ? cur_proc_ptr->sym->as_sym : NULL);
+}
+
+/* Add a new filename, and set up all of the file relative
+ virtual arrays (strings, symbols, aux syms, etc.). Record
+ where the current file structure lives. */
+
+static void
+add_file (const char *file_name, int indx ATTRIBUTE_UNUSED, int fake)
+{
+ register int first_ch;
+ register efdr_t *fil_ptr;
+
+#ifdef ECOFF_DEBUG
+ if (debug)
+ fprintf (stderr, "\tfile\t%.*s\n", len, file_start);
+#endif
+
+ /* If the file name is NULL, then no .file symbol appeared, and we
+ want to use the actual file name. */
+ if (file_name == (const char *) NULL)
+ {
+ char *file;
+
+ if (first_file != (efdr_t *) NULL)
+ as_fatal (_("fake .file after real one"));
+ as_where (&file, (unsigned int *) NULL);
+ file_name = (const char *) file;
+
+ /* Automatically generate ECOFF debugging information, since I
+ think that's what other ECOFF assemblers do. We don't do
+ this if we see a .file directive with a string, since that
+ implies that some sort of debugging information is being
+ provided. */
+ if (! symbol_table_frozen && debug_type == DEBUG_UNSPECIFIED)
+ debug_type = DEBUG_ECOFF;
+ }
+ else if (debug_type == DEBUG_UNSPECIFIED)
+ debug_type = DEBUG_NONE;
+
+#ifndef NO_LISTING
+ if (listing)
+ listing_source_file (file_name);
+#endif
+
+ current_stabs_filename = file_name;
+
+ /* If we're creating stabs, then we don't actually make a new FDR.
+ Instead, we just create a stabs symbol. */
+ if (stabs_seen)
+ {
+ (void) add_ecoff_symbol (file_name, st_Nil, sc_Nil,
+ symbol_new ("L0\001", now_seg,
+ (valueT) frag_now_fix (),
+ frag_now),
+ (bfd_vma) 0, 0, ECOFF_MARK_STAB (N_SOL));
+ return;
+ }
+
+ first_ch = *file_name;
+
+ /* FIXME: We can't safely merge files which have line number
+ information (fMerge will be zero in this case). Otherwise, we
+ get incorrect line number debugging info. See for instance
+ ecoff_build_lineno, which will end up setting all file->fdr.*
+ fields multiple times, resulting in incorrect debug info. In
+ order to make this work right, all line number and symbol info
+ for the same source file has to be adjacent in the object file,
+ so that a single file descriptor can be used to point to them.
+ This would require maintaining file specific lists of line
+ numbers and symbols for each file, so that they can be merged
+ together (or output together) when two .file pseudo-ops are
+ merged into one file descriptor. */
+
+ /* See if the file has already been created. */
+ for (fil_ptr = first_file;
+ fil_ptr != (efdr_t *) NULL;
+ fil_ptr = fil_ptr->next_file)
+ {
+ if (first_ch == fil_ptr->name[0]
+ && strcmp (file_name, fil_ptr->name) == 0
+ && fil_ptr->fdr.fMerge)
+ {
+ cur_file_ptr = fil_ptr;
+ if (! fake)
+ cur_file_ptr->fake = 0;
+ break;
+ }
+ }
+
+ /* If this is a new file, create it. */
+ if (fil_ptr == (efdr_t *) NULL)
+ {
+ if (file_desc.objects_last_page == file_desc.objects_per_page)
+ add_varray_page (&file_desc);
+
+ fil_ptr = cur_file_ptr =
+ &file_desc.last->datum->file[file_desc.objects_last_page++];
+ *fil_ptr = init_file;
+
+ fil_ptr->file_index = current_file_idx++;
+ ++file_desc.num_allocated;
+
+ fil_ptr->fake = fake;
+
+ /* Allocate the string hash table. */
+ fil_ptr->str_hash = hash_new ();
+
+ /* Make sure 0 byte in string table is null */
+ add_string (&fil_ptr->strings,
+ fil_ptr->str_hash,
+ "",
+ (shash_t **)0);
+
+ if (strlen (file_name) > PAGE_USIZE - 2)
+ as_fatal (_("filename goes over one page boundary"));
+
+ /* Push the start of the filename. We assume that the filename
+ will be stored at string offset 1. */
+ (void) add_ecoff_symbol (file_name, st_File, sc_Text,
+ (symbolS *) NULL, (bfd_vma) 0,
+ (symint_t) 0, (symint_t) 0);
+ fil_ptr->fdr.rss = 1;
+ fil_ptr->name = &fil_ptr->strings.last->datum->byte[1];
+
+ /* Update the linked list of file descriptors. */
+ *last_file_ptr = fil_ptr;
+ last_file_ptr = &fil_ptr->next_file;
+
+ /* Add void & int types to the file (void should be first to catch
+ errant 0's within the index fields). */
+ fil_ptr->void_type = add_aux_sym_tir (&void_type_info,
+ hash_yes,
+ &cur_file_ptr->thash_head[0]);
+
+ fil_ptr->int_type = add_aux_sym_tir (&int_type_info,
+ hash_yes,
+ &cur_file_ptr->thash_head[0]);
+ }
+}
+
+/* This function is called when the assembler notices a preprocessor
+ directive switching to a new file. This will not happen in
+ compiler output, only in hand coded assembler. */
+
+void
+ecoff_new_file (const char *name)
+{
+ if (cur_file_ptr != NULL && strcmp (cur_file_ptr->name, name) == 0)
+ return;
+ add_file (name, 0, 0);
+
+ /* This is a hand coded assembler file, so automatically turn on
+ debugging information. */
+ if (debug_type == DEBUG_UNSPECIFIED)
+ debug_type = DEBUG_ECOFF;
+}
+
+#ifdef ECOFF_DEBUG
+
+/* Convert storage class to string. */
+
+static char *
+sc_to_string (storage_class)
+ sc_t storage_class;
+{
+ switch (storage_class)
+ {
+ case sc_Nil: return "Nil,";
+ case sc_Text: return "Text,";
+ case sc_Data: return "Data,";
+ case sc_Bss: return "Bss,";
+ case sc_Register: return "Register,";
+ case sc_Abs: return "Abs,";
+ case sc_Undefined: return "Undefined,";
+ case sc_CdbLocal: return "CdbLocal,";
+ case sc_Bits: return "Bits,";
+ case sc_CdbSystem: return "CdbSystem,";
+ case sc_RegImage: return "RegImage,";
+ case sc_Info: return "Info,";
+ case sc_UserStruct: return "UserStruct,";
+ case sc_SData: return "SData,";
+ case sc_SBss: return "SBss,";
+ case sc_RData: return "RData,";
+ case sc_Var: return "Var,";
+ case sc_Common: return "Common,";
+ case sc_SCommon: return "SCommon,";
+ case sc_VarRegister: return "VarRegister,";
+ case sc_Variant: return "Variant,";
+ case sc_SUndefined: return "SUndefined,";
+ case sc_Init: return "Init,";
+ case sc_Max: return "Max,";
+ }
+
+ return "???,";
+}
+
+#endif /* DEBUG */
+
+#ifdef ECOFF_DEBUG
+
+/* Convert symbol type to string. */
+
+static char *
+st_to_string (symbol_type)
+ st_t symbol_type;
+{
+ switch (symbol_type)
+ {
+ case st_Nil: return "Nil,";
+ case st_Global: return "Global,";
+ case st_Static: return "Static,";
+ case st_Param: return "Param,";
+ case st_Local: return "Local,";
+ case st_Label: return "Label,";
+ case st_Proc: return "Proc,";
+ case st_Block: return "Block,";
+ case st_End: return "End,";
+ case st_Member: return "Member,";
+ case st_Typedef: return "Typedef,";
+ case st_File: return "File,";
+ case st_RegReloc: return "RegReloc,";
+ case st_Forward: return "Forward,";
+ case st_StaticProc: return "StaticProc,";
+ case st_Constant: return "Constant,";
+ case st_Str: return "String,";
+ case st_Number: return "Number,";
+ case st_Expr: return "Expr,";
+ case st_Type: return "Type,";
+ case st_Max: return "Max,";
+ }
+
+ return "???,";
+}
+
+#endif /* DEBUG */
+
+/* Parse .begin directives which have a label as the first argument
+ which gives the location of the start of the block. */
+
+void
+ecoff_directive_begin (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ char name_end;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ {
+ as_warn (_(".begin directive without a preceding .file directive"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (cur_proc_ptr == (proc_t *) NULL)
+ {
+ as_warn (_(".begin directive without a preceding .ent directive"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ (void) add_ecoff_symbol ((const char *) NULL, st_Block, sc_Text,
+ symbol_find_or_make (name),
+ (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
+
+ *input_line_pointer = name_end;
+
+ /* The line number follows, but we don't use it. */
+ (void) get_absolute_expression ();
+ demand_empty_rest_of_line ();
+}
+
+/* Parse .bend directives which have a label as the first argument
+ which gives the location of the end of the block. */
+
+void
+ecoff_directive_bend (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ char name_end;
+ symbolS *endsym;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ {
+ as_warn (_(".bend directive without a preceding .file directive"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (cur_proc_ptr == (proc_t *) NULL)
+ {
+ as_warn (_(".bend directive without a preceding .ent directive"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ /* The value is the distance between the .bend directive and the
+ corresponding symbol. We fill in the offset when we write out
+ the symbol. */
+ endsym = symbol_find (name);
+ if (endsym == (symbolS *) NULL)
+ as_warn (_(".bend directive names unknown symbol"));
+ else
+ (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text, endsym,
+ (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
+
+ *input_line_pointer = name_end;
+
+ /* The line number follows, but we don't use it. */
+ (void) get_absolute_expression ();
+ demand_empty_rest_of_line ();
+}
+
+/* COFF debugging information is provided as a series of directives
+ (.def, .scl, etc.). We build up information as we read the
+ directives in the following static variables, and file it away when
+ we reach the .endef directive. */
+static char *coff_sym_name;
+static type_info_t coff_type;
+static sc_t coff_storage_class;
+static st_t coff_symbol_typ;
+static int coff_is_function;
+static char *coff_tag;
+static valueT coff_value;
+static symbolS *coff_sym_value;
+static bfd_vma coff_sym_addend;
+static int coff_inside_enumeration;
+
+/* Handle a .def directive: start defining a symbol. */
+
+void
+ecoff_directive_def (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ char name_end;
+
+ ecoff_debugging_seen = 1;
+
+ SKIP_WHITESPACE ();
+
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ if (coff_sym_name != (char *) NULL)
+ as_warn (_(".def pseudo-op used inside of .def/.endef; ignored"));
+ else if (*name == '\0')
+ as_warn (_("empty symbol name in .def; ignored"));
+ else
+ {
+ if (coff_sym_name != (char *) NULL)
+ free (coff_sym_name);
+ if (coff_tag != (char *) NULL)
+ free (coff_tag);
+
+ coff_sym_name = xstrdup (name);
+ coff_type = type_info_init;
+ coff_storage_class = sc_Nil;
+ coff_symbol_typ = st_Nil;
+ coff_is_function = 0;
+ coff_tag = (char *) NULL;
+ coff_value = 0;
+ coff_sym_value = (symbolS *) NULL;
+ coff_sym_addend = 0;
+ }
+
+ *input_line_pointer = name_end;
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .dim directive, used to give dimensions for an array. The
+ arguments are comma separated numbers. mips-tfile assumes that
+ there will not be more than 6 dimensions, and gdb won't read any
+ more than that anyhow, so I will also make that assumption. */
+
+void
+ecoff_directive_dim (int ignore ATTRIBUTE_UNUSED)
+{
+ int dimens[N_TQ];
+ int i;
+
+ if (coff_sym_name == (char *) NULL)
+ {
+ as_warn (_(".dim pseudo-op used outside of .def/.endef; ignored"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ for (i = 0; i < N_TQ; i++)
+ {
+ SKIP_WHITESPACE ();
+ dimens[i] = get_absolute_expression ();
+ if (*input_line_pointer == ',')
+ ++input_line_pointer;
+ else
+ {
+ if (*input_line_pointer != '\n'
+ && *input_line_pointer != ';')
+ as_warn (_("badly formed .dim directive"));
+ break;
+ }
+ }
+
+ if (i == N_TQ)
+ --i;
+
+ /* The dimensions are stored away in reverse order. */
+ for (; i >= 0; i--)
+ {
+ if (coff_type.num_dims >= N_TQ)
+ {
+ as_warn (_("too many .dim entries"));
+ break;
+ }
+ coff_type.dimensions[coff_type.num_dims] = dimens[i];
+ ++coff_type.num_dims;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .scl directive, which sets the COFF storage class of the
+ symbol. */
+
+void
+ecoff_directive_scl (int ignore ATTRIBUTE_UNUSED)
+{
+ long val;
+
+ if (coff_sym_name == (char *) NULL)
+ {
+ as_warn (_(".scl pseudo-op used outside of .def/.endef; ignored"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ val = get_absolute_expression ();
+
+ coff_symbol_typ = map_coff_sym_type[val];
+ coff_storage_class = map_coff_storage[val];
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .size directive. For some reason mips-tfile.c thinks that
+ .size can have multiple arguments. We humor it, although gcc will
+ never generate more than one argument. */
+
+void
+ecoff_directive_size (int ignore ATTRIBUTE_UNUSED)
+{
+ int sizes[N_TQ];
+ int i;
+
+ if (coff_sym_name == (char *) NULL)
+ {
+ as_warn (_(".size pseudo-op used outside of .def/.endef; ignored"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ for (i = 0; i < N_TQ; i++)
+ {
+ SKIP_WHITESPACE ();
+ sizes[i] = get_absolute_expression ();
+ if (*input_line_pointer == ',')
+ ++input_line_pointer;
+ else
+ {
+ if (*input_line_pointer != '\n'
+ && *input_line_pointer != ';')
+ as_warn (_("badly formed .size directive"));
+ break;
+ }
+ }
+
+ if (i == N_TQ)
+ --i;
+
+ /* The sizes are stored away in reverse order. */
+ for (; i >= 0; i--)
+ {
+ if (coff_type.num_sizes >= N_TQ)
+ {
+ as_warn (_("too many .size entries"));
+ break;
+ }
+ coff_type.sizes[coff_type.num_sizes] = sizes[i];
+ ++coff_type.num_sizes;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .type directive, which gives the COFF type of the
+ symbol. */
+
+void
+ecoff_directive_type (int ignore ATTRIBUTE_UNUSED)
+{
+ long val;
+ tq_t *tq_ptr;
+ tq_t *tq_shft;
+
+ if (coff_sym_name == (char *) NULL)
+ {
+ as_warn (_(".type pseudo-op used outside of .def/.endef; ignored"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ val = get_absolute_expression ();
+
+ coff_type.orig_type = BTYPE (val);
+ coff_type.basic_type = map_coff_types[coff_type.orig_type];
+
+ tq_ptr = &coff_type.type_qualifiers[N_TQ];
+ while (val & ~N_BTMASK)
+ {
+ if (tq_ptr == &coff_type.type_qualifiers[0])
+ {
+ /* FIXME: We could handle this by setting the continued bit.
+ There would still be a limit: the .type argument can not
+ be infinite. */
+ as_warn (_("the type of %s is too complex; it will be simplified"),
+ coff_sym_name);
+ break;
+ }
+ if (ISPTR (val))
+ *--tq_ptr = tq_Ptr;
+ else if (ISFCN (val))
+ *--tq_ptr = tq_Proc;
+ else if (ISARY (val))
+ *--tq_ptr = tq_Array;
+ else
+ as_fatal (_("Unrecognized .type argument"));
+
+ val = DECREF (val);
+ }
+
+ tq_shft = &coff_type.type_qualifiers[0];
+ while (tq_ptr != &coff_type.type_qualifiers[N_TQ])
+ *tq_shft++ = *tq_ptr++;
+
+ if (tq_shft != &coff_type.type_qualifiers[0] && tq_shft[-1] == tq_Proc)
+ {
+ /* If this is a function, ignore it, so that we don't get two
+ entries (one from the .ent, and one for the .def that
+ precedes it). Save the type information so that the end
+ block can properly add it after the begin block index. For
+ MIPS knows what reason, we must strip off the function type
+ at this point. */
+ coff_is_function = 1;
+ tq_shft[-1] = tq_Nil;
+ }
+
+ while (tq_shft != &coff_type.type_qualifiers[N_TQ])
+ *tq_shft++ = tq_Nil;
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .tag directive, which gives the name of a structure,
+ union or enum. */
+
+void
+ecoff_directive_tag (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ char name_end;
+
+ if (coff_sym_name == (char *) NULL)
+ {
+ as_warn (_(".tag pseudo-op used outside of .def/.endef; ignored"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ coff_tag = xstrdup (name);
+
+ *input_line_pointer = name_end;
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .val directive, which gives the value of the symbol. It
+ may be the name of a static or global symbol. */
+
+void
+ecoff_directive_val (int ignore ATTRIBUTE_UNUSED)
+{
+ expressionS exp;
+
+ if (coff_sym_name == (char *) NULL)
+ {
+ as_warn (_(".val pseudo-op used outside of .def/.endef; ignored"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ expression (&exp);
+ if (exp.X_op != O_constant && exp.X_op != O_symbol)
+ {
+ as_bad (_(".val expression is too copmlex"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (exp.X_op == O_constant)
+ coff_value = exp.X_add_number;
+ else
+ {
+ coff_sym_value = exp.X_add_symbol;
+ coff_sym_addend = exp.X_add_number;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .endef directive, which terminates processing of COFF
+ debugging information for a symbol. */
+
+void
+ecoff_directive_endef (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ symint_t indx;
+ localsym_t *sym;
+
+ demand_empty_rest_of_line ();
+
+ if (coff_sym_name == (char *) NULL)
+ {
+ as_warn (_(".endef pseudo-op used before .def; ignored"));
+ return;
+ }
+
+ name = coff_sym_name;
+ coff_sym_name = (char *) NULL;
+
+ /* If the symbol is a static or external, we have already gotten the
+ appropriate type and class, so make sure we don't override those
+ values. This is needed because there are some type and classes
+ that are not in COFF, such as short data, etc. */
+ if (coff_sym_value != (symbolS *) NULL)
+ {
+ coff_symbol_typ = st_Nil;
+ coff_storage_class = sc_Nil;
+ }
+
+ coff_type.extra_sizes = coff_tag != (char *) NULL;
+ if (coff_type.num_dims > 0)
+ {
+ int diff = coff_type.num_dims - coff_type.num_sizes;
+ int i = coff_type.num_dims - 1;
+ int j;
+
+ if (coff_type.num_sizes != 1 || diff < 0)
+ {
+ as_warn (_("bad COFF debugging information"));
+ return;
+ }
+
+ /* If this is an array, make sure the same number of dimensions
+ and sizes were passed, creating extra sizes for multiply
+ dimensioned arrays if not passed. */
+ coff_type.extra_sizes = 0;
+ if (diff)
+ {
+ j = (sizeof (coff_type.sizes) / sizeof (coff_type.sizes[0])) - 1;
+ while (j >= 0)
+ {
+ coff_type.sizes[j] = (((j - diff) >= 0)
+ ? coff_type.sizes[j - diff]
+ : 0);
+ j--;
+ }
+
+ coff_type.num_sizes = i + 1;
+ for (i--; i >= 0; i--)
+ coff_type.sizes[i] = (coff_type.dimensions[i + 1] == 0
+ ? 0
+ : (coff_type.sizes[i + 1]
+ / coff_type.dimensions[i + 1]));
+ }
+ }
+ else if (coff_symbol_typ == st_Member
+ && coff_type.num_sizes - coff_type.extra_sizes == 1)
+ {
+ /* Is this a bitfield? This is indicated by a structure member
+ having a size field that isn't an array. */
+ coff_type.bitfield = 1;
+ }
+
+ /* Except for enumeration members & begin/ending of scopes, put the
+ type word in the aux. symbol table. */
+ if (coff_symbol_typ == st_Block || coff_symbol_typ == st_End)
+ indx = 0;
+ else if (coff_inside_enumeration)
+ indx = cur_file_ptr->void_type;
+ else
+ {
+ if (coff_type.basic_type == bt_Struct
+ || coff_type.basic_type == bt_Union
+ || coff_type.basic_type == bt_Enum)
+ {
+ if (coff_tag == (char *) NULL)
+ {
+ as_warn (_("no tag specified for %s"), name);
+ return;
+ }
+
+ coff_type.tag_ptr = get_tag (coff_tag, (localsym_t *) NULL,
+ coff_type.basic_type);
+ }
+
+ if (coff_is_function)
+ {
+ last_func_type_info = coff_type;
+ last_func_sym_value = coff_sym_value;
+ return;
+ }
+
+ indx = add_aux_sym_tir (&coff_type,
+ hash_yes,
+ &cur_file_ptr->thash_head[0]);
+ }
+
+ /* Do any last minute adjustments that are necessary. */
+ switch (coff_symbol_typ)
+ {
+ default:
+ break;
+
+ /* For the beginning of structs, unions, and enumerations, the
+ size info needs to be passed in the value field. */
+ case st_Block:
+ if (coff_type.num_sizes - coff_type.num_dims - coff_type.extra_sizes
+ != 1)
+ {
+ as_warn (_("bad COFF debugging information"));
+ return;
+ }
+ else
+ coff_value = coff_type.sizes[0];
+
+ coff_inside_enumeration = (coff_type.orig_type == T_ENUM);
+ break;
+
+ /* For the end of structs, unions, and enumerations, omit the
+ name which is always ".eos". This needs to be done last, so
+ that any error reporting above gives the correct name. */
+ case st_End:
+ free (name);
+ name = (char *) NULL;
+ coff_value = 0;
+ coff_inside_enumeration = 0;
+ break;
+
+ /* Members of structures and unions that aren't bitfields, need
+ to adjust the value from a byte offset to a bit offset.
+ Members of enumerations do not have the value adjusted, and
+ can be distinguished by indx == indexNil. For enumerations,
+ update the maximum enumeration value. */
+ case st_Member:
+ if (! coff_type.bitfield && ! coff_inside_enumeration)
+ coff_value *= 8;
+
+ break;
+ }
+
+ /* Add the symbol. */
+ sym = add_ecoff_symbol (name,
+ coff_symbol_typ,
+ coff_storage_class,
+ coff_sym_value,
+ coff_sym_addend,
+ (symint_t) coff_value,
+ indx);
+
+ /* deal with struct, union, and enum tags. */
+ if (coff_symbol_typ == st_Block)
+ {
+ /* Create or update the tag information. */
+ tag_t *tag_ptr = get_tag (name,
+ sym,
+ coff_type.basic_type);
+ forward_t **pf;
+
+ /* Remember any forward references. */
+ for (pf = &sym->forward_ref;
+ *pf != (forward_t *) NULL;
+ pf = &(*pf)->next)
+ ;
+ *pf = tag_ptr->forward_ref;
+ tag_ptr->forward_ref = (forward_t *) NULL;
+ }
+}
+
+/* Parse .end directives. */
+
+void
+ecoff_directive_end (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ char name_end;
+ symbolS *ent;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ {
+ as_warn (_(".end directive without a preceding .file directive"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (cur_proc_ptr == (proc_t *) NULL)
+ {
+ as_warn (_(".end directive without a preceding .ent directive"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ if (name == input_line_pointer)
+ {
+ as_warn (_(".end directive has no name"));
+ *input_line_pointer = name_end;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ /* The value is the distance between the .end directive and the
+ corresponding symbol. We create a fake symbol to hold the
+ current location, and put in the offset when we write out the
+ symbol. */
+ ent = symbol_find (name);
+ if (ent == (symbolS *) NULL)
+ as_warn (_(".end directive names unknown symbol"));
+ else
+ (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text,
+ symbol_new ("L0\001", now_seg,
+ (valueT) frag_now_fix (),
+ frag_now),
+ (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
+
+ cur_proc_ptr = (proc_t *) NULL;
+
+ *input_line_pointer = name_end;
+ demand_empty_rest_of_line ();
+}
+
+/* Parse .ent directives. */
+
+void
+ecoff_directive_ent (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ char name_end;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ add_file ((const char *) NULL, 0, 1);
+
+ if (cur_proc_ptr != (proc_t *) NULL)
+ {
+ as_warn (_("second .ent directive found before .end directive"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ if (name == input_line_pointer)
+ {
+ as_warn (_(".ent directive has no name"));
+ *input_line_pointer = name_end;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ add_procedure (name);
+
+ *input_line_pointer = name_end;
+
+ /* The .ent directive is sometimes followed by a number. I'm not
+ really sure what the number means. I don't see any way to store
+ the information in the PDR. The Irix 4 assembler seems to ignore
+ the information. */
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ }
+ if (ISDIGIT (*input_line_pointer)
+ || *input_line_pointer == '-')
+ (void) get_absolute_expression ();
+
+ demand_empty_rest_of_line ();
+}
+
+/* Parse .extern directives. */
+
+void
+ecoff_directive_extern (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ int c;
+ symbolS *symbolp;
+ valueT size;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolp = symbol_find_or_make (name);
+ *input_line_pointer = c;
+
+ S_SET_EXTERNAL (symbolp);
+
+ if (*input_line_pointer == ',')
+ ++input_line_pointer;
+ size = get_absolute_expression ();
+
+ symbol_get_obj (symbolp)->ecoff_extern_size = size;
+}
+
+/* Parse .file directives. */
+
+void
+ecoff_directive_file (int ignore ATTRIBUTE_UNUSED)
+{
+ int indx;
+ char *name;
+ int len;
+
+ if (cur_proc_ptr != (proc_t *) NULL)
+ {
+ as_warn (_("no way to handle .file within .ent/.end section"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ indx = (int) get_absolute_expression ();
+
+ /* FIXME: we don't have to save the name here. */
+ name = demand_copy_C_string (&len);
+
+ add_file (name, indx - 1, 0);
+
+ demand_empty_rest_of_line ();
+}
+
+/* Parse .fmask directives. */
+
+void
+ecoff_directive_fmask (int ignore ATTRIBUTE_UNUSED)
+{
+ long val;
+
+ if (cur_proc_ptr == (proc_t *) NULL)
+ {
+ as_warn (_(".fmask outside of .ent"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (get_absolute_expression_and_terminator (&val) != ',')
+ {
+ as_warn (_("bad .fmask directive"));
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ cur_proc_ptr->pdr.fregmask = val;
+ cur_proc_ptr->pdr.fregoffset = get_absolute_expression ();
+
+ demand_empty_rest_of_line ();
+}
+
+/* Parse .frame directives. */
+
+void
+ecoff_directive_frame (int ignore ATTRIBUTE_UNUSED)
+{
+ long val;
+
+ if (cur_proc_ptr == (proc_t *) NULL)
+ {
+ as_warn (_(".frame outside of .ent"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ cur_proc_ptr->pdr.framereg = tc_get_register (1);
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer++ != ','
+ || get_absolute_expression_and_terminator (&val) != ',')
+ {
+ as_warn (_("bad .frame directive"));
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ cur_proc_ptr->pdr.frameoffset = val;
+
+ cur_proc_ptr->pdr.pcreg = tc_get_register (0);
+
+#if 0
+ /* Alpha-OSF1 adds "the offset of saved $a0 from $sp", according to
+ Sandro. I don't yet know where this value should be stored, if
+ anywhere. */
+ demand_empty_rest_of_line ();
+#else
+ s_ignore (42);
+#endif
+}
+
+/* Parse .mask directives. */
+
+void
+ecoff_directive_mask (int ignore ATTRIBUTE_UNUSED)
+{
+ long val;
+
+ if (cur_proc_ptr == (proc_t *) NULL)
+ {
+ as_warn (_(".mask outside of .ent"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (get_absolute_expression_and_terminator (&val) != ',')
+ {
+ as_warn (_("bad .mask directive"));
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ cur_proc_ptr->pdr.regmask = val;
+ cur_proc_ptr->pdr.regoffset = get_absolute_expression ();
+
+ demand_empty_rest_of_line ();
+}
+
+/* Parse .loc directives. */
+
+void
+ecoff_directive_loc (int ignore ATTRIBUTE_UNUSED)
+{
+ lineno_list_t *list;
+ symint_t lineno;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ {
+ as_warn (_(".loc before .file"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (now_seg != text_section)
+ {
+ as_warn (_(".loc outside of .text"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ /* Skip the file number. */
+ SKIP_WHITESPACE ();
+ get_absolute_expression ();
+ SKIP_WHITESPACE ();
+
+ lineno = get_absolute_expression ();
+
+#ifndef NO_LISTING
+ if (listing)
+ listing_source_line (lineno);
+#endif
+
+ /* If we're building stabs, then output a special label rather than
+ ECOFF line number info. */
+ if (stabs_seen)
+ {
+ (void) add_ecoff_symbol ((char *) NULL, st_Label, sc_Text,
+ symbol_new ("L0\001", now_seg,
+ (valueT) frag_now_fix (),
+ frag_now),
+ (bfd_vma) 0, 0, lineno);
+ return;
+ }
+
+ list = allocate_lineno_list ();
+
+ list->next = (lineno_list_t *) NULL;
+ list->file = cur_file_ptr;
+ list->proc = cur_proc_ptr;
+ list->frag = frag_now;
+ list->paddr = frag_now_fix ();
+ list->lineno = lineno;
+
+ /* We don't want to merge files which have line numbers. */
+ cur_file_ptr->fdr.fMerge = 0;
+
+ /* A .loc directive will sometimes appear before a .ent directive,
+ which means that cur_proc_ptr will be NULL here. Arrange to
+ patch this up. */
+ if (cur_proc_ptr == (proc_t *) NULL)
+ {
+ lineno_list_t **pl;
+
+ pl = &noproc_lineno;
+ while (*pl != (lineno_list_t *) NULL)
+ pl = &(*pl)->next;
+ *pl = list;
+ }
+ else
+ {
+ last_lineno = list;
+ *last_lineno_ptr = list;
+ last_lineno_ptr = &list->next;
+ }
+}
+
+/* The MIPS assembler sometimes inserts nop instructions in the
+ instruction stream. When this happens, we must patch up the .loc
+ information so that it points to the instruction after the nop. */
+
+void
+ecoff_fix_loc (fragS *old_frag, unsigned long old_frag_offset)
+{
+ if (last_lineno != NULL
+ && last_lineno->frag == old_frag
+ && last_lineno->paddr == old_frag_offset)
+ {
+ last_lineno->frag = frag_now;
+ last_lineno->paddr = frag_now_fix ();
+ }
+}
+
+/* Make sure the @stabs symbol is emitted. */
+
+static void
+mark_stabs (int ignore ATTRIBUTE_UNUSED)
+{
+ if (! stabs_seen)
+ {
+ /* Add a dummy @stabs dymbol. */
+ stabs_seen = 1;
+ (void) add_ecoff_symbol (stabs_symbol, stNil, scInfo,
+ (symbolS *) NULL,
+ (bfd_vma) 0, (symint_t) -1,
+ ECOFF_MARK_STAB (0));
+ }
+}
+
+/* Parse .weakext directives. */
+#ifndef TC_MIPS
+/* For TC_MIPS use the version in tc-mips.c. */
+void
+ecoff_directive_weakext (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+ expressionS exp;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer == ',')
+ {
+ if (S_IS_DEFINED (symbolP))
+ {
+ as_bad (_("symbol `%s' is already defined"),
+ S_GET_NAME (symbolP));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ if (! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ expression (&exp);
+ if (exp.X_op != O_symbol)
+ {
+ as_bad (_("bad .weakext directive"));
+ ignore_rest_of_line ();
+ return;
+ }
+ symbol_set_value_expression (symbolP, &exp);
+ }
+ }
+
+ S_SET_WEAK (symbolP);
+
+ demand_empty_rest_of_line ();
+}
+#endif /* not TC_MIPS */
+
+/* Handle .stabs directives. The actual parsing routine is done by a
+ generic routine. This routine is called via OBJ_PROCESS_STAB.
+ When this is called, input_line_pointer will be pointing at the
+ value field of the stab.
+
+ .stabs directives have five fields:
+ "string" a string, encoding the type information.
+ code a numeric code, defined in <stab.h>
+ 0 a zero
+ desc a zero or line number
+ value a numeric value or an address.
+
+ If the value is relocatable, we transform this into:
+ iss points as an index into string space
+ value value from lookup of the name
+ st st from lookup of the name
+ sc sc from lookup of the name
+ index code|CODE_MASK
+
+ If the value is not relocatable, we transform this into:
+ iss points as an index into string space
+ value value
+ st st_Nil
+ sc sc_Nil
+ index code|CODE_MASK
+
+ .stabn directives have four fields (string is null):
+ code a numeric code, defined in <stab.h>
+ 0 a zero
+ desc a zero or a line number
+ value a numeric value or an address. */
+
+void
+ecoff_stab (segT sec ATTRIBUTE_UNUSED,
+ int what,
+ const char *string,
+ int type,
+ int other,
+ int desc)
+{
+ efdr_t *save_file_ptr = cur_file_ptr;
+ symbolS *sym;
+ symint_t value;
+ bfd_vma addend;
+ st_t st;
+ sc_t sc;
+ symint_t indx;
+ localsym_t *hold = NULL;
+
+ ecoff_debugging_seen = 1;
+
+ /* We don't handle .stabd. */
+ if (what != 's' && what != 'n')
+ {
+ as_bad (_(".stab%c is not supported"), what);
+ return;
+ }
+
+ /* A .stabn uses a null name, not an empty string. */
+ if (what == 'n')
+ string = NULL;
+
+ /* We ignore the other field. */
+ if (other != 0)
+ as_warn (_(".stab%c: ignoring non-zero other field"), what);
+
+ /* Make sure we have a current file. */
+ if (cur_file_ptr == (efdr_t *) NULL)
+ {
+ add_file ((const char *) NULL, 0, 1);
+ save_file_ptr = cur_file_ptr;
+ }
+
+ /* For stabs in ECOFF, the first symbol must be @stabs. This is a
+ signal to gdb. */
+ if (stabs_seen == 0)
+ mark_stabs (0);
+
+ /* Line number stabs are handled differently, since they have two
+ values, the line number and the address of the label. We use the
+ index field (aka desc) to hold the line number, and the value
+ field to hold the address. The symbol type is st_Label, which
+ should be different from the other stabs, so that gdb can
+ recognize it. */
+ if (type == N_SLINE)
+ {
+ SYMR dummy_symr;
+ char *name;
+ char name_end;
+
+#ifndef NO_LISTING
+ if (listing)
+ listing_source_line ((unsigned int) desc);
+#endif
+
+ dummy_symr.index = desc;
+ if (dummy_symr.index != desc)
+ {
+ as_warn (_("line number (%d) for .stab%c directive cannot fit in index field (20 bits)"),
+ desc, what);
+ return;
+ }
+
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ sym = symbol_find_or_make (name);
+ *input_line_pointer = name_end;
+
+ value = 0;
+ addend = 0;
+ st = st_Label;
+ sc = sc_Text;
+ indx = desc;
+ }
+ else
+ {
+#ifndef NO_LISTING
+ if (listing && (type == N_SO || type == N_SOL))
+ listing_source_file (string);
+#endif
+
+ if (ISDIGIT (*input_line_pointer)
+ || *input_line_pointer == '-'
+ || *input_line_pointer == '+')
+ {
+ st = st_Nil;
+ sc = sc_Nil;
+ sym = (symbolS *) NULL;
+ value = get_absolute_expression ();
+ addend = 0;
+ }
+ else if (! is_name_beginner ((unsigned char) *input_line_pointer))
+ {
+ as_warn (_("illegal .stab%c directive, bad character"), what);
+ return;
+ }
+ else
+ {
+ expressionS exp;
+
+ sc = sc_Nil;
+ st = st_Nil;
+
+ expression (&exp);
+ if (exp.X_op == O_constant)
+ {
+ sym = NULL;
+ value = exp.X_add_number;
+ addend = 0;
+ }
+ else if (exp.X_op == O_symbol)
+ {
+ sym = exp.X_add_symbol;
+ value = 0;
+ addend = exp.X_add_number;
+ }
+ else
+ {
+ sym = make_expr_symbol (&exp);
+ value = 0;
+ addend = 0;
+ }
+ }
+
+ indx = ECOFF_MARK_STAB (type);
+ }
+
+ /* Don't store the stabs symbol we are creating as the type of the
+ ECOFF symbol. We want to compute the type of the ECOFF symbol
+ independently. */
+ if (sym != (symbolS *) NULL)
+ hold = symbol_get_obj (sym)->ecoff_symbol;
+
+ (void) add_ecoff_symbol (string, st, sc, sym, addend, value, indx);
+
+ if (sym != (symbolS *) NULL)
+ symbol_get_obj (sym)->ecoff_symbol = hold;
+
+ /* Restore normal file type. */
+ cur_file_ptr = save_file_ptr;
+}
+
+/* Frob an ECOFF symbol. Small common symbols go into a special
+ .scommon section rather than bfd_com_section. */
+
+void
+ecoff_frob_symbol (symbolS *sym)
+{
+ if (S_IS_COMMON (sym)
+ && S_GET_VALUE (sym) > 0
+ && S_GET_VALUE (sym) <= bfd_get_gp_size (stdoutput))
+ {
+ static asection scom_section;
+ static asymbol scom_symbol;
+
+ /* We must construct a fake section similar to bfd_com_section
+ but with the name .scommon. */
+ if (scom_section.name == NULL)
+ {
+ scom_section = bfd_com_section;
+ scom_section.name = ".scommon";
+ scom_section.output_section = &scom_section;
+ scom_section.symbol = &scom_symbol;
+ scom_section.symbol_ptr_ptr = &scom_section.symbol;
+ scom_symbol = *bfd_com_section.symbol;
+ scom_symbol.name = ".scommon";
+ scom_symbol.section = &scom_section;
+ }
+ S_SET_SEGMENT (sym, &scom_section);
+ }
+
+ /* Double check weak symbols. */
+ if (S_IS_WEAK (sym))
+ {
+ if (S_IS_COMMON (sym))
+ as_bad (_("symbol `%s' can not be both weak and common"),
+ S_GET_NAME (sym));
+ }
+}
+
+/* Add bytes to the symbolic information buffer. */
+
+static char *
+ecoff_add_bytes (char **buf,
+ char **bufend,
+ char *bufptr,
+ unsigned long need)
+{
+ unsigned long at;
+ unsigned long want;
+
+ at = bufptr - *buf;
+ need -= *bufend - bufptr;
+ if (need < PAGE_SIZE)
+ need = PAGE_SIZE;
+ want = (*bufend - *buf) + need;
+ *buf = xrealloc (*buf, want);
+ *bufend = *buf + want;
+ return *buf + at;
+}
+
+/* Adjust the symbolic information buffer to the alignment required
+ for the ECOFF target debugging information. */
+
+static unsigned long
+ecoff_padding_adjust (const struct ecoff_debug_swap *backend,
+ char **buf,
+ char **bufend,
+ unsigned long offset,
+ char **bufptrptr)
+{
+ bfd_size_type align;
+
+ align = backend->debug_align;
+ if ((offset & (align - 1)) != 0)
+ {
+ unsigned long add;
+
+ add = align - (offset & (align - 1));
+ if ((unsigned long) (*bufend - (*buf + offset)) < add)
+ (void) ecoff_add_bytes (buf, bufend, *buf + offset, add);
+ memset (*buf + offset, 0, add);
+ offset += add;
+ if (bufptrptr != (char **) NULL)
+ *bufptrptr = *buf + offset;
+ }
+
+ return offset;
+}
+
+/* Build the line number information. */
+
+static unsigned long
+ecoff_build_lineno (const struct ecoff_debug_swap *backend,
+ char **buf,
+ char **bufend,
+ unsigned long offset,
+ long *linecntptr)
+{
+ char *bufptr;
+ register lineno_list_t *l;
+ lineno_list_t *last;
+ efdr_t *file;
+ proc_t *proc;
+ unsigned long c;
+ long iline;
+ long totcount;
+ lineno_list_t first;
+ lineno_list_t *local_first_lineno = first_lineno;
+
+ if (linecntptr != (long *) NULL)
+ *linecntptr = 0;
+
+ bufptr = *buf + offset;
+
+ file = (efdr_t *) NULL;
+ proc = (proc_t *) NULL;
+ last = (lineno_list_t *) NULL;
+ c = offset;
+ iline = 0;
+ totcount = 0;
+
+ /* For some reason the address of the first procedure is ignored
+ when reading line numbers. This doesn't matter if the address of
+ the first procedure is 0, but when gcc is generating MIPS
+ embedded PIC code, it will put strings in the .text section
+ before the first procedure. We cope by inserting a dummy line if
+ the address of the first procedure is not 0. Hopefully this
+ won't screw things up too badly.
+
+ Don't do this for ECOFF assembly source line numbers. They work
+ without this extra attention. */
+ if (debug_type != DEBUG_ECOFF
+ && first_proc_ptr != (proc_t *) NULL
+ && local_first_lineno != (lineno_list_t *) NULL
+ && ((S_GET_VALUE (first_proc_ptr->sym->as_sym)
+ + bfd_get_section_vma (stdoutput,
+ S_GET_SEGMENT (first_proc_ptr->sym->as_sym)))
+ != 0))
+ {
+ first.file = local_first_lineno->file;
+ first.proc = local_first_lineno->proc;
+ first.frag = &zero_address_frag;
+ first.paddr = 0;
+ first.lineno = 0;
+
+ first.next = local_first_lineno;
+ local_first_lineno = &first;
+ }
+
+ for (l = local_first_lineno; l != (lineno_list_t *) NULL; l = l->next)
+ {
+ long count;
+ long delta;
+
+ /* Get the offset to the memory address of the next line number
+ (in words). Do this first, so that we can skip ahead to the
+ next useful line number entry. */
+ if (l->next == (lineno_list_t *) NULL)
+ {
+ /* We want a count of zero, but it will be decremented
+ before it is used. */
+ count = 1;
+ }
+ else if (l->next->frag->fr_address + l->next->paddr
+ > l->frag->fr_address + l->paddr)
+ {
+ count = ((l->next->frag->fr_address + l->next->paddr
+ - (l->frag->fr_address + l->paddr))
+ >> 2);
+ }
+ else
+ {
+ /* Don't change last, so we still get the right delta. */
+ continue;
+ }
+
+ if (l->file != file || l->proc != proc)
+ {
+ if (l->proc != proc && proc != (proc_t *) NULL)
+ proc->pdr.lnHigh = last->lineno;
+ if (l->file != file && file != (efdr_t *) NULL)
+ {
+ file->fdr.cbLine = c - file->fdr.cbLineOffset;
+ file->fdr.cline = totcount + count;
+ if (linecntptr != (long *) NULL)
+ *linecntptr += totcount + count;
+ totcount = 0;
+ }
+
+ if (l->file != file)
+ {
+ efdr_t *last_file = file;
+
+ file = l->file;
+ if (last_file != (efdr_t *) NULL)
+ file->fdr.ilineBase
+ = last_file->fdr.ilineBase + last_file->fdr.cline;
+ else
+ file->fdr.ilineBase = 0;
+ file->fdr.cbLineOffset = c;
+ }
+ if (l->proc != proc)
+ {
+ proc = l->proc;
+ if (proc != (proc_t *) NULL)
+ {
+ proc->pdr.lnLow = l->lineno;
+ proc->pdr.cbLineOffset = c - file->fdr.cbLineOffset;
+ proc->pdr.iline = totcount;
+ }
+ }
+
+ last = (lineno_list_t *) NULL;
+ }
+
+ totcount += count;
+
+ /* Get the offset to this line number. */
+ if (last == (lineno_list_t *) NULL)
+ delta = 0;
+ else
+ delta = l->lineno - last->lineno;
+
+ /* Put in the offset to this line number. */
+ while (delta != 0)
+ {
+ int setcount;
+
+ /* 1 is added to each count read. */
+ --count;
+ /* We can only adjust the word count by up to 15 words at a
+ time. */
+ if (count <= 0x0f)
+ {
+ setcount = count;
+ count = 0;
+ }
+ else
+ {
+ setcount = 0x0f;
+ count -= 0x0f;
+ }
+ if (delta >= -7 && delta <= 7)
+ {
+ if (bufptr >= *bufend)
+ bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 1);
+ *bufptr++ = setcount + (delta << 4);
+ delta = 0;
+ ++c;
+ }
+ else
+ {
+ int set;
+
+ if (*bufend - bufptr < 3)
+ bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 3);
+ *bufptr++ = setcount + (8 << 4);
+ if (delta < -0x8000)
+ {
+ set = -0x8000;
+ delta += 0x8000;
+ }
+ else if (delta > 0x7fff)
+ {
+ set = 0x7fff;
+ delta -= 0x7fff;
+ }
+ else
+ {
+ set = delta;
+ delta = 0;
+ }
+ *bufptr++ = set >> 8;
+ *bufptr++ = set & 0xffff;
+ c += 3;
+ }
+ }
+
+ /* Finish adjusting the count. */
+ while (count > 0)
+ {
+ if (bufptr >= *bufend)
+ bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 1);
+ /* 1 is added to each count read. */
+ --count;
+ if (count > 0x0f)
+ {
+ *bufptr++ = 0x0f;
+ count -= 0x0f;
+ }
+ else
+ {
+ *bufptr++ = count;
+ count = 0;
+ }
+ ++c;
+ }
+
+ ++iline;
+ last = l;
+ }
+
+ if (proc != (proc_t *) NULL)
+ proc->pdr.lnHigh = last->lineno;
+ if (file != (efdr_t *) NULL)
+ {
+ file->fdr.cbLine = c - file->fdr.cbLineOffset;
+ file->fdr.cline = totcount;
+ }
+
+ if (linecntptr != (long *) NULL)
+ *linecntptr += totcount;
+
+ c = ecoff_padding_adjust (backend, buf, bufend, c, &bufptr);
+
+ return c;
+}
+
+/* Build and swap out the symbols. */
+
+static unsigned long
+ecoff_build_symbols (const struct ecoff_debug_swap *backend,
+ char **buf,
+ char **bufend,
+ unsigned long offset)
+{
+ const bfd_size_type external_sym_size = backend->external_sym_size;
+ void (* const swap_sym_out) (bfd *, const SYMR *, PTR)
+ = backend->swap_sym_out;
+ char *sym_out;
+ long isym;
+ vlinks_t *file_link;
+
+ sym_out = *buf + offset;
+
+ isym = 0;
+
+ /* The symbols are stored by file. */
+ for (file_link = file_desc.first;
+ file_link != (vlinks_t *) NULL;
+ file_link = file_link->next)
+ {
+ int ifilesym;
+ int fil_cnt;
+ efdr_t *fil_ptr;
+ efdr_t *fil_end;
+
+ if (file_link->next == (vlinks_t *) NULL)
+ fil_cnt = file_desc.objects_last_page;
+ else
+ fil_cnt = file_desc.objects_per_page;
+ fil_ptr = file_link->datum->file;
+ fil_end = fil_ptr + fil_cnt;
+ for (; fil_ptr < fil_end; fil_ptr++)
+ {
+ vlinks_t *sym_link;
+
+ fil_ptr->fdr.isymBase = isym;
+ ifilesym = isym;
+ for (sym_link = fil_ptr->symbols.first;
+ sym_link != (vlinks_t *) NULL;
+ sym_link = sym_link->next)
+ {
+ int sym_cnt;
+ localsym_t *sym_ptr;
+ localsym_t *sym_end;
+
+ if (sym_link->next == (vlinks_t *) NULL)
+ sym_cnt = fil_ptr->symbols.objects_last_page;
+ else
+ sym_cnt = fil_ptr->symbols.objects_per_page;
+ sym_ptr = sym_link->datum->sym;
+ sym_end = sym_ptr + sym_cnt;
+ for (; sym_ptr < sym_end; sym_ptr++)
+ {
+ int local;
+ symbolS *as_sym;
+ forward_t *f;
+
+ know (sym_ptr->file_ptr == fil_ptr);
+
+ /* If there is no associated gas symbol, then this
+ is a pure debugging symbol. We have already
+ added the name (if any) to fil_ptr->strings.
+ Otherwise we must decide whether this is an
+ external or a local symbol (actually, it may be
+ both if the local provides additional debugging
+ information for the external). */
+ local = 1;
+ as_sym = sym_ptr->as_sym;
+ if (as_sym != (symbolS *) NULL)
+ {
+ symint_t indx;
+
+ /* The value of a block start symbol is the
+ offset from the start of the procedure. For
+ other symbols we just use the gas value (but
+ we must offset it by the vma of the section,
+ just as BFD does, because BFD will not see
+ this value). */
+ if (sym_ptr->ecoff_sym.asym.st == (int) st_Block
+ && sym_ptr->ecoff_sym.asym.sc == (int) sc_Text)
+ {
+ symbolS *begin_sym;
+
+ know (sym_ptr->proc_ptr != (proc_t *) NULL);
+ begin_sym = sym_ptr->proc_ptr->sym->as_sym;
+ if (S_GET_SEGMENT (as_sym)
+ != S_GET_SEGMENT (begin_sym))
+ as_warn (_(".begin/.bend in different segments"));
+ sym_ptr->ecoff_sym.asym.value =
+ S_GET_VALUE (as_sym) - S_GET_VALUE (begin_sym);
+ }
+ else
+ sym_ptr->ecoff_sym.asym.value =
+ (S_GET_VALUE (as_sym)
+ + bfd_get_section_vma (stdoutput,
+ S_GET_SEGMENT (as_sym))
+ + sym_ptr->addend);
+
+ sym_ptr->ecoff_sym.weakext = S_IS_WEAK (as_sym);
+
+ /* Set st_Proc to st_StaticProc for local
+ functions. */
+ if (sym_ptr->ecoff_sym.asym.st == st_Proc
+ && S_IS_DEFINED (as_sym)
+ && ! S_IS_EXTERNAL (as_sym)
+ && ! S_IS_WEAK (as_sym))
+ sym_ptr->ecoff_sym.asym.st = st_StaticProc;
+
+ /* Get the type and storage class based on where
+ the symbol actually wound up. Traditionally,
+ N_LBRAC and N_RBRAC are *not* relocated. */
+ indx = sym_ptr->ecoff_sym.asym.index;
+ if (sym_ptr->ecoff_sym.asym.st == st_Nil
+ && sym_ptr->ecoff_sym.asym.sc == sc_Nil
+ && (! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym)
+ || ((ECOFF_UNMARK_STAB (indx) != N_LBRAC)
+ && (ECOFF_UNMARK_STAB (indx) != N_RBRAC))))
+ {
+ segT seg;
+ const char *segname;
+ st_t st;
+ sc_t sc;
+
+ seg = S_GET_SEGMENT (as_sym);
+ segname = segment_name (seg);
+
+ if (! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym)
+ && (S_IS_EXTERNAL (as_sym)
+ || S_IS_WEAK (as_sym)
+ || ! S_IS_DEFINED (as_sym)))
+ {
+ if ((symbol_get_bfdsym (as_sym)->flags
+ & BSF_FUNCTION) != 0)
+ st = st_Proc;
+ else
+ st = st_Global;
+ }
+ else if (seg == text_section)
+ st = st_Label;
+ else
+ st = st_Static;
+
+ if (! S_IS_DEFINED (as_sym))
+ {
+ valueT s;
+
+ s = symbol_get_obj (as_sym)->ecoff_extern_size;
+ if (s == 0
+ || s > bfd_get_gp_size (stdoutput))
+ sc = sc_Undefined;
+ else
+ {
+ sc = sc_SUndefined;
+ sym_ptr->ecoff_sym.asym.value = s;
+ }
+#ifdef S_SET_SIZE
+ S_SET_SIZE (as_sym, s);
+#endif
+ }
+ else if (S_IS_COMMON (as_sym))
+ {
+ if (S_GET_VALUE (as_sym) > 0
+ && (S_GET_VALUE (as_sym)
+ <= bfd_get_gp_size (stdoutput)))
+ sc = sc_SCommon;
+ else
+ sc = sc_Common;
+ }
+ else if (seg == text_section)
+ sc = sc_Text;
+ else if (seg == data_section)
+ sc = sc_Data;
+ else if (strcmp (segname, ".rdata") == 0
+ || strcmp (segname, ".rodata") == 0)
+ sc = sc_RData;
+ else if (strcmp (segname, ".sdata") == 0)
+ sc = sc_SData;
+ else if (seg == bss_section)
+ sc = sc_Bss;
+ else if (strcmp (segname, ".sbss") == 0)
+ sc = sc_SBss;
+ else if (seg == &bfd_abs_section)
+ sc = sc_Abs;
+ else
+ {
+ /* This must be a user named section.
+ This is not possible in ECOFF, but it
+ is in ELF. */
+ sc = sc_Data;
+ }
+
+ sym_ptr->ecoff_sym.asym.st = (int) st;
+ sym_ptr->ecoff_sym.asym.sc = (int) sc;
+ }
+
+ /* This is just an external symbol if it is
+ outside a procedure and it has a type.
+ FIXME: g++ will generate symbols which have
+ different names in the debugging information
+ than the actual symbol. Should we handle
+ them here? */
+ if ((S_IS_EXTERNAL (as_sym)
+ || S_IS_WEAK (as_sym)
+ || ! S_IS_DEFINED (as_sym))
+ && sym_ptr->proc_ptr == (proc_t *) NULL
+ && sym_ptr->ecoff_sym.asym.st != (int) st_Nil
+ && ! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym))
+ local = 0;
+
+ /* This is just an external symbol if it is a
+ common symbol. */
+ if (S_IS_COMMON (as_sym))
+ local = 0;
+
+ /* If an st_end symbol has an associated gas
+ symbol, then it is a local label created for
+ a .bend or .end directive. Stabs line
+ numbers will have \001 in the names. */
+ if (local
+ && sym_ptr->ecoff_sym.asym.st != st_End
+ && strchr (sym_ptr->name, '\001') == 0)
+ sym_ptr->ecoff_sym.asym.iss =
+ add_string (&fil_ptr->strings,
+ fil_ptr->str_hash,
+ sym_ptr->name,
+ (shash_t **) NULL);
+ }
+
+ /* We now know the index of this symbol; fill in
+ locations that have been waiting for that
+ information. */
+ if (sym_ptr->begin_ptr != (localsym_t *) NULL)
+ {
+ localsym_t *begin_ptr;
+ st_t begin_type;
+
+ know (local);
+ begin_ptr = sym_ptr->begin_ptr;
+ know (begin_ptr->sym_index != -1);
+ sym_ptr->ecoff_sym.asym.index = begin_ptr->sym_index;
+ if (sym_ptr->ecoff_sym.asym.sc != (int) sc_Info)
+ sym_ptr->ecoff_sym.asym.iss =
+ begin_ptr->ecoff_sym.asym.iss;
+
+ begin_type = begin_ptr->ecoff_sym.asym.st;
+ if (begin_type == st_File
+ || begin_type == st_Block)
+ {
+ begin_ptr->ecoff_sym.asym.index =
+ isym - ifilesym + 1;
+ (*swap_sym_out) (stdoutput,
+ &begin_ptr->ecoff_sym.asym,
+ (*buf
+ + offset
+ + (begin_ptr->sym_index
+ * external_sym_size)));
+ }
+ else
+ {
+ know (begin_ptr->index_ptr != (aux_t *) NULL);
+ begin_ptr->index_ptr->data.isym =
+ isym - ifilesym + 1;
+ }
+
+ /* The value of the symbol marking the end of a
+ procedure is the size of the procedure. The
+ value of the symbol marking the end of a
+ block is the offset from the start of the
+ procedure to the block. */
+ if (begin_type == st_Proc
+ || begin_type == st_StaticProc)
+ {
+ know (as_sym != (symbolS *) NULL);
+ know (begin_ptr->as_sym != (symbolS *) NULL);
+ if (S_GET_SEGMENT (as_sym)
+ != S_GET_SEGMENT (begin_ptr->as_sym))
+ as_warn (_(".begin/.bend in different segments"));
+ sym_ptr->ecoff_sym.asym.value =
+ (S_GET_VALUE (as_sym)
+ - S_GET_VALUE (begin_ptr->as_sym));
+
+ /* If the size is odd, this is probably a
+ mips16 function; force it to be even. */
+ if ((sym_ptr->ecoff_sym.asym.value & 1) != 0)
+ ++sym_ptr->ecoff_sym.asym.value;
+
+#ifdef S_SET_SIZE
+ S_SET_SIZE (begin_ptr->as_sym,
+ sym_ptr->ecoff_sym.asym.value);
+#endif
+ }
+ else if (begin_type == st_Block
+ && sym_ptr->ecoff_sym.asym.sc != (int) sc_Info)
+ {
+ symbolS *begin_sym;
+
+ know (as_sym != (symbolS *) NULL);
+ know (sym_ptr->proc_ptr != (proc_t *) NULL);
+ begin_sym = sym_ptr->proc_ptr->sym->as_sym;
+ if (S_GET_SEGMENT (as_sym)
+ != S_GET_SEGMENT (begin_sym))
+ as_warn (_(".begin/.bend in different segments"));
+ sym_ptr->ecoff_sym.asym.value =
+ S_GET_VALUE (as_sym) - S_GET_VALUE (begin_sym);
+ }
+ }
+
+ for (f = sym_ptr->forward_ref;
+ f != (forward_t *) NULL;
+ f = f->next)
+ {
+ know (local);
+ f->ifd_ptr->data.isym = fil_ptr->file_index;
+ f->index_ptr->data.rndx.index = isym - ifilesym;
+ }
+
+ if (local)
+ {
+ if ((bfd_size_type)(*bufend - sym_out) < external_sym_size)
+ sym_out = ecoff_add_bytes (buf, bufend,
+ sym_out,
+ external_sym_size);
+ (*swap_sym_out) (stdoutput, &sym_ptr->ecoff_sym.asym,
+ sym_out);
+ sym_out += external_sym_size;
+
+ sym_ptr->sym_index = isym;
+
+ if (sym_ptr->proc_ptr != (proc_t *) NULL
+ && sym_ptr->proc_ptr->sym == sym_ptr)
+ sym_ptr->proc_ptr->pdr.isym = isym - ifilesym;
+
+ ++isym;
+ }
+
+ /* Record the local symbol index and file number in
+ case this is an external symbol. Note that this
+ destroys the asym.index field. */
+ if (as_sym != (symbolS *) NULL
+ && symbol_get_obj (as_sym)->ecoff_symbol == sym_ptr)
+ {
+ if ((sym_ptr->ecoff_sym.asym.st == st_Proc
+ || sym_ptr->ecoff_sym.asym.st == st_StaticProc)
+ && local)
+ sym_ptr->ecoff_sym.asym.index = isym - ifilesym - 1;
+ sym_ptr->ecoff_sym.ifd = fil_ptr->file_index;
+
+ /* Don't try to merge an FDR which has an
+ external symbol attached to it. */
+ if (S_IS_EXTERNAL (as_sym) || S_IS_WEAK (as_sym))
+ fil_ptr->fdr.fMerge = 0;
+ }
+ }
+ }
+ fil_ptr->fdr.csym = isym - fil_ptr->fdr.isymBase;
+ }
+ }
+
+ return offset + isym * external_sym_size;
+}
+
+/* Swap out the procedure information. */
+
+static unsigned long
+ecoff_build_procs (const struct ecoff_debug_swap *backend,
+ char **buf,
+ char **bufend,
+ unsigned long offset)
+{
+ const bfd_size_type external_pdr_size = backend->external_pdr_size;
+ void (* const swap_pdr_out) (bfd *, const PDR *, PTR)
+ = backend->swap_pdr_out;
+ char *pdr_out;
+ long iproc;
+ vlinks_t *file_link;
+
+ pdr_out = *buf + offset;
+
+ iproc = 0;
+
+ /* The procedures are stored by file. */
+ for (file_link = file_desc.first;
+ file_link != (vlinks_t *) NULL;
+ file_link = file_link->next)
+ {
+ int fil_cnt;
+ efdr_t *fil_ptr;
+ efdr_t *fil_end;
+
+ if (file_link->next == (vlinks_t *) NULL)
+ fil_cnt = file_desc.objects_last_page;
+ else
+ fil_cnt = file_desc.objects_per_page;
+ fil_ptr = file_link->datum->file;
+ fil_end = fil_ptr + fil_cnt;
+ for (; fil_ptr < fil_end; fil_ptr++)
+ {
+ vlinks_t *proc_link;
+ int first;
+
+ fil_ptr->fdr.ipdFirst = iproc;
+ first = 1;
+ for (proc_link = fil_ptr->procs.first;
+ proc_link != (vlinks_t *) NULL;
+ proc_link = proc_link->next)
+ {
+ int prc_cnt;
+ proc_t *proc_ptr;
+ proc_t *proc_end;
+
+ if (proc_link->next == (vlinks_t *) NULL)
+ prc_cnt = fil_ptr->procs.objects_last_page;
+ else
+ prc_cnt = fil_ptr->procs.objects_per_page;
+ proc_ptr = proc_link->datum->proc;
+ proc_end = proc_ptr + prc_cnt;
+ for (; proc_ptr < proc_end; proc_ptr++)
+ {
+ symbolS *adr_sym;
+ unsigned long adr;
+
+ adr_sym = proc_ptr->sym->as_sym;
+ adr = (S_GET_VALUE (adr_sym)
+ + bfd_get_section_vma (stdoutput,
+ S_GET_SEGMENT (adr_sym)));
+ if (first)
+ {
+ /* This code used to force the adr of the very
+ first fdr to be 0. However, the native tools
+ don't do that, and I can't remember why it
+ used to work that way, so I took it out. */
+ fil_ptr->fdr.adr = adr;
+ first = 0;
+ }
+ proc_ptr->pdr.adr = adr - fil_ptr->fdr.adr;
+ if ((bfd_size_type)(*bufend - pdr_out) < external_pdr_size)
+ pdr_out = ecoff_add_bytes (buf, bufend,
+ pdr_out,
+ external_pdr_size);
+ (*swap_pdr_out) (stdoutput, &proc_ptr->pdr, pdr_out);
+ pdr_out += external_pdr_size;
+ ++iproc;
+ }
+ }
+ fil_ptr->fdr.cpd = iproc - fil_ptr->fdr.ipdFirst;
+ }
+ }
+
+ return offset + iproc * external_pdr_size;
+}
+
+/* Swap out the aux information. */
+
+static unsigned long
+ecoff_build_aux (const struct ecoff_debug_swap *backend,
+ char **buf,
+ char **bufend,
+ unsigned long offset)
+{
+ int bigendian;
+ union aux_ext *aux_out;
+ long iaux;
+ vlinks_t *file_link;
+
+ bigendian = bfd_big_endian (stdoutput);
+
+ aux_out = (union aux_ext *) (*buf + offset);
+
+ iaux = 0;
+
+ /* The aux entries are stored by file. */
+ for (file_link = file_desc.first;
+ file_link != (vlinks_t *) NULL;
+ file_link = file_link->next)
+ {
+ int fil_cnt;
+ efdr_t *fil_ptr;
+ efdr_t *fil_end;
+
+ if (file_link->next == (vlinks_t *) NULL)
+ fil_cnt = file_desc.objects_last_page;
+ else
+ fil_cnt = file_desc.objects_per_page;
+ fil_ptr = file_link->datum->file;
+ fil_end = fil_ptr + fil_cnt;
+ for (; fil_ptr < fil_end; fil_ptr++)
+ {
+ vlinks_t *aux_link;
+
+ fil_ptr->fdr.fBigendian = bigendian;
+ fil_ptr->fdr.iauxBase = iaux;
+ for (aux_link = fil_ptr->aux_syms.first;
+ aux_link != (vlinks_t *) NULL;
+ aux_link = aux_link->next)
+ {
+ int aux_cnt;
+ aux_t *aux_ptr;
+ aux_t *aux_end;
+
+ if (aux_link->next == (vlinks_t *) NULL)
+ aux_cnt = fil_ptr->aux_syms.objects_last_page;
+ else
+ aux_cnt = fil_ptr->aux_syms.objects_per_page;
+ aux_ptr = aux_link->datum->aux;
+ aux_end = aux_ptr + aux_cnt;
+ for (; aux_ptr < aux_end; aux_ptr++)
+ {
+ if ((unsigned long) (*bufend - (char *) aux_out)
+ < sizeof (union aux_ext))
+ aux_out = ((union aux_ext *)
+ ecoff_add_bytes (buf, bufend,
+ (char *) aux_out,
+ sizeof (union aux_ext)));
+ switch (aux_ptr->type)
+ {
+ case aux_tir:
+ (*backend->swap_tir_out) (bigendian,
+ &aux_ptr->data.ti,
+ &aux_out->a_ti);
+ break;
+ case aux_rndx:
+ (*backend->swap_rndx_out) (bigendian,
+ &aux_ptr->data.rndx,
+ &aux_out->a_rndx);
+ break;
+ case aux_dnLow:
+ AUX_PUT_DNLOW (bigendian, aux_ptr->data.dnLow,
+ aux_out);
+ break;
+ case aux_dnHigh:
+ AUX_PUT_DNHIGH (bigendian, aux_ptr->data.dnHigh,
+ aux_out);
+ break;
+ case aux_isym:
+ AUX_PUT_ISYM (bigendian, aux_ptr->data.isym,
+ aux_out);
+ break;
+ case aux_iss:
+ AUX_PUT_ISS (bigendian, aux_ptr->data.iss,
+ aux_out);
+ break;
+ case aux_width:
+ AUX_PUT_WIDTH (bigendian, aux_ptr->data.width,
+ aux_out);
+ break;
+ case aux_count:
+ AUX_PUT_COUNT (bigendian, aux_ptr->data.count,
+ aux_out);
+ break;
+ }
+
+ ++aux_out;
+ ++iaux;
+ }
+ }
+ fil_ptr->fdr.caux = iaux - fil_ptr->fdr.iauxBase;
+ }
+ }
+
+ return ecoff_padding_adjust (backend, buf, bufend,
+ offset + iaux * sizeof (union aux_ext),
+ (char **) NULL);
+}
+
+/* Copy out the strings from a varray_t. This returns the number of
+ bytes copied, rather than the new offset. */
+
+static unsigned long
+ecoff_build_strings (char **buf,
+ char **bufend,
+ unsigned long offset,
+ varray_t *vp)
+{
+ unsigned long istr;
+ char *str_out;
+ vlinks_t *str_link;
+
+ str_out = *buf + offset;
+
+ istr = 0;
+
+ for (str_link = vp->first;
+ str_link != (vlinks_t *) NULL;
+ str_link = str_link->next)
+ {
+ unsigned long str_cnt;
+
+ if (str_link->next == (vlinks_t *) NULL)
+ str_cnt = vp->objects_last_page;
+ else
+ str_cnt = vp->objects_per_page;
+
+ if ((unsigned long)(*bufend - str_out) < str_cnt)
+ str_out = ecoff_add_bytes (buf, bufend, str_out, str_cnt);
+
+ memcpy (str_out, str_link->datum->byte, str_cnt);
+ str_out += str_cnt;
+ istr += str_cnt;
+ }
+
+ return istr;
+}
+
+/* Dump out the local strings. */
+
+static unsigned long
+ecoff_build_ss (const struct ecoff_debug_swap *backend,
+ char **buf,
+ char **bufend,
+ unsigned long offset)
+{
+ long iss;
+ vlinks_t *file_link;
+
+ iss = 0;
+
+ for (file_link = file_desc.first;
+ file_link != (vlinks_t *) NULL;
+ file_link = file_link->next)
+ {
+ int fil_cnt;
+ efdr_t *fil_ptr;
+ efdr_t *fil_end;
+
+ if (file_link->next == (vlinks_t *) NULL)
+ fil_cnt = file_desc.objects_last_page;
+ else
+ fil_cnt = file_desc.objects_per_page;
+ fil_ptr = file_link->datum->file;
+ fil_end = fil_ptr + fil_cnt;
+ for (; fil_ptr < fil_end; fil_ptr++)
+ {
+ long ss_cnt;
+
+ fil_ptr->fdr.issBase = iss;
+ ss_cnt = ecoff_build_strings (buf, bufend, offset + iss,
+ &fil_ptr->strings);
+ fil_ptr->fdr.cbSs = ss_cnt;
+ iss += ss_cnt;
+ }
+ }
+
+ return ecoff_padding_adjust (backend, buf, bufend, offset + iss,
+ (char **) NULL);
+}
+
+/* Swap out the file descriptors. */
+
+static unsigned long
+ecoff_build_fdr (const struct ecoff_debug_swap *backend,
+ char **buf,
+ char **bufend,
+ unsigned long offset)
+{
+ const bfd_size_type external_fdr_size = backend->external_fdr_size;
+ void (* const swap_fdr_out) (bfd *, const FDR *, PTR)
+ = backend->swap_fdr_out;
+ long ifile;
+ char *fdr_out;
+ vlinks_t *file_link;
+
+ ifile = 0;
+
+ fdr_out = *buf + offset;
+
+ for (file_link = file_desc.first;
+ file_link != (vlinks_t *) NULL;
+ file_link = file_link->next)
+ {
+ int fil_cnt;
+ efdr_t *fil_ptr;
+ efdr_t *fil_end;
+
+ if (file_link->next == (vlinks_t *) NULL)
+ fil_cnt = file_desc.objects_last_page;
+ else
+ fil_cnt = file_desc.objects_per_page;
+ fil_ptr = file_link->datum->file;
+ fil_end = fil_ptr + fil_cnt;
+ for (; fil_ptr < fil_end; fil_ptr++)
+ {
+ if ((bfd_size_type)(*bufend - fdr_out) < external_fdr_size)
+ fdr_out = ecoff_add_bytes (buf, bufend, fdr_out,
+ external_fdr_size);
+ (*swap_fdr_out) (stdoutput, &fil_ptr->fdr, fdr_out);
+ fdr_out += external_fdr_size;
+ ++ifile;
+ }
+ }
+
+ return offset + ifile * external_fdr_size;
+}
+
+/* Set up the external symbols. These are supposed to be handled by
+ the backend. This routine just gets the right information and
+ calls a backend function to deal with it. */
+
+static void
+ecoff_setup_ext (void)
+{
+ register symbolS *sym;
+
+ for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym))
+ {
+ if (symbol_get_obj (sym)->ecoff_symbol == NULL)
+ continue;
+
+ /* If this is a local symbol, then force the fields to zero. */
+ if (! S_IS_EXTERNAL (sym)
+ && ! S_IS_WEAK (sym)
+ && S_IS_DEFINED (sym))
+ {
+ struct localsym *lsym;
+
+ lsym = symbol_get_obj (sym)->ecoff_symbol;
+ lsym->ecoff_sym.asym.value = 0;
+ lsym->ecoff_sym.asym.st = (int) st_Nil;
+ lsym->ecoff_sym.asym.sc = (int) sc_Nil;
+ lsym->ecoff_sym.asym.index = indexNil;
+ }
+
+ obj_ecoff_set_ext (sym, &symbol_get_obj (sym)->ecoff_symbol->ecoff_sym);
+ }
+}
+
+/* Build the ECOFF debugging information. */
+
+unsigned long
+ecoff_build_debug (HDRR *hdr,
+ char **bufp,
+ const struct ecoff_debug_swap *backend)
+{
+ const bfd_size_type external_pdr_size = backend->external_pdr_size;
+ tag_t *ptag;
+ tag_t *ptag_next;
+ efdr_t *fil_ptr;
+ int end_warning;
+ efdr_t *hold_file_ptr;
+ proc_t *hold_proc_ptr;
+ symbolS *sym;
+ char *buf;
+ char *bufend;
+ unsigned long offset;
+
+ /* Make sure we have a file. */
+ if (first_file == (efdr_t *) NULL)
+ add_file ((const char *) NULL, 0, 1);
+
+ /* Handle any top level tags. */
+ for (ptag = top_tag_head->first_tag;
+ ptag != (tag_t *) NULL;
+ ptag = ptag_next)
+ {
+ if (ptag->forward_ref != (forward_t *) NULL)
+ add_unknown_tag (ptag);
+
+ ptag_next = ptag->same_block;
+ ptag->hash_ptr->tag_ptr = ptag->same_name;
+ free_tag (ptag);
+ }
+
+ free_thead (top_tag_head);
+
+ /* Look through the symbols. Add debugging information for each
+ symbol that has not already received it. */
+ hold_file_ptr = cur_file_ptr;
+ hold_proc_ptr = cur_proc_ptr;
+ cur_proc_ptr = (proc_t *) NULL;
+ for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym))
+ {
+ if (symbol_get_obj (sym)->ecoff_symbol != NULL
+ || symbol_get_obj (sym)->ecoff_file == (efdr_t *) NULL
+ || (symbol_get_bfdsym (sym)->flags & BSF_SECTION_SYM) != 0)
+ continue;
+
+ cur_file_ptr = symbol_get_obj (sym)->ecoff_file;
+ add_ecoff_symbol ((const char *) NULL, st_Nil, sc_Nil, sym,
+ (bfd_vma) 0, S_GET_VALUE (sym), indexNil);
+ }
+ cur_proc_ptr = hold_proc_ptr;
+ cur_file_ptr = hold_file_ptr;
+
+ /* Output an ending symbol for all the files. We have to do this
+ here for the last file, so we may as well do it for all of the
+ files. */
+ end_warning = 0;
+ for (fil_ptr = first_file;
+ fil_ptr != (efdr_t *) NULL;
+ fil_ptr = fil_ptr->next_file)
+ {
+ cur_file_ptr = fil_ptr;
+ while (cur_file_ptr->cur_scope != (scope_t *) NULL
+ && cur_file_ptr->cur_scope->prev != (scope_t *) NULL)
+ {
+ cur_file_ptr->cur_scope = cur_file_ptr->cur_scope->prev;
+ if (! end_warning && ! cur_file_ptr->fake)
+ {
+ as_warn (_("missing .end or .bend at end of file"));
+ end_warning = 1;
+ }
+ }
+ if (cur_file_ptr->cur_scope != (scope_t *) NULL)
+ (void) add_ecoff_symbol ((const char *) NULL,
+ st_End, sc_Text,
+ (symbolS *) NULL,
+ (bfd_vma) 0,
+ (symint_t) 0,
+ (symint_t) 0);
+ }
+
+ /* Build the symbolic information. */
+ offset = 0;
+ buf = xmalloc (PAGE_SIZE);
+ bufend = buf + PAGE_SIZE;
+
+ /* Build the line number information. */
+ hdr->cbLineOffset = offset;
+ offset = ecoff_build_lineno (backend, &buf, &bufend, offset,
+ &hdr->ilineMax);
+ hdr->cbLine = offset - hdr->cbLineOffset;
+
+ /* We don't use dense numbers at all. */
+ hdr->idnMax = 0;
+ hdr->cbDnOffset = 0;
+
+ /* We can't build the PDR table until we have built the symbols,
+ because a PDR contains a symbol index. However, we set aside
+ space at this point. */
+ hdr->ipdMax = proc_cnt;
+ hdr->cbPdOffset = offset;
+ if ((bfd_size_type)(bufend - (buf + offset)) < proc_cnt * external_pdr_size)
+ (void) ecoff_add_bytes (&buf, &bufend, buf + offset,
+ proc_cnt * external_pdr_size);
+ offset += proc_cnt * external_pdr_size;
+
+ /* Build the local symbols. */
+ hdr->cbSymOffset = offset;
+ offset = ecoff_build_symbols (backend, &buf, &bufend, offset);
+ hdr->isymMax = (offset - hdr->cbSymOffset) / backend->external_sym_size;
+
+ /* Building the symbols initializes the symbol index in the PDR's.
+ Now we can swap out the PDR's. */
+ (void) ecoff_build_procs (backend, &buf, &bufend, hdr->cbPdOffset);
+
+ /* We don't use optimization symbols. */
+ hdr->ioptMax = 0;
+ hdr->cbOptOffset = 0;
+
+ /* Swap out the auxiliary type information. */
+ hdr->cbAuxOffset = offset;
+ offset = ecoff_build_aux (backend, &buf, &bufend, offset);
+ hdr->iauxMax = (offset - hdr->cbAuxOffset) / sizeof (union aux_ext);
+
+ /* Copy out the local strings. */
+ hdr->cbSsOffset = offset;
+ offset = ecoff_build_ss (backend, &buf, &bufend, offset);
+ hdr->issMax = offset - hdr->cbSsOffset;
+
+ /* We don't use relative file descriptors. */
+ hdr->crfd = 0;
+ hdr->cbRfdOffset = 0;
+
+ /* Swap out the file descriptors. */
+ hdr->cbFdOffset = offset;
+ offset = ecoff_build_fdr (backend, &buf, &bufend, offset);
+ hdr->ifdMax = (offset - hdr->cbFdOffset) / backend->external_fdr_size;
+
+ /* Set up the external symbols, which are handled by the BFD back
+ end. */
+ hdr->issExtMax = 0;
+ hdr->cbSsExtOffset = 0;
+ hdr->iextMax = 0;
+ hdr->cbExtOffset = 0;
+ ecoff_setup_ext ();
+
+ know ((offset & (backend->debug_align - 1)) == 0);
+
+ /* FIXME: This value should be determined from the .verstamp directive,
+ with reasonable defaults in config files. */
+#ifdef TC_ALPHA
+ hdr->vstamp = 0x030b;
+#else
+ hdr->vstamp = 0x020b;
+#endif
+
+ *bufp = buf;
+ return offset;
+}
+
+/* Allocate a cluster of pages. */
+
+#ifndef MALLOC_CHECK
+
+static page_type *
+allocate_cluster (unsigned long npages)
+{
+ register page_type *value = (page_type *) xmalloc (npages * PAGE_USIZE);
+
+#ifdef ECOFF_DEBUG
+ if (debug > 3)
+ fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, value);
+#endif
+
+ memset (value, 0, npages * PAGE_USIZE);
+
+ return value;
+}
+
+static page_type *cluster_ptr = NULL;
+static unsigned long pages_left = 0;
+
+#endif /* MALLOC_CHECK */
+
+/* Allocate one page (which is initialized to 0). */
+
+static page_type *
+allocate_page (void)
+{
+#ifndef MALLOC_CHECK
+
+ if (pages_left == 0)
+ {
+ pages_left = MAX_CLUSTER_PAGES;
+ cluster_ptr = allocate_cluster (pages_left);
+ }
+
+ pages_left--;
+ return cluster_ptr++;
+
+#else /* MALLOC_CHECK */
+
+ page_type *ptr;
+
+ ptr = xmalloc (PAGE_USIZE);
+ memset (ptr, 0, PAGE_USIZE);
+ return ptr;
+
+#endif /* MALLOC_CHECK */
+}
+
+/* Allocate scoping information. */
+
+static scope_t *
+allocate_scope (void)
+{
+ register scope_t *ptr;
+ static scope_t initial_scope;
+
+#ifndef MALLOC_CHECK
+
+ ptr = alloc_counts[(int) alloc_type_scope].free_list.f_scope;
+ if (ptr != (scope_t *) NULL)
+ alloc_counts[(int) alloc_type_scope].free_list.f_scope = ptr->free;
+ else
+ {
+ register int unallocated = alloc_counts[(int) alloc_type_scope].unallocated;
+ register page_type *cur_page = alloc_counts[(int) alloc_type_scope].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (scope_t);
+ alloc_counts[(int) alloc_type_scope].cur_page = cur_page = allocate_page ();
+ alloc_counts[(int) alloc_type_scope].total_pages++;
+ }
+
+ ptr = &cur_page->scope[--unallocated];
+ alloc_counts[(int) alloc_type_scope].unallocated = unallocated;
+ }
+
+#else
+
+ ptr = (scope_t *) xmalloc (sizeof (scope_t));
+
+#endif
+
+ alloc_counts[(int) alloc_type_scope].total_alloc++;
+ *ptr = initial_scope;
+ return ptr;
+}
+
+/* Free scoping information. */
+
+static void
+free_scope (scope_t *ptr)
+{
+ alloc_counts[(int) alloc_type_scope].total_free++;
+
+#ifndef MALLOC_CHECK
+ ptr->free = alloc_counts[(int) alloc_type_scope].free_list.f_scope;
+ alloc_counts[(int) alloc_type_scope].free_list.f_scope = ptr;
+#else
+ free ((PTR) ptr);
+#endif
+}
+
+/* Allocate links for pages in a virtual array. */
+
+static vlinks_t *
+allocate_vlinks (void)
+{
+ register vlinks_t *ptr;
+ static vlinks_t initial_vlinks;
+
+#ifndef MALLOC_CHECK
+
+ register int unallocated = alloc_counts[(int) alloc_type_vlinks].unallocated;
+ register page_type *cur_page = alloc_counts[(int) alloc_type_vlinks].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (vlinks_t);
+ alloc_counts[(int) alloc_type_vlinks].cur_page = cur_page = allocate_page ();
+ alloc_counts[(int) alloc_type_vlinks].total_pages++;
+ }
+
+ ptr = &cur_page->vlinks[--unallocated];
+ alloc_counts[(int) alloc_type_vlinks].unallocated = unallocated;
+
+#else
+
+ ptr = (vlinks_t *) xmalloc (sizeof (vlinks_t));
+
+#endif
+
+ alloc_counts[(int) alloc_type_vlinks].total_alloc++;
+ *ptr = initial_vlinks;
+ return ptr;
+}
+
+/* Allocate string hash buckets. */
+
+static shash_t *
+allocate_shash (void)
+{
+ register shash_t *ptr;
+ static shash_t initial_shash;
+
+#ifndef MALLOC_CHECK
+
+ register int unallocated = alloc_counts[(int) alloc_type_shash].unallocated;
+ register page_type *cur_page = alloc_counts[(int) alloc_type_shash].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (shash_t);
+ alloc_counts[(int) alloc_type_shash].cur_page = cur_page = allocate_page ();
+ alloc_counts[(int) alloc_type_shash].total_pages++;
+ }
+
+ ptr = &cur_page->shash[--unallocated];
+ alloc_counts[(int) alloc_type_shash].unallocated = unallocated;
+
+#else
+
+ ptr = (shash_t *) xmalloc (sizeof (shash_t));
+
+#endif
+
+ alloc_counts[(int) alloc_type_shash].total_alloc++;
+ *ptr = initial_shash;
+ return ptr;
+}
+
+/* Allocate type hash buckets. */
+
+static thash_t *
+allocate_thash (void)
+{
+ register thash_t *ptr;
+ static thash_t initial_thash;
+
+#ifndef MALLOC_CHECK
+
+ register int unallocated = alloc_counts[(int) alloc_type_thash].unallocated;
+ register page_type *cur_page = alloc_counts[(int) alloc_type_thash].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (thash_t);
+ alloc_counts[(int) alloc_type_thash].cur_page = cur_page = allocate_page ();
+ alloc_counts[(int) alloc_type_thash].total_pages++;
+ }
+
+ ptr = &cur_page->thash[--unallocated];
+ alloc_counts[(int) alloc_type_thash].unallocated = unallocated;
+
+#else
+
+ ptr = (thash_t *) xmalloc (sizeof (thash_t));
+
+#endif
+
+ alloc_counts[(int) alloc_type_thash].total_alloc++;
+ *ptr = initial_thash;
+ return ptr;
+}
+
+/* Allocate structure, union, or enum tag information. */
+
+static tag_t *
+allocate_tag (void)
+{
+ register tag_t *ptr;
+ static tag_t initial_tag;
+
+#ifndef MALLOC_CHECK
+
+ ptr = alloc_counts[(int) alloc_type_tag].free_list.f_tag;
+ if (ptr != (tag_t *) NULL)
+ alloc_counts[(int) alloc_type_tag].free_list.f_tag = ptr->free;
+ else
+ {
+ register int unallocated = alloc_counts[(int) alloc_type_tag].unallocated;
+ register page_type *cur_page = alloc_counts[(int) alloc_type_tag].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (tag_t);
+ alloc_counts[(int) alloc_type_tag].cur_page = cur_page = allocate_page ();
+ alloc_counts[(int) alloc_type_tag].total_pages++;
+ }
+
+ ptr = &cur_page->tag[--unallocated];
+ alloc_counts[(int) alloc_type_tag].unallocated = unallocated;
+ }
+
+#else
+
+ ptr = (tag_t *) xmalloc (sizeof (tag_t));
+
+#endif
+
+ alloc_counts[(int) alloc_type_tag].total_alloc++;
+ *ptr = initial_tag;
+ return ptr;
+}
+
+/* Free scoping information. */
+
+static void
+free_tag (tag_t *ptr)
+{
+ alloc_counts[(int) alloc_type_tag].total_free++;
+
+#ifndef MALLOC_CHECK
+ ptr->free = alloc_counts[(int) alloc_type_tag].free_list.f_tag;
+ alloc_counts[(int) alloc_type_tag].free_list.f_tag = ptr;
+#else
+ free ((PTR_T) ptr);
+#endif
+}
+
+/* Allocate forward reference to a yet unknown tag. */
+
+static forward_t *
+allocate_forward (void)
+{
+ register forward_t *ptr;
+ static forward_t initial_forward;
+
+#ifndef MALLOC_CHECK
+
+ register int unallocated = alloc_counts[(int) alloc_type_forward].unallocated;
+ register page_type *cur_page = alloc_counts[(int) alloc_type_forward].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (forward_t);
+ alloc_counts[(int) alloc_type_forward].cur_page = cur_page = allocate_page ();
+ alloc_counts[(int) alloc_type_forward].total_pages++;
+ }
+
+ ptr = &cur_page->forward[--unallocated];
+ alloc_counts[(int) alloc_type_forward].unallocated = unallocated;
+
+#else
+
+ ptr = (forward_t *) xmalloc (sizeof (forward_t));
+
+#endif
+
+ alloc_counts[(int) alloc_type_forward].total_alloc++;
+ *ptr = initial_forward;
+ return ptr;
+}
+
+/* Allocate head of type hash list. */
+
+static thead_t *
+allocate_thead (void)
+{
+ register thead_t *ptr;
+ static thead_t initial_thead;
+
+#ifndef MALLOC_CHECK
+
+ ptr = alloc_counts[(int) alloc_type_thead].free_list.f_thead;
+ if (ptr != (thead_t *) NULL)
+ alloc_counts[(int) alloc_type_thead].free_list.f_thead = ptr->free;
+ else
+ {
+ register int unallocated = alloc_counts[(int) alloc_type_thead].unallocated;
+ register page_type *cur_page = alloc_counts[(int) alloc_type_thead].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (thead_t);
+ alloc_counts[(int) alloc_type_thead].cur_page = cur_page = allocate_page ();
+ alloc_counts[(int) alloc_type_thead].total_pages++;
+ }
+
+ ptr = &cur_page->thead[--unallocated];
+ alloc_counts[(int) alloc_type_thead].unallocated = unallocated;
+ }
+
+#else
+
+ ptr = (thead_t *) xmalloc (sizeof (thead_t));
+
+#endif
+
+ alloc_counts[(int) alloc_type_thead].total_alloc++;
+ *ptr = initial_thead;
+ return ptr;
+}
+
+/* Free scoping information. */
+
+static void
+free_thead (thead_t *ptr)
+{
+ alloc_counts[(int) alloc_type_thead].total_free++;
+
+#ifndef MALLOC_CHECK
+ ptr->free = (thead_t *) alloc_counts[(int) alloc_type_thead].free_list.f_thead;
+ alloc_counts[(int) alloc_type_thead].free_list.f_thead = ptr;
+#else
+ free ((PTR_T) ptr);
+#endif
+}
+
+static lineno_list_t *
+allocate_lineno_list (void)
+{
+ register lineno_list_t *ptr;
+ static lineno_list_t initial_lineno_list;
+
+#ifndef MALLOC_CHECK
+
+ register int unallocated = alloc_counts[(int) alloc_type_lineno].unallocated;
+ register page_type *cur_page = alloc_counts[(int) alloc_type_lineno].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (lineno_list_t);
+ alloc_counts[(int) alloc_type_lineno].cur_page = cur_page = allocate_page ();
+ alloc_counts[(int) alloc_type_lineno].total_pages++;
+ }
+
+ ptr = &cur_page->lineno[--unallocated];
+ alloc_counts[(int) alloc_type_lineno].unallocated = unallocated;
+
+#else
+
+ ptr = (lineno_list_t *) xmalloc (sizeof (lineno_list_t));
+
+#endif
+
+ alloc_counts[(int) alloc_type_lineno].total_alloc++;
+ *ptr = initial_lineno_list;
+ return ptr;
+}
+
+void
+ecoff_set_gp_prolog_size (int sz)
+{
+ if (cur_proc_ptr == 0)
+ return;
+
+ cur_proc_ptr->pdr.gp_prologue = sz;
+ if (cur_proc_ptr->pdr.gp_prologue != sz)
+ {
+ as_warn (_("GP prologue size exceeds field size, using 0 instead"));
+ cur_proc_ptr->pdr.gp_prologue = 0;
+ }
+
+ cur_proc_ptr->pdr.gp_used = 1;
+}
+
+int
+ecoff_no_current_file (void)
+{
+ return cur_file_ptr == (efdr_t *) NULL;
+}
+
+void
+ecoff_generate_asm_lineno (void)
+{
+ unsigned int lineno;
+ char *filename;
+ lineno_list_t *list;
+
+ as_where (&filename, &lineno);
+
+ if (current_stabs_filename == (char *) NULL
+ || strcmp (current_stabs_filename, filename))
+ add_file (filename, 0, 1);
+
+ list = allocate_lineno_list ();
+
+ list->next = (lineno_list_t *) NULL;
+ list->file = cur_file_ptr;
+ list->proc = cur_proc_ptr;
+ list->frag = frag_now;
+ list->paddr = frag_now_fix ();
+ list->lineno = lineno;
+
+ /* We don't want to merge files which have line numbers. */
+ cur_file_ptr->fdr.fMerge = 0;
+
+ /* A .loc directive will sometimes appear before a .ent directive,
+ which means that cur_proc_ptr will be NULL here. Arrange to
+ patch this up. */
+ if (cur_proc_ptr == (proc_t *) NULL)
+ {
+ lineno_list_t **pl;
+
+ pl = &noproc_lineno;
+ while (*pl != (lineno_list_t *) NULL)
+ pl = &(*pl)->next;
+ *pl = list;
+ }
+ else
+ {
+ last_lineno = list;
+ *last_lineno_ptr = list;
+ last_lineno_ptr = &list->next;
+ }
+}
+
+#else
+
+void
+ecoff_generate_asm_lineno (void)
+{
+}
+
+#endif /* ECOFF_DEBUGGING */
diff --git a/x/binutils/gas/ecoff.h b/x/binutils/gas/ecoff.h
new file mode 100644
index 0000000..2f09afc
--- /dev/null
+++ b/x/binutils/gas/ecoff.h
@@ -0,0 +1,111 @@
+/* ecoff.h -- header file for ECOFF debugging support
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+ Put together by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef GAS_ECOFF_H
+#define GAS_ECOFF_H
+
+#ifdef ECOFF_DEBUGGING
+
+#include "coff/sym.h"
+#include "coff/ecoff.h"
+
+/* Whether we have seen any ECOFF debugging information. */
+extern int ecoff_debugging_seen;
+
+/* This function should be called at the start of assembly, by
+ obj_read_begin_hook. */
+extern void ecoff_read_begin_hook (void);
+
+/* This function should be called when the assembler switches to a new
+ file. */
+extern void ecoff_new_file (const char *);
+
+/* This function should be called when a new symbol is created, by
+ obj_symbol_new_hook. */
+extern void ecoff_symbol_new_hook (symbolS *);
+
+/* This function should be called by the obj_frob_symbol hook. */
+extern void ecoff_frob_symbol (symbolS *);
+
+/* Build the ECOFF debugging information. This should be called by
+ obj_frob_file. This fills in the counts in *HDR; the offsets are
+ filled in relative to the start of the *BUFP. It sets *BUFP to a
+ block of memory holding the debugging information. It returns the
+ length of *BUFP. */
+extern unsigned long ecoff_build_debug
+ (HDRR *hdr, char **bufp, const struct ecoff_debug_swap *);
+
+/* Functions to handle the ECOFF debugging directives. */
+extern void ecoff_directive_begin (int);
+extern void ecoff_directive_bend (int);
+extern void ecoff_directive_end (int);
+extern void ecoff_directive_ent (int);
+extern void ecoff_directive_fmask (int);
+extern void ecoff_directive_frame (int);
+extern void ecoff_directive_loc (int);
+extern void ecoff_directive_mask (int);
+
+/* Other ECOFF directives. */
+extern void ecoff_directive_extern (int);
+extern void ecoff_directive_weakext (int);
+
+/* Functions to handle the COFF debugging directives. */
+extern void ecoff_directive_def (int);
+extern void ecoff_directive_dim (int);
+extern void ecoff_directive_endef (int);
+extern void ecoff_directive_file (int);
+extern void ecoff_directive_scl (int);
+extern void ecoff_directive_size (int);
+extern void ecoff_directive_tag (int);
+extern void ecoff_directive_type (int);
+extern void ecoff_directive_val (int);
+
+/* Handle stabs. */
+extern void ecoff_stab (segT sec, int what, const char *string,
+ int type, int other, int desc);
+
+/* Set the GP prologue size. */
+extern void ecoff_set_gp_prolog_size (int sz);
+
+/* This routine is called from the ECOFF code to set the external
+ information for a symbol. */
+#ifndef obj_ecoff_set_ext
+extern void obj_ecoff_set_ext (symbolS *, EXTR *);
+#endif
+
+/* This routine is used to patch up a line number directive when
+ instructions are moved around. */
+extern void ecoff_fix_loc (fragS *, unsigned long);
+
+/* This function is called from read.c to peek at cur_file_ptr. */
+extern int ecoff_no_current_file (void);
+
+/* This function returns the symbol associated with the current proc. */
+extern symbolS *ecoff_get_cur_proc_sym (void);
+
+#endif /* ECOFF_DEBUGGING */
+
+/* This routine is called from read.c to generate line number for .s file. */
+extern void ecoff_generate_asm_lineno (void);
+
+#endif /* ! GAS_ECOFF_H */
diff --git a/x/binutils/gas/ehopt.c b/x/binutils/gas/ehopt.c
new file mode 100644
index 0000000..451aaff
--- /dev/null
+++ b/x/binutils/gas/ehopt.c
@@ -0,0 +1,540 @@
+/* ehopt.c--optimize gcc exception frame information.
+ Copyright 1998, 2000, 2001, 2003 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "as.h"
+#include "subsegs.h"
+
+/* We include this ELF file, even though we may not be assembling for
+ ELF, since the exception frame information is always in a format
+ derived from DWARF. */
+
+#include "elf/dwarf2.h"
+
+/* Try to optimize gcc 2.8 exception frame information.
+
+ Exception frame information is emitted for every function in the
+ .eh_frame or .debug_frame sections. Simple information for a function
+ with no exceptions looks like this:
+
+__FRAME_BEGIN__:
+ .4byte .LLCIE1 / Length of Common Information Entry
+.LSCIE1:
+#if .eh_frame
+ .4byte 0x0 / CIE Identifier Tag
+#elif .debug_frame
+ .4byte 0xffffffff / CIE Identifier Tag
+#endif
+ .byte 0x1 / CIE Version
+ .byte 0x0 / CIE Augmentation (none)
+ .byte 0x1 / ULEB128 0x1 (CIE Code Alignment Factor)
+ .byte 0x7c / SLEB128 -4 (CIE Data Alignment Factor)
+ .byte 0x8 / CIE RA Column
+ .byte 0xc / DW_CFA_def_cfa
+ .byte 0x4 / ULEB128 0x4
+ .byte 0x4 / ULEB128 0x4
+ .byte 0x88 / DW_CFA_offset, column 0x8
+ .byte 0x1 / ULEB128 0x1
+ .align 4
+.LECIE1:
+ .set .LLCIE1,.LECIE1-.LSCIE1 / CIE Length Symbol
+ .4byte .LLFDE1 / FDE Length
+.LSFDE1:
+ .4byte .LSFDE1-__FRAME_BEGIN__ / FDE CIE offset
+ .4byte .LFB1 / FDE initial location
+ .4byte .LFE1-.LFB1 / FDE address range
+ .byte 0x4 / DW_CFA_advance_loc4
+ .4byte .LCFI0-.LFB1
+ .byte 0xe / DW_CFA_def_cfa_offset
+ .byte 0x8 / ULEB128 0x8
+ .byte 0x85 / DW_CFA_offset, column 0x5
+ .byte 0x2 / ULEB128 0x2
+ .byte 0x4 / DW_CFA_advance_loc4
+ .4byte .LCFI1-.LCFI0
+ .byte 0xd / DW_CFA_def_cfa_register
+ .byte 0x5 / ULEB128 0x5
+ .byte 0x4 / DW_CFA_advance_loc4
+ .4byte .LCFI2-.LCFI1
+ .byte 0x2e / DW_CFA_GNU_args_size
+ .byte 0x4 / ULEB128 0x4
+ .byte 0x4 / DW_CFA_advance_loc4
+ .4byte .LCFI3-.LCFI2
+ .byte 0x2e / DW_CFA_GNU_args_size
+ .byte 0x0 / ULEB128 0x0
+ .align 4
+.LEFDE1:
+ .set .LLFDE1,.LEFDE1-.LSFDE1 / FDE Length Symbol
+
+ The immediate issue we can address in the assembler is the
+ DW_CFA_advance_loc4 followed by a four byte value. The value is
+ the difference of two addresses in the function. Since gcc does
+ not know this value, it always uses four bytes. We will know the
+ value at the end of assembly, so we can do better. */
+
+struct cie_info
+{
+ unsigned code_alignment;
+ int z_augmentation;
+};
+
+static int get_cie_info (struct cie_info *);
+
+/* Extract information from the CIE. */
+
+static int
+get_cie_info (struct cie_info *info)
+{
+ fragS *f;
+ fixS *fix;
+ int offset;
+ char CIE_id;
+ char augmentation[10];
+ int iaug;
+ int code_alignment = 0;
+
+ /* We should find the CIE at the start of the section. */
+
+#if defined (BFD_ASSEMBLER) || defined (MANY_SEGMENTS)
+ f = seg_info (now_seg)->frchainP->frch_root;
+#else
+ f = frchain_now->frch_root;
+#endif
+#ifdef BFD_ASSEMBLER
+ fix = seg_info (now_seg)->frchainP->fix_root;
+#else
+ fix = *seg_fix_rootP;
+#endif
+
+ /* Look through the frags of the section to find the code alignment. */
+
+ /* First make sure that the CIE Identifier Tag is 0/-1. */
+
+ if (strcmp (segment_name (now_seg), ".debug_frame") == 0)
+ CIE_id = (char)0xff;
+ else
+ CIE_id = 0;
+
+ offset = 4;
+ while (f != NULL && offset >= f->fr_fix)
+ {
+ offset -= f->fr_fix;
+ f = f->fr_next;
+ }
+ if (f == NULL
+ || f->fr_fix - offset < 4
+ || f->fr_literal[offset] != CIE_id
+ || f->fr_literal[offset + 1] != CIE_id
+ || f->fr_literal[offset + 2] != CIE_id
+ || f->fr_literal[offset + 3] != CIE_id)
+ return 0;
+
+ /* Next make sure the CIE version number is 1. */
+
+ offset += 4;
+ while (f != NULL && offset >= f->fr_fix)
+ {
+ offset -= f->fr_fix;
+ f = f->fr_next;
+ }
+ if (f == NULL
+ || f->fr_fix - offset < 1
+ || f->fr_literal[offset] != 1)
+ return 0;
+
+ /* Skip the augmentation (a null terminated string). */
+
+ iaug = 0;
+ ++offset;
+ while (1)
+ {
+ while (f != NULL && offset >= f->fr_fix)
+ {
+ offset -= f->fr_fix;
+ f = f->fr_next;
+ }
+ if (f == NULL)
+ return 0;
+
+ while (offset < f->fr_fix && f->fr_literal[offset] != '\0')
+ {
+ if ((size_t) iaug < (sizeof augmentation) - 1)
+ {
+ augmentation[iaug] = f->fr_literal[offset];
+ ++iaug;
+ }
+ ++offset;
+ }
+ if (offset < f->fr_fix)
+ break;
+ }
+ ++offset;
+ while (f != NULL && offset >= f->fr_fix)
+ {
+ offset -= f->fr_fix;
+ f = f->fr_next;
+ }
+ if (f == NULL)
+ return 0;
+
+ augmentation[iaug] = '\0';
+ if (augmentation[0] == '\0')
+ {
+ /* No augmentation. */
+ }
+ else if (strcmp (augmentation, "eh") == 0)
+ {
+ /* We have to skip a pointer. Unfortunately, we don't know how
+ large it is. We find out by looking for a matching fixup. */
+ while (fix != NULL
+ && (fix->fx_frag != f || fix->fx_where != offset))
+ fix = fix->fx_next;
+ if (fix == NULL)
+ offset += 4;
+ else
+ offset += fix->fx_size;
+ while (f != NULL && offset >= f->fr_fix)
+ {
+ offset -= f->fr_fix;
+ f = f->fr_next;
+ }
+ if (f == NULL)
+ return 0;
+ }
+ else if (augmentation[0] != 'z')
+ return 0;
+
+ /* We're now at the code alignment factor, which is a ULEB128. If
+ it isn't a single byte, forget it. */
+
+ code_alignment = f->fr_literal[offset] & 0xff;
+ if ((code_alignment & 0x80) != 0)
+ code_alignment = 0;
+
+ info->code_alignment = code_alignment;
+ info->z_augmentation = (augmentation[0] == 'z');
+
+ return 1;
+}
+
+/* This function is called from emit_expr. It looks for cases which
+ we can optimize.
+
+ Rather than try to parse all this information as we read it, we
+ look for a single byte DW_CFA_advance_loc4 followed by a 4 byte
+ difference. We turn that into a rs_cfa_advance frag, and handle
+ those frags at the end of the assembly. If the gcc output changes
+ somewhat, this optimization may stop working.
+
+ This function returns non-zero if it handled the expression and
+ emit_expr should not do anything, or zero otherwise. It can also
+ change *EXP and *PNBYTES. */
+
+int
+check_eh_frame (expressionS *exp, unsigned int *pnbytes)
+{
+ struct frame_data
+ {
+ enum frame_state
+ {
+ state_idle,
+ state_saw_size,
+ state_saw_cie_offset,
+ state_saw_pc_begin,
+ state_seeing_aug_size,
+ state_skipping_aug,
+ state_wait_loc4,
+ state_saw_loc4,
+ state_error,
+ } state;
+
+ int cie_info_ok;
+ struct cie_info cie_info;
+
+ symbolS *size_end_sym;
+ fragS *loc4_frag;
+ int loc4_fix;
+
+ int aug_size;
+ int aug_shift;
+ };
+
+ static struct frame_data eh_frame_data;
+ static struct frame_data debug_frame_data;
+ struct frame_data *d;
+
+ /* Don't optimize. */
+ if (flag_traditional_format)
+ return 0;
+
+ /* Select the proper section data. */
+ if (strcmp (segment_name (now_seg), ".eh_frame") == 0)
+ d = &eh_frame_data;
+ else if (strcmp (segment_name (now_seg), ".debug_frame") == 0)
+ d = &debug_frame_data;
+ else
+ return 0;
+
+ if (d->state >= state_saw_size && S_IS_DEFINED (d->size_end_sym))
+ {
+ /* We have come to the end of the CIE or FDE. See below where
+ we set saw_size. We must check this first because we may now
+ be looking at the next size. */
+ d->state = state_idle;
+ }
+
+ switch (d->state)
+ {
+ case state_idle:
+ if (*pnbytes == 4)
+ {
+ /* This might be the size of the CIE or FDE. We want to know
+ the size so that we don't accidentally optimize across an FDE
+ boundary. We recognize the size in one of two forms: a
+ symbol which will later be defined as a difference, or a
+ subtraction of two symbols. Either way, we can tell when we
+ are at the end of the FDE because the symbol becomes defined
+ (in the case of a subtraction, the end symbol, from which the
+ start symbol is being subtracted). Other ways of describing
+ the size will not be optimized. */
+ if ((exp->X_op == O_symbol || exp->X_op == O_subtract)
+ && ! S_IS_DEFINED (exp->X_add_symbol))
+ {
+ d->state = state_saw_size;
+ d->size_end_sym = exp->X_add_symbol;
+ }
+ }
+ break;
+
+ case state_saw_size:
+ case state_saw_cie_offset:
+ /* Assume whatever form it appears in, it appears atomically. */
+ d->state += 1;
+ break;
+
+ case state_saw_pc_begin:
+ /* Decide whether we should see an augmentation. */
+ if (! d->cie_info_ok
+ && ! (d->cie_info_ok = get_cie_info (&d->cie_info)))
+ d->state = state_error;
+ else if (d->cie_info.z_augmentation)
+ {
+ d->state = state_seeing_aug_size;
+ d->aug_size = 0;
+ d->aug_shift = 0;
+ }
+ else
+ d->state = state_wait_loc4;
+ break;
+
+ case state_seeing_aug_size:
+ /* Bytes == -1 means this comes from an leb128 directive. */
+ if ((int)*pnbytes == -1 && exp->X_op == O_constant)
+ {
+ d->aug_size = exp->X_add_number;
+ d->state = state_skipping_aug;
+ }
+ else if (*pnbytes == 1 && exp->X_op == O_constant)
+ {
+ unsigned char byte = exp->X_add_number;
+ d->aug_size |= (byte & 0x7f) << d->aug_shift;
+ d->aug_shift += 7;
+ if ((byte & 0x80) == 0)
+ d->state = state_skipping_aug;
+ }
+ else
+ d->state = state_error;
+ if (d->state == state_skipping_aug && d->aug_size == 0)
+ d->state = state_wait_loc4;
+ break;
+
+ case state_skipping_aug:
+ if ((int)*pnbytes < 0)
+ d->state = state_error;
+ else
+ {
+ int left = (d->aug_size -= *pnbytes);
+ if (left == 0)
+ d->state = state_wait_loc4;
+ else if (left < 0)
+ d->state = state_error;
+ }
+ break;
+
+ case state_wait_loc4:
+ if (*pnbytes == 1
+ && exp->X_op == O_constant
+ && exp->X_add_number == DW_CFA_advance_loc4)
+ {
+ /* This might be a DW_CFA_advance_loc4. Record the frag and the
+ position within the frag, so that we can change it later. */
+ frag_grow (1);
+ d->state = state_saw_loc4;
+ d->loc4_frag = frag_now;
+ d->loc4_fix = frag_now_fix ();
+ }
+ break;
+
+ case state_saw_loc4:
+ d->state = state_wait_loc4;
+ if (*pnbytes != 4)
+ break;
+ if (exp->X_op == O_constant)
+ {
+ /* This is a case which we can optimize. The two symbols being
+ subtracted were in the same frag and the expression was
+ reduced to a constant. We can do the optimization entirely
+ in this function. */
+ if (d->cie_info.code_alignment > 0
+ && exp->X_add_number % d->cie_info.code_alignment == 0
+ && exp->X_add_number / d->cie_info.code_alignment < 0x40)
+ {
+ d->loc4_frag->fr_literal[d->loc4_fix]
+ = DW_CFA_advance_loc
+ | (exp->X_add_number / d->cie_info.code_alignment);
+ /* No more bytes needed. */
+ return 1;
+ }
+ else if (exp->X_add_number < 0x100)
+ {
+ d->loc4_frag->fr_literal[d->loc4_fix] = DW_CFA_advance_loc1;
+ *pnbytes = 1;
+ }
+ else if (exp->X_add_number < 0x10000)
+ {
+ d->loc4_frag->fr_literal[d->loc4_fix] = DW_CFA_advance_loc2;
+ *pnbytes = 2;
+ }
+ }
+ else if (exp->X_op == O_subtract)
+ {
+ /* This is a case we can optimize. The expression was not
+ reduced, so we can not finish the optimization until the end
+ of the assembly. We set up a variant frag which we handle
+ later. */
+ int fr_subtype;
+
+ if (d->cie_info.code_alignment > 0)
+ fr_subtype = d->cie_info.code_alignment << 3;
+ else
+ fr_subtype = 0;
+
+ frag_var (rs_cfa, 4, 0, fr_subtype, make_expr_symbol (exp),
+ d->loc4_fix, (char *) d->loc4_frag);
+ return 1;
+ }
+ break;
+
+ case state_error:
+ /* Just skipping everything. */
+ break;
+ }
+
+ return 0;
+}
+
+/* The function estimates the size of a rs_cfa variant frag based on
+ the current values of the symbols. It is called before the
+ relaxation loop. We set fr_subtype{0:2} to the expected length. */
+
+int
+eh_frame_estimate_size_before_relax (fragS *frag)
+{
+ offsetT diff;
+ int ca = frag->fr_subtype >> 3;
+ int ret;
+
+ diff = resolve_symbol_value (frag->fr_symbol);
+
+ if (ca > 0 && diff % ca == 0 && diff / ca < 0x40)
+ ret = 0;
+ else if (diff < 0x100)
+ ret = 1;
+ else if (diff < 0x10000)
+ ret = 2;
+ else
+ ret = 4;
+
+ frag->fr_subtype = (frag->fr_subtype & ~7) | ret;
+
+ return ret;
+}
+
+/* This function relaxes a rs_cfa variant frag based on the current
+ values of the symbols. fr_subtype{0:2} is the current length of
+ the frag. This returns the change in frag length. */
+
+int
+eh_frame_relax_frag (fragS *frag)
+{
+ int oldsize, newsize;
+
+ oldsize = frag->fr_subtype & 7;
+ newsize = eh_frame_estimate_size_before_relax (frag);
+ return newsize - oldsize;
+}
+
+/* This function converts a rs_cfa variant frag into a normal fill
+ frag. This is called after all relaxation has been done.
+ fr_subtype{0:2} will be the desired length of the frag. */
+
+void
+eh_frame_convert_frag (fragS *frag)
+{
+ offsetT diff;
+ fragS *loc4_frag;
+ int loc4_fix;
+
+ loc4_frag = (fragS *) frag->fr_opcode;
+ loc4_fix = (int) frag->fr_offset;
+
+ diff = resolve_symbol_value (frag->fr_symbol);
+
+ switch (frag->fr_subtype & 7)
+ {
+ case 0:
+ {
+ int ca = frag->fr_subtype >> 3;
+ assert (ca > 0 && diff % ca == 0 && diff / ca < 0x40);
+ loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc | (diff / ca);
+ }
+ break;
+
+ case 1:
+ assert (diff < 0x100);
+ loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc1;
+ frag->fr_literal[frag->fr_fix] = diff;
+ break;
+
+ case 2:
+ assert (diff < 0x10000);
+ loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc2;
+ md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 2);
+ break;
+
+ default:
+ md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 4);
+ break;
+ }
+
+ frag->fr_fix += frag->fr_subtype & 7;
+ frag->fr_type = rs_fill;
+ frag->fr_subtype = 0;
+ frag->fr_offset = 0;
+}
diff --git a/x/binutils/gas/emul-target.h b/x/binutils/gas/emul-target.h
new file mode 100644
index 0000000..4c1a02a
--- /dev/null
+++ b/x/binutils/gas/emul-target.h
@@ -0,0 +1,64 @@
+/* emul-target.h. Default values for struct emulation defined in emul.h
+ Copyright 2001 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef emul_init
+#define emul_init common_emul_init
+#endif
+
+#ifndef emul_bfd_name
+#define emul_bfd_name default_emul_bfd_name
+#endif
+
+#ifndef emul_local_labels_fb
+#define emul_local_labels_fb 0
+#endif
+
+#ifndef emul_local_labels_dollar
+#define emul_local_labels_dollar 0
+#endif
+
+#ifndef emul_leading_underscore
+#define emul_leading_underscore 2
+#endif
+
+#ifndef emul_strip_underscore
+#define emul_strip_underscore 0
+#endif
+
+#ifndef emul_default_endian
+#define emul_default_endian 2
+#endif
+
+#ifndef emul_fake_label_name
+#define emul_fake_label_name 0
+#endif
+
+struct emulation emul_struct_name =
+ {
+ 0,
+ emul_name,
+ emul_init,
+ emul_bfd_name,
+ emul_local_labels_fb, emul_local_labels_dollar,
+ emul_leading_underscore, emul_strip_underscore,
+ emul_default_endian,
+ emul_fake_label_name,
+ emul_format,
+ };
diff --git a/x/binutils/gas/emul.h b/x/binutils/gas/emul.h
new file mode 100644
index 0000000..e4afa68
--- /dev/null
+++ b/x/binutils/gas/emul.h
@@ -0,0 +1,44 @@
+/* emul.h. File format emulation routines
+ Copyright 2001 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef EMUL_DEFS
+#define EMUL_DEFS
+
+struct emulation
+ {
+ void (* match) (const char *);
+ const char * name;
+ void (* init) (void);
+ const char *(* bfd_name) (void);
+ unsigned local_labels_fb : 1;
+ unsigned local_labels_dollar : 1;
+ unsigned leading_underscore : 2;
+ unsigned strip_underscore : 1;
+ unsigned default_endian : 2;
+ const char * fake_label_name;
+ const struct format_ops * format;
+ };
+
+COMMON struct emulation * this_emulation;
+
+extern const char * default_emul_bfd_name (void);
+extern void common_emul_init (void);
+
+#endif
diff --git a/x/binutils/gas/expr.c b/x/binutils/gas/expr.c
new file mode 100644
index 0000000..d520a04
--- /dev/null
+++ b/x/binutils/gas/expr.c
@@ -0,0 +1,1917 @@
+/* expr.c -operands, expressions-
+ Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This is really a branch office of as-read.c. I split it out to clearly
+ distinguish the world of expressions from the world of statements.
+ (It also gives smaller files to re-compile.)
+ Here, "operand"s are of expressions, not instructions. */
+
+#include <string.h>
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+#include "as.h"
+#include "safe-ctype.h"
+#include "obstack.h"
+
+static void floating_constant (expressionS * expressionP);
+static valueT generic_bignum_to_int32 (void);
+#ifdef BFD64
+static valueT generic_bignum_to_int64 (void);
+#endif
+static void integer_constant (int radix, expressionS * expressionP);
+static void mri_char_constant (expressionS *);
+static void current_location (expressionS *);
+static void clean_up_expression (expressionS * expressionP);
+static segT operand (expressionS *);
+static operatorT operator (int *);
+
+extern const char EXP_CHARS[], FLT_CHARS[];
+
+/* We keep a mapping of expression symbols to file positions, so that
+ we can provide better error messages. */
+
+struct expr_symbol_line {
+ struct expr_symbol_line *next;
+ symbolS *sym;
+ char *file;
+ unsigned int line;
+};
+
+static struct expr_symbol_line *expr_symbol_lines;
+
+/* Build a dummy symbol to hold a complex expression. This is how we
+ build expressions up out of other expressions. The symbol is put
+ into the fake section expr_section. */
+
+symbolS *
+make_expr_symbol (expressionS *expressionP)
+{
+ expressionS zero;
+ symbolS *symbolP;
+ struct expr_symbol_line *n;
+
+ if (expressionP->X_op == O_symbol
+ && expressionP->X_add_number == 0)
+ return expressionP->X_add_symbol;
+
+ if (expressionP->X_op == O_big)
+ {
+ /* This won't work, because the actual value is stored in
+ generic_floating_point_number or generic_bignum, and we are
+ going to lose it if we haven't already. */
+ if (expressionP->X_add_number > 0)
+ as_bad (_("bignum invalid"));
+ else
+ as_bad (_("floating point number invalid"));
+ zero.X_op = O_constant;
+ zero.X_add_number = 0;
+ zero.X_unsigned = 0;
+ clean_up_expression (&zero);
+ expressionP = &zero;
+ }
+
+ /* Putting constant symbols in absolute_section rather than
+ expr_section is convenient for the old a.out code, for which
+ S_GET_SEGMENT does not always retrieve the value put in by
+ S_SET_SEGMENT. */
+ symbolP = symbol_create (FAKE_LABEL_NAME,
+ (expressionP->X_op == O_constant
+ ? absolute_section
+ : expr_section),
+ 0, &zero_address_frag);
+ symbol_set_value_expression (symbolP, expressionP);
+
+ if (expressionP->X_op == O_constant)
+ resolve_symbol_value (symbolP);
+
+ n = (struct expr_symbol_line *) xmalloc (sizeof *n);
+ n->sym = symbolP;
+ as_where (&n->file, &n->line);
+ n->next = expr_symbol_lines;
+ expr_symbol_lines = n;
+
+ return symbolP;
+}
+
+/* Return the file and line number for an expr symbol. Return
+ non-zero if something was found, 0 if no information is known for
+ the symbol. */
+
+int
+expr_symbol_where (symbolS *sym, char **pfile, unsigned int *pline)
+{
+ register struct expr_symbol_line *l;
+
+ for (l = expr_symbol_lines; l != NULL; l = l->next)
+ {
+ if (l->sym == sym)
+ {
+ *pfile = l->file;
+ *pline = l->line;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* Utilities for building expressions.
+ Since complex expressions are recorded as symbols for use in other
+ expressions these return a symbolS * and not an expressionS *.
+ These explicitly do not take an "add_number" argument. */
+/* ??? For completeness' sake one might want expr_build_symbol.
+ It would just return its argument. */
+
+/* Build an expression for an unsigned constant.
+ The corresponding one for signed constants is missing because
+ there's currently no need for it. One could add an unsigned_p flag
+ but that seems more clumsy. */
+
+symbolS *
+expr_build_uconstant (offsetT value)
+{
+ expressionS e;
+
+ e.X_op = O_constant;
+ e.X_add_number = value;
+ e.X_unsigned = 1;
+ return make_expr_symbol (&e);
+}
+
+/* Build an expression for OP s1. */
+
+symbolS *
+expr_build_unary (operatorT op, symbolS *s1)
+{
+ expressionS e;
+
+ e.X_op = op;
+ e.X_add_symbol = s1;
+ e.X_add_number = 0;
+ return make_expr_symbol (&e);
+}
+
+/* Build an expression for s1 OP s2. */
+
+symbolS *
+expr_build_binary (operatorT op, symbolS *s1, symbolS *s2)
+{
+ expressionS e;
+
+ e.X_op = op;
+ e.X_add_symbol = s1;
+ e.X_op_symbol = s2;
+ e.X_add_number = 0;
+ return make_expr_symbol (&e);
+}
+
+/* Build an expression for the current location ('.'). */
+
+symbolS *
+expr_build_dot (void)
+{
+ expressionS e;
+
+ current_location (&e);
+ return make_expr_symbol (&e);
+}
+
+/* Build any floating-point literal here.
+ Also build any bignum literal here. */
+
+/* Seems atof_machine can backscan through generic_bignum and hit whatever
+ happens to be loaded before it in memory. And its way too complicated
+ for me to fix right. Thus a hack. JF: Just make generic_bignum bigger,
+ and never write into the early words, thus they'll always be zero.
+ I hate Dean's floating-point code. Bleh. */
+LITTLENUM_TYPE generic_bignum[SIZE_OF_LARGE_NUMBER + 6];
+
+FLONUM_TYPE generic_floating_point_number = {
+ &generic_bignum[6], /* low. (JF: Was 0) */
+ &generic_bignum[SIZE_OF_LARGE_NUMBER + 6 - 1], /* high. JF: (added +6) */
+ 0, /* leader. */
+ 0, /* exponent. */
+ 0 /* sign. */
+};
+
+/* If nonzero, we've been asked to assemble nan, +inf or -inf. */
+int generic_floating_point_magic;
+
+static void
+floating_constant (expressionS *expressionP)
+{
+ /* input_line_pointer -> floating-point constant. */
+ int error_code;
+
+ error_code = atof_generic (&input_line_pointer, ".", EXP_CHARS,
+ &generic_floating_point_number);
+
+ if (error_code)
+ {
+ if (error_code == ERROR_EXPONENT_OVERFLOW)
+ {
+ as_bad (_("bad floating-point constant: exponent overflow"));
+ }
+ else
+ {
+ as_bad (_("bad floating-point constant: unknown error code=%d"),
+ error_code);
+ }
+ }
+ expressionP->X_op = O_big;
+ /* input_line_pointer -> just after constant, which may point to
+ whitespace. */
+ expressionP->X_add_number = -1;
+}
+
+static valueT
+generic_bignum_to_int32 (void)
+{
+ valueT number =
+ ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
+ | (generic_bignum[0] & LITTLENUM_MASK);
+ number &= 0xffffffff;
+ return number;
+}
+
+#ifdef BFD64
+static valueT
+generic_bignum_to_int64 (void)
+{
+ valueT number =
+ ((((((((valueT) generic_bignum[3] & LITTLENUM_MASK)
+ << LITTLENUM_NUMBER_OF_BITS)
+ | ((valueT) generic_bignum[2] & LITTLENUM_MASK))
+ << LITTLENUM_NUMBER_OF_BITS)
+ | ((valueT) generic_bignum[1] & LITTLENUM_MASK))
+ << LITTLENUM_NUMBER_OF_BITS)
+ | ((valueT) generic_bignum[0] & LITTLENUM_MASK));
+ return number;
+}
+#endif
+
+static void
+integer_constant (int radix, expressionS *expressionP)
+{
+ char *start; /* Start of number. */
+ char *suffix = NULL;
+ char c;
+ valueT number; /* Offset or (absolute) value. */
+ short int digit; /* Value of next digit in current radix. */
+ short int maxdig = 0; /* Highest permitted digit value. */
+ int too_many_digits = 0; /* If we see >= this number of. */
+ char *name; /* Points to name of symbol. */
+ symbolS *symbolP; /* Points to symbol. */
+
+ int small; /* True if fits in 32 bits. */
+
+ /* May be bignum, or may fit in 32 bits. */
+ /* Most numbers fit into 32 bits, and we want this case to be fast.
+ so we pretend it will fit into 32 bits. If, after making up a 32
+ bit number, we realise that we have scanned more digits than
+ comfortably fit into 32 bits, we re-scan the digits coding them
+ into a bignum. For decimal and octal numbers we are
+ conservative: Some numbers may be assumed bignums when in fact
+ they do fit into 32 bits. Numbers of any radix can have excess
+ leading zeros: We strive to recognise this and cast them back
+ into 32 bits. We must check that the bignum really is more than
+ 32 bits, and change it back to a 32-bit number if it fits. The
+ number we are looking for is expected to be positive, but if it
+ fits into 32 bits as an unsigned number, we let it be a 32-bit
+ number. The cavalier approach is for speed in ordinary cases. */
+ /* This has been extended for 64 bits. We blindly assume that if
+ you're compiling in 64-bit mode, the target is a 64-bit machine.
+ This should be cleaned up. */
+
+#ifdef BFD64
+#define valuesize 64
+#else /* includes non-bfd case, mostly */
+#define valuesize 32
+#endif
+
+ if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) && radix == 0)
+ {
+ int flt = 0;
+
+ /* In MRI mode, the number may have a suffix indicating the
+ radix. For that matter, it might actually be a floating
+ point constant. */
+ for (suffix = input_line_pointer; ISALNUM (*suffix); suffix++)
+ {
+ if (*suffix == 'e' || *suffix == 'E')
+ flt = 1;
+ }
+
+ if (suffix == input_line_pointer)
+ {
+ radix = 10;
+ suffix = NULL;
+ }
+ else
+ {
+ c = *--suffix;
+ c = TOUPPER (c);
+ if (c == 'B')
+ radix = 2;
+ else if (c == 'D')
+ radix = 10;
+ else if (c == 'O' || c == 'Q')
+ radix = 8;
+ else if (c == 'H')
+ radix = 16;
+ else if (suffix[1] == '.' || c == 'E' || flt)
+ {
+ floating_constant (expressionP);
+ return;
+ }
+ else
+ {
+ radix = 10;
+ suffix = NULL;
+ }
+ }
+ }
+
+ switch (radix)
+ {
+ case 2:
+ maxdig = 2;
+ too_many_digits = valuesize + 1;
+ break;
+ case 8:
+ maxdig = radix = 8;
+ too_many_digits = (valuesize + 2) / 3 + 1;
+ break;
+ case 16:
+ maxdig = radix = 16;
+ too_many_digits = (valuesize + 3) / 4 + 1;
+ break;
+ case 10:
+ maxdig = radix = 10;
+ too_many_digits = (valuesize + 11) / 4; /* Very rough. */
+ }
+#undef valuesize
+ start = input_line_pointer;
+ c = *input_line_pointer++;
+ for (number = 0;
+ (digit = hex_value (c)) < maxdig;
+ c = *input_line_pointer++)
+ {
+ number = number * radix + digit;
+ }
+ /* c contains character after number. */
+ /* input_line_pointer->char after c. */
+ small = (input_line_pointer - start - 1) < too_many_digits;
+
+ if (radix == 16 && c == '_')
+ {
+ /* This is literal of the form 0x333_0_12345678_1.
+ This example is equivalent to 0x00000333000000001234567800000001. */
+
+ int num_little_digits = 0;
+ int i;
+ input_line_pointer = start; /* -> 1st digit. */
+
+ know (LITTLENUM_NUMBER_OF_BITS == 16);
+
+ for (c = '_'; c == '_'; num_little_digits += 2)
+ {
+
+ /* Convert one 64-bit word. */
+ int ndigit = 0;
+ number = 0;
+ for (c = *input_line_pointer++;
+ (digit = hex_value (c)) < maxdig;
+ c = *(input_line_pointer++))
+ {
+ number = number * radix + digit;
+ ndigit++;
+ }
+
+ /* Check for 8 digit per word max. */
+ if (ndigit > 8)
+ as_bad (_("a bignum with underscores may not have more than 8 hex digits in any word"));
+
+ /* Add this chunk to the bignum.
+ Shift things down 2 little digits. */
+ know (LITTLENUM_NUMBER_OF_BITS == 16);
+ for (i = min (num_little_digits + 1, SIZE_OF_LARGE_NUMBER - 1);
+ i >= 2;
+ i--)
+ generic_bignum[i] = generic_bignum[i - 2];
+
+ /* Add the new digits as the least significant new ones. */
+ generic_bignum[0] = number & 0xffffffff;
+ generic_bignum[1] = number >> 16;
+ }
+
+ /* Again, c is char after number, input_line_pointer->after c. */
+
+ if (num_little_digits > SIZE_OF_LARGE_NUMBER - 1)
+ num_little_digits = SIZE_OF_LARGE_NUMBER - 1;
+
+ assert (num_little_digits >= 4);
+
+ if (num_little_digits != 8)
+ as_bad (_("a bignum with underscores must have exactly 4 words"));
+
+ /* We might have some leading zeros. These can be trimmed to give
+ us a change to fit this constant into a small number. */
+ while (generic_bignum[num_little_digits - 1] == 0
+ && num_little_digits > 1)
+ num_little_digits--;
+
+ if (num_little_digits <= 2)
+ {
+ /* will fit into 32 bits. */
+ number = generic_bignum_to_int32 ();
+ small = 1;
+ }
+#ifdef BFD64
+ else if (num_little_digits <= 4)
+ {
+ /* Will fit into 64 bits. */
+ number = generic_bignum_to_int64 ();
+ small = 1;
+ }
+#endif
+ else
+ {
+ small = 0;
+
+ /* Number of littlenums in the bignum. */
+ number = num_little_digits;
+ }
+ }
+ else if (!small)
+ {
+ /* We saw a lot of digits. manufacture a bignum the hard way. */
+ LITTLENUM_TYPE *leader; /* -> high order littlenum of the bignum. */
+ LITTLENUM_TYPE *pointer; /* -> littlenum we are frobbing now. */
+ long carry;
+
+ leader = generic_bignum;
+ generic_bignum[0] = 0;
+ generic_bignum[1] = 0;
+ generic_bignum[2] = 0;
+ generic_bignum[3] = 0;
+ input_line_pointer = start; /* -> 1st digit. */
+ c = *input_line_pointer++;
+ for (; (carry = hex_value (c)) < maxdig; c = *input_line_pointer++)
+ {
+ for (pointer = generic_bignum; pointer <= leader; pointer++)
+ {
+ long work;
+
+ work = carry + radix * *pointer;
+ *pointer = work & LITTLENUM_MASK;
+ carry = work >> LITTLENUM_NUMBER_OF_BITS;
+ }
+ if (carry)
+ {
+ if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1)
+ {
+ /* Room to grow a longer bignum. */
+ *++leader = carry;
+ }
+ }
+ }
+ /* Again, c is char after number. */
+ /* input_line_pointer -> after c. */
+ know (LITTLENUM_NUMBER_OF_BITS == 16);
+ if (leader < generic_bignum + 2)
+ {
+ /* Will fit into 32 bits. */
+ number = generic_bignum_to_int32 ();
+ small = 1;
+ }
+#ifdef BFD64
+ else if (leader < generic_bignum + 4)
+ {
+ /* Will fit into 64 bits. */
+ number = generic_bignum_to_int64 ();
+ small = 1;
+ }
+#endif
+ else
+ {
+ /* Number of littlenums in the bignum. */
+ number = leader - generic_bignum + 1;
+ }
+ }
+
+ if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri)
+ && suffix != NULL
+ && input_line_pointer - 1 == suffix)
+ c = *input_line_pointer++;
+
+ if (small)
+ {
+ /* Here with number, in correct radix. c is the next char.
+ Note that unlike un*x, we allow "011f" "0x9f" to both mean
+ the same as the (conventional) "9f".
+ This is simply easier than checking for strict canonical
+ form. Syntax sux! */
+
+ if (LOCAL_LABELS_FB && c == 'b')
+ {
+ /* Backward ref to local label.
+ Because it is backward, expect it to be defined. */
+ /* Construct a local label. */
+ name = fb_label_name ((int) number, 0);
+
+ /* Seen before, or symbol is defined: OK. */
+ symbolP = symbol_find (name);
+ if ((symbolP != NULL) && (S_IS_DEFINED (symbolP)))
+ {
+ /* Local labels are never absolute. Don't waste time
+ checking absoluteness. */
+ know (SEG_NORMAL (S_GET_SEGMENT (symbolP)));
+
+ expressionP->X_op = O_symbol;
+ expressionP->X_add_symbol = symbolP;
+ }
+ else
+ {
+ /* Either not seen or not defined. */
+ /* @@ Should print out the original string instead of
+ the parsed number. */
+ as_bad (_("backward ref to unknown label \"%d:\""),
+ (int) number);
+ expressionP->X_op = O_constant;
+ }
+
+ expressionP->X_add_number = 0;
+ } /* case 'b' */
+ else if (LOCAL_LABELS_FB && c == 'f')
+ {
+ /* Forward reference. Expect symbol to be undefined or
+ unknown. undefined: seen it before. unknown: never seen
+ it before.
+
+ Construct a local label name, then an undefined symbol.
+ Don't create a xseg frag for it: caller may do that.
+ Just return it as never seen before. */
+ name = fb_label_name ((int) number, 1);
+ symbolP = symbol_find_or_make (name);
+ /* We have no need to check symbol properties. */
+#ifndef many_segments
+ /* Since "know" puts its arg into a "string", we
+ can't have newlines in the argument. */
+ know (S_GET_SEGMENT (symbolP) == undefined_section || S_GET_SEGMENT (symbolP) == text_section || S_GET_SEGMENT (symbolP) == data_section);
+#endif
+ expressionP->X_op = O_symbol;
+ expressionP->X_add_symbol = symbolP;
+ expressionP->X_add_number = 0;
+ } /* case 'f' */
+ else if (LOCAL_LABELS_DOLLAR && c == '$')
+ {
+ /* If the dollar label is *currently* defined, then this is just
+ another reference to it. If it is not *currently* defined,
+ then this is a fresh instantiation of that number, so create
+ it. */
+
+ if (dollar_label_defined ((long) number))
+ {
+ name = dollar_label_name ((long) number, 0);
+ symbolP = symbol_find (name);
+ know (symbolP != NULL);
+ }
+ else
+ {
+ name = dollar_label_name ((long) number, 1);
+ symbolP = symbol_find_or_make (name);
+ }
+
+ expressionP->X_op = O_symbol;
+ expressionP->X_add_symbol = symbolP;
+ expressionP->X_add_number = 0;
+ } /* case '$' */
+ else
+ {
+ expressionP->X_op = O_constant;
+#ifdef TARGET_WORD_SIZE
+ /* Sign extend NUMBER. */
+ number |= (-(number >> (TARGET_WORD_SIZE - 1))) << (TARGET_WORD_SIZE - 1);
+#endif
+ expressionP->X_add_number = number;
+ input_line_pointer--; /* Restore following character. */
+ } /* Really just a number. */
+ }
+ else
+ {
+ /* Not a small number. */
+ expressionP->X_op = O_big;
+ expressionP->X_add_number = number; /* Number of littlenums. */
+ input_line_pointer--; /* -> char following number. */
+ }
+}
+
+/* Parse an MRI multi character constant. */
+
+static void
+mri_char_constant (expressionS *expressionP)
+{
+ int i;
+
+ if (*input_line_pointer == '\''
+ && input_line_pointer[1] != '\'')
+ {
+ expressionP->X_op = O_constant;
+ expressionP->X_add_number = 0;
+ return;
+ }
+
+ /* In order to get the correct byte ordering, we must build the
+ number in reverse. */
+ for (i = SIZE_OF_LARGE_NUMBER - 1; i >= 0; i--)
+ {
+ int j;
+
+ generic_bignum[i] = 0;
+ for (j = 0; j < CHARS_PER_LITTLENUM; j++)
+ {
+ if (*input_line_pointer == '\'')
+ {
+ if (input_line_pointer[1] != '\'')
+ break;
+ ++input_line_pointer;
+ }
+ generic_bignum[i] <<= 8;
+ generic_bignum[i] += *input_line_pointer;
+ ++input_line_pointer;
+ }
+
+ if (i < SIZE_OF_LARGE_NUMBER - 1)
+ {
+ /* If there is more than one littlenum, left justify the
+ last one to make it match the earlier ones. If there is
+ only one, we can just use the value directly. */
+ for (; j < CHARS_PER_LITTLENUM; j++)
+ generic_bignum[i] <<= 8;
+ }
+
+ if (*input_line_pointer == '\''
+ && input_line_pointer[1] != '\'')
+ break;
+ }
+
+ if (i < 0)
+ {
+ as_bad (_("character constant too large"));
+ i = 0;
+ }
+
+ if (i > 0)
+ {
+ int c;
+ int j;
+
+ c = SIZE_OF_LARGE_NUMBER - i;
+ for (j = 0; j < c; j++)
+ generic_bignum[j] = generic_bignum[i + j];
+ i = c;
+ }
+
+ know (LITTLENUM_NUMBER_OF_BITS == 16);
+ if (i > 2)
+ {
+ expressionP->X_op = O_big;
+ expressionP->X_add_number = i;
+ }
+ else
+ {
+ expressionP->X_op = O_constant;
+ if (i < 2)
+ expressionP->X_add_number = generic_bignum[0] & LITTLENUM_MASK;
+ else
+ expressionP->X_add_number =
+ (((generic_bignum[1] & LITTLENUM_MASK)
+ << LITTLENUM_NUMBER_OF_BITS)
+ | (generic_bignum[0] & LITTLENUM_MASK));
+ }
+
+ /* Skip the final closing quote. */
+ ++input_line_pointer;
+}
+
+/* Return an expression representing the current location. This
+ handles the magic symbol `.'. */
+
+static void
+current_location (expressionS *expressionp)
+{
+ if (now_seg == absolute_section)
+ {
+ expressionp->X_op = O_constant;
+ expressionp->X_add_number = abs_section_offset;
+ }
+ else
+ {
+ expressionp->X_op = O_symbol;
+ expressionp->X_add_symbol = symbol_temp_new_now ();
+ expressionp->X_add_number = 0;
+ }
+}
+
+/* In: Input_line_pointer points to 1st char of operand, which may
+ be a space.
+
+ Out: An expressionS.
+ The operand may have been empty: in this case X_op == O_absent.
+ Input_line_pointer->(next non-blank) char after operand. */
+
+static segT
+operand (expressionS *expressionP)
+{
+ char c;
+ symbolS *symbolP; /* Points to symbol. */
+ char *name; /* Points to name of symbol. */
+ segT segment;
+
+ /* All integers are regarded as unsigned unless they are negated.
+ This is because the only thing which cares whether a number is
+ unsigned is the code in emit_expr which extends constants into
+ bignums. It should only sign extend negative numbers, so that
+ something like ``.quad 0x80000000'' is not sign extended even
+ though it appears negative if valueT is 32 bits. */
+ expressionP->X_unsigned = 1;
+
+ /* Digits, assume it is a bignum. */
+
+ SKIP_WHITESPACE (); /* Leading whitespace is part of operand. */
+ c = *input_line_pointer++; /* input_line_pointer -> past char in c. */
+
+ if (is_end_of_line[(unsigned char) c])
+ goto eol;
+
+ switch (c)
+ {
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ input_line_pointer--;
+
+ integer_constant ((NUMBERS_WITH_SUFFIX || flag_m68k_mri)
+ ? 0 : 10,
+ expressionP);
+ break;
+
+#ifdef LITERAL_PREFIXDOLLAR_HEX
+ case '$':
+ /* $L is the start of a local label, not a hex constant. */
+ if (* input_line_pointer == 'L')
+ goto isname;
+ integer_constant (16, expressionP);
+ break;
+#endif
+
+#ifdef LITERAL_PREFIXPERCENT_BIN
+ case '%':
+ integer_constant (2, expressionP);
+ break;
+#endif
+
+ case '0':
+ /* Non-decimal radix. */
+
+ if (NUMBERS_WITH_SUFFIX || flag_m68k_mri)
+ {
+ char *s;
+
+ /* Check for a hex or float constant. */
+ for (s = input_line_pointer; hex_p (*s); s++)
+ ;
+ if (*s == 'h' || *s == 'H' || *input_line_pointer == '.')
+ {
+ --input_line_pointer;
+ integer_constant (0, expressionP);
+ break;
+ }
+ }
+ c = *input_line_pointer;
+ switch (c)
+ {
+ case 'o':
+ case 'O':
+ case 'q':
+ case 'Q':
+ case '8':
+ case '9':
+ if (NUMBERS_WITH_SUFFIX || flag_m68k_mri)
+ {
+ integer_constant (0, expressionP);
+ break;
+ }
+ /* Fall through. */
+ default:
+ default_case:
+ if (c && strchr (FLT_CHARS, c))
+ {
+ input_line_pointer++;
+ floating_constant (expressionP);
+ expressionP->X_add_number = - TOLOWER (c);
+ }
+ else
+ {
+ /* The string was only zero. */
+ expressionP->X_op = O_constant;
+ expressionP->X_add_number = 0;
+ }
+
+ break;
+
+ case 'x':
+ case 'X':
+ if (flag_m68k_mri)
+ goto default_case;
+ input_line_pointer++;
+ integer_constant (16, expressionP);
+ break;
+
+ case 'b':
+ if (LOCAL_LABELS_FB && ! (flag_m68k_mri || NUMBERS_WITH_SUFFIX))
+ {
+ /* This code used to check for '+' and '-' here, and, in
+ some conditions, fall through to call
+ integer_constant. However, that didn't make sense,
+ as integer_constant only accepts digits. */
+ /* Some of our code elsewhere does permit digits greater
+ than the expected base; for consistency, do the same
+ here. */
+ if (input_line_pointer[1] < '0'
+ || input_line_pointer[1] > '9')
+ {
+ /* Parse this as a back reference to label 0. */
+ input_line_pointer--;
+ integer_constant (10, expressionP);
+ break;
+ }
+ /* Otherwise, parse this as a binary number. */
+ }
+ /* Fall through. */
+ case 'B':
+ input_line_pointer++;
+ if (flag_m68k_mri || NUMBERS_WITH_SUFFIX)
+ goto default_case;
+ integer_constant (2, expressionP);
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ integer_constant ((flag_m68k_mri || NUMBERS_WITH_SUFFIX)
+ ? 0 : 8,
+ expressionP);
+ break;
+
+ case 'f':
+ if (LOCAL_LABELS_FB)
+ {
+ /* If it says "0f" and it could possibly be a floating point
+ number, make it one. Otherwise, make it a local label,
+ and try to deal with parsing the rest later. */
+ if (!input_line_pointer[1]
+ || (is_end_of_line[0xff & input_line_pointer[1]])
+ || strchr (FLT_CHARS, 'f') == NULL)
+ goto is_0f_label;
+ {
+ char *cp = input_line_pointer + 1;
+ int r = atof_generic (&cp, ".", EXP_CHARS,
+ &generic_floating_point_number);
+ switch (r)
+ {
+ case 0:
+ case ERROR_EXPONENT_OVERFLOW:
+ if (*cp == 'f' || *cp == 'b')
+ /* Looks like a difference expression. */
+ goto is_0f_label;
+ else if (cp == input_line_pointer + 1)
+ /* No characters has been accepted -- looks like
+ end of operand. */
+ goto is_0f_label;
+ else
+ goto is_0f_float;
+ default:
+ as_fatal (_("expr.c(operand): bad atof_generic return val %d"),
+ r);
+ }
+ }
+
+ /* Okay, now we've sorted it out. We resume at one of these
+ two labels, depending on what we've decided we're probably
+ looking at. */
+ is_0f_label:
+ input_line_pointer--;
+ integer_constant (10, expressionP);
+ break;
+
+ is_0f_float:
+ /* Fall through. */
+ ;
+ }
+
+ case 'd':
+ case 'D':
+ if (flag_m68k_mri || NUMBERS_WITH_SUFFIX)
+ {
+ integer_constant (0, expressionP);
+ break;
+ }
+ /* Fall through. */
+ case 'F':
+ case 'r':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ input_line_pointer++;
+ floating_constant (expressionP);
+ expressionP->X_add_number = - TOLOWER (c);
+ break;
+
+ case '$':
+ if (LOCAL_LABELS_DOLLAR)
+ {
+ integer_constant (10, expressionP);
+ break;
+ }
+ else
+ goto default_case;
+ }
+
+ break;
+
+ case '(':
+#ifndef NEED_INDEX_OPERATOR
+ case '[':
+#endif
+ /* Didn't begin with digit & not a name. */
+ segment = expression (expressionP);
+ /* expression () will pass trailing whitespace. */
+ if ((c == '(' && *input_line_pointer != ')')
+ || (c == '[' && *input_line_pointer != ']'))
+ {
+#ifdef RELAX_PAREN_GROUPING
+ if (c != '(')
+#endif
+ as_bad (_("missing '%c'"), c == '(' ? ')' : ']');
+ }
+ else
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ /* Here with input_line_pointer -> char after "(...)". */
+ return segment;
+
+#ifdef TC_M68K
+ case 'E':
+ if (! flag_m68k_mri || *input_line_pointer != '\'')
+ goto de_fault;
+ as_bad (_("EBCDIC constants are not supported"));
+ /* Fall through. */
+ case 'A':
+ if (! flag_m68k_mri || *input_line_pointer != '\'')
+ goto de_fault;
+ ++input_line_pointer;
+ /* Fall through. */
+#endif
+ case '\'':
+ if (! flag_m68k_mri)
+ {
+ /* Warning: to conform to other people's assemblers NO
+ ESCAPEMENT is permitted for a single quote. The next
+ character, parity errors and all, is taken as the value
+ of the operand. VERY KINKY. */
+ expressionP->X_op = O_constant;
+ expressionP->X_add_number = *input_line_pointer++;
+ break;
+ }
+
+ mri_char_constant (expressionP);
+ break;
+
+ case '+':
+ /* Do not accept ++e as +(+e).
+ Disabled, since the preprocessor removes whitespace. */
+ if (0 && *input_line_pointer == '+')
+ goto target_op;
+ (void) operand (expressionP);
+ break;
+
+#ifdef TC_M68K
+ case '"':
+ /* Double quote is the bitwise not operator in MRI mode. */
+ if (! flag_m68k_mri)
+ goto de_fault;
+ /* Fall through. */
+#endif
+ case '~':
+ /* '~' is permitted to start a label on the Delta. */
+ if (is_name_beginner (c))
+ goto isname;
+ case '!':
+ case '-':
+ {
+ /* Do not accept --e as -(-e)
+ Disabled, since the preprocessor removes whitespace. */
+ if (0 && c == '-' && *input_line_pointer == '-')
+ goto target_op;
+
+ operand (expressionP);
+ if (expressionP->X_op == O_constant)
+ {
+ /* input_line_pointer -> char after operand. */
+ if (c == '-')
+ {
+ expressionP->X_add_number = - expressionP->X_add_number;
+ /* Notice: '-' may overflow: no warning is given.
+ This is compatible with other people's
+ assemblers. Sigh. */
+ expressionP->X_unsigned = 0;
+ }
+ else if (c == '~' || c == '"')
+ expressionP->X_add_number = ~ expressionP->X_add_number;
+ else
+ expressionP->X_add_number = ! expressionP->X_add_number;
+ }
+ else if (expressionP->X_op == O_big
+ && expressionP->X_add_number <= 0
+ && c == '-'
+ && (generic_floating_point_number.sign == '+'
+ || generic_floating_point_number.sign == 'P'))
+ {
+ /* Negative flonum (eg, -1.000e0). */
+ if (generic_floating_point_number.sign == '+')
+ generic_floating_point_number.sign = '-';
+ else
+ generic_floating_point_number.sign = 'N';
+ }
+ else if (expressionP->X_op != O_illegal
+ && expressionP->X_op != O_absent)
+ {
+ expressionP->X_add_symbol = make_expr_symbol (expressionP);
+ if (c == '-')
+ expressionP->X_op = O_uminus;
+ else if (c == '~' || c == '"')
+ expressionP->X_op = O_bit_not;
+ else
+ expressionP->X_op = O_logical_not;
+ expressionP->X_add_number = 0;
+ }
+ else
+ as_warn (_("Unary operator %c ignored because bad operand follows"),
+ c);
+ }
+ break;
+
+#if defined (DOLLAR_DOT) || defined (TC_M68K)
+ case '$':
+ /* '$' is the program counter when in MRI mode, or when
+ DOLLAR_DOT is defined. */
+#ifndef DOLLAR_DOT
+ if (! flag_m68k_mri)
+ goto de_fault;
+#endif
+ if (flag_m68k_mri && hex_p (*input_line_pointer))
+ {
+ /* In MRI mode, '$' is also used as the prefix for a
+ hexadecimal constant. */
+ integer_constant (16, expressionP);
+ break;
+ }
+
+ if (is_part_of_name (*input_line_pointer))
+ goto isname;
+
+ current_location (expressionP);
+ break;
+#endif
+
+ case '.':
+ if (!is_part_of_name (*input_line_pointer))
+ {
+ current_location (expressionP);
+ break;
+ }
+ else if ((strncasecmp (input_line_pointer, "startof.", 8) == 0
+ && ! is_part_of_name (input_line_pointer[8]))
+ || (strncasecmp (input_line_pointer, "sizeof.", 7) == 0
+ && ! is_part_of_name (input_line_pointer[7])))
+ {
+ int start;
+
+ start = (input_line_pointer[1] == 't'
+ || input_line_pointer[1] == 'T');
+ input_line_pointer += start ? 8 : 7;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '(')
+ as_bad (_("syntax error in .startof. or .sizeof."));
+ else
+ {
+ char *buf;
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ buf = (char *) xmalloc (strlen (name) + 10);
+ if (start)
+ sprintf (buf, ".startof.%s", name);
+ else
+ sprintf (buf, ".sizeof.%s", name);
+ symbolP = symbol_make (buf);
+ free (buf);
+
+ expressionP->X_op = O_symbol;
+ expressionP->X_add_symbol = symbolP;
+ expressionP->X_add_number = 0;
+
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ')')
+ as_bad (_("syntax error in .startof. or .sizeof."));
+ else
+ ++input_line_pointer;
+ }
+ break;
+ }
+ else
+ {
+ goto isname;
+ }
+
+ case ',':
+ eol:
+ /* Can't imagine any other kind of operand. */
+ expressionP->X_op = O_absent;
+ input_line_pointer--;
+ break;
+
+#ifdef TC_M68K
+ case '%':
+ if (! flag_m68k_mri)
+ goto de_fault;
+ integer_constant (2, expressionP);
+ break;
+
+ case '@':
+ if (! flag_m68k_mri)
+ goto de_fault;
+ integer_constant (8, expressionP);
+ break;
+
+ case ':':
+ if (! flag_m68k_mri)
+ goto de_fault;
+
+ /* In MRI mode, this is a floating point constant represented
+ using hexadecimal digits. */
+
+ ++input_line_pointer;
+ integer_constant (16, expressionP);
+ break;
+
+ case '*':
+ if (! flag_m68k_mri || is_part_of_name (*input_line_pointer))
+ goto de_fault;
+
+ current_location (expressionP);
+ break;
+#endif
+
+ default:
+#ifdef TC_M68K
+ de_fault:
+#endif
+ if (is_name_beginner (c)) /* Here if did not begin with a digit. */
+ {
+ /* Identifier begins here.
+ This is kludged for speed, so code is repeated. */
+ isname:
+ name = --input_line_pointer;
+ c = get_symbol_end ();
+
+#ifdef md_parse_name
+ /* This is a hook for the backend to parse certain names
+ specially in certain contexts. If a name always has a
+ specific value, it can often be handled by simply
+ entering it in the symbol table. */
+ if (md_parse_name (name, expressionP, &c))
+ {
+ *input_line_pointer = c;
+ break;
+ }
+#endif
+
+#ifdef TC_I960
+ /* The MRI i960 assembler permits
+ lda sizeof code,g13
+ FIXME: This should use md_parse_name. */
+ if (flag_mri
+ && (strcasecmp (name, "sizeof") == 0
+ || strcasecmp (name, "startof") == 0))
+ {
+ int start;
+ char *buf;
+
+ start = (name[1] == 't'
+ || name[1] == 'T');
+
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ buf = (char *) xmalloc (strlen (name) + 10);
+ if (start)
+ sprintf (buf, ".startof.%s", name);
+ else
+ sprintf (buf, ".sizeof.%s", name);
+ symbolP = symbol_make (buf);
+ free (buf);
+
+ expressionP->X_op = O_symbol;
+ expressionP->X_add_symbol = symbolP;
+ expressionP->X_add_number = 0;
+
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+
+ break;
+ }
+#endif
+
+ symbolP = symbol_find_or_make (name);
+
+ /* If we have an absolute symbol or a reg, then we know its
+ value now. */
+ segment = S_GET_SEGMENT (symbolP);
+ if (segment == absolute_section)
+ {
+ expressionP->X_op = O_constant;
+ expressionP->X_add_number = S_GET_VALUE (symbolP);
+ }
+ else if (segment == reg_section)
+ {
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = S_GET_VALUE (symbolP);
+ }
+ else
+ {
+ expressionP->X_op = O_symbol;
+ expressionP->X_add_symbol = symbolP;
+ expressionP->X_add_number = 0;
+ }
+ *input_line_pointer = c;
+ }
+ else
+ {
+ target_op:
+ /* Let the target try to parse it. Success is indicated by changing
+ the X_op field to something other than O_absent and pointing
+ input_line_pointer past the expression. If it can't parse the
+ expression, X_op and input_line_pointer should be unchanged. */
+ expressionP->X_op = O_absent;
+ --input_line_pointer;
+ md_operand (expressionP);
+ if (expressionP->X_op == O_absent)
+ {
+ ++input_line_pointer;
+ as_bad (_("bad expression"));
+ expressionP->X_op = O_constant;
+ expressionP->X_add_number = 0;
+ }
+ }
+ break;
+ }
+
+ /* It is more 'efficient' to clean up the expressionS when they are
+ created. Doing it here saves lines of code. */
+ clean_up_expression (expressionP);
+ SKIP_WHITESPACE (); /* -> 1st char after operand. */
+ know (*input_line_pointer != ' ');
+
+ /* The PA port needs this information. */
+ if (expressionP->X_add_symbol)
+ symbol_mark_used (expressionP->X_add_symbol);
+
+ switch (expressionP->X_op)
+ {
+ default:
+ return absolute_section;
+ case O_symbol:
+ return S_GET_SEGMENT (expressionP->X_add_symbol);
+ case O_register:
+ return reg_section;
+ }
+}
+
+/* Internal. Simplify a struct expression for use by expr (). */
+
+/* In: address of an expressionS.
+ The X_op field of the expressionS may only take certain values.
+ Elsewise we waste time special-case testing. Sigh. Ditto SEG_ABSENT.
+
+ Out: expressionS may have been modified:
+ Unused fields zeroed to help expr (). */
+
+static void
+clean_up_expression (expressionS *expressionP)
+{
+ switch (expressionP->X_op)
+ {
+ case O_illegal:
+ case O_absent:
+ expressionP->X_add_number = 0;
+ /* Fall through. */
+ case O_big:
+ case O_constant:
+ case O_register:
+ expressionP->X_add_symbol = NULL;
+ /* Fall through. */
+ case O_symbol:
+ case O_uminus:
+ case O_bit_not:
+ expressionP->X_op_symbol = NULL;
+ break;
+ default:
+ break;
+ }
+}
+
+/* Expression parser. */
+
+/* We allow an empty expression, and just assume (absolute,0) silently.
+ Unary operators and parenthetical expressions are treated as operands.
+ As usual, Q==quantity==operand, O==operator, X==expression mnemonics.
+
+ We used to do an aho/ullman shift-reduce parser, but the logic got so
+ warped that I flushed it and wrote a recursive-descent parser instead.
+ Now things are stable, would anybody like to write a fast parser?
+ Most expressions are either register (which does not even reach here)
+ or 1 symbol. Then "symbol+constant" and "symbol-symbol" are common.
+ So I guess it doesn't really matter how inefficient more complex expressions
+ are parsed.
+
+ After expr(RANK,resultP) input_line_pointer->operator of rank <= RANK.
+ Also, we have consumed any leading or trailing spaces (operand does that)
+ and done all intervening operators.
+
+ This returns the segment of the result, which will be
+ absolute_section or the segment of a symbol. */
+
+#undef __
+#define __ O_illegal
+
+/* Maps ASCII -> operators. */
+static const operatorT op_encoding[256] = {
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+
+ __, O_bit_or_not, __, __, __, O_modulus, O_bit_and, __,
+ __, __, O_multiply, O_add, __, O_subtract, __, O_divide,
+ __, __, __, __, __, __, __, __,
+ __, __, __, __, O_lt, __, O_gt, __,
+ __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __,
+ __, __, __,
+#ifdef NEED_INDEX_OPERATOR
+ O_index,
+#else
+ __,
+#endif
+ __, __, O_bit_exclusive_or, __,
+ __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __,
+ __, __, __, __, O_bit_inclusive_or, __, __, __,
+
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __
+};
+
+/* Rank Examples
+ 0 operand, (expression)
+ 1 ||
+ 2 &&
+ 3 == <> < <= >= >
+ 4 + -
+ 5 used for * / % in MRI mode
+ 6 & ^ ! |
+ 7 * / % << >>
+ 8 unary - unary ~
+*/
+static operator_rankT op_rank[] = {
+ 0, /* O_illegal */
+ 0, /* O_absent */
+ 0, /* O_constant */
+ 0, /* O_symbol */
+ 0, /* O_symbol_rva */
+ 0, /* O_register */
+ 0, /* O_big */
+ 9, /* O_uminus */
+ 9, /* O_bit_not */
+ 9, /* O_logical_not */
+ 8, /* O_multiply */
+ 8, /* O_divide */
+ 8, /* O_modulus */
+ 8, /* O_left_shift */
+ 8, /* O_right_shift */
+ 7, /* O_bit_inclusive_or */
+ 7, /* O_bit_or_not */
+ 7, /* O_bit_exclusive_or */
+ 7, /* O_bit_and */
+ 5, /* O_add */
+ 5, /* O_subtract */
+ 4, /* O_eq */
+ 4, /* O_ne */
+ 4, /* O_lt */
+ 4, /* O_le */
+ 4, /* O_ge */
+ 4, /* O_gt */
+ 3, /* O_logical_and */
+ 2, /* O_logical_or */
+ 1, /* O_index */
+ 0, /* O_md1 */
+ 0, /* O_md2 */
+ 0, /* O_md3 */
+ 0, /* O_md4 */
+ 0, /* O_md5 */
+ 0, /* O_md6 */
+ 0, /* O_md7 */
+ 0, /* O_md8 */
+ 0, /* O_md9 */
+ 0, /* O_md10 */
+ 0, /* O_md11 */
+ 0, /* O_md12 */
+ 0, /* O_md13 */
+ 0, /* O_md14 */
+ 0, /* O_md15 */
+ 0, /* O_md16 */
+};
+
+/* Unfortunately, in MRI mode for the m68k, multiplication and
+ division have lower precedence than the bit wise operators. This
+ function sets the operator precedences correctly for the current
+ mode. Also, MRI uses a different bit_not operator, and this fixes
+ that as well. */
+
+#define STANDARD_MUL_PRECEDENCE 8
+#define MRI_MUL_PRECEDENCE 6
+
+void
+expr_set_precedence (void)
+{
+ if (flag_m68k_mri)
+ {
+ op_rank[O_multiply] = MRI_MUL_PRECEDENCE;
+ op_rank[O_divide] = MRI_MUL_PRECEDENCE;
+ op_rank[O_modulus] = MRI_MUL_PRECEDENCE;
+ }
+ else
+ {
+ op_rank[O_multiply] = STANDARD_MUL_PRECEDENCE;
+ op_rank[O_divide] = STANDARD_MUL_PRECEDENCE;
+ op_rank[O_modulus] = STANDARD_MUL_PRECEDENCE;
+ }
+}
+
+/* Initialize the expression parser. */
+
+void
+expr_begin (void)
+{
+ expr_set_precedence ();
+
+ /* Verify that X_op field is wide enough. */
+ {
+ expressionS e;
+ e.X_op = O_max;
+ assert (e.X_op == O_max);
+ }
+}
+
+/* Return the encoding for the operator at INPUT_LINE_POINTER, and
+ sets NUM_CHARS to the number of characters in the operator.
+ Does not advance INPUT_LINE_POINTER. */
+
+static inline operatorT
+operator (int *num_chars)
+{
+ int c;
+ operatorT ret;
+
+ c = *input_line_pointer & 0xff;
+ *num_chars = 1;
+
+ if (is_end_of_line[c])
+ return O_illegal;
+
+ switch (c)
+ {
+ default:
+ return op_encoding[c];
+
+ case '+':
+ case '-':
+ /* Do not allow a++b and a--b to be a + (+b) and a - (-b)
+ Disabled, since the preprocessor removes whitespace. */
+ if (1 || input_line_pointer[1] != c)
+ return op_encoding[c];
+ return O_illegal;
+
+ case '<':
+ switch (input_line_pointer[1])
+ {
+ default:
+ return op_encoding[c];
+ case '<':
+ ret = O_left_shift;
+ break;
+ case '>':
+ ret = O_ne;
+ break;
+ case '=':
+ ret = O_le;
+ break;
+ }
+ *num_chars = 2;
+ return ret;
+
+ case '=':
+ if (input_line_pointer[1] != '=')
+ return op_encoding[c];
+
+ *num_chars = 2;
+ return O_eq;
+
+ case '>':
+ switch (input_line_pointer[1])
+ {
+ default:
+ return op_encoding[c];
+ case '>':
+ ret = O_right_shift;
+ break;
+ case '=':
+ ret = O_ge;
+ break;
+ }
+ *num_chars = 2;
+ return ret;
+
+ case '!':
+ /* We accept !! as equivalent to ^ for MRI compatibility. */
+ if (input_line_pointer[1] != '!')
+ {
+ if (flag_m68k_mri)
+ return O_bit_inclusive_or;
+ return op_encoding[c];
+ }
+ *num_chars = 2;
+ return O_bit_exclusive_or;
+
+ case '|':
+ if (input_line_pointer[1] != '|')
+ return op_encoding[c];
+
+ *num_chars = 2;
+ return O_logical_or;
+
+ case '&':
+ if (input_line_pointer[1] != '&')
+ return op_encoding[c];
+
+ *num_chars = 2;
+ return O_logical_and;
+ }
+
+ /* NOTREACHED */
+}
+
+/* Parse an expression. */
+
+segT
+expr (int rankarg, /* Larger # is higher rank. */
+ expressionS *resultP /* Deliver result here. */)
+{
+ operator_rankT rank = (operator_rankT) rankarg;
+ segT retval;
+ expressionS right;
+ operatorT op_left;
+ operatorT op_right;
+ int op_chars;
+
+ know (rank >= 0);
+
+ /* Save the value of dot for the fixup code. */
+ if (rank == 0)
+ dot_value = frag_now_fix ();
+
+ retval = operand (resultP);
+
+ /* operand () gobbles spaces. */
+ know (*input_line_pointer != ' ');
+
+ op_left = operator (&op_chars);
+ while (op_left != O_illegal && op_rank[(int) op_left] > rank)
+ {
+ segT rightseg;
+
+ input_line_pointer += op_chars; /* -> after operator. */
+
+ rightseg = expr (op_rank[(int) op_left], &right);
+ if (right.X_op == O_absent)
+ {
+ as_warn (_("missing operand; zero assumed"));
+ right.X_op = O_constant;
+ right.X_add_number = 0;
+ right.X_add_symbol = NULL;
+ right.X_op_symbol = NULL;
+ }
+
+ know (*input_line_pointer != ' ');
+
+ if (op_left == O_index)
+ {
+ if (*input_line_pointer != ']')
+ as_bad ("missing right bracket");
+ else
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ }
+ }
+
+ op_right = operator (&op_chars);
+
+ know (op_right == O_illegal
+ || op_rank[(int) op_right] <= op_rank[(int) op_left]);
+ know ((int) op_left >= (int) O_multiply
+ && (int) op_left <= (int) O_logical_or);
+
+ /* input_line_pointer->after right-hand quantity. */
+ /* left-hand quantity in resultP. */
+ /* right-hand quantity in right. */
+ /* operator in op_left. */
+
+ if (resultP->X_op == O_big)
+ {
+ if (resultP->X_add_number > 0)
+ as_warn (_("left operand is a bignum; integer 0 assumed"));
+ else
+ as_warn (_("left operand is a float; integer 0 assumed"));
+ resultP->X_op = O_constant;
+ resultP->X_add_number = 0;
+ resultP->X_add_symbol = NULL;
+ resultP->X_op_symbol = NULL;
+ }
+ if (right.X_op == O_big)
+ {
+ if (right.X_add_number > 0)
+ as_warn (_("right operand is a bignum; integer 0 assumed"));
+ else
+ as_warn (_("right operand is a float; integer 0 assumed"));
+ right.X_op = O_constant;
+ right.X_add_number = 0;
+ right.X_add_symbol = NULL;
+ right.X_op_symbol = NULL;
+ }
+
+ /* Optimize common cases. */
+#ifdef md_optimize_expr
+ if (md_optimize_expr (resultP, op_left, &right))
+ {
+ /* Skip. */
+ ;
+ }
+ else
+#endif
+ if (op_left == O_add && right.X_op == O_constant)
+ {
+ /* X + constant. */
+ resultP->X_add_number += right.X_add_number;
+ }
+ /* This case comes up in PIC code. */
+ else if (op_left == O_subtract
+ && right.X_op == O_symbol
+ && resultP->X_op == O_symbol
+ && (symbol_get_frag (right.X_add_symbol)
+ == symbol_get_frag (resultP->X_add_symbol))
+ && (SEG_NORMAL (rightseg)
+ || right.X_add_symbol == resultP->X_add_symbol))
+ {
+ resultP->X_add_number -= right.X_add_number;
+ resultP->X_add_number += (S_GET_VALUE (resultP->X_add_symbol)
+ - S_GET_VALUE (right.X_add_symbol));
+ resultP->X_op = O_constant;
+ resultP->X_add_symbol = 0;
+ }
+ else if (op_left == O_subtract && right.X_op == O_constant)
+ {
+ /* X - constant. */
+ resultP->X_add_number -= right.X_add_number;
+ }
+ else if (op_left == O_add && resultP->X_op == O_constant)
+ {
+ /* Constant + X. */
+ resultP->X_op = right.X_op;
+ resultP->X_add_symbol = right.X_add_symbol;
+ resultP->X_op_symbol = right.X_op_symbol;
+ resultP->X_add_number += right.X_add_number;
+ retval = rightseg;
+ }
+ else if (resultP->X_op == O_constant && right.X_op == O_constant)
+ {
+ /* Constant OP constant. */
+ offsetT v = right.X_add_number;
+ if (v == 0 && (op_left == O_divide || op_left == O_modulus))
+ {
+ as_warn (_("division by zero"));
+ v = 1;
+ }
+ switch (op_left)
+ {
+ default: abort ();
+ case O_multiply: resultP->X_add_number *= v; break;
+ case O_divide: resultP->X_add_number /= v; break;
+ case O_modulus: resultP->X_add_number %= v; break;
+ case O_left_shift: resultP->X_add_number <<= v; break;
+ case O_right_shift:
+ /* We always use unsigned shifts, to avoid relying on
+ characteristics of the compiler used to compile gas. */
+ resultP->X_add_number =
+ (offsetT) ((valueT) resultP->X_add_number >> (valueT) v);
+ break;
+ case O_bit_inclusive_or: resultP->X_add_number |= v; break;
+ case O_bit_or_not: resultP->X_add_number |= ~v; break;
+ case O_bit_exclusive_or: resultP->X_add_number ^= v; break;
+ case O_bit_and: resultP->X_add_number &= v; break;
+ case O_add: resultP->X_add_number += v; break;
+ case O_subtract: resultP->X_add_number -= v; break;
+ case O_eq:
+ resultP->X_add_number =
+ resultP->X_add_number == v ? ~ (offsetT) 0 : 0;
+ break;
+ case O_ne:
+ resultP->X_add_number =
+ resultP->X_add_number != v ? ~ (offsetT) 0 : 0;
+ break;
+ case O_lt:
+ resultP->X_add_number =
+ resultP->X_add_number < v ? ~ (offsetT) 0 : 0;
+ break;
+ case O_le:
+ resultP->X_add_number =
+ resultP->X_add_number <= v ? ~ (offsetT) 0 : 0;
+ break;
+ case O_ge:
+ resultP->X_add_number =
+ resultP->X_add_number >= v ? ~ (offsetT) 0 : 0;
+ break;
+ case O_gt:
+ resultP->X_add_number =
+ resultP->X_add_number > v ? ~ (offsetT) 0 : 0;
+ break;
+ case O_logical_and:
+ resultP->X_add_number = resultP->X_add_number && v;
+ break;
+ case O_logical_or:
+ resultP->X_add_number = resultP->X_add_number || v;
+ break;
+ }
+ }
+ else if (resultP->X_op == O_symbol
+ && right.X_op == O_symbol
+ && (op_left == O_add
+ || op_left == O_subtract
+ || (resultP->X_add_number == 0
+ && right.X_add_number == 0)))
+ {
+ /* Symbol OP symbol. */
+ resultP->X_op = op_left;
+ resultP->X_op_symbol = right.X_add_symbol;
+ if (op_left == O_add)
+ resultP->X_add_number += right.X_add_number;
+ else if (op_left == O_subtract)
+ {
+ resultP->X_add_number -= right.X_add_number;
+ if (retval == rightseg && SEG_NORMAL (retval))
+ {
+ retval = absolute_section;
+ rightseg = absolute_section;
+ }
+ }
+ }
+ else
+ {
+ /* The general case. */
+ resultP->X_add_symbol = make_expr_symbol (resultP);
+ resultP->X_op_symbol = make_expr_symbol (&right);
+ resultP->X_op = op_left;
+ resultP->X_add_number = 0;
+ resultP->X_unsigned = 1;
+ }
+
+ if (retval != rightseg)
+ {
+ if (! SEG_NORMAL (retval))
+ {
+ if (retval != undefined_section || SEG_NORMAL (rightseg))
+ retval = rightseg;
+ }
+ else if (SEG_NORMAL (rightseg)
+#ifdef DIFF_EXPR_OK
+ && op_left != O_subtract
+#endif
+ )
+ as_bad (_("operation combines symbols in different segments"));
+ }
+
+ op_left = op_right;
+ } /* While next operator is >= this rank. */
+
+ /* The PA port needs this information. */
+ if (resultP->X_add_symbol)
+ symbol_mark_used (resultP->X_add_symbol);
+
+ return resultP->X_op == O_constant ? absolute_section : retval;
+}
+
+/* This lives here because it belongs equally in expr.c & read.c.
+ expr.c is just a branch office read.c anyway, and putting it
+ here lessens the crowd at read.c.
+
+ Assume input_line_pointer is at start of symbol name.
+ Advance input_line_pointer past symbol name.
+ Turn that character into a '\0', returning its former value.
+ This allows a string compare (RMS wants symbol names to be strings)
+ of the symbol name.
+ There will always be a char following symbol name, because all good
+ lines end in end-of-line. */
+
+char
+get_symbol_end (void)
+{
+ char c;
+
+ /* We accept \001 in a name in case this is being called with a
+ constructed string. */
+ if (is_name_beginner (c = *input_line_pointer++) || c == '\001')
+ {
+ while (is_part_of_name (c = *input_line_pointer++)
+ || c == '\001')
+ ;
+ if (is_name_ender (c))
+ c = *input_line_pointer++;
+ }
+ *--input_line_pointer = 0;
+ return (c);
+}
+
+unsigned int
+get_single_number (void)
+{
+ expressionS exp;
+ operand (&exp);
+ return exp.X_add_number;
+}
diff --git a/x/binutils/gas/expr.h b/x/binutils/gas/expr.h
new file mode 100644
index 0000000..382dda9
--- /dev/null
+++ b/x/binutils/gas/expr.h
@@ -0,0 +1,171 @@
+/* expr.h -> header file for expr.c
+ Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ * By popular demand, we define a struct to represent an expression.
+ * This will no doubt mutate as expressions become baroque.
+ *
+ * Currently, we support expressions like "foo OP bar + 42". In other
+ * words we permit a (possibly undefined) symbol, a (possibly
+ * undefined) symbol and the operation used to combine the symbols,
+ * and an (absolute) augend. RMS says this is so we can have 1-pass
+ * assembly for any compiler emissions, and a 'case' statement might
+ * emit 'undefined1 - undefined2'.
+ *
+ * The type of an expression used to be stored as a segment. That got
+ * confusing because it overloaded the concept of a segment. I added
+ * an operator field, instead.
+ */
+
+/* This is the type of an expression. The operator types are also
+ used while parsing an expression.
+
+ NOTE: This enumeration must match the op_rank array in expr.c. */
+
+typedef enum {
+ /* An illegal expression. */
+ O_illegal,
+ /* A nonexistent expression. */
+ O_absent,
+ /* X_add_number (a constant expression). */
+ O_constant,
+ /* X_add_symbol + X_add_number. */
+ O_symbol,
+ /* X_add_symbol + X_add_number - the base address of the image. */
+ O_symbol_rva,
+ /* A register (X_add_number is register number). */
+ O_register,
+ /* A big value. If X_add_number is negative or 0, the value is in
+ generic_floating_point_number. Otherwise the value is in
+ generic_bignum, and X_add_number is the number of LITTLENUMs in
+ the value. */
+ O_big,
+ /* (- X_add_symbol) + X_add_number. */
+ O_uminus,
+ /* (~ X_add_symbol) + X_add_number. */
+ O_bit_not,
+ /* (! X_add_symbol) + X_add_number. */
+ O_logical_not,
+ /* (X_add_symbol * X_op_symbol) + X_add_number. */
+ O_multiply,
+ /* (X_add_symbol / X_op_symbol) + X_add_number. */
+ O_divide,
+ /* (X_add_symbol % X_op_symbol) + X_add_number. */
+ O_modulus,
+ /* (X_add_symbol << X_op_symbol) + X_add_number. */
+ O_left_shift,
+ /* (X_add_symbol >> X_op_symbol) + X_add_number. */
+ O_right_shift,
+ /* (X_add_symbol | X_op_symbol) + X_add_number. */
+ O_bit_inclusive_or,
+ /* (X_add_symbol |~ X_op_symbol) + X_add_number. */
+ O_bit_or_not,
+ /* (X_add_symbol ^ X_op_symbol) + X_add_number. */
+ O_bit_exclusive_or,
+ /* (X_add_symbol & X_op_symbol) + X_add_number. */
+ O_bit_and,
+ /* (X_add_symbol + X_op_symbol) + X_add_number. */
+ O_add,
+ /* (X_add_symbol - X_op_symbol) + X_add_number. */
+ O_subtract,
+ /* (X_add_symbol == X_op_symbol) + X_add_number. */
+ O_eq,
+ /* (X_add_symbol != X_op_symbol) + X_add_number. */
+ O_ne,
+ /* (X_add_symbol < X_op_symbol) + X_add_number. */
+ O_lt,
+ /* (X_add_symbol <= X_op_symbol) + X_add_number. */
+ O_le,
+ /* (X_add_symbol >= X_op_symbol) + X_add_number. */
+ O_ge,
+ /* (X_add_symbol > X_op_symbol) + X_add_number. */
+ O_gt,
+ /* (X_add_symbol && X_op_symbol) + X_add_number. */
+ O_logical_and,
+ /* (X_add_symbol || X_op_symbol) + X_add_number. */
+ O_logical_or,
+ /* X_op_symbol [ X_add_symbol ] */
+ O_index,
+ /* machine dependent operators */
+ O_md1, O_md2, O_md3, O_md4, O_md5, O_md6, O_md7, O_md8,
+ O_md9, O_md10, O_md11, O_md12, O_md13, O_md14, O_md15, O_md16,
+ O_md17, O_md18, O_md19, O_md20, O_md21, O_md22, O_md23, O_md24,
+ O_md25, O_md26, O_md27, O_md28, O_md29, O_md30, O_md31, O_md32,
+ /* this must be the largest value */
+ O_max
+} operatorT;
+
+typedef struct expressionS {
+ /* The main symbol. */
+ symbolS *X_add_symbol;
+ /* The second symbol, if needed. */
+ symbolS *X_op_symbol;
+ /* A number to add. */
+ offsetT X_add_number;
+
+ /* The type of the expression. We can't assume that an arbitrary
+ compiler can handle a bitfield of enum type. FIXME: We could
+ check this using autoconf. */
+#ifdef __GNUC__
+ operatorT X_op : 8;
+#else
+ unsigned char X_op;
+#endif
+
+ /* Non-zero if X_add_number should be regarded as unsigned. This is
+ only valid for O_constant expressions. It is only used when an
+ O_constant must be extended into a bignum (i.e., it is not used
+ when performing arithmetic on these values).
+ FIXME: This field is not set very reliably. */
+ unsigned int X_unsigned : 1;
+
+ /* 7 additional bits can be defined if needed. */
+
+ /* Machine dependent field */
+ unsigned short X_md;
+} expressionS;
+
+/* "result" should be type (expressionS *). */
+#define expression(result) expr (0, result)
+
+/* If an expression is O_big, look here for its value. These common
+ data may be clobbered whenever expr() is called. */
+/* Flonums returned here. Big enough to hold most precise flonum. */
+extern FLONUM_TYPE generic_floating_point_number;
+/* Bignums returned here. */
+extern LITTLENUM_TYPE generic_bignum[];
+/* Number of littlenums in above. */
+#define SIZE_OF_LARGE_NUMBER (20)
+
+typedef char operator_rankT;
+
+extern char get_symbol_end (void);
+extern void expr_begin (void);
+extern void expr_set_precedence (void);
+extern segT expr (int rank, expressionS * resultP);
+extern unsigned int get_single_number (void);
+extern symbolS *make_expr_symbol (expressionS * expressionP);
+extern int expr_symbol_where (symbolS *, char **, unsigned int *);
+
+extern symbolS *expr_build_uconstant (offsetT);
+extern symbolS *expr_build_unary (operatorT, symbolS *);
+extern symbolS *expr_build_binary (operatorT, symbolS *, symbolS *);
+extern symbolS *expr_build_dot (void);
diff --git a/x/binutils/gas/flonum-copy.c b/x/binutils/gas/flonum-copy.c
new file mode 100644
index 0000000..e3aba2c
--- /dev/null
+++ b/x/binutils/gas/flonum-copy.c
@@ -0,0 +1,71 @@
+/* flonum_copy.c - copy a flonum
+ Copyright 1987, 1990, 1991, 1992, 1993, 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+
+void
+flonum_copy (FLONUM_TYPE *in, FLONUM_TYPE *out)
+{
+ unsigned int in_length; /* 0 origin */
+ unsigned int out_length; /* 0 origin */
+
+ out->sign = in->sign;
+ in_length = in->leader - in->low;
+
+ if (in->leader < in->low)
+ {
+ out->leader = out->low - 1; /* 0.0 case */
+ }
+ else
+ {
+ out_length = out->high - out->low;
+ /* Assume no GAPS in packing of littlenums.
+ I.e. sizeof(array) == sizeof(element) * number_of_elements. */
+ if (in_length <= out_length)
+ {
+ {
+ /* For defensive programming, zero any high-order
+ littlenums we don't need. This is destroying evidence
+ and wasting time, so why bother??? */
+ if (in_length < out_length)
+ {
+ memset ((char *) (out->low + in_length + 1), '\0',
+ out_length - in_length);
+ }
+ }
+ memcpy ((void *) (out->low), (void *) (in->low),
+ ((in_length + 1) * sizeof (LITTLENUM_TYPE)));
+ out->exponent = in->exponent;
+ out->leader = in->leader - in->low + out->low;
+ }
+ else
+ {
+ int shorten; /* 1-origin. Number of littlenums we drop. */
+
+ shorten = in_length - out_length;
+ /* Assume out_length >= 0 ! */
+ memcpy ((void *) (out->low), (void *) (in->low + shorten),
+ ((out_length + 1) * sizeof (LITTLENUM_TYPE)));
+ out->leader = out->high;
+ out->exponent = in->exponent + shorten;
+ }
+ } /* if any significant bits */
+}
diff --git a/x/binutils/gas/flonum-konst.c b/x/binutils/gas/flonum-konst.c
new file mode 100644
index 0000000..3e606fb
--- /dev/null
+++ b/x/binutils/gas/flonum-konst.c
@@ -0,0 +1,228 @@
+/* flonum_const.c - Useful Flonum constants
+ Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 2000, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "ansidecl.h"
+#include "flonum.h"
+/* JF: I added the last entry to this table, and I'm not
+ sure if its right or not. Could go either way. I wish
+ I really understood this stuff. */
+
+const int table_size_of_flonum_powers_of_ten = 13;
+
+static const LITTLENUM_TYPE zero[] = {
+ 1
+};
+
+/***********************************************************************\
+ * *
+ * Warning: the low order bits may be WRONG here. *
+ * I took this from a suspect bc(1) script. *
+ * "minus_X"[] is supposed to be 10^(2^-X) expressed in base 2^16. *
+ * The radix point is just AFTER the highest element of the [] *
+ * *
+ * Because bc rounds DOWN for printing (I think), the lowest *
+ * significance littlenums should probably have 1 added to them. *
+ * *
+ \***********************************************************************/
+
+/* JF: If this equals 6553/(2^16)+39321/(2^32)+... it approaches .1 */
+static const LITTLENUM_TYPE minus_1[] = {
+ 39322, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321,
+ 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 6553
+};
+
+static const LITTLENUM_TYPE plus_1[] = {
+ 10
+};
+
+/* JF: If this equals 655/(2^16) + 23592/(2^32) + ... it approaches .01 */
+static const LITTLENUM_TYPE minus_2[] = {
+ 10486, 36700, 62914, 23592, 49807, 10485, 36700, 62914, 23592, 49807,
+ 10485, 36700, 62914, 23592, 49807, 10485, 36700, 62914, 23592, 655
+};
+
+static const LITTLENUM_TYPE plus_2[] = {
+ 100
+};
+
+/* This approaches .0001 */
+static const LITTLENUM_TYPE minus_3[] = {
+ 52534, 20027, 37329, 65116, 64067, 60397, 14784, 18979, 33659, 19503,
+ 2726, 9542, 629, 2202, 40475, 10590, 4299, 47815, 36280, 6
+};
+
+static const LITTLENUM_TYPE plus_3[] = {
+ 10000
+};
+
+/* JF: this approaches 1e-8 */
+static const LITTLENUM_TYPE minus_4[] = {
+ 22517, 49501, 54293, 19424, 60699, 6716, 24348, 22618, 23904, 21327,
+ 3919, 44703, 19149, 28803, 48959, 6259, 50273, 62237, 42
+};
+
+/* This equals 1525 * 2^16 + 57600 */
+static const LITTLENUM_TYPE plus_4[] = {
+ 57600, 1525
+};
+
+/* This approaches 1e-16 */
+static const LITTLENUM_TYPE minus_5[] = {
+ 22199, 45957, 17005, 26266, 10526, 16260, 55017, 35680, 40443, 19789,
+ 17356, 30195, 55905, 28426, 63010, 44197, 1844
+};
+
+static const LITTLENUM_TYPE plus_5[] = {
+ 28609, 34546, 35
+};
+
+static const LITTLENUM_TYPE minus_6[] = {
+ 30926, 26518, 13110, 43018, 54982, 48258, 24658, 15209, 63366, 11929,
+ 20069, 43857, 60487, 51
+};
+
+static const LITTLENUM_TYPE plus_6[] = {
+ 61313, 34220, 16731, 11629, 1262
+};
+
+static const LITTLENUM_TYPE minus_7[] = {
+ 29819, 14733, 21490, 40602, 31315, 65186, 2695
+};
+
+static const LITTLENUM_TYPE plus_7[] = {
+ 7937, 49002, 60772, 28216, 38893, 55975, 63988, 59711, 20227, 24
+};
+
+static const LITTLENUM_TYPE minus_8[] = {
+ 27579, 64807, 12543, 794, 13907, 61297, 12013, 64360, 15961, 20566,
+ 24178, 15922, 59427, 110
+};
+
+static const LITTLENUM_TYPE plus_8[] = {
+ 15873, 11925, 39177, 991, 14589, 3861, 58415, 9076, 62956, 54223,
+ 56328, 50180, 45274, 48333, 32537, 42547, 9731, 59679, 590
+};
+
+static const LITTLENUM_TYPE minus_9[] = {
+ 11042, 8464, 58971, 63429, 6022, 63485, 5500, 53464, 47545, 50068,
+ 56988, 22819, 49708, 54493, 9920, 47667, 40409, 35764, 10383, 54466,
+ 32702, 17493, 32420, 34382, 22750, 20681, 12300
+};
+
+static const LITTLENUM_TYPE plus_9[] = {
+ 20678, 27614, 28272, 53066, 55311, 54677, 29038, 9906, 26288, 44486,
+ 13860, 7445, 54106, 15426, 21518, 25599, 29632, 52309, 61207, 26105,
+ 10482, 21948, 51191, 32988, 60892, 62574, 61390, 24540, 21495, 5
+};
+
+static const LITTLENUM_TYPE minus_10[] = {
+ 6214, 48771, 23471, 30163, 31763, 38013, 57001, 11770, 18263, 36366,
+ 20742, 45086, 56969, 53231, 37856, 55814, 38057, 15692, 46761, 8713,
+ 6102, 20083, 8269, 11839, 11571, 50963, 15649, 11698, 40675, 2308
+};
+
+static const LITTLENUM_TYPE plus_10[] = {
+ 63839, 36576, 45712, 44516, 37803, 29482, 4966, 30556, 37961, 23310,
+ 27070, 44972, 29507, 48257, 45209, 7494, 17831, 38728, 41577, 29443,
+ 36016, 7955, 35339, 35479, 36011, 14553, 49618, 5588, 25396, 28
+};
+
+static const LITTLENUM_TYPE minus_11[] = {
+ 16663, 56882, 61983, 7804, 36555, 32060, 34502, 1000, 14356, 21681,
+ 6605, 34767, 51411, 59048, 53614, 39850, 30079, 6496, 6846, 26841,
+ 40778, 19578, 59899, 44085, 54016, 24259, 11232, 21229, 21313, 81
+};
+
+static const LITTLENUM_TYPE plus_11[] = {
+ 92, 9054, 62707, 17993, 7821, 56838, 13992, 21321, 29637, 48426,
+ 42982, 38668, 49574, 28820, 18200, 18927, 53979, 16219, 37484, 2516,
+ 44642, 14665, 11587, 41926, 13556, 23956, 54320, 6661, 55766, 805
+};
+
+static const LITTLENUM_TYPE minus_12[] = {
+ 33202, 45969, 58804, 56734, 16482, 26007, 44984, 49334, 31007, 32944,
+ 44517, 63329, 47131, 15291, 59465, 2264, 23218, 11829, 59771, 38798,
+ 31051, 28748, 23129, 40541, 41562, 35108, 50620, 59014, 51817, 6613
+};
+
+static const LITTLENUM_TYPE plus_12[] = {
+ 10098, 37922, 58070, 7432, 10470, 63465, 23718, 62190, 47420, 7009,
+ 38443, 4587, 45596, 38472, 52129, 52779, 29012, 13559, 48688, 31678,
+ 41753, 58662, 10668, 36067, 29906, 56906, 21461, 46556, 59571, 9
+};
+
+static const LITTLENUM_TYPE minus_13[] = {
+ 45309, 27592, 37144, 34637, 34328, 41671, 34620, 24135, 53401, 22112,
+ 21576, 45147, 39310, 44051, 48572, 3676, 46544, 59768, 33350, 2323,
+ 49524, 61568, 3903, 36487, 36356, 30903, 14975, 9035, 29715, 667
+};
+
+static const LITTLENUM_TYPE plus_13[] = {
+ 18788, 16960, 6318, 45685, 55400, 46230, 35794, 25588, 7253, 55541,
+ 49716, 59760, 63592, 8191, 63765, 58530, 44667, 13294, 10001, 55586,
+ 47887, 18738, 9509, 40896, 42506, 52580, 4171, 325, 12329, 98
+};
+
+/* Shut up complaints about differing pointer types. They only differ
+ in the const attribute, but there isn't any easy way to do this
+ */
+#define X (LITTLENUM_TYPE *)
+
+const FLONUM_TYPE flonum_negative_powers_of_ten[] = {
+ {X zero, X zero, X zero, 0, '+'},
+ {X minus_1, X minus_1 + 19, X minus_1 + 19, -20, '+'},
+ {X minus_2, X minus_2 + 19, X minus_2 + 19, -20, '+'},
+ {X minus_3, X minus_3 + 19, X minus_3 + 19, -20, '+'},
+ {X minus_4, X minus_4 + 18, X minus_4 + 18, -20, '+'},
+ {X minus_5, X minus_5 + 16, X minus_5 + 16, -20, '+'},
+ {X minus_6, X minus_6 + 13, X minus_6 + 13, -20, '+'},
+ {X minus_7, X minus_7 + 6, X minus_7 + 6, -20, '+'},
+ {X minus_8, X minus_8 + 13, X minus_8 + 13, -40, '+'},
+ {X minus_9, X minus_9 + 26, X minus_9 + 26, -80, '+'},
+ {X minus_10, X minus_10 + 29, X minus_10 + 29, -136, '+'},
+ {X minus_11, X minus_11 + 29, X minus_11 + 29, -242, '+'},
+ {X minus_12, X minus_12 + 29, X minus_12 + 29, -455, '+'},
+ {X minus_13, X minus_13 + 29, X minus_13 + 29, -880, '+'},
+};
+
+const FLONUM_TYPE flonum_positive_powers_of_ten[] = {
+ {X zero, X zero, X zero, 0, '+'},
+ {X plus_1, X plus_1 + 0, X plus_1 + 0, 0, '+'},
+ {X plus_2, X plus_2 + 0, X plus_2 + 0, 0, '+'},
+ {X plus_3, X plus_3 + 0, X plus_3 + 0, 0, '+'},
+ {X plus_4, X plus_4 + 1, X plus_4 + 1, 0, '+'},
+ {X plus_5, X plus_5 + 2, X plus_5 + 2, 1, '+'},
+ {X plus_6, X plus_6 + 4, X plus_6 + 4, 2, '+'},
+ {X plus_7, X plus_7 + 9, X plus_7 + 9, 4, '+'},
+ {X plus_8, X plus_8 + 18, X plus_8 + 18, 8, '+'},
+ {X plus_9, X plus_9 + 29, X plus_9 + 29, 24, '+'},
+ {X plus_10, X plus_10 + 29, X plus_10 + 29, 77, '+'},
+ {X plus_11, X plus_11 + 29, X plus_11 + 29, 183, '+'},
+ {X plus_12, X plus_12 + 29, X plus_12 + 29, 396, '+'},
+ {X plus_13, X plus_13 + 29, X plus_13 + 29, 821, '+'},
+};
+
+#ifdef VMS
+void
+dummy1 ()
+{
+}
+#endif
diff --git a/x/binutils/gas/flonum-mult.c b/x/binutils/gas/flonum-mult.c
new file mode 100644
index 0000000..6d17f0a
--- /dev/null
+++ b/x/binutils/gas/flonum-mult.c
@@ -0,0 +1,188 @@
+/* flonum_mult.c - multiply two flonums
+ Copyright 1987, 1990, 1991, 1992, 1995, 2000, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of Gas, the GNU Assembler.
+
+ The GNU assembler is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY. No author or distributor
+ accepts responsibility to anyone for the consequences of using it
+ or for whether it serves any particular purpose or works at all,
+ unless he says so in writing. Refer to the GNU Assembler General
+ Public License for full details.
+
+ Everyone is granted permission to copy, modify and redistribute
+ the GNU Assembler, but only under the conditions described in the
+ GNU Assembler General Public License. A copy of this license is
+ supposed to have been given to you along with the GNU Assembler
+ so you can know your rights and responsibilities. It should be
+ in a file named COPYING. Among other things, the copyright
+ notice and this notice must be preserved on all copies. */
+
+#include "ansidecl.h"
+#include "flonum.h"
+
+/* plan for a . b => p(roduct)
+
+ +-------+-------+-/ /-+-------+-------+
+ | a | a | ... | a | a |
+ | A | A-1 | | 1 | 0 |
+ +-------+-------+-/ /-+-------+-------+
+
+ +-------+-------+-/ /-+-------+-------+
+ | b | b | ... | b | b |
+ | B | B-1 | | 1 | 0 |
+ +-------+-------+-/ /-+-------+-------+
+
+ +-------+-------+-/ /-+-------+-/ /-+-------+-------+
+ | p | p | ... | p | ... | p | p |
+ | A+B+1| A+B | | N | | 1 | 0 |
+ +-------+-------+-/ /-+-------+-/ /-+-------+-------+
+
+ /^\
+ (carry) a .b ... | ... a .b a .b
+ A B | 0 1 0 0
+ |
+ ... | ... a .b
+ | 1 0
+ |
+ | ...
+ |
+ |
+ |
+ | ___
+ | \
+ +----- P = > a .b
+ N /__ i j
+
+ N = 0 ... A+B
+
+ for all i,j where i+j=N
+ [i,j integers > 0]
+
+ a[], b[], p[] may not intersect.
+ Zero length factors signify 0 significant bits: treat as 0.0.
+ 0.0 factors do the right thing.
+ Zero length product OK.
+
+ I chose the ForTran accent "foo[bar]" instead of the C accent "*garply"
+ because I felt the ForTran way was more intuitive. The C way would
+ probably yield better code on most C compilers. Dean Elsner.
+ (C style also gives deeper insight [to me] ... oh well ...) */
+
+void
+flonum_multip (const FLONUM_TYPE *a, const FLONUM_TYPE *b,
+ FLONUM_TYPE *product)
+{
+ int size_of_a; /* 0 origin */
+ int size_of_b; /* 0 origin */
+ int size_of_product; /* 0 origin */
+ int size_of_sum; /* 0 origin */
+ int extra_product_positions; /* 1 origin */
+ unsigned long work;
+ unsigned long carry;
+ long exponent;
+ LITTLENUM_TYPE *q;
+ long significant; /* TRUE when we emit a non-0 littlenum */
+ /* ForTran accent follows. */
+ int P; /* Scan product low-order -> high. */
+ int N; /* As in sum above. */
+ int A; /* Which [] of a? */
+ int B; /* Which [] of b? */
+
+ if ((a->sign != '-' && a->sign != '+')
+ || (b->sign != '-' && b->sign != '+'))
+ {
+ /* Got to fail somehow. Any suggestions? */
+ product->sign = 0;
+ return;
+ }
+ product->sign = (a->sign == b->sign) ? '+' : '-';
+ size_of_a = a->leader - a->low;
+ size_of_b = b->leader - b->low;
+ exponent = a->exponent + b->exponent;
+ size_of_product = product->high - product->low;
+ size_of_sum = size_of_a + size_of_b;
+ extra_product_positions = size_of_product - size_of_sum;
+ if (extra_product_positions < 0)
+ {
+ P = extra_product_positions; /* P < 0 */
+ exponent -= extra_product_positions; /* Increases exponent. */
+ }
+ else
+ {
+ P = 0;
+ }
+ carry = 0;
+ significant = 0;
+ for (N = 0; N <= size_of_sum; N++)
+ {
+ work = carry;
+ carry = 0;
+ for (A = 0; A <= N; A++)
+ {
+ B = N - A;
+ if (A <= size_of_a && B <= size_of_b && B >= 0)
+ {
+#ifdef TRACE
+ printf ("a:low[%d.]=%04x b:low[%d.]=%04x work_before=%08x\n",
+ A, a->low[A], B, b->low[B], work);
+#endif
+ /* Watch out for sign extension! Without the casts, on
+ the DEC Alpha, the multiplication result is *signed*
+ int, which gets sign-extended to convert to the
+ unsigned long! */
+ work += (unsigned long) a->low[A] * (unsigned long) b->low[B];
+ carry += work >> LITTLENUM_NUMBER_OF_BITS;
+ work &= LITTLENUM_MASK;
+#ifdef TRACE
+ printf ("work=%08x carry=%04x\n", work, carry);
+#endif
+ }
+ }
+ significant |= work;
+ if (significant || P < 0)
+ {
+ if (P >= 0)
+ {
+ product->low[P] = work;
+#ifdef TRACE
+ printf ("P=%d. work[p]:=%04x\n", P, work);
+#endif
+ }
+ P++;
+ }
+ else
+ {
+ extra_product_positions++;
+ exponent++;
+ }
+ }
+ /* [P]-> position # size_of_sum + 1.
+ This is where 'carry' should go. */
+#ifdef TRACE
+ printf ("final carry =%04x\n", carry);
+#endif
+ if (carry)
+ {
+ if (extra_product_positions > 0)
+ product->low[P] = carry;
+ else
+ {
+ /* No room at high order for carry littlenum. */
+ /* Shift right 1 to make room for most significant littlenum. */
+ exponent++;
+ P--;
+ for (q = product->low + P; q >= product->low; q--)
+ {
+ work = *q;
+ *q = carry;
+ carry = work;
+ }
+ }
+ }
+ else
+ P--;
+ product->leader = product->low + P;
+ product->exponent = exponent;
+}
diff --git a/x/binutils/gas/flonum.h b/x/binutils/gas/flonum.h
new file mode 100644
index 0000000..22aa755
--- /dev/null
+++ b/x/binutils/gas/flonum.h
@@ -0,0 +1,102 @@
+/* flonum.h - Floating point package
+ Copyright 1987, 1990, 1991, 1992, 1994, 1996, 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/***********************************************************************\
+ * *
+ * Arbitrary-precision floating point arithmetic. *
+ * *
+ * *
+ * Notation: a floating point number is expressed as *
+ * MANTISSA * (2 ** EXPONENT). *
+ * *
+ * If this offends more traditional mathematicians, then *
+ * please tell me your nomenclature for flonums! *
+ * *
+ \***********************************************************************/
+
+#include "bignum.h"
+
+/***********************************************************************\
+ * *
+ * Variable precision floating point numbers. *
+ * *
+ * Exponent is the place value of the low littlenum. E.g.: *
+ * If 0: low points to the units littlenum. *
+ * If 1: low points to the LITTLENUM_RADIX littlenum. *
+ * If -1: low points to the 1/LITTLENUM_RADIX littlenum. *
+ * *
+ \***********************************************************************/
+
+/* JF: A sign value of 0 means we have been asked to assemble NaN
+ A sign value of 'P' means we've been asked to assemble +Inf
+ A sign value of 'N' means we've been asked to assemble -Inf
+ */
+struct FLONUM_STRUCT {
+ LITTLENUM_TYPE *low; /* low order littlenum of a bignum */
+ LITTLENUM_TYPE *high; /* high order littlenum of a bignum */
+ LITTLENUM_TYPE *leader; /* -> 1st non-zero littlenum */
+ /* If flonum is 0.0, leader==low-1 */
+ long exponent; /* base LITTLENUM_RADIX */
+ char sign; /* '+' or '-' */
+};
+
+typedef struct FLONUM_STRUCT FLONUM_TYPE;
+
+/***********************************************************************\
+ * *
+ * Since we can (& do) meet with exponents like 10^5000, it *
+ * is silly to make a table of ~ 10,000 entries, one for each *
+ * power of 10. We keep a table where item [n] is a struct *
+ * FLONUM_FLOATING_POINT representing 10^(2^n). We then *
+ * multiply appropriate entries from this table to get any *
+ * particular power of 10. For the example of 10^5000, a table *
+ * of just 25 entries suffices: 10^(2^-12)...10^(2^+12). *
+ * *
+ \***********************************************************************/
+
+extern const FLONUM_TYPE flonum_positive_powers_of_ten[];
+extern const FLONUM_TYPE flonum_negative_powers_of_ten[];
+extern const int table_size_of_flonum_powers_of_ten;
+/* Flonum_XXX_powers_of_ten[] table has legal indices from 0 to
+ + this number inclusive. */
+
+/***********************************************************************\
+ * *
+ * Declare worker functions. *
+ * *
+ \***********************************************************************/
+
+int atof_generic (char **address_of_string_pointer,
+ const char *string_of_decimal_marks,
+ const char *string_of_decimal_exponent_marks,
+ FLONUM_TYPE * address_of_generic_floating_point_number);
+
+void flonum_copy (FLONUM_TYPE * in, FLONUM_TYPE * out);
+void flonum_multip (const FLONUM_TYPE * a, const FLONUM_TYPE * b,
+ FLONUM_TYPE * product);
+
+/***********************************************************************\
+ * *
+ * Declare error codes. *
+ * *
+ \***********************************************************************/
+
+#define ERROR_EXPONENT_OVERFLOW (2)
diff --git a/x/binutils/gas/frags.c b/x/binutils/gas/frags.c
new file mode 100644
index 0000000..83625d7
--- /dev/null
+++ b/x/binutils/gas/frags.c
@@ -0,0 +1,378 @@
+/* frags.c - manage frags -
+ Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2003
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+#include "subsegs.h"
+#include "obstack.h"
+
+extern fragS zero_address_frag;
+extern fragS bss_address_frag;
+
+/* Initialization for frag routines. */
+
+void
+frag_init (void)
+{
+ zero_address_frag.fr_type = rs_fill;
+ bss_address_frag.fr_type = rs_fill;
+}
+
+/* Check that we're not trying to assemble into a section that can't
+ allocate frags (currently, this is only possible in the absolute
+ section), or into an mri common. */
+
+static void
+frag_alloc_check (const struct obstack *ob)
+{
+ if (ob->chunk_size == 0)
+ {
+ as_bad (_("attempt to allocate data in absolute section"));
+ subseg_set (text_section, 0);
+ }
+
+ if (mri_common_symbol != NULL)
+ {
+ as_bad (_("attempt to allocate data in common section"));
+ mri_common_symbol = NULL;
+ }
+}
+
+/* Allocate a frag on the specified obstack.
+ Call this routine from everywhere else, so that all the weird alignment
+ hackery can be done in just one place. */
+
+fragS *
+frag_alloc (struct obstack *ob)
+{
+ fragS *ptr;
+ int oalign;
+
+ (void) obstack_alloc (ob, 0);
+ oalign = obstack_alignment_mask (ob);
+ obstack_alignment_mask (ob) = 0;
+ ptr = (fragS *) obstack_alloc (ob, SIZEOF_STRUCT_FRAG);
+ obstack_alignment_mask (ob) = oalign;
+ memset (ptr, 0, SIZEOF_STRUCT_FRAG);
+ return ptr;
+}
+
+/* Try to augment current frag by nchars chars.
+ If there is no room, close of the current frag with a ".fill 0"
+ and begin a new frag. Unless the new frag has nchars chars available
+ do not return. Do not set up any fields of *now_frag. */
+
+void
+frag_grow (unsigned int nchars)
+{
+ if (obstack_room (&frchain_now->frch_obstack) < nchars)
+ {
+ unsigned int n;
+ long oldc;
+
+ frag_wane (frag_now);
+ frag_new (0);
+ oldc = frchain_now->frch_obstack.chunk_size;
+ frchain_now->frch_obstack.chunk_size = 2 * nchars + SIZEOF_STRUCT_FRAG;
+ if (frchain_now->frch_obstack.chunk_size > 0)
+ while ((n = obstack_room (&frchain_now->frch_obstack)) < nchars
+ && (unsigned long) frchain_now->frch_obstack.chunk_size > nchars)
+ {
+ frag_wane (frag_now);
+ frag_new (0);
+ }
+ frchain_now->frch_obstack.chunk_size = oldc;
+ }
+ if (obstack_room (&frchain_now->frch_obstack) < nchars)
+ as_fatal (_("can't extend frag %u chars"), nchars);
+}
+
+/* Call this to close off a completed frag, and start up a new (empty)
+ frag, in the same subsegment as the old frag.
+ [frchain_now remains the same but frag_now is updated.]
+ Because this calculates the correct value of fr_fix by
+ looking at the obstack 'frags', it needs to know how many
+ characters at the end of the old frag belong to the maximal
+ variable part; The rest must belong to fr_fix.
+ It doesn't actually set up the old frag's fr_var. You may have
+ set fr_var == 1, but allocated 10 chars to the end of the frag;
+ In this case you pass old_frags_var_max_size == 10.
+ In fact, you may use fr_var for something totally unrelated to the
+ size of the variable part of the frag; None of the generic frag
+ handling code makes use of fr_var.
+
+ Make a new frag, initialising some components. Link new frag at end
+ of frchain_now. */
+
+void
+frag_new (int old_frags_var_max_size
+ /* Number of chars (already allocated on obstack frags) in
+ variable_length part of frag. */)
+{
+ fragS *former_last_fragP;
+ frchainS *frchP;
+
+ assert (frchain_now->frch_last == frag_now);
+
+ /* Fix up old frag's fr_fix. */
+ frag_now->fr_fix = frag_now_fix_octets () - old_frags_var_max_size;
+ /* Make sure its type is valid. */
+ assert (frag_now->fr_type != 0);
+
+ /* This will align the obstack so the next struct we allocate on it
+ will begin at a correct boundary. */
+ obstack_finish (&frchain_now->frch_obstack);
+ frchP = frchain_now;
+ know (frchP);
+ former_last_fragP = frchP->frch_last;
+ assert (former_last_fragP != 0);
+ assert (former_last_fragP == frag_now);
+ frag_now = frag_alloc (&frchP->frch_obstack);
+
+ as_where (&frag_now->fr_file, &frag_now->fr_line);
+
+ /* Generally, frag_now->points to an address rounded up to next
+ alignment. However, characters will add to obstack frags
+ IMMEDIATELY after the struct frag, even if they are not starting
+ at an alignment address. */
+ former_last_fragP->fr_next = frag_now;
+ frchP->frch_last = frag_now;
+
+#ifndef NO_LISTING
+ {
+ extern struct list_info_struct *listing_tail;
+ frag_now->line = listing_tail;
+ }
+#endif
+
+ assert (frchain_now->frch_last == frag_now);
+
+ frag_now->fr_next = NULL;
+}
+
+/* Start a new frag unless we have n more chars of room in the current frag.
+ Close off the old frag with a .fill 0.
+
+ Return the address of the 1st char to write into. Advance
+ frag_now_growth past the new chars. */
+
+char *
+frag_more (int nchars)
+{
+ register char *retval;
+
+ frag_alloc_check (&frchain_now->frch_obstack);
+ frag_grow (nchars);
+ retval = obstack_next_free (&frchain_now->frch_obstack);
+ obstack_blank_fast (&frchain_now->frch_obstack, nchars);
+ return (retval);
+}
+
+/* Start a new frag unless we have max_chars more chars of room in the
+ current frag. Close off the old frag with a .fill 0.
+
+ Set up a machine_dependent relaxable frag, then start a new frag.
+ Return the address of the 1st char of the var part of the old frag
+ to write into. */
+
+char *
+frag_var (relax_stateT type, int max_chars, int var, relax_substateT subtype,
+ symbolS *symbol, offsetT offset, char *opcode)
+{
+ register char *retval;
+
+ frag_grow (max_chars);
+ retval = obstack_next_free (&frchain_now->frch_obstack);
+ obstack_blank_fast (&frchain_now->frch_obstack, max_chars);
+ frag_now->fr_var = var;
+ frag_now->fr_type = type;
+ frag_now->fr_subtype = subtype;
+ frag_now->fr_symbol = symbol;
+ frag_now->fr_offset = offset;
+ frag_now->fr_opcode = opcode;
+#ifdef USING_CGEN
+ frag_now->fr_cgen.insn = 0;
+ frag_now->fr_cgen.opindex = 0;
+ frag_now->fr_cgen.opinfo = 0;
+#endif
+#ifdef TC_FRAG_INIT
+ TC_FRAG_INIT (frag_now);
+#endif
+ as_where (&frag_now->fr_file, &frag_now->fr_line);
+ frag_new (max_chars);
+ return (retval);
+}
+
+/* OVE: This variant of frag_var assumes that space for the tail has been
+ allocated by caller.
+ No call to frag_grow is done. */
+
+char *
+frag_variant (relax_stateT type, int max_chars, int var,
+ relax_substateT subtype, symbolS *symbol, offsetT offset,
+ char *opcode)
+{
+ register char *retval;
+
+ retval = obstack_next_free (&frchain_now->frch_obstack);
+ frag_now->fr_var = var;
+ frag_now->fr_type = type;
+ frag_now->fr_subtype = subtype;
+ frag_now->fr_symbol = symbol;
+ frag_now->fr_offset = offset;
+ frag_now->fr_opcode = opcode;
+#ifdef USING_CGEN
+ frag_now->fr_cgen.insn = 0;
+ frag_now->fr_cgen.opindex = 0;
+ frag_now->fr_cgen.opinfo = 0;
+#endif
+#ifdef TC_FRAG_INIT
+ TC_FRAG_INIT (frag_now);
+#endif
+ as_where (&frag_now->fr_file, &frag_now->fr_line);
+ frag_new (max_chars);
+ return (retval);
+}
+
+/* Reduce the variable end of a frag to a harmless state. */
+
+void
+frag_wane (register fragS *fragP)
+{
+ fragP->fr_type = rs_fill;
+ fragP->fr_offset = 0;
+ fragP->fr_var = 0;
+}
+
+/* Return the number of bytes by which the current frag can be grown. */
+
+int
+frag_room (void)
+{
+ return obstack_room (&frchain_now->frch_obstack);
+}
+
+/* Make an alignment frag. The size of this frag will be adjusted to
+ force the next frag to have the appropriate alignment. ALIGNMENT
+ is the power of two to which to align. FILL_CHARACTER is the
+ character to use to fill in any bytes which are skipped. MAX is
+ the maximum number of characters to skip when doing the alignment,
+ or 0 if there is no maximum. */
+
+void
+frag_align (int alignment, int fill_character, int max)
+{
+ if (now_seg == absolute_section)
+ {
+ addressT new_off;
+ addressT mask;
+
+ mask = (~(addressT) 0) << alignment;
+ new_off = (abs_section_offset + ~mask) & mask;
+ if (max == 0 || new_off - abs_section_offset <= (addressT) max)
+ abs_section_offset = new_off;
+ }
+ else
+ {
+ char *p;
+
+ p = frag_var (rs_align, 1, 1, (relax_substateT) max,
+ (symbolS *) 0, (offsetT) alignment, (char *) 0);
+ *p = fill_character;
+ }
+}
+
+/* Make an alignment frag like frag_align, but fill with a repeating
+ pattern rather than a single byte. ALIGNMENT is the power of two
+ to which to align. FILL_PATTERN is the fill pattern to repeat in
+ the bytes which are skipped. N_FILL is the number of bytes in
+ FILL_PATTERN. MAX is the maximum number of characters to skip when
+ doing the alignment, or 0 if there is no maximum. */
+
+void
+frag_align_pattern (int alignment, const char *fill_pattern,
+ int n_fill, int max)
+{
+ char *p;
+
+ p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) max,
+ (symbolS *) 0, (offsetT) alignment, (char *) 0);
+ memcpy (p, fill_pattern, n_fill);
+}
+
+/* The NOP_OPCODE is for the alignment fill value. Fill it with a nop
+ instruction so that the disassembler does not choke on it. */
+#ifndef NOP_OPCODE
+#define NOP_OPCODE 0x00
+#endif
+
+/* Use this to restrict the amount of memory allocated for representing
+ the alignment code. Needs to be large enough to hold any fixed sized
+ prologue plus the replicating portion. */
+#ifndef MAX_MEM_FOR_RS_ALIGN_CODE
+ /* Assume that if HANDLE_ALIGN is not defined then no special action
+ is required to code fill, which means that we get just repeat the
+ one NOP_OPCODE byte. */
+# ifndef HANDLE_ALIGN
+# define MAX_MEM_FOR_RS_ALIGN_CODE 1
+# else
+# define MAX_MEM_FOR_RS_ALIGN_CODE ((1 << alignment) - 1)
+# endif
+#endif
+
+void
+frag_align_code (int alignment, int max)
+{
+ char *p;
+
+ p = frag_var (rs_align_code, MAX_MEM_FOR_RS_ALIGN_CODE, 1,
+ (relax_substateT) max, (symbolS *) 0,
+ (offsetT) alignment, (char *) 0);
+ *p = NOP_OPCODE;
+}
+
+addressT
+frag_now_fix_octets (void)
+{
+ if (now_seg == absolute_section)
+ return abs_section_offset;
+
+ return ((char *) obstack_next_free (&frchain_now->frch_obstack)
+ - frag_now->fr_literal);
+}
+
+addressT
+frag_now_fix (void)
+{
+ return frag_now_fix_octets () / OCTETS_PER_BYTE;
+}
+
+void
+frag_append_1_char (int datum)
+{
+ frag_alloc_check (&frchain_now->frch_obstack);
+ if (obstack_room (&frchain_now->frch_obstack) <= 1)
+ {
+ frag_wane (frag_now);
+ frag_new (0);
+ }
+ obstack_1grow (&frchain_now->frch_obstack, datum);
+}
diff --git a/x/binutils/gas/frags.h b/x/binutils/gas/frags.h
new file mode 100644
index 0000000..52a6cfe
--- /dev/null
+++ b/x/binutils/gas/frags.h
@@ -0,0 +1,162 @@
+/* frags.h - Header file for the frag concept.
+ Copyright 1987, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef FRAGS_H
+#define FRAGS_H
+
+#ifdef ANSI_PROTOTYPES
+struct obstack;
+#endif
+
+/* A code fragment (frag) is some known number of chars, followed by some
+ unknown number of chars. Typically the unknown number of chars is an
+ instruction address whose size is yet unknown. We always know the greatest
+ possible size the unknown number of chars may become, and reserve that
+ much room at the end of the frag.
+ Once created, frags do not change address during assembly.
+ We chain the frags in (a) forward-linked list(s). The object-file address
+ of the 1st char of a frag is generally not known until after relax().
+ Many things at assembly time describe an address by {object-file-address
+ of a particular frag}+offset.
+
+ BUG: it may be smarter to have a single pointer off to various different
+ notes for different frag kinds. See how code pans. */
+
+struct frag {
+ /* Object file address (as an octet offset). */
+ addressT fr_address;
+ /* When relaxing multiple times, remember the address the frag had
+ in the last relax pass. */
+ addressT last_fr_address;
+
+ /* (Fixed) number of octets we know we have. May be 0. */
+ offsetT fr_fix;
+ /* May be used for (Variable) number of octets after above.
+ The generic frag handling code no longer makes any use of fr_var. */
+ offsetT fr_var;
+ /* For variable-length tail. */
+ offsetT fr_offset;
+ /* For variable-length tail. */
+ symbolS *fr_symbol;
+ /* Points to opcode low addr byte, for relaxation. */
+ char *fr_opcode;
+
+ /* Chain forward; ascending address order. Rooted in frch_root. */
+ struct frag *fr_next;
+
+ /* Where the frag was created, or where it became a variant frag. */
+ char *fr_file;
+ unsigned int fr_line;
+
+#ifndef NO_LISTING
+ struct list_info_struct *line;
+#endif
+
+ /* Flipped each relax pass so we can easily determine whether
+ fr_address has been adjusted. */
+ unsigned int relax_marker:1;
+
+ /* What state is my tail in? */
+ relax_stateT fr_type;
+ relax_substateT fr_subtype;
+
+#ifdef USING_CGEN
+ /* Don't include this unless using CGEN to keep frag size down. */
+ struct {
+ /* CGEN_INSN entry for this instruction. */
+ const struct cgen_insn *insn;
+ /* Index into operand table. */
+ int opindex;
+ /* Target specific data, usually reloc number. */
+ int opinfo;
+ } fr_cgen;
+#endif
+
+#ifdef TC_FRAG_TYPE
+ TC_FRAG_TYPE tc_frag_data;
+#endif
+
+ /* Data begins here. */
+ char fr_literal[1];
+};
+
+#define SIZEOF_STRUCT_FRAG \
+((char *) zero_address_frag.fr_literal - (char *) &zero_address_frag)
+/* We want to say fr_literal[0] above. */
+
+/* Current frag we are building. This frag is incomplete. It is,
+ however, included in frchain_now. The fr_fix field is bogus;
+ instead, use frag_now_fix (). */
+COMMON fragS *frag_now;
+extern addressT frag_now_fix (void);
+extern addressT frag_now_fix_octets (void);
+
+/* For foreign-segment symbol fixups. */
+COMMON fragS zero_address_frag;
+/* For local common (N_BSS segment) fixups. */
+COMMON fragS bss_address_frag;
+
+#if 0
+/* A macro to speed up appending exactly 1 char to current frag. */
+/* JF changed < 1 to <= 1 to avoid a race condition. */
+#define FRAG_APPEND_1_CHAR(datum) \
+{ \
+ if (obstack_room (&frags) <= 1) \
+ { \
+ frag_wane (frag_now); \
+ frag_new (0); \
+ } \
+ obstack_1grow (&frags, datum); \
+}
+#else
+extern void frag_append_1_char (int);
+#define FRAG_APPEND_1_CHAR(X) frag_append_1_char (X)
+#endif
+
+void frag_init (void);
+fragS *frag_alloc (struct obstack *);
+void frag_grow (unsigned int nchars);
+char *frag_more (int nchars);
+void frag_align (int alignment, int fill_character, int max);
+void frag_align_pattern (int alignment, const char *fill_pattern,
+ int n_fill, int max);
+void frag_align_code (int alignment, int max);
+void frag_new (int old_frags_var_max_size);
+void frag_wane (fragS * fragP);
+int frag_room (void);
+
+char *frag_variant (relax_stateT type,
+ int max_chars,
+ int var,
+ relax_substateT subtype,
+ symbolS * symbol,
+ offsetT offset,
+ char *opcode);
+
+char *frag_var (relax_stateT type,
+ int max_chars,
+ int var,
+ relax_substateT subtype,
+ symbolS * symbol,
+ offsetT offset,
+ char *opcode);
+
+#endif /* FRAGS_H */
diff --git a/x/binutils/gas/gasp.c b/x/binutils/gas/gasp.c
new file mode 100644
index 0000000..d1e4185
--- /dev/null
+++ b/x/binutils/gas/gasp.c
@@ -0,0 +1,3761 @@
+/* gasp.c - Gnu assembler preprocessor main program.
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ Written by Steve and Judy Chamberlain of Cygnus Support,
+ sac@cygnus.com
+
+ This file is part of GASP, the GNU Assembler Preprocessor.
+
+ GASP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GASP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GASP; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+This program translates the input macros and stuff into a form
+suitable for gas to consume.
+
+ gasp [-sdhau] [-c char] [-o <outfile>] <infile>*
+
+ -s copy source to output
+ -c <char> comments are started with <char> instead of !
+ -u allow unreasonable stuff
+ -p print line numbers
+ -d print debugging stats
+ -s semi colons start comments
+ -a use alternate syntax
+ Pseudo ops can start with or without a .
+ Labels have to be in first column.
+ -I specify include dir
+ Macro arg parameters subsituted by name, don't need the &.
+ String can start with ' too.
+ Strings can be surrounded by <..>
+ A %<exp> in a string evaluates the expression
+ Literal char in a string with !
+*/
+
+#include "config.h"
+#include "bin-bugs.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include "getopt.h"
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef NEED_MALLOC_DECLARATION
+extern char *malloc ();
+#endif
+
+#include "ansidecl.h"
+#include "libiberty.h"
+#include "safe-ctype.h"
+#include "sb.h"
+#include "macro.h"
+#include "asintl.h"
+#include "xregex.h"
+
+char *program_version = "1.2";
+
+/* This is normally declared in as.h, but we don't include that. We
+ need the function because other files linked with gasp.c might call
+ it. */
+extern void as_abort PARAMS ((const char *, int, const char *));
+
+/* The default obstack chunk size. If we set this to zero, the
+ obstack code will use whatever will fit in a 4096 byte block. This
+ is used by the hash table code used by macro.c. */
+int chunksize = 0;
+
+#define MAX_INCLUDES 30 /* Maximum include depth. */
+#define MAX_REASONABLE 1000 /* Maximum number of expansions. */
+
+int unreasonable; /* -u on command line. */
+int stats; /* -d on command line. */
+int print_line_number; /* -p flag on command line. */
+int copysource; /* -c flag on command line. */
+int warnings; /* Number of WARNINGs generated so far. */
+int errors; /* Number of ERRORs generated so far. */
+int fatals; /* Number of fatal ERRORs generated so far (either 0 or 1). */
+int alternate = 0; /* -a on command line. */
+int mri = 0; /* -M on command line. */
+char comment_char = '!';
+int radix = 10; /* Default radix. */
+
+int had_end; /* Seen .END. */
+
+/* The output stream. */
+FILE *outfile;
+
+/* The attributes of each character are stored as a bit pattern
+ chartype, which gives us quick tests. */
+
+#define FIRSTBIT 1
+#define NEXTBIT 2
+#define SEPBIT 4
+#define WHITEBIT 8
+#define COMMENTBIT 16
+#define BASEBIT 32
+#define ISCOMMENTCHAR(x) (chartype[(unsigned char)(x)] & COMMENTBIT)
+#define ISFIRSTCHAR(x) (chartype[(unsigned char)(x)] & FIRSTBIT)
+#define ISNEXTCHAR(x) (chartype[(unsigned char)(x)] & NEXTBIT)
+#define ISSEP(x) (chartype[(unsigned char)(x)] & SEPBIT)
+#define ISWHITE(x) (chartype[(unsigned char)(x)] & WHITEBIT)
+#define ISBASE(x) (chartype[(unsigned char)(x)] & BASEBIT)
+static char chartype[256];
+
+/* Conditional assembly uses the `ifstack'. Each aif pushes another
+ entry onto the stack, and sets the on flag if it should. The aelse
+ sets hadelse, and toggles on. An aend pops a level. We limit to
+ 100 levels of nesting, not because we're facists pigs with read
+ only minds, but because more than 100 levels of nesting is probably
+ a bug in the user's macro structure. */
+
+#define IFNESTING 100
+struct {
+ int on; /* Is the level being output. */
+ int hadelse; /* Has an aelse been seen. */
+} ifstack[IFNESTING];
+
+int ifi;
+
+/* The final and intermediate results of expression evaluation are kept in
+ exp_t's. Note that a symbol is not an sb, but a pointer into the input
+ line. It must be coped somewhere safe before the next line is read in. */
+
+typedef struct {
+ char *name;
+ int len;
+} symbol;
+
+typedef struct {
+ int value; /* Constant part. */
+ symbol add_symbol; /* Name part. */
+ symbol sub_symbol; /* Name part. */
+} exp_t;
+
+/* Hashing is done in a pretty standard way. A hash_table has a
+ pointer to a vector of pointers to hash_entrys, and the size of the
+ vector. A hash_entry contains a union of all the info we like to
+ store in hash table. If there is a hash collision, hash_entries
+ with the same hash are kept in a chain. */
+
+/* What the data in a hash_entry means. */
+typedef enum {
+ hash_integer, /* Name->integer mapping. */
+ hash_string, /* Name->string mapping. */
+ hash_macro, /* Name is a macro. */
+ hash_formal /* Name is a formal argument. */
+} hash_type;
+
+typedef struct hs {
+ sb key; /* Symbol name. */
+ hash_type type; /* Symbol meaning. */
+ union {
+ sb s;
+ int i;
+ struct macro_struct *m;
+ struct formal_struct *f;
+ } value;
+ struct hs *next; /* Next hash_entry with same hash key. */
+} hash_entry;
+
+typedef struct {
+ hash_entry **table;
+ int size;
+} hash_table;
+
+/* How we nest files and expand macros etc.
+
+ We keep a stack of of include_stack structs. Each include file
+ pushes a new level onto the stack. We keep an sb with a pushback
+ too. unget chars are pushed onto the pushback sb, getchars first
+ checks the pushback sb before reading from the input stream.
+
+ Small things are expanded by adding the text of the item onto the
+ pushback sb. Larger items are grown by pushing a new level and
+ allocating the entire pushback buf for the item. Each time
+ something like a macro is expanded, the stack index is changed. We
+ can then perform an exitm by popping all entries off the stack with
+ the same stack index. If we're being reasonable, we can detect
+ recusive expansion by checking the index is reasonably small. */
+
+typedef enum {
+ include_file, include_repeat, include_while, include_macro
+} include_type;
+
+struct include_stack {
+ sb pushback; /* Current pushback stream. */
+ int pushback_index; /* Next char to read from stream. */
+ FILE *handle; /* Open file. */
+ sb name; /* Name of file. */
+ int linecount; /* Number of lines read so far. */
+ include_type type;
+ int index; /* Index of this layer. */
+} include_stack[MAX_INCLUDES];
+
+struct include_stack *sp;
+#define isp (sp - include_stack)
+
+/* Include file list. */
+
+typedef struct include_path {
+ struct include_path *next;
+ sb path;
+} include_path;
+
+include_path *paths_head;
+include_path *paths_tail;
+
+static void quit PARAMS ((void));
+static void hash_new_table PARAMS ((int, hash_table *));
+static int hash PARAMS ((sb *));
+static hash_entry *hash_create PARAMS ((hash_table *, sb *));
+static void hash_add_to_string_table PARAMS ((hash_table *, sb *, sb *, int));
+static void hash_add_to_int_table PARAMS ((hash_table *, sb *, int));
+static hash_entry *hash_lookup PARAMS ((hash_table *, sb *));
+static void checkconst PARAMS ((int, exp_t *));
+static int is_flonum PARAMS ((int, sb *));
+static int chew_flonum PARAMS ((int, sb *, sb *));
+static int sb_strtol PARAMS ((int, sb *, int, int *));
+static int level_0 PARAMS ((int, sb *, exp_t *));
+static int level_1 PARAMS ((int, sb *, exp_t *));
+static int level_2 PARAMS ((int, sb *, exp_t *));
+static int level_3 PARAMS ((int, sb *, exp_t *));
+static int level_4 PARAMS ((int, sb *, exp_t *));
+static int level_5 PARAMS ((int, sb *, exp_t *));
+static int exp_parse PARAMS ((int, sb *, exp_t *));
+static void exp_string PARAMS ((exp_t *, sb *));
+static int exp_get_abs PARAMS ((const char *, int, sb *, int *));
+#if 0
+static void strip_comments PARAMS ((sb *));
+#endif
+static void unget PARAMS ((int));
+static void include_buf PARAMS ((sb *, sb *, include_type, int));
+static void include_print_where_line PARAMS ((FILE *));
+static void include_print_line PARAMS ((FILE *));
+static int get_line PARAMS ((sb *));
+static int grab_label PARAMS ((sb *, sb *));
+static void change_base PARAMS ((int, sb *, sb *));
+static void do_end PARAMS ((sb *));
+static void do_assign PARAMS ((int, int, sb *));
+static void do_radix PARAMS ((sb *));
+static int get_opsize PARAMS ((int, sb *, int *));
+static int eol PARAMS ((int, sb *));
+static void do_data PARAMS ((int, sb *, int));
+static void do_datab PARAMS ((int, sb *));
+static void do_align PARAMS ((int, sb *));
+static void do_res PARAMS ((int, sb *, int));
+static void do_export PARAMS ((sb *));
+static void do_print PARAMS ((int, sb *));
+static void do_heading PARAMS ((int, sb *));
+static void do_page PARAMS ((void));
+static void do_form PARAMS ((int, sb *));
+static int get_any_string PARAMS ((int, sb *, sb *, int, int));
+static int skip_openp PARAMS ((int, sb *));
+static int skip_closep PARAMS ((int, sb *));
+static int dolen PARAMS ((int, sb *, sb *));
+static int doinstr PARAMS ((int, sb *, sb *));
+static int dosubstr PARAMS ((int, sb *, sb *));
+static void process_assigns PARAMS ((int, sb *, sb *));
+static int get_and_process PARAMS ((int, sb *, sb *));
+static void process_file PARAMS ((void));
+static void free_old_entry PARAMS ((hash_entry *));
+static void do_assigna PARAMS ((int, sb *));
+static void do_assignc PARAMS ((int, sb *));
+static void do_reg PARAMS ((int, sb *));
+static int condass_lookup_name PARAMS ((sb *, int, sb *, int));
+static int whatcond PARAMS ((int, sb *, int *));
+static int istrue PARAMS ((int, sb *));
+static void do_aif PARAMS ((int, sb *));
+static void do_aelse PARAMS ((void));
+static void do_aendi PARAMS ((void));
+static int condass_on PARAMS ((void));
+static void do_if PARAMS ((int, sb *, int));
+static int get_mri_string PARAMS ((int, sb *, sb *, int));
+static void do_ifc PARAMS ((int, sb *, int));
+static void do_aendr PARAMS ((void));
+static void do_awhile PARAMS ((int, sb *));
+static void do_aendw PARAMS ((void));
+static void do_exitm PARAMS ((void));
+static void do_arepeat PARAMS ((int, sb *));
+static void do_endm PARAMS ((void));
+static void do_irp PARAMS ((int, sb *, int));
+static void do_local PARAMS ((int, sb *));
+static void do_macro PARAMS ((int, sb *));
+static int macro_op PARAMS ((int, sb *));
+static int getstring PARAMS ((int, sb *, sb *));
+static void do_sdata PARAMS ((int, sb *, int));
+static void do_sdatab PARAMS ((int, sb *));
+static int new_file PARAMS ((const char *));
+static void do_include PARAMS ((int, sb *));
+static void include_pop PARAMS ((void));
+static int get PARAMS ((void));
+static int linecount PARAMS ((void));
+static int include_next_index PARAMS ((void));
+static void chartype_init PARAMS ((void));
+static int process_pseudo_op PARAMS ((int, sb *, sb *));
+static void add_keyword PARAMS ((const char *, int));
+static void process_init PARAMS ((void));
+static void do_define PARAMS ((const char *));
+static void show_usage PARAMS ((FILE *, int));
+static void show_help PARAMS ((void));
+
+#define FATAL(x) \
+ do \
+ { \
+ include_print_where_line (stderr); \
+ fprintf x; \
+ fatals++; \
+ quit (); \
+ } \
+ while (0)
+
+#define ERROR(x) \
+ do \
+ { \
+ include_print_where_line (stderr); \
+ fprintf x; \
+ errors++; \
+ } \
+ while (0)
+
+#define WARNING(x) \
+ do \
+ { \
+ include_print_where_line (stderr); \
+ fprintf x; \
+ warnings++; \
+ } \
+ while (0)
+
+/* Exit the program and return the right ERROR code. */
+
+static void
+quit ()
+{
+ int exitcode;
+ if (fatals + errors)
+ exitcode = 1;
+ else
+ exitcode = 0;
+
+ if (stats)
+ {
+ int i;
+ for (i = 0; i < sb_max_power_two; i++)
+ {
+ fprintf (stderr, "strings size %8d : %d\n",
+ 1 << i, string_count[i]);
+ }
+ }
+ exit (exitcode);
+}
+
+/* Hash table maintenance. */
+
+/* Build a new hash table with size buckets
+ and fill in the info at ptr. */
+
+static void
+hash_new_table (size, ptr)
+ int size;
+ hash_table *ptr;
+{
+ int i;
+ ptr->size = size;
+ ptr->table = (hash_entry **) xmalloc (size * (sizeof (hash_entry *)));
+ /* Fill with null-pointer, not zero-bit-pattern. */
+ for (i = 0; i < size; i++)
+ ptr->table[i] = 0;
+}
+
+/* Calculate and return the hash value of the sb at key. */
+
+static int
+hash (key)
+ sb *key;
+{
+ int k = 0x1234;
+ int i;
+ char *p = key->ptr;
+ for (i = 0; i < key->len; i++)
+ {
+ k ^= (k << 2) ^ *p;
+ p++;
+ }
+ return k & 0xf0fff;
+}
+
+/* Look up key in hash_table tab. If present, then return it,
+ otherwise build a new one and fill it with hash_integer. */
+
+static hash_entry *
+hash_create (tab, key)
+ hash_table *tab;
+ sb *key;
+{
+ int k = hash (key) % tab->size;
+ hash_entry *p;
+ hash_entry **table = tab->table;
+
+ p = table[k];
+
+ while (1)
+ {
+ if (!p)
+ {
+ hash_entry *n = (hash_entry *) xmalloc (sizeof (hash_entry));
+ n->next = table[k];
+ sb_new (&n->key);
+ sb_add_sb (&n->key, key);
+ table[k] = n;
+ n->type = hash_integer;
+ return n;
+ }
+ if (strncmp (table[k]->key.ptr, key->ptr, key->len) == 0)
+ {
+ return p;
+ }
+ p = p->next;
+ }
+}
+
+/* Add sb name with key into hash_table tab.
+ If replacing old value and again, then ERROR. */
+
+static void
+hash_add_to_string_table (tab, key, name, again)
+ hash_table *tab;
+ sb *key;
+ sb *name;
+ int again;
+{
+ hash_entry *ptr = hash_create (tab, key);
+ if (ptr->type == hash_integer)
+ {
+ sb_new (&ptr->value.s);
+ }
+ if (ptr->value.s.len)
+ {
+ if (!again)
+ ERROR ((stderr, _("redefinition not allowed\n")));
+ }
+
+ ptr->type = hash_string;
+ sb_reset (&ptr->value.s);
+
+ sb_add_sb (&ptr->value.s, name);
+}
+
+/* Add integer name to hash_table tab with sb key. */
+
+static void
+hash_add_to_int_table (tab, key, name)
+ hash_table *tab;
+ sb *key;
+ int name;
+{
+ hash_entry *ptr = hash_create (tab, key);
+ ptr->value.i = name;
+}
+
+/* Look up sb key in hash_table tab.
+ If found, return hash_entry result, else 0. */
+
+static hash_entry *
+hash_lookup (tab, key)
+ hash_table *tab;
+ sb *key;
+{
+ int k = hash (key) % tab->size;
+ hash_entry **table = tab->table;
+ hash_entry *p = table[k];
+ while (p)
+ {
+ if (p->key.len == key->len
+ && strncmp (p->key.ptr, key->ptr, key->len) == 0)
+ return p;
+ p = p->next;
+ }
+ return 0;
+}
+
+/* expressions
+
+ are handled in a really simple recursive decent way. each bit of
+ the machine takes an index into an sb and a pointer to an exp_t,
+ modifies the *exp_t and returns the index of the first character
+ past the part of the expression parsed.
+
+ expression precedence:
+ ( )
+ unary + - ~
+ * /
+ + -
+ &
+ | ~
+*/
+
+/* Make sure that the exp_t at term is constant.
+ If not the give the op ERROR. */
+
+static void
+checkconst (op, term)
+ int op;
+ exp_t *term;
+{
+ if (term->add_symbol.len
+ || term->sub_symbol.len)
+ {
+ ERROR ((stderr, _("the %c operator cannot take non-absolute arguments.\n"), op));
+ }
+}
+
+/* Chew the flonum from the string starting at idx. Adjust idx to
+ point to the next character after the flonum. */
+
+static int
+chew_flonum (idx, string, out)
+ int idx;
+ sb *string;
+ sb *out;
+{
+ sb buf;
+ regex_t reg;
+ regmatch_t match;
+
+ /* Duplicate and null terminate `string'. */
+ sb_new (&buf);
+ sb_add_sb (&buf, string);
+ sb_add_char (&buf, '\0');
+
+ if (regcomp (&reg, "([0-9]*\\.[0-9]+([eE][+-]?[0-9]+)?)", REG_EXTENDED) != 0)
+ return idx;
+ if (regexec (&reg, &buf.ptr[idx], 1, &match, 0) != 0)
+ return idx;
+
+ /* Copy the match to the output. */
+ assert (match.rm_eo >= match.rm_so);
+ sb_add_buffer (out, &buf.ptr[idx], match.rm_eo - match.rm_so);
+
+ sb_kill (&buf);
+ regfree (&reg);
+ idx += match.rm_eo;
+ return idx;
+}
+
+static int
+is_flonum (idx, string)
+ int idx;
+ sb *string;
+{
+ sb buf;
+ regex_t reg;
+ int rc;
+
+ /* Duplicate and null terminate `string'. */
+ sb_new (&buf);
+ sb_add_sb (&buf, string);
+ sb_add_char (&buf, '\0');
+
+ if (regcomp (&reg, "^[0-9]*\\.[0-9]+([eE][+-]?[0-9]+)?", REG_EXTENDED) != 0)
+ return 0;
+
+ rc = regexec (&reg, &buf.ptr[idx], 0, NULL, 0);
+ sb_kill (&buf);
+ regfree (&reg);
+ return (rc == 0);
+}
+
+/* Turn the number in string at idx into a number of base, fill in
+ ptr, and return the index of the first character not in the number. */
+
+static int
+sb_strtol (idx, string, base, ptr)
+ int idx;
+ sb *string;
+ int base;
+ int *ptr;
+{
+ int value = 0;
+ idx = sb_skip_white (idx, string);
+
+ while (idx < string->len)
+ {
+ int ch = string->ptr[idx];
+ int dig = 0;
+ if (ISDIGIT (ch))
+ dig = ch - '0';
+ else if (ch >= 'a' && ch <= 'f')
+ dig = ch - 'a' + 10;
+ else if (ch >= 'A' && ch <= 'F')
+ dig = ch - 'A' + 10;
+ else
+ break;
+
+ if (dig >= base)
+ break;
+
+ value = value * base + dig;
+ idx++;
+ }
+ *ptr = value;
+ return idx;
+}
+
+static int
+level_0 (idx, string, lhs)
+ int idx;
+ sb *string;
+ exp_t *lhs;
+{
+ lhs->add_symbol.len = 0;
+ lhs->add_symbol.name = 0;
+
+ lhs->sub_symbol.len = 0;
+ lhs->sub_symbol.name = 0;
+
+ idx = sb_skip_white (idx, string);
+
+ lhs->value = 0;
+
+ if (ISDIGIT (string->ptr[idx]))
+ {
+ idx = sb_strtol (idx, string, 10, &lhs->value);
+ }
+ else if (ISFIRSTCHAR (string->ptr[idx]))
+ {
+ int len = 0;
+ lhs->add_symbol.name = string->ptr + idx;
+ while (idx < string->len && ISNEXTCHAR (string->ptr[idx]))
+ {
+ idx++;
+ len++;
+ }
+ lhs->add_symbol.len = len;
+ }
+ else if (string->ptr[idx] == '"')
+ {
+ sb acc;
+ sb_new (&acc);
+ ERROR ((stderr, _("string where expression expected.\n")));
+ idx = getstring (idx, string, &acc);
+ sb_kill (&acc);
+ }
+ else
+ {
+ ERROR ((stderr, _("can't find primary in expression.\n")));
+ idx++;
+ }
+ return sb_skip_white (idx, string);
+}
+
+static int
+level_1 (idx, string, lhs)
+ int idx;
+ sb *string;
+ exp_t *lhs;
+{
+ idx = sb_skip_white (idx, string);
+
+ switch (string->ptr[idx])
+ {
+ case '+':
+ idx = level_1 (idx + 1, string, lhs);
+ break;
+ case '~':
+ idx = level_1 (idx + 1, string, lhs);
+ checkconst ('~', lhs);
+ lhs->value = ~lhs->value;
+ break;
+ case '-':
+ {
+ symbol t;
+ idx = level_1 (idx + 1, string, lhs);
+ lhs->value = -lhs->value;
+ t = lhs->add_symbol;
+ lhs->add_symbol = lhs->sub_symbol;
+ lhs->sub_symbol = t;
+ break;
+ }
+ case '(':
+ idx++;
+ idx = level_5 (sb_skip_white (idx, string), string, lhs);
+ if (string->ptr[idx] != ')')
+ ERROR ((stderr, _("misplaced closing parens.\n")));
+ else
+ idx++;
+ break;
+ default:
+ idx = level_0 (idx, string, lhs);
+ break;
+ }
+ return sb_skip_white (idx, string);
+}
+
+static int
+level_2 (idx, string, lhs)
+ int idx;
+ sb *string;
+ exp_t *lhs;
+{
+ exp_t rhs;
+
+ idx = level_1 (idx, string, lhs);
+
+ while (idx < string->len && (string->ptr[idx] == '*'
+ || string->ptr[idx] == '/'))
+ {
+ char op = string->ptr[idx++];
+ idx = level_1 (idx, string, &rhs);
+ switch (op)
+ {
+ case '*':
+ checkconst ('*', lhs);
+ checkconst ('*', &rhs);
+ lhs->value *= rhs.value;
+ break;
+ case '/':
+ checkconst ('/', lhs);
+ checkconst ('/', &rhs);
+ if (rhs.value == 0)
+ ERROR ((stderr, _("attempt to divide by zero.\n")));
+ else
+ lhs->value /= rhs.value;
+ break;
+ }
+ }
+ return sb_skip_white (idx, string);
+}
+
+static int
+level_3 (idx, string, lhs)
+ int idx;
+ sb *string;
+ exp_t *lhs;
+{
+ exp_t rhs;
+
+ idx = level_2 (idx, string, lhs);
+
+ while (idx < string->len
+ && (string->ptr[idx] == '+'
+ || string->ptr[idx] == '-'))
+ {
+ char op = string->ptr[idx++];
+ idx = level_2 (idx, string, &rhs);
+ switch (op)
+ {
+ case '+':
+ lhs->value += rhs.value;
+ if (lhs->add_symbol.name && rhs.add_symbol.name)
+ {
+ ERROR ((stderr, _("can't add two relocatable expressions\n")));
+ }
+ /* Change nn+symbol to symbol + nn. */
+ if (rhs.add_symbol.name)
+ {
+ lhs->add_symbol = rhs.add_symbol;
+ }
+ break;
+ case '-':
+ lhs->value -= rhs.value;
+ lhs->sub_symbol = rhs.add_symbol;
+ break;
+ }
+ }
+ return sb_skip_white (idx, string);
+}
+
+static int
+level_4 (idx, string, lhs)
+ int idx;
+ sb *string;
+ exp_t *lhs;
+{
+ exp_t rhs;
+
+ idx = level_3 (idx, string, lhs);
+
+ while (idx < string->len &&
+ string->ptr[idx] == '&')
+ {
+ char op = string->ptr[idx++];
+ idx = level_3 (idx, string, &rhs);
+ switch (op)
+ {
+ case '&':
+ checkconst ('&', lhs);
+ checkconst ('&', &rhs);
+ lhs->value &= rhs.value;
+ break;
+ }
+ }
+ return sb_skip_white (idx, string);
+}
+
+static int
+level_5 (idx, string, lhs)
+ int idx;
+ sb *string;
+ exp_t *lhs;
+{
+ exp_t rhs;
+
+ idx = level_4 (idx, string, lhs);
+
+ while (idx < string->len
+ && (string->ptr[idx] == '|' || string->ptr[idx] == '~'))
+ {
+ char op = string->ptr[idx++];
+ idx = level_4 (idx, string, &rhs);
+ switch (op)
+ {
+ case '|':
+ checkconst ('|', lhs);
+ checkconst ('|', &rhs);
+ lhs->value |= rhs.value;
+ break;
+ case '~':
+ checkconst ('~', lhs);
+ checkconst ('~', &rhs);
+ lhs->value ^= rhs.value;
+ break;
+ }
+ }
+ return sb_skip_white (idx, string);
+}
+
+/* Parse the expression at offset idx into string, fill up res with
+ the result. Return the index of the first char past the
+ expression. */
+
+static int
+exp_parse (idx, string, res)
+ int idx;
+ sb *string;
+ exp_t *res;
+{
+ return level_5 (sb_skip_white (idx, string), string, res);
+}
+
+/* Turn the expression at exp into text and glue it onto the end of
+ string. */
+
+static void
+exp_string (exp, string)
+ exp_t *exp;
+ sb *string;
+{
+ int np = 0;
+ int ad = 0;
+ sb_reset (string);
+
+ if (exp->add_symbol.len)
+ {
+ sb_add_buffer (string, exp->add_symbol.name, exp->add_symbol.len);
+ np = 1;
+ ad = 1;
+ }
+ if (exp->value)
+ {
+ char buf[20];
+ if (np)
+ sb_add_char (string, '+');
+ sprintf (buf, "%d", exp->value);
+ sb_add_string (string, buf);
+ np = 1;
+ ad = 1;
+ }
+ if (exp->sub_symbol.len)
+ {
+ sb_add_char (string, '-');
+ sb_add_buffer (string, exp->add_symbol.name, exp->add_symbol.len);
+ np = 0;
+ ad = 1;
+ }
+
+ if (!ad)
+ sb_add_char (string, '0');
+}
+
+/* Parse the expression at offset idx into sb in. Return the value in
+ val. If the expression is not constant, give ERROR emsg. Return
+ the index of the first character past the end of the expression. */
+
+static int
+exp_get_abs (emsg, idx, in, val)
+ const char *emsg;
+ int idx;
+ sb *in;
+ int *val;
+{
+ exp_t res;
+ idx = exp_parse (idx, in, &res);
+ if (res.add_symbol.len || res.sub_symbol.len)
+ ERROR ((stderr, "%s", emsg));
+ *val = res.value;
+ return idx;
+}
+
+/* Current label parsed from line. */
+sb label;
+
+/* Hash table for all assigned variables. */
+hash_table assign_hash_table;
+
+/* Hash table for keyword. */
+hash_table keyword_hash_table;
+
+/* Hash table for eq variables. */
+hash_table vars;
+
+#define in_comment ';'
+
+#if 0
+static void
+strip_comments (out)
+ sb *out;
+{
+ char *s = out->ptr;
+ int i = 0;
+ for (i = 0; i < out->len; i++)
+ {
+ if (ISCOMMENTCHAR (s[i]))
+ {
+ out->len = i;
+ return;
+ }
+ }
+}
+#endif
+
+/* Push back character ch so that it can be read again. */
+
+static void
+unget (ch)
+ int ch;
+{
+ if (ch == '\n')
+ {
+ sp->linecount--;
+ }
+ if (sp->pushback_index)
+ sp->pushback_index--;
+ else
+ sb_add_char (&sp->pushback, ch);
+}
+
+/* Push the sb ptr onto the include stack, with the given name, type
+ and index. */
+
+static void
+include_buf (name, ptr, type, index)
+ sb *name;
+ sb *ptr;
+ include_type type;
+ int index;
+{
+ sp++;
+ if (sp - include_stack >= MAX_INCLUDES)
+ FATAL ((stderr, _("unreasonable nesting.\n")));
+ sb_new (&sp->name);
+ sb_add_sb (&sp->name, name);
+ sp->handle = 0;
+ sp->linecount = 1;
+ sp->pushback_index = 0;
+ sp->type = type;
+ sp->index = index;
+ sb_new (&sp->pushback);
+ sb_add_sb (&sp->pushback, ptr);
+}
+
+/* Used in ERROR messages, print info on where the include stack is
+ onto file. */
+
+static void
+include_print_where_line (file)
+ FILE *file;
+{
+ struct include_stack *p = include_stack + 1;
+
+ while (p <= sp)
+ {
+ fprintf (file, "%s:%d ", sb_name (&p->name), p->linecount - 1);
+ p++;
+ }
+}
+
+/* Used in listings, print the line number onto file. */
+
+static void
+include_print_line (file)
+ FILE *file;
+{
+ int n;
+ struct include_stack *p = include_stack + 1;
+
+ n = fprintf (file, "%4d", p->linecount);
+ p++;
+ while (p <= sp)
+ {
+ n += fprintf (file, ".%d", p->linecount);
+ p++;
+ }
+ while (n < 8 * 3)
+ {
+ fprintf (file, " ");
+ n++;
+ }
+}
+
+/* Read a line from the top of the include stack into sb in. */
+
+static int
+get_line (in)
+ sb *in;
+{
+ int online = 0;
+ int more = 1;
+
+ if (copysource)
+ {
+ putc (comment_char, outfile);
+ if (print_line_number)
+ include_print_line (outfile);
+ }
+
+ while (1)
+ {
+ int ch = get ();
+
+ while (ch == '\r')
+ ch = get ();
+
+ if (ch == EOF)
+ {
+ if (online)
+ {
+ WARNING ((stderr, _("End of file not at start of line.\n")));
+ if (copysource)
+ putc ('\n', outfile);
+ ch = '\n';
+ }
+ else
+ more = 0;
+ break;
+ }
+
+ if (copysource)
+ {
+ putc (ch, outfile);
+ }
+
+ if (ch == '\n')
+ {
+ ch = get ();
+ online = 0;
+ if (ch == '+')
+ {
+ /* Continued line. */
+ if (copysource)
+ {
+ putc (comment_char, outfile);
+ putc ('+', outfile);
+ }
+ ch = get ();
+ }
+ else
+ {
+ if (ch != EOF)
+ unget (ch);
+ break;
+ }
+ }
+ else
+ {
+ sb_add_char (in, ch);
+ }
+ online++;
+ }
+
+ return more;
+}
+
+/* Find a label from sb in and put it in out. */
+
+static int
+grab_label (in, out)
+ sb *in;
+ sb *out;
+{
+ int i = 0;
+ sb_reset (out);
+ if (ISFIRSTCHAR (in->ptr[i]) || in->ptr[i] == '\\')
+ {
+ sb_add_char (out, in->ptr[i]);
+ i++;
+ while ((ISNEXTCHAR (in->ptr[i])
+ || in->ptr[i] == '\\'
+ || in->ptr[i] == '&')
+ && i < in->len)
+ {
+ sb_add_char (out, in->ptr[i]);
+ i++;
+ }
+ }
+ return i;
+}
+
+/* Find all strange base stuff and turn into decimal. Also
+ find all the other numbers and convert them from the default radix. */
+
+static void
+change_base (idx, in, out)
+ int idx;
+ sb *in;
+ sb *out;
+{
+ char buffer[20];
+
+ while (idx < in->len)
+ {
+ if (in->ptr[idx] == '\\'
+ && idx + 1 < in->len
+ && in->ptr[idx + 1] == '(')
+ {
+ idx += 2;
+ while (idx < in->len
+ && in->ptr[idx] != ')')
+ {
+ sb_add_char (out, in->ptr[idx]);
+ idx++;
+ }
+ if (idx < in->len)
+ idx++;
+ }
+ else if (idx < in->len - 1 && in->ptr[idx + 1] == '\'' && ! mri)
+ {
+ int base;
+ int value;
+ switch (in->ptr[idx])
+ {
+ case 'b':
+ case 'B':
+ base = 2;
+ break;
+ case 'q':
+ case 'Q':
+ base = 8;
+ break;
+ case 'h':
+ case 'H':
+ base = 16;
+ break;
+ case 'd':
+ case 'D':
+ base = 10;
+ break;
+ default:
+ ERROR ((stderr, _("Illegal base character %c.\n"), in->ptr[idx]));
+ base = 10;
+ break;
+ }
+
+ idx = sb_strtol (idx + 2, in, base, &value);
+ sprintf (buffer, "%d", value);
+ sb_add_string (out, buffer);
+ }
+ else if (ISFIRSTCHAR (in->ptr[idx]))
+ {
+ /* Copy entire names through quickly. */
+ sb_add_char (out, in->ptr[idx]);
+ idx++;
+ while (idx < in->len && ISNEXTCHAR (in->ptr[idx]))
+ {
+ sb_add_char (out, in->ptr[idx]);
+ idx++;
+ }
+ }
+ else if (is_flonum (idx, in))
+ {
+ idx = chew_flonum (idx, in, out);
+ }
+ else if (ISDIGIT (in->ptr[idx]))
+ {
+ int value;
+ /* All numbers must start with a digit, let's chew it and
+ spit out decimal. */
+ idx = sb_strtol (idx, in, radix, &value);
+ sprintf (buffer, "%d", value);
+ sb_add_string (out, buffer);
+
+ /* Skip all undigsested letters. */
+ while (idx < in->len && ISNEXTCHAR (in->ptr[idx]))
+ {
+ sb_add_char (out, in->ptr[idx]);
+ idx++;
+ }
+ }
+ else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
+ {
+ char tchar = in->ptr[idx];
+ /* Copy entire names through quickly. */
+ sb_add_char (out, in->ptr[idx]);
+ idx++;
+ while (idx < in->len && in->ptr[idx] != tchar)
+ {
+ sb_add_char (out, in->ptr[idx]);
+ idx++;
+ }
+ }
+ else
+ {
+ /* Nothing special, just pass it through. */
+ sb_add_char (out, in->ptr[idx]);
+ idx++;
+ }
+ }
+
+}
+
+/* .end */
+
+static void
+do_end (in)
+ sb *in;
+{
+ had_end = 1;
+ if (mri)
+ fprintf (outfile, "%s\n", sb_name (in));
+}
+
+/* .assign */
+
+static void
+do_assign (again, idx, in)
+ int again;
+ int idx;
+ sb *in;
+{
+ /* Stick label in symbol table with following value. */
+ exp_t e;
+ sb acc;
+
+ sb_new (&acc);
+ idx = exp_parse (idx, in, &e);
+ exp_string (&e, &acc);
+ hash_add_to_string_table (&assign_hash_table, &label, &acc, again);
+ sb_kill (&acc);
+}
+
+/* .radix [b|q|d|h] */
+
+static void
+do_radix (ptr)
+ sb *ptr;
+{
+ int idx = sb_skip_white (0, ptr);
+ switch (ptr->ptr[idx])
+ {
+ case 'B':
+ case 'b':
+ radix = 2;
+ break;
+ case 'q':
+ case 'Q':
+ radix = 8;
+ break;
+ case 'd':
+ case 'D':
+ radix = 10;
+ break;
+ case 'h':
+ case 'H':
+ radix = 16;
+ break;
+ default:
+ ERROR ((stderr, _("radix is %c must be one of b, q, d or h"), radix));
+ }
+}
+
+/* Parse off a .b, .w or .l. */
+
+static int
+get_opsize (idx, in, size)
+ int idx;
+ sb *in;
+ int *size;
+{
+ *size = 4;
+ if (in->ptr[idx] == '.')
+ {
+ idx++;
+ }
+ switch (in->ptr[idx])
+ {
+ case 'b':
+ case 'B':
+ *size = 1;
+ break;
+ case 'w':
+ case 'W':
+ *size = 2;
+ break;
+ case 'l':
+ case 'L':
+ *size = 4;
+ break;
+ case ' ':
+ case '\t':
+ break;
+ default:
+ ERROR ((stderr, _("size must be one of b, w or l, is %c.\n"), in->ptr[idx]));
+ break;
+ }
+ idx++;
+
+ return idx;
+}
+
+static int
+eol (idx, line)
+ int idx;
+ sb *line;
+{
+ idx = sb_skip_white (idx, line);
+ if (idx < line->len
+ && ISCOMMENTCHAR(line->ptr[idx]))
+ return 1;
+ if (idx >= line->len)
+ return 1;
+ return 0;
+}
+
+/* .data [.b|.w|.l] <data>*
+ or d[bwl] <data>* */
+
+static void
+do_data (idx, in, size)
+ int idx;
+ sb *in;
+ int size;
+{
+ int opsize = 4;
+ char *opname = ".yikes!";
+ sb acc;
+ sb_new (&acc);
+
+ if (!size)
+ {
+ idx = get_opsize (idx, in, &opsize);
+ }
+ else
+ {
+ opsize = size;
+ }
+ switch (opsize)
+ {
+ case 4:
+ opname = ".long";
+ break;
+ case 2:
+ opname = ".short";
+ break;
+ case 1:
+ opname = ".byte";
+ break;
+ }
+
+ fprintf (outfile, "%s\t", opname);
+
+ idx = sb_skip_white (idx, in);
+
+ if (alternate
+ && idx < in->len
+ && in->ptr[idx] == '"')
+ {
+ int i;
+ idx = getstring (idx, in, &acc);
+ for (i = 0; i < acc.len; i++)
+ {
+ if (i)
+ fprintf (outfile, ",");
+ fprintf (outfile, "%d", acc.ptr[i]);
+ }
+ }
+ else
+ {
+ while (!eol (idx, in))
+ {
+ exp_t e;
+ idx = exp_parse (idx, in, &e);
+ exp_string (&e, &acc);
+ sb_add_char (&acc, 0);
+ fprintf (outfile, "%s", acc.ptr);
+ if (idx < in->len && in->ptr[idx] == ',')
+ {
+ fprintf (outfile, ",");
+ idx++;
+ }
+ }
+ }
+ sb_kill (&acc);
+ sb_print_at (outfile, idx, in);
+ fprintf (outfile, "\n");
+}
+
+/* .datab [.b|.w|.l] <repeat>,<fill> */
+
+static void
+do_datab (idx, in)
+ int idx;
+ sb *in;
+{
+ int opsize;
+ int repeat;
+ int fill;
+
+ idx = get_opsize (idx, in, &opsize);
+
+ idx = exp_get_abs (_("datab repeat must be constant.\n"), idx, in, &repeat);
+ idx = sb_skip_comma (idx, in);
+ idx = exp_get_abs (_("datab data must be absolute.\n"), idx, in, &fill);
+
+ fprintf (outfile, ".fill\t%d,%d,%d\n", repeat, opsize, fill);
+}
+
+/* .align <size> */
+
+static void
+do_align (idx, in)
+ int idx;
+ sb *in;
+{
+ int al, have_fill, fill;
+
+ idx = exp_get_abs (_("align needs absolute expression.\n"), idx, in, &al);
+ idx = sb_skip_white (idx, in);
+ have_fill = 0;
+ fill = 0;
+ if (! eol (idx, in))
+ {
+ idx = sb_skip_comma (idx, in);
+ idx = exp_get_abs (_(".align needs absolute fill value.\n"), idx, in,
+ &fill);
+ have_fill = 1;
+ }
+
+ fprintf (outfile, ".align %d", al);
+ if (have_fill)
+ fprintf (outfile, ",%d", fill);
+ fprintf (outfile, "\n");
+}
+
+/* .res[.b|.w|.l] <size> */
+
+static void
+do_res (idx, in, type)
+ int idx;
+ sb *in;
+ int type;
+{
+ int size = 4;
+ int count = 0;
+
+ idx = get_opsize (idx, in, &size);
+ while (!eol (idx, in))
+ {
+ idx = sb_skip_white (idx, in);
+ if (in->ptr[idx] == ',')
+ idx++;
+ idx = exp_get_abs (_("res needs absolute expression for fill count.\n"), idx, in, &count);
+
+ if (type == 'c' || type == 'z')
+ count++;
+
+ fprintf (outfile, ".space %d\n", count * size);
+ }
+}
+
+/* .export */
+
+static void
+do_export (in)
+ sb *in;
+{
+ fprintf (outfile, ".global %s\n", sb_name (in));
+}
+
+/* .print [list] [nolist] */
+
+static void
+do_print (idx, in)
+ int idx;
+ sb *in;
+{
+ idx = sb_skip_white (idx, in);
+ while (idx < in->len)
+ {
+ if (strncasecmp (in->ptr + idx, "LIST", 4) == 0)
+ {
+ fprintf (outfile, ".list\n");
+ idx += 4;
+ }
+ else if (strncasecmp (in->ptr + idx, "NOLIST", 6) == 0)
+ {
+ fprintf (outfile, ".nolist\n");
+ idx += 6;
+ }
+ idx++;
+ }
+}
+
+/* .head */
+
+static void
+do_heading (idx, in)
+ int idx;
+ sb *in;
+{
+ sb head;
+ sb_new (&head);
+ idx = getstring (idx, in, &head);
+ fprintf (outfile, ".title \"%s\"\n", sb_name (&head));
+ sb_kill (&head);
+}
+
+/* .page */
+
+static void
+do_page ()
+{
+ fprintf (outfile, ".eject\n");
+}
+
+/* .form [lin=<value>] [col=<value>] */
+
+static void
+do_form (idx, in)
+ int idx;
+ sb *in;
+{
+ int lines = 60;
+ int columns = 132;
+ idx = sb_skip_white (idx, in);
+
+ while (idx < in->len)
+ {
+
+ if (strncasecmp (in->ptr + idx, "LIN=", 4) == 0)
+ {
+ idx += 4;
+ idx = exp_get_abs (_("form LIN= needs absolute expresssion.\n"), idx, in, &lines);
+ }
+
+ if (strncasecmp (in->ptr + idx, _("COL="), 4) == 0)
+ {
+ idx += 4;
+ idx = exp_get_abs (_("form COL= needs absolute expresssion.\n"), idx, in, &columns);
+ }
+
+ idx++;
+ }
+ fprintf (outfile, ".psize %d,%d\n", lines, columns);
+
+}
+
+/* Fetch string from the input stream,
+ rules:
+ 'Bxyx<whitespace> -> return 'Bxyza
+ %<char> -> return string of decimal value of x
+ "<string>" -> return string
+ xyx<whitespace> -> return xyz
+*/
+
+static int
+get_any_string (idx, in, out, expand, pretend_quoted)
+ int idx;
+ sb *in;
+ sb *out;
+ int expand;
+ int pretend_quoted;
+{
+ sb_reset (out);
+ idx = sb_skip_white (idx, in);
+
+ if (idx < in->len)
+ {
+ if (in->len > 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx]))
+ {
+ while (!ISSEP (in->ptr[idx]))
+ sb_add_char (out, in->ptr[idx++]);
+ }
+ else if (in->ptr[idx] == '%'
+ && alternate
+ && expand)
+ {
+ int val;
+ char buf[20];
+ /* Turns the next expression into a string. */
+ /* xgettext: no-c-format */
+ idx = exp_get_abs (_("% operator needs absolute expression"),
+ idx + 1,
+ in,
+ &val);
+ sprintf (buf, "%d", val);
+ sb_add_string (out, buf);
+ }
+ else if (in->ptr[idx] == '"'
+ || in->ptr[idx] == '<'
+ || (alternate && in->ptr[idx] == '\''))
+ {
+ if (alternate && expand)
+ {
+ /* Keep the quotes. */
+ sb_add_char (out, '\"');
+
+ idx = getstring (idx, in, out);
+ sb_add_char (out, '\"');
+
+ }
+ else
+ {
+ idx = getstring (idx, in, out);
+ }
+ }
+ else
+ {
+ while (idx < in->len
+ && (in->ptr[idx] == '"'
+ || in->ptr[idx] == '\''
+ || pretend_quoted
+ || !ISSEP (in->ptr[idx])))
+ {
+ if (in->ptr[idx] == '"'
+ || in->ptr[idx] == '\'')
+ {
+ char tchar = in->ptr[idx];
+ sb_add_char (out, in->ptr[idx++]);
+ while (idx < in->len
+ && in->ptr[idx] != tchar)
+ sb_add_char (out, in->ptr[idx++]);
+ if (idx == in->len)
+ return idx;
+ }
+ sb_add_char (out, in->ptr[idx++]);
+ }
+ }
+ }
+
+ return idx;
+}
+
+/* Skip along sb in starting at idx, suck off whitespace a ( and more
+ whitespace. Return the idx of the next char. */
+
+static int
+skip_openp (idx, in)
+ int idx;
+ sb *in;
+{
+ idx = sb_skip_white (idx, in);
+ if (in->ptr[idx] != '(')
+ ERROR ((stderr, _("misplaced ( .\n")));
+ idx = sb_skip_white (idx + 1, in);
+ return idx;
+}
+
+/* Skip along sb in starting at idx, suck off whitespace a ) and more
+ whitespace. Return the idx of the next char. */
+
+static int
+skip_closep (idx, in)
+ int idx;
+ sb *in;
+{
+ idx = sb_skip_white (idx, in);
+ if (in->ptr[idx] != ')')
+ ERROR ((stderr, _("misplaced ).\n")));
+ idx = sb_skip_white (idx + 1, in);
+ return idx;
+}
+
+/* .len */
+
+static int
+dolen (idx, in, out)
+ int idx;
+ sb *in;
+ sb *out;
+{
+
+ sb stringout;
+ char buffer[10];
+
+ sb_new (&stringout);
+ idx = skip_openp (idx, in);
+ idx = get_and_process (idx, in, &stringout);
+ idx = skip_closep (idx, in);
+ sprintf (buffer, "%d", stringout.len);
+ sb_add_string (out, buffer);
+
+ sb_kill (&stringout);
+ return idx;
+}
+
+/* .instr */
+
+static int
+doinstr (idx, in, out)
+ int idx;
+ sb *in;
+ sb *out;
+{
+ sb string;
+ sb search;
+ int i;
+ int start;
+ int res;
+ char buffer[10];
+
+ sb_new (&string);
+ sb_new (&search);
+ idx = skip_openp (idx, in);
+ idx = get_and_process (idx, in, &string);
+ idx = sb_skip_comma (idx, in);
+ idx = get_and_process (idx, in, &search);
+ idx = sb_skip_comma (idx, in);
+ if (ISDIGIT (in->ptr[idx]))
+ {
+ idx = exp_get_abs (_(".instr needs absolute expresson.\n"), idx, in, &start);
+ }
+ else
+ {
+ start = 0;
+ }
+ idx = skip_closep (idx, in);
+ res = -1;
+ for (i = start; i < string.len; i++)
+ {
+ if (strncmp (string.ptr + i, search.ptr, search.len) == 0)
+ {
+ res = i;
+ break;
+ }
+ }
+ sprintf (buffer, "%d", res);
+ sb_add_string (out, buffer);
+ sb_kill (&string);
+ sb_kill (&search);
+ return idx;
+}
+
+static int
+dosubstr (idx, in, out)
+ int idx;
+ sb *in;
+ sb *out;
+{
+ sb string;
+ int pos;
+ int len;
+ sb_new (&string);
+
+ idx = skip_openp (idx, in);
+ idx = get_and_process (idx, in, &string);
+ idx = sb_skip_comma (idx, in);
+ idx = exp_get_abs (_("need absolute position.\n"), idx, in, &pos);
+ idx = sb_skip_comma (idx, in);
+ idx = exp_get_abs (_("need absolute length.\n"), idx, in, &len);
+ idx = skip_closep (idx, in);
+
+ if (len < 0 || pos < 0 ||
+ pos > string.len
+ || pos + len > string.len)
+ {
+ sb_add_string (out, " ");
+ }
+ else
+ {
+ sb_add_char (out, '"');
+ while (len > 0)
+ {
+ sb_add_char (out, string.ptr[pos++]);
+ len--;
+ }
+ sb_add_char (out, '"');
+ }
+ sb_kill (&string);
+ return idx;
+}
+
+/* Scan line, change tokens in the hash table to their replacements. */
+
+static void
+process_assigns (idx, in, buf)
+ int idx;
+ sb *in;
+ sb *buf;
+{
+ while (idx < in->len)
+ {
+ hash_entry *ptr;
+ if (in->ptr[idx] == '\\'
+ && idx + 1 < in->len
+ && in->ptr[idx + 1] == '(')
+ {
+ do
+ {
+ sb_add_char (buf, in->ptr[idx]);
+ idx++;
+ }
+ while (idx < in->len && in->ptr[idx - 1] != ')');
+ }
+ else if (in->ptr[idx] == '\\'
+ && idx + 1 < in->len
+ && in->ptr[idx + 1] == '&')
+ {
+ idx = condass_lookup_name (in, idx + 2, buf, 1);
+ }
+ else if (in->ptr[idx] == '\\'
+ && idx + 1 < in->len
+ && in->ptr[idx + 1] == '$')
+ {
+ idx = condass_lookup_name (in, idx + 2, buf, 0);
+ }
+ else if (idx + 3 < in->len
+ && in->ptr[idx] == '.'
+ && TOUPPER (in->ptr[idx + 1]) == 'L'
+ && TOUPPER (in->ptr[idx + 2]) == 'E'
+ && TOUPPER (in->ptr[idx + 3]) == 'N')
+ idx = dolen (idx + 4, in, buf);
+ else if (idx + 6 < in->len
+ && in->ptr[idx] == '.'
+ && TOUPPER (in->ptr[idx + 1]) == 'I'
+ && TOUPPER (in->ptr[idx + 2]) == 'N'
+ && TOUPPER (in->ptr[idx + 3]) == 'S'
+ && TOUPPER (in->ptr[idx + 4]) == 'T'
+ && TOUPPER (in->ptr[idx + 5]) == 'R')
+ idx = doinstr (idx + 6, in, buf);
+ else if (idx + 7 < in->len
+ && in->ptr[idx] == '.'
+ && TOUPPER (in->ptr[idx + 1]) == 'S'
+ && TOUPPER (in->ptr[idx + 2]) == 'U'
+ && TOUPPER (in->ptr[idx + 3]) == 'B'
+ && TOUPPER (in->ptr[idx + 4]) == 'S'
+ && TOUPPER (in->ptr[idx + 5]) == 'T'
+ && TOUPPER (in->ptr[idx + 6]) == 'R')
+ idx = dosubstr (idx + 7, in, buf);
+ else if (ISFIRSTCHAR (in->ptr[idx]))
+ {
+ /* May be a simple name subsitution, see if we have a word. */
+ sb acc;
+ int cur = idx + 1;
+ while (cur < in->len
+ && (ISNEXTCHAR (in->ptr[cur])))
+ cur++;
+
+ sb_new (&acc);
+ sb_add_buffer (&acc, in->ptr + idx, cur - idx);
+ ptr = hash_lookup (&assign_hash_table, &acc);
+ if (ptr)
+ {
+ /* Found a definition for it. */
+ sb_add_sb (buf, &ptr->value.s);
+ }
+ else
+ {
+ /* No definition, just copy the word. */
+ sb_add_sb (buf, &acc);
+ }
+ sb_kill (&acc);
+ idx = cur;
+ }
+ else
+ {
+ sb_add_char (buf, in->ptr[idx++]);
+ }
+ }
+}
+
+static int
+get_and_process (idx, in, out)
+ int idx;
+ sb *in;
+ sb *out;
+{
+ sb t;
+ sb_new (&t);
+ idx = get_any_string (idx, in, &t, 1, 0);
+ process_assigns (0, &t, out);
+ sb_kill (&t);
+ return idx;
+}
+
+static void
+process_file ()
+{
+ sb line;
+ sb t1, t2;
+ sb acc;
+ sb label_in;
+ int more;
+
+ sb_new (&line);
+ sb_new (&t1);
+ sb_new (&t2);
+ sb_new (&acc);
+ sb_new (&label_in);
+ sb_reset (&line);
+ more = get_line (&line);
+ while (more)
+ {
+ /* Find any label and pseudo op that we're intested in. */
+ int l;
+ if (line.len == 0)
+ {
+ if (condass_on ())
+ fprintf (outfile, "\n");
+ }
+ else if (mri
+ && (line.ptr[0] == '*'
+ || line.ptr[0] == '!'))
+ {
+ /* MRI line comment. */
+ fprintf (outfile, "%s", sb_name (&line));
+ }
+ else
+ {
+ l = grab_label (&line, &label_in);
+ sb_reset (&label);
+
+ if (line.ptr[l] == ':')
+ l++;
+ while (ISWHITE (line.ptr[l]) && l < line.len)
+ l++;
+
+ if (label_in.len)
+ {
+ int do_assigns;
+
+ /* Munge the label, unless this is EQU or ASSIGN. */
+ do_assigns = 1;
+ if (l < line.len
+ && (line.ptr[l] == '.' || alternate || mri))
+ {
+ int lx = l;
+
+ if (line.ptr[lx] == '.')
+ ++lx;
+ if (lx + 3 <= line.len
+ && strncasecmp ("EQU", line.ptr + lx, 3) == 0
+ && (lx + 3 == line.len
+ || ! ISFIRSTCHAR (line.ptr[lx + 3])))
+ do_assigns = 0;
+ else if (lx + 6 <= line.len
+ && strncasecmp ("ASSIGN", line.ptr + lx, 6) == 0
+ && (lx + 6 == line.len
+ || ! ISFIRSTCHAR (line.ptr[lx + 6])))
+ do_assigns = 0;
+ }
+
+ if (do_assigns)
+ process_assigns (0, &label_in, &label);
+ else
+ sb_add_sb (&label, &label_in);
+ }
+
+ if (l < line.len)
+ {
+ if (process_pseudo_op (l, &line, &acc))
+ {
+
+ }
+ else if (condass_on ())
+ {
+ if (macro_op (l, &line))
+ {
+
+ }
+ else
+ {
+ {
+ if (label.len)
+ {
+ fprintf (outfile, "%s:\t", sb_name (&label));
+ }
+ else
+ fprintf (outfile, "\t");
+ sb_reset (&t1);
+ process_assigns (l, &line, &t1);
+ sb_reset (&t2);
+ change_base (0, &t1, &t2);
+ fprintf (outfile, "%s\n", sb_name (&t2));
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Only a label on this line. */
+ if (label.len && condass_on ())
+ {
+ fprintf (outfile, "%s:\n", sb_name (&label));
+ }
+ }
+ }
+
+ if (had_end)
+ break;
+ sb_reset (&line);
+ more = get_line (&line);
+ }
+
+ if (!had_end && !mri)
+ WARNING ((stderr, _("END missing from end of file.\n")));
+}
+
+static void
+free_old_entry (ptr)
+ hash_entry *ptr;
+{
+ if (ptr)
+ {
+ if (ptr->type == hash_string)
+ sb_kill (&ptr->value.s);
+ }
+}
+
+/* name: .ASSIGNA <value> */
+
+static void
+do_assigna (idx, in)
+ int idx;
+ sb *in;
+{
+ sb tmp;
+ int val;
+ sb_new (&tmp);
+
+ process_assigns (idx, in, &tmp);
+ idx = exp_get_abs (_(".ASSIGNA needs constant expression argument.\n"), 0, &tmp, &val);
+
+ if (!label.len)
+ {
+ ERROR ((stderr, _(".ASSIGNA without label.\n")));
+ }
+ else
+ {
+ hash_entry *ptr = hash_create (&vars, &label);
+ free_old_entry (ptr);
+ ptr->type = hash_integer;
+ ptr->value.i = val;
+ }
+ sb_kill (&tmp);
+}
+
+/* name: .ASSIGNC <string> */
+
+static void
+do_assignc (idx, in)
+ int idx;
+ sb *in;
+{
+ sb acc;
+ sb_new (&acc);
+ idx = getstring (idx, in, &acc);
+
+ if (!label.len)
+ {
+ ERROR ((stderr, _(".ASSIGNS without label.\n")));
+ }
+ else
+ {
+ hash_entry *ptr = hash_create (&vars, &label);
+ free_old_entry (ptr);
+ ptr->type = hash_string;
+ sb_new (&ptr->value.s);
+ sb_add_sb (&ptr->value.s, &acc);
+ }
+ sb_kill (&acc);
+}
+
+/* name: .REG (reg) */
+
+static void
+do_reg (idx, in)
+ int idx;
+ sb *in;
+{
+ /* Remove reg stuff from inside parens. */
+ sb what;
+ if (!mri)
+ idx = skip_openp (idx, in);
+ else
+ idx = sb_skip_white (idx, in);
+ sb_new (&what);
+ while (idx < in->len
+ && (mri
+ ? ! eol (idx, in)
+ : in->ptr[idx] != ')'))
+ {
+ sb_add_char (&what, in->ptr[idx]);
+ idx++;
+ }
+ hash_add_to_string_table (&assign_hash_table, &label, &what, 1);
+ sb_kill (&what);
+}
+
+static int
+condass_lookup_name (inbuf, idx, out, warn)
+ sb *inbuf;
+ int idx;
+ sb *out;
+ int warn;
+{
+ hash_entry *ptr;
+ sb condass_acc;
+ sb_new (&condass_acc);
+
+ while (idx < inbuf->len
+ && ISNEXTCHAR (inbuf->ptr[idx]))
+ {
+ sb_add_char (&condass_acc, inbuf->ptr[idx++]);
+ }
+
+ if (inbuf->ptr[idx] == '\'')
+ idx++;
+ ptr = hash_lookup (&vars, &condass_acc);
+
+ if (!ptr)
+ {
+ if (warn)
+ {
+ WARNING ((stderr, _("Can't find preprocessor variable %s.\n"), sb_name (&condass_acc)));
+ }
+ else
+ {
+ sb_add_string (out, "0");
+ }
+ }
+ else
+ {
+ if (ptr->type == hash_integer)
+ {
+ char buffer[30];
+ sprintf (buffer, "%d", ptr->value.i);
+ sb_add_string (out, buffer);
+ }
+ else
+ {
+ sb_add_sb (out, &ptr->value.s);
+ }
+ }
+ sb_kill (&condass_acc);
+ return idx;
+}
+
+#define EQ 1
+#define NE 2
+#define GE 3
+#define LT 4
+#define LE 5
+#define GT 6
+#define NEVER 7
+
+static int
+whatcond (idx, in, val)
+ int idx;
+ sb *in;
+ int *val;
+{
+ int cond;
+
+ idx = sb_skip_white (idx, in);
+ cond = NEVER;
+ if (idx + 1 < in->len)
+ {
+ char *p;
+ char a, b;
+
+ p = in->ptr + idx;
+ a = TOUPPER (p[0]);
+ b = TOUPPER (p[1]);
+ if (a == 'E' && b == 'Q')
+ cond = EQ;
+ else if (a == 'N' && b == 'E')
+ cond = NE;
+ else if (a == 'L' && b == 'T')
+ cond = LT;
+ else if (a == 'L' && b == 'E')
+ cond = LE;
+ else if (a == 'G' && b == 'T')
+ cond = GT;
+ else if (a == 'G' && b == 'E')
+ cond = GE;
+ }
+ if (cond == NEVER)
+ {
+ ERROR ((stderr, _("Comparison operator must be one of EQ, NE, LT, LE, GT or GE.\n")));
+ cond = NEVER;
+ }
+ idx = sb_skip_white (idx + 2, in);
+ *val = cond;
+ return idx;
+}
+
+static int
+istrue (idx, in)
+ int idx;
+ sb *in;
+{
+ int res;
+ sb acc_a;
+ sb cond;
+ sb acc_b;
+ sb_new (&acc_a);
+ sb_new (&cond);
+ sb_new (&acc_b);
+ idx = sb_skip_white (idx, in);
+
+ if (in->ptr[idx] == '"')
+ {
+ int cond;
+ int same;
+ /* This is a string comparision. */
+ idx = getstring (idx, in, &acc_a);
+ idx = whatcond (idx, in, &cond);
+ idx = getstring (idx, in, &acc_b);
+ same = acc_a.len == acc_b.len
+ && (strncmp (acc_a.ptr, acc_b.ptr, acc_a.len) == 0);
+
+ if (cond != EQ && cond != NE)
+ {
+ ERROR ((stderr, _("Comparison operator for strings must be EQ or NE\n")));
+ res = 0;
+ }
+ else
+ res = (cond != EQ) ^ same;
+ }
+ else
+ /* This is a numeric expression. */
+ {
+ int vala;
+ int valb;
+ int cond;
+ idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx, in, &vala);
+ idx = whatcond (idx, in, &cond);
+ idx = sb_skip_white (idx, in);
+ if (in->ptr[idx] == '"')
+ {
+ WARNING ((stderr, _("String compared against expression.\n")));
+ res = 0;
+ }
+ else
+ {
+ idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx, in, &valb);
+ switch (cond)
+ {
+ default:
+ res = 42;
+ break;
+ case EQ:
+ res = vala == valb;
+ break;
+ case NE:
+ res = vala != valb;
+ break;
+ case LT:
+ res = vala < valb;
+ break;
+ case LE:
+ res = vala <= valb;
+ break;
+ case GT:
+ res = vala > valb;
+ break;
+ case GE:
+ res = vala >= valb;
+ break;
+ case NEVER:
+ res = 0;
+ break;
+ }
+ }
+ }
+
+ sb_kill (&acc_a);
+ sb_kill (&cond);
+ sb_kill (&acc_b);
+ return res;
+}
+
+/* .AIF */
+
+static void
+do_aif (idx, in)
+ int idx;
+ sb *in;
+{
+ if (ifi >= IFNESTING)
+ {
+ FATAL ((stderr, _("AIF nesting unreasonable.\n")));
+ }
+ ifi++;
+ ifstack[ifi].on = ifstack[ifi - 1].on ? istrue (idx, in) : 0;
+ ifstack[ifi].hadelse = 0;
+}
+
+/* .AELSE */
+
+static void
+do_aelse ()
+{
+ ifstack[ifi].on = ifstack[ifi - 1].on ? !ifstack[ifi].on : 0;
+ if (ifstack[ifi].hadelse)
+ {
+ ERROR ((stderr, _("Multiple AELSEs in AIF.\n")));
+ }
+ ifstack[ifi].hadelse = 1;
+}
+
+/* .AENDI */
+
+static void
+do_aendi ()
+{
+ if (ifi != 0)
+ {
+ ifi--;
+ }
+ else
+ {
+ ERROR ((stderr, _("AENDI without AIF.\n")));
+ }
+}
+
+static int
+condass_on ()
+{
+ return ifstack[ifi].on;
+}
+
+/* MRI IFEQ, IFNE, IFLT, IFLE, IFGE, IFGT. */
+
+static void
+do_if (idx, in, cond)
+ int idx;
+ sb *in;
+ int cond;
+{
+ int val;
+ int res;
+
+ if (ifi >= IFNESTING)
+ {
+ FATAL ((stderr, _("IF nesting unreasonable.\n")));
+ }
+
+ idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"),
+ idx, in, &val);
+ switch (cond)
+ {
+ default:
+ case EQ: res = val == 0; break;
+ case NE: res = val != 0; break;
+ case LT: res = val < 0; break;
+ case LE: res = val <= 0; break;
+ case GE: res = val >= 0; break;
+ case GT: res = val > 0; break;
+ }
+
+ ifi++;
+ ifstack[ifi].on = ifstack[ifi - 1].on ? res : 0;
+ ifstack[ifi].hadelse = 0;
+}
+
+/* Get a string for the MRI IFC or IFNC pseudo-ops. */
+
+static int
+get_mri_string (idx, in, val, terminator)
+ int idx;
+ sb *in;
+ sb *val;
+ int terminator;
+{
+ idx = sb_skip_white (idx, in);
+
+ if (idx < in->len
+ && in->ptr[idx] == '\'')
+ {
+ sb_add_char (val, '\'');
+ for (++idx; idx < in->len; ++idx)
+ {
+ sb_add_char (val, in->ptr[idx]);
+ if (in->ptr[idx] == '\'')
+ {
+ ++idx;
+ if (idx >= in->len
+ || in->ptr[idx] != '\'')
+ break;
+ }
+ }
+ idx = sb_skip_white (idx, in);
+ }
+ else
+ {
+ int i;
+
+ while (idx < in->len
+ && in->ptr[idx] != terminator)
+ {
+ sb_add_char (val, in->ptr[idx]);
+ ++idx;
+ }
+ i = val->len - 1;
+ while (i >= 0 && ISWHITE (val->ptr[i]))
+ --i;
+ val->len = i + 1;
+ }
+
+ return idx;
+}
+
+/* MRI IFC, IFNC */
+
+static void
+do_ifc (idx, in, ifnc)
+ int idx;
+ sb *in;
+ int ifnc;
+{
+ sb first;
+ sb second;
+ int res;
+
+ if (ifi >= IFNESTING)
+ {
+ FATAL ((stderr, _("IF nesting unreasonable.\n")));
+ }
+
+ sb_new (&first);
+ sb_new (&second);
+
+ idx = get_mri_string (idx, in, &first, ',');
+
+ if (idx >= in->len || in->ptr[idx] != ',')
+ {
+ ERROR ((stderr, _("Bad format for IF or IFNC.\n")));
+ return;
+ }
+
+ idx = get_mri_string (idx + 1, in, &second, ';');
+
+ res = (first.len == second.len
+ && strncmp (first.ptr, second.ptr, first.len) == 0);
+ res ^= ifnc;
+
+ ifi++;
+ ifstack[ifi].on = ifstack[ifi - 1].on ? res : 0;
+ ifstack[ifi].hadelse = 0;
+}
+
+/* .ENDR */
+
+static void
+do_aendr ()
+{
+ if (!mri)
+ ERROR ((stderr, _("AENDR without a AREPEAT.\n")));
+ else
+ ERROR ((stderr, _("ENDR without a REPT.\n")));
+}
+
+/* .AWHILE */
+
+static void
+do_awhile (idx, in)
+ int idx;
+ sb *in;
+{
+ int line = linecount ();
+ sb exp;
+ sb sub;
+ int doit;
+
+ sb_new (&sub);
+ sb_new (&exp);
+
+ process_assigns (idx, in, &exp);
+ doit = istrue (0, &exp);
+
+ if (! buffer_and_nest ("AWHILE", "AENDW", &sub, get_line))
+ FATAL ((stderr, _("AWHILE without a AENDW at %d.\n"), line - 1));
+
+ /* Turn
+ .AWHILE exp
+ foo
+ .AENDW
+ into
+ foo
+ .AWHILE exp
+ foo
+ .ENDW
+ */
+
+ if (doit)
+ {
+ int index = include_next_index ();
+
+ sb copy;
+ sb_new (&copy);
+ sb_add_sb (&copy, &sub);
+ sb_add_sb (&copy, in);
+ sb_add_string (&copy, "\n");
+ sb_add_sb (&copy, &sub);
+ sb_add_string (&copy, "\t.AENDW\n");
+ /* Push another WHILE. */
+ include_buf (&exp, &copy, include_while, index);
+ sb_kill (&copy);
+ }
+ sb_kill (&exp);
+ sb_kill (&sub);
+}
+
+/* .AENDW */
+
+static void
+do_aendw ()
+{
+ ERROR ((stderr, _("AENDW without a AENDW.\n")));
+}
+
+/* .EXITM
+
+ Pop things off the include stack until the type and index changes. */
+
+static void
+do_exitm ()
+{
+ include_type type = sp->type;
+ if (type == include_repeat
+ || type == include_while
+ || type == include_macro)
+ {
+ int index = sp->index;
+ include_pop ();
+ while (sp->index == index
+ && sp->type == type)
+ {
+ include_pop ();
+ }
+ }
+}
+
+/* .AREPEAT */
+
+static void
+do_arepeat (idx, in)
+ int idx;
+ sb *in;
+{
+ int line = linecount ();
+ sb exp; /* Buffer with expression in it. */
+ sb copy; /* Expanded repeat block. */
+ sb sub; /* Contents of AREPEAT. */
+ int rc;
+ int ret;
+ char buffer[30];
+
+ sb_new (&exp);
+ sb_new (&copy);
+ sb_new (&sub);
+ process_assigns (idx, in, &exp);
+ idx = exp_get_abs (_("AREPEAT must have absolute operand.\n"), 0, &exp, &rc);
+ if (!mri)
+ ret = buffer_and_nest ("AREPEAT", "AENDR", &sub, get_line);
+ else
+ ret = buffer_and_nest ("REPT", "ENDR", &sub, get_line);
+ if (! ret)
+ FATAL ((stderr, _("AREPEAT without a AENDR at %d.\n"), line - 1));
+ if (rc > 0)
+ {
+ /* Push back the text following the repeat, and another repeat block
+ so
+ .AREPEAT 20
+ foo
+ .AENDR
+ gets turned into
+ foo
+ .AREPEAT 19
+ foo
+ .AENDR
+ */
+ int index = include_next_index ();
+ sb_add_sb (&copy, &sub);
+ if (rc > 1)
+ {
+ if (!mri)
+ sprintf (buffer, "\t.AREPEAT %d\n", rc - 1);
+ else
+ sprintf (buffer, "\tREPT %d\n", rc - 1);
+ sb_add_string (&copy, buffer);
+ sb_add_sb (&copy, &sub);
+ if (!mri)
+ sb_add_string (&copy, " .AENDR\n");
+ else
+ sb_add_string (&copy, " ENDR\n");
+ }
+
+ include_buf (&exp, &copy, include_repeat, index);
+ }
+ sb_kill (&exp);
+ sb_kill (&sub);
+ sb_kill (&copy);
+}
+
+/* .ENDM */
+
+static void
+do_endm ()
+{
+ ERROR ((stderr, _(".ENDM without a matching .MACRO.\n")));
+}
+
+/* MRI IRP pseudo-op. */
+
+static void
+do_irp (idx, in, irpc)
+ int idx;
+ sb *in;
+ int irpc;
+{
+ const char *err;
+ sb out;
+
+ sb_new (&out);
+
+ err = expand_irp (irpc, idx, in, &out, get_line, comment_char);
+ if (err != NULL)
+ ERROR ((stderr, "%s\n", err));
+
+ fprintf (outfile, "%s", sb_terminate (&out));
+
+ sb_kill (&out);
+}
+
+/* Macro processing. */
+
+/* Parse off LOCAL n1, n2,... Invent a label name for it. */
+
+static void
+do_local (idx, line)
+ int idx ATTRIBUTE_UNUSED;
+ sb *line ATTRIBUTE_UNUSED;
+{
+ ERROR ((stderr, _("LOCAL outside of MACRO")));
+}
+
+static void
+do_macro (idx, in)
+ int idx;
+ sb *in;
+{
+ const char *err;
+ int line = linecount ();
+
+ err = define_macro (idx, in, &label, get_line, (const char **) NULL);
+ if (err != NULL)
+ ERROR ((stderr, _("macro at line %d: %s\n"), line - 1, err));
+}
+
+static int
+macro_op (idx, in)
+ int idx;
+ sb *in;
+{
+ const char *err;
+ sb out;
+ sb name;
+
+ if (! macro_defined)
+ return 0;
+
+ sb_terminate (in);
+ if (! check_macro (in->ptr + idx, &out, comment_char, &err, NULL))
+ return 0;
+
+ if (err != NULL)
+ ERROR ((stderr, "%s\n", err));
+
+ sb_new (&name);
+ sb_add_string (&name, _("macro expansion"));
+
+ include_buf (&name, &out, include_macro, include_next_index ());
+
+ sb_kill (&name);
+ sb_kill (&out);
+
+ return 1;
+}
+
+/* String handling. */
+
+static int
+getstring (idx, in, acc)
+ int idx;
+ sb *in;
+ sb *acc;
+{
+ idx = sb_skip_white (idx, in);
+
+ while (idx < in->len
+ && (in->ptr[idx] == '"'
+ || in->ptr[idx] == '<'
+ || (in->ptr[idx] == '\'' && alternate)))
+ {
+ if (in->ptr[idx] == '<')
+ {
+ if (alternate || mri)
+ {
+ int nest = 0;
+ idx++;
+ while ((in->ptr[idx] != '>' || nest)
+ && idx < in->len)
+ {
+ if (in->ptr[idx] == '!')
+ {
+ idx++;
+ sb_add_char (acc, in->ptr[idx++]);
+ }
+ else
+ {
+ if (in->ptr[idx] == '>')
+ nest--;
+ if (in->ptr[idx] == '<')
+ nest++;
+ sb_add_char (acc, in->ptr[idx++]);
+ }
+ }
+ idx++;
+ }
+ else
+ {
+ int code;
+ idx++;
+ idx = exp_get_abs (_("Character code in string must be absolute expression.\n"),
+ idx, in, &code);
+ sb_add_char (acc, code);
+
+ if (in->ptr[idx] != '>')
+ ERROR ((stderr, _("Missing > for character code.\n")));
+ idx++;
+ }
+ }
+ else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
+ {
+ char tchar = in->ptr[idx];
+ idx++;
+ while (idx < in->len)
+ {
+ if (alternate && in->ptr[idx] == '!')
+ {
+ idx++;
+ sb_add_char (acc, in->ptr[idx++]);
+ }
+ else
+ {
+ if (in->ptr[idx] == tchar)
+ {
+ idx++;
+ if (idx >= in->len || in->ptr[idx] != tchar)
+ break;
+ }
+ sb_add_char (acc, in->ptr[idx]);
+ idx++;
+ }
+ }
+ }
+ }
+
+ return idx;
+}
+
+/* .SDATA[C|Z] <string> */
+
+static void
+do_sdata (idx, in, type)
+ int idx;
+ sb *in;
+ int type;
+{
+ int nc = 0;
+ int pidx = -1;
+ sb acc;
+ sb_new (&acc);
+ fprintf (outfile, ".byte\t");
+
+ while (!eol (idx, in))
+ {
+ int i;
+ sb_reset (&acc);
+ idx = sb_skip_white (idx, in);
+ while (!eol (idx, in))
+ {
+ pidx = idx = get_any_string (idx, in, &acc, 0, 1);
+ if (type == 'c')
+ {
+ if (acc.len > 255)
+ {
+ ERROR ((stderr, _("string for SDATAC longer than 255 characters (%d).\n"), acc.len));
+ }
+ fprintf (outfile, "%d", acc.len);
+ nc = 1;
+ }
+
+ for (i = 0; i < acc.len; i++)
+ {
+ if (nc)
+ {
+ fprintf (outfile, ",");
+ }
+ fprintf (outfile, "%d", acc.ptr[i]);
+ nc = 1;
+ }
+
+ if (type == 'z')
+ {
+ if (nc)
+ fprintf (outfile, ",");
+ fprintf (outfile, "0");
+ }
+ idx = sb_skip_comma (idx, in);
+ if (idx == pidx)
+ break;
+ }
+ if (!alternate && in->ptr[idx] != ',' && idx != in->len)
+ {
+ fprintf (outfile, "\n");
+ ERROR ((stderr, _("illegal character in SDATA line (0x%x).\n"),
+ in->ptr[idx]));
+ break;
+ }
+ idx++;
+ }
+ sb_kill (&acc);
+ fprintf (outfile, "\n");
+}
+
+/* .SDATAB <count> <string> */
+
+static void
+do_sdatab (idx, in)
+ int idx;
+ sb *in;
+{
+ int repeat;
+ int i;
+ sb acc;
+ sb_new (&acc);
+
+ idx = exp_get_abs (_("Must have absolute SDATAB repeat count.\n"), idx, in, &repeat);
+ if (repeat <= 0)
+ {
+ ERROR ((stderr, _("Must have positive SDATAB repeat count (%d).\n"), repeat));
+ repeat = 1;
+ }
+
+ idx = sb_skip_comma (idx, in);
+ idx = getstring (idx, in, &acc);
+
+ for (i = 0; i < repeat; i++)
+ {
+ if (i)
+ fprintf (outfile, "\t");
+ fprintf (outfile, ".byte\t");
+ sb_print (outfile, &acc);
+ fprintf (outfile, "\n");
+ }
+ sb_kill (&acc);
+
+}
+
+static int
+new_file (name)
+ const char *name;
+{
+ FILE *newone = fopen (name, "r");
+ if (!newone)
+ return 0;
+
+ if (isp == MAX_INCLUDES)
+ FATAL ((stderr, _("Unreasonable include depth (%ld).\n"), (long) isp));
+
+ sp++;
+ sp->handle = newone;
+
+ sb_new (&sp->name);
+ sb_add_string (&sp->name, name);
+
+ sp->linecount = 1;
+ sp->pushback_index = 0;
+ sp->type = include_file;
+ sp->index = 0;
+ sb_new (&sp->pushback);
+ return 1;
+}
+
+static void
+do_include (idx, in)
+ int idx;
+ sb *in;
+{
+ sb t;
+ sb cat;
+ include_path *includes;
+
+ sb_new (&t);
+ sb_new (&cat);
+
+ if (! mri)
+ idx = getstring (idx, in, &t);
+ else
+ {
+ idx = sb_skip_white (idx, in);
+ while (idx < in->len && ! ISWHITE (in->ptr[idx]))
+ {
+ sb_add_char (&t, in->ptr[idx]);
+ ++idx;
+ }
+ }
+
+ for (includes = paths_head; includes; includes = includes->next)
+ {
+ sb_reset (&cat);
+ sb_add_sb (&cat, &includes->path);
+ sb_add_char (&cat, '/');
+ sb_add_sb (&cat, &t);
+ if (new_file (sb_name (&cat)))
+ {
+ break;
+ }
+ }
+ if (!includes)
+ {
+ if (! new_file (sb_name (&t)))
+ FATAL ((stderr, _("Can't open include file `%s'.\n"), sb_name (&t)));
+ }
+ sb_kill (&cat);
+ sb_kill (&t);
+}
+
+static void
+include_pop ()
+{
+ if (sp != include_stack)
+ {
+ if (sp->handle)
+ fclose (sp->handle);
+ sp--;
+ }
+}
+
+/* Get the next character from the include stack. If there's anything
+ in the pushback buffer, take that first. If we're at eof, pop from
+ the stack and try again. Keep the linecount up to date. */
+
+static int
+get ()
+{
+ int r;
+
+ if (sp->pushback.len != sp->pushback_index)
+ {
+ r = (char) (sp->pushback.ptr[sp->pushback_index++]);
+ /* When they've all gone, reset the pointer. */
+ if (sp->pushback_index == sp->pushback.len)
+ {
+ sp->pushback.len = 0;
+ sp->pushback_index = 0;
+ }
+ }
+ else if (sp->handle)
+ {
+ r = getc (sp->handle);
+ }
+ else
+ r = EOF;
+
+ if (r == EOF && isp)
+ {
+ include_pop ();
+ r = get ();
+ while (r == EOF && isp)
+ {
+ include_pop ();
+ r = get ();
+ }
+ return r;
+ }
+ if (r == '\n')
+ {
+ sp->linecount++;
+ }
+
+ return r;
+}
+
+static int
+linecount ()
+{
+ return sp->linecount;
+}
+
+static int
+include_next_index ()
+{
+ static int index;
+ if (!unreasonable
+ && index > MAX_REASONABLE)
+ FATAL ((stderr, _("Unreasonable expansion (-u turns off check).\n")));
+ return ++index;
+}
+
+/* Initialize the chartype vector. */
+
+static void
+chartype_init ()
+{
+ int x;
+ for (x = 0; x < 256; x++)
+ {
+ if (ISALPHA (x) || x == '_' || x == '$')
+ chartype[x] |= FIRSTBIT;
+
+ if (mri && x == '.')
+ chartype[x] |= FIRSTBIT;
+
+ if (ISDIGIT (x) || ISALPHA (x) || x == '_' || x == '$')
+ chartype[x] |= NEXTBIT;
+
+ if (x == ' ' || x == '\t' || x == ',' || x == '"' || x == ';'
+ || x == '"' || x == '<' || x == '>' || x == ')' || x == '(')
+ chartype[x] |= SEPBIT;
+
+ if (x == 'b' || x == 'B'
+ || x == 'q' || x == 'Q'
+ || x == 'h' || x == 'H'
+ || x == 'd' || x == 'D')
+ chartype [x] |= BASEBIT;
+
+ if (x == ' ' || x == '\t')
+ chartype[x] |= WHITEBIT;
+
+ if (x == comment_char)
+ chartype[x] |= COMMENTBIT;
+ }
+}
+
+/* What to do with all the keywords. */
+#define PROCESS 0x1000 /* Run substitution over the line. */
+#define LAB 0x2000 /* Spit out the label. */
+
+#define K_EQU (PROCESS|1)
+#define K_ASSIGN (PROCESS|2)
+#define K_REG (PROCESS|3)
+#define K_ORG (PROCESS|4)
+#define K_RADIX (PROCESS|5)
+#define K_DATA (LAB|PROCESS|6)
+#define K_DATAB (LAB|PROCESS|7)
+#define K_SDATA (LAB|PROCESS|8)
+#define K_SDATAB (LAB|PROCESS|9)
+#define K_SDATAC (LAB|PROCESS|10)
+#define K_SDATAZ (LAB|PROCESS|11)
+#define K_RES (LAB|PROCESS|12)
+#define K_SRES (LAB|PROCESS|13)
+#define K_SRESC (LAB|PROCESS|14)
+#define K_SRESZ (LAB|PROCESS|15)
+#define K_EXPORT (LAB|PROCESS|16)
+#define K_GLOBAL (LAB|PROCESS|17)
+#define K_PRINT (LAB|PROCESS|19)
+#define K_FORM (LAB|PROCESS|20)
+#define K_HEADING (LAB|PROCESS|21)
+#define K_PAGE (LAB|PROCESS|22)
+#define K_IMPORT (LAB|PROCESS|23)
+#define K_PROGRAM (LAB|PROCESS|24)
+#define K_END (PROCESS|25)
+#define K_INCLUDE (PROCESS|26)
+#define K_IGNORED (PROCESS|27)
+#define K_ASSIGNA (PROCESS|28)
+#define K_ASSIGNC (29)
+#define K_AIF (PROCESS|30)
+#define K_AELSE (PROCESS|31)
+#define K_AENDI (PROCESS|32)
+#define K_AREPEAT (PROCESS|33)
+#define K_AENDR (PROCESS|34)
+#define K_AWHILE (35)
+#define K_AENDW (PROCESS|36)
+#define K_EXITM (37)
+#define K_MACRO (PROCESS|38)
+#define K_ENDM (39)
+#define K_ALIGN (PROCESS|LAB|40)
+#define K_ALTERNATE (41)
+#define K_DB (LAB|PROCESS|42)
+#define K_DW (LAB|PROCESS|43)
+#define K_DL (LAB|PROCESS|44)
+#define K_LOCAL (45)
+#define K_IFEQ (PROCESS|46)
+#define K_IFNE (PROCESS|47)
+#define K_IFLT (PROCESS|48)
+#define K_IFLE (PROCESS|49)
+#define K_IFGE (PROCESS|50)
+#define K_IFGT (PROCESS|51)
+#define K_IFC (PROCESS|52)
+#define K_IFNC (PROCESS|53)
+#define K_IRP (PROCESS|54)
+#define K_IRPC (PROCESS|55)
+
+struct keyword {
+ char *name;
+ int code;
+ int extra;
+};
+
+static struct keyword kinfo[] = {
+ { "EQU", K_EQU, 0 },
+ { "ALTERNATE", K_ALTERNATE, 0 },
+ { "ASSIGN", K_ASSIGN, 0 },
+ { "REG", K_REG, 0 },
+ { "ORG", K_ORG, 0 },
+ { "RADIX", K_RADIX, 0 },
+ { "DATA", K_DATA, 0 },
+ { "DB", K_DB, 0 },
+ { "DW", K_DW, 0 },
+ { "DL", K_DL, 0 },
+ { "DATAB", K_DATAB, 0 },
+ { "SDATA", K_SDATA, 0 },
+ { "SDATAB", K_SDATAB, 0 },
+ { "SDATAZ", K_SDATAZ, 0 },
+ { "SDATAC", K_SDATAC, 0 },
+ { "RES", K_RES, 0 },
+ { "SRES", K_SRES, 0 },
+ { "SRESC", K_SRESC, 0 },
+ { "SRESZ", K_SRESZ, 0 },
+ { "EXPORT", K_EXPORT, 0 },
+ { "GLOBAL", K_GLOBAL, 0 },
+ { "PRINT", K_PRINT, 0 },
+ { "FORM", K_FORM, 0 },
+ { "HEADING", K_HEADING, 0 },
+ { "PAGE", K_PAGE, 0 },
+ { "PROGRAM", K_IGNORED, 0 },
+ { "END", K_END, 0 },
+ { "INCLUDE", K_INCLUDE, 0 },
+ { "ASSIGNA", K_ASSIGNA, 0 },
+ { "ASSIGNC", K_ASSIGNC, 0 },
+ { "AIF", K_AIF, 0 },
+ { "AELSE", K_AELSE, 0 },
+ { "AENDI", K_AENDI, 0 },
+ { "AREPEAT", K_AREPEAT, 0 },
+ { "AENDR", K_AENDR, 0 },
+ { "EXITM", K_EXITM, 0 },
+ { "MACRO", K_MACRO, 0 },
+ { "ENDM", K_ENDM, 0 },
+ { "AWHILE", K_AWHILE, 0 },
+ { "ALIGN", K_ALIGN, 0 },
+ { "AENDW", K_AENDW, 0 },
+ { "ALTERNATE", K_ALTERNATE, 0 },
+ { "LOCAL", K_LOCAL, 0 },
+ { NULL, 0, 0 }
+};
+
+/* Although the conditional operators are handled by gas, we need to
+ handle them here as well, in case they are used in a recursive
+ macro to end the recursion. */
+
+static struct keyword mrikinfo[] = {
+ { "IFEQ", K_IFEQ, 0 },
+ { "IFNE", K_IFNE, 0 },
+ { "IFLT", K_IFLT, 0 },
+ { "IFLE", K_IFLE, 0 },
+ { "IFGE", K_IFGE, 0 },
+ { "IFGT", K_IFGT, 0 },
+ { "IFC", K_IFC, 0 },
+ { "IFNC", K_IFNC, 0 },
+ { "ELSEC", K_AELSE, 0 },
+ { "ENDC", K_AENDI, 0 },
+ { "MEXIT", K_EXITM, 0 },
+ { "REPT", K_AREPEAT, 0 },
+ { "IRP", K_IRP, 0 },
+ { "IRPC", K_IRPC, 0 },
+ { "ENDR", K_AENDR, 0 },
+ { NULL, 0, 0 }
+};
+
+/* Look for a pseudo op on the line. If one's there then call
+ its handler. */
+
+static int
+process_pseudo_op (idx, line, acc)
+ int idx;
+ sb *line;
+ sb *acc;
+{
+ int oidx = idx;
+
+ if (line->ptr[idx] == '.' || alternate || mri)
+ {
+ /* Scan forward and find pseudo name. */
+ char *in;
+ hash_entry *ptr;
+
+ char *s;
+ char *e;
+ if (line->ptr[idx] == '.')
+ idx++;
+ in = line->ptr + idx;
+ s = in;
+ e = s;
+ sb_reset (acc);
+
+ while (idx < line->len && *e && ISFIRSTCHAR (*e))
+ {
+ sb_add_char (acc, *e);
+ e++;
+ idx++;
+ }
+
+ ptr = hash_lookup (&keyword_hash_table, acc);
+
+ if (!ptr)
+ {
+#if 0
+ /* This one causes lots of pain when trying to preprocess
+ ordinary code. */
+ WARNING ((stderr, _("Unrecognised pseudo op `%s'.\n"),
+ sb_name (acc)));
+#endif
+ return 0;
+ }
+ if (ptr->value.i & LAB)
+ {
+ /* Output the label. */
+ if (label.len)
+ {
+ fprintf (outfile, "%s:\t", sb_name (&label));
+ }
+ else
+ fprintf (outfile, "\t");
+ }
+
+ if (mri && ptr->value.i == K_END)
+ {
+ sb t;
+
+ sb_new (&t);
+ sb_add_buffer (&t, line->ptr + oidx, idx - oidx);
+ fprintf (outfile, "\t%s", sb_name (&t));
+ sb_kill (&t);
+ }
+
+ if (ptr->value.i & PROCESS)
+ {
+ /* Polish the rest of the line before handling the pseudo op. */
+#if 0
+ strip_comments (line);
+#endif
+ sb_reset (acc);
+ process_assigns (idx, line, acc);
+ sb_reset (line);
+ change_base (0, acc, line);
+ idx = 0;
+ }
+ if (!condass_on ())
+ {
+ switch (ptr->value.i)
+ {
+ case K_AIF:
+ do_aif (idx, line);
+ break;
+ case K_AELSE:
+ do_aelse ();
+ break;
+ case K_AENDI:
+ do_aendi ();
+ break;
+ }
+ return 1;
+ }
+ else
+ {
+ switch (ptr->value.i)
+ {
+ case K_ALTERNATE:
+ alternate = 1;
+ macro_init (1, mri, 0, exp_get_abs);
+ return 1;
+ case K_AELSE:
+ do_aelse ();
+ return 1;
+ case K_AENDI:
+ do_aendi ();
+ return 1;
+ case K_ORG:
+ ERROR ((stderr, _("ORG command not allowed.\n")));
+ break;
+ case K_RADIX:
+ do_radix (line);
+ return 1;
+ case K_DB:
+ do_data (idx, line, 1);
+ return 1;
+ case K_DW:
+ do_data (idx, line, 2);
+ return 1;
+ case K_DL:
+ do_data (idx, line, 4);
+ return 1;
+ case K_DATA:
+ do_data (idx, line, 0);
+ return 1;
+ case K_DATAB:
+ do_datab (idx, line);
+ return 1;
+ case K_SDATA:
+ do_sdata (idx, line, 0);
+ return 1;
+ case K_SDATAB:
+ do_sdatab (idx, line);
+ return 1;
+ case K_SDATAC:
+ do_sdata (idx, line, 'c');
+ return 1;
+ case K_SDATAZ:
+ do_sdata (idx, line, 'z');
+ return 1;
+ case K_ASSIGN:
+ do_assign (0, 0, line);
+ return 1;
+ case K_AIF:
+ do_aif (idx, line);
+ return 1;
+ case K_AREPEAT:
+ do_arepeat (idx, line);
+ return 1;
+ case K_AENDW:
+ do_aendw ();
+ return 1;
+ case K_AWHILE:
+ do_awhile (idx, line);
+ return 1;
+ case K_AENDR:
+ do_aendr ();
+ return 1;
+ case K_EQU:
+ do_assign (1, idx, line);
+ return 1;
+ case K_ALIGN:
+ do_align (idx, line);
+ return 1;
+ case K_RES:
+ do_res (idx, line, 0);
+ return 1;
+ case K_SRES:
+ do_res (idx, line, 's');
+ return 1;
+ case K_INCLUDE:
+ do_include (idx, line);
+ return 1;
+ case K_LOCAL:
+ do_local (idx, line);
+ return 1;
+ case K_MACRO:
+ do_macro (idx, line);
+ return 1;
+ case K_ENDM:
+ do_endm ();
+ return 1;
+ case K_SRESC:
+ do_res (idx, line, 'c');
+ return 1;
+ case K_PRINT:
+ do_print (idx, line);
+ return 1;
+ case K_FORM:
+ do_form (idx, line);
+ return 1;
+ case K_HEADING:
+ do_heading (idx, line);
+ return 1;
+ case K_PAGE:
+ do_page ();
+ return 1;
+ case K_GLOBAL:
+ case K_EXPORT:
+ do_export (line);
+ return 1;
+ case K_IMPORT:
+ return 1;
+ case K_SRESZ:
+ do_res (idx, line, 'z');
+ return 1;
+ case K_IGNORED:
+ return 1;
+ case K_END:
+ do_end (line);
+ return 1;
+ case K_ASSIGNA:
+ do_assigna (idx, line);
+ return 1;
+ case K_ASSIGNC:
+ do_assignc (idx, line);
+ return 1;
+ case K_EXITM:
+ do_exitm ();
+ return 1;
+ case K_REG:
+ do_reg (idx, line);
+ return 1;
+ case K_IFEQ:
+ do_if (idx, line, EQ);
+ return 1;
+ case K_IFNE:
+ do_if (idx, line, NE);
+ return 1;
+ case K_IFLT:
+ do_if (idx, line, LT);
+ return 1;
+ case K_IFLE:
+ do_if (idx, line, LE);
+ return 1;
+ case K_IFGE:
+ do_if (idx, line, GE);
+ return 1;
+ case K_IFGT:
+ do_if (idx, line, GT);
+ return 1;
+ case K_IFC:
+ do_ifc (idx, line, 0);
+ return 1;
+ case K_IFNC:
+ do_ifc (idx, line, 1);
+ return 1;
+ case K_IRP:
+ do_irp (idx, line, 0);
+ return 1;
+ case K_IRPC:
+ do_irp (idx, line, 1);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/* Add a keyword to the hash table. */
+
+static void
+add_keyword (name, code)
+ const char *name;
+ int code;
+{
+ sb label;
+ int j;
+
+ sb_new (&label);
+ sb_add_string (&label, name);
+
+ hash_add_to_int_table (&keyword_hash_table, &label, code);
+
+ sb_reset (&label);
+ for (j = 0; name[j]; j++)
+ sb_add_char (&label, name[j] - 'A' + 'a');
+ hash_add_to_int_table (&keyword_hash_table, &label, code);
+
+ sb_kill (&label);
+}
+
+/* Build the keyword hash table - put each keyword in the table twice,
+ once upper and once lower case. */
+
+static void
+process_init ()
+{
+ int i;
+
+ for (i = 0; kinfo[i].name; i++)
+ add_keyword (kinfo[i].name, kinfo[i].code);
+
+ if (mri)
+ {
+ for (i = 0; mrikinfo[i].name; i++)
+ add_keyword (mrikinfo[i].name, mrikinfo[i].code);
+ }
+}
+
+static void
+do_define (string)
+ const char *string;
+{
+ sb label;
+ int res = 1;
+ hash_entry *ptr;
+ sb_new (&label);
+
+ while (*string)
+ {
+ if (*string == '=')
+ {
+ sb value;
+ sb_new (&value);
+ string++;
+ while (*string)
+ {
+ sb_add_char (&value, *string);
+ string++;
+ }
+ exp_get_abs (_("Invalid expression on command line.\n"),
+ 0, &value, &res);
+ sb_kill (&value);
+ break;
+ }
+ sb_add_char (&label, *string);
+
+ string++;
+ }
+
+ ptr = hash_create (&vars, &label);
+ free_old_entry (ptr);
+ ptr->type = hash_integer;
+ ptr->value.i = res;
+ sb_kill (&label);
+}
+
+char *program_name;
+
+/* The list of long options. */
+static struct option long_options[] =
+{
+ { "alternate", no_argument, 0, 'a' },
+ { "include", required_argument, 0, 'I' },
+ { "commentchar", required_argument, 0, 'c' },
+ { "copysource", no_argument, 0, 's' },
+ { "debug", no_argument, 0, 'd' },
+ { "help", no_argument, 0, 'h' },
+ { "mri", no_argument, 0, 'M' },
+ { "output", required_argument, 0, 'o' },
+ { "print", no_argument, 0, 'p' },
+ { "unreasonable", no_argument, 0, 'u' },
+ { "version", no_argument, 0, 'v' },
+ { "define", required_argument, 0, 'd' },
+ { NULL, no_argument, 0, 0 }
+};
+
+/* Show a usage message and exit. */
+static void
+show_usage (file, status)
+ FILE *file;
+ int status;
+{
+ fprintf (file, _("\
+Usage: %s \n\
+ [-a] [--alternate] enter alternate macro mode\n\
+ [-c char] [--commentchar char] change the comment character from !\n\
+ [-d] [--debug] print some debugging info\n\
+ [-h] [--help] print this message\n\
+ [-M] [--mri] enter MRI compatibility mode\n\
+ [-o out] [--output out] set the output file\n\
+ [-p] [--print] print line numbers\n"), program_name);
+ fprintf (file, _("\
+ [-s] [--copysource] copy source through as comments \n\
+ [-u] [--unreasonable] allow unreasonable nesting\n\
+ [-v] [--version] print the program version\n\
+ [-Dname=value] create preprocessor variable called name, with value\n\
+ [-Ipath] add to include path list\n\
+ [in-file]\n"));
+ if (status == 0)
+ printf (_("Report bugs to %s\n"), REPORT_BUGS_TO);
+ exit (status);
+}
+
+/* Display a help message and exit. */
+
+static void
+show_help ()
+{
+ printf (_("%s: Gnu Assembler Macro Preprocessor\n"), program_name);
+ show_usage (stdout, 0);
+}
+
+int main PARAMS ((int, char **));
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int opt;
+ char *out_name = 0;
+ sp = include_stack;
+
+ ifstack[0].on = 1;
+ ifi = 0;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+#if defined (HAVE_SETLOCALE)
+ setlocale (LC_CTYPE, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = argv[0];
+ xmalloc_set_program_name (program_name);
+
+ hash_new_table (101, &keyword_hash_table);
+ hash_new_table (101, &assign_hash_table);
+ hash_new_table (101, &vars);
+
+ sb_new (&label);
+
+ while ((opt = getopt_long (argc, argv, "I:sdhavc:upo:D:M", long_options,
+ (int *) NULL))
+ != EOF)
+ {
+ switch (opt)
+ {
+ case 'o':
+ out_name = optarg;
+ break;
+ case 'u':
+ unreasonable = 1;
+ break;
+ case 'I':
+ {
+ include_path *p = (include_path *) xmalloc (sizeof (include_path));
+ p->next = NULL;
+ sb_new (&p->path);
+ sb_add_string (&p->path, optarg);
+ if (paths_tail)
+ paths_tail->next = p;
+ else
+ paths_head = p;
+ paths_tail = p;
+ }
+ break;
+ case 'p':
+ print_line_number = 1;
+ break;
+ case 'c':
+ comment_char = optarg[0];
+ break;
+ case 'a':
+ alternate = 1;
+ break;
+ case 's':
+ copysource = 1;
+ break;
+ case 'd':
+ stats = 1;
+ break;
+ case 'D':
+ do_define (optarg);
+ break;
+ case 'M':
+ mri = 1;
+ comment_char = ';';
+ break;
+ case 'h':
+ show_help ();
+ /* NOTREACHED */
+ case 'v':
+ /* This output is intended to follow the GNU standards document. */
+ printf (_("GNU assembler pre-processor %s\n"), program_version);
+ printf (_("Copyright 1996 Free Software Foundation, Inc.\n"));
+ printf (_("\
+This program is free software; you may redistribute it under the terms of\n\
+the GNU General Public License. This program has absolutely no warranty.\n"));
+ exit (0);
+ /* NOTREACHED */
+ case 0:
+ break;
+ default:
+ show_usage (stderr, 1);
+ /* NOTREACHED */
+ }
+ }
+
+ process_init ();
+
+ macro_init (alternate, mri, 0, exp_get_abs);
+
+ if (out_name)
+ {
+ outfile = fopen (out_name, "w");
+ if (!outfile)
+ {
+ fprintf (stderr, _("%s: Can't open output file `%s'.\n"),
+ program_name, out_name);
+ exit (1);
+ }
+ }
+ else
+ {
+ outfile = stdout;
+ }
+
+ chartype_init ();
+ if (!outfile)
+ outfile = stdout;
+
+ /* Process all the input files. */
+
+ while (optind < argc)
+ {
+ if (new_file (argv[optind]))
+ {
+ process_file ();
+ }
+ else
+ {
+ fprintf (stderr, _("%s: Can't open input file `%s'.\n"),
+ program_name, argv[optind]);
+ exit (1);
+ }
+ optind++;
+ }
+
+ quit ();
+ return 0;
+}
+
+/* This function is used because an abort in some of the other files
+ may be compiled into as_abort because they include as.h. */
+
+void
+as_abort (file, line, fn)
+ const char *file, *fn;
+ int line;
+{
+ fprintf (stderr, _("Internal error, aborting at %s line %d"), file, line);
+ if (fn)
+ fprintf (stderr, " in %s", fn);
+ fprintf (stderr, _("\nPlease report this bug.\n"));
+ exit (1);
+}
diff --git a/x/binutils/gas/gdbinit.in b/x/binutils/gas/gdbinit.in
new file mode 100644
index 0000000..e946726
--- /dev/null
+++ b/x/binutils/gas/gdbinit.in
@@ -0,0 +1,39 @@
+dir @srcdir@
+dir .
+
+break as_warn
+break as_warn_where
+break as_bad
+break as_bad_where
+break as_fatal
+break as_perror
+break as_assert
+break as_abort
+
+define pe
+call print_expr ($)
+end
+
+document pe
+Print *$ as an expressionS, expanding parameters.
+end
+
+define ps
+call print_symbol_value ($)
+end
+
+document ps
+Print *$ as a symbolS, including expression value.
+end
+
+define pf
+call print_fixup ($)
+end
+
+document pf
+Print *$ as a fixS, including symbol value.
+end
+
+# Put this last, in case it fails.
+
+break abort
diff --git a/x/binutils/gas/hash.c b/x/binutils/gas/hash.c
new file mode 100644
index 0000000..a7b8298
--- /dev/null
+++ b/x/binutils/gas/hash.c
@@ -0,0 +1,579 @@
+/* hash.c -- gas hash table code
+ Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
+ 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This version of the hash table code is a wholescale replacement of
+ the old hash table code, which was fairly bad. This is based on
+ the hash table code in BFD, but optimized slightly for the
+ assembler. The assembler does not need to derive structures that
+ are stored in the hash table. Instead, it always stores a pointer.
+ The assembler uses the hash table mostly to store symbols, and we
+ don't need to confuse the symbol structure with a hash table
+ structure. */
+
+#include "as.h"
+#include "safe-ctype.h"
+#include "obstack.h"
+
+/* The default number of entries to use when creating a hash table. */
+
+#define DEFAULT_SIZE (4051)
+
+/* An entry in a hash table. */
+
+struct hash_entry {
+ /* Next entry for this hash code. */
+ struct hash_entry *next;
+ /* String being hashed. */
+ const char *string;
+ /* Hash code. This is the full hash code, not the index into the
+ table. */
+ unsigned long hash;
+ /* Pointer being stored in the hash table. */
+ PTR data;
+};
+
+/* A hash table. */
+
+struct hash_control {
+ /* The hash array. */
+ struct hash_entry **table;
+ /* The number of slots in the hash table. */
+ unsigned int size;
+ /* An obstack for this hash table. */
+ struct obstack memory;
+
+#ifdef HASH_STATISTICS
+ /* Statistics. */
+ unsigned long lookups;
+ unsigned long hash_compares;
+ unsigned long string_compares;
+ unsigned long insertions;
+ unsigned long replacements;
+ unsigned long deletions;
+#endif /* HASH_STATISTICS */
+};
+
+/* Create a hash table. This return a control block. */
+
+struct hash_control *
+hash_new (void)
+{
+ unsigned int size;
+ struct hash_control *ret;
+ unsigned int alloc;
+
+ size = DEFAULT_SIZE;
+
+ ret = (struct hash_control *) xmalloc (sizeof *ret);
+ obstack_begin (&ret->memory, chunksize);
+ alloc = size * sizeof (struct hash_entry *);
+ ret->table = (struct hash_entry **) obstack_alloc (&ret->memory, alloc);
+ memset (ret->table, 0, alloc);
+ ret->size = size;
+
+#ifdef HASH_STATISTICS
+ ret->lookups = 0;
+ ret->hash_compares = 0;
+ ret->string_compares = 0;
+ ret->insertions = 0;
+ ret->replacements = 0;
+ ret->deletions = 0;
+#endif
+
+ return ret;
+}
+
+/* Delete a hash table, freeing all allocated memory. */
+
+void
+hash_die (struct hash_control *table)
+{
+ obstack_free (&table->memory, 0);
+ free (table);
+}
+
+/* Look up a string in a hash table. This returns a pointer to the
+ hash_entry, or NULL if the string is not in the table. If PLIST is
+ not NULL, this sets *PLIST to point to the start of the list which
+ would hold this hash entry. If PHASH is not NULL, this sets *PHASH
+ to the hash code for KEY.
+
+ Each time we look up a string, we move it to the start of the list
+ for its hash code, to take advantage of referential locality. */
+
+static struct hash_entry *hash_lookup (struct hash_control *,
+ const char *,
+ struct hash_entry ***,
+ unsigned long *);
+
+static struct hash_entry *
+hash_lookup (struct hash_control *table, const char *key,
+ struct hash_entry ***plist, unsigned long *phash)
+{
+ register unsigned long hash;
+ unsigned int len;
+ register const unsigned char *s;
+ register unsigned int c;
+ unsigned int index;
+ struct hash_entry **list;
+ struct hash_entry *p;
+ struct hash_entry *prev;
+
+#ifdef HASH_STATISTICS
+ ++table->lookups;
+#endif
+
+ hash = 0;
+ len = 0;
+ s = (const unsigned char *) key;
+ while ((c = *s++) != '\0')
+ {
+ hash += c + (c << 17);
+ hash ^= hash >> 2;
+ ++len;
+ }
+ hash += len + (len << 17);
+ hash ^= hash >> 2;
+
+ if (phash != NULL)
+ *phash = hash;
+
+ index = hash % table->size;
+ list = table->table + index;
+
+ if (plist != NULL)
+ *plist = list;
+
+ prev = NULL;
+ for (p = *list; p != NULL; p = p->next)
+ {
+#ifdef HASH_STATISTICS
+ ++table->hash_compares;
+#endif
+
+ if (p->hash == hash)
+ {
+#ifdef HASH_STATISTICS
+ ++table->string_compares;
+#endif
+
+ if (strcmp (p->string, key) == 0)
+ {
+ if (prev != NULL)
+ {
+ prev->next = p->next;
+ p->next = *list;
+ *list = p;
+ }
+
+ return p;
+ }
+ }
+
+ prev = p;
+ }
+
+ return NULL;
+}
+
+/* Insert an entry into a hash table. This returns NULL on success.
+ On error, it returns a printable string indicating the error. It
+ is considered to be an error if the entry already exists in the
+ hash table. */
+
+const char *
+hash_insert (struct hash_control *table, const char *key, PTR value)
+{
+ struct hash_entry *p;
+ struct hash_entry **list;
+ unsigned long hash;
+
+ p = hash_lookup (table, key, &list, &hash);
+ if (p != NULL)
+ return "exists";
+
+#ifdef HASH_STATISTICS
+ ++table->insertions;
+#endif
+
+ p = (struct hash_entry *) obstack_alloc (&table->memory, sizeof (*p));
+ p->string = key;
+ p->hash = hash;
+ p->data = value;
+
+ p->next = *list;
+ *list = p;
+
+ return NULL;
+}
+
+/* Insert or replace an entry in a hash table. This returns NULL on
+ success. On error, it returns a printable string indicating the
+ error. If an entry already exists, its value is replaced. */
+
+const char *
+hash_jam (struct hash_control *table, const char *key, PTR value)
+{
+ struct hash_entry *p;
+ struct hash_entry **list;
+ unsigned long hash;
+
+ p = hash_lookup (table, key, &list, &hash);
+ if (p != NULL)
+ {
+#ifdef HASH_STATISTICS
+ ++table->replacements;
+#endif
+
+ p->data = value;
+ }
+ else
+ {
+#ifdef HASH_STATISTICS
+ ++table->insertions;
+#endif
+
+ p = (struct hash_entry *) obstack_alloc (&table->memory, sizeof (*p));
+ p->string = key;
+ p->hash = hash;
+ p->data = value;
+
+ p->next = *list;
+ *list = p;
+ }
+
+ return NULL;
+}
+
+/* Replace an existing entry in a hash table. This returns the old
+ value stored for the entry. If the entry is not found in the hash
+ table, this does nothing and returns NULL. */
+
+PTR
+hash_replace (struct hash_control *table, const char *key, PTR value)
+{
+ struct hash_entry *p;
+ PTR ret;
+
+ p = hash_lookup (table, key, NULL, NULL);
+ if (p == NULL)
+ return NULL;
+
+#ifdef HASH_STATISTICS
+ ++table->replacements;
+#endif
+
+ ret = p->data;
+
+ p->data = value;
+
+ return ret;
+}
+
+/* Find an entry in a hash table, returning its value. Returns NULL
+ if the entry is not found. */
+
+PTR
+hash_find (struct hash_control *table, const char *key)
+{
+ struct hash_entry *p;
+
+ p = hash_lookup (table, key, NULL, NULL);
+ if (p == NULL)
+ return NULL;
+
+ return p->data;
+}
+
+/* Delete an entry from a hash table. This returns the value stored
+ for that entry, or NULL if there is no such entry. */
+
+PTR
+hash_delete (struct hash_control *table, const char *key)
+{
+ struct hash_entry *p;
+ struct hash_entry **list;
+
+ p = hash_lookup (table, key, &list, NULL);
+ if (p == NULL)
+ return NULL;
+
+ if (p != *list)
+ abort ();
+
+#ifdef HASH_STATISTICS
+ ++table->deletions;
+#endif
+
+ *list = p->next;
+
+ /* Note that we never reclaim the memory for this entry. If gas
+ ever starts deleting hash table entries in a big way, this will
+ have to change. */
+
+ return p->data;
+}
+
+/* Traverse a hash table. Call the function on every entry in the
+ hash table. */
+
+void
+hash_traverse (struct hash_control *table,
+ void (*pfn) (const char *key, PTR value))
+{
+ unsigned int i;
+
+ for (i = 0; i < table->size; ++i)
+ {
+ struct hash_entry *p;
+
+ for (p = table->table[i]; p != NULL; p = p->next)
+ (*pfn) (p->string, p->data);
+ }
+}
+
+/* Print hash table statistics on the specified file. NAME is the
+ name of the hash table, used for printing a header. */
+
+void
+hash_print_statistics (FILE *f ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ struct hash_control *table ATTRIBUTE_UNUSED)
+{
+#ifdef HASH_STATISTICS
+ unsigned int i;
+ unsigned long total;
+ unsigned long empty;
+
+ fprintf (f, "%s hash statistics:\n", name);
+ fprintf (f, "\t%lu lookups\n", table->lookups);
+ fprintf (f, "\t%lu hash comparisons\n", table->hash_compares);
+ fprintf (f, "\t%lu string comparisons\n", table->string_compares);
+ fprintf (f, "\t%lu insertions\n", table->insertions);
+ fprintf (f, "\t%lu replacements\n", table->replacements);
+ fprintf (f, "\t%lu deletions\n", table->deletions);
+
+ total = 0;
+ empty = 0;
+ for (i = 0; i < table->size; ++i)
+ {
+ struct hash_entry *p;
+
+ if (table->table[i] == NULL)
+ ++empty;
+ else
+ {
+ for (p = table->table[i]; p != NULL; p = p->next)
+ ++total;
+ }
+ }
+
+ fprintf (f, "\t%g average chain length\n", (double) total / table->size);
+ fprintf (f, "\t%lu empty slots\n", empty);
+#endif
+}
+
+#ifdef TEST
+
+/* This test program is left over from the old hash table code. */
+
+/* Number of hash tables to maintain (at once) in any testing. */
+#define TABLES (6)
+
+/* We can have 12 statistics. */
+#define STATBUFSIZE (12)
+
+/* Display statistics here. */
+int statbuf[STATBUFSIZE];
+
+/* Human farts here. */
+char answer[100];
+
+/* We test many hash tables at once. */
+char *hashtable[TABLES];
+
+/* Points to current hash_control. */
+char *h;
+char **pp;
+char *p;
+char *name;
+char *value;
+int size;
+int used;
+char command;
+
+/* Number 0:TABLES-1 of current hashed symbol table. */
+int number;
+
+int
+main ()
+{
+ void applicatee ();
+ void destroy ();
+ char *what ();
+ int *ip;
+
+ number = 0;
+ h = 0;
+ printf ("type h <RETURN> for help\n");
+ for (;;)
+ {
+ printf ("hash_test command: ");
+ gets (answer);
+ command = answer[0];
+ command = TOLOWER (command); /* Ecch! */
+ switch (command)
+ {
+ case '#':
+ printf ("old hash table #=%d.\n", number);
+ whattable ();
+ break;
+ case '?':
+ for (pp = hashtable; pp < hashtable + TABLES; pp++)
+ {
+ printf ("address of hash table #%d control block is %xx\n",
+ pp - hashtable, *pp);
+ }
+ break;
+ case 'a':
+ hash_traverse (h, applicatee);
+ break;
+ case 'd':
+ hash_traverse (h, destroy);
+ hash_die (h);
+ break;
+ case 'f':
+ p = hash_find (h, name = what ("symbol"));
+ printf ("value of \"%s\" is \"%s\"\n", name, p ? p : "NOT-PRESENT");
+ break;
+ case 'h':
+ printf ("# show old, select new default hash table number\n");
+ printf ("? display all hashtable control block addresses\n");
+ printf ("a apply a simple display-er to each symbol in table\n");
+ printf ("d die: destroy hashtable\n");
+ printf ("f find value of nominated symbol\n");
+ printf ("h this help\n");
+ printf ("i insert value into symbol\n");
+ printf ("j jam value into symbol\n");
+ printf ("n new hashtable\n");
+ printf ("r replace a value with another\n");
+ printf ("s say what %% of table is used\n");
+ printf ("q exit this program\n");
+ printf ("x delete a symbol from table, report its value\n");
+ break;
+ case 'i':
+ p = hash_insert (h, name = what ("symbol"), value = what ("value"));
+ if (p)
+ {
+ printf ("symbol=\"%s\" value=\"%s\" error=%s\n", name, value,
+ p);
+ }
+ break;
+ case 'j':
+ p = hash_jam (h, name = what ("symbol"), value = what ("value"));
+ if (p)
+ {
+ printf ("symbol=\"%s\" value=\"%s\" error=%s\n", name, value, p);
+ }
+ break;
+ case 'n':
+ h = hashtable[number] = (char *) hash_new ();
+ break;
+ case 'q':
+ exit (EXIT_SUCCESS);
+ case 'r':
+ p = hash_replace (h, name = what ("symbol"), value = what ("value"));
+ printf ("old value was \"%s\"\n", p ? p : "{}");
+ break;
+ case 's':
+ hash_say (h, statbuf, STATBUFSIZE);
+ for (ip = statbuf; ip < statbuf + STATBUFSIZE; ip++)
+ {
+ printf ("%d ", *ip);
+ }
+ printf ("\n");
+ break;
+ case 'x':
+ p = hash_delete (h, name = what ("symbol"));
+ printf ("old value was \"%s\"\n", p ? p : "{}");
+ break;
+ default:
+ printf ("I can't understand command \"%c\"\n", command);
+ break;
+ }
+ }
+}
+
+char *
+what (description)
+ char *description;
+{
+ printf (" %s : ", description);
+ gets (answer);
+ return xstrdup (answer);
+}
+
+void
+destroy (string, value)
+ char *string;
+ char *value;
+{
+ free (string);
+ free (value);
+}
+
+void
+applicatee (string, value)
+ char *string;
+ char *value;
+{
+ printf ("%.20s-%.20s\n", string, value);
+}
+
+/* Determine number: what hash table to use.
+ Also determine h: points to hash_control. */
+
+void
+whattable ()
+{
+ for (;;)
+ {
+ printf (" what hash table (%d:%d) ? ", 0, TABLES - 1);
+ gets (answer);
+ sscanf (answer, "%d", &number);
+ if (number >= 0 && number < TABLES)
+ {
+ h = hashtable[number];
+ if (!h)
+ {
+ printf ("warning: current hash-table-#%d. has no hash-control\n", number);
+ }
+ return;
+ }
+ else
+ {
+ printf ("invalid hash table number: %d\n", number);
+ }
+ }
+}
+
+#endif /* TEST */
diff --git a/x/binutils/gas/hash.h b/x/binutils/gas/hash.h
new file mode 100644
index 0000000..08f41e6
--- /dev/null
+++ b/x/binutils/gas/hash.h
@@ -0,0 +1,78 @@
+/* hash.h -- header file for gas hash table routines
+ Copyright 1987, 1992, 1993, 1995, 1999 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef HASH_H
+#define HASH_H
+
+struct hash_control;
+
+/* Create a hash table. This return a control block. */
+
+extern struct hash_control *hash_new (void);
+
+/* Delete a hash table, freeing all allocated memory. */
+
+extern void hash_die (struct hash_control *);
+
+/* Insert an entry into a hash table. This returns NULL on success.
+ On error, it returns a printable string indicating the error. It
+ is considered to be an error if the entry already exists in the
+ hash table. */
+
+extern const char *hash_insert (struct hash_control *,
+ const char *key, PTR value);
+
+/* Insert or replace an entry in a hash table. This returns NULL on
+ success. On error, it returns a printable string indicating the
+ error. If an entry already exists, its value is replaced. */
+
+extern const char *hash_jam (struct hash_control *,
+ const char *key, PTR value);
+
+/* Replace an existing entry in a hash table. This returns the old
+ value stored for the entry. If the entry is not found in the hash
+ table, this does nothing and returns NULL. */
+
+extern PTR hash_replace (struct hash_control *, const char *key,
+ PTR value);
+
+/* Find an entry in a hash table, returning its value. Returns NULL
+ if the entry is not found. */
+
+extern PTR hash_find (struct hash_control *, const char *key);
+
+/* Delete an entry from a hash table. This returns the value stored
+ for that entry, or NULL if there is no such entry. */
+
+extern PTR hash_delete (struct hash_control *, const char *key);
+
+/* Traverse a hash table. Call the function on every entry in the
+ hash table. */
+
+extern void hash_traverse (struct hash_control *,
+ void (*pfn) (const char *key, PTR value));
+
+/* Print hash table statistics on the specified file. NAME is the
+ name of the hash table, used for printing a header. */
+
+extern void hash_print_statistics (FILE *, const char *name,
+ struct hash_control *);
+
+#endif /* HASH_H */
diff --git a/x/binutils/gas/input-file.c b/x/binutils/gas/input-file.c
new file mode 100644
index 0000000..01cc669
--- /dev/null
+++ b/x/binutils/gas/input-file.c
@@ -0,0 +1,273 @@
+/* input_file.c - Deal with Input Files -
+ Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2003
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Confines all details of reading source bytes to this module.
+ All O/S specific crocks should live here.
+ What we lose in "efficiency" we gain in modularity.
+ Note we don't need to #include the "as.h" file. No common coupling! */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "as.h"
+#include "input-file.h"
+#include "safe-ctype.h"
+
+static int input_file_get (char *, int);
+
+/* This variable is non-zero if the file currently being read should be
+ preprocessed by app. It is zero if the file can be read straight in. */
+int preprocess = 0;
+
+/* This code opens a file, then delivers BUFFER_SIZE character
+ chunks of the file on demand.
+ BUFFER_SIZE is supposed to be a number chosen for speed.
+ The caller only asks once what BUFFER_SIZE is, and asks before
+ the nature of the input files (if any) is known. */
+
+#define BUFFER_SIZE (32 * 1024)
+
+/* We use static data: the data area is not sharable. */
+
+static FILE *f_in;
+static char *file_name;
+
+/* Struct for saving the state of this module for file includes. */
+struct saved_file
+ {
+ FILE * f_in;
+ char * file_name;
+ int preprocess;
+ char * app_save;
+ };
+
+/* These hooks accommodate most operating systems. */
+
+void
+input_file_begin (void)
+{
+ f_in = (FILE *) 0;
+}
+
+void
+input_file_end (void)
+{
+}
+
+/* Return BUFFER_SIZE. */
+unsigned int
+input_file_buffer_size (void)
+{
+ return (BUFFER_SIZE);
+}
+
+int
+input_file_is_open (void)
+{
+ return f_in != (FILE *) 0;
+}
+
+/* Push the state of our input, returning a pointer to saved info that
+ can be restored with input_file_pop (). */
+
+char *
+input_file_push (void)
+{
+ register struct saved_file *saved;
+
+ saved = (struct saved_file *) xmalloc (sizeof *saved);
+
+ saved->f_in = f_in;
+ saved->file_name = file_name;
+ saved->preprocess = preprocess;
+ if (preprocess)
+ saved->app_save = app_push ();
+
+ /* Initialize for new file. */
+ input_file_begin ();
+
+ return (char *) saved;
+}
+
+void
+input_file_pop (char *arg)
+{
+ register struct saved_file *saved = (struct saved_file *) arg;
+
+ input_file_end (); /* Close out old file. */
+
+ f_in = saved->f_in;
+ file_name = saved->file_name;
+ preprocess = saved->preprocess;
+ if (preprocess)
+ app_pop (saved->app_save);
+
+ free (arg);
+}
+
+void
+input_file_open (char *filename, /* "" means use stdin. Must not be 0. */
+ int pre)
+{
+ int c;
+ char buf[80];
+
+ preprocess = pre;
+
+ assert (filename != 0); /* Filename may not be NULL. */
+ if (filename[0])
+ {
+ f_in = fopen (filename, FOPEN_RT);
+ file_name = filename;
+ }
+ else
+ {
+ /* Use stdin for the input file. */
+ f_in = stdin;
+ /* For error messages. */
+ file_name = _("{standard input}");
+ }
+
+ if (f_in)
+ c = getc (f_in);
+
+ if (f_in == NULL || ferror (f_in))
+ {
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
+ as_perror (_("Can't open %s for reading"), file_name);
+
+ if (f_in)
+ {
+ fclose (f_in);
+ f_in = NULL;
+ }
+ return;
+ }
+
+ if (c == '#')
+ {
+ /* Begins with comment, may not want to preprocess. */
+ c = getc (f_in);
+ if (c == 'N')
+ {
+ fgets (buf, 80, f_in);
+ if (!strncmp (buf, "O_APP", 5) && ISSPACE (buf[5]))
+ preprocess = 0;
+ if (!strchr (buf, '\n'))
+ ungetc ('#', f_in); /* It was longer. */
+ else
+ ungetc ('\n', f_in);
+ }
+ else if (c == 'A')
+ {
+ fgets (buf, 80, f_in);
+ if (!strncmp (buf, "PP", 2) && ISSPACE (buf[2]))
+ preprocess = 1;
+ if (!strchr (buf, '\n'))
+ ungetc ('#', f_in);
+ else
+ ungetc ('\n', f_in);
+ }
+ else if (c == '\n')
+ ungetc ('\n', f_in);
+ else
+ ungetc ('#', f_in);
+ }
+ else
+ ungetc (c, f_in);
+}
+
+/* Close input file. */
+
+void
+input_file_close (void)
+{
+ /* Don't close a null file pointer. */
+ if (f_in != NULL)
+ fclose (f_in);
+
+ f_in = 0;
+}
+
+/* This function is passed to do_scrub_chars. */
+
+static int
+input_file_get (char *buf, int buflen)
+{
+ int size;
+
+ size = fread (buf, sizeof (char), buflen, f_in);
+ if (size < 0)
+ {
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
+ as_perror (_("Can't read from %s"), file_name);
+ size = 0;
+ }
+ return size;
+}
+
+/* Read a buffer from the input file. */
+
+char *
+input_file_give_next_buffer (char *where /* Where to place 1st character of new buffer. */)
+{
+ char *return_value; /* -> Last char of what we read, + 1. */
+ register int size;
+
+ if (f_in == (FILE *) 0)
+ return 0;
+ /* fflush (stdin); could be done here if you want to synchronise
+ stdin and stdout, for the case where our input file is stdin.
+ Since the assembler shouldn't do any output to stdout, we
+ don't bother to synch output and input. */
+ if (preprocess)
+ size = do_scrub_chars (input_file_get, where, BUFFER_SIZE);
+ else
+ size = fread (where, sizeof (char), BUFFER_SIZE, f_in);
+ if (size < 0)
+ {
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
+ as_perror (_("Can't read from %s"), file_name);
+ size = 0;
+ }
+ if (size)
+ return_value = where + size;
+ else
+ {
+ if (fclose (f_in))
+ {
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
+ as_perror (_("Can't close %s"), file_name);
+ }
+ f_in = (FILE *) 0;
+ return_value = 0;
+ }
+
+ return return_value;
+}
diff --git a/x/binutils/gas/input-file.h b/x/binutils/gas/input-file.h
new file mode 100644
index 0000000..b686a0d
--- /dev/null
+++ b/x/binutils/gas/input-file.h
@@ -0,0 +1,66 @@
+/* input_file.h header for input-file.c
+ Copyright 1987, 1992, 1993, 2000 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*"input_file.c":Operating-system dependant functions to read source files.*/
+
+/*
+ * No matter what the operating system, this module must provide the
+ * following services to its callers.
+ *
+ * input_file_begin() Call once before anything else.
+ *
+ * input_file_end() Call once after everything else.
+ *
+ * input_file_buffer_size() Call anytime. Returns largest possible
+ * delivery from
+ * input_file_give_next_buffer().
+ *
+ * input_file_open(name) Call once for each input file.
+ *
+ * input_file_give_next_buffer(where) Call once to get each new buffer.
+ * Return 0: no more chars left in file,
+ * the file has already been closed.
+ * Otherwise: return a pointer to just
+ * after the last character we read
+ * into the buffer.
+ * If we can only read 0 characters, then
+ * end-of-file is faked.
+ *
+ * input_file_push() Push state, which can be restored
+ * later. Does implicit input_file_begin.
+ * Returns char * to saved state.
+ *
+ * input_file_pop (arg) Pops previously saved state.
+ *
+ * input_file_close () Closes opened file.
+ *
+ * All errors are reported (using as_perror) so caller doesn't have to think
+ * about I/O errors. No I/O errors are fatal: an end-of-file may be faked.
+ */
+
+char *input_file_give_next_buffer (char *where);
+char *input_file_push (void);
+unsigned int input_file_buffer_size (void);
+int input_file_is_open (void);
+void input_file_begin (void);
+void input_file_close (void);
+void input_file_end (void);
+void input_file_open (char *filename, int pre);
+void input_file_pop (char *arg);
diff --git a/x/binutils/gas/input-scrub.c b/x/binutils/gas/input-scrub.c
new file mode 100644
index 0000000..7a03965
--- /dev/null
+++ b/x/binutils/gas/input-scrub.c
@@ -0,0 +1,514 @@
+/* input_scrub.c - Break up input buffers into whole numbers of lines.
+ Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <errno.h> /* Need this to make errno declaration right */
+#include "as.h"
+#include "input-file.h"
+#include "sb.h"
+#include "listing.h"
+
+/*
+ * O/S independent module to supply buffers of sanitised source code
+ * to rest of assembler. We get sanitised input data of arbitrary length.
+ * We break these buffers on line boundaries, recombine pieces that
+ * were broken across buffers, and return a buffer of full lines to
+ * the caller.
+ * The last partial line begins the next buffer we build and return to caller.
+ * The buffer returned to caller is preceded by BEFORE_STRING and followed
+ * by AFTER_STRING, as sentinels. The last character before AFTER_STRING
+ * is a newline.
+ * Also looks after line numbers, for e.g. error messages.
+ */
+
+/*
+ * We don't care how filthy our buffers are, but our callers assume
+ * that the following sanitation has already been done.
+ *
+ * No comments, reduce a comment to a space.
+ * Reduce a tab to a space unless it is 1st char of line.
+ * All multiple tabs and spaces collapsed into 1 char. Tab only
+ * legal if 1st char of line.
+ * # line file statements converted to .line x;.file y; statements.
+ * Escaped newlines at end of line: remove them but add as many newlines
+ * to end of statement as you removed in the middle, to synch line numbers.
+ */
+
+#define BEFORE_STRING ("\n")
+#define AFTER_STRING ("\0") /* memcpy of 0 chars might choke. */
+#define BEFORE_SIZE (1)
+#define AFTER_SIZE (1)
+
+static char *buffer_start; /*->1st char of full buffer area. */
+static char *partial_where; /*->after last full line in buffer. */
+static int partial_size; /* >=0. Number of chars in partial line in buffer. */
+
+/* Because we need AFTER_STRING just after last full line, it clobbers
+ 1st part of partial line. So we preserve 1st part of partial line
+ here. */
+static char save_source[AFTER_SIZE];
+
+/* What is the largest size buffer that input_file_give_next_buffer()
+ could return to us? */
+static unsigned int buffer_length;
+
+/* The index into an sb structure we are reading from. -1 if none. */
+static int sb_index = -1;
+
+/* If we are reading from an sb structure, this is it. */
+static sb from_sb;
+
+/* Should we do a conditional check on from_sb? */
+static int from_sb_is_expansion = 1;
+
+/* The number of nested sb structures we have included. */
+int macro_nest;
+
+/* We can have more than one source file open at once, though the info for all
+ but the latest one are saved off in a struct input_save. These files remain
+ open, so we are limited by the number of open files allowed by the
+ underlying OS. We may also sequentially read more than one source file in an
+ assembly. */
+
+/* We must track the physical file and line number for error messages. We also
+ track a "logical" file and line number corresponding to (C?) compiler
+ source line numbers. Whenever we open a file we must fill in
+ physical_input_file. So if it is NULL we have not opened any files yet. */
+
+static char *physical_input_file;
+static char *logical_input_file;
+
+typedef unsigned int line_numberT; /* 1-origin line number in a source file. */
+/* A line ends in '\n' or eof. */
+
+static line_numberT physical_input_line;
+static int logical_input_line;
+
+/* Struct used to save the state of the input handler during include files */
+struct input_save {
+ char * buffer_start;
+ char * partial_where;
+ int partial_size;
+ char save_source[AFTER_SIZE];
+ unsigned int buffer_length;
+ char * physical_input_file;
+ char * logical_input_file;
+ line_numberT physical_input_line;
+ int logical_input_line;
+ int sb_index;
+ sb from_sb;
+ int from_sb_is_expansion; /* Should we do a conditional check? */
+ struct input_save * next_saved_file; /* Chain of input_saves. */
+ char * input_file_save; /* Saved state of input routines. */
+ char * saved_position; /* Caller's saved position in buf. */
+};
+
+static struct input_save *input_scrub_push (char *saved_position);
+static char *input_scrub_pop (struct input_save *arg);
+static void as_1_char (unsigned int c, FILE * stream);
+
+/* Saved information about the file that .include'd this one. When we hit EOF,
+ we automatically pop to that file. */
+
+static struct input_save *next_saved_file;
+
+/* Push the state of input reading and scrubbing so that we can #include.
+ The return value is a 'void *' (fudged for old compilers) to a save
+ area, which can be restored by passing it to input_scrub_pop(). */
+
+static struct input_save *
+input_scrub_push (char *saved_position)
+{
+ register struct input_save *saved;
+
+ saved = (struct input_save *) xmalloc (sizeof *saved);
+
+ saved->saved_position = saved_position;
+ saved->buffer_start = buffer_start;
+ saved->partial_where = partial_where;
+ saved->partial_size = partial_size;
+ saved->buffer_length = buffer_length;
+ saved->physical_input_file = physical_input_file;
+ saved->logical_input_file = logical_input_file;
+ saved->physical_input_line = physical_input_line;
+ saved->logical_input_line = logical_input_line;
+ saved->sb_index = sb_index;
+ saved->from_sb = from_sb;
+ saved->from_sb_is_expansion = from_sb_is_expansion;
+ memcpy (saved->save_source, save_source, sizeof (save_source));
+ saved->next_saved_file = next_saved_file;
+ saved->input_file_save = input_file_push ();
+
+ input_file_begin (); /* Reinitialize! */
+ logical_input_line = -1;
+ logical_input_file = (char *) NULL;
+ buffer_length = input_file_buffer_size ();
+ sb_index = -1;
+
+ buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE));
+ memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE);
+
+ return saved;
+}
+
+static char *
+input_scrub_pop (struct input_save *saved)
+{
+ char *saved_position;
+
+ input_scrub_end (); /* Finish off old buffer */
+
+ input_file_pop (saved->input_file_save);
+ saved_position = saved->saved_position;
+ buffer_start = saved->buffer_start;
+ buffer_length = saved->buffer_length;
+ physical_input_file = saved->physical_input_file;
+ logical_input_file = saved->logical_input_file;
+ physical_input_line = saved->physical_input_line;
+ logical_input_line = saved->logical_input_line;
+ sb_index = saved->sb_index;
+ from_sb = saved->from_sb;
+ from_sb_is_expansion = saved->from_sb_is_expansion;
+ partial_where = saved->partial_where;
+ partial_size = saved->partial_size;
+ next_saved_file = saved->next_saved_file;
+ memcpy (save_source, saved->save_source, sizeof (save_source));
+
+ free (saved);
+ return saved_position;
+}
+
+void
+input_scrub_begin (void)
+{
+ know (strlen (BEFORE_STRING) == BEFORE_SIZE);
+ know (strlen (AFTER_STRING) == AFTER_SIZE
+ || (AFTER_STRING[0] == '\0' && AFTER_SIZE == 1));
+
+ input_file_begin ();
+
+ buffer_length = input_file_buffer_size ();
+
+ buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE));
+ memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE);
+
+ /* Line number things. */
+ logical_input_line = -1;
+ logical_input_file = (char *) NULL;
+ physical_input_file = NULL; /* No file read yet. */
+ next_saved_file = NULL; /* At EOF, don't pop to any other file */
+ do_scrub_begin (flag_m68k_mri);
+}
+
+void
+input_scrub_end (void)
+{
+ if (buffer_start)
+ {
+ free (buffer_start);
+ buffer_start = 0;
+ input_file_end ();
+ }
+}
+
+/* Start reading input from a new file.
+ Return start of caller's part of buffer. */
+
+char *
+input_scrub_new_file (char *filename)
+{
+ input_file_open (filename, !flag_no_comments);
+ physical_input_file = filename[0] ? filename : _("{standard input}");
+ physical_input_line = 0;
+
+ partial_size = 0;
+ return (buffer_start + BEFORE_SIZE);
+}
+
+/* Include a file from the current file. Save our state, cause it to
+ be restored on EOF, and begin handling a new file. Same result as
+ input_scrub_new_file. */
+
+char *
+input_scrub_include_file (char *filename, char *position)
+{
+ next_saved_file = input_scrub_push (position);
+ return input_scrub_new_file (filename);
+}
+
+/* Start getting input from an sb structure. This is used when
+ expanding a macro. */
+
+void
+input_scrub_include_sb (sb *from, char *position, int is_expansion)
+{
+ if (macro_nest > max_macro_nest)
+ as_fatal (_("macros nested too deeply"));
+ ++macro_nest;
+
+#ifdef md_macro_start
+ if (is_expansion)
+ {
+ md_macro_start ();
+ }
+#endif
+
+ next_saved_file = input_scrub_push (position);
+
+ sb_new (&from_sb);
+ from_sb_is_expansion = is_expansion;
+ if (from->len >= 1 && from->ptr[0] != '\n')
+ {
+ /* Add the sentinel required by read.c. */
+ sb_add_char (&from_sb, '\n');
+ }
+ sb_add_sb (&from_sb, from);
+ sb_index = 1;
+
+ /* These variables are reset by input_scrub_push. Restore them
+ since we are, after all, still at the same point in the file. */
+ logical_input_line = next_saved_file->logical_input_line;
+ logical_input_file = next_saved_file->logical_input_file;
+}
+
+void
+input_scrub_close (void)
+{
+ input_file_close ();
+}
+
+char *
+input_scrub_next_buffer (char **bufp)
+{
+ register char *limit; /*->just after last char of buffer. */
+
+ if (sb_index >= 0)
+ {
+ if (sb_index >= from_sb.len)
+ {
+ sb_kill (&from_sb);
+ if (from_sb_is_expansion
+ )
+ {
+ cond_finish_check (macro_nest);
+#ifdef md_macro_end
+ /* Allow the target to clean up per-macro expansion
+ data. */
+ md_macro_end ();
+#endif
+ }
+ --macro_nest;
+ partial_where = NULL;
+ if (next_saved_file != NULL)
+ *bufp = input_scrub_pop (next_saved_file);
+ return partial_where;
+ }
+
+ partial_where = from_sb.ptr + from_sb.len;
+ partial_size = 0;
+ *bufp = from_sb.ptr + sb_index;
+ sb_index = from_sb.len;
+ return partial_where;
+ }
+
+ *bufp = buffer_start + BEFORE_SIZE;
+
+ if (partial_size)
+ {
+ memcpy (buffer_start + BEFORE_SIZE, partial_where,
+ (unsigned int) partial_size);
+ memcpy (buffer_start + BEFORE_SIZE, save_source, AFTER_SIZE);
+ }
+ limit = input_file_give_next_buffer (buffer_start
+ + BEFORE_SIZE
+ + partial_size);
+ if (limit)
+ {
+ register char *p; /* Find last newline. */
+
+ for (p = limit - 1; *p != '\n'; --p)
+ ;
+ ++p;
+
+ while (p <= buffer_start + BEFORE_SIZE)
+ {
+ int limoff;
+
+ limoff = limit - buffer_start;
+ buffer_length += input_file_buffer_size ();
+ buffer_start = xrealloc (buffer_start,
+ (BEFORE_SIZE
+ + 2 * buffer_length
+ + AFTER_SIZE));
+ *bufp = buffer_start + BEFORE_SIZE;
+ limit = input_file_give_next_buffer (buffer_start + limoff);
+
+ if (limit == NULL)
+ {
+ as_warn (_("partial line at end of file ignored"));
+ partial_where = NULL;
+ if (next_saved_file)
+ *bufp = input_scrub_pop (next_saved_file);
+ return NULL;
+ }
+
+ for (p = limit - 1; *p != '\n'; --p)
+ ;
+ ++p;
+ }
+
+ partial_where = p;
+ partial_size = limit - p;
+ memcpy (save_source, partial_where, (int) AFTER_SIZE);
+ memcpy (partial_where, AFTER_STRING, (int) AFTER_SIZE);
+ }
+ else
+ {
+ partial_where = 0;
+ if (partial_size > 0)
+ {
+ as_warn (_("partial line at end of file ignored"));
+ }
+
+ /* Tell the listing we've finished the file. */
+ LISTING_EOF ();
+
+ /* If we should pop to another file at EOF, do it. */
+ if (next_saved_file)
+ {
+ *bufp = input_scrub_pop (next_saved_file); /* Pop state */
+ /* partial_where is now correct to return, since we popped it. */
+ }
+ }
+ return (partial_where);
+}
+
+/* The remaining part of this file deals with line numbers, error
+ messages and so on. Return TRUE if we opened any file. */
+
+int
+seen_at_least_1_file (void)
+{
+ return (physical_input_file != NULL);
+}
+
+void
+bump_line_counters (void)
+{
+ if (sb_index < 0)
+ {
+ ++physical_input_line;
+ if (logical_input_line >= 0)
+ ++logical_input_line;
+ }
+}
+
+/* Tells us what the new logical line number and file are.
+ If the line_number is -1, we don't change the current logical line
+ number. If it is -2, we decrement the logical line number (this is
+ to support the .appfile pseudo-op inserted into the stream by
+ do_scrub_chars).
+ If the fname is NULL, we don't change the current logical file name.
+ Returns nonzero if the filename actually changes. */
+
+int
+new_logical_line (char *fname, /* DON'T destroy it! We point to it! */
+ int line_number)
+{
+ if (line_number >= 0)
+ logical_input_line = line_number;
+ else if (line_number == -2 && logical_input_line > 0)
+ --logical_input_line;
+
+ if (fname
+ && (logical_input_file == NULL
+ || strcmp (logical_input_file, fname)))
+ {
+ logical_input_file = fname;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+/* Return the current file name and line number.
+ namep should be char * const *, but there are compilers which screw
+ up declarations like that, and it's easier to avoid it. */
+
+void
+as_where (char **namep, unsigned int *linep)
+{
+ if (logical_input_file != NULL
+ && (linep == NULL || logical_input_line >= 0))
+ {
+ *namep = logical_input_file;
+ if (linep != NULL)
+ *linep = logical_input_line;
+ }
+ else if (physical_input_file != NULL)
+ {
+ *namep = physical_input_file;
+ if (linep != NULL)
+ *linep = physical_input_line;
+ }
+ else
+ {
+ *namep = 0;
+ if (linep != NULL)
+ *linep = 0;
+ }
+}
+
+/* Output to given stream how much of line we have scanned so far.
+ Assumes we have scanned up to and including input_line_pointer.
+ No free '\n' at end of line. */
+
+void
+as_howmuch (FILE *stream /* Opened for write please. */)
+{
+ register char *p; /* Scan input line. */
+
+ for (p = input_line_pointer - 1; *p != '\n'; --p)
+ {
+ }
+ ++p; /* p->1st char of line. */
+ for (; p <= input_line_pointer; p++)
+ {
+ /* Assume ASCII. EBCDIC & other micro-computer char sets ignored. */
+ as_1_char ((unsigned char) *p, stream);
+ }
+}
+
+static void
+as_1_char (unsigned int c, FILE *stream)
+{
+ if (c > 127)
+ {
+ (void) putc ('%', stream);
+ c -= 128;
+ }
+ if (c < 32)
+ {
+ (void) putc ('^', stream);
+ c += '@';
+ }
+ (void) putc (c, stream);
+}
diff --git a/x/binutils/gas/itbl-lex.l b/x/binutils/gas/itbl-lex.l
new file mode 100644
index 0000000..e924efc
--- /dev/null
+++ b/x/binutils/gas/itbl-lex.l
@@ -0,0 +1,114 @@
+/* itbl-lex.l
+ Copyright 1997, 1998, 2001 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+%{
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <itbl-parse.h>
+
+#ifdef DEBUG
+#define DBG(x) printf x
+#define MDBG(x) printf x
+#else
+#define DBG(x)
+#define MDBG(x)
+#endif
+
+int insntbl_line = 1;
+%}
+
+ALNUM [A-Za-z0-9_]
+DIGIT [0-9]
+ALPHA [A-Za-z_]
+HEX [0-9A-Fa-f]
+
+%%
+
+"creg"|"CREG" {
+ return CREG;
+ }
+"dreg"|"DREG" {
+ return DREG;
+ }
+"greg"|"GREG" {
+ return GREG;
+ }
+"immed"|"IMMED" {
+ return IMMED;
+ }
+"addr"|"ADDR" {
+ return ADDR;
+ }
+"insn"|"INSN" {
+ return INSN;
+ }
+"p"{DIGIT} {
+ yytext[yyleng] = 0;
+ yylval.processor = strtoul (yytext+1, 0, 0);
+ return PNUM;
+ }
+{DIGIT}+ {
+ yytext[yyleng] = 0;
+ yylval.num = strtoul (yytext, 0, 0);
+ return NUM;
+ }
+"0x"{HEX}+ {
+ yytext[yyleng] = 0;
+ yylval.num = strtoul (yytext, 0, 0);
+ return NUM;
+ }
+{ALPHA}{ALNUM}* {
+ yytext[yyleng] = 0;
+ yylval.str = strdup (yytext);
+ return ID;
+ }
+";"|"#" {
+ int c;
+ while ((c = input ()) != EOF)
+ {
+ if (c == '\n')
+ {
+ unput (c);
+ break;
+ }
+ }
+ }
+"\n" {
+ insntbl_line++;
+ MDBG (("in lex, NL = %d (x%x)\n", NL, NL));
+ return NL;
+ }
+" "|"\t" {
+ }
+. {
+ MDBG (("char = %x, %d\n", yytext[0], yytext[0]));
+ return yytext[0];
+ }
+%%
+
+#ifndef yywrap
+int
+yywrap ()
+ {
+ return 1;
+ }
+#endif
diff --git a/x/binutils/gas/itbl-ops.c b/x/binutils/gas/itbl-ops.c
new file mode 100644
index 0000000..089bff4
--- /dev/null
+++ b/x/binutils/gas/itbl-ops.c
@@ -0,0 +1,901 @@
+/* itbl-ops.c
+ Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*======================================================================*/
+/*
+ * Herein lies the support for dynamic specification of processor
+ * instructions and registers. Mnemonics, values, and formats for each
+ * instruction and register are specified in an ascii file consisting of
+ * table entries. The grammar for the table is defined in the document
+ * "Processor instruction table specification".
+ *
+ * Instructions use the gnu assembler syntax, with the addition of
+ * allowing mnemonics for register.
+ * Eg. "func $2,reg3,0x100,symbol ; comment"
+ * func - opcode name
+ * $n - register n
+ * reg3 - mnemonic for processor's register defined in table
+ * 0xddd..d - immediate value
+ * symbol - address of label or external symbol
+ *
+ * First, itbl_parse reads in the table of register and instruction
+ * names and formats, and builds a list of entries for each
+ * processor/type combination. lex and yacc are used to parse
+ * the entries in the table and call functions defined here to
+ * add each entry to our list.
+ *
+ * Then, when assembling or disassembling, these functions are called to
+ * 1) get information on a processor's registers and
+ * 2) assemble/disassemble an instruction.
+ * To assemble(disassemble) an instruction, the function
+ * itbl_assemble(itbl_disassemble) is called to search the list of
+ * instruction entries, and if a match is found, uses the format
+ * described in the instruction entry structure to complete the action.
+ *
+ * Eg. Suppose we have a Mips coprocessor "cop3" with data register "d2"
+ * and we want to define function "pig" which takes two operands.
+ *
+ * Given the table entries:
+ * "p3 insn pig 0x1:24-21 dreg:20-16 immed:15-0"
+ * "p3 dreg d2 0x2"
+ * and that the instruction encoding for coprocessor pz has encoding:
+ * #define MIPS_ENCODE_COP_NUM(z) ((0x21|(z<<1))<<25)
+ * #define ITBL_ENCODE_PNUM(pnum) MIPS_ENCODE_COP_NUM(pnum)
+ *
+ * a structure to describe the instruction might look something like:
+ * struct itbl_entry = {
+ * e_processor processor = e_p3
+ * e_type type = e_insn
+ * char *name = "pig"
+ * uint value = 0x1
+ * uint flags = 0
+ * struct itbl_range range = 24-21
+ * struct itbl_field *field = {
+ * e_type type = e_dreg
+ * struct itbl_range range = 20-16
+ * struct itbl_field *next = {
+ * e_type type = e_immed
+ * struct itbl_range range = 15-0
+ * struct itbl_field *next = 0
+ * };
+ * };
+ * struct itbl_entry *next = 0
+ * };
+ *
+ * And the assembler instructions:
+ * "pig d2,0x100"
+ * "pig $2,0x100"
+ *
+ * would both assemble to the hex value:
+ * "0x4e220100"
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "itbl-ops.h"
+#include <itbl-parse.h>
+
+/* #define DEBUG */
+
+#ifdef DEBUG
+#include <assert.h>
+#define ASSERT(x) assert(x)
+#define DBG(x) printf x
+#else
+#define ASSERT(x)
+#define DBG(x)
+#endif
+
+#ifndef min
+#define min(a,b) (a<b?a:b)
+#endif
+
+int itbl_have_entries = 0;
+
+/*======================================================================*/
+/* structures for keeping itbl format entries */
+
+struct itbl_range {
+ int sbit; /* mask starting bit position */
+ int ebit; /* mask ending bit position */
+};
+
+struct itbl_field {
+ e_type type; /* dreg/creg/greg/immed/symb */
+ struct itbl_range range; /* field's bitfield range within instruction */
+ unsigned long flags; /* field flags */
+ struct itbl_field *next; /* next field in list */
+};
+
+/* These structures define the instructions and registers for a processor.
+ * If the type is an instruction, the structure defines the format of an
+ * instruction where the fields are the list of operands.
+ * The flags field below uses the same values as those defined in the
+ * gnu assembler and are machine specific. */
+struct itbl_entry {
+ e_processor processor; /* processor number */
+ e_type type; /* dreg/creg/greg/insn */
+ char *name; /* mnemionic name for insn/register */
+ unsigned long value; /* opcode/instruction mask/register number */
+ unsigned long flags; /* effects of the instruction */
+ struct itbl_range range; /* bit range within instruction for value */
+ struct itbl_field *fields; /* list of operand definitions (if any) */
+ struct itbl_entry *next; /* next entry */
+};
+
+/* local data and structures */
+
+static int itbl_num_opcodes = 0;
+/* Array of entries for each processor and entry type */
+static struct itbl_entry *entries[e_nprocs][e_ntypes] = {
+ {0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0}
+};
+
+/* local prototypes */
+static unsigned long build_opcode (struct itbl_entry *e);
+static e_type get_type (int yytype);
+static e_processor get_processor (int yyproc);
+static struct itbl_entry **get_entries (e_processor processor,
+ e_type type);
+static struct itbl_entry *find_entry_byname (e_processor processor,
+ e_type type, char *name);
+static struct itbl_entry *find_entry_byval (e_processor processor,
+ e_type type, unsigned long val, struct itbl_range *r);
+static struct itbl_entry *alloc_entry (e_processor processor,
+ e_type type, char *name, unsigned long value);
+static unsigned long apply_range (unsigned long value, struct itbl_range r);
+static unsigned long extract_range (unsigned long value, struct itbl_range r);
+static struct itbl_field *alloc_field (e_type type, int sbit,
+ int ebit, unsigned long flags);
+
+/*======================================================================*/
+/* Interfaces to the parser */
+
+/* Open the table and use lex and yacc to parse the entries.
+ * Return 1 for failure; 0 for success. */
+
+int
+itbl_parse (char *insntbl)
+{
+ extern FILE *yyin;
+ extern int yyparse (void);
+
+ yyin = fopen (insntbl, FOPEN_RT);
+ if (yyin == 0)
+ {
+ printf ("Can't open processor instruction specification file \"%s\"\n",
+ insntbl);
+ return 1;
+ }
+
+ while (yyparse ())
+ ;
+
+ fclose (yyin);
+ itbl_have_entries = 1;
+ return 0;
+}
+
+/* Add a register entry */
+
+struct itbl_entry *
+itbl_add_reg (int yyprocessor, int yytype, char *regname,
+ int regnum)
+{
+#if 0
+#include "as.h"
+#include "symbols.h"
+ /* Since register names don't have a prefix, we put them in the symbol table so
+ they can't be used as symbols. This also simplifies argument parsing as
+ we can let gas parse registers for us. The recorded register number is
+ regnum. */
+ /* Use symbol_create here instead of symbol_new so we don't try to
+ output registers into the object file's symbol table. */
+ symbol_table_insert (symbol_create (regname, reg_section,
+ regnum, &zero_address_frag));
+#endif
+ return alloc_entry (get_processor (yyprocessor), get_type (yytype), regname,
+ (unsigned long) regnum);
+}
+
+/* Add an instruction entry */
+
+struct itbl_entry *
+itbl_add_insn (int yyprocessor, char *name, unsigned long value,
+ int sbit, int ebit, unsigned long flags)
+{
+ struct itbl_entry *e;
+ e = alloc_entry (get_processor (yyprocessor), e_insn, name, value);
+ if (e)
+ {
+ e->range.sbit = sbit;
+ e->range.ebit = ebit;
+ e->flags = flags;
+ itbl_num_opcodes++;
+ }
+ return e;
+}
+
+/* Add an operand to an instruction entry */
+
+struct itbl_field *
+itbl_add_operand (struct itbl_entry *e, int yytype, int sbit,
+ int ebit, unsigned long flags)
+{
+ struct itbl_field *f, **last_f;
+ if (!e)
+ return 0;
+ /* Add to end of fields' list. */
+ f = alloc_field (get_type (yytype), sbit, ebit, flags);
+ if (f)
+ {
+ last_f = &e->fields;
+ while (*last_f)
+ last_f = &(*last_f)->next;
+ *last_f = f;
+ f->next = 0;
+ }
+ return f;
+}
+
+/*======================================================================*/
+/* Interfaces for assembler and disassembler */
+
+#ifndef STAND_ALONE
+#include "as.h"
+#include "symbols.h"
+static void append_insns_as_macros (void);
+
+/* Initialize for gas. */
+
+void
+itbl_init (void)
+{
+ struct itbl_entry *e, **es;
+ e_processor procn;
+ e_type type;
+
+ if (!itbl_have_entries)
+ return;
+
+ /* Since register names don't have a prefix, put them in the symbol table so
+ they can't be used as symbols. This simplifies argument parsing as
+ we can let gas parse registers for us. */
+ /* Use symbol_create instead of symbol_new so we don't try to
+ output registers into the object file's symbol table. */
+
+ for (type = e_regtype0; type < e_nregtypes; type++)
+ for (procn = e_p0; procn < e_nprocs; procn++)
+ {
+ es = get_entries (procn, type);
+ for (e = *es; e; e = e->next)
+ {
+ symbol_table_insert (symbol_create (e->name, reg_section,
+ e->value, &zero_address_frag));
+ }
+ }
+ append_insns_as_macros ();
+}
+
+/* Append insns to opcodes table and increase number of opcodes
+ * Structure of opcodes table:
+ * struct itbl_opcode
+ * {
+ * const char *name;
+ * const char *args; - string describing the arguments.
+ * unsigned long match; - opcode, or ISA level if pinfo=INSN_MACRO
+ * unsigned long mask; - opcode mask, or macro id if pinfo=INSN_MACRO
+ * unsigned long pinfo; - insn flags, or INSN_MACRO
+ * };
+ * examples:
+ * {"li", "t,i", 0x34000000, 0xffe00000, WR_t },
+ * {"li", "t,I", 0, (int) M_LI, INSN_MACRO },
+ */
+
+static char *form_args (struct itbl_entry *e);
+static void
+append_insns_as_macros (void)
+{
+ struct ITBL_OPCODE_STRUCT *new_opcodes, *o;
+ struct itbl_entry *e, **es;
+ int n, id, size, new_size, new_num_opcodes;
+
+ if (!itbl_have_entries)
+ return;
+
+ if (!itbl_num_opcodes) /* no new instructions to add! */
+ {
+ return;
+ }
+ DBG (("previous num_opcodes=%d\n", ITBL_NUM_OPCODES));
+
+ new_num_opcodes = ITBL_NUM_OPCODES + itbl_num_opcodes;
+ ASSERT (new_num_opcodes >= itbl_num_opcodes);
+
+ size = sizeof (struct ITBL_OPCODE_STRUCT) * ITBL_NUM_OPCODES;
+ ASSERT (size >= 0);
+ DBG (("I get=%d\n", size / sizeof (ITBL_OPCODES[0])));
+
+ new_size = sizeof (struct ITBL_OPCODE_STRUCT) * new_num_opcodes;
+ ASSERT (new_size > size);
+
+ /* FIXME since ITBL_OPCODES culd be a static table,
+ we can't realloc or delete the old memory. */
+ new_opcodes = (struct ITBL_OPCODE_STRUCT *) malloc (new_size);
+ if (!new_opcodes)
+ {
+ printf (_("Unable to allocate memory for new instructions\n"));
+ return;
+ }
+ if (size) /* copy preexisting opcodes table */
+ memcpy (new_opcodes, ITBL_OPCODES, size);
+
+ /* FIXME! some NUMOPCODES are calculated expressions.
+ These need to be changed before itbls can be supported. */
+
+ id = ITBL_NUM_MACROS; /* begin the next macro id after the last */
+ o = &new_opcodes[ITBL_NUM_OPCODES]; /* append macro to opcodes list */
+ for (n = e_p0; n < e_nprocs; n++)
+ {
+ es = get_entries (n, e_insn);
+ for (e = *es; e; e = e->next)
+ {
+ /* name, args, mask, match, pinfo
+ * {"li", "t,i", 0x34000000, 0xffe00000, WR_t },
+ * {"li", "t,I", 0, (int) M_LI, INSN_MACRO },
+ * Construct args from itbl_fields.
+ */
+ o->name = e->name;
+ o->args = strdup (form_args (e));
+ o->mask = apply_range (e->value, e->range);
+ /* FIXME how to catch during assembly? */
+ /* mask to identify this insn */
+ o->match = apply_range (e->value, e->range);
+ o->pinfo = 0;
+
+#ifdef USE_MACROS
+ o->mask = id++; /* FIXME how to catch during assembly? */
+ o->match = 0; /* for macros, the insn_isa number */
+ o->pinfo = INSN_MACRO;
+#endif
+
+ /* Don't add instructions which caused an error */
+ if (o->args)
+ o++;
+ else
+ new_num_opcodes--;
+ }
+ }
+ ITBL_OPCODES = new_opcodes;
+ ITBL_NUM_OPCODES = new_num_opcodes;
+
+ /* FIXME
+ At this point, we can free the entries, as they should have
+ been added to the assembler's tables.
+ Don't free name though, since name is being used by the new
+ opcodes table.
+
+ Eventually, we should also free the new opcodes table itself
+ on exit.
+ */
+}
+
+static char *
+form_args (struct itbl_entry *e)
+{
+ static char s[31];
+ char c = 0, *p = s;
+ struct itbl_field *f;
+
+ ASSERT (e);
+ for (f = e->fields; f; f = f->next)
+ {
+ switch (f->type)
+ {
+ case e_dreg:
+ c = 'd';
+ break;
+ case e_creg:
+ c = 't';
+ break;
+ case e_greg:
+ c = 's';
+ break;
+ case e_immed:
+ c = 'i';
+ break;
+ case e_addr:
+ c = 'a';
+ break;
+ default:
+ c = 0; /* ignore; unknown field type */
+ }
+ if (c)
+ {
+ if (p != s)
+ *p++ = ',';
+ *p++ = c;
+ }
+ }
+ *p = 0;
+ return s;
+}
+#endif /* !STAND_ALONE */
+
+/* Get processor's register name from val */
+
+int
+itbl_get_reg_val (char *name, unsigned long *pval)
+{
+ e_type t;
+ e_processor p;
+
+ for (p = e_p0; p < e_nprocs; p++)
+ {
+ for (t = e_regtype0; t < e_nregtypes; t++)
+ {
+ if (itbl_get_val (p, t, name, pval))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+char *
+itbl_get_name (e_processor processor, e_type type, unsigned long val)
+{
+ struct itbl_entry *r;
+ /* type depends on instruction passed */
+ r = find_entry_byval (processor, type, val, 0);
+ if (r)
+ return r->name;
+ else
+ return 0; /* error; invalid operand */
+}
+
+/* Get processor's register value from name */
+
+int
+itbl_get_val (e_processor processor, e_type type, char *name,
+ unsigned long *pval)
+{
+ struct itbl_entry *r;
+ /* type depends on instruction passed */
+ r = find_entry_byname (processor, type, name);
+ if (r == NULL)
+ return 0;
+ *pval = r->value;
+ return 1;
+}
+
+/* Assemble instruction "name" with operands "s".
+ * name - name of instruction
+ * s - operands
+ * returns - long word for assembled instruction */
+
+unsigned long
+itbl_assemble (char *name, char *s)
+{
+ unsigned long opcode;
+ struct itbl_entry *e = NULL;
+ struct itbl_field *f;
+ char *n;
+ int processor;
+
+ if (!name || !*name)
+ return 0; /* error! must have an opcode name/expr */
+
+ /* find entry in list of instructions for all processors */
+ for (processor = 0; processor < e_nprocs; processor++)
+ {
+ e = find_entry_byname (processor, e_insn, name);
+ if (e)
+ break;
+ }
+ if (!e)
+ return 0; /* opcode not in table; invalid instruction */
+ opcode = build_opcode (e);
+
+ /* parse opcode's args (if any) */
+ for (f = e->fields; f; f = f->next) /* for each arg, ... */
+ {
+ struct itbl_entry *r;
+ unsigned long value;
+ if (!s || !*s)
+ return 0; /* error - not enough operands */
+ n = itbl_get_field (&s);
+ /* n should be in form $n or 0xhhh (are symbol names valid?? */
+ switch (f->type)
+ {
+ case e_dreg:
+ case e_creg:
+ case e_greg:
+ /* Accept either a string name
+ * or '$' followed by the register number */
+ if (*n == '$')
+ {
+ n++;
+ value = strtol (n, 0, 10);
+ /* FIXME! could have "0l"... then what?? */
+ if (value == 0 && *n != '0')
+ return 0; /* error; invalid operand */
+ }
+ else
+ {
+ r = find_entry_byname (e->processor, f->type, n);
+ if (r)
+ value = r->value;
+ else
+ return 0; /* error; invalid operand */
+ }
+ break;
+ case e_addr:
+ /* use assembler's symbol table to find symbol */
+ /* FIXME!! Do we need this?
+ if so, what about relocs??
+ my_getExpression (&imm_expr, s);
+ return 0; /-* error; invalid operand *-/
+ break;
+ */
+ /* If not a symbol, fall thru to IMMED */
+ case e_immed:
+ if (*n == '0' && *(n + 1) == 'x') /* hex begins 0x... */
+ {
+ n += 2;
+ value = strtol (n, 0, 16);
+ /* FIXME! could have "0xl"... then what?? */
+ }
+ else
+ {
+ value = strtol (n, 0, 10);
+ /* FIXME! could have "0l"... then what?? */
+ if (value == 0 && *n != '0')
+ return 0; /* error; invalid operand */
+ }
+ break;
+ default:
+ return 0; /* error; invalid field spec */
+ }
+ opcode |= apply_range (value, f->range);
+ }
+ if (s && *s)
+ return 0; /* error - too many operands */
+ return opcode; /* done! */
+}
+
+/* Disassemble instruction "insn".
+ * insn - instruction
+ * s - buffer to hold disassembled instruction
+ * returns - 1 if succeeded; 0 if failed
+ */
+
+int
+itbl_disassemble (char *s, unsigned long insn)
+{
+ e_processor processor;
+ struct itbl_entry *e;
+ struct itbl_field *f;
+
+ if (!ITBL_IS_INSN (insn))
+ return 0; /* error */
+ processor = get_processor (ITBL_DECODE_PNUM (insn));
+
+ /* find entry in list */
+ e = find_entry_byval (processor, e_insn, insn, 0);
+ if (!e)
+ return 0; /* opcode not in table; invalid instruction */
+ strcpy (s, e->name);
+
+ /* Parse insn's args (if any). */
+ for (f = e->fields; f; f = f->next) /* for each arg, ... */
+ {
+ struct itbl_entry *r;
+ unsigned long value;
+
+ if (f == e->fields) /* First operand is preceded by tab. */
+ strcat (s, "\t");
+ else /* ','s separate following operands. */
+ strcat (s, ",");
+ value = extract_range (insn, f->range);
+ /* n should be in form $n or 0xhhh (are symbol names valid?? */
+ switch (f->type)
+ {
+ case e_dreg:
+ case e_creg:
+ case e_greg:
+ /* Accept either a string name
+ or '$' followed by the register number. */
+ r = find_entry_byval (e->processor, f->type, value, &f->range);
+ if (r)
+ strcat (s, r->name);
+ else
+ sprintf (s, "%s$%lu", s, value);
+ break;
+ case e_addr:
+ /* Use assembler's symbol table to find symbol. */
+ /* FIXME!! Do we need this? If so, what about relocs?? */
+ /* If not a symbol, fall through to IMMED. */
+ case e_immed:
+ sprintf (s, "%s0x%lx", s, value);
+ break;
+ default:
+ return 0; /* error; invalid field spec */
+ }
+ }
+ return 1; /* Done! */
+}
+
+/*======================================================================*/
+/*
+ * Local functions for manipulating private structures containing
+ * the names and format for the new instructions and registers
+ * for each processor.
+ */
+
+/* Calculate instruction's opcode and function values from entry */
+
+static unsigned long
+build_opcode (struct itbl_entry *e)
+{
+ unsigned long opcode;
+
+ opcode = apply_range (e->value, e->range);
+ opcode |= ITBL_ENCODE_PNUM (e->processor);
+ return opcode;
+}
+
+/* Calculate absolute value given the relative value and bit position range
+ * within the instruction.
+ * The range is inclusive where 0 is least significant bit.
+ * A range of { 24, 20 } will have a mask of
+ * bit 3 2 1
+ * pos: 1098 7654 3210 9876 5432 1098 7654 3210
+ * bin: 0000 0001 1111 0000 0000 0000 0000 0000
+ * hex: 0 1 f 0 0 0 0 0
+ * mask: 0x01f00000.
+ */
+
+static unsigned long
+apply_range (unsigned long rval, struct itbl_range r)
+{
+ unsigned long mask;
+ unsigned long aval;
+ int len = MAX_BITPOS - r.sbit;
+
+ ASSERT (r.sbit >= r.ebit);
+ ASSERT (MAX_BITPOS >= r.sbit);
+ ASSERT (r.ebit >= 0);
+
+ /* create mask by truncating 1s by shifting */
+ mask = 0xffffffff << len;
+ mask = mask >> len;
+ mask = mask >> r.ebit;
+ mask = mask << r.ebit;
+
+ aval = (rval << r.ebit) & mask;
+ return aval;
+}
+
+/* Calculate relative value given the absolute value and bit position range
+ * within the instruction. */
+
+static unsigned long
+extract_range (unsigned long aval, struct itbl_range r)
+{
+ unsigned long mask;
+ unsigned long rval;
+ int len = MAX_BITPOS - r.sbit;
+
+ /* create mask by truncating 1s by shifting */
+ mask = 0xffffffff << len;
+ mask = mask >> len;
+ mask = mask >> r.ebit;
+ mask = mask << r.ebit;
+
+ rval = (aval & mask) >> r.ebit;
+ return rval;
+}
+
+/* Extract processor's assembly instruction field name from s;
+ * forms are "n args" "n,args" or "n" */
+/* Return next argument from string pointer "s" and advance s.
+ * delimiters are " ,()" */
+
+char *
+itbl_get_field (char **S)
+{
+ static char n[128];
+ char *s;
+ int len;
+
+ s = *S;
+ if (!s || !*s)
+ return 0;
+ /* FIXME: This is a weird set of delimiters. */
+ len = strcspn (s, " \t,()");
+ ASSERT (128 > len + 1);
+ strncpy (n, s, len);
+ n[len] = 0;
+ if (s[len] == '\0')
+ s = 0; /* no more args */
+ else
+ s += len + 1; /* advance to next arg */
+
+ *S = s;
+ return n;
+}
+
+/* Search entries for a given processor and type
+ * to find one matching the name "n".
+ * Return a pointer to the entry */
+
+static struct itbl_entry *
+find_entry_byname (e_processor processor,
+ e_type type, char *n)
+{
+ struct itbl_entry *e, **es;
+
+ es = get_entries (processor, type);
+ for (e = *es; e; e = e->next) /* for each entry, ... */
+ {
+ if (!strcmp (e->name, n))
+ return e;
+ }
+ return 0;
+}
+
+/* Search entries for a given processor and type
+ * to find one matching the value "val" for the range "r".
+ * Return a pointer to the entry.
+ * This function is used for disassembling fields of an instruction.
+ */
+
+static struct itbl_entry *
+find_entry_byval (e_processor processor, e_type type,
+ unsigned long val, struct itbl_range *r)
+{
+ struct itbl_entry *e, **es;
+ unsigned long eval;
+
+ es = get_entries (processor, type);
+ for (e = *es; e; e = e->next) /* for each entry, ... */
+ {
+ if (processor != e->processor)
+ continue;
+ /* For insns, we might not know the range of the opcode,
+ * so a range of 0 will allow this routine to match against
+ * the range of the entry to be compared with.
+ * This could cause ambiguities.
+ * For operands, we get an extracted value and a range.
+ */
+ /* if range is 0, mask val against the range of the compared entry. */
+ if (r == 0) /* if no range passed, must be whole 32-bits
+ * so create 32-bit value from entry's range */
+ {
+ eval = apply_range (e->value, e->range);
+ val &= apply_range (0xffffffff, e->range);
+ }
+ else if ((r->sbit == e->range.sbit && r->ebit == e->range.ebit)
+ || (e->range.sbit == 0 && e->range.ebit == 0))
+ {
+ eval = apply_range (e->value, *r);
+ val = apply_range (val, *r);
+ }
+ else
+ continue;
+ if (val == eval)
+ return e;
+ }
+ return 0;
+}
+
+/* Return a pointer to the list of entries for a given processor and type. */
+
+static struct itbl_entry **
+get_entries (e_processor processor, e_type type)
+{
+ return &entries[processor][type];
+}
+
+/* Return an integral value for the processor passed from yyparse. */
+
+static e_processor
+get_processor (int yyproc)
+{
+ /* translate from yacc's processor to enum */
+ if (yyproc >= e_p0 && yyproc < e_nprocs)
+ return (e_processor) yyproc;
+ return e_invproc; /* error; invalid processor */
+}
+
+/* Return an integral value for the entry type passed from yyparse. */
+
+static e_type
+get_type (int yytype)
+{
+ switch (yytype)
+ {
+ /* translate from yacc's type to enum */
+ case INSN:
+ return e_insn;
+ case DREG:
+ return e_dreg;
+ case CREG:
+ return e_creg;
+ case GREG:
+ return e_greg;
+ case ADDR:
+ return e_addr;
+ case IMMED:
+ return e_immed;
+ default:
+ return e_invtype; /* error; invalid type */
+ }
+}
+
+/* Allocate and initialize an entry */
+
+static struct itbl_entry *
+alloc_entry (e_processor processor, e_type type,
+ char *name, unsigned long value)
+{
+ struct itbl_entry *e, **es;
+ if (!name)
+ return 0;
+ e = (struct itbl_entry *) malloc (sizeof (struct itbl_entry));
+ if (e)
+ {
+ memset (e, 0, sizeof (struct itbl_entry));
+ e->name = (char *) malloc (sizeof (strlen (name)) + 1);
+ if (e->name)
+ strcpy (e->name, name);
+ e->processor = processor;
+ e->type = type;
+ e->value = value;
+ es = get_entries (e->processor, e->type);
+ e->next = *es;
+ *es = e;
+ }
+ return e;
+}
+
+/* Allocate and initialize an entry's field */
+
+static struct itbl_field *
+alloc_field (e_type type, int sbit, int ebit,
+ unsigned long flags)
+{
+ struct itbl_field *f;
+ f = (struct itbl_field *) malloc (sizeof (struct itbl_field));
+ if (f)
+ {
+ memset (f, 0, sizeof (struct itbl_field));
+ f->type = type;
+ f->range.sbit = sbit;
+ f->range.ebit = ebit;
+ f->flags = flags;
+ }
+ return f;
+}
diff --git a/x/binutils/gas/itbl-ops.h b/x/binutils/gas/itbl-ops.h
new file mode 100644
index 0000000..4c98d72
--- /dev/null
+++ b/x/binutils/gas/itbl-ops.h
@@ -0,0 +1,108 @@
+/* itbl-ops.h
+ Copyright 1997, 1999, 2000 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* External functions, constants and defines for itbl support */
+
+#include "ansidecl.h"
+
+/* Include file notes: "expr.h" needed before targ-*.h,
+ * "targ-env.h" includes the chain of target dependant headers,
+ * "targ-cpu.h" has the HAVE_ITBL_CPU define, and
+ * as.h includes them all */
+#include "as.h"
+
+#ifdef HAVE_ITBL_CPU
+#include "itbl-cpu.h"
+#endif
+
+/* Defaults for definitions required by generic code */
+#ifndef ITBL_NUMBER_OF_PROCESSORS
+#define ITBL_NUMBER_OF_PROCESSORS 1
+#endif
+
+#ifndef ITBL_MAX_BITPOS
+#define ITBL_MAX_BITPOS 31
+#endif
+
+#ifndef ITBL_TYPE
+#define ITBL_TYPE unsigned long
+#endif
+
+#ifndef ITBL_IS_INSN
+#define ITBL_IS_INSN(insn) 1
+#endif
+
+#ifndef ITBL_DECODE_PNUM
+#define ITBL_DECODE_PNUM(insn) 0
+#endif
+
+#ifndef ITBL_ENCODE_PNUM
+#define ITBL_ENCODE_PNUM(pnum) 0
+#endif
+
+typedef ITBL_TYPE t_insn;
+
+/* types of entries */
+typedef enum
+ {
+ e_insn,
+ e_dreg,
+ e_regtype0 = e_dreg,
+ e_creg,
+ e_greg,
+ e_addr,
+ e_nregtypes = e_greg + 1,
+ e_immed,
+ e_ntypes,
+ e_invtype /* invalid type */
+ } e_type;
+
+typedef enum
+ {
+ e_p0,
+ e_nprocs = NUMBER_OF_PROCESSORS,
+ e_invproc /* invalid processor */
+ } e_processor;
+
+/* 0 means an instruction table was not specified. */
+extern int itbl_have_entries;
+
+/* These routines are visible to the main part of the assembler */
+
+int itbl_parse (char *insntbl);
+void itbl_init (void);
+char *itbl_get_field (char **s);
+unsigned long itbl_assemble (char *name, char *operands);
+int itbl_disassemble (char *str, unsigned long insn);
+int itbl_parse (char *tbl); /* parses insn tbl */
+int itbl_get_reg_val (char *name, unsigned long *pval);
+int itbl_get_val (e_processor processor, e_type type, char *name,
+ unsigned long *pval);
+char *itbl_get_name (e_processor processor, e_type type, unsigned long val);
+
+/* These routines are called by the table parser used to build the
+ dynamic list of new processor instructions and registers. */
+
+struct itbl_entry *itbl_add_reg (int yyproc, int yytype,
+ char *regname, int regnum);
+struct itbl_entry *itbl_add_insn (int yyproc, char *name,
+ unsigned long value, int sbit, int ebit, unsigned long flags);
+struct itbl_field *itbl_add_operand (struct itbl_entry * e, int yytype,
+ int sbit, int ebit, unsigned long flags);
diff --git a/x/binutils/gas/itbl-parse.y b/x/binutils/gas/itbl-parse.y
new file mode 100644
index 0000000..9a0b7c3
--- /dev/null
+++ b/x/binutils/gas/itbl-parse.y
@@ -0,0 +1,460 @@
+/* itbl-parse.y
+ Copyright 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+%{
+
+/*
+
+Yacc grammar for instruction table entries.
+
+=======================================================================
+Original Instruction table specification document:
+
+ MIPS Coprocessor Table Specification
+ ====================================
+
+This document describes the format of the MIPS coprocessor table. The
+table specifies a list of valid functions, data registers and control
+registers that can be used in coprocessor instructions. This list,
+together with the coprocessor instruction classes listed below,
+specifies the complete list of coprocessor instructions that will
+be recognized and assembled by the GNU assembler. In effect,
+this makes the GNU assembler table-driven, where the table is
+specified by the programmer.
+
+The table is an ordinary text file that the GNU assembler reads when
+it starts. Using the information in the table, the assembler
+generates an internal list of valid coprocessor registers and
+functions. The assembler uses this internal list in addition to the
+standard MIPS registers and instructions which are built-in to the
+assembler during code generation.
+
+To specify the coprocessor table when invoking the GNU assembler, use
+the command line option "--itbl file", where file is the
+complete name of the table, including path and extension.
+
+Examples:
+
+ gas -t cop.tbl test.s -o test.o
+ gas -t /usr/local/lib/cop.tbl test.s -o test.o
+ gas --itbl d:\gnu\data\cop.tbl test.s -o test.o
+
+Only one table may be supplied during a single invocation of
+the assembler.
+
+
+Instruction classes
+===================
+
+Below is a list of the valid coprocessor instruction classes for
+any given coprocessor "z". These instructions are already recognized
+by the assembler, and are listed here only for reference.
+
+Class format instructions
+-------------------------------------------------
+Class1:
+ op base rt offset
+ LWCz rt,offset (base)
+ SWCz rt,offset (base)
+Class2:
+ COPz sub rt rd 0
+ MTCz rt,rd
+ MFCz rt,rd
+ CTCz rt,rd
+ CFCz rt,rd
+Class3:
+ COPz CO cofun
+ COPz cofun
+Class4:
+ COPz BC br offset
+ BCzT offset
+ BCzF offset
+Class5:
+ COPz sub rt rd 0
+ DMFCz rt,rd
+ DMTCz rt,rd
+Class6:
+ op base rt offset
+ LDCz rt,offset (base)
+ SDCz rt,offset (base)
+Class7:
+ COPz BC br offset
+ BCzTL offset
+ BCzFL offset
+
+The coprocessor table defines coprocessor-specific registers that can
+be used with all of the above classes of instructions, where
+appropriate. It also defines additional coprocessor-specific
+functions for Class3 (COPz cofun) instructions, Thus, the table allows
+the programmer to use convenient mnemonics and operands for these
+functions, instead of the COPz mmenmonic and cofun operand.
+
+The names of the MIPS general registers and their aliases are defined
+by the assembler and will be recognized as valid register names by the
+assembler when used (where allowed) in coprocessor instructions.
+However, the names and values of all coprocessor data and control
+register mnemonics must be specified in the coprocessor table.
+
+
+Table Grammar
+=============
+
+Here is the grammar for the coprocessor table:
+
+ table -> entry*
+
+ entry -> [z entrydef] [comment] '\n'
+
+ entrydef -> type name val
+ entrydef -> 'insn' name val funcdef ; type of entry (instruction)
+
+ z -> 'p'['0'..'3'] ; processor number
+ type -> ['dreg' | 'creg' | 'greg' ] ; type of entry (register)
+ ; 'dreg', 'creg' or 'greg' specifies a data, control, or general
+ ; register mnemonic, respectively
+ name -> [ltr|dec]* ; mnemonic of register/function
+ val -> [dec|hex] ; register/function number (integer constant)
+
+ funcdef -> frange flags fields
+ ; bitfield range for opcode
+ ; list of fields' formats
+ fields -> field*
+ field -> [','] ftype frange flags
+ flags -> ['*' flagexpr]
+ flagexpr -> '[' flagexpr ']'
+ flagexpr -> val '|' flagexpr
+ ftype -> [ type | 'immed' | 'addr' ]
+ ; 'immed' specifies an immediate value; see grammar for "val" above
+ ; 'addr' specifies a C identifier; name of symbol to be resolved at
+ ; link time
+ frange -> ':' val '-' val ; starting to ending bit positions, where
+ ; where 0 is least significant bit
+ frange -> (null) ; default range of 31-0 will be assumed
+
+ comment -> [';'|'#'] [char]*
+ char -> any printable character
+ ltr -> ['a'..'z'|'A'..'Z']
+ dec -> ['0'..'9']* ; value in decimal
+ hex -> '0x'['0'..'9' | 'a'..'f' | 'A'..'F']* ; value in hexidecimal
+
+
+Examples
+========
+
+Example 1:
+
+The table:
+
+ p1 dreg d1 1 ; data register "d1" for COP1 has value 1
+ p1 creg c3 3 ; ctrl register "c3" for COP1 has value 3
+ p3 func fill 0x1f:24-20 ; function "fill" for COP3 has value 31 and
+ ; no fields
+
+will allow the assembler to accept the following coprocessor instructions:
+
+ LWC1 d1,0x100 ($2)
+ fill
+
+Here, the general purpose register "$2", and instruction "LWC1", are standard
+mnemonics built-in to the MIPS assembler.
+
+
+Example 2:
+
+The table:
+
+ p3 dreg d3 3 ; data register "d3" for COP3 has value 3
+ p3 creg c2 22 ; control register "c2" for COP3 has value 22
+ p3 func fee 0x1f:24-20 dreg:17-13 creg:12-8 immed:7-0
+ ; function "fee" for COP3 has value 31, and 3 fields
+ ; consisting of a data register, a control register,
+ ; and an immediate value.
+
+will allow the assembler to accept the following coprocessor instruction:
+
+ fee d3,c2,0x1
+
+and will emit the object code:
+
+ 31-26 25 24-20 19-18 17-13 12-8 7-0
+ COPz CO fun dreg creg immed
+ 010011 1 11111 00 00011 10110 00000001
+
+ 0x4ff07601
+
+
+Example 3:
+
+The table:
+
+ p3 dreg d3 3 ; data register "d3" for COP3 has value 3
+ p3 creg c2 22 ; control register "c2" for COP3 has value 22
+ p3 func fuu 0x01f00001 dreg:17-13 creg:12-8
+
+will allow the assembler to accept the following coprocessor
+instruction:
+
+ fuu d3,c2
+
+and will emit the object code:
+
+ 31-26 25 24-20 19-18 17-13 12-8 7-0
+ COPz CO fun dreg creg
+ 010011 1 11111 00 00011 10110 00000001
+
+ 0x4ff07601
+
+In this way, the programmer can force arbitrary bits of an instruction
+to have predefined values.
+
+=======================================================================
+Additional notes:
+
+Encoding of ranges:
+To handle more than one bit position range within an instruction,
+use 0s to mask out the ranges which don't apply.
+May decide to modify the syntax to allow commas separate multiple
+ranges within an instruction (range','range).
+
+Changes in grammar:
+ The number of parms argument to the function entry
+was deleted from the original format such that we now count the fields.
+
+----
+FIXME! should really change lexical analyzer
+to recognize 'dreg' etc. in context sensative way.
+Currently function names or mnemonics may be incorrectly parsed as keywords
+
+FIXME! hex is ambiguous with any digit
+
+*/
+
+#include <stdio.h>
+#include "itbl-ops.h"
+
+/* #define DEBUG */
+
+#ifdef DEBUG
+#ifndef DBG_LVL
+#define DBG_LVL 1
+#endif
+#else
+#define DBG_LVL 0
+#endif
+
+#if DBG_LVL >= 1
+#define DBG(x) printf x
+#else
+#define DBG(x)
+#endif
+
+#if DBG_LVL >= 2
+#define DBGL2(x) printf x
+#else
+#define DBGL2(x)
+#endif
+
+static int sbit, ebit;
+static struct itbl_entry *insn=0;
+extern int insntbl_line;
+int yyparse PARAMS ((void));
+int yylex PARAMS ((void));
+static int yyerror PARAMS ((const char *));
+
+%}
+
+%union
+ {
+ char *str;
+ int num;
+ int processor;
+ unsigned long val;
+ }
+
+%token DREG CREG GREG IMMED ADDR INSN NUM ID NL PNUM
+%type <val> value flags flagexpr
+%type <num> number NUM ftype regtype pnum PNUM
+%type <str> ID name
+
+%start insntbl
+
+%%
+
+insntbl:
+ entrys
+ ;
+
+entrys:
+ entry entrys
+ |
+ ;
+
+entry:
+ pnum regtype name value NL
+ {
+ DBG (("line %d: entry pnum=%d type=%d name=%s value=x%x\n",
+ insntbl_line, $1, $2, $3, $4));
+ itbl_add_reg ($1, $2, $3, $4);
+ }
+ | pnum INSN name value range flags
+ {
+ DBG (("line %d: entry pnum=%d type=INSN name=%s value=x%x",
+ insntbl_line, $1, $3, $4));
+ DBG ((" sbit=%d ebit=%d flags=0x%x\n", sbit, ebit, $6));
+ insn=itbl_add_insn ($1, $3, $4, sbit, ebit, $6);
+ }
+ fieldspecs NL
+ {}
+ | NL
+ | error NL
+ ;
+
+fieldspecs:
+ ',' fieldspec fieldspecs
+ | fieldspec fieldspecs
+ |
+ ;
+
+ftype:
+ regtype
+ {
+ DBGL2 (("ftype\n"));
+ $$ = $1;
+ }
+ | ADDR
+ {
+ DBGL2 (("addr\n"));
+ $$ = ADDR;
+ }
+ | IMMED
+ {
+ DBGL2 (("immed\n"));
+ $$ = IMMED;
+ }
+ ;
+
+fieldspec:
+ ftype range flags
+ {
+ DBG (("line %d: field type=%d sbit=%d ebit=%d, flags=0x%x\n",
+ insntbl_line, $1, sbit, ebit, $3));
+ itbl_add_operand (insn, $1, sbit, ebit, $3);
+ }
+ ;
+
+flagexpr:
+ NUM '|' flagexpr
+ {
+ $$ = $1 | $3;
+ }
+ | '[' flagexpr ']'
+ {
+ $$ = $2;
+ }
+ | NUM
+ {
+ $$ = $1;
+ }
+ ;
+
+flags:
+ '*' flagexpr
+ {
+ DBGL2 (("flags=%d\n", $2));
+ $$ = $2;
+ }
+ |
+ {
+ $$ = 0;
+ }
+ ;
+
+range:
+ ':' NUM '-' NUM
+ {
+ DBGL2 (("range %d %d\n", $2, $4));
+ sbit = $2;
+ ebit = $4;
+ }
+ |
+ {
+ sbit = 31;
+ ebit = 0;
+ }
+ ;
+
+pnum:
+ PNUM
+ {
+ DBGL2 (("pnum=%d\n",$1));
+ $$ = $1;
+ }
+ ;
+
+regtype:
+ DREG
+ {
+ DBGL2 (("dreg\n"));
+ $$ = DREG;
+ }
+ | CREG
+ {
+ DBGL2 (("creg\n"));
+ $$ = CREG;
+ }
+ | GREG
+ {
+ DBGL2 (("greg\n"));
+ $$ = GREG;
+ }
+ ;
+
+name:
+ ID
+ {
+ DBGL2 (("name=%s\n",$1));
+ $$ = $1;
+ }
+ ;
+
+number:
+ NUM
+ {
+ DBGL2 (("num=%d\n",$1));
+ $$ = $1;
+ }
+ ;
+
+value:
+ NUM
+ {
+ DBGL2 (("val=x%x\n",$1));
+ $$ = $1;
+ }
+ ;
+%%
+
+static int
+yyerror (msg)
+ const char *msg;
+{
+ printf ("line %d: %s\n", insntbl_line, msg);
+ return 0;
+}
diff --git a/x/binutils/gas/link.cmd b/x/binutils/gas/link.cmd
new file mode 100644
index 0000000..a035ca8
--- /dev/null
+++ b/x/binutils/gas/link.cmd
@@ -0,0 +1,10 @@
+ALIGN=1024
+RESNUM 0x0000, 0x8000
+; Putting in .lit1 gives errors.
+ORDER .data=0x80002000, .data1, .lit, .bss
+; Let's put this on the command line so it goes first, which is what
+; GDB expects.
+; LOAD /s2/amd/29k/lib/crt0.o
+LOAD /s2/amd/29k/lib/libqcb0h.lib
+LOAD /s2/amd/29k/lib/libscb0h.lib
+LOAD /s2/amd/29k/lib/libacb0h.lib
diff --git a/x/binutils/gas/listing.c b/x/binutils/gas/listing.c
new file mode 100644
index 0000000..aa22c5e
--- /dev/null
+++ b/x/binutils/gas/listing.c
@@ -0,0 +1,1344 @@
+/* listing.c - maintain assembly listings
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002, 2003
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Contributed by Steve Chamberlain <sac@cygnus.com>
+
+ A listing page looks like:
+
+ LISTING_HEADER sourcefilename pagenumber
+ TITLE LINE
+ SUBTITLE LINE
+ linenumber address data source
+ linenumber address data source
+ linenumber address data source
+ linenumber address data source
+
+ If not overridden, the listing commands are:
+
+ .title "stuff"
+ Put "stuff" onto the title line
+ .sbttl "stuff"
+ Put stuff onto the subtitle line
+
+ If these commands come within 10 lines of the top of the page, they
+ will affect the page they are on, as well as any subsequent page
+
+ .eject
+ Thow a page
+ .list
+ Increment the enable listing counter
+ .nolist
+ Decrement the enable listing counter
+
+ .psize Y[,X]
+ Set the paper size to X wide and Y high. Setting a psize Y of
+ zero will suppress form feeds except where demanded by .eject
+
+ If the counter goes below zero, listing is suppressed.
+
+ Listings are a maintained by read calling various listing_<foo>
+ functions. What happens most is that the macro NO_LISTING is not
+ defined (from the Makefile), then the macro LISTING_NEWLINE expands
+ into a call to listing_newline. The call is done from read.c, every
+ time it sees a newline, and -l is on the command line.
+
+ The function listing_newline remembers the frag associated with the
+ newline, and creates a new frag - note that this is wasteful, but not
+ a big deal, since listing slows things down a lot anyway. The
+ function also remembers when the filename changes.
+
+ When all the input has finished, and gas has had a chance to settle
+ down, the listing is output. This is done by running down the list of
+ frag/source file records, and opening the files as needed and printing
+ out the bytes and chars associated with them.
+
+ The only things which the architecture can change about the listing
+ are defined in these macros:
+
+ LISTING_HEADER The name of the architecture
+ LISTING_WORD_SIZE The make of the number of bytes in a word, this determines
+ the clumping of the output data. eg a value of
+ 2 makes words look like 1234 5678, whilst 1
+ would make the same value look like 12 34 56
+ 78
+ LISTING_LHS_WIDTH Number of words of above size for the lhs
+
+ LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs
+ for the second line
+
+ LISTING_LHS_CONT_LINES Max number of lines to use up for a continuation
+ LISTING_RHS_WIDTH Number of chars from the input file to print
+ on a line. */
+
+#include "as.h"
+#include "obstack.h"
+#include "safe-ctype.h"
+#include "input-file.h"
+#include "subsegs.h"
+
+#ifndef NO_LISTING
+
+#ifndef LISTING_HEADER
+#define LISTING_HEADER "GAS LISTING"
+#endif
+#ifndef LISTING_WORD_SIZE
+#define LISTING_WORD_SIZE 4
+#endif
+#ifndef LISTING_LHS_WIDTH
+#define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE))
+#endif
+#ifndef LISTING_LHS_WIDTH_SECOND
+#define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH
+#endif
+#ifndef LISTING_RHS_WIDTH
+#define LISTING_RHS_WIDTH 100
+#endif
+#ifndef LISTING_LHS_CONT_LINES
+#define LISTING_LHS_CONT_LINES 4
+#endif
+
+/* This structure remembers which .s were used. */
+typedef struct file_info_struct
+{
+ struct file_info_struct * next;
+ char * filename;
+ long pos;
+ unsigned int linenum;
+ int at_end;
+} file_info_type;
+
+/* This structure remembers which line from which file goes into which
+ frag. */
+struct list_info_struct
+{
+ /* Frag which this line of source is nearest to. */
+ fragS *frag;
+
+ /* The actual line in the source file. */
+ unsigned int line;
+
+ /* Pointer to the file info struct for the file which this line
+ belongs to. */
+ file_info_type *file;
+
+ /* The expanded text of any macro that may have been executing. */
+ char *line_contents;
+
+ /* Next in list. */
+ struct list_info_struct *next;
+
+ /* Pointer to the file info struct for the high level language
+ source line that belongs here. */
+ file_info_type *hll_file;
+
+ /* High level language source line. */
+ unsigned int hll_line;
+
+ /* Pointer to any error message associated with this line. */
+ char *message;
+
+ enum
+ {
+ EDICT_NONE,
+ EDICT_SBTTL,
+ EDICT_TITLE,
+ EDICT_NOLIST,
+ EDICT_LIST,
+ EDICT_NOLIST_NEXT,
+ EDICT_EJECT
+ } edict;
+ char *edict_arg;
+
+ /* Nonzero if this line is to be omitted because it contains
+ debugging information. This can become a flags field if we come
+ up with more information to store here. */
+ int debugging;
+};
+
+typedef struct list_info_struct list_info_type;
+
+int listing_lhs_width = LISTING_LHS_WIDTH;
+int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND;
+int listing_lhs_cont_lines = LISTING_LHS_CONT_LINES;
+int listing_rhs_width = LISTING_RHS_WIDTH;
+
+struct list_info_struct * listing_tail;
+
+static file_info_type * file_info_head;
+static file_info_type * last_open_file_info;
+static FILE * last_open_file;
+static struct list_info_struct * head;
+static int paper_width = 200;
+static int paper_height = 60;
+
+extern int listing;
+
+/* File to output listings to. */
+static FILE *list_file;
+
+/* This static array is used to keep the text of data to be printed
+ before the start of the line. */
+
+#define MAX_BYTES \
+ (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width \
+ + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second) \
+ * listing_lhs_cont_lines) \
+ + 20)
+
+static char *data_buffer;
+
+/* Prototypes. */
+static void listing_message (const char *, const char *);
+static file_info_type *file_info (const char *);
+static void new_frag (void);
+static char *buffer_line (file_info_type *, char *, unsigned int);
+static void listing_page (list_info_type *);
+static unsigned int calc_hex (list_info_type *);
+static void print_lines (list_info_type *, unsigned int, char *, unsigned int);
+static void list_symbol_table (void);
+static void print_source (file_info_type *, list_info_type *, char *, unsigned int);
+static int debugging_pseudo (list_info_type *, const char *);
+static void listing_listing (char *);
+
+static void
+listing_message (const char *name, const char *message)
+{
+ if (listing_tail != (list_info_type *) NULL)
+ {
+ unsigned int l = strlen (name) + strlen (message) + 1;
+ char *n = (char *) xmalloc (l);
+ strcpy (n, name);
+ strcat (n, message);
+ listing_tail->message = n;
+ }
+}
+
+void
+listing_warning (const char *message)
+{
+ listing_message (_("Warning:"), message);
+}
+
+void
+listing_error (const char *message)
+{
+ listing_message (_("Error:"), message);
+}
+
+static file_info_type *
+file_info (const char *file_name)
+{
+ /* Find an entry with this file name. */
+ file_info_type *p = file_info_head;
+
+ while (p != (file_info_type *) NULL)
+ {
+ if (strcmp (p->filename, file_name) == 0)
+ return p;
+ p = p->next;
+ }
+
+ /* Make new entry. */
+ p = xmalloc (sizeof (file_info_type));
+ p->next = file_info_head;
+ file_info_head = p;
+ p->filename = xstrdup (file_name);
+ p->pos = 0;
+ p->linenum = 0;
+ p->at_end = 0;
+
+ return p;
+}
+
+static void
+new_frag (void)
+{
+ frag_wane (frag_now);
+ frag_new (0);
+}
+
+void
+listing_newline (char *ps)
+{
+ char *file;
+ unsigned int line;
+ static unsigned int last_line = 0xffff;
+ static char *last_file = NULL;
+ list_info_type *new = NULL;
+
+ if (listing == 0)
+ return;
+
+ if (now_seg == absolute_section)
+ return;
+
+#ifdef OBJ_ELF
+ /* In ELF, anything in a section beginning with .debug or .line is
+ considered to be debugging information. This includes the
+ statement which switches us into the debugging section, which we
+ can only set after we are already in the debugging section. */
+ if ((listing & LISTING_NODEBUG) != 0
+ && listing_tail != NULL
+ && ! listing_tail->debugging)
+ {
+ const char *segname;
+
+ segname = segment_name (now_seg);
+ if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
+ || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
+ listing_tail->debugging = 1;
+ }
+#endif
+
+ as_where (&file, &line);
+ if (ps == NULL)
+ {
+ if (line == last_line
+ && !(last_file && file && strcmp (file, last_file)))
+ return;
+
+ new = (list_info_type *) xmalloc (sizeof (list_info_type));
+
+ /* Detect if we are reading from stdin by examining the file
+ name returned by as_where().
+
+ [FIXME: We rely upon the name in the strcmp below being the
+ same as the one used by input_scrub_new_file(), if that is
+ not true, then this code will fail].
+
+ If we are reading from stdin, then we need to save each input
+ line here (assuming of course that we actually have a line of
+ input to read), so that it can be displayed in the listing
+ that is produced at the end of the assembly. */
+ if (strcmp (file, _("{standard input}")) == 0
+ && input_line_pointer != NULL)
+ {
+ char *copy;
+ int len;
+ int seen_quote = 0;
+
+ for (copy = input_line_pointer - 1;
+ *copy && (seen_quote
+ || (! is_end_of_line [(unsigned char) *copy]));
+ copy++)
+ if (*copy == '"' && copy[-1] != '\\')
+ seen_quote = ! seen_quote;
+
+ len = (copy - input_line_pointer) + 2;
+
+ copy = xmalloc (len);
+
+ if (copy != NULL)
+ {
+ char *src = input_line_pointer - 1;
+ char *dest = copy;
+
+ while (--len)
+ {
+ unsigned char c = *src++;
+
+ /* Omit control characters in the listing. */
+ if (!ISCNTRL (c))
+ *dest++ = c;
+ }
+
+ *dest = 0;
+ }
+
+ new->line_contents = copy;
+ }
+ else
+ new->line_contents = NULL;
+ }
+ else
+ {
+ new = xmalloc (sizeof (list_info_type));
+ new->line_contents = ps;
+ }
+
+ last_line = line;
+ last_file = file;
+
+ new_frag ();
+
+ if (listing_tail)
+ listing_tail->next = new;
+ else
+ head = new;
+
+ listing_tail = new;
+
+ new->frag = frag_now;
+ new->line = line;
+ new->file = file_info (file);
+ new->next = (list_info_type *) NULL;
+ new->message = (char *) NULL;
+ new->edict = EDICT_NONE;
+ new->hll_file = (file_info_type *) NULL;
+ new->hll_line = 0;
+ new->debugging = 0;
+
+ new_frag ();
+
+#ifdef OBJ_ELF
+ /* In ELF, anything in a section beginning with .debug or .line is
+ considered to be debugging information. */
+ if ((listing & LISTING_NODEBUG) != 0)
+ {
+ const char *segname;
+
+ segname = segment_name (now_seg);
+ if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
+ || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
+ new->debugging = 1;
+ }
+#endif
+}
+
+/* Attach all current frags to the previous line instead of the
+ current line. This is called by the MIPS backend when it discovers
+ that it needs to add some NOP instructions; the added NOP
+ instructions should go with the instruction that has the delay, not
+ with the new instruction. */
+
+void
+listing_prev_line (void)
+{
+ list_info_type *l;
+ fragS *f;
+
+ if (head == (list_info_type *) NULL
+ || head == listing_tail)
+ return;
+
+ new_frag ();
+
+ for (l = head; l->next != listing_tail; l = l->next)
+ ;
+
+ for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
+ if (f->line == listing_tail)
+ f->line = l;
+
+ listing_tail->frag = frag_now;
+ new_frag ();
+}
+
+/* This function returns the next source line from the file supplied,
+ truncated to size. It appends a fake line to the end of each input
+ file to make. */
+
+static char *
+buffer_line (file_info_type *file, char *line, unsigned int size)
+{
+ unsigned int count = 0;
+ int c;
+
+ char *p = line;
+
+ /* If we couldn't open the file, return an empty line. */
+ if (file->at_end)
+ return "";
+
+ /* Check the cache and see if we last used this file. */
+ if (!last_open_file_info || file != last_open_file_info)
+ {
+ if (last_open_file)
+ {
+ last_open_file_info->pos = ftell (last_open_file);
+ fclose (last_open_file);
+ }
+
+ last_open_file_info = file;
+ last_open_file = fopen (file->filename, FOPEN_RT);
+ if (last_open_file == NULL)
+ {
+ file->at_end = 1;
+ return "";
+ }
+
+ /* Seek to where we were last time this file was open. */
+ if (file->pos)
+ fseek (last_open_file, file->pos, SEEK_SET);
+ }
+
+ c = fgetc (last_open_file);
+
+ /* Leave room for null. */
+ size -= 1;
+
+ while (c != EOF && c != '\n')
+ {
+ if (count < size)
+ *p++ = c;
+ count++;
+
+ c = fgetc (last_open_file);
+
+ }
+ if (c == EOF)
+ {
+ file->at_end = 1;
+ if (count + 2 < size)
+ {
+ *p++ = '.';
+ *p++ = '.';
+ *p++ = '.';
+ }
+ }
+ file->linenum++;
+ *p++ = 0;
+ return line;
+}
+
+static const char *fn;
+
+static unsigned int eject; /* Eject pending */
+static unsigned int page; /* Current page number */
+static char *title; /* Current title */
+static char *subtitle; /* Current subtitle */
+static unsigned int on_page; /* Number of lines printed on current page */
+
+static void
+listing_page (list_info_type *list)
+{
+ /* Grope around, see if we can see a title or subtitle edict coming up
+ soon. (we look down 10 lines of the page and see if it's there) */
+ if ((eject || (on_page >= (unsigned int) paper_height))
+ && paper_height != 0)
+ {
+ unsigned int c = 10;
+ int had_title = 0;
+ int had_subtitle = 0;
+
+ page++;
+
+ while (c != 0 && list)
+ {
+ if (list->edict == EDICT_SBTTL && !had_subtitle)
+ {
+ had_subtitle = 1;
+ subtitle = list->edict_arg;
+ }
+ if (list->edict == EDICT_TITLE && !had_title)
+ {
+ had_title = 1;
+ title = list->edict_arg;
+ }
+ list = list->next;
+ c--;
+ }
+
+ if (page > 1)
+ {
+ fprintf (list_file, "\f");
+ }
+
+ fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
+ fprintf (list_file, "%s\n", title);
+ fprintf (list_file, "%s\n", subtitle);
+ on_page = 3;
+ eject = 0;
+ }
+}
+
+static unsigned int
+calc_hex (list_info_type *list)
+{
+ int data_buffer_size;
+ list_info_type *first = list;
+ unsigned int address = ~(unsigned int) 0;
+ fragS *frag;
+ fragS *frag_ptr;
+ unsigned int octet_in_frag;
+
+ /* Find first frag which says it belongs to this line. */
+ frag = list->frag;
+ while (frag && frag->line != list)
+ frag = frag->fr_next;
+
+ frag_ptr = frag;
+
+ data_buffer_size = 0;
+
+ /* Dump all the frags which belong to this line. */
+ while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
+ {
+ /* Print as many bytes from the fixed part as is sensible. */
+ octet_in_frag = 0;
+ while ((offsetT) octet_in_frag < frag_ptr->fr_fix
+ && data_buffer_size < MAX_BYTES - 3)
+ {
+ if (address == ~(unsigned int) 0)
+ address = frag_ptr->fr_address / OCTETS_PER_BYTE;
+
+ sprintf (data_buffer + data_buffer_size,
+ "%02X",
+ (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
+ data_buffer_size += 2;
+ octet_in_frag++;
+ }
+ if (frag_ptr->fr_type == rs_fill)
+ {
+ unsigned int var_rep_max = octet_in_frag;
+ unsigned int var_rep_idx = octet_in_frag;
+
+ /* Print as many bytes from the variable part as is sensible. */
+ while (((offsetT) octet_in_frag
+ < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset))
+ && data_buffer_size < MAX_BYTES - 3)
+ {
+ if (address == ~(unsigned int) 0)
+ address = frag_ptr->fr_address / OCTETS_PER_BYTE;
+
+ sprintf (data_buffer + data_buffer_size,
+ "%02X",
+ (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
+#if 0
+ data_buffer[data_buffer_size++] = '*';
+ data_buffer[data_buffer_size++] = '*';
+#endif
+ data_buffer_size += 2;
+
+ var_rep_idx++;
+ octet_in_frag++;
+
+ if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
+ var_rep_idx = var_rep_max;
+ }
+ }
+
+ frag_ptr = frag_ptr->fr_next;
+ }
+ data_buffer[data_buffer_size] = '\0';
+ return address;
+}
+
+static void
+print_lines (list_info_type *list, unsigned int lineno,
+ char *string, unsigned int address)
+{
+ unsigned int idx;
+ unsigned int nchars;
+ unsigned int lines;
+ unsigned int octet_in_word = 0;
+ char *src = data_buffer;
+ int cur;
+
+ /* Print the stuff on the first line. */
+ listing_page (list);
+ nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
+
+ /* Print the hex for the first line. */
+ if (address == ~(unsigned int) 0)
+ {
+ fprintf (list_file, "% 4d ", lineno);
+ for (idx = 0; idx < nchars; idx++)
+ fprintf (list_file, " ");
+
+ fprintf (list_file, "\t%s\n", string ? string : "");
+
+ on_page++;
+
+ listing_page (0);
+
+ return;
+ }
+
+ if (had_errors ())
+ fprintf (list_file, "% 4d ???? ", lineno);
+ else
+ fprintf (list_file, "% 4d %04x ", lineno, address);
+
+ /* And the data to go along with it. */
+ idx = 0;
+ cur = 0;
+ while (src[cur] && idx < nchars)
+ {
+ int offset;
+ offset = cur;
+ fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
+ cur += 2;
+ octet_in_word++;
+
+ if (octet_in_word == LISTING_WORD_SIZE)
+ {
+ fprintf (list_file, " ");
+ idx++;
+ octet_in_word = 0;
+ }
+
+ idx += 2;
+ }
+
+ for (; idx < nchars; idx++)
+ fprintf (list_file, " ");
+
+ fprintf (list_file, "\t%s\n", string ? string : "");
+ on_page++;
+ listing_page (list);
+
+ if (list->message)
+ {
+ fprintf (list_file, "**** %s\n", list->message);
+ listing_page (list);
+ on_page++;
+ }
+
+ for (lines = 0;
+ lines < (unsigned int) listing_lhs_cont_lines
+ && src[cur];
+ lines++)
+ {
+ nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
+ idx = 0;
+
+ /* Print any more lines of data, but more compactly. */
+ fprintf (list_file, "% 4d ", lineno);
+
+ while (src[cur] && idx < nchars)
+ {
+ int offset;
+ offset = cur;
+ fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
+ cur += 2;
+ idx += 2;
+ octet_in_word++;
+
+ if (octet_in_word == LISTING_WORD_SIZE)
+ {
+ fprintf (list_file, " ");
+ idx++;
+ octet_in_word = 0;
+ }
+ }
+
+ fprintf (list_file, "\n");
+ on_page++;
+ listing_page (list);
+ }
+}
+
+static void
+list_symbol_table (void)
+{
+ extern symbolS *symbol_rootP;
+ int got_some = 0;
+
+ symbolS *ptr;
+ eject = 1;
+ listing_page (0);
+
+ for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
+ {
+ if (SEG_NORMAL (S_GET_SEGMENT (ptr))
+ || S_GET_SEGMENT (ptr) == absolute_section)
+ {
+#ifdef BFD_ASSEMBLER
+ /* Don't report section symbols. They are not interesting. */
+ if (symbol_section_p (ptr))
+ continue;
+#endif
+ if (S_GET_NAME (ptr))
+ {
+ char buf[30], fmt[8];
+ valueT val = S_GET_VALUE (ptr);
+
+ /* @@ Note that this is dependent on the compilation options,
+ not solely on the target characteristics. */
+ if (sizeof (val) == 4 && sizeof (int) == 4)
+ sprintf (buf, "%08lx", (unsigned long) val);
+ else if (sizeof (val) <= sizeof (unsigned long))
+ {
+ sprintf (fmt, "%%0%lulx",
+ (unsigned long) (sizeof (val) * 2));
+ sprintf (buf, fmt, (unsigned long) val);
+ }
+#if defined (BFD64)
+ else if (sizeof (val) > 4)
+ sprintf_vma (buf, val);
+#endif
+ else
+ abort ();
+
+ if (!got_some)
+ {
+ fprintf (list_file, "DEFINED SYMBOLS\n");
+ on_page++;
+ got_some = 1;
+ }
+
+ if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
+ {
+ fprintf (list_file, "%20s:%-5d %s:%s %s\n",
+ symbol_get_frag (ptr)->line->file->filename,
+ symbol_get_frag (ptr)->line->line,
+ segment_name (S_GET_SEGMENT (ptr)),
+ buf, S_GET_NAME (ptr));
+ }
+ else
+ {
+ fprintf (list_file, "%33s:%s %s\n",
+ segment_name (S_GET_SEGMENT (ptr)),
+ buf, S_GET_NAME (ptr));
+ }
+
+ on_page++;
+ listing_page (0);
+ }
+ }
+
+ }
+ if (!got_some)
+ {
+ fprintf (list_file, "NO DEFINED SYMBOLS\n");
+ on_page++;
+ }
+ fprintf (list_file, "\n");
+ on_page++;
+ listing_page (0);
+
+ got_some = 0;
+
+ for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
+ {
+ if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
+ {
+ if (S_GET_SEGMENT (ptr) == undefined_section)
+ {
+ if (!got_some)
+ {
+ got_some = 1;
+ fprintf (list_file, "UNDEFINED SYMBOLS\n");
+ on_page++;
+ listing_page (0);
+ }
+ fprintf (list_file, "%s\n", S_GET_NAME (ptr));
+ on_page++;
+ listing_page (0);
+ }
+ }
+ }
+ if (!got_some)
+ {
+ fprintf (list_file, "NO UNDEFINED SYMBOLS\n");
+ on_page++;
+ listing_page (0);
+ }
+}
+
+static void
+print_source (file_info_type *current_file, list_info_type *list,
+ char *buffer, unsigned int width)
+{
+ if (!current_file->at_end)
+ {
+ while (current_file->linenum < list->hll_line
+ && !current_file->at_end)
+ {
+ char *p = buffer_line (current_file, buffer, width);
+
+ fprintf (list_file, "%4u:%-13s **** %s\n", current_file->linenum,
+ current_file->filename, p);
+ on_page++;
+ listing_page (list);
+ }
+ }
+}
+
+/* Sometimes the user doesn't want to be bothered by the debugging
+ records inserted by the compiler, see if the line is suspicious. */
+
+static int
+debugging_pseudo (list_info_type *list, const char *line)
+{
+ static int in_debug;
+ int was_debug;
+
+ if (list->debugging)
+ {
+ in_debug = 1;
+ return 1;
+ }
+
+ was_debug = in_debug;
+ in_debug = 0;
+
+ while (ISSPACE (*line))
+ line++;
+
+ if (*line != '.')
+ {
+#ifdef OBJ_ELF
+ /* The ELF compiler sometimes emits blank lines after switching
+ out of a debugging section. If the next line drops us back
+ into debugging information, then don't print the blank line.
+ This is a hack for a particular compiler behaviour, not a
+ general case. */
+ if (was_debug
+ && *line == '\0'
+ && list->next != NULL
+ && list->next->debugging)
+ {
+ in_debug = 1;
+ return 1;
+ }
+#endif
+
+ return 0;
+ }
+
+ line++;
+
+ if (strncmp (line, "def", 3) == 0)
+ return 1;
+ if (strncmp (line, "val", 3) == 0)
+ return 1;
+ if (strncmp (line, "scl", 3) == 0)
+ return 1;
+ if (strncmp (line, "line", 4) == 0)
+ return 1;
+ if (strncmp (line, "endef", 5) == 0)
+ return 1;
+ if (strncmp (line, "ln", 2) == 0)
+ return 1;
+ if (strncmp (line, "type", 4) == 0)
+ return 1;
+ if (strncmp (line, "size", 4) == 0)
+ return 1;
+ if (strncmp (line, "dim", 3) == 0)
+ return 1;
+ if (strncmp (line, "tag", 3) == 0)
+ return 1;
+ if (strncmp (line, "stabs", 5) == 0)
+ return 1;
+ if (strncmp (line, "stabn", 5) == 0)
+ return 1;
+
+ return 0;
+}
+
+static void
+listing_listing (char *name ATTRIBUTE_UNUSED)
+{
+ list_info_type *list = head;
+ file_info_type *current_hll_file = (file_info_type *) NULL;
+ char *message;
+ char *buffer;
+ char *p;
+ int show_listing = 1;
+ unsigned int width;
+
+ buffer = xmalloc (listing_rhs_width);
+ data_buffer = xmalloc (MAX_BYTES);
+ eject = 1;
+ list = head;
+
+ while (list != (list_info_type *) NULL && 0)
+ {
+ if (list->next)
+ list->frag = list->next->frag;
+ list = list->next;
+ }
+
+ list = head->next;
+
+ while (list)
+ {
+ unsigned int list_line;
+
+ width = listing_rhs_width > paper_width ? paper_width :
+ listing_rhs_width;
+
+ list_line = list->line;
+ switch (list->edict)
+ {
+ case EDICT_LIST:
+ /* Skip all lines up to the current. */
+ list_line--;
+ break;
+ case EDICT_NOLIST:
+ show_listing--;
+ break;
+ case EDICT_NOLIST_NEXT:
+ if (show_listing == 0)
+ list_line--;
+ break;
+ case EDICT_EJECT:
+ break;
+ case EDICT_NONE:
+ break;
+ case EDICT_TITLE:
+ title = list->edict_arg;
+ break;
+ case EDICT_SBTTL:
+ subtitle = list->edict_arg;
+ break;
+ default:
+ abort ();
+ }
+
+ if (show_listing <= 0)
+ {
+ while (list->file->linenum < list_line
+ && !list->file->at_end)
+ p = buffer_line (list->file, buffer, width);
+ }
+
+ if (list->edict == EDICT_LIST
+ || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
+ {
+ /* Enable listing for the single line that caused the enable. */
+ list_line++;
+ show_listing++;
+ }
+
+ if (show_listing > 0)
+ {
+ /* Scan down the list and print all the stuff which can be done
+ with this line (or lines). */
+ message = 0;
+
+ if (list->hll_file)
+ current_hll_file = list->hll_file;
+
+ if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
+ print_source (current_hll_file, list, buffer, width);
+
+ if (list->line_contents)
+ {
+ if (!((listing & LISTING_NODEBUG)
+ && debugging_pseudo (list, list->line_contents)))
+ print_lines (list,
+ list->file->linenum == 0 ? list->line : list->file->linenum,
+ list->line_contents, calc_hex (list));
+
+ free (list->line_contents);
+ list->line_contents = NULL;
+ }
+ else
+ {
+ while (list->file->linenum < list_line
+ && !list->file->at_end)
+ {
+ unsigned int address;
+
+ p = buffer_line (list->file, buffer, width);
+
+ if (list->file->linenum < list_line)
+ address = ~(unsigned int) 0;
+ else
+ address = calc_hex (list);
+
+ if (!((listing & LISTING_NODEBUG)
+ && debugging_pseudo (list, p)))
+ print_lines (list, list->file->linenum, p, address);
+ }
+ }
+
+ if (list->edict == EDICT_EJECT)
+ eject = 1;
+ }
+
+ if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
+ --show_listing;
+
+ list = list->next;
+ }
+
+ free (buffer);
+ free (data_buffer);
+ data_buffer = NULL;
+}
+
+void
+listing_print (char *name)
+{
+ int using_stdout;
+
+ title = "";
+ subtitle = "";
+
+ if (name == NULL)
+ {
+ list_file = stdout;
+ using_stdout = 1;
+ }
+ else
+ {
+ list_file = fopen (name, FOPEN_WT);
+ if (list_file != NULL)
+ using_stdout = 0;
+ else
+ {
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
+ as_perror (_("can't open list file: %s"), name);
+ list_file = stdout;
+ using_stdout = 1;
+ }
+ }
+
+ if (listing & LISTING_NOFORM)
+ paper_height = 0;
+
+ if (listing & LISTING_LISTING)
+ listing_listing (name);
+
+ if (listing & LISTING_SYMBOLS)
+ list_symbol_table ();
+
+ if (! using_stdout)
+ {
+ if (fclose (list_file) == EOF)
+ {
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
+ as_perror (_("error closing list file: %s"), name);
+ }
+ }
+
+ if (last_open_file)
+ fclose (last_open_file);
+}
+
+void
+listing_file (const char *name)
+{
+ fn = name;
+}
+
+void
+listing_eject (int ignore ATTRIBUTE_UNUSED)
+{
+ if (listing)
+ listing_tail->edict = EDICT_EJECT;
+}
+
+void
+listing_flags (int ignore ATTRIBUTE_UNUSED)
+{
+ while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
+ input_line_pointer++;
+
+}
+
+/* Turn listing on or off. An argument of 0 means to turn off
+ listing. An argument of 1 means to turn on listing. An argument
+ of 2 means to turn off listing, but as of the next line; that is,
+ the current line should be listed, but the next line should not. */
+
+void
+listing_list (int on)
+{
+ if (listing)
+ {
+ switch (on)
+ {
+ case 0:
+ if (listing_tail->edict == EDICT_LIST)
+ listing_tail->edict = EDICT_NONE;
+ else
+ listing_tail->edict = EDICT_NOLIST;
+ break;
+ case 1:
+ if (listing_tail->edict == EDICT_NOLIST
+ || listing_tail->edict == EDICT_NOLIST_NEXT)
+ listing_tail->edict = EDICT_NONE;
+ else
+ listing_tail->edict = EDICT_LIST;
+ break;
+ case 2:
+ listing_tail->edict = EDICT_NOLIST_NEXT;
+ break;
+ default:
+ abort ();
+ }
+ }
+}
+
+void
+listing_psize (int width_only)
+{
+ if (! width_only)
+ {
+ paper_height = get_absolute_expression ();
+
+ if (paper_height < 0 || paper_height > 1000)
+ {
+ paper_height = 0;
+ as_warn (_("strange paper height, set to no form"));
+ }
+
+ if (*input_line_pointer != ',')
+ {
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ ++input_line_pointer;
+ }
+
+ paper_width = get_absolute_expression ();
+
+ demand_empty_rest_of_line ();
+}
+
+void
+listing_nopage (int ignore ATTRIBUTE_UNUSED)
+{
+ paper_height = 0;
+}
+
+void
+listing_title (int depth)
+{
+ int quoted;
+ char *start;
+ char *ttl;
+ unsigned int length;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '\"')
+ quoted = 0;
+ else
+ {
+ quoted = 1;
+ ++input_line_pointer;
+ }
+
+ start = input_line_pointer;
+
+ while (*input_line_pointer)
+ {
+ if (quoted
+ ? *input_line_pointer == '\"'
+ : is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ if (listing)
+ {
+ length = input_line_pointer - start;
+ ttl = xmalloc (length + 1);
+ memcpy (ttl, start, length);
+ ttl[length] = 0;
+ listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
+ listing_tail->edict_arg = ttl;
+ }
+ if (quoted)
+ input_line_pointer++;
+ demand_empty_rest_of_line ();
+ return;
+ }
+ else if (*input_line_pointer == '\n')
+ {
+ as_bad (_("new line in title"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+ else
+ {
+ input_line_pointer++;
+ }
+ }
+}
+
+void
+listing_source_line (unsigned int line)
+{
+ if (listing)
+ {
+ new_frag ();
+ listing_tail->hll_line = line;
+ new_frag ();
+ }
+}
+
+void
+listing_source_file (const char *file)
+{
+ if (listing)
+ listing_tail->hll_file = file_info (file);
+}
+
+#else
+
+/* Dummy functions for when compiled without listing enabled. */
+
+void
+listing_flags (int ignore)
+{
+ s_ignore (0);
+}
+
+void
+listing_list (int on)
+{
+ s_ignore (0);
+}
+
+void
+listing_eject (int ignore)
+{
+ s_ignore (0);
+}
+
+void
+listing_psize (int ignore)
+{
+ s_ignore (0);
+}
+
+void
+listing_nopage (int ignore)
+{
+ s_ignore (0);
+}
+
+void
+listing_title (int depth)
+{
+ s_ignore (0);
+}
+
+void
+listing_file (const char *name)
+{
+}
+
+void
+listing_newline (char *name)
+{
+}
+
+void
+listing_source_line (unsigned int n)
+{
+}
+
+void
+listing_source_file (const char *n)
+{
+}
+
+#endif
diff --git a/x/binutils/gas/listing.h b/x/binutils/gas/listing.h
new file mode 100644
index 0000000..424b664
--- /dev/null
+++ b/x/binutils/gas/listing.h
@@ -0,0 +1,67 @@
+/* This file is listing.h
+ Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1995, 1997, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef __listing_h__
+#define __listing_h__
+
+#define LISTING_LISTING 1
+#define LISTING_SYMBOLS 2
+#define LISTING_NOFORM 4
+#define LISTING_HLL 8
+#define LISTING_NODEBUG 16
+#define LISTING_NOCOND 32
+#define LISTING_MACEXP 64
+
+#define LISTING_DEFAULT (LISTING_LISTING | LISTING_HLL | LISTING_SYMBOLS)
+
+#ifndef NO_LISTING
+#define LISTING_NEWLINE() { if (listing) listing_newline(NULL); }
+#else
+#define LISTING_NEWLINE() {;}
+#endif
+#define LISTING_EOF() LISTING_NEWLINE()
+
+#define LISTING_SKIP_COND() ((listing & LISTING_NOCOND) != 0)
+
+void listing_eject (int);
+void listing_error (const char *message);
+void listing_file (const char *name);
+void listing_flags (int);
+void listing_list (int on);
+void listing_newline (char *ps);
+void listing_prev_line (void);
+void listing_print (char *name);
+void listing_psize (int);
+void listing_nopage (int);
+void listing_source_file (const char *);
+void listing_source_line (unsigned int);
+void listing_title (int depth);
+void listing_warning (const char *message);
+void listing_width (unsigned int x);
+
+extern int listing_lhs_width;
+extern int listing_lhs_width_second;
+extern int listing_lhs_cont_lines;
+extern int listing_rhs_width;
+
+#endif /* __listing_h__ */
+
+/* end of listing.h */
diff --git a/x/binutils/gas/literal.c b/x/binutils/gas/literal.c
new file mode 100644
index 0000000..7315f3e
--- /dev/null
+++ b/x/binutils/gas/literal.c
@@ -0,0 +1,95 @@
+/* as.c - GAS literal pool management.
+ Copyright 1994, 2000 Free Software Foundation, Inc.
+ Written by Ken Raeburn (raeburn@cygnus.com).
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This isn't quite a "constant" pool. Some of the values may get
+ adjusted at run time, e.g., for symbolic relocations when shared
+ libraries are in use. It's more of a "literal" pool.
+
+ On the Alpha, this should be used for .lita and .lit8. (Is there
+ ever a .lit4?) On the MIPS, it could be used for .lit4 as well.
+
+ The expressions passed here should contain either constants or symbols,
+ not a combination of both. Typically, the constant pool is accessed
+ with some sort of GP register, so the size of the pool must be kept down
+ if possible. The exception is section offsets -- if you're storing a
+ pointer to the start of .data, for example, and your machine provides
+ for 16-bit signed addends, you might want to store .data+32K, so that
+ you can access all of the first 64K of .data with the one pointer.
+
+ This isn't a requirement, just a guideline that can help keep .o file
+ size down. */
+
+#include "as.h"
+#include "subsegs.h"
+
+#if defined (BFD_ASSEMBLER) && defined (NEED_LITERAL_POOL)
+
+valueT
+add_to_literal_pool (sym, addend, sec, size)
+ symbolS *sym;
+ valueT addend;
+ segT sec;
+ int size;
+{
+ segT current_section = now_seg;
+ int current_subsec = now_subseg;
+ valueT offset;
+ bfd_reloc_code_real_type reloc_type;
+ char *p;
+ segment_info_type *seginfo = seg_info (sec);
+ fixS *fixp;
+
+ offset = 0;
+ /* @@ This assumes all entries in a given section will be of the same
+ size... Probably correct, but unwise to rely on. */
+ /* This must always be called with the same subsegment. */
+ if (seginfo->frchainP)
+ for (fixp = seginfo->frchainP->fix_root;
+ fixp != (fixS *) NULL;
+ fixp = fixp->fx_next, offset += size)
+ {
+ if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
+ return offset;
+ }
+
+ subseg_set (sec, 0);
+ p = frag_more (size);
+ memset (p, 0, size);
+
+ switch (size)
+ {
+ case 4:
+ reloc_type = BFD_RELOC_32;
+ break;
+ case 8:
+ reloc_type = BFD_RELOC_64;
+ break;
+ default:
+ abort ();
+ }
+ fix_new (frag_now, p - frag_now->fr_literal, size, sym, addend, 0,
+ reloc_type);
+
+ subseg_set (current_section, current_subsec);
+ offset = seginfo->literal_pool_size;
+ seginfo->literal_pool_size += size;
+ return offset;
+}
+#endif /* BFD_ASSEMBLER */
diff --git a/x/binutils/gas/macro.c b/x/binutils/gas/macro.c
new file mode 100644
index 0000000..0991744
--- /dev/null
+++ b/x/binutils/gas/macro.c
@@ -0,0 +1,1177 @@
+/* macro.c - macro support for gas
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
+
+ Written by Steve and Judy Chamberlain of Cygnus Support,
+ sac@cygnus.com
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "config.h"
+
+#ifndef __GNUC__
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+/* Indented so that pre-ansi C compilers will ignore it, rather than
+ choke on it. Some versions of AIX require this to be the first
+ thing in the file. */
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+# if !defined (__STDC__) && !defined (__hpux)
+extern char *alloca ();
+# else
+extern void *alloca ();
+# endif /* __STDC__, __hpux */
+# endif /* alloca */
+# endif /* _AIX */
+# endif /* HAVE_ALLOCA_H */
+#endif /* __GNUC__ */
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include "libiberty.h"
+#include "safe-ctype.h"
+#include "sb.h"
+#include "hash.h"
+#include "macro.h"
+
+#include "asintl.h"
+
+/* The routines in this file handle macro definition and expansion.
+ They are called by gas. */
+
+/* Internal functions. */
+
+static int get_token (int, sb *, sb *);
+static int getstring (int, sb *, sb *);
+static int get_any_string (int, sb *, sb *, int, int);
+static int do_formals (macro_entry *, int, sb *);
+static int get_apost_token (int, sb *, sb *, int);
+static int sub_actual (int, sb *, sb *, struct hash_control *, int, sb *, int);
+static const char *macro_expand_body
+ (sb *, sb *, formal_entry *, struct hash_control *, int);
+static const char *macro_expand (int, sb *, macro_entry *, sb *);
+
+#define ISWHITE(x) ((x) == ' ' || (x) == '\t')
+
+#define ISSEP(x) \
+ ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
+ || (x) == ')' || (x) == '(' \
+ || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>')))
+
+#define ISBASE(x) \
+ ((x) == 'b' || (x) == 'B' \
+ || (x) == 'q' || (x) == 'Q' \
+ || (x) == 'h' || (x) == 'H' \
+ || (x) == 'd' || (x) == 'D')
+
+/* The macro hash table. */
+
+struct hash_control *macro_hash;
+
+/* Whether any macros have been defined. */
+
+int macro_defined;
+
+/* Whether we are in alternate syntax mode. */
+
+static int macro_alternate;
+
+/* Whether we are in MRI mode. */
+
+static int macro_mri;
+
+/* Whether we should strip '@' characters. */
+
+static int macro_strip_at;
+
+/* Function to use to parse an expression. */
+
+static int (*macro_expr) (const char *, int, sb *, int *);
+
+/* Number of macro expansions that have been done. */
+
+static int macro_number;
+
+/* Initialize macro processing. */
+
+void
+macro_init (int alternate, int mri, int strip_at,
+ int (*expr) (const char *, int, sb *, int *))
+{
+ macro_hash = hash_new ();
+ macro_defined = 0;
+ macro_alternate = alternate;
+ macro_mri = mri;
+ macro_strip_at = strip_at;
+ macro_expr = expr;
+}
+
+/* Switch in and out of MRI mode on the fly. */
+
+void
+macro_mri_mode (int mri)
+{
+ macro_mri = mri;
+}
+
+/* Read input lines till we get to a TO string.
+ Increase nesting depth if we get a FROM string.
+ Put the results into sb at PTR.
+ Add a new input line to an sb using GET_LINE.
+ Return 1 on success, 0 on unexpected EOF. */
+
+int
+buffer_and_nest (const char *from, const char *to, sb *ptr,
+ int (*get_line) (sb *))
+{
+ int from_len = strlen (from);
+ int to_len = strlen (to);
+ int depth = 1;
+ int line_start = ptr->len;
+
+ int more = get_line (ptr);
+
+ while (more)
+ {
+ /* Try and find the first pseudo op on the line. */
+ int i = line_start;
+
+ if (! macro_alternate && ! macro_mri)
+ {
+ /* With normal syntax we can suck what we want till we get
+ to the dot. With the alternate, labels have to start in
+ the first column, since we cant tell what's a label and
+ whats a pseudoop. */
+
+ /* Skip leading whitespace. */
+ while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+ i++;
+
+ /* Skip over a label. */
+ while (i < ptr->len
+ && (ISALNUM (ptr->ptr[i])
+ || ptr->ptr[i] == '_'
+ || ptr->ptr[i] == '$'))
+ i++;
+
+ /* And a colon. */
+ if (i < ptr->len
+ && ptr->ptr[i] == ':')
+ i++;
+
+ }
+ /* Skip trailing whitespace. */
+ while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+ i++;
+
+ if (i < ptr->len && (ptr->ptr[i] == '.'
+ || macro_alternate
+ || macro_mri))
+ {
+ if (ptr->ptr[i] == '.')
+ i++;
+ if (strncasecmp (ptr->ptr + i, from, from_len) == 0
+ && (ptr->len == (i + from_len)
+ || ! ISALNUM (ptr->ptr[i + from_len])))
+ depth++;
+ if (strncasecmp (ptr->ptr + i, to, to_len) == 0
+ && (ptr->len == (i + to_len)
+ || ! ISALNUM (ptr->ptr[i + to_len])))
+ {
+ depth--;
+ if (depth == 0)
+ {
+ /* Reset the string to not include the ending rune. */
+ ptr->len = line_start;
+ break;
+ }
+ }
+ }
+
+ /* Add the original end-of-line char to the end and keep running. */
+ sb_add_char (ptr, more);
+ line_start = ptr->len;
+ more = get_line (ptr);
+ }
+
+ /* Return 1 on success, 0 on unexpected EOF. */
+ return depth == 0;
+}
+
+/* Pick up a token. */
+
+static int
+get_token (int idx, sb *in, sb *name)
+{
+ if (idx < in->len
+ && (ISALPHA (in->ptr[idx])
+ || in->ptr[idx] == '_'
+ || in->ptr[idx] == '$'))
+ {
+ sb_add_char (name, in->ptr[idx++]);
+ while (idx < in->len
+ && (ISALNUM (in->ptr[idx])
+ || in->ptr[idx] == '_'
+ || in->ptr[idx] == '$'))
+ {
+ sb_add_char (name, in->ptr[idx++]);
+ }
+ }
+ /* Ignore trailing &. */
+ if (macro_alternate && idx < in->len && in->ptr[idx] == '&')
+ idx++;
+ return idx;
+}
+
+/* Pick up a string. */
+
+static int
+getstring (int idx, sb *in, sb *acc)
+{
+ idx = sb_skip_white (idx, in);
+
+ while (idx < in->len
+ && (in->ptr[idx] == '"'
+ || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
+ || (in->ptr[idx] == '\'' && macro_alternate)))
+ {
+ if (in->ptr[idx] == '<')
+ {
+ int nest = 0;
+ idx++;
+ while ((in->ptr[idx] != '>' || nest)
+ && idx < in->len)
+ {
+ if (in->ptr[idx] == '!')
+ {
+ idx++;
+ sb_add_char (acc, in->ptr[idx++]);
+ }
+ else
+ {
+ if (in->ptr[idx] == '>')
+ nest--;
+ if (in->ptr[idx] == '<')
+ nest++;
+ sb_add_char (acc, in->ptr[idx++]);
+ }
+ }
+ idx++;
+ }
+ else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
+ {
+ char tchar = in->ptr[idx];
+ int escaped = 0;
+
+ idx++;
+
+ while (idx < in->len)
+ {
+ if (in->ptr[idx - 1] == '\\')
+ escaped ^= 1;
+ else
+ escaped = 0;
+
+ if (macro_alternate && in->ptr[idx] == '!')
+ {
+ idx ++;
+
+ sb_add_char (acc, in->ptr[idx]);
+
+ idx ++;
+ }
+ else if (escaped && in->ptr[idx] == tchar)
+ {
+ sb_add_char (acc, tchar);
+ idx ++;
+ }
+ else
+ {
+ if (in->ptr[idx] == tchar)
+ {
+ idx ++;
+
+ if (idx >= in->len || in->ptr[idx] != tchar)
+ break;
+ }
+
+ sb_add_char (acc, in->ptr[idx]);
+ idx ++;
+ }
+ }
+ }
+ }
+
+ return idx;
+}
+
+/* Fetch string from the input stream,
+ rules:
+ 'Bxyx<whitespace> -> return 'Bxyza
+ %<char> -> return string of decimal value of x
+ "<string>" -> return string
+ xyx<whitespace> -> return xyz
+*/
+
+static int
+get_any_string (int idx, sb *in, sb *out, int expand, int pretend_quoted)
+{
+ sb_reset (out);
+ idx = sb_skip_white (idx, in);
+
+ if (idx < in->len)
+ {
+ if (in->len > idx + 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx]))
+ {
+ while (!ISSEP (in->ptr[idx]))
+ sb_add_char (out, in->ptr[idx++]);
+ }
+ else if (in->ptr[idx] == '%'
+ && macro_alternate
+ && expand)
+ {
+ int val;
+ char buf[20];
+ /* Turns the next expression into a string. */
+ /* xgettext: no-c-format */
+ idx = (*macro_expr) (_("% operator needs absolute expression"),
+ idx + 1,
+ in,
+ &val);
+ sprintf (buf, "%d", val);
+ sb_add_string (out, buf);
+ }
+ else if (in->ptr[idx] == '"'
+ || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
+ || (macro_alternate && in->ptr[idx] == '\''))
+ {
+ if (macro_alternate
+ && ! macro_strip_at
+ && expand)
+ {
+ /* Keep the quotes. */
+ sb_add_char (out, '\"');
+
+ idx = getstring (idx, in, out);
+ sb_add_char (out, '\"');
+ }
+ else
+ {
+ idx = getstring (idx, in, out);
+ }
+ }
+ else
+ {
+ while (idx < in->len
+ && (in->ptr[idx] == '"'
+ || in->ptr[idx] == '\''
+ || pretend_quoted
+ || (in->ptr[idx] != ' '
+ && in->ptr[idx] != '\t'
+ && in->ptr[idx] != ','
+ && (in->ptr[idx] != '<'
+ || (! macro_alternate && ! macro_mri)))))
+ {
+ if (in->ptr[idx] == '"'
+ || in->ptr[idx] == '\'')
+ {
+ char tchar = in->ptr[idx];
+ sb_add_char (out, in->ptr[idx++]);
+ while (idx < in->len
+ && in->ptr[idx] != tchar)
+ sb_add_char (out, in->ptr[idx++]);
+ if (idx == in->len)
+ return idx;
+ }
+ sb_add_char (out, in->ptr[idx++]);
+ }
+ }
+ }
+
+ return idx;
+}
+
+/* Pick up the formal parameters of a macro definition. */
+
+static int
+do_formals (macro_entry *macro, int idx, sb *in)
+{
+ formal_entry **p = &macro->formals;
+
+ macro->formal_count = 0;
+ macro->formal_hash = hash_new ();
+ while (idx < in->len)
+ {
+ formal_entry *formal;
+
+ formal = (formal_entry *) xmalloc (sizeof (formal_entry));
+
+ sb_new (&formal->name);
+ sb_new (&formal->def);
+ sb_new (&formal->actual);
+
+ idx = sb_skip_white (idx, in);
+ idx = get_token (idx, in, &formal->name);
+ if (formal->name.len == 0)
+ break;
+ idx = sb_skip_white (idx, in);
+ if (formal->name.len)
+ {
+ /* This is a formal. */
+ if (idx < in->len && in->ptr[idx] == '=')
+ {
+ /* Got a default. */
+ idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
+ }
+ }
+
+ /* Add to macro's hash table. */
+ hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal);
+
+ formal->index = macro->formal_count;
+ idx = sb_skip_comma (idx, in);
+ macro->formal_count++;
+ *p = formal;
+ p = &formal->next;
+ *p = NULL;
+ }
+
+ if (macro_mri)
+ {
+ formal_entry *formal;
+ const char *name;
+
+ /* Add a special NARG formal, which macro_expand will set to the
+ number of arguments. */
+ formal = (formal_entry *) xmalloc (sizeof (formal_entry));
+
+ sb_new (&formal->name);
+ sb_new (&formal->def);
+ sb_new (&formal->actual);
+
+ /* The same MRI assemblers which treat '@' characters also use
+ the name $NARG. At least until we find an exception. */
+ if (macro_strip_at)
+ name = "$NARG";
+ else
+ name = "NARG";
+
+ sb_add_string (&formal->name, name);
+
+ /* Add to macro's hash table. */
+ hash_jam (macro->formal_hash, name, formal);
+
+ formal->index = NARG_INDEX;
+ *p = formal;
+ formal->next = NULL;
+ }
+
+ return idx;
+}
+
+/* Define a new macro. Returns NULL on success, otherwise returns an
+ error message. If NAMEP is not NULL, *NAMEP is set to the name of
+ the macro which was defined. */
+
+const char *
+define_macro (int idx, sb *in, sb *label,
+ int (*get_line) (sb *), const char **namep)
+{
+ macro_entry *macro;
+ sb name;
+ const char *namestr;
+
+ macro = (macro_entry *) xmalloc (sizeof (macro_entry));
+ sb_new (&macro->sub);
+ sb_new (&name);
+
+ macro->formal_count = 0;
+ macro->formals = 0;
+
+ idx = sb_skip_white (idx, in);
+ if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
+ return _("unexpected end of file in macro definition");
+ if (label != NULL && label->len != 0)
+ {
+ sb_add_sb (&name, label);
+ if (idx < in->len && in->ptr[idx] == '(')
+ {
+ /* It's the label: MACRO (formals,...) sort */
+ idx = do_formals (macro, idx + 1, in);
+ if (in->ptr[idx] != ')')
+ return _("missing ) after formals");
+ }
+ else
+ {
+ /* It's the label: MACRO formals,... sort */
+ idx = do_formals (macro, idx, in);
+ }
+ }
+ else
+ {
+ idx = get_token (idx, in, &name);
+ idx = sb_skip_comma (idx, in);
+ idx = do_formals (macro, idx, in);
+ }
+
+ /* And stick it in the macro hash table. */
+ for (idx = 0; idx < name.len; idx++)
+ name.ptr[idx] = TOLOWER (name.ptr[idx]);
+ namestr = sb_terminate (&name);
+ hash_jam (macro_hash, namestr, (PTR) macro);
+
+ macro_defined = 1;
+
+ if (namep != NULL)
+ *namep = namestr;
+
+ return NULL;
+}
+
+/* Scan a token, and then skip KIND. */
+
+static int
+get_apost_token (int idx, sb *in, sb *name, int kind)
+{
+ idx = get_token (idx, in, name);
+ if (idx < in->len
+ && in->ptr[idx] == kind
+ && (! macro_mri || macro_strip_at)
+ && (! macro_strip_at || kind == '@'))
+ idx++;
+ return idx;
+}
+
+/* Substitute the actual value for a formal parameter. */
+
+static int
+sub_actual (int start, sb *in, sb *t, struct hash_control *formal_hash,
+ int kind, sb *out, int copyifnotthere)
+{
+ int src;
+ formal_entry *ptr;
+
+ src = get_apost_token (start, in, t, kind);
+ /* See if it's in the macro's hash table, unless this is
+ macro_strip_at and kind is '@' and the token did not end in '@'. */
+ if (macro_strip_at
+ && kind == '@'
+ && (src == start || in->ptr[src - 1] != '@'))
+ ptr = NULL;
+ else
+ ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (t));
+ if (ptr)
+ {
+ if (ptr->actual.len)
+ {
+ sb_add_sb (out, &ptr->actual);
+ }
+ else
+ {
+ sb_add_sb (out, &ptr->def);
+ }
+ }
+ else if (kind == '&')
+ {
+ /* Doing this permits people to use & in macro bodies. */
+ sb_add_char (out, '&');
+ sb_add_sb (out, t);
+ }
+ else if (copyifnotthere)
+ {
+ sb_add_sb (out, t);
+ }
+ else
+ {
+ sb_add_char (out, '\\');
+ sb_add_sb (out, t);
+ }
+ return src;
+}
+
+/* Expand the body of a macro. */
+
+static const char *
+macro_expand_body (sb *in, sb *out, formal_entry *formals,
+ struct hash_control *formal_hash, int locals)
+{
+ sb t;
+ int src = 0;
+ int inquote = 0;
+ formal_entry *loclist = NULL;
+
+ sb_new (&t);
+
+ while (src < in->len)
+ {
+ if (in->ptr[src] == '&')
+ {
+ sb_reset (&t);
+ if (macro_mri)
+ {
+ if (src + 1 < in->len && in->ptr[src + 1] == '&')
+ src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
+ else
+ sb_add_char (out, in->ptr[src++]);
+ }
+ else
+ {
+ /* FIXME: Why do we do this? */
+ src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
+ }
+ }
+ else if (in->ptr[src] == '\\')
+ {
+ src++;
+ if (in->ptr[src] == '(')
+ {
+ /* Sub in till the next ')' literally. */
+ src++;
+ while (src < in->len && in->ptr[src] != ')')
+ {
+ sb_add_char (out, in->ptr[src++]);
+ }
+ if (in->ptr[src] == ')')
+ src++;
+ else
+ return _("missplaced )");
+ }
+ else if (in->ptr[src] == '@')
+ {
+ /* Sub in the macro invocation number. */
+
+ char buffer[10];
+ src++;
+ sprintf (buffer, "%d", macro_number);
+ sb_add_string (out, buffer);
+ }
+ else if (in->ptr[src] == '&')
+ {
+ /* This is a preprocessor variable name, we don't do them
+ here. */
+ sb_add_char (out, '\\');
+ sb_add_char (out, '&');
+ src++;
+ }
+ else if (macro_mri && ISALNUM (in->ptr[src]))
+ {
+ int ind;
+ formal_entry *f;
+
+ if (ISDIGIT (in->ptr[src]))
+ ind = in->ptr[src] - '0';
+ else if (ISUPPER (in->ptr[src]))
+ ind = in->ptr[src] - 'A' + 10;
+ else
+ ind = in->ptr[src] - 'a' + 10;
+ ++src;
+ for (f = formals; f != NULL; f = f->next)
+ {
+ if (f->index == ind - 1)
+ {
+ if (f->actual.len != 0)
+ sb_add_sb (out, &f->actual);
+ else
+ sb_add_sb (out, &f->def);
+ break;
+ }
+ }
+ }
+ else
+ {
+ sb_reset (&t);
+ src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
+ }
+ }
+ else if ((macro_alternate || macro_mri)
+ && (ISALPHA (in->ptr[src])
+ || in->ptr[src] == '_'
+ || in->ptr[src] == '$')
+ && (! inquote
+ || ! macro_strip_at
+ || (src > 0 && in->ptr[src - 1] == '@')))
+ {
+ if (! locals
+ || src + 5 >= in->len
+ || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
+ || ! ISWHITE (in->ptr[src + 5]))
+ {
+ sb_reset (&t);
+ src = sub_actual (src, in, &t, formal_hash,
+ (macro_strip_at && inquote) ? '@' : '\'',
+ out, 1);
+ }
+ else
+ {
+ formal_entry *f;
+
+ src = sb_skip_white (src + 5, in);
+ while (in->ptr[src] != '\n')
+ {
+ static int loccnt;
+ char buf[20];
+ const char *err;
+
+ f = (formal_entry *) xmalloc (sizeof (formal_entry));
+ sb_new (&f->name);
+ sb_new (&f->def);
+ sb_new (&f->actual);
+ f->index = LOCAL_INDEX;
+ f->next = loclist;
+ loclist = f;
+
+ src = get_token (src, in, &f->name);
+ ++loccnt;
+ sprintf (buf, "LL%04x", loccnt);
+ sb_add_string (&f->actual, buf);
+
+ err = hash_jam (formal_hash, sb_terminate (&f->name), f);
+ if (err != NULL)
+ return err;
+
+ src = sb_skip_comma (src, in);
+ }
+ }
+ }
+ else if (in->ptr[src] == '"'
+ || (macro_mri && in->ptr[src] == '\''))
+ {
+ inquote = !inquote;
+ sb_add_char (out, in->ptr[src++]);
+ }
+ else if (in->ptr[src] == '@' && macro_strip_at)
+ {
+ ++src;
+ if (src < in->len
+ && in->ptr[src] == '@')
+ {
+ sb_add_char (out, '@');
+ ++src;
+ }
+ }
+ else if (macro_mri
+ && in->ptr[src] == '='
+ && src + 1 < in->len
+ && in->ptr[src + 1] == '=')
+ {
+ formal_entry *ptr;
+
+ sb_reset (&t);
+ src = get_token (src + 2, in, &t);
+ ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (&t));
+ if (ptr == NULL)
+ {
+ /* FIXME: We should really return a warning string here,
+ but we can't, because the == might be in the MRI
+ comment field, and, since the nature of the MRI
+ comment field depends upon the exact instruction
+ being used, we don't have enough information here to
+ figure out whether it is or not. Instead, we leave
+ the == in place, which should cause a syntax error if
+ it is not in a comment. */
+ sb_add_char (out, '=');
+ sb_add_char (out, '=');
+ sb_add_sb (out, &t);
+ }
+ else
+ {
+ if (ptr->actual.len)
+ {
+ sb_add_string (out, "-1");
+ }
+ else
+ {
+ sb_add_char (out, '0');
+ }
+ }
+ }
+ else
+ {
+ sb_add_char (out, in->ptr[src++]);
+ }
+ }
+
+ sb_kill (&t);
+
+ while (loclist != NULL)
+ {
+ formal_entry *f;
+
+ f = loclist->next;
+ /* Setting the value to NULL effectively deletes the entry. We
+ avoid calling hash_delete because it doesn't reclaim memory. */
+ hash_jam (formal_hash, sb_terminate (&loclist->name), NULL);
+ sb_kill (&loclist->name);
+ sb_kill (&loclist->def);
+ sb_kill (&loclist->actual);
+ free (loclist);
+ loclist = f;
+ }
+
+ return NULL;
+}
+
+/* Assign values to the formal parameters of a macro, and expand the
+ body. */
+
+static const char *
+macro_expand (int idx, sb *in, macro_entry *m, sb *out)
+{
+ sb t;
+ formal_entry *ptr;
+ formal_entry *f;
+ int is_positional = 0;
+ int is_keyword = 0;
+ int narg = 0;
+ const char *err;
+
+ sb_new (&t);
+
+ /* Reset any old value the actuals may have. */
+ for (f = m->formals; f; f = f->next)
+ sb_reset (&f->actual);
+ f = m->formals;
+ while (f != NULL && f->index < 0)
+ f = f->next;
+
+ if (macro_mri)
+ {
+ /* The macro may be called with an optional qualifier, which may
+ be referred to in the macro body as \0. */
+ if (idx < in->len && in->ptr[idx] == '.')
+ {
+ /* The Microtec assembler ignores this if followed by a white space.
+ (Macro invocation with empty extension) */
+ idx++;
+ if ( idx < in->len
+ && in->ptr[idx] != ' '
+ && in->ptr[idx] != '\t')
+ {
+ formal_entry *n;
+
+ n = (formal_entry *) xmalloc (sizeof (formal_entry));
+ sb_new (&n->name);
+ sb_new (&n->def);
+ sb_new (&n->actual);
+ n->index = QUAL_INDEX;
+
+ n->next = m->formals;
+ m->formals = n;
+
+ idx = get_any_string (idx, in, &n->actual, 1, 0);
+ }
+ }
+ }
+
+ /* Peel off the actuals and store them away in the hash tables' actuals. */
+ idx = sb_skip_white (idx, in);
+ while (idx < in->len)
+ {
+ int scan;
+
+ /* Look and see if it's a positional or keyword arg. */
+ scan = idx;
+ while (scan < in->len
+ && !ISSEP (in->ptr[scan])
+ && !(macro_mri && in->ptr[scan] == '\'')
+ && (!macro_alternate && in->ptr[scan] != '='))
+ scan++;
+ if (scan < in->len && !macro_alternate && in->ptr[scan] == '=')
+ {
+ is_keyword = 1;
+
+ /* It's OK to go from positional to keyword. */
+
+ /* This is a keyword arg, fetch the formal name and
+ then the actual stuff. */
+ sb_reset (&t);
+ idx = get_token (idx, in, &t);
+ if (in->ptr[idx] != '=')
+ return _("confusion in formal parameters");
+
+ /* Lookup the formal in the macro's list. */
+ ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
+ if (!ptr)
+ return _("macro formal argument does not exist");
+ else
+ {
+ /* Insert this value into the right place. */
+ sb_reset (&ptr->actual);
+ idx = get_any_string (idx + 1, in, &ptr->actual, 0, 0);
+ if (ptr->actual.len > 0)
+ ++narg;
+ }
+ }
+ else
+ {
+ /* This is a positional arg. */
+ is_positional = 1;
+ if (is_keyword)
+ return _("can't mix positional and keyword arguments");
+
+ if (!f)
+ {
+ formal_entry **pf;
+ int c;
+
+ if (!macro_mri)
+ return _("too many positional arguments");
+
+ f = (formal_entry *) xmalloc (sizeof (formal_entry));
+ sb_new (&f->name);
+ sb_new (&f->def);
+ sb_new (&f->actual);
+ f->next = NULL;
+
+ c = -1;
+ for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
+ if ((*pf)->index >= c)
+ c = (*pf)->index + 1;
+ if (c == -1)
+ c = 0;
+ *pf = f;
+ f->index = c;
+ }
+
+ sb_reset (&f->actual);
+ idx = get_any_string (idx, in, &f->actual, 1, 0);
+ if (f->actual.len > 0)
+ ++narg;
+ do
+ {
+ f = f->next;
+ }
+ while (f != NULL && f->index < 0);
+ }
+
+ if (! macro_mri)
+ idx = sb_skip_comma (idx, in);
+ else
+ {
+ if (in->ptr[idx] == ',')
+ ++idx;
+ if (ISWHITE (in->ptr[idx]))
+ break;
+ }
+ }
+
+ if (macro_mri)
+ {
+ char buffer[20];
+
+ sb_reset (&t);
+ sb_add_string (&t, macro_strip_at ? "$NARG" : "NARG");
+ ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
+ sb_reset (&ptr->actual);
+ sprintf (buffer, "%d", narg);
+ sb_add_string (&ptr->actual, buffer);
+ }
+
+ err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, 1);
+ if (err != NULL)
+ return err;
+
+ /* Discard any unnamed formal arguments. */
+ if (macro_mri)
+ {
+ formal_entry **pf;
+
+ pf = &m->formals;
+ while (*pf != NULL)
+ {
+ if ((*pf)->name.len != 0)
+ pf = &(*pf)->next;
+ else
+ {
+ sb_kill (&(*pf)->name);
+ sb_kill (&(*pf)->def);
+ sb_kill (&(*pf)->actual);
+ f = (*pf)->next;
+ free (*pf);
+ *pf = f;
+ }
+ }
+ }
+
+ sb_kill (&t);
+ macro_number++;
+
+ return NULL;
+}
+
+/* Check for a macro. If one is found, put the expansion into
+ *EXPAND. Return 1 if a macro is found, 0 otherwise. */
+
+int
+check_macro (const char *line, sb *expand,
+ const char **error, macro_entry **info)
+{
+ const char *s;
+ char *copy, *cs;
+ macro_entry *macro;
+ sb line_sb;
+
+ if (! ISALPHA (*line)
+ && *line != '_'
+ && *line != '$'
+ && (! macro_mri || *line != '.'))
+ return 0;
+
+ s = line + 1;
+ while (ISALNUM (*s)
+ || *s == '_'
+ || *s == '$')
+ ++s;
+
+ copy = (char *) alloca (s - line + 1);
+ memcpy (copy, line, s - line);
+ copy[s - line] = '\0';
+ for (cs = copy; *cs != '\0'; cs++)
+ *cs = TOLOWER (*cs);
+
+ macro = (macro_entry *) hash_find (macro_hash, copy);
+
+ if (macro == NULL)
+ return 0;
+
+ /* Wrap the line up in an sb. */
+ sb_new (&line_sb);
+ while (*s != '\0' && *s != '\n' && *s != '\r')
+ sb_add_char (&line_sb, *s++);
+
+ sb_new (expand);
+ *error = macro_expand (0, &line_sb, macro, expand);
+
+ sb_kill (&line_sb);
+
+ /* Export the macro information if requested. */
+ if (info)
+ *info = macro;
+
+ return 1;
+}
+
+/* Delete a macro. */
+
+void
+delete_macro (const char *name)
+{
+ hash_delete (macro_hash, name);
+}
+
+/* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
+ combined macro definition and execution. This returns NULL on
+ success, or an error message otherwise. */
+
+const char *
+expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
+{
+ const char *mn;
+ sb sub;
+ formal_entry f;
+ struct hash_control *h;
+ const char *err;
+
+ if (irpc)
+ mn = "IRPC";
+ else
+ mn = "IRP";
+
+ idx = sb_skip_white (idx, in);
+
+ sb_new (&sub);
+ if (! buffer_and_nest (mn, "ENDR", &sub, get_line))
+ return _("unexpected end of file in irp or irpc");
+
+ sb_new (&f.name);
+ sb_new (&f.def);
+ sb_new (&f.actual);
+
+ idx = get_token (idx, in, &f.name);
+ if (f.name.len == 0)
+ return _("missing model parameter");
+
+ h = hash_new ();
+ err = hash_jam (h, sb_terminate (&f.name), &f);
+ if (err != NULL)
+ return err;
+
+ f.index = 1;
+ f.next = NULL;
+
+ sb_reset (out);
+
+ idx = sb_skip_comma (idx, in);
+ if (idx >= in->len)
+ {
+ /* Expand once with a null string. */
+ err = macro_expand_body (&sub, out, &f, h, 0);
+ if (err != NULL)
+ return err;
+ }
+ else
+ {
+ if (irpc && in->ptr[idx] == '"')
+ ++idx;
+ while (idx < in->len)
+ {
+ if (!irpc)
+ idx = get_any_string (idx, in, &f.actual, 1, 0);
+ else
+ {
+ if (in->ptr[idx] == '"')
+ {
+ int nxt;
+
+ nxt = sb_skip_white (idx + 1, in);
+ if (nxt >= in->len)
+ {
+ idx = nxt;
+ break;
+ }
+ }
+ sb_reset (&f.actual);
+ sb_add_char (&f.actual, in->ptr[idx]);
+ ++idx;
+ }
+ err = macro_expand_body (&sub, out, &f, h, 0);
+ if (err != NULL)
+ return err;
+ if (!irpc)
+ idx = sb_skip_comma (idx, in);
+ else
+ idx = sb_skip_white (idx, in);
+ }
+ }
+
+ hash_die (h);
+ sb_kill (&sub);
+
+ return NULL;
+}
diff --git a/x/binutils/gas/macro.h b/x/binutils/gas/macro.h
new file mode 100644
index 0000000..a8bffaa
--- /dev/null
+++ b/x/binutils/gas/macro.h
@@ -0,0 +1,83 @@
+/* macro.h - header file for macro support for gas
+ Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2002
+ Free Software Foundation, Inc.
+
+ Written by Steve and Judy Chamberlain of Cygnus Support,
+ sac@cygnus.com
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef MACRO_H
+
+#define MACRO_H
+
+#include "ansidecl.h"
+#include "sb.h"
+
+/* Structures used to store macros.
+
+ Each macro knows its name and included text. It gets built with a
+ list of formal arguments, and also keeps a hash table which points
+ into the list to speed up formal search. Each formal knows its
+ name and its default value. Each time the macro is expanded, the
+ formals get the actual values attached to them. */
+
+/* Describe the formal arguments to a macro. */
+
+typedef struct formal_struct {
+ struct formal_struct *next; /* Next formal in list. */
+ sb name; /* Name of the formal. */
+ sb def; /* The default value. */
+ sb actual; /* The actual argument (changed on each expansion). */
+ int index; /* The index of the formal 0..formal_count - 1. */
+} formal_entry;
+
+/* Other values found in the index field of a formal_entry. */
+#define QUAL_INDEX (-1)
+#define NARG_INDEX (-2)
+#define LOCAL_INDEX (-3)
+
+/* Describe the macro. */
+
+typedef struct macro_struct
+{
+ sb sub; /* Substitution text. */
+ int formal_count; /* Number of formal args. */
+ formal_entry *formals; /* Pointer to list of formal_structs. */
+ struct hash_control *formal_hash; /* Hash table of formals. */
+} macro_entry;
+
+/* Whether any macros have been defined. */
+
+extern int macro_defined;
+
+/* The macro nesting level. */
+
+extern int macro_nest;
+
+extern int buffer_and_nest (const char *, const char *, sb *, int (*) (sb *));
+extern void macro_init
+ (int, int, int, int (*) (const char *, int, sb *, int *));
+extern void macro_mri_mode (int);
+extern const char *define_macro
+ (int, sb *, sb *, int (*) (sb *), const char **);
+extern int check_macro (const char *, sb *, const char **, macro_entry **);
+extern void delete_macro (const char *);
+extern const char *expand_irp (int, int, sb *, sb *, int (*) (sb *));
+
+#endif
diff --git a/x/binutils/gas/messages.c b/x/binutils/gas/messages.c
new file mode 100644
index 0000000..005cd22
--- /dev/null
+++ b/x/binutils/gas/messages.c
@@ -0,0 +1,505 @@
+/* messages.c - error reporter -
+ Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, 2003
+ Free Software Foundation, Inc.
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+
+#include <stdio.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef USE_STDARG
+#include <stdarg.h>
+#endif
+
+#ifdef USE_VARARGS
+#include <varargs.h>
+#endif
+
+#if !defined (USE_STDARG) && !defined (USE_VARARGS)
+/* Roll our own. */
+#define va_alist REST
+#define va_dcl
+typedef int * va_list;
+#define va_start(ARGS) ARGS = &REST
+#define va_end(ARGS)
+#endif
+
+static void identify (char *);
+static void as_show_where (void);
+static void as_warn_internal (char *, unsigned int, char *);
+static void as_bad_internal (char *, unsigned int, char *);
+
+/* Despite the rest of the comments in this file, (FIXME-SOON),
+ here is the current scheme for error messages etc:
+
+ as_fatal() is used when gas is quite confused and
+ continuing the assembly is pointless. In this case we
+ exit immediately with error status.
+
+ as_bad() is used to mark errors that result in what we
+ presume to be a useless object file. Say, we ignored
+ something that might have been vital. If we see any of
+ these, assembly will continue to the end of the source,
+ no object file will be produced, and we will terminate
+ with error status. The new option, -Z, tells us to
+ produce an object file anyway but we still exit with
+ error status. The assumption here is that you don't want
+ this object file but we could be wrong.
+
+ as_warn() is used when we have an error from which we
+ have a plausible error recovery. eg, masking the top
+ bits of a constant that is longer than will fit in the
+ destination. In this case we will continue to assemble
+ the source, although we may have made a bad assumption,
+ and we will produce an object file and return normal exit
+ status (ie, no error). The new option -X tells us to
+ treat all as_warn() errors as as_bad() errors. That is,
+ no object file will be produced and we will exit with
+ error status. The idea here is that we don't kill an
+ entire make because of an error that we knew how to
+ correct. On the other hand, sometimes you might want to
+ stop the make at these points.
+
+ as_tsktsk() is used when we see a minor error for which
+ our error recovery action is almost certainly correct.
+ In this case, we print a message and then assembly
+ continues as though no error occurred. */
+
+static void
+identify (char *file)
+{
+ static int identified;
+
+ if (identified)
+ return;
+ identified++;
+
+ if (!file)
+ {
+ unsigned int x;
+ as_where (&file, &x);
+ }
+
+ if (file)
+ fprintf (stderr, "%s: ", file);
+ fprintf (stderr, _("Assembler messages:\n"));
+}
+
+/* The number of warnings issued. */
+static int warning_count;
+
+int
+had_warnings (void)
+{
+ return warning_count;
+}
+
+/* Nonzero if we've hit a 'bad error', and should not write an obj file,
+ and exit with a nonzero error code. */
+
+static int error_count;
+
+int
+had_errors (void)
+{
+ return error_count;
+}
+
+/* Print the current location to stderr. */
+
+static void
+as_show_where (void)
+{
+ char *file;
+ unsigned int line;
+
+ as_where (&file, &line);
+ identify (file);
+ if (file)
+ fprintf (stderr, "%s:%u: ", file, line);
+}
+
+/* Like perror(3), but with more info. */
+
+void
+as_perror (const char *gripe, /* Unpunctuated error theme. */
+ const char *filename)
+{
+ const char *errtxt;
+ int saved_errno = errno;
+
+ as_show_where ();
+ fprintf (stderr, gripe, filename);
+ errno = saved_errno;
+#ifdef BFD_ASSEMBLER
+ errtxt = bfd_errmsg (bfd_get_error ());
+#else
+ errtxt = xstrerror (errno);
+#endif
+ fprintf (stderr, ": %s\n", errtxt);
+ errno = 0;
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_no_error);
+#endif
+}
+
+/* Send to stderr a string as a warning, and locate warning
+ in input file(s).
+ Please only use this for when we have some recovery action.
+ Please explain in string (which may have '\n's) what recovery was
+ done. */
+
+#ifdef USE_STDARG
+void
+as_tsktsk (const char *format, ...)
+{
+ va_list args;
+
+ as_show_where ();
+ va_start (args, format);
+ vfprintf (stderr, format, args);
+ va_end (args);
+ (void) putc ('\n', stderr);
+}
+#else
+void
+as_tsktsk (format, va_alist)
+ const char *format;
+ va_dcl
+{
+ va_list args;
+
+ as_show_where ();
+ va_start (args);
+ vfprintf (stderr, format, args);
+ va_end (args);
+ (void) putc ('\n', stderr);
+}
+#endif /* not NO_STDARG */
+
+/* The common portion of as_warn and as_warn_where. */
+
+static void
+as_warn_internal (char *file, unsigned int line, char *buffer)
+{
+ ++warning_count;
+
+ if (file == NULL)
+ as_where (&file, &line);
+
+ identify (file);
+ if (file)
+ fprintf (stderr, "%s:%u: ", file, line);
+ fprintf (stderr, _("Warning: "));
+ fputs (buffer, stderr);
+ (void) putc ('\n', stderr);
+#ifndef NO_LISTING
+ listing_warning (buffer);
+#endif
+}
+
+/* Send to stderr a string as a warning, and locate warning
+ in input file(s).
+ Please only use this for when we have some recovery action.
+ Please explain in string (which may have '\n's) what recovery was
+ done. */
+
+#ifdef USE_STDARG
+void
+as_warn (const char *format, ...)
+{
+ va_list args;
+ char buffer[2000];
+
+ if (!flag_no_warnings)
+ {
+ va_start (args, format);
+ vsprintf (buffer, format, args);
+ va_end (args);
+ as_warn_internal ((char *) NULL, 0, buffer);
+ }
+}
+#else
+void
+as_warn (format, va_alist)
+ const char *format;
+ va_dcl
+{
+ va_list args;
+ char buffer[2000];
+
+ if (!flag_no_warnings)
+ {
+ va_start (args);
+ vsprintf (buffer, format, args);
+ va_end (args);
+ as_warn_internal ((char *) NULL, 0, buffer);
+ }
+}
+#endif /* not NO_STDARG */
+
+/* Like as_bad but the file name and line number are passed in.
+ Unfortunately, we have to repeat the function in order to handle
+ the varargs correctly and portably. */
+
+#ifdef USE_STDARG
+void
+as_warn_where (char *file, unsigned int line, const char *format, ...)
+{
+ va_list args;
+ char buffer[2000];
+
+ if (!flag_no_warnings)
+ {
+ va_start (args, format);
+ vsprintf (buffer, format, args);
+ va_end (args);
+ as_warn_internal (file, line, buffer);
+ }
+}
+#else
+void
+as_warn_where (file, line, format, va_alist)
+ char *file;
+ unsigned int line;
+ const char *format;
+ va_dcl
+{
+ va_list args;
+ char buffer[2000];
+
+ if (!flag_no_warnings)
+ {
+ va_start (args);
+ vsprintf (buffer, format, args);
+ va_end (args);
+ as_warn_internal (file, line, buffer);
+ }
+}
+#endif /* not NO_STDARG */
+
+/* The common portion of as_bad and as_bad_where. */
+
+static void
+as_bad_internal (char *file, unsigned int line, char *buffer)
+{
+ ++error_count;
+
+ if (file == NULL)
+ as_where (&file, &line);
+
+ identify (file);
+ if (file)
+ fprintf (stderr, "%s:%u: ", file, line);
+ fprintf (stderr, _("Error: "));
+ fputs (buffer, stderr);
+ (void) putc ('\n', stderr);
+#ifndef NO_LISTING
+ listing_error (buffer);
+#endif
+}
+
+/* Send to stderr a string as a warning, and locate warning in input
+ file(s). Please us when there is no recovery, but we want to
+ continue processing but not produce an object file.
+ Please explain in string (which may have '\n's) what recovery was
+ done. */
+
+#ifdef USE_STDARG
+void
+as_bad (const char *format, ...)
+{
+ va_list args;
+ char buffer[2000];
+
+ va_start (args, format);
+ vsprintf (buffer, format, args);
+ va_end (args);
+
+ as_bad_internal ((char *) NULL, 0, buffer);
+}
+
+#else
+void
+as_bad (format, va_alist)
+ const char *format;
+ va_dcl
+{
+ va_list args;
+ char buffer[2000];
+
+ va_start (args);
+ vsprintf (buffer, format, args);
+ va_end (args);
+
+ as_bad_internal ((char *) NULL, 0, buffer);
+}
+#endif /* not NO_STDARG */
+
+/* Like as_bad but the file name and line number are passed in.
+ Unfortunately, we have to repeat the function in order to handle
+ the varargs correctly and portably. */
+
+#ifdef USE_STDARG
+void
+as_bad_where (char *file, unsigned int line, const char *format, ...)
+{
+ va_list args;
+ char buffer[2000];
+
+ va_start (args, format);
+ vsprintf (buffer, format, args);
+ va_end (args);
+
+ as_bad_internal (file, line, buffer);
+}
+
+#else
+void
+as_bad_where (file, line, format, va_alist)
+ char *file;
+ unsigned int line;
+ const char *format;
+ va_dcl
+{
+ va_list args;
+ char buffer[2000];
+
+ va_start (args);
+ vsprintf (buffer, format, args);
+ va_end (args);
+
+ as_bad_internal (file, line, buffer);
+}
+#endif /* not NO_STDARG */
+
+/* Send to stderr a string as a fatal message, and print location of
+ error in input file(s).
+ Please only use this for when we DON'T have some recovery action.
+ It xexit()s with a warning status. */
+
+#ifdef USE_STDARG
+void
+as_fatal (const char *format, ...)
+{
+ va_list args;
+
+ as_show_where ();
+ va_start (args, format);
+ fprintf (stderr, _("Fatal error: "));
+ vfprintf (stderr, format, args);
+ (void) putc ('\n', stderr);
+ va_end (args);
+ /* Delete the output file, if it exists. This will prevent make from
+ thinking that a file was created and hence does not need rebuilding. */
+ if (out_file_name != NULL)
+ unlink (out_file_name);
+ xexit (EXIT_FAILURE);
+}
+#else
+void
+as_fatal (format, va_alist)
+ char *format;
+ va_dcl
+{
+ va_list args;
+
+ as_show_where ();
+ va_start (args);
+ fprintf (stderr, _("Fatal error: "));
+ vfprintf (stderr, format, args);
+ (void) putc ('\n', stderr);
+ va_end (args);
+ xexit (EXIT_FAILURE);
+}
+#endif /* not NO_STDARG */
+
+/* Indicate assertion failure.
+ Arguments: Filename, line number, optional function name. */
+
+void
+as_assert (const char *file, int line, const char *fn)
+{
+ as_show_where ();
+ fprintf (stderr, _("Internal error!\n"));
+ if (fn)
+ fprintf (stderr, _("Assertion failure in %s at %s line %d.\n"),
+ fn, file, line);
+ else
+ fprintf (stderr, _("Assertion failure at %s line %d.\n"), file, line);
+ fprintf (stderr, _("Please report this bug.\n"));
+ xexit (EXIT_FAILURE);
+}
+
+/* as_abort: Print a friendly message saying how totally hosed we are,
+ and exit without producing a core file. */
+
+void
+as_abort (const char *file, int line, const char *fn)
+{
+ as_show_where ();
+ if (fn)
+ fprintf (stderr, _("Internal error, aborting at %s line %d in %s\n"),
+ file, line, fn);
+ else
+ fprintf (stderr, _("Internal error, aborting at %s line %d\n"),
+ file, line);
+ fprintf (stderr, _("Please report this bug.\n"));
+ xexit (EXIT_FAILURE);
+}
+
+/* Support routines. */
+
+void
+fprint_value (FILE *file, valueT val)
+{
+ if (sizeof (val) <= sizeof (long))
+ {
+ fprintf (file, "%ld", (long) val);
+ return;
+ }
+#ifdef BFD_ASSEMBLER
+ if (sizeof (val) <= sizeof (bfd_vma))
+ {
+ fprintf_vma (file, val);
+ return;
+ }
+#endif
+ abort ();
+}
+
+void
+sprint_value (char *buf, valueT val)
+{
+ if (sizeof (val) <= sizeof (long))
+ {
+ sprintf (buf, "%ld", (long) val);
+ return;
+ }
+#ifdef BFD_ASSEMBLER
+ if (sizeof (val) <= sizeof (bfd_vma))
+ {
+ sprintf_vma (buf, val);
+ return;
+ }
+#endif
+ abort ();
+}
diff --git a/x/binutils/gas/obj.h b/x/binutils/gas/obj.h
new file mode 100644
index 0000000..497524a
--- /dev/null
+++ b/x/binutils/gas/obj.h
@@ -0,0 +1,94 @@
+/* obj.h - defines the object dependent hooks for all object
+ format backends.
+
+ Copyright 1987, 1990, 1991, 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+char *obj_default_output_file_name (void);
+void obj_emit_relocations (char **where, fixS * fixP,
+ relax_addressT segment_address_in_file);
+void obj_emit_strings (char **where);
+void obj_emit_symbols (char **where, symbolS * symbols);
+#ifndef obj_read_begin_hook
+void obj_read_begin_hook (void);
+#endif
+#ifndef BFD_ASSEMBLER
+void obj_crawl_symbol_chain (object_headers * headers);
+void obj_header_append (char **where, object_headers * headers);
+#ifndef obj_pre_write_hook
+void obj_pre_write_hook (object_headers * headers);
+#endif
+#endif
+
+#ifndef obj_symbol_new_hook
+void obj_symbol_new_hook (symbolS * symbolP);
+#endif
+
+void obj_symbol_to_chars (char **where, symbolS * symbolP);
+
+extern const pseudo_typeS obj_pseudo_table[];
+
+#ifdef BFD_ASSEMBLER
+struct format_ops {
+ int flavor;
+ unsigned dfl_leading_underscore : 1;
+ unsigned emit_section_symbols : 1;
+ void (*begin) (void);
+ void (*app_file) (const char *);
+ void (*frob_symbol) (symbolS *, int *);
+ void (*frob_file) (void);
+ void (*frob_file_before_adjust) (void);
+ void (*frob_file_before_fix) (void);
+ void (*frob_file_after_relocs) (void);
+ bfd_vma (*s_get_size) (symbolS *);
+ void (*s_set_size) (symbolS *, bfd_vma);
+ bfd_vma (*s_get_align) (symbolS *);
+ void (*s_set_align) (symbolS *, bfd_vma);
+ int (*s_get_other) (symbolS *);
+ void (*s_set_other) (symbolS *, int);
+ int (*s_get_desc) (symbolS *);
+ void (*s_set_desc) (symbolS *, int);
+ int (*s_get_type) (symbolS *);
+ void (*s_set_type) (symbolS *, int);
+ void (*copy_symbol_attributes) (symbolS *, symbolS *);
+ void (*generate_asm_lineno) (void);
+ void (*process_stab) (segT, int, const char *, int, int, int);
+ int (*separate_stab_sections) (void);
+ void (*init_stab_section) (segT);
+ int (*sec_sym_ok_for_reloc) (asection *);
+ void (*pop_insert) (void);
+ /* For configurations using ECOFF_DEBUGGING, this callback is used. */
+ void (*ecoff_set_ext) (symbolS *, struct ecoff_extr *);
+
+ void (*read_begin_hook) (void);
+ void (*symbol_new_hook) (symbolS *);
+};
+
+extern const struct format_ops elf_format_ops;
+extern const struct format_ops ecoff_format_ops;
+extern const struct format_ops coff_format_ops;
+extern const struct format_ops aout_format_ops;
+
+#ifndef this_format
+COMMON const struct format_ops *this_format;
+#endif
+#endif
+
+/* end of obj.h */
diff --git a/x/binutils/gas/output-file.c b/x/binutils/gas/output-file.c
new file mode 100644
index 0000000..4c376b4
--- /dev/null
+++ b/x/binutils/gas/output-file.c
@@ -0,0 +1,154 @@
+/* output-file.c - Deal with the output file
+ Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1996, 1998, 1999, 2001, 2003
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <stdio.h>
+
+#include "as.h"
+
+#include "output-file.h"
+
+#ifdef BFD_HEADERS
+#define USE_BFD
+#endif
+
+#ifdef BFD_ASSEMBLER
+#define USE_BFD
+#ifndef TARGET_MACH
+#define TARGET_MACH 0
+#endif
+#endif
+
+#ifdef USE_BFD
+#include "bfd.h"
+bfd *stdoutput;
+
+void
+output_file_create (char *name)
+{
+ if (name[0] == '-' && name[1] == '\0')
+ as_fatal (_("can't open a bfd on stdout %s"), name);
+
+ else if (!(stdoutput = bfd_openw (name, TARGET_FORMAT)))
+ {
+ as_perror (_("FATAL: can't create %s"), name);
+ exit (EXIT_FAILURE);
+ }
+
+ bfd_set_format (stdoutput, bfd_object);
+#ifdef BFD_ASSEMBLER
+ bfd_set_arch_mach (stdoutput, TARGET_ARCH, TARGET_MACH);
+#endif
+ if (flag_traditional_format)
+ stdoutput->flags |= BFD_TRADITIONAL_FORMAT;
+}
+
+void
+output_file_close (char *filename)
+{
+#ifdef BFD_ASSEMBLER
+ /* Close the bfd. */
+ if (bfd_close (stdoutput) == 0)
+ {
+ bfd_perror (filename);
+ as_perror (_("FATAL: can't close %s\n"), filename);
+ exit (EXIT_FAILURE);
+ }
+#else
+ /* Close the bfd without getting bfd to write out anything by itself. */
+ if (bfd_close_all_done (stdoutput) == 0)
+ {
+ as_perror (_("FATAL: can't close %s\n"), filename);
+ exit (EXIT_FAILURE);
+ }
+#endif
+ stdoutput = NULL; /* Trust nobody! */
+}
+
+#ifndef BFD_ASSEMBLER
+void
+output_file_append (char *where ATTRIBUTE_UNUSED,
+ long length ATTRIBUTE_UNUSED,
+ char *filename ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+#endif
+
+#else
+
+static FILE *stdoutput;
+
+void
+output_file_create (char *name)
+{
+ if (name[0] == '-' && name[1] == '\0')
+ {
+ stdoutput = stdout;
+ return;
+ }
+
+ stdoutput = fopen (name, FOPEN_WB);
+ if (stdoutput == NULL)
+ {
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
+ as_perror (_("FATAL: can't create %s"), name);
+ exit (EXIT_FAILURE);
+ }
+}
+
+void
+output_file_close (char *filename)
+{
+ if (EOF == fclose (stdoutput))
+ {
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
+ as_perror (_("FATAL: can't close %s"), filename);
+ exit (EXIT_FAILURE);
+ }
+
+ /* Trust nobody! */
+ stdoutput = NULL;
+}
+
+void
+output_file_append (char * where, long length, char * filename)
+{
+ for (; length; length--, where++)
+ {
+ (void) putc (*where, stdoutput);
+
+ if (ferror (stdoutput))
+ {
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
+ as_perror (_("Failed to emit an object byte"), filename);
+ as_fatal (_("can't continue"));
+ }
+ }
+}
+
+#endif
+
diff --git a/x/binutils/gas/output-file.h b/x/binutils/gas/output-file.h
new file mode 100644
index 0000000..6779e4b
--- /dev/null
+++ b/x/binutils/gas/output-file.h
@@ -0,0 +1,26 @@
+/* This file is output-file.h
+
+ Copyright 1987, 1988, 1989, 1990, 1991, 1992
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+void output_file_append (char *where, long length, char *filename);
+void output_file_close (char *filename);
+void output_file_create (char *name);
+
+/* end of output-file.h */
diff --git a/x/binutils/gas/po/Make-in b/x/binutils/gas/po/Make-in
new file mode 100644
index 0000000..6176dbf
--- /dev/null
+++ b/x/binutils/gas/po/Make-in
@@ -0,0 +1,253 @@
+# Makefile for program source directory in GNU NLS utilities package.
+# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datadir = $(prefix)/@DATADIRNAME@
+localedir = $(datadir)/locale
+gnulocaledir = $(prefix)/share/locale
+gettextsrcdir = $(prefix)/share/gettext/po
+subdir = po
+
+DESTDIR =
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+
+CC = @CC@
+GENCAT = @GENCAT@
+GMSGFMT = PATH=../src:$$PATH @GMSGFMT@
+MSGFMT = @MSGFMT@
+XGETTEXT = PATH=../src:$$PATH @XGETTEXT@
+MSGMERGE = PATH=../src:$$PATH msgmerge
+
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+
+INCLUDES = -I.. -I$(top_srcdir)/intl
+
+COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
+
+SOURCES = cat-id-tbl.c
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \
+stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES)
+
+POTFILES = \
+
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+INSTOBJEXT = @INSTOBJEXT@
+
+.SUFFIXES:
+.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat
+
+.c.o:
+ $(COMPILE) $<
+
+.po.pox:
+ $(MAKE) $(PACKAGE).pot
+ $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox
+
+.po.mo:
+ $(MSGFMT) -o $@ $<
+
+.po.gmo:
+ file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \
+ && rm -f $$file && $(GMSGFMT) -o $$file $<
+
+.po.cat:
+ sed -f ../intl/po2msg.sed < $< > $*.msg \
+ && rm -f $@ && $(GENCAT) $@ $*.msg
+
+
+all: all-@USE_NLS@
+
+all-yes: $(CATALOGS) @MAINT@ $(PACKAGE).pot
+all-no:
+
+$(srcdir)/$(PACKAGE).pot: $(POTFILES)
+ $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \
+ --add-comments --keyword=_ --keyword=N_ \
+ --files-from=$(srcdir)/POTFILES.in
+ rm -f $(srcdir)/$(PACKAGE).pot
+ mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot
+
+$(srcdir)/cat-id-tbl.c: stamp-cat-id; @:
+$(srcdir)/stamp-cat-id: $(PACKAGE).pot
+ rm -f cat-id-tbl.tmp
+ sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \
+ | sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp
+ if cmp -s cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; then \
+ rm cat-id-tbl.tmp; \
+ else \
+ echo cat-id-tbl.c changed; \
+ rm -f $(srcdir)/cat-id-tbl.c; \
+ mv cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; \
+ fi
+ cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id
+
+
+install: install-exec install-data
+install-exec:
+install-info:
+install-data: install-data-@USE_NLS@
+install-data-no: all
+install-data-yes: all
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(DESTDIR)$(datadir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(datadir); \
+ fi
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ case "$$cat" in \
+ *.gmo) destdir=$(gnulocaledir);; \
+ *) destdir=$(localedir);; \
+ esac; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ dir=$(DESTDIR)$$destdir/$$lang/LC_MESSAGES; \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $$dir; \
+ else \
+ $(top_srcdir)/mkinstalldirs $$dir; \
+ fi; \
+ if test -r $$cat; then \
+ $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ else \
+ $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ fi; \
+ if test -r $$cat.m; then \
+ $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ if test -r $(srcdir)/$$cat.m ; then \
+ $(INSTALL_DATA) $(srcdir)/$$cat.m \
+ $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ true; \
+ fi; \
+ fi; \
+ done
+ if test "$(PACKAGE)" = "gettext"; then \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(DESTDIR)$(gettextsrcdir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(gettextsrcdir); \
+ fi; \
+ $(INSTALL_DATA) $(srcdir)/Makefile.in.in \
+ $(DESTDIR)$(gettextsrcdir)/Makefile.in.in; \
+ else \
+ : ; \
+ fi
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall:
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ done
+ rm -f $(DESTDIR)$(gettextsrcdir)/po-Makefile.in.in
+
+check: all
+
+cat-id-tbl.o: ../intl/libgettext.h
+
+dvi info tags TAGS ID:
+
+mostlyclean:
+ rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp
+ rm -fr *.o
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ rm -f $(GMOFILES)
+
+distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir: update-po $(DISTFILES)
+ dists="$(DISTFILES)"; \
+ for file in $$dists; do \
+ ln $(srcdir)/$$file $(distdir) 2> /dev/null \
+ || cp -p $(srcdir)/$$file $(distdir); \
+ done
+
+update-po: Makefile
+ $(MAKE) $(PACKAGE).pot
+ PATH=`pwd`/../src:$$PATH; \
+ cd $(srcdir); \
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ mv $$lang.po $$lang.old.po; \
+ echo "$$lang:"; \
+ if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \
+ rm -f $$lang.old.po; \
+ else \
+ echo "msgmerge for $$cat failed!"; \
+ rm -f $$lang.po; \
+ mv $$lang.old.po $$lang.po; \
+ fi; \
+ done
+
+POTFILES: POTFILES.in
+ ( if test 'x$(srcdir)' != 'x.'; then \
+ posrcprefix='$(top_srcdir)/'; \
+ else \
+ posrcprefix="../"; \
+ fi; \
+ rm -f $@-t $@ \
+ && (sed -e '/^#/d' -e '/^[ ]*$$/d' \
+ -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \
+ | sed -e '$$s/\\$$//') > $@-t \
+ && chmod a-w $@-t \
+ && mv $@-t $@ )
+
+POTFILES.in: @MAINT@ ../Makefile
+ cd .. && $(MAKE) po/POTFILES.in
+
+Makefile: Make-in ../config.status POTFILES
+ cd .. \
+ && CONFIG_FILES=$(subdir)/Makefile.in:$(subdir)/Make-in \
+ CONFIG_HEADERS= $(SHELL) ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/x/binutils/gas/po/POTFILES.in b/x/binutils/gas/po/POTFILES.in
new file mode 100644
index 0000000..e4e3e4e
--- /dev/null
+++ b/x/binutils/gas/po/POTFILES.in
@@ -0,0 +1,213 @@
+app.c
+app.c
+as.c
+as.c
+as.h
+asintl.h
+atof-generic.c
+atof-generic.c
+bignum-copy.c
+bignum-copy.c
+bignum.h
+bit_fix.h
+cgen.h
+cond.c
+cond.c
+config/e-crisaout.c
+config/e-criself.c
+config/e-i386aout.c
+config/e-i386coff.c
+config/e-i386elf.c
+config/e-mipsecoff.c
+config/e-mipself.c
+config/obj-aout.c
+config/obj-aout.h
+config/obj-bout.c
+config/obj-bout.h
+config/obj-coff.c
+config/obj-coff.h
+config/obj-ecoff.c
+config/obj-ecoff.h
+config/obj-elf.c
+config/obj-elf.h
+config/obj-evax.c
+config/obj-evax.h
+config/obj-hp300.c
+config/obj-hp300.h
+config/obj-ieee.c
+config/obj-ieee.h
+config/obj-som.c
+config/obj-som.h
+config/obj-vms.c
+config/obj-vms.h
+config/tc-a29k.c
+config/tc-a29k.h
+config/tc-alpha.c
+config/tc-alpha.h
+config/tc-arc.c
+config/tc-arc.h
+config/tc-arm.c
+config/tc-arm.h
+config/tc-avr.c
+config/tc-avr.h
+config/tc-cris.c
+config/tc-cris.h
+config/tc-d10v.c
+config/tc-d10v.h
+config/tc-d30v.c
+config/tc-d30v.h
+config/tc-dlx.c
+config/tc-dlx.h
+config/tc-fr30.c
+config/tc-fr30.h
+config/tc-frv.c
+config/tc-frv.h
+config/tc-h8300.c
+config/tc-h8300.h
+config/tc-h8500.c
+config/tc-h8500.h
+config/tc-hppa.c
+config/tc-hppa.h
+config/tc-i370.c
+config/tc-i370.h
+config/tc-i386.c
+config/tc-i386.h
+config/tc-i860.c
+config/tc-i860.h
+config/tc-i960.c
+config/tc-i960.h
+config/tc-ia64.c
+config/tc-ia64.h
+config/tc-ip2k.c
+config/tc-ip2k.h
+config/tc-m32r.c
+config/tc-m32r.h
+config/tc-m68hc11.c
+config/tc-m68hc11.h
+config/tc-m68k.c
+config/tc-m68k.h
+config/tc-m88k.c
+config/tc-m88k.h
+config/tc-mcore.c
+config/tc-mcore.h
+config/tc-mips.c
+config/tc-mips.h
+config/tc-mmix.c
+config/tc-mmix.h
+config/tc-mn10200.c
+config/tc-mn10200.h
+config/tc-mn10300.c
+config/tc-mn10300.h
+config/tc-msp430.c
+config/tc-msp430.h
+config/tc-ns32k.c
+config/tc-ns32k.h
+config/tc-openrisc.c
+config/tc-openrisc.h
+config/tc-or32.c
+config/tc-or32.h
+config/tc-pdp11.c
+config/tc-pdp11.h
+config/tc-pj.c
+config/tc-pj.h
+config/tc-ppc.c
+config/tc-ppc.h
+config/tc-s390.c
+config/tc-s390.h
+config/tc-sh64.c
+config/tc-sh64.h
+config/tc-sh.c
+config/tc-sh.h
+config/tc-sparc.c
+config/tc-sparc.h
+config/tc-tahoe.c
+config/tc-tahoe.h
+config/tc-tic30.c
+config/tc-tic30.h
+config/tc-tic54x.c
+config/tc-tic54x.h
+config/tc-tic80.c
+config/tc-tic80.h
+config/tc-v850.c
+config/tc-v850.h
+config/tc-vax.c
+config/tc-vax.h
+config/tc-w65.c
+config/tc-w65.h
+config/tc-xstormy16.c
+config/tc-xstormy16.h
+config/tc-xtensa.c
+config/tc-xtensa.h
+config/tc-z8k.c
+config/tc-z8k.h
+depend.c
+depend.c
+dw2gencfi.c
+dw2gencfi.c
+dw2gencfi.h
+dwarf2dbg.c
+dwarf2dbg.c
+dwarf2dbg.h
+ecoff.c
+ecoff.c
+ecoff.h
+ehopt.c
+ehopt.c
+emul.h
+emul-target.h
+expr.c
+expr.c
+expr.h
+flonum-copy.c
+flonum-copy.c
+flonum.h
+flonum-konst.c
+flonum-konst.c
+flonum-mult.c
+flonum-mult.c
+frags.c
+frags.c
+frags.h
+hash.c
+hash.c
+hash.h
+input-file.c
+input-file.c
+input-file.h
+input-scrub.c
+input-scrub.c
+itbl-ops.c
+itbl-ops.h
+listing.c
+listing.c
+listing.h
+literal.c
+literal.c
+macro.c
+macro.c
+macro.h
+messages.c
+messages.c
+obj.h
+output-file.c
+output-file.c
+output-file.h
+read.c
+read.c
+read.h
+sb.c
+sb.c
+sb.h
+stabs.c
+stabs.c
+struc-symbol.h
+subsegs.c
+subsegs.c
+subsegs.h
+symbols.c
+symbols.c
+symbols.h
+tc.h
+write.c
+write.c
+write.h
diff --git a/x/binutils/gas/po/gas.pot b/x/binutils/gas/po/gas.pot
new file mode 100644
index 0000000..ae3cbab
--- /dev/null
+++ b/x/binutils/gas/po/gas.pot
@@ -0,0 +1,11467 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2003-07-17 14:56+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: app.c:474 app.c:488
+msgid "end of file in comment"
+msgstr ""
+
+#: app.c:567
+msgid "end of file in string; inserted '\"'"
+msgstr ""
+
+#: app.c:612
+msgid "end of file in string; '\"' inserted"
+msgstr ""
+
+#: app.c:638
+#, c-format
+msgid "unknown escape '\\%c' in string; ignored"
+msgstr ""
+
+#: app.c:790
+msgid "end of file not at end of a line; newline inserted"
+msgstr ""
+
+#: app.c:949
+msgid "end of file in multiline comment"
+msgstr ""
+
+#: app.c:1013
+msgid "end of file after a one-character quote; \\0 inserted"
+msgstr ""
+
+#: app.c:1021
+msgid "end of file in escape character"
+msgstr ""
+
+#: app.c:1033
+msgid "missing close quote; (assumed)"
+msgstr ""
+
+#: app.c:1101 app.c:1155 app.c:1166 app.c:1231
+msgid "end of file in comment; newline inserted"
+msgstr ""
+
+#: as.c:160
+msgid "missing emulation mode name"
+msgstr ""
+
+#: as.c:175
+#, c-format
+msgid "unrecognized emulation name `%s'"
+msgstr ""
+
+#: as.c:222
+#, c-format
+msgid "GNU assembler version %s (%s) using BFD version %s"
+msgstr ""
+
+#: as.c:225
+#, c-format
+msgid "GNU assembler version %s (%s)"
+msgstr ""
+
+#: as.c:234
+#, c-format
+msgid "Usage: %s [option...] [asmfile...]\n"
+msgstr ""
+
+#: as.c:236
+msgid ""
+"Options:\n"
+" -a[sub-option...]\t turn on listings\n"
+" \t Sub-options [default hls]:\n"
+" \t c omit false conditionals\n"
+" \t d omit debugging directives\n"
+" \t h include high-level source\n"
+" \t l include assembly\n"
+" \t m include macro expansions\n"
+" \t n omit forms processing\n"
+" \t s include symbols\n"
+" \t =FILE list to FILE (must be last sub-option)\n"
+msgstr ""
+
+#: as.c:249
+msgid " -D produce assembler debugging messages\n"
+msgstr ""
+
+#: as.c:251
+msgid " --defsym SYM=VAL define symbol SYM to given value\n"
+msgstr ""
+
+#: as.c:267
+#, c-format
+msgid " emulate output (default %s)\n"
+msgstr ""
+
+#: as.c:272
+msgid " --execstack require executable stack for this object\n"
+msgstr ""
+
+#: as.c:274
+msgid ""
+" --noexecstack don't require executable stack for this object\n"
+msgstr ""
+
+#: as.c:277
+msgid " -f skip whitespace and comment preprocessing\n"
+msgstr ""
+
+#: as.c:279
+msgid " --gstabs generate stabs debugging information\n"
+msgstr ""
+
+#: as.c:281
+msgid " --gdwarf2 generate DWARF2 debugging information\n"
+msgstr ""
+
+#: as.c:283
+msgid " --help show this message and exit\n"
+msgstr ""
+
+#: as.c:285
+msgid " --target-help show target specific options\n"
+msgstr ""
+
+#: as.c:287
+msgid ""
+" -I DIR add DIR to search list for .include directives\n"
+msgstr ""
+
+#: as.c:289
+msgid " -J don't warn about signed overflow\n"
+msgstr ""
+
+#: as.c:291
+msgid ""
+" -K warn when differences altered for long "
+"displacements\n"
+msgstr ""
+
+#: as.c:293
+msgid " -L,--keep-locals keep local symbols (e.g. starting with `L')\n"
+msgstr ""
+
+#: as.c:295
+msgid " -M,--mri assemble in MRI compatibility mode\n"
+msgstr ""
+
+#: as.c:297
+msgid ""
+" --MD FILE write dependency information in FILE (default "
+"none)\n"
+msgstr ""
+
+#: as.c:299
+msgid " -nocpp ignored\n"
+msgstr ""
+
+#: as.c:301
+msgid ""
+" -o OBJFILE name the object-file output OBJFILE (default a."
+"out)\n"
+msgstr ""
+
+#: as.c:303
+msgid " -R fold data section into text section\n"
+msgstr ""
+
+#: as.c:305
+msgid ""
+" --statistics print various measured statistics from execution\n"
+msgstr ""
+
+#: as.c:307
+msgid " --strip-local-absolute strip local absolute symbols\n"
+msgstr ""
+
+#: as.c:309
+msgid ""
+" --traditional-format Use same format as native assembler when possible\n"
+msgstr ""
+
+#: as.c:311
+msgid " --version print assembler version number and exit\n"
+msgstr ""
+
+#: as.c:313
+msgid " -W --no-warn suppress warnings\n"
+msgstr ""
+
+#: as.c:315
+msgid " --warn don't suppress warnings\n"
+msgstr ""
+
+#: as.c:317
+msgid " --fatal-warnings treat warnings as errors\n"
+msgstr ""
+
+#: as.c:319
+msgid ""
+" --itbl INSTTBL extend instruction set to include instructions\n"
+" matching the specifications defined in file "
+"INSTTBL\n"
+msgstr ""
+
+#: as.c:322
+msgid " -w ignored\n"
+msgstr ""
+
+#: as.c:324
+msgid " -X ignored\n"
+msgstr ""
+
+#: as.c:326
+msgid " -Z generate object file even after errors\n"
+msgstr ""
+
+#: as.c:328
+msgid ""
+" --listing-lhs-width set the width in words of the output data column "
+"of\n"
+" the listing\n"
+msgstr ""
+
+#: as.c:331
+msgid ""
+" --listing-lhs-width2 set the width in words of the continuation lines\n"
+" of the output data column; ignored if smaller "
+"than\n"
+" the width of the first line\n"
+msgstr ""
+
+#: as.c:335
+msgid ""
+" --listing-rhs-width set the max width in characters of the lines from\n"
+" the source file\n"
+msgstr ""
+
+#: as.c:338
+msgid ""
+" --listing-cont-lines set the maximum number of continuation lines used\n"
+" for the output data column of the listing\n"
+msgstr ""
+
+#: as.c:345
+#, c-format
+msgid "Report bugs to %s\n"
+msgstr ""
+
+#: as.c:557 as.c:559
+#, c-format
+msgid "GNU assembler %s\n"
+msgstr ""
+
+#: as.c:561
+msgid "Copyright 2002 Free Software Foundation, Inc.\n"
+msgstr ""
+
+#: as.c:562
+msgid ""
+"This program is free software; you may redistribute it under the terms of\n"
+"the GNU General Public License. This program has absolutely no warranty.\n"
+msgstr ""
+
+#: as.c:565
+#, c-format
+msgid "This assembler was configured for a target of `%s'.\n"
+msgstr ""
+
+#: as.c:572
+msgid "multiple emulation names specified"
+msgstr ""
+
+#: as.c:574
+msgid "emulations not handled in this configuration"
+msgstr ""
+
+#: as.c:579
+#, c-format
+msgid "alias = %s\n"
+msgstr ""
+
+#: as.c:580
+#, c-format
+msgid "canonical = %s\n"
+msgstr ""
+
+#: as.c:581
+#, c-format
+msgid "cpu-type = %s\n"
+msgstr ""
+
+#: as.c:583
+#, c-format
+msgid "format = %s\n"
+msgstr ""
+
+#: as.c:586
+#, c-format
+msgid "bfd-target = %s\n"
+msgstr ""
+
+#: as.c:599
+msgid "bad defsym; format is --defsym name=value"
+msgstr ""
+
+#: as.c:623
+msgid "no file name following -t option"
+msgstr ""
+
+#: as.c:638
+#, c-format
+msgid "failed to read instruction table %s\n"
+msgstr ""
+
+#: as.c:765
+#, c-format
+msgid "invalid listing option `%c'"
+msgstr ""
+
+#: as.c:984
+#, c-format
+msgid "%d warnings, treating warnings as errors"
+msgstr ""
+
+#: as.c:1015
+#, c-format
+msgid "%s: total time in assembly: %ld.%06ld\n"
+msgstr ""
+
+#: as.c:1018
+#, c-format
+msgid "%s: data size %ld\n"
+msgstr ""
+
+#: as.h:216
+#, c-format
+msgid "Case value %ld unexpected at line %d of file \"%s\"\n"
+msgstr ""
+
+#.
+#. * We have a GROSS internal error.
+#. * This should never happen.
+#.
+#: atof-generic.c:437 config/tc-m68k.c:2869
+msgid "failed sanity check"
+msgstr ""
+
+#: cond.c:83
+msgid "invalid identifier for \".ifdef\""
+msgstr ""
+
+#: cond.c:151
+msgid "non-constant expression in \".if\" statement"
+msgstr ""
+
+#: cond.c:247
+msgid "bad format for ifc or ifnc"
+msgstr ""
+
+#: cond.c:278
+msgid "\".elseif\" without matching \".if\""
+msgstr ""
+
+#: cond.c:282
+msgid "\".elseif\" after \".else\""
+msgstr ""
+
+#: cond.c:285 cond.c:393
+msgid "here is the previous \"else\""
+msgstr ""
+
+#: cond.c:288 cond.c:396
+msgid "here is the previous \"if\""
+msgstr ""
+
+#: cond.c:317
+msgid "non-constant expression in \".elseif\" statement"
+msgstr ""
+
+#: cond.c:356
+msgid "\".endif\" without \".if\""
+msgstr ""
+
+#: cond.c:386
+msgid "\".else\" without matching \".if\""
+msgstr ""
+
+#: cond.c:390
+msgid "duplicate \"else\""
+msgstr ""
+
+#: cond.c:442
+msgid ".ifeqs syntax error"
+msgstr ""
+
+#: cond.c:525
+msgid "end of macro inside conditional"
+msgstr ""
+
+#: cond.c:527
+msgid "end of file inside conditional"
+msgstr ""
+
+#: cond.c:530
+msgid "here is the start of the unterminated conditional"
+msgstr ""
+
+#: cond.c:534
+msgid "here is the \"else\" of the unterminated conditional"
+msgstr ""
+
+#: config/obj-aout.c:162
+#, c-format
+msgid "Attempt to put a common symbol into set %s"
+msgstr ""
+
+#: config/obj-aout.c:166
+#, c-format
+msgid "Attempt to put an undefined symbol into set %s"
+msgstr ""
+
+#: config/obj-aout.c:197 config/obj-coff.c:1276
+#, c-format
+msgid "Symbol `%s' can not be both weak and common"
+msgstr ""
+
+#: config/obj-aout.c:255 config/obj-coff.c:2022
+msgid "unresolved relocation"
+msgstr ""
+
+#: config/obj-aout.c:257 config/obj-coff.c:2024
+#, c-format
+msgid "bad relocation: symbol `%s' not in symbol table"
+msgstr ""
+
+#: config/obj-aout.c:344
+#, c-format
+msgid "%s: bad type for weak symbol"
+msgstr ""
+
+#: config/obj-aout.c:458 config/obj-coff.c:2945 write.c:1931
+#, c-format
+msgid "%s: global symbols not supported in common sections"
+msgstr ""
+
+#: config/obj-aout.c:524
+#, c-format
+msgid "Local symbol %s never defined."
+msgstr ""
+
+#: config/obj-bout.c:319 config/obj-vms.c:629
+#, c-format
+msgid "Local symbol %s never defined"
+msgstr ""
+
+#: config/obj-coff.c:166
+#, c-format
+msgid "Inserting \"%s\" into structure table failed: %s"
+msgstr ""
+
+#. Zero is used as an end marker in the file.
+#: config/obj-coff.c:469
+msgid "Line numbers must be positive integers\n"
+msgstr ""
+
+#. Wrong context.
+#: config/obj-coff.c:503 config/obj-coff.c:2367
+msgid ".ln pseudo-op inside .def/.endef: ignored."
+msgstr ""
+
+#: config/obj-coff.c:546 ecoff.c:3278
+msgid ".loc outside of .text"
+msgstr ""
+
+#: config/obj-coff.c:553
+msgid ".loc pseudo-op inside .def/.endef: ignored."
+msgstr ""
+
+#: config/obj-coff.c:641 config/obj-coff.c:2419
+msgid ".def pseudo-op used inside of .def/.endef: ignored."
+msgstr ""
+
+#: config/obj-coff.c:687 config/obj-coff.c:2471
+msgid ".endef pseudo-op used outside of .def/.endef: ignored."
+msgstr ""
+
+#: config/obj-coff.c:725
+#, c-format
+msgid "`%s' symbol without preceding function"
+msgstr ""
+
+#: config/obj-coff.c:812 config/obj-coff.c:2551
+#, c-format
+msgid "unexpected storage class %d"
+msgstr ""
+
+#: config/obj-coff.c:925 config/obj-coff.c:2658
+msgid ".dim pseudo-op used outside of .def/.endef: ignored."
+msgstr ""
+
+#: config/obj-coff.c:945 config/obj-coff.c:2678
+msgid "badly formed .dim directive ignored"
+msgstr ""
+
+#: config/obj-coff.c:996 config/obj-coff.c:2738
+msgid ".size pseudo-op used outside of .def/.endef ignored."
+msgstr ""
+
+#: config/obj-coff.c:1012 config/obj-coff.c:2754
+msgid ".scl pseudo-op used outside of .def/.endef ignored."
+msgstr ""
+
+#: config/obj-coff.c:1030 config/obj-coff.c:2772
+msgid ".tag pseudo-op used outside of .def/.endef ignored."
+msgstr ""
+
+#: config/obj-coff.c:1049 config/obj-coff.c:2789
+#, c-format
+msgid "tag not found for .tag %s"
+msgstr ""
+
+#: config/obj-coff.c:1064 config/obj-coff.c:2803
+msgid ".type pseudo-op used outside of .def/.endef ignored."
+msgstr ""
+
+#: config/obj-coff.c:1086 config/obj-coff.c:2823
+msgid ".val pseudo-op used outside of .def/.endef ignored."
+msgstr ""
+
+#: config/obj-coff.c:1233 config/obj-coff.c:3016
+msgid "mismatched .eb"
+msgstr ""
+
+#: config/obj-coff.c:1254 config/obj-coff.c:3054
+msgid "C_EFCN symbol out of scope"
+msgstr ""
+
+#. STYP_INFO
+#. STYP_LIB
+#. STYP_OVER
+#: config/obj-coff.c:1482
+#, c-format
+msgid "unsupported section attribute '%c'"
+msgstr ""
+
+#: config/obj-coff.c:1487 config/obj-coff.c:3759 config/tc-ppc.c:4508
+#, c-format
+msgid "unknown section attribute '%c'"
+msgstr ""
+
+#: config/obj-coff.c:1517 config/tc-ppc.c:4526 config/tc-tic54x.c:4339
+#: read.c:2562
+#, c-format
+msgid "error setting flags for \"%s\": %s"
+msgstr ""
+
+#: config/obj-coff.c:1528
+#, c-format
+msgid "Ignoring changed section attributes for %s"
+msgstr ""
+
+#: config/obj-coff.c:1664
+#, c-format
+msgid "0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"
+msgstr ""
+
+#: config/obj-coff.c:1849 config/obj-ieee.c:69
+msgid "Out of step\n"
+msgstr ""
+
+#: config/obj-coff.c:2286
+msgid "bfd_coff_swap_scnhdr_out failed"
+msgstr ""
+
+#: config/obj-coff.c:2507
+msgid "`.bf' symbol without preceding function\n"
+msgstr ""
+
+#: config/obj-coff.c:3457 config/obj-ieee.c:521
+#, c-format
+msgid "FATAL: Can't create %s"
+msgstr ""
+
+#: config/obj-coff.c:3635
+#, c-format
+msgid "Can't close %s: %s"
+msgstr ""
+
+#: config/obj-coff.c:3669
+#, c-format
+msgid "Too many new sections; can't add \"%s\""
+msgstr ""
+
+#: config/obj-coff.c:4057 config/tc-sparc.c:3635
+msgid "Expected comma after name"
+msgstr ""
+
+#: config/obj-coff.c:4063
+msgid "Missing size expression"
+msgstr ""
+
+#: config/obj-coff.c:4069
+#, c-format
+msgid "lcomm length (%d.) <0! Ignored."
+msgstr ""
+
+#: config/obj-coff.c:4097
+#, c-format
+msgid "Symbol %s already defined"
+msgstr ""
+
+#: config/obj-coff.c:4193 config/tc-i960.c:3221
+#, c-format
+msgid "No 'bal' entry point for leafproc %s"
+msgstr ""
+
+#: config/obj-coff.c:4270
+#, c-format
+msgid "Negative of non-absolute symbol %s"
+msgstr ""
+
+#: config/obj-coff.c:4290
+msgid "callj to difference of 2 symbols"
+msgstr ""
+
+#: config/obj-coff.c:4334
+#, c-format
+msgid "Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %ld."
+msgstr ""
+
+#: config/obj-coff.c:4420 config/tc-i960.c:2844
+msgid "can't use COBR format with external label"
+msgstr ""
+
+#: config/obj-coff.c:4493
+#, c-format
+msgid "Value of %ld too large for field of %d bytes at 0x%lx"
+msgstr ""
+
+#: config/obj-coff.c:4507
+#, c-format
+msgid "Signed .word overflow; switch may be too large; %ld at 0x%lx"
+msgstr ""
+
+#: config/obj-ecoff.c:192
+msgid "Can't set GP value"
+msgstr ""
+
+#: config/obj-ecoff.c:199
+msgid "Can't set register masks"
+msgstr ""
+
+#: config/obj-elf.c:316
+msgid "expected comma after symbol-name"
+msgstr ""
+
+#: config/obj-elf.c:326
+#, c-format
+msgid ".COMMon length (%ld) out of range, ignored."
+msgstr ""
+
+#: config/obj-elf.c:335 ecoff.c:3397 read.c:1406 read.c:1507 read.c:2145
+#: read.c:2234 read.c:2863 read.c:4968 symbols.c:367 symbols.c:466
+#, c-format
+msgid "symbol `%s' is already defined"
+msgstr ""
+
+#: config/obj-elf.c:343
+#, c-format
+msgid "length of .comm \"%s\" is already %ld; not changed to %ld"
+msgstr ""
+
+#: config/obj-elf.c:367
+msgid "common alignment negative; 0 assumed"
+msgstr ""
+
+#: config/obj-elf.c:386
+msgid "common alignment not a power of 2"
+msgstr ""
+
+#: config/obj-elf.c:449 config/tc-sparc.c:3931 config/tc-v850.c:461
+#, c-format
+msgid "bad .common segment %s"
+msgstr ""
+
+#: config/obj-elf.c:717
+#, c-format
+msgid "setting incorrect section type for %s"
+msgstr ""
+
+#: config/obj-elf.c:721
+#, c-format
+msgid "ignoring incorrect section type for %s"
+msgstr ""
+
+#: config/obj-elf.c:734
+#, c-format
+msgid "setting incorrect section attributes for %s"
+msgstr ""
+
+#: config/obj-elf.c:786
+#, c-format
+msgid "ignoring changed section attributes for %s"
+msgstr ""
+
+#: config/obj-elf.c:788
+#, c-format
+msgid "ignoring changed section entity size for %s"
+msgstr ""
+
+#: config/obj-elf.c:791
+#, c-format
+msgid "ignoring new section group for %s"
+msgstr ""
+
+#: config/obj-elf.c:845
+msgid "unrecognized .section attribute: want a,w,x,M,S,G,T"
+msgstr ""
+
+#: config/obj-elf.c:884
+msgid "unrecognized section attribute"
+msgstr ""
+
+#: config/obj-elf.c:906 read.c:2545
+msgid "unrecognized section type"
+msgstr ""
+
+#: config/obj-elf.c:936
+msgid "missing name"
+msgstr ""
+
+#: config/obj-elf.c:1048
+msgid "invalid merge entity size"
+msgstr ""
+
+#: config/obj-elf.c:1055
+msgid "entity size for SHF_MERGE not specified"
+msgstr ""
+
+#: config/obj-elf.c:1075
+msgid "group name for SHF_GROUP not specified"
+msgstr ""
+
+#: config/obj-elf.c:1088
+msgid "character following name is not '#'"
+msgstr ""
+
+#: config/obj-elf.c:1189
+msgid ".previous without corresponding .section; ignored"
+msgstr ""
+
+#: config/obj-elf.c:1216
+msgid ".popsection without corresponding .pushsection; ignored"
+msgstr ""
+
+#: config/obj-elf.c:1270
+msgid "expected comma after name in .symver"
+msgstr ""
+
+#: config/obj-elf.c:1294
+#, c-format
+msgid "missing version name in `%s' for symbol `%s'"
+msgstr ""
+
+#: config/obj-elf.c:1305
+#, c-format
+msgid "multiple versions [`%s'|`%s'] for symbol `%s'"
+msgstr ""
+
+#: config/obj-elf.c:1541
+msgid "expected quoted string"
+msgstr ""
+
+#: config/obj-elf.c:1562
+#, c-format
+msgid "expected comma after name `%s' in .size directive"
+msgstr ""
+
+#: config/obj-elf.c:1571
+msgid "missing expression in .size directive"
+msgstr ""
+
+#: config/obj-elf.c:1660
+#, c-format
+msgid "unrecognized symbol type \"%s\""
+msgstr ""
+
+#: config/obj-elf.c:1841
+msgid ".size expression too complicated to fix up"
+msgstr ""
+
+#: config/obj-elf.c:1873
+#, c-format
+msgid ""
+"invalid attempt to declare external version name as default in symbol `%s'"
+msgstr ""
+
+#: config/obj-elf.c:1934 ecoff.c:3642
+#, c-format
+msgid "symbol `%s' can not be both weak and common"
+msgstr ""
+
+#: config/obj-elf.c:2054
+#, c-format
+msgid "assuming all members of group `%s' are COMDAT"
+msgstr ""
+
+#: config/obj-elf.c:2076
+#, c-format
+msgid "can't create group: %s"
+msgstr ""
+
+#: config/obj-elf.c:2183
+#, c-format
+msgid "failed to set up debugging information: %s"
+msgstr ""
+
+#: config/obj-elf.c:2203
+#, c-format
+msgid "can't start writing .mdebug section: %s"
+msgstr ""
+
+#: config/obj-elf.c:2211
+#, c-format
+msgid "could not write .mdebug section: %s"
+msgstr ""
+
+#: config/obj-ieee.c:455
+msgid "too many sections"
+msgstr ""
+
+#: config/obj-som.c:138
+msgid "Only one .version pseudo-op per file!"
+msgstr ""
+
+#: config/obj-som.c:155 config/obj-som.c:201
+msgid "Expected quoted string"
+msgstr ""
+
+#: config/obj-som.c:164
+#, c-format
+msgid "FATAL: Attaching version header %s"
+msgstr ""
+
+#: config/obj-som.c:184
+msgid "Only one .copyright pseudo-op per file!"
+msgstr ""
+
+#: config/obj-som.c:210
+#, c-format
+msgid "FATAL: Attaching copyright header %s"
+msgstr ""
+
+#: config/obj-vms.c:530
+#, c-format
+msgid "compiler emitted zero-size common symbol `%s' already defined"
+msgstr ""
+
+#: config/obj-vms.c:540
+#, c-format
+msgid "compiler redefined zero-size common symbol `%s'"
+msgstr ""
+
+#: config/obj-vms.c:663
+#, c-format
+msgid "Couldn't create VMS object file \"%s\""
+msgstr ""
+
+#: config/obj-vms.c:688
+msgid "I/O error writing VMS object file (length prefix)"
+msgstr ""
+
+#: config/obj-vms.c:702
+msgid "I/O error writing VMS object file"
+msgstr ""
+
+#: config/obj-vms.c:1292
+#, c-format
+msgid "Couldn't find source file \"%s\", status=%%X%x"
+msgstr ""
+
+#: config/obj-vms.c:1790 config/obj-vms.c:2967
+#, c-format
+msgid "debugger forward reference error, dbx type %d"
+msgstr ""
+
+#: config/obj-vms.c:1865
+#, c-format
+msgid "Variable descriptor %d too complicated. Defined as `void *'."
+msgstr ""
+
+#: config/obj-vms.c:2179
+msgid ""
+"***Warning - the assembly code generated by the compiler has placed \n"
+" global constant(s) in the text psect. These will not be available to \n"
+" other modules, since this is not the correct way to handle this. You \n"
+" have two options: 1) get a patched compiler that does not put global \n"
+" constants in the text psect, or 2) remove the 'const' keyword from \n"
+" definitions of global variables in your source module(s). Don't say \n"
+" I didn't warn you! \n"
+msgstr ""
+
+#: config/obj-vms.c:2494
+#, c-format
+msgid "debugginer output: %d is an unknown untyped variable."
+msgstr ""
+
+#: config/obj-vms.c:2712
+#, c-format
+msgid "debugger output: structure element `%s' has undefined type"
+msgstr ""
+
+#: config/obj-vms.c:2823
+#, c-format
+msgid "debugger output: %d is an unknown type of variable."
+msgstr ""
+
+#: config/obj-vms.c:2956
+#, c-format
+msgid "debugger output: Unable to resolve %d circular references."
+msgstr ""
+
+#: config/obj-vms.c:3158
+#, c-format
+msgid "Module name truncated: %s\n"
+msgstr ""
+
+#: config/obj-vms.c:3436
+#, c-format
+msgid "Symbol %s replaced by %s\n"
+msgstr ""
+
+#. impossible
+#: config/obj-vms.c:3719
+#, c-format
+msgid "Unknown VMS psect type (%ld)"
+msgstr ""
+
+#: config/obj-vms.c:3760
+#, c-format
+msgid "Globalsymbol attribute for symbol %s was unexpected."
+msgstr ""
+
+#: config/obj-vms.c:3909
+msgid "Invalid data type for globalvalue"
+msgstr ""
+
+#: config/obj-vms.c:3921
+#, c-format
+msgid "Invalid globalvalue of %s"
+msgstr ""
+
+#: config/obj-vms.c:4271
+msgid "Couldn't find fixup fragment when checking for indirect reference"
+msgstr ""
+
+#: config/obj-vms.c:4614 config/obj-vms.c:4757
+msgid "Fixup data addsy and subsy don't have the same type"
+msgstr ""
+
+#: config/obj-vms.c:4618 config/obj-vms.c:4761
+msgid "Fixup data addsy and subsy don't have an appropriate type"
+msgstr ""
+
+#: config/obj-vms.c:4621 config/obj-vms.c:4764
+msgid "Fixup data is erroneously \"pcrel\""
+msgstr ""
+
+#: config/obj-vms.c:4637 config/obj-vms.c:4783
+msgid "Fixup datum is not a longword"
+msgstr ""
+
+#: config/obj-vms.c:4641 config/obj-vms.c:4787
+msgid "Fixup datum is not \"fixP->fx_addsy\""
+msgstr ""
+
+#: config/obj-vms.c:4858
+#, c-format
+msgid ""
+"g++ wrote an extern reference to `%s' as a routine.\n"
+"I will fix it, but I hope that it was note really a routine."
+msgstr ""
+
+#: config/obj-vms.c:4990
+msgid "Can't handle global xtors symbols yet."
+msgstr ""
+
+#: config/obj-vms.c:4993
+#, c-format
+msgid "Unknown %s"
+msgstr ""
+
+#.
+#. * Error otherwise.
+#.
+#: config/obj-vms.c:5078
+#, c-format
+msgid "unhandled stab type %d"
+msgstr ""
+
+#: config/tc-a29k.c:163 config/tc-sparc.c:3983
+msgid "Unknown segment type"
+msgstr ""
+
+#. Probably a memory allocation problem? Give up now.
+#: config/tc-a29k.c:333 config/tc-dlx.c:369 config/tc-hppa.c:1463
+#: config/tc-mips.c:1108 config/tc-mips.c:1150 config/tc-or32.c:228
+#: config/tc-sparc.c:853
+msgid "Broken assembler. No assembly attempted."
+msgstr ""
+
+#: config/tc-a29k.c:378 config/tc-avr.c:1121 config/tc-d10v.c:545
+#: config/tc-d30v.c:551 config/tc-h8300.c:492 config/tc-h8500.c:283
+#: config/tc-mcore.c:607 config/tc-mmix.c:470 config/tc-mn10200.c:940
+#: config/tc-mn10300.c:1815 config/tc-msp430.c:1544 config/tc-or32.c:334
+#: config/tc-or32.c:390 config/tc-ppc.c:2334 config/tc-s390.c:1236
+#: config/tc-sh.c:1264 config/tc-sh64.c:2254 config/tc-tic80.c:279
+#: config/tc-v850.c:2024 config/tc-w65.c:218 config/tc-z8k.c:376
+msgid "missing operand"
+msgstr ""
+
+#: config/tc-a29k.c:417 config/tc-cris.c:1075 config/tc-cris.c:1083
+#: config/tc-dlx.c:834 config/tc-hppa.c:1599 config/tc-i860.c:453
+#: config/tc-i860.c:470 config/tc-i860.c:930 config/tc-sparc.c:1415
+#: config/tc-sparc.c:1421
+#, c-format
+msgid "Unknown opcode: `%s'"
+msgstr ""
+
+#: config/tc-a29k.c:422 config/tc-dlx.c:852
+#, c-format
+msgid "Unknown opcode `%s'."
+msgstr ""
+
+#: config/tc-a29k.c:454 config/tc-dlx.c:913
+#, c-format
+msgid "Too many operands: %s"
+msgstr ""
+
+#: config/tc-a29k.c:476 config/tc-a29k.c:507
+#, c-format
+msgid "Immediate value of %ld is too large"
+msgstr ""
+
+#: config/tc-a29k.c:546 config/tc-i860.c:355 config/tc-i860.c:902
+#: config/tc-m68k.c:3171 config/tc-m68k.c:3200 config/tc-sparc.c:2647
+msgid "failed sanity check."
+msgstr ""
+
+#: config/tc-a29k.c:892 config/tc-or32.c:1044 config/tc-or32.c:1178
+#, c-format
+msgid "bad relocation type: 0x%02x"
+msgstr ""
+
+#: config/tc-a29k.c:919
+#, c-format
+msgid "need %o3\n"
+msgstr ""
+
+#: config/tc-a29k.c:935
+msgid "a29k_convert_frag\n"
+msgstr ""
+
+#: config/tc-a29k.c:944
+msgid "a29k_estimate_size_before_relax\n"
+msgstr ""
+
+#: config/tc-a29k.c:1095 config/tc-dlx.c:1283 config/tc-or32.c:1373
+#, c-format
+msgid "label \"$%d\" redefined"
+msgstr ""
+
+#: config/tc-a29k.c:1168 config/tc-dlx.c:511 config/tc-or32.c:1466
+#, c-format
+msgid "Invalid expression after %%%%\n"
+msgstr ""
+
+#: config/tc-a29k.c:1179
+msgid "Invalid register in & expression"
+msgstr ""
+
+#: config/tc-alpha.c:826
+#, c-format
+msgid "internal error: can't hash opcode `%s': %s"
+msgstr ""
+
+#: config/tc-alpha.c:860
+#, c-format
+msgid "internal error: can't hash macro `%s': %s"
+msgstr ""
+
+#: config/tc-alpha.c:943 config/tc-i960.c:2707 config/tc-xtensa.c:4954
+#: config/tc-xtensa.c:5015
+msgid "syntax error"
+msgstr ""
+
+#: config/tc-alpha.c:1017 config/tc-h8300.c:2099 config/tc-h8500.c:1204
+#: config/tc-hppa.c:4018 config/tc-i860.c:1004 config/tc-m68hc11.c:568
+#: config/tc-m68k.c:4196 config/tc-m88k.c:991 config/tc-ns32k.c:1689
+#: config/tc-or32.c:910 config/tc-sparc.c:2934 config/tc-z8k.c:1371
+msgid "Bad call to MD_ATOF()"
+msgstr ""
+
+#: config/tc-alpha.c:1067
+#, c-format
+msgid "Unknown CPU identifier `%s'"
+msgstr ""
+
+#: config/tc-alpha.c:1111
+msgid ""
+"Alpha options:\n"
+"-32addr\t\t\ttreat addresses as 32-bit values\n"
+"-F\t\t\tlack floating point instructions support\n"
+"-mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n"
+"\t\t\tspecify variant of Alpha architecture\n"
+"-m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -"
+"m21264b\n"
+"\t\t\tthese variants include PALcode opcodes\n"
+msgstr ""
+
+#: config/tc-alpha.c:1121
+msgid ""
+"VMS options:\n"
+"-+\t\t\thash encode (don't truncate) names longer than 64 characters\n"
+"-H\t\t\tshow new symbol after hash truncation\n"
+msgstr ""
+
+#: config/tc-alpha.c:1298
+#, c-format
+msgid "unhandled relocation type %s"
+msgstr ""
+
+#: config/tc-alpha.c:1311
+msgid "non-absolute expression in constant field"
+msgstr ""
+
+#: config/tc-alpha.c:1325
+#, c-format
+msgid "type %d reloc done?\n"
+msgstr ""
+
+#: config/tc-alpha.c:1373 config/tc-alpha.c:1380 config/tc-mips.c:8603
+msgid "Used $at without \".set noat\""
+msgstr ""
+
+#: config/tc-alpha.c:1542
+#, c-format
+msgid "!samegp reloc against symbol without .prologue: %s"
+msgstr ""
+
+#: config/tc-alpha.c:1581 config/tc-xtensa.c:5451
+#, c-format
+msgid "cannot represent `%s' relocation in object file"
+msgstr ""
+
+#: config/tc-alpha.c:1588 config/tc-xtensa.c:5458
+#, c-format
+msgid "internal error? cannot generate `%s' relocation"
+msgstr ""
+
+#: config/tc-alpha.c:1642
+#, c-format
+msgid "frame reg expected, using $%d."
+msgstr ""
+
+#: config/tc-alpha.c:1743
+#, c-format
+msgid "No !literal!%ld was found"
+msgstr ""
+
+#: config/tc-alpha.c:1750
+#, c-format
+msgid "No !tlsgd!%ld was found"
+msgstr ""
+
+#: config/tc-alpha.c:1757
+#, c-format
+msgid "No !tlsldm!%ld was found"
+msgstr ""
+
+#: config/tc-alpha.c:1766
+#, c-format
+msgid "No ldah !gpdisp!%ld was found"
+msgstr ""
+
+#: config/tc-alpha.c:1816
+#, c-format
+msgid "too many !literal!%ld for %s"
+msgstr ""
+
+#: config/tc-alpha.c:1846
+#, c-format
+msgid "No lda !gpdisp!%ld was found"
+msgstr ""
+
+#. Only support one relocation op per insn.
+#: config/tc-alpha.c:1994
+msgid "More than one relocation op per insn"
+msgstr ""
+
+#: config/tc-alpha.c:2010
+msgid "No relocation operand"
+msgstr ""
+
+#: config/tc-alpha.c:2020
+#, c-format
+msgid "Unknown relocation operand: !%s"
+msgstr ""
+
+#: config/tc-alpha.c:2030
+#, c-format
+msgid "no sequence number after !%s"
+msgstr ""
+
+#: config/tc-alpha.c:2040
+#, c-format
+msgid "!%s does not use a sequence number"
+msgstr ""
+
+#: config/tc-alpha.c:2050
+#, c-format
+msgid "Bad sequence number: !%s!%s"
+msgstr ""
+
+#: config/tc-alpha.c:2378
+#, c-format
+msgid "operand out of range (%s not between %d and %d)"
+msgstr ""
+
+#: config/tc-alpha.c:2490 config/tc-alpha.c:2514 config/tc-d10v.c:634
+#: config/tc-d30v.c:639 config/tc-mn10200.c:995 config/tc-mn10300.c:1888
+#: config/tc-ppc.c:2300 config/tc-ppc.c:2517 config/tc-ppc.c:2529
+#: config/tc-s390.c:1246 config/tc-s390.c:1346 config/tc-s390.c:1442
+#: config/tc-v850.c:1804 config/tc-v850.c:1827 config/tc-v850.c:2047
+msgid "too many fixups"
+msgstr ""
+
+#: config/tc-alpha.c:2526
+msgid "invalid relocation for instruction"
+msgstr ""
+
+#: config/tc-alpha.c:2537
+msgid "invalid relocation for field"
+msgstr ""
+
+#: config/tc-alpha.c:2642
+#, c-format
+msgid "too many ldah insns for !gpdisp!%ld"
+msgstr ""
+
+#: config/tc-alpha.c:2644 config/tc-alpha.c:2656
+#, c-format
+msgid "both insns for !gpdisp!%ld must be in the same section"
+msgstr ""
+
+#: config/tc-alpha.c:2654
+#, c-format
+msgid "too many lda insns for !gpdisp!%ld"
+msgstr ""
+
+#: config/tc-alpha.c:2707
+#, c-format
+msgid "too many lituse insns for !lituse_tlsgd!%ld"
+msgstr ""
+
+#: config/tc-alpha.c:2710
+#, c-format
+msgid "too many lituse insns for !lituse_tlsldm!%ld"
+msgstr ""
+
+#: config/tc-alpha.c:2727
+#, c-format
+msgid "duplicate !tlsgd!%ld"
+msgstr ""
+
+#: config/tc-alpha.c:2729
+#, c-format
+msgid "sequence number in use for !tlsldm!%ld"
+msgstr ""
+
+#: config/tc-alpha.c:2743
+#, c-format
+msgid "duplicate !tlsldm!%ld"
+msgstr ""
+
+#: config/tc-alpha.c:2745
+#, c-format
+msgid "sequence number in use for !tlsgd!%ld"
+msgstr ""
+
+#: config/tc-alpha.c:2790 config/tc-alpha.c:2863
+#, c-format
+msgid "inappropriate arguments for opcode `%s'"
+msgstr ""
+
+#: config/tc-alpha.c:2792 config/tc-alpha.c:2865
+#, c-format
+msgid "opcode `%s' not supported for target %s"
+msgstr ""
+
+#: config/tc-alpha.c:2796 config/tc-alpha.c:2869 config/tc-avr.c:1087
+#: config/tc-msp430.c:446
+#, c-format
+msgid "unknown opcode `%s'"
+msgstr ""
+
+#: config/tc-alpha.c:2916
+msgid "can not resolve expression"
+msgstr ""
+
+#: config/tc-alpha.c:3060 config/tc-alpha.c:3239
+msgid "overflow in literal (.lita) table"
+msgstr ""
+
+#: config/tc-alpha.c:3067 config/tc-alpha.c:3090 config/tc-alpha.c:3252
+#: config/tc-alpha.c:3467 config/tc-alpha.c:3512 config/tc-alpha.c:3586
+#: config/tc-alpha.c:3678 config/tc-alpha.c:3926 config/tc-alpha.c:4025
+msgid "macro requires $at register while noat in effect"
+msgstr ""
+
+#: config/tc-alpha.c:3069 config/tc-alpha.c:3092 config/tc-alpha.c:3254
+msgid "macro requires $at while $at in use"
+msgstr ""
+
+#: config/tc-alpha.c:3200
+msgid "bignum invalid; zero assumed"
+msgstr ""
+
+#: config/tc-alpha.c:3202
+msgid "floating point number invalid; zero assumed"
+msgstr ""
+
+#: config/tc-alpha.c:3207
+msgid "can't handle expression"
+msgstr ""
+
+#: config/tc-alpha.c:3245
+msgid "overflow in literal (.lit8) table"
+msgstr ""
+
+#: config/tc-alpha.c:4262 config/tc-ppc.c:1740 config/tc-ppc.c:4271
+#, c-format
+msgid ".COMMon length (%ld.) <0! Ignored."
+msgstr ""
+
+#: config/tc-alpha.c:4291 config/tc-sparc.c:3799 config/tc-v850.c:256
+msgid "Ignoring attempt to re-define symbol"
+msgstr ""
+
+#: config/tc-alpha.c:4300 config/tc-alpha.c:4309 config/tc-ppc.c:4308
+#, c-format
+msgid "Length of .comm \"%s\" is already %ld. Not changed to %ld."
+msgstr ""
+
+#: config/tc-alpha.c:4430 ecoff.c:3082
+msgid ".ent directive has no name"
+msgstr ""
+
+#: config/tc-alpha.c:4438
+msgid "nested .ent directives"
+msgstr ""
+
+#: config/tc-alpha.c:4483 ecoff.c:3032
+msgid ".end directive has no name"
+msgstr ""
+
+#: config/tc-alpha.c:4492
+msgid ".end directive without matching .ent"
+msgstr ""
+
+#: config/tc-alpha.c:4494
+msgid ".end directive names different symbol than .ent"
+msgstr ""
+
+#: config/tc-alpha.c:4538 ecoff.c:3171
+msgid ".fmask outside of .ent"
+msgstr ""
+
+#: config/tc-alpha.c:4540 ecoff.c:3241
+msgid ".mask outside of .ent"
+msgstr ""
+
+#: config/tc-alpha.c:4548 ecoff.c:3178
+msgid "bad .fmask directive"
+msgstr ""
+
+#: config/tc-alpha.c:4550 ecoff.c:3248
+msgid "bad .mask directive"
+msgstr ""
+
+#: config/tc-alpha.c:4584 config/tc-mips.c:14143 ecoff.c:3200
+msgid ".frame outside of .ent"
+msgstr ""
+
+#: config/tc-alpha.c:4595 ecoff.c:3211
+msgid "bad .frame directive"
+msgstr ""
+
+#: config/tc-alpha.c:4628
+msgid ".prologue directive without a preceding .ent directive"
+msgstr ""
+
+#: config/tc-alpha.c:4646
+#, c-format
+msgid "Invalid argument %d to .prologue."
+msgstr ""
+
+#: config/tc-alpha.c:4741
+msgid "ECOFF debugging is disabled."
+msgstr ""
+
+#: config/tc-alpha.c:4755
+msgid ".ent directive without matching .end"
+msgstr ""
+
+#: config/tc-alpha.c:4840
+msgid ".usepv directive has no name"
+msgstr ""
+
+#: config/tc-alpha.c:4851
+msgid ".usepv directive has no type"
+msgstr ""
+
+#: config/tc-alpha.c:4866
+msgid "unknown argument for .usepv"
+msgstr ""
+
+#: config/tc-alpha.c:4900
+msgid "Unknown section directive"
+msgstr ""
+
+#: config/tc-alpha.c:4936
+msgid ".ent directive has no symbol"
+msgstr ""
+
+#: config/tc-alpha.c:4963
+msgid "Bad .frame directive 1./2. param"
+msgstr ""
+
+#: config/tc-alpha.c:4975
+msgid "Bad .frame directive 3./4. param"
+msgstr ""
+
+#: config/tc-alpha.c:5000
+msgid ".pdesc directive not in link (.link) section"
+msgstr ""
+
+#: config/tc-alpha.c:5008
+msgid ".pdesc has no matching .ent"
+msgstr ""
+
+#: config/tc-alpha.c:5019
+msgid ".pdesc directive has no entry symbol"
+msgstr ""
+
+#: config/tc-alpha.c:5032
+msgid "No comma after .pdesc <entryname>"
+msgstr ""
+
+#: config/tc-alpha.c:5055
+msgid "unknown procedure kind"
+msgstr ""
+
+#: config/tc-alpha.c:5148
+msgid ".name directive not in link (.link) section"
+msgstr ""
+
+#: config/tc-alpha.c:5156
+msgid ".name directive has no symbol"
+msgstr ""
+
+#: config/tc-alpha.c:5190
+msgid "No symbol after .linkage"
+msgstr ""
+
+#: config/tc-alpha.c:5218
+msgid "No symbol after .code_address"
+msgstr ""
+
+#: config/tc-alpha.c:5251
+msgid "Bad .mask directive"
+msgstr ""
+
+#: config/tc-alpha.c:5272
+msgid "Bad .fmask directive"
+msgstr ""
+
+#: config/tc-alpha.c:5440
+#, c-format
+msgid "Expected comma after name \"%s\""
+msgstr ""
+
+#. *symbol_get_obj (symbolP) = (signed char) temp;
+#: config/tc-alpha.c:5451
+#, c-format
+msgid "unhandled: .proc %s,%d"
+msgstr ""
+
+#: config/tc-alpha.c:5486
+#, c-format
+msgid "Tried to .set unrecognized mode `%s'"
+msgstr ""
+
+#. not fatal, but it might not work in the end
+#: config/tc-alpha.c:5503
+msgid "File overrides no-base-register option."
+msgstr ""
+
+#: config/tc-alpha.c:5520
+#, c-format
+msgid "Bad base register, using $%d."
+msgstr ""
+
+#: config/tc-alpha.c:5542
+#, c-format
+msgid "Alignment too large: %d. assumed"
+msgstr ""
+
+#: config/tc-alpha.c:5546 config/tc-d30v.c:2200
+msgid "Alignment negative: 0 assumed"
+msgstr ""
+
+#: config/tc-alpha.c:5860
+#, c-format
+msgid "Chose GP value of %lx\n"
+msgstr ""
+
+#: config/tc-alpha.c:5876
+msgid "Bad .section directive: want a,s,w,x,M,S,G,T in string"
+msgstr ""
+
+#: config/tc-arc.c:1615 config/tc-arm.c:11416 config/tc-ip2k.c:219
+msgid "md_estimate_size_before_relax\n"
+msgstr ""
+
+#: config/tc-arc.c:1627
+msgid "md_convert_frag\n"
+msgstr ""
+
+#. We can't actually support subtracting a symbol.
+#: config/tc-arc.c:1898 config/tc-arm.c:6617 config/tc-arm.c:9705
+#: config/tc-arm.c:9805 config/tc-avr.c:854 config/tc-cris.c:3123
+#: config/tc-d10v.c:1710 config/tc-d30v.c:1851 config/tc-mips.c:3630
+#: config/tc-mips.c:4695 config/tc-mips.c:5828 config/tc-mips.c:6517
+#: config/tc-msp430.c:1403 config/tc-ppc.c:5460 config/tc-v850.c:2356
+#: config/tc-xstormy16.c:483
+msgid "expression too complex"
+msgstr ""
+
+#: config/tc-arm.c:763
+msgid "ARM register expected"
+msgstr ""
+
+#: config/tc-arm.c:764 config/tc-arm.c:3174
+msgid "bad or missing co-processor number"
+msgstr ""
+
+#. In the few cases where we might be able to accept something else
+#. this error can be overridden.
+#: config/tc-arm.c:765 config/tc-arm.c:3229
+msgid "co-processor register expected"
+msgstr ""
+
+#: config/tc-arm.c:766
+msgid "FPA register expected"
+msgstr ""
+
+#: config/tc-arm.c:767
+msgid "VFP single precision register expected"
+msgstr ""
+
+#: config/tc-arm.c:768
+msgid "VFP double precision register expected"
+msgstr ""
+
+#: config/tc-arm.c:769
+msgid "Maverick MVF register expected"
+msgstr ""
+
+#: config/tc-arm.c:770
+msgid "Maverick MVD register expected"
+msgstr ""
+
+#: config/tc-arm.c:771 config/tc-arm.c:772
+msgid "Maverick MVFX register expected"
+msgstr ""
+
+#: config/tc-arm.c:773
+msgid "Maverick MVAX register expected"
+msgstr ""
+
+#: config/tc-arm.c:774
+msgid "Maverick DSPSC register expected"
+msgstr ""
+
+#: config/tc-arm.c:775
+msgid "Intel Wireless MMX technology register expected"
+msgstr ""
+
+#: config/tc-arm.c:2309
+msgid "bad arguments to instruction"
+msgstr ""
+
+#: config/tc-arm.c:2310
+msgid "r15 not allowed here"
+msgstr ""
+
+#: config/tc-arm.c:2311
+msgid "instruction is not conditional"
+msgstr ""
+
+#: config/tc-arm.c:2312
+msgid "acc0 expected"
+msgstr ""
+
+#: config/tc-arm.c:2505
+msgid "literal pool overflow"
+msgstr ""
+
+#: config/tc-arm.c:2647
+msgid "invalid syntax for .req directive"
+msgstr ""
+
+#: config/tc-arm.c:2727
+#, c-format
+msgid "alignment too large: %d assumed"
+msgstr ""
+
+#: config/tc-arm.c:2730
+msgid "alignment negative. 0 assumed."
+msgstr ""
+
+#: config/tc-arm.c:2814
+#, c-format
+msgid "expected comma after name \"%s\""
+msgstr ""
+
+#: config/tc-arm.c:2864 config/tc-m32r.c:420
+#, c-format
+msgid "symbol `%s' already defined"
+msgstr ""
+
+#: config/tc-arm.c:2889
+msgid "selected processor does not support THUMB opcodes"
+msgstr ""
+
+#: config/tc-arm.c:2902
+msgid "selected processor does not support ARM opcodes"
+msgstr ""
+
+#: config/tc-arm.c:2914
+#, c-format
+msgid "invalid instruction size selected (%d)"
+msgstr ""
+
+#: config/tc-arm.c:2949
+#, c-format
+msgid "invalid operand to .code directive (%d) (expecting 16 or 32)"
+msgstr ""
+
+#: config/tc-arm.c:2960
+msgid "garbage following instruction"
+msgstr ""
+
+#. In the few cases where we might be able to accept something else
+#. this error can be overridden.
+#: config/tc-arm.c:3010
+#, c-format
+msgid "register expected, not '%.100s'"
+msgstr ""
+
+#. In the few cases where we might be able to accept
+#. something else this error can be overridden.
+#: config/tc-arm.c:3061
+#, c-format
+msgid "Intel Wireless MMX technology register expected, not '%.100s'"
+msgstr ""
+
+#. In the few cases where we might be able to accept
+#. something else this error can be overridden.
+#: config/tc-arm.c:3133
+msgid "flag for {c}psr instruction expected"
+msgstr ""
+
+#: config/tc-arm.c:3167
+msgid "illegal co-processor number"
+msgstr ""
+
+#: config/tc-arm.c:3199 config/tc-arm.c:4778
+msgid "bad or missing expression"
+msgstr ""
+
+#: config/tc-arm.c:3205
+msgid "immediate co-processor expression too large"
+msgstr ""
+
+#. In the few cases where we might be able to accept something else
+#. this error can be overridden.
+#: config/tc-arm.c:3252
+msgid "floating point register expected"
+msgstr ""
+
+#: config/tc-arm.c:3269 config/tc-arm.c:3414
+msgid "immediate expression expected"
+msgstr ""
+
+#: config/tc-arm.c:3284
+msgid "co-processor address must be word aligned"
+msgstr ""
+
+#: config/tc-arm.c:3290 config/tc-arm.c:3429
+msgid "offset too large"
+msgstr ""
+
+#: config/tc-arm.c:3339 config/tc-arm.c:3477
+msgid "pc may not be used in post-increment"
+msgstr ""
+
+#: config/tc-arm.c:3355 config/tc-arm.c:3493 config/tc-arm.c:3938
+#: config/tc-arm.c:5197 config/tc-arm.c:6064 config/tc-arm.c:6398
+msgid "pre-indexed expression expected"
+msgstr ""
+
+#: config/tc-arm.c:3368 config/tc-arm.c:3506 config/tc-arm.c:3951
+#: config/tc-arm.c:5208 config/tc-arm.c:6076 config/tc-arm.c:6410
+#: config/tc-arm.c:6784 config/tc-arm.c:9448 config/tc-arm.c:9463
+msgid "missing ]"
+msgstr ""
+
+#: config/tc-arm.c:3378 config/tc-arm.c:3516
+msgid "pc may not be used with write-back"
+msgstr ""
+
+#: config/tc-arm.c:3568
+msgid "comma expected after register name"
+msgstr ""
+
+#: config/tc-arm.c:3587
+msgid "CPSR or SPSR expected"
+msgstr ""
+
+#: config/tc-arm.c:3613
+msgid "comma missing after psr flags"
+msgstr ""
+
+#: config/tc-arm.c:3629 config/tc-arm.c:3639
+msgid "only a register or immediate value can follow a psr flag"
+msgstr ""
+
+#: config/tc-arm.c:3650
+msgid "immediate value cannot be used to set this field"
+msgstr ""
+
+#: config/tc-arm.c:3668 config/tc-arm.c:5424 config/tc-arm.c:5704
+#: config/tc-arm.c:5724 config/tc-i960.c:1935
+msgid "invalid constant"
+msgstr ""
+
+#: config/tc-arm.c:3716
+msgid "rdhi, rdlo and rm must all be different"
+msgstr ""
+
+#: config/tc-arm.c:3770
+msgid "rd and rm should be different in mul"
+msgstr ""
+
+#: config/tc-arm.c:3824
+msgid "rd and rm should be different in mla"
+msgstr ""
+
+#: config/tc-arm.c:3872
+#, c-format
+msgid "acc0 expected, not '%.100s'"
+msgstr ""
+
+#: config/tc-arm.c:4050
+msgid "rdhi and rdlo must be different"
+msgstr ""
+
+#: config/tc-arm.c:4158
+msgid "Warning: instruction unpredictable when using r15"
+msgstr ""
+
+#: config/tc-arm.c:4373
+msgid "use of r15 in bxj is not really useful"
+msgstr ""
+
+#: config/tc-arm.c:4400 config/tc-arm.c:4585 config/tc-arm.c:5445 expr.c:1318
+#: read.c:2206
+msgid "bad expression"
+msgstr ""
+
+#: config/tc-arm.c:4409 config/tc-arm.c:4594 config/tc-arm.c:4786
+#: config/tc-arm.c:8389 config/tc-arm.c:8424 config/tc-arm.c:8434
+#: config/tc-z8k.c:1161 config/tc-z8k.c:1173
+msgid "immediate value out of range"
+msgstr ""
+
+#: config/tc-arm.c:4833
+msgid "only r15 allowed here"
+msgstr ""
+
+#: config/tc-arm.c:5160
+msgid "'[' expected after PLD mnemonic"
+msgstr ""
+
+#: config/tc-arm.c:5182
+msgid "post-indexed expression used in preload instruction"
+msgstr ""
+
+#: config/tc-arm.c:5187 config/tc-arm.c:5217
+msgid "writeback used in preload instruction"
+msgstr ""
+
+#: config/tc-arm.c:5259
+msgid "destination register must be even"
+msgstr ""
+
+#: config/tc-arm.c:5265
+msgid "r14 not allowed here"
+msgstr ""
+
+#: config/tc-arm.c:5272
+msgid "pre/post-indexing used when modified address register is destination"
+msgstr ""
+
+#: config/tc-arm.c:5282
+msgid "ldrd destination registers must not overlap index register"
+msgstr ""
+
+#: config/tc-arm.c:5408
+msgid "bad_segment"
+msgstr ""
+
+#: config/tc-arm.c:5468 config/tc-arm.c:5479
+msgid "shift expression expected"
+msgstr ""
+
+#: config/tc-arm.c:5503
+msgid "shift requires register or #expression"
+msgstr ""
+
+#: config/tc-arm.c:5504
+msgid "shift requires #expression"
+msgstr ""
+
+#: config/tc-arm.c:5534
+msgid "shift of 0 ignored."
+msgstr ""
+
+#: config/tc-arm.c:5540
+msgid "invalid immediate shift"
+msgstr ""
+
+#: config/tc-arm.c:5695 config/tc-arm.c:6112 config/tc-arm.c:6447
+#: config/tc-arm.c:7081 config/tc-v850.c:1907 config/tc-v850.c:1928
+msgid "constant expression expected"
+msgstr ""
+
+#: config/tc-arm.c:5737
+msgid "register or shift expression expected"
+msgstr ""
+
+#: config/tc-arm.c:5790
+msgid "invalid floating point immediate expression"
+msgstr ""
+
+#: config/tc-arm.c:5794
+msgid "floating point register or immediate expression expected"
+msgstr ""
+
+#: config/tc-arm.c:5948 config/tc-arm.c:6278
+msgid "address offset too large"
+msgstr ""
+
+#: config/tc-arm.c:6006 config/tc-arm.c:6196 config/tc-arm.c:6338
+msgid "address expected"
+msgstr ""
+
+#: config/tc-arm.c:6036 config/tc-arm.c:6048 config/tc-arm.c:6085
+#: config/tc-arm.c:6214 config/tc-arm.c:6368 config/tc-arm.c:6382
+#: config/tc-arm.c:6419
+#, c-format
+msgid "%s register same as write-back base"
+msgstr ""
+
+#: config/tc-arm.c:6038 config/tc-arm.c:6050 config/tc-arm.c:6087
+#: config/tc-arm.c:6216 config/tc-arm.c:6370 config/tc-arm.c:6384
+#: config/tc-arm.c:6421
+msgid "destination"
+msgstr ""
+
+#: config/tc-arm.c:6038 config/tc-arm.c:6050 config/tc-arm.c:6087
+#: config/tc-arm.c:6216 config/tc-arm.c:6370 config/tc-arm.c:6384
+#: config/tc-arm.c:6421
+msgid "source"
+msgstr ""
+
+#: config/tc-arm.c:6097 config/tc-arm.c:6431 config/tc-arm.c:8695
+msgid "invalid pseudo operation"
+msgstr ""
+
+#: config/tc-arm.c:6149 config/tc-arm.c:6482
+msgid "literal pool insertion failed"
+msgstr ""
+
+#: config/tc-arm.c:6244 config/tc-arm.c:6250
+msgid "post-indexed expression expected"
+msgstr ""
+
+#: config/tc-arm.c:6548
+msgid "bad range in register list"
+msgstr ""
+
+#: config/tc-arm.c:6556 config/tc-arm.c:6565 config/tc-arm.c:6607
+#, c-format
+msgid "Warning: duplicated register (r%d) in register list"
+msgstr ""
+
+#: config/tc-arm.c:6568
+msgid "Warning: register range not in ascending order"
+msgstr ""
+
+#: config/tc-arm.c:6580
+msgid "missing `}'"
+msgstr ""
+
+#: config/tc-arm.c:6596
+msgid "invalid register mask"
+msgstr ""
+
+#: config/tc-arm.c:6655
+msgid "r15 not allowed as base register"
+msgstr ""
+
+#: config/tc-arm.c:6689 config/tc-arm.c:6698
+msgid "writeback of base register is UNPREDICTABLE"
+msgstr ""
+
+#: config/tc-arm.c:6692
+msgid "writeback of base register when in register list is UNPREDICTABLE"
+msgstr ""
+
+#: config/tc-arm.c:6702
+msgid "if writeback register is in list, it must be the lowest reg in the list"
+msgstr ""
+
+#: config/tc-arm.c:6744 config/tc-arm.c:6758
+msgid "r15 not allowed in swap"
+msgstr ""
+
+#: config/tc-arm.c:6853
+msgid "use of r15 in bx in ARM mode is not really useful"
+msgstr ""
+
+#: config/tc-arm.c:7087
+msgid "constant value required for number of registers"
+msgstr ""
+
+#: config/tc-arm.c:7095
+msgid "number of registers must be in the range [1:4]"
+msgstr ""
+
+#: config/tc-arm.c:7156
+msgid "r15 not allowed as base register with write-back"
+msgstr ""
+
+#: config/tc-arm.c:7538
+msgid "only two consecutive VFP SP registers allowed here"
+msgstr ""
+
+#: config/tc-arm.c:7706
+msgid "VFP system register expected"
+msgstr ""
+
+#: config/tc-arm.c:7844 config/tc-arm.c:7883 config/tc-arm.c:7896
+#: config/tc-arm.c:7957 config/tc-arm.c:7996 config/tc-arm.c:8009
+#: config/tc-h8300.c:1035 config/tc-mips.c:9723 config/tc-mips.c:9753
+msgid "invalid register list"
+msgstr ""
+
+#: config/tc-arm.c:7850 config/tc-arm.c:7963
+msgid "register list not in ascending order"
+msgstr ""
+
+#: config/tc-arm.c:7875 config/tc-arm.c:7988
+msgid "register range not in ascending order"
+msgstr ""
+
+#: config/tc-arm.c:7913 config/tc-arm.c:8026
+msgid "non-contiguous register range"
+msgstr ""
+
+#: config/tc-arm.c:8056 config/tc-arm.c:8093
+msgid "this addressing mode requires base-register writeback"
+msgstr ""
+
+#: config/tc-arm.c:8253
+msgid "lo register required"
+msgstr ""
+
+#: config/tc-arm.c:8261
+msgid "hi register required"
+msgstr ""
+
+#: config/tc-arm.c:8331 config/tc-arm.c:9537
+msgid "dest and source1 must be the same register"
+msgstr ""
+
+#: config/tc-arm.c:8338
+msgid "subtract valid only on lo regs"
+msgstr ""
+
+#: config/tc-arm.c:8362
+msgid "invalid Hi register with immediate"
+msgstr ""
+
+#: config/tc-arm.c:8402
+msgid "invalid immediate value for stack adjust"
+msgstr ""
+
+#: config/tc-arm.c:8413
+msgid "invalid immediate for address calculation"
+msgstr ""
+
+#: config/tc-arm.c:8500
+msgid "source1 and dest must be same register"
+msgstr ""
+
+#: config/tc-arm.c:8534
+msgid "invalid immediate for shift"
+msgstr ""
+
+#: config/tc-arm.c:8613
+msgid "only lo regs allowed with immediate"
+msgstr ""
+
+#: config/tc-arm.c:8632
+msgid "invalid immediate"
+msgstr ""
+
+#: config/tc-arm.c:8686
+msgid "expected ']'"
+msgstr ""
+
+#: config/tc-arm.c:8759
+msgid "byte or halfword not valid for base register"
+msgstr ""
+
+#: config/tc-arm.c:8764
+msgid "r15 based store not allowed"
+msgstr ""
+
+#: config/tc-arm.c:8769
+msgid "invalid base register for register offset"
+msgstr ""
+
+#: config/tc-arm.c:8787 config/tc-arm.c:8822
+msgid "invalid offset"
+msgstr ""
+
+#: config/tc-arm.c:8798
+msgid "invalid base register in load/store"
+msgstr ""
+
+#: config/tc-arm.c:9341
+msgid "expecting immediate, 7bit operand"
+msgstr ""
+
+#: config/tc-arm.c:9356
+msgid "immediate out of range"
+msgstr ""
+
+#: config/tc-arm.c:9399
+msgid "offset expected"
+msgstr ""
+
+#: config/tc-arm.c:9408 config/tc-pj.c:537 config/tc-sh.c:3593
+msgid "offset out of range"
+msgstr ""
+
+#: config/tc-arm.c:9545
+msgid "Rs and Rd must be different in MUL"
+msgstr ""
+
+#: config/tc-arm.c:9689
+msgid ""
+"inserted missing '!': load/store multiple always writes back base register"
+msgstr ""
+
+#: config/tc-arm.c:9711
+msgid "only lo-regs valid in load/store multiple"
+msgstr ""
+
+#: config/tc-arm.c:9757
+msgid "syntax: ldrs[b] Rd, [Rb, Ro]"
+msgstr ""
+
+#: config/tc-arm.c:9821
+msgid "invalid register list to push/pop instruction"
+msgstr ""
+
+#: config/tc-arm.c:9933 config/tc-arm.c:10159
+msgid "virtual memory exhausted"
+msgstr ""
+
+#: config/tc-arm.c:10014
+#, c-format
+msgid "register '%s' does not exist\n"
+msgstr ""
+
+#: config/tc-arm.c:10018
+#, c-format
+msgid ""
+"ignoring redefinition of register alias '%s' to non-existant register '%s'"
+msgstr ""
+
+#: config/tc-arm.c:10027
+#, c-format
+msgid "ignoring redefinition of register alias '%s'"
+msgstr ""
+
+#: config/tc-arm.c:10033
+msgid "ignoring incomplete .req pseuso op"
+msgstr ""
+
+#: config/tc-arm.c:10183
+msgid "use of old and new-style options to set CPU type"
+msgstr ""
+
+#: config/tc-arm.c:10193
+msgid "use of old and new-style options to set FPU type"
+msgstr ""
+
+#: config/tc-arm.c:10473
+msgid "bad call to MD_ATOF()"
+msgstr ""
+
+#: config/tc-arm.c:10703
+#, c-format
+msgid "invalid constant (%lx) after fixup"
+msgstr ""
+
+#: config/tc-arm.c:10741
+#, c-format
+msgid "unable to compute ADRL instructions for PC offset of 0x%lx"
+msgstr ""
+
+#: config/tc-arm.c:10771
+#, c-format
+msgid "bad immediate value for offset (%ld)"
+msgstr ""
+
+#: config/tc-arm.c:10793 config/tc-arm.c:10815
+msgid "invalid literal constant: pool needs to be closer"
+msgstr ""
+
+#: config/tc-arm.c:10795
+#, c-format
+msgid "bad immediate value for half-word offset (%ld)"
+msgstr ""
+
+#: config/tc-arm.c:10832
+msgid "shift expression is too large"
+msgstr ""
+
+#: config/tc-arm.c:10851 config/tc-arm.c:10860
+msgid "invalid swi expression"
+msgstr ""
+
+#: config/tc-arm.c:10870
+msgid "invalid expression in load/store multiple"
+msgstr ""
+
+#: config/tc-arm.c:10923
+msgid "GAS can't handle same-section branch dest >= 0x04000000"
+msgstr ""
+
+#: config/tc-arm.c:10932
+msgid "out of range branch"
+msgstr ""
+
+#: config/tc-arm.c:10965 config/tc-arm.c:10981
+msgid "branch out of range"
+msgstr ""
+
+#: config/tc-arm.c:11005
+msgid "branch with link out of range"
+msgstr ""
+
+#: config/tc-arm.c:11074
+msgid "illegal value for co-processor offset"
+msgstr ""
+
+#: config/tc-arm.c:11086
+msgid "Illegal value for co-processor offset"
+msgstr ""
+
+#: config/tc-arm.c:11110
+#, c-format
+msgid "invalid offset, target not word aligned (0x%08X)"
+msgstr ""
+
+#: config/tc-arm.c:11116 config/tc-arm.c:11126 config/tc-arm.c:11134
+#: config/tc-arm.c:11142 config/tc-arm.c:11150
+#, c-format
+msgid "invalid offset, value too big (0x%08lX)"
+msgstr ""
+
+#: config/tc-arm.c:11190
+msgid "invalid immediate for stack address calculation"
+msgstr ""
+
+#: config/tc-arm.c:11199
+#, c-format
+msgid "invalid immediate for address calculation (value = 0x%08lX)"
+msgstr ""
+
+#: config/tc-arm.c:11209
+msgid "invalid 8bit immediate"
+msgstr ""
+
+#: config/tc-arm.c:11217
+msgid "invalid 3bit immediate"
+msgstr ""
+
+#: config/tc-arm.c:11233
+#, c-format
+msgid "invalid immediate: %ld is too large"
+msgstr ""
+
+#: config/tc-arm.c:11248
+#, c-format
+msgid "illegal Thumb shift value: %ld"
+msgstr ""
+
+#: config/tc-arm.c:11262
+#, c-format
+msgid "bad relocation fixup type (%d)"
+msgstr ""
+
+#: config/tc-arm.c:11333
+msgid "literal referenced across section boundary"
+msgstr ""
+
+#: config/tc-arm.c:11346
+msgid "internal relocation (type: IMMEDIATE) not fixed up"
+msgstr ""
+
+#: config/tc-arm.c:11351
+msgid "ADRL used for a symbol not defined in the same file"
+msgstr ""
+
+#: config/tc-arm.c:11356
+msgid "internal_relocation (type: OFFSET_IMM) not fixed up"
+msgstr ""
+
+#: config/tc-arm.c:11374 config/tc-cris.c:3063 config/tc-mcore.c:2052
+#: config/tc-mmix.c:2867 config/tc-ns32k.c:2396
+msgid "<unknown>"
+msgstr ""
+
+#: config/tc-arm.c:11377 config/tc-arm.c:11398
+#, c-format
+msgid "cannot represent %s relocation in this object file format"
+msgstr ""
+
+#: config/tc-arm.c:11494
+#, c-format
+msgid "no operator -- statement `%s'\n"
+msgstr ""
+
+#: config/tc-arm.c:11512 config/tc-arm.c:11537
+#, c-format
+msgid "selected processor does not support `%s'"
+msgstr ""
+
+#: config/tc-arm.c:11554
+#, c-format
+msgid "bad instruction `%s'"
+msgstr ""
+
+#: config/tc-arm.c:11655
+msgid "generate PIC code"
+msgstr ""
+
+#: config/tc-arm.c:11656
+msgid "assemble Thumb code"
+msgstr ""
+
+#: config/tc-arm.c:11657
+msgid "support ARM/Thumb interworking"
+msgstr ""
+
+#: config/tc-arm.c:11659
+msgid "use old ABI (ELF only)"
+msgstr ""
+
+#: config/tc-arm.c:11660
+msgid "code uses 32-bit program counter"
+msgstr ""
+
+#: config/tc-arm.c:11661
+msgid "code uses 26-bit program counter"
+msgstr ""
+
+#: config/tc-arm.c:11662
+msgid "floating point args are in fp regs"
+msgstr ""
+
+#: config/tc-arm.c:11664
+msgid "re-entrant code"
+msgstr ""
+
+#: config/tc-arm.c:11665
+msgid "code is ATPCS conformant"
+msgstr ""
+
+#: config/tc-arm.c:11666
+msgid "assemble for big-endian"
+msgstr ""
+
+#: config/tc-arm.c:11667
+msgid "assemble for little-endian"
+msgstr ""
+
+#. These are recognized by the assembler, but have no affect on code.
+#: config/tc-arm.c:11671
+msgid "use frame pointer"
+msgstr ""
+
+#: config/tc-arm.c:11672
+msgid "use stack size checking"
+msgstr ""
+
+#. DON'T add any new processors to this list -- we want the whole list
+#. to go away... Add them to the processors table instead.
+#: config/tc-arm.c:11676 config/tc-arm.c:11677
+msgid "use -mcpu=arm1"
+msgstr ""
+
+#: config/tc-arm.c:11678 config/tc-arm.c:11679
+msgid "use -mcpu=arm2"
+msgstr ""
+
+#: config/tc-arm.c:11680 config/tc-arm.c:11681
+msgid "use -mcpu=arm250"
+msgstr ""
+
+#: config/tc-arm.c:11682 config/tc-arm.c:11683
+msgid "use -mcpu=arm3"
+msgstr ""
+
+#: config/tc-arm.c:11684 config/tc-arm.c:11685
+msgid "use -mcpu=arm6"
+msgstr ""
+
+#: config/tc-arm.c:11686 config/tc-arm.c:11687
+msgid "use -mcpu=arm600"
+msgstr ""
+
+#: config/tc-arm.c:11688 config/tc-arm.c:11689
+msgid "use -mcpu=arm610"
+msgstr ""
+
+#: config/tc-arm.c:11690 config/tc-arm.c:11691
+msgid "use -mcpu=arm620"
+msgstr ""
+
+#: config/tc-arm.c:11692 config/tc-arm.c:11693
+msgid "use -mcpu=arm7"
+msgstr ""
+
+#: config/tc-arm.c:11694 config/tc-arm.c:11695
+msgid "use -mcpu=arm70"
+msgstr ""
+
+#: config/tc-arm.c:11696 config/tc-arm.c:11697
+msgid "use -mcpu=arm700"
+msgstr ""
+
+#: config/tc-arm.c:11698 config/tc-arm.c:11699
+msgid "use -mcpu=arm700i"
+msgstr ""
+
+#: config/tc-arm.c:11700 config/tc-arm.c:11701
+msgid "use -mcpu=arm710"
+msgstr ""
+
+#: config/tc-arm.c:11702 config/tc-arm.c:11703
+msgid "use -mcpu=arm710c"
+msgstr ""
+
+#: config/tc-arm.c:11704 config/tc-arm.c:11705
+msgid "use -mcpu=arm720"
+msgstr ""
+
+#: config/tc-arm.c:11706 config/tc-arm.c:11707
+msgid "use -mcpu=arm7d"
+msgstr ""
+
+#: config/tc-arm.c:11708 config/tc-arm.c:11709
+msgid "use -mcpu=arm7di"
+msgstr ""
+
+#: config/tc-arm.c:11710 config/tc-arm.c:11711
+msgid "use -mcpu=arm7m"
+msgstr ""
+
+#: config/tc-arm.c:11712 config/tc-arm.c:11713
+msgid "use -mcpu=arm7dm"
+msgstr ""
+
+#: config/tc-arm.c:11714 config/tc-arm.c:11715
+msgid "use -mcpu=arm7dmi"
+msgstr ""
+
+#: config/tc-arm.c:11716 config/tc-arm.c:11717
+msgid "use -mcpu=arm7100"
+msgstr ""
+
+#: config/tc-arm.c:11718 config/tc-arm.c:11719
+msgid "use -mcpu=arm7500"
+msgstr ""
+
+#: config/tc-arm.c:11720 config/tc-arm.c:11721
+msgid "use -mcpu=arm7500fe"
+msgstr ""
+
+#: config/tc-arm.c:11722 config/tc-arm.c:11723 config/tc-arm.c:11724
+#: config/tc-arm.c:11725
+msgid "use -mcpu=arm7tdmi"
+msgstr ""
+
+#: config/tc-arm.c:11726 config/tc-arm.c:11727
+msgid "use -mcpu=arm710t"
+msgstr ""
+
+#: config/tc-arm.c:11728 config/tc-arm.c:11729
+msgid "use -mcpu=arm720t"
+msgstr ""
+
+#: config/tc-arm.c:11730 config/tc-arm.c:11731
+msgid "use -mcpu=arm740t"
+msgstr ""
+
+#: config/tc-arm.c:11732 config/tc-arm.c:11733
+msgid "use -mcpu=arm8"
+msgstr ""
+
+#: config/tc-arm.c:11734 config/tc-arm.c:11735
+msgid "use -mcpu=arm810"
+msgstr ""
+
+#: config/tc-arm.c:11736 config/tc-arm.c:11737
+msgid "use -mcpu=arm9"
+msgstr ""
+
+#: config/tc-arm.c:11738 config/tc-arm.c:11739
+msgid "use -mcpu=arm9tdmi"
+msgstr ""
+
+#: config/tc-arm.c:11740 config/tc-arm.c:11741
+msgid "use -mcpu=arm920"
+msgstr ""
+
+#: config/tc-arm.c:11742 config/tc-arm.c:11743
+msgid "use -mcpu=arm940"
+msgstr ""
+
+#: config/tc-arm.c:11744
+msgid "use -mcpu=strongarm"
+msgstr ""
+
+#: config/tc-arm.c:11746
+msgid "use -mcpu=strongarm110"
+msgstr ""
+
+#: config/tc-arm.c:11748
+msgid "use -mcpu=strongarm1100"
+msgstr ""
+
+#: config/tc-arm.c:11750
+msgid "use -mcpu=strongarm1110"
+msgstr ""
+
+#: config/tc-arm.c:11751
+msgid "use -mcpu=xscale"
+msgstr ""
+
+#: config/tc-arm.c:11752
+msgid "use -mcpu=iwmmxt"
+msgstr ""
+
+#: config/tc-arm.c:11753
+msgid "use -mcpu=all"
+msgstr ""
+
+#. Architecture variants -- don't add any more to this list either.
+#: config/tc-arm.c:11756 config/tc-arm.c:11757
+msgid "use -march=armv2"
+msgstr ""
+
+#: config/tc-arm.c:11758 config/tc-arm.c:11759
+msgid "use -march=armv2a"
+msgstr ""
+
+#: config/tc-arm.c:11760 config/tc-arm.c:11761
+msgid "use -march=armv3"
+msgstr ""
+
+#: config/tc-arm.c:11762 config/tc-arm.c:11763
+msgid "use -march=armv3m"
+msgstr ""
+
+#: config/tc-arm.c:11764 config/tc-arm.c:11765
+msgid "use -march=armv4"
+msgstr ""
+
+#: config/tc-arm.c:11766 config/tc-arm.c:11767
+msgid "use -march=armv4t"
+msgstr ""
+
+#: config/tc-arm.c:11768 config/tc-arm.c:11769
+msgid "use -march=armv5"
+msgstr ""
+
+#: config/tc-arm.c:11770 config/tc-arm.c:11771
+msgid "use -march=armv5t"
+msgstr ""
+
+#: config/tc-arm.c:11772 config/tc-arm.c:11773
+msgid "use -march=armv5te"
+msgstr ""
+
+#. Floating point variants -- don't add any more to this list either.
+#: config/tc-arm.c:11776
+msgid "use -mfpu=fpe"
+msgstr ""
+
+#: config/tc-arm.c:11777
+msgid "use -mfpu=fpa10"
+msgstr ""
+
+#: config/tc-arm.c:11778
+msgid "use -mfpu=fpa11"
+msgstr ""
+
+#: config/tc-arm.c:11780
+msgid "use either -mfpu=softfpa or -mfpu=softvfp"
+msgstr ""
+
+#: config/tc-arm.c:11963
+msgid "invalid architectural extension"
+msgstr ""
+
+#: config/tc-arm.c:11977
+msgid "missing architectural extension"
+msgstr ""
+
+#: config/tc-arm.c:11990
+#, c-format
+msgid "unknown architectural extnsion `%s'"
+msgstr ""
+
+#: config/tc-arm.c:12015
+#, c-format
+msgid "missing cpu name `%s'"
+msgstr ""
+
+#: config/tc-arm.c:12031
+#, c-format
+msgid "unknown cpu `%s'"
+msgstr ""
+
+#: config/tc-arm.c:12050
+#, c-format
+msgid "missing architecture name `%s'"
+msgstr ""
+
+#: config/tc-arm.c:12067
+#, c-format
+msgid "unknown architecture `%s'\n"
+msgstr ""
+
+#: config/tc-arm.c:12084
+#, c-format
+msgid "unknown floating point format `%s'\n"
+msgstr ""
+
+#: config/tc-arm.c:12090
+msgid "<cpu name>\t assemble for CPU <cpu name>"
+msgstr ""
+
+#: config/tc-arm.c:12092
+msgid "<arch name>\t assemble for architecture <arch name>"
+msgstr ""
+
+#: config/tc-arm.c:12094
+msgid "<fpu name>\t assemble for FPU architecture <fpu name>"
+msgstr ""
+
+#: config/tc-arm.c:12136 config/tc-arm.c:12158
+#, c-format
+msgid "option `-%c%s' is deprecated: %s"
+msgstr ""
+
+#: config/tc-arm.c:12167
+#, c-format
+msgid "unrecognized option `-%c%s'"
+msgstr ""
+
+#: config/tc-arm.c:12181
+msgid " ARM-specific assembler options:\n"
+msgstr ""
+
+#: config/tc-arm.c:12192
+msgid " -EB assemble code for a big-endian cpu\n"
+msgstr ""
+
+#: config/tc-arm.c:12197
+msgid " -EL assemble code for a little-endian cpu\n"
+msgstr ""
+
+#: config/tc-arm.c:12381
+#, c-format
+msgid "%s: unexpected function type: %d"
+msgstr ""
+
+#: config/tc-arm.c:12756
+msgid "alignments greater than 32 bytes not supported in .text sections."
+msgstr ""
+
+#: config/tc-arm.h:98
+msgid "arm convert_frag\n"
+msgstr ""
+
+#: config/tc-avr.c:203
+msgid "Known MCU names:"
+msgstr ""
+
+#: config/tc-avr.c:272
+msgid ""
+"AVR options:\n"
+" -mmcu=[avr-name] select microcontroller variant\n"
+" [avr-name] can be:\n"
+" avr1 - AT90S1200, ATtiny1x, ATtiny28\n"
+" avr2 - AT90S2xxx, AT90S4xxx, AT90S8xxx, ATtiny22\n"
+" avr3 - ATmega103, ATmega603\n"
+" avr4 - ATmega83, ATmega85\n"
+" avr5 - ATmega161, ATmega163, ATmega32, AT94K\n"
+" or immediate microcontroller name.\n"
+msgstr ""
+
+#: config/tc-avr.c:282
+msgid ""
+" -mall-opcodes accept all AVR opcodes, even if not supported by MCU\n"
+" -mno-skip-bug disable warnings for skipping two-word instructions\n"
+" (default for avr4, avr5)\n"
+" -mno-wrap reject rjmp/rcall instructions with 8K wrap-around\n"
+" (default for avr3, avr5)\n"
+msgstr ""
+
+#: config/tc-avr.c:330 config/tc-msp430.c:257
+#, c-format
+msgid "unknown MCU: %s\n"
+msgstr ""
+
+#: config/tc-avr.c:339
+#, c-format
+msgid "redefinition of mcu type `%s' to `%s'"
+msgstr ""
+
+#: config/tc-avr.c:390 config/tc-d10v.c:319 config/tc-d30v.c:365
+#: config/tc-mips.c:10137 config/tc-mmix.c:2246 config/tc-mn10200.c:361
+#: config/tc-msp430.c:378 config/tc-pj.c:374 config/tc-ppc.c:5105
+#: config/tc-sh.c:2528 config/tc-v850.c:1244
+msgid "bad call to md_atof"
+msgstr ""
+
+#: config/tc-avr.c:453
+msgid "constant value required"
+msgstr ""
+
+#: config/tc-avr.c:456
+#, c-format
+msgid "number must be less than %d"
+msgstr ""
+
+#: config/tc-avr.c:508
+msgid "`,' required"
+msgstr ""
+
+#: config/tc-avr.c:527
+msgid "undefined combination of operands"
+msgstr ""
+
+#: config/tc-avr.c:536
+msgid "skipping two-word instruction"
+msgstr ""
+
+#: config/tc-avr.c:598
+msgid "register r16-r23 required"
+msgstr ""
+
+#: config/tc-avr.c:604
+msgid "register number above 15 required"
+msgstr ""
+
+#: config/tc-avr.c:610
+msgid "even register number required"
+msgstr ""
+
+#: config/tc-avr.c:616
+msgid "register r24, r26, r28 or r30 required"
+msgstr ""
+
+#: config/tc-avr.c:622
+msgid "register name or number from 0 to 31 required"
+msgstr ""
+
+#: config/tc-avr.c:640
+msgid "pointer register (X, Y or Z) required"
+msgstr ""
+
+#: config/tc-avr.c:647
+msgid "cannot both predecrement and postincrement"
+msgstr ""
+
+#: config/tc-avr.c:655
+msgid "addressing mode not supported"
+msgstr ""
+
+#: config/tc-avr.c:661
+msgid "can't predecrement"
+msgstr ""
+
+#: config/tc-avr.c:664
+msgid "pointer register Z required"
+msgstr ""
+
+#: config/tc-avr.c:682
+msgid "pointer register (Y or Z) required"
+msgstr ""
+
+#: config/tc-avr.c:787
+#, c-format
+msgid "unknown constraint `%c'"
+msgstr ""
+
+#: config/tc-avr.c:881 config/tc-avr.c:897 config/tc-avr.c:998
+#: config/tc-msp430.c:1431 config/tc-msp430.c:1448
+#, c-format
+msgid "odd address operand: %ld"
+msgstr ""
+
+#: config/tc-avr.c:889 config/tc-avr.c:908 config/tc-d10v.c:586
+#: config/tc-d30v.c:655 config/tc-msp430.c:1439 config/tc-msp430.c:1453
+#: config/tc-msp430.c:1463
+#, c-format
+msgid "operand out of range: %ld"
+msgstr ""
+
+#: config/tc-avr.c:1007 config/tc-d10v.c:1793 config/tc-d30v.c:1973
+#: config/tc-msp430.c:1481
+#, c-format
+msgid "line %d: unknown relocation type: 0x%x"
+msgstr ""
+
+#: config/tc-avr.c:1021
+msgid "only constant expression allowed"
+msgstr ""
+
+#: config/tc-avr.c:1057 config/tc-d10v.c:1659 config/tc-d30v.c:1806
+#: config/tc-mn10200.c:1255 config/tc-mn10300.c:2303 config/tc-msp430.c:1520
+#: config/tc-or32.c:1618 config/tc-ppc.c:5919 config/tc-v850.c:2263
+#, c-format
+msgid "reloc %d not supported by object file format"
+msgstr ""
+
+#: config/tc-avr.c:1081 config/tc-d10v.c:1248 config/tc-d10v.c:1262
+#: config/tc-h8300.c:1915 config/tc-h8500.c:1106 config/tc-mcore.c:938
+#: config/tc-msp430.c:438 config/tc-pj.c:283 config/tc-sh.c:2096
+#: config/tc-z8k.c:1238
+msgid "can't find opcode "
+msgstr ""
+
+#: config/tc-avr.c:1098
+#, c-format
+msgid "illegal opcode %s for mcu %s"
+msgstr ""
+
+#: config/tc-avr.c:1106
+msgid "garbage at end of line"
+msgstr ""
+
+#: config/tc-avr.c:1170 read.c:3226
+msgid "illegal expression"
+msgstr ""
+
+#: config/tc-avr.c:1196 config/tc-avr.c:1262
+msgid "`)' required"
+msgstr ""
+
+#: config/tc-avr.c:1216
+#, c-format
+msgid "constant out of 8-bit range: %d"
+msgstr ""
+
+#: config/tc-avr.c:1219
+msgid "expression possibly out of 8-bit range"
+msgstr ""
+
+#: config/tc-avr.c:1290 config/tc-avr.c:1297
+#, c-format
+msgid "illegal %srelocation size: %d"
+msgstr ""
+
+#: config/tc-cris.c:386 config/tc-m68hc11.c:2831
+#, c-format
+msgid "internal inconsistency problem in %s: fr_symbol %lx"
+msgstr ""
+
+#: config/tc-cris.c:390 config/tc-m68hc11.c:2835
+#, c-format
+msgid "internal inconsistency problem in %s: resolved symbol"
+msgstr ""
+
+#: config/tc-cris.c:396 config/tc-m68hc11.c:2841
+#, c-format
+msgid "internal inconsistency problem in %s: fr_subtype %d"
+msgstr ""
+
+#: config/tc-cris.c:650
+#, c-format
+msgid "internal inconsistency in %s: bdapq no symbol"
+msgstr ""
+
+#: config/tc-cris.c:663
+#, c-format
+msgid "internal inconsistency in %s: bdap.w with no symbol"
+msgstr ""
+
+#: config/tc-cris.c:807
+msgid "Virtual memory exhausted"
+msgstr ""
+
+#: config/tc-cris.c:815
+#, c-format
+msgid "Can't hash `%s': %s\n"
+msgstr ""
+
+#: config/tc-cris.c:816
+msgid "(unknown reason)"
+msgstr ""
+
+#: config/tc-cris.c:820
+#, c-format
+msgid "Buggy opcode: `%s' \"%s\"\n"
+msgstr ""
+
+#: config/tc-cris.c:1164
+#, c-format
+msgid "Immediate value not in 5 bit unsigned range: %ld"
+msgstr ""
+
+#: config/tc-cris.c:1180
+#, c-format
+msgid "Immediate value not in 4 bit unsigned range: %ld"
+msgstr ""
+
+#: config/tc-cris.c:1219
+#, c-format
+msgid "Immediate value not in 6 bit range: %ld"
+msgstr ""
+
+#: config/tc-cris.c:1234
+#, c-format
+msgid "Immediate value not in 6 bit unsigned range: %ld"
+msgstr ""
+
+#. Others have a generic warning.
+#: config/tc-cris.c:1324
+#, c-format
+msgid "Unimplemented register `%s' specified"
+msgstr ""
+
+#. We've come to the end of instructions with this
+#. opcode, so it must be an error.
+#: config/tc-cris.c:1483
+msgid "Illegal operands"
+msgstr ""
+
+#: config/tc-cris.c:1514 config/tc-cris.c:1545
+#, c-format
+msgid "Immediate value not in 8 bit range: %ld"
+msgstr ""
+
+#: config/tc-cris.c:1524 config/tc-cris.c:1552
+#, c-format
+msgid "Immediate value not in 16 bit range: %ld"
+msgstr ""
+
+#: config/tc-cris.c:1573
+msgid "PIC relocation size does not match operand size"
+msgstr ""
+
+#: config/tc-cris.c:2572
+msgid "32-bit conditional branch generated"
+msgstr ""
+
+#: config/tc-cris.c:2626
+msgid "Complex expression not supported"
+msgstr ""
+
+#. FIXME: Is this function mentioned in the internals.texi manual? If
+#. not, add it.
+#: config/tc-cris.c:2747
+msgid "Bad call to md_atof () - floating point formats are not supported"
+msgstr ""
+
+#: config/tc-cris.c:2794
+msgid "PC-relative relocation must be trivially resolved"
+msgstr ""
+
+#: config/tc-cris.c:2837
+#, c-format
+msgid "Value not in 16 bit range: %ld"
+msgstr ""
+
+#: config/tc-cris.c:2848
+#, c-format
+msgid "Value not in 8 bit range: %ld"
+msgstr ""
+
+#: config/tc-cris.c:2855
+#, c-format
+msgid "Value not in 4 bit unsigned range: %ld"
+msgstr ""
+
+#: config/tc-cris.c:2862
+#, c-format
+msgid "Value not in 5 bit unsigned range: %ld"
+msgstr ""
+
+#: config/tc-cris.c:2869
+#, c-format
+msgid "Value not in 6 bit range: %ld"
+msgstr ""
+
+#: config/tc-cris.c:2876
+#, c-format
+msgid "Value not in 6 bit unsigned range: %ld"
+msgstr ""
+
+#: config/tc-cris.c:2924
+msgid "Please use --help to see usage and options for this assembler.\n"
+msgstr ""
+
+#: config/tc-cris.c:2936
+msgid "--no-underscore is invalid with a.out format"
+msgstr ""
+
+#: config/tc-cris.c:3012
+msgid ""
+"Semantics error. This type of operand can not be relocated, it must be an "
+"assembly-time constant"
+msgstr ""
+
+#: config/tc-cris.c:3064
+#, c-format
+msgid "Cannot generate relocation type for symbol %s, code %s"
+msgstr ""
+
+#. The messages are formatted to line up with the generic options.
+#: config/tc-cris.c:3078
+msgid "CRIS-specific options:\n"
+msgstr ""
+
+#: config/tc-cris.c:3080
+msgid ""
+" -h, -H Don't execute, print this help text. Deprecated.\n"
+msgstr ""
+
+#: config/tc-cris.c:3082
+msgid " -N Warn when branches are expanded to jumps.\n"
+msgstr ""
+
+#: config/tc-cris.c:3084
+msgid ""
+" --underscore User symbols are normally prepended with "
+"underscore.\n"
+msgstr ""
+
+#: config/tc-cris.c:3086
+msgid " Registers will not need any prefix.\n"
+msgstr ""
+
+#: config/tc-cris.c:3088
+msgid " --no-underscore User symbols do not have any prefix.\n"
+msgstr ""
+
+#: config/tc-cris.c:3090
+msgid " Registers will require a `$'-prefix.\n"
+msgstr ""
+
+#: config/tc-cris.c:3092
+msgid " --pic\t\t\tEnable generation of position-independent code.\n"
+msgstr ""
+
+#: config/tc-cris.c:3115
+msgid "Invalid relocation"
+msgstr ""
+
+#: config/tc-cris.c:3149
+msgid "Invalid pc-relative relocation"
+msgstr ""
+
+#: config/tc-cris.c:3198
+#, c-format
+msgid "Adjusted signed .word (%ld) overflows: `switch'-statement too large."
+msgstr ""
+
+#: config/tc-cris.c:3225
+#, c-format
+msgid ".syntax %s requires command-line option `--underscore'"
+msgstr ""
+
+#: config/tc-cris.c:3234
+#, c-format
+msgid ".syntax %s requires command-line option `--no-underscore'"
+msgstr ""
+
+#: config/tc-cris.c:3272
+msgid "Unknown .syntax operand"
+msgstr ""
+
+#: config/tc-cris.c:3283
+msgid "Pseudodirective .file is only valid when generating ELF"
+msgstr ""
+
+#: config/tc-cris.c:3296
+msgid "Pseudodirective .loc is only valid when generating ELF"
+msgstr ""
+
+#: config/tc-d10v.c:252
+msgid ""
+"D10V options:\n"
+"-O Optimize. Will do some operations in parallel.\n"
+"--gstabs-packing Pack adjacent short instructions together even\n"
+" when --gstabs is specified. On by default.\n"
+"--no-gstabs-packing If --gstabs is specified, do not pack adjacent\n"
+" instructions together.\n"
+msgstr ""
+
+#: config/tc-d10v.c:543 config/tc-d30v.c:549 config/tc-mn10200.c:937
+#: config/tc-mn10300.c:1812 config/tc-ppc.c:2332 config/tc-s390.c:1234
+#: config/tc-tic80.c:275 config/tc-v850.c:2021
+msgid "illegal operand"
+msgstr ""
+
+#: config/tc-d10v.c:657
+msgid "operand is not an immediate"
+msgstr ""
+
+#: config/tc-d10v.c:675
+#, c-format
+msgid "operand out of range: %lu"
+msgstr ""
+
+#: config/tc-d10v.c:736
+msgid "Instruction must be executed in parallel with another instruction."
+msgstr ""
+
+#: config/tc-d10v.c:792
+msgid "Instruction must be executed in parallel"
+msgstr ""
+
+#: config/tc-d10v.c:795
+msgid "Long instructions may not be combined."
+msgstr ""
+
+#: config/tc-d10v.c:828
+msgid "One of these instructions may not be executed in parallel."
+msgstr ""
+
+#: config/tc-d10v.c:832 config/tc-d30v.c:876
+msgid "Two IU instructions may not be executed in parallel"
+msgstr ""
+
+#: config/tc-d10v.c:834 config/tc-d10v.c:842 config/tc-d10v.c:856
+#: config/tc-d10v.c:871 config/tc-d30v.c:877 config/tc-d30v.c:886
+msgid "Swapping instruction order"
+msgstr ""
+
+#: config/tc-d10v.c:840 config/tc-d30v.c:883
+msgid "Two MU instructions may not be executed in parallel"
+msgstr ""
+
+#: config/tc-d10v.c:860 config/tc-d30v.c:903
+msgid "IU instruction may not be in the left container"
+msgstr ""
+
+#: config/tc-d10v.c:862 config/tc-d10v.c:877
+msgid ""
+"Instruction in R container is squashed by flow control instruction in L "
+"container."
+msgstr ""
+
+#: config/tc-d10v.c:875 config/tc-d30v.c:914
+msgid "MU instruction may not be in the right container"
+msgstr ""
+
+#: config/tc-d10v.c:881 config/tc-d30v.c:926
+msgid "unknown execution type passed to write_2_short()"
+msgstr ""
+
+#: config/tc-d10v.c:1072 config/tc-d10v.c:1080
+#, c-format
+msgid "packing conflict: %s must dispatch sequentially"
+msgstr ""
+
+#: config/tc-d10v.c:1179
+#, c-format
+msgid "resource conflict (R%d)"
+msgstr ""
+
+#: config/tc-d10v.c:1182
+#, c-format
+msgid "resource conflict (A%d)"
+msgstr ""
+
+#: config/tc-d10v.c:1184
+msgid "resource conflict (PSW)"
+msgstr ""
+
+#: config/tc-d10v.c:1186
+msgid "resource conflict (C flag)"
+msgstr ""
+
+#: config/tc-d10v.c:1188
+msgid "resource conflict (F flag)"
+msgstr ""
+
+#: config/tc-d10v.c:1276 config/tc-d10v.c:1298 config/tc-d30v.c:1410
+msgid "Unable to mix instructions as specified"
+msgstr ""
+
+#: config/tc-d10v.c:1345 config/tc-d30v.c:1547
+#, c-format
+msgid "unknown opcode: %s"
+msgstr ""
+
+#: config/tc-d10v.c:1428 config/tc-d10v.c:1603 config/tc-tic80.c:532
+msgid "bad opcode or operands"
+msgstr ""
+
+#: config/tc-d10v.c:1503 config/tc-m68k.c:4305
+msgid "value out of range"
+msgstr ""
+
+#: config/tc-d10v.c:1579
+msgid "illegal operand - register name found where none expected"
+msgstr ""
+
+#: config/tc-d10v.c:1614 config/tc-tic80.c:543
+msgid "Register number must be EVEN"
+msgstr ""
+
+#: config/tc-d10v.c:1617
+msgid "Unsupported use of sp"
+msgstr ""
+
+#: config/tc-d10v.c:1636
+#, c-format
+msgid "cr%ld is a reserved control register"
+msgstr ""
+
+#: config/tc-d10v.c:1773
+#, c-format
+msgid "line %d: rep or repi must include at least 4 instructions"
+msgstr ""
+
+#: config/tc-d30v.c:192
+#, c-format
+msgid "Register name %s conflicts with symbol of the same name"
+msgstr ""
+
+#: config/tc-d30v.c:287
+msgid ""
+"\n"
+"D30V options:\n"
+"-O Make adjacent short instructions parallel if "
+"possible.\n"
+"-n Warn about all NOPs inserted by the assembler.\n"
+"-N\t\t\tWarn about NOPs inserted after word multiplies.\n"
+"-c Warn about symbols whoes names match register "
+"names.\n"
+"-C Opposite of -C. -c is the default.\n"
+msgstr ""
+
+#: config/tc-d30v.c:461
+msgid "unexpected 12-bit reloc type"
+msgstr ""
+
+#: config/tc-d30v.c:468
+msgid "unexpected 18-bit reloc type"
+msgstr ""
+
+#: config/tc-d30v.c:719
+#, c-format
+msgid "%s NOP inserted"
+msgstr ""
+
+#: config/tc-d30v.c:720
+msgid "sequential"
+msgstr ""
+
+#: config/tc-d30v.c:720
+msgid "parallel"
+msgstr ""
+
+#: config/tc-d30v.c:872
+msgid "Instructions may not be executed in parallel"
+msgstr ""
+
+#: config/tc-d30v.c:885
+#, c-format
+msgid "Executing %s in IU may not work"
+msgstr ""
+
+#: config/tc-d30v.c:892
+#, c-format
+msgid "Executing %s in IU may not work in parallel execution"
+msgstr ""
+
+#: config/tc-d30v.c:905
+#, c-format
+msgid "special left instruction `%s' kills instruction `%s' in right container"
+msgstr ""
+
+#: config/tc-d30v.c:916
+#, c-format
+msgid "Executing %s in reverse serial with %s may not work"
+msgstr ""
+
+#: config/tc-d30v.c:919
+#, c-format
+msgid "Executing %s in IU in reverse serial may not work"
+msgstr ""
+
+#: config/tc-d30v.c:1289 config/tc-d30v.c:1306
+msgid "Cannot assemble instruction"
+msgstr ""
+
+#: config/tc-d30v.c:1291
+msgid "First opcode is long. Unable to mix instructions as specified."
+msgstr ""
+
+#: config/tc-d30v.c:1360
+msgid "word of NOPs added between word multiply and load"
+msgstr ""
+
+#: config/tc-d30v.c:1362
+msgid "word of NOPs added between word multiply and 16-bit multiply"
+msgstr ""
+
+#: config/tc-d30v.c:1394
+msgid "Instruction uses long version, so it cannot be mixed as specified"
+msgstr ""
+
+#: config/tc-d30v.c:1477 config/tc-d30v.c:1515
+#, c-format
+msgid "unknown condition code: %s"
+msgstr ""
+
+#: config/tc-d30v.c:1508
+#, c-format
+msgid "cmpu doesn't support condition code %s"
+msgstr ""
+
+#: config/tc-d30v.c:1558
+#, c-format
+msgid "operands for opcode `%s' do not match any valid format"
+msgstr ""
+
+#: config/tc-d30v.c:1776
+msgid "Odd numbered register used as target of multi-register instruction"
+msgstr ""
+
+#: config/tc-d30v.c:1862
+#, c-format
+msgid "line %d: unable to place address of symbol '%s' into a byte"
+msgstr ""
+
+#: config/tc-d30v.c:1865
+#, c-format
+msgid "line %d: unable to place value %lx into a byte"
+msgstr ""
+
+#: config/tc-d30v.c:1873
+#, c-format
+msgid "line %d: unable to place address of symbol '%s' into a short"
+msgstr ""
+
+#: config/tc-d30v.c:1876
+#, c-format
+msgid "line %d: unable to place value %lx into a short"
+msgstr ""
+
+#: config/tc-d30v.c:1884
+#, c-format
+msgid "line %d: unable to place address of symbol '%s' into a quad"
+msgstr ""
+
+#: config/tc-d30v.c:2053
+#, c-format
+msgid "value too large to fit in %d bits"
+msgstr ""
+
+#: config/tc-d30v.c:2196
+#, c-format
+msgid "Alignment too large: %d assumed"
+msgstr ""
+
+#: config/tc-dlx.c:283
+msgid "missing .proc"
+msgstr ""
+
+#: config/tc-dlx.c:300
+msgid ".endfunc missing for previous .proc"
+msgstr ""
+
+#: config/tc-dlx.c:498
+#, c-format
+msgid "Expression Error for operand modifier %%hi/%%lo\n"
+msgstr ""
+
+#: config/tc-dlx.c:552
+#, c-format
+msgid "Bad operand for a load instruction: <%s>"
+msgstr ""
+
+#: config/tc-dlx.c:667
+#, c-format
+msgid "Bad operand for a store instruction: <%s>"
+msgstr ""
+
+#: config/tc-dlx.c:865
+msgid "Can not set dlx_skip_hi16_flag"
+msgstr ""
+
+#: config/tc-dlx.c:879
+#, c-format
+msgid "Missing arguments for opcode <%s>."
+msgstr ""
+
+#: config/tc-dlx.c:950
+#, c-format
+msgid "Both the_insn.HI and the_insn.LO are set : %s"
+msgstr ""
+
+#: config/tc-dlx.c:1022
+msgid "failed regnum sanity check."
+msgstr ""
+
+#: config/tc-dlx.c:1035
+msgid "failed general register sanity check."
+msgstr ""
+
+#: config/tc-dlx.c:1324
+msgid "Invalid expression after # number\n"
+msgstr ""
+
+#: config/tc-fr30.c:85
+msgid " FR30 specific command line options:\n"
+msgstr ""
+
+#: config/tc-fr30.c:139 config/tc-openrisc.c:152
+#, c-format
+msgid "Instruction %s not allowed in a delay slot."
+msgstr ""
+
+#: config/tc-fr30.c:383 config/tc-m32r.c:1576
+msgid "Addend to unresolved symbol not on word boundary."
+msgstr ""
+
+#: config/tc-fr30.c:524 config/tc-frv.c:1289 config/tc-i960.c:798
+#: config/tc-ip2k.c:351 config/tc-m32r.c:1884 config/tc-openrisc.c:452
+#: config/tc-xstormy16.c:636
+msgid "Bad call to md_atof()"
+msgstr ""
+
+#: config/tc-frv.c:413
+msgid "FRV specific command line options:\n"
+msgstr ""
+
+#: config/tc-frv.c:414
+msgid "-G n Data >= n bytes is in small data area\n"
+msgstr ""
+
+#: config/tc-frv.c:415
+msgid "-mgpr-32 Note 32 gprs are used\n"
+msgstr ""
+
+#: config/tc-frv.c:416
+msgid "-mgpr-64 Note 64 gprs are used\n"
+msgstr ""
+
+#: config/tc-frv.c:417
+msgid "-mfpr-32 Note 32 fprs are used\n"
+msgstr ""
+
+#: config/tc-frv.c:418
+msgid "-mfpr-64 Note 64 fprs are used\n"
+msgstr ""
+
+#: config/tc-frv.c:419
+msgid "-msoft-float Note software fp is used\n"
+msgstr ""
+
+#: config/tc-frv.c:420
+msgid "-mdword Note stack is aligned to a 8 byte boundary\n"
+msgstr ""
+
+#: config/tc-frv.c:421
+msgid "-mno-dword Note stack is aligned to a 4 byte boundary\n"
+msgstr ""
+
+#: config/tc-frv.c:422
+msgid "-mdouble Note fp double insns are used\n"
+msgstr ""
+
+#: config/tc-frv.c:423
+msgid "-mmedia Note media insns are used\n"
+msgstr ""
+
+#: config/tc-frv.c:424
+msgid "-mmuladd Note multiply add/subtract insns are used\n"
+msgstr ""
+
+#: config/tc-frv.c:425
+msgid "-mpack Note instructions are packed\n"
+msgstr ""
+
+#: config/tc-frv.c:426
+msgid "-mno-pack Do not allow instructions to be packed\n"
+msgstr ""
+
+#: config/tc-frv.c:427
+msgid "-mpic Note small position independent code\n"
+msgstr ""
+
+#: config/tc-frv.c:428
+msgid "-mPIC Note large position independent code\n"
+msgstr ""
+
+#: config/tc-frv.c:429
+msgid "-mlibrary-pic Compile library for large position indepedent code\n"
+msgstr ""
+
+#: config/tc-frv.c:430
+msgid "-mcpu={fr500|fr400|fr300|frv|simple|tomcat}\n"
+msgstr ""
+
+#: config/tc-frv.c:431
+msgid " Record the cpu type\n"
+msgstr ""
+
+#: config/tc-frv.c:432
+msgid "-mtomcat-stats Print out stats for tomcat workarounds\n"
+msgstr ""
+
+#: config/tc-frv.c:433
+msgid "-mtomcat-debug Debug tomcat workarounds\n"
+msgstr ""
+
+#: config/tc-frv.c:1012
+msgid "VLIW packing used for -mno-pack"
+msgstr ""
+
+#: config/tc-frv.c:1025
+msgid "VLIW packing constraint violation"
+msgstr ""
+
+#: config/tc-frv.c:1540
+#, c-format
+msgid "Relocation %s is not safe for %s"
+msgstr ""
+
+#: config/tc-h8300.c:84 config/tc-h8300.c:96 config/tc-h8300.c:109
+#: config/tc-h8300.c:122 config/tc-h8300.c:135 config/tc-h8300.c:149
+#: config/tc-h8300.c:222 config/tc-hppa.c:1423 config/tc-hppa.c:6909
+#: config/tc-hppa.c:6915 config/tc-hppa.c:6921 config/tc-hppa.c:6927
+#: config/tc-mn10300.c:1218 config/tc-mn10300.c:1223 config/tc-mn10300.c:2722
+msgid "could not set architecture and machine"
+msgstr ""
+
+#: config/tc-h8300.c:436 config/tc-h8300.c:444
+msgid "Reg not valid for H8/300"
+msgstr ""
+
+#: config/tc-h8300.c:529
+msgid "invalid operand size requested"
+msgstr ""
+
+#: config/tc-h8300.c:626 config/tc-h8300.c:629
+msgid "Invalid register list for ldm/stm\n"
+msgstr ""
+
+#: config/tc-h8300.c:632
+msgid "Invalid register list for ldm/stm)\n"
+msgstr ""
+
+#: config/tc-h8300.c:658 config/tc-h8300.c:663 config/tc-h8300.c:670
+msgid "mismatch between register and suffix"
+msgstr ""
+
+#: config/tc-h8300.c:697
+msgid "address too high for vector table jmp/jsr"
+msgstr ""
+
+#: config/tc-h8300.c:722 config/tc-h8300.c:832 config/tc-h8300.c:840
+msgid "Wrong size pointer register for architecture."
+msgstr ""
+
+#: config/tc-h8300.c:781 config/tc-h8300.c:789 config/tc-h8300.c:818
+msgid "expected @(exp, reg16)"
+msgstr ""
+
+#: config/tc-h8300.c:807
+msgid "expected .L, .W or .B for register in indexed addressing mode"
+msgstr ""
+
+#: config/tc-h8300.c:1000
+msgid "expected valid addressing mode for mova: \"@(disp, ea.sz),ERn\""
+msgstr ""
+
+#: config/tc-h8300.c:1018 config/tc-h8300.c:1027
+msgid "expected register"
+msgstr ""
+
+#: config/tc-h8300.c:1043
+msgid "expected closing paren"
+msgstr ""
+
+#: config/tc-h8300.c:1104
+#, c-format
+msgid "can't use high part of register in operand %d"
+msgstr ""
+
+#: config/tc-h8300.c:1268
+#, c-format
+msgid "Opcode `%s' with these operand types not available in %s mode"
+msgstr ""
+
+#: config/tc-h8300.c:1277
+msgid "mismatch between opcode size and operand size"
+msgstr ""
+
+#: config/tc-h8300.c:1316
+#, c-format
+msgid "operand %s0x%lx out of range."
+msgstr ""
+
+#: config/tc-h8300.c:1415
+msgid "Can't work out size of operand.\n"
+msgstr ""
+
+#: config/tc-h8300.c:1466
+#, c-format
+msgid "Opcode `%s' with these operand types not available in H8/300 mode"
+msgstr ""
+
+#: config/tc-h8300.c:1471
+#, c-format
+msgid "Opcode `%s' with these operand types not available in H8/300H mode"
+msgstr ""
+
+#: config/tc-h8300.c:1477
+#, c-format
+msgid "Opcode `%s' with these operand types not available in H8/300S mode"
+msgstr ""
+
+#: config/tc-h8300.c:1538 config/tc-h8300.c:1558
+msgid "Need #1 or #2 here"
+msgstr ""
+
+#: config/tc-h8300.c:1553
+msgid "#4 not valid on H8/300."
+msgstr ""
+
+#: config/tc-h8300.c:1645 config/tc-h8300.c:1727
+#, c-format
+msgid "branch operand has odd offset (%lx)\n"
+msgstr ""
+
+#: config/tc-h8300.c:1766
+msgid "destination operand must be 16 bit register"
+msgstr ""
+
+#: config/tc-h8300.c:1775
+msgid "source operand must be 8 bit register"
+msgstr ""
+
+#: config/tc-h8300.c:1783
+msgid "destination operand must be 16bit absolute address"
+msgstr ""
+
+#: config/tc-h8300.c:1790
+msgid "destination operand must be 8 bit register"
+msgstr ""
+
+#: config/tc-h8300.c:1798
+msgid "source operand must be 16bit absolute address"
+msgstr ""
+
+#. This seems more sane than saying "too many operands". We'll
+#. get here only if the trailing trash starts with a comma.
+#: config/tc-h8300.c:1806 config/tc-mmix.c:454 config/tc-mmix.c:466
+#: config/tc-mmix.c:2502 config/tc-mmix.c:2526 config/tc-mmix.c:2802
+#: config/tc-or32.c:640 config/tc-or32.c:854
+msgid "invalid operands"
+msgstr ""
+
+#: config/tc-h8300.c:1839
+msgid "operand/size mis-match"
+msgstr ""
+
+#: config/tc-h8300.c:1926 config/tc-h8500.c:1112 config/tc-mips.c:9302
+#: config/tc-sh.c:2363 config/tc-sh64.c:2837 config/tc-w65.c:691
+#: config/tc-z8k.c:1248
+msgid "unknown opcode"
+msgstr ""
+
+#: config/tc-h8300.c:2031 config/tc-h8500.c:1139 config/tc-sh.c:2483
+#: config/tc-z8k.c:1304
+msgid "call to tc_crawl_symbol_chain \n"
+msgstr ""
+
+#: config/tc-h8300.c:2047 config/tc-h8500.c:1153 config/tc-sh.c:2490
+#: config/tc-z8k.c:1320
+msgid "call to tc_headers_hook \n"
+msgstr ""
+
+#: config/tc-h8300.c:2140
+msgid "call to tc_aout_fix_to_chars \n"
+msgstr ""
+
+#: config/tc-h8300.c:2154
+msgid "call to md_convert_frag \n"
+msgstr ""
+
+#: config/tc-h8300.c:2216
+msgid "call tomd_estimate_size_before_relax \n"
+msgstr ""
+
+#: config/tc-h8300.c:2337 config/tc-mcore.c:2355 config/tc-pj.c:581
+#: config/tc-sh.c:3956
+#, c-format
+msgid "Cannot represent relocation type %s"
+msgstr ""
+
+#: config/tc-h8500.c:325
+msgid ":24 not valid for this opcode"
+msgstr ""
+
+#: config/tc-h8500.c:332
+msgid "expect :8,:16 or :24"
+msgstr ""
+
+#: config/tc-h8500.c:391
+msgid "syntax error in reg list"
+msgstr ""
+
+#: config/tc-h8500.c:409
+msgid "missing final register in range"
+msgstr ""
+
+#: config/tc-h8500.c:498 config/tc-h8500.c:505 config/tc-h8500.c:511
+msgid "expected @(exp, Rn)"
+msgstr ""
+
+#: config/tc-h8500.c:527
+msgid "@Rn+ needs word register"
+msgstr ""
+
+#: config/tc-h8500.c:537
+msgid "@Rn needs word register"
+msgstr ""
+
+#: config/tc-h8500.c:838 config/tc-sh.c:1827
+#, c-format
+msgid "unhandled %d\n"
+msgstr ""
+
+#: config/tc-h8500.c:868
+#, c-format
+msgid "operand must be absolute in range %d..%d"
+msgstr ""
+
+#: config/tc-h8500.c:963 config/tc-sh.c:2036
+#, c-format
+msgid "failed for %d\n"
+msgstr ""
+
+#: config/tc-h8500.c:1128 config/tc-sh.c:2138 config/tc-sh.c:2412
+#: config/tc-w65.c:710
+msgid "invalid operands for opcode"
+msgstr ""
+
+#. Simple range checking for FIELD againt HIGH and LOW bounds.
+#. IGNORE is used to suppress the error message.
+#: config/tc-hppa.c:1156 config/tc-hppa.c:1170
+#, c-format
+msgid "Field out of range [%d..%d] (%d)."
+msgstr ""
+
+#. Simple alignment checking for FIELD againt ALIGN (a power of two).
+#. IGNORE is used to suppress the error message.
+#: config/tc-hppa.c:1184
+#, c-format
+msgid "Field not properly aligned [%d] (%d)."
+msgstr ""
+
+#: config/tc-hppa.c:1213
+msgid "Missing .exit\n"
+msgstr ""
+
+#: config/tc-hppa.c:1216
+msgid "Missing .procend\n"
+msgstr ""
+
+#: config/tc-hppa.c:1396
+#, c-format
+msgid "Invalid field selector. Assuming F%%."
+msgstr ""
+
+#: config/tc-hppa.c:1429
+msgid "-R option not supported on this target."
+msgstr ""
+
+#: config/tc-hppa.c:1445 config/tc-sparc.c:809 config/tc-sparc.c:845
+#, c-format
+msgid "Internal error: can't hash `%s': %s\n"
+msgstr ""
+
+#: config/tc-hppa.c:1453 config/tc-i860.c:201
+#, c-format
+msgid "internal error: losing opcode: `%s' \"%s\"\n"
+msgstr ""
+
+#: config/tc-hppa.c:1524 config/tc-hppa.c:7048 config/tc-hppa.c:7105
+msgid "Missing function name for .PROC (corrupted label chain)"
+msgstr ""
+
+#: config/tc-hppa.c:1527 config/tc-hppa.c:7108
+msgid "Missing function name for .PROC"
+msgstr ""
+
+#: config/tc-hppa.c:1634 config/tc-hppa.c:4905
+msgid "could not update architecture and machine"
+msgstr ""
+
+#: config/tc-hppa.c:1842
+msgid "Invalid Indexed Load Completer."
+msgstr ""
+
+#: config/tc-hppa.c:1847
+msgid "Invalid Indexed Load Completer Syntax."
+msgstr ""
+
+#: config/tc-hppa.c:1884
+msgid "Invalid Short Load/Store Completer."
+msgstr ""
+
+#: config/tc-hppa.c:1944 config/tc-hppa.c:1949
+msgid "Invalid Store Bytes Short Completer"
+msgstr ""
+
+#: config/tc-hppa.c:2260 config/tc-hppa.c:2266
+msgid "Invalid left/right combination completer"
+msgstr ""
+
+#: config/tc-hppa.c:2315 config/tc-hppa.c:2322
+msgid "Invalid permutation completer"
+msgstr ""
+
+#: config/tc-hppa.c:2423
+#, c-format
+msgid "Invalid Add Condition: %s"
+msgstr ""
+
+#: config/tc-hppa.c:2434 config/tc-hppa.c:2444
+msgid "Invalid Add and Branch Condition"
+msgstr ""
+
+#: config/tc-hppa.c:2465 config/tc-hppa.c:2603
+msgid "Invalid Compare/Subtract Condition"
+msgstr ""
+
+#: config/tc-hppa.c:2505
+#, c-format
+msgid "Invalid Bit Branch Condition: %c"
+msgstr ""
+
+#: config/tc-hppa.c:2591
+#, c-format
+msgid "Invalid Compare/Subtract Condition: %s"
+msgstr ""
+
+#: config/tc-hppa.c:2618
+msgid "Invalid Compare and Branch Condition"
+msgstr ""
+
+#: config/tc-hppa.c:2714
+msgid "Invalid Logical Instruction Condition."
+msgstr ""
+
+#: config/tc-hppa.c:2769
+msgid "Invalid Shift/Extract/Deposit Condition."
+msgstr ""
+
+#: config/tc-hppa.c:2881
+msgid "Invalid Unit Instruction Condition."
+msgstr ""
+
+#: config/tc-hppa.c:3258 config/tc-hppa.c:3290 config/tc-hppa.c:3321
+#: config/tc-hppa.c:3351
+msgid "Branch to unaligned address"
+msgstr ""
+
+#: config/tc-hppa.c:3529
+msgid "Invalid SFU identifier"
+msgstr ""
+
+#: config/tc-hppa.c:3579
+msgid "Invalid COPR identifier"
+msgstr ""
+
+#: config/tc-hppa.c:3708
+msgid "Invalid Floating Point Operand Format."
+msgstr ""
+
+#: config/tc-hppa.c:3825 config/tc-hppa.c:3845 config/tc-hppa.c:3865
+#: config/tc-hppa.c:3885 config/tc-hppa.c:3905
+msgid "Invalid register for single precision fmpyadd or fmpysub"
+msgstr ""
+
+#: config/tc-hppa.c:3962
+#, c-format
+msgid "Invalid operands %s"
+msgstr ""
+
+#: config/tc-hppa.c:4080
+msgid "Cannot handle fixup"
+msgstr ""
+
+#: config/tc-hppa.c:4381
+msgid " -Q ignored\n"
+msgstr ""
+
+#: config/tc-hppa.c:4385
+msgid " -c print a warning if a comment is found\n"
+msgstr ""
+
+#: config/tc-hppa.c:4456
+#, c-format
+msgid "no hppa_fixup entry for fixup type 0x%x"
+msgstr ""
+
+#: config/tc-hppa.c:4627
+msgid "Unknown relocation encountered in md_apply_fix."
+msgstr ""
+
+#: config/tc-hppa.c:4769 config/tc-hppa.c:4794
+#, c-format
+msgid "Undefined register: '%s'."
+msgstr ""
+
+#: config/tc-hppa.c:4828
+#, c-format
+msgid "Non-absolute symbol: '%s'."
+msgstr ""
+
+#: config/tc-hppa.c:4843
+#, c-format
+msgid "Undefined absolute constant: '%s'."
+msgstr ""
+
+#: config/tc-hppa.c:4944
+#, c-format
+msgid "Invalid FP Compare Condition: %s"
+msgstr ""
+
+#: config/tc-hppa.c:5000
+#, c-format
+msgid "Invalid FTEST completer: %s"
+msgstr ""
+
+#: config/tc-hppa.c:5067 config/tc-hppa.c:5105
+#, c-format
+msgid "Invalid FP Operand Format: %3s"
+msgstr ""
+
+#: config/tc-hppa.c:5184
+msgid "Bad segment in expression."
+msgstr ""
+
+#: config/tc-hppa.c:5243
+msgid "Bad segment (should be absolute)."
+msgstr ""
+
+#: config/tc-hppa.c:5286
+#, c-format
+msgid "Invalid argument location: %s\n"
+msgstr ""
+
+#: config/tc-hppa.c:5317
+#, c-format
+msgid "Invalid argument description: %d"
+msgstr ""
+
+#: config/tc-hppa.c:5340
+#, c-format
+msgid "Invalid Nullification: (%c)"
+msgstr ""
+
+#: config/tc-hppa.c:6060
+#, c-format
+msgid "Invalid .CALL argument: %s"
+msgstr ""
+
+#: config/tc-hppa.c:6182
+msgid ".callinfo is not within a procedure definition"
+msgstr ""
+
+#: config/tc-hppa.c:6202
+#, c-format
+msgid "FRAME parameter must be a multiple of 8: %d\n"
+msgstr ""
+
+#: config/tc-hppa.c:6221
+msgid "Value for ENTRY_GR must be in the range 3..18\n"
+msgstr ""
+
+#: config/tc-hppa.c:6233
+msgid "Value for ENTRY_FR must be in the range 12..21\n"
+msgstr ""
+
+#: config/tc-hppa.c:6243
+msgid "Value for ENTRY_SR must be 3\n"
+msgstr ""
+
+#: config/tc-hppa.c:6299
+#, c-format
+msgid "Invalid .CALLINFO argument: %s"
+msgstr ""
+
+#: config/tc-hppa.c:6410
+msgid "The .ENTER pseudo-op is not supported"
+msgstr ""
+
+#: config/tc-hppa.c:6426
+msgid "Misplaced .entry. Ignored."
+msgstr ""
+
+#: config/tc-hppa.c:6430
+msgid "Missing .callinfo."
+msgstr ""
+
+#: config/tc-hppa.c:6496
+msgid ".REG expression must be a register"
+msgstr ""
+
+#: config/tc-hppa.c:6512
+msgid "bad or irreducible absolute expression; zero assumed"
+msgstr ""
+
+#: config/tc-hppa.c:6523
+msgid ".REG must use a label"
+msgstr ""
+
+#: config/tc-hppa.c:6525
+msgid ".EQU must use a label"
+msgstr ""
+
+#: config/tc-hppa.c:6578
+msgid ".EXIT must appear within a procedure"
+msgstr ""
+
+#: config/tc-hppa.c:6582
+msgid "Missing .callinfo"
+msgstr ""
+
+#: config/tc-hppa.c:6586
+msgid "No .ENTRY for this .EXIT"
+msgstr ""
+
+#: config/tc-hppa.c:6613
+#, c-format
+msgid "Cannot define export symbol: %s\n"
+msgstr ""
+
+#: config/tc-hppa.c:6671
+#, c-format
+msgid "Using ENTRY rather than CODE in export directive for %s"
+msgstr ""
+
+#: config/tc-hppa.c:6788
+#, c-format
+msgid "Undefined .EXPORT/.IMPORT argument (ignored): %s"
+msgstr ""
+
+#: config/tc-hppa.c:6870
+msgid "Missing label name on .LABEL"
+msgstr ""
+
+#: config/tc-hppa.c:6875
+msgid "extra .LABEL arguments ignored."
+msgstr ""
+
+#: config/tc-hppa.c:6892
+msgid "The .LEAVE pseudo-op is not supported"
+msgstr ""
+
+#: config/tc-hppa.c:6931
+msgid "Unrecognized .LEVEL argument\n"
+msgstr ""
+
+#: config/tc-hppa.c:6967
+#, c-format
+msgid "Cannot define static symbol: %s\n"
+msgstr ""
+
+#: config/tc-hppa.c:7002
+msgid "Nested procedures"
+msgstr ""
+
+#: config/tc-hppa.c:7012
+msgid "Cannot allocate unwind descriptor\n"
+msgstr ""
+
+#: config/tc-hppa.c:7112
+msgid "misplaced .procend"
+msgstr ""
+
+#: config/tc-hppa.c:7115
+msgid "Missing .callinfo for this procedure"
+msgstr ""
+
+#: config/tc-hppa.c:7118
+msgid "Missing .EXIT for a .ENTRY"
+msgstr ""
+
+#: config/tc-hppa.c:7156
+msgid "Not in a space.\n"
+msgstr ""
+
+#: config/tc-hppa.c:7159
+msgid "Not in a subspace.\n"
+msgstr ""
+
+#: config/tc-hppa.c:7250
+msgid "Invalid .SPACE argument"
+msgstr ""
+
+#: config/tc-hppa.c:7297
+msgid "Can't change spaces within a procedure definition. Ignored"
+msgstr ""
+
+#: config/tc-hppa.c:7426
+#, c-format
+msgid "Undefined space: '%s' Assuming space number = 0."
+msgstr ""
+
+#: config/tc-hppa.c:7450
+msgid "Must be in a space before changing or declaring subspaces.\n"
+msgstr ""
+
+#: config/tc-hppa.c:7454
+msgid "Can't change subspaces within a procedure definition. Ignored"
+msgstr ""
+
+#: config/tc-hppa.c:7489
+msgid "Parameters of an existing subspace can't be modified"
+msgstr ""
+
+#: config/tc-hppa.c:7540
+msgid "Alignment must be a power of 2"
+msgstr ""
+
+#: config/tc-hppa.c:7582
+msgid "FIRST not supported as a .SUBSPACE argument"
+msgstr ""
+
+#: config/tc-hppa.c:7584
+msgid "Invalid .SUBSPACE argument"
+msgstr ""
+
+#: config/tc-hppa.c:7764
+#, c-format
+msgid "Internal error: Unable to find containing space for %s."
+msgstr ""
+
+#: config/tc-hppa.c:7803
+#, c-format
+msgid "Out of memory: could not allocate new space chain entry: %s\n"
+msgstr ""
+
+#: config/tc-hppa.c:7889
+#, c-format
+msgid "Out of memory: could not allocate new subspace chain entry: %s\n"
+msgstr ""
+
+#: config/tc-hppa.c:8622
+#, c-format
+msgid "Symbol '%s' could not be created."
+msgstr ""
+
+#: config/tc-hppa.c:8626
+msgid "No memory for symbol name."
+msgstr ""
+
+#: config/tc-i386.c:689
+#, c-format
+msgid "%s shortened to %s"
+msgstr ""
+
+#: config/tc-i386.c:745
+msgid "same type of prefix used twice"
+msgstr ""
+
+#: config/tc-i386.c:763
+msgid "64bit mode not supported on this CPU."
+msgstr ""
+
+#: config/tc-i386.c:767
+msgid "32bit mode not supported on this CPU."
+msgstr ""
+
+#: config/tc-i386.c:800
+msgid "bad argument to syntax directive."
+msgstr ""
+
+#: config/tc-i386.c:844
+#, c-format
+msgid "no such architecture: `%s'"
+msgstr ""
+
+#: config/tc-i386.c:849
+msgid "missing cpu architecture"
+msgstr ""
+
+#: config/tc-i386.c:863
+#, c-format
+msgid "no such architecture modifier: `%s'"
+msgstr ""
+
+#: config/tc-i386.c:880 config/tc-i386.c:5022
+msgid "Unknown architecture"
+msgstr ""
+
+#: config/tc-i386.c:915 config/tc-i386.c:938 config/tc-m68k.c:3816
+#, c-format
+msgid "Internal Error: Can't hash %s: %s"
+msgstr ""
+
+#: config/tc-i386.c:1192
+msgid "There are no unsigned pc-relative relocations"
+msgstr ""
+
+#: config/tc-i386.c:1199 config/tc-i386.c:5234
+#, c-format
+msgid "can not do %d byte pc-relative relocation"
+msgstr ""
+
+#: config/tc-i386.c:1216
+#, c-format
+msgid "can not do %s %d byte relocation"
+msgstr ""
+
+#: config/tc-i386.c:1428
+#, c-format
+msgid "can't use register '%%%s' as operand %d in '%s'."
+msgstr ""
+
+#. UnixWare fsub no args is alias for fsubp, fadd -> faddp, etc.
+#: config/tc-i386.c:1457
+#, c-format
+msgid "translating to `%sp'"
+msgstr ""
+
+#: config/tc-i386.c:1502
+#, c-format
+msgid "can't encode register '%%%s' in an instruction requiring REX prefix.\n"
+msgstr ""
+
+#: config/tc-i386.c:1541 config/tc-i386.c:1636
+#, c-format
+msgid "no such instruction: `%s'"
+msgstr ""
+
+#: config/tc-i386.c:1551 config/tc-i386.c:1668
+#, c-format
+msgid "invalid character %s in mnemonic"
+msgstr ""
+
+#: config/tc-i386.c:1558
+msgid "expecting prefix; got nothing"
+msgstr ""
+
+#: config/tc-i386.c:1560
+msgid "expecting mnemonic; got nothing"
+msgstr ""
+
+#: config/tc-i386.c:1579
+#, c-format
+msgid "redundant %s prefix"
+msgstr ""
+
+#: config/tc-i386.c:1677
+#, c-format
+msgid "`%s' is not supported on `%s'"
+msgstr ""
+
+#: config/tc-i386.c:1682
+msgid "use .code16 to ensure correct addressing mode"
+msgstr ""
+
+#: config/tc-i386.c:1689
+#, c-format
+msgid "expecting string instruction after `%s'"
+msgstr ""
+
+#: config/tc-i386.c:1717
+#, c-format
+msgid "invalid character %s before operand %d"
+msgstr ""
+
+#: config/tc-i386.c:1731
+#, c-format
+msgid "unbalanced parenthesis in operand %d."
+msgstr ""
+
+#: config/tc-i386.c:1734
+#, c-format
+msgid "unbalanced brackets in operand %d."
+msgstr ""
+
+#: config/tc-i386.c:1743
+#, c-format
+msgid "invalid character %s in operand %d"
+msgstr ""
+
+#: config/tc-i386.c:1770
+#, c-format
+msgid "spurious operands; (%d operands/instruction max)"
+msgstr ""
+
+#: config/tc-i386.c:1793
+msgid "expecting operand after ','; got nothing"
+msgstr ""
+
+#: config/tc-i386.c:1798
+msgid "expecting operand before ','; got nothing"
+msgstr ""
+
+#. We found no match.
+#: config/tc-i386.c:2140
+#, c-format
+msgid "suffix or operands invalid for `%s'"
+msgstr ""
+
+#: config/tc-i386.c:2151
+#, c-format
+msgid "indirect %s without `*'"
+msgstr ""
+
+#. Warn them that a data or address size prefix doesn't
+#. affect assembly of the next line of code.
+#: config/tc-i386.c:2159
+#, c-format
+msgid "stand-alone `%s' prefix"
+msgstr ""
+
+#: config/tc-i386.c:2188 config/tc-i386.c:2203
+#, c-format
+msgid "`%s' operand %d must use `%%es' segment"
+msgstr ""
+
+#: config/tc-i386.c:2283
+msgid ""
+"no instruction mnemonic suffix given and no register operands; can't size "
+"instruction"
+msgstr ""
+
+#. Prohibit these changes in the 64bit mode, since the
+#. lowering is more complicated.
+#: config/tc-i386.c:2367 config/tc-i386.c:2426 config/tc-i386.c:2443
+#: config/tc-i386.c:2475 config/tc-i386.c:2508
+#, c-format
+msgid "Incorrect register `%%%s' used with `%c' suffix"
+msgstr ""
+
+#: config/tc-i386.c:2375 config/tc-i386.c:2433 config/tc-i386.c:2515
+#, c-format
+msgid "using `%%%s' instead of `%%%s' due to `%c' suffix"
+msgstr ""
+
+#: config/tc-i386.c:2390 config/tc-i386.c:2411 config/tc-i386.c:2462
+#: config/tc-i386.c:2493
+#, c-format
+msgid "`%%%s' not allowed with `%s%c'"
+msgstr ""
+
+#: config/tc-i386.c:2556
+msgid "no instruction mnemonic suffix given; can't determine immediate size"
+msgstr ""
+
+#: config/tc-i386.c:2589
+#, c-format
+msgid ""
+"no instruction mnemonic suffix given; can't determine immediate size %x %c"
+msgstr ""
+
+#. Reversed arguments on faddp, fsubp, etc.
+#: config/tc-i386.c:2638
+#, c-format
+msgid "translating to `%s %%%s,%%%s'"
+msgstr ""
+
+#. Extraneous `l' suffix on fp insn.
+#: config/tc-i386.c:2645
+#, c-format
+msgid "translating to `%s %%%s'"
+msgstr ""
+
+#: config/tc-i386.c:2663
+#, c-format
+msgid "you can't `pop %%cs'"
+msgstr ""
+
+#. lea
+#: config/tc-i386.c:2682
+msgid "segment override on `lea' is ineffectual"
+msgstr ""
+
+#: config/tc-i386.c:2991 config/tc-i386.c:3085 config/tc-i386.c:3130
+msgid "skipping prefixes on this instruction"
+msgstr ""
+
+#: config/tc-i386.c:3150
+msgid "16-bit jump out of range"
+msgstr ""
+
+#: config/tc-i386.c:3159
+#, c-format
+msgid "can't handle non absolute segment in `%s'"
+msgstr ""
+
+#: config/tc-i386.c:3601
+#, c-format
+msgid "@%s reloc is not supported in %s bit mode"
+msgstr ""
+
+#: config/tc-i386.c:3677
+msgid "only 1 or 2 immediate operands are allowed"
+msgstr ""
+
+#: config/tc-i386.c:3700 config/tc-i386.c:3892
+#, c-format
+msgid "junk `%s' after expression"
+msgstr ""
+
+#. Missing or bad expr becomes absolute 0.
+#: config/tc-i386.c:3711
+#, c-format
+msgid "missing or invalid immediate expression `%s' taken as 0"
+msgstr ""
+
+#: config/tc-i386.c:3743 config/tc-i386.c:3958
+#, c-format
+msgid "unimplemented segment %s in operand"
+msgstr ""
+
+#: config/tc-i386.c:3745 config/tc-i386.c:3960
+#, c-format
+msgid "unimplemented segment type %d in operand"
+msgstr ""
+
+#: config/tc-i386.c:3789 config/tc-i386.c:6011
+#, c-format
+msgid "expecting scale factor of 1, 2, 4, or 8: got `%s'"
+msgstr ""
+
+#: config/tc-i386.c:3796
+#, c-format
+msgid "scale factor of %d without an index register"
+msgstr ""
+
+#: config/tc-i386.c:3912
+#, c-format
+msgid "bad expression used with @%s"
+msgstr ""
+
+#. Missing or bad expr becomes absolute 0.
+#: config/tc-i386.c:3934
+#, c-format
+msgid "missing or invalid displacement expression `%s' taken as 0"
+msgstr ""
+
+#: config/tc-i386.c:4058
+#, c-format
+msgid "`%s' is not a valid base/index expression"
+msgstr ""
+
+#: config/tc-i386.c:4062
+#, c-format
+msgid "`%s' is not a valid %s bit base/index expression"
+msgstr ""
+
+#: config/tc-i386.c:4137
+#, c-format
+msgid "bad memory operand `%s'"
+msgstr ""
+
+#: config/tc-i386.c:4152
+#, c-format
+msgid "junk `%s' after register"
+msgstr ""
+
+#: config/tc-i386.c:4161 config/tc-i386.c:4276 config/tc-i386.c:4314
+#, c-format
+msgid "bad register name `%s'"
+msgstr ""
+
+#: config/tc-i386.c:4169
+msgid "immediate operand illegal with absolute jump"
+msgstr ""
+
+#: config/tc-i386.c:4191
+#, c-format
+msgid "too many memory references for `%s'"
+msgstr ""
+
+#: config/tc-i386.c:4269
+#, c-format
+msgid "expecting `,' or `)' after index register in `%s'"
+msgstr ""
+
+#: config/tc-i386.c:4293
+#, c-format
+msgid "expecting `)' after scale factor in `%s'"
+msgstr ""
+
+#: config/tc-i386.c:4300
+#, c-format
+msgid "expecting index register or scale factor after `,'; got '%c'"
+msgstr ""
+
+#: config/tc-i386.c:4307
+#, c-format
+msgid "expecting `,' or `)' after base register in `%s'"
+msgstr ""
+
+#. It's not a memory operand; argh!
+#: config/tc-i386.c:4348
+#, c-format
+msgid "invalid char %s beginning operand %d `%s'"
+msgstr ""
+
+#: config/tc-i386.c:4531
+msgid "long jump required"
+msgstr ""
+
+#: config/tc-i386.c:4805
+msgid "Bad call to md_atof ()"
+msgstr ""
+
+#: config/tc-i386.c:4973
+msgid "No compiled in support for x86_64"
+msgstr ""
+
+#: config/tc-i386.c:4994
+msgid ""
+" -Q ignored\n"
+" -V print assembler version number\n"
+" -k ignored\n"
+" -n Do not optimize code alignment\n"
+" -q quieten some warnings\n"
+" -s ignored\n"
+msgstr ""
+
+#: config/tc-i386.c:5002
+msgid ""
+" -n Do not optimize code alignment\n"
+" -q quieten some warnings\n"
+msgstr ""
+
+#: config/tc-i386.c:5104 config/tc-s390.c:1841
+msgid "GOT already in symbol table"
+msgstr ""
+
+#: config/tc-i386.c:5249
+#, c-format
+msgid "can not do %d byte relocation"
+msgstr ""
+
+#: config/tc-i386.c:5317 config/tc-s390.c:2285
+#, c-format
+msgid "cannot represent relocation type %s"
+msgstr ""
+
+#: config/tc-i386.c:5613
+#, c-format
+msgid "too many memory references for '%s'"
+msgstr ""
+
+#: config/tc-i386.c:5776
+#, c-format
+msgid "Unknown operand modifier `%s'\n"
+msgstr ""
+
+#: config/tc-i386.c:5983
+#, c-format
+msgid "`%s' is not a valid segment register"
+msgstr ""
+
+#: config/tc-i386.c:5993 config/tc-i386.c:6114
+msgid "Register scaling only allowed in memory operands."
+msgstr ""
+
+#: config/tc-i386.c:6024
+msgid "Too many register references in memory operand.\n"
+msgstr ""
+
+#: config/tc-i386.c:6093
+#, c-format
+msgid "Syntax error. Expecting a constant. Got `%s'.\n"
+msgstr ""
+
+#: config/tc-i386.c:6163
+#, c-format
+msgid "Unrecognized token '%s'"
+msgstr ""
+
+#: config/tc-i386.c:6180
+#, c-format
+msgid "Unexpected token `%s'\n"
+msgstr ""
+
+#: config/tc-i386.c:6324
+#, c-format
+msgid "Unrecognized token `%s'\n"
+msgstr ""
+
+#: config/tc-i860.c:165 config/tc-i860.c:169
+msgid "Unknown temporary pseudo register"
+msgstr ""
+
+#: config/tc-i860.c:192 config/tc-mips.c:1105
+#, c-format
+msgid "internal error: can't hash `%s': %s\n"
+msgstr ""
+
+#: config/tc-i860.c:212
+msgid "Defective assembler. No assembly attempted."
+msgstr ""
+
+#: config/tc-i860.c:362
+#, c-format
+msgid "Expanded opcode after delayed branch: `%s'"
+msgstr ""
+
+#: config/tc-i860.c:366
+#, c-format
+msgid "Expanded opcode in dual mode: `%s'"
+msgstr ""
+
+#: config/tc-i860.c:370
+#, c-format
+msgid "An instruction was expanded (%s)"
+msgstr ""
+
+#: config/tc-i860.c:643
+msgid "Pipelined instruction: fsrc1 = fdest"
+msgstr ""
+
+#: config/tc-i860.c:844 config/tc-i860.c:851 config/tc-i860.c:858
+msgid "Assembler does not yet support PIC"
+msgstr ""
+
+#: config/tc-i860.c:919
+#, c-format
+msgid "Illegal operands for %s"
+msgstr ""
+
+#: config/tc-i860.c:947 config/tc-sparc.c:2834
+msgid "bad segment"
+msgstr ""
+
+#: config/tc-i860.c:1037
+msgid "i860_estimate_size_before_relax\n"
+msgstr ""
+
+#: config/tc-i860.c:1134
+msgid ""
+" -EL\t\t\t generate code for little endian mode (default)\n"
+" -EB\t\t\t generate code for big endian mode\n"
+" -mwarn-expand\t\t warn if pseudo operations are expanded\n"
+" -mxp\t\t\t enable i860XP support (disabled by default)\n"
+msgstr ""
+
+#. SVR4 compatibility flags.
+#: config/tc-i860.c:1141
+msgid ""
+" -V\t\t\t print assembler version number\n"
+" -Qy, -Qn\t\t ignored\n"
+msgstr ""
+
+#: config/tc-i860.c:1210
+msgid "This immediate requires 0 MOD 2 alignment"
+msgstr ""
+
+#: config/tc-i860.c:1213
+msgid "This immediate requires 0 MOD 4 alignment"
+msgstr ""
+
+#: config/tc-i860.c:1216
+msgid "This immediate requires 0 MOD 8 alignment"
+msgstr ""
+
+#: config/tc-i860.c:1219
+msgid "This immediate requires 0 MOD 16 alignment"
+msgstr ""
+
+#: config/tc-i860.c:1317
+msgid "5-bit immediate too large"
+msgstr ""
+
+#: config/tc-i860.c:1320
+msgid "5-bit field must be absolute"
+msgstr ""
+
+#: config/tc-i860.c:1365 config/tc-i860.c:1388
+msgid "A branch offset requires 0 MOD 4 alignment"
+msgstr ""
+
+#: config/tc-i860.c:1409
+#, c-format
+msgid "Unrecognized fix-up (0x%08lx)"
+msgstr ""
+
+#: config/tc-i860.h:80
+msgid "i860_convert_frag\n"
+msgstr ""
+
+#: config/tc-i960.c:574
+#, c-format
+msgid "Hashing returned \"%s\"."
+msgstr ""
+
+#. Offset of last character in opcode mnemonic
+#: config/tc-i960.c:608
+msgid "branch prediction invalid on this opcode"
+msgstr ""
+
+#: config/tc-i960.c:648
+#, c-format
+msgid "invalid opcode, \"%s\"."
+msgstr ""
+
+#: config/tc-i960.c:653
+#, c-format
+msgid "improper number of operands. expecting %d, got %d"
+msgstr ""
+
+#: config/tc-i960.c:877
+#, c-format
+msgid "Fixup of %ld too large for field width of %d"
+msgstr ""
+
+#: config/tc-i960.c:994
+#, c-format
+msgid "invalid architecture %s"
+msgstr ""
+
+#: config/tc-i960.c:1014
+msgid "I960 options:\n"
+msgstr ""
+
+#: config/tc-i960.c:1017
+msgid ""
+"\n"
+"\t\t\tspecify variant of 960 architecture\n"
+"-b\t\t\tadd code to collect statistics about branches taken\n"
+"-link-relax\t\tpreserve individual alignment directives so linker\n"
+"\t\t\tcan do relaxing (b.out format only)\n"
+"-no-relax\t\tdon't alter compare-and-branch instructions for\n"
+"\t\t\tlong displacements\n"
+msgstr ""
+
+#: config/tc-i960.c:1419 config/tc-xtensa.c:8604
+msgid "too many operands"
+msgstr ""
+
+#: config/tc-i960.c:1477 config/tc-i960.c:1702
+msgid "expression syntax error"
+msgstr ""
+
+#: config/tc-i960.c:1515
+msgid "attempt to branch into different segment"
+msgstr ""
+
+#: config/tc-i960.c:1519
+#, c-format
+msgid "target of %s instruction must be a label"
+msgstr ""
+
+#: config/tc-i960.c:1557
+msgid "unmatched '['"
+msgstr ""
+
+#: config/tc-i960.c:1568
+msgid "garbage after index spec ignored"
+msgstr ""
+
+#. We never moved: there was no opcode either!
+#: config/tc-i960.c:1633
+msgid "missing opcode"
+msgstr ""
+
+#: config/tc-i960.c:2046
+msgid "invalid index register"
+msgstr ""
+
+#: config/tc-i960.c:2069
+msgid "invalid scale factor"
+msgstr ""
+
+#: config/tc-i960.c:2250
+msgid "unaligned register"
+msgstr ""
+
+#: config/tc-i960.c:2273
+msgid "no such sfr in this architecture"
+msgstr ""
+
+#: config/tc-i960.c:2311
+msgid "illegal literal"
+msgstr ""
+
+#. Should not happen: see block comment above
+#: config/tc-i960.c:2539
+#, c-format
+msgid "Trying to 'bal' to %s"
+msgstr ""
+
+#: config/tc-i960.c:2550
+msgid "Looks like a proc, but can't tell what kind.\n"
+msgstr ""
+
+#: config/tc-i960.c:2582
+msgid "should have 1 or 2 operands"
+msgstr ""
+
+#: config/tc-i960.c:2591 config/tc-i960.c:2610
+#, c-format
+msgid "Redefining leafproc %s"
+msgstr ""
+
+#: config/tc-i960.c:2641
+msgid "should have two operands"
+msgstr ""
+
+#: config/tc-i960.c:2651
+msgid "'entry_num' must be absolute number in [0,31]"
+msgstr ""
+
+#: config/tc-i960.c:2660
+#, c-format
+msgid "Redefining entrynum for sysproc %s"
+msgstr ""
+
+#: config/tc-i960.c:2764
+msgid "architecture of opcode conflicts with that of earlier instruction(s)"
+msgstr ""
+
+#: config/tc-i960.c:2785
+msgid "big endian mode is not supported"
+msgstr ""
+
+#: config/tc-i960.c:2787
+#, c-format
+msgid "ignoring unrecognized .endian type `%s'"
+msgstr ""
+
+#: config/tc-i960.c:3071
+#, c-format
+msgid "leafproc symbol '%s' undefined"
+msgstr ""
+
+#: config/tc-i960.c:3081
+#, c-format
+msgid "Warning: making leafproc entries %s and %s both global\n"
+msgstr ""
+
+#: config/tc-i960.c:3190
+msgid "option --link-relax is only supported in b.out format"
+msgstr ""
+
+#: config/tc-ia64.c:982
+msgid "Bad .section directive: want a,o,s,w,x,M,S,G,T in string"
+msgstr ""
+
+#: config/tc-ia64.c:1105
+msgid "Unwind directive not followed by an instruction."
+msgstr ""
+
+#: config/tc-ia64.c:4563
+msgid "Register name expected"
+msgstr ""
+
+#: config/tc-ia64.c:4568 config/tc-ia64.c:4854
+msgid "Comma expected"
+msgstr ""
+
+#: config/tc-ia64.c:4576
+msgid "Register value annotation ignored"
+msgstr ""
+
+#: config/tc-ia64.c:4600
+msgid "Directive invalid within a bundle"
+msgstr ""
+
+#: config/tc-ia64.c:4667
+msgid "Missing predicate relation type"
+msgstr ""
+
+#: config/tc-ia64.c:4683
+msgid "Unrecognized predicate relation type"
+msgstr ""
+
+#: config/tc-ia64.c:4703 config/tc-ia64.c:4728
+msgid "Predicate register expected"
+msgstr ""
+
+#: config/tc-ia64.c:4715
+msgid "Duplicate predicate register ignored"
+msgstr ""
+
+#: config/tc-ia64.c:4737
+msgid "Bad register range"
+msgstr ""
+
+#: config/tc-ia64.c:4765
+msgid "Predicate source and target required"
+msgstr ""
+
+#: config/tc-ia64.c:4767 config/tc-ia64.c:4779
+msgid "Use of p0 is not valid in this context"
+msgstr ""
+
+#: config/tc-ia64.c:4774
+msgid "At least two PR arguments expected"
+msgstr ""
+
+#: config/tc-ia64.c:4788
+msgid "At least one PR argument expected"
+msgstr ""
+
+#: config/tc-ia64.c:4824
+#, c-format
+msgid "Inserting \"%s\" into entry hint table failed: %s"
+msgstr ""
+
+#. FIXME -- need 62-bit relocation type
+#: config/tc-ia64.c:5302
+msgid "62-bit relocation not yet implemented"
+msgstr ""
+
+#. XXX technically, this is wrong: we should not be issuing warning
+#. messages until we're sure this instruction pattern is going to
+#. be used!
+#: config/tc-ia64.c:5375
+msgid "lower 16 bits of mask ignored"
+msgstr ""
+
+#: config/tc-ia64.c:5939
+msgid "Value truncated to 62 bits"
+msgstr ""
+
+#: config/tc-ia64.c:6291
+msgid ""
+"Additional NOP may be necessary to workaround Itanium processor A/B step "
+"errata"
+msgstr ""
+
+#: config/tc-ia64.c:6474
+#, c-format
+msgid "Unrecognized option '-x%s'"
+msgstr ""
+
+#: config/tc-ia64.c:6502
+msgid ""
+"IA-64 options:\n"
+" --mconstant-gp\t mark output file as using the constant-GP model\n"
+"\t\t\t (sets ELF header flag EF_IA_64_CONS_GP)\n"
+" --mauto-pic\t\t mark output file as using the constant-GP model\n"
+"\t\t\t without function descriptors (sets ELF header flag\n"
+"\t\t\t EF_IA_64_NOFUNCDESC_CONS_GP)\n"
+" -milp32|-milp64|-mlp64|-mp64\tselect data model (default -mlp64)\n"
+" -mle | -mbe\t\t select little- or big-endian byte order (default -mle)\n"
+" -x | -xexplicit\t turn on dependency violation checking (default)\n"
+" -xauto\t\t automagically remove dependency violations\n"
+" -xdebug\t\t debug dependency violation checker\n"
+msgstr ""
+
+#: config/tc-ia64.c:6521
+msgid "--gstabs is not supported for ia64"
+msgstr ""
+
+#: config/tc-ia64.c:6824 config/tc-mips.c:1094
+msgid "Could not set architecture and machine"
+msgstr ""
+
+#: config/tc-ia64.c:6931
+msgid "Explicit stops are ignored in auto mode"
+msgstr ""
+
+#: config/tc-ia64.c:6981
+msgid "Found '{' after explicit switch to automatic mode"
+msgstr ""
+
+#: config/tc-ia64.c:7428
+#, c-format
+msgid "Unhandled dependency %s for %s (%s), note %d"
+msgstr ""
+
+#: config/tc-ia64.c:8704
+#, c-format
+msgid "Unrecognized dependency specifier %d\n"
+msgstr ""
+
+#: config/tc-ia64.c:9506
+msgid "Only the first path encountering the conflict is reported"
+msgstr ""
+
+#: config/tc-ia64.c:9509
+msgid "This is the location of the conflicting usage"
+msgstr ""
+
+#: config/tc-ia64.c:10778 read.c:1370 read.c:1976 read.c:2184 read.c:2795
+msgid "expected symbol name"
+msgstr ""
+
+#: config/tc-ia64.c:10788 read.c:1380 read.c:2194 read.c:2805 stabs.c:478
+#, c-format
+msgid "expected comma after \"%s\""
+msgstr ""
+
+#: config/tc-ia64.c:10829
+#, c-format
+msgid "`%s' is already the alias of %s `%s'"
+msgstr ""
+
+#: config/tc-ia64.c:10839
+#, c-format
+msgid "%s `%s' already has an alias `%s'"
+msgstr ""
+
+#: config/tc-ia64.c:10850
+#, c-format
+msgid "inserting \"%s\" into %s alias hash table failed: %s"
+msgstr ""
+
+#: config/tc-ia64.c:10858
+#, c-format
+msgid "inserting \"%s\" into %s name hash table failed: %s"
+msgstr ""
+
+#: config/tc-ia64.c:10877
+#, c-format
+msgid "symbol `%s' aliased to `%s' is not used"
+msgstr ""
+
+#: config/tc-ia64.c:10899
+#, c-format
+msgid "section `%s' aliased to `%s' is not used"
+msgstr ""
+
+#: config/tc-ip2k.c:123
+msgid "IP2K specific command line options:\n"
+msgstr ""
+
+#: config/tc-ip2k.c:124
+msgid " -mip2022 restrict to IP2022 insns \n"
+msgstr ""
+
+#: config/tc-ip2k.c:125
+msgid " -mip2022ext permit extended IP2022 insn\n"
+msgstr ""
+
+#: config/tc-ip2k.c:246
+msgid "md_pcrel_from\n"
+msgstr ""
+
+#. Pretend that we do not recognise this option.
+#: config/tc-m32r.c:233
+msgid "Unrecognised option: -hidden"
+msgstr ""
+
+#: config/tc-m32r.c:267
+msgid " M32R specific command line options:\n"
+msgstr ""
+
+#: config/tc-m32r.c:269
+msgid ""
+" -m32r disable support for the m32rx instruction set\n"
+msgstr ""
+
+#: config/tc-m32r.c:271
+msgid " -m32rx support the extended m32rx instruction set\n"
+msgstr ""
+
+#: config/tc-m32r.c:273
+msgid " -O try to combine instructions in parallel\n"
+msgstr ""
+
+#: config/tc-m32r.c:276
+msgid ""
+" -warn-explicit-parallel-conflicts warn when parallel instructions\n"
+msgstr ""
+
+#: config/tc-m32r.c:278
+msgid " violate contraints\n"
+msgstr ""
+
+#: config/tc-m32r.c:280
+msgid " -no-warn-explicit-parallel-conflicts do not warn when parallel\n"
+msgstr ""
+
+#: config/tc-m32r.c:282
+msgid ""
+" instructions violate contraints\n"
+msgstr ""
+
+#: config/tc-m32r.c:284
+msgid ""
+" -Wp synonym for -warn-explicit-parallel-conflicts\n"
+msgstr ""
+
+#: config/tc-m32r.c:286
+msgid ""
+" -Wnp synonym for -no-warn-explicit-parallel-conflicts\n"
+msgstr ""
+
+#: config/tc-m32r.c:289
+msgid ""
+" -warn-unmatched-high warn when an (s)high reloc has no matching low "
+"reloc\n"
+msgstr ""
+
+#: config/tc-m32r.c:291
+msgid " -no-warn-unmatched-high do not warn about missing low relocs\n"
+msgstr ""
+
+#: config/tc-m32r.c:293
+msgid " -Wuh synonym for -warn-unmatched-high\n"
+msgstr ""
+
+#: config/tc-m32r.c:295
+msgid " -Wnuh synonym for -no-warn-unmatched-high\n"
+msgstr ""
+
+#: config/tc-m32r.c:299
+msgid " -relax create linker relaxable code\n"
+msgstr ""
+
+#: config/tc-m32r.c:301
+msgid " -cpu-desc provide runtime cpu description file\n"
+msgstr ""
+
+#: config/tc-m32r.c:700
+msgid "Instructions write to the same destination register."
+msgstr ""
+
+#: config/tc-m32r.c:708
+msgid "Instructions do not use parallel execution pipelines."
+msgstr ""
+
+#: config/tc-m32r.c:715
+msgid "Instructions share the same execution pipeline"
+msgstr ""
+
+#: config/tc-m32r.c:791 config/tc-m32r.c:887
+#, c-format
+msgid "not a 16 bit instruction '%s'"
+msgstr ""
+
+#: config/tc-m32r.c:798 config/tc-m32r.c:894 config/tc-m32r.c:1050
+#, c-format
+msgid "unknown instruction '%s'"
+msgstr ""
+
+#: config/tc-m32r.c:807 config/tc-m32r.c:901 config/tc-m32r.c:1057
+#, c-format
+msgid "instruction '%s' is for the M32RX only"
+msgstr ""
+
+#: config/tc-m32r.c:816 config/tc-m32r.c:910
+#, c-format
+msgid "instruction '%s' cannot be executed in parallel."
+msgstr ""
+
+#: config/tc-m32r.c:871 config/tc-m32r.c:935 config/tc-m32r.c:1107
+msgid "internal error: lookup/get operands failed"
+msgstr ""
+
+#: config/tc-m32r.c:920
+#, c-format
+msgid "'%s': only the NOP instruction can be issued in parallel on the m32r"
+msgstr ""
+
+#: config/tc-m32r.c:949
+#, c-format
+msgid ""
+"%s: output of 1st instruction is the same as an input to 2nd instruction - "
+"is this intentional ?"
+msgstr ""
+
+#: config/tc-m32r.c:953
+#, c-format
+msgid ""
+"%s: output of 2nd instruction is the same as an input to 1st instruction - "
+"is this intentional ?"
+msgstr ""
+
+#: config/tc-m32r.c:1267 config/tc-ppc.c:1732 config/tc-ppc.c:4263
+msgid "Expected comma after symbol-name: rest of line ignored."
+msgstr ""
+
+#: config/tc-m32r.c:1277
+#, c-format
+msgid ".SCOMMon length (%ld.) <0! Ignored."
+msgstr ""
+
+#: config/tc-m32r.c:1291 config/tc-ppc.c:1754 config/tc-ppc.c:2899
+#: config/tc-ppc.c:4287
+msgid "ignoring bad alignment"
+msgstr ""
+
+#: config/tc-m32r.c:1303 config/tc-ppc.c:1791 config/tc-v850.c:335
+msgid "Common alignment not a power of 2"
+msgstr ""
+
+#: config/tc-m32r.c:1318 config/tc-ppc.c:1765 config/tc-ppc.c:4299
+#, c-format
+msgid "Ignoring attempt to re-define symbol `%s'."
+msgstr ""
+
+#: config/tc-m32r.c:1327
+#, c-format
+msgid "Length of .scomm \"%s\" is already %ld. Not changed to %ld."
+msgstr ""
+
+#: config/tc-m32r.c:1808
+msgid "Unmatched high/shigh reloc"
+msgstr ""
+
+#: config/tc-m68hc11.c:372
+#, c-format
+msgid ""
+"Motorola 68HC11/68HC12/68HCS12 options:\n"
+" -m68hc11 | -m68hc12 |\n"
+" -m68hcs12 specify the processor [default %s]\n"
+" -mshort use 16-bit int ABI (default)\n"
+" -mlong use 32-bit int ABI\n"
+" -mshort-double use 32-bit double ABI\n"
+" -mlong-double use 64-bit double ABI (default)\n"
+" --force-long-branchs always turn relative branchs into absolute ones\n"
+" -S,--short-branchs do not turn relative branchs into absolute ones\n"
+" when the offset is out of range\n"
+" --strict-direct-mode do not turn the direct mode into extended mode\n"
+" when the instruction does not support direct mode\n"
+" --print-insn-syntax print the syntax of instruction in case of error\n"
+" --print-opcodes print the list of instructions with syntax\n"
+" --generate-example generate an example of each instruction\n"
+" (used for testing)\n"
+msgstr ""
+
+#: config/tc-m68hc11.c:418
+#, c-format
+msgid "Default target `%s' is not supported."
+msgstr ""
+
+#. Dump the opcode statistics table.
+#: config/tc-m68hc11.c:437
+msgid "Name # Modes Min ops Max ops Modes mask # Used\n"
+msgstr ""
+
+#: config/tc-m68hc11.c:505
+#, c-format
+msgid "Option `%s' is not recognized."
+msgstr ""
+
+#: config/tc-m68hc11.c:737
+msgid "#<imm8>"
+msgstr ""
+
+#: config/tc-m68hc11.c:746
+msgid "#<imm16>"
+msgstr ""
+
+#: config/tc-m68hc11.c:755 config/tc-m68hc11.c:764
+msgid "<imm8>,X"
+msgstr ""
+
+#: config/tc-m68hc11.c:791
+msgid "*<abs8>"
+msgstr ""
+
+#: config/tc-m68hc11.c:803
+msgid "#<mask>"
+msgstr ""
+
+#: config/tc-m68hc11.c:813
+#, c-format
+msgid "symbol%d"
+msgstr ""
+
+#: config/tc-m68hc11.c:815
+msgid "<abs>"
+msgstr ""
+
+#: config/tc-m68hc11.c:834
+msgid "<label>"
+msgstr ""
+
+#: config/tc-m68hc11.c:850
+#, c-format
+msgid ""
+"# Example of `%s' instructions\n"
+"\t.sect .text\n"
+"_start:\n"
+msgstr ""
+
+#: config/tc-m68hc11.c:898
+#, c-format
+msgid "Instruction `%s' is not recognized."
+msgstr ""
+
+#: config/tc-m68hc11.c:903
+#, c-format
+msgid "Instruction formats for `%s':"
+msgstr ""
+
+#: config/tc-m68hc11.c:1038
+#, c-format
+msgid "Immediate operand is not allowed for operand %d."
+msgstr ""
+
+#: config/tc-m68hc11.c:1082
+msgid "Indirect indexed addressing is not valid for 68HC11."
+msgstr ""
+
+#: config/tc-m68hc11.c:1102
+msgid "Spurious `,' or bad indirect register addressing mode."
+msgstr ""
+
+#: config/tc-m68hc11.c:1124
+msgid "Missing second register or offset for indexed-indirect mode."
+msgstr ""
+
+#: config/tc-m68hc11.c:1134
+msgid "Missing second register for indexed-indirect mode."
+msgstr ""
+
+#: config/tc-m68hc11.c:1150
+msgid "Missing `]' to close indexed-indirect mode."
+msgstr ""
+
+#: config/tc-m68hc11.c:1195
+msgid "Illegal operand."
+msgstr ""
+
+#: config/tc-m68hc11.c:1200
+msgid "Missing operand."
+msgstr ""
+
+#: config/tc-m68hc11.c:1253
+msgid "Pre-increment mode is not valid for 68HC11"
+msgstr ""
+
+#: config/tc-m68hc11.c:1266
+msgid "Wrong register in register indirect mode."
+msgstr ""
+
+#: config/tc-m68hc11.c:1274
+msgid "Missing `]' to close register indirect operand."
+msgstr ""
+
+#: config/tc-m68hc11.c:1294
+msgid "Post-decrement mode is not valid for 68HC11."
+msgstr ""
+
+#: config/tc-m68hc11.c:1302
+msgid "Post-increment mode is not valid for 68HC11."
+msgstr ""
+
+#: config/tc-m68hc11.c:1320
+msgid "Invalid indexed indirect mode."
+msgstr ""
+
+#: config/tc-m68hc11.c:1417
+#, c-format
+msgid "Trap id `%ld' is out of range."
+msgstr ""
+
+#: config/tc-m68hc11.c:1421
+msgid "Trap id must be within [0x30..0x39] or [0x40..0xff]."
+msgstr ""
+
+#: config/tc-m68hc11.c:1428
+#, c-format
+msgid "Operand out of 8-bit range: `%ld'."
+msgstr ""
+
+#: config/tc-m68hc11.c:1435
+msgid "The trap id must be a constant."
+msgstr ""
+
+#: config/tc-m68hc11.c:1470
+#, c-format
+msgid "Operand `%x' not recognized in fixup8."
+msgstr ""
+
+#: config/tc-m68hc11.c:1490 config/tc-m68hc11.c:1542
+#, c-format
+msgid "Operand out of 16-bit range: `%ld'."
+msgstr ""
+
+#: config/tc-m68hc11.c:1522 config/tc-m68hc11.c:1558
+#, c-format
+msgid "Operand `%x' not recognized in fixup16."
+msgstr ""
+
+#: config/tc-m68hc11.c:1576
+#, c-format
+msgid "Unexpected branch conversion with `%x'"
+msgstr ""
+
+#: config/tc-m68hc11.c:1671 config/tc-m68hc11.c:1812
+#, c-format
+msgid "Operand out of range for a relative branch: `%ld'"
+msgstr ""
+
+#: config/tc-m68hc11.c:1780
+msgid "Invalid register for dbcc/tbcc instruction."
+msgstr ""
+
+#: config/tc-m68hc11.c:1871
+#, c-format
+msgid "Increment/decrement value is out of range: `%ld'."
+msgstr ""
+
+#: config/tc-m68hc11.c:1882
+msgid "Expecting a register."
+msgstr ""
+
+#: config/tc-m68hc11.c:1897
+msgid "Invalid register for post/pre increment."
+msgstr ""
+
+#: config/tc-m68hc11.c:1927
+msgid "Invalid register."
+msgstr ""
+
+#: config/tc-m68hc11.c:1934
+#, c-format
+msgid "Offset out of 16-bit range: %ld."
+msgstr ""
+
+#: config/tc-m68hc11.c:1939
+#, c-format
+msgid "Offset out of 5-bit range for movw/movb insn: %ld."
+msgstr ""
+
+#: config/tc-m68hc11.c:2020
+msgid "Expecting register D for indexed indirect mode."
+msgstr ""
+
+#: config/tc-m68hc11.c:2022
+msgid "Indexed indirect mode is not allowed for movb/movw."
+msgstr ""
+
+#: config/tc-m68hc11.c:2039
+msgid "Invalid accumulator register."
+msgstr ""
+
+#: config/tc-m68hc11.c:2064
+msgid "Invalid indexed register."
+msgstr ""
+
+#: config/tc-m68hc11.c:2072
+msgid "Addressing mode not implemented yet."
+msgstr ""
+
+#: config/tc-m68hc11.c:2087
+msgid "Invalid source register for this instruction, use 'tfr'."
+msgstr ""
+
+#: config/tc-m68hc11.c:2089
+msgid "Invalid source register."
+msgstr ""
+
+#: config/tc-m68hc11.c:2094
+msgid "Invalid destination register for this instruction, use 'tfr'."
+msgstr ""
+
+#: config/tc-m68hc11.c:2096
+msgid "Invalid destination register."
+msgstr ""
+
+#: config/tc-m68hc11.c:2194
+msgid "Invalid indexed register, expecting register X."
+msgstr ""
+
+#: config/tc-m68hc11.c:2196
+msgid "Invalid indexed register, expecting register Y."
+msgstr ""
+
+#: config/tc-m68hc11.c:2508
+msgid "No instruction or missing opcode."
+msgstr ""
+
+#: config/tc-m68hc11.c:2573
+#, c-format
+msgid "Opcode `%s' is not recognized."
+msgstr ""
+
+#: config/tc-m68hc11.c:2595
+#, c-format
+msgid "Garbage at end of instruction: `%s'."
+msgstr ""
+
+#: config/tc-m68hc11.c:2618
+#, c-format
+msgid "Invalid operand for `%s'"
+msgstr ""
+
+#: config/tc-m68hc11.c:2670
+#, c-format
+msgid "Invalid mode: %s\n"
+msgstr ""
+
+#: config/tc-m68hc11.c:2732
+msgid "bad .relax format"
+msgstr ""
+
+#: config/tc-m68hc11.c:2779
+#, c-format
+msgid "Relocation %d is not supported by object file format."
+msgstr ""
+
+#: config/tc-m68hc11.c:3065
+msgid "bra or bsr with undefined symbol."
+msgstr ""
+
+#: config/tc-m68hc11.c:3168 config/tc-m68hc11.c:3225
+#, c-format
+msgid "Subtype %d is not recognized."
+msgstr ""
+
+#: config/tc-m68hc11.c:3289
+msgid "Expression too complex."
+msgstr ""
+
+#: config/tc-m68hc11.c:3322
+msgid "Value out of 16-bit range."
+msgstr ""
+
+#: config/tc-m68hc11.c:3346
+#, c-format
+msgid "Value %ld too large for 8-bit PC-relative branch."
+msgstr ""
+
+#: config/tc-m68hc11.c:3353
+#, c-format
+msgid "Auto increment/decrement offset '%ld' is out of range."
+msgstr ""
+
+#: config/tc-m68hc11.c:3371
+#, c-format
+msgid "Line %d: unknown relocation type: 0x%x."
+msgstr ""
+
+#: config/tc-m68k.c:678
+msgid "Unknown PC relative instruction"
+msgstr ""
+
+#: config/tc-m68k.c:817
+#, c-format
+msgid "Can not do %d byte pc-relative relocation"
+msgstr ""
+
+#: config/tc-m68k.c:819
+#, c-format
+msgid "Can not do %d byte pc-relative pic relocation"
+msgstr ""
+
+#: config/tc-m68k.c:824
+#, c-format
+msgid "Can not do %d byte relocation"
+msgstr ""
+
+#: config/tc-m68k.c:826
+#, c-format
+msgid "Can not do %d byte pic relocation"
+msgstr ""
+
+#: config/tc-m68k.c:894
+#, c-format
+msgid "Unable to produce reloc against symbol '%s'"
+msgstr ""
+
+#: config/tc-m68k.c:938 config/tc-mips.c:13322 config/tc-vax.c:3441
+#, c-format
+msgid "Cannot make %s relocation PC relative"
+msgstr ""
+
+#: config/tc-m68k.c:1031 config/tc-tahoe.c:1495 config/tc-vax.c:1889
+msgid "No operator"
+msgstr ""
+
+#: config/tc-m68k.c:1061 config/tc-tahoe.c:1512 config/tc-vax.c:1906
+msgid "Unknown operator"
+msgstr ""
+
+#: config/tc-m68k.c:1836
+msgid "invalid instruction for this architecture; needs "
+msgstr ""
+
+#: config/tc-m68k.c:1841
+msgid "fpu (68040, 68060 or 68881/68882)"
+msgstr ""
+
+#: config/tc-m68k.c:1844
+msgid "mmu (68030 or 68851)"
+msgstr ""
+
+#: config/tc-m68k.c:1847
+msgid "68020 or higher"
+msgstr ""
+
+#: config/tc-m68k.c:1850
+msgid "68000 or higher"
+msgstr ""
+
+#: config/tc-m68k.c:1853
+msgid "68010 or higher"
+msgstr ""
+
+#: config/tc-m68k.c:1882
+msgid "operands mismatch"
+msgstr ""
+
+#: config/tc-m68k.c:1939 config/tc-m68k.c:1945 config/tc-m68k.c:1951
+#: config/tc-mmix.c:2464 config/tc-mmix.c:2488
+msgid "operand out of range"
+msgstr ""
+
+#: config/tc-m68k.c:2008
+#, c-format
+msgid "Bignum too big for %c format; truncated"
+msgstr ""
+
+#: config/tc-m68k.c:2076
+msgid "displacement too large for this architecture; needs 68020 or higher"
+msgstr ""
+
+#: config/tc-m68k.c:2186
+msgid ""
+"scale factor invalid on this architecture; needs cpu32 or 68020 or higher"
+msgstr ""
+
+#: config/tc-m68k.c:2191
+msgid "invalid index size for coldfire"
+msgstr ""
+
+#: config/tc-m68k.c:2244
+msgid "Forcing byte displacement"
+msgstr ""
+
+#: config/tc-m68k.c:2246
+msgid "byte displacement out of range"
+msgstr ""
+
+#: config/tc-m68k.c:2293 config/tc-m68k.c:2331
+msgid "invalid operand mode for this architecture; needs 68020 or higher"
+msgstr ""
+
+#: config/tc-m68k.c:2317 config/tc-m68k.c:2351
+msgid ":b not permitted; defaulting to :w"
+msgstr ""
+
+#: config/tc-m68k.c:2428
+msgid "unsupported byte value; use a different suffix"
+msgstr ""
+
+#: config/tc-m68k.c:2442
+msgid "unknown/incorrect operand"
+msgstr ""
+
+#: config/tc-m68k.c:2475 config/tc-m68k.c:2483 config/tc-m68k.c:2490
+#: config/tc-m68k.c:2497
+msgid "out of range"
+msgstr ""
+
+#: config/tc-m68k.c:2543
+msgid "Can't use long branches on 68000/68010/5200"
+msgstr ""
+
+#: config/tc-m68k.c:2653
+msgid "Expression out of range, using 0"
+msgstr ""
+
+#: config/tc-m68k.c:2765 config/tc-m68k.c:2781
+msgid "Floating point register in register list"
+msgstr ""
+
+#: config/tc-m68k.c:2771
+msgid "Wrong register in floating-point reglist"
+msgstr ""
+
+#: config/tc-m68k.c:2787
+msgid "incorrect register in reglist"
+msgstr ""
+
+#: config/tc-m68k.c:2793
+msgid "wrong register in floating-point reglist"
+msgstr ""
+
+#. ERROR
+#: config/tc-m68k.c:3234
+msgid "Extra )"
+msgstr ""
+
+#. ERROR
+#: config/tc-m68k.c:3245
+msgid "Missing )"
+msgstr ""
+
+#: config/tc-m68k.c:3262
+msgid "Missing operand"
+msgstr ""
+
+#: config/tc-m68k.c:3594
+#, c-format
+msgid "%s -- statement `%s' ignored"
+msgstr ""
+
+#: config/tc-m68k.c:3643
+#, c-format
+msgid "Don't know how to figure width of %c in md_assemble()"
+msgstr ""
+
+#: config/tc-m68k.c:3825 config/tc-m68k.c:3863
+#, c-format
+msgid "Internal Error: Can't find %s in hash table"
+msgstr ""
+
+#: config/tc-m68k.c:3828 config/tc-m68k.c:3866
+#, c-format
+msgid "Internal Error: Can't hash %s: %s"
+msgstr ""
+
+#: config/tc-m68k.c:3948
+msgid "architecture not yet selected: defaulting to 68020"
+msgstr ""
+
+#: config/tc-m68k.c:3997
+#, c-format
+msgid "unrecognized default cpu `%s' ???"
+msgstr ""
+
+#: config/tc-m68k.c:4009
+msgid "68040 and 68851 specified; mmu instructions may assemble incorrectly"
+msgstr ""
+
+#: config/tc-m68k.c:4029
+msgid "options for 68881 and no-68881 both given"
+msgstr ""
+
+#: config/tc-m68k.c:4031
+msgid "options for 68851 and no-68851 both given"
+msgstr ""
+
+#: config/tc-m68k.c:4102
+#, c-format
+msgid "text label `%s' aligned to odd boundary"
+msgstr ""
+
+#: config/tc-m68k.c:4321
+msgid "invalid byte branch offset"
+msgstr ""
+
+#: config/tc-m68k.c:4358
+msgid "short branch with zero offset: use :w"
+msgstr ""
+
+#: config/tc-m68k.c:4827 config/tc-m68k.c:4838
+msgid "expression out of range: defaulting to 1"
+msgstr ""
+
+#: config/tc-m68k.c:4870
+msgid "expression out of range: defaulting to 0"
+msgstr ""
+
+#: config/tc-m68k.c:4903 config/tc-m68k.c:4915
+#, c-format
+msgid "Can't deal with expression; defaulting to %ld"
+msgstr ""
+
+#: config/tc-m68k.c:4929
+msgid "expression doesn't fit in BYTE"
+msgstr ""
+
+#: config/tc-m68k.c:4933
+msgid "expression doesn't fit in WORD"
+msgstr ""
+
+#: config/tc-m68k.c:5026
+#, c-format
+msgid "%s: unrecognized processor name"
+msgstr ""
+
+#: config/tc-m68k.c:5091
+msgid "bad coprocessor id"
+msgstr ""
+
+#: config/tc-m68k.c:5097
+msgid "unrecognized fopt option"
+msgstr ""
+
+#: config/tc-m68k.c:5231
+#, c-format
+msgid "option `%s' may not be negated"
+msgstr ""
+
+#: config/tc-m68k.c:5242
+#, c-format
+msgid "option `%s' not recognized"
+msgstr ""
+
+#: config/tc-m68k.c:5275
+msgid "bad format of OPT NEST=depth"
+msgstr ""
+
+#: config/tc-m68k.c:5338
+msgid "missing label"
+msgstr ""
+
+#: config/tc-m68k.c:5362 config/tc-m68k.c:5391
+msgid "bad register list"
+msgstr ""
+
+#: config/tc-m68k.c:5364
+#, c-format
+msgid "bad register list: %s"
+msgstr ""
+
+#: config/tc-m68k.c:5462
+msgid "restore without save"
+msgstr ""
+
+#: config/tc-m68k.c:5636 config/tc-m68k.c:6023
+msgid "syntax error in structured control directive"
+msgstr ""
+
+#: config/tc-m68k.c:5685
+msgid "missing condition code in structured control directive"
+msgstr ""
+
+#: config/tc-m68k.c:5757
+#, c-format
+msgid ""
+"Condition <%c%c> in structured control directive can not be encoded correctly"
+msgstr ""
+
+#: config/tc-m68k.c:6066
+msgid "missing then"
+msgstr ""
+
+#: config/tc-m68k.c:6148
+msgid "else without matching if"
+msgstr ""
+
+#: config/tc-m68k.c:6182
+msgid "endi without matching if"
+msgstr ""
+
+#: config/tc-m68k.c:6223
+msgid "break outside of structured loop"
+msgstr ""
+
+#: config/tc-m68k.c:6262
+msgid "next outside of structured loop"
+msgstr ""
+
+#: config/tc-m68k.c:6314
+msgid "missing ="
+msgstr ""
+
+#: config/tc-m68k.c:6352
+msgid "missing to or downto"
+msgstr ""
+
+#: config/tc-m68k.c:6388 config/tc-m68k.c:6422 config/tc-m68k.c:6641
+msgid "missing do"
+msgstr ""
+
+#: config/tc-m68k.c:6525
+msgid "endf without for"
+msgstr ""
+
+#: config/tc-m68k.c:6581
+msgid "until without repeat"
+msgstr ""
+
+#: config/tc-m68k.c:6677
+msgid "endw without while"
+msgstr ""
+
+#: config/tc-m68k.c:6801
+#, c-format
+msgid "unrecognized option `%s'"
+msgstr ""
+
+#: config/tc-m68k.c:6846
+#, c-format
+msgid "unrecognized architecture specification `%s'"
+msgstr ""
+
+#: config/tc-m68k.c:6940
+#, c-format
+msgid ""
+"680X0 options:\n"
+"-l\t\t\tuse 1 word for refs to undefined symbols [default 2]\n"
+"-m68000 | -m68008 | -m68010 | -m68020 | -m68030 | -m68040 | -m68060 |\n"
+"-m68302 | -m68331 | -m68332 | -m68333 | -m68340 | -m68360 | -mcpu32 |\n"
+"-m5200 | -m5202 | -m5204 | -m5206 | -m5206e | -m5307 | -m5407\n"
+"\t\t\tspecify variant of 680X0 architecture [default %s]\n"
+"-m68881 | -m68882 | -mno-68881 | -mno-68882\n"
+"\t\t\ttarget has/lacks floating-point coprocessor\n"
+"\t\t\t[default yes for 68020, 68030, and cpu32]\n"
+msgstr ""
+
+#: config/tc-m68k.c:6951
+msgid ""
+"-m68851 | -mno-68851\n"
+"\t\t\ttarget has/lacks memory-management unit coprocessor\n"
+"\t\t\t[default yes for 68020 and up]\n"
+"-pic, -k\t\tgenerate position independent code\n"
+"-S\t\t\tturn jbsr into jsr\n"
+"--pcrel never turn PC-relative branches into absolute jumps\n"
+"--register-prefix-optional\n"
+"\t\t\trecognize register names without prefix character\n"
+"--bitwise-or\t\tdo not treat `|' as a comment character\n"
+msgstr ""
+
+#: config/tc-m68k.c:6961
+msgid ""
+"--base-size-default-16\tbase reg without size is 16 bits\n"
+"--base-size-default-32\tbase reg without size is 32 bits (default)\n"
+"--disp-size-default-16\tdisplacement with unknown size is 16 bits\n"
+"--disp-size-default-32\tdisplacement with unknown size is 32 bits (default)\n"
+msgstr ""
+
+#: config/tc-m68k.c:6996
+#, c-format
+msgid "Error %s in %s\n"
+msgstr ""
+
+#: config/tc-m68k.c:7000
+#, c-format
+msgid "Opcode(%d.%s): "
+msgstr ""
+
+#: config/tc-m88k.c:201
+#, c-format
+msgid "Can't hash instruction '%s':%s"
+msgstr ""
+
+#: config/tc-m88k.c:250
+#, c-format
+msgid "Invalid mnemonic '%s'"
+msgstr ""
+
+#: config/tc-m88k.c:268
+msgid "Parameter syntax error"
+msgstr ""
+
+#: config/tc-m88k.c:321
+msgid "Unknown relocation type"
+msgstr ""
+
+#. Having this here repeats the warning somtimes.
+#. But can't we stand that?
+#: config/tc-m88k.c:434
+msgid "Use of obsolete instruction"
+msgstr ""
+
+#: config/tc-m88k.c:551
+msgid "Expression truncated to 16 bits"
+msgstr ""
+
+#: config/tc-m88k.c:617 config/tc-m88k.c:639
+msgid "Expression truncated to 5 bits"
+msgstr ""
+
+#: config/tc-m88k.c:856
+msgid "Expression truncated to 9 bits"
+msgstr ""
+
+#: config/tc-m88k.c:878
+msgid "Removed lower 2 bits of expression"
+msgstr ""
+
+#: config/tc-m88k.c:1057
+msgid "Relaxation should never occur"
+msgstr ""
+
+#: config/tc-m88k.h:78
+msgid "m88k convert_frag\n"
+msgstr ""
+
+#: config/tc-mcore.c:460
+#, c-format
+msgid "register expected, but saw '%.6s'"
+msgstr ""
+
+#: config/tc-mcore.c:544
+#, c-format
+msgid "control register expected, but saw '%.6s'"
+msgstr ""
+
+#: config/tc-mcore.c:582
+msgid "bad/missing psr specifier"
+msgstr ""
+
+#: config/tc-mcore.c:743
+msgid "more than 65K literal pools"
+msgstr ""
+
+#: config/tc-mcore.c:797
+msgid "missing ']'"
+msgstr ""
+
+#: config/tc-mcore.c:837
+msgid "operand must be a constant"
+msgstr ""
+
+#: config/tc-mcore.c:839
+#, c-format
+msgid "operand must be absolute in range %u..%u, not %ld"
+msgstr ""
+
+#: config/tc-mcore.c:875
+msgid "operand must be a multiple of 4"
+msgstr ""
+
+#: config/tc-mcore.c:882
+msgid "operand must be a multiple of 2"
+msgstr ""
+
+#: config/tc-mcore.c:896 config/tc-mcore.c:1410 config/tc-mcore.c:1464
+msgid "base register expected"
+msgstr ""
+
+#: config/tc-mcore.c:945
+#, c-format
+msgid "unknown opcode \"%s\""
+msgstr ""
+
+#: config/tc-mcore.c:988
+msgid "invalid register: r15 illegal"
+msgstr ""
+
+#: config/tc-mcore.c:1036 config/tc-mcore.c:1614
+msgid "M340 specific opcode used when assembling for M210"
+msgstr ""
+
+#: config/tc-mcore.c:1054 config/tc-mcore.c:1093 config/tc-mcore.c:1112
+#: config/tc-mcore.c:1131 config/tc-mcore.c:1158 config/tc-mcore.c:1187
+#: config/tc-mcore.c:1224 config/tc-mcore.c:1259 config/tc-mcore.c:1278
+#: config/tc-mcore.c:1297 config/tc-mcore.c:1331 config/tc-mcore.c:1356
+#: config/tc-mcore.c:1413 config/tc-mcore.c:1467 config/tc-mcore.c:1503
+#: config/tc-mcore.c:1561 config/tc-mcore.c:1583 config/tc-mcore.c:1606
+msgid "second operand missing"
+msgstr ""
+
+#: config/tc-mcore.c:1069
+msgid "destination register must be r1"
+msgstr ""
+
+#: config/tc-mcore.c:1090
+msgid "source register must be r1"
+msgstr ""
+
+#: config/tc-mcore.c:1153 config/tc-mcore.c:1210
+msgid "immediate is not a power of two"
+msgstr ""
+
+#: config/tc-mcore.c:1181
+msgid "translating bgeni to movi"
+msgstr ""
+
+#: config/tc-mcore.c:1218
+msgid "translating mgeni to movi"
+msgstr ""
+
+#: config/tc-mcore.c:1250
+msgid "translating bmaski to movi"
+msgstr ""
+
+#: config/tc-mcore.c:1326
+#, c-format
+msgid "displacement too large (%d)"
+msgstr ""
+
+#: config/tc-mcore.c:1340
+msgid "Invalid register: r0 and r15 illegal"
+msgstr ""
+
+#: config/tc-mcore.c:1371
+msgid "bad starting register: r0 and r15 invalid"
+msgstr ""
+
+#: config/tc-mcore.c:1384
+msgid "ending register must be r15"
+msgstr ""
+
+#: config/tc-mcore.c:1404
+msgid "bad base register: must be r0"
+msgstr ""
+
+#: config/tc-mcore.c:1422
+msgid "first register must be r4"
+msgstr ""
+
+#: config/tc-mcore.c:1433
+msgid "last register must be r7"
+msgstr ""
+
+#: config/tc-mcore.c:1470
+msgid "reg-reg expected"
+msgstr ""
+
+#: config/tc-mcore.c:1580
+msgid "second operand must be 1"
+msgstr ""
+
+#: config/tc-mcore.c:1601
+msgid "zero used as immediate value"
+msgstr ""
+
+#: config/tc-mcore.c:1628
+msgid "duplicated psr bit specifier"
+msgstr ""
+
+#: config/tc-mcore.c:1634
+msgid "`af' must appear alone"
+msgstr ""
+
+#: config/tc-mcore.c:1641
+#, c-format
+msgid "unimplemented opcode \"%s\""
+msgstr ""
+
+#: config/tc-mcore.c:1650
+#, c-format
+msgid "ignoring operands: %s "
+msgstr ""
+
+#: config/tc-mcore.c:1718 config/tc-w65.c:772
+msgid "Bad call to MD_NTOF()"
+msgstr ""
+
+#: config/tc-mcore.c:1788
+#, c-format
+msgid "unrecognised cpu type '%s'"
+msgstr ""
+
+#: config/tc-mcore.c:1807
+msgid ""
+"MCORE specific options:\n"
+" -{no-}jsri2bsr\t {dis}able jsri to bsr transformation (def: dis)\n"
+" -{no-}sifilter\t {dis}able silicon filter behavior (def: dis)\n"
+" -cpu=[210|340] select CPU type\n"
+" -EB assemble for a big endian system (default)\n"
+" -EL assemble for a little endian system\n"
+msgstr ""
+
+#: config/tc-mcore.c:1826
+msgid "failed sanity check: short_jump"
+msgstr ""
+
+#: config/tc-mcore.c:1837
+msgid "failed sanity check: long_jump"
+msgstr ""
+
+#: config/tc-mcore.c:1863
+#, c-format
+msgid "odd displacement at %x"
+msgstr ""
+
+#: config/tc-mcore.c:2047
+msgid "unknown"
+msgstr ""
+
+#: config/tc-mcore.c:2073
+#, c-format
+msgid "odd distance branch (0x%lx bytes)"
+msgstr ""
+
+#: config/tc-mcore.c:2077
+#, c-format
+msgid "pcrel for branch to %s too far (0x%lx)"
+msgstr ""
+
+#: config/tc-mcore.c:2096
+#, c-format
+msgid "pcrel for lrw/jmpi/jsri to %s too far (0x%lx)"
+msgstr ""
+
+#: config/tc-mcore.c:2107
+#, c-format
+msgid "pcrel for loopt too far (0x%lx)"
+msgstr ""
+
+#: config/tc-mcore.c:2336
+#, c-format
+msgid "Can not do %d byte %srelocation"
+msgstr ""
+
+#: config/tc-mcore.c:2338
+msgid "pc-relative"
+msgstr ""
+
+#. Prototypes for static functions.
+#: config/tc-mips.c:818
+#, c-format
+msgid "internal Error, line %d, %s"
+msgstr ""
+
+#: config/tc-mips.c:1131
+#, c-format
+msgid "internal: can't hash `%s': %s"
+msgstr ""
+
+#: config/tc-mips.c:1139
+#, c-format
+msgid "internal error: bad mips16 opcode: %s %s\n"
+msgstr ""
+
+#: config/tc-mips.c:1332
+#, c-format
+msgid "returned from mips_ip(%s) insn_opcode = 0x%x\n"
+msgstr ""
+
+#: config/tc-mips.c:1976 config/tc-mips.c:13666
+msgid "extended instruction in delay slot"
+msgstr ""
+
+#: config/tc-mips.c:2022 config/tc-mips.c:2032
+#, c-format
+msgid "jump to misaligned address (0x%lx)"
+msgstr ""
+
+#: config/tc-mips.c:2025 config/tc-mips.c:2035
+#, c-format
+msgid "jump address range overflow (0x%lx)"
+msgstr ""
+
+#: config/tc-mips.c:2805 config/tc-mips.c:3194
+msgid "Macro instruction expanded into multiple instructions"
+msgstr ""
+
+#: config/tc-mips.c:2817
+msgid ""
+"Macro instruction expanded into multiple instructions in a branch delay slot"
+msgstr ""
+
+#: config/tc-mips.c:3225 config/tc-mips.c:7549 config/tc-mips.c:7575
+#: config/tc-mips.c:7653 config/tc-mips.c:7678
+msgid "operand overflow"
+msgstr ""
+
+#: config/tc-mips.c:3251 config/tc-mips.c:6902 config/tc-mips.c:7754
+msgid "Macro used $at after \".set noat\""
+msgstr ""
+
+#: config/tc-mips.c:3281
+msgid "unsupported large constant"
+msgstr ""
+
+#: config/tc-mips.c:3283
+#, c-format
+msgid "Instruction %s requires absolute expression"
+msgstr ""
+
+#: config/tc-mips.c:3422
+#, c-format
+msgid "Number (0x%lx) larger than 32 bits"
+msgstr ""
+
+#: config/tc-mips.c:3444
+msgid "Number larger than 64 bits"
+msgstr ""
+
+#: config/tc-mips.c:3747 config/tc-mips.c:3787 config/tc-mips.c:3829
+#: config/tc-mips.c:3886 config/tc-mips.c:6069 config/tc-mips.c:6111
+#: config/tc-mips.c:6163 config/tc-mips.c:6661 config/tc-mips.c:6716
+msgid "PIC code offset overflow (max 16 signed bits)"
+msgstr ""
+
+#: config/tc-mips.c:4146
+#, c-format
+msgid "Branch %s is always false (nop)"
+msgstr ""
+
+#: config/tc-mips.c:4153
+#, c-format
+msgid "Branch likely %s is always false"
+msgstr ""
+
+#: config/tc-mips.c:4160 config/tc-mips.c:4228 config/tc-mips.c:4320
+#: config/tc-mips.c:4369 config/tc-mips.c:7857 config/tc-mips.c:7865
+#: config/tc-mips.c:7872 config/tc-mips.c:7979
+msgid "Unsupported large constant"
+msgstr ""
+
+#. result is always true
+#: config/tc-mips.c:4194
+#, c-format
+msgid "Branch %s is always true"
+msgstr ""
+
+#: config/tc-mips.c:4437 config/tc-mips.c:4540
+msgid "Divide by zero."
+msgstr ""
+
+#: config/tc-mips.c:4622
+msgid "dla used to load 32-bit register"
+msgstr ""
+
+#: config/tc-mips.c:4625
+msgid "la used to load 64-bit address"
+msgstr ""
+
+#: config/tc-mips.c:5000 config/tc-mips.c:5353
+msgid "PIC code offset overflow (max 32 signed bits)"
+msgstr ""
+
+#: config/tc-mips.c:5419
+msgid "MIPS PIC call to register other than $25"
+msgstr ""
+
+#: config/tc-mips.c:5425 config/tc-mips.c:5436 config/tc-mips.c:5574
+#: config/tc-mips.c:5585
+msgid "No .cprestore pseudo-op used in PIC code"
+msgstr ""
+
+#: config/tc-mips.c:5430 config/tc-mips.c:5579
+msgid "No .frame pseudo-op used in PIC code"
+msgstr ""
+
+#: config/tc-mips.c:5657 config/tc-mips.c:5746 config/tc-mips.c:6414
+#: config/tc-mips.c:6453 config/tc-mips.c:6471 config/tc-mips.c:7221
+msgid "opcode not supported on this processor"
+msgstr ""
+
+#: config/tc-mips.c:5970
+msgid "load/store address overflow (max 32 bits)"
+msgstr ""
+
+#: config/tc-mips.c:7084 config/tc-mips.c:7117 config/tc-mips.c:7167
+#: config/tc-mips.c:7199
+msgid "Improper rotate count"
+msgstr ""
+
+#: config/tc-mips.c:7260
+#, c-format
+msgid "Instruction %s: result is always false"
+msgstr ""
+
+#: config/tc-mips.c:7418
+#, c-format
+msgid "Instruction %s: result is always true"
+msgstr ""
+
+#. FIXME: Check if this is one of the itbl macros, since they
+#. are added dynamically.
+#: config/tc-mips.c:7750
+#, c-format
+msgid "Macro %s not implemented yet"
+msgstr ""
+
+#: config/tc-mips.c:8010
+#, c-format
+msgid "internal: bad mips opcode (mask error): %s %s"
+msgstr ""
+
+#: config/tc-mips.c:8030 config/tc-mips.c:8361
+#, c-format
+msgid "internal: bad mips opcode (unknown extension operand type `+%c'): %s %s"
+msgstr ""
+
+#: config/tc-mips.c:8091
+#, c-format
+msgid "internal: bad mips opcode (unknown operand type `%c'): %s %s"
+msgstr ""
+
+#: config/tc-mips.c:8098
+#, c-format
+msgid "internal: bad mips opcode (bits 0x%lx undefined): %s %s"
+msgstr ""
+
+#: config/tc-mips.c:8212
+#, c-format
+msgid "opcode not supported on this processor: %s (%s)"
+msgstr ""
+
+#: config/tc-mips.c:8293
+#, c-format
+msgid "Improper position (%lu)"
+msgstr ""
+
+#: config/tc-mips.c:8319
+#, c-format
+msgid "Improper insert size (%lu, position %lu)"
+msgstr ""
+
+#: config/tc-mips.c:8345
+#, c-format
+msgid "Improper extract size (%lu, position %lu)"
+msgstr ""
+
+#: config/tc-mips.c:8379
+#, c-format
+msgid "Improper shift amount (%lu)"
+msgstr ""
+
+#: config/tc-mips.c:8405 config/tc-mips.c:9655 config/tc-mips.c:9770
+#, c-format
+msgid "Invalid value for `%s' (%lu)"
+msgstr ""
+
+#: config/tc-mips.c:8423
+#, c-format
+msgid "Illegal break code (%lu)"
+msgstr ""
+
+#: config/tc-mips.c:8437
+#, c-format
+msgid "Illegal lower break code (%lu)"
+msgstr ""
+
+#: config/tc-mips.c:8450
+#, c-format
+msgid "Illegal 20-bit code (%lu)"
+msgstr ""
+
+#: config/tc-mips.c:8462
+#, c-format
+msgid "Coproccesor code > 25 bits (%lu)"
+msgstr ""
+
+#: config/tc-mips.c:8475
+#, c-format
+msgid "Illegal 19-bit code (%lu)"
+msgstr ""
+
+#: config/tc-mips.c:8487
+#, c-format
+msgid "Invalid performance register (%lu)"
+msgstr ""
+
+#: config/tc-mips.c:8525
+#, c-format
+msgid "Invalid register number (%d)"
+msgstr ""
+
+#: config/tc-mips.c:8703
+#, c-format
+msgid "Invalid MDMX Immediate (%ld)"
+msgstr ""
+
+#: config/tc-mips.c:8746
+#, c-format
+msgid "Invalid float register number (%d)"
+msgstr ""
+
+#: config/tc-mips.c:8756
+#, c-format
+msgid "Float register should be even, was %d"
+msgstr ""
+
+#: config/tc-mips.c:8795
+#, c-format
+msgid "Bad element selector %ld"
+msgstr ""
+
+#: config/tc-mips.c:8802
+#, c-format
+msgid "Expecting ']' found '%s'"
+msgstr ""
+
+#: config/tc-mips.c:8844
+msgid "absolute expression required"
+msgstr ""
+
+#: config/tc-mips.c:8912
+#, c-format
+msgid "Bad floating point constant: %s"
+msgstr ""
+
+#: config/tc-mips.c:9040
+msgid "Can't use floating point insn in this section"
+msgstr ""
+
+#: config/tc-mips.c:9101
+msgid "expression out of range"
+msgstr ""
+
+#: config/tc-mips.c:9141
+msgid "lui expression not in range 0..65535"
+msgstr ""
+
+#: config/tc-mips.c:9165
+#, c-format
+msgid "invalid condition code register $fcc%d"
+msgstr ""
+
+#: config/tc-mips.c:9190
+msgid "invalid coprocessor sub-selection value (0-7)"
+msgstr ""
+
+#: config/tc-mips.c:9202 config/tc-mips.c:9219
+#, c-format
+msgid "bad byte vector index (%ld)"
+msgstr ""
+
+#: config/tc-mips.c:9230
+#, c-format
+msgid "bad char = '%c'\n"
+msgstr ""
+
+#: config/tc-mips.c:9241 config/tc-mips.c:9246 config/tc-mips.c:9795
+msgid "illegal operands"
+msgstr ""
+
+#: config/tc-mips.c:9311
+msgid "unrecognized opcode"
+msgstr ""
+
+#: config/tc-mips.c:9423
+#, c-format
+msgid "invalid register number (%d)"
+msgstr ""
+
+#: config/tc-mips.c:9514
+msgid "used $at without \".set noat\""
+msgstr ""
+
+#: config/tc-mips.c:9689
+msgid "can't parse register list"
+msgstr ""
+
+#: config/tc-mips.c:9913
+msgid "extended operand requested but not required"
+msgstr ""
+
+#: config/tc-mips.c:9915
+msgid "invalid unextended operand value"
+msgstr ""
+
+#: config/tc-mips.c:9943
+msgid "operand value out of range for instruction"
+msgstr ""
+
+#: config/tc-mips.c:10341
+#, c-format
+msgid "A different %s was already specified, is now %s"
+msgstr ""
+
+#: config/tc-mips.c:10502
+msgid "-G may not be used with embedded PIC code"
+msgstr ""
+
+#: config/tc-mips.c:10531
+msgid "-call_shared is supported only for ELF format"
+msgstr ""
+
+#: config/tc-mips.c:10538 config/tc-mips.c:11849 config/tc-mips.c:12087
+msgid "-G may not be used with SVR4 PIC code"
+msgstr ""
+
+#: config/tc-mips.c:10547
+msgid "-non_shared is supported only for ELF format"
+msgstr ""
+
+#: config/tc-mips.c:10565
+msgid "-G is not supported for this configuration"
+msgstr ""
+
+#: config/tc-mips.c:10570
+msgid "-G may not be used with SVR4 or embedded PIC code"
+msgstr ""
+
+#: config/tc-mips.c:10584
+msgid "-32 is supported for ELF format only"
+msgstr ""
+
+#: config/tc-mips.c:10593
+msgid "-n32 is supported for ELF format only"
+msgstr ""
+
+#: config/tc-mips.c:10602
+msgid "-64 is supported for ELF format only"
+msgstr ""
+
+#: config/tc-mips.c:10607 config/tc-mips.c:10644
+msgid "No compiled in support for 64 bit object file format"
+msgstr ""
+
+#: config/tc-mips.c:10631
+msgid "-mabi is supported for ELF format only"
+msgstr ""
+
+#: config/tc-mips.c:10651
+#, c-format
+msgid "invalid abi -mabi=%s"
+msgstr ""
+
+#: config/tc-mips.c:10718
+msgid "-G not supported in this configuration."
+msgstr ""
+
+#: config/tc-mips.c:10744
+#, c-format
+msgid "-%s conflicts with the other architecture options, which imply -%s"
+msgstr ""
+
+#: config/tc-mips.c:10775
+msgid "-mgp64 used with a 32-bit processor"
+msgstr ""
+
+#: config/tc-mips.c:10777
+msgid "-mgp32 used with a 64-bit ABI"
+msgstr ""
+
+#: config/tc-mips.c:10779
+msgid "-mgp64 used with a 32-bit ABI"
+msgstr ""
+
+#: config/tc-mips.c:10809
+msgid "trap exception not supported at ISA 1"
+msgstr ""
+
+#: config/tc-mips.c:10957
+#, c-format
+msgid "Unmatched %%hi reloc"
+msgstr ""
+
+#: config/tc-mips.c:11049
+msgid "Cannot branch to undefined symbol."
+msgstr ""
+
+#: config/tc-mips.c:11056
+msgid "Cannot branch to symbol in another section."
+msgstr ""
+
+#: config/tc-mips.c:11065
+msgid "Pretending global symbol used as branch target is local."
+msgstr ""
+
+#: config/tc-mips.c:11230
+msgid "Invalid PC relative reloc"
+msgstr ""
+
+#: config/tc-mips.c:11325 config/tc-sparc.c:3185 config/tc-sparc.c:3192
+#: config/tc-sparc.c:3199 config/tc-sparc.c:3206 config/tc-sparc.c:3213
+#: config/tc-sparc.c:3222 config/tc-sparc.c:3233 config/tc-sparc.c:3255
+#: config/tc-sparc.c:3279 write.c:998 write.c:1070
+msgid "relocation overflow"
+msgstr ""
+
+#: config/tc-mips.c:11335
+#, c-format
+msgid "Branch to odd address (%lx)"
+msgstr ""
+
+#: config/tc-mips.c:11384
+msgid "Branch out of range"
+msgstr ""
+
+#: config/tc-mips.c:11491
+#, c-format
+msgid "%08lx UNDEFINED\n"
+msgstr ""
+
+#: config/tc-mips.c:11550
+#, c-format
+msgid "Alignment too large: %d. assumed."
+msgstr ""
+
+#: config/tc-mips.c:11553
+msgid "Alignment negative: 0 assumed."
+msgstr ""
+
+#: config/tc-mips.c:11640
+msgid "No read only data section in this object file format"
+msgstr ""
+
+#: config/tc-mips.c:11663
+msgid "Global pointers not supported; recompile -G 0"
+msgstr ""
+
+#: config/tc-mips.c:11805
+#, c-format
+msgid "%s: no such section"
+msgstr ""
+
+#: config/tc-mips.c:11844
+#, c-format
+msgid ".option pic%d not supported"
+msgstr ""
+
+#: config/tc-mips.c:11855
+#, c-format
+msgid "Unrecognized option \"%s\""
+msgstr ""
+
+#: config/tc-mips.c:11917
+msgid "`noreorder' must be set before `nomacro'"
+msgstr ""
+
+#: config/tc-mips.c:11989
+#, c-format
+msgid "unknown architecture %s"
+msgstr ""
+
+#: config/tc-mips.c:11997 config/tc-mips.c:12018
+#, c-format
+msgid "unknown ISA level %s"
+msgstr ""
+
+#: config/tc-mips.c:12046
+msgid ".set pop with no .set push"
+msgstr ""
+
+#: config/tc-mips.c:12070
+#, c-format
+msgid "Tried to set unrecognized symbol: %s\n"
+msgstr ""
+
+#: config/tc-mips.c:12120
+msgid ".cpload not in noreorder section"
+msgstr ""
+
+#: config/tc-mips.c:12176 config/tc-mips.c:12195
+msgid "missing argument separator ',' for .cpsetup"
+msgstr ""
+
+#: config/tc-mips.c:12373
+msgid "Unsupported use of .gpword"
+msgstr ""
+
+#: config/tc-mips.c:12409
+msgid "Unsupported use of .gpdword"
+msgstr ""
+
+#: config/tc-mips.c:12544
+msgid "expected `$'"
+msgstr ""
+
+#: config/tc-mips.c:12552
+msgid "Bad register number"
+msgstr ""
+
+#: config/tc-mips.c:12600
+msgid "Unrecognized register name"
+msgstr ""
+
+#: config/tc-mips.c:12835
+msgid "unsupported PC relative reference to different section"
+msgstr ""
+
+#: config/tc-mips.c:12948
+msgid "unsupported relocation"
+msgstr ""
+
+#: config/tc-mips.c:13063
+msgid "AT used after \".set noat\" or macro used after \".set nomacro\""
+msgstr ""
+
+#: config/tc-mips.c:13126
+msgid "Double check fx_r_type in tc-mips.c:tc_gen_reloc"
+msgstr ""
+
+#: config/tc-mips.c:13341 config/tc-sh.c:3800
+#, c-format
+msgid "Can not represent %s relocation in this object file format"
+msgstr ""
+
+#: config/tc-mips.c:13430
+msgid "relaxed out-of-range branch into a jump"
+msgstr ""
+
+#: config/tc-mips.c:13903
+msgid "missing .end at end of assembly"
+msgstr ""
+
+#: config/tc-mips.c:13918
+msgid "expected simple number"
+msgstr ""
+
+#: config/tc-mips.c:13944
+#, c-format
+msgid " *input_line_pointer == '%c' 0x%02x\n"
+msgstr ""
+
+#: config/tc-mips.c:13946
+msgid "invalid number"
+msgstr ""
+
+#: config/tc-mips.c:14019
+msgid ".end not in text section"
+msgstr ""
+
+#: config/tc-mips.c:14023
+msgid ".end directive without a preceding .ent directive."
+msgstr ""
+
+#: config/tc-mips.c:14032
+msgid ".end symbol does not match .ent symbol."
+msgstr ""
+
+#: config/tc-mips.c:14039
+msgid ".end directive missing or unknown symbol"
+msgstr ""
+
+#: config/tc-mips.c:14099
+msgid ".ent or .aent not in text section."
+msgstr ""
+
+#: config/tc-mips.c:14102
+msgid "missing .end"
+msgstr ""
+
+#: config/tc-mips.c:14154
+msgid "Bad .frame directive"
+msgstr ""
+
+#: config/tc-mips.c:14186
+msgid ".mask/.fmask outside of .ent"
+msgstr ""
+
+#: config/tc-mips.c:14193
+msgid "Bad .mask/.fmask directive"
+msgstr ""
+
+#: config/tc-mips.c:14472
+msgid ""
+"MIPS options:\n"
+"-membedded-pic\t\tgenerate embedded position independent code\n"
+"-EB\t\t\tgenerate big endian output\n"
+"-EL\t\t\tgenerate little endian output\n"
+"-g, -g2\t\t\tdo not remove unneeded NOPs or swap branches\n"
+"-G NUM\t\t\tallow referencing objects up to NUM bytes\n"
+"\t\t\timplicitly with the gp register [default 8]\n"
+msgstr ""
+
+#: config/tc-mips.c:14480
+msgid ""
+"-mips1\t\t\tgenerate MIPS ISA I instructions\n"
+"-mips2\t\t\tgenerate MIPS ISA II instructions\n"
+"-mips3\t\t\tgenerate MIPS ISA III instructions\n"
+"-mips4\t\t\tgenerate MIPS ISA IV instructions\n"
+"-mips5 generate MIPS ISA V instructions\n"
+"-mips32 generate MIPS32 ISA instructions\n"
+"-mips32r2 generate MIPS32 release 2 ISA instructions\n"
+"-mips64 generate MIPS64 ISA instructions\n"
+"-march=CPU/-mtune=CPU\tgenerate code/schedule for CPU, where CPU is one of:\n"
+msgstr ""
+
+#: config/tc-mips.c:14498
+msgid ""
+"-mCPU\t\t\tequivalent to -march=CPU -mtune=CPU. Deprecated.\n"
+"-no-mCPU\t\tdon't generate code specific to CPU.\n"
+"\t\t\tFor -mCPU and -no-mCPU, CPU must be one of:\n"
+msgstr ""
+
+#: config/tc-mips.c:14511
+msgid ""
+"-mips16\t\t\tgenerate mips16 instructions\n"
+"-no-mips16\t\tdo not generate mips16 instructions\n"
+msgstr ""
+
+#: config/tc-mips.c:14514
+msgid ""
+"-mgp32\t\t\tuse 32-bit GPRs, regardless of the chosen ISA\n"
+"-mfp32\t\t\tuse 32-bit FPRs, regardless of the chosen ISA\n"
+"-O0\t\t\tremove unneeded NOPs, do not swap branches\n"
+"-O\t\t\tremove unneeded NOPs and swap branches\n"
+"-n\t\t\twarn about NOPs generated from macros\n"
+"--[no-]construct-floats [dis]allow floating point values to be constructed\n"
+"--trap, --no-break\ttrap exception on div by 0 and mult overflow\n"
+"--break, --no-trap\tbreak exception on div by 0 and mult overflow\n"
+msgstr ""
+
+#: config/tc-mips.c:14524
+msgid ""
+"-KPIC, -call_shared\tgenerate SVR4 position independent code\n"
+"-non_shared\t\tdo not generate position independent code\n"
+"-xgot\t\t\tassume a 32 bit GOT\n"
+"-mabi=ABI\t\tcreate ABI conformant object file for:\n"
+msgstr ""
+
+#: config/tc-mips.c:14540
+msgid ""
+"-32\t\t\tcreate o32 ABI object file (default)\n"
+"-n32\t\t\tcreate n32 ABI object file\n"
+"-64\t\t\tcreate 64 ABI object file\n"
+msgstr ""
+
+#: config/tc-mmix.c:677
+msgid " MMIX-specific command line options:\n"
+msgstr ""
+
+#: config/tc-mmix.c:678
+msgid ""
+" -fixed-special-register-names\n"
+" Allow only the original special register names.\n"
+msgstr ""
+
+#: config/tc-mmix.c:681
+msgid " -globalize-symbols Make all symbols global.\n"
+msgstr ""
+
+#: config/tc-mmix.c:683
+msgid " -gnu-syntax Turn off mmixal syntax compatibility.\n"
+msgstr ""
+
+#: config/tc-mmix.c:685
+msgid " -relax Create linker relaxable code.\n"
+msgstr ""
+
+#: config/tc-mmix.c:687
+msgid ""
+" -no-predefined-syms Do not provide mmixal built-in constants.\n"
+" Implies -fixed-special-register-names.\n"
+msgstr ""
+
+#: config/tc-mmix.c:690
+msgid ""
+" -no-expand Do not expand GETA, branches, PUSHJ or JUMP\n"
+" into multiple instructions.\n"
+msgstr ""
+
+#: config/tc-mmix.c:693
+msgid ""
+" -no-merge-gregs Do not merge GREG definitions with nearby values.\n"
+msgstr ""
+
+#: config/tc-mmix.c:695
+msgid ""
+" -linker-allocated-gregs If there's no suitable GREG definition for "
+"the operands of an instruction, let the linker "
+"resolve.\n"
+msgstr ""
+
+#: config/tc-mmix.c:698
+msgid ""
+" -x Do not warn when an operand to GETA, a branch,\n"
+" PUSHJ or JUMP is not known to be within range.\n"
+" The linker will catch any errors. Implies\n"
+" -linker-allocated-gregs."
+msgstr ""
+
+#: config/tc-mmix.c:825
+#, c-format
+msgid "unknown opcode: `%s'"
+msgstr ""
+
+#: config/tc-mmix.c:947 config/tc-mmix.c:962
+msgid "specified location wasn't TETRA-aligned"
+msgstr ""
+
+#: config/tc-mmix.c:949 config/tc-mmix.c:964 config/tc-mmix.c:4015
+#: config/tc-mmix.c:4031
+msgid "unaligned data at an absolute location is not supported"
+msgstr ""
+
+#: config/tc-mmix.c:1074
+#, c-format
+msgid "invalid operand to opcode %s: `%s'"
+msgstr ""
+
+#: config/tc-mmix.c:1096 config/tc-mmix.c:1123 config/tc-mmix.c:1156
+#: config/tc-mmix.c:1164 config/tc-mmix.c:1181 config/tc-mmix.c:1209
+#: config/tc-mmix.c:1230 config/tc-mmix.c:1255 config/tc-mmix.c:1303
+#: config/tc-mmix.c:1401 config/tc-mmix.c:1426 config/tc-mmix.c:1458
+#: config/tc-mmix.c:1490 config/tc-mmix.c:1520 config/tc-mmix.c:1573
+#: config/tc-mmix.c:1590 config/tc-mmix.c:1617 config/tc-mmix.c:1645
+#: config/tc-mmix.c:1672 config/tc-mmix.c:1698 config/tc-mmix.c:1714
+#: config/tc-mmix.c:1740 config/tc-mmix.c:1756 config/tc-mmix.c:1772
+#: config/tc-mmix.c:1835 config/tc-mmix.c:1851
+#, c-format
+msgid "invalid operands to opcode %s: `%s'"
+msgstr ""
+
+#: config/tc-mmix.c:1828
+#, c-format
+msgid "unsupported operands to %s: `%s'"
+msgstr ""
+
+#: config/tc-mmix.c:1956
+msgid "internal: mmix_prefix_name but empty prefix"
+msgstr ""
+
+#: config/tc-mmix.c:2001
+#, c-format
+msgid "too many GREG registers allocated (max %d)"
+msgstr ""
+
+#: config/tc-mmix.c:2061
+msgid "BSPEC already active. Nesting is not supported."
+msgstr ""
+
+#: config/tc-mmix.c:2070
+msgid "invalid BSPEC expression"
+msgstr ""
+
+#: config/tc-mmix.c:2086
+#, c-format
+msgid "can't create section %s"
+msgstr ""
+
+#: config/tc-mmix.c:2091
+#, c-format
+msgid "can't set section flags for section %s"
+msgstr ""
+
+#: config/tc-mmix.c:2113
+msgid "ESPEC without preceding BSPEC"
+msgstr ""
+
+#: config/tc-mmix.c:2143
+msgid "missing local expression"
+msgstr ""
+
+#: config/tc-mmix.c:2363
+msgid "operand out of range, instruction expanded"
+msgstr ""
+
+#. The BFD_RELOC_MMIX_LOCAL-specific message is supposed to be
+#. user-friendly, though a little bit non-substantial.
+#: config/tc-mmix.c:2620
+msgid "directive LOCAL must be placed in code or data"
+msgstr ""
+
+#: config/tc-mmix.c:2621
+msgid "internal confusion: relocation in a section without contents"
+msgstr ""
+
+#: config/tc-mmix.c:2734
+msgid "internal: BFD_RELOC_MMIX_BASE_PLUS_OFFSET not resolved to section"
+msgstr ""
+
+#: config/tc-mmix.c:2782
+msgid "no suitable GREG definition for operands"
+msgstr ""
+
+#: config/tc-mmix.c:2841
+msgid "operands were not reducible at assembly-time"
+msgstr ""
+
+#: config/tc-mmix.c:2868
+#, c-format
+msgid "cannot generate relocation type for symbol %s, code %s"
+msgstr ""
+
+#: config/tc-mmix.c:2888
+#, c-format
+msgid "internal: unhandled label %s"
+msgstr ""
+
+#: config/tc-mmix.c:2942
+msgid "[0-9]H labels may not appear alone on a line"
+msgstr ""
+
+#: config/tc-mmix.c:2951
+msgid "[0-9]H labels do not mix with dot-pseudos"
+msgstr ""
+
+#: config/tc-mmix.c:3015
+msgid "invalid characters in input"
+msgstr ""
+
+#: config/tc-mmix.c:3119
+msgid "empty label field for IS"
+msgstr ""
+
+#: config/tc-mmix.c:3344
+#, c-format
+msgid "internal: unexpected relax type %d:%d"
+msgstr ""
+
+#: config/tc-mmix.c:3366
+msgid "BSPEC without ESPEC."
+msgstr ""
+
+#: config/tc-mmix.c:3568
+msgid "GREG expression too complicated"
+msgstr ""
+
+#: config/tc-mmix.c:3583
+msgid "internal: GREG expression not resolved to section"
+msgstr ""
+
+#: config/tc-mmix.c:3634
+msgid "register section has contents\n"
+msgstr ""
+
+#: config/tc-mmix.c:3768
+msgid "section change from within a BSPEC/ESPEC pair is not supported"
+msgstr ""
+
+#: config/tc-mmix.c:3790
+msgid "directive LOC from within a BSPEC/ESPEC pair is not supported"
+msgstr ""
+
+#: config/tc-mmix.c:3801
+msgid "invalid LOC expression"
+msgstr ""
+
+#: config/tc-mmix.c:3826 config/tc-mmix.c:3852
+msgid "LOC expression stepping backwards is not supported"
+msgstr ""
+
+#. We will only get here in rare cases involving #NO_APP,
+#. where the unterminated string is not recognized by the
+#. preformatting pass.
+#: config/tc-mmix.c:3936 config/tc-mmix.c:4097
+msgid "unterminated string"
+msgstr ""
+
+#: config/tc-mmix.c:3953
+msgid "BYTE expression not a pure number"
+msgstr ""
+
+#. Note that mmixal does not allow negative numbers in
+#. BYTE sequences, so neither should we.
+#: config/tc-mmix.c:3962
+msgid "BYTE expression not in the range 0..255"
+msgstr ""
+
+#: config/tc-mmix.c:4013 config/tc-mmix.c:4029
+msgid "data item with alignment larger than location"
+msgstr ""
+
+#. Since integer_constant is local to expr.c, we have to make this a
+#. macro. FIXME: Do it cleaner.
+#: config/tc-mmix.h:104
+msgid "`&' serial number operator is not supported"
+msgstr ""
+
+#: config/tc-mn10200.c:319
+msgid ""
+"MN10200 options:\n"
+"none yet\n"
+msgstr ""
+
+#: config/tc-mn10200.c:793 config/tc-mn10300.c:1387 config/tc-ppc.c:2088
+#: config/tc-s390.c:1540 config/tc-v850.c:1677
+#, c-format
+msgid "Unrecognized opcode: `%s'"
+msgstr ""
+
+#: config/tc-mn10200.c:1036 config/tc-mn10300.c:1960 config/tc-ppc.c:2566
+#: config/tc-s390.c:1455 config/tc-v850.c:2100
+#, c-format
+msgid "junk at end of line: `%s'"
+msgstr ""
+
+#: config/tc-mn10200.c:1242 write.c:2691
+#, c-format
+msgid "can't resolve `%s' {%s section} - `%s' {%s section}"
+msgstr ""
+
+#: config/tc-mn10200.c:1347 config/tc-mn10300.c:2589 config/tc-ppc.c:1426
+#: config/tc-v850.c:1606
+#, c-format
+msgid "operand out of range (%s not between %ld and %ld)"
+msgstr ""
+
+#: config/tc-mn10300.c:690
+msgid ""
+"MN10300 options:\n"
+"none yet\n"
+msgstr ""
+
+#: config/tc-mn10300.c:1356 config/tc-sh.c:805 config/tc-xtensa.c:5177
+#: read.c:3764
+#, c-format
+msgid "unsupported BFD relocation size %u"
+msgstr ""
+
+#: config/tc-mn10300.c:1404
+msgid "Invalid opcode/operands"
+msgstr ""
+
+#: config/tc-mn10300.c:1931
+msgid "Invalid register specification."
+msgstr ""
+
+#: config/tc-mn10300.c:2514
+#, c-format
+msgid "Bad relocation fixup type (%d)"
+msgstr ""
+
+#: config/tc-msp430.c:170
+msgid "Known MCU names:\n"
+msgstr ""
+
+#: config/tc-msp430.c:173
+#, c-format
+msgid "\t %s\n"
+msgstr ""
+
+#: config/tc-msp430.c:183
+msgid ""
+"MSP430 options:\n"
+" -mmcu=[msp430-name] select microcontroller type\n"
+" msp430x110 msp430x112\n"
+" msp430x1101 msp430x1111\n"
+" msp430x1121 msp430x1122 msp430x1132\n"
+" msp430x122 msp430x123\n"
+" msp430x1222 msp430x1232\n"
+" msp430x133 msp430x135\n"
+" msp430x1331 msp430x1351\n"
+" msp430x147 msp430x148 msp430x149\n"
+" msp430x155 msp430x156 msp430x157\n"
+" msp430x167 msp430x168 msp430x169\n"
+" msp430x311 msp430x312 msp430x313 msp430x314 "
+"msp430x315\n"
+" msp430x323 msp430x325\n"
+" msp430x336 msp430x337\n"
+" msp430x412 msp430x413\n"
+" msp430x435 msp430x436 msp430x437\n"
+" msp430x447 msp430x448 msp430x449\n"
+msgstr ""
+
+#: config/tc-msp430.c:263
+#, c-format
+msgid "redefinition of mcu type %s' to %s'"
+msgstr ""
+
+#: config/tc-msp430.c:496
+#, c-format
+msgid "instruction %s requires %d operand(s)"
+msgstr ""
+
+#: config/tc-msp430.c:743
+#, c-format
+msgid "Even number required. Rounded to %d"
+msgstr ""
+
+#: config/tc-msp430.c:754
+#, c-format
+msgid "Wrong displacement %d"
+msgstr ""
+
+#: config/tc-msp430.c:771
+msgid "instruction requires label sans '$'"
+msgstr ""
+
+#: config/tc-msp430.c:777
+msgid "instruction requires label or value in range -511:512"
+msgstr ""
+
+#: config/tc-msp430.c:783
+msgid "instruction requires label"
+msgstr ""
+
+#: config/tc-msp430.c:789
+msgid "Ilegal instruction or not implmented opcode."
+msgstr ""
+
+#: config/tc-msp430.c:817
+#, c-format
+msgid "Internal bug. Try to use 0(r%d) instead of @r%d"
+msgstr ""
+
+#: config/tc-msp430.c:827
+msgid "this addressing mode is not applicable for destination operand"
+msgstr ""
+
+#: config/tc-msp430.c:944
+#, c-format
+msgid "value %ld out of range. Use #lo() or #hi()"
+msgstr ""
+
+#: config/tc-msp430.c:1040
+#, c-format
+msgid "unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "
+msgstr ""
+
+#: config/tc-msp430.c:1090 config/tc-msp430.c:1304
+#, c-format
+msgid "unknown operand %s"
+msgstr ""
+
+#: config/tc-msp430.c:1111 config/tc-msp430.c:1242
+#, c-format
+msgid "value out of range: %d"
+msgstr ""
+
+#: config/tc-msp430.c:1120 config/tc-msp430.c:1259
+#, c-format
+msgid "unknown expression in operand %s"
+msgstr ""
+
+#: config/tc-msp430.c:1134 config/tc-msp430.c:1141
+#, c-format
+msgid "unknown addressing mode %s"
+msgstr ""
+
+#: config/tc-msp430.c:1149
+#, c-format
+msgid "Bad register name r%s"
+msgstr ""
+
+#: config/tc-msp430.c:1161
+#, c-format
+msgid "MSP430 does not have %d registers"
+msgstr ""
+
+#: config/tc-msp430.c:1181
+msgid "')' required"
+msgstr ""
+
+#: config/tc-msp430.c:1194
+#, c-format
+msgid "unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"
+msgstr ""
+
+#: config/tc-msp430.c:1203
+#, c-format
+msgid "unknown operator (r%s substituded as a register name"
+msgstr ""
+
+#: config/tc-msp430.c:1215 config/tc-msp430.c:1226
+#, c-format
+msgid "unknown operator %s"
+msgstr ""
+
+#: config/tc-msp430.c:1220
+msgid "r2 should not be used in indexed addressing mode"
+msgstr ""
+
+#. Unreachable.
+#: config/tc-msp430.c:1321
+#, c-format
+msgid "unknown addressing mode for operand %s"
+msgstr ""
+
+#: config/tc-ns32k.c:449
+msgid "Invalid syntax in PC-relative addressing mode"
+msgstr ""
+
+#: config/tc-ns32k.c:473
+msgid "Invalid syntax in External addressing mode"
+msgstr ""
+
+#: config/tc-ns32k.c:554
+msgid "Invalid syntax in Memory Relative addressing mode"
+msgstr ""
+
+#: config/tc-ns32k.c:621
+msgid "Invalid scaled-indexed mode, use (b,w,d,q)"
+msgstr ""
+
+#: config/tc-ns32k.c:626
+msgid "Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}"
+msgstr ""
+
+#: config/tc-ns32k.c:631
+msgid "Scaled-indexed addressing mode combined with scaled-index"
+msgstr ""
+
+#: config/tc-ns32k.c:642
+msgid "Invalid or illegal addressing mode combined with scaled-index"
+msgstr ""
+
+#: config/tc-ns32k.c:757
+msgid "Premature end of suffix -- Defaulting to d"
+msgstr ""
+
+#: config/tc-ns32k.c:770
+msgid "Bad suffix after ':' use {b|w|d} Defaulting to d"
+msgstr ""
+
+#: config/tc-ns32k.c:817
+msgid "Very short instr to option, ie you can't do it on a NULLstr"
+msgstr ""
+
+#: config/tc-ns32k.c:870
+msgid "No such entry in list. (cpu/mmu register)"
+msgstr ""
+
+#: config/tc-ns32k.c:915
+msgid "Internal consistency error. check ns32k-opcode.h"
+msgstr ""
+
+#: config/tc-ns32k.c:939
+msgid "Address of immediate operand"
+msgstr ""
+
+#: config/tc-ns32k.c:940
+msgid "Invalid immediate write operand."
+msgstr ""
+
+#: config/tc-ns32k.c:1070
+msgid "Bad opcode-table-option, check in file ns32k-opcode.h"
+msgstr ""
+
+#: config/tc-ns32k.c:1107
+msgid "No such opcode"
+msgstr ""
+
+#: config/tc-ns32k.c:1184
+msgid "Bad suffix, defaulting to d"
+msgstr ""
+
+#: config/tc-ns32k.c:1212
+msgid "Too many operands passed to instruction"
+msgstr ""
+
+#. Check error in default.
+#: config/tc-ns32k.c:1225
+msgid "Wrong numbers of operands in default, check ns32k-opcodes.h"
+msgstr ""
+
+#: config/tc-ns32k.c:1229
+msgid "Wrong number of operands"
+msgstr ""
+
+#: config/tc-ns32k.c:1355
+msgid "iif convert internal pcrel/binary"
+msgstr ""
+
+#: config/tc-ns32k.c:1372
+msgid "Bignum too big for long"
+msgstr ""
+
+#: config/tc-ns32k.c:1451
+msgid "iif convert internal pcrel/pointer"
+msgstr ""
+
+#: config/tc-ns32k.c:1456
+msgid "Internal logic error in iif.iifP[n].type"
+msgstr ""
+
+#. We cant relax this case.
+#: config/tc-ns32k.c:1493
+msgid "Can't relax difference"
+msgstr ""
+
+#: config/tc-ns32k.c:1541
+msgid "Displacement to large for :d"
+msgstr ""
+
+#: config/tc-ns32k.c:1554
+msgid "Internal logic error in iif.iifP[].type"
+msgstr ""
+
+#: config/tc-ns32k.c:1614
+#, c-format
+msgid "Can not do %d byte pc-relative relocation for storage type %d"
+msgstr ""
+
+#: config/tc-ns32k.c:1617
+#, c-format
+msgid "Can not do %d byte relocation for storage type %d"
+msgstr ""
+
+#. Fatal.
+#: config/tc-ns32k.c:1652
+#, c-format
+msgid "Can't hash %s: %s"
+msgstr ""
+
+#: config/tc-ns32k.c:1740
+#, c-format
+msgid "value of %ld out of byte displacement range."
+msgstr ""
+
+#: config/tc-ns32k.c:1749
+#, c-format
+msgid "value of %ld out of word displacement range."
+msgstr ""
+
+#: config/tc-ns32k.c:1763
+#, c-format
+msgid "value of %ld out of double word displacement range."
+msgstr ""
+
+#: config/tc-ns32k.c:1783
+#, c-format
+msgid "Internal logic error. line %d, file \"%s\""
+msgstr ""
+
+#: config/tc-ns32k.c:1831
+#, c-format
+msgid "Internal logic error. line %d, file \"%s\""
+msgstr ""
+
+#: config/tc-ns32k.c:1936
+msgid "Bit field out of range"
+msgstr ""
+
+#: config/tc-ns32k.c:2183
+#, c-format
+msgid "invalid architecture option -m%s, ignored"
+msgstr ""
+
+#: config/tc-ns32k.c:2196
+#, c-format
+msgid "invalid default displacement size \"%s\". Defaulting to %d."
+msgstr ""
+
+#: config/tc-ns32k.c:2213
+msgid ""
+"NS32K options:\n"
+"-m32032 | -m32532\tselect variant of NS32K architecture\n"
+"--disp-size-default=<1|2|4>\n"
+msgstr ""
+
+#: config/tc-ns32k.c:2397
+#, c-format
+msgid "Cannot find relocation type for symbol %s, code %d"
+msgstr ""
+
+#: config/tc-or32.c:465 config/tc-or32.c:680
+#, c-format
+msgid "unknown opcode1: `%s'"
+msgstr ""
+
+#: config/tc-or32.c:471 config/tc-or32.c:686
+#, c-format
+msgid "unknown opcode2 `%s'."
+msgstr ""
+
+#: config/tc-or32.c:510 config/tc-or32.c:725
+#, c-format
+msgid "instruction not allowed: %s"
+msgstr ""
+
+#: config/tc-or32.c:513 config/tc-or32.c:728
+#, c-format
+msgid "too many operands: %s"
+msgstr ""
+
+#: config/tc-or32.c:603 config/tc-or32.c:819
+msgid "call/jmp target out of range (1)"
+msgstr ""
+
+#: config/tc-or32.c:1016 config/tc-or32.c:1133
+msgid "the linker will not handle this relocation correctly (1)"
+msgstr ""
+
+#: config/tc-or32.c:1025 config/tc-or32.c:1142
+msgid "call/jmp target out of range (2)"
+msgstr ""
+
+#: config/tc-or32.c:1433
+msgid "register out of range"
+msgstr ""
+
+#: config/tc-or32.c:1478
+msgid "invalid register in & expression"
+msgstr ""
+
+#: config/tc-pdp11.c:454
+msgid "Low order bits truncated in immediate float operand"
+msgstr ""
+
+#: config/tc-pdp11.c:665
+#, c-format
+msgid "Unknown instruction '%s'"
+msgstr ""
+
+#: config/tc-pj.c:82 config/tc-pj.c:90
+msgid "confusing relocation expressions"
+msgstr ""
+
+#: config/tc-pj.c:181
+msgid "can't have relocation for ipush"
+msgstr ""
+
+#: config/tc-pj.c:290 config/tc-xtensa.c:4976
+#, c-format
+msgid "unknown opcode %s"
+msgstr ""
+
+#: config/tc-pj.c:439
+msgid ""
+"PJ options:\n"
+"-little\t\t\tgenerate little endian code\n"
+"-big\t\t\tgenerate big endian code\n"
+msgstr ""
+
+#: config/tc-pj.c:469 config/tc-sh.c:3464 config/tc-sh.c:3471
+#: config/tc-sh.c:3478 config/tc-sh.c:3485
+msgid "pcrel too far"
+msgstr ""
+
+#: config/tc-pj.h:38
+msgid "convert_frag\n"
+msgstr ""
+
+#: config/tc-pj.h:39
+msgid "estimate size\n"
+msgstr ""
+
+#: config/tc-ppc.c:879
+#, c-format
+msgid "%s unsupported"
+msgstr ""
+
+#: config/tc-ppc.c:1029 config/tc-s390.c:414 config/tc-s390.c:421
+#, c-format
+msgid "invalid switch -m%s"
+msgstr ""
+
+#: config/tc-ppc.c:1066
+msgid ""
+"PowerPC options:\n"
+"-a32\t\t\tgenerate ELF32/XCOFF32\n"
+"-a64\t\t\tgenerate ELF64/XCOFF64\n"
+"-u\t\t\tignored\n"
+"-mpwrx, -mpwr2\t\tgenerate code for POWER/2 (RIOS2)\n"
+"-mpwr\t\t\tgenerate code for POWER (RIOS1)\n"
+"-m601\t\t\tgenerate code for PowerPC 601\n"
+"-mppc, -mppc32, -m603, -m604\n"
+"\t\t\tgenerate code for PowerPC 603/604\n"
+"-m403, -m405\t\tgenerate code for PowerPC 403/405\n"
+"-m7400, -m7410, -m7450, -m7455\n"
+"\t\t\tgenerate code For PowerPC 7400/7410/7450/7455\n"
+msgstr ""
+
+#: config/tc-ppc.c:1079
+msgid ""
+"-mppc64, -m620\t\tgenerate code for PowerPC 620/625/630\n"
+"-mppc64bridge\t\tgenerate code for PowerPC 64, including bridge insns\n"
+"-mbooke64\t\tgenerate code for 64-bit PowerPC BookE\n"
+"-mbooke, mbooke32\tgenerate code for 32-bit PowerPC BookE\n"
+"-mpower4\t\tgenerate code for Power4 architecture\n"
+"-mcom\t\t\tgenerate code Power/PowerPC common instructions\n"
+"-many\t\t\tgenerate code for any architecture (PWR/PWRX/PPC)\n"
+msgstr ""
+
+#: config/tc-ppc.c:1087
+msgid ""
+"-maltivec\t\tgenerate code for AltiVec\n"
+"-me500, -me500x2\tgenerate code for Motorola e500 core complex\n"
+"-mspe\t\t\tgenerate code for Motorola SPE instructions\n"
+"-mregnames\t\tAllow symbolic names for registers\n"
+"-mno-regnames\t\tDo not allow symbolic names for registers\n"
+msgstr ""
+
+#: config/tc-ppc.c:1094
+msgid ""
+"-mrelocatable\t\tsupport for GCC's -mrelocatble option\n"
+"-mrelocatable-lib\tsupport for GCC's -mrelocatble-lib option\n"
+"-memb\t\t\tset PPC_EMB bit in ELF flags\n"
+"-mlittle, -mlittle-endian, -l, -le\n"
+"\t\t\tgenerate code for a little endian machine\n"
+"-mbig, -mbig-endian, -b, -be\n"
+"\t\t\tgenerate code for a big endian machine\n"
+"-msolaris\t\tgenerate code for Solaris\n"
+"-mno-solaris\t\tdo not generate code for Solaris\n"
+"-V\t\t\tprint assembler version number\n"
+"-Qy, -Qn\t\tignored\n"
+msgstr ""
+
+#: config/tc-ppc.c:1136
+#, c-format
+msgid "Unknown default cpu = %s, os = %s"
+msgstr ""
+
+#: config/tc-ppc.c:1161
+msgid "Neither Power nor PowerPC opcodes were selected."
+msgstr ""
+
+#: config/tc-ppc.c:1257 config/tc-s390.c:516
+#, c-format
+msgid "Internal assembler error for instruction %s"
+msgstr ""
+
+#: config/tc-ppc.c:1277
+#, c-format
+msgid "Internal assembler error for macro %s"
+msgstr ""
+
+#: config/tc-ppc.c:1599
+msgid "identifier+constant@got means identifier@got+constant"
+msgstr ""
+
+#: config/tc-ppc.c:1666
+#, c-format
+msgid "%s relocations do not fit in %d bytes\n"
+msgstr ""
+
+#: config/tc-ppc.c:1773
+#, c-format
+msgid "Length of .lcomm \"%s\" is already %ld. Not changed to %ld."
+msgstr ""
+
+#: config/tc-ppc.c:1855
+msgid "Relocation cannot be done when using -mrelocatable"
+msgstr ""
+
+#: config/tc-ppc.c:1981
+#, c-format
+msgid "syntax error: invalid toc specifier `%s'"
+msgstr ""
+
+#: config/tc-ppc.c:1995
+#, c-format
+msgid "syntax error: expected `]', found `%c'"
+msgstr ""
+
+#: config/tc-ppc.c:2272
+msgid "[tocv] symbol is not a toc symbol"
+msgstr ""
+
+#: config/tc-ppc.c:2283
+msgid "Unimplemented toc32 expression modifier"
+msgstr ""
+
+#: config/tc-ppc.c:2288
+msgid "Unimplemented toc64 expression modifier"
+msgstr ""
+
+#: config/tc-ppc.c:2292
+#, c-format
+msgid "Unexpected return value [%d] from parse_toc_entry!\n"
+msgstr ""
+
+#: config/tc-ppc.c:2510
+msgid "unsupported relocation for DS offset field"
+msgstr ""
+
+#: config/tc-ppc.c:2554
+#, c-format
+msgid "syntax error; found `%c' but expected `%c'"
+msgstr ""
+
+#: config/tc-ppc.c:2703
+msgid "wrong number of operands"
+msgstr ""
+
+#: config/tc-ppc.c:2759
+msgid "Bad .section directive: want a,e,w,x,M,S,G,T in string"
+msgstr ""
+
+#: config/tc-ppc.c:2874
+msgid "missing size"
+msgstr ""
+
+#: config/tc-ppc.c:2883
+msgid "negative size"
+msgstr ""
+
+#: config/tc-ppc.c:2920
+msgid "missing real symbol name"
+msgstr ""
+
+#: config/tc-ppc.c:2941
+msgid "attempt to redefine symbol"
+msgstr ""
+
+#: config/tc-ppc.c:3188
+msgid "The XCOFF file format does not support arbitrary sections"
+msgstr ""
+
+#: config/tc-ppc.c:3265
+msgid "missing rename string"
+msgstr ""
+
+#: config/tc-ppc.c:3296 config/tc-ppc.c:3851 read.c:3060
+msgid "missing value"
+msgstr ""
+
+#: config/tc-ppc.c:3314
+msgid "illegal .stabx expression; zero assumed"
+msgstr ""
+
+#: config/tc-ppc.c:3346
+msgid "missing class"
+msgstr ""
+
+#: config/tc-ppc.c:3355
+msgid "missing type"
+msgstr ""
+
+#: config/tc-ppc.c:3436
+msgid "missing symbol name"
+msgstr ""
+
+#: config/tc-ppc.c:3630
+msgid "nested .bs blocks"
+msgstr ""
+
+#: config/tc-ppc.c:3663
+msgid ".es without preceding .bs"
+msgstr ""
+
+#: config/tc-ppc.c:3843
+msgid "non-constant byte count"
+msgstr ""
+
+#: config/tc-ppc.c:3891
+msgid ".tc not in .toc section"
+msgstr ""
+
+#: config/tc-ppc.c:3910
+msgid ".tc with no label"
+msgstr ""
+
+#: config/tc-ppc.c:4021
+msgid "No previous section to return to. Directive ignored."
+msgstr ""
+
+#. Section Contents
+#. unknown
+#: config/tc-ppc.c:4438
+msgid "Unsupported section attribute -- 'a'"
+msgstr ""
+
+#: config/tc-ppc.c:4627
+msgid "bad symbol suffix"
+msgstr ""
+
+#: config/tc-ppc.c:4720
+msgid "Unrecognized symbol suffix"
+msgstr ""
+
+#: config/tc-ppc.c:4806
+msgid "two .function pseudo-ops with no intervening .ef"
+msgstr ""
+
+#: config/tc-ppc.c:4819
+msgid ".ef with no preceding .function"
+msgstr ""
+
+#: config/tc-ppc.c:4947
+#, c-format
+msgid "warning: symbol %s has no csect"
+msgstr ""
+
+#: config/tc-ppc.c:5251
+msgid "symbol in .toc does not match any .tc"
+msgstr ""
+
+#: config/tc-ppc.c:5584 config/tc-s390.c:2072 config/tc-v850.c:2401
+#: config/tc-xstormy16.c:537
+msgid "unresolved expression that must be resolved"
+msgstr ""
+
+#: config/tc-ppc.c:5587
+#, c-format
+msgid "unsupported relocation against %s"
+msgstr ""
+
+#: config/tc-ppc.c:5662
+#, c-format
+msgid "cannot emit PC relative %s relocation against %s"
+msgstr ""
+
+#: config/tc-ppc.c:5667
+#, c-format
+msgid "cannot emit PC relative %s relocation"
+msgstr ""
+
+#: config/tc-ppc.c:5841
+msgid "must branch to an address a multiple of 4"
+msgstr ""
+
+#: config/tc-ppc.c:5845
+#, c-format
+msgid "@local or @plt branch destination is too far away, %ld bytes"
+msgstr ""
+
+#: config/tc-ppc.c:5876
+#, c-format
+msgid "Gas failure, reloc value %d\n"
+msgstr ""
+
+#: config/tc-s390.c:457
+msgid ""
+" S390 options:\n"
+" -mregnames Allow symbolic names for registers\n"
+" -mwarn-areg-zero Warn about zero base/index registers\n"
+" -mno-regnames Do not allow symbolic names for registers\n"
+" -m31 Set file format to 31 bit format\n"
+" -m64 Set file format to 64 bit format\n"
+msgstr ""
+
+#: config/tc-s390.c:464
+msgid ""
+" -V print assembler version number\n"
+" -Qy, -Qn ignored\n"
+msgstr ""
+
+#: config/tc-s390.c:500
+#, c-format
+msgid "Internal assembler error for instruction format %s"
+msgstr ""
+
+#: config/tc-s390.c:782
+#, c-format
+msgid "identifier+constant@%s means identifier@%s+constant"
+msgstr ""
+
+#: config/tc-s390.c:865
+msgid "Can't handle O_big in s390_exp_compare"
+msgstr ""
+
+#: config/tc-s390.c:949
+msgid "Invalid suffix for literal pool entry"
+msgstr ""
+
+#: config/tc-s390.c:1006
+msgid "Big number is too big"
+msgstr ""
+
+#: config/tc-s390.c:1144 config/tc-s390.c:1722
+#, c-format
+msgid "%s relocations do not fit in %d bytes"
+msgstr ""
+
+#: config/tc-s390.c:1154
+msgid "relocation not applicable"
+msgstr ""
+
+#: config/tc-s390.c:1342
+msgid "invalid operand suffix"
+msgstr ""
+
+#: config/tc-s390.c:1365
+msgid "syntax error; missing '(' after displacement"
+msgstr ""
+
+#: config/tc-s390.c:1375 config/tc-s390.c:1408 config/tc-s390.c:1427
+msgid "syntax error; expected ,"
+msgstr ""
+
+#: config/tc-s390.c:1402
+msgid "syntax error; missing ')' after base register"
+msgstr ""
+
+#: config/tc-s390.c:1420
+msgid "syntax error; ')' not allowed here"
+msgstr ""
+
+#: config/tc-s390.c:1602 config/tc-s390.c:1622 config/tc-s390.c:1635
+msgid "Invalid .insn format\n"
+msgstr ""
+
+#: config/tc-s390.c:1610
+#, c-format
+msgid "Unrecognized opcode format: `%s'"
+msgstr ""
+
+#: config/tc-s390.c:1638
+msgid "second operand of .insn not a constant\n"
+msgstr ""
+
+#: config/tc-s390.c:1641
+msgid "missing comma after insn constant\n"
+msgstr ""
+
+#: config/tc-s390.c:2075
+msgid "unsupported relocation type"
+msgstr ""
+
+#: config/tc-sh64.c:596
+msgid "This operand must be constant at assembly time"
+msgstr ""
+
+#: config/tc-sh64.c:711
+msgid "Invalid operand expression"
+msgstr ""
+
+#: config/tc-sh64.c:798 config/tc-sh64.c:904
+msgid "PTB operand is a SHmedia symbol"
+msgstr ""
+
+#: config/tc-sh64.c:801 config/tc-sh64.c:901
+msgid "PTA operand is a SHcompact symbol"
+msgstr ""
+
+#: config/tc-sh64.c:817
+msgid "invalid expression in operand"
+msgstr ""
+
+#: config/tc-sh64.c:1514
+#, c-format
+msgid "invalid operand, not a 5-bit unsigned value: %d"
+msgstr ""
+
+#: config/tc-sh64.c:1519
+#, c-format
+msgid "invalid operand, not a 6-bit signed value: %d"
+msgstr ""
+
+#: config/tc-sh64.c:1524
+#, c-format
+msgid "invalid operand, not a 6-bit unsigned value: %d"
+msgstr ""
+
+#: config/tc-sh64.c:1529 config/tc-sh64.c:1541
+#, c-format
+msgid "invalid operand, not a 11-bit signed value: %d"
+msgstr ""
+
+#: config/tc-sh64.c:1531
+#, c-format
+msgid "invalid operand, not a multiple of 32: %d"
+msgstr ""
+
+#: config/tc-sh64.c:1536
+#, c-format
+msgid "invalid operand, not a 10-bit signed value: %d"
+msgstr ""
+
+#: config/tc-sh64.c:1543
+#, c-format
+msgid "invalid operand, not an even value: %d"
+msgstr ""
+
+#: config/tc-sh64.c:1548
+#, c-format
+msgid "invalid operand, not a 12-bit signed value: %d"
+msgstr ""
+
+#: config/tc-sh64.c:1550
+#, c-format
+msgid "invalid operand, not a multiple of 4: %d"
+msgstr ""
+
+#: config/tc-sh64.c:1555
+#, c-format
+msgid "invalid operand, not a 13-bit signed value: %d"
+msgstr ""
+
+#: config/tc-sh64.c:1557
+#, c-format
+msgid "invalid operand, not a multiple of 8: %d"
+msgstr ""
+
+#: config/tc-sh64.c:1562
+#, c-format
+msgid "invalid operand, not a 16-bit signed value: %d"
+msgstr ""
+
+#: config/tc-sh64.c:1567
+#, c-format
+msgid "invalid operand, not an 16-bit unsigned value: %d"
+msgstr ""
+
+#: config/tc-sh64.c:1573
+msgid "operand out of range for PT, PTA and PTB"
+msgstr ""
+
+#: config/tc-sh64.c:1575
+#, c-format
+msgid "operand not a multiple of 4 for PT, PTA or PTB: %d"
+msgstr ""
+
+#: config/tc-sh64.c:2103
+#, c-format
+msgid "MOVI operand is not a 32-bit signed value: 0x%8x%08x"
+msgstr ""
+
+#: config/tc-sh64.c:2466 config/tc-sh64.c:2631 config/tc-sh64.c:2646
+msgid "invalid PIC reference"
+msgstr ""
+
+#: config/tc-sh64.c:2524
+msgid "can't find opcode"
+msgstr ""
+
+#: config/tc-sh64.c:2854
+#, c-format
+msgid "invalid operands to %s"
+msgstr ""
+
+#: config/tc-sh64.c:2860
+#, c-format
+msgid "excess operands to %s"
+msgstr ""
+
+#: config/tc-sh64.c:2906
+#, c-format
+msgid "The `.mode %s' directive is not valid with this architecture"
+msgstr ""
+
+#: config/tc-sh64.c:2914
+#, c-format
+msgid "Invalid argument to .mode: %s"
+msgstr ""
+
+#: config/tc-sh64.c:2945
+#, c-format
+msgid "The `.abi %s' directive is not valid with this architecture"
+msgstr ""
+
+#: config/tc-sh64.c:2951
+msgid "`.abi 64' but command-line options do not specify 64-bit ABI"
+msgstr ""
+
+#: config/tc-sh64.c:2956
+msgid "`.abi 32' but command-line options do not specify 32-bit ABI"
+msgstr ""
+
+#: config/tc-sh64.c:2959
+#, c-format
+msgid "Invalid argument to .abi: %s"
+msgstr ""
+
+#: config/tc-sh64.c:3014
+msgid "-no-mix is invalid without specifying SHcompact or SHmedia"
+msgstr ""
+
+#: config/tc-sh64.c:3019
+msgid "-shcompact-const-crange is invalid without SHcompact"
+msgstr ""
+
+#: config/tc-sh64.c:3022
+msgid "-expand-pt32 only valid with -abi=64"
+msgstr ""
+
+#: config/tc-sh64.c:3025
+msgid "-no-expand only valid with SHcompact or SHmedia"
+msgstr ""
+
+#: config/tc-sh64.c:3028
+msgid "-expand-pt32 invalid together with -no-expand"
+msgstr ""
+
+#: config/tc-sh64.c:3250
+msgid ""
+"SHmedia code not allowed in same section as constants and SHcompact code"
+msgstr ""
+
+#: config/tc-sh64.c:3268
+msgid "No segment info for current section"
+msgstr ""
+
+#: config/tc-sh64.c:3310
+msgid "duplicate datalabel operator ignored"
+msgstr ""
+
+#: config/tc-sh64.c:3380
+msgid "Invalid DataLabel expression"
+msgstr ""
+
+#: config/tc-sh.c:91
+msgid "directive .big encountered when option -big required"
+msgstr ""
+
+#: config/tc-sh.c:102
+msgid "directive .little encountered when option -little required"
+msgstr ""
+
+#: config/tc-sh.c:776
+msgid "Invalid PIC expression."
+msgstr ""
+
+#: config/tc-sh.c:1269
+msgid "misplaced PIC operand"
+msgstr ""
+
+#: config/tc-sh.c:1310
+msgid "illegal register after @-"
+msgstr ""
+
+#: config/tc-sh.c:1326
+msgid "must be @(r0,...)"
+msgstr ""
+
+#: config/tc-sh.c:1350
+msgid "syntax error in @(r0,...)"
+msgstr ""
+
+#: config/tc-sh.c:1355
+msgid "syntax error in @(r0...)"
+msgstr ""
+
+#: config/tc-sh.c:1396
+msgid "Deprecated syntax."
+msgstr ""
+
+#: config/tc-sh.c:1408 config/tc-sh.c:1413
+msgid "syntax error in @(disp,[Rn, gbr, pc])"
+msgstr ""
+
+#: config/tc-sh.c:1418
+msgid "expecting )"
+msgstr ""
+
+#: config/tc-sh.c:1426
+msgid "illegal register after @"
+msgstr ""
+
+#: config/tc-sh.c:1977
+#, c-format
+msgid "Invalid register: 'r%d'"
+msgstr ""
+
+#: config/tc-sh.c:2143
+msgid "insn can't be combined with parallel processing insn"
+msgstr ""
+
+#: config/tc-sh.c:2150 config/tc-sh.c:2161
+msgid "multiple movx specifications"
+msgstr ""
+
+#: config/tc-sh.c:2155 config/tc-sh.c:2182
+msgid "multiple movy specifications"
+msgstr ""
+
+#: config/tc-sh.c:2163
+msgid "invalid movx address register"
+msgstr ""
+
+#: config/tc-sh.c:2169 config/tc-sh.c:2174
+msgid "invalid movx dsp register"
+msgstr ""
+
+#: config/tc-sh.c:2191 config/tc-sh.c:2196
+msgid "invalid movy dsp register"
+msgstr ""
+
+#: config/tc-sh.c:2200
+msgid "invalid movy address register"
+msgstr ""
+
+#: config/tc-sh.c:2206
+msgid "dsp immediate shift value not constant"
+msgstr ""
+
+#: config/tc-sh.c:2213 config/tc-sh.c:2226
+msgid "multiple parallel processing specifications"
+msgstr ""
+
+#: config/tc-sh.c:2219
+msgid "multiple condition specifications"
+msgstr ""
+
+#: config/tc-sh.c:2235
+msgid "insn cannot be combined with pmuls"
+msgstr ""
+
+#: config/tc-sh.c:2252
+msgid "bad padd / psub pmuls output operand"
+msgstr ""
+
+#: config/tc-sh.c:2262
+msgid "destination register is same for parallel insns"
+msgstr ""
+
+#: config/tc-sh.c:2271
+msgid "condition not followed by conditionalizable insn"
+msgstr ""
+
+#: config/tc-sh.c:2281
+msgid "unrecognized characters at end of parallel processing insn"
+msgstr ""
+
+#: config/tc-sh.c:2417
+#, c-format
+msgid "excess operands: '%s'"
+msgstr ""
+
+#: config/tc-sh.c:2569
+msgid ".uses pseudo-op seen when not relaxing"
+msgstr ""
+
+#: config/tc-sh.c:2575
+msgid "bad .uses format"
+msgstr ""
+
+#: config/tc-sh.c:2654
+msgid "Invalid combination: --isa=SHcompact with --isa=SHmedia"
+msgstr ""
+
+#: config/tc-sh.c:2660
+msgid "Invalid combination: --isa=SHmedia with --isa=SHcompact"
+msgstr ""
+
+#: config/tc-sh.c:2662
+msgid "Invalid combination: --abi=64 with --isa=SHcompact"
+msgstr ""
+
+#: config/tc-sh.c:2675
+msgid "Invalid combination: --abi=32 with --abi=64"
+msgstr ""
+
+#: config/tc-sh.c:2681
+msgid "Invalid combination: --abi=64 with --abi=32"
+msgstr ""
+
+#: config/tc-sh.c:2683
+msgid "Invalid combination: --isa=SHcompact with --abi=64"
+msgstr ""
+
+#: config/tc-sh.c:2718
+msgid ""
+"SH options:\n"
+"-little\t\t\tgenerate little endian code\n"
+"-big\t\t\tgenerate big endian code\n"
+"-relax\t\t\talter jump instructions for long displacements\n"
+"-small\t\t\talign sections to 4 byte boundaries, not 16\n"
+"-dsp\t\t\tenable sh-dsp insns, and disable sh2e/sh3e/sh4 insns.\n"
+msgstr ""
+
+#: config/tc-sh.c:2726
+msgid ""
+"-isa=[shmedia\t\tset default instruction set for SH64\n"
+" | SHmedia\n"
+" | shcompact\n"
+" | SHcompact]\n"
+"-abi=[32|64]\t\tset size of expanded SHmedia operands and object\n"
+"\t\t\tfile type\n"
+"-shcompact-const-crange\temit code-range descriptors for constants in\n"
+"\t\t\tSHcompact code sections\n"
+"-no-mix\t\t\tdisallow SHmedia code in the same section as\n"
+"\t\t\tconstants and SHcompact code\n"
+"-no-expand\t\tdo not expand MOVI, PT, PTA or PTB instructions\n"
+"-expand-pt32\t\twith -abi=64, expand PT, PTA and PTB instructions\n"
+"\t\t\tto 32 bits only"
+msgstr ""
+
+#: config/tc-sh.c:2823
+msgid ".uses does not refer to a local symbol in the same section"
+msgstr ""
+
+#: config/tc-sh.c:2842
+msgid "can't find fixup pointed to by .uses"
+msgstr ""
+
+#: config/tc-sh.c:2865
+msgid ".uses target does not refer to a local symbol in the same section"
+msgstr ""
+
+#: config/tc-sh.c:2967
+msgid "displacement overflows 12-bit field"
+msgstr ""
+
+#: config/tc-sh.c:2970
+#, c-format
+msgid "displacement to defined symbol %s overflows 12-bit field"
+msgstr ""
+
+#: config/tc-sh.c:2974
+#, c-format
+msgid "displacement to undefined symbol %s overflows 12-bit field"
+msgstr ""
+
+#: config/tc-sh.c:3052
+msgid "displacement overflows 8-bit field"
+msgstr ""
+
+#: config/tc-sh.c:3055
+#, c-format
+msgid "displacement to defined symbol %s overflows 8-bit field"
+msgstr ""
+
+#: config/tc-sh.c:3059
+#, c-format
+msgid "displacement to undefined symbol %s overflows 8-bit field "
+msgstr ""
+
+#: config/tc-sh.c:3076
+#, c-format
+msgid "overflow in branch to %s; converted into longer instruction sequence"
+msgstr ""
+
+#: config/tc-sh.c:3151 config/tc-sh.c:3199 config/tc-sparc.c:4192
+#: config/tc-sparc.c:4217
+msgid "misaligned data"
+msgstr ""
+
+#: config/tc-sh.c:3585
+msgid "misaligned offset"
+msgstr ""
+
+#: config/tc-sparc.c:287
+msgid "Invalid default architecture, broken assembler."
+msgstr ""
+
+#: config/tc-sparc.c:291 config/tc-sparc.c:494
+msgid "Bad opcode table, broken assembler."
+msgstr ""
+
+#: config/tc-sparc.c:486
+#, c-format
+msgid "invalid architecture -xarch=%s"
+msgstr ""
+
+#: config/tc-sparc.c:488
+#, c-format
+msgid "invalid architecture -A%s"
+msgstr ""
+
+#: config/tc-sparc.c:555
+#, c-format
+msgid "No compiled in support for %d bit object file format"
+msgstr ""
+
+#: config/tc-sparc.c:592
+msgid "Unrecognized option following -K"
+msgstr ""
+
+#: config/tc-sparc.c:633
+msgid "SPARC options:\n"
+msgstr ""
+
+#: config/tc-sparc.c:662
+msgid ""
+"\n"
+"\t\t\tspecify variant of SPARC architecture\n"
+"-bump\t\t\twarn when assembler switches architectures\n"
+"-sparc\t\t\tignored\n"
+"--enforce-aligned-data\tforce .long, etc., to be aligned correctly\n"
+"-relax\t\t\trelax jumps and branches (default)\n"
+"-no-relax\t\tavoid changing any jumps and branches\n"
+msgstr ""
+
+#: config/tc-sparc.c:670
+msgid "-k\t\t\tgenerate PIC\n"
+msgstr ""
+
+#: config/tc-sparc.c:674
+msgid ""
+"-32\t\t\tcreate 32 bit object file\n"
+"-64\t\t\tcreate 64 bit object file\n"
+msgstr ""
+
+#: config/tc-sparc.c:677
+#, c-format
+msgid "\t\t\t[default is %d]\n"
+msgstr ""
+
+#: config/tc-sparc.c:679
+msgid ""
+"-TSO\t\t\tuse Total Store Ordering\n"
+"-PSO\t\t\tuse Partial Store Ordering\n"
+"-RMO\t\t\tuse Relaxed Memory Ordering\n"
+msgstr ""
+
+#: config/tc-sparc.c:683
+#, c-format
+msgid "\t\t\t[default is %s]\n"
+msgstr ""
+
+#: config/tc-sparc.c:685
+msgid ""
+"-KPIC\t\t\tgenerate PIC\n"
+"-V\t\t\tprint assembler version number\n"
+"-undeclared-regs\tignore application global register usage without\n"
+"\t\t\tappropriate .register directive (default)\n"
+"-no-undeclared-regs\tforce error on application global register usage\n"
+"\t\t\twithout appropriate .register directive\n"
+"-q\t\t\tignored\n"
+"-Qy, -Qn\t\tignored\n"
+"-s\t\t\tignored\n"
+msgstr ""
+
+#: config/tc-sparc.c:697
+msgid ""
+"-EL\t\t\tgenerate code for a little endian machine\n"
+"-EB\t\t\tgenerate code for a big endian machine\n"
+"--little-endian-data\tgenerate code for a machine having big endian\n"
+" instructions and little endian data.\n"
+msgstr ""
+
+#: config/tc-sparc.c:817
+#, c-format
+msgid "Internal error: losing opcode: `%s' \"%s\"\n"
+msgstr ""
+
+#: config/tc-sparc.c:836
+#, c-format
+msgid "Internal error: can't find opcode `%s' for `%s'\n"
+msgstr ""
+
+#: config/tc-sparc.c:982
+msgid "Support for 64-bit arithmetic not compiled in."
+msgstr ""
+
+#: config/tc-sparc.c:1029
+msgid "set: number not in 0..4294967295 range"
+msgstr ""
+
+#: config/tc-sparc.c:1036
+msgid "set: number not in -2147483648..4294967295 range"
+msgstr ""
+
+#: config/tc-sparc.c:1096
+msgid "setsw: number not in -2147483648..4294967295 range"
+msgstr ""
+
+#: config/tc-sparc.c:1145
+msgid "setx: temporary register same as destination register"
+msgstr ""
+
+#: config/tc-sparc.c:1216
+msgid "setx: illegal temporary register g0"
+msgstr ""
+
+#: config/tc-sparc.c:1313
+msgid "FP branch in delay slot"
+msgstr ""
+
+#: config/tc-sparc.c:1329
+msgid "FP branch preceded by FP instruction; NOP inserted"
+msgstr ""
+
+#: config/tc-sparc.c:1369
+msgid "failed special case insn sanity check"
+msgstr ""
+
+#: config/tc-sparc.c:1457
+msgid ": invalid membar mask name"
+msgstr ""
+
+#: config/tc-sparc.c:1473
+msgid ": invalid membar mask expression"
+msgstr ""
+
+#: config/tc-sparc.c:1478
+msgid ": invalid membar mask number"
+msgstr ""
+
+#: config/tc-sparc.c:1493
+msgid ": invalid siam mode expression"
+msgstr ""
+
+#: config/tc-sparc.c:1498
+msgid ": invalid siam mode number"
+msgstr ""
+
+#: config/tc-sparc.c:1514
+msgid ": invalid prefetch function name"
+msgstr ""
+
+#: config/tc-sparc.c:1522
+msgid ": invalid prefetch function expression"
+msgstr ""
+
+#: config/tc-sparc.c:1527
+msgid ": invalid prefetch function number"
+msgstr ""
+
+#: config/tc-sparc.c:1555 config/tc-sparc.c:1567
+msgid ": unrecognizable privileged register"
+msgstr ""
+
+#: config/tc-sparc.c:1591 config/tc-sparc.c:1616
+msgid ": unrecognizable v9a or v9b ancillary state register"
+msgstr ""
+
+#: config/tc-sparc.c:1596
+msgid ": rd on write only ancillary state register"
+msgstr ""
+
+#. %sys_tick and %sys_tick_cmpr are v9bnotv9a
+#: config/tc-sparc.c:1604
+msgid ": unrecognizable v9a ancillary state register"
+msgstr ""
+
+#: config/tc-sparc.c:1640
+msgid ": asr number must be between 16 and 31"
+msgstr ""
+
+#: config/tc-sparc.c:1648
+msgid ": asr number must be between 0 and 31"
+msgstr ""
+
+#: config/tc-sparc.c:1658
+msgid ": expecting %asrN"
+msgstr ""
+
+#: config/tc-sparc.c:1840 config/tc-sparc.c:1878 config/tc-sparc.c:2279
+#: config/tc-sparc.c:2315
+#, c-format
+msgid "Illegal operands: %%%s requires arguments in ()"
+msgstr ""
+
+#: config/tc-sparc.c:1846
+#, c-format
+msgid ""
+"Illegal operands: %%%s cannot be used together with other relocs in the insn "
+"()"
+msgstr ""
+
+#: config/tc-sparc.c:1857
+#, c-format
+msgid "Illegal operands: %%%s can be only used with call __tls_get_addr"
+msgstr ""
+
+#: config/tc-sparc.c:2064
+msgid "detected global register use not covered by .register pseudo-op"
+msgstr ""
+
+#: config/tc-sparc.c:2135
+msgid ": There are only 64 f registers; [0-63]"
+msgstr ""
+
+#: config/tc-sparc.c:2137 config/tc-sparc.c:2149
+msgid ": There are only 32 f registers; [0-31]"
+msgstr ""
+
+#: config/tc-sparc.c:2327
+#, c-format
+msgid ""
+"Illegal operands: Can't do arithmetics other than + and - involving %%%s()"
+msgstr ""
+
+#: config/tc-sparc.c:2437
+#, c-format
+msgid "Illegal operands: Can't add non-constant expression to %%%s()"
+msgstr ""
+
+#: config/tc-sparc.c:2447
+#, c-format
+msgid ""
+"Illegal operands: Can't do arithmetics involving %%%s() of a relocatable "
+"symbol"
+msgstr ""
+
+#: config/tc-sparc.c:2465
+msgid ": PC-relative operand can't be a constant"
+msgstr ""
+
+#: config/tc-sparc.c:2472
+msgid ": TLS operand can't be a constant"
+msgstr ""
+
+#: config/tc-sparc.c:2505
+msgid ": invalid ASI name"
+msgstr ""
+
+#: config/tc-sparc.c:2513
+msgid ": invalid ASI expression"
+msgstr ""
+
+#: config/tc-sparc.c:2518
+msgid ": invalid ASI number"
+msgstr ""
+
+#: config/tc-sparc.c:2615
+msgid "OPF immediate operand out of range (0-0x1ff)"
+msgstr ""
+
+#: config/tc-sparc.c:2620
+msgid "non-immediate OPF operand, ignored"
+msgstr ""
+
+#: config/tc-sparc.c:2639
+msgid ": invalid cpreg name"
+msgstr ""
+
+#: config/tc-sparc.c:2668
+#, c-format
+msgid "Illegal operands%s"
+msgstr ""
+
+#: config/tc-sparc.c:2702
+#, c-format
+msgid "architecture bumped from \"%s\" to \"%s\" on \"%s\""
+msgstr ""
+
+#: config/tc-sparc.c:2738
+#, c-format
+msgid "Architecture mismatch on \"%s\"."
+msgstr ""
+
+#: config/tc-sparc.c:2739
+#, c-format
+msgid " (Requires %s; requested architecture is %s.)"
+msgstr ""
+
+#: config/tc-sparc.c:3325
+#, c-format
+msgid "bad or unhandled relocation type: 0x%02x"
+msgstr ""
+
+#: config/tc-sparc.c:3480
+#, c-format
+msgid "internal error: can't export reloc type %d (`%s')"
+msgstr ""
+
+#: config/tc-sparc.c:3644
+#, c-format
+msgid "BSS length (%d.) <0! Ignored."
+msgstr ""
+
+#: config/tc-sparc.c:3656
+msgid "bad .reserve segment -- expected BSS segment"
+msgstr ""
+
+#: config/tc-sparc.c:3673 read.c:2048
+msgid "missing alignment"
+msgstr ""
+
+#: config/tc-sparc.c:3684 config/tc-sparc.c:3835
+#, c-format
+msgid "alignment too large; assuming %d"
+msgstr ""
+
+#: config/tc-sparc.c:3690 config/tc-sparc.c:3841
+msgid "negative alignment"
+msgstr ""
+
+#: config/tc-sparc.c:3700 config/tc-sparc.c:3864 read.c:1251 read.c:2064
+msgid "alignment not a power of 2"
+msgstr ""
+
+#: config/tc-sparc.c:3778 config/tc-v850.c:233
+msgid "Expected comma after symbol-name"
+msgstr ""
+
+#: config/tc-sparc.c:3788 read.c:1392
+#, c-format
+msgid ".COMMon length (%lu) out of range ignored"
+msgstr ""
+
+#: config/tc-sparc.c:3807 config/tc-v850.c:266
+#, c-format
+msgid "Length of .comm \"%s\" is already %ld. Not changed to %d."
+msgstr ""
+
+#: config/tc-sparc.c:3821
+msgid "Expected comma after common length"
+msgstr ""
+
+#: config/tc-sparc.c:4062 config/tc-sparc.c:4072
+#, c-format
+msgid "register syntax is .register %%g[2367],{#scratch|symbolname|#ignore}"
+msgstr ""
+
+#: config/tc-sparc.c:4090
+msgid "redefinition of global register"
+msgstr ""
+
+#: config/tc-sparc.c:4101
+#, c-format
+msgid "Register symbol %s already defined."
+msgstr ""
+
+#: config/tc-sparc.c:4310
+#, c-format
+msgid "Illegal operands: %%r_plt in %d-byte data field"
+msgstr ""
+
+#: config/tc-sparc.c:4320
+#, c-format
+msgid "Illegal operands: %%r_tls_dtpoff in %d-byte data field"
+msgstr ""
+
+#: config/tc-sparc.c:4357
+#, c-format
+msgid "Illegal operands: Only %%r_%s%d allowed in %d-byte data fields"
+msgstr ""
+
+#: config/tc-sparc.c:4365 config/tc-sparc.c:4396 config/tc-sparc.c:4405
+#, c-format
+msgid "Illegal operands: %%r_%s%d requires arguments in ()"
+msgstr ""
+
+#: config/tc-sparc.c:4414
+#, c-format
+msgid "Illegal operands: garbage after %%r_%s%d()"
+msgstr ""
+
+#: config/tc-sparc.h:55
+msgid "sparc convert_frag\n"
+msgstr ""
+
+#: config/tc-sparc.h:57
+msgid "estimate_size_before_relax called"
+msgstr ""
+
+#: config/tc-tahoe.c:403
+msgid "The -a option doesn't exist. (Despite what the man page says!"
+msgstr ""
+
+#: config/tc-tahoe.c:407 config/tc-vax.c:3285
+#, c-format
+msgid "Displacement length %s ignored!"
+msgstr ""
+
+#: config/tc-tahoe.c:411 config/tc-vax.c:3277
+msgid "SYMBOL TABLE not implemented"
+msgstr ""
+
+#: config/tc-tahoe.c:415 config/tc-vax.c:3281
+msgid "TOKEN TRACE not implemented"
+msgstr ""
+
+#: config/tc-tahoe.c:419 config/tc-vax.c:3289
+#, c-format
+msgid "I don't need or use temp. file \"%s\"."
+msgstr ""
+
+#: config/tc-tahoe.c:423 config/tc-vax.c:3293
+msgid "I don't use an interpass file! -V ignored"
+msgstr ""
+
+#: config/tc-tahoe.c:437
+msgid ""
+"Tahoe options:\n"
+"-a\t\t\tignored\n"
+"-d LENGTH\t\tignored\n"
+"-J\t\t\tignored\n"
+"-S\t\t\tignored\n"
+"-t FILE\t\t\tignored\n"
+"-T\t\t\tignored\n"
+"-V\t\t\tignored\n"
+msgstr ""
+
+#: config/tc-tahoe.c:1066
+msgid "Casting a branch displacement is bad form, and is ignored."
+msgstr ""
+
+#: config/tc-tahoe.c:1122
+msgid "Couldn't parse the [index] in this operand."
+msgstr ""
+
+#: config/tc-tahoe.c:1128
+msgid "Couldn't find the opening '[' for the index of this operand."
+msgstr ""
+
+#: config/tc-tahoe.c:1168
+msgid "Couldn't find the opening '(' for the deref of this operand."
+msgstr ""
+
+#: config/tc-tahoe.c:1178
+msgid "Operand can't be both pre-inc and post-dec."
+msgstr ""
+
+#: config/tc-tahoe.c:1208
+msgid "I parsed 2 registers in this operand."
+msgstr ""
+
+#: config/tc-tahoe.c:1258
+msgid "Can't relocate expression error."
+msgstr ""
+
+#. This is an error. Tahoe doesn't allow any expressions
+#. bigger that a 32 bit long word. Any bigger has to be referenced
+#. by address.
+#: config/tc-tahoe.c:1265
+msgid "Expression is too large for a 32 bits."
+msgstr ""
+
+#: config/tc-tahoe.c:1270
+msgid "Junk at end of expression."
+msgstr ""
+
+#: config/tc-tahoe.c:1309
+msgid "Syntax error in direct register mode."
+msgstr ""
+
+#: config/tc-tahoe.c:1311
+msgid "You can't index a register in direct register mode."
+msgstr ""
+
+#: config/tc-tahoe.c:1314
+msgid "SP can't be the source operand with direct register addressing."
+msgstr ""
+
+#: config/tc-tahoe.c:1316
+msgid "Can't take the address of a register."
+msgstr ""
+
+#: config/tc-tahoe.c:1318
+msgid "Direct Register can't be used in a branch."
+msgstr ""
+
+#: config/tc-tahoe.c:1320
+msgid "For quad access, the register must be even and < 14."
+msgstr ""
+
+#: config/tc-tahoe.c:1322
+msgid "You can't cast a direct register."
+msgstr ""
+
+#: config/tc-tahoe.c:1328
+msgid "Using reg 14 for quadwords can tromp the FP register."
+msgstr ""
+
+#: config/tc-tahoe.c:1340
+msgid "Syntax error in auto-dec mode."
+msgstr ""
+
+#: config/tc-tahoe.c:1342
+msgid "You can't have an index auto dec mode."
+msgstr ""
+
+#: config/tc-tahoe.c:1344
+msgid "Auto dec mode cant be used for reading."
+msgstr ""
+
+#: config/tc-tahoe.c:1346
+msgid "Auto dec only works of the SP register."
+msgstr ""
+
+#: config/tc-tahoe.c:1348
+msgid "Auto dec can't be used in a branch."
+msgstr ""
+
+#: config/tc-tahoe.c:1350
+msgid "Auto dec won't work with quadwords."
+msgstr ""
+
+#: config/tc-tahoe.c:1357
+msgid "Syntax error in one of the auto-inc modes."
+msgstr ""
+
+#: config/tc-tahoe.c:1363
+msgid "Auto inc deferred only works of the SP register."
+msgstr ""
+
+#: config/tc-tahoe.c:1365
+msgid "You can't have an index auto inc deferred mode."
+msgstr ""
+
+#: config/tc-tahoe.c:1367 config/tc-tahoe.c:1378
+msgid "Auto inc can't be used in a branch."
+msgstr ""
+
+#: config/tc-tahoe.c:1374
+msgid "You can't write to an auto inc register."
+msgstr ""
+
+#: config/tc-tahoe.c:1376
+msgid "Auto inc only works of the SP register."
+msgstr ""
+
+#: config/tc-tahoe.c:1380
+msgid "Auto inc won't work with quadwords."
+msgstr ""
+
+#: config/tc-tahoe.c:1382
+msgid "You can't have an index in auto inc mode."
+msgstr ""
+
+#: config/tc-tahoe.c:1390
+msgid "You can't index the sp register."
+msgstr ""
+
+#: config/tc-tahoe.c:1396
+msgid "Syntax error in register displaced mode."
+msgstr ""
+
+#: config/tc-tahoe.c:1415
+msgid "An offest is needed for this operand."
+msgstr ""
+
+#: config/tc-tahoe.c:1427
+msgid "You can't index a register in immediate mode."
+msgstr ""
+
+#: config/tc-tahoe.c:1429
+msgid "Immediate access can't be used as an address."
+msgstr ""
+
+#: config/tc-tahoe.c:1540
+#, c-format
+msgid "Compiler bug: ODD number of bytes in arg structure %s."
+msgstr ""
+
+#: config/tc-tahoe.c:1567 config/tc-vax.c:1962
+msgid "Not enough operands"
+msgstr ""
+
+#: config/tc-tahoe.c:1577 config/tc-vax.c:1969
+msgid "Too many operands"
+msgstr ""
+
+#: config/tc-tahoe.c:1628 config/tc-vax.c:403
+#, c-format
+msgid "Ignoring statement due to \"%s\""
+msgstr ""
+
+#: config/tc-tahoe.c:1723
+#, c-format
+msgid "Compliler bug: Got a case (%d) I wasn't expecting."
+msgstr ""
+
+#: config/tc-tahoe.c:1817
+msgid "Real branch displacements must be expressions."
+msgstr ""
+
+#: config/tc-tahoe.c:1820
+#, c-format
+msgid "Complier error: I got an unknown synthetic branch :%c"
+msgstr ""
+
+#: config/tc-tahoe.c:1961
+#, c-format
+msgid "Barf, bad mode %x\n"
+msgstr ""
+
+#. Only word (et al.), align, or conditionals are allowed within
+#. .struct/.union.
+#: config/tc-tic54x.c:224
+msgid "pseudo-op illegal within .struct/.union"
+msgstr ""
+
+#: config/tc-tic54x.c:349
+msgid "C54x-specific command line options:\n"
+msgstr ""
+
+#: config/tc-tic54x.c:350
+msgid "-mfar-mode | -mf Use extended addressing\n"
+msgstr ""
+
+#: config/tc-tic54x.c:351
+msgid "-mcpu=<CPU version> Specify the CPU version\n"
+msgstr ""
+
+#: config/tc-tic54x.c:353
+msgid "-mcoff-version={0|1|2} Select COFF version\n"
+msgstr ""
+
+#: config/tc-tic54x.c:355
+msgid "-merrors-to-file <filename>\n"
+msgstr ""
+
+#: config/tc-tic54x.c:356
+msgid "-me <filename> Redirect errors to a file\n"
+msgstr ""
+
+#: config/tc-tic54x.c:478
+msgid "Comma and symbol expected for '.asg STRING, SYMBOL'"
+msgstr ""
+
+#: config/tc-tic54x.c:532
+msgid "Unterminated string after absolute expression"
+msgstr ""
+
+#: config/tc-tic54x.c:540
+msgid "Comma and symbol expected for '.eval EXPR, SYMBOL'"
+msgstr ""
+
+#: config/tc-tic54x.c:552
+msgid "symbols assigned with .eval must begin with a letter"
+msgstr ""
+
+#: config/tc-tic54x.c:810
+msgid "Offset on nested structures is ignored"
+msgstr ""
+
+#: config/tc-tic54x.c:861
+#, c-format
+msgid ".end%s without preceding .%s"
+msgstr ""
+
+#: config/tc-tic54x.c:928
+#, c-format
+msgid "Unrecognized struct/union tag '%s'"
+msgstr ""
+
+#: config/tc-tic54x.c:930
+msgid ".tag requires a structure tag"
+msgstr ""
+
+#: config/tc-tic54x.c:936
+msgid "Label required for .tag"
+msgstr ""
+
+#: config/tc-tic54x.c:955
+#, c-format
+msgid ".tag target '%s' undefined"
+msgstr ""
+
+#: config/tc-tic54x.c:1018
+#, c-format
+msgid ".field count '%d' out of range (1 <= X <= 32)"
+msgstr ""
+
+#: config/tc-tic54x.c:1046
+#, c-format
+msgid "Unrecognized field type '%c'"
+msgstr ""
+
+#. Disallow .byte with a non constant expression that will
+#. require relocation.
+#: config/tc-tic54x.c:1183
+msgid "Relocatable values require at least WORD storage"
+msgstr ""
+
+#: config/tc-tic54x.c:1245
+msgid "Use of .def/.ref is deprecated. Use .global instead"
+msgstr ""
+
+#: config/tc-tic54x.c:1444
+msgid ".space/.bes repeat count is negative, ignored"
+msgstr ""
+
+#: config/tc-tic54x.c:1449
+msgid ".space/.bes repeat count is zero, ignored"
+msgstr ""
+
+#: config/tc-tic54x.c:1527
+msgid "Missing size argument"
+msgstr ""
+
+#: config/tc-tic54x.c:1664
+msgid "CPU version has already been set"
+msgstr ""
+
+#: config/tc-tic54x.c:1668
+#, c-format
+msgid "Unrecognized version '%s'"
+msgstr ""
+
+#: config/tc-tic54x.c:1674
+msgid "Changing of CPU version on the fly not supported"
+msgstr ""
+
+#: config/tc-tic54x.c:1810
+msgid "p2align not supported on this target"
+msgstr ""
+
+#: config/tc-tic54x.c:1823
+msgid "Argument to .even ignored"
+msgstr ""
+
+#: config/tc-tic54x.c:1870
+msgid "Invalid field size, must be from 1 to 32"
+msgstr ""
+
+#: config/tc-tic54x.c:1883
+msgid "field size must be 16 when value is relocatable"
+msgstr ""
+
+#: config/tc-tic54x.c:1898
+msgid "field value truncated"
+msgstr ""
+
+#: config/tc-tic54x.c:2007 config/tc-tic54x.c:2324
+#, c-format
+msgid "Unrecognized section '%s'"
+msgstr ""
+
+#: config/tc-tic54x.c:2016
+msgid "Current section is unitialized, section name required for .clink"
+msgstr ""
+
+#: config/tc-tic54x.c:2230
+msgid "ENDLOOP without corresponding LOOP"
+msgstr ""
+
+#: config/tc-tic54x.c:2274
+msgid "Mixing of normal and extended addressing not supported"
+msgstr ""
+
+#: config/tc-tic54x.c:2280
+msgid "Extended addressing not supported on the specified CPU"
+msgstr ""
+
+#: config/tc-tic54x.c:2330
+msgid ".sblock may be used for initialized sections only"
+msgstr ""
+
+#: config/tc-tic54x.c:2361
+msgid "Symbol missing for .set/.equ"
+msgstr ""
+
+#: config/tc-tic54x.c:2420
+msgid ".var may only be used within a macro definition"
+msgstr ""
+
+#: config/tc-tic54x.c:2428
+msgid "Substitution symbols must begin with a letter"
+msgstr ""
+
+#: config/tc-tic54x.c:2522
+#, c-format
+msgid "Can't open macro library file '%s' for reading."
+msgstr ""
+
+#: config/tc-tic54x.c:2529
+#, c-format
+msgid "File '%s' not in macro archive format"
+msgstr ""
+
+#: config/tc-tic54x.c:2689
+#, c-format
+msgid "Bad COFF version '%s'"
+msgstr ""
+
+#: config/tc-tic54x.c:2698
+#, c-format
+msgid "Bad CPU version '%s'"
+msgstr ""
+
+#: config/tc-tic54x.c:2711 config/tc-tic54x.c:2714
+#, c-format
+msgid "Can't redirect stderr to the file '%s'"
+msgstr ""
+
+#: config/tc-tic54x.c:2861
+#, c-format
+msgid "Undefined substitution symbol '%s'"
+msgstr ""
+
+#: config/tc-tic54x.c:3518
+msgid "Badly formed address expression"
+msgstr ""
+
+#: config/tc-tic54x.c:3782
+#, c-format
+msgid "Invalid dmad syntax '%s'"
+msgstr ""
+
+#: config/tc-tic54x.c:3848
+#, c-format
+msgid ""
+"Use the .mmregs directive to use memory-mapped register names such as '%s'"
+msgstr ""
+
+#: config/tc-tic54x.c:3901
+msgid "Address mode *+ARx is write-only. Results of reading are undefined."
+msgstr ""
+
+#: config/tc-tic54x.c:3921
+#, c-format
+msgid "Unrecognized indirect address format \"%s\""
+msgstr ""
+
+#: config/tc-tic54x.c:3960
+#, c-format
+msgid "Operand '%s' out of range (%d <= x <= %d)"
+msgstr ""
+
+#: config/tc-tic54x.c:3980
+msgid "Error in relocation handling"
+msgstr ""
+
+#: config/tc-tic54x.c:4001 config/tc-tic54x.c:4065 config/tc-tic54x.c:4097
+#, c-format
+msgid "Unrecognized condition code \"%s\""
+msgstr ""
+
+#: config/tc-tic54x.c:4018
+#, c-format
+msgid "Condition \"%s\" does not match preceding group"
+msgstr ""
+
+#: config/tc-tic54x.c:4026
+#, c-format
+msgid ""
+"Condition \"%s\" uses a different accumulator from a preceding condition"
+msgstr ""
+
+#: config/tc-tic54x.c:4033
+msgid "Only one comparison conditional allowed"
+msgstr ""
+
+#: config/tc-tic54x.c:4038
+msgid "Only one overflow conditional allowed"
+msgstr ""
+
+#: config/tc-tic54x.c:4046
+#, c-format
+msgid "Duplicate %s conditional"
+msgstr ""
+
+#: config/tc-tic54x.c:4081
+msgid "Invalid auxiliary register (use AR0-AR7)"
+msgstr ""
+
+#: config/tc-tic54x.c:4117
+msgid "lk addressing modes are invalid for memory-mapped register addressing"
+msgstr ""
+
+#: config/tc-tic54x.c:4125
+msgid ""
+"Address mode *+ARx is not allowed in memory-mapped register addressing. "
+"Resulting behavior is undefined."
+msgstr ""
+
+#: config/tc-tic54x.c:4151
+msgid ""
+"Destination accumulator for each part of this parallel instruction must be "
+"different"
+msgstr ""
+
+#: config/tc-tic54x.c:4200
+#, c-format
+msgid "Memory mapped register \"%s\" out of range"
+msgstr ""
+
+#: config/tc-tic54x.c:4239
+msgid "Invalid operand (use 1, 2, or 3)"
+msgstr ""
+
+#: config/tc-tic54x.c:4264
+msgid "A status register or status bit name is required"
+msgstr ""
+
+#: config/tc-tic54x.c:4274
+#, c-format
+msgid "Unrecognized status bit \"%s\""
+msgstr ""
+
+#: config/tc-tic54x.c:4297
+#, c-format
+msgid "Invalid status register \"%s\""
+msgstr ""
+
+#: config/tc-tic54x.c:4309
+#, c-format
+msgid "Operand \"%s\" out of range (use 1 or 2)"
+msgstr ""
+
+#: config/tc-tic54x.c:4517
+#, c-format
+msgid "Unrecognized instruction \"%s\""
+msgstr ""
+
+#: config/tc-tic54x.c:4546
+#, c-format
+msgid "Unrecognized operand list '%s' for instruction '%s'"
+msgstr ""
+
+#: config/tc-tic54x.c:4578
+#, c-format
+msgid "Unrecognized parallel instruction \"%s\""
+msgstr ""
+
+#: config/tc-tic54x.c:4629
+#, c-format
+msgid "Invalid operand (s) for parallel instruction \"%s\""
+msgstr ""
+
+#: config/tc-tic54x.c:4632
+#, c-format
+msgid "Unrecognized parallel instruction combination \"%s || %s\""
+msgstr ""
+
+#: config/tc-tic54x.c:4869
+#, c-format
+msgid "%s symbol recursion stopped at second appearance of '%s'"
+msgstr ""
+
+#: config/tc-tic54x.c:4909
+msgid "Unrecognized substitution symbol function"
+msgstr ""
+
+#: config/tc-tic54x.c:4914
+msgid "Missing '(' after substitution symbol function"
+msgstr ""
+
+#: config/tc-tic54x.c:4928
+msgid "Expecting second argument"
+msgstr ""
+
+#: config/tc-tic54x.c:4941 config/tc-tic54x.c:4991
+msgid "Extra junk in function call, expecting ')'"
+msgstr ""
+
+#: config/tc-tic54x.c:4967
+msgid "Function expects two arguments"
+msgstr ""
+
+#: config/tc-tic54x.c:4980
+msgid "Expecting character constant argument"
+msgstr ""
+
+#: config/tc-tic54x.c:4986
+msgid "Both arguments must be substitution symbols"
+msgstr ""
+
+#: config/tc-tic54x.c:5039
+#, c-format
+msgid "Invalid subscript (use 1 to %d)"
+msgstr ""
+
+#: config/tc-tic54x.c:5049
+#, c-format
+msgid "Invalid length (use 0 to %d"
+msgstr ""
+
+#: config/tc-tic54x.c:5059
+msgid "Missing ')' in subscripted substitution symbol expression"
+msgstr ""
+
+#: config/tc-tic54x.c:5079
+msgid "Missing forced substitution terminator ':'"
+msgstr ""
+
+#: config/tc-tic54x.c:5252
+#, c-format
+msgid ""
+"Instruction does not fit in available delay slots (%d-word insn, %d slots "
+"left)"
+msgstr ""
+
+#: config/tc-tic54x.c:5293
+#, c-format
+msgid "Unrecognized parallel instruction '%s'"
+msgstr ""
+
+#: config/tc-tic54x.c:5305
+#, c-format
+msgid "Instruction '%s' requires an LP cpu version"
+msgstr ""
+
+#: config/tc-tic54x.c:5312
+#, c-format
+msgid "Instruction '%s' requires far mode addressing"
+msgstr ""
+
+#: config/tc-tic54x.c:5324
+#, c-format
+msgid ""
+"Instruction does not fit in available delay slots (%d-word insn, %d slots "
+"left). Resulting behavior is undefined."
+msgstr ""
+
+#: config/tc-tic54x.c:5334
+msgid ""
+"Instructions which cause PC discontinuity are not allowed in a delay slot. "
+"Resulting behavior is undefined."
+msgstr ""
+
+#: config/tc-tic54x.c:5345
+#, c-format
+msgid "'%s' is not repeatable. Resulting behavior is undefined."
+msgstr ""
+
+#: config/tc-tic54x.c:5349
+msgid ""
+"Instructions using long offset modifiers or absolute addresses are not "
+"repeatable. Resulting behavior is undefined."
+msgstr ""
+
+#: config/tc-tic54x.c:5545
+#, c-format
+msgid "Unsupported relocation size %d"
+msgstr ""
+
+#: config/tc-tic54x.c:5699
+msgid "non-absolute value used with .space/.bes"
+msgstr ""
+
+#: config/tc-tic54x.c:5703
+#, c-format
+msgid "negative value ignored in %s"
+msgstr ""
+
+#: config/tc-tic54x.c:5792
+#, c-format
+msgid "attempt to .space/.bes backwards? (%ld)"
+msgstr ""
+
+#: config/tc-tic54x.c:5826
+#, c-format
+msgid "Invalid label '%s'"
+msgstr ""
+
+#: config/tc-tic80.c:26
+#, c-format
+msgid "internal error:%s:%d: %s\n"
+msgstr ""
+
+#: config/tc-tic80.c:29
+#, c-format
+msgid "internal error:%s:%d: %s %ld\n"
+msgstr ""
+
+#: config/tc-tic80.c:89
+msgid "Relaxation is a luxury we can't afford"
+msgstr ""
+
+#: config/tc-tic80.c:138
+msgid "bad call to md_atof ()"
+msgstr ""
+
+#: config/tc-tic80.c:235
+msgid "':' not followed by 'm' or 's'"
+msgstr ""
+
+#: config/tc-tic80.c:248
+msgid "paren nesting"
+msgstr ""
+
+#: config/tc-tic80.c:262
+msgid "mismatched parenthesis"
+msgstr ""
+
+#: config/tc-tic80.c:464
+msgid "unhandled expression type"
+msgstr ""
+
+#: config/tc-tic80.c:678
+msgid "symbol reloc that is not PC relative or 32 bits"
+msgstr ""
+
+#: config/tc-tic80.c:707
+msgid "unhandled operand modifier"
+msgstr ""
+
+#: config/tc-tic80.c:749
+msgid "unhandled expression"
+msgstr ""
+
+#: config/tc-tic80.c:797
+#, c-format
+msgid "Invalid mnemonic: '%s'"
+msgstr ""
+
+#: config/tc-tic80.c:810
+#, c-format
+msgid "Invalid operands: '%s'"
+msgstr ""
+
+#: config/tc-tic80.c:888
+msgid "unhandled predefined symbol bits"
+msgstr ""
+
+#: config/tc-tic80.c:983
+#, c-format
+msgid "PC offset 0x%lx outside range 0x%lx-0x%lx"
+msgstr ""
+
+#: config/tc-tic80.c:998
+msgid "unhandled relocation type in fixup"
+msgstr ""
+
+#: config/tc-tic80.c:1037
+msgid "md_convert_frag() not implemented yet"
+msgstr ""
+
+#: config/tc-v850.c:244
+#, c-format
+msgid ".COMMon length (%d.) < 0! Ignored."
+msgstr ""
+
+#: config/tc-v850.c:293
+msgid "Common alignment negative; 0 assumed"
+msgstr ""
+
+#: config/tc-v850.c:974
+#, c-format
+msgid "unknown operand shift: %x\n"
+msgstr ""
+
+#: config/tc-v850.c:975
+msgid "internal failure in parse_register_list"
+msgstr ""
+
+#: config/tc-v850.c:991
+msgid "constant expression or register list expected"
+msgstr ""
+
+#: config/tc-v850.c:996 config/tc-v850.c:1009 config/tc-v850.c:1028
+msgid "high bits set in register list expression"
+msgstr ""
+
+#: config/tc-v850.c:1067 config/tc-v850.c:1130
+msgid "illegal register included in list"
+msgstr ""
+
+#: config/tc-v850.c:1073
+msgid "system registers cannot be included in list"
+msgstr ""
+
+#: config/tc-v850.c:1078
+msgid "PSW cannot be included in list"
+msgstr ""
+
+#: config/tc-v850.c:1085
+msgid "High value system registers cannot be included in list"
+msgstr ""
+
+#: config/tc-v850.c:1109
+msgid "second register should follow dash in register list"
+msgstr ""
+
+#: config/tc-v850.c:1154
+msgid " V850 options:\n"
+msgstr ""
+
+#: config/tc-v850.c:1155
+msgid " -mwarn-signed-overflow Warn if signed immediate values overflow\n"
+msgstr ""
+
+#: config/tc-v850.c:1156
+msgid ""
+" -mwarn-unsigned-overflow Warn if unsigned immediate values overflow\n"
+msgstr ""
+
+#: config/tc-v850.c:1157
+msgid " -mv850 The code is targeted at the v850\n"
+msgstr ""
+
+#: config/tc-v850.c:1158
+msgid " -mv850e The code is targeted at the v850e\n"
+msgstr ""
+
+#: config/tc-v850.c:1159
+msgid ""
+" -mv850any The code is generic, despite any processor "
+"specific instructions\n"
+msgstr ""
+
+#: config/tc-v850.c:1160
+msgid " -mrelax Enable relaxation\n"
+msgstr ""
+
+#: config/tc-v850.c:1172 config/tc-v850.c:1207
+#, c-format
+msgid "unknown command line option: -%c%s\n"
+msgstr ""
+
+#: config/tc-v850.c:1348
+#, c-format
+msgid "Unable to determine default target processor from string: %s"
+msgstr ""
+
+#: config/tc-v850.c:1385
+msgid "ctoff() relocation used on an instruction which does not support it"
+msgstr ""
+
+#: config/tc-v850.c:1411
+msgid "sdaoff() relocation used on an instruction which does not support it"
+msgstr ""
+
+#: config/tc-v850.c:1437
+msgid "zdaoff() relocation used on an instruction which does not support it"
+msgstr ""
+
+#: config/tc-v850.c:1474
+msgid "tdaoff() relocation used on an instruction which does not support it"
+msgstr ""
+
+#: config/tc-v850.c:1698
+msgid "Target processor does not support this instruction."
+msgstr ""
+
+#: config/tc-v850.c:1788 config/tc-v850.c:1817 config/tc-v850.c:2005
+msgid "immediate operand is too large"
+msgstr ""
+
+#: config/tc-v850.c:1799
+msgid "AAARG -> unhandled constant reloc"
+msgstr ""
+
+#: config/tc-v850.c:1843
+msgid "invalid register name"
+msgstr ""
+
+#: config/tc-v850.c:1848
+msgid "register r0 cannot be used here"
+msgstr ""
+
+#: config/tc-v850.c:1860
+msgid "invalid system register name"
+msgstr ""
+
+#: config/tc-v850.c:1873
+msgid "expected EP register"
+msgstr ""
+
+#: config/tc-v850.c:1890
+msgid "invalid condition code name"
+msgstr ""
+
+#: config/tc-v850.c:1911 config/tc-v850.c:1915
+msgid "constant too big to fit into instruction"
+msgstr ""
+
+#: config/tc-v850.c:1968
+msgid "syntax error: value is missing before the register name"
+msgstr ""
+
+#: config/tc-v850.c:1970
+msgid "syntax error: register not expected"
+msgstr ""
+
+#: config/tc-v850.c:1984
+msgid "syntax error: system register not expected"
+msgstr ""
+
+#: config/tc-v850.c:1989
+msgid "syntax error: condition code not expected"
+msgstr ""
+
+#: config/tc-v850.c:2030
+msgid "invalid operand"
+msgstr ""
+
+#: config/tc-vax.c:285
+#, c-format
+msgid "VIP_BEGIN error:%s"
+msgstr ""
+
+#: config/tc-vax.c:422
+#, c-format
+msgid "Aborting because statement has \"%s\""
+msgstr ""
+
+#: config/tc-vax.c:469
+msgid "Can't relocate expression"
+msgstr ""
+
+#: config/tc-vax.c:572
+msgid "Bignum not permitted in short literal. Immediate mode assumed."
+msgstr ""
+
+#: config/tc-vax.c:581
+msgid "Can't do flonum short literal: immediate mode used."
+msgstr ""
+
+#: config/tc-vax.c:626
+#, c-format
+msgid "A bignum/flonum may not be a displacement: 0x%lx used"
+msgstr ""
+
+#: config/tc-vax.c:961
+#, c-format
+msgid "Short literal overflow(%ld.), immediate mode assumed."
+msgstr ""
+
+#: config/tc-vax.c:970
+#, c-format
+msgid "Forced short literal to immediate mode. now_seg=%s to_seg=%s"
+msgstr ""
+
+#: config/tc-vax.c:1035
+msgid "Length specification ignored. Address mode 9F used"
+msgstr ""
+
+#: config/tc-vax.c:1096
+msgid "Invalid operand: immediate value used as base address."
+msgstr ""
+
+#: config/tc-vax.c:1098
+msgid "Invalid operand: immediate value used as address."
+msgstr ""
+
+#: config/tc-vax.c:1123
+msgid "Symbol used as immediate operand in PIC mode."
+msgstr ""
+
+#: config/tc-vax.c:1941
+msgid "odd number of bytes in operand description"
+msgstr ""
+
+#: config/tc-vax.c:1957
+msgid "Bad operand"
+msgstr ""
+
+#: config/tc-vax.c:2532
+msgid "no '[' to match ']'"
+msgstr ""
+
+#: config/tc-vax.c:2552
+msgid "bad register in []"
+msgstr ""
+
+#: config/tc-vax.c:2554
+msgid "[PC] index banned"
+msgstr ""
+
+#: config/tc-vax.c:2589
+msgid "no '(' to match ')'"
+msgstr ""
+
+#: config/tc-vax.c:2729
+msgid "invalid branch operand"
+msgstr ""
+
+#: config/tc-vax.c:2758
+msgid "address prohibits @"
+msgstr ""
+
+#: config/tc-vax.c:2760
+msgid "address prohibits #"
+msgstr ""
+
+#: config/tc-vax.c:2764
+msgid "address prohibits -()"
+msgstr ""
+
+#: config/tc-vax.c:2766
+msgid "address prohibits ()+"
+msgstr ""
+
+#: config/tc-vax.c:2769
+msgid "address prohibits ()"
+msgstr ""
+
+#: config/tc-vax.c:2771
+msgid "address prohibits []"
+msgstr ""
+
+#: config/tc-vax.c:2773
+msgid "address prohibits register"
+msgstr ""
+
+#: config/tc-vax.c:2775
+msgid "address prohibits displacement length specifier"
+msgstr ""
+
+#: config/tc-vax.c:2805
+msgid "invalid operand of S^#"
+msgstr ""
+
+#: config/tc-vax.c:2822
+msgid "S^# needs expression"
+msgstr ""
+
+#: config/tc-vax.c:2829
+msgid "S^# may only read-access"
+msgstr ""
+
+#: config/tc-vax.c:2854
+msgid "invalid operand of -()"
+msgstr ""
+
+#: config/tc-vax.c:2860
+msgid "-(PC) unpredictable"
+msgstr ""
+
+#: config/tc-vax.c:2862
+msgid "[]index same as -()register: unpredictable"
+msgstr ""
+
+#: config/tc-vax.c:2898
+msgid "invalid operand of ()+"
+msgstr ""
+
+#: config/tc-vax.c:2904
+msgid "(PC)+ unpredictable"
+msgstr ""
+
+#: config/tc-vax.c:2906
+msgid "[]index same as ()+register: unpredictable"
+msgstr ""
+
+#: config/tc-vax.c:2931
+msgid "# conflicts length"
+msgstr ""
+
+#: config/tc-vax.c:2933
+msgid "# bars register"
+msgstr ""
+
+#: config/tc-vax.c:2955
+msgid "writing or modifying # is unpredictable"
+msgstr ""
+
+#: config/tc-vax.c:2985
+msgid "length not needed"
+msgstr ""
+
+#: config/tc-vax.c:2992
+msgid "can't []index a register, because it has no address"
+msgstr ""
+
+#: config/tc-vax.c:2994
+msgid "a register has no address"
+msgstr ""
+
+#: config/tc-vax.c:3005
+msgid "PC part of operand unpredictable"
+msgstr ""
+
+#: config/tc-vax.c:3345
+msgid ""
+"VAX options:\n"
+"-d LENGTH\t\tignored\n"
+"-J\t\t\tignored\n"
+"-S\t\t\tignored\n"
+"-t FILE\t\t\tignored\n"
+"-T\t\t\tignored\n"
+"-V\t\t\tignored\n"
+msgstr ""
+
+#: config/tc-vax.c:3354
+msgid ""
+"VMS options:\n"
+"-+\t\t\thash encode names longer than 31 characters\n"
+"-1\t\t\t`const' handling compatible with gcc 1.x\n"
+"-H\t\t\tshow new symbol after hash truncation\n"
+"-h NUM\t\t\tdon't hash mixed-case names, and adjust case:\n"
+"\t\t\t0 = upper, 2 = lower, 3 = preserve case\n"
+"-v\"VERSION\"\t\tcode being assembled was produced by compiler \"VERSION\"\n"
+msgstr ""
+
+#: config/tc-w65.c:145
+msgid "need on or off."
+msgstr ""
+
+#: config/tc-w65.c:281 config/tc-w65.c:324
+msgid "syntax error after <exp"
+msgstr ""
+
+#: config/tc-xstormy16.c:80
+msgid " XSTORMY16 specific command line options:\n"
+msgstr ""
+
+#: config/tc-xstormy16.c:562
+#, c-format
+msgid "internal error: can't install fix for reloc type %d (`%s')"
+msgstr ""
+
+#: config/tc-xtensa.c:929
+msgid "'--density' option not supported in this Xtensa configuration"
+msgstr ""
+
+#: config/tc-xtensa.c:1030
+msgid ""
+"'--literal-section-name' is deprecated; use '--rename-section ."
+"literal=NEWNAME'"
+msgstr ""
+
+#: config/tc-xtensa.c:1036
+msgid ""
+"'--text-section-name' is deprecated; use '--rename-section .text=NEWNAME'"
+msgstr ""
+
+#: config/tc-xtensa.c:1042
+msgid ""
+"'--data-section-name' is deprecated; use '--rename-section .data=NEWNAME'"
+msgstr ""
+
+#: config/tc-xtensa.c:1048
+msgid "'--bss-section-name' is deprecated; use '--rename-section .bss=NEWNAME'"
+msgstr ""
+
+#: config/tc-xtensa.c:1186
+msgid "unmatched end directive"
+msgstr ""
+
+#: config/tc-xtensa.c:1215
+msgid ".begin directive with no matching .end directive"
+msgstr ""
+
+#: config/tc-xtensa.c:1259
+#, c-format
+msgid "directive %s can't be negated"
+msgstr ""
+
+#: config/tc-xtensa.c:1265
+msgid "unknown directive"
+msgstr ""
+
+#: config/tc-xtensa.c:1300
+msgid "cannot set literal_prefix inside literal fragment"
+msgstr ""
+
+#: config/tc-xtensa.c:1337 config/tc-xtensa.c:1371
+msgid "Xtensa density option not supported; ignored"
+msgstr ""
+
+#: config/tc-xtensa.c:1383
+#, c-format
+msgid "does not match begin %s%s at %s:%d"
+msgstr ""
+
+#: config/tc-xtensa.c:1429
+msgid ".literal_position inside literal directive; ignoring"
+msgstr ""
+
+#: config/tc-xtensa.c:1480
+msgid "expected comma or colon after symbol name; rest of line ignored"
+msgstr ""
+
+#: config/tc-xtensa.c:1655 config/tc-xtensa.c:1672
+#, c-format
+msgid "bad register name: %s"
+msgstr ""
+
+#: config/tc-xtensa.c:1661
+#, c-format
+msgid "bad register number: %s"
+msgstr ""
+
+#: config/tc-xtensa.c:1724
+msgid "register number out of range"
+msgstr ""
+
+#: config/tc-xtensa.c:1836
+msgid "too many arguments"
+msgstr ""
+
+#: config/tc-xtensa.c:1922
+#, c-format
+msgid "not enough operands (%d) for '%s'; expected %d"
+msgstr ""
+
+#: config/tc-xtensa.c:1929
+#, c-format
+msgid "too many operands (%d) for '%s'; expected %d"
+msgstr ""
+
+#: config/tc-xtensa.c:1973
+#, c-format
+msgid "register number for `%s' is not a constant"
+msgstr ""
+
+#: config/tc-xtensa.c:1978
+#, c-format
+msgid "register number (%ld) for `%s' is out of range"
+msgstr ""
+
+#: config/tc-xtensa.c:2464
+#, c-format
+msgid "operand %d not properly aligned for '%s'"
+msgstr ""
+
+#: config/tc-xtensa.c:2469
+#, c-format
+msgid "operand %d not in immediate table for '%s'"
+msgstr ""
+
+#: config/tc-xtensa.c:2474
+#, c-format
+msgid "operand %d too large for '%s'"
+msgstr ""
+
+#: config/tc-xtensa.c:2479
+#, c-format
+msgid "operand %d too small for '%s'"
+msgstr ""
+
+#: config/tc-xtensa.c:2484
+#, c-format
+msgid "operand %d is invalid for '%s'"
+msgstr ""
+
+#: config/tc-xtensa.c:3716
+msgid "INSTR_LABEL_DEF not supported yet"
+msgstr ""
+
+#: config/tc-xtensa.c:3745
+msgid "can't handle generation of literal/labels yet"
+msgstr ""
+
+#: config/tc-xtensa.c:3749
+msgid "can't handle undefined OP TYPE"
+msgstr ""
+
+#: config/tc-xtensa.c:3810
+#, c-format
+msgid "found %d operands for '%s': Expected %d"
+msgstr ""
+
+#: config/tc-xtensa.c:3817
+#, c-format
+msgid "found too many (%d) operands for '%s': Expected %d"
+msgstr ""
+
+#: config/tc-xtensa.c:4072
+msgid "instruction fragment may contain data"
+msgstr ""
+
+#: config/tc-xtensa.c:4105
+#, c-format
+msgid "invalid operand %d on '%s'"
+msgstr ""
+
+#: config/tc-xtensa.c:4116
+#, c-format
+msgid "invalid expression for operand %d on '%s'"
+msgstr ""
+
+#: config/tc-xtensa.c:4177
+#, c-format
+msgid "invalid relocation operand %i on '%s'"
+msgstr ""
+
+#: config/tc-xtensa.c:4186
+#, c-format
+msgid "undefined symbol for opcode \"%s\"."
+msgstr ""
+
+#: config/tc-xtensa.c:4280
+msgid "instruction with constant operands does not fit"
+msgstr ""
+
+#: config/tc-xtensa.c:4289
+msgid "instruction with constant operands does not fit without widening"
+msgstr ""
+
+#: config/tc-xtensa.c:4379
+msgid "instruction's constant operands do not fit"
+msgstr ""
+
+#: config/tc-xtensa.c:4718
+msgid "opcode 'NOP.N' unavailable in this configuration"
+msgstr ""
+
+#: config/tc-xtensa.c:4727
+msgid "opcode 'OR' unavailable in this configuration"
+msgstr ""
+
+#: config/tc-xtensa.c:4737
+#, c-format
+msgid "invalid %d-byte NOP requested"
+msgstr ""
+
+#: config/tc-xtensa.c:4757
+msgid "get_expanded_loop_offset: undefined opcode"
+msgstr ""
+
+#: config/tc-xtensa.c:4764
+msgid "get_expanded_loop_offset: invalid opcode"
+msgstr ""
+
+#: config/tc-xtensa.c:4880
+msgid "invalid last instruction for a zero-overhead loop"
+msgstr ""
+
+#: config/tc-xtensa.c:4935
+#, c-format
+msgid "cannot assemble '%s' into a literal fragment"
+msgstr ""
+
+#: config/tc-xtensa.c:4937
+msgid "..."
+msgstr ""
+
+#: config/tc-xtensa.c:5071
+msgid "entry instruction with stack decrement < 16"
+msgstr ""
+
+#: config/tc-xtensa.c:5075
+msgid "entry instruction with non-constant decrement"
+msgstr ""
+
+#: config/tc-xtensa.c:5152
+#, c-format
+msgid "undefined @ suffix '%s', expected '%s'"
+msgstr ""
+
+#: config/tc-xtensa.c:5242
+#, c-format
+msgid "invalid operand relocation for '%s' instruction"
+msgstr ""
+
+#: config/tc-xtensa.c:5245
+#, c-format
+msgid "invalid relocation for operand %d in '%s' instruction"
+msgstr ""
+
+#: config/tc-xtensa.c:5252
+#, c-format
+msgid "invalid relocation type %d for %s instruction"
+msgstr ""
+
+#: config/tc-xtensa.c:5261
+#, c-format
+msgid "invalid relocation for operand %d of '%s'"
+msgstr ""
+
+#: config/tc-xtensa.c:5269
+#, c-format
+msgid "non-PCREL relocation operand %d for '%s': %s"
+msgstr ""
+
+#: config/tc-xtensa.c:5328 config/tc-xtensa.c:5366
+#, c-format
+msgid "unhandled local relocation fix %s"
+msgstr ""
+
+#: config/tc-xtensa.c:5350
+msgid "undecodable FIX"
+msgstr ""
+
+#: config/tc-xtensa.c:5478
+msgid "emitting simplification relocation"
+msgstr ""
+
+#: config/tc-xtensa.c:5482
+msgid "emitting unknown relocation"
+msgstr ""
+
+#: config/tc-xtensa.c:5814
+#, c-format
+msgid "fr_var %lu < length %d; ignoring"
+msgstr ""
+
+#: config/tc-xtensa.c:6000 config/tc-xtensa.c:6044
+msgid "undecodable instruction in instruction frag"
+msgstr ""
+
+#: config/tc-xtensa.c:6092
+msgid "invalid empty loop"
+msgstr ""
+
+#: config/tc-xtensa.c:6097
+msgid "loop target does not follow loop instruction in section"
+msgstr ""
+
+#: config/tc-xtensa.c:6215
+msgid "get_text_align_power: argument too large"
+msgstr ""
+
+#: config/tc-xtensa.c:6420 config/tc-xtensa.c:6566
+msgid "invalid opcode for RELAX_ALIGN_NEXT_OPCODE"
+msgstr ""
+
+#: config/tc-xtensa.c:6421 config/tc-xtensa.c:6567
+msgid "cannot continue"
+msgstr ""
+
+#: config/tc-xtensa.c:6458
+msgid "expected loop opcode in relax align next target"
+msgstr ""
+
+#: config/tc-xtensa.c:6475
+msgid "expected align_code or RELAX_ALIGN_NEXT_OPCODE"
+msgstr ""
+
+#: config/tc-xtensa.c:6549 config/tc-xtensa.c:6587 config/tc-xtensa.c:6591
+#: config/tc-xtensa.c:6595
+msgid "internal error aligning"
+msgstr ""
+
+#: config/tc-xtensa.c:6676
+msgid "bad relaxation state"
+msgstr ""
+
+#: config/tc-xtensa.c:6752
+#, c-format
+msgid "fr_var (%ld) < length (%d); ignoring"
+msgstr ""
+
+#: config/tc-xtensa.c:6928
+msgid "internal error: relaxation failed"
+msgstr ""
+
+#: config/tc-xtensa.c:6934
+msgid "internal error: relaxation requires too many steps"
+msgstr ""
+
+#: config/tc-xtensa.c:7055
+msgid "invalid relaxation fragment result"
+msgstr ""
+
+#: config/tc-xtensa.c:7128
+msgid "unable to widen instruction"
+msgstr ""
+
+#: config/tc-xtensa.c:7215
+msgid "multiple literals in expansion"
+msgstr ""
+
+#: config/tc-xtensa.c:7219
+msgid "no registered fragment for literal"
+msgstr ""
+
+#: config/tc-xtensa.c:7221
+msgid "number of literal tokens != 1"
+msgstr ""
+
+#: config/tc-xtensa.c:7298 config/tc-xtensa.c:7304
+#, c-format
+msgid "unresolved loop target symbol: %s"
+msgstr ""
+
+#: config/tc-xtensa.c:7401
+msgid "loop relaxation specification does not correspond"
+msgstr ""
+
+#: config/tc-xtensa.c:7428
+msgid "loop too long for LOOP instruction"
+msgstr ""
+
+#: config/tc-xtensa.c:7465
+#, c-format
+msgid "invalid expression evaluation type %d"
+msgstr ""
+
+#: config/tc-xtensa.c:7702
+#, c-format
+msgid "fixes not all moved from %s"
+msgstr ""
+
+#: config/tc-xtensa.c:7835
+msgid "inlining literal pool; specify location with .literal_position."
+msgstr ""
+
+#: config/tc-xtensa.c:8230
+#, c-format
+msgid "could not create section %s"
+msgstr ""
+
+#: config/tc-xtensa.c:8232
+#, c-format
+msgid "invalid flag combination on section %s"
+msgstr ""
+
+#: config/tc-xtensa.c:8481
+#, c-format
+msgid "invalid symbolic operand %d on '%s'"
+msgstr ""
+
+#: config/tc-xtensa.c:8545
+msgid "operand number mismatch"
+msgstr ""
+
+#: config/tc-xtensa.c:8592
+msgid "invalid opcode"
+msgstr ""
+
+#: config/tc-xtensa.c:8598
+msgid "too few operands"
+msgstr ""
+
+#: config/tc-xtensa.c:8817
+msgid "ignoring extra '-rename-section' delimiter ':'"
+msgstr ""
+
+#: config/tc-xtensa.c:8822
+#, c-format
+msgid "ignoring invalid '-rename-section' specification: '%s'"
+msgstr ""
+
+#: config/tc-xtensa.c:8845
+#, c-format
+msgid "section %s renamed multiple times"
+msgstr ""
+
+#: config/tc-xtensa.c:8847
+#, c-format
+msgid "multiple sections remapped to output section %s"
+msgstr ""
+
+#: config/tc-z8k.c:314
+#, c-format
+msgid "register rr%d out of range"
+msgstr ""
+
+#: config/tc-z8k.c:316
+#, c-format
+msgid "register rr%d does not exist"
+msgstr ""
+
+#: config/tc-z8k.c:326
+#, c-format
+msgid "register rh%d out of range"
+msgstr ""
+
+#: config/tc-z8k.c:336
+#, c-format
+msgid "register rl%d out of range"
+msgstr ""
+
+#: config/tc-z8k.c:347
+#, c-format
+msgid "register rq%d out of range"
+msgstr ""
+
+#: config/tc-z8k.c:349
+#, c-format
+msgid "register rq%d does not exist"
+msgstr ""
+
+#: config/tc-z8k.c:359
+#, c-format
+msgid "register r%d out of range"
+msgstr ""
+
+#: config/tc-z8k.c:404
+#, c-format
+msgid "expected %c"
+msgstr ""
+
+#: config/tc-z8k.c:421
+#, c-format
+msgid "register is wrong size for a word %s"
+msgstr ""
+
+#: config/tc-z8k.c:437
+#, c-format
+msgid "register is wrong size for address %s"
+msgstr ""
+
+#. No interrupt type specified, opcode won't do anything.
+#: config/tc-z8k.c:585
+msgid "opcode has no effect"
+msgstr ""
+
+#: config/tc-z8k.c:697
+msgid "Missing ) in ra(rb)"
+msgstr ""
+
+#: config/tc-z8k.c:919 config/tc-z8k.c:925
+msgid "invalid indirect register size"
+msgstr ""
+
+#: config/tc-z8k.c:971
+#, c-format
+msgid "operand %s0x%x out of range"
+msgstr ""
+
+#: config/tc-z8k.c:1099
+msgid "immediate must be 1 or 2"
+msgstr ""
+
+#: config/tc-z8k.c:1102
+msgid "immediate 1 or 2 expected"
+msgstr ""
+
+#: config/tc-z8k.c:1129
+msgid "can't use R0 here"
+msgstr ""
+
+#: config/tc-z8k.c:1292
+msgid "Can't find opcode to match operands"
+msgstr ""
+
+#: config/tc-z8k.c:1411
+#, c-format
+msgid "invalid architecture -z%s"
+msgstr ""
+
+#: config/tc-z8k.c:1432
+msgid ""
+" Z8K options:\n"
+" -z8001 generate segmented code\n"
+" -z8002 generate unsegmented code\n"
+" -linkrelax create linker relaxable code\n"
+msgstr ""
+
+#: config/tc-z8k.c:1445
+msgid "call to md_convert_frag\n"
+msgstr ""
+
+#: config/tc-z8k.c:1476 config/tc-z8k.c:1487
+msgid "cannot branch to odd address"
+msgstr ""
+
+#: config/tc-z8k.c:1479 config/tc-z8k.c:1490
+msgid "relative jump out of range"
+msgstr ""
+
+#: config/tc-z8k.c:1497
+msgid "relative call out of range"
+msgstr ""
+
+#: config/tc-z8k.c:1523
+msgid "relative address out of range"
+msgstr ""
+
+#: config/tc-z8k.c:1543
+#, c-format
+msgid "md_apply_fix3: unknown r_type 0x%x\n"
+msgstr ""
+
+#: config/tc-z8k.c:1556
+msgid "call to md_estimate_size_before_relax\n"
+msgstr ""
+
+#: config/tc-z8k.c:1600
+#, c-format
+msgid "Can't subtract symbols in different sections %s %s"
+msgstr ""
+
+#: depend.c:200
+#, c-format
+msgid "can't open `%s' for writing"
+msgstr ""
+
+#: depend.c:212
+#, c-format
+msgid "can't close `%s'"
+msgstr ""
+
+#: dw2gencfi.c:262
+#, c-format
+msgid "register save offset not a multiple of %u"
+msgstr ""
+
+#: dw2gencfi.c:388
+msgid "missing separator"
+msgstr ""
+
+#: dw2gencfi.c:410 dw2gencfi.c:428
+msgid "bad register expression"
+msgstr ""
+
+#: dw2gencfi.c:450 dw2gencfi.c:547
+msgid "CFI instruction used without previous .cfi_startproc"
+msgstr ""
+
+#: dw2gencfi.c:579
+msgid "previous CFI entry not closed (missing .cfi_endproc)"
+msgstr ""
+
+#: dw2gencfi.c:612
+msgid ".cfi_endproc without corresponding .cfi_startproc"
+msgstr ""
+
+#: dw2gencfi.c:987
+msgid "open CFI at the end of file; missing .cfi_endproc directive"
+msgstr ""
+
+#: dwarf2dbg.c:468 dwarf2dbg.c:498
+msgid "file number less than one"
+msgstr ""
+
+#: dwarf2dbg.c:474
+#, c-format
+msgid "file number %ld already allocated"
+msgstr ""
+
+#: dwarf2dbg.c:503 dwarf2dbg.c:1064
+#, c-format
+msgid "unassigned file number %ld"
+msgstr ""
+
+#: dwarf2dbg.c:1130 dwarf2dbg.c:1327
+msgid "internal error: unknown dwarf2 format"
+msgstr ""
+
+#: dwarf2dbg.c:1472 dwarf2dbg.c:1480 dwarf2dbg.c:1488 dwarf2dbg.c:1509
+msgid "dwarf2 is not supported for this object file format"
+msgstr ""
+
+#: ecoff.c:1556
+#, c-format
+msgid "string too big (%lu bytes)"
+msgstr ""
+
+#: ecoff.c:1582
+#, c-format
+msgid "inserting \"%s\" into string hash table: %s"
+msgstr ""
+
+#: ecoff.c:1614 ecoff.c:1808 ecoff.c:1833 ecoff.c:1865 ecoff.c:2019
+#: ecoff.c:2132
+msgid "no current file pointer"
+msgstr ""
+
+#: ecoff.c:1701
+msgid "too many st_End's"
+msgstr ""
+
+#: ecoff.c:2044
+#, c-format
+msgid "inserting \"%s\" into tag hash table: %s"
+msgstr ""
+
+#: ecoff.c:2210
+msgid "fake .file after real one"
+msgstr ""
+
+#: ecoff.c:2300
+msgid "filename goes over one page boundary"
+msgstr ""
+
+#: ecoff.c:2435
+msgid ".begin directive without a preceding .file directive"
+msgstr ""
+
+#: ecoff.c:2442
+msgid ".begin directive without a preceding .ent directive"
+msgstr ""
+
+#: ecoff.c:2474
+msgid ".bend directive without a preceding .file directive"
+msgstr ""
+
+#: ecoff.c:2481
+msgid ".bend directive without a preceding .ent directive"
+msgstr ""
+
+#: ecoff.c:2494
+msgid ".bend directive names unknown symbol"
+msgstr ""
+
+#: ecoff.c:2538
+msgid ".def pseudo-op used inside of .def/.endef; ignored"
+msgstr ""
+
+#: ecoff.c:2540
+msgid "empty symbol name in .def; ignored"
+msgstr ""
+
+#: ecoff.c:2578
+msgid ".dim pseudo-op used outside of .def/.endef; ignored"
+msgstr ""
+
+#: ecoff.c:2593
+msgid "badly formed .dim directive"
+msgstr ""
+
+#: ecoff.c:2606
+msgid "too many .dim entries"
+msgstr ""
+
+#: ecoff.c:2627
+msgid ".scl pseudo-op used outside of .def/.endef; ignored"
+msgstr ""
+
+#: ecoff.c:2653
+msgid ".size pseudo-op used outside of .def/.endef; ignored"
+msgstr ""
+
+#: ecoff.c:2668
+msgid "badly formed .size directive"
+msgstr ""
+
+#: ecoff.c:2681
+msgid "too many .size entries"
+msgstr ""
+
+#: ecoff.c:2704
+msgid ".type pseudo-op used outside of .def/.endef; ignored"
+msgstr ""
+
+#. FIXME: We could handle this by setting the continued bit.
+#. There would still be a limit: the .type argument can not
+#. be infinite.
+#: ecoff.c:2722
+#, c-format
+msgid "the type of %s is too complex; it will be simplified"
+msgstr ""
+
+#: ecoff.c:2733
+msgid "Unrecognized .type argument"
+msgstr ""
+
+#: ecoff.c:2772
+msgid ".tag pseudo-op used outside of .def/.endef; ignored"
+msgstr ""
+
+#: ecoff.c:2798
+msgid ".val pseudo-op used outside of .def/.endef; ignored"
+msgstr ""
+
+#: ecoff.c:2806
+msgid ".val expression is too copmlex"
+msgstr ""
+
+#: ecoff.c:2837
+msgid ".endef pseudo-op used before .def; ignored"
+msgstr ""
+
+#: ecoff.c:2863 ecoff.c:2944
+msgid "bad COFF debugging information"
+msgstr ""
+
+#: ecoff.c:2912
+#, c-format
+msgid "no tag specified for %s"
+msgstr ""
+
+#: ecoff.c:3015
+msgid ".end directive without a preceding .file directive"
+msgstr ""
+
+#: ecoff.c:3022
+msgid ".end directive without a preceding .ent directive"
+msgstr ""
+
+#: ecoff.c:3044
+msgid ".end directive names unknown symbol"
+msgstr ""
+
+#: ecoff.c:3072
+msgid "second .ent directive found before .end directive"
+msgstr ""
+
+#: ecoff.c:3146
+msgid "no way to handle .file within .ent/.end section"
+msgstr ""
+
+#: ecoff.c:3271
+msgid ".loc before .file"
+msgstr ""
+
+#: ecoff.c:3410
+msgid "bad .weakext directive"
+msgstr ""
+
+#: ecoff.c:3479
+#, c-format
+msgid ".stab%c is not supported"
+msgstr ""
+
+#: ecoff.c:3489
+#, c-format
+msgid ".stab%c: ignoring non-zero other field"
+msgstr ""
+
+#: ecoff.c:3523
+#, c-format
+msgid ""
+"line number (%d) for .stab%c directive cannot fit in index field (20 bits)"
+msgstr ""
+
+#: ecoff.c:3559
+#, c-format
+msgid "illegal .stab%c directive, bad character"
+msgstr ""
+
+#: ecoff.c:4021 ecoff.c:4210 ecoff.c:4235
+msgid ".begin/.bend in different segments"
+msgstr ""
+
+#: ecoff.c:4737
+msgid "missing .end or .bend at end of file"
+msgstr ""
+
+#: ecoff.c:5227
+msgid "GP prologue size exceeds field size, using 0 instead"
+msgstr ""
+
+#: expr.c:83 read.c:3232
+msgid "bignum invalid"
+msgstr ""
+
+#: expr.c:85 read.c:3234 read.c:3574 read.c:4474
+msgid "floating point number invalid"
+msgstr ""
+
+#: expr.c:243
+msgid "bad floating-point constant: exponent overflow"
+msgstr ""
+
+#: expr.c:247
+#, c-format
+msgid "bad floating-point constant: unknown error code=%d"
+msgstr ""
+
+#: expr.c:425
+msgid ""
+"a bignum with underscores may not have more than 8 hex digits in any word"
+msgstr ""
+
+#: expr.c:448
+msgid "a bignum with underscores must have exactly 4 words"
+msgstr ""
+
+#. Either not seen or not defined.
+#. @@ Should print out the original string instead of
+#. the parsed number.
+#: expr.c:571
+#, c-format
+msgid "backward ref to unknown label \"%d:\""
+msgstr ""
+
+#: expr.c:694
+msgid "character constant too large"
+msgstr ""
+
+#: expr.c:942
+#, c-format
+msgid "expr.c(operand): bad atof_generic return val %d"
+msgstr ""
+
+#: expr.c:1004
+#, c-format
+msgid "missing '%c'"
+msgstr ""
+
+#: expr.c:1016 read.c:3945
+msgid "EBCDIC constants are not supported"
+msgstr ""
+
+#: expr.c:1099
+#, c-format
+msgid "Unary operator %c ignored because bad operand follows"
+msgstr ""
+
+#: expr.c:1145 expr.c:1170
+msgid "syntax error in .startof. or .sizeof."
+msgstr ""
+
+#: expr.c:1666
+msgid "missing operand; zero assumed"
+msgstr ""
+
+#: expr.c:1701
+msgid "left operand is a bignum; integer 0 assumed"
+msgstr ""
+
+#: expr.c:1703
+msgid "left operand is a float; integer 0 assumed"
+msgstr ""
+
+#: expr.c:1712
+msgid "right operand is a bignum; integer 0 assumed"
+msgstr ""
+
+#: expr.c:1714
+msgid "right operand is a float; integer 0 assumed"
+msgstr ""
+
+#: expr.c:1770 symbols.c:1191
+msgid "division by zero"
+msgstr ""
+
+#: expr.c:1868
+msgid "operation combines symbols in different segments"
+msgstr ""
+
+#: frags.c:48
+msgid "attempt to allocate data in absolute section"
+msgstr ""
+
+#: frags.c:54
+msgid "attempt to allocate data in common section"
+msgstr ""
+
+#: frags.c:107
+#, c-format
+msgid "can't extend frag %u chars"
+msgstr ""
+
+#. Detect if we are reading from stdin by examining the file
+#. name returned by as_where().
+#.
+#. [FIXME: We rely upon the name in the strcmp below being the
+#. same as the one used by input_scrub_new_file(), if that is
+#. not true, then this code will fail].
+#.
+#. If we are reading from stdin, then we need to save each input
+#. line here (assuming of course that we actually have a line of
+#. input to read), so that it can be displayed in the listing
+#. that is produced at the end of the assembly.
+#: input-file.c:145 input-scrub.c:242 listing.c:343
+msgid "{standard input}"
+msgstr ""
+
+#: input-file.c:149
+#, c-format
+msgid "can't open %s for reading"
+msgstr ""
+
+#: input-file.c:212 input-file.c:239
+#, c-format
+msgid "Can't read from %s"
+msgstr ""
+
+#: input-file.c:247
+#, c-format
+msgid "Can't close %s"
+msgstr ""
+
+#: input-scrub.c:272
+msgid "macros nested too deeply"
+msgstr ""
+
+#: input-scrub.c:375 input-scrub.c:397
+msgid "partial line at end of file ignored"
+msgstr ""
+
+#: itbl-ops.c:351
+msgid "Unable to allocate memory for new instructions\n"
+msgstr ""
+
+#: listing.c:243
+msgid "Warning:"
+msgstr ""
+
+#: listing.c:250
+msgid "Error:"
+msgstr ""
+
+#: listing.c:1130
+#, c-format
+msgid "can't open list file: %s"
+msgstr ""
+
+#: listing.c:1154
+#, c-format
+msgid "error closing list file: %s"
+msgstr ""
+
+#: listing.c:1233
+msgid "strange paper height, set to no form"
+msgstr ""
+
+#: listing.c:1299
+msgid "new line in title"
+msgstr ""
+
+#. Turns the next expression into a string.
+#: macro.c:382
+#, no-c-format
+msgid "% operator needs absolute expression"
+msgstr ""
+
+#: macro.c:545
+msgid "unexpected end of file in macro definition"
+msgstr ""
+
+#: macro.c:554
+msgid "missing ) after formals"
+msgstr ""
+
+#: macro.c:703
+msgid "missplaced )"
+msgstr ""
+
+#: macro.c:960
+msgid "confusion in formal parameters"
+msgstr ""
+
+#: macro.c:965
+msgid "macro formal argument does not exist"
+msgstr ""
+
+#: macro.c:980
+msgid "can't mix positional and keyword arguments"
+msgstr ""
+
+#: macro.c:988
+msgid "too many positional arguments"
+msgstr ""
+
+#: macro.c:1163
+msgid "unexpected end of file in irp or irpc"
+msgstr ""
+
+#: macro.c:1171
+msgid "missing model parameter"
+msgstr ""
+
+#: messages.c:104
+msgid "Assembler messages:\n"
+msgstr ""
+
+#: messages.c:214
+msgid "Warning: "
+msgstr ""
+
+#: messages.c:318
+msgid "Error: "
+msgstr ""
+
+#: messages.c:413 messages.c:433
+msgid "Fatal error: "
+msgstr ""
+
+#: messages.c:450
+msgid "Internal error!\n"
+msgstr ""
+
+#: messages.c:452
+#, c-format
+msgid "Assertion failure in %s at %s line %d.\n"
+msgstr ""
+
+#: messages.c:455
+#, c-format
+msgid "Assertion failure at %s line %d.\n"
+msgstr ""
+
+#: messages.c:456 messages.c:475
+msgid "Please report this bug.\n"
+msgstr ""
+
+#: messages.c:470
+#, c-format
+msgid "Internal error, aborting at %s line %d in %s\n"
+msgstr ""
+
+#: messages.c:473
+#, c-format
+msgid "Internal error, aborting at %s line %d\n"
+msgstr ""
+
+#: output-file.c:48
+#, c-format
+msgid "can't open a bfd on stdout %s"
+msgstr ""
+
+#: output-file.c:52 output-file.c:115
+#, c-format
+msgid "FATAL: can't create %s"
+msgstr ""
+
+#: output-file.c:73 output-file.c:80
+#, c-format
+msgid "FATAL: can't close %s\n"
+msgstr ""
+
+#: output-file.c:126
+#, c-format
+msgid "FATAL: can't close %s"
+msgstr ""
+
+#: output-file.c:147
+msgid "Failed to emit an object byte"
+msgstr ""
+
+#: output-file.c:148
+msgid "can't continue"
+msgstr ""
+
+#: read.c:442
+#, c-format
+msgid "error constructing %s pseudo-op table: %s"
+msgstr ""
+
+#: read.c:809
+#, c-format
+msgid "unknown pseudo-op: `%s'"
+msgstr ""
+
+#: read.c:940
+#, c-format
+msgid "label \"%d$\" redefined"
+msgstr ""
+
+#: read.c:1152
+msgid ".abort detected. Abandoning ship."
+msgstr ""
+
+#: read.c:1174 read.c:2413
+msgid "ignoring fill value in absolute section"
+msgstr ""
+
+#: read.c:1260
+#, c-format
+msgid "alignment too large: %u assumed"
+msgstr ""
+
+#: read.c:1292
+msgid "expected fill pattern missing"
+msgstr ""
+
+#: read.c:1417
+#, c-format
+msgid "length of .comm \"%s\" is already %ld; not changing to %ld"
+msgstr ""
+
+#. Some of the back ends can't deal with non-positive line numbers.
+#. Besides, it's silly.
+#: read.c:1636
+#, c-format
+msgid "line numbers must be positive; line number %d rejected"
+msgstr ""
+
+#: read.c:1664
+msgid "start address not supported"
+msgstr ""
+
+#: read.c:1674
+msgid ".err encountered"
+msgstr ""
+
+#: read.c:1693 read.c:1695
+#, c-format
+msgid ".fail %ld encountered"
+msgstr ""
+
+#: read.c:1732
+#, c-format
+msgid ".fill size clamped to %d"
+msgstr ""
+
+#: read.c:1737
+msgid "size negative; .fill ignored"
+msgstr ""
+
+#: read.c:1743
+msgid "repeat < 0; .fill ignored"
+msgstr ""
+
+#: read.c:1903
+#, c-format
+msgid "unrecognized .linkonce type `%s'"
+msgstr ""
+
+#: read.c:1916 read.c:1942
+msgid ".linkonce is not supported for this object file format"
+msgstr ""
+
+#: read.c:1938
+#, c-format
+msgid "bfd_set_section_flags: %s"
+msgstr ""
+
+#: read.c:1993
+msgid "missing size expression"
+msgstr ""
+
+#: read.c:1999
+#, c-format
+msgid "BSS length (%d) < 0 ignored"
+msgstr ""
+
+#: read.c:2015
+#, c-format
+msgid "error setting flags for \".sbss\": %s"
+msgstr ""
+
+#: read.c:2038
+msgid "expected comma after size"
+msgstr ""
+
+#: read.c:2072
+#, c-format
+msgid "alignment too large; %d assumed"
+msgstr ""
+
+#: read.c:2077
+msgid "alignment negative; 0 assumed"
+msgstr ""
+
+#: read.c:2342
+#, c-format
+msgid "attempt to redefine pseudo-op `%s' ignored"
+msgstr ""
+
+#: read.c:2408
+#, c-format
+msgid "invalid segment \"%s\""
+msgstr ""
+
+#: read.c:2416
+msgid "only constant offsets supported in absolute section"
+msgstr ""
+
+#: read.c:2456
+msgid "MRI style ORG pseudo-op not supported"
+msgstr ""
+
+#: read.c:2613
+#, c-format
+msgid "unrecognized section type `%s'"
+msgstr ""
+
+#: read.c:2627
+msgid "absolute sections are not supported"
+msgstr ""
+
+#: read.c:2642
+#, c-format
+msgid "unrecognized section command `%s'"
+msgstr ""
+
+#: read.c:2708
+msgid ".endr encountered without preceeding .rept, .irc, or .irp"
+msgstr ""
+
+#: read.c:2740
+#, c-format
+msgid "%s without %s"
+msgstr ""
+
+#: read.c:2949
+msgid "unsupported variable size or fill value"
+msgstr ""
+
+#: read.c:2974
+msgid ".space repeat count is zero, ignored"
+msgstr ""
+
+#: read.c:2976
+msgid ".space repeat count is negative, ignored"
+msgstr ""
+
+#: read.c:3005
+msgid "space allocation too complex in absolute section"
+msgstr ""
+
+#: read.c:3011
+msgid "space allocation too complex in common section"
+msgstr ""
+
+#: read.c:3099 read.c:4190
+#, c-format
+msgid "bad floating literal: %s"
+msgstr ""
+
+#: read.c:3172
+#, c-format
+msgid "rest of line ignored; first ignored character is `%c'"
+msgstr ""
+
+#: read.c:3175
+#, c-format
+msgid "rest of line ignored; first ignored character valued 0x%x"
+msgstr ""
+
+#: read.c:3228
+msgid "missing expression"
+msgstr ""
+
+#: read.c:3404
+msgid "rva without symbol"
+msgstr ""
+
+#: read.c:3530
+msgid "attempt to store value in absolute section"
+msgstr ""
+
+#: read.c:3568 read.c:4468
+msgid "zero assumed for missing expression"
+msgstr ""
+
+#: read.c:3580 read.c:4480 write.c:322
+msgid "register value used as expression"
+msgstr ""
+
+#. Leading bits contain both 0s & 1s.
+#: read.c:3671
+#, c-format
+msgid "value 0x%lx truncated to 0x%lx"
+msgstr ""
+
+#: read.c:3687
+#, c-format
+msgid "bignum truncated to %d bytes"
+msgstr ""
+
+#: read.c:3854
+msgid "using a bit field width of zero"
+msgstr ""
+
+#: read.c:3862
+#, c-format
+msgid "field width \"%s\" too complex for a bitfield"
+msgstr ""
+
+#: read.c:3870
+#, c-format
+msgid "field width %lu too big to fit in %d bytes: truncated to %d bits"
+msgstr ""
+
+#: read.c:3892
+#, c-format
+msgid "field value \"%s\" too complex for a bitfield"
+msgstr ""
+
+#: read.c:4018 read.c:4212
+msgid "unresolvable or nonpositive repeat count; using 1"
+msgstr ""
+
+#: read.c:4069
+#, c-format
+msgid "unknown floating type type '%c'"
+msgstr ""
+
+#: read.c:4091
+msgid "floating point constant too large"
+msgstr ""
+
+#: read.c:4581
+msgid "strings must be placed into a section"
+msgstr ""
+
+#: read.c:4631
+msgid "expected <nn>"
+msgstr ""
+
+#. To be compatible with BSD 4.2 as: give the luser a linefeed!!
+#: read.c:4664 read.c:4750
+msgid "unterminated string; newline inserted"
+msgstr ""
+
+#: read.c:4758
+msgid "bad escaped character in string"
+msgstr ""
+
+#: read.c:4784
+msgid "expected address expression"
+msgstr ""
+
+#: read.c:4804
+#, c-format
+msgid "symbol \"%s\" undefined; zero assumed"
+msgstr ""
+
+#: read.c:4807
+msgid "some symbol undefined; zero assumed"
+msgstr ""
+
+#: read.c:4824
+msgid "bad or irreducible absolute expression"
+msgstr ""
+
+#: read.c:4867
+msgid "this string may not contain '\\0'"
+msgstr ""
+
+#: read.c:4904
+msgid "missing string"
+msgstr ""
+
+#: read.c:5027
+#, c-format
+msgid ".incbin count zero, ignoring `%s'"
+msgstr ""
+
+#: read.c:5053
+#, c-format
+msgid "file not found: %s"
+msgstr ""
+
+#: read.c:5067
+#, c-format
+msgid "seek to end of .incbin file failed `%s'"
+msgstr ""
+
+#: read.c:5078
+#, c-format
+msgid "skip (%ld) + count (%ld) larger than file size (%ld)"
+msgstr ""
+
+#: read.c:5085
+#, c-format
+msgid "could not skip to %ld in file `%s'"
+msgstr ""
+
+#: read.c:5094
+#, c-format
+msgid "truncated file `%s', %ld of %ld bytes read"
+msgstr ""
+
+#: read.c:5257
+msgid "missing .func"
+msgstr ""
+
+#: read.c:5274
+msgid ".endfunc missing for previous .func"
+msgstr ""
+
+#: stabs.c:220 stabs.c:228 stabs.c:236 stabs.c:255
+#, c-format
+msgid ".stab%c: missing comma"
+msgstr ""
+
+#. This could happen for example with a source file with a huge
+#. number of lines. The only cure is to use a different debug
+#. format, probably DWARF.
+#: stabs.c:248
+#, c-format
+msgid ".stab%c: description field '%x' too big, try a different debug format"
+msgstr ""
+
+#: stabs.c:433
+msgid "comma missing in .xstabs"
+msgstr ""
+
+#: subsegs.c:377
+#, c-format
+msgid "attempt to switch to nonexistent segment \"%s\""
+msgstr ""
+
+#: symbols.c:318
+#, c-format
+msgid "cannot define symbol `%s' in absolute section"
+msgstr ""
+
+#: symbols.c:452
+#, c-format
+msgid "symbol `%s' is already defined as \"%s\"/%s%ld"
+msgstr ""
+
+#: symbols.c:529 symbols.c:536
+#, c-format
+msgid "inserting \"%s\" into symbol table failed: %s"
+msgstr ""
+
+#: symbols.c:874 symbols.c:878
+#, c-format
+msgid "undefined symbol `%s' in operation"
+msgstr ""
+
+#: symbols.c:885
+#, c-format
+msgid "invalid sections for operation on `%s' and `%s'"
+msgstr ""
+
+#: symbols.c:889
+#, c-format
+msgid "invalid section for operation on `%s'"
+msgstr ""
+
+#: symbols.c:897 symbols.c:900
+#, c-format
+msgid "undefined symbol `%s' in operation setting `%s'"
+msgstr ""
+
+#: symbols.c:907
+#, c-format
+msgid "invalid sections for operation on `%s' and `%s' setting `%s'"
+msgstr ""
+
+#: symbols.c:911
+#, c-format
+msgid "invalid section for operation on `%s' setting `%s'"
+msgstr ""
+
+#: symbols.c:964
+#, c-format
+msgid "symbol definition loop encountered at `%s'"
+msgstr ""
+
+#: symbols.c:1193
+#, c-format
+msgid "division by zero when setting `%s'"
+msgstr ""
+
+#: symbols.c:1280 write.c:2008
+#, c-format
+msgid "can't resolve value for symbol `%s'"
+msgstr ""
+
+#: symbols.c:1674
+#, c-format
+msgid "\"%d\" (instance number %d of a %s label)"
+msgstr ""
+
+#: symbols.c:1711
+#, c-format
+msgid "attempt to get value of unresolved symbol `%s'"
+msgstr ""
+
+#: symbols.c:1971
+msgid "section symbols are already global"
+msgstr ""
+
+#: symbols.c:2014
+#, c-format
+msgid "Accessing function `%s' as thread-local object"
+msgstr ""
+
+#: symbols.c:2018
+#, c-format
+msgid "Accessing `%s' as thread-local object"
+msgstr ""
+
+#: write.c:215
+#, c-format
+msgid "field fx_size too small to hold %d"
+msgstr ""
+
+#: write.c:349
+msgid "rva not supported"
+msgstr ""
+
+#: write.c:570
+#, c-format
+msgid "attempt to .org/.space backwards? (%ld)"
+msgstr ""
+
+#: write.c:1002 write.c:1074
+msgid "relocation out of range"
+msgstr ""
+
+#: write.c:1005 write.c:1077
+#, c-format
+msgid "%s:%u: bad return from bfd_install_relocation: %x"
+msgstr ""
+
+#: write.c:1057
+msgid "internal error: fixup not contained within frag"
+msgstr ""
+
+#: write.c:1164 write.c:1188
+#, c-format
+msgid "FATAL: Can't write %s"
+msgstr ""
+
+#: write.c:1220
+msgid "cannot write to output file"
+msgstr ""
+
+#: write.c:1477
+#, c-format
+msgid "%d error%s, %d warning%s, generating bad object file"
+msgstr ""
+
+#: write.c:1484
+#, c-format
+msgid "%d error%s, %d warning%s, no object file generated"
+msgstr ""
+
+#: write.c:1945
+#, c-format
+msgid "local label `%s' is not defined"
+msgstr ""
+
+#: write.c:2244
+#, c-format
+msgid "alignment padding (%lu bytes) not a multiple of %ld"
+msgstr ""
+
+#: write.c:2361
+#, c-format
+msgid ".word %s-%s+%s didn't fit"
+msgstr ""
+
+#: write.c:2446
+msgid "attempt to move .org backwards"
+msgstr ""
+
+#: write.c:2474
+msgid ".space specifies non-absolute value"
+msgstr ""
+
+#: write.c:2481
+msgid ".space or .fill with negative value, ignored"
+msgstr ""
+
+#: write.c:2773
+#, c-format
+msgid "value of %s too large for field of %d bytes at %s"
+msgstr ""
+
+#: write.c:2785
+#, c-format
+msgid "signed .word overflow; switch may be too large; %ld at 0x%lx"
+msgstr ""
diff --git a/x/binutils/gas/read.c b/x/binutils/gas/read.c
new file mode 100644
index 0000000..f97bd25
--- /dev/null
+++ b/x/binutils/gas/read.c
@@ -0,0 +1,5204 @@
+/* read.c - read a source file -
+ Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#if 0
+/* If your chars aren't 8 bits, you will change this a bit.
+ But then, GNU isn't spozed to run on your machine anyway.
+ (RMS is so shortsighted sometimes.) */
+#define MASK_CHAR (0xFF)
+#else
+#define MASK_CHAR ((int)(unsigned char) -1)
+#endif
+
+/* This is the largest known floating point format (for now). It will
+ grow when we do 4361 style flonums. */
+#define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)
+
+/* Routines that read assembler source text to build spaghetti in memory.
+ Another group of these functions is in the expr.c module. */
+
+#include "as.h"
+#include "safe-ctype.h"
+#include "subsegs.h"
+#include "sb.h"
+#include "macro.h"
+#include "obstack.h"
+#include "listing.h"
+#include "ecoff.h"
+#include "dw2gencfi.h"
+
+#ifndef TC_START_LABEL
+#define TC_START_LABEL(x,y) (x == ':')
+#endif
+
+/* Set by the object-format or the target. */
+#ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
+#define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
+ do \
+ { \
+ if ((SIZE) >= 8) \
+ (P2VAR) = 3; \
+ else if ((SIZE) >= 4) \
+ (P2VAR) = 2; \
+ else if ((SIZE) >= 2) \
+ (P2VAR) = 1; \
+ else \
+ (P2VAR) = 0; \
+ } \
+ while (0)
+#endif
+
+char *input_line_pointer; /*->next char of source file to parse. */
+
+#if BITS_PER_CHAR != 8
+/* The following table is indexed by[(char)] and will break if
+ a char does not have exactly 256 states (hopefully 0:255!)! */
+die horribly;
+#endif
+
+#ifndef LEX_AT
+/* The m88k unfortunately uses @ as a label beginner. */
+#define LEX_AT 0
+#endif
+
+#ifndef LEX_BR
+/* The RS/6000 assembler uses {,},[,] as parts of symbol names. */
+#define LEX_BR 0
+#endif
+
+#ifndef LEX_PCT
+/* The Delta 68k assembler permits % inside label names. */
+#define LEX_PCT 0
+#endif
+
+#ifndef LEX_QM
+/* The PowerPC Windows NT assemblers permits ? inside label names. */
+#define LEX_QM 0
+#endif
+
+#ifndef LEX_HASH
+/* The IA-64 assembler uses # as a suffix designating a symbol. We include
+ it in the symbol and strip it out in tc_canonicalize_symbol_name. */
+#define LEX_HASH 0
+#endif
+
+#ifndef LEX_DOLLAR
+/* The a29k assembler does not permits labels to start with $. */
+#define LEX_DOLLAR 3
+#endif
+
+#ifndef LEX_TILDE
+/* The Delta 68k assembler permits ~ at start of label names. */
+#define LEX_TILDE 0
+#endif
+
+/* Used by is_... macros. our ctype[]. */
+char lex_type[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
+ 0, 0, 0, LEX_HASH, LEX_DOLLAR, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, LEX_QM, /* 0123456789:;<=>? */
+ LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, 0, 3, /* PQRSTUVWXYZ[\]^_ */
+ 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, LEX_TILDE, 0, /* pqrstuvwxyz{|}~. */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
+};
+
+/* In: a character.
+ Out: 1 if this character ends a line. */
+char is_end_of_line[256] = {
+#ifdef CR_EOL
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, /* @abcdefghijklmno */
+#else
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* @abcdefghijklmno */
+#endif
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* _!"#$%&'()*+,-./ */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0123456789:;<=>? */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* */
+};
+
+#ifndef TC_CASE_SENSITIVE
+char original_case_string[128];
+#endif
+
+/* Functions private to this file. */
+
+static char *buffer; /* 1st char of each buffer of lines is here. */
+static char *buffer_limit; /*->1 + last char in buffer. */
+
+/* TARGET_BYTES_BIG_ENDIAN is required to be defined to either 0 or 1
+ in the tc-<CPU>.h file. See the "Porting GAS" section of the
+ internals manual. */
+int target_big_endian = TARGET_BYTES_BIG_ENDIAN;
+
+/* Variables for handling include file directory table. */
+
+/* Table of pointers to directories to search for .include's. */
+char **include_dirs;
+
+/* How many are in the table. */
+int include_dir_count;
+
+/* Length of longest in table. */
+int include_dir_maxlen = 1;
+
+#ifndef WORKING_DOT_WORD
+struct broken_word *broken_words;
+int new_broken_words;
+#endif
+
+/* The current offset into the absolute section. We don't try to
+ build frags in the absolute section, since no data can be stored
+ there. We just keep track of the current offset. */
+addressT abs_section_offset;
+
+/* If this line had an MRI style label, it is stored in this variable.
+ This is used by some of the MRI pseudo-ops. */
+symbolS *line_label;
+
+/* This global variable is used to support MRI common sections. We
+ translate such sections into a common symbol. This variable is
+ non-NULL when we are in an MRI common section. */
+symbolS *mri_common_symbol;
+
+/* In MRI mode, after a dc.b pseudo-op with an odd number of bytes, we
+ need to align to an even byte boundary unless the next pseudo-op is
+ dc.b, ds.b, or dcb.b. This variable is set to 1 if an alignment
+ may be needed. */
+static int mri_pending_align;
+
+#ifndef NO_LISTING
+#ifdef OBJ_ELF
+/* This variable is set to be non-zero if the next string we see might
+ be the name of the source file in DWARF debugging information. See
+ the comment in emit_expr for the format we look for. */
+static int dwarf_file_string;
+#endif
+#endif
+
+static void do_align (int, char *, int, int);
+static void s_align (int, int);
+static int hex_float (int, char *);
+static segT get_known_segmented_expression (expressionS * expP);
+static void pobegin (void);
+static int get_line_sb (sb *);
+static void generate_file_debug (void);
+
+void
+read_begin (void)
+{
+ const char *p;
+
+ pobegin ();
+ obj_read_begin_hook ();
+
+ /* Something close -- but not too close -- to a multiple of 1024.
+ The debugging malloc I'm using has 24 bytes of overhead. */
+ obstack_begin (&notes, chunksize);
+ obstack_begin (&cond_obstack, chunksize);
+
+ /* Use machine dependent syntax. */
+ for (p = line_separator_chars; *p; p++)
+ is_end_of_line[(unsigned char) *p] = 1;
+ /* Use more. FIXME-SOMEDAY. */
+
+ if (flag_mri)
+ lex_type['?'] = 3;
+}
+
+/* Set up pseudo-op tables. */
+
+static struct hash_control *po_hash;
+
+static const pseudo_typeS potable[] = {
+ {"abort", s_abort, 0},
+ {"align", s_align_ptwo, 0},
+ {"ascii", stringer, 0},
+ {"asciz", stringer, 1},
+ {"balign", s_align_bytes, 0},
+ {"balignw", s_align_bytes, -2},
+ {"balignl", s_align_bytes, -4},
+/* block */
+ {"byte", cons, 1},
+ {"comm", s_comm, 0},
+ {"common", s_mri_common, 0},
+ {"common.s", s_mri_common, 1},
+ {"data", s_data, 0},
+ {"dc", cons, 2},
+ {"dc.b", cons, 1},
+ {"dc.d", float_cons, 'd'},
+ {"dc.l", cons, 4},
+ {"dc.s", float_cons, 'f'},
+ {"dc.w", cons, 2},
+ {"dc.x", float_cons, 'x'},
+ {"dcb", s_space, 2},
+ {"dcb.b", s_space, 1},
+ {"dcb.d", s_float_space, 'd'},
+ {"dcb.l", s_space, 4},
+ {"dcb.s", s_float_space, 'f'},
+ {"dcb.w", s_space, 2},
+ {"dcb.x", s_float_space, 'x'},
+ {"ds", s_space, 2},
+ {"ds.b", s_space, 1},
+ {"ds.d", s_space, 8},
+ {"ds.l", s_space, 4},
+ {"ds.p", s_space, 12},
+ {"ds.s", s_space, 4},
+ {"ds.w", s_space, 2},
+ {"ds.x", s_space, 12},
+ {"debug", s_ignore, 0},
+#ifdef S_SET_DESC
+ {"desc", s_desc, 0},
+#endif
+/* dim */
+ {"double", float_cons, 'd'},
+/* dsect */
+ {"eject", listing_eject, 0}, /* Formfeed listing. */
+ {"else", s_else, 0},
+ {"elsec", s_else, 0},
+ {"elseif", s_elseif, (int) O_ne},
+ {"end", s_end, 0},
+ {"endc", s_endif, 0},
+ {"endfunc", s_func, 1},
+ {"endif", s_endif, 0},
+ {"endr", s_bad_endr, 0},
+/* endef */
+ {"equ", s_set, 0},
+ {"equiv", s_set, 1},
+ {"err", s_err, 0},
+ {"exitm", s_mexit, 0},
+/* extend */
+ {"extern", s_ignore, 0}, /* We treat all undef as ext. */
+ {"appfile", s_app_file, 1},
+ {"appline", s_app_line, 0},
+ {"fail", s_fail, 0},
+ {"file", s_app_file, 0},
+ {"fill", s_fill, 0},
+ {"float", float_cons, 'f'},
+ {"format", s_ignore, 0},
+ {"func", s_func, 0},
+ {"global", s_globl, 0},
+ {"globl", s_globl, 0},
+ {"hword", cons, 2},
+ {"if", s_if, (int) O_ne},
+ {"ifc", s_ifc, 0},
+ {"ifdef", s_ifdef, 0},
+ {"ifeq", s_if, (int) O_eq},
+ {"ifeqs", s_ifeqs, 0},
+ {"ifge", s_if, (int) O_ge},
+ {"ifgt", s_if, (int) O_gt},
+ {"ifle", s_if, (int) O_le},
+ {"iflt", s_if, (int) O_lt},
+ {"ifnc", s_ifc, 1},
+ {"ifndef", s_ifdef, 1},
+ {"ifne", s_if, (int) O_ne},
+ {"ifnes", s_ifeqs, 1},
+ {"ifnotdef", s_ifdef, 1},
+ {"incbin", s_incbin, 0},
+ {"include", s_include, 0},
+ {"int", cons, 4},
+ {"irp", s_irp, 0},
+ {"irep", s_irp, 0},
+ {"irpc", s_irp, 1},
+ {"irepc", s_irp, 1},
+ {"lcomm", s_lcomm, 0},
+ {"lflags", listing_flags, 0}, /* Listing flags. */
+ {"linkonce", s_linkonce, 0},
+ {"list", listing_list, 1}, /* Turn listing on. */
+ {"llen", listing_psize, 1},
+ {"long", cons, 4},
+ {"lsym", s_lsym, 0},
+ {"macro", s_macro, 0},
+ {"mexit", s_mexit, 0},
+ {"mri", s_mri, 0},
+ {".mri", s_mri, 0}, /* Special case so .mri works in MRI mode. */
+ {"name", s_ignore, 0},
+ {"noformat", s_ignore, 0},
+ {"nolist", listing_list, 0}, /* Turn listing off. */
+ {"nopage", listing_nopage, 0},
+ {"octa", cons, 16},
+ {"offset", s_struct, 0},
+ {"org", s_org, 0},
+ {"p2align", s_align_ptwo, 0},
+ {"p2alignw", s_align_ptwo, -2},
+ {"p2alignl", s_align_ptwo, -4},
+ {"page", listing_eject, 0},
+ {"plen", listing_psize, 0},
+ {"print", s_print, 0},
+ {"psize", listing_psize, 0}, /* Set paper size. */
+ {"purgem", s_purgem, 0},
+ {"quad", cons, 8},
+ {"rep", s_rept, 0},
+ {"rept", s_rept, 0},
+ {"rva", s_rva, 4},
+ {"sbttl", listing_title, 1}, /* Subtitle of listing. */
+/* scl */
+/* sect */
+ {"set", s_set, 0},
+ {"short", cons, 2},
+ {"single", float_cons, 'f'},
+/* size */
+ {"space", s_space, 0},
+ {"skip", s_space, 0},
+ {"sleb128", s_leb128, 1},
+ {"spc", s_ignore, 0},
+ {"stabd", s_stab, 'd'},
+ {"stabn", s_stab, 'n'},
+ {"stabs", s_stab, 's'},
+ {"string", stringer, 1},
+ {"struct", s_struct, 0},
+/* tag */
+ {"text", s_text, 0},
+
+ /* This is for gcc to use. It's only just been added (2/94), so gcc
+ won't be able to use it for a while -- probably a year or more.
+ But once this has been released, check with gcc maintainers
+ before deleting it or even changing the spelling. */
+ {"this_GCC_requires_the_GNU_assembler", s_ignore, 0},
+ /* If we're folding case -- done for some targets, not necessarily
+ all -- the above string in an input file will be converted to
+ this one. Match it either way... */
+ {"this_gcc_requires_the_gnu_assembler", s_ignore, 0},
+
+ {"title", listing_title, 0}, /* Listing title. */
+ {"ttl", listing_title, 0},
+/* type */
+ {"uleb128", s_leb128, 0},
+/* use */
+/* val */
+ {"xcom", s_comm, 0},
+ {"xdef", s_globl, 0},
+ {"xref", s_ignore, 0},
+ {"xstabs", s_xstab, 's'},
+ {"word", cons, 2},
+ {"zero", s_space, 0},
+ {NULL, NULL, 0} /* End sentinel. */
+};
+
+static int pop_override_ok = 0;
+static const char *pop_table_name;
+
+void
+pop_insert (const pseudo_typeS *table)
+{
+ const char *errtxt;
+ const pseudo_typeS *pop;
+ for (pop = table; pop->poc_name; pop++)
+ {
+ errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
+ if (errtxt && (!pop_override_ok || strcmp (errtxt, "exists")))
+ as_fatal (_("error constructing %s pseudo-op table: %s"), pop_table_name,
+ errtxt);
+ }
+}
+
+#ifndef md_pop_insert
+#define md_pop_insert() pop_insert(md_pseudo_table)
+#endif
+
+#ifndef obj_pop_insert
+#define obj_pop_insert() pop_insert(obj_pseudo_table)
+#endif
+
+#ifndef cfi_pop_insert
+#define cfi_pop_insert() pop_insert(cfi_pseudo_table)
+#endif
+
+static void
+pobegin (void)
+{
+ po_hash = hash_new ();
+
+ /* Do the target-specific pseudo ops. */
+ pop_table_name = "md";
+ md_pop_insert ();
+
+ /* Now object specific. Skip any that were in the target table. */
+ pop_table_name = "obj";
+ pop_override_ok = 1;
+ obj_pop_insert ();
+
+ /* Now portable ones. Skip any that we've seen already. */
+ pop_table_name = "standard";
+ pop_insert (potable);
+
+#ifdef TARGET_USE_CFIPOP
+ pop_table_name = "cfi";
+ pop_override_ok = 1;
+ cfi_pop_insert ();
+#endif
+}
+
+#define HANDLE_CONDITIONAL_ASSEMBLY() \
+ if (ignore_input ()) \
+ { \
+ while (!is_end_of_line[(unsigned char) *input_line_pointer++]) \
+ if (input_line_pointer == buffer_limit) \
+ break; \
+ continue; \
+ }
+
+/* This function is used when scrubbing the characters between #APP
+ and #NO_APP. */
+
+static char *scrub_string;
+static char *scrub_string_end;
+
+static int
+scrub_from_string (char *buf, int buflen)
+{
+ int copy;
+
+ copy = scrub_string_end - scrub_string;
+ if (copy > buflen)
+ copy = buflen;
+ memcpy (buf, scrub_string, copy);
+ scrub_string += copy;
+ return copy;
+}
+
+/* We read the file, putting things into a web that represents what we
+ have been reading. */
+void
+read_a_source_file (char *name)
+{
+ register char c;
+ register char *s; /* String of symbol, '\0' appended. */
+ register int temp;
+ pseudo_typeS *pop;
+
+#ifdef WARN_COMMENTS
+ found_comment = 0;
+#endif
+
+ buffer = input_scrub_new_file (name);
+
+ listing_file (name);
+ listing_newline (NULL);
+ register_dependency (name);
+
+ /* Generate debugging information before we've read anything in to denote
+ this file as the "main" source file and not a subordinate one
+ (e.g. N_SO vs N_SOL in stabs). */
+ generate_file_debug ();
+
+ while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
+ { /* We have another line to parse. */
+ know (buffer_limit[-1] == '\n'); /* Must have a sentinel. */
+
+ while (input_line_pointer < buffer_limit)
+ {
+ /* We have more of this buffer to parse. */
+
+ /* We now have input_line_pointer->1st char of next line.
+ If input_line_pointer [-1] == '\n' then we just
+ scanned another line: so bump line counters. */
+ if (is_end_of_line[(unsigned char) input_line_pointer[-1]])
+ {
+#ifdef md_start_line_hook
+ md_start_line_hook ();
+#endif
+ if (input_line_pointer[-1] == '\n')
+ bump_line_counters ();
+
+ line_label = NULL;
+
+ if (LABELS_WITHOUT_COLONS || flag_m68k_mri)
+ {
+ /* Text at the start of a line must be a label, we
+ run down and stick a colon in. */
+ if (is_name_beginner (*input_line_pointer))
+ {
+ char *line_start = input_line_pointer;
+ char c;
+ int mri_line_macro;
+
+ LISTING_NEWLINE ();
+ HANDLE_CONDITIONAL_ASSEMBLY ();
+
+ c = get_symbol_end ();
+
+ /* In MRI mode, the EQU and MACRO pseudoops must
+ be handled specially. */
+ mri_line_macro = 0;
+ if (flag_m68k_mri)
+ {
+ char *rest = input_line_pointer + 1;
+
+ if (*rest == ':')
+ ++rest;
+ if (*rest == ' ' || *rest == '\t')
+ ++rest;
+ if ((strncasecmp (rest, "EQU", 3) == 0
+ || strncasecmp (rest, "SET", 3) == 0)
+ && (rest[3] == ' ' || rest[3] == '\t'))
+ {
+ input_line_pointer = rest + 3;
+ equals (line_start,
+ strncasecmp (rest, "SET", 3) == 0);
+ continue;
+ }
+ if (strncasecmp (rest, "MACRO", 5) == 0
+ && (rest[5] == ' '
+ || rest[5] == '\t'
+ || is_end_of_line[(unsigned char) rest[5]]))
+ mri_line_macro = 1;
+ }
+
+ /* In MRI mode, we need to handle the MACRO
+ pseudo-op specially: we don't want to put the
+ symbol in the symbol table. */
+ if (!mri_line_macro
+#ifdef TC_START_LABEL_WITHOUT_COLON
+ && TC_START_LABEL_WITHOUT_COLON(c,
+ input_line_pointer)
+#endif
+ )
+ line_label = colon (line_start);
+ else
+ line_label = symbol_create (line_start,
+ absolute_section,
+ (valueT) 0,
+ &zero_address_frag);
+
+ *input_line_pointer = c;
+ if (c == ':')
+ input_line_pointer++;
+ }
+ }
+ }
+
+ /* We are at the beginning of a line, or similar place.
+ We expect a well-formed assembler statement.
+ A "symbol-name:" is a statement.
+
+ Depending on what compiler is used, the order of these tests
+ may vary to catch most common case 1st.
+ Each test is independent of all other tests at the (top) level.
+ PLEASE make a compiler that doesn't use this assembler.
+ It is crufty to waste a compiler's time encoding things for this
+ assembler, which then wastes more time decoding it.
+ (And communicating via (linear) files is silly!
+ If you must pass stuff, please pass a tree!) */
+ if ((c = *input_line_pointer++) == '\t'
+ || c == ' '
+ || c == '\f'
+ || c == 0)
+ c = *input_line_pointer++;
+
+ know (c != ' '); /* No further leading whitespace. */
+
+#ifndef NO_LISTING
+ /* If listing is on, and we are expanding a macro, then give
+ the listing code the contents of the expanded line. */
+ if (listing)
+ {
+ if ((listing & LISTING_MACEXP) && macro_nest > 0)
+ {
+ char *copy;
+ int len;
+
+ /* Find the end of the current expanded macro line. */
+ for (s = input_line_pointer - 1; *s; ++s)
+ if (is_end_of_line[(unsigned char) *s])
+ break;
+
+ /* Copy it for safe keeping. Also give an indication of
+ how much macro nesting is involved at this point. */
+ len = s - (input_line_pointer - 1);
+ copy = (char *) xmalloc (len + macro_nest + 2);
+ memset (copy, '>', macro_nest);
+ copy[macro_nest] = ' ';
+ memcpy (copy + macro_nest + 1, input_line_pointer - 1, len);
+ copy[macro_nest + 1 + len] = '\0';
+
+ /* Install the line with the listing facility. */
+ listing_newline (copy);
+ }
+ else
+ listing_newline (NULL);
+ }
+#endif
+ /* C is the 1st significant character.
+ Input_line_pointer points after that character. */
+ if (is_name_beginner (c))
+ {
+ /* Want user-defined label or pseudo/opcode. */
+ HANDLE_CONDITIONAL_ASSEMBLY ();
+
+ s = --input_line_pointer;
+ c = get_symbol_end (); /* name's delimiter. */
+
+ /* C is character after symbol.
+ That character's place in the input line is now '\0'.
+ S points to the beginning of the symbol.
+ [In case of pseudo-op, s->'.'.]
+ Input_line_pointer->'\0' where c was. */
+ if (TC_START_LABEL (c, input_line_pointer))
+ {
+ if (flag_m68k_mri)
+ {
+ char *rest = input_line_pointer + 1;
+
+ /* In MRI mode, \tsym: set 0 is permitted. */
+ if (*rest == ':')
+ ++rest;
+
+ if (*rest == ' ' || *rest == '\t')
+ ++rest;
+
+ if ((strncasecmp (rest, "EQU", 3) == 0
+ || strncasecmp (rest, "SET", 3) == 0)
+ && (rest[3] == ' ' || rest[3] == '\t'))
+ {
+ input_line_pointer = rest + 3;
+ equals (s, 1);
+ continue;
+ }
+ }
+
+ line_label = colon (s); /* User-defined label. */
+ /* Put ':' back for error messages' sake. */
+ *input_line_pointer++ = ':';
+#ifdef tc_check_label
+ tc_check_label (line_label);
+#endif
+ /* Input_line_pointer->after ':'. */
+ SKIP_WHITESPACE ();
+ }
+ else if (c == '='
+ || ((c == ' ' || c == '\t')
+ && input_line_pointer[1] == '='
+#ifdef TC_EQUAL_IN_INSN
+ && !TC_EQUAL_IN_INSN (c, input_line_pointer)
+#endif
+ ))
+ {
+ equals (s, 1);
+ demand_empty_rest_of_line ();
+ }
+ else
+ {
+ /* Expect pseudo-op or machine instruction. */
+ pop = NULL;
+
+#ifndef TC_CASE_SENSITIVE
+ {
+ char *s2 = s;
+
+ strncpy (original_case_string, s2, sizeof (original_case_string));
+ original_case_string[sizeof (original_case_string) - 1] = 0;
+
+ while (*s2)
+ {
+ *s2 = TOLOWER (*s2);
+ s2++;
+ }
+ }
+#endif
+ if (NO_PSEUDO_DOT || flag_m68k_mri)
+ {
+ /* The MRI assembler and the m88k use pseudo-ops
+ without a period. */
+ pop = (pseudo_typeS *) hash_find (po_hash, s);
+ if (pop != NULL && pop->poc_handler == NULL)
+ pop = NULL;
+ }
+
+ if (pop != NULL
+ || (!flag_m68k_mri && *s == '.'))
+ {
+ /* PSEUDO - OP.
+
+ WARNING: c has next char, which may be end-of-line.
+ We lookup the pseudo-op table with s+1 because we
+ already know that the pseudo-op begins with a '.'. */
+
+ if (pop == NULL)
+ pop = (pseudo_typeS *) hash_find (po_hash, s + 1);
+ if (pop && !pop->poc_handler)
+ pop = NULL;
+
+ /* In MRI mode, we may need to insert an
+ automatic alignment directive. What a hack
+ this is. */
+ if (mri_pending_align
+ && (pop == NULL
+ || !((pop->poc_handler == cons
+ && pop->poc_val == 1)
+ || (pop->poc_handler == s_space
+ && pop->poc_val == 1)
+#ifdef tc_conditional_pseudoop
+ || tc_conditional_pseudoop (pop)
+#endif
+ || pop->poc_handler == s_if
+ || pop->poc_handler == s_ifdef
+ || pop->poc_handler == s_ifc
+ || pop->poc_handler == s_ifeqs
+ || pop->poc_handler == s_else
+ || pop->poc_handler == s_endif
+ || pop->poc_handler == s_globl
+ || pop->poc_handler == s_ignore)))
+ {
+ do_align (1, (char *) NULL, 0, 0);
+ mri_pending_align = 0;
+
+ if (line_label != NULL)
+ {
+ symbol_set_frag (line_label, frag_now);
+ S_SET_VALUE (line_label, frag_now_fix ());
+ }
+ }
+
+ /* Print the error msg now, while we still can. */
+ if (pop == NULL)
+ {
+ as_bad (_("unknown pseudo-op: `%s'"), s);
+ *input_line_pointer = c;
+ s_ignore (0);
+ continue;
+ }
+
+ /* Put it back for error messages etc. */
+ *input_line_pointer = c;
+ /* The following skip of whitespace is compulsory.
+ A well shaped space is sometimes all that separates
+ keyword from operands. */
+ if (c == ' ' || c == '\t')
+ input_line_pointer++;
+
+ /* Input_line is restored.
+ Input_line_pointer->1st non-blank char
+ after pseudo-operation. */
+ (*pop->poc_handler) (pop->poc_val);
+
+ /* If that was .end, just get out now. */
+ if (pop->poc_handler == s_end)
+ goto quit;
+ }
+ else
+ {
+ int inquote = 0;
+#ifdef QUOTES_IN_INSN
+ int inescape = 0;
+#endif
+
+ /* WARNING: c has char, which may be end-of-line. */
+ /* Also: input_line_pointer->`\0` where c was. */
+ *input_line_pointer = c;
+ while (!is_end_of_line[(unsigned char) *input_line_pointer]
+ || inquote
+#ifdef TC_EOL_IN_INSN
+ || TC_EOL_IN_INSN (input_line_pointer)
+#endif
+ )
+ {
+ if (flag_m68k_mri && *input_line_pointer == '\'')
+ inquote = !inquote;
+#ifdef QUOTES_IN_INSN
+ if (inescape)
+ inescape = 0;
+ else if (*input_line_pointer == '"')
+ inquote = !inquote;
+ else if (*input_line_pointer == '\\')
+ inescape = 1;
+#endif
+ input_line_pointer++;
+ }
+
+ c = *input_line_pointer;
+ *input_line_pointer = '\0';
+
+ generate_lineno_debug ();
+
+ if (macro_defined)
+ {
+ sb out;
+ const char *err;
+ macro_entry *macro;
+
+ if (check_macro (s, &out, &err, &macro))
+ {
+ if (err != NULL)
+ as_bad ("%s", err);
+ *input_line_pointer++ = c;
+ input_scrub_include_sb (&out,
+ input_line_pointer, 1);
+ sb_kill (&out);
+ buffer_limit =
+ input_scrub_next_buffer (&input_line_pointer);
+#ifdef md_macro_info
+ md_macro_info (macro);
+#endif
+ continue;
+ }
+ }
+
+ if (mri_pending_align)
+ {
+ do_align (1, (char *) NULL, 0, 0);
+ mri_pending_align = 0;
+ if (line_label != NULL)
+ {
+ symbol_set_frag (line_label, frag_now);
+ S_SET_VALUE (line_label, frag_now_fix ());
+ }
+ }
+
+ md_assemble (s); /* Assemble 1 instruction. */
+
+ *input_line_pointer++ = c;
+
+ /* We resume loop AFTER the end-of-line from
+ this instruction. */
+ }
+ }
+ continue;
+ }
+
+ /* Empty statement? */
+ if (is_end_of_line[(unsigned char) c])
+ continue;
+
+ if ((LOCAL_LABELS_DOLLAR || LOCAL_LABELS_FB) && ISDIGIT (c))
+ {
+ /* local label ("4:") */
+ char *backup = input_line_pointer;
+
+ HANDLE_CONDITIONAL_ASSEMBLY ();
+
+ temp = c - '0';
+
+ /* Read the whole number. */
+ while (ISDIGIT (*input_line_pointer))
+ {
+ temp = (temp * 10) + *input_line_pointer - '0';
+ ++input_line_pointer;
+ }
+
+ if (LOCAL_LABELS_DOLLAR
+ && *input_line_pointer == '$'
+ && *(input_line_pointer + 1) == ':')
+ {
+ input_line_pointer += 2;
+
+ if (dollar_label_defined (temp))
+ {
+ as_fatal (_("label \"%d$\" redefined"), temp);
+ }
+
+ define_dollar_label (temp);
+ colon (dollar_label_name (temp, 0));
+ continue;
+ }
+
+ if (LOCAL_LABELS_FB
+ && *input_line_pointer++ == ':')
+ {
+ fb_label_instance_inc (temp);
+ colon (fb_label_name (temp, 0));
+ continue;
+ }
+
+ input_line_pointer = backup;
+ } /* local label ("4:") */
+
+ if (c && strchr (line_comment_chars, c))
+ { /* Its a comment. Better say APP or NO_APP. */
+ sb sbuf;
+ char *ends;
+ char *new_buf;
+ char *new_tmp;
+ unsigned int new_length;
+ char *tmp_buf = 0;
+
+ bump_line_counters ();
+ s = input_line_pointer;
+ if (strncmp (s, "APP\n", 4))
+ continue; /* We ignore it */
+ s += 4;
+
+ sb_new (&sbuf);
+ ends = strstr (s, "#NO_APP\n");
+
+ if (!ends)
+ {
+ unsigned int tmp_len;
+ unsigned int num;
+
+ /* The end of the #APP wasn't in this buffer. We
+ keep reading in buffers until we find the #NO_APP
+ that goes with this #APP There is one. The specs
+ guarantee it... */
+ tmp_len = buffer_limit - s;
+ tmp_buf = xmalloc (tmp_len + 1);
+ memcpy (tmp_buf, s, tmp_len);
+ do
+ {
+ new_tmp = input_scrub_next_buffer (&buffer);
+ if (!new_tmp)
+ break;
+ else
+ buffer_limit = new_tmp;
+ input_line_pointer = buffer;
+ ends = strstr (buffer, "#NO_APP\n");
+ if (ends)
+ num = ends - buffer;
+ else
+ num = buffer_limit - buffer;
+
+ tmp_buf = xrealloc (tmp_buf, tmp_len + num);
+ memcpy (tmp_buf + tmp_len, buffer, num);
+ tmp_len += num;
+ }
+ while (!ends);
+
+ input_line_pointer = ends ? ends + 8 : NULL;
+
+ s = tmp_buf;
+ ends = s + tmp_len;
+
+ }
+ else
+ {
+ input_line_pointer = ends + 8;
+ }
+
+ scrub_string = s;
+ scrub_string_end = ends;
+
+ new_length = ends - s;
+ new_buf = (char *) xmalloc (new_length);
+ new_tmp = new_buf;
+ for (;;)
+ {
+ int space;
+ int size;
+
+ space = (new_buf + new_length) - new_tmp;
+ size = do_scrub_chars (scrub_from_string, new_tmp, space);
+
+ if (size < space)
+ {
+ new_tmp[size] = 0;
+ break;
+ }
+
+ new_buf = xrealloc (new_buf, new_length + 100);
+ new_tmp = new_buf + new_length;
+ new_length += 100;
+ }
+
+ if (tmp_buf)
+ free (tmp_buf);
+
+ /* We've "scrubbed" input to the preferred format. In the
+ process we may have consumed the whole of the remaining
+ file (and included files). We handle this formatted
+ input similar to that of macro expansion, letting
+ actual macro expansion (possibly nested) and other
+ input expansion work. Beware that in messages, line
+ numbers and possibly file names will be incorrect. */
+ sb_add_string (&sbuf, new_buf);
+ input_scrub_include_sb (&sbuf, input_line_pointer, 0);
+ sb_kill (&sbuf);
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+ free (new_buf);
+ continue;
+ }
+
+ HANDLE_CONDITIONAL_ASSEMBLY ();
+
+#ifdef tc_unrecognized_line
+ if (tc_unrecognized_line (c))
+ continue;
+#endif
+ input_line_pointer--;
+ /* Report unknown char as ignored. */
+ demand_empty_rest_of_line ();
+ }
+
+#ifdef md_after_pass_hook
+ md_after_pass_hook ();
+#endif
+ }
+
+ quit:
+
+#ifdef md_cleanup
+ md_cleanup ();
+#endif
+ /* Close the input file. */
+ input_scrub_close ();
+#ifdef WARN_COMMENTS
+ {
+ if (warn_comment && found_comment)
+ as_warn_where (found_comment_file, found_comment,
+ "first comment found here");
+ }
+#endif
+}
+
+/* For most MRI pseudo-ops, the line actually ends at the first
+ nonquoted space. This function looks for that point, stuffs a null
+ in, and sets *STOPCP to the character that used to be there, and
+ returns the location.
+
+ Until I hear otherwise, I am going to assume that this is only true
+ for the m68k MRI assembler. */
+
+char *
+mri_comment_field (char *stopcp)
+{
+ char *s;
+#ifdef TC_M68K
+ int inquote = 0;
+
+ know (flag_m68k_mri);
+
+ for (s = input_line_pointer;
+ ((!is_end_of_line[(unsigned char) *s] && *s != ' ' && *s != '\t')
+ || inquote);
+ s++)
+ {
+ if (*s == '\'')
+ inquote = !inquote;
+ }
+#else
+ for (s = input_line_pointer;
+ !is_end_of_line[(unsigned char) *s];
+ s++)
+ ;
+#endif
+ *stopcp = *s;
+ *s = '\0';
+
+ return s;
+}
+
+/* Skip to the end of an MRI comment field. */
+
+void
+mri_comment_end (char *stop, int stopc)
+{
+ know (flag_mri);
+
+ input_line_pointer = stop;
+ *stop = stopc;
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+}
+
+void
+s_abort (int ignore ATTRIBUTE_UNUSED)
+{
+ as_fatal (_(".abort detected. Abandoning ship."));
+}
+
+/* Guts of .align directive. N is the power of two to which to align.
+ FILL may be NULL, or it may point to the bytes of the fill pattern.
+ LEN is the length of whatever FILL points to, if anything. MAX is
+ the maximum number of characters to skip when doing the alignment,
+ or 0 if there is no maximum. */
+
+static void
+do_align (int n, char *fill, int len, int max)
+{
+ if (now_seg == absolute_section)
+ {
+ if (fill != NULL)
+ while (len-- > 0)
+ if (*fill++ != '\0')
+ {
+ as_warn (_("ignoring fill value in absolute section"));
+ break;
+ }
+ fill = NULL;
+ len = 0;
+ }
+
+#ifdef md_do_align
+ md_do_align (n, fill, len, max, just_record_alignment);
+#endif
+
+ /* Only make a frag if we HAVE to... */
+ if (n != 0 && !need_pass_2)
+ {
+ if (fill == NULL)
+ {
+ if (subseg_text_p (now_seg))
+ frag_align_code (n, max);
+ else
+ frag_align (n, 0, max);
+ }
+ else if (len <= 1)
+ frag_align (n, *fill, max);
+ else
+ frag_align_pattern (n, fill, len, max);
+ }
+
+#ifdef md_do_align
+ just_record_alignment: ATTRIBUTE_UNUSED_LABEL
+#endif
+
+ record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER);
+}
+
+/* Handle the .align pseudo-op. A positive ARG is a default alignment
+ (in bytes). A negative ARG is the negative of the length of the
+ fill pattern. BYTES_P is non-zero if the alignment value should be
+ interpreted as the byte boundary, rather than the power of 2. */
+
+static void
+s_align (int arg, int bytes_p)
+{
+ register unsigned int align;
+ char *stop = NULL;
+ char stopc;
+ offsetT fill = 0;
+ int max;
+ int fill_p;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ if (is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ if (arg < 0)
+ align = 0;
+ else
+ align = arg; /* Default value from pseudo-op table. */
+ }
+ else
+ {
+ align = get_absolute_expression ();
+ SKIP_WHITESPACE ();
+ }
+
+ if (bytes_p)
+ {
+ /* Convert to a power of 2. */
+ if (align != 0)
+ {
+ unsigned int i;
+
+ for (i = 0; (align & 1) == 0; align >>= 1, ++i)
+ ;
+ if (align != 1)
+ as_bad (_("alignment not a power of 2"));
+
+ align = i;
+ }
+ }
+
+ if (align > 15)
+ {
+ align = 15;
+ as_warn (_("alignment too large: %u assumed"), align);
+ }
+
+ if (*input_line_pointer != ',')
+ {
+ fill_p = 0;
+ max = 0;
+ }
+ else
+ {
+ ++input_line_pointer;
+ if (*input_line_pointer == ',')
+ fill_p = 0;
+ else
+ {
+ fill = get_absolute_expression ();
+ SKIP_WHITESPACE ();
+ fill_p = 1;
+ }
+
+ if (*input_line_pointer != ',')
+ max = 0;
+ else
+ {
+ ++input_line_pointer;
+ max = get_absolute_expression ();
+ }
+ }
+
+ if (!fill_p)
+ {
+ if (arg < 0)
+ as_warn (_("expected fill pattern missing"));
+ do_align (align, (char *) NULL, 0, max);
+ }
+ else
+ {
+ int fill_len;
+
+ if (arg >= 0)
+ fill_len = 1;
+ else
+ fill_len = -arg;
+ if (fill_len <= 1)
+ {
+ char fill_char;
+
+ fill_char = fill;
+ do_align (align, &fill_char, fill_len, max);
+ }
+ else
+ {
+ char ab[16];
+
+ if ((size_t) fill_len > sizeof ab)
+ abort ();
+ md_number_to_chars (ab, fill, fill_len);
+ do_align (align, ab, fill_len, max);
+ }
+ }
+
+ demand_empty_rest_of_line ();
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+}
+
+/* Handle the .align pseudo-op on machines where ".align 4" means
+ align to a 4 byte boundary. */
+
+void
+s_align_bytes (int arg)
+{
+ s_align (arg, 1);
+}
+
+/* Handle the .align pseudo-op on machines where ".align 4" means align
+ to a 2**4 boundary. */
+
+void
+s_align_ptwo (int arg)
+{
+ s_align (arg, 0);
+}
+
+symbolS *
+s_comm_internal (int param,
+ symbolS *(*comm_parse_extra) (int, symbolS *, addressT))
+{
+ char *name;
+ char c;
+ char *p;
+ offsetT temp, size;
+ symbolS *symbolP = NULL;
+ char *stop = NULL;
+ char stopc;
+ expressionS exp;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ /* Just after name is now '\0'. */
+ p = input_line_pointer;
+ *p = c;
+
+ if (name == p)
+ {
+ as_bad (_("expected symbol name"));
+ discard_rest_of_line ();
+ goto out;
+ }
+
+ SKIP_WHITESPACE ();
+
+ /* Accept an optional comma after the name. The comma used to be
+ required, but Irix 5 cc does not generate it for .lcomm. */
+ if (*input_line_pointer == ',')
+ input_line_pointer++;
+
+ *p = 0;
+ temp = get_absolute_expr (&exp);
+ size = temp;
+#ifdef BFD_ASSEMBLER
+ size &= ((offsetT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1;
+#endif
+ if (exp.X_op == O_absent)
+ {
+ as_bad (_("missing size expression"));
+ *p = c;
+ ignore_rest_of_line ();
+ goto out;
+ }
+ else if (temp != size || !exp.X_unsigned)
+ {
+ as_warn (_("size (%ld) out of range, ignored"), (long) temp);
+ *p = c;
+ ignore_rest_of_line ();
+ goto out;
+ }
+
+ symbolP = symbol_find_or_make (name);
+ if (S_IS_DEFINED (symbolP) && !S_IS_COMMON (symbolP))
+ {
+ symbolP = NULL;
+ as_bad (_("symbol `%s' is already defined"), name);
+ *p = c;
+ ignore_rest_of_line ();
+ goto out;
+ }
+
+ size = S_GET_VALUE (symbolP);
+ if (size == 0)
+ size = temp;
+ else if (size != temp)
+ as_warn (_("size of \"%s\" is already %ld; not changing to %ld"),
+ name, (long) size, (long) temp);
+
+ *p = c;
+ if (comm_parse_extra != NULL)
+ symbolP = (*comm_parse_extra) (param, symbolP, size);
+ else
+ {
+ S_SET_VALUE (symbolP, (valueT) size);
+ S_SET_EXTERNAL (symbolP);
+#ifdef OBJ_VMS
+ {
+ extern int flag_one;
+ if (size == 0 || !flag_one)
+ S_GET_OTHER (symbolP) = const_flag;
+ }
+#endif
+ }
+
+ know (symbolP == NULL || symbolP->sy_frag == &zero_address_frag);
+ demand_empty_rest_of_line ();
+ out:
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+ return symbolP;
+}
+
+void
+s_comm (int ignore)
+{
+ s_comm_internal (ignore, NULL);
+}
+
+/* The MRI COMMON pseudo-op. We handle this by creating a common
+ symbol with the appropriate name. We make s_space do the right
+ thing by increasing the size. */
+
+void
+s_mri_common (int small ATTRIBUTE_UNUSED)
+{
+ char *name;
+ char c;
+ char *alc = NULL;
+ symbolS *sym;
+ offsetT align;
+ char *stop = NULL;
+ char stopc;
+
+ if (!flag_mri)
+ {
+ s_comm (0);
+ return;
+ }
+
+ stop = mri_comment_field (&stopc);
+
+ SKIP_WHITESPACE ();
+
+ name = input_line_pointer;
+ if (!ISDIGIT (*name))
+ c = get_symbol_end ();
+ else
+ {
+ do
+ {
+ ++input_line_pointer;
+ }
+ while (ISDIGIT (*input_line_pointer));
+
+ c = *input_line_pointer;
+ *input_line_pointer = '\0';
+
+ if (line_label != NULL)
+ {
+ alc = (char *) xmalloc (strlen (S_GET_NAME (line_label))
+ + (input_line_pointer - name)
+ + 1);
+ sprintf (alc, "%s%s", name, S_GET_NAME (line_label));
+ name = alc;
+ }
+ }
+
+ sym = symbol_find_or_make (name);
+ *input_line_pointer = c;
+ if (alc != NULL)
+ free (alc);
+
+ if (*input_line_pointer != ',')
+ align = 0;
+ else
+ {
+ ++input_line_pointer;
+ align = get_absolute_expression ();
+ }
+
+ if (S_IS_DEFINED (sym) && !S_IS_COMMON (sym))
+ {
+ as_bad (_("symbol `%s' is already defined"), S_GET_NAME (sym));
+ ignore_rest_of_line ();
+ mri_comment_end (stop, stopc);
+ return;
+ }
+
+ S_SET_EXTERNAL (sym);
+ mri_common_symbol = sym;
+
+#ifdef S_SET_ALIGN
+ if (align != 0)
+ S_SET_ALIGN (sym, align);
+#endif
+
+ if (line_label != NULL)
+ {
+ expressionS exp;
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = sym;
+ exp.X_add_number = 0;
+ symbol_set_value_expression (line_label, &exp);
+ symbol_set_frag (line_label, &zero_address_frag);
+ S_SET_SEGMENT (line_label, expr_section);
+ }
+
+ /* FIXME: We just ignore the small argument, which distinguishes
+ COMMON and COMMON.S. I don't know what we can do about it. */
+
+ /* Ignore the type and hptype. */
+ if (*input_line_pointer == ',')
+ input_line_pointer += 2;
+ if (*input_line_pointer == ',')
+ input_line_pointer += 2;
+
+ demand_empty_rest_of_line ();
+
+ mri_comment_end (stop, stopc);
+}
+
+void
+s_data (int ignore ATTRIBUTE_UNUSED)
+{
+ segT section;
+ register int temp;
+
+ temp = get_absolute_expression ();
+ if (flag_readonly_data_in_text)
+ {
+ section = text_section;
+ temp += 1000;
+ }
+ else
+ section = data_section;
+
+ subseg_set (section, (subsegT) temp);
+
+#ifdef OBJ_VMS
+ const_flag = 0;
+#endif
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .appfile pseudo-op. This is automatically generated by
+ do_scrub_chars when a preprocessor # line comment is seen with a
+ file name. This default definition may be overridden by the object
+ or CPU specific pseudo-ops. This function is also the default
+ definition for .file; the APPFILE argument is 1 for .appfile, 0 for
+ .file. */
+
+void
+s_app_file_string (char *file)
+{
+#ifdef LISTING
+ if (listing)
+ listing_source_file (file);
+#endif
+ register_dependency (file);
+#ifdef obj_app_file
+ obj_app_file (file);
+#endif
+}
+
+void
+s_app_file (int appfile)
+{
+ register char *s;
+ int length;
+
+ /* Some assemblers tolerate immediately following '"'. */
+ if ((s = demand_copy_string (&length)) != 0)
+ {
+ /* If this is a fake .appfile, a fake newline was inserted into
+ the buffer. Passing -2 to new_logical_line tells it to
+ account for it. */
+ int may_omit
+ = (!new_logical_line (s, appfile ? -2 : -1) && appfile);
+
+ /* In MRI mode, the preprocessor may have inserted an extraneous
+ backquote. */
+ if (flag_m68k_mri
+ && *input_line_pointer == '\''
+ && is_end_of_line[(unsigned char) input_line_pointer[1]])
+ ++input_line_pointer;
+
+ demand_empty_rest_of_line ();
+ if (!may_omit)
+ s_app_file_string (s);
+ }
+}
+
+/* Handle the .appline pseudo-op. This is automatically generated by
+ do_scrub_chars when a preprocessor # line comment is seen. This
+ default definition may be overridden by the object or CPU specific
+ pseudo-ops. */
+
+void
+s_app_line (int ignore ATTRIBUTE_UNUSED)
+{
+ int l;
+
+ /* The given number is that of the next line. */
+ l = get_absolute_expression () - 1;
+ if (l < 0)
+ /* Some of the back ends can't deal with non-positive line numbers.
+ Besides, it's silly. */
+ as_warn (_("line numbers must be positive; line number %d rejected"),
+ l + 1);
+ else
+ {
+ new_logical_line ((char *) NULL, l);
+#ifdef LISTING
+ if (listing)
+ listing_source_line (l);
+#endif
+ }
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .end pseudo-op. Actually, the real work is done in
+ read_a_source_file. */
+
+void
+s_end (int ignore ATTRIBUTE_UNUSED)
+{
+ if (flag_mri)
+ {
+ /* The MRI assembler permits the start symbol to follow .end,
+ but we don't support that. */
+ SKIP_WHITESPACE ();
+ if (!is_end_of_line[(unsigned char) *input_line_pointer]
+ && *input_line_pointer != '*'
+ && *input_line_pointer != '!')
+ as_warn (_("start address not supported"));
+ }
+}
+
+/* Handle the .err pseudo-op. */
+
+void
+s_err (int ignore ATTRIBUTE_UNUSED)
+{
+ as_bad (_(".err encountered"));
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the MRI fail pseudo-op. */
+
+void
+s_fail (int ignore ATTRIBUTE_UNUSED)
+{
+ offsetT temp;
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ temp = get_absolute_expression ();
+ if (temp >= 500)
+ as_warn (_(".fail %ld encountered"), (long) temp);
+ else
+ as_bad (_(".fail %ld encountered"), (long) temp);
+
+ demand_empty_rest_of_line ();
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+}
+
+void
+s_fill (int ignore ATTRIBUTE_UNUSED)
+{
+ expressionS rep_exp;
+ long size = 1;
+ register long fill = 0;
+ char *p;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ get_known_segmented_expression (&rep_exp);
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ size = get_absolute_expression ();
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ fill = get_absolute_expression ();
+ }
+ }
+
+ /* This is to be compatible with BSD 4.2 AS, not for any rational reason. */
+#define BSD_FILL_SIZE_CROCK_8 (8)
+ if (size > BSD_FILL_SIZE_CROCK_8)
+ {
+ as_warn (_(".fill size clamped to %d"), BSD_FILL_SIZE_CROCK_8);
+ size = BSD_FILL_SIZE_CROCK_8;
+ }
+ if (size < 0)
+ {
+ as_warn (_("size negative; .fill ignored"));
+ size = 0;
+ }
+ else if (rep_exp.X_op == O_constant && rep_exp.X_add_number <= 0)
+ {
+ if (rep_exp.X_add_number < 0)
+ as_warn (_("repeat < 0; .fill ignored"));
+ size = 0;
+ }
+
+ if (size && !need_pass_2)
+ {
+ if (rep_exp.X_op == O_constant)
+ {
+ p = frag_var (rs_fill, (int) size, (int) size,
+ (relax_substateT) 0, (symbolS *) 0,
+ (offsetT) rep_exp.X_add_number,
+ (char *) 0);
+ }
+ else
+ {
+ /* We don't have a constant repeat count, so we can't use
+ rs_fill. We can get the same results out of rs_space,
+ but its argument is in bytes, so we must multiply the
+ repeat count by size. */
+
+ symbolS *rep_sym;
+ rep_sym = make_expr_symbol (&rep_exp);
+ if (size != 1)
+ {
+ expressionS size_exp;
+ size_exp.X_op = O_constant;
+ size_exp.X_add_number = size;
+
+ rep_exp.X_op = O_multiply;
+ rep_exp.X_add_symbol = rep_sym;
+ rep_exp.X_op_symbol = make_expr_symbol (&size_exp);
+ rep_exp.X_add_number = 0;
+ rep_sym = make_expr_symbol (&rep_exp);
+ }
+
+ p = frag_var (rs_space, (int) size, (int) size,
+ (relax_substateT) 0, rep_sym, (offsetT) 0, (char *) 0);
+ }
+
+ memset (p, 0, (unsigned int) size);
+
+ /* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX
+ flavoured AS. The following bizarre behaviour is to be
+ compatible with above. I guess they tried to take up to 8
+ bytes from a 4-byte expression and they forgot to sign
+ extend. */
+#define BSD_FILL_SIZE_CROCK_4 (4)
+ md_number_to_chars (p, (valueT) fill,
+ (size > BSD_FILL_SIZE_CROCK_4
+ ? BSD_FILL_SIZE_CROCK_4
+ : (int) size));
+ /* Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
+ but emits no error message because it seems a legal thing to do.
+ It is a degenerate case of .fill but could be emitted by a
+ compiler. */
+ }
+ demand_empty_rest_of_line ();
+}
+
+void
+s_globl (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ do
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ S_SET_EXTERNAL (symbolP);
+
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ c = *input_line_pointer;
+ if (c == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (is_end_of_line[(unsigned char) *input_line_pointer])
+ c = '\n';
+ }
+ }
+ while (c == ',');
+
+ demand_empty_rest_of_line ();
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+}
+
+/* Handle the MRI IRP and IRPC pseudo-ops. */
+
+void
+s_irp (int irpc)
+{
+ char *file;
+ unsigned int line;
+ sb s;
+ const char *err;
+ sb out;
+
+ as_where (&file, &line);
+
+ sb_new (&s);
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ sb_add_char (&s, *input_line_pointer++);
+
+ sb_new (&out);
+
+ err = expand_irp (irpc, 0, &s, &out, get_line_sb);
+ if (err != NULL)
+ as_bad_where (file, line, "%s", err);
+
+ sb_kill (&s);
+
+ input_scrub_include_sb (&out, input_line_pointer, 1);
+ sb_kill (&out);
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+}
+
+/* Handle the .linkonce pseudo-op. This tells the assembler to mark
+ the section to only be linked once. However, this is not supported
+ by most object file formats. This takes an optional argument,
+ which is what to do about duplicates. */
+
+void
+s_linkonce (int ignore ATTRIBUTE_UNUSED)
+{
+ enum linkonce_type type;
+
+ SKIP_WHITESPACE ();
+
+ type = LINKONCE_DISCARD;
+
+ if (!is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ char *s;
+ char c;
+
+ s = input_line_pointer;
+ c = get_symbol_end ();
+ if (strcasecmp (s, "discard") == 0)
+ type = LINKONCE_DISCARD;
+ else if (strcasecmp (s, "one_only") == 0)
+ type = LINKONCE_ONE_ONLY;
+ else if (strcasecmp (s, "same_size") == 0)
+ type = LINKONCE_SAME_SIZE;
+ else if (strcasecmp (s, "same_contents") == 0)
+ type = LINKONCE_SAME_CONTENTS;
+ else
+ as_warn (_("unrecognized .linkonce type `%s'"), s);
+
+ *input_line_pointer = c;
+ }
+
+#ifdef obj_handle_link_once
+ obj_handle_link_once (type);
+#else /* ! defined (obj_handle_link_once) */
+#ifdef BFD_ASSEMBLER
+ {
+ flagword flags;
+
+ if ((bfd_applicable_section_flags (stdoutput) & SEC_LINK_ONCE) == 0)
+ as_warn (_(".linkonce is not supported for this object file format"));
+
+ flags = bfd_get_section_flags (stdoutput, now_seg);
+ flags |= SEC_LINK_ONCE;
+ switch (type)
+ {
+ default:
+ abort ();
+ case LINKONCE_DISCARD:
+ flags |= SEC_LINK_DUPLICATES_DISCARD;
+ break;
+ case LINKONCE_ONE_ONLY:
+ flags |= SEC_LINK_DUPLICATES_ONE_ONLY;
+ break;
+ case LINKONCE_SAME_SIZE:
+ flags |= SEC_LINK_DUPLICATES_SAME_SIZE;
+ break;
+ case LINKONCE_SAME_CONTENTS:
+ flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS;
+ break;
+ }
+ if (!bfd_set_section_flags (stdoutput, now_seg, flags))
+ as_bad (_("bfd_set_section_flags: %s"),
+ bfd_errmsg (bfd_get_error ()));
+ }
+#else /* ! defined (BFD_ASSEMBLER) */
+ as_warn (_(".linkonce is not supported for this object file format"));
+#endif /* ! defined (BFD_ASSEMBLER) */
+#endif /* ! defined (obj_handle_link_once) */
+
+ demand_empty_rest_of_line ();
+}
+
+void
+bss_alloc (symbolS *symbolP, addressT size, int align)
+{
+ char *pfrag;
+ segT current_seg = now_seg;
+ subsegT current_subseg = now_subseg;
+ segT bss_seg = bss_section;
+
+#if defined (TC_MIPS) || defined (TC_ALPHA)
+ if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour
+ || OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ {
+ /* For MIPS and Alpha ECOFF or ELF, small objects are put in .sbss. */
+ if (size <= bfd_get_gp_size (stdoutput))
+ {
+ bss_seg = subseg_new (".sbss", 1);
+ seg_info (bss_seg)->bss = 1;
+#ifdef BFD_ASSEMBLER
+ if (!bfd_set_section_flags (stdoutput, bss_seg, SEC_ALLOC))
+ as_warn (_("error setting flags for \".sbss\": %s"),
+ bfd_errmsg (bfd_get_error ()));
+#endif
+ }
+ }
+#endif
+ subseg_set (bss_seg, 1);
+
+ if (align)
+ {
+ record_alignment (bss_seg, align);
+ frag_align (align, 0, 0);
+ }
+
+ /* Detach from old frag. */
+ if (S_GET_SEGMENT (symbolP) == bss_seg)
+ symbol_get_frag (symbolP)->fr_symbol = NULL;
+
+ symbol_set_frag (symbolP, frag_now);
+ pfrag = frag_var (rs_org, 1, 1, 0, symbolP, size, NULL);
+ *pfrag = 0;
+
+#ifdef S_SET_SIZE
+ S_SET_SIZE (symbolP, size);
+#endif
+ S_SET_SEGMENT (symbolP, bss_seg);
+
+#ifdef OBJ_COFF
+ /* The symbol may already have been created with a preceding
+ ".globl" directive -- be careful not to step on storage class
+ in that case. Otherwise, set it to static. */
+ if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
+ S_SET_STORAGE_CLASS (symbolP, C_STAT);
+#endif /* OBJ_COFF */
+
+ subseg_set (current_seg, current_subseg);
+}
+
+offsetT
+parse_align (int align_bytes)
+{
+ expressionS exp;
+ addressT align;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ no_align:
+ as_bad (_("expected alignment after size"));
+ ignore_rest_of_line ();
+ return -1;
+ }
+
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+
+ align = get_absolute_expr (&exp);
+ if (exp.X_op == O_absent)
+ goto no_align;
+
+ if (!exp.X_unsigned)
+ {
+ as_warn (_("alignment negative; 0 assumed"));
+ align = 0;
+ }
+
+ if (align_bytes && align != 0)
+ {
+ /* convert to a power of 2 alignment */
+ unsigned int alignp2 = 0;
+ while ((align & 1) == 0)
+ align >>= 1, ++alignp2;
+ if (align != 1)
+ {
+ as_bad (_("alignment not a power of 2"));
+ ignore_rest_of_line ();
+ return -1;
+ }
+ align = alignp2;
+ }
+ return align;
+}
+
+/* Called from s_comm_internal after symbol name and size have been
+ parsed. NEEDS_ALIGN is 0 if it was an ".lcomm" (2 args only),
+ 1 if this was a ".bss" directive which has a 3rd argument
+ (alignment as a power of 2), or 2 if this was a ".bss" directive
+ with alignment in bytes. */
+
+symbolS *
+s_lcomm_internal (int needs_align, symbolS *symbolP, addressT size)
+{
+ addressT align = 0;
+
+ if (needs_align)
+ {
+ align = parse_align (needs_align - 1);
+ if (align == (addressT) -1)
+ return NULL;
+ }
+ else
+ /* Assume some objects may require alignment on some systems. */
+ TC_IMPLICIT_LCOMM_ALIGNMENT (size, align);
+
+ bss_alloc (symbolP, size, align);
+ return symbolP;
+}
+
+void
+s_lcomm (int needs_align)
+{
+ s_comm_internal (needs_align, s_lcomm_internal);
+}
+
+void
+s_lcomm_bytes (int needs_align)
+{
+ s_comm_internal (needs_align * 2, s_lcomm_internal);
+}
+
+void
+s_lsym (int ignore ATTRIBUTE_UNUSED)
+{
+ register char *name;
+ register char c;
+ register char *p;
+ expressionS exp;
+ register symbolS *symbolP;
+
+ /* We permit ANY defined expression: BSD4.2 demands constants. */
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ p = input_line_pointer;
+ *p = c;
+
+ if (name == p)
+ {
+ as_bad (_("expected symbol name"));
+ discard_rest_of_line ();
+ return;
+ }
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != ',')
+ {
+ *p = 0;
+ as_bad (_("expected comma after \"%s\""), name);
+ *p = c;
+ ignore_rest_of_line ();
+ return;
+ }
+
+ input_line_pointer++;
+ expression (&exp);
+
+ if (exp.X_op != O_constant
+ && exp.X_op != O_register)
+ {
+ as_bad (_("bad expression"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+
+ /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0 &&
+ symbolP->sy_desc == 0) out of this test because coff doesn't have
+ those fields, and I can't see when they'd ever be tripped. I
+ don't think I understand why they were here so I may have
+ introduced a bug. As recently as 1.37 didn't have this test
+ anyway. xoxorich. */
+
+ if (S_GET_SEGMENT (symbolP) == undefined_section
+ && S_GET_VALUE (symbolP) == 0)
+ {
+ /* The name might be an undefined .global symbol; be sure to
+ keep the "external" bit. */
+ S_SET_SEGMENT (symbolP,
+ (exp.X_op == O_constant
+ ? absolute_section
+ : reg_section));
+ S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
+ }
+ else
+ {
+ as_bad (_("symbol `%s' is already defined"), name);
+ }
+
+ *p = c;
+ demand_empty_rest_of_line ();
+}
+
+/* Read a line into an sb. Returns the character that ended the line
+ or zero if there are no more lines. */
+
+static int
+get_line_sb (sb *line)
+{
+ char quote1, quote2, inquote;
+ unsigned char c;
+
+ if (input_line_pointer[-1] == '\n')
+ bump_line_counters ();
+
+ if (input_line_pointer >= buffer_limit)
+ {
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+ if (buffer_limit == 0)
+ return 0;
+ }
+
+ /* If app.c sets any other characters to LEX_IS_STRINGQUOTE, this
+ code needs to be changed. */
+ if (!flag_m68k_mri)
+ quote1 = '"';
+ else
+ quote1 = '\0';
+
+ quote2 = '\0';
+ if (flag_m68k_mri)
+ quote2 = '\'';
+#ifdef LEX_IS_STRINGQUOTE
+ quote2 = '\'';
+#endif
+
+ inquote = '\0';
+
+ while ((c = * input_line_pointer ++) != 0
+ && (!is_end_of_line[c]
+ || (inquote != '\0' && c != '\n')))
+ {
+ if (inquote == c)
+ inquote = '\0';
+ else if (inquote == '\0')
+ {
+ if (c == quote1)
+ inquote = quote1;
+ else if (c == quote2)
+ inquote = quote2;
+ }
+
+ sb_add_char (line, c);
+ }
+
+ /* Don't skip multiple end-of-line characters, because that breaks support
+ for the IA-64 stop bit (;;) which looks like two consecutive end-of-line
+ characters but isn't. Instead just skip one end of line character and
+ return the character skipped so that the caller can re-insert it if
+ necessary. */
+ return c;
+}
+
+/* Define a macro. This is an interface to macro.c. */
+
+void
+s_macro (int ignore ATTRIBUTE_UNUSED)
+{
+ char *file;
+ unsigned int line;
+ sb s;
+ sb label;
+ const char *err;
+ const char *name;
+
+ as_where (&file, &line);
+
+ sb_new (&s);
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ sb_add_char (&s, *input_line_pointer++);
+
+ sb_new (&label);
+ if (line_label != NULL)
+ sb_add_string (&label, S_GET_NAME (line_label));
+
+ err = define_macro (0, &s, &label, get_line_sb, &name);
+ if (err != NULL)
+ as_bad_where (file, line, "%s", err);
+ else
+ {
+ if (line_label != NULL)
+ {
+ S_SET_SEGMENT (line_label, undefined_section);
+ S_SET_VALUE (line_label, 0);
+ symbol_set_frag (line_label, &zero_address_frag);
+ }
+
+ if (((NO_PSEUDO_DOT || flag_m68k_mri)
+ && hash_find (po_hash, name) != NULL)
+ || (!flag_m68k_mri
+ && *name == '.'
+ && hash_find (po_hash, name + 1) != NULL))
+ as_warn (_("attempt to redefine pseudo-op `%s' ignored"),
+ name);
+ }
+
+ sb_kill (&s);
+}
+
+/* Handle the .mexit pseudo-op, which immediately exits a macro
+ expansion. */
+
+void
+s_mexit (int ignore ATTRIBUTE_UNUSED)
+{
+ cond_exit_macro (macro_nest);
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+}
+
+/* Switch in and out of MRI mode. */
+
+void
+s_mri (int ignore ATTRIBUTE_UNUSED)
+{
+ int on, old_flag;
+
+ on = get_absolute_expression ();
+ old_flag = flag_mri;
+ if (on != 0)
+ {
+ flag_mri = 1;
+#ifdef TC_M68K
+ flag_m68k_mri = 1;
+#endif
+ macro_mri_mode (1);
+ }
+ else
+ {
+ flag_mri = 0;
+#ifdef TC_M68K
+ flag_m68k_mri = 0;
+#endif
+ macro_mri_mode (0);
+ }
+
+ /* Operator precedence changes in m68k MRI mode, so we need to
+ update the operator rankings. */
+ expr_set_precedence ();
+
+#ifdef MRI_MODE_CHANGE
+ if (on != old_flag)
+ MRI_MODE_CHANGE (on);
+#endif
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle changing the location counter. */
+
+static void
+do_org (segT segment, expressionS *exp, int fill)
+{
+ if (segment != now_seg && segment != absolute_section)
+ as_bad (_("invalid segment \"%s\""), segment_name (segment));
+
+ if (now_seg == absolute_section)
+ {
+ if (fill != 0)
+ as_warn (_("ignoring fill value in absolute section"));
+ if (exp->X_op != O_constant)
+ {
+ as_bad (_("only constant offsets supported in absolute section"));
+ exp->X_add_number = 0;
+ }
+ abs_section_offset = exp->X_add_number;
+ }
+ else
+ {
+ char *p;
+ symbolS *sym = exp->X_add_symbol;
+ offsetT off = exp->X_add_number * OCTETS_PER_BYTE;
+
+ if (exp->X_op != O_constant && exp->X_op != O_symbol)
+ {
+ /* Handle complex expressions. */
+ sym = make_expr_symbol (exp);
+ off = 0;
+ }
+
+ p = frag_var (rs_org, 1, 1, (relax_substateT) 0, sym, off, (char *) 0);
+ *p = fill;
+ }
+}
+
+void
+s_org (int ignore ATTRIBUTE_UNUSED)
+{
+ register segT segment;
+ expressionS exp;
+ register long temp_fill;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ /* The m68k MRI assembler has a different meaning for .org. It
+ means to create an absolute section at a given address. We can't
+ support that--use a linker script instead. */
+ if (flag_m68k_mri)
+ {
+ as_bad (_("MRI style ORG pseudo-op not supported"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ /* Don't believe the documentation of BSD 4.2 AS. There is no such
+ thing as a sub-segment-relative origin. Any absolute origin is
+ given a warning, then assumed to be segment-relative. Any
+ segmented origin expression ("foo+42") had better be in the right
+ segment or the .org is ignored.
+
+ BSD 4.2 AS warns if you try to .org backwards. We cannot because
+ we never know sub-segment sizes when we are reading code. BSD
+ will crash trying to emit negative numbers of filler bytes in
+ certain .orgs. We don't crash, but see as-write for that code.
+
+ Don't make frag if need_pass_2==1. */
+ segment = get_known_segmented_expression (&exp);
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ temp_fill = get_absolute_expression ();
+ }
+ else
+ temp_fill = 0;
+
+ if (!need_pass_2)
+ do_org (segment, &exp, temp_fill);
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle parsing for the MRI SECT/SECTION pseudo-op. This should be
+ called by the obj-format routine which handles section changing
+ when in MRI mode. It will create a new section, and return it. It
+ will set *TYPE to the section type: one of 'C' (code), 'D' (data),
+ 'M' (mixed), or 'R' (romable). If BFD_ASSEMBLER is defined, the
+ flags will be set in the section. */
+
+void
+s_mri_sect (char *type ATTRIBUTE_UNUSED)
+{
+#ifdef TC_M68K
+
+ char *name;
+ char c;
+ segT seg;
+
+ SKIP_WHITESPACE ();
+
+ name = input_line_pointer;
+ if (!ISDIGIT (*name))
+ c = get_symbol_end ();
+ else
+ {
+ do
+ {
+ ++input_line_pointer;
+ }
+ while (ISDIGIT (*input_line_pointer));
+
+ c = *input_line_pointer;
+ *input_line_pointer = '\0';
+ }
+
+ name = xstrdup (name);
+
+ *input_line_pointer = c;
+
+ seg = subseg_new (name, 0);
+
+ if (*input_line_pointer == ',')
+ {
+ int align;
+
+ ++input_line_pointer;
+ align = get_absolute_expression ();
+ record_alignment (seg, align);
+ }
+
+ *type = 'C';
+ if (*input_line_pointer == ',')
+ {
+ c = *++input_line_pointer;
+ c = TOUPPER (c);
+ if (c == 'C' || c == 'D' || c == 'M' || c == 'R')
+ *type = c;
+ else
+ as_bad (_("unrecognized section type"));
+ ++input_line_pointer;
+
+#ifdef BFD_ASSEMBLER
+ {
+ flagword flags;
+
+ flags = SEC_NO_FLAGS;
+ if (*type == 'C')
+ flags = SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE;
+ else if (*type == 'D' || *type == 'M')
+ flags = SEC_ALLOC | SEC_LOAD | SEC_DATA;
+ else if (*type == 'R')
+ flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_READONLY | SEC_ROM;
+ if (flags != SEC_NO_FLAGS)
+ {
+ if (!bfd_set_section_flags (stdoutput, seg, flags))
+ as_warn (_("error setting flags for \"%s\": %s"),
+ bfd_section_name (stdoutput, seg),
+ bfd_errmsg (bfd_get_error ()));
+ }
+ }
+#endif
+ }
+
+ /* Ignore the HP type. */
+ if (*input_line_pointer == ',')
+ input_line_pointer += 2;
+
+ demand_empty_rest_of_line ();
+
+#else /* ! TC_M68K */
+#ifdef TC_I960
+
+ char *name;
+ char c;
+ segT seg;
+
+ SKIP_WHITESPACE ();
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ name = xstrdup (name);
+
+ *input_line_pointer = c;
+
+ seg = subseg_new (name, 0);
+
+ if (*input_line_pointer != ',')
+ *type = 'C';
+ else
+ {
+ char *sectype;
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ sectype = input_line_pointer;
+ c = get_symbol_end ();
+ if (*sectype == '\0')
+ *type = 'C';
+ else if (strcasecmp (sectype, "text") == 0)
+ *type = 'C';
+ else if (strcasecmp (sectype, "data") == 0)
+ *type = 'D';
+ else if (strcasecmp (sectype, "romdata") == 0)
+ *type = 'R';
+ else
+ as_warn (_("unrecognized section type `%s'"), sectype);
+ *input_line_pointer = c;
+ }
+
+ if (*input_line_pointer == ',')
+ {
+ char *seccmd;
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ seccmd = input_line_pointer;
+ c = get_symbol_end ();
+ if (strcasecmp (seccmd, "absolute") == 0)
+ {
+ as_bad (_("absolute sections are not supported"));
+ *input_line_pointer = c;
+ ignore_rest_of_line ();
+ return;
+ }
+ else if (strcasecmp (seccmd, "align") == 0)
+ {
+ int align;
+
+ *input_line_pointer = c;
+ align = get_absolute_expression ();
+ record_alignment (seg, align);
+ }
+ else
+ {
+ as_warn (_("unrecognized section command `%s'"), seccmd);
+ *input_line_pointer = c;
+ }
+ }
+
+ demand_empty_rest_of_line ();
+
+#else /* ! TC_I960 */
+ /* The MRI assembler seems to use different forms of .sect for
+ different targets. */
+ as_bad ("MRI mode not supported for this target");
+ ignore_rest_of_line ();
+#endif /* ! TC_I960 */
+#endif /* ! TC_M68K */
+}
+
+/* Handle the .print pseudo-op. */
+
+void
+s_print (int ignore ATTRIBUTE_UNUSED)
+{
+ char *s;
+ int len;
+
+ s = demand_copy_C_string (&len);
+ if (s != NULL)
+ printf ("%s\n", s);
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .purgem pseudo-op. */
+
+void
+s_purgem (int ignore ATTRIBUTE_UNUSED)
+{
+ if (is_it_end_of_statement ())
+ {
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ do
+ {
+ char *name;
+ char c;
+
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ delete_macro (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ }
+ while (*input_line_pointer++ == ',');
+
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .rept pseudo-op. */
+
+void
+s_bad_endr (int ignore ATTRIBUTE_UNUSED)
+{
+ as_warn (_(".endr encountered without preceeding .rept, .irc, or .irp"));
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .rept pseudo-op. */
+
+void
+s_rept (int ignore ATTRIBUTE_UNUSED)
+{
+ int count;
+
+ count = get_absolute_expression ();
+
+ do_repeat (count, "REPT", "ENDR");
+}
+
+/* This function provides a generic repeat block implementation. It allows
+ different directives to be used as the start/end keys. */
+
+void
+do_repeat (int count, const char *start, const char *end)
+{
+ sb one;
+ sb many;
+
+ sb_new (&one);
+ if (!buffer_and_nest (start, end, &one, get_line_sb))
+ {
+ as_bad (_("%s without %s"), start, end);
+ return;
+ }
+
+ sb_new (&many);
+ while (count-- > 0)
+ sb_add_sb (&many, &one);
+
+ sb_kill (&one);
+
+ input_scrub_include_sb (&many, input_line_pointer, 1);
+ sb_kill (&many);
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+}
+
+/* Skip to end of current repeat loop; EXTRA indicates how many additional
+ input buffers to skip. Assumes that conditionals preceding the loop end
+ are properly nested.
+
+ This function makes it easier to implement a premature "break" out of the
+ loop. The EXTRA arg accounts for other buffers we might have inserted,
+ such as line substitutions. */
+
+void
+end_repeat (int extra)
+{
+ cond_exit_macro (macro_nest);
+ while (extra-- >= 0)
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+}
+
+/* Handle the .equ, .equiv and .set directives. If EQUIV is 1, then
+ this is .equiv, and it is an error if the symbol is already
+ defined. */
+
+void
+s_set (int equiv)
+{
+ register char *name;
+ register char delim;
+ register char *end_name;
+ register symbolS *symbolP;
+
+ /* Especial apologies for the random logic:
+ this just grew, and could be parsed much more simply!
+ Dean in haste. */
+ name = input_line_pointer;
+ delim = get_symbol_end ();
+ end_name = input_line_pointer;
+ *end_name = delim;
+
+ if (name == end_name)
+ {
+ as_bad (_("expected symbol name"));
+ discard_rest_of_line ();
+ return;
+ }
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != ',')
+ {
+ *end_name = 0;
+ as_bad (_("expected comma after \"%s\""), name);
+ *end_name = delim;
+ ignore_rest_of_line ();
+ return;
+ }
+
+ input_line_pointer++;
+ *end_name = 0;
+
+ if (name[0] == '.' && name[1] == '\0')
+ {
+ /* Turn '. = mumble' into a .org mumble. */
+ register segT segment;
+ expressionS exp;
+
+ segment = get_known_segmented_expression (&exp);
+
+ if (!need_pass_2)
+ do_org (segment, &exp, 0);
+
+ *end_name = delim;
+ return;
+ }
+
+ if ((symbolP = symbol_find (name)) == NULL
+ && (symbolP = md_undefined_symbol (name)) == NULL)
+ {
+#ifndef NO_LISTING
+ /* When doing symbol listings, play games with dummy fragments living
+ outside the normal fragment chain to record the file and line info
+ for this symbol. */
+ if (listing & LISTING_SYMBOLS)
+ {
+ extern struct list_info_struct *listing_tail;
+ fragS *dummy_frag = (fragS *) xmalloc (sizeof (fragS));
+ memset (dummy_frag, 0, sizeof (fragS));
+ dummy_frag->fr_type = rs_fill;
+ dummy_frag->line = listing_tail;
+ symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
+ dummy_frag->fr_symbol = symbolP;
+ }
+ else
+#endif
+ symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
+
+#ifdef OBJ_COFF
+ /* "set" symbols are local unless otherwise specified. */
+ SF_SET_LOCAL (symbolP);
+#endif /* OBJ_COFF */
+ }
+
+ symbol_table_insert (symbolP);
+
+ *end_name = delim;
+
+ if (equiv
+ && S_IS_DEFINED (symbolP)
+ && S_GET_SEGMENT (symbolP) != reg_section)
+ as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP));
+
+ pseudo_set (symbolP);
+ demand_empty_rest_of_line ();
+}
+
+void
+s_space (int mult)
+{
+ expressionS exp;
+ expressionS val;
+ char *p = 0;
+ char *stop = NULL;
+ char stopc;
+ int bytes;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ /* In m68k MRI mode, we need to align to a word boundary, unless
+ this is ds.b. */
+ if (flag_m68k_mri && mult > 1)
+ {
+ if (now_seg == absolute_section)
+ {
+ abs_section_offset += abs_section_offset & 1;
+ if (line_label != NULL)
+ S_SET_VALUE (line_label, abs_section_offset);
+ }
+ else if (mri_common_symbol != NULL)
+ {
+ valueT val;
+
+ val = S_GET_VALUE (mri_common_symbol);
+ if ((val & 1) != 0)
+ {
+ S_SET_VALUE (mri_common_symbol, val + 1);
+ if (line_label != NULL)
+ {
+ expressionS *symexp;
+
+ symexp = symbol_get_value_expression (line_label);
+ know (symexp->X_op == O_symbol);
+ know (symexp->X_add_symbol == mri_common_symbol);
+ symexp->X_add_number += 1;
+ }
+ }
+ }
+ else
+ {
+ do_align (1, (char *) NULL, 0, 0);
+ if (line_label != NULL)
+ {
+ symbol_set_frag (line_label, frag_now);
+ S_SET_VALUE (line_label, frag_now_fix ());
+ }
+ }
+ }
+
+ bytes = mult;
+
+ expression (&exp);
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ expression (&val);
+ }
+ else
+ {
+ val.X_op = O_constant;
+ val.X_add_number = 0;
+ }
+
+ if (val.X_op != O_constant
+ || val.X_add_number < - 0x80
+ || val.X_add_number > 0xff
+ || (mult != 0 && mult != 1 && val.X_add_number != 0))
+ {
+ if (exp.X_op != O_constant)
+ as_bad (_("unsupported variable size or fill value"));
+ else
+ {
+ offsetT i;
+
+ if (mult == 0)
+ mult = 1;
+ bytes = mult * exp.X_add_number;
+ for (i = 0; i < exp.X_add_number; i++)
+ emit_expr (&val, mult);
+ }
+ }
+ else
+ {
+ if (exp.X_op == O_constant)
+ {
+ long repeat;
+
+ repeat = exp.X_add_number;
+ if (mult)
+ repeat *= mult;
+ bytes = repeat;
+ if (repeat <= 0)
+ {
+ if (!flag_mri)
+ as_warn (_(".space repeat count is zero, ignored"));
+ else if (repeat < 0)
+ as_warn (_(".space repeat count is negative, ignored"));
+ goto getout;
+ }
+
+ /* If we are in the absolute section, just bump the offset. */
+ if (now_seg == absolute_section)
+ {
+ abs_section_offset += repeat;
+ goto getout;
+ }
+
+ /* If we are secretly in an MRI common section, then
+ creating space just increases the size of the common
+ symbol. */
+ if (mri_common_symbol != NULL)
+ {
+ S_SET_VALUE (mri_common_symbol,
+ S_GET_VALUE (mri_common_symbol) + repeat);
+ goto getout;
+ }
+
+ if (!need_pass_2)
+ p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
+ (offsetT) repeat, (char *) 0);
+ }
+ else
+ {
+ if (now_seg == absolute_section)
+ {
+ as_bad (_("space allocation too complex in absolute section"));
+ subseg_set (text_section, 0);
+ }
+
+ if (mri_common_symbol != NULL)
+ {
+ as_bad (_("space allocation too complex in common section"));
+ mri_common_symbol = NULL;
+ }
+
+ if (!need_pass_2)
+ p = frag_var (rs_space, 1, 1, (relax_substateT) 0,
+ make_expr_symbol (&exp), (offsetT) 0, (char *) 0);
+ }
+
+ if (p)
+ *p = val.X_add_number;
+ }
+
+ getout:
+
+ /* In MRI mode, after an odd number of bytes, we must align to an
+ even word boundary, unless the next instruction is a dc.b, ds.b
+ or dcb.b. */
+ if (flag_mri && (bytes & 1) != 0)
+ mri_pending_align = 1;
+
+ demand_empty_rest_of_line ();
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+}
+
+/* This is like s_space, but the value is a floating point number with
+ the given precision. This is for the MRI dcb.s pseudo-op and
+ friends. */
+
+void
+s_float_space (int float_type)
+{
+ offsetT count;
+ int flen;
+ char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ count = get_absolute_expression ();
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing value"));
+ ignore_rest_of_line ();
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+ return;
+ }
+
+ ++input_line_pointer;
+
+ SKIP_WHITESPACE ();
+
+ /* Skip any 0{letter} that may be present. Don't even check if the
+ * letter is legal. */
+ if (input_line_pointer[0] == '0'
+ && ISALPHA (input_line_pointer[1]))
+ input_line_pointer += 2;
+
+ /* Accept :xxxx, where the x's are hex digits, for a floating point
+ with the exact digits specified. */
+ if (input_line_pointer[0] == ':')
+ {
+ flen = hex_float (float_type, temp);
+ if (flen < 0)
+ {
+ ignore_rest_of_line ();
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+ return;
+ }
+ }
+ else
+ {
+ char *err;
+
+ err = md_atof (float_type, temp, &flen);
+ know (flen <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
+ know (flen > 0);
+ if (err)
+ {
+ as_bad (_("bad floating literal: %s"), err);
+ ignore_rest_of_line ();
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+ return;
+ }
+ }
+
+ while (--count >= 0)
+ {
+ char *p;
+
+ p = frag_more (flen);
+ memcpy (p, temp, (unsigned int) flen);
+ }
+
+ demand_empty_rest_of_line ();
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+}
+
+/* Handle the .struct pseudo-op, as found in MIPS assemblers. */
+
+void
+s_struct (int ignore ATTRIBUTE_UNUSED)
+{
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+ abs_section_offset = get_absolute_expression ();
+ subseg_set (absolute_section, 0);
+ demand_empty_rest_of_line ();
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+}
+
+void
+s_text (int ignore ATTRIBUTE_UNUSED)
+{
+ register int temp;
+
+ temp = get_absolute_expression ();
+ subseg_set (text_section, (subsegT) temp);
+ demand_empty_rest_of_line ();
+#ifdef OBJ_VMS
+ const_flag &= ~IN_DEFAULT_SECTION;
+#endif
+}
+
+
+/* Verify that we are at the end of a line. If not, issue an error and
+ skip to EOL. */
+
+void
+demand_empty_rest_of_line (void)
+{
+ SKIP_WHITESPACE ();
+ if (is_end_of_line[(unsigned char) *input_line_pointer])
+ input_line_pointer++;
+ else
+ {
+ if (ISPRINT (*input_line_pointer))
+ as_bad (_("junk at end of line, first unrecognized character is `%c'"),
+ *input_line_pointer);
+ else
+ as_bad (_("junk at end of line, first unrecognized character valued 0x%x"),
+ *input_line_pointer);
+ ignore_rest_of_line ();
+ }
+
+ /* Return pointing just after end-of-line. */
+ know (is_end_of_line[(unsigned char) input_line_pointer[-1]]);
+}
+
+/* Silently advance to the end of line. Use this after already having
+ issued an error about something bad. */
+
+void
+ignore_rest_of_line (void)
+{
+ while (input_line_pointer < buffer_limit
+ && !is_end_of_line[(unsigned char) *input_line_pointer])
+ input_line_pointer++;
+
+ input_line_pointer++;
+
+ /* Return pointing just after end-of-line. */
+ know (is_end_of_line[(unsigned char) input_line_pointer[-1]]);
+}
+
+void
+discard_rest_of_line (void)
+{
+ while (input_line_pointer < buffer_limit
+ && !is_end_of_line[(unsigned char) *input_line_pointer])
+ input_line_pointer++;
+
+ input_line_pointer++;
+
+ /* Return pointing just after end-of-line. */
+ know (is_end_of_line[(unsigned char) input_line_pointer[-1]]);
+}
+
+/* In: Pointer to a symbol.
+ Input_line_pointer->expression.
+
+ Out: Input_line_pointer->just after any whitespace after expression.
+ Tried to set symbol to value of expression.
+ Will change symbols type, value, and frag; */
+
+void
+pseudo_set (symbolS *symbolP)
+{
+ expressionS exp;
+#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
+ int ext;
+#endif /* OBJ_AOUT or OBJ_BOUT */
+
+ know (symbolP); /* NULL pointer is logic error. */
+#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
+ ext = S_IS_EXTERNAL (symbolP);
+#endif /* OBJ_AOUT or OBJ_BOUT */
+
+ (void) expression (&exp);
+
+ if (exp.X_op == O_illegal)
+ as_bad (_("illegal expression"));
+ else if (exp.X_op == O_absent)
+ as_bad (_("missing expression"));
+ else if (exp.X_op == O_big)
+ {
+ if (exp.X_add_number > 0)
+ as_bad (_("bignum invalid"));
+ else
+ as_bad (_("floating point number invalid"));
+ }
+ else if (exp.X_op == O_subtract
+ && SEG_NORMAL (S_GET_SEGMENT (exp.X_add_symbol))
+ && (symbol_get_frag (exp.X_add_symbol)
+ == symbol_get_frag (exp.X_op_symbol)))
+ {
+ exp.X_op = O_constant;
+ exp.X_add_number = (S_GET_VALUE (exp.X_add_symbol)
+ - S_GET_VALUE (exp.X_op_symbol));
+ }
+
+ switch (exp.X_op)
+ {
+ case O_illegal:
+ case O_absent:
+ case O_big:
+ exp.X_add_number = 0;
+ /* Fall through. */
+ case O_constant:
+ S_SET_SEGMENT (symbolP, absolute_section);
+#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
+ if (ext)
+ S_SET_EXTERNAL (symbolP);
+ else
+ S_CLEAR_EXTERNAL (symbolP);
+#endif /* OBJ_AOUT or OBJ_BOUT */
+ S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
+ if (exp.X_op != O_constant)
+ symbol_set_frag (symbolP, &zero_address_frag);
+ break;
+
+ case O_register:
+ S_SET_SEGMENT (symbolP, reg_section);
+ S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
+ symbol_set_frag (symbolP, &zero_address_frag);
+ break;
+
+ case O_symbol:
+ if (S_GET_SEGMENT (exp.X_add_symbol) == undefined_section
+ || exp.X_add_number != 0)
+ symbol_set_value_expression (symbolP, &exp);
+ else if (symbol_section_p (symbolP))
+ as_bad ("attempt to set value of section symbol");
+ else
+ {
+ symbolS *s = exp.X_add_symbol;
+
+ S_SET_SEGMENT (symbolP, S_GET_SEGMENT (s));
+#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
+ if (ext)
+ S_SET_EXTERNAL (symbolP);
+ else
+ S_CLEAR_EXTERNAL (symbolP);
+#endif /* OBJ_AOUT or OBJ_BOUT */
+ S_SET_VALUE (symbolP,
+ exp.X_add_number + S_GET_VALUE (s));
+ symbol_set_frag (symbolP, symbol_get_frag (s));
+ copy_symbol_attributes (symbolP, s);
+ }
+ break;
+
+ default:
+ /* The value is some complex expression.
+ FIXME: Should we set the segment to anything? */
+ symbol_set_value_expression (symbolP, &exp);
+ break;
+ }
+}
+
+/* cons()
+
+ CONStruct more frag of .bytes, or .words etc.
+ Should need_pass_2 be 1 then emit no frag(s).
+ This understands EXPRESSIONS.
+
+ Bug (?)
+
+ This has a split personality. We use expression() to read the
+ value. We can detect if the value won't fit in a byte or word.
+ But we can't detect if expression() discarded significant digits
+ in the case of a long. Not worth the crocks required to fix it. */
+
+/* Select a parser for cons expressions. */
+
+/* Some targets need to parse the expression in various fancy ways.
+ You can define TC_PARSE_CONS_EXPRESSION to do whatever you like
+ (for example, the HPPA does this). Otherwise, you can define
+ BITFIELD_CONS_EXPRESSIONS to permit bitfields to be specified, or
+ REPEAT_CONS_EXPRESSIONS to permit repeat counts. If none of these
+ are defined, which is the normal case, then only simple expressions
+ are permitted. */
+
+#ifdef TC_M68K
+static void
+parse_mri_cons (expressionS *exp, unsigned int nbytes);
+#endif
+
+#ifndef TC_PARSE_CONS_EXPRESSION
+#ifdef BITFIELD_CONS_EXPRESSIONS
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_bitfield_cons (EXP, NBYTES)
+static void
+parse_bitfield_cons (expressionS *exp, unsigned int nbytes);
+#endif
+#ifdef REPEAT_CONS_EXPRESSIONS
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_repeat_cons (EXP, NBYTES)
+static void
+parse_repeat_cons (expressionS *exp, unsigned int nbytes);
+#endif
+
+/* If we haven't gotten one yet, just call expression. */
+#ifndef TC_PARSE_CONS_EXPRESSION
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) expression (EXP)
+#endif
+#endif
+
+void
+do_parse_cons_expression (expressionS *exp,
+ int nbytes ATTRIBUTE_UNUSED)
+{
+ TC_PARSE_CONS_EXPRESSION (exp, nbytes);
+}
+
+
+/* Worker to do .byte etc statements.
+ Clobbers input_line_pointer and checks end-of-line. */
+
+static void
+cons_worker (register int nbytes, /* 1=.byte, 2=.word, 4=.long. */
+ int rva)
+{
+ int c;
+ expressionS exp;
+ char *stop = NULL;
+ char stopc;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ if (is_it_end_of_statement ())
+ {
+ demand_empty_rest_of_line ();
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+ return;
+ }
+
+#ifdef md_cons_align
+ md_cons_align (nbytes);
+#endif
+
+ c = 0;
+ do
+ {
+#ifdef TC_M68K
+ if (flag_m68k_mri)
+ parse_mri_cons (&exp, (unsigned int) nbytes);
+ else
+#endif
+ TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
+
+ if (rva)
+ {
+ if (exp.X_op == O_symbol)
+ exp.X_op = O_symbol_rva;
+ else
+ as_fatal (_("rva without symbol"));
+ }
+ emit_expr (&exp, (unsigned int) nbytes);
+ ++c;
+ }
+ while (*input_line_pointer++ == ',');
+
+ /* In MRI mode, after an odd number of bytes, we must align to an
+ even word boundary, unless the next instruction is a dc.b, ds.b
+ or dcb.b. */
+ if (flag_mri && nbytes == 1 && (c & 1) != 0)
+ mri_pending_align = 1;
+
+ input_line_pointer--; /* Put terminator back into stream. */
+
+ demand_empty_rest_of_line ();
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+}
+
+void
+cons (int size)
+{
+ cons_worker (size, 0);
+}
+
+void
+s_rva (int size)
+{
+ cons_worker (size, 1);
+}
+
+/* Put the contents of expression EXP into the object file using
+ NBYTES bytes. If need_pass_2 is 1, this does nothing. */
+
+void
+emit_expr (expressionS *exp, unsigned int nbytes)
+{
+ operatorT op;
+ register char *p;
+ valueT extra_digit = 0;
+
+ /* Don't do anything if we are going to make another pass. */
+ if (need_pass_2)
+ return;
+
+ dot_value = frag_now_fix ();
+
+#ifndef NO_LISTING
+#ifdef OBJ_ELF
+ /* When gcc emits DWARF 1 debugging pseudo-ops, a line number will
+ appear as a four byte positive constant in the .line section,
+ followed by a 2 byte 0xffff. Look for that case here. */
+ {
+ static int dwarf_line = -1;
+
+ if (strcmp (segment_name (now_seg), ".line") != 0)
+ dwarf_line = -1;
+ else if (dwarf_line >= 0
+ && nbytes == 2
+ && exp->X_op == O_constant
+ && (exp->X_add_number == -1 || exp->X_add_number == 0xffff))
+ listing_source_line ((unsigned int) dwarf_line);
+ else if (nbytes == 4
+ && exp->X_op == O_constant
+ && exp->X_add_number >= 0)
+ dwarf_line = exp->X_add_number;
+ else
+ dwarf_line = -1;
+ }
+
+ /* When gcc emits DWARF 1 debugging pseudo-ops, a file name will
+ appear as a 2 byte TAG_compile_unit (0x11) followed by a 2 byte
+ AT_sibling (0x12) followed by a four byte address of the sibling
+ followed by a 2 byte AT_name (0x38) followed by the name of the
+ file. We look for that case here. */
+ {
+ static int dwarf_file = 0;
+
+ if (strcmp (segment_name (now_seg), ".debug") != 0)
+ dwarf_file = 0;
+ else if (dwarf_file == 0
+ && nbytes == 2
+ && exp->X_op == O_constant
+ && exp->X_add_number == 0x11)
+ dwarf_file = 1;
+ else if (dwarf_file == 1
+ && nbytes == 2
+ && exp->X_op == O_constant
+ && exp->X_add_number == 0x12)
+ dwarf_file = 2;
+ else if (dwarf_file == 2
+ && nbytes == 4)
+ dwarf_file = 3;
+ else if (dwarf_file == 3
+ && nbytes == 2
+ && exp->X_op == O_constant
+ && exp->X_add_number == 0x38)
+ dwarf_file = 4;
+ else
+ dwarf_file = 0;
+
+ /* The variable dwarf_file_string tells stringer that the string
+ may be the name of the source file. */
+ if (dwarf_file == 4)
+ dwarf_file_string = 1;
+ else
+ dwarf_file_string = 0;
+ }
+#endif
+#endif
+
+ if (check_eh_frame (exp, &nbytes))
+ return;
+
+ op = exp->X_op;
+
+ /* Allow `.word 0' in the absolute section. */
+ if (now_seg == absolute_section)
+ {
+ if (op != O_constant || exp->X_add_number != 0)
+ as_bad (_("attempt to store value in absolute section"));
+ abs_section_offset += nbytes;
+ return;
+ }
+
+ /* Handle a negative bignum. */
+ if (op == O_uminus
+ && exp->X_add_number == 0
+ && symbol_get_value_expression (exp->X_add_symbol)->X_op == O_big
+ && symbol_get_value_expression (exp->X_add_symbol)->X_add_number > 0)
+ {
+ int i;
+ unsigned long carry;
+
+ exp = symbol_get_value_expression (exp->X_add_symbol);
+
+ /* Negate the bignum: one's complement each digit and add 1. */
+ carry = 1;
+ for (i = 0; i < exp->X_add_number; i++)
+ {
+ unsigned long next;
+
+ next = (((~(generic_bignum[i] & LITTLENUM_MASK))
+ & LITTLENUM_MASK)
+ + carry);
+ generic_bignum[i] = next & LITTLENUM_MASK;
+ carry = next >> LITTLENUM_NUMBER_OF_BITS;
+ }
+
+ /* We can ignore any carry out, because it will be handled by
+ extra_digit if it is needed. */
+
+ extra_digit = (valueT) -1;
+ op = O_big;
+ }
+
+ if (op == O_absent || op == O_illegal)
+ {
+ as_warn (_("zero assumed for missing expression"));
+ exp->X_add_number = 0;
+ op = O_constant;
+ }
+ else if (op == O_big && exp->X_add_number <= 0)
+ {
+ as_bad (_("floating point number invalid"));
+ exp->X_add_number = 0;
+ op = O_constant;
+ }
+ else if (op == O_register)
+ {
+ as_warn (_("register value used as expression"));
+ op = O_constant;
+ }
+
+ p = frag_more ((int) nbytes);
+
+#ifndef WORKING_DOT_WORD
+ /* If we have the difference of two symbols in a word, save it on
+ the broken_words list. See the code in write.c. */
+ if (op == O_subtract && nbytes == 2)
+ {
+ struct broken_word *x;
+
+ x = (struct broken_word *) xmalloc (sizeof (struct broken_word));
+ x->next_broken_word = broken_words;
+ broken_words = x;
+ x->seg = now_seg;
+ x->subseg = now_subseg;
+ x->frag = frag_now;
+ x->word_goes_here = p;
+ x->dispfrag = 0;
+ x->add = exp->X_add_symbol;
+ x->sub = exp->X_op_symbol;
+ x->addnum = exp->X_add_number;
+ x->added = 0;
+ x->use_jump = 0;
+ new_broken_words++;
+ return;
+ }
+#endif
+
+ /* If we have an integer, but the number of bytes is too large to
+ pass to md_number_to_chars, handle it as a bignum. */
+ if (op == O_constant && nbytes > sizeof (valueT))
+ {
+ valueT val;
+ int gencnt;
+
+ if (!exp->X_unsigned && exp->X_add_number < 0)
+ extra_digit = (valueT) -1;
+ val = (valueT) exp->X_add_number;
+ gencnt = 0;
+ do
+ {
+ generic_bignum[gencnt] = val & LITTLENUM_MASK;
+ val >>= LITTLENUM_NUMBER_OF_BITS;
+ ++gencnt;
+ }
+ while (val != 0);
+ op = exp->X_op = O_big;
+ exp->X_add_number = gencnt;
+ }
+
+ if (op == O_constant)
+ {
+ register valueT get;
+ register valueT use;
+ register valueT mask;
+ valueT hibit;
+ register valueT unmask;
+
+ /* JF << of >= number of bits in the object is undefined. In
+ particular SPARC (Sun 4) has problems. */
+ if (nbytes >= sizeof (valueT))
+ {
+ mask = 0;
+ if (nbytes > sizeof (valueT))
+ hibit = 0;
+ else
+ hibit = (valueT) 1 << (nbytes * BITS_PER_CHAR - 1);
+ }
+ else
+ {
+ /* Don't store these bits. */
+ mask = ~(valueT) 0 << (BITS_PER_CHAR * nbytes);
+ hibit = (valueT) 1 << (nbytes * BITS_PER_CHAR - 1);
+ }
+
+ unmask = ~mask; /* Do store these bits. */
+
+#ifdef NEVER
+ "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
+ mask = ~(unmask >> 1); /* Includes sign bit now. */
+#endif
+
+ get = exp->X_add_number;
+ use = get & unmask;
+ if ((get & mask) != 0
+ && ((get & mask) != mask
+ || (get & hibit) == 0))
+ { /* Leading bits contain both 0s & 1s. */
+ as_warn (_("value 0x%lx truncated to 0x%lx"),
+ (unsigned long) get, (unsigned long) use);
+ }
+ /* Put bytes in right order. */
+ md_number_to_chars (p, use, (int) nbytes);
+ }
+ else if (op == O_big)
+ {
+ unsigned int size;
+ LITTLENUM_TYPE *nums;
+
+ know (nbytes % CHARS_PER_LITTLENUM == 0);
+
+ size = exp->X_add_number * CHARS_PER_LITTLENUM;
+ if (nbytes < size)
+ {
+ as_warn (_("bignum truncated to %d bytes"), nbytes);
+ size = nbytes;
+ }
+
+ if (target_big_endian)
+ {
+ while (nbytes > size)
+ {
+ md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM);
+ nbytes -= CHARS_PER_LITTLENUM;
+ p += CHARS_PER_LITTLENUM;
+ }
+
+ nums = generic_bignum + size / CHARS_PER_LITTLENUM;
+ while (size >= CHARS_PER_LITTLENUM)
+ {
+ --nums;
+ md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM);
+ size -= CHARS_PER_LITTLENUM;
+ p += CHARS_PER_LITTLENUM;
+ }
+ }
+ else
+ {
+ nums = generic_bignum;
+ while (size >= CHARS_PER_LITTLENUM)
+ {
+ md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM);
+ ++nums;
+ size -= CHARS_PER_LITTLENUM;
+ p += CHARS_PER_LITTLENUM;
+ nbytes -= CHARS_PER_LITTLENUM;
+ }
+
+ while (nbytes >= CHARS_PER_LITTLENUM)
+ {
+ md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM);
+ nbytes -= CHARS_PER_LITTLENUM;
+ p += CHARS_PER_LITTLENUM;
+ }
+ }
+ }
+ else
+ {
+ memset (p, 0, nbytes);
+
+ /* Now we need to generate a fixS to record the symbol value.
+ This is easy for BFD. For other targets it can be more
+ complex. For very complex cases (currently, the HPPA and
+ NS32K), you can define TC_CONS_FIX_NEW to do whatever you
+ want. For simpler cases, you can define TC_CONS_RELOC to be
+ the name of the reloc code that should be stored in the fixS.
+ If neither is defined, the code uses NO_RELOC if it is
+ defined, and otherwise uses 0. */
+
+#ifdef BFD_ASSEMBLER
+#ifdef TC_CONS_FIX_NEW
+ TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp);
+#else
+ {
+ bfd_reloc_code_real_type r;
+
+ switch (nbytes)
+ {
+ case 1:
+ r = BFD_RELOC_8;
+ break;
+ case 2:
+ r = BFD_RELOC_16;
+ break;
+ case 4:
+ r = BFD_RELOC_32;
+ break;
+ case 8:
+ r = BFD_RELOC_64;
+ break;
+ default:
+ as_bad (_("unsupported BFD relocation size %u"), nbytes);
+ r = BFD_RELOC_32;
+ break;
+ }
+ fix_new_exp (frag_now, p - frag_now->fr_literal, (int) nbytes, exp,
+ 0, r);
+ }
+#endif
+#else
+#ifdef TC_CONS_FIX_NEW
+ TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp);
+#else
+ /* Figure out which reloc number to use. Use TC_CONS_RELOC if
+ it is defined, otherwise use NO_RELOC if it is defined,
+ otherwise use 0. */
+#ifndef TC_CONS_RELOC
+#ifdef NO_RELOC
+#define TC_CONS_RELOC NO_RELOC
+#else
+#define TC_CONS_RELOC 0
+#endif
+#endif
+ fix_new_exp (frag_now, p - frag_now->fr_literal, (int) nbytes, exp, 0,
+ TC_CONS_RELOC);
+#endif /* TC_CONS_FIX_NEW */
+#endif /* BFD_ASSEMBLER */
+ }
+}
+
+#ifdef BITFIELD_CONS_EXPRESSIONS
+
+/* i960 assemblers, (eg, asm960), allow bitfields after ".byte" as
+ w:x,y:z, where w and y are bitwidths and x and y are values. They
+ then pack them all together. We do a little better in that we allow
+ them in words, longs, etc. and we'll pack them in target byte order
+ for you.
+
+ The rules are: pack least significant bit first, if a field doesn't
+ entirely fit, put it in the next unit. Overflowing the bitfield is
+ explicitly *not* even a warning. The bitwidth should be considered
+ a "mask".
+
+ To use this function the tc-XXX.h file should define
+ BITFIELD_CONS_EXPRESSIONS. */
+
+static void
+parse_bitfield_cons (exp, nbytes)
+ expressionS *exp;
+ unsigned int nbytes;
+{
+ unsigned int bits_available = BITS_PER_CHAR * nbytes;
+ char *hold = input_line_pointer;
+
+ (void) expression (exp);
+
+ if (*input_line_pointer == ':')
+ {
+ /* Bitfields. */
+ long value = 0;
+
+ for (;;)
+ {
+ unsigned long width;
+
+ if (*input_line_pointer != ':')
+ {
+ input_line_pointer = hold;
+ break;
+ } /* Next piece is not a bitfield. */
+
+ /* In the general case, we can't allow
+ full expressions with symbol
+ differences and such. The relocation
+ entries for symbols not defined in this
+ assembly would require arbitrary field
+ widths, positions, and masks which most
+ of our current object formats don't
+ support.
+
+ In the specific case where a symbol
+ *is* defined in this assembly, we
+ *could* build fixups and track it, but
+ this could lead to confusion for the
+ backends. I'm lazy. I'll take any
+ SEG_ABSOLUTE. I think that means that
+ you can use a previous .set or
+ .equ type symbol. xoxorich. */
+
+ if (exp->X_op == O_absent)
+ {
+ as_warn (_("using a bit field width of zero"));
+ exp->X_add_number = 0;
+ exp->X_op = O_constant;
+ } /* Implied zero width bitfield. */
+
+ if (exp->X_op != O_constant)
+ {
+ *input_line_pointer = '\0';
+ as_bad (_("field width \"%s\" too complex for a bitfield"), hold);
+ *input_line_pointer = ':';
+ demand_empty_rest_of_line ();
+ return;
+ } /* Too complex. */
+
+ if ((width = exp->X_add_number) > (BITS_PER_CHAR * nbytes))
+ {
+ as_warn (_("field width %lu too big to fit in %d bytes: truncated to %d bits"),
+ width, nbytes, (BITS_PER_CHAR * nbytes));
+ width = BITS_PER_CHAR * nbytes;
+ } /* Too big. */
+
+ if (width > bits_available)
+ {
+ /* FIXME-SOMEDAY: backing up and reparsing is wasteful. */
+ input_line_pointer = hold;
+ exp->X_add_number = value;
+ break;
+ } /* Won't fit. */
+
+ /* Skip ':'. */
+ hold = ++input_line_pointer;
+
+ (void) expression (exp);
+ if (exp->X_op != O_constant)
+ {
+ char cache = *input_line_pointer;
+
+ *input_line_pointer = '\0';
+ as_bad (_("field value \"%s\" too complex for a bitfield"), hold);
+ *input_line_pointer = cache;
+ demand_empty_rest_of_line ();
+ return;
+ } /* Too complex. */
+
+ value |= ((~(-1 << width) & exp->X_add_number)
+ << ((BITS_PER_CHAR * nbytes) - bits_available));
+
+ if ((bits_available -= width) == 0
+ || is_it_end_of_statement ()
+ || *input_line_pointer != ',')
+ {
+ break;
+ } /* All the bitfields we're gonna get. */
+
+ hold = ++input_line_pointer;
+ (void) expression (exp);
+ }
+
+ exp->X_add_number = value;
+ exp->X_op = O_constant;
+ exp->X_unsigned = 1;
+ }
+}
+
+#endif /* BITFIELD_CONS_EXPRESSIONS */
+
+/* Handle an MRI style string expression. */
+
+#ifdef TC_M68K
+static void
+parse_mri_cons (exp, nbytes)
+ expressionS *exp;
+ unsigned int nbytes;
+{
+ if (*input_line_pointer != '\''
+ && (input_line_pointer[1] != '\''
+ || (*input_line_pointer != 'A'
+ && *input_line_pointer != 'E')))
+ TC_PARSE_CONS_EXPRESSION (exp, nbytes);
+ else
+ {
+ unsigned int scan;
+ unsigned int result = 0;
+
+ /* An MRI style string. Cut into as many bytes as will fit into
+ a nbyte chunk, left justify if necessary, and separate with
+ commas so we can try again later. */
+ if (*input_line_pointer == 'A')
+ ++input_line_pointer;
+ else if (*input_line_pointer == 'E')
+ {
+ as_bad (_("EBCDIC constants are not supported"));
+ ++input_line_pointer;
+ }
+
+ input_line_pointer++;
+ for (scan = 0; scan < nbytes; scan++)
+ {
+ if (*input_line_pointer == '\'')
+ {
+ if (input_line_pointer[1] == '\'')
+ {
+ input_line_pointer++;
+ }
+ else
+ break;
+ }
+ result = (result << 8) | (*input_line_pointer++);
+ }
+
+ /* Left justify. */
+ while (scan < nbytes)
+ {
+ result <<= 8;
+ scan++;
+ }
+
+ /* Create correct expression. */
+ exp->X_op = O_constant;
+ exp->X_add_number = result;
+
+ /* Fake it so that we can read the next char too. */
+ if (input_line_pointer[0] != '\'' ||
+ (input_line_pointer[0] == '\'' && input_line_pointer[1] == '\''))
+ {
+ input_line_pointer -= 2;
+ input_line_pointer[0] = ',';
+ input_line_pointer[1] = '\'';
+ }
+ else
+ input_line_pointer++;
+ }
+}
+#endif /* TC_M68K */
+
+#ifdef REPEAT_CONS_EXPRESSIONS
+
+/* Parse a repeat expression for cons. This is used by the MIPS
+ assembler. The format is NUMBER:COUNT; NUMBER appears in the
+ object file COUNT times.
+
+ To use this for a target, define REPEAT_CONS_EXPRESSIONS. */
+
+static void
+parse_repeat_cons (exp, nbytes)
+ expressionS *exp;
+ unsigned int nbytes;
+{
+ expressionS count;
+ register int i;
+
+ expression (exp);
+
+ if (*input_line_pointer != ':')
+ {
+ /* No repeat count. */
+ return;
+ }
+
+ ++input_line_pointer;
+ expression (&count);
+ if (count.X_op != O_constant
+ || count.X_add_number <= 0)
+ {
+ as_warn (_("unresolvable or nonpositive repeat count; using 1"));
+ return;
+ }
+
+ /* The cons function is going to output this expression once. So we
+ output it count - 1 times. */
+ for (i = count.X_add_number - 1; i > 0; i--)
+ emit_expr (exp, nbytes);
+}
+
+#endif /* REPEAT_CONS_EXPRESSIONS */
+
+/* Parse a floating point number represented as a hex constant. This
+ permits users to specify the exact bits they want in the floating
+ point number. */
+
+static int
+hex_float (int float_type, char *bytes)
+{
+ int length;
+ int i;
+
+ switch (float_type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ length = 4;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ length = 8;
+ break;
+
+ case 'x':
+ case 'X':
+ length = 12;
+ break;
+
+ case 'p':
+ case 'P':
+ length = 12;
+ break;
+
+ default:
+ as_bad (_("unknown floating type type '%c'"), float_type);
+ return -1;
+ }
+
+ /* It would be nice if we could go through expression to parse the
+ hex constant, but if we get a bignum it's a pain to sort it into
+ the buffer correctly. */
+ i = 0;
+ while (hex_p (*input_line_pointer) || *input_line_pointer == '_')
+ {
+ int d;
+
+ /* The MRI assembler accepts arbitrary underscores strewn about
+ through the hex constant, so we ignore them as well. */
+ if (*input_line_pointer == '_')
+ {
+ ++input_line_pointer;
+ continue;
+ }
+
+ if (i >= length)
+ {
+ as_warn (_("floating point constant too large"));
+ return -1;
+ }
+ d = hex_value (*input_line_pointer) << 4;
+ ++input_line_pointer;
+ while (*input_line_pointer == '_')
+ ++input_line_pointer;
+ if (hex_p (*input_line_pointer))
+ {
+ d += hex_value (*input_line_pointer);
+ ++input_line_pointer;
+ }
+ if (target_big_endian)
+ bytes[i] = d;
+ else
+ bytes[length - i - 1] = d;
+ ++i;
+ }
+
+ if (i < length)
+ {
+ if (target_big_endian)
+ memset (bytes + i, 0, length - i);
+ else
+ memset (bytes, 0, length - i);
+ }
+
+ return length;
+}
+
+/* float_cons()
+
+ CONStruct some more frag chars of .floats .ffloats etc.
+ Makes 0 or more new frags.
+ If need_pass_2 == 1, no frags are emitted.
+ This understands only floating literals, not expressions. Sorry.
+
+ A floating constant is defined by atof_generic(), except it is preceded
+ by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
+ reading, I decided to be incompatible. This always tries to give you
+ rounded bits to the precision of the pseudo-op. Former AS did premature
+ truncation, restored noisy bits instead of trailing 0s AND gave you
+ a choice of 2 flavours of noise according to which of 2 floating-point
+ scanners you directed AS to use.
+
+ In: input_line_pointer->whitespace before, or '0' of flonum. */
+
+void
+float_cons (/* Clobbers input_line-pointer, checks end-of-line. */
+ register int float_type /* 'f':.ffloat ... 'F':.float ... */)
+{
+ register char *p;
+ int length; /* Number of chars in an object. */
+ register char *err; /* Error from scanning floating literal. */
+ char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
+
+ if (is_it_end_of_statement ())
+ {
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ do
+ {
+ /* input_line_pointer->1st char of a flonum (we hope!). */
+ SKIP_WHITESPACE ();
+
+ /* Skip any 0{letter} that may be present. Don't even check if the
+ letter is legal. Someone may invent a "z" format and this routine
+ has no use for such information. Lusers beware: you get
+ diagnostics if your input is ill-conditioned. */
+ if (input_line_pointer[0] == '0'
+ && ISALPHA (input_line_pointer[1]))
+ input_line_pointer += 2;
+
+ /* Accept :xxxx, where the x's are hex digits, for a floating
+ point with the exact digits specified. */
+ if (input_line_pointer[0] == ':')
+ {
+ ++input_line_pointer;
+ length = hex_float (float_type, temp);
+ if (length < 0)
+ {
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ else
+ {
+ err = md_atof (float_type, temp, &length);
+ know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
+ know (length > 0);
+ if (err)
+ {
+ as_bad (_("bad floating literal: %s"), err);
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+
+ if (!need_pass_2)
+ {
+ int count;
+
+ count = 1;
+
+#ifdef REPEAT_CONS_EXPRESSIONS
+ if (*input_line_pointer == ':')
+ {
+ expressionS count_exp;
+
+ ++input_line_pointer;
+ expression (&count_exp);
+
+ if (count_exp.X_op != O_constant
+ || count_exp.X_add_number <= 0)
+ as_warn (_("unresolvable or nonpositive repeat count; using 1"));
+ else
+ count = count_exp.X_add_number;
+ }
+#endif
+
+ while (--count >= 0)
+ {
+ p = frag_more (length);
+ memcpy (p, temp, (unsigned int) length);
+ }
+ }
+ SKIP_WHITESPACE ();
+ }
+ while (*input_line_pointer++ == ',');
+
+ /* Put terminator back into stream. */
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+}
+
+/* Return the size of a LEB128 value. */
+
+static inline int
+sizeof_sleb128 (offsetT value)
+{
+ register int size = 0;
+ register unsigned byte;
+
+ do
+ {
+ byte = (value & 0x7f);
+ /* Sadly, we cannot rely on typical arithmetic right shift behaviour.
+ Fortunately, we can structure things so that the extra work reduces
+ to a noop on systems that do things "properly". */
+ value = (value >> 7) | ~(-(offsetT)1 >> 7);
+ size += 1;
+ }
+ while (!(((value == 0) && ((byte & 0x40) == 0))
+ || ((value == -1) && ((byte & 0x40) != 0))));
+
+ return size;
+}
+
+static inline int
+sizeof_uleb128 (valueT value)
+{
+ register int size = 0;
+ register unsigned byte;
+
+ do
+ {
+ byte = (value & 0x7f);
+ value >>= 7;
+ size += 1;
+ }
+ while (value != 0);
+
+ return size;
+}
+
+int
+sizeof_leb128 (valueT value, int sign)
+{
+ if (sign)
+ return sizeof_sleb128 ((offsetT) value);
+ else
+ return sizeof_uleb128 (value);
+}
+
+/* Output a LEB128 value. */
+
+static inline int
+output_sleb128 (char *p, offsetT value)
+{
+ register char *orig = p;
+ register int more;
+
+ do
+ {
+ unsigned byte = (value & 0x7f);
+
+ /* Sadly, we cannot rely on typical arithmetic right shift behaviour.
+ Fortunately, we can structure things so that the extra work reduces
+ to a noop on systems that do things "properly". */
+ value = (value >> 7) | ~(-(offsetT)1 >> 7);
+
+ more = !((((value == 0) && ((byte & 0x40) == 0))
+ || ((value == -1) && ((byte & 0x40) != 0))));
+ if (more)
+ byte |= 0x80;
+
+ *p++ = byte;
+ }
+ while (more);
+
+ return p - orig;
+}
+
+static inline int
+output_uleb128 (char *p, valueT value)
+{
+ char *orig = p;
+
+ do
+ {
+ unsigned byte = (value & 0x7f);
+ value >>= 7;
+ if (value != 0)
+ /* More bytes to follow. */
+ byte |= 0x80;
+
+ *p++ = byte;
+ }
+ while (value != 0);
+
+ return p - orig;
+}
+
+int
+output_leb128 (char *p, valueT value, int sign)
+{
+ if (sign)
+ return output_sleb128 (p, (offsetT) value);
+ else
+ return output_uleb128 (p, value);
+}
+
+/* Do the same for bignums. We combine sizeof with output here in that
+ we don't output for NULL values of P. It isn't really as critical as
+ for "normal" values that this be streamlined. */
+
+static inline int
+output_big_sleb128 (char *p, LITTLENUM_TYPE *bignum, int size)
+{
+ char *orig = p;
+ valueT val = 0;
+ int loaded = 0;
+ unsigned byte;
+
+ /* Strip leading sign extensions off the bignum. */
+ while (size > 0 && bignum[size - 1] == (LITTLENUM_TYPE) -1)
+ size--;
+
+ do
+ {
+ if (loaded < 7 && size > 0)
+ {
+ val |= (*bignum << loaded);
+ loaded += 8 * CHARS_PER_LITTLENUM;
+ size--;
+ bignum++;
+ }
+
+ byte = val & 0x7f;
+ loaded -= 7;
+ val >>= 7;
+
+ if (size == 0)
+ {
+ if ((val == 0 && (byte & 0x40) == 0)
+ || (~(val | ~(((valueT) 1 << loaded) - 1)) == 0
+ && (byte & 0x40) != 0))
+ byte |= 0x80;
+ }
+
+ if (orig)
+ *p = byte;
+ p++;
+ }
+ while (byte & 0x80);
+
+ return p - orig;
+}
+
+static inline int
+output_big_uleb128 (char *p, LITTLENUM_TYPE *bignum, int size)
+{
+ char *orig = p;
+ valueT val = 0;
+ int loaded = 0;
+ unsigned byte;
+
+ /* Strip leading zeros off the bignum. */
+ /* XXX: Is this needed? */
+ while (size > 0 && bignum[size - 1] == 0)
+ size--;
+
+ do
+ {
+ if (loaded < 7 && size > 0)
+ {
+ val |= (*bignum << loaded);
+ loaded += 8 * CHARS_PER_LITTLENUM;
+ size--;
+ bignum++;
+ }
+
+ byte = val & 0x7f;
+ loaded -= 7;
+ val >>= 7;
+
+ if (size > 0 || val)
+ byte |= 0x80;
+
+ if (orig)
+ *p = byte;
+ p++;
+ }
+ while (byte & 0x80);
+
+ return p - orig;
+}
+
+static int
+output_big_leb128 (char *p, LITTLENUM_TYPE *bignum, int size, int sign)
+{
+ if (sign)
+ return output_big_sleb128 (p, bignum, size);
+ else
+ return output_big_uleb128 (p, bignum, size);
+}
+
+/* Generate the appropriate fragments for a given expression to emit a
+ leb128 value. */
+
+void
+emit_leb128_expr (expressionS *exp, int sign)
+{
+ operatorT op = exp->X_op;
+ int nbytes;
+
+ if (op == O_absent || op == O_illegal)
+ {
+ as_warn (_("zero assumed for missing expression"));
+ exp->X_add_number = 0;
+ op = O_constant;
+ }
+ else if (op == O_big && exp->X_add_number <= 0)
+ {
+ as_bad (_("floating point number invalid"));
+ exp->X_add_number = 0;
+ op = O_constant;
+ }
+ else if (op == O_register)
+ {
+ as_warn (_("register value used as expression"));
+ op = O_constant;
+ }
+
+ /* Let check_eh_frame know that data is being emitted. nbytes == -1 is
+ a signal that this is leb128 data. It shouldn't optimize this away. */
+ nbytes = -1;
+ if (check_eh_frame (exp, &nbytes))
+ abort ();
+
+ /* Let the backend know that subsequent data may be byte aligned. */
+#ifdef md_cons_align
+ md_cons_align (1);
+#endif
+
+ if (op == O_constant)
+ {
+ /* If we've got a constant, emit the thing directly right now. */
+
+ valueT value = exp->X_add_number;
+ int size;
+ char *p;
+
+ size = sizeof_leb128 (value, sign);
+ p = frag_more (size);
+ output_leb128 (p, value, sign);
+ }
+ else if (op == O_big)
+ {
+ /* O_big is a different sort of constant. */
+
+ int size;
+ char *p;
+
+ size = output_big_leb128 (NULL, generic_bignum, exp->X_add_number, sign);
+ p = frag_more (size);
+ output_big_leb128 (p, generic_bignum, exp->X_add_number, sign);
+ }
+ else
+ {
+ /* Otherwise, we have to create a variable sized fragment and
+ resolve things later. */
+
+ frag_var (rs_leb128, sizeof_uleb128 (~(valueT) 0), 0, sign,
+ make_expr_symbol (exp), 0, (char *) NULL);
+ }
+}
+
+/* Parse the .sleb128 and .uleb128 pseudos. */
+
+void
+s_leb128 (int sign)
+{
+ expressionS exp;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ do
+ {
+ expression (&exp);
+ emit_leb128_expr (&exp, sign);
+ }
+ while (*input_line_pointer++ == ',');
+
+ input_line_pointer--;
+ demand_empty_rest_of_line ();
+}
+
+/* We read 0 or more ',' separated, double-quoted strings.
+ Caller should have checked need_pass_2 is FALSE because we don't
+ check it. */
+
+void
+stringer (/* Worker to do .ascii etc statements. */
+ /* Checks end-of-line. */
+ register int append_zero /* 0: don't append '\0', else 1. */)
+{
+ register unsigned int c;
+ char *start;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ /* The following awkward logic is to parse ZERO or more strings,
+ comma separated. Recall a string expression includes spaces
+ before the opening '\"' and spaces after the closing '\"'.
+ We fake a leading ',' if there is (supposed to be)
+ a 1st, expression. We keep demanding expressions for each ','. */
+ if (is_it_end_of_statement ())
+ {
+ c = 0; /* Skip loop. */
+ ++input_line_pointer; /* Compensate for end of loop. */
+ }
+ else
+ {
+ c = ','; /* Do loop. */
+ }
+ /* If we have been switched into the abs_section then we
+ will not have an obstack onto which we can hang strings. */
+ if (now_seg == absolute_section)
+ {
+ as_bad (_("strings must be placed into a section"));
+ c = 0;
+ ignore_rest_of_line ();
+ }
+
+ while (c == ',' || c == '<' || c == '"')
+ {
+ SKIP_WHITESPACE ();
+ switch (*input_line_pointer)
+ {
+ case '\"':
+ ++input_line_pointer; /*->1st char of string. */
+ start = input_line_pointer;
+ while (is_a_char (c = next_char_of_string ()))
+ {
+ FRAG_APPEND_1_CHAR (c);
+ }
+ if (append_zero)
+ {
+ FRAG_APPEND_1_CHAR (0);
+ }
+ know (input_line_pointer[-1] == '\"');
+
+#ifndef NO_LISTING
+#ifdef OBJ_ELF
+ /* In ELF, when gcc is emitting DWARF 1 debugging output, it
+ will emit .string with a filename in the .debug section
+ after a sequence of constants. See the comment in
+ emit_expr for the sequence. emit_expr will set
+ dwarf_file_string to non-zero if this string might be a
+ source file name. */
+ if (strcmp (segment_name (now_seg), ".debug") != 0)
+ dwarf_file_string = 0;
+ else if (dwarf_file_string)
+ {
+ c = input_line_pointer[-1];
+ input_line_pointer[-1] = '\0';
+ listing_source_file (start);
+ input_line_pointer[-1] = c;
+ }
+#endif
+#endif
+
+ break;
+ case '<':
+ input_line_pointer++;
+ c = get_single_number ();
+ FRAG_APPEND_1_CHAR (c);
+ if (*input_line_pointer != '>')
+ {
+ as_bad (_("expected <nn>"));
+ }
+ input_line_pointer++;
+ break;
+ case ',':
+ input_line_pointer++;
+ break;
+ }
+ SKIP_WHITESPACE ();
+ c = *input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+} /* stringer() */
+
+/* FIXME-SOMEDAY: I had trouble here on characters with the
+ high bits set. We'll probably also have trouble with
+ multibyte chars, wide chars, etc. Also be careful about
+ returning values bigger than 1 byte. xoxorich. */
+
+unsigned int
+next_char_of_string (void)
+{
+ register unsigned int c;
+
+ c = *input_line_pointer++ & CHAR_MASK;
+ switch (c)
+ {
+ case '\"':
+ c = NOT_A_CHAR;
+ break;
+
+ case '\n':
+ as_warn (_("unterminated string; newline inserted"));
+ bump_line_counters ();
+ break;
+
+#ifndef NO_STRING_ESCAPES
+ case '\\':
+ switch (c = *input_line_pointer++)
+ {
+ case 'b':
+ c = '\b';
+ break;
+
+ case 'f':
+ c = '\f';
+ break;
+
+ case 'n':
+ c = '\n';
+ break;
+
+ case 'r':
+ c = '\r';
+ break;
+
+ case 't':
+ c = '\t';
+ break;
+
+ case 'v':
+ c = '\013';
+ break;
+
+ case '\\':
+ case '"':
+ break; /* As itself. */
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ long number;
+ int i;
+
+ for (i = 0, number = 0;
+ ISDIGIT (c) && i < 3;
+ c = *input_line_pointer++, i++)
+ {
+ number = number * 8 + c - '0';
+ }
+
+ c = number & 0xff;
+ }
+ --input_line_pointer;
+ break;
+
+ case 'x':
+ case 'X':
+ {
+ long number;
+
+ number = 0;
+ c = *input_line_pointer++;
+ while (ISXDIGIT (c))
+ {
+ if (ISDIGIT (c))
+ number = number * 16 + c - '0';
+ else if (ISUPPER (c))
+ number = number * 16 + c - 'A' + 10;
+ else
+ number = number * 16 + c - 'a' + 10;
+ c = *input_line_pointer++;
+ }
+ c = number & 0xff;
+ --input_line_pointer;
+ }
+ break;
+
+ case '\n':
+ /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */
+ as_warn (_("unterminated string; newline inserted"));
+ c = '\n';
+ bump_line_counters ();
+ break;
+
+ default:
+
+#ifdef ONLY_STANDARD_ESCAPES
+ as_bad (_("bad escaped character in string"));
+ c = '?';
+#endif /* ONLY_STANDARD_ESCAPES */
+
+ break;
+ }
+ break;
+#endif /* ! defined (NO_STRING_ESCAPES) */
+
+ default:
+ break;
+ }
+ return (c);
+}
+
+static segT
+get_segmented_expression (register expressionS *expP)
+{
+ register segT retval;
+
+ retval = expression (expP);
+ if (expP->X_op == O_illegal
+ || expP->X_op == O_absent
+ || expP->X_op == O_big)
+ {
+ as_bad (_("expected address expression"));
+ expP->X_op = O_constant;
+ expP->X_add_number = 0;
+ retval = absolute_section;
+ }
+ return retval;
+}
+
+static segT
+get_known_segmented_expression (register expressionS *expP)
+{
+ register segT retval;
+
+ if ((retval = get_segmented_expression (expP)) == undefined_section)
+ {
+ /* There is no easy way to extract the undefined symbol from the
+ expression. */
+ if (expP->X_add_symbol != NULL
+ && S_GET_SEGMENT (expP->X_add_symbol) != expr_section)
+ as_warn (_("symbol \"%s\" undefined; zero assumed"),
+ S_GET_NAME (expP->X_add_symbol));
+ else
+ as_warn (_("some symbol undefined; zero assumed"));
+ retval = absolute_section;
+ expP->X_op = O_constant;
+ expP->X_add_number = 0;
+ }
+ know (retval == absolute_section || SEG_NORMAL (retval));
+ return (retval);
+}
+
+offsetT
+get_absolute_expr (expressionS *exp)
+{
+ expression (exp);
+ if (exp->X_op != O_constant)
+ {
+ if (exp->X_op != O_absent)
+ as_bad (_("bad or irreducible absolute expression"));
+ exp->X_add_number = 0;
+ }
+ return exp->X_add_number;
+}
+
+offsetT
+get_absolute_expression (void)
+{
+ expressionS exp;
+
+ return get_absolute_expr (&exp);
+}
+
+char /* Return terminator. */
+get_absolute_expression_and_terminator (long *val_pointer /* Return value of expression. */)
+{
+ /* FIXME: val_pointer should probably be offsetT *. */
+ *val_pointer = (long) get_absolute_expression ();
+ return (*input_line_pointer++);
+}
+
+/* Like demand_copy_string, but return NULL if the string contains any '\0's.
+ Give a warning if that happens. */
+
+char *
+demand_copy_C_string (int *len_pointer)
+{
+ register char *s;
+
+ if ((s = demand_copy_string (len_pointer)) != 0)
+ {
+ register int len;
+
+ for (len = *len_pointer; len > 0; len--)
+ {
+ if (*s == 0)
+ {
+ s = 0;
+ len = 1;
+ *len_pointer = 0;
+ as_bad (_("this string may not contain \'\\0\'"));
+ }
+ }
+ }
+
+ return s;
+}
+
+/* Demand string, but return a safe (=private) copy of the string.
+ Return NULL if we can't read a string here. */
+
+char *
+demand_copy_string (int *lenP)
+{
+ register unsigned int c;
+ register int len;
+ char *retval;
+
+ len = 0;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\"')
+ {
+ input_line_pointer++; /* Skip opening quote. */
+
+ while (is_a_char (c = next_char_of_string ()))
+ {
+ obstack_1grow (&notes, c);
+ len++;
+ }
+ /* JF this next line is so demand_copy_C_string will return a
+ null terminated string. */
+ obstack_1grow (&notes, '\0');
+ retval = obstack_finish (&notes);
+ }
+ else
+ {
+ as_bad (_("missing string"));
+ retval = NULL;
+ ignore_rest_of_line ();
+ }
+ *lenP = len;
+ return (retval);
+}
+
+/* In: Input_line_pointer->next character.
+
+ Do: Skip input_line_pointer over all whitespace.
+
+ Out: 1 if input_line_pointer->end-of-line. */
+
+int
+is_it_end_of_statement (void)
+{
+ SKIP_WHITESPACE ();
+ return (is_end_of_line[(unsigned char) *input_line_pointer]);
+}
+
+void
+equals (char *sym_name, int reassign)
+{
+ register symbolS *symbolP; /* Symbol we are working with. */
+ char *stop = NULL;
+ char stopc;
+
+ input_line_pointer++;
+ if (*input_line_pointer == '=')
+ input_line_pointer++;
+
+ while (*input_line_pointer == ' ' || *input_line_pointer == '\t')
+ input_line_pointer++;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ if (sym_name[0] == '.' && sym_name[1] == '\0')
+ {
+ /* Turn '. = mumble' into a .org mumble. */
+ register segT segment;
+ expressionS exp;
+
+ segment = get_known_segmented_expression (&exp);
+ if (!need_pass_2)
+ do_org (segment, &exp, 0);
+ }
+ else
+ {
+#ifdef OBJ_COFF
+ int local;
+
+ symbolP = symbol_find (sym_name);
+ local = symbolP == NULL;
+ if (local)
+#endif /* OBJ_COFF */
+ symbolP = symbol_find_or_make (sym_name);
+ /* Permit register names to be redefined. */
+ if (!reassign
+ && S_IS_DEFINED (symbolP)
+ && S_GET_SEGMENT (symbolP) != reg_section)
+ as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP));
+
+#ifdef OBJ_COFF
+ /* "set" symbols are local unless otherwise specified. */
+ if (local)
+ SF_SET_LOCAL (symbolP);
+#endif /* OBJ_COFF */
+
+ pseudo_set (symbolP);
+ }
+
+ if (flag_mri)
+ {
+ /* Check garbage after the expression. */
+ demand_empty_rest_of_line ();
+ mri_comment_end (stop, stopc);
+ }
+}
+
+/* .incbin -- include a file verbatim at the current location. */
+
+void
+s_incbin (int x ATTRIBUTE_UNUSED)
+{
+ FILE * binfile;
+ char * path;
+ char * filename;
+ char * binfrag;
+ long skip = 0;
+ long count = 0;
+ long bytes;
+ int len;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ SKIP_WHITESPACE ();
+ filename = demand_copy_string (& len);
+ if (filename == NULL)
+ return;
+
+ SKIP_WHITESPACE ();
+
+ /* Look for optional skip and count. */
+ if (* input_line_pointer == ',')
+ {
+ ++ input_line_pointer;
+ skip = get_absolute_expression ();
+
+ SKIP_WHITESPACE ();
+
+ if (* input_line_pointer == ',')
+ {
+ ++ input_line_pointer;
+
+ count = get_absolute_expression ();
+ if (count == 0)
+ as_warn (_(".incbin count zero, ignoring `%s'"), filename);
+
+ SKIP_WHITESPACE ();
+ }
+ }
+
+ demand_empty_rest_of_line ();
+
+ /* Try opening absolute path first, then try include dirs. */
+ binfile = fopen (filename, FOPEN_RB);
+ if (binfile == NULL)
+ {
+ int i;
+
+ path = xmalloc ((unsigned long) len + include_dir_maxlen + 5);
+
+ for (i = 0; i < include_dir_count; i++)
+ {
+ sprintf (path, "%s/%s", include_dirs[i], filename);
+
+ binfile = fopen (path, FOPEN_RB);
+ if (binfile != NULL)
+ break;
+ }
+
+ if (binfile == NULL)
+ as_bad (_("file not found: %s"), filename);
+ }
+ else
+ path = xstrdup (filename);
+
+ if (binfile)
+ {
+ long file_len;
+
+ register_dependency (path);
+
+ /* Compute the length of the file. */
+ if (fseek (binfile, 0, SEEK_END) != 0)
+ {
+ as_bad (_("seek to end of .incbin file failed `%s'"), path);
+ goto done;
+ }
+ file_len = ftell (binfile);
+
+ /* If a count was not specified use the size of the file. */
+ if (count == 0)
+ count = file_len;
+
+ if (skip + count > file_len)
+ {
+ as_bad (_("skip (%ld) + count (%ld) larger than file size (%ld)"),
+ skip, count, file_len);
+ goto done;
+ }
+
+ if (fseek (binfile, skip, SEEK_SET) != 0)
+ {
+ as_bad (_("could not skip to %ld in file `%s'"), skip, path);
+ goto done;
+ }
+
+ /* Allocate frag space and store file contents in it. */
+ binfrag = frag_more (count);
+
+ bytes = fread (binfrag, 1, count, binfile);
+ if (bytes < count)
+ as_warn (_("truncated file `%s', %ld of %ld bytes read"),
+ path, bytes, count);
+ }
+done:
+ if (binfile != NULL)
+ fclose (binfile);
+ if (path)
+ free (path);
+}
+
+/* .include -- include a file at this point. */
+
+void
+s_include (int arg ATTRIBUTE_UNUSED)
+{
+ char *filename;
+ int i;
+ FILE *try;
+ char *path;
+
+ if (!flag_m68k_mri)
+ {
+ filename = demand_copy_string (&i);
+ if (filename == NULL)
+ {
+ /* demand_copy_string has already printed an error and
+ called ignore_rest_of_line. */
+ return;
+ }
+ }
+ else
+ {
+ SKIP_WHITESPACE ();
+ i = 0;
+ while (!is_end_of_line[(unsigned char) *input_line_pointer]
+ && *input_line_pointer != ' '
+ && *input_line_pointer != '\t')
+ {
+ obstack_1grow (&notes, *input_line_pointer);
+ ++input_line_pointer;
+ ++i;
+ }
+
+ obstack_1grow (&notes, '\0');
+ filename = obstack_finish (&notes);
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+ path = xmalloc ((unsigned long) i + include_dir_maxlen + 5 /* slop */ );
+
+ for (i = 0; i < include_dir_count; i++)
+ {
+ strcpy (path, include_dirs[i]);
+ strcat (path, "/");
+ strcat (path, filename);
+ if (0 != (try = fopen (path, FOPEN_RT)))
+ {
+ fclose (try);
+ goto gotit;
+ }
+ }
+
+ free (path);
+ path = filename;
+gotit:
+ /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */
+ register_dependency (path);
+ input_scrub_insert_file (path);
+}
+
+void
+add_include_dir (char *path)
+{
+ int i;
+
+ if (include_dir_count == 0)
+ {
+ include_dirs = (char **) xmalloc (2 * sizeof (*include_dirs));
+ include_dirs[0] = "."; /* Current dir. */
+ include_dir_count = 2;
+ }
+ else
+ {
+ include_dir_count++;
+ include_dirs =
+ (char **) realloc (include_dirs,
+ include_dir_count * sizeof (*include_dirs));
+ }
+
+ include_dirs[include_dir_count - 1] = path; /* New one. */
+
+ i = strlen (path);
+ if (i > include_dir_maxlen)
+ include_dir_maxlen = i;
+}
+
+/* Output debugging information to denote the source file. */
+
+static void
+generate_file_debug (void)
+{
+ if (debug_type == DEBUG_STABS)
+ stabs_generate_asm_file ();
+}
+
+/* Output line number debugging information for the current source line. */
+
+void
+generate_lineno_debug (void)
+{
+ switch (debug_type)
+ {
+ case DEBUG_UNSPECIFIED:
+ case DEBUG_NONE:
+ case DEBUG_DWARF:
+ break;
+ case DEBUG_STABS:
+ stabs_generate_asm_lineno ();
+ break;
+ case DEBUG_ECOFF:
+ ecoff_generate_asm_lineno ();
+ break;
+ case DEBUG_DWARF2:
+ /* ??? We could here indicate to dwarf2dbg.c that something
+ has changed. However, since there is additional backend
+ support that is required (calling dwarf2_emit_insn), we
+ let dwarf2dbg.c call as_where on its own. */
+ break;
+ }
+}
+
+/* Output debugging information to mark a function entry point or end point.
+ END_P is zero for .func, and non-zero for .endfunc. */
+
+void
+s_func (int end_p)
+{
+ do_s_func (end_p, NULL);
+}
+
+/* Subroutine of s_func so targets can choose a different default prefix.
+ If DEFAULT_PREFIX is NULL, use the target's "leading char". */
+
+void
+do_s_func (int end_p, const char *default_prefix)
+{
+ /* Record the current function so that we can issue an error message for
+ misplaced .func,.endfunc, and also so that .endfunc needs no
+ arguments. */
+ static char *current_name;
+ static char *current_label;
+
+ if (end_p)
+ {
+ if (current_name == NULL)
+ {
+ as_bad (_("missing .func"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (debug_type == DEBUG_STABS)
+ stabs_generate_asm_endfunc (current_name, current_label);
+
+ current_name = current_label = NULL;
+ }
+ else /* ! end_p */
+ {
+ char *name, *label;
+ char delim1, delim2;
+
+ if (current_name != NULL)
+ {
+ as_bad (_(".endfunc missing for previous .func"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ name = input_line_pointer;
+ delim1 = get_symbol_end ();
+ name = xstrdup (name);
+ *input_line_pointer = delim1;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ if (default_prefix)
+ asprintf (&label, "%s%s", default_prefix, name);
+ else
+ {
+ char leading_char = 0;
+#ifdef BFD_ASSEMBLER
+ leading_char = bfd_get_symbol_leading_char (stdoutput);
+#endif
+ /* Missing entry point, use function's name with the leading
+ char prepended. */
+ if (leading_char)
+ asprintf (&label, "%c%s", leading_char, name);
+ else
+ label = name;
+ }
+ }
+ else
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ label = input_line_pointer;
+ delim2 = get_symbol_end ();
+ label = xstrdup (label);
+ *input_line_pointer = delim2;
+ }
+
+ if (debug_type == DEBUG_STABS)
+ stabs_generate_asm_func (name, label);
+
+ current_name = name;
+ current_label = label;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+void
+s_ignore (int arg ATTRIBUTE_UNUSED)
+{
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ ++input_line_pointer;
+ }
+ ++input_line_pointer;
+}
+
+void
+read_print_statistics (FILE *file)
+{
+ hash_print_statistics (file, "pseudo-op table", po_hash);
+}
+
+/* Inserts the given line into the input stream.
+
+ This call avoids macro/conditionals nesting checking, since the contents of
+ the line are assumed to replace the contents of a line already scanned.
+
+ An appropriate use of this function would be substitution of input lines when
+ called by md_start_line_hook(). The given line is assumed to already be
+ properly scrubbed. */
+
+void
+input_scrub_insert_line (const char *line)
+{
+ sb newline;
+ sb_new (&newline);
+ sb_add_string (&newline, line);
+ input_scrub_include_sb (&newline, input_line_pointer, 0);
+ sb_kill (&newline);
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+}
+
+/* Insert a file into the input stream; the path must resolve to an actual
+ file; no include path searching or dependency registering is performed. */
+
+void
+input_scrub_insert_file (char *path)
+{
+ input_scrub_include_file (path, input_line_pointer);
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+}
diff --git a/x/binutils/gas/read.h b/x/binutils/gas/read.h
new file mode 100644
index 0000000..b89ffcb
--- /dev/null
+++ b/x/binutils/gas/read.h
@@ -0,0 +1,188 @@
+/* read.h - of read.c
+ Copyright 1986, 1990, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+extern char *input_line_pointer; /* -> char we are parsing now. */
+
+/* Define to make whitespace be allowed in many syntactically
+ unnecessary places. Normally undefined. For compatibility with
+ ancient GNU cc. */
+/* #undef PERMIT_WHITESPACE */
+#define PERMIT_WHITESPACE
+
+#ifdef PERMIT_WHITESPACE
+#define SKIP_WHITESPACE() \
+ ((*input_line_pointer == ' ') ? ++input_line_pointer : 0)
+#else
+#define SKIP_WHITESPACE() know(*input_line_pointer != ' ' )
+#endif
+
+#define LEX_NAME (1) /* may continue a name */
+#define LEX_BEGIN_NAME (2) /* may begin a name */
+#define LEX_END_NAME (4) /* ends a name */
+
+#define is_name_beginner(c) \
+ ( lex_type[(unsigned char) (c)] & LEX_BEGIN_NAME )
+#define is_part_of_name(c) \
+ ( lex_type[(unsigned char) (c)] & LEX_NAME )
+#define is_name_ender(c) \
+ ( lex_type[(unsigned char) (c)] & LEX_END_NAME )
+
+#ifndef is_a_char
+#define CHAR_MASK (0xff)
+#define NOT_A_CHAR (CHAR_MASK+1)
+#define is_a_char(c) (((unsigned) (c)) <= CHAR_MASK)
+#endif /* is_a_char() */
+
+extern char lex_type[];
+extern char is_end_of_line[];
+
+extern int is_it_end_of_statement (void);
+
+extern int target_big_endian;
+
+/* These are initialized by the CPU specific target files (tc-*.c). */
+extern const char comment_chars[];
+extern const char line_comment_chars[];
+extern const char line_separator_chars[];
+
+/* Table of -I directories. */
+extern char **include_dirs;
+extern int include_dir_count;
+extern int include_dir_maxlen;
+
+/* The offset in the absolute section. */
+extern addressT abs_section_offset;
+
+/* The label on a line, used by some of the pseudo-ops. */
+extern symbolS *line_label;
+
+/* This is used to support MRI common sections. */
+extern symbolS *mri_common_symbol;
+
+/* True if a stabs line debug statement is currently being emitted. */
+extern int outputting_stabs_line_debug;
+
+/* Possible arguments to .linkonce. */
+enum linkonce_type {
+ LINKONCE_UNSET = 0,
+ LINKONCE_DISCARD,
+ LINKONCE_ONE_ONLY,
+ LINKONCE_SAME_SIZE,
+ LINKONCE_SAME_CONTENTS
+};
+
+#ifndef TC_CASE_SENSITIVE
+extern char original_case_string[];
+#endif
+
+extern void pop_insert (const pseudo_typeS *);
+extern unsigned int get_stab_string_offset
+ (const char *string, const char *stabstr_secname);
+extern void aout_process_stab (int, const char *, int, int, int);
+extern char *demand_copy_string (int *lenP);
+extern char *demand_copy_C_string (int *len_pointer);
+extern char get_absolute_expression_and_terminator (long *val_pointer);
+extern offsetT get_absolute_expr (expressionS *);
+extern offsetT get_absolute_expression (void);
+extern unsigned int next_char_of_string (void);
+extern void s_mri_sect (char *);
+extern char *mri_comment_field (char *);
+extern void mri_comment_end (char *, int);
+extern void add_include_dir (char *path);
+extern void cons (int nbytes);
+extern void demand_empty_rest_of_line (void);
+extern void emit_expr (expressionS *exp, unsigned int nbytes);
+extern void emit_leb128_expr (expressionS *, int);
+extern void equals (char *sym_name, int reassign);
+extern void float_cons (int float_type);
+extern void ignore_rest_of_line (void);
+extern void discard_rest_of_line (void);
+extern int output_leb128 (char *, valueT, int sign);
+extern void pseudo_set (symbolS * symbolP);
+extern void read_a_source_file (char *name);
+extern void read_begin (void);
+extern void read_print_statistics (FILE *);
+extern int sizeof_leb128 (valueT, int sign);
+extern void stabs_generate_asm_file (void);
+extern void stabs_generate_asm_lineno (void);
+extern void stabs_generate_asm_func (const char *, const char *);
+extern void stabs_generate_asm_endfunc (const char *, const char *);
+extern void do_repeat (int,const char *,const char *);
+extern void end_repeat (int);
+extern void do_parse_cons_expression (expressionS *, int);
+
+extern void generate_lineno_debug (void);
+
+extern void s_abort (int) ATTRIBUTE_NORETURN;
+extern void s_align_bytes (int arg);
+extern void s_align_ptwo (int);
+extern void bss_alloc (symbolS *, addressT, int);
+extern offsetT parse_align (int);
+extern symbolS *s_comm_internal (int, symbolS *(*) (int, symbolS *, addressT));
+extern symbolS *s_lcomm_internal (int, symbolS *, addressT);
+extern void s_app_file_string (char *);
+extern void s_app_file (int);
+extern void s_app_line (int);
+extern void s_bad_endr (int);
+extern void s_comm (int);
+extern void s_data (int);
+extern void s_desc (int);
+extern void s_else (int arg);
+extern void s_elseif (int arg);
+extern void s_end (int arg);
+extern void s_endif (int arg);
+extern void s_err (int);
+extern void s_fail (int);
+extern void s_fill (int);
+extern void s_float_space (int mult);
+extern void s_func (int);
+extern void do_s_func (int, const char *);
+extern void s_globl (int arg);
+extern void s_if (int arg);
+extern void s_ifc (int arg);
+extern void s_ifdef (int arg);
+extern void s_ifeqs (int arg);
+extern void s_ignore (int arg);
+extern void s_include (int arg);
+extern void s_irp (int arg);
+extern void s_lcomm (int needs_align);
+extern void s_lcomm_bytes (int needs_align);
+extern void s_leb128 (int sign);
+extern void s_linkonce (int);
+extern void s_lsym (int);
+extern void s_macro (int);
+extern void s_mexit (int);
+extern void s_mri (int);
+extern void s_mri_common (int);
+extern void s_org (int);
+extern void s_print (int);
+extern void s_purgem (int);
+extern void s_rept (int);
+extern void s_set (int);
+extern void s_space (int mult);
+extern void s_stab (int what);
+extern void s_struct (int);
+extern void s_text (int);
+extern void stringer (int append_zero);
+extern void s_xstab (int what);
+extern void s_rva (int);
+extern void s_incbin (int);
diff --git a/x/binutils/gas/sb.c b/x/binutils/gas/sb.c
new file mode 100644
index 0000000..27b29ee
--- /dev/null
+++ b/x/binutils/gas/sb.c
@@ -0,0 +1,264 @@
+/* sb.c - string buffer manipulation routines
+ Copyright 1994, 1995, 2000 Free Software Foundation, Inc.
+
+ Written by Steve and Judy Chamberlain of Cygnus Support,
+ sac@cygnus.com
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "config.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include "libiberty.h"
+#include "sb.h"
+
+/* These routines are about manipulating strings.
+
+ They are managed in things called `sb's which is an abbreviation
+ for string buffers. An sb has to be created, things can be glued
+ on to it, and at the end of it's life it should be freed. The
+ contents should never be pointed at whilst it is still growing,
+ since it could be moved at any time
+
+ eg:
+ sb_new (&foo);
+ sb_grow... (&foo,...);
+ use foo->ptr[*];
+ sb_kill (&foo);
+
+*/
+
+#define dsize 5
+
+static void sb_check (sb *, int);
+
+/* Statistics of sb structures. */
+
+int string_count[sb_max_power_two];
+
+/* Free list of sb structures. */
+
+static sb_list_vector free_list;
+
+/* initializes an sb. */
+
+void
+sb_build (sb *ptr, int size)
+{
+ /* see if we can find one to allocate */
+ sb_element *e;
+
+ if (size > sb_max_power_two)
+ abort ();
+
+ e = free_list.size[size];
+ if (!e)
+ {
+ /* nothing there, allocate one and stick into the free list */
+ e = (sb_element *) xmalloc (sizeof (sb_element) + (1 << size));
+ e->next = free_list.size[size];
+ e->size = 1 << size;
+ free_list.size[size] = e;
+ string_count[size]++;
+ }
+
+ /* remove from free list */
+
+ free_list.size[size] = e->next;
+
+ /* copy into callers world */
+ ptr->ptr = e->data;
+ ptr->pot = size;
+ ptr->len = 0;
+ ptr->item = e;
+}
+
+void
+sb_new (sb *ptr)
+{
+ sb_build (ptr, dsize);
+}
+
+/* deallocate the sb at ptr */
+
+void
+sb_kill (sb *ptr)
+{
+ /* return item to free list */
+ ptr->item->next = free_list.size[ptr->pot];
+ free_list.size[ptr->pot] = ptr->item;
+}
+
+/* add the sb at s to the end of the sb at ptr */
+
+void
+sb_add_sb (sb *ptr, sb *s)
+{
+ sb_check (ptr, s->len);
+ memcpy (ptr->ptr + ptr->len, s->ptr, s->len);
+ ptr->len += s->len;
+}
+
+/* make sure that the sb at ptr has room for another len characters,
+ and grow it if it doesn't. */
+
+static void
+sb_check (sb *ptr, int len)
+{
+ if (ptr->len + len >= 1 << ptr->pot)
+ {
+ sb tmp;
+ int pot = ptr->pot;
+ while (ptr->len + len >= 1 << pot)
+ pot++;
+ sb_build (&tmp, pot);
+ sb_add_sb (&tmp, ptr);
+ sb_kill (ptr);
+ *ptr = tmp;
+ }
+}
+
+/* make the sb at ptr point back to the beginning. */
+
+void
+sb_reset (sb *ptr)
+{
+ ptr->len = 0;
+}
+
+/* add character c to the end of the sb at ptr. */
+
+void
+sb_add_char (sb *ptr, int c)
+{
+ sb_check (ptr, 1);
+ ptr->ptr[ptr->len++] = c;
+}
+
+/* add null terminated string s to the end of sb at ptr. */
+
+void
+sb_add_string (sb *ptr, const char *s)
+{
+ int len = strlen (s);
+ sb_check (ptr, len);
+ memcpy (ptr->ptr + ptr->len, s, len);
+ ptr->len += len;
+}
+
+/* add string at s of length len to sb at ptr */
+
+void
+sb_add_buffer (sb *ptr, const char *s, int len)
+{
+ sb_check (ptr, len);
+ memcpy (ptr->ptr + ptr->len, s, len);
+ ptr->len += len;
+}
+
+/* print the sb at ptr to the output file */
+
+void
+sb_print (FILE *outfile, sb *ptr)
+{
+ int i;
+ int nc = 0;
+
+ for (i = 0; i < ptr->len; i++)
+ {
+ if (nc)
+ {
+ fprintf (outfile, ",");
+ }
+ fprintf (outfile, "%d", ptr->ptr[i]);
+ nc = 1;
+ }
+}
+
+void
+sb_print_at (FILE *outfile, int idx, sb *ptr)
+{
+ int i;
+ for (i = idx; i < ptr->len; i++)
+ putc (ptr->ptr[i], outfile);
+}
+
+/* put a null at the end of the sb at in and return the start of the
+ string, so that it can be used as an arg to printf %s. */
+
+char *
+sb_name (sb *in)
+{
+ /* stick a null on the end of the string */
+ sb_add_char (in, 0);
+ return in->ptr;
+}
+
+/* like sb_name, but don't include the null byte in the string. */
+
+char *
+sb_terminate (sb *in)
+{
+ sb_add_char (in, 0);
+ --in->len;
+ return in->ptr;
+}
+
+/* start at the index idx into the string in sb at ptr and skip
+ whitespace. return the index of the first non whitespace character */
+
+int
+sb_skip_white (int idx, sb *ptr)
+{
+ while (idx < ptr->len
+ && (ptr->ptr[idx] == ' '
+ || ptr->ptr[idx] == '\t'))
+ idx++;
+ return idx;
+}
+
+/* start at the index idx into the sb at ptr. skips whitespace,
+ a comma and any following whitespace. returns the index of the
+ next character. */
+
+int
+sb_skip_comma (int idx, sb *ptr)
+{
+ while (idx < ptr->len
+ && (ptr->ptr[idx] == ' '
+ || ptr->ptr[idx] == '\t'))
+ idx++;
+
+ if (idx < ptr->len
+ && ptr->ptr[idx] == ',')
+ idx++;
+
+ while (idx < ptr->len
+ && (ptr->ptr[idx] == ' '
+ || ptr->ptr[idx] == '\t'))
+ idx++;
+
+ return idx;
+}
diff --git a/x/binutils/gas/sb.h b/x/binutils/gas/sb.h
new file mode 100644
index 0000000..30e5bc3
--- /dev/null
+++ b/x/binutils/gas/sb.h
@@ -0,0 +1,99 @@
+/* sb.h - header file for string buffer manipulation routines
+ Copyright 1994, 1995, 2000 Free Software Foundation, Inc.
+
+ Written by Steve and Judy Chamberlain of Cygnus Support,
+ sac@cygnus.com
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef SB_H
+
+#define SB_H
+
+#include <stdio.h>
+#include "ansidecl.h"
+
+/* string blocks
+
+ I had a couple of choices when deciding upon this data structure.
+ gas uses null terminated strings for all its internal work. This
+ often means that parts of the program that want to examine
+ substrings have to manipulate the data in the string to do the
+ right thing (a common operation is to single out a bit of text by
+ saving away the character after it, nulling it out, operating on
+ the substring and then replacing the character which was under the
+ null). This is a pain and I remember a load of problems that I had with
+ code in gas which almost got this right. Also, it's harder to grow and
+ allocate null terminated strings efficiently.
+
+ Obstacks provide all the functionality needed, but are too
+ complicated, hence the sb.
+
+ An sb is allocated by the caller, and is initialized to point to an
+ sb_element. sb_elements are kept on a free lists, and used when
+ needed, replaced onto the free list when unused.
+ */
+
+#define sb_max_power_two 30 /* don't allow strings more than
+ 2^sb_max_power_two long */
+/* structure of an sb */
+typedef struct sb
+ {
+ char *ptr; /* points to the current block. */
+ int len; /* how much is used. */
+ int pot; /* the maximum length is 1<<pot */
+ struct le *item;
+ }
+sb;
+
+/* Structure of the free list object of an sb */
+typedef struct le
+ {
+ struct le *next;
+ int size;
+ char data[1];
+ }
+sb_element;
+
+/* The free list */
+typedef struct
+ {
+ sb_element *size[sb_max_power_two];
+ } sb_list_vector;
+
+extern int string_count[sb_max_power_two];
+
+extern void sb_build (sb *, int);
+extern void sb_new (sb *);
+extern void sb_kill (sb *);
+extern void sb_add_sb (sb *, sb *);
+extern void sb_reset (sb *);
+extern void sb_add_char (sb *, int);
+extern void sb_add_string (sb *, const char *);
+extern void sb_add_buffer (sb *, const char *, int);
+extern void sb_print (FILE *, sb *);
+extern void sb_print_at (FILE *, int, sb *);
+extern char *sb_name (sb *);
+extern char *sb_terminate (sb *);
+extern int sb_skip_white (int, sb *);
+extern int sb_skip_comma (int, sb *);
+
+/* Actually in input-scrub.c. */
+extern void input_scrub_include_sb (sb *, char *, int);
+
+#endif /* SB_H */
diff --git a/x/binutils/gas/stabs.c b/x/binutils/gas/stabs.c
new file mode 100644
index 0000000..f8acdc8
--- /dev/null
+++ b/x/binutils/gas/stabs.c
@@ -0,0 +1,708 @@
+/* Generic stabs parsing for gas.
+ Copyright 1989, 1990, 1991, 1993, 1995, 1996, 1997, 1998, 2000, 2001
+ Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2,
+or (at your option) any later version.
+
+GAS is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "as.h"
+#include "obstack.h"
+#include "subsegs.h"
+#include "ecoff.h"
+
+/* We need this, despite the apparent object format dependency, since
+ it defines stab types, which all object formats can use now. */
+
+#include "aout/stab_gnu.h"
+
+/* Holds whether the assembler is generating stabs line debugging
+ information or not. Potentially used by md_cleanup function. */
+
+int outputting_stabs_line_debug = 0;
+
+static void s_stab_generic (int, char *, char *);
+static void generate_asm_file (int, char *);
+
+/* Allow backends to override the names used for the stab sections. */
+#ifndef STAB_SECTION_NAME
+#define STAB_SECTION_NAME ".stab"
+#endif
+
+#ifndef STAB_STRING_SECTION_NAME
+#define STAB_STRING_SECTION_NAME ".stabstr"
+#endif
+
+/* Non-zero if we're in the middle of a .func function, in which case
+ stabs_generate_asm_lineno emits function relative line number stabs.
+ Otherwise it emits line number stabs with absolute addresses. Note that
+ both cases only apply to assembler code assembled with -gstabs. */
+static int in_dot_func_p;
+
+/* Label at start of current function if in_dot_func_p != 0. */
+static const char *current_function_label;
+
+/*
+ * Handle .stabX directives, which used to be open-coded.
+ * So much creeping featurism overloaded the semantics that we decided
+ * to put all .stabX thinking in one place. Here.
+ *
+ * We try to make any .stabX directive legal. Other people's AS will often
+ * do assembly-time consistency checks: eg assigning meaning to n_type bits
+ * and "protecting" you from setting them to certain values. (They also zero
+ * certain bits before emitting symbols. Tut tut.)
+ *
+ * If an expression is not absolute we either gripe or use the relocation
+ * information. Other people's assemblers silently forget information they
+ * don't need and invent information they need that you didn't supply.
+ */
+
+/*
+ * Build a string dictionary entry for a .stabX symbol.
+ * The symbol is added to the .<secname>str section.
+ */
+
+#ifndef SEPARATE_STAB_SECTIONS
+#define SEPARATE_STAB_SECTIONS 0
+#endif
+
+unsigned int
+get_stab_string_offset (const char *string, const char *stabstr_secname)
+{
+ unsigned int length;
+ unsigned int retval;
+ segT save_seg;
+ subsegT save_subseg;
+ segT seg;
+ char *p;
+
+ if (! SEPARATE_STAB_SECTIONS)
+ abort ();
+
+ length = strlen (string);
+
+ save_seg = now_seg;
+ save_subseg = now_subseg;
+
+ /* Create the stab string section. */
+ seg = subseg_new (stabstr_secname, 0);
+
+ retval = seg_info (seg)->stabu.stab_string_size;
+ if (retval <= 0)
+ {
+ /* Make sure the first string is empty. */
+ p = frag_more (1);
+ *p = 0;
+ retval = seg_info (seg)->stabu.stab_string_size = 1;
+#ifdef BFD_ASSEMBLER
+ bfd_set_section_flags (stdoutput, seg, SEC_READONLY | SEC_DEBUGGING);
+ if (seg->name == stabstr_secname)
+ seg->name = xstrdup (stabstr_secname);
+#endif
+ }
+
+ if (length > 0)
+ { /* Ordinary case. */
+ p = frag_more (length + 1);
+ strcpy (p, string);
+
+ seg_info (seg)->stabu.stab_string_size += length + 1;
+ }
+ else
+ retval = 0;
+
+ subseg_set (save_seg, save_subseg);
+
+ return retval;
+}
+
+#ifdef AOUT_STABS
+#ifndef OBJ_PROCESS_STAB
+#define OBJ_PROCESS_STAB(SEG,W,S,T,O,D) aout_process_stab(W,S,T,O,D)
+#endif
+
+/* Here instead of obj-aout.c because other formats use it too. */
+void
+aout_process_stab (what, string, type, other, desc)
+ int what;
+ const char *string;
+ int type, other, desc;
+{
+ /* Put the stab information in the symbol table. */
+ symbolS *symbol;
+
+ /* Create the symbol now, but only insert it into the symbol chain
+ after any symbols mentioned in the value expression get into the
+ symbol chain. This is to avoid "continuation symbols" (where one
+ ends in "\" and the debug info is continued in the next .stabs
+ directive) from being separated by other random symbols. */
+ symbol = symbol_create (string, undefined_section, 0,
+ (struct frag *) NULL);
+ if (what == 's' || what == 'n')
+ {
+ /* Pick up the value from the input line. */
+ symbol_set_frag (symbol, &zero_address_frag);
+ pseudo_set (symbol);
+ }
+ else
+ {
+ /* .stabd sets the name to NULL. Why? */
+ S_SET_NAME (symbol, NULL);
+ symbol_set_frag (symbol, frag_now);
+ S_SET_VALUE (symbol, (valueT) frag_now_fix ());
+ }
+
+ symbol_append (symbol, symbol_lastP, &symbol_rootP, &symbol_lastP);
+
+ S_SET_TYPE (symbol, type);
+ S_SET_OTHER (symbol, other);
+ S_SET_DESC (symbol, desc);
+}
+#endif
+
+/* This can handle different kinds of stabs (s,n,d) and different
+ kinds of stab sections. */
+
+static void
+s_stab_generic (int what, char *stab_secname, char *stabstr_secname)
+{
+ long longint;
+ char *string, *saved_string_obstack_end;
+ int type;
+ int other;
+ int desc;
+
+ /* The general format is:
+ .stabs "STRING",TYPE,OTHER,DESC,VALUE
+ .stabn TYPE,OTHER,DESC,VALUE
+ .stabd TYPE,OTHER,DESC
+ At this point input_line_pointer points after the pseudo-op and
+ any trailing whitespace. The argument what is one of 's', 'n' or
+ 'd' indicating which type of .stab this is. */
+
+ if (what != 's')
+ {
+ string = "";
+ saved_string_obstack_end = 0;
+ }
+ else
+ {
+ int length;
+
+ string = demand_copy_C_string (&length);
+ /* FIXME: We should probably find some other temporary storage
+ for string, rather than leaking memory if someone else
+ happens to use the notes obstack. */
+ saved_string_obstack_end = notes.next_free;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ input_line_pointer++;
+ else
+ {
+ as_warn (_(".stab%c: missing comma"), what);
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+
+ if (get_absolute_expression_and_terminator (&longint) != ',')
+ {
+ as_warn (_(".stab%c: missing comma"), what);
+ ignore_rest_of_line ();
+ return;
+ }
+ type = longint;
+
+ if (get_absolute_expression_and_terminator (&longint) != ',')
+ {
+ as_warn (_(".stab%c: missing comma"), what);
+ ignore_rest_of_line ();
+ return;
+ }
+ other = longint;
+
+ desc = get_absolute_expression ();
+
+ if ((desc > 0xffff) || (desc < -0x8000))
+ /* This could happen for example with a source file with a huge
+ number of lines. The only cure is to use a different debug
+ format, probably DWARF. */
+ as_warn (_(".stab%c: description field '%x' too big, try a different debug format"),
+ what, desc);
+
+ if (what == 's' || what == 'n')
+ {
+ if (*input_line_pointer != ',')
+ {
+ as_warn (_(".stab%c: missing comma"), what);
+ ignore_rest_of_line ();
+ return;
+ }
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ }
+
+#ifdef TC_PPC
+#ifdef OBJ_ELF
+ /* Solaris on PowerPC has decided that .stabd can take 4 arguments, so if we were
+ given 4 arguments, make it a .stabn */
+ else if (what == 'd')
+ {
+ char *save_location = input_line_pointer;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ what = 'n';
+ }
+ else
+ input_line_pointer = save_location;
+ }
+#endif /* OBJ_ELF */
+#endif /* TC_PPC */
+
+#ifndef NO_LISTING
+ if (listing)
+ {
+ switch (type)
+ {
+ case N_SLINE:
+ listing_source_line ((unsigned int) desc);
+ break;
+ case N_SO:
+ case N_SOL:
+ listing_source_file (string);
+ break;
+ }
+ }
+#endif /* ! NO_LISTING */
+
+ /* We have now gathered the type, other, and desc information. For
+ .stabs or .stabn, input_line_pointer is now pointing at the
+ value. */
+
+ if (SEPARATE_STAB_SECTIONS)
+ /* Output the stab information in a separate section. This is used
+ at least for COFF and ELF. */
+ {
+ segT saved_seg = now_seg;
+ subsegT saved_subseg = now_subseg;
+ fragS *saved_frag = frag_now;
+ valueT dot;
+ segT seg;
+ unsigned int stroff;
+ char *p;
+
+ static segT cached_sec;
+ static char *cached_secname;
+
+ dot = frag_now_fix ();
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ if (cached_secname && !strcmp (cached_secname, stab_secname))
+ {
+ seg = cached_sec;
+ subseg_set (seg, 0);
+ }
+ else
+ {
+ seg = subseg_new (stab_secname, 0);
+ if (cached_secname)
+ free (cached_secname);
+ cached_secname = xstrdup (stab_secname);
+ cached_sec = seg;
+ }
+
+ if (! seg_info (seg)->hadone)
+ {
+#ifdef BFD_ASSEMBLER
+ bfd_set_section_flags (stdoutput, seg,
+ SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
+#endif
+#ifdef INIT_STAB_SECTION
+ INIT_STAB_SECTION (seg);
+#endif
+ seg_info (seg)->hadone = 1;
+ }
+
+ stroff = get_stab_string_offset (string, stabstr_secname);
+ if (what == 's')
+ {
+ /* Release the string, if nobody else has used the obstack. */
+ if (saved_string_obstack_end == notes.next_free)
+ obstack_free (&notes, string);
+ }
+
+ /* At least for now, stabs in a special stab section are always
+ output as 12 byte blocks of information. */
+ p = frag_more (8);
+ md_number_to_chars (p, (valueT) stroff, 4);
+ md_number_to_chars (p + 4, (valueT) type, 1);
+ md_number_to_chars (p + 5, (valueT) other, 1);
+ md_number_to_chars (p + 6, (valueT) desc, 2);
+
+ if (what == 's' || what == 'n')
+ {
+ /* Pick up the value from the input line. */
+ cons (4);
+ input_line_pointer--;
+ }
+ else
+ {
+ symbolS *symbol;
+ expressionS exp;
+
+ /* Arrange for a value representing the current location. */
+ symbol = symbol_temp_new (saved_seg, dot, saved_frag);
+
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = symbol;
+ exp.X_add_number = 0;
+
+ emit_expr (&exp, 4);
+ }
+
+#ifdef OBJ_PROCESS_STAB
+ OBJ_PROCESS_STAB (seg, what, string, type, other, desc);
+#endif
+
+ subseg_set (saved_seg, saved_subseg);
+ }
+ else
+ {
+#ifdef OBJ_PROCESS_STAB
+ OBJ_PROCESS_STAB (0, what, string, type, other, desc);
+#else
+ abort ();
+#endif
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Regular stab directive. */
+
+void
+s_stab (int what)
+{
+ s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME);
+}
+
+/* "Extended stabs", used in Solaris only now. */
+
+void
+s_xstab (int what)
+{
+ int length;
+ char *stab_secname, *stabstr_secname;
+ static char *saved_secname, *saved_strsecname;
+
+ /* @@ MEMORY LEAK: This allocates a copy of the string, but in most
+ cases it will be the same string, so we could release the storage
+ back to the obstack it came from. */
+ stab_secname = demand_copy_C_string (&length);
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ input_line_pointer++;
+ else
+ {
+ as_bad (_("comma missing in .xstabs"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ /* To get the name of the stab string section, simply add "str" to
+ the stab section name. */
+ if (saved_secname == 0 || strcmp (saved_secname, stab_secname))
+ {
+ stabstr_secname = (char *) xmalloc (strlen (stab_secname) + 4);
+ strcpy (stabstr_secname, stab_secname);
+ strcat (stabstr_secname, "str");
+ if (saved_secname)
+ {
+ free (saved_secname);
+ free (saved_strsecname);
+ }
+ saved_secname = stab_secname;
+ saved_strsecname = stabstr_secname;
+ }
+ s_stab_generic (what, saved_secname, saved_strsecname);
+}
+
+#ifdef S_SET_DESC
+
+/* Frob invented at RMS' request. Set the n_desc of a symbol. */
+
+void
+s_desc (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ char *name;
+ char c;
+ char *p;
+ symbolS *symbolP;
+ int temp;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ *p = 0;
+ as_bad (_("expected comma after \"%s\""), name);
+ *p = c;
+ ignore_rest_of_line ();
+ }
+ else
+ {
+ input_line_pointer++;
+ temp = get_absolute_expression ();
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+ S_SET_DESC (symbolP, temp);
+ }
+ demand_empty_rest_of_line ();
+} /* s_desc() */
+
+#endif /* defined (S_SET_DESC) */
+
+/* Generate stabs debugging information to denote the main source file. */
+
+void
+stabs_generate_asm_file (void)
+{
+ char *file;
+ unsigned int lineno;
+
+ as_where (&file, &lineno);
+ if (use_gnu_debug_info_extensions)
+ {
+ char *dir, *dir2;
+
+ dir = getpwd ();
+ dir2 = alloca (strlen (dir) + 2);
+ sprintf (dir2, "%s%s", dir, "/");
+ generate_asm_file (N_SO, dir2);
+ }
+ generate_asm_file (N_SO, file);
+}
+
+/* Generate stabs debugging information to denote the source file.
+ TYPE is one of N_SO, N_SOL. */
+
+static void
+generate_asm_file (int type, char *file)
+{
+ static char *last_file;
+ static int label_count;
+ char *hold;
+ char sym[30];
+ char *buf;
+ char *tmp = file;
+ char *endp = file + strlen (file);
+ char *bufp;
+
+ if (last_file != NULL
+ && strcmp (last_file, file) == 0)
+ return;
+
+ /* Rather than try to do this in some efficient fashion, we just
+ generate a string and then parse it again. That lets us use the
+ existing stabs hook, which expect to see a string, rather than
+ inventing new ones. */
+ hold = input_line_pointer;
+
+ sprintf (sym, "%sF%d", FAKE_LABEL_NAME, label_count);
+ ++label_count;
+
+ /* Allocate enough space for the file name (possibly extended with
+ doubled up backslashes), the symbol name, and the other characters
+ that make up a stabs file directive. */
+ bufp = buf = xmalloc (2 * strlen (file) + strlen (sym) + 12);
+
+ *bufp++ = '"';
+
+ while (tmp < endp)
+ {
+ char *bslash = strchr (tmp, '\\');
+ size_t len = (bslash) ? (size_t) (bslash - tmp + 1) : strlen (tmp);
+
+ /* Double all backslashes, since demand_copy_C_string (used by
+ s_stab to extract the part in quotes) will try to replace them as
+ escape sequences. backslash may appear in a filespec. */
+ strncpy (bufp, tmp, len);
+
+ tmp += len;
+ bufp += len;
+
+ if (bslash != NULL)
+ *bufp++ = '\\';
+ }
+
+ sprintf (bufp, "\",%d,0,0,%s\n", type, sym);
+
+ input_line_pointer = buf;
+ s_stab ('s');
+ colon (sym);
+
+ if (last_file != NULL)
+ free (last_file);
+ last_file = xstrdup (file);
+
+ free (buf);
+
+ input_line_pointer = hold;
+}
+
+/* Generate stabs debugging information for the current line. This is
+ used to produce debugging information for an assembler file. */
+
+void
+stabs_generate_asm_lineno (void)
+{
+ static int label_count;
+ char *hold;
+ char *file;
+ unsigned int lineno;
+ char *buf;
+ char sym[30];
+ /* Remember the last file/line and avoid duplicates. */
+ static unsigned int prev_lineno = -1;
+ static char *prev_file = NULL;
+
+ /* Rather than try to do this in some efficient fashion, we just
+ generate a string and then parse it again. That lets us use the
+ existing stabs hook, which expect to see a string, rather than
+ inventing new ones. */
+
+ hold = input_line_pointer;
+
+ as_where (&file, &lineno);
+
+ /* Don't emit sequences of stabs for the same line. */
+ if (prev_file == NULL)
+ {
+ /* First time thru. */
+ prev_file = xstrdup (file);
+ prev_lineno = lineno;
+ }
+ else if (lineno == prev_lineno
+ && strcmp (file, prev_file) == 0)
+ {
+ /* Same file/line as last time. */
+ return;
+ }
+ else
+ {
+ /* Remember file/line for next time. */
+ prev_lineno = lineno;
+ if (strcmp (file, prev_file) != 0)
+ {
+ free (prev_file);
+ prev_file = xstrdup (file);
+ }
+ }
+
+ /* Let the world know that we are in the middle of generating a
+ piece of stabs line debugging information. */
+ outputting_stabs_line_debug = 1;
+
+ generate_asm_file (N_SOL, file);
+
+ sprintf (sym, "%sL%d", FAKE_LABEL_NAME, label_count);
+ ++label_count;
+
+ if (in_dot_func_p)
+ {
+ buf = (char *) alloca (100 + strlen (current_function_label));
+ sprintf (buf, "%d,0,%d,%s-%s\n", N_SLINE, lineno,
+ sym, current_function_label);
+ }
+ else
+ {
+ buf = (char *) alloca (100);
+ sprintf (buf, "%d,0,%d,%s\n", N_SLINE, lineno, sym);
+ }
+ input_line_pointer = buf;
+ s_stab ('n');
+ colon (sym);
+
+ input_line_pointer = hold;
+ outputting_stabs_line_debug = 0;
+}
+
+/* Emit a function stab.
+ All assembler functions are assumed to have return type `void'. */
+
+void
+stabs_generate_asm_func (const char *funcname, const char *startlabname)
+{
+ static int void_emitted_p;
+ char *hold = input_line_pointer;
+ char *buf;
+ char *file;
+ unsigned int lineno;
+
+ if (! void_emitted_p)
+ {
+ input_line_pointer = "\"void:t1=1\",128,0,0,0";
+ s_stab ('s');
+ void_emitted_p = 1;
+ }
+
+ as_where (&file, &lineno);
+ asprintf (&buf, "\"%s:F1\",%d,0,%d,%s",
+ funcname, N_FUN, lineno + 1, startlabname);
+ input_line_pointer = buf;
+ s_stab ('s');
+ free (buf);
+
+ input_line_pointer = hold;
+ current_function_label = xstrdup (startlabname);
+ in_dot_func_p = 1;
+}
+
+/* Emit a stab to record the end of a function. */
+
+void
+stabs_generate_asm_endfunc (const char *funcname ATTRIBUTE_UNUSED,
+ const char *startlabname)
+{
+ static int label_count;
+ char *hold = input_line_pointer;
+ char *buf;
+ char sym[30];
+
+ sprintf (sym, "%sendfunc%d", FAKE_LABEL_NAME, label_count);
+ ++label_count;
+ colon (sym);
+
+ asprintf (&buf, "\"\",%d,0,0,%s-%s", N_FUN, sym, startlabname);
+ input_line_pointer = buf;
+ s_stab ('s');
+ free (buf);
+
+ input_line_pointer = hold;
+ in_dot_func_p = 0;
+ current_function_label = NULL;
+}
diff --git a/x/binutils/gas/stamp-h.in b/x/binutils/gas/stamp-h.in
new file mode 100644
index 0000000..9788f70
--- /dev/null
+++ b/x/binutils/gas/stamp-h.in
@@ -0,0 +1 @@
+timestamp
diff --git a/x/binutils/gas/struc-symbol.h b/x/binutils/gas/struc-symbol.h
new file mode 100644
index 0000000..90945c4
--- /dev/null
+++ b/x/binutils/gas/struc-symbol.h
@@ -0,0 +1,159 @@
+/* struct_symbol.h - Internal symbol structure
+ Copyright 1987, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef __struc_symbol_h__
+#define __struc_symbol_h__
+
+#ifdef BFD_ASSEMBLER
+/* The BFD code wants to walk the list in both directions. */
+#undef SYMBOLS_NEED_BACKPOINTERS
+#define SYMBOLS_NEED_BACKPOINTERS
+#endif
+
+/* The information we keep for a symbol. Note that the symbol table
+ holds pointers both to this and to local_symbol structures. See
+ below. */
+
+struct symbol
+{
+#ifdef BFD_ASSEMBLER
+ /* BFD symbol */
+ asymbol *bsym;
+#else
+ /* The (4-origin) position of sy_name in the symbol table of the object
+ file. This will be 0 for (nameless) .stabd symbols.
+
+ Not used until write_object_file() time. */
+ unsigned long sy_name_offset;
+
+ /* What we write in .o file (if permitted). */
+ obj_symbol_type sy_symbol;
+
+ /* The 24 bit symbol number. Symbol numbers start at 0 and are unsigned. */
+ long sy_number;
+#endif
+
+ /* The value of the symbol. */
+ expressionS sy_value;
+
+ /* Forwards and (optionally) backwards chain pointers. */
+ struct symbol *sy_next;
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+ struct symbol *sy_previous;
+#endif /* SYMBOLS_NEED_BACKPOINTERS */
+
+ /* Pointer to the frag this symbol is attached to, if any.
+ Otherwise, NULL. */
+ struct frag *sy_frag;
+
+ unsigned int written : 1;
+ /* Whether symbol value has been completely resolved (used during
+ final pass over symbol table). */
+ unsigned int sy_resolved : 1;
+ /* Whether the symbol value is currently being resolved (used to
+ detect loops in symbol dependencies). */
+ unsigned int sy_resolving : 1;
+ /* Whether the symbol value is used in a reloc. This is used to
+ ensure that symbols used in relocs are written out, even if they
+ are local and would otherwise not be. */
+ unsigned int sy_used_in_reloc : 1;
+
+ /* Whether the symbol is used as an operand or in an expression.
+ NOTE: Not all the backends keep this information accurate;
+ backends which use this bit are responsible for setting it when
+ a symbol is used in backend routines. */
+ unsigned int sy_used : 1;
+
+ /* This is set if the symbol is defined in an MRI common section.
+ We handle such sections as single common symbols, so symbols
+ defined within them must be treated specially by the relocation
+ routines. */
+ unsigned int sy_mri_common : 1;
+
+#ifdef OBJ_SYMFIELD_TYPE
+ OBJ_SYMFIELD_TYPE sy_obj;
+#endif
+
+#ifdef TC_SYMFIELD_TYPE
+ TC_SYMFIELD_TYPE sy_tc;
+#endif
+
+#ifdef TARGET_SYMBOL_FIELDS
+ TARGET_SYMBOL_FIELDS
+#endif
+};
+
+#ifdef BFD_ASSEMBLER
+
+/* A pointer in the symbol may point to either a complete symbol
+ (struct symbol above) or to a local symbol (struct local_symbol
+ defined here). The symbol code can detect the case by examining
+ the first field. It is always NULL for a local symbol.
+
+ We do this because we ordinarily only need a small amount of
+ information for a local symbol. The symbol table takes up a lot of
+ space, and storing less information for a local symbol can make a
+ big difference in assembler memory usage when assembling a large
+ file. */
+
+struct local_symbol
+{
+ /* This pointer is always NULL to indicate that this is a local
+ symbol. */
+ asymbol *lsy_marker;
+
+ /* The symbol section. This also serves as a flag. If this is
+ reg_section, then this symbol has been converted into a regular
+ symbol, and lsy_sym points to it. */
+ segT lsy_section;
+
+ /* The symbol name. */
+ const char *lsy_name;
+
+ /* The symbol frag or the real symbol, depending upon the value in
+ lsy_section. If the symbol has been fully resolved, lsy_frag is
+ set to NULL. */
+ union
+ {
+ fragS *lsy_frag;
+ symbolS *lsy_sym;
+ } u;
+
+ /* The value of the symbol. */
+ valueT lsy_value;
+
+#ifdef TC_LOCAL_SYMFIELD_TYPE
+ TC_LOCAL_SYMFIELD_TYPE lsy_tc;
+#endif
+};
+
+#define local_symbol_converted_p(l) ((l)->lsy_section == reg_section)
+#define local_symbol_mark_converted(l) ((l)->lsy_section = reg_section)
+#define local_symbol_resolved_p(l) ((l)->u.lsy_frag == NULL)
+#define local_symbol_mark_resolved(l) ((l)->u.lsy_frag = NULL)
+#define local_symbol_get_frag(l) ((l)->u.lsy_frag)
+#define local_symbol_set_frag(l, f) ((l)->u.lsy_frag = (f))
+#define local_symbol_get_real_symbol(l) ((l)->u.lsy_sym)
+#define local_symbol_set_real_symbol(l, s) ((l)->u.lsy_sym = (s))
+
+#endif /* BFD_ASSEMBLER */
+
+#endif /* __struc_symbol_h__ */
diff --git a/x/binutils/gas/subsegs.c b/x/binutils/gas/subsegs.c
new file mode 100644
index 0000000..b2432e9
--- /dev/null
+++ b/x/binutils/gas/subsegs.c
@@ -0,0 +1,646 @@
+/* subsegs.c - subsegments -
+ Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Segments & sub-segments. */
+
+#include "as.h"
+
+#include "subsegs.h"
+#include "obstack.h"
+
+frchainS *frchain_root, *frchain_now;
+
+static struct obstack frchains;
+
+#ifndef BFD_ASSEMBLER
+#ifdef MANY_SEGMENTS
+segment_info_type segment_info[SEG_MAXIMUM_ORDINAL];
+
+#else
+/* Commented in "subsegs.h". */
+frchainS *data0_frchainP, *bss0_frchainP;
+
+#endif /* MANY_SEGMENTS */
+char const *const seg_name[] = {
+ "absolute",
+#ifdef MANY_SEGMENTS
+ "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9",
+ "e10", "e11", "e12", "e13", "e14", "e15", "e16", "e17", "e18", "e19",
+ "e20", "e21", "e22", "e23", "e24", "e25", "e26", "e27", "e28", "e29",
+ "e30", "e31", "e32", "e33", "e34", "e35", "e36", "e37", "e38", "e39",
+#else
+ "text",
+ "data",
+ "bss",
+#endif /* MANY_SEGMENTS */
+ "unknown",
+ "ASSEMBLER-INTERNAL-LOGIC-ERROR!",
+ "expr",
+ "debug",
+ "transfert vector preload",
+ "transfert vector postload",
+ "register",
+ "",
+}; /* Used by error reporters, dumpers etc. */
+#else /* BFD_ASSEMBLER */
+
+/* Gas segment information for bfd_abs_section_ptr and
+ bfd_und_section_ptr. */
+static segment_info_type *abs_seg_info;
+static segment_info_type *und_seg_info;
+
+#endif /* BFD_ASSEMBLER */
+
+static void subseg_set_rest (segT, subsegT);
+
+static fragS dummy_frag;
+
+static frchainS absolute_frchain;
+
+void
+subsegs_begin (void)
+{
+ /* Check table(s) seg_name[], seg_N_TYPE[] is in correct order */
+#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
+ know (SEG_ABSOLUTE == 0);
+ know (SEG_TEXT == 1);
+ know (SEG_DATA == 2);
+ know (SEG_BSS == 3);
+ know (SEG_UNKNOWN == 4);
+ know (SEG_GOOF == 5);
+ know (SEG_EXPR == 6);
+ know (SEG_DEBUG == 7);
+ know (SEG_NTV == 8);
+ know (SEG_PTV == 9);
+ know (SEG_REGISTER == 10);
+ know (SEG_MAXIMUM_ORDINAL == SEG_REGISTER);
+#endif
+
+ obstack_begin (&frchains, chunksize);
+#if __GNUC__ >= 2
+ obstack_alignment_mask (&frchains) = __alignof__ (frchainS) - 1;
+#endif
+
+ frchain_root = NULL;
+ frchain_now = NULL; /* Warn new_subseg() that we are booting. */
+
+ frag_now = &dummy_frag;
+
+#ifndef BFD_ASSEMBLER
+ now_subseg = 42; /* Lie for 1st call to subseg_new. */
+#ifdef MANY_SEGMENTS
+ {
+ int i;
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ subseg_set (i, 0);
+ segment_info[i].frchainP = frchain_now;
+ }
+ }
+#else
+ subseg_set (SEG_DATA, 0); /* .data 0 */
+ data0_frchainP = frchain_now;
+
+ subseg_set (SEG_BSS, 0);
+ bss0_frchainP = frchain_now;
+
+#endif /* ! MANY_SEGMENTS */
+#endif /* ! BFD_ASSEMBLER */
+
+ absolute_frchain.frch_seg = absolute_section;
+ absolute_frchain.frch_subseg = 0;
+#ifdef BFD_ASSEMBLER
+ absolute_frchain.fix_root = absolute_frchain.fix_tail = 0;
+#endif
+ absolute_frchain.frch_frag_now = &zero_address_frag;
+ absolute_frchain.frch_root = absolute_frchain.frch_last = &zero_address_frag;
+}
+
+/*
+ * subseg_change()
+ *
+ * Change the subsegment we are in, BUT DO NOT MAKE A NEW FRAG for the
+ * subsegment. If we are already in the correct subsegment, change nothing.
+ * This is used eg as a worker for subseg_set [which does make a new frag_now]
+ * and for changing segments after we have read the source. We construct eg
+ * fixSs even after the source file is read, so we do have to keep the
+ * segment context correct.
+ */
+void
+subseg_change (register segT seg, register int subseg)
+{
+ now_seg = seg;
+ now_subseg = subseg;
+
+ if (now_seg == absolute_section)
+ return;
+
+#ifdef BFD_ASSEMBLER
+ {
+ segment_info_type *seginfo;
+ seginfo = (segment_info_type *) bfd_get_section_userdata (stdoutput, seg);
+ if (! seginfo)
+ {
+ seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
+ memset ((PTR) seginfo, 0, sizeof (*seginfo));
+ seginfo->fix_root = NULL;
+ seginfo->fix_tail = NULL;
+ seginfo->bfd_section = seg;
+ seginfo->sym = 0;
+ if (seg == bfd_abs_section_ptr)
+ abs_seg_info = seginfo;
+ else if (seg == bfd_und_section_ptr)
+ und_seg_info = seginfo;
+ else
+ bfd_set_section_userdata (stdoutput, seg, (PTR) seginfo);
+ }
+ }
+#else
+#ifdef MANY_SEGMENTS
+ seg_fix_rootP = &segment_info[seg].fix_root;
+ seg_fix_tailP = &segment_info[seg].fix_tail;
+#else
+ if (seg == SEG_DATA)
+ {
+ seg_fix_rootP = &data_fix_root;
+ seg_fix_tailP = &data_fix_tail;
+ }
+ else if (seg == SEG_TEXT)
+ {
+ seg_fix_rootP = &text_fix_root;
+ seg_fix_tailP = &text_fix_tail;
+ }
+ else
+ {
+ know (seg == SEG_BSS);
+ seg_fix_rootP = &bss_fix_root;
+ seg_fix_tailP = &bss_fix_tail;
+ }
+
+#endif
+#endif
+}
+
+static void
+subseg_set_rest (segT seg, subsegT subseg)
+{
+ register frchainS *frcP; /* crawl frchain chain */
+ register frchainS **lastPP; /* address of last pointer */
+ frchainS *newP; /* address of new frchain */
+
+ mri_common_symbol = NULL;
+
+ if (frag_now && frchain_now)
+ frchain_now->frch_frag_now = frag_now;
+
+ assert (frchain_now == 0
+ || now_seg == undefined_section
+ || now_seg == absolute_section
+ || frchain_now->frch_last == frag_now);
+
+ subseg_change (seg, (int) subseg);
+
+ if (seg == absolute_section)
+ {
+ frchain_now = &absolute_frchain;
+ frag_now = &zero_address_frag;
+ return;
+ }
+
+ assert (frchain_now == 0
+ || now_seg == undefined_section
+ || frchain_now->frch_last == frag_now);
+
+ /*
+ * Attempt to find or make a frchain for that sub seg.
+ * Crawl along chain of frchainSs, begins @ frchain_root.
+ * If we need to make a frchainS, link it into correct
+ * position of chain rooted in frchain_root.
+ */
+ for (frcP = *(lastPP = &frchain_root);
+ frcP && frcP->frch_seg <= seg;
+ frcP = *(lastPP = &frcP->frch_next))
+ {
+ if (frcP->frch_seg == seg
+ && frcP->frch_subseg >= subseg)
+ {
+ break;
+ }
+ }
+ /*
+ * frcP: Address of the 1st frchainS in correct segment with
+ * frch_subseg >= subseg.
+ * We want to either use this frchainS, or we want
+ * to insert a new frchainS just before it.
+ *
+ * If frcP==NULL, then we are at the end of the chain
+ * of frchainS-s. A NULL frcP means we fell off the end
+ * of the chain looking for a
+ * frch_subseg >= subseg, so we
+ * must make a new frchainS.
+ *
+ * If we ever maintain a pointer to
+ * the last frchainS in the chain, we change that pointer
+ * ONLY when frcP==NULL.
+ *
+ * lastPP: Address of the pointer with value frcP;
+ * Never NULL.
+ * May point to frchain_root.
+ *
+ */
+ if (!frcP
+ || (frcP->frch_seg > seg
+ || frcP->frch_subseg > subseg)) /* Kinky logic only works with 2 segments. */
+ {
+ /*
+ * This should be the only code that creates a frchainS.
+ */
+ newP = (frchainS *) obstack_alloc (&frchains, sizeof (frchainS));
+ newP->frch_subseg = subseg;
+ newP->frch_seg = seg;
+#ifdef BFD_ASSEMBLER
+ newP->fix_root = NULL;
+ newP->fix_tail = NULL;
+#endif
+ obstack_begin (&newP->frch_obstack, chunksize);
+#if __GNUC__ >= 2
+ obstack_alignment_mask (&newP->frch_obstack) = __alignof__ (fragS) - 1;
+#endif
+ newP->frch_frag_now = frag_alloc (&newP->frch_obstack);
+ newP->frch_frag_now->fr_type = rs_fill;
+
+ newP->frch_root = newP->frch_last = newP->frch_frag_now;
+
+ *lastPP = newP;
+ newP->frch_next = frcP; /* perhaps NULL */
+
+#ifdef BFD_ASSEMBLER
+ {
+ segment_info_type *seginfo;
+ seginfo = seg_info (seg);
+ if (seginfo && seginfo->frchainP == frcP)
+ seginfo->frchainP = newP;
+ }
+#endif
+
+ frcP = newP;
+ }
+ /*
+ * Here with frcP pointing to the frchainS for subseg.
+ */
+ frchain_now = frcP;
+ frag_now = frcP->frch_frag_now;
+
+ assert (frchain_now->frch_last == frag_now);
+}
+
+/*
+ * subseg_set(segT, subsegT)
+ *
+ * If you attempt to change to the current subsegment, nothing happens.
+ *
+ * In: segT, subsegT code for new subsegment.
+ * frag_now -> incomplete frag for current subsegment.
+ * If frag_now==NULL, then there is no old, incomplete frag, so
+ * the old frag is not closed off.
+ *
+ * Out: now_subseg, now_seg updated.
+ * Frchain_now points to the (possibly new) struct frchain for this
+ * sub-segment.
+ * Frchain_root updated if needed.
+ */
+
+#ifndef BFD_ASSEMBLER
+
+segT
+subseg_new (segname, subseg)
+ const char *segname;
+ subsegT subseg;
+{
+ int i;
+
+ for (i = 0; i < (int) SEG_MAXIMUM_ORDINAL; i++)
+ {
+ const char *s;
+
+ s = segment_name ((segT) i);
+ if (strcmp (segname, s) == 0
+ || (segname[0] == '.'
+ && strcmp (segname + 1, s) == 0))
+ {
+ subseg_set ((segT) i, subseg);
+ return (segT) i;
+ }
+#ifdef obj_segment_name
+ s = obj_segment_name ((segT) i);
+ if (strcmp (segname, s) == 0
+ || (segname[0] == '.'
+ && strcmp (segname + 1, s) == 0))
+ {
+ subseg_set ((segT) i, subseg);
+ return (segT) i;
+ }
+#endif
+ }
+
+#ifdef obj_add_segment
+ {
+ segT new_seg;
+ new_seg = obj_add_segment (segname);
+ subseg_set (new_seg, subseg);
+ return new_seg;
+ }
+#else
+ as_bad (_("attempt to switch to nonexistent segment \"%s\""), segname);
+ return now_seg;
+#endif
+}
+
+void
+subseg_set (seg, subseg) /* begin assembly for a new sub-segment */
+ register segT seg; /* SEG_DATA or SEG_TEXT */
+ register subsegT subseg;
+{
+#ifndef MANY_SEGMENTS
+ know (seg == SEG_DATA
+ || seg == SEG_TEXT
+ || seg == SEG_BSS
+ || seg == SEG_ABSOLUTE);
+#endif
+
+ if (seg != now_seg || subseg != now_subseg)
+ { /* we just changed sub-segments */
+ subseg_set_rest (seg, subseg);
+ }
+ mri_common_symbol = NULL;
+}
+
+#else /* BFD_ASSEMBLER */
+
+segT
+subseg_get (const char *segname, int force_new)
+{
+ segT secptr;
+ segment_info_type *seginfo;
+ const char *now_seg_name = (now_seg
+ ? bfd_get_section_name (stdoutput, now_seg)
+ : 0);
+
+ if (!force_new
+ && now_seg_name
+ && (now_seg_name == segname
+ || !strcmp (now_seg_name, segname)))
+ return now_seg;
+
+ if (!force_new)
+ secptr = bfd_make_section_old_way (stdoutput, segname);
+ else
+ secptr = bfd_make_section_anyway (stdoutput, segname);
+
+#ifdef obj_sec_set_private_data
+ obj_sec_set_private_data (stdoutput, secptr);
+#endif
+
+ seginfo = seg_info (secptr);
+ if (! seginfo)
+ {
+ /* Check whether output_section is set first because secptr may
+ be bfd_abs_section_ptr. */
+ if (secptr->output_section != secptr)
+ secptr->output_section = secptr;
+ seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
+ memset ((PTR) seginfo, 0, sizeof (*seginfo));
+ seginfo->fix_root = NULL;
+ seginfo->fix_tail = NULL;
+ seginfo->bfd_section = secptr;
+ if (secptr == bfd_abs_section_ptr)
+ abs_seg_info = seginfo;
+ else if (secptr == bfd_und_section_ptr)
+ und_seg_info = seginfo;
+ else
+ bfd_set_section_userdata (stdoutput, secptr, (PTR) seginfo);
+ seginfo->frchainP = NULL;
+ seginfo->lineno_list_head = seginfo->lineno_list_tail = NULL;
+ seginfo->sym = NULL;
+ seginfo->dot = NULL;
+ }
+ return secptr;
+}
+
+segT
+subseg_new (const char *segname, subsegT subseg)
+{
+ segT secptr;
+ segment_info_type *seginfo;
+
+ secptr = subseg_get (segname, 0);
+ subseg_set_rest (secptr, subseg);
+ seginfo = seg_info (secptr);
+ if (! seginfo->frchainP)
+ seginfo->frchainP = frchain_now;
+ return secptr;
+}
+
+/* Like subseg_new, except a new section is always created, even if
+ a section with that name already exists. */
+segT
+subseg_force_new (const char *segname, subsegT subseg)
+{
+ segT secptr;
+ segment_info_type *seginfo;
+
+ secptr = subseg_get (segname, 1);
+ subseg_set_rest (secptr, subseg);
+ seginfo = seg_info (secptr);
+ if (! seginfo->frchainP)
+ seginfo->frchainP = frchain_now;
+ return secptr;
+}
+
+void
+subseg_set (segT secptr, subsegT subseg)
+{
+ if (! (secptr == now_seg && subseg == now_subseg))
+ subseg_set_rest (secptr, subseg);
+ mri_common_symbol = NULL;
+}
+
+#ifndef obj_sec_sym_ok_for_reloc
+#define obj_sec_sym_ok_for_reloc(SEC) 0
+#endif
+
+/* Get the gas information we are storing for a section. */
+
+segment_info_type *
+seg_info (segT sec)
+{
+ if (sec == bfd_abs_section_ptr)
+ return abs_seg_info;
+ else if (sec == bfd_und_section_ptr)
+ return und_seg_info;
+ else
+ return (segment_info_type *) bfd_get_section_userdata (stdoutput, sec);
+}
+
+symbolS *
+section_symbol (segT sec)
+{
+ segment_info_type *seginfo = seg_info (sec);
+ symbolS *s;
+
+ if (seginfo == 0)
+ abort ();
+ if (seginfo->sym)
+ return seginfo->sym;
+
+#ifndef EMIT_SECTION_SYMBOLS
+#define EMIT_SECTION_SYMBOLS 1
+#endif
+
+ if (! EMIT_SECTION_SYMBOLS || symbol_table_frozen)
+ {
+ /* Here we know it won't be going into the symbol table. */
+ s = symbol_create (sec->symbol->name, sec, 0, &zero_address_frag);
+ }
+ else
+ {
+ s = symbol_find_base (sec->symbol->name, 0);
+ if (s == NULL)
+ s = symbol_new (sec->symbol->name, sec, 0, &zero_address_frag);
+ else
+ {
+ if (S_GET_SEGMENT (s) == undefined_section)
+ {
+ S_SET_SEGMENT (s, sec);
+ symbol_set_frag (s, &zero_address_frag);
+ }
+ }
+ }
+
+ S_CLEAR_EXTERNAL (s);
+
+ /* Use the BFD section symbol, if possible. */
+ if (obj_sec_sym_ok_for_reloc (sec))
+ symbol_set_bfdsym (s, sec->symbol);
+ else
+ symbol_get_bfdsym (s)->flags |= BSF_SECTION_SYM;
+
+ seginfo->sym = s;
+ return s;
+}
+
+#endif /* BFD_ASSEMBLER */
+
+/* Return whether the specified segment is thought to hold text. */
+
+#ifndef BFD_ASSEMBLER
+const char * const nontext_section_names[] = {
+ ".eh_frame",
+ ".gcc_except_table",
+#ifdef OBJ_COFF
+#ifndef COFF_LONG_SECTION_NAMES
+ ".eh_fram",
+ ".gcc_exc",
+#endif
+#endif
+ NULL
+};
+#endif /* ! BFD_ASSEMBLER */
+
+int
+subseg_text_p (segT sec)
+{
+#ifdef BFD_ASSEMBLER
+ return (bfd_get_section_flags (stdoutput, sec) & SEC_CODE) != 0;
+#else /* ! BFD_ASSEMBLER */
+ const char * const *p;
+
+ if (sec == data_section || sec == bss_section || sec == absolute_section)
+ return 0;
+
+ for (p = nontext_section_names; *p != NULL; ++p)
+ {
+ if (strcmp (segment_name (sec), *p) == 0)
+ return 0;
+
+#ifdef obj_segment_name
+ if (strcmp (obj_segment_name (sec), *p) == 0)
+ return 0;
+#endif
+ }
+
+ return 1;
+
+#endif /* ! BFD_ASSEMBLER */
+}
+
+void
+subsegs_print_statistics (FILE *file)
+{
+ frchainS *frchp;
+ fprintf (file, "frag chains:\n");
+ for (frchp = frchain_root; frchp; frchp = frchp->frch_next)
+ {
+ int count = 0;
+ fragS *fragp;
+
+ /* If frch_subseg is non-zero, it's probably been chained onto
+ the end of a previous subsection. Don't count it again. */
+ if (frchp->frch_subseg != 0)
+ continue;
+
+ /* Skip gas-internal sections. */
+ if (segment_name (frchp->frch_seg)[0] == '*')
+ continue;
+
+ for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
+ {
+#if 0
+ switch (fragp->fr_type)
+ {
+ case rs_fill:
+ fprintf (file, "f"); break;
+ case rs_align:
+ fprintf (file, "a"); break;
+ case rs_align_code:
+ fprintf (file, "c"); break;
+ case rs_org:
+ fprintf (file, "o"); break;
+ case rs_machine_dependent:
+ fprintf (file, "m"); break;
+ case rs_space:
+ fprintf (file, "s"); break;
+ case 0:
+ fprintf (file, "0"); break;
+ default:
+ fprintf (file, "?"); break;
+ }
+#endif
+ count++;
+ }
+ fprintf (file, "\n");
+ fprintf (file, "\t%p %-10s\t%10d frags\n", (void *) frchp,
+ segment_name (frchp->frch_seg), count);
+ }
+}
+
+/* end of subsegs.c */
diff --git a/x/binutils/gas/subsegs.h b/x/binutils/gas/subsegs.h
new file mode 100644
index 0000000..331c557
--- /dev/null
+++ b/x/binutils/gas/subsegs.h
@@ -0,0 +1,155 @@
+/* subsegs.h -> subsegs.c
+ Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1998, 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ * For every sub-segment the user mentions in the ASsembler program,
+ * we make one struct frchain. Each sub-segment has exactly one struct frchain
+ * and vice versa.
+ *
+ * Struct frchain's are forward chained (in ascending order of sub-segment
+ * code number). The chain runs through frch_next of each subsegment.
+ * This makes it hard to find a subsegment's frags
+ * if programmer uses a lot of them. Most programs only use text0 and
+ * data0, so they don't suffer. At least this way:
+ * (1) There are no "arbitrary" restrictions on how many subsegments
+ * can be programmed;
+ * (2) Subsegments' frchain-s are (later) chained together in the order in
+ * which they are emitted for object file viz text then data.
+ *
+ * From each struct frchain dangles a chain of struct frags. The frags
+ * represent code fragments, for that sub-segment, forward chained.
+ */
+
+#include "obstack.h"
+
+struct frchain /* control building of a frag chain */
+{ /* FRCH = FRagment CHain control */
+ struct frag *frch_root; /* 1st struct frag in chain, or NULL */
+ struct frag *frch_last; /* last struct frag in chain, or NULL */
+ struct frchain *frch_next; /* next in chain of struct frchain-s */
+ segT frch_seg; /* SEG_TEXT or SEG_DATA. */
+ subsegT frch_subseg; /* subsegment number of this chain */
+#ifdef BFD_ASSEMBLER
+ fixS *fix_root; /* Root of fixups for this subsegment. */
+ fixS *fix_tail; /* Last fixup for this subsegment. */
+#endif
+ struct obstack frch_obstack; /* for objects in this frag chain */
+ fragS *frch_frag_now; /* frag_now for this subsegment */
+};
+
+typedef struct frchain frchainS;
+
+/* All subsegments' chains hang off here. NULL means no frchains yet. */
+extern frchainS *frchain_root;
+
+/* Frchain we are assembling into now. That is, the current segment's
+ frag chain, even if it contains no (complete) frags. */
+extern frchainS *frchain_now;
+
+typedef struct segment_info_struct {
+ frchainS *frchainP;
+ unsigned int hadone : 1;
+
+ /* This field is set if this is a .bss section which does not really
+ have any contents. Once upon a time a .bss section did not have
+ any frags, but that is no longer true. This field prevent the
+ SEC_HAS_CONTENTS flag from being set for the section even if
+ there are frags. */
+ unsigned int bss : 1;
+
+ int user_stuff;
+
+ /* Fixups for this segment. If BFD_ASSEMBLER, this is only valid
+ after the frchains are run together. */
+ fixS *fix_root;
+ fixS *fix_tail;
+
+#if defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
+ struct internal_scnhdr scnhdr;
+ enum linkonce_type linkonce;
+ const char *name;
+#endif
+
+ symbolS *dot;
+
+ struct lineno_list *lineno_list_head;
+ struct lineno_list *lineno_list_tail;
+
+#ifdef BFD_ASSEMBLER
+ /* Which BFD section does this gas segment correspond to? */
+ asection *bfd_section;
+
+ /* NULL, or pointer to the gas symbol that is the section symbol for
+ this section. sym->bsym and bfd_section->symbol should be the same. */
+ symbolS *sym;
+#endif
+
+ union {
+ /* Current size of section holding stabs strings. */
+ unsigned long stab_string_size;
+ /* Initial frag for ELF. */
+ char *p;
+ }
+ stabu;
+
+#ifdef NEED_LITERAL_POOL
+ unsigned long literal_pool_size;
+#endif
+
+#ifdef TC_SEGMENT_INFO_TYPE
+ TC_SEGMENT_INFO_TYPE tc_segment_info_data;
+#endif
+} segment_info_type;
+
+#ifdef BFD_ASSEMBLER
+
+extern segment_info_type *seg_info (segT);
+extern symbolS *section_symbol (segT);
+
+#else /* ! BFD_ASSEMBLER */
+
+#ifdef MANY_SEGMENTS
+
+extern segment_info_type segment_info[];
+
+#define seg_info(SEC) (&segment_info[SEC])
+
+#else
+
+/* Sentinel for frchain crawling. Points to the 1st data-segment
+ frchain. (Which is pointed to by the last text-segment frchain.) */
+extern frchainS *data0_frchainP;
+extern frchainS *bss0_frchainP;
+
+/* Dummy so stuff can compile. Should never be used. */
+struct seg_info_trash {
+ struct {
+ unsigned stab_string_size : 1;
+ } stabu;
+ unsigned hadone : 1;
+};
+#define seg_info(S) (abort (), (struct seg_info_trash *) 0)
+
+#endif
+
+#endif /* ! BFD_ASSEMBLER */
+
+extern void subsegs_print_statistics (FILE *);
diff --git a/x/binutils/gas/symbols.c b/x/binutils/gas/symbols.c
new file mode 100644
index 0000000..761a020
--- /dev/null
+++ b/x/binutils/gas/symbols.c
@@ -0,0 +1,2576 @@
+/* symbols.c -symbol table-
+ Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* #define DEBUG_SYMS / * to debug symbol list maintenance. */
+
+#include "as.h"
+
+#include "safe-ctype.h"
+#include "obstack.h" /* For "symbols.h" */
+#include "subsegs.h"
+
+#include "struc-symbol.h"
+
+/* This is non-zero if symbols are case sensitive, which is the
+ default. */
+int symbols_case_sensitive = 1;
+
+#ifndef WORKING_DOT_WORD
+extern int new_broken_words;
+#endif
+
+/* symbol-name => struct symbol pointer */
+static struct hash_control *sy_hash;
+
+/* Table of local symbols. */
+static struct hash_control *local_hash;
+
+/* Below are commented in "symbols.h". */
+symbolS *symbol_rootP;
+symbolS *symbol_lastP;
+symbolS abs_symbol;
+
+#ifdef DEBUG_SYMS
+#define debug_verify_symchain verify_symbol_chain
+#else
+#define debug_verify_symchain(root, last) ((void) 0)
+#endif
+
+#define DOLLAR_LABEL_CHAR '\001'
+#define LOCAL_LABEL_CHAR '\002'
+
+struct obstack notes;
+
+static char *save_symbol_name (const char *);
+static void fb_label_init (void);
+static long dollar_label_instance (long);
+static long fb_label_instance (long);
+
+static void print_binary (FILE *, const char *, expressionS *);
+static void report_op_error (symbolS *, symbolS *, symbolS *);
+
+/* Return a pointer to a new symbol. Die if we can't make a new
+ symbol. Fill in the symbol's values. Add symbol to end of symbol
+ chain.
+
+ This function should be called in the general case of creating a
+ symbol. However, if the output file symbol table has already been
+ set, and you are certain that this symbol won't be wanted in the
+ output file, you can call symbol_create. */
+
+symbolS *
+symbol_new (const char *name, segT segment, valueT valu, fragS *frag)
+{
+ symbolS *symbolP = symbol_create (name, segment, valu, frag);
+
+ /* Link to end of symbol chain. */
+#ifdef BFD_ASSEMBLER
+ {
+ extern int symbol_table_frozen;
+ if (symbol_table_frozen)
+ abort ();
+ }
+#endif
+ symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP);
+
+ return symbolP;
+}
+
+/* Save a symbol name on a permanent obstack, and convert it according
+ to the object file format. */
+
+static char *
+save_symbol_name (const char *name)
+{
+ unsigned int name_length;
+ char *ret;
+
+ name_length = strlen (name) + 1; /* +1 for \0. */
+ obstack_grow (&notes, name, name_length);
+ ret = obstack_finish (&notes);
+
+#ifdef STRIP_UNDERSCORE
+ if (ret[0] == '_')
+ ++ret;
+#endif
+
+#ifdef tc_canonicalize_symbol_name
+ ret = tc_canonicalize_symbol_name (ret);
+#endif
+
+ if (! symbols_case_sensitive)
+ {
+ char *s;
+
+ for (s = ret; *s != '\0'; s++)
+ *s = TOUPPER (*s);
+ }
+
+ return ret;
+}
+
+symbolS *
+symbol_create (const char *name, /* It is copied, the caller can destroy/modify. */
+ segT segment, /* Segment identifier (SEG_<something>). */
+ valueT valu, /* Symbol value. */
+ fragS *frag /* Associated fragment. */)
+{
+ char *preserved_copy_of_name;
+ symbolS *symbolP;
+
+ preserved_copy_of_name = save_symbol_name (name);
+
+ symbolP = (symbolS *) obstack_alloc (&notes, sizeof (symbolS));
+
+ /* symbol must be born in some fixed state. This seems as good as any. */
+ memset (symbolP, 0, sizeof (symbolS));
+
+#ifdef BFD_ASSEMBLER
+ symbolP->bsym = bfd_make_empty_symbol (stdoutput);
+ if (symbolP->bsym == NULL)
+ as_perror ("%s", "bfd_make_empty_symbol");
+ symbolP->bsym->udata.p = (PTR) symbolP;
+#endif
+ S_SET_NAME (symbolP, preserved_copy_of_name);
+
+ S_SET_SEGMENT (symbolP, segment);
+ S_SET_VALUE (symbolP, valu);
+ symbol_clear_list_pointers (symbolP);
+
+ symbolP->sy_frag = frag;
+#ifndef BFD_ASSEMBLER
+ symbolP->sy_number = ~0;
+ symbolP->sy_name_offset = (unsigned int) ~0;
+#endif
+
+ obj_symbol_new_hook (symbolP);
+
+#ifdef tc_symbol_new_hook
+ tc_symbol_new_hook (symbolP);
+#endif
+
+ return symbolP;
+}
+
+#ifdef BFD_ASSEMBLER
+
+/* Local symbol support. If we can get away with it, we keep only a
+ small amount of information for local symbols. */
+
+static symbolS *local_symbol_convert (struct local_symbol *);
+
+/* Used for statistics. */
+
+static unsigned long local_symbol_count;
+static unsigned long local_symbol_conversion_count;
+
+/* This macro is called with a symbol argument passed by reference.
+ It returns whether this is a local symbol. If necessary, it
+ changes its argument to the real symbol. */
+
+#define LOCAL_SYMBOL_CHECK(s) \
+ (s->bsym == NULL \
+ ? (local_symbol_converted_p ((struct local_symbol *) s) \
+ ? (s = local_symbol_get_real_symbol ((struct local_symbol *) s), \
+ 0) \
+ : 1) \
+ : 0)
+
+/* Create a local symbol and insert it into the local hash table. */
+
+struct local_symbol *
+local_symbol_make (const char *name, segT section, valueT value, fragS *frag)
+{
+ char *name_copy;
+ struct local_symbol *ret;
+
+ ++local_symbol_count;
+
+ name_copy = save_symbol_name (name);
+
+ ret = (struct local_symbol *) obstack_alloc (&notes, sizeof *ret);
+ ret->lsy_marker = NULL;
+ ret->lsy_name = name_copy;
+ ret->lsy_section = section;
+ local_symbol_set_frag (ret, frag);
+ ret->lsy_value = value;
+
+ hash_jam (local_hash, name_copy, (PTR) ret);
+
+ return ret;
+}
+
+/* Convert a local symbol into a real symbol. Note that we do not
+ reclaim the space used by the local symbol. */
+
+static symbolS *
+local_symbol_convert (struct local_symbol *locsym)
+{
+ symbolS *ret;
+
+ assert (locsym->lsy_marker == NULL);
+ if (local_symbol_converted_p (locsym))
+ return local_symbol_get_real_symbol (locsym);
+
+ ++local_symbol_conversion_count;
+
+ ret = symbol_new (locsym->lsy_name, locsym->lsy_section, locsym->lsy_value,
+ local_symbol_get_frag (locsym));
+
+ if (local_symbol_resolved_p (locsym))
+ ret->sy_resolved = 1;
+
+ /* Local symbols are always either defined or used. */
+ ret->sy_used = 1;
+
+#ifdef TC_LOCAL_SYMFIELD_CONVERT
+ TC_LOCAL_SYMFIELD_CONVERT (locsym, ret);
+#endif
+
+ symbol_table_insert (ret);
+
+ local_symbol_mark_converted (locsym);
+ local_symbol_set_real_symbol (locsym, ret);
+
+ hash_jam (local_hash, locsym->lsy_name, NULL);
+
+ return ret;
+}
+
+#else /* ! BFD_ASSEMBLER */
+
+#define LOCAL_SYMBOL_CHECK(s) 0
+#define local_symbol_convert(s) ((symbolS *) s)
+
+#endif /* ! BFD_ASSEMBLER */
+
+/* We have just seen "<name>:".
+ Creates a struct symbol unless it already exists.
+
+ Gripes if we are redefining a symbol incompatibly (and ignores it). */
+
+symbolS *
+colon (/* Just seen "x:" - rattle symbols & frags. */
+ const char *sym_name /* Symbol name, as a cannonical string. */
+ /* We copy this string: OK to alter later. */)
+{
+ register symbolS *symbolP; /* Symbol we are working with. */
+
+ /* Sun local labels go out of scope whenever a non-local symbol is
+ defined. */
+ if (LOCAL_LABELS_DOLLAR)
+ {
+ int local;
+
+#ifdef BFD_ASSEMBLER
+ local = bfd_is_local_label_name (stdoutput, sym_name);
+#else
+ local = LOCAL_LABEL (sym_name);
+#endif
+
+ if (! local)
+ dollar_label_clear ();
+ }
+
+#ifndef WORKING_DOT_WORD
+ if (new_broken_words)
+ {
+ struct broken_word *a;
+ int possible_bytes;
+ fragS *frag_tmp;
+ char *frag_opcode;
+
+ extern const int md_short_jump_size;
+ extern const int md_long_jump_size;
+
+ if (now_seg == absolute_section)
+ {
+ as_bad (_("cannot define symbol `%s' in absolute section"), sym_name);
+ return NULL;
+ }
+
+ possible_bytes = (md_short_jump_size
+ + new_broken_words * md_long_jump_size);
+
+ frag_tmp = frag_now;
+ frag_opcode = frag_var (rs_broken_word,
+ possible_bytes,
+ possible_bytes,
+ (relax_substateT) 0,
+ (symbolS *) broken_words,
+ (offsetT) 0,
+ NULL);
+
+ /* We want to store the pointer to where to insert the jump
+ table in the fr_opcode of the rs_broken_word frag. This
+ requires a little hackery. */
+ while (frag_tmp
+ && (frag_tmp->fr_type != rs_broken_word
+ || frag_tmp->fr_opcode))
+ frag_tmp = frag_tmp->fr_next;
+ know (frag_tmp);
+ frag_tmp->fr_opcode = frag_opcode;
+ new_broken_words = 0;
+
+ for (a = broken_words; a && a->dispfrag == 0; a = a->next_broken_word)
+ a->dispfrag = frag_tmp;
+ }
+#endif /* WORKING_DOT_WORD */
+
+ if ((symbolP = symbol_find (sym_name)) != 0)
+ {
+#ifdef RESOLVE_SYMBOL_REDEFINITION
+ if (RESOLVE_SYMBOL_REDEFINITION (symbolP))
+ return symbolP;
+#endif
+ /* Now check for undefined symbols. */
+ if (LOCAL_SYMBOL_CHECK (symbolP))
+ {
+#ifdef BFD_ASSEMBLER
+ struct local_symbol *locsym = (struct local_symbol *) symbolP;
+
+ if (locsym->lsy_section != undefined_section
+ && (local_symbol_get_frag (locsym) != frag_now
+ || locsym->lsy_section != now_seg
+ || locsym->lsy_value != frag_now_fix ()))
+ {
+ as_bad (_("symbol `%s' is already defined"), sym_name);
+ return symbolP;
+ }
+
+ locsym->lsy_section = now_seg;
+ local_symbol_set_frag (locsym, frag_now);
+ locsym->lsy_value = frag_now_fix ();
+#endif
+ }
+ else if (!S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP))
+ {
+ if (S_GET_VALUE (symbolP) == 0)
+ {
+ symbolP->sy_frag = frag_now;
+#ifdef OBJ_VMS
+ S_SET_OTHER (symbolP, const_flag);
+#endif
+ S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
+ S_SET_SEGMENT (symbolP, now_seg);
+#ifdef N_UNDF
+ know (N_UNDF == 0);
+#endif /* if we have one, it better be zero. */
+
+ }
+ else
+ {
+ /* There are still several cases to check:
+
+ A .comm/.lcomm symbol being redefined as initialized
+ data is OK
+
+ A .comm/.lcomm symbol being redefined with a larger
+ size is also OK
+
+ This only used to be allowed on VMS gas, but Sun cc
+ on the sparc also depends on it. */
+
+ if (((!S_IS_DEBUG (symbolP)
+ && (!S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP))
+ && S_IS_EXTERNAL (symbolP))
+ || S_GET_SEGMENT (symbolP) == bss_section)
+ && (now_seg == data_section
+ || now_seg == S_GET_SEGMENT (symbolP)))
+ {
+ /* Select which of the 2 cases this is. */
+ if (now_seg != data_section)
+ {
+ /* New .comm for prev .comm symbol.
+
+ If the new size is larger we just change its
+ value. If the new size is smaller, we ignore
+ this symbol. */
+ if (S_GET_VALUE (symbolP)
+ < ((unsigned) frag_now_fix ()))
+ {
+ S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
+ }
+ }
+ else
+ {
+ /* It is a .comm/.lcomm being converted to initialized
+ data. */
+ symbolP->sy_frag = frag_now;
+#ifdef OBJ_VMS
+ S_SET_OTHER (symbolP, const_flag);
+#endif
+ S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
+ S_SET_SEGMENT (symbolP, now_seg); /* Keep N_EXT bit. */
+ }
+ }
+ else
+ {
+#if (!defined (OBJ_AOUT) && !defined (OBJ_MAYBE_AOUT) \
+ && !defined (OBJ_BOUT) && !defined (OBJ_MAYBE_BOUT))
+ static const char *od_buf = "";
+#else
+ char od_buf[100];
+ od_buf[0] = '\0';
+#ifdef BFD_ASSEMBLER
+ if (OUTPUT_FLAVOR == bfd_target_aout_flavour)
+#endif
+ sprintf (od_buf, "%d.%d.",
+ S_GET_OTHER (symbolP),
+ S_GET_DESC (symbolP));
+#endif
+ as_bad (_("symbol `%s' is already defined as \"%s\"/%s%ld"),
+ sym_name,
+ segment_name (S_GET_SEGMENT (symbolP)),
+ od_buf,
+ (long) S_GET_VALUE (symbolP));
+ }
+ } /* if the undefined symbol has no value */
+ }
+ else
+ {
+ /* Don't blow up if the definition is the same. */
+ if (!(frag_now == symbolP->sy_frag
+ && S_GET_VALUE (symbolP) == frag_now_fix ()
+ && S_GET_SEGMENT (symbolP) == now_seg))
+ as_bad (_("symbol `%s' is already defined"), sym_name);
+ }
+
+ }
+#ifdef BFD_ASSEMBLER
+ else if (! flag_keep_locals && bfd_is_local_label_name (stdoutput, sym_name))
+ {
+ symbolP = (symbolS *) local_symbol_make (sym_name, now_seg,
+ (valueT) frag_now_fix (),
+ frag_now);
+ }
+#endif /* BFD_ASSEMBLER */
+ else
+ {
+ symbolP = symbol_new (sym_name, now_seg, (valueT) frag_now_fix (),
+ frag_now);
+#ifdef OBJ_VMS
+ S_SET_OTHER (symbolP, const_flag);
+#endif /* OBJ_VMS */
+
+ symbol_table_insert (symbolP);
+ }
+
+ if (mri_common_symbol != NULL)
+ {
+ /* This symbol is actually being defined within an MRI common
+ section. This requires special handling. */
+ if (LOCAL_SYMBOL_CHECK (symbolP))
+ symbolP = local_symbol_convert ((struct local_symbol *) symbolP);
+ symbolP->sy_value.X_op = O_symbol;
+ symbolP->sy_value.X_add_symbol = mri_common_symbol;
+ symbolP->sy_value.X_add_number = S_GET_VALUE (mri_common_symbol);
+ symbolP->sy_frag = &zero_address_frag;
+ S_SET_SEGMENT (symbolP, expr_section);
+ symbolP->sy_mri_common = 1;
+ }
+
+#ifdef tc_frob_label
+ tc_frob_label (symbolP);
+#endif
+#ifdef obj_frob_label
+ obj_frob_label (symbolP);
+#endif
+
+ return symbolP;
+}
+
+/* Die if we can't insert the symbol. */
+
+void
+symbol_table_insert (symbolS *symbolP)
+{
+ register const char *error_string;
+
+ know (symbolP);
+ know (S_GET_NAME (symbolP));
+
+ if (LOCAL_SYMBOL_CHECK (symbolP))
+ {
+ error_string = hash_jam (local_hash, S_GET_NAME (symbolP),
+ (PTR) symbolP);
+ if (error_string != NULL)
+ as_fatal (_("inserting \"%s\" into symbol table failed: %s"),
+ S_GET_NAME (symbolP), error_string);
+ return;
+ }
+
+ if ((error_string = hash_jam (sy_hash, S_GET_NAME (symbolP), (PTR) symbolP)))
+ {
+ as_fatal (_("inserting \"%s\" into symbol table failed: %s"),
+ S_GET_NAME (symbolP), error_string);
+ } /* on error */
+}
+
+/* If a symbol name does not exist, create it as undefined, and insert
+ it into the symbol table. Return a pointer to it. */
+
+symbolS *
+symbol_find_or_make (const char *name)
+{
+ register symbolS *symbolP;
+
+ symbolP = symbol_find (name);
+
+ if (symbolP == NULL)
+ {
+#ifdef BFD_ASSEMBLER
+ if (! flag_keep_locals && bfd_is_local_label_name (stdoutput, name))
+ {
+ symbolP = md_undefined_symbol ((char *) name);
+ if (symbolP != NULL)
+ return symbolP;
+
+ symbolP = (symbolS *) local_symbol_make (name, undefined_section,
+ (valueT) 0,
+ &zero_address_frag);
+ return symbolP;
+ }
+#endif
+
+ symbolP = symbol_make (name);
+
+ symbol_table_insert (symbolP);
+ } /* if symbol wasn't found */
+
+ return (symbolP);
+}
+
+symbolS *
+symbol_make (const char *name)
+{
+ symbolS *symbolP;
+
+ /* Let the machine description default it, e.g. for register names. */
+ symbolP = md_undefined_symbol ((char *) name);
+
+ if (!symbolP)
+ symbolP = symbol_new (name, undefined_section, (valueT) 0, &zero_address_frag);
+
+ return (symbolP);
+}
+
+symbolS *
+symbol_temp_new (segT seg, valueT ofs, fragS *frag)
+{
+ return symbol_new (FAKE_LABEL_NAME, seg, ofs, frag);
+}
+
+symbolS *
+symbol_temp_new_now (void)
+{
+ return symbol_temp_new (now_seg, frag_now_fix (), frag_now);
+}
+
+symbolS *
+symbol_temp_make (void)
+{
+ return symbol_make (FAKE_LABEL_NAME);
+}
+
+/* Implement symbol table lookup.
+ In: A symbol's name as a string: '\0' can't be part of a symbol name.
+ Out: NULL if the name was not in the symbol table, else the address
+ of a struct symbol associated with that name. */
+
+symbolS *
+symbol_find (const char *name)
+{
+#ifdef STRIP_UNDERSCORE
+ return (symbol_find_base (name, 1));
+#else /* STRIP_UNDERSCORE */
+ return (symbol_find_base (name, 0));
+#endif /* STRIP_UNDERSCORE */
+}
+
+symbolS *
+symbol_find_exact (const char *name)
+{
+#ifdef BFD_ASSEMBLER
+ {
+ struct local_symbol *locsym;
+
+ locsym = (struct local_symbol *) hash_find (local_hash, name);
+ if (locsym != NULL)
+ return (symbolS *) locsym;
+ }
+#endif
+
+ return ((symbolS *) hash_find (sy_hash, name));
+}
+
+symbolS *
+symbol_find_base (const char *name, int strip_underscore)
+{
+ if (strip_underscore && *name == '_')
+ name++;
+
+#ifdef tc_canonicalize_symbol_name
+ {
+ char *copy;
+ size_t len = strlen (name) + 1;
+
+ copy = (char *) alloca (len);
+ memcpy (copy, name, len);
+ name = tc_canonicalize_symbol_name (copy);
+ }
+#endif
+
+ if (! symbols_case_sensitive)
+ {
+ char *copy;
+ const char *orig;
+ unsigned char c;
+
+ orig = name;
+ name = copy = (char *) alloca (strlen (name) + 1);
+
+ while ((c = *orig++) != '\0')
+ {
+ *copy++ = TOUPPER (c);
+ }
+ *copy = '\0';
+ }
+
+ return symbol_find_exact (name);
+}
+
+/* Once upon a time, symbols were kept in a singly linked list. At
+ least coff needs to be able to rearrange them from time to time, for
+ which a doubly linked list is much more convenient. Loic did these
+ as macros which seemed dangerous to me so they're now functions.
+ xoxorich. */
+
+/* Link symbol ADDME after symbol TARGET in the chain. */
+
+void
+symbol_append (symbolS *addme, symbolS *target,
+ symbolS **rootPP, symbolS **lastPP)
+{
+ if (LOCAL_SYMBOL_CHECK (addme))
+ abort ();
+ if (target != NULL && LOCAL_SYMBOL_CHECK (target))
+ abort ();
+
+ if (target == NULL)
+ {
+ know (*rootPP == NULL);
+ know (*lastPP == NULL);
+ addme->sy_next = NULL;
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+ addme->sy_previous = NULL;
+#endif
+ *rootPP = addme;
+ *lastPP = addme;
+ return;
+ } /* if the list is empty */
+
+ if (target->sy_next != NULL)
+ {
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+ target->sy_next->sy_previous = addme;
+#endif /* SYMBOLS_NEED_BACKPOINTERS */
+ }
+ else
+ {
+ know (*lastPP == target);
+ *lastPP = addme;
+ } /* if we have a next */
+
+ addme->sy_next = target->sy_next;
+ target->sy_next = addme;
+
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+ addme->sy_previous = target;
+#endif /* SYMBOLS_NEED_BACKPOINTERS */
+
+ debug_verify_symchain (symbol_rootP, symbol_lastP);
+}
+
+/* Set the chain pointers of SYMBOL to null. */
+
+void
+symbol_clear_list_pointers (symbolS *symbolP)
+{
+ if (LOCAL_SYMBOL_CHECK (symbolP))
+ abort ();
+ symbolP->sy_next = NULL;
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+ symbolP->sy_previous = NULL;
+#endif
+}
+
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+/* Remove SYMBOLP from the list. */
+
+void
+symbol_remove (symbolS *symbolP, symbolS **rootPP, symbolS **lastPP)
+{
+ if (LOCAL_SYMBOL_CHECK (symbolP))
+ abort ();
+
+ if (symbolP == *rootPP)
+ {
+ *rootPP = symbolP->sy_next;
+ } /* if it was the root */
+
+ if (symbolP == *lastPP)
+ {
+ *lastPP = symbolP->sy_previous;
+ } /* if it was the tail */
+
+ if (symbolP->sy_next != NULL)
+ {
+ symbolP->sy_next->sy_previous = symbolP->sy_previous;
+ } /* if not last */
+
+ if (symbolP->sy_previous != NULL)
+ {
+ symbolP->sy_previous->sy_next = symbolP->sy_next;
+ } /* if not first */
+
+ debug_verify_symchain (*rootPP, *lastPP);
+}
+
+/* Link symbol ADDME before symbol TARGET in the chain. */
+
+void
+symbol_insert (symbolS *addme, symbolS *target,
+ symbolS **rootPP, symbolS **lastPP ATTRIBUTE_UNUSED)
+{
+ if (LOCAL_SYMBOL_CHECK (addme))
+ abort ();
+ if (LOCAL_SYMBOL_CHECK (target))
+ abort ();
+
+ if (target->sy_previous != NULL)
+ {
+ target->sy_previous->sy_next = addme;
+ }
+ else
+ {
+ know (*rootPP == target);
+ *rootPP = addme;
+ } /* if not first */
+
+ addme->sy_previous = target->sy_previous;
+ target->sy_previous = addme;
+ addme->sy_next = target;
+
+ debug_verify_symchain (*rootPP, *lastPP);
+}
+
+#endif /* SYMBOLS_NEED_BACKPOINTERS */
+
+void
+verify_symbol_chain (symbolS *rootP, symbolS *lastP)
+{
+ symbolS *symbolP = rootP;
+
+ if (symbolP == NULL)
+ return;
+
+ for (; symbol_next (symbolP) != NULL; symbolP = symbol_next (symbolP))
+ {
+#ifdef BFD_ASSEMBLER
+ assert (symbolP->bsym != NULL);
+#endif
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+ assert (symbolP->sy_next->sy_previous == symbolP);
+#else
+ /* Walk the list anyways, to make sure pointers are still good. */
+ ;
+#endif /* SYMBOLS_NEED_BACKPOINTERS */
+ }
+
+ assert (lastP == symbolP);
+}
+
+void
+verify_symbol_chain_2 (symbolS *sym)
+{
+ symbolS *p = sym, *n = sym;
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+ while (symbol_previous (p))
+ p = symbol_previous (p);
+#endif
+ while (symbol_next (n))
+ n = symbol_next (n);
+ verify_symbol_chain (p, n);
+}
+
+static void
+report_op_error (symbolS *symp, symbolS *left, symbolS *right)
+{
+ char *file;
+ unsigned int line;
+ segT seg_left = S_GET_SEGMENT (left);
+ segT seg_right = right ? S_GET_SEGMENT (right) : 0;
+
+ if (expr_symbol_where (symp, &file, &line))
+ {
+ if (seg_left == undefined_section)
+ as_bad_where (file, line,
+ _("undefined symbol `%s' in operation"),
+ S_GET_NAME (left));
+ if (seg_right == undefined_section)
+ as_bad_where (file, line,
+ _("undefined symbol `%s' in operation"),
+ S_GET_NAME (right));
+ if (seg_left != undefined_section
+ && seg_right != undefined_section)
+ {
+ if (right)
+ as_bad_where (file, line,
+ _("invalid sections for operation on `%s' and `%s'"),
+ S_GET_NAME (left), S_GET_NAME (right));
+ else
+ as_bad_where (file, line,
+ _("invalid section for operation on `%s'"),
+ S_GET_NAME (left));
+ }
+
+ }
+ else
+ {
+ if (seg_left == undefined_section)
+ as_bad (_("undefined symbol `%s' in operation setting `%s'"),
+ S_GET_NAME (left), S_GET_NAME (symp));
+ if (seg_right == undefined_section)
+ as_bad (_("undefined symbol `%s' in operation setting `%s'"),
+ S_GET_NAME (right), S_GET_NAME (symp));
+ if (seg_left != undefined_section
+ && seg_right != undefined_section)
+ {
+ if (right)
+ as_bad_where (file, line,
+ _("invalid sections for operation on `%s' and `%s' setting `%s'"),
+ S_GET_NAME (left), S_GET_NAME (right), S_GET_NAME (symp));
+ else
+ as_bad_where (file, line,
+ _("invalid section for operation on `%s' setting `%s'"),
+ S_GET_NAME (left), S_GET_NAME (symp));
+ }
+ }
+}
+
+/* Resolve the value of a symbol. This is called during the final
+ pass over the symbol table to resolve any symbols with complex
+ values. */
+
+valueT
+resolve_symbol_value (symbolS *symp)
+{
+ int resolved;
+ valueT final_val = 0;
+ segT final_seg;
+
+#ifdef BFD_ASSEMBLER
+ if (LOCAL_SYMBOL_CHECK (symp))
+ {
+ struct local_symbol *locsym = (struct local_symbol *) symp;
+
+ final_val = locsym->lsy_value;
+ if (local_symbol_resolved_p (locsym))
+ return final_val;
+
+ final_val += local_symbol_get_frag (locsym)->fr_address / OCTETS_PER_BYTE;
+
+ if (finalize_syms)
+ {
+ locsym->lsy_value = final_val;
+ local_symbol_mark_resolved (locsym);
+ }
+
+ return final_val;
+ }
+#endif
+
+ if (symp->sy_resolved)
+ {
+ if (symp->sy_value.X_op == O_constant)
+ return (valueT) symp->sy_value.X_add_number;
+ else
+ return 0;
+ }
+
+ resolved = 0;
+ final_seg = S_GET_SEGMENT (symp);
+
+ if (symp->sy_resolving)
+ {
+ if (finalize_syms)
+ as_bad (_("symbol definition loop encountered at `%s'"),
+ S_GET_NAME (symp));
+ final_val = 0;
+ resolved = 1;
+ }
+ else
+ {
+ symbolS *add_symbol, *op_symbol;
+ offsetT left, right;
+ segT seg_left, seg_right;
+ operatorT op;
+
+ symp->sy_resolving = 1;
+
+ /* Help out with CSE. */
+ add_symbol = symp->sy_value.X_add_symbol;
+ op_symbol = symp->sy_value.X_op_symbol;
+ final_val = symp->sy_value.X_add_number;
+ op = symp->sy_value.X_op;
+
+ switch (op)
+ {
+ default:
+ BAD_CASE (op);
+ break;
+
+ case O_absent:
+ final_val = 0;
+ /* Fall through. */
+
+ case O_constant:
+ final_val += symp->sy_frag->fr_address / OCTETS_PER_BYTE;
+ if (final_seg == expr_section)
+ final_seg = absolute_section;
+ resolved = 1;
+ break;
+
+ case O_symbol:
+ case O_symbol_rva:
+ left = resolve_symbol_value (add_symbol);
+ seg_left = S_GET_SEGMENT (add_symbol);
+ if (finalize_syms)
+ symp->sy_value.X_op_symbol = NULL;
+
+ do_symbol:
+ if (symp->sy_mri_common)
+ {
+ /* This is a symbol inside an MRI common section. The
+ relocation routines are going to handle it specially.
+ Don't change the value. */
+ resolved = symbol_resolved_p (add_symbol);
+ break;
+ }
+
+ if (finalize_syms && final_val == 0)
+ {
+ if (LOCAL_SYMBOL_CHECK (add_symbol))
+ add_symbol = local_symbol_convert ((struct local_symbol *)
+ add_symbol);
+ copy_symbol_attributes (symp, add_symbol);
+ }
+
+ /* If we have equated this symbol to an undefined or common
+ symbol, keep X_op set to O_symbol, and don't change
+ X_add_number. This permits the routine which writes out
+ relocation to detect this case, and convert the
+ relocation to be against the symbol to which this symbol
+ is equated. */
+ if (! S_IS_DEFINED (add_symbol) || S_IS_COMMON (add_symbol))
+ {
+ if (finalize_syms)
+ {
+ symp->sy_value.X_op = O_symbol;
+ symp->sy_value.X_add_symbol = add_symbol;
+ symp->sy_value.X_add_number = final_val;
+ /* Use X_op_symbol as a flag. */
+ symp->sy_value.X_op_symbol = add_symbol;
+ final_seg = seg_left;
+ }
+ final_val = 0;
+ resolved = symbol_resolved_p (add_symbol);
+ symp->sy_resolving = 0;
+ goto exit_dont_set_value;
+ }
+ else if (finalize_syms && final_seg == expr_section
+ && seg_left != expr_section)
+ {
+ /* If the symbol is an expression symbol, do similarly
+ as for undefined and common syms above. Handles
+ "sym +/- expr" where "expr" cannot be evaluated
+ immediately, and we want relocations to be against
+ "sym", eg. because it is weak. */
+ symp->sy_value.X_op = O_symbol;
+ symp->sy_value.X_add_symbol = add_symbol;
+ symp->sy_value.X_add_number = final_val;
+ symp->sy_value.X_op_symbol = add_symbol;
+ final_seg = seg_left;
+ final_val += symp->sy_frag->fr_address + left;
+ resolved = symbol_resolved_p (add_symbol);
+ symp->sy_resolving = 0;
+ goto exit_dont_set_value;
+ }
+ else
+ {
+ final_val += symp->sy_frag->fr_address + left;
+ if (final_seg == expr_section || final_seg == undefined_section)
+ final_seg = seg_left;
+ }
+
+ resolved = symbol_resolved_p (add_symbol);
+ break;
+
+ case O_uminus:
+ case O_bit_not:
+ case O_logical_not:
+ left = resolve_symbol_value (add_symbol);
+ seg_left = S_GET_SEGMENT (add_symbol);
+
+ /* By reducing these to the relevant dyadic operator, we get
+ !S -> S == 0 permitted on anything,
+ -S -> 0 - S only permitted on absolute
+ ~S -> S ^ ~0 only permitted on absolute */
+ if (op != O_logical_not && seg_left != absolute_section
+ && finalize_syms)
+ report_op_error (symp, add_symbol, NULL);
+
+ if (final_seg == expr_section || final_seg == undefined_section)
+ final_seg = absolute_section;
+
+ if (op == O_uminus)
+ left = -left;
+ else if (op == O_logical_not)
+ left = !left;
+ else
+ left = ~left;
+
+ final_val += left + symp->sy_frag->fr_address;
+
+ resolved = symbol_resolved_p (add_symbol);
+ break;
+
+ case O_multiply:
+ case O_divide:
+ case O_modulus:
+ case O_left_shift:
+ case O_right_shift:
+ case O_bit_inclusive_or:
+ case O_bit_or_not:
+ case O_bit_exclusive_or:
+ case O_bit_and:
+ case O_add:
+ case O_subtract:
+ case O_eq:
+ case O_ne:
+ case O_lt:
+ case O_le:
+ case O_ge:
+ case O_gt:
+ case O_logical_and:
+ case O_logical_or:
+ left = resolve_symbol_value (add_symbol);
+ right = resolve_symbol_value (op_symbol);
+ seg_left = S_GET_SEGMENT (add_symbol);
+ seg_right = S_GET_SEGMENT (op_symbol);
+
+ /* Simplify addition or subtraction of a constant by folding the
+ constant into X_add_number. */
+ if (op == O_add)
+ {
+ if (seg_right == absolute_section)
+ {
+ final_val += right;
+ goto do_symbol;
+ }
+ else if (seg_left == absolute_section)
+ {
+ final_val += left;
+ add_symbol = op_symbol;
+ left = right;
+ seg_left = seg_right;
+ goto do_symbol;
+ }
+ }
+ else if (op == O_subtract)
+ {
+ if (seg_right == absolute_section)
+ {
+ final_val -= right;
+ goto do_symbol;
+ }
+ }
+
+ /* Equality and non-equality tests are permitted on anything.
+ Subtraction, and other comparison operators are permitted if
+ both operands are in the same section. Otherwise, both
+ operands must be absolute. We already handled the case of
+ addition or subtraction of a constant above. This will
+ probably need to be changed for an object file format which
+ supports arbitrary expressions, such as IEEE-695.
+
+ Don't emit messages unless we're finalizing the symbol value,
+ otherwise we may get the same message multiple times. */
+ if (finalize_syms
+ && !(seg_left == absolute_section
+ && seg_right == absolute_section)
+ && !(op == O_eq || op == O_ne)
+ && !((op == O_subtract
+ || op == O_lt || op == O_le || op == O_ge || op == O_gt)
+ && seg_left == seg_right
+ && (seg_left != undefined_section
+ || add_symbol == op_symbol)))
+ report_op_error (symp, add_symbol, op_symbol);
+
+ if (final_seg == expr_section || final_seg == undefined_section)
+ final_seg = absolute_section;
+
+ /* Check for division by zero. */
+ if ((op == O_divide || op == O_modulus) && right == 0)
+ {
+ /* If seg_right is not absolute_section, then we've
+ already issued a warning about using a bad symbol. */
+ if (seg_right == absolute_section && finalize_syms)
+ {
+ char *file;
+ unsigned int line;
+
+ if (expr_symbol_where (symp, &file, &line))
+ as_bad_where (file, line, _("division by zero"));
+ else
+ as_bad (_("division by zero when setting `%s'"),
+ S_GET_NAME (symp));
+ }
+
+ right = 1;
+ }
+
+ switch (symp->sy_value.X_op)
+ {
+ case O_multiply: left *= right; break;
+ case O_divide: left /= right; break;
+ case O_modulus: left %= right; break;
+ case O_left_shift: left <<= right; break;
+ case O_right_shift: left >>= right; break;
+ case O_bit_inclusive_or: left |= right; break;
+ case O_bit_or_not: left |= ~right; break;
+ case O_bit_exclusive_or: left ^= right; break;
+ case O_bit_and: left &= right; break;
+ case O_add: left += right; break;
+ case O_subtract: left -= right; break;
+ case O_eq:
+ case O_ne:
+ left = (left == right && seg_left == seg_right
+ && (seg_left != undefined_section
+ || add_symbol == op_symbol)
+ ? ~ (offsetT) 0 : 0);
+ if (symp->sy_value.X_op == O_ne)
+ left = ~left;
+ break;
+ case O_lt: left = left < right ? ~ (offsetT) 0 : 0; break;
+ case O_le: left = left <= right ? ~ (offsetT) 0 : 0; break;
+ case O_ge: left = left >= right ? ~ (offsetT) 0 : 0; break;
+ case O_gt: left = left > right ? ~ (offsetT) 0 : 0; break;
+ case O_logical_and: left = left && right; break;
+ case O_logical_or: left = left || right; break;
+ default: abort ();
+ }
+
+ final_val += symp->sy_frag->fr_address + left;
+ if (final_seg == expr_section || final_seg == undefined_section)
+ {
+ if (seg_left == undefined_section
+ || seg_right == undefined_section)
+ final_seg = undefined_section;
+ else if (seg_left == absolute_section)
+ final_seg = seg_right;
+ else
+ final_seg = seg_left;
+ }
+ resolved = (symbol_resolved_p (add_symbol)
+ && symbol_resolved_p (op_symbol));
+ break;
+
+ case O_register:
+ case O_big:
+ case O_illegal:
+ /* Give an error (below) if not in expr_section. We don't
+ want to worry about expr_section symbols, because they
+ are fictional (they are created as part of expression
+ resolution), and any problems may not actually mean
+ anything. */
+ break;
+ }
+
+ symp->sy_resolving = 0;
+ }
+
+ if (finalize_syms)
+ S_SET_VALUE (symp, final_val);
+
+exit_dont_set_value:
+ /* Always set the segment, even if not finalizing the value.
+ The segment is used to determine whether a symbol is defined. */
+#if defined (OBJ_AOUT) && ! defined (BFD_ASSEMBLER)
+ /* The old a.out backend does not handle S_SET_SEGMENT correctly
+ for a stab symbol, so we use this bad hack. */
+ if (final_seg != S_GET_SEGMENT (symp))
+#endif
+ S_SET_SEGMENT (symp, final_seg);
+
+ /* Don't worry if we can't resolve an expr_section symbol. */
+ if (finalize_syms)
+ {
+ if (resolved)
+ symp->sy_resolved = 1;
+ else if (S_GET_SEGMENT (symp) != expr_section)
+ {
+ as_bad (_("can't resolve value for symbol `%s'"),
+ S_GET_NAME (symp));
+ symp->sy_resolved = 1;
+ }
+ }
+
+ return final_val;
+}
+
+#ifdef BFD_ASSEMBLER
+
+static void resolve_local_symbol (const char *, PTR);
+
+/* A static function passed to hash_traverse. */
+
+static void
+resolve_local_symbol (const char *key ATTRIBUTE_UNUSED, PTR value)
+{
+ if (value != NULL)
+ resolve_symbol_value (value);
+}
+
+#endif
+
+/* Resolve all local symbols. */
+
+void
+resolve_local_symbol_values (void)
+{
+#ifdef BFD_ASSEMBLER
+ hash_traverse (local_hash, resolve_local_symbol);
+#endif
+}
+
+/* Dollar labels look like a number followed by a dollar sign. Eg, "42$".
+ They are *really* local. That is, they go out of scope whenever we see a
+ label that isn't local. Also, like fb labels, there can be multiple
+ instances of a dollar label. Therefor, we name encode each instance with
+ the instance number, keep a list of defined symbols separate from the real
+ symbol table, and we treat these buggers as a sparse array. */
+
+static long *dollar_labels;
+static long *dollar_label_instances;
+static char *dollar_label_defines;
+static unsigned long dollar_label_count;
+static unsigned long dollar_label_max;
+
+int
+dollar_label_defined (long label)
+{
+ long *i;
+
+ know ((dollar_labels != NULL) || (dollar_label_count == 0));
+
+ for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
+ if (*i == label)
+ return dollar_label_defines[i - dollar_labels];
+
+ /* If we get here, label isn't defined. */
+ return 0;
+}
+
+static long
+dollar_label_instance (long label)
+{
+ long *i;
+
+ know ((dollar_labels != NULL) || (dollar_label_count == 0));
+
+ for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
+ if (*i == label)
+ return (dollar_label_instances[i - dollar_labels]);
+
+ /* If we get here, we haven't seen the label before.
+ Therefore its instance count is zero. */
+ return 0;
+}
+
+void
+dollar_label_clear (void)
+{
+ memset (dollar_label_defines, '\0', (unsigned int) dollar_label_count);
+}
+
+#define DOLLAR_LABEL_BUMP_BY 10
+
+void
+define_dollar_label (long label)
+{
+ long *i;
+
+ for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
+ if (*i == label)
+ {
+ ++dollar_label_instances[i - dollar_labels];
+ dollar_label_defines[i - dollar_labels] = 1;
+ return;
+ }
+
+ /* If we get to here, we don't have label listed yet. */
+
+ if (dollar_labels == NULL)
+ {
+ dollar_labels = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
+ dollar_label_instances = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
+ dollar_label_defines = xmalloc (DOLLAR_LABEL_BUMP_BY);
+ dollar_label_max = DOLLAR_LABEL_BUMP_BY;
+ dollar_label_count = 0;
+ }
+ else if (dollar_label_count == dollar_label_max)
+ {
+ dollar_label_max += DOLLAR_LABEL_BUMP_BY;
+ dollar_labels = (long *) xrealloc ((char *) dollar_labels,
+ dollar_label_max * sizeof (long));
+ dollar_label_instances = (long *) xrealloc ((char *) dollar_label_instances,
+ dollar_label_max * sizeof (long));
+ dollar_label_defines = xrealloc (dollar_label_defines, dollar_label_max);
+ } /* if we needed to grow */
+
+ dollar_labels[dollar_label_count] = label;
+ dollar_label_instances[dollar_label_count] = 1;
+ dollar_label_defines[dollar_label_count] = 1;
+ ++dollar_label_count;
+}
+
+/* Caller must copy returned name: we re-use the area for the next name.
+
+ The mth occurence of label n: is turned into the symbol "Ln^Am"
+ where n is the label number and m is the instance number. "L" makes
+ it a label discarded unless debugging and "^A"('\1') ensures no
+ ordinary symbol SHOULD get the same name as a local label
+ symbol. The first "4:" is "L4^A1" - the m numbers begin at 1.
+
+ fb labels get the same treatment, except that ^B is used in place
+ of ^A. */
+
+char * /* Return local label name. */
+dollar_label_name (register long n, /* we just saw "n$:" : n a number. */
+ register int augend /* 0 for current instance, 1 for new instance. */)
+{
+ long i;
+ /* Returned to caller, then copied. Used for created names ("4f"). */
+ static char symbol_name_build[24];
+ register char *p;
+ register char *q;
+ char symbol_name_temporary[20]; /* Build up a number, BACKWARDS. */
+
+ know (n >= 0);
+ know (augend == 0 || augend == 1);
+ p = symbol_name_build;
+#ifdef LOCAL_LABEL_PREFIX
+ *p++ = LOCAL_LABEL_PREFIX;
+#endif
+ *p++ = 'L';
+
+ /* Next code just does sprintf( {}, "%d", n); */
+ /* Label number. */
+ q = symbol_name_temporary;
+ for (*q++ = 0, i = n; i; ++q)
+ {
+ *q = i % 10 + '0';
+ i /= 10;
+ }
+ while ((*p = *--q) != '\0')
+ ++p;
+
+ *p++ = DOLLAR_LABEL_CHAR; /* ^A */
+
+ /* Instance number. */
+ q = symbol_name_temporary;
+ for (*q++ = 0, i = dollar_label_instance (n) + augend; i; ++q)
+ {
+ *q = i % 10 + '0';
+ i /= 10;
+ }
+ while ((*p++ = *--q) != '\0');;
+
+ /* The label, as a '\0' ended string, starts at symbol_name_build. */
+ return symbol_name_build;
+}
+
+/* Somebody else's idea of local labels. They are made by "n:" where n
+ is any decimal digit. Refer to them with
+ "nb" for previous (backward) n:
+ or "nf" for next (forward) n:.
+
+ We do a little better and let n be any number, not just a single digit, but
+ since the other guy's assembler only does ten, we treat the first ten
+ specially.
+
+ Like someone else's assembler, we have one set of local label counters for
+ entire assembly, not one set per (sub)segment like in most assemblers. This
+ implies that one can refer to a label in another segment, and indeed some
+ crufty compilers have done just that.
+
+ Since there could be a LOT of these things, treat them as a sparse
+ array. */
+
+#define FB_LABEL_SPECIAL (10)
+
+static long fb_low_counter[FB_LABEL_SPECIAL];
+static long *fb_labels;
+static long *fb_label_instances;
+static long fb_label_count;
+static long fb_label_max;
+
+/* This must be more than FB_LABEL_SPECIAL. */
+#define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6)
+
+static void
+fb_label_init (void)
+{
+ memset ((void *) fb_low_counter, '\0', sizeof (fb_low_counter));
+}
+
+/* Add one to the instance number of this fb label. */
+
+void
+fb_label_instance_inc (long label)
+{
+ long *i;
+
+ if (label < FB_LABEL_SPECIAL)
+ {
+ ++fb_low_counter[label];
+ return;
+ }
+
+ if (fb_labels != NULL)
+ {
+ for (i = fb_labels + FB_LABEL_SPECIAL;
+ i < fb_labels + fb_label_count; ++i)
+ {
+ if (*i == label)
+ {
+ ++fb_label_instances[i - fb_labels];
+ return;
+ } /* if we find it */
+ } /* for each existing label */
+ }
+
+ /* If we get to here, we don't have label listed yet. */
+
+ if (fb_labels == NULL)
+ {
+ fb_labels = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
+ fb_label_instances = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
+ fb_label_max = FB_LABEL_BUMP_BY;
+ fb_label_count = FB_LABEL_SPECIAL;
+
+ }
+ else if (fb_label_count == fb_label_max)
+ {
+ fb_label_max += FB_LABEL_BUMP_BY;
+ fb_labels = (long *) xrealloc ((char *) fb_labels,
+ fb_label_max * sizeof (long));
+ fb_label_instances = (long *) xrealloc ((char *) fb_label_instances,
+ fb_label_max * sizeof (long));
+ } /* if we needed to grow */
+
+ fb_labels[fb_label_count] = label;
+ fb_label_instances[fb_label_count] = 1;
+ ++fb_label_count;
+}
+
+static long
+fb_label_instance (long label)
+{
+ long *i;
+
+ if (label < FB_LABEL_SPECIAL)
+ {
+ return (fb_low_counter[label]);
+ }
+
+ if (fb_labels != NULL)
+ {
+ for (i = fb_labels + FB_LABEL_SPECIAL;
+ i < fb_labels + fb_label_count; ++i)
+ {
+ if (*i == label)
+ {
+ return (fb_label_instances[i - fb_labels]);
+ } /* if we find it */
+ } /* for each existing label */
+ }
+
+ /* We didn't find the label, so this must be a reference to the
+ first instance. */
+ return 0;
+}
+
+/* Caller must copy returned name: we re-use the area for the next name.
+
+ The mth occurence of label n: is turned into the symbol "Ln^Bm"
+ where n is the label number and m is the instance number. "L" makes
+ it a label discarded unless debugging and "^B"('\2') ensures no
+ ordinary symbol SHOULD get the same name as a local label
+ symbol. The first "4:" is "L4^B1" - the m numbers begin at 1.
+
+ dollar labels get the same treatment, except that ^A is used in
+ place of ^B. */
+
+char * /* Return local label name. */
+fb_label_name (long n, /* We just saw "n:", "nf" or "nb" : n a number. */
+ long augend /* 0 for nb, 1 for n:, nf. */)
+{
+ long i;
+ /* Returned to caller, then copied. Used for created names ("4f"). */
+ static char symbol_name_build[24];
+ register char *p;
+ register char *q;
+ char symbol_name_temporary[20]; /* Build up a number, BACKWARDS. */
+
+ know (n >= 0);
+ know (augend == 0 || augend == 1);
+ p = symbol_name_build;
+#ifdef LOCAL_LABEL_PREFIX
+ *p++ = LOCAL_LABEL_PREFIX;
+#endif
+ *p++ = 'L';
+
+ /* Next code just does sprintf( {}, "%d", n); */
+ /* Label number. */
+ q = symbol_name_temporary;
+ for (*q++ = 0, i = n; i; ++q)
+ {
+ *q = i % 10 + '0';
+ i /= 10;
+ }
+ while ((*p = *--q) != '\0')
+ ++p;
+
+ *p++ = LOCAL_LABEL_CHAR; /* ^B */
+
+ /* Instance number. */
+ q = symbol_name_temporary;
+ for (*q++ = 0, i = fb_label_instance (n) + augend; i; ++q)
+ {
+ *q = i % 10 + '0';
+ i /= 10;
+ }
+ while ((*p++ = *--q) != '\0');;
+
+ /* The label, as a '\0' ended string, starts at symbol_name_build. */
+ return (symbol_name_build);
+}
+
+/* Decode name that may have been generated by foo_label_name() above.
+ If the name wasn't generated by foo_label_name(), then return it
+ unaltered. This is used for error messages. */
+
+char *
+decode_local_label_name (char *s)
+{
+ char *p;
+ char *symbol_decode;
+ int label_number;
+ int instance_number;
+ char *type;
+ const char *message_format;
+ int index = 0;
+
+#ifdef LOCAL_LABEL_PREFIX
+ if (s[index] == LOCAL_LABEL_PREFIX)
+ ++index;
+#endif
+
+ if (s[index] != 'L')
+ return s;
+
+ for (label_number = 0, p = s + index + 1; ISDIGIT (*p); ++p)
+ label_number = (10 * label_number) + *p - '0';
+
+ if (*p == DOLLAR_LABEL_CHAR)
+ type = "dollar";
+ else if (*p == LOCAL_LABEL_CHAR)
+ type = "fb";
+ else
+ return s;
+
+ for (instance_number = 0, p++; ISDIGIT (*p); ++p)
+ instance_number = (10 * instance_number) + *p - '0';
+
+ message_format = _("\"%d\" (instance number %d of a %s label)");
+ symbol_decode = obstack_alloc (&notes, strlen (message_format) + 30);
+ sprintf (symbol_decode, message_format, label_number, instance_number, type);
+
+ return symbol_decode;
+}
+
+/* Get the value of a symbol. */
+
+valueT
+S_GET_VALUE (symbolS *s)
+{
+#ifdef BFD_ASSEMBLER
+ if (LOCAL_SYMBOL_CHECK (s))
+ return resolve_symbol_value (s);
+#endif
+
+ if (!s->sy_resolved)
+ {
+ valueT val = resolve_symbol_value (s);
+ if (!finalize_syms)
+ return val;
+ }
+ if (s->sy_value.X_op != O_constant)
+ {
+ static symbolS *recur;
+
+ /* FIXME: In non BFD assemblers, S_IS_DEFINED and S_IS_COMMON
+ may call S_GET_VALUE. We use a static symbol to avoid the
+ immediate recursion. */
+ if (recur == s)
+ return (valueT) s->sy_value.X_add_number;
+ recur = s;
+ if (! s->sy_resolved
+ || s->sy_value.X_op != O_symbol
+ || (S_IS_DEFINED (s) && ! S_IS_COMMON (s)))
+ as_bad (_("attempt to get value of unresolved symbol `%s'"),
+ S_GET_NAME (s));
+ recur = NULL;
+ }
+ return (valueT) s->sy_value.X_add_number;
+}
+
+/* Set the value of a symbol. */
+
+void
+S_SET_VALUE (symbolS *s, valueT val)
+{
+#ifdef BFD_ASSEMBLER
+ if (LOCAL_SYMBOL_CHECK (s))
+ {
+ ((struct local_symbol *) s)->lsy_value = val;
+ return;
+ }
+#endif
+
+ s->sy_value.X_op = O_constant;
+ s->sy_value.X_add_number = (offsetT) val;
+ s->sy_value.X_unsigned = 0;
+}
+
+void
+copy_symbol_attributes (symbolS *dest, symbolS *src)
+{
+ if (LOCAL_SYMBOL_CHECK (dest))
+ dest = local_symbol_convert ((struct local_symbol *) dest);
+ if (LOCAL_SYMBOL_CHECK (src))
+ src = local_symbol_convert ((struct local_symbol *) src);
+
+#ifdef BFD_ASSEMBLER
+ /* In an expression, transfer the settings of these flags.
+ The user can override later, of course. */
+#define COPIED_SYMFLAGS (BSF_FUNCTION | BSF_OBJECT)
+ dest->bsym->flags |= src->bsym->flags & COPIED_SYMFLAGS;
+#endif
+
+#ifdef OBJ_COPY_SYMBOL_ATTRIBUTES
+ OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src);
+#endif
+}
+
+#ifdef BFD_ASSEMBLER
+
+int
+S_IS_FUNCTION (symbolS *s)
+{
+ flagword flags;
+
+ if (LOCAL_SYMBOL_CHECK (s))
+ return 0;
+
+ flags = s->bsym->flags;
+
+ return (flags & BSF_FUNCTION) != 0;
+}
+
+int
+S_IS_EXTERNAL (symbolS *s)
+{
+ flagword flags;
+
+ if (LOCAL_SYMBOL_CHECK (s))
+ return 0;
+
+ flags = s->bsym->flags;
+
+ /* Sanity check. */
+ if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL))
+ abort ();
+
+ return (flags & BSF_GLOBAL) != 0;
+}
+
+int
+S_IS_WEAK (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return 0;
+ return (s->bsym->flags & BSF_WEAK) != 0;
+}
+
+int
+S_IS_COMMON (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return 0;
+ return bfd_is_com_section (s->bsym->section);
+}
+
+int
+S_IS_DEFINED (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return ((struct local_symbol *) s)->lsy_section != undefined_section;
+ return s->bsym->section != undefined_section;
+}
+
+
+#ifndef EXTERN_FORCE_RELOC
+#define EXTERN_FORCE_RELOC IS_ELF
+#endif
+
+/* Return true for symbols that should not be reduced to section
+ symbols or eliminated from expressions, because they may be
+ overridden by the linker. */
+int
+S_FORCE_RELOC (symbolS *s, int strict)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return ((struct local_symbol *) s)->lsy_section == undefined_section;
+
+ return ((strict
+ && ((s->bsym->flags & BSF_WEAK) != 0
+ || (EXTERN_FORCE_RELOC
+ && (s->bsym->flags & BSF_GLOBAL) != 0)))
+ || s->bsym->section == undefined_section
+ || bfd_is_com_section (s->bsym->section));
+}
+
+int
+S_IS_DEBUG (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return 0;
+ if (s->bsym->flags & BSF_DEBUGGING)
+ return 1;
+ return 0;
+}
+
+int
+S_IS_LOCAL (symbolS *s)
+{
+ flagword flags;
+ const char *name;
+
+ if (LOCAL_SYMBOL_CHECK (s))
+ return 1;
+
+ flags = s->bsym->flags;
+
+ /* Sanity check. */
+ if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL))
+ abort ();
+
+ if (bfd_get_section (s->bsym) == reg_section)
+ return 1;
+
+ if (flag_strip_local_absolute
+ && (flags & BSF_GLOBAL) == 0
+ && bfd_get_section (s->bsym) == absolute_section)
+ return 1;
+
+ name = S_GET_NAME (s);
+ return (name != NULL
+ && ! S_IS_DEBUG (s)
+ && (strchr (name, DOLLAR_LABEL_CHAR)
+ || strchr (name, LOCAL_LABEL_CHAR)
+ || (! flag_keep_locals
+ && (bfd_is_local_label (stdoutput, s->bsym)
+ || (flag_mri
+ && name[0] == '?'
+ && name[1] == '?')))));
+}
+
+int
+S_IS_EXTERN (symbolS *s)
+{
+ return S_IS_EXTERNAL (s);
+}
+
+int
+S_IS_STABD (symbolS *s)
+{
+ return S_GET_NAME (s) == 0;
+}
+
+const char *
+S_GET_NAME (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return ((struct local_symbol *) s)->lsy_name;
+ return s->bsym->name;
+}
+
+segT
+S_GET_SEGMENT (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return ((struct local_symbol *) s)->lsy_section;
+ return s->bsym->section;
+}
+
+void
+S_SET_SEGMENT (symbolS *s, segT seg)
+{
+ /* Don't reassign section symbols. The direct reason is to prevent seg
+ faults assigning back to const global symbols such as *ABS*, but it
+ shouldn't happen anyway. */
+
+ if (LOCAL_SYMBOL_CHECK (s))
+ {
+ if (seg == reg_section)
+ s = local_symbol_convert ((struct local_symbol *) s);
+ else
+ {
+ ((struct local_symbol *) s)->lsy_section = seg;
+ return;
+ }
+ }
+
+ if (s->bsym->flags & BSF_SECTION_SYM)
+ {
+ if (s->bsym->section != seg)
+ abort ();
+ }
+ else
+ s->bsym->section = seg;
+}
+
+void
+S_SET_EXTERNAL (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ s = local_symbol_convert ((struct local_symbol *) s);
+ if ((s->bsym->flags & BSF_WEAK) != 0)
+ {
+ /* Let .weak override .global. */
+ return;
+ }
+ if (s->bsym->flags & BSF_SECTION_SYM)
+ {
+ char * file;
+ unsigned int line;
+
+ /* Do not reassign section symbols. */
+ as_where (& file, & line);
+ as_warn_where (file, line,
+ _("section symbols are already global"));
+ return;
+ }
+ s->bsym->flags |= BSF_GLOBAL;
+ s->bsym->flags &= ~(BSF_LOCAL | BSF_WEAK);
+}
+
+void
+S_CLEAR_EXTERNAL (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return;
+ if ((s->bsym->flags & BSF_WEAK) != 0)
+ {
+ /* Let .weak override. */
+ return;
+ }
+ s->bsym->flags |= BSF_LOCAL;
+ s->bsym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
+}
+
+void
+S_SET_WEAK (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ s = local_symbol_convert ((struct local_symbol *) s);
+ s->bsym->flags |= BSF_WEAK;
+ s->bsym->flags &= ~(BSF_GLOBAL | BSF_LOCAL);
+}
+
+void
+S_SET_THREAD_LOCAL (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ s = local_symbol_convert ((struct local_symbol *) s);
+ if (bfd_is_com_section (s->bsym->section)
+ && (s->bsym->flags & BSF_THREAD_LOCAL) != 0)
+ return;
+ s->bsym->flags |= BSF_THREAD_LOCAL;
+ if ((s->bsym->flags & BSF_FUNCTION) != 0)
+ as_bad (_("Accessing function `%s' as thread-local object"),
+ S_GET_NAME (s));
+ else if (! bfd_is_und_section (s->bsym->section)
+ && (s->bsym->section->flags & SEC_THREAD_LOCAL) == 0)
+ as_bad (_("Accessing `%s' as thread-local object"),
+ S_GET_NAME (s));
+}
+
+void
+S_SET_NAME (symbolS *s, char *name)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ {
+ ((struct local_symbol *) s)->lsy_name = name;
+ return;
+ }
+ s->bsym->name = name;
+}
+#endif /* BFD_ASSEMBLER */
+
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+
+/* Return the previous symbol in a chain. */
+
+symbolS *
+symbol_previous (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ abort ();
+ return s->sy_previous;
+}
+
+#endif /* SYMBOLS_NEED_BACKPOINTERS */
+
+/* Return the next symbol in a chain. */
+
+symbolS *
+symbol_next (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ abort ();
+ return s->sy_next;
+}
+
+/* Return a pointer to the value of a symbol as an expression. */
+
+expressionS *
+symbol_get_value_expression (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ s = local_symbol_convert ((struct local_symbol *) s);
+ return &s->sy_value;
+}
+
+/* Set the value of a symbol to an expression. */
+
+void
+symbol_set_value_expression (symbolS *s, const expressionS *exp)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ s = local_symbol_convert ((struct local_symbol *) s);
+ s->sy_value = *exp;
+}
+
+/* Set the value of SYM to the current position in the current segment. */
+
+void
+symbol_set_value_now (symbolS *sym)
+{
+ S_SET_SEGMENT (sym, now_seg);
+ S_SET_VALUE (sym, frag_now_fix ());
+ symbol_set_frag (sym, frag_now);
+}
+
+/* Set the frag of a symbol. */
+
+void
+symbol_set_frag (symbolS *s, fragS *f)
+{
+#ifdef BFD_ASSEMBLER
+ if (LOCAL_SYMBOL_CHECK (s))
+ {
+ local_symbol_set_frag ((struct local_symbol *) s, f);
+ return;
+ }
+#endif
+ s->sy_frag = f;
+}
+
+/* Return the frag of a symbol. */
+
+fragS *
+symbol_get_frag (symbolS *s)
+{
+#ifdef BFD_ASSEMBLER
+ if (LOCAL_SYMBOL_CHECK (s))
+ return local_symbol_get_frag ((struct local_symbol *) s);
+#endif
+ return s->sy_frag;
+}
+
+/* Mark a symbol as having been used. */
+
+void
+symbol_mark_used (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return;
+ s->sy_used = 1;
+}
+
+/* Clear the mark of whether a symbol has been used. */
+
+void
+symbol_clear_used (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ s = local_symbol_convert ((struct local_symbol *) s);
+ s->sy_used = 0;
+}
+
+/* Return whether a symbol has been used. */
+
+int
+symbol_used_p (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return 1;
+ return s->sy_used;
+}
+
+/* Mark a symbol as having been used in a reloc. */
+
+void
+symbol_mark_used_in_reloc (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ s = local_symbol_convert ((struct local_symbol *) s);
+ s->sy_used_in_reloc = 1;
+}
+
+/* Clear the mark of whether a symbol has been used in a reloc. */
+
+void
+symbol_clear_used_in_reloc (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return;
+ s->sy_used_in_reloc = 0;
+}
+
+/* Return whether a symbol has been used in a reloc. */
+
+int
+symbol_used_in_reloc_p (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return 0;
+ return s->sy_used_in_reloc;
+}
+
+/* Mark a symbol as an MRI common symbol. */
+
+void
+symbol_mark_mri_common (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ s = local_symbol_convert ((struct local_symbol *) s);
+ s->sy_mri_common = 1;
+}
+
+/* Clear the mark of whether a symbol is an MRI common symbol. */
+
+void
+symbol_clear_mri_common (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return;
+ s->sy_mri_common = 0;
+}
+
+/* Return whether a symbol is an MRI common symbol. */
+
+int
+symbol_mri_common_p (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return 0;
+ return s->sy_mri_common;
+}
+
+/* Mark a symbol as having been written. */
+
+void
+symbol_mark_written (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return;
+ s->written = 1;
+}
+
+/* Clear the mark of whether a symbol has been written. */
+
+void
+symbol_clear_written (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return;
+ s->written = 0;
+}
+
+/* Return whether a symbol has been written. */
+
+int
+symbol_written_p (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return 0;
+ return s->written;
+}
+
+/* Mark a symbol has having been resolved. */
+
+void
+symbol_mark_resolved (symbolS *s)
+{
+#ifdef BFD_ASSEMBLER
+ if (LOCAL_SYMBOL_CHECK (s))
+ {
+ local_symbol_mark_resolved ((struct local_symbol *) s);
+ return;
+ }
+#endif
+ s->sy_resolved = 1;
+}
+
+/* Return whether a symbol has been resolved. */
+
+int
+symbol_resolved_p (symbolS *s)
+{
+#ifdef BFD_ASSEMBLER
+ if (LOCAL_SYMBOL_CHECK (s))
+ return local_symbol_resolved_p ((struct local_symbol *) s);
+#endif
+ return s->sy_resolved;
+}
+
+/* Return whether a symbol is a section symbol. */
+
+int
+symbol_section_p (symbolS *s ATTRIBUTE_UNUSED)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return 0;
+#ifdef BFD_ASSEMBLER
+ return (s->bsym->flags & BSF_SECTION_SYM) != 0;
+#else
+ /* FIXME. */
+ return 0;
+#endif
+}
+
+/* Return whether a symbol is equated to another symbol. */
+
+int
+symbol_equated_p (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return 0;
+ return s->sy_value.X_op == O_symbol;
+}
+
+/* Return whether a symbol is equated to another symbol, and should be
+ treated specially when writing out relocs. */
+
+int
+symbol_equated_reloc_p (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return 0;
+ /* X_op_symbol, normally not used for O_symbol, is set by
+ resolve_symbol_value to flag expression syms that have been
+ equated. */
+ return (s->sy_value.X_op == O_symbol
+ && ((s->sy_resolved && s->sy_value.X_op_symbol != NULL)
+ || ! S_IS_DEFINED (s)
+ || S_IS_COMMON (s)));
+}
+
+/* Return whether a symbol has a constant value. */
+
+int
+symbol_constant_p (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return 1;
+ return s->sy_value.X_op == O_constant;
+}
+
+#ifdef BFD_ASSEMBLER
+
+/* Return the BFD symbol for a symbol. */
+
+asymbol *
+symbol_get_bfdsym (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ s = local_symbol_convert ((struct local_symbol *) s);
+ return s->bsym;
+}
+
+/* Set the BFD symbol for a symbol. */
+
+void
+symbol_set_bfdsym (symbolS *s, asymbol *bsym)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ s = local_symbol_convert ((struct local_symbol *) s);
+ s->bsym = bsym;
+}
+
+#endif /* BFD_ASSEMBLER */
+
+#ifdef OBJ_SYMFIELD_TYPE
+
+/* Get a pointer to the object format information for a symbol. */
+
+OBJ_SYMFIELD_TYPE *
+symbol_get_obj (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ s = local_symbol_convert ((struct local_symbol *) s);
+ return &s->sy_obj;
+}
+
+/* Set the object format information for a symbol. */
+
+void
+symbol_set_obj (symbolS *s, OBJ_SYMFIELD_TYPE *o)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ s = local_symbol_convert ((struct local_symbol *) s);
+ s->sy_obj = *o;
+}
+
+#endif /* OBJ_SYMFIELD_TYPE */
+
+#ifdef TC_SYMFIELD_TYPE
+
+/* Get a pointer to the processor information for a symbol. */
+
+TC_SYMFIELD_TYPE *
+symbol_get_tc (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ s = local_symbol_convert ((struct local_symbol *) s);
+ return &s->sy_tc;
+}
+
+/* Set the processor information for a symbol. */
+
+void
+symbol_set_tc (symbolS *s, TC_SYMFIELD_TYPE *o)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ s = local_symbol_convert ((struct local_symbol *) s);
+ s->sy_tc = *o;
+}
+
+#endif /* TC_SYMFIELD_TYPE */
+
+void
+symbol_begin (void)
+{
+ symbol_lastP = NULL;
+ symbol_rootP = NULL; /* In case we have 0 symbols (!!) */
+ sy_hash = hash_new ();
+#ifdef BFD_ASSEMBLER
+ local_hash = hash_new ();
+#endif
+
+ memset ((char *) (&abs_symbol), '\0', sizeof (abs_symbol));
+#ifdef BFD_ASSEMBLER
+#if defined (EMIT_SECTION_SYMBOLS) || !defined (RELOC_REQUIRES_SYMBOL)
+ abs_symbol.bsym = bfd_abs_section.symbol;
+#endif
+#else
+ /* Can't initialise a union. Sigh. */
+ S_SET_SEGMENT (&abs_symbol, absolute_section);
+#endif
+ abs_symbol.sy_value.X_op = O_constant;
+ abs_symbol.sy_frag = &zero_address_frag;
+
+ if (LOCAL_LABELS_FB)
+ fb_label_init ();
+}
+
+int indent_level;
+
+/* Maximum indent level.
+ Available for modification inside a gdb session. */
+int max_indent_level = 8;
+
+#if 0
+
+static void
+indent (void)
+{
+ printf ("%*s", indent_level * 4, "");
+}
+
+#endif
+
+void
+print_symbol_value_1 (FILE *file, symbolS *sym)
+{
+ const char *name = S_GET_NAME (sym);
+ if (!name || !name[0])
+ name = "(unnamed)";
+ fprintf (file, "sym %lx %s", (unsigned long) sym, name);
+
+ if (LOCAL_SYMBOL_CHECK (sym))
+ {
+#ifdef BFD_ASSEMBLER
+ struct local_symbol *locsym = (struct local_symbol *) sym;
+ if (local_symbol_get_frag (locsym) != &zero_address_frag
+ && local_symbol_get_frag (locsym) != NULL)
+ fprintf (file, " frag %lx", (long) local_symbol_get_frag (locsym));
+ if (local_symbol_resolved_p (locsym))
+ fprintf (file, " resolved");
+ fprintf (file, " local");
+#endif
+ }
+ else
+ {
+ if (sym->sy_frag != &zero_address_frag)
+ fprintf (file, " frag %lx", (long) sym->sy_frag);
+ if (sym->written)
+ fprintf (file, " written");
+ if (sym->sy_resolved)
+ fprintf (file, " resolved");
+ else if (sym->sy_resolving)
+ fprintf (file, " resolving");
+ if (sym->sy_used_in_reloc)
+ fprintf (file, " used-in-reloc");
+ if (sym->sy_used)
+ fprintf (file, " used");
+ if (S_IS_LOCAL (sym))
+ fprintf (file, " local");
+ if (S_IS_EXTERN (sym))
+ fprintf (file, " extern");
+ if (S_IS_DEBUG (sym))
+ fprintf (file, " debug");
+ if (S_IS_DEFINED (sym))
+ fprintf (file, " defined");
+ }
+ fprintf (file, " %s", segment_name (S_GET_SEGMENT (sym)));
+ if (symbol_resolved_p (sym))
+ {
+ segT s = S_GET_SEGMENT (sym);
+
+ if (s != undefined_section
+ && s != expr_section)
+ fprintf (file, " %lx", (long) S_GET_VALUE (sym));
+ }
+ else if (indent_level < max_indent_level
+ && S_GET_SEGMENT (sym) != undefined_section)
+ {
+ indent_level++;
+ fprintf (file, "\n%*s<", indent_level * 4, "");
+#ifdef BFD_ASSEMBLER
+ if (LOCAL_SYMBOL_CHECK (sym))
+ fprintf (file, "constant %lx",
+ (long) ((struct local_symbol *) sym)->lsy_value);
+ else
+#endif
+ print_expr_1 (file, &sym->sy_value);
+ fprintf (file, ">");
+ indent_level--;
+ }
+ fflush (file);
+}
+
+void
+print_symbol_value (symbolS *sym)
+{
+ indent_level = 0;
+ print_symbol_value_1 (stderr, sym);
+ fprintf (stderr, "\n");
+}
+
+static void
+print_binary (FILE *file, const char *name, expressionS *exp)
+{
+ indent_level++;
+ fprintf (file, "%s\n%*s<", name, indent_level * 4, "");
+ print_symbol_value_1 (file, exp->X_add_symbol);
+ fprintf (file, ">\n%*s<", indent_level * 4, "");
+ print_symbol_value_1 (file, exp->X_op_symbol);
+ fprintf (file, ">");
+ indent_level--;
+}
+
+void
+print_expr_1 (FILE *file, expressionS *exp)
+{
+ fprintf (file, "expr %lx ", (long) exp);
+ switch (exp->X_op)
+ {
+ case O_illegal:
+ fprintf (file, "illegal");
+ break;
+ case O_absent:
+ fprintf (file, "absent");
+ break;
+ case O_constant:
+ fprintf (file, "constant %lx", (long) exp->X_add_number);
+ break;
+ case O_symbol:
+ indent_level++;
+ fprintf (file, "symbol\n%*s<", indent_level * 4, "");
+ print_symbol_value_1 (file, exp->X_add_symbol);
+ fprintf (file, ">");
+ maybe_print_addnum:
+ if (exp->X_add_number)
+ fprintf (file, "\n%*s%lx", indent_level * 4, "",
+ (long) exp->X_add_number);
+ indent_level--;
+ break;
+ case O_register:
+ fprintf (file, "register #%d", (int) exp->X_add_number);
+ break;
+ case O_big:
+ fprintf (file, "big");
+ break;
+ case O_uminus:
+ fprintf (file, "uminus -<");
+ indent_level++;
+ print_symbol_value_1 (file, exp->X_add_symbol);
+ fprintf (file, ">");
+ goto maybe_print_addnum;
+ case O_bit_not:
+ fprintf (file, "bit_not");
+ break;
+ case O_multiply:
+ print_binary (file, "multiply", exp);
+ break;
+ case O_divide:
+ print_binary (file, "divide", exp);
+ break;
+ case O_modulus:
+ print_binary (file, "modulus", exp);
+ break;
+ case O_left_shift:
+ print_binary (file, "lshift", exp);
+ break;
+ case O_right_shift:
+ print_binary (file, "rshift", exp);
+ break;
+ case O_bit_inclusive_or:
+ print_binary (file, "bit_ior", exp);
+ break;
+ case O_bit_exclusive_or:
+ print_binary (file, "bit_xor", exp);
+ break;
+ case O_bit_and:
+ print_binary (file, "bit_and", exp);
+ break;
+ case O_eq:
+ print_binary (file, "eq", exp);
+ break;
+ case O_ne:
+ print_binary (file, "ne", exp);
+ break;
+ case O_lt:
+ print_binary (file, "lt", exp);
+ break;
+ case O_le:
+ print_binary (file, "le", exp);
+ break;
+ case O_ge:
+ print_binary (file, "ge", exp);
+ break;
+ case O_gt:
+ print_binary (file, "gt", exp);
+ break;
+ case O_logical_and:
+ print_binary (file, "logical_and", exp);
+ break;
+ case O_logical_or:
+ print_binary (file, "logical_or", exp);
+ break;
+ case O_add:
+ indent_level++;
+ fprintf (file, "add\n%*s<", indent_level * 4, "");
+ print_symbol_value_1 (file, exp->X_add_symbol);
+ fprintf (file, ">\n%*s<", indent_level * 4, "");
+ print_symbol_value_1 (file, exp->X_op_symbol);
+ fprintf (file, ">");
+ goto maybe_print_addnum;
+ case O_subtract:
+ indent_level++;
+ fprintf (file, "subtract\n%*s<", indent_level * 4, "");
+ print_symbol_value_1 (file, exp->X_add_symbol);
+ fprintf (file, ">\n%*s<", indent_level * 4, "");
+ print_symbol_value_1 (file, exp->X_op_symbol);
+ fprintf (file, ">");
+ goto maybe_print_addnum;
+ default:
+ fprintf (file, "{unknown opcode %d}", (int) exp->X_op);
+ break;
+ }
+ fflush (stdout);
+}
+
+void
+print_expr (expressionS *exp)
+{
+ print_expr_1 (stderr, exp);
+ fprintf (stderr, "\n");
+}
+
+void
+symbol_print_statistics (FILE *file)
+{
+ hash_print_statistics (file, "symbol table", sy_hash);
+#ifdef BFD_ASSEMBLER
+ hash_print_statistics (file, "mini local symbol table", local_hash);
+ fprintf (file, "%lu mini local symbols created, %lu converted\n",
+ local_symbol_count, local_symbol_conversion_count);
+#endif
+}
diff --git a/x/binutils/gas/symbols.h b/x/binutils/gas/symbols.h
new file mode 100644
index 0000000..15dc263
--- /dev/null
+++ b/x/binutils/gas/symbols.h
@@ -0,0 +1,213 @@
+/* symbols.h -
+ Copyright 1987, 1990, 1992, 1993, 1994, 1995, 1997, 1999, 2000, 2001,
+ 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifdef BFD_ASSEMBLER
+/* The BFD code wants to walk the list in both directions. */
+#undef SYMBOLS_NEED_BACKPOINTERS
+#define SYMBOLS_NEED_BACKPOINTERS
+#endif
+
+#ifndef BFD_ASSEMBLER
+/* The non-BFD code expects to be able to manipulate the symbol fields
+ directly. */
+#include "struc-symbol.h"
+#endif
+
+extern struct obstack notes; /* eg FixS live here. */
+
+extern struct obstack cond_obstack; /* this is where we track .ifdef/.endif
+ (if we do that at all). */
+
+extern symbolS *symbol_rootP; /* all the symbol nodes */
+extern symbolS *symbol_lastP; /* last struct symbol we made, or NULL */
+
+extern symbolS abs_symbol;
+
+extern int symbol_table_frozen;
+
+/* This is non-zero if symbols are case sensitive, which is the
+ default. */
+extern int symbols_case_sensitive;
+
+char *decode_local_label_name (char *s);
+symbolS *symbol_find (const char *name);
+symbolS *symbol_find_exact (const char *name);
+symbolS *symbol_find_base (const char *name, int strip_underscore);
+symbolS *symbol_find_or_make (const char *name);
+symbolS *symbol_make (const char *name);
+symbolS *symbol_new (const char *name, segT segment, valueT value,
+ fragS * frag);
+symbolS *symbol_create (const char *name, segT segment, valueT value,
+ fragS * frag);
+struct local_symbol *local_symbol_make (const char *name, segT section,
+ valueT value, fragS * frag);
+symbolS *symbol_temp_new (segT, valueT, fragS *);
+symbolS *symbol_temp_new_now (void);
+symbolS *symbol_temp_make (void);
+
+symbolS *colon (const char *sym_name);
+void local_colon (int n);
+void symbol_begin (void);
+void symbol_print_statistics (FILE *);
+void symbol_table_insert (symbolS * symbolP);
+valueT resolve_symbol_value (symbolS *);
+void resolve_local_symbol_values (void);
+
+void print_symbol_value (symbolS *);
+void print_expr (expressionS *);
+void print_expr_1 (FILE *, expressionS *);
+void print_symbol_value_1 (FILE *, symbolS *);
+
+int dollar_label_defined (long l);
+void dollar_label_clear (void);
+void define_dollar_label (long l);
+char *dollar_label_name (long l, int augend);
+
+void fb_label_instance_inc (long label);
+char *fb_label_name (long n, long augend);
+
+extern void copy_symbol_attributes (symbolS *, symbolS *);
+
+/* Get and set the values of symbols. These used to be macros. */
+extern valueT S_GET_VALUE (symbolS *);
+extern void S_SET_VALUE (symbolS *, valueT);
+
+#ifdef BFD_ASSEMBLER
+extern int S_IS_FUNCTION (symbolS *);
+extern int S_IS_EXTERNAL (symbolS *);
+extern int S_IS_WEAK (symbolS *);
+extern int S_IS_COMMON (symbolS *);
+extern int S_IS_DEFINED (symbolS *);
+extern int S_FORCE_RELOC (symbolS *, int);
+extern int S_IS_DEBUG (symbolS *);
+extern int S_IS_LOCAL (symbolS *);
+extern int S_IS_EXTERN (symbolS *);
+extern int S_IS_STABD (symbolS *);
+extern const char *S_GET_NAME (symbolS *);
+extern segT S_GET_SEGMENT (symbolS *);
+extern void S_SET_SEGMENT (symbolS *, segT);
+extern void S_SET_EXTERNAL (symbolS *);
+extern void S_SET_NAME (symbolS *, char *);
+extern void S_CLEAR_EXTERNAL (symbolS *);
+extern void S_SET_WEAK (symbolS *);
+extern void S_SET_THREAD_LOCAL (symbolS *);
+#endif
+
+#ifndef WORKING_DOT_WORD
+struct broken_word
+ {
+ /* Linked list -- one of these structures per ".word x-y+C"
+ expression. */
+ struct broken_word *next_broken_word;
+ /* Segment and subsegment for broken word. */
+ segT seg;
+ subsegT subseg;
+ /* Which frag is this broken word in? */
+ fragS *frag;
+ /* Where in the frag is it? */
+ char *word_goes_here;
+ /* Where to add the break. */
+ fragS *dispfrag; /* where to add the break */
+ /* Operands of expression. */
+ symbolS *add;
+ symbolS *sub;
+ offsetT addnum;
+
+ int added; /* nasty thing happened yet? */
+ /* 1: added and has a long-jump */
+ /* 2: added but uses someone elses long-jump */
+
+ /* Pointer to broken_word with a similar long-jump. */
+ struct broken_word *use_jump;
+ };
+extern struct broken_word *broken_words;
+#endif /* ndef WORKING_DOT_WORD */
+
+/*
+ * Current means for getting from symbols to segments and vice verse.
+ * This will change for infinite-segments support (e.g. COFF).
+ */
+extern const segT N_TYPE_seg[]; /* subseg.c */
+
+#define SEGMENT_TO_SYMBOL_TYPE(seg) ( seg_N_TYPE [(int) (seg)] )
+extern const short seg_N_TYPE[];/* subseg.c */
+
+#define N_REGISTER 30 /* Fake N_TYPE value for SEG_REGISTER */
+
+void symbol_clear_list_pointers (symbolS * symbolP);
+
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+
+void symbol_insert (symbolS * addme, symbolS * target,
+ symbolS ** rootP, symbolS ** lastP);
+void symbol_remove (symbolS * symbolP, symbolS ** rootP,
+ symbolS ** lastP);
+
+extern symbolS *symbol_previous (symbolS *);
+
+#endif /* SYMBOLS_NEED_BACKPOINTERS */
+
+void verify_symbol_chain (symbolS * rootP, symbolS * lastP);
+void verify_symbol_chain_2 (symbolS * symP);
+
+void symbol_append (symbolS * addme, symbolS * target,
+ symbolS ** rootP, symbolS ** lastP);
+
+extern symbolS *symbol_next (symbolS *);
+
+extern expressionS *symbol_get_value_expression (symbolS *);
+extern void symbol_set_value_expression (symbolS *, const expressionS *);
+extern void symbol_set_value_now (symbolS *);
+extern void symbol_set_frag (symbolS *, fragS *);
+extern fragS *symbol_get_frag (symbolS *);
+extern void symbol_mark_used (symbolS *);
+extern void symbol_clear_used (symbolS *);
+extern int symbol_used_p (symbolS *);
+extern void symbol_mark_used_in_reloc (symbolS *);
+extern void symbol_clear_used_in_reloc (symbolS *);
+extern int symbol_used_in_reloc_p (symbolS *);
+extern void symbol_mark_mri_common (symbolS *);
+extern void symbol_clear_mri_common (symbolS *);
+extern int symbol_mri_common_p (symbolS *);
+extern void symbol_mark_written (symbolS *);
+extern void symbol_clear_written (symbolS *);
+extern int symbol_written_p (symbolS *);
+extern void symbol_mark_resolved (symbolS *);
+extern int symbol_resolved_p (symbolS *);
+extern int symbol_section_p (symbolS *);
+extern int symbol_equated_p (symbolS *);
+extern int symbol_equated_reloc_p (symbolS *);
+extern int symbol_constant_p (symbolS *);
+
+#ifdef BFD_ASSEMBLER
+extern asymbol *symbol_get_bfdsym (symbolS *);
+extern void symbol_set_bfdsym (symbolS *, asymbol *);
+#endif
+
+#ifdef OBJ_SYMFIELD_TYPE
+OBJ_SYMFIELD_TYPE *symbol_get_obj (symbolS *);
+void symbol_set_obj (symbolS *, OBJ_SYMFIELD_TYPE *);
+#endif
+
+#ifdef TC_SYMFIELD_TYPE
+TC_SYMFIELD_TYPE *symbol_get_tc (symbolS *);
+void symbol_set_tc (symbolS *, TC_SYMFIELD_TYPE *);
+#endif
diff --git a/x/binutils/gas/tc.h b/x/binutils/gas/tc.h
new file mode 100644
index 0000000..5d7b44d
--- /dev/null
+++ b/x/binutils/gas/tc.h
@@ -0,0 +1,93 @@
+/* tc.h - target cpu dependent
+
+ Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 2000, 2001, 2003
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* In theory (mine, at least!) the machine dependent part of the assembler
+ should only have to include one file. This one. -- JF */
+
+extern const pseudo_typeS md_pseudo_table[];
+
+extern const int md_reloc_size; /* Size of a relocation record */
+
+char *md_atof (int what_statement_type, char *literalP, int *sizeP);
+#ifndef md_estimate_size_before_relax
+int md_estimate_size_before_relax (fragS * fragP, segT segment);
+#endif
+int md_parse_option (int c, char *arg);
+void md_show_usage (FILE *);
+#ifndef md_pcrel_from
+long md_pcrel_from (fixS * fixP);
+#endif
+short tc_coff_fix2rtype (fixS * fixP);
+void md_assemble (char *str);
+void md_begin (void);
+#ifndef md_create_long_jump
+void md_create_long_jump (char *ptr, addressT from_addr,
+ addressT to_addr, fragS * frag,
+ symbolS * to_symbol);
+#endif
+#ifndef md_create_short_jump
+void md_create_short_jump (char *ptr, addressT from_addr,
+ addressT to_addr, fragS * frag,
+ symbolS * to_symbol);
+#endif
+void md_number_to_chars (char *buf, valueT val, int n);
+
+#ifndef md_operand
+void md_operand (expressionS * expressionP);
+#endif
+
+void md_apply_fix3 (fixS *, valueT *, segT);
+
+#ifdef BFD_ASSEMBLER
+#ifndef md_convert_frag
+void md_convert_frag (bfd * headers, segT sec, fragS * fragP);
+#endif
+#ifndef tc_headers_hook
+void tc_headers_hook (segT *, fixS *);
+#endif
+#ifndef RELOC_EXPANSION_POSSIBLE
+extern arelent *tc_gen_reloc (asection *, fixS *);
+#else
+extern arelent **tc_gen_reloc (asection *, fixS *);
+#endif
+#else /* not BFD_ASSEMBLER */
+#ifndef md_convert_frag
+void md_convert_frag (object_headers * headers, segT, fragS * fragP);
+#endif
+
+#ifndef tc_crawl_symbol_chain
+void tc_crawl_symbol_chain (object_headers * headers);
+#endif /* tc_crawl_symbol_chain */
+
+#ifndef tc_headers_hook
+void tc_headers_hook (object_headers * headers);
+#endif /* tc_headers_hook */
+#endif /* BFD_ASSEMBLER */
+
+#ifndef md_section_align
+valueT md_section_align (segT seg, valueT size);
+#endif
+
+#ifndef md_undefined_symbol
+symbolS *md_undefined_symbol (char *name);
+#endif
+
+/* end of tc.h */
diff --git a/x/binutils/gas/write.c b/x/binutils/gas/write.c
new file mode 100644
index 0000000..5acd607
--- /dev/null
+++ b/x/binutils/gas/write.c
@@ -0,0 +1,2839 @@
+/* write.c - emit .o file
+ Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This thing should be set up to do byteordering correctly. But... */
+
+#include "as.h"
+#include "subsegs.h"
+#include "obstack.h"
+#include "output-file.h"
+#include "dwarf2dbg.h"
+
+#ifndef TC_ADJUST_RELOC_COUNT
+#define TC_ADJUST_RELOC_COUNT(FIX, COUNT)
+#endif
+
+#ifndef TC_FORCE_RELOCATION
+#define TC_FORCE_RELOCATION(FIX) \
+ (generic_force_reloc (FIX))
+#endif
+
+#ifndef TC_FORCE_RELOCATION_ABS
+#define TC_FORCE_RELOCATION_ABS(FIX) \
+ (TC_FORCE_RELOCATION (FIX))
+#endif
+
+#ifndef TC_FORCE_RELOCATION_LOCAL
+#define TC_FORCE_RELOCATION_LOCAL(FIX) \
+ (!(FIX)->fx_pcrel \
+ || (FIX)->fx_plt \
+ || TC_FORCE_RELOCATION (FIX))
+#endif
+
+#ifndef TC_FORCE_RELOCATION_SUB_SAME
+#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEG) \
+ (! SEG_NORMAL (SEG))
+#endif
+
+#ifndef TC_FORCE_RELOCATION_SUB_ABS
+#define TC_FORCE_RELOCATION_SUB_ABS(FIX) 0
+#endif
+
+#ifndef TC_FORCE_RELOCATION_SUB_LOCAL
+#ifdef DIFF_EXPR_OK
+#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX) 0
+#else
+#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX) 1
+#endif
+#endif
+
+#ifndef TC_VALIDATE_FIX_SUB
+#ifdef UNDEFINED_DIFFERENCE_OK
+/* The PA needs this for PIC code generation. */
+#define TC_VALIDATE_FIX_SUB(FIX) 1
+#else
+#ifdef BFD_ASSEMBLER
+#define TC_VALIDATE_FIX_SUB(FIX) \
+ ((FIX)->fx_r_type == BFD_RELOC_GPREL32 \
+ || (FIX)->fx_r_type == BFD_RELOC_GPREL16)
+#else
+#define TC_VALIDATE_FIX_SUB(FIX) 0
+#endif
+#endif
+#endif
+
+#ifndef TC_LINKRELAX_FIXUP
+#define TC_LINKRELAX_FIXUP(SEG) 1
+#endif
+
+#ifndef MD_APPLY_SYM_VALUE
+#define MD_APPLY_SYM_VALUE(FIX) 1
+#endif
+
+#ifndef TC_FINALIZE_SYMS_BEFORE_SIZE_SEG
+#define TC_FINALIZE_SYMS_BEFORE_SIZE_SEG 1
+#endif
+
+#ifndef MD_PCREL_FROM_SECTION
+#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from (FIX)
+#endif
+
+#ifndef WORKING_DOT_WORD
+extern const int md_short_jump_size;
+extern const int md_long_jump_size;
+#endif
+
+/* Used to control final evaluation of expressions. */
+int finalize_syms = 0;
+
+int symbol_table_frozen;
+
+symbolS *abs_section_sym;
+
+/* Remember the value of dot when parsing expressions. */
+addressT dot_value;
+
+void print_fixup (fixS *);
+
+#ifdef BFD_ASSEMBLER
+static void renumber_sections (bfd *, asection *, PTR);
+
+/* We generally attach relocs to frag chains. However, after we have
+ chained these all together into a segment, any relocs we add after
+ that must be attached to a segment. This will include relocs added
+ in md_estimate_size_for_relax, for example. */
+static int frags_chained = 0;
+#endif
+
+#ifndef BFD_ASSEMBLER
+
+#ifndef MANY_SEGMENTS
+struct frag *text_frag_root;
+struct frag *data_frag_root;
+struct frag *bss_frag_root;
+
+struct frag *text_last_frag; /* Last frag in segment. */
+struct frag *data_last_frag; /* Last frag in segment. */
+static struct frag *bss_last_frag; /* Last frag in segment. */
+#endif
+
+#ifndef BFD
+static object_headers headers;
+#endif
+
+long string_byte_count;
+char *next_object_file_charP; /* Tracks object file bytes. */
+
+#ifndef OBJ_VMS
+int magic_number_for_object_file = DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE;
+#endif
+
+#endif /* BFD_ASSEMBLER */
+
+static int n_fixups;
+
+#ifdef BFD_ASSEMBLER
+#define RELOC_ENUM enum bfd_reloc_code_real
+#else
+#define RELOC_ENUM int
+#endif
+
+static fixS *fix_new_internal (fragS *, int where, int size,
+ symbolS *add, symbolS *sub,
+ offsetT offset, int pcrel,
+ RELOC_ENUM r_type);
+#if defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS))
+static long fixup_segment (fixS *, segT);
+#endif
+static relax_addressT relax_align (relax_addressT addr, int align);
+#if defined (BFD_ASSEMBLER) || ! defined (BFD)
+static fragS *chain_frchains_together_1 (segT, struct frchain *);
+#endif
+#ifdef BFD_ASSEMBLER
+static void chain_frchains_together (bfd *, segT, PTR);
+static void cvt_frag_to_fill (segT, fragS *);
+static void adjust_reloc_syms (bfd *, asection *, PTR);
+static void fix_segment (bfd *, asection *, PTR);
+static void write_relocs (bfd *, asection *, PTR);
+static void write_contents (bfd *, asection *, PTR);
+static void set_symtab (void);
+#endif
+#if defined (BFD_ASSEMBLER) || (! defined (BFD) && ! defined (OBJ_AOUT))
+static void merge_data_into_text (void);
+#endif
+#if ! defined (BFD_ASSEMBLER) && ! defined (BFD)
+static void cvt_frag_to_fill (object_headers *, segT, fragS *);
+static void remove_subsegs (frchainS *, int, fragS **, fragS **);
+static void relax_and_size_all_segments (void);
+#endif
+
+/* Create a fixS in obstack 'notes'. */
+
+static fixS *
+fix_new_internal (fragS *frag, /* Which frag? */
+ int where, /* Where in that frag? */
+ int size, /* 1, 2, or 4 usually. */
+ symbolS *add_symbol, /* X_add_symbol. */
+ symbolS *sub_symbol, /* X_op_symbol. */
+ offsetT offset, /* X_add_number. */
+ int pcrel, /* TRUE if PC-relative relocation. */
+ RELOC_ENUM r_type ATTRIBUTE_UNUSED /* Relocation type. */)
+{
+ fixS *fixP;
+
+ n_fixups++;
+
+ fixP = (fixS *) obstack_alloc (&notes, sizeof (fixS));
+
+ fixP->fx_frag = frag;
+ fixP->fx_where = where;
+ fixP->fx_size = size;
+ /* We've made fx_size a narrow field; check that it's wide enough. */
+ if (fixP->fx_size != size)
+ {
+ as_bad (_("field fx_size too small to hold %d"), size);
+ abort ();
+ }
+ fixP->fx_addsy = add_symbol;
+ fixP->fx_subsy = sub_symbol;
+ fixP->fx_offset = offset;
+ fixP->fx_dot_value = dot_value;
+ fixP->fx_pcrel = pcrel;
+ fixP->fx_plt = 0;
+#if defined(NEED_FX_R_TYPE) || defined (BFD_ASSEMBLER)
+ fixP->fx_r_type = r_type;
+#endif
+ fixP->fx_im_disp = 0;
+ fixP->fx_pcrel_adjust = 0;
+ fixP->fx_bit_fixP = 0;
+ fixP->fx_addnumber = 0;
+ fixP->fx_tcbit = 0;
+ fixP->fx_done = 0;
+ fixP->fx_no_overflow = 0;
+ fixP->fx_signed = 0;
+
+#ifdef USING_CGEN
+ fixP->fx_cgen.insn = NULL;
+ fixP->fx_cgen.opinfo = 0;
+#endif
+
+#ifdef TC_FIX_TYPE
+ TC_INIT_FIX_DATA (fixP);
+#endif
+
+ as_where (&fixP->fx_file, &fixP->fx_line);
+
+ /* Usually, we want relocs sorted numerically, but while
+ comparing to older versions of gas that have relocs
+ reverse sorted, it is convenient to have this compile
+ time option. xoxorich. */
+ {
+
+#ifdef BFD_ASSEMBLER
+ fixS **seg_fix_rootP = (frags_chained
+ ? &seg_info (now_seg)->fix_root
+ : &frchain_now->fix_root);
+ fixS **seg_fix_tailP = (frags_chained
+ ? &seg_info (now_seg)->fix_tail
+ : &frchain_now->fix_tail);
+#endif
+
+#ifdef REVERSE_SORT_RELOCS
+
+ fixP->fx_next = *seg_fix_rootP;
+ *seg_fix_rootP = fixP;
+
+#else /* REVERSE_SORT_RELOCS */
+
+ fixP->fx_next = NULL;
+
+ if (*seg_fix_tailP)
+ (*seg_fix_tailP)->fx_next = fixP;
+ else
+ *seg_fix_rootP = fixP;
+ *seg_fix_tailP = fixP;
+
+#endif /* REVERSE_SORT_RELOCS */
+ }
+
+ return fixP;
+}
+
+/* Create a fixup relative to a symbol (plus a constant). */
+
+fixS *
+fix_new (fragS *frag, /* Which frag? */
+ int where, /* Where in that frag? */
+ int size, /* 1, 2, or 4 usually. */
+ symbolS *add_symbol, /* X_add_symbol. */
+ offsetT offset, /* X_add_number. */
+ int pcrel, /* TRUE if PC-relative relocation. */
+ RELOC_ENUM r_type /* Relocation type. */)
+{
+ return fix_new_internal (frag, where, size, add_symbol,
+ (symbolS *) NULL, offset, pcrel, r_type);
+}
+
+/* Create a fixup for an expression. Currently we only support fixups
+ for difference expressions. That is itself more than most object
+ file formats support anyhow. */
+
+fixS *
+fix_new_exp (fragS *frag, /* Which frag? */
+ int where, /* Where in that frag? */
+ int size, /* 1, 2, or 4 usually. */
+ expressionS *exp, /* Expression. */
+ int pcrel, /* TRUE if PC-relative relocation. */
+ RELOC_ENUM r_type /* Relocation type. */)
+{
+ symbolS *add = NULL;
+ symbolS *sub = NULL;
+ offsetT off = 0;
+
+ switch (exp->X_op)
+ {
+ case O_absent:
+ break;
+
+ case O_register:
+ as_bad (_("register value used as expression"));
+ break;
+
+ case O_add:
+ /* This comes up when _GLOBAL_OFFSET_TABLE_+(.-L0) is read, if
+ the difference expression cannot immediately be reduced. */
+ {
+ symbolS *stmp = make_expr_symbol (exp);
+
+ exp->X_op = O_symbol;
+ exp->X_op_symbol = 0;
+ exp->X_add_symbol = stmp;
+ exp->X_add_number = 0;
+
+ return fix_new_exp (frag, where, size, exp, pcrel, r_type);
+ }
+
+ case O_symbol_rva:
+ add = exp->X_add_symbol;
+ off = exp->X_add_number;
+
+#if defined(BFD_ASSEMBLER)
+ r_type = BFD_RELOC_RVA;
+#else
+#if defined(TC_RVA_RELOC)
+ r_type = TC_RVA_RELOC;
+#else
+ as_fatal (_("rva not supported"));
+#endif
+#endif
+ break;
+
+ case O_uminus:
+ sub = exp->X_add_symbol;
+ off = exp->X_add_number;
+ break;
+
+ case O_subtract:
+ sub = exp->X_op_symbol;
+ /* Fall through. */
+ case O_symbol:
+ add = exp->X_add_symbol;
+ /* Fall through. */
+ case O_constant:
+ off = exp->X_add_number;
+ break;
+
+ default:
+ add = make_expr_symbol (exp);
+ break;
+ }
+
+ return fix_new_internal (frag, where, size, add, sub, off, pcrel, r_type);
+}
+
+/* Generic function to determine whether a fixup requires a relocation. */
+int
+generic_force_reloc (fixS *fix)
+{
+#ifdef BFD_ASSEMBLER
+ if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 1;
+#endif
+ return S_FORCE_RELOC (fix->fx_addsy, fix->fx_subsy == NULL);
+}
+
+/* Append a string onto another string, bumping the pointer along. */
+void
+append (char **charPP, char *fromP, unsigned long length)
+{
+ /* Don't trust memcpy() of 0 chars. */
+ if (length == 0)
+ return;
+
+ memcpy (*charPP, fromP, length);
+ *charPP += length;
+}
+
+#ifndef BFD_ASSEMBLER
+int section_alignment[SEG_MAXIMUM_ORDINAL];
+#endif
+
+/* This routine records the largest alignment seen for each segment.
+ If the beginning of the segment is aligned on the worst-case
+ boundary, all of the other alignments within it will work. At
+ least one object format really uses this info. */
+
+void
+record_alignment (/* Segment to which alignment pertains. */
+ segT seg,
+ /* Alignment, as a power of 2 (e.g., 1 => 2-byte
+ boundary, 2 => 4-byte boundary, etc.) */
+ int align)
+{
+ if (seg == absolute_section)
+ return;
+#ifdef BFD_ASSEMBLER
+ if ((unsigned int) align > bfd_get_section_alignment (stdoutput, seg))
+ bfd_set_section_alignment (stdoutput, seg, align);
+#else
+ if (align > section_alignment[(int) seg])
+ section_alignment[(int) seg] = align;
+#endif
+}
+
+int
+get_recorded_alignment (segT seg)
+{
+ if (seg == absolute_section)
+ return 0;
+#ifdef BFD_ASSEMBLER
+ return bfd_get_section_alignment (stdoutput, seg);
+#else
+ return section_alignment[(int) seg];
+#endif
+}
+
+#ifdef BFD_ASSEMBLER
+
+/* Reset the section indices after removing the gas created sections. */
+
+static void
+renumber_sections (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, PTR countparg)
+{
+ int *countp = (int *) countparg;
+
+ sec->index = *countp;
+ ++*countp;
+}
+
+#endif /* defined (BFD_ASSEMBLER) */
+
+#if defined (BFD_ASSEMBLER) || ! defined (BFD)
+
+static fragS *
+chain_frchains_together_1 (segT section, struct frchain *frchp)
+{
+ fragS dummy, *prev_frag = &dummy;
+#ifdef BFD_ASSEMBLER
+ fixS fix_dummy, *prev_fix = &fix_dummy;
+#endif
+
+ for (; frchp && frchp->frch_seg == section; frchp = frchp->frch_next)
+ {
+ prev_frag->fr_next = frchp->frch_root;
+ prev_frag = frchp->frch_last;
+ assert (prev_frag->fr_type != 0);
+#ifdef BFD_ASSEMBLER
+ if (frchp->fix_root != (fixS *) NULL)
+ {
+ if (seg_info (section)->fix_root == (fixS *) NULL)
+ seg_info (section)->fix_root = frchp->fix_root;
+ prev_fix->fx_next = frchp->fix_root;
+ seg_info (section)->fix_tail = frchp->fix_tail;
+ prev_fix = frchp->fix_tail;
+ }
+#endif
+ }
+ assert (prev_frag->fr_type != 0);
+ prev_frag->fr_next = 0;
+ return prev_frag;
+}
+
+#endif
+
+#ifdef BFD_ASSEMBLER
+
+static void
+chain_frchains_together (bfd *abfd ATTRIBUTE_UNUSED,
+ segT section,
+ PTR xxx ATTRIBUTE_UNUSED)
+{
+ segment_info_type *info;
+
+ /* BFD may have introduced its own sections without using
+ subseg_new, so it is possible that seg_info is NULL. */
+ info = seg_info (section);
+ if (info != (segment_info_type *) NULL)
+ info->frchainP->frch_last
+ = chain_frchains_together_1 (section, info->frchainP);
+
+ /* Now that we've chained the frags together, we must add new fixups
+ to the segment, not to the frag chain. */
+ frags_chained = 1;
+}
+
+#endif
+
+#if !defined (BFD) && !defined (BFD_ASSEMBLER)
+
+static void
+remove_subsegs (frchainS *head, int seg, fragS **root, fragS **last)
+{
+ *root = head->frch_root;
+ *last = chain_frchains_together_1 (seg, head);
+}
+
+#endif /* BFD */
+
+#if defined (BFD_ASSEMBLER) || !defined (BFD)
+
+#ifdef BFD_ASSEMBLER
+static void
+cvt_frag_to_fill (segT sec ATTRIBUTE_UNUSED, fragS *fragP)
+#else
+static void
+cvt_frag_to_fill (object_headers *headersP, segT sec, fragS *fragP)
+#endif
+{
+ switch (fragP->fr_type)
+ {
+ case rs_align:
+ case rs_align_code:
+ case rs_align_test:
+ case rs_org:
+ case rs_space:
+#ifdef HANDLE_ALIGN
+ HANDLE_ALIGN (fragP);
+#endif
+ know (fragP->fr_next != NULL);
+ fragP->fr_offset = (fragP->fr_next->fr_address
+ - fragP->fr_address
+ - fragP->fr_fix) / fragP->fr_var;
+ if (fragP->fr_offset < 0)
+ {
+ as_bad_where (fragP->fr_file, fragP->fr_line,
+ _("attempt to .org/.space backwards? (%ld)"),
+ (long) fragP->fr_offset);
+ fragP->fr_offset = 0;
+ }
+ fragP->fr_type = rs_fill;
+ break;
+
+ case rs_fill:
+ break;
+
+ case rs_leb128:
+ {
+ valueT value = S_GET_VALUE (fragP->fr_symbol);
+ int size;
+
+ size = output_leb128 (fragP->fr_literal + fragP->fr_fix, value,
+ fragP->fr_subtype);
+
+ fragP->fr_fix += size;
+ fragP->fr_type = rs_fill;
+ fragP->fr_var = 0;
+ fragP->fr_offset = 0;
+ fragP->fr_symbol = NULL;
+ }
+ break;
+
+ case rs_cfa:
+ eh_frame_convert_frag (fragP);
+ break;
+
+ case rs_dwarf2dbg:
+ dwarf2dbg_convert_frag (fragP);
+ break;
+
+ case rs_machine_dependent:
+#ifdef BFD_ASSEMBLER
+ md_convert_frag (stdoutput, sec, fragP);
+#else
+ md_convert_frag (headersP, sec, fragP);
+#endif
+
+ assert (fragP->fr_next == NULL
+ || ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
+ == fragP->fr_fix));
+
+ /* After md_convert_frag, we make the frag into a ".space 0".
+ md_convert_frag() should set up any fixSs and constants
+ required. */
+ frag_wane (fragP);
+ break;
+
+#ifndef WORKING_DOT_WORD
+ case rs_broken_word:
+ {
+ struct broken_word *lie;
+
+ if (fragP->fr_subtype)
+ {
+ fragP->fr_fix += md_short_jump_size;
+ for (lie = (struct broken_word *) (fragP->fr_symbol);
+ lie && lie->dispfrag == fragP;
+ lie = lie->next_broken_word)
+ if (lie->added == 1)
+ fragP->fr_fix += md_long_jump_size;
+ }
+ frag_wane (fragP);
+ }
+ break;
+#endif
+
+ default:
+ BAD_CASE (fragP->fr_type);
+ break;
+ }
+}
+
+#endif /* defined (BFD_ASSEMBLER) || !defined (BFD) */
+
+#ifdef BFD_ASSEMBLER
+static void relax_seg (bfd *, asection *, PTR);
+
+static void
+relax_seg (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, PTR xxx)
+{
+ segment_info_type *seginfo = seg_info (sec);
+
+ if (seginfo && seginfo->frchainP
+ && relax_segment (seginfo->frchainP->frch_root, sec))
+ {
+ int *result = (int *) xxx;
+ *result = 1;
+ }
+}
+
+static void size_seg (bfd *, asection *, PTR);
+
+static void
+size_seg (bfd *abfd, asection *sec, PTR xxx ATTRIBUTE_UNUSED)
+{
+ flagword flags;
+ fragS *fragp;
+ segment_info_type *seginfo;
+ int x;
+ valueT size, newsize;
+
+ subseg_change (sec, 0);
+
+ seginfo = seg_info (sec);
+ if (seginfo && seginfo->frchainP)
+ {
+ for (fragp = seginfo->frchainP->frch_root; fragp; fragp = fragp->fr_next)
+ cvt_frag_to_fill (sec, fragp);
+ for (fragp = seginfo->frchainP->frch_root;
+ fragp->fr_next;
+ fragp = fragp->fr_next)
+ /* Walk to last elt. */
+ ;
+ size = fragp->fr_address + fragp->fr_fix;
+ }
+ else
+ size = 0;
+
+ flags = bfd_get_section_flags (abfd, sec);
+
+ if (size > 0 && ! seginfo->bss)
+ flags |= SEC_HAS_CONTENTS;
+
+ /* @@ This is just an approximation. */
+ if (seginfo && seginfo->fix_root)
+ flags |= SEC_RELOC;
+ else
+ flags &= ~SEC_RELOC;
+ x = bfd_set_section_flags (abfd, sec, flags);
+ assert (x);
+
+ newsize = md_section_align (sec, size);
+ x = bfd_set_section_size (abfd, sec, newsize);
+ assert (x);
+
+ /* If the size had to be rounded up, add some padding in the last
+ non-empty frag. */
+ assert (newsize >= size);
+ if (size != newsize)
+ {
+ fragS *last = seginfo->frchainP->frch_last;
+ fragp = seginfo->frchainP->frch_root;
+ while (fragp->fr_next != last)
+ fragp = fragp->fr_next;
+ last->fr_address = size;
+ if ((newsize - size) % fragp->fr_var == 0)
+ fragp->fr_offset += (newsize - size) / fragp->fr_var;
+ else
+ /* If we hit this abort, it's likely due to subsegs_finish not
+ providing sufficient alignment on the last frag, and the
+ machine dependent code using alignment frags with fr_var
+ greater than 1. */
+ abort ();
+ }
+
+#ifdef tc_frob_section
+ tc_frob_section (sec);
+#endif
+#ifdef obj_frob_section
+ obj_frob_section (sec);
+#endif
+}
+
+#ifdef DEBUG2
+static void
+dump_section_relocs (abfd, sec, stream_)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *sec;
+ char *stream_;
+{
+ FILE *stream = (FILE *) stream_;
+ segment_info_type *seginfo = seg_info (sec);
+ fixS *fixp = seginfo->fix_root;
+
+ if (!fixp)
+ return;
+
+ fprintf (stream, "sec %s relocs:\n", sec->name);
+ while (fixp)
+ {
+ symbolS *s = fixp->fx_addsy;
+
+ fprintf (stream, " %08lx: type %d ", (unsigned long) fixp,
+ (int) fixp->fx_r_type);
+ if (s == NULL)
+ fprintf (stream, "no sym\n");
+ else
+ {
+ print_symbol_value_1 (stream, s);
+ fprintf (stream, "\n");
+ }
+ fixp = fixp->fx_next;
+ }
+}
+#else
+#define dump_section_relocs(ABFD,SEC,STREAM) ((void) 0)
+#endif
+
+#ifndef EMIT_SECTION_SYMBOLS
+#define EMIT_SECTION_SYMBOLS 1
+#endif
+
+/* This pass over fixups decides whether symbols can be replaced with
+ section symbols. */
+
+static void
+adjust_reloc_syms (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ PTR xxx ATTRIBUTE_UNUSED)
+{
+ segment_info_type *seginfo = seg_info (sec);
+ fixS *fixp;
+
+ if (seginfo == NULL)
+ return;
+
+ dump_section_relocs (abfd, sec, stderr);
+
+ for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
+ if (fixp->fx_done)
+ /* Ignore it. */
+ ;
+ else if (fixp->fx_addsy)
+ {
+ symbolS *sym;
+ asection *symsec;
+
+#ifdef DEBUG5
+ fprintf (stderr, "\n\nadjusting fixup:\n");
+ print_fixup (fixp);
+#endif
+
+ sym = fixp->fx_addsy;
+
+ /* All symbols should have already been resolved at this
+ point. It is possible to see unresolved expression
+ symbols, though, since they are not in the regular symbol
+ table. */
+ resolve_symbol_value (sym);
+
+ if (fixp->fx_subsy != NULL)
+ resolve_symbol_value (fixp->fx_subsy);
+
+ /* If this symbol is equated to an undefined symbol, convert
+ the fixup to being against that symbol. */
+ if (symbol_equated_reloc_p (sym))
+ {
+ fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number;
+ sym = symbol_get_value_expression (sym)->X_add_symbol;
+ fixp->fx_addsy = sym;
+ }
+
+ if (symbol_mri_common_p (sym))
+ {
+ /* These symbols are handled specially in fixup_segment. */
+ continue;
+ }
+
+ /* If the symbol is undefined, common, weak, or global (ELF
+ shared libs), we can't replace it with the section symbol. */
+ if (S_FORCE_RELOC (fixp->fx_addsy, 1))
+ continue;
+
+ /* Is there some other (target cpu dependent) reason we can't adjust
+ this one? (E.g. relocations involving function addresses on
+ the PA. */
+#ifdef tc_fix_adjustable
+ if (! tc_fix_adjustable (fixp))
+ continue;
+#endif
+
+ /* Since we're reducing to section symbols, don't attempt to reduce
+ anything that's already using one. */
+ if (symbol_section_p (sym))
+ continue;
+
+ symsec = S_GET_SEGMENT (sym);
+ if (symsec == NULL)
+ abort ();
+
+ if (bfd_is_abs_section (symsec))
+ {
+ /* The fixup_segment routine normally will not use this
+ symbol in a relocation. */
+ continue;
+ }
+
+ /* Don't try to reduce relocs which refer to non-local symbols
+ in .linkonce sections. It can lead to confusion when a
+ debugging section refers to a .linkonce section. I hope
+ this will always be correct. */
+ if (symsec != sec && ! S_IS_LOCAL (sym))
+ {
+ if ((symsec->flags & SEC_LINK_ONCE) != 0
+ || (IS_ELF
+ /* The GNU toolchain uses an extension for ELF: a
+ section beginning with the magic string
+ .gnu.linkonce is a linkonce section. */
+ && strncmp (segment_name (symsec), ".gnu.linkonce",
+ sizeof ".gnu.linkonce" - 1) == 0))
+ continue;
+ }
+
+ /* Never adjust a reloc against local symbol in a merge section
+ with non-zero addend. */
+ if ((symsec->flags & SEC_MERGE) != 0
+ && (fixp->fx_offset != 0 || fixp->fx_subsy != NULL))
+ continue;
+
+ /* Never adjust a reloc against TLS local symbol. */
+ if ((symsec->flags & SEC_THREAD_LOCAL) != 0)
+ continue;
+
+ /* We refetch the segment when calling section_symbol, rather
+ than using symsec, because S_GET_VALUE may wind up changing
+ the section when it calls resolve_symbol_value. */
+ fixp->fx_offset += S_GET_VALUE (sym);
+ fixp->fx_addsy = section_symbol (S_GET_SEGMENT (sym));
+#ifdef DEBUG5
+ fprintf (stderr, "\nadjusted fixup:\n");
+ print_fixup (fixp);
+#endif
+ }
+
+ dump_section_relocs (abfd, sec, stderr);
+}
+
+static void
+fix_segment (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ PTR xxx ATTRIBUTE_UNUSED)
+{
+ segment_info_type *seginfo = seg_info (sec);
+
+ fixup_segment (seginfo->fix_root, sec);
+}
+
+static void
+write_relocs (bfd *abfd, asection *sec, PTR xxx ATTRIBUTE_UNUSED)
+{
+ segment_info_type *seginfo = seg_info (sec);
+ unsigned int i;
+ unsigned int n;
+ arelent **relocs;
+ fixS *fixp;
+ char *err;
+
+ /* If seginfo is NULL, we did not create this section; don't do
+ anything with it. */
+ if (seginfo == NULL)
+ return;
+
+ n = 0;
+ for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
+ n++;
+
+#ifndef RELOC_EXPANSION_POSSIBLE
+ /* Set up reloc information as well. */
+ relocs = (arelent **) xcalloc (n, sizeof (arelent *));
+
+ i = 0;
+ for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
+ {
+ arelent *reloc;
+ bfd_reloc_status_type s;
+ symbolS *sym;
+
+ if (fixp->fx_done)
+ {
+ n--;
+ continue;
+ }
+
+ /* If this is an undefined symbol which was equated to another
+ symbol, then generate the reloc against the latter symbol
+ rather than the former. */
+ sym = fixp->fx_addsy;
+ while (symbol_equated_reloc_p (sym))
+ {
+ symbolS *n;
+
+ /* We must avoid looping, as that can occur with a badly
+ written program. */
+ n = symbol_get_value_expression (sym)->X_add_symbol;
+ if (n == sym)
+ break;
+ fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number;
+ sym = n;
+ }
+ fixp->fx_addsy = sym;
+
+ reloc = tc_gen_reloc (sec, fixp);
+ if (!reloc)
+ {
+ n--;
+ continue;
+ }
+
+#if 0
+ /* This test is triggered inappropriately for the SH. */
+ if (fixp->fx_where + fixp->fx_size
+ > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
+ abort ();
+#endif
+
+ s = bfd_install_relocation (stdoutput, reloc,
+ fixp->fx_frag->fr_literal,
+ fixp->fx_frag->fr_address,
+ sec, &err);
+ switch (s)
+ {
+ case bfd_reloc_ok:
+ break;
+ case bfd_reloc_overflow:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("relocation overflow"));
+ break;
+ case bfd_reloc_outofrange:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("relocation out of range"));
+ break;
+ default:
+ as_fatal (_("%s:%u: bad return from bfd_install_relocation: %x"),
+ fixp->fx_file, fixp->fx_line, s);
+ }
+ relocs[i++] = reloc;
+ }
+#else
+ n = n * MAX_RELOC_EXPANSION;
+ /* Set up reloc information as well. */
+ relocs = (arelent **) xcalloc (n, sizeof (arelent *));
+
+ i = 0;
+ for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
+ {
+ arelent **reloc;
+ bfd_reloc_status_type s;
+ symbolS *sym;
+ int j;
+
+ if (fixp->fx_done)
+ {
+ n--;
+ continue;
+ }
+
+ /* If this is an undefined symbol which was equated to another
+ symbol, then generate the reloc against the latter symbol
+ rather than the former. */
+ sym = fixp->fx_addsy;
+ while (symbol_equated_reloc_p (sym))
+ {
+ symbolS *n;
+
+ /* We must avoid looping, as that can occur with a badly
+ written program. */
+ n = symbol_get_value_expression (sym)->X_add_symbol;
+ if (n == sym)
+ break;
+ fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number;
+ sym = n;
+ }
+ fixp->fx_addsy = sym;
+
+ reloc = tc_gen_reloc (sec, fixp);
+
+ for (j = 0; reloc[j]; j++)
+ {
+ relocs[i++] = reloc[j];
+ assert (i <= n);
+ }
+ if (fixp->fx_where + fixp->fx_size
+ > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("internal error: fixup not contained within frag"));
+ for (j = 0; reloc[j]; j++)
+ {
+ s = bfd_install_relocation (stdoutput, reloc[j],
+ fixp->fx_frag->fr_literal,
+ fixp->fx_frag->fr_address,
+ sec, &err);
+ switch (s)
+ {
+ case bfd_reloc_ok:
+ break;
+ case bfd_reloc_overflow:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("relocation overflow"));
+ break;
+ case bfd_reloc_outofrange:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("relocation out of range"));
+ break;
+ default:
+ as_fatal (_("%s:%u: bad return from bfd_install_relocation: %x"),
+ fixp->fx_file, fixp->fx_line, s);
+ }
+ }
+ }
+ n = i;
+#endif
+
+#ifdef DEBUG4
+ {
+ int i, j, nsyms;
+ asymbol **sympp;
+ sympp = bfd_get_outsymbols (stdoutput);
+ nsyms = bfd_get_symcount (stdoutput);
+ for (i = 0; i < n; i++)
+ if (((*relocs[i]->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0)
+ {
+ for (j = 0; j < nsyms; j++)
+ if (sympp[j] == *relocs[i]->sym_ptr_ptr)
+ break;
+ if (j == nsyms)
+ abort ();
+ }
+ }
+#endif
+
+ if (n)
+ bfd_set_reloc (stdoutput, sec, relocs, n);
+ else
+ bfd_set_section_flags (abfd, sec,
+ (bfd_get_section_flags (abfd, sec)
+ & (flagword) ~SEC_RELOC));
+
+#ifdef SET_SECTION_RELOCS
+ SET_SECTION_RELOCS (sec, relocs, n);
+#endif
+
+#ifdef DEBUG3
+ {
+ int i;
+ arelent *r;
+ asymbol *s;
+ fprintf (stderr, "relocs for sec %s\n", sec->name);
+ for (i = 0; i < n; i++)
+ {
+ r = relocs[i];
+ s = *r->sym_ptr_ptr;
+ fprintf (stderr, " reloc %2d @%08x off %4x : sym %-10s addend %x\n",
+ i, r, r->address, s->name, r->addend);
+ }
+ }
+#endif
+}
+
+static void
+write_contents (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ PTR xxx ATTRIBUTE_UNUSED)
+{
+ segment_info_type *seginfo = seg_info (sec);
+ addressT offset = 0;
+ fragS *f;
+
+ /* Write out the frags. */
+ if (seginfo == NULL
+ || !(bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS))
+ return;
+
+ for (f = seginfo->frchainP->frch_root;
+ f;
+ f = f->fr_next)
+ {
+ int x;
+ addressT fill_size;
+ char *fill_literal;
+ offsetT count;
+
+ assert (f->fr_type == rs_fill);
+ if (f->fr_fix)
+ {
+ x = bfd_set_section_contents (stdoutput, sec,
+ f->fr_literal, (file_ptr) offset,
+ (bfd_size_type) f->fr_fix);
+ if (!x)
+ {
+ bfd_perror (stdoutput->filename);
+ as_perror (_("FATAL: Can't write %s"), stdoutput->filename);
+ exit (EXIT_FAILURE);
+ }
+ offset += f->fr_fix;
+ }
+ fill_literal = f->fr_literal + f->fr_fix;
+ fill_size = f->fr_var;
+ count = f->fr_offset;
+ assert (count >= 0);
+ if (fill_size && count)
+ {
+ char buf[256];
+ if (fill_size > sizeof (buf))
+ {
+ /* Do it the old way. Can this ever happen? */
+ while (count--)
+ {
+ x = bfd_set_section_contents (stdoutput, sec,
+ fill_literal,
+ (file_ptr) offset,
+ (bfd_size_type) fill_size);
+ if (!x)
+ {
+ bfd_perror (stdoutput->filename);
+ as_perror (_("FATAL: Can't write %s"),
+ stdoutput->filename);
+ exit (EXIT_FAILURE);
+ }
+ offset += fill_size;
+ }
+ }
+ else
+ {
+ /* Build a buffer full of fill objects and output it as
+ often as necessary. This saves on the overhead of
+ potentially lots of bfd_set_section_contents calls. */
+ int n_per_buf, i;
+ if (fill_size == 1)
+ {
+ n_per_buf = sizeof (buf);
+ memset (buf, *fill_literal, n_per_buf);
+ }
+ else
+ {
+ char *bufp;
+ n_per_buf = sizeof (buf) / fill_size;
+ for (i = n_per_buf, bufp = buf; i; i--, bufp += fill_size)
+ memcpy (bufp, fill_literal, fill_size);
+ }
+ for (; count > 0; count -= n_per_buf)
+ {
+ n_per_buf = n_per_buf > count ? count : n_per_buf;
+ x = bfd_set_section_contents
+ (stdoutput, sec, buf, (file_ptr) offset,
+ (bfd_size_type) n_per_buf * fill_size);
+ if (!x)
+ as_fatal (_("cannot write to output file"));
+ offset += n_per_buf * fill_size;
+ }
+ }
+ }
+ }
+}
+#endif
+
+#if defined(BFD_ASSEMBLER) || (!defined (BFD) && !defined(OBJ_AOUT))
+static void
+merge_data_into_text (void)
+{
+#if defined(BFD_ASSEMBLER) || defined(MANY_SEGMENTS)
+ seg_info (text_section)->frchainP->frch_last->fr_next =
+ seg_info (data_section)->frchainP->frch_root;
+ seg_info (text_section)->frchainP->frch_last =
+ seg_info (data_section)->frchainP->frch_last;
+ seg_info (data_section)->frchainP = 0;
+#else
+ fixS *tmp;
+
+ text_last_frag->fr_next = data_frag_root;
+ text_last_frag = data_last_frag;
+ data_last_frag = NULL;
+ data_frag_root = NULL;
+ if (text_fix_root)
+ {
+ for (tmp = text_fix_root; tmp->fx_next; tmp = tmp->fx_next);;
+ tmp->fx_next = data_fix_root;
+ text_fix_tail = data_fix_tail;
+ }
+ else
+ text_fix_root = data_fix_root;
+ data_fix_root = NULL;
+#endif
+}
+#endif /* BFD_ASSEMBLER || (! BFD && ! OBJ_AOUT) */
+
+#if !defined (BFD_ASSEMBLER) && !defined (BFD)
+static void
+relax_and_size_all_segments ()
+{
+ fragS *fragP;
+
+ relax_segment (text_frag_root, SEG_TEXT);
+ relax_segment (data_frag_root, SEG_DATA);
+ relax_segment (bss_frag_root, SEG_BSS);
+
+ /* Now the addresses of frags are correct within the segment. */
+ know (text_last_frag->fr_type == rs_fill && text_last_frag->fr_offset == 0);
+ H_SET_TEXT_SIZE (&headers, text_last_frag->fr_address);
+ text_last_frag->fr_address = H_GET_TEXT_SIZE (&headers);
+
+ /* Join the 2 segments into 1 huge segment.
+ To do this, re-compute every rn_address in the SEG_DATA frags.
+ Then join the data frags after the text frags.
+
+ Determine a_data [length of data segment]. */
+ if (data_frag_root)
+ {
+ register relax_addressT slide;
+
+ know ((text_last_frag->fr_type == rs_fill)
+ && (text_last_frag->fr_offset == 0));
+
+ H_SET_DATA_SIZE (&headers, data_last_frag->fr_address);
+ data_last_frag->fr_address = H_GET_DATA_SIZE (&headers);
+ slide = H_GET_TEXT_SIZE (&headers); /* & in file of the data segment. */
+#ifdef OBJ_BOUT
+#define RoundUp(N,S) (((N)+(S)-1)&-(S))
+ /* For b.out: If the data section has a strict alignment
+ requirement, its load address in the .o file will be
+ rounded up from the size of the text section. These
+ two values are *not* the same! Similarly for the bss
+ section.... */
+ slide = RoundUp (slide, 1 << section_alignment[SEG_DATA]);
+#endif
+
+ for (fragP = data_frag_root; fragP; fragP = fragP->fr_next)
+ fragP->fr_address += slide;
+
+ know (text_last_frag != 0);
+ text_last_frag->fr_next = data_frag_root;
+ }
+ else
+ {
+ H_SET_DATA_SIZE (&headers, 0);
+ }
+
+#ifdef OBJ_BOUT
+ /* See above comments on b.out data section address. */
+ {
+ addressT bss_vma;
+ if (data_last_frag == 0)
+ bss_vma = H_GET_TEXT_SIZE (&headers);
+ else
+ bss_vma = data_last_frag->fr_address;
+ bss_vma = RoundUp (bss_vma, 1 << section_alignment[SEG_BSS]);
+ bss_address_frag.fr_address = bss_vma;
+ }
+#else /* ! OBJ_BOUT */
+ bss_address_frag.fr_address = (H_GET_TEXT_SIZE (&headers) +
+ H_GET_DATA_SIZE (&headers));
+
+#endif /* ! OBJ_BOUT */
+
+ /* Slide all the frags. */
+ if (bss_frag_root)
+ {
+ relax_addressT slide = bss_address_frag.fr_address;
+
+ for (fragP = bss_frag_root; fragP; fragP = fragP->fr_next)
+ fragP->fr_address += slide;
+ }
+
+ if (bss_last_frag)
+ H_SET_BSS_SIZE (&headers,
+ bss_last_frag->fr_address - bss_frag_root->fr_address);
+ else
+ H_SET_BSS_SIZE (&headers, 0);
+}
+#endif /* ! BFD_ASSEMBLER && ! BFD */
+
+#if defined (BFD_ASSEMBLER) || !defined (BFD)
+
+#ifdef BFD_ASSEMBLER
+static void
+set_symtab (void)
+{
+ int nsyms;
+ asymbol **asympp;
+ symbolS *symp;
+ bfd_boolean result;
+ extern PTR bfd_alloc (bfd *, bfd_size_type);
+
+ /* Count symbols. We can't rely on a count made by the loop in
+ write_object_file, because *_frob_file may add a new symbol or
+ two. */
+ nsyms = 0;
+ for (symp = symbol_rootP; symp; symp = symbol_next (symp))
+ nsyms++;
+
+ if (nsyms)
+ {
+ int i;
+ bfd_size_type amt = (bfd_size_type) nsyms * sizeof (asymbol *);
+
+ asympp = (asymbol **) bfd_alloc (stdoutput, amt);
+ symp = symbol_rootP;
+ for (i = 0; i < nsyms; i++, symp = symbol_next (symp))
+ {
+ asympp[i] = symbol_get_bfdsym (symp);
+ symbol_mark_written (symp);
+ }
+ }
+ else
+ asympp = 0;
+ result = bfd_set_symtab (stdoutput, asympp, nsyms);
+ assert (result);
+ symbol_table_frozen = 1;
+}
+#endif
+
+/* Finish the subsegments. After every sub-segment, we fake an
+ ".align ...". This conforms to BSD4.2 brane-damage. We then fake
+ ".fill 0" because that is the kind of frag that requires least
+ thought. ".align" frags like to have a following frag since that
+ makes calculating their intended length trivial. */
+
+#ifndef SUB_SEGMENT_ALIGN
+#ifdef HANDLE_ALIGN
+/* The last subsegment gets an alignment corresponding to the alignment
+ of the section. This allows proper nop-filling at the end of
+ code-bearing sections. */
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \
+ (!(FRCHAIN)->frch_next || (FRCHAIN)->frch_next->frch_seg != (SEG) \
+ ? get_recorded_alignment (SEG) : 0)
+#else
+#ifdef BFD_ASSEMBLER
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
+#else
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 2
+#endif
+#endif
+#endif
+
+void
+subsegs_finish (void)
+{
+ struct frchain *frchainP;
+
+ for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next)
+ {
+ int alignment = 0;
+
+ subseg_set (frchainP->frch_seg, frchainP->frch_subseg);
+
+ /* This now gets called even if we had errors. In that case,
+ any alignment is meaningless, and, moreover, will look weird
+ if we are generating a listing. */
+ if (!had_errors ())
+ {
+ alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP);
+#ifdef BFD_ASSEMBLER
+ if ((bfd_get_section_flags (now_seg->owner, now_seg) & SEC_MERGE)
+ && now_seg->entsize)
+ {
+ unsigned int entsize = now_seg->entsize;
+ int entalign = 0;
+
+ while ((entsize & 1) == 0)
+ {
+ ++entalign;
+ entsize >>= 1;
+ }
+ if (entalign > alignment)
+ alignment = entalign;
+ }
+#endif
+ }
+
+ if (subseg_text_p (now_seg))
+ frag_align_code (alignment, 0);
+ else
+ frag_align (alignment, 0, 0);
+
+ /* frag_align will have left a new frag.
+ Use this last frag for an empty ".fill".
+
+ For this segment ...
+ Create a last frag. Do not leave a "being filled in frag". */
+ frag_wane (frag_now);
+ frag_now->fr_fix = 0;
+ know (frag_now->fr_next == NULL);
+ }
+}
+
+/* Write the object file. */
+
+void
+write_object_file (void)
+{
+#if ! defined (BFD_ASSEMBLER) || ! defined (WORKING_DOT_WORD)
+ fragS *fragP; /* Track along all frags. */
+#endif
+
+ /* Do we really want to write it? */
+ {
+ int n_warns, n_errs;
+ n_warns = had_warnings ();
+ n_errs = had_errors ();
+ /* The -Z flag indicates that an object file should be generated,
+ regardless of warnings and errors. */
+ if (flag_always_generate_output)
+ {
+ if (n_warns || n_errs)
+ as_warn (_("%d error%s, %d warning%s, generating bad object file"),
+ n_errs, n_errs == 1 ? "" : "s",
+ n_warns, n_warns == 1 ? "" : "s");
+ }
+ else
+ {
+ if (n_errs)
+ as_fatal (_("%d error%s, %d warning%s, no object file generated"),
+ n_errs, n_errs == 1 ? "" : "s",
+ n_warns, n_warns == 1 ? "" : "s");
+ }
+ }
+
+#ifdef OBJ_VMS
+ /* Under VMS we try to be compatible with VAX-11 "C". Thus, we call
+ a routine to check for the definition of the procedure "_main",
+ and if so -- fix it up so that it can be program entry point. */
+ vms_check_for_main ();
+#endif /* OBJ_VMS */
+
+ /* From now on, we don't care about sub-segments. Build one frag chain
+ for each segment. Linked thru fr_next. */
+
+#ifdef BFD_ASSEMBLER
+ /* Remove the sections created by gas for its own purposes. */
+ {
+ asection **seclist;
+ int i;
+
+ seclist = &stdoutput->sections;
+ while (*seclist)
+ {
+ if (*seclist == reg_section || *seclist == expr_section)
+ {
+ bfd_section_list_remove (stdoutput, seclist);
+ stdoutput->section_count--;
+ }
+ else
+ seclist = &(*seclist)->next;
+ }
+ i = 0;
+ bfd_map_over_sections (stdoutput, renumber_sections, &i);
+ }
+
+ bfd_map_over_sections (stdoutput, chain_frchains_together, (char *) 0);
+#else
+ remove_subsegs (frchain_root, SEG_TEXT, &text_frag_root, &text_last_frag);
+ remove_subsegs (data0_frchainP, SEG_DATA, &data_frag_root, &data_last_frag);
+ remove_subsegs (bss0_frchainP, SEG_BSS, &bss_frag_root, &bss_last_frag);
+#endif
+
+ /* We have two segments. If user gave -R flag, then we must put the
+ data frags into the text segment. Do this before relaxing so
+ we know to take advantage of -R and make shorter addresses. */
+#if !defined (OBJ_AOUT) || defined (BFD_ASSEMBLER)
+ if (flag_readonly_data_in_text)
+ {
+ merge_data_into_text ();
+ }
+#endif
+
+#ifdef BFD_ASSEMBLER
+ while (1)
+ {
+ int changed;
+
+#ifndef WORKING_DOT_WORD
+ /* We need to reset the markers in the broken word list and
+ associated frags between calls to relax_segment (via
+ relax_seg). Since the broken word list is global, we do it
+ once per round, rather than locally in relax_segment for each
+ segment. */
+ struct broken_word *brokp;
+
+ for (brokp = broken_words;
+ brokp != (struct broken_word *) NULL;
+ brokp = brokp->next_broken_word)
+ {
+ brokp->added = 0;
+
+ if (brokp->dispfrag != (fragS *) NULL
+ && brokp->dispfrag->fr_type == rs_broken_word)
+ brokp->dispfrag->fr_subtype = 0;
+ }
+#endif
+
+ changed = 0;
+ bfd_map_over_sections (stdoutput, relax_seg, &changed);
+ if (!changed)
+ break;
+ }
+
+ /* Note - Most ports will use the default value of
+ TC_FINALIZE_SYMS_BEFORE_SIZE_SEG, which 1. This will force
+ local symbols to be resolved, removing their frag information.
+ Some ports however, will not have finished relaxing all of
+ their frags and will still need the local symbol frag
+ information. These ports can set
+ TC_FINALIZE_SYMS_BEFORE_SIZE_SEG to 0. */
+ finalize_syms = TC_FINALIZE_SYMS_BEFORE_SIZE_SEG;
+
+ bfd_map_over_sections (stdoutput, size_seg, (char *) 0);
+#else
+ relax_and_size_all_segments ();
+#endif /* BFD_ASSEMBLER */
+
+ /* Relaxation has completed. Freeze all syms. */
+ finalize_syms = 1;
+
+#ifdef md_post_relax_hook
+ md_post_relax_hook;
+#endif
+
+#ifndef BFD_ASSEMBLER
+ /* Crawl the symbol chain.
+
+ For each symbol whose value depends on a frag, take the address of
+ that frag and subsume it into the value of the symbol.
+ After this, there is just one way to lookup a symbol value.
+ Values are left in their final state for object file emission.
+ We adjust the values of 'L' local symbols, even if we do
+ not intend to emit them to the object file, because their values
+ are needed for fix-ups.
+
+ Unless we saw a -L flag, remove all symbols that begin with 'L'
+ from the symbol chain. (They are still pointed to by the fixes.)
+
+ Count the remaining symbols.
+ Assign a symbol number to each symbol.
+ Count the number of string-table chars we will emit.
+ Put this info into the headers as appropriate. */
+ know (zero_address_frag.fr_address == 0);
+ string_byte_count = sizeof (string_byte_count);
+
+ obj_crawl_symbol_chain (&headers);
+
+ if (string_byte_count == sizeof (string_byte_count))
+ string_byte_count = 0;
+
+ H_SET_STRING_SIZE (&headers, string_byte_count);
+
+ /* Addresses of frags now reflect addresses we use in the object file.
+ Symbol values are correct.
+ Scan the frags, converting any ".org"s and ".align"s to ".fill"s.
+ Also converting any machine-dependent frags using md_convert_frag(); */
+ subseg_change (SEG_TEXT, 0);
+
+ for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
+ {
+ /* At this point we have linked all the frags into a single
+ chain. However, cvt_frag_to_fill may call md_convert_frag
+ which may call fix_new. We need to ensure that fix_new adds
+ the fixup to the right section. */
+ if (fragP == data_frag_root)
+ subseg_change (SEG_DATA, 0);
+
+ cvt_frag_to_fill (&headers, SEG_TEXT, fragP);
+
+ /* Some assert macros don't work with # directives mixed in. */
+#ifndef NDEBUG
+ if (!(fragP->fr_next == NULL
+#ifdef OBJ_BOUT
+ || fragP->fr_next == data_frag_root
+#endif
+ || ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
+ == (fragP->fr_fix + fragP->fr_offset * fragP->fr_var))))
+ abort ();
+#endif
+ }
+#endif /* ! BFD_ASSEMBLER */
+
+#ifndef WORKING_DOT_WORD
+ {
+ struct broken_word *lie;
+ struct broken_word **prevP;
+
+ prevP = &broken_words;
+ for (lie = broken_words; lie; lie = lie->next_broken_word)
+ if (!lie->added)
+ {
+ expressionS exp;
+
+ subseg_change (lie->seg, lie->subseg);
+ exp.X_op = O_subtract;
+ exp.X_add_symbol = lie->add;
+ exp.X_op_symbol = lie->sub;
+ exp.X_add_number = lie->addnum;
+#ifdef BFD_ASSEMBLER
+#ifdef TC_CONS_FIX_NEW
+ TC_CONS_FIX_NEW (lie->frag,
+ lie->word_goes_here - lie->frag->fr_literal,
+ 2, &exp);
+#else
+ fix_new_exp (lie->frag,
+ lie->word_goes_here - lie->frag->fr_literal,
+ 2, &exp, 0, BFD_RELOC_16);
+#endif
+#else
+#if defined(TC_SPARC) || defined(TC_A29K) || defined(NEED_FX_R_TYPE)
+ fix_new_exp (lie->frag,
+ lie->word_goes_here - lie->frag->fr_literal,
+ 2, &exp, 0, NO_RELOC);
+#else
+#ifdef TC_NS32K
+ fix_new_ns32k_exp (lie->frag,
+ lie->word_goes_here - lie->frag->fr_literal,
+ 2, &exp, 0, 0, 2, 0, 0);
+#else
+ fix_new_exp (lie->frag,
+ lie->word_goes_here - lie->frag->fr_literal,
+ 2, &exp, 0, 0);
+#endif /* TC_NS32K */
+#endif /* TC_SPARC|TC_A29K|NEED_FX_R_TYPE */
+#endif /* BFD_ASSEMBLER */
+ *prevP = lie->next_broken_word;
+ }
+ else
+ prevP = &(lie->next_broken_word);
+
+ for (lie = broken_words; lie;)
+ {
+ struct broken_word *untruth;
+ char *table_ptr;
+ addressT table_addr;
+ addressT from_addr, to_addr;
+ int n, m;
+
+ subseg_change (lie->seg, lie->subseg);
+ fragP = lie->dispfrag;
+
+ /* Find out how many broken_words go here. */
+ n = 0;
+ for (untruth = lie;
+ untruth && untruth->dispfrag == fragP;
+ untruth = untruth->next_broken_word)
+ if (untruth->added == 1)
+ n++;
+
+ table_ptr = lie->dispfrag->fr_opcode;
+ table_addr = (lie->dispfrag->fr_address
+ + (table_ptr - lie->dispfrag->fr_literal));
+ /* Create the jump around the long jumps. This is a short
+ jump from table_ptr+0 to table_ptr+n*long_jump_size. */
+ from_addr = table_addr;
+ to_addr = table_addr + md_short_jump_size + n * md_long_jump_size;
+ md_create_short_jump (table_ptr, from_addr, to_addr, lie->dispfrag,
+ lie->add);
+ table_ptr += md_short_jump_size;
+ table_addr += md_short_jump_size;
+
+ for (m = 0;
+ lie && lie->dispfrag == fragP;
+ m++, lie = lie->next_broken_word)
+ {
+ if (lie->added == 2)
+ continue;
+ /* Patch the jump table. */
+ /* This is the offset from ??? to table_ptr+0. */
+ to_addr = table_addr - S_GET_VALUE (lie->sub);
+#ifdef TC_CHECK_ADJUSTED_BROKEN_DOT_WORD
+ TC_CHECK_ADJUSTED_BROKEN_DOT_WORD (to_addr, lie);
+#endif
+ md_number_to_chars (lie->word_goes_here, to_addr, 2);
+ for (untruth = lie->next_broken_word;
+ untruth && untruth->dispfrag == fragP;
+ untruth = untruth->next_broken_word)
+ {
+ if (untruth->use_jump == lie)
+ md_number_to_chars (untruth->word_goes_here, to_addr, 2);
+ }
+
+ /* Install the long jump. */
+ /* This is a long jump from table_ptr+0 to the final target. */
+ from_addr = table_addr;
+ to_addr = S_GET_VALUE (lie->add) + lie->addnum;
+ md_create_long_jump (table_ptr, from_addr, to_addr, lie->dispfrag,
+ lie->add);
+ table_ptr += md_long_jump_size;
+ table_addr += md_long_jump_size;
+ }
+ }
+ }
+#endif /* not WORKING_DOT_WORD */
+
+#ifndef BFD_ASSEMBLER
+#ifndef OBJ_VMS
+ { /* not vms */
+ char *the_object_file;
+ long object_file_size;
+ /* Scan every FixS performing fixups. We had to wait until now to
+ do this because md_convert_frag() may have made some fixSs. */
+ int trsize, drsize;
+
+ subseg_change (SEG_TEXT, 0);
+ trsize = md_reloc_size * fixup_segment (text_fix_root, SEG_TEXT);
+ subseg_change (SEG_DATA, 0);
+ drsize = md_reloc_size * fixup_segment (data_fix_root, SEG_DATA);
+ H_SET_RELOCATION_SIZE (&headers, trsize, drsize);
+
+ /* FIXME: Move this stuff into the pre-write-hook. */
+ H_SET_MAGIC_NUMBER (&headers, magic_number_for_object_file);
+ H_SET_ENTRY_POINT (&headers, 0);
+
+ obj_pre_write_hook (&headers); /* Extra coff stuff. */
+
+ object_file_size = H_GET_FILE_SIZE (&headers);
+ next_object_file_charP = the_object_file = xmalloc (object_file_size);
+
+ output_file_create (out_file_name);
+
+ obj_header_append (&next_object_file_charP, &headers);
+
+ know ((next_object_file_charP - the_object_file)
+ == H_GET_HEADER_SIZE (&headers));
+
+ /* Emit code. */
+ for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
+ {
+ register long count;
+ register char *fill_literal;
+ register long fill_size;
+
+ PROGRESS (1);
+ know (fragP->fr_type == rs_fill);
+ append (&next_object_file_charP, fragP->fr_literal,
+ (unsigned long) fragP->fr_fix);
+ fill_literal = fragP->fr_literal + fragP->fr_fix;
+ fill_size = fragP->fr_var;
+ know (fragP->fr_offset >= 0);
+
+ for (count = fragP->fr_offset; count; count--)
+ append (&next_object_file_charP, fill_literal,
+ (unsigned long) fill_size);
+ }
+
+ know ((next_object_file_charP - the_object_file)
+ == (H_GET_HEADER_SIZE (&headers)
+ + H_GET_TEXT_SIZE (&headers)
+ + H_GET_DATA_SIZE (&headers)));
+
+ /* Emit relocations. */
+ obj_emit_relocations (&next_object_file_charP, text_fix_root,
+ (relax_addressT) 0);
+ know ((next_object_file_charP - the_object_file)
+ == (H_GET_HEADER_SIZE (&headers)
+ + H_GET_TEXT_SIZE (&headers)
+ + H_GET_DATA_SIZE (&headers)
+ + H_GET_TEXT_RELOCATION_SIZE (&headers)));
+#ifdef TC_I960
+ /* Make addresses in data relocation directives relative to beginning of
+ first data fragment, not end of last text fragment: alignment of the
+ start of the data segment may place a gap between the segments. */
+ obj_emit_relocations (&next_object_file_charP, data_fix_root,
+ data0_frchainP->frch_root->fr_address);
+#else /* TC_I960 */
+ obj_emit_relocations (&next_object_file_charP, data_fix_root,
+ text_last_frag->fr_address);
+#endif /* TC_I960 */
+
+ know ((next_object_file_charP - the_object_file)
+ == (H_GET_HEADER_SIZE (&headers)
+ + H_GET_TEXT_SIZE (&headers)
+ + H_GET_DATA_SIZE (&headers)
+ + H_GET_TEXT_RELOCATION_SIZE (&headers)
+ + H_GET_DATA_RELOCATION_SIZE (&headers)));
+
+ /* Emit line number entries. */
+ OBJ_EMIT_LINENO (&next_object_file_charP, lineno_rootP, the_object_file);
+ know ((next_object_file_charP - the_object_file)
+ == (H_GET_HEADER_SIZE (&headers)
+ + H_GET_TEXT_SIZE (&headers)
+ + H_GET_DATA_SIZE (&headers)
+ + H_GET_TEXT_RELOCATION_SIZE (&headers)
+ + H_GET_DATA_RELOCATION_SIZE (&headers)
+ + H_GET_LINENO_SIZE (&headers)));
+
+ /* Emit symbols. */
+ obj_emit_symbols (&next_object_file_charP, symbol_rootP);
+ know ((next_object_file_charP - the_object_file)
+ == (H_GET_HEADER_SIZE (&headers)
+ + H_GET_TEXT_SIZE (&headers)
+ + H_GET_DATA_SIZE (&headers)
+ + H_GET_TEXT_RELOCATION_SIZE (&headers)
+ + H_GET_DATA_RELOCATION_SIZE (&headers)
+ + H_GET_LINENO_SIZE (&headers)
+ + H_GET_SYMBOL_TABLE_SIZE (&headers)));
+
+ /* Emit strings. */
+ if (string_byte_count > 0)
+ obj_emit_strings (&next_object_file_charP);
+
+#ifdef BFD_HEADERS
+ bfd_seek (stdoutput, (file_ptr) 0, 0);
+ bfd_bwrite (the_object_file, (bfd_size_type) object_file_size, stdoutput);
+#else
+
+ /* Write the data to the file. */
+ output_file_append (the_object_file, object_file_size, out_file_name);
+ free (the_object_file);
+#endif
+ }
+#else /* OBJ_VMS */
+ /* Now do the VMS-dependent part of writing the object file. */
+ vms_write_object_file (H_GET_TEXT_SIZE (&headers),
+ H_GET_DATA_SIZE (&headers),
+ H_GET_BSS_SIZE (&headers),
+ text_frag_root, data_frag_root);
+#endif /* OBJ_VMS */
+#else /* BFD_ASSEMBLER */
+
+ /* Resolve symbol values. This needs to be done before processing
+ the relocations. */
+ if (symbol_rootP)
+ {
+ symbolS *symp;
+
+ for (symp = symbol_rootP; symp; symp = symbol_next (symp))
+ resolve_symbol_value (symp);
+ }
+ resolve_local_symbol_values ();
+
+ PROGRESS (1);
+
+#ifdef tc_frob_file_before_adjust
+ tc_frob_file_before_adjust ();
+#endif
+#ifdef obj_frob_file_before_adjust
+ obj_frob_file_before_adjust ();
+#endif
+
+ bfd_map_over_sections (stdoutput, adjust_reloc_syms, (char *) 0);
+
+#ifdef tc_frob_file_before_fix
+ tc_frob_file_before_fix ();
+#endif
+#ifdef obj_frob_file_before_fix
+ obj_frob_file_before_fix ();
+#endif
+
+ bfd_map_over_sections (stdoutput, fix_segment, (char *) 0);
+
+ /* Set up symbol table, and write it out. */
+ if (symbol_rootP)
+ {
+ symbolS *symp;
+
+ for (symp = symbol_rootP; symp; symp = symbol_next (symp))
+ {
+ int punt = 0;
+ const char *name;
+
+ if (symbol_mri_common_p (symp))
+ {
+ if (S_IS_EXTERNAL (symp))
+ as_bad (_("%s: global symbols not supported in common sections"),
+ S_GET_NAME (symp));
+ symbol_remove (symp, &symbol_rootP, &symbol_lastP);
+ continue;
+ }
+
+ name = S_GET_NAME (symp);
+ if (name)
+ {
+ const char *name2 =
+ decode_local_label_name ((char *) S_GET_NAME (symp));
+ /* They only differ if `name' is a fb or dollar local
+ label name. */
+ if (name2 != name && ! S_IS_DEFINED (symp))
+ as_bad (_("local label `%s' is not defined"), name2);
+ }
+
+ /* Do it again, because adjust_reloc_syms might introduce
+ more symbols. They'll probably only be section symbols,
+ but they'll still need to have the values computed. */
+ resolve_symbol_value (symp);
+
+ /* Skip symbols which were equated to undefined or common
+ symbols. */
+ if (symbol_equated_reloc_p (symp))
+ {
+ symbol_remove (symp, &symbol_rootP, &symbol_lastP);
+ continue;
+ }
+
+ /* So far, common symbols have been treated like undefined symbols.
+ Put them in the common section now. */
+ if (S_IS_DEFINED (symp) == 0
+ && S_GET_VALUE (symp) != 0)
+ S_SET_SEGMENT (symp, bfd_com_section_ptr);
+#if 0
+ printf ("symbol `%s'\n\t@%x: value=%d flags=%x seg=%s\n",
+ S_GET_NAME (symp), symp,
+ S_GET_VALUE (symp),
+ symbol_get_bfdsym (symp)->flags,
+ segment_name (S_GET_SEGMENT (symp)));
+#endif
+
+#ifdef obj_frob_symbol
+ obj_frob_symbol (symp, punt);
+#endif
+#ifdef tc_frob_symbol
+ if (! punt || symbol_used_in_reloc_p (symp))
+ tc_frob_symbol (symp, punt);
+#endif
+
+ /* If we don't want to keep this symbol, splice it out of
+ the chain now. If EMIT_SECTION_SYMBOLS is 0, we never
+ want section symbols. Otherwise, we skip local symbols
+ and symbols that the frob_symbol macros told us to punt,
+ but we keep such symbols if they are used in relocs. */
+ if (symp == abs_section_sym
+ || (! EMIT_SECTION_SYMBOLS
+ && symbol_section_p (symp))
+ /* Note that S_IS_EXTERN and S_IS_LOCAL are not always
+ opposites. Sometimes the former checks flags and the
+ latter examines the name... */
+ || (!S_IS_EXTERN (symp)
+ && (punt || S_IS_LOCAL (symp))
+ && ! symbol_used_in_reloc_p (symp)))
+ {
+ symbol_remove (symp, &symbol_rootP, &symbol_lastP);
+
+ /* After symbol_remove, symbol_next(symp) still returns
+ the one that came after it in the chain. So we don't
+ need to do any extra cleanup work here. */
+ continue;
+ }
+
+ /* Make sure we really got a value for the symbol. */
+ if (! symbol_resolved_p (symp))
+ {
+ as_bad (_("can't resolve value for symbol `%s'"),
+ S_GET_NAME (symp));
+ symbol_mark_resolved (symp);
+ }
+
+ /* Set the value into the BFD symbol. Up til now the value
+ has only been kept in the gas symbolS struct. */
+ symbol_get_bfdsym (symp)->value = S_GET_VALUE (symp);
+ }
+ }
+
+ PROGRESS (1);
+
+ /* Now do any format-specific adjustments to the symbol table, such
+ as adding file symbols. */
+#ifdef tc_adjust_symtab
+ tc_adjust_symtab ();
+#endif
+#ifdef obj_adjust_symtab
+ obj_adjust_symtab ();
+#endif
+
+ /* Now that all the sizes are known, and contents correct, we can
+ start writing to the file. */
+ set_symtab ();
+
+ /* If *_frob_file changes the symbol value at this point, it is
+ responsible for moving the changed value into symp->bsym->value
+ as well. Hopefully all symbol value changing can be done in
+ *_frob_symbol. */
+#ifdef tc_frob_file
+ tc_frob_file ();
+#endif
+#ifdef obj_frob_file
+ obj_frob_file ();
+#endif
+
+ bfd_map_over_sections (stdoutput, write_relocs, (char *) 0);
+
+#ifdef tc_frob_file_after_relocs
+ tc_frob_file_after_relocs ();
+#endif
+#ifdef obj_frob_file_after_relocs
+ obj_frob_file_after_relocs ();
+#endif
+
+ bfd_map_over_sections (stdoutput, write_contents, (char *) 0);
+#endif /* BFD_ASSEMBLER */
+}
+#endif /* ! BFD */
+
+#ifdef TC_GENERIC_RELAX_TABLE
+
+/* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
+
+long
+relax_frag (segT segment, fragS *fragP, long stretch)
+{
+ const relax_typeS *this_type;
+ const relax_typeS *start_type;
+ relax_substateT next_state;
+ relax_substateT this_state;
+ offsetT growth;
+ offsetT aim;
+ addressT target;
+ addressT address;
+ symbolS *symbolP;
+ const relax_typeS *table;
+
+ target = fragP->fr_offset;
+ address = fragP->fr_address;
+ table = TC_GENERIC_RELAX_TABLE;
+ this_state = fragP->fr_subtype;
+ start_type = this_type = table + this_state;
+ symbolP = fragP->fr_symbol;
+
+ if (symbolP)
+ {
+ fragS *sym_frag;
+
+ sym_frag = symbol_get_frag (symbolP);
+
+#ifndef DIFF_EXPR_OK
+#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
+ know ((S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
+ || (S_GET_SEGMENT (symbolP) == SEG_DATA)
+ || (S_GET_SEGMENT (symbolP) == SEG_BSS)
+ || (S_GET_SEGMENT (symbolP) == SEG_TEXT));
+#endif
+ know (sym_frag != NULL);
+#endif
+ know (S_GET_SEGMENT (symbolP) != absolute_section
+ || sym_frag == &zero_address_frag);
+ target += S_GET_VALUE (symbolP);
+
+ /* If frag has yet to be reached on this pass,
+ assume it will move by STRETCH just as we did.
+ If this is not so, it will be because some frag
+ between grows, and that will force another pass. */
+
+ if (stretch != 0
+ && sym_frag->relax_marker != fragP->relax_marker
+ && S_GET_SEGMENT (symbolP) == segment)
+ {
+ target += stretch;
+ }
+ }
+
+ aim = target - address - fragP->fr_fix;
+#ifdef TC_PCREL_ADJUST
+ /* Currently only the ns32k family needs this. */
+ aim += TC_PCREL_ADJUST (fragP);
+/* #else */
+ /* This machine doesn't want to use pcrel_adjust.
+ In that case, pcrel_adjust should be zero. */
+#if 0
+ assert (fragP->fr_targ.ns32k.pcrel_adjust == 0);
+#endif
+#endif
+#ifdef md_prepare_relax_scan /* formerly called M68K_AIM_KLUDGE */
+ md_prepare_relax_scan (fragP, address, aim, this_state, this_type);
+#endif
+
+ if (aim < 0)
+ {
+ /* Look backwards. */
+ for (next_state = this_type->rlx_more; next_state;)
+ if (aim >= this_type->rlx_backward)
+ next_state = 0;
+ else
+ {
+ /* Grow to next state. */
+ this_state = next_state;
+ this_type = table + this_state;
+ next_state = this_type->rlx_more;
+ }
+ }
+ else
+ {
+ /* Look forwards. */
+ for (next_state = this_type->rlx_more; next_state;)
+ if (aim <= this_type->rlx_forward)
+ next_state = 0;
+ else
+ {
+ /* Grow to next state. */
+ this_state = next_state;
+ this_type = table + this_state;
+ next_state = this_type->rlx_more;
+ }
+ }
+
+ growth = this_type->rlx_length - start_type->rlx_length;
+ if (growth != 0)
+ fragP->fr_subtype = this_state;
+ return growth;
+}
+
+#endif /* defined (TC_GENERIC_RELAX_TABLE) */
+
+/* Relax_align. Advance location counter to next address that has 'alignment'
+ lowest order bits all 0s, return size of adjustment made. */
+static relax_addressT
+relax_align (register relax_addressT address, /* Address now. */
+ register int alignment /* Alignment (binary). */)
+{
+ relax_addressT mask;
+ relax_addressT new_address;
+
+ mask = ~((~0) << alignment);
+ new_address = (address + mask) & (~mask);
+#ifdef LINKER_RELAXING_SHRINKS_ONLY
+ if (linkrelax)
+ /* We must provide lots of padding, so the linker can discard it
+ when needed. The linker will not add extra space, ever. */
+ new_address += (1 << alignment);
+#endif
+ return (new_address - address);
+}
+
+/* Now we have a segment, not a crowd of sub-segments, we can make
+ fr_address values.
+
+ Relax the frags.
+
+ After this, all frags in this segment have addresses that are correct
+ within the segment. Since segments live in different file addresses,
+ these frag addresses may not be the same as final object-file
+ addresses. */
+
+int
+relax_segment (struct frag *segment_frag_root, segT segment)
+{
+ register struct frag *fragP;
+ register relax_addressT address;
+ int ret;
+
+#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
+ know (segment == SEG_DATA || segment == SEG_TEXT || segment == SEG_BSS);
+#endif
+ /* In case md_estimate_size_before_relax() wants to make fixSs. */
+ subseg_change (segment, 0);
+
+ /* For each frag in segment: count and store (a 1st guess of)
+ fr_address. */
+ address = 0;
+ for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
+ {
+ fragP->relax_marker = 0;
+ fragP->fr_address = address;
+ address += fragP->fr_fix;
+
+ switch (fragP->fr_type)
+ {
+ case rs_fill:
+ address += fragP->fr_offset * fragP->fr_var;
+ break;
+
+ case rs_align:
+ case rs_align_code:
+ case rs_align_test:
+ {
+ addressT offset = relax_align (address, (int) fragP->fr_offset);
+
+ if (fragP->fr_subtype != 0 && offset > fragP->fr_subtype)
+ offset = 0;
+
+ if (offset % fragP->fr_var != 0)
+ {
+ as_bad_where (fragP->fr_file, fragP->fr_line,
+ _("alignment padding (%lu bytes) not a multiple of %ld"),
+ (unsigned long) offset, (long) fragP->fr_var);
+ offset -= (offset % fragP->fr_var);
+ }
+
+ address += offset;
+ }
+ break;
+
+ case rs_org:
+ case rs_space:
+ /* Assume .org is nugatory. It will grow with 1st relax. */
+ break;
+
+ case rs_machine_dependent:
+ /* If fr_symbol is an expression, this call to
+ resolve_symbol_value sets up the correct segment, which will
+ likely be needed in md_estimate_size_before_relax. */
+ if (fragP->fr_symbol)
+ resolve_symbol_value (fragP->fr_symbol);
+
+ address += md_estimate_size_before_relax (fragP, segment);
+ break;
+
+#ifndef WORKING_DOT_WORD
+ /* Broken words don't concern us yet. */
+ case rs_broken_word:
+ break;
+#endif
+
+ case rs_leb128:
+ /* Initial guess is always 1; doing otherwise can result in
+ stable solutions that are larger than the minimum. */
+ address += fragP->fr_offset = 1;
+ break;
+
+ case rs_cfa:
+ address += eh_frame_estimate_size_before_relax (fragP);
+ break;
+
+ case rs_dwarf2dbg:
+ address += dwarf2dbg_estimate_size_before_relax (fragP);
+ break;
+
+ default:
+ BAD_CASE (fragP->fr_type);
+ break;
+ }
+ }
+
+ /* Do relax(). */
+ {
+ offsetT stretch; /* May be any size, 0 or negative. */
+ /* Cumulative number of addresses we have relaxed this pass.
+ We may have relaxed more than one address. */
+ int stretched; /* Have we stretched on this pass? */
+ /* This is 'cuz stretch may be zero, when, in fact some piece of code
+ grew, and another shrank. If a branch instruction doesn't fit anymore,
+ we could be scrod. */
+
+ do
+ {
+ stretch = 0;
+ stretched = 0;
+
+ for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
+ {
+ offsetT growth = 0;
+ addressT was_address;
+ offsetT offset;
+ symbolS *symbolP;
+
+ fragP->relax_marker ^= 1;
+ was_address = fragP->fr_address;
+ address = fragP->fr_address += stretch;
+ symbolP = fragP->fr_symbol;
+ offset = fragP->fr_offset;
+
+ switch (fragP->fr_type)
+ {
+ case rs_fill: /* .fill never relaxes. */
+ growth = 0;
+ break;
+
+#ifndef WORKING_DOT_WORD
+ /* JF: This is RMS's idea. I do *NOT* want to be blamed
+ for it I do not want to write it. I do not want to have
+ anything to do with it. This is not the proper way to
+ implement this misfeature. */
+ case rs_broken_word:
+ {
+ struct broken_word *lie;
+ struct broken_word *untruth;
+
+ /* Yes this is ugly (storing the broken_word pointer
+ in the symbol slot). Still, this whole chunk of
+ code is ugly, and I don't feel like doing anything
+ about it. Think of it as stubbornness in action. */
+ growth = 0;
+ for (lie = (struct broken_word *) (fragP->fr_symbol);
+ lie && lie->dispfrag == fragP;
+ lie = lie->next_broken_word)
+ {
+
+ if (lie->added)
+ continue;
+
+ offset = (S_GET_VALUE (lie->add)
+ + lie->addnum
+ - S_GET_VALUE (lie->sub));
+ if (offset <= -32768 || offset >= 32767)
+ {
+ if (flag_warn_displacement)
+ {
+ char buf[50];
+ sprint_value (buf, (addressT) lie->addnum);
+ as_warn_where (fragP->fr_file, fragP->fr_line,
+ _(".word %s-%s+%s didn't fit"),
+ S_GET_NAME (lie->add),
+ S_GET_NAME (lie->sub),
+ buf);
+ }
+ lie->added = 1;
+ if (fragP->fr_subtype == 0)
+ {
+ fragP->fr_subtype++;
+ growth += md_short_jump_size;
+ }
+ for (untruth = lie->next_broken_word;
+ untruth && untruth->dispfrag == lie->dispfrag;
+ untruth = untruth->next_broken_word)
+ if ((symbol_get_frag (untruth->add)
+ == symbol_get_frag (lie->add))
+ && (S_GET_VALUE (untruth->add)
+ == S_GET_VALUE (lie->add)))
+ {
+ untruth->added = 2;
+ untruth->use_jump = lie;
+ }
+ growth += md_long_jump_size;
+ }
+ }
+
+ break;
+ } /* case rs_broken_word */
+#endif
+ case rs_align:
+ case rs_align_code:
+ case rs_align_test:
+ {
+ addressT oldoff, newoff;
+
+ oldoff = relax_align (was_address + fragP->fr_fix,
+ (int) offset);
+ newoff = relax_align (address + fragP->fr_fix,
+ (int) offset);
+
+ if (fragP->fr_subtype != 0)
+ {
+ if (oldoff > fragP->fr_subtype)
+ oldoff = 0;
+ if (newoff > fragP->fr_subtype)
+ newoff = 0;
+ }
+
+ growth = newoff - oldoff;
+ }
+ break;
+
+ case rs_org:
+ {
+ addressT target = offset;
+ addressT after;
+
+ if (symbolP)
+ {
+#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
+ know ((S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
+ || (S_GET_SEGMENT (symbolP) == SEG_DATA)
+ || (S_GET_SEGMENT (symbolP) == SEG_TEXT)
+ || S_GET_SEGMENT (symbolP) == SEG_BSS);
+ know (symbolP->sy_frag);
+ know (!(S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
+ || (symbolP->sy_frag == &zero_address_frag));
+#endif
+ /* Convert from an actual address to an octet offset
+ into the section. Here it is assumed that the
+ section's VMA is zero, and can omit subtracting it
+ from the symbol's value to get the address offset. */
+ know (S_GET_SECTION (symbolP)->vma == 0);
+ target += S_GET_VALUE (symbolP) * OCTETS_PER_BYTE;
+ }
+
+ know (fragP->fr_next);
+ after = fragP->fr_next->fr_address;
+ growth = target - after;
+ if (growth < 0)
+ {
+ /* Growth may be negative, but variable part of frag
+ cannot have fewer than 0 chars. That is, we can't
+ .org backwards. */
+ as_bad_where (fragP->fr_file, fragP->fr_line,
+ _("attempt to move .org backwards"));
+
+ /* We've issued an error message. Change the
+ frag to avoid cascading errors. */
+ fragP->fr_type = rs_align;
+ fragP->fr_subtype = 0;
+ fragP->fr_offset = 0;
+ fragP->fr_fix = after - address;
+ growth = stretch;
+ }
+
+ /* This is an absolute growth factor */
+ growth -= stretch;
+ break;
+ }
+
+ case rs_space:
+ growth = 0;
+ if (symbolP)
+ {
+ offsetT amount;
+
+ amount = S_GET_VALUE (symbolP);
+ if (S_GET_SEGMENT (symbolP) != absolute_section
+ || S_IS_COMMON (symbolP)
+ || ! S_IS_DEFINED (symbolP))
+ {
+ as_bad_where (fragP->fr_file, fragP->fr_line,
+ _(".space specifies non-absolute value"));
+ /* Prevent repeat of this error message. */
+ fragP->fr_symbol = 0;
+ }
+ else if (amount < 0)
+ {
+ as_warn_where (fragP->fr_file, fragP->fr_line,
+ _(".space or .fill with negative value, ignored"));
+ fragP->fr_symbol = 0;
+ }
+ else
+ growth = (was_address + fragP->fr_fix + amount
+ - fragP->fr_next->fr_address);
+ }
+ break;
+
+ case rs_machine_dependent:
+#ifdef md_relax_frag
+ growth = md_relax_frag (segment, fragP, stretch);
+#else
+#ifdef TC_GENERIC_RELAX_TABLE
+ /* The default way to relax a frag is to look through
+ TC_GENERIC_RELAX_TABLE. */
+ growth = relax_frag (segment, fragP, stretch);
+#endif /* TC_GENERIC_RELAX_TABLE */
+#endif
+ break;
+
+ case rs_leb128:
+ {
+ valueT value;
+ offsetT size;
+
+ value = resolve_symbol_value (fragP->fr_symbol);
+ size = sizeof_leb128 (value, fragP->fr_subtype);
+ growth = size - fragP->fr_offset;
+ fragP->fr_offset = size;
+ }
+ break;
+
+ case rs_cfa:
+ growth = eh_frame_relax_frag (fragP);
+ break;
+
+ case rs_dwarf2dbg:
+ growth = dwarf2dbg_relax_frag (fragP);
+ break;
+
+ default:
+ BAD_CASE (fragP->fr_type);
+ break;
+ }
+ if (growth)
+ {
+ stretch += growth;
+ stretched = 1;
+ }
+ } /* For each frag in the segment. */
+ }
+ while (stretched); /* Until nothing further to relax. */
+ } /* do_relax */
+
+ ret = 0;
+ for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
+ if (fragP->last_fr_address != fragP->fr_address)
+ {
+ fragP->last_fr_address = fragP->fr_address;
+ ret = 1;
+ }
+ return ret;
+}
+
+#if defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS))
+
+/* fixup_segment()
+
+ Go through all the fixS's in a segment and see which ones can be
+ handled now. (These consist of fixS where we have since discovered
+ the value of a symbol, or the address of the frag involved.)
+ For each one, call md_apply_fix3 to put the fix into the frag data.
+
+ Result is a count of how many relocation structs will be needed to
+ handle the remaining fixS's that we couldn't completely handle here.
+ These will be output later by emit_relocations(). */
+
+static long
+fixup_segment (fixS *fixP, segT this_segment)
+{
+ long seg_reloc_count = 0;
+ valueT add_number;
+ fragS *fragP;
+ segT add_symbol_segment = absolute_section;
+
+ if (fixP != NULL && abs_section_sym == NULL)
+ {
+#ifndef BFD_ASSEMBLER
+ abs_section_sym = &abs_symbol;
+#else
+ abs_section_sym = section_symbol (absolute_section);
+#endif
+ }
+
+ /* If the linker is doing the relaxing, we must not do any fixups.
+
+ Well, strictly speaking that's not true -- we could do any that
+ are PC-relative and don't cross regions that could change size.
+ And for the i960 we might be able to turn callx/callj into bal
+ anyways in cases where we know the maximum displacement. */
+ if (linkrelax && TC_LINKRELAX_FIXUP (this_segment))
+ {
+ for (; fixP; fixP = fixP->fx_next)
+ if (!fixP->fx_done)
+ {
+ if (fixP->fx_addsy == NULL)
+ {
+ /* There was no symbol required by this relocation.
+ However, BFD doesn't really handle relocations
+ without symbols well. So fake up a local symbol in
+ the absolute section. */
+ fixP->fx_addsy = abs_section_sym;
+ }
+ symbol_mark_used_in_reloc (fixP->fx_addsy);
+ if (fixP->fx_subsy != NULL)
+ symbol_mark_used_in_reloc (fixP->fx_subsy);
+ seg_reloc_count++;
+ }
+ TC_ADJUST_RELOC_COUNT (fixP, seg_reloc_count);
+ return seg_reloc_count;
+ }
+
+ for (; fixP; fixP = fixP->fx_next)
+ {
+#ifdef DEBUG5
+ fprintf (stderr, "\nprocessing fixup:\n");
+ print_fixup (fixP);
+#endif
+
+ fragP = fixP->fx_frag;
+ know (fragP);
+#ifdef TC_VALIDATE_FIX
+ TC_VALIDATE_FIX (fixP, this_segment, skip);
+#endif
+ add_number = fixP->fx_offset;
+
+ if (fixP->fx_addsy != NULL
+ && symbol_mri_common_p (fixP->fx_addsy))
+ {
+ know (fixP->fx_addsy->sy_value.X_op == O_symbol);
+ add_number += S_GET_VALUE (fixP->fx_addsy);
+ fixP->fx_offset = add_number;
+ fixP->fx_addsy
+ = symbol_get_value_expression (fixP->fx_addsy)->X_add_symbol;
+ }
+
+ if (fixP->fx_addsy != NULL)
+ add_symbol_segment = S_GET_SEGMENT (fixP->fx_addsy);
+
+ if (fixP->fx_subsy != NULL)
+ {
+ segT sub_symbol_segment;
+ resolve_symbol_value (fixP->fx_subsy);
+ sub_symbol_segment = S_GET_SEGMENT (fixP->fx_subsy);
+ if (fixP->fx_addsy != NULL
+ && sub_symbol_segment == add_symbol_segment
+ && !TC_FORCE_RELOCATION_SUB_SAME (fixP, add_symbol_segment))
+ {
+ add_number += S_GET_VALUE (fixP->fx_addsy);
+ add_number -= S_GET_VALUE (fixP->fx_subsy);
+ fixP->fx_offset = add_number;
+ fixP->fx_addsy = NULL;
+ fixP->fx_subsy = NULL;
+#ifdef TC_M68K
+ /* See the comment below about 68k weirdness. */
+ fixP->fx_pcrel = 0;
+#endif
+ }
+ else if (sub_symbol_segment == absolute_section
+ && !TC_FORCE_RELOCATION_SUB_ABS (fixP))
+ {
+ add_number -= S_GET_VALUE (fixP->fx_subsy);
+ fixP->fx_offset = add_number;
+ fixP->fx_subsy = NULL;
+ }
+ else if (sub_symbol_segment == this_segment
+ && !TC_FORCE_RELOCATION_SUB_LOCAL (fixP))
+ {
+ add_number -= S_GET_VALUE (fixP->fx_subsy);
+ fixP->fx_offset = (add_number + fixP->fx_dot_value
+ + fixP->fx_frag->fr_address);
+
+ /* Make it pc-relative. If the back-end code has not
+ selected a pc-relative reloc, cancel the adjustment
+ we do later on all pc-relative relocs. */
+ if (0
+#ifdef TC_M68K
+ /* Do this for m68k even if it's already described
+ as pc-relative. On the m68k, an operand of
+ "pc@(foo-.-2)" should address "foo" in a
+ pc-relative mode. */
+ || 1
+#endif
+ || !fixP->fx_pcrel)
+ add_number += MD_PCREL_FROM_SECTION (fixP, this_segment);
+ fixP->fx_subsy = NULL;
+ fixP->fx_pcrel = 1;
+ }
+ else if (!TC_VALIDATE_FIX_SUB (fixP))
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("can't resolve `%s' {%s section} - `%s' {%s section}"),
+ fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
+ segment_name (add_symbol_segment),
+ S_GET_NAME (fixP->fx_subsy),
+ segment_name (sub_symbol_segment));
+ }
+ }
+
+ if (fixP->fx_addsy)
+ {
+ if (add_symbol_segment == this_segment
+ && !TC_FORCE_RELOCATION_LOCAL (fixP))
+ {
+ /* This fixup was made when the symbol's segment was
+ SEG_UNKNOWN, but it is now in the local segment.
+ So we know how to do the address without relocation. */
+ add_number += S_GET_VALUE (fixP->fx_addsy);
+ fixP->fx_offset = add_number;
+ if (fixP->fx_pcrel)
+ add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment);
+ fixP->fx_addsy = NULL;
+ fixP->fx_pcrel = 0;
+ }
+ else if (add_symbol_segment == absolute_section
+ && !TC_FORCE_RELOCATION_ABS (fixP))
+ {
+ add_number += S_GET_VALUE (fixP->fx_addsy);
+ fixP->fx_offset = add_number;
+ fixP->fx_addsy = NULL;
+ }
+ else if (add_symbol_segment != undefined_section
+#ifdef BFD_ASSEMBLER
+ && ! bfd_is_com_section (add_symbol_segment)
+#endif
+ && MD_APPLY_SYM_VALUE (fixP))
+ add_number += S_GET_VALUE (fixP->fx_addsy);
+ }
+
+ if (fixP->fx_pcrel)
+ {
+ add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment);
+ if (!fixP->fx_done && fixP->fx_addsy == NULL)
+ {
+ /* There was no symbol required by this relocation.
+ However, BFD doesn't really handle relocations
+ without symbols well. So fake up a local symbol in
+ the absolute section. */
+ fixP->fx_addsy = abs_section_sym;
+ }
+ }
+
+ if (!fixP->fx_done)
+ md_apply_fix3 (fixP, &add_number, this_segment);
+
+ if (!fixP->fx_done)
+ {
+ ++seg_reloc_count;
+ if (fixP->fx_addsy == NULL)
+ fixP->fx_addsy = abs_section_sym;
+ symbol_mark_used_in_reloc (fixP->fx_addsy);
+ if (fixP->fx_subsy != NULL)
+ symbol_mark_used_in_reloc (fixP->fx_subsy);
+ }
+
+ if (!fixP->fx_bit_fixP && !fixP->fx_no_overflow && fixP->fx_size != 0)
+ {
+ if (fixP->fx_size < sizeof (valueT))
+ {
+ valueT mask;
+
+ mask = 0;
+ mask--; /* Set all bits to one. */
+ mask <<= fixP->fx_size * 8 - (fixP->fx_signed ? 1 : 0);
+ if ((add_number & mask) != 0 && (add_number & mask) != mask)
+ {
+ char buf[50], buf2[50];
+ sprint_value (buf, fragP->fr_address + fixP->fx_where);
+ if (add_number > 1000)
+ sprint_value (buf2, add_number);
+ else
+ sprintf (buf2, "%ld", (long) add_number);
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("value of %s too large for field of %d bytes at %s"),
+ buf2, fixP->fx_size, buf);
+ } /* Generic error checking. */
+ }
+#ifdef WARN_SIGNED_OVERFLOW_WORD
+ /* Warn if a .word value is too large when treated as a signed
+ number. We already know it is not too negative. This is to
+ catch over-large switches generated by gcc on the 68k. */
+ if (!flag_signed_overflow_ok
+ && fixP->fx_size == 2
+ && add_number > 0x7fff)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("signed .word overflow; switch may be too large; %ld at 0x%lx"),
+ (long) add_number,
+ (long) (fragP->fr_address + fixP->fx_where));
+#endif
+ } /* Not a bit fix. */
+
+#ifdef TC_VALIDATE_FIX
+ skip: ATTRIBUTE_UNUSED_LABEL
+ ;
+#endif
+#ifdef DEBUG5
+ fprintf (stderr, "result:\n");
+ print_fixup (fixP);
+#endif
+ } /* For each fixS in this segment. */
+
+ TC_ADJUST_RELOC_COUNT (fixP, seg_reloc_count);
+ return seg_reloc_count;
+}
+
+#endif /* defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS)) */
+
+void
+number_to_chars_bigendian (char *buf, valueT val, int n)
+{
+ if (n <= 0)
+ abort ();
+ while (n--)
+ {
+ buf[n] = val & 0xff;
+ val >>= 8;
+ }
+}
+
+void
+number_to_chars_littleendian (char *buf, valueT val, int n)
+{
+ if (n <= 0)
+ abort ();
+ while (n--)
+ {
+ *buf++ = val & 0xff;
+ val >>= 8;
+ }
+}
+
+void
+write_print_statistics (FILE *file)
+{
+ fprintf (file, "fixups: %d\n", n_fixups);
+}
+
+/* For debugging. */
+extern int indent_level;
+
+void
+print_fixup (fixS *fixp)
+{
+ indent_level = 1;
+ fprintf (stderr, "fix %lx %s:%d", (long) fixp, fixp->fx_file, fixp->fx_line);
+ if (fixp->fx_pcrel)
+ fprintf (stderr, " pcrel");
+ if (fixp->fx_pcrel_adjust)
+ fprintf (stderr, " pcrel_adjust=%d", fixp->fx_pcrel_adjust);
+ if (fixp->fx_im_disp)
+ {
+#ifdef TC_NS32K
+ fprintf (stderr, " im_disp=%d", fixp->fx_im_disp);
+#else
+ fprintf (stderr, " im_disp");
+#endif
+ }
+ if (fixp->fx_tcbit)
+ fprintf (stderr, " tcbit");
+ if (fixp->fx_done)
+ fprintf (stderr, " done");
+ fprintf (stderr, "\n size=%d frag=%lx where=%ld offset=%lx addnumber=%lx",
+ fixp->fx_size, (long) fixp->fx_frag, (long) fixp->fx_where,
+ (long) fixp->fx_offset, (long) fixp->fx_addnumber);
+#ifdef BFD_ASSEMBLER
+ fprintf (stderr, "\n %s (%d)", bfd_get_reloc_code_name (fixp->fx_r_type),
+ fixp->fx_r_type);
+#else
+#ifdef NEED_FX_R_TYPE
+ fprintf (stderr, " r_type=%d", fixp->fx_r_type);
+#endif
+#endif
+ if (fixp->fx_addsy)
+ {
+ fprintf (stderr, "\n +<");
+ print_symbol_value_1 (stderr, fixp->fx_addsy);
+ fprintf (stderr, ">");
+ }
+ if (fixp->fx_subsy)
+ {
+ fprintf (stderr, "\n -<");
+ print_symbol_value_1 (stderr, fixp->fx_subsy);
+ fprintf (stderr, ">");
+ }
+ fprintf (stderr, "\n");
+#ifdef TC_FIX_DATA_PRINT
+ TC_FIX_DATA_PRINT (stderr, fixp);
+#endif
+}
diff --git a/x/binutils/gas/write.h b/x/binutils/gas/write.h
new file mode 100644
index 0000000..0e0f59f
--- /dev/null
+++ b/x/binutils/gas/write.h
@@ -0,0 +1,217 @@
+/* write.h
+ Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef __write_h__
+#define __write_h__
+
+#ifndef TC_I960
+#ifdef hpux
+#define EXEC_MACHINE_TYPE HP9000S200_ID
+#endif
+#endif /* TC_I960 */
+
+#ifndef BFD_ASSEMBLER
+
+#ifndef LOCAL_LABEL
+#define LOCAL_LABEL(name) (name [0] == 'L' )
+#endif
+
+#define S_LOCAL_NAME(s) (LOCAL_LABEL (S_GET_NAME (s)))
+
+#endif /* ! BFD_ASSEMBLER */
+
+/* This is the name of a fake symbol which will never appear in the
+ assembler output. S_IS_LOCAL detects it because of the \001. */
+#ifndef FAKE_LABEL_NAME
+#define FAKE_LABEL_NAME "L0\001"
+#endif
+
+#include "bit_fix.h"
+
+/*
+ * FixSs may be built up in any order.
+ */
+
+struct fix
+{
+ /* These small fields are grouped together for compactness of
+ this structure, and efficiency of access on some architectures. */
+
+ /* pc-relative offset adjust (only used by m68k) */
+ char fx_pcrel_adjust;
+
+ /* How many bytes are involved? */
+ unsigned char fx_size;
+
+ /* Is this a pc-relative relocation? */
+ unsigned fx_pcrel : 1;
+
+ /* Is this a relocation to a procedure linkage table entry? If so,
+ some of the reductions we try to apply are invalid. A better way
+ might be to represent PLT entries with different kinds of
+ symbols, and use normal relocations (with undefined symbols);
+ look into it for version 2.6. */
+ unsigned fx_plt : 1;
+
+ /* Is this value an immediate displacement? */
+ /* Only used on i960 and ns32k; merge it into TC_FIX_TYPE sometime. */
+ unsigned fx_im_disp : 2;
+
+ /* A bit for the CPU specific code.
+ This probably can be folded into tc_fix_data, below. */
+ unsigned fx_tcbit : 1;
+
+ /* Has this relocation already been applied? */
+ unsigned fx_done : 1;
+
+ /* Suppress overflow complaints on large addends. This is used
+ in the PowerPC ELF config to allow large addends on the
+ BFD_RELOC_{LO16,HI16,HI16_S} relocations.
+
+ @@ Can this be determined from BFD? */
+ unsigned fx_no_overflow : 1;
+
+ /* The value is signed when checking for overflow. */
+ unsigned fx_signed : 1;
+
+ /* Which frag does this fix apply to? */
+ fragS *fx_frag;
+
+ /* Where is the first byte to fix up? */
+ long fx_where;
+
+ /* NULL or Symbol whose value we add in. */
+ symbolS *fx_addsy;
+
+ /* NULL or Symbol whose value we subtract. */
+ symbolS *fx_subsy;
+
+ /* Absolute number we add in. */
+ valueT fx_offset;
+
+ /* The value of dot when the fixup expression was parsed. */
+ addressT fx_dot_value;
+
+ /* Next fixS in linked list, or NULL. */
+ struct fix *fx_next;
+
+ /* If NULL, no bitfix's to do. */
+ /* Only i960-coff and ns32k use this, and i960-coff stores an
+ integer. This can probably be folded into tc_fix_data, below.
+ @@ Alpha also uses it, but only to disable certain relocation
+ processing. */
+ bit_fixS *fx_bit_fixP;
+
+#ifdef BFD_ASSEMBLER
+ bfd_reloc_code_real_type fx_r_type;
+#else
+#ifdef NEED_FX_R_TYPE
+ /* Hack for machines where the type of reloc can't be
+ worked out by looking at how big it is. */
+ int fx_r_type;
+#endif
+#endif
+
+ /* This field is sort of misnamed. It appears to be a sort of random
+ scratch field, for use by the back ends. The main gas code doesn't
+ do anything but initialize it to zero. The use of it does need to
+ be coordinated between the cpu and format files, though. E.g., some
+ coff targets pass the `addend' field from the cpu file via this
+ field. I don't know why the `fx_offset' field above can't be used
+ for that; investigate later and document. KR */
+ valueT fx_addnumber;
+
+ /* The location of the instruction which created the reloc, used
+ in error messages. */
+ char *fx_file;
+ unsigned fx_line;
+
+#ifdef USING_CGEN
+ struct {
+ /* CGEN_INSN entry for this instruction. */
+ const struct cgen_insn *insn;
+ /* Target specific data, usually reloc number. */
+ int opinfo;
+ } fx_cgen;
+#endif
+
+#ifdef TC_FIX_TYPE
+ /* Location where a backend can attach additional data
+ needed to perform fixups. */
+ TC_FIX_TYPE tc_fix_data;
+#endif
+};
+
+typedef struct fix fixS;
+
+extern int finalize_syms;
+extern symbolS *abs_section_sym;
+extern addressT dot_value;
+
+#ifndef BFD_ASSEMBLER
+extern char *next_object_file_charP;
+
+#ifndef MANY_SEGMENTS
+COMMON fixS *text_fix_root, *text_fix_tail; /* Chains fixSs. */
+COMMON fixS *data_fix_root, *data_fix_tail; /* Chains fixSs. */
+COMMON fixS *bss_fix_root, *bss_fix_tail; /* Chains fixSs. */
+extern struct frag *text_last_frag; /* Last frag in segment. */
+extern struct frag *data_last_frag; /* Last frag in segment. */
+#endif
+COMMON fixS **seg_fix_rootP, **seg_fix_tailP; /* -> one of above. */
+#endif
+
+extern long string_byte_count;
+extern int section_alignment[];
+
+extern bit_fixS *bit_fix_new
+ (int size, int offset, long base_type, long base_adj, long min,
+ long max, long add);
+extern void append (char **charPP, char *fromP, unsigned long length);
+extern void record_alignment (segT seg, int align);
+extern int get_recorded_alignment (segT seg);
+extern void subsegs_finish (void);
+extern void write_object_file (void);
+extern long relax_frag (segT, fragS *, long);
+extern int relax_segment (struct frag * seg_frag_root, segT seg_type);
+
+extern void number_to_chars_littleendian (char *, valueT, int);
+extern void number_to_chars_bigendian (char *, valueT, int);
+
+#ifdef BFD_ASSEMBLER
+extern fixS *fix_new
+ (fragS * frag, int where, int size, symbolS * add_symbol,
+ offsetT offset, int pcrel, bfd_reloc_code_real_type r_type);
+extern fixS *fix_new_exp
+ (fragS * frag, int where, int size, expressionS *exp, int pcrel,
+ bfd_reloc_code_real_type r_type);
+#else
+extern fixS *fix_new
+ (fragS * frag, int where, int size, symbolS * add_symbol,
+ offsetT offset, int pcrel, int r_type);
+extern fixS *fix_new_exp
+ (fragS * frag, int where, int size, expressionS *exp, int pcrel,
+ int r_type);
+#endif
+
+extern void write_print_statistics (FILE *);
+
+#endif /* __write_h__ */
OpenPOWER on IntegriCloud