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