1/* BFD library support routines for the Renesas H8/300 architecture. 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 2000, 2001, 2002, 2003 3 Free Software Foundation, Inc. 4 Hacked by Steve Chamberlain of Cygnus Support. 5 6 This file is part of BFD, the Binary File Descriptor library. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, 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 27h8300_scan (const struct bfd_arch_info *info, const char *string) 28{ 29 if (*string != 'h' && *string != 'H') 30 return FALSE; 31 32 string++; 33 if (*string != '8') 34 return FALSE; 35 36 string++; 37 if (*string == '/') 38 string++; 39 40 if (*string != '3') 41 return FALSE; 42 string++; 43 if (*string != '0') 44 return FALSE; 45 string++; 46 if (*string != '0') 47 return FALSE; 48 string++; 49 if (*string == '-') 50 string++; 51 52 /* In ELF linker scripts, we typically express the architecture/machine 53 as architecture:machine. 54 55 So if we've matched so far and encounter a colon, try to match the 56 string following the colon. */ 57 if (*string == ':') 58 { 59 string++; 60 return h8300_scan (info, string); 61 } 62 63 if (*string == 'h' || *string == 'H') 64 { 65 string++; 66 if (*string == 'n' || *string == 'N') 67 return (info->mach == bfd_mach_h8300hn); 68 69 return (info->mach == bfd_mach_h8300h); 70 } 71 else if (*string == 's' || *string == 'S') 72 { 73 string++; 74 if (*string == 'n' || *string == 'N') 75 return (info->mach == bfd_mach_h8300sn); 76 77 if (*string == 'x' || *string == 'X') 78 { 79 string++; 80 if (*string == 'n' || *string == 'N') 81 return (info->mach == bfd_mach_h8300sxn); 82 83 return (info->mach == bfd_mach_h8300sx); 84 } 85 86 return (info->mach == bfd_mach_h8300s); 87 } 88 else 89 return info->mach == bfd_mach_h8300; 90} 91 92/* This routine is provided two arch_infos and works out the machine 93 which would be compatible with both and returns a pointer to its 94 info structure. */ 95 96static const bfd_arch_info_type * 97compatible (const bfd_arch_info_type *in, const bfd_arch_info_type *out) 98{ 99 /* It's really not a good idea to mix and match modes. */ 100 if (in->arch != out->arch || in->mach != out->mach) 101 return 0; 102 else 103 return in; 104} 105 106static const bfd_arch_info_type h8300sxn_info_struct = 107{ 108 32, /* 32 bits in a word */ 109 16, /* 16 bits in an address */ 110 8, /* 8 bits in a byte */ 111 bfd_arch_h8300, 112 bfd_mach_h8300sxn, 113 "h8300sxn", /* arch_name */ 114 "h8300sxn", /* printable name */ 115 1, 116 FALSE, /* the default machine */ 117 compatible, 118 h8300_scan, 119 0 120}; 121 122static const bfd_arch_info_type h8300sx_info_struct = 123{ 124 32, /* 32 bits in a word */ 125 32, /* 32 bits in an address */ 126 8, /* 8 bits in a byte */ 127 bfd_arch_h8300, 128 bfd_mach_h8300sx, 129 "h8300sx", /* arch_name */ 130 "h8300sx", /* printable name */ 131 1, 132 FALSE, /* the default machine */ 133 compatible, 134 h8300_scan, 135 &h8300sxn_info_struct 136}; 137 138static const bfd_arch_info_type h8300sn_info_struct = 139{ 140 32, /* 32 bits in a word. */ 141 16, /* 16 bits in an address. */ 142 8, /* 8 bits in a byte. */ 143 bfd_arch_h8300, 144 bfd_mach_h8300sn, 145 "h8300sn", /* Architecture name. */ 146 "h8300sn", /* Printable name. */ 147 1, 148 FALSE, /* The default machine. */ 149 compatible, 150 h8300_scan, 151 &h8300sx_info_struct 152}; 153 154static const bfd_arch_info_type h8300hn_info_struct = 155{ 156 32, /* 32 bits in a word. */ 157 16, /* 16 bits in an address. */ 158 8, /* 8 bits in a byte. */ 159 bfd_arch_h8300, 160 bfd_mach_h8300hn, 161 "h8300hn", /* Architecture name. */ 162 "h8300hn", /* Printable name. */ 163 1, 164 FALSE, /* The default machine. */ 165 compatible, 166 h8300_scan, 167 &h8300sn_info_struct 168}; 169 170static const bfd_arch_info_type h8300s_info_struct = 171{ 172 32, /* 32 bits in a word. */ 173 32, /* 32 bits in an address. */ 174 8, /* 8 bits in a byte. */ 175 bfd_arch_h8300, 176 bfd_mach_h8300s, 177 "h8300s", /* Architecture name. */ 178 "h8300s", /* Printable name. */ 179 1, 180 FALSE, /* The default machine. */ 181 compatible, 182 h8300_scan, 183 & h8300hn_info_struct 184}; 185 186static const bfd_arch_info_type h8300h_info_struct = 187{ 188 32, /* 32 bits in a word. */ 189 32, /* 32 bits in an address. */ 190 8, /* 8 bits in a byte. */ 191 bfd_arch_h8300, 192 bfd_mach_h8300h, 193 "h8300h", /* Architecture name. */ 194 "h8300h", /* Printable name. */ 195 1, 196 FALSE, /* The default machine. */ 197 compatible, 198 h8300_scan, 199 &h8300s_info_struct 200}; 201 202const bfd_arch_info_type bfd_h8300_arch = 203{ 204 16, /* 16 bits in a word. */ 205 16, /* 16 bits in an address. */ 206 8, /* 8 bits in a byte. */ 207 bfd_arch_h8300, 208 bfd_mach_h8300, 209 "h8300", /* Architecture name. */ 210 "h8300", /* Printable name. */ 211 1, 212 TRUE, /* The default machine. */ 213 compatible, 214 h8300_scan, 215 &h8300h_info_struct 216}; 217 218/* Pad the given address to 32 bits, converting 16-bit and 24-bit 219 addresses into the values they would have had on a h8s target. */ 220 221bfd_vma 222bfd_h8300_pad_address (bfd *abfd, bfd_vma address) 223{ 224 /* Cope with bfd_vma's larger than 32 bits. */ 225 address &= 0xffffffffu; 226 227 switch (bfd_get_mach (abfd)) 228 { 229 case bfd_mach_h8300: 230 case bfd_mach_h8300hn: 231 case bfd_mach_h8300sn: 232 case bfd_mach_h8300sxn: 233 /* Sign extend a 16-bit address. */ 234 if (address >= 0x8000) 235 return address | 0xffff0000u; 236 return address; 237 238 case bfd_mach_h8300h: 239 /* Sign extend a 24-bit address. */ 240 if (address >= 0x800000) 241 return address | 0xff000000u; 242 return address; 243 244 case bfd_mach_h8300s: 245 case bfd_mach_h8300sx: 246 return address; 247 248 default: 249 abort (); 250 } 251} 252