1 /* tc-bfin.c -- Assembler for the ADI Blackfin. 2 Copyright 2005 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 2, 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 the Free 19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 20 02110-1301, USA. */ 21 22 #include "as.h" 23 #include "struc-symbol.h" 24 #include "obj-elf.h" 25 #include "bfin-defs.h" 26 #include "obstack.h" 27 #include "safe-ctype.h" 28 #ifdef OBJ_ELF 29 #include "dwarf2dbg.h" 30 #endif 31 #include "libbfd.h" 32 #include "elf/common.h" 33 #include "elf/bfin.h" 34 35 extern int yyparse (void); 36 struct yy_buffer_state; 37 typedef struct yy_buffer_state *YY_BUFFER_STATE; 38 extern YY_BUFFER_STATE yy_scan_string (const char *yy_str); 39 extern void yy_delete_buffer (YY_BUFFER_STATE b); 40 static parse_state parse (char *line); 41 static void bfin_s_bss PARAMS ((int)); 42 static int md_chars_to_number PARAMS ((char *, int)); 43 44 /* Global variables. */ 45 struct bfin_insn *insn; 46 int last_insn_size; 47 48 extern struct obstack mempool; 49 FILE *errorf; 50 51 /* Flags to set in the elf header */ 52 #define DEFAULT_FLAGS 0 53 54 static flagword bfin_flags = DEFAULT_FLAGS; 55 static const char *bfin_pic_flag = (const char *)0; 56 57 /* Registers list. */ 58 struct bfin_reg_entry 59 { 60 const char *name; 61 int number; 62 }; 63 64 static const struct bfin_reg_entry bfin_reg_info[] = { 65 {"R0.L", REG_RL0}, 66 {"R1.L", REG_RL1}, 67 {"R2.L", REG_RL2}, 68 {"R3.L", REG_RL3}, 69 {"R4.L", REG_RL4}, 70 {"R5.L", REG_RL5}, 71 {"R6.L", REG_RL6}, 72 {"R7.L", REG_RL7}, 73 {"R0.H", REG_RH0}, 74 {"R1.H", REG_RH1}, 75 {"R2.H", REG_RH2}, 76 {"R3.H", REG_RH3}, 77 {"R4.H", REG_RH4}, 78 {"R5.H", REG_RH5}, 79 {"R6.H", REG_RH6}, 80 {"R7.H", REG_RH7}, 81 {"R0", REG_R0}, 82 {"R1", REG_R1}, 83 {"R2", REG_R2}, 84 {"R3", REG_R3}, 85 {"R4", REG_R4}, 86 {"R5", REG_R5}, 87 {"R6", REG_R6}, 88 {"R7", REG_R7}, 89 {"P0", REG_P0}, 90 {"P0.H", REG_P0}, 91 {"P0.L", REG_P0}, 92 {"P1", REG_P1}, 93 {"P1.H", REG_P1}, 94 {"P1.L", REG_P1}, 95 {"P2", REG_P2}, 96 {"P2.H", REG_P2}, 97 {"P2.L", REG_P2}, 98 {"P3", REG_P3}, 99 {"P3.H", REG_P3}, 100 {"P3.L", REG_P3}, 101 {"P4", REG_P4}, 102 {"P4.H", REG_P4}, 103 {"P4.L", REG_P4}, 104 {"P5", REG_P5}, 105 {"P5.H", REG_P5}, 106 {"P5.L", REG_P5}, 107 {"SP", REG_SP}, 108 {"SP.L", REG_SP}, 109 {"SP.H", REG_SP}, 110 {"FP", REG_FP}, 111 {"FP.L", REG_FP}, 112 {"FP.H", REG_FP}, 113 {"A0x", REG_A0x}, 114 {"A1x", REG_A1x}, 115 {"A0w", REG_A0w}, 116 {"A1w", REG_A1w}, 117 {"A0.x", REG_A0x}, 118 {"A1.x", REG_A1x}, 119 {"A0.w", REG_A0w}, 120 {"A1.w", REG_A1w}, 121 {"A0", REG_A0}, 122 {"A0.L", REG_A0}, 123 {"A0.H", REG_A0}, 124 {"A1", REG_A1}, 125 {"A1.L", REG_A1}, 126 {"A1.H", REG_A1}, 127 {"I0", REG_I0}, 128 {"I0.L", REG_I0}, 129 {"I0.H", REG_I0}, 130 {"I1", REG_I1}, 131 {"I1.L", REG_I1}, 132 {"I1.H", REG_I1}, 133 {"I2", REG_I2}, 134 {"I2.L", REG_I2}, 135 {"I2.H", REG_I2}, 136 {"I3", REG_I3}, 137 {"I3.L", REG_I3}, 138 {"I3.H", REG_I3}, 139 {"M0", REG_M0}, 140 {"M0.H", REG_M0}, 141 {"M0.L", REG_M0}, 142 {"M1", REG_M1}, 143 {"M1.H", REG_M1}, 144 {"M1.L", REG_M1}, 145 {"M2", REG_M2}, 146 {"M2.H", REG_M2}, 147 {"M2.L", REG_M2}, 148 {"M3", REG_M3}, 149 {"M3.H", REG_M3}, 150 {"M3.L", REG_M3}, 151 {"B0", REG_B0}, 152 {"B0.H", REG_B0}, 153 {"B0.L", REG_B0}, 154 {"B1", REG_B1}, 155 {"B1.H", REG_B1}, 156 {"B1.L", REG_B1}, 157 {"B2", REG_B2}, 158 {"B2.H", REG_B2}, 159 {"B2.L", REG_B2}, 160 {"B3", REG_B3}, 161 {"B3.H", REG_B3}, 162 {"B3.L", REG_B3}, 163 {"L0", REG_L0}, 164 {"L0.H", REG_L0}, 165 {"L0.L", REG_L0}, 166 {"L1", REG_L1}, 167 {"L1.H", REG_L1}, 168 {"L1.L", REG_L1}, 169 {"L2", REG_L2}, 170 {"L2.H", REG_L2}, 171 {"L2.L", REG_L2}, 172 {"L3", REG_L3}, 173 {"L3.H", REG_L3}, 174 {"L3.L", REG_L3}, 175 {"AZ", S_AZ}, 176 {"AN", S_AN}, 177 {"AC0", S_AC0}, 178 {"AC1", S_AC1}, 179 {"AV0", S_AV0}, 180 {"AV0S", S_AV0S}, 181 {"AV1", S_AV1}, 182 {"AV1S", S_AV1S}, 183 {"AQ", S_AQ}, 184 {"V", S_V}, 185 {"VS", S_VS}, 186 {"sftreset", REG_sftreset}, 187 {"omode", REG_omode}, 188 {"excause", REG_excause}, 189 {"emucause", REG_emucause}, 190 {"idle_req", REG_idle_req}, 191 {"hwerrcause", REG_hwerrcause}, 192 {"CC", REG_CC}, 193 {"LC0", REG_LC0}, 194 {"LC1", REG_LC1}, 195 {"ASTAT", REG_ASTAT}, 196 {"RETS", REG_RETS}, 197 {"LT0", REG_LT0}, 198 {"LB0", REG_LB0}, 199 {"LT1", REG_LT1}, 200 {"LB1", REG_LB1}, 201 {"CYCLES", REG_CYCLES}, 202 {"CYCLES2", REG_CYCLES2}, 203 {"USP", REG_USP}, 204 {"SEQSTAT", REG_SEQSTAT}, 205 {"SYSCFG", REG_SYSCFG}, 206 {"RETI", REG_RETI}, 207 {"RETX", REG_RETX}, 208 {"RETN", REG_RETN}, 209 {"RETE", REG_RETE}, 210 {"EMUDAT", REG_EMUDAT}, 211 {0, 0} 212 }; 213 214 /* Blackfin specific function to handle FD-PIC pointer initializations. */ 215 216 static void 217 bfin_pic_ptr (int nbytes) 218 { 219 expressionS exp; 220 char *p; 221 222 if (nbytes != 4) 223 abort (); 224 225 #ifdef md_flush_pending_output 226 md_flush_pending_output (); 227 #endif 228 229 if (is_it_end_of_statement ()) 230 { 231 demand_empty_rest_of_line (); 232 return; 233 } 234 235 #ifdef md_cons_align 236 md_cons_align (nbytes); 237 #endif 238 239 do 240 { 241 bfd_reloc_code_real_type reloc_type = BFD_RELOC_BFIN_FUNCDESC; 242 243 if (strncasecmp (input_line_pointer, "funcdesc(", 9) == 0) 244 { 245 input_line_pointer += 9; 246 expression (&exp); 247 if (*input_line_pointer == ')') 248 input_line_pointer++; 249 else 250 as_bad ("missing ')'"); 251 } 252 else 253 error ("missing funcdesc in picptr"); 254 255 p = frag_more (4); 256 memset (p, 0, 4); 257 fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &exp, 0, 258 reloc_type); 259 } 260 while (*input_line_pointer++ == ','); 261 262 input_line_pointer--; /* Put terminator back into stream. */ 263 demand_empty_rest_of_line (); 264 } 265 266 static void 267 bfin_s_bss (int ignore ATTRIBUTE_UNUSED) 268 { 269 register int temp; 270 271 temp = get_absolute_expression (); 272 subseg_set (bss_section, (subsegT) temp); 273 demand_empty_rest_of_line (); 274 } 275 276 const pseudo_typeS md_pseudo_table[] = { 277 {"align", s_align_bytes, 0}, 278 {"byte2", cons, 2}, 279 {"byte4", cons, 4}, 280 {"picptr", bfin_pic_ptr, 4}, 281 {"code", obj_elf_section, 0}, 282 {"db", cons, 1}, 283 {"dd", cons, 4}, 284 {"dw", cons, 2}, 285 {"p", s_ignore, 0}, 286 {"pdata", s_ignore, 0}, 287 {"var", s_ignore, 0}, 288 {"bss", bfin_s_bss, 0}, 289 {0, 0, 0} 290 }; 291 292 /* Characters that are used to denote comments and line separators. */ 293 const char comment_chars[] = ""; 294 const char line_comment_chars[] = "#"; 295 const char line_separator_chars[] = ";"; 296 297 /* Characters that can be used to separate the mantissa from the 298 exponent in floating point numbers. */ 299 const char EXP_CHARS[] = "eE"; 300 301 /* Characters that mean this number is a floating point constant. 302 As in 0f12.456 or 0d1.2345e12. */ 303 const char FLT_CHARS[] = "fFdDxX"; 304 305 /* Define bfin-specific command-line options (there are none). */ 306 const char *md_shortopts = ""; 307 308 #define OPTION_FDPIC (OPTION_MD_BASE) 309 310 struct option md_longopts[] = 311 { 312 { "mfdpic", no_argument, NULL, OPTION_FDPIC }, 313 { NULL, no_argument, NULL, 0 }, 314 }; 315 316 size_t md_longopts_size = sizeof (md_longopts); 317 318 319 int 320 md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED) 321 { 322 switch (c) 323 { 324 default: 325 return 0; 326 327 case OPTION_FDPIC: 328 bfin_flags |= EF_BFIN_FDPIC; 329 bfin_pic_flag = "-mfdpic"; 330 break; 331 } 332 333 return 1; 334 } 335 336 void 337 md_show_usage (FILE * stream ATTRIBUTE_UNUSED) 338 { 339 fprintf (stream, _(" BFIN specific command line options:\n")); 340 } 341 342 /* Perform machine-specific initializations. */ 343 void 344 md_begin () 345 { 346 /* Set the ELF flags if desired. */ 347 if (bfin_flags) 348 bfd_set_private_flags (stdoutput, bfin_flags); 349 350 /* Set the default machine type. */ 351 if (!bfd_set_arch_mach (stdoutput, bfd_arch_bfin, 0)) 352 as_warn ("Could not set architecture and machine."); 353 354 /* Ensure that lines can begin with '(', for multiple 355 register stack pops. */ 356 lex_type ['('] = LEX_BEGIN_NAME; 357 358 #ifdef OBJ_ELF 359 record_alignment (text_section, 2); 360 record_alignment (data_section, 2); 361 record_alignment (bss_section, 2); 362 #endif 363 364 errorf = stderr; 365 obstack_init (&mempool); 366 367 #ifdef DEBUG 368 extern int debug_codeselection; 369 debug_codeselection = 1; 370 #endif 371 372 last_insn_size = 0; 373 } 374 375 /* Perform the main parsing, and assembly of the input here. Also, 376 call the required routines for alignment and fixups here. 377 This is called for every line that contains real assembly code. */ 378 379 void 380 md_assemble (char *line) 381 { 382 char *toP = 0; 383 extern char *current_inputline; 384 int size, insn_size; 385 struct bfin_insn *tmp_insn; 386 size_t len; 387 static size_t buffer_len = 0; 388 parse_state state; 389 390 len = strlen (line); 391 if (len + 2 > buffer_len) 392 { 393 if (buffer_len > 0) 394 free (current_inputline); 395 buffer_len = len + 40; 396 current_inputline = xmalloc (buffer_len); 397 } 398 memcpy (current_inputline, line, len); 399 current_inputline[len] = ';'; 400 current_inputline[len + 1] = '\0'; 401 402 state = parse (current_inputline); 403 if (state == NO_INSN_GENERATED) 404 return; 405 406 for (insn_size = 0, tmp_insn = insn; tmp_insn; tmp_insn = tmp_insn->next) 407 if (!tmp_insn->reloc || !tmp_insn->exp->symbol) 408 insn_size += 2; 409 410 if (insn_size) 411 toP = frag_more (insn_size); 412 413 last_insn_size = insn_size; 414 415 #ifdef DEBUG 416 printf ("INS:"); 417 #endif 418 while (insn) 419 { 420 if (insn->reloc && insn->exp->symbol) 421 { 422 char *prev_toP = toP - 2; 423 switch (insn->reloc) 424 { 425 case BFD_RELOC_BFIN_24_PCREL_JUMP_L: 426 case BFD_RELOC_24_PCREL: 427 case BFD_RELOC_BFIN_16_LOW: 428 case BFD_RELOC_BFIN_16_HIGH: 429 size = 4; 430 break; 431 default: 432 size = 2; 433 } 434 435 /* Following if condition checks for the arithmetic relocations. 436 If the case then it doesn't required to generate the code. 437 It has been assumed that, their ID will be contiguous. */ 438 if ((BFD_ARELOC_BFIN_PUSH <= insn->reloc 439 && BFD_ARELOC_BFIN_COMP >= insn->reloc) 440 || insn->reloc == BFD_RELOC_BFIN_16_IMM) 441 { 442 size = 2; 443 } 444 if (insn->reloc == BFD_ARELOC_BFIN_CONST 445 || insn->reloc == BFD_ARELOC_BFIN_PUSH) 446 size = 4; 447 448 fix_new (frag_now, 449 (prev_toP - frag_now->fr_literal), 450 size, insn->exp->symbol, insn->exp->value, 451 insn->pcrel, insn->reloc); 452 } 453 else 454 { 455 md_number_to_chars (toP, insn->value, 2); 456 toP += 2; 457 } 458 459 #ifdef DEBUG 460 printf (" reloc :"); 461 printf (" %02x%02x", ((unsigned char *) &insn->value)[0], 462 ((unsigned char *) &insn->value)[1]); 463 printf ("\n"); 464 #endif 465 insn = insn->next; 466 } 467 #ifdef OBJ_ELF 468 dwarf2_emit_insn (insn_size); 469 #endif 470 } 471 472 /* Parse one line of instructions, and generate opcode for it. 473 To parse the line, YACC and LEX are used, because the instruction set 474 syntax doesn't confirm to the AT&T assembly syntax. 475 To call a YACC & LEX generated parser, we must provide the input via 476 a FILE stream, otherwise stdin is used by default. Below the input 477 to the function will be put into a temporary file, then the generated 478 parser uses the temporary file for parsing. */ 479 480 static parse_state 481 parse (char *line) 482 { 483 parse_state state; 484 YY_BUFFER_STATE buffstate; 485 486 buffstate = yy_scan_string (line); 487 488 /* our lex requires setting the start state to keyword 489 every line as the first word may be a keyword. 490 Fixes a bug where we could not have keywords as labels. */ 491 set_start_state (); 492 493 /* Call yyparse here. */ 494 state = yyparse (); 495 if (state == SEMANTIC_ERROR) 496 { 497 as_bad ("Parse failed."); 498 insn = 0; 499 } 500 501 yy_delete_buffer (buffstate); 502 return state; 503 } 504 505 /* We need to handle various expressions properly. 506 Such as, [SP--] = 34, concerned by md_assemble(). */ 507 508 void 509 md_operand (expressionS * expressionP) 510 { 511 if (*input_line_pointer == '[') 512 { 513 as_tsktsk ("We found a '['!"); 514 input_line_pointer++; 515 expression (expressionP); 516 } 517 } 518 519 /* Handle undefined symbols. */ 520 symbolS * 521 md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 522 { 523 return (symbolS *) 0; 524 } 525 526 int 527 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, 528 segT segment ATTRIBUTE_UNUSED) 529 { 530 return 0; 531 } 532 533 /* Convert from target byte order to host byte order. */ 534 535 static int 536 md_chars_to_number (char *val, int n) 537 { 538 int retval; 539 540 for (retval = 0; n--;) 541 { 542 retval <<= 8; 543 retval |= val[n]; 544 } 545 return retval; 546 } 547 548 void 549 md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED) 550 { 551 char *where = fixP->fx_frag->fr_literal + fixP->fx_where; 552 553 long value = *valueP; 554 long newval; 555 556 switch (fixP->fx_r_type) 557 { 558 case BFD_RELOC_BFIN_GOT: 559 case BFD_RELOC_BFIN_GOT17M4: 560 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4: 561 fixP->fx_no_overflow = 1; 562 newval = md_chars_to_number (where, 2); 563 newval |= 0x0 & 0x7f; 564 md_number_to_chars (where, newval, 2); 565 break; 566 567 case BFD_RELOC_BFIN_10_PCREL: 568 if (!value) 569 break; 570 if (value < -1024 || value > 1022) 571 as_bad_where (fixP->fx_file, fixP->fx_line, 572 "pcrel too far BFD_RELOC_BFIN_10"); 573 574 /* 11 bit offset even numbered, so we remove right bit. */ 575 value = value >> 1; 576 newval = md_chars_to_number (where, 2); 577 newval |= value & 0x03ff; 578 md_number_to_chars (where, newval, 2); 579 break; 580 581 case BFD_RELOC_BFIN_12_PCREL_JUMP: 582 case BFD_RELOC_BFIN_12_PCREL_JUMP_S: 583 case BFD_RELOC_12_PCREL: 584 if (!value) 585 break; 586 587 if (value < -4096 || value > 4094) 588 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_12"); 589 /* 13 bit offset even numbered, so we remove right bit. */ 590 value = value >> 1; 591 newval = md_chars_to_number (where, 2); 592 newval |= value & 0xfff; 593 md_number_to_chars (where, newval, 2); 594 break; 595 596 case BFD_RELOC_BFIN_16_LOW: 597 case BFD_RELOC_BFIN_16_HIGH: 598 fixP->fx_done = FALSE; 599 break; 600 601 case BFD_RELOC_BFIN_24_PCREL_JUMP_L: 602 case BFD_RELOC_BFIN_24_PCREL_CALL_X: 603 case BFD_RELOC_24_PCREL: 604 if (!value) 605 break; 606 607 if (value < -16777216 || value > 16777214) 608 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_24"); 609 610 /* 25 bit offset even numbered, so we remove right bit. */ 611 value = value >> 1; 612 value++; 613 614 md_number_to_chars (where - 2, value >> 16, 1); 615 md_number_to_chars (where, value, 1); 616 md_number_to_chars (where + 1, value >> 8, 1); 617 break; 618 619 case BFD_RELOC_BFIN_5_PCREL: /* LSETUP (a, b) : "a" */ 620 if (!value) 621 break; 622 if (value < 4 || value > 30) 623 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_5"); 624 value = value >> 1; 625 newval = md_chars_to_number (where, 1); 626 newval = (newval & 0xf0) | (value & 0xf); 627 md_number_to_chars (where, newval, 1); 628 break; 629 630 case BFD_RELOC_BFIN_11_PCREL: /* LSETUP (a, b) : "b" */ 631 if (!value) 632 break; 633 value += 2; 634 if (value < 4 || value > 2046) 635 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_11_PCREL"); 636 /* 11 bit unsigned even, so we remove right bit. */ 637 value = value >> 1; 638 newval = md_chars_to_number (where, 2); 639 newval |= value & 0x03ff; 640 md_number_to_chars (where, newval, 2); 641 break; 642 643 case BFD_RELOC_8: 644 if (value < -0x80 || value >= 0x7f) 645 as_bad_where (fixP->fx_file, fixP->fx_line, "rel too far BFD_RELOC_8"); 646 md_number_to_chars (where, value, 1); 647 break; 648 649 case BFD_RELOC_BFIN_16_IMM: 650 case BFD_RELOC_16: 651 if (value < -0x8000 || value >= 0x7fff) 652 as_bad_where (fixP->fx_file, fixP->fx_line, "rel too far BFD_RELOC_8"); 653 md_number_to_chars (where, value, 2); 654 break; 655 656 case BFD_RELOC_32: 657 md_number_to_chars (where, value, 4); 658 break; 659 660 case BFD_RELOC_BFIN_PLTPC: 661 md_number_to_chars (where, value, 2); 662 break; 663 664 case BFD_RELOC_BFIN_FUNCDESC: 665 case BFD_RELOC_VTABLE_INHERIT: 666 case BFD_RELOC_VTABLE_ENTRY: 667 fixP->fx_done = FALSE; 668 break; 669 670 default: 671 if ((BFD_ARELOC_BFIN_PUSH > fixP->fx_r_type) || (BFD_ARELOC_BFIN_COMP < fixP->fx_r_type)) 672 { 673 fprintf (stderr, "Relocation %d not handled in gas." " Contact support.\n", fixP->fx_r_type); 674 return; 675 } 676 } 677 678 if (!fixP->fx_addsy) 679 fixP->fx_done = TRUE; 680 681 } 682 683 /* Round up a section size to the appropriate boundary. */ 684 valueT 685 md_section_align (segment, size) 686 segT segment; 687 valueT size; 688 { 689 int boundary = bfd_get_section_alignment (stdoutput, segment); 690 return ((size + (1 << boundary) - 1) & (-1 << boundary)); 691 } 692 693 694 /* Turn a string in input_line_pointer into a floating point 695 constant of type type, and store the appropriate bytes in 696 *litP. The number of LITTLENUMS emitted is stored in *sizeP. 697 An error message is returned, or NULL on OK. */ 698 699 /* Equal to MAX_PRECISION in atof-ieee.c. */ 700 #define MAX_LITTLENUMS 6 701 702 char * 703 md_atof (type, litP, sizeP) 704 char type; 705 char * litP; 706 int * sizeP; 707 { 708 int prec; 709 LITTLENUM_TYPE words [MAX_LITTLENUMS]; 710 LITTLENUM_TYPE *wordP; 711 char * t; 712 713 switch (type) 714 { 715 case 'f': 716 case 'F': 717 prec = 2; 718 break; 719 720 case 'd': 721 case 'D': 722 prec = 4; 723 break; 724 725 /* FIXME: Some targets allow other format chars for bigger sizes here. */ 726 727 default: 728 *sizeP = 0; 729 return _("Bad call to md_atof()"); 730 } 731 732 t = atof_ieee (input_line_pointer, type, words); 733 if (t) 734 input_line_pointer = t; 735 *sizeP = prec * sizeof (LITTLENUM_TYPE); 736 737 *sizeP = prec * sizeof (LITTLENUM_TYPE); 738 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with 739 the littleendianness of the processor. */ 740 for (wordP = words + prec - 1; prec--;) 741 { 742 md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE)); 743 litP += sizeof (LITTLENUM_TYPE); 744 } 745 746 return 0; 747 } 748 749 750 /* If while processing a fixup, a reloc really needs to be created 751 then it is done here. */ 752 753 arelent * 754 tc_gen_reloc (seg, fixp) 755 asection *seg ATTRIBUTE_UNUSED; 756 fixS *fixp; 757 { 758 arelent *reloc; 759 760 reloc = (arelent *) xmalloc (sizeof (arelent)); 761 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); 762 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 763 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 764 765 reloc->addend = fixp->fx_offset; 766 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 767 768 if (reloc->howto == (reloc_howto_type *) NULL) 769 { 770 as_bad_where (fixp->fx_file, fixp->fx_line, 771 /* xgettext:c-format. */ 772 _("reloc %d not supported by object file format"), 773 (int) fixp->fx_r_type); 774 775 xfree (reloc); 776 777 return NULL; 778 } 779 780 return reloc; 781 } 782 783 /* The location from which a PC relative jump should be calculated, 784 given a PC relative reloc. */ 785 786 long 787 md_pcrel_from_section (fixP, sec) 788 fixS *fixP; 789 segT sec; 790 { 791 if (fixP->fx_addsy != (symbolS *) NULL 792 && (!S_IS_DEFINED (fixP->fx_addsy) 793 || S_GET_SEGMENT (fixP->fx_addsy) != sec)) 794 { 795 /* The symbol is undefined (or is defined but not in this section). 796 Let the linker figure it out. */ 797 return 0; 798 } 799 return fixP->fx_frag->fr_address + fixP->fx_where; 800 } 801 802 /* Return true if the fix can be handled by GAS, false if it must 803 be passed through to the linker. */ 804 805 bfd_boolean 806 bfin_fix_adjustable (fixS *fixP) 807 { 808 switch (fixP->fx_r_type) 809 { 810 /* Adjust_reloc_syms doesn't know about the GOT. */ 811 case BFD_RELOC_BFIN_GOT: 812 case BFD_RELOC_BFIN_GOT17M4: 813 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4: 814 case BFD_RELOC_BFIN_PLTPC: 815 /* We need the symbol name for the VTABLE entries. */ 816 case BFD_RELOC_VTABLE_INHERIT: 817 case BFD_RELOC_VTABLE_ENTRY: 818 return 0; 819 820 default: 821 return 1; 822 } 823 } 824 825 826 /* Handle the LOOP_BEGIN and LOOP_END statements. 827 Parse the Loop_Begin/Loop_End and create a label. */ 828 void 829 bfin_start_line_hook () 830 { 831 bfd_boolean maybe_begin = FALSE; 832 bfd_boolean maybe_end = FALSE; 833 834 char *c1, *label_name; 835 symbolS *line_label; 836 char *c = input_line_pointer; 837 838 while (ISSPACE (*c)) 839 c++; 840 841 /* Look for Loop_Begin or Loop_End statements. */ 842 843 if (*c != 'L' && *c != 'l') 844 return; 845 846 c++; 847 if (*c != 'O' && *c != 'o') 848 return; 849 850 c++; 851 if (*c != 'O' && *c != 'o') 852 return; 853 854 c++; 855 if (*c != 'P' && *c != 'p') 856 return; 857 858 c++; 859 if (*c != '_') 860 return; 861 862 c++; 863 if (*c == 'E' || *c == 'e') 864 maybe_end = TRUE; 865 else if (*c == 'B' || *c == 'b') 866 maybe_begin = TRUE; 867 else 868 return; 869 870 if (maybe_end) 871 { 872 c++; 873 if (*c != 'N' && *c != 'n') 874 return; 875 876 c++; 877 if (*c != 'D' && *c != 'd') 878 return; 879 } 880 881 if (maybe_begin) 882 { 883 c++; 884 if (*c != 'E' && *c != 'e') 885 return; 886 887 c++; 888 if (*c != 'G' && *c != 'g') 889 return; 890 891 c++; 892 if (*c != 'I' && *c != 'i') 893 return; 894 895 c++; 896 if (*c != 'N' && *c != 'n') 897 return; 898 } 899 900 c++; 901 while (ISSPACE (*c)) c++; 902 c1 = c; 903 while (ISALPHA (*c) || ISDIGIT (*c) || *c == '_') c++; 904 905 input_line_pointer = c; 906 if (maybe_end) 907 { 908 label_name = (char *) xmalloc ((c - c1) + strlen ("__END") + 1); 909 label_name[0] = 0; 910 strncat (label_name, c1, c-c1); 911 strcat (label_name, "__END"); 912 } 913 else /* maybe_begin. */ 914 { 915 label_name = (char *) xmalloc ((c - c1) + strlen ("__BEGIN") + 1); 916 label_name[0] = 0; 917 strncat (label_name, c1, c-c1); 918 strcat (label_name, "__BEGIN"); 919 } 920 921 line_label = colon (label_name); 922 923 /* Loop_End follows the last instruction in the loop. 924 Adjust label address. */ 925 if (maybe_end) 926 line_label->sy_value.X_add_number -= last_insn_size; 927 928 } 929 930 /* Special extra functions that help bfin-parse.y perform its job. */ 931 932 #include <stdio.h> 933 #include <assert.h> 934 #include <obstack.h> 935 #include <bfd.h> 936 #include "bfin-defs.h" 937 938 struct obstack mempool; 939 940 INSTR_T 941 conscode (INSTR_T head, INSTR_T tail) 942 { 943 if (!head) 944 return tail; 945 head->next = tail; 946 return head; 947 } 948 949 INSTR_T 950 conctcode (INSTR_T head, INSTR_T tail) 951 { 952 INSTR_T temp = (head); 953 if (!head) 954 return tail; 955 while (temp->next) 956 temp = temp->next; 957 temp->next = tail; 958 959 return head; 960 } 961 962 INSTR_T 963 note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel) 964 { 965 /* Assert that the symbol is not an operator. */ 966 assert (symbol->type == Expr_Node_Reloc); 967 968 return note_reloc1 (code, symbol->value.s_value, reloc, pcrel); 969 970 } 971 972 INSTR_T 973 note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel) 974 { 975 code->reloc = reloc; 976 code->exp = mkexpr (0, symbol_find_or_make (symbol)); 977 code->pcrel = pcrel; 978 return code; 979 } 980 981 INSTR_T 982 note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel) 983 { 984 code->reloc = reloc; 985 code->exp = mkexpr (value, symbol_find_or_make (symbol)); 986 code->pcrel = pcrel; 987 return code; 988 } 989 990 INSTR_T 991 gencode (unsigned long x) 992 { 993 INSTR_T cell = (INSTR_T) obstack_alloc (&mempool, sizeof (struct bfin_insn)); 994 memset (cell, 0, sizeof (struct bfin_insn)); 995 cell->value = (x); 996 return cell; 997 } 998 999 int reloc; 1000 int ninsns; 1001 int count_insns; 1002 1003 static void * 1004 allocate (int n) 1005 { 1006 return (void *) obstack_alloc (&mempool, n); 1007 } 1008 1009 Expr_Node * 1010 Expr_Node_Create (Expr_Node_Type type, 1011 Expr_Node_Value value, 1012 Expr_Node *Left_Child, 1013 Expr_Node *Right_Child) 1014 { 1015 1016 1017 Expr_Node *node = (Expr_Node *) allocate (sizeof (Expr_Node)); 1018 node->type = type; 1019 node->value = value; 1020 node->Left_Child = Left_Child; 1021 node->Right_Child = Right_Child; 1022 return node; 1023 } 1024 1025 static const char *con = ".__constant"; 1026 static const char *op = ".__operator"; 1027 static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head); 1028 INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc); 1029 1030 INSTR_T 1031 Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc) 1032 { 1033 /* Top level reloction expression generator VDSP style. 1034 If the relocation is just by itself, generate one item 1035 else generate this convoluted expression. */ 1036 1037 INSTR_T note = NULL_CODE; 1038 INSTR_T note1 = NULL_CODE; 1039 int pcrel = 1; /* Is the parent reloc pcrelative? 1040 This calculation here and HOWTO should match. */ 1041 1042 if (parent_reloc) 1043 { 1044 /* If it's 32 bit quantity then 16bit code needs to be added. */ 1045 int value = 0; 1046 1047 if (head->type == Expr_Node_Constant) 1048 { 1049 /* If note1 is not null code, we have to generate a right 1050 aligned value for the constant. Otherwise the reloc is 1051 a part of the basic command and the yacc file 1052 generates this. */ 1053 value = head->value.i_value; 1054 } 1055 switch (parent_reloc) 1056 { 1057 /* Some reloctions will need to allocate extra words. */ 1058 case BFD_RELOC_BFIN_16_IMM: 1059 case BFD_RELOC_BFIN_16_LOW: 1060 case BFD_RELOC_BFIN_16_HIGH: 1061 note1 = conscode (gencode (value), NULL_CODE); 1062 pcrel = 0; 1063 break; 1064 case BFD_RELOC_BFIN_PLTPC: 1065 note1 = conscode (gencode (value), NULL_CODE); 1066 pcrel = 0; 1067 break; 1068 case BFD_RELOC_16: 1069 case BFD_RELOC_BFIN_GOT: 1070 case BFD_RELOC_BFIN_GOT17M4: 1071 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4: 1072 note1 = conscode (gencode (value), NULL_CODE); 1073 pcrel = 0; 1074 break; 1075 case BFD_RELOC_24_PCREL: 1076 case BFD_RELOC_BFIN_24_PCREL_JUMP_L: 1077 case BFD_RELOC_BFIN_24_PCREL_CALL_X: 1078 /* These offsets are even numbered pcrel. */ 1079 note1 = conscode (gencode (value >> 1), NULL_CODE); 1080 break; 1081 default: 1082 note1 = NULL_CODE; 1083 } 1084 } 1085 if (head->type == Expr_Node_Constant) 1086 note = note1; 1087 else if (head->type == Expr_Node_Reloc) 1088 { 1089 note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel); 1090 if (note1 != NULL_CODE) 1091 note = conscode (note1, note); 1092 } 1093 else if (head->type == Expr_Node_Binop 1094 && (head->value.op_value == Expr_Op_Type_Add 1095 || head->value.op_value == Expr_Op_Type_Sub) 1096 && head->Left_Child->type == Expr_Node_Reloc 1097 && head->Right_Child->type == Expr_Node_Constant) 1098 { 1099 int val = head->Right_Child->value.i_value; 1100 if (head->value.op_value == Expr_Op_Type_Sub) 1101 val = -val; 1102 note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value, 1103 parent_reloc, val, 0), 1104 NULL_CODE); 1105 if (note1 != NULL_CODE) 1106 note = conscode (note1, note); 1107 } 1108 else 1109 { 1110 /* Call the recursive function. */ 1111 note = note_reloc1 (gencode (0), op, parent_reloc, pcrel); 1112 if (note1 != NULL_CODE) 1113 note = conscode (note1, note); 1114 note = conctcode (Expr_Node_Gen_Reloc_R (head), note); 1115 } 1116 return note; 1117 } 1118 1119 static INSTR_T 1120 Expr_Node_Gen_Reloc_R (Expr_Node * head) 1121 { 1122 1123 INSTR_T note = 0; 1124 INSTR_T note1 = 0; 1125 1126 switch (head->type) 1127 { 1128 case Expr_Node_Constant: 1129 note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE); 1130 break; 1131 case Expr_Node_Reloc: 1132 note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE); 1133 break; 1134 case Expr_Node_Binop: 1135 note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child)); 1136 switch (head->value.op_value) 1137 { 1138 case Expr_Op_Type_Add: 1139 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE)); 1140 break; 1141 case Expr_Op_Type_Sub: 1142 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE)); 1143 break; 1144 case Expr_Op_Type_Mult: 1145 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE)); 1146 break; 1147 case Expr_Op_Type_Div: 1148 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE)); 1149 break; 1150 case Expr_Op_Type_Mod: 1151 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE)); 1152 break; 1153 case Expr_Op_Type_Lshift: 1154 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE)); 1155 break; 1156 case Expr_Op_Type_Rshift: 1157 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE)); 1158 break; 1159 case Expr_Op_Type_BAND: 1160 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE)); 1161 break; 1162 case Expr_Op_Type_BOR: 1163 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE)); 1164 break; 1165 case Expr_Op_Type_BXOR: 1166 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE)); 1167 break; 1168 case Expr_Op_Type_LAND: 1169 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE)); 1170 break; 1171 case Expr_Op_Type_LOR: 1172 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE)); 1173 break; 1174 default: 1175 fprintf (stderr, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__, __LINE__); 1176 1177 1178 } 1179 break; 1180 case Expr_Node_Unop: 1181 note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE); 1182 switch (head->value.op_value) 1183 { 1184 case Expr_Op_Type_NEG: 1185 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE)); 1186 break; 1187 case Expr_Op_Type_COMP: 1188 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE)); 1189 break; 1190 default: 1191 fprintf (stderr, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__, __LINE__); 1192 } 1193 break; 1194 default: 1195 fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__); 1196 } 1197 return note; 1198 } 1199 1200 1201 /* Blackfin opcode generation. */ 1202 1203 /* These functions are called by the generated parser 1204 (from bfin-parse.y), the register type classification 1205 happens in bfin-lex.l. */ 1206 1207 #include "bfin-aux.h" 1208 #include "opcode/bfin.h" 1209 1210 #define INIT(t) t c_code = init_##t 1211 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x) 1212 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x) 1213 1214 #define HI(x) ((x >> 16) & 0xffff) 1215 #define LO(x) ((x ) & 0xffff) 1216 1217 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4) 1218 1219 #define GEN_OPCODE32() \ 1220 conscode (gencode (HI (c_code.opcode)), \ 1221 conscode (gencode (LO (c_code.opcode)), NULL_CODE)) 1222 1223 #define GEN_OPCODE16() \ 1224 conscode (gencode (c_code.opcode), NULL_CODE) 1225 1226 1227 /* 32 BIT INSTRUCTIONS. */ 1228 1229 1230 /* DSP32 instruction generation. */ 1231 1232 INSTR_T 1233 bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P, 1234 int h01, int h11, int h00, int h10, int op0, 1235 REG_T dst, REG_T src0, REG_T src1, int w0) 1236 { 1237 INIT (DSP32Mac); 1238 1239 ASSIGN (op0); 1240 ASSIGN (op1); 1241 ASSIGN (MM); 1242 ASSIGN (mmod); 1243 ASSIGN (w0); 1244 ASSIGN (w1); 1245 ASSIGN (h01); 1246 ASSIGN (h11); 1247 ASSIGN (h00); 1248 ASSIGN (h10); 1249 ASSIGN (P); 1250 1251 /* If we have full reg assignments, mask out LSB to encode 1252 single or simultaneous even/odd register moves. */ 1253 if (P) 1254 { 1255 dst->regno &= 0x06; 1256 } 1257 1258 ASSIGN_R (dst); 1259 ASSIGN_R (src0); 1260 ASSIGN_R (src1); 1261 1262 return GEN_OPCODE32 (); 1263 } 1264 1265 INSTR_T 1266 bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P, 1267 int h01, int h11, int h00, int h10, int op0, 1268 REG_T dst, REG_T src0, REG_T src1, int w0) 1269 { 1270 INIT (DSP32Mult); 1271 1272 ASSIGN (op0); 1273 ASSIGN (op1); 1274 ASSIGN (MM); 1275 ASSIGN (mmod); 1276 ASSIGN (w0); 1277 ASSIGN (w1); 1278 ASSIGN (h01); 1279 ASSIGN (h11); 1280 ASSIGN (h00); 1281 ASSIGN (h10); 1282 ASSIGN (P); 1283 1284 if (P) 1285 { 1286 dst->regno &= 0x06; 1287 } 1288 1289 ASSIGN_R (dst); 1290 ASSIGN_R (src0); 1291 ASSIGN_R (src1); 1292 1293 return GEN_OPCODE32 (); 1294 } 1295 1296 INSTR_T 1297 bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x, 1298 REG_T dst0, REG_T dst1, REG_T src0, REG_T src1) 1299 { 1300 INIT (DSP32Alu); 1301 1302 ASSIGN (HL); 1303 ASSIGN (aopcde); 1304 ASSIGN (aop); 1305 ASSIGN (s); 1306 ASSIGN (x); 1307 ASSIGN_R (dst0); 1308 ASSIGN_R (dst1); 1309 ASSIGN_R (src0); 1310 ASSIGN_R (src1); 1311 1312 return GEN_OPCODE32 (); 1313 } 1314 1315 INSTR_T 1316 bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0, 1317 REG_T src1, int sop, int HLs) 1318 { 1319 INIT (DSP32Shift); 1320 1321 ASSIGN (sopcde); 1322 ASSIGN (sop); 1323 ASSIGN (HLs); 1324 1325 ASSIGN_R (dst0); 1326 ASSIGN_R (src0); 1327 ASSIGN_R (src1); 1328 1329 return GEN_OPCODE32 (); 1330 } 1331 1332 INSTR_T 1333 bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag, 1334 REG_T src1, int sop, int HLs) 1335 { 1336 INIT (DSP32ShiftImm); 1337 1338 ASSIGN (sopcde); 1339 ASSIGN (sop); 1340 ASSIGN (HLs); 1341 1342 ASSIGN_R (dst0); 1343 ASSIGN (immag); 1344 ASSIGN_R (src1); 1345 1346 return GEN_OPCODE32 (); 1347 } 1348 1349 /* LOOP SETUP. */ 1350 1351 INSTR_T 1352 bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop, 1353 Expr_Node * peoffset, REG_T reg) 1354 { 1355 int soffset, eoffset; 1356 INIT (LoopSetup); 1357 1358 soffset = (EXPR_VALUE (psoffset) >> 1); 1359 ASSIGN (soffset); 1360 eoffset = (EXPR_VALUE (peoffset) >> 1); 1361 ASSIGN (eoffset); 1362 ASSIGN (rop); 1363 ASSIGN_R (c); 1364 ASSIGN_R (reg); 1365 1366 return 1367 conscode (gencode (HI (c_code.opcode)), 1368 conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL), 1369 conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL)))); 1370 1371 } 1372 1373 /* Call, Link. */ 1374 1375 INSTR_T 1376 bfin_gen_calla (Expr_Node * addr, int S) 1377 { 1378 int val; 1379 int high_val; 1380 int reloc = 0; 1381 INIT (CALLa); 1382 1383 switch(S){ 1384 case 0 : reloc = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break; 1385 case 1 : reloc = BFD_RELOC_24_PCREL; break; 1386 case 2 : reloc = BFD_RELOC_BFIN_PLTPC; break; 1387 default : break; 1388 } 1389 1390 ASSIGN (S); 1391 1392 val = EXPR_VALUE (addr) >> 1; 1393 high_val = val >> 16; 1394 1395 return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)), 1396 Expr_Node_Gen_Reloc (addr, reloc)); 1397 } 1398 1399 INSTR_T 1400 bfin_gen_linkage (int R, int framesize) 1401 { 1402 INIT (Linkage); 1403 1404 ASSIGN (R); 1405 ASSIGN (framesize); 1406 1407 return GEN_OPCODE32 (); 1408 } 1409 1410 1411 /* Load and Store. */ 1412 1413 INSTR_T 1414 bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int reloc) 1415 { 1416 int grp, hword; 1417 unsigned val = EXPR_VALUE (phword); 1418 INIT (LDIMMhalf); 1419 1420 ASSIGN (H); 1421 ASSIGN (S); 1422 ASSIGN (Z); 1423 1424 ASSIGN_R (reg); 1425 grp = (GROUP (reg)); 1426 ASSIGN (grp); 1427 if (reloc == 2) 1428 { 1429 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM)); 1430 } 1431 else if (reloc == 1) 1432 { 1433 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, IS_H (*reg) ? BFD_RELOC_BFIN_16_HIGH : BFD_RELOC_BFIN_16_LOW)); 1434 } 1435 else 1436 { 1437 hword = val; 1438 ASSIGN (hword); 1439 } 1440 return GEN_OPCODE32 (); 1441 } 1442 1443 INSTR_T 1444 bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset) 1445 { 1446 INIT (LDSTidxI); 1447 1448 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z)) 1449 { 1450 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n"); 1451 return 0; 1452 } 1453 1454 ASSIGN_R (ptr); 1455 ASSIGN_R (reg); 1456 ASSIGN (W); 1457 ASSIGN (sz); 1458 1459 ASSIGN (Z); 1460 1461 if (poffset->type != Expr_Node_Constant) 1462 { 1463 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */ 1464 /* distinguish between R0 = [P5 + symbol@GOT] and 1465 P5 = [P5 + _current_shared_library_p5_offset_] 1466 */ 1467 if (poffset->type == Expr_Node_Reloc 1468 && !strcmp (poffset->value.s_value, 1469 "_current_shared_library_p5_offset_")) 1470 { 1471 return conscode (gencode (HI (c_code.opcode)), 1472 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16)); 1473 } 1474 else if (poffset->type != Expr_Node_GOT_Reloc) 1475 abort (); 1476 1477 return conscode (gencode (HI (c_code.opcode)), 1478 Expr_Node_Gen_Reloc(poffset->Left_Child, 1479 poffset->value.i_value)); 1480 } 1481 else 1482 { 1483 int value, offset; 1484 switch (sz) 1485 { // load/store access size 1486 case 0: // 32 bit 1487 value = EXPR_VALUE (poffset) >> 2; 1488 break; 1489 case 1: // 16 bit 1490 value = EXPR_VALUE (poffset) >> 1; 1491 break; 1492 case 2: // 8 bit 1493 value = EXPR_VALUE (poffset); 1494 break; 1495 default: 1496 abort (); 1497 } 1498 1499 offset = (value & 0xffff); 1500 ASSIGN (offset); 1501 return GEN_OPCODE32 (); 1502 } 1503 } 1504 1505 1506 INSTR_T 1507 bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W) 1508 { 1509 INIT (LDST); 1510 1511 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z)) 1512 { 1513 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n"); 1514 return 0; 1515 } 1516 1517 ASSIGN_R (ptr); 1518 ASSIGN_R (reg); 1519 ASSIGN (aop); 1520 ASSIGN (sz); 1521 ASSIGN (Z); 1522 ASSIGN (W); 1523 1524 return GEN_OPCODE16 (); 1525 } 1526 1527 INSTR_T 1528 bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int op) 1529 { 1530 int offset; 1531 int value = 0; 1532 INIT (LDSTii); 1533 1534 1535 if (!IS_PREG (*ptr)) 1536 { 1537 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n"); 1538 return 0; 1539 } 1540 1541 switch (op) 1542 { 1543 case 1: 1544 case 2: 1545 value = EXPR_VALUE (poffset) >> 1; 1546 break; 1547 case 0: 1548 case 3: 1549 value = EXPR_VALUE (poffset) >> 2; 1550 break; 1551 } 1552 1553 ASSIGN_R (ptr); 1554 ASSIGN_R (reg); 1555 1556 offset = value; 1557 ASSIGN (offset); 1558 ASSIGN (W); 1559 ASSIGN (op); 1560 1561 return GEN_OPCODE16 (); 1562 } 1563 1564 INSTR_T 1565 bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W) 1566 { 1567 /* Set bit 4 if it's a Preg. */ 1568 int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0); 1569 int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1; 1570 INIT (LDSTiiFP); 1571 ASSIGN (reg); 1572 ASSIGN (offset); 1573 ASSIGN (W); 1574 1575 return GEN_OPCODE16 (); 1576 } 1577 1578 INSTR_T 1579 bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx) 1580 { 1581 INIT (LDSTpmod); 1582 1583 ASSIGN_R (ptr); 1584 ASSIGN_R (reg); 1585 ASSIGN (aop); 1586 ASSIGN (W); 1587 ASSIGN_R (idx); 1588 1589 return GEN_OPCODE16 (); 1590 } 1591 1592 INSTR_T 1593 bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m) 1594 { 1595 INIT (DspLDST); 1596 1597 ASSIGN_R (i); 1598 ASSIGN_R (reg); 1599 ASSIGN (aop); 1600 ASSIGN (W); 1601 ASSIGN (m); 1602 1603 return GEN_OPCODE16 (); 1604 } 1605 1606 INSTR_T 1607 bfin_gen_logi2op (int opc, int src, int dst) 1608 { 1609 INIT (LOGI2op); 1610 1611 ASSIGN (opc); 1612 ASSIGN (src); 1613 ASSIGN (dst); 1614 1615 return GEN_OPCODE16 (); 1616 } 1617 1618 INSTR_T 1619 bfin_gen_brcc (int T, int B, Expr_Node * poffset) 1620 { 1621 int offset; 1622 INIT (BRCC); 1623 1624 ASSIGN (T); 1625 ASSIGN (B); 1626 offset = ((EXPR_VALUE (poffset) >> 1)); 1627 ASSIGN (offset); 1628 return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL)); 1629 } 1630 1631 INSTR_T 1632 bfin_gen_ujump (Expr_Node * poffset) 1633 { 1634 int offset; 1635 INIT (UJump); 1636 1637 offset = ((EXPR_VALUE (poffset) >> 1)); 1638 ASSIGN (offset); 1639 1640 return conscode (gencode (c_code.opcode), 1641 Expr_Node_Gen_Reloc ( 1642 poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S)); 1643 } 1644 1645 INSTR_T 1646 bfin_gen_alu2op (REG_T dst, REG_T src, int opc) 1647 { 1648 INIT (ALU2op); 1649 1650 ASSIGN_R (dst); 1651 ASSIGN_R (src); 1652 ASSIGN (opc); 1653 1654 return GEN_OPCODE16 (); 1655 } 1656 1657 INSTR_T 1658 bfin_gen_compi2opd (REG_T dst, int src, int op) 1659 { 1660 INIT (COMPI2opD); 1661 1662 ASSIGN_R (dst); 1663 ASSIGN (src); 1664 ASSIGN (op); 1665 1666 return GEN_OPCODE16 (); 1667 } 1668 1669 INSTR_T 1670 bfin_gen_compi2opp (REG_T dst, int src, int op) 1671 { 1672 INIT (COMPI2opP); 1673 1674 ASSIGN_R (dst); 1675 ASSIGN (src); 1676 ASSIGN (op); 1677 1678 return GEN_OPCODE16 (); 1679 } 1680 1681 INSTR_T 1682 bfin_gen_dagmodik (REG_T i, int op) 1683 { 1684 INIT (DagMODik); 1685 1686 ASSIGN_R (i); 1687 ASSIGN (op); 1688 1689 return GEN_OPCODE16 (); 1690 } 1691 1692 INSTR_T 1693 bfin_gen_dagmodim (REG_T i, REG_T m, int op, int br) 1694 { 1695 INIT (DagMODim); 1696 1697 ASSIGN_R (i); 1698 ASSIGN_R (m); 1699 ASSIGN (op); 1700 ASSIGN (br); 1701 1702 return GEN_OPCODE16 (); 1703 } 1704 1705 INSTR_T 1706 bfin_gen_ptr2op (REG_T dst, REG_T src, int opc) 1707 { 1708 INIT (PTR2op); 1709 1710 ASSIGN_R (dst); 1711 ASSIGN_R (src); 1712 ASSIGN (opc); 1713 1714 return GEN_OPCODE16 (); 1715 } 1716 1717 INSTR_T 1718 bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc) 1719 { 1720 INIT (COMP3op); 1721 1722 ASSIGN_R (src0); 1723 ASSIGN_R (src1); 1724 ASSIGN_R (dst); 1725 ASSIGN (opc); 1726 1727 return GEN_OPCODE16 (); 1728 } 1729 1730 INSTR_T 1731 bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G) 1732 { 1733 INIT (CCflag); 1734 1735 ASSIGN_R (x); 1736 ASSIGN (y); 1737 ASSIGN (opc); 1738 ASSIGN (I); 1739 ASSIGN (G); 1740 1741 return GEN_OPCODE16 (); 1742 } 1743 1744 INSTR_T 1745 bfin_gen_ccmv (REG_T src, REG_T dst, int T) 1746 { 1747 int s, d; 1748 INIT (CCmv); 1749 1750 ASSIGN_R (src); 1751 ASSIGN_R (dst); 1752 s = (GROUP (src)); 1753 ASSIGN (s); 1754 d = (GROUP (dst)); 1755 ASSIGN (d); 1756 ASSIGN (T); 1757 1758 return GEN_OPCODE16 (); 1759 } 1760 1761 INSTR_T 1762 bfin_gen_cc2stat (int cbit, int op, int D) 1763 { 1764 INIT (CC2stat); 1765 1766 ASSIGN (cbit); 1767 ASSIGN (op); 1768 ASSIGN (D); 1769 1770 return GEN_OPCODE16 (); 1771 } 1772 1773 INSTR_T 1774 bfin_gen_regmv (REG_T src, REG_T dst) 1775 { 1776 int gs, gd; 1777 INIT (RegMv); 1778 1779 ASSIGN_R (src); 1780 ASSIGN_R (dst); 1781 1782 gs = (GROUP (src)); 1783 ASSIGN (gs); 1784 gd = (GROUP (dst)); 1785 ASSIGN (gd); 1786 1787 return GEN_OPCODE16 (); 1788 } 1789 1790 INSTR_T 1791 bfin_gen_cc2dreg (int op, REG_T reg) 1792 { 1793 INIT (CC2dreg); 1794 1795 ASSIGN (op); 1796 ASSIGN_R (reg); 1797 1798 return GEN_OPCODE16 (); 1799 } 1800 1801 INSTR_T 1802 bfin_gen_progctrl (int prgfunc, int poprnd) 1803 { 1804 INIT (ProgCtrl); 1805 1806 ASSIGN (prgfunc); 1807 ASSIGN (poprnd); 1808 1809 return GEN_OPCODE16 (); 1810 } 1811 1812 INSTR_T 1813 bfin_gen_cactrl (REG_T reg, int a, int op) 1814 { 1815 INIT (CaCTRL); 1816 1817 ASSIGN_R (reg); 1818 ASSIGN (a); 1819 ASSIGN (op); 1820 1821 return GEN_OPCODE16 (); 1822 } 1823 1824 INSTR_T 1825 bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W) 1826 { 1827 INIT (PushPopMultiple); 1828 1829 ASSIGN (dr); 1830 ASSIGN (pr); 1831 ASSIGN (d); 1832 ASSIGN (p); 1833 ASSIGN (W); 1834 1835 return GEN_OPCODE16 (); 1836 } 1837 1838 INSTR_T 1839 bfin_gen_pushpopreg (REG_T reg, int W) 1840 { 1841 int grp; 1842 INIT (PushPopReg); 1843 1844 ASSIGN_R (reg); 1845 grp = (GROUP (reg)); 1846 ASSIGN (grp); 1847 ASSIGN (W); 1848 1849 return GEN_OPCODE16 (); 1850 } 1851 1852 /* Pseudo Debugging Support. */ 1853 1854 INSTR_T 1855 bfin_gen_pseudodbg (int fn, int reg, int grp) 1856 { 1857 INIT (PseudoDbg); 1858 1859 ASSIGN (fn); 1860 ASSIGN (reg); 1861 ASSIGN (grp); 1862 1863 return GEN_OPCODE16 (); 1864 } 1865 1866 INSTR_T 1867 bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected) 1868 { 1869 INIT (PseudoDbg_Assert); 1870 1871 ASSIGN (dbgop); 1872 ASSIGN_R (regtest); 1873 ASSIGN (expected); 1874 1875 return GEN_OPCODE32 (); 1876 } 1877 1878 /* Multiple instruction generation. */ 1879 1880 INSTR_T 1881 bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2) 1882 { 1883 INSTR_T walk; 1884 1885 /* If it's a 0, convert into MNOP. */ 1886 if (dsp32) 1887 { 1888 walk = dsp32->next; 1889 SET_MULTI_INSTRUCTION_BIT (dsp32); 1890 } 1891 else 1892 { 1893 dsp32 = gencode (0xc803); 1894 walk = gencode (0x1800); 1895 dsp32->next = walk; 1896 } 1897 1898 if (!dsp16_grp1) 1899 { 1900 dsp16_grp1 = gencode (0x0000); 1901 } 1902 1903 if (!dsp16_grp2) 1904 { 1905 dsp16_grp2 = gencode (0x0000); 1906 } 1907 1908 walk->next = dsp16_grp1; 1909 dsp16_grp1->next = dsp16_grp2; 1910 dsp16_grp2->next = NULL_CODE; 1911 1912 return dsp32; 1913 } 1914 1915 INSTR_T 1916 bfin_gen_loop (Expr_Node *expr, REG_T reg, int rop, REG_T preg) 1917 { 1918 const char *loopsym; 1919 char *lbeginsym, *lendsym; 1920 Expr_Node_Value lbeginval, lendval; 1921 Expr_Node *lbegin, *lend; 1922 1923 loopsym = expr->value.s_value; 1924 lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 1); 1925 lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 1); 1926 1927 lbeginsym[0] = 0; 1928 lendsym[0] = 0; 1929 1930 strcat (lbeginsym, loopsym); 1931 strcat (lbeginsym, "__BEGIN"); 1932 1933 strcat (lendsym, loopsym); 1934 strcat (lendsym, "__END"); 1935 1936 lbeginval.s_value = lbeginsym; 1937 lendval.s_value = lendsym; 1938 1939 lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL); 1940 lend = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL); 1941 return bfin_gen_loopsetup(lbegin, reg, rop, lend, preg); 1942 } 1943 1944 bfd_boolean 1945 bfin_eol_in_insn (char *line) 1946 { 1947 /* Allow a new-line to appear in the middle of a multi-issue instruction. */ 1948 1949 char *temp = line; 1950 1951 if (*line != '\n') 1952 return FALSE; 1953 1954 /* A semi-colon followed by a newline is always the end of a line. */ 1955 if (line[-1] == ';') 1956 return FALSE; 1957 1958 if (line[-1] == '|') 1959 return TRUE; 1960 1961 /* If the || is on the next line, there might be leading whitespace. */ 1962 temp++; 1963 while (*temp == ' ' || *temp == '\t') temp++; 1964 1965 if (*temp == '|') 1966 return TRUE; 1967 1968 return FALSE; 1969 } 1970 1971 bfd_boolean 1972 bfin_name_is_register (char *name) 1973 { 1974 int i; 1975 1976 if (*name == '[' || *name == '(') 1977 return TRUE; 1978 1979 if ((name[0] == 'W' || name[0] == 'w') && name[1] == '[') 1980 return TRUE; 1981 1982 if ((name[0] == 'B' || name[0] == 'b') && name[1] == '[') 1983 return TRUE; 1984 1985 for (i=0; bfin_reg_info[i].name != 0; i++) 1986 { 1987 if (!strcasecmp (bfin_reg_info[i].name, name)) 1988 return TRUE; 1989 } 1990 return FALSE; 1991 } 1992 1993 void 1994 bfin_equals (Expr_Node *sym) 1995 { 1996 char *c; 1997 1998 c = input_line_pointer; 1999 while (*c != '=') 2000 c--; 2001 2002 input_line_pointer = c; 2003 2004 equals ((char *) sym->value.s_value, 1); 2005 } 2006 2007 bfd_boolean 2008 bfin_start_label (char *ptr) 2009 { 2010 ptr--; 2011 while (!ISSPACE (*ptr) && !is_end_of_line[(unsigned char) *ptr]) 2012 ptr--; 2013 2014 ptr++; 2015 if (*ptr == '(' || *ptr == '[') 2016 return FALSE; 2017 2018 return TRUE; 2019 } 2020 2021 int 2022 bfin_force_relocation (struct fix *fixp) 2023 { 2024 if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW 2025 || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH) 2026 return TRUE; 2027 2028 return generic_force_reloc (fixp); 2029 } 2030