xref: /openbsd-src/gnu/usr.bin/binutils/bfd/coff-sh.c (revision 007c2a4539b8b8aaa95c5e73e77620090abe113b)
1c074d1c9Sdrahn /* BFD back-end for Renesas Super-H COFF binaries.
2c074d1c9Sdrahn    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3b55d4692Sfgsch    Free Software Foundation, Inc.
42159047fSniklas    Contributed by Cygnus Support.
52159047fSniklas    Written by Steve Chamberlain, <sac@cygnus.com>.
6c88b1d6cSniklas    Relaxing code written by Ian Lance Taylor, <ian@cygnus.com>.
72159047fSniklas 
82159047fSniklas    This file is part of BFD, the Binary File Descriptor library.
92159047fSniklas 
102159047fSniklas    This program is free software; you can redistribute it and/or modify
112159047fSniklas    it under the terms of the GNU General Public License as published by
122159047fSniklas    the Free Software Foundation; either version 2 of the License, or
132159047fSniklas    (at your option) any later version.
142159047fSniklas 
152159047fSniklas    This program is distributed in the hope that it will be useful,
162159047fSniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
172159047fSniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
182159047fSniklas    GNU General Public License for more details.
192159047fSniklas 
202159047fSniklas    You should have received a copy of the GNU General Public License
212159047fSniklas    along with this program; if not, write to the Free Software
222159047fSniklas    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
232159047fSniklas 
242159047fSniklas #include "bfd.h"
252159047fSniklas #include "sysdep.h"
26c074d1c9Sdrahn #include "libiberty.h"
272159047fSniklas #include "libbfd.h"
282159047fSniklas #include "bfdlink.h"
292159047fSniklas #include "coff/sh.h"
302159047fSniklas #include "coff/internal.h"
31b305b0f1Sespie 
32b305b0f1Sespie #ifdef COFF_WITH_PE
33b305b0f1Sespie #include "coff/pe.h"
34b305b0f1Sespie 
35b305b0f1Sespie #ifndef COFF_IMAGE_WITH_PE
36c074d1c9Sdrahn static bfd_boolean sh_align_load_span
37b305b0f1Sespie   PARAMS ((bfd *, asection *, bfd_byte *,
38c074d1c9Sdrahn 	   bfd_boolean (*) (bfd *, asection *, PTR, bfd_byte *, bfd_vma),
39c074d1c9Sdrahn 	   PTR, bfd_vma **, bfd_vma *, bfd_vma, bfd_vma, bfd_boolean *));
40b305b0f1Sespie 
41b305b0f1Sespie #define _bfd_sh_align_load_span sh_align_load_span
42b305b0f1Sespie #endif
43b305b0f1Sespie #endif
44b305b0f1Sespie 
452159047fSniklas #include "libcoff.h"
462159047fSniklas 
472159047fSniklas /* Internal functions.  */
482159047fSniklas static bfd_reloc_status_type sh_reloc
492159047fSniklas   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
502159047fSniklas static long get_symbol_value PARAMS ((asymbol *));
51c074d1c9Sdrahn static bfd_boolean sh_relax_section
52c074d1c9Sdrahn   PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
53c074d1c9Sdrahn static bfd_boolean sh_relax_delete_bytes
542159047fSniklas   PARAMS ((bfd *, asection *, bfd_vma, int));
55b305b0f1Sespie #ifndef COFF_IMAGE_WITH_PE
56c88b1d6cSniklas static const struct sh_opcode *sh_insn_info PARAMS ((unsigned int));
57b305b0f1Sespie #endif
58c074d1c9Sdrahn static bfd_boolean sh_align_loads
59c074d1c9Sdrahn   PARAMS ((bfd *, asection *, struct internal_reloc *, bfd_byte *,
60c074d1c9Sdrahn 	   bfd_boolean *));
61c074d1c9Sdrahn static bfd_boolean sh_swap_insns
620c6d0228Sniklas   PARAMS ((bfd *, asection *, PTR, bfd_byte *, bfd_vma));
63c074d1c9Sdrahn static bfd_boolean sh_relocate_section
642159047fSniklas   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
652159047fSniklas 	   struct internal_reloc *, struct internal_syment *, asection **));
662159047fSniklas static bfd_byte *sh_coff_get_relocated_section_contents
672159047fSniklas   PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
68c074d1c9Sdrahn 	   bfd_byte *, bfd_boolean, asymbol **));
69c074d1c9Sdrahn static reloc_howto_type * sh_coff_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type));
702159047fSniklas 
71b305b0f1Sespie #ifdef COFF_WITH_PE
72b305b0f1Sespie /* Can't build import tables with 2**4 alignment.  */
73b305b0f1Sespie #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER	2
74b305b0f1Sespie #else
75c88b1d6cSniklas /* Default section alignment to 2**4.  */
76b305b0f1Sespie #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER	4
77b305b0f1Sespie #endif
78b305b0f1Sespie 
79b305b0f1Sespie #ifdef COFF_IMAGE_WITH_PE
80b305b0f1Sespie /* Align PE executables.  */
81b305b0f1Sespie #define COFF_PAGE_SIZE 0x1000
82b305b0f1Sespie #endif
832159047fSniklas 
842159047fSniklas /* Generate long file names.  */
852159047fSniklas #define COFF_LONG_FILENAMES
862159047fSniklas 
87b305b0f1Sespie #ifdef COFF_WITH_PE
88c074d1c9Sdrahn static bfd_boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *));
89c074d1c9Sdrahn /* Return TRUE if this relocation should
90b305b0f1Sespie    appear in the output .reloc section.  */
in_reloc_p(abfd,howto)91c074d1c9Sdrahn static bfd_boolean in_reloc_p (abfd, howto)
92b305b0f1Sespie      bfd * abfd ATTRIBUTE_UNUSED;
93b305b0f1Sespie      reloc_howto_type * howto;
94b305b0f1Sespie {
95b305b0f1Sespie   return ! howto->pc_relative && howto->type != R_SH_IMAGEBASE;
96b305b0f1Sespie }
97b305b0f1Sespie #endif
98b305b0f1Sespie 
992159047fSniklas /* The supported relocations.  There are a lot of relocations defined
1002159047fSniklas    in coff/internal.h which we do not expect to ever see.  */
1012159047fSniklas static reloc_howto_type sh_coff_howtos[] =
1022159047fSniklas {
103b305b0f1Sespie   EMPTY_HOWTO (0),
104b305b0f1Sespie   EMPTY_HOWTO (1),
105b305b0f1Sespie #ifdef COFF_WITH_PE
106b305b0f1Sespie   /* Windows CE */
107b305b0f1Sespie   HOWTO (R_SH_IMM32CE,		/* type */
108b305b0f1Sespie 	 0,			/* rightshift */
109b305b0f1Sespie 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
110b305b0f1Sespie 	 32,			/* bitsize */
111c074d1c9Sdrahn 	 FALSE,			/* pc_relative */
112b305b0f1Sespie 	 0,			/* bitpos */
113b305b0f1Sespie 	 complain_overflow_bitfield, /* complain_on_overflow */
114b305b0f1Sespie 	 sh_reloc,		/* special_function */
115b305b0f1Sespie 	 "r_imm32ce",		/* name */
116c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
117b305b0f1Sespie 	 0xffffffff,		/* src_mask */
118b305b0f1Sespie 	 0xffffffff,		/* dst_mask */
119c074d1c9Sdrahn 	 FALSE),		/* pcrel_offset */
120b305b0f1Sespie #else
121b305b0f1Sespie   EMPTY_HOWTO (2),
122b305b0f1Sespie #endif
123b305b0f1Sespie   EMPTY_HOWTO (3), /* R_SH_PCREL8 */
124b305b0f1Sespie   EMPTY_HOWTO (4), /* R_SH_PCREL16 */
125b305b0f1Sespie   EMPTY_HOWTO (5), /* R_SH_HIGH8 */
126b305b0f1Sespie   EMPTY_HOWTO (6), /* R_SH_IMM24 */
127b305b0f1Sespie   EMPTY_HOWTO (7), /* R_SH_LOW16 */
128b305b0f1Sespie   EMPTY_HOWTO (8),
129b305b0f1Sespie   EMPTY_HOWTO (9), /* R_SH_PCDISP8BY4 */
1302159047fSniklas 
1312159047fSniklas   HOWTO (R_SH_PCDISP8BY2,	/* type */
1322159047fSniklas 	 1,			/* rightshift */
1332159047fSniklas 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1342159047fSniklas 	 8,			/* bitsize */
135c074d1c9Sdrahn 	 TRUE,			/* pc_relative */
1362159047fSniklas 	 0,			/* bitpos */
1372159047fSniklas 	 complain_overflow_signed, /* complain_on_overflow */
1382159047fSniklas 	 sh_reloc,		/* special_function */
1392159047fSniklas 	 "r_pcdisp8by2",	/* name */
140c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
1412159047fSniklas 	 0xff,			/* src_mask */
1422159047fSniklas 	 0xff,			/* dst_mask */
143c074d1c9Sdrahn 	 TRUE),			/* pcrel_offset */
1442159047fSniklas 
145b305b0f1Sespie   EMPTY_HOWTO (11), /* R_SH_PCDISP8 */
1462159047fSniklas 
1472159047fSniklas   HOWTO (R_SH_PCDISP,		/* type */
1482159047fSniklas 	 1,			/* rightshift */
1492159047fSniklas 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1502159047fSniklas 	 12,			/* bitsize */
151c074d1c9Sdrahn 	 TRUE,			/* pc_relative */
1522159047fSniklas 	 0,			/* bitpos */
1532159047fSniklas 	 complain_overflow_signed, /* complain_on_overflow */
1542159047fSniklas 	 sh_reloc,		/* special_function */
1552159047fSniklas 	 "r_pcdisp12by2",	/* name */
156c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
1572159047fSniklas 	 0xfff,			/* src_mask */
1582159047fSniklas 	 0xfff,			/* dst_mask */
159c074d1c9Sdrahn 	 TRUE),			/* pcrel_offset */
1602159047fSniklas 
161b305b0f1Sespie   EMPTY_HOWTO (13),
1622159047fSniklas 
1632159047fSniklas   HOWTO (R_SH_IMM32,		/* type */
1642159047fSniklas 	 0,			/* rightshift */
1652159047fSniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1662159047fSniklas 	 32,			/* bitsize */
167c074d1c9Sdrahn 	 FALSE,			/* pc_relative */
1682159047fSniklas 	 0,			/* bitpos */
1692159047fSniklas 	 complain_overflow_bitfield, /* complain_on_overflow */
1702159047fSniklas 	 sh_reloc,		/* special_function */
1712159047fSniklas 	 "r_imm32",		/* name */
172c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
1732159047fSniklas 	 0xffffffff,		/* src_mask */
1742159047fSniklas 	 0xffffffff,		/* dst_mask */
175c074d1c9Sdrahn 	 FALSE),		/* pcrel_offset */
1762159047fSniklas 
177b305b0f1Sespie   EMPTY_HOWTO (15),
178b305b0f1Sespie #ifdef COFF_WITH_PE
179b305b0f1Sespie   HOWTO (R_SH_IMAGEBASE,        /* type */
180b305b0f1Sespie 	 0,	                /* rightshift */
181b305b0f1Sespie 	 2,	                /* size (0 = byte, 1 = short, 2 = long) */
182b305b0f1Sespie 	 32,	                /* bitsize */
183c074d1c9Sdrahn 	 FALSE,	                /* pc_relative */
184b305b0f1Sespie 	 0,	                /* bitpos */
185b305b0f1Sespie 	 complain_overflow_bitfield, /* complain_on_overflow */
186b305b0f1Sespie 	 sh_reloc,       	/* special_function */
187b305b0f1Sespie 	 "rva32",	        /* name */
188c074d1c9Sdrahn 	 TRUE,	                /* partial_inplace */
189b305b0f1Sespie 	 0xffffffff,            /* src_mask */
190b305b0f1Sespie 	 0xffffffff,            /* dst_mask */
191c074d1c9Sdrahn 	 FALSE),                /* pcrel_offset */
192b305b0f1Sespie #else
193b305b0f1Sespie   EMPTY_HOWTO (16), /* R_SH_IMM8 */
194b305b0f1Sespie #endif
195b305b0f1Sespie   EMPTY_HOWTO (17), /* R_SH_IMM8BY2 */
196b305b0f1Sespie   EMPTY_HOWTO (18), /* R_SH_IMM8BY4 */
197b305b0f1Sespie   EMPTY_HOWTO (19), /* R_SH_IMM4 */
198b305b0f1Sespie   EMPTY_HOWTO (20), /* R_SH_IMM4BY2 */
199b305b0f1Sespie   EMPTY_HOWTO (21), /* R_SH_IMM4BY4 */
2002159047fSniklas 
2012159047fSniklas   HOWTO (R_SH_PCRELIMM8BY2,	/* type */
2022159047fSniklas 	 1,			/* rightshift */
2032159047fSniklas 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
2042159047fSniklas 	 8,			/* bitsize */
205c074d1c9Sdrahn 	 TRUE,			/* pc_relative */
2062159047fSniklas 	 0,			/* bitpos */
2072159047fSniklas 	 complain_overflow_unsigned, /* complain_on_overflow */
2082159047fSniklas 	 sh_reloc,		/* special_function */
2092159047fSniklas 	 "r_pcrelimm8by2",	/* name */
210c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
2112159047fSniklas 	 0xff,			/* src_mask */
2122159047fSniklas 	 0xff,			/* dst_mask */
213c074d1c9Sdrahn 	 TRUE),			/* pcrel_offset */
2142159047fSniklas 
2152159047fSniklas   HOWTO (R_SH_PCRELIMM8BY4,	/* type */
2162159047fSniklas 	 2,			/* rightshift */
2172159047fSniklas 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
2182159047fSniklas 	 8,			/* bitsize */
219c074d1c9Sdrahn 	 TRUE,			/* pc_relative */
2202159047fSniklas 	 0,			/* bitpos */
2212159047fSniklas 	 complain_overflow_unsigned, /* complain_on_overflow */
2222159047fSniklas 	 sh_reloc,		/* special_function */
2232159047fSniklas 	 "r_pcrelimm8by4",	/* name */
224c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
2252159047fSniklas 	 0xff,			/* src_mask */
2262159047fSniklas 	 0xff,			/* dst_mask */
227c074d1c9Sdrahn 	 TRUE),			/* pcrel_offset */
2282159047fSniklas 
2292159047fSniklas   HOWTO (R_SH_IMM16,		/* type */
2302159047fSniklas 	 0,			/* rightshift */
2312159047fSniklas 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
2322159047fSniklas 	 16,			/* bitsize */
233c074d1c9Sdrahn 	 FALSE,			/* pc_relative */
2342159047fSniklas 	 0,			/* bitpos */
2352159047fSniklas 	 complain_overflow_bitfield, /* complain_on_overflow */
2362159047fSniklas 	 sh_reloc,		/* special_function */
2372159047fSniklas 	 "r_imm16",		/* name */
238c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
2392159047fSniklas 	 0xffff,		/* src_mask */
2402159047fSniklas 	 0xffff,		/* dst_mask */
241c074d1c9Sdrahn 	 FALSE),		/* pcrel_offset */
2422159047fSniklas 
2432159047fSniklas   HOWTO (R_SH_SWITCH16,		/* type */
2442159047fSniklas 	 0,			/* rightshift */
2452159047fSniklas 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
2462159047fSniklas 	 16,			/* bitsize */
247c074d1c9Sdrahn 	 FALSE,			/* pc_relative */
2482159047fSniklas 	 0,			/* bitpos */
2492159047fSniklas 	 complain_overflow_bitfield, /* complain_on_overflow */
2502159047fSniklas 	 sh_reloc,		/* special_function */
2512159047fSniklas 	 "r_switch16",		/* name */
252c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
2532159047fSniklas 	 0xffff,		/* src_mask */
2542159047fSniklas 	 0xffff,		/* dst_mask */
255c074d1c9Sdrahn 	 FALSE),		/* pcrel_offset */
2562159047fSniklas 
2572159047fSniklas   HOWTO (R_SH_SWITCH32,		/* type */
2582159047fSniklas 	 0,			/* rightshift */
2592159047fSniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
2602159047fSniklas 	 32,			/* bitsize */
261c074d1c9Sdrahn 	 FALSE,			/* pc_relative */
2622159047fSniklas 	 0,			/* bitpos */
2632159047fSniklas 	 complain_overflow_bitfield, /* complain_on_overflow */
2642159047fSniklas 	 sh_reloc,		/* special_function */
2652159047fSniklas 	 "r_switch32",		/* name */
266c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
2672159047fSniklas 	 0xffffffff,		/* src_mask */
2682159047fSniklas 	 0xffffffff,		/* dst_mask */
269c074d1c9Sdrahn 	 FALSE),		/* pcrel_offset */
2702159047fSniklas 
2712159047fSniklas   HOWTO (R_SH_USES,		/* type */
2722159047fSniklas 	 0,			/* rightshift */
2732159047fSniklas 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
2742159047fSniklas 	 16,			/* bitsize */
275c074d1c9Sdrahn 	 FALSE,			/* pc_relative */
2762159047fSniklas 	 0,			/* bitpos */
2772159047fSniklas 	 complain_overflow_bitfield, /* complain_on_overflow */
2782159047fSniklas 	 sh_reloc,		/* special_function */
2792159047fSniklas 	 "r_uses",		/* name */
280c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
2812159047fSniklas 	 0xffff,		/* src_mask */
2822159047fSniklas 	 0xffff,		/* dst_mask */
283c074d1c9Sdrahn 	 FALSE),		/* pcrel_offset */
2842159047fSniklas 
2852159047fSniklas   HOWTO (R_SH_COUNT,		/* type */
2862159047fSniklas 	 0,			/* rightshift */
2872159047fSniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
2882159047fSniklas 	 32,			/* bitsize */
289c074d1c9Sdrahn 	 FALSE,			/* pc_relative */
2902159047fSniklas 	 0,			/* bitpos */
2912159047fSniklas 	 complain_overflow_bitfield, /* complain_on_overflow */
2922159047fSniklas 	 sh_reloc,		/* special_function */
2932159047fSniklas 	 "r_count",		/* name */
294c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
2952159047fSniklas 	 0xffffffff,		/* src_mask */
2962159047fSniklas 	 0xffffffff,		/* dst_mask */
297c074d1c9Sdrahn 	 FALSE),		/* pcrel_offset */
2982159047fSniklas 
2992159047fSniklas   HOWTO (R_SH_ALIGN,		/* type */
3002159047fSniklas 	 0,			/* rightshift */
3012159047fSniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
3022159047fSniklas 	 32,			/* bitsize */
303c074d1c9Sdrahn 	 FALSE,			/* pc_relative */
3042159047fSniklas 	 0,			/* bitpos */
3052159047fSniklas 	 complain_overflow_bitfield, /* complain_on_overflow */
3062159047fSniklas 	 sh_reloc,		/* special_function */
3072159047fSniklas 	 "r_align",		/* name */
308c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
3092159047fSniklas 	 0xffffffff,		/* src_mask */
3102159047fSniklas 	 0xffffffff,		/* dst_mask */
311c074d1c9Sdrahn 	 FALSE),		/* pcrel_offset */
312c88b1d6cSniklas 
313c88b1d6cSniklas   HOWTO (R_SH_CODE,		/* type */
314c88b1d6cSniklas 	 0,			/* rightshift */
315c88b1d6cSniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
316c88b1d6cSniklas 	 32,			/* bitsize */
317c074d1c9Sdrahn 	 FALSE,			/* pc_relative */
318c88b1d6cSniklas 	 0,			/* bitpos */
319c88b1d6cSniklas 	 complain_overflow_bitfield, /* complain_on_overflow */
320c88b1d6cSniklas 	 sh_reloc,		/* special_function */
321c88b1d6cSniklas 	 "r_code",		/* name */
322c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
323c88b1d6cSniklas 	 0xffffffff,		/* src_mask */
324c88b1d6cSniklas 	 0xffffffff,		/* dst_mask */
325c074d1c9Sdrahn 	 FALSE),		/* pcrel_offset */
326c88b1d6cSniklas 
327c88b1d6cSniklas   HOWTO (R_SH_DATA,		/* type */
328c88b1d6cSniklas 	 0,			/* rightshift */
329c88b1d6cSniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
330c88b1d6cSniklas 	 32,			/* bitsize */
331c074d1c9Sdrahn 	 FALSE,			/* pc_relative */
332c88b1d6cSniklas 	 0,			/* bitpos */
333c88b1d6cSniklas 	 complain_overflow_bitfield, /* complain_on_overflow */
334c88b1d6cSniklas 	 sh_reloc,		/* special_function */
335c88b1d6cSniklas 	 "r_data",		/* name */
336c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
337c88b1d6cSniklas 	 0xffffffff,		/* src_mask */
338c88b1d6cSniklas 	 0xffffffff,		/* dst_mask */
339c074d1c9Sdrahn 	 FALSE),		/* pcrel_offset */
340c88b1d6cSniklas 
341c88b1d6cSniklas   HOWTO (R_SH_LABEL,		/* type */
342c88b1d6cSniklas 	 0,			/* rightshift */
343c88b1d6cSniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
344c88b1d6cSniklas 	 32,			/* bitsize */
345c074d1c9Sdrahn 	 FALSE,			/* pc_relative */
346c88b1d6cSniklas 	 0,			/* bitpos */
347c88b1d6cSniklas 	 complain_overflow_bitfield, /* complain_on_overflow */
348c88b1d6cSniklas 	 sh_reloc,		/* special_function */
349c88b1d6cSniklas 	 "r_label",		/* name */
350c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
351c88b1d6cSniklas 	 0xffffffff,		/* src_mask */
352c88b1d6cSniklas 	 0xffffffff,		/* dst_mask */
353c074d1c9Sdrahn 	 FALSE),		/* pcrel_offset */
354b305b0f1Sespie 
355b305b0f1Sespie   HOWTO (R_SH_SWITCH8,		/* type */
356b305b0f1Sespie 	 0,			/* rightshift */
357b305b0f1Sespie 	 0,			/* size (0 = byte, 1 = short, 2 = long) */
358b305b0f1Sespie 	 8,			/* bitsize */
359c074d1c9Sdrahn 	 FALSE,			/* pc_relative */
360b305b0f1Sespie 	 0,			/* bitpos */
361b305b0f1Sespie 	 complain_overflow_bitfield, /* complain_on_overflow */
362b305b0f1Sespie 	 sh_reloc,		/* special_function */
363b305b0f1Sespie 	 "r_switch8",		/* name */
364c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
365b305b0f1Sespie 	 0xff,			/* src_mask */
366b305b0f1Sespie 	 0xff,			/* dst_mask */
367c074d1c9Sdrahn 	 FALSE)			/* pcrel_offset */
3682159047fSniklas };
3692159047fSniklas 
3702159047fSniklas #define SH_COFF_HOWTO_COUNT (sizeof sh_coff_howtos / sizeof sh_coff_howtos[0])
3712159047fSniklas 
3722159047fSniklas /* Check for a bad magic number.  */
3732159047fSniklas #define BADMAG(x) SHBADMAG(x)
3742159047fSniklas 
3752159047fSniklas /* Customize coffcode.h (this is not currently used).  */
3762159047fSniklas #define SH 1
3772159047fSniklas 
3782159047fSniklas /* FIXME: This should not be set here.  */
3792159047fSniklas #define __A_MAGIC_SET__
3802159047fSniklas 
381b305b0f1Sespie #ifndef COFF_WITH_PE
3822159047fSniklas /* Swap the r_offset field in and out.  */
383c074d1c9Sdrahn #define SWAP_IN_RELOC_OFFSET  H_GET_32
384c074d1c9Sdrahn #define SWAP_OUT_RELOC_OFFSET H_PUT_32
3852159047fSniklas 
3862159047fSniklas /* Swap out extra information in the reloc structure.  */
3872159047fSniklas #define SWAP_OUT_RELOC_EXTRA(abfd, src, dst)	\
3882159047fSniklas   do						\
3892159047fSniklas     {						\
3902159047fSniklas       dst->r_stuff[0] = 'S';			\
3912159047fSniklas       dst->r_stuff[1] = 'C';			\
3922159047fSniklas     }						\
3932159047fSniklas   while (0)
394b305b0f1Sespie #endif
3952159047fSniklas 
3962159047fSniklas /* Get the value of a symbol, when performing a relocation.  */
3972159047fSniklas 
3982159047fSniklas static long
get_symbol_value(symbol)3992159047fSniklas get_symbol_value (symbol)
4002159047fSniklas      asymbol *symbol;
4012159047fSniklas {
4022159047fSniklas   bfd_vma relocation;
4032159047fSniklas 
4042159047fSniklas   if (bfd_is_com_section (symbol->section))
4052159047fSniklas     relocation = 0;
4062159047fSniklas   else
4072159047fSniklas     relocation = (symbol->value +
4082159047fSniklas 		  symbol->section->output_section->vma +
4092159047fSniklas 		  symbol->section->output_offset);
4102159047fSniklas 
4112159047fSniklas   return relocation;
4122159047fSniklas }
4132159047fSniklas 
414b305b0f1Sespie #ifdef COFF_WITH_PE
415b305b0f1Sespie /* Convert an rtype to howto for the COFF backend linker.
416b305b0f1Sespie    Copied from coff-i386.  */
417b305b0f1Sespie #define coff_rtype_to_howto coff_sh_rtype_to_howto
418c074d1c9Sdrahn static reloc_howto_type * coff_sh_rtype_to_howto PARAMS ((bfd *, asection *, struct internal_reloc *, struct coff_link_hash_entry *, struct internal_syment *, bfd_vma *));
419b305b0f1Sespie 
420b305b0f1Sespie static reloc_howto_type *
coff_sh_rtype_to_howto(abfd,sec,rel,h,sym,addendp)421b305b0f1Sespie coff_sh_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
422b305b0f1Sespie      bfd * abfd ATTRIBUTE_UNUSED;
423b305b0f1Sespie      asection * sec;
424b305b0f1Sespie      struct internal_reloc * rel;
425b305b0f1Sespie      struct coff_link_hash_entry * h;
426b305b0f1Sespie      struct internal_syment * sym;
427b305b0f1Sespie      bfd_vma * addendp;
428b305b0f1Sespie {
429b305b0f1Sespie   reloc_howto_type * howto;
430b305b0f1Sespie 
431b305b0f1Sespie   howto = sh_coff_howtos + rel->r_type;
432b305b0f1Sespie 
433b305b0f1Sespie   *addendp = 0;
434b305b0f1Sespie 
435b305b0f1Sespie   if (howto->pc_relative)
436b305b0f1Sespie     *addendp += sec->vma;
437b305b0f1Sespie 
438b305b0f1Sespie   if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
439b305b0f1Sespie     {
440b305b0f1Sespie       /* This is a common symbol.  The section contents include the
441b305b0f1Sespie 	 size (sym->n_value) as an addend.  The relocate_section
442b305b0f1Sespie 	 function will be adding in the final value of the symbol.  We
443b305b0f1Sespie 	 need to subtract out the current size in order to get the
444b305b0f1Sespie 	 correct result.  */
445b305b0f1Sespie       BFD_ASSERT (h != NULL);
446b305b0f1Sespie     }
447b305b0f1Sespie 
448b305b0f1Sespie   if (howto->pc_relative)
449b305b0f1Sespie     {
450b305b0f1Sespie       *addendp -= 4;
451b305b0f1Sespie 
452b305b0f1Sespie       /* If the symbol is defined, then the generic code is going to
453b305b0f1Sespie          add back the symbol value in order to cancel out an
454b305b0f1Sespie          adjustment it made to the addend.  However, we set the addend
455b305b0f1Sespie          to 0 at the start of this function.  We need to adjust here,
456b305b0f1Sespie          to avoid the adjustment the generic code will make.  FIXME:
457b305b0f1Sespie          This is getting a bit hackish.  */
458b305b0f1Sespie       if (sym != NULL && sym->n_scnum != 0)
459b305b0f1Sespie 	*addendp -= sym->n_value;
460b305b0f1Sespie     }
461b305b0f1Sespie 
462b305b0f1Sespie   if (rel->r_type == R_SH_IMAGEBASE)
463b305b0f1Sespie     *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
464b305b0f1Sespie 
465b305b0f1Sespie   return howto;
466b305b0f1Sespie }
467b305b0f1Sespie 
468c074d1c9Sdrahn #endif /* COFF_WITH_PE */
469c074d1c9Sdrahn 
470b305b0f1Sespie /* This structure is used to map BFD reloc codes to SH PE relocs.  */
471b305b0f1Sespie struct shcoff_reloc_map
472b305b0f1Sespie {
473c074d1c9Sdrahn   bfd_reloc_code_real_type bfd_reloc_val;
474b305b0f1Sespie   unsigned char shcoff_reloc_val;
475b305b0f1Sespie };
476b305b0f1Sespie 
477c074d1c9Sdrahn #ifdef COFF_WITH_PE
478b305b0f1Sespie /* An array mapping BFD reloc codes to SH PE relocs.  */
479b305b0f1Sespie static const struct shcoff_reloc_map sh_reloc_map[] =
480b305b0f1Sespie {
481b305b0f1Sespie   { BFD_RELOC_32, R_SH_IMM32CE },
482b305b0f1Sespie   { BFD_RELOC_RVA, R_SH_IMAGEBASE },
483b305b0f1Sespie   { BFD_RELOC_CTOR, R_SH_IMM32CE },
484b305b0f1Sespie };
485c074d1c9Sdrahn #else
486c074d1c9Sdrahn /* An array mapping BFD reloc codes to SH PE relocs.  */
487c074d1c9Sdrahn static const struct shcoff_reloc_map sh_reloc_map[] =
488c074d1c9Sdrahn {
489c074d1c9Sdrahn   { BFD_RELOC_32, R_SH_IMM32 },
490c074d1c9Sdrahn   { BFD_RELOC_CTOR, R_SH_IMM32 },
491c074d1c9Sdrahn };
492c074d1c9Sdrahn #endif
493b305b0f1Sespie 
494b305b0f1Sespie /* Given a BFD reloc code, return the howto structure for the
495b305b0f1Sespie    corresponding SH PE reloc.  */
496b305b0f1Sespie #define coff_bfd_reloc_type_lookup	sh_coff_reloc_type_lookup
497b305b0f1Sespie 
498b305b0f1Sespie static reloc_howto_type *
sh_coff_reloc_type_lookup(abfd,code)499b305b0f1Sespie sh_coff_reloc_type_lookup (abfd, code)
500b305b0f1Sespie      bfd * abfd ATTRIBUTE_UNUSED;
501b305b0f1Sespie      bfd_reloc_code_real_type code;
502b305b0f1Sespie {
503b305b0f1Sespie   unsigned int i;
504b305b0f1Sespie 
505c074d1c9Sdrahn   for (i = ARRAY_SIZE (sh_reloc_map); i--;)
506b305b0f1Sespie     if (sh_reloc_map[i].bfd_reloc_val == code)
507b305b0f1Sespie       return &sh_coff_howtos[(int) sh_reloc_map[i].shcoff_reloc_val];
508b305b0f1Sespie 
509b305b0f1Sespie   fprintf (stderr, "SH Error: unknown reloc type %d\n", code);
510b305b0f1Sespie   return NULL;
511b305b0f1Sespie }
512b305b0f1Sespie 
5132159047fSniklas /* This macro is used in coffcode.h to get the howto corresponding to
5142159047fSniklas    an internal reloc.  */
5152159047fSniklas 
5162159047fSniklas #define RTYPE2HOWTO(relent, internal)		\
5172159047fSniklas   ((relent)->howto =				\
5182159047fSniklas    ((internal)->r_type < SH_COFF_HOWTO_COUNT	\
5192159047fSniklas     ? &sh_coff_howtos[(internal)->r_type]	\
5202159047fSniklas     : (reloc_howto_type *) NULL))
5212159047fSniklas 
5222159047fSniklas /* This is the same as the macro in coffcode.h, except that it copies
5232159047fSniklas    r_offset into reloc_entry->addend for some relocs.  */
5242159047fSniklas #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)                \
5252159047fSniklas   {                                                             \
5262159047fSniklas     coff_symbol_type *coffsym = (coff_symbol_type *) NULL;      \
5272159047fSniklas     if (ptr && bfd_asymbol_bfd (ptr) != abfd)                   \
5282159047fSniklas       coffsym = (obj_symbols (abfd)                             \
5292159047fSniklas                  + (cache_ptr->sym_ptr_ptr - symbols));         \
5302159047fSniklas     else if (ptr)                                               \
5312159047fSniklas       coffsym = coff_symbol_from (abfd, ptr);                   \
5322159047fSniklas     if (coffsym != (coff_symbol_type *) NULL                    \
5332159047fSniklas         && coffsym->native->u.syment.n_scnum == 0)              \
5342159047fSniklas       cache_ptr->addend = 0;                                    \
5352159047fSniklas     else if (ptr && bfd_asymbol_bfd (ptr) == abfd               \
5362159047fSniklas              && ptr->section != (asection *) NULL)              \
5372159047fSniklas       cache_ptr->addend = - (ptr->section->vma + ptr->value);   \
5382159047fSniklas     else                                                        \
5392159047fSniklas       cache_ptr->addend = 0;                                    \
540b305b0f1Sespie     if ((reloc).r_type == R_SH_SWITCH8				\
541b305b0f1Sespie 	|| (reloc).r_type == R_SH_SWITCH16			\
5422159047fSniklas 	|| (reloc).r_type == R_SH_SWITCH32			\
5432159047fSniklas 	|| (reloc).r_type == R_SH_USES				\
5442159047fSniklas 	|| (reloc).r_type == R_SH_COUNT				\
5452159047fSniklas 	|| (reloc).r_type == R_SH_ALIGN)			\
5462159047fSniklas       cache_ptr->addend = (reloc).r_offset;			\
5472159047fSniklas   }
5482159047fSniklas 
5492159047fSniklas /* This is the howto function for the SH relocations.  */
5502159047fSniklas 
5512159047fSniklas static bfd_reloc_status_type
sh_reloc(abfd,reloc_entry,symbol_in,data,input_section,output_bfd,error_message)5522159047fSniklas sh_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
5532159047fSniklas 	  error_message)
5542159047fSniklas      bfd *abfd;
5552159047fSniklas      arelent *reloc_entry;
5562159047fSniklas      asymbol *symbol_in;
5572159047fSniklas      PTR data;
5582159047fSniklas      asection *input_section;
5592159047fSniklas      bfd *output_bfd;
560b305b0f1Sespie      char **error_message ATTRIBUTE_UNUSED;
5612159047fSniklas {
5622159047fSniklas   unsigned long insn;
5632159047fSniklas   bfd_vma sym_value;
5642159047fSniklas   unsigned short r_type;
5652159047fSniklas   bfd_vma addr = reloc_entry->address;
5662159047fSniklas   bfd_byte *hit_data = addr + (bfd_byte *) data;
5672159047fSniklas 
5682159047fSniklas   r_type = reloc_entry->howto->type;
5692159047fSniklas 
5702159047fSniklas   if (output_bfd != NULL)
5712159047fSniklas     {
5722159047fSniklas       /* Partial linking--do nothing.  */
5732159047fSniklas       reloc_entry->address += input_section->output_offset;
5742159047fSniklas       return bfd_reloc_ok;
5752159047fSniklas     }
5762159047fSniklas 
5772159047fSniklas   /* Almost all relocs have to do with relaxing.  If any work must be
5782159047fSniklas      done for them, it has been done in sh_relax_section.  */
5792159047fSniklas   if (r_type != R_SH_IMM32
580b305b0f1Sespie #ifdef COFF_WITH_PE
581b305b0f1Sespie       && r_type != R_SH_IMM32CE
582b305b0f1Sespie       && r_type != R_SH_IMAGEBASE
583b305b0f1Sespie #endif
5842159047fSniklas       && (r_type != R_SH_PCDISP
5852159047fSniklas 	  || (symbol_in->flags & BSF_LOCAL) != 0))
5862159047fSniklas     return bfd_reloc_ok;
5872159047fSniklas 
5882159047fSniklas   if (symbol_in != NULL
5892159047fSniklas       && bfd_is_und_section (symbol_in->section))
5902159047fSniklas     return bfd_reloc_undefined;
5912159047fSniklas 
5922159047fSniklas   sym_value = get_symbol_value (symbol_in);
5932159047fSniklas 
5942159047fSniklas   switch (r_type)
5952159047fSniklas     {
5962159047fSniklas     case R_SH_IMM32:
597b305b0f1Sespie #ifdef COFF_WITH_PE
598b305b0f1Sespie     case R_SH_IMM32CE:
599b305b0f1Sespie #endif
6002159047fSniklas       insn = bfd_get_32 (abfd, hit_data);
6012159047fSniklas       insn += sym_value + reloc_entry->addend;
602c074d1c9Sdrahn       bfd_put_32 (abfd, (bfd_vma) insn, hit_data);
6032159047fSniklas       break;
604b305b0f1Sespie #ifdef COFF_WITH_PE
605b305b0f1Sespie     case R_SH_IMAGEBASE:
606b305b0f1Sespie       insn = bfd_get_32 (abfd, hit_data);
607c074d1c9Sdrahn       insn += sym_value + reloc_entry->addend;
608c074d1c9Sdrahn       insn -= pe_data (input_section->output_section->owner)->pe_opthdr.ImageBase;
609c074d1c9Sdrahn       bfd_put_32 (abfd, (bfd_vma) insn, hit_data);
610b305b0f1Sespie       break;
611b305b0f1Sespie #endif
6122159047fSniklas     case R_SH_PCDISP:
6132159047fSniklas       insn = bfd_get_16 (abfd, hit_data);
6142159047fSniklas       sym_value += reloc_entry->addend;
6152159047fSniklas       sym_value -= (input_section->output_section->vma
6162159047fSniklas 		    + input_section->output_offset
6172159047fSniklas 		    + addr
6182159047fSniklas 		    + 4);
6192159047fSniklas       sym_value += (insn & 0xfff) << 1;
6202159047fSniklas       if (insn & 0x800)
6212159047fSniklas 	sym_value -= 0x1000;
6222159047fSniklas       insn = (insn & 0xf000) | (sym_value & 0xfff);
623c074d1c9Sdrahn       bfd_put_16 (abfd, (bfd_vma) insn, hit_data);
6242159047fSniklas       if (sym_value < (bfd_vma) -0x1000 || sym_value >= 0x1000)
6252159047fSniklas 	return bfd_reloc_overflow;
6262159047fSniklas       break;
6272159047fSniklas     default:
6282159047fSniklas       abort ();
6292159047fSniklas       break;
6302159047fSniklas     }
6312159047fSniklas 
6322159047fSniklas   return bfd_reloc_ok;
6332159047fSniklas }
6342159047fSniklas 
635b305b0f1Sespie #define coff_bfd_merge_private_bfd_data _bfd_generic_verify_endian_match
636b305b0f1Sespie 
6372159047fSniklas /* We can do relaxing.  */
6382159047fSniklas #define coff_bfd_relax_section sh_relax_section
6392159047fSniklas 
6402159047fSniklas /* We use the special COFF backend linker.  */
6412159047fSniklas #define coff_relocate_section sh_relocate_section
6422159047fSniklas 
6432159047fSniklas /* When relaxing, we need to use special code to get the relocated
6442159047fSniklas    section contents.  */
6452159047fSniklas #define coff_bfd_get_relocated_section_contents \
6462159047fSniklas   sh_coff_get_relocated_section_contents
6472159047fSniklas 
6482159047fSniklas #include "coffcode.h"
649c88b1d6cSniklas 
6502159047fSniklas /* This function handles relaxing on the SH.
6512159047fSniklas 
6522159047fSniklas    Function calls on the SH look like this:
6532159047fSniklas 
6542159047fSniklas        movl  L1,r0
6552159047fSniklas        ...
6562159047fSniklas        jsr   @r0
6572159047fSniklas        ...
6582159047fSniklas      L1:
6592159047fSniklas        .long function
6602159047fSniklas 
6612159047fSniklas    The compiler and assembler will cooperate to create R_SH_USES
6622159047fSniklas    relocs on the jsr instructions.  The r_offset field of the
6632159047fSniklas    R_SH_USES reloc is the PC relative offset to the instruction which
6642159047fSniklas    loads the register (the r_offset field is computed as though it
6652159047fSniklas    were a jump instruction, so the offset value is actually from four
6662159047fSniklas    bytes past the instruction).  The linker can use this reloc to
6672159047fSniklas    determine just which function is being called, and thus decide
6682159047fSniklas    whether it is possible to replace the jsr with a bsr.
6692159047fSniklas 
6702159047fSniklas    If multiple function calls are all based on a single register load
6712159047fSniklas    (i.e., the same function is called multiple times), the compiler
6722159047fSniklas    guarantees that each function call will have an R_SH_USES reloc.
6732159047fSniklas    Therefore, if the linker is able to convert each R_SH_USES reloc
6742159047fSniklas    which refers to that address, it can safely eliminate the register
6752159047fSniklas    load.
6762159047fSniklas 
6772159047fSniklas    When the assembler creates an R_SH_USES reloc, it examines it to
6782159047fSniklas    determine which address is being loaded (L1 in the above example).
6792159047fSniklas    It then counts the number of references to that address, and
6802159047fSniklas    creates an R_SH_COUNT reloc at that address.  The r_offset field of
6812159047fSniklas    the R_SH_COUNT reloc will be the number of references.  If the
6822159047fSniklas    linker is able to eliminate a register load, it can use the
6832159047fSniklas    R_SH_COUNT reloc to see whether it can also eliminate the function
684c88b1d6cSniklas    address.
685c88b1d6cSniklas 
686c88b1d6cSniklas    SH relaxing also handles another, unrelated, matter.  On the SH, if
687c88b1d6cSniklas    a load or store instruction is not aligned on a four byte boundary,
688c88b1d6cSniklas    the memory cycle interferes with the 32 bit instruction fetch,
689c88b1d6cSniklas    causing a one cycle bubble in the pipeline.  Therefore, we try to
690c88b1d6cSniklas    align load and store instructions on four byte boundaries if we
691c88b1d6cSniklas    can, by swapping them with one of the adjacent instructions.  */
6922159047fSniklas 
693c074d1c9Sdrahn static bfd_boolean
sh_relax_section(abfd,sec,link_info,again)6942159047fSniklas sh_relax_section (abfd, sec, link_info, again)
6952159047fSniklas      bfd *abfd;
6962159047fSniklas      asection *sec;
6972159047fSniklas      struct bfd_link_info *link_info;
698c074d1c9Sdrahn      bfd_boolean *again;
6992159047fSniklas {
7002159047fSniklas   struct internal_reloc *internal_relocs;
7012159047fSniklas   struct internal_reloc *free_relocs = NULL;
702c074d1c9Sdrahn   bfd_boolean have_code;
7032159047fSniklas   struct internal_reloc *irel, *irelend;
7042159047fSniklas   bfd_byte *contents = NULL;
7052159047fSniklas   bfd_byte *free_contents = NULL;
7062159047fSniklas 
707c074d1c9Sdrahn   *again = FALSE;
7082159047fSniklas 
709*007c2a45Smiod   if (link_info->relocatable
7102159047fSniklas       || (sec->flags & SEC_RELOC) == 0
7112159047fSniklas       || sec->reloc_count == 0)
712c074d1c9Sdrahn     return TRUE;
7132159047fSniklas 
7142159047fSniklas   /* If this is the first time we have been called for this section,
7152159047fSniklas      initialize the cooked size.  */
7162159047fSniklas   if (sec->_cooked_size == 0)
7172159047fSniklas     sec->_cooked_size = sec->_raw_size;
7182159047fSniklas 
7192159047fSniklas   internal_relocs = (_bfd_coff_read_internal_relocs
7202159047fSniklas 		     (abfd, sec, link_info->keep_memory,
721c074d1c9Sdrahn 		      (bfd_byte *) NULL, FALSE,
7222159047fSniklas 		      (struct internal_reloc *) NULL));
7232159047fSniklas   if (internal_relocs == NULL)
7242159047fSniklas     goto error_return;
7252159047fSniklas   if (! link_info->keep_memory)
7262159047fSniklas     free_relocs = internal_relocs;
7272159047fSniklas 
728c074d1c9Sdrahn   have_code = FALSE;
729c88b1d6cSniklas 
7302159047fSniklas   irelend = internal_relocs + sec->reloc_count;
7312159047fSniklas   for (irel = internal_relocs; irel < irelend; irel++)
7322159047fSniklas     {
7332159047fSniklas       bfd_vma laddr, paddr, symval;
7342159047fSniklas       unsigned short insn;
7352159047fSniklas       struct internal_reloc *irelfn, *irelscan, *irelcount;
7362159047fSniklas       struct internal_syment sym;
7372159047fSniklas       bfd_signed_vma foff;
7382159047fSniklas 
739c88b1d6cSniklas       if (irel->r_type == R_SH_CODE)
740c074d1c9Sdrahn 	have_code = TRUE;
741c88b1d6cSniklas 
7422159047fSniklas       if (irel->r_type != R_SH_USES)
7432159047fSniklas 	continue;
7442159047fSniklas 
7452159047fSniklas       /* Get the section contents.  */
7462159047fSniklas       if (contents == NULL)
7472159047fSniklas 	{
7482159047fSniklas 	  if (coff_section_data (abfd, sec) != NULL
7492159047fSniklas 	      && coff_section_data (abfd, sec)->contents != NULL)
7502159047fSniklas 	    contents = coff_section_data (abfd, sec)->contents;
7512159047fSniklas 	  else
7522159047fSniklas 	    {
753c88b1d6cSniklas 	      contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
7542159047fSniklas 	      if (contents == NULL)
7552159047fSniklas 		goto error_return;
7562159047fSniklas 	      free_contents = contents;
7572159047fSniklas 
7582159047fSniklas 	      if (! bfd_get_section_contents (abfd, sec, contents,
7592159047fSniklas 					      (file_ptr) 0, sec->_raw_size))
7602159047fSniklas 		goto error_return;
7612159047fSniklas 	    }
7622159047fSniklas 	}
7632159047fSniklas 
7642159047fSniklas       /* The r_offset field of the R_SH_USES reloc will point us to
7652159047fSniklas          the register load.  The 4 is because the r_offset field is
7662159047fSniklas          computed as though it were a jump offset, which are based
7672159047fSniklas          from 4 bytes after the jump instruction.  */
768b305b0f1Sespie       laddr = irel->r_vaddr - sec->vma + 4;
769b305b0f1Sespie       /* Careful to sign extend the 32-bit offset.  */
770b305b0f1Sespie       laddr += ((irel->r_offset & 0xffffffff) ^ 0x80000000) - 0x80000000;
7712159047fSniklas       if (laddr >= sec->_raw_size)
7722159047fSniklas 	{
7732159047fSniklas 	  (*_bfd_error_handler) ("%s: 0x%lx: warning: bad R_SH_USES offset",
774c074d1c9Sdrahn 				 bfd_archive_filename (abfd),
7752159047fSniklas 				 (unsigned long) irel->r_vaddr);
7762159047fSniklas 	  continue;
7772159047fSniklas 	}
7782159047fSniklas       insn = bfd_get_16 (abfd, contents + laddr);
7792159047fSniklas 
780b305b0f1Sespie       /* If the instruction is not mov.l NN,rN, we don't know what to do.  */
7812159047fSniklas       if ((insn & 0xf000) != 0xd000)
7822159047fSniklas 	{
7832159047fSniklas 	  ((*_bfd_error_handler)
7842159047fSniklas 	   ("%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x",
785c074d1c9Sdrahn 	    bfd_archive_filename (abfd), (unsigned long) irel->r_vaddr, insn));
7862159047fSniklas 	  continue;
7872159047fSniklas 	}
7882159047fSniklas 
7892159047fSniklas       /* Get the address from which the register is being loaded.  The
7902159047fSniklas       	 displacement in the mov.l instruction is quadrupled.  It is a
7912159047fSniklas       	 displacement from four bytes after the movl instruction, but,
7922159047fSniklas       	 before adding in the PC address, two least significant bits
7932159047fSniklas       	 of the PC are cleared.  We assume that the section is aligned
7942159047fSniklas       	 on a four byte boundary.  */
7952159047fSniklas       paddr = insn & 0xff;
7962159047fSniklas       paddr *= 4;
797c074d1c9Sdrahn       paddr += (laddr + 4) &~ (bfd_vma) 3;
7982159047fSniklas       if (paddr >= sec->_raw_size)
7992159047fSniklas 	{
8002159047fSniklas 	  ((*_bfd_error_handler)
8012159047fSniklas 	   ("%s: 0x%lx: warning: bad R_SH_USES load offset",
802c074d1c9Sdrahn 	    bfd_archive_filename (abfd), (unsigned long) irel->r_vaddr));
8032159047fSniklas 	  continue;
8042159047fSniklas 	}
8052159047fSniklas 
8062159047fSniklas       /* Get the reloc for the address from which the register is
8072159047fSniklas          being loaded.  This reloc will tell us which function is
8082159047fSniklas          actually being called.  */
8092159047fSniklas       paddr += sec->vma;
8102159047fSniklas       for (irelfn = internal_relocs; irelfn < irelend; irelfn++)
8112159047fSniklas 	if (irelfn->r_vaddr == paddr
812b305b0f1Sespie #ifdef COFF_WITH_PE
813b305b0f1Sespie 	    && (irelfn->r_type == R_SH_IMM32
814b305b0f1Sespie 		|| irelfn->r_type == R_SH_IMM32CE
815b305b0f1Sespie 		|| irelfn->r_type == R_SH_IMAGEBASE))
816b305b0f1Sespie 
817b305b0f1Sespie #else
8182159047fSniklas 	    && irelfn->r_type == R_SH_IMM32)
819b305b0f1Sespie #endif
8202159047fSniklas 	  break;
8212159047fSniklas       if (irelfn >= irelend)
8222159047fSniklas 	{
8232159047fSniklas 	  ((*_bfd_error_handler)
8242159047fSniklas 	   ("%s: 0x%lx: warning: could not find expected reloc",
825c074d1c9Sdrahn 	    bfd_archive_filename (abfd), (unsigned long) paddr));
8262159047fSniklas 	  continue;
8272159047fSniklas 	}
8282159047fSniklas 
8292159047fSniklas       /* Get the value of the symbol referred to by the reloc.  */
8302159047fSniklas       if (! _bfd_coff_get_external_symbols (abfd))
8312159047fSniklas 	goto error_return;
8322159047fSniklas       bfd_coff_swap_sym_in (abfd,
8332159047fSniklas 			    ((bfd_byte *) obj_coff_external_syms (abfd)
8342159047fSniklas 			     + (irelfn->r_symndx
8352159047fSniklas 				* bfd_coff_symesz (abfd))),
8362159047fSniklas 			    &sym);
8372159047fSniklas       if (sym.n_scnum != 0 && sym.n_scnum != sec->target_index)
8382159047fSniklas 	{
8392159047fSniklas 	  ((*_bfd_error_handler)
8402159047fSniklas 	   ("%s: 0x%lx: warning: symbol in unexpected section",
841c074d1c9Sdrahn 	    bfd_archive_filename (abfd), (unsigned long) paddr));
8422159047fSniklas 	  continue;
8432159047fSniklas 	}
8442159047fSniklas 
8452159047fSniklas       if (sym.n_sclass != C_EXT)
8462159047fSniklas 	{
8472159047fSniklas 	  symval = (sym.n_value
8482159047fSniklas 		    - sec->vma
8492159047fSniklas 		    + sec->output_section->vma
8502159047fSniklas 		    + sec->output_offset);
8512159047fSniklas 	}
8522159047fSniklas       else
8532159047fSniklas 	{
8542159047fSniklas 	  struct coff_link_hash_entry *h;
8552159047fSniklas 
8562159047fSniklas 	  h = obj_coff_sym_hashes (abfd)[irelfn->r_symndx];
8572159047fSniklas 	  BFD_ASSERT (h != NULL);
8582159047fSniklas 	  if (h->root.type != bfd_link_hash_defined
8592159047fSniklas 	      && h->root.type != bfd_link_hash_defweak)
8602159047fSniklas 	    {
8612159047fSniklas 	      /* This appears to be a reference to an undefined
8622159047fSniklas                  symbol.  Just ignore it--it will be caught by the
8632159047fSniklas                  regular reloc processing.  */
8642159047fSniklas 	      continue;
8652159047fSniklas 	    }
8662159047fSniklas 
8672159047fSniklas 	  symval = (h->root.u.def.value
8682159047fSniklas 		    + h->root.u.def.section->output_section->vma
8692159047fSniklas 		    + h->root.u.def.section->output_offset);
8702159047fSniklas 	}
8712159047fSniklas 
8722159047fSniklas       symval += bfd_get_32 (abfd, contents + paddr - sec->vma);
8732159047fSniklas 
8742159047fSniklas       /* See if this function call can be shortened.  */
8752159047fSniklas       foff = (symval
8762159047fSniklas 	      - (irel->r_vaddr
8772159047fSniklas 		 - sec->vma
8782159047fSniklas 		 + sec->output_section->vma
8792159047fSniklas 		 + sec->output_offset
8802159047fSniklas 		 + 4));
8812159047fSniklas       if (foff < -0x1000 || foff >= 0x1000)
8822159047fSniklas 	{
8832159047fSniklas 	  /* After all that work, we can't shorten this function call.  */
8842159047fSniklas 	  continue;
8852159047fSniklas 	}
8862159047fSniklas 
8872159047fSniklas       /* Shorten the function call.  */
8882159047fSniklas 
8892159047fSniklas       /* For simplicity of coding, we are going to modify the section
8902159047fSniklas 	 contents, the section relocs, and the BFD symbol table.  We
8912159047fSniklas 	 must tell the rest of the code not to free up this
8922159047fSniklas 	 information.  It would be possible to instead create a table
8932159047fSniklas 	 of changes which have to be made, as is done in coff-mips.c;
8942159047fSniklas 	 that would be more work, but would require less memory when
8952159047fSniklas 	 the linker is run.  */
8962159047fSniklas 
8972159047fSniklas       if (coff_section_data (abfd, sec) == NULL)
8982159047fSniklas 	{
899c074d1c9Sdrahn 	  bfd_size_type amt = sizeof (struct coff_section_tdata);
900c074d1c9Sdrahn 	  sec->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
9012159047fSniklas 	  if (sec->used_by_bfd == NULL)
9022159047fSniklas 	    goto error_return;
9032159047fSniklas 	}
9042159047fSniklas 
9052159047fSniklas       coff_section_data (abfd, sec)->relocs = internal_relocs;
906c074d1c9Sdrahn       coff_section_data (abfd, sec)->keep_relocs = TRUE;
9072159047fSniklas       free_relocs = NULL;
9082159047fSniklas 
9092159047fSniklas       coff_section_data (abfd, sec)->contents = contents;
910c074d1c9Sdrahn       coff_section_data (abfd, sec)->keep_contents = TRUE;
9112159047fSniklas       free_contents = NULL;
9122159047fSniklas 
913c074d1c9Sdrahn       obj_coff_keep_syms (abfd) = TRUE;
9142159047fSniklas 
9152159047fSniklas       /* Replace the jsr with a bsr.  */
9162159047fSniklas 
9172159047fSniklas       /* Change the R_SH_USES reloc into an R_SH_PCDISP reloc, and
9182159047fSniklas          replace the jsr with a bsr.  */
9192159047fSniklas       irel->r_type = R_SH_PCDISP;
9202159047fSniklas       irel->r_symndx = irelfn->r_symndx;
9212159047fSniklas       if (sym.n_sclass != C_EXT)
9222159047fSniklas 	{
9232159047fSniklas 	  /* If this needs to be changed because of future relaxing,
9242159047fSniklas              it will be handled here like other internal PCDISP
9252159047fSniklas              relocs.  */
9262159047fSniklas 	  bfd_put_16 (abfd,
927c074d1c9Sdrahn 		      (bfd_vma) 0xb000 | ((foff >> 1) & 0xfff),
9282159047fSniklas 		      contents + irel->r_vaddr - sec->vma);
9292159047fSniklas 	}
9302159047fSniklas       else
9312159047fSniklas 	{
9322159047fSniklas 	  /* We can't fully resolve this yet, because the external
9332159047fSniklas              symbol value may be changed by future relaxing.  We let
9342159047fSniklas              the final link phase handle it.  */
935c074d1c9Sdrahn 	  bfd_put_16 (abfd, (bfd_vma) 0xb000,
936c074d1c9Sdrahn 		      contents + irel->r_vaddr - sec->vma);
9372159047fSniklas 	}
9382159047fSniklas 
9392159047fSniklas       /* See if there is another R_SH_USES reloc referring to the same
9402159047fSniklas          register load.  */
9412159047fSniklas       for (irelscan = internal_relocs; irelscan < irelend; irelscan++)
9422159047fSniklas 	if (irelscan->r_type == R_SH_USES
9432159047fSniklas 	    && laddr == irelscan->r_vaddr - sec->vma + 4 + irelscan->r_offset)
9442159047fSniklas 	  break;
9452159047fSniklas       if (irelscan < irelend)
9462159047fSniklas 	{
9472159047fSniklas 	  /* Some other function call depends upon this register load,
9482159047fSniklas 	     and we have not yet converted that function call.
9492159047fSniklas 	     Indeed, we may never be able to convert it.  There is
9502159047fSniklas 	     nothing else we can do at this point.  */
9512159047fSniklas 	  continue;
9522159047fSniklas 	}
9532159047fSniklas 
9542159047fSniklas       /* Look for a R_SH_COUNT reloc on the location where the
9552159047fSniklas          function address is stored.  Do this before deleting any
9562159047fSniklas          bytes, to avoid confusion about the address.  */
9572159047fSniklas       for (irelcount = internal_relocs; irelcount < irelend; irelcount++)
9582159047fSniklas 	if (irelcount->r_vaddr == paddr
9592159047fSniklas 	    && irelcount->r_type == R_SH_COUNT)
9602159047fSniklas 	  break;
9612159047fSniklas 
9622159047fSniklas       /* Delete the register load.  */
9632159047fSniklas       if (! sh_relax_delete_bytes (abfd, sec, laddr, 2))
9642159047fSniklas 	goto error_return;
9652159047fSniklas 
9662159047fSniklas       /* That will change things, so, just in case it permits some
9672159047fSniklas          other function call to come within range, we should relax
9682159047fSniklas          again.  Note that this is not required, and it may be slow.  */
969c074d1c9Sdrahn       *again = TRUE;
9702159047fSniklas 
9712159047fSniklas       /* Now check whether we got a COUNT reloc.  */
9722159047fSniklas       if (irelcount >= irelend)
9732159047fSniklas 	{
9742159047fSniklas 	  ((*_bfd_error_handler)
9752159047fSniklas 	   ("%s: 0x%lx: warning: could not find expected COUNT reloc",
976c074d1c9Sdrahn 	    bfd_archive_filename (abfd), (unsigned long) paddr));
9772159047fSniklas 	  continue;
9782159047fSniklas 	}
9792159047fSniklas 
9802159047fSniklas       /* The number of uses is stored in the r_offset field.  We've
9812159047fSniklas          just deleted one.  */
9822159047fSniklas       if (irelcount->r_offset == 0)
9832159047fSniklas 	{
9842159047fSniklas 	  ((*_bfd_error_handler) ("%s: 0x%lx: warning: bad count",
985c074d1c9Sdrahn 				  bfd_archive_filename (abfd),
9862159047fSniklas 				  (unsigned long) paddr));
9872159047fSniklas 	  continue;
9882159047fSniklas 	}
9892159047fSniklas 
9902159047fSniklas       --irelcount->r_offset;
9912159047fSniklas 
9922159047fSniklas       /* If there are no more uses, we can delete the address.  Reload
9932159047fSniklas          the address from irelfn, in case it was changed by the
9942159047fSniklas          previous call to sh_relax_delete_bytes.  */
9952159047fSniklas       if (irelcount->r_offset == 0)
9962159047fSniklas 	{
9972159047fSniklas 	  if (! sh_relax_delete_bytes (abfd, sec,
9982159047fSniklas 				       irelfn->r_vaddr - sec->vma, 4))
9992159047fSniklas 	    goto error_return;
10002159047fSniklas 	}
10012159047fSniklas 
10022159047fSniklas       /* We've done all we can with that function call.  */
10032159047fSniklas     }
10042159047fSniklas 
1005c88b1d6cSniklas   /* Look for load and store instructions that we can align on four
1006c88b1d6cSniklas      byte boundaries.  */
1007c88b1d6cSniklas   if (have_code)
1008c88b1d6cSniklas     {
1009c074d1c9Sdrahn       bfd_boolean swapped;
1010c88b1d6cSniklas 
1011c88b1d6cSniklas       /* Get the section contents.  */
1012c88b1d6cSniklas       if (contents == NULL)
1013c88b1d6cSniklas 	{
1014c88b1d6cSniklas 	  if (coff_section_data (abfd, sec) != NULL
1015c88b1d6cSniklas 	      && coff_section_data (abfd, sec)->contents != NULL)
1016c88b1d6cSniklas 	    contents = coff_section_data (abfd, sec)->contents;
1017c88b1d6cSniklas 	  else
1018c88b1d6cSniklas 	    {
1019c88b1d6cSniklas 	      contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
1020c88b1d6cSniklas 	      if (contents == NULL)
1021c88b1d6cSniklas 		goto error_return;
1022c88b1d6cSniklas 	      free_contents = contents;
1023c88b1d6cSniklas 
1024c88b1d6cSniklas 	      if (! bfd_get_section_contents (abfd, sec, contents,
1025c88b1d6cSniklas 					      (file_ptr) 0, sec->_raw_size))
1026c88b1d6cSniklas 		goto error_return;
1027c88b1d6cSniklas 	    }
1028c88b1d6cSniklas 	}
1029c88b1d6cSniklas 
1030c88b1d6cSniklas       if (! sh_align_loads (abfd, sec, internal_relocs, contents, &swapped))
1031c88b1d6cSniklas 	goto error_return;
1032c88b1d6cSniklas 
1033c88b1d6cSniklas       if (swapped)
1034c88b1d6cSniklas 	{
1035c88b1d6cSniklas 	  if (coff_section_data (abfd, sec) == NULL)
1036c88b1d6cSniklas 	    {
1037c074d1c9Sdrahn 	      bfd_size_type amt = sizeof (struct coff_section_tdata);
1038c074d1c9Sdrahn 	      sec->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
1039c88b1d6cSniklas 	      if (sec->used_by_bfd == NULL)
1040c88b1d6cSniklas 		goto error_return;
1041c88b1d6cSniklas 	    }
1042c88b1d6cSniklas 
1043c88b1d6cSniklas 	  coff_section_data (abfd, sec)->relocs = internal_relocs;
1044c074d1c9Sdrahn 	  coff_section_data (abfd, sec)->keep_relocs = TRUE;
1045c88b1d6cSniklas 	  free_relocs = NULL;
1046c88b1d6cSniklas 
1047c88b1d6cSniklas 	  coff_section_data (abfd, sec)->contents = contents;
1048c074d1c9Sdrahn 	  coff_section_data (abfd, sec)->keep_contents = TRUE;
1049c88b1d6cSniklas 	  free_contents = NULL;
1050c88b1d6cSniklas 
1051c074d1c9Sdrahn 	  obj_coff_keep_syms (abfd) = TRUE;
1052c88b1d6cSniklas 	}
1053c88b1d6cSniklas     }
1054c88b1d6cSniklas 
10552159047fSniklas   if (free_relocs != NULL)
10562159047fSniklas     {
10572159047fSniklas       free (free_relocs);
10582159047fSniklas       free_relocs = NULL;
10592159047fSniklas     }
10602159047fSniklas 
10612159047fSniklas   if (free_contents != NULL)
10622159047fSniklas     {
10632159047fSniklas       if (! link_info->keep_memory)
10642159047fSniklas 	free (free_contents);
10652159047fSniklas       else
10662159047fSniklas 	{
10672159047fSniklas 	  /* Cache the section contents for coff_link_input_bfd.  */
10682159047fSniklas 	  if (coff_section_data (abfd, sec) == NULL)
10692159047fSniklas 	    {
1070c074d1c9Sdrahn 	      bfd_size_type amt = sizeof (struct coff_section_tdata);
1071c074d1c9Sdrahn 	      sec->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
10722159047fSniklas 	      if (sec->used_by_bfd == NULL)
10732159047fSniklas 		goto error_return;
10742159047fSniklas 	      coff_section_data (abfd, sec)->relocs = NULL;
10752159047fSniklas 	    }
10762159047fSniklas 	  coff_section_data (abfd, sec)->contents = contents;
10772159047fSniklas 	}
10782159047fSniklas     }
10792159047fSniklas 
1080c074d1c9Sdrahn   return TRUE;
10812159047fSniklas 
10822159047fSniklas  error_return:
10832159047fSniklas   if (free_relocs != NULL)
10842159047fSniklas     free (free_relocs);
10852159047fSniklas   if (free_contents != NULL)
10862159047fSniklas     free (free_contents);
1087c074d1c9Sdrahn   return FALSE;
10882159047fSniklas }
10892159047fSniklas 
10902159047fSniklas /* Delete some bytes from a section while relaxing.  */
10912159047fSniklas 
1092c074d1c9Sdrahn static bfd_boolean
sh_relax_delete_bytes(abfd,sec,addr,count)10932159047fSniklas sh_relax_delete_bytes (abfd, sec, addr, count)
10942159047fSniklas      bfd *abfd;
10952159047fSniklas      asection *sec;
10962159047fSniklas      bfd_vma addr;
10972159047fSniklas      int count;
10982159047fSniklas {
10992159047fSniklas   bfd_byte *contents;
11002159047fSniklas   struct internal_reloc *irel, *irelend;
11012159047fSniklas   struct internal_reloc *irelalign;
11022159047fSniklas   bfd_vma toaddr;
11032159047fSniklas   bfd_byte *esym, *esymend;
11042159047fSniklas   bfd_size_type symesz;
11052159047fSniklas   struct coff_link_hash_entry **sym_hash;
11062159047fSniklas   asection *o;
11072159047fSniklas 
11082159047fSniklas   contents = coff_section_data (abfd, sec)->contents;
11092159047fSniklas 
11102159047fSniklas   /* The deletion must stop at the next ALIGN reloc for an aligment
11112159047fSniklas      power larger than the number of bytes we are deleting.  */
11122159047fSniklas 
11132159047fSniklas   irelalign = NULL;
11142159047fSniklas   toaddr = sec->_cooked_size;
11152159047fSniklas 
11162159047fSniklas   irel = coff_section_data (abfd, sec)->relocs;
11172159047fSniklas   irelend = irel + sec->reloc_count;
11182159047fSniklas   for (; irel < irelend; irel++)
11192159047fSniklas     {
11202159047fSniklas       if (irel->r_type == R_SH_ALIGN
11212159047fSniklas 	  && irel->r_vaddr - sec->vma > addr
11222159047fSniklas 	  && count < (1 << irel->r_offset))
11232159047fSniklas 	{
11242159047fSniklas 	  irelalign = irel;
11252159047fSniklas 	  toaddr = irel->r_vaddr - sec->vma;
11262159047fSniklas 	  break;
11272159047fSniklas 	}
11282159047fSniklas     }
11292159047fSniklas 
11302159047fSniklas   /* Actually delete the bytes.  */
1131c074d1c9Sdrahn   memmove (contents + addr, contents + addr + count,
1132c074d1c9Sdrahn 	   (size_t) (toaddr - addr - count));
11332159047fSniklas   if (irelalign == NULL)
11342159047fSniklas     sec->_cooked_size -= count;
11352159047fSniklas   else
1136c88b1d6cSniklas     {
1137c88b1d6cSniklas       int i;
1138c88b1d6cSniklas 
1139c88b1d6cSniklas #define NOP_OPCODE (0x0009)
1140c88b1d6cSniklas 
1141c88b1d6cSniklas       BFD_ASSERT ((count & 1) == 0);
1142c88b1d6cSniklas       for (i = 0; i < count; i += 2)
1143c074d1c9Sdrahn 	bfd_put_16 (abfd, (bfd_vma) NOP_OPCODE, contents + toaddr - count + i);
1144c88b1d6cSniklas     }
11452159047fSniklas 
11462159047fSniklas   /* Adjust all the relocs.  */
11472159047fSniklas   for (irel = coff_section_data (abfd, sec)->relocs; irel < irelend; irel++)
11482159047fSniklas     {
1149b305b0f1Sespie       bfd_vma nraddr, stop;
1150b305b0f1Sespie       bfd_vma start = 0;
11512159047fSniklas       int insn = 0;
11522159047fSniklas       struct internal_syment sym;
11532159047fSniklas       int off, adjust, oinsn;
1154b305b0f1Sespie       bfd_signed_vma voff = 0;
1155c074d1c9Sdrahn       bfd_boolean overflow;
11562159047fSniklas 
11572159047fSniklas       /* Get the new reloc address.  */
11582159047fSniklas       nraddr = irel->r_vaddr - sec->vma;
11592159047fSniklas       if ((irel->r_vaddr - sec->vma > addr
11602159047fSniklas 	   && irel->r_vaddr - sec->vma < toaddr)
11612159047fSniklas 	  || (irel->r_type == R_SH_ALIGN
11622159047fSniklas 	      && irel->r_vaddr - sec->vma == toaddr))
11632159047fSniklas 	nraddr -= count;
11642159047fSniklas 
11652159047fSniklas       /* See if this reloc was for the bytes we have deleted, in which
1166c88b1d6cSniklas 	 case we no longer care about it.  Don't delete relocs which
1167c88b1d6cSniklas 	 represent addresses, though.  */
11682159047fSniklas       if (irel->r_vaddr - sec->vma >= addr
11692159047fSniklas 	  && irel->r_vaddr - sec->vma < addr + count
1170c88b1d6cSniklas 	  && irel->r_type != R_SH_ALIGN
1171c88b1d6cSniklas 	  && irel->r_type != R_SH_CODE
1172b305b0f1Sespie 	  && irel->r_type != R_SH_DATA
1173b305b0f1Sespie 	  && irel->r_type != R_SH_LABEL)
11742159047fSniklas 	irel->r_type = R_SH_UNUSED;
11752159047fSniklas 
11762159047fSniklas       /* If this is a PC relative reloc, see if the range it covers
11772159047fSniklas          includes the bytes we have deleted.  */
11782159047fSniklas       switch (irel->r_type)
11792159047fSniklas 	{
11802159047fSniklas 	default:
11812159047fSniklas 	  break;
11822159047fSniklas 
11832159047fSniklas 	case R_SH_PCDISP8BY2:
11842159047fSniklas 	case R_SH_PCDISP:
11852159047fSniklas 	case R_SH_PCRELIMM8BY2:
11862159047fSniklas 	case R_SH_PCRELIMM8BY4:
11872159047fSniklas 	  start = irel->r_vaddr - sec->vma;
11882159047fSniklas 	  insn = bfd_get_16 (abfd, contents + nraddr);
11892159047fSniklas 	  break;
11902159047fSniklas 	}
11912159047fSniklas 
11922159047fSniklas       switch (irel->r_type)
11932159047fSniklas 	{
11942159047fSniklas 	default:
11952159047fSniklas 	  start = stop = addr;
11962159047fSniklas 	  break;
11972159047fSniklas 
11982159047fSniklas 	case R_SH_IMM32:
1199b305b0f1Sespie #ifdef COFF_WITH_PE
1200b305b0f1Sespie 	case R_SH_IMM32CE:
1201b305b0f1Sespie 	case R_SH_IMAGEBASE:
1202b305b0f1Sespie #endif
12032159047fSniklas 	  /* If this reloc is against a symbol defined in this
12042159047fSniklas              section, and the symbol will not be adjusted below, we
12052159047fSniklas              must check the addend to see it will put the value in
12062159047fSniklas              range to be adjusted, and hence must be changed.  */
12072159047fSniklas 	  bfd_coff_swap_sym_in (abfd,
12082159047fSniklas 				((bfd_byte *) obj_coff_external_syms (abfd)
12092159047fSniklas 				 + (irel->r_symndx
12102159047fSniklas 				    * bfd_coff_symesz (abfd))),
12112159047fSniklas 				&sym);
12122159047fSniklas 	  if (sym.n_sclass != C_EXT
12132159047fSniklas 	      && sym.n_scnum == sec->target_index
12142159047fSniklas 	      && ((bfd_vma) sym.n_value <= addr
12152159047fSniklas 		  || (bfd_vma) sym.n_value >= toaddr))
12162159047fSniklas 	    {
12172159047fSniklas 	      bfd_vma val;
12182159047fSniklas 
12192159047fSniklas 	      val = bfd_get_32 (abfd, contents + nraddr);
12202159047fSniklas 	      val += sym.n_value;
1221b305b0f1Sespie 	      if (val > addr && val < toaddr)
12222159047fSniklas 		bfd_put_32 (abfd, val - count, contents + nraddr);
12232159047fSniklas 	    }
12242159047fSniklas 	  start = stop = addr;
12252159047fSniklas 	  break;
12262159047fSniklas 
12272159047fSniklas 	case R_SH_PCDISP8BY2:
12282159047fSniklas 	  off = insn & 0xff;
12292159047fSniklas 	  if (off & 0x80)
12302159047fSniklas 	    off -= 0x100;
12312159047fSniklas 	  stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2);
12322159047fSniklas 	  break;
12332159047fSniklas 
12342159047fSniklas 	case R_SH_PCDISP:
12352159047fSniklas 	  bfd_coff_swap_sym_in (abfd,
12362159047fSniklas 				((bfd_byte *) obj_coff_external_syms (abfd)
12372159047fSniklas 				 + (irel->r_symndx
12382159047fSniklas 				    * bfd_coff_symesz (abfd))),
12392159047fSniklas 				&sym);
12402159047fSniklas 	  if (sym.n_sclass == C_EXT)
12412159047fSniklas 	    start = stop = addr;
12422159047fSniklas 	  else
12432159047fSniklas 	    {
12442159047fSniklas 	      off = insn & 0xfff;
12452159047fSniklas 	      if (off & 0x800)
12462159047fSniklas 		off -= 0x1000;
12472159047fSniklas 	      stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2);
12482159047fSniklas 	    }
12492159047fSniklas 	  break;
12502159047fSniklas 
12512159047fSniklas 	case R_SH_PCRELIMM8BY2:
12522159047fSniklas 	  off = insn & 0xff;
12532159047fSniklas 	  stop = start + 4 + off * 2;
12542159047fSniklas 	  break;
12552159047fSniklas 
12562159047fSniklas 	case R_SH_PCRELIMM8BY4:
12572159047fSniklas 	  off = insn & 0xff;
12582159047fSniklas 	  stop = (start &~ (bfd_vma) 3) + 4 + off * 4;
12592159047fSniklas 	  break;
12602159047fSniklas 
1261b305b0f1Sespie 	case R_SH_SWITCH8:
12622159047fSniklas 	case R_SH_SWITCH16:
12632159047fSniklas 	case R_SH_SWITCH32:
12642159047fSniklas 	  /* These relocs types represent
12652159047fSniklas 	       .word L2-L1
12662159047fSniklas 	     The r_offset field holds the difference between the reloc
12672159047fSniklas 	     address and L1.  That is the start of the reloc, and
12682159047fSniklas 	     adding in the contents gives us the top.  We must adjust
12692159047fSniklas 	     both the r_offset field and the section contents.  */
12702159047fSniklas 
12712159047fSniklas 	  start = irel->r_vaddr - sec->vma;
12722159047fSniklas 	  stop = (bfd_vma) ((bfd_signed_vma) start - (long) irel->r_offset);
12732159047fSniklas 
12742159047fSniklas 	  if (start > addr
12752159047fSniklas 	      && start < toaddr
12762159047fSniklas 	      && (stop <= addr || stop >= toaddr))
12772159047fSniklas 	    irel->r_offset += count;
12782159047fSniklas 	  else if (stop > addr
12792159047fSniklas 		   && stop < toaddr
12802159047fSniklas 		   && (start <= addr || start >= toaddr))
12812159047fSniklas 	    irel->r_offset -= count;
12822159047fSniklas 
12832159047fSniklas 	  start = stop;
12842159047fSniklas 
12852159047fSniklas 	  if (irel->r_type == R_SH_SWITCH16)
12862159047fSniklas 	    voff = bfd_get_signed_16 (abfd, contents + nraddr);
1287b305b0f1Sespie 	  else if (irel->r_type == R_SH_SWITCH8)
1288b305b0f1Sespie 	    voff = bfd_get_8 (abfd, contents + nraddr);
12892159047fSniklas 	  else
12902159047fSniklas 	    voff = bfd_get_signed_32 (abfd, contents + nraddr);
12912159047fSniklas 	  stop = (bfd_vma) ((bfd_signed_vma) start + voff);
12922159047fSniklas 
12932159047fSniklas 	  break;
12942159047fSniklas 
12952159047fSniklas 	case R_SH_USES:
12962159047fSniklas 	  start = irel->r_vaddr - sec->vma;
1297c88b1d6cSniklas 	  stop = (bfd_vma) ((bfd_signed_vma) start
1298c88b1d6cSniklas 			    + (long) irel->r_offset
1299c88b1d6cSniklas 			    + 4);
13002159047fSniklas 	  break;
13012159047fSniklas 	}
13022159047fSniklas 
13032159047fSniklas       if (start > addr
13042159047fSniklas 	  && start < toaddr
13052159047fSniklas 	  && (stop <= addr || stop >= toaddr))
13062159047fSniklas 	adjust = count;
13072159047fSniklas       else if (stop > addr
13082159047fSniklas 	       && stop < toaddr
13092159047fSniklas 	       && (start <= addr || start >= toaddr))
13102159047fSniklas 	adjust = - count;
13112159047fSniklas       else
13122159047fSniklas 	adjust = 0;
13132159047fSniklas 
13142159047fSniklas       if (adjust != 0)
13152159047fSniklas 	{
13162159047fSniklas 	  oinsn = insn;
1317c074d1c9Sdrahn 	  overflow = FALSE;
13182159047fSniklas 	  switch (irel->r_type)
13192159047fSniklas 	    {
13202159047fSniklas 	    default:
13212159047fSniklas 	      abort ();
13222159047fSniklas 	      break;
13232159047fSniklas 
13242159047fSniklas 	    case R_SH_PCDISP8BY2:
13252159047fSniklas 	    case R_SH_PCRELIMM8BY2:
13262159047fSniklas 	      insn += adjust / 2;
13272159047fSniklas 	      if ((oinsn & 0xff00) != (insn & 0xff00))
1328c074d1c9Sdrahn 		overflow = TRUE;
1329c074d1c9Sdrahn 	      bfd_put_16 (abfd, (bfd_vma) insn, contents + nraddr);
13302159047fSniklas 	      break;
13312159047fSniklas 
13322159047fSniklas 	    case R_SH_PCDISP:
13332159047fSniklas 	      insn += adjust / 2;
13342159047fSniklas 	      if ((oinsn & 0xf000) != (insn & 0xf000))
1335c074d1c9Sdrahn 		overflow = TRUE;
1336c074d1c9Sdrahn 	      bfd_put_16 (abfd, (bfd_vma) insn, contents + nraddr);
13372159047fSniklas 	      break;
13382159047fSniklas 
13392159047fSniklas 	    case R_SH_PCRELIMM8BY4:
13402159047fSniklas 	      BFD_ASSERT (adjust == count || count >= 4);
13412159047fSniklas 	      if (count >= 4)
13422159047fSniklas 		insn += adjust / 4;
13432159047fSniklas 	      else
13442159047fSniklas 		{
13452159047fSniklas 		  if ((irel->r_vaddr & 3) == 0)
13462159047fSniklas 		    ++insn;
13472159047fSniklas 		}
13482159047fSniklas 	      if ((oinsn & 0xff00) != (insn & 0xff00))
1349c074d1c9Sdrahn 		overflow = TRUE;
1350c074d1c9Sdrahn 	      bfd_put_16 (abfd, (bfd_vma) insn, contents + nraddr);
13512159047fSniklas 	      break;
13522159047fSniklas 
1353b305b0f1Sespie 	    case R_SH_SWITCH8:
1354b305b0f1Sespie 	      voff += adjust;
1355b305b0f1Sespie 	      if (voff < 0 || voff >= 0xff)
1356c074d1c9Sdrahn 		overflow = TRUE;
1357c074d1c9Sdrahn 	      bfd_put_8 (abfd, (bfd_vma) voff, contents + nraddr);
1358b305b0f1Sespie 	      break;
1359b305b0f1Sespie 
13602159047fSniklas 	    case R_SH_SWITCH16:
13612159047fSniklas 	      voff += adjust;
13622159047fSniklas 	      if (voff < - 0x8000 || voff >= 0x8000)
1363c074d1c9Sdrahn 		overflow = TRUE;
1364c074d1c9Sdrahn 	      bfd_put_signed_16 (abfd, (bfd_vma) voff, contents + nraddr);
13652159047fSniklas 	      break;
13662159047fSniklas 
13672159047fSniklas 	    case R_SH_SWITCH32:
13682159047fSniklas 	      voff += adjust;
1369c074d1c9Sdrahn 	      bfd_put_signed_32 (abfd, (bfd_vma) voff, contents + nraddr);
13702159047fSniklas 	      break;
13712159047fSniklas 
13722159047fSniklas 	    case R_SH_USES:
13732159047fSniklas 	      irel->r_offset += adjust;
13742159047fSniklas 	      break;
13752159047fSniklas 	    }
13762159047fSniklas 
13772159047fSniklas 	  if (overflow)
13782159047fSniklas 	    {
13792159047fSniklas 	      ((*_bfd_error_handler)
13802159047fSniklas 	       ("%s: 0x%lx: fatal: reloc overflow while relaxing",
1381c074d1c9Sdrahn 		bfd_archive_filename (abfd), (unsigned long) irel->r_vaddr));
13822159047fSniklas 	      bfd_set_error (bfd_error_bad_value);
1383c074d1c9Sdrahn 	      return FALSE;
13842159047fSniklas 	    }
13852159047fSniklas 	}
13862159047fSniklas 
13872159047fSniklas       irel->r_vaddr = nraddr + sec->vma;
13882159047fSniklas     }
13892159047fSniklas 
13902159047fSniklas   /* Look through all the other sections.  If there contain any IMM32
13912159047fSniklas      relocs against internal symbols which we are not going to adjust
13922159047fSniklas      below, we may need to adjust the addends.  */
13932159047fSniklas   for (o = abfd->sections; o != NULL; o = o->next)
13942159047fSniklas     {
13952159047fSniklas       struct internal_reloc *internal_relocs;
13962159047fSniklas       struct internal_reloc *irelscan, *irelscanend;
13972159047fSniklas       bfd_byte *ocontents;
13982159047fSniklas 
13992159047fSniklas       if (o == sec
14002159047fSniklas 	  || (o->flags & SEC_RELOC) == 0
14012159047fSniklas 	  || o->reloc_count == 0)
14022159047fSniklas 	continue;
14032159047fSniklas 
14042159047fSniklas       /* We always cache the relocs.  Perhaps, if info->keep_memory is
1405c074d1c9Sdrahn          FALSE, we should free them, if we are permitted to, when we
14062159047fSniklas          leave sh_coff_relax_section.  */
14072159047fSniklas       internal_relocs = (_bfd_coff_read_internal_relocs
1408c074d1c9Sdrahn 			 (abfd, o, TRUE, (bfd_byte *) NULL, FALSE,
14092159047fSniklas 			  (struct internal_reloc *) NULL));
14102159047fSniklas       if (internal_relocs == NULL)
1411c074d1c9Sdrahn 	return FALSE;
14122159047fSniklas 
14132159047fSniklas       ocontents = NULL;
14142159047fSniklas       irelscanend = internal_relocs + o->reloc_count;
14152159047fSniklas       for (irelscan = internal_relocs; irelscan < irelscanend; irelscan++)
14162159047fSniklas 	{
14172159047fSniklas 	  struct internal_syment sym;
14182159047fSniklas 
1419b305b0f1Sespie #ifdef COFF_WITH_PE
1420b305b0f1Sespie 	  if (irelscan->r_type != R_SH_IMM32
1421b305b0f1Sespie 	      && irelscan->r_type != R_SH_IMAGEBASE
1422b305b0f1Sespie 	      && irelscan->r_type != R_SH_IMM32CE)
1423b305b0f1Sespie #else
14242159047fSniklas 	  if (irelscan->r_type != R_SH_IMM32)
1425b305b0f1Sespie #endif
14262159047fSniklas 	    continue;
14272159047fSniklas 
14282159047fSniklas 	  bfd_coff_swap_sym_in (abfd,
14292159047fSniklas 				((bfd_byte *) obj_coff_external_syms (abfd)
14302159047fSniklas 				 + (irelscan->r_symndx
14312159047fSniklas 				    * bfd_coff_symesz (abfd))),
14322159047fSniklas 				&sym);
14332159047fSniklas 	  if (sym.n_sclass != C_EXT
14342159047fSniklas 	      && sym.n_scnum == sec->target_index
14352159047fSniklas 	      && ((bfd_vma) sym.n_value <= addr
14362159047fSniklas 		  || (bfd_vma) sym.n_value >= toaddr))
14372159047fSniklas 	    {
14382159047fSniklas 	      bfd_vma val;
14392159047fSniklas 
14402159047fSniklas 	      if (ocontents == NULL)
14412159047fSniklas 		{
14422159047fSniklas 		  if (coff_section_data (abfd, o)->contents != NULL)
14432159047fSniklas 		    ocontents = coff_section_data (abfd, o)->contents;
14442159047fSniklas 		  else
14452159047fSniklas 		    {
14462159047fSniklas 		      /* We always cache the section contents.
1447c074d1c9Sdrahn                          Perhaps, if info->keep_memory is FALSE, we
14482159047fSniklas                          should free them, if we are permitted to,
14492159047fSniklas                          when we leave sh_coff_relax_section.  */
1450c88b1d6cSniklas 		      ocontents = (bfd_byte *) bfd_malloc (o->_raw_size);
14512159047fSniklas 		      if (ocontents == NULL)
1452c074d1c9Sdrahn 			return FALSE;
14532159047fSniklas 		      if (! bfd_get_section_contents (abfd, o, ocontents,
14542159047fSniklas 						      (file_ptr) 0,
14552159047fSniklas 						      o->_raw_size))
1456c074d1c9Sdrahn 			return FALSE;
14572159047fSniklas 		      coff_section_data (abfd, o)->contents = ocontents;
14582159047fSniklas 		    }
14592159047fSniklas 		}
14602159047fSniklas 
14612159047fSniklas 	      val = bfd_get_32 (abfd, ocontents + irelscan->r_vaddr - o->vma);
14622159047fSniklas 	      val += sym.n_value;
1463b305b0f1Sespie 	      if (val > addr && val < toaddr)
14642159047fSniklas 		bfd_put_32 (abfd, val - count,
14652159047fSniklas 			    ocontents + irelscan->r_vaddr - o->vma);
14662159047fSniklas 
1467c074d1c9Sdrahn 	      coff_section_data (abfd, o)->keep_contents = TRUE;
14682159047fSniklas 	    }
14692159047fSniklas 	}
14702159047fSniklas     }
14712159047fSniklas 
14722159047fSniklas   /* Adjusting the internal symbols will not work if something has
14732159047fSniklas      already retrieved the generic symbols.  It would be possible to
14742159047fSniklas      make this work by adjusting the generic symbols at the same time.
14752159047fSniklas      However, this case should not arise in normal usage.  */
14762159047fSniklas   if (obj_symbols (abfd) != NULL
14772159047fSniklas       || obj_raw_syments (abfd) != NULL)
14782159047fSniklas     {
14792159047fSniklas       ((*_bfd_error_handler)
14802159047fSniklas        ("%s: fatal: generic symbols retrieved before relaxing",
1481c074d1c9Sdrahn 	bfd_archive_filename (abfd)));
14822159047fSniklas       bfd_set_error (bfd_error_invalid_operation);
1483c074d1c9Sdrahn       return FALSE;
14842159047fSniklas     }
14852159047fSniklas 
14862159047fSniklas   /* Adjust all the symbols.  */
14872159047fSniklas   sym_hash = obj_coff_sym_hashes (abfd);
14882159047fSniklas   symesz = bfd_coff_symesz (abfd);
14892159047fSniklas   esym = (bfd_byte *) obj_coff_external_syms (abfd);
14902159047fSniklas   esymend = esym + obj_raw_syment_count (abfd) * symesz;
14912159047fSniklas   while (esym < esymend)
14922159047fSniklas     {
14932159047fSniklas       struct internal_syment isym;
14942159047fSniklas 
14952159047fSniklas       bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &isym);
14962159047fSniklas 
14972159047fSniklas       if (isym.n_scnum == sec->target_index
14982159047fSniklas 	  && (bfd_vma) isym.n_value > addr
14992159047fSniklas 	  && (bfd_vma) isym.n_value < toaddr)
15002159047fSniklas 	{
15012159047fSniklas 	  isym.n_value -= count;
15022159047fSniklas 
15032159047fSniklas 	  bfd_coff_swap_sym_out (abfd, (PTR) &isym, (PTR) esym);
15042159047fSniklas 
15052159047fSniklas 	  if (*sym_hash != NULL)
15062159047fSniklas 	    {
15072159047fSniklas 	      BFD_ASSERT ((*sym_hash)->root.type == bfd_link_hash_defined
15082159047fSniklas 			  || (*sym_hash)->root.type == bfd_link_hash_defweak);
15092159047fSniklas 	      BFD_ASSERT ((*sym_hash)->root.u.def.value >= addr
15102159047fSniklas 			  && (*sym_hash)->root.u.def.value < toaddr);
15112159047fSniklas 	      (*sym_hash)->root.u.def.value -= count;
15122159047fSniklas 	    }
15132159047fSniklas 	}
15142159047fSniklas 
15152159047fSniklas       esym += (isym.n_numaux + 1) * symesz;
15162159047fSniklas       sym_hash += isym.n_numaux + 1;
15172159047fSniklas     }
15182159047fSniklas 
15192159047fSniklas   /* See if we can move the ALIGN reloc forward.  We have adjusted
15202159047fSniklas      r_vaddr for it already.  */
15212159047fSniklas   if (irelalign != NULL)
15222159047fSniklas     {
1523c88b1d6cSniklas       bfd_vma alignto, alignaddr;
15242159047fSniklas 
1525c88b1d6cSniklas       alignto = BFD_ALIGN (toaddr, 1 << irelalign->r_offset);
15262159047fSniklas       alignaddr = BFD_ALIGN (irelalign->r_vaddr - sec->vma,
15272159047fSniklas 			     1 << irelalign->r_offset);
1528c88b1d6cSniklas       if (alignto != alignaddr)
15292159047fSniklas 	{
15302159047fSniklas 	  /* Tail recursion.  */
1531c88b1d6cSniklas 	  return sh_relax_delete_bytes (abfd, sec, alignaddr,
1532c074d1c9Sdrahn 					(int) (alignto - alignaddr));
15332159047fSniklas 	}
15342159047fSniklas     }
15352159047fSniklas 
1536c074d1c9Sdrahn   return TRUE;
15372159047fSniklas }
1538c88b1d6cSniklas 
1539c88b1d6cSniklas /* This is yet another version of the SH opcode table, used to rapidly
1540c88b1d6cSniklas    get information about a particular instruction.  */
15412159047fSniklas 
1542c88b1d6cSniklas /* The opcode map is represented by an array of these structures.  The
1543c88b1d6cSniklas    array is indexed by the high order four bits in the instruction.  */
1544c88b1d6cSniklas 
1545c88b1d6cSniklas struct sh_major_opcode
1546c88b1d6cSniklas {
1547c88b1d6cSniklas   /* A pointer to the instruction list.  This is an array which
1548c88b1d6cSniklas      contains all the instructions with this major opcode.  */
1549c88b1d6cSniklas   const struct sh_minor_opcode *minor_opcodes;
1550c88b1d6cSniklas   /* The number of elements in minor_opcodes.  */
1551c88b1d6cSniklas   unsigned short count;
1552c88b1d6cSniklas };
1553c88b1d6cSniklas 
1554c88b1d6cSniklas /* This structure holds information for a set of SH opcodes.  The
1555c88b1d6cSniklas    instruction code is anded with the mask value, and the resulting
1556c88b1d6cSniklas    value is used to search the order opcode list.  */
1557c88b1d6cSniklas 
1558c88b1d6cSniklas struct sh_minor_opcode
1559c88b1d6cSniklas {
1560c88b1d6cSniklas   /* The sorted opcode list.  */
1561c88b1d6cSniklas   const struct sh_opcode *opcodes;
1562c88b1d6cSniklas   /* The number of elements in opcodes.  */
1563c88b1d6cSniklas   unsigned short count;
1564c88b1d6cSniklas   /* The mask value to use when searching the opcode list.  */
1565c88b1d6cSniklas   unsigned short mask;
1566c88b1d6cSniklas };
1567c88b1d6cSniklas 
1568c88b1d6cSniklas /* This structure holds information for an SH instruction.  An array
1569c88b1d6cSniklas    of these structures is sorted in order by opcode.  */
1570c88b1d6cSniklas 
1571c88b1d6cSniklas struct sh_opcode
1572c88b1d6cSniklas {
1573c88b1d6cSniklas   /* The code for this instruction, after it has been anded with the
1574c88b1d6cSniklas      mask value in the sh_major_opcode structure.  */
1575c88b1d6cSniklas   unsigned short opcode;
1576c88b1d6cSniklas   /* Flags for this instruction.  */
1577b305b0f1Sespie   unsigned long flags;
1578c88b1d6cSniklas };
1579c88b1d6cSniklas 
1580c88b1d6cSniklas /* Flag which appear in the sh_opcode structure.  */
1581c88b1d6cSniklas 
1582c88b1d6cSniklas /* This instruction loads a value from memory.  */
1583c88b1d6cSniklas #define LOAD (0x1)
1584c88b1d6cSniklas 
1585c88b1d6cSniklas /* This instruction stores a value to memory.  */
1586c88b1d6cSniklas #define STORE (0x2)
1587c88b1d6cSniklas 
1588c88b1d6cSniklas /* This instruction is a branch.  */
1589c88b1d6cSniklas #define BRANCH (0x4)
1590c88b1d6cSniklas 
1591c88b1d6cSniklas /* This instruction has a delay slot.  */
1592c88b1d6cSniklas #define DELAY (0x8)
1593c88b1d6cSniklas 
1594c88b1d6cSniklas /* This instruction uses the value in the register in the field at
1595c88b1d6cSniklas    mask 0x0f00 of the instruction.  */
1596c88b1d6cSniklas #define USES1 (0x10)
1597b305b0f1Sespie #define USES1_REG(x) ((x & 0x0f00) >> 8)
1598c88b1d6cSniklas 
1599c88b1d6cSniklas /* This instruction uses the value in the register in the field at
1600c88b1d6cSniklas    mask 0x00f0 of the instruction.  */
1601c88b1d6cSniklas #define USES2 (0x20)
1602b305b0f1Sespie #define USES2_REG(x) ((x & 0x00f0) >> 4)
1603c88b1d6cSniklas 
1604c88b1d6cSniklas /* This instruction uses the value in register 0.  */
1605c88b1d6cSniklas #define USESR0 (0x40)
1606c88b1d6cSniklas 
1607c88b1d6cSniklas /* This instruction sets the value in the register in the field at
1608c88b1d6cSniklas    mask 0x0f00 of the instruction.  */
1609c88b1d6cSniklas #define SETS1 (0x80)
1610b305b0f1Sespie #define SETS1_REG(x) ((x & 0x0f00) >> 8)
1611c88b1d6cSniklas 
1612c88b1d6cSniklas /* This instruction sets the value in the register in the field at
1613c88b1d6cSniklas    mask 0x00f0 of the instruction.  */
1614c88b1d6cSniklas #define SETS2 (0x100)
1615b305b0f1Sespie #define SETS2_REG(x) ((x & 0x00f0) >> 4)
1616c88b1d6cSniklas 
1617c88b1d6cSniklas /* This instruction sets register 0.  */
1618c88b1d6cSniklas #define SETSR0 (0x200)
1619c88b1d6cSniklas 
1620c88b1d6cSniklas /* This instruction sets a special register.  */
1621c88b1d6cSniklas #define SETSSP (0x400)
1622c88b1d6cSniklas 
1623c88b1d6cSniklas /* This instruction uses a special register.  */
1624c88b1d6cSniklas #define USESSP (0x800)
1625c88b1d6cSniklas 
1626c88b1d6cSniklas /* This instruction uses the floating point register in the field at
1627c88b1d6cSniklas    mask 0x0f00 of the instruction.  */
1628c88b1d6cSniklas #define USESF1 (0x1000)
1629b305b0f1Sespie #define USESF1_REG(x) ((x & 0x0f00) >> 8)
1630c88b1d6cSniklas 
1631c88b1d6cSniklas /* This instruction uses the floating point register in the field at
1632c88b1d6cSniklas    mask 0x00f0 of the instruction.  */
1633c88b1d6cSniklas #define USESF2 (0x2000)
1634b305b0f1Sespie #define USESF2_REG(x) ((x & 0x00f0) >> 4)
1635c88b1d6cSniklas 
1636c88b1d6cSniklas /* This instruction uses floating point register 0.  */
1637c88b1d6cSniklas #define USESF0 (0x4000)
1638c88b1d6cSniklas 
1639c88b1d6cSniklas /* This instruction sets the floating point register in the field at
1640c88b1d6cSniklas    mask 0x0f00 of the instruction.  */
1641c88b1d6cSniklas #define SETSF1 (0x8000)
1642b305b0f1Sespie #define SETSF1_REG(x) ((x & 0x0f00) >> 8)
1643c88b1d6cSniklas 
1644b305b0f1Sespie #define USESAS (0x10000)
1645b305b0f1Sespie #define USESAS_REG(x) (((((x) >> 8) - 2) & 3) + 2)
1646b305b0f1Sespie #define USESR8 (0x20000)
1647b305b0f1Sespie #define SETSAS (0x40000)
1648b305b0f1Sespie #define SETSAS_REG(x) USESAS_REG (x)
1649b305b0f1Sespie 
1650*007c2a45Smiod #define MAP(a) a, sizeof a / sizeof a[0]
1651*007c2a45Smiod 
1652b305b0f1Sespie #ifndef COFF_IMAGE_WITH_PE
1653c074d1c9Sdrahn static bfd_boolean sh_insn_uses_reg
1654c88b1d6cSniklas   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int));
1655c074d1c9Sdrahn static bfd_boolean sh_insn_sets_reg
1656b305b0f1Sespie   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int));
1657c074d1c9Sdrahn static bfd_boolean sh_insn_uses_or_sets_reg
1658b305b0f1Sespie   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int));
1659c074d1c9Sdrahn static bfd_boolean sh_insn_uses_freg
1660c88b1d6cSniklas   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int));
1661c074d1c9Sdrahn static bfd_boolean sh_insn_sets_freg
1662b305b0f1Sespie   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int));
1663c074d1c9Sdrahn static bfd_boolean sh_insn_uses_or_sets_freg
1664b305b0f1Sespie   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int));
1665c074d1c9Sdrahn static bfd_boolean sh_insns_conflict
1666c88b1d6cSniklas   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int,
1667c88b1d6cSniklas 	   const struct sh_opcode *));
1668c074d1c9Sdrahn static bfd_boolean sh_load_use
1669c88b1d6cSniklas   PARAMS ((unsigned int, const struct sh_opcode *, unsigned int,
1670c88b1d6cSniklas 	   const struct sh_opcode *));
1671c88b1d6cSniklas 
1672*007c2a45Smiod /* The opcode maps.  */
1673c88b1d6cSniklas 
1674c88b1d6cSniklas static const struct sh_opcode sh_opcode00[] =
1675c88b1d6cSniklas {
1676c88b1d6cSniklas   { 0x0008, SETSSP },			/* clrt */
1677c88b1d6cSniklas   { 0x0009, 0 },			/* nop */
1678c88b1d6cSniklas   { 0x000b, BRANCH | DELAY | USESSP },	/* rts */
1679c88b1d6cSniklas   { 0x0018, SETSSP },			/* sett */
1680c88b1d6cSniklas   { 0x0019, SETSSP },			/* div0u */
1681c88b1d6cSniklas   { 0x001b, 0 },			/* sleep */
1682c88b1d6cSniklas   { 0x0028, SETSSP },			/* clrmac */
1683c88b1d6cSniklas   { 0x002b, BRANCH | DELAY | SETSSP },	/* rte */
1684c88b1d6cSniklas   { 0x0038, USESSP | SETSSP },		/* ldtlb */
1685c88b1d6cSniklas   { 0x0048, SETSSP },			/* clrs */
1686c88b1d6cSniklas   { 0x0058, SETSSP }			/* sets */
1687c88b1d6cSniklas };
1688c88b1d6cSniklas 
1689c88b1d6cSniklas static const struct sh_opcode sh_opcode01[] =
1690c88b1d6cSniklas {
1691c88b1d6cSniklas   { 0x0003, BRANCH | DELAY | USES1 | SETSSP },	/* bsrf rn */
1692c88b1d6cSniklas   { 0x000a, SETS1 | USESSP },			/* sts mach,rn */
1693c88b1d6cSniklas   { 0x001a, SETS1 | USESSP },			/* sts macl,rn */
1694c88b1d6cSniklas   { 0x0023, BRANCH | DELAY | USES1 },		/* braf rn */
1695c88b1d6cSniklas   { 0x0029, SETS1 | USESSP },			/* movt rn */
1696c88b1d6cSniklas   { 0x002a, SETS1 | USESSP },			/* sts pr,rn */
1697b305b0f1Sespie   { 0x005a, SETS1 | USESSP },			/* sts fpul,rn */
1698b305b0f1Sespie   { 0x006a, SETS1 | USESSP },			/* sts fpscr,rn / sts dsr,rn */
1699b305b0f1Sespie   { 0x0083, LOAD | USES1 },			/* pref @rn */
1700b305b0f1Sespie   { 0x007a, SETS1 | USESSP },			/* sts a0,rn */
1701b305b0f1Sespie   { 0x008a, SETS1 | USESSP },			/* sts x0,rn */
1702b305b0f1Sespie   { 0x009a, SETS1 | USESSP },			/* sts x1,rn */
1703b305b0f1Sespie   { 0x00aa, SETS1 | USESSP },			/* sts y0,rn */
1704b305b0f1Sespie   { 0x00ba, SETS1 | USESSP }			/* sts y1,rn */
1705b305b0f1Sespie };
1706b305b0f1Sespie 
1707b305b0f1Sespie /* These sixteen instructions can be handled with one table entry below.  */
1708b305b0f1Sespie #if 0
1709b305b0f1Sespie   { 0x0002, SETS1 | USESSP },			/* stc sr,rn */
1710b305b0f1Sespie   { 0x0012, SETS1 | USESSP },			/* stc gbr,rn */
1711b305b0f1Sespie   { 0x0022, SETS1 | USESSP },			/* stc vbr,rn */
1712c88b1d6cSniklas   { 0x0032, SETS1 | USESSP },			/* stc ssr,rn */
1713c88b1d6cSniklas   { 0x0042, SETS1 | USESSP },			/* stc spc,rn */
1714b305b0f1Sespie   { 0x0052, SETS1 | USESSP },			/* stc mod,rn */
1715b305b0f1Sespie   { 0x0062, SETS1 | USESSP },			/* stc rs,rn */
1716b305b0f1Sespie   { 0x0072, SETS1 | USESSP },			/* stc re,rn */
1717c88b1d6cSniklas   { 0x0082, SETS1 | USESSP },			/* stc r0_bank,rn */
1718c88b1d6cSniklas   { 0x0092, SETS1 | USESSP },			/* stc r1_bank,rn */
1719c88b1d6cSniklas   { 0x00a2, SETS1 | USESSP },			/* stc r2_bank,rn */
1720c88b1d6cSniklas   { 0x00b2, SETS1 | USESSP },			/* stc r3_bank,rn */
1721c88b1d6cSniklas   { 0x00c2, SETS1 | USESSP },			/* stc r4_bank,rn */
1722c88b1d6cSniklas   { 0x00d2, SETS1 | USESSP },			/* stc r5_bank,rn */
1723c88b1d6cSniklas   { 0x00e2, SETS1 | USESSP },			/* stc r6_bank,rn */
1724c88b1d6cSniklas   { 0x00f2, SETS1 | USESSP }			/* stc r7_bank,rn */
1725b305b0f1Sespie #endif
1726c88b1d6cSniklas 
1727c88b1d6cSniklas static const struct sh_opcode sh_opcode02[] =
1728c88b1d6cSniklas {
1729b305b0f1Sespie   { 0x0002, SETS1 | USESSP },			/* stc <special_reg>,rn */
1730c88b1d6cSniklas   { 0x0004, STORE | USES1 | USES2 | USESR0 },	/* mov.b rm,@(r0,rn) */
1731c88b1d6cSniklas   { 0x0005, STORE | USES1 | USES2 | USESR0 },	/* mov.w rm,@(r0,rn) */
1732c88b1d6cSniklas   { 0x0006, STORE | USES1 | USES2 | USESR0 },	/* mov.l rm,@(r0,rn) */
1733c88b1d6cSniklas   { 0x0007, SETSSP | USES1 | USES2 },		/* mul.l rm,rn */
1734c88b1d6cSniklas   { 0x000c, LOAD | SETS1 | USES2 | USESR0 },	/* mov.b @(r0,rm),rn */
1735c88b1d6cSniklas   { 0x000d, LOAD | SETS1 | USES2 | USESR0 },	/* mov.w @(r0,rm),rn */
1736c88b1d6cSniklas   { 0x000e, LOAD | SETS1 | USES2 | USESR0 },	/* mov.l @(r0,rm),rn */
1737c88b1d6cSniklas   { 0x000f, LOAD|SETS1|SETS2|SETSSP|USES1|USES2|USESSP }, /* mac.l @rm+,@rn+ */
1738c88b1d6cSniklas };
1739c88b1d6cSniklas 
1740c88b1d6cSniklas static const struct sh_minor_opcode sh_opcode0[] =
1741c88b1d6cSniklas {
1742c88b1d6cSniklas   { MAP (sh_opcode00), 0xffff },
1743c88b1d6cSniklas   { MAP (sh_opcode01), 0xf0ff },
1744c88b1d6cSniklas   { MAP (sh_opcode02), 0xf00f }
1745c88b1d6cSniklas };
1746c88b1d6cSniklas 
1747c88b1d6cSniklas static const struct sh_opcode sh_opcode10[] =
1748c88b1d6cSniklas {
1749c88b1d6cSniklas   { 0x1000, STORE | USES1 | USES2 }	/* mov.l rm,@(disp,rn) */
1750c88b1d6cSniklas };
1751c88b1d6cSniklas 
1752c88b1d6cSniklas static const struct sh_minor_opcode sh_opcode1[] =
1753c88b1d6cSniklas {
1754c88b1d6cSniklas   { MAP (sh_opcode10), 0xf000 }
1755c88b1d6cSniklas };
1756c88b1d6cSniklas 
1757c88b1d6cSniklas static const struct sh_opcode sh_opcode20[] =
1758c88b1d6cSniklas {
1759c88b1d6cSniklas   { 0x2000, STORE | USES1 | USES2 },		/* mov.b rm,@rn */
1760c88b1d6cSniklas   { 0x2001, STORE | USES1 | USES2 },		/* mov.w rm,@rn */
1761c88b1d6cSniklas   { 0x2002, STORE | USES1 | USES2 },		/* mov.l rm,@rn */
1762c88b1d6cSniklas   { 0x2004, STORE | SETS1 | USES1 | USES2 },	/* mov.b rm,@-rn */
1763c88b1d6cSniklas   { 0x2005, STORE | SETS1 | USES1 | USES2 },	/* mov.w rm,@-rn */
1764c88b1d6cSniklas   { 0x2006, STORE | SETS1 | USES1 | USES2 },	/* mov.l rm,@-rn */
1765c88b1d6cSniklas   { 0x2007, SETSSP | USES1 | USES2 | USESSP },	/* div0s */
1766c88b1d6cSniklas   { 0x2008, SETSSP | USES1 | USES2 },		/* tst rm,rn */
1767c88b1d6cSniklas   { 0x2009, SETS1 | USES1 | USES2 },		/* and rm,rn */
1768c88b1d6cSniklas   { 0x200a, SETS1 | USES1 | USES2 },		/* xor rm,rn */
1769c88b1d6cSniklas   { 0x200b, SETS1 | USES1 | USES2 },		/* or rm,rn */
1770c88b1d6cSniklas   { 0x200c, SETSSP | USES1 | USES2 },		/* cmp/str rm,rn */
1771c88b1d6cSniklas   { 0x200d, SETS1 | USES1 | USES2 },		/* xtrct rm,rn */
1772c88b1d6cSniklas   { 0x200e, SETSSP | USES1 | USES2 },		/* mulu.w rm,rn */
1773c88b1d6cSniklas   { 0x200f, SETSSP | USES1 | USES2 }		/* muls.w rm,rn */
1774c88b1d6cSniklas };
1775c88b1d6cSniklas 
1776c88b1d6cSniklas static const struct sh_minor_opcode sh_opcode2[] =
1777c88b1d6cSniklas {
1778c88b1d6cSniklas   { MAP (sh_opcode20), 0xf00f }
1779c88b1d6cSniklas };
1780c88b1d6cSniklas 
1781c88b1d6cSniklas static const struct sh_opcode sh_opcode30[] =
1782c88b1d6cSniklas {
1783c88b1d6cSniklas   { 0x3000, SETSSP | USES1 | USES2 },		/* cmp/eq rm,rn */
1784c88b1d6cSniklas   { 0x3002, SETSSP | USES1 | USES2 },		/* cmp/hs rm,rn */
1785c88b1d6cSniklas   { 0x3003, SETSSP | USES1 | USES2 },		/* cmp/ge rm,rn */
1786c88b1d6cSniklas   { 0x3004, SETSSP | USESSP | USES1 | USES2 },	/* div1 rm,rn */
1787c88b1d6cSniklas   { 0x3005, SETSSP | USES1 | USES2 },		/* dmulu.l rm,rn */
1788c88b1d6cSniklas   { 0x3006, SETSSP | USES1 | USES2 },		/* cmp/hi rm,rn */
1789c88b1d6cSniklas   { 0x3007, SETSSP | USES1 | USES2 },		/* cmp/gt rm,rn */
1790c88b1d6cSniklas   { 0x3008, SETS1 | USES1 | USES2 },		/* sub rm,rn */
1791c88b1d6cSniklas   { 0x300a, SETS1 | SETSSP | USES1 | USES2 | USESSP }, /* subc rm,rn */
1792c88b1d6cSniklas   { 0x300b, SETS1 | SETSSP | USES1 | USES2 },	/* subv rm,rn */
1793c88b1d6cSniklas   { 0x300c, SETS1 | USES1 | USES2 },		/* add rm,rn */
1794c88b1d6cSniklas   { 0x300d, SETSSP | USES1 | USES2 },		/* dmuls.l rm,rn */
1795c88b1d6cSniklas   { 0x300e, SETS1 | SETSSP | USES1 | USES2 | USESSP }, /* addc rm,rn */
1796c88b1d6cSniklas   { 0x300f, SETS1 | SETSSP | USES1 | USES2 }	/* addv rm,rn */
1797c88b1d6cSniklas };
1798c88b1d6cSniklas 
1799c88b1d6cSniklas static const struct sh_minor_opcode sh_opcode3[] =
1800c88b1d6cSniklas {
1801c88b1d6cSniklas   { MAP (sh_opcode30), 0xf00f }
1802c88b1d6cSniklas };
1803c88b1d6cSniklas 
1804c88b1d6cSniklas static const struct sh_opcode sh_opcode40[] =
1805c88b1d6cSniklas {
1806c88b1d6cSniklas   { 0x4000, SETS1 | SETSSP | USES1 },		/* shll rn */
1807c88b1d6cSniklas   { 0x4001, SETS1 | SETSSP | USES1 },		/* shlr rn */
1808c88b1d6cSniklas   { 0x4002, STORE | SETS1 | USES1 | USESSP },	/* sts.l mach,@-rn */
1809c88b1d6cSniklas   { 0x4004, SETS1 | SETSSP | USES1 },		/* rotl rn */
1810c88b1d6cSniklas   { 0x4005, SETS1 | SETSSP | USES1 },		/* rotr rn */
1811c88b1d6cSniklas   { 0x4006, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,mach */
1812c88b1d6cSniklas   { 0x4008, SETS1 | USES1 },			/* shll2 rn */
1813c88b1d6cSniklas   { 0x4009, SETS1 | USES1 },			/* shlr2 rn */
1814c88b1d6cSniklas   { 0x400a, SETSSP | USES1 },			/* lds rm,mach */
1815c88b1d6cSniklas   { 0x400b, BRANCH | DELAY | USES1 },		/* jsr @rn */
1816c88b1d6cSniklas   { 0x4010, SETS1 | SETSSP | USES1 },		/* dt rn */
1817c88b1d6cSniklas   { 0x4011, SETSSP | USES1 },			/* cmp/pz rn */
1818c88b1d6cSniklas   { 0x4012, STORE | SETS1 | USES1 | USESSP },	/* sts.l macl,@-rn */
1819b305b0f1Sespie   { 0x4014, SETSSP | USES1 },			/* setrc rm */
1820c88b1d6cSniklas   { 0x4015, SETSSP | USES1 },			/* cmp/pl rn */
1821c88b1d6cSniklas   { 0x4016, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,macl */
1822c88b1d6cSniklas   { 0x4018, SETS1 | USES1 },			/* shll8 rn */
1823c88b1d6cSniklas   { 0x4019, SETS1 | USES1 },			/* shlr8 rn */
1824c88b1d6cSniklas   { 0x401a, SETSSP | USES1 },			/* lds rm,macl */
1825c88b1d6cSniklas   { 0x401b, LOAD | SETSSP | USES1 },		/* tas.b @rn */
1826c88b1d6cSniklas   { 0x4020, SETS1 | SETSSP | USES1 },		/* shal rn */
1827c88b1d6cSniklas   { 0x4021, SETS1 | SETSSP | USES1 },		/* shar rn */
1828c88b1d6cSniklas   { 0x4022, STORE | SETS1 | USES1 | USESSP },	/* sts.l pr,@-rn */
1829c88b1d6cSniklas   { 0x4024, SETS1 | SETSSP | USES1 | USESSP },	/* rotcl rn */
1830c88b1d6cSniklas   { 0x4025, SETS1 | SETSSP | USES1 | USESSP },	/* rotcr rn */
1831c88b1d6cSniklas   { 0x4026, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,pr */
1832c88b1d6cSniklas   { 0x4028, SETS1 | USES1 },			/* shll16 rn */
1833c88b1d6cSniklas   { 0x4029, SETS1 | USES1 },			/* shlr16 rn */
1834c88b1d6cSniklas   { 0x402a, SETSSP | USES1 },			/* lds rm,pr */
1835c88b1d6cSniklas   { 0x402b, BRANCH | DELAY | USES1 },		/* jmp @rn */
1836c88b1d6cSniklas   { 0x4052, STORE | SETS1 | USES1 | USESSP },	/* sts.l fpul,@-rn */
1837c88b1d6cSniklas   { 0x4056, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,fpul */
1838c88b1d6cSniklas   { 0x405a, SETSSP | USES1 },			/* lds.l rm,fpul */
1839b305b0f1Sespie   { 0x4062, STORE | SETS1 | USES1 | USESSP },	/* sts.l fpscr / dsr,@-rn */
1840b305b0f1Sespie   { 0x4066, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,fpscr / dsr */
1841b305b0f1Sespie   { 0x406a, SETSSP | USES1 },			/* lds rm,fpscr / lds rm,dsr */
1842b305b0f1Sespie   { 0x4072, STORE | SETS1 | USES1 | USESSP },	/* sts.l a0,@-rn */
1843b305b0f1Sespie   { 0x4076, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,a0 */
1844b305b0f1Sespie   { 0x407a, SETSSP | USES1 },			/* lds.l rm,a0 */
1845b305b0f1Sespie   { 0x4082, STORE | SETS1 | USES1 | USESSP },	/* sts.l x0,@-rn */
1846b305b0f1Sespie   { 0x4086, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,x0 */
1847b305b0f1Sespie   { 0x408a, SETSSP | USES1 },			/* lds.l rm,x0 */
1848b305b0f1Sespie   { 0x4092, STORE | SETS1 | USES1 | USESSP },	/* sts.l x1,@-rn */
1849b305b0f1Sespie   { 0x4096, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,x1 */
1850b305b0f1Sespie   { 0x409a, SETSSP | USES1 },			/* lds.l rm,x1 */
1851b305b0f1Sespie   { 0x40a2, STORE | SETS1 | USES1 | USESSP },	/* sts.l y0,@-rn */
1852b305b0f1Sespie   { 0x40a6, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,y0 */
1853b305b0f1Sespie   { 0x40aa, SETSSP | USES1 },			/* lds.l rm,y0 */
1854b305b0f1Sespie   { 0x40b2, STORE | SETS1 | USES1 | USESSP },	/* sts.l y1,@-rn */
1855b305b0f1Sespie   { 0x40b6, LOAD | SETS1 | SETSSP | USES1 },	/* lds.l @rm+,y1 */
1856b305b0f1Sespie   { 0x40ba, SETSSP | USES1 }			/* lds.l rm,y1 */
1857b305b0f1Sespie #if 0 /* These groups sixteen insns can be
1858b305b0f1Sespie          handled with one table entry each below.  */
1859b305b0f1Sespie   { 0x4003, STORE | SETS1 | USES1 | USESSP },	/* stc.l sr,@-rn */
1860b305b0f1Sespie   { 0x4013, STORE | SETS1 | USES1 | USESSP },	/* stc.l gbr,@-rn */
1861b305b0f1Sespie   { 0x4023, STORE | SETS1 | USES1 | USESSP },	/* stc.l vbr,@-rn */
1862b305b0f1Sespie   { 0x4033, STORE | SETS1 | USES1 | USESSP },	/* stc.l ssr,@-rn */
1863b305b0f1Sespie   { 0x4043, STORE | SETS1 | USES1 | USESSP },	/* stc.l spc,@-rn */
1864b305b0f1Sespie   { 0x4053, STORE | SETS1 | USES1 | USESSP },	/* stc.l mod,@-rn */
1865b305b0f1Sespie   { 0x4063, STORE | SETS1 | USES1 | USESSP },	/* stc.l rs,@-rn */
1866b305b0f1Sespie   { 0x4073, STORE | SETS1 | USES1 | USESSP },	/* stc.l re,@-rn */
1867b305b0f1Sespie   { 0x4083, STORE | SETS1 | USES1 | USESSP },	/* stc.l r0_bank,@-rn */
1868b305b0f1Sespie   ..
1869b305b0f1Sespie   { 0x40f3, STORE | SETS1 | USES1 | USESSP },	/* stc.l r7_bank,@-rn */
1870b305b0f1Sespie 
1871b305b0f1Sespie   { 0x4007, LOAD | SETS1 | SETSSP | USES1 },	/* ldc.l @rm+,sr */
1872b305b0f1Sespie   { 0x4017, LOAD | SETS1 | SETSSP | USES1 },	/* ldc.l @rm+,gbr */
1873b305b0f1Sespie   { 0x4027, LOAD | SETS1 | SETSSP | USES1 },	/* ldc.l @rm+,vbr */
1874b305b0f1Sespie   { 0x4037, LOAD | SETS1 | SETSSP | USES1 },	/* ldc.l @rm+,ssr */
1875b305b0f1Sespie   { 0x4047, LOAD | SETS1 | SETSSP | USES1 },	/* ldc.l @rm+,spc */
1876b305b0f1Sespie   { 0x4057, LOAD | SETS1 | SETSSP | USES1 },	/* ldc.l @rm+,mod */
1877b305b0f1Sespie   { 0x4067, LOAD | SETS1 | SETSSP | USES1 },	/* ldc.l @rm+,rs */
1878b305b0f1Sespie   { 0x4077, LOAD | SETS1 | SETSSP | USES1 },	/* ldc.l @rm+,re */
1879b305b0f1Sespie   { 0x4087, LOAD | SETS1 | SETSSP | USES1 },	/* ldc.l @rm+,r0_bank */
1880b305b0f1Sespie   ..
1881b305b0f1Sespie   { 0x40f7, LOAD | SETS1 | SETSSP | USES1 },	/* ldc.l @rm+,r7_bank */
1882b305b0f1Sespie 
1883b305b0f1Sespie   { 0x400e, SETSSP | USES1 },			/* ldc rm,sr */
1884b305b0f1Sespie   { 0x401e, SETSSP | USES1 },			/* ldc rm,gbr */
1885b305b0f1Sespie   { 0x402e, SETSSP | USES1 },			/* ldc rm,vbr */
1886b305b0f1Sespie   { 0x403e, SETSSP | USES1 },			/* ldc rm,ssr */
1887b305b0f1Sespie   { 0x404e, SETSSP | USES1 },			/* ldc rm,spc */
1888b305b0f1Sespie   { 0x405e, SETSSP | USES1 },			/* ldc rm,mod */
1889b305b0f1Sespie   { 0x406e, SETSSP | USES1 },			/* ldc rm,rs */
1890b305b0f1Sespie   { 0x407e, SETSSP | USES1 }			/* ldc rm,re */
1891b305b0f1Sespie   { 0x408e, SETSSP | USES1 }			/* ldc rm,r0_bank */
1892b305b0f1Sespie   ..
1893b305b0f1Sespie   { 0x40fe, SETSSP | USES1 }			/* ldc rm,r7_bank */
1894b305b0f1Sespie #endif
1895c88b1d6cSniklas };
1896c88b1d6cSniklas 
1897c88b1d6cSniklas static const struct sh_opcode sh_opcode41[] =
1898c88b1d6cSniklas {
1899b305b0f1Sespie   { 0x4003, STORE | SETS1 | USES1 | USESSP },	/* stc.l <special_reg>,@-rn */
1900b305b0f1Sespie   { 0x4007, LOAD | SETS1 | SETSSP | USES1 },	/* ldc.l @rm+,<special_reg> */
1901c88b1d6cSniklas   { 0x400c, SETS1 | USES1 | USES2 },		/* shad rm,rn */
1902c88b1d6cSniklas   { 0x400d, SETS1 | USES1 | USES2 },		/* shld rm,rn */
1903b305b0f1Sespie   { 0x400e, SETSSP | USES1 },			/* ldc rm,<special_reg> */
1904c88b1d6cSniklas   { 0x400f, LOAD|SETS1|SETS2|SETSSP|USES1|USES2|USESSP }, /* mac.w @rm+,@rn+ */
1905c88b1d6cSniklas };
1906c88b1d6cSniklas 
1907c88b1d6cSniklas static const struct sh_minor_opcode sh_opcode4[] =
1908c88b1d6cSniklas {
1909c88b1d6cSniklas   { MAP (sh_opcode40), 0xf0ff },
1910b305b0f1Sespie   { MAP (sh_opcode41), 0xf00f }
1911c88b1d6cSniklas };
1912c88b1d6cSniklas 
1913c88b1d6cSniklas static const struct sh_opcode sh_opcode50[] =
1914c88b1d6cSniklas {
1915c88b1d6cSniklas   { 0x5000, LOAD | SETS1 | USES2 }	/* mov.l @(disp,rm),rn */
1916c88b1d6cSniklas };
1917c88b1d6cSniklas 
1918c88b1d6cSniklas static const struct sh_minor_opcode sh_opcode5[] =
1919c88b1d6cSniklas {
1920c88b1d6cSniklas   { MAP (sh_opcode50), 0xf000 }
1921c88b1d6cSniklas };
1922c88b1d6cSniklas 
1923c88b1d6cSniklas static const struct sh_opcode sh_opcode60[] =
1924c88b1d6cSniklas {
1925c88b1d6cSniklas   { 0x6000, LOAD | SETS1 | USES2 },		/* mov.b @rm,rn */
1926c88b1d6cSniklas   { 0x6001, LOAD | SETS1 | USES2 },		/* mov.w @rm,rn */
1927c88b1d6cSniklas   { 0x6002, LOAD | SETS1 | USES2 },		/* mov.l @rm,rn */
1928c88b1d6cSniklas   { 0x6003, SETS1 | USES2 },			/* mov rm,rn */
1929c88b1d6cSniklas   { 0x6004, LOAD | SETS1 | SETS2 | USES2 },	/* mov.b @rm+,rn */
1930c88b1d6cSniklas   { 0x6005, LOAD | SETS1 | SETS2 | USES2 },	/* mov.w @rm+,rn */
1931c88b1d6cSniklas   { 0x6006, LOAD | SETS1 | SETS2 | USES2 },	/* mov.l @rm+,rn */
1932c88b1d6cSniklas   { 0x6007, SETS1 | USES2 },			/* not rm,rn */
1933c88b1d6cSniklas   { 0x6008, SETS1 | USES2 },			/* swap.b rm,rn */
1934c88b1d6cSniklas   { 0x6009, SETS1 | USES2 },			/* swap.w rm,rn */
1935c88b1d6cSniklas   { 0x600a, SETS1 | SETSSP | USES2 | USESSP },	/* negc rm,rn */
1936c88b1d6cSniklas   { 0x600b, SETS1 | USES2 },			/* neg rm,rn */
1937c88b1d6cSniklas   { 0x600c, SETS1 | USES2 },			/* extu.b rm,rn */
1938c88b1d6cSniklas   { 0x600d, SETS1 | USES2 },			/* extu.w rm,rn */
1939c88b1d6cSniklas   { 0x600e, SETS1 | USES2 },			/* exts.b rm,rn */
1940c88b1d6cSniklas   { 0x600f, SETS1 | USES2 }			/* exts.w rm,rn */
1941c88b1d6cSniklas };
1942c88b1d6cSniklas 
1943c88b1d6cSniklas static const struct sh_minor_opcode sh_opcode6[] =
1944c88b1d6cSniklas {
1945c88b1d6cSniklas   { MAP (sh_opcode60), 0xf00f }
1946c88b1d6cSniklas };
1947c88b1d6cSniklas 
1948c88b1d6cSniklas static const struct sh_opcode sh_opcode70[] =
1949c88b1d6cSniklas {
1950c88b1d6cSniklas   { 0x7000, SETS1 | USES1 }		/* add #imm,rn */
1951c88b1d6cSniklas };
1952c88b1d6cSniklas 
1953c88b1d6cSniklas static const struct sh_minor_opcode sh_opcode7[] =
1954c88b1d6cSniklas {
1955c88b1d6cSniklas   { MAP (sh_opcode70), 0xf000 }
1956c88b1d6cSniklas };
1957c88b1d6cSniklas 
1958c88b1d6cSniklas static const struct sh_opcode sh_opcode80[] =
1959c88b1d6cSniklas {
1960c88b1d6cSniklas   { 0x8000, STORE | USES2 | USESR0 },	/* mov.b r0,@(disp,rn) */
1961c88b1d6cSniklas   { 0x8100, STORE | USES2 | USESR0 },	/* mov.w r0,@(disp,rn) */
1962b305b0f1Sespie   { 0x8200, SETSSP },			/* setrc #imm */
1963c88b1d6cSniklas   { 0x8400, LOAD | SETSR0 | USES2 },	/* mov.b @(disp,rm),r0 */
1964c88b1d6cSniklas   { 0x8500, LOAD | SETSR0 | USES2 },	/* mov.w @(disp,rn),r0 */
1965c88b1d6cSniklas   { 0x8800, SETSSP | USESR0 },		/* cmp/eq #imm,r0 */
1966c88b1d6cSniklas   { 0x8900, BRANCH | USESSP },		/* bt label */
1967c88b1d6cSniklas   { 0x8b00, BRANCH | USESSP },		/* bf label */
1968b305b0f1Sespie   { 0x8c00, SETSSP },			/* ldrs @(disp,pc) */
1969c88b1d6cSniklas   { 0x8d00, BRANCH | DELAY | USESSP },	/* bt/s label */
1970b305b0f1Sespie   { 0x8e00, SETSSP },			/* ldre @(disp,pc) */
1971c88b1d6cSniklas   { 0x8f00, BRANCH | DELAY | USESSP }	/* bf/s label */
1972c88b1d6cSniklas };
1973c88b1d6cSniklas 
1974c88b1d6cSniklas static const struct sh_minor_opcode sh_opcode8[] =
1975c88b1d6cSniklas {
1976c88b1d6cSniklas   { MAP (sh_opcode80), 0xff00 }
1977c88b1d6cSniklas };
1978c88b1d6cSniklas 
1979c88b1d6cSniklas static const struct sh_opcode sh_opcode90[] =
1980c88b1d6cSniklas {
1981c88b1d6cSniklas   { 0x9000, LOAD | SETS1 }	/* mov.w @(disp,pc),rn */
1982c88b1d6cSniklas };
1983c88b1d6cSniklas 
1984c88b1d6cSniklas static const struct sh_minor_opcode sh_opcode9[] =
1985c88b1d6cSniklas {
1986c88b1d6cSniklas   { MAP (sh_opcode90), 0xf000 }
1987c88b1d6cSniklas };
1988c88b1d6cSniklas 
1989c88b1d6cSniklas static const struct sh_opcode sh_opcodea0[] =
1990c88b1d6cSniklas {
1991c88b1d6cSniklas   { 0xa000, BRANCH | DELAY }	/* bra label */
1992c88b1d6cSniklas };
1993c88b1d6cSniklas 
1994c88b1d6cSniklas static const struct sh_minor_opcode sh_opcodea[] =
1995c88b1d6cSniklas {
1996c88b1d6cSniklas   { MAP (sh_opcodea0), 0xf000 }
1997c88b1d6cSniklas };
1998c88b1d6cSniklas 
1999c88b1d6cSniklas static const struct sh_opcode sh_opcodeb0[] =
2000c88b1d6cSniklas {
2001c88b1d6cSniklas   { 0xb000, BRANCH | DELAY }	/* bsr label */
2002c88b1d6cSniklas };
2003c88b1d6cSniklas 
2004c88b1d6cSniklas static const struct sh_minor_opcode sh_opcodeb[] =
2005c88b1d6cSniklas {
2006c88b1d6cSniklas   { MAP (sh_opcodeb0), 0xf000 }
2007c88b1d6cSniklas };
2008c88b1d6cSniklas 
2009c88b1d6cSniklas static const struct sh_opcode sh_opcodec0[] =
2010c88b1d6cSniklas {
2011c88b1d6cSniklas   { 0xc000, STORE | USESR0 | USESSP },		/* mov.b r0,@(disp,gbr) */
2012c88b1d6cSniklas   { 0xc100, STORE | USESR0 | USESSP },		/* mov.w r0,@(disp,gbr) */
2013c88b1d6cSniklas   { 0xc200, STORE | USESR0 | USESSP },		/* mov.l r0,@(disp,gbr) */
2014c88b1d6cSniklas   { 0xc300, BRANCH | USESSP },			/* trapa #imm */
2015c88b1d6cSniklas   { 0xc400, LOAD | SETSR0 | USESSP },		/* mov.b @(disp,gbr),r0 */
2016c88b1d6cSniklas   { 0xc500, LOAD | SETSR0 | USESSP },		/* mov.w @(disp,gbr),r0 */
2017c88b1d6cSniklas   { 0xc600, LOAD | SETSR0 | USESSP },		/* mov.l @(disp,gbr),r0 */
2018c88b1d6cSniklas   { 0xc700, SETSR0 },				/* mova @(disp,pc),r0 */
2019c88b1d6cSniklas   { 0xc800, SETSSP | USESR0 },			/* tst #imm,r0 */
2020c88b1d6cSniklas   { 0xc900, SETSR0 | USESR0 },			/* and #imm,r0 */
2021c88b1d6cSniklas   { 0xca00, SETSR0 | USESR0 },			/* xor #imm,r0 */
2022c88b1d6cSniklas   { 0xcb00, SETSR0 | USESR0 },			/* or #imm,r0 */
2023c88b1d6cSniklas   { 0xcc00, LOAD | SETSSP | USESR0 | USESSP },	/* tst.b #imm,@(r0,gbr) */
2024c88b1d6cSniklas   { 0xcd00, LOAD | STORE | USESR0 | USESSP },	/* and.b #imm,@(r0,gbr) */
2025c88b1d6cSniklas   { 0xce00, LOAD | STORE | USESR0 | USESSP },	/* xor.b #imm,@(r0,gbr) */
2026c88b1d6cSniklas   { 0xcf00, LOAD | STORE | USESR0 | USESSP }	/* or.b #imm,@(r0,gbr) */
2027c88b1d6cSniklas };
2028c88b1d6cSniklas 
2029c88b1d6cSniklas static const struct sh_minor_opcode sh_opcodec[] =
2030c88b1d6cSniklas {
2031c88b1d6cSniklas   { MAP (sh_opcodec0), 0xff00 }
2032c88b1d6cSniklas };
2033c88b1d6cSniklas 
2034c88b1d6cSniklas static const struct sh_opcode sh_opcoded0[] =
2035c88b1d6cSniklas {
2036c88b1d6cSniklas   { 0xd000, LOAD | SETS1 }		/* mov.l @(disp,pc),rn */
2037c88b1d6cSniklas };
2038c88b1d6cSniklas 
2039c88b1d6cSniklas static const struct sh_minor_opcode sh_opcoded[] =
2040c88b1d6cSniklas {
2041c88b1d6cSniklas   { MAP (sh_opcoded0), 0xf000 }
2042c88b1d6cSniklas };
2043c88b1d6cSniklas 
2044c88b1d6cSniklas static const struct sh_opcode sh_opcodee0[] =
2045c88b1d6cSniklas {
2046c88b1d6cSniklas   { 0xe000, SETS1 }		/* mov #imm,rn */
2047c88b1d6cSniklas };
2048c88b1d6cSniklas 
2049c88b1d6cSniklas static const struct sh_minor_opcode sh_opcodee[] =
2050c88b1d6cSniklas {
2051c88b1d6cSniklas   { MAP (sh_opcodee0), 0xf000 }
2052c88b1d6cSniklas };
2053c88b1d6cSniklas 
2054c88b1d6cSniklas static const struct sh_opcode sh_opcodef0[] =
2055c88b1d6cSniklas {
2056c88b1d6cSniklas   { 0xf000, SETSF1 | USESF1 | USESF2 },		/* fadd fm,fn */
2057c88b1d6cSniklas   { 0xf001, SETSF1 | USESF1 | USESF2 },		/* fsub fm,fn */
2058c88b1d6cSniklas   { 0xf002, SETSF1 | USESF1 | USESF2 },		/* fmul fm,fn */
2059c88b1d6cSniklas   { 0xf003, SETSF1 | USESF1 | USESF2 },		/* fdiv fm,fn */
2060c88b1d6cSniklas   { 0xf004, SETSSP | USESF1 | USESF2 },		/* fcmp/eq fm,fn */
2061c88b1d6cSniklas   { 0xf005, SETSSP | USESF1 | USESF2 },		/* fcmp/gt fm,fn */
2062c88b1d6cSniklas   { 0xf006, LOAD | SETSF1 | USES2 | USESR0 },	/* fmov.s @(r0,rm),fn */
2063c88b1d6cSniklas   { 0xf007, STORE | USES1 | USESF2 | USESR0 },	/* fmov.s fm,@(r0,rn) */
2064c88b1d6cSniklas   { 0xf008, LOAD | SETSF1 | USES2 },		/* fmov.s @rm,fn */
2065c88b1d6cSniklas   { 0xf009, LOAD | SETS2 | SETSF1 | USES2 },	/* fmov.s @rm+,fn */
2066c88b1d6cSniklas   { 0xf00a, STORE | USES1 | USESF2 },		/* fmov.s fm,@rn */
2067c88b1d6cSniklas   { 0xf00b, STORE | SETS1 | USES1 | USESF2 },	/* fmov.s fm,@-rn */
2068c88b1d6cSniklas   { 0xf00c, SETSF1 | USESF2 },			/* fmov fm,fn */
2069c88b1d6cSniklas   { 0xf00e, SETSF1 | USESF1 | USESF2 | USESF0 }	/* fmac f0,fm,fn */
2070c88b1d6cSniklas };
2071c88b1d6cSniklas 
2072c88b1d6cSniklas static const struct sh_opcode sh_opcodef1[] =
2073c88b1d6cSniklas {
2074c88b1d6cSniklas   { 0xf00d, SETSF1 | USESSP },	/* fsts fpul,fn */
2075c88b1d6cSniklas   { 0xf01d, SETSSP | USESF1 },	/* flds fn,fpul */
2076c88b1d6cSniklas   { 0xf02d, SETSF1 | USESSP },	/* float fpul,fn */
2077c88b1d6cSniklas   { 0xf03d, SETSSP | USESF1 },	/* ftrc fn,fpul */
2078c88b1d6cSniklas   { 0xf04d, SETSF1 | USESF1 },	/* fneg fn */
2079c88b1d6cSniklas   { 0xf05d, SETSF1 | USESF1 },	/* fabs fn */
2080c88b1d6cSniklas   { 0xf06d, SETSF1 | USESF1 },	/* fsqrt fn */
2081c88b1d6cSniklas   { 0xf07d, SETSSP | USESF1 },	/* ftst/nan fn */
2082c88b1d6cSniklas   { 0xf08d, SETSF1 },		/* fldi0 fn */
2083c88b1d6cSniklas   { 0xf09d, SETSF1 }		/* fldi1 fn */
2084c88b1d6cSniklas };
2085c88b1d6cSniklas 
2086c88b1d6cSniklas static const struct sh_minor_opcode sh_opcodef[] =
2087c88b1d6cSniklas {
2088c88b1d6cSniklas   { MAP (sh_opcodef0), 0xf00f },
2089c88b1d6cSniklas   { MAP (sh_opcodef1), 0xf0ff }
2090c88b1d6cSniklas };
2091c88b1d6cSniklas 
2092b305b0f1Sespie static struct sh_major_opcode sh_opcodes[] =
2093c88b1d6cSniklas {
2094c88b1d6cSniklas   { MAP (sh_opcode0) },
2095c88b1d6cSniklas   { MAP (sh_opcode1) },
2096c88b1d6cSniklas   { MAP (sh_opcode2) },
2097c88b1d6cSniklas   { MAP (sh_opcode3) },
2098c88b1d6cSniklas   { MAP (sh_opcode4) },
2099c88b1d6cSniklas   { MAP (sh_opcode5) },
2100c88b1d6cSniklas   { MAP (sh_opcode6) },
2101c88b1d6cSniklas   { MAP (sh_opcode7) },
2102c88b1d6cSniklas   { MAP (sh_opcode8) },
2103c88b1d6cSniklas   { MAP (sh_opcode9) },
2104c88b1d6cSniklas   { MAP (sh_opcodea) },
2105c88b1d6cSniklas   { MAP (sh_opcodeb) },
2106c88b1d6cSniklas   { MAP (sh_opcodec) },
2107c88b1d6cSniklas   { MAP (sh_opcoded) },
2108c88b1d6cSniklas   { MAP (sh_opcodee) },
2109c88b1d6cSniklas   { MAP (sh_opcodef) }
2110c88b1d6cSniklas };
2111c88b1d6cSniklas 
2112b305b0f1Sespie /* The double data transfer / parallel processing insns are not
2113b305b0f1Sespie    described here.  This will cause sh_align_load_span to leave them alone.  */
2114b305b0f1Sespie 
2115b305b0f1Sespie static const struct sh_opcode sh_dsp_opcodef0[] =
2116b305b0f1Sespie {
2117b305b0f1Sespie   { 0xf400, USESAS | SETSAS | LOAD | SETSSP },	/* movs.x @-as,ds */
2118b305b0f1Sespie   { 0xf401, USESAS | SETSAS | STORE | USESSP },	/* movs.x ds,@-as */
2119b305b0f1Sespie   { 0xf404, USESAS | LOAD | SETSSP },		/* movs.x @as,ds */
2120b305b0f1Sespie   { 0xf405, USESAS | STORE | USESSP },		/* movs.x ds,@as */
2121b305b0f1Sespie   { 0xf408, USESAS | SETSAS | LOAD | SETSSP },	/* movs.x @as+,ds */
2122b305b0f1Sespie   { 0xf409, USESAS | SETSAS | STORE | USESSP },	/* movs.x ds,@as+ */
2123b305b0f1Sespie   { 0xf40c, USESAS | SETSAS | LOAD | SETSSP | USESR8 },	/* movs.x @as+r8,ds */
2124b305b0f1Sespie   { 0xf40d, USESAS | SETSAS | STORE | USESSP | USESR8 }	/* movs.x ds,@as+r8 */
2125b305b0f1Sespie };
2126b305b0f1Sespie 
2127b305b0f1Sespie static const struct sh_minor_opcode sh_dsp_opcodef[] =
2128b305b0f1Sespie {
2129b305b0f1Sespie   { MAP (sh_dsp_opcodef0), 0xfc0d }
2130b305b0f1Sespie };
2131b305b0f1Sespie 
2132c88b1d6cSniklas /* Given an instruction, return a pointer to the corresponding
2133c88b1d6cSniklas    sh_opcode structure.  Return NULL if the instruction is not
2134c88b1d6cSniklas    recognized.  */
2135c88b1d6cSniklas 
2136c88b1d6cSniklas static const struct sh_opcode *
sh_insn_info(insn)2137c88b1d6cSniklas sh_insn_info (insn)
2138c88b1d6cSniklas      unsigned int insn;
2139c88b1d6cSniklas {
2140c88b1d6cSniklas   const struct sh_major_opcode *maj;
2141c88b1d6cSniklas   const struct sh_minor_opcode *min, *minend;
2142c88b1d6cSniklas 
2143c88b1d6cSniklas   maj = &sh_opcodes[(insn & 0xf000) >> 12];
2144c88b1d6cSniklas   min = maj->minor_opcodes;
2145c88b1d6cSniklas   minend = min + maj->count;
2146c88b1d6cSniklas   for (; min < minend; min++)
2147c88b1d6cSniklas     {
2148c88b1d6cSniklas       unsigned int l;
2149c88b1d6cSniklas       const struct sh_opcode *op, *opend;
2150c88b1d6cSniklas 
2151c88b1d6cSniklas       l = insn & min->mask;
2152c88b1d6cSniklas       op = min->opcodes;
2153c88b1d6cSniklas       opend = op + min->count;
2154c88b1d6cSniklas 
2155c88b1d6cSniklas       /* Since the opcodes tables are sorted, we could use a binary
2156c88b1d6cSniklas          search here if the count were above some cutoff value.  */
2157c88b1d6cSniklas       for (; op < opend; op++)
2158c88b1d6cSniklas 	if (op->opcode == l)
2159c88b1d6cSniklas 	  return op;
2160c88b1d6cSniklas     }
2161c88b1d6cSniklas 
2162c88b1d6cSniklas   return NULL;
2163c88b1d6cSniklas }
2164c88b1d6cSniklas 
2165b305b0f1Sespie /* See whether an instruction uses or sets a general purpose register */
2166b305b0f1Sespie 
2167c074d1c9Sdrahn static bfd_boolean
sh_insn_uses_or_sets_reg(insn,op,reg)2168b305b0f1Sespie sh_insn_uses_or_sets_reg (insn, op, reg)
2169b305b0f1Sespie      unsigned int insn;
2170b305b0f1Sespie      const struct sh_opcode *op;
2171b305b0f1Sespie      unsigned int reg;
2172b305b0f1Sespie {
2173b305b0f1Sespie   if (sh_insn_uses_reg (insn, op, reg))
2174c074d1c9Sdrahn     return TRUE;
2175b305b0f1Sespie 
2176b305b0f1Sespie   return sh_insn_sets_reg (insn, op, reg);
2177b305b0f1Sespie }
2178b305b0f1Sespie 
2179c88b1d6cSniklas /* See whether an instruction uses a general purpose register.  */
2180c88b1d6cSniklas 
2181c074d1c9Sdrahn static bfd_boolean
sh_insn_uses_reg(insn,op,reg)2182c88b1d6cSniklas sh_insn_uses_reg (insn, op, reg)
2183c88b1d6cSniklas      unsigned int insn;
2184c88b1d6cSniklas      const struct sh_opcode *op;
2185c88b1d6cSniklas      unsigned int reg;
2186c88b1d6cSniklas {
2187c88b1d6cSniklas   unsigned int f;
2188c88b1d6cSniklas 
2189c88b1d6cSniklas   f = op->flags;
2190c88b1d6cSniklas 
2191c88b1d6cSniklas   if ((f & USES1) != 0
2192b305b0f1Sespie       && USES1_REG (insn) == reg)
2193c074d1c9Sdrahn     return TRUE;
2194c88b1d6cSniklas   if ((f & USES2) != 0
2195b305b0f1Sespie       && USES2_REG (insn) == reg)
2196c074d1c9Sdrahn     return TRUE;
2197c88b1d6cSniklas   if ((f & USESR0) != 0
2198c88b1d6cSniklas       && reg == 0)
2199c074d1c9Sdrahn     return TRUE;
2200b305b0f1Sespie   if ((f & USESAS) && reg == USESAS_REG (insn))
2201c074d1c9Sdrahn     return TRUE;
2202b305b0f1Sespie   if ((f & USESR8) && reg == 8)
2203c074d1c9Sdrahn     return TRUE;
2204c88b1d6cSniklas 
2205c074d1c9Sdrahn   return FALSE;
2206c88b1d6cSniklas }
2207c88b1d6cSniklas 
2208b305b0f1Sespie /* See whether an instruction sets a general purpose register.  */
2209b305b0f1Sespie 
2210c074d1c9Sdrahn static bfd_boolean
sh_insn_sets_reg(insn,op,reg)2211b305b0f1Sespie sh_insn_sets_reg (insn, op, reg)
2212b305b0f1Sespie      unsigned int insn;
2213b305b0f1Sespie      const struct sh_opcode *op;
2214b305b0f1Sespie      unsigned int reg;
2215b305b0f1Sespie {
2216b305b0f1Sespie   unsigned int f;
2217b305b0f1Sespie 
2218b305b0f1Sespie   f = op->flags;
2219b305b0f1Sespie 
2220b305b0f1Sespie   if ((f & SETS1) != 0
2221b305b0f1Sespie       && SETS1_REG (insn) == reg)
2222c074d1c9Sdrahn     return TRUE;
2223b305b0f1Sespie   if ((f & SETS2) != 0
2224b305b0f1Sespie       && SETS2_REG (insn) == reg)
2225c074d1c9Sdrahn     return TRUE;
2226b305b0f1Sespie   if ((f & SETSR0) != 0
2227b305b0f1Sespie       && reg == 0)
2228c074d1c9Sdrahn     return TRUE;
2229b305b0f1Sespie   if ((f & SETSAS) && reg == SETSAS_REG (insn))
2230c074d1c9Sdrahn     return TRUE;
2231b305b0f1Sespie 
2232c074d1c9Sdrahn   return FALSE;
2233b305b0f1Sespie }
2234b305b0f1Sespie 
2235b305b0f1Sespie /* See whether an instruction uses or sets a floating point register */
2236b305b0f1Sespie 
2237c074d1c9Sdrahn static bfd_boolean
sh_insn_uses_or_sets_freg(insn,op,reg)2238b305b0f1Sespie sh_insn_uses_or_sets_freg (insn, op, reg)
2239b305b0f1Sespie      unsigned int insn;
2240b305b0f1Sespie      const struct sh_opcode *op;
2241b305b0f1Sespie      unsigned int reg;
2242b305b0f1Sespie {
2243b305b0f1Sespie   if (sh_insn_uses_freg (insn, op, reg))
2244c074d1c9Sdrahn     return TRUE;
2245b305b0f1Sespie 
2246b305b0f1Sespie   return sh_insn_sets_freg (insn, op, reg);
2247b305b0f1Sespie }
2248b305b0f1Sespie 
2249c88b1d6cSniklas /* See whether an instruction uses a floating point register.  */
2250c88b1d6cSniklas 
2251c074d1c9Sdrahn static bfd_boolean
sh_insn_uses_freg(insn,op,freg)2252c88b1d6cSniklas sh_insn_uses_freg (insn, op, freg)
2253c88b1d6cSniklas      unsigned int insn;
2254c88b1d6cSniklas      const struct sh_opcode *op;
2255c88b1d6cSniklas      unsigned int freg;
2256c88b1d6cSniklas {
2257c88b1d6cSniklas   unsigned int f;
2258c88b1d6cSniklas 
2259c88b1d6cSniklas   f = op->flags;
2260c88b1d6cSniklas 
2261b305b0f1Sespie   /* We can't tell if this is a double-precision insn, so just play safe
2262b305b0f1Sespie      and assume that it might be.  So not only have we test FREG against
2263b305b0f1Sespie      itself, but also even FREG against FREG+1 - if the using insn uses
2264b305b0f1Sespie      just the low part of a double precision value - but also an odd
2265b305b0f1Sespie      FREG against FREG-1 -  if the setting insn sets just the low part
2266b305b0f1Sespie      of a double precision value.
2267b305b0f1Sespie      So what this all boils down to is that we have to ignore the lowest
2268b305b0f1Sespie      bit of the register number.  */
2269b305b0f1Sespie 
2270c88b1d6cSniklas   if ((f & USESF1) != 0
2271b305b0f1Sespie       && (USESF1_REG (insn) & 0xe) == (freg & 0xe))
2272c074d1c9Sdrahn     return TRUE;
2273c88b1d6cSniklas   if ((f & USESF2) != 0
2274b305b0f1Sespie       && (USESF2_REG (insn) & 0xe) == (freg & 0xe))
2275c074d1c9Sdrahn     return TRUE;
2276c88b1d6cSniklas   if ((f & USESF0) != 0
2277c88b1d6cSniklas       && freg == 0)
2278c074d1c9Sdrahn     return TRUE;
2279c88b1d6cSniklas 
2280c074d1c9Sdrahn   return FALSE;
2281c88b1d6cSniklas }
2282c88b1d6cSniklas 
2283b305b0f1Sespie /* See whether an instruction sets a floating point register.  */
2284b305b0f1Sespie 
2285c074d1c9Sdrahn static bfd_boolean
sh_insn_sets_freg(insn,op,freg)2286b305b0f1Sespie sh_insn_sets_freg (insn, op, freg)
2287b305b0f1Sespie      unsigned int insn;
2288b305b0f1Sespie      const struct sh_opcode *op;
2289b305b0f1Sespie      unsigned int freg;
2290b305b0f1Sespie {
2291b305b0f1Sespie   unsigned int f;
2292b305b0f1Sespie 
2293b305b0f1Sespie   f = op->flags;
2294b305b0f1Sespie 
2295b305b0f1Sespie   /* We can't tell if this is a double-precision insn, so just play safe
2296b305b0f1Sespie      and assume that it might be.  So not only have we test FREG against
2297b305b0f1Sespie      itself, but also even FREG against FREG+1 - if the using insn uses
2298b305b0f1Sespie      just the low part of a double precision value - but also an odd
2299b305b0f1Sespie      FREG against FREG-1 -  if the setting insn sets just the low part
2300b305b0f1Sespie      of a double precision value.
2301b305b0f1Sespie      So what this all boils down to is that we have to ignore the lowest
2302b305b0f1Sespie      bit of the register number.  */
2303b305b0f1Sespie 
2304b305b0f1Sespie   if ((f & SETSF1) != 0
2305b305b0f1Sespie       && (SETSF1_REG (insn) & 0xe) == (freg & 0xe))
2306c074d1c9Sdrahn     return TRUE;
2307b305b0f1Sespie 
2308c074d1c9Sdrahn   return FALSE;
2309b305b0f1Sespie }
2310b305b0f1Sespie 
2311c88b1d6cSniklas /* See whether instructions I1 and I2 conflict, assuming I1 comes
2312c88b1d6cSniklas    before I2.  OP1 and OP2 are the corresponding sh_opcode structures.
2313c074d1c9Sdrahn    This should return TRUE if there is a conflict, or FALSE if the
23140c6d0228Sniklas    instructions can be swapped safely.  */
2315c88b1d6cSniklas 
2316c074d1c9Sdrahn static bfd_boolean
sh_insns_conflict(i1,op1,i2,op2)2317c88b1d6cSniklas sh_insns_conflict (i1, op1, i2, op2)
2318c88b1d6cSniklas      unsigned int i1;
2319c88b1d6cSniklas      const struct sh_opcode *op1;
2320c88b1d6cSniklas      unsigned int i2;
2321c88b1d6cSniklas      const struct sh_opcode *op2;
2322c88b1d6cSniklas {
2323c88b1d6cSniklas   unsigned int f1, f2;
2324c88b1d6cSniklas 
2325c88b1d6cSniklas   f1 = op1->flags;
2326c88b1d6cSniklas   f2 = op2->flags;
2327c88b1d6cSniklas 
2328b305b0f1Sespie   /* Load of fpscr conflicts with floating point operations.
2329b305b0f1Sespie      FIXME: shouldn't test raw opcodes here.  */
2330b305b0f1Sespie   if (((i1 & 0xf0ff) == 0x4066 && (i2 & 0xf000) == 0xf000)
2331b305b0f1Sespie       || ((i2 & 0xf0ff) == 0x4066 && (i1 & 0xf000) == 0xf000))
2332c074d1c9Sdrahn     return TRUE;
2333b305b0f1Sespie 
2334c88b1d6cSniklas   if ((f1 & (BRANCH | DELAY)) != 0
2335c88b1d6cSniklas       || (f2 & (BRANCH | DELAY)) != 0)
2336c074d1c9Sdrahn     return TRUE;
2337c88b1d6cSniklas 
2338b305b0f1Sespie   if (((f1 | f2) & SETSSP)
2339b305b0f1Sespie       && (f1 & (SETSSP | USESSP))
2340b305b0f1Sespie       && (f2 & (SETSSP | USESSP)))
2341c074d1c9Sdrahn     return TRUE;
2342c88b1d6cSniklas 
2343c88b1d6cSniklas   if ((f1 & SETS1) != 0
2344b305b0f1Sespie       && sh_insn_uses_or_sets_reg (i2, op2, SETS1_REG (i1)))
2345c074d1c9Sdrahn     return TRUE;
2346c88b1d6cSniklas   if ((f1 & SETS2) != 0
2347b305b0f1Sespie       && sh_insn_uses_or_sets_reg (i2, op2, SETS2_REG (i1)))
2348c074d1c9Sdrahn     return TRUE;
2349c88b1d6cSniklas   if ((f1 & SETSR0) != 0
2350b305b0f1Sespie       && sh_insn_uses_or_sets_reg (i2, op2, 0))
2351c074d1c9Sdrahn     return TRUE;
2352b305b0f1Sespie   if ((f1 & SETSAS)
2353b305b0f1Sespie       && sh_insn_uses_or_sets_reg (i2, op2, SETSAS_REG (i1)))
2354c074d1c9Sdrahn     return TRUE;
2355c88b1d6cSniklas   if ((f1 & SETSF1) != 0
2356b305b0f1Sespie       && sh_insn_uses_or_sets_freg (i2, op2, SETSF1_REG (i1)))
2357c074d1c9Sdrahn     return TRUE;
2358c88b1d6cSniklas 
2359c88b1d6cSniklas   if ((f2 & SETS1) != 0
2360b305b0f1Sespie       && sh_insn_uses_or_sets_reg (i1, op1, SETS1_REG (i2)))
2361c074d1c9Sdrahn     return TRUE;
2362c88b1d6cSniklas   if ((f2 & SETS2) != 0
2363b305b0f1Sespie       && sh_insn_uses_or_sets_reg (i1, op1, SETS2_REG (i2)))
2364c074d1c9Sdrahn     return TRUE;
2365c88b1d6cSniklas   if ((f2 & SETSR0) != 0
2366b305b0f1Sespie       && sh_insn_uses_or_sets_reg (i1, op1, 0))
2367c074d1c9Sdrahn     return TRUE;
2368b305b0f1Sespie   if ((f2 & SETSAS)
2369b305b0f1Sespie       && sh_insn_uses_or_sets_reg (i1, op1, SETSAS_REG (i2)))
2370c074d1c9Sdrahn     return TRUE;
2371c88b1d6cSniklas   if ((f2 & SETSF1) != 0
2372b305b0f1Sespie       && sh_insn_uses_or_sets_freg (i1, op1, SETSF1_REG (i2)))
2373c074d1c9Sdrahn     return TRUE;
2374c88b1d6cSniklas 
2375c88b1d6cSniklas   /* The instructions do not conflict.  */
2376c074d1c9Sdrahn   return FALSE;
2377c88b1d6cSniklas }
2378c88b1d6cSniklas 
2379c88b1d6cSniklas /* I1 is a load instruction, and I2 is some other instruction.  Return
2380c074d1c9Sdrahn    TRUE if I1 loads a register which I2 uses.  */
2381c88b1d6cSniklas 
2382c074d1c9Sdrahn static bfd_boolean
sh_load_use(i1,op1,i2,op2)2383c88b1d6cSniklas sh_load_use (i1, op1, i2, op2)
2384c88b1d6cSniklas      unsigned int i1;
2385c88b1d6cSniklas      const struct sh_opcode *op1;
2386c88b1d6cSniklas      unsigned int i2;
2387c88b1d6cSniklas      const struct sh_opcode *op2;
2388c88b1d6cSniklas {
2389c88b1d6cSniklas   unsigned int f1;
2390c88b1d6cSniklas 
2391c88b1d6cSniklas   f1 = op1->flags;
2392c88b1d6cSniklas 
2393c88b1d6cSniklas   if ((f1 & LOAD) == 0)
2394c074d1c9Sdrahn     return FALSE;
2395c88b1d6cSniklas 
2396c88b1d6cSniklas   /* If both SETS1 and SETSSP are set, that means a load to a special
2397c88b1d6cSniklas      register using postincrement addressing mode, which we don't care
2398c88b1d6cSniklas      about here.  */
2399c88b1d6cSniklas   if ((f1 & SETS1) != 0
2400c88b1d6cSniklas       && (f1 & SETSSP) == 0
2401c88b1d6cSniklas       && sh_insn_uses_reg (i2, op2, (i1 & 0x0f00) >> 8))
2402c074d1c9Sdrahn     return TRUE;
2403c88b1d6cSniklas 
2404c88b1d6cSniklas   if ((f1 & SETSR0) != 0
2405c88b1d6cSniklas       && sh_insn_uses_reg (i2, op2, 0))
2406c074d1c9Sdrahn     return TRUE;
2407c88b1d6cSniklas 
2408c88b1d6cSniklas   if ((f1 & SETSF1) != 0
2409c88b1d6cSniklas       && sh_insn_uses_freg (i2, op2, (i1 & 0x0f00) >> 8))
2410c074d1c9Sdrahn     return TRUE;
2411c88b1d6cSniklas 
2412c074d1c9Sdrahn   return FALSE;
2413c88b1d6cSniklas }
2414c88b1d6cSniklas 
24150c6d0228Sniklas /* Try to align loads and stores within a span of memory.  This is
24160c6d0228Sniklas    called by both the ELF and the COFF sh targets.  ABFD and SEC are
24170c6d0228Sniklas    the BFD and section we are examining.  CONTENTS is the contents of
24180c6d0228Sniklas    the section.  SWAP is the routine to call to swap two instructions.
24190c6d0228Sniklas    RELOCS is a pointer to the internal relocation information, to be
24200c6d0228Sniklas    passed to SWAP.  PLABEL is a pointer to the current label in a
24210c6d0228Sniklas    sorted list of labels; LABEL_END is the end of the list.  START and
24220c6d0228Sniklas    STOP are the range of memory to examine.  If a swap is made,
2423c074d1c9Sdrahn    *PSWAPPED is set to TRUE.  */
2424c88b1d6cSniklas 
2425b305b0f1Sespie #ifdef COFF_WITH_PE
2426b305b0f1Sespie static
2427b305b0f1Sespie #endif
2428c074d1c9Sdrahn bfd_boolean
_bfd_sh_align_load_span(abfd,sec,contents,swap,relocs,plabel,label_end,start,stop,pswapped)24290c6d0228Sniklas _bfd_sh_align_load_span (abfd, sec, contents, swap, relocs,
24300c6d0228Sniklas 			 plabel, label_end, start, stop, pswapped)
2431c88b1d6cSniklas      bfd *abfd;
2432c88b1d6cSniklas      asection *sec;
2433c88b1d6cSniklas      bfd_byte *contents;
2434c074d1c9Sdrahn      bfd_boolean (*swap) PARAMS ((bfd *, asection *, PTR, bfd_byte *, bfd_vma));
24350c6d0228Sniklas      PTR relocs;
24360c6d0228Sniklas      bfd_vma **plabel;
24370c6d0228Sniklas      bfd_vma *label_end;
24380c6d0228Sniklas      bfd_vma start;
24390c6d0228Sniklas      bfd_vma stop;
2440c074d1c9Sdrahn      bfd_boolean *pswapped;
2441c88b1d6cSniklas {
2442b305b0f1Sespie   int dsp = (abfd->arch_info->mach == bfd_mach_sh_dsp
2443b305b0f1Sespie 	     || abfd->arch_info->mach == bfd_mach_sh3_dsp);
24440c6d0228Sniklas   bfd_vma i;
2445c88b1d6cSniklas 
2446b305b0f1Sespie   /* The SH4 has a Harvard architecture, hence aligning loads is not
2447b305b0f1Sespie      desirable.  In fact, it is counter-productive, since it interferes
2448b305b0f1Sespie      with the schedules generated by the compiler.  */
2449b305b0f1Sespie   if (abfd->arch_info->mach == bfd_mach_sh4)
2450c074d1c9Sdrahn     return TRUE;
2451b305b0f1Sespie 
2452b305b0f1Sespie   /* If we are linking sh[3]-dsp code, swap the FPU instructions for DSP
2453b305b0f1Sespie      instructions.  */
2454b305b0f1Sespie   if (dsp)
2455b305b0f1Sespie     {
2456b305b0f1Sespie       sh_opcodes[0xf].minor_opcodes = sh_dsp_opcodef;
2457b305b0f1Sespie       sh_opcodes[0xf].count = sizeof sh_dsp_opcodef / sizeof sh_dsp_opcodef;
2458b305b0f1Sespie     }
2459b305b0f1Sespie 
2460c88b1d6cSniklas   /* Instructions should be aligned on 2 byte boundaries.  */
2461c88b1d6cSniklas   if ((start & 1) == 1)
2462c88b1d6cSniklas     ++start;
2463c88b1d6cSniklas 
2464c88b1d6cSniklas   /* Now look through the unaligned addresses.  */
2465c88b1d6cSniklas   i = start;
2466c88b1d6cSniklas   if ((i & 2) == 0)
2467c88b1d6cSniklas     i += 2;
2468c88b1d6cSniklas   for (; i < stop; i += 4)
2469c88b1d6cSniklas     {
2470c88b1d6cSniklas       unsigned int insn;
2471c88b1d6cSniklas       const struct sh_opcode *op;
2472c88b1d6cSniklas       unsigned int prev_insn = 0;
2473c88b1d6cSniklas       const struct sh_opcode *prev_op = NULL;
2474c88b1d6cSniklas 
2475c88b1d6cSniklas       insn = bfd_get_16 (abfd, contents + i);
2476c88b1d6cSniklas       op = sh_insn_info (insn);
2477c88b1d6cSniklas       if (op == NULL
2478c88b1d6cSniklas 	  || (op->flags & (LOAD | STORE)) == 0)
2479c88b1d6cSniklas 	continue;
2480c88b1d6cSniklas 
24810c6d0228Sniklas       /* This is a load or store which is not on a four byte boundary.  */
2482c88b1d6cSniklas 
24830c6d0228Sniklas       while (*plabel < label_end && **plabel < i)
24840c6d0228Sniklas 	++*plabel;
2485c88b1d6cSniklas 
2486c88b1d6cSniklas       if (i > start)
2487c88b1d6cSniklas 	{
2488c88b1d6cSniklas 	  prev_insn = bfd_get_16 (abfd, contents + i - 2);
2489b305b0f1Sespie 	  /* If INSN is the field b of a parallel processing insn, it is not
2490b305b0f1Sespie 	     a load / store after all.  Note that the test here might mistake
2491b305b0f1Sespie 	     the field_b of a pcopy insn for the starting code of a parallel
2492b305b0f1Sespie 	     processing insn; this might miss a swapping opportunity, but at
2493b305b0f1Sespie 	     least we're on the safe side.  */
2494b305b0f1Sespie 	  if (dsp && (prev_insn & 0xfc00) == 0xf800)
2495b305b0f1Sespie 	    continue;
2496b305b0f1Sespie 
2497b305b0f1Sespie 	  /* Check if prev_insn is actually the field b of a parallel
2498b305b0f1Sespie 	     processing insn.  Again, this can give a spurious match
2499b305b0f1Sespie 	     after a pcopy.  */
2500b305b0f1Sespie 	  if (dsp && i - 2 > start)
2501b305b0f1Sespie 	    {
2502b305b0f1Sespie 	      unsigned pprev_insn = bfd_get_16 (abfd, contents + i - 4);
2503b305b0f1Sespie 
2504b305b0f1Sespie 	      if ((pprev_insn & 0xfc00) == 0xf800)
2505b305b0f1Sespie 		prev_op = NULL;
2506b305b0f1Sespie 	      else
2507b305b0f1Sespie 		prev_op = sh_insn_info (prev_insn);
2508b305b0f1Sespie 	    }
2509b305b0f1Sespie 	  else
2510c88b1d6cSniklas 	    prev_op = sh_insn_info (prev_insn);
2511c88b1d6cSniklas 
2512c88b1d6cSniklas 	  /* If the load/store instruction is in a delay slot, we
2513c88b1d6cSniklas 	     can't swap.  */
2514c88b1d6cSniklas 	  if (prev_op == NULL
2515c88b1d6cSniklas 	      || (prev_op->flags & DELAY) != 0)
2516c88b1d6cSniklas 	    continue;
2517c88b1d6cSniklas 	}
2518c88b1d6cSniklas       if (i > start
25190c6d0228Sniklas 	  && (*plabel >= label_end || **plabel != i)
2520c88b1d6cSniklas 	  && prev_op != NULL
2521c88b1d6cSniklas 	  && (prev_op->flags & (LOAD | STORE)) == 0
2522c88b1d6cSniklas 	  && ! sh_insns_conflict (prev_insn, prev_op, insn, op))
2523c88b1d6cSniklas 	{
2524c074d1c9Sdrahn 	  bfd_boolean ok;
2525c88b1d6cSniklas 
2526c88b1d6cSniklas 	  /* The load/store instruction does not have a label, and
2527c88b1d6cSniklas 	     there is a previous instruction; PREV_INSN is not
2528c88b1d6cSniklas 	     itself a load/store instruction, and PREV_INSN and
2529c88b1d6cSniklas 	     INSN do not conflict.  */
2530c88b1d6cSniklas 
2531c074d1c9Sdrahn 	  ok = TRUE;
2532c88b1d6cSniklas 
2533c88b1d6cSniklas 	  if (i >= start + 4)
2534c88b1d6cSniklas 	    {
2535c88b1d6cSniklas 	      unsigned int prev2_insn;
2536c88b1d6cSniklas 	      const struct sh_opcode *prev2_op;
2537c88b1d6cSniklas 
2538c88b1d6cSniklas 	      prev2_insn = bfd_get_16 (abfd, contents + i - 4);
2539c88b1d6cSniklas 	      prev2_op = sh_insn_info (prev2_insn);
2540c88b1d6cSniklas 
2541c88b1d6cSniklas 	      /* If the instruction before PREV_INSN has a delay
2542c88b1d6cSniklas 		 slot--that is, PREV_INSN is in a delay slot--we
2543c88b1d6cSniklas 		 can not swap.  */
2544c88b1d6cSniklas 	      if (prev2_op == NULL
2545c88b1d6cSniklas 		  || (prev2_op->flags & DELAY) != 0)
2546c074d1c9Sdrahn 		ok = FALSE;
2547c88b1d6cSniklas 
2548c88b1d6cSniklas 	      /* If the instruction before PREV_INSN is a load,
2549c88b1d6cSniklas 		 and it sets a register which INSN uses, then
2550c88b1d6cSniklas 		 putting INSN immediately after PREV_INSN will
2551c88b1d6cSniklas 		 cause a pipeline bubble, so there is no point to
2552c88b1d6cSniklas 		 making the swap.  */
2553c88b1d6cSniklas 	      if (ok
2554c88b1d6cSniklas 		  && (prev2_op->flags & LOAD) != 0
2555c88b1d6cSniklas 		  && sh_load_use (prev2_insn, prev2_op, insn, op))
2556c074d1c9Sdrahn 		ok = FALSE;
2557c88b1d6cSniklas 	    }
2558c88b1d6cSniklas 
2559c88b1d6cSniklas 	  if (ok)
2560c88b1d6cSniklas 	    {
25610c6d0228Sniklas 	      if (! (*swap) (abfd, sec, relocs, contents, i - 2))
2562c074d1c9Sdrahn 		return FALSE;
2563c074d1c9Sdrahn 	      *pswapped = TRUE;
2564c88b1d6cSniklas 	      continue;
2565c88b1d6cSniklas 	    }
2566c88b1d6cSniklas 	}
2567c88b1d6cSniklas 
25680c6d0228Sniklas       while (*plabel < label_end && **plabel < i + 2)
25690c6d0228Sniklas 	++*plabel;
2570c88b1d6cSniklas 
2571c88b1d6cSniklas       if (i + 2 < stop
25720c6d0228Sniklas 	  && (*plabel >= label_end || **plabel != i + 2))
2573c88b1d6cSniklas 	{
2574c88b1d6cSniklas 	  unsigned int next_insn;
2575c88b1d6cSniklas 	  const struct sh_opcode *next_op;
2576c88b1d6cSniklas 
2577c88b1d6cSniklas 	  /* There is an instruction after the load/store
2578c88b1d6cSniklas 	     instruction, and it does not have a label.  */
2579c88b1d6cSniklas 	  next_insn = bfd_get_16 (abfd, contents + i + 2);
2580c88b1d6cSniklas 	  next_op = sh_insn_info (next_insn);
2581c88b1d6cSniklas 	  if (next_op != NULL
2582c88b1d6cSniklas 	      && (next_op->flags & (LOAD | STORE)) == 0
2583c88b1d6cSniklas 	      && ! sh_insns_conflict (insn, op, next_insn, next_op))
2584c88b1d6cSniklas 	    {
2585c074d1c9Sdrahn 	      bfd_boolean ok;
2586c88b1d6cSniklas 
2587c88b1d6cSniklas 	      /* NEXT_INSN is not itself a load/store instruction,
2588c88b1d6cSniklas 		 and it does not conflict with INSN.  */
2589c88b1d6cSniklas 
2590c074d1c9Sdrahn 	      ok = TRUE;
2591c88b1d6cSniklas 
2592c88b1d6cSniklas 	      /* If PREV_INSN is a load, and it sets a register
2593c88b1d6cSniklas 		 which NEXT_INSN uses, then putting NEXT_INSN
2594c88b1d6cSniklas 		 immediately after PREV_INSN will cause a pipeline
2595c88b1d6cSniklas 		 bubble, so there is no reason to make this swap.  */
2596c88b1d6cSniklas 	      if (prev_op != NULL
2597c88b1d6cSniklas 		  && (prev_op->flags & LOAD) != 0
2598c88b1d6cSniklas 		  && sh_load_use (prev_insn, prev_op, next_insn, next_op))
2599c074d1c9Sdrahn 		ok = FALSE;
2600c88b1d6cSniklas 
2601c88b1d6cSniklas 	      /* If INSN is a load, and it sets a register which
2602c88b1d6cSniklas 		 the insn after NEXT_INSN uses, then doing the
2603c88b1d6cSniklas 		 swap will cause a pipeline bubble, so there is no
2604c88b1d6cSniklas 		 reason to make the swap.  However, if the insn
2605c88b1d6cSniklas 		 after NEXT_INSN is itself a load or store
2606c88b1d6cSniklas 		 instruction, then it is misaligned, so
2607c88b1d6cSniklas 		 optimistically hope that it will be swapped
2608c88b1d6cSniklas 		 itself, and just live with the pipeline bubble if
2609c88b1d6cSniklas 		 it isn't.  */
2610c88b1d6cSniklas 	      if (ok
2611c88b1d6cSniklas 		  && i + 4 < stop
2612c88b1d6cSniklas 		  && (op->flags & LOAD) != 0)
2613c88b1d6cSniklas 		{
2614c88b1d6cSniklas 		  unsigned int next2_insn;
2615c88b1d6cSniklas 		  const struct sh_opcode *next2_op;
2616c88b1d6cSniklas 
2617c88b1d6cSniklas 		  next2_insn = bfd_get_16 (abfd, contents + i + 4);
2618c88b1d6cSniklas 		  next2_op = sh_insn_info (next2_insn);
2619c88b1d6cSniklas 		  if ((next2_op->flags & (LOAD | STORE)) == 0
2620c88b1d6cSniklas 		      && sh_load_use (insn, op, next2_insn, next2_op))
2621c074d1c9Sdrahn 		    ok = FALSE;
2622c88b1d6cSniklas 		}
2623c88b1d6cSniklas 
2624c88b1d6cSniklas 	      if (ok)
2625c88b1d6cSniklas 		{
26260c6d0228Sniklas 		  if (! (*swap) (abfd, sec, relocs, contents, i))
2627c074d1c9Sdrahn 		    return FALSE;
2628c074d1c9Sdrahn 		  *pswapped = TRUE;
2629c88b1d6cSniklas 		  continue;
2630c88b1d6cSniklas 		}
2631c88b1d6cSniklas 	    }
2632c88b1d6cSniklas 	}
2633c88b1d6cSniklas     }
26340c6d0228Sniklas 
2635c074d1c9Sdrahn   return TRUE;
26360c6d0228Sniklas }
2637b305b0f1Sespie #endif /* not COFF_IMAGE_WITH_PE */
26380c6d0228Sniklas 
26390c6d0228Sniklas /* Look for loads and stores which we can align to four byte
26400c6d0228Sniklas    boundaries.  See the longer comment above sh_relax_section for why
26410c6d0228Sniklas    this is desirable.  This sets *PSWAPPED if some instruction was
26420c6d0228Sniklas    swapped.  */
26430c6d0228Sniklas 
2644c074d1c9Sdrahn static bfd_boolean
sh_align_loads(abfd,sec,internal_relocs,contents,pswapped)26450c6d0228Sniklas sh_align_loads (abfd, sec, internal_relocs, contents, pswapped)
26460c6d0228Sniklas      bfd *abfd;
26470c6d0228Sniklas      asection *sec;
26480c6d0228Sniklas      struct internal_reloc *internal_relocs;
26490c6d0228Sniklas      bfd_byte *contents;
2650c074d1c9Sdrahn      bfd_boolean *pswapped;
26510c6d0228Sniklas {
26520c6d0228Sniklas   struct internal_reloc *irel, *irelend;
26530c6d0228Sniklas   bfd_vma *labels = NULL;
26540c6d0228Sniklas   bfd_vma *label, *label_end;
2655c074d1c9Sdrahn   bfd_size_type amt;
26560c6d0228Sniklas 
2657c074d1c9Sdrahn   *pswapped = FALSE;
26580c6d0228Sniklas 
26590c6d0228Sniklas   irelend = internal_relocs + sec->reloc_count;
26600c6d0228Sniklas 
26610c6d0228Sniklas   /* Get all the addresses with labels on them.  */
2662c074d1c9Sdrahn   amt = (bfd_size_type) sec->reloc_count * sizeof (bfd_vma);
2663c074d1c9Sdrahn   labels = (bfd_vma *) bfd_malloc (amt);
26640c6d0228Sniklas   if (labels == NULL)
26650c6d0228Sniklas     goto error_return;
26660c6d0228Sniklas   label_end = labels;
26670c6d0228Sniklas   for (irel = internal_relocs; irel < irelend; irel++)
26680c6d0228Sniklas     {
26690c6d0228Sniklas       if (irel->r_type == R_SH_LABEL)
26700c6d0228Sniklas 	{
26710c6d0228Sniklas 	  *label_end = irel->r_vaddr - sec->vma;
26720c6d0228Sniklas 	  ++label_end;
26730c6d0228Sniklas 	}
26740c6d0228Sniklas     }
26750c6d0228Sniklas 
26760c6d0228Sniklas   /* Note that the assembler currently always outputs relocs in
26770c6d0228Sniklas      address order.  If that ever changes, this code will need to sort
26780c6d0228Sniklas      the label values and the relocs.  */
26790c6d0228Sniklas 
26800c6d0228Sniklas   label = labels;
26810c6d0228Sniklas 
26820c6d0228Sniklas   for (irel = internal_relocs; irel < irelend; irel++)
26830c6d0228Sniklas     {
26840c6d0228Sniklas       bfd_vma start, stop;
26850c6d0228Sniklas 
26860c6d0228Sniklas       if (irel->r_type != R_SH_CODE)
26870c6d0228Sniklas 	continue;
26880c6d0228Sniklas 
26890c6d0228Sniklas       start = irel->r_vaddr - sec->vma;
26900c6d0228Sniklas 
26910c6d0228Sniklas       for (irel++; irel < irelend; irel++)
26920c6d0228Sniklas 	if (irel->r_type == R_SH_DATA)
26930c6d0228Sniklas 	  break;
26940c6d0228Sniklas       if (irel < irelend)
26950c6d0228Sniklas 	stop = irel->r_vaddr - sec->vma;
26960c6d0228Sniklas       else
26970c6d0228Sniklas 	stop = sec->_cooked_size;
26980c6d0228Sniklas 
26990c6d0228Sniklas       if (! _bfd_sh_align_load_span (abfd, sec, contents, sh_swap_insns,
27000c6d0228Sniklas 				     (PTR) internal_relocs, &label,
27010c6d0228Sniklas 				     label_end, start, stop, pswapped))
27020c6d0228Sniklas 	goto error_return;
2703c88b1d6cSniklas     }
2704c88b1d6cSniklas 
2705c88b1d6cSniklas   free (labels);
2706c88b1d6cSniklas 
2707c074d1c9Sdrahn   return TRUE;
2708c88b1d6cSniklas 
2709c88b1d6cSniklas  error_return:
2710c88b1d6cSniklas   if (labels != NULL)
2711c88b1d6cSniklas     free (labels);
2712c074d1c9Sdrahn   return FALSE;
2713c88b1d6cSniklas }
2714c88b1d6cSniklas 
2715c88b1d6cSniklas /* Swap two SH instructions.  */
2716c88b1d6cSniklas 
2717c074d1c9Sdrahn static bfd_boolean
sh_swap_insns(abfd,sec,relocs,contents,addr)27180c6d0228Sniklas sh_swap_insns (abfd, sec, relocs, contents, addr)
2719c88b1d6cSniklas      bfd *abfd;
2720c88b1d6cSniklas      asection *sec;
27210c6d0228Sniklas      PTR relocs;
2722c88b1d6cSniklas      bfd_byte *contents;
2723c88b1d6cSniklas      bfd_vma addr;
2724c88b1d6cSniklas {
27250c6d0228Sniklas   struct internal_reloc *internal_relocs = (struct internal_reloc *) relocs;
2726c88b1d6cSniklas   unsigned short i1, i2;
2727c88b1d6cSniklas   struct internal_reloc *irel, *irelend;
2728c88b1d6cSniklas 
2729c88b1d6cSniklas   /* Swap the instructions themselves.  */
2730c88b1d6cSniklas   i1 = bfd_get_16 (abfd, contents + addr);
2731c88b1d6cSniklas   i2 = bfd_get_16 (abfd, contents + addr + 2);
2732c074d1c9Sdrahn   bfd_put_16 (abfd, (bfd_vma) i2, contents + addr);
2733c074d1c9Sdrahn   bfd_put_16 (abfd, (bfd_vma) i1, contents + addr + 2);
2734c88b1d6cSniklas 
2735c88b1d6cSniklas   /* Adjust all reloc addresses.  */
2736c88b1d6cSniklas   irelend = internal_relocs + sec->reloc_count;
2737c88b1d6cSniklas   for (irel = internal_relocs; irel < irelend; irel++)
2738c88b1d6cSniklas     {
2739c88b1d6cSniklas       int type, add;
2740c88b1d6cSniklas 
2741c88b1d6cSniklas       /* There are a few special types of relocs that we don't want to
2742c88b1d6cSniklas          adjust.  These relocs do not apply to the instruction itself,
2743c88b1d6cSniklas          but are only associated with the address.  */
2744c88b1d6cSniklas       type = irel->r_type;
2745c88b1d6cSniklas       if (type == R_SH_ALIGN
2746c88b1d6cSniklas 	  || type == R_SH_CODE
2747c88b1d6cSniklas 	  || type == R_SH_DATA
2748c88b1d6cSniklas 	  || type == R_SH_LABEL)
2749c88b1d6cSniklas 	continue;
2750c88b1d6cSniklas 
2751c88b1d6cSniklas       /* If an R_SH_USES reloc points to one of the addresses being
2752c88b1d6cSniklas          swapped, we must adjust it.  It would be incorrect to do this
2753c88b1d6cSniklas          for a jump, though, since we want to execute both
2754c88b1d6cSniklas          instructions after the jump.  (We have avoided swapping
2755c88b1d6cSniklas          around a label, so the jump will not wind up executing an
2756c88b1d6cSniklas          instruction it shouldn't).  */
2757c88b1d6cSniklas       if (type == R_SH_USES)
2758c88b1d6cSniklas 	{
2759c88b1d6cSniklas 	  bfd_vma off;
2760c88b1d6cSniklas 
2761c88b1d6cSniklas 	  off = irel->r_vaddr - sec->vma + 4 + irel->r_offset;
2762c88b1d6cSniklas 	  if (off == addr)
2763c88b1d6cSniklas 	    irel->r_offset += 2;
2764c88b1d6cSniklas 	  else if (off == addr + 2)
2765c88b1d6cSniklas 	    irel->r_offset -= 2;
2766c88b1d6cSniklas 	}
2767c88b1d6cSniklas 
2768c88b1d6cSniklas       if (irel->r_vaddr - sec->vma == addr)
2769c88b1d6cSniklas 	{
2770c88b1d6cSniklas 	  irel->r_vaddr += 2;
2771c88b1d6cSniklas 	  add = -2;
2772c88b1d6cSniklas 	}
2773c88b1d6cSniklas       else if (irel->r_vaddr - sec->vma == addr + 2)
2774c88b1d6cSniklas 	{
2775c88b1d6cSniklas 	  irel->r_vaddr -= 2;
2776c88b1d6cSniklas 	  add = 2;
2777c88b1d6cSniklas 	}
2778c88b1d6cSniklas       else
2779c88b1d6cSniklas 	add = 0;
2780c88b1d6cSniklas 
2781c88b1d6cSniklas       if (add != 0)
2782c88b1d6cSniklas 	{
2783c88b1d6cSniklas 	  bfd_byte *loc;
2784c88b1d6cSniklas 	  unsigned short insn, oinsn;
2785c074d1c9Sdrahn 	  bfd_boolean overflow;
2786c88b1d6cSniklas 
2787c88b1d6cSniklas 	  loc = contents + irel->r_vaddr - sec->vma;
2788c074d1c9Sdrahn 	  overflow = FALSE;
2789c88b1d6cSniklas 	  switch (type)
2790c88b1d6cSniklas 	    {
2791c88b1d6cSniklas 	    default:
2792c88b1d6cSniklas 	      break;
2793c88b1d6cSniklas 
2794c88b1d6cSniklas 	    case R_SH_PCDISP8BY2:
2795c88b1d6cSniklas 	    case R_SH_PCRELIMM8BY2:
2796c88b1d6cSniklas 	      insn = bfd_get_16 (abfd, loc);
2797c88b1d6cSniklas 	      oinsn = insn;
2798c88b1d6cSniklas 	      insn += add / 2;
2799c88b1d6cSniklas 	      if ((oinsn & 0xff00) != (insn & 0xff00))
2800c074d1c9Sdrahn 		overflow = TRUE;
2801c074d1c9Sdrahn 	      bfd_put_16 (abfd, (bfd_vma) insn, loc);
2802c88b1d6cSniklas 	      break;
2803c88b1d6cSniklas 
2804c88b1d6cSniklas 	    case R_SH_PCDISP:
2805c88b1d6cSniklas 	      insn = bfd_get_16 (abfd, loc);
2806c88b1d6cSniklas 	      oinsn = insn;
2807c88b1d6cSniklas 	      insn += add / 2;
2808c88b1d6cSniklas 	      if ((oinsn & 0xf000) != (insn & 0xf000))
2809c074d1c9Sdrahn 		overflow = TRUE;
2810c074d1c9Sdrahn 	      bfd_put_16 (abfd, (bfd_vma) insn, loc);
2811c88b1d6cSniklas 	      break;
2812c88b1d6cSniklas 
2813c88b1d6cSniklas 	    case R_SH_PCRELIMM8BY4:
2814c88b1d6cSniklas 	      /* This reloc ignores the least significant 3 bits of
2815c88b1d6cSniklas                  the program counter before adding in the offset.
2816c88b1d6cSniklas                  This means that if ADDR is at an even address, the
2817c88b1d6cSniklas                  swap will not affect the offset.  If ADDR is an at an
2818c88b1d6cSniklas                  odd address, then the instruction will be crossing a
2819c88b1d6cSniklas                  four byte boundary, and must be adjusted.  */
2820c88b1d6cSniklas 	      if ((addr & 3) != 0)
2821c88b1d6cSniklas 		{
2822c88b1d6cSniklas 		  insn = bfd_get_16 (abfd, loc);
2823c88b1d6cSniklas 		  oinsn = insn;
2824c88b1d6cSniklas 		  insn += add / 2;
2825c88b1d6cSniklas 		  if ((oinsn & 0xff00) != (insn & 0xff00))
2826c074d1c9Sdrahn 		    overflow = TRUE;
2827c074d1c9Sdrahn 		  bfd_put_16 (abfd, (bfd_vma) insn, loc);
2828c88b1d6cSniklas 		}
2829c88b1d6cSniklas 
2830c88b1d6cSniklas 	      break;
2831c88b1d6cSniklas 	    }
2832c88b1d6cSniklas 
2833c88b1d6cSniklas 	  if (overflow)
2834c88b1d6cSniklas 	    {
2835c88b1d6cSniklas 	      ((*_bfd_error_handler)
2836c88b1d6cSniklas 	       ("%s: 0x%lx: fatal: reloc overflow while relaxing",
2837c074d1c9Sdrahn 		bfd_archive_filename (abfd), (unsigned long) irel->r_vaddr));
2838c88b1d6cSniklas 	      bfd_set_error (bfd_error_bad_value);
2839c074d1c9Sdrahn 	      return FALSE;
2840c88b1d6cSniklas 	    }
2841c88b1d6cSniklas 	}
2842c88b1d6cSniklas     }
2843c88b1d6cSniklas 
2844c074d1c9Sdrahn   return TRUE;
2845c88b1d6cSniklas }
2846c88b1d6cSniklas 
28472159047fSniklas /* This is a modification of _bfd_coff_generic_relocate_section, which
28482159047fSniklas    will handle SH relaxing.  */
28492159047fSniklas 
2850c074d1c9Sdrahn static bfd_boolean
sh_relocate_section(output_bfd,info,input_bfd,input_section,contents,relocs,syms,sections)28512159047fSniklas sh_relocate_section (output_bfd, info, input_bfd, input_section, contents,
28522159047fSniklas 		     relocs, syms, sections)
2853b305b0f1Sespie      bfd *output_bfd ATTRIBUTE_UNUSED;
28542159047fSniklas      struct bfd_link_info *info;
28552159047fSniklas      bfd *input_bfd;
28562159047fSniklas      asection *input_section;
28572159047fSniklas      bfd_byte *contents;
28582159047fSniklas      struct internal_reloc *relocs;
28592159047fSniklas      struct internal_syment *syms;
28602159047fSniklas      asection **sections;
28612159047fSniklas {
28622159047fSniklas   struct internal_reloc *rel;
28632159047fSniklas   struct internal_reloc *relend;
28642159047fSniklas 
28652159047fSniklas   rel = relocs;
28662159047fSniklas   relend = rel + input_section->reloc_count;
28672159047fSniklas   for (; rel < relend; rel++)
28682159047fSniklas     {
28692159047fSniklas       long symndx;
28702159047fSniklas       struct coff_link_hash_entry *h;
28712159047fSniklas       struct internal_syment *sym;
28722159047fSniklas       bfd_vma addend;
28732159047fSniklas       bfd_vma val;
28742159047fSniklas       reloc_howto_type *howto;
28752159047fSniklas       bfd_reloc_status_type rstat;
28762159047fSniklas 
28772159047fSniklas       /* Almost all relocs have to do with relaxing.  If any work must
28782159047fSniklas          be done for them, it has been done in sh_relax_section.  */
28792159047fSniklas       if (rel->r_type != R_SH_IMM32
2880b305b0f1Sespie #ifdef COFF_WITH_PE
2881b305b0f1Sespie 	  && rel->r_type != R_SH_IMM32CE
2882b305b0f1Sespie 	  && rel->r_type != R_SH_IMAGEBASE
2883b305b0f1Sespie #endif
28842159047fSniklas 	  && rel->r_type != R_SH_PCDISP)
28852159047fSniklas 	continue;
28862159047fSniklas 
28872159047fSniklas       symndx = rel->r_symndx;
28882159047fSniklas 
28892159047fSniklas       if (symndx == -1)
28902159047fSniklas 	{
28912159047fSniklas 	  h = NULL;
28922159047fSniklas 	  sym = NULL;
28932159047fSniklas 	}
28942159047fSniklas       else
28952159047fSniklas 	{
2896b305b0f1Sespie 	  if (symndx < 0
2897b305b0f1Sespie 	      || (unsigned long) symndx >= obj_raw_syment_count (input_bfd))
2898e93f7393Sniklas 	    {
2899e93f7393Sniklas 	      (*_bfd_error_handler)
2900e93f7393Sniklas 		("%s: illegal symbol index %ld in relocs",
2901c074d1c9Sdrahn 		 bfd_archive_filename (input_bfd), symndx);
2902e93f7393Sniklas 	      bfd_set_error (bfd_error_bad_value);
2903c074d1c9Sdrahn 	      return FALSE;
2904e93f7393Sniklas 	    }
29052159047fSniklas 	  h = obj_coff_sym_hashes (input_bfd)[symndx];
29062159047fSniklas 	  sym = syms + symndx;
29072159047fSniklas 	}
29082159047fSniklas 
29092159047fSniklas       if (sym != NULL && sym->n_scnum != 0)
29102159047fSniklas 	addend = - sym->n_value;
29112159047fSniklas       else
29122159047fSniklas 	addend = 0;
29132159047fSniklas 
29142159047fSniklas       if (rel->r_type == R_SH_PCDISP)
29152159047fSniklas 	addend -= 4;
29162159047fSniklas 
29172159047fSniklas       if (rel->r_type >= SH_COFF_HOWTO_COUNT)
29182159047fSniklas 	howto = NULL;
29192159047fSniklas       else
29202159047fSniklas 	howto = &sh_coff_howtos[rel->r_type];
29212159047fSniklas 
29222159047fSniklas       if (howto == NULL)
29232159047fSniklas 	{
29242159047fSniklas 	  bfd_set_error (bfd_error_bad_value);
2925c074d1c9Sdrahn 	  return FALSE;
29262159047fSniklas 	}
29272159047fSniklas 
2928b305b0f1Sespie #ifdef COFF_WITH_PE
2929b305b0f1Sespie       if (rel->r_type == R_SH_IMAGEBASE)
2930b305b0f1Sespie 	addend -= pe_data (input_section->output_section->owner)->pe_opthdr.ImageBase;
2931b305b0f1Sespie #endif
2932b305b0f1Sespie 
29332159047fSniklas       val = 0;
29342159047fSniklas 
29352159047fSniklas       if (h == NULL)
29362159047fSniklas 	{
29372159047fSniklas 	  asection *sec;
29382159047fSniklas 
29392159047fSniklas 	  /* There is nothing to do for an internal PCDISP reloc.  */
29402159047fSniklas 	  if (rel->r_type == R_SH_PCDISP)
29412159047fSniklas 	    continue;
29422159047fSniklas 
29432159047fSniklas 	  if (symndx == -1)
29442159047fSniklas 	    {
29452159047fSniklas 	      sec = bfd_abs_section_ptr;
29462159047fSniklas 	      val = 0;
29472159047fSniklas 	    }
29482159047fSniklas 	  else
29492159047fSniklas 	    {
29502159047fSniklas 	      sec = sections[symndx];
29512159047fSniklas               val = (sec->output_section->vma
29522159047fSniklas 		     + sec->output_offset
29532159047fSniklas 		     + sym->n_value
29542159047fSniklas 		     - sec->vma);
29552159047fSniklas 	    }
29562159047fSniklas 	}
29572159047fSniklas       else
29582159047fSniklas 	{
29592159047fSniklas 	  if (h->root.type == bfd_link_hash_defined
29602159047fSniklas 	      || h->root.type == bfd_link_hash_defweak)
29612159047fSniklas 	    {
29622159047fSniklas 	      asection *sec;
29632159047fSniklas 
29642159047fSniklas 	      sec = h->root.u.def.section;
29652159047fSniklas 	      val = (h->root.u.def.value
29662159047fSniklas 		     + sec->output_section->vma
29672159047fSniklas 		     + sec->output_offset);
29682159047fSniklas 	    }
2969*007c2a45Smiod 	  else if (! info->relocatable)
29702159047fSniklas 	    {
29712159047fSniklas 	      if (! ((*info->callbacks->undefined_symbol)
29722159047fSniklas 		     (info, h->root.root.string, input_bfd, input_section,
2973c074d1c9Sdrahn 		      rel->r_vaddr - input_section->vma, TRUE)))
2974c074d1c9Sdrahn 		return FALSE;
29752159047fSniklas 	    }
29762159047fSniklas 	}
29772159047fSniklas 
29782159047fSniklas       rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
29792159047fSniklas 					contents,
29802159047fSniklas 					rel->r_vaddr - input_section->vma,
29812159047fSniklas 					val, addend);
29822159047fSniklas 
29832159047fSniklas       switch (rstat)
29842159047fSniklas 	{
29852159047fSniklas 	default:
29862159047fSniklas 	  abort ();
29872159047fSniklas 	case bfd_reloc_ok:
29882159047fSniklas 	  break;
29892159047fSniklas 	case bfd_reloc_overflow:
29902159047fSniklas 	  {
29912159047fSniklas 	    const char *name;
29922159047fSniklas 	    char buf[SYMNMLEN + 1];
29932159047fSniklas 
29942159047fSniklas 	    if (symndx == -1)
29952159047fSniklas 	      name = "*ABS*";
29962159047fSniklas 	    else if (h != NULL)
29972159047fSniklas 	      name = h->root.root.string;
29982159047fSniklas 	    else if (sym->_n._n_n._n_zeroes == 0
29992159047fSniklas 		     && sym->_n._n_n._n_offset != 0)
30002159047fSniklas 	      name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
30012159047fSniklas 	    else
30022159047fSniklas 	      {
30032159047fSniklas  		strncpy (buf, sym->_n._n_name, SYMNMLEN);
30042159047fSniklas 		buf[SYMNMLEN] = '\0';
30052159047fSniklas 		name = buf;
30062159047fSniklas 	      }
30072159047fSniklas 
30082159047fSniklas 	    if (! ((*info->callbacks->reloc_overflow)
30092159047fSniklas 		   (info, name, howto->name, (bfd_vma) 0, input_bfd,
30102159047fSniklas 		    input_section, rel->r_vaddr - input_section->vma)))
3011c074d1c9Sdrahn 	      return FALSE;
30122159047fSniklas 	  }
30132159047fSniklas 	}
30142159047fSniklas     }
30152159047fSniklas 
3016c074d1c9Sdrahn   return TRUE;
30172159047fSniklas }
30182159047fSniklas 
30192159047fSniklas /* This is a version of bfd_generic_get_relocated_section_contents
30202159047fSniklas    which uses sh_relocate_section.  */
30212159047fSniklas 
30222159047fSniklas static bfd_byte *
sh_coff_get_relocated_section_contents(output_bfd,link_info,link_order,data,relocatable,symbols)30232159047fSniklas sh_coff_get_relocated_section_contents (output_bfd, link_info, link_order,
3024*007c2a45Smiod 					data, relocatable, symbols)
30252159047fSniklas      bfd *output_bfd;
30262159047fSniklas      struct bfd_link_info *link_info;
30272159047fSniklas      struct bfd_link_order *link_order;
30282159047fSniklas      bfd_byte *data;
3029*007c2a45Smiod      bfd_boolean relocatable;
30302159047fSniklas      asymbol **symbols;
30312159047fSniklas {
30322159047fSniklas   asection *input_section = link_order->u.indirect.section;
30332159047fSniklas   bfd *input_bfd = input_section->owner;
30342159047fSniklas   asection **sections = NULL;
30352159047fSniklas   struct internal_reloc *internal_relocs = NULL;
30362159047fSniklas   struct internal_syment *internal_syms = NULL;
30372159047fSniklas 
30382159047fSniklas   /* We only need to handle the case of relaxing, or of having a
30392159047fSniklas      particular set of section contents, specially.  */
3040*007c2a45Smiod   if (relocatable
30412159047fSniklas       || coff_section_data (input_bfd, input_section) == NULL
30422159047fSniklas       || coff_section_data (input_bfd, input_section)->contents == NULL)
30432159047fSniklas     return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
30442159047fSniklas 						       link_order, data,
3045*007c2a45Smiod 						       relocatable,
30462159047fSniklas 						       symbols);
30472159047fSniklas 
30482159047fSniklas   memcpy (data, coff_section_data (input_bfd, input_section)->contents,
3049c074d1c9Sdrahn 	  (size_t) input_section->_raw_size);
30502159047fSniklas 
30512159047fSniklas   if ((input_section->flags & SEC_RELOC) != 0
30522159047fSniklas       && input_section->reloc_count > 0)
30532159047fSniklas     {
30542159047fSniklas       bfd_size_type symesz = bfd_coff_symesz (input_bfd);
30552159047fSniklas       bfd_byte *esym, *esymend;
30562159047fSniklas       struct internal_syment *isymp;
30572159047fSniklas       asection **secpp;
3058c074d1c9Sdrahn       bfd_size_type amt;
30592159047fSniklas 
30602159047fSniklas       if (! _bfd_coff_get_external_symbols (input_bfd))
30612159047fSniklas 	goto error_return;
30622159047fSniklas 
30632159047fSniklas       internal_relocs = (_bfd_coff_read_internal_relocs
3064c074d1c9Sdrahn 			 (input_bfd, input_section, FALSE, (bfd_byte *) NULL,
3065c074d1c9Sdrahn 			  FALSE, (struct internal_reloc *) NULL));
30662159047fSniklas       if (internal_relocs == NULL)
30672159047fSniklas 	goto error_return;
30682159047fSniklas 
3069c074d1c9Sdrahn       amt = obj_raw_syment_count (input_bfd);
3070c074d1c9Sdrahn       amt *= sizeof (struct internal_syment);
3071c074d1c9Sdrahn       internal_syms = (struct internal_syment *) bfd_malloc (amt);
30722159047fSniklas       if (internal_syms == NULL)
30732159047fSniklas 	goto error_return;
30742159047fSniklas 
3075c074d1c9Sdrahn       amt = obj_raw_syment_count (input_bfd);
3076c074d1c9Sdrahn       amt *= sizeof (asection *);
3077c074d1c9Sdrahn       sections = (asection **) bfd_malloc (amt);
30782159047fSniklas       if (sections == NULL)
30792159047fSniklas 	goto error_return;
30802159047fSniklas 
30812159047fSniklas       isymp = internal_syms;
30822159047fSniklas       secpp = sections;
30832159047fSniklas       esym = (bfd_byte *) obj_coff_external_syms (input_bfd);
30842159047fSniklas       esymend = esym + obj_raw_syment_count (input_bfd) * symesz;
30852159047fSniklas       while (esym < esymend)
30862159047fSniklas 	{
30872159047fSniklas 	  bfd_coff_swap_sym_in (input_bfd, (PTR) esym, (PTR) isymp);
30882159047fSniklas 
30892159047fSniklas 	  if (isymp->n_scnum != 0)
30902159047fSniklas 	    *secpp = coff_section_from_bfd_index (input_bfd, isymp->n_scnum);
30912159047fSniklas 	  else
30922159047fSniklas 	    {
30932159047fSniklas 	      if (isymp->n_value == 0)
30942159047fSniklas 		*secpp = bfd_und_section_ptr;
30952159047fSniklas 	      else
30962159047fSniklas 		*secpp = bfd_com_section_ptr;
30972159047fSniklas 	    }
30982159047fSniklas 
30992159047fSniklas 	  esym += (isymp->n_numaux + 1) * symesz;
31002159047fSniklas 	  secpp += isymp->n_numaux + 1;
31012159047fSniklas 	  isymp += isymp->n_numaux + 1;
31022159047fSniklas 	}
31032159047fSniklas 
31042159047fSniklas       if (! sh_relocate_section (output_bfd, link_info, input_bfd,
31052159047fSniklas 				 input_section, data, internal_relocs,
31062159047fSniklas 				 internal_syms, sections))
31072159047fSniklas 	goto error_return;
31082159047fSniklas 
31092159047fSniklas       free (sections);
31102159047fSniklas       sections = NULL;
31112159047fSniklas       free (internal_syms);
31122159047fSniklas       internal_syms = NULL;
31132159047fSniklas       free (internal_relocs);
31142159047fSniklas       internal_relocs = NULL;
31152159047fSniklas     }
31162159047fSniklas 
31172159047fSniklas   return data;
31182159047fSniklas 
31192159047fSniklas  error_return:
31202159047fSniklas   if (internal_relocs != NULL)
31212159047fSniklas     free (internal_relocs);
31222159047fSniklas   if (internal_syms != NULL)
31232159047fSniklas     free (internal_syms);
31242159047fSniklas   if (sections != NULL)
31252159047fSniklas     free (sections);
31262159047fSniklas   return NULL;
31272159047fSniklas }
31282159047fSniklas 
31292159047fSniklas /* The target vectors.  */
31302159047fSniklas 
3131b305b0f1Sespie #ifndef TARGET_SHL_SYM
3132*007c2a45Smiod CREATE_BIG_COFF_TARGET_VEC (shcoff_vec, "coff-sh", BFD_IS_RELAXABLE, 0, '_', NULL, COFF_SWAP_TABLE)
3133b305b0f1Sespie #endif
3134b305b0f1Sespie 
3135b305b0f1Sespie #ifdef TARGET_SHL_SYM
3136b305b0f1Sespie #define TARGET_SYM TARGET_SHL_SYM
3137b305b0f1Sespie #else
3138b305b0f1Sespie #define TARGET_SYM shlcoff_vec
3139b305b0f1Sespie #endif
3140b305b0f1Sespie 
3141b305b0f1Sespie #ifndef TARGET_SHL_NAME
3142b305b0f1Sespie #define TARGET_SHL_NAME "coff-shl"
3143b305b0f1Sespie #endif
3144b305b0f1Sespie 
3145b305b0f1Sespie #ifdef COFF_WITH_PE
3146b305b0f1Sespie CREATE_LITTLE_COFF_TARGET_VEC (TARGET_SYM, TARGET_SHL_NAME, BFD_IS_RELAXABLE,
3147*007c2a45Smiod 			       SEC_CODE | SEC_DATA, '_', NULL, COFF_SWAP_TABLE);
3148b305b0f1Sespie #else
3149b305b0f1Sespie CREATE_LITTLE_COFF_TARGET_VEC (TARGET_SYM, TARGET_SHL_NAME, BFD_IS_RELAXABLE,
3150*007c2a45Smiod 			       0, '_', NULL, COFF_SWAP_TABLE)
3151b305b0f1Sespie #endif
3152b305b0f1Sespie 
3153b305b0f1Sespie #ifndef TARGET_SHL_SYM
3154c074d1c9Sdrahn static const bfd_target * coff_small_object_p PARAMS ((bfd *));
3155c074d1c9Sdrahn static bfd_boolean coff_small_new_section_hook PARAMS ((bfd *, asection *));
3156b305b0f1Sespie /* Some people want versions of the SH COFF target which do not align
3157b305b0f1Sespie    to 16 byte boundaries.  We implement that by adding a couple of new
3158b305b0f1Sespie    target vectors.  These are just like the ones above, but they
3159b305b0f1Sespie    change the default section alignment.  To generate them in the
3160b305b0f1Sespie    assembler, use -small.  To use them in the linker, use -b
3161b305b0f1Sespie    coff-sh{l}-small and -oformat coff-sh{l}-small.
3162b305b0f1Sespie 
3163b305b0f1Sespie    Yes, this is a horrible hack.  A general solution for setting
3164b305b0f1Sespie    section alignment in COFF is rather complex.  ELF handles this
3165b305b0f1Sespie    correctly.  */
3166b305b0f1Sespie 
3167b305b0f1Sespie /* Only recognize the small versions if the target was not defaulted.
3168b305b0f1Sespie    Otherwise we won't recognize the non default endianness.  */
3169b305b0f1Sespie 
3170b305b0f1Sespie static const bfd_target *
coff_small_object_p(abfd)3171b305b0f1Sespie coff_small_object_p (abfd)
3172b305b0f1Sespie      bfd *abfd;
31732159047fSniklas {
3174b305b0f1Sespie   if (abfd->target_defaulted)
3175b305b0f1Sespie     {
3176b305b0f1Sespie       bfd_set_error (bfd_error_wrong_format);
3177b305b0f1Sespie       return NULL;
3178b305b0f1Sespie     }
3179b305b0f1Sespie   return coff_object_p (abfd);
3180b305b0f1Sespie }
3181b305b0f1Sespie 
3182b305b0f1Sespie /* Set the section alignment for the small versions.  */
3183b305b0f1Sespie 
3184c074d1c9Sdrahn static bfd_boolean
coff_small_new_section_hook(abfd,section)3185b305b0f1Sespie coff_small_new_section_hook (abfd, section)
3186b305b0f1Sespie      bfd *abfd;
3187b305b0f1Sespie      asection *section;
3188b305b0f1Sespie {
3189b305b0f1Sespie   if (! coff_new_section_hook (abfd, section))
3190c074d1c9Sdrahn     return FALSE;
3191b305b0f1Sespie 
3192b305b0f1Sespie   /* We must align to at least a four byte boundary, because longword
3193b305b0f1Sespie      accesses must be on a four byte boundary.  */
3194b305b0f1Sespie   if (section->alignment_power == COFF_DEFAULT_SECTION_ALIGNMENT_POWER)
3195b305b0f1Sespie     section->alignment_power = 2;
3196b305b0f1Sespie 
3197c074d1c9Sdrahn   return TRUE;
3198b305b0f1Sespie }
3199b305b0f1Sespie 
3200b305b0f1Sespie /* This is copied from bfd_coff_std_swap_table so that we can change
3201b305b0f1Sespie    the default section alignment power.  */
3202b305b0f1Sespie 
3203b305b0f1Sespie static const bfd_coff_backend_data bfd_coff_small_swap_table =
3204b305b0f1Sespie {
3205b305b0f1Sespie   coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in,
3206b305b0f1Sespie   coff_swap_aux_out, coff_swap_sym_out,
3207b305b0f1Sespie   coff_swap_lineno_out, coff_swap_reloc_out,
3208b305b0f1Sespie   coff_swap_filehdr_out, coff_swap_aouthdr_out,
3209b305b0f1Sespie   coff_swap_scnhdr_out,
3210b305b0f1Sespie   FILHSZ, AOUTSZ, SCNHSZ, SYMESZ, AUXESZ, RELSZ, LINESZ, FILNMLEN,
3211b305b0f1Sespie #ifdef COFF_LONG_FILENAMES
3212c074d1c9Sdrahn   TRUE,
3213b305b0f1Sespie #else
3214c074d1c9Sdrahn   FALSE,
3215b305b0f1Sespie #endif
3216b305b0f1Sespie #ifdef COFF_LONG_SECTION_NAMES
3217c074d1c9Sdrahn   TRUE,
3218b305b0f1Sespie #else
3219c074d1c9Sdrahn   FALSE,
3220b305b0f1Sespie #endif
3221b305b0f1Sespie   2,
3222b55d4692Sfgsch #ifdef COFF_FORCE_SYMBOLS_IN_STRINGS
3223c074d1c9Sdrahn   TRUE,
3224b55d4692Sfgsch #else
3225c074d1c9Sdrahn   FALSE,
3226b55d4692Sfgsch #endif
3227b55d4692Sfgsch #ifdef COFF_DEBUG_STRING_WIDE_PREFIX
3228b55d4692Sfgsch   4,
3229b55d4692Sfgsch #else
3230b55d4692Sfgsch   2,
3231b55d4692Sfgsch #endif
3232b305b0f1Sespie   coff_swap_filehdr_in, coff_swap_aouthdr_in, coff_swap_scnhdr_in,
3233b305b0f1Sespie   coff_swap_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook,
3234b305b0f1Sespie   coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook,
3235b305b0f1Sespie   coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook,
3236b305b0f1Sespie   coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
3237b305b0f1Sespie   coff_classify_symbol, coff_compute_section_file_positions,
3238b305b0f1Sespie   coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
3239b305b0f1Sespie   coff_adjust_symndx, coff_link_add_one_symbol,
3240b305b0f1Sespie   coff_link_output_has_begun, coff_final_link_postscript
3241b305b0f1Sespie };
3242b305b0f1Sespie 
3243b305b0f1Sespie #define coff_small_close_and_cleanup \
3244b305b0f1Sespie   coff_close_and_cleanup
3245b305b0f1Sespie #define coff_small_bfd_free_cached_info \
3246b305b0f1Sespie   coff_bfd_free_cached_info
3247b305b0f1Sespie #define coff_small_get_section_contents \
3248b305b0f1Sespie   coff_get_section_contents
3249b305b0f1Sespie #define coff_small_get_section_contents_in_window \
3250b305b0f1Sespie   coff_get_section_contents_in_window
3251b305b0f1Sespie 
3252b305b0f1Sespie extern const bfd_target shlcoff_small_vec;
3253b305b0f1Sespie 
3254b305b0f1Sespie const bfd_target shcoff_small_vec =
3255b305b0f1Sespie {
3256b305b0f1Sespie   "coff-sh-small",		/* name */
32572159047fSniklas   bfd_target_coff_flavour,
3258c88b1d6cSniklas   BFD_ENDIAN_BIG,		/* data byte order is big */
3259c88b1d6cSniklas   BFD_ENDIAN_BIG,		/* header byte order is big */
32602159047fSniklas 
32612159047fSniklas   (HAS_RELOC | EXEC_P |		/* object flags */
32622159047fSniklas    HAS_LINENO | HAS_DEBUG |
32632159047fSniklas    HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE),
32642159047fSniklas 
32652159047fSniklas   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),
32662159047fSniklas   '_',				/* leading symbol underscore */
32672159047fSniklas   '/',				/* ar_pad_char */
32682159047fSniklas   15,				/* ar_max_namelen */
32692159047fSniklas   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
32702159047fSniklas   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
32712159047fSniklas   bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
32722159047fSniklas   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
32732159047fSniklas   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
32742159047fSniklas   bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
32752159047fSniklas 
3276b305b0f1Sespie   {_bfd_dummy_target, coff_small_object_p, /* bfd_check_format */
32772159047fSniklas      bfd_generic_archive_p, _bfd_dummy_target},
32782159047fSniklas   {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
32792159047fSniklas      bfd_false},
32802159047fSniklas   {bfd_false, coff_write_object_contents, /* bfd_write_contents */
32812159047fSniklas      _bfd_write_archive_contents, bfd_false},
32822159047fSniklas 
3283b305b0f1Sespie   BFD_JUMP_TABLE_GENERIC (coff_small),
32842159047fSniklas   BFD_JUMP_TABLE_COPY (coff),
32852159047fSniklas   BFD_JUMP_TABLE_CORE (_bfd_nocore),
32862159047fSniklas   BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
32872159047fSniklas   BFD_JUMP_TABLE_SYMBOLS (coff),
32882159047fSniklas   BFD_JUMP_TABLE_RELOCS (coff),
32892159047fSniklas   BFD_JUMP_TABLE_WRITE (coff),
32902159047fSniklas   BFD_JUMP_TABLE_LINK (coff),
32912159047fSniklas   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
32922159047fSniklas 
3293b305b0f1Sespie   & shlcoff_small_vec,
3294b305b0f1Sespie 
3295b305b0f1Sespie   (PTR) &bfd_coff_small_swap_table
32962159047fSniklas };
32972159047fSniklas 
3298b305b0f1Sespie const bfd_target shlcoff_small_vec =
32992159047fSniklas {
3300b305b0f1Sespie   "coff-shl-small",		/* name */
33012159047fSniklas   bfd_target_coff_flavour,
3302c88b1d6cSniklas   BFD_ENDIAN_LITTLE,		/* data byte order is little */
3303c88b1d6cSniklas   BFD_ENDIAN_LITTLE,		/* header byte order is little endian too*/
33042159047fSniklas 
33052159047fSniklas   (HAS_RELOC | EXEC_P |		/* object flags */
33062159047fSniklas    HAS_LINENO | HAS_DEBUG |
33072159047fSniklas    HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE),
33082159047fSniklas 
33092159047fSniklas   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),
33102159047fSniklas   '_',				/* leading symbol underscore */
33112159047fSniklas   '/',				/* ar_pad_char */
33122159047fSniklas   15,				/* ar_max_namelen */
33132159047fSniklas   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
33142159047fSniklas   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
33152159047fSniklas   bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
33162159047fSniklas   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
33172159047fSniklas   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
33182159047fSniklas   bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
33192159047fSniklas 
3320b305b0f1Sespie   {_bfd_dummy_target, coff_small_object_p, /* bfd_check_format */
33212159047fSniklas      bfd_generic_archive_p, _bfd_dummy_target},
33222159047fSniklas   {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
33232159047fSniklas      bfd_false},
33242159047fSniklas   {bfd_false, coff_write_object_contents, /* bfd_write_contents */
33252159047fSniklas      _bfd_write_archive_contents, bfd_false},
33262159047fSniklas 
3327b305b0f1Sespie   BFD_JUMP_TABLE_GENERIC (coff_small),
33282159047fSniklas   BFD_JUMP_TABLE_COPY (coff),
33292159047fSniklas   BFD_JUMP_TABLE_CORE (_bfd_nocore),
33302159047fSniklas   BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
33312159047fSniklas   BFD_JUMP_TABLE_SYMBOLS (coff),
33322159047fSniklas   BFD_JUMP_TABLE_RELOCS (coff),
33332159047fSniklas   BFD_JUMP_TABLE_WRITE (coff),
33342159047fSniklas   BFD_JUMP_TABLE_LINK (coff),
33352159047fSniklas   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
33362159047fSniklas 
3337b305b0f1Sespie   & shcoff_small_vec,
3338b305b0f1Sespie 
3339b305b0f1Sespie   (PTR) &bfd_coff_small_swap_table
33402159047fSniklas };
3341b305b0f1Sespie #endif
3342