From 252b5132c753830d5fd56823373aed85f2a0db63 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 3 May 1999 07:29:11 +0000 Subject: 19990502 sourceware import --- gas/CONTRIBUTORS | 111 + gas/COPYING | 340 + gas/ChangeLog | 3170 ++++++ gas/ChangeLog-9295 | 13110 +++++++++++++++++++++++++ gas/ChangeLog-9697 | 5960 +++++++++++ gas/Makefile.am | 1695 ++++ gas/Makefile.in | 2488 +++++ gas/NEWS | 287 + gas/README | 274 + gas/README-vms | 248 + gas/acinclude.m4 | 56 + gas/aclocal.m4 | 822 ++ gas/app.c | 1255 +++ gas/as.c | 1010 ++ gas/as.h | 645 ++ gas/asintl.h | 44 + gas/atof-generic.c | 636 ++ gas/bignum-copy.c | 80 + gas/bignum.h | 52 + gas/bit_fix.h | 51 + gas/cgen.c | 663 ++ gas/cgen.h | 94 + gas/cond.c | 461 + gas/config-gas.com | 186 + gas/config.in | 273 + gas/config/aout_gnu.h | 455 + gas/config/atof-ieee.c | 696 ++ gas/config/atof-tahoe.c | 431 + gas/config/atof-vax.c | 517 + gas/config/e-i386coff.c | 17 + gas/config/e-i386elf.c | 17 + gas/config/e-mipsecoff.c | 37 + gas/config/e-mipself.c | 37 + gas/config/go32.cfg | 93 + gas/config/itbl-mips.h | 47 + gas/config/m68k-parse.h | 283 + gas/config/m68k-parse.y | 1061 ++ gas/config/m88k-opcode.h | 559 ++ gas/config/obj-aout.c | 629 ++ gas/config/obj-aout.h | 239 + gas/config/obj-bout.c | 348 + gas/config/obj-bout.h | 316 + gas/config/obj-coff.c | 4482 +++++++++ gas/config/obj-coff.h | 841 ++ gas/config/obj-ecoff.c | 309 + gas/config/obj-ecoff.h | 67 + gas/config/obj-elf.c | 1764 ++++ gas/config/obj-elf.h | 194 + gas/config/obj-evax.c | 83 + gas/config/obj-evax.h | 95 + gas/config/obj-generic.c | 41 + gas/config/obj-generic.h | 80 + gas/config/obj-hp300.c | 52 + gas/config/obj-hp300.h | 71 + gas/config/obj-ieee.c | 627 ++ gas/config/obj-ieee.h | 50 + gas/config/obj-multi.c | 4 + gas/config/obj-multi.h | 50 + gas/config/obj-som.c | 307 + gas/config/obj-som.h | 73 + gas/config/obj-vms.c | 5549 +++++++++++ gas/config/obj-vms.h | 552 ++ gas/config/tc-a29k.c | 1296 +++ gas/config/tc-a29k.h | 54 + gas/config/tc-alpha.c | 4762 +++++++++ gas/config/tc-alpha.h | 104 + gas/config/tc-arc.c | 1481 +++ gas/config/tc-arc.h | 71 + gas/config/tc-arm.c | 6857 +++++++++++++ gas/config/tc-arm.h | 204 + gas/config/tc-d10v.c | 1636 +++ gas/config/tc-d10v.h | 62 + gas/config/tc-d30v.c | 2218 +++++ gas/config/tc-d30v.h | 59 + gas/config/tc-fr30.c | 664 ++ gas/config/tc-fr30.h | 81 + gas/config/tc-generic.c | 0 gas/config/tc-generic.h | 39 + gas/config/tc-h8300.c | 1595 +++ gas/config/tc-h8300.h | 58 + gas/config/tc-h8500.c | 1633 +++ gas/config/tc-h8500.h | 57 + gas/config/tc-hppa.c | 6716 +++++++++++++ gas/config/tc-hppa.h | 162 + gas/config/tc-i386.c | 4475 +++++++++ gas/config/tc-i386.h | 471 + gas/config/tc-i860.c | 1263 +++ gas/config/tc-i860.h | 39 + gas/config/tc-i960.c | 3231 ++++++ gas/config/tc-i960.h | 171 + gas/config/tc-m32r.c | 1300 +++ gas/config/tc-m32r.h | 102 + gas/config/tc-m68851.h | 304 + gas/config/tc-m68k.c | 7009 +++++++++++++ gas/config/tc-m68k.h | 216 + gas/config/tc-m88k.c | 1452 +++ gas/config/tc-m88k.h | 108 + gas/config/tc-mcore.c | 2183 ++++ gas/config/tc-mcore.h | 119 + gas/config/tc-mips.c | 11783 ++++++++++++++++++++++ gas/config/tc-mips.h | 153 + gas/config/tc-mn10200.c | 1414 +++ gas/config/tc-mn10200.h | 51 + gas/config/tc-mn10300.c | 1649 ++++ gas/config/tc-mn10300.h | 50 + gas/config/tc-ns32k.c | 2328 +++++ gas/config/tc-ns32k.h | 155 + gas/config/tc-ppc.c | 5003 ++++++++++ gas/config/tc-ppc.h | 276 + gas/config/tc-sh.c | 2425 +++++ gas/config/tc-sh.h | 152 + gas/config/tc-sparc.c | 3551 +++++++ gas/config/tc-sparc.h | 164 + gas/config/tc-tahoe.c | 2027 ++++ gas/config/tc-tahoe.h | 43 + gas/config/tc-tic30.c | 1887 ++++ gas/config/tc-tic30.h | 55 + gas/config/tc-tic80.c | 1061 ++ gas/config/tc-tic80.h | 63 + gas/config/tc-v850.c | 2478 +++++ gas/config/tc-v850.h | 85 + gas/config/tc-vax.c | 3242 ++++++ gas/config/tc-vax.h | 45 + gas/config/tc-w65.c | 1219 +++ gas/config/tc-w65.h | 61 + gas/config/tc-z8k.c | 1589 +++ gas/config/tc-z8k.h | 54 + gas/config/te-386bsd.h | 31 + gas/config/te-aux.h | 17 + gas/config/te-delt88.h | 13 + gas/config/te-delta.h | 14 + gas/config/te-dpx2.h | 12 + gas/config/te-dynix.h | 7 + gas/config/te-epoc-pe.h | 8 + gas/config/te-generic.h | 22 + gas/config/te-go32.h | 16 + gas/config/te-hp300.h | 25 + gas/config/te-hppa.h | 26 + gas/config/te-i386aix.h | 29 + gas/config/te-ic960.h | 38 + gas/config/te-linux.h | 4 + gas/config/te-lnews.h | 5 + gas/config/te-lynx.h | 7 + gas/config/te-mach.h | 2 + gas/config/te-macos.h | 11 + gas/config/te-multi.h | 22 + gas/config/te-nbsd.h | 23 + gas/config/te-nbsd532.h | 19 + gas/config/te-pc532mach.h | 19 + gas/config/te-pe.h | 7 + gas/config/te-ppcnw.h | 31 + gas/config/te-psos.h | 22 + gas/config/te-riscix.h | 6 + gas/config/te-sparcaout.h | 21 + gas/config/te-sun3.h | 48 + gas/config/te-svr4.h | 4 + gas/config/te-sysv32.h | 6 + gas/config/vax-inst.h | 77 + gas/config/vms-a-conf.h | 129 + gas/config/vms-conf.h | 179 + gas/configure | 5750 +++++++++++ gas/configure.bat | 57 + gas/configure.in | 766 ++ gas/debug.c | 104 + gas/dep-in.sed | 45 + gas/depend.c | 208 + gas/doc/Makefile.am | 49 + gas/doc/Makefile.in | 438 + gas/doc/all.texi | 72 + gas/doc/as.1 | 302 + gas/doc/as.texinfo | 5322 ++++++++++ gas/doc/c-a29k.texi | 182 + gas/doc/c-arm.texi | 207 + gas/doc/c-d10v.texi | 250 + gas/doc/c-d30v.texi | 292 + gas/doc/c-h8300.texi | 342 + gas/doc/c-h8500.texi | 272 + gas/doc/c-hppa.texi | 263 + gas/doc/c-i386.texi | 518 + gas/doc/c-i960.texi | 298 + gas/doc/c-m32r.texi | 13 + gas/doc/c-m68k.texi | 503 + gas/doc/c-mips.texi | 257 + gas/doc/c-ns32k.texi | 30 + gas/doc/c-sh.texi | 272 + gas/doc/c-sparc.texi | 179 + gas/doc/c-v850.texi | 363 + gas/doc/c-vax.texi | 357 + gas/doc/c-z8k.texi | 380 + gas/doc/gasp.texi | 1086 ++ gas/doc/h8.texi | 26 + gas/doc/internals.texi | 1557 +++ gas/ecoff.c | 5308 ++++++++++ gas/ecoff.h | 110 + gas/ehopt.c | 469 + gas/emul-target.h | 43 + gas/emul.h | 23 + gas/expr.c | 1859 ++++ gas/expr.h | 162 + gas/flonum-copy.c | 73 + gas/flonum-konst.c | 209 + gas/flonum-mult.c | 200 + gas/flonum.h | 110 + gas/frags.c | 359 + gas/frags.h | 158 + gas/gasp.c | 3745 +++++++ gas/gdbinit.in | 39 + gas/hash.c | 1028 ++ gas/hash.h | 45 + gas/input-file.c | 248 + gas/input-file.h | 68 + gas/input-scrub.c | 521 + gas/itbl-lex.l | 114 + gas/itbl-ops.c | 921 ++ gas/itbl-ops.h | 109 + gas/itbl-parse.y | 459 + gas/link.cmd | 10 + gas/listing.c | 1420 +++ gas/listing.h | 67 + gas/literal.c | 95 + gas/mac-as.r | 42 + gas/macro.c | 1259 +++ gas/macro.h | 53 + gas/makefile.vms | 124 + gas/messages.c | 541 + gas/mpw-config.in | 115 + gas/mpw-make.sed | 100 + gas/obj.h | 81 + gas/output-file.c | 156 + gas/output-file.h | 25 + gas/po/Make-in | 251 + gas/po/POTFILES.in | 193 + gas/po/gas.pot | 3853 ++++++++ gas/read.c | 5054 ++++++++++ gas/read.h | 166 + gas/sb.c | 289 + gas/sb.h | 99 + gas/stabs.c | 632 ++ gas/stamp-h.in | 1 + gas/struc-symbol.h | 166 + gas/subsegs.c | 618 ++ gas/subsegs.h | 159 + gas/symbols.c | 1785 ++++ gas/symbols.h | 90 + gas/tc.h | 112 + gas/testsuite/ChangeLog | 2333 +++++ gas/testsuite/config/default.exp | 46 + gas/testsuite/gas/all/align.d | 12 + gas/testsuite/gas/all/align.s | 61 + gas/testsuite/gas/all/cofftag.d | 25 + gas/testsuite/gas/all/cofftag.s | 57 + gas/testsuite/gas/all/comment.s | 3 + gas/testsuite/gas/all/cond.d | 20 + gas/testsuite/gas/all/cond.s | 18 + gas/testsuite/gas/all/diff1.s | 5 + gas/testsuite/gas/all/float.s | 4 + gas/testsuite/gas/all/gas.exp | 145 + gas/testsuite/gas/all/itbl | 20 + gas/testsuite/gas/all/itbl-test.c | 129 + gas/testsuite/gas/all/itbl.s | 13 + gas/testsuite/gas/all/p1480.s | 3 + gas/testsuite/gas/all/p2425.s | 6 + gas/testsuite/gas/all/struct.d | 8 + gas/testsuite/gas/all/struct.s | 10 + gas/testsuite/gas/all/x930509.s | 3 + gas/testsuite/gas/alpha/fp.d | 7 + gas/testsuite/gas/alpha/fp.exp | 15 + gas/testsuite/gas/alpha/fp.s | 14 + gas/testsuite/gas/arc/alias.d | 68 + gas/testsuite/gas/arc/alias.s | 76 + gas/testsuite/gas/arc/arc.exp | 114 + gas/testsuite/gas/arc/branch.d | 45 + gas/testsuite/gas/arc/branch.s | 47 + gas/testsuite/gas/arc/flag.d | 29 + gas/testsuite/gas/arc/flag.s | 27 + gas/testsuite/gas/arc/insn3.d | 44 + gas/testsuite/gas/arc/insn3.s | 52 + gas/testsuite/gas/arc/j.d | 75 + gas/testsuite/gas/arc/j.s | 45 + gas/testsuite/gas/arc/ld.d | 30 + gas/testsuite/gas/arc/ld.s | 24 + gas/testsuite/gas/arc/math.d | 78 + gas/testsuite/gas/arc/math.s | 89 + gas/testsuite/gas/arc/sshift.d | 44 + gas/testsuite/gas/arc/sshift.s | 52 + gas/testsuite/gas/arc/st.d | 25 + gas/testsuite/gas/arc/st.s | 19 + gas/testsuite/gas/arc/warn.exp | 13 + gas/testsuite/gas/arc/warn.s | 14 + gas/testsuite/gas/arm/arch4t.s | 21 + gas/testsuite/gas/arm/arm.exp | 34 + gas/testsuite/gas/arm/arm3.s | 6 + gas/testsuite/gas/arm/arm6.s | 12 + gas/testsuite/gas/arm/arm7dm.s | 12 + gas/testsuite/gas/arm/arm7t.d | 68 + gas/testsuite/gas/arm/arm7t.s | 79 + gas/testsuite/gas/arm/copro.s | 24 + gas/testsuite/gas/arm/float.s | 162 + gas/testsuite/gas/arm/immed.s | 11 + gas/testsuite/gas/arm/inst.d | 168 + gas/testsuite/gas/arm/inst.s | 189 + gas/testsuite/gas/arm/le-fpconst.d | 8 + gas/testsuite/gas/arm/le-fpconst.s | 8 + gas/testsuite/gas/arm/thumb.s | 193 + gas/testsuite/gas/d30v/align.d | 17 + gas/testsuite/gas/d30v/align.s | 28 + gas/testsuite/gas/d30v/array.d | 31 + gas/testsuite/gas/d30v/array.s | 15 + gas/testsuite/gas/d30v/bittest.d | 20 + gas/testsuite/gas/d30v/bittest.l | 56 + gas/testsuite/gas/d30v/bittest.s | 28 + gas/testsuite/gas/d30v/d30.exp | 35 + gas/testsuite/gas/d30v/guard-debug.d | 25 + gas/testsuite/gas/d30v/guard-debug.s | 17 + gas/testsuite/gas/d30v/guard.d | 17 + gas/testsuite/gas/d30v/guard.s | 24 + gas/testsuite/gas/d30v/inst.d | 256 + gas/testsuite/gas/d30v/inst.s | 504 + gas/testsuite/gas/d30v/label-debug.d | 24 + gas/testsuite/gas/d30v/label-debug.s | 11 + gas/testsuite/gas/d30v/label.d | 16 + gas/testsuite/gas/d30v/label.s | 11 + gas/testsuite/gas/d30v/mul.d | 20 + gas/testsuite/gas/d30v/mul.s | 19 + gas/testsuite/gas/d30v/opt.d | 89 + gas/testsuite/gas/d30v/opt.s | 216 + gas/testsuite/gas/d30v/reloc.d | 93 + gas/testsuite/gas/d30v/reloc.s | 68 + gas/testsuite/gas/d30v/serial.l | 46 + gas/testsuite/gas/d30v/serial.s | 14 + gas/testsuite/gas/d30v/serial2.l | 138 + gas/testsuite/gas/d30v/serial2.s | 29 + gas/testsuite/gas/d30v/serial2O.l | 99 + gas/testsuite/gas/d30v/serial2O.s | 29 + gas/testsuite/gas/d30v/warn_oddreg.l | 40 + gas/testsuite/gas/d30v/warn_oddreg.s | 12 + gas/testsuite/gas/fr30/allinsn.d | 440 + gas/testsuite/gas/fr30/allinsn.exp | 5 + gas/testsuite/gas/fr30/allinsn.s | 434 + gas/testsuite/gas/fr30/fr30.exp | 5 + gas/testsuite/gas/h8300/addsub.s | 16 + gas/testsuite/gas/h8300/addsubh.s | 25 + gas/testsuite/gas/h8300/addsubs.s | 25 + gas/testsuite/gas/h8300/bitops1.s | 18 + gas/testsuite/gas/h8300/bitops1h.s | 19 + gas/testsuite/gas/h8300/bitops1s.s | 29 + gas/testsuite/gas/h8300/bitops2.s | 15 + gas/testsuite/gas/h8300/bitops2h.s | 16 + gas/testsuite/gas/h8300/bitops2s.s | 23 + gas/testsuite/gas/h8300/bitops3.s | 15 + gas/testsuite/gas/h8300/bitops3h.s | 16 + gas/testsuite/gas/h8300/bitops3s.s | 24 + gas/testsuite/gas/h8300/bitops4.s | 18 + gas/testsuite/gas/h8300/bitops4h.s | 19 + gas/testsuite/gas/h8300/bitops4s.s | 29 + gas/testsuite/gas/h8300/branch.s | 10 + gas/testsuite/gas/h8300/branchh.s | 12 + gas/testsuite/gas/h8300/branchs.s | 12 + gas/testsuite/gas/h8300/cbranch.s | 23 + gas/testsuite/gas/h8300/cbranchh.s | 44 + gas/testsuite/gas/h8300/cbranchs.s | 44 + gas/testsuite/gas/h8300/cmpsi2.s | 28 + gas/testsuite/gas/h8300/compare.s | 6 + gas/testsuite/gas/h8300/compareh.s | 10 + gas/testsuite/gas/h8300/compares.s | 10 + gas/testsuite/gas/h8300/decimal.s | 5 + gas/testsuite/gas/h8300/decimalh.s | 6 + gas/testsuite/gas/h8300/decimals.s | 6 + gas/testsuite/gas/h8300/divmul.s | 5 + gas/testsuite/gas/h8300/divmulh.s | 12 + gas/testsuite/gas/h8300/divmuls.s | 12 + gas/testsuite/gas/h8300/extendh.s | 8 + gas/testsuite/gas/h8300/extends.s | 8 + gas/testsuite/gas/h8300/ffxx1.d | 23 + gas/testsuite/gas/h8300/ffxx1.s | 20 + gas/testsuite/gas/h8300/h8300.exp | 2183 ++++ gas/testsuite/gas/h8300/incdec.s | 5 + gas/testsuite/gas/h8300/incdech.s | 14 + gas/testsuite/gas/h8300/incdecs.s | 14 + gas/testsuite/gas/h8300/logical.s | 14 + gas/testsuite/gas/h8300/logicalh.s | 31 + gas/testsuite/gas/h8300/logicals.s | 34 + gas/testsuite/gas/h8300/macs.s | 11 + gas/testsuite/gas/h8300/misc.s | 13 + gas/testsuite/gas/h8300/misch.s | 27 + gas/testsuite/gas/h8300/miscs.s | 41 + gas/testsuite/gas/h8300/mov32bug.s | 4 + gas/testsuite/gas/h8300/movb.s | 15 + gas/testsuite/gas/h8300/movbh.s | 20 + gas/testsuite/gas/h8300/movbs.s | 20 + gas/testsuite/gas/h8300/movlh.s | 18 + gas/testsuite/gas/h8300/movls.s | 18 + gas/testsuite/gas/h8300/movw.s | 13 + gas/testsuite/gas/h8300/movwh.s | 18 + gas/testsuite/gas/h8300/movws.s | 18 + gas/testsuite/gas/h8300/multiples.s | 10 + gas/testsuite/gas/h8300/pushpop.s | 5 + gas/testsuite/gas/h8300/pushpoph.s | 8 + gas/testsuite/gas/h8300/pushpops.s | 8 + gas/testsuite/gas/h8300/rotsh.s | 11 + gas/testsuite/gas/h8300/rotshh.s | 27 + gas/testsuite/gas/h8300/rotshs.s | 51 + gas/testsuite/gas/hppa/README | 34 + gas/testsuite/gas/hppa/basic/add.s | 100 + gas/testsuite/gas/hppa/basic/addi.s | 83 + gas/testsuite/gas/hppa/basic/basic.exp | 2262 +++++ gas/testsuite/gas/hppa/basic/branch.s | 227 + gas/testsuite/gas/hppa/basic/comclr.s | 50 + gas/testsuite/gas/hppa/basic/copr.s | 19 + gas/testsuite/gas/hppa/basic/coprmem.s | 55 + gas/testsuite/gas/hppa/basic/dcor.s | 41 + gas/testsuite/gas/hppa/basic/deposit.s | 88 + gas/testsuite/gas/hppa/basic/ds.s | 32 + gas/testsuite/gas/hppa/basic/extract.s | 51 + gas/testsuite/gas/hppa/basic/fmem.s | 52 + gas/testsuite/gas/hppa/basic/fmemLRbug.s | 76 + gas/testsuite/gas/hppa/basic/fp_comp.s | 81 + gas/testsuite/gas/hppa/basic/fp_conv.s | 92 + gas/testsuite/gas/hppa/basic/fp_fcmp.s | 114 + gas/testsuite/gas/hppa/basic/fp_misc.s | 18 + gas/testsuite/gas/hppa/basic/imem.s | 93 + gas/testsuite/gas/hppa/basic/immed.s | 21 + gas/testsuite/gas/hppa/basic/logical.s | 60 + gas/testsuite/gas/hppa/basic/purge.s | 35 + gas/testsuite/gas/hppa/basic/sh1add.s | 67 + gas/testsuite/gas/hppa/basic/sh2add.s | 67 + gas/testsuite/gas/hppa/basic/sh3add.s | 67 + gas/testsuite/gas/hppa/basic/shift.s | 34 + gas/testsuite/gas/hppa/basic/special.s | 15 + gas/testsuite/gas/hppa/basic/spop.s | 34 + gas/testsuite/gas/hppa/basic/sub.s | 117 + gas/testsuite/gas/hppa/basic/subi.s | 49 + gas/testsuite/gas/hppa/basic/system.s | 46 + gas/testsuite/gas/hppa/basic/unit.s | 55 + gas/testsuite/gas/hppa/basic/weird.s | 870 ++ gas/testsuite/gas/hppa/parse/align1.s | 41 + gas/testsuite/gas/hppa/parse/align2.s | 15 + gas/testsuite/gas/hppa/parse/appbug.s | 1 + gas/testsuite/gas/hppa/parse/badfmpyadd.s | 33 + gas/testsuite/gas/hppa/parse/block1.s | 18 + gas/testsuite/gas/hppa/parse/block2.s | 15 + gas/testsuite/gas/hppa/parse/calldatabug.s | 189 + gas/testsuite/gas/hppa/parse/callinfobug.s | 8 + gas/testsuite/gas/hppa/parse/defbug.s | 18 + gas/testsuite/gas/hppa/parse/entrybug.s | 24 + gas/testsuite/gas/hppa/parse/exportbug.s | 14 + gas/testsuite/gas/hppa/parse/exprbug.s | 39 + gas/testsuite/gas/hppa/parse/fixup7bug.s | 6192 ++++++++++++ gas/testsuite/gas/hppa/parse/global.s | 15 + gas/testsuite/gas/hppa/parse/labelbug.s | 35 + gas/testsuite/gas/hppa/parse/linesepbug.s | 20 + gas/testsuite/gas/hppa/parse/lselbug.s | 18 + gas/testsuite/gas/hppa/parse/nosubspace.s | 21 + gas/testsuite/gas/hppa/parse/parse.exp | 222 + gas/testsuite/gas/hppa/parse/procbug.s | 16 + gas/testsuite/gas/hppa/parse/regpopbug.s | 17 + gas/testsuite/gas/hppa/parse/spacebug.s | 3 + gas/testsuite/gas/hppa/parse/ssbug.s | 10 + gas/testsuite/gas/hppa/parse/stdreg.s | 27 + gas/testsuite/gas/hppa/parse/stringer.s | 19 + gas/testsuite/gas/hppa/parse/undefbug.s | 14 + gas/testsuite/gas/hppa/parse/versionbug.s | 9 + gas/testsuite/gas/hppa/parse/xmpyubug.s | 17 + gas/testsuite/gas/hppa/reloc/applybug.s | 130 + gas/testsuite/gas/hppa/reloc/blebug.s | 16 + gas/testsuite/gas/hppa/reloc/blebug2.s | 14 + gas/testsuite/gas/hppa/reloc/blebug3.s | 14 + gas/testsuite/gas/hppa/reloc/exitbug.s | 19 + gas/testsuite/gas/hppa/reloc/fixupbug.s | 19 + gas/testsuite/gas/hppa/reloc/funcrelocbug.s | 186 + gas/testsuite/gas/hppa/reloc/labelopbug.s | 37 + gas/testsuite/gas/hppa/reloc/longcall.s | 40 + gas/testsuite/gas/hppa/reloc/picreloc.s | 13 + gas/testsuite/gas/hppa/reloc/plabelbug.s | 47 + gas/testsuite/gas/hppa/reloc/r_no_reloc.s | 45 + gas/testsuite/gas/hppa/reloc/reduce.s | 48 + gas/testsuite/gas/hppa/reloc/reduce2.s | 80 + gas/testsuite/gas/hppa/reloc/reduce3.s | 51 + gas/testsuite/gas/hppa/reloc/reloc.exp | 679 ++ gas/testsuite/gas/hppa/reloc/roundmode.s | 23 + gas/testsuite/gas/hppa/reloc/selectorbug.s | 28 + gas/testsuite/gas/hppa/unsorted/align3.s | 20 + gas/testsuite/gas/hppa/unsorted/align4.s | 4 + gas/testsuite/gas/hppa/unsorted/brlenbug.s | 3502 +++++++ gas/testsuite/gas/hppa/unsorted/common.s | 8 + gas/testsuite/gas/hppa/unsorted/fragbug.s | 3 + gas/testsuite/gas/hppa/unsorted/globalbug.s | 16 + gas/testsuite/gas/hppa/unsorted/importbug.s | 42 + gas/testsuite/gas/hppa/unsorted/labeldiffs.s | 40 + gas/testsuite/gas/hppa/unsorted/locallabel.s | 15 + gas/testsuite/gas/hppa/unsorted/ss_align.s | 12 + gas/testsuite/gas/hppa/unsorted/unsorted.exp | 258 + gas/testsuite/gas/i386/amd.d | 37 + gas/testsuite/gas/i386/amd.s | 33 + gas/testsuite/gas/i386/float.l | 81 + gas/testsuite/gas/i386/float.s | 68 + gas/testsuite/gas/i386/general.l | 205 + gas/testsuite/gas/i386/general.s | 152 + gas/testsuite/gas/i386/i386.exp | 34 + gas/testsuite/gas/i386/inval.l | 98 + gas/testsuite/gas/i386/inval.s | 48 + gas/testsuite/gas/i386/modrm.l | 1984 ++++ gas/testsuite/gas/i386/modrm.s | 1671 ++++ gas/testsuite/gas/i386/opcode.d | 574 ++ gas/testsuite/gas/i386/opcode.s | 567 ++ gas/testsuite/gas/i386/prefix.d | 15 + gas/testsuite/gas/i386/prefix.s | 11 + gas/testsuite/gas/i386/reloc.d | 15 + gas/testsuite/gas/i386/reloc.s | 8 + gas/testsuite/gas/i386/white.l | 21 + gas/testsuite/gas/i386/white.s | 18 + gas/testsuite/gas/ieee-fp/x930509a.exp | 25 + gas/testsuite/gas/ieee-fp/x930509a.s | 5 + gas/testsuite/gas/m32r/allinsn.d | 374 + gas/testsuite/gas/m32r/allinsn.exp | 5 + gas/testsuite/gas/m32r/allinsn.s | 501 + gas/testsuite/gas/m32r/fslot.d | 31 + gas/testsuite/gas/m32r/fslot.s | 27 + gas/testsuite/gas/m32r/high-1.d | 19 + gas/testsuite/gas/m32r/high-1.s | 14 + gas/testsuite/gas/m32r/m32r.exp | 8 + gas/testsuite/gas/m32r/outofrange.s | 145 + gas/testsuite/gas/m32r/relax-1.d | 18 + gas/testsuite/gas/m32r/relax-1.s | 17 + gas/testsuite/gas/m32r/uppercase.d | 26 + gas/testsuite/gas/m32r/uppercase.s | 14 + gas/testsuite/gas/m68k-coff/gas.exp | 15 + gas/testsuite/gas/m68k-coff/p2389.s | 19 + gas/testsuite/gas/m68k-coff/p2389a.s | 3 + gas/testsuite/gas/m68k-coff/p2430.s | 6 + gas/testsuite/gas/m68k-coff/p2430a.s | 4 + gas/testsuite/gas/m68k-coff/t1.s | 36 + gas/testsuite/gas/m68k/all.exp | 39 + gas/testsuite/gas/m68k/bitfield.d | 28 + gas/testsuite/gas/m68k/bitfield.s | 24 + gas/testsuite/gas/m68k/cas.d | 20 + gas/testsuite/gas/m68k/cas.s | 16 + gas/testsuite/gas/m68k/disperr.s | 16 + gas/testsuite/gas/m68k/fmoveml.d | 60 + gas/testsuite/gas/m68k/fmoveml.s | 58 + gas/testsuite/gas/m68k/link.d | 17 + gas/testsuite/gas/m68k/link.s | 13 + gas/testsuite/gas/m68k/op68000.d | 195 + gas/testsuite/gas/m68k/operands.d | 242 + gas/testsuite/gas/m68k/operands.s | 272 + gas/testsuite/gas/m68k/p2410.s | 15 + gas/testsuite/gas/m68k/p2663.s | 16 + gas/testsuite/gas/m68k/pcrel.d | 88 + gas/testsuite/gas/m68k/pcrel.s | 59 + gas/testsuite/gas/m68k/pic1.s | 5 + gas/testsuite/gas/m68k/t2.d | 8 + gas/testsuite/gas/m68k/t2.s | 6 + gas/testsuite/gas/m88k/init.d | 11 + gas/testsuite/gas/m88k/init.s | 5 + gas/testsuite/gas/m88k/m88k.exp | 10 + gas/testsuite/gas/macros/err.s | 5 + gas/testsuite/gas/macros/irp.d | 13 + gas/testsuite/gas/macros/irp.s | 8 + gas/testsuite/gas/macros/macros.exp | 22 + gas/testsuite/gas/macros/rept.d | 10 + gas/testsuite/gas/macros/rept.s | 3 + gas/testsuite/gas/macros/semi.d | 8 + gas/testsuite/gas/macros/semi.s | 14 + gas/testsuite/gas/macros/test1.d | 5 + gas/testsuite/gas/macros/test1.s | 7 + gas/testsuite/gas/macros/test2.d | 10 + gas/testsuite/gas/macros/test2.s | 9 + gas/testsuite/gas/macros/test3.d | 8 + gas/testsuite/gas/macros/test3.s | 7 + gas/testsuite/gas/mcore/allinsn.d | 400 + gas/testsuite/gas/mcore/allinsn.exp | 5 + gas/testsuite/gas/mcore/allinsn.s | 146 + gas/testsuite/gas/mips/abs.d | 15 + gas/testsuite/gas/mips/abs.s | 5 + gas/testsuite/gas/mips/add.d | 20 + gas/testsuite/gas/mips/add.s | 16 + gas/testsuite/gas/mips/and.d | 34 + gas/testsuite/gas/mips/and.s | 28 + gas/testsuite/gas/mips/beq.d | 40 + gas/testsuite/gas/mips/beq.s | 28 + gas/testsuite/gas/mips/bge.d | 53 + gas/testsuite/gas/mips/bge.s | 31 + gas/testsuite/gas/mips/bgeu.d | 47 + gas/testsuite/gas/mips/bgeu.s | 27 + gas/testsuite/gas/mips/blt.d | 53 + gas/testsuite/gas/mips/blt.s | 31 + gas/testsuite/gas/mips/bltu.d | 47 + gas/testsuite/gas/mips/bltu.s | 27 + gas/testsuite/gas/mips/break20.d | 18 + gas/testsuite/gas/mips/break20.s | 17 + gas/testsuite/gas/mips/delay.d | 20 + gas/testsuite/gas/mips/delay.s | 8 + gas/testsuite/gas/mips/div-ilocks.d | 110 + gas/testsuite/gas/mips/div.d | 125 + gas/testsuite/gas/mips/div.s | 41 + gas/testsuite/gas/mips/dli.d | 115 + gas/testsuite/gas/mips/dli.s | 67 + gas/testsuite/gas/mips/elf_e_flags.c | 24 + gas/testsuite/gas/mips/elf_e_flags.s | 43 + gas/testsuite/gas/mips/elf_e_flags1.d | 26 + gas/testsuite/gas/mips/elf_e_flags2.d | 26 + gas/testsuite/gas/mips/elf_e_flags3.d | 26 + gas/testsuite/gas/mips/elf_e_flags4.d | 26 + gas/testsuite/gas/mips/itbl | 19 + gas/testsuite/gas/mips/itbl.s | 18 + gas/testsuite/gas/mips/jal-empic.d | 26 + gas/testsuite/gas/mips/jal-svr4pic.d | 39 + gas/testsuite/gas/mips/jal-svr4pic.s | 20 + gas/testsuite/gas/mips/jal-xgot.d | 42 + gas/testsuite/gas/mips/jal.d | 24 + gas/testsuite/gas/mips/jal.s | 11 + gas/testsuite/gas/mips/la-empic.d | 105 + gas/testsuite/gas/mips/la-empic.s | 57 + gas/testsuite/gas/mips/la-svr4pic.d | 474 + gas/testsuite/gas/mips/la-xgot.d | 618 ++ gas/testsuite/gas/mips/la.d | 384 + gas/testsuite/gas/mips/la.s | 114 + gas/testsuite/gas/mips/lb-empic.d | 102 + gas/testsuite/gas/mips/lb-pic.s | 55 + gas/testsuite/gas/mips/lb-svr4pic.d | 182 + gas/testsuite/gas/mips/lb-xgot-ilocks.d | 214 + gas/testsuite/gas/mips/lb-xgot.d | 242 + gas/testsuite/gas/mips/lb.d | 395 + gas/testsuite/gas/mips/lb.s | 125 + gas/testsuite/gas/mips/ld-empic.d | 186 + gas/testsuite/gas/mips/ld-ilocks-addr32.d | 632 ++ gas/testsuite/gas/mips/ld-ilocks.d | 631 ++ gas/testsuite/gas/mips/ld-pic.s | 60 + gas/testsuite/gas/mips/ld-svr4pic.d | 225 + gas/testsuite/gas/mips/ld-xgot.d | 273 + gas/testsuite/gas/mips/ld.d | 639 ++ gas/testsuite/gas/mips/ld.s | 144 + gas/testsuite/gas/mips/li.d | 16 + gas/testsuite/gas/mips/li.s | 12 + gas/testsuite/gas/mips/lif-empic.d | 24 + gas/testsuite/gas/mips/lif-svr4pic.d | 30 + gas/testsuite/gas/mips/lif-xgot.d | 30 + gas/testsuite/gas/mips/lifloat.d | 23 + gas/testsuite/gas/mips/lifloat.s | 24 + gas/testsuite/gas/mips/lineno.d | 97 + gas/testsuite/gas/mips/lineno.s | 60 + gas/testsuite/gas/mips/mips.exp | 102 + gas/testsuite/gas/mips/mips16.d | 683 ++ gas/testsuite/gas/mips/mips16.s | 258 + gas/testsuite/gas/mips/mips4.d | 51 + gas/testsuite/gas/mips/mips4.s | 52 + gas/testsuite/gas/mips/mips4010.d | 23 + gas/testsuite/gas/mips/mips4010.s | 20 + gas/testsuite/gas/mips/mips4100.d | 15 + gas/testsuite/gas/mips/mips4100.s | 10 + gas/testsuite/gas/mips/mips4650.d | 14 + gas/testsuite/gas/mips/mips4650.s | 8 + gas/testsuite/gas/mips/mul-ilocks.d | 81 + gas/testsuite/gas/mips/mul.d | 92 + gas/testsuite/gas/mips/mul.s | 27 + gas/testsuite/gas/mips/nodelay.d | 19 + gas/testsuite/gas/mips/rol.d | 37 + gas/testsuite/gas/mips/rol.s | 12 + gas/testsuite/gas/mips/sb.d | 396 + gas/testsuite/gas/mips/sb.s | 124 + gas/testsuite/gas/mips/sync.d | 10 + gas/testsuite/gas/mips/sync.s | 5 + gas/testsuite/gas/mips/trap20.d | 20 + gas/testsuite/gas/mips/trap20.s | 18 + gas/testsuite/gas/mips/trunc.d | 29 + gas/testsuite/gas/mips/trunc.s | 6 + gas/testsuite/gas/mips/uld.d | 270 + gas/testsuite/gas/mips/uld.s | 66 + gas/testsuite/gas/mips/ulh-empic.d | 91 + gas/testsuite/gas/mips/ulh-pic.s | 36 + gas/testsuite/gas/mips/ulh-svr4pic.d | 124 + gas/testsuite/gas/mips/ulh-xgot.d | 154 + gas/testsuite/gas/mips/ulh.d | 374 + gas/testsuite/gas/mips/ulh.s | 69 + gas/testsuite/gas/mips/ulw.d | 270 + gas/testsuite/gas/mips/ulw.s | 66 + gas/testsuite/gas/mips/usd.d | 270 + gas/testsuite/gas/mips/usd.s | 66 + gas/testsuite/gas/mips/ush.d | 455 + gas/testsuite/gas/mips/ush.s | 65 + gas/testsuite/gas/mips/usw.d | 270 + gas/testsuite/gas/mips/usw.s | 66 + gas/testsuite/gas/mn10200/add.s | 13 + gas/testsuite/gas/mn10200/basic.exp | 836 ++ gas/testsuite/gas/mn10200/bcc.s | 17 + gas/testsuite/gas/mn10200/bccx.s | 16 + gas/testsuite/gas/mn10200/bit.s | 5 + gas/testsuite/gas/mn10200/cmp.s | 10 + gas/testsuite/gas/mn10200/ext.s | 7 + gas/testsuite/gas/mn10200/logical.s | 12 + gas/testsuite/gas/mn10200/mov1.s | 13 + gas/testsuite/gas/mn10200/mov2.s | 10 + gas/testsuite/gas/mn10200/mov3.s | 11 + gas/testsuite/gas/mn10200/mov4.s | 9 + gas/testsuite/gas/mn10200/movb.s | 13 + gas/testsuite/gas/mn10200/movbu.s | 8 + gas/testsuite/gas/mn10200/movx.s | 7 + gas/testsuite/gas/mn10200/muldiv.s | 4 + gas/testsuite/gas/mn10200/other.s | 10 + gas/testsuite/gas/mn10200/shift.s | 5 + gas/testsuite/gas/mn10200/sub.s | 10 + gas/testsuite/gas/mn10300/add.s | 15 + gas/testsuite/gas/mn10300/basic.exp | 986 ++ gas/testsuite/gas/mn10300/bcc.s | 17 + gas/testsuite/gas/mn10300/bit.s | 12 + gas/testsuite/gas/mn10300/cmp.s | 11 + gas/testsuite/gas/mn10300/ext.s | 7 + gas/testsuite/gas/mn10300/extend.s | 15 + gas/testsuite/gas/mn10300/logical.s | 15 + gas/testsuite/gas/mn10300/loop.s | 15 + gas/testsuite/gas/mn10300/mov1.s | 17 + gas/testsuite/gas/mn10300/mov2.s | 16 + gas/testsuite/gas/mn10300/mov3.s | 16 + gas/testsuite/gas/mn10300/mov4.s | 13 + gas/testsuite/gas/mn10300/movbu.s | 21 + gas/testsuite/gas/mn10300/movhu.s | 21 + gas/testsuite/gas/mn10300/movm.s | 5 + gas/testsuite/gas/mn10300/muldiv.s | 5 + gas/testsuite/gas/mn10300/other.s | 20 + gas/testsuite/gas/mn10300/shift.s | 10 + gas/testsuite/gas/mn10300/sub.s | 8 + gas/testsuite/gas/mn10300/udf.s | 129 + gas/testsuite/gas/mri/char.d | 9 + gas/testsuite/gas/mri/char.s | 6 + gas/testsuite/gas/mri/comment.d | 9 + gas/testsuite/gas/mri/comment.s | 13 + gas/testsuite/gas/mri/common.d | 8 + gas/testsuite/gas/mri/common.s | 11 + gas/testsuite/gas/mri/constants.d | 20 + gas/testsuite/gas/mri/constants.s | 31 + gas/testsuite/gas/mri/empty.s | 9 + gas/testsuite/gas/mri/equ.d | 7 + gas/testsuite/gas/mri/equ.s | 3 + gas/testsuite/gas/mri/expr.d | 11 + gas/testsuite/gas/mri/expr.s | 7 + gas/testsuite/gas/mri/float.d | 10 + gas/testsuite/gas/mri/float.s | 7 + gas/testsuite/gas/mri/for.d | 30 + gas/testsuite/gas/mri/for.s | 22 + gas/testsuite/gas/mri/if.d | 25 + gas/testsuite/gas/mri/if.s | 17 + gas/testsuite/gas/mri/immconst.d | 22 + gas/testsuite/gas/mri/label.d | 8 + gas/testsuite/gas/mri/label.s | 5 + gas/testsuite/gas/mri/moveml.d | 27 + gas/testsuite/gas/mri/moveml.s | 17 + gas/testsuite/gas/mri/mri.exp | 28 + gas/testsuite/gas/mri/repeat.d | 16 + gas/testsuite/gas/mri/repeat.s | 14 + gas/testsuite/gas/mri/semi.d | 9 + gas/testsuite/gas/mri/semi.s | 14 + gas/testsuite/gas/mri/while.d | 18 + gas/testsuite/gas/mri/while.s | 14 + gas/testsuite/gas/ppc/astest.d | 74 + gas/testsuite/gas/ppc/astest.s | 52 + gas/testsuite/gas/ppc/astest2.d | 75 + gas/testsuite/gas/ppc/astest2.s | 52 + gas/testsuite/gas/ppc/ppc.exp | 21 + gas/testsuite/gas/ppc/simpshft.d | 27 + gas/testsuite/gas/ppc/simpshft.s | 110 + gas/testsuite/gas/sh/basic.exp | 86 + gas/testsuite/gas/sh/fp.s | 44 + gas/testsuite/gas/sparc-solaris/addend.exp | 36 + gas/testsuite/gas/sparc-solaris/addend.s | 11 + gas/testsuite/gas/sparc-solaris/gas.exp | 10 + gas/testsuite/gas/sparc-solaris/sol-cc.s | 81 + gas/testsuite/gas/sparc-solaris/sol-gcc.s | 66 + gas/testsuite/gas/sparc/asi.d | 35 + gas/testsuite/gas/sparc/asi.s | 28 + gas/testsuite/gas/sparc/membar.d | 19 + gas/testsuite/gas/sparc/membar.s | 12 + gas/testsuite/gas/sparc/mism-1.s | 22 + gas/testsuite/gas/sparc/mismatch.exp | 20 + gas/testsuite/gas/sparc/prefetch.d | 19 + gas/testsuite/gas/sparc/prefetch.s | 11 + gas/testsuite/gas/sparc/rdpr.d | 26 + gas/testsuite/gas/sparc/rdpr.s | 19 + gas/testsuite/gas/sparc/reloc64.d | 76 + gas/testsuite/gas/sparc/reloc64.s | 48 + gas/testsuite/gas/sparc/set64.d | 88 + gas/testsuite/gas/sparc/set64.s | 43 + gas/testsuite/gas/sparc/sparc.exp | 27 + gas/testsuite/gas/sparc/splet-2.d | 23 + gas/testsuite/gas/sparc/splet-2.s | 21 + gas/testsuite/gas/sparc/splet.d | 195 + gas/testsuite/gas/sparc/splet.s | 211 + gas/testsuite/gas/sparc/synth.d | 11 + gas/testsuite/gas/sparc/synth.s | 7 + gas/testsuite/gas/sparc/synth64.d | 19 + gas/testsuite/gas/sparc/synth64.s | 16 + gas/testsuite/gas/sparc/wrpr.d | 24 + gas/testsuite/gas/sparc/wrpr.s | 17 + gas/testsuite/gas/sun4/addend.d | 13 + gas/testsuite/gas/sun4/addend.exp | 7 + gas/testsuite/gas/sun4/addend.s | 11 + gas/testsuite/gas/template | 96 + gas/testsuite/gas/tic80/add.d | 22 + gas/testsuite/gas/tic80/add.lst | 34 + gas/testsuite/gas/tic80/add.s | 19 + gas/testsuite/gas/tic80/align.d | 19 + gas/testsuite/gas/tic80/align.lst | 47 + gas/testsuite/gas/tic80/align.s | 37 + gas/testsuite/gas/tic80/bitnum.d | 82 + gas/testsuite/gas/tic80/bitnum.lst | 97 + gas/testsuite/gas/tic80/bitnum.s | 85 + gas/testsuite/gas/tic80/ccode.d | 32 + gas/testsuite/gas/tic80/ccode.lst | 37 + gas/testsuite/gas/tic80/ccode.s | 30 + gas/testsuite/gas/tic80/cregops.d | 68 + gas/testsuite/gas/tic80/cregops.lst | 76 + gas/testsuite/gas/tic80/cregops.s | 64 + gas/testsuite/gas/tic80/endmask.d | 41 + gas/testsuite/gas/tic80/endmask.lst | 45 + gas/testsuite/gas/tic80/endmask.s | 38 + gas/testsuite/gas/tic80/float.d | 40 + gas/testsuite/gas/tic80/float.lst | 76 + gas/testsuite/gas/tic80/float.s | 32 + gas/testsuite/gas/tic80/regops.d | 188 + gas/testsuite/gas/tic80/regops.lst | 264 + gas/testsuite/gas/tic80/regops.s | 237 + gas/testsuite/gas/tic80/regops2.d | 68 + gas/testsuite/gas/tic80/regops2.lst | 96 + gas/testsuite/gas/tic80/regops2.s | 60 + gas/testsuite/gas/tic80/regops3.d | 28 + gas/testsuite/gas/tic80/regops3.lst | 27 + gas/testsuite/gas/tic80/regops3.s | 20 + gas/testsuite/gas/tic80/regops4.d | 28 + gas/testsuite/gas/tic80/regops4.lst | 27 + gas/testsuite/gas/tic80/regops4.s | 20 + gas/testsuite/gas/tic80/relocs1.c | 28 + gas/testsuite/gas/tic80/relocs1.d | 56 + gas/testsuite/gas/tic80/relocs1.lst | 80 + gas/testsuite/gas/tic80/relocs1.s | 66 + gas/testsuite/gas/tic80/relocs1b.d | 12 + gas/testsuite/gas/tic80/relocs2.c | 41 + gas/testsuite/gas/tic80/relocs2.d | 37 + gas/testsuite/gas/tic80/relocs2.lst | 112 + gas/testsuite/gas/tic80/relocs2.s | 72 + gas/testsuite/gas/tic80/relocs2b.d | 38 + gas/testsuite/gas/tic80/tic80.exp | 21 + gas/testsuite/gas/v850/arith.s | 24 + gas/testsuite/gas/v850/basic.exp | 438 + gas/testsuite/gas/v850/bit.s | 8 + gas/testsuite/gas/v850/branch.s | 24 + gas/testsuite/gas/v850/compare.s | 28 + gas/testsuite/gas/v850/fepsw.s | 2 + gas/testsuite/gas/v850/hilo.s | 5 + gas/testsuite/gas/v850/hilo2.s | 4 + gas/testsuite/gas/v850/jumps.s | 8 + gas/testsuite/gas/v850/logical.s | 11 + gas/testsuite/gas/v850/mem.s | 16 + gas/testsuite/gas/v850/misc.s | 13 + gas/testsuite/gas/v850/move.s | 8 + gas/testsuite/gas/v850/range.s | 2 + gas/testsuite/gas/v850/reloc.s | 7 + gas/testsuite/gas/vax/quad.exp | 23 + gas/testsuite/gas/vax/quad.s | 2 + gas/testsuite/gas/vtable/entry0.d | 10 + gas/testsuite/gas/vtable/entry0.s | 2 + gas/testsuite/gas/vtable/entry1.d | 10 + gas/testsuite/gas/vtable/entry1.s | 2 + gas/testsuite/gas/vtable/inherit0.d | 10 + gas/testsuite/gas/vtable/inherit0.s | 13 + gas/testsuite/gas/vtable/inherit1.l | 6 + gas/testsuite/gas/vtable/inherit1.s | 1 + gas/testsuite/gas/vtable/vtable.exp | 39 + gas/testsuite/gasp/INC1.H | 3 + gas/testsuite/gasp/INC2.H | 2 + gas/testsuite/gasp/assign.asm | 13 + gas/testsuite/gasp/assign.err | 1 + gas/testsuite/gasp/assign.out | 22 + gas/testsuite/gasp/condass.asm | 129 + gas/testsuite/gasp/condass.err | 0 gas/testsuite/gasp/condass.out | 155 + gas/testsuite/gasp/crash.asm | 22 + gas/testsuite/gasp/crash.err | 1 + gas/testsuite/gasp/crash.out | 3059 ++++++ gas/testsuite/gasp/crash1.asm | 13 + gas/testsuite/gasp/crash1.err | 0 gas/testsuite/gasp/crash1.out | 24 + gas/testsuite/gasp/crash2.asm | 41 + gas/testsuite/gasp/crash2.err | 0 gas/testsuite/gasp/crash2.out | 69 + gas/testsuite/gasp/data.asm | 23 + gas/testsuite/gasp/data.err | 0 gas/testsuite/gasp/data.out | 45 + gas/testsuite/gasp/exp.asm | 80 + gas/testsuite/gasp/exp.err | 7 + gas/testsuite/gasp/exp.out | 124 + gas/testsuite/gasp/gasp.exp | 40 + gas/testsuite/gasp/include.asm | 4 + gas/testsuite/gasp/include.err | 0 gas/testsuite/gasp/include.out | 15 + gas/testsuite/gasp/listing.asm | 15 + gas/testsuite/gasp/listing.err | 0 gas/testsuite/gasp/listing.out | 28 + gas/testsuite/gasp/macro.asm | 102 + gas/testsuite/gasp/macro.err | 0 gas/testsuite/gasp/macro.out | 382 + gas/testsuite/gasp/mdouble.asm | 47 + gas/testsuite/gasp/mdouble.err | 0 gas/testsuite/gasp/mdouble.out | 68 + gas/testsuite/gasp/mri/embed.asm | 5 + gas/testsuite/gasp/mri/embed.out | 9 + gas/testsuite/gasp/mri/exists.asm | 10 + gas/testsuite/gasp/mri/exists.out | 24 + gas/testsuite/gasp/mri/irp.asm | 4 + gas/testsuite/gasp/mri/irp.out | 8 + gas/testsuite/gasp/mri/irpc.asm | 3 + gas/testsuite/gasp/mri/irpc.out | 8 + gas/testsuite/gasp/mri/macro.asm | 8 + gas/testsuite/gasp/mri/macro.out | 18 + gas/testsuite/gasp/mri/narg.asm | 9 + gas/testsuite/gasp/mri/narg.out | 38 + gas/testsuite/gasp/mri/rept.asm | 3 + gas/testsuite/gasp/mri/rept.out | 16 + gas/testsuite/gasp/pl1.asm | 20 + gas/testsuite/gasp/pl1.err | 1 + gas/testsuite/gasp/pl1.out | 49 + gas/testsuite/gasp/pl2.asm | 28 + gas/testsuite/gasp/pl2.err | 0 gas/testsuite/gasp/pl2.out | 51 + gas/testsuite/gasp/pl3.asm | 30 + gas/testsuite/gasp/pl3.err | 0 gas/testsuite/gasp/pl3.out | 86 + gas/testsuite/gasp/pl4.asm | 10 + gas/testsuite/gasp/pl4.err | 0 gas/testsuite/gasp/pl4.out | 16 + gas/testsuite/gasp/pl5.asm | 15 + gas/testsuite/gasp/pl5.err | 0 gas/testsuite/gasp/pl5.out | 32 + gas/testsuite/gasp/pl6.asm | 21 + gas/testsuite/gasp/pl6.err | 0 gas/testsuite/gasp/pl6.out | 54 + gas/testsuite/gasp/pl7.asm | 12 + gas/testsuite/gasp/pl7.err | 1 + gas/testsuite/gasp/pl7.out | 26 + gas/testsuite/gasp/pl8.asm | 18 + gas/testsuite/gasp/pl8.err | 0 gas/testsuite/gasp/pl8.out | 33 + gas/testsuite/gasp/pr7583.asm | 3 + gas/testsuite/gasp/pr7583.err | 0 gas/testsuite/gasp/pr7583.out | 5 + gas/testsuite/gasp/reg.asm | 9 + gas/testsuite/gasp/reg.err | 0 gas/testsuite/gasp/reg.out | 15 + gas/testsuite/gasp/rep.asm | 13 + gas/testsuite/gasp/rep.err | 0 gas/testsuite/gasp/rep.out | 391 + gas/testsuite/gasp/repeat.asm | 14 + gas/testsuite/gasp/repeat.err | 0 gas/testsuite/gasp/repeat.out | 211 + gas/testsuite/gasp/reperr.asm | 2 + gas/testsuite/gasp/reperr.err | 1 + gas/testsuite/gasp/reperr.out | 5 + gas/testsuite/gasp/reperr1.asm | 3 + gas/testsuite/gasp/reperr1.err | 1 + gas/testsuite/gasp/reperr1.out | 5 + gas/testsuite/gasp/reperr2.asm | 6 + gas/testsuite/gasp/reperr2.err | 1 + gas/testsuite/gasp/reperr2.out | 14 + gas/testsuite/gasp/reperr3.asm | 21 + gas/testsuite/gasp/reperr3.err | 6 + gas/testsuite/gasp/reperr3.out | 2035 ++++ gas/testsuite/gasp/sdata.asm | 24 + gas/testsuite/gasp/sdata.err | 3 + gas/testsuite/gasp/sdata.out | 59 + gas/testsuite/gasp/sfunc.asm | 26 + gas/testsuite/gasp/sfunc.err | 0 gas/testsuite/gasp/sfunc.out | 49 + gas/testsuite/gasp/t1.asm | 3 + gas/testsuite/gasp/t1.err | 0 gas/testsuite/gasp/t1.out | 5 + gas/testsuite/gasp/t2.asm | 8 + gas/testsuite/gasp/t2.err | 0 gas/testsuite/gasp/t2.out | 13 + gas/testsuite/gasp/t3.asm | 12 + gas/testsuite/gasp/t3.err | 1 + gas/testsuite/gasp/t3.out | 25 + gas/testsuite/gasp/while.asm | 18 + gas/testsuite/gasp/while.err | 0 gas/testsuite/gasp/while.out | 388 + gas/testsuite/lib/doboth | 19 + gas/testsuite/lib/doobjcmp | 88 + gas/testsuite/lib/dostriptest | 14 + gas/testsuite/lib/dotest | 43 + gas/testsuite/lib/dounsreloc | 8 + gas/testsuite/lib/dounssym | 8 + gas/testsuite/lib/gas-defs.exp | 574 ++ gas/testsuite/lib/gas-dg.exp | 53 + gas/testsuite/lib/run | 2 + gas/vmsconf.sh | 128 + gas/write.c | 2884 ++++++ gas/write.h | 208 + 994 files changed, 276712 insertions(+) create mode 100644 gas/CONTRIBUTORS create mode 100644 gas/COPYING create mode 100644 gas/ChangeLog create mode 100644 gas/ChangeLog-9295 create mode 100644 gas/ChangeLog-9697 create mode 100644 gas/Makefile.am create mode 100644 gas/Makefile.in create mode 100644 gas/NEWS create mode 100644 gas/README create mode 100644 gas/README-vms create mode 100644 gas/acinclude.m4 create mode 100644 gas/aclocal.m4 create mode 100644 gas/app.c create mode 100644 gas/as.c create mode 100644 gas/as.h create mode 100644 gas/asintl.h create mode 100644 gas/atof-generic.c create mode 100644 gas/bignum-copy.c create mode 100644 gas/bignum.h create mode 100644 gas/bit_fix.h create mode 100644 gas/cgen.c create mode 100644 gas/cgen.h create mode 100644 gas/cond.c create mode 100644 gas/config-gas.com create mode 100644 gas/config.in create mode 100644 gas/config/aout_gnu.h create mode 100644 gas/config/atof-ieee.c create mode 100644 gas/config/atof-tahoe.c create mode 100644 gas/config/atof-vax.c create mode 100644 gas/config/e-i386coff.c create mode 100644 gas/config/e-i386elf.c create mode 100644 gas/config/e-mipsecoff.c create mode 100644 gas/config/e-mipself.c create mode 100644 gas/config/go32.cfg create mode 100644 gas/config/itbl-mips.h create mode 100644 gas/config/m68k-parse.h create mode 100644 gas/config/m68k-parse.y create mode 100644 gas/config/m88k-opcode.h create mode 100644 gas/config/obj-aout.c create mode 100644 gas/config/obj-aout.h create mode 100644 gas/config/obj-bout.c create mode 100644 gas/config/obj-bout.h create mode 100644 gas/config/obj-coff.c create mode 100644 gas/config/obj-coff.h create mode 100644 gas/config/obj-ecoff.c create mode 100644 gas/config/obj-ecoff.h create mode 100644 gas/config/obj-elf.c create mode 100644 gas/config/obj-elf.h create mode 100644 gas/config/obj-evax.c create mode 100644 gas/config/obj-evax.h create mode 100644 gas/config/obj-generic.c create mode 100644 gas/config/obj-generic.h create mode 100644 gas/config/obj-hp300.c create mode 100644 gas/config/obj-hp300.h create mode 100644 gas/config/obj-ieee.c create mode 100644 gas/config/obj-ieee.h create mode 100644 gas/config/obj-multi.c create mode 100644 gas/config/obj-multi.h create mode 100644 gas/config/obj-som.c create mode 100644 gas/config/obj-som.h create mode 100644 gas/config/obj-vms.c create mode 100644 gas/config/obj-vms.h create mode 100644 gas/config/tc-a29k.c create mode 100644 gas/config/tc-a29k.h create mode 100644 gas/config/tc-alpha.c create mode 100644 gas/config/tc-alpha.h create mode 100644 gas/config/tc-arc.c create mode 100644 gas/config/tc-arc.h create mode 100644 gas/config/tc-arm.c create mode 100644 gas/config/tc-arm.h create mode 100644 gas/config/tc-d10v.c create mode 100644 gas/config/tc-d10v.h create mode 100644 gas/config/tc-d30v.c create mode 100644 gas/config/tc-d30v.h create mode 100644 gas/config/tc-fr30.c create mode 100644 gas/config/tc-fr30.h create mode 100644 gas/config/tc-generic.c create mode 100644 gas/config/tc-generic.h create mode 100644 gas/config/tc-h8300.c create mode 100644 gas/config/tc-h8300.h create mode 100644 gas/config/tc-h8500.c create mode 100644 gas/config/tc-h8500.h create mode 100644 gas/config/tc-hppa.c create mode 100644 gas/config/tc-hppa.h create mode 100644 gas/config/tc-i386.c create mode 100644 gas/config/tc-i386.h create mode 100644 gas/config/tc-i860.c create mode 100644 gas/config/tc-i860.h create mode 100644 gas/config/tc-i960.c create mode 100644 gas/config/tc-i960.h create mode 100644 gas/config/tc-m32r.c create mode 100644 gas/config/tc-m32r.h create mode 100644 gas/config/tc-m68851.h create mode 100644 gas/config/tc-m68k.c create mode 100644 gas/config/tc-m68k.h create mode 100644 gas/config/tc-m88k.c create mode 100644 gas/config/tc-m88k.h create mode 100644 gas/config/tc-mcore.c create mode 100644 gas/config/tc-mcore.h create mode 100644 gas/config/tc-mips.c create mode 100644 gas/config/tc-mips.h create mode 100644 gas/config/tc-mn10200.c create mode 100644 gas/config/tc-mn10200.h create mode 100644 gas/config/tc-mn10300.c create mode 100644 gas/config/tc-mn10300.h create mode 100644 gas/config/tc-ns32k.c create mode 100644 gas/config/tc-ns32k.h create mode 100644 gas/config/tc-ppc.c create mode 100644 gas/config/tc-ppc.h create mode 100644 gas/config/tc-sh.c create mode 100644 gas/config/tc-sh.h create mode 100644 gas/config/tc-sparc.c create mode 100644 gas/config/tc-sparc.h create mode 100644 gas/config/tc-tahoe.c create mode 100644 gas/config/tc-tahoe.h create mode 100644 gas/config/tc-tic30.c create mode 100644 gas/config/tc-tic30.h create mode 100644 gas/config/tc-tic80.c create mode 100644 gas/config/tc-tic80.h create mode 100644 gas/config/tc-v850.c create mode 100644 gas/config/tc-v850.h create mode 100644 gas/config/tc-vax.c create mode 100644 gas/config/tc-vax.h create mode 100644 gas/config/tc-w65.c create mode 100644 gas/config/tc-w65.h create mode 100644 gas/config/tc-z8k.c create mode 100644 gas/config/tc-z8k.h create mode 100644 gas/config/te-386bsd.h create mode 100644 gas/config/te-aux.h create mode 100644 gas/config/te-delt88.h create mode 100644 gas/config/te-delta.h create mode 100644 gas/config/te-dpx2.h create mode 100644 gas/config/te-dynix.h create mode 100644 gas/config/te-epoc-pe.h create mode 100644 gas/config/te-generic.h create mode 100644 gas/config/te-go32.h create mode 100644 gas/config/te-hp300.h create mode 100644 gas/config/te-hppa.h create mode 100644 gas/config/te-i386aix.h create mode 100644 gas/config/te-ic960.h create mode 100644 gas/config/te-linux.h create mode 100644 gas/config/te-lnews.h create mode 100644 gas/config/te-lynx.h create mode 100644 gas/config/te-mach.h create mode 100644 gas/config/te-macos.h create mode 100644 gas/config/te-multi.h create mode 100644 gas/config/te-nbsd.h create mode 100644 gas/config/te-nbsd532.h create mode 100644 gas/config/te-pc532mach.h create mode 100644 gas/config/te-pe.h create mode 100644 gas/config/te-ppcnw.h create mode 100644 gas/config/te-psos.h create mode 100644 gas/config/te-riscix.h create mode 100644 gas/config/te-sparcaout.h create mode 100644 gas/config/te-sun3.h create mode 100644 gas/config/te-svr4.h create mode 100644 gas/config/te-sysv32.h create mode 100644 gas/config/vax-inst.h create mode 100644 gas/config/vms-a-conf.h create mode 100644 gas/config/vms-conf.h create mode 100755 gas/configure create mode 100644 gas/configure.bat create mode 100644 gas/configure.in create mode 100644 gas/debug.c create mode 100644 gas/dep-in.sed create mode 100644 gas/depend.c create mode 100644 gas/doc/Makefile.am create mode 100644 gas/doc/Makefile.in create mode 100644 gas/doc/all.texi create mode 100644 gas/doc/as.1 create mode 100644 gas/doc/as.texinfo create mode 100644 gas/doc/c-a29k.texi create mode 100644 gas/doc/c-arm.texi create mode 100644 gas/doc/c-d10v.texi create mode 100644 gas/doc/c-d30v.texi create mode 100644 gas/doc/c-h8300.texi create mode 100644 gas/doc/c-h8500.texi create mode 100644 gas/doc/c-hppa.texi create mode 100644 gas/doc/c-i386.texi create mode 100644 gas/doc/c-i960.texi create mode 100644 gas/doc/c-m32r.texi create mode 100644 gas/doc/c-m68k.texi create mode 100644 gas/doc/c-mips.texi create mode 100644 gas/doc/c-ns32k.texi create mode 100644 gas/doc/c-sh.texi create mode 100644 gas/doc/c-sparc.texi create mode 100644 gas/doc/c-v850.texi create mode 100644 gas/doc/c-vax.texi create mode 100644 gas/doc/c-z8k.texi create mode 100644 gas/doc/gasp.texi create mode 100644 gas/doc/h8.texi create mode 100644 gas/doc/internals.texi create mode 100644 gas/ecoff.c create mode 100644 gas/ecoff.h create mode 100644 gas/ehopt.c create mode 100644 gas/emul-target.h create mode 100644 gas/emul.h create mode 100644 gas/expr.c create mode 100644 gas/expr.h create mode 100644 gas/flonum-copy.c create mode 100644 gas/flonum-konst.c create mode 100644 gas/flonum-mult.c create mode 100644 gas/flonum.h create mode 100644 gas/frags.c create mode 100644 gas/frags.h create mode 100644 gas/gasp.c create mode 100644 gas/gdbinit.in create mode 100644 gas/hash.c create mode 100644 gas/hash.h create mode 100644 gas/input-file.c create mode 100644 gas/input-file.h create mode 100644 gas/input-scrub.c create mode 100644 gas/itbl-lex.l create mode 100644 gas/itbl-ops.c create mode 100644 gas/itbl-ops.h create mode 100644 gas/itbl-parse.y create mode 100644 gas/link.cmd create mode 100644 gas/listing.c create mode 100644 gas/listing.h create mode 100644 gas/literal.c create mode 100644 gas/mac-as.r create mode 100644 gas/macro.c create mode 100644 gas/macro.h create mode 100644 gas/makefile.vms create mode 100644 gas/messages.c create mode 100644 gas/mpw-config.in create mode 100644 gas/mpw-make.sed create mode 100644 gas/obj.h create mode 100644 gas/output-file.c create mode 100644 gas/output-file.h create mode 100644 gas/po/Make-in create mode 100644 gas/po/POTFILES.in create mode 100644 gas/po/gas.pot create mode 100644 gas/read.c create mode 100644 gas/read.h create mode 100644 gas/sb.c create mode 100644 gas/sb.h create mode 100644 gas/stabs.c create mode 100644 gas/stamp-h.in create mode 100644 gas/struc-symbol.h create mode 100644 gas/subsegs.c create mode 100644 gas/subsegs.h create mode 100644 gas/symbols.c create mode 100644 gas/symbols.h create mode 100644 gas/tc.h create mode 100644 gas/testsuite/ChangeLog create mode 100644 gas/testsuite/config/default.exp create mode 100644 gas/testsuite/gas/all/align.d create mode 100644 gas/testsuite/gas/all/align.s create mode 100644 gas/testsuite/gas/all/cofftag.d create mode 100644 gas/testsuite/gas/all/cofftag.s create mode 100644 gas/testsuite/gas/all/comment.s create mode 100644 gas/testsuite/gas/all/cond.d create mode 100644 gas/testsuite/gas/all/cond.s create mode 100644 gas/testsuite/gas/all/diff1.s create mode 100644 gas/testsuite/gas/all/float.s create mode 100644 gas/testsuite/gas/all/gas.exp create mode 100644 gas/testsuite/gas/all/itbl create mode 100644 gas/testsuite/gas/all/itbl-test.c create mode 100644 gas/testsuite/gas/all/itbl.s create mode 100644 gas/testsuite/gas/all/p1480.s create mode 100644 gas/testsuite/gas/all/p2425.s create mode 100644 gas/testsuite/gas/all/struct.d create mode 100644 gas/testsuite/gas/all/struct.s create mode 100644 gas/testsuite/gas/all/x930509.s create mode 100644 gas/testsuite/gas/alpha/fp.d create mode 100644 gas/testsuite/gas/alpha/fp.exp create mode 100644 gas/testsuite/gas/alpha/fp.s create mode 100644 gas/testsuite/gas/arc/alias.d create mode 100644 gas/testsuite/gas/arc/alias.s create mode 100644 gas/testsuite/gas/arc/arc.exp create mode 100644 gas/testsuite/gas/arc/branch.d create mode 100644 gas/testsuite/gas/arc/branch.s create mode 100644 gas/testsuite/gas/arc/flag.d create mode 100644 gas/testsuite/gas/arc/flag.s create mode 100644 gas/testsuite/gas/arc/insn3.d create mode 100644 gas/testsuite/gas/arc/insn3.s create mode 100644 gas/testsuite/gas/arc/j.d create mode 100644 gas/testsuite/gas/arc/j.s create mode 100644 gas/testsuite/gas/arc/ld.d create mode 100644 gas/testsuite/gas/arc/ld.s create mode 100644 gas/testsuite/gas/arc/math.d create mode 100644 gas/testsuite/gas/arc/math.s create mode 100644 gas/testsuite/gas/arc/sshift.d create mode 100644 gas/testsuite/gas/arc/sshift.s create mode 100644 gas/testsuite/gas/arc/st.d create mode 100644 gas/testsuite/gas/arc/st.s create mode 100644 gas/testsuite/gas/arc/warn.exp create mode 100644 gas/testsuite/gas/arc/warn.s create mode 100644 gas/testsuite/gas/arm/arch4t.s create mode 100644 gas/testsuite/gas/arm/arm.exp create mode 100644 gas/testsuite/gas/arm/arm3.s create mode 100644 gas/testsuite/gas/arm/arm6.s create mode 100644 gas/testsuite/gas/arm/arm7dm.s create mode 100644 gas/testsuite/gas/arm/arm7t.d create mode 100644 gas/testsuite/gas/arm/arm7t.s create mode 100644 gas/testsuite/gas/arm/copro.s create mode 100644 gas/testsuite/gas/arm/float.s create mode 100644 gas/testsuite/gas/arm/immed.s create mode 100644 gas/testsuite/gas/arm/inst.d create mode 100644 gas/testsuite/gas/arm/inst.s create mode 100644 gas/testsuite/gas/arm/le-fpconst.d create mode 100644 gas/testsuite/gas/arm/le-fpconst.s create mode 100644 gas/testsuite/gas/arm/thumb.s create mode 100644 gas/testsuite/gas/d30v/align.d create mode 100644 gas/testsuite/gas/d30v/align.s create mode 100644 gas/testsuite/gas/d30v/array.d create mode 100644 gas/testsuite/gas/d30v/array.s create mode 100644 gas/testsuite/gas/d30v/bittest.d create mode 100644 gas/testsuite/gas/d30v/bittest.l create mode 100644 gas/testsuite/gas/d30v/bittest.s create mode 100644 gas/testsuite/gas/d30v/d30.exp create mode 100644 gas/testsuite/gas/d30v/guard-debug.d create mode 100644 gas/testsuite/gas/d30v/guard-debug.s create mode 100644 gas/testsuite/gas/d30v/guard.d create mode 100644 gas/testsuite/gas/d30v/guard.s create mode 100644 gas/testsuite/gas/d30v/inst.d create mode 100644 gas/testsuite/gas/d30v/inst.s create mode 100644 gas/testsuite/gas/d30v/label-debug.d create mode 100644 gas/testsuite/gas/d30v/label-debug.s create mode 100644 gas/testsuite/gas/d30v/label.d create mode 100644 gas/testsuite/gas/d30v/label.s create mode 100644 gas/testsuite/gas/d30v/mul.d create mode 100644 gas/testsuite/gas/d30v/mul.s create mode 100644 gas/testsuite/gas/d30v/opt.d create mode 100644 gas/testsuite/gas/d30v/opt.s create mode 100644 gas/testsuite/gas/d30v/reloc.d create mode 100644 gas/testsuite/gas/d30v/reloc.s create mode 100644 gas/testsuite/gas/d30v/serial.l create mode 100644 gas/testsuite/gas/d30v/serial.s create mode 100644 gas/testsuite/gas/d30v/serial2.l create mode 100644 gas/testsuite/gas/d30v/serial2.s create mode 100644 gas/testsuite/gas/d30v/serial2O.l create mode 100644 gas/testsuite/gas/d30v/serial2O.s create mode 100644 gas/testsuite/gas/d30v/warn_oddreg.l create mode 100644 gas/testsuite/gas/d30v/warn_oddreg.s create mode 100644 gas/testsuite/gas/fr30/allinsn.d create mode 100644 gas/testsuite/gas/fr30/allinsn.exp create mode 100644 gas/testsuite/gas/fr30/allinsn.s create mode 100644 gas/testsuite/gas/fr30/fr30.exp create mode 100644 gas/testsuite/gas/h8300/addsub.s create mode 100644 gas/testsuite/gas/h8300/addsubh.s create mode 100644 gas/testsuite/gas/h8300/addsubs.s create mode 100644 gas/testsuite/gas/h8300/bitops1.s create mode 100644 gas/testsuite/gas/h8300/bitops1h.s create mode 100644 gas/testsuite/gas/h8300/bitops1s.s create mode 100644 gas/testsuite/gas/h8300/bitops2.s create mode 100644 gas/testsuite/gas/h8300/bitops2h.s create mode 100644 gas/testsuite/gas/h8300/bitops2s.s create mode 100644 gas/testsuite/gas/h8300/bitops3.s create mode 100644 gas/testsuite/gas/h8300/bitops3h.s create mode 100644 gas/testsuite/gas/h8300/bitops3s.s create mode 100644 gas/testsuite/gas/h8300/bitops4.s create mode 100644 gas/testsuite/gas/h8300/bitops4h.s create mode 100644 gas/testsuite/gas/h8300/bitops4s.s create mode 100644 gas/testsuite/gas/h8300/branch.s create mode 100644 gas/testsuite/gas/h8300/branchh.s create mode 100644 gas/testsuite/gas/h8300/branchs.s create mode 100644 gas/testsuite/gas/h8300/cbranch.s create mode 100644 gas/testsuite/gas/h8300/cbranchh.s create mode 100644 gas/testsuite/gas/h8300/cbranchs.s create mode 100644 gas/testsuite/gas/h8300/cmpsi2.s create mode 100644 gas/testsuite/gas/h8300/compare.s create mode 100644 gas/testsuite/gas/h8300/compareh.s create mode 100644 gas/testsuite/gas/h8300/compares.s create mode 100644 gas/testsuite/gas/h8300/decimal.s create mode 100644 gas/testsuite/gas/h8300/decimalh.s create mode 100644 gas/testsuite/gas/h8300/decimals.s create mode 100644 gas/testsuite/gas/h8300/divmul.s create mode 100644 gas/testsuite/gas/h8300/divmulh.s create mode 100644 gas/testsuite/gas/h8300/divmuls.s create mode 100644 gas/testsuite/gas/h8300/extendh.s create mode 100644 gas/testsuite/gas/h8300/extends.s create mode 100644 gas/testsuite/gas/h8300/ffxx1.d create mode 100644 gas/testsuite/gas/h8300/ffxx1.s create mode 100644 gas/testsuite/gas/h8300/h8300.exp create mode 100644 gas/testsuite/gas/h8300/incdec.s create mode 100644 gas/testsuite/gas/h8300/incdech.s create mode 100644 gas/testsuite/gas/h8300/incdecs.s create mode 100644 gas/testsuite/gas/h8300/logical.s create mode 100644 gas/testsuite/gas/h8300/logicalh.s create mode 100644 gas/testsuite/gas/h8300/logicals.s create mode 100644 gas/testsuite/gas/h8300/macs.s create mode 100644 gas/testsuite/gas/h8300/misc.s create mode 100644 gas/testsuite/gas/h8300/misch.s create mode 100644 gas/testsuite/gas/h8300/miscs.s create mode 100644 gas/testsuite/gas/h8300/mov32bug.s create mode 100644 gas/testsuite/gas/h8300/movb.s create mode 100644 gas/testsuite/gas/h8300/movbh.s create mode 100644 gas/testsuite/gas/h8300/movbs.s create mode 100644 gas/testsuite/gas/h8300/movlh.s create mode 100644 gas/testsuite/gas/h8300/movls.s create mode 100644 gas/testsuite/gas/h8300/movw.s create mode 100644 gas/testsuite/gas/h8300/movwh.s create mode 100644 gas/testsuite/gas/h8300/movws.s create mode 100644 gas/testsuite/gas/h8300/multiples.s create mode 100644 gas/testsuite/gas/h8300/pushpop.s create mode 100644 gas/testsuite/gas/h8300/pushpoph.s create mode 100644 gas/testsuite/gas/h8300/pushpops.s create mode 100644 gas/testsuite/gas/h8300/rotsh.s create mode 100644 gas/testsuite/gas/h8300/rotshh.s create mode 100644 gas/testsuite/gas/h8300/rotshs.s create mode 100644 gas/testsuite/gas/hppa/README create mode 100644 gas/testsuite/gas/hppa/basic/add.s create mode 100644 gas/testsuite/gas/hppa/basic/addi.s create mode 100644 gas/testsuite/gas/hppa/basic/basic.exp create mode 100644 gas/testsuite/gas/hppa/basic/branch.s create mode 100644 gas/testsuite/gas/hppa/basic/comclr.s create mode 100644 gas/testsuite/gas/hppa/basic/copr.s create mode 100644 gas/testsuite/gas/hppa/basic/coprmem.s create mode 100644 gas/testsuite/gas/hppa/basic/dcor.s create mode 100644 gas/testsuite/gas/hppa/basic/deposit.s create mode 100644 gas/testsuite/gas/hppa/basic/ds.s create mode 100644 gas/testsuite/gas/hppa/basic/extract.s create mode 100644 gas/testsuite/gas/hppa/basic/fmem.s create mode 100644 gas/testsuite/gas/hppa/basic/fmemLRbug.s create mode 100644 gas/testsuite/gas/hppa/basic/fp_comp.s create mode 100644 gas/testsuite/gas/hppa/basic/fp_conv.s create mode 100644 gas/testsuite/gas/hppa/basic/fp_fcmp.s create mode 100644 gas/testsuite/gas/hppa/basic/fp_misc.s create mode 100644 gas/testsuite/gas/hppa/basic/imem.s create mode 100644 gas/testsuite/gas/hppa/basic/immed.s create mode 100644 gas/testsuite/gas/hppa/basic/logical.s create mode 100644 gas/testsuite/gas/hppa/basic/purge.s create mode 100644 gas/testsuite/gas/hppa/basic/sh1add.s create mode 100644 gas/testsuite/gas/hppa/basic/sh2add.s create mode 100644 gas/testsuite/gas/hppa/basic/sh3add.s create mode 100644 gas/testsuite/gas/hppa/basic/shift.s create mode 100644 gas/testsuite/gas/hppa/basic/special.s create mode 100644 gas/testsuite/gas/hppa/basic/spop.s create mode 100644 gas/testsuite/gas/hppa/basic/sub.s create mode 100644 gas/testsuite/gas/hppa/basic/subi.s create mode 100644 gas/testsuite/gas/hppa/basic/system.s create mode 100644 gas/testsuite/gas/hppa/basic/unit.s create mode 100644 gas/testsuite/gas/hppa/basic/weird.s create mode 100644 gas/testsuite/gas/hppa/parse/align1.s create mode 100644 gas/testsuite/gas/hppa/parse/align2.s create mode 100644 gas/testsuite/gas/hppa/parse/appbug.s create mode 100644 gas/testsuite/gas/hppa/parse/badfmpyadd.s create mode 100644 gas/testsuite/gas/hppa/parse/block1.s create mode 100644 gas/testsuite/gas/hppa/parse/block2.s create mode 100644 gas/testsuite/gas/hppa/parse/calldatabug.s create mode 100644 gas/testsuite/gas/hppa/parse/callinfobug.s create mode 100644 gas/testsuite/gas/hppa/parse/defbug.s create mode 100644 gas/testsuite/gas/hppa/parse/entrybug.s create mode 100644 gas/testsuite/gas/hppa/parse/exportbug.s create mode 100644 gas/testsuite/gas/hppa/parse/exprbug.s create mode 100644 gas/testsuite/gas/hppa/parse/fixup7bug.s create mode 100644 gas/testsuite/gas/hppa/parse/global.s create mode 100644 gas/testsuite/gas/hppa/parse/labelbug.s create mode 100644 gas/testsuite/gas/hppa/parse/linesepbug.s create mode 100644 gas/testsuite/gas/hppa/parse/lselbug.s create mode 100644 gas/testsuite/gas/hppa/parse/nosubspace.s create mode 100644 gas/testsuite/gas/hppa/parse/parse.exp create mode 100644 gas/testsuite/gas/hppa/parse/procbug.s create mode 100644 gas/testsuite/gas/hppa/parse/regpopbug.s create mode 100644 gas/testsuite/gas/hppa/parse/spacebug.s create mode 100644 gas/testsuite/gas/hppa/parse/ssbug.s create mode 100644 gas/testsuite/gas/hppa/parse/stdreg.s create mode 100644 gas/testsuite/gas/hppa/parse/stringer.s create mode 100644 gas/testsuite/gas/hppa/parse/undefbug.s create mode 100644 gas/testsuite/gas/hppa/parse/versionbug.s create mode 100644 gas/testsuite/gas/hppa/parse/xmpyubug.s create mode 100644 gas/testsuite/gas/hppa/reloc/applybug.s create mode 100644 gas/testsuite/gas/hppa/reloc/blebug.s create mode 100644 gas/testsuite/gas/hppa/reloc/blebug2.s create mode 100644 gas/testsuite/gas/hppa/reloc/blebug3.s create mode 100644 gas/testsuite/gas/hppa/reloc/exitbug.s create mode 100644 gas/testsuite/gas/hppa/reloc/fixupbug.s create mode 100644 gas/testsuite/gas/hppa/reloc/funcrelocbug.s create mode 100644 gas/testsuite/gas/hppa/reloc/labelopbug.s create mode 100644 gas/testsuite/gas/hppa/reloc/longcall.s create mode 100644 gas/testsuite/gas/hppa/reloc/picreloc.s create mode 100644 gas/testsuite/gas/hppa/reloc/plabelbug.s create mode 100644 gas/testsuite/gas/hppa/reloc/r_no_reloc.s create mode 100644 gas/testsuite/gas/hppa/reloc/reduce.s create mode 100644 gas/testsuite/gas/hppa/reloc/reduce2.s create mode 100644 gas/testsuite/gas/hppa/reloc/reduce3.s create mode 100644 gas/testsuite/gas/hppa/reloc/reloc.exp create mode 100644 gas/testsuite/gas/hppa/reloc/roundmode.s create mode 100644 gas/testsuite/gas/hppa/reloc/selectorbug.s create mode 100644 gas/testsuite/gas/hppa/unsorted/align3.s create mode 100644 gas/testsuite/gas/hppa/unsorted/align4.s create mode 100644 gas/testsuite/gas/hppa/unsorted/brlenbug.s create mode 100644 gas/testsuite/gas/hppa/unsorted/common.s create mode 100644 gas/testsuite/gas/hppa/unsorted/fragbug.s create mode 100644 gas/testsuite/gas/hppa/unsorted/globalbug.s create mode 100644 gas/testsuite/gas/hppa/unsorted/importbug.s create mode 100644 gas/testsuite/gas/hppa/unsorted/labeldiffs.s create mode 100644 gas/testsuite/gas/hppa/unsorted/locallabel.s create mode 100644 gas/testsuite/gas/hppa/unsorted/ss_align.s create mode 100644 gas/testsuite/gas/hppa/unsorted/unsorted.exp create mode 100644 gas/testsuite/gas/i386/amd.d create mode 100644 gas/testsuite/gas/i386/amd.s create mode 100644 gas/testsuite/gas/i386/float.l create mode 100644 gas/testsuite/gas/i386/float.s create mode 100644 gas/testsuite/gas/i386/general.l create mode 100644 gas/testsuite/gas/i386/general.s create mode 100644 gas/testsuite/gas/i386/i386.exp create mode 100644 gas/testsuite/gas/i386/inval.l create mode 100644 gas/testsuite/gas/i386/inval.s create mode 100644 gas/testsuite/gas/i386/modrm.l create mode 100644 gas/testsuite/gas/i386/modrm.s create mode 100644 gas/testsuite/gas/i386/opcode.d create mode 100644 gas/testsuite/gas/i386/opcode.s create mode 100644 gas/testsuite/gas/i386/prefix.d create mode 100644 gas/testsuite/gas/i386/prefix.s create mode 100644 gas/testsuite/gas/i386/reloc.d create mode 100644 gas/testsuite/gas/i386/reloc.s create mode 100644 gas/testsuite/gas/i386/white.l create mode 100644 gas/testsuite/gas/i386/white.s create mode 100644 gas/testsuite/gas/ieee-fp/x930509a.exp create mode 100644 gas/testsuite/gas/ieee-fp/x930509a.s create mode 100644 gas/testsuite/gas/m32r/allinsn.d create mode 100644 gas/testsuite/gas/m32r/allinsn.exp create mode 100644 gas/testsuite/gas/m32r/allinsn.s create mode 100644 gas/testsuite/gas/m32r/fslot.d create mode 100644 gas/testsuite/gas/m32r/fslot.s create mode 100644 gas/testsuite/gas/m32r/high-1.d create mode 100644 gas/testsuite/gas/m32r/high-1.s create mode 100644 gas/testsuite/gas/m32r/m32r.exp create mode 100644 gas/testsuite/gas/m32r/outofrange.s create mode 100644 gas/testsuite/gas/m32r/relax-1.d create mode 100644 gas/testsuite/gas/m32r/relax-1.s create mode 100644 gas/testsuite/gas/m32r/uppercase.d create mode 100644 gas/testsuite/gas/m32r/uppercase.s create mode 100644 gas/testsuite/gas/m68k-coff/gas.exp create mode 100644 gas/testsuite/gas/m68k-coff/p2389.s create mode 100644 gas/testsuite/gas/m68k-coff/p2389a.s create mode 100644 gas/testsuite/gas/m68k-coff/p2430.s create mode 100644 gas/testsuite/gas/m68k-coff/p2430a.s create mode 100644 gas/testsuite/gas/m68k-coff/t1.s create mode 100644 gas/testsuite/gas/m68k/all.exp create mode 100644 gas/testsuite/gas/m68k/bitfield.d create mode 100644 gas/testsuite/gas/m68k/bitfield.s create mode 100644 gas/testsuite/gas/m68k/cas.d create mode 100644 gas/testsuite/gas/m68k/cas.s create mode 100644 gas/testsuite/gas/m68k/disperr.s create mode 100644 gas/testsuite/gas/m68k/fmoveml.d create mode 100644 gas/testsuite/gas/m68k/fmoveml.s create mode 100644 gas/testsuite/gas/m68k/link.d create mode 100644 gas/testsuite/gas/m68k/link.s create mode 100644 gas/testsuite/gas/m68k/op68000.d create mode 100644 gas/testsuite/gas/m68k/operands.d create mode 100644 gas/testsuite/gas/m68k/operands.s create mode 100644 gas/testsuite/gas/m68k/p2410.s create mode 100644 gas/testsuite/gas/m68k/p2663.s create mode 100644 gas/testsuite/gas/m68k/pcrel.d create mode 100644 gas/testsuite/gas/m68k/pcrel.s create mode 100644 gas/testsuite/gas/m68k/pic1.s create mode 100644 gas/testsuite/gas/m68k/t2.d create mode 100644 gas/testsuite/gas/m68k/t2.s create mode 100644 gas/testsuite/gas/m88k/init.d create mode 100644 gas/testsuite/gas/m88k/init.s create mode 100644 gas/testsuite/gas/m88k/m88k.exp create mode 100644 gas/testsuite/gas/macros/err.s create mode 100644 gas/testsuite/gas/macros/irp.d create mode 100644 gas/testsuite/gas/macros/irp.s create mode 100644 gas/testsuite/gas/macros/macros.exp create mode 100644 gas/testsuite/gas/macros/rept.d create mode 100644 gas/testsuite/gas/macros/rept.s create mode 100644 gas/testsuite/gas/macros/semi.d create mode 100644 gas/testsuite/gas/macros/semi.s create mode 100644 gas/testsuite/gas/macros/test1.d create mode 100644 gas/testsuite/gas/macros/test1.s create mode 100644 gas/testsuite/gas/macros/test2.d create mode 100644 gas/testsuite/gas/macros/test2.s create mode 100644 gas/testsuite/gas/macros/test3.d create mode 100644 gas/testsuite/gas/macros/test3.s create mode 100644 gas/testsuite/gas/mcore/allinsn.d create mode 100644 gas/testsuite/gas/mcore/allinsn.exp create mode 100644 gas/testsuite/gas/mcore/allinsn.s create mode 100644 gas/testsuite/gas/mips/abs.d create mode 100644 gas/testsuite/gas/mips/abs.s create mode 100644 gas/testsuite/gas/mips/add.d create mode 100644 gas/testsuite/gas/mips/add.s create mode 100644 gas/testsuite/gas/mips/and.d create mode 100644 gas/testsuite/gas/mips/and.s create mode 100644 gas/testsuite/gas/mips/beq.d create mode 100644 gas/testsuite/gas/mips/beq.s create mode 100644 gas/testsuite/gas/mips/bge.d create mode 100644 gas/testsuite/gas/mips/bge.s create mode 100644 gas/testsuite/gas/mips/bgeu.d create mode 100644 gas/testsuite/gas/mips/bgeu.s create mode 100644 gas/testsuite/gas/mips/blt.d create mode 100644 gas/testsuite/gas/mips/blt.s create mode 100644 gas/testsuite/gas/mips/bltu.d create mode 100644 gas/testsuite/gas/mips/bltu.s create mode 100644 gas/testsuite/gas/mips/break20.d create mode 100644 gas/testsuite/gas/mips/break20.s create mode 100644 gas/testsuite/gas/mips/delay.d create mode 100644 gas/testsuite/gas/mips/delay.s create mode 100644 gas/testsuite/gas/mips/div-ilocks.d create mode 100644 gas/testsuite/gas/mips/div.d create mode 100644 gas/testsuite/gas/mips/div.s create mode 100644 gas/testsuite/gas/mips/dli.d create mode 100644 gas/testsuite/gas/mips/dli.s create mode 100644 gas/testsuite/gas/mips/elf_e_flags.c create mode 100644 gas/testsuite/gas/mips/elf_e_flags.s create mode 100644 gas/testsuite/gas/mips/elf_e_flags1.d create mode 100644 gas/testsuite/gas/mips/elf_e_flags2.d create mode 100644 gas/testsuite/gas/mips/elf_e_flags3.d create mode 100644 gas/testsuite/gas/mips/elf_e_flags4.d create mode 100644 gas/testsuite/gas/mips/itbl create mode 100644 gas/testsuite/gas/mips/itbl.s create mode 100644 gas/testsuite/gas/mips/jal-empic.d create mode 100644 gas/testsuite/gas/mips/jal-svr4pic.d create mode 100644 gas/testsuite/gas/mips/jal-svr4pic.s create mode 100644 gas/testsuite/gas/mips/jal-xgot.d create mode 100644 gas/testsuite/gas/mips/jal.d create mode 100644 gas/testsuite/gas/mips/jal.s create mode 100644 gas/testsuite/gas/mips/la-empic.d create mode 100644 gas/testsuite/gas/mips/la-empic.s create mode 100644 gas/testsuite/gas/mips/la-svr4pic.d create mode 100644 gas/testsuite/gas/mips/la-xgot.d create mode 100644 gas/testsuite/gas/mips/la.d create mode 100644 gas/testsuite/gas/mips/la.s create mode 100644 gas/testsuite/gas/mips/lb-empic.d create mode 100644 gas/testsuite/gas/mips/lb-pic.s create mode 100644 gas/testsuite/gas/mips/lb-svr4pic.d create mode 100644 gas/testsuite/gas/mips/lb-xgot-ilocks.d create mode 100644 gas/testsuite/gas/mips/lb-xgot.d create mode 100644 gas/testsuite/gas/mips/lb.d create mode 100644 gas/testsuite/gas/mips/lb.s create mode 100644 gas/testsuite/gas/mips/ld-empic.d create mode 100644 gas/testsuite/gas/mips/ld-ilocks-addr32.d create mode 100644 gas/testsuite/gas/mips/ld-ilocks.d create mode 100644 gas/testsuite/gas/mips/ld-pic.s create mode 100644 gas/testsuite/gas/mips/ld-svr4pic.d create mode 100644 gas/testsuite/gas/mips/ld-xgot.d create mode 100644 gas/testsuite/gas/mips/ld.d create mode 100644 gas/testsuite/gas/mips/ld.s create mode 100644 gas/testsuite/gas/mips/li.d create mode 100644 gas/testsuite/gas/mips/li.s create mode 100644 gas/testsuite/gas/mips/lif-empic.d create mode 100644 gas/testsuite/gas/mips/lif-svr4pic.d create mode 100644 gas/testsuite/gas/mips/lif-xgot.d create mode 100644 gas/testsuite/gas/mips/lifloat.d create mode 100644 gas/testsuite/gas/mips/lifloat.s create mode 100644 gas/testsuite/gas/mips/lineno.d create mode 100644 gas/testsuite/gas/mips/lineno.s create mode 100644 gas/testsuite/gas/mips/mips.exp create mode 100644 gas/testsuite/gas/mips/mips16.d create mode 100644 gas/testsuite/gas/mips/mips16.s create mode 100644 gas/testsuite/gas/mips/mips4.d create mode 100644 gas/testsuite/gas/mips/mips4.s create mode 100644 gas/testsuite/gas/mips/mips4010.d create mode 100644 gas/testsuite/gas/mips/mips4010.s create mode 100644 gas/testsuite/gas/mips/mips4100.d create mode 100644 gas/testsuite/gas/mips/mips4100.s create mode 100644 gas/testsuite/gas/mips/mips4650.d create mode 100644 gas/testsuite/gas/mips/mips4650.s create mode 100644 gas/testsuite/gas/mips/mul-ilocks.d create mode 100644 gas/testsuite/gas/mips/mul.d create mode 100644 gas/testsuite/gas/mips/mul.s create mode 100644 gas/testsuite/gas/mips/nodelay.d create mode 100644 gas/testsuite/gas/mips/rol.d create mode 100644 gas/testsuite/gas/mips/rol.s create mode 100644 gas/testsuite/gas/mips/sb.d create mode 100644 gas/testsuite/gas/mips/sb.s create mode 100644 gas/testsuite/gas/mips/sync.d create mode 100644 gas/testsuite/gas/mips/sync.s create mode 100644 gas/testsuite/gas/mips/trap20.d create mode 100644 gas/testsuite/gas/mips/trap20.s create mode 100644 gas/testsuite/gas/mips/trunc.d create mode 100644 gas/testsuite/gas/mips/trunc.s create mode 100644 gas/testsuite/gas/mips/uld.d create mode 100644 gas/testsuite/gas/mips/uld.s create mode 100644 gas/testsuite/gas/mips/ulh-empic.d create mode 100644 gas/testsuite/gas/mips/ulh-pic.s create mode 100644 gas/testsuite/gas/mips/ulh-svr4pic.d create mode 100644 gas/testsuite/gas/mips/ulh-xgot.d create mode 100644 gas/testsuite/gas/mips/ulh.d create mode 100644 gas/testsuite/gas/mips/ulh.s create mode 100644 gas/testsuite/gas/mips/ulw.d create mode 100644 gas/testsuite/gas/mips/ulw.s create mode 100644 gas/testsuite/gas/mips/usd.d create mode 100644 gas/testsuite/gas/mips/usd.s create mode 100644 gas/testsuite/gas/mips/ush.d create mode 100644 gas/testsuite/gas/mips/ush.s create mode 100644 gas/testsuite/gas/mips/usw.d create mode 100644 gas/testsuite/gas/mips/usw.s create mode 100644 gas/testsuite/gas/mn10200/add.s create mode 100644 gas/testsuite/gas/mn10200/basic.exp create mode 100644 gas/testsuite/gas/mn10200/bcc.s create mode 100644 gas/testsuite/gas/mn10200/bccx.s create mode 100644 gas/testsuite/gas/mn10200/bit.s create mode 100644 gas/testsuite/gas/mn10200/cmp.s create mode 100644 gas/testsuite/gas/mn10200/ext.s create mode 100644 gas/testsuite/gas/mn10200/logical.s create mode 100644 gas/testsuite/gas/mn10200/mov1.s create mode 100644 gas/testsuite/gas/mn10200/mov2.s create mode 100644 gas/testsuite/gas/mn10200/mov3.s create mode 100644 gas/testsuite/gas/mn10200/mov4.s create mode 100644 gas/testsuite/gas/mn10200/movb.s create mode 100644 gas/testsuite/gas/mn10200/movbu.s create mode 100644 gas/testsuite/gas/mn10200/movx.s create mode 100644 gas/testsuite/gas/mn10200/muldiv.s create mode 100644 gas/testsuite/gas/mn10200/other.s create mode 100644 gas/testsuite/gas/mn10200/shift.s create mode 100644 gas/testsuite/gas/mn10200/sub.s create mode 100644 gas/testsuite/gas/mn10300/add.s create mode 100644 gas/testsuite/gas/mn10300/basic.exp create mode 100644 gas/testsuite/gas/mn10300/bcc.s create mode 100644 gas/testsuite/gas/mn10300/bit.s create mode 100644 gas/testsuite/gas/mn10300/cmp.s create mode 100644 gas/testsuite/gas/mn10300/ext.s create mode 100644 gas/testsuite/gas/mn10300/extend.s create mode 100644 gas/testsuite/gas/mn10300/logical.s create mode 100644 gas/testsuite/gas/mn10300/loop.s create mode 100644 gas/testsuite/gas/mn10300/mov1.s create mode 100644 gas/testsuite/gas/mn10300/mov2.s create mode 100644 gas/testsuite/gas/mn10300/mov3.s create mode 100644 gas/testsuite/gas/mn10300/mov4.s create mode 100644 gas/testsuite/gas/mn10300/movbu.s create mode 100644 gas/testsuite/gas/mn10300/movhu.s create mode 100644 gas/testsuite/gas/mn10300/movm.s create mode 100644 gas/testsuite/gas/mn10300/muldiv.s create mode 100644 gas/testsuite/gas/mn10300/other.s create mode 100644 gas/testsuite/gas/mn10300/shift.s create mode 100644 gas/testsuite/gas/mn10300/sub.s create mode 100644 gas/testsuite/gas/mn10300/udf.s create mode 100644 gas/testsuite/gas/mri/char.d create mode 100644 gas/testsuite/gas/mri/char.s create mode 100644 gas/testsuite/gas/mri/comment.d create mode 100644 gas/testsuite/gas/mri/comment.s create mode 100644 gas/testsuite/gas/mri/common.d create mode 100644 gas/testsuite/gas/mri/common.s create mode 100644 gas/testsuite/gas/mri/constants.d create mode 100644 gas/testsuite/gas/mri/constants.s create mode 100644 gas/testsuite/gas/mri/empty.s create mode 100644 gas/testsuite/gas/mri/equ.d create mode 100644 gas/testsuite/gas/mri/equ.s create mode 100644 gas/testsuite/gas/mri/expr.d create mode 100644 gas/testsuite/gas/mri/expr.s create mode 100644 gas/testsuite/gas/mri/float.d create mode 100644 gas/testsuite/gas/mri/float.s create mode 100644 gas/testsuite/gas/mri/for.d create mode 100644 gas/testsuite/gas/mri/for.s create mode 100644 gas/testsuite/gas/mri/if.d create mode 100644 gas/testsuite/gas/mri/if.s create mode 100644 gas/testsuite/gas/mri/immconst.d create mode 100644 gas/testsuite/gas/mri/label.d create mode 100644 gas/testsuite/gas/mri/label.s create mode 100644 gas/testsuite/gas/mri/moveml.d create mode 100644 gas/testsuite/gas/mri/moveml.s create mode 100644 gas/testsuite/gas/mri/mri.exp create mode 100644 gas/testsuite/gas/mri/repeat.d create mode 100644 gas/testsuite/gas/mri/repeat.s create mode 100644 gas/testsuite/gas/mri/semi.d create mode 100644 gas/testsuite/gas/mri/semi.s create mode 100644 gas/testsuite/gas/mri/while.d create mode 100644 gas/testsuite/gas/mri/while.s create mode 100644 gas/testsuite/gas/ppc/astest.d create mode 100644 gas/testsuite/gas/ppc/astest.s create mode 100644 gas/testsuite/gas/ppc/astest2.d create mode 100644 gas/testsuite/gas/ppc/astest2.s create mode 100644 gas/testsuite/gas/ppc/ppc.exp create mode 100644 gas/testsuite/gas/ppc/simpshft.d create mode 100644 gas/testsuite/gas/ppc/simpshft.s create mode 100644 gas/testsuite/gas/sh/basic.exp create mode 100644 gas/testsuite/gas/sh/fp.s create mode 100644 gas/testsuite/gas/sparc-solaris/addend.exp create mode 100644 gas/testsuite/gas/sparc-solaris/addend.s create mode 100644 gas/testsuite/gas/sparc-solaris/gas.exp create mode 100644 gas/testsuite/gas/sparc-solaris/sol-cc.s create mode 100644 gas/testsuite/gas/sparc-solaris/sol-gcc.s create mode 100644 gas/testsuite/gas/sparc/asi.d create mode 100644 gas/testsuite/gas/sparc/asi.s create mode 100644 gas/testsuite/gas/sparc/membar.d create mode 100644 gas/testsuite/gas/sparc/membar.s create mode 100644 gas/testsuite/gas/sparc/mism-1.s create mode 100644 gas/testsuite/gas/sparc/mismatch.exp create mode 100644 gas/testsuite/gas/sparc/prefetch.d create mode 100644 gas/testsuite/gas/sparc/prefetch.s create mode 100644 gas/testsuite/gas/sparc/rdpr.d create mode 100644 gas/testsuite/gas/sparc/rdpr.s create mode 100644 gas/testsuite/gas/sparc/reloc64.d create mode 100644 gas/testsuite/gas/sparc/reloc64.s create mode 100644 gas/testsuite/gas/sparc/set64.d create mode 100644 gas/testsuite/gas/sparc/set64.s create mode 100644 gas/testsuite/gas/sparc/sparc.exp create mode 100644 gas/testsuite/gas/sparc/splet-2.d create mode 100644 gas/testsuite/gas/sparc/splet-2.s create mode 100644 gas/testsuite/gas/sparc/splet.d create mode 100644 gas/testsuite/gas/sparc/splet.s create mode 100644 gas/testsuite/gas/sparc/synth.d create mode 100644 gas/testsuite/gas/sparc/synth.s create mode 100644 gas/testsuite/gas/sparc/synth64.d create mode 100644 gas/testsuite/gas/sparc/synth64.s create mode 100644 gas/testsuite/gas/sparc/wrpr.d create mode 100644 gas/testsuite/gas/sparc/wrpr.s create mode 100644 gas/testsuite/gas/sun4/addend.d create mode 100644 gas/testsuite/gas/sun4/addend.exp create mode 100644 gas/testsuite/gas/sun4/addend.s create mode 100644 gas/testsuite/gas/template create mode 100644 gas/testsuite/gas/tic80/add.d create mode 100644 gas/testsuite/gas/tic80/add.lst create mode 100644 gas/testsuite/gas/tic80/add.s create mode 100644 gas/testsuite/gas/tic80/align.d create mode 100644 gas/testsuite/gas/tic80/align.lst create mode 100644 gas/testsuite/gas/tic80/align.s create mode 100644 gas/testsuite/gas/tic80/bitnum.d create mode 100644 gas/testsuite/gas/tic80/bitnum.lst create mode 100644 gas/testsuite/gas/tic80/bitnum.s create mode 100644 gas/testsuite/gas/tic80/ccode.d create mode 100644 gas/testsuite/gas/tic80/ccode.lst create mode 100644 gas/testsuite/gas/tic80/ccode.s create mode 100644 gas/testsuite/gas/tic80/cregops.d create mode 100644 gas/testsuite/gas/tic80/cregops.lst create mode 100644 gas/testsuite/gas/tic80/cregops.s create mode 100644 gas/testsuite/gas/tic80/endmask.d create mode 100644 gas/testsuite/gas/tic80/endmask.lst create mode 100644 gas/testsuite/gas/tic80/endmask.s create mode 100644 gas/testsuite/gas/tic80/float.d create mode 100644 gas/testsuite/gas/tic80/float.lst create mode 100644 gas/testsuite/gas/tic80/float.s create mode 100644 gas/testsuite/gas/tic80/regops.d create mode 100644 gas/testsuite/gas/tic80/regops.lst create mode 100644 gas/testsuite/gas/tic80/regops.s create mode 100644 gas/testsuite/gas/tic80/regops2.d create mode 100644 gas/testsuite/gas/tic80/regops2.lst create mode 100644 gas/testsuite/gas/tic80/regops2.s create mode 100644 gas/testsuite/gas/tic80/regops3.d create mode 100644 gas/testsuite/gas/tic80/regops3.lst create mode 100644 gas/testsuite/gas/tic80/regops3.s create mode 100644 gas/testsuite/gas/tic80/regops4.d create mode 100644 gas/testsuite/gas/tic80/regops4.lst create mode 100644 gas/testsuite/gas/tic80/regops4.s create mode 100644 gas/testsuite/gas/tic80/relocs1.c create mode 100644 gas/testsuite/gas/tic80/relocs1.d create mode 100644 gas/testsuite/gas/tic80/relocs1.lst create mode 100644 gas/testsuite/gas/tic80/relocs1.s create mode 100644 gas/testsuite/gas/tic80/relocs1b.d create mode 100644 gas/testsuite/gas/tic80/relocs2.c create mode 100644 gas/testsuite/gas/tic80/relocs2.d create mode 100644 gas/testsuite/gas/tic80/relocs2.lst create mode 100644 gas/testsuite/gas/tic80/relocs2.s create mode 100644 gas/testsuite/gas/tic80/relocs2b.d create mode 100644 gas/testsuite/gas/tic80/tic80.exp create mode 100644 gas/testsuite/gas/v850/arith.s create mode 100644 gas/testsuite/gas/v850/basic.exp create mode 100644 gas/testsuite/gas/v850/bit.s create mode 100644 gas/testsuite/gas/v850/branch.s create mode 100644 gas/testsuite/gas/v850/compare.s create mode 100644 gas/testsuite/gas/v850/fepsw.s create mode 100644 gas/testsuite/gas/v850/hilo.s create mode 100644 gas/testsuite/gas/v850/hilo2.s create mode 100644 gas/testsuite/gas/v850/jumps.s create mode 100644 gas/testsuite/gas/v850/logical.s create mode 100644 gas/testsuite/gas/v850/mem.s create mode 100644 gas/testsuite/gas/v850/misc.s create mode 100644 gas/testsuite/gas/v850/move.s create mode 100644 gas/testsuite/gas/v850/range.s create mode 100644 gas/testsuite/gas/v850/reloc.s create mode 100644 gas/testsuite/gas/vax/quad.exp create mode 100644 gas/testsuite/gas/vax/quad.s create mode 100644 gas/testsuite/gas/vtable/entry0.d create mode 100644 gas/testsuite/gas/vtable/entry0.s create mode 100644 gas/testsuite/gas/vtable/entry1.d create mode 100644 gas/testsuite/gas/vtable/entry1.s create mode 100644 gas/testsuite/gas/vtable/inherit0.d create mode 100644 gas/testsuite/gas/vtable/inherit0.s create mode 100644 gas/testsuite/gas/vtable/inherit1.l create mode 100644 gas/testsuite/gas/vtable/inherit1.s create mode 100644 gas/testsuite/gas/vtable/vtable.exp create mode 100644 gas/testsuite/gasp/INC1.H create mode 100644 gas/testsuite/gasp/INC2.H create mode 100644 gas/testsuite/gasp/assign.asm create mode 100644 gas/testsuite/gasp/assign.err create mode 100644 gas/testsuite/gasp/assign.out create mode 100644 gas/testsuite/gasp/condass.asm create mode 100644 gas/testsuite/gasp/condass.err create mode 100644 gas/testsuite/gasp/condass.out create mode 100644 gas/testsuite/gasp/crash.asm create mode 100644 gas/testsuite/gasp/crash.err create mode 100644 gas/testsuite/gasp/crash.out create mode 100644 gas/testsuite/gasp/crash1.asm create mode 100644 gas/testsuite/gasp/crash1.err create mode 100644 gas/testsuite/gasp/crash1.out create mode 100644 gas/testsuite/gasp/crash2.asm create mode 100644 gas/testsuite/gasp/crash2.err create mode 100644 gas/testsuite/gasp/crash2.out create mode 100644 gas/testsuite/gasp/data.asm create mode 100644 gas/testsuite/gasp/data.err create mode 100644 gas/testsuite/gasp/data.out create mode 100644 gas/testsuite/gasp/exp.asm create mode 100644 gas/testsuite/gasp/exp.err create mode 100644 gas/testsuite/gasp/exp.out create mode 100644 gas/testsuite/gasp/gasp.exp create mode 100644 gas/testsuite/gasp/include.asm create mode 100644 gas/testsuite/gasp/include.err create mode 100644 gas/testsuite/gasp/include.out create mode 100644 gas/testsuite/gasp/listing.asm create mode 100644 gas/testsuite/gasp/listing.err create mode 100644 gas/testsuite/gasp/listing.out create mode 100644 gas/testsuite/gasp/macro.asm create mode 100644 gas/testsuite/gasp/macro.err create mode 100644 gas/testsuite/gasp/macro.out create mode 100644 gas/testsuite/gasp/mdouble.asm create mode 100644 gas/testsuite/gasp/mdouble.err create mode 100644 gas/testsuite/gasp/mdouble.out create mode 100644 gas/testsuite/gasp/mri/embed.asm create mode 100644 gas/testsuite/gasp/mri/embed.out create mode 100644 gas/testsuite/gasp/mri/exists.asm create mode 100644 gas/testsuite/gasp/mri/exists.out create mode 100644 gas/testsuite/gasp/mri/irp.asm create mode 100644 gas/testsuite/gasp/mri/irp.out create mode 100644 gas/testsuite/gasp/mri/irpc.asm create mode 100644 gas/testsuite/gasp/mri/irpc.out create mode 100644 gas/testsuite/gasp/mri/macro.asm create mode 100644 gas/testsuite/gasp/mri/macro.out create mode 100644 gas/testsuite/gasp/mri/narg.asm create mode 100644 gas/testsuite/gasp/mri/narg.out create mode 100644 gas/testsuite/gasp/mri/rept.asm create mode 100644 gas/testsuite/gasp/mri/rept.out create mode 100644 gas/testsuite/gasp/pl1.asm create mode 100644 gas/testsuite/gasp/pl1.err create mode 100644 gas/testsuite/gasp/pl1.out create mode 100644 gas/testsuite/gasp/pl2.asm create mode 100644 gas/testsuite/gasp/pl2.err create mode 100644 gas/testsuite/gasp/pl2.out create mode 100644 gas/testsuite/gasp/pl3.asm create mode 100644 gas/testsuite/gasp/pl3.err create mode 100644 gas/testsuite/gasp/pl3.out create mode 100644 gas/testsuite/gasp/pl4.asm create mode 100644 gas/testsuite/gasp/pl4.err create mode 100644 gas/testsuite/gasp/pl4.out create mode 100644 gas/testsuite/gasp/pl5.asm create mode 100644 gas/testsuite/gasp/pl5.err create mode 100644 gas/testsuite/gasp/pl5.out create mode 100644 gas/testsuite/gasp/pl6.asm create mode 100644 gas/testsuite/gasp/pl6.err create mode 100644 gas/testsuite/gasp/pl6.out create mode 100644 gas/testsuite/gasp/pl7.asm create mode 100644 gas/testsuite/gasp/pl7.err create mode 100644 gas/testsuite/gasp/pl7.out create mode 100644 gas/testsuite/gasp/pl8.asm create mode 100644 gas/testsuite/gasp/pl8.err create mode 100644 gas/testsuite/gasp/pl8.out create mode 100644 gas/testsuite/gasp/pr7583.asm create mode 100644 gas/testsuite/gasp/pr7583.err create mode 100644 gas/testsuite/gasp/pr7583.out create mode 100644 gas/testsuite/gasp/reg.asm create mode 100644 gas/testsuite/gasp/reg.err create mode 100644 gas/testsuite/gasp/reg.out create mode 100644 gas/testsuite/gasp/rep.asm create mode 100644 gas/testsuite/gasp/rep.err create mode 100644 gas/testsuite/gasp/rep.out create mode 100644 gas/testsuite/gasp/repeat.asm create mode 100644 gas/testsuite/gasp/repeat.err create mode 100644 gas/testsuite/gasp/repeat.out create mode 100644 gas/testsuite/gasp/reperr.asm create mode 100644 gas/testsuite/gasp/reperr.err create mode 100644 gas/testsuite/gasp/reperr.out create mode 100644 gas/testsuite/gasp/reperr1.asm create mode 100644 gas/testsuite/gasp/reperr1.err create mode 100644 gas/testsuite/gasp/reperr1.out create mode 100644 gas/testsuite/gasp/reperr2.asm create mode 100644 gas/testsuite/gasp/reperr2.err create mode 100644 gas/testsuite/gasp/reperr2.out create mode 100644 gas/testsuite/gasp/reperr3.asm create mode 100644 gas/testsuite/gasp/reperr3.err create mode 100644 gas/testsuite/gasp/reperr3.out create mode 100644 gas/testsuite/gasp/sdata.asm create mode 100644 gas/testsuite/gasp/sdata.err create mode 100644 gas/testsuite/gasp/sdata.out create mode 100644 gas/testsuite/gasp/sfunc.asm create mode 100644 gas/testsuite/gasp/sfunc.err create mode 100644 gas/testsuite/gasp/sfunc.out create mode 100644 gas/testsuite/gasp/t1.asm create mode 100644 gas/testsuite/gasp/t1.err create mode 100644 gas/testsuite/gasp/t1.out create mode 100644 gas/testsuite/gasp/t2.asm create mode 100644 gas/testsuite/gasp/t2.err create mode 100644 gas/testsuite/gasp/t2.out create mode 100644 gas/testsuite/gasp/t3.asm create mode 100644 gas/testsuite/gasp/t3.err create mode 100644 gas/testsuite/gasp/t3.out create mode 100644 gas/testsuite/gasp/while.asm create mode 100644 gas/testsuite/gasp/while.err create mode 100644 gas/testsuite/gasp/while.out create mode 100755 gas/testsuite/lib/doboth create mode 100755 gas/testsuite/lib/doobjcmp create mode 100755 gas/testsuite/lib/dostriptest create mode 100755 gas/testsuite/lib/dotest create mode 100755 gas/testsuite/lib/dounsreloc create mode 100755 gas/testsuite/lib/dounssym create mode 100644 gas/testsuite/lib/gas-defs.exp create mode 100644 gas/testsuite/lib/gas-dg.exp create mode 100755 gas/testsuite/lib/run create mode 100644 gas/vmsconf.sh create mode 100644 gas/write.c create mode 100644 gas/write.h (limited to 'gas') diff --git a/gas/CONTRIBUTORS b/gas/CONTRIBUTORS new file mode 100644 index 0000000000..b3fd03eb1b --- /dev/null +++ b/gas/CONTRIBUTORS @@ -0,0 +1,111 @@ +(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, +raeburn@cygnus.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 currently maintains gas, and 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/gas/COPYING b/gas/COPYING new file mode 100644 index 0000000000..60549be514 --- /dev/null +++ b/gas/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 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. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program 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. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public 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. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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 of the License, 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/gas/ChangeLog b/gas/ChangeLog new file mode 100644 index 0000000000..852b6c7787 --- /dev/null +++ b/gas/ChangeLog @@ -0,0 +1,3170 @@ +1999-04-30 Nick Clifton + + * config/tc-mcore.c (mcore_s_section): Dump literals before + changing section. + +1999-04-29 Nick Clifton + + * 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 + + * 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 + + * aclocal.m4, configure: Updated for new version of libtool. + +1999-04-22 Nick Clifton + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/obj-coff.c (c_section_symbol): Fix typo in previous + change. + +1999-04-16 Nick Clifton + + * config/tc-mcore.h (LOCAL_LABELS_FB): Define to 1. + +Thu Apr 15 16:52:09 1999 Jeffrey A Law (law@cygnus.com) + + * tc-hppa.c (pa_get_absolute_exression): Try to handle "5 %r3" + expressions correctly. + + +1999-04-15 Gavin Romig-Koch + + * 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) + + * tc-hppa.c (pa_ip, case '3'): New case for PA2.0 fmpyfadd + and fmpynfadd instructions. + +1999-04-11 Richard Henderson + + * 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 : + + * 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 + + * tc-alpha.c (load_expression): Call as_bad instead of abort. + +1999-04-08 Nick Clifton + + * 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 + + * 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 + + * 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 + + * configure.in: Add mips*-*-vxworks* target; have it define + MIPS_STABS_ELF. + * configure, config.in: Rebuild. + +1999-03-31 Nick Clifton + + * 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 + + * tc-mips.c (md_apply_fix): Adjust value for linkonce sections. + +Wed Mar 24 14:11:10 1999 Jeffrey A Law (law@cygnus.com) + + * 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) + + * 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 + + * doc/internals.texi (CPU backend): Mention that + line_separator_chars should not include newline. From thi + . + +1999-03-22 Doug Evans + + * 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 + + * tc-alpha.c (md_assemble): Allow '6' in an opcode. + +Thu Mar 18 10:55:30 1999 Jeffrey A Law (law@cygnus.com) + + * 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) + + * tc-hppa.c (pa_ip, case 'd'): Do not allow ",n". + +1999-03-15 Martin Hunt + + * 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 + + * config/tc-d30v.c (md_apply_fix3): Handle BFD_RELOC_8, + BFD_RELOC_16 and BFD_RELOC_64. + +1999-03-12 Andreas Schwab + + * expr.c (expr): Add missing else. + +1999-03-12 Nick Clifton + + * config/tc-arm.c (md_apply_fix3): Improve error message. + +1999-03-11 Doug Evans + + * 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 + + * config/tc-mips.c (md_show_usage): Fix message. + +1999-03-03 Nick Clifton + + * doc/c-arm.texi (ARM Syntax): Document new command line switches + and LDR reg,= 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 + + * doc/c-arm.texi (ARM-Chars): Fix typo in use of '@'. + +1999-02-17 Nick Clifton + + This patch was created by: Scott Bambrough + + + * 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 + + * 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 + + * config/tc-mips.c (mips_ip: case 'o'): Fix assertion failure for + non-constant offset from a base register. + +1999-02-14 Ken Raeburn + + * config/tc-alpha.c (md_show_usage): Put \ before newline in + strings always. + +Sat Feb 13 14:10:10 1999 Richard Henderson + + * 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 + + * 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 + + * 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 + + * 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 + + * Makefile.am (EXTRA_as_new_SOURCES): Uncomment--fixed by automake + patch. + * Makefile.in: Rebuild. + +1999-02-09 Doug Evans + + * Makefile.am (DISTCLEANFILES): Change cgen-opc.h to cgen-desc.h. + (cgen.o): Ditto. + (EXTRA_as_new_SOURCES): Comment out. + (.tcdep): -opc.h renamed to -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): -opc.h renamed to -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 + + * config/tc-arm.c (md_apply_fix3): Fix handling of label1 - label2 + relocations for ELF targets. + +1999-02-08 Nick Clifton + + * configure.in: Add support for StrongARM target. + * configure: Regenerate. + +1999-02-05 Nick Clifton + + * 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 + + * config/tc-alpha.c (md_show_usage): Document pca56 and ev6 options. + +Mon Feb 1 20:37:30 1999 Catherine Moore + + * 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 + + * 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 + + * 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 + + * 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 + + * Makefile.in: Regenerate. + * configure.in: Redo test for using cgen. + * configure: Regenerate. + +1999-01-09 Nick Clifton + + * config/obj-coff.h (obj_adjust_symtab): Prevent accidental + redefinition of this macro. + +Tue Jan 5 21:58:03 1999 Doug Evans + + * config/tc-mips.c (mips_frob_file): Disable "Unmatched %hi reloc" + warning. + +1998-12-29 Gavin Romig-Koch + + * 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 + + * config/tc-mips.c (md_begin): Another correction to the setting of + mips_eabi64. + +1998-12-23 Gavin Romig-Koch + + * config/tc-mips.c (md_begin): Correct type-o in setting of mips_eabi64. + +1998-12-21 Nick Clifton + + * 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 + + * config/tc-mips.c (mips_eabi64): New. + (md_begin): Set mips_eabi64. + (mips_elf_final_processing): Use it. + +1998-12-18 Gavin Romig-Koch + + * config/tc-mips.c (mips_elf_final_processing): + Correct setting of ABI in e_flags. + +Wed Dec 16 16:17:22 1998 Dave Brolley + + * config/tc-fr30.c (md_assemble): Warn about invalid instructions in delay slots. + +1998-12-16 Gavin Romig-Koch + + * config/tc-mips.c (md_begin,md_parse_option): Handle vr4111. + +1998-12-15 Doug Evans + + * 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 + + * 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 + + * config/tc-mips.c (md_parse_option): Handle vr4111. + +98-12-11 Ken Raeburn + + * 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 + + * config/tc-fr30.c: Add line separator character. + +Tue Dec 8 19:51:50 1998 Mark Klein + + * 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 + + * read.c (output_leb128): Don't mark as inline. + +1998-12-08 Andrew MacLeod + + * 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 + + * config/tc-d30v.c (md_assemble, do_assemble): Improve erroneous + input handling. + +Mon Dec 7 09:48:34 1998 Catherine Moore + + * 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 + + * 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 + : + * 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 + . + * 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 + + * config/tc-fr30.c (md_cgen_lookup_reloc): Generate + BFD_RELOC_FR30_48 instead of BFD_RELOC_FR30_32. + +1998-12-02 Nick Clifton + + * config/tc-fr30.c (md_cgen_lookup_reloc): Enable relocs for + LDI:20 insn. + +Thu Nov 26 11:23:48 1998 Dave Brolley + + * config/tc-fr30.c (md_pcrel_from_section): Restore previous calculation + of pcrel point. + +Tue Nov 24 17:21:52 1998 Nick Clifton + + * config/tc-fr30.c (md_pcrel_from_section): Fix calculation of + pcrel point. + +Tue Nov 24 14:54:38 1998 Nick Clifton + + * 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 + + * config/tc-fr30.c (md_cgen_lookup_reloc): Add support for + FR30_OPERAND_I32. + +Thu Nov 19 15:01:29 1998 Nick Clifton + + * config/tc-arm.c (md_parse_option): Add support for -marm7xxx and + -marm6xxx command line switches. + +1998-11-18 Doug Evans + + * 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 + + * 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 + + * po/gas.pot: Regenerated. + +Thu Nov 12 10:54:16 1998 Nick Clifton + + * 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 + + * config/tc-fr30.c: Removed currently superflous code. + +Tue Nov 10 13:13:05 1998 Nick Clifton + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-m32r.c (assemble_two_insns): Ensure both insns + are 16 bit insns. + +Mon Nov 2 20:10:18 1998 Martin von Loewis + + * 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 + + * configure.in: detect cygwin* instead of cygwin32* + * configure: regenerate + +Tue Oct 27 13:18:40 1998 Nick Clifton + + * listing.c: Add support for producing a listing from piped + input. + +Tue Oct 27 08:56:44 1998 Gavin Romig-Koch + + * config/tc-mips.c (hilo_interlocks): Remove mips_3900. + (append_insn): Account for the tx39's multiply behavior. + +1998-10-26 Michael Meissner + + * 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 + + * config/tc-sh.c (sh_fix_adjustable): Adjust EXTERN and + WEAK handling. + +Thu Oct 22 12:41:33 1998 Catherine Moore + + * cgen.c (gas_cgen_md_apply_fix3): Revert last change. + +Thu Oct 22 10:03:15 1998 Ron Unrau + + * config/tc-mips.c : support frame and regmask/fregmask when + MIPS_STABS_ELF is specified. + +Wed Oct 21 11;34:51 1998 Catherine Moore + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * doc/c-arm.texi (ARM Directives): Document .ltorn directive. + +Mon Oct 12 11:07:21 1998 Nick Clifton + + * 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 + + * 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 + + * 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 + + * tc-sparc.h (TC_FORCE_RELOCATION): Define. + (elf32_sparc_force_relocation): Declare. + * 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 + + * 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) + + * 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 + + * 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 + * doc/c-i386.texi (i386-SIMD): New section. + +Thu Oct 1 15:37:54 1998 Richard Henderson + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/obj-elf.h (ECOFF_DEBUGGING): Add missing parens. + +Tue Sep 22 15:44:21 1998 Nick Clifton + + * 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 + + * config/tc-m32r.c (m32r_do_align): After inserting NOPs, reset + the previous insn to empty. + +1998-09-20 Michael Meissner + + * 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 + + * 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 + + * 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 + + * config/tc-i386.c (i386_operand): Fix typo in last patch. + +Tue Sep 8 18:10:01 1998 Catherine Moore + + * 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 + + * config/tc-i386.c (i386_operand): Detect non-segment registers + used as segment prefixes. + +Sat Sep 5 19:00:38 1998 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-arm.c (md_show_usage): Improve formatting of --help output. + +Fri Aug 21 18:43:48 1998 Nick Clifton + + * 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 + + * read.h (generate_lineno_debug): Add prototype. + * read.c (generate_lineno_debug): Make non-static. + +Thu Aug 20 23:17:04 1998 Alan Modra + + * config/tc-i386.c (md_assemble): Only warn for address/data size + prefixes. + +Thu Aug 20 14:45:08 1998 Nick Clifton + + * 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 + + * 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 + + * 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 + + * tc-arm.h: Define obj_fix_adjustable for OBJ_ELF. + * tc-arm.c (arm_fix_adjustable): New routine. + +1998-08-13 Vladimir N. Makarov + + * 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 + + * 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 + + * config/tc-hppa.c (pa_enter): Call as_bad rather than abort. + (pa_leave): Likewise. + +Wed Aug 12 13:25:03 1998 Alan Modra + + * 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 + + * 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 + + * 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 + + * 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 + + 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 + + * 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 + + * config/tc-alpha.c (alpha_fix_adjustable): Don't adjust weak syms. + +Wed Aug 5 15:54:14 1998 Nick Clifton + + * 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 + + * 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 + + * 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 + + 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * Makefile.am (install-exec-local): Don't remove the file before + checking whether $(bindir) == $(tooldir)/bin. From Maciej + W. Rozycki . + * Makefile.in: Rebuild. + +Fri Jul 24 09:13:46 1998 Doug Evans + + * 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 + + * 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 + + * 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 + + * config/tc-m32r.c (ms_show_usage): Formatting changes. + +Wed Jul 15 15:38:28 1998 Ian Lance Taylor + + * 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 + + * configure.in (i386-*-beos{pe,elf,}*): Recognize. + +Tue Jul 14 12:33:44 1998 Chris Torek + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + Based on patch from Matt Semersky : + * 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 + + * 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 + + * 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. + + * 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 + + * 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 + + * 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 + + * config/tc-sh (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 + + * 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 + + * config/tc-v850.c (v850_comm): Restore old section + after common processing. + +Wed Jun 24 11:50:54 1998 Klaus Kaempf + + * config/obj-vms.c (Create_VMS_Object_File): Force binary file. + +Tue Jun 23 17:47:31 1998 Jim Wilson + + * 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 + + * 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 + + * 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 + + * config/obj-coff.c (c_symbol_merge): Fix copying of auxiliary + information. + +Mon Jun 22 15:18:58 1998 Ian Lance Taylor + + * 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 + + * config/tc-sh.c (md_apply_fix): Handle weak symbols correctly if + BFD_ASSEMBLER. + +Sun Jun 21 12:26:36 1998 Nick Clifton + + * 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 + + * 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 + + * config/tc-mips.c (md_show_usage): Fix -mipsN usage. + +Tue Jun 16 13:06:21 1998 Alan Modra + + * 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 + + * po/Make-in (all-yes): If maintainer mode, depend on .pot file. + ($(PACKAGE).pot): Unconditionally depend on POTFILES. + +1998-06-12 Vladimir N. Makarov + + * config/tc-d10v.c (md_apply_fix3): Checking displacement + constraint in instructions REP & REPI. + +Thu Jun 11 08:56:46 1998 Nick Clifton + + * 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 + + * config/tc-v850.c (v850_comm): Create special sections as needed. + +1998-06-10 Vladimir N. Makarov + + * 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 + + * Makefile.am: Rebuild dependencies. + (DEP_INCLUDES): Fix reference to intl build directory. + * Makefile.in: Rebuild. + +Tue Jun 9 12:20:05 1998 Alan Modra + + * 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 + + * 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 + + * 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 + : + * 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 : + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-d30v.c (md_assemble): Store previous segment state + with previous instruction. + +Wed Jun 3 18:21:56 1998 Alan Modra + + * 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 + + * 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 + + * 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 + + * config/tc-m68k.c (relaxable_symbol): If TARGET_OS is "elf", all + symbols are relaxable. + +Wed Jun 3 09:16:00 1998 Catherine Moore + + * 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 + + From Matt Semersky : + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + From Andrew Crabtree : + * 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 + + 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 + + * 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 + + * 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 + + * symbols.c (symbol_find_base): Fix case insensitive symbol name + code. From Chris Moller . + + Based on patch from Klaus Kaempf : + * 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 + + * 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 + + * 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 + + * config/tc-arm.c (find_real_start): Relax definition of local + labels. + +Tue May 19 16:59:44 1998 Nick Clifton + + * 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 + + * 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 + + * config/tc-v850.c (md_assemble): Remove artificially created + register name symbols. + +Mon May 18 13:47:06 1998 Doug Evans + + * write.c (fixup_segment): Change "segment" to "section" in + error message. + +Mon May 18 16:55:40 1998 Michael Meissner + + * write.c (fixup_segment): Change sym1-sym2 message again. + +Mon May 18 09:31:43 1998 Michael Meissner + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * cgen.c (cgen_asm_finish_insn): Fix typo. + +Thu May 7 02:19:14 1998 Doug Evans + + * 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 + + * 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 + + * doc/c-vax.texi: Correct and extend vax/vms documentation. + +Wed May 6 11:51:51 1998 Richard Henderson + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * read.c (sizeof_leb128): Referenced externally by write.c so + don't inline. + +Wed Apr 29 15:45:57 1998 Michael Meissner + + * 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 + + * as.c (main): Conditionally call setlocale. + * gasp.c (main): Likewise. + * asintl.h: Include if HAVE_LOCALE_H. + (LC_MESSAGES): Now can be defined even when ENABLE_NLS. + +Tue Apr 28 18:33:23 1998 Frank Ch. Eigler + + * config/tc-d30v.c (md_show_usage): Correct gettext typo. + +Tue Apr 28 12:16:30 1998 Ian Lance Taylor + + * 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 + + * 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 + + * configure.in: Change version number to 2.9.4 + * configure: Rebuild. + +Mon Apr 27 12:07:33 1998 Doug Evans + + * cgen.c (cgen_asm_finish_insn): New arg relax_p. All callers updated. + +Mon Apr 27 15:16:12 1998 Ian Lance Taylor + + * ecoff.h: Change symbolS in function declaration to struct + symbol. + +Sun Apr 26 13:44:22 1998 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * po/Make-in (MKINSTALLDIRS): Don't look in $(top_srcdir). + +Wed Apr 22 14:52:36 1998 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-mips.c (hilo_interlocks): Remove 4300. + +Mon Apr 13 16:51:04 1998 Nick Clifton + + * config/tc-arm.c (do_msr): Support undocumented 'msr cpsr_flg, + #' instruction. + +Thu Apr 9 10:29:42 1998 Doug Evans + + * 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 + + * symbols.c (print_binary): New function. + (print_expr_1): Call it. + +Mon Apr 6 12:06:39 1998 Andreas Schwab + + * 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 + + * 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 + + * doc/as.texinfo (Invoking): Clarify -Wa example. + +Fri Apr 3 09:12:23 1998 Gavin Koch + + * 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 + + * gasp.c (main): Set next field of new include_path structure to + NULL. From Avery Pennarun . + + * 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 + + * 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 + + * config/tc-arm.c (decode_shift): Handle addressing mode 2 w/rrx + also. + +Wed Apr 1 13:13:20 1998 Andreas Schwab + + * 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 + + * 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 + + * 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 + + * 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 + + * stabs.c (get_stab_string_offset): Always create a stab string + section. + +Sat Mar 28 22:28:02 1998 Ian Lance Taylor + + 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 + + * 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 + + * config/tc-v850.c (md_assemble): Store relocation addend in + fixup instead of instruction. + +Thu Mar 26 23:07:18 1998 Alan Modra + + * 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 + + * 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 + + * 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 + + Based on patch from H.J. Lu : + * Makefile.am (DISTSTUFF): New variable. + (diststuff): New target. + * Makefile.in: Rebuild. + +Tue Mar 24 16:51:29 1998 Nick Clifton + + * 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 + + * 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 + + * 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 + + * configure.in: (sh*-*-rtems*): Switched from ELF to COFF. + * configure: Rebuild. + +Fri Mar 20 19:15:44 1998 Ian Lance Taylor + + * aclocal.m4, configure: Rebuild with libtool 1.2. + +Thu Mar 19 16:03:12 1998 Nick Clifton + + * 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 + + * configure.in (emulations): Add thumb-pe target. + + * configure (emulations): Add thumb-pe target. + +1998-03-17 Ken Raeburn + + * itbl-lex.l (yywrap): Don't define if already defined as a + macro. + +Fri Mar 13 16:31:38 1998 Tom Tromey + + * depend.c (quote_string_for_make): New function. + (wrap_output): Use it. + +Thu Mar 12 18:28:22 1998 Nick Clifton + + * 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 + + * 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 + + * config/obj-elf.c [TC_ALPHA]: Include . + * config/tc-alpha.h (ELF_TC_SPECIAL_SECTIONS): New. + +Thu Feb 26 15:49:04 1998 Michael Meissner + + * 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 + + * 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 + + * 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 + + * config/tc-ppc.c (md_pseudo_table): Add "section". + (ppc_named_section): New static function. + +Thu Feb 19 22:25:42 1998 Richard Henderson + + * 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 + + * 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 + + * 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 + + * Makefile.am (install-exec-local): Install properly when ln + fails or tooldir == prefix. + +Tue Feb 17 18:58:51 1998 Doug Evans + + * 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 + + * 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 + + * 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 + + Based on patches from Ross Harvey : + * 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 : + * 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 + +Fix rac to accept only a0: + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * expr.c: Add support for 0x1_2_3_4 bignums. + +Tue Feb 10 14:43:40 1998 Ian Lance Taylor + + * 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 + + * Makefile.am: Update dependencies. + * Makefile.in: Rebuild. + +Sat Feb 7 15:33:51 1998 Ian Lance Taylor + + * 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 + + * config/tc-v850.c (md_parse_option): Add -mv850any command line option. + +Thu Feb 5 12:39:08 1998 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-sparc.c: Only include elf/sparc.h if OBJ_ELF. + +Mon Feb 2 18:30:34 1998 Steve Haworth + + 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 + + * config/tc-v850.c (md_assemble): Improvements to error messages. + +Mon Feb 2 12:39:05 1998 Geoff Keating + + * 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 + + * read.h (include_dirs): Declare. + (include_dir_count,include_dir_maxlen): Declare. + +Fri Jan 30 11:47:02 1998 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * as.h (flag_warn_suppress_instructionswap): added new flag. + * tc-d10v.c (md_parse_option,md_longopts): added "--nowarnswap" + command line argument. + * 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 + + * configure.in (i386-*-mingw32*): New target. + * configure: Rebuild. + +Wed Jan 28 14:51:18 1998 Ian Lance Taylor + + * 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 + + 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 + + * config/obj-coff.h (RESOLVE_SYMBOL_REDEFINITION): Define. + +Wed Jan 28 09:52:00 1998 Nick Clifton + + * config/tc-v850.c (v850_insert_operand): Display instruction when + an error is encountered. + +Tue Jan 27 13:32:01 1998 Robert Lipe + + * 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 + + * config/tc-v850.c: Tidy error message production. + +Tue Jan 27 12:24:32 1998 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * tc-sh.c (get_specific): Handle SGR & DBR. + +Thu Jan 15 13:46:48 1998 Richard Henderson + + * tc-h8300.c (parse_reg): Take the length of the symbol into + account when attempting to match a register name. + * tc-h8500.c (parse_reg): Likewise. + +Wed Jan 14 17:52:33 1998 Nick Clifton + + * 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 + + 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 + + * config/tc-mips.c (mips_ip): Don't test pinfo flags if INSN_MACRO. + +Mon Jan 12 13:04:57 1998 Doug Evans + + * 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. + * 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 + + * 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 + + * 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/gas/ChangeLog-9295 b/gas/ChangeLog-9295 new file mode 100644 index 0000000000..7ea48e6a9c --- /dev/null +++ b/gas/ChangeLog-9295 @@ -0,0 +1,13110 @@ +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 + + * 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 + + * config/tc-mips.c (load_address): Correctly handle a constant in + SVR4_PIC case. From Richard Kenner . + +Fri Dec 15 14:25:07 1995 J.T. Conklin + + * 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 + + * ecoff.c (ecoff_build_aux): Use new bfd_big_endian macro. + +Fri Dec 15 12:11:48 1995 Raymond Jou + + * mpw-make.sed: If linking, edit ALL_CFLAGS to CFLAGS. + +Thu Dec 14 15:09:52 1995 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * config/obj-multi.h: If OBJ_MAYBE_ELF, define OBJ_SYMFIELD_TYPE. + +Tue Dec 5 13:26:34 1995 Ken Raeburn + + * read.c (s_fill): If md_flush_pending_output is defined, call + it. + +Mon Dec 4 15:10:53 1995 Ken Raeburn + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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. + * symbol.c (symbol_print_statistics): New function. + * symbol.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 + + * configure: Rebuild with autoconf 2.7. + +Tue Nov 21 18:39:01 1995 Ian Lance Taylor + + * aclocal.m4 (AC_PROG_CC): Remove local definition. + * configure: Rebuild with autoconf 2.6. + +Mon Nov 20 17:26:00 1995 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + 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 + + * 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 + + * config/tc-i386.h (md_do_align): cast fill and 0x90 to char + before comparing + + Mon May 1 10:91:49 1995 Alan Modra + + * 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 + + * 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 + + * config/tc-m68k.c (s_mri_until): Call pop_mri_control. + +Mon Nov 13 20:39:06 1995 Stan Shebs + + * 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 + + * 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 + + * 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 + . + * 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 + + * configure.in (a29k-nyu-sym1): New target, just like other a29k + targets. + +Wed Nov 8 11:38:48 1995 Ian Lance Taylor + + * config/obj-coff.c (c_dot_file_symbol): Cast xmalloc return. + +Tue Nov 7 09:14:35 1995 Kim Knuttila + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/obj-elf.h: Include bfd/elf-bfd.h rather than + bfd/libelf.h. + +Tue Oct 31 16:34:28 1995 David Mosberger-Tang + + * 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 + + * 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 + + * listing.c (listing_newline): Don't create a frag in the absolute + section. + +Sat Oct 28 01:02:05 1995 Ian Lance Taylor + + * 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 + + * 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) + + * tc-arm.c (do_ldst): Assemble ldr/str r0, [r1] as a pre-increment + instruction. + +Wed Oct 25 11:59:24 1995 Per Bothner + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-mips.c: Correct s_cons arguments. From Michael + Joosten . + +Mon Oct 9 19:59:53 1995 Ian Lance Taylor + + * 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 + + Mon Sep 25 22:49:32 1995 Andreas Schwab + + * 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 + + * sb.c, macro.c: Decide whether to include or + just as as.h does. + +Fri Oct 6 09:55:33 1995 Doug Evans + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + 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 + + * 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 + + * 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 + + * 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 + + * config/tc-arm.h (TARGET_FORMAT): Define for arm-coff. + +Wed Sep 27 12:53:58 1995 Ian Lance Taylor + + * 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 + + * 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 + + * 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 - 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * configure.in (mips-dec-netbsd*): New target. + * configure: Rebuild. + +Sun Sep 17 22:17:43 1995 Ian Lance Taylor + + * configure.in: Set endian to little for mips-*-ultrix*. + * configure: Rebuild. + +Fri Sep 15 13:16:55 1995 Ian Lance Taylor + + * 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 + + Tue Sep 12 17:08:23 1995 Pat Rankin + + * 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 + + * 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 + + * 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 + + * 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 if it exists. + +Fri Sep 8 00:27:46 1995 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * write.c (fixup_segment): Get TC_FORCE_RELOCATION up the + right way! + +Fri Sep 1 08:20:19 1995 James G. Smith + + * 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 + + * 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 + + * 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 + + * config/tc-arm.c (tc_gen_reloc): Delete duplicated code. + +Wed Aug 30 23:51:57 1995 Ian Lance Taylor + + * 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 + + * 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 + + * config/tc-sparc.c (membar_masks): Deleted. + (sparc_ip): Clean up ASI and membar support. + +Tue Aug 29 13:20:27 1995 steve chamberlain + + * 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 + + * 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 + + * 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 + + Sat Aug 19 18:08:16 1995 Pat Rankin + + * 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 + + * 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 + + * 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 + + * config/tc-ppc.c (md_assemble): Allow @HA, @L, and @H suffixes on + constant expressions. + +Sun Aug 20 15:54:37 1995 Jim Wilson + + * config/tc-arm.c (md_reloc_size): Add const to declaration. + +Fri Aug 18 10:58:09 1995 Ian Lance Taylor + + * 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 + + * as.h (alloca): Use void* declaration on HP/UX. + +Wed Aug 16 12:49:17 1995 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * Makefile.in (TE_OBJS): Add empty definition. + +Fri Aug 11 19:16:08 1995 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * tc-sh.c (md_convert_frag): Make some error messages more + explict. + +Mon Jul 31 21:40:47 1995 Ken Raeburn + + Sat Jul 29 18:55:23 1995 Pat Rankin + + * 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 + + * 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 + + * config/tc-ppc.h (SUB_SEGMENT_ALIGN): Define. From Niclas + Andersson . + +Thu Jul 27 20:47:12 1995 Ken Raeburn + + * 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 + + * 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 + + * 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 + + * 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 + + 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + 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 + + * config/obj-coff.c (fixup_segment): Support MD_APPLY_FIX3. + +Wed Jul 12 01:12:12 1995 Ken Raeburn + + * 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 + + * doc/c-mips.texi: Document -m4010 and -mno-4010. + +Tue Jul 11 14:28:55 1995 Jeff Spiegel + + * 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 + + * 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 + + * 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 + + Based on patches from H.J. Lu : + * 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 + + * 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 + + * 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 + + * All files: Updated FSF address. + +Thu Jul 6 16:30:34 1995 Jim Wilson + + * 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 + + Patches from Jerry Blakely : + * 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 + + * 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 + + * 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. + * 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 + + * configure[.in] (i386-*-win32): New host and target. + +Thu Jun 29 17:25:43 1995 Steve Chamberlain + + 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 + + * 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 + + * 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 + + Sun May 7 11:53:41 MDT 1995 Bryan Ford + + * configure.in: Added i386-*-moss* target. + +Thu Jun 22 14:41:23 1995 Michael Meissner + + * 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 + + Changes from Andreas Schwab : + * 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 + + * gasp.c (do_print, do_form, buffer_and_nest): Use case insensitive + string compares. + +Tue Jun 20 14:55:02 1995 Ken Raeburn + + * 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 + + * 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 + + * 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 + + * 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 and ). + * 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 + + * config/tc-arm.h (LOCAL_LABELS_FB): Define. + +Mon Jun 5 02:17:58 1995 Ken Raeburn + + * 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 + + * 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 + + * config/te-dpx2.h: Include obj-format.h. + (COFF_MAGIC): Renamed from FILE_HEADER_MAGIC. + +Wed May 24 13:45:32 1995 Steve Chamberlain + + * 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 + + * 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 + + * 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 + + * 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 + + 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 + + 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 + + * 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 + + * 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 + + * 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 + + * 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 + + 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * Makefile.in (RUNTEST): Use one in srcdir if present. + (RUNTESTFLAGS): Define. + +Wed Apr 26 15:54:10 1995 Ken Raeburn + + Support for more portable alignment handling in assembly code, + based on patches from Bryan Ford : + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * tc-m68k.c (m68k_init_after_args): Test for m68360. + (md_parse_option): Likewise. + (md_show_usage): Mention m68360. + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-mips.c (md_show_usage): Mention -mips4 and -m4650. + +Fri Mar 17 16:47:13 1995 Stan Shebs + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + Delete this patch, it breaks the h8300 assembler. + Tue Jan 10 13:34:14 1995 Ken Raeburn + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * doc/as.texinfo: Add documentation for SPARC V9, from Doug Evans + . + +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 + + * 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 + + * 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 + + * config/tc-i386.h (AOUT_MACHTYPE): Define as 100, not 0. + +Tue Feb 28 18:29:27 1995 Ken Raeburn + + * 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 + + * 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 + + * configure.in: add a29k-*-vxworks configuration. + +Fri Feb 24 14:41:15 1995 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * expr.c (operand): Move md_operand handling to default case + (so it works). + +Wed Feb 15 16:08:47 1995 Jason Molenda + + * config/tc-h8500.c (tc_coff_symbol_emit_hook): Add ignored + parameter, to match prototype. + +Wed Feb 15 15:07:00 1995 Michael Meissner + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 . + + * 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 + + * 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 ; create a + rudimentary one if necessary. + +Tue Feb 7 13:34:46 1995 Michael Meissner + + * 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 + + Changes from Bryan Ford 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 + + * 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 + + * config/tc-ppc.h (NO_STRING_ESCAPES): Don't define if we are + using ELF. + +Thu Jan 26 19:03:42 1995 Ken Raeburn + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * configure: Regenerated. + + * config/tc-mips.c: Include libiberty.h. + +Mon Jan 23 14:07:58 1995 Ian Lance Taylor + + * 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 + + * 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 + + * hash.c (hash_code): Undo last change. + +Thu Jan 19 14:49:47 1995 Ken Raeburn + + * 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 + + * 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 + + * 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. + * tc-h8300.h (tc_reloc_mangle): Declare. + +Tue Jan 17 10:58:06 1995 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * subsegs.h: Include obstack.h. + +Tue Dec 27 18:16:04 1994 Ken Raeburn + + * as.h (struct frag): Enable align* components now. + +Tue Dec 20 14:56:31 1994 Ken Raeburn + + * 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 + + * config/obj-coff.h: Include bfd/libcoff.h, not libcoff.h. + +Mon Dec 19 16:53:36 1994 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + 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 + + * config/tc-mips.c (load_address): Fix RELAX_ENCODE arguments for + NO_PIC case. + +Tue Nov 1 16:10:59 1994 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * Makefile.in (BISON): Use bison -y, not bison. + +Thu Oct 13 19:22:54 1994 Ken Raeburn + + * 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 + + * 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 + + * 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--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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 . + (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 . + (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 . 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 . 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 + (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 ). + +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. + + * 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. + * cofnig/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) + + * 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) + + * 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 ). + (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) + + * 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) + + * 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. + * 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 + hexidecimal 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 . + (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. + * 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 *. + + * 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.ch, 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, tc-h8500.c, tc-h8500.h, 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. + * obj-vms.c: Patch to fix bug where we were not correctly parsing the + stabs directives. + * 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. + * obj-vms.c (obj_aout_stab): Add code to generate listing file. + * 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. + * 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. + * obj-vms.c (VMS_LSYM_Parse): Correctly handle case of continuation + stabs directives. + * 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. + * 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 + . + * 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, 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. + * tc-i386.h: Define SUB_SEGMENT_ALIGN. + * tc-a29k.h: Define ZERO_BASED_SEGMENTS. + * 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. + + * obj-coff.c (obj_coff_endef): Use as_warn, not fprintf. + + * 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. + + * 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. + * tc-m68k.h (OPTIONAL_REGISTER_PREFIX): Define to be "%", if not + M68KCOFF. + + * obj-coffbfd.c (fill_section): set STYP_NOLOAD bit for .bss + section. + + * atof-ieee.c, atof-ns32k.c, 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) + + * 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) + + * obj-coff.c (callj_table): Delete global variable. + (obj_emit_relocations): Define it locally here, and only if + TC_I960 is defined. + + * 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. + + * obj-coff.c: Replaced ANSI and non-ANSI function declarations + with a single set using PARAMS macro. + + * tc-i960.c (tc_bout_fix_to_chars): Bit-field fixups want a length + of 2. + + * tc-i960.c: Missed a couple of 0->NO_RELOC conversions. + + * 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) + + * 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. + * 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 + + * 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) + + * obj-coffbfd.c (write_object_file): don't fixup for the z8k + * tc-z8k.c: lots of bug fixes + +Tue Sep 29 10:51:55 1992 Ian Lance Taylor (ian@cygnus.com) + + * tc-i960.h, tc-i960.c: avoid the ANSI preprocessor addition + #elif, since it is not supported by old compilers. + ho-rs6000.h, 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. + + * 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) + + * 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) + + * 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) + + * tc-m68k.c: Replace "enum m68k_architecture" with "int" + throughout. That enum no longer means what we thought it meant. + + * tc-m68k.c (md_assemble, md_parse_option): Handle new + "-mno-688[58]1" options. + + * tc-m68k.c: Added CPU32 support. + +Fri Sep 18 08:02:18 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * 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. + + * obj-coffbfd.h: define WARN_SIGNED_OVERFLOW_WORD. + obj-coffbfd.c (fixup_segment): check for signed .word overflow if + WARN_SIGNED_OVERFLOW_WORD. + + * 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 + * obj-coffbfd.h : added stuff + * tc-i386.c (tc_coff_fix2rtype): new function + * 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 + + * 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. + tc-m68kmote.c, tc-m68kmote.h: removed now superfluous files. + From Steve Chamberlain: + m68kcoff.mt: for m68k COFF. + 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. + obj-coffbfd.h: define WORKING_DOT_WORD (too hard to support) and + handle m68k. + 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) + + * obj-bout.h, obj-bout.c (obj_header_append, obj_symbol_to_chars), + 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. + + * tc-m68k.c: use TARGET_CPU to choose default cpu type. + + * 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) + + * 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. + + * obj-bout.c (obj_emit_relocations): Emit alignment relocs despite + their not having symbols associated. + + * 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. + * 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) + + * 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) + + * 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) + + * 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. + + * 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. + + * 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) + + * obj-coffbfd.c: use is a synonym for section, (do_relocs_for): + calc the base of relocs correctly. + * 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) + + * tc-m68k.h, 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. + + * 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 accomodate 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- 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. + + * obj-aout.c: do not include stab.gnu.h if NO_LISTING. + + * 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. + + * 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. + + * 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. + + * tc-m88k.[hc]: pulled in from hack's unfinished work. These + aren't yet integrated. + + * tc-i860.[hc]: blew off the dust. Something must still be done + about conflicting relocation types. + + * tc-ns32k.c: Replaced previous tc_aout_fix_to_chars stub with the + real thing. + + * tc-i960.c, tc-sparc.c: white space and comments only. + + * 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/gas/ChangeLog-9697 b/gas/ChangeLog-9697 new file mode 100644 index 0000000000..dd2af82455 --- /dev/null +++ b/gas/ChangeLog-9697 @@ -0,0 +1,5960 @@ +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 + + * 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 + + * 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 + + * config/tc-d10v.c (build_insn): Make `number' a long for 64-bit hosts. + +Thu Dec 18 16:42:57 1997 Richard Henderson + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-arm.c: Prevent use of interworking support for + non-COFF targets. + +Mon Dec 15 15:20:32 1997 Nick Clifton + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-v850.c: Brought up to date with the branch. + +Mon Dec 1 20:24:18 1997 J"orn Rennecke + + * 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 + + * 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 + + * config/tc-arm.c: Brought up to date with latest changes on arm + branch. + +Sat Nov 22 15:50:09 1997 Klaus Kaempf + + * 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 + + * 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 + + * tc-sh.c (parse_reg): Properly quote for fv4. + +Wed Nov 19 23:46:18 1997 Ian Lance Taylor + + * symbols.c (resolve_symbol_value): Add missing breaks in case on + symbol value operator. + +Tue Nov 18 18:45:14 1997 J"orn Rennecke + + * 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 + + * 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 + + * configure.in (emulations): Make FreeBSD an aout / i386bsd + variant. + * configure: Re-generate. + +Thu Nov 13 11:07:14 1997 Gavin Koch + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * frags.h: Handle multiple inclusion. + +Wed Nov 5 10:51:49 1997 Doug Evans + + 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-d30v.c (build_insn): Allow odd registers for ld2w and + friends. + +Fri Oct 24 15:56:47 1997 Ian Lance Taylor + + * 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 + + * 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 + + * config/tc-sparc.c (v9a_asr_table): New variable. + (sparc_ip): Handle v9a asr's. + Patch from David Miller . + +Wed Oct 22 17:22:59 1997 Richard Henderson + + * config/tc-sparc.h (md_do_align): New macro. + * config/tc-sparc.c (sparc_handle_align): Handle rs_align_code. + Patch from Jakub Jelinek . + +Wed Oct 22 12:51:18 1997 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * read.c (get_line_sb): Accept any eol marker while scanning macros. + +Tue Oct 14 19:12:45 1997 Richard Henderson + + * 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 + + * 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 + + * 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 + + * 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 + + * configure.in (sparc): Set DEFAULT_ARCH from correct target. + * configure: Regenerated. + +Fri Oct 10 11:22:45 1997 Martin M. Hunt + + * 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 + + * config/tc-d10v.c (parallel_ok): Flag SP as modified for @-sp + operand - OPERAND_ATMINUS. + +Fri Oct 10 00:47:44 1997 Michael Meissner + + * 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 + + From Robin Kirkham : + * 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 + + * tc-d10v.h (TC_START_LABEL): Don't define. + (tc_frob_label): Define. + +Thu Oct 9 00:07:23 1997 J"orn Rennecke + + * 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 + + * 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 + + * 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 + + * configure.in: Change alpha-*-* to alpha*-*-*; config.guess now + recognizes alphaev5 etc. + * configure: Rebuild. + +Wed Oct 8 00:04:05 1997 Gavin Koch + + * 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 + + * 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 + + * 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 + + * 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 + . + + * 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 + + * 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 + + * config/tc-m68k.c (m68k_ip): Remove ` operand specifier. + +Wed Sep 24 16:54:40 1997 Joel Sherrill + + * configure.in (sh*-*-rtems*): New target, like sh-*-elf*. + * configure: Rebuild. + +Wed Sep 24 11:30:25 1997 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + 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 + + * config/tc-v850.c (md_assemble): Corrected spelling mistake. + * configure.in (emulations): Add v850 emulation. + +Tue Sep 9 17:14:33 1997 Doug Evans + + * 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 + + * 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 + + 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 + + * 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 + + * as.h: Don't declare alloca if it is a macro. + * macro.c: Likewise. + +Sun Sep 7 00:30:19 1997 Richard Henderson + + * 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 + + * read.h (s_lcomm_bytes): Add prototype (for real this time). + +Thu Sep 4 12:10:01 1997 Ian Lance Taylor + + * config/obj-elf.c (elf_frob_symbol): Only set BSF_OBJECT for + symbols on Irix. + +Wed Sep 3 11:21:33 1997 Nick Clifton + + * 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 + + * 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 + + * 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 + + * 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 + + * doc/c-v850.texi (V850 Opcodes): Correct name for tiny data area + pointer. + +Tue Aug 26 12:23:25 1997 Ian Lance Taylor + + * 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 . + + * 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 + + * 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 + + * 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 + + * 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 + + * doc/c-v850.texi: Change the major node to v850 Machine + Dependencies. + +Fri Aug 22 11:16:14 1997 Nick Clifton + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-v850.c (system_register_name): Support numbers for + system register IDs. + +Tue Aug 19 08:59:12 1997 Fred Fish + + * 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 + + * macro.c (check_macro): use alloca instead of xmalloc to plug leak. + +Mon Aug 18 20:33:06 1997 Richard Henderson + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * doc/internals.texi: Document rs_leb128. + +Tue Aug 12 12:17:03 1997 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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) + + * 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 + + * tc-sparc.c (md_begin): Cast sparc_opcodes to PTR for hash_insert. + +Thu Jul 24 17:51:29 1997 Ian Lance Taylor + + * macro.c (define_macro): Make sure the index is in range before + checking for '('. + +Thu Jul 24 12:13:19 1997 Fred Fish + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-tic80.c (build_insn): Fix endianness problem with + O_big operands. + +Sun Jul 13 20:43:46 1997 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + From Jason Merrill : + * 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 + + * 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 + + * 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 + + * 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 + + * 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 . + + * 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 + + * 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 + + * 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 + + * depend.c (wrap_output): new prototype. + +Mon Jun 9 12:52:44 1997 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-mips.c: Added r3900 support. + +Thu May 29 12:58:26 1997 Ben Pfaff + + * as.c: (parse_args) `-t' option requires an argument. + +Wed May 28 15:45:07 1997 Nick Clifton + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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. + + * 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 + + * 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 + + * 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 + + * config/tc-i386.c (pi): Check for RegMMX. + +Thu May 8 11:10:15 1997 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * config/obj-coff.c (c_section_symbol): Clear the LOCAL bit #ifdef + TE_DELTA. + +Tue Apr 29 20:23:10 1997 Jim Wilson + + * 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 + + * 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 + + * 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 + + * Makefile.in (DISTSTUFF): Add itbl-parse.h. + +Fri Apr 25 12:03:15 1997 Ian Lance Taylor + + * 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 + + * doc/c-mips.texi: Document .set autoextend. + +Sat Apr 19 23:09:25 1997 Niklas Hallqvist + + * 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 + + * 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 + + * config/tc-ppc.c (ppc_fix_adjustable): Handle zero length csects + correctly. + +Fri Apr 18 11:51:35 1997 Niklas Hallqvist + + * configure.in (alpha*-*-openbsd*): New target. + * configure: Rebuild. + +Thu Apr 17 13:59:47 1997 Per Fogelstrom + + * configure.in (mips-*-openbsd*): New target. + * configure: Rebuild. + +Wed Apr 16 12:31:24 1997 Martin Hunt + + * config/tc-d30v.c (parallel_ok): Fix parallel checking + for instructions using conditional execution. + +Tue Apr 15 18:11:44 1997 Gavin Koch + + * config/tc-mips.c (insn_uses_reg): Correct test for fpr pairs. + +Tue Apr 15 13:04:47 1997 Ian Lance Taylor + + * 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 + + * Makefile.in (INSTALL): Change install.sh to install-sh. + + * symbols.c (resolve_symbol_value): Check for division by zero. + + From Thomas Graichen : + * 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 + + * 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 + + * 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 + + * 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 + + * makefile.vms: Update to build gasp.exe. + +Fri Apr 4 16:10:02 1997 Doug Evans + + * 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 + + * 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 + + * Makefile.in (VERSION): Set to 2.8.1. + + * Branched binutils 2.8. + +Wed Apr 2 12:24:10 1997 Ian Lance Taylor + + * 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 + + * config/tc-mips.c (md_begin): Don't set interlocks for 4100. + +Tue Apr 1 16:24:28 1997 Klaus Kaempf + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-ppc.c (register_name): Declare. + +Mon Mar 31 16:31:04 1997 Joel Sherrill + + * configure.in (hppa*-*-rtems*): New target, like hppa-*-*elf*. + * configure: Rebuild. + +Mon Mar 31 14:15:19 1997 Ian Lance Taylor + + * 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 + + * config/tc-m68k.h (TARGET_FORMAT): Set to "coff-m68k-sysv" if + TE_DELTA. + +Fri Mar 28 18:03:19 1997 Alan Modra + + * 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 + + * configure.in (sparc-*-linux*aout*, sparc-*-linux*): New + targets. + * configure: Rebuild. + +Fri Mar 28 13:08:33 1997 Ian Lance Taylor + + * itbl-parse.y (yyerror): Make static. Declare. + + From Ralf Baechle : + * 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 + + * 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 + + * config/tc-d30v.c (md_apply_fix3): Get the relocs right. + +Wed Mar 26 13:35:15 1997 H.J. Lu + + * config/tc-i386.c (tc_i386_fix_adjustable): Only define if + BFD_ASSEMBLER. + +Wed Mar 26 11:32:51 1997 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * Makefile.in: Added automatic dependency building. + * dep-in.sed: New file. + +Fri Mar 21 15:42:37 1997 Ian Lance Taylor + + * 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 + + * doc/as.texinfo (Symbol Names): Don't use obsolete @ctrl macro. + +Thu Mar 20 16:49:14 1997 Andreas Schwab + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + . + + * 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 : + * 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 + + From Eric Youngdale : + * 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 + + * 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 + + * 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 + + * read.c (equals): Add reassign parameter. Change all callers. + * read.h (equals): Update declaration. + +Sat Mar 1 01:04:04 1997 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * configure.in (mips*-*-lnews*): New target, also make empty + emulation list for this target. + * configure: Update. + * tc-mips.c (ECOFF_LITTLE_FORMAT): Define. + (mips_target_format): Use. + * te-lnews.h: New file. + +Wed Feb 26 15:33:46 1997 Fred Fish + + * 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 + + * 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 + + * 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 + + Based on patches from Robert Lipe : + * 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 : + * 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 + + * config/tc-tic80.c (md_apply_fix): Handle R_ABS type fixups. + +Mon Feb 24 18:27:43 1997 Eric Youngdale + + * doc/as.texinfo: Document .symver. + +Mon Feb 24 15:19:57 1997 Martin M. Hunt + + * 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 + + * 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 + + * 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 + + * itbl-ops.h: Include as.h. + +Mon Feb 24 01:04:00 1997 Dawn Perchik + + * 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 + + * itbl-ops.c: Don't define DEBUG. + +Sun Feb 23 17:49:00 1997 Dawn Perchik + + * Makefile.in: Update itbl-test.c to reflect its new location. + +Sun Feb 23 15:50:00 1997 Dawn Perchik + + * 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 + + * 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 + + * 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 + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + Based on patches from Eric Youngdale : + * 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 + + * 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 + + * 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 + + * 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 + + Based on notes from Peter Eriksson . 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 + + * config/tc-mips.c: Changed opcode parsing. + +Thu Feb 13 20:02:16 1997 Fred Fish + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-i386.c (i386_align_code): Add comments explaining the + nop instructions. + +Fri Jan 31 10:46:14 1997 Ian Lance Taylor + + * 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 + + * 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 + + * config/tc-i386.c (i386_align_code): Improve the nop patterns. + +Thu Jan 30 12:08:40 1997 Ian Lance Taylor + + * 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 : + * 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 + + * 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 + + * 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 + + * 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 + + Patch presumed to have been checked in awhile ago but wasn't. + Mon Nov 25 10:45:14 1996 Doug Evans + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * configure.in (tic80-*-*): Don't require 'coff'. + * configure: Regenerate. + +Thu Jan 9 09:08:43 1997 Ian Lance Taylor + + * 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 + + * config/tc-m68k.c (s_even): Adjust the alignment of the current + section. + +Fri Jan 3 17:10:33 1997 Richard Henderson + + * 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 + + * 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 . + + * 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 + + * 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 : + * 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 : + * 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 : + * 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 + + * 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 + + * read.c (read_a_source_file): Check mri_pending_align after + checking for a macro. From Ronald F. Guilmette + . + + * 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 + + * config/tc-mips.c (mips16_macro): Add case for M_ABS. + +Fri Dec 27 22:51:51 1996 Fred Fish + + * 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 + + * doc/as.texinfo (M): Mention explicitly that -M changes macro + handling. + +Thu Dec 19 12:06:08 1996 Ian Lance Taylor + + * 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 + + * mpw-make.sed: Use NewFolderRecursive for installation. + +Wed Dec 18 16:00:42 1996 Martin M. Hunt + + * config/tc-d10v.c (do_assemble): Correct previous bug fix. + +Wed Dec 18 15:27:40 1996 Martin M. Hunt + + * 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 + + * 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 + + * 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 + + * write.c (adjust_reloc_syms): Fix linkonce check for ELF. + +Sat Dec 14 22:37:27 1996 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-d10v.c (md_assemble, d10v_cleanup): Fix bug + with multiple sections. + +Wed Dec 4 13:00:07 1996 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-i386.c: Correct misspelling: balenced to balanced. + +Wed Nov 27 13:25:39 1996 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * read.c (read_a_source_file): New hook md_cleanup(). + +Fri Oct 25 00:01:00 1996 Ian Lance Taylor + + * 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 + + * 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 + + * config/tc-d10v.c (parallel_ok): Don't allow illegal combinations + of instructions. + +Tue Oct 22 11:28:39 1996 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-mips.c (load_register): Add cast to offsetT when using + a constant with &~. + +Mon Oct 14 11:24:28 1996 Richard Henderson + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * obj-evax.h: move openvms definitions from here to tc-alpha.c. + * 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. + * tc-alpha.h (TC_CONS_FIX_NEW): define + +Tue Oct 1 16:16:01 1996 Joel Sherrill + + * configure.in (mips-*-rtems*): New target, like mips-*-elf*. + * configure: Rebuild. + +Tue Oct 1 12:37:48 1996 Ian Lance Taylor + + * 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 . + + * 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) + + * tc-v850.h: Define LOCAL_LABEL to recognise _.L_* symbols + generated by DWARF. + +Sat Sep 28 03:38:08 1996 Ian Lance Taylor + + * 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 + + * expr.c (expr): Change >>= to >> (fix typo). (From meissner). + +Tue Sep 24 19:05:08 1996 Ian Lance Taylor + + * read.c (float_cons): Call md_flush_pending_output if it is + defined. + +Tue Sep 24 12:22:18 1996 Martin M. Hunt + + * 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 + + * 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 + + * 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 + + * 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 + + * expr.c (expr): Always use unsigned right shifts for >>. + +Thu Sep 12 10:25:45 1996 James G. Smith + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 . + +Wed Sep 4 10:23:20 1996 Ian Lance Taylor + + * config/tc-mips.c (load_register): Remove unused variable tmp. + +Wed Sep 4 11:24:29 1996 James G. Smith + + * 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 + + * 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 + + * 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 + + 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-d10v.c (parallel_ok): Fix bug in parallel + checking code. + +Mon Aug 26 14:38:22 1996 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-arm.c: Major changes to add Thumb support, with lots + of change input from . + 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) + + * 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 + + * 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 + + * 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 + + * config/tc-mips.h (BYTE_ORDER): Don't define. No longer used. + +Fri Aug 9 17:48:28 1996 Martin M. Hunt + + * config/tc-d10v.c: Fix problem with relocs. + +Fri Aug 9 14:16:14 1996 Ian Lance Taylor + + * 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 + + 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 + + * configure.in: Make GAS_CHECK_DECL_NEEDED include or + 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 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 + + * 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 . + (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 + + * 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 + + * config/tc-i960.c (mem_fmt): Call parse_expr before emit. + +Fri Aug 2 11:23:31 1996 Ian Lance Taylor + + * 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 + + * config/tc-d10v.c: Disable range checking on 16-bit values. + +Wed Jul 31 16:27:19 1996 Ian Lance Taylor + + * 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 + + * config/tc-d10v.c: Fixed bugs in short relocs and range checking. + +Wed Jul 31 15:41:42 1996 James G. Smith + + * 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 + + * config/tc-sparc.c (md_pseudo_table): Add 2byte, 4byte, and 8byte + pseudo-ops. + +Fri Jul 26 11:43:03 1996 Martin M. Hunt + + * 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 + + * 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 + + * config/tc-d10v.c (md_assemble): Now handles multiline + instructions. + +Thu Jul 25 12:03:33 1996 Martin M. Hunt + + * 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 + + * 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 + + * 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 + + * 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 + + * 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. + * tc-alpha.h (md_flush_pending_output): Remove. + (md_cons_align): Add. + + * 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 + + From Andrew Gierth : + * 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 + + * configure.in (d10v-*-*): Allow d10v-*-*, don't require d10v-*-elf*. + +Wed Jul 17 14:25:13 1996 Martin M. Hunt + + * 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 + + * config/tc-ppc.c (md_parse_option): Recognize -K PIC. + +Wed Jul 10 12:39:08 1996 Richard Henderson + + * 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 + + * 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 + + * 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 + ). + (md_show_usage): Correct -mfc5200 to -m5200. + +Fri Jul 5 10:32:58 1996 J.T. Conklin + + * 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 + + * 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 + + * Makefile.in (VERSION): Set to cygnus-2.7.1. + + * Released binutils 2.7. + +Thu Jul 4 10:11:33 1996 James G. Smith + + * 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 + + * 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 + + * 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 : + * 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 + + * 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 + + * Makefile.in (config.status): Just run config.status as other + tools do. + +Fri Jun 28 11:09:38 1996 Stan Shebs + + * mpw-config.in (TARGET_OS): Add definition to conf. + +Thu Jun 27 20:39:40 1996 James G. Smith + + * config/tc-mips.c (append_insn): Parenthesize + cop_interlocks expressions. + +Thu Jun 27 12:18:26 1996 Ian Lance Taylor + + * 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 . + +Wed Jun 26 13:21:34 1996 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * configure.in: Add support for *-*-rtems* configurations. + * configure: Rebuild. + +Fri Jun 21 16:01:18 1996 Richard Henderson + + * 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 + + * 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 + + * 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 + + * symbols.c (colon): #if VMS, use S_SET_OTHER to store `const_flag'. + + Tue Mar 5 14:31:45 1996 Pat Rankin + + * config/tc-vax.h (NOP_OPCODE): Define. + + Sun Feb 4 21:01:03 1996 Pat Rankin + + * 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 + + * config/vms-conf.h: Reconcile with conf.in. + +Wed Jun 19 11:31:50 1996 Ian Lance Taylor + + * 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 . + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * listing.c (listing_newline): Don't do anything if listing is 0. + +Thu Jun 13 17:50:54 1996 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * symbols.c (colon): Use LOCAL_LABEL. + +Tue Jun 4 10:55:16 1996 Tom Tromey + + * 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 + + * config/ppc-sol.mt (TDEFINES): Don't turn on -mregnames by + default. + +Mon Jun 3 11:34:41 1996 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-ppc.c (ppc_set_cpu): Change defaults to match AIX. + +Thu May 23 17:34:24 1996 Michael Meissner + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * Makefile.in: Add subsegs.h to appropriate TARG_CPU_DEP_* + variables. + +Fri May 3 17:58:31 1996 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * configure.in: Add i386-*-freebsdelf* target; from John Polstra + . + * configure: Rebuild. + +Fri Apr 5 18:39:28 1996 James G. Smith + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * configure.in (sparc-*-solaris2*): Renamed from sparc*-*-solaris2*. + * configure: Regenerated. + +Tue Mar 26 18:19:12 1996 Ian Lance Taylor + + * as.c (main): Call bfd_set_error_program_name. + +Fri Mar 22 11:13:00 1996 Ian Lance Taylor + + * 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 + + * config/tc-i386.c (md_parse_option): If OBJ_ELF, ignore -k for + FreeBSD compatibility. From John Polstra . + +Wed Mar 20 18:13:32 1996 Andreas Schwab + + * doc/as.texinfo, doc/c-i960.texi: Fix typos. + +Wed Mar 20 17:05:16 1996 David Mosberger-Tang + + * config/alpha-opcode.h: Added cvtst instruction. + +Mon Mar 18 13:12:46 1996 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * configure: Rebuild with autoconf 2.8. + +Mon Mar 11 18:57:12 1996 Ian Lance Taylor + + * config/atof-ieee.c (gen_to_words): Improve handling of + X_PRECISION numbers. Based on patches from Andreas Schwab + . + +Mon Mar 11 09:59:53 1996 Steve Chamberlain + + * as.h (SEG_NORMAL, SEG_LIST): Bump segment limit from 10 to 40. + (SEG_LAST): New. + * subsegs.c (MANY_SEGMENTS): Increase segment limit. + * 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 + + * 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 + + * 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 + + * config/tc-sh.c (sh_do_align): Pass 1 not 2 to frag_align. + +Mon Mar 4 20:50:57 1996 Steve Chamberlain + + * 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 + + * 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 + + * 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 + + * 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 + + * mpw-make.sed: Update to handle shared library support. + +Mon Feb 26 10:34:10 1996 Doug Evans + + * config/tc-sparc.c (sparc_ip): Print all architectures that support + the insn on mismatch. + +Fri Feb 23 21:44:39 1996 Rob Savoye + + * configure.in: Add support for a29-coff. + * configure: Rebuild. + +Thu Feb 22 16:39:43 1996 Ian Lance Taylor + + * 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 . + +Wed Feb 21 17:00:32 1996 Ian Lance Taylor + + * 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 + + * config/tc-sparc.c (sparc_ip): Recognize %asr0 for v8. + +Tue Feb 20 21:48:03 1996 Doug Evans + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 : i386 + doesn't need opcodes. If configuring shared, opcodes needs bfd. + * configure: Rebuild. + +Wed Feb 14 16:33:12 1996 Martin Anantharaman + + * 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 + + From Alan Modra : + * 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 + + * 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 + + * configure.in: Set HDLFLAGS for *-*-hpux with --enable-shared. + * configure: Rebuild. + +Mon Feb 12 15:53:46 1996 Doug Evans + + * configure.in: Recognize any sparc* cpu. + * configure: Regenerated. + +Mon Feb 12 15:41:21 1996 Ian Lance Taylor + + * 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 + + 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 + + * 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 + + * 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 + + * config/te-aux.h: Change include of aux.h to aux-coff.h. + +Thu Feb 8 20:02:58 1996 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * 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 : + * 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 + + * 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 + + * Makefile.in (INSTALL_XFORM): Remove -e. + +Fri Feb 2 12:32:15 1996 Ian Lance Taylor + + * 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 + + * 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 + + * configure.in (i386-*-cygwin32, ppc-*-cygwin32): New. + * configure: Rebuild. + +Wed Jan 31 14:03:17 1996 Richard Henderson + + * 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 + + * 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 + + * 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 + + * config/obj-elf.c (obj_elf_type): Set BSF_OBJECT flag for a type + of object. From Ronald F. Guilmette . + + * 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 + + * 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 + + * 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 + + * 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 + + SCO ELF support from Robert Lipe : + * 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 + + * 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 + + * Makefile.in (RUNTEST): Fix reference to $${srcdir}. + +Mon Jan 22 09:21:36 1996 Doug Evans + + * 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 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/tc-ppc.c (mapping): Add more relocation suffixes. + +Sun Jan 14 21:29:36 1996 Michael Meissner + + * 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 + + * config/tc-ppc.c (ppc_section*): Wrap these functions inside + #ifdef OBJ_ELF. + +Fri Jan 12 15:32:07 1996 Michael Meissner + + * 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 + + * 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 . + + * expr.c (operand): Skip whitespace after a close parenthesis. + From James Carlson . + +Tue Jan 2 12:43:23 1996 Jim Wilson + + * 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/gas/Makefile.am b/gas/Makefile.am new file mode 100644 index 0000000000..688f21ccc6 --- /dev/null +++ b/gas/Makefile.am @@ -0,0 +1,1695 @@ +## Process this file with automake to generate Makefile.in + +## Work around apparent automake bug. +INTLLIBS = @INTLLIBS@ + +AUTOMAKE_OPTIONS = cygnus dejagnu + +SUBDIRS = doc po + +tooldir = $(exec_prefix)/$(target_alias) + +YACC = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L../bison/bison ; else echo bison -y ; fi` +LEX = `if [ -f ../flex/flex ] ; then echo ../flex/flex ; else echo flex ; fi` + +DEP = $(srcdir)/../mkdep + +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 \ + d10v \ + d30v \ + fr30 \ + h8300 \ + h8500 \ + hppa \ + i386 \ + i860 \ + i960 \ + m32r \ + m68k \ + m88k \ + mcore \ + mips \ + mn10200 \ + mn10300 \ + ns32k \ + ppc \ + sh \ + sparc \ + tahoe \ + tic30 \ + tic80 \ + vax \ + w65 \ + v850 \ + 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 | i386 | i860 | m68k | mips | ns32k | sparc | tahoe | tic30 | vax) \ + valid=yes ;; \ + esac ;; \ + bout) \ + case $$c in \ + i960) valid=yes ;; \ + esac ;; \ + coff) valid=yes ;; \ + 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; + +# This is like CPU_OBJ_VALID, for the obj=multi case. + +CPU_MULTI_VALID = \ + valid= ; \ + case $$c in \ + i386 | mips) valid=yes ;; \ + esac; + +# Regular source files. + +GAS_CFILES = \ + app.c \ + as.c \ + atof-generic.c \ + bignum-copy.c \ + cond.c \ + depend.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) gasp.c itbl-ops.c + +HFILES = \ + as.h \ + asintl.h \ + bignum.h \ + bit_fix.h \ + cgen.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-d10v.c \ + config/tc-d30v.c \ + config/tc-h8300.c \ + config/tc-h8500.c \ + config/tc-hppa.c \ + config/tc-i386.c \ + config/tc-i860.c \ + config/tc-i960.c \ + config/tc-m32r.c \ + config/tc-m68k.c \ + config/tc-m88k.c \ + config/tc-mcore.c \ + config/tc-mips.c \ + config/tc-mn10200.c \ + config/tc-mn10300.c \ + config/tc-ns32k.c \ + config/tc-ppc.c \ + config/tc-sh.c \ + config/tc-sparc.c \ + config/tc-tahoe.c \ + config/tc-tic30.c \ + config/tc-tic80.c \ + config/tc-vax.c \ + config/tc-w65.c \ + config/tc-v850.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-d10v.h \ + config/tc-d30v.h \ + config/tc-h8300.h \ + config/tc-h8500.h \ + config/tc-hppa.h \ + config/tc-i386.h \ + config/tc-i860.h \ + config/tc-i960.h \ + config/tc-m32r.h \ + config/tc-m68k.h \ + config/tc-m88k.h \ + config/tc-mcore.h \ + config/tc-mips.h \ + config/tc-mn10200.h \ + config/tc-mn10300.h \ + config/tc-ns32k.h \ + config/tc-ppc.h \ + config/tc-sh.h \ + config/tc-sparc.h \ + config/tc-tahoe.h \ + config/tc-tic30.h \ + config/tc-tic80.h \ + config/tc-vax.h \ + config/tc-w65.h \ + config/tc-v850.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-generic.h \ + config/te-go32.h \ + config/te-hp300.h \ + config/te-hppa.h \ + config/te-i386aix.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-multi.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 + +# Multi files in config + +MULTI_CFILES = \ + 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 \ + 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 file in $(POTFILES); do echo $$file; done | sort > tmp \ + && mv tmp $(srcdir)/po/POTFILES.in + +noinst_PROGRAMS = as-new gasp-new +noinst_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 + +DISTSTUFF = make-gas.com m68k-parse.c itbl-parse.c itbl-parse.h itbl-lex.c +diststuff: $(DISTSTUFF) 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\"" + +# 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) + +$(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) +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): config.h as.h $(TARG_ENV_H) $(OBJ_FORMAT_H) $(TARG_CPU_H) flonum.h \ + expr.h struc-symbol.h write.h frags.h hash.h read.h symbols.h tc.h \ + obj.h listing.h bignum.h bit_fix.h $(INCDIR)/libiberty.h asintl.h + +gasp_new_SOURCES = gasp.c macro.c sb.c hash.c +gasp_new_LDADD = ../libiberty/libiberty.a $(INTLLIBS) +gasp_new_DEPENDENCIES = ../libiberty/libiberty.a $(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= + +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) $(TARG_CPU_DEP_@target_cpu_type@) + $(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-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 + +# 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-test-ops.o itbl-test.o $(GASLIBS) @LEXLIB@ + +itbl-test-ops.o: $(srcdir)/itbl-ops.c $(srcdir)/itbl-ops.h itbl-parse.h + $(COMPILE) -o itbl-test-ops.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 .tcdep .objdep .dep2 .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) $(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 $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +install-exec-tooldir: $(noinst_PROGRAMS) + $(mkinstalldirs) $(tooldir)/bin + n=`echo as | sed '$(transform)'`; \ + if [ "$(bindir)/$$n$(EXEEXT)" != "$(tooldir)/bin/as$(EXEEXT)" ]; then \ + rm -f $(tooldir)/bin/as$(EXEEXT); \ + ln $(bindir)/$$n$(EXEEXT) $(tooldir)/bin/as$(EXEEXT) >/dev/null 2>/dev/null \ + || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) as-new$(EXEEXT) $(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 + +# Automatic dependency computation. This is a real pain, because the +# dependencies change based on target_cpu_type and obj_format. We +# currently ignore any dependencies caused by emulation files. + +DEP_FILE_DEPS = $(CFILES) $(HFILES) $(TARGET_CPU_CFILES) \ + $(TARGET_CPU_HFILES) $(OBJ_FORMAT_CFILES) $(OBJ_FORMAT_HFILES) + +.dep: dep.sed $(DEP_FILE_DEPS) .tcdep .objdep .dep2 + rm -f .dep1 + srcdir=`cd $(srcdir); pwd`; \ + $(MAKE) DEP=$(DEP) srcdir=$${srcdir} VPATH=$${srcdir} .dep1 + rm -rf .depdir + sed -f dep.sed < .dep1 > .depa + sed -f dep.sed < .tcdep >> .depa + sed -f dep.sed < .objdep >> .depa + sed -f dep.sed < .dep2 >> .depa + echo '$$(OBJS): $$(DEP_@target''_cpu_type@_@obj''_format@)' >> .depa + echo '$$(TARG_CPU_O): $$(TCDEP_@target''_cpu_type@_@obj''_format@)' >> .depa + echo '$$(OBJ_FORMAT_O): $$(OBJDEP_@target''_cpu_type@_@obj''_format@)' >> .depa + echo '# IF YOU PUT ANYTHING HERE IT WILL GO AWAY' >> .depa + $(SHELL) $(srcdir)/../move-if-change .depa .dep + +# This rule needs a mkdep that runs "gcc -MM". +.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 '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep; \ + $(DEP) -f .dep -DBFD_ASSEMBLER -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES) $? + sed -e '/IF YOU PUT ANYTHING/,$$d' < .depdir/.dep > .dep1 + rm -f .depdir/.dep + +# Work out the special dependencies for the tc-*.c files. +.tcdep: $(TARGET_CPU_CFILES) + rm -f .tcdepa + 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 '#include "opcodes/'"$${c}"'-desc.h"' > cgen-desc.h; \ + rm -f dummy.c; \ + cp $${srcdir}/config/tc-$${c}.c dummy.c; \ + echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep; \ + $(DEP) -f .dep -DBFD_ASSEMBLER -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES) dummy.c; \ + sed -e "s/dummy.o: dummy.c/TCDEP_$${c}_$${o} =/" \ + -e '1,/DO NOT PUT ANYTHING AFTER/d' \ + -e '/IF YOU PUT ANYTHING/,$$d' \ + -e '/^$$/d' < .dep >> ../.tcdepa; \ + rm -f dummy.c; \ + else true; fi; \ + done; \ + done + echo 'TCDEP_hppa_som = $$(srcdir)/config/tc-hppa.h subsegs.h \' >> .tcdepa + echo ' $$(INCDIR)/obstack.h $$(BFDDIR)/libhppa.h \' >> .tcdepa + echo ' $$(INCDIR)/opcode/hppa.h $$(BFDDIR)/som.h' >> .tcdepa + # We don't try to handle all multi cases. + for c in $(CPU_TYPES); do \ + $(CPU_MULTI_VALID) \ + if [ x$${valid} = xyes ]; then \ + o=ecoff; \ + $(CPU_OBJ_VALID) \ + echo 'TCDEP_'"$${c}"'_multi = \' >> .tcdepa; \ + echo '$$(TCDEP_'"$${c}"'_coff) \' >> .tcdepa; \ + if [ x$${valid} = xyes ]; then \ + echo '$$(TCDEP_'"$${c}"'_ecoff) \' >> .tcdepa; \ + else true; fi; \ + echo '$$(TCDEP_'"$${c}"'_elf)' >> .tcdepa; \ + else true; fi; \ + done + mv -f .tcdepa .tcdep + +# Work out the special dependencies for the obj-*.c files. +.objdep: $(OBJ_FORMAT_CFILES) + rm -f .objdepa + 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; \ + rm -f dummy.c; \ + cp $${srcdir}/config/obj-$${o}.c dummy.c; \ + echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep; \ + $(DEP) -f .dep -DBFD_ASSEMBLER -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES) dummy.c; \ + sed -e "s/dummy.o: dummy.c/OBJDEP_$${c}_$${o} =/" \ + -e '1,/DO NOT PUT ANYTHING AFTER/d' \ + -e '/IF YOU PUT ANYTHING/,$$d' \ + -e '/^$$/d' < .dep >> ../.objdepa; \ + rm -f dummy.c; \ + else true; fi; \ + done; \ + done + echo 'OBJDEP_hppa_som = $$(srcdir)/config/obj-som.h subsegs.h \' >> .objdepa + echo ' $$(INCDIR)/obstack.h $$(BFDDIR)/libhppa.h \' >> .objdepa + echo ' $$(BFDDIR)/som.h $$(INCDIR)/aout/stab_gnu.h \' >> .objdepa + echo ' $$(INCDIR)/aout/stab.def' >> .objdepa + # We don't try to handle all multi cases. + for c in $(CPU_TYPES); do \ + $(CPU_MULTI_VALID) \ + if [ x$${valid} = xyes ]; then \ + o=ecoff; \ + $(CPU_OBJ_VALID) \ + echo 'OBJDEP_'"$${c}"'_multi = \' >> .objdepa; \ + echo '$$(OBJDEP_'"$${c}"'_coff) \' >> .objdepa; \ + if [ x$${valid} = xyes ]; then \ + echo '$$(OBJDEP_'"$${c}"'_ecoff) \' >> .objdepa; \ + else true; fi; \ + echo '$$(OBJDEP_'"$${c}"'_elf)' >> .objdepa; \ + else true; fi; \ + done + mv -f .objdepa .objdep + +# 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; \ + echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep; \ + $(DEP) -f .dep -DBFD_ASSEMBLER -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES) dummy.c; \ + sed -e "s/dummy.o: dummy.c/DEP_$${c}_$${o} =/" \ + -e '1,/DO NOT PUT ANYTHING AFTER/d' \ + -e '/IF YOU PUT ANYTHING/,$$d' \ + -e '/^$$/d' < .dep >> ../.dep2a; \ + else true; fi; \ + done; \ + done + echo 'DEP_hppa_som = $$(BFDDIR)/som.h' >> .dep2a + # We don't try to handle all multi cases. + for c in $(CPU_TYPES); do \ + $(CPU_MULTI_VALID) \ + if [ x$${valid} = xyes ]; then \ + o=ecoff; \ + $(CPU_OBJ_VALID) \ + echo 'DEP_'"$${c}"'_multi = \' >> .dep2a; \ + echo '$$(DEP_'"$${c}"'_coff) \' >> .dep2a; \ + if [ x$${valid} = xyes ]; then \ + echo '$$(DEP_'"$${c}"'_ecoff) \' >> .dep2a; \ + else true; fi; \ + echo '$$(DEP_'"$${c}"'_elf)' >> .dep2a; \ + else true; fi; \ + 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}!" + +dep: .dep + sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile + cat .dep >> tmp-Makefile + $(SHELL) $(srcdir)/../move-if-change tmp-Makefile Makefile + +dep-in: .dep + sed -e '/^..DO NOT DELETE THIS LINE/,$$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 '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am + cat .dep >> tmp-Makefile.am + $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am + +.PHONY: dep dep-in dep-am + +# DO NOT DELETE THIS LINE -- mkdep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +app.o: app.c +as.o: as.c subsegs.h $(INCDIR)/obstack.h output-file.h \ + sb.h macro.h +atof-generic.o: atof-generic.c +bignum-copy.o: bignum-copy.c +cond.o: cond.c macro.h sb.h $(INCDIR)/obstack.h +depend.o: depend.c +ecoff.o: ecoff.c +ehopt.o: ehopt.c subsegs.h $(INCDIR)/obstack.h $(INCDIR)/elf/dwarf2.h +expr.o: expr.c $(INCDIR)/obstack.h +flonum-copy.o: flonum-copy.c +flonum-konst.o: flonum-konst.c +flonum-mult.o: flonum-mult.c +frags.o: frags.c subsegs.h $(INCDIR)/obstack.h +hash.o: hash.c +input-file.o: input-file.c input-file.h +input-scrub.o: input-scrub.c input-file.h sb.h +listing.o: listing.c input-file.h subsegs.h +literal.o: literal.c subsegs.h $(INCDIR)/obstack.h +macro.o: macro.c sb.h macro.h +messages.o: messages.c +output-file.o: output-file.c output-file.h +read.o: read.c subsegs.h $(INCDIR)/obstack.h sb.h macro.h \ + ecoff.h +sb.o: sb.c sb.h +stabs.o: stabs.c $(INCDIR)/obstack.h subsegs.h ecoff.h \ + $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def +subsegs.o: subsegs.c subsegs.h $(INCDIR)/obstack.h +symbols.o: symbols.c $(INCDIR)/obstack.h subsegs.h +write.o: write.c subsegs.h $(INCDIR)/obstack.h output-file.h +gasp.o: gasp.c sb.h macro.h +e-i386coff.o: $(srcdir)/config/e-i386coff.c emul.h \ + emul-target.h +e-i386elf.o: $(srcdir)/config/e-i386elf.c emul.h emul-target.h +e-mipsecoff.o: $(srcdir)/config/e-mipsecoff.c emul.h \ + emul-target.h +e-mipself.o: $(srcdir)/config/e-mipself.c emul.h emul-target.h + +TCDEP_a29k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-a29k.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/a29k.h +TCDEP_a29k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-a29k.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/a29k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/opcode/a29k.h +TCDEP_a29k_elf = $(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)/opcode/a29k.h +TCDEP_alpha_coff = $(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 ecoff.h $(INCDIR)/opcode/alpha.h \ + $(srcdir)/config/atof-vax.c +TCDEP_alpha_ecoff = $(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 $(INCDIR)/opcode/alpha.h \ + $(srcdir)/config/atof-vax.c +TCDEP_alpha_elf = $(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 ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \ + $(INCDIR)/opcode/alpha.h $(INCDIR)/elf/alpha.h $(INCDIR)/elf/reloc-macros.h \ + $(srcdir)/config/atof-vax.c +TCDEP_alpha_evax = $(srcdir)/config/obj-evax.h $(srcdir)/config/tc-alpha.h \ + subsegs.h $(INCDIR)/obstack.h ecoff.h $(INCDIR)/opcode/alpha.h \ + $(srcdir)/config/atof-vax.c +TCDEP_arc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arc.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/arc.h \ + $(INCDIR)/elf/arc.h $(INCDIR)/elf/reloc-macros.h +TCDEP_arc_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/arc.h $(INCDIR)/elf/arc.h \ + $(INCDIR)/elf/reloc-macros.h +TCDEP_arm_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-arm.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h +TCDEP_arm_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arm.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/arm.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h +TCDEP_arm_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h +TCDEP_d10v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d10v.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/d10v.h \ + $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h +TCDEP_d10v_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/d10v.h $(INCDIR)/elf/ppc.h \ + $(INCDIR)/elf/reloc-macros.h +TCDEP_d30v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d30v.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/d30v.h +TCDEP_d30v_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/d30v.h +TCDEP_fr30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-fr30.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/symcat.h $(srcdir)/../opcodes/fr30-desc.h \ + $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/fr30-opc.h \ + cgen.h +TCDEP_fr30_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/symcat.h $(srcdir)/../opcodes/fr30-desc.h \ + $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/fr30-opc.h \ + cgen.h +TCDEP_h8300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8300.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8300.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/h8300.h +TCDEP_h8300_elf = $(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 $(INCDIR)/opcode/h8300.h +TCDEP_h8500_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8500.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8500.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/h8500-opc.h +TCDEP_h8500_elf = $(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 +TCDEP_hppa_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-hppa.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(BFDDIR)/libhppa.h $(BFDDIR)/libbfd.h \ + $(INCDIR)/opcode/hppa.h +TCDEP_hppa_elf = $(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 \ + subsegs.h $(INCDIR)/obstack.h $(BFDDIR)/libbfd.h $(INCDIR)/opcode/hppa.h +TCDEP_i386_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i386.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \ + $(INCDIR)/opcode/i386.h +TCDEP_i386_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i386.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/i386.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/i386.h +TCDEP_i386_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/i386.h +TCDEP_i860_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i860.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/i860.h +TCDEP_i860_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i860.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/opcode/i860.h +TCDEP_i860_elf = $(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)/opcode/i860.h +TCDEP_i960_bout = $(srcdir)/config/obj-bout.h $(srcdir)/config/tc-i960.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/i960.h +TCDEP_i960_coff = $(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 $(INCDIR)/opcode/i960.h +TCDEP_i960_elf = $(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)/obstack.h \ + $(INCDIR)/opcode/i960.h +TCDEP_m32r_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m32r.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/symcat.h $(srcdir)/../opcodes/m32r-desc.h \ + $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/m32r-opc.h \ + cgen.h +TCDEP_m32r_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/symcat.h $(srcdir)/../opcodes/m32r-desc.h \ + $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/m32r-opc.h \ + cgen.h +TCDEP_m68k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \ + subsegs.h $(INCDIR)/opcode/m68k.h $(srcdir)/config/m68k-parse.h +TCDEP_m68k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m68k.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/m68k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h $(INCDIR)/opcode/m68k.h \ + $(srcdir)/config/m68k-parse.h +TCDEP_m68k_elf = $(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)/obstack.h \ + subsegs.h $(INCDIR)/opcode/m68k.h $(srcdir)/config/m68k-parse.h +TCDEP_m68k_hp300 = $(srcdir)/config/obj-hp300.h $(srcdir)/config/obj-aout.h \ + $(srcdir)/config/tc-m68k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/obstack.h subsegs.h $(INCDIR)/opcode/m68k.h \ + $(srcdir)/config/m68k-parse.h +TCDEP_m88k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m88k.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/m88k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/config/m88k-opcode.h +TCDEP_m88k_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(srcdir)/config/m88k-opcode.h +TCDEP_mcore_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mcore.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/mcore.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/mcore-opc.h +TCDEP_mcore_elf = $(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)/elf/mcore.h $(INCDIR)/elf/reloc-macros.h +TCDEP_mips_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-mips.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \ + $(INCDIR)/opcode/mips.h itbl-ops.h ecoff.h $(INCDIR)/coff/sym.h \ + $(INCDIR)/coff/ecoff.h +TCDEP_mips_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mips.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mips.h \ + itbl-ops.h ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h +TCDEP_mips_ecoff = $(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)/opcode/mips.h \ + itbl-ops.h +TCDEP_mips_elf = $(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)/opcode/mips.h itbl-ops.h \ + $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h ecoff.h \ + $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h +TCDEP_mn10200_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10200.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10200.h +TCDEP_mn10200_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10200.h +TCDEP_mn10300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10300.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10300.h +TCDEP_mn10300_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10300.h +TCDEP_ns32k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-ns32k.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/ns32k.h \ + $(INCDIR)/obstack.h +TCDEP_ns32k_coff = $(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 +TCDEP_ns32k_elf = $(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 +TCDEP_ppc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ppc.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/rs6000.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/ppc.h +TCDEP_ppc_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/ppc.h $(INCDIR)/elf/ppc.h \ + $(INCDIR)/elf/reloc-macros.h +TCDEP_sh_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sh.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/sh.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/sh-opc.h +TCDEP_sh_elf = $(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 +TCDEP_sparc_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-sparc.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \ + $(INCDIR)/opcode/sparc.h +TCDEP_sparc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sparc.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/sparc.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/sparc.h +TCDEP_sparc_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/sparc.h $(INCDIR)/elf/sparc.h \ + $(INCDIR)/elf/reloc-macros.h +TCDEP_tahoe_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tahoe.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \ + $(INCDIR)/opcode/tahoe.h +TCDEP_tahoe_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tahoe.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/tahoe.h +TCDEP_tahoe_elf = $(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)/obstack.h \ + $(INCDIR)/opcode/tahoe.h +TCDEP_tic30_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tic30.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/tic30.h +TCDEP_tic30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic30.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic30.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/opcode/tic30.h +TCDEP_tic30_elf = $(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)/opcode/tic30.h +TCDEP_tic80_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic80.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic80.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/opcode/tic80.h +TCDEP_tic80_elf = $(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)/opcode/tic80.h +TCDEP_vax_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-vax.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(srcdir)/config/vax-inst.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/vax.h +TCDEP_vax_coff = $(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 $(INCDIR)/opcode/vax.h +TCDEP_vax_elf = $(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 $(INCDIR)/opcode/vax.h +TCDEP_vax_vms = $(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 $(INCDIR)/opcode/vax.h +TCDEP_w65_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-w65.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/w65.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/w65-opc.h +TCDEP_w65_elf = $(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 +TCDEP_v850_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-v850.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/v850.h +TCDEP_v850_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/v850.h +TCDEP_z8k_coff = $(srcdir)/../opcodes/z8k-opc.h $(srcdir)/config/obj-coff.h \ + $(srcdir)/config/tc-z8k.h $(INCDIR)/coff/internal.h \ + $(INCDIR)/coff/z8k.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h +TCDEP_z8k_elf = $(srcdir)/../opcodes/z8k-opc.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 +TCDEP_hppa_som = $(srcdir)/config/tc-hppa.h subsegs.h \ + $(INCDIR)/obstack.h $(BFDDIR)/libhppa.h $(INCDIR)/opcode/hppa.h \ + $(BFDDIR)/som.h +TCDEP_i386_multi = $(TCDEP_i386_coff) $(TCDEP_i386_elf) +TCDEP_mips_multi = $(TCDEP_mips_coff) $(TCDEP_mips_ecoff) \ + $(TCDEP_mips_elf) +OBJDEP_a29k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-a29k.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h +OBJDEP_a29k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-a29k.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/a29k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h +OBJDEP_a29k_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_alpha_coff = $(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 +OBJDEP_alpha_ecoff = $(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 +OBJDEP_alpha_elf = $(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 ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \ + $(INCDIR)/elf/alpha.h $(INCDIR)/elf/reloc-macros.h \ + $(INCDIR)/aout/aout64.h +OBJDEP_alpha_evax = $(srcdir)/config/obj-evax.h $(srcdir)/config/tc-alpha.h +OBJDEP_arc_coff = $(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 +OBJDEP_arc_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_arm_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-arm.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h +OBJDEP_arm_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arm.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/arm.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h +OBJDEP_arm_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_d10v_coff = $(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 +OBJDEP_d10v_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_d30v_coff = $(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 +OBJDEP_d30v_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_fr30_coff = $(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 +OBJDEP_fr30_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_h8300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8300.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8300.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h +OBJDEP_h8300_elf = $(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 $(INCDIR)/aout/aout64.h +OBJDEP_h8500_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8500.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8500.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h +OBJDEP_h8500_elf = $(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 $(INCDIR)/aout/aout64.h +OBJDEP_hppa_coff = $(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 +OBJDEP_hppa_elf = $(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 \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_i386_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i386.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h +OBJDEP_i386_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i386.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/i386.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h +OBJDEP_i386_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_i860_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i860.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h +OBJDEP_i860_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i860.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/obstack.h subsegs.h +OBJDEP_i860_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_i960_bout = $(srcdir)/config/obj-bout.h $(srcdir)/config/tc-i960.h \ + $(INCDIR)/obstack.h +OBJDEP_i960_coff = $(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 +OBJDEP_i960_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_m32r_coff = $(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 +OBJDEP_m32r_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_m68k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h +OBJDEP_m68k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m68k.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/m68k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h +OBJDEP_m68k_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_m68k_hp300 = $(srcdir)/config/obj-aout.c $(srcdir)/config/obj-hp300.h \ + $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h +OBJDEP_m88k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m88k.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/m88k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h +OBJDEP_m88k_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_mcore_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mcore.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/mcore.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h +OBJDEP_mcore_elf = $(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 $(INCDIR)/aout/aout64.h +OBJDEP_mips_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-mips.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h +OBJDEP_mips_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mips.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/obstack.h subsegs.h +OBJDEP_mips_ecoff = $(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 +OBJDEP_mips_elf = $(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 ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \ + $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/aout/aout64.h +OBJDEP_mn10200_coff = $(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 +OBJDEP_mn10200_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_mn10300_coff = $(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 +OBJDEP_mn10300_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_ns32k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-ns32k.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h +OBJDEP_ns32k_coff = $(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 +OBJDEP_ns32k_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_ppc_coff = $(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 +OBJDEP_ppc_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h \ + $(INCDIR)/aout/aout64.h +OBJDEP_sh_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sh.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/sh.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h +OBJDEP_sh_elf = $(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 $(INCDIR)/aout/aout64.h +OBJDEP_sparc_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-sparc.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h +OBJDEP_sparc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sparc.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/sparc.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h +OBJDEP_sparc_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_tahoe_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tahoe.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h +OBJDEP_tahoe_coff = $(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 +OBJDEP_tahoe_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_tic30_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tic30.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h +OBJDEP_tic30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic30.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic30.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h +OBJDEP_tic30_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_tic80_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic80.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic80.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h +OBJDEP_tic80_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_vax_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-vax.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h +OBJDEP_vax_coff = $(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 +OBJDEP_vax_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_vax_vms = $(srcdir)/config/obj-vms.h $(srcdir)/config/tc-vax.h \ + $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def subsegs.h \ + $(INCDIR)/obstack.h +OBJDEP_w65_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-w65.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/w65.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h +OBJDEP_w65_elf = $(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 $(INCDIR)/aout/aout64.h +OBJDEP_v850_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-v850.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/obstack.h subsegs.h +OBJDEP_v850_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_z8k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-z8k.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/z8k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h +OBJDEP_z8k_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h +OBJDEP_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 +OBJDEP_i386_multi = $(OBJDEP_i386_coff) $(OBJDEP_i386_elf) +OBJDEP_mips_multi = $(OBJDEP_mips_coff) $(OBJDEP_mips_ecoff) \ + $(OBJDEP_mips_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)/coff/internal.h $(INCDIR)/coff/a29k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h +DEP_a29k_elf = $(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 +DEP_alpha_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-alpha.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 $(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)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h +DEP_arc_elf = $(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 +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)/coff/internal.h $(INCDIR)/coff/arm.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h +DEP_arm_elf = $(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 +DEP_d10v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d10v.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h +DEP_d10v_elf = $(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 +DEP_d30v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d30v.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h +DEP_d30v_elf = $(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 +DEP_fr30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-fr30.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h +DEP_fr30_elf = $(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 +DEP_h8300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8300.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8300.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h +DEP_h8300_elf = $(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 +DEP_h8500_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8500.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8500.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h +DEP_h8500_elf = $(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 +DEP_hppa_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-hppa.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h +DEP_hppa_elf = $(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 +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)/coff/internal.h $(INCDIR)/coff/i386.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h +DEP_i386_elf = $(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 +DEP_i860_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i860.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h +DEP_i860_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i860.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h +DEP_i860_elf = $(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 +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)/coff/internal.h $(INCDIR)/coff/i960.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h +DEP_i960_elf = $(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 +DEP_m32r_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m32r.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h +DEP_m32r_elf = $(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 +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)/coff/internal.h $(INCDIR)/coff/m68k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h +DEP_m68k_elf = $(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 +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)/coff/internal.h $(INCDIR)/coff/m88k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h +DEP_m88k_elf = $(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 +DEP_mcore_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mcore.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/mcore.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h +DEP_mcore_elf = $(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 +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)/coff/internal.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 $(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_mn10200_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10200.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h +DEP_mn10200_elf = $(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 +DEP_mn10300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10300.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h +DEP_mn10300_elf = $(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 +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)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h +DEP_ns32k_elf = $(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 +DEP_ppc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ppc.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/rs6000.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h +DEP_ppc_elf = $(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 +DEP_sh_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sh.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/sh.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h +DEP_sh_elf = $(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 +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)/coff/internal.h $(INCDIR)/coff/sparc.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h +DEP_sparc_elf = $(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 +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)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h +DEP_tahoe_elf = $(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 +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)/coff/internal.h $(INCDIR)/coff/tic30.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h +DEP_tic30_elf = $(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 +DEP_tic80_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic80.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic80.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h +DEP_tic80_elf = $(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 +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)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h +DEP_vax_elf = $(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 +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)/coff/internal.h $(INCDIR)/coff/w65.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h +DEP_w65_elf = $(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 +DEP_v850_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-v850.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h +DEP_v850_elf = $(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 +DEP_z8k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-z8k.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/z8k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h +DEP_z8k_elf = $(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 +DEP_hppa_som = $(BFDDIR)/som.h +DEP_i386_multi = $(DEP_i386_coff) $(DEP_i386_elf) +DEP_mips_multi = $(DEP_mips_coff) $(DEP_mips_ecoff) \ + $(DEP_mips_elf) +$(OBJS): $(DEP_@target_cpu_type@_@obj_format@) +$(TARG_CPU_O): $(TCDEP_@target_cpu_type@_@obj_format@) +$(OBJ_FORMAT_O): $(OBJDEP_@target_cpu_type@_@obj_format@) +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/gas/Makefile.in b/gas/Makefile.in new file mode 100644 index 0000000000..244fff2ef3 --- /dev/null +++ b/gas/Makefile.in @@ -0,0 +1,2488 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 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. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +ALL_OBJ_DEPS = @ALL_OBJ_DEPS@ +AS = @AS@ +BFDLIB = @BFDLIB@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +DATADIRNAME = @DATADIRNAME@ +DLLTOOL = @DLLTOOL@ +EXEEXT = @EXEEXT@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLOBJS = @INTLOBJS@ +LD = @LD@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +NM = @NM@ +OPCODES_LIB = @OPCODES_LIB@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +atof = @atof@ +cgen_cpu_prefix = @cgen_cpu_prefix@ +extra_objects = @extra_objects@ +install_tooldir = @install_tooldir@ +l = @l@ +obj_format = @obj_format@ +target_cpu_type = @target_cpu_type@ +te_file = @te_file@ + +INTLLIBS = @INTLLIBS@ + +AUTOMAKE_OPTIONS = cygnus dejagnu + +SUBDIRS = doc po + +tooldir = $(exec_prefix)/$(target_alias) + +YACC = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L../bison/bison ; else echo bison -y ; fi` +LEX = `if [ -f ../flex/flex ] ; then echo ../flex/flex ; else echo flex ; fi` + +DEP = $(srcdir)/../mkdep + +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 \ + d10v \ + d30v \ + fr30 \ + h8300 \ + h8500 \ + hppa \ + i386 \ + i860 \ + i960 \ + m32r \ + m68k \ + m88k \ + mcore \ + mips \ + mn10200 \ + mn10300 \ + ns32k \ + ppc \ + sh \ + sparc \ + tahoe \ + tic30 \ + tic80 \ + vax \ + w65 \ + v850 \ + 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 | i386 | i860 | m68k | mips | ns32k | sparc | tahoe | tic30 | vax) \ + valid=yes ;; \ + esac ;; \ + bout) \ + case $$c in \ + i960) valid=yes ;; \ + esac ;; \ + coff) valid=yes ;; \ + 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; + + +# This is like CPU_OBJ_VALID, for the obj=multi case. + +CPU_MULTI_VALID = \ + valid= ; \ + case $$c in \ + i386 | mips) valid=yes ;; \ + esac; + + +# Regular source files. + +GAS_CFILES = \ + app.c \ + as.c \ + atof-generic.c \ + bignum-copy.c \ + cond.c \ + depend.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) gasp.c itbl-ops.c + +HFILES = \ + as.h \ + asintl.h \ + bignum.h \ + bit_fix.h \ + cgen.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-d10v.c \ + config/tc-d30v.c \ + config/tc-h8300.c \ + config/tc-h8500.c \ + config/tc-hppa.c \ + config/tc-i386.c \ + config/tc-i860.c \ + config/tc-i960.c \ + config/tc-m32r.c \ + config/tc-m68k.c \ + config/tc-m88k.c \ + config/tc-mcore.c \ + config/tc-mips.c \ + config/tc-mn10200.c \ + config/tc-mn10300.c \ + config/tc-ns32k.c \ + config/tc-ppc.c \ + config/tc-sh.c \ + config/tc-sparc.c \ + config/tc-tahoe.c \ + config/tc-tic30.c \ + config/tc-tic80.c \ + config/tc-vax.c \ + config/tc-w65.c \ + config/tc-v850.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-d10v.h \ + config/tc-d30v.h \ + config/tc-h8300.h \ + config/tc-h8500.h \ + config/tc-hppa.h \ + config/tc-i386.h \ + config/tc-i860.h \ + config/tc-i960.h \ + config/tc-m32r.h \ + config/tc-m68k.h \ + config/tc-m88k.h \ + config/tc-mcore.h \ + config/tc-mips.h \ + config/tc-mn10200.h \ + config/tc-mn10300.h \ + config/tc-ns32k.h \ + config/tc-ppc.h \ + config/tc-sh.h \ + config/tc-sparc.h \ + config/tc-tahoe.h \ + config/tc-tic30.h \ + config/tc-tic80.h \ + config/tc-vax.h \ + config/tc-w65.h \ + config/tc-v850.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-generic.h \ + config/te-go32.h \ + config/te-hp300.h \ + config/te-hppa.h \ + config/te-i386aix.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-multi.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 + + +# Multi files in config + +MULTI_CFILES = \ + 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 \ + 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_PROGRAMS = as-new gasp-new +noinst_SCRIPTS = .gdbinit + +EXTRA_DIST = make-gas.com + +DISTSTUFF = 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\"" + +# 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) + +as_new_DEPENDENCIES = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \ + $(extra_objects) $(GASLIBS) $(INTLDEPS) + + +gasp_new_SOURCES = gasp.c macro.c sb.c hash.c +gasp_new_LDADD = ../libiberty/libiberty.a $(INTLLIBS) +gasp_new_DEPENDENCIES = ../libiberty/libiberty.a $(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 + +# stand-alone itbl assembler & disassembler + +EXTRA_PROGRAMS = itbl-test +itbl_test_SOURCES = itbl-parse.y itbl-lex.l +itbl_test_LDADD = itbl-test-ops.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 .tcdep .objdep .dep2 .dep1 .depa .dep .depdir + +against = stage2 + +# Automatic dependency computation. This is a real pain, because the +# dependencies change based on target_cpu_type and obj_format. We +# currently ignore any dependencies caused by emulation files. + +DEP_FILE_DEPS = $(CFILES) $(HFILES) $(TARGET_CPU_CFILES) \ + $(TARGET_CPU_HFILES) $(OBJ_FORMAT_CFILES) $(OBJ_FORMAT_HFILES) + + +TCDEP_a29k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-a29k.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/a29k.h + +TCDEP_a29k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-a29k.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/a29k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/opcode/a29k.h + +TCDEP_a29k_elf = $(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)/opcode/a29k.h + +TCDEP_alpha_coff = $(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 ecoff.h $(INCDIR)/opcode/alpha.h \ + $(srcdir)/config/atof-vax.c + +TCDEP_alpha_ecoff = $(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 $(INCDIR)/opcode/alpha.h \ + $(srcdir)/config/atof-vax.c + +TCDEP_alpha_elf = $(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 ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \ + $(INCDIR)/opcode/alpha.h $(INCDIR)/elf/alpha.h $(INCDIR)/elf/reloc-macros.h \ + $(srcdir)/config/atof-vax.c + +TCDEP_alpha_evax = $(srcdir)/config/obj-evax.h $(srcdir)/config/tc-alpha.h \ + subsegs.h $(INCDIR)/obstack.h ecoff.h $(INCDIR)/opcode/alpha.h \ + $(srcdir)/config/atof-vax.c + +TCDEP_arc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arc.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/arc.h \ + $(INCDIR)/elf/arc.h $(INCDIR)/elf/reloc-macros.h + +TCDEP_arc_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/arc.h $(INCDIR)/elf/arc.h \ + $(INCDIR)/elf/reloc-macros.h + +TCDEP_arm_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-arm.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h + +TCDEP_arm_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arm.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/arm.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h + +TCDEP_arm_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h + +TCDEP_d10v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d10v.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/d10v.h \ + $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h + +TCDEP_d10v_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/d10v.h $(INCDIR)/elf/ppc.h \ + $(INCDIR)/elf/reloc-macros.h + +TCDEP_d30v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d30v.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/d30v.h + +TCDEP_d30v_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/d30v.h + +TCDEP_fr30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-fr30.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/symcat.h $(srcdir)/../opcodes/fr30-desc.h \ + $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/fr30-opc.h \ + cgen.h + +TCDEP_fr30_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/symcat.h $(srcdir)/../opcodes/fr30-desc.h \ + $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/fr30-opc.h \ + cgen.h + +TCDEP_h8300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8300.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8300.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/h8300.h + +TCDEP_h8300_elf = $(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 $(INCDIR)/opcode/h8300.h + +TCDEP_h8500_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8500.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8500.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/h8500-opc.h + +TCDEP_h8500_elf = $(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 + +TCDEP_hppa_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-hppa.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(BFDDIR)/libhppa.h $(BFDDIR)/libbfd.h \ + $(INCDIR)/opcode/hppa.h + +TCDEP_hppa_elf = $(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 \ + subsegs.h $(INCDIR)/obstack.h $(BFDDIR)/libbfd.h $(INCDIR)/opcode/hppa.h + +TCDEP_i386_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i386.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \ + $(INCDIR)/opcode/i386.h + +TCDEP_i386_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i386.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/i386.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/i386.h + +TCDEP_i386_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/i386.h + +TCDEP_i860_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i860.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/i860.h + +TCDEP_i860_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i860.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/opcode/i860.h + +TCDEP_i860_elf = $(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)/opcode/i860.h + +TCDEP_i960_bout = $(srcdir)/config/obj-bout.h $(srcdir)/config/tc-i960.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/i960.h + +TCDEP_i960_coff = $(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 $(INCDIR)/opcode/i960.h + +TCDEP_i960_elf = $(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)/obstack.h \ + $(INCDIR)/opcode/i960.h + +TCDEP_m32r_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m32r.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/symcat.h $(srcdir)/../opcodes/m32r-desc.h \ + $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/m32r-opc.h \ + cgen.h + +TCDEP_m32r_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/symcat.h $(srcdir)/../opcodes/m32r-desc.h \ + $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/m32r-opc.h \ + cgen.h + +TCDEP_m68k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \ + subsegs.h $(INCDIR)/opcode/m68k.h $(srcdir)/config/m68k-parse.h + +TCDEP_m68k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m68k.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/m68k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h $(INCDIR)/opcode/m68k.h \ + $(srcdir)/config/m68k-parse.h + +TCDEP_m68k_elf = $(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)/obstack.h \ + subsegs.h $(INCDIR)/opcode/m68k.h $(srcdir)/config/m68k-parse.h + +TCDEP_m68k_hp300 = $(srcdir)/config/obj-hp300.h $(srcdir)/config/obj-aout.h \ + $(srcdir)/config/tc-m68k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/obstack.h subsegs.h $(INCDIR)/opcode/m68k.h \ + $(srcdir)/config/m68k-parse.h + +TCDEP_m88k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m88k.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/m88k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/config/m88k-opcode.h + +TCDEP_m88k_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(srcdir)/config/m88k-opcode.h + +TCDEP_mcore_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mcore.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/mcore.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/mcore-opc.h + +TCDEP_mcore_elf = $(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)/elf/mcore.h $(INCDIR)/elf/reloc-macros.h + +TCDEP_mips_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-mips.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \ + $(INCDIR)/opcode/mips.h itbl-ops.h ecoff.h $(INCDIR)/coff/sym.h \ + $(INCDIR)/coff/ecoff.h + +TCDEP_mips_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mips.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mips.h \ + itbl-ops.h ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h + +TCDEP_mips_ecoff = $(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)/opcode/mips.h \ + itbl-ops.h + +TCDEP_mips_elf = $(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)/opcode/mips.h itbl-ops.h \ + $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h ecoff.h \ + $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h + +TCDEP_mn10200_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10200.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10200.h + +TCDEP_mn10200_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10200.h + +TCDEP_mn10300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10300.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10300.h + +TCDEP_mn10300_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10300.h + +TCDEP_ns32k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-ns32k.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/ns32k.h \ + $(INCDIR)/obstack.h + +TCDEP_ns32k_coff = $(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 + +TCDEP_ns32k_elf = $(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 + +TCDEP_ppc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ppc.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/rs6000.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/ppc.h + +TCDEP_ppc_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/ppc.h $(INCDIR)/elf/ppc.h \ + $(INCDIR)/elf/reloc-macros.h + +TCDEP_sh_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sh.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/sh.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/sh-opc.h + +TCDEP_sh_elf = $(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 + +TCDEP_sparc_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-sparc.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \ + $(INCDIR)/opcode/sparc.h + +TCDEP_sparc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sparc.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/sparc.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/sparc.h + +TCDEP_sparc_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/sparc.h $(INCDIR)/elf/sparc.h \ + $(INCDIR)/elf/reloc-macros.h + +TCDEP_tahoe_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tahoe.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \ + $(INCDIR)/opcode/tahoe.h + +TCDEP_tahoe_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tahoe.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/tahoe.h + +TCDEP_tahoe_elf = $(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)/obstack.h \ + $(INCDIR)/opcode/tahoe.h + +TCDEP_tic30_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tic30.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/tic30.h + +TCDEP_tic30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic30.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic30.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/opcode/tic30.h + +TCDEP_tic30_elf = $(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)/opcode/tic30.h + +TCDEP_tic80_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic80.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic80.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/opcode/tic80.h + +TCDEP_tic80_elf = $(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)/opcode/tic80.h + +TCDEP_vax_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-vax.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(srcdir)/config/vax-inst.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/vax.h + +TCDEP_vax_coff = $(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 $(INCDIR)/opcode/vax.h + +TCDEP_vax_elf = $(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 $(INCDIR)/opcode/vax.h + +TCDEP_vax_vms = $(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 $(INCDIR)/opcode/vax.h + +TCDEP_w65_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-w65.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/w65.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/w65-opc.h + +TCDEP_w65_elf = $(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 + +TCDEP_v850_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-v850.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/v850.h + +TCDEP_v850_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/opcode/v850.h + +TCDEP_z8k_coff = $(srcdir)/../opcodes/z8k-opc.h $(srcdir)/config/obj-coff.h \ + $(srcdir)/config/tc-z8k.h $(INCDIR)/coff/internal.h \ + $(INCDIR)/coff/z8k.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h + +TCDEP_z8k_elf = $(srcdir)/../opcodes/z8k-opc.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 + +TCDEP_hppa_som = $(srcdir)/config/tc-hppa.h subsegs.h \ + $(INCDIR)/obstack.h $(BFDDIR)/libhppa.h $(INCDIR)/opcode/hppa.h \ + $(BFDDIR)/som.h + +TCDEP_i386_multi = $(TCDEP_i386_coff) $(TCDEP_i386_elf) +TCDEP_mips_multi = $(TCDEP_mips_coff) $(TCDEP_mips_ecoff) \ + $(TCDEP_mips_elf) + +OBJDEP_a29k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-a29k.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h + +OBJDEP_a29k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-a29k.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/a29k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h + +OBJDEP_a29k_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_alpha_coff = $(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 + +OBJDEP_alpha_ecoff = $(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 + +OBJDEP_alpha_elf = $(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 ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \ + $(INCDIR)/elf/alpha.h $(INCDIR)/elf/reloc-macros.h \ + $(INCDIR)/aout/aout64.h + +OBJDEP_alpha_evax = $(srcdir)/config/obj-evax.h $(srcdir)/config/tc-alpha.h +OBJDEP_arc_coff = $(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 + +OBJDEP_arc_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_arm_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-arm.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h + +OBJDEP_arm_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arm.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/arm.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h + +OBJDEP_arm_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_d10v_coff = $(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 + +OBJDEP_d10v_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_d30v_coff = $(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 + +OBJDEP_d30v_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_fr30_coff = $(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 + +OBJDEP_fr30_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_h8300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8300.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8300.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h + +OBJDEP_h8300_elf = $(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 $(INCDIR)/aout/aout64.h + +OBJDEP_h8500_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8500.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8500.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h + +OBJDEP_h8500_elf = $(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 $(INCDIR)/aout/aout64.h + +OBJDEP_hppa_coff = $(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 + +OBJDEP_hppa_elf = $(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 \ + subsegs.h $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_i386_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i386.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h + +OBJDEP_i386_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i386.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/i386.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h + +OBJDEP_i386_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_i860_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i860.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h + +OBJDEP_i860_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i860.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/obstack.h subsegs.h + +OBJDEP_i860_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_i960_bout = $(srcdir)/config/obj-bout.h $(srcdir)/config/tc-i960.h \ + $(INCDIR)/obstack.h + +OBJDEP_i960_coff = $(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 + +OBJDEP_i960_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_m32r_coff = $(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 + +OBJDEP_m32r_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_m68k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h + +OBJDEP_m68k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m68k.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/m68k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h + +OBJDEP_m68k_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_m68k_hp300 = $(srcdir)/config/obj-aout.c $(srcdir)/config/obj-hp300.h \ + $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h + +OBJDEP_m88k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m88k.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/m88k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h + +OBJDEP_m88k_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_mcore_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mcore.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/mcore.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h + +OBJDEP_mcore_elf = $(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 $(INCDIR)/aout/aout64.h + +OBJDEP_mips_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-mips.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h + +OBJDEP_mips_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mips.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/obstack.h subsegs.h + +OBJDEP_mips_ecoff = $(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 + +OBJDEP_mips_elf = $(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 ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \ + $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/aout/aout64.h + +OBJDEP_mn10200_coff = $(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 + +OBJDEP_mn10200_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_mn10300_coff = $(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 + +OBJDEP_mn10300_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_ns32k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-ns32k.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h + +OBJDEP_ns32k_coff = $(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 + +OBJDEP_ns32k_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_ppc_coff = $(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 + +OBJDEP_ppc_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h \ + $(INCDIR)/aout/aout64.h + +OBJDEP_sh_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sh.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/sh.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h + +OBJDEP_sh_elf = $(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 $(INCDIR)/aout/aout64.h + +OBJDEP_sparc_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-sparc.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h + +OBJDEP_sparc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sparc.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/sparc.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h + +OBJDEP_sparc_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_tahoe_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tahoe.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h + +OBJDEP_tahoe_coff = $(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 + +OBJDEP_tahoe_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_tic30_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tic30.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h + +OBJDEP_tic30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic30.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic30.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h + +OBJDEP_tic30_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_tic80_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic80.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic80.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h + +OBJDEP_tic80_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_vax_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-vax.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ + $(INCDIR)/obstack.h + +OBJDEP_vax_coff = $(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 + +OBJDEP_vax_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_vax_vms = $(srcdir)/config/obj-vms.h $(srcdir)/config/tc-vax.h \ + $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def subsegs.h \ + $(INCDIR)/obstack.h + +OBJDEP_w65_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-w65.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/w65.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h + +OBJDEP_w65_elf = $(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 $(INCDIR)/aout/aout64.h + +OBJDEP_v850_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-v850.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/obstack.h subsegs.h + +OBJDEP_v850_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_z8k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-z8k.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/z8k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h + +OBJDEP_z8k_elf = $(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 subsegs.h \ + $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h + +OBJDEP_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 + +OBJDEP_i386_multi = $(OBJDEP_i386_coff) $(OBJDEP_i386_elf) +OBJDEP_mips_multi = $(OBJDEP_mips_coff) $(OBJDEP_mips_ecoff) \ + $(OBJDEP_mips_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)/coff/internal.h $(INCDIR)/coff/a29k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h + +DEP_a29k_elf = $(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 + +DEP_alpha_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-alpha.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 $(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)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h + +DEP_arc_elf = $(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 + +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)/coff/internal.h $(INCDIR)/coff/arm.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h + +DEP_arm_elf = $(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 + +DEP_d10v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d10v.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h + +DEP_d10v_elf = $(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 + +DEP_d30v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d30v.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h + +DEP_d30v_elf = $(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 + +DEP_fr30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-fr30.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h + +DEP_fr30_elf = $(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 + +DEP_h8300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8300.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8300.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h + +DEP_h8300_elf = $(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 + +DEP_h8500_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8500.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8500.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h + +DEP_h8500_elf = $(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 + +DEP_hppa_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-hppa.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h + +DEP_hppa_elf = $(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 + +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)/coff/internal.h $(INCDIR)/coff/i386.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h + +DEP_i386_elf = $(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 + +DEP_i860_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i860.h \ + $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h + +DEP_i860_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i860.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h + +DEP_i860_elf = $(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 + +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)/coff/internal.h $(INCDIR)/coff/i960.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h + +DEP_i960_elf = $(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 + +DEP_m32r_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m32r.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h + +DEP_m32r_elf = $(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 + +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)/coff/internal.h $(INCDIR)/coff/m68k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h + +DEP_m68k_elf = $(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 + +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)/coff/internal.h $(INCDIR)/coff/m88k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h + +DEP_m88k_elf = $(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 + +DEP_mcore_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mcore.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/mcore.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h + +DEP_mcore_elf = $(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 + +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)/coff/internal.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 $(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_mn10200_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10200.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h + +DEP_mn10200_elf = $(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 + +DEP_mn10300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10300.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h + +DEP_mn10300_elf = $(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 + +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)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h + +DEP_ns32k_elf = $(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 + +DEP_ppc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ppc.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/rs6000.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h + +DEP_ppc_elf = $(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 + +DEP_sh_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sh.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/sh.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h + +DEP_sh_elf = $(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 + +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)/coff/internal.h $(INCDIR)/coff/sparc.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h + +DEP_sparc_elf = $(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 + +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)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h + +DEP_tahoe_elf = $(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 + +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)/coff/internal.h $(INCDIR)/coff/tic30.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h + +DEP_tic30_elf = $(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 + +DEP_tic80_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic80.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic80.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h + +DEP_tic80_elf = $(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 + +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)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h + +DEP_vax_elf = $(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 + +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)/coff/internal.h $(INCDIR)/coff/w65.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h + +DEP_w65_elf = $(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 + +DEP_v850_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-v850.h \ + $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h + +DEP_v850_elf = $(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 + +DEP_z8k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-z8k.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/z8k.h $(BFDDIR)/libcoff.h \ + $(INCDIR)/bfdlink.h + +DEP_z8k_elf = $(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 + +DEP_hppa_som = $(BFDDIR)/som.h +DEP_i386_multi = $(DEP_i386_coff) $(DEP_i386_elf) +DEP_mips_multi = $(DEP_mips_coff) $(DEP_mips_ecoff) \ + $(DEP_mips_elf) + +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = .gdbinit +noinst_PROGRAMS = as-new$(EXEEXT) gasp-new$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +itbl_test_OBJECTS = itbl-parse.o itbl-lex.o +itbl_test_DEPENDENCIES = itbl-test-ops.o itbl-test.o \ +../libiberty/libiberty.a +itbl_test_LDFLAGS = +as_new_OBJECTS = app.o as.o atof-generic.o bignum-copy.o cond.o \ +depend.o ecoff.o ehopt.o expr.o flonum-copy.o flonum-konst.o \ +flonum-mult.o frags.o hash.o input-file.o input-scrub.o listing.o \ +literal.o macro.o messages.o output-file.o read.o sb.o stabs.o \ +subsegs.o symbols.o write.o +as_new_LDFLAGS = +gasp_new_OBJECTS = gasp.o macro.o sb.o hash.o +gasp_new_LDFLAGS = +SCRIPTS = $(noinst_SCRIPTS) + +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LEXLIB = @LEXLIB@ +YLWRAP = $(top_srcdir)/../ylwrap +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = README ./stamp-h.in COPYING ChangeLog Makefile.am \ +Makefile.in NEWS acinclude.m4 aclocal.m4 config.in config/m68k-parse.c \ +configure configure.in gdbinit.in itbl-lex.c itbl-parse.c + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +SOURCES = $(itbl_test_SOURCES) $(as_new_SOURCES) $(EXTRA_as_new_SOURCES) $(gasp_new_SOURCES) +OBJECTS = $(itbl_test_OBJECTS) $(as_new_OBJECTS) $(gasp_new_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .l .lo .o .s .y +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4 + cd $(srcdir) && $(ACLOCAL) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +config.h: stamp-h + @if test ! -f $@; then \ + rm -f stamp-h; \ + $(MAKE) stamp-h; \ + else :; fi +stamp-h: $(srcdir)/config.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES= CONFIG_HEADERS=config.h:config.in \ + $(SHELL) ./config.status + @echo timestamp > stamp-h 2> /dev/null +$(srcdir)/config.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in + @if test ! -f $@; then \ + rm -f $(srcdir)/stamp-h.in; \ + $(MAKE) $(srcdir)/stamp-h.in; \ + else :; fi +$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOHEADER) + @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null + +mostlyclean-hdr: + +clean-hdr: + +distclean-hdr: + -rm -f config.h + +maintainer-clean-hdr: +.gdbinit: $(top_builddir)/config.status gdbinit.in + cd $(top_builddir) && CONFIG_FILES=$@:gdbinit.in CONFIG_HEADERS= $(SHELL) ./config.status + +mostlyclean-noinstPROGRAMS: + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +distclean-noinstPROGRAMS: + +maintainer-clean-noinstPROGRAMS: + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +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) + +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) + +gasp-new$(EXEEXT): $(gasp_new_OBJECTS) $(gasp_new_DEPENDENCIES) + @rm -f gasp-new$(EXEEXT) + $(LINK) $(gasp_new_LDFLAGS) $(gasp_new_OBJECTS) $(gasp_new_LDADD) $(LIBS) +.l.c: + $(LEX) $(AM_LFLAGS) $(LFLAGS) $< && mv $(LEX_OUTPUT_ROOT).c $@ +.y.c: + $(SHELL) $(YLWRAP) "$(YACC)" $< y.tab.c $*.c y.tab.h $*.h -- $(AM_YFLAGS) $(YFLAGS) +config/m68k-parse.h: config/m68k-parse.c +itbl-parse.h: itbl-parse.c + + +# 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. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive install-info-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @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; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" = "." && dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && 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 + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)config.in$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.in $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done + +DEJATOOL = $(PACKAGE) + +RUNTESTDEFAULTFLAGS = --tool $(DEJATOOL) --srcdir $$srcdir +site.exp: Makefile + @echo 'Making a new site.exp file...' + @test ! -f site.bak || rm -f site.bak + @echo '## these variables are automatically generated by make ##' > $@-t + @echo '# Do not edit here. If you wish to override these values' >> $@-t + @echo '# edit the last section' >> $@-t + @echo 'set tool $(DEJATOOL)' >> $@-t + @echo 'set srcdir $(srcdir)' >> $@-t + @echo 'set objdir' `pwd` >> $@-t + @echo 'set host_alias $(host_alias)' >> $@-t + @echo 'set host_triplet $(host_triplet)' >> $@-t + @echo 'set target_alias $(target_alias)' >> $@-t + @echo 'set target_triplet $(target_triplet)' >> $@-t + @echo 'set build_alias $(build_alias)' >> $@-t + @echo 'set build_triplet $(build_triplet)' >> $@-t + @echo '## All variables above are generated by configure. Do Not Edit ##' >> $@-t + @test ! -f site.exp || sed '1,/^## All variables above are.*##/ d' site.exp >> $@-t + @test ! -f site.exp || mv site.exp site.bak + @mv $@-t site.exp +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: + $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +install-info-am: +install-info: install-info-recursive +all-recursive-am: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +install-exec-am: install-exec-local +install-exec: install-exec-recursive + +install-data-am: +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: +uninstall: uninstall-recursive +all-am: Makefile $(PROGRAMS) $(SCRIPTS) config.h +all-redirect: all-recursive-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + -test -z "itbl-lexlconfig/m68k-parsehconfig/m68k-parsecitbl-parsehitbl-parsec" || rm -f itbl-lexl config/m68k-parseh config/m68k-parsec itbl-parseh itbl-parsec +mostlyclean-am: mostlyclean-hdr mostlyclean-noinstPROGRAMS \ + mostlyclean-compile mostlyclean-libtool \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-hdr clean-noinstPROGRAMS clean-compile clean-libtool \ + clean-tags clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-hdr distclean-noinstPROGRAMS distclean-compile \ + distclean-libtool distclean-tags distclean-generic \ + clean-am + -rm -f libtool + +distclean: distclean-recursive + -rm -f config.status + +maintainer-clean-am: maintainer-clean-hdr \ + maintainer-clean-noinstPROGRAMS \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + -rm -f config.status + +.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ +mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \ +clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool install-data-recursive \ +uninstall-data-recursive install-exec-recursive \ +uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ +all-recursive check-recursive installcheck-recursive info-recursive \ +dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir check-DEJAGNU \ +info-am info dvi-am dvi check check-am installcheck-am installcheck \ +install-info-am install-info all-recursive-am install-exec-local \ +install-exec-am install-exec install-data-am install-data install-am \ +install uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + +po/POTFILES.in: @MAINT@ Makefile + for file in $(POTFILES); do echo $$file; done | 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: $(DISTSTUFF) 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): config.h as.h $(TARG_ENV_H) $(OBJ_FORMAT_H) $(TARG_CPU_H) flonum.h \ + expr.h struc-symbol.h write.h frags.h hash.h read.h symbols.h tc.h \ + obj.h listing.h bignum.h bit_fix.h $(INCDIR)/libiberty.h asintl.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) $(TARG_CPU_DEP_@target_cpu_type@) + $(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-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 + +# 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-test-ops.o: $(srcdir)/itbl-ops.c $(srcdir)/itbl-ops.h itbl-parse.h + $(COMPILE) -o itbl-test-ops.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) $(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 $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +install-exec-tooldir: $(noinst_PROGRAMS) + $(mkinstalldirs) $(tooldir)/bin + n=`echo as | sed '$(transform)'`; \ + if [ "$(bindir)/$$n$(EXEEXT)" != "$(tooldir)/bin/as$(EXEEXT)" ]; then \ + rm -f $(tooldir)/bin/as$(EXEEXT); \ + ln $(bindir)/$$n$(EXEEXT) $(tooldir)/bin/as$(EXEEXT) >/dev/null 2>/dev/null \ + || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) as-new$(EXEEXT) $(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 + +.dep: dep.sed $(DEP_FILE_DEPS) .tcdep .objdep .dep2 + rm -f .dep1 + srcdir=`cd $(srcdir); pwd`; \ + $(MAKE) DEP=$(DEP) srcdir=$${srcdir} VPATH=$${srcdir} .dep1 + rm -rf .depdir + sed -f dep.sed < .dep1 > .depa + sed -f dep.sed < .tcdep >> .depa + sed -f dep.sed < .objdep >> .depa + sed -f dep.sed < .dep2 >> .depa + echo '$$(OBJS): $$(DEP_@target''_cpu_type@_@obj''_format@)' >> .depa + echo '$$(TARG_CPU_O): $$(TCDEP_@target''_cpu_type@_@obj''_format@)' >> .depa + echo '$$(OBJ_FORMAT_O): $$(OBJDEP_@target''_cpu_type@_@obj''_format@)' >> .depa + echo '# IF YOU PUT ANYTHING HERE IT WILL GO AWAY' >> .depa + $(SHELL) $(srcdir)/../move-if-change .depa .dep + +# This rule needs a mkdep that runs "gcc -MM". +.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 '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep; \ + $(DEP) -f .dep -DBFD_ASSEMBLER -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES) $? + sed -e '/IF YOU PUT ANYTHING/,$$d' < .depdir/.dep > .dep1 + rm -f .depdir/.dep + +# Work out the special dependencies for the tc-*.c files. +.tcdep: $(TARGET_CPU_CFILES) + rm -f .tcdepa + 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 '#include "opcodes/'"$${c}"'-desc.h"' > cgen-desc.h; \ + rm -f dummy.c; \ + cp $${srcdir}/config/tc-$${c}.c dummy.c; \ + echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep; \ + $(DEP) -f .dep -DBFD_ASSEMBLER -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES) dummy.c; \ + sed -e "s/dummy.o: dummy.c/TCDEP_$${c}_$${o} =/" \ + -e '1,/DO NOT PUT ANYTHING AFTER/d' \ + -e '/IF YOU PUT ANYTHING/,$$d' \ + -e '/^$$/d' < .dep >> ../.tcdepa; \ + rm -f dummy.c; \ + else true; fi; \ + done; \ + done + echo 'TCDEP_hppa_som = $$(srcdir)/config/tc-hppa.h subsegs.h \' >> .tcdepa + echo ' $$(INCDIR)/obstack.h $$(BFDDIR)/libhppa.h \' >> .tcdepa + echo ' $$(INCDIR)/opcode/hppa.h $$(BFDDIR)/som.h' >> .tcdepa + # We don't try to handle all multi cases. + for c in $(CPU_TYPES); do \ + $(CPU_MULTI_VALID) \ + if [ x$${valid} = xyes ]; then \ + o=ecoff; \ + $(CPU_OBJ_VALID) \ + echo 'TCDEP_'"$${c}"'_multi = \' >> .tcdepa; \ + echo '$$(TCDEP_'"$${c}"'_coff) \' >> .tcdepa; \ + if [ x$${valid} = xyes ]; then \ + echo '$$(TCDEP_'"$${c}"'_ecoff) \' >> .tcdepa; \ + else true; fi; \ + echo '$$(TCDEP_'"$${c}"'_elf)' >> .tcdepa; \ + else true; fi; \ + done + mv -f .tcdepa .tcdep + +# Work out the special dependencies for the obj-*.c files. +.objdep: $(OBJ_FORMAT_CFILES) + rm -f .objdepa + 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; \ + rm -f dummy.c; \ + cp $${srcdir}/config/obj-$${o}.c dummy.c; \ + echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep; \ + $(DEP) -f .dep -DBFD_ASSEMBLER -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES) dummy.c; \ + sed -e "s/dummy.o: dummy.c/OBJDEP_$${c}_$${o} =/" \ + -e '1,/DO NOT PUT ANYTHING AFTER/d' \ + -e '/IF YOU PUT ANYTHING/,$$d' \ + -e '/^$$/d' < .dep >> ../.objdepa; \ + rm -f dummy.c; \ + else true; fi; \ + done; \ + done + echo 'OBJDEP_hppa_som = $$(srcdir)/config/obj-som.h subsegs.h \' >> .objdepa + echo ' $$(INCDIR)/obstack.h $$(BFDDIR)/libhppa.h \' >> .objdepa + echo ' $$(BFDDIR)/som.h $$(INCDIR)/aout/stab_gnu.h \' >> .objdepa + echo ' $$(INCDIR)/aout/stab.def' >> .objdepa + # We don't try to handle all multi cases. + for c in $(CPU_TYPES); do \ + $(CPU_MULTI_VALID) \ + if [ x$${valid} = xyes ]; then \ + o=ecoff; \ + $(CPU_OBJ_VALID) \ + echo 'OBJDEP_'"$${c}"'_multi = \' >> .objdepa; \ + echo '$$(OBJDEP_'"$${c}"'_coff) \' >> .objdepa; \ + if [ x$${valid} = xyes ]; then \ + echo '$$(OBJDEP_'"$${c}"'_ecoff) \' >> .objdepa; \ + else true; fi; \ + echo '$$(OBJDEP_'"$${c}"'_elf)' >> .objdepa; \ + else true; fi; \ + done + mv -f .objdepa .objdep + +# 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; \ + echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep; \ + $(DEP) -f .dep -DBFD_ASSEMBLER -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES) dummy.c; \ + sed -e "s/dummy.o: dummy.c/DEP_$${c}_$${o} =/" \ + -e '1,/DO NOT PUT ANYTHING AFTER/d' \ + -e '/IF YOU PUT ANYTHING/,$$d' \ + -e '/^$$/d' < .dep >> ../.dep2a; \ + else true; fi; \ + done; \ + done + echo 'DEP_hppa_som = $$(BFDDIR)/som.h' >> .dep2a + # We don't try to handle all multi cases. + for c in $(CPU_TYPES); do \ + $(CPU_MULTI_VALID) \ + if [ x$${valid} = xyes ]; then \ + o=ecoff; \ + $(CPU_OBJ_VALID) \ + echo 'DEP_'"$${c}"'_multi = \' >> .dep2a; \ + echo '$$(DEP_'"$${c}"'_coff) \' >> .dep2a; \ + if [ x$${valid} = xyes ]; then \ + echo '$$(DEP_'"$${c}"'_ecoff) \' >> .dep2a; \ + else true; fi; \ + echo '$$(DEP_'"$${c}"'_elf)' >> .dep2a; \ + else true; fi; \ + 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}!" + +dep: .dep + sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile + cat .dep >> tmp-Makefile + $(SHELL) $(srcdir)/../move-if-change tmp-Makefile Makefile + +dep-in: .dep + sed -e '/^..DO NOT DELETE THIS LINE/,$$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 '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am + cat .dep >> tmp-Makefile.am + $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am + +.PHONY: dep dep-in dep-am + +# DO NOT DELETE THIS LINE -- mkdep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +app.o: app.c +as.o: as.c subsegs.h $(INCDIR)/obstack.h output-file.h \ + sb.h macro.h +atof-generic.o: atof-generic.c +bignum-copy.o: bignum-copy.c +cond.o: cond.c macro.h sb.h $(INCDIR)/obstack.h +depend.o: depend.c +ecoff.o: ecoff.c +ehopt.o: ehopt.c subsegs.h $(INCDIR)/obstack.h $(INCDIR)/elf/dwarf2.h +expr.o: expr.c $(INCDIR)/obstack.h +flonum-copy.o: flonum-copy.c +flonum-konst.o: flonum-konst.c +flonum-mult.o: flonum-mult.c +frags.o: frags.c subsegs.h $(INCDIR)/obstack.h +hash.o: hash.c +input-file.o: input-file.c input-file.h +input-scrub.o: input-scrub.c input-file.h sb.h +listing.o: listing.c input-file.h subsegs.h +literal.o: literal.c subsegs.h $(INCDIR)/obstack.h +macro.o: macro.c sb.h macro.h +messages.o: messages.c +output-file.o: output-file.c output-file.h +read.o: read.c subsegs.h $(INCDIR)/obstack.h sb.h macro.h \ + ecoff.h +sb.o: sb.c sb.h +stabs.o: stabs.c $(INCDIR)/obstack.h subsegs.h ecoff.h \ + $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def +subsegs.o: subsegs.c subsegs.h $(INCDIR)/obstack.h +symbols.o: symbols.c $(INCDIR)/obstack.h subsegs.h +write.o: write.c subsegs.h $(INCDIR)/obstack.h output-file.h +gasp.o: gasp.c sb.h macro.h +e-i386coff.o: $(srcdir)/config/e-i386coff.c emul.h \ + emul-target.h +e-i386elf.o: $(srcdir)/config/e-i386elf.c emul.h emul-target.h +e-mipsecoff.o: $(srcdir)/config/e-mipsecoff.c emul.h \ + emul-target.h +e-mipself.o: $(srcdir)/config/e-mipself.c emul.h emul-target.h +$(OBJS): $(DEP_@target_cpu_type@_@obj_format@) +$(TARG_CPU_O): $(TCDEP_@target_cpu_type@_@obj_format@) +$(OBJ_FORMAT_O): $(OBJDEP_@target_cpu_type@_@obj_format@) +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY + +# 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/gas/NEWS b/gas/NEWS new file mode 100644 index 0000000000..0844076352 --- /dev/null +++ b/gas/NEWS @@ -0,0 +1,287 @@ +-*- text -*- + +Changes in 2.10: + +Support for the Motorolla MCore 210 processor 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. + +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. + +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/gas/README b/gas/README new file mode 100644 index 0000000000..4ac27db82f --- /dev/null +++ b/gas/README @@ -0,0 +1,274 @@ + 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 +standalone `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 targetted for +most of the above hosts, plus + + 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, m88k 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-gnu-utils@gnu.org. They may be +cross-posted to bug-gcc if they affect the use of gas with gcc. They +should not be reported just to bug-gcc, since I don't read that list, +and therefore wouldn't see them. + +If you report a bug in GAS, please remember to include: + +A description of exactly what went wrong, and exactly what should have +happened instead. + +The type of machine (VAX, 68020, etc) and operating system (BSD, SunOS, DYNIX, +VMS, etc) GAS was running on. + +The configuration name(s) given to the "configure" script. The +"config.status" file should have this information. + +The options given to GAS at run time. + +The actual input file that caused the problem. + +It is silly to report a bug in GAS without including an input file for GAS. +Don't ask us to generate the file just because you made it from files you +think we have access to. + +1. You might be mistaken. +2. It might take us a lot of time to install things to regenerate that file. +3. We might get a different file from the one you got, and might not see any + bug. + +To save us these delays and uncertainties, always send the input file for the +program that failed. A smaller test case that demonstrates the problem is of +course preferable, but be sure it is a complete input file, and that it really +does demonstrate the problem; but if paring it down would cause large delays +in filing the bug report, don't bother. + +If the input file is very large, and you are on the internet, you may want to +make it avaliable for anonymous FTP instead of mailing it. If you do, include +instructions for FTP'ing it in your bug report. + +If you expect to be contributing a large number of test cases, it would be +helpful if you would look at the test suite included in the release (based on +the Deja Gnu testing framework, available from the usual ftp sites) and write +test cases to fit into that framework. This is certainly not required. diff --git a/gas/README-vms b/gas/README-vms new file mode 100644 index 0000000000..796c603b4f --- /dev/null +++ b/gas/README-vms @@ -0,0 +1,248 @@ + This document explains a couple of things that are specific to VMS. +There are currently two "chapters", the first deals with cross-assembly +issues, and the second deals with the VMS debugger and GNU-CC. + + +*********************************************************************** +****************** Notes for Cross Assembly with VMS ****************** +*********************************************************************** + + If you wish to build gas on a non-VMS system to cross-assemble, +you should use: + +configure ${hosttype} -target=vms + +and then follow the usual procedure. The object files generated on +Unix will be correct from a binary point of view, but the real trick is +getting them to the VMS machine. The format of the object file is +a variable-length record, but each record contains binary data. gas +writes the records in the same format that VMS would expect, +namely a two-byte count followed by that number of bytes. + + If you try to copy the file to a VMS system using ftp, the ftp +protocol will screw up the file by looking for nulls (record terminator for +unix) and it will insert it's own record terminators at that point. This +will obviously corrupt the file. + + If you try to transfer the file with ftp in binary mode, the +file itself will not be corrupt, but VMS will think that the file contains +fixed-length records of 512 bytes. You can use the public-domain FILE +utility to change this with a command like: + +$FILE foo.o/type=variable + +If you do not have this utility available, the following program can be +used to perform this task: + + #include + + #define RME$C_SETRFM 1 + + struct FAB * fab; + + main(int argc, char * argv[]){ + int i, status; + fab = (struct FAB*) malloc(sizeof(struct FAB)); + *fab = cc$rms_fab; /* initialize FAB*/ + fab->fab$b_fac = FAB$M_PUT; + fab->fab$l_fop |= FAB$M_ESC; + fab->fab$l_ctx = RME$C_SETRFM; + fab->fab$w_ifi = 0; + for(i=1;ifab$l_fna = argv[i]; + fab->fab$b_fns = strlen(argv[i]); + status = sys$open(fab,0,0); + if((status & 7) != 1) lib$signal(status); + fab->fab$b_rfm = FAB$C_VAR; + status = sys$modify(fab,0,0); + if((status & 7) != 1) lib$signal(status); + status = sys$close(fab,0,0); + if((status & 7) != 1) lib$signal(status); + }; + } + + If you have NFS running on the VMS system, what you need to do +depends upon which NFS software you are running on the VMS system. There +are a number of different TCP/IP packages for VMS available, and only very +limited testing has been performed. In the tests that has been done so +far, the contents of the file will always be correct when transferring the +file via NFS, but the record attributes may or may not be correct. + + One proprietary TCP/IP/NFS package for VMS is known to +automatically fix the record attributes of the object file if you NFS mount +a unix disk from the VMS system, and if the file has a ".obj" extension on +the unix system. Other TCP/IP packages might do this for you as well, but +they have not been checked. + +No matter what method you use to get the file to the VMS system, it is +always a good idea to check to make sure that it is the correct type by +doing a "$dir/full" on the object file. The desired record attributes will +be "None". Undesirable record attributes will be "Stream-LF" or anything +else. + +Once you get the files on the VMS system, you can check their integrity +with the "$anal/obj" command. (Naturally at some point you should rename +the .o files to .obj). As far as the debugger is concerned, the records +will be correct, but the debugger will not be able to find the source files, +since it only has the file name, and not the full directory specification. +You must give the debugger some help by telling it which directories to +search for the individual files - once you have done this you should be +able to proceed normally. + + It is a good idea to use names for your files which will be valid +under VMS, since otherwise you will have no way of getting the debugger to +find the source file when deugging. + +The reason for this is that the object file normally contins specific +information that the debugger can use to positively identify a file, and if +you are assembling on a unix system this information simply does not exist +in a meaningful way. You must help the debugger by using the "SET FILE=" +command to tell the debugger where to look for source files. The debugger +records will be correct, except that the debugger will not be initially +able to find the source files. You can use the "SET FILE" command to tell +the debugger where to look for the source files. + +I have only tested this with a SVr4 i486 machine, and everything seems to +work OK, with the limited testing that I have done. Other machines may +or may not work. You should read the chapters on cross-compilers in the gcc +manual before fooling with this. Since gas does not need to do any floating +point arithmetic, the floating point constants that are generated here should +be correct - the only concern is with constant folding in the main compiler. +The range and precision of floats and doubles are similar on the 486 (with +a builtin 80387) and the VAX, although there is a factor of 2 to 4 +difference in the range. The double, as implemented on the 486, is quite +similar to the G_FLOAT on the VAX. + +*********************************************************************** +****************** Notes for using GNU CC with the VMS debugger******** +*********************************************************************** + + + 1) You should be aware that GNU-C, as with any other decent compiler, +will do things when optimization is turned on that you may not expect. +Sometimes intermediate results are not written to variables, if they are only +used in one place, and sometimes variables that are not used at all will not be +written to the symbol table. Also, parameters to inline functions are often +inaccessible. You can see the assembly code equivalent by using KP7 in the +debugger, and from this you can tell if in fact a variable should have the +value that you expect. You can find out if a variable lives withing a register +by doing a 'show symbol/addr'. + + 2) Overly complex data types, such as: + +int (*(*(*(*(*(* sarr6)[1])[1])[2])[3])[4])[5]; + +will not be debugged properly, since the debugging record overflows an internal +debugger buffer. gcc-as will convert these to *void as far as the debugger +symbol table is concerned, which will avoid any problems, and the assembler +will give you a message informing you that this has happened. + + 3) You must, of course, compile and link with /debug. If you link +without debug, you still get traceback table in the executable, but there is no +symbol table for variables. + + 4) Included in the patches to VMS.C are fixes to two bugs that are +unrelated to the changes that I have made. One of these made it impossible to +debug small programs sometimes, and the other caused the debugger to become +confused about which routine it was in, and give this incorrect info in +tracebacks. + + 5) If you are using the GNU-C++ compiler, you should modify the +compiler driver file GNU_CC:[000000]GCC.COM (or GXX.COM). If you have a +seperate GXX.COM, then you need to change one line in GXX.COM to: +$ if f$locate("D",p2) .ne. P2_Length then Debug = " ""-G0""" + Notice zero---> ^ +If you are using a GCC.COM that does both C and C++, add the following lines to +GCC.COM: + +$! +$! Use old style debugging records for VMS +$! +$ if (Debug.nes."" ).and. Plus then Debug = " ""-G0""" + +after the variables Plus and Debug are set. The reason for this, is that C++ +compiler by default generates debugging records that are more complex, +with many new syntactical elements that allow for the new features of the +language. The -G0 switch tells the C++ compiler to use the old style debugging +records. Until the debugger understands C++ there is not any point to try and +use the expanded syntax. + + 6) When you have nested scopes, i.e.: +main(){ + int i; + {int i; + {int i; +};};} +and you say "EXAM i" the debugger needs to figure out which variable you +actually want to reference. I have arranged things to define a block to the +debugger when you use brackets to enter a new scope, so in the example above, +the variables would be described as: +TEST\main\i +TEST\main\$0\i +TEST\main\$0\$0\i +At each level, the block name is a number with a dollar sign prefix, the +numbers start with 0 and count upward. When you say EXAM i, the debugger looks +at the current PC, and decides which block it is currently in. It works from +the innermost level outward until it finds a block that has the variable "i" +defined. You can always specify the scope explicitly. + + 7) With C++, there can be a lot of inline functions, and it would be +rather restrictive to force the user to debug the program by converting all of +the inline functions to normal functions. What I have done is to essentially +"add" (with the debugger) source lines from the include files that contain the +inline functions. Thus when you step into an inline function it appears as if +you have called the function, and you can examine variables and so forth. +There are several *very* important differences, however. First of all, since +there is no function call involved, you cannot step over the inline function +call - you always step into it. Secondly, since the same source lines are used +in many locations, there is a seperate copy of the source for *each* usage. +Without this, breakpoints do not work, since we must have a 1-to-1 mapping +between source lines and PC. + Since you cannot step over inline function calls, it can be a real pain +if you are not really interested in what is going on for that function call. +What I have done is to use the "-D" switch for the assembler to toggle the +following behavior. With the "-D" switch, all inline functions are included in +the object file, and you can debug everything. Without the "-D" switch +(default case with VMS implementation), inline functions are included *only* if +they did not come from system header files (i.e. from GNU_CC_INCLUDE: or +GNU_GXX_INCLUDE:). Thus, without the switch the user only debugs his/her own +inline functions, and not the system ones. (This is especially useful if you do +a lot of stream I/O in C++). This probably will not provide enough granularity +for many users, but for now this is still somewhat experimental, and I would +like to reflect upon it and get some feedback before I go any further. +Possible solutions include an interactive prompting, a logical name, or a new +command line option in gcc.c (which is then passed through somehow to the guts +of the assembler). + The inline functions from header files appear after the source code +for the source file. This has the advantage that the source file itself is +numbered with the same line numbers that you get with an editor. In addition, +the entire header file is not included, since the assembler makes a list of +the min and max source lines that are used, and only includes those lines from +the first to the last actually used. (It is easy to change it to include the +whole file). + + 8) When you are debugging C++ objects, the object "this" is refered to +as "$this". Actually, the compiler writes it as ".this", but the period is +not good for the debugger, so I have a routine to convert it to a $. (It +actually converts all periods to $, but only for variables, since this was +intended to allow us to access "this". + + 9) If you use the asm("...") keyword for global symbols, you will not +be able to see that symbol with the debugger. The reason is that there are two +records for the symbol stored in the data structures of the assembler. One +contains the info such as psect number and offset, and the other one contains +the information having to do with the data type of the variable. In order to +debug as symbol, you need to be able to coorelate these records, and the only +way to do this is by name. The record with the storage attributes will take +the name used in the asm directive, and the record that specifies the data type +has the actual variable name, and thus when you use the asm directive to change +a variable name, the symbol becomes invisible. + + 10) Older versions of the compiler ( GNU-C 1.37.92 and earlier) place +global constants in the text psect. This is unfortunate, since to the linker +this appears to be an entry point. I sent a patch to the compiler to RMS, +which will generate a .const section for these variables, and patched the +assembler to put these variables into a psect just like that for normal +variables, except that they are marked NOWRT. static constants are still +placed in the text psect, since there is no need for any external access. diff --git a/gas/acinclude.m4 b/gas/acinclude.m4 new file mode 100644 index 0000000000..31a2c1632f --- /dev/null +++ b/gas/acinclude.m4 @@ -0,0 +1,56 @@ +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 +#include ], [ +/* 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 diff --git a/gas/aclocal.m4 b/gas/aclocal.m4 new file mode 100644 index 0000000000..1c6d60cb23 --- /dev/null +++ b/gas/aclocal.m4 @@ -0,0 +1,822 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4 + +dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +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 +#include ], [ +/* 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 + +# Do all the work for Automake. 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. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN(AM_INIT_AUTOMAKE, +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +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 +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN(AM_SANITY_CHECK, +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# 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 conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $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" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN(AM_MISSING_PROG, +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + + +# serial 25 AM_PROG_LIBTOOL +AC_DEFUN(AM_PROG_LIBTOOL, +[AC_REQUIRE([AM_ENABLE_SHARED])dnl +AC_REQUIRE([AM_ENABLE_STATIC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_RANLIB])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AM_PROG_LD])dnl +AC_REQUIRE([AM_PROG_NM])dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +dnl +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Check for any special flags to pass to ltconfig. +libtool_flags= +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$silent" = yes && libtool_flags="$libtool_flags --silent" +test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" + +# 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 __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + CFLAGS="$CFLAGS -belf" + ;; + +*-*-cygwin*) + AM_SYS_LIBTOOL_CYGWIN + ;; + +esac + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \ +DLLTOOL="$DLLTOOL" AS="$AS" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \ +|| AC_MSG_ERROR([libtool configure failed]) + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +# AM_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AM_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AM_ENABLE_SHARED, +[define([AM_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared[=PKGS] build shared libraries [default=>>AM_ENABLE_SHARED_DEFAULT], +changequote([, ])dnl +[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], +enable_shared=AM_ENABLE_SHARED_DEFAULT)dnl +]) + +# AM_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN(AM_DISABLE_SHARED, +[AM_ENABLE_SHARED(no)]) + +# AM_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN(AM_DISABLE_STATIC, +[AM_ENABLE_STATIC(no)]) + +# AM_ENABLE_STATIC - implement the --enable-static flag +# Usage: AM_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AM_ENABLE_STATIC, +[define([AM_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static[=PKGS] build static libraries [default=>>AM_ENABLE_STATIC_DEFAULT], +changequote([, ])dnl +[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], +enable_static=AM_ENABLE_STATIC_DEFAULT)dnl +]) + + +# AM_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN(AM_PROG_LD, +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC]) +ac_prog=ld +if test "$ac_cv_prog_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. +changequote(,)dnl + /* | [A-Za-z]:\\*) +changequote([,])dnl + 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 + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(ac_cv_path_LD, +[if test -z "$LD"; then + 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_prog"; then + ac_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 "$ac_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 + ac_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$ac_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_SUBST(LD) +AM_PROG_LD_GNU +]) + +AC_DEFUN(AM_PROG_LD_GNU, +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + ac_cv_prog_gnu_ld=yes +else + ac_cv_prog_gnu_ld=no +fi]) +]) + +# AM_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN(AM_PROG_NM, +[AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(ac_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + ac_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm; 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 + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -B" + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -p" + else + ac_cv_path_NM="$ac_dir/nm" + fi + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm +fi]) +NM="$ac_cv_path_NM" +AC_MSG_RESULT([$NM]) +AC_SUBST(NM) +]) + +# AM_SYS_LIBTOOL_CYGWIN - find tools needed on cygwin +AC_DEFUN(AM_SYS_LIBTOOL_CYGWIN, +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +AC_CHECK_TOOL(AS, as, false) +]) + +# Like AC_CONFIG_HEADER, but automatically create stamp file. + +AC_DEFUN(AM_CONFIG_HEADER, +[AC_PREREQ([2.12]) +AC_CONFIG_HEADER([$1]) +dnl When config.status generates a header, we must update the stamp-h file. +dnl This file resides in the same directory as the config header +dnl that is generated. We must strip everything past the first ":", +dnl and everything past the last "/". +AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl +ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, +<>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, +<>; do + case " <<$>>CONFIG_HEADERS " in + *" <<$>>am_file "*<<)>> + echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx + ;; + esac + am_indx=`expr "<<$>>am_indx" + 1` +done<<>>dnl>>) +changequote([,]))]) + + +dnl AM_PROG_LEX +dnl Look for flex, lex or missing, then run AC_PROG_LEX and AC_DECL_YYTEXT +AC_DEFUN(AM_PROG_LEX, +[missing_dir=ifelse([$1],,`cd $ac_aux_dir && pwd`,$1) +AC_CHECK_PROGS(LEX, flex lex, "$missing_dir/missing flex") +AC_PROG_LEX +AC_DECL_YYTEXT]) + +# This file is derived from `gettext.m4'. The difference is that the +# included macros assume Cygnus-style source and build trees. + +# Macro to add for using GNU gettext. +# Ulrich Drepper , 1995. +# +# 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. + +# serial 3 + +AC_DEFUN(CY_WITH_NLS, + [AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE(nls, + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT($USE_NLS) + AC_SUBST(USE_NLS) + + USE_INCLUDED_LIBINTL=no + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + AC_DEFINE(ENABLE_NLS, 1, [Define to 1 if NLS is requested]) + AC_MSG_CHECKING([whether included gettext is requested]) + AC_ARG_WITH(included-gettext, + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If gettext or catgets are available (in this order) we + dnl use this. Else we have to fall back to GNU NLS library. + dnl catgets is only used if permitted by option --with-catgets. + nls_cv_header_intl= + nls_cv_header_libgt= + CATOBJEXT=NONE + + AC_CHECK_HEADER(libintl.h, + [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc, + [AC_TRY_LINK([#include ], [return (int) gettext ("")], + gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)]) + + if test "$gt_cv_func_gettext_libc" != "yes"; then + AC_CHECK_LIB(intl, bindtextdomain, + [AC_CACHE_CHECK([for gettext in libintl], + gt_cv_func_gettext_libintl, + [AC_TRY_LINK([], [return (int) gettext ("")], + gt_cv_func_gettext_libintl=yes, + gt_cv_func_gettext_libintl=no)])]) + fi + + if test "$gt_cv_func_gettext_libc" = "yes" \ + || test "$gt_cv_func_gettext_libintl" = "yes"; then + AC_DEFINE(HAVE_GETTEXT, 1, + [Define as 1 if you have gettext and don't want to use GNU gettext.]) + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl + if test "$MSGFMT" != "no"; then + AC_CHECK_FUNCS(dcgettext) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr], + [CATOBJEXT=.gmo + DATADIRNAME=share], + [CATOBJEXT=.mo + DATADIRNAME=lib]) + INSTOBJEXT=.mo + fi + fi + ]) + + dnl In the standard gettext, we would now check for catgets. + dnl However, we never want to use catgets for our releases. + + if test "$CATOBJEXT" = "NONE"; then + dnl Neither gettext nor catgets in included in the C library. + dnl Fall back on GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + INTLOBJS="\$(GETTOBJS)" + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_SUBST(MSGFMT) + 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 + + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is no GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext programs is not GNU xgettext; ignore it]) + 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 + + dnl These rules are solely for the distribution goal. While doing this + dnl we only have to keep exactly one list of the available catalogs + dnl in configure.in. + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + dnl Make all variables we use known to autoconf. + AC_SUBST(USE_INCLUDED_LIBINTL) + AC_SUBST(CATALOGS) + AC_SUBST(CATOBJEXT) + AC_SUBST(DATADIRNAME) + AC_SUBST(GMOFILES) + AC_SUBST(INSTOBJEXT) + AC_SUBST(INTLDEPS) + AC_SUBST(INTLLIBS) + AC_SUBST(INTLOBJS) + AC_SUBST(POFILES) + AC_SUBST(POSUB) + ]) + +AC_DEFUN(CY_GNU_GETTEXT, + [AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_PROG_RANLIB])dnl + AC_REQUIRE([AC_ISC_POSIX])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + AC_REQUIRE([AC_C_CONST])dnl + AC_REQUIRE([AC_C_INLINE])dnl + AC_REQUIRE([AC_TYPE_OFF_T])dnl + AC_REQUIRE([AC_TYPE_SIZE_T])dnl + AC_REQUIRE([AC_FUNC_ALLOCA])dnl + AC_REQUIRE([AC_FUNC_MMAP])dnl + + AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \ +unistd.h values.h sys/param.h]) + AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \ +__argz_count __argz_stringify __argz_next]) + + if test "${ac_cv_func_stpcpy+set}" != "set"; then + AC_CHECK_FUNCS(stpcpy) + fi + if test "${ac_cv_func_stpcpy}" = "yes"; then + AC_DEFINE(HAVE_STPCPY, 1, [Define if you have the stpcpy function]) + fi + + AM_LC_MESSAGES + CY_WITH_NLS + + if test "x$CATOBJEXT" != "x"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + AC_MSG_CHECKING(for catalogs to be installed) + NEW_LINGUAS= + for lang in ${LINGUAS=$ALL_LINGUAS}; do + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac + done + LINGUAS=$NEW_LINGUAS + AC_MSG_RESULT($LINGUAS) + fi + + dnl Construct list of names of catalog files to be constructed. + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + dnl The reference to in the installed file + dnl must be resolved because we cannot expect the users of this + dnl to define HAVE_LOCALE_H. + if test $ac_cv_header_locale_h = yes; then + INCLUDE_LOCALE_H="#include " + else + INCLUDE_LOCALE_H="\ +/* The system does not provide the header . Take care yourself. */" + fi + AC_SUBST(INCLUDE_LOCALE_H) + + dnl Determine which catalog format we have (if any is needed) + dnl For now we know about two different formats: + dnl Linux libc-5 and the normal X/Open format + if test -f $srcdir/po2tbl.sed.in; then + if test "$CATOBJEXT" = ".cat"; then + AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen) + + dnl Transform the SED scripts while copying because some dumb SEDs + dnl cannot handle comments. + sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed + fi + dnl po2tbl.sed is always needed. + sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \ + $srcdir/po2tbl.sed.in > po2tbl.sed + fi + + dnl In the intl/Makefile.in we have a special dependency which makes + dnl only sense for gettext. We comment this out for non-gettext + dnl packages. + if test "$PACKAGE" = "gettext"; then + GT_NO="#NO#" + GT_YES= + else + GT_NO= + GT_YES="#YES#" + fi + AC_SUBST(GT_NO) + AC_SUBST(GT_YES) + + MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs" + AC_SUBST(MKINSTALLDIRS) + + dnl *** For now the libtool support in intl/Makefile is not for real. + l= + AC_SUBST(l) + + dnl Generate list of files to be processed by xgettext which will + dnl be included in po/Makefile. But only do this if the po directory + dnl exists in srcdir. + if test -d $srcdir/po; 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 + ]) + +# Search path for a program which passes the given test. +# Ulrich Drepper , 1996. +# +# 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. + +# serial 1 + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN(AM_PATH_PROG_WITH_TEST, +[# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + /*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in ifelse([$5], , $PATH, [$5]); do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test -n "[$]$1"; then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) + +# Check whether LC_MESSAGES is available in . +# Ulrich Drepper , 1995. +# +# 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. + +# serial 1 + +AC_DEFUN(AM_LC_MESSAGES, + [if test $ac_cv_header_locale_h = yes; then + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include ], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES, 1, + [Define if your locale.h file contains LC_MESSAGES.]) + fi + fi]) + +# Add --enable-maintainer-mode option to configure. +# From Jim Meyering + +# serial 1 + +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 +] +) + +# Define a conditional. + +AC_DEFUN(AM_CONDITIONAL, +[AC_SUBST($1_TRUE) +AC_SUBST($1_FALSE) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi]) + diff --git a/gas/app.c b/gas/app.c new file mode 100644 index 0000000000..2a8df3ace5 --- /dev/null +++ b/gas/app.c @@ -0,0 +1,1255 @@ +/* This is the Assembler Pre-Processor + Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 98, 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. */ + +/* 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 + # into a .line \n.file + pair. This needs better error-handling. */ + +#include +#include "as.h" /* For BAD_CASE() only */ + +#if (__STDC__ != 1) +#ifndef const +#define const /* empty */ +#endif +#endif + +/* 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"; + +#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 LEX_IS_DOUBLEBAR_1ST 13 +#endif +#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_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 PARAMS ((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 (m68k_mri) + int m68k_mri; +{ + const char *p; + int c; + + scrub_m68k_mri = m68k_mri; + + lex[' '] = LEX_IS_WHITESPACE; + lex['\t'] = LEX_IS_WHITESPACE; + lex['\r'] = LEX_IS_WHITESPACE; + lex['\n'] = LEX_IS_NEWLINE; + lex[';'] = LEX_IS_LINE_SEPARATOR; + lex[':'] = LEX_IS_COLON; + + if (! m68k_mri) + { + lex['"'] = LEX_IS_STRINGQUOTE; + +#ifndef TC_HPPA + 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; + } /* declare symbol characters */ + + 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; + } /* declare comment chars */ + + for (p = line_comment_chars; *p; p++) + { + lex[(unsigned char) *p] = LEX_IS_LINE_COMMENT_START; + } /* declare line comment chars */ + + for (p = line_separator_chars; *p; p++) + { + lex[(unsigned char) *p] = LEX_IS_LINE_SEPARATOR; + } /* declare line separators */ + + /* 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; + } + + 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; + } + +#ifdef TC_V850 + lex['-'] = LEX_IS_DOUBLEDASH_1ST; +#endif +#ifdef TC_M32R + 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 +} /* do_scrub_begin() */ + +/* 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 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; + int scrub_m68k_mri; + const char * mri_state; + char mri_last_ch; +#if defined TC_ARM && defined OBJ_ELF + const char * symver_state; +#endif + }; + +char * +app_push () +{ + 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; + saved->saved_input = saved_input; + saved->saved_input_len = saved_input_len; + saved->scrub_m68k_mri = scrub_m68k_mri; + 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 (arg) + 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; + saved_input = saved->saved_input; + saved_input_len = saved->saved_input_len; + scrub_m68k_mri = saved->scrub_m68k_mri; + 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); +} /* app_pop() */ + +/* @@ This assumes that \n &c are the same on host and target. This is not + necessarily true. */ +static int +process_escape (ch) + 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 (get, tostart, tolen) + int (*get) PARAMS ((char **)); + 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 TC_M32R + 13: After seeing a vertical bar, looking for a second vertical bar as a parallel expression seperator. +#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 a 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 \ + ? (free (saved_input), \ + saved_input = NULL, \ + 0) \ + : 0), \ + fromlen = (*get) (&from), \ + 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) (&from); + if (fromlen == 0) + return 0; + 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 '"': + 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; +#if defined(IGNORE_NONSTANDARD_ESCAPES) | defined(ONLY_STANDARD_ESCAPES) + default: + as_warn (_("Unknown escape '\\%c' in string: Ignored"), ch); + break; +#else /* ONLY_STANDARD_ESCAPES */ + default: + /* Accept \x as x for any x */ + break; +#endif /* ONLY_STANDARD_ESCAPES */ + + case EOF: + as_warn (_("End of file in string: '\"' inserted")); + PUT ('"'); + continue; + } + 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; + } + + /* OK, we are somewhere in states 0 through 4 or 9 through 11 */ + + /* flushchar: */ + ch = GET (); + + 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; + } + + if (IS_COMMENT (ch) + || ch == '/' + || IS_LINE_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 (flag_m68k_mri +#ifdef LABELS_WITHOUT_COLONS + || 1 +#endif + ) + 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; + } + 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: + if (state == 9 || state == 10) + state = 3; + else if (state != 3) + state = 1; + 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 thru into... */ + + case LEX_IS_LINE_SEPARATOR: + state = 0; + 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 TC_M32R + case LEX_IS_DOUBLEBAR_1ST: + ch2 = GET(); + if (ch2 != '|') + { + UNGET (ch2); + goto de_fault; + } + /* Reset back to state 1 and pretend that we are parsing a line from + just after the first white space. */ + state = 1; + PUT ('|'); + 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); + } + } /* bad hack */ + + 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 (_("EOF in Comment: Newline inserted")); + state = 0; + PUT ('\n'); + break; + } + /* Loks 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 + 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 (lex[ch] != LEX_IS_SYMBOL_COMPONENT) + state = 3; + } + else if (state == 10) + { + 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) + { + char *save; + + save = (char *) xmalloc (fromend - from); + memcpy (save, from, fromend - from); + if (saved_input != NULL) + free (saved_input); + saved_input = save; + saved_input_len = fromend - from; + } + else + { + if (saved_input != NULL) + { + free (saved_input); + saved_input = NULL; + } + } + return to - tostart; +} + +/* end of app.c */ diff --git a/gas/as.c b/gas/as.c new file mode 100644 index 0000000000..0cdd357dc7 --- /dev/null +++ b/gas/as.c @@ -0,0 +1,1010 @@ +/* as.c - GAS main program. + Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 98, 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. */ + +/* + * 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" + +#ifndef HAVE_ITBL_CPU +#define itbl_parse(itbl_file) 1 +#define itbl_init() +#endif + +#ifdef HAVE_SBRK +#ifdef NEED_DECLARATION_SBRK +extern PTR sbrk (); +#endif +#endif + +static void show_usage PARAMS ((FILE *)); +static void parse_args PARAMS ((int *, char ***)); +static void dump_statistics PARAMS ((void)); +static void perform_an_assembly_pass PARAMS ((int argc, char **argv)); +static int macro_expr PARAMS ((const char *, int, sb *, int *)); + +int listing; /* true if a listing is wanted */ + +static char *listing_filename = NULL; /* Name of listing file. */ + +/* Type of debugging to generate. */ + +enum debug_info_type debug_type = DEBUG_NONE; + +/* Maximum level of macro nesting. */ + +int max_macro_nest = 100; + +char *myname; /* argv[0] */ +#ifdef BFD_ASSEMBLER +segT reg_section, expr_section; +segT text_section, data_section, bss_section; +#endif + +/* 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; + +/* 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; +}; + +static struct defsym_list *defsyms; + +/* Keep a record of the itbl files we read in. */ + +struct itbl_file_list +{ + struct itbl_file_list *next; + char *name; +}; + +static struct itbl_file_list *itbl_files; + +void +print_version_id () +{ + 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); +#else + fprintf (stderr, _("GNU assembler version %s (%s)"), VERSION, TARGET_ALIAS); +#endif + fprintf (stderr, "\n"); +} + +static void +show_usage (stream) + 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 set listing file name (must be last sub-option)\n")); + + fprintf (stream, _("\ + -D produce assembler debugging messages\n\ + --defsym SYM=VAL define symbol SYM to given value\n\ + -f skip whitespace and comment preprocessing\n\ + --gstabs generate stabs debugging information\n\ + --help show this message and exit\n\ + -I DIR add DIR to search list for .include directives\n\ + -J don't warn about signed overflow\n\ + -K warn when differences altered for long displacements\n\ + -L,--keep-locals keep local symbols (e.g. starting with `L')\n")); + + fprintf (stream, _("\ + -M,--mri assemble in MRI compatibility mode\n\ + --MD FILE write dependency information in FILE (default none)\n\ + -nocpp ignored\n\ + -o OBJFILE name the object-file output OBJFILE (default a.out)\n\ + -R fold data section into text section\n\ + --statistics print various measured statistics from execution\n\ + --strip-local-absolute strip local absolute symbols\n\ + --traditional-format Use same format as native assembler when possible\n\ + --version print assembler version number and exit\n\ + -W suppress warnings\n\ + --itbl INSTTBL extend instruction set to include instructions\n\ + matching the specifications defined in file INSTTBL\n\ + -w ignored\n\ + -X ignored\n\ + -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\ + --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\ + --listing-rhs-width set the max width in characters of the lines from\n\ + the source file\n\ + --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); + + fprintf (stream, _("\nReport bugs to bug-gnu-utils@gnu.org\n")); +} + +#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; + +static struct emulation *const emulations[] = { EMULATIONS }; +static const int n_emulations = sizeof (emulations) / sizeof (emulations[0]); + +static void select_emulation_mode PARAMS ((int, char **)); + +static void +select_emulation_mode (argc, argv) + 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 () +{ + abort (); + return NULL; +} + +void +common_emul_init () +{ + 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 + +/* + * 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 (pargc, pargv) + int *pargc; + char ***pargv; +{ + int old_argc, new_argc; + char **old_argv, **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', 'f', 'a', ':', ':', 'D', '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; + static const struct option std_longopts[] = { +#define OPTION_HELP (OPTION_STD_BASE) + {"help", no_argument, NULL, OPTION_HELP}, + {"keep-locals", no_argument, NULL, 'L'}, + {"mri", no_argument, NULL, 'M'}, +#define OPTION_NOCPP (OPTION_STD_BASE + 1) + {"nocpp", no_argument, NULL, OPTION_NOCPP}, +#define OPTION_STATISTICS (OPTION_STD_BASE + 2) + {"statistics", no_argument, NULL, OPTION_STATISTICS}, +#define OPTION_VERSION (OPTION_STD_BASE + 3) + {"version", no_argument, NULL, OPTION_VERSION}, +#define OPTION_DUMPCONFIG (OPTION_STD_BASE + 4) + {"dump-config", no_argument, NULL, OPTION_DUMPCONFIG}, +#define OPTION_VERBOSE (OPTION_STD_BASE + 5) + {"verbose", no_argument, NULL, OPTION_VERBOSE}, +#define OPTION_EMULATION (OPTION_STD_BASE + 6) + {"emulation", required_argument, NULL, OPTION_EMULATION}, +#define OPTION_DEFSYM (OPTION_STD_BASE + 7) + {"defsym", required_argument, NULL, OPTION_DEFSYM}, +#define OPTION_INSTTBL (OPTION_STD_BASE + 8) + /* 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}, +#define OPTION_LISTING_LHS_WIDTH (OPTION_STD_BASE + 9) + {"listing-lhs-width", required_argument, NULL, OPTION_LISTING_LHS_WIDTH}, +#define OPTION_LISTING_LHS_WIDTH2 (OPTION_STD_BASE + 10) + {"listing-lhs-width", required_argument, NULL, OPTION_LISTING_LHS_WIDTH2}, +#define OPTION_LISTING_RHS_WIDTH (OPTION_STD_BASE + 11) + {"listing-rhs-width", required_argument, NULL, OPTION_LISTING_RHS_WIDTH}, +#define OPTION_LISTING_CONT_LINES (OPTION_STD_BASE + 12) + {"listing-cont-lines", required_argument, NULL, OPTION_LISTING_CONT_LINES}, +#define OPTION_DEPFILE (OPTION_STD_BASE + 13) + {"MD", required_argument, NULL, OPTION_DEPFILE}, +#define OPTION_GSTABS (OPTION_STD_BASE + 14) + {"gstabs", no_argument, NULL, OPTION_GSTABS}, +#define OPTION_STRIP_LOCAL_ABSOLUTE (OPTION_STD_BASE + 15) + {"strip-local-absolute", no_argument, NULL, OPTION_STRIP_LOCAL_ABSOLUTE}, +#define OPTION_TRADITIONAL_FORMAT (OPTION_STD_BASE + 16) + {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT} + }; + + /* Construct the option lists from the standard list and the + target dependent list. */ + shortopts = concat (std_shortopts, md_shortopts, (char *) NULL); + longopts = (struct option *) xmalloc (sizeof (std_longopts) + md_longopts_size); + memcpy (longopts, std_longopts, sizeof (std_longopts)); + memcpy ((char *) longopts + sizeof (std_longopts), + md_longopts, md_longopts_size); + + /* Make a local copy of the old argv. */ + old_argc = *pargc; + old_argv = *pargv; + + /* Initialize a new argv that contains no options. */ + new_argv = (char **) 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 explicity 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 (); + break; + } + /*FALLTHRU*/ + + 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_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. */ + printf (_("GNU assembler %s\n"), VERSION); + printf (_("Copyright 1997 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; + long 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'; + i = strtol (s, (char **) NULL, 0); + n = (struct defsym_list *) 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\n") ); + break; + } + + n = (struct itbl_file_list *) 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) + { + fprintf (stderr, _("Failed to read instruction table %s\n"), + itbl_files->name); + exit (EXIT_SUCCESS); + } + } + break; + + case OPTION_DEPFILE: + start_dependencies (optarg); + break; + + case OPTION_GSTABS: + debug_type = DEBUG_STABS; + 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 'Z': + flag_always_generate_output = 1; + break; + + case 'a': + if (optarg) + { + 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; +} + +static long start_time; + +int +main (argc, argv) + 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 + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + if (debug_memory) + { +#ifdef BFD_ASSEMBLER + extern long _bfd_chunksize; + _bfd_chunksize = 64; +#endif + 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); + + perform_an_assembly_pass (argc, argv); /* Assemble it. */ + + cond_finish_check (-1); + +#ifdef md_end + md_end (); +#endif + + 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 (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); +} + +static void +dump_statistics () +{ +#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 +} + + +/* perform_an_assembly_pass() + * + * 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 (argc, argv) + 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)); + /* @@ FIXME -- SEC_CODE seems to mean code only, rather than code possibly.*/ + bfd_set_section_flags (stdoutput, data_section, + applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)); + 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 obj_begin + obj_begin (); +#endif + + argv++; /* skip argv[0] */ + argc--; /* skip argv[0] */ + 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 (""); +} /* perform_an_assembly_pass() */ + +/* The interface between the macro code and gas expression handling. */ + +static int +macro_expr (emsg, idx, in, val) + 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; +} + +/* end of as.c */ diff --git a/gas/as.h b/gas/as.h new file mode 100644 index 0000000000..a72dfad28d --- /dev/null +++ b/gas/as.h @@ -0,0 +1,645 @@ +/* as.h - global header file + Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 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 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" + +/* 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 #undef for DJ Delorie. The right fix is to ensure that as.h + is included first, before even any system header files, in all files + that use it. KR 1994.11.03 */ +/* 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 */ + +/* AIX requires this to be the first thing in the file. */ +#ifdef __GNUC__ +# ifndef alloca +# ifdef __STDC__ +extern void *alloca (); +# else +extern char *alloca (); +# endif +# endif +#else +# if HAVE_ALLOCA_H +# include +# else +# ifdef _AIX + #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 + +/* Now, tend to the rest of the configuration. */ + +/* System include files first... */ +#include +#include +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_TYPES_H +/* for size_t, pid_t */ +#include +#endif + +#include +/* 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. + 170 gives the standard options room to grow. */ +#define OPTION_MD_BASE 170 + +#ifdef DEBUG +#undef NDEBUG +#endif +#if !defined (__GNUC__) || __GNUC_MINOR__ <= 5 +#define __PRETTY_FUNCTION__ ((char*)0) +#endif +#if 0 + +/* Handle lossage with assert.h. */ +#ifndef BROKEN_ASSERT +#include +#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 +#ifdef BFD_ASSEMBLER +#include +#endif +#include + +/* Define the standard progress macros. */ +#include + +/* 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 +#ifdef GO32 +#include "fopen-bin.h" +#else +#include "fopen-same.h" +#endif +#endif + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 +#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 elswhere */ +#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 accreting 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, + + /* 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 + }; + +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; + +/* 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; + +/* True if we are assembling in m68k MRI mode. */ +COMMON int flag_m68k_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 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; + +/* 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 + only support stabs and ECOFF. */ + +enum debug_info_type + { + DEBUG_UNSPECIFIED, + DEBUG_NONE, + DEBUG_STABS, + DEBUG_ECOFF, + DEBUG_DWARF, + DEBUG_DWARF2 + }; + +extern enum debug_info_type debug_type; + +/* Maximum level of macro nesting. */ +extern int max_macro_nest; + +/* 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) PARAMS ((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_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 PARAMS ((const char *format, ...)) +#define PRINTF_WHERE_LIKE(FCN) void FCN PARAMS ((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); +PRINTF_LIKE (as_tsktsk); +PRINTF_LIKE (as_warn); +PRINTF_WHERE_LIKE (as_bad_where); +PRINTF_WHERE_LIKE (as_warn_where); + +void as_assert PARAMS ((const char *, int, const char *)); +void as_abort PARAMS ((const char *, int, const char *)); + +void fprint_value PARAMS ((FILE *file, addressT value)); +void sprint_value PARAMS ((char *buf, addressT value)); + +int had_errors PARAMS ((void)); +int had_warnings PARAMS ((void)); + +void print_version_id PARAMS ((void)); +char *app_push PARAMS ((void)); +char *atof_ieee PARAMS ((char *str, int what_kind, LITTLENUM_TYPE * words)); +char *input_scrub_include_file PARAMS ((char *filename, char *position)); +char *input_scrub_new_file PARAMS ((char *filename)); +char *input_scrub_next_buffer PARAMS ((char **bufp)); +int do_scrub_chars PARAMS ((int (*get) (char **), char *to, int tolen)); +int gen_to_words PARAMS ((LITTLENUM_TYPE * words, int precision, + long exponent_bits)); +int had_err PARAMS ((void)); +int ignore_input PARAMS ((void)); +void cond_finish_check PARAMS ((int)); +void cond_exit_macro PARAMS ((int)); +int seen_at_least_1_file PARAMS ((void)); +void app_pop PARAMS ((char *arg)); +void as_howmuch PARAMS ((FILE * stream)); +void as_perror PARAMS ((const char *gripe, const char *filename)); +void as_where PARAMS ((char **namep, unsigned int *linep)); +void bump_line_counters PARAMS ((void)); +void do_scrub_begin PARAMS ((int)); +void input_scrub_begin PARAMS ((void)); +void input_scrub_close PARAMS ((void)); +void input_scrub_end PARAMS ((void)); +int new_logical_line PARAMS ((char *fname, int line_number)); +void subsegs_begin PARAMS ((void)); +void subseg_change PARAMS ((segT seg, int subseg)); +segT subseg_new PARAMS ((const char *name, subsegT subseg)); +segT subseg_force_new PARAMS ((const char *name, subsegT subseg)); +void subseg_set PARAMS ((segT seg, subsegT subseg)); +#ifdef BFD_ASSEMBLER +segT subseg_get PARAMS ((const char *, int)); +#endif + +void start_dependencies PARAMS ((char *)); +void register_dependency PARAMS ((char *)); +void print_dependencies PARAMS ((void)); + +struct expressionS; +struct fix; +struct symbol; +struct relax_type; +typedef struct frag fragS; + +#ifdef BFD_ASSEMBLER +/* literal.c */ +valueT add_to_literal_pool PARAMS ((struct symbol *, valueT, segT, int)); +#endif + +int check_eh_frame PARAMS ((struct expressionS *, unsigned int *)); +int eh_frame_estimate_size_before_relax PARAMS ((fragS *)); +int eh_frame_relax_frag PARAMS ((fragS *)); +void eh_frame_convert_frag PARAMS ((fragS *)); + +#include "expr.h" /* Before targ-*.h */ + +/* this one starts the chain of target dependant headers */ +#include "targ-env.h" + +#include "struc-symbol.h" +#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" + +#ifndef LOCAL_LABELS_DOLLAR +#define LOCAL_LABELS_DOLLAR 0 +#endif + +#ifndef LOCAL_LABELS_FB +#define LOCAL_LABELS_FB 0 +#endif + +#ifndef TEXT_SECTION_NAME +#define TEXT_SECTION_NAME ".text" +#define DATA_SECTION_NAME ".data" +#define BSS_SECTION_NAME ".bss" +#endif + +#endif /* GAS */ + +/* end of as.h */ diff --git a/gas/asintl.h b/gas/asintl.h new file mode 100644 index 0000000000..b733c85f0f --- /dev/null +++ b/gas/asintl.h @@ -0,0 +1,44 @@ +/* asintl.h - gas-specific header for gettext code. + Copyright (C) 1998, 1999 Free Software Foundation, Inc. + + Written by Tom Tromey + + 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 +#endif + +#ifdef ENABLE_NLS +# include +# define _(String) gettext (String) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +/* Stubs that do something close enough. */ +# define textdomain(String) (String) +# define gettext(String) (String) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +# define bindtextdomain(Domain,Directory) (Domain) +# define _(String) (String) +# define N_(String) (String) +#endif diff --git a/gas/atof-generic.c b/gas/atof-generic.c new file mode 100644 index 0000000000..316f665a45 --- /dev/null +++ b/gas/atof-generic.c @@ -0,0 +1,636 @@ +/* atof_generic.c - turn a string of digits into a Flonum + Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 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. */ + +#include +#include + +#include "as.h" + +#ifndef FALSE +#define FALSE (0) +#endif +#ifndef TRUE +#define TRUE (1) +#endif + +#ifdef TRACE +static void flonum_print PARAMS ((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: + + ::= + ::= '+' | '-' | {empty} + ::= + | + | + | + + ::= {empty} + | + + ::= | + ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' + ::= {one character from "string_of_decimal_exponent_marks"} + ::= {one character from "string_of_decimal_marks"} + + */ + +int +atof_generic (address_of_string_pointer, + string_of_decimal_marks, + string_of_decimal_exponent_marks, + address_of_generic_floating_point_number) + /* 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 ((unsigned char) 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 ((unsigned char) 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 ((unsigned char) 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 ((unsigned char) 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 sucessful, 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/gas/bignum-copy.c b/gas/bignum-copy.c new file mode 100644 index 0000000000..2bffcbfea4 --- /dev/null +++ b/gas/bignum-copy.c @@ -0,0 +1,80 @@ +/* bignum_copy.c - copy a bignum + Copyright (C) 1987, 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. */ + +#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 (in, in_length, out, out_length) + 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/gas/bignum.h b/gas/bignum.h new file mode 100644 index 0000000000..e3b2f16799 --- /dev/null +++ b/gas/bignum.h @@ -0,0 +1,52 @@ +/* bignum.h-arbitrary precision integers + 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. */ + +/***********************************************************************\ + * * + * 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 PARAMS ((LITTLENUM_TYPE * in, int in_length, + LITTLENUM_TYPE * out, int out_length)); + +/* end of bignum.h */ diff --git a/gas/bit_fix.h b/gas/bit_fix.h new file mode 100644 index 0000000000..6a729a700c --- /dev/null +++ b/gas/bit_fix.h @@ -0,0 +1,51 @@ +/* write.h + + 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. */ + +/* 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 possibillity 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 an some bitfield. ( ex: 5 bits in a short field of a 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__ */ + +/* end of bit_fix.h */ diff --git a/gas/cgen.c b/gas/cgen.c new file mode 100644 index 0000000000..3d2330e05f --- /dev/null +++ b/gas/cgen.c @@ -0,0 +1,663 @@ +/* GAS interface for targets using CGEN: Cpu tools GENerator. + Copyright (C) 1996, 1997, 1998, 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. */ + +#include +#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" + +/* 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; + 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 three functions allow a backup of the fixup chain to be made, + and to have this backup be swapped with the current chain. This allows + certain ports, eg the m32r, to swap two instructions and swap their fixups + at the same time. */ +/* ??? I think with cgen_asm_finish_insn (or something else) there is no + more need for this. */ + +static struct fixup saved_fixups [GAS_CGEN_MAX_FIXUPS]; +static int saved_num_fixups; + +void +gas_cgen_save_fixups () +{ + saved_num_fixups = num_fixups; + + memcpy (saved_fixups, fixups, sizeof (fixups[0]) * num_fixups); + + num_fixups = 0; +} + +void +gas_cgen_restore_fixups () +{ + num_fixups = saved_num_fixups; + + memcpy (fixups, saved_fixups, sizeof (fixups[0]) * num_fixups); + + saved_num_fixups = 0; +} + +void +gas_cgen_swap_fixups () +{ + int tmp; + struct fixup tmp_fixup; + + if (num_fixups == 0) + { + gas_cgen_restore_fixups (); + } + else if (saved_num_fixups == 0) + { + gas_cgen_save_fixups (); + } + else + { + tmp = saved_num_fixups; + saved_num_fixups = num_fixups; + num_fixups = tmp; + + for (tmp = GAS_CGEN_MAX_FIXUPS; tmp--;) + { + tmp_fixup = saved_fixups [tmp]; + saved_fixups [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_fix. */ + +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_fix. */ + +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; + +/* 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; + 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 = NULL; + 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) + { + input_line_pointer = (char *) hold; + * resultP_1 = CGEN_PARSE_OPERAND_RESULT_ERROR; + return "illegal operand"; + } + + expression (& exp); + + * 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; +{ + 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_RELAX)) + abort (); /* These currently shouldn't get here. */ + + /* 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; + +#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; + + 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 */, + fixups[relax_operand].exp.X_add_symbol, + fixups[relax_operand].exp.X_add_number, + 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 + + /* 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_RELAX 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. */ + +int +gas_cgen_md_apply_fix3 (fixP, valueP, seg) + fixS * fixP; + valueT * valueP; + segT seg; +{ + char * where = fixP->fx_frag->fr_literal + fixP->fx_where; + valueT value; + /* canonical name, since used a lot */ + CGEN_CPU_DESC cd = gas_cgen_cpu_desc; + + /* FIXME FIXME FIXME: The value we are passed in *valuep 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 *valuep since bfd_install_relocation is not being used. + However, if the reloc is not fully resolved we do not want to use + *valuep, and must use fx_offset instead. However, if the reloc + is PC relative, we do want to use *valuep since it includes the + result of md_pcrel_from. This is confusing. */ + + if (fixP->fx_addsy == (symbolS *) NULL) + { + value = * valueP; + fixP->fx_done = 1; + } + else if (fixP->fx_pcrel) + value = * valueP; + 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 = (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 1; + + /* 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 1; + } + } + 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; + /* FIXME: later add support for 64 bits. */ + 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; + + return 1; +} + +/* 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; + 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, + _("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); + + reloc->sym_ptr_ptr = & fixP->fx_addsy->bsym; + + /* 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; +} diff --git a/gas/cgen.h b/gas/cgen.h new file mode 100644 index 0000000000..2bc1732247 --- /dev/null +++ b/gas/cgen.h @@ -0,0 +1,94 @@ +/* GAS cgen support. + Copyright (C) 1998, 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 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. */ +#define GAS_CGEN_MAX_FIXUPS 3 + +/* 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 + PARAMS ((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 PARAMS ((void)); + +extern void gas_cgen_save_fixups PARAMS ((void)); +extern void gas_cgen_restore_fixups PARAMS ((void)); +extern void gas_cgen_swap_fixups PARAMS ((void)); + +/* 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 PARAMS ((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 PARAMS ((const CGEN_INSN *, + CGEN_INSN_BYTES_PTR, unsigned int, + int, finished_insnS *)); + +/* Record a fixup. */ +extern fixS * gas_cgen_record_fixup PARAMS ((fragS *, int, const CGEN_INSN *, + int, const CGEN_OPERAND *, int, + symbolS *, offsetT)); +extern fixS * gas_cgen_record_fixup_exp PARAMS ((fragS *, int, const CGEN_INSN *, + int, const CGEN_OPERAND *, int, + expressionS *)); + +/* md_apply_fix3 handler */ +extern int gas_cgen_md_apply_fix3 PARAMS ((fixS *, valueT *, segT)); + +/* tc_gen_reloc handler */ +extern arelent *gas_cgen_tc_gen_reloc PARAMS ((asection *, fixS *)); + +/* Target supplied routine to lookup a reloc. */ +extern bfd_reloc_code_real_type +md_cgen_lookup_reloc PARAMS ((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 PARAMS ((fragS *, int, const CGEN_INSN *, int, + const CGEN_OPERAND *, int, + expressionS *)); + +#endif /* GAS_CGEN_H */ diff --git a/gas/cond.c b/gas/cond.c new file mode 100644 index 0000000000..71a2a8e7d1 --- /dev/null +++ b/gas/cond.c @@ -0,0 +1,461 @@ +/* cond.c - conditional assembly pseudo-ops, and .include + Copyright (C) 1990, 91, 92, 93, 95, 96, 97, 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. */ + +#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. */ + int dead_tree; + /* Macro nesting level at which this conditional was created. */ + int macro_nest; +}; + +static void initialize_cframe PARAMS ((struct conditional_frame *cframe)); +static char *get_mri_string PARAMS ((int, int *)); + +static struct conditional_frame *current_cframe = NULL; + +void +s_ifdef (arg) + int arg; +{ + register char *name; /* points to name of symbol */ + register struct symbol *symbolP; /* Points to symbol */ + struct conditional_frame cframe; + + SKIP_WHITESPACE (); /* Leading whitespace is part of operand. */ + name = input_line_pointer; + + if (!is_name_beginner (*name)) + { + as_bad (_("invalid identifier for \".ifdef\"")); + obstack_1grow (&cond_obstack, 0); + ignore_rest_of_line (); + } + else + { + char c; + + c = get_symbol_end (); + symbolP = symbol_find (name); + *input_line_pointer = c; + + initialize_cframe (&cframe); + cframe.ignoring = cframe.dead_tree || !((symbolP != 0) ^ 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 (); + } /* if a valid identifyer name */ +} /* s_ifdef() */ + +void +s_if (arg) + int arg; +{ + expressionS operand; + struct conditional_frame cframe; + int t; + char *stop = NULL; + char stopc; + + if (flag_mri) + stop = mri_comment_field (&stopc); + + SKIP_WHITESPACE (); /* Leading whitespace is part of operand. */ + + 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 (); +} /* s_if() */ + +/* Get a string for the MRI IFC or IFNC pseudo-ops. */ + +static char * +get_mri_string (terminator, len) + 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 (arg) + 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_endif (arg) + int arg; +{ + 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 (); +} /* s_endif() */ + +void +s_else (arg) + int arg; +{ + if (current_cframe == NULL) + { + as_bad (_(".else without matching .if - ignored")); + + } + else if (current_cframe->else_seen) + { + as_bad (_("duplicate \"else\" - ignored")); + 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 (¤t_cframe->else_file_line.file, + ¤t_cframe->else_file_line.line); + + if (!current_cframe->dead_tree) + { + current_cframe->ignoring = !current_cframe->ignoring; + if (LISTING_SKIP_COND ()) + { + if (! current_cframe->ignoring) + listing_list (1); + else + listing_list (2); + } + } /* if not a dead tree */ + + current_cframe->else_seen = 1; + } /* if error else do it */ + + if (flag_mri) + { + while (! is_end_of_line[(unsigned char) *input_line_pointer]) + ++input_line_pointer; + } + + demand_empty_rest_of_line (); +} /* s_else() */ + +void +s_ifeqs (arg) + 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 (); +} /* s_ifeqs() */ + +int +ignore_input () +{ + char *s; + + s = input_line_pointer; + + if (flag_m68k_mri +#ifdef NO_PSEUDO_DOT + || 1 +#endif + ) + { + 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); +} /* ignore_input() */ + +static void +initialize_cframe (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 (nest) + 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 (nest) + 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); + } +} + +/* end of cond.c */ diff --git a/gas/config-gas.com b/gas/config-gas.com new file mode 100644 index 0000000000..cf5248af5d --- /dev/null +++ b/gas/config-gas.com @@ -0,0 +1,186 @@ +$!config-gas.com +$! This file sets things up to build gas on a VMS system to generate object +$! files for a VMS system. We do not use the configure script, since we +$! do not have /bin/sh to execute it. +$! +$! +$ gas_host="vms" +$ arch_indx = 1 + ((f$getsyi("CPU").ge.128).and.1) ! vax==1, alpha==2 +$ arch = f$element(arch_indx,"|","|VAX|Alpha|") +$ if arch.eqs."VAX" +$ then +$ cpu_type="vax" +$ obj_format="vms" +$ atof="vax" +$ else +$ cpu_type="alpha" +$ obj_format="evax" +$ atof="ieee" +$ endif +$ emulation="generic" +$! +$ DELETE = "delete/noConfirm" +$ ECHO = "write sys$output" +$! +$! Target specific information +$ call make "targ-cpu.h" "[.config]tc-''cpu_type'.h" +$ call make "targ-env.h" "[.config]te-''emulation'.h" +$! +$! Code to handle the object file format. +$ call make "obj-format.h" "[.config]obj-''obj_format'.h" +$! +$! (not currently used for vax or alpha) +$ call make "itbl-cpu.h" "[.config]itbl-''cpu_type'.h" +$! +$! +$! Create the file version.opt, which helps identify the executable. +$! +$if f$trnlnm("IFILE$").nes."" then close/noLog ifile$ +$search CONFIGURE.IN "AM_INIT_AUTOMAKE"/Exact/Output=config-gas-tmp.tmp +$open ifile$ config-gas-tmp.tmp +$read ifile$ line +$close ifile$ +$DELETE config-gas-tmp.tmp;* +$! Discard "AM_INIT_AUTOMAKE(gas, " and ")" parts. +$ijk=f$locate(",",line)+2 +$line=f$extract(ijk,f$length(line)-ijk,line) +$ijk=f$locate(")",line) +$line=f$extract(0,ijk,line) +$! +$ if f$search("version.opt").nes."" then DELETE version.opt;* +$copy _NL: version.opt +$open/Append ifile$ version.opt +$write ifile$ "identification="+""""+line+"""" +$close ifile$ +$! +$! Now write config.h. +$! +$ if f$search("config.h").nes."" then DELETE config.h;* +$copy _NL: config.h +$open/Append ifile$ config.h +$write ifile$ "/* config.h. Generated by config-gas.com. */ +$write ifile$ "#ifndef VERSION" +$write ifile$ "#define VERSION """,line,"""" +$write ifile$ "#endif" +$write ifile$ "/*--*/" +$if arch .eqs. "VAX" +$then +$append [.config]vms-conf.h ifile$: +$else +$ append [.config]vms-a-conf.h ifile$: +$endif +$close ifile$ +$ECHO "Created config.h." +$! +$! Check for, and possibly make, header file . +$! +$ if f$search("tmp-chk-h.*").nes."" then DELETE tmp-chk-h.*;* +$!can't use simple `#include HDR' with `gcc /Define="HDR="' +$!because the 2.6.[0-3] preprocessor handles it wrong (VMS-specific gcc bug) +$ create tmp-chk-h.c +int tmp_chk_h; /* guarantee non-empty output */ +#ifdef HAVE_STDIO_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_UNIXIO_H +#include +#endif +#ifdef HAVE_UNIXLIB_H +#include +#endif +$ on warning then continue +$ CHECK = "call tmp_chk_h" +$ CHECK "HAVE_STDIO_H" +$ if .not.$status +$ then type sys$input: + +? could not compile . + + If you're compiling with DEC C or VAX C, create config.status as an + empty file and start gnu make again. + + If you're compiling with GNU C, there is some setup problem and + gas configuration cannot proceed. + +$ DELETE tmp-chk-h.c;* +$ exit %x002C +$ endif +$! +$ CHECK "HAVE_UNISTD_H" +$ if .not.$status +$ then +$ if f$trnlnm("HFILE$").nes."" then close/noLog hfile$ +$ CHECK "HAVE_UNIXIO_H" +$ got_unixio = ($status .and. 1) +$ CHECK "HAVE_UNIXLIB_H" +$ got_unixlib = ($status .and. 1) +$ create []unistd.h !with rudimentary contents +/* substitute for building gas */ +#ifndef UNISTD_H +#define UNISTD_H + +$ open/Append hfile$ []unistd.h +$ if got_unixio +$ then write hfile$ "#include " +$ else append sys$input: hfile$: +/* some of the routines normally prototyped in */ +extern int creat(), open(), close(), read(), write(); +extern int access(), dup(), dup2(), fstat(), stat(); +extern long lseek(); +$ endif +$ write hfile$ "" +$ if got_unixlib +$ then write hfile$ "#include " +$ else append sys$input: hfile$: +/* some of the routines normally prototyped in */ +extern char *sbrk(), *getcwd(), *cuserid(); +extern int brk(), chdir(), chmod(), chown(), mkdir(); +extern unsigned getuid(), umask(); +$ endif +$ append sys$input: hfile$: + +#endif /*UNISTD_H*/ +$ close hfile$ +$ ECHO "Created ""[]unistd.h""." +$ endif !gcc '#include ' failed +$ DELETE tmp-chk-h.c;* +$ +$tmp_chk_h: subroutine +$ set noOn +$ hname = f$edit("<" + (p1 - "HAVE_" - "_H") + ".h>","LOWERCASE") +$ write sys$output "Checking for ''hname'." +$ if f$search("tmp-chk-h.obj").nes."" then DELETE tmp-chk-h.obj;* +$ define/noLog sys$error _NL: !can't use /User_Mode here due to gcc +$ define/noLog sys$output _NL: ! driver's use of multiple image activation +$ gcc /Include=([],[-.include]) /Define=("''p1'") tmp-chk-h.c +$!can't just check $status; gcc 2.6.[0-3] preprocessor doesn't set it correctly +$ ok = (($status.and.1).and.(f$search("tmp-chk-h.obj").nes."")) .or. %x10000000 +$ deassign sys$error !restore, more or less +$ deassign sys$output +$ if ok then DELETE tmp-chk-h.obj;* +$ exit ok +$ endsubroutine !tmp_chk_h +$ +$! +$! Done +$! +$ if f$search("config.status") .nes. "" then DELETE config.status;* +$ open/write cfile []config.status +$ write cfile "Links are now set up for use with a "+arch+" running VMS." +$ close cfile +$ type []config.status +$exit +$! +$! +$make: subroutine +$ if f$search(p1).nes."" then DELETE 'p1';* +$ create 'p1' +$ if f$trnlnm("IFILE$").nes."" then close/noLog ifile$ +$ open/Append ifile$ 'p1' +$ write ifile$ "#include ""''f$string(p2 - "[.config]")'""" +$ close ifile$ +$ ECHO "Created ''p1' for ''p2'." +$endsubroutine !make diff --git a/gas/config.in b/gas/config.in new file mode 100644 index 0000000000..81f2adac60 --- /dev/null +++ b/gas/config.in @@ -0,0 +1,273 @@ +/* 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 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 doesn't define. */ +#undef off_t + +/* Define if you need to in order for stat and other things to work. */ +#undef _POSIX_SOURCE + +/* Define to `unsigned' if 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 header file. */ +#undef HAVE_ARGZ_H + +/* Define if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define if you have the header file. */ +#undef HAVE_NL_TYPES_H + +/* Define if you have the header file. */ +#undef HAVE_STDARG_H + +/* Define if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define if you have the header file. */ +#undef HAVE_STRING_H + +/* Define if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if you have the header file. */ +#undef HAVE_VALUES_H + +/* Define if you have the 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 + +/* Use ELF stabs for MIPS, not ECOFF stabs */ +#undef MIPS_STABS_ELF + +/* Define if default target is PowerPC Solaris. */ +#undef TARGET_SOLARIS_COMMENT + +/* Define as 1 if big endian. */ +#undef TARGET_BYTES_BIG_ENDIAN + +/* 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/gas/config/aout_gnu.h b/gas/config/aout_gnu.h new file mode 100644 index 0000000000..badf9cb21c --- /dev/null +++ b/gas/config/aout_gnu.h @@ -0,0 +1,455 @@ +/* This file is aout_gnu.h + + 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. */ + +#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 */ + /* 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/gas/config/atof-ieee.c b/gas/config/atof-ieee.c new file mode 100644 index 0000000000..d586e3a85e --- /dev/null +++ b/gas/config/atof-ieee.c @@ -0,0 +1,696 @@ +/* atof_ieee.c - turn a Flonum into an IEEE floating point number + Copyright (C) 1987, 92, 93, 94, 95, 96, 97, 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. */ + +#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) + +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")); + words[0] = (LITTLENUM_TYPE) ((unsigned) -1) >> 1; /* Zero the leftmost bit */ + 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. */ + char 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 (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') + { + /* +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') + { + /* 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]) + { + 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; + while (lp < words_end) + *lp++ = 0; + } + } + else if ((*lp & mask[prec_bits]) != mask[prec_bits]) + *lp += 1; + } + + return return_value; + } + else if ((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 >= words); lp--) + { + carry = *lp + carry; + *lp = carry; + carry >>= LITTLENUM_NUMBER_OF_BITS; + } + 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)); + /* make_invalid_floating_point_number (words); */ + /* return return_value; */ + } + } + 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 + +/* end of atof-ieee.c */ diff --git a/gas/config/atof-tahoe.c b/gas/config/atof-tahoe.c new file mode 100644 index 0000000000..760485c5fd --- /dev/null +++ b/gas/config/atof-tahoe.c @@ -0,0 +1,431 @@ + +/* atof_tahoe.c - turn a string into a Tahoe floating point number + Copyright (C) 1987, 1998 Free Software Foundation, Inc. + */ + +/* This is really a simplified version of atof_vax.c. I glommed it wholesale + and then shaved it down. I don't even know how it works. (Don't you find + my honesty refreshing? bowen@cs.Buffalo.EDU (Devon E Bowen) + + I don't allow uppercase letters in the precision descrpitors. Ie 'f' and + 'd' are allowed but 'F' and 'D' aren't */ + +#include "as.h" + +/* Precision in LittleNums. */ +#define MAX_PRECISION (4) +#define D_PRECISION (4) +#define F_PRECISION (2) + +/* Precision in chars. */ +#define D_PRECISION_CHARS (8) +#define F_PRECISION_CHARS (4) + +/* Length in LittleNums of guard bits. */ +#define GUARD (2) + +static const long int 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_gen2tahoe and next_bits */ +static int bits_left_in_littlenum; +static LITTLENUM_TYPE *littlenum_pointer; +static LITTLENUM_TYPE *littlenum_end; + +#if __STDC__ == 1 + +int flonum_gen2tahoe (int format_letter, FLONUM_TYPE * f, LITTLENUM_TYPE * words); + +#else /* not __STDC__ */ + +int flonum_gen2tahoe (); + +#endif /* not __STDC__ */ + + +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) + char letter; /* In: lowercase please. What kind of float? */ + int *precisionP; /* Number of 16-bit words in the float. */ + long int *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; + + 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! * +* * +\***********************************************************************/ + +char * /* Return pointer past text consumed. */ +atof_tahoe (str, what_kind, words) + char *str; /* Text to convert to binary. */ + char 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 int exponent_bits; + + return_value = str; + f.low = bits + MAX_PRECISION; + f.high = NULL; + f.leader = NULL; + f.exponent = NULL; + 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_gen2tahoe (what_kind, &f, words)) + { + return_value = NULL; + } + } + } + return (return_value); +} + +/* + * In: a flonum, a Tahoe floating point format. + * Out: a Tahoe floating-point bit pattern. + */ + +int /* 0: OK. */ +flonum_gen2tahoe (format_letter, f, words) + char format_letter; /* One of 'd' 'f'. */ + FLONUM_TYPE *f; + LITTLENUM_TYPE *words; /* Deliver answer here. */ +{ + LITTLENUM_TYPE *lp; + int precision; + long int 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 int exponent_1; + long int exponent_2; + long int exponent_3; + long int 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 tahoe floating_point formats 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. + * + * So we need: number of bits of exponent, number of bits of + * mantissa. + */ + + 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 int 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); +} + +/* + * 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. + */ + +char * +md_atof (what_statement_type, literalP, sizeP) + char what_statement_type; + char *literalP; + int *sizeP; +{ + LITTLENUM_TYPE words[MAX_PRECISION]; + register char kind_of_float; + register int number_of_chars; + register LITTLENUM_TYPE *littlenum_pointer; + + switch (what_statement_type) + { + case 'f': /* .ffloat */ + case 'd': /* .dfloat */ + kind_of_float = what_statement_type; + break; + + default: + kind_of_float = 0; + break; + }; + + if (kind_of_float) + { + register LITTLENUM_TYPE *limit; + + input_line_pointer = atof_tahoe (input_line_pointer, + kind_of_float, + words); + /* + * The atof_tahoe() builds up 16-bit numbers. + * Since the assembler may not be running on + * a different-endian machine, be very careful about + * converting words to chars. + */ + number_of_chars = (kind_of_float == 'f' ? F_PRECISION_CHARS : + (kind_of_float == 'd' ? D_PRECISION_CHARS : 0)); + know (number_of_chars <= MAX_PRECISION * sizeof (LITTLENUM_TYPE)); + limit = words + (number_of_chars / sizeof (LITTLENUM_TYPE)); + for (littlenum_pointer = words; + littlenum_pointer < limit; + littlenum_pointer++) + { + md_number_to_chars (literalP, *littlenum_pointer, + sizeof (LITTLENUM_TYPE)); + literalP += sizeof (LITTLENUM_TYPE); + }; + } + else + { + number_of_chars = 0; + }; + + *sizeP = number_of_chars; + return kind_of_float ? 0 : _("Bad call to md_atof()"); +} + +/* atof_tahoe.c */ diff --git a/gas/config/atof-vax.c b/gas/config/atof-vax.c new file mode 100644 index 0000000000..45b90a8cc2 --- /dev/null +++ b/gas/config/atof-vax.c @@ -0,0 +1,517 @@ +/* atof_vax.c - turn a Flonum into a VAX floating point number + Copyright (C) 1987, 1992, 93, 95, 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. */ + +#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) + char 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 ? 0 : _("Bad call to md_atof()"); +} + +/* end of atof-vax.c */ diff --git a/gas/config/e-i386coff.c b/gas/config/e-i386coff.c new file mode 100644 index 0000000000..afed72886a --- /dev/null +++ b/gas/config/e-i386coff.c @@ -0,0 +1,17 @@ +#include "as.h" +#include "emul.h" + +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/gas/config/e-i386elf.c b/gas/config/e-i386elf.c new file mode 100644 index 0000000000..a16701e811 --- /dev/null +++ b/gas/config/e-i386elf.c @@ -0,0 +1,17 @@ +#include "as.h" +#include "emul.h" + +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/gas/config/e-mipsecoff.c b/gas/config/e-mipsecoff.c new file mode 100644 index 0000000000..be2f71b7d4 --- /dev/null +++ b/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/gas/config/e-mipself.c b/gas/config/e-mipself.c new file mode 100644 index 0000000000..eea72f5165 --- /dev/null +++ b/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/gas/config/go32.cfg b/gas/config/go32.cfg new file mode 100644 index 0000000000..4059395da8 --- /dev/null +++ b/gas/config/go32.cfg @@ -0,0 +1,93 @@ +/* config.h for go32 */ + +#define I386COFF 1 + +/* 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 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 + +/* 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. */ +#define TARGET_ALIAS "i386" +#define TARGET_CPU "i386" +#define TARGET_CANONICAL "i386-i386" +#define TARGET_OS "djgpp" +#define TARGET_VENDOR "djgpp" + +/* Some operating systems, for example DOS, require the use of "wb" mode when + opening a binary file for writing. If only "w" is used, the file will not + be correct. However, some other systems reject such a mode. This indicates + which ../include/fopen-*.h header file we want to include, so that we can + get macros that'll do the right thing for this system. */ +#define WANT_FOPEN_BIN 1 + +/* 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 errno.h doesn't declare errno itself. */ +#undef NEED_DECLARATION_ERRNO + +#define MANY_SEGMENTS 1 + +/* Needed only for sparc configuration */ +#undef sparcv9 + +/* Define if you have the remove function. */ +#define HAVE_REMOVE 1 + +/* Define if you have the unlink function. */ +#define HAVE_UNLINK 1 + +/* Define if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDARG_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +#undef HAVE_VARARGS_H diff --git a/gas/config/itbl-mips.h b/gas/config/itbl-mips.h new file mode 100644 index 0000000000..f6482bd1f7 --- /dev/null +++ b/gas/config/itbl-mips.h @@ -0,0 +1,47 @@ + +/* itbl-mips.h + + Copyright (C) 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/gas/config/m68k-parse.h b/gas/config/m68k-parse.h new file mode 100644 index 0000000000..e13134212e --- /dev/null +++ b/gas/config/m68k-parse.h @@ -0,0 +1,283 @@ +/* m68k-parse.h -- header file for m68k assembler + Copyright (C) 1987, 91, 92, 93, 94, 1995 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 M68K_PARSE_H +#define M68K_PARSE_H + +/* This header file defines things which are shared between the + operand parser in m68k.y and the m68k assembler proper in + tc-m68k.c. */ + +/* The various m68k registers. */ + +/* DATA and ADDR have to be contiguous, so that reg-DATA gives + 0-7==data reg, 8-15==addr reg for operands that take both types. + + We don't use forms like "ADDR0 = ADDR" here because this file is + likely to be used on an Apollo, and the broken Apollo compiler + gives an `undefined variable' error if we do that, according to + troy@cbme.unsw.edu.au. */ + +#define DATA DATA0 +#define ADDR ADDR0 +#define SP ADDR7 +#define BAD BAD0 +#define BAC BAC0 + +enum m68k_register +{ + DATA0 = 1, /* 1- 8 == data registers 0-7 */ + DATA1, + DATA2, + DATA3, + DATA4, + DATA5, + DATA6, + DATA7, + + ADDR0, + ADDR1, + ADDR2, + ADDR3, + ADDR4, + ADDR5, + ADDR6, + ADDR7, + + FP0, /* Eight FP registers */ + FP1, + FP2, + FP3, + FP4, + FP5, + FP6, + FP7, + + COP0, /* Co-processor #0-#7 */ + COP1, + COP2, + COP3, + COP4, + COP5, + COP6, + COP7, + + PC, /* Program counter */ + ZPC, /* Hack for Program space, but 0 addressing */ + SR, /* Status Reg */ + CCR, /* Condition code Reg */ + + /* These have to be grouped together for the movec instruction to work. */ + USP, /* User Stack Pointer */ + ISP, /* Interrupt stack pointer */ + SFC, + DFC, + CACR, + VBR, + CAAR, + MSP, + ITT0, + ITT1, + DTT0, + DTT1, + MMUSR, + TC, + SRP, + URP, + BUSCR, /* 68060 added these */ + PCR, + ROMBAR, /* mcf5200 added these */ + RAMBAR0, + RAMBAR1, + MBAR, +#define last_movec_reg MBAR + /* end of movec ordering constraints */ + + FPI, + FPS, + FPC, + + DRP, /* 68851 or 68030 MMU regs */ + CRP, + CAL, + VAL, + SCC, + AC, + BAD0, + BAD1, + BAD2, + BAD3, + BAD4, + BAD5, + BAD6, + BAD7, + BAC0, + BAC1, + BAC2, + BAC3, + BAC4, + BAC5, + BAC6, + BAC7, + PSR, /* aka MMUSR on 68030 (but not MMUSR on 68040) + and ACUSR on 68ec030 */ + PCSR, + + IC, /* instruction cache token */ + DC, /* data cache token */ + NC, /* no cache token */ + BC, /* both caches token */ + + TT0, /* 68030 access control unit regs */ + TT1, + + ZDATA0, /* suppressed data registers. */ + ZDATA1, + ZDATA2, + ZDATA3, + ZDATA4, + ZDATA5, + ZDATA6, + ZDATA7, + + ZADDR0, /* suppressed address registers. */ + ZADDR1, + ZADDR2, + ZADDR3, + ZADDR4, + ZADDR5, + ZADDR6, + ZADDR7, +}; + +/* Size information. */ + +enum m68k_size +{ + /* Unspecified. */ + SIZE_UNSPEC, + + /* Byte. */ + SIZE_BYTE, + + /* Word (2 bytes). */ + SIZE_WORD, + + /* Longword (4 bytes). */ + SIZE_LONG +}; + +/* The structure used to hold information about an index register. */ + +struct m68k_indexreg +{ + /* The index register itself. */ + enum m68k_register reg; + + /* The size to use. */ + enum m68k_size size; + + /* The value to scale by. */ + int scale; +}; + +#ifdef OBJ_ELF +/* The type of a PIC expression. */ + +enum pic_relocation +{ + pic_none, /* not pic */ + pic_plt_pcrel, /* @PLTPC */ + pic_got_pcrel, /* @GOTPC */ + pic_plt_off, /* @PLT */ + pic_got_off /* @GOT */ +}; +#endif + +/* The structure used to hold information about an expression. */ + +struct m68k_exp +{ + /* The size to use. */ + enum m68k_size size; + +#ifdef OBJ_ELF + /* The type of pic relocation if any. */ + enum pic_relocation pic_reloc; +#endif + + /* The expression itself. */ + expressionS exp; +}; + +/* The operand modes. */ + +enum m68k_operand_type +{ + IMMED = 1, + ABSL, + DREG, + AREG, + FPREG, + CONTROL, + AINDR, + AINC, + ADEC, + DISP, + BASE, + POST, + PRE, + REGLST +}; + +/* The structure used to hold a parsed operand. */ + +struct m68k_op +{ + /* The type of operand. */ + enum m68k_operand_type mode; + + /* The main register. */ + enum m68k_register reg; + + /* The register mask for mode REGLST. */ + unsigned long mask; + + /* An error message. */ + const char *error; + + /* The index register. */ + struct m68k_indexreg index; + + /* The displacement. */ + struct m68k_exp disp; + + /* The outer displacement. */ + struct m68k_exp odisp; +}; + +#endif /* ! defined (M68K_PARSE_H) */ + +/* The parsing function. */ + +extern int m68k_ip_op PARAMS ((char *, struct m68k_op *)); + +/* Whether register prefixes are optional. */ +extern int flag_reg_prefix_optional; diff --git a/gas/config/m68k-parse.y b/gas/config/m68k-parse.y new file mode 100644 index 0000000000..70a4e4fe86 --- /dev/null +++ b/gas/config/m68k-parse.y @@ -0,0 +1,1061 @@ +/* m68k.y -- bison grammar for m68k operand parsing + Copyright (C) 1995, 96, 1997, 1998 Free Software Foundation, Inc. + Written by Ken Raeburn and 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. */ + +/* This file holds a bison grammar to parse m68k operands. The m68k + has a complicated operand syntax, and gas supports two main + variations of it. Using a grammar is probably overkill, but at + least it makes clear exactly what we do support. */ + +%{ + +#include "as.h" +#include "tc-m68k.h" +#include "m68k-parse.h" + +/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, + etc), as well as gratuitiously global symbol names If other parser + generators (bison, byacc, etc) produce additional global names that + conflict at link time, then those parser generators need to be + fixed instead of adding those names to this list. */ + +#define yymaxdepth m68k_maxdepth +#define yyparse m68k_parse +#define yylex m68k_lex +#define yyerror m68k_error +#define yylval m68k_lval +#define yychar m68k_char +#define yydebug m68k_debug +#define yypact m68k_pact +#define yyr1 m68k_r1 +#define yyr2 m68k_r2 +#define yydef m68k_def +#define yychk m68k_chk +#define yypgo m68k_pgo +#define yyact m68k_act +#define yyexca m68k_exca +#define yyerrflag m68k_errflag +#define yynerrs m68k_nerrs +#define yyps m68k_ps +#define yypv m68k_pv +#define yys m68k_s +#define yy_yys m68k_yys +#define yystate m68k_state +#define yytmp m68k_tmp +#define yyv m68k_v +#define yy_yyv m68k_yyv +#define yyval m68k_val +#define yylloc m68k_lloc +#define yyreds m68k_reds /* With YYDEBUG defined */ +#define yytoks m68k_toks /* With YYDEBUG defined */ +#define yylhs m68k_yylhs +#define yylen m68k_yylen +#define yydefred m68k_yydefred +#define yydgoto m68k_yydgoto +#define yysindex m68k_yysindex +#define yyrindex m68k_yyrindex +#define yygindex m68k_yygindex +#define yytable m68k_yytable +#define yycheck m68k_yycheck + +#ifndef YYDEBUG +#define YYDEBUG 1 +#endif + +/* Internal functions. */ + +static enum m68k_register m68k_reg_parse PARAMS ((char **)); +static int yylex PARAMS ((void)); +static void yyerror PARAMS ((const char *)); + +/* The parser sets fields pointed to by this global variable. */ +static struct m68k_op *op; + +%} + +%union +{ + struct m68k_indexreg indexreg; + enum m68k_register reg; + struct m68k_exp exp; + unsigned long mask; + int onereg; +} + +%token DR AR FPR FPCR LPC ZAR ZDR LZPC CREG +%token INDEXREG +%token EXPR + +%type zireg zdireg +%type zadr zdr apc zapc zpc optzapc optczapc +%type optcexpr optexprc +%type reglist ireglist reglistpair +%type reglistreg + +%% + +/* An operand. */ + +operand: + generic_operand + | motorola_operand + | mit_operand + ; + +/* A generic operand. */ + +generic_operand: + DR + { + op->mode = DREG; + op->reg = $1; + } + | AR + { + op->mode = AREG; + op->reg = $1; + } + | FPR + { + op->mode = FPREG; + op->reg = $1; + } + | FPCR + { + op->mode = CONTROL; + op->reg = $1; + } + | CREG + { + op->mode = CONTROL; + op->reg = $1; + } + | EXPR + { + op->mode = ABSL; + op->disp = $1; + } + | '#' EXPR + { + op->mode = IMMED; + op->disp = $2; + } + | '&' EXPR + { + op->mode = IMMED; + op->disp = $2; + } + | reglist + { + op->mode = REGLST; + op->mask = $1; + } + ; + +/* An operand in Motorola syntax. This includes MRI syntax as well, + which may or may not be different in that it permits commutativity + of index and base registers, and permits an offset expression to + appear inside or outside of the parentheses. */ + +motorola_operand: + '(' AR ')' + { + op->mode = AINDR; + op->reg = $2; + } + | '(' AR ')' '+' + { + op->mode = AINC; + op->reg = $2; + } + | '-' '(' AR ')' + { + op->mode = ADEC; + op->reg = $3; + } + | '(' EXPR ',' zapc ')' + { + op->reg = $4; + op->disp = $2; + if (($4 >= ZADDR0 && $4 <= ZADDR7) + || $4 == ZPC) + op->mode = BASE; + else + op->mode = DISP; + } + | '(' zapc ',' EXPR ')' + { + op->reg = $2; + op->disp = $4; + if (($2 >= ZADDR0 && $2 <= ZADDR7) + || $2 == ZPC) + op->mode = BASE; + else + op->mode = DISP; + } + | EXPR '(' zapc ')' + { + op->reg = $3; + op->disp = $1; + if (($3 >= ZADDR0 && $3 <= ZADDR7) + || $3 == ZPC) + op->mode = BASE; + else + op->mode = DISP; + } + | '(' LPC ')' + { + op->mode = DISP; + op->reg = $2; + } + | '(' ZAR ')' + { + op->mode = BASE; + op->reg = $2; + } + | '(' LZPC ')' + { + op->mode = BASE; + op->reg = $2; + } + | '(' EXPR ',' zapc ',' zireg ')' + { + op->mode = BASE; + op->reg = $4; + op->disp = $2; + op->index = $6; + } + | '(' EXPR ',' zapc ',' zpc ')' + { + if ($4 == PC || $4 == ZPC) + yyerror (_("syntax error")); + op->mode = BASE; + op->reg = $6; + op->disp = $2; + op->index.reg = $4; + op->index.size = SIZE_UNSPEC; + op->index.scale = 1; + } + | '(' EXPR ',' zdireg optczapc ')' + { + op->mode = BASE; + op->reg = $5; + op->disp = $2; + op->index = $4; + } + | '(' zdireg ',' EXPR ')' + { + op->mode = BASE; + op->disp = $4; + op->index = $2; + } + | EXPR '(' zapc ',' zireg ')' + { + op->mode = BASE; + op->reg = $3; + op->disp = $1; + op->index = $5; + } + | '(' zapc ',' zireg ')' + { + op->mode = BASE; + op->reg = $2; + op->index = $4; + } + | EXPR '(' zapc ',' zpc ')' + { + if ($3 == PC || $3 == ZPC) + yyerror (_("syntax error")); + op->mode = BASE; + op->reg = $5; + op->disp = $1; + op->index.reg = $3; + op->index.size = SIZE_UNSPEC; + op->index.scale = 1; + } + | '(' zapc ',' zpc ')' + { + if ($2 == PC || $2 == ZPC) + yyerror (_("syntax error")); + op->mode = BASE; + op->reg = $4; + op->index.reg = $2; + op->index.size = SIZE_UNSPEC; + op->index.scale = 1; + } + | EXPR '(' zdireg optczapc ')' + { + op->mode = BASE; + op->reg = $4; + op->disp = $1; + op->index = $3; + } + | '(' zdireg optczapc ')' + { + op->mode = BASE; + op->reg = $3; + op->index = $2; + } + | '(' '[' EXPR optczapc ']' ',' zireg optcexpr ')' + { + op->mode = POST; + op->reg = $4; + op->disp = $3; + op->index = $7; + op->odisp = $8; + } + | '(' '[' EXPR optczapc ']' optcexpr ')' + { + op->mode = POST; + op->reg = $4; + op->disp = $3; + op->odisp = $6; + } + | '(' '[' zapc ']' ',' zireg optcexpr ')' + { + op->mode = POST; + op->reg = $3; + op->index = $6; + op->odisp = $7; + } + | '(' '[' zapc ']' optcexpr ')' + { + op->mode = POST; + op->reg = $3; + op->odisp = $5; + } + | '(' '[' EXPR ',' zapc ',' zireg ']' optcexpr ')' + { + op->mode = PRE; + op->reg = $5; + op->disp = $3; + op->index = $7; + op->odisp = $9; + } + | '(' '[' zapc ',' zireg ']' optcexpr ')' + { + op->mode = PRE; + op->reg = $3; + op->index = $5; + op->odisp = $7; + } + | '(' '[' EXPR ',' zapc ',' zpc ']' optcexpr ')' + { + if ($5 == PC || $5 == ZPC) + yyerror (_("syntax error")); + op->mode = PRE; + op->reg = $7; + op->disp = $3; + op->index.reg = $5; + op->index.size = SIZE_UNSPEC; + op->index.scale = 1; + op->odisp = $9; + } + | '(' '[' zapc ',' zpc ']' optcexpr ')' + { + if ($3 == PC || $3 == ZPC) + yyerror (_("syntax error")); + op->mode = PRE; + op->reg = $5; + op->index.reg = $3; + op->index.size = SIZE_UNSPEC; + op->index.scale = 1; + op->odisp = $7; + } + | '(' '[' optexprc zdireg optczapc ']' optcexpr ')' + { + op->mode = PRE; + op->reg = $5; + op->disp = $3; + op->index = $4; + op->odisp = $7; + } + ; + +/* An operand in MIT syntax. */ + +mit_operand: + optzapc '@' + { + /* We use optzapc to avoid a shift/reduce conflict. */ + if ($1 < ADDR0 || $1 > ADDR7) + yyerror (_("syntax error")); + op->mode = AINDR; + op->reg = $1; + } + | optzapc '@' '+' + { + /* We use optzapc to avoid a shift/reduce conflict. */ + if ($1 < ADDR0 || $1 > ADDR7) + yyerror (_("syntax error")); + op->mode = AINC; + op->reg = $1; + } + | optzapc '@' '-' + { + /* We use optzapc to avoid a shift/reduce conflict. */ + if ($1 < ADDR0 || $1 > ADDR7) + yyerror (_("syntax error")); + op->mode = ADEC; + op->reg = $1; + } + | optzapc '@' '(' EXPR ')' + { + op->reg = $1; + op->disp = $4; + if (($1 >= ZADDR0 && $1 <= ZADDR7) + || $1 == ZPC) + op->mode = BASE; + else + op->mode = DISP; + } + | optzapc '@' '(' optexprc zireg ')' + { + op->mode = BASE; + op->reg = $1; + op->disp = $4; + op->index = $5; + } + | optzapc '@' '(' EXPR ')' '@' '(' optexprc zireg ')' + { + op->mode = POST; + op->reg = $1; + op->disp = $4; + op->index = $9; + op->odisp = $8; + } + | optzapc '@' '(' EXPR ')' '@' '(' EXPR ')' + { + op->mode = POST; + op->reg = $1; + op->disp = $4; + op->odisp = $8; + } + | optzapc '@' '(' optexprc zireg ')' '@' '(' EXPR ')' + { + op->mode = PRE; + op->reg = $1; + op->disp = $4; + op->index = $5; + op->odisp = $9; + } + ; + +/* An index register, possibly suppressed, which need not have a size + or scale. */ + +zireg: + INDEXREG + | zadr + { + $$.reg = $1; + $$.size = SIZE_UNSPEC; + $$.scale = 1; + } + ; + +/* A register which may be an index register, but which may not be an + address register. This nonterminal is used to avoid ambiguity when + trying to parse something like (0,d5,a6) as compared to (0,a6,d5). */ + +zdireg: + INDEXREG + | zdr + { + $$.reg = $1; + $$.size = SIZE_UNSPEC; + $$.scale = 1; + } + ; + +/* An address or data register, or a suppressed address or data + register. */ + +zadr: + zdr + | AR + | ZAR + ; + +/* A data register which may be suppressed. */ + +zdr: + DR + | ZDR + ; + +/* Either an address register or the PC. */ + +apc: + AR + | LPC + ; + +/* Either an address register, or the PC, or a suppressed address + register, or a suppressed PC. */ + +zapc: + apc + | LZPC + | ZAR + ; + +/* An optional zapc. */ + +optzapc: + /* empty */ + { + $$ = ZADDR0; + } + | zapc + ; + +/* The PC, optionally suppressed. */ + +zpc: + LPC + | LZPC + ; + +/* ',' zapc when it may be omitted. */ + +optczapc: + /* empty */ + { + $$ = ZADDR0; + } + | ',' zapc + { + $$ = $2; + } + ; + +/* ',' EXPR when it may be omitted. */ + +optcexpr: + /* empty */ + { + $$.exp.X_op = O_absent; + $$.size = SIZE_UNSPEC; + } + | ',' EXPR + { + $$ = $2; + } + ; + +/* EXPR ',' when it may be omitted. */ + +optexprc: + /* empty */ + { + $$.exp.X_op = O_absent; + $$.size = SIZE_UNSPEC; + } + | EXPR ',' + { + $$ = $1; + } + ; + +/* A register list for the movem instruction. */ + +reglist: + reglistpair + | reglistpair '/' ireglist + { + $$ = $1 | $3; + } + | reglistreg '/' ireglist + { + $$ = (1 << $1) | $3; + } + ; + +/* We use ireglist when we know we are looking at a reglist, and we + can safely reduce a simple register to reglistreg. If we permitted + reglist to reduce to reglistreg, it would be ambiguous whether a + plain register were a DREG/AREG/FPREG or a REGLST. */ + +ireglist: + reglistreg + { + $$ = 1 << $1; + } + | reglistpair + | reglistpair '/' ireglist + { + $$ = $1 | $3; + } + | reglistreg '/' ireglist + { + $$ = (1 << $1) | $3; + } + ; + +reglistpair: + reglistreg '-' reglistreg + { + if ($1 <= $3) + $$ = (1 << ($3 + 1)) - 1 - ((1 << $1) - 1); + else + $$ = (1 << ($1 + 1)) - 1 - ((1 << $3) - 1); + } + ; + +reglistreg: + DR + { + $$ = $1 - DATA0; + } + | AR + { + $$ = $1 - ADDR0 + 8; + } + | FPR + { + $$ = $1 - FP0 + 16; + } + | FPCR + { + if ($1 == FPI) + $$ = 24; + else if ($1 == FPS) + $$ = 25; + else + $$ = 26; + } + ; + +%% + +/* The string to parse is stored here, and modified by yylex. */ + +static char *str; + +/* The original string pointer. */ + +static char *strorig; + +/* If *CCP could be a register, return the register number and advance + *CCP. Otherwise don't change *CCP, and return 0. */ + +static enum m68k_register +m68k_reg_parse (ccp) + register char **ccp; +{ + char *start = *ccp; + char c; + char *p; + symbolS *symbolp; + + if (flag_reg_prefix_optional) + { + if (*start == REGISTER_PREFIX) + start++; + p = start; + } + else + { + if (*start != REGISTER_PREFIX) + return 0; + p = start + 1; + } + + if (! is_name_beginner (*p)) + return 0; + + p++; + while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*') + p++; + + c = *p; + *p = 0; + symbolp = symbol_find (start); + *p = c; + + if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section) + { + *ccp = p; + return S_GET_VALUE (symbolp); + } + + /* In MRI mode, something like foo.bar can be equated to a register + name. */ + while (flag_mri && c == '.') + { + ++p; + while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*') + p++; + c = *p; + *p = '\0'; + symbolp = symbol_find (start); + *p = c; + if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section) + { + *ccp = p; + return S_GET_VALUE (symbolp); + } + } + + return 0; +} + +/* The lexer. */ + +static int +yylex () +{ + enum m68k_register reg; + char *s; + int parens; + int c = 0; + int tail = 0; + char *hold; + + if (*str == ' ') + ++str; + + if (*str == '\0') + return 0; + + /* Various special characters are just returned directly. */ + switch (*str) + { + case '@': + /* In MRI mode, this can be the start of an octal number. */ + if (flag_mri) + { + if (isdigit (str[1]) + || ((str[1] == '+' || str[1] == '-') + && isdigit (str[2]))) + break; + } + /* Fall through. */ + case '#': + case '&': + case ',': + case ')': + case '/': + case '[': + case ']': + return *str++; + case '+': + /* It so happens that a '+' can only appear at the end of an + operand. If it appears anywhere else, it must be a unary + plus on an expression. */ + if (str[1] == '\0') + return *str++; + break; + case '-': + /* A '-' can only appear in -(ar), rn-rn, or ar@-. If it + appears anywhere else, it must be a unary minus on an + expression. */ + if (str[1] == '\0') + return *str++; + s = str + 1; + if (*s == '(') + ++s; + if (m68k_reg_parse (&s) != 0) + return *str++; + break; + case '(': + /* A '(' can only appear in `(reg)', `(expr,...', `([', `@(', or + `)('. If it appears anywhere else, it must be starting an + expression. */ + if (str[1] == '[' + || (str > strorig + && (str[-1] == '@' + || str[-1] == ')'))) + return *str++; + s = str + 1; + if (m68k_reg_parse (&s) != 0) + return *str++; + /* Check for the case of '(expr,...' by scanning ahead. If we + find a comma outside of balanced parentheses, we return '('. + If we find an unbalanced right parenthesis, then presumably + the '(' really starts an expression. */ + parens = 0; + for (s = str + 1; *s != '\0'; s++) + { + if (*s == '(') + ++parens; + else if (*s == ')') + { + if (parens == 0) + break; + --parens; + } + else if (*s == ',' && parens == 0) + { + /* A comma can not normally appear in an expression, so + this is a case of '(expr,...'. */ + return *str++; + } + } + } + + /* See if it's a register. */ + + reg = m68k_reg_parse (&str); + if (reg != 0) + { + int ret; + + yylval.reg = reg; + + if (reg >= DATA0 && reg <= DATA7) + ret = DR; + else if (reg >= ADDR0 && reg <= ADDR7) + ret = AR; + else if (reg >= FP0 && reg <= FP7) + return FPR; + else if (reg == FPI + || reg == FPS + || reg == FPC) + return FPCR; + else if (reg == PC) + return LPC; + else if (reg >= ZDATA0 && reg <= ZDATA7) + ret = ZDR; + else if (reg >= ZADDR0 && reg <= ZADDR7) + ret = ZAR; + else if (reg == ZPC) + return LZPC; + else + return CREG; + + /* If we get here, we have a data or address register. We + must check for a size or scale; if we find one, we must + return INDEXREG. */ + + s = str; + + if (*s != '.' && *s != ':' && *s != '*') + return ret; + + yylval.indexreg.reg = reg; + + if (*s != '.' && *s != ':') + yylval.indexreg.size = SIZE_UNSPEC; + else + { + ++s; + switch (*s) + { + case 'w': + case 'W': + yylval.indexreg.size = SIZE_WORD; + ++s; + break; + case 'l': + case 'L': + yylval.indexreg.size = SIZE_LONG; + ++s; + break; + default: + yyerror (_("illegal size specification")); + yylval.indexreg.size = SIZE_UNSPEC; + break; + } + } + + yylval.indexreg.scale = 1; + + if (*s == '*' || *s == ':') + { + expressionS scale; + + ++s; + + hold = input_line_pointer; + input_line_pointer = s; + expression (&scale); + s = input_line_pointer; + input_line_pointer = hold; + + if (scale.X_op != O_constant) + yyerror (_("scale specification must resolve to a number")); + else + { + switch (scale.X_add_number) + { + case 1: + case 2: + case 4: + case 8: + yylval.indexreg.scale = scale.X_add_number; + break; + default: + yyerror (_("invalid scale value")); + break; + } + } + } + + str = s; + + return INDEXREG; + } + + /* It must be an expression. Before we call expression, we need to + look ahead to see if there is a size specification. We must do + that first, because otherwise foo.l will be treated as the symbol + foo.l, rather than as the symbol foo with a long size + specification. The grammar requires that all expressions end at + the end of the operand, or with ',', '(', ']', ')'. */ + + parens = 0; + for (s = str; *s != '\0'; s++) + { + if (*s == '(') + { + if (parens == 0 + && s > str + && (s[-1] == ')' || isalnum ((unsigned char) s[-1]))) + break; + ++parens; + } + else if (*s == ')') + { + if (parens == 0) + break; + --parens; + } + else if (parens == 0 + && (*s == ',' || *s == ']')) + break; + } + + yylval.exp.size = SIZE_UNSPEC; + if (s <= str + 2 + || (s[-2] != '.' && s[-2] != ':')) + tail = 0; + else + { + switch (s[-1]) + { + case 's': + case 'S': + case 'b': + case 'B': + yylval.exp.size = SIZE_BYTE; + break; + case 'w': + case 'W': + yylval.exp.size = SIZE_WORD; + break; + case 'l': + case 'L': + yylval.exp.size = SIZE_LONG; + break; + default: + break; + } + if (yylval.exp.size != SIZE_UNSPEC) + tail = 2; + } + +#ifdef OBJ_ELF + { + /* Look for @PLTPC, etc. */ + char *cp; + + yylval.exp.pic_reloc = pic_none; + cp = s - tail; + if (cp - 6 > str && cp[-6] == '@') + { + if (strncmp (cp - 6, "@PLTPC", 6) == 0) + { + yylval.exp.pic_reloc = pic_plt_pcrel; + tail += 6; + } + else if (strncmp (cp - 6, "@GOTPC", 6) == 0) + { + yylval.exp.pic_reloc = pic_got_pcrel; + tail += 6; + } + } + else if (cp - 4 > str && cp[-4] == '@') + { + if (strncmp (cp - 4, "@PLT", 4) == 0) + { + yylval.exp.pic_reloc = pic_plt_off; + tail += 4; + } + else if (strncmp (cp - 4, "@GOT", 4) == 0) + { + yylval.exp.pic_reloc = pic_got_off; + tail += 4; + } + } + } +#endif + + if (tail != 0) + { + c = s[-tail]; + s[-tail] = 0; + } + + hold = input_line_pointer; + input_line_pointer = str; + expression (&yylval.exp.exp); + str = input_line_pointer; + input_line_pointer = hold; + + if (tail != 0) + { + s[-tail] = c; + str = s; + } + + return EXPR; +} + +/* Parse an m68k operand. This is the only function which is called + from outside this file. */ + +int +m68k_ip_op (s, oparg) + char *s; + struct m68k_op *oparg; +{ + memset (oparg, 0, sizeof *oparg); + oparg->error = NULL; + oparg->index.reg = ZDATA0; + oparg->index.scale = 1; + oparg->disp.exp.X_op = O_absent; + oparg->odisp.exp.X_op = O_absent; + + str = strorig = s; + op = oparg; + + return yyparse (); +} + +/* The error handler. */ + +static void +yyerror (s) + const char *s; +{ + op->error = s; +} diff --git a/gas/config/m88k-opcode.h b/gas/config/m88k-opcode.h new file mode 100644 index 0000000000..27464bc0fc --- /dev/null +++ b/gas/config/m88k-opcode.h @@ -0,0 +1,559 @@ +/* m88k-opcode.h -- Instruction information for the Motorola 88000 + Contributed by Devon Bowen of Buffalo University + and Torbjorn Granlund of the Swedish Institute of Computer Science. + Copyright (C) 1989, 1990, 1991 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 1, 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 !defined(__STDC__) && !defined(const) +#define const +#endif + +/* + Character codes for op_spec field below. + Reserved for self-matching: [ ] , + + d = GRF Destination register (21:5) + x = XRF register prefix. Makes next d, 1, or 2, match an extended register. + 1 = Source register 1 (16:5) + 2 = Source register 2 (0:5) + 3 = Both source registers (same value) (0:5 and 16:5) + I = IMM16 (0:16) + b = bit field spec. (0:10) + p = 16 bit pc displ. (0:16) + P = 26 bit pc displ. (0:26) + B = bb0/bb1 condition (21:5) + M = bcnd condition (21:5) + f = fcr (5:6) + c = cr (5:6) + V = VEC9 (0:9) + o = O6 field of "prot" insn (10:7) + ? = Give warning for this insn/operand combination + */ + +/* instruction descriptor structure */ + +struct m88k_opcode +{ + unsigned int opcode; + char *name; + char *op_spec; +}; + +/* and introducing... the Motorola 88100 and 88110 instruction sets... */ + +/* By default, include the 88110 instructions. */ +#define MC88110 + +#if defined (MC88110) +#define _MC88100(OPCODE,MNEM,OP_SPEC) +#define _MC88110(OPCODE,MNEM,OP_SPEC) {OPCODE,MNEM,OP_SPEC}, +#else +#define _MC88100(OPCODE,MNEM,OP_SPEC) {OPCODE,MNEM,OP_SPEC}, +#define _MC88110(OPCODE,MNEM,OP_SPEC) +#endif + +#define _MC88xxx(OPCODE,MNEM,OP_SPEC) {OPCODE,MNEM,OP_SPEC}, + +/* Equal mnemonics must be adjacent. + More specific operand specification must go before more general. + For example, "d,1,2" must go before "d,1,I" as a register for s2 + would otherwise be considered a variable name. */ + +static struct m88k_opcode m88k_opcodes[] = +{ + /* Opcode Mnemonic Opspec */ + + _MC88xxx (0xf4007000, "add", "d,1,2") + _MC88xxx (0x70000000, "add", "d,1,I") + _MC88xxx (0xf4007200, "add.ci", "d,1,2") + _MC88xxx (0xf4007300, "add.cio", "d,1,2") + _MC88xxx (0xf4007100, "add.co", "d,1,2") + _MC88xxx (0xf4006000, "addu", "d,1,2") + _MC88xxx (0x60000000, "addu", "d,1,I") + _MC88xxx (0xf4006200, "addu.ci", "d,1,2") + _MC88xxx (0xf4006300, "addu.cio", "d,1,2") + _MC88xxx (0xf4006100, "addu.co", "d,1,2") + _MC88xxx (0xf4004000, "and", "d,1,2") + _MC88xxx (0x40000000, "and", "d,1,I") + _MC88xxx (0xf4004400, "and.c", "d,1,2") + _MC88xxx (0x44000000, "and.u", "d,1,I") + _MC88xxx (0xd0000000, "bb0", "B,1,p") + _MC88xxx (0xd4000000, "bb0.n", "B,1,p") + _MC88xxx (0xd8000000, "bb1", "B,1,p") + _MC88xxx (0xdc000000, "bb1.n", "B,1,p") + _MC88xxx (0xe8000000, "bcnd", "M,1,p") + _MC88xxx (0xec000000, "bcnd.n", "M,1,p") + _MC88xxx (0xc0000000, "br", "P") + _MC88xxx (0xc4000000, "br.n", "P") + _MC88xxx (0xc8000000, "bsr", "P") + _MC88xxx (0xcc000000, "bsr.n", "P") + _MC88xxx (0xf4008000, "clr", "d,1,2") + _MC88xxx (0xf0008000, "clr", "d,1,b") + _MC88xxx (0xf4007c00, "cmp", "d,1,2") + _MC88xxx (0x7c000000, "cmp", "d,1,I") + _MC88xxx (0xf4007800, "div", "d,1,2") + _MC88xxx (0x78000000, "div", "d,1,I") + _MC88xxx (0xf4007800, "divs", "d,1,2") + _MC88xxx (0x78000000, "divs", "d,1,I") + _MC88110 (0xf4006900, "divu.d", "d,1,2") + _MC88xxx (0xf4006800, "divu", "d,1,2") + _MC88xxx (0x68000000, "divu", "d,1,I") + _MC88xxx (0xf4009000, "ext", "d,1,2") + _MC88xxx (0xf0009000, "ext", "d,1,b") + _MC88xxx (0xf4009800, "extu", "d,1,2") + _MC88xxx (0xf0009800, "extu", "d,1,b") + _MC88xxx (0x84002800, "fadd.sss", "d,1,2") + _MC88110 (0x8400a800, "fadd.sss", "xd,x1,x2") + _MC88xxx (0x84002880, "fadd.ssd", "d,1,2") + _MC88110 (0x8400a820, "fadd.ssd", "xd,x1,x2") + _MC88110 (0x8400a840, "fadd.ssx", "xd,x1,x2") + _MC88xxx (0x84002a00, "fadd.sds", "d,1,2") + _MC88110 (0x8400a880, "fadd.sds", "xd,x1,x2") + _MC88xxx (0x84002a80, "fadd.sdd", "d,1,2") + _MC88110 (0x8400a8a0, "fadd.sdd", "xd,x1,x2") + _MC88110 (0x8400a8c0, "fadd.sdx", "xd,x1,x2") + _MC88110 (0x8400a900, "fadd.sxs", "xd,x1,x2") + _MC88110 (0x8400a920, "fadd.sxd", "xd,x1,x2") + _MC88110 (0x8400a940, "fadd.sxx", "xd,x1,x2") + _MC88xxx (0x84002820, "fadd.dss", "d,1,2") + _MC88110 (0x8400aa00, "fadd.dss", "xd,x1,x2") + _MC88xxx (0x840028a0, "fadd.dsd", "d,1,2") + _MC88110 (0x8400aa20, "fadd.dsd", "xd,x1,x2") + _MC88110 (0x8400aa40, "fadd.dsx", "xd,x1,x2") + _MC88xxx (0x84002a20, "fadd.dds", "d,1,2") + _MC88110 (0x8400aa80, "fadd.dds", "xd,x1,x2") + _MC88xxx (0x84002aa0, "fadd.ddd", "d,1,2") + _MC88110 (0x8400aaa0, "fadd.ddd", "xd,x1,x2") + _MC88110 (0x8400aac0, "fadd.ddx", "xd,x1,x2") + _MC88110 (0x8400ab00, "fadd.dxs", "xd,x1,x2") + _MC88110 (0x8400ab20, "fadd.dxd", "xd,x1,x2") + _MC88110 (0x8400ab40, "fadd.dxx", "xd,x1,x2") + _MC88110 (0x8400ac00, "fadd.xss", "xd,x1,x2") + _MC88110 (0x8400ac20, "fadd.xsd", "xd,x1,x2") + _MC88110 (0x8400ac40, "fadd.xsx", "xd,x1,x2") + _MC88110 (0x8400ac80, "fadd.xds", "xd,x1,x2") + _MC88110 (0x8400aca0, "fadd.xdd", "xd,x1,x2") + _MC88110 (0x8400acc0, "fadd.xdx", "xd,x1,x2") + _MC88110 (0x8400ad00, "fadd.xxs", "xd,x1,x2") + _MC88110 (0x8400ad20, "fadd.xxd", "xd,x1,x2") + _MC88110 (0x8400ad40, "fadd.xxx", "xd,x1,x2") + _MC88xxx (0x84003a80, "fcmp.sdd", "d,1,2") + _MC88110 (0x8400ba80, "fcmp.sdd", "d,x1,x2") + _MC88xxx (0x84003a00, "fcmp.sds", "d,1,2") + _MC88110 (0x8400ba00, "fcmp.sds", "d,x1,x2") + _MC88110 (0x8400bb00, "fcmp.sdx", "d,x1,x2") + _MC88xxx (0x84003880, "fcmp.ssd", "d,1,2") + _MC88110 (0x8400b880, "fcmp.ssd", "d,x1,x2") + _MC88xxx (0x84003800, "fcmp.sss", "d,1,2") + _MC88110 (0x8400b800, "fcmp.sss", "d,x1,x2") + _MC88110 (0x8400b900, "fcmp.ssx", "d,x1,x2") + _MC88110 (0x8400bc80, "fcmp.sxd", "d,x1,x2") + _MC88110 (0x8400bc00, "fcmp.sxs", "d,x1,x2") + _MC88110 (0x8400bd00, "fcmp.sxx", "d,x1,x2") + _MC88110 (0x84003aa0, "fcmpu.sdd", "d,1,2") + _MC88110 (0x8400baa0, "fcmpu.sdd", "d,x1,x2") + _MC88110 (0x84003a20, "fcmpu.sds", "d,1,2") + _MC88110 (0x8400ba20, "fcmpu.sds", "d,x1,x2") + _MC88110 (0x8400bb20, "fcmpu.sdx", "d,x1,x2") + _MC88110 (0x840038a0, "fcmpu.ssd", "d,1,2") + _MC88110 (0x8400b8a0, "fcmpu.ssd", "d,x1,x2") + _MC88110 (0x84003820, "fcmpu.sss", "d,1,2") + _MC88110 (0x8400b820, "fcmpu.sss", "d,x1,x2") + _MC88110 (0x8400b920, "fcmpu.ssx", "d,x1,x2") + _MC88110 (0x8400bca0, "fcmpu.sxd", "d,x1,x2") + _MC88110 (0x8400bc20, "fcmpu.sxs", "d,x1,x2") + _MC88110 (0x8400bd20, "fcmpu.sxx", "d,x1,x2") + _MC88110 (0x84000880, "fcvt.ds", "d,2") + _MC88110 (0x84008880, "fcvt.ds", "xd,x2") + _MC88110 (0x840088c0, "fcvt.dx", "xd,x2") + _MC88110 (0x84000820, "fcvt.sd", "d,2") + _MC88110 (0x84008820, "fcvt.sd", "xd,x2") + _MC88110 (0x84008840, "fcvt.sx", "xd,x2") + _MC88110 (0x84008920, "fcvt.xd", "xd,x2") + _MC88110 (0x84008900, "fcvt.xs", "xd,x2") + _MC88xxx (0x84007000, "fdiv.sss", "d,1,2") + _MC88110 (0x8400f000, "fdiv.sss", "xd,x1,x2") + _MC88xxx (0x84007080, "fdiv.ssd", "d,1,2") + _MC88110 (0x8400f020, "fdiv.ssd", "xd,x1,x2") + _MC88110 (0x8400f040, "fdiv.ssx", "xd,x1,x2") + _MC88xxx (0x84007200, "fdiv.sds", "d,1,2") + _MC88110 (0x8400f080, "fdiv.sds", "xd,x1,x2") + _MC88xxx (0x84007280, "fdiv.sdd", "d,1,2") + _MC88110 (0x8400f0a0, "fdiv.sdd", "xd,x1,x2") + _MC88110 (0x8400f0c0, "fdiv.sdx", "xd,x1,x2") + _MC88110 (0x8400f100, "fdiv.sxs", "xd,x1,x2") + _MC88110 (0x8400f120, "fdiv.sxd", "xd,x1,x2") + _MC88110 (0x8400f140, "fdiv.sxx", "xd,x1,x2") + _MC88xxx (0x84007020, "fdiv.dss", "d,1,2") + _MC88110 (0x8400f200, "fdiv.dss", "xd,x1,x2") + _MC88xxx (0x840070a0, "fdiv.dsd", "d,1,2") + _MC88110 (0x8400f220, "fdiv.dsd", "xd,x1,x2") + _MC88110 (0x8400f240, "fdiv.dsx", "xd,x1,x2") + _MC88xxx (0x84007220, "fdiv.dds", "d,1,2") + _MC88110 (0x8400f280, "fdiv.dds", "xd,x1,x2") + _MC88xxx (0x840072a0, "fdiv.ddd", "d,1,2") + _MC88110 (0x8400f2a0, "fdiv.ddd", "xd,x1,x2") + _MC88110 (0x8400f2c0, "fdiv.ddx", "xd,x1,x2") + _MC88110 (0x8400f300, "fdiv.dxs", "xd,x1,x2") + _MC88110 (0x8400f320, "fdiv.dxd", "xd,x1,x2") + _MC88110 (0x8400f340, "fdiv.dxx", "xd,x1,x2") + _MC88110 (0x8400f400, "fdiv.xss", "xd,x1,x2") + _MC88110 (0x8400f420, "fdiv.xsd", "xd,x1,x2") + _MC88110 (0x8400f440, "fdiv.xsx", "xd,x1,x2") + _MC88110 (0x8400f480, "fdiv.xds", "xd,x1,x2") + _MC88110 (0x8400f4a0, "fdiv.xdd", "xd,x1,x2") + _MC88110 (0x8400f4c0, "fdiv.xdx", "xd,x1,x2") + _MC88110 (0x8400f500, "fdiv.xxs", "xd,x1,x2") + _MC88110 (0x8400f520, "fdiv.xxd", "xd,x1,x2") + _MC88110 (0x8400f540, "fdiv.xxx", "xd,x1,x2") + _MC88xxx (0xf400ec00, "ff0", "d,2") + _MC88xxx (0xf400e800, "ff1", "d,2") + _MC88xxx (0x80004800, "fldcr", "d,f") + _MC88xxx (0x84002020, "flt.ds", "d,2") + _MC88110 (0x84002220, "flt.ds", "xd,2") + _MC88xxx (0x84002000, "flt.ss", "d,2") + _MC88110 (0x84002200, "flt.ss", "xd,2") + _MC88110 (0x84002240, "flt.xs", "xd,2") + _MC88xxx (0x84000000, "fmul.sss", "d,1,2") + _MC88110 (0x84008000, "fmul.sss", "xd,x1,x2") + _MC88xxx (0x84000080, "fmul.ssd", "d,1,2") + _MC88110 (0x84008020, "fmul.ssd", "xd,x1,x2") + _MC88110 (0x84008040, "fmul.ssx", "xd,x1,x2") + _MC88xxx (0x84000200, "fmul.sds", "d,1,2") + _MC88110 (0x84008080, "fmul.sds", "xd,x1,x2") + _MC88xxx (0x84000280, "fmul.sdd", "d,1,2") + _MC88110 (0x840080a0, "fmul.sdd", "xd,x1,x2") + _MC88110 (0x840080c0, "fmul.sdx", "xd,x1,x2") + _MC88110 (0x84008100, "fmul.sxs", "xd,x1,x2") + _MC88110 (0x84008120, "fmul.sxd", "xd,x1,x2") + _MC88110 (0x84008140, "fmul.sxx", "xd,x1,x2") + _MC88xxx (0x84000020, "fmul.dss", "d,1,2") + _MC88110 (0x84008200, "fmul.dss", "xd,x1,x2") + _MC88xxx (0x840000a0, "fmul.dsd", "d,1,2") + _MC88110 (0x84008220, "fmul.dsd", "xd,x1,x2") + _MC88110 (0x84008240, "fmul.dsx", "xd,x1,x2") + _MC88xxx (0x84000220, "fmul.dds", "d,1,2") + _MC88110 (0x84008280, "fmul.dds", "xd,x1,x2") + _MC88xxx (0x840002a0, "fmul.ddd", "d,1,2") + _MC88110 (0x840082a0, "fmul.ddd", "xd,x1,x2") + _MC88110 (0x840082c0, "fmul.ddx", "xd,x1,x2") + _MC88110 (0x84008300, "fmul.dxs", "xd,x1,x2") + _MC88110 (0x84008320, "fmul.dxd", "xd,x1,x2") + _MC88110 (0x84008340, "fmul.dxx", "xd,x1,x2") + _MC88110 (0x84008400, "fmul.xss", "xd,x1,x2") + _MC88110 (0x84008420, "fmul.xsd", "xd,x1,x2") + _MC88110 (0x84008440, "fmul.xsx", "xd,x1,x2") + _MC88110 (0x84008480, "fmul.xds", "xd,x1,x2") + _MC88110 (0x840084a0, "fmul.xdd", "xd,x1,x2") + _MC88110 (0x840084c0, "fmul.xdx", "xd,x1,x2") + _MC88110 (0x84008500, "fmul.xxs", "xd,x1,x2") + _MC88110 (0x84008520, "fmul.xxd", "xd,x1,x2") + _MC88110 (0x84008540, "fmul.xxx", "xd,x1,x2") + _MC88110 (0x840078a0, "fsqrt.dd", "d,2") + _MC88110 (0x8400f8a0, "fsqrt.dd", "xd,x2") + _MC88110 (0x84007880, "fsqrt.ds", "d,2") + _MC88110 (0x8400f880, "fsqrt.ds", "xd,x2") + _MC88110 (0x8400f8c0, "fsqrt.dx", "xd,x2") + _MC88110 (0x84007820, "fsqrt.sd", "d,2") + _MC88110 (0x8400f820, "fsqrt.sd", "xd,x2") + _MC88110 (0x84007800, "fsqrt.ss", "d,2") + _MC88110 (0x8400f800, "fsqrt.ss", "xd,x2") + _MC88110 (0x8400f840, "fsqrt.sx", "xd,x2") + _MC88110 (0x8400f920, "fsqrt.xd", "xd,x2") + _MC88110 (0x8400f900, "fsqrt.xs", "xd,x2") + _MC88110 (0x8400f940, "fsqrt.xx", "xd,x2") + _MC88xxx (0x80008800, "fstcr", "3,f") + _MC88xxx (0x84003000, "fsub.sss", "d,1,2") + _MC88110 (0x8400b000, "fsub.sss", "xd,x1,x2") + _MC88xxx (0x84003080, "fsub.ssd", "d,1,2") + _MC88110 (0x8400b020, "fsub.ssd", "xd,x1,x2") + _MC88110 (0x8400b040, "fsub.ssx", "xd,x1,x2") + _MC88xxx (0x84003200, "fsub.sds", "d,1,2") + _MC88110 (0x8400b080, "fsub.sds", "xd,x1,x2") + _MC88xxx (0x84003280, "fsub.sdd", "d,1,2") + _MC88110 (0x8400b0a0, "fsub.sdd", "xd,x1,x2") + _MC88110 (0x8400b0c0, "fsub.sdx", "xd,x1,x2") + _MC88110 (0x8400b100, "fsub.sxs", "xd,x1,x2") + _MC88110 (0x8400b120, "fsub.sxd", "xd,x1,x2") + _MC88110 (0x8400b140, "fsub.sxx", "xd,x1,x2") + _MC88xxx (0x84003020, "fsub.dss", "d,1,2") + _MC88110 (0x8400b200, "fsub.dss", "xd,x1,x2") + _MC88xxx (0x840030a0, "fsub.dsd", "d,1,2") + _MC88110 (0x8400b220, "fsub.dsd", "xd,x1,x2") + _MC88110 (0x8400b240, "fsub.dsx", "xd,x1,x2") + _MC88xxx (0x84003220, "fsub.dds", "d,1,2") + _MC88110 (0x8400b280, "fsub.dds", "xd,x1,x2") + _MC88xxx (0x840032a0, "fsub.ddd", "d,1,2") + _MC88110 (0x8400b2a0, "fsub.ddd", "xd,x1,x2") + _MC88110 (0x8400b2c0, "fsub.ddx", "xd,x1,x2") + _MC88110 (0x8400b300, "fsub.dxs", "xd,x1,x2") + _MC88110 (0x8400b320, "fsub.dxd", "xd,x1,x2") + _MC88110 (0x8400b340, "fsub.dxx", "xd,x1,x2") + _MC88110 (0x8400b400, "fsub.xss", "xd,x1,x2") + _MC88110 (0x8400b420, "fsub.xsd", "xd,x1,x2") + _MC88110 (0x8400b440, "fsub.xsx", "xd,x1,x2") + _MC88110 (0x8400b480, "fsub.xds", "xd,x1,x2") + _MC88110 (0x8400b4a0, "fsub.xdd", "xd,x1,x2") + _MC88110 (0x8400b4c0, "fsub.xdx", "xd,x1,x2") + _MC88110 (0x8400b500, "fsub.xxs", "xd,x1,x2") + _MC88110 (0x8400b520, "fsub.xxd", "xd,x1,x2") + _MC88110 (0x8400b540, "fsub.xxx", "xd,x1,x2") + _MC88xxx (0x8000c800, "fxcr", "d,3,f") + _MC88xxx (0x8400fc01, "illop1", "") + _MC88xxx (0x8400fc02, "illop2", "") + _MC88xxx (0x8400fc03, "illop3", "") + _MC88xxx (0x84004880, "int.sd", "d,2") + _MC88110 (0x8400c880, "int.sd", "d,x2") + _MC88xxx (0x84004800, "int.ss", "d,2") + _MC88110 (0x8400c800, "int.ss", "d,x2") + _MC88110 (0x8400c900, "int.sx", "d,x2") + _MC88xxx (0xf400c000, "jmp", "2") + _MC88xxx (0xf400c400, "jmp.n", "2") + _MC88xxx (0xf400c800, "jsr", "2") + _MC88xxx (0xf400cc00, "jsr.n", "2") + _MC88xxx (0xf4001400, "ld", "d,1,2") + _MC88xxx (0xf4001600, "ld", "d,1[2]") + _MC88xxx (0x14000000, "ld", "d,1,I") + _MC88110 (0xf0001600, "ld", "xd,1[2]") + _MC88110 (0xf0001400, "ld", "xd,1,2") + _MC88110 (0x04000000, "ld", "xd,1,I") + _MC88xxx (0xf4001e00, "ld.b", "d,1[2]") + _MC88xxx (0xf4001c00, "ld.b", "d,1,2") + _MC88xxx (0x1c000000, "ld.b", "d,1,I") + _MC88xxx (0xf4001d00, "ld.b.usr", "d,1,2") + _MC88xxx (0xf4001f00, "ld.b.usr", "d,1[2]") + _MC88xxx (0xf4000e00, "ld.bu", "d,1[2]") + _MC88xxx (0xf4000c00, "ld.bu", "d,1,2") + _MC88xxx (0x0c000000, "ld.bu", "d,1,I") + _MC88xxx (0xf4000d00, "ld.bu.usr", "d,1,2") + _MC88xxx (0xf4000f00, "ld.bu.usr", "d,1[2]") + _MC88xxx (0xf4001200, "ld.d", "d,1[2]") + _MC88xxx (0xf4001000, "ld.d", "d,1,2") + _MC88xxx (0x10000000, "ld.d", "d,1,I") + _MC88110 (0xf0001200, "ld.d", "xd,1[2]") + _MC88110 (0xf0001000, "ld.d", "xd,1,2") + _MC88110 (0x00000000, "ld.d", "xd,1,I") + _MC88xxx (0xf4001100, "ld.d.usr", "d,1,2") + _MC88xxx (0xf4001300, "ld.d.usr", "d,1[2]") + _MC88110 (0xf0001100, "ld.d.usr", "xd,1,2") + _MC88110 (0xf0001300, "ld.d.usr", "xd,1[2]") + _MC88xxx (0xf4001a00, "ld.h", "d,1[2]") + _MC88xxx (0xf4001800, "ld.h", "d,1,2") + _MC88xxx (0x18000000, "ld.h", "d,1,I") + _MC88xxx (0xf4001900, "ld.h.usr", "d,1,2") + _MC88xxx (0xf4001b00, "ld.h.usr", "d,1[2]") + _MC88xxx (0xf4000a00, "ld.hu", "d,1[2]") + _MC88xxx (0xf4000800, "ld.hu", "d,1,2") + _MC88xxx (0x08000000, "ld.hu", "d,1,I") + _MC88xxx (0xf4000900, "ld.hu.usr", "d,1,2") + _MC88xxx (0xf4000b00, "ld.hu.usr", "d,1[2]") + _MC88xxx (0xf4001500, "ld.usr", "d,1,2") + _MC88xxx (0xf4001700, "ld.usr", "d,1[2]") + _MC88110 (0xf0001500, "ld.usr", "xd,1,2") + _MC88110 (0xf0001700, "ld.usr", "xd,1[2]") + _MC88110 (0xf0001a00, "ld.x", "xd,1[2]") + _MC88110 (0xf0001800, "ld.x", "xd,1,2") + _MC88110 (0x3c000000, "ld.x", "xd,1,I") + _MC88110 (0xf0001900, "ld.x.usr", "xd,1,2") + _MC88110 (0xf0001b00, "ld.x.usr", "xd,1[2]") + _MC88xxx (0xf4003600, "lda", "d,1[2]") + _MC88xxx (0xf4006000, "lda", "?d,1,2") /* Output addu */ + _MC88xxx (0x60000000, "lda", "?d,1,I") /* Output addu */ + _MC88xxx (0xf4006000, "lda.b", "?d,1[2]") /* Output addu */ + _MC88xxx (0xf4006000, "lda.b", "?d,1,2") /* Output addu */ + _MC88xxx (0x60000000, "lda.b", "?d,1,I") /* Output addu */ + _MC88xxx (0xf4003200, "lda.d", "d,1[2]") + _MC88xxx (0xf4006000, "lda.d", "?d,1,2") /* Output addu */ + _MC88xxx (0x60000000, "lda.d", "?d,1,I") /* Output addu */ + _MC88110 (0xf4003e00, "lda.x", "d,1[2]") + _MC88xxx (0xf4003a00, "lda.h", "d,1[2]") + _MC88xxx (0xf4006000, "lda.h", "?d,1,2") /* Output addu */ + _MC88xxx (0x60000000, "lda.h", "?d,1,I") /* Output addu */ + _MC88xxx (0x80004000, "ldcr", "d,c") + _MC88xxx (0xf400a000, "mak", "d,1,2") + _MC88xxx (0xf000a000, "mak", "d,1,b") + _MC88xxx (0x48000000, "mask", "d,1,I") + _MC88xxx (0x4c000000, "mask.u", "d,1,I") + _MC88110 (0x8400c000, "mov.s", "d,x2") + _MC88110 (0x84004200, "mov.s", "xd,2") + _MC88110 (0x8400c080, "mov.d", "d,x2") + _MC88110 (0x84004280, "mov.d", "xd,2") + _MC88110 (0x8400c300, "mov", "xd,x2") + _MC88xxx (0xf4006c00, "mul", "d,1,2") + _MC88xxx (0x6c000000, "mul", "d,1,I") + _MC88xxx (0xf4006e00, "muls", "d,1,2") + _MC88xxx (0x6c000000, "muls", "d,1,I") + _MC88xxx (0xf4006c00, "mulu", "d,1,2") /* synonym for mul */ + _MC88xxx (0x6c000000, "mulu", "d,1,I") /* synonym for mul */ + _MC88110 (0xf4006d00, "mulu.d", "d,1,2") + _MC88xxx (0x84005080, "nint.sd", "d,2") + _MC88110 (0x8400d080, "nint.sd", "d,x2") + _MC88xxx (0x84005000, "nint.ss", "d,2") + _MC88110 (0x8400d000, "nint.ss", "d,x2") + _MC88110 (0x8400d100, "nint.sx", "d,x2") + _MC88xxx (0xf4005800, "or", "d,1,2") + _MC88xxx (0x58000000, "or", "d,1,I") + _MC88xxx (0xf4005c00, "or.c", "d,1,2") + _MC88xxx (0x5c000000, "or.u", "d,1,I") + _MC88110 (0x88002020, "padd.b", "d,1,2") + _MC88110 (0x88002040, "padd.h", "d,1,2") + _MC88110 (0x88002060, "padd", "d,1,2") + _MC88110 (0x880020a0, "padds.u.b", "d,1,2") + _MC88110 (0x880020c0, "padds.u.h", "d,1,2") + _MC88110 (0x880020e0, "padds.u", "d,1,2") + _MC88110 (0x88002120, "padds.us.b", "d,1,2") + _MC88110 (0x88002140, "padds.us.h", "d,1,2") + _MC88110 (0x88002160, "padds.us", "d,1,2") + _MC88110 (0x880021a0, "padds.s.b", "d,1,2") + _MC88110 (0x880021c0, "padds.s.h", "d,1,2") + _MC88110 (0x880021e0, "padds.s", "d,1,2") + _MC88110 (0x88003860, "pcmp", "d,1,2") + _MC88110 (0x88000000, "pmul", "d,1,2") + _MC88110 (0x88006420, "ppack.32.b", "d,1,2") + _MC88110 (0x88006240, "ppack.16.h", "d,1,2") + _MC88110 (0x88006440, "ppack.32.h", "d,1,2") + _MC88110 (0x88006160, "ppack.8", "d,1,2") + _MC88110 (0x88006260, "ppack.16", "d,1,2") + _MC88110 (0x88006460, "ppack.32", "d,1,2") + _MC88110 (0x88007800, "prot", "d,1,2") + _MC88110 (0x88007000, "prot", "d,1,o") + _MC88110 (0x88003020, "psub.b", "d,1,2") + _MC88110 (0x88003040, "psub.h", "d,1,2") + _MC88110 (0x88003060, "psub", "d,1,2") + _MC88110 (0x880030a0, "psubs.u.b", "d,1,2") + _MC88110 (0x880030c0, "psubs.u.h", "d,1,2") + _MC88110 (0x880030e0, "psubs.u", "d,1,2") + _MC88110 (0x88003120, "psubs.us.b", "d,1,2") + _MC88110 (0x88003140, "psubs.us.h", "d,1,2") + _MC88110 (0x88003160, "psubs.us", "d,1,2") + _MC88110 (0x880031a0, "psubs.s.b", "d,1,2") + _MC88110 (0x880031c0, "psubs.s.h", "d,1,2") + _MC88110 (0x880031e0, "psubs.s", "d,1,2") + _MC88110 (0x88006800, "punpk.n", "d,1") + _MC88110 (0x88006820, "punpk.b", "d,1") + _MC88110 (0x88006840, "punpk.h", "d,1") + _MC88xxx (0xf400a800, "rot", "d,1,2") + _MC88xxx (0xf000a800, "rot", "d,1,b") + _MC88xxx (0xf400fc00, "rte", "") + _MC88xxx (0xf4008800, "set", "d,1,2") + _MC88xxx (0xf0008800, "set", "d,1,b") + _MC88xxx (0xf4002600, "st", "d,1[2]") + _MC88xxx (0xf4002400, "st", "d,1,2") + _MC88xxx (0x24000000, "st", "d,1,I") + _MC88110 (0xf0002600, "st", "xd,1[2]") + _MC88110 (0xf0002400, "st", "xd,1,2") + _MC88110 (0x34000000, "st", "xd,1,I") + _MC88xxx (0xf4002e00, "st.b", "d,1[2]") + _MC88xxx (0xf4002c00, "st.b", "d,1,2") + _MC88xxx (0x2c000000, "st.b", "d,1,I") + _MC88xxx (0xf4002d00, "st.b.usr", "d,1,2") + _MC88xxx (0xf4002f00, "st.b.usr", "d,1[2]") + _MC88110 (0xf4002d80, "st.b.usr.wt", "d,1,2") + _MC88110 (0xf4002f80, "st.b.usr.wt", "d,1[2]") + _MC88110 (0xf4002c80, "st.b.wt", "d,1,2") + _MC88110 (0xf4002e80, "st.b.wt", "d,1[2]") + _MC88xxx (0xf4002200, "st.d", "d,1[2]") + _MC88xxx (0xf4002000, "st.d", "d,1,2") + _MC88xxx (0x20000000, "st.d", "d,1,I") + _MC88110 (0xf0002200, "st.d", "xd,1[2]") + _MC88110 (0xf0002000, "st.d", "xd,1,2") + _MC88110 (0x30000000, "st.d", "xd,1,I") + _MC88xxx (0xf4002100, "st.d.usr", "d,1,2") + _MC88xxx (0xf4002300, "st.d.usr", "d,1[2]") + _MC88110 (0xf0002100, "st.d.usr", "xd,1,2") + _MC88110 (0xf0002300, "st.d.usr", "xd,1[2]") + _MC88110 (0xf4002180, "st.d.usr.wt", "d,1,2") + _MC88110 (0xf4002380, "st.d.usr.wt", "d,1[2]") + _MC88110 (0xf0002180, "st.d.usr.wt", "xd,1,2") + _MC88110 (0xf0002380, "st.d.usr.wt", "xd,1[2]") + _MC88110 (0xf4002080, "st.d.wt", "d,1,2") + _MC88110 (0xf4002280, "st.d.wt", "d,1[2]") + _MC88110 (0xf0002080, "st.d.wt", "xd,1,2") + _MC88110 (0xf0002280, "st.d.wt", "xd,1[2]") + _MC88xxx (0xf4002a00, "st.h", "d,1[2]") + _MC88xxx (0xf4002800, "st.h", "d,1,2") + _MC88xxx (0x28000000, "st.h", "d,1,I") + _MC88xxx (0xf4002900, "st.h.usr", "d,1,2") + _MC88xxx (0xf4002b00, "st.h.usr", "d,1[2]") + _MC88110 (0xf4002980, "st.h.usr.wt", "d,1,2") + _MC88110 (0xf4002b80, "st.h.usr.wt", "d,1[2]") + _MC88110 (0xf4002880, "st.h.wt", "d,1,2") + _MC88110 (0xf4002a80, "st.h.wt", "d,1[2]") + _MC88xxx (0xf4002500, "st.usr", "d,1,2") + _MC88xxx (0xf4002700, "st.usr", "d,1[2]") + _MC88110 (0xf0002500, "st.usr", "xd,1,2") + _MC88110 (0xf0002700, "st.usr", "xd,1[2]") + _MC88110 (0xf4002580, "st.usr.wt", "d,1,2") + _MC88110 (0xf4002780, "st.usr.wt", "d,1[2]") + _MC88110 (0xf0002580, "st.usr.wt", "xd,1,2") + _MC88110 (0xf0002780, "st.usr.wt", "xd,1[2]") + _MC88110 (0xf4002480, "st.wt", "d,1,2") + _MC88110 (0xf4002680, "st.wt", "d,1[2]") + _MC88110 (0xf0002480, "st.wt", "xd,1,2") + _MC88110 (0xf0002680, "st.wt", "xd,1[2]") + _MC88110 (0xf0002a00, "st.x", "xd,1[2]") + _MC88110 (0xf0002800, "st.x", "xd,1,2") + _MC88110 (0x38000000, "st.x", "xd,1,I") + _MC88110 (0xf0002900, "st.x.usr", "xd,1,2") + _MC88110 (0xf0002b00, "st.x.usr", "xd,1[2]") + _MC88110 (0xf0002980, "st.x.usr.wt", "xd,1,2") + _MC88110 (0xf0002b80, "st.x.usr.wt", "xd,1[2]") + _MC88110 (0xf0002880, "st.x.wt", "xd,1,2") + _MC88110 (0xf0002a80, "st.x.wt", "xd,1[2]") + _MC88xxx (0x80008000, "stcr", "3,c") + _MC88xxx (0xf4007400, "sub", "d,1,2") + _MC88xxx (0x74000000, "sub", "d,1,I") + _MC88xxx (0xf4007600, "sub.ci", "d,1,2") + _MC88xxx (0xf4007700, "sub.cio", "d,1,2") + _MC88xxx (0xf4007500, "sub.co", "d,1,2") + _MC88xxx (0xf4006400, "subu", "d,1,2") + _MC88xxx (0x64000000, "subu", "d,1,I") + _MC88xxx (0xf4006600, "subu.ci", "d,1,2") + _MC88xxx (0xf4006700, "subu.cio", "d,1,2") + _MC88xxx (0xf4006500, "subu.co", "d,1,2") + _MC88xxx (0xf000d000, "tb0", "B,1,V") + _MC88xxx (0xf000d800, "tb1", "B,1,V") + _MC88xxx (0xf400f800, "tbnd", "1,2") + _MC88xxx (0xf8000000, "tbnd", "1,I") + _MC88xxx (0xf000e800, "tcnd", "M,1,V") + _MC88xxx (0x84005880, "trnc.sd", "d,2") + _MC88110 (0x8400d880, "trnc.sd", "d,x2") + _MC88xxx (0x84005800, "trnc.ss", "d,2") + _MC88110 (0x8400d800, "trnc.ss", "d,x2") + _MC88110 (0x8400d900, "trnc.sx", "d,x2") + _MC88xxx (0x8000c000, "xcr", "d,3,c") + _MC88xxx (0xf4000600, "xmem", "d,1[2]") + _MC88xxx (0xf4000400, "xmem", "d,1,2") + _MC88100 (0x04000000, "xmem", "?d,1,I") + _MC88xxx (0xf4000200, "xmem.bu", "d,1[2]") + _MC88xxx (0xf4000000, "xmem.bu", "d,1,2") + _MC88100 (0x00000000, "xmem.bu", "?d,1,I") + _MC88xxx (0xf4000300, "xmem.bu.usr", "d,1[2]") + _MC88xxx (0xf4000100, "xmem.bu.usr", "d,1,2") + _MC88100 (0x00000100, "xmem.bu.usr", "?d,1,I") + _MC88xxx (0xf4000700, "xmem.usr", "d,1[2]") + _MC88xxx (0xf4000500, "xmem.usr", "d,1,2") + _MC88100 (0x04000100, "xmem.usr", "?d,1,I") + _MC88xxx (0xf4005000, "xor", "d,1,2") + _MC88xxx (0x50000000, "xor", "d,1,I") + _MC88xxx (0xf4005400, "xor.c", "d,1,2") + _MC88xxx (0x54000000, "xor.u", "d,1,I") + _MC88xxx (0x00000000, "", 0) +}; + +#define NUMOPCODES ((sizeof m88k_opcodes)/(sizeof m88k_opcodes[0])) diff --git a/gas/config/obj-aout.c b/gas/config/obj-aout.c new file mode 100644 index 0000000000..b5193475c1 --- /dev/null +++ b/gas/config/obj-aout.c @@ -0,0 +1,629 @@ +/* a.out object file format + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 1996 + 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" +#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 obj_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} /* end sentinel */ +}; /* obj_pseudo_table */ + + +#ifdef BFD_ASSEMBLER + +void +obj_aout_frob_symbol (sym, punt) + symbolS *sym; + int *punt; +{ + flagword flags; + asection *sec; + int desc, type, other; + + flags = sym->bsym->flags; + desc = S_GET_DESC (sym); + type = S_GET_TYPE (sym); + other = S_GET_OTHER (sym); + sec = sym->bsym->section; + + /* Only frob simple symbols this way right now. */ + if (! (type & ~ (N_TYPE | N_EXT))) + { + if (type == (N_UNDF | N_EXT) + && sec == &bfd_abs_section) + sym->bsym->section = sec = bfd_und_section_ptr; + + 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. */ + sym->bsym->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. */ + sym->bsym->section = bfd_ind_section_ptr; + sym->bsym->flags |= BSF_INDIRECT; + if (type & N_EXT) + { + sym->bsym->flags |= BSF_EXPORT; + sym->bsym->flags &=~ BSF_LOCAL; + } + break; + case N_WARNING: + /* Mark warning symbols. */ + sym->bsym->flags |= BSF_WARNING; + break; + } + } + else + { + sym->bsym->flags |= BSF_DEBUGGING; + } + + S_SET_TYPE (sym, type); + + /* Double check weak symbols. */ + if (sym->bsym->flags & BSF_WEAK) + { + 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 () +{ + /* 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; + 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 == true); +} + +#else + +/* 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 + +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; +{ + /* 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; +{ + 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 ogas ignored the .type pseudo-op, so we also ignore it if + we can't parse it. */ + +static void +obj_aout_type (ignore) + int ignore; +{ + char *name; + int c; + symbolS *sym; + + name = input_line_pointer; + c = get_symbol_end (); + sym = symbol_find (name); + *input_line_pointer = c; + if (sym != NULL) + { + 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) + S_SET_OTHER (sym, 1); + else if (strncmp (input_line_pointer, "function", 8) == 0) + S_SET_OTHER (sym, 2); + } + } + } + + /* Ignore everything else on the line. */ + s_ignore (0); +} + +void +obj_read_begin_hook () +{ +} + +#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 pusing data into text */ + + resolve_symbol_value (symbolP, 1); + + /* Skip symbols which were equated to undefined or common + symbols. */ + if (symbolP->sy_value.X_op == O_symbol + && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (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 = &(symbol_next (symbolP)); + } + 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); +} + +void +DEFUN_VOID (s_sect) +{ + /* Strip out the section name */ + char *section_name; + char *section_name_end; + char c; + + unsigned int len; + unsigned int exp; + char *save; + + section_name = input_line_pointer; + c = get_symbol_end (); + section_name_end = input_line_pointer; + + len = section_name_end - section_name; + input_line_pointer++; + save = input_line_pointer; + + SKIP_WHITESPACE (); + if (c == ',') + { + exp = get_absolute_expression (); + } + else if (*input_line_pointer == ',') + { + input_line_pointer++; + exp = get_absolute_expression (); + } + else + { + input_line_pointer = save; + exp = 0; + } + if (exp >= 1000) + { + as_bad (_("subsegment index too high")); + } + + if (strcmp (section_name, ".text") == 0) + { + subseg_set (SEG_TEXT, (subsegT) exp); + } + + if (strcmp (section_name, ".data") == 0) + { + if (flag_readonly_data_in_text) + subseg_set (SEG_TEXT, (subsegT) exp + 1000); + else + subseg_set (SEG_DATA, (subsegT) exp); + } + + *section_name_end = c; +} + +#endif /* ! BFD_ASSEMBLER */ + +/* end of obj-aout.c */ diff --git a/gas/config/obj-aout.h b/gas/config/obj-aout.h new file mode 100644 index 0000000000..339070e093 --- /dev/null +++ b/gas/config/obj-aout.h @@ -0,0 +1,239 @@ +/* obj-aout.h, a.out object file format for gas, the assembler. + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 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. */ + +/* 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 */ + +/* 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((S)->bsym)->other = (V)) +#define S_SET_TYPE(S,T) (aout_symbol((S)->bsym)->type = (T)) +#define S_SET_DESC(S,D) (aout_symbol((S)->bsym)->desc = (D)) +#define S_GET_OTHER(S) (aout_symbol((S)->bsym)->other) +#define S_GET_TYPE(S) (aout_symbol((S)->bsym)->type) +#define S_GET_DESC(S) (aout_symbol((S)->bsym)->desc) + +asection *text_section, *data_section, *bss_section; + +#define obj_frob_symbol(S,PUNT) obj_aout_frob_symbol (S, &PUNT) +#define obj_frob_file() obj_aout_frob_file () +extern void obj_aout_frob_symbol PARAMS ((struct symbol *, int *)); +extern void obj_aout_frob_file 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 syntaxic 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) + +#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_symbol_new_hook(s) {;} + +#define EMIT_SECTION_SYMBOLS 0 + +#define AOUT_STABS + +/* end of obj-aout.h */ diff --git a/gas/config/obj-bout.c b/gas/config/obj-bout.c new file mode 100644 index 0000000000..c9b80f5733 --- /dev/null +++ b/gas/config/obj-bout.c @@ -0,0 +1,348 @@ +/* b.out object file format + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 1996 + 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" +const short /* in: segT out: N_TYPE bits */ + 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, +}; + +static void obj_bout_line PARAMS ((int)); + +const pseudo_typeS obj_pseudo_table[] = +{ + {"line", obj_bout_line, 0}, /* source code line number */ + +/* coff debugging directives. Currently ignored silently */ + {"def", s_ignore, 0}, + {"dim", s_ignore, 0}, + {"endef", s_ignore, 0}, + {"ln", s_ignore, 0}, + {"scl", s_ignore, 0}, + {"size", s_ignore, 0}, + {"tag", s_ignore, 0}, + {"type", s_ignore, 0}, + {"val", s_ignore, 0}, + +/* other stuff we don't handle */ + {"ABORT", s_ignore, 0}, + {"ident", s_ignore, 0}, + + {NULL} /* end sentinel */ +}; /* obj_pseudo_table */ + +/* 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 + || fixP->fx_r_type != NO_RELOC) + { + 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; + + tc_bout_fix_to_chars (*where, fixP, segment_address_in_file); + *where += sizeof (struct relocation_info); + } /* if there's a symbol */ + } /* for each fixup */ + +} /* emit_relocations() */ + +/* Aout file generation & utilities */ + +/* Convert a lvalue to machine dependent data */ +void +obj_header_append (where, headers) + char **where; + object_headers *headers; +{ + /* Always leave in host byte order */ + + headers->header.a_talign = section_alignment[SEG_TEXT]; + + if (headers->header.a_talign < 2) + { + headers->header.a_talign = 2; + } /* force to at least 2 */ + + headers->header.a_dalign = section_alignment[SEG_DATA]; + headers->header.a_balign = section_alignment[SEG_BSS]; + + headers->header.a_tload = 0; + headers->header.a_dload = md_section_align (SEG_DATA, H_GET_TEXT_SIZE (headers)); + + headers->header.a_relaxable = linkrelax; + +#ifdef CROSS_COMPILE + md_number_to_chars (*where, headers->header.a_magic, sizeof (headers->header.a_magic)); + *where += sizeof (headers->header.a_magic); + 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); + md_number_to_chars (*where, headers->header.a_tload, sizeof (headers->header.a_tload)); + *where += sizeof (headers->header.a_tload); + md_number_to_chars (*where, headers->header.a_dload, sizeof (headers->header.a_dload)); + *where += sizeof (headers->header.a_dload); + md_number_to_chars (*where, headers->header.a_talign, sizeof (headers->header.a_talign)); + *where += sizeof (headers->header.a_talign); + md_number_to_chars (*where, headers->header.a_dalign, sizeof (headers->header.a_dalign)); + *where += sizeof (headers->header.a_dalign); + md_number_to_chars (*where, headers->header.a_balign, sizeof (headers->header.a_balign)); + *where += sizeof (headers->header.a_balign); + md_number_to_chars (*where, headers->header.a_relaxable, sizeof (headers->header.a_relaxable)); + *where += sizeof (headers->header.a_relaxable); +#else /* ! CROSS_COMPILE */ + append (where, (char *) &headers->header, sizeof (headers->header)); +#endif /* ! CROSS_COMPILE */ +} /* a_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)); +} /* obj_symbol_to_chars() */ + +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. */ + 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); + + obj_symbol_to_chars (where, symbolP); + S_SET_NAME (symbolP, temp); + } +} /* emit_symbols() */ + +void +obj_symbol_new_hook (symbolP) + symbolS *symbolP; +{ + S_SET_OTHER (symbolP, 0); + S_SET_DESC (symbolP, 0); +} + +static void +obj_bout_line (ignore) + int ignore; +{ + /* 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_bout_line() */ + +void +obj_read_begin_hook () +{ +} + +void +obj_crawl_symbol_chain (headers) + object_headers *headers; +{ + symbolS **symbolPP; + symbolS *symbolP; + int symbol_number = 0; + + tc_crawl_symbol_chain (headers); + + symbolPP = &symbol_rootP; /*->last symbol chain link. */ + while ((symbolP = *symbolPP) != NULL) + { + if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_DATA)) + { + S_SET_SEGMENT (symbolP, SEG_TEXT); + } /* if pusing data into text */ + + resolve_symbol_value (symbolP, 1); + + /* Skip symbols which were equated to undefined or common + symbols. */ + if (symbolP->sy_value.X_op == O_symbol + && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (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 (1 + && !S_IS_REGISTER (symbolP) + && (!S_GET_NAME (symbolP) + || S_IS_DEBUG (symbolP) +#ifdef TC_I960 + /* FIXME-SOON this ifdef seems highly dubious to me. xoxorich. */ + || !S_IS_DEFINED (symbolP) + || S_IS_EXTERNAL (symbolP) +#endif /* TC_I960 */ + || (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 = &(symbol_next (symbolP)); + } + else + { + if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP)) + { + as_bad (_("Local symbol %s never defined"), 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 (where, S_GET_NAME (symbolP), (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1)); + } /* walk symbol chain */ +} + +/* end of obj-bout.c */ diff --git a/gas/config/obj-bout.h b/gas/config/obj-bout.h new file mode 100644 index 0000000000..ec539a0cf4 --- /dev/null +++ b/gas/config/obj-bout.h @@ -0,0 +1,316 @@ +/* b.out object file format + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 1996 + 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, Cambridge, MA + 02139, USA. */ + +/* + * This file is a modified version of 'a.out.h'. It is to be used in all GNU + * tools modified to support the i80960 b.out format (or tools that operate on + * object files created by such tools). + * + * All i80960 development is done in a CROSS-DEVELOPMENT environment. I.e., + * object code is generated on, and executed under the direction of a symbolic + * debugger running on, a host system. We do not want to be subject to the + * vagaries of which host it is or whether it supports COFF or a.out format, or + * anything else. We DO want to: + * + * o always generate the same format object files, regardless of host. + * + * o have an 'a.out' header that we can modify for our own purposes + * (the 80960 is typically an embedded processor and may require + * enhanced linker support that the normal a.out.h header can't + * accommodate). + * + * As for byte-ordering, the following rules apply: + * + * o Text and data that is actually downloaded to the target is always + * in i80960 (little-endian) order. + * + * o All other numbers (in the header, symbols, relocation directives) + * are in host byte-order: object files CANNOT be lifted from a + * little-end host and used on a big-endian (or vice versa) without + * modification. + * ==> THIS IS NO LONGER TRUE USING BFD. WE CAN GENERATE ANY BYTE ORDER + * FOR THE HEADER, AND READ ANY BYTE ORDER. PREFERENCE WOULD BE TO + * USE LITTLE-ENDIAN BYTE ORDER THROUGHOUT, REGARDLESS OF HOST. <== + * + * o The downloader ('comm960') takes care to generate a pseudo-header + * with correct (i80960) byte-ordering before shipping text and data + * off to the NINDY monitor in the target systems. Symbols and + * relocation info are never sent to the target. + */ + + +#define OBJ_BOUT 1 + +#define OUTPUT_FLAVOR bfd_target_aout_flavour + +#include "targ-cpu.h" + +#define OBJ_DEFAULT_OUTPUT_FILE_NAME "b.out" + +extern const short seg_N_TYPE[]; +extern const segT N_TYPE_seg[]; + +#define BMAGIC 0415 +/* We don't accept the following (see N_BADMAG macro). + * They're just here so GNU code will compile. + */ +#define OMAGIC 0407 /* old impure format */ +#define NMAGIC 0410 /* read-only text */ +#define ZMAGIC 0413 /* demand load format */ + +#ifndef DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE +#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (BMAGIC) +#endif /* DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE */ + +/* FILE HEADER + * All 'lengths' are given as a number of bytes. + * All 'alignments' are for relinkable files only; an alignment of + * 'n' indicates the corresponding segment must begin at an + * address that is a multiple of (2**n). + */ +struct exec + { + /* Standard stuff */ + unsigned long a_magic; /* Identifies this as a b.out file */ + unsigned long a_text; /* Length of text */ + unsigned long a_data; /* Length of data */ + unsigned long a_bss; /* Length of runtime uninitialized data area */ + unsigned long a_syms; /* Length of symbol table */ + unsigned long a_entry; /* Runtime start address */ + unsigned long a_trsize; /* Length of text relocation info */ + unsigned long a_drsize; /* Length of data relocation info */ + + /* Added for i960 */ + unsigned long a_tload; /* Text runtime load address */ + unsigned long a_dload; /* Data runtime load address */ + unsigned char a_talign; /* Alignment of text segment */ + unsigned char a_dalign; /* Alignment of data segment */ + unsigned char a_balign; /* Alignment of bss segment */ + unsigned char a_relaxable; /* Contains enough info to relax */ + }; + +#define N_BADMAG(x) (((x).a_magic)!=BMAGIC) +#define N_TXTOFF(x) ( sizeof(struct exec) ) +#define N_DATOFF(x) ( N_TXTOFF(x) + (x).a_text ) +#define N_TROFF(x) ( N_DATOFF(x) + (x).a_data ) +#define N_DROFF(x) ( N_TROFF(x) + (x).a_trsize ) +#define N_SYMOFF(x) ( N_DROFF(x) + (x).a_drsize ) +#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms ) + +/* A single entry in the symbol table + */ +struct nlist + { + union + { + char *n_name; + struct nlist *n_next; + long n_strx; /* Index into string table */ + } + n_un; + unsigned char n_type; /* See below */ + char n_other; /* Used in i80960 support -- see below */ + short n_desc; + unsigned long n_value; + }; + +typedef struct nlist obj_symbol_type; + +/* Legal values of n_type + */ +#define N_UNDF 0 /* Undefined symbol */ +#define N_ABS 2 /* Absolute symbol */ +#define N_TEXT 4 /* Text symbol */ +#define N_DATA 6 /* Data symbol */ +#define N_BSS 8 /* BSS symbol */ +#define N_FN 31 /* Filename symbol */ + +#define N_EXT 1 /* External symbol (OR'd in with one of above) */ +#define N_TYPE 036 /* Mask for all the type bits */ +#define N_STAB 0340 /* Mask for all bits used for SDB entries */ + +#ifndef CUSTOM_RELOC_FORMAT +struct relocation_info + { + int r_address; /* File address of item to be relocated */ + unsigned + r_index:24, /* Index of symbol on which relocation is based*/ + r_pcrel:1, /* 1 => relocate PC-relative; else absolute + * On i960, pc-relative implies 24-bit + * address, absolute implies 32-bit. + */ + r_length:2, /* Number of bytes to relocate: + * 0 => 1 byte + * 1 => 2 bytes + * 2 => 4 bytes -- only value used for i960 + */ + r_extern:1, r_bsr:1, /* Something for the GNU NS32K assembler */ + r_disp:1, /* Something for the GNU NS32K assembler */ + r_callj:1, /* 1 if relocation target is an i960 'callj' */ + nuthin:1; /* Unused */ + }; + +#endif /* CUSTOM_RELOC_FORMAT */ + +/* + * Macros to extract information from a symbol table entry. + * This syntaxic 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.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) + +#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) == NULL) + +/* 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) + +/* 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_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)) +/* Set the n_type value */ +#define S_SET_TYPE(s,v) ((s)->sy_symbol.n_type = (v)) + +/* File header macro and type definition */ + +#define H_GET_FILE_SIZE(h) (sizeof(struct exec) + \ + 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)->string_table_size) + +#define H_GET_HEADER_SIZE(h) (sizeof(struct exec)) +#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_MAGIC_NUMBER(h) ((h)->header.a_info) +#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) + +#ifdef EXEC_MACHINE_TYPE +#define H_GET_MACHINE_TYPE(h) ((h)->header.a_machtype) +#endif /* EXEC_MACHINE_TYPE */ +#ifdef EXEC_VERSION +#define H_GET_VERSION(h) ((h)->header.a_version) +#endif /* EXEC_VERSION */ + +#define H_SET_TEXT_SIZE(h,v) ((h)->header.a_text = (v)) +#define H_SET_DATA_SIZE(h,v) ((h)->header.a_data = (v)) +#define H_SET_BSS_SIZE(h,v) ((h)->header.a_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) * \ + sizeof(struct nlist)) + +#define H_SET_MAGIC_NUMBER(h,v) ((h)->header.a_magic = (v)) + +#define H_SET_ENTRY_POINT(h,v) ((h)->header.a_entry = (v)) +#define H_SET_STRING_SIZE(h,v) ((h)->string_table_size = (v)) +#ifdef EXEC_MACHINE_TYPE +#define H_SET_MACHINE_TYPE(h,v) ((h)->header.a_machtype = (v)) +#endif /* EXEC_MACHINE_TYPE */ +#ifdef EXEC_VERSION +#define H_SET_VERSION(h,v) ((h)->header.a_version = (v)) +#endif /* EXEC_VERSION */ + +typedef struct + { + struct exec header; /* a.out header */ + long string_table_size; /* names + '\0' + sizeof(int) */ + } + +object_headers; + +/* unused hooks. */ +#define OBJ_EMIT_LINENO(a, b, c) {;} +#define obj_pre_write_hook(a) {;} + +#if __STDC__ +struct fix; +#endif +extern void tc_aout_fix_to_chars PARAMS ((char *where, + struct fix *fixP, + relax_addressT segment_address)); +extern void tc_bout_fix_to_chars PARAMS ((char *where, + struct fix *fixP, + relax_addressT segment_address)); + +#define AOUT_STABS + +/* end of obj-bout.h */ diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c new file mode 100644 index 0000000000..5639fbed96 --- /dev/null +++ b/gas/config/obj-coff.c @@ -0,0 +1,4482 @@ +/* coff object file format + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 1998 + 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 + +static void obj_coff_bss PARAMS ((int)); +const char *s_get_name PARAMS ((symbolS * s)); +static symbolS *def_symbol_in_progress; + + +/* stack stuff */ +typedef struct + { + unsigned long chunk_size; + unsigned long element_size; + unsigned long size; + char *data; + unsigned long pointer; + } +stack; + +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 structres. + */ + +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; +{ + 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; +{ + 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 (); + +#ifdef BFD_ASSEMLER + 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 void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *)); + +#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 (sym->bsym)->native[1]; + p = coffsymbol (val->bsym)->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 (sym->bsym)->native[1]; + p = coffsymbol (val->bsym)->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 (sym->bsym)->native->u.syment.n_type; +} + +int +S_SET_DATA_TYPE (sym, val) + symbolS *sym; + int val; +{ + coffsymbol (sym->bsym)->native->u.syment.n_type = val; + return val; +} + +int +S_GET_STORAGE_CLASS (sym) + symbolS *sym; +{ + return coffsymbol (sym->bsym)->native->u.syment.n_sclass; +} + +int +S_SET_STORAGE_CLASS (sym, val) + symbolS *sym; + int val; +{ + coffsymbol (sym->bsym)->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) + char *filename; +{ + symbolS *symbolP; + + 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); + + symbolP->bsym->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 (symbolP->bsym)->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; + int offset; + int num; +{ + struct line_no *new_line = + (struct line_no *) xmalloc (sizeof (struct line_no)); + if (!current_lineno_sym) + { + abort (); + } + 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 (current_lineno_sym->bsym)->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 (!appline) + { + add_lineno (frag_now, frag_now_fix (), l); + } + + if (appline) + new_logical_line ((char *) NULL, l - 1); + +#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 (); +} + +/* + * 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; +{ + 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); + 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; +{ + symbolS *symbolP; + + /* 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 = bfd_asymbol_name (def_symbol_in_progress->bsym); + if (name[1] == 'b' && name[2] == 'f') + { + if (! in_function ()) + as_warn (_("`%s' symbol without preceding function"), name); +/* SA_SET_SYM_LNNO (def_symbol_in_progress, 12345);*/ + /* Will need relocating */ + SF_SET_PROCESS (def_symbol_in_progress); + clear_function (); + } + } + 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: + SF_SET_DEBUG (def_symbol_in_progress); + S_SET_SEGMENT (def_symbol_in_progress, absolute_section); + break; + + case C_MOS: + case C_MOE: + case C_MOU: + case C_EOS: + 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; + + 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 + SEG_ABSOLUTE or untagged SEG_DEBUG it never merges. */ + + /* 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 + || (!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 + || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL) + { + if (def_symbol_in_progress != 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; +{ + 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; +{ + 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, coff_line_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) coff_line_base); + } +#endif +} + +static void +obj_coff_size (ignore) + int ignore; +{ + 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; +{ + 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; +{ + 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; +{ + 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; +{ + 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, ".")) + { + 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); + } + /* 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; +static symbolS *coff_last_bf; + +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) + && (real = symbol_find_base (S_GET_NAME (symp), DO_NOT_STRIP)) + && real != symp) + { + c_symbol_merge (symp, real); + *punt = 1; + } + 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 = &coffsymbol (symp->bsym)->native[1].u.auxent; + 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)) + symp->bsym->flags |= BSF_FUNCTION; + + /* more ... */ + } + + 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 (! symp->sy_used_in_reloc + && ((symp->bsym->flags & BSF_SECTION_SYM) != 0 + || (! S_IS_EXTERNAL (symp) + && ! symp->sy_tc.output + && S_GET_STORAGE_CLASS (symp) != C_FILE))) + *punt = 1; +#endif + + if (set_end != (symbolS *) NULL + && ! *punt + && ((symp->bsym->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 + && ! *punt) + set_end = next_set_end; + + 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; + } + + if (coffsymbol (symp->bsym)->lineno) + { + int i; + struct line_no *lptr; + alent *l; + + lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno; + for (i = 0; lptr; lptr = lptr->next) + i++; + lptr = (struct line_no *) coffsymbol (symp->bsym)->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 (symp->bsym)->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; + l[i] = lptr->l; + lptr = lptr->next; + } + } +} + +void +coff_adjust_section_syms (abfd, sec, x) + bfd *abfd; + asection *sec; + PTR x; +{ + 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); + 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 + * But if the argument is not a quoted string, treat it as a + * subsegment number. + */ + +void +obj_coff_section (ignore) + int ignore; +{ + /* Strip out the section name */ + char *section_name; + char c; + char *name; + unsigned int exp; + flagword flags; + 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; break; + case 'd': + case 'w': flags &=~ SEC_READONLY; break; + case 'x': flags |= SEC_CODE; break; + case 'r': flags |= 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); + + if (flags != SEC_NO_FLAGS) + { + flagword oldflags; + + oldflags = bfd_get_section_flags (stdoutput, sec); + oldflags &= SEC_LINK_ONCE | SEC_LINK_DUPLICATES; + flags |= oldflags; + + 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 ())); + } + + 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; + + /* The COFF back end in BFD requires that all section sizes be + rounded up to multiples of the corresponding section alignments. + Seems kinda silly to me, but that's the way it is. */ + size = bfd_get_section_size_before_reloc (sec); + mask = ((bfd_vma) 1 << (bfd_vma) sec->alignment_power) - 1; + if (size & mask) + { + size = (size + mask) & ~mask; + bfd_set_section_size (stdoutput, sec, size); + } + + /* 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. */ + if (size != 0 + || sec == text_section + || sec == data_section + || sec == bss_section) + { + 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 *) alloca (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 + +#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 an internal segment into a section # + suitable for insertion into a coff symbol table + */ + +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 +*/ +static symbolS *previous_file_symbol; +void c_symbol_merge (); +static int line_base; + +symbolS *c_section_symbol (); +bfd *abfd; + +static void fixup_segment PARAMS ((segment_info_type *segP, + segT this_segment_type)); + + +static void fixup_mdeps PARAMS ((fragS *, + object_headers *, + segT)); + + +static void fill_section PARAMS ((bfd * abfd, + object_headers *, + unsigned long *)); + + +static int c_line_new PARAMS ((symbolS * symbol, long paddr, + int line_number, + fragS * frag)); + + +static void w_symbols PARAMS ((bfd * abfd, char *where, + symbolS * symbol_rootP)); + +static void adjust_stab_section PARAMS ((bfd *abfd, segT seg)); + +static void obj_coff_lcomm PARAMS ((int)); +static void obj_coff_text PARAMS ((int)); +static void obj_coff_data PARAMS ((int)); +static void obj_coff_ident PARAMS ((int)); +void obj_coff_section PARAMS ((int)); + +/* Section stuff + + We allow more than just the standard 3 sections, infact, we allow + 40 sections, (though the usual three have to be there). + + This structure performs the mappings for us: +*/ + + +typedef struct +{ + segT seg_t; + int i; +} seg_info_type; + +static const seg_info_type 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 (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).seg_t; +} + +/* 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; + 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: + assert (frag->fr_symbol == 0); + 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: + { + 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)) + { +#ifdef TC_A29K + 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, 1); + 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 emited, 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_write ((PTR) external_reloc_vec, 1, 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 postions +*/ +static void +fill_section (abfd, h, file_cursor) + bfd * abfd; + object_headers *h; + 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; + + 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 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 + } + 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: + assert (frag->fr_symbol == 0); + case rs_fill: + case rs_align: + case rs_align_code: + 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_write (buffer, s->s_size, 1, 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, 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_write (buffer, i, 1, abfd); + bfd_write (buffero, H_GET_SIZEOF_OPTIONAL_HEADER (h), 1, 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_write (buffer, size, 1, 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) + { + as_warn (_(".ln pseudo-op inside .def/.endef: ignored.")); + demand_empty_rest_of_line (); + return; + } /* wrong context */ + + 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 (); +} + +/* + * 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; +{ + 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 (); + + def_symbol_in_progress = (symbolS *) obstack_alloc (¬es, 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; +{ + 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; + } /* 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, SEG_DEBUG); + 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: + 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")); + } /* missing function symbol */ + 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; + } /* 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 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 not already in place */ + } /* if function */ + } /* normal or mergable */ + + 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); + } /* 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; +{ + 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; +{ + 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; +{ + 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; +{ + 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; +{ + 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); + } /* 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; +{ + 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; +{ + 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, ".")) + { + 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 oposite (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 not local but dup'd */ + + if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_E1)) + { + S_SET_SEGMENT (symbolP, SEG_E0); + } /* push data into text */ + + resolve_symbol_value (symbolP, 1); + + 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 */ + register 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); + } /* make it at least 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; + } /* no one points at the first .file symbol */ + } /* if debug or tag or eos or file */ + +#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; + } /* fix "long" names */ + + symbolP->sy_number = symbol_number; + symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP); + } /* if local symbol */ + } /* traverse the symbol list */ + 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); + + /* and process */ + if (SF_GET_STRING (tmp)) + { + tmp->sy_name_offset = string_byte_count; + string_byte_count += strlen (S_GET_NAME (tmp)) + 1; + } + else + { + tmp->sy_name_offset = 0; + } /* fix "long" names */ + + tmp->sy_number = symbol_number; + symbol_number += 1 + S_GET_NUMBER_AUXILIARY (tmp); + } /* append the entire extern chain */ + + 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; +{ + 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 (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 */ + 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_write (buffer, 1, 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; +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; + + for (frchain_ptr = frchain_root; + frchain_ptr != (struct frchain *) NULL; + frchain_ptr = frchain_ptr->frch_next) + { + /* 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. */ + + subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg); +#ifndef SUB_SEGMENT_ALIGN +#define SUB_SEGMENT_ALIGN(SEG) 1 +#endif +#ifdef md_do_align + md_do_align (SUB_SEGMENT_ALIGN (now_seg), (char *) NULL, 0, 0, + alignment_done); +#endif + frag_align (SUB_SEGMENT_ALIGN (now_seg), NOP_OPCODE, 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); + } + + 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_write (buffer1, 1, 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) == false) + 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; +{ + /* 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; +{ + subseg_new (".text", get_absolute_expression ()); +} + + +static void +obj_coff_data (ignore) + int ignore; +{ + 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; +{ + 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)); + } /* take the most we have */ + + 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 all the auxiliary information */ + + /* Move the debug flags. */ + SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug)); +} /* c_symbol_merge() */ + +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); + } +} /* c_dot_file_symbol() */ + +/* + * 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; +} /* c_section_symbol() */ + +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. */ + register 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); + } + +} /* w_symbols() */ + +static void +obj_coff_lcomm (ignore) + int ignore; +{ + 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; + segT this_segment; +{ + subseg_change (this_segment, 0); + while (frags) + { + switch (frags->fr_type) + { + case rs_align: + case rs_align_code: + 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; +{ + register fixS * fixP; + register symbolS *add_symbolP; + register symbolS *sub_symbolP; + long add_number; + register int size; + register char *place; + register long where; + register char pcrel; + register fragS *fragP; + register 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, 1); + + 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, 1); + + 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 there is an addend */ + + 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 absolute */ + } + } /* if sub_symbolP */ + + 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 + reloc_callj (fixP); /* See comment about reloc_callj() above*/ +#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) + /* 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; + } /* COBR */ +#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 . */ + /* 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 . */ + if (S_IS_COMMON (add_symbolP)) + add_number += S_GET_VALUE (add_symbolP); +#endif + break; + + + } /* switch on symbol seg */ + } /* if not in local seg */ + } /* if there was a + symbol */ + + if (pcrel) + { +#if !defined(TC_M88K) && !(defined(TE_PE) && defined(TC_I386)) && !defined(TC_A29K) + /* 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 there's an add_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 + } /* if pcrel */ + + 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 + } /* not a bit fix */ + /* Once this fix has been applied, we don't have to output + anything nothing more need be done. */ +#ifdef MD_APPLY_FIX3 + md_apply_fix3 (fixP, (valueT *) &add_number, this_segment_type); +#else + md_apply_fix (fixP, add_number); +#endif + } /* For each fixS in this segment. */ +} /* fixup_segment() */ + +#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 obj_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}, + {"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}, +#ifndef BFD_ASSEMBLER + {"use", obj_coff_section, 0}, + {"text", obj_coff_text, 0}, + {"data", obj_coff_data, 0}, + {"lcomm", obj_coff_lcomm, 0}, + {"ident", obj_coff_ident, 0}, +#else + {"optim", s_ignore, 0}, /* For sun386i cc (?) */ + {"ident", s_ignore, 0}, /* we don't yet handle this. */ +#endif + {"version", s_ignore, 0}, + {"ABORT", s_abort, 0}, +#ifdef TC_M88K + /* The m88k uses sdef instead of def. */ + {"sdef", obj_coff_def, 0}, +#endif + {NULL} /* end sentinel */ +}; /* obj_pseudo_table */ + +#ifdef BFD_ASSEMBLER + +/* Support for a COFF emulation. */ + +static void +coff_pop_insert () +{ + pop_insert (obj_pseudo_table); +} + +static int +coff_sec_sym_ok_for_reloc (sec) + asection *sec; +{ + return 0; +} + +static void +no_func () +{ + abort (); +} + +const struct format_ops coff_format_ops = +{ + bfd_target_coff_flavour, + 0, + 1, + coff_frob_symbol, + no_func, + coff_frob_file_after_relocs, + 0, 0, + 0, 0, + 0, +#if 0 + obj_generate_asm_lineno, +#else + no_func, +#endif +#if 0 + obj_stab, +#else + no_func, +#endif + coff_sec_sym_ok_for_reloc, + coff_pop_insert, +#if 0 + obj_set_ext, +#else + no_func, +#endif + coff_obj_read_begin_hook, + coff_obj_symbol_new_hook, +}; + +#endif diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h new file mode 100644 index 0000000000..465047796f --- /dev/null +++ b/gas/config/obj-coff.h @@ -0,0 +1,841 @@ +/* coff object file format + Copyright (C) 1989, 90, 91, 92, 94, 95, 96, 97, 98, 1999 + 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_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 +#include "coff/sh.h" +#define TARGET_FORMAT \ + (shl \ + ? (sh_small ? "coff-shl-small" : "coff-shl") \ + : (sh_small ? "coff-sh-small" : "coff-sh")) +#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_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 ((struct symbol *)); +#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: + + #ifdef BFD_ASSEMBLER + + #else + + #endif + + 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 struct symbol * +#define sy_tc bal +#endif + +#define OBJ_SYMFIELD_TYPE unsigned long +#define sy_obj sy_flags + +#define SYM_AUXENT(S) (&coffsymbol ((S)->bsym)->native[1].u.auxent) +#define SYM_AUXINFO(S) (&coffsymbol ((S)->bsym)->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((s)->bsym)->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 ((struct symbol *, int)); +extern int S_SET_STORAGE_CLASS PARAMS ((struct symbol *, int)); +extern int S_GET_STORAGE_CLASS PARAMS ((struct symbol *)); +extern void SA_SET_SYM_ENDNDX PARAMS ((struct symbol *, struct symbol *)); + +/* 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) ((s)->sy_flags) +#define SF_GET_DEBUG(s) ((s)->bsym->flags & BSF_DEBUGGING) +#define SF_SET_DEBUG(s) ((s)->bsym->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 ((struct symbol *)); + + +void c_dot_file_symbol PARAMS ((char *filename)); +#define obj_app_file c_dot_file_symbol + +extern void coff_frob_symbol PARAMS ((struct symbol *, 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 struct symbol *coff_last_function; + +/* Forward the segment of a forwarded symbol, handle assignments that + just copy symbol values, etc. */ +#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 + +/* 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 */ + +#ifdef TC_A29K +/* 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 usefull 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 syntaxic 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)) +/* 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 convinience */ +#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 ((struct symbol * 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 ((struct symbol *)); +#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 */ + +/* 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) + +#endif /* OBJ_FORMAT_H */ diff --git a/gas/config/obj-ecoff.c b/gas/config/obj-ecoff.c new file mode 100644 index 0000000000..ec3ce8811b --- /dev/null +++ b/gas/config/obj-ecoff.c @@ -0,0 +1,309 @@ +/* ECOFF object file format. + Copyright (C) 1993, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc. + Contributed by Cygnus Support. + This file was put together by Ian Lance Taylor . + + 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)); + +/* 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 } +}; + +/* 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; + asection *sec; + HDRR *hdr; + char *buf; + char *set; + + /* 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 (sizeof (names) / sizeof (names[0])) + + addr = 0; + { + /* Sections that match names, order to be straightened out later. */ + asection *secs[n_names]; + /* Linked list of sections with non-matching names. Random ordering. */ + asection *other_sections = 0; + /* Pointer to next section, since we're destroying the original + ordering. */ + asection *next; + + int i; + + for (i = 0; i < n_names; i++) + secs[i] = 0; + for (sec = stdoutput->sections; sec != (asection *) NULL; sec = next) + { + next = sec->next; + for (i = 0; i < n_names; i++) + if (!strcmp (sec->name, names[i])) + { + secs[i] = sec; + break; + } + if (i == n_names) + { + bfd_set_section_vma (stdoutput, sec, addr); + addr += bfd_section_size (stdoutput, sec); + sec->next = other_sections; + other_sections = sec; + } + } + for (i = 0; i < n_names; i++) + if (secs[i]) + { + sec = secs[i]; + bfd_set_section_vma (stdoutput, sec, addr); + addr += bfd_section_size (stdoutput, sec); + } + for (i = n_names - 1; i >= 0; i--) + if (secs[i]) + { + sec = secs[i]; + sec->next = other_sections; + other_sections = sec; + } + stdoutput->sections = other_sections; + } + + /* 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 + + /* 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")); + } +} + +/* 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 (sym->bsym) == bfd_target_ecoff_flavour); + esym = ecoffsymbol (sym->bsym); + 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; +{ + return 1; +} + +static void +obj_ecoff_frob_symbol (sym, puntp) + symbolS *sym; + int *puntp; +{ + ecoff_frob_symbol (sym); +} + +static void +ecoff_pop_insert () +{ + pop_insert (obj_pseudo_table); +} + +const struct format_ops ecoff_format_ops = +{ + bfd_target_ecoff_flavour, + 0, + 1, + obj_ecoff_frob_symbol, + ecoff_frob_file, + 0, + 0, 0, + 0, 0, + 0, + ecoff_generate_asm_lineno, + ecoff_stab, + ecoff_sec_sym_ok_for_reloc, + ecoff_pop_insert, + ecoff_set_ext, + ecoff_read_begin_hook, + ecoff_symbol_new_hook, +}; diff --git a/gas/config/obj-ecoff.h b/gas/config/obj-ecoff.h new file mode 100644 index 0000000000..427e619ee1 --- /dev/null +++ b/gas/config/obj-ecoff.h @@ -0,0 +1,67 @@ +/* ECOFF object file format header file. + Copyright (C) 1993, 94, 95, 96, 97, 1999 Free Software Foundation, Inc. + Contributed by Cygnus Support. + Written by Ian Lance Taylor . + + 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). */ + +#define TARGET_SYMBOL_FIELDS \ + struct efdr *ecoff_file; \ + struct localsym *ecoff_symbol; \ + valueT ecoff_extern_size; + +/* Modify the ECOFF symbol. */ +#define obj_frob_symbol(symp, punt) ecoff_frob_symbol (symp) + +/* 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 ((struct symbol *, EXTR *)); diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c new file mode 100644 index 0000000000..f50c4b7257 --- /dev/null +++ b/gas/config/obj-elf.c @@ -0,0 +1,1764 @@ +/* ELF object file format + Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 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. */ + +#define OBJ_HEADER "obj-elf.h" +#include "as.h" +#include "subsegs.h" +#include "obstack.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 + +static bfd_vma elf_s_get_size PARAMS ((symbolS *)); +static void elf_s_set_size PARAMS ((symbolS *, bfd_vma)); +static bfd_vma elf_s_get_align PARAMS ((symbolS *)); +static void elf_s_set_align PARAMS ((symbolS *, bfd_vma)); +static void elf_copy_symbol_attributes PARAMS ((symbolS *, symbolS *)); +static int elf_sec_sym_ok_for_reloc PARAMS ((asection *)); +static void adjust_stab_sections PARAMS ((bfd *, asection *, PTR)); + +#ifdef NEED_ECOFF_DEBUG +static boolean elf_get_extr PARAMS ((asymbol *, EXTR *)); +static void elf_set_index PARAMS ((asymbol *, bfd_size_type)); +#endif + +static void obj_elf_line PARAMS ((int)); +void obj_elf_version PARAMS ((int)); +static void obj_elf_size PARAMS ((int)); +static void obj_elf_type PARAMS ((int)); +static void obj_elf_ident PARAMS ((int)); +static void obj_elf_weak PARAMS ((int)); +static void obj_elf_local PARAMS ((int)); +static void obj_elf_common PARAMS ((int)); +static void obj_elf_symver PARAMS ((int)); +static void obj_elf_vtable_inherit PARAMS ((int)); +static void obj_elf_vtable_entry PARAMS ((int)); +static void obj_elf_data PARAMS ((int)); +static void obj_elf_text PARAMS ((int)); +static void obj_elf_subsection PARAMS ((int)); + +static const pseudo_typeS elf_pseudo_table[] = +{ + {"comm", obj_elf_common, 0}, + {"ident", obj_elf_ident, 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}, + {"size", obj_elf_size, 0}, + {"type", obj_elf_type, 0}, + {"version", obj_elf_version, 0}, + {"weak", obj_elf_weak, 0}, + + /* 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", obj_elf_vtable_inherit, 0}, + {"vtable_entry", obj_elf_vtable_entry, 0}, + + /* These are used for dwarf. */ + {"2byte", cons, 2}, + {"4byte", cons, 4}, + {"8byte", cons, 8}, + + /* We need to trap the section changing calls to handle .previous. */ + {"data", obj_elf_data, 0}, + {"text", obj_elf_text, 0}, + + /* End sentinel. */ + {NULL}, +}; + +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} /* end sentinel */ +}; + +#undef NO_RELOC +#include "aout/aout64.h" + +/* This is called when the assembler starts. */ + +void +elf_begin () +{ + /* Add symbols for the known sections to the symbol table. */ + symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput, + TEXT_SECTION_NAME))); + symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput, + DATA_SECTION_NAME))); + symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput, + BSS_SECTION_NAME))); +} + +void +elf_pop_insert () +{ + pop_insert (elf_pseudo_table); + if (ECOFF_DEBUGGING) + pop_insert (ecoff_debug_pseudo_table); +} + +static bfd_vma +elf_s_get_size (sym) + symbolS *sym; +{ + return S_GET_SIZE (sym); +} + +static void +elf_s_set_size (sym, sz) + symbolS *sym; + bfd_vma sz; +{ + S_SET_SIZE (sym, sz); +} + +static bfd_vma +elf_s_get_align (sym) + symbolS *sym; +{ + return S_GET_ALIGN (sym); +} + +static void +elf_s_set_align (sym, align) + symbolS *sym; + bfd_vma align; +{ + S_SET_ALIGN (sym, align); +} + +static void +elf_copy_symbol_attributes (dest, src) + symbolS *dest, *src; +{ + OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src); +} + +static int +elf_sec_sym_ok_for_reloc (sec) + asection *sec; +{ + return obj_sec_sym_ok_for_reloc (sec); +} + +void +elf_file_symbol (s) + char *s; +{ + symbolS *sym; + + sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0); + sym->sy_frag = &zero_address_frag; + sym->bsym->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 +} + +static void +obj_elf_common (ignore) + int ignore; +{ + char *name; + char c; + char *p; + int temp, 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; + } + input_line_pointer++; /* skip ',' */ + if ((temp = get_absolute_expression ()) < 0) + { + 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) + { + as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."), + S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size); + } + } + know (symbolP->sy_frag == &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 (symbolP->local) + { + segT old_sec; + int old_subsec; + char *pfrag; + int align; + + /* allocate_bss: */ + old_sec = now_seg; + old_subsec = now_subseg; + 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 (bss_section, align); + subseg_set (bss_section, 0); + if (align) + frag_align (align, 0, 0); + if (S_GET_SEGMENT (symbolP) == bss_section) + symbolP->sy_frag->fr_symbol = 0; + 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); + subseg_set (old_sec, old_subsec); + } + else + { + allocate_common: + S_SET_VALUE (symbolP, (valueT) size); + S_SET_ALIGN (symbolP, temp); + 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; + } + + symbolP->bsym->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 +obj_elf_local (ignore) + int ignore; +{ + 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); + 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 (ignore) + int ignore; +{ + 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); + 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 segT previous_section; +static int previous_subsection; + +/* 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. */ + +/* Certain named sections have particular defined types, listed on p. + 4-19 of the ABI. */ +struct special_section +{ + const char *name; + int type; + int attributes; +}; + +static struct special_section special_sections[] = +{ + { ".bss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, + { ".comment", SHT_PROGBITS, 0 }, + { ".data", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, + { ".data1", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, + { ".debug", SHT_PROGBITS, 0 }, + { ".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, + { ".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, + { ".line", SHT_PROGBITS, 0 }, + { ".note", SHT_NOTE, 0 }, + { ".rodata", SHT_PROGBITS, SHF_ALLOC }, + { ".rodata1", SHT_PROGBITS, SHF_ALLOC }, + { ".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, + +#ifdef ELF_TC_SPECIAL_SECTIONS + ELF_TC_SPECIAL_SECTIONS +#endif + +#if 0 + /* The following section names are special, but they can not + reasonably appear in assembler code. Some of the attributes are + processor dependent. */ + { ".dynamic", SHT_DYNAMIC, SHF_ALLOC /* + SHF_WRITE */ }, + { ".dynstr", SHT_STRTAB, SHF_ALLOC }, + { ".dynsym", SHT_DYNSYM, SHF_ALLOC }, + { ".got", SHT_PROGBITS, 0 }, + { ".hash", SHT_HASH, SHF_ALLOC }, + { ".interp", SHT_PROGBITS, /* SHF_ALLOC */ }, + { ".plt", SHT_PROGBITS, 0 }, + { ".shstrtab",SHT_STRTAB, 0 }, + { ".strtab", SHT_STRTAB, /* SHF_ALLOC */ }, + { ".symtab", SHT_SYMTAB, /* SHF_ALLOC */ }, +#endif + + { NULL, 0, 0 } +}; + +void +obj_elf_section (xxx) + int xxx; +{ + char *string; + int new_sec; + segT sec; + int type, attr; + int i; + flagword flags; + symbolS *secsym; + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + + if (flag_mri) + { + char mri_type; + + 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; + } + + /* Get name of section. */ + SKIP_WHITESPACE (); + if (*input_line_pointer == '"') + { + string = demand_copy_C_string (&xxx); + if (string == NULL) + { + ignore_rest_of_line (); + return; + } + } + else + { + char *p = input_line_pointer; + char c; + while (0 == strchr ("\n\t,; ", *p)) + p++; + if (p == input_line_pointer) + { + as_warn (_("Missing section name")); + ignore_rest_of_line (); + return; + } + c = *p; + *p = 0; + string = xmalloc ((unsigned long) (p - input_line_pointer + 1)); + strcpy (string, input_line_pointer); + *p = c; + input_line_pointer = p; + } + + /* Switch to the section, creating it if necessary. */ + previous_section = now_seg; + previous_subsection = now_subseg; + + new_sec = bfd_get_section_by_name (stdoutput, string) == NULL; + sec = subseg_new (string, 0); + + /* If this section already existed, we don't bother to change the + flag values. */ + if (! new_sec) + { + while (! is_end_of_line[(unsigned char) *input_line_pointer]) + ++input_line_pointer; + ++input_line_pointer; + +#ifdef md_elf_section_change_hook + md_elf_section_change_hook (); +#endif + + return; + } + + SKIP_WHITESPACE (); + + type = SHT_NULL; + attr = 0; + + if (*input_line_pointer == ',') + { + /* Skip the comma. */ + ++input_line_pointer; + + SKIP_WHITESPACE (); + + if (*input_line_pointer == '"') + { + /* Pick up a string with a combination of a, w, x. */ + ++input_line_pointer; + while (*input_line_pointer != '"') + { + switch (*input_line_pointer) + { + case 'a': + attr |= SHF_ALLOC; + break; + case 'w': + attr |= SHF_WRITE; + break; + case 'x': + attr |= SHF_EXECINSTR; + break; + default: + { + char *bad_msg = _("Bad .section directive: want a,w,x in string"); +#ifdef md_elf_section_letter + int md_attr = md_elf_section_letter (*input_line_pointer, &bad_msg); + if (md_attr) + attr |= md_attr; + else +#endif + { + as_warn (bad_msg); + ignore_rest_of_line (); + return; + } + } + } + ++input_line_pointer; + } + + /* Skip the closing quote. */ + ++input_line_pointer; + + SKIP_WHITESPACE (); + if (*input_line_pointer == ',') + { + ++input_line_pointer; + SKIP_WHITESPACE (); + if (*input_line_pointer == '@' || *input_line_pointer == '%') + { + ++input_line_pointer; + if (strncmp (input_line_pointer, "progbits", + sizeof "progbits" - 1) == 0) + { + type = SHT_PROGBITS; + input_line_pointer += sizeof "progbits" - 1; + } + else if (strncmp (input_line_pointer, "nobits", + sizeof "nobits" - 1) == 0) + { + type = SHT_NOBITS; + input_line_pointer += sizeof "nobits" - 1; + } + else + { +#ifdef md_elf_section_type + int md_type = md_elf_section_type (&input_line_pointer); + if (md_type) + type = md_type; + else +#endif + { + as_warn (_("Unrecognized section type")); + ignore_rest_of_line (); + } + } + } + } + } + else + { + do + { + SKIP_WHITESPACE (); + if (*input_line_pointer != '#') + { + as_warn (_("Bad .section directive - character following name is not '#'")); + ignore_rest_of_line (); + return; + } + ++input_line_pointer; + if (strncmp (input_line_pointer, "write", + sizeof "write" - 1) == 0) + { + attr |= SHF_WRITE; + input_line_pointer += sizeof "write" - 1; + } + else if (strncmp (input_line_pointer, "alloc", + sizeof "alloc" - 1) == 0) + { + attr |= SHF_ALLOC; + input_line_pointer += sizeof "alloc" - 1; + } + else if (strncmp (input_line_pointer, "execinstr", + sizeof "execinstr" - 1) == 0) + { + attr |= SHF_EXECINSTR; + input_line_pointer += sizeof "execinstr" - 1; + } + else + { +#ifdef md_elf_section_word + int md_attr = md_elf_section_word (&input_line_pointer); + if (md_attr) + attr |= md_attr; + else +#endif + { + as_warn (_("Unrecognized section attribute")); + ignore_rest_of_line (); + return; + } + } + SKIP_WHITESPACE (); + } + while (*input_line_pointer++ == ','); + --input_line_pointer; + } + } + + /* See if this is one of the special sections. */ + for (i = 0; special_sections[i].name != NULL; i++) + { + if (string[1] == special_sections[i].name[1] + && strcmp (string, special_sections[i].name) == 0) + { + if (type == SHT_NULL) + type = special_sections[i].type; + else if (type != special_sections[i].type) + as_warn (_("Setting incorrect section type for %s"), string); + + if ((attr &~ special_sections[i].attributes) != 0) + { + /* As a GNU extension, we permit a .note section to be + allocatable. If the linker sees an allocateable + .note section, it will create a PT_NOTE segment in + the output file. */ + if (strcmp (string, ".note") != 0 + || attr != SHF_ALLOC) + as_warn (_("Setting incorrect section attributes for %s"), + string); + } + attr |= special_sections[i].attributes; + + break; + } + } + + 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)); + if (special_sections[i].name == NULL) + { + if (type == SHT_PROGBITS) + flags |= SEC_ALLOC | SEC_LOAD; + else if (type == SHT_NOBITS) + { + flags |= SEC_ALLOC; + flags &=~ SEC_LOAD; + } + +#ifdef md_elf_section_flags + flags = md_elf_section_flags (flags, attr, type); +#endif + } + + /* Prevent SEC_HAS_CONTENTS from being inadvertently set. */ + if (type == SHT_NOBITS) + seg_info (sec)->bss = 1; + + bfd_set_section_flags (stdoutput, sec, flags); + + /* Add a symbol for this section to the symbol table. */ + secsym = symbol_find (string); + if (secsym != NULL) + secsym->bsym = sec->symbol; + else + symbol_table_insert (section_symbol (sec)); + +#ifdef md_elf_section_change_hook + md_elf_section_change_hook (); +#endif + + demand_empty_rest_of_line (); +} + +/* Change to the .data section. */ + +static void +obj_elf_data (i) + 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. */ + +static void +obj_elf_text (i) + 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 (ignore) + int ignore; +{ + 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 () +{ + previous_section = now_seg; + previous_subsection = now_subseg; +} + +void +obj_elf_previous (ignore) + int ignore; +{ + if (previous_section == 0) + { + as_bad (_(".previous without corresponding .section; ignored")); + return; + } + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + + subseg_set (previous_section, previous_subsection); + previous_section = 0; + +#ifdef md_elf_section_change_hook + md_elf_section_change_hook (); +#endif +} + +static void +obj_elf_line (ignore) + int ignore; +{ + /* 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 (); +} + +/* 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 (ignore) + int ignore; +{ + char *name; + char c; + symbolS *sym; + + name = input_line_pointer; + c = get_symbol_end (); + + sym = symbol_find_or_make (name); + + *input_line_pointer = c; + + if (sym->sy_obj.versioned_name != NULL) + { + as_bad (_("multiple .symver directives for symbol `%s'"), + S_GET_NAME (sym)); + ignore_rest_of_line (); + return; + } + + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') + { + as_bad (_("expected comma after name in .symver")); + ignore_rest_of_line (); + return; + } + + ++input_line_pointer; + name = input_line_pointer; + while (1) + { + c = get_symbol_end (); + if (c != ELF_VER_CHR) + break; + *input_line_pointer++ = c; + } + + sym->sy_obj.versioned_name = xstrdup (name); + + *input_line_pointer = c; + + if (strchr (sym->sy_obj.versioned_name, ELF_VER_CHR) == NULL) + { + as_bad (_("missing version name in `%s' for symbol `%s'"), + sym->sy_obj.versioned_name, S_GET_NAME (sym)); + ignore_rest_of_line (); + return; + } + + 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". */ + +static void +obj_elf_vtable_inherit (ignore) +{ + 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 || csym->sy_frag == 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; + } + + ++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; + + assert (csym->sy_value.X_op == O_constant); + fix_new (csym->sy_frag, csym->sy_value.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". */ + +static void +obj_elf_vtable_entry (ignore) +{ + 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; + } + + ++input_line_pointer; + if (*input_line_pointer == '#') + ++input_line_pointer; + + offset = get_absolute_expression (); + + fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0, + BFD_RELOC_VTABLE_ENTRY); + + demand_empty_rest_of_line (); +} + +void +obj_read_begin_hook () +{ +#ifdef NEED_ECOFF_DEBUG + if (ECOFF_DEBUGGING) + ecoff_read_begin_hook (); +#endif +} + +void +obj_symbol_new_hook (symbolP) + symbolS *symbolP; +{ + symbolP->sy_obj.size = NULL; + symbolP->sy_obj.versioned_name = NULL; + +#ifdef NEED_ECOFF_DEBUG + if (ECOFF_DEBUGGING) + ecoff_symbol_new_hook (symbolP); +#endif +} + +void +obj_elf_version (ignore) + int ignore; +{ + 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 = (asection *) NULL; + int i, 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, (valueT) i_note.namesz, 4); + p = frag_more (sizeof (e_note.descsz)); + md_number_to_chars (p, (valueT) i_note.descsz, 4); + p = frag_more (sizeof (e_note.type)); + md_number_to_chars (p, (valueT) i_note.type, 4); + + for (i = 0; i < len; i++) + { + ch = *(name + i); + { + FRAG_APPEND_1_CHAR (ch); + } + } + 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 (ignore) + int ignore; +{ + 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); + else + { + sym->sy_obj.size = (expressionS *) xmalloc (sizeof (expressionS)); + *sym->sy_obj.size = exp; + } + demand_empty_rest_of_line (); +} + +/* Handle the ELF .type pseudo-op. This sets the type of a symbol. + There are four 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 + */ + +static void +obj_elf_type (ignore) + int ignore; +{ + char *name; + char c; + int type; + const char *typename; + 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 == '@' + || *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 + as_bad (_("ignoring unrecognized symbol type \"%s\""), typename); + + *input_line_pointer = c; + + sym->bsym->flags |= type; + + demand_empty_rest_of_line (); +} + +static void +obj_elf_ident (ignore) + int ignore; +{ + static segT comment_section; + segT old_section = now_seg; + int old_subsection = now_subseg; + + 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 (seg) + 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, (unsigned int *) NULL); + stabstr_name = (char *) alloca (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 (abfd, sec, xxx) + bfd *abfd; + asection *sec; + PTR xxx; +{ + 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 = (char *) 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, (bfd_vma) nsyms, (bfd_byte *) p + 6); + bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) 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 (sym, ext) + symbolS *sym; + struct ecoff_extr *ext; +{ + sym->bsym->udata.p = (PTR) 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 boolean +elf_get_extr (sym, ext) + 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. */ + +/*ARGSUSED*/ +static void +elf_set_index (sym, indx) + asymbol *sym; + bfd_size_type indx; +{ +} + +#endif /* NEED_ECOFF_DEBUG */ + +void +elf_frob_symbol (symp, puntp) + symbolS *symp; + int *puntp; +{ +#ifdef NEED_ECOFF_DEBUG + if (ECOFF_DEBUGGING) + ecoff_frob_symbol (symp); +#endif + + if (symp->sy_obj.size != NULL) + { + switch (symp->sy_obj.size->X_op) + { + case O_subtract: + S_SET_SIZE (symp, + (S_GET_VALUE (symp->sy_obj.size->X_add_symbol) + + symp->sy_obj.size->X_add_number + - S_GET_VALUE (symp->sy_obj.size->X_op_symbol))); + break; + case O_constant: + S_SET_SIZE (symp, + (S_GET_VALUE (symp->sy_obj.size->X_add_symbol) + + symp->sy_obj.size->X_add_number)); + break; + default: + as_bad (_(".size expression too complicated to fix up")); + break; + } + free (symp->sy_obj.size); + symp->sy_obj.size = NULL; + } + + if (symp->sy_obj.versioned_name != 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)) + { + char *p; + + /* Verify that the name isn't using the @@ syntax--this is + reserved for definitions of the default version to link + against. */ + p = strchr (symp->sy_obj.versioned_name, ELF_VER_CHR); + know (p != NULL); + if (p[1] == ELF_VER_CHR) + { + as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"), + symp->sy_obj.versioned_name); + *puntp = true; + } + S_SET_NAME (symp, 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 (symp->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) - symp->sy_frag->fr_address); + + symp2->sy_frag = symp->sy_frag; + + /* This will copy over the size information. */ + copy_symbol_attributes (symp2, symp); + + if (S_IS_WEAK (symp)) + S_SET_WEAK (symp2); + + if (S_IS_EXTERNAL (symp)) + S_SET_EXTERNAL (symp2); + } + } + + /* Double check weak symbols. */ + if (symp->bsym->flags & BSF_WEAK) + { + 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)) + symp->bsym->flags |= BSF_OBJECT; + + if (strstr (TARGET_OS, "irix") != NULL + && (! S_IS_DEFINED (symp) && ((symp->bsym->flags & BSF_FUNCTION) == 0))) + symp->bsym->flags |= BSF_OBJECT; +#endif + +#ifdef TC_PPC + /* Frob the PowerPC, so that the symbol always has object type + if it is not some other type. VxWorks needs this. */ + if ((symp->bsym->flags & (BSF_FUNCTION | BSF_FILE | BSF_SECTION_SYM)) == 0 + && S_IS_DEFINED (symp)) + symp->bsym->flags |= BSF_OBJECT; +#endif +} + +void +elf_frob_file () +{ + bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0); + +#ifdef elf_tc_final_processing + elf_tc_final_processing (); +#endif +} + +/* 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 () +{ +#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 != (const struct ecoff_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, PTR); + SET (external_pdr, cbPdOffset, PTR); + SET (external_sym, cbSymOffset, PTR); + SET (external_opt, cbOptOffset, PTR); + SET (external_aux, cbAuxOffset, union aux_ext *); + SET (ss, cbSsOffset, char *); + SET (external_fdr, cbFdOffset, PTR); + SET (external_rfd, cbRfdOffset, PTR); + /* 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 == false); + + /* 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); + + if (! bfd_set_section_contents (stdoutput, sec, (PTR) NULL, + (file_ptr) 0, (bfd_size_type) 0)) + as_fatal (_("Can't start writing .mdebug section: %s"), + bfd_errmsg (bfd_get_error ())); + + know (stdoutput->output_has_begun == true); + 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 plagarized 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 () +{ + + 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 = (asection *) 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, (valueT) i_note.namesz, 4); + + p = frag_more (sizeof (i_note.descsz)); + md_number_to_chars (p, (valueT) i_note.descsz, 4); + + p = frag_more (sizeof (i_note.type)); + md_number_to_chars (p, (valueT) 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 */ + +const struct format_ops elf_format_ops = +{ + bfd_target_elf_flavour, + 0, + 1, + elf_frob_symbol, + elf_frob_file, + elf_frob_file_after_relocs, + elf_s_get_size, elf_s_set_size, + elf_s_get_align, elf_s_set_align, + elf_copy_symbol_attributes, +#ifdef NEED_ECOFF_DEBUG + ecoff_generate_asm_lineno, + ecoff_stab, +#else + 0, + 0, /* process_stab */ +#endif + elf_sec_sym_ok_for_reloc, + elf_pop_insert, +#ifdef NEED_ECOFF_DEBUG + elf_ecoff_set_ext, +#else + 0, +#endif + obj_read_begin_hook, + obj_symbol_new_hook, +}; diff --git a/gas/config/obj-elf.h b/gas/config/obj-elf.h new file mode 100644 index 0000000000..2f4bc5f977 --- /dev/null +++ b/gas/config/obj-elf.h @@ -0,0 +1,194 @@ +/* ELF object file format. + Copyright (C) 1992, 93, 94, 95, 96, 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 1, 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 + +#define OUTPUT_FLAVOR bfd_target_elf_flavour + +#include + +#define BYTES_IN_WORD 4 /* for now */ +#include "bfd/elf-bfd.h" + +/* Additional information we keep for each symbol. */ + +/* FIXME: For some reason, this structure is needed both here and in + obj-multi.h. */ +#ifndef OBJ_SYMFIELD_TYPE +struct elf_obj_sy +{ + /* 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; +}; +#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. */ +#define TARGET_SYMBOL_FIELDS ELF_TARGET_SYMBOL_FIELDS + +#include "targ-cpu.h" + +#ifndef FALSE +#define FALSE 0 +#define TRUE !FALSE +#endif + +#define obj_begin() elf_begin () +extern void elf_begin PARAMS ((void)); + +/* should be conditional on address size! */ +#define elf_symbol(asymbol) ((elf_symbol_type *)(&(asymbol)->the_bfd)) + +#define S_GET_SIZE(S) (elf_symbol ((S)->bsym)->internal_elf_sym.st_size) +#define S_SET_SIZE(S,V) \ + (elf_symbol((S)->bsym)->internal_elf_sym.st_size = (V)) + +#define S_GET_ALIGN(S) (elf_symbol ((S)->bsym)->internal_elf_sym.st_value) +#define S_SET_ALIGN(S,V) \ + (elf_symbol ((S)->bsym)->internal_elf_sym.st_value = (V)) + +#define S_GET_OTHER(S) (elf_symbol ((S)->bsym)->internal_elf_sym.st_other) +#define S_SET_OTHER(S,V) \ + (elf_symbol ((S)->bsym)->internal_elf_sym.st_other = (V)) + +extern asection *gdb_section; + +#define obj_frob_file elf_frob_file +extern void elf_frob_file PARAMS ((void)); + +#define obj_frob_file_after_relocs elf_frob_file_after_relocs +extern void elf_frob_file_after_relocs PARAMS ((void)); + +#define obj_app_file elf_file_symbol +extern void elf_file_symbol PARAMS ((char *)); + +extern void obj_elf_section_change_hook PARAMS ((void)); + +extern void obj_elf_section PARAMS ((int)); +extern void obj_elf_previous PARAMS ((int)); +extern void obj_elf_version PARAMS ((int)); + +/* BFD wants to write the udata field, which is a no-no for the + globally defined sections. */ +#define obj_sec_sym_ok_for_reloc(SEC) ((SEC)->owner != 0) + +/* 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. */ +#define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST,SRC) \ +do \ + { \ + if ((SRC)->sy_obj.size) \ + { \ + if ((DEST)->sy_obj.size == NULL) \ + (DEST)->sy_obj.size = \ + (expressionS *) xmalloc (sizeof (expressionS)); \ + *(DEST)->sy_obj.size = *(SRC)->sy_obj.size; \ + } \ + else \ + { \ + if ((DEST)->sy_obj.size != NULL) \ + free ((DEST)->sy_obj.size); \ + (DEST)->sy_obj.size = NULL; \ + } \ + S_SET_SIZE ((DEST), S_GET_SIZE (SRC)); \ + S_SET_OTHER ((DEST), S_GET_OTHER (SRC)); \ + } \ +while (0) + +/* 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 PARAMS ((segT)); +#define INIT_STAB_SECTION(seg) obj_elf_init_stab_section (seg) + +#ifdef TC_ALPHA +#define ECOFF_DEBUGGING alpha_flag_mdebug +extern int alpha_flag_mdebug; +#endif + +/* For now, always set ECOFF_DEBUGGING for a MIPS target. */ +#ifdef TC_MIPS +#ifdef MIPS_STABS_ELF +#define ECOFF_DEBUGGING 0 +#else +#define ECOFF_DEBUGGING 1 +#endif /* MIPS_STABS_ELF */ +#endif /* TC_MIPS */ + +#ifdef ECOFF_DEBUGGING +/* If we are generating ECOFF debugging information, we need some + additional fields for each symbol. */ +#undef TARGET_SYMBOL_FIELDS +#define TARGET_SYMBOL_FIELDS \ + ELF_TARGET_SYMBOL_FIELDS \ + struct efdr *ecoff_file; \ + struct localsym *ecoff_symbol; \ + valueT ecoff_extern_size; + +/* 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))) + +#define OBJ_PROCESS_STAB(seg, what, string, type, other, desc) \ + if (ECOFF_DEBUGGING) \ + ecoff_stab ((seg), (what), (string), (type), (other), (desc)) +#endif /* ECOFF_DEBUGGING */ + +extern void elf_frob_symbol PARAMS ((struct symbol *, int *)); +#ifndef obj_frob_symbol +#define obj_frob_symbol(symp, punt) elf_frob_symbol (symp, &punt) +#endif + +extern void elf_pop_insert PARAMS ((void)); +#define obj_pop_insert() elf_pop_insert() + +#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 PARAMS ((struct symbol *, struct ecoff_extr *)); +#endif + +#endif /* _OBJ_ELF_H */ diff --git a/gas/config/obj-evax.c b/gas/config/obj-evax.c new file mode 100644 index 0000000000..e818c83b90 --- /dev/null +++ b/gas/config/obj-evax.c @@ -0,0 +1,83 @@ +/* obj-evax.c - EVAX (openVMS/Alpha) object file format. + Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Contributed by Klaus Kämpf (kkaempf@progis.de) of + proGIS Software, Aachen, Germany. + + 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-evax.h" + +#include "as.h" + +static void s_evax_weak PARAMS ((int)); + +const pseudo_typeS obj_pseudo_table[] = +{ + { "weak", s_evax_weak, 0}, + {0, 0, 0}, +}; /* obj_pseudo_table */ + +void obj_read_begin_hook () {} + +/* Handle the weak specific pseudo-op. */ + +static void +s_evax_weak (ignore) + int ignore; +{ + 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); + *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 == ','); + + if (flag_mri) + mri_comment_end (stop, stopc); + + demand_empty_rest_of_line (); +} + +/* + * Local Variables: + * comment-column: 0 + * fill-column: 131 + * End: + */ + +/* end of obj-evax.c */ diff --git a/gas/config/obj-evax.h b/gas/config/obj-evax.h new file mode 100644 index 0000000000..1d9db19f41 --- /dev/null +++ b/gas/config/obj-evax.h @@ -0,0 +1,95 @@ +/* This file is obj-evax.h + Copyright (C) 1996 Free Software Foundation, Inc. + Contributed by Klaus Kämpf (kkaempf@progis.de) of + proGIS Software, Aachen, Germany. + + 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-evax.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_EVAX 1 + +/* include whatever target cpu is appropriate. */ +#include "targ-cpu.h" + +#ifdef BFD_ASSEMBLER +#define OUTPUT_FLAVOR bfd_target_evax_flavour +#endif + +/* + * 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; + +#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. */ + +#define obj_symbol_new_hook(s) {;} + +#define S_SET_OTHER(S,V) +#define S_SET_TYPE(S,T) +#define S_SET_DESC(S,D) +#define S_GET_OTHER(S) 0 +#define S_GET_TYPE(S) 0 +#define S_GET_DESC(S) 0 + +#define PDSC_S_K_KIND_FP_STACK 9 +#define PDSC_S_K_KIND_FP_REGISTER 10 +#define PDSC_S_K_KIND_NULL 8 + +#define PDSC_S_K_MIN_STACK_SIZE 32 +#define PDSC_S_K_MIN_REGISTER_SIZE 24 +#define PDSC_S_K_NULL_SIZE 16 + +#define PDSC_S_M_BASE_REG_IS_FP 0x80 /* low byte */ +#define PDSC_S_M_NATIVE 0x10 /* high byte */ +#define PDSC_S_M_NO_JACKET 0x20 /* high byte */ + +#define LKP_S_K_SIZE 16 + +/* + * Local Variables: + * comment-column: 0 + * fill-column: 131 + * End: + */ + +/* end of obj-evax.h */ diff --git a/gas/config/obj-generic.c b/gas/config/obj-generic.c new file mode 100644 index 0000000000..69fc3d1dbf --- /dev/null +++ b/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/gas/config/obj-generic.h b/gas/config/obj-generic.h new file mode 100644 index 0000000000..dc18e43970 --- /dev/null +++ b/gas/config/obj-generic.h @@ -0,0 +1,80 @@ +/* This file is obj-generic.h + 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. */ + +/* + * 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: + */ + +/* end of obj-generic.h */ diff --git a/gas/config/obj-hp300.c b/gas/config/obj-hp300.c new file mode 100644 index 0000000000..6e9cc53927 --- /dev/null +++ b/gas/config/obj-hp300.c @@ -0,0 +1,52 @@ +/* This file is obj-hp300.h + Copyright (C) 1993 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 "config/obj-aout.c" + +/* Aout file generation & utilities */ +void +hp300_header_append (where, headers) + char **where; + object_headers *headers; +{ + tc_headers_hook (headers); + +#define DO(FIELD) \ + { \ + md_number_to_chars (*where, headers->header.FIELD, sizeof (headers->header.FIELD)); \ + *where += sizeof (headers->header.FIELD); \ + } + + DO (a_info); + DO (a_spare1); + DO (a_spare2); + DO (a_text); + DO (a_data); + DO (a_bss); + DO (a_trsize); + DO (a_drsize); + DO (a_spare3); + DO (a_spare4); + DO (a_spare5); + DO (a_entry); + DO (a_spare6); + DO (a_spare7); + DO (a_syms); + DO (a_spare8); +} diff --git a/gas/config/obj-hp300.h b/gas/config/obj-hp300.h new file mode 100644 index 0000000000..ff4006b604 --- /dev/null +++ b/gas/config/obj-hp300.h @@ -0,0 +1,71 @@ +/* This file is obj-hp300.h + Copyright (C) 1993 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 __STRUCT_EXEC_OVERRIDE__ + +struct exec_bytes +{ + unsigned char a_info[4]; /* a_machtype/a_magic */ + unsigned char a_spare1[4]; + unsigned char a_spare2[4]; + unsigned char a_text[4]; /* length of text, in bytes */ + unsigned char a_data[4]; /* length of data, in bytes */ + unsigned char a_bss[4]; /* length of uninitialized data area for file, in bytes */ + unsigned char a_trsize[4]; /* length of relocation info for text, in bytes */ + unsigned char a_drsize[4]; /* length of relocation info for data, in bytes */ + unsigned char a_spare3[4]; /* HP = pascal interface size */ + unsigned char a_spare4[4]; /* HP = symbol table size */ + unsigned char a_spare5[4]; /* HP = debug name table size */ + unsigned char a_entry[4]; /* start address */ + unsigned char a_spare6[4]; /* HP = source line table size */ + unsigned char a_spare7[4]; /* HP = value table size */ + unsigned char a_syms[4]; /* length of symbol table data in file, in bytes */ + unsigned char a_spare8[4]; +}; + +/* How big the "struct exec" is on disk */ +#define EXEC_BYTES_SIZE (16 * 4) + +struct exec +{ + unsigned long a_info; + unsigned long a_spare1; + unsigned long a_spare2; + unsigned long a_text; + unsigned long a_data; + unsigned long a_bss; + unsigned long a_trsize; + unsigned long a_drsize; + unsigned long a_spare3; + unsigned long a_spare4; + unsigned long a_spare5; + unsigned long a_entry; + unsigned long a_spare6; + unsigned long a_spare7; + unsigned long a_syms; + unsigned long a_spare8; +}; + +#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (OMAGIC) +#define AOUT_VERSION 0x02 +#define AOUT_MACHTYPE 0x0c +#define OMAGIC 0x106 + +#define obj_header_append hp300_header_append +#include "config/obj-aout.h" diff --git a/gas/config/obj-ieee.c b/gas/config/obj-ieee.c new file mode 100644 index 0000000000..30a0798e29 --- /dev/null +++ b/gas/config/obj-ieee.c @@ -0,0 +1,627 @@ +/* obj-format for ieee-695 records. + Copyright (C) 1991, 92, 93, 94, 95, 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. */ + + +/* + 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) + register relax_addressT address; /* Address now. */ + register long alignment; /* Alignment (binary). */ +{ + relax_addressT mask; + relax_addressT new_address; + + mask = ~((~0) << alignment); + new_address = (address + mask) & (~mask); + return (new_address - address); +} /* relax_align() */ + +/* calculate the size of the frag chain and create a bfd section + to contain all of it */ +static void +DEFUN (size_section, (abfd, idx), + bfd * abfd AND + 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 +DEFUN (fill_section, (abfd, idx), + bfd * abfd AND + 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 +DEFUN (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 +DEFUN (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; + } + + /* attatch to the section */ + section->orelocation = reloc_ptr_vector; + section->reloc_count = nrelocs; + section->flags |= SEC_LOAD; + } +} + +/* do the symbols.. */ +static void +DEFUN (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) + ptr->sy_frag->fr_address); + 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 +DEFUN_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; + +} + + +void cons (); +void s_ignore (); + + +void s_globl (); +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 +extern void +DEFUN_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); + for (frchain_ptr = frchain_root; + frchain_ptr != (struct frchain *) NULL; + frchain_ptr = frchain_ptr->frch_next) + { + /* 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. */ + + subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg); +#ifndef SUB_SEGMENT_ALIGN +#define SUB_SEGMENT_ALIGN(SEG) 2 +#endif + frag_align (SUB_SEGMENT_ALIGN (now_seg), 0, 0); + 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; + + /* struct frag **head_ptr = segment_info[i].frag_root;*/ + + segment_info[i].frag_root = segment_info[i].frchainP->frch_root; +#if 0 + /* Im 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); + } + + /* 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 (); +} + +/* end of obj-ieee.c */ diff --git a/gas/config/obj-ieee.h b/gas/config/obj-ieee.h new file mode 100644 index 0000000000..4a0f126ebe --- /dev/null +++ b/gas/config/obj-ieee.h @@ -0,0 +1,50 @@ +/* This file is obj-ieee.h + + 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. */ + +#define BFD 1 + +#include + +typedef struct +{ + asymbol sy; + int seg; +} + +obj_symbol_type; + +#define S_GET_NAME(s) (((s)->sy_symbol.sy.name)) + +typedef struct + { + int x; + } + +object_headers; + +#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE 1 + + +int lineno_rootP; + + +#define IEEE_STYLE + +/* end of obj-ieee.h */ diff --git a/gas/config/obj-multi.c b/gas/config/obj-multi.c new file mode 100644 index 0000000000..d115093aff --- /dev/null +++ b/gas/config/obj-multi.c @@ -0,0 +1,4 @@ +/* foo */ + +#include "as.h" + diff --git a/gas/config/obj-multi.h b/gas/config/obj-multi.h new file mode 100644 index 0000000000..fe8d98d0d6 --- /dev/null +++ b/gas/config/obj-multi.h @@ -0,0 +1,50 @@ +/* hi */ + +#include "emul.h" +#include "targ-cpu.h" + +#define OUTPUT_FLAVOR (this_format->flavor) +#define obj_frob_symbol(S,P) (this_format->frob_symbol)(S,&(P)) +#define obj_frob_file (this_format->frob_file) +#define obj_frob_file_after_relocs (this_format->frob_file_after_relocs) +#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 (this_format->symbol_new_hook) +#define obj_sec_sym_ok_for_reloc (this_format->sec_sym_ok_for_reloc) +#define S_GET_SIZE (this_format->s_get_size) +#define S_SET_SIZE (this_format->s_set_size) +#define S_GET_ALIGN (this_format->s_get_align) +#define S_SET_ALIGN (this_format->s_set_align) +#define OBJ_COPY_SYMBOL_ATTRIBUTES (this_format->copy_symbol_attributes) +#define OBJ_PROCESS_STAB (this_format->process_stab) + +#if defined (OBJ_MAYBE_ECOFF) || (defined (OBJ_MAYBE_ELF) && defined (TC_MIPS)) +#define ECOFF_DEBUGGING 1 +#endif + +/* FIXME: What's the story here? Why do we have to define + OBJ_SYMFIELD_TYPE both here and in obj-elf.h? */ +#ifdef OBJ_MAYBE_ELF +struct elf_obj_sy +{ + expressionS *size; + char *versioned_name; +}; +#define OBJ_SYMFIELD_TYPE struct elf_obj_sy +#define ELF_TARGET_SYMBOL_FIELDS int local:1; +#else +#define ELF_TARGET_SYMBOL_FIELDS +#endif + +#ifdef ECOFF_DEBUGGING +struct efdr; +struct localsym; +#define ECOFF_DEBUG_TARGET_SYMBOL_FIELDS struct efdr *ecoff_file; struct localsym *ecoff_symbol; valueT ecoff_extern_size; +#else +#define ECOFF_DEBUG_TARGET_SYMBOL_FIELDS +#endif + +#define TARGET_SYMBOL_FIELDS \ + ELF_TARGET_SYMBOL_FIELDS \ + ECOFF_DEBUG_TARGET_SYMBOL_FIELDS diff --git a/gas/config/obj-som.c b/gas/config/obj-som.c new file mode 100644 index 0000000000..80af18fd37 --- /dev/null +++ b/gas/config/obj-som.c @@ -0,0 +1,307 @@ +/* SOM object file format. + Copyright (C) 1993, 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. + + Written by the Center for Software Science at the University of Utah + and by Cygnus Support. */ + +#include "as.h" +#include "subsegs.h" +#include "aout/stab_gnu.h" +#include "obstack.h" + +/* SOM does not need any pseudo-ops. */ + +const pseudo_typeS obj_pseudo_table[] = +{ + {NULL} +}; + +static int version_seen = 0; +static int copyright_seen = 0; +static int compiler_seen = 0; + +/* Unused by SOM. */ +void obj_read_begin_hook () {} + +/* Handle a .compiler directive. This is intended to create the + compilation unit auxiliary header for MPE such that the linkeditor + can handle SOM extraction from archives. The format of the quoted + string is "sourcefile language version" and is delimited by blanks.*/ + +void +obj_som_compiler (unused) + int unused; +{ + char *buf; + char c; + char *filename; + char *language_name; + char *p; + char *version_id; + + if (compiler_seen) + { + as_bad ("Only one .compiler pseudo-op per file!"); + ignore_rest_of_line (); + return; + } + + SKIP_WHITESPACE (); + if (*input_line_pointer == '\"') + { + buf = input_line_pointer; + ++input_line_pointer; + while (is_a_char (next_char_of_string ())) + ; + c = *input_line_pointer; + *input_line_pointer = '\000'; + } + else + { + as_bad ("Expected quoted string"); + ignore_rest_of_line (); + return; + } + + /* Parse the quoted string into its component parts. Skip the + quote. */ + filename = buf + 1; + p = filename; + while (*p != ' ' && *p != '\000') + p++; + if (*p == '\000') + { + as_bad (".compiler directive missing language and version"); + return; + } + *p = '\000'; + + language_name = ++p; + while (*p != ' ' && *p != '\000') p++; + if (*p == '\000') + { + as_bad (".compiler directive missing version"); + return; + } + *p = '\000'; + + version_id = ++p; + while (*p != '\000') p++; + /* Remove the trailing quote. */ + *(--p) = '\000'; + + compiler_seen = 1; + if (! bfd_som_attach_compilation_unit (stdoutput, filename, language_name, + "GNU Tools", version_id)) + { + bfd_perror (stdoutput->filename); + as_fatal ("FATAL: Attaching compiler header %s", stdoutput->filename); + } + *input_line_pointer = c; + demand_empty_rest_of_line (); +} + +/* Handle a .version directive. */ + +void +obj_som_version (unused) + int unused; +{ + char *version, c; + + if (version_seen) + { + as_bad (_("Only one .version pseudo-op per file!")); + ignore_rest_of_line (); + return; + } + + SKIP_WHITESPACE (); + if (*input_line_pointer == '\"') + { + version = input_line_pointer; + ++input_line_pointer; + while (is_a_char (next_char_of_string ())) + ; + c = *input_line_pointer; + *input_line_pointer = '\000'; + } + else + { + as_bad (_("Expected quoted string")); + ignore_rest_of_line (); + return; + } + + version_seen = 1; + if (bfd_som_attach_aux_hdr (stdoutput, VERSION_AUX_ID, version) == false) + { + bfd_perror (stdoutput->filename); + as_perror (_("FATAL: Attaching version header %s"), stdoutput->filename); + exit (EXIT_FAILURE); + } + *input_line_pointer = c; + demand_empty_rest_of_line (); +} + +/* Handle a .copyright directive. This probably isn't complete, but + it's of dubious value anyway and (IMHO) not worth the time to finish. + If you care about copyright strings that much, you fix it. */ + +void +obj_som_copyright (unused) + int unused; +{ + char *copyright, c; + + if (copyright_seen) + { + as_bad (_("Only one .copyright pseudo-op per file!")); + ignore_rest_of_line (); + return; + } + + SKIP_WHITESPACE (); + if (*input_line_pointer == '\"') + { + copyright = input_line_pointer; + ++input_line_pointer; + while (is_a_char (next_char_of_string ())) + ; + c = *input_line_pointer; + *input_line_pointer = '\000'; + } + else + { + as_bad (_("Expected quoted string")); + ignore_rest_of_line (); + return; + } + + copyright_seen = 1; + if (bfd_som_attach_aux_hdr (stdoutput, COPYRIGHT_AUX_ID, copyright) == false) + { + bfd_perror (stdoutput->filename); + as_perror (_("FATAL: Attaching copyright header %s"), stdoutput->filename); + exit (EXIT_FAILURE); + } + *input_line_pointer = c; + demand_empty_rest_of_line (); +} + +/* Perform any initialization necessary for stabs support. + + For SOM we need to create the space which will contain the + two stabs subspaces. Additionally we need to set up the + space/subspace relationships and set space/subspace attributes + which BFD does not understand. */ + +void +obj_som_init_stab_section (seg) + segT seg; +{ + segT saved_seg = now_seg; + segT space; + subsegT saved_subseg = now_subseg; + char *p, *file; + unsigned int stroff; + + /* Make the space which will contain the debug subspaces. */ + space = bfd_make_section_old_way (stdoutput, "$GDB_DEBUG$"); + + /* Set SOM specific attributes for the space. In particular we set + the space "defined", "private", "sort_key", and "spnum" values. + + Due to a bug in pxdb (called by hpux linker), the sort keys + of the various stabs spaces/subspaces need to be "small". We + reserve range 72/73 which appear to work well. */ + obj_set_section_attributes (space, 1, 1, 72, 2); + bfd_set_section_alignment (stdoutput, space, 2); + + /* Set the containing space for both stab sections to be $GDB_DEBUG$ + (just created above). Also set some attributes which BFD does + not understand. In particular, access bits, sort keys, and load + quadrant. */ + obj_set_subsection_attributes (seg, space, 0x1f, 73, 0); + bfd_set_section_alignment (stdoutput, seg, 2); + + /* Make some space for the first special stab entry and zero the memory. + It contains information about the length of this file's + stab string and the like. Using it avoids the need to + relocate the stab strings. + + The $GDB_STRINGS$ space will be created as a side effect of + the call to get_stab_string_offset. */ + p = frag_more (12); + memset (p, 0, 12); + as_where (&file, (unsigned int *) NULL); + stroff = get_stab_string_offset (file, "$GDB_STRINGS$"); + know (stroff == 1); + md_number_to_chars (p, stroff, 4); + seg_info (seg)->stabu.p = p; + + /* Set the containing space for both stab sections to be $GDB_DEBUG$ + (just created above). Also set some attributes which BFD does + not understand. In particular, access bits, sort keys, and load + quadrant. */ + seg = bfd_get_section_by_name (stdoutput, "$GDB_STRINGS$"); + obj_set_subsection_attributes (seg, space, 0x1f, 72, 0); + bfd_set_section_alignment (stdoutput, seg, 2); + + subseg_set (saved_seg, saved_subseg); +} + +/* Fill in the counts in the first entry in a .stabs section. */ + +static void +adjust_stab_sections (abfd, sec, xxx) + bfd *abfd; + asection *sec; + PTR xxx; +{ + asection *strsec; + char *p; + int strsz, nsyms; + + if (strcmp ("$GDB_SYMBOLS$", sec->name)) + return; + + strsec = bfd_get_section_by_name (abfd, "$GDB_STRINGS$"); + 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, (bfd_vma) nsyms, (bfd_byte *) p + 6); + bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8); +} + +/* Called late in the asssembly phase to adjust the special + stab entry and to set the starting address for each code subspace. */ + +void +som_frob_file () +{ + bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0); +} diff --git a/gas/config/obj-som.h b/gas/config/obj-som.h new file mode 100644 index 0000000000..62087b125f --- /dev/null +++ b/gas/config/obj-som.h @@ -0,0 +1,73 @@ +/* SOM object file format. + Copyright (C) 1993, 1994, 1995, 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 1, 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 the Center for Software Science at the University of Utah + and by Cygnus Support. */ + +#ifndef _OBJ_SOM_H +#define _OBJ_SOM_H + +#define OBJ_SOM 1 + +#include +#include "bfd/som.h" +#include "targ-cpu.h" + +#ifndef FALSE +#define FALSE 0 +#define TRUE !FALSE +#endif + +/* should be conditional on address size! */ +#define som_symbol(asymbol) ((som_symbol_type *)(&(asymbol)->the_bfd)) + +extern void som_file_symbol PARAMS ((char *)); +extern void obj_som_version PARAMS ((int)); +extern void obj_som_init_stab_section PARAMS ((segT)); +extern void obj_som_copyright PARAMS ((int)); +extern void obj_som_compiler PARAMS ((int)); + +#define obj_symbol_new_hook(s) {;} + +/* SOM has several attributes for spaces/subspaces which can not + be easily expressed in BFD. We use these macros to trigger calls + into the SOM BFD backend to set these attributes. */ +#define obj_set_section_attributes bfd_som_set_section_attributes +#define obj_set_subsection_attributes bfd_som_set_subsection_attributes + +/* Likewise for symbol types. */ +#define obj_set_symbol_type bfd_som_set_symbol_type + +/* Stabs go in a separate sections. GDB expects to find them in sections + with the names $GDB_SYMBOLS$ and $GDB_STRINGS$ rather than .stab and + .stabstr. */ +#define SEPARATE_STAB_SECTIONS 1 +#define STAB_SECTION_NAME "$GDB_SYMBOLS$" +#define STAB_STRING_SECTION_NAME "$GDB_STRINGS$" + +/* We use INIT_STAB_SECTION to record the space/subspace relationships + for the various debugging sections. */ +#define INIT_STAB_SECTION(seg) obj_som_init_stab_section (seg) + +/* We'll be updating the magic 1st stab entry once the entire assembly + fail has been processed. */ +#define obj_frob_file() som_frob_file() + +#endif /* _OBJ_SOM_H */ diff --git a/gas/config/obj-vms.c b/gas/config/obj-vms.c new file mode 100644 index 0000000000..0f08f8eb3f --- /dev/null +++ b/gas/config/obj-vms.c @@ -0,0 +1,5549 @@ +/* vms.c -- Write out a VAX/VMS object file + Copyright (C) 1987, 88, 92, 94, 95, 97, 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. */ + +/* Written by David L. Kashtan */ +/* Modified by Eric Youngdale to write VMS debug records for program + variables */ + +/* Want all of obj-vms.h (as obj-format.h, via targ-env.h, via as.h). */ +#define WANT_VMS_OBJ_DEFS + +#include "as.h" +#include "config.h" +#include "subsegs.h" +#include "obstack.h" + +/* What we do if there is a goof. */ +#define error as_fatal + +#ifdef VMS /* These are of no use if we are cross assembling. */ +#include /* Define File Access Block */ +#include /* Define NAM Block */ +#include /* Define XAB - all different types*/ +extern int sys$open(), sys$close(), sys$asctim(); +#endif + +/* + * Version string of the compiler that produced the code we are + * assembling. (And this assembler, if we do not have compiler info.) + */ +char *compiler_version_string; + +extern int flag_hash_long_names; /* -+ */ +extern int flag_one; /* -1; compatibility with gcc 1.x */ +extern int flag_show_after_trunc; /* -H */ +extern int flag_no_hash_mixed_case; /* -h NUM */ + +/* Flag that determines how we map names. This takes several values, and + * is set with the -h switch. A value of zero implies names should be + * upper case, and the presence of the -h switch inhibits the case hack. + * No -h switch at all sets vms_name_mapping to 0, and allows case hacking. + * A value of 2 (set with -h2) implies names should be + * all lower case, with no case hack. A value of 3 (set with -h3) implies + * that case should be preserved. */ + +/* If the -+ switch is given, then the hash is appended to any name that is + * longer than 31 characters, regardless of the setting of the -h switch. + */ + +char vms_name_mapping = 0; + +static symbolS *Entry_Point_Symbol = 0; /* Pointer to "_main" */ + +/* + * We augment the "gas" symbol structure with this + */ +struct VMS_Symbol +{ + struct VMS_Symbol *Next; + symbolS *Symbol; + int Size; + int Psect_Index; + int Psect_Offset; +}; + +struct VMS_Symbol *VMS_Symbols = 0; +struct VMS_Symbol *Ctors_Symbols = 0; +struct VMS_Symbol *Dtors_Symbols = 0; + +/* We need this to keep track of the various input files, so that we can + * give the debugger the correct source line. + */ + +struct input_file +{ + struct input_file *next; + struct input_file *same_file_fpnt; + int file_number; + int max_line; + int min_line; + int offset; + char flag; + char *name; + symbolS *spnt; +}; + +static struct input_file *file_root = (struct input_file *) NULL; + + +/* + * Styles of PSECTS (program sections) that we generate; just shorthand + * to avoid lists of section attributes. Used by VMS_Psect_Spec(). + */ +enum ps_type +{ + ps_TEXT, ps_DATA, ps_COMMON, ps_CONST, ps_CTORS, ps_DTORS +}; + +/* + * This enum is used to keep track of the various types of variables that + * may be present. + */ + +enum advanced_type +{ + BASIC, POINTER, ARRAY, ENUM, STRUCT, UNION, FUNCTION, VOID, ALIAS, UNKNOWN +}; + +/* + * This structure contains the information from the stabs directives, and the + * information is filled in by VMS_typedef_parse. Everything that is needed + * to generate the debugging record for a given symbol is present here. + * This could be done more efficiently, using nested struct/unions, but for now + * I am happy that it works. + */ +struct VMS_DBG_Symbol +{ + struct VMS_DBG_Symbol *next; + /* description of what this is */ + enum advanced_type advanced; + /* this record is for this type */ + int dbx_type; + /* For advanced types this is the type referred to. I.e., the type + a pointer points to, or the type of object that makes up an + array. */ + int type2; + /* Use this type when generating a variable def */ + int VMS_type; + /* used for arrays - this will be present for all */ + int index_min; + /* entries, but will be meaningless for non-arrays */ + int index_max; + /* Size in bytes of the data type. For an array, this is the size + of one element in the array */ + int data_size; + /* Number of the structure/union/enum - used for ref */ + int struc_numb; +}; + +#define SYMTYPLST_SIZE (1<<4) /* 16; must be power of two */ +#define SYMTYP_HASH(x) ((unsigned)(x) & (SYMTYPLST_SIZE-1)) +struct VMS_DBG_Symbol *VMS_Symbol_type_list[SYMTYPLST_SIZE]; + +/* + * We need this structure to keep track of forward references to + * struct/union/enum that have not been defined yet. When they are ultimately + * defined, then we can go back and generate the TIR commands to make a back + * reference. + */ + +struct forward_ref +{ + struct forward_ref *next; + int dbx_type; + int struc_numb; + char resolved; +}; + +struct forward_ref *f_ref_root = (struct forward_ref *) NULL; + +/* + * This routine is used to compare the names of certain types to various + * fixed types that are known by the debugger. + */ +#define type_check(X) !strcmp (symbol_name, X) + +/* + * This variable is used to keep track of the name of the symbol we are + * working on while we are parsing the stabs directives. + */ +static const char *symbol_name; + +/* We use this counter to assign numbers to all of the structures, unions + * and enums that we define. When we actually declare a variable to the + * debugger, we can simply do it by number, rather than describing the + * whole thing each time. + */ + +static structure_count = 0; + +/* This variable is used to indicate that we are making the last attempt to + parse the stabs, and that we should define as much as we can, and ignore + the rest */ + +static int final_pass; + +/* This variable is used to keep track of the current structure number + * for a given variable. If this is < 0, that means that the structure + * has not yet been defined to the debugger. This is still cool, since + * the VMS object language has ways of fixing things up after the fact, + * so we just make a note of this, and generate fixups at the end. + */ +static int struct_number; + +/* This is used to distinguish between D_float and G_float for telling + the debugger about doubles. gcc outputs the same .stabs regardless + of whether -mg is used to select alternate doubles. */ + +static int vax_g_doubles = 0; + +/* Local symbol references (used to handle N_ABS symbols; gcc does not + generate those, but they're possible with hand-coded assembler input) + are always made relative to some particular environment. If the current + input has any such symbols, then we expect this to get incremented + exactly once and end up having all of them be in environment #0. */ + +static int Current_Environment = -1; + +/* Every object file must specify an module name, which is also used by + traceback records. Set in Write_VMS_MHD_Records(). */ + +static char Module_Name[255+1]; + +/* + * Variable descriptors are used tell the debugger the data types of certain + * more complicated variables (basically anything involving a structure, + * union, enum, array or pointer). Some non-pointer variables of the + * basic types that the debugger knows about do not require a variable + * descriptor. + * + * Since it is impossible to have a variable descriptor longer than 128 + * bytes by virtue of the way that the VMS object language is set up, + * it makes not sense to make the arrays any longer than this, or worrying + * about dynamic sizing of the array. + * + * These are the arrays and counters that we use to build a variable + * descriptor. + */ + +#define MAX_DEBUG_RECORD 128 +static char Local[MAX_DEBUG_RECORD]; /* buffer for variable descriptor */ +static char Asuffix[MAX_DEBUG_RECORD]; /* buffer for array descriptor */ +static int Lpnt; /* index into Local */ +static int Apoint; /* index into Asuffix */ +static char overflow; /* flag to indicate we have written too much*/ +static int total_len; /* used to calculate the total length of variable + descriptor plus array descriptor - used for len byte*/ + +/* Flag if we have told user about finding global constants in the text + section. */ +static int gave_compiler_message = 0; + + +/* + * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime) + */ +static int VMS_Object_File_FD; /* File Descriptor for object file */ +static char Object_Record_Buffer[512]; /* Buffer for object file records */ +static int Object_Record_Offset;/* Offset to end of data */ +static int Current_Object_Record_Type; /* Type of record in above */ + +/* + * Macros for moving data around. Must work on big-endian systems. + */ +#ifdef VMS /* These are more efficient for VMS->VMS systems */ +#define COPY_LONG(dest,val) ( *(long *)(dest) = (val) ) +#define COPY_SHORT(dest,val) ( *(short *)(dest) = (val) ) +#else +#define COPY_LONG(dest,val) md_number_to_chars ((dest), (val), 4) +#define COPY_SHORT(dest,val) md_number_to_chars ((dest), (val), 2) +#endif +/* + * Macros for placing data into the object record buffer. + */ +#define PUT_LONG(val) \ + ( COPY_LONG (&Object_Record_Buffer[Object_Record_Offset], (val)), \ + Object_Record_Offset += 4 ) + +#define PUT_SHORT(val) \ + ( COPY_SHORT (&Object_Record_Buffer[Object_Record_Offset], (val)), \ + Object_Record_Offset += 2 ) + +#define PUT_CHAR(val) ( Object_Record_Buffer[Object_Record_Offset++] = (val) ) + +#define PUT_COUNTED_STRING(cp) do { \ + register const char *p = (cp); \ + PUT_CHAR ((char) strlen (p)); \ + while (*p) PUT_CHAR (*p++); } while (0) + +/* + * Macro for determining if a Name has psect attributes attached + * to it. + */ +#define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_" +#define PSECT_ATTRIBUTES_STRING_LENGTH 18 + +#define HAS_PSECT_ATTRIBUTES(Name) \ + (strncmp ((*Name == '_' ? Name + 1 : Name), \ + PSECT_ATTRIBUTES_STRING, \ + PSECT_ATTRIBUTES_STRING_LENGTH) == 0) + + + /* 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, +}; + + +/* Local support routines which return a value. */ + +static struct input_file *find_file PARAMS ((symbolS *)); +static struct VMS_DBG_Symbol *find_symbol PARAMS ((int)); +static symbolS *Define_Routine PARAMS ((symbolS *,int,symbolS *,int)); + +static char *cvt_integer PARAMS ((char *,int *)); +static char *fix_name PARAMS ((char *)); +static char *get_struct_name PARAMS ((char *)); + +static offsetT VMS_Initialized_Data_Size PARAMS ((symbolS *,unsigned)); + +static int VMS_TBT_Source_File PARAMS ((char *,int)); +static int gen1 PARAMS ((struct VMS_DBG_Symbol *,int)); +static int forward_reference PARAMS ((char *)); +static int final_forward_reference PARAMS ((struct VMS_DBG_Symbol *)); +static int VMS_typedef_parse PARAMS ((char *)); +static int hash_string PARAMS ((const char *)); +static int VMS_Psect_Spec PARAMS ((const char *,int,enum ps_type, + struct VMS_Symbol *)); + +/* Local support routines which don't directly return any value. */ + +static void s_const PARAMS ((int)); +static void Create_VMS_Object_File PARAMS ((void)); +static void Flush_VMS_Object_Record_Buffer PARAMS ((void)); +static void Set_VMS_Object_File_Record PARAMS ((int)); +static void Close_VMS_Object_File PARAMS ((void)); +static void vms_tir_stack_psect PARAMS ((int,int,int)); +static void VMS_Store_Immediate_Data PARAMS ((const char *,int,int)); +static void VMS_Set_Data PARAMS ((int,int,int,int)); +static void VMS_Store_Struct PARAMS ((int)); +static void VMS_Def_Struct PARAMS ((int)); +static void VMS_Set_Struct PARAMS ((int)); +static void VMS_TBT_Module_Begin PARAMS ((void)); +static void VMS_TBT_Module_End PARAMS ((void)); +static void VMS_TBT_Routine_Begin PARAMS ((symbolS *,int)); +static void VMS_TBT_Routine_End PARAMS ((int,symbolS *)); +static void VMS_TBT_Block_Begin PARAMS ((symbolS *,int,char *)); +static void VMS_TBT_Block_End PARAMS ((valueT)); +static void VMS_TBT_Line_PC_Correlation PARAMS ((int,int,int,int)); +static void VMS_TBT_Source_Lines PARAMS ((int,int,int)); +static void fpush PARAMS ((int,int)); +static void rpush PARAMS ((int,int)); +static void array_suffix PARAMS ((struct VMS_DBG_Symbol *)); +static void new_forward_ref PARAMS ((int)); +static void generate_suffix PARAMS ((struct VMS_DBG_Symbol *,int)); +static void bitfield_suffix PARAMS ((struct VMS_DBG_Symbol *,int)); +static void setup_basic_type PARAMS ((struct VMS_DBG_Symbol *)); +static void VMS_DBG_record PARAMS ((struct VMS_DBG_Symbol *,int,int,char *)); +static void VMS_local_stab_Parse PARAMS ((symbolS *)); +static void VMS_stab_parse PARAMS ((symbolS *,int,int,int,int)); +static void VMS_GSYM_Parse PARAMS ((symbolS *,int)); +static void VMS_LCSYM_Parse PARAMS ((symbolS *,int)); +static void VMS_STSYM_Parse PARAMS ((symbolS *,int)); +static void VMS_RSYM_Parse PARAMS ((symbolS *,symbolS *,int)); +static void VMS_LSYM_Parse PARAMS ((void)); +static void Define_Local_Symbols PARAMS ((symbolS *,symbolS *,symbolS *,int)); +static void Write_VMS_MHD_Records PARAMS ((void)); +static void Write_VMS_EOM_Record PARAMS ((int,valueT)); +static void VMS_Case_Hack_Symbol PARAMS ((const char *,char *)); +static void VMS_Modify_Psect_Attributes PARAMS ((const char *,int *)); +static void VMS_Global_Symbol_Spec PARAMS ((const char *,int,int,int)); +static void VMS_Local_Environment_Setup PARAMS ((const char *)); +static void VMS_Emit_Globalvalues PARAMS ((unsigned,unsigned,char *)); +static void VMS_Procedure_Entry_Pt PARAMS ((char *,int,int,int)); +static void VMS_Set_Psect PARAMS ((int,int,int)); +static void VMS_Store_Repeated_Data PARAMS ((int,char *,int,int)); +static void VMS_Store_PIC_Symbol_Reference PARAMS ((symbolS *,int, + int,int,int,int)); +static void VMS_Fix_Indirect_Reference PARAMS ((int,int,fragS *,fragS *)); + +/* Support code which used to be inline within vms_write_object_file. */ +static void vms_fixup_text_section PARAMS ((unsigned,struct frag *,struct frag *)); +static void synthesize_data_segment PARAMS ((unsigned,unsigned,struct frag *)); +static void vms_fixup_data_section PARAMS ((unsigned,unsigned)); +static void global_symbol_directory PARAMS ((unsigned,unsigned)); +static void local_symbols_DST PARAMS ((symbolS *,symbolS *)); +static void vms_build_DST PARAMS ((unsigned)); +static void vms_fixup_xtors_section PARAMS ((struct VMS_Symbol *, int)); + + +/* The following code defines the special types of pseudo-ops that we + use with VMS. */ + +unsigned char const_flag = IN_DEFAULT_SECTION; + +static void +s_const (arg) + int arg; /* 3rd field from obj_pseudo_table[]; not needed here */ +{ + /* Since we don't need `arg', use it as our scratch variable so that + we won't get any "not used" warnings about it. */ + arg = get_absolute_expression (); + subseg_set (SEG_DATA, (subsegT) arg); + const_flag = 1; + demand_empty_rest_of_line (); +} + +const pseudo_typeS obj_pseudo_table[] = +{ + {"const", s_const, 0}, + {0, 0, 0}, +}; /* obj_pseudo_table */ + + +/* Routine to perform RESOLVE_SYMBOL_REDEFINITION(). */ + +int +vms_resolve_symbol_redef (sym) + symbolS *sym; +{ + /* + * If the new symbol is .comm AND it has a size of zero, + * we ignore it (i.e. the old symbol overrides it) + */ + if (SEGMENT_TO_SYMBOL_TYPE ((int) now_seg) == (N_UNDF | N_EXT) + && frag_now_fix () == 0) + { + as_warn (_("compiler emitted zero-size common symbol `%s' already defined"), + S_GET_NAME (sym)); + return 1; + } + /* + * If the old symbol is .comm and it has a size of zero, + * we override it with the new symbol value. + */ + if (S_IS_EXTERNAL (sym) && S_IS_DEFINED (sym) && S_GET_VALUE (sym) == 0) + { + as_warn (_("compiler redefined zero-size common symbol `%s'"), + S_GET_NAME (sym)); + sym->sy_frag = frag_now; + S_SET_OTHER (sym, const_flag); + S_SET_VALUE (sym, frag_now_fix ()); + /* Keep N_EXT bit. */ + sym->sy_symbol.n_type |= SEGMENT_TO_SYMBOL_TYPE ((int) now_seg); + return 1; + } + + return 0; +} + + +/* `tc_frob_label' handler for colon(symbols.c), used to examine the + dummy label(s) gcc inserts at the beginning of each file it generates. + gcc 1.x put "gcc_compiled."; gcc 2.x (as of 2.7) puts "gcc2_compiled." + and "__gnu_language_" and possibly "__vax__doubles". */ + +void +vms_check_for_special_label (symbolP) +symbolS *symbolP; +{ + /* Special labels only occur prior to explicit section directives. */ + if ((const_flag & IN_DEFAULT_SECTION) != 0) + { + char *sym_name = S_GET_NAME (symbolP); + + if (*sym_name == '_') + ++sym_name; + + if (!strcmp (sym_name, "__vax_g_doubles")) + vax_g_doubles = 1; +#if 0 /* not necessary */ + else if (!strcmp (sym_name, "__vax_d_doubles")) + vax_g_doubles = 0; +#endif +#if 0 /* these are potential alternatives to tc-vax.c's md_parse_options() */ + else if (!strcmp (sym_name, "gcc_compiled.")) + flag_one = 1; + else if (!strcmp (sym_name, "__gnu_language_cplusplus")) + flag_hash_long_names = 1; +#endif + } + return; +} + + +void +obj_read_begin_hook () +{ + return; +} + + +void +obj_crawl_symbol_chain (headers) + object_headers *headers; +{ + symbolS *symbolP; + symbolS **symbolPP; + int symbol_number = 0; + + symbolPP = &symbol_rootP; /* -> last symbol chain link. */ + while ((symbolP = *symbolPP) != NULL) + { + resolve_symbol_value (symbolP, 1); + + /* 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 with \1 as their 3rd character (numeric labels) + * "local labels" needed for PIC fixups + + Symbols that don't are: + * symbols that are registers + + All other symbols are output. We complain if a deleted + symbol was marked external. */ + + if (!S_IS_REGISTER (symbolP)) + { + symbolP->sy_number = symbol_number++; + symbolP->sy_name_offset = 0; + symbolPP = &(symbol_next (symbolP)); + } + else + { + if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP)) + { + as_bad (_("Local symbol %s never defined"), 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_STRING_SIZE (headers, string_byte_count); + H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number); +} /* obj_crawl_symbol_chain() */ + + + /****** VMS OBJECT FILE HACKING ROUTINES *******/ + + +/* Create the VMS object file. */ + +static void +Create_VMS_Object_File () +{ +#if defined(eunice) || !defined(VMS) + VMS_Object_File_FD = creat (out_file_name, 0777, "var"); +#else /* eunice */ + VMS_Object_File_FD = creat (out_file_name, 0, "rfm=var", + "ctx=bin", "mbc=16", "deq=64", "fop=tef", + "shr=nil"); +#endif /* eunice */ + /* Deal with errors. */ + if (VMS_Object_File_FD < 0) + as_fatal (_("Couldn't create VMS object file \"%s\""), out_file_name); + /* Initialize object file hacking variables. */ + Object_Record_Offset = 0; + Current_Object_Record_Type = -1; +} + + +/* Flush the object record buffer to the object file. */ + +static void +Flush_VMS_Object_Record_Buffer () +{ + /* If the buffer is empty, there's nothing to do. */ + if (Object_Record_Offset == 0) + return; + +#ifndef VMS /* For cross-assembly purposes. */ + { + char RecLen[2]; + + /* "Variable-length record" files have a two byte length field + prepended to each record. It's normally out-of-band, and native + VMS output will insert it automatically for this type of file. + When cross-assembling, we must write it explicitly. */ + md_number_to_chars (RecLen, Object_Record_Offset, 2); + if (write (VMS_Object_File_FD, RecLen, 2) != 2) + error (_("I/O error writing VMS object file (length prefix)")); + /* We also need to force the actual record to be an even number of + bytes. For native output, that's automatic; when cross-assembling, + pad with a NUL byte if length is odd. Do so _after_ writing the + pre-padded length. Since our buffer is defined with even size, + an odd offset implies that it has some room left. */ + if ((Object_Record_Offset & 1) != 0) + Object_Record_Buffer[Object_Record_Offset++] = '\0'; + } +#endif /* not VMS */ + + /* Write the data to the file. */ + if (write (VMS_Object_File_FD, Object_Record_Buffer, Object_Record_Offset) + != Object_Record_Offset) + error (_("I/O error writing VMS object file")); + + /* The buffer is now empty. */ + Object_Record_Offset = 0; +} + + +/* Declare a particular type of object file record. */ + +static void +Set_VMS_Object_File_Record (Type) + int Type; +{ + /* If the type matches, we are done. */ + if (Type == Current_Object_Record_Type) + return; + /* Otherwise: flush the buffer. */ + Flush_VMS_Object_Record_Buffer (); + /* Remember the new type. */ + Current_Object_Record_Type = Type; +} + + +/* Close the VMS Object file. */ + +static void +Close_VMS_Object_File () +{ + /* Flush (should never be necessary) and reset saved record-type context. */ + Set_VMS_Object_File_Record (-1); + +#ifndef VMS /* For cross-assembly purposes. */ + { + char RecLen[2]; + int minus_one = -1; + + /* Write a 2 byte record-length field of -1 into the file, which + means end-of-block when read, hence end-of-file when occurring + in the file's last block. It is only needed for variable-length + record files transferred to VMS as fixed-length record files + (typical for binary FTP; NFS shouldn't need it, but it won't hurt). */ + md_number_to_chars (RecLen, minus_one, 2); + write (VMS_Object_File_FD, RecLen, 2); + } +#else + /* When written on a VMS system, the file header (cf inode) will record + the actual end-of-file position and no inline marker is needed. */ +#endif + + close (VMS_Object_File_FD); +} + + + /****** Text Information and Relocation routines ******/ + + +/* Stack Psect base followed by signed, varying-sized offset. + Common to several object records. */ + +static void +vms_tir_stack_psect (Psect_Index, Offset, Force) + int Psect_Index; + int Offset; + int Force; +{ + int psect_width, offset_width; + + psect_width = ((unsigned) Psect_Index > 255) ? 2 : 1; + offset_width = (Force || Offset > 32767 || Offset < -32768) ? 4 + : (Offset > 127 || Offset < -128) ? 2 : 1; +#define Sta_P(p,o) (((o)<<1) | ((p)-1)) + /* byte or word psect; byte, word, or longword offset */ + switch (Sta_P(psect_width,offset_width)) + { + case Sta_P(1,1): PUT_CHAR (TIR_S_C_STA_PB); + PUT_CHAR ((char)(unsigned char) Psect_Index); + PUT_CHAR ((char) Offset); + break; + case Sta_P(1,2): PUT_CHAR (TIR_S_C_STA_PW); + PUT_CHAR ((char)(unsigned char) Psect_Index); + PUT_SHORT (Offset); + break; + case Sta_P(1,4): PUT_CHAR (TIR_S_C_STA_PL); + PUT_CHAR ((char)(unsigned char) Psect_Index); + PUT_LONG (Offset); + break; + case Sta_P(2,1): PUT_CHAR (TIR_S_C_STA_WPB); + PUT_SHORT (Psect_Index); + PUT_CHAR ((char) Offset); + break; + case Sta_P(2,2): PUT_CHAR (TIR_S_C_STA_WPW); + PUT_SHORT (Psect_Index); + PUT_SHORT (Offset); + break; + case Sta_P(2,4): PUT_CHAR (TIR_S_C_STA_WPL); + PUT_SHORT (Psect_Index); + PUT_LONG (Offset); + break; + } +#undef Sta_P +} + + +/* Store immediate data in current Psect. */ + +static void +VMS_Store_Immediate_Data (Pointer, Size, Record_Type) + const char *Pointer; + int Size; + int Record_Type; +{ + register int i; + + Set_VMS_Object_File_Record (Record_Type); + /* We can only store as most 128 bytes at a time due to the way that + TIR commands are encoded. */ + while (Size > 0) + { + i = (Size > 128) ? 128 : Size; + Size -= i; + /* If we cannot accommodate this record, flush the buffer. */ + if ((Object_Record_Offset + i + 1) >= sizeof Object_Record_Buffer) + Flush_VMS_Object_Record_Buffer (); + /* If the buffer is empty we must insert record type. */ + if (Object_Record_Offset == 0) + PUT_CHAR (Record_Type); + /* Store the count. The Store Immediate TIR command is implied by + a negative command byte, and the length of the immediate data + is abs(command_byte). So, we write the negated length value. */ + PUT_CHAR ((char) (-i & 0xff)); + /* Now store the data. */ + while (--i >= 0) + PUT_CHAR (*Pointer++); + } + /* Flush the buffer if it is more than 75% full. */ + if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4)) + Flush_VMS_Object_Record_Buffer (); +} + + +/* Make a data reference. */ + +static void +VMS_Set_Data (Psect_Index, Offset, Record_Type, Force) + int Psect_Index; + int Offset; + int Record_Type; + int Force; +{ + Set_VMS_Object_File_Record (Record_Type); + /* If the buffer is empty we must insert the record type. */ + if (Object_Record_Offset == 0) + PUT_CHAR (Record_Type); + /* Stack the Psect base with its offset. */ + vms_tir_stack_psect (Psect_Index, Offset, Force); + /* Set relocation base. */ + PUT_CHAR (TIR_S_C_STO_PIDR); + /* Flush the buffer if it is more than 75% full. */ + if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4)) + Flush_VMS_Object_Record_Buffer (); +} + + +/* Make a debugger reference to a struct, union or enum. */ + +static void +VMS_Store_Struct (Struct_Index) + int Struct_Index; +{ + /* We are writing a debug record. */ + Set_VMS_Object_File_Record (OBJ_S_C_DBG); + /* If the buffer is empty we must insert the record type. */ + if (Object_Record_Offset == 0) + PUT_CHAR (OBJ_S_C_DBG); + PUT_CHAR (TIR_S_C_STA_UW); + PUT_SHORT (Struct_Index); + PUT_CHAR (TIR_S_C_CTL_STKDL); + PUT_CHAR (TIR_S_C_STO_L); + /* Flush the buffer if it is more than 75% full. */ + if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4)) + Flush_VMS_Object_Record_Buffer (); +} + + +/* Make a debugger reference to partially define a struct, union or enum. */ + +static void +VMS_Def_Struct (Struct_Index) + int Struct_Index; +{ + /* We are writing a debug record. */ + Set_VMS_Object_File_Record (OBJ_S_C_DBG); + /* If the buffer is empty we must insert the record type. */ + if (Object_Record_Offset == 0) + PUT_CHAR (OBJ_S_C_DBG); + PUT_CHAR (TIR_S_C_STA_UW); + PUT_SHORT (Struct_Index); + PUT_CHAR (TIR_S_C_CTL_DFLOC); + /* Flush the buffer if it is more than 75% full. */ + if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4)) + Flush_VMS_Object_Record_Buffer (); +} + +static void +VMS_Set_Struct (Struct_Index) + int Struct_Index; +{ /* see previous functions for comments */ + Set_VMS_Object_File_Record (OBJ_S_C_DBG); + if (Object_Record_Offset == 0) + PUT_CHAR (OBJ_S_C_DBG); + PUT_CHAR (TIR_S_C_STA_UW); + PUT_SHORT (Struct_Index); + PUT_CHAR (TIR_S_C_CTL_STLOC); + if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4)) + Flush_VMS_Object_Record_Buffer (); +} + + + /****** Traceback Information routines ******/ + + +/* Write the Traceback Module Begin record. */ + +static void +VMS_TBT_Module_Begin () +{ + register char *cp, *cp1; + int Size; + char Local[256]; + + /* Arrange to store the data locally (leave room for size byte). */ + cp = &Local[1]; + /* Begin module. */ + *cp++ = DST_S_C_MODBEG; + *cp++ = 0; /* flags; not used */ + /* + * Language type == "C" + * + * (FIXME: this should be based on the input...) + */ + COPY_LONG (cp, DST_S_C_C); + cp += 4; + /* Store the module name. */ + *cp++ = (char) strlen (Module_Name); + cp1 = Module_Name; + while (*cp1) + *cp++ = *cp1++; + /* Now we can store the record size. */ + Size = (cp - Local); + Local[0] = Size - 1; + /* Put it into the object record. */ + VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_TBT); +} + + +/* Write the Traceback Module End record. */ + +static void +VMS_TBT_Module_End () +{ + char Local[2]; + + /* End module. */ + Local[0] = 1; + Local[1] = DST_S_C_MODEND; + /* Put it into the object record. */ + VMS_Store_Immediate_Data (Local, 2, OBJ_S_C_TBT); +} + + +/* Write a Traceback Routine Begin record. */ + +static void +VMS_TBT_Routine_Begin (symbolP, Psect) + symbolS *symbolP; + int Psect; +{ + register char *cp, *cp1; + char *Name; + int Offset; + int Size; + char Local[512]; + + /* Strip the leading "_" from the name. */ + Name = S_GET_NAME (symbolP); + if (*Name == '_') + Name++; + /* Get the text psect offset. */ + Offset = S_GET_VALUE (symbolP); + /* Set the record size. */ + Size = 1 + 1 + 4 + 1 + strlen (Name); + Local[0] = Size; + /* DST type "routine begin". */ + Local[1] = DST_S_C_RTNBEG; + /* Uses CallS/CallG. */ + Local[2] = 0; + /* Store the data so far. */ + VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_TBT); + /* Make sure we are still generating a OBJ_S_C_TBT record. */ + if (Object_Record_Offset == 0) + PUT_CHAR (OBJ_S_C_TBT); + /* Stack the address. */ + vms_tir_stack_psect (Psect, Offset, 0); + /* Store the data reference. */ + PUT_CHAR (TIR_S_C_STO_PIDR); + /* Store the counted string as data. */ + cp = Local; + cp1 = Name; + Size = strlen (cp1) + 1; + *cp++ = Size - 1; + while (*cp1) + *cp++ = *cp1++; + VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_TBT); +} + + +/* Write a Traceback Routine End record. + + We *must* search the symbol table to find the next routine, since the + assember has a way of reassembling the symbol table OUT OF ORDER Thus + the next routine in the symbol list is not necessarily the next one in + memory. For debugging to work correctly we must know the size of the + routine. */ + +static void +VMS_TBT_Routine_End (Max_Size, sp) + int Max_Size; + symbolS *sp; +{ + symbolS *symbolP; + int Size = 0x7fffffff; + char Local[16]; + valueT sym_value, sp_value = S_GET_VALUE (sp); + + for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) + { + if (!S_IS_DEBUG (symbolP) && S_GET_TYPE (symbolP) == N_TEXT) + { + if (*S_GET_NAME (symbolP) == 'L') + continue; + sym_value = S_GET_VALUE (symbolP); + if (sym_value > sp_value && sym_value < Size) + Size = sym_value; + + /* + * Dummy labels like "gcc_compiled." should no longer reach here. + */ +#if 0 + else + /* check if gcc_compiled. has size of zero */ + if (sym_value == sp_value && + sp != symbolP && + (!strcmp (S_GET_NAME (sp), "gcc_compiled.") || + !strcmp (S_GET_NAME (sp), "gcc2_compiled."))) + Size = sym_value; +#endif + } + } + if (Size == 0x7fffffff) + Size = Max_Size; + Size -= sp_value; /* and get the size of the routine */ + /* Record Size. */ + Local[0] = 6; + /* DST type is "routine end". */ + Local[1] = DST_S_C_RTNEND; + Local[2] = 0; /* unused */ + /* Size of routine. */ + COPY_LONG (&Local[3], Size); + /* Store the record. */ + VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_TBT); +} + + +/* Write a Traceback Block Begin record. */ + +static void +VMS_TBT_Block_Begin (symbolP, Psect, Name) + symbolS *symbolP; + int Psect; + char *Name; +{ + register char *cp, *cp1; + int Offset; + int Size; + char Local[512]; + + /* Set the record size. */ + Size = 1 + 1 + 4 + 1 + strlen (Name); + Local[0] = Size; + /* DST type is "begin block"; we simulate with a phony routine. */ + Local[1] = DST_S_C_BLKBEG; + /* Uses CallS/CallG. */ + Local[2] = 0; + /* Store the data so far. */ + VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_DBG); + /* Make sure we are still generating a debug record. */ + if (Object_Record_Offset == 0) + PUT_CHAR (OBJ_S_C_DBG); + /* Now get the symbol address. */ + PUT_CHAR (TIR_S_C_STA_WPL); + PUT_SHORT (Psect); + /* Get the text psect offset. */ + Offset = S_GET_VALUE (symbolP); + PUT_LONG (Offset); + /* Store the data reference. */ + PUT_CHAR (TIR_S_C_STO_PIDR); + /* Store the counted string as data. */ + cp = Local; + cp1 = Name; + Size = strlen (cp1) + 1; + *cp++ = Size - 1; + while (*cp1) + *cp++ = *cp1++; + VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_DBG); +} + + +/* Write a Traceback Block End record. */ + +static void +VMS_TBT_Block_End (Size) + valueT Size; +{ + char Local[16]; + + Local[0] = 6; /* record length */ + /* DST type is "block end"; simulate with a phony end routine. */ + Local[1] = DST_S_C_BLKEND; + Local[2] = 0; /* unused, must be zero */ + COPY_LONG (&Local[3], Size); + VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_DBG); +} + + +/* Write a Line number <-> Program Counter correlation record. */ + +static void +VMS_TBT_Line_PC_Correlation (Line_Number, Offset, Psect, Do_Delta) + int Line_Number; + int Offset; + int Psect; + int Do_Delta; +{ + register char *cp; + char Local[64]; + + if (Do_Delta == 0) + { + /* + * If not delta, set our PC/Line number correlation. + */ + cp = &Local[1]; /* Put size in Local[0] later. */ + /* DST type is "Line Number/PC correlation". */ + *cp++ = DST_S_C_LINE_NUM; + /* Set Line number. */ + if (Line_Number - 1 <= 255) + { + *cp++ = DST_S_C_SET_LINUM_B; + *cp++ = (char) (Line_Number - 1); + } + else if (Line_Number - 1 <= 65535) + { + *cp++ = DST_S_C_SET_LINE_NUM; + COPY_SHORT (cp, Line_Number - 1), cp += 2; + } + else + { + *cp++ = DST_S_C_SET_LINUM_L; + COPY_LONG (cp, Line_Number - 1), cp += 4; + } + /* Set PC. */ + *cp++ = DST_S_C_SET_ABS_PC; + /* Store size now that we know it, then output the data. */ + Local[0] = cp - &Local[1]; + /* Account for the space that TIR_S_C_STO_PIDR will use for the PC. */ + Local[0] += 4; /* size includes length of another longword */ + VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT); + /* Make sure we are still generating a OBJ_S_C_TBT record. */ + if (Object_Record_Offset == 0) + PUT_CHAR (OBJ_S_C_TBT); + vms_tir_stack_psect (Psect, Offset, 0); + PUT_CHAR (TIR_S_C_STO_PIDR); + /* Do a PC offset of 0 to register the line number. */ + Local[0] = 2; + Local[1] = DST_S_C_LINE_NUM; + Local[2] = 0; /* Increment PC by 0 and register line # */ + VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_TBT); + } + else + { + if (Do_Delta < 0) + { + /* + * When delta is negative, terminate the line numbers. + */ + Local[0] = 1 + 1 + 4; + Local[1] = DST_S_C_LINE_NUM; + Local[2] = DST_S_C_TERM_L; + COPY_LONG (&Local[3], Offset); + VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_TBT); + return; + } + /* + * Do a PC/Line delta. + */ + cp = &Local[1]; + *cp++ = DST_S_C_LINE_NUM; + if (Line_Number > 1) + { + /* We need to increment the line number. */ + if (Line_Number - 1 <= 255) + { + *cp++ = DST_S_C_INCR_LINUM; + *cp++ = Line_Number - 1; + } + else if (Line_Number - 1 <= 65535) + { + *cp++ = DST_S_C_INCR_LINUM_W; + COPY_SHORT (cp, Line_Number - 1), cp += 2; + } + else + { + *cp++ = DST_S_C_INCR_LINUM_L; + COPY_LONG (cp, Line_Number - 1), cp += 4; + } + } + /* + * Increment the PC + */ + if (Offset <= 128) + { + /* Small offsets are encoded as negative numbers, rather than the + usual non-negative type code followed by another data field. */ + *cp++ = (char) -Offset; + } + else if (Offset <= 65535) + { + *cp++ = DST_S_C_DELTA_PC_W; + COPY_SHORT (cp, Offset), cp += 2; + } + else + { + *cp++ = DST_S_C_DELTA_PC_L; + COPY_LONG (cp, Offset), cp += 4; + } + /* Set size now that be know it, then output the data. */ + Local[0] = cp - &Local[1]; + VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT); + } +} + + +/* Describe a source file to the debugger. */ + +static int +VMS_TBT_Source_File (Filename, ID_Number) + char *Filename; + int ID_Number; +{ + register char *cp; + int len, rfo, ffb, ebk; + char cdt[8]; + char Local[512]; +#ifdef VMS /* Used for native assembly */ + unsigned Status; + struct FAB fab; /* RMS file access block */ + struct NAM nam; /* file name information */ + struct XABDAT xabdat; /* date+time fields */ + struct XABFHC xabfhc; /* file header characteristics */ + char resultant_string_buffer[255 + 1]; + + /* + * Set up RMS structures: + */ + /* FAB -- file access block */ + memset ((char *) &fab, 0, sizeof fab); + fab.fab$b_bid = FAB$C_BID; + fab.fab$b_bln = (unsigned char) sizeof fab; + fab.fab$l_fna = Filename; + fab.fab$b_fns = (unsigned char) strlen (Filename); + fab.fab$l_nam = (char *) &nam; + fab.fab$l_xab = (char *) &xabdat; + /* NAM -- file name block */ + memset ((char *) &nam, 0, sizeof nam); + nam.nam$b_bid = NAM$C_BID; + nam.nam$b_bln = (unsigned char) sizeof nam; + nam.nam$l_rsa = resultant_string_buffer; + nam.nam$b_rss = (unsigned char) (sizeof resultant_string_buffer - 1); + /* XABs -- extended attributes blocks */ + memset ((char *) &xabdat, 0, sizeof xabdat); + xabdat.xab$b_cod = XAB$C_DAT; + xabdat.xab$b_bln = (unsigned char) sizeof xabdat; + xabdat.xab$l_nxt = (char *) &xabfhc; + memset ((char *) &xabfhc, 0, sizeof xabfhc); + xabfhc.xab$b_cod = XAB$C_FHC; + xabfhc.xab$b_bln = (unsigned char) sizeof xabfhc; + xabfhc.xab$l_nxt = 0; + /* + * Get the file information + */ + Status = sys$open (&fab); + if (!(Status & 1)) + { + as_tsktsk (_("Couldn't find source file \"%s\", status=%%X%x"), + Filename, Status); + return 0; + } + sys$close (&fab); + /* Now extract fields of interest. */ + memcpy (cdt, (char *) &xabdat.xab$q_cdt, 8); /* creation date */ + ebk = xabfhc.xab$l_ebk; /* end-of-file block */ + ffb = xabfhc.xab$w_ffb; /* first free byte of last block */ + rfo = xabfhc.xab$b_rfo; /* record format */ + len = nam.nam$b_rsl; /* length of Filename */ + resultant_string_buffer[len] = '\0'; + Filename = resultant_string_buffer; /* full filename */ +#else /* Cross-assembly */ + /* [Perhaps we ought to use actual values derived from stat() here?] */ + memset (cdt, 0, 8); /* null VMS quadword binary time */ + ebk = ffb = rfo = 0; + len = strlen (Filename); + if (len > 255) /* a single byte is used as count prefix */ + { + Filename += (len - 255); /* tail end is more significant */ + len = 255; + } +#endif /* VMS */ + + cp = &Local[1]; /* fill in record length later */ + *cp++ = DST_S_C_SOURCE; /* DST type is "source file" */ + *cp++ = DST_S_C_SRC_FORMFEED; /* formfeeds count as source records */ + *cp++ = DST_S_C_SRC_DECLFILE; /* declare source file */ + know (cp == &Local[4]); + *cp++ = 0; /* fill in this length below */ + *cp++ = 0; /* flags; must be zero */ + COPY_SHORT (cp, ID_Number), cp += 2; /* file ID number */ + memcpy (cp, cdt, 8), cp += 8; /* creation date+time */ + COPY_LONG (cp, ebk), cp += 4; /* end-of-file block */ + COPY_SHORT (cp, ffb), cp += 2; /* first free byte of last block */ + *cp++ = (char) rfo; /* RMS record format */ + /* Filename. */ + *cp++ = (char) len; + while (--len >= 0) + *cp++ = *Filename++; + /* Library module name (none). */ + *cp++ = 0; + /* Now that size is known, fill it in and write out the record. */ + Local[4] = cp - &Local[5]; /* source file declaration size */ + Local[0] = cp - &Local[1]; /* TBT record size */ + VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT); + return 1; +} + + +/* Traceback information is described in terms of lines from compiler + listing files, not lines from source files. We need to set up the + correlation between listing line numbers and source line numbers. + Since gcc's .stabn directives refer to the source lines, we just + need to describe a one-to-one correspondence. */ + +static void +VMS_TBT_Source_Lines (ID_Number, Starting_Line_Number, Number_Of_Lines) + int ID_Number; + int Starting_Line_Number; + int Number_Of_Lines; +{ + char *cp; + int chunk_limit; + char Local[128]; /* room enough to describe 1310700 lines... */ + + cp = &Local[1]; /* Put size in Local[0] later. */ + *cp++ = DST_S_C_SOURCE; /* DST type is "source file". */ + *cp++ = DST_S_C_SRC_SETFILE; /* Set Source File. */ + COPY_SHORT (cp, ID_Number), cp += 2; /* File ID Number. */ + /* Set record number and define lines. Since no longword form of + SRC_DEFLINES is available, we need to be able to cope with any huge + files a chunk at a time. It doesn't matter for tracebacks, since + unspecified lines are mapped one-to-one and work out right, but it + does matter within the debugger. Without this explicit mapping, + it will complain about lines not existing in the module. */ + chunk_limit = (sizeof Local - 5) / 6; + if (Number_Of_Lines > 65535 * chunk_limit) /* avoid buffer overflow */ + Number_Of_Lines = 65535 * chunk_limit; + while (Number_Of_Lines > 65535) + { + *cp++ = DST_S_C_SRC_SETREC_L; + COPY_LONG (cp, Starting_Line_Number), cp += 4; + *cp++ = DST_S_C_SRC_DEFLINES_W; + COPY_SHORT (cp, 65535), cp += 2; + Starting_Line_Number += 65535; + Number_Of_Lines -= 65535; + } + /* Set record number and define lines, normal case. */ + if (Starting_Line_Number <= 65535) + { + *cp++ = DST_S_C_SRC_SETREC_W; + COPY_SHORT (cp, Starting_Line_Number), cp += 2; + } + else + { + *cp++ = DST_S_C_SRC_SETREC_L; + COPY_LONG (cp, Starting_Line_Number), cp += 4; + } + *cp++ = DST_S_C_SRC_DEFLINES_W; + COPY_SHORT (cp, Number_Of_Lines), cp += 2; + /* Set size now that be know it, then output the data. */ + Local[0] = cp - &Local[1]; + VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT); +} + + + /****** Debugger Information support routines ******/ + + +/* This routine locates a file in the list of files. If an entry does + not exist, one is created. For include files, a new entry is always + created such that inline functions can be properly debugged. */ + +static struct input_file * +find_file (sp) + symbolS *sp; +{ + struct input_file *same_file = 0; + struct input_file *fpnt, *last = 0; + char *sp_name; + + for (fpnt = file_root; fpnt; fpnt = fpnt->next) + { + if (fpnt->spnt == sp) + return fpnt; + last = fpnt; + } + sp_name = S_GET_NAME (sp); + for (fpnt = file_root; fpnt; fpnt = fpnt->next) + { + if (strcmp (sp_name, fpnt->name) == 0) + { + if (fpnt->flag == 1) + return fpnt; + same_file = fpnt; + break; + } + } + fpnt = (struct input_file *) xmalloc (sizeof (struct input_file)); + if (!file_root) + file_root = fpnt; + else + last->next = fpnt; + fpnt->next = 0; + fpnt->name = sp_name; + fpnt->min_line = 0x7fffffff; + fpnt->max_line = 0; + fpnt->offset = 0; + fpnt->flag = 0; + fpnt->file_number = 0; + fpnt->spnt = sp; + fpnt->same_file_fpnt = same_file; + return fpnt; +} + + +/* This routine converts a number string into an integer, and stops when + it sees an invalid character. The return value is the address of the + character just past the last character read. No error is generated. */ + +static char * +cvt_integer (str, rtn) + char *str; + int *rtn; +{ + int ival = 0, sgn = 1; + + if (*str == '-') + sgn = -1, ++str; + while (*str >= '0' && *str <= '9') + ival = 10 * ival + *str++ - '0'; + *rtn = sgn * ival; + return str; +} + + +/* + * The following functions and definitions are used to generate object + * records that will describe program variables to the VMS debugger. + * + * This file contains many of the routines needed to output debugging info + * into the object file that the VMS debugger needs to understand symbols. + * These routines are called very late in the assembly process, and thus + * we can be fairly lax about changing things, since the GSD and the TIR + * sections have already been output. + */ + + +/* This routine fixes the names that are generated by C++, ".this" is a good + example. The period does not work for the debugger, since it looks like + the syntax for a structure element, and thus it gets mightily confused. + + We also use this to strip the PsectAttribute hack from the name before we + write a debugger record. */ + +static char * +fix_name (pnt) + char *pnt; +{ + char *pnt1; + + /* Kill any leading "_". */ + if (*pnt == '_') + pnt++; + + /* Is there a Psect Attribute to skip?? */ + if (HAS_PSECT_ATTRIBUTES (pnt)) + { + /* Yes: Skip it. */ + pnt += PSECT_ATTRIBUTES_STRING_LENGTH; + while (*pnt) + { + if ((pnt[0] == '$') && (pnt[1] == '$')) + { + pnt += 2; + break; + } + pnt++; + } + } + + /* Here we fix the .this -> $this conversion. */ + for (pnt1 = pnt; *pnt1 != 0; pnt1++) + if (*pnt1 == '.') + *pnt1 = '$'; + + return pnt; +} + + +/* When defining a structure, this routine is called to find the name of + the actual structure. It is assumed that str points to the equal sign + in the definition, and it moves backward until it finds the start of the + name. If it finds a 0, then it knows that this structure def is in the + outermost level, and thus symbol_name points to the symbol name. */ + +static char * +get_struct_name (str) + char *str; +{ + char *pnt; + pnt = str; + while ((*pnt != ':') && (*pnt != '\0')) + pnt--; + if (*pnt == '\0') + return (char *) symbol_name; + *pnt-- = '\0'; + while ((*pnt != ';') && (*pnt != '=')) + pnt--; + if (*pnt == ';') + return pnt + 1; + while ((*pnt < '0') || (*pnt > '9')) + pnt++; + while ((*pnt >= '0') && (*pnt <= '9')) + pnt++; + return pnt; +} + + +/* Search symbol list for type number dbx_type. + Return a pointer to struct. */ + +static struct VMS_DBG_Symbol * +find_symbol (dbx_type) + int dbx_type; +{ + struct VMS_DBG_Symbol *spnt; + + spnt = VMS_Symbol_type_list[SYMTYP_HASH (dbx_type)]; + while (spnt) + { + if (spnt->dbx_type == dbx_type) + break; + spnt = spnt->next; + } + if (!spnt || spnt->advanced != ALIAS) + return spnt; + return find_symbol (spnt->type2); +} + + +#if 0 /* obsolete */ +/* this routine puts info into either Local or Asuffix, depending on the sign + * of size. The reason is that it is easier to build the variable descriptor + * backwards, while the array descriptor is best built forwards. In the end + * they get put together, if there is not a struct/union/enum along the way + */ +static void +push (value, size1) + int value, size1; +{ + if (size1 < 0) + { + size1 = -size1; + if (Lpnt < size1) + { + overflow = 1; + Lpnt = 1; + return; + } + Lpnt -= size1; + md_number_to_chars (&Local[Lpnt + 1], value, size1); + } + else + { + if (Apoint + size1 >= MAX_DEBUG_RECORD) + { + overflow = 1; + Apoint = MAX_DEBUG_RECORD - 1; + return; + } + md_number_to_chars (&Asuffix[Apoint], value, size1); + Apoint += size1; + } +} +#endif + + +static void +fpush (value, size) + int value, size; +{ + if (Apoint + size >= MAX_DEBUG_RECORD) + { + overflow = 1; + Apoint = MAX_DEBUG_RECORD - 1; + return; + } + if (size == 1) + Asuffix[Apoint++] = (char) value; + else + { + md_number_to_chars (&Asuffix[Apoint], value, size); + Apoint += size; + } +} + +static void +rpush (value, size) + int value, size; +{ + if (Lpnt < size) + { + overflow = 1; + Lpnt = 1; + return; + } + if (size == 1) + Local[Lpnt--] = (char) value; + else + { + Lpnt -= size; + md_number_to_chars (&Local[Lpnt + 1], value, size); + } +} + + +/* This routine generates the array descriptor for a given array. */ + +static void +array_suffix (spnt2) + struct VMS_DBG_Symbol *spnt2; +{ + struct VMS_DBG_Symbol *spnt; + struct VMS_DBG_Symbol *spnt1; + int rank; + int total_size; + + rank = 0; + spnt = spnt2; + while (spnt->advanced != ARRAY) + { + spnt = find_symbol (spnt->type2); + if (!spnt) + return; + } + spnt1 = spnt; + total_size = 1; + while (spnt1->advanced == ARRAY) + { + rank++; + total_size *= (spnt1->index_max - spnt1->index_min + 1); + spnt1 = find_symbol (spnt1->type2); + } + total_size = total_size * spnt1->data_size; + fpush (spnt1->data_size, 2); /* element size */ + if (spnt1->VMS_type == DBG_S_C_ADVANCED_TYPE) + fpush (0, 1); + else + fpush (spnt1->VMS_type, 1); /* element type */ + fpush (DSC_K_CLASS_A, 1); /* descriptor class */ + fpush (0, 4); /* base address */ + fpush (0, 1); /* scale factor -- not applicable */ + fpush (0, 1); /* digit count -- not applicable */ + fpush (0xc0, 1); /* flags: multiplier block & bounds present */ + fpush (rank, 1); /* number of dimensions */ + fpush (total_size, 4); + fpush (0, 4); /* pointer to element [0][0]...[0] */ + spnt1 = spnt; + while (spnt1->advanced == ARRAY) + { + fpush (spnt1->index_max - spnt1->index_min + 1, 4); + spnt1 = find_symbol (spnt1->type2); + } + spnt1 = spnt; + while (spnt1->advanced == ARRAY) + { + fpush (spnt1->index_min, 4); + fpush (spnt1->index_max, 4); + spnt1 = find_symbol (spnt1->type2); + } +} + + +/* This routine generates the start of a variable descriptor based upon + a struct/union/enum that has yet to be defined. We define this spot as + a new location, and save four bytes for the address. When the struct is + finally defined, then we can go back and plug in the correct address. */ + +static void +new_forward_ref (dbx_type) + int dbx_type; +{ + struct forward_ref *fpnt; + fpnt = (struct forward_ref *) xmalloc (sizeof (struct forward_ref)); + fpnt->next = f_ref_root; + f_ref_root = fpnt; + fpnt->dbx_type = dbx_type; + fpnt->struc_numb = ++structure_count; + fpnt->resolved = 'N'; + rpush (DST_K_TS_IND, 1); /* indirect type specification */ + total_len = 5; + rpush (total_len, 2); + struct_number = -fpnt->struc_numb; +} + + +/* This routine generates the variable descriptor used to describe non-basic + variables. It calls itself recursively until it gets to the bottom of it + all, and then builds the descriptor backwards. It is easiest to do it + this way since we must periodically write length bytes, and it is easiest + if we know the value when it is time to write it. */ + +static int +gen1 (spnt, array_suffix_len) + struct VMS_DBG_Symbol *spnt; + int array_suffix_len; +{ + struct VMS_DBG_Symbol *spnt1; + int i; + + switch (spnt->advanced) + { + case VOID: + rpush (DBG_S_C_VOID, 1); + total_len += 1; + rpush (total_len, 2); + return 0; + case BASIC: + case FUNCTION: + if (array_suffix_len == 0) + { + rpush (spnt->VMS_type, 1); + rpush (DBG_S_C_BASIC, 1); + total_len = 2; + rpush (total_len, 2); + return 1; + } + rpush (0, 4); + rpush (DST_K_VFLAGS_DSC, 1); + rpush (DST_K_TS_DSC, 1); /* descriptor type specification */ + total_len = -2; + return 1; + case STRUCT: + case UNION: + case ENUM: + struct_number = spnt->struc_numb; + if (struct_number < 0) + { + new_forward_ref (spnt->dbx_type); + return 1; + } + rpush (DBG_S_C_STRUCT, 1); + total_len = 5; + rpush (total_len, 2); + return 1; + case POINTER: + spnt1 = find_symbol (spnt->type2); + i = 1; + if (!spnt1) + new_forward_ref (spnt->type2); + else + i = gen1 (spnt1, 0); + if (i) + { /* (*void) is a special case, do not put pointer suffix */ + rpush (DBG_S_C_POINTER, 1); + total_len += 3; + rpush (total_len, 2); + } + return 1; + case ARRAY: + spnt1 = spnt; + while (spnt1->advanced == ARRAY) + { + spnt1 = find_symbol (spnt1->type2); + if (!spnt1) + { + as_tsktsk (_("debugger forward reference error, dbx type %d"), + spnt->type2); + return 0; + } + } +/* It is too late to generate forward references, so the user gets a message. + * This should only happen on a compiler error */ + (void) gen1 (spnt1, 1); + i = Apoint; + array_suffix (spnt); + array_suffix_len = Apoint - i; + switch (spnt1->advanced) + { + case BASIC: + case FUNCTION: + break; + default: + rpush (0, 2); + total_len += 2; + rpush (total_len, 2); + rpush (DST_K_VFLAGS_DSC, 1); + rpush (1, 1); /* flags: element value spec included */ + rpush (1, 1); /* one dimension */ + rpush (DBG_S_C_COMPLEX_ARRAY, 1); + } + total_len += array_suffix_len + 8; + rpush (total_len, 2); + break; + default: /* lint suppression */ + break; + } + return 0; +} + + +/* This generates a suffix for a variable. If it is not a defined type yet, + then dbx_type contains the type we are expecting so we can generate a + forward reference. This calls gen1 to build most of the descriptor, and + then it puts the icing on at the end. It then dumps whatever is needed + to get a complete descriptor (i.e. struct reference, array suffix). */ + +static void +generate_suffix (spnt, dbx_type) + struct VMS_DBG_Symbol *spnt; + int dbx_type; +{ + static const char pvoid[6] = { + 5, /* record.length == 5 */ + DST_K_TYPSPEC, /* record.type == 1 (type specification) */ + 0, /* name.length == 0, no name follows */ + 1, 0, /* type.length == 1 {2 bytes, little endian} */ + DBG_S_C_VOID /* type.type == 5 (pointer to unspecified) */ + }; + int i; + + Apoint = 0; + Lpnt = MAX_DEBUG_RECORD - 1; + total_len = 0; + struct_number = 0; + overflow = 0; + if (!spnt) + new_forward_ref (dbx_type); + else + { + if (spnt->VMS_type != DBG_S_C_ADVANCED_TYPE) + return; /* no suffix needed */ + gen1 (spnt, 0); + } + rpush (0, 1); /* no name (len==0) */ + rpush (DST_K_TYPSPEC, 1); + total_len += 4; + rpush (total_len, 1); + /* If the variable descriptor overflows the record, output a descriptor + for a pointer to void. */ + if ((total_len >= MAX_DEBUG_RECORD) || overflow) + { + as_warn (_("Variable descriptor %d too complicated. Defined as `void *'."), + spnt->dbx_type); + VMS_Store_Immediate_Data (pvoid, 6, OBJ_S_C_DBG); + return; + } + i = 0; + while (Lpnt < MAX_DEBUG_RECORD - 1) + Local[i++] = Local[++Lpnt]; + Lpnt = i; + /* we use this for reference to structure that has already been defined */ + if (struct_number > 0) + { + VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG); + Lpnt = 0; + VMS_Store_Struct (struct_number); + } + /* We use this for a forward reference to a structure that has yet to + be defined. We store four bytes of zero to make room for the actual + address once it is known. */ + if (struct_number < 0) + { + struct_number = -struct_number; + VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG); + Lpnt = 0; + VMS_Def_Struct (struct_number); + COPY_LONG (&Local[Lpnt], 0L); + Lpnt += 4; + VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG); + Lpnt = 0; + } + i = 0; + while (i < Apoint) + Local[Lpnt++] = Asuffix[i++]; + if (Lpnt != 0) + VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG); + Lpnt = 0; +} + + + /* "novel length" type doesn't work for simple atomic types */ +#define USE_BITSTRING_DESCRIPTOR(t) ((t)->advanced == BASIC) +#undef SETUP_BASIC_TYPES + +/* This routine generates a type description for a bitfield. */ + +static void +bitfield_suffix (spnt, width) + struct VMS_DBG_Symbol *spnt; + int width; +{ + Local[Lpnt++] = 13; /* rec.len==13 */ + Local[Lpnt++] = DST_K_TYPSPEC; /* a type specification record */ + Local[Lpnt++] = 0; /* not named */ + COPY_SHORT (&Local[Lpnt], 9); /* typ.len==9 */ + Lpnt += 2; + Local[Lpnt++] = DST_K_TS_NOV_LENG; /* This type is a "novel length" + incarnation of some other type. */ + COPY_LONG (&Local[Lpnt], width); /* size in bits == novel length */ + Lpnt += 4; + VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG); + Lpnt = 0; + /* assert( spnt->struc_numb > 0 ); */ + VMS_Store_Struct (spnt->struc_numb); /* output 4 more bytes */ +} + + +/* Formally define a builtin type, so that it can serve as the target of + an indirect reference. It makes bitfield_suffix() easier by avoiding + the need to use a forward reference for the first occurrence of each + type used in a bitfield. */ + +static void +setup_basic_type (spnt) + struct VMS_DBG_Symbol *spnt; +{ +#ifdef SETUP_BASIC_TYPES + /* This would be very useful if "novel length" fields actually worked + with basic types like they do with enumerated types. However, + they do not, so this isn't worth doing just so that you can use + EXAMINE/TYPE=(__long_long_int) instead of EXAMINE/QUAD. */ + char *p; +#ifndef SETUP_SYNONYM_TYPES + /* This determines whether compatible things like `int' and `long int' + ought to have distinct type records rather than sharing one. */ + struct VMS_DBG_Symbol *spnt2; + + /* first check whether this type has already been seen by another name */ + for (spnt2 = VMS_Symbol_type_list[SYMTYP_HASH (spnt->VMS_type)]; + spnt2; + spnt2 = spnt2->next) + if (spnt2 != spnt && spnt2->VMS_type == spnt->VMS_type) + { + spnt->struc_numb = spnt2->struc_numb; + return; + } +#endif + + /* `structure number' doesn't really mean `structure'; it means an index + into a linker maintained set of saved locations which can be referenced + again later. */ + spnt->struc_numb = ++structure_count; + VMS_Def_Struct (spnt->struc_numb); /* remember where this type lives */ + /* define the simple scalar type */ + Local[Lpnt++] = 6 + strlen (symbol_name) + 2; /* rec.len */ + Local[Lpnt++] = DST_K_TYPSPEC; /* rec.typ==type specification */ + Local[Lpnt++] = strlen (symbol_name) + 2; + Local[Lpnt++] = '_'; /* prefix name with "__" */ + Local[Lpnt++] = '_'; + for (p = symbol_name; *p; p++) + Local[Lpnt++] = *p == ' ' ? '_' : *p; + COPY_SHORT (&Local[Lpnt], 2); /* typ.len==2 */ + Lpnt += 2; + Local[Lpnt++] = DST_K_TS_ATOM; /* typ.kind is simple type */ + Local[Lpnt++] = spnt->VMS_type; /* typ.type */ + VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG); + Lpnt = 0; +#endif /* SETUP_BASIC_TYPES */ + return; +} + + +/* This routine generates a symbol definition for a C symbol for the debugger. + It takes a psect and offset for global symbols; if psect < 0, then this is + a local variable and the offset is relative to FP. In this case it can + be either a variable (Offset < 0) or a parameter (Offset > 0). */ + +static void +VMS_DBG_record (spnt, Psect, Offset, Name) + struct VMS_DBG_Symbol *spnt; + int Psect; + int Offset; + char *Name; +{ + char *Name_pnt; + int len; + int i = 0; + + /* if there are bad characters in name, convert them */ + Name_pnt = fix_name (Name); + + len = strlen (Name_pnt); + if (Psect < 0) + { /* this is a local variable, referenced to SP */ + Local[i++] = 7 + len; + Local[i++] = spnt->VMS_type; + Local[i++] = (Offset > 0) ? DBG_C_FUNCTION_PARAM : DBG_C_LOCAL_SYM; + COPY_LONG (&Local[i], Offset); + i += 4; + } + else + { + Local[i++] = 7 + len; + Local[i++] = spnt->VMS_type; + Local[i++] = DST_K_VALKIND_ADDR; + VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG); + i = 0; + VMS_Set_Data (Psect, Offset, OBJ_S_C_DBG, 0); + } + Local[i++] = len; + while (*Name_pnt != '\0') + Local[i++] = *Name_pnt++; + VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG); + if (spnt->VMS_type == DBG_S_C_ADVANCED_TYPE) + generate_suffix (spnt, 0); +} + + +/* This routine parses the stabs entries in order to make the definition + for the debugger of local symbols and function parameters. */ + +static void +VMS_local_stab_Parse (sp) + symbolS *sp; +{ + struct VMS_DBG_Symbol *spnt; + char *pnt; + char *pnt1; + char *str; + int dbx_type; + + dbx_type = 0; + str = S_GET_NAME (sp); + pnt = (char *) strchr (str, ':'); + if (!pnt) + return; /* no colon present */ + pnt1 = pnt++; /* save this for later, and skip colon */ + if (*pnt == 'c') + return; /* ignore static constants */ + +/* there is one little catch that we must be aware of. Sometimes function + * parameters are optimized into registers, and the compiler, in its infiite + * wisdom outputs stabs records for *both*. In general we want to use the + * register if it is present, so we must search the rest of the symbols for + * this function to see if this parameter is assigned to a register. + */ + { + symbolS *sp1; + char *str1; + char *pnt2; + + if (*pnt == 'p') + { + for (sp1 = symbol_next (sp); sp1; sp1 = symbol_next (sp1)) + { + if (!S_IS_DEBUG (sp1)) + continue; + if (S_GET_RAW_TYPE (sp1) == N_FUN) + { + pnt2 = (char *) strchr (S_GET_NAME (sp1), ':') + 1; + if (*pnt2 == 'F' || *pnt2 == 'f') + break; + } + if (S_GET_RAW_TYPE (sp1) != N_RSYM) + continue; + str1 = S_GET_NAME (sp1); /* and get the name */ + pnt2 = str; + while (*pnt2 != ':') + { + if (*pnt2 != *str1) + break; + pnt2++; + str1++; + } + if (*str1 == ':' && *pnt2 == ':') + return; /* they are the same! lets skip this one */ + } /* for */ + pnt++; /* skip p in case no register */ + } /* if */ + } /* p block */ + + pnt = cvt_integer (pnt, &dbx_type); + spnt = find_symbol (dbx_type); + if (!spnt) + return; /*Dunno what this is*/ + *pnt1 = '\0'; + VMS_DBG_record (spnt, -1, S_GET_VALUE (sp), str); + *pnt1 = ':'; /* and restore the string */ + return; +} + + +/* This routine parses a stabs entry to find the information required + to define a variable. It is used for global and static variables. + Basically we need to know the address of the symbol. With older + versions of the compiler, const symbols are treated differently, in + that if they are global they are written into the text psect. The + global symbol entry for such a const is actually written as a program + entry point (Yuk!!), so if we cannot find a symbol in the list of + psects, we must search the entry points as well. static consts are + even harder, since they are never assigned a memory address. The + compiler passes a stab to tell us the value, but I am not sure what + to do with it. */ + +static void +VMS_stab_parse (sp, expected_type, type1, type2, Text_Psect) + symbolS *sp; + int expected_type; /* char */ + int type1, type2, Text_Psect; +{ + char *pnt; + char *pnt1; + char *str; + symbolS *sp1; + struct VMS_DBG_Symbol *spnt; + struct VMS_Symbol *vsp; + int dbx_type; + + dbx_type = 0; + str = S_GET_NAME (sp); + pnt = (char *) strchr (str, ':'); + if (!pnt) + return; /* no colon present */ + pnt1 = pnt; /* save this for later*/ + pnt++; + if (*pnt == expected_type) + { + pnt = cvt_integer (pnt + 1, &dbx_type); + spnt = find_symbol (dbx_type); + if (!spnt) + return; /*Dunno what this is*/ + /* + * Now we need to search the symbol table to find the psect and + * offset for this variable. + */ + *pnt1 = '\0'; + vsp = VMS_Symbols; + while (vsp) + { + pnt = S_GET_NAME (vsp->Symbol); + if (pnt && *pnt++ == '_' + /* make sure name is the same and symbol type matches */ + && strcmp (pnt, str) == 0 + && (S_GET_RAW_TYPE (vsp->Symbol) == type1 + || S_GET_RAW_TYPE (vsp->Symbol) == type2)) + break; + vsp = vsp->Next; + } + if (vsp) + { + VMS_DBG_record (spnt, vsp->Psect_Index, vsp->Psect_Offset, str); + *pnt1 = ':'; /* and restore the string */ + return; + } + /* The symbol was not in the symbol list, but it may be an + "entry point" if it was a constant. */ + for (sp1 = symbol_rootP; sp1; sp1 = symbol_next (sp1)) + { + /* + * Dispatch on STAB type + */ + if (S_IS_DEBUG (sp1) || (S_GET_TYPE (sp1) != N_TEXT)) + continue; + pnt = S_GET_NAME (sp1); + if (*pnt == '_') + pnt++; + if (strcmp (pnt, str) == 0) + { + if (!gave_compiler_message && expected_type == 'G') + { + char *long_const_msg = _("\ +***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"); + + as_tsktsk (long_const_msg); + gave_compiler_message = 1; + } + VMS_DBG_record (spnt, + Text_Psect, + S_GET_VALUE (sp1), + str); + *pnt1 = ':'; + /* fool assembler to not output this as a routine in the TBT */ + pnt1 = S_GET_NAME (sp1); + *pnt1 = 'L'; + S_SET_NAME (sp1, pnt1); + return; + } + } + } + *pnt1 = ':'; /* and restore the string */ + return; +} + + +/* Simpler interfaces into VMS_stab_parse(). */ + +static void +VMS_GSYM_Parse (sp, Text_Psect) + symbolS *sp; + int Text_Psect; +{ /* Global variables */ + VMS_stab_parse (sp, 'G', (N_UNDF | N_EXT), (N_DATA | N_EXT), Text_Psect); +} + +static void +VMS_LCSYM_Parse (sp, Text_Psect) + symbolS *sp; + int Text_Psect; +{ /* Static symbols - uninitialized */ + VMS_stab_parse (sp, 'S', N_BSS, -1, Text_Psect); +} + +static void +VMS_STSYM_Parse (sp, Text_Psect) + symbolS *sp; + int Text_Psect; +{ /* Static symbols - initialized */ + VMS_stab_parse (sp, 'S', N_DATA, -1, Text_Psect); +} + + +/* For register symbols, we must figure out what range of addresses + within the psect are valid. We will use the brackets in the stab + directives to give us guidance as to the PC range that this variable + is in scope. I am still not completely comfortable with this but + as I learn more, I seem to get a better handle on what is going on. + Caveat Emptor. */ + +static void +VMS_RSYM_Parse (sp, Current_Routine, Text_Psect) + symbolS *sp, *Current_Routine; + int Text_Psect; +{ + symbolS *symbolP; + struct VMS_DBG_Symbol *spnt; + char *pnt; + char *pnt1; + char *str; + int dbx_type; + int len; + int i = 0; + int bcnt = 0; + int Min_Offset = -1; /* min PC of validity */ + int Max_Offset = 0; /* max PC of validity */ + + for (symbolP = sp; symbolP; symbolP = symbol_next (symbolP)) + { + /* + * Dispatch on STAB type + */ + switch (S_GET_RAW_TYPE (symbolP)) + { + case N_LBRAC: + if (bcnt++ == 0) + Min_Offset = S_GET_VALUE (symbolP); + break; + case N_RBRAC: + if (--bcnt == 0) + Max_Offset = S_GET_VALUE (symbolP) - 1; + break; + } + if ((Min_Offset != -1) && (bcnt == 0)) + break; + if (S_GET_RAW_TYPE (symbolP) == N_FUN) + { + pnt = (char *) strchr (S_GET_NAME (symbolP), ':') + 1; + if (*pnt == 'F' || *pnt == 'f') break; + } + } + + /* Check to see that the addresses were defined. If not, then there + were no brackets in the function, and we must try to search for + the next function. Since functions can be in any order, we should + search all of the symbol list to find the correct ending address. */ + if (Min_Offset == -1) + { + int Max_Source_Offset; + int This_Offset; + + Min_Offset = S_GET_VALUE (sp); + Max_Source_Offset = Min_Offset; /* just in case no N_SLINEs found */ + for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) + switch (S_GET_RAW_TYPE (symbolP)) + { + case N_TEXT | N_EXT: + This_Offset = S_GET_VALUE (symbolP); + if (This_Offset > Min_Offset && This_Offset < Max_Offset) + Max_Offset = This_Offset; + break; + case N_SLINE: + This_Offset = S_GET_VALUE (symbolP); + if (This_Offset > Max_Source_Offset) + Max_Source_Offset = This_Offset; + break; + } + /* If this is the last routine, then we use the PC of the last source + line as a marker of the max PC for which this reg is valid. */ + if (Max_Offset == 0x7fffffff) + Max_Offset = Max_Source_Offset; + } + + dbx_type = 0; + str = S_GET_NAME (sp); + if ((pnt = (char *) strchr (str, ':')) == 0) + return; /* no colon present */ + pnt1 = pnt; /* save this for later*/ + pnt++; + if (*pnt != 'r') + return; + pnt = cvt_integer (pnt + 1, &dbx_type); + spnt = find_symbol (dbx_type); + if (!spnt) + return; /*Dunno what this is yet*/ + *pnt1 = '\0'; + pnt = fix_name (S_GET_NAME (sp)); /* if there are bad characters in name, convert them */ + len = strlen (pnt); + Local[i++] = 25 + len; + Local[i++] = spnt->VMS_type; + Local[i++] = DST_K_VFLAGS_TVS; /* trailing value specified */ + COPY_LONG (&Local[i], 1 + len); /* relative offset, beyond name */ + i += 4; + Local[i++] = len; /* name length (ascic prefix) */ + while (*pnt != '\0') + Local[i++] = *pnt++; + Local[i++] = DST_K_VS_FOLLOWS; /* value specification follows */ + COPY_SHORT (&Local[i], 15); /* length of rest of record */ + i += 2; + Local[i++] = DST_K_VS_ALLOC_SPLIT; /* split lifetime */ + Local[i++] = 1; /* one binding follows */ + VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG); + i = 0; + VMS_Set_Data (Text_Psect, Min_Offset, OBJ_S_C_DBG, 1); + VMS_Set_Data (Text_Psect, Max_Offset, OBJ_S_C_DBG, 1); + Local[i++] = DST_K_VALKIND_REG; /* nested value spec */ + COPY_LONG (&Local[i], S_GET_VALUE (sp)); + i += 4; + VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG); + *pnt1 = ':'; + if (spnt->VMS_type == DBG_S_C_ADVANCED_TYPE) + generate_suffix (spnt, 0); +} + + +/* This function examines a structure definition, checking all of the elements + to make sure that all of them are fully defined. The only thing that we + kick out are arrays of undefined structs, since we do not know how big + they are. All others we can handle with a normal forward reference. */ + +static int +forward_reference (pnt) + char *pnt; +{ + struct VMS_DBG_Symbol *spnt, *spnt1; + int i; + + pnt = cvt_integer (pnt + 1, &i); + if (*pnt == ';') + return 0; /* no forward references */ + do + { + pnt = (char *) strchr (pnt, ':'); + pnt = cvt_integer (pnt + 1, &i); + spnt = find_symbol (i); + while (spnt && (spnt->advanced == POINTER || spnt->advanced == ARRAY)) + { + spnt1 = find_symbol (spnt->type2); + if (spnt->advanced == ARRAY && !spnt1) + return 1; + spnt = spnt1; + } + pnt = cvt_integer (pnt + 1, &i); + pnt = cvt_integer (pnt + 1, &i); + } while (*++pnt != ';'); + return 0; /* no forward refences found */ +} + + +/* Used to check a single element of a structure on the final pass. */ + +static int +final_forward_reference (spnt) + struct VMS_DBG_Symbol *spnt; +{ + struct VMS_DBG_Symbol *spnt1; + + while (spnt && (spnt->advanced == POINTER || spnt->advanced == ARRAY)) + { + spnt1 = find_symbol (spnt->type2); + if (spnt->advanced == ARRAY && !spnt1) + return 1; + spnt = spnt1; + } + return 0; /* no forward refences found */ +} + + +/* This routine parses the stabs directives to find any definitions of dbx + type numbers. It makes a note of all of them, creating a structure + element of VMS_DBG_Symbol that describes it. This also generates the + info for the debugger that describes the struct/union/enum, so that + further references to these data types will be by number + + We have to process pointers right away, since there can be references + to them later in the same stabs directive. We cannot have forward + references to pointers, (but we can have a forward reference to a + pointer to a structure/enum/union) and this is why we process them + immediately. After we process the pointer, then we search for defs + that are nested even deeper. + + 8/15/92: We have to process arrays right away too, because there can + be multiple references to identical array types in one structure + definition, and only the first one has the definition. */ + +static int +VMS_typedef_parse (str) + char *str; +{ + char *pnt; + char *pnt1; + const char *pnt2; + int i; + int dtype; + struct forward_ref *fpnt; + int i1, i2, i3, len; + struct VMS_DBG_Symbol *spnt; + struct VMS_DBG_Symbol *spnt1; + + /* check for any nested def's */ + pnt = (char *) strchr (str + 1, '='); + if (pnt && str[1] != '*' && (str[1] != 'a' || str[2] != 'r') + && VMS_typedef_parse (pnt) == 1) + return 1; + /* now find dbx_type of entry */ + pnt = str - 1; + if (*pnt == 'c') + { /* check for static constants */ + *str = '\0'; /* for now we ignore them */ + return 0; + } + while ((*pnt <= '9') && (*pnt >= '0')) + pnt--; + pnt++; /* and get back to the number */ + cvt_integer (pnt, &i1); + spnt = find_symbol (i1); + /* first see if this has been defined already, due to forward reference */ + if (!spnt) + { + i2 = SYMTYP_HASH (i1); + spnt = (struct VMS_DBG_Symbol *) xmalloc (sizeof (struct VMS_DBG_Symbol)); + spnt->next = VMS_Symbol_type_list[i2]; + VMS_Symbol_type_list[i2] = spnt; + spnt->dbx_type = i1; /* and save the type */ + spnt->type2 = spnt->VMS_type = spnt->data_size = 0; + spnt->index_min = spnt->index_max = spnt->struc_numb = 0; + } + /* + * For structs and unions, do a partial parse, otherwise we sometimes get + * circular definitions that are impossible to resolve. We read enough + * info so that any reference to this type has enough info to be resolved. + */ + pnt = str + 1; /* point to character past equal sign */ + if (*pnt >= '0' && *pnt <= '9') + { + if (type_check ("void")) + { /* this is the void symbol */ + *str = '\0'; + spnt->advanced = VOID; + return 0; + } + if (type_check ("unknown type")) + { + *str = '\0'; + spnt->advanced = UNKNOWN; + return 0; + } + pnt1 = cvt_integer (pnt, &i1); + if (i1 != spnt->dbx_type) + { + spnt->advanced = ALIAS; + spnt->type2 = i1; + strcpy (str, pnt1); + return 0; + } + as_tsktsk (_("debugginer output: %d is an unknown untyped variable."), + spnt->dbx_type); + return 1; /* do not know what this is */ + } + + pnt = str + 1; /* point to character past equal sign */ + switch (*pnt) + { + case 'r': + spnt->advanced = BASIC; + if (type_check ("int")) + { + spnt->VMS_type = DBG_S_C_SLINT; + spnt->data_size = 4; + } + else if (type_check ("long int")) + { + spnt->VMS_type = DBG_S_C_SLINT; + spnt->data_size = 4; + } + else if (type_check ("unsigned int")) + { + spnt->VMS_type = DBG_S_C_ULINT; + spnt->data_size = 4; + } + else if (type_check ("long unsigned int")) + { + spnt->VMS_type = DBG_S_C_ULINT; + spnt->data_size = 4; + } + else if (type_check ("short int")) + { + spnt->VMS_type = DBG_S_C_SSINT; + spnt->data_size = 2; + } + else if (type_check ("short unsigned int")) + { + spnt->VMS_type = DBG_S_C_USINT; + spnt->data_size = 2; + } + else if (type_check ("char")) + { + spnt->VMS_type = DBG_S_C_SCHAR; + spnt->data_size = 1; + } + else if (type_check ("signed char")) + { + spnt->VMS_type = DBG_S_C_SCHAR; + spnt->data_size = 1; + } + else if (type_check ("unsigned char")) + { + spnt->VMS_type = DBG_S_C_UCHAR; + spnt->data_size = 1; + } + else if (type_check ("float")) + { + spnt->VMS_type = DBG_S_C_REAL4; + spnt->data_size = 4; + } + else if (type_check ("double")) + { + spnt->VMS_type = vax_g_doubles ? DBG_S_C_REAL8_G : DBG_S_C_REAL8; + spnt->data_size = 8; + } + else if (type_check ("long double")) + { + /* same as double, at least for now */ + spnt->VMS_type = vax_g_doubles ? DBG_S_C_REAL8_G : DBG_S_C_REAL8; + spnt->data_size = 8; + } + else if (type_check ("long long int")) + { + spnt->VMS_type = DBG_S_C_SQUAD; /* signed quadword */ + spnt->data_size = 8; + } + else if (type_check ("long long unsigned int")) + { + spnt->VMS_type = DBG_S_C_UQUAD; /* unsigned quadword */ + spnt->data_size = 8; + } + else if (type_check ("complex float")) + { + spnt->VMS_type = DBG_S_C_COMPLX4; + spnt->data_size = 2 * 4; + } + else if (type_check ("complex double")) + { + spnt->VMS_type = vax_g_doubles ? DBG_S_C_COMPLX8_G : DBG_S_C_COMPLX8; + spnt->data_size = 2 * 8; + } + else if (type_check ("complex long double")) + { + /* same as complex double, at least for now */ + spnt->VMS_type = vax_g_doubles ? DBG_S_C_COMPLX8_G : DBG_S_C_COMPLX8; + spnt->data_size = 2 * 8; + } + else + { + /* [pr] + * Shouldn't get here, but if we do, something + * more substantial ought to be done... + */ + spnt->VMS_type = 0; + spnt->data_size = 0; + } + if (spnt->VMS_type != 0) + setup_basic_type (spnt); + pnt1 = (char *) strchr (str, ';') + 1; + break; + case 's': + case 'u': + spnt->advanced = (*pnt == 's') ? STRUCT : UNION; + spnt->VMS_type = DBG_S_C_ADVANCED_TYPE; + pnt1 = cvt_integer (pnt + 1, &spnt->data_size); + if (!final_pass && forward_reference (pnt)) + { + spnt->struc_numb = -1; + return 1; + } + spnt->struc_numb = ++structure_count; + pnt1--; + pnt = get_struct_name (str); + VMS_Def_Struct (spnt->struc_numb); + i = 0; + for (fpnt = f_ref_root; fpnt; fpnt = fpnt->next) + if (fpnt->dbx_type == spnt->dbx_type) + { + fpnt->resolved = 'Y'; + VMS_Set_Struct (fpnt->struc_numb); + VMS_Store_Struct (spnt->struc_numb); + i++; + } + if (i > 0) + VMS_Set_Struct (spnt->struc_numb); + i = 0; + Local[i++] = 11 + strlen (pnt); + Local[i++] = DBG_S_C_STRUCT_START; + Local[i++] = DST_K_VFLAGS_NOVAL; /* structure definition only */ + COPY_LONG (&Local[i], 0L); /* hence value is unused */ + i += 4; + Local[i++] = strlen (pnt); + pnt2 = pnt; + while (*pnt2 != '\0') + Local[i++] = *pnt2++; + i2 = spnt->data_size * 8; /* number of bits */ + COPY_LONG (&Local[i], i2); + i += 4; + VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG); + i = 0; + if (pnt != symbol_name) + { + pnt += strlen (pnt); + *pnt = ':'; + } /* replace colon for later */ + while (*++pnt1 != ';') + { + pnt = (char *) strchr (pnt1, ':'); + *pnt = '\0'; + pnt2 = pnt1; + pnt1 = cvt_integer (pnt + 1, &dtype); + pnt1 = cvt_integer (pnt1 + 1, &i2); + pnt1 = cvt_integer (pnt1 + 1, &i3); + spnt1 = find_symbol (dtype); + len = strlen (pnt2); + if (spnt1 && (spnt1->advanced == BASIC || spnt1->advanced == ENUM) + && ((i3 != spnt1->data_size * 8) || (i2 % 8 != 0))) + { /* bitfield */ + if (USE_BITSTRING_DESCRIPTOR (spnt1)) + { + /* This uses a type descriptor, which doesn't work if + the enclosing structure has been placed in a register. + Also, enum bitfields degenerate to simple integers. */ + int unsigned_type = (spnt1->VMS_type == DBG_S_C_ULINT + || spnt1->VMS_type == DBG_S_C_USINT + || spnt1->VMS_type == DBG_S_C_UCHAR + || spnt1->VMS_type == DBG_S_C_UQUAD + || spnt1->advanced == ENUM); /* (approximate) */ + Apoint = 0; + fpush (19 + len, 1); + fpush (unsigned_type ? DBG_S_C_UBITU : DBG_S_C_SBITU, 1); + fpush (DST_K_VFLAGS_DSC, 1); /* specified by descriptor */ + fpush (1 + len, 4); /* relative offset to descriptor */ + fpush (len, 1); /* length byte (ascic prefix) */ + while (*pnt2 != '\0') /* name bytes */ + fpush (*pnt2++, 1); + fpush (i3, 2); /* dsc length == size of bitfield */ + /* dsc type == un?signed bitfield */ + fpush (unsigned_type ? DBG_S_C_UBITU : DBG_S_C_SBITU, 1); + fpush (DSC_K_CLASS_UBS, 1); /* dsc class == unaligned bitstring */ + fpush (0x00, 4); /* dsc pointer == zeroes */ + fpush (i2, 4); /* start position */ + VMS_Store_Immediate_Data (Asuffix, Apoint, OBJ_S_C_DBG); + Apoint = 0; + } + else + { + /* Use a "novel length" type specification, which works + right for register structures and for enum bitfields + but results in larger object modules. */ + Local[i++] = 7 + len; + Local[i++] = DBG_S_C_ADVANCED_TYPE; /* type spec follows */ + Local[i++] = DBG_S_C_STRUCT_ITEM; /* value is a bit offset */ + COPY_LONG (&Local[i], i2); /* bit offset */ + i += 4; + Local[i++] = strlen (pnt2); + while (*pnt2 != '\0') + Local[i++] = *pnt2++; + VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG); + i = 0; + bitfield_suffix (spnt1, i3); + } + } + else + { /* not a bitfield */ + /* check if this is a forward reference */ + if (final_pass && final_forward_reference (spnt1)) + { + as_tsktsk (_("debugger output: structure element `%s' has undefined type"), + pnt2); + continue; + } + Local[i++] = 7 + len; + Local[i++] = spnt1 ? spnt1->VMS_type : DBG_S_C_ADVANCED_TYPE; + Local[i++] = DBG_S_C_STRUCT_ITEM; + COPY_LONG (&Local[i], i2); /* bit offset */ + i += 4; + Local[i++] = strlen (pnt2); + while (*pnt2 != '\0') + Local[i++] = *pnt2++; + VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG); + i = 0; + if (!spnt1) + generate_suffix (spnt1, dtype); + else if (spnt1->VMS_type == DBG_S_C_ADVANCED_TYPE) + generate_suffix (spnt1, 0); + } + } + pnt1++; + Local[i++] = 0x01; /* length byte */ + Local[i++] = DBG_S_C_STRUCT_END; + VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG); + i = 0; + break; + case 'e': + spnt->advanced = ENUM; + spnt->VMS_type = DBG_S_C_ADVANCED_TYPE; + spnt->struc_numb = ++structure_count; + spnt->data_size = 4; + VMS_Def_Struct (spnt->struc_numb); + i = 0; + for (fpnt = f_ref_root; fpnt; fpnt = fpnt->next) + if (fpnt->dbx_type == spnt->dbx_type) + { + fpnt->resolved = 'Y'; + VMS_Set_Struct (fpnt->struc_numb); + VMS_Store_Struct (spnt->struc_numb); + i++; + } + if (i > 0) + VMS_Set_Struct (spnt->struc_numb); + i = 0; + len = strlen (symbol_name); + Local[i++] = 3 + len; + Local[i++] = DBG_S_C_ENUM_START; + Local[i++] = 4 * 8; /* enum values are 32 bits */ + Local[i++] = len; + pnt2 = symbol_name; + while (*pnt2 != '\0') + Local[i++] = *pnt2++; + VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG); + i = 0; + while (*++pnt != ';') + { + pnt1 = (char *) strchr (pnt, ':'); + *pnt1++ = '\0'; + pnt1 = cvt_integer (pnt1, &i1); + len = strlen (pnt); + Local[i++] = 7 + len; + Local[i++] = DBG_S_C_ENUM_ITEM; + Local[i++] = DST_K_VALKIND_LITERAL; + COPY_LONG (&Local[i], i1); + i += 4; + Local[i++] = len; + pnt2 = pnt; + while (*pnt != '\0') + Local[i++] = *pnt++; + VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG); + i = 0; + pnt = pnt1; /* Skip final semicolon */ + } + Local[i++] = 0x01; /* len byte */ + Local[i++] = DBG_S_C_ENUM_END; + VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG); + i = 0; + pnt1 = pnt + 1; + break; + case 'a': + spnt->advanced = ARRAY; + spnt->VMS_type = DBG_S_C_ADVANCED_TYPE; + pnt = (char *) strchr (pnt, ';'); + if (!pnt) + return 1; + pnt1 = cvt_integer (pnt + 1, &spnt->index_min); + pnt1 = cvt_integer (pnt1 + 1, &spnt->index_max); + pnt1 = cvt_integer (pnt1 + 1, &spnt->type2); + pnt = (char *) strchr (str + 1, '='); + if (pnt && VMS_typedef_parse (pnt) == 1) + return 1; + break; + case 'f': + spnt->advanced = FUNCTION; + spnt->VMS_type = DBG_S_C_FUNCTION_ADDR; + /* this masquerades as a basic type*/ + spnt->data_size = 4; + pnt1 = cvt_integer (pnt + 1, &spnt->type2); + break; + case '*': + spnt->advanced = POINTER; + spnt->VMS_type = DBG_S_C_ADVANCED_TYPE; + spnt->data_size = 4; + pnt1 = cvt_integer (pnt + 1, &spnt->type2); + pnt = (char *) strchr (str + 1, '='); + if (pnt && VMS_typedef_parse (pnt) == 1) + return 1; + break; + default: + spnt->advanced = UNKNOWN; + spnt->VMS_type = 0; + as_tsktsk (_("debugger output: %d is an unknown type of variable."), + spnt->dbx_type); + return 1; /* unable to decipher */ + } + /* This removes the evidence of the definition so that the outer levels + of parsing do not have to worry about it. */ + pnt = str; + while (*pnt1 != '\0') + *pnt++ = *pnt1++; + *pnt = '\0'; + return 0; +} + + +/* This is the root routine that parses the stabs entries for definitions. + it calls VMS_typedef_parse, which can in turn call itself. We need to + be careful, since sometimes there are forward references to other symbol + types, and these cannot be resolved until we have completed the parse. + + Also check and see if we are using continuation stabs, if we are, then + paste together the entire contents of the stab before we pass it to + VMS_typedef_parse. */ + +static void +VMS_LSYM_Parse () +{ + char *pnt; + char *pnt1; + char *pnt2; + char *str; + char *parse_buffer = 0; + char fixit[10]; + int incomplete, pass, incom1; + struct forward_ref *fpnt; + symbolS *sp; + + pass = 0; + final_pass = 0; + incomplete = 0; + do + { + incom1 = incomplete; + incomplete = 0; + for (sp = symbol_rootP; sp; sp = symbol_next (sp)) + { + /* + * Deal with STAB symbols + */ + if (S_IS_DEBUG (sp)) + { + /* + * Dispatch on STAB type + */ + switch (S_GET_RAW_TYPE (sp)) + { + case N_GSYM: + case N_LCSYM: + case N_STSYM: + case N_PSYM: + case N_RSYM: + case N_LSYM: + case N_FUN: /*sometimes these contain typedefs*/ + str = S_GET_NAME (sp); + symbol_name = str; + pnt = str + strlen (str) - 1; + if (*pnt == '?') /* Continuation stab. */ + { + symbolS *spnext; + int tlen = 0; + + spnext = sp; + do { + tlen += strlen (str) - 1; + spnext = symbol_next (spnext); + str = S_GET_NAME (spnext); + pnt = str + strlen (str) - 1; + } while (*pnt == '?'); + tlen += strlen (str); + parse_buffer = (char *) xmalloc (tlen + 1); + strcpy (parse_buffer, S_GET_NAME (sp)); + pnt2 = parse_buffer + strlen (parse_buffer) - 1; + *pnt2 = '\0'; + spnext = sp; + do { + spnext = symbol_next (spnext); + str = S_GET_NAME (spnext); + strcat (pnt2, str); + pnt2 += strlen (str) - 1; + *str = '\0'; /* Erase this string */ + /* S_SET_NAME (spnext, str); */ + if (*pnt2 != '?') break; + *pnt2 = '\0'; + } while (1); + str = parse_buffer; + symbol_name = str; + } + if ((pnt = (char *) strchr (str, ':')) != 0) + { + *pnt = '\0'; + pnt1 = pnt + 1; + if ((pnt2 = (char *) strchr (pnt1, '=')) != 0) + incomplete += VMS_typedef_parse (pnt2); + if (parse_buffer) + { + /* At this point the parse buffer should just + contain name:nn. If it does not, then we + are in real trouble. Anyway, this is always + shorter than the original line. */ + pnt2 = S_GET_NAME (sp); + strcpy (pnt2, parse_buffer); + /* S_SET_NAME (sp, pnt2); */ + free (parse_buffer), parse_buffer = 0; + } + *pnt = ':'; /* put back colon to restore dbx_type */ + } + break; + } /*switch*/ + } /* if */ + } /*for*/ + pass++; + /* + * Make one last pass, if needed, and define whatever we can + * that is left. + */ + if (final_pass == 0 && incomplete == incom1) + { + final_pass = 1; + incom1++; /* Force one last pass through */ + } + } while (incomplete != 0 && incomplete != incom1); + /* repeat until all refs resolved if possible */ +/* if (pass > 1) printf (" Required %d passes\n", pass); */ + if (incomplete != 0) + { + as_tsktsk (_("debugger output: Unable to resolve %d circular references."), + incomplete); + } + fpnt = f_ref_root; + symbol_name = "\0"; + while (fpnt) + { + if (fpnt->resolved != 'Y') + { + if (find_symbol (fpnt->dbx_type)) + { + as_tsktsk (_("debugger forward reference error, dbx type %d"), + fpnt->dbx_type); + break; + } + fixit[0] = 0; + sprintf (&fixit[1], "%d=s4;", fpnt->dbx_type); + pnt2 = (char *) strchr (&fixit[1], '='); + VMS_typedef_parse (pnt2); + } + fpnt = fpnt->next; + } +} + + +static void +Define_Local_Symbols (s0P, s2P, Current_Routine, Text_Psect) + symbolS *s0P, *s2P; + symbolS *Current_Routine; + int Text_Psect; +{ + symbolS *s1P; /* each symbol from s0P .. s2P (exclusive) */ + + for (s1P = symbol_next (s0P); s1P != s2P; s1P = symbol_next (s1P)) + { + if (!s1P) + break; /* and return */ + if (S_GET_RAW_TYPE (s1P) == N_FUN) + { + char *pnt = (char *) strchr (S_GET_NAME (s1P), ':') + 1; + if (*pnt == 'F' || *pnt == 'f') break; + } + if (!S_IS_DEBUG (s1P)) + continue; + /* + * Dispatch on STAB type + */ + switch (S_GET_RAW_TYPE (s1P)) + { + default: + continue; /* not left or right brace */ + + case N_LSYM: + case N_PSYM: + VMS_local_stab_Parse (s1P); + break; + + case N_RSYM: + VMS_RSYM_Parse (s1P, Current_Routine, Text_Psect); + break; + } /*switch*/ + } /* for */ +} + + +/* This function crawls the symbol chain searching for local symbols that + need to be described to the debugger. When we enter a new scope with + a "{", it creates a new "block", which helps the debugger keep track + of which scope we are currently in. */ + +static symbolS * +Define_Routine (s0P, Level, Current_Routine, Text_Psect) + symbolS *s0P; + int Level; + symbolS *Current_Routine; + int Text_Psect; +{ + symbolS *s1P; + valueT Offset; + int rcount = 0; + + for (s1P = symbol_next (s0P); s1P != 0; s1P = symbol_next (s1P)) + { + if (S_GET_RAW_TYPE (s1P) == N_FUN) + { + char *pnt = (char *) strchr (S_GET_NAME (s1P), ':') + 1; + if (*pnt == 'F' || *pnt == 'f') break; + } + if (!S_IS_DEBUG (s1P)) + continue; + /* + * Dispatch on STAB type + */ + switch (S_GET_RAW_TYPE (s1P)) + { + default: + continue; /* not left or right brace */ + + case N_LBRAC: + if (Level != 0) + { + char str[10]; + sprintf (str, "$%d", rcount++); + VMS_TBT_Block_Begin (s1P, Text_Psect, str); + } + Offset = S_GET_VALUE (s1P); /* side-effect: fully resolve symbol */ + Define_Local_Symbols (s0P, s1P, Current_Routine, Text_Psect); + s1P = Define_Routine (s1P, Level + 1, Current_Routine, Text_Psect); + if (Level != 0) + VMS_TBT_Block_End (S_GET_VALUE (s1P) - Offset); + s0P = s1P; + break; + + case N_RBRAC: + return s1P; + } /*switch*/ + } /* for */ + + /* We end up here if there were no brackets in this function. + Define everything. */ + Define_Local_Symbols (s0P, (symbolS *)0, Current_Routine, Text_Psect); + return s1P; +} + + +#ifndef VMS +#include +#include +static void get_VMS_time_on_unix PARAMS ((char *)); + +/* Manufacture a VMS-like time string on a Unix based system. */ +static void +get_VMS_time_on_unix (Now) + char *Now; +{ + char *pnt; + time_t timeb; + + time (&timeb); + pnt = ctime (&timeb); + pnt[3] = 0; + pnt[7] = 0; + pnt[10] = 0; + pnt[16] = 0; + pnt[24] = 0; + sprintf (Now, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11); +} +#endif /* not VMS */ + + +/* Write the MHD (Module Header) records. */ + +static void +Write_VMS_MHD_Records () +{ + register const char *cp; + register char *cp1; + register int i; +#ifdef VMS + struct { unsigned short len, mbz; char *ptr; } Descriptor; +#endif + char Now[17+1]; + + /* We are writing a module header record. */ + Set_VMS_Object_File_Record (OBJ_S_C_HDR); + /* + * *************************** + * *MAIN MODULE HEADER RECORD* + * *************************** + */ + /* Store record type and header type. */ + PUT_CHAR (OBJ_S_C_HDR); + PUT_CHAR (MHD_S_C_MHD); + /* Structure level is 0. */ + PUT_CHAR (OBJ_S_C_STRLVL); + /* Maximum record size is size of the object record buffer. */ + PUT_SHORT (sizeof (Object_Record_Buffer)); + + /* + * FIXME: module name and version should be user + * specifiable via `.ident' and/or `#pragma ident'. + */ + + /* Get module name (the FILENAME part of the object file). */ + cp = out_file_name; + cp1 = Module_Name; + while (*cp) + { + if (*cp == ']' || *cp == '>' || *cp == ':' || *cp == '/') + { + cp1 = Module_Name; + cp++; + continue; + } + *cp1++ = islower (*cp) ? toupper (*cp++) : *cp++; + } + *cp1 = '\0'; + + /* Limit it to 31 characters and store in the object record. */ + while (--cp1 >= Module_Name) + if (*cp1 == '.') + *cp1 = '\0'; + if (strlen (Module_Name) > 31) + { + if (flag_hash_long_names) + as_tsktsk (_("Module name truncated: %s\n"), Module_Name); + Module_Name[31] = '\0'; + } + PUT_COUNTED_STRING (Module_Name); + /* Module Version is "V1.0". */ + PUT_COUNTED_STRING ("V1.0"); + /* Creation time is "now" (17 chars of time string): "dd-MMM-yyyy hh:mm". */ +#ifndef VMS + get_VMS_time_on_unix (Now); +#else /* VMS */ + Descriptor.len = sizeof Now - 1; + Descriptor.mbz = 0; /* type & class unspecified */ + Descriptor.ptr = Now; + (void) sys$asctim ((unsigned short *)0, &Descriptor, (long *)0, 0); +#endif /* VMS */ + for (i = 0; i < 17; i++) + PUT_CHAR (Now[i]); + /* Patch time is "never" (17 zeros). */ + for (i = 0; i < 17; i++) + PUT_CHAR (0); + /* Force this to be a separate output record. */ + Flush_VMS_Object_Record_Buffer (); + + /* + * ************************* + * *LANGUAGE PROCESSOR NAME* + * ************************* + */ + /* Store record type and header type. */ + PUT_CHAR (OBJ_S_C_HDR); + PUT_CHAR (MHD_S_C_LNM); + /* + * Store language processor name and version (not a counted string!). + * + * This is normally supplied by the gcc driver for the command line + * which invokes gas. If absent, we fall back to gas's version. + */ + cp = compiler_version_string; + if (cp == 0) + { + cp = "GNU AS V"; + while (*cp) + PUT_CHAR (*cp++); + cp = VERSION; + } + while (*cp >= ' ') + PUT_CHAR (*cp++); + /* Force this to be a separate output record. */ + Flush_VMS_Object_Record_Buffer (); +} + + +/* Write the EOM (End Of Module) record. */ + +static void +Write_VMS_EOM_Record (Psect, Offset) + int Psect; + valueT Offset; +{ + /* + * We are writing an end-of-module record + * (this assumes that the entry point will always be in a psect + * represented by a single byte, which is the case for code in + * Text_Psect==0) + */ + Set_VMS_Object_File_Record (OBJ_S_C_EOM); + PUT_CHAR (OBJ_S_C_EOM); /* Record type. */ + PUT_CHAR (0); /* Error severity level (we ignore it). */ + /* + * Store the entry point, if it exists + */ + if (Psect >= 0) + { + PUT_CHAR (Psect); + PUT_LONG (Offset); + } + /* Flush the record; this will be our final output. */ + Flush_VMS_Object_Record_Buffer (); +} + + +/* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/ + +static int +hash_string (ptr) + const char *ptr; +{ + register const unsigned char *p = (unsigned char *) ptr; + register const unsigned char *end = p + strlen (ptr); + register unsigned char c; + register int hash = 0; + + while (p != end) + { + c = *p++; + hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c); + } + return hash; +} + +/* + * Generate a Case-Hacked VMS symbol name (limited to 31 chars) + */ +static void +VMS_Case_Hack_Symbol (In, Out) + register const char *In; + register char *Out; +{ + long int init; + long int result; + char *pnt = 0; + char *new_name; + const char *old_name; + register int i; + int destructor = 0; /*hack to allow for case sens in a destructor*/ + int truncate = 0; + int Case_Hack_Bits = 0; + int Saw_Dollar = 0; + static char Hex_Table[16] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + + /* + * Kill any leading "_" + */ + if ((In[0] == '_') && ((In[1] > '9') || (In[1] < '0'))) + In++; + + new_name = Out; /* save this for later*/ + +#if barfoo /* Dead code */ + if ((In[0] == '_') && (In[1] == '$') && (In[2] == '_')) + destructor = 1; +#endif + + /* We may need to truncate the symbol, save the hash for later*/ + result = (strlen (In) > 23) ? hash_string (In) : 0; + /* + * Is there a Psect Attribute to skip?? + */ + if (HAS_PSECT_ATTRIBUTES (In)) + { + /* + * Yes: Skip it + */ + In += PSECT_ATTRIBUTES_STRING_LENGTH; + while (*In) + { + if ((In[0] == '$') && (In[1] == '$')) + { + In += 2; + break; + } + In++; + } + } + + old_name = In; +/* if (strlen (In) > 31 && flag_hash_long_names) + as_tsktsk ("Symbol name truncated: %s\n", In); */ + /* + * Do the case conversion + */ + i = 23; /* Maximum of 23 chars */ + while (*In && (--i >= 0)) + { + Case_Hack_Bits <<= 1; + if (*In == '$') + Saw_Dollar = 1; + if ((destructor == 1) && (i == 21)) + Saw_Dollar = 0; + switch (vms_name_mapping) + { + case 0: + if (isupper (*In)) { + *Out++ = *In++; + Case_Hack_Bits |= 1; + } else { + *Out++ = islower (*In) ? toupper (*In++) : *In++; + } + break; + case 3: *Out++ = *In++; + break; + case 2: + if (islower (*In)) { + *Out++ = *In++; + } else { + *Out++ = isupper (*In) ? tolower (*In++) : *In++; + } + break; + } + } + /* + * If we saw a dollar sign, we don't do case hacking + */ + if (flag_no_hash_mixed_case || Saw_Dollar) + Case_Hack_Bits = 0; + + /* + * If we have more than 23 characters and everything is lowercase + * we can insert the full 31 characters + */ + if (*In) + { + /* + * We have more than 23 characters + * If we must add the case hack, then we have truncated the str + */ + pnt = Out; + truncate = 1; + if (Case_Hack_Bits == 0) + { + /* + * And so far they are all lower case: + * Check up to 8 more characters + * and ensure that they are lowercase + */ + for (i = 0; (In[i] != 0) && (i < 8); i++) + if (isupper (In[i]) && !Saw_Dollar && !flag_no_hash_mixed_case) + break; + + if (In[i] == 0) + truncate = 0; + + if ((i == 8) || (In[i] == 0)) + { + /* + * They are: Copy up to 31 characters + * to the output string + */ + i = 8; + while ((--i >= 0) && (*In)) + switch (vms_name_mapping){ + case 0: *Out++ = islower (*In) ? toupper (*In++) : *In++; + break; + case 3: *Out++ = *In++; + break; + case 2: *Out++ = isupper (*In) ? tolower (*In++) : *In++; + break; + } + } + } + } + /* + * If there were any uppercase characters in the name we + * take on the case hacking string + */ + + /* Old behavior for regular GNU-C compiler */ + if (!flag_hash_long_names) + truncate = 0; + if ((Case_Hack_Bits != 0) || (truncate == 1)) + { + if (truncate == 0) + { + *Out++ = '_'; + for (i = 0; i < 6; i++) + { + *Out++ = Hex_Table[Case_Hack_Bits & 0xf]; + Case_Hack_Bits >>= 4; + } + *Out++ = 'X'; + } + else + { + Out = pnt; /*Cut back to 23 characters maximum */ + *Out++ = '_'; + for (i = 0; i < 7; i++) + { + init = result & 0x01f; + *Out++ = (init < 10) ? ('0' + init) : ('A' + init - 10); + result = result >> 5; + } + } + } /*Case Hack */ + /* + * Done + */ + *Out = 0; + if (truncate == 1 && flag_hash_long_names && flag_show_after_trunc) + as_tsktsk (_("Symbol %s replaced by %s\n"), old_name, new_name); +} + + +/* + * Scan a symbol name for a psect attribute specification + */ +#define GLOBALSYMBOL_BIT 0x10000 +#define GLOBALVALUE_BIT 0x20000 + + +static void +VMS_Modify_Psect_Attributes (Name, Attribute_Pointer) + const char *Name; + int *Attribute_Pointer; +{ + register int i; + register const char *cp; + int Negate; + static const struct + { + const char *Name; + int Value; + } Attributes[] = + { + {"PIC", GPS_S_M_PIC}, + {"LIB", GPS_S_M_LIB}, + {"OVR", GPS_S_M_OVR}, + {"REL", GPS_S_M_REL}, + {"GBL", GPS_S_M_GBL}, + {"SHR", GPS_S_M_SHR}, + {"EXE", GPS_S_M_EXE}, + {"RD", GPS_S_M_RD}, + {"WRT", GPS_S_M_WRT}, + {"VEC", GPS_S_M_VEC}, + {"GLOBALSYMBOL", GLOBALSYMBOL_BIT}, + {"GLOBALVALUE", GLOBALVALUE_BIT}, + {0, 0} + }; + + /* + * Kill leading "_" + */ + if (*Name == '_') + Name++; + /* + * Check for a PSECT attribute list + */ + if (!HAS_PSECT_ATTRIBUTES (Name)) + return; /* If not, return */ + /* + * Skip the attribute list indicator + */ + Name += PSECT_ATTRIBUTES_STRING_LENGTH; + /* + * Process the attributes ("_" separated, "$" terminated) + */ + while (*Name != '$') + { + /* + * Assume not negating + */ + Negate = 0; + /* + * Check for "NO" + */ + if ((Name[0] == 'N') && (Name[1] == 'O')) + { + /* + * We are negating (and skip the NO) + */ + Negate = 1; + Name += 2; + } + /* + * Find the token delimiter + */ + cp = Name; + while (*cp && (*cp != '_') && (*cp != '$')) + cp++; + /* + * Look for the token in the attribute list + */ + for (i = 0; Attributes[i].Name; i++) + { + /* + * If the strings match, set/clear the attr. + */ + if (strncmp (Name, Attributes[i].Name, cp - Name) == 0) + { + /* + * Set or clear + */ + if (Negate) + *Attribute_Pointer &= + ~Attributes[i].Value; + else + *Attribute_Pointer |= + Attributes[i].Value; + /* + * Done + */ + break; + } + } + /* + * Now skip the attribute + */ + Name = cp; + if (*Name == '_') + Name++; + } +} + + +#define GBLSYM_REF 0 +#define GBLSYM_DEF 1 +#define GBLSYM_VAL 2 +#define GBLSYM_LCL 4 /* not GBL after all... */ +#define GBLSYM_WEAK 8 + +/* + * Define a global symbol (or possibly a local one). + */ +static void +VMS_Global_Symbol_Spec (Name, Psect_Number, Psect_Offset, Flags) + const char *Name; + int Psect_Number; + int Psect_Offset; + int Flags; +{ + char Local[32]; + + /* + * We are writing a GSD record + */ + Set_VMS_Object_File_Record (OBJ_S_C_GSD); + /* + * If the buffer is empty we must insert the GSD record type + */ + if (Object_Record_Offset == 0) + PUT_CHAR (OBJ_S_C_GSD); + /* + * We are writing a Global (or local) symbol definition subrecord. + */ + PUT_CHAR ((Flags & GBLSYM_LCL) != 0 ? GSD_S_C_LSY : + ((unsigned) Psect_Number <= 255) ? GSD_S_C_SYM : GSD_S_C_SYMW); + /* + * Data type is undefined + */ + PUT_CHAR (0); + /* + * Switch on Definition/Reference + */ + if ((Flags & GBLSYM_DEF) == 0) + { + /* + * Reference + */ + PUT_SHORT (((Flags & GBLSYM_VAL) == 0) ? GSY_S_M_REL : 0); + if ((Flags & GBLSYM_LCL) != 0) /* local symbols have extra field */ + PUT_SHORT (Current_Environment); + } + else + { + int sym_flags; + + /* + * Definition + *[ assert (LSY_S_M_DEF == GSY_S_M_DEF && LSY_S_M_REL == GSY_S_M_REL); ] + */ + sym_flags = GSY_S_M_DEF; + if (Flags & GBLSYM_WEAK) + sym_flags |= GSY_S_M_WEAK; + if ((Flags & GBLSYM_VAL) == 0) + sym_flags |= GSY_S_M_REL; + PUT_SHORT (sym_flags); + if ((Flags & GBLSYM_LCL) != 0) /* local symbols have extra field */ + PUT_SHORT (Current_Environment); + /* + * Psect Number + */ + if ((Flags & GBLSYM_LCL) == 0 && (unsigned) Psect_Number <= 255) + PUT_CHAR (Psect_Number); + else + PUT_SHORT (Psect_Number); + /* + * Offset + */ + PUT_LONG (Psect_Offset); + } + /* + * Finally, the global symbol name + */ + VMS_Case_Hack_Symbol (Name, Local); + PUT_COUNTED_STRING (Local); + /* + * Flush the buffer if it is more than 75% full + */ + if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4)) + Flush_VMS_Object_Record_Buffer (); +} + +/* + * Define an environment to support local symbol references. + * This is just to mollify the linker; we don't actually do + * anything useful with it. + */ +static void +VMS_Local_Environment_Setup (Env_Name) + const char *Env_Name; +{ + /* We are writing a GSD record. */ + Set_VMS_Object_File_Record (OBJ_S_C_GSD); + /* If the buffer is empty we must insert the GSD record type. */ + if (Object_Record_Offset == 0) + PUT_CHAR (OBJ_S_C_GSD); + /* We are writing an ENV subrecord. */ + PUT_CHAR (GSD_S_C_ENV); + + ++Current_Environment; /* index of environment being defined */ + + /* ENV$W_FLAGS: we are defining the next environment. It's not nested. */ + PUT_SHORT (ENV_S_M_DEF); + /* ENV$W_ENVINDX: index is always 0 for non-nested definitions. */ + PUT_SHORT (0); + + /* ENV$B_NAMLNG + ENV$T_NAME: environment name in ASCIC format. */ + if (!Env_Name) Env_Name = ""; + PUT_COUNTED_STRING ((char *)Env_Name); + + /* Flush the buffer if it is more than 75% full. */ + if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4)) + Flush_VMS_Object_Record_Buffer (); +} + + +/* + * Define a psect + */ +static int +VMS_Psect_Spec (Name, Size, Type, vsp) + const char *Name; + int Size; + enum ps_type Type; + struct VMS_Symbol *vsp; +{ + char Local[32]; + int Psect_Attributes; + + /* + * Generate the appropriate PSECT flags given the PSECT type + */ + switch (Type) + { + case ps_TEXT: + /* Text psects are PIC,noOVR,REL,noGBL,SHR,EXE,RD,noWRT. */ + Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE + |GPS_S_M_RD); + break; + case ps_DATA: + /* Data psects are PIC,noOVR,REL,noGBL,noSHR,noEXE,RD,WRT. */ + Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT); + break; + case ps_COMMON: + /* Common block psects are: PIC,OVR,REL,GBL,noSHR,noEXE,RD,WRT. */ + Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL + |GPS_S_M_RD|GPS_S_M_WRT); + break; + case ps_CONST: + /* Const data psects are: PIC,OVR,REL,GBL,noSHR,noEXE,RD,noWRT. */ + Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL + |GPS_S_M_RD); + break; + case ps_CTORS: + /* Ctor psects are PIC,noOVR,REL,GBL,noSHR,noEXE,RD,noWRT. */ + Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD); + break; + case ps_DTORS: + /* Dtor psects are PIC,noOVR,REL,GBL,noSHR,noEXE,RD,noWRT. */ + Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD); + break; + default: + /* impossible */ + error (_("Unknown VMS psect type (%ld)"), (long) Type); + break; + } + /* + * Modify the psect attributes according to any attribute string + */ + if (vsp && S_GET_TYPE (vsp->Symbol) == N_ABS) + Psect_Attributes |= GLOBALVALUE_BIT; + else if (HAS_PSECT_ATTRIBUTES (Name)) + VMS_Modify_Psect_Attributes (Name, &Psect_Attributes); + /* + * Check for globalref/def/val. + */ + if ((Psect_Attributes & GLOBALVALUE_BIT) != 0) + { + /* + * globalvalue symbols were generated before. This code + * prevents unsightly psect buildup, and makes sure that + * fixup references are emitted correctly. + */ + vsp->Psect_Index = -1; /* to catch errors */ + S_SET_TYPE (vsp->Symbol, N_UNDF); /* make refs work */ + return 1; /* decrement psect counter */ + } + + if ((Psect_Attributes & GLOBALSYMBOL_BIT) != 0) + { + switch (S_GET_RAW_TYPE (vsp->Symbol)) + { + case N_UNDF | N_EXT: + VMS_Global_Symbol_Spec (Name, vsp->Psect_Index, + vsp->Psect_Offset, GBLSYM_REF); + vsp->Psect_Index = -1; + S_SET_TYPE (vsp->Symbol, N_UNDF); + return 1; /* return and indicate no psect */ + case N_DATA | N_EXT: + VMS_Global_Symbol_Spec (Name, vsp->Psect_Index, + vsp->Psect_Offset, GBLSYM_DEF); + /* In this case we still generate the psect */ + break; + default: + as_fatal (_("Globalsymbol attribute for symbol %s was unexpected."), + Name); + break; + } /* switch */ + } + + Psect_Attributes &= 0xffff; /* clear out the globalref/def stuff */ + /* + * We are writing a GSD record + */ + Set_VMS_Object_File_Record (OBJ_S_C_GSD); + /* + * If the buffer is empty we must insert the GSD record type + */ + if (Object_Record_Offset == 0) + PUT_CHAR (OBJ_S_C_GSD); + /* + * We are writing a PSECT definition subrecord + */ + PUT_CHAR (GSD_S_C_PSC); + /* + * Psects are always LONGWORD aligned + */ + PUT_CHAR (2); + /* + * Specify the psect attributes + */ + PUT_SHORT (Psect_Attributes); + /* + * Specify the allocation + */ + PUT_LONG (Size); + /* + * Finally, the psect name + */ + VMS_Case_Hack_Symbol (Name, Local); + PUT_COUNTED_STRING (Local); + /* + * Flush the buffer if it is more than 75% full + */ + if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4)) + Flush_VMS_Object_Record_Buffer (); + return 0; +} + + +/* Given the pointer to a symbol we calculate how big the data at the + symbol is. We do this by looking for the next symbol (local or global) + which will indicate the start of another datum. */ + +static offsetT +VMS_Initialized_Data_Size (s0P, End_Of_Data) + register symbolS *s0P; + unsigned End_Of_Data; +{ + symbolS *s1P; + valueT s0P_val = S_GET_VALUE (s0P), s1P_val, + nearest_val = (valueT) End_Of_Data; + + /* Find the nearest symbol what follows this one. */ + for (s1P = symbol_rootP; s1P; s1P = symbol_next (s1P)) + { + /* The data type must match. */ + if (S_GET_TYPE (s1P) != N_DATA) + continue; + s1P_val = S_GET_VALUE (s1P); + if (s1P_val > s0P_val && s1P_val < nearest_val) + nearest_val = s1P_val; + } + /* Calculate its size. */ + return (offsetT) (nearest_val - s0P_val); +} + + +/* Check symbol names for the Psect hack with a globalvalue, and then + generate globalvalues for those that have it. */ + +static void +VMS_Emit_Globalvalues (text_siz, data_siz, Data_Segment) + unsigned text_siz; + unsigned data_siz; + char *Data_Segment; +{ + register symbolS *sp; + char *stripped_name, *Name; + int Size; + int Psect_Attributes; + int globalvalue; + int typ, abstyp; + + /* + * Scan the symbol table for globalvalues, and emit def/ref when + * required. These will be caught again later and converted to + * N_UNDF + */ + for (sp = symbol_rootP; sp; sp = sp->sy_next) + { + typ = S_GET_RAW_TYPE (sp); + abstyp = ((typ & ~N_EXT) == N_ABS); + /* + * See if this is something we want to look at. + */ + if (!abstyp && + typ != (N_DATA | N_EXT) && + typ != (N_UNDF | N_EXT)) + continue; + /* + * See if this has globalvalue specification. + */ + Name = S_GET_NAME (sp); + + if (abstyp) + { + stripped_name = 0; + Psect_Attributes = GLOBALVALUE_BIT; + } + else if (HAS_PSECT_ATTRIBUTES (Name)) + { + stripped_name = (char *) xmalloc (strlen (Name) + 1); + strcpy (stripped_name, Name); + Psect_Attributes = 0; + VMS_Modify_Psect_Attributes (stripped_name, &Psect_Attributes); + } + else + continue; + + if ((Psect_Attributes & GLOBALVALUE_BIT) != 0) + { + switch (typ) + { + case N_ABS: + /* Local symbol references will want + to have an environment defined. */ + if (Current_Environment < 0) + VMS_Local_Environment_Setup (".N_ABS"); + VMS_Global_Symbol_Spec (Name, 0, + S_GET_VALUE (sp), + GBLSYM_DEF|GBLSYM_VAL|GBLSYM_LCL); + break; + case N_ABS | N_EXT: + VMS_Global_Symbol_Spec (Name, 0, + S_GET_VALUE (sp), + GBLSYM_DEF|GBLSYM_VAL); + break; + case N_UNDF | N_EXT: + VMS_Global_Symbol_Spec (stripped_name, 0, 0, GBLSYM_VAL); + break; + case N_DATA | N_EXT: + Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz); + if (Size > 4) + error (_("Invalid data type for globalvalue")); + globalvalue = md_chars_to_number (Data_Segment + + S_GET_VALUE (sp) - text_siz , Size); + /* Three times for good luck. The linker seems to get confused + if there are fewer than three */ + VMS_Global_Symbol_Spec (stripped_name, 0, 0, GBLSYM_VAL); + VMS_Global_Symbol_Spec (stripped_name, 0, globalvalue, + GBLSYM_DEF|GBLSYM_VAL); + VMS_Global_Symbol_Spec (stripped_name, 0, globalvalue, + GBLSYM_DEF|GBLSYM_VAL); + break; + default: + as_warn (_("Invalid globalvalue of %s"), stripped_name); + break; + } /* switch */ + } /* if */ + if (stripped_name) free (stripped_name); /* clean up */ + } /* for */ + +} + + +/* + * Define a procedure entry pt/mask + */ +static void +VMS_Procedure_Entry_Pt (Name, Psect_Number, Psect_Offset, Entry_Mask) + char *Name; + int Psect_Number; + int Psect_Offset; + int Entry_Mask; +{ + char Local[32]; + + /* + * We are writing a GSD record + */ + Set_VMS_Object_File_Record (OBJ_S_C_GSD); + /* + * If the buffer is empty we must insert the GSD record type + */ + if (Object_Record_Offset == 0) + PUT_CHAR (OBJ_S_C_GSD); + /* + * We are writing a Procedure Entry Pt/Mask subrecord + */ + PUT_CHAR (((unsigned) Psect_Number <= 255) ? GSD_S_C_EPM : GSD_S_C_EPMW); + /* + * Data type is undefined + */ + PUT_CHAR (0); + /* + * Flags = "RELOCATABLE" and "DEFINED" + */ + PUT_SHORT (GSY_S_M_DEF | GSY_S_M_REL); + /* + * Psect Number + */ + if ((unsigned) Psect_Number <= 255) + PUT_CHAR (Psect_Number); + else + PUT_SHORT (Psect_Number); + /* + * Offset + */ + PUT_LONG (Psect_Offset); + /* + * Entry mask + */ + PUT_SHORT (Entry_Mask); + /* + * Finally, the global symbol name + */ + VMS_Case_Hack_Symbol (Name, Local); + PUT_COUNTED_STRING (Local); + /* + * Flush the buffer if it is more than 75% full + */ + if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4)) + Flush_VMS_Object_Record_Buffer (); +} + + +/* + * Set the current location counter to a particular Psect and Offset + */ +static void +VMS_Set_Psect (Psect_Index, Offset, Record_Type) + int Psect_Index; + int Offset; + int Record_Type; +{ + /* + * We are writing a "Record_Type" record + */ + Set_VMS_Object_File_Record (Record_Type); + /* + * If the buffer is empty we must insert the record type + */ + if (Object_Record_Offset == 0) + PUT_CHAR (Record_Type); + /* + * Stack the Psect base + Offset + */ + vms_tir_stack_psect (Psect_Index, Offset, 0); + /* + * Set relocation base + */ + PUT_CHAR (TIR_S_C_CTL_SETRB); + /* + * Flush the buffer if it is more than 75% full + */ + if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4)) + Flush_VMS_Object_Record_Buffer (); +} + + +/* + * Store repeated immediate data in current Psect + */ +static void +VMS_Store_Repeated_Data (Repeat_Count, Pointer, Size, Record_Type) + int Repeat_Count; + register char *Pointer; + int Size; + int Record_Type; +{ + + /* + * Ignore zero bytes/words/longwords + */ + switch (Size) + { + case 4: + if (Pointer[3] != 0 || Pointer[2] != 0) break; + /* else FALLTHRU */ + case 2: + if (Pointer[1] != 0) break; + /* else FALLTHRU */ + case 1: + if (Pointer[0] != 0) break; + /* zero value */ + return; + default: + break; + } + /* + * If the data is too big for a TIR_S_C_STO_RIVB sub-record + * then we do it manually + */ + if (Size > 255) + { + while (--Repeat_Count >= 0) + VMS_Store_Immediate_Data (Pointer, Size, Record_Type); + return; + } + /* + * We are writing a "Record_Type" record + */ + Set_VMS_Object_File_Record (Record_Type); + /* + * If the buffer is empty we must insert record type + */ + if (Object_Record_Offset == 0) + PUT_CHAR (Record_Type); + /* + * Stack the repeat count + */ + PUT_CHAR (TIR_S_C_STA_LW); + PUT_LONG (Repeat_Count); + /* + * And now the command and its data + */ + PUT_CHAR (TIR_S_C_STO_RIVB); + PUT_CHAR (Size); + while (--Size >= 0) + PUT_CHAR (*Pointer++); + /* + * Flush the buffer if it is more than 75% full + */ + if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4)) + Flush_VMS_Object_Record_Buffer (); +} + + +/* + * Store a Position Independent Reference + */ +static void +VMS_Store_PIC_Symbol_Reference (Symbol, Offset, PC_Relative, + Psect, Psect_Offset, Record_Type) + symbolS *Symbol; + int Offset; + int PC_Relative; + int Psect; + int Psect_Offset; + int Record_Type; +{ + register struct VMS_Symbol *vsp = Symbol->sy_obj; + char Local[32]; + int local_sym = 0; + + /* + * We are writing a "Record_Type" record + */ + Set_VMS_Object_File_Record (Record_Type); + /* + * If the buffer is empty we must insert record type + */ + if (Object_Record_Offset == 0) + PUT_CHAR (Record_Type); + /* + * Set to the appropriate offset in the Psect. + * For a Code reference we need to fix the operand + * specifier as well, so back up 1 byte; + * for a Data reference we just store HERE. + */ + VMS_Set_Psect (Psect, + PC_Relative ? Psect_Offset - 1 : Psect_Offset, + Record_Type); + /* + * Make sure we are still generating a "Record Type" record + */ + if (Object_Record_Offset == 0) + PUT_CHAR (Record_Type); + /* + * Dispatch on symbol type (so we can stack its value) + */ + switch (S_GET_RAW_TYPE (Symbol)) + { + /* + * Global symbol + */ + case N_ABS: + local_sym = 1; + /*FALLTHRU*/ + case N_ABS | N_EXT: +#ifdef NOT_VAX_11_C_COMPATIBLE + case N_UNDF | N_EXT: + case N_DATA | N_EXT: +#endif /* NOT_VAX_11_C_COMPATIBLE */ + case N_UNDF: + case N_TEXT | N_EXT: + /* + * Get the symbol name (case hacked) + */ + VMS_Case_Hack_Symbol (S_GET_NAME (Symbol), Local); + /* + * Stack the global symbol value + */ + if (!local_sym) + { + PUT_CHAR (TIR_S_C_STA_GBL); + } + else + { + /* Local symbols have an extra field. */ + PUT_CHAR (TIR_S_C_STA_LSY); + PUT_SHORT (Current_Environment); + } + PUT_COUNTED_STRING (Local); + if (Offset) + { + /* + * Stack the longword offset + */ + PUT_CHAR (TIR_S_C_STA_LW); + PUT_LONG (Offset); + /* + * Add the two, leaving the result on the stack + */ + PUT_CHAR (TIR_S_C_OPR_ADD); + } + break; + /* + * Uninitialized local data + */ + case N_BSS: + /* + * Stack the Psect (+offset) + */ + vms_tir_stack_psect (vsp->Psect_Index, + vsp->Psect_Offset + Offset, + 0); + break; + /* + * Local text + */ + case N_TEXT: + /* + * Stack the Psect (+offset) + */ + vms_tir_stack_psect (vsp->Psect_Index, + S_GET_VALUE (Symbol) + Offset, + 0); + break; + /* + * Initialized local or global data + */ + case N_DATA: +#ifndef NOT_VAX_11_C_COMPATIBLE + case N_UNDF | N_EXT: + case N_DATA | N_EXT: +#endif /* NOT_VAX_11_C_COMPATIBLE */ + /* + * Stack the Psect (+offset) + */ + vms_tir_stack_psect (vsp->Psect_Index, + vsp->Psect_Offset + Offset, + 0); + break; + } + /* + * Store either a code or data reference + */ + PUT_CHAR (PC_Relative ? TIR_S_C_STO_PICR : TIR_S_C_STO_PIDR); + /* + * Flush the buffer if it is more than 75% full + */ + if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4)) + Flush_VMS_Object_Record_Buffer (); +} + + +/* + * Check in the text area for an indirect pc-relative reference + * and fix it up with addressing mode 0xff [PC indirect] + * + * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE + * PIC CODE GENERATING FIXUP ROUTINE. + */ +static void +VMS_Fix_Indirect_Reference (Text_Psect, Offset, fragP, text_frag_root) + int Text_Psect; + int Offset; + register fragS *fragP; + fragS *text_frag_root; +{ + /* + * The addressing mode byte is 1 byte before the address + */ + Offset--; + /* + * Is it in THIS frag?? + */ + if ((Offset < fragP->fr_address) || + (Offset >= (fragP->fr_address + fragP->fr_fix))) + { + /* + * We need to search for the fragment containing this + * Offset + */ + for (fragP = text_frag_root; fragP; fragP = fragP->fr_next) + { + if ((Offset >= fragP->fr_address) && + (Offset < (fragP->fr_address + fragP->fr_fix))) + break; + } + /* + * If we couldn't find the frag, things are BAD!! + */ + if (fragP == 0) + error (_("Couldn't find fixup fragment when checking for indirect reference")); + } + /* + * Check for indirect PC relative addressing mode + */ + if (fragP->fr_literal[Offset - fragP->fr_address] == (char) 0xff) + { + static char Address_Mode = (char) 0xff; + + /* + * Yes: Store the indirect mode back into the image + * to fix up the damage done by STO_PICR + */ + VMS_Set_Psect (Text_Psect, Offset, OBJ_S_C_TIR); + VMS_Store_Immediate_Data (&Address_Mode, 1, OBJ_S_C_TIR); + } +} + + +/* + * If the procedure "main()" exists we have to add the instruction + * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C". + * + * FIXME: the macro name `HACK_DEC_C_STARTUP' should be renamed + * to `HACK_VAXCRTL_STARTUP' because Digital's compiler + * named "DEC C" uses run-time library "DECC$SHR", but this + * startup code is for "VAXCRTL", the library for Digital's + * older "VAX C". Also, this extra code isn't needed for + * supporting gcc because it already generates the VAXCRTL + * startup call when compiling main(). The reference to + * `flag_hash_long_names' looks very suspicious too; + * probably an old-style command line option was inadvertently + * overloaded here, then blindly converted into the new one. + */ +void +vms_check_for_main () +{ + register symbolS *symbolP; +#ifdef HACK_DEC_C_STARTUP /* JF */ + register struct frchain *frchainP; + register fragS *fragP; + register fragS **prev_fragPP; + register struct fix *fixP; + register fragS *New_Frag; + int i; +#endif /* HACK_DEC_C_STARTUP */ + + symbolP = (symbolS *) symbol_find ("_main"); + if (symbolP && !S_IS_DEBUG (symbolP) && + S_IS_EXTERNAL (symbolP) && (S_GET_TYPE (symbolP) == N_TEXT)) + { +#ifdef HACK_DEC_C_STARTUP + if (!flag_hash_long_names) + { +#endif + /* + * Remember the entry point symbol + */ + Entry_Point_Symbol = symbolP; +#ifdef HACK_DEC_C_STARTUP + } + else + { + /* + * Scan all the fragment chains for the one with "_main" + * (Actually we know the fragment from the symbol, but we need + * the previous fragment so we can change its pointer) + */ + frchainP = frchain_root; + while (frchainP) + { + /* + * Scan all the fragments in this chain, remembering + * the "previous fragment" + */ + prev_fragPP = &frchainP->frch_root; + fragP = frchainP->frch_root; + while (fragP && (fragP != frchainP->frch_last)) + { + /* + * Is this the fragment? + */ + if (fragP == symbolP->sy_frag) + { + /* + * Yes: Modify the fragment by replacing + * it with a new fragment. + */ + New_Frag = (fragS *) + xmalloc (sizeof (*New_Frag) + + fragP->fr_fix + + fragP->fr_var + + 5); + /* + * The fragments are the same except + * that the "fixed" area is larger + */ + *New_Frag = *fragP; + New_Frag->fr_fix += 6; + /* + * Copy the literal data opening a hole + * 2 bytes after "_main" (i.e. just after + * the entry mask). Into which we place + * the JSB instruction. + */ + New_Frag->fr_literal[0] = fragP->fr_literal[0]; + New_Frag->fr_literal[1] = fragP->fr_literal[1]; + New_Frag->fr_literal[2] = 0x16; /* Jsb */ + New_Frag->fr_literal[3] = 0xef; + New_Frag->fr_literal[4] = 0; + New_Frag->fr_literal[5] = 0; + New_Frag->fr_literal[6] = 0; + New_Frag->fr_literal[7] = 0; + for (i = 2; i < fragP->fr_fix + fragP->fr_var; i++) + New_Frag->fr_literal[i + 6] = + fragP->fr_literal[i]; + /* + * Now replace the old fragment with the + * newly generated one. + */ + *prev_fragPP = New_Frag; + /* + * Remember the entry point symbol + */ + Entry_Point_Symbol = symbolP; + /* + * Scan the text area fixup structures + * as offsets in the fragment may have + * changed + */ + for (fixP = text_fix_root; fixP; fixP = fixP->fx_next) + { + /* + * Look for references to this + * fragment. + */ + if (fixP->fx_frag == fragP) + { + /* + * Change the fragment + * pointer + */ + fixP->fx_frag = New_Frag; + /* + * If the offset is after + * the entry mask we need + * to account for the JSB + * instruction we just + * inserted. + */ + if (fixP->fx_where >= 2) + fixP->fx_where += 6; + } + } + /* + * Scan the symbols as offsets in the + * fragment may have changed + */ + for (symbolP = symbol_rootP; + symbolP; + symbolP = symbol_next (symbolP)) + { + /* + * Look for references to this + * fragment. + */ + if (symbolP->sy_frag == fragP) + { + /* + * Change the fragment + * pointer + */ + symbolP->sy_frag = New_Frag; + /* + * If the offset is after + * the entry mask we need + * to account for the JSB + * instruction we just + * inserted. + */ + if (S_GET_VALUE (symbolP) >= 2) + S_SET_VALUE (symbolP, + S_GET_VALUE (symbolP) + 6); + } + } + /* + * Make a symbol reference to + * "_c$main_args" so we can get + * its address inserted into the + * JSB instruction. + */ + symbolP = (symbolS *) xmalloc (sizeof (*symbolP)); + S_SET_NAME (symbolP, "_C$MAIN_ARGS"); + S_SET_TYPE (symbolP, N_UNDF); + S_SET_OTHER (symbolP, 0); + S_SET_DESC (symbolP, 0); + S_SET_VALUE (symbolP, 0); + symbolP->sy_name_offset = 0; + symbolP->sy_number = 0; + symbolP->sy_obj = 0; + symbolP->sy_frag = New_Frag; + symbolP->sy_resolved = 0; + symbolP->sy_resolving = 0; + /* this actually inserts at the beginning of the list */ + symbol_append (symbol_rootP, symbolP, + &symbol_rootP, &symbol_lastP); + + symbol_rootP = symbolP; + /* + * Generate a text fixup structure + * to get "_c$main_args" stored into the + * JSB instruction. + */ + fixP = (struct fix *) xmalloc (sizeof (*fixP)); + fixP->fx_frag = New_Frag; + fixP->fx_where = 4; + fixP->fx_addsy = symbolP; + fixP->fx_subsy = 0; + fixP->fx_offset = 0; + fixP->fx_size = 4; + fixP->fx_pcrel = 1; + fixP->fx_next = text_fix_root; + text_fix_root = fixP; + /* + * Now make sure we exit from the loop + */ + frchainP = 0; + break; + } + /* + * Try the next fragment + */ + prev_fragPP = &fragP->fr_next; + fragP = fragP->fr_next; + } + /* + * Try the next fragment chain + */ + if (frchainP) + frchainP = frchainP->frch_next; + } + } +#endif /* HACK_DEC_C_STARTUP */ + } +} + + +/* + * Beginning of vms_write_object_file(). + */ + +static +struct vms_obj_state { + + /* Next program section index to use. */ + int psect_number; + + /* Psect index for code. Always ends up #0. */ + int text_psect; + + /* Psect index for initialized static variables. */ + int data_psect; + + /* Psect index for uninitialized static variables. */ + int bss_psect; + + /* Psect index for static constructors. */ + int ctors_psect; + + /* Psect index for static destructors. */ + int dtors_psect; + + /* Number of bytes used for local symbol data. */ + int local_initd_data_size; + + /* Dynamic buffer for initialized data. */ + char *data_segment; + +} vms_obj_state; + +#define Psect_Number vms_obj_state.psect_number +#define Text_Psect vms_obj_state.text_psect +#define Data_Psect vms_obj_state.data_psect +#define Bss_Psect vms_obj_state.bss_psect +#define Ctors_Psect vms_obj_state.ctors_psect +#define Dtors_Psect vms_obj_state.dtors_psect +#define Local_Initd_Data_Size vms_obj_state.local_initd_data_size +#define Data_Segment vms_obj_state.data_segment + + +#define IS_GXX_VTABLE(symP) (strncmp (S_GET_NAME (symP), "__vt.", 5) == 0) +#define IS_GXX_XTOR(symP) (strncmp (S_GET_NAME (symP), "__GLOBAL_.", 10) == 0) +#define XTOR_SIZE 4 + + +/* Perform text segment fixups. */ + +static void +vms_fixup_text_section (text_siz, text_frag_root, data_frag_root) + unsigned text_siz; + struct frag *text_frag_root; + struct frag *data_frag_root; +{ + register fragS *fragP; + register struct fix *fixP; + offsetT dif; + + /* Scan the text fragments. */ + for (fragP = text_frag_root; fragP; fragP = fragP->fr_next) + { + /* Stop if we get to the data fragments. */ + if (fragP == data_frag_root) + break; + /* Ignore fragments with no data. */ + if ((fragP->fr_fix == 0) && (fragP->fr_var == 0)) + continue; + /* Go the the appropriate offset in the Text Psect. */ + VMS_Set_Psect (Text_Psect, fragP->fr_address, OBJ_S_C_TIR); + /* Store the "fixed" part. */ + if (fragP->fr_fix) + VMS_Store_Immediate_Data (fragP->fr_literal, + fragP->fr_fix, + OBJ_S_C_TIR); + /* Store the "variable" part. */ + if (fragP->fr_var && fragP->fr_offset) + VMS_Store_Repeated_Data (fragP->fr_offset, + fragP->fr_literal + fragP->fr_fix, + fragP->fr_var, + OBJ_S_C_TIR); + } /* text frag loop */ + + /* + * Now we go through the text segment fixups and generate + * TIR records to fix up addresses within the Text Psect. + */ + for (fixP = text_fix_root; fixP; fixP = fixP->fx_next) + { + /* We DO handle the case of "Symbol - Symbol" as + long as it is in the same segment. */ + if (fixP->fx_subsy && fixP->fx_addsy) + { + /* They need to be in the same segment. */ + if (S_GET_RAW_TYPE (fixP->fx_subsy) != + S_GET_RAW_TYPE (fixP->fx_addsy)) + error (_("Fixup data addsy and subsy don't have the same type")); + /* And they need to be in one that we can check the psect on. */ + if ((S_GET_TYPE (fixP->fx_addsy) != N_DATA) && + (S_GET_TYPE (fixP->fx_addsy) != N_TEXT)) + error (_("Fixup data addsy and subsy don't have an appropriate type")); + /* This had better not be PC relative! */ + if (fixP->fx_pcrel) + error (_("Fixup data is erroneously \"pcrel\"")); + /* Subtract their values to get the difference. */ + dif = S_GET_VALUE (fixP->fx_addsy) - S_GET_VALUE (fixP->fx_subsy); + md_number_to_chars (Local, (valueT)dif, fixP->fx_size); + /* Now generate the fixup object records; + set the psect and store the data. */ + VMS_Set_Psect (Text_Psect, + fixP->fx_where + fixP->fx_frag->fr_address, + OBJ_S_C_TIR); + VMS_Store_Immediate_Data (Local, + fixP->fx_size, + OBJ_S_C_TIR); + continue; /* done with this fixup */ + } /* if fx_subsy && fx_addsy */ + /* Size will HAVE to be "long". */ + if (fixP->fx_size != 4) + error (_("Fixup datum is not a longword")); + /* Symbol must be "added" (if it is ever + subtracted we can fix this assumption). */ + if (fixP->fx_addsy == 0) + error (_("Fixup datum is not \"fixP->fx_addsy\"")); + /* Store the symbol value in a PIC fashion. */ + VMS_Store_PIC_Symbol_Reference (fixP->fx_addsy, + fixP->fx_offset, + fixP->fx_pcrel, + Text_Psect, + fixP->fx_where + fixP->fx_frag->fr_address, + OBJ_S_C_TIR); + /* + * Check for indirect address reference, which has to be fixed up + * (as the linker will screw it up with TIR_S_C_STO_PICR)... + */ + if (fixP->fx_pcrel) + VMS_Fix_Indirect_Reference (Text_Psect, + fixP->fx_where + fixP->fx_frag->fr_address, + fixP->fx_frag, + text_frag_root); + } /* text fix loop */ +} + + +/* Create a buffer holding the data segment. */ + +static void +synthesize_data_segment (data_siz, text_siz, data_frag_root) + unsigned data_siz, text_siz; + struct frag *data_frag_root; +{ + register fragS *fragP; + char *fill_literal; + long fill_size, count, i; + + /* Allocate the data segment. */ + Data_Segment = (char *) xmalloc (data_siz); + /* Run through the data fragments, filling in the segment. */ + for (fragP = data_frag_root; fragP; fragP = fragP->fr_next) + { + i = fragP->fr_address - text_siz; + if (fragP->fr_fix) + memcpy (Data_Segment + i, fragP->fr_literal, fragP->fr_fix); + i += fragP->fr_fix; + + if ((fill_size = fragP->fr_var) != 0) + { + fill_literal = fragP->fr_literal + fragP->fr_fix; + for (count = fragP->fr_offset; count; count--) + { + memcpy (Data_Segment + i, fill_literal, fill_size); + i += fill_size; + } + } + } /* data frag loop */ + + return; +} + + +/* Perform data segment fixups. */ + +static void +vms_fixup_data_section (data_siz, text_siz) + unsigned data_siz, text_siz; +{ + register struct VMS_Symbol *vsp; + register struct fix *fixP; + register symbolS *sp; + addressT fr_address; + offsetT dif; + valueT val; + + /* Run through all the data symbols and store the data. */ + for (vsp = VMS_Symbols; vsp; vsp = vsp->Next) + { + /* Ignore anything other than data symbols. */ + if (S_GET_TYPE (vsp->Symbol) != N_DATA) + continue; + /* Set the Psect + Offset. */ + VMS_Set_Psect (vsp->Psect_Index, + vsp->Psect_Offset, + OBJ_S_C_TIR); + /* Store the data. */ + val = S_GET_VALUE (vsp->Symbol); + VMS_Store_Immediate_Data (Data_Segment + val - text_siz, + vsp->Size, + OBJ_S_C_TIR); + } /* N_DATA symbol loop */ + + /* + * Now we go through the data segment fixups and generate + * TIR records to fix up addresses within the Data Psects. + */ + for (fixP = data_fix_root; fixP; fixP = fixP->fx_next) + { + /* Find the symbol for the containing datum. */ + for (vsp = VMS_Symbols; vsp; vsp = vsp->Next) + { + /* Only bother with Data symbols. */ + sp = vsp->Symbol; + if (S_GET_TYPE (sp) != N_DATA) + continue; + /* Ignore symbol if After fixup. */ + val = S_GET_VALUE (sp); + fr_address = fixP->fx_frag->fr_address; + if (val > fixP->fx_where + fr_address) + continue; + /* See if the datum is here. */ + if (val + vsp->Size <= fixP->fx_where + fr_address) + continue; + /* We DO handle the case of "Symbol - Symbol" as + long as it is in the same segment. */ + if (fixP->fx_subsy && fixP->fx_addsy) + { + /* They need to be in the same segment. */ + if (S_GET_RAW_TYPE (fixP->fx_subsy) != + S_GET_RAW_TYPE (fixP->fx_addsy)) + error (_("Fixup data addsy and subsy don't have the same type")); + /* And they need to be in one that we can check the psect on. */ + if ((S_GET_TYPE (fixP->fx_addsy) != N_DATA) && + (S_GET_TYPE (fixP->fx_addsy) != N_TEXT)) + error (_("Fixup data addsy and subsy don't have an appropriate type")); + /* This had better not be PC relative! */ + if (fixP->fx_pcrel) + error (_("Fixup data is erroneously \"pcrel\"")); + /* Subtract their values to get the difference. */ + dif = S_GET_VALUE (fixP->fx_addsy) - S_GET_VALUE (fixP->fx_subsy); + md_number_to_chars (Local, (valueT)dif, fixP->fx_size); + /* + * Now generate the fixup object records; + * set the psect and store the data. + */ + VMS_Set_Psect (vsp->Psect_Index, + fr_address + fixP->fx_where + - val + vsp->Psect_Offset, + OBJ_S_C_TIR); + VMS_Store_Immediate_Data (Local, + fixP->fx_size, + OBJ_S_C_TIR); + break; /* done with this fixup */ + } + /* Size will HAVE to be "long". */ + if (fixP->fx_size != 4) + error (_("Fixup datum is not a longword")); + /* Symbol must be "added" (if it is ever + subtracted we can fix this assumption). */ + if (fixP->fx_addsy == 0) + error (_("Fixup datum is not \"fixP->fx_addsy\"")); + /* Store the symbol value in a PIC fashion. */ + VMS_Store_PIC_Symbol_Reference (fixP->fx_addsy, + fixP->fx_offset, + fixP->fx_pcrel, + vsp->Psect_Index, + fr_address + fixP->fx_where + - val + vsp->Psect_Offset, + OBJ_S_C_TIR); + /* Done with this fixup. */ + break; + } /* vms_symbol loop */ + + } /* data fix loop */ +} + +/* Perform ctors/dtors segment fixups. */ + +static void +vms_fixup_xtors_section (symbols, sect_no) + struct VMS_Symbol *symbols; + int sect_no; +{ + register struct VMS_Symbol *vsp; + + /* Run through all the symbols and store the data. */ + for (vsp = symbols; vsp; vsp = vsp->Next) + { + register symbolS *sp; + + /* Set relocation base. */ + VMS_Set_Psect (vsp->Psect_Index, vsp->Psect_Offset, OBJ_S_C_TIR); + + sp = vsp->Symbol; + /* Stack the Psect base with its offset. */ + VMS_Set_Data (Text_Psect, S_GET_VALUE (sp), OBJ_S_C_TIR, 0); + } + /* Flush the buffer if it is more than 75% full. */ + if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4)) + Flush_VMS_Object_Record_Buffer (); + + return; +} + + +/* Define symbols for the linker. */ + +static void +global_symbol_directory (text_siz, data_siz) + unsigned text_siz, data_siz; +{ + register fragS *fragP; + register symbolS *sp; + register struct VMS_Symbol *vsp; + int Globalref, define_as_global_symbol; + +#if 0 + /* The g++ compiler does not write out external references to + vtables correctly. Check for this and holler if we see it + happening. If that compiler bug is ever fixed we can remove + this. + + (Jun'95: gcc 2.7.0's cc1plus still exhibits this behavior.) + + This was reportedly fixed as of June 2, 1998. */ + + for (sp = symbol_rootP; sp; sp = symbol_next (sp)) + if (S_GET_RAW_TYPE (sp) == N_UNDF && IS_GXX_VTABLE (sp)) + { + S_SET_TYPE (sp, N_UNDF | N_EXT); + S_SET_OTHER (sp, 1); + as_warn (_("g++ wrote an extern reference to `%s' as a routine.\nI will fix it, but I hope that it was note really a routine."), + S_GET_NAME (sp)); + } +#endif + + /* + * Now scan the symbols and emit the appropriate GSD records + */ + for (sp = symbol_rootP; sp; sp = symbol_next (sp)) + { + define_as_global_symbol = 0; + vsp = 0; + /* Dispatch on symbol type. */ + switch (S_GET_RAW_TYPE (sp)) + { + + /* Global uninitialized data. */ + case N_UNDF | N_EXT: + /* Make a VMS data symbol entry. */ + vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp); + vsp->Symbol = sp; + vsp->Size = S_GET_VALUE (sp); + vsp->Psect_Index = Psect_Number++; + vsp->Psect_Offset = 0; + vsp->Next = VMS_Symbols; + VMS_Symbols = vsp; + sp->sy_obj = vsp; + /* Make the psect for this data. */ + Globalref = VMS_Psect_Spec (S_GET_NAME (sp), + vsp->Size, + S_GET_OTHER (sp) ? ps_CONST : ps_COMMON, + vsp); + if (Globalref) + Psect_Number--; +#ifdef NOT_VAX_11_C_COMPATIBLE + define_as_global_symbol = 1; +#else + /* See if this is an external vtable. We want to help the + linker find these things in libraries, so we make a symbol + reference. This is not compatible with VAX-C usage for + variables, but since vtables are only used internally by + g++, we can get away with this hack. */ + define_as_global_symbol = IS_GXX_VTABLE (sp); +#endif + break; + + /* Local uninitialized data. */ + case N_BSS: + /* Make a VMS data symbol entry. */ + vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp); + vsp->Symbol = sp; + vsp->Size = 0; + vsp->Psect_Index = Bss_Psect; + vsp->Psect_Offset = S_GET_VALUE (sp) - bss_address_frag.fr_address; + vsp->Next = VMS_Symbols; + VMS_Symbols = vsp; + sp->sy_obj = vsp; + break; + + /* Global initialized data. */ + case N_DATA | N_EXT: + /* Make a VMS data symbol entry. */ + vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp); + vsp->Symbol = sp; + vsp->Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz); + vsp->Psect_Index = Psect_Number++; + vsp->Psect_Offset = 0; + vsp->Next = VMS_Symbols; + VMS_Symbols = vsp; + sp->sy_obj = vsp; + /* Make its psect. */ + Globalref = VMS_Psect_Spec (S_GET_NAME (sp), + vsp->Size, + S_GET_OTHER (sp) ? ps_CONST : ps_COMMON, + vsp); + if (Globalref) + Psect_Number--; +#ifdef NOT_VAX_11_C_COMPATIBLE + define_as_global_symbol = 1; +#else + /* See N_UNDF|N_EXT above for explanation. */ + define_as_global_symbol = IS_GXX_VTABLE (sp); +#endif + break; + + /* Local initialized data. */ + case N_DATA: + { + char *sym_name = S_GET_NAME (sp); + + /* Always suppress local numeric labels. */ + if (sym_name && strcmp (sym_name, FAKE_LABEL_NAME) == 0) + break; + + /* Make a VMS data symbol entry. */ + vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp); + vsp->Symbol = sp; + vsp->Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz); + vsp->Psect_Index = Data_Psect; + vsp->Psect_Offset = Local_Initd_Data_Size; + Local_Initd_Data_Size += vsp->Size; + vsp->Next = VMS_Symbols; + VMS_Symbols = vsp; + sp->sy_obj = vsp; + } + break; + + /* Global Text definition. */ + case N_TEXT | N_EXT: + { + + if (IS_GXX_XTOR (sp)) + { + vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp); + vsp->Symbol = sp; + vsp->Size = XTOR_SIZE; + sp->sy_obj = vsp; + switch ((S_GET_NAME (sp))[10]) + { + case 'I': + vsp->Psect_Index = Ctors_Psect; + vsp->Psect_Offset = (Ctors_Symbols==0)?0:(Ctors_Symbols->Psect_Offset+XTOR_SIZE); + vsp->Next = Ctors_Symbols; + Ctors_Symbols = vsp; + break; + case 'D': + vsp->Psect_Index = Dtors_Psect; + vsp->Psect_Offset = (Dtors_Symbols==0)?0:(Dtors_Symbols->Psect_Offset+XTOR_SIZE); + vsp->Next = Dtors_Symbols; + Dtors_Symbols = vsp; + break; + case 'G': + as_warn (_("Can't handle global xtors symbols yet.")); + break; + default: + as_warn (_("Unknown %s"), S_GET_NAME (sp)); + break; + } + } + else + { + unsigned short Entry_Mask; + + /* Get the entry mask. */ + fragP = sp->sy_frag; + /* First frag might be empty if we're generating listings. + So skip empty rs_fill frags. */ + while (fragP && fragP->fr_type == rs_fill && fragP->fr_fix == 0) + fragP = fragP->fr_next; + + /* If first frag doesn't contain the data, what do we do? + If it's possibly smaller than two bytes, that would + imply that the entry mask is not stored where we're + expecting it. + + If you can find a test case that triggers this, report + it (and tell me what the entry mask field ought to be), + and I'll try to fix it. KR */ + if (fragP->fr_fix < 2) + abort (); + + Entry_Mask = (fragP->fr_literal[0] & 0x00ff) | + ((fragP->fr_literal[1] & 0x00ff) << 8); + /* Define the procedure entry point. */ + VMS_Procedure_Entry_Pt (S_GET_NAME (sp), + Text_Psect, + S_GET_VALUE (sp), + Entry_Mask); + } + break; + } + + /* Local Text definition. */ + case N_TEXT: + /* Make a VMS data symbol entry. */ + if (Text_Psect != -1) + { + vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp); + vsp->Symbol = sp; + vsp->Size = 0; + vsp->Psect_Index = Text_Psect; + vsp->Psect_Offset = S_GET_VALUE (sp); + vsp->Next = VMS_Symbols; + VMS_Symbols = vsp; + sp->sy_obj = vsp; + } + break; + + /* Global Reference. */ + case N_UNDF: + /* Make a GSD global symbol reference record. */ + VMS_Global_Symbol_Spec (S_GET_NAME (sp), + 0, + 0, + GBLSYM_REF); + break; + + /* Absolute symbol. */ + case N_ABS: + case N_ABS | N_EXT: + /* gcc doesn't generate these; + VMS_Emit_Globalvalue handles them though. */ + vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp); + vsp->Symbol = sp; + vsp->Size = 4; /* always assume 32 bits */ + vsp->Psect_Index = 0; + vsp->Psect_Offset = S_GET_VALUE (sp); + vsp->Next = VMS_Symbols; + VMS_Symbols = vsp; + sp->sy_obj = vsp; + break; + + /* Anything else. */ + default: + /* Ignore STAB symbols, including .stabs emitted by g++. */ + if (S_IS_DEBUG (sp) || (S_GET_TYPE (sp) == 22)) + break; + /* + * Error otherwise. + */ + as_tsktsk (_("unhandled stab type %d"), S_GET_TYPE (sp)); + break; + } + + /* Global symbols have different linkage than external variables. */ + if (define_as_global_symbol) + VMS_Global_Symbol_Spec (S_GET_NAME (sp), + vsp->Psect_Index, + 0, + GBLSYM_DEF); + } + + return; +} + + +/* Output debugger symbol table information for symbols which + are local to a specific routine. */ + +static void +local_symbols_DST (s0P, Current_Routine) + symbolS *s0P, *Current_Routine; +{ + symbolS *s1P; + char *s0P_name, *pnt0, *pnt1; + + s0P_name = S_GET_NAME (s0P); + if (*s0P_name++ != '_') + return; + + for (s1P = Current_Routine; s1P; s1P = symbol_next (s1P)) + { +#if 0 /* redundant; RAW_TYPE != N_FUN suffices */ + if (!S_IS_DEBUG (s1P)) + continue; +#endif + if (S_GET_RAW_TYPE (s1P) != N_FUN) + continue; + pnt0 = s0P_name; + pnt1 = S_GET_NAME (s1P); + /* We assume the two strings are never exactly equal... */ + while (*pnt0++ == *pnt1++) + { + } + /* Found it if s0P name is exhausted and s1P name has ":F" or ":f" next. + Note: both pointers have advanced one past the non-matching char. */ + if ((*pnt1 == 'F' || *pnt1 == 'f') && *--pnt1 == ':' && *--pnt0 == '\0') + { + Define_Routine (s1P, 0, Current_Routine, Text_Psect); + return; + } + } +} + + +/* Construct and output the debug symbol table. */ + +static void +vms_build_DST (text_siz) + unsigned text_siz; +{ + register symbolS *symbolP; + symbolS *Current_Routine = 0; + struct input_file *Cur_File = 0; + offsetT Cur_Offset = -1; + int Cur_Line_Number = 0; + int File_Number = 0; + int Debugger_Offset = 0; + int file_available; + int dsc; + offsetT val; + + /* Write the Traceback Begin Module record. */ + VMS_TBT_Module_Begin (); + + /* + * Output debugging info for global variables and static variables + * that are not specific to one routine. We also need to examine + * all stabs directives, to find the definitions to all of the + * advanced data types, and this is done by VMS_LSYM_Parse. This + * needs to be done before any definitions are output to the object + * file, since there can be forward references in the stabs + * directives. When through with parsing, the text of the stabs + * directive is altered, with the definitions removed, so that later + * passes will see directives as they would be written if the type + * were already defined. + * + * We also look for files and include files, and make a list of + * them. We examine the source file numbers to establish the actual + * lines that code was generated from, and then generate offsets. + */ + VMS_LSYM_Parse (); + for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) + { + /* Only deal with STAB symbols here. */ + if (!S_IS_DEBUG (symbolP)) + continue; + /* + * Dispatch on STAB type. + */ + switch (S_GET_RAW_TYPE (symbolP)) + { + case N_SLINE: + dsc = S_GET_DESC (symbolP); + if (dsc > Cur_File->max_line) + Cur_File->max_line = dsc; + if (dsc < Cur_File->min_line) + Cur_File->min_line = dsc; + break; + case N_SO: + Cur_File = find_file (symbolP); + Cur_File->flag = 1; + Cur_File->min_line = 1; + break; + case N_SOL: + Cur_File = find_file (symbolP); + break; + case N_GSYM: + VMS_GSYM_Parse (symbolP, Text_Psect); + break; + case N_LCSYM: + VMS_LCSYM_Parse (symbolP, Text_Psect); + break; + case N_FUN: /* For static constant symbols */ + case N_STSYM: + VMS_STSYM_Parse (symbolP, Text_Psect); + break; + default: + break; + } /* switch */ + } /* for */ + + /* + * Now we take a quick sweep through the files and assign offsets + * to each one. This will essentially be the starting line number to + * the debugger for each file. Output the info for the debugger to + * specify the files, and then tell it how many lines to use. + */ + for (Cur_File = file_root; Cur_File; Cur_File = Cur_File->next) + { + if (Cur_File->max_line == 0) + continue; + if ((strncmp (Cur_File->name, "GNU_GXX_INCLUDE:", 16) == 0) && + !flag_debug) + continue; + if ((strncmp (Cur_File->name, "GNU_CC_INCLUDE:", 15) == 0) && + !flag_debug) + continue; + /* show a few extra lines at the start of the region selected */ + if (Cur_File->min_line > 2) + Cur_File->min_line -= 2; + Cur_File->offset = Debugger_Offset - Cur_File->min_line + 1; + Debugger_Offset += Cur_File->max_line - Cur_File->min_line + 1; + if (Cur_File->same_file_fpnt) + { + Cur_File->file_number = Cur_File->same_file_fpnt->file_number; + } + else + { + Cur_File->file_number = ++File_Number; + file_available = VMS_TBT_Source_File (Cur_File->name, + Cur_File->file_number); + if (!file_available) + { + Cur_File->file_number = 0; + File_Number--; + continue; + } + } + VMS_TBT_Source_Lines (Cur_File->file_number, + Cur_File->min_line, + Cur_File->max_line - Cur_File->min_line + 1); + } /* for */ + Cur_File = (struct input_file *) NULL; + + /* + * Scan the symbols and write out the routines + * (this makes the assumption that symbols are in + * order of ascending text segment offset) + */ + for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) + { + /* + * Deal with text symbols. + */ + if (!S_IS_DEBUG (symbolP) && S_GET_TYPE (symbolP) == N_TEXT) + { + /* + * Ignore symbols starting with "L", as they are local symbols. + */ + if (*S_GET_NAME (symbolP) == 'L') + continue; + /* + * If there is a routine start defined, terminate it. + */ + if (Current_Routine) + VMS_TBT_Routine_End (text_siz, Current_Routine); + + /* + * Check for & skip dummy labels like "gcc_compiled.". + * They're identified by the IN_DEFAULT_SECTION flag. + */ + if ((S_GET_OTHER (symbolP) & IN_DEFAULT_SECTION) != 0 && + S_GET_VALUE (symbolP) == 0) + continue; + /* + * Store the routine begin traceback info. + */ + VMS_TBT_Routine_Begin (symbolP, Text_Psect); + Current_Routine = symbolP; + /* + * Define symbols local to this routine. + */ + local_symbols_DST (symbolP, Current_Routine); + /* + * Done + */ + continue; + + } + /* + * Deal with STAB symbols. + */ + else if (S_IS_DEBUG (symbolP)) + { + /* + * Dispatch on STAB type. + */ + switch (S_GET_RAW_TYPE (symbolP)) + { + /* + * Line number + */ + case N_SLINE: + /* Offset the line into the correct portion of the file. */ + if (Cur_File->file_number == 0) + break; + val = S_GET_VALUE (symbolP); + /* Sometimes the same offset gets several source lines + assigned to it. We should be selective about which + lines we allow, we should prefer lines that are in + the main source file when debugging inline functions. */ + if (val == Cur_Offset && Cur_File->file_number != 1) + break; + + /* calculate actual debugger source line */ + dsc = S_GET_DESC (symbolP) + Cur_File->offset; + S_SET_DESC (symbolP, dsc); + /* + * Define PC/Line correlation. + */ + if (Cur_Offset == -1) + { + /* + * First N_SLINE; set up initial correlation. + */ + VMS_TBT_Line_PC_Correlation (dsc, + val, + Text_Psect, + 0); + } + else if ((dsc - Cur_Line_Number) <= 0) + { + /* + * Line delta is not +ve, we need to close the line and + * start a new PC/Line correlation. + */ + VMS_TBT_Line_PC_Correlation (0, + val - Cur_Offset, + 0, + -1); + VMS_TBT_Line_PC_Correlation (dsc, + val, + Text_Psect, + 0); + } + else + { + /* + * Line delta is +ve, all is well. + */ + VMS_TBT_Line_PC_Correlation (dsc - Cur_Line_Number, + val - Cur_Offset, + 0, + 1); + } + /* Update the current line/PC info. */ + Cur_Line_Number = dsc; + Cur_Offset = val; + break; + + /* + * Source file + */ + case N_SO: + /* Remember that we had a source file and emit + the source file debugger record. */ + Cur_File = find_file (symbolP); + break; + + case N_SOL: + /* We need to make sure that we are really in the actual + source file when we compute the maximum line number. + Otherwise the debugger gets really confused. */ + Cur_File = find_file (symbolP); + break; + + default: + break; + } /* switch */ + } /* if (IS_DEBUG) */ + } /* for */ + + /* + * If there is a routine start defined, terminate it + * (and the line numbers). + */ + if (Current_Routine) + { + /* Terminate the line numbers. */ + VMS_TBT_Line_PC_Correlation (0, + text_siz - S_GET_VALUE (Current_Routine), + 0, + -1); + /* Terminate the routine. */ + VMS_TBT_Routine_End (text_siz, Current_Routine); + } + + /* Write the Traceback End Module TBT record. */ + VMS_TBT_Module_End (); +} + + +/* Write a VAX/VMS object file (everything else has been done!). */ + +void +vms_write_object_file (text_siz, data_siz, bss_siz, text_frag_root, + data_frag_root) + unsigned text_siz; + unsigned data_siz; + unsigned bss_siz; + fragS *text_frag_root; + fragS *data_frag_root; +{ + register struct VMS_Symbol *vsp; + + /* + * Initialize program section indices; values get updated later. + */ + Psect_Number = 0; /* next Psect Index to use */ + Text_Psect = -1; /* Text Psect Index */ + Data_Psect = -2; /* Data Psect Index JF: Was -1 */ + Bss_Psect = -3; /* Bss Psect Index JF: Was -1 */ + Ctors_Psect = -4; /* Ctors Psect Index */ + Dtors_Psect = -5; /* Dtors Psect Index */ + /* Initialize other state variables. */ + Data_Segment = 0; + Local_Initd_Data_Size = 0; + + /* + * Create the actual output file and populate it with required + * "module header" information. + */ + Create_VMS_Object_File (); + Write_VMS_MHD_Records (); + + /* + * Create the Data segment: + * + * Since this is REALLY hard to do any other way, + * we actually manufacture the data segment and + * then store the appropriate values out of it. + * We need to generate this early, so that globalvalues + * can be properly emitted. + */ + if (data_siz > 0) + synthesize_data_segment (data_siz, text_siz, data_frag_root); + + + /******* Global Symbol Directory *******/ + + /* + * Emit globalvalues now. We must do this before the text psect is + * defined, or we will get linker warnings about multiply defined + * symbols. All of the globalvalues "reference" psect 0, although + * it really does not have anything to do with it. + */ + VMS_Emit_Globalvalues (text_siz, data_siz, Data_Segment); + /* + * Define the Text Psect + */ + Text_Psect = Psect_Number++; + VMS_Psect_Spec ("$code", text_siz, ps_TEXT, 0); + /* + * Define the BSS Psect + */ + if (bss_siz > 0) + { + Bss_Psect = Psect_Number++; + VMS_Psect_Spec ("$uninitialized_data", bss_siz, ps_DATA, 0); + } + /* + * Define symbols to the linker. + */ + global_symbol_directory (text_siz, data_siz); + /* + * Define the Data Psect + */ + if (data_siz > 0 && Local_Initd_Data_Size > 0) + { + Data_Psect = Psect_Number++; + VMS_Psect_Spec ("$data", Local_Initd_Data_Size, ps_DATA, 0); + /* + * Local initialized data (N_DATA) symbols need to be updated to the + * proper value of Data_Psect now that it's actually been defined. + * (A dummy value was used in global_symbol_directory() above.) + */ + for (vsp = VMS_Symbols; vsp; vsp = vsp->Next) + if (vsp->Psect_Index < 0 && S_GET_RAW_TYPE (vsp->Symbol) == N_DATA) + vsp->Psect_Index = Data_Psect; + } + + + if (Ctors_Symbols != 0) + { + char *ps_name = "$ctors"; + Ctors_Psect = Psect_Number++; + VMS_Psect_Spec (ps_name, Ctors_Symbols->Psect_Offset + XTOR_SIZE, + ps_CTORS, 0); + VMS_Global_Symbol_Spec (ps_name, Ctors_Psect, + 0, GBLSYM_DEF|GBLSYM_WEAK); + for (vsp = Ctors_Symbols; vsp; vsp = vsp->Next) + vsp->Psect_Index = Ctors_Psect; + } + + if (Dtors_Symbols != 0) + { + char *ps_name = "$dtors"; + Dtors_Psect = Psect_Number++; + VMS_Psect_Spec (ps_name, Dtors_Symbols->Psect_Offset + XTOR_SIZE, + ps_DTORS, 0); + VMS_Global_Symbol_Spec (ps_name, Dtors_Psect, + 0, GBLSYM_DEF|GBLSYM_WEAK); + for (vsp = Dtors_Symbols; vsp; vsp = vsp->Next) + vsp->Psect_Index = Dtors_Psect; + } + + /******* Text Information and Relocation Records *******/ + + /* + * Write the text segment data + */ + if (text_siz > 0) + vms_fixup_text_section (text_siz, text_frag_root, data_frag_root); + /* + * Write the data segment data, then discard it. + */ + if (data_siz > 0) + { + vms_fixup_data_section (data_siz, text_siz); + free (Data_Segment), Data_Segment = 0; + } + + if (Ctors_Symbols != 0) + { + vms_fixup_xtors_section (Ctors_Symbols, Ctors_Psect); + } + + if (Dtors_Symbols != 0) + { + vms_fixup_xtors_section (Dtors_Symbols, Dtors_Psect); + } + + + /******* Debugger Symbol Table Records *******/ + + vms_build_DST (text_siz); + + + /******* Wrap things up *******/ + + /* + * Write the End Of Module record + */ + if (Entry_Point_Symbol) + Write_VMS_EOM_Record (Text_Psect, S_GET_VALUE (Entry_Point_Symbol)); + else + Write_VMS_EOM_Record (-1, (valueT) 0); + + /* + * All done, close the object file + */ + Close_VMS_Object_File (); +} + +/* end of obj-vms.c */ diff --git a/gas/config/obj-vms.h b/gas/config/obj-vms.h new file mode 100644 index 0000000000..ac0c1fb356 --- /dev/null +++ b/gas/config/obj-vms.h @@ -0,0 +1,552 @@ +/* VMS object file format + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 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. */ + +/* Tag to validate a.out object file format processing */ +#define OBJ_VMS 1 + +#include "targ-cpu.h" + +#define LONGWORD_ALIGNMENT 2 + +/* This macro controls subsection alignment within a section. + * + * Under VAX/VMS, the linker (and PSECT specifications) + * take care of correctly aligning the segments. + * Doing the alignment here (on initialized data) can + * mess up the calculation of global data PSECT sizes. + */ +#define SUB_SEGMENT_ALIGN(SEG) \ + (((SEG) == data_section) ? 0 : LONGWORD_ALIGNMENT) + +/* This flag is used to remember whether we are in the const or the + data section. By and large they are identical, but we set a no-write + bit for psects in the const section. */ + +extern unsigned char const_flag; + +/* This is overloaded onto const_flag, for convenience. It's used to flag + dummy labels like "gcc2_compiled." which occur before the first .text + or .data section directive. */ + +#define IN_DEFAULT_SECTION 0x80 + +/* These are defined in obj-vms.c. */ +extern const short seg_N_TYPE[]; +extern const segT N_TYPE_seg[]; + +#undef NO_RELOC +enum reloc_type + { + NO_RELOC, RELOC_32 + }; + +#define N_BADMAG(x) (0) +#define N_TXTOFF(x) ( sizeof(struct exec) ) +#define N_DATOFF(x) ( N_TXTOFF(x) + (x).a_text ) +#define N_TROFF(x) ( N_DATOFF(x) + (x).a_data ) +#define N_DROFF(x) ( N_TROFF(x) + (x).a_trsize ) +#define N_SYMOFF(x) ( N_DROFF(x) + (x).a_drsize ) +#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms ) + +/* We use this copy of the exec header for VMS. We do not actually use it, but + what we actually do is let gas fill in the relevant slots, and when we get + around to writing an obj file, we just pick out what we need. */ + +struct exec +{ + unsigned long a_text; /* length of text, in bytes */ + unsigned long a_data; /* length of data, in bytes */ + unsigned long a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned long a_trsize; /* length of relocation info for text, in bytes */ + unsigned long a_drsize; /* length of relocation info for data, in bytes */ + unsigned long a_entry; /* start address */ + unsigned long a_syms; /* length of symbol table data in file, in bytes */ +}; + +typedef struct + { + struct exec header; /* a.out header */ + long string_table_size; /* names + '\0' + sizeof(int) */ + } +object_headers; + +/* A single entry in the symbol table + * (this started as a clone of bout.h's nlist, but much was unneeded). + */ +struct nlist + { + char *n_name; + unsigned char n_type; /* See below */ + unsigned char n_other; /* used for const_flag and "default section" */ + unsigned : 16; /* padding for alignment */ + int n_desc; /* source line number for N_SLINE stabs */ + }; + +/* Legal values of n_type (see aout/stab.def for the majority of the codes). + */ +#define N_UNDF 0 /* Undefined symbol */ +#define N_ABS 2 /* Absolute symbol */ +#define N_TEXT 4 /* Text symbol */ +#define N_DATA 6 /* Data symbol */ +#define N_BSS 8 /* BSS symbol */ +#define N_FN 31 /* Filename symbol */ + +#define N_EXT 1 /* External symbol (OR'd in with one of above) */ +#define N_TYPE 036 /* Mask for all the type bits */ + +#define N_STAB 0340 /* Mask for all bits used for SDB entries */ + +#include "aout/stab_gnu.h" + +/* SYMBOL TABLE */ +/* Symbol table entry data type */ + +typedef struct nlist obj_symbol_type; /* Symbol table entry */ + +/* Symbol table macros and constants */ + +#define OBJ_SYMFIELD_TYPE struct VMS_Symbol * + +/* + * Macros to extract information from a symbol table entry. + * This syntaxic 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) + +#define S_IS_COMMON(s) (S_GET_TYPE(s) == N_UNDF && S_GET_VALUE(s) != 0) + +#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 */ +/* A symbol name whose name begin with ^A is a gas internal pseudo symbol + nameless symbols come from .stab directives. */ +#define S_IS_LOCAL(s) (S_GET_NAME(s) && \ + !S_IS_DEBUG(s) && \ + (strchr(S_GET_NAME(s), '\001') != 0 || \ + strchr(S_GET_NAME(s), '\002') != 0 || \ + (S_LOCAL_NAME(s) && !flag_keep_locals))) +/* 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_name) +/* The pointer to the string table */ +#define S_GET_OFFSET(s) ((s)->sy_name_offset) +/* The raw type of the symbol */ +#define S_GET_RAW_TYPE(s) ((s)->sy_symbol.n_type) +/* 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) + +/* 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_name = (v)) +/* Set the offset in the string table */ +#define S_SET_OFFSET(s,v) ((s)->sy_name_offset = (v)) +/* 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)) +/* Set the n_type expression value */ +#define S_SET_TYPE(s,v) ((s)->sy_symbol.n_type = (v)) + + +/* File header macro and type definition */ + +#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_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_STRING_SIZE(h,v) ((h)->string_table_size = (v)) +#define H_SET_SYMBOL_TABLE_SIZE(h,v) ((h)->header.a_syms = (v) * \ + sizeof(struct nlist)) + +/* line numbering stuff. */ +#define OBJ_EMIT_LINENO(a, b, c) {;} + +#define obj_symbol_new_hook(s) {;} + +/* Force structure tags into scope so that their use in prototypes + will never be their first occurance. */ +struct fix; +struct symbol; +struct frag; + +/* obj-vms routines visible to the rest of gas. */ + +extern void tc_aout_fix_to_chars PARAMS ((char *,struct fix *,relax_addressT)); + +extern int vms_resolve_symbol_redef PARAMS ((struct symbol *)); +#define RESOLVE_SYMBOL_REDEFINITION(X) vms_resolve_symbol_redef(X) + +/* Compiler-generated label "__vax_g_doubles" is used to augment .stabs. */ +extern void vms_check_for_special_label PARAMS ((struct symbol *)); +#define obj_frob_label(X) vms_check_for_special_label(X) + +extern void vms_check_for_main PARAMS ((void)); + +extern void vms_write_object_file PARAMS ((unsigned,unsigned,unsigned, + struct frag *,struct frag *)); + +/* VMS executables are nothing like a.out, but the VMS port of gcc uses + a.out format stabs which obj-vms.c then translates. */ + +#define AOUT_STABS + + +#ifdef WANT_VMS_OBJ_DEFS + +/* The rest of this file contains definitions for constants used within + the actual VMS object file. We do not use a $ in the symbols (as per + usual VMS convention) since System V gags on it. */ + +#define OBJ_S_C_HDR 0 +#define OBJ_S_C_HDR_MHD 0 +#define OBJ_S_C_HDR_LNM 1 +#define OBJ_S_C_HDR_SRC 2 +#define OBJ_S_C_HDR_TTL 3 +#define OBJ_S_C_HDR_CPR 4 +#define OBJ_S_C_HDR_MTC 5 +#define OBJ_S_C_HDR_GTX 6 +#define OBJ_S_C_GSD 1 +#define OBJ_S_C_GSD_PSC 0 +#define OBJ_S_C_GSD_SYM 1 +#define OBJ_S_C_GSD_EPM 2 +#define OBJ_S_C_GSD_PRO 3 +#define OBJ_S_C_GSD_SYMW 4 +#define OBJ_S_C_GSD_EPMW 5 +#define OBJ_S_C_GSD_PROW 6 +#define OBJ_S_C_GSD_IDC 7 +#define OBJ_S_C_GSD_ENV 8 +#define OBJ_S_C_GSD_LSY 9 +#define OBJ_S_C_GSD_LEPM 10 +#define OBJ_S_C_GSD_LPRO 11 +#define OBJ_S_C_GSD_SPSC 12 +#define OBJ_S_C_TIR 2 +#define OBJ_S_C_EOM 3 +#define OBJ_S_C_DBG 4 +#define OBJ_S_C_TBT 5 +#define OBJ_S_C_LNK 6 +#define OBJ_S_C_EOMW 7 +#define OBJ_S_C_MAXRECTYP 7 +#define OBJ_S_K_SUBTYP 1 +#define OBJ_S_C_SUBTYP 1 +#define OBJ_S_C_MAXRECSIZ 2048 +#define OBJ_S_C_STRLVL 0 +#define OBJ_S_C_SYMSIZ 31 +#define OBJ_S_C_STOREPLIM -1 +#define OBJ_S_C_PSCALILIM 9 + +#define MHD_S_C_MHD 0 +#define MHD_S_C_LNM 1 +#define MHD_S_C_SRC 2 +#define MHD_S_C_TTL 3 +#define MHD_S_C_CPR 4 +#define MHD_S_C_MTC 5 +#define MHD_S_C_GTX 6 +#define MHD_S_C_MAXHDRTYP 6 + +#define GSD_S_K_ENTRIES 1 +#define GSD_S_C_ENTRIES 1 +#define GSD_S_C_PSC 0 +#define GSD_S_C_SYM 1 +#define GSD_S_C_EPM 2 +#define GSD_S_C_PRO 3 +#define GSD_S_C_SYMW 4 +#define GSD_S_C_EPMW 5 +#define GSD_S_C_PROW 6 +#define GSD_S_C_IDC 7 +#define GSD_S_C_ENV 8 +#define GSD_S_C_LSY 9 +#define GSD_S_C_LEPM 10 +#define GSD_S_C_LPRO 11 +#define GSD_S_C_SPSC 12 +#define GSD_S_C_SYMV 13 +#define GSD_S_C_EPMV 14 +#define GSD_S_C_PROV 15 +#define GSD_S_C_MAXRECTYP 15 + +#define GSY_S_M_WEAK 1 +#define GSY_S_M_DEF 2 +#define GSY_S_M_UNI 4 +#define GSY_S_M_REL 8 + +#define LSY_S_M_DEF 2 +#define LSY_S_M_REL 8 + +#define ENV_S_M_DEF 1 +#define ENV_S_M_NESTED 2 + +#define GPS_S_M_PIC 1 +#define GPS_S_M_LIB 2 +#define GPS_S_M_OVR 4 +#define GPS_S_M_REL 8 +#define GPS_S_M_GBL 16 +#define GPS_S_M_SHR 32 +#define GPS_S_M_EXE 64 +#define GPS_S_M_RD 128 +#define GPS_S_M_WRT 256 +#define GPS_S_M_VEC 512 +#define GPS_S_K_NAME 9 +#define GPS_S_C_NAME 9 + +#define TIR_S_C_STA_GBL 0 +#define TIR_S_C_STA_SB 1 +#define TIR_S_C_STA_SW 2 +#define TIR_S_C_STA_LW 3 +#define TIR_S_C_STA_PB 4 +#define TIR_S_C_STA_PW 5 +#define TIR_S_C_STA_PL 6 +#define TIR_S_C_STA_UB 7 +#define TIR_S_C_STA_UW 8 +#define TIR_S_C_STA_BFI 9 +#define TIR_S_C_STA_WFI 10 +#define TIR_S_C_STA_LFI 11 +#define TIR_S_C_STA_EPM 12 +#define TIR_S_C_STA_CKARG 13 +#define TIR_S_C_STA_WPB 14 +#define TIR_S_C_STA_WPW 15 +#define TIR_S_C_STA_WPL 16 +#define TIR_S_C_STA_LSY 17 +#define TIR_S_C_STA_LIT 18 +#define TIR_S_C_STA_LEPM 19 +#define TIR_S_C_MAXSTACOD 19 +#define TIR_S_C_MINSTOCOD 20 +#define TIR_S_C_STO_SB 20 +#define TIR_S_C_STO_SW 21 +#define TIR_S_C_STO_L 22 +#define TIR_S_C_STO_BD 23 +#define TIR_S_C_STO_WD 24 +#define TIR_S_C_STO_LD 25 +#define TIR_S_C_STO_LI 26 +#define TIR_S_C_STO_PIDR 27 +#define TIR_S_C_STO_PICR 28 +#define TIR_S_C_STO_RSB 29 +#define TIR_S_C_STO_RSW 30 +#define TIR_S_C_STO_RL 31 +#define TIR_S_C_STO_VPS 32 +#define TIR_S_C_STO_USB 33 +#define TIR_S_C_STO_USW 34 +#define TIR_S_C_STO_RUB 35 +#define TIR_S_C_STO_RUW 36 +#define TIR_S_C_STO_B 37 +#define TIR_S_C_STO_W 38 +#define TIR_S_C_STO_RB 39 +#define TIR_S_C_STO_RW 40 +#define TIR_S_C_STO_RIVB 41 +#define TIR_S_C_STO_PIRR 42 +#define TIR_S_C_MAXSTOCOD 42 +#define TIR_S_C_MINOPRCOD 50 +#define TIR_S_C_OPR_NOP 50 +#define TIR_S_C_OPR_ADD 51 +#define TIR_S_C_OPR_SUB 52 +#define TIR_S_C_OPR_MUL 53 +#define TIR_S_C_OPR_DIV 54 +#define TIR_S_C_OPR_AND 55 +#define TIR_S_C_OPR_IOR 56 +#define TIR_S_C_OPR_EOR 57 +#define TIR_S_C_OPR_NEG 58 +#define TIR_S_C_OPR_COM 59 +#define TIR_S_C_OPR_INSV 60 +#define TIR_S_C_OPR_ASH 61 +#define TIR_S_C_OPR_USH 62 +#define TIR_S_C_OPR_ROT 63 +#define TIR_S_C_OPR_SEL 64 +#define TIR_S_C_OPR_REDEF 65 +#define TIR_S_C_OPR_DFLIT 66 +#define TIR_S_C_MAXOPRCOD 66 +#define TIR_S_C_MINCTLCOD 80 +#define TIR_S_C_CTL_SETRB 80 +#define TIR_S_C_CTL_AUGRB 81 +#define TIR_S_C_CTL_DFLOC 82 +#define TIR_S_C_CTL_STLOC 83 +#define TIR_S_C_CTL_STKDL 84 +#define TIR_S_C_MAXCTLCOD 84 + +/* + * Debugger symbol definitions: These are done by hand, as no + * machine-readable version seems + * to be available. + */ +#define DST_S_C_C 7 /* Language == "C" */ +#define DST_S_C_CXX 15 /* Language == "C++" */ +#define DST_S_C_VERSION 153 +#define DST_S_C_SOURCE 155 /* Source file */ +#define DST_S_C_PROLOG 162 +#define DST_S_C_BLKBEG 176 /* Beginning of block */ +#define DST_S_C_BLKEND 177 /* End of block */ +#define DST_S_C_ENTRY 181 +#define DST_S_C_PSECT 184 +#define DST_S_C_LINE_NUM 185 /* Line Number */ +#define DST_S_C_LBLORLIT 186 +#define DST_S_C_LABEL 187 +#define DST_S_C_MODBEG 188 /* Beginning of module */ +#define DST_S_C_MODEND 189 /* End of module */ +#define DST_S_C_RTNBEG 190 /* Beginning of routine */ +#define DST_S_C_RTNEND 191 /* End of routine */ +#define DST_S_C_DELTA_PC_W 1 /* Incr PC */ +#define DST_S_C_INCR_LINUM 2 /* Incr Line # */ +#define DST_S_C_INCR_LINUM_W 3 /* Incr Line # */ +#define DST_S_C_SET_LINUM_INCR 4 +#define DST_S_C_SET_LINUM_INCR_W 5 +#define DST_S_C_RESET_LINUM_INCR 6 +#define DST_S_C_BEG_STMT_MODE 7 +#define DST_S_C_END_STMT_MODE 8 +#define DST_S_C_SET_LINE_NUM 9 /* Set Line # */ +#define DST_S_C_SET_PC 10 +#define DST_S_C_SET_PC_W 11 +#define DST_S_C_SET_PC_L 12 +#define DST_S_C_SET_STMTNUM 13 +#define DST_S_C_TERM 14 /* End of lines */ +#define DST_S_C_TERM_W 15 /* End of lines */ +#define DST_S_C_SET_ABS_PC 16 /* Set PC */ +#define DST_S_C_DELTA_PC_L 17 /* Incr PC */ +#define DST_S_C_INCR_LINUM_L 18 /* Incr Line # */ +#define DST_S_C_SET_LINUM_B 19 /* Set Line # */ +#define DST_S_C_SET_LINUM_L 20 /* Set Line # */ +#define DST_S_C_TERM_L 21 /* End of lines */ +/* these are used with DST_S_C_SOURCE */ +#define DST_S_C_SRC_DECLFILE 1 /* Declare source file */ +#define DST_S_C_SRC_SETFILE 2 /* Set source file */ +#define DST_S_C_SRC_SETREC_L 3 /* Set record, longword value */ +#define DST_S_C_SRC_SETREC_W 4 /* Set record, word value */ +#define DST_S_C_SRC_DEFLINES_W 10 /* # of line, word counter */ +#define DST_S_C_SRC_DEFLINES_B 11 /* # of line, byte counter */ +#define DST_S_C_SRC_FORMFEED 16 /* ^L counts as a record */ +/* the following are the codes for the various data types. Anything not on + * the list is included under 'advanced_type' + */ +#define DBG_S_C_UCHAR 0x02 +#define DBG_S_C_USINT 0x03 +#define DBG_S_C_ULINT 0x04 +#define DBG_S_C_UQUAD 0x05 +#define DBG_S_C_SCHAR 0x06 +#define DBG_S_C_SSINT 0x07 +#define DBG_S_C_SLINT 0x08 +#define DBG_S_C_SQUAD 0x09 +#define DBG_S_C_REAL4 0x0a +#define DBG_S_C_REAL8 0x0b /* D_float double */ +#define DBG_S_C_COMPLX4 0x0c /* 2xF_float complex float */ +#define DBG_S_C_COMPLX8 0x0d /* 2xD_float complex double */ +#define DBG_S_C_REAL8_G 0x1b /* G_float double */ +#define DBG_S_C_COMPLX8_G 0x1d /* 2xG_float complex double */ +#define DBG_S_C_FUNCTION_ADDR 0x17 +#define DBG_S_C_ADVANCED_TYPE 0xa3 +/* Some of these are just for future reference. [pr] + */ +#define DBG_S_C_UBITA 0x01 /* unsigned, aligned bit field */ +#define DBG_S_C_UBITU 0x22 /* unsigned, unaligned bit field */ +#define DBG_S_C_SBITA 0x29 /* signed, aligned bit field */ +#define DBG_S_C_SBITU 0x2a /* signed, unaligned bit field */ +#define DBG_S_C_CSTRING 0x2e /* asciz ('\0' terminated) string */ +#define DBG_S_C_WCHAR 0x38 /* wchar_t */ +/* These are descriptor class codes. + */ +#define DSC_K_CLASS_S 0x01 /* static (fixed length) */ +#define DSC_K_CLASS_D 0x02 /* dynamic string (not via malloc!) */ +#define DSC_K_CLASS_A 0x04 /* array */ +#define DSC_K_CLASS_UBS 0x0d /* unaligned bit string */ +/* These are the codes that are used to generate the definitions of struct + * union and enum records + */ +#define DBG_S_C_ENUM_ITEM 0xa4 +#define DBG_S_C_ENUM_START 0xa5 +#define DBG_S_C_ENUM_END 0xa6 +#define DBG_S_C_STRUCT_ITEM DST_K_VFLAGS_BITOFFS /* 0xff */ +#define DBG_S_C_STRUCT_START 0xab +#define DBG_S_C_STRUCT_END 0xac +#define DST_K_TYPSPEC 0xaf /* type specification */ +/* These codes are used in the generation of the symbol definition records + */ +#define DST_K_VFLAGS_NOVAL 0x80 /* struct definition only */ +#define DST_K_VFLAGS_DSC 0xfa /* descriptor used */ +#define DST_K_VFLAGS_TVS 0xfb /* trailing value specified */ +#define DST_K_VS_FOLLOWS 0xfd /* value spec follows */ +#define DST_K_VFLAGS_BITOFFS 0xff /* value contains bit offset */ +#define DST_K_VALKIND_LITERAL 0 +#define DST_K_VALKIND_ADDR 1 +#define DST_K_VALKIND_DESC 2 +#define DST_K_VALKIND_REG 3 +#define DST_K_REG_VAX_AP 0x0c /* R12 */ +#define DST_K_REG_VAX_FP 0x0d /* R13 */ +#define DST_K_REG_VAX_SP 0x0e /* R14 */ +#define DST_V_VALKIND 0 /* offset of valkind field */ +#define DST_V_INDIRECT 2 /* offset to indirect bit */ +#define DST_V_DISP 3 /* offset to displacement bit */ +#define DST_V_REGNUM 4 /* offset to register number */ +#define DST_M_INDIRECT (1< +#include "as.h" + +#include "opcode/a29k.h" + +/* Make it easier to clone this machine desc into another one. */ +#define machine_opcode a29k_opcode +#define machine_opcodes a29k_opcodes +#define machine_ip a29k_ip +#define machine_it a29k_it + +#define IMMEDIATE_BIT 0x01000000 /* Turns RB into Immediate */ +#define ABSOLUTE_BIT 0x01000000 /* Turns PC-relative to Absolute */ +#define CE_BIT 0x00800000 /* Coprocessor enable in LOAD */ +#define UI_BIT 0x00000080 /* Unsigned integer in CONVERT */ + +/* handle of the OPCODE hash table */ +static struct hash_control *op_hash = NULL; + +struct machine_it + { + char *error; + unsigned long opcode; + struct nlist *nlistp; + expressionS exp; + int pcrel; + int reloc_offset; /* Offset of reloc within insn */ + + int reloc; + } +the_insn; + +static void machine_ip PARAMS ((char *str)); +/* static void print_insn PARAMS ((struct machine_it *insn)); */ +#ifndef OBJ_COFF +static void s_data1 PARAMS ((void)); +static void s_use PARAMS ((int)); +#endif + +const pseudo_typeS +md_pseudo_table[] = +{ + {"align", s_align_bytes, 4}, + {"block", s_space, 0}, + {"cputype", s_ignore, 0}, /* CPU as 29000 or 29050 */ + {"reg", s_lsym, 0}, /* Register equate, same as equ */ + {"space", s_ignore, 0}, /* Listing control */ + {"sect", s_ignore, 0}, /* Creation of coff sections */ +#ifndef OBJ_COFF + /* We can do this right with coff. */ + {"use", s_use, 0}, +#endif + {"word", cons, 4}, + {NULL, 0, 0}, +}; + +#if defined(BFD_HEADERS) +#ifdef RELSZ +const int md_reloc_size = RELSZ; /* Coff headers */ +#else +const int md_reloc_size = 12; /* something else headers */ +#endif +#else +const int md_reloc_size = 12; /* Not bfdized*/ +#endif + +/* 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[] = "#"; + +/* We needed an unused char for line separation to work around the + lack of macros, using sed and such. */ +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. */ + +/* + * anull bit - causes the branch delay slot instructions to not be executed + */ +#define ANNUL (1 << 29) + +#ifndef OBJ_COFF + +static void +s_use (ignore) + int ignore; +{ + if (strncmp (input_line_pointer, ".text", 5) == 0) + { + input_line_pointer += 5; + s_text (0); + return; + } + if (strncmp (input_line_pointer, ".data", 5) == 0) + { + input_line_pointer += 5; + s_data (0); + return; + } + if (strncmp (input_line_pointer, ".data1", 6) == 0) + { + input_line_pointer += 6; + s_data1 (); + return; + } + /* Literals can't go in the text segment because you can't read from + instruction memory on some 29k's. So, into initialized data. */ + if (strncmp (input_line_pointer, ".lit", 4) == 0) + { + input_line_pointer += 4; + subseg_set (SEG_DATA, 200); + demand_empty_rest_of_line (); + return; + } + + as_bad (_("Unknown segment type")); + demand_empty_rest_of_line (); +} + +static void +s_data1 () +{ + subseg_set (SEG_DATA, 1); + demand_empty_rest_of_line (); +} + +#endif /* OBJ_COFF */ + +/* Install symbol definition that maps REGNAME to REGNO. + FIXME-SOON: These are not recognized in mixed case. */ + +static void +insert_sreg (regname, regnum) + char *regname; + int regnum; +{ + /* FIXME-SOON, put something in these syms so they won't be output + to the symbol table of the resulting object file. */ + + /* Must be large enough to hold the names of the special registers. */ + char buf[80]; + int i; + + symbol_table_insert (symbol_new (regname, SEG_REGISTER, (valueT) regnum, + &zero_address_frag)); + for (i = 0; regname[i]; i++) + buf[i] = islower (regname[i]) ? toupper (regname[i]) : regname[i]; + buf[i] = '\0'; + + symbol_table_insert (symbol_new (buf, SEG_REGISTER, (valueT) regnum, + &zero_address_frag)); +} + +/* Install symbol definitions for assorted special registers. + See ASM29K Ref page 2-9. */ + +void +define_some_regs () +{ +#define SREG 256 + + /* Protected special-purpose register names */ + insert_sreg ("vab", SREG + 0); + insert_sreg ("ops", SREG + 1); + insert_sreg ("cps", SREG + 2); + insert_sreg ("cfg", SREG + 3); + insert_sreg ("cha", SREG + 4); + insert_sreg ("chd", SREG + 5); + insert_sreg ("chc", SREG + 6); + insert_sreg ("rbp", SREG + 7); + insert_sreg ("tmc", SREG + 8); + insert_sreg ("tmr", SREG + 9); + insert_sreg ("pc0", SREG + 10); + insert_sreg ("pc1", SREG + 11); + insert_sreg ("pc2", SREG + 12); + insert_sreg ("mmu", SREG + 13); + insert_sreg ("lru", SREG + 14); + + /* Additional protected special-purpose registers for the 29050 */ + insert_sreg ("rsn", SREG + 15); + insert_sreg ("rma0", SREG + 16); + insert_sreg ("rmc0", SREG + 17); + insert_sreg ("rma1", SREG + 18); + insert_sreg ("rmc1", SREG + 19); + insert_sreg ("spc0", SREG + 20); + insert_sreg ("spc1", SREG + 21); + insert_sreg ("spc2", SREG + 22); + insert_sreg ("iba0", SREG + 23); + insert_sreg ("ibc0", SREG + 24); + insert_sreg ("iba1", SREG + 25); + insert_sreg ("ibc1", SREG + 26); + + /* Additional registers for the 29040. */ + insert_sreg ("dba", SREG + 27); + insert_sreg ("dbc", SREG + 28); + insert_sreg ("cir", SREG + 29); + insert_sreg ("cdr", SREG + 30); + + /* Unprotected special-purpose register names */ + insert_sreg ("ipc", SREG + 128); + insert_sreg ("ipa", SREG + 129); + insert_sreg ("ipb", SREG + 130); + insert_sreg ("q", SREG + 131); + insert_sreg ("alu", SREG + 132); + insert_sreg ("bp", SREG + 133); + insert_sreg ("fc", SREG + 134); + insert_sreg ("cr", SREG + 135); + insert_sreg ("fpe", SREG + 160); + insert_sreg ("inte", SREG + 161); + insert_sreg ("fps", SREG + 162); + /* "", SREG+163); Reserved */ + insert_sreg ("exop", SREG + 164); +} + +/* 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 int skipnext = 0; + register unsigned int i; + register char *strend, *strend2; + + /* Hash up all the opcodes for fast use later. */ + + op_hash = hash_new (); + + for (i = 0; i < num_opcodes; i++) + { + const char *name = machine_opcodes[i].name; + + if (skipnext) + { + skipnext = 0; + continue; + } + + /* Hack to avoid multiple opcode entries. We pre-locate all the + variations (b/i field and P/A field) and handle them. */ + + if (!strcmp (name, machine_opcodes[i + 1].name)) + { + if ((machine_opcodes[i].opcode & 0x01000000) != 0 + || (machine_opcodes[i + 1].opcode & 0x01000000) == 0 + || ((machine_opcodes[i].opcode | 0x01000000) + != machine_opcodes[i + 1].opcode)) + goto bad_table; + strend = machine_opcodes[i].args + strlen (machine_opcodes[i].args) - 1; + strend2 = machine_opcodes[i + 1].args + strlen (machine_opcodes[i + 1].args) - 1; + switch (*strend) + { + case 'b': + if (*strend2 != 'i') + goto bad_table; + break; + case 'P': + if (*strend2 != 'A') + goto bad_table; + break; + default: + bad_table: + fprintf (stderr, "internal error: can't handle opcode %s\n", + name); + lose = 1; + } + + /* OK, this is an i/b or A/P pair. We skip the + higher-valued one, and let the code for operand checking + handle OR-ing in the bit. */ + skipnext = 1; + } + + retval = hash_insert (op_hash, name, (PTR) &machine_opcodes[i]); + if (retval != NULL) + { + fprintf (stderr, "internal error: can't hash `%s': %s\n", + machine_opcodes[i].name, retval); + lose = 1; + } + } + + if (lose) + as_fatal (_("Broken assembler. No assembly attempted.")); + + define_some_regs (); +} + +/* Assemble a single instruction. Its label has already been handled + by the generic front end. We just parse opcode and operands, and + produce the bytes of data and relocation. */ + +void +md_assemble (str) + char *str; +{ + char *toP; + + know (str); + machine_ip (str); + toP = frag_more (4); + /* put out the opcode */ + md_number_to_chars (toP, the_insn.opcode, 4); + + /* put out the symbol-dependent stuff */ + if (the_insn.reloc != NO_RELOC) + { + fix_new_exp (frag_now, + (toP - frag_now->fr_literal + the_insn.reloc_offset), + 4, /* size */ + &the_insn.exp, + the_insn.pcrel, + the_insn.reloc); + } +} + +char * +parse_operand (s, operandp, opt) + char *s; + expressionS *operandp; + int opt; +{ + char *save = input_line_pointer; + char *new; + + input_line_pointer = s; + expression (operandp); + if (operandp->X_op == O_absent && ! opt) + as_bad (_("missing operand")); + new = input_line_pointer; + input_line_pointer = save; + return new; +} + +/* Instruction parsing. Takes a string containing the opcode. + Operands are at input_line_pointer. Output is in the_insn. + Warnings or errors are generated. */ + +static void +machine_ip (str) + char *str; +{ + char *s; + const char *args; + struct machine_opcode *insn; + char *argsStart; + unsigned long opcode; + expressionS the_operand; + expressionS *operand = &the_operand; + unsigned int reg; + + /* Must handle `div0' opcode. */ + s = str; + if (isalpha (*s)) + for (; isalnum (*s); ++s) + if (isupper (*s)) + *s = tolower (*s); + + switch (*s) + { + case '\0': + break; + + case ' ': /* FIXME-SOMEDAY more whitespace */ + *s++ = '\0'; + break; + + default: + as_bad (_("Unknown opcode: `%s'"), str); + return; + } + if ((insn = (struct machine_opcode *) hash_find (op_hash, str)) == NULL) + { + as_bad (_("Unknown opcode `%s'."), str); + return; + } + argsStart = s; + opcode = insn->opcode; + memset (&the_insn, '\0', sizeof (the_insn)); + the_insn.reloc = NO_RELOC; + + /* Build the opcode, checking as we go to make sure that the + operands match. + + If an operand matches, we modify the_insn or opcode appropriately, + and do a "continue". If an operand fails to match, we "break". */ + + if (insn->args[0] != '\0') + { + /* Prime the pump. */ + s = parse_operand (s, operand, insn->args[0] == 'I'); + } + + for (args = insn->args;; ++args) + { + switch (*args) + { + + case '\0': /* end of args */ + if (*s == '\0') + { + /* We are truly done. */ + the_insn.opcode = opcode; + return; + } + as_bad (_("Too many operands: %s"), s); + break; + + case ',': /* Must match a comma */ + if (*s++ == ',') + { + /* Parse next operand. */ + s = parse_operand (s, operand, args[1] == 'I'); + continue; + } + break; + + case 'v': /* Trap numbers (immediate field) */ + if (operand->X_op == O_constant) + { + if (operand->X_add_number < 256) + { + opcode |= (operand->X_add_number << 16); + continue; + } + else + { + as_bad (_("Immediate value of %ld is too large"), + (long) operand->X_add_number); + continue; + } + } + the_insn.reloc = RELOC_8; + the_insn.reloc_offset = 1; /* BIG-ENDIAN Byte 1 of insn */ + the_insn.exp = *operand; + continue; + + case 'b': /* A general register or 8-bit immediate */ + case 'i': + /* We treat the two cases identically since we mashed + them together in the opcode table. */ + if (operand->X_op == O_register) + goto general_reg; + + /* Make sure the 'i' case really exists. */ + if ((insn->opcode | IMMEDIATE_BIT) != (insn + 1)->opcode) + break; + + opcode |= IMMEDIATE_BIT; + if (operand->X_op == O_constant) + { + if (operand->X_add_number < 256) + { + opcode |= operand->X_add_number; + continue; + } + else + { + as_bad (_("Immediate value of %ld is too large"), + (long) operand->X_add_number); + continue; + } + } + the_insn.reloc = RELOC_8; + the_insn.reloc_offset = 3; /* BIG-ENDIAN Byte 3 of insn */ + the_insn.exp = *operand; + continue; + + case 'a': /* next operand must be a register */ + case 'c': + general_reg: + /* lrNNN or grNNN or %%expr or a user-def register name */ + if (operand->X_op != O_register) + break; /* Only registers */ + know (operand->X_add_symbol == 0); + know (operand->X_op_symbol == 0); + reg = operand->X_add_number; + if (reg >= SREG) + break; /* No special registers */ + + /* Got the register, now figure out where it goes in the + opcode. */ + switch (*args) + { + case 'a': + opcode |= reg << 8; + continue; + + case 'b': + case 'i': + opcode |= reg; + continue; + + case 'c': + opcode |= reg << 16; + continue; + } + as_fatal (_("failed sanity check.")); + break; + + case 'x': /* 16 bit constant, zero-extended */ + case 'X': /* 16 bit constant, one-extended */ + if (operand->X_op == O_constant) + { + opcode |= (operand->X_add_number & 0xFF) << 0 | + ((operand->X_add_number & 0xFF00) << 8); + continue; + } + the_insn.reloc = RELOC_CONST; + the_insn.exp = *operand; + continue; + + case 'h': + if (operand->X_op == O_constant) + { + opcode |= (operand->X_add_number & 0x00FF0000) >> 16 | + (((unsigned long) operand->X_add_number + /* avoid sign ext */ & 0xFF000000) >> 8); + continue; + } + the_insn.reloc = RELOC_CONSTH; + the_insn.exp = *operand; + continue; + + case 'P': /* PC-relative jump address */ + case 'A': /* Absolute jump address */ + /* These two are treated together since we folded the + opcode table entries together. */ + if (operand->X_op == O_constant) + { + /* Make sure the 'A' case really exists. */ + if ((insn->opcode | ABSOLUTE_BIT) != (insn + 1)->opcode) + break; + { + bfd_vma v, mask; + mask = 0x1ffff; + v = operand->X_add_number & ~ mask; + if (v) + as_bad ("call/jmp target out of range"); + } + opcode |= ABSOLUTE_BIT | + (operand->X_add_number & 0x0003FC00) << 6 | + ((operand->X_add_number & 0x000003FC) >> 2); + continue; + } + the_insn.reloc = RELOC_JUMPTARG; + the_insn.exp = *operand; + the_insn.pcrel = 1; /* Assume PC-relative jump */ + /* FIXME-SOON, Do we figure out whether abs later, after + know sym val? */ + continue; + + case 'e': /* Coprocessor enable bit for LOAD/STORE insn */ + if (operand->X_op == O_constant) + { + if (operand->X_add_number == 0) + continue; + if (operand->X_add_number == 1) + { + opcode |= CE_BIT; + continue; + } + } + break; + + case 'n': /* Control bits for LOAD/STORE instructions */ + if (operand->X_op == O_constant && + operand->X_add_number < 128) + { + opcode |= (operand->X_add_number << 16); + continue; + } + break; + + case 's': /* Special register number */ + if (operand->X_op != O_register) + break; /* Only registers */ + if (operand->X_add_number < SREG) + break; /* Not a special register */ + opcode |= (operand->X_add_number & 0xFF) << 8; + continue; + + case 'u': /* UI bit of CONVERT */ + if (operand->X_op == O_constant) + { + if (operand->X_add_number == 0) + continue; + if (operand->X_add_number == 1) + { + opcode |= UI_BIT; + continue; + } + } + break; + + case 'r': /* RND bits of CONVERT */ + if (operand->X_op == O_constant && + operand->X_add_number < 8) + { + opcode |= operand->X_add_number << 4; + continue; + } + break; + + case 'I': /* ID bits of INV and IRETINV. */ + /* This operand is optional. */ + if (operand->X_op == O_absent) + continue; + else if (operand->X_op == O_constant + && operand->X_add_number < 4) + { + opcode |= operand->X_add_number << 16; + continue; + } + break; + + case 'd': /* FD bits of CONVERT */ + if (operand->X_op == O_constant && + operand->X_add_number < 4) + { + opcode |= operand->X_add_number << 2; + continue; + } + break; + + + case 'f': /* FS bits of CONVERT */ + if (operand->X_op == O_constant && + operand->X_add_number < 4) + { + opcode |= operand->X_add_number << 0; + continue; + } + break; + + case 'C': + if (operand->X_op == O_constant && + operand->X_add_number < 4) + { + opcode |= operand->X_add_number << 16; + continue; + } + break; + + case 'F': + if (operand->X_op == O_constant && + operand->X_add_number < 16) + { + opcode |= operand->X_add_number << 18; + continue; + } + break; + + default: + BAD_CASE (*args); + } + /* Types or values of args don't match. */ + as_bad ("Invalid operands"); + return; + } +} + +/* 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 prec; + LITTLENUM_TYPE words[MAX_LITTLENUMS]; + LITTLENUM_TYPE *wordP; + 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); + for (wordP = words; prec--;) + { + md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE)); + litP += sizeof (LITTLENUM_TYPE); + } + return 0; +} + +/* + * Write out big-endian. + */ +void +md_number_to_chars (buf, val, n) + char *buf; + valueT val; + int n; +{ + number_to_chars_bigendian (buf, val, n); +} + +void +md_apply_fix (fixP, val) + fixS *fixP; + long val; +{ + char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; + + fixP->fx_addnumber = val; /* Remember value for emit_reloc */ + + + know (fixP->fx_size == 4); + know (fixP->fx_r_type < NO_RELOC); + + /* This is a hack. There should be a better way to handle this. */ + if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy) + { + val += fixP->fx_where + fixP->fx_frag->fr_address; + } + + switch (fixP->fx_r_type) + { + + case RELOC_32: + buf[0] = val >> 24; + buf[1] = val >> 16; + buf[2] = val >> 8; + buf[3] = val; + break; + + case RELOC_8: + buf[0] = val; + break; + + case RELOC_WDISP30: + val = (val >>= 2) + 1; + buf[0] |= (val >> 24) & 0x3f; + buf[1] = (val >> 16); + buf[2] = val >> 8; + buf[3] = val; + break; + + case RELOC_HI22: + buf[1] |= (val >> 26) & 0x3f; + buf[2] = val >> 18; + buf[3] = val >> 10; + break; + + case RELOC_LO10: + buf[2] |= (val >> 8) & 0x03; + buf[3] = val; + break; + + case RELOC_BASE13: + buf[2] |= (val >> 8) & 0x1f; + buf[3] = val; + break; + + case RELOC_WDISP22: + val = (val >>= 2) + 1; + /* FALLTHROUGH */ + case RELOC_BASE22: + buf[1] |= (val >> 16) & 0x3f; + buf[2] = val >> 8; + buf[3] = val; + break; + + case RELOC_JUMPTARG: /* 00XX00XX pattern in a word */ + if (!fixP->fx_done) + { + /* The linker tries to support both AMD and old GNU style + R_IREL relocs. That means that if the addend is exactly + the negative of the address within the section, the + linker will not handle it correctly. */ + if (fixP->fx_pcrel + && val != 0 + && val == - (fixP->fx_frag->fr_address + fixP->fx_where)) + as_bad_where + (fixP->fx_file, fixP->fx_line, + "the linker will not handle this relocation correctly"); + } + else if (fixP->fx_pcrel) + { + long v = val >> 17; + if (v != 0 && v != -1) + as_bad_where (fixP->fx_file, fixP->fx_line, + "call/jmp target out of range"); + } + else + /* this case was supposed to be handled in machine_ip */ + abort (); + buf[1] = val >> 10; /* Holds bits 0003FFFC of address */ + buf[3] = val >> 2; + break; + + case RELOC_CONST: /* 00XX00XX pattern in a word */ + buf[1] = val >> 8; /* Holds bits 0000XXXX */ + buf[3] = val; + break; + + case RELOC_CONSTH: /* 00XX00XX pattern in a word */ + buf[1] = val >> 24; /* Holds bits XXXX0000 */ + buf[3] = val >> 16; + break; + + case NO_RELOC: + default: + as_bad (_("bad relocation type: 0x%02x"), fixP->fx_r_type); + break; + } +} + +#ifdef OBJ_COFF +short +tc_coff_fix2rtype (fixP) + fixS *fixP; +{ + + switch (fixP->fx_r_type) + { + case RELOC_32: + return (R_WORD); + case RELOC_8: + return (R_BYTE); + case RELOC_CONST: + return (R_ILOHALF); + case RELOC_CONSTH: + return (R_IHIHALF); + case RELOC_JUMPTARG: + return (R_IREL); + default: + printf (_("need %o3\n"), fixP->fx_r_type); + abort (); + } /* switch on type */ + + return (0); +} + +#endif /* OBJ_COFF */ + +/* should never be called for 29k */ +void +md_convert_frag (headers, seg, fragP) + object_headers *headers; + segT seg; + register fragS *fragP; +{ + as_fatal (_("a29k_convert_frag\n")); +} + +/* should never be called for a29k */ +int +md_estimate_size_before_relax (fragP, segtype) + register fragS *fragP; + segT segtype; +{ + as_fatal (_("a29k_estimate_size_before_relax\n")); + return 0; +} + +#if 0 +/* for debugging only */ +static void +print_insn (insn) + struct machine_it *insn; +{ + char *Reloc[] = + { + "RELOC_8", + "RELOC_16", + "RELOC_32", + "RELOC_DISP8", + "RELOC_DISP16", + "RELOC_DISP32", + "RELOC_WDISP30", + "RELOC_WDISP22", + "RELOC_HI22", + "RELOC_22", + "RELOC_13", + "RELOC_LO10", + "RELOC_SFA_BASE", + "RELOC_SFA_OFF13", + "RELOC_BASE10", + "RELOC_BASE13", + "RELOC_BASE22", + "RELOC_PC10", + "RELOC_PC22", + "RELOC_JMP_TBL", + "RELOC_SEGOFF16", + "RELOC_GLOB_DAT", + "RELOC_JMP_SLOT", + "RELOC_RELATIVE", + "NO_RELOC" + }; + + if (insn->error) + { + fprintf (stderr, "ERROR: %s\n"); + } + fprintf (stderr, "opcode=0x%08x\n", insn->opcode); + fprintf (stderr, "reloc = %s\n", Reloc[insn->reloc]); + fprintf (stderr, "exp = {\n"); + fprintf (stderr, "\t\tX_add_symbol = %s\n", + insn->exp.X_add_symbol ? + (S_GET_NAME (insn->exp.X_add_symbol) ? + S_GET_NAME (insn->exp.X_add_symbol) : "???") : "0"); + fprintf (stderr, "\t\tX_op_symbol = %s\n", + insn->exp.X_op_symbol ? + (S_GET_NAME (insn->exp.X_op_symbol) ? + S_GET_NAME (insn->exp.X_op_symbol) : "???") : "0"); + fprintf (stderr, "\t\tX_add_number = %d\n", + insn->exp.X_add_number); + fprintf (stderr, "}\n"); +} + +#endif + +/* Translate internal representation of relocation info to target format. + + On sparc/29k: first 4 bytes are normal unsigned long address, next three + bytes are index, most sig. byte first. Byte 7 is broken up with + bit 7 as external, bits 6 & 5 unused, and the lower + five bits as relocation type. Next 4 bytes are long addend. */ +/* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */ + +#ifdef OBJ_AOUT + +void +tc_aout_fix_to_chars (where, fixP, segment_address_in_file) + char *where; + fixS *fixP; + relax_addressT segment_address_in_file; +{ + long r_symbolnum; + + know (fixP->fx_r_type < NO_RELOC); + know (fixP->fx_addsy != NULL); + + md_number_to_chars (where, + fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, + 4); + + r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy) + ? S_GET_TYPE (fixP->fx_addsy) + : fixP->fx_addsy->sy_number); + + where[4] = (r_symbolnum >> 16) & 0x0ff; + where[5] = (r_symbolnum >> 8) & 0x0ff; + where[6] = r_symbolnum & 0x0ff; + where[7] = (((!S_IS_DEFINED (fixP->fx_addsy)) << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F); + /* Also easy */ + md_number_to_chars (&where[8], fixP->fx_addnumber, 4); +} + +#endif /* OBJ_AOUT */ + +CONST char *md_shortopts = ""; +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; +{ + return 0; +} + +void +md_show_usage (stream) + FILE *stream; +{ +} + +/* This is called when a line is unrecognized. This is used to handle + definitions of a29k style local labels. */ + +int +a29k_unrecognized_line (c) + int c; +{ + int lab; + char *s; + + if (c != '$' + || ! isdigit ((unsigned char) input_line_pointer[0])) + return 0; + + s = input_line_pointer; + + lab = 0; + while (isdigit ((unsigned char) *s)) + { + lab = lab * 10 + *s - '0'; + ++s; + } + + if (*s != ':') + { + /* Not a label definition. */ + return 0; + } + + if (dollar_label_defined (lab)) + { + as_bad (_("label \"$%d\" redefined"), lab); + return 0; + } + + define_dollar_label (lab); + colon (dollar_label_name (lab, 0)); + input_line_pointer = s + 1; + + return 1; +} + +/* Default the values of symbols known that should be "predefined". We + don't bother to predefine them unless you actually use one, since there + are a lot of them. */ + +symbolS * +md_undefined_symbol (name) + char *name; +{ + long regnum; + char testbuf[5 + /*SLOP*/ 5]; + + if (name[0] == 'g' || name[0] == 'G' + || name[0] == 'l' || name[0] == 'L' + || name[0] == 's' || name[0] == 'S') + { + /* Perhaps a global or local register name */ + if (name[1] == 'r' || name[1] == 'R') + { + long maxreg; + + /* Parse the number, make sure it has no extra zeroes or + trailing chars. */ + regnum = atol (&name[2]); + + if (name[0] == 's' || name[0] == 'S') + maxreg = 255; + else + maxreg = 127; + if (regnum > maxreg) + return NULL; + + sprintf (testbuf, "%ld", regnum); + if (strcmp (testbuf, &name[2]) != 0) + return NULL; /* gr007 or lr7foo or whatever */ + + /* We have a wiener! Define and return a new symbol for it. */ + if (name[0] == 'l' || name[0] == 'L') + regnum += 128; + else if (name[0] == 's' || name[0] == 'S') + regnum += SREG; + return (symbol_new (name, SEG_REGISTER, (valueT) regnum, + &zero_address_frag)); + } + } + + return NULL; +} + +/* Parse an operand that is machine-specific. */ + +void +md_operand (expressionP) + expressionS *expressionP; +{ + + if (input_line_pointer[0] == '%' && input_line_pointer[1] == '%') + { + /* We have a numeric register expression. No biggy. */ + input_line_pointer += 2; /* Skip %% */ + (void) expression (expressionP); + if (expressionP->X_op != O_constant + || expressionP->X_add_number > 255) + as_bad (_("Invalid expression after %%%%\n")); + expressionP->X_op = O_register; + } + else if (input_line_pointer[0] == '&') + { + /* We are taking the 'address' of a register...this one is not + in the manual, but it *is* in traps/fpsymbol.h! What they + seem to want is the register number, as an absolute number. */ + input_line_pointer++; /* Skip & */ + (void) expression (expressionP); + if (expressionP->X_op != O_register) + as_bad (_("Invalid register in & expression")); + else + expressionP->X_op = O_constant; + } + else if (input_line_pointer[0] == '$' + && isdigit ((unsigned char) input_line_pointer[1])) + { + long lab; + char *name; + symbolS *sym; + + /* This is a local label. */ + ++input_line_pointer; + lab = (long) get_absolute_expression (); + if (dollar_label_defined (lab)) + { + name = dollar_label_name (lab, 0); + sym = symbol_find (name); + } + else + { + name = dollar_label_name (lab, 1); + sym = symbol_find_or_make (name); + } + + expressionP->X_op = O_symbol; + expressionP->X_add_symbol = sym; + expressionP->X_add_number = 0; + } + else if (input_line_pointer[0] == '$') + { + char *s; + char type; + int fieldnum, fieldlimit; + LITTLENUM_TYPE floatbuf[8]; + + /* $float(), $doubleN(), or $extendN() convert floating values + to integers. */ + + s = input_line_pointer; + + ++s; + + fieldnum = 0; + if (strncmp (s, "double", sizeof "double" - 1) == 0) + { + s += sizeof "double" - 1; + type = 'd'; + fieldlimit = 2; + } + else if (strncmp (s, "float", sizeof "float" - 1) == 0) + { + s += sizeof "float" - 1; + type = 'f'; + fieldlimit = 1; + } + else if (strncmp (s, "extend", sizeof "extend" - 1) == 0) + { + s += sizeof "extend" - 1; + type = 'x'; + fieldlimit = 4; + } + else + { + return; + } + + if (isdigit (*s)) + { + fieldnum = *s - '0'; + ++s; + } + if (fieldnum >= fieldlimit) + return; + + SKIP_WHITESPACE (); + if (*s != '(') + return; + ++s; + SKIP_WHITESPACE (); + + s = atof_ieee (s, type, floatbuf); + if (s == NULL) + return; + s = s; + + SKIP_WHITESPACE (); + if (*s != ')') + return; + ++s; + SKIP_WHITESPACE (); + + input_line_pointer = s; + expressionP->X_op = O_constant; + expressionP->X_unsigned = 1; + expressionP->X_add_number = ((floatbuf[fieldnum * 2] + << LITTLENUM_NUMBER_OF_BITS) + + floatbuf[fieldnum * 2 + 1]); + } +} + +/* Round up a section size to the appropriate boundary. */ +valueT +md_section_align (segment, size) + segT segment; + valueT size; +{ + return size; /* Byte alignment is fine */ +} + +/* Exactly what point is a PC-relative offset relative TO? + On the 29000, they're relative to the address of the instruction, + which we have set up as the address of the fixup too. */ +long +md_pcrel_from (fixP) + fixS *fixP; +{ + return fixP->fx_where + fixP->fx_frag->fr_address; +} + +/* end of tc-a29k.c */ diff --git a/gas/config/tc-a29k.h b/gas/config/tc-a29k.h new file mode 100644 index 0000000000..b60f605825 --- /dev/null +++ b/gas/config/tc-a29k.h @@ -0,0 +1,54 @@ +/* tc-a29k.h -- Assemble for the AMD 29000. + Copyright (C) 1989, 90, 91, 92, 93, 95, 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. */ + +#define TC_A29K + +#define TARGET_BYTES_BIG_ENDIAN 1 + +#define WORKING_DOT_WORD + +#define LEX_DOLLAR 1 + +#define tc_unrecognized_line(c) a29k_unrecognized_line (c) +extern int a29k_unrecognized_line PARAMS ((int)); + +#define tc_headers_hook(a) ; /* not used */ +#define tc_headers_hook(a) ; /* not used */ +#define tc_crawl_symbol_chain(a) ; /* not used */ +#define tc_coff_symbol_emit_hook(a) ; /* not used */ + +#define AOUT_MACHTYPE 101 +#define TC_COFF_FIX2RTYPE(fix_ptr) tc_coff_fix2rtype(fix_ptr) +#define BFD_ARCH bfd_arch_a29k +#define COFF_MAGIC SIPFBOMAGIC +/* Should the reloc be output ? + on the 29k, this is true only if there is a symbol attatched. + on the h8, this is allways true, since no fixup is done +*/ +#define TC_COUNT_RELOC(x) (x->fx_addsy) +#define TC_CONS_RELOC RELOC_32 + +#define COFF_FLAGS F_AR32W +#define reloc_type int +#define NEED_FX_R_TYPE + +#define ZERO_BASED_SEGMENTS + +/* end of tc-a29k.h */ diff --git a/gas/config/tc-alpha.c b/gas/config/tc-alpha.c new file mode 100644 index 0000000000..568617f74e --- /dev/null +++ b/gas/config/tc-alpha.c @@ -0,0 +1,4762 @@ +/* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU. + Copyright (C) 1989, 93-98, 1999 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 "ecoff.h" + +#include "opcode/alpha.h" + +#ifdef OBJ_ELF +#include "elf/alpha.h" +#endif + +#include + + +/* Local types */ + +#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]; +}; + +enum alpha_macro_arg +{ + MACRO_EOA = 1, MACRO_IR, MACRO_PIR, 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]; +}; + +/* Two extra symbols we want to see in our input. This is a blatent + misuse of the expressionS.X_op field. */ + +#define O_pregister (O_max+1) /* O_register, but in parentheses */ +#define O_cpregister (O_pregister+1) /* + a leading comma */ + +/* 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 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 *)); +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 int 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_coff_wrapper 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 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 = ""; + +/* 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; +static segT alpha_lit4_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; +static symbolS *alpha_lit4_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_lit4_literal; +static offsetT alpha_lit8_literal; +#endif + +/* The active .ent symbol. */ +#ifdef OBJ_ELF +static symbolS *alpha_cur_ent_sym; +#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 + +/* 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) }, + + { "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 }, + + { "all", AXP_OPCODE_BASE }, + { 0 } +}; + +/* The macro table */ + +static const struct alpha_macro alpha_macros[] = { +/* Load/Store macros */ + { "lda", emit_lda, NULL, + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "ldah", emit_ldah, NULL, + { MACRO_IR, MACRO_EXP, MACRO_EOA } }, + + { "ldl", emit_ir_load, "ldl", + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "ldl_l", emit_ir_load, "ldl_l", + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "ldq", emit_ir_load, "ldq", + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "ldq_l", emit_ir_load, "ldq_l", + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "ldq_u", emit_ir_load, "ldq_u", + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "ldf", emit_loadstore, "ldf", + { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_FPR, MACRO_EXP, MACRO_EOA } }, + { "ldg", emit_loadstore, "ldg", + { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_FPR, MACRO_EXP, MACRO_EOA } }, + { "lds", emit_loadstore, "lds", + { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_FPR, MACRO_EXP, MACRO_EOA } }, + { "ldt", emit_loadstore, "ldt", + { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_FPR, MACRO_EXP, MACRO_EOA } }, + + { "ldb", emit_ldX, (PTR)0, + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "ldbu", emit_ldXu, (PTR)0, + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "ldw", emit_ldX, (PTR)1, + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "ldwu", emit_ldXu, (PTR)1, + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + + { "uldw", emit_uldX, (PTR)1, + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "uldwu", emit_uldXu, (PTR)1, + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "uldl", emit_uldX, (PTR)2, + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "uldlu", emit_uldXu, (PTR)2, + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "uldq", emit_uldXu, (PTR)3, + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, 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_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "stl_c", emit_loadstore, "stl_c", + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "stq", emit_loadstore, "stq", + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "stq_c", emit_loadstore, "stq_c", + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "stq_u", emit_loadstore, "stq_u", + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "stf", emit_loadstore, "stf", + { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_FPR, MACRO_EXP, MACRO_EOA } }, + { "stg", emit_loadstore, "stg", + { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_FPR, MACRO_EXP, MACRO_EOA } }, + { "sts", emit_loadstore, "sts", + { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_FPR, MACRO_EXP, MACRO_EOA } }, + { "stt", emit_loadstore, "stt", + { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_FPR, MACRO_EXP, MACRO_EOA } }, + + { "stb", emit_stX, (PTR)0, + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "stw", emit_stX, (PTR)1, + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "ustw", emit_ustX, (PTR)1, + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "ustl", emit_ustX, (PTR)2, + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, MACRO_EOA } }, + { "ustq", emit_ustX, (PTR)3, + { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA, + MACRO_IR, MACRO_EXP, 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 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; + + /* 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 ("", 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 */ + + 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, opnamelen, trunclen; + + /* split off the opcode */ + opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/468"); + 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) + { + 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 | -mall\n\ + specify variant of Alpha architecture\n\ +-m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264\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_ALPHA_GPDISP: + case BFD_RELOC_ALPHA_GPDISP_HI16: + case BFD_RELOC_ALPHA_GPDISP_LO16: + return addr; + default: + return fixP->fx_size + 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. */ + +int +md_apply_fix (fixP, valueP) + fixS *fixP; + valueT *valueP; +{ + char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where; + valueT value = *valueP; + unsigned image, size; + + switch (fixP->fx_r_type) + { + /* The GPDISP relocations are processed internally with a symbol + referring to the current function; 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; + assert (next->fx_r_type == BFD_RELOC_ALPHA_GPDISP_LO16); + + 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 (absolute_section); + 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 1; + +#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; +#endif +#ifdef OBJ_ELF + case BFD_RELOC_GPREL32: + return 1; +#endif + + 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 1; + + 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 1; + +#ifdef OBJ_ECOFF + case BFD_RELOC_ALPHA_LITERAL: + md_number_to_chars (fixpos, value, 2); + return 1; + + case BFD_RELOC_ALPHA_LITUSE: + return 1; +#endif +#ifdef OBJ_ELF + case BFD_RELOC_ALPHA_ELF_LITERAL: + case BFD_RELOC_ALPHA_LITUSE: + return 1; +#endif +#ifdef OBJ_EVAX + case BFD_RELOC_ALPHA_LINKAGE: + case BFD_RELOC_ALPHA_CODEADDR: + return 1; +#endif + + 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 < 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 + && fixP->fx_addsy->bsym->section != 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 1; + 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; + return 0; +} + +/* + * 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 == 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 a 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: +#ifdef OBJ_ECOFF + case BFD_RELOC_ALPHA_LITERAL: +#endif +#ifdef OBJ_ELF + case BFD_RELOC_ALPHA_ELF_LITERAL: +#endif + case BFD_RELOC_ALPHA_LITUSE: + case BFD_RELOC_GPREL32: +#ifdef OBJ_EVAX + case BFD_RELOC_ALPHA_LINKAGE: + case BFD_RELOC_ALPHA_CODEADDR: +#endif + return 1; + + case BFD_RELOC_23_PCREL_S2: + case BFD_RELOC_32: + case BFD_RELOC_64: + case BFD_RELOC_ALPHA_HINT: + return 0; + + default: + assert((int)f->fx_r_type < 0 && -(int)f->fx_r_type < alpha_num_operands); + return 0; + } +} + +/* Return true if we can partially resolve a relocation now. */ + +int +alpha_fix_adjustable (f) + fixS *f; +{ +#ifdef OBJ_ELF + /* Prevent all adjustments to global symbols */ + if (S_IS_EXTERN (f->fx_addsy) || S_IS_WEAK (f->fx_addsy)) + return 0; +#endif + + /* 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; + +#ifdef OBJ_ECOFF + case BFD_RELOC_ALPHA_LITERAL: +#endif +#ifdef OBJ_ELF + case BFD_RELOC_ALPHA_ELF_LITERAL: +#endif +#ifdef OBJ_EVAX + case BFD_RELOC_ALPHA_LINKAGE: + case BFD_RELOC_ALPHA_CODEADDR: +#endif + return 1; + + case BFD_RELOC_ALPHA_LITUSE: + return 0; + + case BFD_RELOC_GPREL32: + case BFD_RELOC_23_PCREL_S2: + case BFD_RELOC_32: + case BFD_RELOC_64: + case BFD_RELOC_ALPHA_HINT: + return 1; + + default: + assert ((int)f->fx_r_type < 0 + && - (int)f->fx_r_type < alpha_num_operands); + 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; + 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; + + /* 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_IS_COMMON(fixp->fx_addsy)) + reloc->addend -= fixp->fx_addsy->bsym->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; +{ + 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 */ + +/* 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; + + 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; + + while (tok < end_tok && *input_line_pointer) + { + SKIP_WHITESPACE (); + switch (*input_line_pointer) + { + case '\0': + goto fini; + + 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; + return ntok - (end_tok - tok); + +err: + input_line_pointer = old_input_line_pointer; + return -1; +} + +/* 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 < 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; + + 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; + 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; + 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; + 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; + + 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: + goto match_failed; + + default: + break; + } + ++tokidx; + break; + + match_failed: + while (*arg != MACRO_EOA) + ++arg; + tokidx = 0; + break; + } + ++arg; + } + } + while (++macro-alpha_macros < 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) + const struct alpha_opcode *opcode; + const expressionS *tok; + int ntok; + struct alpha_insn *insn; +{ + 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; + + 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 const expressionS zero_exp = { 0, 0, 0, O_constant, 1 }; + t = &zero_exp; + } + 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); + break; + + default: + { + 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 = operand->default_reloc; + } + break; + } + } + + 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); + + /* Apply the fixups in order */ + for (i = 0; i < insn->nfixups; ++i) + { + const struct alpha_operand *operand; + struct alpha_fixup *fixup = &insn->fixups[i]; + 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); + } +#ifdef OBJ_ELF + /* These relocation types are only used internally. */ + else if (fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16 + || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16) + { + size = 2, pcrel = 0; + } +#endif + else + { + reloc_howto_type *reloc_howto + = bfd_reloc_type_lookup (stdoutput, fixup->reloc); + assert (reloc_howto); + + size = bfd_get_reloc_size (reloc_howto); + pcrel = reloc_howto->pc_relative; + } + assert (size >= 1 && size <= 4); + + 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 */ + switch (fixup->reloc) + { + case BFD_RELOC_ALPHA_GPDISP_LO16: +#ifdef OBJ_ECOFF + case BFD_RELOC_ALPHA_LITERAL: +#endif +#ifdef OBJ_ELF + case BFD_RELOC_ALPHA_ELF_LITERAL: +#endif + case BFD_RELOC_GPREL32: + fixP->fx_no_overflow = 1; + break; + + 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); + 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; + + /* search macros */ + 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); + 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 ldX_op[] = { "ldb", "ldw", "ldll", "ldq" }; +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; + const PTR 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; + + /* We're going to need this symbol in md_apply_fix(). */ + (void) section_symbol (absolute_section); + +#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; + + 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; + + 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 = -basesym->sy_obj; + + /* @@ 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. + + Finally, the return value is true if the calling macro may emit a + LITUSE reloc if otherwise appropriate. */ + +static int +load_expression (targreg, exp, pbasereg, poffset) + int targreg; + const expressionS *exp; + int *pbasereg; + expressionS *poffset; +{ + int 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; +#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; +#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 + emit_lituse = 1; + + 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; + + /* 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 + + 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); + if (insn.nfixups > 0) + { + memmove (&insn.fixups[1], &insn.fixups[0], + sizeof(struct alpha_fixup) * insn.nfixups); + } + insn.nfixups++; + insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE; + insn.fixups[0].exp.X_op = O_constant; + insn.fixups[0].exp.X_add_number = 1; + 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, particualrly symbol address loads and + large constants. */ + +static void +emit_lda (tok, ntok, unused) + const expressionS *tok; + int ntok; + const PTR 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; + const PTR 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, 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); + if (insn.nfixups > 0) + { + memmove (&insn.fixups[1], &insn.fixups[0], + sizeof(struct alpha_fixup) * insn.nfixups); + } + insn.nfixups++; + insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE; + insn.fixups[0].exp.X_op = O_constant; + insn.fixups[0].exp.X_add_number = 1; + } + + 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, 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); + if (insn.nfixups > 0) + { + memmove (&insn.fixups[1], &insn.fixups[0], + sizeof(struct alpha_fixup) * insn.nfixups); + } + insn.nfixups++; + insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE; + insn.fixups[0].exp.X_op = O_constant; + insn.fixups[0].exp.X_add_number = 1; + } + + 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]; + + 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 targ, 0($at)" */ + + newtok[0] = tok[0]; + set_tok_const (newtok[1], 0); + set_tok_preg (newtok[2], AXP_REG_AT); + assemble_tokens ("ldq_u", newtok, 3, 1); + + /* emit "extXl targ, $at, targ" */ + + set_tok_reg (newtok[1], AXP_REG_AT); + newtok[2] = newtok[0]; + assemble_tokens (extXl_op[(long)vlgsize], newtok, 3, 1); + } +} + +/* 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< */ +#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); + + /* add the LITUSE fixup */ + if (lituse) + { + assert (insn.nfixups < MAX_INSN_FIXUPS); + if (insn.nfixups > 0) + { + memmove (&insn.fixups[1], &insn.fixups[0], + sizeof(struct alpha_fixup) * insn.nfixups); + } + insn.nfixups++; + insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE; + insn.fixups[0].exp.X_op = O_constant; + insn.fixups[0].exp.X_add_number = 3; + } + + 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; + +{ + s_text (i); + 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; +{ + s_data (i); + 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; +{ + 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)) + symbolP->bsym->section = 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 (symbolP->sy_frag == &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; +{ + 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; +{ + 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 + +/* 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; +{ + 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; +{ + 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 (alpha_cur_ent_sym) + as_warn (_("nested .ent directives")); + + sym = symbol_find_or_make (name); + sym->bsym->flags |= BSF_FUNCTION; + alpha_cur_ent_sym = sym; + + /* 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; +{ + 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 (sym != alpha_cur_ent_sym) + as_warn (_(".end directive names different symbol than .ent")); + + /* Create an expression to calculate the size of the function. */ + if (sym) + { + sym->sy_obj.size = (expressionS *) xmalloc (sizeof (expressionS)); + sym->sy_obj.size->X_op = O_subtract; + sym->sy_obj.size->X_add_symbol + = symbol_new ("L0\001", now_seg, frag_now_fix (), frag_now); + sym->sy_obj.size->X_op_symbol = sym; + sym->sy_obj.size->X_add_number = 0; + } + + alpha_cur_ent_sym = 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 + discard_rest_of_line (); +} + +static void +s_alpha_frame (dummy) + int dummy; +{ + if (ECOFF_DEBUGGING) + ecoff_directive_frame (0); + else + discard_rest_of_line (); +} + +static void +s_alpha_prologue (ignore) + int ignore; +{ + symbolS *sym; + int arg; + + arg = get_absolute_expression (); + demand_empty_rest_of_line (); + + if (ECOFF_DEBUGGING) + sym = ecoff_get_cur_proc_sym (); + else + sym = alpha_cur_ent_sym; + know (sym != NULL); + + switch (arg) + { + case 0: /* No PV required. */ + S_SET_OTHER (sym, STO_ALPHA_NOPV); + break; + case 1: /* Std GP load. */ + S_SET_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; + } +} + +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_file, + ecoff_directive_scl, + ecoff_directive_tag, + ecoff_directive_val, + ecoff_directive_loc, + }; + + assert (which >= 0 && which < sizeof(fns)/sizeof(*fns)); + + if (ECOFF_DEBUGGING) + (*fns[which])(0); + else + { + as_bad (_("ECOFF debugging is disabled.")); + ignore_rest_of_line (); + } +} +#endif /* OBJ_ELF */ + +#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; +{ + 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->bsym->flags |= BSF_FUNCTION; + alpha_evax_proc.symbol = symbol; + + demand_empty_rest_of_line (); + return; +} + + +/* Parse .frame ,,RA, directives. */ + +static void +s_alpha_frame (ignore) + int ignore; +{ + 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 (); + + return; +} + +static void +s_alpha_pdesc (ignore) + int ignore; +{ + 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; + } + + alpha_evax_proc.symbol->sy_obj = (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. */ + alpha_evax_proc.symbol->bsym->udata.p = (PTR)entry_sym->bsym; + + SKIP_WHITESPACE (); + if (*input_line_pointer++ != ',') + { + as_warn (_("No comma after .pdesc ")); + 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); + + return; +} + + +/* Support for crash debug on vms. */ + +static void +s_alpha_name (ignore) + int ignore; +{ + 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); + + return; +} + + +static void +s_alpha_linkage (ignore) + int ignore; +{ + 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 (); + + return; +} + + +static void +s_alpha_code_address (ignore) + int ignore; +{ + 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 (); + + return; +} + + +static void +s_alpha_fp_save (ignore) + int ignore; +{ + + alpha_evax_proc.fp_save = tc_get_register (1); + + demand_empty_rest_of_line (); + return; +} + + +static void +s_alpha_mask (ignore) + int ignore; +{ + 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 (); + + return; +} + + +static void +s_alpha_fmask (ignore) + int ignore; +{ + 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 (); + + return; +} + +static void +s_alpha_end (ignore) + int ignore; +{ + char c; + + c = get_symbol_end (); + *input_line_pointer = c; + demand_empty_rest_of_line (); + alpha_evax_proc.symbol = 0; + + return; +} + + +static void +s_alpha_file (ignore) + int ignore; +{ + symbolS *s; + int length; + static char case_hack[32]; + + extern char *demand_copy_string PARAMS ((int *lenP)); + + sprintf (case_hack, "", + alpha_flag_hash_long_names, alpha_flag_show_after_trunc); + + s = symbol_find_or_make (case_hack); + s->bsym->flags |= BSF_FILE; + + get_absolute_expression (); + s = symbol_find_or_make (demand_copy_string (&length)); + s->bsym->flags |= BSF_FILE; + demand_empty_rest_of_line (); + + return; +} +#endif /* OBJ_EVAX */ + +/* Handle the .gprel32 pseudo op. */ + +static void +s_alpha_gprel32 (ignore) + int ignore; +{ + 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; +{ + 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 (); + } + /* symbolP->sy_other = (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; +{ + 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; +{ +#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; +{ + 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; +{ + 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; + } + return; +} +#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}, + /* 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}, + {"file", s_alpha_coff_wrapper, 5}, + {"scl", s_alpha_coff_wrapper, 6}, + {"tag", s_alpha_coff_wrapper, 7}, + {"val", s_alpha_coff_wrapper, 8}, + {"loc", s_alpha_coff_wrapper, 9}, +#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 (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 */ + +/* 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; +{ + if (alpha_current_align >= n) + return; + + if (pfill == NULL) + { + if (n > 2 + && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0) + { + static char const unop[4] = { 0x00, 0x00, 0xe0, 0x2f }; + static char const nopunop[8] = { + 0x1f, 0x04, 0xff, 0x47, + 0x00, 0x00, 0xe0, 0x2f + }; + + /* First, make sure we're on a four-byte boundary, in case + someone has been putting .byte values into the text + section. The DEC assembler silently fills with unaligned + no-op instructions. This will zero-fill, then nop-fill + with proper alignment. */ + if (alpha_current_align < 2) + frag_align (2, 0, 0); + if (alpha_current_align < 3) + frag_align_pattern (3, unop, sizeof unop, 0); + if (n > 3) + frag_align_pattern (n, nopunop, sizeof nopunop, 0); + } + else + frag_align (n, 0, 0); + } + else + frag_align (n, *pfill, 0); + + alpha_current_align = n; + + if (label != NULL) + { + assert (S_GET_SEGMENT (label) == now_seg); + label->sy_frag = 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. */ +} + +/* 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/gas/config/tc-alpha.h b/gas/config/tc-alpha.h new file mode 100644 index 0000000000..ca6903a70a --- /dev/null +++ b/gas/config/tc-alpha.h @@ -0,0 +1,104 @@ +/* This file is tc-alpha.h + Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. + Written by Ken Raeburn . + + 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 + +#define TARGET_FORMAT (OUTPUT_FLAVOR == bfd_target_ecoff_flavour \ + ? "ecoff-littlealpha" \ + : OUTPUT_FLAVOR == bfd_target_elf_flavour \ + ? "elf64-alpha" \ + : OUTPUT_FLAVOR == bfd_target_evax_flavour \ + ? "vms-alpha" \ + : "unknown-format") + +#define NEED_LITERAL_POOL +#define TC_HANDLES_FX_DONE +#define REPEAT_CONS_EXPRESSIONS + +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(FIXP) alpha_force_relocation (FIXP) +#define tc_fix_adjustable(FIXP) alpha_fix_adjustable (FIXP) +#define RELOC_REQUIRES_SYMBOL + +/* 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. */ + +#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ + ((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_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 + +#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 ((struct symbol *)); + +#define md_cons_align(nbytes) alpha_cons_align (nbytes) +extern void alpha_cons_align PARAMS ((int)); + +#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 ELF_TC_SPECIAL_SECTIONS \ + { ".sdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL }, \ + { ".sbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL }, +#endif diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c new file mode 100644 index 0000000000..c07c2d791a --- /dev/null +++ b/gas/config/tc-arc.c @@ -0,0 +1,1481 @@ +/* tc-arc.c -- Assembler for the ARC + Copyright (C) 1994, 1995, 1997, 1998 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 +#include +#include "as.h" +#include "subsegs.h" +#include "opcode/arc.h" +#include "elf/arc.h" + +extern int arc_get_mach PARAMS ((char *)); + +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_cpu PARAMS ((int)); +/*static void arc_rename PARAMS ((int));*/ +static int get_arc_exp_reloc_type PARAMS ((int, int, expressionS *, + expressionS *)); + +const pseudo_typeS md_pseudo_table[] = +{ + { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0) */ + { "common", arc_common, 0 }, +/*{ "hword", cons, 2 }, - already exists */ + { "word", cons, 4 }, +/*{ "xword", cons, 8 },*/ + { "cpu", arc_cpu, 0 }, +/*{ "rename", arc_rename, 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; + +/* One of bfd_mach_arc_xxx. */ +static int arc_mach_type = bfd_mach_arc_base; + +/* 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 .cpu 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}, + { NULL, no_argument, NULL, 0 } +}; +size_t md_longopts_size = sizeof (md_longopts); + +/* + * md_parse_option + * + * 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; +{ + switch (c) + { + 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\ +-EB generate big endian output\n\ +-EL generate little endian output\n")); +} + +/* 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 defered until later because we might see a .cpu + 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")); + + /* Assume the base cpu. 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 (bfd_mach_arc_base, + 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; +{ + register unsigned 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 (! arc_opval_supported (&arc_suffixes[i])) + continue; + 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 index in `arc_reg_names'. */ + for (i = 0; i < arc_reg_names_count; i++) + { + if (! arc_opval_supported (&arc_reg_names[i])) + 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, + i, &zero_address_frag)); + } + + /* Tell `s_cpu' 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; + char *start; + arc_insn insn; + static int init_tables_p = 0; + + /* Opcode table initialization is deferred until here because we have to + wait for a possible .cpu 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. */ + + opcode = arc_opcode_lookup_asm (str); + + /* Keep looking until we find a match. */ + + start = str; + for ( ; opcode != NULL; opcode = ARC_OPCODE_NEXT_ASM (opcode)) + { + int past_opcode_p, fc, num_suffixes; + 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; + 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; + + /* 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[*syn]].flags)) + { + mods |= arc_operands[arc_operand_map[*syn]].flags & ARC_MOD_BITS; + ++syn; + } + operand = arc_operands + arc_operand_map[*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 we get an error, go on to try the next insn. */ + if (errmsg) + break; + } + ++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,*suffix_end; + + 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 && isalpha (*t); ++t) + continue; + c = *t; + *t = '\0'; + suf = hash_find (arc_suffix_hash, s); + *t = c; + 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. */ + 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; + 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 c; + 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 (*str == '\0') + break; +#if 0 + /* Is this a syntax character? Eg: is there a '[' present when + there shouldn't be? */ + if (!isalnum (*str) + /* '.' as in ".LLC0" */ + && *str != '.' + /* '_' as in "_print" */ + && *str != '_' + /* '-' as in "[fp,-4]" */ + && *str != '-' + /* '%' as in "%ia(_func)" */ + && *str != '%') + break; +#endif + + /* 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 = arc_reg_names + exp.X_add_number; + } + else + { + /* We need to generate a fixup for this expression. */ + if (fc >= MAX_FIXUPS) + as_fatal (_("too many fixups")); + fixups[fc].exp = exp; + + /* If this is a register constant (IE: one whose + register value gets stored as 61-63) then this + must be a limm. We don't support shimm relocs. */ + /* ??? This bit could use some cleaning up. + Referencing the format chars like this goes + against style. */ +#define IS_REG_OPERAND(o) ((o) == 'a' || (o) == 'b' || (o) == 'c') + if (IS_REG_OPERAND (*syn)) + { + const char *junk; + + fixups[fc].opindex = arc_operand_map['L']; + limm_reloc_p = 1; + /* 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[*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 0 + if (errmsg != (const char *) NULL) + as_warn (errmsg); +#endif + /* FIXME: We want to try shimm insns for limm ones. But if + the constant won't fit, we must go on to try the next + possibility. Where do we issue warnings for constants + that are too big then? At present, we'll flag the insn + as unrecognizable! Maybe have the "bad instruction" + error message include our `errmsg'? */ + if (errmsg != (const char *) NULL) + 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 (*str != '\0') + 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; + int need_cc_nop_p = 0; + + 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) + 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) + as_warn (_("conditional branch follows set of flags")); + prev_insn_needs_cc_nop_p = 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); + } + 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); + } + + /* 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_fix. + + 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) + { + op_type = fixups[i].opindex; + /* FIXME: can we add this data to the operand table? */ + if (op_type == arc_operand_map['L']) + 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. */ + } + + as_bad (_("bad instruction `%s'"), start); +} + +/* ??? This was copied from tc-sparc.c, I think. Is it necessary? */ + +static void +arc_common (ignore) + int ignore; +{ + char *name; + char c; + char *p; + int 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; + } + input_line_pointer++; /* skip ',' */ + if ((temp = get_absolute_expression ()) < 0) + { + 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) + { + as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."), + S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size); + } + } + assert (symbolP->sy_frag == &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 (); + if (temp < 0) + { + temp = 0; + as_warn (_("Common alignment negative; 0 assumed")); + } + if (symbolP->local) + { + segT old_sec; + int old_subsec; + char *p; + int align; + + allocate_bss: + old_sec = now_seg; + old_subsec = now_subseg; + align = temp; + record_alignment (bss_section, align); + subseg_set (bss_section, 0); + if (align) + frag_align (align, 0, 0); + if (S_GET_SEGMENT (symbolP) == bss_section) + symbolP->sy_frag->fr_symbol = 0; + symbolP->sy_frag = 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); + subseg_set (old_sec, old_subsec); + } + else + { + allocate_common: + S_SET_VALUE (symbolP, (valueT) size); + S_SET_ALIGN (symbolP, temp); + S_SET_EXTERNAL (symbolP); + S_SET_SEGMENT (symbolP, bfd_com_section_ptr); + } + } + else + { + input_line_pointer++; + /* ??? Some say data, some say bss. */ + if (strncmp (input_line_pointer, ".bss\"", 5) + && strncmp (input_line_pointer, ".data\"", 6)) + { + input_line_pointer--; + goto bad_common_segment; + } + while (*input_line_pointer++ != '"') + ; + goto allocate_common; + } + 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; + } +} + +/* Select the cpu we're assembling for. */ + +static void +arc_cpu (ignore) + int ignore; +{ + int mach; + char c; + char *cpu; + + /* If an instruction has already been seen, it's too late. */ + if (cpu_tables_init_p) + { + as_bad (_(".cpu command must appear before any instructions")); + ignore_rest_of_line (); + return; + } + + cpu = input_line_pointer; + c = get_symbol_end (); + mach = arc_get_mach (cpu); + *input_line_pointer = c; + if (mach == -1) + goto bad_cpu; + + demand_empty_rest_of_line (); + + /* The cpu may have been selected on the command line. + The choices must match. */ + /* ??? This was a command line option early on. It's gone now, but + leave this in. */ + if (mach_type_specified_p && mach != arc_mach_type) + as_bad (_(".cpu conflicts with previous value")); + else + { + arc_mach_type = mach; + mach_type_specified_p = 1; + if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach)) + as_warn (_("could not set architecture and machine")); + } + return; + + bad_cpu: + as_bad (_("bad .cpu op")); + ignore_rest_of_line (); +} + +#if 0 +/* The .rename pseudo-op. This is used by gcc to implement + -mmangle-cpu-libgcc. */ + +static void +arc_rename (ignore) + int ignore; +{ + char *name,*new; + char c; + symbolS *sym; + int len; + + name = input_line_pointer; + c = get_symbol_end (); + sym = symbol_find_or_make (name); + *input_line_pointer = c; + + if (*input_line_pointer != ',') + { + as_bad (_("missing rename string")); + ignore_rest_of_line (); + return; + } + ++input_line_pointer; + SKIP_WHITESPACE (); + + name = input_line_pointer; + c = get_symbol_end (); + if (*name == '\0') + { + *input_line_pointer = c; + as_bad (_("invalid symbol to rename to")); + ignore_rest_of_line (); + return; + } + new = (char *) xmalloc (strlen (name) + 1); + strcpy (new, name); + *input_line_pointer = c; + sym->sy_tc.real_name = new; + + demand_empty_rest_of_line (); +} +#endif + +/* 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 prec; + LITTLENUM_TYPE words[MAX_LITTLENUMS]; + LITTLENUM_TYPE *wordP; + char *t; + char *atof_ieee (); + + 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; + asection *seg; +{ + abort (); +} + +/* Convert a machine dependent frag. We never generate these. */ + +void +md_convert_frag (abfd, sec, fragp) + bfd *abfd; + asection *sec; + fragS *fragp; +{ + abort (); +} + +/* 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. Perhaps put a special cookie in X_add_number + to mark the expression as special. */ + +void +md_operand (expressionP) + expressionS *expressionP; +{ + char *p = input_line_pointer; + + if (*p == '%' && strncmp (p, "%st(", 4) == 0) + { + input_line_pointer += 4; + expression (expressionP); + if (*input_line_pointer != ')') + { + as_bad (_("missing ')' in %-op")); + return; + } + ++input_line_pointer; + if (expressionP->X_op == O_symbol + && expressionP->X_add_number == 0 + /* I think this test is unnecessary but just as a sanity check... */ + && expressionP->X_op_symbol == NULL) + { + expressionS two; + + 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); + } + /* 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 for %%st")); + return; + } + } +} + +/* 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; +{ + 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; + int nbytes; +{ + expr (0, exp); +} + +/* 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; +{ + if (fixP->fx_addsy != (symbolS *) NULL + && ! S_IS_DEFINED (fixP->fx_addsy)) + { + /* The symbol is undefined. Let the linker figure it out. */ + return 0; + } + + /* 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. Similarily 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. */ + +int +md_apply_fix3 (fixP, valueP, seg) + fixS *fixP; + valueT *valueP; + segT seg; +{ + /*char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;*/ + valueT value; + + /* FIXME FIXME FIXME: The value we are passed in *valueP 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_perform_relocation, which is also going to use the symbol + value. That means that if the reloc is fully resolved we want to + use *valueP since bfd_perform_relocation is not being used. + However, if the reloc is not fully resolved we do not want to use + *valueP, and must use fx_offset instead. However, if the reloc + is PC relative, we do want to use *valueP since it includes the + result of md_pcrel_from. This is confusing. */ + + if (fixP->fx_addsy == (symbolS *) NULL) + { + value = *valueP; + fixP->fx_done = 1; + } + else if (fixP->fx_pcrel) + { + value = *valueP; + /* ELF relocations are against symbols. + 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 (S_IS_DEFINED (fixP->fx_addsy) + && S_GET_SEGMENT (fixP->fx_addsy) != seg) + value += md_pcrel_from (fixP); + } + 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 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 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 1; + } + + /* 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 (0 && 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 (0 && 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 1; + } + } + 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 (); + } + } + + fixP->fx_addnumber = value; + + return 1; +} + +/* Translate internal representation of relocation info to BFD target + format. */ + +arelent * +tc_gen_reloc (section, fixP) + asection *section; + 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); + + reloc->addend = fixP->fx_addnumber; + + return reloc; +} + +/* Frobbers. */ + +#if 0 +/* Set the real name if the .rename pseudo-op was used. + Return 1 if the symbol should not be included in the symbol table. */ + +int +arc_frob_symbol (sym) + symbolS *sym; +{ + if (sym->sy_tc.real_name != (char *) NULL) + S_SET_NAME (sym, sym->sy_tc.real_name); + + return 0; +} +#endif diff --git a/gas/config/tc-arc.h b/gas/config/tc-arc.h new file mode 100644 index 0000000000..6a95ff4b61 --- /dev/null +++ b/gas/config/tc-arc.h @@ -0,0 +1,71 @@ +/* tc-arc.h - Macros and type defines for the ARC. + Copyright (C) 1994, 1995, 1997 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 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 " + +#define TC_HANDLES_FX_DONE + +#define MD_APPLY_FIX3 + +/* The ARC needs to parse reloc specifiers in .word. */ + +extern void arc_parse_cons_expression (); +#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \ +arc_parse_cons_expression (EXP, NBYTES) + +extern void arc_cons_fix_new (); +#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \ +arc_cons_fix_new (FRAG, WHERE, NBYTES, EXP) + +#if 0 +/* Extra stuff that we need to keep track of for each symbol. */ +struct arc_tc_sy +{ + /* The real name, if the symbol was renamed. */ + char *real_name; +}; + +#define TC_SYMFIELD_TYPE struct arc_tc_sy + +/* Finish up the symbol. */ +extern int arc_frob_symbol PARAMS ((struct symbol *)); +#define tc_frob_symbol(sym, punt) punt = arc_frob_symbol (sym) +#endif diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c new file mode 100644 index 0000000000..d898bf0ecd --- /dev/null +++ b/gas/config/tc-arm.c @@ -0,0 +1,6857 @@ +/* tc-arm.c -- Assemble for the ARM + Copyright (C) 1994, 95, 96, 97, 98, 1999 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. */ + +#include +#include +#define NO_RELOC 0 +#include "as.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" +#endif + +/* Types of processor to assemble for. */ +#define ARM_1 0x00000001 +#define ARM_2 0x00000002 +#define ARM_3 0x00000004 +#define ARM_250 ARM_3 +#define ARM_6 0x00000008 +#define ARM_7 ARM_6 /* same core instruction set */ +#define ARM_8 ARM_6 /* same core instruction set */ +#define ARM_9 ARM_6 /* same core instruction set */ +#define ARM_CPU_MASK 0x0000000f + +/* The following bitmasks control CPU extensions (ARM7 onwards): */ +#define ARM_LONGMUL 0x00000010 /* allow long multiplies */ +#define ARM_HALFWORD 0x00000020 /* allow half word loads */ +#define ARM_THUMB 0x00000040 /* allow BX instruction */ + +#define ARM_ARCHv4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD) + +/* Some useful combinations: */ +#define ARM_ANY 0x00ffffff +#define ARM_2UP 0x00fffffe +#define ARM_ALL ARM_2UP /* Not arm1 only */ +#define ARM_3UP 0x00fffffc +#define ARM_6UP 0x00fffff8 /* Includes ARM7 */ + +#define FPU_CORE 0x80000000 +#define FPU_FPA10 0x40000000 +#define FPU_FPA11 0x40000000 +#define FPU_NONE 0 + +/* Some useful combinations */ +#define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */ +#define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */ + + +#ifndef CPU_DEFAULT +#if defined __thumb__ +#define CPU_DEFAULT (ARM_ARCHv4 | ARM_THUMB) +#else +#define CPU_DEFAULT ARM_ALL +#endif +#endif + +#ifndef FPU_DEFAULT +#define FPU_DEFAULT FPU_ALL +#endif + +#define streq(a,b) (strcmp (a, b) == 0) + +static unsigned long cpu_variant = CPU_DEFAULT | FPU_DEFAULT; +static int target_oabi = 0; + +#if defined OBJ_COFF || defined OBJ_ELF +/* Flags stored in private area of BFD structure */ +static boolean uses_apcs_26 = false; +static boolean support_interwork = false; +static boolean uses_apcs_float = false; +static boolean pic_code = false; +#endif + +/* 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[] = "#"; + +#ifdef TE_LINUX +CONST char line_separator_chars[] = ";"; +#else +CONST char line_separator_chars[] = ""; +#endif + +/* 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[] = "rRsSfFdDxXeEpP"; + +/* Prefix characters that indicate the start of an immediate + value. */ +#define is_immediate_prefix(C) ((C) == '#' || (C) == '$') + +#ifdef OBJ_ELF +symbolS * GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */ +#endif + +CONST int md_reloc_size = 8; /* Size of relocation record */ + +static int thumb_mode = 0; /* non-zero if assembling thumb instructions */ + +typedef struct arm_fix +{ + int thumb_mode; +} arm_fix_data; + +struct arm_it +{ + CONST char * error; + unsigned long instruction; + int suffix; + int size; + struct + { + bfd_reloc_code_real_type type; + expressionS exp; + int pc_rel; + } reloc; +}; + +struct arm_it inst; + +struct asm_shift +{ + CONST char * template; + unsigned long value; +}; + +static CONST struct asm_shift shift[] = +{ + {"asl", 0}, + {"lsl", 0}, + {"lsr", 0x00000020}, + {"asr", 0x00000040}, + {"ror", 0x00000060}, + {"rrx", 0x00000060}, + {"ASL", 0}, + {"LSL", 0}, + {"LSR", 0x00000020}, + {"ASR", 0x00000040}, + {"ROR", 0x00000060}, + {"RRX", 0x00000060} +}; + +#define NO_SHIFT_RESTRICT 1 +#define SHIFT_RESTRICT 0 + +#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) + +#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 TRANS_BIT (0x00200000) + +struct asm_cond +{ + CONST char * template; + unsigned long value; +}; + +/* This is to save a hash look-up in the common case */ +#define COND_ALWAYS 0xe0000000 + +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} +}; + +/* Warning: If the top bit of the set_bits is set, then the standard + instruction bitmask is ignored, and the new bitmask is taken from + the set_bits: */ +struct asm_flg +{ + CONST char * template; /* Basic flag string */ + unsigned long set_bits; /* Bits to set */ +}; + +static CONST struct asm_flg s_flag[] = +{ + {"s", CONDS_BIT}, + {NULL, 0} +}; + +static CONST struct asm_flg ldr_flags[] = +{ + {"b", 0x00400000}, + {"t", TRANS_BIT}, + {"bt", 0x00400000 | TRANS_BIT}, + {"h", 0x801000b0}, + {"sh", 0x801000f0}, + {"sb", 0x801000d0}, + {NULL, 0} +}; + +static CONST struct asm_flg str_flags[] = +{ + {"b", 0x00400000}, + {"t", TRANS_BIT}, + {"bt", 0x00400000 | TRANS_BIT}, + {"h", 0x800000b0}, + {NULL, 0} +}; + +static CONST struct asm_flg byte_flag[] = +{ + {"b", 0x00400000}, + {NULL, 0} +}; + +static CONST struct asm_flg cmp_flags[] = +{ + {"s", CONDS_BIT}, + {"p", 0x0010f000}, + {NULL, 0} +}; + +static CONST struct asm_flg ldm_flags[] = +{ + {"ed", 0x01800000}, + {"fd", 0x00800000}, + {"ea", 0x01000000}, + {"fa", 0x08000000}, + {"ib", 0x01800000}, + {"ia", 0x00800000}, + {"db", 0x01000000}, + {"da", 0x08000000}, + {NULL, 0} +}; + +static CONST struct asm_flg stm_flags[] = +{ + {"ed", 0x08000000}, + {"fd", 0x01000000}, + {"ea", 0x00800000}, + {"fa", 0x01800000}, + {"ib", 0x01800000}, + {"ia", 0x00800000}, + {"db", 0x01000000}, + {"da", 0x08000000}, + {NULL, 0} +}; + +static CONST struct asm_flg lfm_flags[] = +{ + {"fd", 0x00800000}, + {"ea", 0x01000000}, + {NULL, 0} +}; + +static CONST struct asm_flg sfm_flags[] = +{ + {"fd", 0x01000000}, + {"ea", 0x00800000}, + {NULL, 0} +}; + +static CONST struct asm_flg round_flags[] = +{ + {"p", 0x00000020}, + {"m", 0x00000040}, + {"z", 0x00000060}, + {NULL, 0} +}; + +/* 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. */ +static CONST struct asm_flg fix_flags[] = +{ + {"p", 0x00000020}, + {"m", 0x00000040}, + {"z", 0x00000060}, + {"sp", 0x00000020}, + {"sm", 0x00000040}, + {"sz", 0x00000060}, + {"dp", 0x00000020}, + {"dm", 0x00000040}, + {"dz", 0x00000060}, + {"ep", 0x00000020}, + {"em", 0x00000040}, + {"ez", 0x00000060}, + {NULL, 0} +}; + +static CONST struct asm_flg except_flag[] = +{ + {"e", 0x00400000}, + {NULL, 0} +}; + +static CONST struct asm_flg cplong_flag[] = +{ + {"l", 0x00400000}, + {NULL, 0} +}; + +struct asm_psr +{ + CONST char * template; + unsigned long number; +}; + +#define PSR_FIELD_MASK 0x000f0000 + +#define PSR_FLAGS 0x00080000 +#define PSR_CONTROL 0x00010000 /* Undocumented instruction, its use is discouraged by ARM */ +#define PSR_ALL 0x00090000 + +#define CPSR_ALL 0 +#define SPSR_ALL 1 +#define CPSR_FLG 2 +#define SPSR_FLG 3 +#define CPSR_CTL 4 +#define SPSR_CTL 5 + +static CONST struct asm_psr psrs[] = +{ + /* Valid 's */ + {"cpsr", CPSR_ALL}, + {"cpsr_all", CPSR_ALL}, + {"spsr", SPSR_ALL}, + {"spsr_all", SPSR_ALL}, + + /* Valid 's */ + {"cpsr_flg", CPSR_FLG}, + {"spsr_flg", SPSR_FLG}, + + /* Valid 's */ + {"cpsr_c", CPSR_CTL}, + {"cpsr_ctl", CPSR_CTL}, + {"spsr_c", SPSR_CTL}, + {"spsr_ctl", SPSR_CTL} +}; + +/* Functions called by parser */ +/* ARM instructions */ +static void do_arit PARAMS ((char *operands, unsigned long flags)); +static void do_cmp PARAMS ((char *operands, unsigned long flags)); +static void do_mov PARAMS ((char *operands, unsigned long flags)); +static void do_ldst PARAMS ((char *operands, unsigned long flags)); +static void do_ldmstm PARAMS ((char *operands, unsigned long flags)); +static void do_branch PARAMS ((char *operands, unsigned long flags)); +static void do_swi PARAMS ((char *operands, unsigned long flags)); +/* Pseudo Op codes */ +static void do_adr PARAMS ((char *operands, unsigned long flags)); +static void do_nop PARAMS ((char *operands, unsigned long flags)); +/* ARM 2 */ +static void do_mul PARAMS ((char *operands, unsigned long flags)); +static void do_mla PARAMS ((char *operands, unsigned long flags)); +/* ARM 3 */ +static void do_swap PARAMS ((char *operands, unsigned long flags)); +/* ARM 6 */ +static void do_msr PARAMS ((char *operands, unsigned long flags)); +static void do_mrs PARAMS ((char *operands, unsigned long flags)); +/* ARM 7M */ +static void do_mull PARAMS ((char *operands, unsigned long flags)); +/* ARM THUMB */ +static void do_bx PARAMS ((char *operands, unsigned long flags)); + +/* Coprocessor Instructions */ +static void do_cdp PARAMS ((char *operands, unsigned long flags)); +static void do_lstc PARAMS ((char *operands, unsigned long flags)); +static void do_co_reg PARAMS ((char *operands, unsigned long flags)); +static void do_fp_ctrl PARAMS ((char *operands, unsigned long flags)); +static void do_fp_ldst PARAMS ((char *operands, unsigned long flags)); +static void do_fp_ldmstm PARAMS ((char *operands, unsigned long flags)); +static void do_fp_dyadic PARAMS ((char *operands, unsigned long flags)); +static void do_fp_monadic PARAMS ((char *operands, unsigned long flags)); +static void do_fp_cmp PARAMS ((char *operands, unsigned long flags)); +static void do_fp_from_reg PARAMS ((char *operands, unsigned long flags)); +static void do_fp_to_reg PARAMS ((char *operands, unsigned long flags)); + +static void fix_new_arm PARAMS ((fragS *frag, int where, + short int size, expressionS *exp, + int pc_rel, int reloc)); +static int arm_reg_parse PARAMS ((char **ccp)); +static int arm_psr_parse PARAMS ((char **ccp)); +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 int validate_offset_imm PARAMS ((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 **, int, int)); +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 cp_address_offset PARAMS ((char **)); +static int cp_address_required_here PARAMS ((char **)); +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 **, int)); +static void thumb_add_sub PARAMS ((char *, int)); +static void insert_reg PARAMS ((int)); +static void thumb_shift PARAMS ((char *, int)); +static void thumb_mov_compare PARAMS ((char *, int)); +static void set_constant_flonums PARAMS ((void)); +static valueT md_chars_to_number PARAMS ((char *, int)); +static void insert_reg_alias PARAMS ((char *, int)); +static void output_inst PARAMS ((char *)); +#ifdef OBJ_ELF +static bfd_reloc_code_real_type arm_parse_reloc(void); +#endif + +/* ARM instructions take 4bytes in the object file, Thumb instructions + take 2: */ +#define INSN_SIZE 4 + +/* LONGEST_INST is the longest basic instruction name without conditions or + * flags. + * ARM7M has 4 of length 5 + */ + +#define LONGEST_INST 5 + +struct asm_opcode +{ + CONST char * template; /* Basic string to match */ + unsigned long value; /* Basic instruction code */ + CONST char * comp_suffix; /* Compulsory suffix that must follow conds */ + CONST struct asm_flg * flags; /* Bits to toggle if flag 'n' set */ + unsigned long variants; /* Which CPU variants this exists for */ + /* Function to call to parse args */ + void (* parms) PARAMS ((char *, unsigned long)); +}; + +static CONST struct asm_opcode insns[] = +{ +/* ARM Instructions */ + {"and", 0x00000000, NULL, s_flag, ARM_ANY, do_arit}, + {"eor", 0x00200000, NULL, s_flag, ARM_ANY, do_arit}, + {"sub", 0x00400000, NULL, s_flag, ARM_ANY, do_arit}, + {"rsb", 0x00600000, NULL, s_flag, ARM_ANY, do_arit}, + {"add", 0x00800000, NULL, s_flag, ARM_ANY, do_arit}, + {"adc", 0x00a00000, NULL, s_flag, ARM_ANY, do_arit}, + {"sbc", 0x00c00000, NULL, s_flag, ARM_ANY, do_arit}, + {"rsc", 0x00e00000, NULL, s_flag, ARM_ANY, do_arit}, + {"orr", 0x01800000, NULL, s_flag, ARM_ANY, do_arit}, + {"bic", 0x01c00000, NULL, s_flag, ARM_ANY, do_arit}, + {"tst", 0x01000000, NULL, cmp_flags, ARM_ANY, do_cmp}, + {"teq", 0x01200000, NULL, cmp_flags, ARM_ANY, do_cmp}, + {"cmp", 0x01400000, NULL, cmp_flags, ARM_ANY, do_cmp}, + {"cmn", 0x01600000, NULL, cmp_flags, ARM_ANY, do_cmp}, + {"mov", 0x01a00000, NULL, s_flag, ARM_ANY, do_mov}, + {"mvn", 0x01e00000, NULL, s_flag, ARM_ANY, do_mov}, + {"str", 0x04000000, NULL, str_flags, ARM_ANY, do_ldst}, + {"ldr", 0x04100000, NULL, ldr_flags, ARM_ANY, do_ldst}, + {"stm", 0x08000000, NULL, stm_flags, ARM_ANY, do_ldmstm}, + {"ldm", 0x08100000, NULL, ldm_flags, ARM_ANY, do_ldmstm}, + {"swi", 0x0f000000, NULL, NULL, ARM_ANY, do_swi}, + {"bl", 0x0bfffffe, NULL, NULL, ARM_ANY, do_branch}, + {"b", 0x0afffffe, NULL, NULL, ARM_ANY, do_branch}, + +/* Pseudo ops */ + {"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr}, + {"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop}, + +/* ARM 2 multiplies */ + {"mul", 0x00000090, NULL, s_flag, ARM_2UP, do_mul}, + {"mla", 0x00200090, NULL, s_flag, ARM_2UP, do_mla}, + +/* ARM 3 - swp instructions */ + {"swp", 0x01000090, NULL, byte_flag, ARM_3UP, do_swap}, + +/* ARM 6 Coprocessor instructions */ + {"mrs", 0x010f0000, NULL, NULL, ARM_6UP, do_mrs}, + {"msr", 0x0120f000, NULL, NULL, ARM_6UP, do_msr}, +/* ScottB: our code uses 0x0128f000 for msr. + NickC: but this is wrong because the bits 16 and 19 are handled + by the PSR_xxx defines above. */ + +/* ARM 7M long multiplies - need signed/unsigned flags! */ + {"smull", 0x00c00090, NULL, s_flag, ARM_LONGMUL, do_mull}, + {"umull", 0x00800090, NULL, s_flag, ARM_LONGMUL, do_mull}, + {"smlal", 0x00e00090, NULL, s_flag, ARM_LONGMUL, do_mull}, + {"umlal", 0x00a00090, NULL, s_flag, ARM_LONGMUL, do_mull}, + +/* ARM THUMB interworking */ + {"bx", 0x012fff10, NULL, NULL, ARM_THUMB, do_bx}, + +/* Floating point instructions */ + {"wfs", 0x0e200110, NULL, NULL, FPU_ALL, do_fp_ctrl}, + {"rfs", 0x0e300110, NULL, NULL, FPU_ALL, do_fp_ctrl}, + {"wfc", 0x0e400110, NULL, NULL, FPU_ALL, do_fp_ctrl}, + {"rfc", 0x0e500110, NULL, NULL, FPU_ALL, do_fp_ctrl}, + {"ldf", 0x0c100100, "sdep", NULL, FPU_ALL, do_fp_ldst}, + {"stf", 0x0c000100, "sdep", NULL, FPU_ALL, do_fp_ldst}, + {"lfm", 0x0c100200, NULL, lfm_flags, FPU_MEMMULTI, do_fp_ldmstm}, + {"sfm", 0x0c000200, NULL, sfm_flags, FPU_MEMMULTI, do_fp_ldmstm}, + {"mvf", 0x0e008100, "sde", round_flags, FPU_ALL, do_fp_monadic}, + {"mnf", 0x0e108100, "sde", round_flags, FPU_ALL, do_fp_monadic}, + {"abs", 0x0e208100, "sde", round_flags, FPU_ALL, do_fp_monadic}, + {"rnd", 0x0e308100, "sde", round_flags, FPU_ALL, do_fp_monadic}, + {"sqt", 0x0e408100, "sde", round_flags, FPU_ALL, do_fp_monadic}, + {"log", 0x0e508100, "sde", round_flags, FPU_ALL, do_fp_monadic}, + {"lgn", 0x0e608100, "sde", round_flags, FPU_ALL, do_fp_monadic}, + {"exp", 0x0e708100, "sde", round_flags, FPU_ALL, do_fp_monadic}, + {"sin", 0x0e808100, "sde", round_flags, FPU_ALL, do_fp_monadic}, + {"cos", 0x0e908100, "sde", round_flags, FPU_ALL, do_fp_monadic}, + {"tan", 0x0ea08100, "sde", round_flags, FPU_ALL, do_fp_monadic}, + {"asn", 0x0eb08100, "sde", round_flags, FPU_ALL, do_fp_monadic}, + {"acs", 0x0ec08100, "sde", round_flags, FPU_ALL, do_fp_monadic}, + {"atn", 0x0ed08100, "sde", round_flags, FPU_ALL, do_fp_monadic}, + {"urd", 0x0ee08100, "sde", round_flags, FPU_ALL, do_fp_monadic}, + {"nrm", 0x0ef08100, "sde", round_flags, FPU_ALL, do_fp_monadic}, + {"adf", 0x0e000100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, + {"suf", 0x0e200100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, + {"rsf", 0x0e300100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, + {"muf", 0x0e100100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, + {"dvf", 0x0e400100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, + {"rdf", 0x0e500100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, + {"pow", 0x0e600100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, + {"rpw", 0x0e700100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, + {"rmf", 0x0e800100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, + {"fml", 0x0e900100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, + {"fdv", 0x0ea00100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, + {"frd", 0x0eb00100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, + {"pol", 0x0ec00100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, + {"cmf", 0x0e90f110, NULL, except_flag, FPU_ALL, do_fp_cmp}, + {"cnf", 0x0eb0f110, NULL, except_flag, FPU_ALL, do_fp_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", 0x0ed0f110, NULL, NULL, FPU_ALL, do_fp_cmp}, + {"cnfe", 0x0ef0f110, NULL, NULL, FPU_ALL, do_fp_cmp}, + {"flt", 0x0e000110, "sde", round_flags, FPU_ALL, do_fp_from_reg}, + {"fix", 0x0e100110, NULL, fix_flags, FPU_ALL, do_fp_to_reg}, + +/* Generic copressor instructions */ + {"cdp", 0x0e000000, NULL, NULL, ARM_2UP, do_cdp}, + {"ldc", 0x0c100000, NULL, cplong_flag, ARM_2UP, do_lstc}, + {"stc", 0x0c000000, NULL, cplong_flag, ARM_2UP, do_lstc}, + {"mcr", 0x0e000010, NULL, NULL, ARM_2UP, do_co_reg}, + {"mrc", 0x0e100010, NULL, NULL, ARM_2UP, do_co_reg}, +}; + +/* 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 MULTI_SET_PSR 0x00400000 + +#define LITERAL_MASK 0xf000f000 +#define COND_MASK 0xf0000000 +#define OPCODE_MASK 0xfe1fffff +#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 + +static void do_t_nop PARAMS ((char *operands)); +static void do_t_arit PARAMS ((char *operands)); +static void do_t_add PARAMS ((char *operands)); +static void do_t_asr PARAMS ((char *operands)); +static void do_t_branch9 PARAMS ((char *operands)); +static void do_t_branch12 PARAMS ((char *operands)); +static void do_t_branch23 PARAMS ((char *operands)); +static void do_t_bx PARAMS ((char *operands)); +static void do_t_compare PARAMS ((char *operands)); +static void do_t_ldmstm PARAMS ((char *operands)); +static void do_t_ldr PARAMS ((char *operands)); +static void do_t_ldrb PARAMS ((char *operands)); +static void do_t_ldrh PARAMS ((char *operands)); +static void do_t_lds PARAMS ((char *operands)); +static void do_t_lsl PARAMS ((char *operands)); +static void do_t_lsr PARAMS ((char *operands)); +static void do_t_mov PARAMS ((char *operands)); +static void do_t_push_pop PARAMS ((char *operands)); +static void do_t_str PARAMS ((char *operands)); +static void do_t_strb PARAMS ((char *operands)); +static void do_t_strh PARAMS ((char *operands)); +static void do_t_sub PARAMS ((char *operands)); +static void do_t_swi PARAMS ((char *operands)); +static void do_t_adr PARAMS ((char *operands)); + +#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_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 +{ + CONST char * template; /* Basic string to match */ + unsigned long value; /* Basic instruction code */ + int size; + void (* parms) PARAMS ((char *)); /* Function to call to parse args */ +}; + +static CONST struct thumb_opcode tinsns[] = +{ + {"adc", 0x4140, 2, do_t_arit}, + {"add", 0x0000, 2, do_t_add}, + {"and", 0x4000, 2, do_t_arit}, + {"asr", 0x0000, 2, do_t_asr}, + {"b", T_OPCODE_BRANCH, 2, do_t_branch12}, + {"beq", 0xd0fe, 2, do_t_branch9}, + {"bne", 0xd1fe, 2, do_t_branch9}, + {"bcs", 0xd2fe, 2, do_t_branch9}, + {"bhs", 0xd2fe, 2, do_t_branch9}, + {"bcc", 0xd3fe, 2, do_t_branch9}, + {"bul", 0xd3fe, 2, do_t_branch9}, + {"blo", 0xd3fe, 2, do_t_branch9}, + {"bmi", 0xd4fe, 2, do_t_branch9}, + {"bpl", 0xd5fe, 2, do_t_branch9}, + {"bvs", 0xd6fe, 2, do_t_branch9}, + {"bvc", 0xd7fe, 2, do_t_branch9}, + {"bhi", 0xd8fe, 2, do_t_branch9}, + {"bls", 0xd9fe, 2, do_t_branch9}, + {"bge", 0xdafe, 2, do_t_branch9}, + {"blt", 0xdbfe, 2, do_t_branch9}, + {"bgt", 0xdcfe, 2, do_t_branch9}, + {"ble", 0xddfe, 2, do_t_branch9}, + {"bic", 0x4380, 2, do_t_arit}, + {"bl", 0xf7fffffe, 4, do_t_branch23}, + {"bx", 0x4700, 2, do_t_bx}, + {"cmn", T_OPCODE_CMN, 2, do_t_arit}, + {"cmp", 0x0000, 2, do_t_compare}, + {"eor", 0x4040, 2, do_t_arit}, + {"ldmia", 0xc800, 2, do_t_ldmstm}, + {"ldr", 0x0000, 2, do_t_ldr}, + {"ldrb", 0x0000, 2, do_t_ldrb}, + {"ldrh", 0x0000, 2, do_t_ldrh}, + {"ldrsb", 0x5600, 2, do_t_lds}, + {"ldrsh", 0x5e00, 2, do_t_lds}, + {"ldsb", 0x5600, 2, do_t_lds}, + {"ldsh", 0x5e00, 2, do_t_lds}, + {"lsl", 0x0000, 2, do_t_lsl}, + {"lsr", 0x0000, 2, do_t_lsr}, + {"mov", 0x0000, 2, do_t_mov}, + {"mul", T_OPCODE_MUL, 2, do_t_arit}, + {"mvn", T_OPCODE_MVN, 2, do_t_arit}, + {"neg", T_OPCODE_NEG, 2, do_t_arit}, + {"orr", 0x4300, 2, do_t_arit}, + {"pop", 0xbc00, 2, do_t_push_pop}, + {"push", 0xb400, 2, do_t_push_pop}, + {"ror", 0x41c0, 2, do_t_arit}, + {"sbc", 0x4180, 2, do_t_arit}, + {"stmia", 0xc000, 2, do_t_ldmstm}, + {"str", 0x0000, 2, do_t_str}, + {"strb", 0x0000, 2, do_t_strb}, + {"strh", 0x0000, 2, do_t_strh}, + {"swi", 0xdf00, 2, do_t_swi}, + {"sub", 0x0000, 2, do_t_sub}, + {"tst", T_OPCODE_TST, 2, do_t_arit}, + /* Pseudo ops: */ + {"adr", 0x0000, 2, do_t_adr}, + {"nop", 0x46C0, 2, do_t_nop}, /* mov r8,r8 */ +}; + +struct reg_entry +{ + CONST char * name; + int number; +}; + +#define int_register(reg) ((reg) >= 0 && (reg) <= 15) +#define cp_register(reg) ((reg) >= 32 && (reg) <= 47) +#define fp_register(reg) ((reg) >= 16 && (reg) <= 23) + +#define REG_PC 15 +#define REG_LR 14 +#define REG_SP 13 + +/* These are the standard names; Users can add aliases with .req */ +static CONST struct reg_entry reg_table[] = +{ + /* Processor Register Numbers */ + {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3}, + {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7}, + {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11}, + {"r12", 12}, {"r13", REG_SP},{"r14", REG_LR},{"r15", REG_PC}, + /* APCS conventions */ + {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3}, + {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8}, + {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10}, + {"fp", 11}, {"ip", 12}, {"sp", REG_SP},{"lr", REG_LR},{"pc", REG_PC}, + /* FP Registers */ + {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19}, + {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23}, + {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35}, + {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39}, + {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43}, + {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47}, + {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35}, + {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39}, + {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43}, + {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47}, + {NULL, 0} +}; + +#define bad_args _("Bad arguments to instruction"); +#define bad_pc _("r15 not allowed here"); + +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_reg_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_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)); +#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[] = +{ + {"req", s_req, 0}, /* Never called becasue '.req' does not start line */ + {"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}, + {"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} +}; + +/* Stuff needed to resolve the label ambiguity + As: + ... + label: + may differ from: + ... + label: + +*/ + +symbolS * last_label_seen; +static int label_is_thumb_function_name = false; + +/* Literal stuff */ + +#define MAX_LITERAL_POOL_SIZE 1024 + +typedef struct literalS +{ + struct expressionS exp; + struct arm_it * inst; +} literalT; + +literalT literals[MAX_LITERAL_POOL_SIZE]; +int next_literal_pool_place = 0; /* Next free entry in the pool */ +int lit_pool_num = 1; /* Next literal pool number */ +symbolS * current_poolP = NULL; +symbolS * symbol_make_empty PARAMS ((void)); + +static int +add_to_lit_pool () +{ + int lit_count = 0; + + if (current_poolP == NULL) + current_poolP = symbol_make_empty (); + + /* Check if this literal value is already in the pool: */ + while (lit_count < next_literal_pool_place) + { + if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op + && inst.reloc.exp.X_op == O_constant + && literals[lit_count].exp.X_add_number == inst.reloc.exp.X_add_number + && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned) + break; + lit_count++; + } + + if (lit_count == next_literal_pool_place) /* new entry */ + { + if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE) + { + inst.error = _("Literal Pool Overflow"); + return FAIL; + } + + literals[next_literal_pool_place].exp = inst.reloc.exp; + lit_count = next_literal_pool_place++; + } + + inst.reloc.exp.X_op = O_symbol; + inst.reloc.exp.X_add_number = (lit_count) * 4 - 8; + inst.reloc.exp.X_add_symbol = current_poolP; + + 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_) */ + 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 (¬es, name, name_length); + preserved_copy_of_name = obstack_finish (¬es); +#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); + + symbolP->sy_frag = 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 */ +} + +symbolS * +symbol_make_empty () +{ + symbolS * symbolP; + + symbolP = (symbolS *) obstack_alloc (¬es, sizeof (symbolS)); + + /* symbol must be born in some fixed state. This seems as good as any. */ + memset (symbolP, 0, sizeof (symbolS)); + + symbolP->bsym = bfd_make_empty_symbol (stdoutput); + assert (symbolP->bsym != 0); + symbolP->bsym->udata.p = (PTR) symbolP; + + return symbolP; +} + +/* Check that an immediate is valid, and 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; +} + +static int +validate_offset_imm (val, hwse) + int val; + int hwse; +{ + if ((hwse && (val < -255 || val > 255)) + || (val < -4095 || val > 4095)) + return FAIL; + return val; +} + + +static void +s_req (a) + int a; +{ + as_bad (_("Invalid syntax for .req directive.")); +} + +static void +s_bss (ignore) + int ignore; +{ + /* 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 (); +} + +static void +s_even (ignore) + int ignore; +{ + if (!need_pass_2) /* Never make frag if expect extra pass. */ + frag_align (1, 0, 0); + + record_alignment (now_seg, 1); + + demand_empty_rest_of_line (); +} + +static void +s_ltorg (internal) + int internal; +{ + int lit_count = 0; + char sym_name[20]; + + if (current_poolP == NULL) + { + /* Nothing to do */ + if (!internal) + as_tsktsk (_("Nothing to put in the pool\n")); + return; + } + + /* 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); + + if (internal) + as_tsktsk (_("Inserting implicit pool at change of section")); + + sprintf (sym_name, "$$lit_\002%x", lit_pool_num++); + + symbol_locate (current_poolP, sym_name, now_seg, + (valueT) frag_now_fix (), frag_now); + symbol_table_insert (current_poolP); + + ARM_SET_THUMB (current_poolP, thumb_mode); + +#if defined OBJ_COFF || defined OBJ_ELF + ARM_SET_INTERWORK (current_poolP, support_interwork); +#endif + + while (lit_count < next_literal_pool_place) + /* First output the expression in the instruction to the pool */ + emit_expr (&(literals[lit_count++].exp), 4); /* .word */ + + next_literal_pool_place = 0; + current_poolP = NULL; +} + +static void +s_align (unused) /* Same as s_align_ptwo but align 0 => align 2 */ + int 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; +{ + /* 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 = 1; + + record_alignment (now_seg, 1); + } + + demand_empty_rest_of_line (); +} + +static void +s_thumb_func (ignore) + int ignore; +{ + /* 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 (); +} + +static void +opcode_select (width) + int width; +{ + switch (width) + { + case 16: + if (! thumb_mode) + { + if (! (cpu_variant & ARM_THUMB)) + 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); + } + break; + + case 32: + if (thumb_mode) + { + if ((cpu_variant & ARM_ANY) == ARM_THUMB) + 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); + } + break; + + default: + as_bad (_("invalid instruction size selected (%d)"), width); + } +} + +static void +s_arm (ignore) + int ignore; +{ + opcode_select (32); + demand_empty_rest_of_line (); +} + +static void +s_thumb (ignore) + int ignore; +{ + opcode_select (16); + demand_empty_rest_of_line (); +} + +static void +s_code (unused) + int 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; +{ + while (*str == ' ') + str++; + + if (*str != '\0') + 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 the instruction. */ + +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)) != FAIL && int_register (reg)) + { + 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; +} + +static int +psr_required_here (str, cpsr, spsr) + char ** str; + int cpsr; + int spsr; +{ + int psr; + char * start = *str; + psr = arm_psr_parse (str); + + if (psr == cpsr || psr == spsr) + { + if (psr == spsr) + inst.instruction |= 1 << 22; + + return SUCCESS; + } + + /* In the few cases where we might be able to accept something else + this error can be overridden */ + inst.error = _(" expected"); + + /* Restore the start point. */ + *str = start; + return FAIL; +} + +static int +co_proc_number (str) + char **str; +{ + int processor, pchar; + + while (**str == ' ') + (*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 (**str == 'p' || **str == 'P') + (*str)++; + + 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; + + while (**str == ' ') + (*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)) != FAIL && cp_register (reg)) + { + reg &= 15; + 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)) != FAIL && fp_register (reg)) + { + reg &= 7; + 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; + + while (**str == ' ') + (*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) + char ** str; +{ + char * p = * str; + int pre_inc = 0; + int write_back = 0; + + if (*p == '[') + { + int reg; + + p++; + while (*p == ' ') + p++; + + if ((reg = reg_required_here (& p, 16)) == FAIL) + return FAIL; + + while (*p == ' ') + 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_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_address_offset (& p) == FAIL) + return FAIL; + + while (*p == ' ') + p++; + + if (*p++ != ']') + { + inst.error = _("missing ]"); + return FAIL; + } + + while (*p == ' ') + 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; + 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_nop (str, flags) + char * str; + unsigned long flags; +{ + /* Do nothing really */ + inst.instruction |= flags; /* This is pointless */ + end_of_line (str); + return; +} + +static void +do_mrs (str, flags) + char *str; + unsigned long flags; +{ + /* Only one syntax */ + while (*str == ' ') + str++; + + if (reg_required_here (&str, 12) == FAIL) + { + inst.error = bad_args; + return; + } + + if (skip_past_comma (&str) == FAIL + || psr_required_here (& str, CPSR_ALL, SPSR_ALL) == FAIL) + { + inst.error = _(" expected"); + return; + } + + inst.instruction |= flags; + end_of_line (str); + return; +} + +/* Three possible forms: ", Rm", ", Rm", ", #expression" */ +static void +do_msr (str, flags) + char * str; + unsigned long flags; +{ + int reg; + + while (*str == ' ') + str ++; + + if (psr_required_here (&str, CPSR_ALL, SPSR_ALL) == SUCCESS) + { + inst.instruction |= PSR_ALL; + + /* Sytax should be ", Rm" */ + if (skip_past_comma (&str) == FAIL + || (reg = reg_required_here (&str, 0)) == FAIL) + { + inst.error = bad_args; + return; + } + } + else + { + if (psr_required_here (& str, CPSR_FLG, SPSR_FLG) == SUCCESS) + inst.instruction |= PSR_FLAGS; + else if (psr_required_here (& str, CPSR_CTL, SPSR_CTL) == SUCCESS) + inst.instruction |= PSR_CONTROL; + else + { + inst.error = bad_args; + return; + } + + if (skip_past_comma (&str) == FAIL) + { + inst.error = bad_args; + return; + } + + /* Syntax could be ", rm", ", #expression" */ + + if ((reg = reg_required_here (& str, 0)) != FAIL) + ; + /* Immediate expression */ + else if (is_immediate_prefix (* str)) + { + str ++; + inst.error = NULL; + + if (my_get_expression (& inst.reloc.exp, & str)) + { + inst.error = _("Register or shift expression expected"); + return; + } + + 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 == FAIL) + { + inst.error = _("Invalid constant"); + return; + } + + inst.instruction |= value; + } + + flags |= INST_IMMEDIATE; + } + else + { + inst.error = _("Error: unrecognised syntax for second argument to msr instruction"); + return; + } + } + + inst.error = NULL; + inst.instruction |= flags; + end_of_line (str); + return; +} + +/* 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, flags) + char * str; + unsigned long flags; +{ + int rdlo, rdhi, rm, rs; + + /* only one format "rdlo, rdhi, rm, rs" */ + while (*str == ' ') + 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; + } + + inst.instruction |= flags; + end_of_line (str); + return; +} + +static void +do_mul (str, flags) + char * str; + unsigned long flags; +{ + int rd, rm; + + /* only one format "rd, rm, rs" */ + while (*str == ' ') + 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; + } + + inst.instruction |= flags; + end_of_line (str); + return; +} + +static void +do_mla (str, flags) + char * str; + unsigned long flags; +{ + int rd, rm; + + /* only one format "rd, rm, rs, rn" */ + while (*str == ' ') + 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; + } + + inst.instruction |= flags; + end_of_line (str); + return; +} + +/* 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 [(int)(*save_in)] || *save_in == '\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 = 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 (sp->sy_value.X_op == O_big) + return 1; + + if (sp->sy_value.X_add_symbol) + { + return (walk_no_bignums (sp->sy_value.X_add_symbol) + || (sp->sy_value.X_op_symbol + && walk_no_bignums (sp->sy_value.X_op_symbol))); + } + + return 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; + seg = expression (ep); + +#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; +} + +/* unrestrict should be one if is permitted for this + instruction */ + +static int +decode_shift (str, unrestrict) + char ** str; + int unrestrict; +{ + struct asm_shift * shft; + char * p; + char c; + + while (**str == ' ') + (*str)++; + + for (p = *str; isalpha (*p); p++) + ; + + if (p == *str) + { + inst.error = _("Shift expression expected"); + return FAIL; + } + + c = *p; + *p = '\0'; + shft = (struct asm_shift *) hash_find (arm_shift_hsh, *str); + *p = c; + if (shft) + { + if (!strncmp (*str, "rrx", 3) + || !strncmp (*str, "RRX", 3)) + { + *str = p; + inst.instruction |= shft->value; + return SUCCESS; + } + + while (*p == ' ') + p++; + + if (unrestrict && reg_required_here (&p, 8) != FAIL) + { + inst.instruction |= shft->value | SHIFT_BY_REG; + *str = p; + return SUCCESS; + } + else if (is_immediate_prefix (* p)) + { + 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, or lsl #32 */ + if (num > 32 || (num == 32 && shft->value == 0)) + { + inst.error = _("Invalid immediate shift"); + return FAIL; + } + + /* Shifts of zero should be converted to lsl (which is zero)*/ + if (num == 0) + { + *str = p; + return SUCCESS; + } + + /* Shifts of 32 are encoded as 0, for those shifts that + support it. */ + if (num == 32) + num = 0; + + inst.instruction |= (num << 7) | shft->value; + *str = p; + return SUCCESS; + } + + inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM; + inst.reloc.pc_rel = 0; + inst.instruction |= shft->value; + *str = p; + return SUCCESS; + } + else + { + inst.error = unrestrict ? _("shift requires register or #expression") + : _("shift requires #expression"); + *str = p; + return FAIL; + } + } + + inst.error = _("Shift expression expected"); + return FAIL; +} + +/* Do those data_ops which can take a negative immediate constant */ +/* by altering the instuction. 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 == 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; + + while (**str == ' ') + (*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; +{ + while (**str == ' ') + (*str)++; + + if (fp_reg_required_here (str, 0) != FAIL) + return SUCCESS; + else + { + /* Immediate expression */ + if (*((*str)++) == '#') + { + int i; + + inst.error = NULL; + while (**str == ' ') + (*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[(int)**str] || **str == '\0') + { + 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, flags) + char * str; + unsigned long flags; +{ + while (*str == ' ') + 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; + } + + inst.instruction |= flags; + end_of_line (str); + return; +} + +static void +do_adr (str, flags) + char * str; + unsigned long flags; +{ + /* 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" */ + + while (*str == ' ') + 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; + inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */ + inst.reloc.pc_rel = 1; + inst.instruction |= flags; + end_of_line (str); + return; +} + +static void +do_cmp (str, flags) + char * str; + unsigned long flags; +{ + while (*str == ' ') + 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; + } + + inst.instruction |= flags; + if ((flags & 0x0000f000) == 0) + inst.instruction |= CONDS_BIT; + + end_of_line (str); + return; +} + +static void +do_mov (str, flags) + char * str; + unsigned long flags; +{ + while (*str == ' ') + 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; + } + + inst.instruction |= flags; + end_of_line (str); + return; +} + +static int +ldst_extend (str, hwse) + char ** str; + int hwse; +{ + 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 ((hwse && (value < -255 || value > 255)) + || (value < -4095 || value > 4095)) + { + 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 */ + if (hwse) + inst.instruction |= add | HWOFFSET_IMM | (value >> 4) << 8 | value & 0xF; + else + inst.instruction |= add | value; + } + else + { + if (hwse) + { + inst.instruction |= HWOFFSET_IMM; + inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8; + } + else + inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM; + inst.reloc.pc_rel = 0; + } + return SUCCESS; + + case '-': + add = 0; /* and fall through */ + case '+': + (*str)++; /* and fall through */ + default: + if (reg_required_here (str, 0) == FAIL) + return FAIL; + + if (hwse) + inst.instruction |= add; + else + { + inst.instruction |= add | OFFSET_REG; + if (skip_past_comma (str) == SUCCESS) + return decode_shift (str, SHIFT_RESTRICT); + } + + return SUCCESS; + } +} + +static void +do_ldst (str, flags) + char * str; + unsigned long flags; +{ + int halfword = 0; + int pre_inc = 0; + int conflict_reg; + int value; + + /* This is not ideal, but it is the simplest way of dealing with the + ARM7T halfword instructions (since they use a different + encoding, but the same mnemonic): */ + if (halfword = ((flags & 0x80000000) != 0)) + { + /* This is actually a load/store of a halfword, or a + signed-extension load */ + if ((cpu_variant & ARM_HALFWORD) == 0) + { + inst.error + = _("Processor does not support halfwords or signed bytes"); + return; + } + + inst.instruction = (inst.instruction & COND_MASK) + | (flags & ~COND_MASK); + + flags = 0; + } + + while (*str == ' ') + 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++; + while (*str == ' ') + str++; + + if ((reg = reg_required_here (&str, 16)) == FAIL) + return; + + conflict_reg = (((conflict_reg == reg) + && (inst.instruction & LOAD_BIT)) + ? 1 : 0); + + while (*str == ' ') + str++; + + if (*str == ']') + { + str++; + if (skip_past_comma (&str) == SUCCESS) + { + /* [Rn],... (post inc) */ + if (ldst_extend (&str, halfword) == FAIL) + return; + if (conflict_reg) + as_warn (_("destination register same as write-back base\n")); + } + else + { + /* [Rn] */ + if (halfword) + inst.instruction |= HWOFFSET_IMM; + + while (*str == ' ') + str++; + + if (*str == '!') + { + if (conflict_reg) + as_warn (_("destination register same as write-back base\n")); + str++; + inst.instruction |= WRITE_BACK; + } + + flags |= INDEX_UP; + if (! (flags & TRANS_BIT)) + 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, halfword) == FAIL) + return; + + while (*str == ' ') + str++; + + if (*str++ != ']') + { + inst.error = _("missing ]"); + return; + } + + while (*str == ' ') + str++; + + if (*str == '!') + { + if (conflict_reg) + as_tsktsk (_("destination register same as write-back base\n")); + str++; + inst.instruction |= WRITE_BACK; + } + } + } + else if (*str == '=') + { + /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */ + str++; + + while (*str == ' ') + 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)) != FAIL) + { + /* This can be done with a mov instruction */ + inst.instruction &= LITERAL_MASK; + inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT); + inst.instruction |= (flags & COND_MASK) | (value & 0xfff); + end_of_line(str); + return; + } + else + { + /* 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 */ + if (halfword) + { + inst.instruction |= HWOFFSET_IMM; + inst.reloc.type = BFD_RELOC_ARM_HWLITERAL; + } + else + 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; + + if (halfword) + { + inst.instruction |= HWOFFSET_IMM; + inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8; + } + else + inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM; + inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */ + inst.reloc.pc_rel = 1; + inst.instruction |= (REG_PC << 16); + pre_inc = 1; + } + + if (pre_inc && (flags & TRANS_BIT)) + inst.error = _("Pre-increment instruction with translate"); + + inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0); + end_of_line (str); + return; +} + +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; + + while (*str == ' ') + 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--; + while (*str == ' ') + 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; + } + } + + while (*str == ' ') + str++; + + if (*str == '|' || *str == '+') + { + str++; + another_range = 1; + } + } while (another_range); + + *strp = str; + return range; +} + +static void +do_ldmstm (str, flags) + char * str; + unsigned long flags; +{ + int base_reg; + long range; + + while (*str == ' ') + 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; + } + + while (*str == ' ') + str++; + if (*str == '!') + { + flags |= 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++; + flags |= MULTI_SET_PSR; + } + + inst.instruction |= flags | range; + end_of_line (str); + return; +} + +static void +do_swi (str, flags) + char * str; + unsigned long flags; +{ + while (*str == ' ') + 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; + inst.instruction |= flags; + + end_of_line (str); + + return; +} + +static void +do_swap (str, flags) + char * str; + unsigned long flags; +{ + int reg; + + while (*str == ' ') + 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; + } + + while (*str == ' ') + str++; + + if ((reg = reg_required_here (&str, 16)) == FAIL) + return; + + if (reg == REG_PC) + { + inst.error = bad_pc; + return; + } + + while (*str == ' ') + str++; + + if (*str++ != ']') + { + inst.error = _("missing ]"); + return; + } + + inst.instruction |= flags; + end_of_line (str); + return; +} + +static void +do_branch (str, flags) + char * str; + unsigned long flags; +{ + 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); + return; +} + +static void +do_bx (str, flags) + char * str; + unsigned long flags; +{ + int reg; + + while (*str == ' ') + str++; + + if ((reg = reg_required_here (&str, 0)) == FAIL) + return; + + if (reg == REG_PC) + as_tsktsk (_("Use of r15 in bx has undefined behaviour")); + + end_of_line (str); + return; +} + +static void +do_cdp (str, flags) + char * str; + unsigned long flags; +{ + /* Co-processor data operation. + Format: CDP{cond} CP#,,CRd,CRn,CRm{,} */ + while (*str == ' ') + 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); + return; +} + +static void +do_lstc (str, flags) + char * str; + unsigned long flags; +{ + /* Co-processor register load/store. + Format: */ + + while (*str == ' ') + 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) == FAIL) + { + if (! inst.error) + inst.error = bad_args; + return; + } + + inst.instruction |= flags; + end_of_line (str); + return; +} + +static void +do_co_reg (str, flags) + char * str; + unsigned long flags; +{ + /* Co-processor register transfer. + Format: {cond} CP#,,Rd,CRn,CRm{,} */ + + while (*str == ' ') + 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); + return; +} + +static void +do_fp_ctrl (str, flags) + char * str; + unsigned long flags; +{ + /* FP control registers. + Format: {cond} Rn */ + + while (*str == ' ') + str++; + + if (reg_required_here (&str, 12) == FAIL) + { + if (!inst.error) + inst.error = bad_args; + return; + } + + end_of_line (str); + return; +} + +static void +do_fp_ldst (str, flags) + char * str; + unsigned long flags; +{ + while (*str == ' ') + str++; + + switch (inst.suffix) + { + case SUFF_S: + break; + case SUFF_D: + inst.instruction |= CP_T_X; + break; + case SUFF_E: + inst.instruction |= CP_T_Y; + break; + case SUFF_P: + inst.instruction |= CP_T_X | CP_T_Y; + break; + default: + abort (); + } + + 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) == FAIL) + { + if (!inst.error) + inst.error = bad_args; + return; + } + + end_of_line (str); +} + +static void +do_fp_ldmstm (str, flags) + char * str; + unsigned long flags; +{ + int num_regs; + + while (*str == ' ') + 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 (flags) + { + 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++; + while (*str == ' ') + str++; + + if ((reg = reg_required_here (&str, 16)) == FAIL) + return; + + while (*str == ' ') + 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 (flags & CP_T_Pre) + { + /* Pre-decrement */ + offset = 3 * num_regs; + if (write_back) + flags |= CP_T_WB; + } + else + { + /* Post-increment */ + if (write_back) + { + flags |= CP_T_WB; + offset = 3 * num_regs; + } + else + { + /* No write-back, so convert this into a standard pre-increment + instruction -- aesthetically more pleasing. */ + flags = CP_T_Pre | CP_T_UD; + offset = 0; + } + } + + inst.instruction |= flags | offset; + } + else if (skip_past_comma (&str) == FAIL + || cp_address_required_here (&str) == FAIL) + { + if (! inst.error) + inst.error = bad_args; + return; + } + + end_of_line (str); +} + +static void +do_fp_dyadic (str, flags) + char * str; + unsigned long flags; +{ + while (*str == ' ') + str++; + + switch (inst.suffix) + { + case SUFF_S: + break; + case SUFF_D: + inst.instruction |= 0x00000080; + break; + case SUFF_E: + inst.instruction |= 0x00080000; + break; + default: + abort (); + } + + 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; + } + + inst.instruction |= flags; + end_of_line (str); + return; +} + +static void +do_fp_monadic (str, flags) + char * str; + unsigned long flags; +{ + while (*str == ' ') + str++; + + switch (inst.suffix) + { + case SUFF_S: + break; + case SUFF_D: + inst.instruction |= 0x00000080; + break; + case SUFF_E: + inst.instruction |= 0x00080000; + break; + default: + abort (); + } + + 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; + } + + inst.instruction |= flags; + end_of_line (str); + return; +} + +static void +do_fp_cmp (str, flags) + char * str; + unsigned long flags; +{ + while (*str == ' ') + 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; + } + + inst.instruction |= flags; + end_of_line (str); + return; +} + +static void +do_fp_from_reg (str, flags) + char * str; + unsigned long flags; +{ + while (*str == ' ') + str++; + + switch (inst.suffix) + { + case SUFF_S: + break; + case SUFF_D: + inst.instruction |= 0x00000080; + break; + case SUFF_E: + inst.instruction |= 0x00080000; + break; + default: + abort (); + } + + 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; + } + + inst.instruction |= flags; + end_of_line (str); + return; +} + +static void +do_fp_to_reg (str, flags) + char * str; + unsigned long flags; +{ + while (*str == ' ') + 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; + } + + inst.instruction |= flags; + end_of_line (str); + return; +} + +/* 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; + + while (*str == ' ') + 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; + } + } + else + 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; + + while (*str == ' ') + 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; + + while (*str == ' ') + 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)) + { + 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 (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 + 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; + + while (*str == ' ') + 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 == '=') + { + /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */ + str++; + + while (*str == ' ') + 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); + inst.reloc.exp.X_add_number += 4; /* Adjust ARM pipeline offset to Thumb */ + + 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); +} + +static void +do_t_nop (str) + char * str; +{ + /* Do nothing */ + end_of_line (str); + return; +} + +/* 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; + + while (*str == ' ') + str++; + + if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL) + return; + + if (skip_past_comma (&str) == FAIL + || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL) + { + if (! inst.error) + 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 one 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 definitonmust 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; + + while (*str == ' ') + 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; + + while (*str == ' ') + 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; + + while (*str == ' ') + 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; + + while (*str == ' ') + 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; +{ + while (*str == ' ') + str++; + + if (my_get_expression (&inst.reloc.exp, &str)) + return; + + inst.reloc.type = BFD_RELOC_ARM_SWI; + end_of_line (str); + return; +} + +static void +do_t_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-.-4" */ + while (*str == ' ') + str++; + + if (reg_required_here (&str, 4) == FAIL /* Store Rd in temporary location inside instruction. */ + || 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 (entry) + int entry; +{ + int len = strlen (reg_table[entry].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, reg_table[entry].name); + + for (i = 0; buf[i]; i++) + buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i]; + + buf2[i] = '\0'; + + hash_insert (arm_reg_hsh, buf, (PTR) ®_table[entry]); + hash_insert (arm_reg_hsh, buf2, (PTR) ®_table[entry]); +} + +static void +insert_reg_alias (str, regnum) + char *str; + int regnum; +{ + struct reg_entry *new = + (struct reg_entry *)xmalloc (sizeof (struct reg_entry)); + char *name = xmalloc (strlen (str) + 1); + strcpy (name, str); + + new->name = name; + new->number = regnum; + + hash_insert (arm_reg_hsh, name, (PTR) new); +} + +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 (); +} + +void +md_begin () +{ + 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_reg_hsh = hash_new ()) == NULL + || (arm_psr_hsh = hash_new ()) == NULL) + as_fatal (_("Virtual memory exhausted")); + + for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++) + hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i)); + 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) / sizeof (struct asm_shift); i++) + hash_insert (arm_shift_hsh, shift[i].template, (PTR) (shift + 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 = 0; reg_table[i].name; i++) + insert_reg (i); + + set_constant_flonums (); + +#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; + + bfd_set_private_flags (stdoutput, flags); + } +#endif + + { + unsigned mach; + + /* 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; + + default: + case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined */ + mach = bfd_mach_arm_4; + break; + + case ARM_7: /* also ARM_6 */ + mach = bfd_mach_arm_3; + break; + } + + /* Catch special cases */ + if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT)) + { + if (cpu_variant & ARM_THUMB) + mach = bfd_mach_arm_4T; + else if ((cpu_variant & ARM_ARCHv4) == ARM_ARCHv4) + mach = bfd_mach_arm_4; + else if (cpu_variant & ARM_LONGMUL) + mach = bfd_mach_arm_3M; + } + + 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 + { + /* 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 relocs + for the ELF port and into the insns themselves for the COFF port. */ +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; + } + + return fixP->fx_where + fixP->fx_frag->fr_address; +} + +/* Round up a section size to the appropriate boundary. */ +valueT +md_section_align (segment, size) + segT segment; + valueT size; +{ +#ifdef OBJ_ELF + /* Don't align the dwarf2 debug sections */ + if (!strncmp (segment->name, ".debug", 5)) + return size; +#endif + /* Round all sects to multiple of 4 */ + return (size + 3) & ~3; +} + +/* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise + we have no need to default values of symbols. */ + +/* ARGSUSED */ +symbolS * +md_undefined_symbol (name) + char * name; +{ +#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) + register char ** ccp; +{ + 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 (arm_reg_hsh, start); + *p = c; + + if (reg) + { + *ccp = p; + return reg->number; + } + + return FAIL; +} + +static int +arm_psr_parse (ccp) + register char ** ccp; +{ + char * start = * ccp; + char c; + char * p; + CONST struct asm_psr * psr; + + p = start; + c = *p++; + while (isalpha (c) || c == '_') + c = *p++; + + *--p = 0; + psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start); + *p = c; + + if (psr) + { + *ccp = p; + return psr->number; + } + + return FAIL; +} + +int +md_apply_fix3 (fixP, val, seg) + fixS * fixP; + valueT * val; + segT seg; +{ + offsetT value = * val; + 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 || fixP->fx_addsy->sy_value.X_op == O_constant) + && !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 (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH) + value = 0; + else + value += md_pcrel_from (fixP); + } + } + + fixP->fx_addnumber = value; /* Remember value for emit_reloc */ + + 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 (%x) after fixup\n"), value); + break; + } + + newimm |= (temp & 0xfffff000); + md_number_to_chars (buf, (valueT) newimm, INSN_SIZE); + break; + + case BFD_RELOC_ARM_OFFSET_IMM: + sign = value >= 0; + if ((value = validate_offset_imm (value, 0)) == FAIL) + { + as_bad (_("bad immediate value for offset (%d)"), val); + break; + } + if (value < 0) + value = -value; + + 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 = 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\n")); + else + as_bad (_("bad immediate value for offset (%d)"), value); + break; + } + + if (value < 0) + value = -value; + + 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 ((value = validate_offset_imm (value, 0)) == FAIL) + { + as_bad_where (fixP->fx_file, fixP->fx_line, + _("invalid literal constant: pool needs to be closer\n")); + 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) + newval &= ~0x60; /* Shifts of zero must be done as lsl */ + 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); +#ifdef OBJ_ELF + newval &= 0xff000000; + if (! target_oabi) + value = fixP->fx_offset; + else +#else + value = (value >> 2) & 0x00ffffff; +#endif + value = (value + (newval & 0x00ffffff)) & 0x00ffffff; + newval = value | (newval & 0xff000000); + 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_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; + 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); + 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_GOTPC: + md_number_to_chars (buf, value, 4); + break; + + 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_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")); + + /* 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")); + newval |= value >> 2; + break; + + case 6: /* Word load/store */ + if (value & ~0x7c) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("Invalid offset")); + 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")); + newval |= value << 6; + break; + + case 8: /* Halfword load/store */ + if (value & ~0x3e) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("Invalid offset")); + newval |= value << 5; /* 6 - 1 */ + break; + + default: + as_bad_where (fixP->fx_file, fixP->fx_line, + "Unable to process relocation for thumb opcode: %x", 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%08X)"), 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: %d is too large"), 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: %d"), 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 1; + + case BFD_RELOC_NONE: + default: + as_bad_where (fixP->fx_file, fixP->fx_line, + _("Bad relocation fixup type (%d)\n"), fixP->fx_r_type); + } + + return 1; +} + +/* Translate internal representation of relocation info to BFD target + format. */ +arelent * +tc_gen_reloc (section, fixp) + asection * section; + fixS * fixp; +{ + arelent * reloc; + bfd_reloc_code_real_type code; + + reloc = (arelent *) xmalloc (sizeof (arelent)); + + reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym; + 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_RVA: + case BFD_RELOC_THUMB_PCREL_BRANCH9: + case BFD_RELOC_THUMB_PCREL_BRANCH12: + case BFD_RELOC_THUMB_PCREL_BRANCH23: + 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 boundry - possibly due to an implicit dump */ + as_bad_where (fixp->fx_file, fixp->fx_line, + _("Literal referenced across section boundry (Implicit dump?)")); + return NULL; + + case BFD_RELOC_ARM_GOTPC: + assert (fixp->fx_pcrel != 0); + code = fixp->fx_r_type; + code = BFD_RELOC_32_PCREL; + break; + +#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 %d) not fixed up (IMMEDIATE)"), + fixp->fx_r_type); + return NULL; + + case BFD_RELOC_ARM_OFFSET_IMM: + as_bad_where (fixp->fx_file, fixp->fx_line, + _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"), + fixp->fx_r_type); + return NULL; + + default: + { + char * type; + switch (fixp->fx_r_type) + { + case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break; + case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break; + 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 = ""; break; + } + as_bad_where (fixp->fx_file, fixp->fx_line, + _("Can not represent %s relocation in this object file format (%d)"), + type, fixp->fx_pcrel); + return NULL; + } + } + +#ifdef OBJ_ELF + if (code == BFD_RELOC_32_PCREL + && GOT_symbol + && fixp->fx_addsy == GOT_symbol) + code = BFD_RELOC_ARM_GOTPC; +#endif + + 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)); + return NULL; + } + + return reloc; +} + +int +md_estimate_size_before_relax (fragP, segtype) + fragS * fragP; + segT segtype; +{ + as_fatal (_("md_estimate_size_before_relax\n")); + return 1; +} + +static void +output_inst (str) + char * str; +{ + char * to = NULL; + + if (inst.error) + { + as_bad (inst.error); + 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 + 2, inst.instruction, THUMB_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); + + return; +} + +void +md_assemble (str) + char * str; +{ + char c; + char * p; + char * q; + char * start; + + /* Align the instruction. + This may not be the right thing to do but ... */ + /* arm_align (2, 0); */ + listing_prev_line (); /* Defined in listing.h */ + + /* Align the previous label if needed. */ + if (last_label_seen != NULL) + { + last_label_seen->sy_frag = 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; + + if (*str == ' ') + str++; /* Skip leading white space */ + + /* 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) + { + inst.instruction = opcode->value; + inst.size = opcode->size; + (*opcode->parms)(p); + output_inst (start); + return; + } + } + else + { + CONST struct asm_opcode *opcode; + + inst.size = INSN_SIZE; + /* p now points to the end of the opcode, probably white space, but we + have to break the opcode up in case it contains condionals and flags; + keep trying with progressively smaller basic instructions until one + matches, or we run out of opcode. */ + q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p; + for (; q != str; q--) + { + c = *q; + *q = '\0'; + opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str); + *q = c; + if (opcode && opcode->template) + { + unsigned long flag_bits = 0; + char *r; + + /* Check that this instruction is supported for this CPU */ + if ((opcode->variants & cpu_variant) == 0) + goto try_shorter; + + inst.instruction = opcode->value; + if (q == p) /* Just a simple opcode */ + { + if (opcode->comp_suffix != 0) + as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str, + opcode->comp_suffix); + else + { + inst.instruction |= COND_ALWAYS; + (*opcode->parms)(q, 0); + } + output_inst (start); + return; + } + + /* Now check for a conditional */ + r = q; + if (p - r >= 2) + { + CONST struct asm_cond *cond; + char d = *(r + 2); + + *(r + 2) = '\0'; + cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r); + *(r + 2) = d; + if (cond) + { + if (cond->value == 0xf0000000) + as_tsktsk ( +_("Warning: Use of the 'nv' conditional is deprecated\n")); + + inst.instruction |= cond->value; + r += 2; + } + else + inst.instruction |= COND_ALWAYS; + } + else + inst.instruction |= COND_ALWAYS; + + /* if there is a compulsory suffix, it should come here, before + any optional flags. */ + if (opcode->comp_suffix) + { + CONST char *s = opcode->comp_suffix; + + while (*s) + { + inst.suffix++; + if (*r == *s) + break; + s++; + } + + if (*s == '\0') + { + as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str, + opcode->comp_suffix); + return; + } + + r++; + } + + /* The remainder, if any should now be flags for the instruction; + Scan these checking each one found with the opcode. */ + if (r != p) + { + char d; + CONST struct asm_flg *flag = opcode->flags; + + if (flag) + { + int flagno; + + d = *p; + *p = '\0'; + + for (flagno = 0; flag[flagno].template; flagno++) + { + if (streq (r, flag[flagno].template)) + { + flag_bits |= flag[flagno].set_bits; + break; + } + } + + *p = d; + if (! flag[flagno].template) + goto try_shorter; + } + else + goto try_shorter; + } + + (*opcode->parms) (p, flag_bits); + output_inst (start); + return; + } + + try_shorter: + ; + } + } + + /* It wasn't an instruction, but it might be a register alias of the form + alias .req reg + */ + q = p; + while (*q == ' ') + q++; + + c = *p; + *p = '\0'; + + if (*q && !strncmp (q, ".req ", 4)) + { + int reg; + char * copy_of_str = str; + char * r; + + q += 4; + while (*q == ' ') + q++; + + for (r = q; *r != '\0'; r++) + if (*r == ' ') + break; + + if (r != q) + { + int regnum; + char d = *r; + + *r = '\0'; + regnum = arm_reg_parse (& q); + *r = d; + + reg = arm_reg_parse (& str); + + if (reg == FAIL) + { + if (regnum != FAIL) + { + insert_reg_alias (str, regnum); + } + else + { + as_warn (_("register '%s' does not exist\n"), q); + } + } + else if (regnum != FAIL) + { + if (reg != regnum) + as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str ); + + /* Do not warn abpout redefinitions to the same alias. */ + } + else + as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"), + copy_of_str, q); + } + else + as_warn (_("ignoring incomplete .req pseuso op")); + + *p = c; + return; + } + + *p = c; + 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. These are: + * 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 + * -mstrongarm[110] Arm 8 processors + * -mall All (except the ARM1) + * FP variants: + * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions + * -mfpe-old (No float load/store multiples) + * -mno-fpu Disable all floating point instructions + * Run-time endian selection: + * -EB big endian cpu + * -EL little endian cpu + * ARM Procedure Calling Standard: + * -mapcs-32 32 bit APCS + * -mapcs-26 26 bit APCS + * -mapcs-float Pass floats in float regs + * -mapcs-reentrant Position independent code + * -mthumb-interwork Code supports Arm/Thumb interworking + * -moabi Old ELF ABI + */ + +CONST char * md_shortopts = "m:k"; +struct option md_longopts[] = +{ +#ifdef ARM_BI_ENDIAN +#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}, +#ifdef OBJ_ELF +#define OPTION_OABI (OPTION_MD_BASE +2) + {"oabi", no_argument, NULL, OPTION_OABI}, +#endif +#endif + {NULL, no_argument, NULL, 0} +}; +size_t md_longopts_size = sizeof (md_longopts); + +int +md_parse_option (c, arg) + int c; + char * arg; +{ + char * str = arg; + + switch (c) + { +#ifdef ARM_BI_ENDIAN + case OPTION_EB: + target_big_endian = 1; + break; + case OPTION_EL: + target_big_endian = 0; + break; +#endif + + case 'm': + switch (*str) + { + case 'f': + if (streq (str, "fpa10")) + cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10; + else if (streq (str, "fpa11")) + cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11; + else if (streq (str, "fpe-old")) + cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE; + else + goto bad; + break; + + case 'n': + if (streq (str, "no-fpu")) + cpu_variant &= ~FPU_ALL; + break; + +#ifdef OBJ_ELF + case 'o': + if (streq (str, "oabi")) + target_oabi = true; + break; +#endif + + case 't': + /* Limit assembler to generating only Thumb instructions: */ + if (streq (str, "thumb")) + { + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB; + cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE; + thumb_mode = 1; + } + else if (streq (str, "thumb-interwork")) + { + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB | ARM_ARCHv4; +#if defined OBJ_COFF || defined OBJ_ELF + support_interwork = true; +#endif + } + else + goto bad; + break; + + default: + if (streq (str, "all")) + { + cpu_variant = ARM_ALL | FPU_ALL; + return 1; + } +#if defined OBJ_COFF || defined OBJ_ELF + if (! strncmp (str, "apcs-", 5)) + { + /* GCC passes on all command line options starting "-mapcs-..." + to us, so we must parse them here. */ + + str += 5; + + if (streq (str, "32")) + { + uses_apcs_26 = false; + return 1; + } + else if (streq (str, "26")) + { + uses_apcs_26 = true; + return 1; + } + else if (streq (str, "frame")) + { + /* Stack frames are being generated - does not affect + linkage of code. */ + return 1; + } + else if (streq (str, "stack-check")) + { + /* Stack checking is being performed - does not affect + linkage, but does require that the functions + __rt_stkovf_split_small and __rt_stkovf_split_big be + present in the final link. */ + + return 1; + } + else if (streq (str, "float")) + { + /* Floating point arguments are being passed in the floating + point registers. This does affect linking, since this + version of the APCS is incompatible with the version that + passes floating points in the integer registers. */ + + uses_apcs_float = true; + return 1; + } + else if (streq (str, "reentrant")) + { + /* Reentrant code has been generated. This does affect + linking, since there is no point in linking reentrant/ + position independent code with absolute position code. */ + pic_code = true; + return 1; + } + + as_bad (_("Unrecognised APCS switch -m%s"), arg); + return 0; + } +#endif + /* Strip off optional "arm" */ + if (! strncmp (str, "arm", 3)) + str += 3; + + switch (*str) + { + case '1': + if (streq (str, "1")) + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1; + else + goto bad; + break; + + case '2': + if (streq (str, "2")) + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; + else if (streq (str, "250")) + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250; + else + goto bad; + break; + + case '3': + if (streq (str, "3")) + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; + else + goto bad; + break; + + case '6': + switch (strtol (str, NULL, 10)) + { + case 6: + case 60: + case 600: + case 610: + case 620: + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6; + break; + default: + goto bad; + } + break; + + case '7': + switch (strtol (str, & str, 10)) /* Eat the processor name */ + { + case 7: + case 70: + case 700: + case 710: + case 7100: + case 7500: + break; + default: + goto bad; + } + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7; + for (; *str; str++) + { + switch (* str) + { + case 't': + cpu_variant |= (ARM_THUMB | ARM_ARCHv4); + break; + + case 'm': + cpu_variant |= ARM_LONGMUL; + break; + + case 'f': /* fe => fp enabled cpu. */ + if (str[1] == 'e') + ++ str; + else + goto bad; + + case 'c': /* Left over from 710c processor name. */ + case 'd': /* Debug */ + case 'i': /* Embedded ICE */ + /* Included for completeness in ARM processor naming. */ + break; + + default: + goto bad; + } + } + break; + + case '8': + if (streq (str, "8") || streq (str, "810")) + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCHv4 | ARM_LONGMUL; + else + goto bad; + break; + + case '9': + if (streq (str, "9")) + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCHv4 | ARM_LONGMUL; + else if (streq (str, "9tdmi")) + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCHv4 | ARM_LONGMUL | ARM_THUMB; + else + goto bad; + break; + + case 's': + if (streq (str, "strongarm") + || streq (str, "strongarm110") + || streq (str, "strongarm1100")) + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCHv4 | ARM_LONGMUL; + else + goto bad; + break; + + case 'v': + /* Select variant based on architecture rather than processor */ + switch (*++str) + { + case '2': + switch (*++str) + { + case 'a': cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; break; + case 0: cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; break; + default: as_bad (_("Invalid architecture variant -m%s"), arg); break; + } + break; + + case '3': + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7; + + switch (*++str) + { + case 'm': cpu_variant |= ARM_LONGMUL; break; + case 0: break; + default: as_bad (_("Invalid architecture variant -m%s"), arg); break; + } + break; + + case '4': + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCHv4; + + switch (*++str) + { + case 't': cpu_variant |= ARM_THUMB; break; + case 0: break; + default: as_bad (_("Invalid architecture variant -m%s"), arg); break; + } + break; + + default: + as_bad (_("Invalid architecture variant -m%s"), arg); + break; + } + break; + + default: + bad: + as_bad (_("Invalid processor variant -m%s"), arg); + return 0; + } + } + break; + + case 'k': + pic_code = 1; + break; + + default: + return 0; + } + + return 1; +} + +void +md_show_usage (fp) + FILE * fp; +{ + fprintf (fp, +_("\ + ARM Specific Assembler Options:\n\ + -m[arm][] select processor variant\n\ + -m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\ + -mthumb only allow Thumb instructions\n\ + -mthumb-interwork mark the assembled code as supporting interworking\n\ + -mall allow any instruction\n\ + -mfpa10, -mfpa11 select floating point architecture\n\ + -mfpe-old don't allow floating-point multiple instructions\n\ + -mno-fpu don't allow any floating-point instructions.\n")); + fprintf (fp, +_("\ + -k generate PIC code.\n")); +#if defined OBJ_COFF || defined OBJ_ELF + fprintf (fp, +_("\ + -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n")); + fprintf (fp, +_("\ + -mapcs-float floating point args are passed in FP regs\n")); + fprintf (fp, +_("\ + -mapcs-reentrant the code is position independent/reentrant\n")); + #endif +#ifdef OBJ_ELF + fprintf (fp, +_("\ + -moabi support the old ELF ABI\n")); +#endif +#ifdef ARM_BI_ENDIAN + fprintf (fp, +_("\ + -EB assemble code for a big endian cpu\n\ + -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; + + return; +} + + +/* + * This fix_new is called by cons via TC_CONS_FIX_NEW + * + * We check the expression to see if it is of the form + * __GLOBAL_OFFSET_TABLE + ??? + * If it is then this is a PC relative reference to the GOT. + * i.e. + * ldr sl, L1 + * add sl, pc, sl + * L2: + * ... + * L1: + * .word __GLOBAL_OFFSET_TABLE + (. - (L2 + 4)) + * + * In this case use a reloc type BFD_RELOC_ARM_GOTPC instead of the + * normal BFD_RELOC_{16,32,64} + */ + +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 ... + * + * @@ Should look at CPU word size. + */ + switch (size) + { + case 2: + type = BFD_RELOC_16; + break; + case 4: + default: + type = BFD_RELOC_32; + break; + case 8: + type = BFD_RELOC_64; + break; + } + + /* Look for possible GOTPC reloc */ + + /* + * Look for pic assembler and 'undef symbol + expr symbol' expression + * and a 32 bit size. + */ + + 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 () +{ + if (current_poolP != NULL) + { + subseg_set (text_section, 0); /* Put it at the end of text section */ + s_ltorg (0); + listing_prev_line (); + } +} + +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 + + if (label_is_thumb_function_name) + { + /* 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(sym->bsym)->native->u.syment.n_flags = 0xFF; + } +#endif +#ifdef OBJ_ELF + symbolS * sym; + elf_symbol_type * elf_sym; + char bind; + + for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym)) + { + if (ARM_IS_THUMB (sym)) + { + if (THUMB_IS_FUNC (sym)) + { + elf_sym = elf_symbol (sym->bsym); + bind = ELF_ST_BIND (elf_sym); + elf_sym->internal_elf_sym.st_info = ELF_ST_INFO (bind, STT_ARM_TFUNC); + } + } + } +#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; +} + +boolean +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); + return true; + } + + return false; +} + +#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. */ + +boolean +arm_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; + + if (S_IS_WEAK (fixP->fx_addsy)) + return 0; + + 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; + + 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); +} + +int +arm_force_relocation (fixp) + struct fix * fixp; +{ + if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT + || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY + || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH) + return 1; + + return 0; +} + +static bfd_reloc_code_real_type +arm_parse_reloc () +{ + char id[16]; + char * ip; + 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 + + 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++ == ','); + + input_line_pointer--; /* Put terminator back into stream. */ + demand_empty_rest_of_line (); +} + +#endif /* OBJ_ELF */ + diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h new file mode 100644 index 0000000000..bf99e243b5 --- /dev/null +++ b/gas/config/tc-arm.h @@ -0,0 +1,204 @@ +/* This file is tc-arm.h + Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 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 + +#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 +#endif /* OBJ_AOUT */ + +#ifdef OBJ_AIF +#define TARGET_FORMAT "aif" +#endif + +#if defined OBJ_COFF || defined OBJ_ELF +# define ARM_BI_ENDIAN + +# define TC_VALIDATE_FIX(fixP, segType, Label) \ + if (arm_validate_fix (fixP)) add_symbolP = fixP->fx_addsy + extern boolean arm_validate_fix PARAMS ((struct fix *)); +#endif + +#ifdef OBJ_COFF +# if defined TE_PE +# define TC_FORCE_RELOCATION(x) ((x)->fx_r_type == BFD_RELOC_RVA) +# ifdef 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 +#endif + +#ifdef OBJ_ELF +# define TARGET_FORMAT elf32_arm_target_format() + extern const char * elf32_arm_target_format PARAMS ((void)); + +# define TC_FORCE_RELOCATION(fixp) arm_force_relocation (fixp) + extern int arm_force_relocation PARAMS ((struct fix *)); +#endif + +#define md_convert_frag(b, s, f) {as_fatal (_("arm convert_frag\n"));} + +#define md_cleanup() arm_cleanup () + extern void arm_cleanup PARAMS ((void)); + +#define md_start_line_hook() arm_start_line_hook () + extern void arm_start_line_hook PARAMS ((void)); + +#define tc_frob_label(S) arm_frob_label (S) + extern void arm_frob_label PARAMS ((struct symbol *)); + +/* 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. */ + +#ifdef OBJ_ELF +#define obj_fix_adjustable(fixP) arm_fix_adjustable (fixP) +#else +#define obj_fix_adjustable(fixP) 0 +#endif + +/* We need to keep some local information on symbols. */ + +#define TC_SYMFIELD_TYPE unsigned int +#define ARM_GET_FLAG(s) ((s)->sy_tc) +#define ARM_SET_FLAG(s,v) ((s)->sy_tc |= (v)) +#define ARM_RESET_FLAG(s,v) ((s)->sy_tc &= ~(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 suppports 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_FIX_TYPE PTR +#define TC_INIT_FIX_DATA(FIXP) ((FIXP)->tc_fix_data = NULL) + +#define TC_START_LABEL(C,STR) \ + (c == ':' || (c == '/' && arm_data_in_code ())) +int arm_data_in_code PARAMS ((void)); + +#define tc_canonicalize_symbol_name(str) \ + arm_canonicalize_symbol_name (str); +char * arm_canonicalize_symbol_name PARAMS ((char *)); + +#define obj_adjust_symtab() arm_adjust_symtab () + extern void arm_adjust_symtab PARAMS ((void)); + +#ifdef OBJ_ELF +#define obj_frob_symbol(sym, punt) armelf_frob_symbol (sym, punt) +#endif + +#define tc_aout_pre_write_hook(x) {;} /* not used */ + +#define LISTING_HEADER "ARM GAS " + +#define OPTIONAL_REGISTER_PREFIX '%' + +#define md_operand(x) + +#define TC_HANDLES_FX_DONE + +#define MD_APPLY_FIX3 + +#define LOCAL_LABEL(name) (name[0] == '.' && (name[1] == 'L')) +#define LOCAL_LABELS_FB 1 + +/* 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. */ + +#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ + ( (FIX)->fx_r_type != BFD_RELOC_ARM_GOT12 \ + && (FIX)->fx_r_type != BFD_RELOC_ARM_GOT32 \ + && (FIX)->fx_r_type != BFD_RELOC_32) + +#define TC_CONS_FIX_NEW cons_fix_new_arm + extern void cons_fix_new_arm PARAMS ((fragS *, int, int, expressionS *)); + +/* Don't allow symbols to be discarded on GOT related relocs, + nor on globals. */ +#define tc_fix_adjustable(x) (\ + ((x)->fx_r_type == BFD_RELOC_ARM_PLT32 \ + || (x)->fx_r_type == BFD_RELOC_ARM_GOT32 \ + || (x)->fx_r_type == BFD_RELOC_ARM_GOTOFF \ + || S_IS_EXTERN ((x)->fx_addsy) \ + || S_IS_WEAK ((x)->fx_addsy)) ? 0 : 1) + +#ifdef OBJ_ELF +#define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_" +#else +#define GLOBAL_OFFSET_TABLE_NAME "__GLOBAL_OFFSET_TABLE_" +#endif + +/* end of tc-arm.h */ diff --git a/gas/config/tc-d10v.c b/gas/config/tc-d10v.c new file mode 100644 index 0000000000..cf38f3e1e7 --- /dev/null +++ b/gas/config/tc-d10v.c @@ -0,0 +1,1636 @@ +/* tc-d10v.c -- Assembler code for the Mitsubishi D10V + + Copyright (C) 1996, 1997, 1998 Free Software Foundation. + + 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 +#include +#include "as.h" +#include "subsegs.h" +#include "opcode/d10v.h" +#include "elf/ppc.h" + +const char comment_chars[] = ";"; +const char line_comment_chars[] = "#"; +const char line_separator_chars[] = ""; +const char *md_shortopts = "O"; +const char EXP_CHARS[] = "eE"; +const char FLT_CHARS[] = "dD"; + +int Optimizing = 0; + +#define AT_WORD_P(X) ((X)->X_op == O_right_shift \ + && (X)->X_op_symbol != NULL \ + && (X)->X_op_symbol->sy_value.X_op == O_constant \ + && (X)->X_op_symbol->sy_value.X_add_number == AT_WORD_RIGHT_SHIFT) +#define AT_WORD_RIGHT_SHIFT 2 + + +/* fixups */ +#define MAX_INSN_FIXUPS (5) +struct d10v_fixup +{ + expressionS exp; + int operand; + int pcrel; + int size; + bfd_reloc_code_real_type reloc; +}; + +typedef struct _fixups +{ + int fc; + struct d10v_fixup fix[MAX_INSN_FIXUPS]; + struct _fixups *next; +} Fixups; + +static Fixups FixUps[2]; +static Fixups *fixups; + +/* True if instruction swapping warnings should be inhibited. */ +static unsigned char flag_warn_suppress_instructionswap; /* --nowarnswap */ + +/* local functions */ +static int reg_name_search PARAMS ((char *name)); +static int register_name PARAMS ((expressionS *expressionP)); +static int check_range PARAMS ((unsigned long num, int bits, int flags)); +static int postfix PARAMS ((char *p)); +static bfd_reloc_code_real_type get_reloc PARAMS ((struct d10v_operand *op)); +static int get_operands PARAMS ((expressionS exp[])); +static struct d10v_opcode *find_opcode PARAMS ((struct d10v_opcode *opcode, expressionS ops[])); +static unsigned long build_insn PARAMS ((struct d10v_opcode *opcode, expressionS *opers, unsigned long insn)); +static void write_long PARAMS ((struct d10v_opcode *opcode, unsigned long insn, Fixups *fx)); +static void write_1_short PARAMS ((struct d10v_opcode *opcode, unsigned long insn, Fixups *fx)); +static int write_2_short PARAMS ((struct d10v_opcode *opcode1, unsigned long insn1, + struct d10v_opcode *opcode2, unsigned long insn2, int exec_type, Fixups *fx)); +static unsigned long do_assemble PARAMS ((char *str, struct d10v_opcode **opcode)); +static unsigned long d10v_insert_operand PARAMS (( unsigned long insn, int op_type, + offsetT value, int left, fixS *fix)); +static int parallel_ok PARAMS ((struct d10v_opcode *opcode1, unsigned long insn1, + struct d10v_opcode *opcode2, unsigned long insn2, + int exec_type)); +static symbolS * find_symbol_matching_register PARAMS ((expressionS *)); + +struct option md_longopts[] = +{ +#define OPTION_NOWARNSWAP (OPTION_MD_BASE) + {"nowarnswap", no_argument, NULL, OPTION_NOWARNSWAP}, + {NULL, no_argument, NULL, 0} +}; +size_t md_longopts_size = sizeof(md_longopts); + +static void d10v_dot_word PARAMS ((int)); + +/* The target specific pseudo-ops which we support. */ +const pseudo_typeS md_pseudo_table[] = +{ + { "word", d10v_dot_word, 2 }, + { NULL, NULL, 0 } +}; + +/* Opcode hash table. */ +static struct hash_control *d10v_hash; + +/* reg_name_search does a binary search of the d10v_predefined_registers + array to see if "name" is a valid regiter name. Returns the register + number from the array on success, or -1 on failure. */ + +static int +reg_name_search (name) + char *name; +{ + int middle, low, high; + int cmp; + + low = 0; + high = d10v_reg_name_cnt() - 1; + + do + { + middle = (low + high) / 2; + cmp = strcasecmp (name, d10v_predefined_registers[middle].name); + if (cmp < 0) + high = middle - 1; + else if (cmp > 0) + low = middle + 1; + else + return d10v_predefined_registers[middle].value; + } + while (low <= high); + return -1; +} + +/* register_name() checks the string at input_line_pointer + to see if it is a valid register name */ + +static int +register_name (expressionP) + expressionS *expressionP; +{ + int reg_number; + char c, *p = input_line_pointer; + + while (*p && *p!='\n' && *p!='\r' && *p !=',' && *p!=' ' && *p!=')') + p++; + + c = *p; + if (c) + *p++ = 0; + + /* look to see if it's in the register table */ + reg_number = reg_name_search (input_line_pointer); + if (reg_number >= 0) + { + expressionP->X_op = O_register; + /* temporarily store a pointer to the string here */ + expressionP->X_op_symbol = (struct symbol *)input_line_pointer; + expressionP->X_add_number = reg_number; + input_line_pointer = p; + return 1; + } + if (c) + *(p-1) = c; + return 0; +} + + +static int +check_range (num, bits, flags) + unsigned long num; + int bits; + int flags; +{ + long min, max, bit1; + int retval=0; + + /* don't bother checking 16-bit values */ + if (bits == 16) + return 0; + + if (flags & OPERAND_SHIFT) + { + /* all special shift operands are unsigned */ + /* and <= 16. We allow 0 for now. */ + if (num>16) + return 1; + else + return 0; + } + + if (flags & OPERAND_SIGNED) + { + max = (1 << (bits - 1))-1; + min = - (1 << (bits - 1)); + if (((long)num > max) || ((long)num < min)) + retval = 1; + } + else + { + max = (1 << bits) - 1; + min = 0; + if ((num > max) || (num < min)) + retval = 1; + } + return retval; +} + + +void +md_show_usage (stream) + FILE *stream; +{ + fprintf(stream, _("D10V options:\n\ +-O optimize. Will do some operations in parallel.\n")); +} + +int +md_parse_option (c, arg) + int c; + char *arg; +{ + switch (c) + { + case 'O': + /* Optimize. Will attempt to parallelize operations */ + Optimizing = 1; + break; + case OPTION_NOWARNSWAP: + flag_warn_suppress_instructionswap = 1; + break; + default: + return 0; + } + return 1; +} + +symbolS * +md_undefined_symbol (name) + char *name; +{ + return 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; +} + +void +md_convert_frag (abfd, sec, fragP) + bfd *abfd; + asection *sec; + fragS *fragP; +{ + 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 = ""; + struct d10v_opcode *opcode; + d10v_hash = hash_new(); + + /* Insert unique names into hash table. The D10v 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. */ + + for (opcode = (struct d10v_opcode *)d10v_opcodes; opcode->name; opcode++) + { + if (strcmp (prev_name, opcode->name)) + { + prev_name = (char *)opcode->name; + hash_insert (d10v_hash, opcode->name, (char *) opcode); + } + } + + fixups = &FixUps[0]; + FixUps[0].next = &FixUps[1]; + FixUps[1].next = &FixUps[0]; +} + + +/* this function removes the postincrement or postdecrement + operator ( '+' or '-' ) from an expression */ + +static int postfix (p) + char *p; +{ + while (*p != '-' && *p != '+') + { + if (*p==0 || *p=='\n' || *p=='\r') + break; + p++; + } + + if (*p == '-') + { + *p = ' '; + return (-1); + } + if (*p == '+') + { + *p = ' '; + return (1); + } + + return (0); +} + + +static bfd_reloc_code_real_type +get_reloc (op) + struct d10v_operand *op; +{ + int bits = op->bits; + + if (bits <= 4) + return (0); + + if (op->flags & OPERAND_ADDR) + { + if (bits == 8) + return (BFD_RELOC_D10V_10_PCREL_R); + else + return (BFD_RELOC_D10V_18_PCREL); + } + + return (BFD_RELOC_16); +} + + +/* get_operands parses a string of operands and returns + an array of expressions */ + +static int +get_operands (exp) + expressionS exp[]; +{ + char *p = input_line_pointer; + int numops = 0; + int post = 0; + + while (*p) + { + while (*p == ' ' || *p == '\t' || *p == ',') + p++; + if (*p==0 || *p=='\n' || *p=='\r') + break; + + if (*p == '@') + { + p++; + exp[numops].X_op = O_absent; + if (*p == '(') + { + p++; + exp[numops].X_add_number = OPERAND_ATPAR; + } + else if (*p == '-') + { + p++; + exp[numops].X_add_number = OPERAND_ATMINUS; + } + else + { + exp[numops].X_add_number = OPERAND_ATSIGN; + post = postfix (p); + } + numops++; + continue; + } + + if (*p == ')') + { + /* just skip the trailing paren */ + p++; + continue; + } + + input_line_pointer = p; + + /* check to see if it might be a register name */ + if (!register_name (&exp[numops])) + { + /* parse as an expression */ + expression (&exp[numops]); + } + + if (strncasecmp (input_line_pointer, "@word", 5) == 0) + { + input_line_pointer += 5; + if (exp[numops].X_op == O_register) + { + /* if it looked like a register name but was followed by + "@word" then it was really a symbol, so change it to + one */ + exp[numops].X_op = O_symbol; + exp[numops].X_add_symbol = symbol_find_or_make ((char *)exp[numops].X_op_symbol); + } + + /* check for identifier@word+constant */ + if (*input_line_pointer == '-' || *input_line_pointer == '+') + { + char *orig_line = input_line_pointer; + expressionS new_exp; + expression (&new_exp); + exp[numops].X_add_number = new_exp.X_add_number; + } + + /* convert expr into a right shift by AT_WORD_RIGHT_SHIFT */ + { + expressionS new_exp; + memset (&new_exp, 0, sizeof new_exp); + new_exp.X_add_number = AT_WORD_RIGHT_SHIFT; + new_exp.X_op = O_constant; + new_exp.X_unsigned = 1; + exp[numops].X_op_symbol = make_expr_symbol (&new_exp); + exp[numops].X_op = O_right_shift; + } + + know (AT_WORD_P (&exp[numops])); + } + + if (exp[numops].X_op == O_illegal) + as_bad (_("illegal operand")); + else if (exp[numops].X_op == O_absent) + as_bad (_("missing operand")); + + numops++; + p = input_line_pointer; + } + + switch (post) + { + case -1: /* postdecrement mode */ + exp[numops].X_op = O_absent; + exp[numops++].X_add_number = OPERAND_MINUS; + break; + case 1: /* postincrement mode */ + exp[numops].X_op = O_absent; + exp[numops++].X_add_number = OPERAND_PLUS; + break; + } + + exp[numops].X_op = 0; + return (numops); +} + +static unsigned long +d10v_insert_operand (insn, op_type, value, left, fix) + unsigned long insn; + int op_type; + offsetT value; + int left; + fixS *fix; +{ + int shift, bits; + + shift = d10v_operands[op_type].shift; + if (left) + shift += 15; + + bits = d10v_operands[op_type].bits; + + /* truncate to the proper number of bits */ + if (check_range (value, bits, d10v_operands[op_type].flags)) + as_bad_where (fix->fx_file, fix->fx_line, _("operand out of range: %d"), value); + + value &= 0x7FFFFFFF >> (31 - bits); + insn |= (value << shift); + + return insn; +} + + +/* build_insn takes a pointer to the opcode entry in the opcode table + and the array of operand expressions and returns the instruction */ + +static unsigned long +build_insn (opcode, opers, insn) + struct d10v_opcode *opcode; + expressionS *opers; + unsigned long insn; +{ + int i, bits, shift, flags, format; + unsigned long number; + + /* the insn argument is only used for the DIVS kludge */ + if (insn) + format = LONG_R; + else + { + insn = opcode->opcode; + format = opcode->format; + } + + for (i=0;opcode->operands[i];i++) + { + flags = d10v_operands[opcode->operands[i]].flags; + bits = d10v_operands[opcode->operands[i]].bits; + shift = d10v_operands[opcode->operands[i]].shift; + number = opers[i].X_add_number; + + if (flags & OPERAND_REG) + { + number &= REGISTER_MASK; + if (format == LONG_L) + shift += 15; + } + + if (opers[i].X_op != O_register && opers[i].X_op != O_constant) + { + /* now create a fixup */ + + if (fixups->fc >= MAX_INSN_FIXUPS) + as_fatal (_("too many fixups")); + + if (AT_WORD_P (&opers[i])) + { + /* Reconize XXX>>1+N aka XXX@word+N as special (AT_WORD) */ + fixups->fix[fixups->fc].reloc = BFD_RELOC_D10V_18; + opers[i].X_op = O_symbol; + opers[i].X_op_symbol = NULL; /* Should free it */ + /* number is left shifted by AT_WORD_RIGHT_SHIFT so + that, it is aligned with the symbol's value. Later, + BFD_RELOC_D10V_18 will right shift (symbol_value + + X_add_number). */ + number <<= AT_WORD_RIGHT_SHIFT; + opers[i].X_add_number = number; + } + else + fixups->fix[fixups->fc].reloc = + get_reloc((struct d10v_operand *)&d10v_operands[opcode->operands[i]]); + + if (fixups->fix[fixups->fc].reloc == BFD_RELOC_16 || + fixups->fix[fixups->fc].reloc == BFD_RELOC_D10V_18) + fixups->fix[fixups->fc].size = 2; + else + fixups->fix[fixups->fc].size = 4; + + fixups->fix[fixups->fc].exp = opers[i]; + fixups->fix[fixups->fc].operand = opcode->operands[i]; + fixups->fix[fixups->fc].pcrel = (flags & OPERAND_ADDR) ? true : false; + (fixups->fc)++; + } + + /* truncate to the proper number of bits */ + if ((opers[i].X_op == O_constant) && check_range (number, bits, flags)) + as_bad (_("operand out of range: %d"),number); + number &= 0x7FFFFFFF >> (31 - bits); + insn = insn | (number << shift); + } + + /* kludge: for DIVS, we need to put the operands in twice */ + /* on the second pass, format is changed to LONG_R to force */ + /* the second set of operands to not be shifted over 15 */ + if ((opcode->opcode == OPCODE_DIVS) && (format==LONG_L)) + insn = build_insn (opcode, opers, insn); + + return insn; +} + +/* write out a long form instruction */ +static void +write_long (opcode, insn, fx) + struct d10v_opcode *opcode; + unsigned long insn; + Fixups *fx; +{ + int i, where; + char *f = frag_more(4); + + insn |= FM11; + number_to_chars_bigendian (f, insn, 4); + + for (i=0; i < fx->fc; i++) + { + if (fx->fix[i].reloc) + { + where = f - frag_now->fr_literal; + if (fx->fix[i].size == 2) + where += 2; + + if (fx->fix[i].reloc == BFD_RELOC_D10V_18) + fx->fix[i].operand |= 4096; + + fix_new_exp (frag_now, + where, + fx->fix[i].size, + &(fx->fix[i].exp), + fx->fix[i].pcrel, + fx->fix[i].operand|2048); + } + } + fx->fc = 0; +} + + +/* write out a short form instruction by itself */ +static void +write_1_short (opcode, insn, fx) + struct d10v_opcode *opcode; + unsigned long insn; + Fixups *fx; +{ + char *f = frag_more(4); + int i, where; + + if (opcode->exec_type & PARONLY) + as_fatal (_("Instruction must be executed in parallel with another instruction.")); + + /* the other container needs to be NOP */ + /* according to 4.3.1: for FM=00, sub-instructions performed only + by IU cannot be encoded in L-container. */ + if (opcode->unit == IU) + insn |= FM00 | (NOP << 15); /* right container */ + else + insn = FM00 | (insn << 15) | NOP; /* left container */ + + number_to_chars_bigendian (f, insn, 4); + for (i=0; i < fx->fc; i++) + { + if (fx->fix[i].reloc) + { + where = f - frag_now->fr_literal; + if (fx->fix[i].size == 2) + where += 2; + + if (fx->fix[i].reloc == BFD_RELOC_D10V_18) + fx->fix[i].operand |= 4096; + + /* if it's an R reloc, we may have to switch it to L */ + if ( (fx->fix[i].reloc == BFD_RELOC_D10V_10_PCREL_R) && (opcode->unit != IU) ) + fx->fix[i].operand |= 1024; + + fix_new_exp (frag_now, + where, + fx->fix[i].size, + &(fx->fix[i].exp), + fx->fix[i].pcrel, + fx->fix[i].operand|2048); + } + } + fx->fc = 0; +} + +/* write out a short form instruction if possible */ +/* return number of instructions not written out */ +static int +write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx) + struct d10v_opcode *opcode1, *opcode2; + unsigned long insn1, insn2; + int exec_type; + Fixups *fx; +{ + unsigned long insn; + char *f; + int i,j, where; + + if ( (exec_type != 1) && ((opcode1->exec_type & PARONLY) + || (opcode2->exec_type & PARONLY))) + as_fatal (_("Instruction must be executed in parallel")); + + if ( (opcode1->format & LONG_OPCODE) || (opcode2->format & LONG_OPCODE)) + as_fatal (_("Long instructions may not be combined.")); + + if(opcode1->exec_type & BRANCH_LINK && exec_type == 0) + { + /* Instructions paired with a subroutine call are executed before the + subroutine, so don't do these pairings unless explicitly requested. */ + write_1_short (opcode1, insn1, fx->next); + return (1); + } + + switch (exec_type) + { + case 0: /* order not specified */ + if ( Optimizing && parallel_ok (opcode1, insn1, opcode2, insn2, exec_type)) + { + /* parallel */ + if (opcode1->unit == IU) + insn = FM00 | (insn2 << 15) | insn1; + else if (opcode2->unit == MU) + insn = FM00 | (insn2 << 15) | insn1; + else + { + insn = FM00 | (insn1 << 15) | insn2; + fx = fx->next; + } + } + else if (opcode1->unit == IU) + { + /* reverse sequential */ + insn = FM10 | (insn2 << 15) | insn1; + } + else + { + /* sequential */ + insn = FM01 | (insn1 << 15) | insn2; + fx = fx->next; + } + break; + case 1: /* parallel */ + if (opcode1->exec_type & SEQ || opcode2->exec_type & SEQ) + as_fatal (_("One of these instructions may not be executed in parallel.")); + + if (opcode1->unit == IU) + { + if (opcode2->unit == IU) + as_fatal (_("Two IU instructions may not be executed in parallel")); + if (!flag_warn_suppress_instructionswap) + as_warn (_("Swapping instruction order")); + insn = FM00 | (insn2 << 15) | insn1; + } + else if (opcode2->unit == MU) + { + if (opcode1->unit == MU) + as_fatal (_("Two MU instructions may not be executed in parallel")); + if (!flag_warn_suppress_instructionswap) + as_warn (_("Swapping instruction order")); + insn = FM00 | (insn2 << 15) | insn1; + } + else + { + insn = FM00 | (insn1 << 15) | insn2; + fx = fx->next; + } + break; + case 2: /* sequential */ + if (opcode1->unit != IU) + insn = FM01 | (insn1 << 15) | insn2; + else if (opcode2->unit == MU || opcode2->unit == EITHER) + { + if (!flag_warn_suppress_instructionswap) + as_warn (_("Swapping instruction order")); + insn = FM10 | (insn2 << 15) | insn1; + } + else + as_fatal (_("IU instruction may not be in the left container")); + fx = fx->next; + break; + case 3: /* reverse sequential */ + if (opcode2->unit != MU) + insn = FM10 | (insn1 << 15) | insn2; + else if (opcode1->unit == IU || opcode1->unit == EITHER) + { + if (!flag_warn_suppress_instructionswap) + as_warn (_("Swapping instruction order")); + insn = FM01 | (insn2 << 15) | insn1; + } + else + as_fatal (_("MU instruction may not be in the right container")); + fx = fx->next; + break; + default: + as_fatal (_("unknown execution type passed to write_2_short()")); + } + + f = frag_more(4); + number_to_chars_bigendian (f, insn, 4); + + for (j=0; j<2; j++) + { + for (i=0; i < fx->fc; i++) + { + if (fx->fix[i].reloc) + { + where = f - frag_now->fr_literal; + if (fx->fix[i].size == 2) + where += 2; + + if ( (fx->fix[i].reloc == BFD_RELOC_D10V_10_PCREL_R) && (j == 0) ) + fx->fix[i].operand |= 1024; + + if (fx->fix[i].reloc == BFD_RELOC_D10V_18) + fx->fix[i].operand |= 4096; + + fix_new_exp (frag_now, + where, + fx->fix[i].size, + &(fx->fix[i].exp), + fx->fix[i].pcrel, + fx->fix[i].operand|2048); + } + } + fx->fc = 0; + fx = fx->next; + } + return (0); +} + + +/* Check 2 instructions and determine if they can be safely */ +/* executed in parallel. Returns 1 if they can be. */ +static int +parallel_ok (op1, insn1, op2, insn2, exec_type) + struct d10v_opcode *op1, *op2; + unsigned long insn1, insn2; + int exec_type; +{ + int i, j, flags, mask, shift, regno; + unsigned long ins, mod[2], used[2]; + struct d10v_opcode *op; + + if ((op1->exec_type & SEQ) != 0 || (op2->exec_type & SEQ) != 0 + || (op1->exec_type & PAR) == 0 || (op2->exec_type & PAR) == 0 + || (op1->unit == BOTH) || (op2->unit == BOTH) + || (op1->unit == IU && op2->unit == IU) + || (op1->unit == MU && op2->unit == MU)) + return 0; + + /* If the first instruction is a branch and this is auto parallazation, + don't combine with any second instruction. */ + if (exec_type == 0 && (op1->exec_type & BRANCH) != 0) + return 0; + + /* The idea here is to create two sets of bitmasks (mod and used) + which indicate which registers are modified or used by each + instruction. The operation can only be done in parallel if + instruction 1 and instruction 2 modify different registers, and + the first instruction does not modify registers that the second + is using (The second instruction can modify registers that the + first is using as they are only written back after the first + instruction has completed). Accesses to control registers, PSW, + and memory are treated as accesses to a single register. So if + both instructions write memory or if the first instruction writes + memory and the second reads, then they cannot be done in + parallel. Likewise, if the first instruction mucks with the psw + and the second reads the PSW (which includes C, F0, and F1), then + they cannot operate safely in parallel. */ + + /* the bitmasks (mod and used) look like this (bit 31 = MSB) */ + /* r0-r15 0-15 */ + /* a0-a1 16-17 */ + /* cr (not psw) 18 */ + /* psw 19 */ + /* mem 20 */ + + for (j=0;j<2;j++) + { + if (j == 0) + { + op = op1; + ins = insn1; + } + else + { + op = op2; + ins = insn2; + } + mod[j] = used[j] = 0; + if (op->exec_type & BRANCH_LINK) + mod[j] |= 1 << 13; + + for (i = 0; op->operands[i]; i++) + { + flags = d10v_operands[op->operands[i]].flags; + shift = d10v_operands[op->operands[i]].shift; + mask = 0x7FFFFFFF >> (31 - d10v_operands[op->operands[i]].bits); + if (flags & OPERAND_REG) + { + regno = (ins >> shift) & mask; + if (flags & (OPERAND_ACC0|OPERAND_ACC1)) + regno += 16; + else if (flags & OPERAND_CONTROL) /* mvtc or mvfc */ + { + if (regno == 0) + regno = 19; + else + regno = 18; + } + else if (flags & (OPERAND_FFLAG|OPERAND_CFLAG)) + regno = 19; + + if ( flags & OPERAND_DEST ) + { + mod[j] |= 1 << regno; + if (flags & OPERAND_EVEN) + mod[j] |= 1 << (regno + 1); + } + else + { + used[j] |= 1 << regno ; + if (flags & OPERAND_EVEN) + used[j] |= 1 << (regno + 1); + + /* Auto inc/dec also modifies the register. */ + if (op->operands[i+1] != 0 + && (d10v_operands[op->operands[i+1]].flags + & (OPERAND_PLUS | OPERAND_MINUS)) != 0) + mod[j] |= 1 << regno; + } + } + else if (flags & OPERAND_ATMINUS) + { + /* SP implicitly used/modified */ + mod[j] |= 1 << 15; + used[j] |= 1 << 15; + } + } + if (op->exec_type & RMEM) + used[j] |= 1 << 20; + else if (op->exec_type & WMEM) + mod[j] |= 1 << 20; + else if (op->exec_type & RF0) + used[j] |= 1 << 19; + else if (op->exec_type & WF0) + mod[j] |= 1 << 19; + else if (op->exec_type & WCAR) + mod[j] |= 1 << 19; + } + if ((mod[0] & mod[1]) == 0 && (mod[0] & used[1]) == 0) + return 1; + return 0; +} + + +/* This is the main entry point for the machine-dependent assembler. str points to a + machine-dependent instruction. This function is supposed to emit the frags/bytes + it assembles to. For the D10V, it mostly handles the special VLIW parsing and packing + and leaves the difficult stuff to do_assemble(). + */ + +static unsigned long prev_insn; +static struct d10v_opcode *prev_opcode = 0; +static subsegT prev_subseg; +static segT prev_seg = 0;; +static int etype = 0; /* saved extype. used for multiline instructions */ + +void +md_assemble (str) + char *str; +{ + struct d10v_opcode * opcode; + unsigned long insn; + int extype = 0; /* execution type; parallel, etc */ + char * str2; + + if (etype == 0) + { + /* look for the special multiple instruction separators */ + str2 = strstr (str, "||"); + if (str2) + extype = 1; + else + { + str2 = strstr (str, "->"); + if (str2) + extype = 2; + else + { + str2 = strstr (str, "<-"); + if (str2) + extype = 3; + } + } + /* str2 points to the separator, if one */ + if (str2) + { + *str2 = 0; + + /* if two instructions are present and we already have one saved + then first write it out */ + d10v_cleanup (); + + /* assemble first instruction and save it */ + prev_insn = do_assemble (str, &prev_opcode); + if (prev_insn == -1) + as_fatal (_("can't find opcode ")); + fixups = fixups->next; + str = str2 + 2; + } + } + + insn = do_assemble (str, &opcode); + if (insn == -1) + { + if (extype) + { + etype = extype; + return; + } + as_fatal (_("can't find opcode ")); + } + + if (etype) + { + extype = etype; + etype = 0; + } + + /* if this is a long instruction, write it and any previous short instruction */ + if (opcode->format & LONG_OPCODE) + { + if (extype) + as_fatal (_("Unable to mix instructions as specified")); + d10v_cleanup (); + write_long (opcode, insn, fixups); + prev_opcode = NULL; + return; + } + + if (prev_opcode && prev_seg && ((prev_seg != now_seg) || (prev_subseg != now_subseg))) + d10v_cleanup(); + + if (prev_opcode && (write_2_short (prev_opcode, prev_insn, opcode, insn, extype, fixups) == 0)) + { + /* no instructions saved */ + prev_opcode = NULL; + } + else + { + if (extype) + as_fatal (_("Unable to mix instructions as specified")); + /* save off last instruction so it may be packed on next pass */ + prev_opcode = opcode; + prev_insn = insn; + prev_seg = now_seg; + prev_subseg = now_subseg; + fixups = fixups->next; + } +} + + +/* do_assemble assembles a single instruction and returns an opcode */ +/* it returns -1 (an invalid opcode) on error */ + +static unsigned long +do_assemble (str, opcode) + char *str; + struct d10v_opcode **opcode; +{ + unsigned char *op_start, *save; + unsigned char *op_end; + char name[20]; + int nlen = 0; + expressionS myops[6]; + unsigned long insn; + + /* Drop leading whitespace. */ + while (*str == ' ') + str++; + + /* Find the opcode end. */ + for (op_start = op_end = (unsigned char *) (str); + *op_end + && nlen < 20 + && !is_end_of_line[*op_end] && *op_end != ' '; + op_end++) + { + name[nlen] = tolower (op_start[nlen]); + nlen++; + } + name[nlen] = 0; + + if (nlen == 0) + return -1; + + /* Find the first opcode with the proper name. */ + *opcode = (struct d10v_opcode *)hash_find (d10v_hash, name); + if (*opcode == NULL) + as_fatal (_("unknown opcode: %s"),name); + + save = input_line_pointer; + input_line_pointer = op_end; + *opcode = find_opcode (*opcode, myops); + if (*opcode == 0) + return -1; + input_line_pointer = save; + + insn = build_insn ((*opcode), myops, 0); + return (insn); +} + +/* Find the symbol which has the same name as the register in the given expression. */ +static symbolS * +find_symbol_matching_register (exp) + expressionS * exp; +{ + int i; + + if (exp->X_op != O_register) + return NULL; + + /* Find the name of the register. */ + for (i = d10v_reg_name_cnt (); i--;) + if (d10v_predefined_registers [i].value == exp->X_add_number) + break; + + if (i < 0) + abort (); + + /* Now see if a symbol has been defined with the same name. */ + return symbol_find (d10v_predefined_registers [i].name); +} + + +/* find_opcode() gets a pointer to an entry in the opcode table. */ +/* It must look at all opcodes with the same name and use the operands */ +/* to choose the correct opcode. */ + +static struct d10v_opcode * +find_opcode (opcode, myops) + struct d10v_opcode *opcode; + expressionS myops[]; +{ + int i, match, done; + struct d10v_opcode *next_opcode; + + /* get all the operands and save them as expressions */ + get_operands (myops); + + /* now see if the operand is a fake. If so, find the correct size */ + /* instruction, if possible */ + if (opcode->format == OPCODE_FAKE) + { + int opnum = opcode->operands[0]; + int flags; + + if (myops[opnum].X_op == O_register) + { + myops[opnum].X_op = O_symbol; + myops[opnum].X_add_symbol = symbol_find_or_make ((char *)myops[opnum].X_op_symbol); + myops[opnum].X_add_number = 0; + myops[opnum].X_op_symbol = NULL; + } + + next_opcode=opcode+1; + + /* If the first operand is supposed to be a register, make sure + we got a valid one. */ + flags = d10v_operands[next_opcode->operands[0]].flags; + if (flags & OPERAND_REG) + { + int X_op = myops[0].X_op; + int num = myops[0].X_add_number; + + if (X_op != O_register + || (num & ~flags + & (OPERAND_GPR | OPERAND_ACC0 | OPERAND_ACC1 + | OPERAND_FFLAG | OPERAND_CFLAG | OPERAND_CONTROL))) + { + as_bad (_("bad opcode or operands")); + return 0; + } + } + + if (myops[opnum].X_op == O_constant || (myops[opnum].X_op == O_symbol && + S_IS_DEFINED(myops[opnum].X_add_symbol) && + (S_GET_SEGMENT(myops[opnum].X_add_symbol) == now_seg))) + { + for (i=0; opcode->operands[i+1]; i++) + { + int bits = d10v_operands[next_opcode->operands[opnum]].bits; + int flags = d10v_operands[next_opcode->operands[opnum]].flags; + if (flags & OPERAND_ADDR) + bits += 2; + if (myops[opnum].X_op == O_constant) + { + if (!check_range (myops[opnum].X_add_number, bits, flags)) + return next_opcode; + } + else + { + fragS *f; + long value; + /* calculate the current address by running through the previous frags */ + /* and adding our current offset */ + for (value = 0, f = frchain_now->frch_root; f; f = f->fr_next) + value += f->fr_fix + f->fr_offset; + + if (flags & OPERAND_ADDR) + value = S_GET_VALUE(myops[opnum].X_add_symbol) - value - + (obstack_next_free(&frchain_now->frch_obstack) - frag_now->fr_literal); + else + value = S_GET_VALUE(myops[opnum].X_add_symbol); + + if (AT_WORD_P (&myops[opnum])) + { + if (bits > 4) + { + bits += 2; + if (!check_range (value, bits, flags)) + return next_opcode; + } + } + else if (!check_range (value, bits, flags)) + return next_opcode; + } + next_opcode++; + } + as_fatal (_("value out of range")); + } + else + { + /* not a constant, so use a long instruction */ + return opcode+2; + } + } + else + { + match = 0; + /* now search the opcode table table for one with operands */ + /* that matches what we've got */ + while (!match) + { + match = 1; + for (i = 0; opcode->operands[i]; i++) + { + int flags = d10v_operands[opcode->operands[i]].flags; + int X_op = myops[i].X_op; + int num = myops[i].X_add_number; + + if (X_op == 0) + { + match = 0; + break; + } + + if (flags & OPERAND_REG) + { + if ((X_op != O_register) + || (num & ~flags + & (OPERAND_GPR | OPERAND_ACC0 | OPERAND_ACC1 + | OPERAND_FFLAG | OPERAND_CFLAG + | OPERAND_CONTROL))) + { + match = 0; + break; + } + } + + if (((flags & OPERAND_MINUS) && ((X_op != O_absent) || (num != OPERAND_MINUS))) || + ((flags & OPERAND_PLUS) && ((X_op != O_absent) || (num != OPERAND_PLUS))) || + ((flags & OPERAND_ATMINUS) && ((X_op != O_absent) || (num != OPERAND_ATMINUS))) || + ((flags & OPERAND_ATPAR) && ((X_op != O_absent) || (num != OPERAND_ATPAR))) || + ((flags & OPERAND_ATSIGN) && ((X_op != O_absent) || (num != OPERAND_ATSIGN)))) + { + match = 0; + break; + } + + /* Unfortunatly, for the indirect operand in instructions such as + ``ldb r1, @(c,r14)'' this function can be passed X_op == O_register + (because 'c' is a valid register name). However we cannot just + ignore the case when X_op == O_register but flags & OPERAND_REG is + null, so we check to see if a symbol of the same name as the register + exists. If the symbol does exist, then the parser was unable to + distinguish the two cases and we fix things here. (Ref: PR14826) */ + + if (!(flags & OPERAND_REG) && (X_op == O_register)) + { + symbolS * sym; + + sym = find_symbol_matching_register (& myops[i]); + + if (sym != NULL) + { + myops [i].X_op == X_op == O_symbol; + myops [i].X_add_symbol = sym; + } + else + as_bad + (_("illegal operand - register name found where none expected")); + } + } + + /* We're only done if the operands matched so far AND there + are no more to check. */ + if (match && myops[i].X_op == 0) + break; + else + match = 0; + + next_opcode = opcode + 1; + + if (next_opcode->opcode == 0) + break; + + if (strcmp (next_opcode->name, opcode->name)) + break; + + opcode = next_opcode; + } + } + + if (!match) + { + as_bad (_("bad opcode or operands")); + return (0); + } + + /* Check that all registers that are required to be even are. */ + /* Also, if any operands were marked as registers, but were really symbols */ + /* fix that here. */ + for (i=0; opcode->operands[i]; i++) + { + if ((d10v_operands[opcode->operands[i]].flags & OPERAND_EVEN) && + (myops[i].X_add_number & 1)) + as_fatal (_("Register number must be EVEN")); + if (myops[i].X_op == O_register) + { + if (!(d10v_operands[opcode->operands[i]].flags & OPERAND_REG)) + { + myops[i].X_op = O_symbol; + myops[i].X_add_symbol = symbol_find_or_make ((char *)myops[i].X_op_symbol); + myops[i].X_add_number = 0; + myops[i].X_op_symbol = NULL; + } + } + } + return opcode; +} + +/* 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; + 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, + _("reloc %d not supported by object file format"), (int)fixp->fx_r_type); + return NULL; + } + + if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT + || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + reloc->address = fixp->fx_offset; + + reloc->addend = fixp->fx_addnumber; + + return reloc; +} + +int +md_estimate_size_before_relax (fragp, seg) + fragS *fragp; + asection *seg; +{ + abort (); + return 0; +} + +long +md_pcrel_from_section (fixp, sec) + fixS *fixp; + segT sec; +{ + if (fixp->fx_addsy != (symbolS *)NULL && (!S_IS_DEFINED (fixp->fx_addsy) || + (S_GET_SEGMENT (fixp->fx_addsy) != sec))) + return 0; + return fixp->fx_frag->fr_address + fixp->fx_where; +} + +int +md_apply_fix3 (fixp, valuep, seg) + fixS *fixp; + valueT *valuep; + segT seg; +{ + char *where; + unsigned long insn; + long value; + int op_type; + int left=0; + + if (fixp->fx_addsy == (symbolS *) NULL) + { + value = *valuep; + fixp->fx_done = 1; + } + else if (fixp->fx_pcrel) + value = *valuep; + 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")); + } + } + } + + op_type = fixp->fx_r_type; + if (op_type & 2048) + { + op_type -= 2048; + if (op_type & 1024) + { + op_type -= 1024; + fixp->fx_r_type = BFD_RELOC_D10V_10_PCREL_L; + left = 1; + } + else if (op_type & 4096) + { + op_type -= 4096; + fixp->fx_r_type = BFD_RELOC_D10V_18; + } + else + fixp->fx_r_type = get_reloc((struct d10v_operand *)&d10v_operands[op_type]); + } + + /* Fetch the instruction, insert the fully resolved operand + value, and stuff the instruction back again. */ + where = fixp->fx_frag->fr_literal + fixp->fx_where; + insn = bfd_getb32 ((unsigned char *) where); + + switch (fixp->fx_r_type) + { + case BFD_RELOC_D10V_10_PCREL_L: + case BFD_RELOC_D10V_10_PCREL_R: + case BFD_RELOC_D10V_18_PCREL: + case BFD_RELOC_D10V_18: + /* instruction addresses are always right-shifted by 2 */ + value >>= AT_WORD_RIGHT_SHIFT; + if (fixp->fx_size == 2) + bfd_putb16 ((bfd_vma) value, (unsigned char *) where); + else + { + struct d10v_opcode *rep, *repi; + + rep = (struct d10v_opcode *) hash_find (d10v_hash, "rep"); + repi = (struct d10v_opcode *) hash_find (d10v_hash, "repi"); + if ((insn & FM11) == FM11 + && (repi != NULL && (insn & repi->mask) == repi->opcode + || rep != NULL && (insn & rep->mask) == rep->opcode) + && value < 4) + as_fatal + (_("line %d: rep or repi must include at least 4 instructions"), + fixp->fx_line); + insn = d10v_insert_operand (insn, op_type, (offsetT)value, left, fixp); + bfd_putb32 ((bfd_vma) insn, (unsigned char *) where); + } + break; + case BFD_RELOC_32: + bfd_putb32 ((bfd_vma) value, (unsigned char *) where); + break; + case BFD_RELOC_16: + bfd_putb16 ((bfd_vma) value, (unsigned char *) where); + break; + + case BFD_RELOC_VTABLE_INHERIT: + case BFD_RELOC_VTABLE_ENTRY: + fixp->fx_done = 0; + return 1; + + default: + as_fatal (_("line %d: unknown relocation type: 0x%x"),fixp->fx_line,fixp->fx_r_type); + } + return 0; +} + +/* d10v_cleanup() is called after the assembler has finished parsing the input + file or after a label is defined. Because the D10V assembler sometimes saves short + instructions to see if it can package them with the next instruction, there may + be a short instruction that still needs written. */ +int +d10v_cleanup () +{ + segT seg; + subsegT subseg; + + if (prev_opcode && etype == 0) + { + seg = now_seg; + subseg = now_subseg; + if (prev_seg) + subseg_set (prev_seg, prev_subseg); + write_1_short (prev_opcode, prev_insn, fixups->next); + subseg_set (seg, subseg); + prev_opcode = NULL; + } + return 1; +} + +/* Like normal .word, except support @word */ +/* clobbers input_line_pointer, checks end-of-line. */ +static void +d10v_dot_word (nbytes) + register int nbytes; /* 1=.byte, 2=.word, 4=.long */ +{ + expressionS exp; + bfd_reloc_code_real_type reloc; + char *p; + int offset; + + if (is_it_end_of_statement ()) + { + demand_empty_rest_of_line (); + return; + } + + do + { + expression (&exp); + if (!strncasecmp (input_line_pointer, "@word", 5)) + { + exp.X_add_number = 0; + input_line_pointer += 5; + + p = frag_more (2); + fix_new_exp (frag_now, p - frag_now->fr_literal, 2, + &exp, 0, BFD_RELOC_D10V_18); + } + else + emit_expr (&exp, 2); + } + while (*input_line_pointer++ == ','); + + input_line_pointer--; /* Put terminator back into stream. */ + demand_empty_rest_of_line (); +} + + +/* Mitsubishi asked that we support some old syntax that apparently */ +/* had immediate operands starting with '#'. This is in some of their */ +/* sample code but is not documented (although it appears in some */ +/* examples in their assembler manual). For now, we'll solve this */ +/* compatibility problem by simply ignoring any '#' at the beginning */ +/* of an operand. */ + +/* operands that begin with '#' should fall through to here */ +/* from expr.c */ + +void +md_operand (expressionP) + expressionS *expressionP; +{ + if (*input_line_pointer == '#') + { + input_line_pointer++; + expression (expressionP); + } +} + +boolean +d10v_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; + if (S_IS_WEAK (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 +d10v_force_relocation (fixp) + struct fix *fixp; +{ + if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT + || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + return 1; + + return 0; +} diff --git a/gas/config/tc-d10v.h b/gas/config/tc-d10v.h new file mode 100644 index 0000000000..c6ffd5c3ea --- /dev/null +++ b/gas/config/tc-d10v.h @@ -0,0 +1,62 @@ +/* tc-d10v.h -- Header file for tc-d10v.c. + Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Written by Martin Hunt, 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_D10V + +#define TARGET_BYTES_BIG_ENDIAN 0 + +#ifndef BFD_ASSEMBLER + #error D10V support requires BFD_ASSEMBLER +#endif + +/* The target BFD architecture. */ +#define TARGET_ARCH bfd_arch_d10v + +#define TARGET_FORMAT "elf32-d10v" + +#define MD_APPLY_FIX3 + +/* call md_pcrel_from_section, not md_pcrel_from */ +#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC) + +/* 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_bigendian + +int d10v_cleanup PARAMS ((void)); +#define md_after_pass_hook() d10v_cleanup() +#define md_cleanup() d10v_cleanup() +#define md_do_align(a,b,c,d,e) d10v_cleanup() +#define tc_frob_label(sym) do {\ + d10v_cleanup(); \ + S_SET_VALUE (sym, (valueT) frag_now_fix ()); \ +} while (0) + +#define obj_fix_adjustable(fixP) d10v_fix_adjustable(fixP) +#define TC_FORCE_RELOCATION(fixp) d10v_force_relocation(fixp) +extern int d10v_force_relocation PARAMS ((struct fix *)); + diff --git a/gas/config/tc-d30v.c b/gas/config/tc-d30v.c new file mode 100644 index 0000000000..c5033ba33f --- /dev/null +++ b/gas/config/tc-d30v.c @@ -0,0 +1,2218 @@ +/* tc-d30v.c -- Assembler code for the Mitsubishi D30V + + Copyright (C) 1997, 1998 Free Software Foundation. + + 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 +#include +#include "as.h" +#include "subsegs.h" +#include "opcode/d30v.h" + +const char comment_chars[] = ";"; +const char line_comment_chars[] = "#"; +const char line_separator_chars[] = ""; +const char *md_shortopts = "OnNcC"; +const char EXP_CHARS[] = "eE"; +const char FLT_CHARS[] = "dD"; + +#define NOP_MULTIPLY 1 +#define NOP_ALL 2 +static int warn_nops = 0; +static int Optimizing = 0; +static int warn_register_name_conflicts = 1; + +#define FORCE_SHORT 1 +#define FORCE_LONG 2 + +/* EXEC types. */ +typedef enum _exec_type +{ + EXEC_UNKNOWN, /* no order specified */ + EXEC_PARALLEL, /* done in parallel (FM=00) */ + EXEC_SEQ, /* sequential (FM=01) */ + EXEC_REVSEQ /* reverse sequential (FM=10) */ +} exec_type_enum; + +/* fixups */ +#define MAX_INSN_FIXUPS (5) +struct d30v_fixup +{ + expressionS exp; + int operand; + int pcrel; + int size; + bfd_reloc_code_real_type reloc; +}; + +typedef struct _fixups +{ + int fc; + struct d30v_fixup fix[MAX_INSN_FIXUPS]; + struct _fixups *next; +} Fixups; + +static Fixups FixUps[2]; +static Fixups *fixups; + +/* Whether current and previous instruction are word multiply insns. */ +static int cur_mul32_p = 0; +static int prev_mul32_p = 0; + +/* The flag_explicitly_parallel is true iff the instruction being assembled + has been explicitly written as a parallel short-instruction pair by the + human programmer. It is used in parallel_ok() to distinguish between + those dangerous parallelizations attempted by the human, which are to be + allowed, and those attempted by the assembler, which are not. It is set + from md_assemble(). */ +static int flag_explicitly_parallel = 0; +static int flag_xp_state = 0; + +/* Whether current and previous left sub-instruction disables + execution of right sub-instruction. */ +static int cur_left_kills_right_p = 0; +static int prev_left_kills_right_p = 0; + +/* The known current alignment of the current section. */ +static int d30v_current_align; +static segT d30v_current_align_seg; + +/* The last seen label in the current section. This is used to auto-align + labels preceeding instructions. */ +static symbolS *d30v_last_label; + +/* Two nops */ +#define NOP_LEFT ((long long) NOP << 32) +#define NOP_RIGHT ((long long) NOP) +#define NOP2 (FM00 | NOP_LEFT | NOP_RIGHT) + +/* local functions */ +static int reg_name_search PARAMS ((char *name)); +static int register_name PARAMS ((expressionS *expressionP)); +static int check_range PARAMS ((unsigned long num, int bits, int flags)); +static int postfix PARAMS ((char *p)); +static bfd_reloc_code_real_type get_reloc PARAMS ((struct d30v_operand *op, int rel_flag)); +static int get_operands PARAMS ((expressionS exp[], int cmp_hack)); +static struct d30v_format *find_format PARAMS ((struct d30v_opcode *opcode, + expressionS ops[],int fsize, int cmp_hack)); +static long long build_insn PARAMS ((struct d30v_insn *opcode, expressionS *opers)); +static void write_long PARAMS ((struct d30v_insn *opcode, long long insn, Fixups *fx)); +static void write_1_short PARAMS ((struct d30v_insn *opcode, long long insn, + Fixups *fx, int use_sequential)); +static int write_2_short PARAMS ((struct d30v_insn *opcode1, long long insn1, + struct d30v_insn *opcode2, long long insn2, exec_type_enum exec_type, Fixups *fx)); +static long long do_assemble PARAMS ((char *str, struct d30v_insn *opcode, + int shortp, int is_parallel)); +static int parallel_ok PARAMS ((struct d30v_insn *opcode1, unsigned long insn1, + struct d30v_insn *opcode2, unsigned long insn2, + exec_type_enum exec_type)); +static void d30v_number_to_chars PARAMS ((char *buf, long long value, int nbytes)); +static void check_size PARAMS ((long value, int bits, char *file, int line)); +static void d30v_align PARAMS ((int, char *, symbolS *)); +static void s_d30v_align PARAMS ((int)); +static void s_d30v_text PARAMS ((int)); +static void s_d30v_data PARAMS ((int)); +static void s_d30v_section PARAMS ((int)); + +struct option md_longopts[] = { + {NULL, no_argument, NULL, 0} +}; +size_t md_longopts_size = sizeof(md_longopts); + + +/* The target specific pseudo-ops which we support. */ +const pseudo_typeS md_pseudo_table[] = +{ + { "word", cons, 4 }, + { "hword", cons, 2 }, + { "align", s_d30v_align, 0 }, + { "text", s_d30v_text, 0 }, + { "data", s_d30v_data, 0 }, + { "section", s_d30v_section, 0 }, + { "section.s", s_d30v_section, 0 }, + { "sect", s_d30v_section, 0 }, + { "sect.s", s_d30v_section, 0 }, + { NULL, NULL, 0 } +}; + +/* Opcode hash table. */ +static struct hash_control *d30v_hash; + +/* reg_name_search does a binary search of the pre_defined_registers + array to see if "name" is a valid regiter name. Returns the register + number from the array on success, or -1 on failure. */ + +static int +reg_name_search (name) + char *name; +{ + int middle, low, high; + int cmp; + + low = 0; + high = reg_name_cnt () - 1; + + do + { + middle = (low + high) / 2; + cmp = strcasecmp (name, pre_defined_registers[middle].name); + if (cmp < 0) + high = middle - 1; + else if (cmp > 0) + low = middle + 1; + else + { + if (symbol_find (name) != NULL) + { + if (warn_register_name_conflicts) + as_warn (_("Register name %s conflicts with symbol of the same name"), + name); + } + + return pre_defined_registers[middle].value; + } + } + while (low <= high); + + return -1; +} + +/* register_name() checks the string at input_line_pointer + to see if it is a valid register name. */ + +static int +register_name (expressionP) + expressionS *expressionP; +{ + int reg_number; + char c, *p = input_line_pointer; + + while (*p && *p!='\n' && *p!='\r' && *p !=',' && *p!=' ' && *p!=')') + p++; + + c = *p; + if (c) + *p++ = 0; + + /* look to see if it's in the register table */ + reg_number = reg_name_search (input_line_pointer); + if (reg_number >= 0) + { + expressionP->X_op = O_register; + /* temporarily store a pointer to the string here */ + expressionP->X_op_symbol = (struct symbol *)input_line_pointer; + expressionP->X_add_number = reg_number; + input_line_pointer = p; + return 1; + } + if (c) + *(p-1) = c; + return 0; +} + + +static int +check_range (num, bits, flags) + unsigned long num; + int bits; + int flags; +{ + long min, max; + int retval=0; + + /* don't bother checking 32-bit values */ + if (bits == 32) + return 0; + + if (flags & OPERAND_SHIFT) + { + /* We know that all shifts are right by three bits.... */ + + if (flags & OPERAND_SIGNED) + num = (unsigned long) (((/*signed*/ long) num) >> 3); + else + num >>= 3; + } + + if (flags & OPERAND_SIGNED) + { + max = (1 << (bits - 1))-1; + min = - (1 << (bits - 1)); + if (((long)num > max) || ((long)num < min)) + retval = 1; + } + else + { + max = (1 << bits) - 1; + min = 0; + if ((num > max) || (num < min)) + retval = 1; + } + + return retval; +} + + +void +md_show_usage (stream) + FILE *stream; +{ + fprintf (stream, _("\nD30V options:\n\ +-O Make adjacent short instructions parallel if possible.\n\ +-n Warn about all NOPs inserted by the assembler.\n\ +-N Warn 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")); +} + +int +md_parse_option (c, arg) + int c; + char *arg; +{ + switch (c) + { + /* Optimize. Will attempt to parallelize operations */ + case 'O': + Optimizing = 1; + break; + + /* Warn about all NOPS that the assembler inserts. */ + case 'n': + warn_nops = NOP_ALL; + break; + + /* Warn about the NOPS that the assembler inserts because of the + multiply hazard. */ + case 'N': + warn_nops = NOP_MULTIPLY; + break; + + case 'c': + warn_register_name_conflicts = 1; + break; + + case 'C': + warn_register_name_conflicts = 0; + break; + + default: + return 0; + } + return 1; +} + +symbolS * +md_undefined_symbol (name) + char *name; +{ + return 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; +} + +void +md_convert_frag (abfd, sec, fragP) + bfd *abfd; + asection *sec; + fragS *fragP; +{ + 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 () +{ + struct d30v_opcode * opcode; + d30v_hash = hash_new (); + + /* Insert opcode names into a hash table. */ + for (opcode = (struct d30v_opcode *)d30v_opcode_table; opcode->name; opcode++) + hash_insert (d30v_hash, opcode->name, (char *) opcode); + + fixups = &FixUps[0]; + FixUps[0].next = &FixUps[1]; + FixUps[1].next = &FixUps[0]; + + d30v_current_align_seg = now_seg; +} + + +/* this function removes the postincrement or postdecrement + operator ( '+' or '-' ) from an expression */ + +static int postfix (p) + char *p; +{ + while (*p != '-' && *p != '+') + { + if (*p==0 || *p=='\n' || *p=='\r' || *p==' ' || *p==',') + break; + p++; + } + + if (*p == '-') + { + *p = ' '; + return (-1); + } + if (*p == '+') + { + *p = ' '; + return (1); + } + + return (0); +} + + +static bfd_reloc_code_real_type +get_reloc (op, rel_flag) + struct d30v_operand *op; + int rel_flag; +{ + switch (op->bits) + { + case 6: + if (op->flags & OPERAND_SHIFT) + return BFD_RELOC_D30V_9_PCREL; + else + return BFD_RELOC_D30V_6; + break; + case 12: + if (!(op->flags & OPERAND_SHIFT)) + as_warn (_("unexpected 12-bit reloc type")); + if (rel_flag == RELOC_PCREL) + return BFD_RELOC_D30V_15_PCREL; + else + return BFD_RELOC_D30V_15; + case 18: + if (!(op->flags & OPERAND_SHIFT)) + as_warn (_("unexpected 18-bit reloc type")); + if (rel_flag == RELOC_PCREL) + return BFD_RELOC_D30V_21_PCREL; + else + return BFD_RELOC_D30V_21; + case 32: + if (rel_flag == RELOC_PCREL) + return BFD_RELOC_D30V_32_PCREL; + else + return BFD_RELOC_D30V_32; + default: + return 0; + } +} + +/* get_operands parses a string of operands and returns + an array of expressions */ + +static int +get_operands (exp, cmp_hack) + expressionS exp[]; + int cmp_hack; +{ + char *p = input_line_pointer; + int numops = 0; + int post = 0; + + if (cmp_hack) + { + exp[numops].X_op = O_absent; + exp[numops++].X_add_number = cmp_hack - 1; + } + + while (*p) + { + while (*p == ' ' || *p == '\t' || *p == ',') + p++; + if (*p==0 || *p=='\n' || *p=='\r') + break; + + if (*p == '@') + { + p++; + exp[numops].X_op = O_absent; + if (*p == '(') + { + p++; + exp[numops].X_add_number = OPERAND_ATPAR; + post = postfix (p); + } + else if (*p == '-') + { + p++; + exp[numops].X_add_number = OPERAND_ATMINUS; + } + else + { + exp[numops].X_add_number = OPERAND_ATSIGN; + post = postfix (p); + } + numops++; + continue; + } + + if (*p == ')') + { + /* just skip the trailing paren */ + p++; + continue; + } + + input_line_pointer = p; + + /* check to see if it might be a register name */ + if (!register_name (&exp[numops])) + { + /* parse as an expression */ + expression (&exp[numops]); + } + + if (exp[numops].X_op == O_illegal) + as_bad (_("illegal operand")); + else if (exp[numops].X_op == O_absent) + as_bad (_("missing operand")); + + numops++; + p = input_line_pointer; + + switch (post) + { + case -1: /* postdecrement mode */ + exp[numops].X_op = O_absent; + exp[numops++].X_add_number = OPERAND_MINUS; + break; + case 1: /* postincrement mode */ + exp[numops].X_op = O_absent; + exp[numops++].X_add_number = OPERAND_PLUS; + break; + } + post = 0; + } + + exp[numops].X_op = 0; + return (numops); +} + +/* build_insn generates the instruction. It does everything */ +/* but write the FM bits. */ + +static long long +build_insn (opcode, opers) + struct d30v_insn *opcode; + expressionS *opers; +{ + int i, length, bits, shift, flags; + unsigned int number, id=0; + long long insn; + struct d30v_opcode *op = opcode->op; + struct d30v_format *form = opcode->form; + + insn = opcode->ecc << 28 | op->op1 << 25 | op->op2 << 20 | form->modifier << 18; + + for (i=0; form->operands[i]; i++) + { + flags = d30v_operand_table[form->operands[i]].flags; + + /* must be a register or number */ + if (!(flags & OPERAND_REG) && !(flags & OPERAND_NUM) && + !(flags & OPERAND_NAME) && !(flags & OPERAND_SPECIAL)) + continue; + + bits = d30v_operand_table[form->operands[i]].bits; + if (flags & OPERAND_SHIFT) + bits += 3; + + length = d30v_operand_table[form->operands[i]].length; + shift = 12 - d30v_operand_table[form->operands[i]].position; + if (opers[i].X_op != O_symbol) + number = opers[i].X_add_number; + else + number = 0; + if (flags & OPERAND_REG) + { + /* check for mvfsys or mvtsys control registers */ + if (flags & OPERAND_CONTROL && (number & 0x7f) > MAX_CONTROL_REG) + { + /* PSWL or PSWH */ + id = (number & 0x7f) - MAX_CONTROL_REG; + number = 0; + } + else if (number & OPERAND_FLAG) + { + id = 3; /* number is a flag register */ + } + number &= 0x7F; + } + else if (flags & OPERAND_SPECIAL) + { + number = id; + } + + if (opers[i].X_op != O_register && opers[i].X_op != O_constant && !(flags & OPERAND_NAME)) + { + /* now create a fixup */ + + if (fixups->fc >= MAX_INSN_FIXUPS) + as_fatal (_("too many fixups")); + + fixups->fix[fixups->fc].reloc = + get_reloc ((struct d30v_operand *)&d30v_operand_table[form->operands[i]], op->reloc_flag); + fixups->fix[fixups->fc].size = 4; + fixups->fix[fixups->fc].exp = opers[i]; + fixups->fix[fixups->fc].operand = form->operands[i]; + if (fixups->fix[fixups->fc].reloc == BFD_RELOC_D30V_9_PCREL) + fixups->fix[fixups->fc].pcrel = RELOC_PCREL; + else + fixups->fix[fixups->fc].pcrel = op->reloc_flag; + (fixups->fc)++; + } + + /* truncate to the proper number of bits */ + if ((opers[i].X_op == O_constant) && check_range (number, bits, flags)) + as_bad (_("operand out of range: %d"),number); + if (bits < 31) + number &= 0x7FFFFFFF >> (31 - bits); + if (flags & OPERAND_SHIFT) + number >>= 3; + if (bits == 32) + { + /* it's a LONG instruction */ + insn |= (number >> 26); /* top 6 bits */ + insn <<= 32; /* shift the first word over */ + insn |= ((number & 0x03FC0000) << 2); /* next 8 bits */ + insn |= number & 0x0003FFFF; /* bottom 18 bits */ + } + else + insn |= number << shift; + } + return insn; +} + + +/* write out a long form instruction */ +static void +write_long (opcode, insn, fx) + struct d30v_insn *opcode; + long long insn; + Fixups *fx; +{ + int i, where; + char *f = frag_more (8); + + insn |= FM11; + d30v_number_to_chars (f, insn, 8); + + for (i=0; i < fx->fc; i++) + { + if (fx->fix[i].reloc) + { + where = f - frag_now->fr_literal; + fix_new_exp (frag_now, + where, + fx->fix[i].size, + &(fx->fix[i].exp), + fx->fix[i].pcrel, + fx->fix[i].reloc); + } + } + fx->fc = 0; +} + + +/* Write out a short form instruction by itself. */ +static void +write_1_short (opcode, insn, fx, use_sequential) + struct d30v_insn *opcode; + long long insn; + Fixups *fx; + int use_sequential; +{ + char *f = frag_more (8); + int i, where; + + if (warn_nops == NOP_ALL) + as_warn (_("%s NOP inserted"), use_sequential ? + _("sequential") : _("parallel")); + + /* The other container needs to be NOP. */ + if (use_sequential) + { + /* Use a sequential NOP rather than a parallel one, + as the current instruction is a FLAG_MUL32 type one + and the next instruction is a load. */ + + /* According to 4.3.1: for FM=01, sub-instructions performed + only by IU cannot be encoded in L-container. */ + + if (opcode->op->unit == IU) + insn |= FM10 | NOP_LEFT; /* right then left */ + else + insn = FM01 | (insn << 32) | NOP_RIGHT; /* left then right */ + } + else + { + /* According to 4.3.1: for FM=00, sub-instructions performed + only by IU cannot be encoded in L-container. */ + + if (opcode->op->unit == IU) + insn |= FM00 | NOP_LEFT; /* right container */ + else + insn = FM00 | (insn << 32) | NOP_RIGHT; /* left container */ + } + + d30v_number_to_chars (f, insn, 8); + + for (i=0; i < fx->fc; i++) + { + if (fx->fix[i].reloc) + { + where = f - frag_now->fr_literal; + fix_new_exp (frag_now, + where, + fx->fix[i].size, + &(fx->fix[i].exp), + fx->fix[i].pcrel, + fx->fix[i].reloc); + } + } + fx->fc = 0; +} + +/* Write out a short form instruction if possible. + Return number of instructions not written out. */ +static int +write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx) + struct d30v_insn *opcode1, *opcode2; + long long insn1, insn2; + exec_type_enum exec_type; + Fixups *fx; +{ + long long insn = NOP2; + char *f; + int i,j, where; + + if (exec_type == EXEC_SEQ + && (opcode1->op->flags_used & (FLAG_JMP | FLAG_JSR)) + && ((opcode1->op->flags_used & FLAG_DELAY) == 0) + && ((opcode1->ecc == ECC_AL) || ! Optimizing)) + { + /* Unconditional, non-delayed branches kill instructions in + the right bin. Conditional branches don't always but if + we are not optimizing, then we have been asked to produce + an error about such constructs. For the purposes of this + test, subroutine calls are considered to be branches. */ + write_1_short (opcode1, insn1, fx->next, false); + return 1; + } + + /* Note: we do not have to worry about subroutine calls occuring + in the right hand container. The return address is always + aligned to the next 64 bit boundary, be that 64 or 32 bit away. */ + + switch (exec_type) + { + case EXEC_UNKNOWN: /* Order not specified. */ + if (Optimizing + && parallel_ok (opcode1, insn1, opcode2, insn2, exec_type) + && ! ( (opcode1->op->unit == EITHER_BUT_PREFER_MU + || opcode1->op->unit == MU) + && + ( opcode2->op->unit == EITHER_BUT_PREFER_MU + || opcode2->op->unit == MU))) + { + /* parallel */ + exec_type = EXEC_PARALLEL; + + if (opcode1->op->unit == IU + || opcode2->op->unit == MU + || opcode2->op->unit == EITHER_BUT_PREFER_MU) + insn = FM00 | (insn2 << 32) | insn1; + else + { + insn = FM00 | (insn1 << 32) | insn2; + fx = fx->next; + } + } + else if (opcode1->op->flags_used & (FLAG_JMP | FLAG_JSR) + && ((opcode1->op->flags_used & FLAG_DELAY) == 0) + && ((opcode1->ecc == ECC_AL) || ! Optimizing)) + { + /* We must emit (non-delayed) branch type instructions + on their own with nothing in the right container. */ + write_1_short (opcode1, insn1, fx->next, false); + return 1; + } + else if (prev_left_kills_right_p) + { + /* The left instruction kils the right slot, so we + must leave it empty. */ + write_1_short (opcode1, insn1, fx->next, false); + return 1; + } + else if (opcode1->op->unit == IU + || (opcode1->op->unit == EITHER + && opcode2->op->unit == EITHER_BUT_PREFER_MU)) + { + /* reverse sequential */ + insn = FM10 | (insn2 << 32) | insn1; + exec_type = EXEC_REVSEQ; + } + else + { + /* sequential */ + insn = FM01 | (insn1 << 32) | insn2; + fx = fx->next; + exec_type = EXEC_SEQ; + } + break; + + case EXEC_PARALLEL: /* parallel */ + flag_explicitly_parallel = flag_xp_state; + if (! parallel_ok (opcode1, insn1, opcode2, insn2, exec_type)) + as_bad (_("Instructions may not be executed in parallel")); + else if (opcode1->op->unit == IU) + { + if (opcode2->op->unit == IU) + as_bad (_("Two IU instructions may not be executed in parallel")); + as_warn (_("Swapping instruction order")); + insn = FM00 | (insn2 << 32) | insn1; + } + else if (opcode2->op->unit == MU) + { + if (opcode1->op->unit == MU) + as_bad (_("Two MU instructions may not be executed in parallel")); + else if (opcode1->op->unit == EITHER_BUT_PREFER_MU) + as_warn (_("Executing %s in IU may not work"), opcode1->op->name); + as_warn (_("Swapping instruction order")); + insn = FM00 | (insn2 << 32) | insn1; + } + else + { + if (opcode2->op->unit == EITHER_BUT_PREFER_MU) + as_warn (_("Executing %s in IU may not work"), opcode2->op->name); + + insn = FM00 | (insn1 << 32) | insn2; + fx = fx->next; + } + flag_explicitly_parallel = 0; + break; + + case EXEC_SEQ: /* sequential */ + if (opcode1->op->unit == IU) + as_bad (_("IU instruction may not be in the left container")); + if (prev_left_kills_right_p) + as_bad (_("special left instruction `%s' kills instruction " + "`%s' in right container"), + opcode1->op->name, opcode2->op->name); + if (opcode2->op->unit == EITHER_BUT_PREFER_MU) + as_warn (_("Executing %s in IU may not work"), opcode2->op->name); + insn = FM01 | (insn1 << 32) | insn2; + fx = fx->next; + break; + + case EXEC_REVSEQ: /* reverse sequential */ + if (opcode2->op->unit == MU) + as_bad (_("MU instruction may not be in the right container")); + if (opcode2->op->unit == EITHER_BUT_PREFER_MU) + as_warn (_("Executing %s in IU may not work"), opcode2->op->name); + insn = FM10 | (insn1 << 32) | insn2; + fx = fx->next; + break; + + default: + as_fatal (_("unknown execution type passed to write_2_short()")); + } + + /* printf ("writing out %llx\n",insn); */ + f = frag_more (8); + d30v_number_to_chars (f, insn, 8); + + /* If the previous instruction was a 32-bit multiply but it is put into a + parallel container, mark the current instruction as being a 32-bit + multiply. */ + if (prev_mul32_p && exec_type == EXEC_PARALLEL) + cur_mul32_p = 1; + + for (j=0; j<2; j++) + { + for (i=0; i < fx->fc; i++) + { + if (fx->fix[i].reloc) + { + where = (f - frag_now->fr_literal) + 4*j; + + fix_new_exp (frag_now, + where, + fx->fix[i].size, + &(fx->fix[i].exp), + fx->fix[i].pcrel, + fx->fix[i].reloc); + } + } + + fx->fc = 0; + fx = fx->next; + } + + return 0; +} + + +/* Check 2 instructions and determine if they can be safely */ +/* executed in parallel. Returns 1 if they can be. */ +static int +parallel_ok (op1, insn1, op2, insn2, exec_type) + struct d30v_insn *op1, *op2; + unsigned long insn1, insn2; + exec_type_enum exec_type; +{ + int i, j, shift, regno, bits, ecc; + unsigned long flags, mask, flags_set1, flags_set2, flags_used1, flags_used2; + unsigned long ins, mod_reg[2][3], used_reg[2][3], flag_reg[2]; + struct d30v_format *f; + struct d30v_opcode *op; + + /* section 4.3: both instructions must not be IU or MU only */ + if ((op1->op->unit == IU && op2->op->unit == IU) + || (op1->op->unit == MU && op2->op->unit == MU)) + return 0; + + /* first instruction must not be a jump to safely optimize, unless this + is an explicit parallel operation. */ + if (exec_type != EXEC_PARALLEL + && (op1->op->flags_used & (FLAG_JMP | FLAG_JSR))) + return 0; + + /* If one instruction is /TX or /XT and the other is /FX or /XF respectively, + then it is safe to allow the two to be done as parallel ops, since only + one will ever be executed at a time. */ + if ((op1->ecc == ECC_TX && op2->ecc == ECC_FX) + || (op1->ecc == ECC_FX && op2->ecc == ECC_TX) + || (op1->ecc == ECC_XT && op2->ecc == ECC_XF) + || (op1->ecc == ECC_XF && op2->ecc == ECC_XT)) + return 1; + + /* [0] r0-r31 + [1] r32-r63 + [2] a0, a1, flag registers */ + + for (j = 0; j < 2; j++) + { + if (j == 0) + { + f = op1->form; + op = op1->op; + ecc = op1->ecc; + ins = insn1; + } + else + { + f = op2->form; + op = op2->op; + ecc = op2->ecc; + ins = insn2; + } + flag_reg[j] = 0; + mod_reg[j][0] = mod_reg[j][1] = 0; + used_reg[j][0] = used_reg[j][1] = 0; + + if (flag_explicitly_parallel) + { + /* For human specified parallel instructions we have been asked + to ignore the possibility that both instructions could modify + bits in the PSW, so we initialise the mod & used arrays to 0. + We have been asked, however, to refuse to allow parallel + instructions which explicitly set the same flag register, + eg "cmpne f0,r1,0x10 || cmpeq f0, r5, 0x2", so further on we test + for the use of a flag register and set a bit in the mod or used + array appropriately. */ + + mod_reg[j][2] = 0; + used_reg[j][2] = 0; + } + else + { + mod_reg[j][2] = (op->flags_set & FLAG_ALL); + used_reg[j][2] = (op->flags_used & FLAG_ALL); + } + + /* BSR/JSR always sets R62 */ + if (op->flags_used & FLAG_JSR) + mod_reg[j][1] = (1L << (62-32)); + + /* conditional execution affects the flags_used */ + switch (ecc) + { + case ECC_TX: + case ECC_FX: + used_reg[j][2] |= flag_reg[j] = FLAG_0; + break; + + case ECC_XT: + case ECC_XF: + used_reg[j][2] |= flag_reg[j] = FLAG_1; + break; + + case ECC_TT: + case ECC_TF: + used_reg[j][2] |= flag_reg[j] = (FLAG_0 | FLAG_1); + break; + } + + for (i = 0; f->operands[i]; i++) + { + flags = d30v_operand_table[f->operands[i]].flags; + shift = 12 - d30v_operand_table[f->operands[i]].position; + bits = d30v_operand_table[f->operands[i]].bits; + if (bits == 32) + mask = 0xffffffff; + else + mask = 0x7FFFFFFF >> (31 - bits); + + if ((flags & OPERAND_PLUS) || (flags & OPERAND_MINUS)) + { + /* this is a post-increment or post-decrement */ + /* the previous register needs to be marked as modified */ + + shift = 12 - d30v_operand_table[f->operands[i-1]].position; + regno = (ins >> shift) & 0x3f; + if (regno >= 32) + mod_reg[j][1] |= 1L << (regno - 32); + else + mod_reg[j][0] |= 1L << regno; + } + else if (flags & OPERAND_REG) + { + regno = (ins >> shift) & mask; + /* the memory write functions don't have a destination register */ + if ((flags & OPERAND_DEST) && !(op->flags_set & FLAG_MEM)) + { + /* MODIFIED registers and flags */ + if (flags & OPERAND_ACC) + { + if (regno == 0) + mod_reg[j][2] |= FLAG_A0; + else if (regno == 1) + mod_reg[j][2] |= FLAG_A1; + else + abort (); + } + else if (flags & OPERAND_FLAG) + mod_reg[j][2] |= 1L << regno; + else if (!(flags & OPERAND_CONTROL)) + { + int r, z; + + /* need to check if there are two destination */ + /* registers, for example ld2w */ + if (flags & OPERAND_2REG) + z = 1; + else + z = 0; + + for (r = regno; r <= regno + z; r++) + { + if (r >= 32) + mod_reg[j][1] |= 1L << (r - 32); + else + mod_reg[j][0] |= 1L << r; + } + } + } + else + { + /* USED, but not modified registers and flags */ + if (flags & OPERAND_ACC) + { + if (regno == 0) + used_reg[j][2] |= FLAG_A0; + else if (regno == 1) + used_reg[j][2] |= FLAG_A1; + else + abort (); + } + else if (flags & OPERAND_FLAG) + used_reg[j][2] |= 1L << regno; + else if (!(flags & OPERAND_CONTROL)) + { + int r, z; + + /* need to check if there are two source */ + /* registers, for example st2w */ + if (flags & OPERAND_2REG) + z = 1; + else + z = 0; + + for (r = regno; r <= regno + z; r++) + { + if (r >= 32) + used_reg[j][1] |= 1L << (r - 32); + else + used_reg[j][0] |= 1L << r; + } + } + } + } + } + } + + flags_set1 = op1->op->flags_set; + flags_set2 = op2->op->flags_set; + flags_used1 = op1->op->flags_used; + flags_used2 = op2->op->flags_used; + + /* ST2W/ST4HB combined with ADDppp/SUBppp is illegal. */ + if (((flags_set1 & (FLAG_MEM | FLAG_2WORD)) == (FLAG_MEM | FLAG_2WORD) + && (flags_used2 & FLAG_ADDSUBppp) != 0) + || ((flags_set2 & (FLAG_MEM | FLAG_2WORD)) == (FLAG_MEM | FLAG_2WORD) + && (flags_used1 & FLAG_ADDSUBppp) != 0)) + return 0; + + /* Load instruction combined with half-word multiply is illegal. */ + if (((flags_used1 & FLAG_MEM) != 0 && (flags_used2 & FLAG_MUL16)) + || ((flags_used2 & FLAG_MEM) != 0 && (flags_used1 & FLAG_MUL16))) + return 0; + + /* Specifically allow add || add by removing carry, overflow bits dependency. + This is safe, even if an addc follows since the IU takes the argument in + the right container, and it writes its results last. + However, don't paralellize add followed by addc or sub followed by + subb. */ + + if (mod_reg[0][2] == FLAG_CVVA && mod_reg[1][2] == FLAG_CVVA + && (used_reg[0][2] & ~flag_reg[0]) == 0 + && (used_reg[1][2] & ~flag_reg[1]) == 0 + && op1->op->unit == EITHER && op2->op->unit == EITHER) + { + mod_reg[0][2] = mod_reg[1][2] = 0; + } + + for (j = 0; j < 3; j++) + { + /* If the second instruction depends on the first, we obviously + cannot parallelize. Note, the mod flag implies use, so + check that as well. */ + /* If flag_explicitly_parallel is set, then the case of the + second instruction using a register the first instruction + modifies is assumed to be okay; we trust the human. We + don't trust the human if both instructions modify the same + register but we do trust the human if they modify the same + flags. */ + /* We have now been requested not to trust the human if the + instructions modify the same flag registers either. */ + if (flag_explicitly_parallel) + { + if ((mod_reg[0][j] & mod_reg[1][j]) != 0) + return 0; + } + else + if ((mod_reg[0][j] & (mod_reg[1][j] | used_reg[1][j])) != 0) + return 0; + } + + return 1; +} + + +/* This is the main entry point for the machine-dependent assembler. str points to a + machine-dependent instruction. This function is supposed to emit the frags/bytes + it assembles to. For the D30V, it mostly handles the special VLIW parsing and packing + and leaves the difficult stuff to do_assemble(). */ + +static long long prev_insn = -1; +static struct d30v_insn prev_opcode; +static subsegT prev_subseg; +static segT prev_seg = 0; + +void +md_assemble (str) + char *str; +{ + struct d30v_insn opcode; + long long insn; + exec_type_enum extype = EXEC_UNKNOWN; /* execution type; parallel, etc */ + static exec_type_enum etype = EXEC_UNKNOWN; /* saved extype. used for multiline instructions */ + char *str2; + + if ((prev_insn != -1) && prev_seg + && ((prev_seg != now_seg) || (prev_subseg != now_subseg))) + d30v_cleanup (false); + + if (d30v_current_align < 3) + d30v_align (3, NULL, d30v_last_label); + else if (d30v_current_align > 3) + d30v_current_align = 3; + d30v_last_label = NULL; + + flag_explicitly_parallel = 0; + flag_xp_state = 0; + if (etype == EXEC_UNKNOWN) + { + /* look for the special multiple instruction separators */ + str2 = strstr (str, "||"); + if (str2) + { + extype = EXEC_PARALLEL; + flag_xp_state = 1; + } + else + { + str2 = strstr (str, "->"); + if (str2) + extype = EXEC_SEQ; + else + { + str2 = strstr (str, "<-"); + if (str2) + extype = EXEC_REVSEQ; + } + } + /* str2 points to the separator, if one */ + if (str2) + { + *str2 = 0; + + /* if two instructions are present and we already have one saved + then first write it out */ + d30v_cleanup (false); + + /* Assemble first instruction and save it. */ + prev_insn = do_assemble (str, &prev_opcode, 1, 0); + if (prev_insn == -1) + as_bad (_("Cannot assemble instruction")); + if (prev_opcode.form != NULL && prev_opcode.form->form >= LONG) + as_bad (_("First opcode is long. Unable to mix instructions as specified.")); + fixups = fixups->next; + str = str2 + 2; + prev_seg = now_seg; + prev_subseg = now_subseg; + } + } + + insn = do_assemble (str, &opcode, + (extype != EXEC_UNKNOWN || etype != EXEC_UNKNOWN), + extype == EXEC_PARALLEL); + if (insn == -1) + { + if (extype != EXEC_UNKNOWN) + etype = extype; + as_bad (_("Cannot assemble instruction")); + return; + } + + if (etype != EXEC_UNKNOWN) + { + extype = etype; + etype = EXEC_UNKNOWN; + } + + /* Word multiply instructions must not be followed by either a load or a + 16-bit multiply instruction in the next cycle. */ + if ( (extype != EXEC_REVSEQ) + && prev_mul32_p + && (opcode.op->flags_used & (FLAG_MEM | FLAG_MUL16))) + { + /* However, load and multiply should able to be combined in a parallel + operation, so check for that first. */ + if (prev_insn != -1 + && (opcode.op->flags_used & FLAG_MEM) + && opcode.form->form < LONG + && (extype == EXEC_PARALLEL || (Optimizing && extype == EXEC_UNKNOWN)) + && parallel_ok (&prev_opcode, (long)prev_insn, + &opcode, (long)insn, extype) + && write_2_short (&prev_opcode, (long)prev_insn, + &opcode, (long)insn, extype, fixups) == 0) + { + /* no instructions saved */ + prev_insn = -1; + return; + } + else + { + /* Can't parallelize, flush previous instruction and emit a word of NOPS, + unless the previous instruction is a NOP, in which case just flush it, + as this will generate a word of NOPs for us. */ + + if (prev_insn != -1 && (strcmp (prev_opcode.op->name, "nop") == 0)) + d30v_cleanup (false); + else + { + char * f; + + if (prev_insn != -1) + d30v_cleanup (true); + else + { + f = frag_more (8); + d30v_number_to_chars (f, NOP2, 8); + + if (warn_nops == NOP_ALL || warn_nops == NOP_MULTIPLY) + { + if (opcode.op->flags_used & FLAG_MEM) + as_warn (_("word of NOPs added between word multiply and load")); + else + as_warn (_("word of NOPs added between word multiply and 16-bit multiply")); + } + } + } + + extype = EXEC_UNKNOWN; + } + } + else if ( (extype == EXEC_REVSEQ) + && cur_mul32_p + && (prev_opcode.op->flags_used & (FLAG_MEM | FLAG_MUL16))) + { + /* Can't parallelize, flush current instruction and add a sequential NOP. */ + write_1_short (& opcode, (long) insn, fixups->next->next, true); + + /* Make the previous instruction the current one. */ + extype = EXEC_UNKNOWN; + insn = prev_insn; + now_seg = prev_seg; + now_subseg = prev_subseg; + prev_insn = -1; + cur_mul32_p = prev_mul32_p; + prev_mul32_p = 0; + memcpy (&opcode, &prev_opcode, sizeof (prev_opcode)); + } + + /* If this is a long instruction, write it and any previous short instruction. */ + if (opcode.form->form >= LONG) + { + if (extype != EXEC_UNKNOWN) + as_bad (_("Instruction uses long version, so it cannot be mixed as specified")); + d30v_cleanup (false); + write_long (& opcode, insn, fixups); + prev_insn = -1; + } + else if ((prev_insn != -1) + && (write_2_short + (& prev_opcode, (long) prev_insn, & opcode, + (long) insn, extype, fixups) == 0)) + { + /* No instructions saved. */ + prev_insn = -1; + } + else + { + if (extype != EXEC_UNKNOWN) + as_bad (_("Unable to mix instructions as specified")); + + /* Save off last instruction so it may be packed on next pass. */ + memcpy (&prev_opcode, &opcode, sizeof (prev_opcode)); + prev_insn = insn; + prev_seg = now_seg; + prev_subseg = now_subseg; + fixups = fixups->next; + prev_mul32_p = cur_mul32_p; + } +} + + +/* do_assemble assembles a single instruction and returns an opcode */ +/* it returns -1 (an invalid opcode) on error */ + +#define NAME_BUF_LEN 20 + +static long long +do_assemble (str, opcode, shortp, is_parallel) + char *str; + struct d30v_insn *opcode; + int shortp; + int is_parallel; +{ + unsigned char * op_start; + unsigned char * save; + unsigned char * op_end; + char name [NAME_BUF_LEN]; + int cmp_hack; + int nlen = 0; + int fsize = (shortp ? FORCE_SHORT : 0); + expressionS myops [6]; + long long insn; + + /* Drop leading whitespace */ + while (* str == ' ') + str ++; + + /* find the opcode end */ + for (op_start = op_end = (unsigned char *) (str); + * op_end + && nlen < (NAME_BUF_LEN - 1) + && * op_end != '/' + && !is_end_of_line[*op_end] && *op_end != ' '; + op_end++) + { + name[nlen] = tolower (op_start[nlen]); + nlen++; + } + + if (nlen == 0) + return -1; + + name[nlen] = 0; + + /* if there is an execution condition code, handle it */ + if (*op_end == '/') + { + int i = 0; + while ( (i < ECC_MAX) && strncasecmp (d30v_ecc_names[i], op_end + 1, 2)) + i++; + + if (i == ECC_MAX) + { + char tmp[4]; + strncpy (tmp, op_end + 1, 2); + tmp[2] = 0; + as_bad (_("unknown condition code: %s"),tmp); + return -1; + } + /* printf ("condition code=%d\n",i); */ + opcode->ecc = i; + op_end += 3; + } + else + opcode->ecc = ECC_AL; + + + /* CMP and CMPU change their name based on condition codes */ + if (!strncmp (name, "cmp", 3)) + { + int p,i; + char **str = (char **)d30v_cc_names; + if (name[3] == 'u') + p = 4; + else + p = 3; + + for (i=1; *str && strncmp (*str, & name[p], 2); i++, str++) + ; + + /* cmpu only supports some condition codes */ + if (p == 4) + { + if (i < 3 || i > 6) + { + name[p+2]=0; + as_bad (_("cmpu doesn't support condition code %s"),&name[p]); + } + } + + if (!*str) + { + name[p+2]=0; + as_bad (_("unknown condition code: %s"),&name[p]); + } + + cmp_hack = i; + name[p] = 0; + } + else + cmp_hack = 0; + + /* printf("cmp_hack=%d\n",cmp_hack); */ + + /* need to look for .s or .l */ + if (name[nlen-2] == '.') + { + switch (name[nlen-1]) + { + case 's': + fsize = FORCE_SHORT; + break; + case 'l': + fsize = FORCE_LONG; + break; + } + name[nlen-2] = 0; + } + + /* find the first opcode with the proper name */ + opcode->op = (struct d30v_opcode *)hash_find (d30v_hash, name); + if (opcode->op == NULL) + { + as_bad (_("unknown opcode: %s"),name); + return -1; + } + + save = input_line_pointer; + input_line_pointer = op_end; + while (!(opcode->form = find_format (opcode->op, myops, fsize, cmp_hack))) + { + opcode->op++; + if (opcode->op->name == NULL || strcmp (opcode->op->name, name)) + { + as_bad (_("operands for opcode `%s' do not match any valid format"), name); + return -1; + } + } + input_line_pointer = save; + + insn = build_insn (opcode, myops); + + /* Propigate multiply status */ + if (insn != -1) + { + if (is_parallel && prev_mul32_p) + cur_mul32_p = 1; + else + { + prev_mul32_p = cur_mul32_p; + cur_mul32_p = (opcode->op->flags_used & FLAG_MUL32) != 0; + } + } + + /* Propagate left_kills_right status */ + if (insn != -1) + { + prev_left_kills_right_p = cur_left_kills_right_p; + + if (opcode->op->flags_set & FLAG_LKR) + { + cur_left_kills_right_p = 1; + + if (strcmp (opcode->op->name, "mvtsys") == 0) + { + /* Left kills right for only mvtsys only for PSW/PSWH/PSWL/flags target. */ + if ((myops[0].X_op == O_register) && + ((myops[0].X_add_number == OPERAND_CONTROL) || /* psw */ + (myops[0].X_add_number == OPERAND_CONTROL+MAX_CONTROL_REG+2) || /* pswh */ + (myops[0].X_add_number == OPERAND_CONTROL+MAX_CONTROL_REG+1) || /* pswl */ + (myops[0].X_add_number == OPERAND_FLAG+0) || /* f0 */ + (myops[0].X_add_number == OPERAND_FLAG+1) || /* f1 */ + (myops[0].X_add_number == OPERAND_FLAG+2) || /* f2 */ + (myops[0].X_add_number == OPERAND_FLAG+3) || /* f3 */ + (myops[0].X_add_number == OPERAND_FLAG+4) || /* f4 */ + (myops[0].X_add_number == OPERAND_FLAG+5) || /* f5 */ + (myops[0].X_add_number == OPERAND_FLAG+6) || /* f6 */ + (myops[0].X_add_number == OPERAND_FLAG+7))) /* f7 */ + { + cur_left_kills_right_p = 1; + } + else + { + /* Other mvtsys target registers don't kill right instruction. */ + cur_left_kills_right_p = 0; + } + } /* mvtsys */ + } + else + cur_left_kills_right_p = 0; + } + + return insn; +} + + +/* find_format() gets a pointer to an entry in the format table. + It must look at all formats for an opcode and use the operands + to choose the correct one. Returns NULL on error. */ + +static struct d30v_format * +find_format (opcode, myops, fsize, cmp_hack) + struct d30v_opcode *opcode; + expressionS myops[]; + int fsize; + int cmp_hack; +{ + int numops, match, index, i=0, j, k; + struct d30v_format *fm; + + if (opcode == NULL) + return NULL; + + /* Get all the operands and save them as expressions. */ + numops = get_operands (myops, cmp_hack); + + while ((index = opcode->format[i++]) != 0) + { + if (fsize == FORCE_SHORT && index >= LONG) + continue; + + if (fsize == FORCE_LONG && index < LONG) + continue; + + fm = (struct d30v_format *)&d30v_format_table[index]; + k = index; + while (fm->form == index) + { + match = 1; + /* Now check the operands for compatibility. */ + for (j = 0; match && fm->operands[j]; j++) + { + int flags = d30v_operand_table[fm->operands[j]].flags; + int bits = d30v_operand_table[fm->operands[j]].bits; + int X_op = myops[j].X_op; + int num = myops[j].X_add_number; + + if (flags & OPERAND_SPECIAL) + break; + else if (X_op == O_illegal) + match = 0; + else if (flags & OPERAND_REG) + { + if (X_op != O_register + || ((flags & OPERAND_ACC) && !(num & OPERAND_ACC)) + || (!(flags & OPERAND_ACC) && (num & OPERAND_ACC)) + || ((flags & OPERAND_FLAG) && !(num & OPERAND_FLAG)) + || (!(flags & (OPERAND_FLAG | OPERAND_CONTROL)) && (num & OPERAND_FLAG)) + || ((flags & OPERAND_CONTROL) + && !(num & (OPERAND_CONTROL | OPERAND_FLAG)))) + { + match = 0; + } + } + else if (((flags & OPERAND_MINUS) + && (X_op != O_absent || num != OPERAND_MINUS)) + || ((flags & OPERAND_PLUS) + && (X_op != O_absent || num != OPERAND_PLUS)) + || ((flags & OPERAND_ATMINUS) + && (X_op != O_absent || num != OPERAND_ATMINUS)) + || ((flags & OPERAND_ATPAR) + && (X_op != O_absent || num != OPERAND_ATPAR)) + || ((flags & OPERAND_ATSIGN) + && (X_op != O_absent || num != OPERAND_ATSIGN))) + { + match=0; + } + else if (flags & OPERAND_NUM) + { + /* A number can be a constant or symbol expression. */ + + /* If we have found a register name, but that name also + matches a symbol, then re-parse the name as an expression. */ + if (X_op == O_register + && symbol_find ((char *) myops[j].X_op_symbol)) + { + input_line_pointer = (char *) myops[j].X_op_symbol; + expression (& myops[j]); + } + + /* Turn an expression into a symbol for later resolution. */ + if (X_op != O_absent && X_op != O_constant + && X_op != O_symbol && X_op != O_register + && X_op != O_big) + { + symbolS *sym = make_expr_symbol (&myops[j]); + myops[j].X_op = X_op = O_symbol; + myops[j].X_add_symbol = sym; + myops[j].X_add_number = num = 0; + } + + if (fm->form >= LONG) + { + /* If we're testing for a LONG format, either fits. */ + if (X_op != O_constant && X_op != O_symbol) + match = 0; + } + else if (fm->form < LONG + && ((fsize == FORCE_SHORT && X_op == O_symbol) + || (fm->form == SHORT_D2 && j == 0))) + match = 1; + /* This is the tricky part. Will the constant or symbol + fit into the space in the current format? */ + else if (X_op == O_constant) + { + if (check_range (num, bits, flags)) + match = 0; + } + else if (X_op == O_symbol + && S_IS_DEFINED (myops[j].X_add_symbol) + && S_GET_SEGMENT (myops[j].X_add_symbol) == now_seg + && opcode->reloc_flag == RELOC_PCREL) + { + /* If the symbol is defined, see if the value will fit + into the form we're considering. */ + fragS *f; + long value; + + /* Calculate the current address by running through the + previous frags and adding our current offset. */ + value = 0; + for (f = frchain_now->frch_root; f; f = f->fr_next) + value += f->fr_fix + f->fr_offset; + value = (S_GET_VALUE (myops[j].X_add_symbol) - value + - (obstack_next_free (&frchain_now->frch_obstack) + - frag_now->fr_literal)); + if (check_range (value, bits, flags)) + match = 0; + } + else + match = 0; + } + } + /* printf("through the loop: match=%d\n",match); */ + /* We're only done if the operands matched so far AND there + are no more to check. */ + if (match && myops[j].X_op == 0) + { + /* Final check - issue a warning if an odd numbered register + is used as the first register in an instruction that reads + or writes 2 registers. */ + + for (j = 0; fm->operands[j]; j++) + if (myops[j].X_op == O_register + && (myops[j].X_add_number & 1) + && (d30v_operand_table[fm->operands[j]].flags & OPERAND_2REG)) + as_warn (\ +_("Odd numbered register used as target of multi-register instruction")); + + return fm; + } + fm = (struct d30v_format *)&d30v_format_table[++k]; + } + /* printf("trying another format: i=%d\n",i); */ + } + return NULL; +} + +/* 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; + 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, + _("reloc %d not supported by object file format"), (int)fixp->fx_r_type); + return NULL; + } + reloc->addend = fixp->fx_addnumber; + return reloc; +} + +int +md_estimate_size_before_relax (fragp, seg) + fragS *fragp; + asection *seg; +{ + abort (); + return 0; +} + +long +md_pcrel_from_section (fixp, sec) + fixS *fixp; + segT sec; +{ + if (fixp->fx_addsy != (symbolS *)NULL && (!S_IS_DEFINED (fixp->fx_addsy) || + (S_GET_SEGMENT (fixp->fx_addsy) != sec))) + return 0; + return fixp->fx_frag->fr_address + fixp->fx_where; +} + +int +md_apply_fix3 (fixp, valuep, seg) + fixS * fixp; + valueT * valuep; + segT seg; +{ + char * where; + unsigned long insn, insn2; + long value; + + if (fixp->fx_addsy == (symbolS *) NULL) + { + value = * valuep; + fixp->fx_done = 1; + } + else if (fixp->fx_pcrel) + value = * valuep; + 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")); + } + } + } + + /* Fetch the instruction, insert the fully resolved operand + value, and stuff the instruction back again. */ + where = fixp->fx_frag->fr_literal + fixp->fx_where; + insn = bfd_getb32 ((unsigned char *) where); + + switch (fixp->fx_r_type) + { + case BFD_RELOC_8: /* Check for a bad .byte directive. */ + if (fixp->fx_addsy != NULL) + as_bad (_("line %d: unable to place address of symbol '%s' into a byte"), + fixp->fx_line, S_GET_NAME (fixp->fx_addsy)); + else if (((unsigned)value) > 0xff) + as_bad (_("line %d: unable to place value %x into a byte"), + fixp->fx_line, value); + else + * (unsigned char *) where = value; + break; + + case BFD_RELOC_16: /* Check for a bad .short directive. */ + if (fixp->fx_addsy != NULL) + as_bad (_("line %d: unable to place address of symbol '%s' into a short"), + fixp->fx_line, S_GET_NAME (fixp->fx_addsy)); + else if (((unsigned)value) > 0xffff) + as_bad (_("line %d: unable to place value %x into a short"), + fixp->fx_line, value); + else + bfd_putb16 ((bfd_vma) value, (unsigned char *) where); + break; + + case BFD_RELOC_64: /* Check for a bad .quad directive. */ + if (fixp->fx_addsy != NULL) + as_bad (_("line %d: unable to place address of symbol '%s' into a quad"), + fixp->fx_line, S_GET_NAME (fixp->fx_addsy)); + else + { + bfd_putb32 ((bfd_vma) value, (unsigned char *) where); + bfd_putb32 (0, ((unsigned char *) where) + 4); + } + break; + + case BFD_RELOC_D30V_6: + check_size (value, 6, fixp->fx_file, fixp->fx_line); + insn |= value & 0x3F; + bfd_putb32 ((bfd_vma) insn, (unsigned char *) where); + break; + + case BFD_RELOC_D30V_9_PCREL: + if (fixp->fx_where & 0x7) + { + if (fixp->fx_done) + value += 4; + else + fixp->fx_r_type = BFD_RELOC_D30V_9_PCREL_R; + } + check_size (value, 9, fixp->fx_file, fixp->fx_line); + insn |= ((value >> 3) & 0x3F) << 12; + bfd_putb32 ((bfd_vma) insn, (unsigned char *) where); + break; + + case BFD_RELOC_D30V_15: + check_size (value, 15, fixp->fx_file, fixp->fx_line); + insn |= (value >> 3) & 0xFFF; + bfd_putb32 ((bfd_vma) insn, (unsigned char *) where); + break; + + case BFD_RELOC_D30V_15_PCREL: + if (fixp->fx_where & 0x7) + { + if (fixp->fx_done) + value += 4; + else + fixp->fx_r_type = BFD_RELOC_D30V_15_PCREL_R; + } + check_size (value, 15, fixp->fx_file, fixp->fx_line); + insn |= (value >> 3) & 0xFFF; + bfd_putb32 ((bfd_vma) insn, (unsigned char *) where); + break; + + case BFD_RELOC_D30V_21: + check_size (value, 21, fixp->fx_file, fixp->fx_line); + insn |= (value >> 3) & 0x3FFFF; + bfd_putb32 ((bfd_vma) insn, (unsigned char *) where); + break; + + case BFD_RELOC_D30V_21_PCREL: + if (fixp->fx_where & 0x7) + { + if (fixp->fx_done) + value += 4; + else + fixp->fx_r_type = BFD_RELOC_D30V_21_PCREL_R; + } + check_size (value, 21, fixp->fx_file, fixp->fx_line); + insn |= (value >> 3) & 0x3FFFF; + bfd_putb32 ((bfd_vma) insn, (unsigned char *) where); + break; + + case BFD_RELOC_D30V_32: + insn2 = bfd_getb32 ((unsigned char *) where + 4); + insn |= (value >> 26) & 0x3F; /* top 6 bits */ + insn2 |= ((value & 0x03FC0000) << 2); /* next 8 bits */ + insn2 |= value & 0x0003FFFF; /* bottom 18 bits */ + bfd_putb32 ((bfd_vma) insn, (unsigned char *) where); + bfd_putb32 ((bfd_vma) insn2, (unsigned char *) where + 4); + break; + + case BFD_RELOC_D30V_32_PCREL: + insn2 = bfd_getb32 ((unsigned char *) where + 4); + insn |= (value >> 26) & 0x3F; /* top 6 bits */ + insn2 |= ((value & 0x03FC0000) << 2); /* next 8 bits */ + insn2 |= value & 0x0003FFFF; /* bottom 18 bits */ + bfd_putb32 ((bfd_vma) insn, (unsigned char *) where); + bfd_putb32 ((bfd_vma) insn2, (unsigned char *) where + 4); + break; + + case BFD_RELOC_32: + bfd_putb32 ((bfd_vma) value, (unsigned char *) where); + break; + + default: + as_bad (_("line %d: unknown relocation type: 0x%x"), + fixp->fx_line,fixp->fx_r_type); + } + + return 0; +} + + +/* d30v_cleanup() is called after the assembler has finished parsing the input + file or after a label is defined. Because the D30V assembler sometimes saves short + instructions to see if it can package them with the next instruction, there may + be a short instruction that still needs written. */ +int +d30v_cleanup (use_sequential) + int use_sequential; +{ + segT seg; + subsegT subseg; + + if (prev_insn != -1) + { + seg = now_seg; + subseg = now_subseg; + subseg_set (prev_seg, prev_subseg); + write_1_short (&prev_opcode, (long)prev_insn, fixups->next, use_sequential); + subseg_set (seg, subseg); + prev_insn = -1; + if (use_sequential) + prev_mul32_p = false; + } + return 1; +} + +static void +d30v_number_to_chars (buf, value, n) + char *buf; /* Return 'nbytes' of chars here. */ + long long value; /* The value of the bits. */ + int n; /* Number of bytes in the output. */ +{ + while (n--) + { + buf[n] = value & 0xff; + value >>= 8; + } +} + + +/* This function is called at the start of every line. */ +/* it checks to see if the first character is a '.' */ +/* which indicates the start of a pseudo-op. If it is, */ +/* then write out any unwritten instructions */ + +void +d30v_start_line () +{ + char *c = input_line_pointer; + + while (isspace (*c)) + c++; + + if (*c == '.') + d30v_cleanup (false); +} + +static void +check_size (value, bits, file, line) + long value; + int bits; + char *file; + int line; +{ + int tmp, max; + + if (value < 0) + tmp = ~value; + else + tmp = value; + + max = (1 << (bits - 1)) - 1; + + if (tmp > max) + as_bad_where (file, line, _("value too large to fit in %d bits"), bits); + + return; +} + +/* d30v_frob_label() is called when after a label is recognized. */ + +void +d30v_frob_label (lab) + symbolS *lab; +{ + /* Emit any pending instructions. */ + d30v_cleanup (false); + + /* Update the label's address with the current output pointer. */ + lab->sy_frag = frag_now; + S_SET_VALUE (lab, (valueT) frag_now_fix ()); + + /* Record this label for future adjustment after we find out what + kind of data it references, and the required alignment therewith. */ + d30v_last_label = lab; +} + +/* Hook into cons for capturing alignment changes. */ + +void +d30v_cons_align (size) + int size; +{ + int log_size; + + log_size = 0; + while ((size >>= 1) != 0) + ++log_size; + + if (d30v_current_align < log_size) + d30v_align (log_size, (char *) NULL, NULL); + else if (d30v_current_align > log_size) + d30v_current_align = log_size; + d30v_last_label = NULL; +} + +/* 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-aligning + labels wrt code. */ + +static void +d30v_align (n, pfill, label) + int n; + char *pfill; + symbolS *label; +{ + /* The front end is prone to changing segments out from under us + temporarily when -g is in effect. */ + int switched_seg_p = (d30v_current_align_seg != now_seg); + + /* Do not assume that if 'd30v_current_align >= n' and + '! switched_seg_p' that it is safe to avoid performing + this alignement request. The alignment of the current frag + can be changed under our feet, for example by a .ascii + directive in the source code. cf testsuite/gas/d30v/reloc.s */ + + d30v_cleanup (false); + + if (pfill == NULL) + { + if (n > 2 + && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0) + { + static char const nop[4] = { 0x00, 0xf0, 0x00, 0x00 }; + + /* First, make sure we're on a four-byte boundary, in case + someone has been putting .byte values the text section. */ + if (d30v_current_align < 2 || switched_seg_p) + frag_align (2, 0, 0); + frag_align_pattern (n, nop, sizeof nop, 0); + } + else + frag_align (n, 0, 0); + } + else + frag_align (n, *pfill, 0); + + if (!switched_seg_p) + d30v_current_align = n; + + if (label != NULL) + { + symbolS * sym; + int label_seen = false; + struct frag * old_frag; + valueT old_value; + valueT new_value; + + assert (S_GET_SEGMENT (label) == now_seg); + + old_frag = label->sy_frag; + old_value = S_GET_VALUE (label); + new_value = (valueT) frag_now_fix (); + + /* It is possible to have more than one label at a particular + address, especially if debugging is enabled, so we must + take care to adjust all the labels at this address in this + fragment. To save time we search from the end of the symbol + list, backwards, since the symbols we are interested in are + almost certainly the ones that were most recently added. + Also to save time we stop searching once we have seen at least + one matching label, and we encounter a label that is no longer + in the target fragment. Note, this search is guaranteed to + find at least one match when sym == label, so no special case + code is necessary. */ + for (sym = symbol_lastP; sym != NULL; sym = sym->sy_previous) + { + if (sym->sy_frag == old_frag && S_GET_VALUE (sym) == old_value) + { + label_seen = true; + sym->sy_frag = frag_now; + S_SET_VALUE (sym, new_value); + } + else if (label_seen && sym->sy_frag != old_frag) + break; + } + } + + record_alignment (now_seg, n); +} + +/* Handle the .align pseudo-op. This aligns to a power of two. We + hook here to latch the current alignment. */ + +static void +s_d30v_align (ignore) + int ignore; +{ + int align; + char fill, *pfill = NULL; + long max_alignment = 15; + + align = get_absolute_expression (); + if (align > max_alignment) + { + align = max_alignment; + as_warn (_("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; + } + + d30v_last_label = NULL; + d30v_align (align, pfill, NULL); + + demand_empty_rest_of_line (); +} + +/* Handle the .text pseudo-op. This is like the usual one, but it + clears the saved last label and resets known alignment. */ + +static void +s_d30v_text (i) + int i; + +{ + s_text (i); + d30v_last_label = NULL; + d30v_current_align = 0; + d30v_current_align_seg = now_seg; +} + +/* Handle the .data pseudo-op. This is like the usual one, but it + clears the saved last label and resets known alignment. */ + +static void +s_d30v_data (i) + int i; +{ + s_data (i); + d30v_last_label = NULL; + d30v_current_align = 0; + d30v_current_align_seg = now_seg; +} + +/* Handle the .section pseudo-op. This is like the usual one, but it + clears the saved last label and resets known alignment. */ + +static void +s_d30v_section (ignore) + int ignore; +{ + obj_elf_section (ignore); + d30v_last_label = NULL; + d30v_current_align = 0; + d30v_current_align_seg = now_seg; +} diff --git a/gas/config/tc-d30v.h b/gas/config/tc-d30v.h new file mode 100644 index 0000000000..acce285693 --- /dev/null +++ b/gas/config/tc-d30v.h @@ -0,0 +1,59 @@ +/* tc-310v.h -- Header file for tc-d30v.c. + Copyright (C) 1997 Free Software Foundation, Inc. + Written by Martin Hunt, 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_D30V + +#ifndef BFD_ASSEMBLER + #error D30V support requires BFD_ASSEMBLER +#endif + +/* The target BFD architecture. */ +#define TARGET_ARCH bfd_arch_d30v +#define TARGET_FORMAT "elf32-d30v" +#define TARGET_BYTES_BIG_ENDIAN 1 + +#define md_operand(x) + +#define MD_APPLY_FIX3 + +/* call md_pcrel_from_section, not md_pcrel_from */ +#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC) + +/* 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_bigendian + +int d30v_cleanup PARAMS ((int)); +#define md_after_pass_hook() d30v_cleanup (false) +#define md_cleanup() d30v_cleanup (false) +#define TC_START_LABEL(ch, ptr) (ch == ':' && d30v_cleanup (false)) +#define md_start_line_hook() d30v_start_line (false) + +void d30v_frob_label PARAMS ((struct symbol *)); +#define tc_frob_label(sym) d30v_frob_label(sym) + +void d30v_cons_align PARAMS ((int)); +#define md_cons_align(nbytes) d30v_cons_align(nbytes) diff --git a/gas/config/tc-fr30.c b/gas/config/tc-fr30.c new file mode 100644 index 0000000000..aa075b7322 --- /dev/null +++ b/gas/config/tc-fr30.c @@ -0,0 +1,664 @@ +/* tc-fr30.c -- Assembler for the Fujitsu FR30. + Copyright (C) 1998, 1999 Free Software Foundation. + + 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 +#include +#include "as.h" +#include "subsegs.h" +#include "symcat.h" +#include "opcodes/fr30-desc.h" +#include "opcodes/fr30-opc.h" +#include "cgen.h" + +/* Structure to hold all of the different components describing + an individual instruction. */ +typedef struct +{ + const CGEN_INSN * insn; + const CGEN_INSN * orig_insn; + CGEN_FIELDS fields; +#if CGEN_INT_INSN_P + CGEN_INSN_INT buffer [1]; +#define INSN_VALUE(buf) (*(buf)) +#else + unsigned char buffer [CGEN_MAX_INSN_SIZE]; +#define INSN_VALUE(buf) (buf) +#endif + char * addr; + fragS * frag; + int num_fixups; + fixS * fixups [GAS_CGEN_MAX_FIXUPS]; + int indices [MAX_OPERAND_INSTANCES]; +} +fr30_insn; + +const char comment_chars[] = ";"; +const char line_comment_chars[] = "#"; +const char line_separator_chars[] = "|"; +const char EXP_CHARS[] = "eE"; +const char FLT_CHARS[] = "dD"; + +#define FR30_SHORTOPTS "" +const char * md_shortopts = FR30_SHORTOPTS; + +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) + { + default: + return 0; + } + return 1; +} + +void +md_show_usage (stream) + FILE * stream; +{ + fprintf (stream, _(" FR30 specific command line options:\n")); +} + +/* The target specific pseudo-ops which we support. */ +const pseudo_typeS md_pseudo_table[] = +{ + { "word", cons, 4 }, + { NULL, NULL, 0 } +}; + + +void +md_begin () +{ + flagword applicable; + segT seg; + subsegT subseg; + + /* Initialize the `cgen' interface. */ + + /* Set the machine number and endian. */ + gas_cgen_cpu_desc = fr30_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0, + CGEN_CPU_OPEN_ENDIAN, + CGEN_ENDIAN_BIG, + CGEN_CPU_OPEN_END); + fr30_cgen_init_asm (gas_cgen_cpu_desc); + + /* This is a callback from cgen to gas to parse operands. */ + cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand); +} + +void +md_assemble (str) + char * str; +{ + static int last_insn_had_delay_slot = 0; + fr30_insn insn; + char * errmsg; + char * str2 = NULL; + + /* Initialize GAS's cgen interface for a new instruction. */ + gas_cgen_init_parse (); + + insn.insn = fr30_cgen_assemble_insn + (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg); + + if (!insn.insn) + { + as_bad (errmsg); + return; + } + + /* Doesn't really matter what we pass for RELAX_P here. */ + gas_cgen_finish_insn (insn.insn, insn.buffer, + CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL); + + /* Warn about invalid insns in delay slots. */ + if (last_insn_had_delay_slot + && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_NOT_IN_DELAY_SLOT)) + as_warn (_("Instruction %s not allowed in a delay slot."), + CGEN_INSN_NAME (insn.insn)); + + last_insn_had_delay_slot + = CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT); +} + +/* The syntax in the manual says constants begin with '#'. + We just ignore it. */ + +void +md_operand (expressionP) + expressionS * expressionP; +{ + if (* input_line_pointer == '#') + { + input_line_pointer ++; + expression (expressionP); + } +} + +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)); +} + +symbolS * +md_undefined_symbol (name) + char * name; +{ + return 0; +} + +/* Interface to relax_segment. */ + +/* FIXME: Build table by hand, get it working, then machine generate. */ + +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 add to the size of the current frag + 4) which index into the table to try if we can't fit into this one. */ + + /* The first entry must be unused because an `rlx_more' value of zero ends + each list. */ + {1, 1, 0, 0}, + + /* The displacement used by GAS is from the end of the 2 byte insn, + so we subtract 2 from the following. */ + /* 16 bit insn, 8 bit disp -> 10 bit range. + This doesn't handle a branch in the right slot at the border: + the "& -4" isn't taken into account. It's not important enough to + complicate things over it, so we subtract an extra 2 (or + 2 in -ve + case). */ + {511 - 2 - 2, -512 - 2 + 2, 0, 2 }, + /* 32 bit insn, 24 bit disp -> 26 bit range. */ + {0x2000000 - 1 - 2, -0x2000000 - 2, 2, 0 }, + /* Same thing, but with leading nop for alignment. */ + {0x2000000 - 1 - 2, -0x2000000 - 2, 4, 0 } +}; + +long +fr30_relax_frag (fragP, stretch) + fragS * fragP; + long stretch; +{ + /* Address of branch insn. */ + long address = fragP->fr_address + fragP->fr_fix - 2; + long growth = 0; + + /* Keep 32 bit insns aligned on 32 bit boundaries. */ + if (fragP->fr_subtype == 2) + { + if ((address & 3) != 0) + { + fragP->fr_subtype = 3; + growth = 2; + } + } + else if (fragP->fr_subtype == 3) + { + if ((address & 3) == 0) + { + fragP->fr_subtype = 2; + growth = -2; + } + } + else + { + growth = relax_frag (fragP, stretch); + + /* Long jump on odd halfword boundary? */ + if (fragP->fr_subtype == 2 && (address & 3) != 0) + { + fragP->fr_subtype = 3; + growth += 2; + } + } + + return growth; +} + +/* Return an initial guess of the length by which a fragment must grow to + hold a branch to reach its destination. + Also updates fr_type/fr_subtype as necessary. + + Called just before doing relaxation. + Any symbol that is now undefined will not become defined. + The guess for fr_var is ACTUALLY the growth beyond fr_fix. + Whatever we do to grow fr_fix or fr_var contributes to our returned value. + Although it may not be explicit in the frag, pretend fr_var starts with a + 0 value. */ + +int +md_estimate_size_before_relax (fragP, segment) + fragS * fragP; + segT segment; +{ + int old_fr_fix = fragP->fr_fix; + + /* The only thing we have to handle here are symbols outside of the + current segment. They may be undefined or in a different segment in + which case linker scripts may place them anywhere. + However, we can't finish the fragment here and emit the reloc as insn + alignment requirements may move the insn about. */ + + if (S_GET_SEGMENT (fragP->fr_symbol) != segment) + { + /* The symbol is undefined in this segment. + Change the relaxation subtype to the max allowable and leave + all further handling to md_convert_frag. */ + fragP->fr_subtype = 2; + +#if 0 /* Can't use this, but leave in for illustration. */ + /* Change 16 bit insn to 32 bit insn. */ + fragP->fr_opcode[0] |= 0x80; + + /* Increase known (fixed) size of fragment. */ + fragP->fr_fix += 2; + + /* Create a relocation for it. */ + fix_new (fragP, old_fr_fix, 4, + fragP->fr_symbol, + fragP->fr_offset, 1 /* pcrel */, + /* FIXME: Can't use a real BFD reloc here. + gas_cgen_md_apply_fix3 can't handle it. */ + BFD_RELOC_FR30_26_PCREL); + + /* Mark this fragment as finished. */ + frag_wane (fragP); +#else + { + const CGEN_INSN * insn; + int i; + + /* Update the recorded insn. + Fortunately we don't have to look very far. + FIXME: Change this to record in the instruction the next higher + relaxable insn to use. */ + for (i = 0, insn = fragP->fr_cgen.insn; i < 4; i++, insn++) + { + if ((strcmp (CGEN_INSN_MNEMONIC (insn), + CGEN_INSN_MNEMONIC (fragP->fr_cgen.insn)) + == 0) + && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX)) + break; + } + if (i == 4) + abort (); + + fragP->fr_cgen.insn = insn; + return 2; + } +#endif + } + + return (fragP->fr_var + fragP->fr_fix - old_fr_fix); +} + +/* *fragP has been relaxed to its final size, and now needs to have + the bytes inside it modified to conform to the new size. + + Called after relaxation is finished. + fragP->fr_type == rs_machine_dependent. + fragP->fr_subtype is the subtype of what the address relaxed to. */ + +void +md_convert_frag (abfd, sec, fragP) + bfd * abfd; + segT sec; + fragS * fragP; +{ +#if 0 + char * opcode; + char * displacement; + int target_address; + int opcode_address; + int extension; + int addend; + + opcode = fragP->fr_opcode; + + /* Address opcode resides at in file space. */ + opcode_address = fragP->fr_address + fragP->fr_fix - 2; + + switch (fragP->fr_subtype) + { + case 1 : + extension = 0; + displacement = & opcode[1]; + break; + case 2 : + opcode[0] |= 0x80; + extension = 2; + displacement = & opcode[1]; + break; + case 3 : + opcode[2] = opcode[0] | 0x80; + md_number_to_chars (opcode, PAR_NOP_INSN, 2); + opcode_address += 2; + extension = 4; + displacement = & opcode[3]; + break; + default : + abort (); + } + + if (S_GET_SEGMENT (fragP->fr_symbol) != sec) + { + /* symbol must be resolved by linker */ + if (fragP->fr_offset & 3) + as_warn (_("Addend to unresolved symbol not on word boundary.")); + addend = fragP->fr_offset >> 2; + } + else + { + /* Address we want to reach in file space. */ + target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset; + target_address += fragP->fr_symbol->sy_frag->fr_address; + addend = (target_address - (opcode_address & -4)) >> 2; + } + + /* Create a relocation for symbols that must be resolved by the linker. + Otherwise output the completed insn. */ + + if (S_GET_SEGMENT (fragP->fr_symbol) != sec) + { + assert (fragP->fr_subtype != 1); + assert (fragP->fr_cgen.insn != 0); + gas_cgen_record_fixup (fragP, + /* Offset of branch insn in frag. */ + fragP->fr_fix + extension - 4, + fragP->fr_cgen.insn, + 4 /*length*/, + /* FIXME: quick hack */ +#if 0 + CGEN_OPERAND_ENTRY (fragP->fr_cgen.opindex), +#else + CGEN_OPERAND_ENTRY (FR30_OPERAND_DISP24), +#endif + fragP->fr_cgen.opinfo, + fragP->fr_symbol, fragP->fr_offset); + } + +#define SIZE_FROM_RELAX_STATE(n) ((n) == 1 ? 1 : 3) + + md_number_to_chars (displacement, (valueT) addend, + SIZE_FROM_RELAX_STATE (fragP->fr_subtype)); + + fragP->fr_fix += extension; +#endif +} + +/* 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; +{ + if (fixP->fx_addsy != (symbolS *) NULL + && (! S_IS_DEFINED (fixP->fx_addsy) + || S_GET_SEGMENT (fixP->fx_addsy) != sec)) + { + /* The symbol is undefined (or is defined but not in this section). + Let the linker figure it out. */ + return 0; + } + + return (fixP->fx_frag->fr_address + fixP->fx_where) & ~1; +} + +/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP. + Returns BFD_RELOC_NONE if no reloc type can be found. + *FIXP may be modified if desired. */ + +bfd_reloc_code_real_type +md_cgen_lookup_reloc (insn, operand, fixP) + const CGEN_INSN * insn; + const CGEN_OPERAND * operand; + fixS * fixP; +{ + switch (operand->type) + { + case FR30_OPERAND_LABEL9: fixP->fx_pcrel = 1; return BFD_RELOC_FR30_9_PCREL; + case FR30_OPERAND_LABEL12: fixP->fx_pcrel = 1; return BFD_RELOC_FR30_12_PCREL; + case FR30_OPERAND_DISP10: return BFD_RELOC_FR30_10_IN_8; + case FR30_OPERAND_DISP9: return BFD_RELOC_FR30_9_IN_8; + case FR30_OPERAND_DISP8: return BFD_RELOC_FR30_8_IN_8; + case FR30_OPERAND_UDISP6: return BFD_RELOC_FR30_6_IN_4; + case FR30_OPERAND_I8: return BFD_RELOC_8; + case FR30_OPERAND_I32: return BFD_RELOC_FR30_48; + case FR30_OPERAND_I20: return BFD_RELOC_FR30_20; + default : /* avoid -Wall warning */ + break; + } + + return BFD_RELOC_NONE; +} + +/* 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 +fr30_force_relocation (fix) + fixS * fix; +{ + if ( fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT + || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + return 1; + + 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; +{ + number_to_chars_bigendian (buf, val, n); +} + +/* 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; + int prec; + LITTLENUM_TYPE words [MAX_LITTLENUMS]; + 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; + + /* FIXME: Some targets allow other format chars for bigger sizes here. */ + + 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 (i = 0; i < prec; i++) + { + md_number_to_chars (litP, (valueT) words[i], + sizeof (LITTLENUM_TYPE)); + litP += sizeof (LITTLENUM_TYPE); + } + + return 0; +} + +/* Worker function for fr30_is_colon_insn(). */ +static char +restore_colon (advance_i_l_p_by) + int advance_i_l_p_by; +{ + char c; + + /* Restore the colon, and advance input_line_pointer to + the end of the new symbol. */ + * input_line_pointer = ':'; + input_line_pointer += advance_i_l_p_by; + c = * input_line_pointer; + * input_line_pointer = 0; + + return c; +} + +/* Determines if the symbol starting at START and ending in + a colon that was at the location pointed to by INPUT_LINE_POINTER + (but which has now been replaced bu a NUL) is in fact an + LDI:8, LDI:20, LDI:32, CALL:D. JMP:D, RET:D or Bcc:D instruction. + If it is, then it restores the colon, advances INPUT_LINE_POINTER + to the real end of the instruction/symbol, and returns the character + that really terminated the symbol. Otherwise it returns 0. */ +char +fr30_is_colon_insn (start) + char * start; +{ + char * i_l_p = input_line_pointer; + + /* Check to see if the symbol parsed so far is 'ldi' */ + if ( (start[0] != 'l' && start[0] != 'L') + || (start[1] != 'd' && start[1] != 'D') + || (start[2] != 'i' && start[2] != 'I') + || start[3] != 0) + { + /* Nope - check to see a 'd' follows the colon. */ + if ( (i_l_p[1] == 'd' || i_l_p[1] == 'D') + && (i_l_p[2] == ' ' || i_l_p[2] == '\t' || i_l_p[2] == '\n')) + { + /* Yup - it might be delay slot instruction. */ + int i; + static char * delay_insns [] = + { + "call", "jmp", "ret", "bra", "bno", + "beq", "bne", "bc", "bnc", "bn", + "bp", "bv", "bnv", "blt", "bge", + "ble", "bgt", "bls", "bhi" + }; + + for (i = sizeof (delay_insns) / sizeof (delay_insns[0]); i--;) + { + char * insn = delay_insns[i]; + int len = strlen (insn); + + if (start [len] != 0) + continue; + + while (len --) + if (tolower (start [len]) != insn [len]) + break; + + if (len == -1) + return restore_colon (1); + } + } + + /* Nope - it is a normal label. */ + return 0; + } + + /* Check to see if the text following the colon is '8' */ + if (i_l_p[1] == '8' && (i_l_p[2] == ' ' || i_l_p[2] == '\t')) + return restore_colon (2); + + /* Check to see if the text following the colon is '20' */ + else if (i_l_p[1] == '2' && i_l_p[2] =='0' && (i_l_p[3] == ' ' || i_l_p[3] == '\t')) + return restore_colon (3); + + /* Check to see if the text following the colon is '32' */ + else if (i_l_p[1] == '3' && i_l_p[2] =='2' && (i_l_p[3] == ' ' || i_l_p[3] == '\t')) + return restore_colon (3); + + return 0; +} + +boolean +fr30_fix_adjustable (fixP) + fixS * fixP; +{ + if (fixP->fx_addsy == NULL) + return 1; + +#if 0 + /* Prevent all adjustments to global symbols. */ + if (S_IS_EXTERN (fixP->fx_addsy)) + return 0; + + if (S_IS_WEAK (fixP->fx_addsy)) + return 0; +#endif + + /* 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; +} diff --git a/gas/config/tc-fr30.h b/gas/config/tc-fr30.h new file mode 100644 index 0000000000..a672d8bab1 --- /dev/null +++ b/gas/config/tc-fr30.h @@ -0,0 +1,81 @@ +/* tc-fr30.h -- Header file for tc-fr30.c. + Copyright (C) 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. */ + +#define TC_FR30 + +#ifndef BFD_ASSEMBLER +/* leading space so will compile with cc */ + #error FR30 support requires BFD_ASSEMBLER +#endif + +#define LISTING_HEADER "FR30 GAS " + +/* The target BFD architecture. */ +#define TARGET_ARCH bfd_arch_fr30 + +#define TARGET_FORMAT "elf32-fr30" + +#define TARGET_BYTES_BIG_ENDIAN 1 + +/* call md_pcrel_from_section, not md_pcrel_from */ +long md_pcrel_from_section PARAMS ((struct fix *, segT)); +#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC) + +/* 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_APPLY_FIX3 +#define md_apply_fix3 gas_cgen_md_apply_fix3 + +#define obj_fix_adjustable(fixP) fr30_fix_adjustable (fixP) +extern boolean fr30_fix_adjustable PARAMS ((struct fix *)); + +/* When relaxing, we need to emit various relocs we otherwise wouldn't. */ +#define TC_FORCE_RELOCATION(fix) fr30_force_relocation (fix) +extern int fr30_force_relocation PARAMS ((struct fix *)); + +#define TC_HANDLES_FX_DONE + +#define tc_gen_reloc gas_cgen_tc_gen_reloc + +/* Call md_pcrel_from_section(), not md_pcrel_from(). */ +#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC) +extern long md_pcrel_from_section PARAMS ((struct fix *, segT)); + +/* For 8 vs 16 vs 32 bit branch selection. */ +#define TC_GENERIC_RELAX_TABLE md_relax_table +extern const struct relax_type md_relax_table[]; + +/* We need a special version of the TC_START_LABEL macro so that we + allow the LDI:8, LDI:20, LDI:32 and delay slot instructions to be + parsed as such. Note - in a HORRIBLE HACK, we make use of the + knowledge that this marco is only ever evaluated in one place + (read_a_source_file in read.c) where we can access the local + variable 's' - the start of the symbol that was terminated by + 'character'. Also we need to be able to change the contents of + the local variable 'c' which is passed to this macro as 'character'. */ +#define TC_START_LABEL(character, i_l_p) \ + ((character) != ':' ? 0 : (character = fr30_is_colon_insn (s)) ? 0 : ((character = ':'), 1)) +extern char fr30_is_colon_insn PARAMS ((char *)); diff --git a/gas/config/tc-generic.c b/gas/config/tc-generic.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gas/config/tc-generic.h b/gas/config/tc-generic.h new file mode 100644 index 0000000000..72df020316 --- /dev/null +++ b/gas/config/tc-generic.h @@ -0,0 +1,39 @@ +/* This file is tc-generic.h + + Copyright (C) 1987, 91, 92, 95, 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/gas/config/tc-h8300.c b/gas/config/tc-h8300.c new file mode 100644 index 0000000000..115ada1542 --- /dev/null +++ b/gas/config/tc-h8300.c @@ -0,0 +1,1595 @@ +/* tc-h8300.c -- Assemble code for the Hitachi H8/300 + Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation. + + 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 +#include "as.h" +#include "subsegs.h" +#include "bfd.h" +#define DEFINE_TABLE +#define h8_opcodes ops +#include "opcode/h8300.h" +#include + +const char comment_chars[] = +{';', 0}; +const char line_separator_chars[] = +{0}; +const char line_comment_chars[] = "#"; + +/* 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 + */ + +void cons (); + +int Hmode; +int Smode; +#define PSIZE (Hmode ? L_32 : L_16) +#define DMODE (L_16) +#define DSYMMODE (Hmode ? L_24 : L_16) +int bsize = L_8; /* default branch displacement */ + + +void +h8300hmode () +{ + Hmode = 1; + Smode = 0; +} + +void +h8300smode () +{ + Smode = 1; + Hmode = 1; +} +void +sbranch (size) + int size; +{ + bsize = size; +} + +static void pint () +{ + cons (Hmode ? 4 : 2); +} + +const pseudo_typeS md_pseudo_table[] = +{ + + {"h8300h", h8300hmode, 0}, + {"h8300s", h8300smode, 0}, + {"sbranch", sbranch, L_8}, + {"lbranch", sbranch, L_16}, + + {"int", pint, 0}, + {"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}, + {0, 0, 0} +}; + +const int md_reloc_size; + +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"; + +static struct hash_control *opcode_hash_control; /* Opcode mnemonics */ + +/* + 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 () +{ + struct h8_opcode *opcode; + char prev_buffer[100]; + int idx = 0; + + opcode_hash_control = hash_new (); + prev_buffer[0] = 0; + + for (opcode = h8_opcodes; opcode->name; opcode++) + { + /* Strip off any . part when inserting the opcode and only enter + unique codes into the hash table + */ + char *src = opcode->name; + unsigned int len = strlen (src); + char *dst = malloc (len + 1); + char *buffer = dst; + + opcode->size = 0; + while (*src) + { + if (*src == '.') + { + src++; + opcode->size = *src; + break; + } + *dst++ = *src++; + } + *dst++ = 0; + if (strcmp (buffer, prev_buffer)) + { + hash_insert (opcode_hash_control, buffer, (char *) opcode); + strcpy (prev_buffer, buffer); + idx++; + } + opcode->idx = idx; + + + /* Find the number of operands */ + opcode->noperands = 0; + while (opcode->args.nib[opcode->noperands] != E) + opcode->noperands++; + /* Find the length of the opcode in bytes */ + opcode->length = 0; + while (opcode->data.nib[opcode->length * 2] != E) + opcode->length++; + } + + linkrelax = 1; +} + + +struct h8_exp +{ + char *e_beg; + char *e_end; + expressionS e_exp; +}; +int dispreg; +int opsize; /* Set when a register size is seen */ + + +struct h8_op +{ + op_type mode; + unsigned reg; + expressionS exp; +}; + +/* + parse operands + WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp + r0l,r0h,..r7l,r7h + @WREG + @WREG+ + @-WREG + #const + ccr +*/ + +/* try and parse a reg name, returns number of chars consumed */ +int +parse_reg (src, mode, reg, direction) + char *src; + op_type *mode; + unsigned int *reg; + int direction; + +{ + char *end; + int len; + + /* Cribbed from get_symbol_end(). */ + if (!is_name_beginner (*src) || *src == '\001') + return 0; + end = src+1; + while (is_part_of_name (*end) || *end == '\001') + end++; + len = end - src; + + if (len == 2 && src[0] == 's' && src[1] == 'p') + { + *mode = PSIZE | REG | direction; + *reg = 7; + return len; + } + if (len == 3 && src[0] == 'c' && src[1] == 'c' && src[2] == 'r') + { + *mode = CCR; + *reg = 0; + return len; + } + if (len == 3 && src[0] == 'e' && src[1] == 'x' && src[2] == 'r') + { + *mode = EXR; + *reg = 0; + return len; + } + if (len == 2 && src[0] == 'f' && src[1] == 'p') + { + *mode = PSIZE | REG | direction; + *reg = 6; + return len; + } + if (len == 3 && src[0] == 'e' && src[1] == 'r' + && src[2] >= '0' && src[2] <= '7') + { + *mode = L_32 | REG | direction; + *reg = src[2] - '0'; + if (!Hmode) + as_warn (_("Reg not valid for H8/300")); + return len; + } + if (len == 2 && src[0] == 'e' && src[1] >= '0' && src[1] <= '7') + { + *mode = L_16 | REG | direction; + *reg = src[1] - '0' + 8; + if (!Hmode) + as_warn (_("Reg not valid for H8/300")); + return len; + } + + if (src[0] == 'r') + { + if (src[1] >= '0' && src[1] <= '7') + { + if (len == 3 && src[2] == 'l') + { + *mode = L_8 | REG | direction; + *reg = (src[1] - '0') + 8; + return len; + } + if (len == 3 && src[2] == 'h') + { + *mode = L_8 | REG | direction; + *reg = (src[1] - '0'); + return len; + } + if (len == 2) + { + *mode = L_16 | REG | direction; + *reg = (src[1] - '0'); + return len; + } + } + } + + return 0; +} + +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; +} + +static char * +skip_colonthing (ptr, exp, mode) + char *ptr; + expressionS *exp; + int *mode; +{ + if (*ptr == ':') + { + ptr++; + *mode &= ~SIZE; + if (*ptr == '8') + { + ptr++; + /* ff fill any 8 bit quantity */ + /* exp->X_add_number -= 0x100;*/ + *mode |= L_8; + } + else + { + if (*ptr == '2') + { + *mode |= L_24; + } + else if (*ptr == '3') + { + *mode |= L_32; + } + else if (*ptr == '1') + { + *mode |= L_16; + } + while (isdigit (*ptr)) + ptr++; + } + } + return ptr; +} + +/* The many forms of operand: + + Rn Register direct + @Rn Register indirect + @(exp[:16], Rn) Register indirect with displacement + @Rn+ + @-Rn + @aa:8 absolute 8 bit + @aa:16 absolute 16 bit + @aa absolute 16 bit + + #xx[:size] immediate data + @(exp:[8], pc) pc rel + @@aa[:8] memory indirect + + */ + +char * +colonmod24 (op, src) + struct h8_op *op; + char *src; + +{ + int mode = 0; + src = skip_colonthing (src, &op->exp, &mode); + + if (!mode) + { + /* Choose a default mode */ + if (op->exp.X_add_number < -32768 + || op->exp.X_add_number > 32767) + { + if (Hmode) + mode = L_24; + else + mode = L_16; + } + else if (op->exp.X_add_symbol + || op->exp.X_op_symbol) + mode = DSYMMODE; + else + mode = DMODE; + } + op->mode |= mode; + return src; + +} + + +static void +get_operand (ptr, op, dst, direction) + char **ptr; + struct h8_op *op; + unsigned int dst; + int direction; +{ + char *src = *ptr; + op_type mode; + unsigned int num; + unsigned int len; + + op->mode = E; + + /* Gross. Gross. ldm and stm have a format not easily handled + by get_operand. We deal with it explicitly here. */ + if (src[0] == 'e' && src[1] == 'r' && isdigit(src[2]) + && src[3] == '-' && src[4] == 'e' && src[5] == 'r' && isdigit(src[6])) + { + int low, high; + + low = src[2] - '0'; + high = src[6] - '0'; + + if (high < low) + as_bad (_("Invalid register list for ldm/stm\n")); + + if (low % 2) + as_bad (_("Invalid register list for ldm/stm\n")); + + if (high - low > 3) + as_bad (_("Invalid register list for ldm/stm\n")); + + if (high - low != 1 + && low % 4) + as_bad (_("Invalid register list for ldm/stm\n")); + + /* Even sicker. We encode two registers into op->reg. One + for the low register to save, the other for the high + register to save; we also set the high bit in op->reg + so we know this is "very special". */ + op->reg = 0x80000000 | (high << 8) | low; + op->mode = REG; + *ptr = src + 7; + return; + } + + len = parse_reg (src, &op->mode, &op->reg, direction); + if (len) + { + *ptr = src + len; + return; + } + + if (*src == '@') + { + src++; + if (*src == '@') + { + src++; + src = parse_exp (src, &op->exp); + + src = skip_colonthing (src, &op->exp, &op->mode); + + *ptr = src; + + op->mode = MEMIND; + return; + + } + + + if (*src == '-') + { + src++; + len = parse_reg (src, &mode, &num, direction); + if (len == 0) + { + /* Oops, not a reg after all, must be ordinary exp */ + src--; + /* must be a symbol */ + op->mode = ABS | PSIZE | direction; + *ptr = skip_colonthing (parse_exp (src, &op->exp), + &op->exp, &op->mode); + + return; + + + } + + + if ((mode & SIZE) != PSIZE) + as_bad (_("Wrong size pointer register for architecture.")); + op->mode = RDDEC; + op->reg = num; + *ptr = src + len; + return; + } + if (*src == '(') + { + /* Disp */ + src++; + + /* Start off assuming a 16 bit offset */ + + + src = parse_exp (src, &op->exp); + + src = colonmod24 (op, src); + + if (*src == ')') + { + src++; + op->mode |= ABS | direction; + *ptr = src; + return; + } + + if (*src != ',') + { + as_bad (_("expected @(exp, reg16)")); + return; + + } + src++; + + len = parse_reg (src, &mode, &op->reg, direction); + if (len == 0 || !(mode & REG)) + { + as_bad (_("expected @(exp, reg16)")); + return; + } + op->mode |= DISP | direction; + dispreg = op->reg; + src += len; + src = skip_colonthing (src, &op->exp, &op->mode); + + if (*src != ')' && '(') + { + as_bad (_("expected @(exp, reg16)")); + return; + } + *ptr = src + 1; + + return; + } + len = parse_reg (src, &mode, &num, direction); + + if (len) + { + src += len; + if (*src == '+') + { + src++; + if ((mode & SIZE) != PSIZE) + as_bad (_("Wrong size pointer register for architecture.")); + op->mode = RSINC; + op->reg = num; + *ptr = src; + return; + } + if ((mode & SIZE) != PSIZE) + as_bad (_("Wrong size pointer register for architecture.")); + + op->mode = direction | IND | PSIZE; + op->reg = num; + *ptr = src; + + return; + } + else + { + /* must be a symbol */ + + op->mode = ABS | direction; + src = parse_exp (src, &op->exp); + + *ptr = colonmod24 (op, src); + + return; + } + } + + + if (*src == '#') + { + src++; + op->mode = IMM; + src = parse_exp (src, &op->exp); + *ptr = skip_colonthing (src, &op->exp, &op->mode); + + return; + } + else if (strncmp (src, "mach", 4) == 0 + || strncmp (src, "macl", 4) == 0) + { + op->reg = src[3] == 'l'; + op->mode = MACREG; + *ptr = src + 4; + return; + } + else + { + src = parse_exp (src, &op->exp); + /* Trailing ':' size ? */ + if (*src == ':') + { + if (src[1] == '1' && src[2] == '6') + { + op->mode = PCREL | L_16; + src += 3; + } + else if (src[1] == '8') + { + op->mode = PCREL | L_8; + src += 2; + } + else + { + as_bad (_("expect :8 or :16 here")); + } + } + else + { + op->mode = PCREL | bsize; + } + *ptr = src; + } +} + + +static +char * +get_operands (noperands, op_end, operand) + unsigned int noperands; + char *op_end; + struct h8_op *operand; +{ + char *ptr = op_end; + + switch (noperands) + { + case 0: + operand[0].mode = 0; + operand[1].mode = 0; + break; + + case 1: + ptr++; + get_operand (&ptr, operand + 0, 0, SRC); + if (*ptr == ',') + { + ptr++; + get_operand (&ptr, operand + 1, 1, DST); + } + else + { + operand[1].mode = 0; + } + + break; + case 2: + ptr++; + get_operand (&ptr, operand + 0, 0, SRC); + if (*ptr == ',') + ptr++; + get_operand (&ptr, operand + 1, 1, DST); + 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 +struct h8_opcode * +get_specific (opcode, operands, size) + struct h8_opcode *opcode; + struct h8_op *operands; + int size; +{ + struct h8_opcode *this_try = opcode; + int found = 0; + + unsigned int this_index = opcode->idx; + + /* There's only one ldm/stm and it's easier to just + get out quick for them. */ + if (strcmp (opcode->name, "stm.l") == 0 + || strcmp (opcode->name, "ldm.l") == 0) + return this_try; + + while (this_index == opcode->idx && !found) + { + found = 1; + + this_try = opcode++; + if (this_try->noperands == 0) + { + int this_size; + + this_size = this_try->how & SN; + if (this_size != size && (this_size != SB || size != SN)) + found = 0; + } + else + { + unsigned int i; + + for (i = 0; i < this_try->noperands && found; i++) + { + op_type op = this_try->args.nib[i]; + int x = operands[i].mode; + + if ((op & (DISP | REG)) == (DISP | REG) + && ((x & (DISP | REG)) == (DISP | REG))) + { + dispreg = operands[i].reg; + } + else if (op & REG) + { + if (!(x & REG)) + found = 0; + + if (x & L_P) + x = (x & ~L_P) | (Hmode ? L_32 : L_16); + if (op & L_P) + op = (op & ~L_P) | (Hmode ? L_32 : L_16); + + opsize = op & SIZE; + + /* The size of the reg is v important */ + if ((op & SIZE) != (x & SIZE)) + found = 0; + } + else if ((op & ABSJMP) && (x & ABS)) + { + operands[i].mode &= ~ABS; + operands[i].mode |= ABSJMP; + /* But it may not be 24 bits long */ + if (!Hmode) + { + operands[i].mode &= ~SIZE; + operands[i].mode |= L_16; + } + } + else if ((op & (KBIT | DBIT)) && (x & IMM)) + { + /* This is ok if the immediate value is sensible */ + } + else if (op & PCREL) + { + /* The size of the displacement is important */ + if ((op & SIZE) != (x & SIZE)) + found = 0; + } + else if ((op & (DISP | IMM | ABS)) + && (op & (DISP | IMM | ABS)) == (x & (DISP | IMM | ABS))) + { + /* Promote a L_24 to L_32 if it makes us match. */ + if ((x & L_24) && (op & L_32)) + { + x &= ~L_24; + x |= L_32; + } + /* Promote an L8 to L_16 if it makes us match. */ + if (op & ABS && op & L_8 && op & DISP) + { + if (x & L_16) + found= 1; + } + else if ((x & SIZE) != 0 + && ((op & SIZE) != (x & SIZE))) + found = 0; + } + else if ((op & MACREG) != (x & MACREG)) + { + found = 0; + } + else if ((op & MODE) != (x & MODE)) + { + found = 0; + } + } + } + } + if (found) + return this_try; + else + return 0; +} + +static void +check_operand (operand, width, string) + struct h8_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)) + { + if (width == 255 + && (operand->exp.X_add_number & 0xff00) == 0xff00) + { + /* Just ignore this one - which happens when trying to + fit a 16 bit address truncated into an 8 bit address + of something like bset. */ + } + else + { + as_warn (_("operand %s0x%lx out of range."), string, + (unsigned long) operand->exp.X_add_number); + } + } + } + +} + +/* RELAXMODE has one of 3 values: + + 0 Output a "normal" reloc, no relaxing possible for this insn/reloc + + 1 Output a relaxable 24bit absolute mov.w address relocation + (may relax into a 16bit absolute address). + + 2 Output a relaxable 16/24 absolute mov.b address relocation + (may relax into an 8bit absolute address). */ + +static void +do_a_fix_imm (offset, operand, relaxmode) + int offset; + struct h8_op *operand; + int relaxmode; +{ + int idx; + int size; + int where; + + + char *t = operand->mode & IMM ? "#" : "@"; + + if (operand->exp.X_add_symbol == 0) + { + char *bytes = frag_now->fr_literal + offset; + switch (operand->mode & SIZE) + { + case L_2: + check_operand (operand, 0x3, t); + bytes[0] |= (operand->exp.X_add_number) << 4; + break; + case L_3: + check_operand (operand, 0x7, t); + bytes[0] |= (operand->exp.X_add_number) << 4; + break; + case L_8: + check_operand (operand, 0xff, t); + bytes[0] = operand->exp.X_add_number; + break; + case L_16: + check_operand (operand, 0xffff, t); + bytes[0] = operand->exp.X_add_number >> 8; + bytes[1] = operand->exp.X_add_number >> 0; + break; + case L_24: + check_operand (operand, 0xffffff, t); + bytes[0] = operand->exp.X_add_number >> 16; + bytes[1] = operand->exp.X_add_number >> 8; + bytes[2] = operand->exp.X_add_number >> 0; + break; + + case L_32: + /* This should be done with bfd */ + bytes[0] = operand->exp.X_add_number >> 24; + bytes[1] = operand->exp.X_add_number >> 16; + bytes[2] = operand->exp.X_add_number >> 8; + bytes[3] = operand->exp.X_add_number >> 0; + break; + } + + } + else + { + switch (operand->mode & SIZE) + { + + case L_24: + case L_32: + size = 4; + where = (operand->mode & SIZE) == L_24 ? -1 : 0; + if (relaxmode == 2) + idx = R_MOV24B1; + else if (relaxmode == 1) + idx = R_MOVL1; + else + idx = R_RELLONG; + break; + default: + as_bad(_("Can't work out size of operand.\n")); + case L_16: + size = 2; + where = 0; + if (relaxmode == 2) + idx = R_MOV16B1; + else + idx = R_RELWORD; + operand->exp.X_add_number = (short)operand->exp.X_add_number; + break; + case L_8: + size = 1; + where = 0; + idx = R_RELBYTE; + /* This used to use a cast to char, but that fails if char is an + unsigned type. We can't use `signed char', as that isn't valid + K&R C. */ + if (operand->exp.X_add_number & 0x80) + operand->exp.X_add_number |= ((offsetT) -1 << 8); + else + operand->exp.X_add_number &= 0xff; + } + + fix_new_exp (frag_now, + offset + where, + size, + &operand->exp, + 0, + idx); + } + +} + +/* Now we know what sort of opcodes it is, lets build the bytes - + */ +static void +build_bytes (this_try, operand) + struct h8_opcode *this_try; + struct h8_op *operand; +{ + unsigned int i; + + char *output = frag_more (this_try->length); + op_type *nibble_ptr = this_try->data.nib; + op_type c; + unsigned int nibble_count = 0; + int absat; + int immat; + int nib; + int movb = 0; + char asnibbles[30]; + char *p = asnibbles; + + if (!(this_try->inbase || Hmode)) + as_warn (_("Opcode `%s' with these operand types not available in H8/300 mode"), + this_try->name); + + while (*nibble_ptr != E) + { + int d; + c = *nibble_ptr++; + + d = (c & (DST | SRC_IN_DST)) != 0; + + if (c < 16) + { + nib = c; + } + else + { + + if (c & (REG | IND | INC | DEC)) + { + nib = operand[d].reg; + } + else if ((c & DISPREG) == (DISPREG)) + { + nib = dispreg; + } + else if (c & ABS ) + { + operand[d].mode = c; + absat = nibble_count / 2; + nib = 0; + } + else if (c & (IMM | PCREL | ABS | ABSJMP | DISP)) + { + operand[d].mode = c; + immat = nibble_count / 2; + nib = 0; + } + else if (c & IGNORE) + { + nib = 0; + } + else if (c & DBIT) + { + switch (operand[0].exp.X_add_number) + { + case 1: + nib = c; + break; + case 2: + nib = 0x8 | c; + break; + default: + as_bad (_("Need #1 or #2 here")); + } + } + else if (c & KBIT) + { + switch (operand[0].exp.X_add_number) + { + case 1: + nib = 0; + break; + case 2: + nib = 8; + break; + case 4: + if (!Hmode) + as_warn (_("#4 not valid on H8/300.")); + nib = 9; + break; + + default: + as_bad (_("Need #1 or #2 here")); + break; + } + /* stop it making a fix */ + operand[0].mode = 0; + } + + if (c & MEMRELAX) + { + operand[d].mode |= MEMRELAX; + } + + if (c & B31) + { + nib |= 0x8; + } + + if (c & MACREG) + { + nib = 2 + operand[d].reg; + } + } + nibble_count++; + + *p++ = nib; + } + + /* Disgusting. Why, oh why didn't someone ask us for advice + on the assembler format. */ + if (strcmp (this_try->name, "stm.l") == 0 + || strcmp (this_try->name, "ldm.l") == 0) + { + int high, low; + high = (operand[this_try->name[0] == 'l' ? 1 : 0].reg >> 8) & 0xf; + low = operand[this_try->name[0] == 'l' ? 1 : 0].reg & 0xf; + + asnibbles[2] = high - low; + asnibbles[7] = (this_try->name[0] == 'l') ? high : low; + } + + for (i = 0; i < this_try->length; i++) + { + output[i] = (asnibbles[i * 2] << 4) | asnibbles[i * 2 + 1]; + } + + /* Note if this is a movb instruction -- there's a special relaxation + which only applies to them. */ + if (strcmp (this_try->name, "mov.b") == 0) + movb = 1; + + /* output any fixes */ + for (i = 0; i < 2; i++) + { + int x = operand[i].mode; + + if (x & (IMM | DISP)) + { + do_a_fix_imm (output - frag_now->fr_literal + immat, + operand + i, x & MEMRELAX != 0); + } + else if (x & ABS) + { + do_a_fix_imm (output - frag_now->fr_literal + absat, + operand + i, x & MEMRELAX ? movb + 1 : 0); + } + else if (x & PCREL) + { + int size16 = x & L_16; + int where = size16 ? 2 : 1; + int size = size16 ? 2 : 1; + int type = size16 ? R_PCRWORD : R_PCRBYTE; + + check_operand (operand + i, size16 ? 0x7fff : 0x7f, "@"); + + if (operand[i].exp.X_add_number & 1) + { + as_warn (_("branch operand has odd offset (%lx)\n"), + (unsigned long) operand->exp.X_add_number); + } + + operand[i].exp.X_add_number -= 1; + /* This used to use a cast to char, but that fails if char is an + unsigned type. We can't use `signed char', as that isn't valid + K&R C. */ + if (operand[i].exp.X_add_number & 0x80) + operand[i].exp.X_add_number |= ((offsetT) -1 << 8); + else + operand[i].exp.X_add_number &= 0xff; + + fix_new_exp (frag_now, + output - frag_now->fr_literal + where, + size, + &operand[i].exp, + 1, + type); + } + else if (x & MEMIND) + { + + check_operand (operand + i, 0xff, "@@"); + fix_new_exp (frag_now, + output - frag_now->fr_literal + 1, + 1, + &operand[i].exp, + 0, + R_MEM_INDIRECT); + } + else if (x & ABSJMP) + { + /* This jmp may be a jump or a branch */ + + check_operand (operand + i, Hmode ? 0xffffff : 0xffff, "@"); + if (operand[i].exp.X_add_number & 1) + { + as_warn (_("branch operand has odd offset (%lx)\n"), + (unsigned long) operand->exp.X_add_number); + } + if (!Hmode) + operand[i].exp.X_add_number = (short) operand[i].exp.X_add_number; + fix_new_exp (frag_now, + output - frag_now->fr_literal, + 4, + &operand[i].exp, + 0, + R_JMPL1); + } + } + +} + +/* + try and give an intelligent error message for common and simple to + detect errors + */ + +static void +clever_message (opcode, operand) + struct h8_opcode *opcode; + struct h8_op *operand; +{ + /* Find out if there was more than one possible opccode */ + + if ((opcode + 1)->idx != opcode->idx) + { + unsigned int argn; + + /* Only one opcode of this flavour, try and guess which operand + didn't match */ + for (argn = 0; argn < opcode->noperands; argn++) + { + switch (opcode->args.nib[argn]) + { + case RD16: + if (operand[argn].mode != RD16) + { + as_bad (_("destination operand must be 16 bit register")); + return; + + } + break; + + case RS8: + + if (operand[argn].mode != RS8) + { + as_bad (_("source operand must be 8 bit register")); + return; + } + break; + + case ABS16DST: + if (operand[argn].mode != ABS16DST) + { + as_bad (_("destination operand must be 16bit absolute address")); + return; + } + break; + case RD8: + if (operand[argn].mode != RD8) + { + as_bad (_("destination operand must be 8 bit register")); + return; + } + break; + + + case ABS16SRC: + if (operand[argn].mode != ABS16SRC) + { + as_bad (_("source operand must be 16bit absolute address")); + return; + } + break; + + } + } + } + as_bad (_("invalid operands")); +} + +/* This is the guts of the machine-dependent assembler. STR points to a + machine dependent instruction. This funciton is supposed to emit + the frags/bytes it assembles to. + */ + + + +void +md_assemble (str) + char *str; +{ + char *op_start; + char *op_end; + struct h8_op operand[2]; + struct h8_opcode *opcode; + struct h8_opcode *prev_opcode; + + char *dot = 0; + char c; + int size; + + /* 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 == '.') + { + dot = op_end + 1; + *op_end = 0; + op_end += 2; + break; + } + } + + ; + + if (op_end == op_start) + { + as_bad (_("can't find opcode ")); + } + c = *op_end; + + *op_end = 0; + + opcode = (struct h8_opcode *) hash_find (opcode_hash_control, + op_start); + + if (opcode == NULL) + { + as_bad (_("unknown opcode")); + return; + } + + /* We use to set input_line_pointer to the result of get_operands, + but that is wrong. Our caller assumes we don't change it. */ + + (void) get_operands (opcode->noperands, op_end, operand); + *op_end = c; + prev_opcode = opcode; + + size = SN; + if (dot) + { + switch (*dot) + { + case 'b': + size = SB; + break; + + case 'w': + size = SW; + break; + + case 'l': + size = SL; + break; + } + } + opcode = get_specific (opcode, operand, size); + + if (opcode == 0) + { + /* Couldn't find an opcode which matched the operands */ + char *where = frag_more (2); + + where[0] = 0x0; + where[1] = 0x0; + clever_message (prev_opcode, operand); + + return; + } + if (opcode->size && dot) + { + if (opcode->size != *dot) + { + as_warn (_("mismatch between opcode size and operand size")); + } + } + + build_bytes (opcode, operand); + +} + +void +tc_crawl_symbol_chain (headers) + object_headers * headers; +{ + printf (_("call to tc_crawl_symbol_chain \n")); +} + +symbolS * +md_undefined_symbol (name) + char *name; +{ + return 0; +} + +void +tc_headers_hook (headers) + object_headers * headers; +{ + 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 = ""; +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; +{ + return 0; +} + +void +md_show_usage (stream) + FILE *stream; +{ +} + +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; + segT seg; + fragS *fragP; +{ + 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_fix (fixP, val) + fixS *fixP; + long val; +{ + char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; + + switch (fixP->fx_size) + { + case 1: + *buf++ = val; + break; + case 2: + *buf++ = (val >> 8); + *buf++ = val; + break; + case 4: + *buf++ = (val >> 24); + *buf++ = (val >> 16); + *buf++ = (val >> 8); + *buf++ = val; + break; + default: + abort (); + } +} + +int +md_estimate_size_before_relax (fragP, segment_type) + register fragS *fragP; + register segT segment_type; +{ + 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; +{ + abort (); +} + + +void +tc_reloc_mangle (fix_ptr, intr, base) + fixS *fix_ptr; + struct internal_reloc *intr; + bfd_vma base; + +{ + symbolS *symbol_ptr; + + 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 == TC_CONS_RELOC) + { + /* cons likes to create reloc32's whatever the size of the reloc.. + */ + switch (fix_ptr->fx_size) + { + case 4: + intr->r_type = R_RELLONG; + break; + case 2: + intr->r_type = R_RELWORD; + break; + case 1: + intr->r_type = R_RELBYTE; + 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) + { + if (symbol_ptr->sy_number != -1) + intr->r_symndx = symbol_ptr->sy_number; + else + { + symbolS *segsym; + + /* This case arises when a reference is made to `.'. */ + segsym = seg_info (S_GET_SEGMENT (symbol_ptr))->dot; + if (segsym == NULL) + intr->r_symndx = -1; + else + { + intr->r_symndx = segsym->sy_number; + intr->r_offset += S_GET_VALUE (symbol_ptr); + } + } + } + else + intr->r_symndx = -1; + + +} + +/* end of tc-h8300.c */ diff --git a/gas/config/tc-h8300.h b/gas/config/tc-h8300.h new file mode 100644 index 0000000000..2a2a7040f3 --- /dev/null +++ b/gas/config/tc-h8300.h @@ -0,0 +1,58 @@ +/* This file is tc-h8300.h + Copyright (C) 1987-1992, 93, 94, 95, 96, 97, 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. */ + + +#define TC_H8300 + +#define TARGET_BYTES_BIG_ENDIAN 1 + +#if ANSI_PROTOTYPES +struct internal_reloc; +#endif + +#define WORKING_DOT_WORD + +/* This macro translates between an internal fix and an coff reloc type */ +#define TC_COFF_FIX2RTYPE(fixP) abort(); + +#define BFD_ARCH bfd_arch_h8300 +#define COFF_MAGIC ( Smode ? 0x8302 : Hmode ? 0x8301 : 0x8300) +#define TC_COUNT_RELOC(x) (1) +#define IGNORE_NONSTANDARD_ESCAPES + +#define tc_coff_symbol_emit_hook(a) ; /* not used */ +#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 TC_CONS_RELOC (Hmode ? R_RELLONG: R_RELWORD) + +#define DO_NOT_STRIP 0 +#define LISTING_HEADER "Hitachi H8/300 GAS " +#define NEED_FX_R_TYPE 1 +#define RELOC_32 1234 + +extern int Hmode; +extern int Smode; + +#define md_operand(x) + +/* end of tc-h8300.h */ diff --git a/gas/config/tc-h8500.c b/gas/config/tc-h8500.c new file mode 100644 index 0000000000..9dec3e2e6a --- /dev/null +++ b/gas/config/tc-h8500.c @@ -0,0 +1,1633 @@ +/* tc-h8500.c -- Assemble code for the Hitachi H8/500 + Copyright (C) 1993, 94, 95, 1998 Free Software Foundation. + + 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 +#include "as.h" +#include "bfd.h" +#include "subsegs.h" +#define DEFINE_TABLE +#define ASSEMBLER_TABLE +#include "opcodes/h8500-opc.h" +#include + +const char comment_chars[] = "!"; +const char line_separator_chars[] = ";"; +const char line_comment_chars[] = "!#"; + +/* 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 + */ + +void cons (); + +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}, + {0, 0, 0} +}; + +const int md_reloc_size; + +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) << 2) + (length)) + +#define GET_WHAT(x) ((x>>2)) + +#define BYTE_DISP 1 +#define WORD_DISP 2 +#define UNDEF_BYTE_DISP 0 +#define UNDEF_WORD_DISP 3 + +#define BRANCH 1 +#define SCB_F 2 +#define SCB_TST 3 +#define END 4 + +#define BYTE_F 127 +#define BYTE_B -126 +#define WORD_F 32767 +#define WORD_B 32768 + +relax_typeS md_relax_table[C (END, 0)]; + +static struct hash_control *opcode_hash_control; /* Opcode mnemonics */ + +/* + 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 () +{ + h8500_opcode_info *opcode; + char prev_buffer[100]; + int idx = 0; + register relax_typeS *table; + + opcode_hash_control = hash_new (); + prev_buffer[0] = 0; + + /* Insert unique names into hash table */ + for (opcode = h8500_table; opcode->name; opcode++) + { + if (idx != opcode->idx) + { + hash_insert (opcode_hash_control, opcode->name, (char *) opcode); + idx++; + } + } + + /* Initialize the relax table. We use a local variable to avoid + warnings about modifying a supposedly const data structure. */ + table = (relax_typeS *) md_relax_table; + table[C (BRANCH, BYTE_DISP)].rlx_forward = BYTE_F; + table[C (BRANCH, BYTE_DISP)].rlx_backward = BYTE_B; + table[C (BRANCH, BYTE_DISP)].rlx_length = 2; + table[C (BRANCH, BYTE_DISP)].rlx_more = C (BRANCH, WORD_DISP); + + table[C (BRANCH, WORD_DISP)].rlx_forward = WORD_F; + table[C (BRANCH, WORD_DISP)].rlx_backward = WORD_B; + table[C (BRANCH, WORD_DISP)].rlx_length = 3; + table[C (BRANCH, WORD_DISP)].rlx_more = 0; + + table[C (SCB_F, BYTE_DISP)].rlx_forward = BYTE_F; + table[C (SCB_F, BYTE_DISP)].rlx_backward = BYTE_B; + table[C (SCB_F, BYTE_DISP)].rlx_length = 3; + table[C (SCB_F, BYTE_DISP)].rlx_more = C (SCB_F, WORD_DISP); + + table[C (SCB_F, WORD_DISP)].rlx_forward = WORD_F; + table[C (SCB_F, WORD_DISP)].rlx_backward = WORD_B; + table[C (SCB_F, WORD_DISP)].rlx_length = 8; + table[C (SCB_F, WORD_DISP)].rlx_more = 0; + + table[C (SCB_TST, BYTE_DISP)].rlx_forward = BYTE_F; + table[C (SCB_TST, BYTE_DISP)].rlx_backward = BYTE_B; + table[C (SCB_TST, BYTE_DISP)].rlx_length = 3; + table[C (SCB_TST, BYTE_DISP)].rlx_more = C (SCB_TST, WORD_DISP); + + table[C (SCB_TST, WORD_DISP)].rlx_forward = WORD_F; + table[C (SCB_TST, WORD_DISP)].rlx_backward = WORD_B; + table[C (SCB_TST, WORD_DISP)].rlx_length = 10; + table[C (SCB_TST, WORD_DISP)].rlx_more = 0; + +} + +static int rn; /* register number used by RN */ +static int rs; /* register number used by RS */ +static int rd; /* register number used by RD */ +static int crb; /* byte size cr */ +static int crw; /* word sized cr */ +static int cr; /* unknown size cr */ + +static expressionS displacement;/* displacement expression */ +static int displacement_size; /* and size if given */ + +static int immediate_inpage; +static expressionS immediate; /* immediate expression */ +static int immediate_size; /* and size if given */ + +static expressionS absolute; /* absolute expression */ +static int absolute_size; /* and size if given */ + +typedef struct +{ + int type; + int reg; + expressionS exp; + int page; +} + +h8500_operand_info; + +/* try and parse a reg name, returns number of chars consumed */ +static int +parse_reg (src, mode, reg) + char *src; + int *mode; + int *reg; +{ + char *end; + int len; + + /* Cribbed from get_symbol_end(). */ + if (!is_name_beginner (*src) || *src == '\001') + return 0; + end = src+1; + while (is_part_of_name (*end) || *end == '\001') + end++; + len = end - src; + + if (len == 2 && src[0] == 'r') + { + if (src[1] >= '0' && src[1] <= '7') + { + *mode = RN; + *reg = (src[1] - '0'); + return len; + } + } + if (len == 2 && src[0] == 's' && src[1] == 'p') + { + *mode = RN; + *reg = 7; + return len; + } + if (len == 3 && src[0] == 'c' && src[1] == 'c' && src[2] == 'r') + { + *mode = CRB; + *reg = 1; + return len; + } + if (len == 2 && src[0] == 's' && src[1] == 'r') + { + *mode = CRW; + *reg = 0; + return len; + } + if (len == 2 && src[0] == 'b' && src[1] == 'r') + { + *mode = CRB; + *reg = 3; + return len; + } + if (len == 2 && src[0] == 'e' && src[1] == 'p') + { + *mode = CRB; + *reg = 4; + return len; + } + if (len == 2 && src[0] == 'd' && src[1] == 'p') + { + *mode = CRB; + *reg = 5; + return len; + } + if (len == 2 && src[0] == 't' && src[1] == 'p') + { + *mode = CRB; + *reg = 7; + return len; + } + if (len == 2 && src[0] == 'f' && src[1] == 'p') + { + *mode = RN; + *reg = 6; + return len; + } + return 0; +} + +static +char * +parse_exp (s, op, page) + char *s; + expressionS *op; + int *page; +{ + char *save; + char *new; + + save = input_line_pointer; + + *page = 0; + if (s[0] == '%') + { + if (s[1] == 'p' && s[2] == 'a' && s[3] == 'g' && s[4] == 'e') + { + s += 5; + *page = 'p'; + } + if (s[1] == 'h' && s[2] == 'i' && s[3] == '1' && s[4] == '6') + { + s += 5; + *page = 'h'; + } + else if (s[1] == 'o' && s[2] == 'f' && s[3] == 'f') + { + s += 4; + *page = 'o'; + } + } + + 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; +} + +typedef enum + { + exp_signed, exp_unsigned, exp_sandu + } sign_type; + + +static char * +skip_colonthing (sign, ptr, exp, def, size8, size16, size24) + sign_type sign; + char *ptr; + h8500_operand_info *exp; + int def; + int size8; + int size16; + int size24; +{ + ptr = parse_exp (ptr, &exp->exp, &exp->page); + if (*ptr == ':') + { + ptr++; + if (*ptr == '8') + { + ptr++; + exp->type = size8; + } + else if (ptr[0] == '1' & ptr[1] == '6') + { + ptr += 2; + exp->type = size16; + } + else if (ptr[0] == '2' & ptr[1] == '4') + { + if (!size24) + { + as_bad (_(":24 not valid for this opcode")); + } + ptr += 2; + exp->type = size24; + } + else + { + as_bad (_("expect :8,:16 or :24")); + exp->type = size16; + } + } + else + { + if (exp->page == 'p') + { + exp->type = IMM8; + } + else if (exp->page == 'h') + { + exp->type = IMM16; + } + else + { + /* Let's work out the size from the context */ + int n = exp->exp.X_add_number; + if (size8 + && exp->exp.X_op == O_constant + && ((sign == exp_signed && (n >= -128 && n <= 127)) + || (sign == exp_unsigned && (n >= 0 && (n <= 255))) + || (sign == exp_sandu && (n >= -128 && (n <= 255))))) + { + exp->type = size8; + } + else + { + exp->type = def; + } + } + } + return ptr; +} + +static int +parse_reglist (src, op) + char *src; + h8500_operand_info *op; +{ + int mode; + int rn; + int mask = 0; + int rm; + int idx = 1; /* skip ( */ + + while (src[idx] && src[idx] != ')') + { + int done = parse_reg (src + idx, &mode, &rn); + + if (done) + { + idx += done; + mask |= 1 << rn; + } + else + { + as_bad (_("syntax error in reg list")); + return 0; + } + if (src[idx] == '-') + { + idx++; + done = parse_reg (src + idx, &mode, &rm); + if (done) + { + idx += done; + while (rn <= rm) + { + mask |= 1 << rn; + rn++; + } + } + else + { + as_bad (_("missing final register in range")); + } + } + if (src[idx] == ',') + idx++; + } + idx++; + op->exp.X_add_symbol = 0; + op->exp.X_op_symbol = 0; + op->exp.X_add_number = mask; + op->exp.X_op = O_constant; + op->exp.X_unsigned = 1; + op->type = IMM8; + return idx; + +} + +/* The many forms of operand: + + Rn Register direct + @Rn Register indirect + @(disp[:size], Rn) Register indirect with displacement + @Rn+ + @-Rn + @aa[:size] absolute + #xx[:size] immediate data + + */ + +static void +get_operand (ptr, op, ispage) + char **ptr; + h8500_operand_info *op; + char ispage; +{ + char *src = *ptr; + int mode; + unsigned int num; + unsigned int len; + op->page = 0; + if (src[0] == '(' && src[1] == 'r') + { + /* This is a register list */ + *ptr = src + parse_reglist (src, op); + return; + } + + len = parse_reg (src, &op->type, &op->reg); + + if (len) + { + *ptr = src + len; + return; + } + + if (*src == '@') + { + src++; + if (*src == '-') + { + src++; + len = parse_reg (src, &mode, &num); + if (len == 0) + { + /* Oops, not a reg after all, must be ordinary exp */ + src--; + /* must be a symbol */ + *ptr = skip_colonthing (exp_unsigned, src, + op, ABS16, ABS8, ABS16, ABS24); + return; + } + + op->type = RNDEC; + op->reg = num; + *ptr = src + len; + return; + } + if (*src == '(') + { + /* Disp */ + src++; + + src = skip_colonthing (exp_signed, src, + op, RNIND_D16, RNIND_D8, RNIND_D16, 0); + + if (*src != ',') + { + as_bad (_("expected @(exp, Rn)")); + return; + } + src++; + len = parse_reg (src, &mode, &op->reg); + if (len == 0 || mode != RN) + { + as_bad (_("expected @(exp, Rn)")); + return; + } + src += len; + if (*src != ')') + { + as_bad (_("expected @(exp, Rn)")); + return; + } + *ptr = src + 1; + return; + } + len = parse_reg (src, &mode, &num); + + if (len) + { + src += len; + if (*src == '+') + { + src++; + if (mode != RN) + { + as_bad (_("@Rn+ needs word register")); + return; + } + op->type = RNINC; + op->reg = num; + *ptr = src; + return; + } + if (mode != RN) + { + as_bad (_("@Rn needs word register")); + return; + } + op->type = RNIND; + op->reg = num; + *ptr = src; + return; + } + else + { + /* must be a symbol */ + *ptr = + skip_colonthing (exp_unsigned, src, op, + ispage ? ABS24 : ABS16, ABS8, ABS16, ABS24); + return; + } + } + + if (*src == '#') + { + src++; + *ptr = skip_colonthing (exp_sandu, src, op, IMM16, IMM8, IMM16, ABS24); + return; + } + else + { + *ptr = skip_colonthing (exp_signed, src, op, + ispage ? ABS24 : PCREL8, PCREL8, PCREL16, ABS24); + } +} + +static +char * +get_operands (info, args, operand) + h8500_opcode_info *info; + char *args; + h8500_operand_info *operand; + +{ + char *ptr = args; + + switch (info->nargs) + { + case 0: + operand[0].type = 0; + operand[1].type = 0; + break; + + case 1: + ptr++; + get_operand (&ptr, operand + 0, info->name[0] == 'p'); + operand[1].type = 0; + break; + + case 2: + ptr++; + get_operand (&ptr, operand + 0, 0); + if (*ptr == ',') + ptr++; + get_operand (&ptr, operand + 1, 0); + 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 + */ + +int pcrel8; /* Set when we've seen a pcrel operand */ + +static +h8500_opcode_info * +get_specific (opcode, operands) + h8500_opcode_info *opcode; + h8500_operand_info *operands; +{ + h8500_opcode_info *this_try = opcode; + int found = 0; + unsigned int noperands = opcode->nargs; + + unsigned int this_index = opcode->idx; + + while (this_index == opcode->idx && !found) + { + unsigned int i; + + this_try = opcode++; + + /* look at both operands needed by the opcodes and provided by + the user*/ + for (i = 0; i < noperands; i++) + { + h8500_operand_info *user = operands + i; + + switch (this_try->arg_type[i]) + { + case FPIND_D8: + /* Opcode needs (disp:8,fp) */ + if (user->type == RNIND_D8 && user->reg == 6) + { + displacement = user->exp; + continue; + } + break; + case RDIND_D16: + if (user->type == RNIND_D16) + { + displacement = user->exp; + rd = user->reg; + continue; + } + break; + case RDIND_D8: + if (user->type == RNIND_D8) + { + displacement = user->exp; + rd = user->reg; + continue; + } + break; + case RNIND_D16: + case RNIND_D8: + if (user->type == this_try->arg_type[i]) + { + displacement = user->exp; + rn = user->reg; + continue; + } + break; + + case SPDEC: + if (user->type == RNDEC && user->reg == 7) + { + continue; + } + break; + case SPINC: + if (user->type == RNINC && user->reg == 7) + { + continue; + } + break; + case ABS16: + if (user->type == ABS16) + { + absolute = user->exp; + continue; + } + break; + case ABS8: + if (user->type == ABS8) + { + absolute = user->exp; + continue; + } + break; + case ABS24: + if (user->type == ABS24) + { + absolute = user->exp; + continue; + } + break; + + case CRB: + if ((user->type == CRB || user->type == CR) && user->reg != 0) + { + crb = user->reg; + continue; + } + break; + case CRW: + if ((user->type == CRW || user->type == CR) && user->reg == 0) + { + crw = user->reg; + continue; + } + break; + case DISP16: + if (user->type == DISP16) + { + displacement = user->exp; + continue; + } + break; + case DISP8: + if (user->type == DISP8) + { + displacement = user->exp; + continue; + } + break; + case FP: + if (user->type == RN && user->reg == 6) + { + continue; + } + break; + case PCREL16: + if (user->type == PCREL16) + { + displacement = user->exp; + continue; + } + break; + case PCREL8: + if (user->type == PCREL8) + { + displacement = user->exp; + pcrel8 = 1; + continue; + } + break; + + case IMM16: + if (user->type == IMM16 + || user->type == IMM8) + { + immediate_inpage = user->page; + immediate = user->exp; + continue; + } + break; + case RLIST: + case IMM8: + if (user->type == IMM8) + { + immediate_inpage = user->page; + immediate = user->exp; + continue; + } + break; + case IMM4: + if (user->type == IMM8) + { + immediate_inpage = user->page; + immediate = user->exp; + continue; + } + break; + case QIM: + if (user->type == IMM8 + && user->exp.X_op == O_constant + && + (user->exp.X_add_number == -2 + || user->exp.X_add_number == -1 + || user->exp.X_add_number == 1 + || user->exp.X_add_number == 2)) + { + immediate_inpage = user->page; + immediate = user->exp; + continue; + } + break; + case RD: + if (user->type == RN) + { + rd = user->reg; + continue; + } + break; + case RS: + if (user->type == RN) + { + rs = user->reg; + continue; + } + break; + case RDIND: + if (user->type == RNIND) + { + rd = user->reg; + continue; + + } + break; + case RNINC: + case RNIND: + case RNDEC: + case RN: + + if (user->type == this_try->arg_type[i]) + { + rn = user->reg; + continue; + } + break; + case SP: + if (user->type == RN && user->reg == 7) + { + continue; + } + break; + default: + printf (_("unhandled %d\n"), this_try->arg_type[i]); + break; + } + + /* If we get here this didn't work out */ + goto fail; + } + found = 1; + fail:; + + } + + if (found) + return this_try; + else + return 0; +} + +int +check (operand, low, high) + expressionS *operand; + int low; + int high; +{ + if (operand->X_op != O_constant + || operand->X_add_number < low + || operand->X_add_number > high) + { + as_bad (_("operand must be absolute in range %d..%d"), low, high); + } + return operand->X_add_number; +} + +static +void +insert (output, index, exp, reloc, pcrel) + char *output; + int index; + expressionS *exp; + int reloc; + int pcrel; +{ + fix_new_exp (frag_now, + output - frag_now->fr_literal + index, + 4, /* always say size is 4, but we know better */ + exp, + pcrel, + reloc); +} + +void +build_relaxable_instruction (opcode, operand) + h8500_opcode_info *opcode; + h8500_operand_info *operand; +{ + /* All relaxable instructions start life as two bytes but can become + three bytes long if a lonely branch and up to 9 bytes if long scb + */ + char *p; + int len; + int type; + + if (opcode->bytes[0].contents == 0x01) + { + type = SCB_F; + } + else if (opcode->bytes[0].contents == 0x06 + || opcode->bytes[0].contents == 0x07) + { + type = SCB_TST; + } + else + { + type = BRANCH; + } + + p = frag_var (rs_machine_dependent, + md_relax_table[C (type, WORD_DISP)].rlx_length, + len = md_relax_table[C (type, BYTE_DISP)].rlx_length, + C (type, UNDEF_BYTE_DISP), + displacement.X_add_symbol, + displacement.X_add_number, + 0); + + p[0] = opcode->bytes[0].contents; + if (type != BRANCH) + { + p[1] = opcode->bytes[1].contents | rs; + } +} + +/* Now we know what sort of opcodes it is, lets build the bytes - + */ +static void +build_bytes (opcode, operand) + h8500_opcode_info *opcode; + h8500_operand_info *operand; + +{ + int index; + + if (pcrel8) + { + pcrel8 = 0; + build_relaxable_instruction (opcode, operand); + } + else + { + char *output = frag_more (opcode->length); + + memset (output, 0, opcode->length); + for (index = 0; index < opcode->length; index++) + { + output[index] = opcode->bytes[index].contents; + + switch (opcode->bytes[index].insert) + { + default: + printf (_("failed for %d\n"), opcode->bytes[index].insert); + break; + case 0: + break; + case RN: + output[index] |= rn; + break; + case RD: + case RDIND: + + output[index] |= rd; + break; + case RS: + output[index] |= rs; + break; + case DISP16: + insert (output, index, &displacement, R_H8500_IMM16, 0); + index++; + break; + case DISP8: + case FPIND_D8: + insert (output, index, &displacement, R_H8500_IMM8, 0); + break; + + case IMM16: + { + int p; + switch (immediate_inpage) { + case 'p': + p = R_H8500_HIGH16; + break; + case 'h': + p = R_H8500_HIGH16; + break; + default: + p = R_H8500_IMM16; + break; + } + + insert (output, index, &immediate,p, 0); + } + + index++; + break; + case RLIST: + case IMM8: + if (immediate_inpage) + { + insert (output, index, &immediate, R_H8500_HIGH8, 0); + } + else + { + insert (output, index, &immediate, R_H8500_IMM8, 0); + } + break; + case PCREL16: + insert (output, index, &displacement, R_H8500_PCREL16, 1); + index++; + break; + case PCREL8: + insert (output, index, &displacement, R_H8500_PCREL8, 1); + break; + case IMM4: + output[index] |= check (&immediate, 0, 15); + break; + case CR: + + output[index] |= cr; + if (cr == 0) + { + output[0] |= 0x8; + } + else + { + output[0] &= ~0x8; + } + + break; + + case CRB: + output[index] |= crb; + output[0] &= ~0x8; + break; + case CRW: + output[index] |= crw; + output[0] |= 0x8; + break; + case ABS24: + insert (output, index, &absolute, R_H8500_IMM24, 0); + index += 2; + break; + case ABS16: + insert (output, index, &absolute, R_H8500_IMM16, 0); + index++; + break; + case ABS8: + insert (output, index, &absolute, R_H8500_IMM8, 0); + break; + case QIM: + switch (immediate.X_add_number) + { + case -2: + output[index] |= 0x5; + break; + case -1: + output[index] |= 0x4; + break; + case 1: + output[index] |= 0; + break; + case 2: + output[index] |= 1; + break; + } + break; + } + } + } +} + +/* This is the guts of the machine-dependent assembler. STR points to a + machine dependent instruction. This funciton is supposed to emit + the frags/bytes it assembles to. + */ + +void +DEFUN (md_assemble, (str), + char *str) +{ + char *op_start; + char *op_end; + h8500_operand_info operand[2]; + h8500_opcode_info *opcode; + h8500_opcode_info *prev_opcode; + char name[11]; + + int nlen = 0; + + /* Drop leading whitespace */ + while (*str == ' ') + str++; + + /* find the op code end */ + for (op_start = op_end = str; + *op_end && + !is_end_of_line[*op_end] && *op_end != ' '; + op_end++) + { + if ( /**op_end != '.' + && *op_end != ':' + && */ nlen < 10) + { + name[nlen++] = *op_end; + } + } + name[nlen] = 0; + + if (op_end == op_start) + { + as_bad (_("can't find opcode ")); + } + + opcode = (h8500_opcode_info *) hash_find (opcode_hash_control, name); + + if (opcode == NULL) + { + as_bad (_("unknown opcode")); + return; + } + + 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 (_("invalid operands for opcode")); + return; + } + + build_bytes (opcode, operand); + +} + +void +DEFUN (tc_crawl_symbol_chain, (headers), + object_headers * headers) +{ + printf (_("call to tc_crawl_symbol_chain \n")); +} + +symbolS * +DEFUN (md_undefined_symbol, (name), + char *name) +{ + return 0; +} + +void +DEFUN (tc_headers_hook, (headers), + object_headers * headers) +{ + 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 = ""; +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; +{ + return 0; +} + +void +md_show_usage (stream) + FILE *stream; +{ +} + +void +tc_aout_fix_to_chars () +{ + printf (_("call to tc_aout_fix_to_chars \n")); + abort (); +} + +static +void +wordify_scb (buffer, disp_size, inst_size) + char *buffer; + int *disp_size; + int *inst_size; +{ + int rn = buffer[1] & 0x7; + + switch (buffer[0]) + { + case 0x0e: /* BSR */ + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + case 0x28: + case 0x29: + case 0x2a: + case 0x2b: + case 0x2c: + case 0x2d: + case 0x2e: + case 0x2f: + buffer[0] |= 0x10; + buffer[1] = 0; + buffer[2] = 0; + *disp_size = 2; + *inst_size = 1; + return; + default: + abort (); + + case 0x01: + *inst_size = 6; + *disp_size = 2; + break; + case 0x06: + *inst_size = 8; + *disp_size = 2; + + *buffer++ = 0x26; /* bne + 8 */ + *buffer++ = 0x08; + break; + case 0x07: + *inst_size = 8; + *disp_size = 2; + *buffer++ = 0x27; /* bne + 8 */ + *buffer++ = 0x08; + break; + + } + *buffer++ = 0xa8 | rn; /* addq -1,rn */ + *buffer++ = 0x0c; + *buffer++ = 0x04; /* cmp #0xff:8, rn */ + *buffer++ = 0xff; + *buffer++ = 0x70 | rn; + *buffer++ = 0x36; /* bne ... */ + *buffer++ = 0; + *buffer++ = 0; +} + +/* +called after relaxing, change the frags so they know how big they are +*/ +void +md_convert_frag (headers, seg, fragP) + object_headers *headers; + segT seg; + fragS *fragP; +{ + int disp_size = 0; + int inst_size = 0; + char *buffer = fragP->fr_fix + fragP->fr_literal; + + switch (fragP->fr_subtype) + { + case C (BRANCH, BYTE_DISP): + disp_size = 1; + inst_size = 1; + break; + + case C (SCB_F, BYTE_DISP): + case C (SCB_TST, BYTE_DISP): + disp_size = 1; + inst_size = 2; + break; + + /* Branches to a known 16 bit displacement */ + + /* Turn on the 16bit bit */ + case C (BRANCH, WORD_DISP): + case C (SCB_F, WORD_DISP): + case C (SCB_TST, WORD_DISP): + wordify_scb (buffer, &disp_size, &inst_size); + break; + + case C (BRANCH, UNDEF_WORD_DISP): + case C (SCB_F, UNDEF_WORD_DISP): + case C (SCB_TST, UNDEF_WORD_DISP): + /* This tried to be relaxed, but didn't manage it, it now needs a + fix */ + wordify_scb (buffer, &disp_size, &inst_size); + + /* Make a reloc */ + fix_new (fragP, + fragP->fr_fix + inst_size, + 4, + fragP->fr_symbol, + fragP->fr_offset, + 0, + R_H8500_PCREL16); + + fragP->fr_fix += disp_size + inst_size; + fragP->fr_var = 0; + return; + break; + default: + abort (); + } + if (inst_size) + { + /* Get the address of the end of the instruction */ + int next_inst = fragP->fr_fix + fragP->fr_address + disp_size + inst_size; + int targ_addr = (S_GET_VALUE (fragP->fr_symbol) + + fragP->fr_offset); + int disp = targ_addr - next_inst; + + md_number_to_chars (buffer + inst_size, disp, disp_size); + fragP->fr_fix += disp_size + inst_size; + fragP->fr_var = 0; + } +} + +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_fix (fixP, val) + fixS *fixP; + long val; +{ + char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; + + if (fixP->fx_r_type == 0) + { + fixP->fx_r_type = fixP->fx_size == 4 ? R_H8500_IMM32 : R_H8500_IMM16; + } + + switch (fixP->fx_r_type) + { + + case R_H8500_IMM8: + case R_H8500_PCREL8: + *buf++ = val; + break; + case R_H8500_IMM16: + case R_H8500_LOW16: + case R_H8500_PCREL16: + *buf++ = (val >> 8); + *buf++ = val; + break; + case R_H8500_HIGH8: + *buf++ = val >> 16; + break; + case R_H8500_HIGH16: + *buf++ = val >> 24; + *buf++ = val >> 16; + break; + case R_H8500_IMM24: + *buf++ = (val >> 16); + *buf++ = (val >> 8); + *buf++ = val; + break; + case R_H8500_IMM32: + *buf++ = (val >> 24); + *buf++ = (val >> 16); + *buf++ = (val >> 8); + *buf++ = val; + break; + default: + abort (); + + } +} + +/* +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 = GET_WHAT (fragP->fr_subtype); + + switch (fragP->fr_subtype) + { + default: + abort (); + case C (BRANCH, UNDEF_BYTE_DISP): + case C (SCB_F, UNDEF_BYTE_DISP): + case C (SCB_TST, UNDEF_BYTE_DISP): + /* used to be a branch to somewhere which was unknown */ + if (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, BYTE_DISP); + fragP->fr_var = md_relax_table[C (what, BYTE_DISP)].rlx_length; + } + else + { + /* Its got a segment, but its not ours, so it will always be long */ + fragP->fr_subtype = C (what, UNDEF_WORD_DISP); + fragP->fr_var = md_relax_table[C (what, WORD_DISP)].rlx_length; + return md_relax_table[C (what, WORD_DISP)].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; +{ + number_to_chars_bigendian (ptr, use, nbytes); +} + +long +md_pcrel_from (fixP) + fixS *fixP; +{ + return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; +} + +/*ARGSUSED*/ +void +tc_coff_symbol_emit_hook (ignore) + symbolS *ignore; +{ +} + +short +tc_coff_fix2rtype (fix_ptr) + fixS *fix_ptr; +{ + if (fix_ptr->fx_r_type == RELOC_32) + { + /* cons likes to create reloc32's whatever the size of the reloc.. + */ + switch (fix_ptr->fx_size) + { + case 2: + return R_H8500_IMM16; + break; + case 1: + return R_H8500_IMM8; + break; + default: + abort (); + } + } + return fix_ptr->fx_r_type; +} + +void +tc_reloc_mangle (fix_ptr, intr, base) + fixS *fix_ptr; + struct internal_reloc *intr; + bfd_vma base; + +{ + symbolS *symbol_ptr; + + 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 == RELOC_32) + { + /* 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; + 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; + + /* Turn the segment of the symbol into an offset. */ + if (symbol_ptr) + { + symbolS *dot; + + dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot; + if (dot) + { + /* intr->r_offset -= + segment_info[S_GET_SEGMENT(symbol_ptr)].scnhdr.s_paddr;*/ + intr->r_offset += S_GET_VALUE (symbol_ptr); + intr->r_symndx = dot->sy_number; + } + else + { + intr->r_symndx = symbol_ptr->sy_number; + } + + } + else + { + intr->r_symndx = -1; + } + +} + + + +int +start_label (ptr) + char *ptr; +{ + /* Check for :s.w */ + if (isalpha (ptr[1]) && ptr[2] == '.') + return 0; + /* Check for :s */ + if (isalpha (ptr[1]) && !isalpha (ptr[2])) + return 0; + return 1; +} + + +int +tc_coff_sizemachdep (frag) + fragS *frag; +{ + return md_relax_table[frag->fr_subtype].rlx_length; +} + +/* end of tc-h8500.c */ + diff --git a/gas/config/tc-h8500.h b/gas/config/tc-h8500.h new file mode 100644 index 0000000000..2a53ec35ce --- /dev/null +++ b/gas/config/tc-h8500.h @@ -0,0 +1,57 @@ +/* This file is tc-h8500.h + Copyright (C) 1993, 95, 97, 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. */ + + +#define TC_H8500 + +#define TARGET_BYTES_BIG_ENDIAN 1 + +#if ANSI_PROTOTYPES +struct internal_reloc; +#endif + +#define WORKING_DOT_WORD + +/* This macro translates between an internal fix and an coff reloc type */ +#define TC_COFF_FIX2RTYPE(fixP) tc_coff_fix2rtype(fixP) + +#define BFD_ARCH bfd_arch_h8500 +#define COFF_MAGIC 0x8500 +#define TC_COUNT_RELOC(x) ((x)->fx_addsy||(x)->fx_subsy) +#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 "Hitachi H8/500 GAS " +#define NEED_FX_R_TYPE 1 +#define RELOC_32 1234 + +#define TC_START_LABEL(ch, ptr) (ch == ':' && start_label(ptr)) +#define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep(frag) + +#define md_operand(x) + +extern struct relax_type md_relax_table[]; +#define TC_GENERIC_RELAX_TABLE md_relax_table + +/* end of tc-h8500.h */ diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c new file mode 100644 index 0000000000..8785de8769 --- /dev/null +++ b/gas/config/tc-hppa.c @@ -0,0 +1,6716 @@ +/* tc-hppa.c -- Assemble for the PA + Copyright (C) 1989, 93, 94, 95, 96, 97, 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. */ + + +/* HP PA-RISC support was contributed by the Center for Software Science + at the University of Utah. */ + +#include +#include + +#include "as.h" +#include "subsegs.h" + +#include "bfd/libhppa.h" +#include "bfd/libbfd.h" + +/* Be careful, this file includes data *declarations*. */ +#include "opcode/hppa.h" + +/* A "convient" place to put object file dependencies which do + not need to be seen outside of tc-hppa.c. */ +#ifdef OBJ_ELF +/* Names of various debugging spaces/subspaces. */ +#define GDB_DEBUG_SPACE_NAME ".stab" +#define GDB_STRINGS_SUBSPACE_NAME ".stabstr" +#define GDB_SYMBOLS_SUBSPACE_NAME ".stab" +#define UNWIND_SECTION_NAME ".PARISC.unwind" +/* Nonzero if CODE is a fixup code needing further processing. */ + +/* Object file formats specify relocation types. */ +typedef elf32_hppa_reloc_type reloc_type; + +/* Object file formats specify BFD symbol types. */ +typedef elf_symbol_type obj_symbol_type; + +/* How to generate a relocation. */ +#define hppa_gen_reloc_type hppa_elf_gen_reloc_type + +/* ELF objects can have versions, but apparently do not have anywhere + to store a copyright string. */ +#define obj_version obj_elf_version +#define obj_copyright obj_elf_version + +/* Use space aliases. */ +#define USE_ALIASES 1 +#endif + +#ifdef OBJ_SOM +/* Names of various debugging spaces/subspaces. */ +#define GDB_DEBUG_SPACE_NAME "$GDB_DEBUG$" +#define GDB_STRINGS_SUBSPACE_NAME "$GDB_STRINGS$" +#define GDB_SYMBOLS_SUBSPACE_NAME "$GDB_SYMBOLS$" +#define UNWIND_SECTION_NAME "$UNWIND$" + +/* Object file formats specify relocation types. */ +typedef int reloc_type; + +/* SOM objects can have both a version string and a copyright string. */ +#define obj_version obj_som_version +#define obj_copyright obj_som_copyright + +/* Do not use space aliases. */ +#define USE_ALIASES 0 + +/* How to generate a relocation. */ +#define hppa_gen_reloc_type hppa_som_gen_reloc_type + +/* Object file formats specify BFD symbol types. */ +typedef som_symbol_type obj_symbol_type; + +/* This apparently isn't in older versions of hpux reloc.h. */ +#ifndef R_DLT_REL +#define R_DLT_REL 0x78 +#endif +#endif + +#ifndef R_N0SEL +#define R_N0SEL 0xd8 +#endif + +#ifndef R_N1SEL +#define R_N1SEL 0xd9 +#endif + +/* Various structures and types used internally in tc-hppa.c. */ + +/* Unwind table and descriptor. FIXME: Sync this with GDB version. */ + +struct unwind_desc + { + unsigned int cannot_unwind:1; + unsigned int millicode:1; + unsigned int millicode_save_rest:1; + unsigned int region_desc:2; + unsigned int save_sr:2; + unsigned int entry_fr:4; + unsigned int entry_gr:5; + unsigned int args_stored:1; + unsigned int call_fr:5; + unsigned int call_gr:5; + unsigned int save_sp:1; + unsigned int save_rp:1; + unsigned int save_rp_in_frame:1; + unsigned int extn_ptr_defined:1; + unsigned int cleanup_defined:1; + + unsigned int hpe_interrupt_marker:1; + unsigned int hpux_interrupt_marker:1; + unsigned int reserved:3; + unsigned int frame_size:27; + }; + +struct unwind_table + { + /* Starting and ending offsets of the region described by + descriptor. */ + unsigned int start_offset; + unsigned int end_offset; + struct unwind_desc descriptor; + }; + +/* This structure is used by the .callinfo, .enter, .leave pseudo-ops to + control the entry and exit code they generate. It is also used in + creation of the correct stack unwind descriptors. + + NOTE: GAS does not support .enter and .leave for the generation of + prologues and epilogues. FIXME. + + The fields in structure roughly correspond to the arguments available on the + .callinfo pseudo-op. */ + +struct call_info + { + /* The unwind descriptor being built. */ + struct unwind_table ci_unwind; + + /* Name of this function. */ + symbolS *start_symbol; + + /* (temporary) symbol used to mark the end of this function. */ + symbolS *end_symbol; + + /* Next entry in the chain. */ + struct call_info *ci_next; + }; + +/* Operand formats for FP instructions. Note not all FP instructions + allow all four formats to be used (for example fmpysub only allows + SGL and DBL). */ +typedef enum + { + SGL, DBL, ILLEGAL_FMT, QUAD, W, UW, DW, UDW, QW, UQW + } +fp_operand_format; + +/* This fully describes the symbol types which may be attached to + an EXPORT or IMPORT directive. Only SOM uses this formation + (ELF has no need for it). */ +typedef enum + { + SYMBOL_TYPE_UNKNOWN, + SYMBOL_TYPE_ABSOLUTE, + SYMBOL_TYPE_CODE, + SYMBOL_TYPE_DATA, + SYMBOL_TYPE_ENTRY, + SYMBOL_TYPE_MILLICODE, + SYMBOL_TYPE_PLABEL, + SYMBOL_TYPE_PRI_PROG, + SYMBOL_TYPE_SEC_PROG, + } +pa_symbol_type; + +/* This structure contains information needed to assemble + individual instructions. */ +struct pa_it + { + /* Holds the opcode after parsing by pa_ip. */ + unsigned long opcode; + + /* Holds an expression associated with the current instruction. */ + expressionS exp; + + /* Does this instruction use PC-relative addressing. */ + int pcrel; + + /* Floating point formats for operand1 and operand2. */ + fp_operand_format fpof1; + fp_operand_format fpof2; + + + /* Holds the field selector for this instruction + (for example L%, LR%, etc). */ + long field_selector; + + /* Holds any argument relocation bits associated with this + instruction. (instruction should be some sort of call). */ + long arg_reloc; + + /* The format specification for this instruction. */ + int format; + + /* The relocation (if any) associated with this instruction. */ + reloc_type reloc; + }; + +/* PA-89 floating point registers are arranged like this: + + + +--------------+--------------+ + | 0 or 16L | 16 or 16R | + +--------------+--------------+ + | 1 or 17L | 17 or 17R | + +--------------+--------------+ + | | | + + . . . + . . . + . . . + + | | | + +--------------+--------------+ + | 14 or 30L | 30 or 30R | + +--------------+--------------+ + | 15 or 31L | 31 or 31R | + +--------------+--------------+ + + + The following is a version of pa_parse_number that + handles the L/R notation and returns the correct + value to put into the instruction register field. + The correct value to put into the instruction is + encoded in the structure 'pa_11_fp_reg_struct'. */ + +struct pa_11_fp_reg_struct + { + /* The register number. */ + char number_part; + + /* L/R selector. */ + char l_r_select; + }; + +/* Additional information needed to build argument relocation stubs. */ +struct call_desc + { + /* The argument relocation specification. */ + unsigned int arg_reloc; + + /* Number of arguments. */ + unsigned int arg_count; + }; + +/* This structure defines an entry in the subspace dictionary + chain. */ + +struct subspace_dictionary_chain + { + /* Nonzero if this space has been defined by the user code. */ + unsigned int ssd_defined; + + /* Name of this subspace. */ + char *ssd_name; + + /* GAS segment and subsegment associated with this subspace. */ + asection *ssd_seg; + int ssd_subseg; + + /* Next space in the subspace dictionary chain. */ + struct subspace_dictionary_chain *ssd_next; + }; + +typedef struct subspace_dictionary_chain ssd_chain_struct; + +/* This structure defines an entry in the subspace dictionary + chain. */ + +struct space_dictionary_chain + { + /* Nonzero if this space has been defined by the user code or + as a default space. */ + unsigned int sd_defined; + + /* Nonzero if this spaces has been defined by the user code. */ + unsigned int sd_user_defined; + + /* The space number (or index). */ + unsigned int sd_spnum; + + /* The name of this subspace. */ + char *sd_name; + + /* GAS segment to which this subspace corresponds. */ + asection *sd_seg; + + /* Current subsegment number being used. */ + int sd_last_subseg; + + /* The chain of subspaces contained within this space. */ + ssd_chain_struct *sd_subspaces; + + /* The next entry in the space dictionary chain. */ + struct space_dictionary_chain *sd_next; + }; + +typedef struct space_dictionary_chain sd_chain_struct; + +/* Structure for previous label tracking. Needed so that alignments, + callinfo declarations, etc can be easily attached to a particular + label. */ +typedef struct label_symbol_struct + { + struct symbol *lss_label; + sd_chain_struct *lss_space; + struct label_symbol_struct *lss_next; + } +label_symbol_struct; + +/* This structure defines attributes of the default subspace + dictionary entries. */ + +struct default_subspace_dict + { + /* Name of the subspace. */ + char *name; + + /* FIXME. Is this still needed? */ + char defined; + + /* Nonzero if this subspace is loadable. */ + char loadable; + + /* Nonzero if this subspace contains only code. */ + char code_only; + + /* Nonzero if this is a common subspace. */ + char common; + + /* Nonzero if this is a common subspace which allows symbols + to be multiply defined. */ + char dup_common; + + /* Nonzero if this subspace should be zero filled. */ + char zero; + + /* Sort key for this subspace. */ + unsigned char sort; + + /* Access control bits for this subspace. Can represent RWX access + as well as privilege level changes for gateways. */ + int access; + + /* Index of containing space. */ + int space_index; + + /* Alignment (in bytes) of this subspace. */ + int alignment; + + /* Quadrant within space where this subspace should be loaded. */ + int quadrant; + + /* An index into the default spaces array. */ + int def_space_index; + + /* An alias for this section (or NULL if no alias exists). */ + char *alias; + + /* Subsegment associated with this subspace. */ + subsegT subsegment; + }; + +/* This structure defines attributes of the default space + dictionary entries. */ + +struct default_space_dict + { + /* Name of the space. */ + char *name; + + /* Space number. It is possible to identify spaces within + assembly code numerically! */ + int spnum; + + /* Nonzero if this space is loadable. */ + char loadable; + + /* Nonzero if this space is "defined". FIXME is still needed */ + char defined; + + /* Nonzero if this space can not be shared. */ + char private; + + /* Sort key for this space. */ + unsigned char sort; + + /* Segment associated with this space. */ + asection *segment; + + /* An alias for this section (or NULL if no alias exists). */ + char *alias; + }; + +/* Extra information needed to perform fixups (relocations) on the PA. */ +struct hppa_fix_struct + { + /* The field selector. */ + enum hppa_reloc_field_selector_type_alt fx_r_field; + + /* Type of fixup. */ + int fx_r_type; + + /* Format of fixup. */ + int fx_r_format; + + /* Argument relocation bits. */ + long fx_arg_reloc; + + /* The segment this fixup appears in. */ + segT segment; + }; + +/* Structure to hold information about predefined registers. */ + +struct pd_reg + { + char *name; + int value; + }; + +/* This structure defines the mapping from a FP condition string + to a condition number which can be recorded in an instruction. */ +struct fp_cond_map + { + char *string; + int cond; + }; + +/* This structure defines a mapping from a field selector + string to a field selector type. */ +struct selector_entry + { + char *prefix; + int field_selector; + }; + +/* Prototypes for functions local to tc-hppa.c. */ + +static void pa_check_current_space_and_subspace PARAMS ((void)); +static fp_operand_format pa_parse_fp_format PARAMS ((char **s)); +static void pa_cons PARAMS ((int)); +static void pa_data PARAMS ((int)); +static void pa_float_cons PARAMS ((int)); +static void pa_fill PARAMS ((int)); +static void pa_lcomm PARAMS ((int)); +static void pa_lsym PARAMS ((int)); +static void pa_stringer PARAMS ((int)); +static void pa_text PARAMS ((int)); +static void pa_version PARAMS ((int)); +static int pa_parse_fp_cmp_cond PARAMS ((char **)); +static int get_expression PARAMS ((char *)); +static int pa_get_absolute_expression PARAMS ((struct pa_it *, char **)); +static int evaluate_absolute PARAMS ((struct pa_it *)); +static unsigned int pa_build_arg_reloc PARAMS ((char *)); +static unsigned int pa_align_arg_reloc PARAMS ((unsigned int, unsigned int)); +static int pa_parse_nullif PARAMS ((char **)); +static int pa_parse_nonneg_cmpsub_cmpltr PARAMS ((char **, int)); +static int pa_parse_neg_cmpsub_cmpltr PARAMS ((char **, int)); +static int pa_parse_neg_add_cmpltr PARAMS ((char **, int)); +static int pa_parse_nonneg_add_cmpltr PARAMS ((char **, int)); +static void pa_align PARAMS ((int)); +static void pa_block PARAMS ((int)); +static void pa_brtab PARAMS ((int)); +static void pa_try PARAMS ((int)); +static void pa_call PARAMS ((int)); +static void pa_call_args PARAMS ((struct call_desc *)); +static void pa_callinfo PARAMS ((int)); +static void pa_code PARAMS ((int)); +static void pa_comm PARAMS ((int)); +#ifdef OBJ_SOM +static void pa_compiler PARAMS ((int)); +#endif +static void pa_copyright PARAMS ((int)); +static void pa_end PARAMS ((int)); +static void pa_enter PARAMS ((int)); +static void pa_entry PARAMS ((int)); +static void pa_equ PARAMS ((int)); +static void pa_exit PARAMS ((int)); +static void pa_export PARAMS ((int)); +static void pa_type_args PARAMS ((symbolS *, int)); +static void pa_import PARAMS ((int)); +static void pa_label PARAMS ((int)); +static void pa_leave PARAMS ((int)); +static void pa_level PARAMS ((int)); +static void pa_origin PARAMS ((int)); +static void pa_proc PARAMS ((int)); +static void pa_procend PARAMS ((int)); +static void pa_space PARAMS ((int)); +static void pa_spnum PARAMS ((int)); +static void pa_subspace PARAMS ((int)); +static void pa_param PARAMS ((int)); +static void pa_undefine_label PARAMS ((void)); +static int need_pa11_opcode PARAMS ((struct pa_it *, + struct pa_11_fp_reg_struct *)); +static int pa_parse_number PARAMS ((char **, struct pa_11_fp_reg_struct *)); +static label_symbol_struct *pa_get_label PARAMS ((void)); +static sd_chain_struct *create_new_space PARAMS ((char *, int, int, + int, int, int, + asection *, int)); +static ssd_chain_struct *create_new_subspace PARAMS ((sd_chain_struct *, + char *, int, int, + int, int, int, + int, int, int, int, + int, asection *)); +static ssd_chain_struct *update_subspace PARAMS ((sd_chain_struct *, + char *, int, int, int, + int, int, int, int, + int, int, int, + asection *)); +static sd_chain_struct *is_defined_space PARAMS ((char *)); +static ssd_chain_struct *is_defined_subspace PARAMS ((char *)); +static sd_chain_struct *pa_segment_to_space PARAMS ((asection *)); +static ssd_chain_struct *pa_subsegment_to_subspace PARAMS ((asection *, + subsegT)); +static sd_chain_struct *pa_find_space_by_number PARAMS ((int)); +static unsigned int pa_subspace_start PARAMS ((sd_chain_struct *, int)); +static void pa_ip PARAMS ((char *)); +static void fix_new_hppa PARAMS ((fragS *, int, int, symbolS *, + long, expressionS *, int, + bfd_reloc_code_real_type, + enum hppa_reloc_field_selector_type_alt, + int, long, int *)); +static int is_end_of_statement PARAMS ((void)); +static int reg_name_search PARAMS ((char *)); +static int pa_chk_field_selector PARAMS ((char **)); +static int is_same_frag PARAMS ((fragS *, fragS *)); +static void process_exit PARAMS ((void)); +static sd_chain_struct *pa_parse_space_stmt PARAMS ((char *, int)); +static int log2 PARAMS ((int)); +static int pa_next_subseg PARAMS ((sd_chain_struct *)); +static unsigned int pa_stringer_aux PARAMS ((char *)); +static void pa_spaces_begin PARAMS ((void)); + +#ifdef OBJ_ELF +static void hppa_elf_mark_end_of_function PARAMS ((void)); +static void pa_build_unwind_subspace PARAMS ((struct call_info *)); +#endif + +/* File and gloally scoped variable declarations. */ + +/* Root and final entry in the space chain. */ +static sd_chain_struct *space_dict_root; +static sd_chain_struct *space_dict_last; + +/* The current space and subspace. */ +static sd_chain_struct *current_space; +static ssd_chain_struct *current_subspace; + +/* Root of the call_info chain. */ +static struct call_info *call_info_root; + +/* The last call_info (for functions) structure + seen so it can be associated with fixups and + function labels. */ +static struct call_info *last_call_info; + +/* The last call description (for actual calls). */ +static struct call_desc last_call_desc; + +/* handle of the OPCODE hash table */ +static struct hash_control *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[] = ";"; + +/* Table of pseudo ops for the PA. FIXME -- how many of these + are now redundant with the overall GAS and the object file + dependent tables? */ +const pseudo_typeS md_pseudo_table[] = +{ + /* align pseudo-ops on the PA specify the actual alignment requested, + not the log2 of the requested alignment. */ + {"align", pa_align, 8}, + {"begin_brtab", pa_brtab, 1}, + {"begin_try", pa_try, 1}, + {"block", pa_block, 1}, + {"blockz", pa_block, 0}, + {"byte", pa_cons, 1}, + {"call", pa_call, 0}, + {"callinfo", pa_callinfo, 0}, + {"code", pa_code, 0}, + {"comm", pa_comm, 0}, +#ifdef OBJ_SOM + {"compiler", pa_compiler, 0}, +#endif + {"copyright", pa_copyright, 0}, + {"data", pa_data, 0}, + {"double", pa_float_cons, 'd'}, + {"end", pa_end, 0}, + {"end_brtab", pa_brtab, 0}, + {"end_try", pa_try, 0}, + {"enter", pa_enter, 0}, + {"entry", pa_entry, 0}, + {"equ", pa_equ, 0}, + {"exit", pa_exit, 0}, + {"export", pa_export, 0}, + {"fill", pa_fill, 0}, + {"float", pa_float_cons, 'f'}, + {"half", pa_cons, 2}, + {"import", pa_import, 0}, + {"int", pa_cons, 4}, + {"label", pa_label, 0}, + {"lcomm", pa_lcomm, 0}, + {"leave", pa_leave, 0}, + {"level", pa_level, 0}, + {"long", pa_cons, 4}, + {"lsym", pa_lsym, 0}, + {"nsubspa", pa_subspace, 1}, + {"octa", pa_cons, 16}, + {"org", pa_origin, 0}, + {"origin", pa_origin, 0}, + {"param", pa_param, 0}, + {"proc", pa_proc, 0}, + {"procend", pa_procend, 0}, + {"quad", pa_cons, 8}, + {"reg", pa_equ, 1}, + {"short", pa_cons, 2}, + {"single", pa_float_cons, 'f'}, + {"space", pa_space, 0}, + {"spnum", pa_spnum, 0}, + {"string", pa_stringer, 0}, + {"stringz", pa_stringer, 1}, + {"subspa", pa_subspace, 0}, + {"text", pa_text, 0}, + {"version", pa_version, 0}, + {"word", pa_cons, 4}, + {NULL, 0, 0} +}; + +/* 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 will always work. */ +const char line_comment_chars[] = "#"; + +/* This array holds the characters which act as line separators. */ +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. + + Be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be + changed in read.c. Ideally it shouldn't hae to know abou it at + all, but nothing is ideal around here. */ +const char FLT_CHARS[] = "rRsSfFdDxXpP"; + +static struct pa_it the_insn; + +/* Points to the end of an expression just parsed by get_expressoin + and friends. FIXME. This shouldn't be handled with a file-global + variable. */ +static char *expr_end; + +/* Nonzero if a .callinfo appeared within the current procedure. */ +static int callinfo_found; + +/* Nonzero if the assembler is currently within a .entry/.exit pair. */ +static int within_entry_exit; + +/* Nonzero if the assembler is currently within a procedure definition. */ +static int within_procedure; + +/* Handle on strucutre which keep track of the last symbol + seen in each subspace. */ +static label_symbol_struct *label_symbols_rootp = NULL; + +/* Holds the last field selector. */ +static int hppa_field_selector; + + +/* A dummy bfd symbol so that all relocations have symbols of some kind. */ +static symbolS *dummy_symbol; + +/* Nonzero if errors are to be printed. */ +static int print_errors = 1; + +/* List of registers that are pre-defined: + + Each general register has one predefined name of the form + %r which has the value . + + Space and control registers are handled in a similar manner, + but use %sr and %cr as their predefined names. + + Likewise for the floating point registers, but of the form + %fr. Floating point registers have additional predefined + names with 'L' and 'R' suffixes (e.g. %fr19L, %fr19R) which + again have the value . + + Many registers also have synonyms: + + %r26 - %r23 have %arg0 - %arg3 as synonyms + %r28 - %r29 have %ret0 - %ret1 as synonyms + %r30 has %sp as a synonym + %r27 has %dp as a synonym + %r2 has %rp as a synonym + + Almost every control register has a synonym; they are not listed + here for brevity. + + The table is sorted. Suitable for searching by a binary search. */ + +static const struct pd_reg pre_defined_registers[] = +{ + {"%arg0", 26}, + {"%arg1", 25}, + {"%arg2", 24}, + {"%arg3", 23}, + {"%cr0", 0}, + {"%cr10", 10}, + {"%cr11", 11}, + {"%cr12", 12}, + {"%cr13", 13}, + {"%cr14", 14}, + {"%cr15", 15}, + {"%cr16", 16}, + {"%cr17", 17}, + {"%cr18", 18}, + {"%cr19", 19}, + {"%cr20", 20}, + {"%cr21", 21}, + {"%cr22", 22}, + {"%cr23", 23}, + {"%cr24", 24}, + {"%cr25", 25}, + {"%cr26", 26}, + {"%cr27", 27}, + {"%cr28", 28}, + {"%cr29", 29}, + {"%cr30", 30}, + {"%cr31", 31}, + {"%cr8", 8}, + {"%cr9", 9}, + {"%dp", 27}, + {"%eiem", 15}, + {"%eirr", 23}, + {"%fr0", 0}, + {"%fr0l", 0}, + {"%fr0r", 0}, + {"%fr1", 1}, + {"%fr10", 10}, + {"%fr10l", 10}, + {"%fr10r", 10}, + {"%fr11", 11}, + {"%fr11l", 11}, + {"%fr11r", 11}, + {"%fr12", 12}, + {"%fr12l", 12}, + {"%fr12r", 12}, + {"%fr13", 13}, + {"%fr13l", 13}, + {"%fr13r", 13}, + {"%fr14", 14}, + {"%fr14l", 14}, + {"%fr14r", 14}, + {"%fr15", 15}, + {"%fr15l", 15}, + {"%fr15r", 15}, + {"%fr16", 16}, + {"%fr16l", 16}, + {"%fr16r", 16}, + {"%fr17", 17}, + {"%fr17l", 17}, + {"%fr17r", 17}, + {"%fr18", 18}, + {"%fr18l", 18}, + {"%fr18r", 18}, + {"%fr19", 19}, + {"%fr19l", 19}, + {"%fr19r", 19}, + {"%fr1l", 1}, + {"%fr1r", 1}, + {"%fr2", 2}, + {"%fr20", 20}, + {"%fr20l", 20}, + {"%fr20r", 20}, + {"%fr21", 21}, + {"%fr21l", 21}, + {"%fr21r", 21}, + {"%fr22", 22}, + {"%fr22l", 22}, + {"%fr22r", 22}, + {"%fr23", 23}, + {"%fr23l", 23}, + {"%fr23r", 23}, + {"%fr24", 24}, + {"%fr24l", 24}, + {"%fr24r", 24}, + {"%fr25", 25}, + {"%fr25l", 25}, + {"%fr25r", 25}, + {"%fr26", 26}, + {"%fr26l", 26}, + {"%fr26r", 26}, + {"%fr27", 27}, + {"%fr27l", 27}, + {"%fr27r", 27}, + {"%fr28", 28}, + {"%fr28l", 28}, + {"%fr28r", 28}, + {"%fr29", 29}, + {"%fr29l", 29}, + {"%fr29r", 29}, + {"%fr2l", 2}, + {"%fr2r", 2}, + {"%fr3", 3}, + {"%fr30", 30}, + {"%fr30l", 30}, + {"%fr30r", 30}, + {"%fr31", 31}, + {"%fr31l", 31}, + {"%fr31r", 31}, + {"%fr3l", 3}, + {"%fr3r", 3}, + {"%fr4", 4}, + {"%fr4l", 4}, + {"%fr4r", 4}, + {"%fr5", 5}, + {"%fr5l", 5}, + {"%fr5r", 5}, + {"%fr6", 6}, + {"%fr6l", 6}, + {"%fr6r", 6}, + {"%fr7", 7}, + {"%fr7l", 7}, + {"%fr7r", 7}, + {"%fr8", 8}, + {"%fr8l", 8}, + {"%fr8r", 8}, + {"%fr9", 9}, + {"%fr9l", 9}, + {"%fr9r", 9}, + {"%hta", 25}, + {"%iir", 19}, + {"%ior", 21}, + {"%ipsw", 22}, + {"%isr", 20}, + {"%itmr", 16}, + {"%iva", 14}, + {"%pcoq", 18}, + {"%pcsq", 17}, + {"%pidr1", 8}, + {"%pidr2", 9}, + {"%pidr3", 12}, + {"%pidr4", 13}, + {"%ppda", 24}, + {"%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}, + {"%rctr", 0}, + {"%ret0", 28}, + {"%ret1", 29}, + {"%rp", 2}, + {"%sar", 11}, + {"%sp", 30}, + {"%sr0", 0}, + {"%sr1", 1}, + {"%sr2", 2}, + {"%sr3", 3}, + {"%sr4", 4}, + {"%sr5", 5}, + {"%sr6", 6}, + {"%sr7", 7}, + {"%tr0", 24}, + {"%tr1", 25}, + {"%tr2", 26}, + {"%tr3", 27}, + {"%tr4", 28}, + {"%tr5", 29}, + {"%tr6", 30}, + {"%tr7", 31} +}; + +/* This table is sorted by order of the length of the string. This is + so we check for <> before we check for <. If we had a <> and checked + for < first, we would get a false match. */ +static const struct fp_cond_map fp_cond_map[] = +{ + {"false?", 0}, + {"false", 1}, + {"true?", 30}, + {"true", 31}, + {"!<=>", 3}, + {"!?>=", 8}, + {"!?<=", 16}, + {"!<>", 7}, + {"!>=", 11}, + {"!?>", 12}, + {"?<=", 14}, + {"!<=", 19}, + {"!?<", 20}, + {"?>=", 22}, + {"!?=", 24}, + {"!=t", 27}, + {"<=>", 29}, + {"=t", 5}, + {"?=", 6}, + {"?<", 10}, + {"<=", 13}, + {"!>", 15}, + {"?>", 18}, + {">=", 21}, + {"!<", 23}, + {"<>", 25}, + {"!=", 26}, + {"!?", 28}, + {"?", 2}, + {"=", 4}, + {"<", 9}, + {">", 17} +}; + +static const struct selector_entry selector_table[] = +{ + {"f", e_fsel}, + {"l", e_lsel}, + {"ld", e_ldsel}, + {"lp", e_lpsel}, + {"lr", e_lrsel}, + {"ls", e_lssel}, + {"lt", e_ltsel}, + {"n", e_nsel}, + {"nl", e_nlsel}, + {"nlr", e_nlrsel}, + {"p", e_psel}, + {"r", e_rsel}, + {"rd", e_rdsel}, + {"rp", e_rpsel}, + {"rr", e_rrsel}, + {"rs", e_rssel}, + {"rt", e_rtsel}, + {"t", e_tsel}, +}; + +/* default space and subspace dictionaries */ + +#define GDB_SYMBOLS GDB_SYMBOLS_SUBSPACE_NAME +#define GDB_STRINGS GDB_STRINGS_SUBSPACE_NAME + +/* pre-defined subsegments (subspaces) for the HPPA. */ +#define SUBSEG_CODE 0 +#define SUBSEG_LIT 1 +#define SUBSEG_MILLI 2 +#define SUBSEG_DATA 0 +#define SUBSEG_BSS 2 +#define SUBSEG_UNWIND 3 +#define SUBSEG_GDB_STRINGS 0 +#define SUBSEG_GDB_SYMBOLS 1 + +static struct default_subspace_dict pa_def_subspaces[] = +{ + {"$CODE$", 1, 1, 1, 0, 0, 0, 24, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_CODE}, + {"$DATA$", 1, 1, 0, 0, 0, 0, 24, 0x1f, 1, 8, 1, 1, ".data", SUBSEG_DATA}, + {"$LIT$", 1, 1, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_LIT}, + {"$MILLICODE$", 1, 1, 0, 0, 0, 0, 8, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_MILLI}, + {"$BSS$", 1, 1, 0, 0, 0, 1, 80, 0x1f, 1, 8, 1, 1, ".bss", SUBSEG_BSS}, +#ifdef OBJ_ELF + {"$UNWIND$", 1, 1, 0, 0, 0, 0, 64, 0x2c, 0, 4, 0, 0, ".PARISC.unwind", SUBSEG_UNWIND}, +#endif + {NULL, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 0, 0} +}; + +static struct default_space_dict pa_def_spaces[] = +{ + {"$TEXT$", 0, 1, 1, 0, 8, ASEC_NULL, ".text"}, + {"$PRIVATE$", 1, 1, 1, 1, 16, ASEC_NULL, ".data"}, + {NULL, 0, 0, 0, 0, 0, ASEC_NULL, NULL} +}; + +/* Misc local definitions used by the assembler. */ + +/* Return nonzero if the string pointed to by S potentially represents + a right or left half of a FP register */ +#define IS_R_SELECT(S) (*(S) == 'R' || *(S) == 'r') +#define IS_L_SELECT(S) (*(S) == 'L' || *(S) == 'l') + +/* These macros are used to maintain spaces/subspaces. */ +#define SPACE_DEFINED(space_chain) (space_chain)->sd_defined +#define SPACE_USER_DEFINED(space_chain) (space_chain)->sd_user_defined +#define SPACE_SPNUM(space_chain) (space_chain)->sd_spnum +#define SPACE_NAME(space_chain) (space_chain)->sd_name + +#define SUBSPACE_DEFINED(ss_chain) (ss_chain)->ssd_defined +#define SUBSPACE_NAME(ss_chain) (ss_chain)->ssd_name + +/* Insert FIELD into OPCODE starting at bit START. Continue pa_ip + main loop after insertion. */ + +#define INSERT_FIELD_AND_CONTINUE(OPCODE, FIELD, START) \ + { \ + ((OPCODE) |= (FIELD) << (START)); \ + continue; \ + } + +/* Simple range checking for FIELD againt HIGH and LOW bounds. + IGNORE is used to suppress the error message. */ + +#define CHECK_FIELD(FIELD, HIGH, LOW, IGNORE) \ + { \ + if ((FIELD) > (HIGH) || (FIELD) < (LOW)) \ + { \ + if (! IGNORE) \ + as_bad (_("Field out of range [%d..%d] (%d)."), (LOW), (HIGH), \ + (int) (FIELD));\ + break; \ + } \ + } + +#define is_DP_relative(exp) \ + ((exp).X_op == O_subtract \ + && strcmp((exp).X_op_symbol->bsym->name, "$global$") == 0) + +#define is_PC_relative(exp) \ + ((exp).X_op == O_subtract \ + && strcmp((exp).X_op_symbol->bsym->name, "$PIC_pcrel$0") == 0) + +/* We need some complex handling for stabs (sym1 - sym2). Luckily, we'll + always be able to reduce the expression to a constant, so we don't + need real complex handling yet. */ +#define is_complex(exp) \ + ((exp).X_op != O_constant && (exp).X_op != O_symbol) + +/* Actual functions to implement the PA specific code for the assembler. */ + +/* Called before writing the object file. Make sure entry/exit and + proc/procend pairs match. */ + +void +pa_check_eof () +{ + if (within_entry_exit) + as_fatal (_("Missing .exit\n")); + + if (within_procedure) + as_fatal (_("Missing .procend\n")); +} + +/* Check to make sure we have a valid space and subspace. */ + +static void +pa_check_current_space_and_subspace () +{ + if (current_space == NULL) + as_fatal (_("Not in a space.\n")); + + if (current_subspace == NULL) + as_fatal (_("Not in a subspace.\n")); +} + +/* Returns a pointer to the label_symbol_struct for the current space. + or NULL if no label_symbol_struct exists for the current space. */ + +static label_symbol_struct * +pa_get_label () +{ + label_symbol_struct *label_chain; + sd_chain_struct *space_chain = current_space; + + for (label_chain = label_symbols_rootp; + label_chain; + label_chain = label_chain->lss_next) + if (space_chain == label_chain->lss_space && label_chain->lss_label) + return label_chain; + + return NULL; +} + +/* Defines a label for the current space. If one is already defined, + this function will replace it with the new label. */ + +void +pa_define_label (symbol) + symbolS *symbol; +{ + label_symbol_struct *label_chain = pa_get_label (); + sd_chain_struct *space_chain = current_space; + + if (label_chain) + label_chain->lss_label = symbol; + else + { + /* Create a new label entry and add it to the head of the chain. */ + label_chain + = (label_symbol_struct *) xmalloc (sizeof (label_symbol_struct)); + label_chain->lss_label = symbol; + label_chain->lss_space = space_chain; + label_chain->lss_next = NULL; + + if (label_symbols_rootp) + label_chain->lss_next = label_symbols_rootp; + + label_symbols_rootp = label_chain; + } +} + +/* Removes a label definition for the current space. + If there is no label_symbol_struct entry, then no action is taken. */ + +static void +pa_undefine_label () +{ + label_symbol_struct *label_chain; + label_symbol_struct *prev_label_chain = NULL; + sd_chain_struct *space_chain = current_space; + + for (label_chain = label_symbols_rootp; + label_chain; + label_chain = label_chain->lss_next) + { + if (space_chain == label_chain->lss_space && label_chain->lss_label) + { + /* Remove the label from the chain and free its memory. */ + if (prev_label_chain) + prev_label_chain->lss_next = label_chain->lss_next; + else + label_symbols_rootp = label_chain->lss_next; + + free (label_chain); + break; + } + prev_label_chain = label_chain; + } +} + + +/* An HPPA-specific version of fix_new. This is required because the HPPA + code needs to keep track of some extra stuff. Each call to fix_new_hppa + results in the creation of an instance of an hppa_fix_struct. An + hppa_fix_struct stores the extra information along with a pointer to the + original fixS. This is attached to the original fixup via the + tc_fix_data field. */ + +static void +fix_new_hppa (frag, where, size, add_symbol, offset, exp, pcrel, + r_type, r_field, r_format, arg_reloc, unwind_bits) + fragS *frag; + int where; + int size; + symbolS *add_symbol; + long offset; + expressionS *exp; + int pcrel; + bfd_reloc_code_real_type r_type; + enum hppa_reloc_field_selector_type_alt r_field; + int r_format; + long arg_reloc; + int* unwind_bits; +{ + fixS *new_fix; + + struct hppa_fix_struct *hppa_fix = (struct hppa_fix_struct *) + obstack_alloc (¬es, sizeof (struct hppa_fix_struct)); + + if (exp != NULL) + new_fix = fix_new_exp (frag, where, size, exp, pcrel, r_type); + else + new_fix = fix_new (frag, where, size, add_symbol, offset, pcrel, r_type); + new_fix->tc_fix_data = (void *) hppa_fix; + hppa_fix->fx_r_type = r_type; + hppa_fix->fx_r_field = r_field; + hppa_fix->fx_r_format = r_format; + hppa_fix->fx_arg_reloc = arg_reloc; + hppa_fix->segment = now_seg; +#ifdef OBJ_SOM + if (r_type == R_ENTRY || r_type == R_EXIT) + new_fix->fx_offset = *unwind_bits; +#endif + + /* foo-$global$ is used to access non-automatic storage. $global$ + is really just a marker and has served its purpose, so eliminate + it now so as not to confuse write.c. */ + if (new_fix->fx_subsy + && !strcmp (S_GET_NAME (new_fix->fx_subsy), "$global$")) + new_fix->fx_subsy = NULL; +} + +/* Parse a .byte, .word, .long expression for the HPPA. Called by + cons via the TC_PARSE_CONS_EXPRESSION macro. */ + +void +parse_cons_expression_hppa (exp) + expressionS *exp; +{ + hppa_field_selector = pa_chk_field_selector (&input_line_pointer); + expression (exp); +} + +/* This fix_new is called by cons via TC_CONS_FIX_NEW. + hppa_field_selector is set by the parse_cons_expression_hppa. */ + +void +cons_fix_new_hppa (frag, where, size, exp) + fragS *frag; + int where; + int size; + expressionS *exp; +{ + unsigned int rel_type; + + /* Get a base relocation type. */ + if (is_DP_relative (*exp)) + rel_type = R_HPPA_GOTOFF; + else if (is_complex (*exp)) + rel_type = R_HPPA_COMPLEX; + else + rel_type = R_HPPA; + + if (hppa_field_selector != e_psel && hppa_field_selector != e_fsel) + as_warn (_("Invalid field selector. Assuming F%%.")); + + fix_new_hppa (frag, where, size, + (symbolS *) NULL, (offsetT) 0, exp, 0, rel_type, + hppa_field_selector, 32, 0, NULL); + + /* Reset field selector to its default state. */ + hppa_field_selector = 0; +} + +/* 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 () +{ + const char *retval = NULL; + int lose = 0; + unsigned int i = 0; + + last_call_info = NULL; + call_info_root = NULL; + + /* Set the default machine type. */ + if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, 10)) + as_warn (_("could not set architecture and machine")); + + /* Folding of text and data segments fails miserably on the PA. + Warn user and disable "-R" option. */ + if (flag_readonly_data_in_text) + { + as_warn (_("-R option not supported on this target.")); + flag_readonly_data_in_text = 0; + } + + pa_spaces_begin (); + + op_hash = hash_new (); + + while (i < NUMOPCODES) + { + const char *name = pa_opcodes[i].name; + retval = hash_insert (op_hash, name, (struct pa_opcode *) &pa_opcodes[i]); + if (retval != NULL && *retval != '\0') + { + as_fatal (_("Internal error: can't hash `%s': %s\n"), name, retval); + lose = 1; + } + do + { + if ((pa_opcodes[i].match & pa_opcodes[i].mask) + != pa_opcodes[i].match) + { + fprintf (stderr, _("internal error: losing opcode: `%s' \"%s\"\n"), + pa_opcodes[i].name, pa_opcodes[i].args); + lose = 1; + } + ++i; + } + while (i < NUMOPCODES && !strcmp (pa_opcodes[i].name, name)); + } + + if (lose) + as_fatal (_("Broken assembler. No assembly attempted.")); + + /* SOM will change text_section. To make sure we never put + anything into the old one switch to the new one now. */ + subseg_set (text_section, 0); + + dummy_symbol = symbol_find_or_make ("L$dummy"); + S_SET_SEGMENT (dummy_symbol, text_section); +} + +/* Assemble a single instruction storing it into a frag. */ +void +md_assemble (str) + char *str; +{ + char *to; + + /* The had better be something to assemble. */ + assert (str); + + /* If we are within a procedure definition, make sure we've + defined a label for the procedure; handle case where the + label was defined after the .PROC directive. + + Note there's not need to diddle with the segment or fragment + for the label symbol in this case. We have already switched + into the new $CODE$ subspace at this point. */ + if (within_procedure && last_call_info->start_symbol == NULL) + { + label_symbol_struct *label_symbol = pa_get_label (); + + if (label_symbol) + { + if (label_symbol->lss_label) + { + last_call_info->start_symbol = label_symbol->lss_label; + label_symbol->lss_label->bsym->flags |= BSF_FUNCTION; +#ifdef OBJ_SOM + /* Also handle allocation of a fixup to hold the unwind + information when the label appears after the proc/procend. */ + if (within_entry_exit) + { + char *where = frag_more (0); + + fix_new_hppa (frag_now, where - frag_now->fr_literal, 0, + NULL, (offsetT) 0, NULL, + 0, R_HPPA_ENTRY, e_fsel, 0, 0, + (int *)&last_call_info->ci_unwind.descriptor); + } +#endif + } + else + as_bad (_("Missing function name for .PROC (corrupted label chain)")); + } + else + as_bad (_("Missing function name for .PROC")); + } + + /* Assemble the instruction. Results are saved into "the_insn". */ + pa_ip (str); + + /* Get somewhere to put the assembled instrution. */ + to = frag_more (4); + + /* Output the opcode. */ + md_number_to_chars (to, the_insn.opcode, 4); + + /* If necessary output more stuff. */ + if (the_insn.reloc != R_HPPA_NONE) + fix_new_hppa (frag_now, (to - frag_now->fr_literal), 4, NULL, + (offsetT) 0, &the_insn.exp, the_insn.pcrel, + the_insn.reloc, the_insn.field_selector, + the_insn.format, the_insn.arg_reloc, NULL); +} + +/* Do the real work for assembling a single instruction. Store results + into the global "the_insn" variable. */ + +static void +pa_ip (str) + char *str; +{ + char *error_message = ""; + char *s, c, *argstart, *name, *save_s; + const char *args; + int match = FALSE; + int comma = 0; + int cmpltr, nullif, flag, cond, num; + unsigned long opcode; + struct pa_opcode *insn; + + /* We must have a valid space and subspace. */ + pa_check_current_space_and_subspace (); + + /* Skip to something interesting. */ + for (s = str; isupper (*s) || islower (*s) || (*s >= '0' && *s <= '3'); ++s) + ; + + switch (*s) + { + + case '\0': + break; + + case ',': + comma = 1; + + /*FALLTHROUGH */ + + case ' ': + *s++ = '\0'; + break; + + default: + as_fatal (_("Unknown opcode: `%s'"), str); + } + + save_s = str; + + /* Convert everything into lower case. */ + while (*save_s) + { + if (isupper (*save_s)) + *save_s = tolower (*save_s); + save_s++; + } + + /* Look up the opcode in the has table. */ + if ((insn = (struct pa_opcode *) hash_find (op_hash, str)) == NULL) + { + as_bad ("Unknown opcode: `%s'", str); + return; + } + + if (comma) + { + *--s = ','; + } + + /* Mark the location where arguments for the instruction start, then + start processing them. */ + argstart = s; + for (;;) + { + /* Do some initialization. */ + opcode = insn->match; + memset (&the_insn, 0, sizeof (the_insn)); + + the_insn.reloc = R_HPPA_NONE; + + /* If this instruction is specific to a particular architecture, + then set a new architecture. */ + /* But do not automatically promote to pa2.0. The automatic promotion + crud is for compatability with HP's old assemblers only. */ + if (insn->arch < 20 + && bfd_get_mach (stdoutput) < insn->arch) + { + if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, insn->arch)) + as_warn (_("could not update architecture and machine")); + } + else if (bfd_get_mach (stdoutput) < insn->arch) + { + match = FALSE; + goto failed; + } + + /* Build the opcode, checking as we go to make + sure that the operands match. */ + for (args = insn->args;; ++args) + { + switch (*args) + { + + /* End of arguments. */ + case '\0': + if (*s == '\0') + match = TRUE; + break; + + case '+': + if (*s == '+') + { + ++s; + continue; + } + if (*s == '-') + continue; + break; + + /* These must match exactly. */ + case '(': + case ')': + case ',': + case ' ': + if (*s++ == *args) + continue; + break; + + /* Handle a 5 bit register or control register field at 10. */ + case 'b': + case '^': + num = pa_parse_number (&s, 0); + CHECK_FIELD (num, 31, 0, 0); + INSERT_FIELD_AND_CONTINUE (opcode, num, 21); + + /* Handle a 5 bit register field at 15. */ + case 'x': + num = pa_parse_number (&s, 0); + CHECK_FIELD (num, 31, 0, 0); + INSERT_FIELD_AND_CONTINUE (opcode, num, 16); + + /* Handle a 5 bit register field at 31. */ + case 'y': + case 't': + num = pa_parse_number (&s, 0); + CHECK_FIELD (num, 31, 0, 0); + INSERT_FIELD_AND_CONTINUE (opcode, num, 0); + + /* Handle a 5 bit field length at 31. */ + case 'T': + num = pa_get_absolute_expression (&the_insn, &s); + s = expr_end; + CHECK_FIELD (num, 32, 1, 0); + INSERT_FIELD_AND_CONTINUE (opcode, 32 - num, 0); + + /* Handle a 5 bit immediate at 15. */ + case '5': + num = pa_get_absolute_expression (&the_insn, &s); + s = expr_end; + CHECK_FIELD (num, 15, -16, 0); + low_sign_unext (num, 5, &num); + INSERT_FIELD_AND_CONTINUE (opcode, num, 16); + + /* Handle a 5 bit immediate at 31. */ + case 'V': + num = pa_get_absolute_expression (&the_insn, &s); + s = expr_end; + CHECK_FIELD (num, 15, -16, 0) + low_sign_unext (num, 5, &num); + INSERT_FIELD_AND_CONTINUE (opcode, num, 0); + + /* Handle an unsigned 5 bit immediate at 31. */ + case 'r': + num = pa_get_absolute_expression (&the_insn, &s); + s = expr_end; + CHECK_FIELD (num, 31, 0, 0); + INSERT_FIELD_AND_CONTINUE (opcode, num, 0); + + /* Handle an unsigned 5 bit immediate at 15. */ + case 'R': + num = pa_get_absolute_expression (&the_insn, &s); + s = expr_end; + CHECK_FIELD (num, 31, 0, 0); + INSERT_FIELD_AND_CONTINUE (opcode, num, 16); + + /* Handle a 2 bit space identifier at 17. */ + case 's': + num = pa_parse_number (&s, 0); + CHECK_FIELD (num, 3, 0, 1); + INSERT_FIELD_AND_CONTINUE (opcode, num, 14); + + /* Handle a 3 bit space identifier at 18. */ + case 'S': + num = pa_parse_number (&s, 0); + CHECK_FIELD (num, 7, 0, 1); + dis_assemble_3 (num, &num); + INSERT_FIELD_AND_CONTINUE (opcode, num, 13); + + /* Handle a completer for an indexing load or store. */ + case 'c': + { + int uu = 0; + int m = 0; + int i = 0; + while (*s == ',' && i < 2) + { + s++; + if (strncasecmp (s, "sm", 2) == 0) + { + uu = 1; + m = 1; + s++; + i++; + } + else if (strncasecmp (s, "m", 1) == 0) + m = 1; + else if (strncasecmp (s, "s", 1) == 0) + uu = 1; + else + as_bad (_("Invalid Indexed Load Completer.")); + s++; + i++; + } + if (i > 2) + as_bad (_("Invalid Indexed Load Completer Syntax.")); + opcode |= m << 5; + INSERT_FIELD_AND_CONTINUE (opcode, uu, 13); + } + + /* Handle a short load/store completer. */ + case 'C': + { + int a = 0; + int m = 0; + if (*s == ',') + { + s++; + if (strncasecmp (s, "ma", 2) == 0) + { + a = 0; + m = 1; + } + else if (strncasecmp (s, "mb", 2) == 0) + { + a = 1; + m = 1; + } + else + as_bad (_("Invalid Short Load/Store Completer.")); + s += 2; + } + + if (*args == 'C') + { + opcode |= m << 5; + INSERT_FIELD_AND_CONTINUE (opcode, a, 13); + } + } + + /* Handle a stbys completer. */ + case 'Y': + { + int a = 0; + int m = 0; + int i = 0; + while (*s == ',' && i < 2) + { + s++; + if (strncasecmp (s, "m", 1) == 0) + m = 1; + else if (strncasecmp (s, "b", 1) == 0) + a = 0; + else if (strncasecmp (s, "e", 1) == 0) + a = 1; + else + as_bad (_("Invalid Store Bytes Short Completer")); + s++; + i++; + } + if (i > 2) + as_bad (_("Invalid Store Bytes Short Completer")); + opcode |= m << 5; + INSERT_FIELD_AND_CONTINUE (opcode, a, 13); + } + + /* Handle a non-negated compare/stubtract condition. */ + case '<': + cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 1); + if (cmpltr < 0) + { + as_bad (_("Invalid Compare/Subtract Condition: %c"), *s); + cmpltr = 0; + } + INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13); + + /* Handle a negated or non-negated compare/subtract condition. */ + case '?': + save_s = s; + cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 1); + if (cmpltr < 0) + { + s = save_s; + cmpltr = pa_parse_neg_cmpsub_cmpltr (&s, 1); + if (cmpltr < 0) + { + as_bad (_("Invalid Compare/Subtract Condition.")); + cmpltr = 0; + } + else + { + /* Negated condition requires an opcode change. */ + opcode |= 1 << 27; + } + } + + INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13); + + /* Handle non-negated add condition. */ + case '!': + cmpltr = pa_parse_nonneg_add_cmpltr (&s, 1); + if (cmpltr < 0) + { + as_bad (_("Invalid Compare/Subtract Condition: %c"), *s); + cmpltr = 0; + } + INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13); + + /* Handle a negated or non-negated add condition. */ + case '@': + save_s = s; + cmpltr = pa_parse_nonneg_add_cmpltr (&s, 1); + if (cmpltr < 0) + { + s = save_s; + cmpltr = pa_parse_neg_add_cmpltr (&s, 1); + if (cmpltr < 0) + { + as_bad (_("Invalid Compare/Subtract Condition")); + cmpltr = 0; + } + else + { + /* Negated condition requires an opcode change. */ + opcode |= 1 << 27; + } + } + INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13); + + /* Handle a compare/subtract condition. */ + case 'a': + cmpltr = 0; + flag = 0; + if (*s == ',') + { + s++; + name = s; + while (*s != ',' && *s != ' ' && *s != '\t') + s += 1; + c = *s; + *s = 0x00; + if (strcmp (name, "=") == 0) + cmpltr = 1; + else if (strcmp (name, "<") == 0) + cmpltr = 2; + else if (strcmp (name, "<=") == 0) + cmpltr = 3; + else if (strcasecmp (name, "<<") == 0) + cmpltr = 4; + else if (strcasecmp (name, "<<=") == 0) + cmpltr = 5; + else if (strcasecmp (name, "sv") == 0) + cmpltr = 6; + else if (strcasecmp (name, "od") == 0) + cmpltr = 7; + else if (strcasecmp (name, "tr") == 0) + { + cmpltr = 0; + flag = 1; + } + else if (strcmp (name, "<>") == 0) + { + cmpltr = 1; + flag = 1; + } + else if (strcmp (name, ">=") == 0) + { + cmpltr = 2; + flag = 1; + } + else if (strcmp (name, ">") == 0) + { + cmpltr = 3; + flag = 1; + } + else if (strcasecmp (name, ">>=") == 0) + { + cmpltr = 4; + flag = 1; + } + else if (strcasecmp (name, ">>") == 0) + { + cmpltr = 5; + flag = 1; + } + else if (strcasecmp (name, "nsv") == 0) + { + cmpltr = 6; + flag = 1; + } + else if (strcasecmp (name, "ev") == 0) + { + cmpltr = 7; + flag = 1; + } + else + as_bad (_("Invalid Add Condition: %s"), name); + *s = c; + } + opcode |= cmpltr << 13; + INSERT_FIELD_AND_CONTINUE (opcode, flag, 12); + + /* Handle a non-negated add condition. */ + case 'd': + cmpltr = 0; + flag = 0; + if (*s == ',') + { + s++; + name = s; + while (*s != ',' && *s != ' ' && *s != '\t') + s += 1; + c = *s; + *s = 0x00; + if (strcmp (name, "=") == 0) + cmpltr = 1; + else if (strcmp (name, "<") == 0) + cmpltr = 2; + else if (strcmp (name, "<=") == 0) + cmpltr = 3; + else if (strcasecmp (name, "nuv") == 0) + cmpltr = 4; + else if (strcasecmp (name, "znv") == 0) + cmpltr = 5; + else if (strcasecmp (name, "sv") == 0) + cmpltr = 6; + else if (strcasecmp (name, "od") == 0) + cmpltr = 7; + else if (strcasecmp (name, "tr") == 0) + { + cmpltr = 0; + flag = 1; + } + else if (strcmp (name, "<>") == 0) + { + cmpltr = 1; + flag = 1; + } + else if (strcmp (name, ">=") == 0) + { + cmpltr = 2; + flag = 1; + } + else if (strcmp (name, ">") == 0) + { + cmpltr = 3; + flag = 1; + } + else if (strcasecmp (name, "uv") == 0) + { + cmpltr = 4; + flag = 1; + } + else if (strcasecmp (name, "vnz") == 0) + { + cmpltr = 5; + flag = 1; + } + else if (strcasecmp (name, "nsv") == 0) + { + cmpltr = 6; + flag = 1; + } + else if (strcasecmp (name, "ev") == 0) + { + cmpltr = 7; + flag = 1; + } + else + as_bad (_("Invalid Add Condition: %s"), name); + *s = c; + } + opcode |= cmpltr << 13; + INSERT_FIELD_AND_CONTINUE (opcode, flag, 12); + + /* HANDLE a logical instruction condition. */ + case '&': + cmpltr = 0; + flag = 0; + if (*s == ',') + { + s++; + name = s; + while (*s != ',' && *s != ' ' && *s != '\t') + s += 1; + c = *s; + *s = 0x00; + + + if (strcmp (name, "=") == 0) + cmpltr = 1; + else if (strcmp (name, "<") == 0) + cmpltr = 2; + else if (strcmp (name, "<=") == 0) + cmpltr = 3; + else if (strcasecmp (name, "od") == 0) + cmpltr = 7; + else if (strcasecmp (name, "tr") == 0) + { + cmpltr = 0; + flag = 1; + } + else if (strcmp (name, "<>") == 0) + { + cmpltr = 1; + flag = 1; + } + else if (strcmp (name, ">=") == 0) + { + cmpltr = 2; + flag = 1; + } + else if (strcmp (name, ">") == 0) + { + cmpltr = 3; + flag = 1; + } + else if (strcasecmp (name, "ev") == 0) + { + cmpltr = 7; + flag = 1; + } + else + as_bad (_("Invalid Logical Instruction Condition.")); + *s = c; + } + opcode |= cmpltr << 13; + INSERT_FIELD_AND_CONTINUE (opcode, flag, 12); + + /* Handle a unit instruction condition. */ + case 'U': + cmpltr = 0; + flag = 0; + if (*s == ',') + { + s++; + + + if (strncasecmp (s, "sbz", 3) == 0) + { + cmpltr = 2; + s += 3; + } + else if (strncasecmp (s, "shz", 3) == 0) + { + cmpltr = 3; + s += 3; + } + else if (strncasecmp (s, "sdc", 3) == 0) + { + cmpltr = 4; + s += 3; + } + else if (strncasecmp (s, "sbc", 3) == 0) + { + cmpltr = 6; + s += 3; + } + else if (strncasecmp (s, "shc", 3) == 0) + { + cmpltr = 7; + s += 3; + } + else if (strncasecmp (s, "tr", 2) == 0) + { + cmpltr = 0; + flag = 1; + s += 2; + } + else if (strncasecmp (s, "nbz", 3) == 0) + { + cmpltr = 2; + flag = 1; + s += 3; + } + else if (strncasecmp (s, "nhz", 3) == 0) + { + cmpltr = 3; + flag = 1; + s += 3; + } + else if (strncasecmp (s, "ndc", 3) == 0) + { + cmpltr = 4; + flag = 1; + s += 3; + } + else if (strncasecmp (s, "nbc", 3) == 0) + { + cmpltr = 6; + flag = 1; + s += 3; + } + else if (strncasecmp (s, "nhc", 3) == 0) + { + cmpltr = 7; + flag = 1; + s += 3; + } + else + as_bad (_("Invalid Logical Instruction Condition.")); + } + opcode |= cmpltr << 13; + INSERT_FIELD_AND_CONTINUE (opcode, flag, 12); + + /* Handle a shift/extract/deposit condition. */ + case '|': + case '>': + cmpltr = 0; + if (*s == ',') + { + save_s = s++; + + + name = s; + while (*s != ',' && *s != ' ' && *s != '\t') + s += 1; + c = *s; + *s = 0x00; + if (strcmp (name, "=") == 0) + cmpltr = 1; + else if (strcmp (name, "<") == 0) + cmpltr = 2; + else if (strcasecmp (name, "od") == 0) + cmpltr = 3; + else if (strcasecmp (name, "tr") == 0) + cmpltr = 4; + else if (strcmp (name, "<>") == 0) + cmpltr = 5; + else if (strcmp (name, ">=") == 0) + cmpltr = 6; + else if (strcasecmp (name, "ev") == 0) + cmpltr = 7; + /* Handle movb,n. Put things back the way they were. + This includes moving s back to where it started. */ + else if (strcasecmp (name, "n") == 0 && *args == '|') + { + *s = c; + s = save_s; + continue; + } + else + as_bad (_("Invalid Shift/Extract/Deposit Condition.")); + *s = c; + } + INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13); + + /* Handle bvb and bb conditions. */ + case '~': + cmpltr = 0; + if (*s == ',') + { + s++; + if (strncmp (s, "<", 1) == 0) + { + cmpltr = 0; + s++; + } + else if (strncmp (s, ">=", 2) == 0) + { + cmpltr = 1; + s += 2; + } + else + as_bad (_("Invalid Bit Branch Condition: %c"), *s); + } + INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 15); + + /* Handle a system control completer. */ + case 'Z': + if (*s == ',' && (*(s + 1) == 'm' || *(s + 1) == 'M')) + { + flag = 1; + s += 2; + } + else + flag = 0; + + INSERT_FIELD_AND_CONTINUE (opcode, flag, 5); + + /* Handle a nullification completer for branch instructions. */ + case 'n': + nullif = pa_parse_nullif (&s); + INSERT_FIELD_AND_CONTINUE (opcode, nullif, 1); + + /* Handle a nullification completer for copr and spop insns. */ + case 'N': + nullif = pa_parse_nullif (&s); + INSERT_FIELD_AND_CONTINUE (opcode, nullif, 5); + + + /* Handle a 11 bit immediate at 31. */ + case 'i': + the_insn.field_selector = pa_chk_field_selector (&s); + get_expression (s); + s = expr_end; + if (the_insn.exp.X_op == O_constant) + { + num = evaluate_absolute (&the_insn); + CHECK_FIELD (num, 1023, -1024, 0); + low_sign_unext (num, 11, &num); + INSERT_FIELD_AND_CONTINUE (opcode, num, 0); + } + else + { + if (is_DP_relative (the_insn.exp)) + the_insn.reloc = R_HPPA_GOTOFF; + else if (is_PC_relative (the_insn.exp)) + the_insn.reloc = R_HPPA_PCREL_CALL; + else + the_insn.reloc = R_HPPA; + the_insn.format = 11; + continue; + } + + + /* Handle a 14 bit immediate at 31. */ + case 'j': + the_insn.field_selector = pa_chk_field_selector (&s); + get_expression (s); + s = expr_end; + if (the_insn.exp.X_op == O_constant) + { + num = evaluate_absolute (&the_insn); + CHECK_FIELD (num, 8191, -8192, 0); + low_sign_unext (num, 14, &num); + INSERT_FIELD_AND_CONTINUE (opcode, num, 0); + } + else + { + if (is_DP_relative (the_insn.exp)) + the_insn.reloc = R_HPPA_GOTOFF; + else if (is_PC_relative (the_insn.exp)) + the_insn.reloc = R_HPPA_PCREL_CALL; + else + the_insn.reloc = R_HPPA; + the_insn.format = 14; + continue; + } + + /* Handle a 21 bit immediate at 31. */ + case 'k': + the_insn.field_selector = pa_chk_field_selector (&s); + get_expression (s); + s = expr_end; + if (the_insn.exp.X_op == O_constant) + { + num = evaluate_absolute (&the_insn); + CHECK_FIELD (num >> 11, 1048575, -1048576, 0); + dis_assemble_21 (num, &num); + INSERT_FIELD_AND_CONTINUE (opcode, num, 0); + } + else + { + if (is_DP_relative (the_insn.exp)) + the_insn.reloc = R_HPPA_GOTOFF; + else if (is_PC_relative (the_insn.exp)) + the_insn.reloc = R_HPPA_PCREL_CALL; + else + the_insn.reloc = R_HPPA; + the_insn.format = 21; + continue; + } + + /* Handle a 12 bit branch displacement. */ + case 'w': + the_insn.field_selector = pa_chk_field_selector (&s); + get_expression (s); + s = expr_end; + the_insn.pcrel = 1; + if (!strcmp (S_GET_NAME (the_insn.exp.X_add_symbol), "L$0\001")) + { + unsigned int w1, w, result; + + num = evaluate_absolute (&the_insn); + if (num % 4) + { + as_bad (_("Branch to unaligned address")); + break; + } + CHECK_FIELD (num, 8199, -8184, 0); + sign_unext ((num - 8) >> 2, 12, &result); + dis_assemble_12 (result, &w1, &w); + INSERT_FIELD_AND_CONTINUE (opcode, ((w1 << 2) | w), 0); + } + else + { + the_insn.reloc = R_HPPA_PCREL_CALL; + the_insn.format = 12; + the_insn.arg_reloc = last_call_desc.arg_reloc; + memset (&last_call_desc, 0, sizeof (struct call_desc)); + s = expr_end; + continue; + } + + /* Handle a 17 bit branch displacement. */ + case 'W': + the_insn.field_selector = pa_chk_field_selector (&s); + get_expression (s); + s = expr_end; + the_insn.pcrel = 1; + if (!the_insn.exp.X_add_symbol + || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol), + "L$0\001")) + { + unsigned int w2, w1, w, result; + + num = evaluate_absolute (&the_insn); + if (num % 4) + { + as_bad (_("Branch to unaligned address")); + break; + } + CHECK_FIELD (num, 262143, -262144, 0); + + if (the_insn.exp.X_add_symbol) + num -= 8; + + sign_unext (num >> 2, 17, &result); + dis_assemble_17 (result, &w1, &w2, &w); + INSERT_FIELD_AND_CONTINUE (opcode, + ((w2 << 2) | (w1 << 16) | w), 0); + } + else + { + the_insn.reloc = R_HPPA_PCREL_CALL; + the_insn.format = 17; + the_insn.arg_reloc = last_call_desc.arg_reloc; + memset (&last_call_desc, 0, sizeof (struct call_desc)); + continue; + } + + /* Handle an absolute 17 bit branch target. */ + case 'z': + the_insn.field_selector = pa_chk_field_selector (&s); + get_expression (s); + s = expr_end; + the_insn.pcrel = 0; + if (!the_insn.exp.X_add_symbol + || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol), + "L$0\001")) + { + unsigned int w2, w1, w, result; + + num = evaluate_absolute (&the_insn); + if (num % 4) + { + as_bad (_("Branch to unaligned address")); + break; + } + CHECK_FIELD (num, 262143, -262144, 0); + + if (the_insn.exp.X_add_symbol) + num -= 8; + + sign_unext (num >> 2, 17, &result); + dis_assemble_17 (result, &w1, &w2, &w); + INSERT_FIELD_AND_CONTINUE (opcode, + ((w2 << 2) | (w1 << 16) | w), 0); + } + else + { + the_insn.reloc = R_HPPA_ABS_CALL; + the_insn.format = 17; + the_insn.arg_reloc = last_call_desc.arg_reloc; + memset (&last_call_desc, 0, sizeof (struct call_desc)); + continue; + } + + /* Handle a 5 bit shift count at 26. */ + case 'p': + num = pa_get_absolute_expression (&the_insn, &s); + s = expr_end; + CHECK_FIELD (num, 31, 0, 0); + INSERT_FIELD_AND_CONTINUE (opcode, 31 - num, 5); + + /* Handle a 5 bit bit position at 26. */ + case 'P': + num = pa_get_absolute_expression (&the_insn, &s); + s = expr_end; + CHECK_FIELD (num, 31, 0, 0); + INSERT_FIELD_AND_CONTINUE (opcode, num, 5); + + /* Handle a 5 bit immediate at 10. */ + case 'Q': + + num = pa_get_absolute_expression (&the_insn, &s); + if (the_insn.exp.X_op != O_constant) + break; + s = expr_end; + CHECK_FIELD (num, 31, 0, 0); + INSERT_FIELD_AND_CONTINUE (opcode, num, 21); + + /* Handle a 13 bit immediate at 18. */ + case 'A': + num = pa_get_absolute_expression (&the_insn, &s); + s = expr_end; + CHECK_FIELD (num, 8191, 0, 0); + INSERT_FIELD_AND_CONTINUE (opcode, num, 13); + + /* Handle a 26 bit immediate at 31. */ + case 'D': + num = pa_get_absolute_expression (&the_insn, &s); + s = expr_end; + CHECK_FIELD (num, 671108864, 0, 0); + INSERT_FIELD_AND_CONTINUE (opcode, num, 0); + + /* Handle a 3 bit SFU identifier at 25. */ + case 'f': + if (*s++ != ',') + as_bad (_("Invalid SFU identifier")); + num = pa_get_absolute_expression (&the_insn, &s); + s = expr_end; + CHECK_FIELD (num, 7, 0, 0); + INSERT_FIELD_AND_CONTINUE (opcode, num, 6); + + /* Handle a 20 bit SOP field for spop0. */ + case 'O': + num = pa_get_absolute_expression (&the_insn, &s); + s = expr_end; + CHECK_FIELD (num, 1048575, 0, 0); + num = (num & 0x1f) | ((num & 0x000fffe0) << 6); + INSERT_FIELD_AND_CONTINUE (opcode, num, 0); + + /* Handle a 15bit SOP field for spop1. */ + case 'o': + num = pa_get_absolute_expression (&the_insn, &s); + s = expr_end; + CHECK_FIELD (num, 32767, 0, 0); + INSERT_FIELD_AND_CONTINUE (opcode, num, 11); + + /* Handle a 10bit SOP field for spop3. */ + case '0': + num = pa_get_absolute_expression (&the_insn, &s); + s = expr_end; + CHECK_FIELD (num, 1023, 0, 0); + num = (num & 0x1f) | ((num & 0x000003e0) << 6); + INSERT_FIELD_AND_CONTINUE (opcode, num, 0); + + /* Handle a 15 bit SOP field for spop2. */ + case '1': + num = pa_get_absolute_expression (&the_insn, &s); + s = expr_end; + CHECK_FIELD (num, 32767, 0, 0); + num = (num & 0x1f) | ((num & 0x00007fe0) << 6); + INSERT_FIELD_AND_CONTINUE (opcode, num, 0); + + /* Handle a 3-bit co-processor ID field. */ + case 'u': + if (*s++ != ',') + as_bad (_("Invalid COPR identifier")); + num = pa_get_absolute_expression (&the_insn, &s); + s = expr_end; + CHECK_FIELD (num, 7, 0, 0); + INSERT_FIELD_AND_CONTINUE (opcode, num, 6); + + /* Handle a 22bit SOP field for copr. */ + case '2': + num = pa_get_absolute_expression (&the_insn, &s); + s = expr_end; + CHECK_FIELD (num, 4194303, 0, 0); + num = (num & 0x1f) | ((num & 0x003fffe0) << 4); + INSERT_FIELD_AND_CONTINUE (opcode, num, 0); + + + /* Handle a source FP operand format completer. */ + case 'F': + flag = pa_parse_fp_format (&s); + the_insn.fpof1 = flag; + INSERT_FIELD_AND_CONTINUE (opcode, flag, 11); + + /* Handle a destination FP operand format completer. */ + case 'G': + /* pa_parse_format needs the ',' prefix. */ + s--; + flag = pa_parse_fp_format (&s); + the_insn.fpof2 = flag; + INSERT_FIELD_AND_CONTINUE (opcode, flag, 13); + + /* Handle FP compare conditions. */ + case 'M': + cond = pa_parse_fp_cmp_cond (&s); + INSERT_FIELD_AND_CONTINUE (opcode, cond, 0); + + /* Handle L/R register halves like 't'. */ + case 'v': + { + struct pa_11_fp_reg_struct result; + + pa_parse_number (&s, &result); + CHECK_FIELD (result.number_part, 31, 0, 0); + opcode |= result.number_part; + + /* 0x30 opcodes are FP arithmetic operation opcodes + and need to be turned into 0x38 opcodes. This + is not necessary for loads/stores. */ + if (need_pa11_opcode (&the_insn, &result) + && ((opcode & 0xfc000000) == 0x30000000)) + opcode |= 1 << 27; + + INSERT_FIELD_AND_CONTINUE (opcode, result.l_r_select & 1, 6); + } + + /* Handle L/R register halves like 'b'. */ + case 'E': + { + struct pa_11_fp_reg_struct result; + + pa_parse_number (&s, &result); + CHECK_FIELD (result.number_part, 31, 0, 0); + opcode |= result.number_part << 21; + if (need_pa11_opcode (&the_insn, &result)) + { + opcode |= (result.l_r_select & 1) << 7; + opcode |= 1 << 27; + } + continue; + } + + /* Handle L/R register halves like 'b'. */ + case '3': + { + struct pa_11_fp_reg_struct result; + int regnum; + + pa_parse_number (&s, &result); + CHECK_FIELD (result.number_part, 31, 0, 0); + opcode |= (result.number_part & 0x1c) << 11; + opcode |= (result.number_part & 0x3) << 9; + opcode |= (result.l_r_select & 1) << 8; + continue; + } + + /* Handle L/R register halves like 'x'. */ + case 'e': + { + struct pa_11_fp_reg_struct result; + + pa_parse_number (&s, &result); + CHECK_FIELD (result.number_part, 31, 0, 0); + opcode |= (result.number_part & 0x1f) << 16; + if (need_pa11_opcode (&the_insn, &result)) + { + opcode |= (result.l_r_select & 1) << 1; + } + continue; + } + + /* Handle L/R register halves like 'x'. */ + case 'X': + { + struct pa_11_fp_reg_struct result; + + pa_parse_number (&s, &result); + CHECK_FIELD (result.number_part, 31, 0, 0); + opcode |= (result.number_part & 0x1f) << 16; + if (need_pa11_opcode (&the_insn, &result)) + { + opcode |= (result.l_r_select & 1) << 12; + opcode |= 1 << 27; + } + continue; + } + + /* Handle a 5 bit register field at 10. */ + case '4': + { + struct pa_11_fp_reg_struct result; + + pa_parse_number (&s, &result); + CHECK_FIELD (result.number_part, 31, 0, 0); + if (the_insn.fpof1 == SGL) + { + if (result.number_part < 16) + { + as_bad (_("Invalid register for single precision fmpyadd or fmpysub")); + break; + } + + result.number_part &= 0xF; + result.number_part |= (result.l_r_select & 1) << 4; + } + INSERT_FIELD_AND_CONTINUE (opcode, result.number_part, 21); + } + + /* Handle a 5 bit register field at 15. */ + case '6': + { + struct pa_11_fp_reg_struct result; + + pa_parse_number (&s, &result); + CHECK_FIELD (result.number_part, 31, 0, 0); + if (the_insn.fpof1 == SGL) + { + if (result.number_part < 16) + { + as_bad (_("Invalid register for single precision fmpyadd or fmpysub")); + break; + } + result.number_part &= 0xF; + result.number_part |= (result.l_r_select & 1) << 4; + } + INSERT_FIELD_AND_CONTINUE (opcode, result.number_part, 16); + } + + /* Handle a 5 bit register field at 31. */ + case '7': + { + struct pa_11_fp_reg_struct result; + + pa_parse_number (&s, &result); + CHECK_FIELD (result.number_part, 31, 0, 0); + if (the_insn.fpof1 == SGL) + { + if (result.number_part < 16) + { + as_bad (_("Invalid register for single precision fmpyadd or fmpysub")); + break; + } + result.number_part &= 0xF; + result.number_part |= (result.l_r_select & 1) << 4; + } + INSERT_FIELD_AND_CONTINUE (opcode, result.number_part, 0); + } + + /* Handle a 5 bit register field at 20. */ + case '8': + { + struct pa_11_fp_reg_struct result; + + pa_parse_number (&s, &result); + CHECK_FIELD (result.number_part, 31, 0, 0); + if (the_insn.fpof1 == SGL) + { + if (result.number_part < 16) + { + as_bad (_("Invalid register for single precision fmpyadd or fmpysub")); + break; + } + result.number_part &= 0xF; + result.number_part |= (result.l_r_select & 1) << 4; + } + INSERT_FIELD_AND_CONTINUE (opcode, result.number_part, 11); + } + + /* Handle a 5 bit register field at 25. */ + case '9': + { + struct pa_11_fp_reg_struct result; + + pa_parse_number (&s, &result); + CHECK_FIELD (result.number_part, 31, 0, 0); + if (the_insn.fpof1 == SGL) + { + if (result.number_part < 16) + { + as_bad (_("Invalid register for single precision fmpyadd or fmpysub")); + break; + } + result.number_part &= 0xF; + result.number_part |= (result.l_r_select & 1) << 4; + } + INSERT_FIELD_AND_CONTINUE (opcode, result.number_part, 6); + } + + /* Handle a floating point operand format at 26. + Only allows single and double precision. */ + case 'H': + flag = pa_parse_fp_format (&s); + switch (flag) + { + case SGL: + opcode |= 0x20; + case DBL: + the_insn.fpof1 = flag; + continue; + + case QUAD: + case ILLEGAL_FMT: + default: + as_bad (_("Invalid Floating Point Operand Format.")); + } + break; + + default: + abort (); + } + break; + } + + failed: + /* Check if the args matched. */ + if (match == FALSE) + { + if (&insn[1] - pa_opcodes < (int) NUMOPCODES + && !strcmp (insn->name, insn[1].name)) + { + ++insn; + s = argstart; + continue; + } + else + { + as_bad (_("Invalid operands %s"), error_message); + return; + } + } + break; + } + + the_insn.opcode = opcode; +} + +/* 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 or NULL is returned. */ + +#define MAX_LITTLENUMS 6 + +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) + { + + 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, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE)); + litP += sizeof (LITTLENUM_TYPE); + } + return NULL; +} + +/* Write out big-endian. */ + +void +md_number_to_chars (buf, val, n) + char *buf; + valueT val; + int n; +{ + number_to_chars_bigendian (buf, val, n); +} + +/* Translate internal representation of relocation info to BFD target + format. */ + +arelent ** +tc_gen_reloc (section, fixp) + asection *section; + fixS *fixp; +{ + arelent *reloc; + struct hppa_fix_struct *hppa_fixp; + bfd_reloc_code_real_type code; + static arelent *no_relocs = NULL; + arelent **relocs; + bfd_reloc_code_real_type **codes; + int n_relocs; + int i; + + hppa_fixp = (struct hppa_fix_struct *) fixp->tc_fix_data; + if (fixp->fx_addsy == 0) + return &no_relocs; + assert (hppa_fixp != 0); + assert (section != 0); + + reloc = (arelent *) xmalloc (sizeof (arelent)); + + reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym; + codes = (bfd_reloc_code_real_type **) hppa_gen_reloc_type (stdoutput, + fixp->fx_r_type, + hppa_fixp->fx_r_format, + hppa_fixp->fx_r_field, + fixp->fx_subsy != NULL, + fixp->fx_addsy->bsym); + + if (codes == NULL) + abort (); + + for (n_relocs = 0; codes[n_relocs]; n_relocs++) + ; + + relocs = (arelent **) xmalloc (sizeof (arelent *) * n_relocs + 1); + reloc = (arelent *) xmalloc (sizeof (arelent) * n_relocs); + for (i = 0; i < n_relocs; i++) + relocs[i] = &reloc[i]; + + relocs[n_relocs] = NULL; + +#ifdef OBJ_ELF + switch (fixp->fx_r_type) + { + default: + assert (n_relocs == 1); + + code = *codes[0]; + + reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym; + reloc->howto = bfd_reloc_type_lookup (stdoutput, code); + reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; + reloc->addend = 0; /* default */ + + assert (reloc->howto && code == reloc->howto->type); + + /* Now, do any processing that is dependent on the relocation type. */ + switch (code) + { + case R_PARISC_DLTREL21L: + case R_PARISC_DLTREL14R: + case R_PARISC_DLTREL14F: + case R_PARISC_PLABEL32: + case R_PARISC_PLABEL21L: + case R_PARISC_PLABEL14R: + /* For plabel relocations, the addend of the + relocation should be either 0 (no static link) or 2 + (static link required). + + FIXME: We always assume no static link! + + We also slam a zero addend into the DLT relative relocs; + it doesn't make a lot of sense to use any addend since + it gets you a different (eg unknown) DLT entry. */ + reloc->addend = 0; + break; + + case R_PARISC_PCREL21L: + case R_PARISC_PCREL17R: + case R_PARISC_PCREL17F: + case R_PARISC_PCREL17C: + case R_PARISC_PCREL14R: + case R_PARISC_PCREL14F: + /* The constant is stored in the instruction. */ + reloc->addend = HPPA_R_ADDEND (hppa_fixp->fx_arg_reloc, 0); + break; + default: + reloc->addend = fixp->fx_offset; + break; + } + break; + } +#else /* OBJ_SOM */ + + /* Walk over reach relocation returned by the BFD backend. */ + for (i = 0; i < n_relocs; i++) + { + code = *codes[i]; + + relocs[i]->sym_ptr_ptr = &fixp->fx_addsy->bsym; + relocs[i]->howto = bfd_reloc_type_lookup (stdoutput, code); + relocs[i]->address = fixp->fx_frag->fr_address + fixp->fx_where; + + switch (code) + { + case R_COMP2: + /* The only time we ever use a R_COMP2 fixup is for the difference + of two symbols. With that in mind we fill in all four + relocs now and break out of the loop. */ + assert (i == 1); + relocs[0]->sym_ptr_ptr = (asymbol **) &bfd_abs_symbol; + relocs[0]->howto = bfd_reloc_type_lookup (stdoutput, *codes[0]); + relocs[0]->address = fixp->fx_frag->fr_address + fixp->fx_where; + relocs[0]->addend = 0; + relocs[1]->sym_ptr_ptr = &fixp->fx_addsy->bsym; + relocs[1]->howto = bfd_reloc_type_lookup (stdoutput, *codes[1]); + relocs[1]->address = fixp->fx_frag->fr_address + fixp->fx_where; + relocs[1]->addend = 0; + relocs[2]->sym_ptr_ptr = &fixp->fx_subsy->bsym; + relocs[2]->howto = bfd_reloc_type_lookup (stdoutput, *codes[2]); + relocs[2]->address = fixp->fx_frag->fr_address + fixp->fx_where; + relocs[2]->addend = 0; + relocs[3]->sym_ptr_ptr = (asymbol **) &bfd_abs_symbol; + relocs[3]->howto = bfd_reloc_type_lookup (stdoutput, *codes[3]); + relocs[3]->address = fixp->fx_frag->fr_address + fixp->fx_where; + relocs[3]->addend = 0; + relocs[4]->sym_ptr_ptr = (asymbol **) &bfd_abs_symbol; + relocs[4]->howto = bfd_reloc_type_lookup (stdoutput, *codes[4]); + relocs[4]->address = fixp->fx_frag->fr_address + fixp->fx_where; + relocs[4]->addend = 0; + goto done; + case R_PCREL_CALL: + case R_ABS_CALL: + relocs[i]->addend = HPPA_R_ADDEND (hppa_fixp->fx_arg_reloc, 0); + break; + + case R_DLT_REL: + case R_DATA_PLABEL: + case R_CODE_PLABEL: + /* For plabel relocations, the addend of the + relocation should be either 0 (no static link) or 2 + (static link required). + + FIXME: We always assume no static link! + + We also slam a zero addend into the DLT relative relocs; + it doesn't make a lot of sense to use any addend since + it gets you a different (eg unknown) DLT entry. */ + relocs[i]->addend = 0; + break; + + case R_N_MODE: + case R_S_MODE: + case R_D_MODE: + case R_R_MODE: + case R_FSEL: + case R_LSEL: + case R_RSEL: + case R_BEGIN_BRTAB: + case R_END_BRTAB: + case R_BEGIN_TRY: + case R_N0SEL: + case R_N1SEL: + /* There is no symbol or addend associated with these fixups. */ + relocs[i]->sym_ptr_ptr = &dummy_symbol->bsym; + relocs[i]->addend = 0; + break; + + case R_END_TRY: + case R_ENTRY: + case R_EXIT: + /* There is no symbol associated with these fixups. */ + relocs[i]->sym_ptr_ptr = &dummy_symbol->bsym; + relocs[i]->addend = fixp->fx_offset; + break; + + default: + relocs[i]->addend = fixp->fx_offset; + } + } + + done: +#endif + + return relocs; +} + +/* Process any machine dependent frag types. */ + +void +md_convert_frag (abfd, sec, fragP) + register bfd *abfd; + register asection *sec; + register fragS *fragP; +{ + unsigned int address; + + if (fragP->fr_type == rs_machine_dependent) + { + switch ((int) fragP->fr_subtype) + { + case 0: + fragP->fr_type = rs_fill; + know (fragP->fr_var == 1); + know (fragP->fr_next); + address = fragP->fr_address + fragP->fr_fix; + if (address % fragP->fr_offset) + { + fragP->fr_offset = + fragP->fr_next->fr_address + - fragP->fr_address + - fragP->fr_fix; + } + else + fragP->fr_offset = 0; + break; + } + } +} + +/* Round up a section size to the appropriate boundary. */ + +valueT +md_section_align (segment, size) + asection *segment; + valueT size; +{ + int align = bfd_get_section_alignment (stdoutput, segment); + int align2 = (1 << align) - 1; + + return (size + align2) & ~align2; +} + +/* Return the approximate size of a frag before relaxation has occurred. */ +int +md_estimate_size_before_relax (fragP, segment) + register fragS *fragP; + asection *segment; +{ + int size; + + size = 0; + + while ((fragP->fr_fix + size) % fragP->fr_offset) + size++; + + return size; +} + +CONST char *md_shortopts = ""; +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; +{ + return 0; +} + +void +md_show_usage (stream) + FILE *stream; +{ +} + +/* We have no need to default values of symbols. */ + +symbolS * +md_undefined_symbol (name) + char *name; +{ + return 0; +} + +/* Apply a fixup to an instruction. */ + +int +md_apply_fix (fixP, valp) + fixS *fixP; + valueT *valp; +{ + char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; + struct hppa_fix_struct *hppa_fixP; + long new_val, result = 0; + unsigned int w1, w2, w, resulti; + + hppa_fixP = (struct hppa_fix_struct *) fixP->tc_fix_data; + /* SOM uses R_HPPA_ENTRY and R_HPPA_EXIT relocations which can + never be "applied" (they are just markers). Likewise for + R_HPPA_BEGIN_BRTAB and R_HPPA_END_BRTAB. */ +#ifdef OBJ_SOM + if (fixP->fx_r_type == R_HPPA_ENTRY + || fixP->fx_r_type == R_HPPA_EXIT + || fixP->fx_r_type == R_HPPA_BEGIN_BRTAB + || fixP->fx_r_type == R_HPPA_END_BRTAB + || fixP->fx_r_type == R_HPPA_BEGIN_TRY) + return 1; + + /* Disgusting. We must set fx_offset ourselves -- R_HPPA_END_TRY + fixups are considered not adjustable, which in turn causes + adjust_reloc_syms to not set fx_offset. Ugh. */ + if (fixP->fx_r_type == R_HPPA_END_TRY) + { + fixP->fx_offset = *valp; + return 1; + } +#endif + + /* There should have been an HPPA specific fixup associated + with the GAS fixup. */ + if (hppa_fixP) + { + unsigned long buf_wd = bfd_get_32 (stdoutput, buf); + unsigned char fmt = bfd_hppa_insn2fmt (buf_wd); + + /* If there is a symbol associated with this fixup, then it's something + which will need a SOM relocation (except for some PC-relative relocs). + In such cases we should treat the "val" or "addend" as zero since it + will be added in as needed from fx_offset in tc_gen_reloc. */ + if ((fixP->fx_addsy != NULL + || fixP->fx_r_type == R_HPPA_NONE) +#ifdef OBJ_SOM + && fmt != 32 +#endif + ) + new_val = ((fmt == 12 || fmt == 17) ? 8 : 0); +#ifdef OBJ_SOM + /* These field selectors imply that we do not want an addend. */ + else if (hppa_fixP->fx_r_field == e_psel + || hppa_fixP->fx_r_field == e_rpsel + || hppa_fixP->fx_r_field == e_lpsel + || hppa_fixP->fx_r_field == e_tsel + || hppa_fixP->fx_r_field == e_rtsel + || hppa_fixP->fx_r_field == e_ltsel) + new_val = ((fmt == 12 || fmt == 17) ? 8 : 0); + /* This is truely disgusting. The machine independent code blindly + adds in the value of the symbol being relocated against. Damn! */ + else if (fmt == 32 + && fixP->fx_addsy != NULL + && S_GET_SEGMENT (fixP->fx_addsy) != bfd_com_section_ptr) + new_val = hppa_field_adjust (*valp - S_GET_VALUE (fixP->fx_addsy), + 0, hppa_fixP->fx_r_field); +#endif + else + new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field); + + /* Handle pc-relative exceptions from above. */ +#define arg_reloc_stub_needed(CALLER, CALLEE) \ + ((CALLEE) && (CALLER) && ((CALLEE) != (CALLER))) + if ((fmt == 12 || fmt == 17) + && fixP->fx_addsy + && fixP->fx_pcrel + && !arg_reloc_stub_needed ((long) ((obj_symbol_type *) + fixP->fx_addsy->bsym)->tc_data.ap.hppa_arg_reloc, + hppa_fixP->fx_arg_reloc) + && ((int)(*valp) > -262144 && (int)(*valp) < 262143) + && S_GET_SEGMENT (fixP->fx_addsy) == hppa_fixP->segment + && !(fixP->fx_subsy + && S_GET_SEGMENT (fixP->fx_subsy) != hppa_fixP->segment)) + + new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field); +#undef arg_reloc_stub_needed + + switch (fmt) + { + /* Handle all opcodes with the 'j' operand type. */ + case 14: + CHECK_FIELD (new_val, 8191, -8192, 0); + + /* Mask off 14 bits to be changed. */ + bfd_put_32 (stdoutput, + bfd_get_32 (stdoutput, buf) & 0xffffc000, + buf); + low_sign_unext (new_val, 14, &resulti); + result = resulti; + break; + + /* Handle all opcodes with the 'k' operand type. */ + case 21: + CHECK_FIELD (new_val, 2097152, 0, 0); + + /* Mask off 21 bits to be changed. */ + bfd_put_32 (stdoutput, + bfd_get_32 (stdoutput, buf) & 0xffe00000, + buf); + dis_assemble_21 (new_val, &resulti); + result = resulti; + break; + + /* Handle all the opcodes with the 'i' operand type. */ + case 11: + CHECK_FIELD (new_val, 1023, -1023, 0); + + /* Mask off 11 bits to be changed. */ + bfd_put_32 (stdoutput, + bfd_get_32 (stdoutput, buf) & 0xffff800, + buf); + low_sign_unext (new_val, 11, &resulti); + result = resulti; + break; + + /* Handle all the opcodes with the 'w' operand type. */ + case 12: + CHECK_FIELD (new_val, 8199, -8184, 0); + + /* Mask off 11 bits to be changed. */ + sign_unext ((new_val - 8) >> 2, 12, &resulti); + bfd_put_32 (stdoutput, + bfd_get_32 (stdoutput, buf) & 0xffffe002, + buf); + + dis_assemble_12 (resulti, &w1, &w); + result = ((w1 << 2) | w); + break; + + /* Handle some of the opcodes with the 'W' operand type. */ + case 17: + { + int distance = *valp; + + CHECK_FIELD (new_val, 262143, -262144, 0); + + /* If this is an absolute branch (ie no link) with an out of + range target, then we want to complain. */ + if (fixP->fx_r_type == R_HPPA_PCREL_CALL + && (distance > 262143 || distance < -262144) + && (bfd_get_32 (stdoutput, buf) & 0xffe00000) == 0xe8000000) + CHECK_FIELD (distance, 262143, -262144, 0); + + /* Mask off 17 bits to be changed. */ + bfd_put_32 (stdoutput, + bfd_get_32 (stdoutput, buf) & 0xffe0e002, + buf); + sign_unext ((new_val - 8) >> 2, 17, &resulti); + dis_assemble_17 (resulti, &w1, &w2, &w); + result = ((w2 << 2) | (w1 << 16) | w); + break; + } + + case 32: + result = 0; + bfd_put_32 (stdoutput, new_val, buf); + break; + + default: + as_bad (_("Unknown relocation encountered in md_apply_fix.")); + return 0; + } + + /* Insert the relocation. */ + bfd_put_32 (stdoutput, bfd_get_32 (stdoutput, buf) | result, buf); + return 1; + } + else + { + printf (_("no hppa_fixup entry for this fixup (fixP = 0x%x, type = 0x%x)\n"), + (unsigned int) fixP, fixP->fx_r_type); + return 0; + } +} + +/* Exactly what point is a PC-relative offset relative TO? + On the PA, they're relative to the address of the offset. */ + +long +md_pcrel_from (fixP) + fixS *fixP; +{ + return fixP->fx_where + fixP->fx_frag->fr_address; +} + +/* Return nonzero if the input line pointer is at the end of + a statement. */ + +static int +is_end_of_statement () +{ + return ((*input_line_pointer == '\n') + || (*input_line_pointer == ';') + || (*input_line_pointer == '!')); +} + +/* Read a number from S. The number might come in one of many forms, + the most common will be a hex or decimal constant, but it could be + a pre-defined register (Yuk!), or an absolute symbol. + + Return a number or -1 for failure. + + When parsing PA-89 FP register numbers RESULT will be + the address of a structure to return information about + L/R half of FP registers, store results there as appropriate. + + pa_parse_number can not handle negative constants and will fail + horribly if it is passed such a constant. */ + +static int +pa_parse_number (s, result) + char **s; + struct pa_11_fp_reg_struct *result; +{ + int num; + char *name; + char c; + symbolS *sym; + int status; + char *p = *s; + + /* Skip whitespace before the number. */ + while (*p == ' ' || *p == '\t') + p = p + 1; + + /* Store info in RESULT if requested by caller. */ + if (result) + { + result->number_part = -1; + result->l_r_select = -1; + } + num = -1; + + if (isdigit (*p)) + { + /* Looks like a number. */ + num = 0; + + if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) + { + /* The number is specified in hex. */ + p += 2; + while (isdigit (*p) || ((*p >= 'a') && (*p <= 'f')) + || ((*p >= 'A') && (*p <= 'F'))) + { + if (isdigit (*p)) + num = num * 16 + *p - '0'; + else if (*p >= 'a' && *p <= 'f') + num = num * 16 + *p - 'a' + 10; + else + num = num * 16 + *p - 'A' + 10; + ++p; + } + } + else + { + /* The number is specified in decimal. */ + while (isdigit (*p)) + { + num = num * 10 + *p - '0'; + ++p; + } + } + + /* Store info in RESULT if requested by the caller. */ + if (result) + { + result->number_part = num; + + if (IS_R_SELECT (p)) + { + result->l_r_select = 1; + ++p; + } + else if (IS_L_SELECT (p)) + { + result->l_r_select = 0; + ++p; + } + else + result->l_r_select = 0; + } + } + else if (*p == '%') + { + /* The number might be a predefined register. */ + num = 0; + name = p; + p++; + c = *p; + /* Tege hack: Special case for general registers as the general + code makes a binary search with case translation, and is VERY + slow. */ + if (c == 'r') + { + p++; + if (*p == 'e' && *(p + 1) == 't' + && (*(p + 2) == '0' || *(p + 2) == '1')) + { + p += 2; + num = *p - '0' + 28; + p++; + } + else if (*p == 'p') + { + num = 2; + p++; + } + else if (!isdigit (*p)) + { + if (print_errors) + as_bad (_("Undefined register: '%s'."), name); + num = -1; + } + else + { + do + num = num * 10 + *p++ - '0'; + while (isdigit (*p)); + } + } + else + { + /* Do a normal register search. */ + while (is_part_of_name (c)) + { + p = p + 1; + c = *p; + } + *p = 0; + status = reg_name_search (name); + if (status >= 0) + num = status; + else + { + if (print_errors) + as_bad (_("Undefined register: '%s'."), name); + num = -1; + } + *p = c; + } + + /* Store info in RESULT if requested by caller. */ + if (result) + { + result->number_part = num; + if (IS_R_SELECT (p - 1)) + result->l_r_select = 1; + else if (IS_L_SELECT (p - 1)) + result->l_r_select = 0; + else + result->l_r_select = 0; + } + } + else + { + /* And finally, it could be a symbol in the absolute section which + is effectively a constant. */ + num = 0; + name = p; + c = *p; + while (is_part_of_name (c)) + { + p = p + 1; + c = *p; + } + *p = 0; + if ((sym = symbol_find (name)) != NULL) + { + if (S_GET_SEGMENT (sym) == &bfd_abs_section) + num = S_GET_VALUE (sym); + else + { + if (print_errors) + as_bad (_("Non-absolute symbol: '%s'."), name); + num = -1; + } + } + else + { + /* There is where we'd come for an undefined symbol + or for an empty string. For an empty string we + will return zero. That's a concession made for + compatability with the braindamaged HP assemblers. */ + if (*name == 0) + num = 0; + else + { + if (print_errors) + as_bad (_("Undefined absolute constant: '%s'."), name); + num = -1; + } + } + *p = c; + + /* Store info in RESULT if requested by caller. */ + if (result) + { + result->number_part = num; + if (IS_R_SELECT (p - 1)) + result->l_r_select = 1; + else if (IS_L_SELECT (p - 1)) + result->l_r_select = 0; + else + result->l_r_select = 0; + } + } + + *s = p; + return num; +} + +#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 (name) + char *name; +{ + int middle, low, high; + int cmp; + + low = 0; + high = REG_NAME_CNT - 1; + + do + { + middle = (low + high) / 2; + cmp = strcasecmp (name, pre_defined_registers[middle].name); + if (cmp < 0) + high = middle - 1; + else if (cmp > 0) + low = middle + 1; + else + return pre_defined_registers[middle].value; + } + while (low <= high); + + return -1; +} + + +/* Return nonzero if the given INSN and L/R information will require + a new PA-1.1 opcode. */ + +static int +need_pa11_opcode (insn, result) + struct pa_it *insn; + struct pa_11_fp_reg_struct *result; +{ + if (result->l_r_select == 1 && !(insn->fpof1 == DBL && insn->fpof2 == DBL)) + { + /* If this instruction is specific to a particular architecture, + then set a new architecture. */ + if (bfd_get_mach (stdoutput) < pa11) + { + if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, pa11)) + as_warn (_("could not update architecture and machine")); + } + return TRUE; + } + else + return FALSE; +} + +/* Parse a condition for a fcmp instruction. Return the numerical + code associated with the condition. */ + +static int +pa_parse_fp_cmp_cond (s) + char **s; +{ + int cond, i; + + cond = 0; + + for (i = 0; i < 32; i++) + { + if (strncasecmp (*s, fp_cond_map[i].string, + strlen (fp_cond_map[i].string)) == 0) + { + cond = fp_cond_map[i].cond; + *s += strlen (fp_cond_map[i].string); + /* If not a complete match, back up the input string and + report an error. */ + if (**s != ' ' && **s != '\t') + { + *s -= strlen (fp_cond_map[i].string); + break; + } + while (**s == ' ' || **s == '\t') + *s = *s + 1; + return cond; + } + } + + as_bad (_("Invalid FP Compare Condition: %s"), *s); + + /* Advance over the bogus completer. */ + while (**s != ',' && **s != ' ' && **s != '\t') + *s += 1; + + return 0; +} + + +/* Parse an FP operand format completer returning the completer + type. */ + +static fp_operand_format +pa_parse_fp_format (s) + char **s; +{ + int format; + + format = SGL; + if (**s == ',') + { + *s += 1; + if (strncasecmp (*s, "sgl", 3) == 0) + { + format = SGL; + *s += 4; + } + else if (strncasecmp (*s, "dbl", 3) == 0) + { + format = DBL; + *s += 4; + } + else if (strncasecmp (*s, "quad", 4) == 0) + { + format = QUAD; + *s += 5; + } + else + { + format = ILLEGAL_FMT; + as_bad (_("Invalid FP Operand Format: %3s"), *s); + } + } + + return format; +} + +/* Convert from a selector string into a selector type. */ + +static int +pa_chk_field_selector (str) + char **str; +{ + int middle, low, high; + int cmp; + char name[4]; + + /* Read past any whitespace. */ + /* FIXME: should we read past newlines and formfeeds??? */ + while (**str == ' ' || **str == '\t' || **str == '\n' || **str == '\f') + *str = *str + 1; + + if ((*str)[1] == '\'' || (*str)[1] == '%') + name[0] = tolower ((*str)[0]), + name[1] = 0; + else if ((*str)[2] == '\'' || (*str)[2] == '%') + name[0] = tolower ((*str)[0]), + name[1] = tolower ((*str)[1]), + name[2] = 0; +#ifdef OBJ_SOM + else if ((*str)[3] == '\'' || (*str)[3] == '%') + name[0] = tolower ((*str)[0]), + name[1] = tolower ((*str)[1]), + name[2] = tolower ((*str)[2]), + name[3] = 0; +#endif + else + return e_fsel; + + low = 0; + high = sizeof (selector_table) / sizeof (struct selector_entry) - 1; + + do + { + middle = (low + high) / 2; + cmp = strcmp (name, selector_table[middle].prefix); + if (cmp < 0) + high = middle - 1; + else if (cmp > 0) + low = middle + 1; + else + { + *str += strlen (name) + 1; +#ifndef OBJ_SOM + if (selector_table[middle].field_selector == e_nsel) + return e_fsel; +#endif + return selector_table[middle].field_selector; + } + } + while (low <= high); + + return e_fsel; +} + +/* Mark (via expr_end) the end of an expression (I think). FIXME. */ + +static int +get_expression (str) + char *str; +{ + char *save_in; + asection *seg; + + save_in = input_line_pointer; + input_line_pointer = str; + seg = expression (&the_insn.exp); + if (!(seg == absolute_section + || seg == undefined_section + || SEG_NORMAL (seg))) + { + as_warn (_("Bad segment in expression.")); + expr_end = input_line_pointer; + input_line_pointer = save_in; + return 1; + } + expr_end = input_line_pointer; + input_line_pointer = save_in; + return 0; +} + +/* Mark (via expr_end) the end of an absolute expression. FIXME. */ +static int +pa_get_absolute_expression (insn, strp) + struct pa_it *insn; + char **strp; +{ + char *save_in; + + insn->field_selector = pa_chk_field_selector (strp); + save_in = input_line_pointer; + input_line_pointer = *strp; + expression (&insn->exp); + /* This is not perfect, but is a huge improvement over doing nothing. + + The PA assembly syntax is ambigious in a variety of ways. Consider + this string "4 %r5" Is that the number 4 followed by the register + r5, or is that 4 MOD 5? + + If we get a modulo expresion When looking for an absolute, we try + again cutting off the input string at the first whitespace character. */ + if (insn->exp.X_op == O_modulus) + { + char *s, c; + int retval; + + input_line_pointer = *strp; + s = *strp; + while (*s != ',' && *s != ' ' && *s != '\t') + s++; + + c = *s; + *s = 0; + + retval = pa_get_absolute_expression (insn, strp); + + input_line_pointer = save_in; + *s = c; + return evaluate_absolute (insn); + } + if (insn->exp.X_op != O_constant) + { + as_bad (_("Bad segment (should be absolute).")); + expr_end = input_line_pointer; + input_line_pointer = save_in; + return 0; + } + expr_end = input_line_pointer; + input_line_pointer = save_in; + return evaluate_absolute (insn); +} + +/* Evaluate an absolute expression EXP which may be modified by + the selector FIELD_SELECTOR. Return the value of the expression. */ +static int +evaluate_absolute (insn) + struct pa_it *insn; +{ + int value; + expressionS exp; + int field_selector = insn->field_selector; + + exp = insn->exp; + value = exp.X_add_number; + + switch (field_selector) + { + /* No change. */ + case e_fsel: + break; + + /* If bit 21 is on then add 0x800 and arithmetic shift right 11 bits. */ + case e_lssel: + if (value & 0x00000400) + value += 0x800; + value = (value & 0xfffff800) >> 11; + break; + + /* Sign extend from bit 21. */ + case e_rssel: + if (value & 0x00000400) + value |= 0xfffff800; + else + value &= 0x7ff; + break; + + /* Arithmetic shift right 11 bits. */ + case e_lsel: + value = (value & 0xfffff800) >> 11; + break; + + /* Set bits 0-20 to zero. */ + case e_rsel: + value = value & 0x7ff; + break; + + /* Add 0x800 and arithmetic shift right 11 bits. */ + case e_ldsel: + value += 0x800; + value = (value & 0xfffff800) >> 11; + break; + + /* Set bitgs 0-21 to one. */ + case e_rdsel: + value |= 0xfffff800; + break; + +#define RSEL_ROUND(c) (((c) + 0x1000) & ~0x1fff) + case e_rrsel: + value = (RSEL_ROUND (value) & 0x7ff) + (value - RSEL_ROUND (value)); + break; + + case e_lrsel: + value = (RSEL_ROUND (value) >> 11) & 0x1fffff; + break; +#undef RSEL_ROUND + + default: + BAD_CASE (field_selector); + break; + } + return value; +} + +/* Given an argument location specification return the associated + argument location number. */ + +static unsigned int +pa_build_arg_reloc (type_name) + char *type_name; +{ + + if (strncasecmp (type_name, "no", 2) == 0) + return 0; + if (strncasecmp (type_name, "gr", 2) == 0) + return 1; + else if (strncasecmp (type_name, "fr", 2) == 0) + return 2; + else if (strncasecmp (type_name, "fu", 2) == 0) + return 3; + else + as_bad (_("Invalid argument location: %s\n"), type_name); + + return 0; +} + +/* Encode and return an argument relocation specification for + the given register in the location specified by arg_reloc. */ + +static unsigned int +pa_align_arg_reloc (reg, arg_reloc) + unsigned int reg; + unsigned int arg_reloc; +{ + unsigned int new_reloc; + + new_reloc = arg_reloc; + switch (reg) + { + case 0: + new_reloc <<= 8; + break; + case 1: + new_reloc <<= 6; + break; + case 2: + new_reloc <<= 4; + break; + case 3: + new_reloc <<= 2; + break; + default: + as_bad (_("Invalid argument description: %d"), reg); + } + + return new_reloc; +} + +/* Parse a PA nullification completer (,n). Return nonzero if the + completer was found; return zero if no completer was found. */ + +static int +pa_parse_nullif (s) + char **s; +{ + int nullif; + + nullif = 0; + if (**s == ',') + { + *s = *s + 1; + if (strncasecmp (*s, "n", 1) == 0) + nullif = 1; + else + { + as_bad (_("Invalid Nullification: (%c)"), **s); + nullif = 0; + } + *s = *s + 1; + } + + return nullif; +} + +/* Parse a non-negated compare/subtract completer returning the + number (for encoding in instrutions) of the given completer. + + ISBRANCH specifies whether or not this is parsing a condition + completer for a branch (vs a nullification completer for a + computational instruction. */ + +static int +pa_parse_nonneg_cmpsub_cmpltr (s, isbranch) + char **s; + int isbranch; +{ + int cmpltr; + char *name = *s + 1; + char c; + char *save_s = *s; + int nullify = 0; + + cmpltr = 0; + if (**s == ',') + { + *s += 1; + while (**s != ',' && **s != ' ' && **s != '\t') + *s += 1; + c = **s; + **s = 0x00; + + + if (strcmp (name, "=") == 0) + { + cmpltr = 1; + } + else if (strcmp (name, "<") == 0) + { + cmpltr = 2; + } + else if (strcmp (name, "<=") == 0) + { + cmpltr = 3; + } + else if (strcmp (name, "<<") == 0) + { + cmpltr = 4; + } + else if (strcmp (name, "<<=") == 0) + { + cmpltr = 5; + } + else if (strcasecmp (name, "sv") == 0) + { + cmpltr = 6; + } + else if (strcasecmp (name, "od") == 0) + { + cmpltr = 7; + } + /* If we have something like addb,n then there is no condition + completer. */ + else if (strcasecmp (name, "n") == 0 && isbranch) + { + cmpltr = 0; + nullify = 1; + } + else + { + cmpltr = -1; + } + **s = c; + } + + /* Reset pointers if this was really a ,n for a branch instruction. */ + if (nullify) + *s = save_s; + + + return cmpltr; +} + +/* Parse a negated compare/subtract completer returning the + number (for encoding in instrutions) of the given completer. + + ISBRANCH specifies whether or not this is parsing a condition + completer for a branch (vs a nullification completer for a + computational instruction. */ + +static int +pa_parse_neg_cmpsub_cmpltr (s, isbranch) + char **s; + int isbranch; +{ + int cmpltr; + char *name = *s + 1; + char c; + char *save_s = *s; + int nullify = 0; + + cmpltr = 0; + if (**s == ',') + { + *s += 1; + while (**s != ',' && **s != ' ' && **s != '\t') + *s += 1; + c = **s; + **s = 0x00; + + + if (strcasecmp (name, "tr") == 0) + { + cmpltr = 0; + } + else if (strcmp (name, "<>") == 0) + { + cmpltr = 1; + } + else if (strcmp (name, ">=") == 0) + { + cmpltr = 2; + } + else if (strcmp (name, ">") == 0) + { + cmpltr = 3; + } + else if (strcmp (name, ">>=") == 0) + { + cmpltr = 4; + } + else if (strcmp (name, ">>") == 0) + { + cmpltr = 5; + } + else if (strcasecmp (name, "nsv") == 0) + { + cmpltr = 6; + } + else if (strcasecmp (name, "ev") == 0) + { + cmpltr = 7; + } + /* If we have something like addb,n then there is no condition + completer. */ + else if (strcasecmp (name, "n") == 0 && isbranch) + { + cmpltr = 0; + nullify = 1; + } + else + { + cmpltr = -1; + } + **s = c; + } + + /* Reset pointers if this was really a ,n for a branch instruction. */ + if (nullify) + *s = save_s; + + + return cmpltr; +} + + +/* Parse a non-negated addition completer returning the number + (for encoding in instrutions) of the given completer. + + ISBRANCH specifies whether or not this is parsing a condition + completer for a branch (vs a nullification completer for a + computational instruction. */ + +static int +pa_parse_nonneg_add_cmpltr (s, isbranch) + char **s; + int isbranch; +{ + int cmpltr; + char *name = *s + 1; + char c; + char *save_s = *s; + + cmpltr = 0; + if (**s == ',') + { + *s += 1; + while (**s != ',' && **s != ' ' && **s != '\t') + *s += 1; + c = **s; + **s = 0x00; + if (strcmp (name, "=") == 0) + { + cmpltr = 1; + } + else if (strcmp (name, "<") == 0) + { + cmpltr = 2; + } + else if (strcmp (name, "<=") == 0) + { + cmpltr = 3; + } + else if (strcasecmp (name, "nuv") == 0) + { + cmpltr = 4; + } + else if (strcasecmp (name, "znv") == 0) + { + cmpltr = 5; + } + else if (strcasecmp (name, "sv") == 0) + { + cmpltr = 6; + } + else if (strcasecmp (name, "od") == 0) + { + cmpltr = 7; + } + /* If we have something like addb,n then there is no condition + completer. */ + else if (strcasecmp (name, "n") == 0 && isbranch) + { + cmpltr = 0; + } + else + { + cmpltr = -1; + } + **s = c; + } + + /* Reset pointers if this was really a ,n for a branch instruction. */ + if (cmpltr == 0 && *name == 'n' && isbranch) + *s = save_s; + + return cmpltr; +} + +/* Parse a negated addition completer returning the number + (for encoding in instrutions) of the given completer. + + ISBRANCH specifies whether or not this is parsing a condition + completer for a branch (vs a nullification completer for a + computational instruction). */ + +static int +pa_parse_neg_add_cmpltr (s, isbranch) + char **s; + int isbranch; +{ + int cmpltr; + char *name = *s + 1; + char c; + char *save_s = *s; + + cmpltr = 0; + if (**s == ',') + { + *s += 1; + while (**s != ',' && **s != ' ' && **s != '\t') + *s += 1; + c = **s; + **s = 0x00; + if (strcasecmp (name, "tr") == 0) + { + cmpltr = 0; + } + else if (strcmp (name, "<>") == 0) + { + cmpltr = 1; + } + else if (strcmp (name, ">=") == 0) + { + cmpltr = 2; + } + else if (strcmp (name, ">") == 0) + { + cmpltr = 3; + } + else if (strcasecmp (name, "uv") == 0) + { + cmpltr = 4; + } + else if (strcasecmp (name, "vnz") == 0) + { + cmpltr = 5; + } + else if (strcasecmp (name, "nsv") == 0) + { + cmpltr = 6; + } + else if (strcasecmp (name, "ev") == 0) + { + cmpltr = 7; + } + /* If we have something like addb,n then there is no condition + completer. */ + else if (strcasecmp (name, "n") == 0 && isbranch) + { + cmpltr = 0; + } + else + { + cmpltr = -1; + } + **s = c; + } + + /* Reset pointers if this was really a ,n for a branch instruction. */ + if (cmpltr == 0 && *name == 'n' && isbranch) + *s = save_s; + + return cmpltr; +} + +/* Handle an alignment directive. Special so that we can update the + alignment of the subspace if necessary. */ +static void +pa_align (bytes) +{ + /* We must have a valid space and subspace. */ + pa_check_current_space_and_subspace (); + + /* Let the generic gas code do most of the work. */ + s_align_bytes (bytes); + + /* If bytes is a power of 2, then update the current subspace's + alignment if necessary. */ + if (log2 (bytes) != -1) + record_alignment (current_subspace->ssd_seg, log2 (bytes)); +} + +/* Handle a .BLOCK type pseudo-op. */ + +static void +pa_block (z) + int z; +{ + char *p; + long int temp_fill; + unsigned int temp_size; + unsigned int i; + + /* We must have a valid space and subspace. */ + pa_check_current_space_and_subspace (); + + temp_size = get_absolute_expression (); + + /* Always fill with zeros, that's what the HP assembler does. */ + temp_fill = 0; + + p = frag_var (rs_fill, (int) temp_size, (int) temp_size, + (relax_substateT) 0, (symbolS *) 0, (offsetT) 1, NULL); + memset (p, 0, temp_size); + + /* Convert 2 bytes at a time. */ + + for (i = 0; i < temp_size; i += 2) + { + md_number_to_chars (p + i, + (valueT) temp_fill, + (int) ((temp_size - i) > 2 ? 2 : (temp_size - i))); + } + + pa_undefine_label (); + demand_empty_rest_of_line (); +} + +/* Handle a .begin_brtab and .end_brtab pseudo-op. */ + +static void +pa_brtab (begin) + int begin; +{ + +#ifdef OBJ_SOM + /* The BRTAB relocations are only availble in SOM (to denote + the beginning and end of branch tables). */ + char *where = frag_more (0); + + fix_new_hppa (frag_now, where - frag_now->fr_literal, 0, + NULL, (offsetT) 0, NULL, + 0, begin ? R_HPPA_BEGIN_BRTAB : R_HPPA_END_BRTAB, + e_fsel, 0, 0, NULL); +#endif + + demand_empty_rest_of_line (); +} + +/* Handle a .begin_try and .end_try pseudo-op. */ + +static void +pa_try (begin) + int begin; +{ +#ifdef OBJ_SOM + expressionS exp; + char *where = frag_more (0); + + if (! begin) + expression (&exp); + + /* The TRY relocations are only availble in SOM (to denote + the beginning and end of exception handling regions). */ + + fix_new_hppa (frag_now, where - frag_now->fr_literal, 0, + NULL, (offsetT) 0, begin ? NULL : &exp, + 0, begin ? R_HPPA_BEGIN_TRY : R_HPPA_END_TRY, + e_fsel, 0, 0, NULL); +#endif + + demand_empty_rest_of_line (); +} + +/* Handle a .CALL pseudo-op. This involves storing away information + about where arguments are to be found so the linker can detect + (and correct) argument location mismatches between caller and callee. */ + +static void +pa_call (unused) + int unused; +{ + /* We must have a valid space and subspace. */ + pa_check_current_space_and_subspace (); + + pa_call_args (&last_call_desc); + demand_empty_rest_of_line (); +} + +/* Do the dirty work of building a call descriptor which describes + where the caller placed arguments to a function call. */ + +static void +pa_call_args (call_desc) + struct call_desc *call_desc; +{ + char *name, c, *p; + unsigned int temp, arg_reloc; + + while (!is_end_of_statement ()) + { + name = input_line_pointer; + c = get_symbol_end (); + /* Process a source argument. */ + if ((strncasecmp (name, "argw", 4) == 0)) + { + temp = atoi (name + 4); + p = input_line_pointer; + *p = c; + input_line_pointer++; + name = input_line_pointer; + c = get_symbol_end (); + arg_reloc = pa_build_arg_reloc (name); + call_desc->arg_reloc |= pa_align_arg_reloc (temp, arg_reloc); + } + /* Process a return value. */ + else if ((strncasecmp (name, "rtnval", 6) == 0)) + { + p = input_line_pointer; + *p = c; + input_line_pointer++; + name = input_line_pointer; + c = get_symbol_end (); + arg_reloc = pa_build_arg_reloc (name); + call_desc->arg_reloc |= (arg_reloc & 0x3); + } + else + { + as_bad (_("Invalid .CALL argument: %s"), name); + } + p = input_line_pointer; + *p = c; + if (!is_end_of_statement ()) + input_line_pointer++; + } +} + +/* Return TRUE if FRAG1 and FRAG2 are the same. */ + +static int +is_same_frag (frag1, frag2) + fragS *frag1; + fragS *frag2; +{ + + if (frag1 == NULL) + return (FALSE); + else if (frag2 == NULL) + return (FALSE); + else if (frag1 == frag2) + return (TRUE); + else if (frag2->fr_type == rs_fill && frag2->fr_fix == 0) + return (is_same_frag (frag1, frag2->fr_next)); + else + return (FALSE); +} + +#ifdef OBJ_ELF +/* Build an entry in the UNWIND subspace from the given function + attributes in CALL_INFO. This is not needed for SOM as using + R_ENTRY and R_EXIT relocations allow the linker to handle building + of the unwind spaces. */ + +static void +pa_build_unwind_subspace (call_info) + struct call_info *call_info; +{ + char *unwind; + asection *seg, *save_seg; + subsegT subseg, save_subseg; + int i; + char c, *p; + + /* Get into the right seg/subseg. This may involve creating + the seg the first time through. Make sure to have the + old seg/subseg so that we can reset things when we are done. */ + subseg = SUBSEG_UNWIND; + seg = bfd_get_section_by_name (stdoutput, UNWIND_SECTION_NAME); + if (seg == ASEC_NULL) + { + seg = bfd_make_section_old_way (stdoutput, UNWIND_SECTION_NAME); + bfd_set_section_flags (stdoutput, seg, + SEC_READONLY | SEC_HAS_CONTENTS + | SEC_LOAD | SEC_RELOC); + } + + save_seg = now_seg; + save_subseg = now_subseg; + subseg_set (seg, subseg); + + + /* Get some space to hold relocation information for the unwind + descriptor. */ + p = frag_more (4); + md_number_to_chars (p, 0, 4); + + /* Relocation info. for start offset of the function. */ + fix_new_hppa (frag_now, p - frag_now->fr_literal, 4, + call_info->start_symbol, (offsetT) 0, + (expressionS *) NULL, 0, R_PARISC_DIR32, e_fsel, 32, 0, NULL); + + p = frag_more (4); + md_number_to_chars (p, 0, 4); + + /* Relocation info. for end offset of the function. + + Because we allow reductions of 32bit relocations for ELF, this will be + reduced to section_sym + offset which avoids putting the temporary + symbol into the symbol table. It (should) end up giving the same + value as call_info->start_symbol + function size once the linker is + finished with its work. */ + + fix_new_hppa (frag_now, p - frag_now->fr_literal, 4, + call_info->end_symbol, (offsetT) 0, + (expressionS *) NULL, 0, R_PARISC_DIR32, e_fsel, 32, 0, NULL); + + /* Dump it. */ + unwind = (char *) &call_info->ci_unwind; + for (i = 8; i < sizeof (struct unwind_table); i++) + { + c = *(unwind + i); + { + FRAG_APPEND_1_CHAR (c); + } + } + + /* Return back to the original segment/subsegment. */ + subseg_set (save_seg, save_subseg); +} +#endif + +/* Process a .CALLINFO pseudo-op. This information is used later + to build unwind descriptors and maybe one day to support + .ENTER and .LEAVE. */ + +static void +pa_callinfo (unused) + int unused; +{ + char *name, c, *p; + int temp; + + /* We must have a valid space and subspace. */ + pa_check_current_space_and_subspace (); + + /* .CALLINFO must appear within a procedure definition. */ + if (!within_procedure) + as_bad (_(".callinfo is not within a procedure definition")); + + /* Mark the fact that we found the .CALLINFO for the + current procedure. */ + callinfo_found = TRUE; + + /* Iterate over the .CALLINFO arguments. */ + while (!is_end_of_statement ()) + { + name = input_line_pointer; + c = get_symbol_end (); + /* Frame size specification. */ + if ((strncasecmp (name, "frame", 5) == 0)) + { + p = input_line_pointer; + *p = c; + input_line_pointer++; + temp = get_absolute_expression (); + if ((temp & 0x3) != 0) + { + as_bad (_("FRAME parameter must be a multiple of 8: %d\n"), temp); + temp = 0; + } + + /* callinfo is in bytes and unwind_desc is in 8 byte units. */ + last_call_info->ci_unwind.descriptor.frame_size = temp / 8; + + } + /* Entry register (GR, GR and SR) specifications. */ + else if ((strncasecmp (name, "entry_gr", 8) == 0)) + { + p = input_line_pointer; + *p = c; + input_line_pointer++; + temp = get_absolute_expression (); + /* The HP assembler accepts 19 as the high bound for ENTRY_GR + even though %r19 is caller saved. I think this is a bug in + the HP assembler, and we are not going to emulate it. */ + if (temp < 3 || temp > 18) + as_bad (_("Value for ENTRY_GR must be in the range 3..18\n")); + last_call_info->ci_unwind.descriptor.entry_gr = temp - 2; + } + else if ((strncasecmp (name, "entry_fr", 8) == 0)) + { + p = input_line_pointer; + *p = c; + input_line_pointer++; + temp = get_absolute_expression (); + /* Similarly the HP assembler takes 31 as the high bound even + though %fr21 is the last callee saved floating point register. */ + if (temp < 12 || temp > 21) + as_bad (_("Value for ENTRY_FR must be in the range 12..21\n")); + last_call_info->ci_unwind.descriptor.entry_fr = temp - 11; + } + else if ((strncasecmp (name, "entry_sr", 8) == 0)) + { + p = input_line_pointer; + *p = c; + input_line_pointer++; + temp = get_absolute_expression (); + if (temp != 3) + as_bad (_("Value for ENTRY_SR must be 3\n")); + } + /* Note whether or not this function performs any calls. */ + else if ((strncasecmp (name, "calls", 5) == 0) || + (strncasecmp (name, "caller", 6) == 0)) + { + p = input_line_pointer; + *p = c; + } + else if ((strncasecmp (name, "no_calls", 8) == 0)) + { + p = input_line_pointer; + *p = c; + } + /* Should RP be saved into the stack. */ + else if ((strncasecmp (name, "save_rp", 7) == 0)) + { + p = input_line_pointer; + *p = c; + last_call_info->ci_unwind.descriptor.save_rp = 1; + } + /* Likewise for SP. */ + else if ((strncasecmp (name, "save_sp", 7) == 0)) + { + p = input_line_pointer; + *p = c; + last_call_info->ci_unwind.descriptor.save_sp = 1; + } + /* Is this an unwindable procedure. If so mark it so + in the unwind descriptor. */ + else if ((strncasecmp (name, "no_unwind", 9) == 0)) + { + p = input_line_pointer; + *p = c; + last_call_info->ci_unwind.descriptor.cannot_unwind = 1; + } + /* Is this an interrupt routine. If so mark it in the + unwind descriptor. */ + else if ((strncasecmp (name, "hpux_int", 7) == 0)) + { + p = input_line_pointer; + *p = c; + last_call_info->ci_unwind.descriptor.hpux_interrupt_marker = 1; + } + /* Is this a millicode routine. "millicode" isn't in my + assembler manual, but my copy is old. The HP assembler + accepts it, and there's a place in the unwind descriptor + to drop the information, so we'll accept it too. */ + else if ((strncasecmp (name, "millicode", 9) == 0)) + { + p = input_line_pointer; + *p = c; + last_call_info->ci_unwind.descriptor.millicode = 1; + } + else + { + as_bad (_("Invalid .CALLINFO argument: %s"), name); + *input_line_pointer = c; + } + if (!is_end_of_statement ()) + input_line_pointer++; + } + + demand_empty_rest_of_line (); +} + +/* Switch into the code subspace. */ + +static void +pa_code (unused) + int unused; +{ + current_space = is_defined_space ("$TEXT$"); + current_subspace + = pa_subsegment_to_subspace (current_space->sd_seg, 0); + s_text (0); + pa_undefine_label (); +} + +/* This is different than the standard GAS s_comm(). On HP9000/800 machines, + the .comm pseudo-op has the following symtax: + +