+2001-05-23 Alan Modra <amodra@one.net.au>
+
+ Merge from mainline.
+ 2001-05-17 Alan Modra <amodra@one.net.au>
+ * elf32-hppa.c (hppa_build_one_stub): Add an assert to check
+ plt.offset.
+
+ 2001-05-16 Alan Modra <amodra@one.net.au>
+ * section.c (asection): Add linker_has_input field.
+ (STD_SECTION): Adjust initialization to suit.
+ * ecoff.c (bfd_debug_section): Likewise.
+ * bfd-in2.h: Regenerate.
+
+ 2001-05-07 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+ * ecoff.c (bfd_debug_section): Fix initialization.
+
+ 2001-05-12 Peter Targett <peter.targett@arccores.com>
+ * cpu-arc.c (arch_info_struct): Add entry 'base' representing old
+ name for 'arc5' core versions.
+ (bfd_arc_arch): Make bfd_mach_arc_6 default.
+ * elf32-arc.c (arc_elf_object_p): Make E_ARC_MACH_ARC6 default
+ architecture.
+ (arc_elf_final_write_processing): Make bfd_mach_arc_6 default.
+
+ 2001-05-08 Ian Lance Taylor <ian@zembu.com>
+ * coff-i386.c (coff_i386_reloc): Don't dump core if output_bfd is
+ NULL or is not COFF.
+ (coff_i386_rtype_to_howto): Don't dump core if output section
+ owner is not COFF.
+
+ 2001-04-13 Roger Sayle <roger@metaphorics.com>
+ * coff-i386.c (TARGET_SYM): SEC_READONLY is an applicable section
+ flag on pe-i386 targets.
+
+ 2001-04-26 H.J. Lu <hjl@gnu.org>
+ * elf32-i386.c (elf_i386_check_relocs): Verify if r_symndx is
+ valid.
+
+ 2001-04-05 David Mosberger <davidm@hpl.hp.com>
+ * elf32-i386.c (elf_i386_fake_sections): Treat ".reloc" as an
+ ordinary "progbits" section.
+
2001-05-04 Richard Henderson <rth@redhat.com>
* elf64-alpha.c (SREL16, SREL32, SREL64): Set pcrel_offset true.
/* A mark flag used by some of the linker backends. */
unsigned int linker_mark : 1;
+ /* Another mark flag used by some of the linker backends. Set for
+ output sections that have a input section. */
+ unsigned int linker_has_input : 1;
+
/* A mark flag used by some linker backends for garbage collection. */
unsigned int gc_mark : 1;
/* BFD back-end for Intel 386 COFF files.
- Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001
Free Software Foundation, Inc.
Written by Cygnus Support.
#ifdef COFF_WITH_PE
/* FIXME: How should this case be handled? */
- if (reloc_entry->howto->type == R_IMAGEBASE)
+ if (reloc_entry->howto->type == R_IMAGEBASE
+ && output_bfd != NULL
+ && bfd_get_flavour(output_bfd) == bfd_target_coff_flavour)
diff -= pe_data (output_bfd)->pe_opthdr.ImageBase;
#endif
*addendp -= sym->n_value;
}
- if (rel->r_type == R_IMAGEBASE)
+ if (rel->r_type == R_IMAGEBASE
+ && (bfd_get_flavour(sec->output_section->owner)
+ == bfd_target_coff_flavour))
{
*addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
}
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
#ifdef COFF_WITH_PE
- | SEC_LINK_ONCE | SEC_LINK_DUPLICATES
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY
#endif
| SEC_CODE | SEC_DATA),
/* BFD support for the ARC processor
- Copyright 1994, 1995, 1997 Free Software Foundation, Inc.
+ Copyright 1994, 1995, 1997, 2001 Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com).
This file is part of BFD, the Binary File Descriptor library.
print_name, \
4, /* section alignment power */ \
default_p, \
- bfd_default_compatible, \
+ bfd_default_compatible, \
bfd_default_scan, \
next, \
}
static const bfd_arch_info_type arch_info_struct[] =
{
ARC ( bfd_mach_arc_5, "arc5", false, &arch_info_struct[1] ),
- ARC ( bfd_mach_arc_6, "arc6", false, &arch_info_struct[2] ),
- ARC ( bfd_mach_arc_7, "arc7", false, &arch_info_struct[3] ),
+ ARC ( bfd_mach_arc_5, "base", false, &arch_info_struct[2] ),
+ ARC ( bfd_mach_arc_6, "arc6", false, &arch_info_struct[3] ),
+ ARC ( bfd_mach_arc_7, "arc7", false, &arch_info_struct[4] ),
ARC ( bfd_mach_arc_8, "arc8", false, NULL ),
};
const bfd_arch_info_type bfd_arc_arch =
- ARC ( bfd_mach_arc_5, "arc", true, &arch_info_struct[0] );
+ ARC ( bfd_mach_arc_6, "arc", true, &arch_info_struct[0] );
/* Utility routines. */
/* Generic ECOFF (Extended-COFF) routines.
- Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
+ Copyright 1990, 1991, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
Original version by Per Bothner.
Full support added by Ian Lance Taylor, ian@cygnus.com.
static asection bfd_debug_section =
{
- /* name, index, next, flags, set_vma, reloc_done, linker_mark, gc_mark */
- "*DEBUG*", 0, 0, 0, 0, 0, 0, 0,
- /* vma, lma, _cooked_size, _raw_size, output_offset, output_section, */
- 0, 0, 0, 0, 0, NULL,
- /* alig, reloc..., orel..., reloc_count, filepos, rel_..., line_... */
- 0, 0, 0, 0, 0, 0, 0,
- /* userdata, contents, lineno, lineno_count */
- 0, 0, 0, 0,
- /* comdat_info, moving_line_filepos, target_index, used_by_bfd, */
- NULL, 0, 0, 0,
- /* cons, owner, symbol */
- 0, 0, (struct symbol_cache_entry *) NULL,
- /* symbol_ptr_ptr, link_order_head, ..._tail */
- (struct symbol_cache_entry **) NULL, NULL, NULL
+ /* name, id, index, next, flags, user_set_vma, reloc_done, */
+ "*DEBUG*", 0, 0, NULL, 0, 0, 0,
+ /* linker_mark, linker_has_input, gc_mark, segment_mark, */
+ 0, 0, 0, 0,
+ /* vma, lma, _cooked_size, _raw_size, */
+ 0, 0, 0, 0,
+ /* output_offset, output_section, alignment_power, */
+ 0, NULL, 0,
+ /* relocation, orelocation, reloc_count, filepos, rel_filepos, */
+ NULL, NULL, 0, 0, 0,
+ /* line_filepos, userdata, contents, lineno, lineno_count, */
+ 0, NULL, NULL, NULL, 0,
+ /* comdat, kept_section, moving_line_filepos, */
+ NULL, NULL, 0,
+ /* target_index, used_by_bfd, constructor_chain, owner, */
+ 0, NULL, NULL, NULL,
+ /* symbol, */
+ (struct symbol_cache_entry *) NULL,
+ /* symbol_ptr_ptr, */
+ (struct symbol_cache_entry **) NULL,
+ /* link_order_head, link_order_tail */
+ NULL, NULL
};
/* Create an ECOFF object. */
/* ARC-specific support for 32-bit ELF
- Copyright (C) 1994, 1995, 1997, 1999, 2000 Free Software Foundation, Inc.
+ Copyright 1994, 1995, 1997, 1999, 2001 Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com).
This file is part of BFD, the Binary File Descriptor library.
/* A standard 32 bit relocation. */
HOWTO (R_ARC_32, /* type */
- 0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
- false, /* pc_relative */
- 0, /* bitpos */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
- bfd_elf_generic_reloc, /* special_function */
+ bfd_elf_generic_reloc, /* special_function */
"R_ARC_32", /* name */
- false, /* partial_inplace */
- 0xffffffff, /* src_mask */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
/* A 26 bit absolute branch, right shifted by 2. */
HOWTO (R_ARC_B26, /* type */
arc_elf_object_p (abfd)
bfd *abfd;
{
- int mach = bfd_mach_arc_5;
+ int mach = bfd_mach_arc_6;
if (elf_elfheader(abfd)->e_machine == EM_ARC)
{
switch (arch)
{
- default:
case E_ARC_MACH_ARC5:
mach = bfd_mach_arc_5;
break;
+ default:
case E_ARC_MACH_ARC6:
mach = bfd_mach_arc_6;
break;
switch (bfd_get_mach (abfd))
{
- default:
case bfd_mach_arc_5:
val = E_ARC_MACH_ARC5;
break;
+ default:
case bfd_mach_arc_6:
val = E_ARC_MACH_ARC6;
break;
case hppa_stub_import:
case hppa_stub_import_shared:
+ BFD_ASSERT (stub_entry->h->elf.plt.offset < (bfd_vma) -2);
sym_value = (stub_entry->h->elf.plt.offset
+ hplink->splt->output_offset
+ hplink->splt->output_section->vma
/* Intel 80386/80486-specific support for 32-bit ELF
- Copyright 1993, 94, 95, 96, 97, 98, 99, 2000
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_size / symtab_hdr->sh_entsize)
+ {
+ if (abfd->my_archive)
+ (*_bfd_error_handler) (_("%s(%s): bad symbol index: %d"),
+ bfd_get_filename (abfd->my_archive),
+ bfd_get_filename (abfd),
+ r_symndx);
+ else
+ (*_bfd_error_handler) (_("%s: bad symbol index: %d"),
+ bfd_get_filename (abfd),
+ r_symndx);
+ return false;
+ }
+
if (r_symndx < symtab_hdr->sh_info)
h = NULL;
else
(*_bfd_error_handler) (_("%s: bad relocation section name `%s\'"),
bfd_get_filename (abfd),
name);
- }
+ }
sreloc = bfd_get_section_by_name (dynobj, name);
if (sreloc == NULL)
return true;
}
+/* Set the correct type for an x86 ELF section. We do this by the
+ section name, which is a hack, but ought to work. */
+
+static boolean
+elf_i386_fake_sections (abfd, hdr, sec)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ Elf32_Internal_Shdr *hdr;
+ asection *sec;
+{
+ register const char *name;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ if (strcmp (name, ".reloc") == 0)
+ /*
+ * This is an ugly, but unfortunately necessary hack that is
+ * needed when producing EFI binaries on x86. It tells
+ * elf.c:elf_fake_sections() not to consider ".reloc" as a section
+ * containing ELF relocation info. We need this hack in order to
+ * be able to generate ELF binaries that can be translated into
+ * EFI applications (which are essentially COFF objects). Those
+ * files contain a COFF ".reloc" section inside an ELFNN object,
+ * which would normally cause BFD to segfault because it would
+ * attempt to interpret this section as containing relocation
+ * entries for section "oc". With this hack enabled, ".reloc"
+ * will be treated as a normal data section, which will avoid the
+ * segfault. However, you won't be able to create an ELFNN binary
+ * with a section named "oc" that needs relocations, but that's
+ * the kind of ugly side-effects you get when detecting section
+ * types based on their names... In practice, this limitation is
+ * unlikely to bite.
+ */
+ hdr->sh_type = SHT_PROGBITS;
+
+ return true;
+}
+
+
#define TARGET_LITTLE_SYM bfd_elf32_i386_vec
#define TARGET_LITTLE_NAME "elf32-i386"
#define ELF_ARCH bfd_arch_i386
#define elf_backend_gc_sweep_hook elf_i386_gc_sweep_hook
#define elf_backend_relocate_section elf_i386_relocate_section
#define elf_backend_size_dynamic_sections elf_i386_size_dynamic_sections
+#define elf_backend_fake_sections elf_i386_fake_sections
#include "elf32-target.h"
/* Object file "section" support for the BFD library.
- Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001
Free Software Foundation, Inc.
Written by Cygnus Support.
. {* A mark flag used by some of the linker backends. *}
. unsigned int linker_mark : 1;
.
+. {* Another mark flag used by some of the linker backends. Set for
+. output sections that have a input section. *}
+. unsigned int linker_has_input : 1;
+.
. {* A mark flag used by some linker backends for garbage collection. *}
. unsigned int gc_mark : 1;
.
/* name, id, index, next, flags, user_set_vma, reloc_done, */ \
{ NAME, IDX, 0, NULL, FLAGS, 0, 0, \
\
- /* linker_mark, gc_mark, segment_mark, vma, lma, _cooked_size, */ \
- 0, 1, 0, 0, 0, 0, \
+ /* linker_mark, linker_has_input, gc_mark, segment_mark, */ \
+ 0, 0, 1, 0, \
+ \
+ /* vma, lma, _cooked_size, _raw_size, */ \
+ 0, 0, 0, 0, \
\
- /* _raw_size, output_offset, output_section, alignment_power, */ \
- 0, 0, (struct sec *) &SEC, 0, \
+ /* output_offset, output_section, alignment_power, */ \
+ 0, (struct sec *) &SEC, 0, \
\
/* relocation, orelocation, reloc_count, filepos, rel_filepos, */ \
NULL, NULL, 0, 0, 0, \
+2001-05-23 Alan Modra <amodra@one.net.au>
+
+ Merge from mainline.
+ 2001-05-22 Alan Modra <amodra@one.net.au>
+ * config/tc-arc.c (md_assemble): Use is_end_of_line instead of
+ testing for NULs.
+
+ 2001-05-16 Alan Modra <amodra@one.net.au>
+ * config/tc-arc.c (md_assemble): Correct dwarf2_emit_insn param
+ for 8 byte insns.
+ * config/tc-i386.c (md_assemble): Call dwarf2_emit_insn before
+ opcodes are output rather than after. Delete insn_size.
+ * config/tc-v850.c (md_assemble): Similarly, but delete
+ total_insn_size. Update copyright.
+
+ 2001-05-03 Alan Modra <amodra@one.net.au>
+ * config/tc-i386.c (i386_displacement): Call as_bad for bad GOTOFF
+ expressions rather than triggering an assert.
+
+ 2001-03-30 Alan Modra <alan@linuxcare.com.au>
+ * config/tc-i386.c (UNCOND_JUMP, COND_JUMP, COND_JUMP86): Decrement.
+ (md_relax_table): Remove first four unused entries. Increment
+ rlx_length by one throughout table, and update comments to suit.
+ (md_estimate_size_before_relax): Return size of current variable
+ part of frag to reflect reality when relaxing more than once.
+
+ 2001-03-25 Alan Modra <alan@linuxcare.com.au>
+ * config/tc-i386.c (i386_scale): Accept an absolute expression for
+ scale factor, and return the end of the expression.
+ (i386_operand): Modify for above.
+
+ 2001-03-13 Alan Modra <alan@linuxcare.com.au>
+ * config/tc-i386.c (RELOC_ENUM): Define. Use throughout file.
+ (NUM_FLAG_CODE): Define.
+ (lex_got): New function.
+ (got_reloc): New global var.
+ (x86_cons_fix_new): New function.
+ (x86_cons): New function.
+ (i386_immediate): Use lex_got here, replacing inline code. Change
+ "ignoring junk.." error message to "junk.."
+ (i386_displacement): Likewise.
+ * config/tc-i386.h (TC_PARSE_CONS_EXPRESSION): Define.
+ (x86_cons): Declare.
+ (TC_CONS_FIX_NEW): Define.
+ (x86_cons_fix_new): Declare.
+
+ 2001-03-07 Alan Modra <alan@linuxcare.com.au>
+ * config/tc-i386.c (struct _i386_insn): Rename disp_reloc to reloc.
+ (md_assemble) <smallest displacement>: Use correct field of i.op[]
+ union.
+ <JumpInterSegment output>: Use correct i.disp_reloc[].
+ <immediate output>: Likewise.
+
+ 2001-02-13 Alan Modra <alan@linuxcare.com.au>
+ * doc/c-i386.texi (i386-Arch): Add "jumps"/"nojumps" blurb.
+ Mention effect of < 386 architectures on jump promotion.
+ (i386-Jumps): xref above. Don't assume long disp is 32 bits.
+
+ * config/tc-i386.c (no_cond_jump_promotion): New.
+ (set_cpu_arch): Parse "jumps" arch modifier.
+ (insn_size): Modify usage comment.
+ (ENCODE_RELAX_STATE): Reformat and protect macro arg.
+ (SIZE_FROM_RELAX_STATE): Rename to DISP_SIZE_FROM_RELAX_STATE.
+ (TYPE_FROM_RELAX_STATE): New define.
+ (UNCOND_JUMP, COND_JUMP): Renumber.
+ (md_relax_table): Reorder to suit.
+ (COND_JUMP86): New define.
+ (md_relax_table): Handle COND_JUMP86 cases. Add a few comments.
+ (md_assemble): Create frag var for jumps of max size, encode relax
+ state for COND_JUMP86.
+ (md_estimate_size_before_relax): Handle COND_JUMP86 cases, and
+ leave conditional jumps small if no_cond_jump_promotion.
+ (md_convert_frag): Likewise.
+
+ 2001-05-10 Alan Modra <amodra@one.net.au>
+ * config/tc-v850.c (md_estimate_size_before_relax): Rewrite.
+ (md_convert_frag): Don't bother clearing fr_var.
+ (md_pseudo_table): Correct initialization.
+
+ 2001-05-12 Peter Targett <peter.targett@arccores.com>
+ * config/tc-arc.c: Update copyright and tidy source comments.
+ (md_pseudo_table): Add directive .cpu back as an alias for
+ .option. Add .file and .line for dwarf2 support.
+ (arc_mach_type): Make bfd_mach_arc_6 default.
+ (md_longopts): Add entry 'pre-v6' representing old command line
+ option when assembling for 'arc5' core versions.
+ (md_parse_option): Make OPTION_ARC same as OPTION_ARC6, for new
+ default behaviour.
+ (arc_code_symbol): Make symbol value for @h30 fixup expression
+ equal to O_constant.
+ (md_assemble): Call dwarf2_emit_insn.
+ Include "dwarf2dbg2.h". Formatting fixes throughout file.
+ * config/tc-arc.h (DWARF2_LINE_MIN_INSN_LENGTH): Define.
+ * doc/c-arc.texi (ARC_CORE_DEFAULT): Update to new default.
+
+ 2001-05-15 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-mn10300.c (mn10300_force_relocation): Don't
+ optimize differences between symbols in code sections to
+ constants.
+ (mn10300_fix_adjustable): Don't adjust to section+offset
+ relocations pointing at symbols in code sections.
+
+ 2001-05-14 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-mn10300.c (md_assemble): Anchor dwarf2 line info
+ before a relaxable insns.
+
+ 2001-05-13 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-mn10300.c (tc_gen_reloc): Don't reject differences
+ between symbols if the base symbol is in the current section;
+ emit a PC-relative relocation instead.
+
+ 2001-05-09 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-mn10300.c (md_apply_fix3): Accept PC-relative relocs.
+
+ 2001-05-06 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-mn10300.c (md_assemble): Subtract operand->shift
+ from offset in non-pcrel operands too.
+
+ 2001-04-14 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-mn10300.c (md_assemble): Simplify offset adjustment of
+ pc-relative relocations not placed at the end of the instruction.
+
+ 2001-04-06 Alexandre Oliva <aoliva@redhat.com>
+ * config/tc-mn10300.c (xr_registers): Added `pc'.
+
+ 2001-03-30 Alan Modra <alan@linuxcare.com.au>
+ * config/tc-mn10300.c (md_estimate_size_before_relax): Rewrite.
+
+ 2001-02-23 Richard Sandiford <rsandifo@redhat.com>
+ * config/tc-mn10300.c (md_apply_fix3): Don't mark a fixup as
+ done if it's against a symbol.
+
+ 2001-03-28 H.J. Lu <hjl@gnu.org>
+ * read.c (equals): Set to local for COFF only if it hasn't been
+ defined before.
+
+ 2001-03-27 Nick Papadonis <nick@coelacanth.com>
+ * read.c (equals): (for COFF) default symbols to being local.
+
+ 2001-03-23 Richard Sandiford <rsandifo@redhat.com>
+ * write.c (fix_new_exp): Print an error if passed a register.
+
+ 2001-03-20 Alan Modra <alan@linuxcare.com.au>
+ * frags.h (struct frag): Add relax_marker.
+ * write.c (is_dnrange): Delete.
+ (relax_frag): Use correct types for `aim', `target', `address'.
+ Delete `offset', `was_address'. Test `relax_marker' instead of
+ using fragile (and slow) address test.
+ (relax_segment): Init and flip `relax_marker'.
+
+ 2001-02-13 Ian Lance Taylor <ian@zembu.com>
+ * write.c (is_dnrange): Stop as soon as the address becomes
+ larger.
+ (relax_frag): Add segment parameter. Only call symbol_get_frag
+ once. Only call is_dnrange if the symbol is in the same segment,
+ and the symbol address is larger.
+ (relax_segment): Pass segment to md_relax_frag and relax_frag.
+ * write.h (relax_frag): Update declaration.
+ * config/tc-fr30.c (fr30_relax_frag): Add segment parameter. Pass
+ it to relax_frag.
+ * config/tc-m32r.c (m32r_relax_frag): Likewise.
+ * config/tc-m32r.h (md_relax_frag): Add segment parameter.
+ (m32r_relax_frag): Update declaration.
+ * config/tc-mips.h (md_relax_frag): Add segment parameter.
+ * config/tc-tic54x.h (md_relax_frag): Likewise.
+ * doc/internals.texi (CPU backend): Update documentation for
+ md_relax_frag.
+
+ 2001-03-15 DJ Delorie <dj@redhat.com>
+ * stabs.c (s_stab_generic): Don't corrupt the notes obstack by
+ blindly freeing string if it isn't at the top of the obstack.
+
2001-05-14 Richard Henderson <rth@redhat.com>
* ehopt.c (eh_frame_convert_frag): Fix missed subtype adjustment
* config/tc-i386.c (tc_i386_fix_adjustable): Fix GOTPCREL GOT
entry.
-001-02-18 David O'Brien <obrien@FreeBSD.org>
+2001-02-18 David O'Brien <obrien@FreeBSD.org>
* configure.in (cpu_type, arch): Add a generic FreeBSD specification as
all FreeBSD platforms should look the same at this level.
/* tc-arc.c -- Assembler for the ARC
- Copyright (C) 1994, 1995, 1997, 2000 Free Software Foundation, Inc.
+ Copyright 1994, 1995, 1997, 1999, 2000, 2001
+ Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com).
This file is part of GAS, the GNU Assembler.
#include "opcode/arc.h"
#include "../opcodes/arc-ext.h"
#include "elf/arc.h"
+#include "dwarf2dbg.h"
extern int arc_get_mach PARAMS ((char *));
extern int arc_operand_type PARAMS ((int));
#define MAXSYNTAXCLASS (sizeof (syntaxclass) / sizeof (struct syntax_classes))
const pseudo_typeS md_pseudo_table[] = {
- { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0) */
+ { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */
{ "comm", arc_common, 0 },
{ "common", arc_common, 0 },
{ "lcomm", arc_common, 1 },
{ "4byte", cons, 4 },
{ "word", cons, 4 },
{ "option", arc_option, 0 },
+ { "cpu", arc_option, 0 },
{ "block", s_space, 0 },
+ { "file", dwarf2_directive_file, 0 },
+ { "loc", dwarf2_directive_loc, 0 },
{ "extcondcode", arc_extoper, 0 },
{ "extcoreregister", arc_extoper, 1 },
{ "extauxregister", arc_extoper, 2 },
};
/* This array holds the chars that always start a comment. If the
- pre-processor is disabled, these aren't very useful */
+ 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
const char line_separator_chars[] = "";
-/* Chars that can be used to separate mant from exp in floating point nums */
+/* 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 */
+/* Chars that mean this number is a floating point constant
+ As in 0f12.456 or 0d1.2345e12. */
const char FLT_CHARS[] = "rRsSfFdD";
/* Byte order. */
static segT arcext_section;
/* One of bfd_mach_arc_n. */
-static int arc_mach_type = bfd_mach_arc_5;
+static int arc_mach_type = bfd_mach_arc_6;
/* Non-zero if the cpu type has been explicitly specified. */
static int mach_type_specified_p = 0;
/* Non-zero if opcode tables have been initialized.
- A .cpu command must appear before any instructions. */
+ A .option command must appear before any instructions. */
static int cpu_tables_init_p = 0;
static struct hash_control *arc_suffix_hash = NULL;
const char *md_shortopts = "";
struct option md_longopts[] = {
#define OPTION_EB (OPTION_MD_BASE + 0)
- {"EB", no_argument, NULL, OPTION_EB},
+ { "EB", no_argument, NULL, OPTION_EB },
#define OPTION_EL (OPTION_MD_BASE + 1)
- {"EL", no_argument, NULL, OPTION_EL},
+ { "EL", no_argument, NULL, OPTION_EL },
#define OPTION_ARC5 (OPTION_MD_BASE + 2)
- {"marc5", no_argument, NULL, OPTION_ARC5},
+ { "marc5", no_argument, NULL, OPTION_ARC5 },
+ { "pre-v6", no_argument, NULL, OPTION_ARC5 },
#define OPTION_ARC6 (OPTION_MD_BASE + 3)
- {"marc6", no_argument, NULL, OPTION_ARC6},
+ { "marc6", no_argument, NULL, OPTION_ARC6 },
#define OPTION_ARC7 (OPTION_MD_BASE + 4)
- {"marc7", no_argument, NULL, OPTION_ARC7},
+ { "marc7", no_argument, NULL, OPTION_ARC7 },
#define OPTION_ARC8 (OPTION_MD_BASE + 5)
- {"marc8", no_argument, NULL, OPTION_ARC8},
+ { "marc8", no_argument, NULL, OPTION_ARC8 },
#define OPTION_ARC (OPTION_MD_BASE + 6)
- {"marc", no_argument, NULL, OPTION_ARC},
+ { "marc", no_argument, NULL, OPTION_ARC },
{ NULL, no_argument, NULL, 0 }
};
size_t md_longopts_size = sizeof (md_longopts);
{
switch (c)
{
- case OPTION_ARC:
case OPTION_ARC5:
arc_mach_type = bfd_mach_arc_5;
break;
+ case OPTION_ARC:
case OPTION_ARC6:
arc_mach_type = bfd_mach_arc_6;
break;
/* 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
+ Opcode selection is deferred until later because we might see a .option
command. */
void
if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
as_warn ("could not set architecture and machine");
- /* This call is necessary because we need to
- initialize `arc_operand_map' which may be needed before we see the
- first insn. */
+ /* This call is necessary because we need to initialize `arc_operand_map'
+ which may be needed before we see the first insn. */
arc_opcode_init_tables (arc_get_opcode_mach (arc_mach_type,
target_big_endian));
}
/* Initialize the various opcode and operand tables.
MACH is one of bfd_mach_arc_xxx. */
-
static void
init_opcode_tables (mach)
int mach;
continue;
/* Use symbol_create here instead of symbol_new so we don't try to
output registers into the object file's symbol table. */
- symbol_table_insert (symbol_create (arc_reg_names[i].name, reg_section,
- (int) &arc_reg_names[i], &zero_address_frag));
+ symbol_table_insert (symbol_create (arc_reg_names[i].name,
+ reg_section,
+ (int) &arc_reg_names[i],
+ &zero_address_frag));
}
/* Tell `.option' it's too late. */
that would screw up references to ``.''. */
struct arc_fixup {
- /* index into `arc_operands' */
+ /* index into `arc_operands' */
int opindex;
expressionS exp;
};
static int init_tables_p = 0;
/* Opcode table initialization is deferred until here because we have to
- wait for a possible .cpu command. */
+ wait for a possible .option command. */
if (!init_tables_p)
{
init_opcode_tables (arc_mach_type);
/* 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')
+ if (is_end_of_line[(unsigned char) *str])
break;
/* Parse the operand. */
while (isspace (*str))
++str;
- if (*str != '\0')
+ if (!is_end_of_line[(unsigned char) *str])
as_bad ("junk at end of line: `%s'", str);
/* Is there a limm value? */
f = frag_more (8);
md_number_to_chars (f, insn, 4);
md_number_to_chars (f + 4, limm, 4);
+ dwarf2_emit_insn (8);
}
else if (limm_reloc_p)
{
{
f = frag_more (4);
md_number_to_chars (f, insn, 4);
+ dwarf2_emit_insn (4);
}
/* Create any fixups. */
p++;
}
- /* just after name is now '\0' */
+ /* just after name is now '\0' */
p = input_line_pointer;
*p = c;
SKIP_WHITESPACE ();
return;
}
- input_line_pointer++; /* skip ',' */
+ input_line_pointer++; /* skip ',' */
number = get_absolute_expression ();
if (number < 0)
return;
}
- input_line_pointer++; /* skip ',' */
+ input_line_pointer++; /* skip ',' */
mode = input_line_pointer;
if (!strncmp (mode, "r|w", 3))
return;
}
- input_line_pointer++; /* skip ',' */
+ input_line_pointer++; /* skip ',' */
if (!strncmp (input_line_pointer, "cannot_shortcut", 15))
{
strcpy (syntax, name);
name_len = strlen (name);
- /* just after name is now '\0' */
+ /* just after name is now '\0' */
p = input_line_pointer;
*p = c;
return;
}
- input_line_pointer++; /* skip ',' */
+ input_line_pointer++; /* skip ',' */
opcode = get_absolute_expression ();
SKIP_WHITESPACE ();
return;
}
- input_line_pointer++; /* skip ',' */
+ input_line_pointer++; /* skip ',' */
subopcode = get_absolute_expression ();
if (subopcode < 0)
return;
}
- input_line_pointer++; /* skip ',' */
+ input_line_pointer++; /* skip ',' */
for (i = 0; i < (int) MAXSUFFIXCLASS; i++)
{
return;
}
- input_line_pointer++; /* skip ',' */
+ input_line_pointer++; /* skip ',' */
for (i = 0; i < (int) MAXSYNTAXCLASS; i++)
{
name = input_line_pointer;
c = get_symbol_end ();
- /* just after name is now '\0' */
+ /* just after name is now '\0' */
p = input_line_pointer;
*p = c;
SKIP_WHITESPACE ();
return;
}
- input_line_pointer++; /* skip ',' */
+ input_line_pointer++; /* skip ',' */
size = get_absolute_expression ();
if (size < 0)
old_sec = now_seg;
old_subsec = now_subseg;
record_alignment (bss_section, align);
- subseg_set (bss_section, 0); /* ??? subseg_set (bss_section, 1); ??? */
+ subseg_set (bss_section, 0); /* ??? subseg_set (bss_section, 1); ??? */
if (align)
/* Do alignment. */
{
expressionS two;
expressionP->X_op = O_right_shift;
+ expressionP->X_add_symbol->sy_value.X_op = O_constant;
two.X_op = O_constant;
two.X_add_symbol = two.X_op_symbol = NULL;
two.X_add_number = 2;
expressionP->X_op_symbol = make_expr_symbol (&two);
}
- /* Allow %st(sym1-sym2) */
+ /* Allow %st(sym1-sym2) */
else if (expressionP->X_op == O_subtract
&& expressionP->X_add_symbol != NULL
&& expressionP->X_op_symbol != NULL
arc_code_symbol (expressionP);
}
else
- { /* It could be a register. */
+ {
+ /* It could be a register. */
int i, l;
struct arc_ext_operand_value *ext_oper = arc_ext_operands;
p++;
/* tc-arc.h - Macros and type defines for the ARC.
- Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
+ Copyright 1994, 1995, 1997, 2000, 2001 Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com).
This file is part of GAS, the GNU Assembler.
extern void arc_cons_fix_new ();
#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \
arc_cons_fix_new (FRAG, WHERE, NBYTES, EXP)
+
+#define DWARF2_LINE_MIN_INSN_LENGTH 4
/* tc-fr30.c -- Assembler for the Fujitsu FR30.
- Copyright (C) 1998, 1999, 2000 Free Software Foundation.
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
};
long
-fr30_relax_frag (fragP, stretch)
+fr30_relax_frag (segment, fragP, stretch)
+ segT segment;
fragS * fragP;
long stretch;
{
}
else
{
- growth = relax_frag (fragP, stretch);
+ growth = relax_frag (segment, fragP, stretch);
/* Long jump on odd halfword boundary? */
if (fragP->fr_subtype == 2 && (address & 3) != 0)
/* i386.c -- Assemble code for the Intel 80386
- Copyright (C) 1989, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001
+ Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
#ifdef BFD_ASSEMBLER
static bfd_reloc_code_real_type reloc
PARAMS ((int, int, int, bfd_reloc_code_real_type));
+#define RELOC_ENUM enum bfd_reloc_code_real
+#else
+#define RELOC_ENUM int
#endif
#ifndef DEFAULT_ARCH
#define Operand_PCrel 1
/* Relocation type for operand */
-#ifdef BFD_ASSEMBLER
- enum bfd_reloc_code_real disp_reloc[MAX_OPERANDS];
-#else
- int disp_reloc[MAX_OPERANDS];
-#endif
+ RELOC_ENUM reloc[MAX_OPERANDS];
/* BASE_REG, INDEX_REG, and LOG2_SCALE_FACTOR are used to encode
the base index byte below. */
CODE_32BIT,
CODE_16BIT,
CODE_64BIT };
+#define NUM_FLAG_CODE ((int) CODE_64BIT + 1)
static enum flag_code flag_code;
static int use_rela_relocations = 0;
/* CPU feature flags. */
static unsigned int cpu_arch_flags = CpuUnknownFlags|CpuNo64;
+/* If set, conditional jumps are not automatically promoted to handle
+ larger than a byte offset. */
+static unsigned int no_cond_jump_promotion = 0;
+
/* Interface to relax_segment.
- There are 2 relax states for 386 jump insns: one for conditional &
- one for unconditional jumps. This is because these two types of
- jumps add different sizes to frags when we're figuring out what
- sort of jump to choose to reach a given label. */
+ There are 3 major relax states for 386 jump insns because the
+ different types of jumps add different sizes to frags when we're
+ figuring out what sort of jump to choose to reach a given label. */
/* Types. */
+#define UNCOND_JUMP 0
#define COND_JUMP 1
-#define UNCOND_JUMP 2
+#define COND_JUMP86 2
+
/* Sizes. */
#define CODE16 1
#define SMALL 0
#endif
#endif
-#define ENCODE_RELAX_STATE(type,size) \
- ((relax_substateT) ((type<<2) | (size)))
-#define SIZE_FROM_RELAX_STATE(s) \
- ( (((s) & 0x3) == BIG ? 4 : (((s) & 0x3) == BIG16 ? 2 : 1)) )
+#define ENCODE_RELAX_STATE(type, size) \
+ ((relax_substateT) (((type) << 2) | (size)))
+#define TYPE_FROM_RELAX_STATE(s) \
+ ((s) >> 2)
+#define DISP_SIZE_FROM_RELAX_STATE(s) \
+ ((((s) & 3) == BIG ? 4 : (((s) & 3) == BIG16 ? 2 : 1)))
/* This table is used by relax_frag to promote short jumps to long
ones where necessary. SMALL (short) jumps may be promoted to BIG
/* 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
+ 3) how many bytes this mode will have in the variable part of the frag
4) which index into the table to try if we can't fit into this one. */
- {1, 1, 0, 0},
- {1, 1, 0, 0},
- {1, 1, 0, 0},
- {1, 1, 0, 0},
-
- {127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (COND_JUMP, BIG)},
- {127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (COND_JUMP, BIG16)},
- /* dword conditionals adds 4 bytes to frag:
- 1 extra opcode byte, 3 extra displacement bytes. */
+
+ /* UNCOND_JUMP states. */
+ {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG)},
+ {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16)},
+ /* dword jmp adds 4 bytes to frag:
+ 0 extra opcode bytes, 4 displacement bytes. */
{0, 0, 4, 0},
- /* word conditionals add 2 bytes to frag:
- 1 extra opcode byte, 1 extra displacement byte. */
+ /* word jmp adds 2 byte2 to frag:
+ 0 extra opcode bytes, 2 displacement bytes. */
{0, 0, 2, 0},
- {127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG)},
- {127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16)},
- /* dword jmp adds 3 bytes to frag:
- 0 extra opcode bytes, 3 extra displacement bytes. */
+ /* COND_JUMP states. */
+ {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG)},
+ {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG16)},
+ /* dword conditionals adds 5 bytes to frag:
+ 1 extra opcode byte, 4 displacement bytes. */
+ {0, 0, 5, 0},
+ /* word conditionals add 3 bytes to frag:
+ 1 extra opcode byte, 2 displacement bytes. */
{0, 0, 3, 0},
- /* word jmp adds 1 byte to frag:
- 0 extra opcode bytes, 1 extra displacement byte. */
- {0, 0, 1, 0}
+ /* COND_JUMP86 states. */
+ {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG)},
+ {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG16)},
+ /* dword conditionals adds 5 bytes to frag:
+ 1 extra opcode byte, 4 displacement bytes. */
+ {0, 0, 5, 0},
+ /* word conditionals add 4 bytes to frag:
+ 1 displacement byte and a 3 byte long branch insn. */
+ {0, 0, 4, 0}
};
static const arch_entry cpu_arch[] = {
if (strcmp (string, cpu_arch[i].name) == 0)
{
cpu_arch_name = cpu_arch[i].name;
- cpu_arch_flags = cpu_arch[i].flags | (flag_code == CODE_64BIT ? Cpu64 : CpuNo64);
+ cpu_arch_flags = (cpu_arch[i].flags
+ | (flag_code == CODE_64BIT ? Cpu64 : CpuNo64));
break;
}
}
else
as_bad (_("missing cpu architecture"));
+ no_cond_jump_promotion = 0;
+ if (*input_line_pointer == ','
+ && ! is_end_of_line[(unsigned char) input_line_pointer[1]])
+ {
+ char *string = ++input_line_pointer;
+ int e = get_symbol_end ();
+
+ if (strcmp (string, "nojumps") == 0)
+ no_cond_jump_promotion = 1;
+ else if (strcmp (string, "jumps") == 0)
+ ;
+ else
+ as_bad (_("no such architecture modifier: `%s'"), string);
+
+ *input_line_pointer = e;
+ }
+
demand_empty_rest_of_line ();
}
/* Points to template once we've found it. */
const template *t;
- /* Count the size of the instruction generated. */
- int insn_size = 0;
-
int j;
char mnemonic[MAX_MNEM_SIZE];
/* Initialize globals. */
memset (&i, '\0', sizeof (i));
for (j = 0; j < MAX_OPERANDS; j++)
- i.disp_reloc[j] = NO_RELOC;
+ i.reloc[j] = NO_RELOC;
memset (disp_expressions, '\0', sizeof (disp_expressions));
memset (im_expressions, '\0', sizeof (im_expressions));
save_stack_p = save_stack;
{
union i386_op temp_op;
unsigned int temp_type;
-#ifdef BFD_ASSEMBLER
- enum bfd_reloc_code_real temp_reloc;
-#else
- int temp_reloc;
-#endif
+ RELOC_ENUM temp_reloc;
int xchg1 = 0;
int xchg2 = 0;
temp_op = i.op[xchg2];
i.op[xchg2] = i.op[xchg1];
i.op[xchg1] = temp_op;
- temp_reloc = i.disp_reloc[xchg2];
- i.disp_reloc[xchg2] = i.disp_reloc[xchg1];
- i.disp_reloc[xchg1] = temp_reloc;
+ temp_reloc = i.reloc[xchg2];
+ i.reloc[xchg2] = i.reloc[xchg1];
+ i.reloc[xchg1] = temp_reloc;
if (i.mem_operands == 2)
{
for (op = i.operands; --op >= 0;)
if ((i.types[op] & Disp)
- && i.op[op].imms->X_op == O_constant)
+ && i.op[op].disps->X_op == O_constant)
{
offsetT disp = i.op[op].disps->X_add_number;
{
register char *p;
+ /* Tie dwarf2 debug info to the address at the start of the insn.
+ We can't do this after the insn has been output as the current
+ frag may have been closed off. eg. by frag_var. */
+ dwarf2_emit_insn (0);
+
/* Output jumps. */
if (i.tm.opcode_modifier & Jump)
{
- int size;
int code16;
int prefix;
i.prefixes--;
}
- size = 4;
- if (code16)
- size = 2;
-
if (i.prefixes != 0 && !intel_syntax)
as_warn (_("skipping prefixes on this instruction"));
instruction we may generate in md_convert_frag. This is 2
bytes for the opcode and room for the prefix and largest
displacement. */
- frag_grow (prefix + 2 + size);
- insn_size += prefix + 1;
+ frag_grow (prefix + 2 + 4);
/* Prefix and 1 opcode byte go in fr_fix. */
p = frag_more (prefix + 1);
if (i.prefix[DATA_PREFIX])
/* 1 possible extra opcode + displacement go in var part.
Pass reloc in fr_var. */
frag_var (rs_machine_dependent,
- 1 + size,
- i.disp_reloc[0],
+ 1 + 4,
+ i.reloc[0],
((unsigned char) *p == JUMP_PC_RELATIVE
? ENCODE_RELAX_STATE (UNCOND_JUMP, SMALL) | code16
- : ENCODE_RELAX_STATE (COND_JUMP, SMALL) | code16),
+ : ((cpu_arch_flags & Cpu386) != 0
+ ? ENCODE_RELAX_STATE (COND_JUMP, SMALL) | code16
+ : ENCODE_RELAX_STATE (COND_JUMP86, SMALL) | code16)),
i.op[0].disps->X_add_symbol,
i.op[0].disps->X_add_number,
p);
size = 1;
if (i.prefix[ADDR_PREFIX])
{
- insn_size += 1;
FRAG_APPEND_1_CHAR (ADDR_PREFIX_OPCODE);
i.prefixes -= 1;
}
if (i.prefix[DATA_PREFIX])
{
- insn_size += 1;
FRAG_APPEND_1_CHAR (DATA_PREFIX_OPCODE);
i.prefixes -= 1;
code16 ^= CODE16;
if (i.prefix[REX_PREFIX])
{
FRAG_APPEND_1_CHAR (i.prefix[REX_PREFIX]);
- insn_size++;
i.prefixes -= 1;
}
if (fits_in_unsigned_byte (i.tm.base_opcode))
{
- insn_size += 1 + size;
p = frag_more (1 + size);
}
else
{
/* Opcode can be at most two bytes. */
- insn_size += 2 + size;
p = frag_more (2 + size);
*p++ = (i.tm.base_opcode >> 8) & 0xff;
}
*p++ = i.tm.base_opcode & 0xff;
fix_new_exp (frag_now, p - frag_now->fr_literal, size,
- i.op[0].disps, 1, reloc (size, 1, 1, i.disp_reloc[0]));
+ i.op[0].disps, 1, reloc (size, 1, 1, i.reloc[0]));
}
else if (i.tm.opcode_modifier & JumpInterSegment)
{
as_warn (_("skipping prefixes on this instruction"));
/* 1 opcode; 2 segment; offset */
- insn_size += prefix + 1 + 2 + size;
p = frag_more (prefix + 1 + 2 + size);
if (i.prefix[DATA_PREFIX])
}
else
fix_new_exp (frag_now, p - frag_now->fr_literal, size,
- i.op[1].imms, 0, reloc (size, 0, 0, i.disp_reloc[0]));
+ i.op[1].imms, 0, reloc (size, 0, 0, i.reloc[1]));
if (i.op[0].imms->X_op != O_constant)
as_bad (_("can't handle non absolute segment in `%s'"),
i.tm.name);
{
if (*q)
{
- insn_size += 1;
p = frag_more (1);
md_number_to_chars (p, (valueT) *q, 1);
}
/* Now the opcode; be careful about word order here! */
if (fits_in_unsigned_byte (i.tm.base_opcode))
{
- insn_size += 1;
FRAG_APPEND_1_CHAR (i.tm.base_opcode);
}
else
{
- insn_size += 2;
p = frag_more (2);
/* Put out high byte first: can't use md_number_to_chars! */
*p++ = (i.tm.base_opcode >> 8) & 0xff;
/* Now the modrm byte and sib byte (if present). */
if (i.tm.opcode_modifier & Modrm)
{
- insn_size += 1;
p = frag_more (1);
md_number_to_chars (p,
(valueT) (i.rm.regmem << 0
&& i.rm.mode != 3
&& !(i.base_reg && (i.base_reg->reg_type & Reg16) != 0))
{
- insn_size += 1;
p = frag_more (1);
md_number_to_chars (p,
(valueT) (i.sib.base << 0
}
val = offset_in_range (i.op[n].disps->X_add_number,
size);
- insn_size += size;
p = frag_more (size);
md_number_to_chars (p, val, size);
}
size = 8;
}
- insn_size += size;
p = frag_more (size);
fix_new_exp (frag_now, p - frag_now->fr_literal, size,
i.op[n].disps, pcrel,
- reloc (size, pcrel, sign, i.disp_reloc[n]));
+ reloc (size, pcrel, sign, i.reloc[n]));
}
}
}
}
val = offset_in_range (i.op[n].imms->X_add_number,
size);
- insn_size += size;
p = frag_more (size);
md_number_to_chars (p, val, size);
}
Need a 32-bit fixup (don't support 8bit
non-absolute imms). Try to support other
sizes ... */
-#ifdef BFD_ASSEMBLER
- enum bfd_reloc_code_real reloc_type;
-#else
- int reloc_type;
-#endif
+ RELOC_ENUM reloc_type;
int size = 4;
int sign = 0;
size = 8;
}
- insn_size += size;
p = frag_more (size);
- reloc_type = reloc (size, 0, sign, i.disp_reloc[0]);
+ reloc_type = reloc (size, 0, sign, i.reloc[n]);
#ifdef BFD_ASSEMBLER
if (reloc_type == BFD_RELOC_32
&& GOT_symbol
}
}
- dwarf2_emit_insn (insn_size);
-
#ifdef DEBUG386
if (flag_debug)
{
}
}
\f
+#ifndef LEX_AT
+static char *lex_got PARAMS ((RELOC_ENUM *, int *));
+
+/* Parse operands of the form
+ <symbol>@GOTOFF+<nnn>
+ and similar .plt or .got references.
+
+ If we find one, set up the correct relocation in RELOC and copy the
+ input string, minus the `@GOTOFF' into a malloc'd buffer for
+ parsing by the calling routine. Return this buffer, and if ADJUST
+ is non-null set it to the length of the string we removed from the
+ input line. Otherwise return NULL. */
+static char *
+lex_got (reloc, adjust)
+ RELOC_ENUM *reloc;
+ int *adjust;
+{
+ static const char * const mode_name[NUM_FLAG_CODE] = { "32", "16", "64" };
+ static const struct {
+ const char *str;
+ const RELOC_ENUM rel[NUM_FLAG_CODE];
+ } gotrel[] = {
+ { "PLT", { BFD_RELOC_386_PLT32, 0, BFD_RELOC_X86_64_PLT32 } },
+ { "GOTOFF", { BFD_RELOC_386_GOTOFF, 0, 0 } },
+ { "GOTPCREL", { 0, 0, BFD_RELOC_X86_64_GOTPCREL } },
+ { "GOT", { BFD_RELOC_386_GOT32, 0, BFD_RELOC_X86_64_GOT32 } }
+ };
+ char *cp;
+ unsigned int j;
+
+ for (cp = input_line_pointer; *cp != '@'; cp++)
+ if (is_end_of_line[(unsigned char) *cp])
+ return NULL;
+
+ for (j = 0; j < sizeof (gotrel) / sizeof (gotrel[0]); j++)
+ {
+ int len;
+
+ len = strlen (gotrel[j].str);
+ if (strncmp (cp + 1, gotrel[j].str, len) == 0)
+ {
+ if (gotrel[j].rel[(unsigned int) flag_code] != 0)
+ {
+ int first;
+ char *tmpbuf;
+
+ *reloc = gotrel[j].rel[(unsigned int) flag_code];
+
+ if (GOT_symbol == NULL)
+ GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
+
+ /* Replace the relocation token with ' ', so that
+ errors like foo@GOTOFF1 will be detected. */
+ first = cp - input_line_pointer;
+ tmpbuf = xmalloc (strlen (input_line_pointer));
+ memcpy (tmpbuf, input_line_pointer, first);
+ tmpbuf[first] = ' ';
+ strcpy (tmpbuf + first + 1, cp + 1 + len);
+ if (adjust)
+ *adjust = len;
+ return tmpbuf;
+ }
+
+ as_bad (_("@%s reloc is not supported in %s bit mode"),
+ gotrel[j].str, mode_name[(unsigned int) flag_code]);
+ return NULL;
+ }
+ }
+
+ /* Might be a symbol version string. Don't as_bad here. */
+ return NULL;
+}
+
+/* x86_cons_fix_new is called via the expression parsing code when a
+ reloc is needed. We use this hook to get the correct .got reloc. */
+static RELOC_ENUM got_reloc = NO_RELOC;
+
+void
+x86_cons_fix_new (frag, off, len, exp)
+ fragS *frag;
+ unsigned int off;
+ unsigned int len;
+ expressionS *exp;
+{
+ RELOC_ENUM r = reloc (len, 0, 0, got_reloc);
+ got_reloc = NO_RELOC;
+ fix_new_exp (frag, off, len, exp, 0, r);
+}
+
+void
+x86_cons (exp, size)
+ expressionS *exp;
+ int size;
+{
+ if (size == 4)
+ {
+ /* Handle @GOTOFF and the like in an expression. */
+ char *save;
+ char *gotfree_input_line;
+ int adjust;
+
+ save = input_line_pointer;
+ gotfree_input_line = lex_got (&got_reloc, &adjust);
+ if (gotfree_input_line)
+ input_line_pointer = gotfree_input_line;
+
+ expression (exp);
+
+ if (gotfree_input_line)
+ {
+ /* expression () has merrily parsed up to the end of line,
+ or a comma - in the wrong buffer. Transfer how far
+ input_line_pointer has moved to the right buffer. */
+ input_line_pointer = (save
+ + (input_line_pointer - gotfree_input_line)
+ + adjust);
+ free (gotfree_input_line);
+ }
+ }
+ else
+ expression (exp);
+}
+#endif
+
static int i386_immediate PARAMS ((char *));
static int
char *imm_start;
{
char *save_input_line_pointer;
+#ifndef LEX_AT
+ char *gotfree_input_line;
+#endif
segT exp_seg = 0;
expressionS *exp;
input_line_pointer = imm_start;
#ifndef LEX_AT
- {
- /* We can have operands of the form
- <symbol>@GOTOFF+<nnn>
- Take the easy way out here and copy everything
- into a temporary buffer... */
- register char *cp;
-
- cp = strchr (input_line_pointer, '@');
- if (cp != NULL)
- {
- char *tmpbuf;
- int len = 0;
- int first;
-
- /* GOT relocations are not supported in 16 bit mode. */
- if (flag_code == CODE_16BIT)
- as_bad (_("GOT relocations not supported in 16 bit mode"));
-
- if (GOT_symbol == NULL)
- GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
-
- if (strncmp (cp + 1, "PLT", 3) == 0)
- {
- if (flag_code == CODE_64BIT)
- i.disp_reloc[this_operand] = BFD_RELOC_X86_64_PLT32;
- else
- i.disp_reloc[this_operand] = BFD_RELOC_386_PLT32;
- len = 3;
- }
- else if (strncmp (cp + 1, "GOTOFF", 6) == 0)
- {
- if (flag_code == CODE_64BIT)
- as_bad ("GOTOFF relocations are unsupported in 64bit mode.");
- i.disp_reloc[this_operand] = BFD_RELOC_386_GOTOFF;
- len = 6;
- }
- else if (strncmp (cp + 1, "GOTPCREL", 8) == 0)
- {
- if (flag_code == CODE_64BIT)
- i.disp_reloc[this_operand] = BFD_RELOC_X86_64_GOTPCREL;
- else
- as_bad ("GOTPCREL relocations are supported only in 64bit mode.");
- len = 8;
- }
- else if (strncmp (cp + 1, "GOT", 3) == 0)
- {
- if (flag_code == CODE_64BIT)
- i.disp_reloc[this_operand] = BFD_RELOC_X86_64_GOT32;
- else
- i.disp_reloc[this_operand] = BFD_RELOC_386_GOT32;
- len = 3;
- }
- else
- as_bad (_("bad reloc specifier in expression"));
-
- /* Replace the relocation token with ' ', so that errors like
- foo@GOTOFF1 will be detected. */
- first = cp - input_line_pointer;
- tmpbuf = (char *) alloca (strlen (input_line_pointer));
- memcpy (tmpbuf, input_line_pointer, first);
- tmpbuf[first] = ' ';
- strcpy (tmpbuf + first + 1, cp + 1 + len);
- input_line_pointer = tmpbuf;
- }
- }
+ gotfree_input_line = lex_got (&i.reloc[this_operand], NULL);
+ if (gotfree_input_line)
+ input_line_pointer = gotfree_input_line;
#endif
exp_seg = expression (exp);
SKIP_WHITESPACE ();
if (*input_line_pointer)
- as_bad (_("ignoring junk `%s' after expression"), input_line_pointer);
+ as_bad (_("junk `%s' after expression"), input_line_pointer);
input_line_pointer = save_input_line_pointer;
+#ifndef LEX_AT
+ if (gotfree_input_line)
+ free (gotfree_input_line);
+#endif
if (exp->X_op == O_absent || exp->X_op == O_big)
{
return 1;
}
-static int i386_scale PARAMS ((char *));
+static char *i386_scale PARAMS ((char *));
-static int
+static char *
i386_scale (scale)
char *scale;
{
- if (!isdigit (*scale))
- goto bad_scale;
+ offsetT val;
+ char *save = input_line_pointer;
+
+ input_line_pointer = scale;
+ val = get_absolute_expression ();
- switch (*scale)
+ switch (val)
{
- case '0':
- case '1':
+ case 0:
+ case 1:
i.log2_scale_factor = 0;
break;
- case '2':
+ case 2:
i.log2_scale_factor = 1;
break;
- case '4':
+ case 4:
i.log2_scale_factor = 2;
break;
- case '8':
+ case 8:
i.log2_scale_factor = 3;
break;
default:
- bad_scale:
as_bad (_("expecting scale factor of 1, 2, 4, or 8: got `%s'"),
scale);
- return 0;
+ input_line_pointer = save;
+ return NULL;
}
if (i.log2_scale_factor != 0 && ! i.index_reg)
{
i.log2_scale_factor = 0;
#endif
}
- return 1;
+ scale = input_line_pointer;
+ input_line_pointer = save;
+ return scale;
}
static int i386_displacement PARAMS ((char *, char *));
register expressionS *exp;
segT exp_seg = 0;
char *save_input_line_pointer;
+#ifndef LEX_AT
+ char *gotfree_input_line;
+#endif
int bigdisp = Disp32;
if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0))
}
#endif
#ifndef LEX_AT
- {
- /* We can have operands of the form
- <symbol>@GOTOFF+<nnn>
- Take the easy way out here and copy everything
- into a temporary buffer... */
- register char *cp;
-
- cp = strchr (input_line_pointer, '@');
- if (cp != NULL)
- {
- char *tmpbuf;
- int len = 0;
- int first;
-
- /* GOT relocations are not supported in 16 bit mode. */
- if (flag_code == CODE_16BIT)
- as_bad (_("GOT relocations not supported in 16 bit mode"));
-
- if (GOT_symbol == NULL)
- GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
-
- if (strncmp (cp + 1, "PLT", 3) == 0)
- {
- if (flag_code == CODE_64BIT)
- i.disp_reloc[this_operand] = BFD_RELOC_X86_64_PLT32;
- else
- i.disp_reloc[this_operand] = BFD_RELOC_386_PLT32;
- len = 3;
- }
- else if (strncmp (cp + 1, "GOTOFF", 6) == 0)
- {
- if (flag_code == CODE_64BIT)
- as_bad ("GOTOFF relocation is not supported in 64bit mode.");
- i.disp_reloc[this_operand] = BFD_RELOC_386_GOTOFF;
- len = 6;
- }
- else if (strncmp (cp + 1, "GOTPCREL", 8) == 0)
- {
- if (flag_code != CODE_64BIT)
- as_bad ("GOTPCREL relocation is supported only in 64bit mode.");
- i.disp_reloc[this_operand] = BFD_RELOC_X86_64_GOTPCREL;
- len = 8;
- }
- else if (strncmp (cp + 1, "GOT", 3) == 0)
- {
- if (flag_code == CODE_64BIT)
- i.disp_reloc[this_operand] = BFD_RELOC_X86_64_GOT32;
- else
- i.disp_reloc[this_operand] = BFD_RELOC_386_GOT32;
- len = 3;
- }
- else
- as_bad (_("bad reloc specifier in expression"));
-
- /* Replace the relocation token with ' ', so that errors like
- foo@GOTOFF1 will be detected. */
- first = cp - input_line_pointer;
- tmpbuf = (char *) alloca (strlen (input_line_pointer));
- memcpy (tmpbuf, input_line_pointer, first);
- tmpbuf[first] = ' ';
- strcpy (tmpbuf + first + 1, cp + 1 + len);
- input_line_pointer = tmpbuf;
- }
- }
+ gotfree_input_line = lex_got (&i.reloc[this_operand], NULL);
+ if (gotfree_input_line)
+ input_line_pointer = gotfree_input_line;
#endif
exp_seg = expression (exp);
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer)
+ as_bad (_("junk `%s' after expression"), input_line_pointer);
+#if GCC_ASM_O_HACK
+ RESTORE_END_STRING (disp_end + 1);
+#endif
+ RESTORE_END_STRING (disp_end);
+ input_line_pointer = save_input_line_pointer;
+#ifndef LEX_AT
+ if (gotfree_input_line)
+ free (gotfree_input_line);
+#endif
+
#ifdef BFD_ASSEMBLER
/* We do this to make sure that the section symbol is in
the symbol table. We will ultimately change the relocation
to be relative to the beginning of the section. */
- if (i.disp_reloc[this_operand] == BFD_RELOC_386_GOTOFF
- || i.disp_reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL)
+ if (i.reloc[this_operand] == BFD_RELOC_386_GOTOFF
+ || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL)
{
+ if (exp->X_op != O_symbol)
+ {
+ as_bad (_("bad expression used with @%s"),
+ (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL
+ ? "GOTPCREL"
+ : "GOTOFF"));
+ return 0;
+ }
+
if (S_IS_LOCAL (exp->X_add_symbol)
&& S_GET_SEGMENT (exp->X_add_symbol) != undefined_section)
section_symbol (S_GET_SEGMENT (exp->X_add_symbol));
- assert (exp->X_op == O_symbol);
exp->X_op = O_subtract;
exp->X_op_symbol = GOT_symbol;
- if (i.disp_reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL)
- i.disp_reloc[this_operand] = BFD_RELOC_32_PCREL;
+ if (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL)
+ i.reloc[this_operand] = BFD_RELOC_32_PCREL;
else
- i.disp_reloc[this_operand] = BFD_RELOC_32;
+ i.reloc[this_operand] = BFD_RELOC_32;
}
#endif
- SKIP_WHITESPACE ();
- if (*input_line_pointer)
- as_bad (_("ignoring junk `%s' after expression"),
- input_line_pointer);
-#if GCC_ASM_O_HACK
- RESTORE_END_STRING (disp_end + 1);
-#endif
- RESTORE_END_STRING (disp_end);
- input_line_pointer = save_input_line_pointer;
-
if (exp->X_op == O_absent || exp->X_op == O_big)
{
/* Missing or bad expr becomes absolute 0. */
}
/* Check for scale factor. */
- if (isdigit ((unsigned char) *base_string))
+ if (*base_string != ')')
{
- if (!i386_scale (base_string))
+ char *end_scale = i386_scale (base_string);
+
+ if (!end_scale)
return 0;
- ++base_string;
+ base_string = end_scale;
if (is_space_char (*base_string))
++base_string;
if (*base_string != ')')
/* Symbol is undefined in this segment, or we need to keep a
reloc so that weak symbols can be overridden. */
int size = (fragP->fr_subtype & CODE16) ? 2 : 4;
-#ifdef BFD_ASSEMBLER
- enum bfd_reloc_code_real reloc_type;
-#else
- int reloc_type;
-#endif
+ RELOC_ENUM reloc_type;
unsigned char *opcode;
int old_fr_fix;
old_fr_fix = fragP->fr_fix;
opcode = (unsigned char *) fragP->fr_opcode;
- switch (opcode[0])
+ switch (TYPE_FROM_RELAX_STATE (fragP->fr_subtype))
{
- case JUMP_PC_RELATIVE:
- /* Make jmp (0xeb) a dword displacement jump. */
+ case UNCOND_JUMP:
+ /* Make jmp (0xeb) a (d)word displacement jump. */
opcode[0] = 0xe9;
fragP->fr_fix += size;
fix_new (fragP, old_fr_fix, size,
reloc_type);
break;
- default:
+ case COND_JUMP86:
+ if (no_cond_jump_promotion)
+ goto relax_guess;
+
+ if (size == 2)
+ {
+ /* Negate the condition, and branch past an
+ unconditional jump. */
+ opcode[0] ^= 1;
+ opcode[1] = 3;
+ /* Insert an unconditional jump. */
+ opcode[2] = 0xe9;
+ /* We added two extra opcode bytes, and have a two byte
+ offset. */
+ fragP->fr_fix += 2 + 2;
+ fix_new (fragP, old_fr_fix + 2, 2,
+ fragP->fr_symbol,
+ fragP->fr_offset, 1,
+ reloc_type);
+ break;
+ }
+ /* Fall through. */
+
+ case COND_JUMP:
+ if (no_cond_jump_promotion)
+ goto relax_guess;
+
/* This changes the byte-displacement jump 0x7N
- to the dword-displacement jump 0x0f,0x8N. */
+ to the (d)word-displacement jump 0x0f,0x8N. */
opcode[1] = opcode[0] + 0x10;
opcode[0] = TWO_BYTE_OPCODE_ESCAPE;
/* We've added an opcode byte. */
fragP->fr_offset, 1,
reloc_type);
break;
+
+ default:
+ BAD_CASE (fragP->fr_subtype);
+ break;
}
frag_wane (fragP);
return fragP->fr_fix - old_fr_fix;
}
- /* Guess a short jump. */
- return 1;
+
+ relax_guess:
+ /* Guess size depending on current relax state. Initially the relax
+ state will correspond to a short jump and we return 1, because
+ the variable part of the frag (the branch offset) is one byte
+ long. However, we can relax a section more than once and in that
+ case we must either set fr_subtype back to the unrelaxed state,
+ or return the value for the appropriate branch. */
+ return md_relax_table[fragP->fr_subtype].rlx_length;
}
/* Called after relax() is finished.
#ifdef BFD_ASSEMBLER
/* Not needed otherwise? */
{
- /* Local symbols which have already been resolved have a NULL frags. */
+ /* Local symbols which have already been resolved have a NULL frag. */
fragS *sym_frag = symbol_get_frag (fragP->fr_symbol);
if (sym_frag)
target_address += sym_frag->fr_address;
/* Displacement from opcode start to fill into instruction. */
displacement_from_opcode_start = target_address - opcode_address;
- switch (fragP->fr_subtype)
+ if ((fragP->fr_subtype & BIG) == 0)
{
- case ENCODE_RELAX_STATE (COND_JUMP, SMALL):
- case ENCODE_RELAX_STATE (COND_JUMP, SMALL16):
- case ENCODE_RELAX_STATE (UNCOND_JUMP, SMALL):
- case ENCODE_RELAX_STATE (UNCOND_JUMP, SMALL16):
/* Don't have to change opcode. */
extension = 1; /* 1 opcode + 1 displacement */
where_to_put_displacement = &opcode[1];
- break;
+ }
+ else
+ {
+ if (no_cond_jump_promotion
+ && TYPE_FROM_RELAX_STATE (fragP->fr_subtype) != UNCOND_JUMP)
+ as_warn_where (fragP->fr_file, fragP->fr_line, _("long jump required"));
- case ENCODE_RELAX_STATE (COND_JUMP, BIG):
- extension = 5; /* 2 opcode + 4 displacement */
- opcode[1] = opcode[0] + 0x10;
- opcode[0] = TWO_BYTE_OPCODE_ESCAPE;
- where_to_put_displacement = &opcode[2];
- break;
+ switch (fragP->fr_subtype)
+ {
+ case ENCODE_RELAX_STATE (UNCOND_JUMP, BIG):
+ extension = 4; /* 1 opcode + 4 displacement */
+ opcode[0] = 0xe9;
+ where_to_put_displacement = &opcode[1];
+ break;
- case ENCODE_RELAX_STATE (UNCOND_JUMP, BIG):
- extension = 4; /* 1 opcode + 4 displacement */
- opcode[0] = 0xe9;
- where_to_put_displacement = &opcode[1];
- break;
+ case ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16):
+ extension = 2; /* 1 opcode + 2 displacement */
+ opcode[0] = 0xe9;
+ where_to_put_displacement = &opcode[1];
+ break;
- case ENCODE_RELAX_STATE (COND_JUMP, BIG16):
- extension = 3; /* 2 opcode + 2 displacement */
- opcode[1] = opcode[0] + 0x10;
- opcode[0] = TWO_BYTE_OPCODE_ESCAPE;
- where_to_put_displacement = &opcode[2];
- break;
+ case ENCODE_RELAX_STATE (COND_JUMP, BIG):
+ case ENCODE_RELAX_STATE (COND_JUMP86, BIG):
+ extension = 5; /* 2 opcode + 4 displacement */
+ opcode[1] = opcode[0] + 0x10;
+ opcode[0] = TWO_BYTE_OPCODE_ESCAPE;
+ where_to_put_displacement = &opcode[2];
+ break;
- case ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16):
- extension = 2; /* 1 opcode + 2 displacement */
- opcode[0] = 0xe9;
- where_to_put_displacement = &opcode[1];
- break;
+ case ENCODE_RELAX_STATE (COND_JUMP, BIG16):
+ extension = 3; /* 2 opcode + 2 displacement */
+ opcode[1] = opcode[0] + 0x10;
+ opcode[0] = TWO_BYTE_OPCODE_ESCAPE;
+ where_to_put_displacement = &opcode[2];
+ break;
- default:
- BAD_CASE (fragP->fr_subtype);
- break;
+ case ENCODE_RELAX_STATE (COND_JUMP86, BIG16):
+ extension = 4;
+ opcode[0] ^= 1;
+ opcode[1] = 3;
+ opcode[2] = 0xe9;
+ where_to_put_displacement = &opcode[3];
+ break;
+
+ default:
+ BAD_CASE (fragP->fr_subtype);
+ break;
+ }
}
+
/* Now put displacement after opcode. */
md_number_to_chars ((char *) where_to_put_displacement,
(valueT) (displacement_from_opcode_start - extension),
- SIZE_FROM_RELAX_STATE (fragP->fr_subtype));
+ DISP_SIZE_FROM_RELAX_STATE (fragP->fr_subtype));
fragP->fr_fix += extension;
}
\f
/* tc-i386.h -- Header file for tc-i386.c
- Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001
- Free Software Foundation.
+ Copyright 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001
+ Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
#endif /* ! BFD_ASSEMBLER */
+#ifndef LEX_AT
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) x86_cons (EXP, NBYTES)
+extern void x86_cons PARAMS ((expressionS *, int));
+
+#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) x86_cons_fix_new(FRAG, OFF, LEN, EXP)
+extern void x86_cons_fix_new
+ PARAMS ((fragS *, unsigned int, unsigned int, expressionS *));
+#endif
+
#define TC_FORCE_RELOCATION(fixp) tc_i386_force_relocation(fixp)
extern int tc_i386_force_relocation PARAMS ((struct fix *));
/* tc-m32r.c -- Assembler for the Mitsubishi M32R.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
};
long
-m32r_relax_frag (fragP, stretch)
+m32r_relax_frag (segment, fragP, stretch)
+ segT segment;
fragS *fragP;
long stretch;
{
}
else
{
- growth = relax_frag (fragP, stretch);
+ growth = relax_frag (segment, fragP, stretch);
/* Long jump on odd halfword boundary? */
if (fragP->fr_subtype == 2 && (address & 3) != 0)
/* tc-m32r.h -- Header file for tc-m32r.c.
- Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
#define md_prepare_relax_scan(fragP, address, aim, this_state, this_type) \
m32r_prepare_relax_scan (fragP, address, aim, this_state, this_type)
#else
-extern long m32r_relax_frag PARAMS ((fragS *, long));
-#define md_relax_frag(fragP, stretch) \
-m32r_relax_frag (fragP, stretch)
+extern long m32r_relax_frag PARAMS ((segT, fragS *, long));
+#define md_relax_frag(segment, fragP, stretch) \
+m32r_relax_frag (segment, fragP, stretch)
#endif
/* Account for nop if 32 bit insn falls on odd halfword boundary. */
#define TC_CGEN_MAX_RELAX(insn, len) (6)
/* tc-mips.h -- header file for tc-mips.c.
- Copyright (C) 1993, 94, 95, 96, 97, 1999, 2000
+ Copyright 1993, 1994, 1995, 1996, 1997, 2000, 2001
Free Software Foundation, Inc.
Contributed by the OSF and Ralph Campbell.
Written by Keith Knowles and Ralph Campbell, working independently.
relocation: */
#define MAX_GPREL_OFFSET (0x7FF4)
-#define md_relax_frag(fragp, stretch) mips_relax_frag(fragp, stretch)
+#define md_relax_frag(segment, fragp, stretch) mips_relax_frag(fragp, stretch)
extern int mips_relax_frag PARAMS ((struct frag *, long));
#define md_undefined_symbol(name) (0)
/* tc-mn10300.c -- Assembler code for the Matsushita 10300
- Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
{ "mcrl", 3 },
{ "mcvf", 4 },
{ "mdrq", 1 },
+ { "pc", 0 },
{ "sp", 0 },
{ "xr0", 0 },
{ "xr1", 1 },
struct mn10300_opcode *next_opcode;
const unsigned char *opindex_ptr;
int next_opindex, relaxable;
- unsigned long insn, extension, size = 0, real_size;
+ unsigned long insn, extension, size = 0;
char *f;
int i;
int match;
if (opcode->format == FMT_D4)
size = 6;
- real_size = size;
-
if (relaxable && fc > 0)
{
int type;
+ /* We want to anchor the line info to the previous frag (if
+ there isn't one, create it), so that, when the insn is
+ resized, we still get the right address for the beginning of
+ the region. */
+ f = frag_more (0);
+ dwarf2_emit_insn (0);
+
/* bCC */
if (size == 2)
{
/* Is the reloc pc-relative? */
pcrel = (operand->flags & MN10300_OPERAND_PCREL) != 0;
- /* Gross. This disgusting hack is to make sure we
- get the right offset for the 16/32 bit reloc in
- "call" instructions. Basically they're a pain
- because the reloc isn't at the end of the instruction. */
- if ((size == 5 || size == 7)
- && (((insn >> 24) & 0xff) == 0xcd
- || ((insn >> 24) & 0xff) == 0xdd))
- size -= 2;
-
- /* Similarly for certain bit instructions which don't
- hav their 32bit reloc at the tail of the instruction. */
- if (size == 7
- && (((insn >> 16) & 0xffff) == 0xfe00
- || ((insn >> 16) & 0xffff) == 0xfe01
- || ((insn >> 16) & 0xffff) == 0xfe02))
- size -= 1;
-
- offset = size - reloc_size / 8;
+ offset = size - (reloc_size + operand->shift) / 8;
/* Choose a proper BFD relocation type. */
if (pcrel)
fixP->fx_offset += offset;
}
}
- }
- dwarf2_emit_insn (real_size);
+ dwarf2_emit_insn (size);
+ }
}
/* If while processing a fixup, a reloc really needs to be created
if (fixp->fx_addsy && fixp->fx_subsy)
{
+ /* If we got a difference between two symbols, and the
+ subtracted symbol is in the current section, use a
+ PC-relative relocation. If both symbols are in the same
+ section, the difference would have already been simplified
+ to a constant. */
+ if (S_GET_SEGMENT (fixp->fx_subsy) == seg)
+ {
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+ reloc->addend = (reloc->address - S_GET_VALUE (fixp->fx_subsy)
+ + fixp->fx_offset);
+
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_8:
+ reloc->howto = bfd_reloc_type_lookup (stdoutput,
+ BFD_RELOC_8_PCREL);
+ return reloc;
+
+ case BFD_RELOC_16:
+ reloc->howto = bfd_reloc_type_lookup (stdoutput,
+ BFD_RELOC_16_PCREL);
+ return reloc;
+
+ case BFD_RELOC_24:
+ reloc->howto = bfd_reloc_type_lookup (stdoutput,
+ BFD_RELOC_24_PCREL);
+ return reloc;
+
+ case BFD_RELOC_32:
+ reloc->howto = bfd_reloc_type_lookup (stdoutput,
+ BFD_RELOC_32_PCREL);
+ return reloc;
+
+ default:
+ /* Try to compute the absolute value below. */
+ break;
+ }
+ }
if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
|| S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
fragS *fragp;
asection *seg;
{
- if (fragp->fr_subtype == 0)
- return 2;
- if (fragp->fr_subtype == 3)
- return 3;
- if (fragp->fr_subtype == 6)
- {
- if (!S_IS_DEFINED (fragp->fr_symbol)
- || seg != S_GET_SEGMENT (fragp->fr_symbol))
- {
- fragp->fr_subtype = 7;
- return 7;
- }
- else
- return 5;
- }
- if (fragp->fr_subtype == 8)
- {
- if (!S_IS_DEFINED (fragp->fr_symbol)
- || seg != S_GET_SEGMENT (fragp->fr_symbol))
- {
- fragp->fr_subtype = 9;
- return 6;
- }
- else
- return 4;
- }
- if (fragp->fr_subtype == 10)
- {
- if (!S_IS_DEFINED (fragp->fr_symbol)
- || seg != S_GET_SEGMENT (fragp->fr_symbol))
- {
- fragp->fr_subtype = 12;
- return 5;
- }
- else
- return 2;
- }
- abort ();
+ if (fragp->fr_subtype == 6
+ && (!S_IS_DEFINED (fragp->fr_symbol)
+ || seg != S_GET_SEGMENT (fragp->fr_symbol)))
+ fragp->fr_subtype = 7;
+ else if (fragp->fr_subtype == 8
+ && (!S_IS_DEFINED (fragp->fr_symbol)
+ || seg != S_GET_SEGMENT (fragp->fr_symbol)))
+ fragp->fr_subtype = 9;
+ else if (fragp->fr_subtype == 10
+ && (!S_IS_DEFINED (fragp->fr_symbol)
+ || seg != S_GET_SEGMENT (fragp->fr_symbol)))
+ fragp->fr_subtype = 12;
+
+ if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
+ abort ();
+
+ return md_relax_table[fragp->fr_subtype].rlx_length;
}
long
switch (fixp->fx_r_type)
{
case BFD_RELOC_8:
+ case BFD_RELOC_8_PCREL:
size = 1;
break;
case BFD_RELOC_16:
+ case BFD_RELOC_16_PCREL:
size = 2;
break;
case BFD_RELOC_32:
+ case BFD_RELOC_32_PCREL:
size = 4;
break;
md_number_to_chars (fixpos, value, size);
- fixp->fx_done = 1;
- return 0;
+ /* If a symbol remains, pass the fixup, as a reloc, onto the linker. */
+ if (fixp->fx_addsy == NULL)
+ fixp->fx_done = 1;
+ return 0;
}
/* Return nonzero if the fixup in FIXP will require a relocation,
|| fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
return 1;
+ /* Do not adjust relocations involving symbols in code sections,
+ because it breaks linker relaxations. This could be fixed in the
+ linker, but this fix is simpler, and it pretty much only affects
+ object size a little bit. */
+ if ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE)
+ && fixp->fx_subsy
+ && S_GET_SEGMENT (fixp->fx_addsy) == S_GET_SEGMENT (fixp->fx_subsy))
+ return 1;
+
return 0;
}
|| fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
return 0;
+ /* Do not adjust relocations involving symbols in code sections,
+ because it breaks linker relaxations. This could be fixed in the
+ linker, but this fix is simpler, and it pretty much only affects
+ object size a little bit. */
+ if (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE)
+ return 0;
+
return 1;
}
/* tc-tic54x.h -- Header file for tc-tic54x.c
- Copyright (C) 1999, 2000 Free Software Foundation.
+ Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Timothy Wall (twall@alum.mit.edu)
This file is part of GAS, the GNU Assembler.
tic54x_estimate_size_before_relax(f,s)
extern int tic54x_estimate_size_before_relax(fragS *, segT);
-#define md_relax_frag(f,s) tic54x_relax_frag(f,s)
+#define md_relax_frag(seg, f,s) tic54x_relax_frag(f,s)
extern int tic54x_relax_frag(fragS *, long);
#define md_convert_frag(b,s,f) tic54x_convert_frag(b,s,f)
/* tc-v850.c -- Assembler code for the NEC V850
- Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
{"call_table_text", v850_call_table_text, 0},
{"v850e", set_machine, bfd_mach_v850e},
{"v850ea", set_machine, bfd_mach_v850ea},
- {"file", dwarf2_directive_file },
- {"loc", dwarf2_directive_loc },
+ {"file", dwarf2_directive_file, 0},
+ {"loc", dwarf2_directive_loc, 0},
{ NULL, NULL, 0}
};
{
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int)fragP->fr_opcode);
- fragP->fr_var = 0;
fragP->fr_fix += 2;
}
/* Out of range conditional branch. Emit a branch around a jump. */
fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
fragP->fr_offset, 1, BFD_RELOC_UNUSED +
(int) fragP->fr_opcode + 1);
- fragP->fr_var = 0;
fragP->fr_fix += 6;
}
/* Out of range unconditional branch. Emit a jump. */
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
fragP->fr_offset, 1, BFD_RELOC_UNUSED +
(int) fragP->fr_opcode + 1);
- fragP->fr_var = 0;
fragP->fr_fix += 4;
}
else
int relaxable = 0;
unsigned long insn;
unsigned long insn_size;
- unsigned long total_insn_size = 0;
char *f;
int i;
int match;
input_line_pointer = str;
+ /* Tie dwarf2 debug info to the address at the start of the insn.
+ We can't do this after the insn has been output as the current
+ frag may have been closed off. eg. by frag_var. */
+ dwarf2_emit_insn (0);
+
/* Write out the instruction. */
if (relaxable && fc > 0)
md_number_to_chars (f, insn, insn_size);
md_number_to_chars (f + 2, 0, 4);
}
- total_insn_size = insn_size;
}
else
{
insn_size = 2;
f = frag_more (insn_size);
- total_insn_size = insn_size;
-
md_number_to_chars (f, insn, insn_size);
if (extra_data_after_insn)
{
f = frag_more (extra_data_len);
- total_insn_size += extra_data_len;
-
md_number_to_chars (f, extra_data, extra_data_len);
extra_data_after_insn = false;
}
input_line_pointer = saved_input_line_pointer;
-
- dwarf2_emit_insn (total_insn_size);
}
/* If while processing a fixup, a reloc really needs to be created
return reloc;
}
-/* Assume everything will fit in two bytes, then expand as necessary. */
+/* Return current size of variable part of frag. */
int
md_estimate_size_before_relax (fragp, seg)
fragS *fragp;
asection *seg ATTRIBUTE_UNUSED;
{
- if (fragp->fr_subtype == 0)
- fragp->fr_var = 4;
- else if (fragp->fr_subtype == 2)
- fragp->fr_var = 2;
- else
+ if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
abort ();
- return 2;
+
+ return md_relax_table[fragp->fr_subtype].rlx_length;
}
long
-@c Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+@c Copyright 2000, 2001 Free Software Foundation, Inc.
@c This is part of the GAS manual.
@c For copying conditions, see the file as.texinfo.
@chapter ARC Dependent Features
@end ifclear
-@set ARC_CORE_DEFAULT 5
+@set ARC_CORE_DEFAULT 6
@cindex ARC support
@menu
-@c Copyright (C) 1991, 92, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
+@c Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001
+@c Free Software Foundation, Inc.
@c This is part of the GAS manual.
@c For copying conditions, see the file as.texinfo.
@ifset GENERIC
* i386-Regs:: Register Naming
* i386-Prefixes:: Instruction Prefixes
* i386-Memory:: Memory References
-* i386-jumps:: Handling of Jump Instructions
+* i386-Jumps:: Handling of Jump Instructions
* i386-Float:: Floating Point
* i386-SIMD:: Intel's MMX and AMD's 3DNow! SIMD Operations
* i386-16bit:: Writing 16-bit Code
Other addressing modes remain unchanged in x86-64 architecture, except
registers used are 64-bit instead of 32-bit.
-@node i386-jumps
+@node i386-Jumps
@section Handling of Jump Instructions
@cindex jump optimization, i386
Jump instructions are always optimized to use the smallest possible
displacements. This is accomplished by using byte (8-bit) displacement
jumps whenever the target is sufficiently close. If a byte displacement
-is insufficient a long (32-bit) displacement is used. We do not support
+is insufficient a long displacement is used. We do not support
word (16-bit) displacement jumps in 32-bit mode (i.e. prefixing the jump
instruction with the @samp{data16} instruction prefix), since the 80386
insists upon masking @samp{%eip} to 16 bits after the word displacement
-is added.
+is added. (See also @pxref{i386-Arch})
Note that the @samp{jcxz}, @samp{jecxz}, @samp{loop}, @samp{loopz},
@samp{loope}, @samp{loopnz} and @samp{loopne} instructions only come in byte
@item @samp{sledgehammer}
@end multitable
-Apart from the warning, there is only one other effect on
-@code{@value{AS}} operation; If you specify a CPU other than
+Apart from the warning, there are only two other effects on
+@code{@value{AS}} operation; Firstly, if you specify a CPU other than
@samp{i486}, then shift by one instructions such as @samp{sarl $1, %eax}
will automatically use a two byte opcode sequence. The larger three
byte opcode sequence is used on the 486 (and when no architecture is
specified) because it executes faster on the 486. Note that you can
explicitly request the two byte opcode by writing @samp{sarl %eax}.
+Secondly, if you specify @samp{i8086}, @samp{i186}, or @samp{i286},
+@emph{and} @samp{.code16} or @samp{.code16gcc} then byte offset
+conditional jumps will be promoted when necessary to a two instruction
+sequence consisting of a conditional jump of the opposite sense around
+an unconditional jump to the target.
+
+Following the CPU architecture, you may specify @samp{jumps} or
+@samp{nojumps} to control automatic promotion of conditional jumps.
+@samp{jumps} is the default, and enables jump promotion; All external
+jumps will be of the long variety, and file-local jumps will be promoted
+as necessary. (@pxref{i386-Jumps}) @samp{nojumps} leaves external
+conditional jumps as byte offset jumps, and warns about file-local
+conditional jumps that @code{@value{AS}} promotes.
+Unconditional jumps are treated as for @samp{jumps}.
+
+For example
+
+@smallexample
+ .arch i8086,nojumps
+@end smallexample
@node i386-Notes
@section Notes
\input texinfo
+@c Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+@c 2001
+@c Free Software Foundation, Inc.
@setfilename internals.info
@node Top
@top Assembler Internals
@item md_relax_frag
@cindex md_relax_frag
-This macro may be defined to relax a frag. GAS will call this with the frag
-and the change in size of all previous frags; @code{md_relax_frag} should
-return the change in size of the frag. @xref{Relaxation}.
+This macro may be defined to relax a frag. GAS will call this with the
+segment, the frag, and the change in size of all previous frags;
+@code{md_relax_frag} should return the change in size of the frag.
+@xref{Relaxation}.
@item TC_GENERIC_RELAX_TABLE
@cindex TC_GENERIC_RELAX_TABLE
/* frags.h - Header file for the frag concept.
- Copyright (C) 1987, 92, 93, 94, 95, 97, 98, 99, 2000
+ Copyright 1987, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
struct list_info_struct *line;
#endif
+ /* Flipped each relax pass so we can easily determine whether
+ fr_address has been adjusted. */
+ unsigned int relax_marker:1;
+
/* What state is my tail in? */
relax_stateT fr_type;
relax_substateT fr_subtype;
}
else
{
+#ifdef OBJ_COFF
+ int local;
+
+ symbolP = symbol_find (sym_name);
+ local = symbolP == NULL;
+ if (local)
+#endif /* OBJ_COFF */
symbolP = symbol_find_or_make (sym_name);
/* Permit register names to be redefined. */
if (!reassign
&& S_IS_DEFINED (symbolP)
&& S_GET_SEGMENT (symbolP) != reg_section)
as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
+
+#ifdef OBJ_COFF
+ /* "set" symbols are local unless otherwise specified. */
+ if (local)
+ SF_SET_LOCAL (symbolP);
+#endif /* OBJ_COFF */
+
pseudo_set (symbolP);
}
/* Generic stabs parsing for gas.
- Copyright (C) 1989, 90, 91, 93, 94, 95, 96, 97, 98, 99, 2000
+ Copyright 1989, 1990, 1991, 1993, 1995, 1996, 1997, 1998, 2000, 2001
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
char *stabstr_secname;
{
long longint;
- char *string;
+ char *string, *saved_string_obstack_end;
int type;
int other;
int desc;
'd' indicating which type of .stab this is. */
if (what != 's')
- string = "";
+ {
+ string = "";
+ saved_string_obstack_end = 0;
+ }
else
{
int length;
string = demand_copy_C_string (&length);
+ /* FIXME: We should probably find some other temporary storage
+ for string, rather than leaking memory if someone else
+ happens to use the notes obstack. */
+ saved_string_obstack_end = notes.next_free;
SKIP_WHITESPACE ();
if (*input_line_pointer == ',')
input_line_pointer++;
stroff = get_stab_string_offset (string, stabstr_secname);
if (what == 's')
{
- /* release the string */
- obstack_free (¬es, string);
+ /* Release the string, if nobody else has used the obstack. */
+ if (saved_string_obstack_end == notes.next_free)
+ obstack_free (¬es, string);
}
/* At least for now, stabs in a special stab section are always
/* write.c - emit .o file
- Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
+ Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
case O_absent:
break;
+ case O_register:
+ as_bad (_("register value used as expression"));
+ break;
+
case O_add:
/* This comes up when _GLOBAL_OFFSET_TABLE_+(.-L0) is read, if
the difference expression cannot immediately be reduced. */
#ifdef TC_GENERIC_RELAX_TABLE
-static int is_dnrange PARAMS ((fragS *, fragS *));
-
-/* Subroutines of relax_segment. */
-static int
-is_dnrange (f1, f2)
- fragS *f1;
- fragS *f2;
-{
- for (; f1; f1 = f1->fr_next)
- if (f1->fr_next == f2)
- return 1;
- return 0;
-}
-
/* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
long
-relax_frag (fragP, stretch)
+relax_frag (segment, fragP, stretch)
+ segT segment;
fragS *fragP;
long stretch;
{
const relax_typeS *start_type;
relax_substateT next_state;
relax_substateT this_state;
- long aim, target, growth;
- symbolS *symbolP = fragP->fr_symbol;
- long offset = fragP->fr_offset;
- /* Recompute was_address by undoing "+= stretch" done by relax_segment. */
- unsigned long was_address = fragP->fr_address - stretch;
- unsigned long address = fragP->fr_address;
- const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
-
+ long growth;
+ offsetT aim;
+ addressT target;
+ addressT address;
+ symbolS *symbolP;
+ const relax_typeS *table;
+
+ target = fragP->fr_offset;
+ address = fragP->fr_address;
+ table = TC_GENERIC_RELAX_TABLE;
this_state = fragP->fr_subtype;
start_type = this_type = table + this_state;
- target = offset;
+ symbolP = fragP->fr_symbol;
if (symbolP)
{
+ fragS *sym_frag;
+
+ sym_frag = symbol_get_frag (symbolP);
+
#ifndef DIFF_EXPR_OK
#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
know ((S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
|| (S_GET_SEGMENT (symbolP) == SEG_BSS)
|| (S_GET_SEGMENT (symbolP) == SEG_TEXT));
#endif
- know (symbolP->sy_frag);
+ know (sym_frag != NULL);
#endif
know (!(S_GET_SEGMENT (symbolP) == absolute_section)
- || symbolP->sy_frag == &zero_address_frag);
- target += S_GET_VALUE (symbolP) + symbol_get_frag (symbolP)->fr_address;
+ || sym_frag == &zero_address_frag);
+ target += S_GET_VALUE (symbolP) + sym_frag->fr_address;
/* If frag has yet to be reached on this pass,
assume it will move by STRETCH just as we did.
If this is not so, it will be because some frag
- between grows, and that will force another pass.
-
- Beware zero-length frags.
-
- There should be a faster way to do this. */
+ between grows, and that will force another pass. */
- if (symbol_get_frag (symbolP)->fr_address >= was_address
- && is_dnrange (fragP, symbol_get_frag (symbolP)))
+ if (stretch != 0
+ && sym_frag->relax_marker != fragP->relax_marker
+ && S_GET_SEGMENT (symbolP) == segment)
{
target += stretch;
}
address = 0;
for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
{
+ fragP->relax_marker = 0;
fragP->fr_address = address;
address += fragP->fr_fix;
long stretch; /* May be any size, 0 or negative. */
/* Cumulative number of addresses we have relaxed this pass.
We may have relaxed more than one address. */
- long stretched; /* Have we stretched on this pass? */
+ int stretched; /* Have we stretched on this pass? */
/* This is 'cuz stretch may be zero, when, in fact some piece of code
grew, and another shrank. If a branch instruction doesn't fit anymore,
we could be scrod. */
do
{
- stretch = stretched = 0;
+ stretch = 0;
+ stretched = 0;
for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
{
offsetT offset;
symbolS *symbolP;
+ fragP->relax_marker ^= 1;
was_address = fragP->fr_address;
address = fragP->fr_address += stretch;
symbolP = fragP->fr_symbol;
case rs_org:
{
- long target = offset;
- long after;
+ addressT target = offset;
+ addressT after;
if (symbolP)
{
case rs_machine_dependent:
#ifdef md_relax_frag
- growth = md_relax_frag (fragP, stretch);
+ growth = md_relax_frag (segment, fragP, stretch);
#else
#ifdef TC_GENERIC_RELAX_TABLE
/* The default way to relax a frag is to look through
TC_GENERIC_RELAX_TABLE. */
- growth = relax_frag (fragP, stretch);
+ growth = relax_frag (segment, fragP, stretch);
#endif /* TC_GENERIC_RELAX_TABLE */
#endif
break;
if (growth)
{
stretch += growth;
- stretched++;
+ stretched = 1;
}
} /* For each frag in the segment. */
}
/* write.h
- Copyright (C) 1987, 92, 93, 94, 95, 96, 97, 2000
+ Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
extern int get_recorded_alignment PARAMS ((segT seg));
extern void subsegs_finish PARAMS ((void));
extern void write_object_file PARAMS ((void));
-extern long relax_frag PARAMS ((fragS *, long));
+extern long relax_frag PARAMS ((segT, fragS *, long));
extern void relax_segment
PARAMS ((struct frag * seg_frag_root, segT seg_type));
+2001-05-23 Alan Modra <amodra@one.net.au>
+
+ * ldlang.c (wild_doit): Use linker_has_input to reliably determine
+ whether an input section is the first one assigned to an output
+ section.
+ Assorted formatting fixes.
+
+ Merge from mainline.
+ 2001-05-03 H.J. Lu <hjl@gnu.org>
+ * emultempl/elf32.em: Include "libiberty.h".
+ (gld${EMULATION_NAME}_vercheck): Call basename () to get the
+ basename of the bfd filename.
+ (gld${EMULATION_NAME}_stat_needed): Likewise.
+ (gld${EMULATION_NAME}_try_needed): Likewise.
+ (gld${EMULATION_NAME}_open_dynamic_archive): Likewise.
+
+ 2001-03-17 Ulrich Drepper <drepper@redhat.com>
+ * emultmpl/elf32.em (gld${EMULATION_NAME}_search_needed): If NAME
+ is an absolute path look only for this file and not along the path.
+ (OPTION_GROUP): New macro.
+ Add new option Bgroup to longopts.
+ (gld*_parse_args): Handle GROUP_OPTION and recognize -z defs.
+ (gld*_list_options): Add -Bgroup and -z defs.
+ * ld.1: Document -Bgroup and -z defs.
+ * ld.texinfo: Likewise.
+
+ 2001-02-01 Nick Clifton <nickc@redhat.com>
+ * ld.1: Replace occurances of -oformat with --oformat.
+
+ 2001-05-02 H.J. Lu <hjl@gnu.org>
+ * ldfile.c: Include "libiberty.h".
+ * ldlex.l: Likewise.
+ * ldmisc.c (buystring): Removed.
+ * ldmisc.h: Likewise.
+ * ldfile.c: Replace buystring with xstrdup.
+ * ldlang.c: Likewise.
+ * ldlex.l: Likewise.
+ * ldmain.c: Likewise.
+ * ldmisc.c: Likewise.
+ * lexsup.c: Likewise.
+ * mpw-eppcmac.c: Likewise.
+
+ 2001-04-28 Paul Sokolovsky <Paul.Sokolovsky@technologist.com>
+ * ldlang.c (load_symbols): Give emulation a chance
+ to process unrecognized file before fatal error is
+ reported, not after.
+
+ 2001-02-26 H.J. Lu <hjl@gnu.org>
+ * ldlang.c (open_input_bfds): Set the bfd error handler so
+ that problems can be caught whilst loading symbols.
+ (record_bfd_errors): New function: Report BFD errors and mark
+ the executable output as being invalid.
+
2001-04-02 Alan Modra <alan@linuxcare.com.au>
* emulparams/hppalinux.sh (MAXPAGESIZE): Set to 64k.
* scripttempl/elf.sc: Add .gnu.linkonce.wi.* to .debug_info
sections.
- * scripttempl/elf32var.sc: Ditto.
+ * scripttempl/elf32avr.sc: Ditto.
* scripttempl/elfd10v.sc: Ditto.
* scripttempl/elfd30v.sc: Ditto.
* scripttempl/elfi370.sc: Ditto.
2000-07-05 Kenneth Block <krblock@computer.org>
- * ld/lexsup.c: Add optional style to demangle switch
- * ld/ld.texinfo: Document optional style to demangle switch.
+ * lexsup.c: Add optional style to demangle switch
+ * ld.texinfo: Document optional style to demangle switch.
2000-07-20 Hans-Peter Nilsson <hp@axis.com>
2000-07-16 Charles Wilson <cwilson@ece.gatech.edu>
- * src/ld/emultempl/pe.em (gld_*_open_dynamic_archive): New search
+ * emultempl/pe.em (gld_*_open_dynamic_archive): New search
order for dynamic library '-lfoo' on pei386: libfoo.dll.a,
foo.dll.a, libfoo.a, libfoo.dll, foo.dll. This fixes compatibility
errors introduced by the old dynamic lib search order.
2000-05-16 Charles Wilson <cwilson@ece.gatech.edu>
- * ld/emultempl/pe.em (_open_dynamic_archive): New function: Search
+ * emultempl/pe.em (_open_dynamic_archive): New function: Search
the library path for "foo.dll" and "libfoo.dll" dynamic libraries
before searching for 'libfoo.a' in response to a '-Bdynamic -lfoo'
link options.
(gld_X_find_potential_libraries): New function. Search for
libraries called "*.lib".
- * scriptempl/pe.sc: Add .pdata section.
+ * scripttempl/pe.sc: Add .pdata section.
2000-02-23 Richard Henderson <rth@cygnus.com>
2000-02-03 Timothy Wall <twall@redhat.com>
- * ld/ldexp.c (fold_name): Make SIZEOF operator return byte count, not
+ * ldexp.c (fold_name): Make SIZEOF operator return byte count, not
octet count.
- * ld/ldlang.c (print_input_section, print_data_statement,
+ * ldlang.c (print_input_section, print_data_statement,
print_reloc_statement, print_padding_statement): Print target
address values and section sizes as bytes, not octets.
(insert_pad) Calculate padding size in octets, and adjust "dot"
/* This file is is generated by a shell script. DO NOT EDIT! */
/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
- Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 99, 2000, 2001
+ Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
Written by Steve Chamberlain <sac@cygnus.com>
ELF support by Ian Lance Taylor <ian@cygnus.com>
#include "bfd.h"
#include "sysdep.h"
+#include "libiberty.h"
#include <ctype.h>
gld${EMULATION_NAME}_vercheck (s)
lang_input_statement_type *s;
{
- const char *soname, *f;
+ const char *soname;
struct bfd_link_needed_list *l;
if (global_vercheck_failed)
soname = bfd_elf_get_dt_soname (s->the_bfd);
if (soname == NULL)
- soname = bfd_get_filename (s->the_bfd);
-
- f = strrchr (soname, '/');
- if (f != NULL)
- ++f;
- else
- f = soname;
+ soname = basename (bfd_get_filename (s->the_bfd));
for (l = global_vercheck_needed; l != NULL; l = l->next)
{
const char *suffix;
- if (strcmp (f, l->name) == 0)
+ if (strcmp (soname, l->name) == 0)
{
/* Probably can't happen, but it's an easy check. */
continue;
suffix += sizeof ".so." - 1;
- if (strncmp (f, l->name, suffix - l->name) == 0)
+ if (strncmp (soname, l->name, suffix - l->name) == 0)
{
/* Here we know that S is a dynamic object FOO.SO.VER1, and
the object we are considering needs a dynamic object
struct stat st;
const char *suffix;
const char *soname;
- const char *f;
if (global_found)
return;
soname = bfd_elf_get_dt_soname (s->the_bfd);
if (soname == NULL)
- soname = s->filename;
-
- f = strrchr (soname, '/');
- if (f != NULL)
- ++f;
- else
- f = soname;
+ soname = basename (s->filename);
- if (strncmp (f, global_needed->name, suffix - global_needed->name) == 0)
+ if (strncmp (soname, global_needed->name,
+ suffix - global_needed->name) == 0)
einfo ("%P: warning: %s, needed by %B, may conflict with %s\n",
- global_needed->name, global_needed->by, f);
+ global_needed->name, global_needed->by, soname);
}
einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd);
/* First strip off everything before the last '/'. */
- soname = strrchr (abfd->filename, '/');
- if (soname)
- soname++;
- else
- soname = abfd->filename;
+ soname = basename (abfd->filename);
if (trace_file_tries)
info_msg (_("found %s at %s\n"), soname, name);
if (bfd_check_format (entry->the_bfd, bfd_object)
&& (entry->the_bfd->flags & DYNAMIC) != 0)
{
- char *needed_name;
-
ASSERT (entry->is_archive && entry->search_dirs_flag);
/* Rather than duplicating the logic above. Just use the
- filename we recorded earlier.
-
- First strip off everything before the last '/'. */
- filename = strrchr (entry->filename, '/');
- filename++;
+ filename we recorded earlier. */
- needed_name = (char *) xmalloc (strlen (filename) + 1);
- strcpy (needed_name, filename);
- bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name);
+ filename = xstrdup (basename (entry->filename));
+ bfd_elf_set_dt_needed_name (entry->the_bfd, filename);
}
return true;
#define OPTION_DISABLE_NEW_DTAGS (400)
#define OPTION_ENABLE_NEW_DTAGS (OPTION_DISABLE_NEW_DTAGS + 1)
+#define OPTION_GROUP (OPTION_ENABLE_NEW_DTAGS + 1)
static struct option longopts[] =
{
{"disable-new-dtags", no_argument, NULL, OPTION_DISABLE_NEW_DTAGS},
{"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS},
{"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS},
+ {"Bgroup", no_argument, NULL, OPTION_GROUP},
+ {"Bgroup", no_argument, NULL, OPTION_GROUP},
EOF
fi
link_info.new_dtags = true;
break;
+ case OPTION_GROUP:
+ link_info.flags_1 |= (bfd_vma) DF_1_GROUP;
+ /* Groups must be self-contained. */
+ link_info.no_undefined = true;
+ break;
+
case 'z':
if (strcmp (optarg, "initfirst") == 0)
link_info.flags_1 |= (bfd_vma) DF_1_INITFIRST;
link_info.flags |= (bfd_vma) DF_ORIGIN;
link_info.flags_1 |= (bfd_vma) DF_1_ORIGIN;
}
+ else if (strcmp (optarg, "defs") == 0)
+ link_info.no_undefined = true;
/* What about the other Solaris -z options? FIXME. */
break;
EOF
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
cat >>e${EMULATION_NAME}.c <<EOF
+ fprintf (file, _(" -Bgroup\t\tSelects group name lookup rules for DSO\n"));
fprintf (file, _(" --disable-new-dtags\tDisable new dynamic tags\n"));
fprintf (file, _(" --enable-new-dtags\tEnable new dynamic tags\n"));
+ fprintf (file, _(" -z defs\t\tDisallows undefined symbols\n"));
fprintf (file, _(" -z initfirst\t\tMark DSO to be initialized first at runtime\n"));
fprintf (file, _(" -z interpose\t\tMark object to interpose all DSOs but executable\n"));
fprintf (file, _(" -z loadfltr\t\tMark object requiring immediate process\n"));
-.\" Copyright (c) 1991, 92, 93, 94, 95, 96, 97, 98, 1999, 2000 Free Software Foundation
+.\" Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+.\" 2001 Free Software Foundation, Inc.
.\" See section COPYING for conditions for redistribution
.TH ld 1 "" "Free Software Foundation" "GNU Development Tools"
.de BP
.I input-format\c
\&\|]
.RB "[\|" \-Bstatic "\|]"
+.RB "[\|" \-Bgroup "\|]"
.RB "[\|" \-Bdynamic "\|]"
.RB "[\|" \-Bsymbolic "\|]"
.RB "[\|" "\-c\ "\c
.RB "[\|" \-O\c
.I level\c
\&\|]
-.RB "[\|" "\-oformat\ "\c
+.RB "[\|" "\--oformat\ "\c
.I output-format\c
\&\|]
.RB "[\|" "\-R\ "\c
for which shared libraries are supported. This option is normally the
default on such platforms.
+.TP
+.B \-Bgroup
+Set the \c
+.B DF_1_GROUP
+\c
+flag in the \c
+.B DT_FLAGS_1
+\c
+entry in the dynamic section. This causes the runtime linker to handle
+lookups in this object and its dependencies to be performed only inside
+the group. No undefined symbols are allowed. This option is only
+meaningful on ELF platforms which support shared libraries.
+
.TP
.B \-Bsymbolic
When creating a shared library, bind references to global symbols to
the optimizations.
.TP
-.BI "\-oformat " "output\-format"
+.BI "\--oformat " "output\-format"
Specify the binary format for the output object file.
You don't usually need to specify this, as
\c
\input texinfo
@setfilename ld.info
+@c Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+@c 2001 Free Software Foundation, Inc.
@syncodeindex ky cp
@include configdoc.texi
@c (configdoc.texi is generated by the Makefile)
binary format. You can also use @samp{-b} to switch formats explicitly (when
linking object files of different formats), by including
@samp{-b @var{input-format}} before each group of object files in a
-particular format.
+particular format.
The default format is taken from the environment variable
@code{GNUTARGET}.
@kindex -d
@kindex -dc
@kindex -dp
-@item -d
+@item -d
@itemx -dc
@itemx -dp
These three options are equivalent; multiple forms are supported for
@cindex entry point, from command line
@kindex -e @var{entry}
@kindex --entry=@var{entry}
-@item -e @var{entry}
+@item -e @var{entry}
@itemx --entry=@var{entry}
Use @var{entry} as the explicit symbol for beginning execution of your
program, rather than the default entry point. If there is no symbol
@cindex search directory, from cmd line
@kindex -L@var{dir}
@kindex --library-path=@var{dir}
-@item -L@var{searchdir}
+@item -L@var{searchdir}
@itemx --library-path=@var{searchdir}
Add path @var{searchdir} to the list of paths that @code{ld} will search
for archive libraries and @code{ld} control scripts. You may use this
@item -n
@itemx --nmagic
Turn off page alignment of sections, and mark the output as
-@code{NMAGIC} if possible.
+@code{NMAGIC} if possible.
@kindex -N
@kindex --omagic
@cindex read/write from cmd line
@cindex OMAGIC
-@item -N
+@item -N
@itemx --omagic
Set the text and data sections to be readable and writable. Also, do
not page-align the data segment. If the output format supports Unix
linking}. As a side effect, in environments that support standard Unix
magic numbers, this option also sets the output file's magic number to
@code{OMAGIC}.
-@c ; see @code{-N}.
+@c ; see @code{-N}.
If this option is not specified, an absolute file is produced. When
linking C++ programs, this option @emph{will not} resolve references to
constructors; to do that, use @samp{-Ur}.
@kindex -s
@kindex --strip-all
@cindex strip all symbols
-@item -s
+@item -s
@itemx --strip-all
Omit all symbol information from the output file.
@kindex -S
@kindex --strip-debug
@cindex strip debugger symbols
-@item -S
+@item -S
@itemx --strip-debug
Omit debugger symbol information (but not all symbols) from the output file.
@kindex -t
@kindex --trace
@cindex input files, displaying
-@item -t
+@item -t
@itemx --trace
Print the names of the input files as @code{ld} processes them.
@kindex -Ur
@cindex constructors
-@item -Ur
+@item -Ur
For anything other than C++ programs, this option is equivalent to
@samp{-r}: it generates relocatable output---i.e., an output file that can in
turn serve as input to @code{ld}. When linking C++ programs, @samp{-Ur}
@kindex --discard-locals
@cindex local symbols, deleting
@cindex L, deleting symbols beginning
-@item -X
+@item -X
@itemx --discard-locals
Delete all temporary local symbols. For most targets, this is all local
symbols whose names begin with @samp{L}.
@code{nodump} marks the object can not be dumped by @code{dldump}.
@code{now} marks the object with the non-lazy runtime binding.
@code{origin} marks the object may contain $ORIGIN.
+@code{defs} disallows undefined symbols.
@kindex -(
@cindex groups of archives
multiple times on the command line: it affects library searching for
@code{-l} options which follow it.
+@kindex -Bgroup
+@item -Bgroup
+Set the @code{DF_1_GROUP} flag in the @code{DT_FLAGS_1} entry in the dynamic
+section. This causes the runtime linker to handle lookups in this
+object and its dependencies to be performed only inside the group.
+@code{--no-undefined} is implied. This option is only meaningful on ELF
+platforms which support shared libraries.
+
@kindex -Bstatic
@kindex -dn
@kindex -non_shared
@kindex -static
-@item -Bstatic
+@item -Bstatic
@itemx -dn
@itemx -non_shared
@itemx -static
and other output. When the linker is told to demangle, it tries to
present symbol names in a readable fashion: it strips leading
underscores if they are used by the object file format, and converts C++
-mangled symbol names into user readable names. Different compilers have
-different mangling styles. The optional demangling style argument can be used
-to choose an appropriate demangling style for your compiler. The linker will
+mangled symbol names into user readable names. Different compilers have
+different mangling styles. The optional demangling style argument can be used
+to choose an appropriate demangling style for your compiler. The linker will
demangle by default unless the environment variable @samp{COLLECT_NO_DEMANGLE}
is set. These options may be used to override the default.
while linking a large executable.
@kindex --no-undefined
+@kindex -z defs
@item --no-undefined
+@itemx -z defs
Normally when creating a non-symbolic shared library, undefined symbols
-are allowed and left to be resolved by the runtime loader. This option
-disallows such undefined symbols.
+are allowed and left to be resolved by the runtime loader. These options
+disallow such undefined symbols.
@kindex --allow-shlib-undefined
@item --allow-shlib-undefined
@cindex synthesizing linker
@cindex relaxing addressing modes
@item --relax
-An option with machine dependent effects.
+An option with machine dependent effects.
@ifset GENERIC
This option is only supported on a few targets.
@end ifset
entry point by trying each of the following methods in order, and
stopping when one of them succeeds:
@itemize @bullet
-@item
+@item
the @samp{-e} @var{entry} command-line option;
-@item
+@item
the @code{ENTRY(@var{symbol})} command in a linker script;
-@item
+@item
the value of the symbol @code{start}, if defined;
-@item
+@item
the address of the first byte of the @samp{.text} section, if present;
-@item
+@item
The address @code{0}.
@end itemize
@subsection Output section description
The full description of an output section looks like this:
@smallexample
-@group
+@group
@var{section} [@var{address}] [(@var{type})] : [AT(@var{lma})]
@{
@var{output-section-command}
@cindex KEEP
@cindex garbage collection
When link-time garbage collection is in use (@samp{--gc-sections}),
-it is often useful to mark sections that should not be eliminated.
+it is often useful to mark sections that should not be eliminated.
This is accomplished by surrounding an input section's wildcard entry
with @code{KEEP()}, as in @code{KEEP(*(.init))} or
@code{KEEP(SORT(*)(.ctors))}.
@}
@}
@end group
-@end smallexample
+@end smallexample
@node Output Section Data
@subsection Output section data
We showed above that the full description of an output section looked
like this:
@smallexample
-@group
+@group
@var{section} [@var{address}] [(@var{type})] : [AT(@var{lma})]
@{
@var{output-section-command}
@var{output-section-command}. In this section we will describe the
remaining section attributes.
-@menu
+@menu
* Output Section Type:: Output section type
* Output Section LMA:: Output section LMA
* Output Section Region:: Output section region
SECTIONS
@{
.text 0x1000 : @{ *(.text) _etext = . ; @}
- .mdata 0x2000 :
+ .mdata 0x2000 :
AT ( ADDR (.text) + SIZEOF (.text) )
@{ _data = . ; *(.data); _edata = . ; @}
.bss 0x3000 :
you wish. The syntax is:
@smallexample
@group
-MEMORY
+MEMORY
@{
@var{name} [(@var{attr})] : ORIGIN = @var{origin}, LENGTH = @var{len}
@dots{}
@smallexample
@group
-MEMORY
+MEMORY
@{
rom (rx) : ORIGIN = 0, LENGTH = 256K
ram (!rx) : org = 0x40000000, l = 4M
global:
foo1;
local:
- old*;
- original*;
- new*;
+ old*;
+ original*;
+ new*;
@};
VERS_1.2 @{
(lowest)
@end smallexample
Notes:
-(1) Prefix operators
+(1) Prefix operators
(2) @xref{Assignments}.
@c TEXI2ROFF-KILL
@end ifinfo
height2pt&\omit&&\omit&&\omit&\cr
&highest&&&&&\cr
% '176 is tilde, '~' in tt font
-&1&&left&&\qquad- \char'176\ !\qquad\dag&\cr
+&1&&left&&\qquad- \char'176\ !\qquad\dag&\cr
&2&&left&&* / \%&\cr
&3&&left&&+ -&\cr
&4&&left&&>> <<&\cr
@group
SECTIONS
@{
- .text 9+this_isnt_constant :
+ .text 9+this_isnt_constant :
@{ *(.text) @}
@}
@end group
@group
SECTIONS @{ @dots{}
.output1 :
- @{
+ @{
start_of_output_1 = ABSOLUTE(.);
@dots{}
@}
@cindex entry point, thumb
@kindex --thumb-entry=@var{entry}
The @samp{--thumb-entry} switch is a duplicate of the generic
-@samp{--entry} switch, in that it sets the program's starting address.
+@samp{--entry} switch, in that it sets the program's starting address.
But it also sets the bottom bit of the address, so that it can be
branched to using a BX instruction, and the program will start
executing in Thumb mode straight away.
@cindex @code{FORMAT} (MRI)
@item FORMAT @var{output-format}
Similar to the @code{OUTPUT_FORMAT} command in the more general linker
-language, but restricted to one of these output formats:
+language, but restricted to one of these output formats:
@enumerate
-@item
+@item
S-records, if @var{output-format} is @samp{S}
@item
@cindex GNU Free Documentation License
GNU Free Documentation License
-
+
Version 1.1, March 2000
Copyright (C) 2000 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
+
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
/* Linker file opening and searching.
- Copyright (C) 1991, 92, 93, 94, 95, 98, 99, 2000
+ Copyright 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
#include "ldgram.h"
#include "ldlex.h"
#include "ldemul.h"
+#include "libiberty.h"
#include <ctype.h>
else
{
search_arch_type *arch;
+ boolean found = false;
/* Try to open <filename><suffix> or lib<filename><suffix>.a */
for (arch = search_arch_head;
arch != (search_arch_type *) NULL;
arch = arch->next)
{
- if (ldfile_open_file_search (arch->name, entry, "lib", ".a"))
- return;
+ found = ldfile_open_file_search (arch->name, entry, "lib", ".a");
+ if (found)
+ break;
#ifdef VMS
- if (ldfile_open_file_search (arch->name, entry, ":lib", ".a"))
- return;
+ found = ldfile_open_file_search (arch->name, entry, ":lib", ".a");
+ if (found)
+ break;
#endif
- if (ldemul_find_potential_libraries (arch->name, entry))
- return;
+ found = ldemul_find_potential_libraries (arch->name, entry);
+ if (found)
+ break;
}
- einfo (_("%F%P: cannot find %s\n"), entry->local_sym_name);
+ /* If we have found the file, we don't need to search directories
+ again. */
+ if (found)
+ entry->search_dirs_flag = false;
+ else
+ einfo (_("%F%P: cannot find %s\n"), entry->local_sym_name);
}
}
ldfile_add_arch (in_name)
CONST char *in_name;
{
- char *name = buystring (in_name);
+ char *name = xstrdup (in_name);
search_arch_type *new =
(search_arch_type *) xmalloc (sizeof (search_arch_type));
/* Linker command language support.
- Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001
Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
#include <ctype.h>
/* FORWARDS */
-static lang_statement_union_type *new_statement PARAMS ((enum statement_enum,
- size_t,
- lang_statement_list_type *));
+static lang_statement_union_type *new_statement
+ PARAMS ((enum statement_enum, size_t, lang_statement_list_type *));
/* LOCALS */
static struct obstack stat_obstack;
fill_type, bfd_vma, boolean));
static void lang_finish PARAMS ((void));
static void ignore_bfd_errors PARAMS ((const char *, ...));
+static void record_bfd_errors PARAMS ((const char *, ...));
static void lang_check PARAMS ((void));
static void lang_common PARAMS ((void));
static boolean lang_one_common PARAMS ((struct bfd_link_hash_entry *, PTR));
etree_type *base; /* Relocation base - or null */
-#if defined(__STDC__) || defined(ALMOST_STDC)
+#if defined (__STDC__) || defined (ALMOST_STDC)
#define cat(a,b) a##b
#else
#define cat(a,b) a/**/b
#endif
-/* Don't beautify the line below with "innocent" whitespace, it breaks the K&R C preprocessor! */
-#define new_stat(x, y) (cat (x,_type)*) new_statement (cat (x,_enum), sizeof (cat (x,_type)), y)
+/* Don't beautify the line below with "innocent" whitespace, it breaks
+ the K&R C preprocessor! */
+#define new_stat(x, y) \
+ (cat (x,_type)*) new_statement (cat (x,_enum), sizeof (cat (x,_type)), y)
-#define outside_section_address(q) ((q)->output_offset + (q)->output_section->vma)
+#define outside_section_address(q) \
+ ((q)->output_offset + (q)->output_section->vma)
-#define outside_symbol_address(q) ((q)->value + outside_section_address (q->section))
+#define outside_symbol_address(q) \
+ ((q)->value + outside_section_address (q->section))
#define SECTION_NAME_MAP_LENGTH (16)
if (ptr->exclude_filename_list != NULL)
{
struct name_list *list_tmp;
- for (list_tmp = ptr->exclude_filename_list; list_tmp; list_tmp = list_tmp->next)
+ for (list_tmp = ptr->exclude_filename_list;
+ list_tmp;
+ list_tmp = list_tmp->next)
{
boolean match;
if (wildcardp (list_tmp->name))
- match = fnmatch (list_tmp->name, file->filename, 0) == 0 ? true : false;
+ match = fnmatch (list_tmp->name, file->filename, 0) == 0;
else
- match = strcmp (list_tmp->name, file->filename) == 0 ? true : false;
+ match = strcmp (list_tmp->name, file->filename) == 0;
if (match)
return;
if (section == NULL)
match = true;
else if (wildcard)
- match = fnmatch (section, sname, 0) == 0 ? true : false;
+ match = fnmatch (section, sname, 0) == 0;
else
- match = strcmp (section, sname) == 0 ? true : false;
+ match = strcmp (section, sname) == 0;
/* If this is a wild-card output section statement, exclude
sections that match UNIQUE_SECTION_LIST. */
We can be supplied with requests for input files more than once;
they may, for example be split over serveral lines like foo.o(.text)
- foo.o(.data) etc, so when asked for a file we check that we havn't
+ foo.o(.data) etc, so when asked for a file we check that we haven't
got it already so we don't duplicate the bfd. */
static lang_input_statement_type *
lang_memory_region_type *new =
(lang_memory_region_type *) stat_alloc (sizeof (lang_memory_region_type));
- new->name = buystring (name);
+ new->name = xstrdup (name);
new->next = (lang_memory_region_type *) NULL;
*lang_memory_region_list_tail = new;
flagword flags;
if (output->bfd_section == NULL)
- {
- init_os (output);
- first = true;
- }
- else
- first = false;
+ init_os (output);
+
+ first = ! output->bfd_section->linker_has_input;
+ output->bfd_section->linker_has_input = 1;
/* Add a section reference to the list. */
new = new_stat (lang_input_section, ptr);
lang_statement_list_type *hold;
err = bfd_get_error ();
+
+ /* See if the emulation has some special knowledge. */
+ if (ldemul_unrecognized_file (entry))
+ return;
+
if (err == bfd_error_file_ambiguously_recognized)
{
char **p;
bfd_close (entry->the_bfd);
entry->the_bfd = NULL;
- /* See if the emulation has some special knowledge. */
-
- if (ldemul_unrecognized_file (entry))
- return;
-
/* Try to interpret the file as a linker script. */
-
ldfile_open_command_file (entry->filename);
hold = stat_ptr;
/* Oh dear, we now have two potential candidates for a successful match.
Compare their names and choose the better one. */
- if (name_compare (target->name, original->name) > name_compare (winner->name, original->name))
+ if (name_compare (target->name, original->name)
+ > name_compare (winner->name, original->name))
winner = target;
/* Keep on searching until wqe have checked them all. */
/* Try to find a target as similar as possible to
the default target, but which has the desired
endian characteristic. */
- (void) bfd_search_for_target (closest_target_match, (PTR) target);
+ (void) bfd_search_for_target (closest_target_match,
+ (PTR) target);
/* Oh dear - we could not find any targets that
satisfy our requirements. */
if (s->input_statement.real)
{
lang_statement_list_type add;
+ bfd_error_handler_type pfn;
s->input_statement.target = current_target;
lang_list_init (&add);
+ /* We need to know if an error occurs whilst loading the
+ symbols, since this means that a valid executable can
+ not be produced. */
+ pfn = bfd_set_error_handler (record_bfd_errors);
+
load_symbols (&s->input_statement, &add);
+ bfd_set_error_handler (pfn);
+
if (add.head != NULL)
{
*add.tail = s->next;
new->next = ldlang_undef_chain_list_head;
ldlang_undef_chain_list_head = new;
- new->name = buystring (name);
+ new->name = xstrdup (name);
}
/* Run through the list of undefineds created above and place them
}
#define IGNORE_SECTION(bfd, s) \
- (((bfd_get_section_flags (bfd, s) & (SEC_ALLOC | SEC_LOAD)) != (SEC_ALLOC | SEC_LOAD)) \
+ (((bfd_get_section_flags (bfd, s) & (SEC_ALLOC | SEC_LOAD)) \
+ != (SEC_ALLOC | SEC_LOAD)) \
|| bfd_section_size (bfd, s) == 0)
/* Check to see if any allocated sections overlap with other allocated
case lang_output_section_statement_enum:
{
bfd_vma after;
- lang_output_section_statement_type *os = &s->output_section_statement;
+ lang_output_section_statement_type *os;
+ os = &s->output_section_statement;
if (os->bfd_section == NULL)
/* This section was never actually created. */
break;
&& ! link_info.relocateable
&& strcmp (os->region->name, "*default*") == 0
&& lang_memory_region_list != NULL
- && (strcmp (lang_memory_region_list->name, "*default*") != 0
+ && (strcmp (lang_memory_region_list->name,
+ "*default*") != 0
|| lang_memory_region_list->next != NULL))
einfo (_("%P: warning: no memory region specified for section `%s'\n"),
- bfd_get_section_name (output_bfd, os->bfd_section));
+ bfd_get_section_name (output_bfd,
+ os->bfd_section));
dot = os->region->current;
bfd_vma olddot;
olddot = dot;
- dot = align_power (dot, os->bfd_section->alignment_power);
+ dot = align_power (dot,
+ os->bfd_section->alignment_power);
if (dot != olddot && config.warn_section_align)
einfo (_("%P: warning: changing start of section %s by %u bytes\n"),
case lang_output_section_statement_enum:
{
- lang_output_section_statement_type *os =
- &(s->output_section_statement);
+ lang_output_section_statement_type *os;
+ os = &(s->output_section_statement);
if (os->bfd_section != NULL)
{
dot = os->bfd_section->vma;
h = bfd_link_hash_lookup (link_info.hash, buf, false, false, true);
if (h != NULL && h->type == bfd_link_hash_undefined)
{
- unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
- ldfile_output_machine);
+ unsigned opb;
+
+ opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
+ ldfile_output_machine);
h->type = bfd_link_hash_defined;
if (s->_cooked_size != 0)
h->u.def.value = s->_cooked_size / opb;
}
}
+/* This is the routine to handle BFD error messages. */
+
+#ifdef ANSI_PROTOTYPES
+
+static void
+record_bfd_errors (const char *s, ...)
+{
+ va_list p;
+
+ einfo ("%P: ");
+
+ va_start (p, s);
+
+ vfprintf (stderr, s, p);
+
+ va_end (p);
+
+ fprintf (stderr, "\n");
+
+ einfo ("%X");
+}
+
+#else /* ! defined (ANSI_PROTOTYPES) */
+
+static void
+record_bfd_errors (va_alist)
+ va_dcl
+{
+ va_list p;
+ const char *s;
+
+ einfo ("%P: ");
+
+ va_start (p);
+
+ s = va_arg (p, const char *);
+ vfprintf (stderr, s, p);
+
+ va_end (p);
+
+ fprintf (stderr, "\n");
+
+ einfo ("%X");
+}
+
+#endif /* ! defined (ANSI_PROTOTYPES) */
+
/* This is a small function used when we want to ignore errors from
BFD. */
const char *name;
etree_type *address;
{
- lang_address_statement_type *ad = new_stat (lang_address_statement, stat_ptr);
+ lang_address_statement_type *ad;
+ ad = new_stat (lang_address_statement, stat_ptr);
ad->section_name = name;
ad->address = address;
}
lang_final_phase_enum);
if (! bfd_record_phdr (output_bfd, l->type,
- l->flags == NULL ? false : true,
- flags,
- l->at == NULL ? false : true,
+ l->flags != NULL, flags, l->at != NULL,
at, l->filehdr, l->phdrs, c, secs))
einfo (_("%F%P: bfd_record_phdr failed: %E\n"));
}
%{
-/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999
+/* Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
#include "ldfile.h"
#include "ldlex.h"
#include "ldmain.h"
+#include "libiberty.h"
/* The type of top-level parser input.
yylex and yyparse (indirectly) both check this. */
<DEFSYMEXP>"-" { RTOKEN('-');}
<DEFSYMEXP>"+" { RTOKEN('+');}
-<DEFSYMEXP>{FILENAMECHAR1}{SYMBOLCHARN}* { yylval.name = buystring(yytext); return NAME; }
+<DEFSYMEXP>{FILENAMECHAR1}{SYMBOLCHARN}* { yylval.name = xstrdup(yytext); return NAME; }
<DEFSYMEXP>"=" { RTOKEN('='); }
<MRI,EXPRESSION>"$"([0-9A-Fa-f])+ {
<MRI>{FILENAMECHAR1}{NOCFILENAMECHAR}* {
/* Filename without commas, needed to parse mri stuff */
- yylval.name = buystring(yytext);
+ yylval.name = xstrdup(yytext);
return NAME;
}
<BOTH,EXPRESSION>{FILENAMECHAR1}{FILENAMECHAR}* {
- yylval.name = buystring(yytext);
+ yylval.name = xstrdup(yytext);
return NAME;
}
<BOTH,EXPRESSION>"-l"{FILENAMECHAR}+ {
- yylval.name = buystring (yytext + 2);
+ yylval.name = xstrdup (yytext + 2);
return LNAME;
}
<SCRIPT>{WILDCHAR}* {
}
else
{
- yylval.name = buystring(yytext);
+ yylval.name = xstrdup(yytext);
return NAME;
}
}
<EXPRESSION,BOTH,SCRIPT,VERS_NODE>"\""[^\"]*"\"" {
/* No matter the state, quotes
give what's inside */
- yylval.name = buystring(yytext+1);
+ yylval.name = xstrdup(yytext+1);
yylval.name[yyleng-2] = 0;
return NAME;
}
<VERS_NODE>extern { RTOKEN(EXTERN); }
-<VERS_NODE>{V_IDENTIFIER} { yylval.name = buystring (yytext);
+<VERS_NODE>{V_IDENTIFIER} { yylval.name = xstrdup (yytext);
return VERS_IDENTIFIER; }
-<VERS_SCRIPT>{V_TAG} { yylval.name = buystring (yytext);
+<VERS_SCRIPT>{V_TAG} { yylval.name = xstrdup (yytext);
return VERS_TAG; }
<VERS_START>"{" { BEGIN(VERS_SCRIPT); return *yytext; }
/* Main program of GNU linker.
- Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
Free Software Foundation, Inc.
Written by Steve Chamberlain steve@cygnus.com
error_count = 0;
if (error_name != (char *) NULL)
free (error_name);
- error_name = buystring (name);
+ error_name = xstrdup (name);
}
if (section != NULL)
/* ldmisc.c
- Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support.
last_bfd = abfd;
if (last_file != NULL)
free (last_file);
- last_file = buystring (filename);
+ last_file = xstrdup (filename);
if (last_function != NULL)
free (last_function);
- last_function = buystring (functionname);
+ last_function = xstrdup (functionname);
}
discard_last = false;
if (linenumber != 0)
einfo (_("%F%P: internal error %s %d\n"), file, line);
}
-char *
-buystring (x)
- CONST char *CONST x;
-{
- size_t l = strlen (x) + 1;
- char *r = xmalloc (l);
- memcpy (r, x, l);
- return r;
-}
-
/* ('m' for map) Format info message and print on map. */
void
/* ldmisc.h -
- Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Copyright 1991, 1992, 1993, 1994, 1996, 1997
+ Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
extern PTR xmalloc PARAMS ((size_t));
extern PTR xrealloc PARAMS ((PTR, size_t));
extern void xexit PARAMS ((int));
-extern char *buystring PARAMS ((CONST char *CONST));
#define ASSERT(x) \
do { if (!(x)) info_assert(__FILE__,__LINE__); } while (0)
/* Parse options for the GNU linker.
- Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001
Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
/* Fall through. */
case OPTION_RPATH:
if (command_line.rpath == NULL)
- command_line.rpath = buystring (optarg);
+ command_line.rpath = xstrdup (optarg);
else
{
size_t rpath_len = strlen (command_line.rpath);
break;
case OPTION_RPATH_LINK:
if (command_line.rpath_link == NULL)
- command_line.rpath_link = buystring (optarg);
+ command_line.rpath_link = xstrdup (optarg);
else
{
char *buf;
/* This file is is generated by a shell script. DO NOT EDIT! */
/* AIX emulation code for ppcmacos
- Copyright (C) 1991, 93, 95, 98, 2000 Free Software Foundation, Inc.
+ Copyright 1991, 1993, 1995, 1996, 1997, 2000
+ Free Software Foundation, Inc.
Written by Steve Chamberlain <sac@cygnus.com>
AIX support by Ian Lance Taylor <ian@cygnus.com>
n = ((struct export_symbol_list *)
xmalloc (sizeof (struct export_symbol_list)));
n->next = export_symbols;
- n->name = buystring (symname);
+ n->name = xstrdup (symname);
n->syscall = syscall;
export_symbols = n;
}
+2001-05-23 Alan Modra <amodra@one.net.au>
+
+ * arc-opc.c: Whitespace changes.
+
+ Merge from mainline
+ 2001-05-12 Peter Targett <peter.targett@arccores.com>
+ * arc-opc.c (arc_reg_names): Correct attribute for lp_count
+ register to r/w. Formatting fixes throughout file.
+
2001-05-12 Alan Modra <amodra@one.net.au>
* i386-dis.c (prefix_user_table): Correct movq2dq, movdq2q, and
* ia64-dis.c (print_insn_ia64): Cast away const on ia64_free_opcode
argument.
- * ia64_gen.c (insert_deplist): Cast sizeof result to int.
+ * ia64-gen.c (insert_deplist): Cast sizeof result to int.
(print_dependency_table): Print NULL if semantics field not set.
(insert_opcode_dependencies): Mark cmp parameter as unused.
(print_main_table): Use fprintf_vma to print long long fields.
Delete "sel" code operands from mfc1 and mtc1.
Add MIPS64 opcode changes (dclo, dclz), and "sel" code variants
for dm[ft]c[023].
-
+
2000-12-03 Ed Satterthwaite ehs@sibyte.com and
Chris Demetriou cgd@sibyte.com
"mfc2," "mfc3," "mtc1," "mtc2," and "mtc3" for MIPS32. Update
MIPS32 "sdbbp" to use 'B' operand specifier. Add MIPS32
"wait" variant which uses 'J' operand specifier.
-
+
* mips-dis.c (set_mips_isa_type): Update to use
CPU_UNKNOWN and ISA_* constants. Add bfd_mach_mips32 case.
Replace bfd_mach_mips4K with bfd_mach_mips32_4k case.
* sparc-dis.c (v9a_asr_reg_names): Add v9b ASRs.
(compute_arch_mask): Add v8plusb and v9b machines.
(print_insn_sparc): siam mode decoding, accept ASRs up to 25.
- * opcodes/sparc-opc.c: Support for Cheetah instruction set.
+ * sparc-opc.c: Support for Cheetah instruction set.
(prefetch_table): Add #invalidate.
2000-10-16 Nick Clifton <nickc@redhat.com>
* ia64-ic.tbl: Update from Intel.
* ia64-asmtab.c: Regenerate.
-
+
2000-10-04 Kazu Hirata <kazu@hxi.com>
* ia64-gen.c: Convert C++-style comments to C-style comments.
* ia64-asmtab.c: Regnerate.
2000-09-13 Anders Norlander <anorland@acc.umu.se>
-
- * mips-opc.c (mips_builtin_opcodes): Support cache instruction on 4K cores.
- Add mfc0 and mtc0 with sub-selection values.
+
+ * mips-opc.c (mips_builtin_opcodes): Support cache instruction on 4K cores.
+ Add mfc0 and mtc0 with sub-selection values.
Add clo and clz opcodes.
- Add msub and msubu instructions for MIPS32.
- Add madd/maddu aliases for mad/madu for MIPS32.
- Support wait, deret, eret, movn, pref for MIPS32.
+ Add msub and msubu instructions for MIPS32.
+ Add madd/maddu aliases for mad/madu for MIPS32.
+ Support wait, deret, eret, movn, pref for MIPS32.
Support tlbp, tlbr, tlbwi, tlbwr.
- (P4): New define.
-
- * mips-dis.c (print_insn_arg): Print sdbbp 'm' args.
- (print_insn_arg): Handle 'H' args.
- (set_mips_isa_type): Recognize 4K.
+ (P4): New define.
+
+ * mips-dis.c (print_insn_arg): Print sdbbp 'm' args.
+ (print_insn_arg): Handle 'H' args.
+ (set_mips_isa_type): Recognize 4K.
Use CPU_* defines instead of hardcoded numbers.
2000-09-11 Catherine Moore <clm@redhat.com>
* d30v-opc.c (d30v_operand_t): New operand type Rb2.
(d30v_format_tab): Use Rb2 for modinc and moddec.
-
+
2000-09-07 Catherine Moore <clm@redhat.com>
-
+
* d30v-opc.c (d30v_format_tab): Use format Ra for
modinc and moddec.
* configure: Regenerate.
* po/opcodes.pot: Regenerate.
-
+
2000-08-31 Alexandre Oliva <aoliva@redhat.com>
* acinclude.m4: Include libtool and gettext macros from the
in the buffer.
* fr30-asm.c: Regenerated.
* fr30-desc.c: Regenerated.
- * fr30-desc.h Regenerated.
+ * fr30-desc.h: Regenerated.
* fr30-dis.c: Regenerated.
* fr30-ibld.c: Regenerated.
* fr30-opc.c: Regenerated.
- * fr30-opc.h Regenerated.
+ * fr30-opc.h: Regenerated.
* m32r-asm.c: Regenerated.
* m32r-desc.c: Regenerated.
- * m32r-desc.h Regenerated.
+ * m32r-desc.h: Regenerated.
* m32r-dis.c: Regenerated.
* m32r-ibld.c: Regenerated.
* m32r-opc.c: Regenerated.
* cgen.sh: Likewise.
2000-08-02 Jim Wilson <wilson@redhat.com>
-
+
* ia64-dis.c (print_insn_ia64): Call ia64_free_opcode at end.
2000-07-29 Marek Michalkiewicz <marekm@linux.org.pl>
2000-06-18 Stephane Carrez <stcarrez@worldnet.fr>
* Makefile.in, configure: regenerate
- * disassemble.c (disassembler): Recognize ARCH_m68hc12,
+ * disassemble.c (disassembler): Recognize ARCH_m68hc12,
ARCH_m68hc11.
- * m68hc11-dis.c (read_memory, print_insn, print_insn_m68hc12):
+ * m68hc11-dis.c (read_memory, print_insn, print_insn_m68hc12):
New functions.
* configure.in: Recognize m68hc12 and m68hc11.
* m68hc11-dis.c, m68hc11-opc.c: New files for support of m68hc1x
- * Makefile.am (CFILES, ALL_MACHINES): New files for disassembly
+ * Makefile.am (CFILES, ALL_MACHINES): New files for disassembly
and opcode generation for m68hc11 and m68hc12.
2000-06-16 Nick Duffek <nsd@redhat.com>
2000-05-11 Thomas de Lellis <tdel@windriver.com>
- * arm-opc.c: Disassembly of thumb ldsb/ldsh
+ * arm-opc.h: Disassembly of thumb ldsb/ldsh
instructions changed to ldrsb/ldrsh.
2000-05-11 Ulf Carlsson <ulfc@engr.sgi.com>
* ia64-asmtab.c, ia64-asmtab.h, ia64-dis.c, ia64-gen.c ia64-ic.tbl,
ia64-opc-a.c, ia64-opc-b.c, ia64-opc-d.c ia64-opc-f.c, ia64-opc-i.c,
ia64-opc-m.c, ia64-opc-x.c, ia64-opc.c, ia64-opc.h, ia64-raw.tbl,
- ia64-war.tbl, ia64-waw.tbl): New files.
+ ia64-war.tbl, ia64-waw.tbl: New files.
2000-04-20 Alexandre Oliva <aoliva@redhat.com>
2000-04-05 J"orn Rennecke <amylaar@redhat.com>
- * sh-opc.c (sh_table): Use A_DISP_PC / PCRELIMM_8BY2 for ldre & ldrs.
+ * sh-opc.h (sh_table): Use A_DISP_PC / PCRELIMM_8BY2 for ldre & ldrs.
stc GBR,@-<REG_N> is available for arch_sh1_up.
Group parallel processing insn with identical mnemonics together.
Make three-operand psha / pshl come first.
2000-02-23 Andrew Haley <aph@redhat.com>
* m32r-asm.c, m32r-desc.c, m32r-desc.h, m32r-dis.c,
- m32r-ibld.c,m32r-opc.h: Rebuild.
+ m32r-ibld.c, m32r-opc.h: Rebuild.
2000-02-23 Linas Vepstas <linas@linas.org>
/* Opcode table for the ARC.
- Copyright 1994, 1995, 1997, 1998, 2000 Free Software Foundation, Inc.
+ Copyright 1994, 1995, 1997, 1998, 2000, 2001
+ Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com).
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
{ "r59", 59, REG, 0 },
/* Loop count register (24 bits). */
- { "lp_count", 60, REG, ARC_REGISTER_READONLY },
+ { "lp_count", 60, REG, 0 },
/* Short immediate data indicator setting flags. */
{ "r61", 61, REG, ARC_REGISTER_READONLY },
/* Long immediate data indicator setting flags. */
int
arc_opcode_limm_p (limmp)
- long *limmp;
+ long *limmp;
{
if (limmp)
*limmp = limm;
static arc_insn
insert_reg (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand;
- int mods;
- const struct arc_operand_value *reg;
- long value;
- const char **errmsg;
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ long value;
+ const char **errmsg;
{
static char buf[100];
enum operand op_type = OP_NONE;
{
int marker;
- op_type = OP_SHIMM;
- /* forget about shimm as dest mlm. */
+ op_type = OP_SHIMM;
+ /* forget about shimm as dest mlm. */
- if('a' != operand->fmt)
+ if ('a' != operand->fmt)
{
shimm_p = 1;
shimm = value;
flagshimm_handled_p = 1;
marker = flag_p ? ARC_REG_SHIMM_UPDATE : ARC_REG_SHIMM;
}
- else
- {
+ else
+ {
/* don't request flag setting on shimm as dest. */
marker = ARC_REG_SHIMM;
- }
+ }
insn |= marker << operand->shift;
/* insn |= value & 511; - done later. */
}
*errmsg = "auxiliary register not allowed here";
else
{
- if((insn & I(-1)) == I(2)) /* check for use validity. */
- {
- if(reg->flags & ARC_REGISTER_READONLY)
- *errmsg = "attempt to set readonly register";
- }
- else
- {
- if(reg->flags & ARC_REGISTER_WRITEONLY)
- *errmsg = "attempt to read writeonly register";
- }
+ if ((insn & I(-1)) == I(2)) /* check for use validity. */
+ {
+ if (reg->flags & ARC_REGISTER_READONLY)
+ *errmsg = "attempt to set readonly register";
+ }
+ else
+ {
+ if (reg->flags & ARC_REGISTER_WRITEONLY)
+ *errmsg = "attempt to read writeonly register";
+ }
insn |= ARC_REG_SHIMM << operand->shift;
insn |= reg->value << arc_operands[reg->type].shift;
}
}
else
{
- /* check for use validity. */
- if('a' == operand->fmt || ((insn & I(-1)) < I(2)))
- {
- if(reg->flags & ARC_REGISTER_READONLY)
+ /* check for use validity. */
+ if ('a' == operand->fmt || ((insn & I(-1)) < I(2)))
+ {
+ if (reg->flags & ARC_REGISTER_READONLY)
*errmsg = "attempt to set readonly register";
- }
- if('a' != operand->fmt)
- {
- if(reg->flags & ARC_REGISTER_WRITEONLY)
+ }
+ if ('a' != operand->fmt)
+ {
+ if (reg->flags & ARC_REGISTER_WRITEONLY)
*errmsg = "attempt to read writeonly register";
- }
+ }
/* We should never get an invalid register number here. */
if ((unsigned int) reg->value > 60)
{
*errmsg = buf;
}
insn |= reg->value << operand->shift;
- op_type = OP_REG;
+ op_type = OP_REG;
}
}
switch (operand->fmt)
{
case 'a':
- ls_operand[LS_DEST] = op_type;
+ ls_operand[LS_DEST] = op_type;
break;
case 's':
- ls_operand[LS_BASE] = op_type;
+ ls_operand[LS_BASE] = op_type;
break;
case 'c':
if ((insn & I(-1)) == I(2))
- ls_operand[LS_VALUE] = op_type;
+ ls_operand[LS_VALUE] = op_type;
else
- ls_operand[LS_OFFSET] = op_type;
+ ls_operand[LS_OFFSET] = op_type;
break;
case 'o': case 'O':
ls_operand[LS_OFFSET] = op_type;
static arc_insn
insert_flag (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand ATTRIBUTE_UNUSED;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
- long value ATTRIBUTE_UNUSED;
- const char **errmsg ATTRIBUTE_UNUSED;
+ arc_insn insn;
+ const struct arc_operand *operand ATTRIBUTE_UNUSED;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
+ long value ATTRIBUTE_UNUSED;
+ const char **errmsg ATTRIBUTE_UNUSED;
{
/* We can't store anything in the insn until we've parsed the registers.
Just record the fact that we've got this flag. `insert_reg' will use it
static arc_insn
insert_nullify (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
- long value;
- const char **errmsg ATTRIBUTE_UNUSED;
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
+ long value;
+ const char **errmsg ATTRIBUTE_UNUSED;
{
nullify_p = 1;
insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
static arc_insn
insert_flagfinish (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
- long value ATTRIBUTE_UNUSED;
- const char **errmsg ATTRIBUTE_UNUSED;
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
+ long value ATTRIBUTE_UNUSED;
+ const char **errmsg ATTRIBUTE_UNUSED;
{
if (flag_p && !flagshimm_handled_p)
{
static arc_insn
insert_cond (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
- long value;
- const char **errmsg ATTRIBUTE_UNUSED;
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
+ long value;
+ const char **errmsg ATTRIBUTE_UNUSED;
{
cond_p = 1;
insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
static arc_insn
insert_forcelimm (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand ATTRIBUTE_UNUSED;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
- long value ATTRIBUTE_UNUSED;
- const char **errmsg ATTRIBUTE_UNUSED;
+ arc_insn insn;
+ const struct arc_operand *operand ATTRIBUTE_UNUSED;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
+ long value ATTRIBUTE_UNUSED;
+ const char **errmsg ATTRIBUTE_UNUSED;
{
cond_p = 1;
return insn;
static arc_insn
insert_addr_wb (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
- long value ATTRIBUTE_UNUSED;
- const char **errmsg ATTRIBUTE_UNUSED;
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
+ long value ATTRIBUTE_UNUSED;
+ const char **errmsg ATTRIBUTE_UNUSED;
{
addrwb_p = 1 << operand->shift;
return insn;
static arc_insn
insert_base (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand;
- int mods;
- const struct arc_operand_value *reg;
- long value;
- const char **errmsg;
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ long value;
+ const char **errmsg;
{
if (reg != NULL)
{
arc_insn myinsn;
myinsn = insert_reg (0, operand,mods, reg, value, errmsg) >> operand->shift;
insn |= B(myinsn);
- ls_operand[LS_BASE] = OP_REG;
+ ls_operand[LS_BASE] = OP_REG;
}
else if (ARC_SHIMM_CONST_P (value) && !cond_p)
{
if (shimm_p && value != shimm)
- {
- /* convert the previous shimm operand to a limm. */
- limm_p = 1;
- limm = shimm;
- insn &= ~C(-1); /* we know where the value is in insn. */
- insn |= C(ARC_REG_LIMM);
- ls_operand[LS_VALUE] = OP_LIMM;
- }
+ {
+ /* convert the previous shimm operand to a limm. */
+ limm_p = 1;
+ limm = shimm;
+ insn &= ~C(-1); /* we know where the value is in insn. */
+ insn |= C(ARC_REG_LIMM);
+ ls_operand[LS_VALUE] = OP_LIMM;
+ }
insn |= ARC_REG_SHIMM << operand->shift;
shimm_p = 1;
shimm = value;
else
{
if (limm_p && value != limm)
- {
- *errmsg = "too many long constants";
- return insn;
- }
+ {
+ *errmsg = "too many long constants";
+ return insn;
+ }
limm_p = 1;
limm = value;
insn |= B(ARC_REG_LIMM);
static arc_insn
insert_offset (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand;
- int mods;
- const struct arc_operand_value *reg;
- long value;
- const char **errmsg;
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ long value;
+ const char **errmsg;
{
long minval, maxval;
myinsn = insert_reg (0,operand,mods,reg,value,errmsg) >> operand->shift;
ls_operand[LS_OFFSET] = OP_REG;
if (operand->flags & ARC_OPERAND_LOAD) /* not if store, catch it later. */
- if ((insn & I(-1)) != I(1)) /* not if opcode == 1, catch it later. */
- insn |= C(myinsn);
+ if ((insn & I(-1)) != I(1)) /* not if opcode == 1, catch it later. */
+ insn |= C(myinsn);
}
else
{
}
if ((cond_p && !limm_p) || (value < minval || value > maxval))
{
- if (limm_p && value != limm)
- {
- *errmsg = "too many long constants";
- }
- else
- {
- limm_p = 1;
- limm = value;
- if (operand->flags & ARC_OPERAND_STORE)
- insn |= B(ARC_REG_LIMM);
- if (operand->flags & ARC_OPERAND_LOAD)
- insn |= C(ARC_REG_LIMM);
- ls_operand[LS_OFFSET] = OP_LIMM;
- }
+ if (limm_p && value != limm)
+ {
+ *errmsg = "too many long constants";
+ }
+ else
+ {
+ limm_p = 1;
+ limm = value;
+ if (operand->flags & ARC_OPERAND_STORE)
+ insn |= B(ARC_REG_LIMM);
+ if (operand->flags & ARC_OPERAND_LOAD)
+ insn |= C(ARC_REG_LIMM);
+ ls_operand[LS_OFFSET] = OP_LIMM;
+ }
}
else
- {
+ {
if ((value < minval || value > maxval))
*errmsg = "need too many limms";
- else if (shimm_p && value != shimm)
+ else if (shimm_p && value != shimm)
{
/* check for bad operand combinations before we lose info about them. */
if ((insn & I(-1)) == I(1))
shimm = value;
shimm_p = 1;
ls_operand[LS_OFFSET] = OP_SHIMM;
- }
+ }
}
out:
return insn;
static long
extract_st_syntax (insn, operand, mods, opval, invalid)
- arc_insn *insn;
- const struct arc_operand *operand ATTRIBUTE_UNUSED;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
- int *invalid;
+ arc_insn *insn;
+ const struct arc_operand *operand ATTRIBUTE_UNUSED;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
+ int *invalid;
{
#define ST_SYNTAX(V,B,O) \
((ls_operand[LS_VALUE] == (V) && \
ls_operand[LS_BASE] == (B) && \
ls_operand[LS_OFFSET] == (O)))
- if (!((ST_SYNTAX(OP_REG,OP_REG,OP_NONE) && (insn[0] & 511) == 0)
+
+ if (!((ST_SYNTAX(OP_REG,OP_REG,OP_NONE) && (insn[0] & 511) == 0)
|| ST_SYNTAX(OP_REG,OP_LIMM,OP_NONE)
|| (ST_SYNTAX(OP_SHIMM,OP_REG,OP_NONE) && (insn[0] & 511) == 0)
|| (ST_SYNTAX(OP_SHIMM,OP_SHIMM,OP_NONE) && (insn[0] & 511) == 0)
|| ST_SYNTAX(OP_SHIMM,OP_LIMM,OP_NONE)
|| ST_SYNTAX(OP_SHIMM,OP_LIMM,OP_SHIMM)
|| ST_SYNTAX(OP_SHIMM,OP_SHIMM,OP_SHIMM)
- || (ST_SYNTAX(OP_LIMM,OP_REG,OP_NONE) && (insn[0] & 511) == 0)
+ || (ST_SYNTAX(OP_LIMM,OP_REG,OP_NONE) && (insn[0] & 511) == 0)
|| ST_SYNTAX(OP_REG,OP_REG,OP_SHIMM)
|| ST_SYNTAX(OP_REG,OP_SHIMM,OP_SHIMM)
|| ST_SYNTAX(OP_SHIMM,OP_REG,OP_SHIMM)
int
arc_limm_fixup_adjust(insn)
- arc_insn insn;
+ arc_insn insn;
{
int retval = 0;
/* check for st shimm,[limm]. */
if ((insn & (I(-1) | C(-1) | B(-1))) ==
- (I(2) | C(ARC_REG_SHIMM) | B(ARC_REG_LIMM)))
+ (I(2) | C(ARC_REG_SHIMM) | B(ARC_REG_LIMM)))
{
retval = insn & 0x1ff;
if (retval & 0x100) /* sign extend 9 bit offset. */
retval |= ~0x1ff;
}
- return(-retval); /* negate offset for return. */
+ return -retval; /* negate offset for return. */
}
/* Used in st insns to do final syntax check. */
static arc_insn
insert_st_syntax (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand ATTRIBUTE_UNUSED;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
- long value ATTRIBUTE_UNUSED;
- const char **errmsg;
+ arc_insn insn;
+ const struct arc_operand *operand ATTRIBUTE_UNUSED;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
+ long value ATTRIBUTE_UNUSED;
+ const char **errmsg;
{
if (ST_SYNTAX(OP_SHIMM,OP_REG,OP_NONE) && shimm != 0)
{
if (ST_SYNTAX(OP_REG,OP_SHIMM,OP_NONE) || ST_SYNTAX(OP_LIMM,OP_SHIMM,OP_NONE))
{
/* try to salvage this syntax. */
- if (shimm & 0x1) /* odd shimms won't work. */
- {
- if (limm_p) /* do we have a limm already? */
- {
- *errmsg = "impossible store";
- }
- limm_p = 1;
- limm = shimm;
- shimm = 0;
- shimm_p = 0;
- insn = insn & ~(B(-1) | 511);
- insn |= B(ARC_REG_LIMM);
- ls_operand[LS_BASE] = OP_LIMM;
- }
- else
- {
- shimm >>= 1;
- insn = insn & ~511;
- insn |= shimm;
- ls_operand[LS_OFFSET] = OP_SHIMM;
- }
+ if (shimm & 0x1) /* odd shimms won't work. */
+ {
+ if (limm_p) /* do we have a limm already? */
+ {
+ *errmsg = "impossible store";
+ }
+ limm_p = 1;
+ limm = shimm;
+ shimm = 0;
+ shimm_p = 0;
+ insn = insn & ~(B(-1) | 511);
+ insn |= B(ARC_REG_LIMM);
+ ls_operand[LS_BASE] = OP_LIMM;
+ }
+ else
+ {
+ shimm >>= 1;
+ insn = insn & ~511;
+ insn |= shimm;
+ ls_operand[LS_OFFSET] = OP_SHIMM;
+ }
}
if (ST_SYNTAX(OP_SHIMM,OP_LIMM,OP_NONE))
{
|| ST_SYNTAX(OP_SHIMM,OP_REG,OP_SHIMM)
|| ST_SYNTAX(OP_SHIMM,OP_SHIMM,OP_SHIMM)
|| ST_SYNTAX(OP_LIMM,OP_SHIMM,OP_SHIMM)
- || ST_SYNTAX(OP_LIMM,OP_REG,OP_NONE)
+ || ST_SYNTAX(OP_LIMM,OP_REG,OP_NONE)
|| ST_SYNTAX(OP_LIMM,OP_REG,OP_SHIMM)))
*errmsg = "st operand error";
if (addrwb_p)
static arc_insn
insert_ld_syntax (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand ATTRIBUTE_UNUSED;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
- long value ATTRIBUTE_UNUSED;
- const char **errmsg;
+ arc_insn insn;
+ const struct arc_operand *operand ATTRIBUTE_UNUSED;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
+ long value ATTRIBUTE_UNUSED;
+ const char **errmsg;
{
#define LD_SYNTAX(D,B,O) \
((ls_operand[LS_DEST] == (D) && \
int test = insn & I(-1);
if (!(test == I(1)))
- {
- if ((ls_operand[LS_DEST] == OP_SHIMM || ls_operand[LS_BASE] == OP_SHIMM
- || ls_operand[LS_OFFSET] == OP_SHIMM))
- *errmsg = "invalid load/shimm insn";
- }
+ {
+ if ((ls_operand[LS_DEST] == OP_SHIMM || ls_operand[LS_BASE] == OP_SHIMM
+ || ls_operand[LS_OFFSET] == OP_SHIMM))
+ *errmsg = "invalid load/shimm insn";
+ }
if (!(LD_SYNTAX(OP_REG,OP_REG,OP_NONE)
|| LD_SYNTAX(OP_REG,OP_REG,OP_REG)
|| LD_SYNTAX(OP_REG,OP_REG,OP_SHIMM)
|| (LD_SYNTAX(OP_REG,OP_LIMM,OP_REG) && !(test == I(1)))
|| (LD_SYNTAX(OP_REG,OP_REG,OP_LIMM) && !(test == I(1)))
- || LD_SYNTAX(OP_REG,OP_SHIMM,OP_SHIMM)
+ || LD_SYNTAX(OP_REG,OP_SHIMM,OP_SHIMM)
|| (LD_SYNTAX(OP_REG,OP_LIMM,OP_NONE) && (test == I(1)))))
- *errmsg = "ld operand error";
+ *errmsg = "ld operand error";
if (addrwb_p)
{
if (ls_operand[LS_BASE] != OP_REG)
static long
extract_ld_syntax (insn, operand, mods, opval, invalid)
- arc_insn *insn;
- const struct arc_operand *operand ATTRIBUTE_UNUSED;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
- int *invalid;
+ arc_insn *insn;
+ const struct arc_operand *operand ATTRIBUTE_UNUSED;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
+ int *invalid;
{
int test = insn[0] & I(-1);
if (!(test == I(1)))
{
- if((ls_operand[LS_DEST] == OP_SHIMM || ls_operand[LS_BASE] == OP_SHIMM
- || ls_operand[LS_OFFSET] == OP_SHIMM))
+ if ((ls_operand[LS_DEST] == OP_SHIMM || ls_operand[LS_BASE] == OP_SHIMM
+ || ls_operand[LS_OFFSET] == OP_SHIMM))
*invalid = 1;
}
if (!((LD_SYNTAX(OP_REG,OP_REG,OP_NONE) && (test == I(1)))
static arc_insn
insert_shimmfinish (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
- long value ATTRIBUTE_UNUSED;
- const char **errmsg ATTRIBUTE_UNUSED;
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
+ long value ATTRIBUTE_UNUSED;
+ const char **errmsg ATTRIBUTE_UNUSED;
{
if (shimm_p)
insn |= (shimm & ((1 << operand->bits) - 1)) << operand->shift;
static arc_insn
insert_limmfinish (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand ATTRIBUTE_UNUSED;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
- long value ATTRIBUTE_UNUSED;
- const char **errmsg ATTRIBUTE_UNUSED;
+ arc_insn insn;
+ const struct arc_operand *operand ATTRIBUTE_UNUSED;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
+ long value ATTRIBUTE_UNUSED;
+ const char **errmsg ATTRIBUTE_UNUSED;
{
#if 0
if (limm_p)
static arc_insn
insert_jumpflags (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
- long value;
- const char **errmsg;
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
+ long value;
+ const char **errmsg;
{
if (!flag_p)
{
*errmsg = "bad jump flags value";
}
jumpflags_p = 1;
- limm = (limm & ((1 << operand->shift) - 1))
- | ((value & ((1 << operand->bits) - 1)) << operand->shift);
+ limm = ((limm & ((1 << operand->shift) - 1))
+ | ((value & ((1 << operand->bits) - 1)) << operand->shift));
return insn;
}
static arc_insn
insert_unopmacro (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
- long value ATTRIBUTE_UNUSED;
- const char **errmsg ATTRIBUTE_UNUSED;
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
+ long value ATTRIBUTE_UNUSED;
+ const char **errmsg ATTRIBUTE_UNUSED;
{
insn |= ((insn >> ARC_SHIFT_REGB) & ARC_MASK_REG) << operand->shift;
return insn;
static arc_insn
insert_reladdr (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
- long value;
- const char **errmsg;
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
+ long value;
+ const char **errmsg;
{
if (value & 3)
*errmsg = "branch address not on 4 byte boundary";
static arc_insn
insert_absaddr (insn, operand, mods, reg, value, errmsg)
- arc_insn insn;
- const struct arc_operand *operand ATTRIBUTE_UNUSED;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
- long value ATTRIBUTE_UNUSED;
- const char **errmsg;
+ arc_insn insn;
+ const struct arc_operand *operand ATTRIBUTE_UNUSED;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
+ long value ATTRIBUTE_UNUSED;
+ const char **errmsg;
{
if (limm_p)
{
}
else
{
- if(nullify != 0x02)
+ if (nullify != 0x02)
{
*errmsg = "must specify .jd or no nullify suffix";
}
static long
extract_reg (insn, operand, mods, opval, invalid)
- arc_insn *insn;
- const struct arc_operand *operand;
- int mods;
- const struct arc_operand_value **opval;
- int *invalid ATTRIBUTE_UNUSED;
+ arc_insn *insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value **opval;
+ int *invalid ATTRIBUTE_UNUSED;
{
int regno;
long value;
if (regno == ARC_REG_SHIMM)
{
op_type = OP_SHIMM;
- /* always return zero if dest is a shimm mlm. */
+ /* always return zero if dest is a shimm mlm. */
if ('a' != operand->fmt)
{
value = insn[1];
limm_p = 1;
/* if this is a jump instruction (j,jl), show new pc correctly. */
- if(0x07 == ((*insn & I(-1)) >> 27))
- {
+ if (0x07 == ((*insn & I(-1)) >> 27))
+ {
value = (value & 0xffffff);
- }
+ }
}
/* It's a register, set OPVAL (that's the only way we distinguish registers
from constants here). */
*opval = reg;
}
switch(operand->fmt)
- {
- case 'a':
- ls_operand[LS_DEST] = op_type;
- break;
- case 's':
- ls_operand[LS_BASE] = op_type;
- break;
- case 'c':
- if((insn[0]& I(-1)) == I(2))
- ls_operand[LS_VALUE] = op_type;
- else
- ls_operand[LS_OFFSET] = op_type;
- break;
- case 'o': case 'O':
- ls_operand[LS_OFFSET] = op_type;
- break;
- }
+ {
+ case 'a':
+ ls_operand[LS_DEST] = op_type;
+ break;
+ case 's':
+ ls_operand[LS_BASE] = op_type;
+ break;
+ case 'c':
+ if ((insn[0]& I(-1)) == I(2))
+ ls_operand[LS_VALUE] = op_type;
+ else
+ ls_operand[LS_OFFSET] = op_type;
+ break;
+ case 'o': case 'O':
+ ls_operand[LS_OFFSET] = op_type;
+ break;
+ }
return value;
}
static long
extract_flag (insn, operand, mods, opval, invalid)
- arc_insn *insn;
- const struct arc_operand *operand;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value **opval;
- int *invalid ATTRIBUTE_UNUSED;
+ arc_insn *insn;
+ const struct arc_operand *operand;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value **opval;
+ int *invalid ATTRIBUTE_UNUSED;
{
int f;
const struct arc_operand_value *val;
static long
extract_cond (insn, operand, mods, opval, invalid)
- arc_insn *insn;
- const struct arc_operand *operand;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value **opval;
- int *invalid ATTRIBUTE_UNUSED;
+ arc_insn *insn;
+ const struct arc_operand *operand;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value **opval;
+ int *invalid ATTRIBUTE_UNUSED;
{
long cond;
const struct arc_operand_value *val;
static long
extract_reladdr (insn, operand, mods, opval, invalid)
- arc_insn *insn;
- const struct arc_operand *operand;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
- int *invalid ATTRIBUTE_UNUSED;
+ arc_insn *insn;
+ const struct arc_operand *operand;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
+ int *invalid ATTRIBUTE_UNUSED;
{
long addr;
/* extract the flags bits from a j or jl long immediate. */
static long
extract_jumpflags(insn, operand, mods, opval, invalid)
- arc_insn *insn;
- const struct arc_operand *operand;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
- int *invalid;
+ arc_insn *insn;
+ const struct arc_operand *operand;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
+ int *invalid;
{
if (!flag_p || !limm_p)
*invalid = 1;
- return((flag_p && limm_p)
- ? (insn[1] >> operand->shift) & ((1 << operand->bits) -1): 0);
+ return ((flag_p && limm_p)
+ ? (insn[1] >> operand->shift) & ((1 << operand->bits) -1): 0);
}
/* extract st insn's offset. */
static long
extract_st_offset (insn, operand, mods, opval, invalid)
- arc_insn *insn;
- const struct arc_operand *operand;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
- int *invalid;
+ arc_insn *insn;
+ const struct arc_operand *operand;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
+ int *invalid;
{
int value = 0;
value = insn[0] & 511;
if ((operand->flags & ARC_OPERAND_SIGNED) && (value & 256))
value -= 512;
- if(value)
+ if (value)
ls_operand[LS_OFFSET] = OP_SHIMM;
}
else
static long
extract_ld_offset (insn, operand, mods, opval, invalid)
- arc_insn *insn;
- const struct arc_operand *operand;
- int mods;
- const struct arc_operand_value **opval;
- int *invalid;
+ arc_insn *insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value **opval;
+ int *invalid;
{
int test = insn[0] & I(-1);
int value;
ls_operand[LS_OFFSET] = OP_SHIMM;
return(value);
}
-/* if it isn't in the insn, it's concealed behind reg 'c'. */
- return extract_reg(insn,
- &arc_operands[arc_operand_map['c']], mods, opval, invalid);
+ /* if it isn't in the insn, it's concealed behind reg 'c'. */
+ return extract_reg (insn, &arc_operands[arc_operand_map['c']],
+ mods, opval, invalid);
}
/* The only thing this does is set the `invalid' flag if B != C.
static long
extract_unopmacro (insn, operand, mods, opval, invalid)
- arc_insn *insn;
- const struct arc_operand *operand ATTRIBUTE_UNUSED;
- int mods ATTRIBUTE_UNUSED;
- const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
- int *invalid;
+ arc_insn *insn;
+ const struct arc_operand *operand ATTRIBUTE_UNUSED;
+ int mods ATTRIBUTE_UNUSED;
+ const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
+ int *invalid;
{
/* This misses the case where B == ARC_REG_SHIMM_UPDATE &&
C == ARC_REG_SHIMM (or vice versa). No big deal. Those insns will get
const struct arc_operand_value *
arc_opcode_lookup_suffix (type, value)
- const struct arc_operand *type;
- int value;
+ const struct arc_operand *type;
+ int value;
{
register const struct arc_operand_value *v,*end;
struct arc_ext_operand_value *ext_oper = arc_ext_operands;
static const struct arc_operand_value *
lookup_register (type, regno)
- int type;
- long regno;
+ int type;
+ long regno;
{
register const struct arc_operand_value *r,*end;
struct arc_ext_operand_value *ext_oper = arc_ext_operands;
int
arc_insn_is_j(insn)
- arc_insn insn;
+ arc_insn insn;
{
return (insn & (I(-1))) == I(0x7);
}
int
arc_insn_not_jl(insn)
- arc_insn insn;
+ arc_insn insn;
{
- return (insn & (I(-1)|A(-1)|C(-1)|R(-1,7,1)|R(-1,9,1))) !=
- (I(0x7) | R(-1,9,1));
+ return ((insn & (I(-1)|A(-1)|C(-1)|R(-1,7,1)|R(-1,9,1)))
+ != (I(0x7) | R(-1,9,1)));
}
int
struct arc_operand_value *
get_ext_suffix(s)
- char *s;
+ char *s;
{
struct arc_ext_operand_value *suffix = arc_ext_operands;
return(&suffix->operand);
suffix = suffix->next;
}
- return(NULL);
+ return NULL;
}
int
arc_get_noshortcut_flag()
{
- return(ARC_REGISTER_NOSHORT_CUT);
+ return ARC_REGISTER_NOSHORT_CUT;
}