1 /* tc-arc.c -- Assembler for the ARC 2 Copyright (C) 1994-2016 Free Software Foundation, Inc. 3 4 Contributor: Claudiu Zissulescu <claziss (at) synopsys.com> 5 6 This file is part of GAS, the GNU Assembler. 7 8 GAS 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, or (at your option) 11 any later version. 12 13 GAS 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 GAS; see the file COPYING. If not, write to the Free 20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 21 02110-1301, USA. */ 22 23 #include "as.h" 24 #include "subsegs.h" 25 #include "struc-symbol.h" 26 #include "dwarf2dbg.h" 27 #include "dw2gencfi.h" 28 #include "safe-ctype.h" 29 30 #include "opcode/arc.h" 31 #include "elf/arc.h" 32 #include "../opcodes/arc-ext.h" 33 34 /* Defines section. */ 35 36 #define MAX_INSN_FIXUPS 2 37 #define MAX_CONSTR_STR 20 38 #define FRAG_MAX_GROWTH 8 39 40 #ifdef DEBUG 41 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args) 42 #else 43 # define pr_debug(fmt, args...) 44 #endif 45 46 #define MAJOR_OPCODE(x) (((x) & 0xF8000000) >> 27) 47 #define SUB_OPCODE(x) (((x) & 0x003F0000) >> 16) 48 #define LP_INSN(x) ((MAJOR_OPCODE (x) == 0x4) && \ 49 (SUB_OPCODE (x) == 0x28)) 50 51 /* Equal to MAX_PRECISION in atof-ieee.c. */ 52 #define MAX_LITTLENUMS 6 53 54 #ifndef TARGET_WITH_CPU 55 #define TARGET_WITH_CPU "arc700" 56 #endif /* TARGET_WITH_CPU */ 57 58 /* Enum used to enumerate the relaxable ins operands. */ 59 enum rlx_operand_type 60 { 61 EMPTY = 0, 62 REGISTER, 63 REGISTER_S, /* Register for short instruction(s). */ 64 REGISTER_NO_GP, /* Is a register but not gp register specifically. */ 65 REGISTER_DUP, /* Duplication of previous operand of type register. */ 66 IMMEDIATE, 67 BRACKET 68 }; 69 70 enum arc_rlx_types 71 { 72 ARC_RLX_NONE = 0, 73 ARC_RLX_BL_S, 74 ARC_RLX_BL, 75 ARC_RLX_B_S, 76 ARC_RLX_B, 77 ARC_RLX_ADD_U3, 78 ARC_RLX_ADD_U6, 79 ARC_RLX_ADD_LIMM, 80 ARC_RLX_LD_U7, 81 ARC_RLX_LD_S9, 82 ARC_RLX_LD_LIMM, 83 ARC_RLX_MOV_U8, 84 ARC_RLX_MOV_S12, 85 ARC_RLX_MOV_LIMM, 86 ARC_RLX_SUB_U3, 87 ARC_RLX_SUB_U6, 88 ARC_RLX_SUB_LIMM, 89 ARC_RLX_MPY_U6, 90 ARC_RLX_MPY_LIMM, 91 ARC_RLX_MOV_RU6, 92 ARC_RLX_MOV_RLIMM, 93 ARC_RLX_ADD_RRU6, 94 ARC_RLX_ADD_RRLIMM, 95 }; 96 97 /* Macros section. */ 98 99 #define regno(x) ((x) & 0x3F) 100 #define is_ir_num(x) (((x) & ~0x3F) == 0) 101 #define is_code_density_p(sc) (((sc) == CD1 || (sc) == CD2)) 102 #define is_spfp_p(op) (((sc) == SPX)) 103 #define is_dpfp_p(op) (((sc) == DPX)) 104 #define is_fpuda_p(op) (((sc) == DPA)) 105 #define is_br_jmp_insn_p(op) (((op)->insn_class == BRANCH || (op)->insn_class == JUMP)) 106 #define is_kernel_insn_p(op) (((op)->insn_class == KERNEL)) 107 #define is_nps400_p(op) (((sc) == NPS400)) 108 109 /* Generic assembler global variables which must be defined by all 110 targets. */ 111 112 /* Characters which always start a comment. */ 113 const char comment_chars[] = "#;"; 114 115 /* Characters which start a comment at the beginning of a line. */ 116 const char line_comment_chars[] = "#"; 117 118 /* Characters which may be used to separate multiple commands on a 119 single line. */ 120 const char line_separator_chars[] = "`"; 121 122 /* Characters which are used to indicate an exponent in a floating 123 point number. */ 124 const char EXP_CHARS[] = "eE"; 125 126 /* Chars that mean this number is a floating point constant 127 As in 0f12.456 or 0d1.2345e12. */ 128 const char FLT_CHARS[] = "rRsSfFdD"; 129 130 /* Byte order. */ 131 extern int target_big_endian; 132 const char *arc_target_format = DEFAULT_TARGET_FORMAT; 133 static int byte_order = DEFAULT_BYTE_ORDER; 134 135 /* Arc extension section. */ 136 static segT arcext_section; 137 138 /* By default relaxation is disabled. */ 139 static int relaxation_state = 0; 140 141 extern int arc_get_mach (char *); 142 143 /* Forward declarations. */ 144 static void arc_lcomm (int); 145 static void arc_option (int); 146 static void arc_extra_reloc (int); 147 static void arc_extinsn (int); 148 static void arc_extcorereg (int); 149 150 const pseudo_typeS md_pseudo_table[] = 151 { 152 /* Make sure that .word is 32 bits. */ 153 { "word", cons, 4 }, 154 155 { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */ 156 { "lcomm", arc_lcomm, 0 }, 157 { "lcommon", arc_lcomm, 0 }, 158 { "cpu", arc_option, 0 }, 159 160 { "extinstruction", arc_extinsn, 0 }, 161 { "extcoreregister", arc_extcorereg, EXT_CORE_REGISTER }, 162 { "extauxregister", arc_extcorereg, EXT_AUX_REGISTER }, 163 { "extcondcode", arc_extcorereg, EXT_COND_CODE }, 164 165 { "tls_gd_ld", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_LD }, 166 { "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL }, 167 168 { NULL, NULL, 0 } 169 }; 170 171 const char *md_shortopts = ""; 172 173 enum options 174 { 175 OPTION_EB = OPTION_MD_BASE, 176 OPTION_EL, 177 178 OPTION_ARC600, 179 OPTION_ARC601, 180 OPTION_ARC700, 181 OPTION_ARCEM, 182 OPTION_ARCHS, 183 184 OPTION_MCPU, 185 OPTION_CD, 186 OPTION_RELAX, 187 OPTION_NPS400, 188 189 OPTION_SPFP, 190 OPTION_DPFP, 191 OPTION_FPUDA, 192 193 /* The following options are deprecated and provided here only for 194 compatibility reasons. */ 195 OPTION_USER_MODE, 196 OPTION_LD_EXT_MASK, 197 OPTION_SWAP, 198 OPTION_NORM, 199 OPTION_BARREL_SHIFT, 200 OPTION_MIN_MAX, 201 OPTION_NO_MPY, 202 OPTION_EA, 203 OPTION_MUL64, 204 OPTION_SIMD, 205 OPTION_XMAC_D16, 206 OPTION_XMAC_24, 207 OPTION_DSP_PACKA, 208 OPTION_CRC, 209 OPTION_DVBF, 210 OPTION_TELEPHONY, 211 OPTION_XYMEMORY, 212 OPTION_LOCK, 213 OPTION_SWAPE, 214 OPTION_RTSC 215 }; 216 217 struct option md_longopts[] = 218 { 219 { "EB", no_argument, NULL, OPTION_EB }, 220 { "EL", no_argument, NULL, OPTION_EL }, 221 { "mcpu", required_argument, NULL, OPTION_MCPU }, 222 { "mA6", no_argument, NULL, OPTION_ARC600 }, 223 { "mARC600", no_argument, NULL, OPTION_ARC600 }, 224 { "mARC601", no_argument, NULL, OPTION_ARC601 }, 225 { "mARC700", no_argument, NULL, OPTION_ARC700 }, 226 { "mA7", no_argument, NULL, OPTION_ARC700 }, 227 { "mEM", no_argument, NULL, OPTION_ARCEM }, 228 { "mHS", no_argument, NULL, OPTION_ARCHS }, 229 { "mcode-density", no_argument, NULL, OPTION_CD }, 230 { "mrelax", no_argument, NULL, OPTION_RELAX }, 231 { "mnps400", no_argument, NULL, OPTION_NPS400 }, 232 233 /* Floating point options */ 234 { "mspfp", no_argument, NULL, OPTION_SPFP}, 235 { "mspfp-compact", no_argument, NULL, OPTION_SPFP}, 236 { "mspfp_compact", no_argument, NULL, OPTION_SPFP}, 237 { "mspfp-fast", no_argument, NULL, OPTION_SPFP}, 238 { "mspfp_fast", no_argument, NULL, OPTION_SPFP}, 239 { "mdpfp", no_argument, NULL, OPTION_DPFP}, 240 { "mdpfp-compact", no_argument, NULL, OPTION_DPFP}, 241 { "mdpfp_compact", no_argument, NULL, OPTION_DPFP}, 242 { "mdpfp-fast", no_argument, NULL, OPTION_DPFP}, 243 { "mdpfp_fast", no_argument, NULL, OPTION_DPFP}, 244 { "mfpuda", no_argument, NULL, OPTION_FPUDA}, 245 246 /* The following options are deprecated and provided here only for 247 compatibility reasons. */ 248 { "mav2em", no_argument, NULL, OPTION_ARCEM }, 249 { "mav2hs", no_argument, NULL, OPTION_ARCHS }, 250 { "muser-mode-only", no_argument, NULL, OPTION_USER_MODE }, 251 { "mld-extension-reg-mask", required_argument, NULL, OPTION_LD_EXT_MASK }, 252 { "mswap", no_argument, NULL, OPTION_SWAP }, 253 { "mnorm", no_argument, NULL, OPTION_NORM }, 254 { "mbarrel-shifter", no_argument, NULL, OPTION_BARREL_SHIFT }, 255 { "mbarrel_shifter", no_argument, NULL, OPTION_BARREL_SHIFT }, 256 { "mmin-max", no_argument, NULL, OPTION_MIN_MAX }, 257 { "mmin_max", no_argument, NULL, OPTION_MIN_MAX }, 258 { "mno-mpy", no_argument, NULL, OPTION_NO_MPY }, 259 { "mea", no_argument, NULL, OPTION_EA }, 260 { "mEA", no_argument, NULL, OPTION_EA }, 261 { "mmul64", no_argument, NULL, OPTION_MUL64 }, 262 { "msimd", no_argument, NULL, OPTION_SIMD}, 263 { "mmac-d16", no_argument, NULL, OPTION_XMAC_D16}, 264 { "mmac_d16", no_argument, NULL, OPTION_XMAC_D16}, 265 { "mmac-24", no_argument, NULL, OPTION_XMAC_24}, 266 { "mmac_24", no_argument, NULL, OPTION_XMAC_24}, 267 { "mdsp-packa", no_argument, NULL, OPTION_DSP_PACKA}, 268 { "mdsp_packa", no_argument, NULL, OPTION_DSP_PACKA}, 269 { "mcrc", no_argument, NULL, OPTION_CRC}, 270 { "mdvbf", no_argument, NULL, OPTION_DVBF}, 271 { "mtelephony", no_argument, NULL, OPTION_TELEPHONY}, 272 { "mxy", no_argument, NULL, OPTION_XYMEMORY}, 273 { "mlock", no_argument, NULL, OPTION_LOCK}, 274 { "mswape", no_argument, NULL, OPTION_SWAPE}, 275 { "mrtsc", no_argument, NULL, OPTION_RTSC}, 276 277 { NULL, no_argument, NULL, 0 } 278 }; 279 280 size_t md_longopts_size = sizeof (md_longopts); 281 282 /* Local data and data types. */ 283 284 /* Used since new relocation types are introduced in this 285 file (DUMMY_RELOC_LITUSE_*). */ 286 typedef int extended_bfd_reloc_code_real_type; 287 288 struct arc_fixup 289 { 290 expressionS exp; 291 292 extended_bfd_reloc_code_real_type reloc; 293 294 /* index into arc_operands. */ 295 unsigned int opindex; 296 297 /* PC-relative, used by internals fixups. */ 298 unsigned char pcrel; 299 300 /* TRUE if this fixup is for LIMM operand. */ 301 bfd_boolean islong; 302 }; 303 304 struct arc_insn 305 { 306 unsigned int insn; 307 int nfixups; 308 struct arc_fixup fixups[MAX_INSN_FIXUPS]; 309 long limm; 310 bfd_boolean short_insn; /* Boolean value: TRUE if current insn is 311 short. */ 312 bfd_boolean has_limm; /* Boolean value: TRUE if limm field is 313 valid. */ 314 bfd_boolean relax; /* Boolean value: TRUE if needs 315 relaxation. */ 316 }; 317 318 /* Structure to hold any last two instructions. */ 319 static struct arc_last_insn 320 { 321 /* Saved instruction opcode. */ 322 const struct arc_opcode *opcode; 323 324 /* Boolean value: TRUE if current insn is short. */ 325 bfd_boolean has_limm; 326 327 /* Boolean value: TRUE if current insn has delay slot. */ 328 bfd_boolean has_delay_slot; 329 } arc_last_insns[2]; 330 331 /* Extension instruction suffix classes. */ 332 typedef struct 333 { 334 const char *name; 335 int len; 336 int attr_class; 337 } attributes_t; 338 339 static const attributes_t suffixclass[] = 340 { 341 { "SUFFIX_FLAG", 11, ARC_SUFFIX_FLAG }, 342 { "SUFFIX_COND", 11, ARC_SUFFIX_COND }, 343 { "SUFFIX_NONE", 11, ARC_SUFFIX_NONE } 344 }; 345 346 /* Extension instruction syntax classes. */ 347 static const attributes_t syntaxclass[] = 348 { 349 { "SYNTAX_3OP", 10, ARC_SYNTAX_3OP }, 350 { "SYNTAX_2OP", 10, ARC_SYNTAX_2OP }, 351 { "SYNTAX_1OP", 10, ARC_SYNTAX_1OP }, 352 { "SYNTAX_NOP", 10, ARC_SYNTAX_NOP } 353 }; 354 355 /* Extension instruction syntax classes modifiers. */ 356 static const attributes_t syntaxclassmod[] = 357 { 358 { "OP1_IMM_IMPLIED" , 15, ARC_OP1_IMM_IMPLIED }, 359 { "OP1_MUST_BE_IMM" , 15, ARC_OP1_MUST_BE_IMM } 360 }; 361 362 /* Extension register type. */ 363 typedef struct 364 { 365 char *name; 366 int number; 367 int imode; 368 } extRegister_t; 369 370 /* A structure to hold the additional conditional codes. */ 371 static struct 372 { 373 struct arc_flag_operand *arc_ext_condcode; 374 int size; 375 } ext_condcode = { NULL, 0 }; 376 377 /* Structure to hold an entry in ARC_OPCODE_HASH. */ 378 struct arc_opcode_hash_entry 379 { 380 /* The number of pointers in the OPCODE list. */ 381 size_t count; 382 383 /* Points to a list of opcode pointers. */ 384 const struct arc_opcode **opcode; 385 }; 386 387 /* Structure used for iterating through an arc_opcode_hash_entry. */ 388 struct arc_opcode_hash_entry_iterator 389 { 390 /* Index into the OPCODE element of the arc_opcode_hash_entry. */ 391 size_t index; 392 393 /* The specific ARC_OPCODE from the ARC_OPCODES table that was last 394 returned by this iterator. */ 395 const struct arc_opcode *opcode; 396 }; 397 398 /* Forward declaration. */ 399 static void assemble_insn 400 (const struct arc_opcode *, const expressionS *, int, 401 const struct arc_flags *, int, struct arc_insn *); 402 403 /* The cpu for which we are generating code. */ 404 static unsigned arc_target; 405 static const char *arc_target_name; 406 static unsigned arc_features; 407 408 /* The default architecture. */ 409 static int arc_mach_type; 410 411 /* TRUE if the cpu type has been explicitly specified. */ 412 static bfd_boolean mach_type_specified_p = FALSE; 413 414 /* The hash table of instruction opcodes. */ 415 static struct hash_control *arc_opcode_hash; 416 417 /* The hash table of register symbols. */ 418 static struct hash_control *arc_reg_hash; 419 420 /* The hash table of aux register symbols. */ 421 static struct hash_control *arc_aux_hash; 422 423 /* A table of CPU names and opcode sets. */ 424 static const struct cpu_type 425 { 426 const char *name; 427 unsigned flags; 428 int mach; 429 unsigned eflags; 430 unsigned features; 431 } 432 cpu_types[] = 433 { 434 { "arc600", ARC_OPCODE_ARC600, bfd_mach_arc_arc600, 435 E_ARC_MACH_ARC600, 0x00}, 436 { "arc700", ARC_OPCODE_ARC700, bfd_mach_arc_arc700, 437 E_ARC_MACH_ARC700, 0x00}, 438 { "nps400", ARC_OPCODE_ARC700 , bfd_mach_arc_arc700, 439 E_ARC_MACH_ARC700, ARC_NPS400}, 440 { "arcem", ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2, 441 EF_ARC_CPU_ARCV2EM, 0x00}, 442 { "archs", ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2, 443 EF_ARC_CPU_ARCV2HS, ARC_CD}, 444 { 0, 0, 0, 0, 0 } 445 }; 446 447 /* Used by the arc_reloc_op table. Order is important. */ 448 #define O_gotoff O_md1 /* @gotoff relocation. */ 449 #define O_gotpc O_md2 /* @gotpc relocation. */ 450 #define O_plt O_md3 /* @plt relocation. */ 451 #define O_sda O_md4 /* @sda relocation. */ 452 #define O_pcl O_md5 /* @pcl relocation. */ 453 #define O_tlsgd O_md6 /* @tlsgd relocation. */ 454 #define O_tlsie O_md7 /* @tlsie relocation. */ 455 #define O_tpoff9 O_md8 /* @tpoff9 relocation. */ 456 #define O_tpoff O_md9 /* @tpoff relocation. */ 457 #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */ 458 #define O_dtpoff O_md11 /* @dtpoff relocation. */ 459 #define O_last O_dtpoff 460 461 /* Used to define a bracket as operand in tokens. */ 462 #define O_bracket O_md32 463 464 /* Dummy relocation, to be sorted out. */ 465 #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1) 466 467 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last) 468 469 /* A table to map the spelling of a relocation operand into an appropriate 470 bfd_reloc_code_real_type type. The table is assumed to be ordered such 471 that op-O_literal indexes into it. */ 472 #define ARC_RELOC_TABLE(op) \ 473 (&arc_reloc_op[ ((!USER_RELOC_P (op)) \ 474 ? (abort (), 0) \ 475 : (int) (op) - (int) O_gotoff) ]) 476 477 #define DEF(NAME, RELOC, REQ) \ 478 { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ} 479 480 static const struct arc_reloc_op_tag 481 { 482 /* String to lookup. */ 483 const char *name; 484 /* Size of the string. */ 485 size_t length; 486 /* Which operator to use. */ 487 operatorT op; 488 extended_bfd_reloc_code_real_type reloc; 489 /* Allows complex relocation expression like identifier@reloc + 490 const. */ 491 unsigned int complex_expr : 1; 492 } 493 arc_reloc_op[] = 494 { 495 DEF (gotoff, BFD_RELOC_ARC_GOTOFF, 1), 496 DEF (gotpc, BFD_RELOC_ARC_GOTPC32, 0), 497 DEF (plt, BFD_RELOC_ARC_PLT32, 0), 498 DEF (sda, DUMMY_RELOC_ARC_ENTRY, 1), 499 DEF (pcl, BFD_RELOC_ARC_PC32, 1), 500 DEF (tlsgd, BFD_RELOC_ARC_TLS_GD_GOT, 0), 501 DEF (tlsie, BFD_RELOC_ARC_TLS_IE_GOT, 0), 502 DEF (tpoff9, BFD_RELOC_ARC_TLS_LE_S9, 0), 503 DEF (tpoff, BFD_RELOC_ARC_TLS_LE_32, 1), 504 DEF (dtpoff9, BFD_RELOC_ARC_TLS_DTPOFF_S9, 0), 505 DEF (dtpoff, BFD_RELOC_ARC_TLS_DTPOFF, 0), 506 }; 507 508 static const int arc_num_reloc_op 509 = sizeof (arc_reloc_op) / sizeof (*arc_reloc_op); 510 511 /* Structure for relaxable instruction that have to be swapped with a 512 smaller alternative instruction. */ 513 struct arc_relaxable_ins 514 { 515 /* Mnemonic that should be checked. */ 516 const char *mnemonic_r; 517 518 /* Operands that should be checked. 519 Indexes of operands from operand array. */ 520 enum rlx_operand_type operands[6]; 521 522 /* Flags that should be checked. */ 523 unsigned flag_classes[5]; 524 525 /* Mnemonic (smaller) alternative to be used later for relaxation. */ 526 const char *mnemonic_alt; 527 528 /* Index of operand that generic relaxation has to check. */ 529 unsigned opcheckidx; 530 531 /* Base subtype index used. */ 532 enum arc_rlx_types subtype; 533 }; 534 535 #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT) \ 536 { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1), \ 537 (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0, \ 538 (SIZE), \ 539 (NEXT) } \ 540 541 #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT) \ 542 { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF, \ 543 (ISSIGNED) ? -(0x7FFFFFFF) : 0, \ 544 (SIZE), \ 545 (NEXT) } \ 546 547 548 /* ARC relaxation table. */ 549 const relax_typeS md_relax_table[] = 550 { 551 /* Fake entry. */ 552 {0, 0, 0, 0}, 553 554 /* BL_S s13 -> 555 BL s25. */ 556 RELAX_TABLE_ENTRY(13, 1, 2, ARC_RLX_BL), 557 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE), 558 559 /* B_S s10 -> 560 B s25. */ 561 RELAX_TABLE_ENTRY(10, 1, 2, ARC_RLX_B), 562 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE), 563 564 /* ADD_S c,b, u3 -> 565 ADD<.f> a,b,u6 -> 566 ADD<.f> a,b,limm. */ 567 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_ADD_U6), 568 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_LIMM), 569 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE), 570 571 /* LD_S a, [b, u7] -> 572 LD<zz><.x><.aa><.di> a, [b, s9] -> 573 LD<zz><.x><.aa><.di> a, [b, limm] */ 574 RELAX_TABLE_ENTRY(7, 0, 2, ARC_RLX_LD_S9), 575 RELAX_TABLE_ENTRY(9, 1, 4, ARC_RLX_LD_LIMM), 576 RELAX_TABLE_ENTRY_MAX(1, 8, ARC_RLX_NONE), 577 578 /* MOV_S b, u8 -> 579 MOV<.f> b, s12 -> 580 MOV<.f> b, limm. */ 581 RELAX_TABLE_ENTRY(8, 0, 2, ARC_RLX_MOV_S12), 582 RELAX_TABLE_ENTRY(8, 0, 4, ARC_RLX_MOV_LIMM), 583 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE), 584 585 /* SUB_S c, b, u3 -> 586 SUB<.f> a, b, u6 -> 587 SUB<.f> a, b, limm. */ 588 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_SUB_U6), 589 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_SUB_LIMM), 590 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE), 591 592 /* MPY<.f> a, b, u6 -> 593 MPY<.f> a, b, limm. */ 594 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MPY_LIMM), 595 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE), 596 597 /* MOV<.f><.cc> b, u6 -> 598 MOV<.f><.cc> b, limm. */ 599 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MOV_RLIMM), 600 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE), 601 602 /* ADD<.f><.cc> b, b, u6 -> 603 ADD<.f><.cc> b, b, limm. */ 604 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_RRLIMM), 605 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE), 606 }; 607 608 /* Order of this table's entries matters! */ 609 const struct arc_relaxable_ins arc_relaxable_insns[] = 610 { 611 { "bl", { IMMEDIATE }, { 0 }, "bl_s", 0, ARC_RLX_BL_S }, 612 { "b", { IMMEDIATE }, { 0 }, "b_s", 0, ARC_RLX_B_S }, 613 { "add", { REGISTER, REGISTER_DUP, IMMEDIATE }, { 5, 1, 0 }, "add", 614 2, ARC_RLX_ADD_RRU6}, 615 { "add", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "add_s", 2, 616 ARC_RLX_ADD_U3 }, 617 { "add", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "add", 2, 618 ARC_RLX_ADD_U6 }, 619 { "ld", { REGISTER_S, BRACKET, REGISTER_S, IMMEDIATE, BRACKET }, 620 { 0 }, "ld_s", 3, ARC_RLX_LD_U7 }, 621 { "ld", { REGISTER, BRACKET, REGISTER_NO_GP, IMMEDIATE, BRACKET }, 622 { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9 }, 623 { "mov", { REGISTER_S, IMMEDIATE }, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8 }, 624 { "mov", { REGISTER, IMMEDIATE }, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12 }, 625 { "mov", { REGISTER, IMMEDIATE }, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6 }, 626 { "sub", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "sub_s", 2, 627 ARC_RLX_SUB_U3 }, 628 { "sub", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "sub", 2, 629 ARC_RLX_SUB_U6 }, 630 { "mpy", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "mpy", 2, 631 ARC_RLX_MPY_U6 }, 632 }; 633 634 const unsigned arc_num_relaxable_ins = ARRAY_SIZE (arc_relaxable_insns); 635 636 /* Flags to set in the elf header. */ 637 static flagword arc_eflag = 0x00; 638 639 /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */ 640 symbolS * GOT_symbol = 0; 641 642 /* Set to TRUE when we assemble instructions. */ 643 static bfd_boolean assembling_insn = FALSE; 644 645 /* Functions implementation. */ 646 647 /* Return a pointer to ARC_OPCODE_HASH_ENTRY that identifies all 648 ARC_OPCODE entries in ARC_OPCODE_HASH that match NAME, or NULL if there 649 are no matching entries in ARC_OPCODE_HASH. */ 650 651 static const struct arc_opcode_hash_entry * 652 arc_find_opcode (const char *name) 653 { 654 const struct arc_opcode_hash_entry *entry; 655 656 entry = hash_find (arc_opcode_hash, name); 657 return entry; 658 } 659 660 /* Initialise the iterator ITER. */ 661 662 static void 663 arc_opcode_hash_entry_iterator_init (struct arc_opcode_hash_entry_iterator *iter) 664 { 665 iter->index = 0; 666 iter->opcode = NULL; 667 } 668 669 /* Return the next ARC_OPCODE from ENTRY, using ITER to hold state between 670 calls to this function. Return NULL when all ARC_OPCODE entries have 671 been returned. */ 672 673 static const struct arc_opcode * 674 arc_opcode_hash_entry_iterator_next (const struct arc_opcode_hash_entry *entry, 675 struct arc_opcode_hash_entry_iterator *iter) 676 { 677 if (iter->opcode == NULL && iter->index == 0) 678 { 679 gas_assert (entry->count > 0); 680 iter->opcode = entry->opcode[iter->index]; 681 } 682 else if (iter->opcode != NULL) 683 { 684 const char *old_name = iter->opcode->name; 685 686 iter->opcode++; 687 if (iter->opcode->name == NULL 688 || strcmp (old_name, iter->opcode->name) != 0) 689 { 690 iter->index++; 691 if (iter->index == entry->count) 692 iter->opcode = NULL; 693 else 694 iter->opcode = entry->opcode[iter->index]; 695 } 696 } 697 698 return iter->opcode; 699 } 700 701 /* Insert an opcode into opcode hash structure. */ 702 703 static void 704 arc_insert_opcode (const struct arc_opcode *opcode) 705 { 706 const char *name, *retval; 707 struct arc_opcode_hash_entry *entry; 708 name = opcode->name; 709 710 entry = hash_find (arc_opcode_hash, name); 711 if (entry == NULL) 712 { 713 entry = XNEW (struct arc_opcode_hash_entry); 714 entry->count = 0; 715 entry->opcode = NULL; 716 717 retval = hash_insert (arc_opcode_hash, name, (void *) entry); 718 if (retval) 719 as_fatal (_("internal error: can't hash opcode '%s': %s"), 720 name, retval); 721 } 722 723 entry->opcode = XRESIZEVEC (const struct arc_opcode *, entry->opcode, 724 entry->count + 1); 725 726 if (entry->opcode == NULL) 727 as_fatal (_("Virtual memory exhausted")); 728 729 entry->opcode[entry->count] = opcode; 730 entry->count++; 731 } 732 733 734 /* Like md_number_to_chars but used for limms. The 4-byte limm value, 735 is encoded as 'middle-endian' for a little-endian target. FIXME! 736 this function is used for regular 4 byte instructions as well. */ 737 738 static void 739 md_number_to_chars_midend (char *buf, valueT val, int n) 740 { 741 if (n == 4) 742 { 743 md_number_to_chars (buf, (val & 0xffff0000) >> 16, 2); 744 md_number_to_chars (buf + 2, (val & 0xffff), 2); 745 } 746 else 747 { 748 md_number_to_chars (buf, val, n); 749 } 750 } 751 752 /* Select an appropriate entry from CPU_TYPES based on ARG and initialise 753 the relevant static global variables. */ 754 755 static void 756 arc_select_cpu (const char *arg) 757 { 758 int cpu_flags = 0; 759 int i; 760 761 for (i = 0; cpu_types[i].name; ++i) 762 { 763 if (!strcasecmp (cpu_types[i].name, arg)) 764 { 765 arc_target = cpu_types[i].flags; 766 arc_target_name = cpu_types[i].name; 767 arc_features = cpu_types[i].features; 768 arc_mach_type = cpu_types[i].mach; 769 cpu_flags = cpu_types[i].eflags; 770 break; 771 } 772 } 773 774 if (!cpu_types[i].name) 775 as_fatal (_("unknown architecture: %s\n"), arg); 776 gas_assert (cpu_flags != 0); 777 arc_eflag = (arc_eflag & ~EF_ARC_MACH_MSK) | cpu_flags; 778 } 779 780 /* Here ends all the ARCompact extension instruction assembling 781 stuff. */ 782 783 static void 784 arc_extra_reloc (int r_type) 785 { 786 char *sym_name, c; 787 symbolS *sym, *lab = NULL; 788 789 if (*input_line_pointer == '@') 790 input_line_pointer++; 791 c = get_symbol_name (&sym_name); 792 sym = symbol_find_or_make (sym_name); 793 restore_line_pointer (c); 794 if (c == ',' && r_type == BFD_RELOC_ARC_TLS_GD_LD) 795 { 796 ++input_line_pointer; 797 char *lab_name; 798 c = get_symbol_name (&lab_name); 799 lab = symbol_find_or_make (lab_name); 800 restore_line_pointer (c); 801 } 802 803 /* These relocations exist as a mechanism for the compiler to tell the 804 linker how to patch the code if the tls model is optimised. However, 805 the relocation itself does not require any space within the assembler 806 fragment, and so we pass a size of 0. 807 808 The lines that generate these relocations look like this: 809 810 .tls_gd_ld @.tdata`bl __tls_get_addr@plt 811 812 The '.tls_gd_ld @.tdata' is processed first and generates the 813 additional relocation, while the 'bl __tls_get_addr@plt' is processed 814 second and generates the additional branch. 815 816 It is possible that the additional relocation generated by the 817 '.tls_gd_ld @.tdata' will be attached at the very end of one fragment, 818 while the 'bl __tls_get_addr@plt' will be generated as the first thing 819 in the next fragment. This will be fine; both relocations will still 820 appear to be at the same address in the generated object file. 821 However, this only works as the additional relocation is generated 822 with size of 0 bytes. */ 823 fixS *fixP 824 = fix_new (frag_now, /* Which frag? */ 825 frag_now_fix (), /* Where in that frag? */ 826 0, /* size: 1, 2, or 4 usually. */ 827 sym, /* X_add_symbol. */ 828 0, /* X_add_number. */ 829 FALSE, /* TRUE if PC-relative relocation. */ 830 r_type /* Relocation type. */); 831 fixP->fx_subsy = lab; 832 } 833 834 static symbolS * 835 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED, 836 symbolS *symbolP, addressT size) 837 { 838 addressT align = 0; 839 SKIP_WHITESPACE (); 840 841 if (*input_line_pointer == ',') 842 { 843 align = parse_align (1); 844 845 if (align == (addressT) -1) 846 return NULL; 847 } 848 else 849 { 850 if (size >= 8) 851 align = 3; 852 else if (size >= 4) 853 align = 2; 854 else if (size >= 2) 855 align = 1; 856 else 857 align = 0; 858 } 859 860 bss_alloc (symbolP, size, align); 861 S_CLEAR_EXTERNAL (symbolP); 862 863 return symbolP; 864 } 865 866 static void 867 arc_lcomm (int ignore) 868 { 869 symbolS *symbolP = s_comm_internal (ignore, arc_lcomm_internal); 870 871 if (symbolP) 872 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; 873 } 874 875 /* Select the cpu we're assembling for. */ 876 877 static void 878 arc_option (int ignore ATTRIBUTE_UNUSED) 879 { 880 int mach = -1; 881 char c; 882 char *cpu; 883 884 c = get_symbol_name (&cpu); 885 mach = arc_get_mach (cpu); 886 887 if (mach == -1) 888 goto bad_cpu; 889 890 if (!mach_type_specified_p) 891 { 892 if ((!strcmp ("ARC600", cpu)) 893 || (!strcmp ("ARC601", cpu)) 894 || (!strcmp ("A6", cpu))) 895 { 896 md_parse_option (OPTION_MCPU, "arc600"); 897 } 898 else if ((!strcmp ("ARC700", cpu)) 899 || (!strcmp ("A7", cpu))) 900 { 901 md_parse_option (OPTION_MCPU, "arc700"); 902 } 903 else if (!strcmp ("EM", cpu)) 904 { 905 md_parse_option (OPTION_MCPU, "arcem"); 906 } 907 else if (!strcmp ("HS", cpu)) 908 { 909 md_parse_option (OPTION_MCPU, "archs"); 910 } 911 else if (!strcmp ("NPS400", cpu)) 912 { 913 md_parse_option (OPTION_MCPU, "nps400"); 914 } 915 else 916 as_fatal (_("could not find the architecture")); 917 918 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach)) 919 as_fatal (_("could not set architecture and machine")); 920 921 /* Set elf header flags. */ 922 bfd_set_private_flags (stdoutput, arc_eflag); 923 } 924 else 925 if (arc_mach_type != mach) 926 as_warn (_("Command-line value overrides \".cpu\" directive")); 927 928 restore_line_pointer (c); 929 demand_empty_rest_of_line (); 930 return; 931 932 bad_cpu: 933 restore_line_pointer (c); 934 as_bad (_("invalid identifier for \".cpu\"")); 935 ignore_rest_of_line (); 936 } 937 938 /* Smartly print an expression. */ 939 940 static void 941 debug_exp (expressionS *t) 942 { 943 const char *name ATTRIBUTE_UNUSED; 944 const char *namemd ATTRIBUTE_UNUSED; 945 946 pr_debug ("debug_exp: "); 947 948 switch (t->X_op) 949 { 950 default: name = "unknown"; break; 951 case O_illegal: name = "O_illegal"; break; 952 case O_absent: name = "O_absent"; break; 953 case O_constant: name = "O_constant"; break; 954 case O_symbol: name = "O_symbol"; break; 955 case O_symbol_rva: name = "O_symbol_rva"; break; 956 case O_register: name = "O_register"; break; 957 case O_big: name = "O_big"; break; 958 case O_uminus: name = "O_uminus"; break; 959 case O_bit_not: name = "O_bit_not"; break; 960 case O_logical_not: name = "O_logical_not"; break; 961 case O_multiply: name = "O_multiply"; break; 962 case O_divide: name = "O_divide"; break; 963 case O_modulus: name = "O_modulus"; break; 964 case O_left_shift: name = "O_left_shift"; break; 965 case O_right_shift: name = "O_right_shift"; break; 966 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break; 967 case O_bit_or_not: name = "O_bit_or_not"; break; 968 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break; 969 case O_bit_and: name = "O_bit_and"; break; 970 case O_add: name = "O_add"; break; 971 case O_subtract: name = "O_subtract"; break; 972 case O_eq: name = "O_eq"; break; 973 case O_ne: name = "O_ne"; break; 974 case O_lt: name = "O_lt"; break; 975 case O_le: name = "O_le"; break; 976 case O_ge: name = "O_ge"; break; 977 case O_gt: name = "O_gt"; break; 978 case O_logical_and: name = "O_logical_and"; break; 979 case O_logical_or: name = "O_logical_or"; break; 980 case O_index: name = "O_index"; break; 981 case O_bracket: name = "O_bracket"; break; 982 } 983 984 switch (t->X_md) 985 { 986 default: namemd = "unknown"; break; 987 case O_gotoff: namemd = "O_gotoff"; break; 988 case O_gotpc: namemd = "O_gotpc"; break; 989 case O_plt: namemd = "O_plt"; break; 990 case O_sda: namemd = "O_sda"; break; 991 case O_pcl: namemd = "O_pcl"; break; 992 case O_tlsgd: namemd = "O_tlsgd"; break; 993 case O_tlsie: namemd = "O_tlsie"; break; 994 case O_tpoff9: namemd = "O_tpoff9"; break; 995 case O_tpoff: namemd = "O_tpoff"; break; 996 case O_dtpoff9: namemd = "O_dtpoff9"; break; 997 case O_dtpoff: namemd = "O_dtpoff"; break; 998 } 999 1000 pr_debug ("%s (%s, %s, %d, %s)", name, 1001 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--", 1002 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--", 1003 (int) t->X_add_number, 1004 (t->X_md) ? namemd : "--"); 1005 pr_debug ("\n"); 1006 fflush (stderr); 1007 } 1008 1009 /* Parse the arguments to an opcode. */ 1010 1011 static int 1012 tokenize_arguments (char *str, 1013 expressionS *tok, 1014 int ntok) 1015 { 1016 char *old_input_line_pointer; 1017 bfd_boolean saw_comma = FALSE; 1018 bfd_boolean saw_arg = FALSE; 1019 int brk_lvl = 0; 1020 int num_args = 0; 1021 int i; 1022 size_t len; 1023 const struct arc_reloc_op_tag *r; 1024 expressionS tmpE; 1025 char *reloc_name, c; 1026 1027 memset (tok, 0, sizeof (*tok) * ntok); 1028 1029 /* Save and restore input_line_pointer around this function. */ 1030 old_input_line_pointer = input_line_pointer; 1031 input_line_pointer = str; 1032 1033 while (*input_line_pointer) 1034 { 1035 SKIP_WHITESPACE (); 1036 switch (*input_line_pointer) 1037 { 1038 case '\0': 1039 goto fini; 1040 1041 case ',': 1042 input_line_pointer++; 1043 if (saw_comma || !saw_arg) 1044 goto err; 1045 saw_comma = TRUE; 1046 break; 1047 1048 case '}': 1049 case ']': 1050 ++input_line_pointer; 1051 --brk_lvl; 1052 if (!saw_arg || num_args == ntok) 1053 goto err; 1054 tok->X_op = O_bracket; 1055 ++tok; 1056 ++num_args; 1057 break; 1058 1059 case '{': 1060 case '[': 1061 input_line_pointer++; 1062 if (brk_lvl || num_args == ntok) 1063 goto err; 1064 ++brk_lvl; 1065 tok->X_op = O_bracket; 1066 ++tok; 1067 ++num_args; 1068 break; 1069 1070 case '@': 1071 /* We have labels, function names and relocations, all 1072 starting with @ symbol. Sort them out. */ 1073 if ((saw_arg && !saw_comma) || num_args == ntok) 1074 goto err; 1075 1076 /* Parse @label. */ 1077 tok->X_op = O_symbol; 1078 tok->X_md = O_absent; 1079 expression (tok); 1080 if (*input_line_pointer != '@') 1081 goto normalsymbol; /* This is not a relocation. */ 1082 1083 relocationsym: 1084 1085 /* A relocation opernad has the following form 1086 @identifier@relocation_type. The identifier is already 1087 in tok! */ 1088 if (tok->X_op != O_symbol) 1089 { 1090 as_bad (_("No valid label relocation operand")); 1091 goto err; 1092 } 1093 1094 /* Parse @relocation_type. */ 1095 input_line_pointer++; 1096 c = get_symbol_name (&reloc_name); 1097 len = input_line_pointer - reloc_name; 1098 if (len == 0) 1099 { 1100 as_bad (_("No relocation operand")); 1101 goto err; 1102 } 1103 1104 /* Go through known relocation and try to find a match. */ 1105 r = &arc_reloc_op[0]; 1106 for (i = arc_num_reloc_op - 1; i >= 0; i--, r++) 1107 if (len == r->length 1108 && memcmp (reloc_name, r->name, len) == 0) 1109 break; 1110 if (i < 0) 1111 { 1112 as_bad (_("Unknown relocation operand: @%s"), reloc_name); 1113 goto err; 1114 } 1115 1116 *input_line_pointer = c; 1117 SKIP_WHITESPACE_AFTER_NAME (); 1118 /* Extra check for TLS: base. */ 1119 if (*input_line_pointer == '@') 1120 { 1121 symbolS *base; 1122 if (tok->X_op_symbol != NULL 1123 || tok->X_op != O_symbol) 1124 { 1125 as_bad (_("Unable to parse TLS base: %s"), 1126 input_line_pointer); 1127 goto err; 1128 } 1129 input_line_pointer++; 1130 char *sym_name; 1131 c = get_symbol_name (&sym_name); 1132 base = symbol_find_or_make (sym_name); 1133 tok->X_op = O_subtract; 1134 tok->X_op_symbol = base; 1135 restore_line_pointer (c); 1136 tmpE.X_add_number = 0; 1137 } 1138 else if ((*input_line_pointer != '+') 1139 && (*input_line_pointer != '-')) 1140 { 1141 tmpE.X_add_number = 0; 1142 } 1143 else 1144 { 1145 /* Parse the constant of a complex relocation expression 1146 like @identifier@reloc +/- const. */ 1147 if (! r->complex_expr) 1148 { 1149 as_bad (_("@%s is not a complex relocation."), r->name); 1150 goto err; 1151 } 1152 expression (&tmpE); 1153 if (tmpE.X_op != O_constant) 1154 { 1155 as_bad (_("Bad expression: @%s + %s."), 1156 r->name, input_line_pointer); 1157 goto err; 1158 } 1159 } 1160 1161 tok->X_md = r->op; 1162 tok->X_add_number = tmpE.X_add_number; 1163 1164 debug_exp (tok); 1165 1166 saw_comma = FALSE; 1167 saw_arg = TRUE; 1168 tok++; 1169 num_args++; 1170 break; 1171 1172 case '%': 1173 /* Can be a register. */ 1174 ++input_line_pointer; 1175 /* Fall through. */ 1176 default: 1177 1178 if ((saw_arg && !saw_comma) || num_args == ntok) 1179 goto err; 1180 1181 tok->X_op = O_absent; 1182 tok->X_md = O_absent; 1183 expression (tok); 1184 1185 /* Legacy: There are cases when we have 1186 identifier@relocation_type, if it is the case parse the 1187 relocation type as well. */ 1188 if (*input_line_pointer == '@') 1189 goto relocationsym; 1190 1191 normalsymbol: 1192 debug_exp (tok); 1193 1194 if (tok->X_op == O_illegal 1195 || tok->X_op == O_absent 1196 || num_args == ntok) 1197 goto err; 1198 1199 saw_comma = FALSE; 1200 saw_arg = TRUE; 1201 tok++; 1202 num_args++; 1203 break; 1204 } 1205 } 1206 1207 fini: 1208 if (saw_comma || brk_lvl) 1209 goto err; 1210 input_line_pointer = old_input_line_pointer; 1211 1212 return num_args; 1213 1214 err: 1215 if (brk_lvl) 1216 as_bad (_("Brackets in operand field incorrect")); 1217 else if (saw_comma) 1218 as_bad (_("extra comma")); 1219 else if (!saw_arg) 1220 as_bad (_("missing argument")); 1221 else 1222 as_bad (_("missing comma or colon")); 1223 input_line_pointer = old_input_line_pointer; 1224 return -1; 1225 } 1226 1227 /* Parse the flags to a structure. */ 1228 1229 static int 1230 tokenize_flags (const char *str, 1231 struct arc_flags flags[], 1232 int nflg) 1233 { 1234 char *old_input_line_pointer; 1235 bfd_boolean saw_flg = FALSE; 1236 bfd_boolean saw_dot = FALSE; 1237 int num_flags = 0; 1238 size_t flgnamelen; 1239 1240 memset (flags, 0, sizeof (*flags) * nflg); 1241 1242 /* Save and restore input_line_pointer around this function. */ 1243 old_input_line_pointer = input_line_pointer; 1244 input_line_pointer = (char *) str; 1245 1246 while (*input_line_pointer) 1247 { 1248 switch (*input_line_pointer) 1249 { 1250 case ' ': 1251 case '\0': 1252 goto fini; 1253 1254 case '.': 1255 input_line_pointer++; 1256 if (saw_dot) 1257 goto err; 1258 saw_dot = TRUE; 1259 saw_flg = FALSE; 1260 break; 1261 1262 default: 1263 if (saw_flg && !saw_dot) 1264 goto err; 1265 1266 if (num_flags >= nflg) 1267 goto err; 1268 1269 flgnamelen = strspn (input_line_pointer, 1270 "abcdefghijklmnopqrstuvwxyz0123456789"); 1271 if (flgnamelen > MAX_FLAG_NAME_LENGTH) 1272 goto err; 1273 1274 memcpy (flags->name, input_line_pointer, flgnamelen); 1275 1276 input_line_pointer += flgnamelen; 1277 flags++; 1278 saw_dot = FALSE; 1279 saw_flg = TRUE; 1280 num_flags++; 1281 break; 1282 } 1283 } 1284 1285 fini: 1286 input_line_pointer = old_input_line_pointer; 1287 return num_flags; 1288 1289 err: 1290 if (saw_dot) 1291 as_bad (_("extra dot")); 1292 else if (!saw_flg) 1293 as_bad (_("unrecognized flag")); 1294 else 1295 as_bad (_("failed to parse flags")); 1296 input_line_pointer = old_input_line_pointer; 1297 return -1; 1298 } 1299 1300 /* Apply the fixups in order. */ 1301 1302 static void 1303 apply_fixups (struct arc_insn *insn, fragS *fragP, int fix) 1304 { 1305 int i; 1306 1307 for (i = 0; i < insn->nfixups; i++) 1308 { 1309 struct arc_fixup *fixup = &insn->fixups[i]; 1310 int size, pcrel, offset = 0; 1311 1312 /* FIXME! the reloc size is wrong in the BFD file. 1313 When it is fixed please delete me. */ 1314 size = (insn->short_insn && !fixup->islong) ? 2 : 4; 1315 1316 if (fixup->islong) 1317 offset = (insn->short_insn) ? 2 : 4; 1318 1319 /* Some fixups are only used internally, thus no howto. */ 1320 if ((int) fixup->reloc == 0) 1321 as_fatal (_("Unhandled reloc type")); 1322 1323 if ((int) fixup->reloc < 0) 1324 { 1325 /* FIXME! the reloc size is wrong in the BFD file. 1326 When it is fixed please enable me. 1327 size = (insn->short_insn && !fixup->islong) ? 2 : 4; */ 1328 pcrel = fixup->pcrel; 1329 } 1330 else 1331 { 1332 reloc_howto_type *reloc_howto = 1333 bfd_reloc_type_lookup (stdoutput, 1334 (bfd_reloc_code_real_type) fixup->reloc); 1335 gas_assert (reloc_howto); 1336 1337 /* FIXME! the reloc size is wrong in the BFD file. 1338 When it is fixed please enable me. 1339 size = bfd_get_reloc_size (reloc_howto); */ 1340 pcrel = reloc_howto->pc_relative; 1341 } 1342 1343 pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \ 1344 offset %d + %d\n", 1345 fragP->fr_file, fragP->fr_line, 1346 (fixup->reloc < 0) ? "Internal" : 1347 bfd_get_reloc_code_name (fixup->reloc), 1348 pcrel ? "Y" : "N", 1349 size, fix, offset); 1350 fix_new_exp (fragP, fix + offset, 1351 size, &fixup->exp, pcrel, fixup->reloc); 1352 1353 /* Check for ZOLs, and update symbol info if any. */ 1354 if (LP_INSN (insn->insn)) 1355 { 1356 gas_assert (fixup->exp.X_add_symbol); 1357 ARC_SET_FLAG (fixup->exp.X_add_symbol, ARC_FLAG_ZOL); 1358 } 1359 } 1360 } 1361 1362 /* Actually output an instruction with its fixup. */ 1363 1364 static void 1365 emit_insn0 (struct arc_insn *insn, char *where, bfd_boolean relax) 1366 { 1367 char *f = where; 1368 1369 pr_debug ("Emit insn : 0x%x\n", insn->insn); 1370 pr_debug ("\tShort : 0x%d\n", insn->short_insn); 1371 pr_debug ("\tLong imm: 0x%lx\n", insn->limm); 1372 1373 /* Write out the instruction. */ 1374 if (insn->short_insn) 1375 { 1376 if (insn->has_limm) 1377 { 1378 if (!relax) 1379 f = frag_more (6); 1380 md_number_to_chars (f, insn->insn, 2); 1381 md_number_to_chars_midend (f + 2, insn->limm, 4); 1382 dwarf2_emit_insn (6); 1383 } 1384 else 1385 { 1386 if (!relax) 1387 f = frag_more (2); 1388 md_number_to_chars (f, insn->insn, 2); 1389 dwarf2_emit_insn (2); 1390 } 1391 } 1392 else 1393 { 1394 if (insn->has_limm) 1395 { 1396 if (!relax) 1397 f = frag_more (8); 1398 md_number_to_chars_midend (f, insn->insn, 4); 1399 md_number_to_chars_midend (f + 4, insn->limm, 4); 1400 dwarf2_emit_insn (8); 1401 } 1402 else 1403 { 1404 if (!relax) 1405 f = frag_more (4); 1406 md_number_to_chars_midend (f, insn->insn, 4); 1407 dwarf2_emit_insn (4); 1408 } 1409 } 1410 1411 if (!relax) 1412 apply_fixups (insn, frag_now, (f - frag_now->fr_literal)); 1413 } 1414 1415 static void 1416 emit_insn1 (struct arc_insn *insn) 1417 { 1418 /* How frag_var's args are currently configured: 1419 - rs_machine_dependent, to dictate it's a relaxation frag. 1420 - FRAG_MAX_GROWTH, maximum size of instruction 1421 - 0, variable size that might grow...unused by generic relaxation. 1422 - frag_now->fr_subtype, fr_subtype starting value, set previously. 1423 - s, opand expression. 1424 - 0, offset but it's unused. 1425 - 0, opcode but it's unused. */ 1426 symbolS *s = make_expr_symbol (&insn->fixups[0].exp); 1427 frag_now->tc_frag_data.pcrel = insn->fixups[0].pcrel; 1428 1429 if (frag_room () < FRAG_MAX_GROWTH) 1430 { 1431 /* Handle differently when frag literal memory is exhausted. 1432 This is used because when there's not enough memory left in 1433 the current frag, a new frag is created and the information 1434 we put into frag_now->tc_frag_data is disregarded. */ 1435 1436 struct arc_relax_type relax_info_copy; 1437 relax_substateT subtype = frag_now->fr_subtype; 1438 1439 memcpy (&relax_info_copy, &frag_now->tc_frag_data, 1440 sizeof (struct arc_relax_type)); 1441 1442 frag_wane (frag_now); 1443 frag_grow (FRAG_MAX_GROWTH); 1444 1445 memcpy (&frag_now->tc_frag_data, &relax_info_copy, 1446 sizeof (struct arc_relax_type)); 1447 1448 frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0, 1449 subtype, s, 0, 0); 1450 } 1451 else 1452 frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0, 1453 frag_now->fr_subtype, s, 0, 0); 1454 } 1455 1456 static void 1457 emit_insn (struct arc_insn *insn) 1458 { 1459 if (insn->relax) 1460 emit_insn1 (insn); 1461 else 1462 emit_insn0 (insn, NULL, FALSE); 1463 } 1464 1465 /* Check whether a symbol involves a register. */ 1466 1467 static bfd_boolean 1468 contains_register (symbolS *sym) 1469 { 1470 if (sym) 1471 { 1472 expressionS *ex = symbol_get_value_expression (sym); 1473 1474 return ((O_register == ex->X_op) 1475 && !contains_register (ex->X_add_symbol) 1476 && !contains_register (ex->X_op_symbol)); 1477 } 1478 1479 return FALSE; 1480 } 1481 1482 /* Returns the register number within a symbol. */ 1483 1484 static int 1485 get_register (symbolS *sym) 1486 { 1487 if (!contains_register (sym)) 1488 return -1; 1489 1490 expressionS *ex = symbol_get_value_expression (sym); 1491 return regno (ex->X_add_number); 1492 } 1493 1494 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a 1495 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */ 1496 1497 static bfd_boolean 1498 generic_reloc_p (extended_bfd_reloc_code_real_type reloc) 1499 { 1500 if (!reloc) 1501 return FALSE; 1502 1503 switch (reloc) 1504 { 1505 case BFD_RELOC_ARC_SDA_LDST: 1506 case BFD_RELOC_ARC_SDA_LDST1: 1507 case BFD_RELOC_ARC_SDA_LDST2: 1508 case BFD_RELOC_ARC_SDA16_LD: 1509 case BFD_RELOC_ARC_SDA16_LD1: 1510 case BFD_RELOC_ARC_SDA16_LD2: 1511 case BFD_RELOC_ARC_SDA16_ST2: 1512 case BFD_RELOC_ARC_SDA32_ME: 1513 return FALSE; 1514 default: 1515 return TRUE; 1516 } 1517 } 1518 1519 /* Allocates a tok entry. */ 1520 1521 static int 1522 allocate_tok (expressionS *tok, int ntok, int cidx) 1523 { 1524 if (ntok > MAX_INSN_ARGS - 2) 1525 return 0; /* No space left. */ 1526 1527 if (cidx > ntok) 1528 return 0; /* Incorect args. */ 1529 1530 memcpy (&tok[ntok+1], &tok[ntok], sizeof (*tok)); 1531 1532 if (cidx == ntok) 1533 return 1; /* Success. */ 1534 return allocate_tok (tok, ntok - 1, cidx); 1535 } 1536 1537 /* Check if an particular ARC feature is enabled. */ 1538 1539 static bfd_boolean 1540 check_cpu_feature (insn_subclass_t sc) 1541 { 1542 if (is_code_density_p (sc) && !(arc_features & ARC_CD)) 1543 return FALSE; 1544 1545 if (is_spfp_p (sc) && !(arc_features & ARC_SPFP)) 1546 return FALSE; 1547 1548 if (is_dpfp_p (sc) && !(arc_features & ARC_DPFP)) 1549 return FALSE; 1550 1551 if (is_fpuda_p (sc) && !(arc_features & ARC_FPUDA)) 1552 return FALSE; 1553 1554 if (is_nps400_p (sc) && !(arc_features & ARC_NPS400)) 1555 return FALSE; 1556 1557 return TRUE; 1558 } 1559 1560 /* Parse the flags described by FIRST_PFLAG and NFLGS against the flag 1561 operands in OPCODE. Stores the matching OPCODES into the FIRST_PFLAG 1562 array and returns TRUE if the flag operands all match, otherwise, 1563 returns FALSE, in which case the FIRST_PFLAG array may have been 1564 modified. */ 1565 1566 static bfd_boolean 1567 parse_opcode_flags (const struct arc_opcode *opcode, 1568 int nflgs, 1569 struct arc_flags *first_pflag) 1570 { 1571 int lnflg, i; 1572 const unsigned char *flgidx; 1573 1574 lnflg = nflgs; 1575 for (i = 0; i < nflgs; i++) 1576 first_pflag[i].flgp = NULL; 1577 1578 /* Check the flags. Iterate over the valid flag classes. */ 1579 for (flgidx = opcode->flags; *flgidx; ++flgidx) 1580 { 1581 /* Get a valid flag class. */ 1582 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx]; 1583 const unsigned *flgopridx; 1584 int cl_matches = 0; 1585 struct arc_flags *pflag = NULL; 1586 1587 /* Check for extension conditional codes. */ 1588 if (ext_condcode.arc_ext_condcode 1589 && cl_flags->flag_class & F_CLASS_EXTEND) 1590 { 1591 struct arc_flag_operand *pf = ext_condcode.arc_ext_condcode; 1592 while (pf->name) 1593 { 1594 pflag = first_pflag; 1595 for (i = 0; i < nflgs; i++, pflag++) 1596 { 1597 if (!strcmp (pf->name, pflag->name)) 1598 { 1599 if (pflag->flgp != NULL) 1600 return FALSE; 1601 /* Found it. */ 1602 cl_matches++; 1603 pflag->flgp = pf; 1604 lnflg--; 1605 break; 1606 } 1607 } 1608 pf++; 1609 } 1610 } 1611 1612 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx) 1613 { 1614 const struct arc_flag_operand *flg_operand; 1615 1616 pflag = first_pflag; 1617 flg_operand = &arc_flag_operands[*flgopridx]; 1618 for (i = 0; i < nflgs; i++, pflag++) 1619 { 1620 /* Match against the parsed flags. */ 1621 if (!strcmp (flg_operand->name, pflag->name)) 1622 { 1623 if (pflag->flgp != NULL) 1624 return FALSE; 1625 cl_matches++; 1626 pflag->flgp = flg_operand; 1627 lnflg--; 1628 break; /* goto next flag class and parsed flag. */ 1629 } 1630 } 1631 } 1632 1633 if ((cl_flags->flag_class & F_CLASS_REQUIRED) && cl_matches == 0) 1634 return FALSE; 1635 if ((cl_flags->flag_class & F_CLASS_OPTIONAL) && cl_matches > 1) 1636 return FALSE; 1637 } 1638 1639 /* Did I check all the parsed flags? */ 1640 return lnflg ? FALSE : TRUE; 1641 } 1642 1643 1644 /* Search forward through all variants of an opcode looking for a 1645 syntax match. */ 1646 1647 static const struct arc_opcode * 1648 find_opcode_match (const struct arc_opcode_hash_entry *entry, 1649 expressionS *tok, 1650 int *pntok, 1651 struct arc_flags *first_pflag, 1652 int nflgs, 1653 int *pcpumatch) 1654 { 1655 const struct arc_opcode *opcode; 1656 struct arc_opcode_hash_entry_iterator iter; 1657 int ntok = *pntok; 1658 int got_cpu_match = 0; 1659 expressionS bktok[MAX_INSN_ARGS]; 1660 int bkntok; 1661 expressionS emptyE; 1662 1663 arc_opcode_hash_entry_iterator_init (&iter); 1664 memset (&emptyE, 0, sizeof (emptyE)); 1665 memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok)); 1666 bkntok = ntok; 1667 1668 for (opcode = arc_opcode_hash_entry_iterator_next (entry, &iter); 1669 opcode != NULL; 1670 opcode = arc_opcode_hash_entry_iterator_next (entry, &iter)) 1671 { 1672 const unsigned char *opidx; 1673 int tokidx = 0; 1674 const expressionS *t = &emptyE; 1675 1676 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ", 1677 frag_now->fr_file, frag_now->fr_line, opcode->opcode); 1678 1679 /* Don't match opcodes that don't exist on this 1680 architecture. */ 1681 if (!(opcode->cpu & arc_target)) 1682 goto match_failed; 1683 1684 if (!check_cpu_feature (opcode->subclass)) 1685 goto match_failed; 1686 1687 got_cpu_match = 1; 1688 pr_debug ("cpu "); 1689 1690 /* Check the operands. */ 1691 for (opidx = opcode->operands; *opidx; ++opidx) 1692 { 1693 const struct arc_operand *operand = &arc_operands[*opidx]; 1694 1695 /* Only take input from real operands. */ 1696 if ((operand->flags & ARC_OPERAND_FAKE) 1697 && !(operand->flags & ARC_OPERAND_BRAKET)) 1698 continue; 1699 1700 /* When we expect input, make sure we have it. */ 1701 if (tokidx >= ntok) 1702 goto match_failed; 1703 1704 /* Match operand type with expression type. */ 1705 switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK) 1706 { 1707 case ARC_OPERAND_IR: 1708 /* Check to be a register. */ 1709 if ((tok[tokidx].X_op != O_register 1710 || !is_ir_num (tok[tokidx].X_add_number)) 1711 && !(operand->flags & ARC_OPERAND_IGNORE)) 1712 goto match_failed; 1713 1714 /* If expect duplicate, make sure it is duplicate. */ 1715 if (operand->flags & ARC_OPERAND_DUPLICATE) 1716 { 1717 /* Check for duplicate. */ 1718 if (t->X_op != O_register 1719 || !is_ir_num (t->X_add_number) 1720 || (regno (t->X_add_number) != 1721 regno (tok[tokidx].X_add_number))) 1722 goto match_failed; 1723 } 1724 1725 /* Special handling? */ 1726 if (operand->insert) 1727 { 1728 const char *errmsg = NULL; 1729 (*operand->insert)(0, 1730 regno (tok[tokidx].X_add_number), 1731 &errmsg); 1732 if (errmsg) 1733 { 1734 if (operand->flags & ARC_OPERAND_IGNORE) 1735 { 1736 /* Missing argument, create one. */ 1737 if (!allocate_tok (tok, ntok - 1, tokidx)) 1738 goto match_failed; 1739 1740 tok[tokidx].X_op = O_absent; 1741 ++ntok; 1742 } 1743 else 1744 goto match_failed; 1745 } 1746 } 1747 1748 t = &tok[tokidx]; 1749 break; 1750 1751 case ARC_OPERAND_BRAKET: 1752 /* Check if bracket is also in opcode table as 1753 operand. */ 1754 if (tok[tokidx].X_op != O_bracket) 1755 goto match_failed; 1756 break; 1757 1758 case ARC_OPERAND_LIMM: 1759 case ARC_OPERAND_SIGNED: 1760 case ARC_OPERAND_UNSIGNED: 1761 switch (tok[tokidx].X_op) 1762 { 1763 case O_illegal: 1764 case O_absent: 1765 case O_register: 1766 goto match_failed; 1767 1768 case O_bracket: 1769 /* Got an (too) early bracket, check if it is an 1770 ignored operand. N.B. This procedure works only 1771 when bracket is the last operand! */ 1772 if (!(operand->flags & ARC_OPERAND_IGNORE)) 1773 goto match_failed; 1774 /* Insert the missing operand. */ 1775 if (!allocate_tok (tok, ntok - 1, tokidx)) 1776 goto match_failed; 1777 1778 tok[tokidx].X_op = O_absent; 1779 ++ntok; 1780 break; 1781 1782 case O_symbol: 1783 { 1784 const char *p; 1785 const struct arc_aux_reg *auxr; 1786 1787 if (opcode->insn_class != AUXREG) 1788 goto de_fault; 1789 p = S_GET_NAME (tok[tokidx].X_add_symbol); 1790 1791 auxr = hash_find (arc_aux_hash, p); 1792 if (auxr) 1793 { 1794 /* We modify the token array here, safe in the 1795 knowledge, that if this was the wrong 1796 choice then the original contents will be 1797 restored from BKTOK. */ 1798 tok[tokidx].X_op = O_constant; 1799 tok[tokidx].X_add_number = auxr->address; 1800 ARC_SET_FLAG (tok[tokidx].X_add_symbol, ARC_FLAG_AUX); 1801 } 1802 1803 if (tok[tokidx].X_op != O_constant) 1804 goto de_fault; 1805 } 1806 /* Fall-through */ 1807 case O_constant: 1808 /* Check the range. */ 1809 if (operand->bits != 32 1810 && !(operand->flags & ARC_OPERAND_NCHK)) 1811 { 1812 offsetT min, max, val; 1813 val = tok[tokidx].X_add_number; 1814 1815 if (operand->flags & ARC_OPERAND_SIGNED) 1816 { 1817 max = (1 << (operand->bits - 1)) - 1; 1818 min = -(1 << (operand->bits - 1)); 1819 } 1820 else 1821 { 1822 max = (1 << operand->bits) - 1; 1823 min = 0; 1824 } 1825 1826 if (val < min || val > max) 1827 goto match_failed; 1828 1829 /* Check alignmets. */ 1830 if ((operand->flags & ARC_OPERAND_ALIGNED32) 1831 && (val & 0x03)) 1832 goto match_failed; 1833 1834 if ((operand->flags & ARC_OPERAND_ALIGNED16) 1835 && (val & 0x01)) 1836 goto match_failed; 1837 } 1838 else if (operand->flags & ARC_OPERAND_NCHK) 1839 { 1840 if (operand->insert) 1841 { 1842 const char *errmsg = NULL; 1843 (*operand->insert)(0, 1844 tok[tokidx].X_add_number, 1845 &errmsg); 1846 if (errmsg) 1847 goto match_failed; 1848 } 1849 else if (!(operand->flags & ARC_OPERAND_IGNORE)) 1850 goto match_failed; 1851 } 1852 break; 1853 1854 case O_subtract: 1855 /* Check if it is register range. */ 1856 if ((tok[tokidx].X_add_number == 0) 1857 && contains_register (tok[tokidx].X_add_symbol) 1858 && contains_register (tok[tokidx].X_op_symbol)) 1859 { 1860 int regs; 1861 1862 regs = get_register (tok[tokidx].X_add_symbol); 1863 regs <<= 16; 1864 regs |= get_register (tok[tokidx].X_op_symbol); 1865 if (operand->insert) 1866 { 1867 const char *errmsg = NULL; 1868 (*operand->insert)(0, 1869 regs, 1870 &errmsg); 1871 if (errmsg) 1872 goto match_failed; 1873 } 1874 else 1875 goto match_failed; 1876 break; 1877 } 1878 default: 1879 de_fault: 1880 if (operand->default_reloc == 0) 1881 goto match_failed; /* The operand needs relocation. */ 1882 1883 /* Relocs requiring long immediate. FIXME! make it 1884 generic and move it to a function. */ 1885 switch (tok[tokidx].X_md) 1886 { 1887 case O_gotoff: 1888 case O_gotpc: 1889 case O_pcl: 1890 case O_tpoff: 1891 case O_dtpoff: 1892 case O_tlsgd: 1893 case O_tlsie: 1894 if (!(operand->flags & ARC_OPERAND_LIMM)) 1895 goto match_failed; 1896 case O_absent: 1897 if (!generic_reloc_p (operand->default_reloc)) 1898 goto match_failed; 1899 default: 1900 break; 1901 } 1902 break; 1903 } 1904 /* If expect duplicate, make sure it is duplicate. */ 1905 if (operand->flags & ARC_OPERAND_DUPLICATE) 1906 { 1907 if (t->X_op == O_illegal 1908 || t->X_op == O_absent 1909 || t->X_op == O_register 1910 || (t->X_add_number != tok[tokidx].X_add_number)) 1911 goto match_failed; 1912 } 1913 t = &tok[tokidx]; 1914 break; 1915 1916 default: 1917 /* Everything else should have been fake. */ 1918 abort (); 1919 } 1920 1921 ++tokidx; 1922 } 1923 pr_debug ("opr "); 1924 1925 /* Setup ready for flag parsing. */ 1926 if (!parse_opcode_flags (opcode, nflgs, first_pflag)) 1927 goto match_failed; 1928 1929 pr_debug ("flg"); 1930 /* Possible match -- did we use all of our input? */ 1931 if (tokidx == ntok) 1932 { 1933 *pntok = ntok; 1934 pr_debug ("\n"); 1935 return opcode; 1936 } 1937 1938 match_failed:; 1939 pr_debug ("\n"); 1940 /* Restore the original parameters. */ 1941 memcpy (tok, bktok, MAX_INSN_ARGS * sizeof (*tok)); 1942 ntok = bkntok; 1943 } 1944 1945 if (*pcpumatch) 1946 *pcpumatch = got_cpu_match; 1947 1948 return NULL; 1949 } 1950 1951 /* Swap operand tokens. */ 1952 1953 static void 1954 swap_operand (expressionS *operand_array, 1955 unsigned source, 1956 unsigned destination) 1957 { 1958 expressionS cpy_operand; 1959 expressionS *src_operand; 1960 expressionS *dst_operand; 1961 size_t size; 1962 1963 if (source == destination) 1964 return; 1965 1966 src_operand = &operand_array[source]; 1967 dst_operand = &operand_array[destination]; 1968 size = sizeof (expressionS); 1969 1970 /* Make copy of operand to swap with and swap. */ 1971 memcpy (&cpy_operand, dst_operand, size); 1972 memcpy (dst_operand, src_operand, size); 1973 memcpy (src_operand, &cpy_operand, size); 1974 } 1975 1976 /* Check if *op matches *tok type. 1977 Returns FALSE if they don't match, TRUE if they match. */ 1978 1979 static bfd_boolean 1980 pseudo_operand_match (const expressionS *tok, 1981 const struct arc_operand_operation *op) 1982 { 1983 offsetT min, max, val; 1984 bfd_boolean ret; 1985 const struct arc_operand *operand_real = &arc_operands[op->operand_idx]; 1986 1987 ret = FALSE; 1988 switch (tok->X_op) 1989 { 1990 case O_constant: 1991 if (operand_real->bits == 32 && (operand_real->flags & ARC_OPERAND_LIMM)) 1992 ret = 1; 1993 else if (!(operand_real->flags & ARC_OPERAND_IR)) 1994 { 1995 val = tok->X_add_number + op->count; 1996 if (operand_real->flags & ARC_OPERAND_SIGNED) 1997 { 1998 max = (1 << (operand_real->bits - 1)) - 1; 1999 min = -(1 << (operand_real->bits - 1)); 2000 } 2001 else 2002 { 2003 max = (1 << operand_real->bits) - 1; 2004 min = 0; 2005 } 2006 if (min <= val && val <= max) 2007 ret = TRUE; 2008 } 2009 break; 2010 2011 case O_symbol: 2012 /* Handle all symbols as long immediates or signed 9. */ 2013 if (operand_real->flags & ARC_OPERAND_LIMM || 2014 ((operand_real->flags & ARC_OPERAND_SIGNED) && operand_real->bits == 9)) 2015 ret = TRUE; 2016 break; 2017 2018 case O_register: 2019 if (operand_real->flags & ARC_OPERAND_IR) 2020 ret = TRUE; 2021 break; 2022 2023 case O_bracket: 2024 if (operand_real->flags & ARC_OPERAND_BRAKET) 2025 ret = TRUE; 2026 break; 2027 2028 default: 2029 /* Unknown. */ 2030 break; 2031 } 2032 return ret; 2033 } 2034 2035 /* Find pseudo instruction in array. */ 2036 2037 static const struct arc_pseudo_insn * 2038 find_pseudo_insn (const char *opname, 2039 int ntok, 2040 const expressionS *tok) 2041 { 2042 const struct arc_pseudo_insn *pseudo_insn = NULL; 2043 const struct arc_operand_operation *op; 2044 unsigned int i; 2045 int j; 2046 2047 for (i = 0; i < arc_num_pseudo_insn; ++i) 2048 { 2049 pseudo_insn = &arc_pseudo_insns[i]; 2050 if (strcmp (pseudo_insn->mnemonic_p, opname) == 0) 2051 { 2052 op = pseudo_insn->operand; 2053 for (j = 0; j < ntok; ++j) 2054 if (!pseudo_operand_match (&tok[j], &op[j])) 2055 break; 2056 2057 /* Found the right instruction. */ 2058 if (j == ntok) 2059 return pseudo_insn; 2060 } 2061 } 2062 return NULL; 2063 } 2064 2065 /* Assumes the expressionS *tok is of sufficient size. */ 2066 2067 static const struct arc_opcode_hash_entry * 2068 find_special_case_pseudo (const char *opname, 2069 int *ntok, 2070 expressionS *tok, 2071 int *nflgs, 2072 struct arc_flags *pflags) 2073 { 2074 const struct arc_pseudo_insn *pseudo_insn = NULL; 2075 const struct arc_operand_operation *operand_pseudo; 2076 const struct arc_operand *operand_real; 2077 unsigned i; 2078 char construct_operand[MAX_CONSTR_STR]; 2079 2080 /* Find whether opname is in pseudo instruction array. */ 2081 pseudo_insn = find_pseudo_insn (opname, *ntok, tok); 2082 2083 if (pseudo_insn == NULL) 2084 return NULL; 2085 2086 /* Handle flag, Limited to one flag at the moment. */ 2087 if (pseudo_insn->flag_r != NULL) 2088 *nflgs += tokenize_flags (pseudo_insn->flag_r, &pflags[*nflgs], 2089 MAX_INSN_FLGS - *nflgs); 2090 2091 /* Handle operand operations. */ 2092 for (i = 0; i < pseudo_insn->operand_cnt; ++i) 2093 { 2094 operand_pseudo = &pseudo_insn->operand[i]; 2095 operand_real = &arc_operands[operand_pseudo->operand_idx]; 2096 2097 if (operand_real->flags & ARC_OPERAND_BRAKET && 2098 !operand_pseudo->needs_insert) 2099 continue; 2100 2101 /* Has to be inserted (i.e. this token does not exist yet). */ 2102 if (operand_pseudo->needs_insert) 2103 { 2104 if (operand_real->flags & ARC_OPERAND_BRAKET) 2105 { 2106 tok[i].X_op = O_bracket; 2107 ++(*ntok); 2108 continue; 2109 } 2110 2111 /* Check if operand is a register or constant and handle it 2112 by type. */ 2113 if (operand_real->flags & ARC_OPERAND_IR) 2114 snprintf (construct_operand, MAX_CONSTR_STR, "r%d", 2115 operand_pseudo->count); 2116 else 2117 snprintf (construct_operand, MAX_CONSTR_STR, "%d", 2118 operand_pseudo->count); 2119 2120 tokenize_arguments (construct_operand, &tok[i], 1); 2121 ++(*ntok); 2122 } 2123 2124 else if (operand_pseudo->count) 2125 { 2126 /* Operand number has to be adjusted accordingly (by operand 2127 type). */ 2128 switch (tok[i].X_op) 2129 { 2130 case O_constant: 2131 tok[i].X_add_number += operand_pseudo->count; 2132 break; 2133 2134 case O_symbol: 2135 break; 2136 2137 default: 2138 /* Ignored. */ 2139 break; 2140 } 2141 } 2142 } 2143 2144 /* Swap operands if necessary. Only supports one swap at the 2145 moment. */ 2146 for (i = 0; i < pseudo_insn->operand_cnt; ++i) 2147 { 2148 operand_pseudo = &pseudo_insn->operand[i]; 2149 2150 if (operand_pseudo->swap_operand_idx == i) 2151 continue; 2152 2153 swap_operand (tok, i, operand_pseudo->swap_operand_idx); 2154 2155 /* Prevent a swap back later by breaking out. */ 2156 break; 2157 } 2158 2159 return arc_find_opcode (pseudo_insn->mnemonic_r); 2160 } 2161 2162 static const struct arc_opcode_hash_entry * 2163 find_special_case_flag (const char *opname, 2164 int *nflgs, 2165 struct arc_flags *pflags) 2166 { 2167 unsigned int i; 2168 const char *flagnm; 2169 unsigned flag_idx, flag_arr_idx; 2170 size_t flaglen, oplen; 2171 const struct arc_flag_special *arc_flag_special_opcode; 2172 const struct arc_opcode_hash_entry *entry; 2173 2174 /* Search for special case instruction. */ 2175 for (i = 0; i < arc_num_flag_special; i++) 2176 { 2177 arc_flag_special_opcode = &arc_flag_special_cases[i]; 2178 oplen = strlen (arc_flag_special_opcode->name); 2179 2180 if (strncmp (opname, arc_flag_special_opcode->name, oplen) != 0) 2181 continue; 2182 2183 /* Found a potential special case instruction, now test for 2184 flags. */ 2185 for (flag_arr_idx = 0;; ++flag_arr_idx) 2186 { 2187 flag_idx = arc_flag_special_opcode->flags[flag_arr_idx]; 2188 if (flag_idx == 0) 2189 break; /* End of array, nothing found. */ 2190 2191 flagnm = arc_flag_operands[flag_idx].name; 2192 flaglen = strlen (flagnm); 2193 if (strcmp (opname + oplen, flagnm) == 0) 2194 { 2195 entry = arc_find_opcode (arc_flag_special_opcode->name); 2196 2197 if (*nflgs + 1 > MAX_INSN_FLGS) 2198 break; 2199 memcpy (pflags[*nflgs].name, flagnm, flaglen); 2200 pflags[*nflgs].name[flaglen] = '\0'; 2201 (*nflgs)++; 2202 return entry; 2203 } 2204 } 2205 } 2206 return NULL; 2207 } 2208 2209 /* The long instructions are not stored in a hash (there's not many of 2210 them) and so there's no arc_opcode_hash_entry structure to return. This 2211 helper function for find_special_case_long_opcode takes an arc_opcode 2212 result and places it into a fake arc_opcode_hash_entry that points to 2213 the single arc_opcode OPCODE, which is then returned. */ 2214 2215 static const struct arc_opcode_hash_entry * 2216 build_fake_opcode_hash_entry (const struct arc_opcode *opcode) 2217 { 2218 static struct arc_opcode_hash_entry entry; 2219 static struct arc_opcode tmp[2]; 2220 static const struct arc_opcode *ptr[2]; 2221 2222 memcpy (&tmp[0], opcode, sizeof (struct arc_opcode)); 2223 memset (&tmp[1], 0, sizeof (struct arc_opcode)); 2224 entry.count = 1; 2225 entry.opcode = ptr; 2226 ptr[0] = tmp; 2227 ptr[1] = NULL; 2228 return &entry; 2229 } 2230 2231 2232 /* Used by the assembler to match the list of tokens against a long (48 or 2233 64 bits) instruction. If a matching long instruction is found, then 2234 some of the tokens are consumed in this function and converted into a 2235 single LIMM value, which is then added to the end of the token list, 2236 where it will be consumed by a LIMM operand that exists in the base 2237 opcode of the long instruction. */ 2238 2239 static const struct arc_opcode_hash_entry * 2240 find_special_case_long_opcode (const char *opname, 2241 int *ntok ATTRIBUTE_UNUSED, 2242 expressionS *tok ATTRIBUTE_UNUSED, 2243 int *nflgs, 2244 struct arc_flags *pflags) 2245 { 2246 unsigned i; 2247 2248 if (*ntok == MAX_INSN_ARGS) 2249 return NULL; 2250 2251 for (i = 0; i < arc_num_long_opcodes; ++i) 2252 { 2253 struct arc_opcode fake_opcode; 2254 const struct arc_opcode *opcode; 2255 struct arc_insn insn; 2256 expressionS *limm_token; 2257 2258 opcode = &arc_long_opcodes[i].base_opcode; 2259 2260 if (!(opcode->cpu & arc_target)) 2261 continue; 2262 2263 if (!check_cpu_feature (opcode->subclass)) 2264 continue; 2265 2266 if (strcmp (opname, opcode->name) != 0) 2267 continue; 2268 2269 /* Check that the flags are a match. */ 2270 if (!parse_opcode_flags (opcode, *nflgs, pflags)) 2271 continue; 2272 2273 /* Parse the LIMM operands into the LIMM template. */ 2274 memset (&fake_opcode, 0, sizeof (fake_opcode)); 2275 fake_opcode.name = "fake limm"; 2276 fake_opcode.opcode = arc_long_opcodes[i].limm_template; 2277 fake_opcode.mask = arc_long_opcodes[i].limm_mask; 2278 fake_opcode.cpu = opcode->cpu; 2279 fake_opcode.insn_class = opcode->insn_class; 2280 fake_opcode.subclass = opcode->subclass; 2281 memcpy (&fake_opcode.operands[0], 2282 &arc_long_opcodes[i].operands, 2283 MAX_INSN_ARGS); 2284 /* Leave fake_opcode.flags as zero. */ 2285 2286 pr_debug ("Calling assemble_insn to build fake limm value\n"); 2287 assemble_insn (&fake_opcode, tok, *ntok, 2288 NULL, 0, &insn); 2289 pr_debug (" got limm value: 0x%x\n", insn.insn); 2290 2291 /* Now create a new token at the end of the token array (We know this 2292 is safe as the token array is always created with enough space for 2293 MAX_INSN_ARGS, and we check at the start at the start of this 2294 function that we're not there yet). This new token will 2295 correspond to a LIMM operand that will be contained in the 2296 base_opcode of the arc_long_opcode. */ 2297 limm_token = &tok[(*ntok)]; 2298 (*ntok)++; 2299 2300 /* Modify the LIMM token to hold the constant. */ 2301 limm_token->X_op = O_constant; 2302 limm_token->X_add_number = insn.insn; 2303 2304 /* Return the base opcode. */ 2305 return build_fake_opcode_hash_entry (opcode); 2306 } 2307 2308 return NULL; 2309 } 2310 2311 /* Used to find special case opcode. */ 2312 2313 static const struct arc_opcode_hash_entry * 2314 find_special_case (const char *opname, 2315 int *nflgs, 2316 struct arc_flags *pflags, 2317 expressionS *tok, 2318 int *ntok) 2319 { 2320 const struct arc_opcode_hash_entry *entry; 2321 2322 entry = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags); 2323 2324 if (entry == NULL) 2325 entry = find_special_case_flag (opname, nflgs, pflags); 2326 2327 if (entry == NULL) 2328 entry = find_special_case_long_opcode (opname, ntok, tok, nflgs, pflags); 2329 2330 return entry; 2331 } 2332 2333 /* Given an opcode name, pre-tockenized set of argumenst and the 2334 opcode flags, take it all the way through emission. */ 2335 2336 static void 2337 assemble_tokens (const char *opname, 2338 expressionS *tok, 2339 int ntok, 2340 struct arc_flags *pflags, 2341 int nflgs) 2342 { 2343 bfd_boolean found_something = FALSE; 2344 const struct arc_opcode_hash_entry *entry; 2345 int cpumatch = 1; 2346 2347 /* Search opcodes. */ 2348 entry = arc_find_opcode (opname); 2349 2350 /* Couldn't find opcode conventional way, try special cases. */ 2351 if (entry == NULL) 2352 entry = find_special_case (opname, &nflgs, pflags, tok, &ntok); 2353 2354 if (entry != NULL) 2355 { 2356 const struct arc_opcode *opcode; 2357 2358 pr_debug ("%s:%d: assemble_tokens: %s\n", 2359 frag_now->fr_file, frag_now->fr_line, opname); 2360 found_something = TRUE; 2361 opcode = find_opcode_match (entry, tok, &ntok, pflags, 2362 nflgs, &cpumatch); 2363 if (opcode != NULL) 2364 { 2365 struct arc_insn insn; 2366 2367 assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn); 2368 emit_insn (&insn); 2369 return; 2370 } 2371 } 2372 2373 if (found_something) 2374 { 2375 if (cpumatch) 2376 as_bad (_("inappropriate arguments for opcode '%s'"), opname); 2377 else 2378 as_bad (_("opcode '%s' not supported for target %s"), opname, 2379 arc_target_name); 2380 } 2381 else 2382 as_bad (_("unknown opcode '%s'"), opname); 2383 } 2384 2385 /* The public interface to the instruction assembler. */ 2386 2387 void 2388 md_assemble (char *str) 2389 { 2390 char *opname; 2391 expressionS tok[MAX_INSN_ARGS]; 2392 int ntok, nflg; 2393 size_t opnamelen; 2394 struct arc_flags flags[MAX_INSN_FLGS]; 2395 2396 /* Split off the opcode. */ 2397 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_0123468"); 2398 opname = xmemdup0 (str, opnamelen); 2399 2400 /* Signalize we are assmbling the instructions. */ 2401 assembling_insn = TRUE; 2402 2403 /* Tokenize the flags. */ 2404 if ((nflg = tokenize_flags (str + opnamelen, flags, MAX_INSN_FLGS)) == -1) 2405 { 2406 as_bad (_("syntax error")); 2407 return; 2408 } 2409 2410 /* Scan up to the end of the mnemonic which must end in space or end 2411 of string. */ 2412 str += opnamelen; 2413 for (; *str != '\0'; str++) 2414 if (*str == ' ') 2415 break; 2416 2417 /* Tokenize the rest of the line. */ 2418 if ((ntok = tokenize_arguments (str, tok, MAX_INSN_ARGS)) < 0) 2419 { 2420 as_bad (_("syntax error")); 2421 return; 2422 } 2423 2424 /* Finish it off. */ 2425 assemble_tokens (opname, tok, ntok, flags, nflg); 2426 assembling_insn = FALSE; 2427 } 2428 2429 /* Callback to insert a register into the hash table. */ 2430 2431 static void 2432 declare_register (const char *name, int number) 2433 { 2434 const char *err; 2435 symbolS *regS = symbol_create (name, reg_section, 2436 number, &zero_address_frag); 2437 2438 err = hash_insert (arc_reg_hash, S_GET_NAME (regS), (void *) regS); 2439 if (err) 2440 as_fatal (_("Inserting \"%s\" into register table failed: %s"), 2441 name, err); 2442 } 2443 2444 /* Construct symbols for each of the general registers. */ 2445 2446 static void 2447 declare_register_set (void) 2448 { 2449 int i; 2450 for (i = 0; i < 64; ++i) 2451 { 2452 char name[7]; 2453 2454 sprintf (name, "r%d", i); 2455 declare_register (name, i); 2456 if ((i & 0x01) == 0) 2457 { 2458 sprintf (name, "r%dr%d", i, i+1); 2459 declare_register (name, i); 2460 } 2461 } 2462 } 2463 2464 /* Port-specific assembler initialization. This function is called 2465 once, at assembler startup time. */ 2466 2467 void 2468 md_begin (void) 2469 { 2470 const struct arc_opcode *opcode = arc_opcodes; 2471 2472 if (!mach_type_specified_p) 2473 arc_select_cpu (TARGET_WITH_CPU); 2474 2475 /* The endianness can be chosen "at the factory". */ 2476 target_big_endian = byte_order == BIG_ENDIAN; 2477 2478 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type)) 2479 as_warn (_("could not set architecture and machine")); 2480 2481 /* Set elf header flags. */ 2482 bfd_set_private_flags (stdoutput, arc_eflag); 2483 2484 /* Set up a hash table for the instructions. */ 2485 arc_opcode_hash = hash_new (); 2486 if (arc_opcode_hash == NULL) 2487 as_fatal (_("Virtual memory exhausted")); 2488 2489 /* Initialize the hash table with the insns. */ 2490 do 2491 { 2492 const char *name = opcode->name; 2493 2494 arc_insert_opcode (opcode); 2495 2496 while (++opcode && opcode->name 2497 && (opcode->name == name 2498 || !strcmp (opcode->name, name))) 2499 continue; 2500 }while (opcode->name); 2501 2502 /* Register declaration. */ 2503 arc_reg_hash = hash_new (); 2504 if (arc_reg_hash == NULL) 2505 as_fatal (_("Virtual memory exhausted")); 2506 2507 declare_register_set (); 2508 declare_register ("gp", 26); 2509 declare_register ("fp", 27); 2510 declare_register ("sp", 28); 2511 declare_register ("ilink", 29); 2512 declare_register ("ilink1", 29); 2513 declare_register ("ilink2", 30); 2514 declare_register ("blink", 31); 2515 2516 /* XY memory registers. */ 2517 declare_register ("x0_u0", 32); 2518 declare_register ("x0_u1", 33); 2519 declare_register ("x1_u0", 34); 2520 declare_register ("x1_u1", 35); 2521 declare_register ("x2_u0", 36); 2522 declare_register ("x2_u1", 37); 2523 declare_register ("x3_u0", 38); 2524 declare_register ("x3_u1", 39); 2525 declare_register ("y0_u0", 40); 2526 declare_register ("y0_u1", 41); 2527 declare_register ("y1_u0", 42); 2528 declare_register ("y1_u1", 43); 2529 declare_register ("y2_u0", 44); 2530 declare_register ("y2_u1", 45); 2531 declare_register ("y3_u0", 46); 2532 declare_register ("y3_u1", 47); 2533 declare_register ("x0_nu", 48); 2534 declare_register ("x1_nu", 49); 2535 declare_register ("x2_nu", 50); 2536 declare_register ("x3_nu", 51); 2537 declare_register ("y0_nu", 52); 2538 declare_register ("y1_nu", 53); 2539 declare_register ("y2_nu", 54); 2540 declare_register ("y3_nu", 55); 2541 2542 declare_register ("mlo", 57); 2543 declare_register ("mmid", 58); 2544 declare_register ("mhi", 59); 2545 2546 declare_register ("acc1", 56); 2547 declare_register ("acc2", 57); 2548 2549 declare_register ("lp_count", 60); 2550 declare_register ("pcl", 63); 2551 2552 /* Initialize the last instructions. */ 2553 memset (&arc_last_insns[0], 0, sizeof (arc_last_insns)); 2554 2555 /* Aux register declaration. */ 2556 arc_aux_hash = hash_new (); 2557 if (arc_aux_hash == NULL) 2558 as_fatal (_("Virtual memory exhausted")); 2559 2560 const struct arc_aux_reg *auxr = &arc_aux_regs[0]; 2561 unsigned int i; 2562 for (i = 0; i < arc_num_aux_regs; i++, auxr++) 2563 { 2564 const char *retval; 2565 2566 if (!(auxr->cpu & arc_target)) 2567 continue; 2568 2569 if ((auxr->subclass != NONE) 2570 && !check_cpu_feature (auxr->subclass)) 2571 continue; 2572 2573 retval = hash_insert (arc_aux_hash, auxr->name, (void *) auxr); 2574 if (retval) 2575 as_fatal (_("internal error: can't hash aux register '%s': %s"), 2576 auxr->name, retval); 2577 } 2578 } 2579 2580 /* Write a value out to the object file, using the appropriate 2581 endianness. */ 2582 2583 void 2584 md_number_to_chars (char *buf, 2585 valueT val, 2586 int n) 2587 { 2588 if (target_big_endian) 2589 number_to_chars_bigendian (buf, val, n); 2590 else 2591 number_to_chars_littleendian (buf, val, n); 2592 } 2593 2594 /* Round up a section size to the appropriate boundary. */ 2595 2596 valueT 2597 md_section_align (segT segment, 2598 valueT size) 2599 { 2600 int align = bfd_get_section_alignment (stdoutput, segment); 2601 2602 return ((size + (1 << align) - 1) & (-((valueT) 1 << align))); 2603 } 2604 2605 /* The location from which a PC relative jump should be calculated, 2606 given a PC relative reloc. */ 2607 2608 long 2609 md_pcrel_from_section (fixS *fixP, 2610 segT sec) 2611 { 2612 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address; 2613 2614 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP->fx_offset); 2615 2616 if (fixP->fx_addsy != (symbolS *) NULL 2617 && (!S_IS_DEFINED (fixP->fx_addsy) 2618 || S_GET_SEGMENT (fixP->fx_addsy) != sec)) 2619 { 2620 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP->fx_addsy)); 2621 2622 /* The symbol is undefined (or is defined but not in this section). 2623 Let the linker figure it out. */ 2624 return 0; 2625 } 2626 2627 if ((int) fixP->fx_r_type < 0) 2628 { 2629 /* These are the "internal" relocations. Align them to 2630 32 bit boundary (PCL), for the moment. */ 2631 base &= ~3; 2632 } 2633 else 2634 { 2635 switch (fixP->fx_r_type) 2636 { 2637 case BFD_RELOC_ARC_PC32: 2638 /* The hardware calculates relative to the start of the 2639 insn, but this relocation is relative to location of the 2640 LIMM, compensate. The base always needs to be 2641 substracted by 4 as we do not support this type of PCrel 2642 relocation for short instructions. */ 2643 base -= 4; 2644 /* Fall through. */ 2645 case BFD_RELOC_ARC_PLT32: 2646 case BFD_RELOC_ARC_S25H_PCREL_PLT: 2647 case BFD_RELOC_ARC_S21H_PCREL_PLT: 2648 case BFD_RELOC_ARC_S25W_PCREL_PLT: 2649 case BFD_RELOC_ARC_S21W_PCREL_PLT: 2650 2651 case BFD_RELOC_ARC_S21H_PCREL: 2652 case BFD_RELOC_ARC_S25H_PCREL: 2653 case BFD_RELOC_ARC_S13_PCREL: 2654 case BFD_RELOC_ARC_S21W_PCREL: 2655 case BFD_RELOC_ARC_S25W_PCREL: 2656 base &= ~3; 2657 break; 2658 default: 2659 as_bad_where (fixP->fx_file, fixP->fx_line, 2660 _("unhandled reloc %s in md_pcrel_from_section"), 2661 bfd_get_reloc_code_name (fixP->fx_r_type)); 2662 break; 2663 } 2664 } 2665 2666 pr_debug ("pcrel from %"BFD_VMA_FMT"x + %lx = %"BFD_VMA_FMT"x, " 2667 "symbol: %s (%"BFD_VMA_FMT"x)\n", 2668 fixP->fx_frag->fr_address, fixP->fx_where, base, 2669 fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "(null)", 2670 fixP->fx_addsy ? S_GET_VALUE (fixP->fx_addsy) : 0); 2671 2672 return base; 2673 } 2674 2675 /* Given a BFD relocation find the coresponding operand. */ 2676 2677 static const struct arc_operand * 2678 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc) 2679 { 2680 unsigned i; 2681 2682 for (i = 0; i < arc_num_operands; i++) 2683 if (arc_operands[i].default_reloc == reloc) 2684 return &arc_operands[i]; 2685 return NULL; 2686 } 2687 2688 /* Insert an operand value into an instruction. */ 2689 2690 static unsigned 2691 insert_operand (unsigned insn, 2692 const struct arc_operand *operand, 2693 offsetT val, 2694 const char *file, 2695 unsigned line) 2696 { 2697 offsetT min = 0, max = 0; 2698 2699 if (operand->bits != 32 2700 && !(operand->flags & ARC_OPERAND_NCHK) 2701 && !(operand->flags & ARC_OPERAND_FAKE)) 2702 { 2703 if (operand->flags & ARC_OPERAND_SIGNED) 2704 { 2705 max = (1 << (operand->bits - 1)) - 1; 2706 min = -(1 << (operand->bits - 1)); 2707 } 2708 else 2709 { 2710 max = (1 << operand->bits) - 1; 2711 min = 0; 2712 } 2713 2714 if (val < min || val > max) 2715 as_bad_value_out_of_range (_("operand"), 2716 val, min, max, file, line); 2717 } 2718 2719 pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n", 2720 min, val, max, insn); 2721 2722 if ((operand->flags & ARC_OPERAND_ALIGNED32) 2723 && (val & 0x03)) 2724 as_bad_where (file, line, 2725 _("Unaligned operand. Needs to be 32bit aligned")); 2726 2727 if ((operand->flags & ARC_OPERAND_ALIGNED16) 2728 && (val & 0x01)) 2729 as_bad_where (file, line, 2730 _("Unaligned operand. Needs to be 16bit aligned")); 2731 2732 if (operand->insert) 2733 { 2734 const char *errmsg = NULL; 2735 2736 insn = (*operand->insert) (insn, val, &errmsg); 2737 if (errmsg) 2738 as_warn_where (file, line, "%s", errmsg); 2739 } 2740 else 2741 { 2742 if (operand->flags & ARC_OPERAND_TRUNCATE) 2743 { 2744 if (operand->flags & ARC_OPERAND_ALIGNED32) 2745 val >>= 2; 2746 if (operand->flags & ARC_OPERAND_ALIGNED16) 2747 val >>= 1; 2748 } 2749 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift); 2750 } 2751 return insn; 2752 } 2753 2754 /* Apply a fixup to the object code. At this point all symbol values 2755 should be fully resolved, and we attempt to completely resolve the 2756 reloc. If we can not do that, we determine the correct reloc code 2757 and put it back in the fixup. To indicate that a fixup has been 2758 eliminated, set fixP->fx_done. */ 2759 2760 void 2761 md_apply_fix (fixS *fixP, 2762 valueT *valP, 2763 segT seg) 2764 { 2765 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where; 2766 valueT value = *valP; 2767 unsigned insn = 0; 2768 symbolS *fx_addsy, *fx_subsy; 2769 offsetT fx_offset; 2770 segT add_symbol_segment = absolute_section; 2771 segT sub_symbol_segment = absolute_section; 2772 const struct arc_operand *operand = NULL; 2773 extended_bfd_reloc_code_real_type reloc; 2774 2775 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n", 2776 fixP->fx_file, fixP->fx_line, fixP->fx_r_type, 2777 ((int) fixP->fx_r_type < 0) ? "Internal": 2778 bfd_get_reloc_code_name (fixP->fx_r_type), value, 2779 fixP->fx_offset); 2780 2781 fx_addsy = fixP->fx_addsy; 2782 fx_subsy = fixP->fx_subsy; 2783 fx_offset = 0; 2784 2785 if (fx_addsy) 2786 { 2787 add_symbol_segment = S_GET_SEGMENT (fx_addsy); 2788 } 2789 2790 if (fx_subsy 2791 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF 2792 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF_S9 2793 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_GD_LD) 2794 { 2795 resolve_symbol_value (fx_subsy); 2796 sub_symbol_segment = S_GET_SEGMENT (fx_subsy); 2797 2798 if (sub_symbol_segment == absolute_section) 2799 { 2800 /* The symbol is really a constant. */ 2801 fx_offset -= S_GET_VALUE (fx_subsy); 2802 fx_subsy = NULL; 2803 } 2804 else 2805 { 2806 as_bad_where (fixP->fx_file, fixP->fx_line, 2807 _("can't resolve `%s' {%s section} - `%s' {%s section}"), 2808 fx_addsy ? S_GET_NAME (fx_addsy) : "0", 2809 segment_name (add_symbol_segment), 2810 S_GET_NAME (fx_subsy), 2811 segment_name (sub_symbol_segment)); 2812 return; 2813 } 2814 } 2815 2816 if (fx_addsy 2817 && !S_IS_WEAK (fx_addsy)) 2818 { 2819 if (add_symbol_segment == seg 2820 && fixP->fx_pcrel) 2821 { 2822 value += S_GET_VALUE (fx_addsy); 2823 value -= md_pcrel_from_section (fixP, seg); 2824 fx_addsy = NULL; 2825 fixP->fx_pcrel = FALSE; 2826 } 2827 else if (add_symbol_segment == absolute_section) 2828 { 2829 value = fixP->fx_offset; 2830 fx_offset += S_GET_VALUE (fixP->fx_addsy); 2831 fx_addsy = NULL; 2832 fixP->fx_pcrel = FALSE; 2833 } 2834 } 2835 2836 if (!fx_addsy) 2837 fixP->fx_done = TRUE; 2838 2839 if (fixP->fx_pcrel) 2840 { 2841 if (fx_addsy 2842 && ((S_IS_DEFINED (fx_addsy) 2843 && S_GET_SEGMENT (fx_addsy) != seg) 2844 || S_IS_WEAK (fx_addsy))) 2845 value += md_pcrel_from_section (fixP, seg); 2846 2847 switch (fixP->fx_r_type) 2848 { 2849 case BFD_RELOC_ARC_32_ME: 2850 /* This is a pc-relative value in a LIMM. Adjust it to the 2851 address of the instruction not to the address of the 2852 LIMM. Note: it is not anylonger valid this afirmation as 2853 the linker consider ARC_PC32 a fixup to entire 64 bit 2854 insn. */ 2855 fixP->fx_offset += fixP->fx_frag->fr_address; 2856 /* Fall through. */ 2857 case BFD_RELOC_32: 2858 fixP->fx_r_type = BFD_RELOC_ARC_PC32; 2859 /* Fall through. */ 2860 case BFD_RELOC_ARC_PC32: 2861 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */ 2862 break; 2863 default: 2864 if ((int) fixP->fx_r_type < 0) 2865 as_fatal (_("PC relative relocation not allowed for (internal) type %d"), 2866 fixP->fx_r_type); 2867 break; 2868 } 2869 } 2870 2871 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n", 2872 fixP->fx_file, fixP->fx_line, fixP->fx_r_type, 2873 ((int) fixP->fx_r_type < 0) ? "Internal": 2874 bfd_get_reloc_code_name (fixP->fx_r_type), value, 2875 fixP->fx_offset); 2876 2877 2878 /* Now check for TLS relocations. */ 2879 reloc = fixP->fx_r_type; 2880 switch (reloc) 2881 { 2882 case BFD_RELOC_ARC_TLS_DTPOFF: 2883 case BFD_RELOC_ARC_TLS_LE_32: 2884 if (fixP->fx_done) 2885 break; 2886 /* Fall through. */ 2887 case BFD_RELOC_ARC_TLS_GD_GOT: 2888 case BFD_RELOC_ARC_TLS_IE_GOT: 2889 S_SET_THREAD_LOCAL (fixP->fx_addsy); 2890 break; 2891 2892 case BFD_RELOC_ARC_TLS_GD_LD: 2893 gas_assert (!fixP->fx_offset); 2894 if (fixP->fx_subsy) 2895 fixP->fx_offset 2896 = (S_GET_VALUE (fixP->fx_subsy) 2897 - fixP->fx_frag->fr_address- fixP->fx_where); 2898 fixP->fx_subsy = NULL; 2899 /* Fall through. */ 2900 case BFD_RELOC_ARC_TLS_GD_CALL: 2901 /* These two relocs are there just to allow ld to change the tls 2902 model for this symbol, by patching the code. The offset - 2903 and scale, if any - will be installed by the linker. */ 2904 S_SET_THREAD_LOCAL (fixP->fx_addsy); 2905 break; 2906 2907 case BFD_RELOC_ARC_TLS_LE_S9: 2908 case BFD_RELOC_ARC_TLS_DTPOFF_S9: 2909 as_bad (_("TLS_*_S9 relocs are not supported yet")); 2910 break; 2911 2912 default: 2913 break; 2914 } 2915 2916 if (!fixP->fx_done) 2917 { 2918 return; 2919 } 2920 2921 /* Addjust the value if we have a constant. */ 2922 value += fx_offset; 2923 2924 /* For hosts with longs bigger than 32-bits make sure that the top 2925 bits of a 32-bit negative value read in by the parser are set, 2926 so that the correct comparisons are made. */ 2927 if (value & 0x80000000) 2928 value |= (-1UL << 31); 2929 2930 reloc = fixP->fx_r_type; 2931 switch (reloc) 2932 { 2933 case BFD_RELOC_8: 2934 case BFD_RELOC_16: 2935 case BFD_RELOC_24: 2936 case BFD_RELOC_32: 2937 case BFD_RELOC_64: 2938 case BFD_RELOC_ARC_32_PCREL: 2939 md_number_to_chars (fixpos, value, fixP->fx_size); 2940 return; 2941 2942 case BFD_RELOC_ARC_GOTPC32: 2943 /* I cannot fix an GOTPC relocation because I need to relax it 2944 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */ 2945 as_bad (_("Unsupported operation on reloc")); 2946 return; 2947 2948 case BFD_RELOC_ARC_TLS_DTPOFF: 2949 case BFD_RELOC_ARC_TLS_LE_32: 2950 gas_assert (!fixP->fx_addsy); 2951 gas_assert (!fixP->fx_subsy); 2952 2953 case BFD_RELOC_ARC_GOTOFF: 2954 case BFD_RELOC_ARC_32_ME: 2955 case BFD_RELOC_ARC_PC32: 2956 md_number_to_chars_midend (fixpos, value, fixP->fx_size); 2957 return; 2958 2959 case BFD_RELOC_ARC_PLT32: 2960 md_number_to_chars_midend (fixpos, value, fixP->fx_size); 2961 return; 2962 2963 case BFD_RELOC_ARC_S25H_PCREL_PLT: 2964 reloc = BFD_RELOC_ARC_S25W_PCREL; 2965 goto solve_plt; 2966 2967 case BFD_RELOC_ARC_S21H_PCREL_PLT: 2968 reloc = BFD_RELOC_ARC_S21H_PCREL; 2969 goto solve_plt; 2970 2971 case BFD_RELOC_ARC_S25W_PCREL_PLT: 2972 reloc = BFD_RELOC_ARC_S25W_PCREL; 2973 goto solve_plt; 2974 2975 case BFD_RELOC_ARC_S21W_PCREL_PLT: 2976 reloc = BFD_RELOC_ARC_S21W_PCREL; 2977 2978 case BFD_RELOC_ARC_S25W_PCREL: 2979 case BFD_RELOC_ARC_S21W_PCREL: 2980 case BFD_RELOC_ARC_S21H_PCREL: 2981 case BFD_RELOC_ARC_S25H_PCREL: 2982 case BFD_RELOC_ARC_S13_PCREL: 2983 solve_plt: 2984 operand = find_operand_for_reloc (reloc); 2985 gas_assert (operand); 2986 break; 2987 2988 default: 2989 { 2990 if ((int) fixP->fx_r_type >= 0) 2991 as_fatal (_("unhandled relocation type %s"), 2992 bfd_get_reloc_code_name (fixP->fx_r_type)); 2993 2994 /* The rest of these fixups needs to be completely resolved as 2995 constants. */ 2996 if (fixP->fx_addsy != 0 2997 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section) 2998 as_bad_where (fixP->fx_file, fixP->fx_line, 2999 _("non-absolute expression in constant field")); 3000 3001 gas_assert (-(int) fixP->fx_r_type < (int) arc_num_operands); 3002 operand = &arc_operands[-(int) fixP->fx_r_type]; 3003 break; 3004 } 3005 } 3006 3007 if (target_big_endian) 3008 { 3009 switch (fixP->fx_size) 3010 { 3011 case 4: 3012 insn = bfd_getb32 (fixpos); 3013 break; 3014 case 2: 3015 insn = bfd_getb16 (fixpos); 3016 break; 3017 default: 3018 as_bad_where (fixP->fx_file, fixP->fx_line, 3019 _("unknown fixup size")); 3020 } 3021 } 3022 else 3023 { 3024 insn = 0; 3025 switch (fixP->fx_size) 3026 { 3027 case 4: 3028 insn = bfd_getl16 (fixpos) << 16 | bfd_getl16 (fixpos + 2); 3029 break; 3030 case 2: 3031 insn = bfd_getl16 (fixpos); 3032 break; 3033 default: 3034 as_bad_where (fixP->fx_file, fixP->fx_line, 3035 _("unknown fixup size")); 3036 } 3037 } 3038 3039 insn = insert_operand (insn, operand, (offsetT) value, 3040 fixP->fx_file, fixP->fx_line); 3041 3042 md_number_to_chars_midend (fixpos, insn, fixP->fx_size); 3043 } 3044 3045 /* Prepare machine-dependent frags for relaxation. 3046 3047 Called just before relaxation starts. Any symbol that is now undefined 3048 will not become defined. 3049 3050 Return the correct fr_subtype in the frag. 3051 3052 Return the initial "guess for fr_var" to caller. The guess for fr_var 3053 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix 3054 or fr_var contributes to our returned value. 3055 3056 Although it may not be explicit in the frag, pretend 3057 fr_var starts with a value. */ 3058 3059 int 3060 md_estimate_size_before_relax (fragS *fragP, 3061 segT segment) 3062 { 3063 int growth; 3064 3065 /* If the symbol is not located within the same section AND it's not 3066 an absolute section, use the maximum. OR if the symbol is a 3067 constant AND the insn is by nature not pc-rel, use the maximum. 3068 OR if the symbol is being equated against another symbol, use the 3069 maximum. OR if the symbol is weak use the maximum. */ 3070 if ((S_GET_SEGMENT (fragP->fr_symbol) != segment 3071 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section) 3072 || (symbol_constant_p (fragP->fr_symbol) 3073 && !fragP->tc_frag_data.pcrel) 3074 || symbol_equated_p (fragP->fr_symbol) 3075 || S_IS_WEAK (fragP->fr_symbol)) 3076 { 3077 while (md_relax_table[fragP->fr_subtype].rlx_more != ARC_RLX_NONE) 3078 ++fragP->fr_subtype; 3079 } 3080 3081 growth = md_relax_table[fragP->fr_subtype].rlx_length; 3082 fragP->fr_var = growth; 3083 3084 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n", 3085 fragP->fr_file, fragP->fr_line, growth); 3086 3087 return growth; 3088 } 3089 3090 /* Translate internal representation of relocation info to BFD target 3091 format. */ 3092 3093 arelent * 3094 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, 3095 fixS *fixP) 3096 { 3097 arelent *reloc; 3098 bfd_reloc_code_real_type code; 3099 3100 reloc = XNEW (arelent); 3101 reloc->sym_ptr_ptr = XNEW (asymbol *); 3102 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy); 3103 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where; 3104 3105 /* Make sure none of our internal relocations make it this far. 3106 They'd better have been fully resolved by this point. */ 3107 gas_assert ((int) fixP->fx_r_type > 0); 3108 3109 code = fixP->fx_r_type; 3110 3111 /* if we have something like add gp, pcl, 3112 _GLOBAL_OFFSET_TABLE_@gotpc. */ 3113 if (code == BFD_RELOC_ARC_GOTPC32 3114 && GOT_symbol 3115 && fixP->fx_addsy == GOT_symbol) 3116 code = BFD_RELOC_ARC_GOTPC; 3117 3118 reloc->howto = bfd_reloc_type_lookup (stdoutput, code); 3119 if (reloc->howto == NULL) 3120 { 3121 as_bad_where (fixP->fx_file, fixP->fx_line, 3122 _("cannot represent `%s' relocation in object file"), 3123 bfd_get_reloc_code_name (code)); 3124 return NULL; 3125 } 3126 3127 if (!fixP->fx_pcrel != !reloc->howto->pc_relative) 3128 as_fatal (_("internal error? cannot generate `%s' relocation"), 3129 bfd_get_reloc_code_name (code)); 3130 3131 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative); 3132 3133 if (code == BFD_RELOC_ARC_TLS_DTPOFF 3134 || code == BFD_RELOC_ARC_TLS_DTPOFF_S9) 3135 { 3136 asymbol *sym 3137 = fixP->fx_subsy ? symbol_get_bfdsym (fixP->fx_subsy) : NULL; 3138 /* We just want to store a 24 bit index, but we have to wait 3139 till after write_contents has been called via 3140 bfd_map_over_sections before we can get the index from 3141 _bfd_elf_symbol_from_bfd_symbol. Thus, the write_relocs 3142 function is elf32-arc.c has to pick up the slack. 3143 Unfortunately, this leads to problems with hosts that have 3144 pointers wider than long (bfd_vma). There would be various 3145 ways to handle this, all error-prone :-( */ 3146 reloc->addend = (bfd_vma) sym; 3147 if ((asymbol *) reloc->addend != sym) 3148 { 3149 as_bad ("Can't store pointer\n"); 3150 return NULL; 3151 } 3152 } 3153 else 3154 reloc->addend = fixP->fx_offset; 3155 3156 return reloc; 3157 } 3158 3159 /* Perform post-processing of machine-dependent frags after relaxation. 3160 Called after relaxation is finished. 3161 In: Address of frag. 3162 fr_type == rs_machine_dependent. 3163 fr_subtype is what the address relaxed to. 3164 3165 Out: Any fixS:s and constants are set up. */ 3166 3167 void 3168 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, 3169 segT segment ATTRIBUTE_UNUSED, 3170 fragS *fragP) 3171 { 3172 const relax_typeS *table_entry; 3173 char *dest; 3174 const struct arc_opcode *opcode; 3175 struct arc_insn insn; 3176 int size, fix; 3177 struct arc_relax_type *relax_arg = &fragP->tc_frag_data; 3178 3179 fix = (fragP->fr_fix < 0 ? 0 : fragP->fr_fix); 3180 dest = fragP->fr_literal + fix; 3181 table_entry = TC_GENERIC_RELAX_TABLE + fragP->fr_subtype; 3182 3183 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, " 3184 "var: %"BFD_VMA_FMT"d\n", 3185 fragP->fr_file, fragP->fr_line, 3186 fragP->fr_subtype, fix, fragP->fr_var); 3187 3188 if (fragP->fr_subtype <= 0 3189 && fragP->fr_subtype >= arc_num_relax_opcodes) 3190 as_fatal (_("no relaxation found for this instruction.")); 3191 3192 opcode = &arc_relax_opcodes[fragP->fr_subtype]; 3193 3194 assemble_insn (opcode, relax_arg->tok, relax_arg->ntok, relax_arg->pflags, 3195 relax_arg->nflg, &insn); 3196 3197 apply_fixups (&insn, fragP, fix); 3198 3199 size = insn.short_insn ? (insn.has_limm ? 6 : 2) : (insn.has_limm ? 8 : 4); 3200 gas_assert (table_entry->rlx_length == size); 3201 emit_insn0 (&insn, dest, TRUE); 3202 3203 fragP->fr_fix += table_entry->rlx_length; 3204 fragP->fr_var = 0; 3205 } 3206 3207 /* We have no need to default values of symbols. We could catch 3208 register names here, but that is handled by inserting them all in 3209 the symbol table to begin with. */ 3210 3211 symbolS * 3212 md_undefined_symbol (char *name) 3213 { 3214 /* The arc abi demands that a GOT[0] should be referencible as 3215 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a 3216 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */ 3217 if (((*name == '_') 3218 && (*(name+1) == 'G') 3219 && (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0)) 3220 || ((*name == '_') 3221 && (*(name+1) == 'D') 3222 && (strcmp (name, DYNAMIC_STRUCT_NAME) == 0))) 3223 { 3224 if (!GOT_symbol) 3225 { 3226 if (symbol_find (name)) 3227 as_bad ("GOT already in symbol table"); 3228 3229 GOT_symbol = symbol_new (GLOBAL_OFFSET_TABLE_NAME, undefined_section, 3230 (valueT) 0, &zero_address_frag); 3231 }; 3232 return GOT_symbol; 3233 } 3234 return NULL; 3235 } 3236 3237 /* Turn a string in input_line_pointer into a floating point constant 3238 of type type, and store the appropriate bytes in *litP. The number 3239 of LITTLENUMS emitted is stored in *sizeP. An error message is 3240 returned, or NULL on OK. */ 3241 3242 const char * 3243 md_atof (int type, char *litP, int *sizeP) 3244 { 3245 return ieee_md_atof (type, litP, sizeP, target_big_endian); 3246 } 3247 3248 /* Called for any expression that can not be recognized. When the 3249 function is called, `input_line_pointer' will point to the start of 3250 the expression. */ 3251 3252 void 3253 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED) 3254 { 3255 char *p = input_line_pointer; 3256 if (*p == '@') 3257 { 3258 input_line_pointer++; 3259 expressionP->X_op = O_symbol; 3260 expression (expressionP); 3261 } 3262 } 3263 3264 /* This function is called from the function 'expression', it attempts 3265 to parse special names (in our case register names). It fills in 3266 the expression with the identified register. It returns TRUE if 3267 it is a register and FALSE otherwise. */ 3268 3269 bfd_boolean 3270 arc_parse_name (const char *name, 3271 struct expressionS *e) 3272 { 3273 struct symbol *sym; 3274 3275 if (!assembling_insn) 3276 return FALSE; 3277 3278 /* Handle only registers. */ 3279 if (e->X_op != O_absent) 3280 return FALSE; 3281 3282 sym = hash_find (arc_reg_hash, name); 3283 if (sym) 3284 { 3285 e->X_op = O_register; 3286 e->X_add_number = S_GET_VALUE (sym); 3287 return TRUE; 3288 } 3289 return FALSE; 3290 } 3291 3292 /* md_parse_option 3293 Invocation line includes a switch not recognized by the base assembler. 3294 See if it's a processor-specific option. 3295 3296 New options (supported) are: 3297 3298 -mcpu=<cpu name> Assemble for selected processor 3299 -EB/-mbig-endian Big-endian 3300 -EL/-mlittle-endian Little-endian 3301 -mrelax Enable relaxation 3302 3303 The following CPU names are recognized: 3304 arc600, arc700, arcem, archs, nps400. */ 3305 3306 int 3307 md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED) 3308 { 3309 switch (c) 3310 { 3311 case OPTION_ARC600: 3312 case OPTION_ARC601: 3313 return md_parse_option (OPTION_MCPU, "arc600"); 3314 3315 case OPTION_ARC700: 3316 return md_parse_option (OPTION_MCPU, "arc700"); 3317 3318 case OPTION_ARCEM: 3319 return md_parse_option (OPTION_MCPU, "arcem"); 3320 3321 case OPTION_ARCHS: 3322 return md_parse_option (OPTION_MCPU, "archs"); 3323 3324 case OPTION_MCPU: 3325 { 3326 arc_select_cpu (arg); 3327 mach_type_specified_p = TRUE; 3328 break; 3329 } 3330 3331 case OPTION_EB: 3332 arc_target_format = "elf32-bigarc"; 3333 byte_order = BIG_ENDIAN; 3334 break; 3335 3336 case OPTION_EL: 3337 arc_target_format = "elf32-littlearc"; 3338 byte_order = LITTLE_ENDIAN; 3339 break; 3340 3341 case OPTION_CD: 3342 /* This option has an effect only on ARC EM. */ 3343 if (arc_target & ARC_OPCODE_ARCv2EM) 3344 arc_features |= ARC_CD; 3345 else 3346 as_warn (_("Code density option invalid for selected CPU")); 3347 break; 3348 3349 case OPTION_RELAX: 3350 relaxation_state = 1; 3351 break; 3352 3353 case OPTION_NPS400: 3354 arc_features |= ARC_NPS400; 3355 break; 3356 3357 case OPTION_SPFP: 3358 arc_features |= ARC_SPFP; 3359 break; 3360 3361 case OPTION_DPFP: 3362 arc_features |= ARC_DPFP; 3363 break; 3364 3365 case OPTION_FPUDA: 3366 /* This option has an effect only on ARC EM. */ 3367 if (arc_target & ARC_OPCODE_ARCv2EM) 3368 arc_features |= ARC_FPUDA; 3369 else 3370 as_warn (_("FPUDA invalid for selected CPU")); 3371 break; 3372 3373 /* Dummy options are accepted but have no effect. */ 3374 case OPTION_USER_MODE: 3375 case OPTION_LD_EXT_MASK: 3376 case OPTION_SWAP: 3377 case OPTION_NORM: 3378 case OPTION_BARREL_SHIFT: 3379 case OPTION_MIN_MAX: 3380 case OPTION_NO_MPY: 3381 case OPTION_EA: 3382 case OPTION_MUL64: 3383 case OPTION_SIMD: 3384 case OPTION_XMAC_D16: 3385 case OPTION_XMAC_24: 3386 case OPTION_DSP_PACKA: 3387 case OPTION_CRC: 3388 case OPTION_DVBF: 3389 case OPTION_TELEPHONY: 3390 case OPTION_XYMEMORY: 3391 case OPTION_LOCK: 3392 case OPTION_SWAPE: 3393 case OPTION_RTSC: 3394 break; 3395 3396 default: 3397 return 0; 3398 } 3399 3400 return 1; 3401 } 3402 3403 void 3404 md_show_usage (FILE *stream) 3405 { 3406 fprintf (stream, _("ARC-specific assembler options:\n")); 3407 3408 fprintf (stream, " -mcpu=<cpu name>\t assemble for CPU <cpu name> " 3409 "(default: %s)\n", TARGET_WITH_CPU); 3410 fprintf (stream, " -mcpu=nps400\t\t same as -mcpu=arc700 -mnps400\n"); 3411 fprintf (stream, " -mA6/-mARC600/-mARC601 same as -mcpu=arc600\n"); 3412 fprintf (stream, " -mA7/-mARC700\t\t same as -mcpu=arc700\n"); 3413 fprintf (stream, " -mEM\t\t\t same as -mcpu=arcem\n"); 3414 fprintf (stream, " -mHS\t\t\t same as -mcpu=archs\n"); 3415 3416 fprintf (stream, " -mnps400\t\t enable NPS-400 extended instructions\n"); 3417 fprintf (stream, " -mspfp\t\t enable single-precision floating point instructions\n"); 3418 fprintf (stream, " -mdpfp\t\t enable double-precision floating point instructions\n"); 3419 fprintf (stream, " -mfpuda\t\t enable double-precision assist floating " 3420 "point\n\t\t\t instructions for ARC EM\n"); 3421 3422 fprintf (stream, 3423 " -mcode-density\t enable code density option for ARC EM\n"); 3424 3425 fprintf (stream, _("\ 3426 -EB assemble code for a big-endian cpu\n")); 3427 fprintf (stream, _("\ 3428 -EL assemble code for a little-endian cpu\n")); 3429 fprintf (stream, _("\ 3430 -mrelax enable relaxation\n")); 3431 3432 fprintf (stream, _("The following ARC-specific assembler options are " 3433 "deprecated and are accepted\nfor compatibility only:\n")); 3434 3435 fprintf (stream, _(" -mEA\n" 3436 " -mbarrel-shifter\n" 3437 " -mbarrel_shifter\n" 3438 " -mcrc\n" 3439 " -mdsp-packa\n" 3440 " -mdsp_packa\n" 3441 " -mdvbf\n" 3442 " -mld-extension-reg-mask\n" 3443 " -mlock\n" 3444 " -mmac-24\n" 3445 " -mmac-d16\n" 3446 " -mmac_24\n" 3447 " -mmac_d16\n" 3448 " -mmin-max\n" 3449 " -mmin_max\n" 3450 " -mmul64\n" 3451 " -mno-mpy\n" 3452 " -mnorm\n" 3453 " -mrtsc\n" 3454 " -msimd\n" 3455 " -mswap\n" 3456 " -mswape\n" 3457 " -mtelephony\n" 3458 " -muser-mode-only\n" 3459 " -mxy\n")); 3460 } 3461 3462 /* Find the proper relocation for the given opcode. */ 3463 3464 static extended_bfd_reloc_code_real_type 3465 find_reloc (const char *name, 3466 const char *opcodename, 3467 const struct arc_flags *pflags, 3468 int nflg, 3469 extended_bfd_reloc_code_real_type reloc) 3470 { 3471 unsigned int i; 3472 int j; 3473 bfd_boolean found_flag, tmp; 3474 extended_bfd_reloc_code_real_type ret = BFD_RELOC_UNUSED; 3475 3476 for (i = 0; i < arc_num_equiv_tab; i++) 3477 { 3478 const struct arc_reloc_equiv_tab *r = &arc_reloc_equiv[i]; 3479 3480 /* Find the entry. */ 3481 if (strcmp (name, r->name)) 3482 continue; 3483 if (r->mnemonic && (strcmp (r->mnemonic, opcodename))) 3484 continue; 3485 if (r->flags[0]) 3486 { 3487 if (!nflg) 3488 continue; 3489 found_flag = FALSE; 3490 unsigned * psflg = (unsigned *)r->flags; 3491 do 3492 { 3493 tmp = FALSE; 3494 for (j = 0; j < nflg; j++) 3495 if (!strcmp (pflags[j].name, 3496 arc_flag_operands[*psflg].name)) 3497 { 3498 tmp = TRUE; 3499 break; 3500 } 3501 if (!tmp) 3502 { 3503 found_flag = FALSE; 3504 break; 3505 } 3506 else 3507 { 3508 found_flag = TRUE; 3509 } 3510 ++ psflg; 3511 } while (*psflg); 3512 3513 if (!found_flag) 3514 continue; 3515 } 3516 3517 if (reloc != r->oldreloc) 3518 continue; 3519 /* Found it. */ 3520 ret = r->newreloc; 3521 break; 3522 } 3523 3524 if (ret == BFD_RELOC_UNUSED) 3525 as_bad (_("Unable to find %s relocation for instruction %s"), 3526 name, opcodename); 3527 return ret; 3528 } 3529 3530 /* All the symbol types that are allowed to be used for 3531 relaxation. */ 3532 3533 static bfd_boolean 3534 may_relax_expr (expressionS tok) 3535 { 3536 /* Check if we have unrelaxable relocs. */ 3537 switch (tok.X_md) 3538 { 3539 default: 3540 break; 3541 case O_plt: 3542 return FALSE; 3543 } 3544 3545 switch (tok.X_op) 3546 { 3547 case O_symbol: 3548 case O_multiply: 3549 case O_divide: 3550 case O_modulus: 3551 case O_add: 3552 case O_subtract: 3553 break; 3554 3555 default: 3556 return FALSE; 3557 } 3558 return TRUE; 3559 } 3560 3561 /* Checks if flags are in line with relaxable insn. */ 3562 3563 static bfd_boolean 3564 relaxable_flag (const struct arc_relaxable_ins *ins, 3565 const struct arc_flags *pflags, 3566 int nflgs) 3567 { 3568 unsigned flag_class, 3569 flag, 3570 flag_class_idx = 0, 3571 flag_idx = 0; 3572 3573 const struct arc_flag_operand *flag_opand; 3574 int i, counttrue = 0; 3575 3576 /* Iterate through flags classes. */ 3577 while ((flag_class = ins->flag_classes[flag_class_idx]) != 0) 3578 { 3579 /* Iterate through flags in flag class. */ 3580 while ((flag = arc_flag_classes[flag_class].flags[flag_idx]) 3581 != 0) 3582 { 3583 flag_opand = &arc_flag_operands[flag]; 3584 /* Iterate through flags in ins to compare. */ 3585 for (i = 0; i < nflgs; ++i) 3586 { 3587 if (strcmp (flag_opand->name, pflags[i].name) == 0) 3588 ++counttrue; 3589 } 3590 3591 ++flag_idx; 3592 } 3593 3594 ++flag_class_idx; 3595 flag_idx = 0; 3596 } 3597 3598 /* If counttrue == nflgs, then all flags have been found. */ 3599 return (counttrue == nflgs ? TRUE : FALSE); 3600 } 3601 3602 /* Checks if operands are in line with relaxable insn. */ 3603 3604 static bfd_boolean 3605 relaxable_operand (const struct arc_relaxable_ins *ins, 3606 const expressionS *tok, 3607 int ntok) 3608 { 3609 const enum rlx_operand_type *operand = &ins->operands[0]; 3610 int i = 0; 3611 3612 while (*operand != EMPTY) 3613 { 3614 const expressionS *epr = &tok[i]; 3615 3616 if (i != 0 && i >= ntok) 3617 return FALSE; 3618 3619 switch (*operand) 3620 { 3621 case IMMEDIATE: 3622 if (!(epr->X_op == O_multiply 3623 || epr->X_op == O_divide 3624 || epr->X_op == O_modulus 3625 || epr->X_op == O_add 3626 || epr->X_op == O_subtract 3627 || epr->X_op == O_symbol)) 3628 return FALSE; 3629 break; 3630 3631 case REGISTER_DUP: 3632 if ((i <= 0) 3633 || (epr->X_add_number != tok[i - 1].X_add_number)) 3634 return FALSE; 3635 /* Fall through. */ 3636 case REGISTER: 3637 if (epr->X_op != O_register) 3638 return FALSE; 3639 break; 3640 3641 case REGISTER_S: 3642 if (epr->X_op != O_register) 3643 return FALSE; 3644 3645 switch (epr->X_add_number) 3646 { 3647 case 0: case 1: case 2: case 3: 3648 case 12: case 13: case 14: case 15: 3649 break; 3650 default: 3651 return FALSE; 3652 } 3653 break; 3654 3655 case REGISTER_NO_GP: 3656 if ((epr->X_op != O_register) 3657 || (epr->X_add_number == 26)) /* 26 is the gp register. */ 3658 return FALSE; 3659 break; 3660 3661 case BRACKET: 3662 if (epr->X_op != O_bracket) 3663 return FALSE; 3664 break; 3665 3666 default: 3667 /* Don't understand, bail out. */ 3668 return FALSE; 3669 break; 3670 } 3671 3672 ++i; 3673 operand = &ins->operands[i]; 3674 } 3675 3676 return (i == ntok ? TRUE : FALSE); 3677 } 3678 3679 /* Return TRUE if this OPDCODE is a candidate for relaxation. */ 3680 3681 static bfd_boolean 3682 relax_insn_p (const struct arc_opcode *opcode, 3683 const expressionS *tok, 3684 int ntok, 3685 const struct arc_flags *pflags, 3686 int nflg) 3687 { 3688 unsigned i; 3689 bfd_boolean rv = FALSE; 3690 3691 /* Check the relaxation table. */ 3692 for (i = 0; i < arc_num_relaxable_ins && relaxation_state; ++i) 3693 { 3694 const struct arc_relaxable_ins *arc_rlx_ins = &arc_relaxable_insns[i]; 3695 3696 if ((strcmp (opcode->name, arc_rlx_ins->mnemonic_r) == 0) 3697 && may_relax_expr (tok[arc_rlx_ins->opcheckidx]) 3698 && relaxable_operand (arc_rlx_ins, tok, ntok) 3699 && relaxable_flag (arc_rlx_ins, pflags, nflg)) 3700 { 3701 rv = TRUE; 3702 frag_now->fr_subtype = arc_relaxable_insns[i].subtype; 3703 memcpy (&frag_now->tc_frag_data.tok, tok, 3704 sizeof (expressionS) * ntok); 3705 memcpy (&frag_now->tc_frag_data.pflags, pflags, 3706 sizeof (struct arc_flags) * nflg); 3707 frag_now->tc_frag_data.nflg = nflg; 3708 frag_now->tc_frag_data.ntok = ntok; 3709 break; 3710 } 3711 } 3712 3713 return rv; 3714 } 3715 3716 /* Turn an opcode description and a set of arguments into 3717 an instruction and a fixup. */ 3718 3719 static void 3720 assemble_insn (const struct arc_opcode *opcode, 3721 const expressionS *tok, 3722 int ntok, 3723 const struct arc_flags *pflags, 3724 int nflg, 3725 struct arc_insn *insn) 3726 { 3727 const expressionS *reloc_exp = NULL; 3728 unsigned image; 3729 const unsigned char *argidx; 3730 int i; 3731 int tokidx = 0; 3732 unsigned char pcrel = 0; 3733 bfd_boolean needGOTSymbol; 3734 bfd_boolean has_delay_slot = FALSE; 3735 extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED; 3736 3737 memset (insn, 0, sizeof (*insn)); 3738 image = opcode->opcode; 3739 3740 pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n", 3741 frag_now->fr_file, frag_now->fr_line, opcode->name, 3742 opcode->opcode); 3743 3744 /* Handle operands. */ 3745 for (argidx = opcode->operands; *argidx; ++argidx) 3746 { 3747 const struct arc_operand *operand = &arc_operands[*argidx]; 3748 const expressionS *t = (const expressionS *) 0; 3749 3750 if ((operand->flags & ARC_OPERAND_FAKE) 3751 && !(operand->flags & ARC_OPERAND_BRAKET)) 3752 continue; 3753 3754 if (operand->flags & ARC_OPERAND_DUPLICATE) 3755 { 3756 /* Duplicate operand, already inserted. */ 3757 tokidx ++; 3758 continue; 3759 } 3760 3761 if (tokidx >= ntok) 3762 { 3763 abort (); 3764 } 3765 else 3766 t = &tok[tokidx++]; 3767 3768 /* Regardless if we have a reloc or not mark the instruction 3769 limm if it is the case. */ 3770 if (operand->flags & ARC_OPERAND_LIMM) 3771 insn->has_limm = TRUE; 3772 3773 switch (t->X_op) 3774 { 3775 case O_register: 3776 image = insert_operand (image, operand, regno (t->X_add_number), 3777 NULL, 0); 3778 break; 3779 3780 case O_constant: 3781 image = insert_operand (image, operand, t->X_add_number, NULL, 0); 3782 reloc_exp = t; 3783 if (operand->flags & ARC_OPERAND_LIMM) 3784 insn->limm = t->X_add_number; 3785 break; 3786 3787 case O_bracket: 3788 /* Ignore brackets. */ 3789 break; 3790 3791 case O_absent: 3792 gas_assert (operand->flags & ARC_OPERAND_IGNORE); 3793 break; 3794 3795 case O_subtract: 3796 /* Maybe register range. */ 3797 if ((t->X_add_number == 0) 3798 && contains_register (t->X_add_symbol) 3799 && contains_register (t->X_op_symbol)) 3800 { 3801 int regs; 3802 3803 regs = get_register (t->X_add_symbol); 3804 regs <<= 16; 3805 regs |= get_register (t->X_op_symbol); 3806 image = insert_operand (image, operand, regs, NULL, 0); 3807 break; 3808 } 3809 3810 default: 3811 /* This operand needs a relocation. */ 3812 needGOTSymbol = FALSE; 3813 3814 switch (t->X_md) 3815 { 3816 case O_plt: 3817 if (opcode->insn_class == JUMP) 3818 as_bad_where (frag_now->fr_file, frag_now->fr_line, 3819 _("Unable to use @plt relocatio for insn %s"), 3820 opcode->name); 3821 needGOTSymbol = TRUE; 3822 reloc = find_reloc ("plt", opcode->name, 3823 pflags, nflg, 3824 operand->default_reloc); 3825 break; 3826 3827 case O_gotoff: 3828 case O_gotpc: 3829 needGOTSymbol = TRUE; 3830 reloc = ARC_RELOC_TABLE (t->X_md)->reloc; 3831 break; 3832 case O_pcl: 3833 reloc = ARC_RELOC_TABLE (t->X_md)->reloc; 3834 if (ARC_SHORT (opcode->mask) || opcode->insn_class == JUMP) 3835 as_bad_where (frag_now->fr_file, frag_now->fr_line, 3836 _("Unable to use @pcl relocation for insn %s"), 3837 opcode->name); 3838 break; 3839 case O_sda: 3840 reloc = find_reloc ("sda", opcode->name, 3841 pflags, nflg, 3842 operand->default_reloc); 3843 break; 3844 case O_tlsgd: 3845 case O_tlsie: 3846 needGOTSymbol = TRUE; 3847 /* Fall-through. */ 3848 3849 case O_tpoff: 3850 case O_dtpoff: 3851 reloc = ARC_RELOC_TABLE (t->X_md)->reloc; 3852 break; 3853 3854 case O_tpoff9: /*FIXME! Check for the conditionality of 3855 the insn. */ 3856 case O_dtpoff9: /*FIXME! Check for the conditionality of 3857 the insn. */ 3858 as_bad (_("TLS_*_S9 relocs are not supported yet")); 3859 break; 3860 3861 default: 3862 /* Just consider the default relocation. */ 3863 reloc = operand->default_reloc; 3864 break; 3865 } 3866 3867 if (needGOTSymbol && (GOT_symbol == NULL)) 3868 GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME); 3869 3870 reloc_exp = t; 3871 3872 #if 0 3873 if (reloc > 0) 3874 { 3875 /* sanity checks. */ 3876 reloc_howto_type *reloc_howto 3877 = bfd_reloc_type_lookup (stdoutput, 3878 (bfd_reloc_code_real_type) reloc); 3879 unsigned reloc_bitsize = reloc_howto->bitsize; 3880 if (reloc_howto->rightshift) 3881 reloc_bitsize -= reloc_howto->rightshift; 3882 if (reloc_bitsize != operand->bits) 3883 { 3884 as_bad (_("invalid relocation %s for field"), 3885 bfd_get_reloc_code_name (reloc)); 3886 return; 3887 } 3888 } 3889 #endif 3890 if (insn->nfixups >= MAX_INSN_FIXUPS) 3891 as_fatal (_("too many fixups")); 3892 3893 struct arc_fixup *fixup; 3894 fixup = &insn->fixups[insn->nfixups++]; 3895 fixup->exp = *t; 3896 fixup->reloc = reloc; 3897 pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0; 3898 fixup->pcrel = pcrel; 3899 fixup->islong = (operand->flags & ARC_OPERAND_LIMM) ? 3900 TRUE : FALSE; 3901 break; 3902 } 3903 } 3904 3905 /* Handle flags. */ 3906 for (i = 0; i < nflg; i++) 3907 { 3908 const struct arc_flag_operand *flg_operand = pflags[i].flgp; 3909 3910 /* Check if the instruction has a delay slot. */ 3911 if (!strcmp (flg_operand->name, "d")) 3912 has_delay_slot = TRUE; 3913 3914 /* There is an exceptional case when we cannot insert a flag 3915 just as it is. The .T flag must be handled in relation with 3916 the relative address. */ 3917 if (!strcmp (flg_operand->name, "t") 3918 || !strcmp (flg_operand->name, "nt")) 3919 { 3920 unsigned bitYoperand = 0; 3921 /* FIXME! move selection bbit/brcc in arc-opc.c. */ 3922 if (!strcmp (flg_operand->name, "t")) 3923 if (!strcmp (opcode->name, "bbit0") 3924 || !strcmp (opcode->name, "bbit1")) 3925 bitYoperand = arc_NToperand; 3926 else 3927 bitYoperand = arc_Toperand; 3928 else 3929 if (!strcmp (opcode->name, "bbit0") 3930 || !strcmp (opcode->name, "bbit1")) 3931 bitYoperand = arc_Toperand; 3932 else 3933 bitYoperand = arc_NToperand; 3934 3935 gas_assert (reloc_exp != NULL); 3936 if (reloc_exp->X_op == O_constant) 3937 { 3938 /* Check if we have a constant and solved it 3939 immediately. */ 3940 offsetT val = reloc_exp->X_add_number; 3941 image |= insert_operand (image, &arc_operands[bitYoperand], 3942 val, NULL, 0); 3943 } 3944 else 3945 { 3946 struct arc_fixup *fixup; 3947 3948 if (insn->nfixups >= MAX_INSN_FIXUPS) 3949 as_fatal (_("too many fixups")); 3950 3951 fixup = &insn->fixups[insn->nfixups++]; 3952 fixup->exp = *reloc_exp; 3953 fixup->reloc = -bitYoperand; 3954 fixup->pcrel = pcrel; 3955 fixup->islong = FALSE; 3956 } 3957 } 3958 else 3959 image |= (flg_operand->code & ((1 << flg_operand->bits) - 1)) 3960 << flg_operand->shift; 3961 } 3962 3963 insn->relax = relax_insn_p (opcode, tok, ntok, pflags, nflg); 3964 3965 /* Short instruction? */ 3966 insn->short_insn = ARC_SHORT (opcode->mask) ? TRUE : FALSE; 3967 3968 insn->insn = image; 3969 3970 /* Update last insn status. */ 3971 arc_last_insns[1] = arc_last_insns[0]; 3972 arc_last_insns[0].opcode = opcode; 3973 arc_last_insns[0].has_limm = insn->has_limm; 3974 arc_last_insns[0].has_delay_slot = has_delay_slot; 3975 3976 /* Check if the current instruction is legally used. */ 3977 if (arc_last_insns[1].has_delay_slot 3978 && is_br_jmp_insn_p (arc_last_insns[0].opcode)) 3979 as_bad_where (frag_now->fr_file, frag_now->fr_line, 3980 _("A jump/branch instruction in delay slot.")); 3981 } 3982 3983 void 3984 arc_handle_align (fragS* fragP) 3985 { 3986 if ((fragP)->fr_type == rs_align_code) 3987 { 3988 char *dest = (fragP)->fr_literal + (fragP)->fr_fix; 3989 valueT count = ((fragP)->fr_next->fr_address 3990 - (fragP)->fr_address - (fragP)->fr_fix); 3991 3992 (fragP)->fr_var = 2; 3993 3994 if (count & 1)/* Padding in the gap till the next 2-byte 3995 boundary with 0s. */ 3996 { 3997 (fragP)->fr_fix++; 3998 *dest++ = 0; 3999 } 4000 /* Writing nop_s. */ 4001 md_number_to_chars (dest, NOP_OPCODE_S, 2); 4002 } 4003 } 4004 4005 /* Here we decide which fixups can be adjusted to make them relative 4006 to the beginning of the section instead of the symbol. Basically 4007 we need to make sure that the dynamic relocations are done 4008 correctly, so in some cases we force the original symbol to be 4009 used. */ 4010 4011 int 4012 tc_arc_fix_adjustable (fixS *fixP) 4013 { 4014 4015 /* Prevent all adjustments to global symbols. */ 4016 if (S_IS_EXTERNAL (fixP->fx_addsy)) 4017 return 0; 4018 if (S_IS_WEAK (fixP->fx_addsy)) 4019 return 0; 4020 4021 /* Adjust_reloc_syms doesn't know about the GOT. */ 4022 switch (fixP->fx_r_type) 4023 { 4024 case BFD_RELOC_ARC_GOTPC32: 4025 case BFD_RELOC_ARC_PLT32: 4026 case BFD_RELOC_ARC_S25H_PCREL_PLT: 4027 case BFD_RELOC_ARC_S21H_PCREL_PLT: 4028 case BFD_RELOC_ARC_S25W_PCREL_PLT: 4029 case BFD_RELOC_ARC_S21W_PCREL_PLT: 4030 return 0; 4031 4032 default: 4033 break; 4034 } 4035 4036 return 1; 4037 } 4038 4039 /* Compute the reloc type of an expression EXP. */ 4040 4041 static void 4042 arc_check_reloc (expressionS *exp, 4043 bfd_reloc_code_real_type *r_type_p) 4044 { 4045 if (*r_type_p == BFD_RELOC_32 4046 && exp->X_op == O_subtract 4047 && exp->X_op_symbol != NULL 4048 && exp->X_op_symbol->bsym->section == now_seg) 4049 *r_type_p = BFD_RELOC_ARC_32_PCREL; 4050 } 4051 4052 4053 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */ 4054 4055 void 4056 arc_cons_fix_new (fragS *frag, 4057 int off, 4058 int size, 4059 expressionS *exp, 4060 bfd_reloc_code_real_type r_type) 4061 { 4062 r_type = BFD_RELOC_UNUSED; 4063 4064 switch (size) 4065 { 4066 case 1: 4067 r_type = BFD_RELOC_8; 4068 break; 4069 4070 case 2: 4071 r_type = BFD_RELOC_16; 4072 break; 4073 4074 case 3: 4075 r_type = BFD_RELOC_24; 4076 break; 4077 4078 case 4: 4079 r_type = BFD_RELOC_32; 4080 arc_check_reloc (exp, &r_type); 4081 break; 4082 4083 case 8: 4084 r_type = BFD_RELOC_64; 4085 break; 4086 4087 default: 4088 as_bad (_("unsupported BFD relocation size %u"), size); 4089 r_type = BFD_RELOC_UNUSED; 4090 } 4091 4092 fix_new_exp (frag, off, size, exp, 0, r_type); 4093 } 4094 4095 /* The actual routine that checks the ZOL conditions. */ 4096 4097 static void 4098 check_zol (symbolS *s) 4099 { 4100 switch (arc_mach_type) 4101 { 4102 case bfd_mach_arc_arcv2: 4103 if (arc_target & ARC_OPCODE_ARCv2EM) 4104 return; 4105 4106 if (is_br_jmp_insn_p (arc_last_insns[0].opcode) 4107 || arc_last_insns[1].has_delay_slot) 4108 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"), 4109 S_GET_NAME (s)); 4110 4111 break; 4112 case bfd_mach_arc_arc600: 4113 4114 if (is_kernel_insn_p (arc_last_insns[0].opcode)) 4115 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"), 4116 S_GET_NAME (s)); 4117 4118 if (arc_last_insns[0].has_limm 4119 && is_br_jmp_insn_p (arc_last_insns[0].opcode)) 4120 as_bad (_("A jump instruction with long immediate detected at the \ 4121 end of the ZOL label @%s"), S_GET_NAME (s)); 4122 4123 /* Fall through. */ 4124 case bfd_mach_arc_arc700: 4125 if (arc_last_insns[0].has_delay_slot) 4126 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"), 4127 S_GET_NAME (s)); 4128 4129 break; 4130 default: 4131 break; 4132 } 4133 } 4134 4135 /* If ZOL end check the last two instruction for illegals. */ 4136 void 4137 arc_frob_label (symbolS * sym) 4138 { 4139 if (ARC_GET_FLAG (sym) & ARC_FLAG_ZOL) 4140 check_zol (sym); 4141 4142 dwarf2_emit_label (sym); 4143 } 4144 4145 /* Used because generic relaxation assumes a pc-rel value whilst we 4146 also relax instructions that use an absolute value resolved out of 4147 relative values (if that makes any sense). An example: 'add r1, 4148 r2, @.L2 - .' The symbols . and @.L2 are relative to the section 4149 but if they're in the same section we can subtract the section 4150 offset relocation which ends up in a resolved value. So if @.L2 is 4151 .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 - 4152 .text + 0x40 = 0x10. */ 4153 int 4154 arc_pcrel_adjust (fragS *fragP) 4155 { 4156 if (!fragP->tc_frag_data.pcrel) 4157 return fragP->fr_address + fragP->fr_fix; 4158 4159 return 0; 4160 } 4161 4162 /* Initialize the DWARF-2 unwind information for this procedure. */ 4163 4164 void 4165 tc_arc_frame_initial_instructions (void) 4166 { 4167 /* Stack pointer is register 28. */ 4168 cfi_add_CFA_def_cfa (28, 0); 4169 } 4170 4171 int 4172 tc_arc_regname_to_dw2regnum (char *regname) 4173 { 4174 struct symbol *sym; 4175 4176 sym = hash_find (arc_reg_hash, regname); 4177 if (sym) 4178 return S_GET_VALUE (sym); 4179 4180 return -1; 4181 } 4182 4183 /* Adjust the symbol table. Delete found AUX register symbols. */ 4184 4185 void 4186 arc_adjust_symtab (void) 4187 { 4188 symbolS * sym; 4189 4190 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym)) 4191 { 4192 /* I've created a symbol during parsing process. Now, remove 4193 the symbol as it is found to be an AUX register. */ 4194 if (ARC_GET_FLAG (sym) & ARC_FLAG_AUX) 4195 symbol_remove (sym, &symbol_rootP, &symbol_lastP); 4196 } 4197 4198 /* Now do generic ELF adjustments. */ 4199 elf_adjust_symtab (); 4200 } 4201 4202 static void 4203 tokenize_extinsn (extInstruction_t *einsn) 4204 { 4205 char *p, c; 4206 char *insn_name; 4207 unsigned char major_opcode; 4208 unsigned char sub_opcode; 4209 unsigned char syntax_class = 0; 4210 unsigned char syntax_class_modifiers = 0; 4211 unsigned char suffix_class = 0; 4212 unsigned int i; 4213 4214 SKIP_WHITESPACE (); 4215 4216 /* 1st: get instruction name. */ 4217 p = input_line_pointer; 4218 c = get_symbol_name (&p); 4219 4220 insn_name = xstrdup (p); 4221 restore_line_pointer (c); 4222 4223 /* 2nd: get major opcode. */ 4224 if (*input_line_pointer != ',') 4225 { 4226 as_bad (_("expected comma after instruction name")); 4227 ignore_rest_of_line (); 4228 return; 4229 } 4230 input_line_pointer++; 4231 major_opcode = get_absolute_expression (); 4232 4233 /* 3rd: get sub-opcode. */ 4234 SKIP_WHITESPACE (); 4235 4236 if (*input_line_pointer != ',') 4237 { 4238 as_bad (_("expected comma after major opcode")); 4239 ignore_rest_of_line (); 4240 return; 4241 } 4242 input_line_pointer++; 4243 sub_opcode = get_absolute_expression (); 4244 4245 /* 4th: get suffix class. */ 4246 SKIP_WHITESPACE (); 4247 4248 if (*input_line_pointer != ',') 4249 { 4250 as_bad ("expected comma after sub opcode"); 4251 ignore_rest_of_line (); 4252 return; 4253 } 4254 input_line_pointer++; 4255 4256 while (1) 4257 { 4258 SKIP_WHITESPACE (); 4259 4260 for (i = 0; i < ARRAY_SIZE (suffixclass); i++) 4261 { 4262 if (!strncmp (suffixclass[i].name, input_line_pointer, 4263 suffixclass[i].len)) 4264 { 4265 suffix_class |= suffixclass[i].attr_class; 4266 input_line_pointer += suffixclass[i].len; 4267 break; 4268 } 4269 } 4270 4271 if (i == ARRAY_SIZE (suffixclass)) 4272 { 4273 as_bad ("invalid suffix class"); 4274 ignore_rest_of_line (); 4275 return; 4276 } 4277 4278 SKIP_WHITESPACE (); 4279 4280 if (*input_line_pointer == '|') 4281 input_line_pointer++; 4282 else 4283 break; 4284 } 4285 4286 /* 5th: get syntax class and syntax class modifiers. */ 4287 if (*input_line_pointer != ',') 4288 { 4289 as_bad ("expected comma after suffix class"); 4290 ignore_rest_of_line (); 4291 return; 4292 } 4293 input_line_pointer++; 4294 4295 while (1) 4296 { 4297 SKIP_WHITESPACE (); 4298 4299 for (i = 0; i < ARRAY_SIZE (syntaxclassmod); i++) 4300 { 4301 if (!strncmp (syntaxclassmod[i].name, 4302 input_line_pointer, 4303 syntaxclassmod[i].len)) 4304 { 4305 syntax_class_modifiers |= syntaxclassmod[i].attr_class; 4306 input_line_pointer += syntaxclassmod[i].len; 4307 break; 4308 } 4309 } 4310 4311 if (i == ARRAY_SIZE (syntaxclassmod)) 4312 { 4313 for (i = 0; i < ARRAY_SIZE (syntaxclass); i++) 4314 { 4315 if (!strncmp (syntaxclass[i].name, 4316 input_line_pointer, 4317 syntaxclass[i].len)) 4318 { 4319 syntax_class |= syntaxclass[i].attr_class; 4320 input_line_pointer += syntaxclass[i].len; 4321 break; 4322 } 4323 } 4324 4325 if (i == ARRAY_SIZE (syntaxclass)) 4326 { 4327 as_bad ("missing syntax class"); 4328 ignore_rest_of_line (); 4329 return; 4330 } 4331 } 4332 4333 SKIP_WHITESPACE (); 4334 4335 if (*input_line_pointer == '|') 4336 input_line_pointer++; 4337 else 4338 break; 4339 } 4340 4341 demand_empty_rest_of_line (); 4342 4343 einsn->name = insn_name; 4344 einsn->major = major_opcode; 4345 einsn->minor = sub_opcode; 4346 einsn->syntax = syntax_class; 4347 einsn->modsyn = syntax_class_modifiers; 4348 einsn->suffix = suffix_class; 4349 einsn->flags = syntax_class 4350 | (syntax_class_modifiers & ARC_OP1_IMM_IMPLIED ? 0x10 : 0); 4351 } 4352 4353 /* Generate an extension section. */ 4354 4355 static int 4356 arc_set_ext_seg (void) 4357 { 4358 if (!arcext_section) 4359 { 4360 arcext_section = subseg_new (".arcextmap", 0); 4361 bfd_set_section_flags (stdoutput, arcext_section, 4362 SEC_READONLY | SEC_HAS_CONTENTS); 4363 } 4364 else 4365 subseg_set (arcext_section, 0); 4366 return 1; 4367 } 4368 4369 /* Create an extension instruction description in the arc extension 4370 section of the output file. 4371 The structure for an instruction is like this: 4372 [0]: Length of the record. 4373 [1]: Type of the record. 4374 4375 [2]: Major opcode. 4376 [3]: Sub-opcode. 4377 [4]: Syntax (flags). 4378 [5]+ Name instruction. 4379 4380 The sequence is terminated by an empty entry. */ 4381 4382 static void 4383 create_extinst_section (extInstruction_t *einsn) 4384 { 4385 4386 segT old_sec = now_seg; 4387 int old_subsec = now_subseg; 4388 char *p; 4389 int name_len = strlen (einsn->name); 4390 4391 arc_set_ext_seg (); 4392 4393 p = frag_more (1); 4394 *p = 5 + name_len + 1; 4395 p = frag_more (1); 4396 *p = EXT_INSTRUCTION; 4397 p = frag_more (1); 4398 *p = einsn->major; 4399 p = frag_more (1); 4400 *p = einsn->minor; 4401 p = frag_more (1); 4402 *p = einsn->flags; 4403 p = frag_more (name_len + 1); 4404 strcpy (p, einsn->name); 4405 4406 subseg_set (old_sec, old_subsec); 4407 } 4408 4409 /* Handler .extinstruction pseudo-op. */ 4410 4411 static void 4412 arc_extinsn (int ignore ATTRIBUTE_UNUSED) 4413 { 4414 extInstruction_t einsn; 4415 struct arc_opcode *arc_ext_opcodes; 4416 const char *errmsg = NULL; 4417 unsigned char moplow, mophigh; 4418 4419 memset (&einsn, 0, sizeof (einsn)); 4420 tokenize_extinsn (&einsn); 4421 4422 /* Check if the name is already used. */ 4423 if (arc_find_opcode (einsn.name)) 4424 as_warn (_("Pseudocode already used %s"), einsn.name); 4425 4426 /* Check the opcode ranges. */ 4427 moplow = 0x05; 4428 mophigh = (arc_target & (ARC_OPCODE_ARCv2EM 4429 | ARC_OPCODE_ARCv2HS)) ? 0x07 : 0x0a; 4430 4431 if ((einsn.major > mophigh) || (einsn.major < moplow)) 4432 as_fatal (_("major opcode not in range [0x%02x - 0x%02x]"), moplow, mophigh); 4433 4434 if ((einsn.minor > 0x3f) && (einsn.major != 0x0a) 4435 && (einsn.major != 5) && (einsn.major != 9)) 4436 as_fatal (_("minor opcode not in range [0x00 - 0x3f]")); 4437 4438 switch (einsn.syntax & ARC_SYNTAX_MASK) 4439 { 4440 case ARC_SYNTAX_3OP: 4441 if (einsn.modsyn & ARC_OP1_IMM_IMPLIED) 4442 as_fatal (_("Improper use of OP1_IMM_IMPLIED")); 4443 break; 4444 case ARC_SYNTAX_2OP: 4445 case ARC_SYNTAX_1OP: 4446 case ARC_SYNTAX_NOP: 4447 if (einsn.modsyn & ARC_OP1_MUST_BE_IMM) 4448 as_fatal (_("Improper use of OP1_MUST_BE_IMM")); 4449 break; 4450 default: 4451 break; 4452 } 4453 4454 arc_ext_opcodes = arcExtMap_genOpcode (&einsn, arc_target, &errmsg); 4455 if (arc_ext_opcodes == NULL) 4456 { 4457 if (errmsg) 4458 as_fatal ("%s", errmsg); 4459 else 4460 as_fatal (_("Couldn't generate extension instruction opcodes")); 4461 } 4462 else if (errmsg) 4463 as_warn ("%s", errmsg); 4464 4465 /* Insert the extension instruction. */ 4466 arc_insert_opcode ((const struct arc_opcode *) arc_ext_opcodes); 4467 4468 create_extinst_section (&einsn); 4469 } 4470 4471 static void 4472 tokenize_extregister (extRegister_t *ereg, int opertype) 4473 { 4474 char *name; 4475 char *mode; 4476 char c; 4477 char *p; 4478 int number, imode = 0; 4479 bfd_boolean isCore_p = (opertype == EXT_CORE_REGISTER) ? TRUE : FALSE; 4480 bfd_boolean isReg_p = (opertype == EXT_CORE_REGISTER 4481 || opertype == EXT_AUX_REGISTER) ? TRUE : FALSE; 4482 4483 /* 1st: get register name. */ 4484 SKIP_WHITESPACE (); 4485 p = input_line_pointer; 4486 c = get_symbol_name (&p); 4487 4488 name = xstrdup (p); 4489 restore_line_pointer (c); 4490 4491 /* 2nd: get register number. */ 4492 SKIP_WHITESPACE (); 4493 4494 if (*input_line_pointer != ',') 4495 { 4496 as_bad (_("expected comma after register name")); 4497 ignore_rest_of_line (); 4498 free (name); 4499 return; 4500 } 4501 input_line_pointer++; 4502 number = get_absolute_expression (); 4503 4504 if (number < 0) 4505 { 4506 as_bad (_("negative operand number %d"), number); 4507 ignore_rest_of_line (); 4508 free (name); 4509 return; 4510 } 4511 4512 if (isReg_p) 4513 { 4514 /* 3rd: get register mode. */ 4515 SKIP_WHITESPACE (); 4516 4517 if (*input_line_pointer != ',') 4518 { 4519 as_bad (_("expected comma after register number")); 4520 ignore_rest_of_line (); 4521 free (name); 4522 return; 4523 } 4524 4525 input_line_pointer++; 4526 mode = input_line_pointer; 4527 4528 if (!strncmp (mode, "r|w", 3)) 4529 { 4530 imode = 0; 4531 input_line_pointer += 3; 4532 } 4533 else if (!strncmp (mode, "r", 1)) 4534 { 4535 imode = ARC_REGISTER_READONLY; 4536 input_line_pointer += 1; 4537 } 4538 else if (strncmp (mode, "w", 1)) 4539 { 4540 as_bad (_("invalid mode")); 4541 ignore_rest_of_line (); 4542 free (name); 4543 return; 4544 } 4545 else 4546 { 4547 imode = ARC_REGISTER_WRITEONLY; 4548 input_line_pointer += 1; 4549 } 4550 } 4551 4552 if (isCore_p) 4553 { 4554 /* 4th: get core register shortcut. */ 4555 SKIP_WHITESPACE (); 4556 if (*input_line_pointer != ',') 4557 { 4558 as_bad (_("expected comma after register mode")); 4559 ignore_rest_of_line (); 4560 free (name); 4561 return; 4562 } 4563 4564 input_line_pointer++; 4565 4566 if (!strncmp (input_line_pointer, "cannot_shortcut", 15)) 4567 { 4568 imode |= ARC_REGISTER_NOSHORT_CUT; 4569 input_line_pointer += 15; 4570 } 4571 else if (strncmp (input_line_pointer, "can_shortcut", 12)) 4572 { 4573 as_bad (_("shortcut designator invalid")); 4574 ignore_rest_of_line (); 4575 free (name); 4576 return; 4577 } 4578 else 4579 { 4580 input_line_pointer += 12; 4581 } 4582 } 4583 demand_empty_rest_of_line (); 4584 4585 ereg->name = name; 4586 ereg->number = number; 4587 ereg->imode = imode; 4588 } 4589 4590 /* Create an extension register/condition description in the arc 4591 extension section of the output file. 4592 4593 The structure for an instruction is like this: 4594 [0]: Length of the record. 4595 [1]: Type of the record. 4596 4597 For core regs and condition codes: 4598 [2]: Value. 4599 [3]+ Name. 4600 4601 For auxilirary registers: 4602 [2..5]: Value. 4603 [6]+ Name 4604 4605 The sequence is terminated by an empty entry. */ 4606 4607 static void 4608 create_extcore_section (extRegister_t *ereg, int opertype) 4609 { 4610 segT old_sec = now_seg; 4611 int old_subsec = now_subseg; 4612 char *p; 4613 int name_len = strlen (ereg->name); 4614 4615 arc_set_ext_seg (); 4616 4617 switch (opertype) 4618 { 4619 case EXT_COND_CODE: 4620 case EXT_CORE_REGISTER: 4621 p = frag_more (1); 4622 *p = 3 + name_len + 1; 4623 p = frag_more (1); 4624 *p = opertype; 4625 p = frag_more (1); 4626 *p = ereg->number; 4627 break; 4628 case EXT_AUX_REGISTER: 4629 p = frag_more (1); 4630 *p = 6 + name_len + 1; 4631 p = frag_more (1); 4632 *p = EXT_AUX_REGISTER; 4633 p = frag_more (1); 4634 *p = (ereg->number >> 24) & 0xff; 4635 p = frag_more (1); 4636 *p = (ereg->number >> 16) & 0xff; 4637 p = frag_more (1); 4638 *p = (ereg->number >> 8) & 0xff; 4639 p = frag_more (1); 4640 *p = (ereg->number) & 0xff; 4641 break; 4642 default: 4643 break; 4644 } 4645 4646 p = frag_more (name_len + 1); 4647 strcpy (p, ereg->name); 4648 4649 subseg_set (old_sec, old_subsec); 4650 } 4651 4652 /* Handler .extCoreRegister pseudo-op. */ 4653 4654 static void 4655 arc_extcorereg (int opertype) 4656 { 4657 extRegister_t ereg; 4658 struct arc_aux_reg *auxr; 4659 const char *retval; 4660 struct arc_flag_operand *ccode; 4661 4662 memset (&ereg, 0, sizeof (ereg)); 4663 tokenize_extregister (&ereg, opertype); 4664 4665 switch (opertype) 4666 { 4667 case EXT_CORE_REGISTER: 4668 /* Core register. */ 4669 if (ereg.number > 60) 4670 as_bad (_("core register %s value (%d) too large"), ereg.name, 4671 ereg.number); 4672 declare_register (ereg.name, ereg.number); 4673 break; 4674 case EXT_AUX_REGISTER: 4675 /* Auxiliary register. */ 4676 auxr = XNEW (struct arc_aux_reg); 4677 auxr->name = ereg.name; 4678 auxr->cpu = arc_target; 4679 auxr->subclass = NONE; 4680 auxr->address = ereg.number; 4681 retval = hash_insert (arc_aux_hash, auxr->name, (void *) auxr); 4682 if (retval) 4683 as_fatal (_("internal error: can't hash aux register '%s': %s"), 4684 auxr->name, retval); 4685 break; 4686 case EXT_COND_CODE: 4687 /* Condition code. */ 4688 if (ereg.number > 31) 4689 as_bad (_("condition code %s value (%d) too large"), ereg.name, 4690 ereg.number); 4691 ext_condcode.size ++; 4692 ext_condcode.arc_ext_condcode = 4693 XRESIZEVEC (struct arc_flag_operand, ext_condcode.arc_ext_condcode, 4694 ext_condcode.size + 1); 4695 if (ext_condcode.arc_ext_condcode == NULL) 4696 as_fatal (_("Virtual memory exhausted")); 4697 4698 ccode = ext_condcode.arc_ext_condcode + ext_condcode.size - 1; 4699 ccode->name = ereg.name; 4700 ccode->code = ereg.number; 4701 ccode->bits = 5; 4702 ccode->shift = 0; 4703 ccode->favail = 0; /* not used. */ 4704 ccode++; 4705 memset (ccode, 0, sizeof (struct arc_flag_operand)); 4706 break; 4707 default: 4708 as_bad (_("Unknown extension")); 4709 break; 4710 } 4711 create_extcore_section (&ereg, opertype); 4712 } 4713 4714 /* Local variables: 4715 eval: (c-set-style "gnu") 4716 indent-tabs-mode: t 4717 End: */ 4718