1 /* GAS interface for targets using CGEN: Cpu tools GENerator. 2 Copyright (C) 1996-2014 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, but WITHOUT 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 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 the Free Software 18 Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 19 20 #include "as.h" 21 #include <setjmp.h> 22 #include "symcat.h" 23 #include "cgen-desc.h" 24 #include "subsegs.h" 25 #include "cgen.h" 26 #include "dwarf2dbg.h" 27 28 #include "symbols.h" 29 #include "struc-symbol.h" 30 31 #ifdef OBJ_COMPLEX_RELC 32 static expressionS * make_right_shifted_expr 33 (expressionS *, const int, const int); 34 35 static unsigned long gas_cgen_encode_addend 36 (const unsigned long, const unsigned long, const unsigned long, \ 37 const unsigned long, const unsigned long, const unsigned long, \ 38 const unsigned long); 39 40 static char * weak_operand_overflow_check 41 (const expressionS *, const CGEN_OPERAND *); 42 43 static void queue_fixup_recursively 44 (const int, const int, expressionS *, \ 45 const CGEN_MAYBE_MULTI_IFLD *, const int, const int); 46 47 static int rightshift = 0; 48 #endif 49 static void queue_fixup (int, int, expressionS *); 50 51 /* Opcode table descriptor, must be set by md_begin. */ 52 53 CGEN_CPU_DESC gas_cgen_cpu_desc; 54 55 /* Callback to insert a register into the symbol table. 56 A target may choose to let GAS parse the registers. 57 ??? Not currently used. */ 58 59 void 60 cgen_asm_record_register (name, number) 61 char *name; 62 int number; 63 { 64 /* Use symbol_create here instead of symbol_new so we don't try to 65 output registers into the object file's symbol table. */ 66 symbol_table_insert (symbol_create (name, reg_section, 67 number, &zero_address_frag)); 68 } 69 70 /* We need to keep a list of fixups. We can't simply generate them as 71 we go, because that would require us to first create the frag, and 72 that would screw up references to ``.''. 73 74 This is used by cpu's with simple operands. It keeps knowledge of what 75 an `expressionS' is and what a `fixup' is out of CGEN which for the time 76 being is preferable. 77 78 OPINDEX is the index in the operand table. 79 OPINFO is something the caller chooses to help in reloc determination. */ 80 81 struct fixup 82 { 83 int opindex; 84 int opinfo; 85 expressionS exp; 86 struct cgen_maybe_multi_ifield * field; 87 int msb_field_p; 88 }; 89 90 static struct fixup fixups[GAS_CGEN_MAX_FIXUPS]; 91 static int num_fixups; 92 93 /* Prepare to parse an instruction. 94 ??? May wish to make this static and delete calls in md_assemble. */ 95 96 void 97 gas_cgen_init_parse () 98 { 99 num_fixups = 0; 100 } 101 102 /* Queue a fixup. */ 103 104 static void 105 queue_fixup (opindex, opinfo, expP) 106 int opindex; 107 int opinfo; 108 expressionS * expP; 109 { 110 /* We need to generate a fixup for this expression. */ 111 if (num_fixups >= GAS_CGEN_MAX_FIXUPS) 112 as_fatal (_("too many fixups")); 113 fixups[num_fixups].exp = *expP; 114 fixups[num_fixups].opindex = opindex; 115 fixups[num_fixups].opinfo = opinfo; 116 ++ num_fixups; 117 } 118 119 /* The following functions allow fixup chains to be stored, retrieved, 120 and swapped. They are a generalization of a pre-existing scheme 121 for storing, restoring and swapping fixup chains that was used by 122 the m32r port. The functionality is essentially the same, only 123 instead of only being able to store a single fixup chain, an entire 124 array of fixup chains can be stored. It is the user's responsibility 125 to keep track of how many fixup chains have been stored and which 126 elements of the array they are in. 127 128 The algorithms used are the same as in the old scheme. Other than the 129 "array-ness" of the whole thing, the functionality is identical to the 130 old scheme. 131 132 gas_cgen_initialize_saved_fixups_array(): 133 Sets num_fixups_in_chain to 0 for each element. Call this from 134 md_begin() if you plan to use these functions and you want the 135 fixup count in each element to be set to 0 initially. This is 136 not necessary, but it's included just in case. It performs 137 the same function for each element in the array of fixup chains 138 that gas_init_parse() performs for the current fixups. 139 140 gas_cgen_save_fixups (element): 141 element - element number of the array you wish to store the fixups 142 to. No mechanism is built in for tracking what element 143 was last stored to. 144 145 gas_cgen_restore_fixups (element): 146 element - element number of the array you wish to restore the fixups 147 from. 148 149 gas_cgen_swap_fixups(int element): 150 element - swap the current fixups with those in this element number. 151 */ 152 153 struct saved_fixups 154 { 155 struct fixup fixup_chain[GAS_CGEN_MAX_FIXUPS]; 156 int num_fixups_in_chain; 157 }; 158 159 static struct saved_fixups stored_fixups[MAX_SAVED_FIXUP_CHAINS]; 160 161 void 162 gas_cgen_initialize_saved_fixups_array () 163 { 164 int i = 0; 165 166 while (i < MAX_SAVED_FIXUP_CHAINS) 167 stored_fixups[i++].num_fixups_in_chain = 0; 168 } 169 170 void 171 gas_cgen_save_fixups (i) 172 int i; 173 { 174 if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS) 175 { 176 as_fatal ("index into stored_fixups[] out of bounds"); 177 return; 178 } 179 180 stored_fixups[i].num_fixups_in_chain = num_fixups; 181 memcpy (stored_fixups[i].fixup_chain, fixups, 182 sizeof (fixups[0]) * num_fixups); 183 num_fixups = 0; 184 } 185 186 void 187 gas_cgen_restore_fixups (i) 188 int i; 189 { 190 if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS) 191 { 192 as_fatal ("index into stored_fixups[] out of bounds"); 193 return; 194 } 195 196 num_fixups = stored_fixups[i].num_fixups_in_chain; 197 memcpy (fixups, stored_fixups[i].fixup_chain, 198 (sizeof (stored_fixups[i].fixup_chain[0])) * num_fixups); 199 stored_fixups[i].num_fixups_in_chain = 0; 200 } 201 202 void 203 gas_cgen_swap_fixups (i) 204 int i; 205 { 206 if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS) 207 { 208 as_fatal ("index into stored_fixups[] out of bounds"); 209 return; 210 } 211 212 if (num_fixups == 0) 213 gas_cgen_restore_fixups (i); 214 215 else if (stored_fixups[i].num_fixups_in_chain == 0) 216 gas_cgen_save_fixups (i); 217 218 else 219 { 220 int tmp; 221 struct fixup tmp_fixup; 222 223 tmp = stored_fixups[i].num_fixups_in_chain; 224 stored_fixups[i].num_fixups_in_chain = num_fixups; 225 num_fixups = tmp; 226 227 for (tmp = GAS_CGEN_MAX_FIXUPS; tmp--;) 228 { 229 tmp_fixup = stored_fixups[i].fixup_chain [tmp]; 230 stored_fixups[i].fixup_chain[tmp] = fixups [tmp]; 231 fixups [tmp] = tmp_fixup; 232 } 233 } 234 } 235 236 /* Default routine to record a fixup. 237 This is a cover function to fix_new. 238 It exists because we record INSN with the fixup. 239 240 FRAG and WHERE are their respective arguments to fix_new_exp. 241 LENGTH is in bits. 242 OPINFO is something the caller chooses to help in reloc determination. 243 244 At this point we do not use a bfd_reloc_code_real_type for 245 operands residing in the insn, but instead just use the 246 operand index. This lets us easily handle fixups for any 247 operand type. We pick a BFD reloc type in md_apply_fix. */ 248 249 fixS * 250 gas_cgen_record_fixup (frag, where, insn, length, operand, opinfo, symbol, offset) 251 fragS * frag; 252 int where; 253 const CGEN_INSN * insn; 254 int length; 255 const CGEN_OPERAND * operand; 256 int opinfo; 257 symbolS * symbol; 258 offsetT offset; 259 { 260 fixS *fixP; 261 262 /* It may seem strange to use operand->attrs and not insn->attrs here, 263 but it is the operand that has a pc relative relocation. */ 264 fixP = fix_new (frag, where, length / 8, symbol, offset, 265 CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR), 266 (bfd_reloc_code_real_type) 267 ((int) BFD_RELOC_UNUSED 268 + (int) operand->type)); 269 fixP->fx_cgen.insn = insn; 270 fixP->fx_cgen.opinfo = opinfo; 271 fixP->fx_cgen.field = NULL; 272 fixP->fx_cgen.msb_field_p = 0; 273 274 return fixP; 275 } 276 277 /* Default routine to record a fixup given an expression. 278 This is a cover function to fix_new_exp. 279 It exists because we record INSN with the fixup. 280 281 FRAG and WHERE are their respective arguments to fix_new_exp. 282 LENGTH is in bits. 283 OPINFO is something the caller chooses to help in reloc determination. 284 285 At this point we do not use a bfd_reloc_code_real_type for 286 operands residing in the insn, but instead just use the 287 operand index. This lets us easily handle fixups for any 288 operand type. We pick a BFD reloc type in md_apply_fix. */ 289 290 fixS * 291 gas_cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp) 292 fragS * frag; 293 int where; 294 const CGEN_INSN * insn; 295 int length; 296 const CGEN_OPERAND * operand; 297 int opinfo; 298 expressionS * exp; 299 { 300 fixS *fixP; 301 302 /* It may seem strange to use operand->attrs and not insn->attrs here, 303 but it is the operand that has a pc relative relocation. */ 304 fixP = fix_new_exp (frag, where, length / 8, exp, 305 CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR), 306 (bfd_reloc_code_real_type) 307 ((int) BFD_RELOC_UNUSED 308 + (int) operand->type)); 309 fixP->fx_cgen.insn = insn; 310 fixP->fx_cgen.opinfo = opinfo; 311 fixP->fx_cgen.field = NULL; 312 fixP->fx_cgen.msb_field_p = 0; 313 314 return fixP; 315 } 316 317 #ifdef OBJ_COMPLEX_RELC 318 static symbolS * 319 expr_build_binary (operatorT op, symbolS * s1, symbolS * s2) 320 { 321 expressionS e; 322 323 e.X_op = op; 324 e.X_add_symbol = s1; 325 e.X_op_symbol = s2; 326 e.X_add_number = 0; 327 return make_expr_symbol (& e); 328 } 329 #endif 330 331 /* Used for communication between the next two procedures. */ 332 static jmp_buf expr_jmp_buf; 333 static int expr_jmp_buf_p; 334 335 /* Callback for cgen interface. Parse the expression at *STRP. 336 The result is an error message or NULL for success (in which case 337 *STRP is advanced past the parsed text). 338 WANT is an indication of what the caller is looking for. 339 If WANT == CGEN_ASM_PARSE_INIT the caller is beginning to try to match 340 a table entry with the insn, reset the queued fixups counter. 341 An enum cgen_parse_operand_result is stored in RESULTP. 342 OPINDEX is the operand's table entry index. 343 OPINFO is something the caller chooses to help in reloc determination. 344 The resulting value is stored in VALUEP. */ 345 346 const char * 347 gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP) 348 349 #ifdef OBJ_COMPLEX_RELC 350 CGEN_CPU_DESC cd; 351 #else 352 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; 353 #endif 354 enum cgen_parse_operand_type want; 355 const char **strP; 356 int opindex; 357 int opinfo; 358 enum cgen_parse_operand_result *resultP; 359 bfd_vma *valueP; 360 { 361 #ifdef __STDC__ 362 /* These are volatile to survive the setjmp. */ 363 char * volatile hold; 364 enum cgen_parse_operand_result * volatile resultP_1; 365 volatile int opinfo_1; 366 #else 367 static char *hold; 368 static enum cgen_parse_operand_result *resultP_1; 369 int opinfo_1; 370 #endif 371 const char *errmsg; 372 expressionS exp; 373 374 #ifdef OBJ_COMPLEX_RELC 375 volatile int signed_p = 0; 376 symbolS * stmp = NULL; 377 bfd_reloc_code_real_type reloc_type; 378 const CGEN_OPERAND * operand; 379 fixS dummy_fixup; 380 #endif 381 if (want == CGEN_PARSE_OPERAND_INIT) 382 { 383 gas_cgen_init_parse (); 384 return NULL; 385 } 386 387 resultP_1 = resultP; 388 hold = input_line_pointer; 389 input_line_pointer = (char *) *strP; 390 opinfo_1 = opinfo; 391 392 /* We rely on md_operand to longjmp back to us. 393 This is done via gas_cgen_md_operand. */ 394 if (setjmp (expr_jmp_buf) != 0) 395 { 396 expr_jmp_buf_p = 0; 397 input_line_pointer = (char *) hold; 398 *resultP_1 = CGEN_PARSE_OPERAND_RESULT_ERROR; 399 return _("illegal operand"); 400 } 401 402 expr_jmp_buf_p = 1; 403 expression (&exp); 404 expr_jmp_buf_p = 0; 405 errmsg = NULL; 406 407 *strP = input_line_pointer; 408 input_line_pointer = hold; 409 410 #ifdef TC_CGEN_PARSE_FIX_EXP 411 opinfo_1 = TC_CGEN_PARSE_FIX_EXP (opinfo_1, & exp); 412 #endif 413 414 /* FIXME: Need to check `want'. */ 415 416 switch (exp.X_op) 417 { 418 case O_illegal: 419 errmsg = _("illegal operand"); 420 *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR; 421 break; 422 case O_absent: 423 errmsg = _("missing operand"); 424 *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR; 425 break; 426 case O_constant: 427 if (want == CGEN_PARSE_OPERAND_SYMBOLIC) 428 goto de_fault; 429 *valueP = exp.X_add_number; 430 *resultP = CGEN_PARSE_OPERAND_RESULT_NUMBER; 431 break; 432 case O_register: 433 *valueP = exp.X_add_number; 434 *resultP = CGEN_PARSE_OPERAND_RESULT_REGISTER; 435 break; 436 de_fault: 437 default: 438 #ifdef OBJ_COMPLEX_RELC 439 /* Look up operand, check to see if there's an obvious 440 overflow (this helps disambiguate some insn parses). */ 441 operand = cgen_operand_lookup_by_num (cd, opindex); 442 errmsg = weak_operand_overflow_check (& exp, operand); 443 444 if (! errmsg) 445 { 446 /* Fragment the expression as necessary, and queue a reloc. */ 447 memset (& dummy_fixup, 0, sizeof (fixS)); 448 449 reloc_type = md_cgen_lookup_reloc (0, operand, & dummy_fixup); 450 451 if (exp.X_op == O_symbol 452 && reloc_type == BFD_RELOC_RELC 453 && exp.X_add_symbol->sy_value.X_op == O_constant 454 && (!exp.X_add_symbol->bsym 455 || (exp.X_add_symbol->bsym->section != expr_section 456 && exp.X_add_symbol->bsym->section != absolute_section 457 && exp.X_add_symbol->bsym->section != undefined_section))) 458 { 459 /* Local labels will have been (eagerly) turned into constants 460 by now, due to the inappropriately deep insight of the 461 expression parser. Unfortunately make_expr_symbol 462 prematurely dives into the symbol evaluator, and in this 463 case it gets a bad answer, so we manually create the 464 expression symbol we want here. */ 465 stmp = symbol_create (FAKE_LABEL_NAME, expr_section, 0, 466 & zero_address_frag); 467 symbol_set_value_expression (stmp, & exp); 468 } 469 else 470 stmp = make_expr_symbol (& exp); 471 472 /* If this is a pc-relative RELC operand, we 473 need to subtract "." from the expression. */ 474 if (reloc_type == BFD_RELOC_RELC 475 && CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR)) 476 stmp = expr_build_binary (O_subtract, stmp, expr_build_dot ()); 477 478 /* FIXME: this is not a perfect heuristic for figuring out 479 whether an operand is signed: it only works when the operand 480 is an immediate. it's not terribly likely that any other 481 values will be signed relocs, but it's possible. */ 482 if (operand && (operand->hw_type == HW_H_SINT)) 483 signed_p = 1; 484 485 if (stmp->bsym && (stmp->bsym->section == expr_section) 486 && ! S_IS_LOCAL (stmp)) 487 { 488 if (signed_p) 489 stmp->bsym->flags |= BSF_SRELC; 490 else 491 stmp->bsym->flags |= BSF_RELC; 492 } 493 494 /* Now package it all up for the fixup emitter. */ 495 exp.X_op = O_symbol; 496 exp.X_op_symbol = 0; 497 exp.X_add_symbol = stmp; 498 exp.X_add_number = 0; 499 500 /* Re-init rightshift quantity, just in case. */ 501 rightshift = operand->length; 502 queue_fixup_recursively (opindex, opinfo_1, & exp, 503 (reloc_type == BFD_RELOC_RELC) ? 504 & (operand->index_fields) : 0, 505 signed_p, -1); 506 } 507 * resultP = errmsg 508 ? CGEN_PARSE_OPERAND_RESULT_ERROR 509 : CGEN_PARSE_OPERAND_RESULT_QUEUED; 510 *valueP = 0; 511 #else 512 queue_fixup (opindex, opinfo_1, &exp); 513 *valueP = 0; 514 *resultP = CGEN_PARSE_OPERAND_RESULT_QUEUED; 515 #endif 516 break; 517 } 518 519 return errmsg; 520 } 521 522 /* md_operand handler to catch unrecognized expressions and halt the 523 parsing process so the next entry can be tried. 524 525 ??? This could be done differently by adding code to `expression'. */ 526 527 void 528 gas_cgen_md_operand (expressionP) 529 expressionS *expressionP ATTRIBUTE_UNUSED; 530 { 531 /* Don't longjmp if we're not called from within cgen_parse_operand(). */ 532 if (expr_jmp_buf_p) 533 longjmp (expr_jmp_buf, 1); 534 } 535 536 /* Finish assembling instruction INSN. 537 BUF contains what we've built up so far. 538 LENGTH is the size of the insn in bits. 539 RELAX_P is non-zero if relaxable insns should be emitted as such. 540 Otherwise they're emitted in non-relaxable forms. 541 The "result" is stored in RESULT if non-NULL. */ 542 543 void 544 gas_cgen_finish_insn (insn, buf, length, relax_p, result) 545 const CGEN_INSN *insn; 546 CGEN_INSN_BYTES_PTR buf; 547 unsigned int length; 548 int relax_p; 549 finished_insnS *result; 550 { 551 int i; 552 int relax_operand; 553 char *f; 554 unsigned int byte_len = length / 8; 555 556 /* ??? Target foo issues various warnings here, so one might want to provide 557 a hook here. However, our caller is defined in tc-foo.c so there 558 shouldn't be a need for a hook. */ 559 560 /* Write out the instruction. 561 It is important to fetch enough space in one call to `frag_more'. 562 We use (f - frag_now->fr_literal) to compute where we are and we 563 don't want frag_now to change between calls. 564 565 Relaxable instructions: We need to ensure we allocate enough 566 space for the largest insn. */ 567 568 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED)) 569 /* These currently shouldn't get here. */ 570 abort (); 571 572 /* Is there a relaxable insn with the relaxable operand needing a fixup? */ 573 574 relax_operand = -1; 575 if (relax_p && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE)) 576 { 577 /* Scan the fixups for the operand affected by relaxing 578 (i.e. the branch address). */ 579 580 for (i = 0; i < num_fixups; ++i) 581 { 582 if (CGEN_OPERAND_ATTR_VALUE (cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex), 583 CGEN_OPERAND_RELAX)) 584 { 585 relax_operand = i; 586 break; 587 } 588 } 589 } 590 591 if (relax_operand != -1) 592 { 593 int max_len; 594 fragS *old_frag; 595 expressionS *exp; 596 symbolS *sym; 597 offsetT off; 598 599 #ifdef TC_CGEN_MAX_RELAX 600 max_len = TC_CGEN_MAX_RELAX (insn, byte_len); 601 #else 602 max_len = CGEN_MAX_INSN_SIZE; 603 #endif 604 /* Ensure variable part and fixed part are in same fragment. */ 605 /* FIXME: Having to do this seems like a hack. */ 606 frag_grow (max_len); 607 608 /* Allocate space for the fixed part. */ 609 f = frag_more (byte_len); 610 611 /* Create a relaxable fragment for this instruction. */ 612 old_frag = frag_now; 613 614 exp = &fixups[relax_operand].exp; 615 sym = exp->X_add_symbol; 616 off = exp->X_add_number; 617 if (exp->X_op != O_constant && exp->X_op != O_symbol) 618 { 619 /* Handle complex expressions. */ 620 sym = make_expr_symbol (exp); 621 off = 0; 622 } 623 624 frag_var (rs_machine_dependent, 625 max_len - byte_len /* max chars */, 626 0 /* variable part already allocated */, 627 /* FIXME: When we machine generate the relax table, 628 machine generate a macro to compute subtype. */ 629 1 /* subtype */, 630 sym, 631 off, 632 f); 633 634 /* Record the operand number with the fragment so md_convert_frag 635 can use gas_cgen_md_record_fixup to record the appropriate reloc. */ 636 old_frag->fr_cgen.insn = insn; 637 old_frag->fr_cgen.opindex = fixups[relax_operand].opindex; 638 old_frag->fr_cgen.opinfo = fixups[relax_operand].opinfo; 639 if (result) 640 result->frag = old_frag; 641 } 642 else 643 { 644 f = frag_more (byte_len); 645 if (result) 646 result->frag = frag_now; 647 } 648 649 /* If we're recording insns as numbers (rather than a string of bytes), 650 target byte order handling is deferred until now. */ 651 #if CGEN_INT_INSN_P 652 cgen_put_insn_value (gas_cgen_cpu_desc, (unsigned char *) f, length, *buf); 653 #else 654 memcpy (f, buf, byte_len); 655 #endif 656 657 /* Emit DWARF2 debugging information. */ 658 dwarf2_emit_insn (byte_len); 659 660 /* Create any fixups. */ 661 for (i = 0; i < num_fixups; ++i) 662 { 663 fixS *fixP; 664 const CGEN_OPERAND *operand = 665 cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex); 666 667 /* Don't create fixups for these. That's done during relaxation. 668 We don't need to test for CGEN_INSN_RELAXED as they can't get here 669 (see above). */ 670 if (relax_p 671 && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE) 672 && CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_RELAX)) 673 continue; 674 675 #ifndef md_cgen_record_fixup_exp 676 #define md_cgen_record_fixup_exp gas_cgen_record_fixup_exp 677 #endif 678 679 fixP = md_cgen_record_fixup_exp (frag_now, f - frag_now->fr_literal, 680 insn, length, operand, 681 fixups[i].opinfo, 682 &fixups[i].exp); 683 fixP->fx_cgen.field = fixups[i].field; 684 fixP->fx_cgen.msb_field_p = fixups[i].msb_field_p; 685 if (result) 686 result->fixups[i] = fixP; 687 } 688 689 if (result) 690 { 691 result->num_fixups = num_fixups; 692 result->addr = f; 693 } 694 } 695 696 #ifdef OBJ_COMPLEX_RELC 697 /* Queue many fixups, recursively. If the field is a multi-ifield, 698 repeatedly queue its sub-parts, right shifted to fit into the field (we 699 assume here multi-fields represent a left-to-right, MSB0-LSB0 700 reading). */ 701 702 static void 703 queue_fixup_recursively (const int opindex, 704 const int opinfo, 705 expressionS * expP, 706 const CGEN_MAYBE_MULTI_IFLD * field, 707 const int signed_p, 708 const int part_of_multi) 709 { 710 if (field && field->count) 711 { 712 int i; 713 714 for (i = 0; i < field->count; ++ i) 715 queue_fixup_recursively (opindex, opinfo, expP, 716 & (field->val.multi[i]), signed_p, i); 717 } 718 else 719 { 720 expressionS * new_exp = expP; 721 722 #ifdef DEBUG 723 printf ("queueing fixup for field %s\n", 724 (field ? field->val.leaf->name : "??")); 725 print_symbol_value (expP->X_add_symbol); 726 #endif 727 if (field && part_of_multi != -1) 728 { 729 rightshift -= field->val.leaf->length; 730 731 /* Shift reloc value by number of bits remaining after this 732 field. */ 733 if (rightshift) 734 new_exp = make_right_shifted_expr (expP, rightshift, signed_p); 735 } 736 737 /* Truncate reloc values to length, *after* leftmost one. */ 738 fixups[num_fixups].msb_field_p = (part_of_multi <= 0); 739 fixups[num_fixups].field = (CGEN_MAYBE_MULTI_IFLD *) field; 740 741 queue_fixup (opindex, opinfo, new_exp); 742 } 743 } 744 745 /* Encode the self-describing RELC reloc format's addend. */ 746 747 static unsigned long 748 gas_cgen_encode_addend (const unsigned long start, /* in bits */ 749 const unsigned long len, /* in bits */ 750 const unsigned long oplen, /* in bits */ 751 const unsigned long wordsz, /* in bytes */ 752 const unsigned long chunksz, /* in bytes */ 753 const unsigned long signed_p, 754 const unsigned long trunc_p) 755 { 756 unsigned long res = 0L; 757 758 res |= start & 0x3F; 759 res |= (oplen & 0x3F) << 6; 760 res |= (len & 0x3F) << 12; 761 res |= (wordsz & 0xF) << 18; 762 res |= (chunksz & 0xF) << 22; 763 res |= (CGEN_INSN_LSB0_P ? 1 : 0) << 27; 764 res |= signed_p << 28; 765 res |= trunc_p << 29; 766 767 return res; 768 } 769 770 /* Purpose: make a weak check that the expression doesn't overflow the 771 operand it's to be inserted into. 772 773 Rationale: some insns used to use %operators to disambiguate during a 774 parse. when these %operators are translated to expressions by the macro 775 expander, the ambiguity returns. we attempt to disambiguate by field 776 size. 777 778 Method: check to see if the expression's top node is an O_and operator, 779 and the mask is larger than the operand length. This would be an 780 overflow, so signal it by returning an error string. Any other case is 781 ambiguous, so we assume it's OK and return NULL. */ 782 783 static char * 784 weak_operand_overflow_check (const expressionS * exp, 785 const CGEN_OPERAND * operand) 786 { 787 const unsigned long len = operand->length; 788 unsigned long mask; 789 unsigned long opmask = (((1L << (len - 1)) - 1) << 1) | 1; 790 791 if (!exp) 792 return NULL; 793 794 if (exp->X_op != O_bit_and) 795 { 796 /* Check for implicit overflow flag. */ 797 if (CGEN_OPERAND_ATTR_VALUE 798 (operand, CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW)) 799 return _("a reloc on this operand implies an overflow"); 800 return NULL; 801 } 802 803 mask = exp->X_add_number; 804 805 if (exp->X_add_symbol 806 && exp->X_add_symbol->sy_value.X_op == O_constant) 807 mask |= exp->X_add_symbol->sy_value.X_add_number; 808 809 if (exp->X_op_symbol 810 && exp->X_op_symbol->sy_value.X_op == O_constant) 811 mask |= exp->X_op_symbol->sy_value.X_add_number; 812 813 /* Want to know if mask covers more bits than opmask. 814 this is the same as asking if mask has any bits not in opmask, 815 or whether (mask & ~opmask) is nonzero. */ 816 if (mask && (mask & ~opmask)) 817 { 818 #ifdef DEBUG 819 printf ("overflow: (mask = %8.8x, ~opmask = %8.8x, AND = %8.8x)\n", 820 mask, ~opmask, (mask & ~opmask)); 821 #endif 822 return _("operand mask overflow"); 823 } 824 825 return NULL; 826 } 827 828 static expressionS * 829 make_right_shifted_expr (expressionS * exp, 830 const int amount, 831 const int signed_p) 832 { 833 symbolS * stmp = 0; 834 expressionS * new_exp; 835 836 stmp = expr_build_binary (O_right_shift, 837 make_expr_symbol (exp), 838 expr_build_uconstant (amount)); 839 840 if (signed_p) 841 stmp->bsym->flags |= BSF_SRELC; 842 else 843 stmp->bsym->flags |= BSF_RELC; 844 845 /* Then wrap that in a "symbol expr" for good measure. */ 846 new_exp = xmalloc (sizeof (expressionS)); 847 memset (new_exp, 0, sizeof (expressionS)); 848 new_exp->X_op = O_symbol; 849 new_exp->X_op_symbol = 0; 850 new_exp->X_add_symbol = stmp; 851 new_exp->X_add_number = 0; 852 853 return new_exp; 854 } 855 856 #endif 857 858 /* Apply a fixup to the object code. This is called for all the 859 fixups we generated by the call to fix_new_exp, above. In the call 860 above we used a reloc code which was the largest legal reloc code 861 plus the operand index. Here we undo that to recover the operand 862 index. At this point all symbol values should be fully resolved, 863 and we attempt to completely resolve the reloc. If we can not do 864 that, we determine the correct reloc code and put it back in the fixup. */ 865 866 /* FIXME: This function handles some of the fixups and bfd_install_relocation 867 handles the rest. bfd_install_relocation (or some other bfd function) 868 should handle them all. */ 869 870 void 871 gas_cgen_md_apply_fix (fixP, valP, seg) 872 fixS * fixP; 873 valueT * valP; 874 segT seg ATTRIBUTE_UNUSED; 875 { 876 char *where = fixP->fx_frag->fr_literal + fixP->fx_where; 877 valueT value = * valP; 878 /* Canonical name, since used a lot. */ 879 CGEN_CPU_DESC cd = gas_cgen_cpu_desc; 880 881 if (fixP->fx_addsy == (symbolS *) NULL) 882 fixP->fx_done = 1; 883 884 /* We don't actually support subtracting a symbol. */ 885 if (fixP->fx_subsy != (symbolS *) NULL) 886 as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex")); 887 888 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED) 889 { 890 int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED; 891 const CGEN_OPERAND *operand = cgen_operand_lookup_by_num (cd, opindex); 892 const char *errmsg; 893 bfd_reloc_code_real_type reloc_type; 894 CGEN_FIELDS *fields = alloca (CGEN_CPU_SIZEOF_FIELDS (cd)); 895 const CGEN_INSN *insn = fixP->fx_cgen.insn; 896 #ifdef OBJ_COMPLEX_RELC 897 int start; 898 int length; 899 int signed_p = 0; 900 901 if (fixP->fx_cgen.field) 902 { 903 /* Use the twisty little pointer path 904 back to the ifield if it exists. */ 905 start = fixP->fx_cgen.field->val.leaf->start; 906 length = fixP->fx_cgen.field->val.leaf->length; 907 } 908 else 909 { 910 /* Or the far less useful operand-size guesstimate. */ 911 start = operand->start; 912 length = operand->length; 913 } 914 915 /* FIXME: this is not a perfect heuristic for figuring out 916 whether an operand is signed: it only works when the operand 917 is an immediate. it's not terribly likely that any other 918 values will be signed relocs, but it's possible. */ 919 if (operand && (operand->hw_type == HW_H_SINT)) 920 signed_p = 1; 921 #endif 922 923 /* If the reloc has been fully resolved finish the operand here. */ 924 /* FIXME: This duplicates the capabilities of code in BFD. */ 925 if (fixP->fx_done 926 /* FIXME: If partial_inplace isn't set bfd_install_relocation won't 927 finish the job. Testing for pcrel is a temporary hack. */ 928 || fixP->fx_pcrel) 929 { 930 CGEN_CPU_SET_FIELDS_BITSIZE (cd) (fields, CGEN_INSN_BITSIZE (insn)); 931 CGEN_CPU_SET_VMA_OPERAND (cd) (cd, opindex, fields, (bfd_vma) value); 932 933 #if CGEN_INT_INSN_P 934 { 935 CGEN_INSN_INT insn_value = 936 cgen_get_insn_value (cd, (unsigned char *) where, 937 CGEN_INSN_BITSIZE (insn)); 938 939 /* ??? 0 is passed for `pc'. */ 940 errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields, 941 &insn_value, (bfd_vma) 0); 942 cgen_put_insn_value (cd, (unsigned char *) where, 943 CGEN_INSN_BITSIZE (insn), insn_value); 944 } 945 #else 946 /* ??? 0 is passed for `pc'. */ 947 errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields, 948 (unsigned char *) where, 949 (bfd_vma) 0); 950 #endif 951 if (errmsg) 952 as_bad_where (fixP->fx_file, fixP->fx_line, "%s", errmsg); 953 } 954 955 if (fixP->fx_done) 956 return; 957 958 /* The operand isn't fully resolved. Determine a BFD reloc value 959 based on the operand information and leave it to 960 bfd_install_relocation. Note that this doesn't work when 961 partial_inplace == false. */ 962 963 reloc_type = md_cgen_lookup_reloc (insn, operand, fixP); 964 #ifdef OBJ_COMPLEX_RELC 965 if (reloc_type == BFD_RELOC_RELC) 966 { 967 /* Change addend to "self-describing" form, 968 for BFD to handle in the linker. */ 969 value = gas_cgen_encode_addend (start, operand->length, 970 length, fixP->fx_size, 971 cd->insn_chunk_bitsize / 8, 972 signed_p, 973 ! (fixP->fx_cgen.msb_field_p)); 974 } 975 #endif 976 977 if (reloc_type != BFD_RELOC_NONE) 978 fixP->fx_r_type = reloc_type; 979 else 980 { 981 as_bad_where (fixP->fx_file, fixP->fx_line, 982 _("unresolved expression that must be resolved")); 983 fixP->fx_done = 1; 984 return; 985 } 986 } 987 else if (fixP->fx_done) 988 { 989 /* We're finished with this fixup. Install it because 990 bfd_install_relocation won't be called to do it. */ 991 switch (fixP->fx_r_type) 992 { 993 case BFD_RELOC_8: 994 md_number_to_chars (where, value, 1); 995 break; 996 case BFD_RELOC_16: 997 md_number_to_chars (where, value, 2); 998 break; 999 case BFD_RELOC_32: 1000 md_number_to_chars (where, value, 4); 1001 break; 1002 case BFD_RELOC_64: 1003 md_number_to_chars (where, value, 8); 1004 break; 1005 default: 1006 as_bad_where (fixP->fx_file, fixP->fx_line, 1007 _("internal error: can't install fix for reloc type %d (`%s')"), 1008 fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type)); 1009 break; 1010 } 1011 } 1012 /* else 1013 bfd_install_relocation will be called to finish things up. */ 1014 1015 /* Tuck `value' away for use by tc_gen_reloc. 1016 See the comment describing fx_addnumber in write.h. 1017 This field is misnamed (or misused :-). */ 1018 fixP->fx_addnumber = value; 1019 } 1020 1021 bfd_reloc_code_real_type 1022 gas_cgen_pcrel_r_type (bfd_reloc_code_real_type r) 1023 { 1024 switch (r) 1025 { 1026 case BFD_RELOC_8: r = BFD_RELOC_8_PCREL; break; 1027 case BFD_RELOC_16: r = BFD_RELOC_16_PCREL; break; 1028 case BFD_RELOC_24: r = BFD_RELOC_24_PCREL; break; 1029 case BFD_RELOC_32: r = BFD_RELOC_32_PCREL; break; 1030 case BFD_RELOC_64: r = BFD_RELOC_64_PCREL; break; 1031 default: 1032 break; 1033 } 1034 return r; 1035 } 1036 1037 /* Translate internal representation of relocation info to BFD target format. 1038 1039 FIXME: To what extent can we get all relevant targets to use this? */ 1040 1041 arelent * 1042 gas_cgen_tc_gen_reloc (section, fixP) 1043 asection * section ATTRIBUTE_UNUSED; 1044 fixS * fixP; 1045 { 1046 bfd_reloc_code_real_type r_type = fixP->fx_r_type; 1047 arelent *reloc; 1048 1049 reloc = (arelent *) xmalloc (sizeof (arelent)); 1050 1051 #ifdef GAS_CGEN_PCREL_R_TYPE 1052 if (fixP->fx_pcrel) 1053 r_type = GAS_CGEN_PCREL_R_TYPE (r_type); 1054 #endif 1055 reloc->howto = bfd_reloc_type_lookup (stdoutput, r_type); 1056 1057 if (reloc->howto == (reloc_howto_type *) NULL) 1058 { 1059 as_bad_where (fixP->fx_file, fixP->fx_line, 1060 _("relocation is not supported")); 1061 return NULL; 1062 } 1063 1064 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative); 1065 1066 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); 1067 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy); 1068 1069 /* Use fx_offset for these cases. */ 1070 if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY 1071 || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT) 1072 reloc->addend = fixP->fx_offset; 1073 else 1074 reloc->addend = fixP->fx_addnumber; 1075 1076 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where; 1077 return reloc; 1078 } 1079 1080 /* Perform any cgen specific initialisation. 1081 Called after gas_cgen_cpu_desc has been created. */ 1082 1083 void 1084 gas_cgen_begin () 1085 { 1086 if (flag_signed_overflow_ok) 1087 cgen_set_signed_overflow_ok (gas_cgen_cpu_desc); 1088 else 1089 cgen_clear_signed_overflow_ok (gas_cgen_cpu_desc); 1090 } 1091