1/* BFD library support routines for the H8/500 architecture.
2   Copyright 1993, 1995, 2000, 2001, 2002, 2003
3   Free Software Foundation, Inc.
4   Hacked by Steve Chamberlain of Cygnus Support.
5
6This file is part of BFD, the Binary File Descriptor library.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
22#include "bfd.h"
23#include "sysdep.h"
24#include "libbfd.h"
25
26static bfd_boolean scan_mach
27  PARAMS ((const struct bfd_arch_info *, const char *));
28
29#if 0
30/*
31Relocations for the Z8K
32
33*/
34static bfd_reloc_status_type
35howto16_callback (abfd, reloc_entry, symbol_in, data,
36		  ignore_input_section, ignore_bfd)
37     bfd *abfd;
38     arelent *reloc_entry;
39     struct bfd_symbol *symbol_in;
40     PTR data;
41     asection *ignore_input_section;
42     bfd *ignore_bfd;
43{
44  long relocation = 0;
45  bfd_vma addr = reloc_entry->address;
46  long x = bfd_get_16 (abfd, (bfd_byte *)data + addr);
47
48  HOWTO_PREPARE(relocation, symbol_in);
49
50  x = (x + relocation + reloc_entry->addend);
51
52  bfd_put_16 (abfd, x, (bfd_byte *)data + addr);
53  return bfd_reloc_ok;
54}
55
56static bfd_reloc_status_type
57howto8_callback (abfd, reloc_entry, symbol_in, data,
58		 ignore_input_section, ignore_bfd)
59     bfd *abfd;
60     arelent *reloc_entry;
61     struct bfd_symbol *symbol_in;
62     PTR data;
63     asection *ignore_input_section;
64     bfd *ignore_bfd;
65{
66  long relocation = 0;
67  bfd_vma addr = reloc_entry->address;
68  long x = bfd_get_8 (abfd, (bfd_byte *)data + addr);
69
70  HOWTO_PREPARE(relocation, symbol_in);
71
72  x = (x + relocation + reloc_entry->addend);
73
74  bfd_put_8 (abfd, x, (bfd_byte *)data + addr);
75  return bfd_reloc_ok;
76}
77
78static bfd_reloc_status_type
79howto8_FFnn_callback (abfd, reloc_entry, symbol_in, data,
80		      ignore_input_section, ignore_bfd)
81     bfd *abfd;
82     arelent *reloc_entry;
83     struct bfd_symbol *symbol_in;
84     PTR data;
85     asection *ignore_input_section;
86     bfd *ignore_bfd;
87{
88  long relocation = 0;
89  bfd_vma addr = reloc_entry->address;
90
91  long x = bfd_get_8 (abfd, (bfd_byte *)data + addr);
92  abort ();
93  HOWTO_PREPARE(relocation, symbol_in);
94
95  x = (x + relocation + reloc_entry->addend);
96
97  bfd_put_8 (abfd, x, (bfd_byte *)data + addr);
98  return bfd_reloc_ok;
99}
100
101static bfd_reloc_status_type
102howto8_pcrel_callback (abfd, reloc_entry, symbol_in, data,
103		       ignore_input_section, ignore_bfd)
104     bfd *abfd;
105     arelent *reloc_entry;
106     struct bfd_symbol *symbol_in;
107     PTR data;
108     asection *ignore_input_section;
109     bfd *ignore_bfd;
110{
111  long relocation = 0;
112  bfd_vma addr = reloc_entry->address;
113  long x = bfd_get_8 (abfd, (bfd_byte *)data + addr);
114  abort ();
115  HOWTO_PREPARE(relocation, symbol_in);
116
117  x = (x + relocation + reloc_entry->addend);
118
119  bfd_put_8 (abfd, x, (bfd_byte *)data + addr);
120  return bfd_reloc_ok;
121}
122
123static reloc_howto_type howto_16
124  = NEWHOWTO (howto16_callback, "abs16", 1, FALSE, FALSE);
125static reloc_howto_type howto_8
126  = NEWHOWTO (howto8_callback, "abs8", 0, FALSE, FALSE);
127
128static reloc_howto_type howto_8_FFnn
129  = NEWHOWTO (howto8_FFnn_callback, "ff00+abs8", 0, FALSE, FALSE);
130
131static reloc_howto_type howto_8_pcrel
132  = NEWHOWTO (howto8_pcrel_callback, "pcrel8", 0, FALSE, TRUE);
133
134static reloc_howto_type *
135local_bfd_reloc_type_lookup (arch, code)
136     const struct bfd_arch_info *arch;
137     bfd_reloc_code_real_type code;
138{
139  switch (code) {
140  case BFD_RELOC_16:
141    return &howto_16;
142  case BFD_RELOC_8_FFnn:
143    return &howto_8_FFnn;
144  case BFD_RELOC_8:
145    return &howto_8;
146  case BFD_RELOC_8_PCREL:
147    return &howto_8_pcrel;
148  }
149  return (reloc_howto_type *)NULL;
150}
151#endif
152
153static bfd_boolean
154scan_mach (info, string)
155     const struct bfd_arch_info *info ATTRIBUTE_UNUSED;
156     const char *string;
157{
158  if (strcmp (string,"h8/500") == 0)
159    return TRUE;
160  if (strcmp (string,"H8/500") == 0)
161    return TRUE;
162  if (strcmp (string,"h8500") == 0)
163    return TRUE;
164  if (strcmp (string,"H8500") == 0)
165    return TRUE;
166  return FALSE;
167}
168
169#if 0 /* not used currently */
170/* This routine is provided two arch_infos and returns whether
171   they'd be compatible */
172
173static const bfd_arch_info_type *
174compatible (a,b)
175     const bfd_arch_info_type *a;
176     const bfd_arch_info_type *b;
177{
178  if (a->arch != b->arch || a->mach != b->mach)
179   return NULL;
180  return a;
181}
182#endif
183
184const bfd_arch_info_type bfd_h8500_arch =
185{
186  16,				/* 16 bits in a word */
187  24,				/* 24 bits in an address */
188  8,				/* 8 bits in a byte */
189  bfd_arch_h8500,
190  0,				/* only 1 machine */
191  "h8500",			/* arch_name  */
192  "h8500",			/* printable name */
193  1,
194  TRUE,				/* the default machine */
195  bfd_default_compatible,
196  scan_mach,
197  0,
198};
199