1 /* tc-iq2000.c -- Assembler for the Sitera IQ2000. 2 Copyright (C) 2003-2022 Free Software Foundation, Inc. 3 4 This file is part of GAS, the GNU Assembler. 5 6 GAS is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 GAS is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GAS; see the file COPYING. If not, write to 18 the Free Software Foundation, 51 Franklin Street - Fifth Floor, 19 Boston, MA 02110-1301, USA. */ 20 21 #include "as.h" 22 #include "safe-ctype.h" 23 #include "subsegs.h" 24 #include "symcat.h" 25 #include "opcodes/iq2000-desc.h" 26 #include "opcodes/iq2000-opc.h" 27 #include "cgen.h" 28 #include "elf/common.h" 29 #include "elf/iq2000.h" 30 #include "sb.h" 31 #include "macro.h" 32 33 /* Structure to hold all of the different components describing 34 an individual instruction. */ 35 typedef struct 36 { 37 const CGEN_INSN * insn; 38 const CGEN_INSN * orig_insn; 39 CGEN_FIELDS fields; 40 #if CGEN_INT_INSN_P 41 CGEN_INSN_INT buffer [1]; 42 #define INSN_VALUE(buf) (*(buf)) 43 #else 44 unsigned char buffer [CGEN_MAX_INSN_SIZE]; 45 #define INSN_VALUE(buf) (buf) 46 #endif 47 char * addr; 48 fragS * frag; 49 int num_fixups; 50 fixS * fixups [GAS_CGEN_MAX_FIXUPS]; 51 int indices [MAX_OPERAND_INSTANCES]; 52 } 53 iq2000_insn; 54 55 const char comment_chars[] = "#"; 56 const char line_comment_chars[] = "#"; 57 const char line_separator_chars[] = ";"; 58 const char EXP_CHARS[] = "eE"; 59 const char FLT_CHARS[] = "dD"; 60 61 /* Default machine. */ 62 #define DEFAULT_MACHINE bfd_mach_iq2000 63 #define DEFAULT_FLAGS EF_IQ2000_CPU_IQ2000 64 65 static unsigned long iq2000_mach = bfd_mach_iq2000; 66 static int cpu_mach = (1 << MACH_IQ2000); 67 68 /* Flags to set in the elf header. */ 69 static flagword iq2000_flags = DEFAULT_FLAGS; 70 71 typedef struct proc 72 { 73 symbolS *isym; 74 unsigned long reg_mask; 75 unsigned long reg_offset; 76 unsigned long fpreg_mask; 77 unsigned long fpreg_offset; 78 unsigned long frame_offset; 79 unsigned long frame_reg; 80 unsigned long pc_reg; 81 } procS; 82 83 static procS cur_proc; 84 static procS *cur_proc_ptr; 85 static int numprocs; 86 87 /* Relocations against symbols are done in two 88 parts, with a HI relocation and a LO relocation. Each relocation 89 has only 16 bits of space to store an addend. This means that in 90 order for the linker to handle carries correctly, it must be able 91 to locate both the HI and the LO relocation. This means that the 92 relocations must appear in order in the relocation table. 93 94 In order to implement this, we keep track of each unmatched HI 95 relocation. We then sort them so that they immediately precede the 96 corresponding LO relocation. */ 97 98 struct iq2000_hi_fixup 99 { 100 struct iq2000_hi_fixup * next; /* Next HI fixup. */ 101 fixS * fixp; /* This fixup. */ 102 segT seg; /* The section this fixup is in. */ 103 }; 104 105 /* The list of unmatched HI relocs. */ 106 static struct iq2000_hi_fixup * iq2000_hi_fixup_list; 107 108 /* Macro hash table, which we will add to. */ 109 extern struct htab *macro_hash; 110 111 const char *md_shortopts = ""; 112 struct option md_longopts[] = 113 { 114 {NULL, no_argument, NULL, 0} 115 }; 116 size_t md_longopts_size = sizeof (md_longopts); 117 118 int 119 md_parse_option (int c ATTRIBUTE_UNUSED, 120 const char * arg ATTRIBUTE_UNUSED) 121 { 122 return 0; 123 } 124 125 void 126 md_show_usage (FILE * stream ATTRIBUTE_UNUSED) 127 { 128 } 129 130 /* Automatically enter conditional branch macros. */ 131 132 typedef struct 133 { 134 const char * mnemonic; 135 const char ** expansion; 136 const char ** args; 137 } iq2000_macro_defs_s; 138 139 static const char * abs_args[] = { "rd", "rs", "scratch=%1", NULL }; 140 static const char * abs_expn = "\n sra \\rd,\\rs,31\n xor \\scratch,\\rd,\\rs\n sub \\rd,\\scratch,\\rd\n"; 141 static const char * la_expn = "\n lui \\reg,%hi(\\label)\n ori \\reg,\\reg,%lo(\\label)\n"; 142 static const char * la_args[] = { "reg", "label", NULL }; 143 static const char * bxx_args[] = { "rs", "rt", "label", "scratch=%1", NULL }; 144 static const char * bge_expn = "\n slt \\scratch,\\rs,\\rt\n beq %0,\\scratch,\\label\n"; 145 static const char * bgeu_expn = "\n sltu \\scratch,\\rs,\\rt\n beq %0,\\scratch,\\label\n"; 146 static const char * bgt_expn = "\n slt \\scratch,\\rt,\\rs\n bne %0,\\scratch,\\label\n"; 147 static const char * bgtu_expn = "\n sltu \\scratch,\\rt,\\rs\n bne %0,\\scratch,\\label\n"; 148 static const char * ble_expn = "\n slt \\scratch,\\rt,\\rs\n beq %0,\\scratch,\\label\n"; 149 static const char * bleu_expn = "\n sltu \\scratch,\\rt,\\rs\n beq %0,\\scratch,\\label\n"; 150 static const char * blt_expn = "\n slt \\scratch,\\rs,\\rt\n bne %0,\\scratch,\\label\n"; 151 static const char * bltu_expn = "\n sltu \\scratch,\\rs,\\rt\n bne %0,\\scratch,\\label\n"; 152 static const char * sxx_args[] = { "rd", "rs", "rt", NULL }; 153 static const char * sge_expn = "\n slt \\rd,\\rs,\\rt\n xori \\rd,\\rd,1\n"; 154 static const char * sgeu_expn = "\n sltu \\rd,\\rs,\\rt\n xori \\rd,\\rd,1\n"; 155 static const char * sle_expn = "\n slt \\rd,\\rt,\\rs\n xori \\rd,\\rd,1\n"; 156 static const char * sleu_expn = "\n sltu \\rd,\\rt,\\rs\n xori \\rd,\\rd,1\n"; 157 static const char * sgt_expn = "\n slt \\rd,\\rt,\\rs\n"; 158 static const char * sgtu_expn = "\n sltu \\rd,\\rt,\\rs\n"; 159 static const char * sne_expn = "\n xor \\rd,\\rt,\\rs\n sltu \\rd,%0,\\rd\n"; 160 static const char * seq_expn = "\n xor \\rd,\\rt,\\rs\n sltu \\rd,%0,\\rd\n xori \\rd,\\rd,1\n"; 161 static const char * ai32_args[] = { "rt", "rs", "imm", NULL }; 162 static const char * andi32_expn = "\n\ 163 .if (\\imm & 0xffff0000 == 0xffff0000)\n\ 164 andoi \\rt,\\rs,%lo(\\imm)\n\ 165 .elseif (\\imm & 0x0000ffff == 0x0000ffff)\n\ 166 andoui \\rt,\\rs,%uhi(\\imm)\n\ 167 .elseif (\\imm & 0xffff0000 == 0x00000000)\n\ 168 andi \\rt,\\rs,%lo(\\imm)\n\ 169 .else\n\ 170 andoui \\rt,\\rs,%uhi(\\imm)\n\ 171 andoi \\rt,\\rt,%lo(\\imm)\n\ 172 .endif\n"; 173 static const char * ori32_expn = "\n\ 174 .if (\\imm & 0xffff == 0)\n\ 175 orui \\rt,\\rs,%uhi(\\imm)\n\ 176 .elseif (\\imm & 0xffff0000 == 0)\n\ 177 ori \\rt,\\rs,%lo(\\imm)\n\ 178 .else\n\ 179 orui \\rt,\\rs,%uhi(\\imm)\n\ 180 ori \\rt,\\rt,%lo(\\imm)\n\ 181 .endif\n"; 182 183 static const char * neg_args[] = { "rd", "rs", NULL }; 184 static const char * neg_expn = "\n sub \\rd,%0,\\rs\n"; 185 static const char * negu_expn = "\n subu \\rd,%0,\\rs\n"; 186 static const char * li_args[] = { "rt", "imm", NULL }; 187 static const char * li_expn = "\n\ 188 .if (\\imm & 0xffff0000 == 0x0)\n\ 189 ori \\rt,%0,\\imm\n\ 190 .elseif (\\imm & 0xffff0000 == 0xffff0000)\n\ 191 addi \\rt,%0,\\imm\n\ 192 .elseif (\\imm & 0x0000ffff == 0)\n\ 193 lui \\rt,%uhi(\\imm)\n\ 194 .else\n\ 195 lui \\rt,%uhi(\\imm)\n\ 196 ori \\rt,\\rt,%lo(\\imm)\n\ 197 .endif\n"; 198 199 static iq2000_macro_defs_s iq2000_macro_defs[] = 200 { 201 {"abs", (const char **) & abs_expn, (const char **) & abs_args}, 202 {"la", (const char **) & la_expn, (const char **) & la_args}, 203 {"bge", (const char **) & bge_expn, (const char **) & bxx_args}, 204 {"bgeu", (const char **) & bgeu_expn, (const char **) & bxx_args}, 205 {"bgt", (const char **) & bgt_expn, (const char **) & bxx_args}, 206 {"bgtu", (const char **) & bgtu_expn, (const char **) & bxx_args}, 207 {"ble", (const char **) & ble_expn, (const char **) & bxx_args}, 208 {"bleu", (const char **) & bleu_expn, (const char **) & bxx_args}, 209 {"blt", (const char **) & blt_expn, (const char **) & bxx_args}, 210 {"bltu", (const char **) & bltu_expn, (const char **) & bxx_args}, 211 {"sge", (const char **) & sge_expn, (const char **) & sxx_args}, 212 {"sgeu", (const char **) & sgeu_expn, (const char **) & sxx_args}, 213 {"sle", (const char **) & sle_expn, (const char **) & sxx_args}, 214 {"sleu", (const char **) & sleu_expn, (const char **) & sxx_args}, 215 {"sgt", (const char **) & sgt_expn, (const char **) & sxx_args}, 216 {"sgtu", (const char **) & sgtu_expn, (const char **) & sxx_args}, 217 {"seq", (const char **) & seq_expn, (const char **) & sxx_args}, 218 {"sne", (const char **) & sne_expn, (const char **) & sxx_args}, 219 {"neg", (const char **) & neg_expn, (const char **) & neg_args}, 220 {"negu", (const char **) & negu_expn, (const char **) & neg_args}, 221 {"li", (const char **) & li_expn, (const char **) & li_args}, 222 {"ori32", (const char **) & ori32_expn, (const char **) & ai32_args}, 223 {"andi32",(const char **) & andi32_expn,(const char **) & ai32_args}, 224 }; 225 226 static void 227 iq2000_add_macro (const char * name, 228 const char * semantics, 229 const char ** arguments) 230 { 231 macro_entry *macro; 232 sb macro_name; 233 const char *namestr; 234 235 macro = XNEW (macro_entry); 236 sb_new (& macro->sub); 237 sb_new (& macro_name); 238 239 macro->formal_count = 0; 240 macro->formals = 0; 241 242 sb_add_string (& macro->sub, semantics); 243 244 if (arguments != NULL) 245 { 246 formal_entry ** p = ¯o->formals; 247 248 macro->formal_count = 0; 249 macro->formal_hash = htab_create_alloc (7, hash_formal_entry, 250 eq_formal_entry, 251 NULL, xcalloc, free); 252 253 254 while (*arguments != NULL) 255 { 256 formal_entry *formal; 257 258 formal = XNEW (formal_entry); 259 260 sb_new (& formal->name); 261 sb_new (& formal->def); 262 sb_new (& formal->actual); 263 264 /* chlm: Added the following to allow defaulted args. */ 265 if (strchr (*arguments,'=')) 266 { 267 char * tt_args = strdup (*arguments); 268 char * tt_dflt = strchr (tt_args,'='); 269 270 *tt_dflt = 0; 271 sb_add_string (& formal->name, tt_args); 272 sb_add_string (& formal->def, tt_dflt + 1); 273 } 274 else 275 sb_add_string (& formal->name, *arguments); 276 277 /* Add to macro's hash table. */ 278 htab_insert (macro->formal_hash, 279 formal_entry_alloc (sb_terminate (& formal->name), 280 formal), 281 1); 282 formal->index = macro->formal_count; 283 macro->formal_count++; 284 *p = formal; 285 p = & formal->next; 286 *p = NULL; 287 ++arguments; 288 } 289 } 290 291 sb_add_string (¯o_name, name); 292 namestr = sb_terminate (¯o_name); 293 htab_insert (macro_hash, macro_entry_alloc (namestr, macro), 1); 294 295 macro_defined = 1; 296 } 297 298 static void 299 iq2000_load_macros (void) 300 { 301 int i; 302 int mcnt = ARRAY_SIZE (iq2000_macro_defs); 303 304 for (i = 0; i < mcnt; i++) 305 iq2000_add_macro (iq2000_macro_defs[i].mnemonic, 306 *iq2000_macro_defs[i].expansion, 307 iq2000_macro_defs[i].args); 308 } 309 310 void 311 md_begin (void) 312 { 313 /* Initialize the `cgen' interface. */ 314 315 /* Set the machine number and endian. */ 316 gas_cgen_cpu_desc = iq2000_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, cpu_mach, 317 CGEN_CPU_OPEN_ENDIAN, 318 CGEN_ENDIAN_BIG, 319 CGEN_CPU_OPEN_END); 320 iq2000_cgen_init_asm (gas_cgen_cpu_desc); 321 322 /* This is a callback from cgen to gas to parse operands. */ 323 cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand); 324 325 /* Set the ELF flags if desired. */ 326 if (iq2000_flags) 327 bfd_set_private_flags (stdoutput, iq2000_flags); 328 329 /* Set the machine type */ 330 bfd_default_set_arch_mach (stdoutput, bfd_arch_iq2000, iq2000_mach); 331 332 iq2000_load_macros (); 333 } 334 335 void 336 md_assemble (char * str) 337 { 338 static long delayed_load_register = 0; 339 static int last_insn_had_delay_slot = 0; 340 static int last_insn_has_load_delay = 0; 341 static int last_insn_unconditional_jump = 0; 342 static int last_insn_was_ldw = 0; 343 344 iq2000_insn insn; 345 char * errmsg; 346 347 /* Initialize GAS's cgen interface for a new instruction. */ 348 gas_cgen_init_parse (); 349 350 insn.insn = iq2000_cgen_assemble_insn 351 (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg); 352 353 if (!insn.insn) 354 { 355 as_bad ("%s", errmsg); 356 return; 357 } 358 359 /* Doesn't really matter what we pass for RELAX_P here. */ 360 gas_cgen_finish_insn (insn.insn, insn.buffer, 361 CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL); 362 363 /* We need to generate an error if there's a yielding instruction in the delay 364 slot of a control flow modifying instruction (jump (yes), load (no)) */ 365 if ((last_insn_had_delay_slot && !last_insn_has_load_delay) && 366 CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_YIELD_INSN)) 367 as_bad (_("the yielding instruction %s may not be in a delay slot."), 368 CGEN_INSN_NAME (insn.insn)); 369 370 /* Warn about odd numbered base registers for paired-register 371 instructions like LDW. On iq2000, result is always rt. */ 372 if (iq2000_mach == bfd_mach_iq2000 373 && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_EVEN_REG_NUM) 374 && (insn.fields.f_rt % 2)) 375 as_bad (_("Register number (R%ld) for double word access must be even."), 376 insn.fields.f_rt); 377 378 /* Warn about insns that reference the target of a previous load. */ 379 /* NOTE: R0 is a special case and is not subject to load delays (except for ldw). */ 380 if (delayed_load_register && (last_insn_has_load_delay || last_insn_was_ldw)) 381 { 382 if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RD) && 383 insn.fields.f_rd == delayed_load_register) 384 as_warn (_("operand references R%ld of previous load."), 385 insn.fields.f_rd); 386 387 if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RS) && 388 insn.fields.f_rs == delayed_load_register) 389 as_warn (_("operand references R%ld of previous load."), 390 insn.fields.f_rs); 391 392 if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RT) && 393 insn.fields.f_rt == delayed_load_register) 394 as_warn (_("operand references R%ld of previous load."), 395 insn.fields.f_rt); 396 397 if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_R31) && 398 delayed_load_register == 31) 399 as_warn (_("instruction implicitly accesses R31 of previous load.")); 400 } 401 402 /* Warn about insns that reference the (target + 1) of a previous ldw. */ 403 if (last_insn_was_ldw) 404 { 405 if ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RD) 406 && insn.fields.f_rd == delayed_load_register + 1) 407 || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RS) 408 && insn.fields.f_rs == delayed_load_register + 1) 409 || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RT) 410 && insn.fields.f_rt == delayed_load_register + 1)) 411 as_warn (_("operand references R%ld of previous load."), 412 delayed_load_register + 1); 413 } 414 415 last_insn_had_delay_slot = 416 CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT); 417 418 last_insn_has_load_delay = 419 CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_LOAD_DELAY); 420 421 if (last_insn_unconditional_jump) 422 last_insn_has_load_delay = last_insn_unconditional_jump = 0; 423 else if (! strcmp (CGEN_INSN_MNEMONIC (insn.insn), "j") 424 || ! strcmp (CGEN_INSN_MNEMONIC (insn.insn), "jal")) 425 last_insn_unconditional_jump = 1; 426 427 /* The meaning of EVEN_REG_NUM was overloaded to also imply LDW. Since 428 that's not true for IQ10, let's make the above logic specific to LDW. */ 429 last_insn_was_ldw = ! strcmp ("ldw", CGEN_INSN_NAME (insn.insn)); 430 431 /* The assumption here is that the target of a load is always rt. */ 432 delayed_load_register = insn.fields.f_rt; 433 } 434 435 valueT 436 md_section_align (segT segment, valueT size) 437 { 438 int align = bfd_section_alignment (segment); 439 return ((size + (1 << align) - 1) & -(1 << align)); 440 } 441 442 symbolS * 443 md_undefined_symbol (char * name ATTRIBUTE_UNUSED) 444 { 445 return 0; 446 } 447 448 /* Interface to relax_segment. */ 449 450 /* Return an initial guess of the length by which a fragment must grow to 451 hold a branch to reach its destination. 452 Also updates fr_type/fr_subtype as necessary. 453 454 Called just before doing relaxation. 455 Any symbol that is now undefined will not become defined. 456 The guess for fr_var is ACTUALLY the growth beyond fr_fix. 457 Whatever we do to grow fr_fix or fr_var contributes to our returned value. 458 Although it may not be explicit in the frag, pretend fr_var starts with a 459 0 value. */ 460 461 int 462 md_estimate_size_before_relax (fragS * fragP, 463 segT segment ATTRIBUTE_UNUSED) 464 { 465 int old_fr_fix = fragP->fr_fix; 466 467 /* The only thing we have to handle here are symbols outside of the 468 current segment. They may be undefined or in a different segment in 469 which case linker scripts may place them anywhere. 470 However, we can't finish the fragment here and emit the reloc as insn 471 alignment requirements may move the insn about. */ 472 473 return (fragP->fr_var + fragP->fr_fix - old_fr_fix); 474 } 475 476 /* *fragP has been relaxed to its final size, and now needs to have 477 the bytes inside it modified to conform to the new size. 478 479 Called after relaxation is finished. 480 fragP->fr_type == rs_machine_dependent. 481 fragP->fr_subtype is the subtype of what the address relaxed to. */ 482 483 void 484 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, 485 segT sec ATTRIBUTE_UNUSED, 486 fragS * fragP ATTRIBUTE_UNUSED) 487 { 488 } 489 490 491 /* Functions concerning relocs. */ 492 493 long 494 md_pcrel_from_section (fixS * fixP, segT sec) 495 { 496 if (fixP->fx_addsy != (symbolS *) NULL 497 && (! S_IS_DEFINED (fixP->fx_addsy) 498 || S_GET_SEGMENT (fixP->fx_addsy) != sec)) 499 { 500 /* The symbol is undefined (or is defined but not in this section). 501 Let the linker figure it out. */ 502 return 0; 503 } 504 505 /* Return the address of the delay slot. */ 506 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; 507 } 508 509 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP. 510 Returns BFD_RELOC_NONE if no reloc type can be found. 511 *FIXP may be modified if desired. */ 512 513 bfd_reloc_code_real_type 514 md_cgen_lookup_reloc (const CGEN_INSN * insn ATTRIBUTE_UNUSED, 515 const CGEN_OPERAND * operand, 516 fixS * fixP ATTRIBUTE_UNUSED) 517 { 518 switch (operand->type) 519 { 520 case IQ2000_OPERAND_OFFSET: return BFD_RELOC_16_PCREL_S2; 521 case IQ2000_OPERAND_JMPTARG: return BFD_RELOC_IQ2000_OFFSET_16; 522 case IQ2000_OPERAND_JMPTARGQ10: return BFD_RELOC_NONE; 523 case IQ2000_OPERAND_HI16: return BFD_RELOC_HI16; 524 case IQ2000_OPERAND_LO16: return BFD_RELOC_LO16; 525 default: break; 526 } 527 528 return BFD_RELOC_NONE; 529 } 530 531 /* Record a HI16 reloc for later matching with its LO16 cousin. */ 532 533 static void 534 iq2000_record_hi16 (int reloc_type, 535 fixS * fixP, 536 segT seg ATTRIBUTE_UNUSED) 537 { 538 struct iq2000_hi_fixup * hi_fixup; 539 540 gas_assert (reloc_type == BFD_RELOC_HI16); 541 542 hi_fixup = XNEW (struct iq2000_hi_fixup); 543 hi_fixup->fixp = fixP; 544 hi_fixup->seg = now_seg; 545 hi_fixup->next = iq2000_hi_fixup_list; 546 547 iq2000_hi_fixup_list = hi_fixup; 548 } 549 550 /* Called while parsing an instruction to create a fixup. 551 We need to check for HI16 relocs and queue them up for later sorting. */ 552 553 fixS * 554 iq2000_cgen_record_fixup_exp (fragS * frag, 555 int where, 556 const CGEN_INSN * insn, 557 int length, 558 const CGEN_OPERAND * operand, 559 int opinfo, 560 expressionS * exp) 561 { 562 fixS * fixP = gas_cgen_record_fixup_exp (frag, where, insn, length, 563 operand, opinfo, exp); 564 565 if (operand->type == IQ2000_OPERAND_HI16 566 /* If low/high was used, it is recorded in `opinfo'. */ 567 && (fixP->fx_cgen.opinfo == BFD_RELOC_HI16 568 || fixP->fx_cgen.opinfo == BFD_RELOC_LO16)) 569 iq2000_record_hi16 (fixP->fx_cgen.opinfo, fixP, now_seg); 570 571 return fixP; 572 } 573 574 /* Return BFD reloc type from opinfo field in a fixS. 575 It's tricky using fx_r_type in iq2000_frob_file because the values 576 are BFD_RELOC_UNUSED + operand number. */ 577 #define FX_OPINFO_R_TYPE(f) ((f)->fx_cgen.opinfo) 578 579 /* Sort any unmatched HI16 relocs so that they immediately precede 580 the corresponding LO16 reloc. This is called before md_apply_fix and 581 tc_gen_reloc. */ 582 583 void 584 iq2000_frob_file (void) 585 { 586 struct iq2000_hi_fixup * l; 587 588 for (l = iq2000_hi_fixup_list; l != NULL; l = l->next) 589 { 590 segment_info_type * seginfo; 591 int pass; 592 593 gas_assert (FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_HI16 594 || FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_LO16); 595 596 /* Check quickly whether the next fixup happens to be a matching low. */ 597 if (l->fixp->fx_next != NULL 598 && FX_OPINFO_R_TYPE (l->fixp->fx_next) == BFD_RELOC_LO16 599 && l->fixp->fx_addsy == l->fixp->fx_next->fx_addsy 600 && l->fixp->fx_offset == l->fixp->fx_next->fx_offset) 601 continue; 602 603 /* Look through the fixups for this segment for a matching 604 `low'. When we find one, move the high just in front of it. 605 We do this in two passes. In the first pass, we try to find 606 a unique `low'. In the second pass, we permit multiple 607 high's relocs for a single `low'. */ 608 seginfo = seg_info (l->seg); 609 for (pass = 0; pass < 2; pass++) 610 { 611 fixS * f; 612 fixS * prev; 613 614 prev = NULL; 615 for (f = seginfo->fix_root; f != NULL; f = f->fx_next) 616 { 617 /* Check whether this is a `low' fixup which matches l->fixp. */ 618 if (FX_OPINFO_R_TYPE (f) == BFD_RELOC_LO16 619 && f->fx_addsy == l->fixp->fx_addsy 620 && f->fx_offset == l->fixp->fx_offset 621 && (pass == 1 622 || prev == NULL 623 || (FX_OPINFO_R_TYPE (prev) != BFD_RELOC_HI16) 624 || prev->fx_addsy != f->fx_addsy 625 || prev->fx_offset != f->fx_offset)) 626 { 627 fixS ** pf; 628 629 /* Move l->fixp before f. */ 630 for (pf = &seginfo->fix_root; 631 * pf != l->fixp; 632 pf = & (* pf)->fx_next) 633 gas_assert (* pf != NULL); 634 635 * pf = l->fixp->fx_next; 636 637 l->fixp->fx_next = f; 638 if (prev == NULL) 639 seginfo->fix_root = l->fixp; 640 else 641 prev->fx_next = l->fixp; 642 643 break; 644 } 645 646 prev = f; 647 } 648 649 if (f != NULL) 650 break; 651 652 if (pass == 1) 653 as_warn_where (l->fixp->fx_file, l->fixp->fx_line, 654 _("Unmatched high relocation")); 655 } 656 } 657 } 658 659 /* See whether we need to force a relocation into the output file. */ 660 661 int 662 iq2000_force_relocation (fixS * fix) 663 { 664 if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT 665 || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY) 666 return 1; 667 668 return 0; 669 } 670 671 /* Handle the .set pseudo-op. */ 672 673 static void 674 s_iq2000_set (int x ATTRIBUTE_UNUSED) 675 { 676 static const char * ignored_arguments [] = 677 { 678 "reorder", 679 "noreorder", 680 "at", 681 "noat", 682 "macro", 683 "nomacro", 684 "move", 685 "novolatile", 686 "nomove", 687 "volatile", 688 "bopt", 689 "nobopt", 690 NULL 691 }; 692 const char ** ignored; 693 char *name = input_line_pointer, ch; 694 char *save_ILP = input_line_pointer; 695 696 while (!is_end_of_line[(unsigned char) *input_line_pointer]) 697 input_line_pointer++; 698 ch = *input_line_pointer; 699 *input_line_pointer = '\0'; 700 701 for (ignored = ignored_arguments; * ignored; ignored ++) 702 if (strcmp (* ignored, name) == 0) 703 break; 704 if (* ignored == NULL) 705 { 706 /* We'd like to be able to use .set symbol, expn */ 707 input_line_pointer = save_ILP; 708 s_set (0); 709 return; 710 } 711 *input_line_pointer = ch; 712 demand_empty_rest_of_line (); 713 } 714 715 /* Write a value out to the object file, using the appropriate endianness. */ 716 717 void 718 md_number_to_chars (char * buf, valueT val, int n) 719 { 720 number_to_chars_bigendian (buf, val, n); 721 } 722 723 void 724 md_operand (expressionS * exp) 725 { 726 /* In case of a syntax error, escape back to try next syntax combo. */ 727 if (exp->X_op == O_absent) 728 gas_cgen_md_operand (exp); 729 } 730 731 const char * 732 md_atof (int type, char * litP, int * sizeP) 733 { 734 return ieee_md_atof (type, litP, sizeP, true); 735 } 736 737 bool 738 iq2000_fix_adjustable (fixS * fixP) 739 { 740 bfd_reloc_code_real_type reloc_type; 741 742 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED) 743 { 744 const CGEN_INSN *insn = NULL; 745 int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED; 746 const CGEN_OPERAND *operand = cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex); 747 748 reloc_type = md_cgen_lookup_reloc (insn, operand, fixP); 749 } 750 else 751 reloc_type = fixP->fx_r_type; 752 753 if (fixP->fx_addsy == NULL) 754 return true; 755 756 /* Prevent all adjustments to global symbols. */ 757 if (S_IS_EXTERNAL (fixP->fx_addsy)) 758 return false; 759 760 if (S_IS_WEAK (fixP->fx_addsy)) 761 return false; 762 763 /* We need the symbol name for the VTABLE entries. */ 764 if ( reloc_type == BFD_RELOC_VTABLE_INHERIT 765 || reloc_type == BFD_RELOC_VTABLE_ENTRY) 766 return false; 767 768 return true; 769 } 770 771 static void 772 s_change_sec (int sec) 773 { 774 #ifdef OBJ_ELF 775 /* The ELF backend needs to know that we are changing sections, so 776 that .previous works correctly. We could do something like check 777 for a obj_section_change_hook macro, but that might be confusing 778 as it would not be appropriate to use it in the section changing 779 functions in read.c, since obj-elf.c intercepts those. FIXME: 780 This should be cleaner, somehow. */ 781 obj_elf_section_change_hook (); 782 #endif 783 784 switch (sec) 785 { 786 case 't': 787 s_text (0); 788 break; 789 case 'd': 790 case 'r': 791 s_data (0); 792 break; 793 } 794 } 795 796 static symbolS * 797 get_symbol (void) 798 { 799 int c; 800 char *name; 801 symbolS *p; 802 803 c = get_symbol_name (&name); 804 p = (symbolS *) symbol_find_or_make (name); 805 (void) restore_line_pointer (c); 806 return p; 807 } 808 809 /* The .end directive. */ 810 811 static void 812 s_iq2000_end (int x ATTRIBUTE_UNUSED) 813 { 814 symbolS *p; 815 int maybe_text; 816 817 if (!is_end_of_line[(unsigned char) *input_line_pointer]) 818 { 819 p = get_symbol (); 820 demand_empty_rest_of_line (); 821 } 822 else 823 p = NULL; 824 825 if ((bfd_section_flags (now_seg) & SEC_CODE) != 0) 826 maybe_text = 1; 827 else 828 maybe_text = 0; 829 830 if (!maybe_text) 831 as_warn (_(".end not in text section")); 832 833 if (!cur_proc_ptr) 834 { 835 as_warn (_(".end directive without a preceding .ent directive.")); 836 demand_empty_rest_of_line (); 837 return; 838 } 839 840 if (p != NULL) 841 { 842 gas_assert (S_GET_NAME (p)); 843 if (strcmp (S_GET_NAME (p), S_GET_NAME (cur_proc_ptr->isym))) 844 as_warn (_(".end symbol does not match .ent symbol.")); 845 } 846 else 847 as_warn (_(".end directive missing or unknown symbol")); 848 849 cur_proc_ptr = NULL; 850 } 851 852 static int 853 get_number (void) 854 { 855 int negative = 0; 856 long val = 0; 857 858 if (*input_line_pointer == '-') 859 { 860 ++input_line_pointer; 861 negative = 1; 862 } 863 864 if (! ISDIGIT (*input_line_pointer)) 865 as_bad (_("Expected simple number.")); 866 867 if (input_line_pointer[0] == '0') 868 { 869 if (input_line_pointer[1] == 'x') 870 { 871 input_line_pointer += 2; 872 while (ISXDIGIT (*input_line_pointer)) 873 { 874 val <<= 4; 875 val |= hex_value (*input_line_pointer++); 876 } 877 return negative ? -val : val; 878 } 879 else 880 { 881 ++input_line_pointer; 882 883 while (ISDIGIT (*input_line_pointer)) 884 { 885 val <<= 3; 886 val |= *input_line_pointer++ - '0'; 887 } 888 return negative ? -val : val; 889 } 890 } 891 892 if (! ISDIGIT (*input_line_pointer)) 893 { 894 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), 895 *input_line_pointer, *input_line_pointer); 896 as_warn (_("Invalid number")); 897 return -1; 898 } 899 900 while (ISDIGIT (*input_line_pointer)) 901 { 902 val *= 10; 903 val += *input_line_pointer++ - '0'; 904 } 905 906 return negative ? -val : val; 907 } 908 909 /* The .aent and .ent directives. */ 910 911 static void 912 s_iq2000_ent (int aent) 913 { 914 symbolS *symbolP; 915 int maybe_text; 916 917 symbolP = get_symbol (); 918 if (*input_line_pointer == ',') 919 input_line_pointer++; 920 SKIP_WHITESPACE (); 921 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-') 922 get_number (); 923 924 if ((bfd_section_flags (now_seg) & SEC_CODE) != 0) 925 maybe_text = 1; 926 else 927 maybe_text = 0; 928 929 if (!maybe_text) 930 as_warn (_(".ent or .aent not in text section.")); 931 932 if (!aent && cur_proc_ptr) 933 as_warn (_("missing `.end'")); 934 935 if (!aent) 936 { 937 cur_proc_ptr = &cur_proc; 938 memset (cur_proc_ptr, '\0', sizeof (procS)); 939 940 cur_proc_ptr->isym = symbolP; 941 942 symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION; 943 944 numprocs++; 945 } 946 947 demand_empty_rest_of_line (); 948 } 949 950 /* The .frame directive. If the mdebug section is present (IRIX 5 native) 951 then ecoff.c (ecoff_directive_frame) is used. For embedded targets, 952 s_iq2000_frame is used so that we can set the PDR information correctly. 953 We can't use the ecoff routines because they make reference to the ecoff 954 symbol table (in the mdebug section). */ 955 956 static void 957 s_iq2000_frame (int ignore) 958 { 959 s_ignore (ignore); 960 } 961 962 /* The .fmask and .mask directives. If the mdebug section is present 963 (IRIX 5 native) then ecoff.c (ecoff_directive_mask) is used. For 964 embedded targets, s_iq2000_mask is used so that we can set the PDR 965 information correctly. We can't use the ecoff routines because they 966 make reference to the ecoff symbol table (in the mdebug section). */ 967 968 static void 969 s_iq2000_mask (int reg_type) 970 { 971 s_ignore (reg_type); 972 } 973 974 /* The target specific pseudo-ops which we support. */ 975 const pseudo_typeS md_pseudo_table[] = 976 { 977 { "align", s_align_bytes, 0 }, 978 { "word", cons, 4 }, 979 { "rdata", s_change_sec, 'r'}, 980 { "sdata", s_change_sec, 's'}, 981 { "set", s_iq2000_set, 0 }, 982 { "ent", s_iq2000_ent, 0 }, 983 { "end", s_iq2000_end, 0 }, 984 { "frame", s_iq2000_frame, 0 }, 985 { "fmask", s_iq2000_mask, 'F'}, 986 { "mask", s_iq2000_mask, 'R'}, 987 { "dword", cons, 8 }, 988 { "half", cons, 2 }, 989 { NULL, NULL, 0 } 990 }; 991