1 /* BFD library support routines for the Renesas H8/300 architecture. 2 Copyright (C) 1990-2014 Free Software Foundation, Inc. 3 Hacked by Steve Chamberlain of Cygnus Support. 4 5 This file is part of BFD, the Binary File Descriptor library. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 MA 02110-1301, USA. */ 21 22 #include "sysdep.h" 23 #include "bfd.h" 24 #include "libbfd.h" 25 26 static bfd_boolean 27 h8300_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 96 static const bfd_arch_info_type * 97 compatible (const bfd_arch_info_type *in, const bfd_arch_info_type *out) 98 { 99 if (in->arch != out->arch) 100 return 0; 101 if (in->mach == bfd_mach_h8300sx && out->mach == bfd_mach_h8300s) 102 return in; 103 if (in->mach == bfd_mach_h8300s && out->mach == bfd_mach_h8300sx) 104 return out; 105 if (in->mach == bfd_mach_h8300sxn && out->mach == bfd_mach_h8300sn) 106 return in; 107 if (in->mach == bfd_mach_h8300sn && out->mach == bfd_mach_h8300sxn) 108 return out; 109 /* It's really not a good idea to mix and match modes. */ 110 if (in->mach != out->mach) 111 return 0; 112 else 113 return in; 114 } 115 116 static const bfd_arch_info_type h8300sxn_info_struct = 117 { 118 32, /* 32 bits in a word */ 119 16, /* 16 bits in an address */ 120 8, /* 8 bits in a byte */ 121 bfd_arch_h8300, 122 bfd_mach_h8300sxn, 123 "h8300sxn", /* arch_name */ 124 "h8300sxn", /* printable name */ 125 1, 126 FALSE, /* the default machine */ 127 compatible, 128 h8300_scan, 129 bfd_arch_default_fill, 130 0 131 }; 132 133 static 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 bfd_arch_default_fill, 147 &h8300sxn_info_struct 148 }; 149 150 static const bfd_arch_info_type h8300sn_info_struct = 151 { 152 32, /* 32 bits in a word. */ 153 16, /* 16 bits in an address. */ 154 8, /* 8 bits in a byte. */ 155 bfd_arch_h8300, 156 bfd_mach_h8300sn, 157 "h8300sn", /* Architecture name. */ 158 "h8300sn", /* Printable name. */ 159 1, 160 FALSE, /* The default machine. */ 161 compatible, 162 h8300_scan, 163 bfd_arch_default_fill, 164 &h8300sx_info_struct 165 }; 166 167 static const bfd_arch_info_type h8300hn_info_struct = 168 { 169 32, /* 32 bits in a word. */ 170 16, /* 16 bits in an address. */ 171 8, /* 8 bits in a byte. */ 172 bfd_arch_h8300, 173 bfd_mach_h8300hn, 174 "h8300hn", /* Architecture name. */ 175 "h8300hn", /* Printable name. */ 176 1, 177 FALSE, /* The default machine. */ 178 compatible, 179 h8300_scan, 180 bfd_arch_default_fill, 181 &h8300sn_info_struct 182 }; 183 184 static const bfd_arch_info_type h8300s_info_struct = 185 { 186 32, /* 32 bits in a word. */ 187 32, /* 32 bits in an address. */ 188 8, /* 8 bits in a byte. */ 189 bfd_arch_h8300, 190 bfd_mach_h8300s, 191 "h8300s", /* Architecture name. */ 192 "h8300s", /* Printable name. */ 193 1, 194 FALSE, /* The default machine. */ 195 compatible, 196 h8300_scan, 197 bfd_arch_default_fill, 198 & h8300hn_info_struct 199 }; 200 201 static const bfd_arch_info_type h8300h_info_struct = 202 { 203 32, /* 32 bits in a word. */ 204 32, /* 32 bits in an address. */ 205 8, /* 8 bits in a byte. */ 206 bfd_arch_h8300, 207 bfd_mach_h8300h, 208 "h8300h", /* Architecture name. */ 209 "h8300h", /* Printable name. */ 210 1, 211 FALSE, /* The default machine. */ 212 compatible, 213 h8300_scan, 214 bfd_arch_default_fill, 215 &h8300s_info_struct 216 }; 217 218 const bfd_arch_info_type bfd_h8300_arch = 219 { 220 16, /* 16 bits in a word. */ 221 16, /* 16 bits in an address. */ 222 8, /* 8 bits in a byte. */ 223 bfd_arch_h8300, 224 bfd_mach_h8300, 225 "h8300", /* Architecture name. */ 226 "h8300", /* Printable name. */ 227 1, 228 TRUE, /* The default machine. */ 229 compatible, 230 h8300_scan, 231 bfd_arch_default_fill, 232 &h8300h_info_struct 233 }; 234 235 /* Pad the given address to 32 bits, converting 16-bit and 24-bit 236 addresses into the values they would have had on a h8s target. */ 237 238 bfd_vma 239 bfd_h8300_pad_address (bfd *abfd, bfd_vma address) 240 { 241 /* Cope with bfd_vma's larger than 32 bits. */ 242 address &= 0xffffffffu; 243 244 switch (bfd_get_mach (abfd)) 245 { 246 case bfd_mach_h8300: 247 case bfd_mach_h8300hn: 248 case bfd_mach_h8300sn: 249 case bfd_mach_h8300sxn: 250 /* Sign extend a 16-bit address. */ 251 if (address >= 0x8000) 252 return address | 0xffff0000u; 253 return address; 254 255 case bfd_mach_h8300h: 256 /* Sign extend a 24-bit address. */ 257 if (address >= 0x800000) 258 return address | 0xff000000u; 259 return address; 260 261 case bfd_mach_h8300s: 262 case bfd_mach_h8300sx: 263 return address; 264 265 default: 266 abort (); 267 } 268 } 269