1/* BFD library support routines for the Renesas H8/300 architecture. 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 2000, 2001, 2002, 3 2003, 2004, 2007 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 3 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., 51 Franklin Street - Fifth Floor, Boston, 21 MA 02110-1301, USA. */ 22 23#include "sysdep.h" 24#include "bfd.h" 25#include "libbfd.h" 26 27static bfd_boolean 28h8300_scan (const struct bfd_arch_info *info, const char *string) 29{ 30 if (*string != 'h' && *string != 'H') 31 return FALSE; 32 33 string++; 34 if (*string != '8') 35 return FALSE; 36 37 string++; 38 if (*string == '/') 39 string++; 40 41 if (*string != '3') 42 return FALSE; 43 string++; 44 if (*string != '0') 45 return FALSE; 46 string++; 47 if (*string != '0') 48 return FALSE; 49 string++; 50 if (*string == '-') 51 string++; 52 53 /* In ELF linker scripts, we typically express the architecture/machine 54 as architecture:machine. 55 56 So if we've matched so far and encounter a colon, try to match the 57 string following the colon. */ 58 if (*string == ':') 59 { 60 string++; 61 return h8300_scan (info, string); 62 } 63 64 if (*string == 'h' || *string == 'H') 65 { 66 string++; 67 if (*string == 'n' || *string == 'N') 68 return (info->mach == bfd_mach_h8300hn); 69 70 return (info->mach == bfd_mach_h8300h); 71 } 72 else if (*string == 's' || *string == 'S') 73 { 74 string++; 75 if (*string == 'n' || *string == 'N') 76 return (info->mach == bfd_mach_h8300sn); 77 78 if (*string == 'x' || *string == 'X') 79 { 80 string++; 81 if (*string == 'n' || *string == 'N') 82 return (info->mach == bfd_mach_h8300sxn); 83 84 return (info->mach == bfd_mach_h8300sx); 85 } 86 87 return (info->mach == bfd_mach_h8300s); 88 } 89 else 90 return info->mach == bfd_mach_h8300; 91} 92 93/* This routine is provided two arch_infos and works out the machine 94 which would be compatible with both and returns a pointer to its 95 info structure. */ 96 97static const bfd_arch_info_type * 98compatible (const bfd_arch_info_type *in, const bfd_arch_info_type *out) 99{ 100 if (in->arch != out->arch) 101 return 0; 102 if (in->mach == bfd_mach_h8300sx && out->mach == bfd_mach_h8300s) 103 return in; 104 if (in->mach == bfd_mach_h8300s && out->mach == bfd_mach_h8300sx) 105 return out; 106 if (in->mach == bfd_mach_h8300sxn && out->mach == bfd_mach_h8300sn) 107 return in; 108 if (in->mach == bfd_mach_h8300sn && out->mach == bfd_mach_h8300sxn) 109 return out; 110 /* It's really not a good idea to mix and match modes. */ 111 if (in->mach != out->mach) 112 return 0; 113 else 114 return in; 115} 116 117static const bfd_arch_info_type h8300sxn_info_struct = 118{ 119 32, /* 32 bits in a word */ 120 16, /* 16 bits in an address */ 121 8, /* 8 bits in a byte */ 122 bfd_arch_h8300, 123 bfd_mach_h8300sxn, 124 "h8300sxn", /* arch_name */ 125 "h8300sxn", /* printable name */ 126 1, 127 FALSE, /* the default machine */ 128 compatible, 129 h8300_scan, 130 0 131}; 132 133static const bfd_arch_info_type h8300sx_info_struct = 134{ 135 32, /* 32 bits in a word */ 136 32, /* 32 bits in an address */ 137 8, /* 8 bits in a byte */ 138 bfd_arch_h8300, 139 bfd_mach_h8300sx, 140 "h8300sx", /* arch_name */ 141 "h8300sx", /* printable name */ 142 1, 143 FALSE, /* the default machine */ 144 compatible, 145 h8300_scan, 146 &h8300sxn_info_struct 147}; 148 149static const bfd_arch_info_type h8300sn_info_struct = 150{ 151 32, /* 32 bits in a word. */ 152 16, /* 16 bits in an address. */ 153 8, /* 8 bits in a byte. */ 154 bfd_arch_h8300, 155 bfd_mach_h8300sn, 156 "h8300sn", /* Architecture name. */ 157 "h8300sn", /* Printable name. */ 158 1, 159 FALSE, /* The default machine. */ 160 compatible, 161 h8300_scan, 162 &h8300sx_info_struct 163}; 164 165static const bfd_arch_info_type h8300hn_info_struct = 166{ 167 32, /* 32 bits in a word. */ 168 16, /* 16 bits in an address. */ 169 8, /* 8 bits in a byte. */ 170 bfd_arch_h8300, 171 bfd_mach_h8300hn, 172 "h8300hn", /* Architecture name. */ 173 "h8300hn", /* Printable name. */ 174 1, 175 FALSE, /* The default machine. */ 176 compatible, 177 h8300_scan, 178 &h8300sn_info_struct 179}; 180 181static const bfd_arch_info_type h8300s_info_struct = 182{ 183 32, /* 32 bits in a word. */ 184 32, /* 32 bits in an address. */ 185 8, /* 8 bits in a byte. */ 186 bfd_arch_h8300, 187 bfd_mach_h8300s, 188 "h8300s", /* Architecture name. */ 189 "h8300s", /* Printable name. */ 190 1, 191 FALSE, /* The default machine. */ 192 compatible, 193 h8300_scan, 194 & h8300hn_info_struct 195}; 196 197static const bfd_arch_info_type h8300h_info_struct = 198{ 199 32, /* 32 bits in a word. */ 200 32, /* 32 bits in an address. */ 201 8, /* 8 bits in a byte. */ 202 bfd_arch_h8300, 203 bfd_mach_h8300h, 204 "h8300h", /* Architecture name. */ 205 "h8300h", /* Printable name. */ 206 1, 207 FALSE, /* The default machine. */ 208 compatible, 209 h8300_scan, 210 &h8300s_info_struct 211}; 212 213const bfd_arch_info_type bfd_h8300_arch = 214{ 215 16, /* 16 bits in a word. */ 216 16, /* 16 bits in an address. */ 217 8, /* 8 bits in a byte. */ 218 bfd_arch_h8300, 219 bfd_mach_h8300, 220 "h8300", /* Architecture name. */ 221 "h8300", /* Printable name. */ 222 1, 223 TRUE, /* The default machine. */ 224 compatible, 225 h8300_scan, 226 &h8300h_info_struct 227}; 228 229/* Pad the given address to 32 bits, converting 16-bit and 24-bit 230 addresses into the values they would have had on a h8s target. */ 231 232bfd_vma 233bfd_h8300_pad_address (bfd *abfd, bfd_vma address) 234{ 235 /* Cope with bfd_vma's larger than 32 bits. */ 236 address &= 0xffffffffu; 237 238 switch (bfd_get_mach (abfd)) 239 { 240 case bfd_mach_h8300: 241 case bfd_mach_h8300hn: 242 case bfd_mach_h8300sn: 243 case bfd_mach_h8300sxn: 244 /* Sign extend a 16-bit address. */ 245 if (address >= 0x8000) 246 return address | 0xffff0000u; 247 return address; 248 249 case bfd_mach_h8300h: 250 /* Sign extend a 24-bit address. */ 251 if (address >= 0x800000) 252 return address | 0xff000000u; 253 return address; 254 255 case bfd_mach_h8300s: 256 case bfd_mach_h8300sx: 257 return address; 258 259 default: 260 abort (); 261 } 262} 263