* elf32-i386.c (elf_i386_copy_indirect_symbol): Swap tls_type
if _bfd_elf_link_hash_copy_indirect will swap got.refcount.
+2002-07-31 Ian Dall <ian@sibyl.beware.dropbear.id.au>
+
+ * cpu-ns32k.c (_bfd_ns32k_put_immdeiate, _bfd_ns32k_get_immediate):
+ There is no 8 byte relocation type for this architecture.
+ (do_ns32k_reloc): Use bfd_vma instead of native types.
+ (bfd_ns32k_put_immediate, _bfd_ns32k_relocate_contents) put_data
+ returns void.
+ (_bfd_ns32k_put_displacement): Don't check for overflow. We can
+ rely on generic code to do that.
+ * aout-ns32k.c (howto_table): Add appropriate overflow detection
+ to all table entries.
+ (_bfd_ns32k_relocate_contents): put_data returns void.
+ * ns32k.h: (_bfd_ns32k_put_displacement, _bfd_ns32k_put_immediate)
+ (_bfd_do_ns32k_reloc_contents): Fix prototypes. put data functions
+ return void.
+
2002-07-31 Ian Dall <ian@sibyl.beware.dropbear.id.au>
* aoutx.h (aout_link_check_ar_symbols): Whether to include an
/* BFD back-end for ns32k a.out-ish binaries.
- Copyright 1990, 1991, 1992, 1994, 1995, 1996, 1998, 2000, 2001
+ Copyright 1990, 1991, 1992, 1994, 1995, 1996, 1998, 2000, 2001, 2002
Free Software Foundation, Inc.
Contributed by Ian Dall (idall@eleceng.adelaide.edu.au).
-This file is part of BFD, the Binary File Descriptor library.
+ This file is part of BFD, the Binary File Descriptor library.
-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 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.
+ 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. */
+ 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. */
#define BYTES_IN_WORD 4
#define MY(OP) MYNS(OP)
-#define MY_swap_std_reloc_in MY(swap_std_reloc_in)
+#define MY_swap_std_reloc_in MY(swap_std_reloc_in)
#define MY_swap_std_reloc_out MY(swap_std_reloc_out)
static void
-MY_swap_std_reloc_in PARAMS ((bfd *abfd, struct reloc_std_external *bytes,
- arelent *cache_ptr, asymbol **symbols,
- bfd_size_type symcount));
+MY_swap_std_reloc_in PARAMS ((bfd *, struct reloc_std_external *,
+ arelent *, asymbol **,
+ bfd_size_type));
static void
-MY_swap_std_reloc_out PARAMS ((bfd *abfd, arelent *g,
- struct reloc_std_external *natptr));
+MY_swap_std_reloc_out PARAMS ((bfd *, arelent *,
+ struct reloc_std_external *));
reloc_howto_type *
MY(reloc_howto) PARAMS ((bfd *, struct reloc_std_external *,
int *, int *, int *));
In addition, for historical reasons the encoding of the relocation types
in the a.out format relocation entries is such that even the relocation
- methods which are standard are not encoded the standard way. */
+ methods which are standard are not encoded the standard way. */
reloc_howto_type MY(howto_table)[] =
{
+ /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
/* ns32k immediate operands. */
- HOWTO (BFD_RELOC_NS32K_IMM_8, 0, 0, 8, false, 0, true,
+ HOWTO (BFD_RELOC_NS32K_IMM_8, 0, 0, 8, false, 0, complain_overflow_signed,
_bfd_ns32k_reloc_imm, "NS32K_IMM_8",
true, 0x000000ff,0x000000ff, false),
- HOWTO (BFD_RELOC_NS32K_IMM_16, 0, 1, 16, false, 0, true,
+ HOWTO (BFD_RELOC_NS32K_IMM_16, 0, 1, 16, false, 0, complain_overflow_signed,
_bfd_ns32k_reloc_imm, "NS32K_IMM_16",
true, 0x0000ffff,0x0000ffff, false),
- HOWTO (BFD_RELOC_NS32K_IMM_32, 0, 2, 32, false, 0, true,
+ HOWTO (BFD_RELOC_NS32K_IMM_32, 0, 2, 32, false, 0, complain_overflow_signed,
_bfd_ns32k_reloc_imm, "NS32K_IMM_32",
true, 0xffffffff,0xffffffff, false),
- HOWTO (BFD_RELOC_NS32K_IMM_8_PCREL, 0, 0, 8, true, 0, false,
+ HOWTO (BFD_RELOC_NS32K_IMM_8_PCREL, 0, 0, 8, true, 0, complain_overflow_signed,
_bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_8",
true, 0x000000ff, 0x000000ff, false),
- HOWTO (BFD_RELOC_NS32K_IMM_16_PCREL, 0, 1, 16, true, 0, false,
+ HOWTO (BFD_RELOC_NS32K_IMM_16_PCREL, 0, 1, 16, true, 0, complain_overflow_signed,
_bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_16",
true, 0x0000ffff,0x0000ffff, false),
- HOWTO (BFD_RELOC_NS32K_IMM_32_PCREL, 0, 2, 32, true, 0, false,
+ HOWTO (BFD_RELOC_NS32K_IMM_32_PCREL, 0, 2, 32, true, 0, complain_overflow_signed,
_bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_32",
true, 0xffffffff,0xffffffff, false),
/* ns32k displacements. */
- HOWTO (BFD_RELOC_NS32K_DISP_8, 0, 0, 8, false, 0, true,
+ HOWTO (BFD_RELOC_NS32K_DISP_8, 0, 0, 7, false, 0, complain_overflow_signed,
_bfd_ns32k_reloc_disp, "NS32K_DISP_8",
true, 0x000000ff,0x000000ff, false),
- HOWTO (BFD_RELOC_NS32K_DISP_16, 0, 1, 16, false, 0, true,
+ HOWTO (BFD_RELOC_NS32K_DISP_16, 0, 1, 14, false, 0, complain_overflow_signed,
_bfd_ns32k_reloc_disp, "NS32K_DISP_16",
true, 0x0000ffff, 0x0000ffff, false),
- HOWTO (BFD_RELOC_NS32K_DISP_32, 0, 2, 32, false, 0, true,
+ HOWTO (BFD_RELOC_NS32K_DISP_32, 0, 2, 30, false, 0, complain_overflow_signed,
_bfd_ns32k_reloc_disp, "NS32K_DISP_32",
true, 0xffffffff, 0xffffffff, false),
- HOWTO (BFD_RELOC_NS32K_DISP_8_PCREL, 0, 0, 8, true, 0, false,
+ HOWTO (BFD_RELOC_NS32K_DISP_8_PCREL, 0, 0, 7, true, 0, complain_overflow_signed,
_bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_8",
true, 0x000000ff,0x000000ff, false),
- HOWTO (BFD_RELOC_NS32K_DISP_16_PCREL, 0, 1, 16, true, 0, false,
+ HOWTO (BFD_RELOC_NS32K_DISP_16_PCREL, 0, 1, 14, true, 0, complain_overflow_signed,
_bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_16",
true, 0x0000ffff,0x0000ffff, false),
- HOWTO (BFD_RELOC_NS32K_DISP_32_PCREL, 0, 2, 32, true, 0, false,
+ HOWTO (BFD_RELOC_NS32K_DISP_32_PCREL, 0, 2, 30, true, 0, complain_overflow_signed,
_bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_32",
true, 0xffffffff,0xffffffff, false),
{
int r_ns32k_type = (howto - MY(howto_table)) / 6;
bfd_vma (*get_data) PARAMS ((bfd_byte *, int));
- int (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
+ void (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
switch (r_ns32k_type)
{
Almost totally rewritten by Ian Dall from initial work
by Andrew Cagney.
-This file is part of BFD, the Binary File Descriptor library.
+ This file is part of BFD, the Binary File Descriptor library.
-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 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.
+ 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. */
+ 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. */
#include "bfd.h"
#include "sysdep.h"
static const bfd_arch_info_type arch_info_struct[] =
{
- N(32532,"ns32k:32532",true, 0), /* the word ns32k will match this too */
+ N(32532,"ns32k:32532",true, 0), /* The word ns32k will match this too. */
};
const bfd_arch_info_type bfd_ns32k_arch =
PARAMS ((bfd *, arelent *, struct symbol_cache_entry *, PTR, asection *,
bfd *, char **,
bfd_vma (*) (bfd_byte *, int),
- int (*) (bfd_vma, bfd_byte *, int)));
+ void (*) (bfd_vma, bfd_byte *, int)));
bfd_vma
_bfd_ns32k_get_displacement (buffer, size)
int size;
{
bfd_signed_vma value;
+
switch (size)
{
case 1:
abort ();
return 0;
}
+
return value;
}
-int
+void
_bfd_ns32k_put_displacement (value, buffer, size)
bfd_vma value;
bfd_byte *buffer;
switch (size)
{
case 1:
- if (value + 0x40 > 0x7f)
- return -1;
value &= 0x7f;
*buffer++ = value;
break;
case 2:
- if (value + 0x2000 > 0x3fff)
- return -1;
value &= 0x3fff;
value |= 0x8000;
*buffer++ = (value >> 8);
break;
case 4:
- /* FIXME: is this correct? -0x1f000000 <= value < 0x2000000 */
- if (value + 0x1f000000 > 0x3effffff)
- return -1;
value |= (bfd_vma) 0xc0000000;
*buffer++ = (value >> 24);
*buffer++ = (value >> 16);
*buffer++ = (value >> 8);
*buffer++ = value;
break;
- default:
- return -1;
}
- return 0;
+ return;
}
bfd_vma
int size;
{
bfd_vma value = 0;
+
switch (size)
{
- case 8:
- value = (value << 8) | (*buffer++ & 0xff);
- value = (value << 8) | (*buffer++ & 0xff);
- value = (value << 8) | (*buffer++ & 0xff);
- value = (value << 8) | (*buffer++ & 0xff);
case 4:
value = (value << 8) | (*buffer++ & 0xff);
value = (value << 8) | (*buffer++ & 0xff);
value = (value << 8) | (*buffer++ & 0xff);
case 1:
value = (value << 8) | (*buffer++ & 0xff);
+ break;
+ default:
+ abort ();
}
return value;
}
-int
+void
_bfd_ns32k_put_immediate (value, buffer, size)
bfd_vma value;
bfd_byte *buffer;
buffer += size - 1;
switch (size)
{
- case 8:
- *buffer-- = (value & 0xff); value >>= 8;
- *buffer-- = (value & 0xff); value >>= 8;
- *buffer-- = (value & 0xff); value >>= 8;
- *buffer-- = (value & 0xff); value >>= 8;
case 4:
*buffer-- = (value & 0xff); value >>= 8;
*buffer-- = (value & 0xff); value >>= 8;
case 1:
*buffer-- = (value & 0xff); value >>= 8;
}
- return 0;
}
/* This is just like the standard perform_relocation except we
- * use get_data and put_data which know about the ns32k
- * storage methods.
- * This is probably a lot more complicated than it needs to be!
- */
+ use get_data and put_data which know about the ns32k storage
+ methods. This is probably a lot more complicated than it
+ needs to be! */
+
static bfd_reloc_status_type
do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
error_message, get_data, put_data)
bfd *output_bfd;
char **error_message ATTRIBUTE_UNUSED;
bfd_vma (*get_data) PARAMS ((bfd_byte *, int));
- int (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
+ void (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
{
int overflow = 0;
bfd_vma relocation;
producing relocateable output it is not what the code
actually does. I don't want to change it, because it seems
far too likely that something will break. */
-
relocation -=
input_section->output_section->vma + input_section->output_offset;
relocation with -r. Removing the line below this comment
fixes that problem; see PR 2953.
-However, Ian wrote the following, regarding removing the line below,
-which explains why it is still enabled: --djm
-
-If you put a patch like that into BFD you need to check all the COFF
-linkers. I am fairly certain that patch will break coff-i386 (e.g.,
-SCO); see coff_i386_reloc in coff-i386.c where I worked around the
-problem in a different way. There may very well be a reason that the
-code works as it does.
-
-Hmmm. The first obvious point is that bfd_perform_relocation should
-not have any tests that depend upon the flavour. It's seem like
-entirely the wrong place for such a thing. The second obvious point
-is that the current code ignores the reloc addend when producing
-relocateable output for COFF. That's peculiar. In fact, I really
-have no idea what the point of the line you want to remove is.
-
-A typical COFF reloc subtracts the old value of the symbol and adds in
-the new value to the location in the object file (if it's a pc
-relative reloc it adds the difference between the symbol value and the
-location). When relocating we need to preserve that property.
-
-BFD handles this by setting the addend to the negative of the old
-value of the symbol. Unfortunately it handles common symbols in a
-non-standard way (it doesn't subtract the old value) but that's a
-different story (we can't change it without losing backward
-compatibility with old object files) (coff-i386 does subtract the old
-value, to be compatible with existing coff-i386 targets, like SCO).
-
-So everything works fine when not producing relocateable output. When
-we are producing relocateable output, logically we should do exactly
-what we do when not producing relocateable output. Therefore, your
-patch is correct. In fact, it should probably always just set
-reloc_entry->addend to 0 for all cases, since it is, in fact, going to
-add the value into the object file. This won't hurt the COFF code,
-which doesn't use the addend; I'm not sure what it will do to other
-formats (the thing to check for would be whether any formats both use
-the addend and set partial_inplace).
-
-When I wanted to make coff-i386 produce relocateable output, I ran
-into the problem that you are running into: I wanted to remove that
-line. Rather than risk it, I made the coff-i386 relocs use a special
-function; it's coff_i386_reloc in coff-i386.c. The function
-specifically adds the addend field into the object file, knowing that
-bfd_perform_relocation is not going to. If you remove that line, then
-coff-i386.c will wind up adding the addend field in twice. It's
-trivial to fix; it just needs to be done.
-
-The problem with removing the line is just that it may break some
-working code. With BFD it's hard to be sure of anything. The right
-way to deal with this is simply to build and test at least all the
-supported COFF targets. It should be straightforward if time and disk
-space consuming. For each target:
- 1) build the linker
- 2) generate some executable, and link it using -r (I would
- probably use paranoia.o and link against newlib/libc.a, which
- for all the supported targets would be available in
- /usr/cygnus/progressive/H-host/target/lib/libc.a).
- 3) make the change to reloc.c
- 4) rebuild the linker
- 5) repeat step 2
- 6) if the resulting object files are the same, you have at least
- made it no worse
- 7) if they are different you have to figure out which version is
- right
-*/
+ However, Ian wrote the following, regarding removing the line
+ below, which explains why it is still enabled: --djm
+
+ If you put a patch like that into BFD you need to check all
+ the COFF linkers. I am fairly certain that patch will break
+ coff-i386 (e.g., SCO); see coff_i386_reloc in coff-i386.c
+ where I worked around the problem in a different way. There
+ may very well be a reason that the code works as it does.
+
+ Hmmm. The first obvious point is that bfd_perform_relocation
+ should not have any tests that depend upon the flavour. It's
+ seem like entirely the wrong place for such a thing. The
+ second obvious point is that the current code ignores the
+ reloc addend when producing relocateable output for COFF.
+ That's peculiar. In fact, I really have no idea what the
+ point of the line you want to remove is.
+
+ A typical COFF reloc subtracts the old value of the symbol
+ and adds in the new value to the location in the object file
+ (if it's a pc relative reloc it adds the difference between
+ the symbol value and the location). When relocating we need
+ to preserve that property.
+
+ BFD handles this by setting the addend to the negative of the
+ old value of the symbol. Unfortunately it handles common
+ symbols in a non-standard way (it doesn't subtract the old
+ value) but that's a different story (we can't change it
+ without losing backward compatibility with old object files)
+ (coff-i386 does subtract the old value, to be compatible with
+ existing coff-i386 targets, like SCO).
+
+ So everything works fine when not producing relocateable
+ output. When we are producing relocateable output, logically
+ we should do exactly what we do when not producing
+ relocateable output. Therefore, your patch is correct. In
+ fact, it should probably always just set reloc_entry->addend
+ to 0 for all cases, since it is, in fact, going to add the
+ value into the object file. This won't hurt the COFF code,
+ which doesn't use the addend; I'm not sure what it will do
+ to other formats (the thing to check for would be whether
+ any formats both use the addend and set partial_inplace).
+
+ When I wanted to make coff-i386 produce relocateable output,
+ I ran into the problem that you are running into: I wanted
+ to remove that line. Rather than risk it, I made the
+ coff-i386 relocs use a special function; it's coff_i386_reloc
+ in coff-i386.c. The function specifically adds the addend
+ field into the object file, knowing that bfd_perform_relocation
+ is not going to. If you remove that line, then coff-i386.c
+ will wind up adding the addend field in twice. It's trivial
+ to fix; it just needs to be done.
+
+ The problem with removing the line is just that it may break
+ some working code. With BFD it's hard to be sure of anything.
+ The right way to deal with this is simply to build and test at
+ least all the supported COFF targets. It should be
+ straightforward if time and disk space consuming. For each
+ target:
+ 1) build the linker
+ 2) generate some executable, and link it using -r (I would
+ probably use paranoia.o and link against newlib/libc.a,
+ which for all the supported targets would be available in
+ /usr/cygnus/progressive/H-host/target/lib/libc.a).
+ 3) make the change to reloc.c
+ 4) rebuild the linker
+ 5) repeat step 2
+ 6) if the resulting object files are the same, you have at
+ least made it no worse
+ 7) if they are different you have to figure out which
+ version is right. */
relocation -= reloc_entry->addend;
#endif
reloc_entry->addend = 0;
}
}
- /*
- Either we are relocating all the way, or we don't want to apply
- the relocation to the reloc entry (probably because there isn't
- any room in the output format to describe addends to relocs)
- */
+ /* Either we are relocating all the way, or we don't want to apply
+ the relocation to the reloc entry (probably because there isn't
+ any room in the output format to describe addends to relocs). */
/* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler
(OSF version 1.3, compiler version 3.11). It miscompiles the
relocation >>= (bfd_vma) howto->rightshift;
- /* Shift everything up to where it's going to be used */
-
+ /* Shift everything up to where it's going to be used. */
relocation <<= (bfd_vma) howto->bitpos;
- /* Wait for the day when all have the mask in them */
+ /* Wait for the day when all have the mask in them. */
/* What we do:
i instruction to be left alone
B B B B B
or A A A A A
-----------------------
- R R R R R R R R R R put into bfd_put<size>
- */
+ R R R R R R R R R R put into bfd_put<size>. */
#define DOIT(x) \
x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
{
case 0:
{
- char x = get_data (location, 1);
+ bfd_vma x = get_data (location, 1);
DOIT (x);
- overflow = put_data ((bfd_vma) x, location, 1);
+ put_data ((bfd_vma) x, location, 1);
}
break;
case 1:
if (relocation)
{
- short x = get_data (location, 2);
+ bfd_vma x = get_data (location, 2);
DOIT (x);
- overflow = put_data ((bfd_vma) x, location, 2);
+ put_data ((bfd_vma) x, location, 2);
}
break;
case 2:
if (relocation)
{
- long x = get_data (location, 4);
+ bfd_vma x = get_data (location, 4);
DOIT (x);
- overflow = put_data ((bfd_vma) x, location, 4);
+ put_data ((bfd_vma) x, location, 4);
}
break;
case -2:
{
- long x = get_data (location, 4);
+ bfd_vma x = get_data (location, 4);
relocation = -relocation;
DOIT(x);
- overflow = put_data ((bfd_vma) x, location, 4);
+ put_data ((bfd_vma) x, location, 4);
}
break;
case 3:
- /* Do nothing */
+ /* Do nothing. */
break;
case 4:
{
bfd_vma x = get_data (location, 8);
DOIT (x);
- overflow = put_data (x, location, 8);
+ put_data (x, location, 8);
}
#else
abort ();
bfd_vma relocation;
bfd_byte *location;
bfd_vma (*get_data) PARAMS ((bfd_byte *, int));
- int (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
+ void (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
{
int size;
bfd_vma x;
/* Header file for ns32k routines.
- Copyright 1996, 2001 Free Software Foundation, Inc.
+ Copyright 1996, 2001, 2002 Free Software Foundation, Inc.
Written by Cygnus Support.
-This file is part of BFD, the Binary File Descriptor library.
+ This file is part of BFD, the Binary File Descriptor library.
-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 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.
+ 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. */
+ 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. */
extern bfd_reloc_status_type _bfd_ns32k_relocate_contents
PARAMS ((reloc_howto_type *, bfd *, bfd_vma, bfd_byte *));
extern bfd_reloc_status_type _bfd_do_ns32k_reloc_contents
PARAMS ((reloc_howto_type *, bfd *, bfd_vma, bfd_byte *,
bfd_vma (*) (bfd_byte *, int),
- int (*) (bfd_vma, bfd_byte *, int)));
+ void (*) (bfd_vma, bfd_byte *, int)));
extern bfd_reloc_status_type _bfd_ns32k_final_link_relocate
PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, bfd_vma,
extern bfd_vma _bfd_ns32k_get_displacement PARAMS ((bfd_byte *, int));
extern bfd_vma _bfd_ns32k_get_immediate PARAMS ((bfd_byte *, int));
-extern int _bfd_ns32k_put_displacement PARAMS ((bfd_vma, bfd_byte *, int));
-extern int _bfd_ns32k_put_immediate PARAMS ((bfd_vma, bfd_byte *, int));
+extern void _bfd_ns32k_put_displacement PARAMS ((bfd_vma, bfd_byte *, int));
+extern void _bfd_ns32k_put_immediate PARAMS ((bfd_vma, bfd_byte *, int));
extern bfd_reloc_status_type _bfd_ns32k_reloc_disp
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+2002-07-31 Ian Dall <ian@sibyl.beware.dropbear.id.au>
+
+ * config/tc-ns32k.h (md_pcrel_adjust): Supply prototype.
+ * config/tc-ns32k.c (convert_iif, md_parse_option, md_show_usage):
+ Allow default displacement size to be an option "--disp-size-default".
+ (md_number_to_disp): Make error messages include value. Use %d to
+ print integers, not %s.
+ (fix_new_ns32k): Conditionally set fx_no_overflow so we don't
+ get duplicate messages sometimes.
+ (convert_iif): Grow frag to max possible instruction size. Avoid
+ creating unnecessary fixes.
+ (md_number_to_field) Add prototype.
+ (encode_operand, parse, convert_iif, md_fix_pcrel_adjust): Add
+ prototypes and make static.
+ (struct addr_mode): Make mode and scaled_mode explicitly signed.
+ (evaluate_expr): Use resultP argument instead of exprP global.
+ (get_addr_mode): Quiten compiler warnings.
+ (encode_operand): eliminate unused variables. Quiten compiler
+ warnings. Eliminate nul character in format strings.
+ (parse): argc is unsigned.
+ (reloc): Type cast index to quieten compiler.
+ (md_pcrel_adjust, md_apply_fix3): Remove unused variable.
+ (md_convert_frag): Note unused parameters. Remove unused
+ variables.
+ (md_create_long_jump, md_create_short_jump,
+ md_undefined_symbol_name, md_section_align, tc_gen_reloc): Note
+ unused parameters.
+
2002-07-31 Nick Clifton <nickc@redhat.com>
* NEWS: Retroactively add entry for Lars Brinkhoff's contribution
const char comment_chars[] = "#";
const char line_comment_chars[] = LINE_COMMENT_CHARS;
const char line_separator_chars[] = ";";
+static int default_disp_size = 4; /* Displacement size for external refs. */
#if !defined(ABSOLUTE_PREFIX) && !defined(IMMEDIATE_PREFIX)
-#define ABSOLUTE_PREFIX '@' /* One or the other MUST be defined */
+#define ABSOLUTE_PREFIX '@' /* One or the other MUST be defined. */
#endif
struct addr_mode
{
- char mode; /* addressing mode of operand (0-31) */
- char scaled_mode; /* mode combined with scaled mode */
- char scaled_reg; /* register used in scaled+1 (1-8) */
- char float_flag; /* set if R0..R7 was F0..F7 ie a
- floating-point-register */
- char am_size; /* estimated max size of general addr-mode
- parts */
- char im_disp; /* if im_disp==1 we have a displacement */
- char pcrel; /* 1 if pcrel, this is really redundant info */
- char disp_suffix[2]; /* length of displacement(s), 0=undefined */
- char *disp[2]; /* pointer(s) at displacement(s)
- or immediates(s) (ascii) */
- char index_byte; /* index byte */
+ signed char mode; /* Addressing mode of operand (0-31). */
+ signed char scaled_mode; /* Mode combined with scaled mode. */
+ char scaled_reg; /* Register used in scaled+1 (1-8). */
+ char float_flag; /* Set if R0..R7 was F0..F7 ie a
+ floating-point-register. */
+ char am_size; /* Estimated max size of general addr-mode
+ parts. */
+ char im_disp; /* If im_disp==1 we have a displacement. */
+ char pcrel; /* 1 if pcrel, this is really redundant info. */
+ char disp_suffix[2]; /* Length of displacement(s), 0=undefined. */
+ char *disp[2]; /* Pointer(s) at displacement(s)
+ or immediates(s) (ascii). */
+ char index_byte; /* Index byte. */
};
typedef struct addr_mode addr_modeS;
do we? */
/* UPPERCASE denotes live names when an instruction is built, IIF is
- * used as an intermediate form to store the actual parts of the
- * instruction. A ns32k machine instruction can be divided into a
- * couple of sub PARTs. When an instruction is assembled the
- * appropriate PART get an assignment. When an IIF has been completed
- * it is converted to a FRAGment as specified in AS.H. */
+ used as an intermediate form to store the actual parts of the
+ instruction. A ns32k machine instruction can be divided into a
+ couple of sub PARTs. When an instruction is assembled the
+ appropriate PART get an assignment. When an IIF has been completed
+ it is converted to a FRAGment as specified in AS.H. */
/* Internal structs. */
struct ns32k_option
typedef struct
{
- int type; /* how to interpret object */
- int size; /* Estimated max size of object */
- unsigned long object; /* binary data */
- int object_adjust; /* number added to object */
- int pcrel; /* True if object is pcrel */
- int pcrel_adjust; /* length in bytes from the
- instruction start to the
- displacement */
- int im_disp; /* True if the object is a displacement */
- relax_substateT relax_substate; /* Initial relaxsubstate */
- bit_fixS *bit_fixP; /* Pointer at bit_fix struct */
+ int type; /* How to interpret object. */
+ int size; /* Estimated max size of object. */
+ unsigned long object; /* Binary data. */
+ int object_adjust; /* Number added to object. */
+ int pcrel; /* True if object is pcrel. */
+ int pcrel_adjust; /* Length in bytes from the instruction
+ start to the displacement. */
+ int im_disp; /* True if the object is a displacement. */
+ relax_substateT relax_substate; /* Initial relaxsubstate. */
+ bit_fixS *bit_fixP; /* Pointer at bit_fix struct. */
int addr_mode; /* What addrmode do we associate with this
- iif-entry */
- char bsr; /* Sequent hack */
- } iif_entryT; /* Internal Instruction Format */
+ iif-entry. */
+ char bsr; /* Sequent hack. */
+ } iif_entryT; /* Internal Instruction Format. */
struct int_ins_form
{
With this representation we simplify the assembly and separates the
machine dependent/independent parts in a more clean way (said OE). */
\f
-struct ns32k_option opt1[] = /* restore, exit */
+struct ns32k_option opt1[] = /* restore, exit. */
{
{"r0", 0x80, 0xff},
{"r1", 0x40, 0xff},
{"r7", 0x01, 0xff},
{0, 0x00, 0xff}
};
-struct ns32k_option opt2[] = /* save, enter */
+struct ns32k_option opt2[] = /* save, enter. */
{
{"r0", 0x01, 0xff},
{"r1", 0x02, 0xff},
{"r7", 0x80, 0xff},
{0, 0x00, 0xff}
};
-struct ns32k_option opt3[] = /* setcfg */
+struct ns32k_option opt3[] = /* setcfg. */
{
{"c", 0x8, 0xff},
{"m", 0x4, 0xff},
{"i", 0x1, 0xff},
{0, 0x0, 0xff}
};
-struct ns32k_option opt4[] = /* cinv */
+struct ns32k_option opt4[] = /* cinv. */
{
{"a", 0x4, 0xff},
{"i", 0x2, 0xff},
{"d", 0x1, 0xff},
{0, 0x0, 0xff}
};
-struct ns32k_option opt5[] = /* string inst */
+struct ns32k_option opt5[] = /* String inst. */
{
{"b", 0x2, 0xff},
{"u", 0xc, 0xff},
{"w", 0x4, 0xff},
{0, 0x0, 0xff}
};
-struct ns32k_option opt6[] = /* plain reg ext,cvtp etc */
+struct ns32k_option opt6[] = /* Plain reg ext,cvtp etc. */
{
{"r0", 0x00, 0xff},
{"r1", 0x01, 0xff},
#define NS32532
#endif
-struct ns32k_option cpureg_532[] = /* lpr spr */
+struct ns32k_option cpureg_532[] = /* lpr spr. */
{
{"us", 0x0, 0xff},
{"dcr", 0x1, 0xff},
{"mod", 0xf, 0xff},
{0, 0x00, 0xff}
};
-struct ns32k_option mmureg_532[] = /* lmr smr */
+struct ns32k_option mmureg_532[] = /* lmr smr. */
{
{"mcr", 0x9, 0xff},
{"msr", 0xa, 0xff},
{0, 0x0, 0xff}
};
-struct ns32k_option cpureg_032[] = /* lpr spr */
+struct ns32k_option cpureg_032[] = /* lpr spr. */
{
{"upsr", 0x0, 0xff},
{"fp", 0x8, 0xff},
{"mod", 0xf, 0xff},
{0, 0x0, 0xff}
};
-struct ns32k_option mmureg_032[] = /* lmr smr */
+struct ns32k_option mmureg_032[] = /* lmr smr. */
{
{"bpr0", 0x0, 0xff},
{"bpr1", 0x1, 0xff},
char disp_size[] =
{4, 1, 2, 0, 4};
\f
-static void evaluate_expr PARAMS ((expressionS * resultP, char *ptr));
-static void md_number_to_disp PARAMS ((char *buf, long val, int n));
-static void md_number_to_imm PARAMS ((char *buf, long val, int n));
+static void evaluate_expr PARAMS ((expressionS * resultP, char *));
+static void md_number_to_disp PARAMS ((char *, long, int));
+static void md_number_to_imm PARAMS ((char *, long, int));
+static void md_number_to_field PARAMS ((char *, long, bit_fixS *));
/* Parse a general operand into an addressingmode struct
Out: data in addr_mode struct. */
-int
+static int addr_mode PARAMS ((char *, addr_modeS *, int));
+
+static int
addr_mode (operand, addr_modeP, recursive_level)
char *operand;
- register addr_modeS *addr_modeP;
+ addr_modeS *addr_modeP;
int recursive_level;
{
- register char *str;
- register int i;
- register int strl;
- register int mode;
+ char *str;
+ int i;
+ int strl;
+ int mode;
int j;
- mode = DEFAULT; /* default */
- addr_modeP->scaled_mode = 0; /* why not */
- addr_modeP->scaled_reg = 0; /* if 0, not scaled index */
+ mode = DEFAULT; /* Default. */
+ addr_modeP->scaled_mode = 0; /* Why not. */
+ addr_modeP->scaled_reg = 0; /* If 0, not scaled index. */
addr_modeP->float_flag = 0;
addr_modeP->am_size = 0;
addr_modeP->im_disp = 0;
- addr_modeP->pcrel = 0; /* not set in this function */
+ addr_modeP->pcrel = 0; /* Not set in this function. */
addr_modeP->disp_suffix[0] = 0;
addr_modeP->disp_suffix[1] = 0;
addr_modeP->disp[0] = NULL;
return -1;
}
default:
- as_warn (_("Invalid syntax in PC-relative addressing mode"));
+ as_bad (_("Invalid syntax in PC-relative addressing mode"));
return 0;
}
}
i = 0;
j = 2;
do
- { /* disp[0]'s termination point */
+ { /* disp[0]'s termination point. */
j += 1;
if (str[j] == '(')
i++;
while (j < strl && i != 0);
if (i != 0 || !(str[j + 1] == '-' || str[j + 1] == '+'))
{
- as_warn (_("Invalid syntax in External addressing mode"));
+ as_bad (_("Invalid syntax in External addressing mode"));
return (0);
}
str[j] = '\000'; /* null terminate disp[0] */
mode = 18;
if (mode != DEFAULT)
- { /* Memory relative. */
+ {
+ /* Memory relative. */
addr_modeP->mode = mode;
j = strl - 5; /* Temp for end of disp[0]. */
i = 0;
if (i != 0)
{
- as_warn (_("Invalid syntax in Memory Relative addressing mode"));
+ as_bad (_("Invalid syntax in Memory Relative addressing mode"));
return (0);
}
mode = 31;
break;
default:
- as_warn (_("Invalid scaled-indexed mode, use (b,w,d,q)"));
+ as_bad (_("Invalid scaled-indexed mode, use (b,w,d,q)"));
if (str[strl - 3] != ':' || str[strl - 6] != '['
|| str[strl - 5] == 'r' || str[strl - 4] < '0'
|| str[strl - 4] > '7')
- as_warn (_("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}"));
+ as_bad (_("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}"));
} /* Scaled index. */
if (recursive_level > 0)
{
- as_warn (_("Scaled-indexed addressing mode combined with scaled-index"));
+ as_bad (_("Scaled-indexed addressing mode combined with scaled-index"));
return 0;
}
- addr_modeP->am_size += 1; /* scaled index byte */
- j = str[strl - 4] - '0'; /* store temporary */
- str[strl - 6] = '\000'; /* nullterminate for recursive call */
+ addr_modeP->am_size += 1; /* scaled index byte. */
+ j = str[strl - 4] - '0'; /* store temporary. */
+ str[strl - 6] = '\000'; /* nullterminate for recursive call. */
i = addr_mode (str, addr_modeP, 1);
if (!i || addr_modeP->mode == 20)
{
- as_warn (_("Invalid or illegal addressing mode combined with scaled-index"));
+ as_bad (_("Invalid or illegal addressing mode combined with scaled-index"));
return 0;
}
specifying suffixes and determines size of immediate mode via
ns32k-opcode. Also builds index bytes if needed. */
-int
+static int get_addr_mode PARAMS ((char *, addr_modeS *));
+static int
get_addr_mode (ptr, addr_modeP)
char *ptr;
addr_modeS *addr_modeP;
case. Think it does so with local labels too, not optimum, pcrel
is better. When I have time I will make gas check this and
select pcrel when possible Actually that is trivial. */
- if (tmp = addr_modeP->scaled_reg)
+ if ((tmp = addr_modeP->scaled_reg))
{ /* Build indexbyte. */
tmp--; /* Remember regnumber comes incremented for
flagpurpose. */
addr_modeP->am_size += 1;
}
- if (disp_test[addr_modeP->mode])
+ assert (addr_modeP->mode >= 0);
+ if (disp_test[(unsigned int) addr_modeP->mode])
{
- register char c;
- register char suffix;
- register char suffix_sub;
- register int i;
- register char *toP;
- register char *fromP;
+ char c;
+ char suffix;
+ char suffix_sub;
+ int i;
+ char *toP;
+ char *fromP;
/* There was a displacement, probe for length specifying suffix. */
addr_modeP->pcrel = 0;
- if (disp_test[addr_modeP->mode])
+ assert(addr_modeP->mode >= 0);
+ if (disp_test[(unsigned int) addr_modeP->mode])
{
/* There is a displacement. */
if (addr_modeP->mode == 27 || addr_modeP->scaled_mode == 27)
{
suffix_sub = suffix = 0;
- if (toP = addr_modeP->disp[i])
+ if ((toP = addr_modeP->disp[i]))
{
/* Suffix of expression, the largest size rules. */
fromP = toP;
- while (c = *fromP++)
+ while ((c = *fromP++))
{
*toP++ = c;
if (c == ':')
/* Read an optionlist. */
-void
+static void optlist PARAMS ((char *, struct ns32k_option *, unsigned long *));
+static void
optlist (str, optionP, default_map)
char *str; /* The string to extract options from. */
struct ns32k_option *optionP; /* How to search the string. */
unsigned long *default_map; /* Default pattern and output. */
{
- register int i, j, k, strlen1, strlen2;
- register char *patternP, *strP;
+ int i, j, k, strlen1, strlen2;
+ char *patternP, *strP;
strlen1 = strlen (str);
the instructions lmr, smr, lpr, spr return true if str is found in
list. */
-int
+static int list_search PARAMS ((char *, struct ns32k_option *, unsigned long *));
+
+static int
list_search (str, optionP, default_map)
char *str; /* The string to match. */
struct ns32k_option *optionP; /* List to search. */
unsigned long *default_map; /* Default pattern and output. */
{
- register int i;
+ int i;
for (i = 0; optionP[i].pattern != 0; i++)
{
}
}
- as_warn (_("No such entry in list. (cpu/mmu register)"));
+ as_bad (_("No such entry in list. (cpu/mmu register)"));
return 0;
}
expressionS *resultP;
char *ptr;
{
- register char *tmp_line;
+ char *tmp_line;
tmp_line = input_line_pointer;
input_line_pointer = ptr;
- expression (&exprP);
+ expression (resultP);
input_line_pointer = tmp_line;
}
\f
opcode.
Be carefull not to put to objects in the same iif-slot. */
-void
+static void encode_operand PARAMS ((int argc, char **argv, char *operandsP, char *, char, char));
+static void
encode_operand (argc, argv, operandsP, suffixP, im_size, opcode_bit_ptr)
int argc;
char **argv;
char *operandsP;
char *suffixP;
- char im_size;
+ char im_size ATTRIBUTE_UNUSED;
char opcode_bit_ptr;
{
- register int i, j;
+ int i, j;
char d;
- int pcrel, tmp, b, loop, pcrel_adjust;
+ int pcrel, b, loop, pcrel_adjust;
+ unsigned long tmp;
for (loop = 0; loop < argc; loop++)
{
switch ((d = operandsP[(loop << 1) + 1]))
{
- case 'f': /* operand of sfsr turns out to be a nasty
- specialcase */
+ case 'f': /* Operand of sfsr turns out to be a nasty
+ specialcase. */
opcode_bit_ptr -= 5;
- case 'Z': /* float not immediate */
- case 'F': /* 32 bit float general form */
- case 'L': /* 64 bit float */
- case 'I': /* integer not immediate */
- case 'B': /* byte */
- case 'W': /* word */
- case 'D': /* double-word */
- case 'A': /* double-word gen-address-form ie no regs
- allowed */
+ case 'Z': /* Float not immediate. */
+ case 'F': /* 32 bit float general form. */
+ case 'L': /* 64 bit float. */
+ case 'I': /* Integer not immediate. */
+ case 'B': /* Byte */
+ case 'W': /* Word */
+ case 'D': /* Double-word. */
+ case 'A': /* Double-word gen-address-form ie no regs
+ allowed. */
get_addr_mode (argv[i], &addr_modeP);
if ((addr_modeP.mode == 20) &&
}
break;
- case 'b': /* multiple instruction disp */
- freeptr++; /* OVE:this is an useful hack */
- sprintf (freeptr, "((%s-1)*%d)\000", argv[i], desc->im_size);
+ case 'b': /* Multiple instruction disp. */
+ freeptr++; /* OVE:this is an useful hack. */
+ sprintf (freeptr, "((%s-1)*%d)", argv[i], desc->im_size);
argv[i] = freeptr;
- pcrel -= 1; /* make pcrel 0 inspite of what case 'p':
- wants */
+ pcrel -= 1; /* Make pcrel 0 inspite of what case 'p':
+ wants. */
/* fall thru */
- case 'p': /* displacement - pc relative addressing */
+ case 'p': /* Displacement - pc relative addressing. */
pcrel += 1;
/* fall thru */
- case 'd': /* displacement */
+ case 'd': /* Displacement. */
iif.instr_size += suffixP[i] ? suffixP[i] : 4;
IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 0);
break;
- case 'H': /* sequent-hack: the linker wants a bit set
- when bsr */
+ case 'H': /* Sequent-hack: the linker wants a bit set
+ when bsr. */
pcrel = 1;
iif.instr_size += suffixP[i] ? suffixP[i] : 4;
IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
IIF (11, 2, 42, (unsigned long) argv[i], 0, 0, 0, 0, 0,
bit_fix_new (4, opcode_bit_ptr, -8, 7, 0, 1, 0), -1, 0);
break;
- case 'r': /* register number (3 bits) */
+ case 'r': /* Register number (3 bits). */
list_search (argv[i], opt6, &tmp);
opcode_bit_ptr -= 3;
iif.iifP[1].object |= tmp << opcode_bit_ptr;
break;
- case 'O': /* setcfg instruction optionslist */
+ case 'O': /* Setcfg instruction optionslist. */
optlist (argv[i], opt3, &tmp);
opcode_bit_ptr -= 4;
iif.iifP[1].object |= tmp << 15;
break;
- case 'C': /* cinv instruction optionslist */
+ case 'C': /* Cinv instruction optionslist. */
optlist (argv[i], opt4, &tmp);
opcode_bit_ptr -= 4;
- iif.iifP[1].object |= tmp << 15; /* insert the regtype in opcode */
+ iif.iifP[1].object |= tmp << 15; /* Insert the regtype in opcode. */
break;
- case 'S': /* stringinstruction optionslist */
+ case 'S': /* String instruction options list. */
optlist (argv[i], opt5, &tmp);
opcode_bit_ptr -= 4;
iif.iifP[1].object |= tmp << 15;
break;
case 'u':
- case 'U': /* registerlist */
+ case 'U': /* Register list. */
IIF (10, 1, 1, 0, 0, 0, 0, 0, 0, NULL, -1, 0);
switch (operandsP[(i << 1) + 1])
{
- case 'u': /* restore, exit */
+ case 'u': /* Restore, exit. */
optlist (argv[i], opt1, &iif.iifP[10].object);
break;
- case 'U': /* save,enter */
+ case 'U': /* Save, enter. */
optlist (argv[i], opt2, &iif.iifP[10].object);
break;
}
iif.instr_size += 1;
break;
- case 'M': /* mmu register */
+ case 'M': /* MMU register. */
list_search (argv[i], mmureg, &tmp);
opcode_bit_ptr -= 4;
iif.iifP[1].object |= tmp << opcode_bit_ptr;
break;
- case 'P': /* cpu register */
+ case 'P': /* CPU register. */
list_search (argv[i], cpureg, &tmp);
opcode_bit_ptr -= 4;
iif.iifP[1].object |= tmp << opcode_bit_ptr;
break;
- case 'g': /* inss exts */
- iif.instr_size += 1; /* 1 byte is allocated after the opcode */
+ case 'g': /* Inss exts. */
+ iif.instr_size += 1; /* 1 byte is allocated after the opcode. */
IIF (10, 2, 1,
- (unsigned long) argv[i], /* i always 2 here */
+ (unsigned long) argv[i], /* i always 2 here. */
0, 0, 0, 0, 0,
- bit_fix_new (3, 5, 0, 7, 0, 0, 0), /* a bit_fix is targeted to
- the byte */
+ bit_fix_new (3, 5, 0, 7, 0, 0, 0), /* A bit_fix is targeted to
+ the byte. */
-1, 0);
break;
case 'G':
IIF (11, 2, 42,
- (unsigned long) argv[i], /* i always 3 here */
+ (unsigned long) argv[i], /* i always 3 here. */
0, 0, 0, 0, 0,
bit_fix_new (5, 0, 1, 32, -1, 0, -1), -1, 0);
break;
case 'i':
iif.instr_size += 1;
- b = 2 + i; /* put the extension byte after opcode */
+ b = 2 + i; /* Put the extension byte after opcode. */
IIF (b, 2, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0);
break;
default:
out: internal structure of instruction
that has been prepared for direct conversion to fragment(s) and
fixes in a systematical fashion
- Return-value = recursive_level. */
+ Return-value = recursive_level. */
/* Build iif of one assembly text line. */
-int
+static int parse PARAMS ((char *, int));
+static int
parse (line, recursive_level)
char *line;
int recursive_level;
{
- register char *lineptr, c, suffix_separator;
- register int i;
- int argc, arg_type;
+ char *lineptr, c, suffix_separator;
+ int i;
+ unsigned int argc;
+ int arg_type;
char sqr, sep;
char suffix[MAX_ARGS], *argv[MAX_ARGS]; /* No more than 4 operands. */
break;
}
- suffix[argc] = 0; /* 0 when no ':' is encountered */
+ suffix[argc] = 0; /* 0 when no ':' is encountered. */
argv[argc] = freeptr;
*freeptr = '\0';
objects not part of an instruction, the pointer to the opcode frag
is always zero. */
-void
+static void convert_iif PARAMS ((void));
+static void
convert_iif ()
{
int i;
int k;
char type;
char size = 0;
- int size_so_far;
+ frag_grow (iif.instr_size); /* This is important. */
memP = frag_more (0);
inst_opcode = memP;
inst_offset = (memP - frag_now->fr_literal);
for (i = 0; i < IIF_ENTRIES; i++)
{
- if (type = iif.iifP[i].type)
+ if ((type = iif.iifP[i].type))
{
/* The object exist, so handle it. */
switch (size = iif.iifP[i].size)
iif.iifP[i].bit_fixP->fx_bit_base = (long) inst_opcode;
/* Fall through. */
- case 8: /* bignum or doublefloat */
+ case 8: /* bignum or doublefloat. */
case 1:
case 2:
case 3:
switch (type)
{
case 1: /* The object is pure binary. */
- if (j || iif.iifP[i].pcrel)
+ if (j)
+ {
+ md_number_to_field(memP, exprP.X_add_number, j);
+ }
+ else if (iif.iifP[i].pcrel)
{
fix_new_ns32k (frag_now,
(long) (memP - frag_now->fr_literal),
iif.iifP[i].object,
iif.iifP[i].pcrel,
iif.iifP[i].im_disp,
- j,
- iif.iifP[i].bsr, /* sequent hack */
+ 0,
+ iif.iifP[i].bsr, /* Sequent hack. */
inst_frag, inst_offset);
}
else
/* We have a bignum ie a quad. This can only
happens in a long suffixed instruction. */
if (k * 2 > size)
- as_warn (_("Bignum too big for long"));
+ as_bad (_("Bignum too big for long"));
if (k == 3)
memP += 2;
for (l = 0; k > 0; k--, l += 2)
- {
- md_number_to_chars (memP + l,
- generic_bignum[l >> 1],
- sizeof (LITTLENUM_TYPE));
- }
+ md_number_to_chars (memP + l,
+ generic_bignum[l >> 1],
+ sizeof (LITTLENUM_TYPE));
}
else
{
}
break;
}
- if (j ||
- exprP.X_add_symbol ||
+ if (exprP.X_add_symbol ||
exprP.X_op_symbol ||
iif.iifP[i].pcrel)
{
iif.iifP[i].bsr,
inst_frag, inst_offset);
}
+ else if (j)
+ {
+ md_number_to_field(memP, exprP.X_add_number, j);
+ }
else
{
/* Good, just put them bytes out. */
if ((exprP.X_add_symbol || exprP.X_op_symbol) &&
!iif.iifP[i].pcrel)
{
- /* Size is unknown until link time so have to
- allow 4 bytes. */
- size = 4;
+ /* Size is unknown until link time so have to default. */
+ size = default_disp_size; /* Normally 4 bytes. */
memP = frag_more (size);
fix_new_ns32k_exp (frag_now,
(long) (memP - frag_now->fr_literal),
(bit_fixS *) 0, 0,
inst_frag,
inst_offset);
- break; /* exit this absolute hack */
+ break; /* Exit this absolute hack. */
}
if (exprP.X_add_symbol || exprP.X_op_symbol)
}
else
{
- as_warn (_("Displacement to large for :d"));
+ as_bad (_("Displacement to large for :d"));
size = 4;
}
}
index = length + 3 * pcrel + 6 * type;
- if (index >= 0 && index < sizeof (relocs) / sizeof (relocs[0]))
+ if (index >= 0 && (unsigned int) index < sizeof (relocs) / sizeof (relocs[0]))
return relocs[index];
if (pcrel)
{
case 1:
if (val < -64 || val > 63)
- as_warn (_("Byte displacement out of range. line number not valid"));
+ as_bad (_("value of %ld out of byte displacement range."), val);
val &= 0x7f;
#ifdef SHOW_NUM
printf ("%x ", val & 0xff);
break;
case 2:
if (val < -8192 || val > 8191)
- as_warn (_("Word displacement out of range. line number not valid"));
+ as_bad (_("value of %ld out of word displacement range."), val);
val &= 0x3fff;
val |= 0x8000;
#ifdef SHOW_NUM
break;
case 4:
if (val < -0x20000000 || val >= 0x20000000)
- as_warn (_("Double word displacement out of range"));
+ as_bad (_("value of %ld out of double word displacement range."), val);
val |= 0xc0000000;
#ifdef SHOW_NUM
printf ("%x ", val >> 24 & 0xff);
*buf++ = val;
break;
default:
- as_fatal (_("Internal logic error. line %s, file \"%s\""),
+ as_fatal (_("Internal logic error. line %d, file \"%s\""),
__LINE__, __FILE__);
}
}
*buf++ = val;
break;
default:
- as_fatal (_("Internal logic error. line %s, file \"%s\""),
+ as_fatal (_("Internal logic error. line %d, file \"%s\""),
__LINE__, __FILE__);
}
}
static void
md_number_to_field (buf, val, field_ptr)
- register char *buf;
- register long val;
- register bit_fixS *field_ptr;
+ char *buf;
+ long val;
+ bit_fixS *field_ptr;
{
- register unsigned long object;
- register unsigned long mask;
- /* define ENDIAN on a ns32k machine */
+ unsigned long object;
+ unsigned long mask;
+ /* Define ENDIAN on a ns32k machine. */
#ifdef ENDIAN
- register unsigned long *mem_ptr;
+ unsigned long *mem_ptr;
#else
- register char *mem_ptr;
+ char *mem_ptr;
#endif
+
if (field_ptr->fx_bit_min <= val && val <= field_ptr->fx_bit_max)
{
#ifdef ENDIAN
#ifdef ENDIAN
/* We have a nice ns32k machine with lowbyte at low-physical mem. */
object = *mem_ptr; /* get some bytes */
-#else /* OVE Goof! the machine is a m68k or dito */
+#else /* OVE Goof! the machine is a m68k or dito. */
/* That takes more byte fiddling. */
object = 0;
object |= mem_ptr[3] & 0xff;
}
else
{
- as_warn (_("Bit field out of range"));
+ as_bad (_("Bit field out of range"));
}
}
return fragP->fr_address + fragP->fr_fix - opcode_address;
}
-int
+static int md_fix_pcrel_adjust PARAMS ((fixS *fixP));
+static int
md_fix_pcrel_adjust (fixP)
fixS *fixP;
{
- fragS *fragP = fixP->fx_frag;
fragS *opcode_frag;
addressT opcode_address;
unsigned int offset;
segT seg ATTRIBUTE_UNUSED;
{
long val = * (long *) valP;
- fragS *fragP = fixP->fx_frag;
char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
if (fix_bit_fixP (fixP))
- /* Bitfields to fix, sigh. */
- md_number_to_field (buf, val, fix_bit_fixP (fixP));
-
+ {
+ /* Bitfields to fix, sigh. */
+ md_number_to_field (buf, val, fix_bit_fixP (fixP));
+ }
else switch (fix_im_disp (fixP))
{
case 0:
case 1:
/* Displacement field. */
- /* Calculate offset */
+ /* Calculate offset. */
md_number_to_disp (buf,
(fixP->fx_pcrel ? val + md_fix_pcrel_adjust (fixP)
: val), fixP->fx_size);
fixP->fx_done = 1;
}
\f
-/* Convert a relaxed displacement to ditto in final output */
+/* Convert a relaxed displacement to ditto in final output. */
#ifndef BFD_ASSEMBLER
void
md_convert_frag (headers, sec, fragP)
object_headers *headers;
segT sec;
- register fragS *fragP;
+ fragS *fragP;
#else
void
md_convert_frag (abfd, sec, fragP)
- bfd *abfd;
- segT sec;
- register fragS *fragP;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ segT sec ATTRIBUTE_UNUSED;
+ fragS *fragP;
#endif
{
long disp;
long ext = 0;
-
/* Address in gas core of the place to store the displacement. */
- register char *buffer_address = fragP->fr_fix + fragP->fr_literal;
+ char *buffer_address = fragP->fr_fix + fragP->fr_literal;
/* Address in object code of the displacement. */
int object_address;
- fragS *opcode_frag;
-
switch (fragP->fr_subtype)
{
case IND (BRANCH, BYTE):
int
md_estimate_size_before_relax (fragP, segment)
- register fragS *fragP;
+ fragS *fragP;
segT segment;
{
if (fragP->fr_subtype == IND (BRANCH, UNDEF))
1,
1,
0,
- frag_bsr(fragP), /*sequent hack */
+ frag_bsr(fragP), /* Sequent hack. */
frag_opcode_frag (fragP),
frag_opcode_offset (fragP));
fragP->fr_fix += 4;
md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
char *ptr;
addressT from_addr, to_addr;
- fragS *frag;
- symbolS *to_symbol;
+ fragS *frag ATTRIBUTE_UNUSED;
+ symbolS *to_symbol ATTRIBUTE_UNUSED;
{
valueT offset;
md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
char *ptr;
addressT from_addr, to_addr;
- fragS *frag;
- symbolS *to_symbol;
+ fragS *frag ATTRIBUTE_UNUSED;
+ symbolS *to_symbol ATTRIBUTE_UNUSED;
{
valueT offset;
struct option md_longopts[] =
{
+#define OPTION_DISP_SIZE (OPTION_MD_BASE)
+ {"disp-size-default", required_argument , NULL, OPTION_DISP_SIZE},
{NULL, no_argument, NULL, 0}
};
}
else
{
- as_bad (_("invalid architecture option -m%s"), arg);
+ as_warn (_("invalid architecture option -m%s, ignored"), arg);
return 0;
}
break;
+ case OPTION_DISP_SIZE:
+ {
+ int size = atoi(arg);
+ switch (size)
+ {
+ case 1: case 2: case 4:
+ default_disp_size = size;
+ break;
+ default:
+ as_warn (_("invalid default displacement size \"%s\". Defaulting to %d."),
+ arg, default_disp_size);
+ }
+ break;
+ }
default:
return 0;
{
fprintf (stream, _("\
NS32K options:\n\
--m32032 | -m32532 select variant of NS32K architecture\n"));
+-m32032 | -m32532 select variant of NS32K architecture\n\
+--disp-size-default=<1|2|4>\n"));
}
\f
/* Create a bit_fixS in obstack 'notes'.
bit_fixS *
bit_fix_new (size, offset, min, max, add, base_type, base_adj)
- char size; /* Length of bitfield */
- char offset; /* Bit offset to bitfield */
- long min; /* Signextended min for bitfield */
- long max; /* Signextended max for bitfield */
- long add; /* Add mask, used for huffman prefix */
- long base_type; /* 0 or 1, if 1 it's exploded to opcode ptr */
+ char size; /* Length of bitfield. */
+ char offset; /* Bit offset to bitfield. */
+ long min; /* Signextended min for bitfield. */
+ long max; /* Signextended max for bitfield. */
+ long add; /* Add mask, used for huffman prefix. */
+ long base_type; /* 0 or 1, if 1 it's exploded to opcode ptr. */
long base_adj;
{
- register bit_fixS *bit_fixP;
+ bit_fixS *bit_fixP;
bit_fixP = (bit_fixS *) obstack_alloc (¬es, sizeof (bit_fixS));
bit_fixP->fx_bit_min = min;
bit_fixP->fx_bit_add = add;
- return (bit_fixP);
+ return bit_fixP;
}
void
int size; /* 1, 2 or 4 usually. */
symbolS *add_symbol; /* X_add_symbol. */
long offset; /* X_add_number. */
- int pcrel; /* TRUE if PC-relative relocation. */
- char im_disp; /* true if the value to write is a
- displacement */
- bit_fixS *bit_fixP; /* pointer at struct of bit_fix's, ignored if
- NULL */
- char bsr; /* sequent-linker-hack: 1 when relocobject is
- a bsr */
+ int pcrel; /* True if PC-relative relocation. */
+ char im_disp; /* True if the value to write is a
+ displacement. */
+ bit_fixS *bit_fixP; /* Pointer at struct of bit_fix's, ignored if
+ NULL. */
+ char bsr; /* Sequent-linker-hack: 1 when relocobject is
+ a bsr. */
fragS *opcode_frag;
unsigned int opcode_offset;
{
fix_im_disp (fixP) = im_disp;
fix_bsr (fixP) = bsr;
fix_bit_fixP (fixP) = bit_fixP;
+ /* We have a MD overflow check for displacements. */
+ fixP->fx_no_overflow = (im_disp != 0);
}
void
int where; /* Where in that frag? */
int size; /* 1, 2 or 4 usually. */
expressionS *exp; /* Expression. */
- int pcrel; /* TRUE if PC-relative relocation. */
- char im_disp; /* true if the value to write is a
- displacement */
- bit_fixS *bit_fixP; /* pointer at struct of bit_fix's, ignored if
- NULL */
- char bsr; /* sequent-linker-hack: 1 when relocobject is
- a bsr */
+ int pcrel; /* True if PC-relative relocation. */
+ char im_disp; /* True if the value to write is a
+ displacement. */
+ bit_fixS *bit_fixP; /* Pointer at struct of bit_fix's, ignored if
+ NULL. */
+ char bsr; /* Sequent-linker-hack: 1 when relocobject is
+ a bsr. */
fragS *opcode_frag;
unsigned int opcode_offset;
{
fix_im_disp (fixP) = im_disp;
fix_bsr (fixP) = bsr;
fix_bit_fixP (fixP) = bit_fixP;
+ /* We have a MD overflow check for displacements. */
+ fixP->fx_no_overflow = (im_disp != 0);
}
/* This is TC_CONS_FIX_NEW, called by emit_expr in read.c. */
symbolS *
md_undefined_symbol (name)
- char *name;
+ char *name ATTRIBUTE_UNUSED;
{
return 0;
}
valueT
md_section_align (segment, size)
- segT segment;
+ segT segment ATTRIBUTE_UNUSED;
valueT size;
{
return size; /* Byte alignment is fine. */
fixS *fixP;
{
long res;
+
res = fixP->fx_where + fixP->fx_frag->fr_address;
#ifdef SEQUENT_COMPATABILITY
if (frag_bsr (fixP->fx_frag))
arelent *
tc_gen_reloc (section, fixp)
- asection *section;
+ asection *section ATTRIBUTE_UNUSED;
fixS *fixp;
{
arelent *rel;
/* tc-ns32k.h -- Opcode table for National Semi 32k processor
- Copyright 1987, 1992, 1993, 1994, 1995, 1997, 2000
+ Copyright 1987, 1992, 1993, 1994, 1995, 1997, 2000, 2002
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
#define TARGET_BYTES_BIG_ENDIAN 0
#define TC_PCREL_ADJUST(F) md_pcrel_adjust(F)
+extern int md_pcrel_adjust PARAMS((fragS *fragP));
#ifdef BFD_ASSEMBLER
#define NO_RELOC BFD_RELOC_NONE
#define ARG_LEN 50
#define TC_CONS_FIX_NEW cons_fix_new_ns32k
-extern void fix_new_ns32k_exp PARAMS((fragS *frag,
- int where,
- int size,
- expressionS *exp,
- int pcrel,
- int im_disp,
- bit_fixS *bit_fixP, /* really bit_fixS */
- int bsr,
- fragS *opcode_frag,
- unsigned int opcode_offset));
-
-extern void fix_new_ns32k PARAMS ((fragS *frag,
- int where,
- int size,
- symbolS *add_symbol,
- long offset,
- int pcrel,
- int im_disp,
- bit_fixS *bit_fixP, /* really bit_fixS */
- int bsr,
- fragS *opcode_frag,
- unsigned int opcode_offset));
-
-extern void cons_fix_new_ns32k PARAMS ((fragS *frag,
- int where,
- int size,
- expressionS *exp));
-
-/* the NS32x32 has a non 0 nop instruction which should be used in aligns */
+extern void fix_new_ns32k_exp PARAMS ((fragS *, int, int, expressionS *,
+ int, int, bit_fixS *, int, fragS *,
+ unsigned int));
+
+extern void fix_new_ns32k PARAMS ((fragS *, int, int, symbolS *, long,
+ int, int, bit_fixS *, int, fragS *,
+ unsigned int));
+
+extern void cons_fix_new_ns32k PARAMS ((fragS *, int, int, expressionS *));
+
+/* The NS32x32 has a non 0 nop instruction which should be used in aligns. */
#define NOP_OPCODE 0xa2
#define md_operand(x)
#define TC_GENERIC_RELAX_TABLE md_relax_table
#define TC_FRAG_TYPE \
-struct { \
- fragS *fr_opcode_fragP; \
- unsigned int fr_opcode_offset; \
- char fr_bsr; \
-}
+ struct \
+ { \
+ fragS * fr_opcode_fragP; \
+ unsigned int fr_opcode_offset; \
+ char fr_bsr; \
+ }
#define TC_FRAG_INIT(X) \
do \
{ \
frag_opcode_frag (X) = NULL; \
frag_opcode_offset (X) = 0; \
- frag_bsr (X) = 0; \
+ frag_bsr (X) = 0; \
} \
while (0)
-/* Accessor macros for things which may move around */
+/* Accessor macros for things which may move around. */
#define frag_opcode_frag(X) (X)->tc_frag_data.fr_opcode_fragP
#define frag_opcode_offset(X) (X)->tc_frag_data.fr_opcode_offset
#define frag_bsr(X) (X)->tc_frag_data.fr_bsr
#define TC_FIX_TYPE \
-struct \
-{ \
- fragS *opcode_fragP; \
- unsigned int opcode_offset; \
- unsigned int bsr : 1; \
-}
+ struct \
+ { \
+ fragS * opcode_fragP; \
+ unsigned int opcode_offset; \
+ unsigned int bsr : 1; \
+ }
/* Accessor macros for things which may move around.
See comments in write.h. */