1 /* OpenRISC 1000 opcode support. -*- C -*- 2 Copyright 2000-2014 Free Software Foundation, Inc. 3 4 Originally ontributed for OR32 by Red Hat Inc; 5 6 This file is part of the GNU Binutils. 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, see <http://www.gnu.org/licenses/>. */ 20 21 /* This file is an addendum to or1k.cpu. Heavy use of C code isn't 22 appropriate in .cpu files, so it resides here. This especially applies 23 to assembly/disassembly where parsing/printing can be quite involved. 24 Such things aren't really part of the specification of the cpu, per se, 25 so .cpu files provide the general framework and .opc files handle the 26 nitty-gritty details as necessary. 27 28 Each section is delimited with start and end markers. 29 30 <arch>-opc.h additions use: "-- opc.h" 31 <arch>-opc.c additions use: "-- opc.c" 32 <arch>-asm.c additions use: "-- asm.c" 33 <arch>-dis.c additions use: "-- dis.c" 34 <arch>-ibd.h additions use: "-- ibd.h" */ 35 36 /* -- opc.h */ 37 38 #undef CGEN_DIS_HASH_SIZE 39 #define CGEN_DIS_HASH_SIZE 256 40 #undef CGEN_DIS_HASH 41 #define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2) 42 43 /* -- */ 44 45 /* -- opc.c */ 46 /* -- */ 47 48 /* -- asm.c */ 49 50 static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'"); 51 52 #define CGEN_VERBOSE_ASSEMBLER_ERRORS 53 54 static const char * 55 parse_disp26 (CGEN_CPU_DESC cd, 56 const char ** strp, 57 int opindex, 58 int opinfo, 59 enum cgen_parse_operand_result * resultp, 60 bfd_vma * valuep) 61 { 62 const char *errmsg = NULL; 63 enum cgen_parse_operand_result result_type; 64 65 if (strncasecmp (*strp, "plt(", 4) == 0) 66 { 67 bfd_vma value; 68 69 *strp += 4; 70 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_PLT26, 71 & result_type, & value); 72 if (**strp != ')') 73 return MISSING_CLOSING_PARENTHESIS; 74 ++*strp; 75 if (errmsg == NULL 76 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 77 value = (value >> 2) & 0xffff; 78 *valuep = value; 79 return errmsg; 80 } 81 return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep); 82 } 83 84 static const char * 85 parse_simm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep) 86 { 87 const char *errmsg; 88 enum cgen_parse_operand_result result_type; 89 long ret; 90 91 if (**strp == '#') 92 ++*strp; 93 94 if (strncasecmp (*strp, "hi(", 3) == 0) 95 { 96 bfd_vma value; 97 98 *strp += 3; 99 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16, 100 & result_type, & value); 101 if (**strp != ')') 102 errmsg = MISSING_CLOSING_PARENTHESIS; 103 ++*strp; 104 105 ret = value; 106 107 if (errmsg == NULL 108 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 109 { 110 ret >>= 16; 111 ret &= 0xffff; 112 ret = (ret ^ 0x8000) - 0x8000; 113 } 114 } 115 else if (strncasecmp (*strp, "lo(", 3) == 0) 116 { 117 bfd_vma value; 118 119 *strp += 3; 120 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16, 121 & result_type, & value); 122 if (**strp != ')') 123 return MISSING_CLOSING_PARENTHESIS; 124 ++*strp; 125 126 ret = value; 127 128 if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 129 { 130 ret &= 0xffff; 131 ret = (ret ^ 0x8000) - 0x8000; 132 } 133 } 134 else if (strncasecmp (*strp, "got(", 4) == 0) 135 { 136 bfd_vma value; 137 138 *strp += 4; 139 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_GOT16, 140 & result_type, & value); 141 if (**strp != ')') 142 return MISSING_CLOSING_PARENTHESIS; 143 ++*strp; 144 if (errmsg == NULL 145 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 146 value &= 0xffff; 147 *valuep = value; 148 return errmsg; 149 } 150 else if (strncasecmp (*strp, "gotpchi(", 8) == 0) 151 { 152 bfd_vma value; 153 154 *strp += 8; 155 errmsg = cgen_parse_address (cd, strp, opindex, 156 BFD_RELOC_OR1K_GOTPC_HI16, 157 & result_type, & value); 158 if (**strp != ')') 159 return MISSING_CLOSING_PARENTHESIS; 160 ++*strp; 161 if (errmsg == NULL 162 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 163 value = (value >> 16) & 0xffff; 164 *valuep = value; 165 return errmsg; 166 } 167 else if (strncasecmp (*strp, "gotpclo(", 8) == 0) 168 { 169 bfd_vma value; 170 171 *strp += 8; 172 errmsg = cgen_parse_address (cd, strp, opindex, 173 BFD_RELOC_OR1K_GOTPC_LO16, 174 &result_type, &value); 175 if (**strp != ')') 176 return MISSING_CLOSING_PARENTHESIS; 177 ++*strp; 178 if (errmsg == NULL 179 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 180 value &= 0xffff; 181 *valuep = value; 182 return errmsg; 183 } 184 else if (strncasecmp (*strp, "gotoffhi(", 9) == 0) 185 { 186 bfd_vma value; 187 188 *strp += 9; 189 errmsg = cgen_parse_address (cd, strp, opindex, 190 BFD_RELOC_OR1K_GOTOFF_HI16, 191 & result_type, & value); 192 193 if (**strp != ')') 194 return MISSING_CLOSING_PARENTHESIS; 195 ++*strp; 196 if (errmsg == NULL 197 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 198 value = (value >> 16) & 0xffff; 199 *valuep = value; 200 return errmsg; 201 } 202 else if (strncasecmp (*strp, "gotofflo(", 9) == 0) 203 { 204 bfd_vma value; 205 206 *strp += 9; 207 errmsg = cgen_parse_address (cd, strp, opindex, 208 BFD_RELOC_OR1K_GOTOFF_LO16, 209 &result_type, &value); 210 if (**strp != ')') 211 return MISSING_CLOSING_PARENTHESIS; 212 ++*strp; 213 if (errmsg == NULL 214 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 215 value &= 0xffff; 216 *valuep = value; 217 return errmsg; 218 } 219 else if (strncasecmp (*strp, "tlsgdhi(", 8) == 0) 220 { 221 bfd_vma value; 222 223 *strp += 8; 224 errmsg = cgen_parse_address (cd, strp, opindex, 225 BFD_RELOC_OR1K_TLS_GD_HI16, 226 & result_type, & value); 227 228 if (**strp != ')') 229 return MISSING_CLOSING_PARENTHESIS; 230 ++*strp; 231 if (errmsg == NULL 232 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 233 value = (value >> 16) & 0xffff; 234 *valuep = value; 235 return errmsg; 236 } 237 else if (strncasecmp (*strp, "tlsgdlo(", 8) == 0) 238 { 239 bfd_vma value; 240 241 *strp += 8; 242 errmsg = cgen_parse_address (cd, strp, opindex, 243 BFD_RELOC_OR1K_TLS_GD_LO16, 244 &result_type, &value); 245 if (**strp != ')') 246 return MISSING_CLOSING_PARENTHESIS; 247 ++*strp; 248 if (errmsg == NULL 249 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 250 value &= 0xffff; 251 *valuep = value; 252 return errmsg; 253 } 254 else if (strncasecmp (*strp, "tlsldmhi(", 9) == 0) 255 { 256 bfd_vma value; 257 258 *strp += 9; 259 errmsg = cgen_parse_address (cd, strp, opindex, 260 BFD_RELOC_OR1K_TLS_LDM_HI16, 261 & result_type, & value); 262 263 if (**strp != ')') 264 return MISSING_CLOSING_PARENTHESIS; 265 ++*strp; 266 if (errmsg == NULL 267 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 268 value = (value >> 16) & 0xffff; 269 *valuep = value; 270 return errmsg; 271 } 272 else if (strncasecmp (*strp, "tlsldmlo(", 9) == 0) 273 { 274 bfd_vma value; 275 276 *strp += 9; 277 errmsg = cgen_parse_address (cd, strp, opindex, 278 BFD_RELOC_OR1K_TLS_LDM_LO16, 279 &result_type, &value); 280 if (**strp != ')') 281 return MISSING_CLOSING_PARENTHESIS; 282 ++*strp; 283 if (errmsg == NULL 284 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 285 value &= 0xffff; 286 *valuep = value; 287 return errmsg; 288 } 289 else if (strncasecmp (*strp, "dtpoffhi(", 9) == 0) 290 { 291 bfd_vma value; 292 293 *strp += 9; 294 errmsg = cgen_parse_address (cd, strp, opindex, 295 BFD_RELOC_OR1K_TLS_LDO_HI16, 296 & result_type, & value); 297 298 if (**strp != ')') 299 return MISSING_CLOSING_PARENTHESIS; 300 ++*strp; 301 if (errmsg == NULL 302 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 303 value = (value >> 16) & 0xffff; 304 *valuep = value; 305 return errmsg; 306 } 307 else if (strncasecmp (*strp, "dtpofflo(", 9) == 0) 308 { 309 bfd_vma value; 310 311 *strp += 9; 312 errmsg = cgen_parse_address (cd, strp, opindex, 313 BFD_RELOC_OR1K_TLS_LDO_LO16, 314 &result_type, &value); 315 if (**strp != ')') 316 return MISSING_CLOSING_PARENTHESIS; 317 ++*strp; 318 if (errmsg == NULL 319 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 320 value &= 0xffff; 321 *valuep = value; 322 return errmsg; 323 } 324 else if (strncasecmp (*strp, "gottpoffhi(", 11) == 0) 325 { 326 bfd_vma value; 327 328 *strp += 11; 329 errmsg = cgen_parse_address (cd, strp, opindex, 330 BFD_RELOC_OR1K_TLS_IE_HI16, 331 & result_type, & value); 332 333 if (**strp != ')') 334 return MISSING_CLOSING_PARENTHESIS; 335 ++*strp; 336 if (errmsg == NULL 337 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 338 value = (value >> 16) & 0xffff; 339 *valuep = value; 340 return errmsg; 341 } 342 else if (strncasecmp (*strp, "gottpofflo(", 11) == 0) 343 { 344 bfd_vma value; 345 346 *strp += 11; 347 errmsg = cgen_parse_address (cd, strp, opindex, 348 BFD_RELOC_OR1K_TLS_IE_LO16, 349 &result_type, &value); 350 if (**strp != ')') 351 return MISSING_CLOSING_PARENTHESIS; 352 ++*strp; 353 if (errmsg == NULL 354 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 355 value &= 0xffff; 356 *valuep = value; 357 return errmsg; 358 } 359 else if (strncasecmp (*strp, "tpoffhi(", 8) == 0) 360 { 361 bfd_vma value; 362 363 *strp += 8; 364 errmsg = cgen_parse_address (cd, strp, opindex, 365 BFD_RELOC_OR1K_TLS_LE_HI16, 366 & result_type, & value); 367 368 if (**strp != ')') 369 return MISSING_CLOSING_PARENTHESIS; 370 ++*strp; 371 if (errmsg == NULL 372 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 373 value = (value >> 16) & 0xffff; 374 *valuep = value; 375 return errmsg; 376 } 377 else if (strncasecmp (*strp, "tpofflo(", 8) == 0) 378 { 379 bfd_vma value; 380 381 *strp += 8; 382 errmsg = cgen_parse_address (cd, strp, opindex, 383 BFD_RELOC_OR1K_TLS_LE_LO16, 384 &result_type, &value); 385 if (**strp != ')') 386 return MISSING_CLOSING_PARENTHESIS; 387 ++*strp; 388 if (errmsg == NULL 389 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 390 value &= 0xffff; 391 *valuep = value; 392 return errmsg; 393 } 394 else 395 { 396 long value; 397 errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value); 398 ret = value; 399 } 400 401 if (errmsg == NULL) 402 *valuep = ret; 403 404 return errmsg; 405 } 406 407 static const char * 408 parse_uimm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, unsigned long * valuep) 409 { 410 const char *errmsg = parse_simm16(cd, strp, opindex, (long *) valuep); 411 412 if (errmsg == NULL) 413 *valuep &= 0xffff; 414 return errmsg; 415 } 416 417 /* -- */ 418 419 /* -- ibd.h */ 420 421 /* -- */ 422