1 /* tc-tic54x.c -- Assembly code for the Texas Instruments TMS320C54X 2 Copyright (C) 1999-2014 Free Software Foundation, Inc. 3 Contributed by Timothy Wall (twall (at) cygnus.com) 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 the Free 19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 20 02110-1301, USA. */ 21 22 /* Texas Instruments TMS320C54X machine specific gas. 23 Written by Timothy Wall (twall (at) alum.mit.edu). 24 25 Valuable things to do: 26 Pipeline conflict warnings 27 We encode/decode "ld #_label, dp" differently in relocatable files 28 This means we're not compatible with TI output containing those 29 expressions. We store the upper nine bits; TI stores the lower nine 30 bits. How they recover the original upper nine bits is beyond me. 31 32 Tests to add to expect testsuite: 33 '=' and '==' with .if, .elseif, and .break 34 35 Incompatibilities (mostly trivial): 36 We don't allow ''' 37 We fill text section with zeroes instead of "nop"s 38 We don't convert '' or "" to a single instance 39 We don't convert '' to '\0' 40 We don't allow strings with .byte/.half/.short/.long 41 Probably details of the subsym stuff are different 42 TI sets labels to be data type 4 (T_INT); GAS uses T_NULL. 43 44 COFF1 limits section names to 8 characters. 45 Some of the default behavior changed from COFF1 to COFF2. */ 46 47 #include "as.h" 48 #include <limits.h> 49 #include "safe-ctype.h" 50 #include "sb.h" 51 #include "macro.h" 52 #include "subsegs.h" 53 #include "struc-symbol.h" 54 #include "opcode/tic54x.h" 55 #include "obj-coff.h" 56 #include <math.h> 57 58 59 static struct stag 60 { 61 symbolS *sym; /* Symbol for this stag; value is offset. */ 62 const char *name; /* Shortcut to symbol name. */ 63 bfd_vma size; /* Size of struct/union. */ 64 int current_bitfield_offset; /* Temporary for tracking fields. */ 65 int is_union; 66 struct stag_field /* List of fields. */ 67 { 68 const char *name; 69 bfd_vma offset; /* Of start of this field. */ 70 int bitfield_offset; /* Of start of this field. */ 71 struct stag *stag; /* If field is struct/union. */ 72 struct stag_field *next; 73 } *field; 74 /* For nesting; used only in stag construction. */ 75 struct stag *inner; /* Enclosed .struct. */ 76 struct stag *outer; /* Enclosing .struct. */ 77 } *current_stag = NULL; 78 79 #define MAX_LINE 256 /* Lines longer than this are truncated by TI's asm. */ 80 81 typedef struct _tic54x_insn 82 { 83 const insn_template *tm; /* Opcode template. */ 84 85 char mnemonic[MAX_LINE]; /* Opcode name/mnemonic. */ 86 char parmnemonic[MAX_LINE]; /* 2nd mnemonic of parallel insn. */ 87 88 int opcount; 89 struct opstruct 90 { 91 char buf[MAX_LINE]; 92 enum optype type; 93 expressionS exp; 94 } operands[MAX_OPERANDS]; 95 96 int paropcount; 97 struct opstruct paroperands[MAX_OPERANDS]; 98 99 int is_lkaddr; 100 int lkoperand; 101 int words; /* Size of insn in 16-bit words. */ 102 int using_default_dst; /* Do we need to explicitly set an 103 omitted OP_DST operand? */ 104 struct 105 { 106 unsigned short word; /* Final encoded opcode data. */ 107 int unresolved; 108 int r_nchars; /* Relocation size. */ 109 bfd_reloc_code_real_type r_type; /* Relocation type. */ 110 expressionS addr_expr; /* Storage for unresolved expressions. */ 111 } opcode[3]; 112 } tic54x_insn; 113 114 enum cpu_version 115 { 116 VNONE = 0, V541 = 1, V542 = 2, V543 = 3, V545 = 5, V548 = 8, V549 = 9, 117 V545LP = 15, V546LP = 16 118 }; 119 120 enum address_mode 121 { 122 c_mode, /* 16-bit addresses. */ 123 far_mode /* >16-bit addresses. */ 124 }; 125 126 static segT stag_saved_seg; 127 static subsegT stag_saved_subseg; 128 129 const char comment_chars[] = ";"; 130 const char line_comment_chars[] = ";*#"; /* At column zero only. */ 131 const char line_separator_chars[] = ""; /* Not permitted. */ 132 133 int emitting_long = 0; 134 135 /* Characters which indicate that this is a floating point constant. */ 136 const char FLT_CHARS[] = "fF"; 137 138 /* Characters that can be used to separate mantissa from exp in FP 139 nums. */ 140 const char EXP_CHARS[] = "eE"; 141 142 const char *md_shortopts = ""; 143 144 #define OPTION_ADDRESS_MODE (OPTION_MD_BASE) 145 #define OPTION_CPU_VERSION (OPTION_ADDRESS_MODE + 1) 146 #define OPTION_COFF_VERSION (OPTION_CPU_VERSION + 1) 147 #define OPTION_STDERR_TO_FILE (OPTION_COFF_VERSION + 1) 148 149 struct option md_longopts[] = 150 { 151 { "mfar-mode", no_argument, NULL, OPTION_ADDRESS_MODE }, 152 { "mf", no_argument, NULL, OPTION_ADDRESS_MODE }, 153 { "mcpu", required_argument, NULL, OPTION_CPU_VERSION }, 154 { "merrors-to-file", required_argument, NULL, OPTION_STDERR_TO_FILE }, 155 { "me", required_argument, NULL, OPTION_STDERR_TO_FILE }, 156 { NULL, no_argument, NULL, 0}, 157 }; 158 159 size_t md_longopts_size = sizeof (md_longopts); 160 161 static int assembly_begun = 0; 162 /* Addressing mode is not entirely implemented; the latest rev of the Other 163 assembler doesn't seem to make any distinction whatsoever; all relocations 164 are stored as extended relocatiosn. Older versions used REL16 vs RELEXT16, 165 but now it seems all relocations are RELEXT16. We use all RELEXT16. 166 167 The cpu version is kind of a waste of time as well. There is one 168 instruction (RND) for LP devices only, and several for devices with 169 extended addressing only. We include it for compatibility. */ 170 static enum address_mode amode = c_mode; 171 static enum cpu_version cpu = VNONE; 172 173 /* Include string substitutions in listing? */ 174 static int listing_sslist = 0; 175 176 /* Did we do subsym substitutions on the line? */ 177 static int substitution_line = 0; 178 179 /* Last label seen. */ 180 static symbolS *last_label_seen = NULL; 181 182 /* This ensures that all new labels are unique. */ 183 static int local_label_id; 184 185 static struct hash_control *subsym_recurse_hash; /* Prevent infinite recurse. */ 186 static struct hash_control *math_hash; /* Built-in math functions. */ 187 /* Allow maximum levels of macro nesting; level 0 is the main substitution 188 symbol table. The other assembler only does 32 levels, so there! */ 189 static struct hash_control *subsym_hash[100]; 190 191 /* Keep track of local labels so we can substitute them before GAS sees them 192 since macros use their own 'namespace' for local labels, use a separate hash 193 194 We do our own local label handling 'cuz it's subtly different from the 195 stock GAS handling. 196 197 We use our own macro nesting counter, since GAS overloads it when expanding 198 other things (like conditionals and repeat loops). */ 199 static int macro_level = 0; 200 static struct hash_control *local_label_hash[100]; 201 /* Keep track of struct/union tags. */ 202 static struct hash_control *stag_hash; 203 static struct hash_control *op_hash; 204 static struct hash_control *parop_hash; 205 static struct hash_control *reg_hash; 206 static struct hash_control *mmreg_hash; 207 static struct hash_control *cc_hash; 208 static struct hash_control *cc2_hash; 209 static struct hash_control *cc3_hash; 210 static struct hash_control *sbit_hash; 211 static struct hash_control *misc_symbol_hash; 212 213 /* Only word (et al.), align, or conditionals are allowed within 214 .struct/.union. */ 215 #define ILLEGAL_WITHIN_STRUCT() \ 216 do \ 217 if (current_stag != NULL) \ 218 { \ 219 as_bad (_("pseudo-op illegal within .struct/.union")); \ 220 return; \ 221 } \ 222 while (0) 223 224 225 static void subsym_create_or_replace (char *, char *); 226 static char *subsym_lookup (char *, int); 227 static char *subsym_substitute (char *, int); 228 229 230 void 231 md_show_usage (FILE *stream) 232 { 233 fprintf (stream, _("C54x-specific command line options:\n")); 234 fprintf (stream, _("-mfar-mode | -mf Use extended addressing\n")); 235 fprintf (stream, _("-mcpu=<CPU version> Specify the CPU version\n")); 236 fprintf (stream, _("-merrors-to-file <filename>\n")); 237 fprintf (stream, _("-me <filename> Redirect errors to a file\n")); 238 } 239 240 /* Output a single character (upper octect is zero). */ 241 242 static void 243 tic54x_emit_char (char c) 244 { 245 expressionS expn; 246 247 expn.X_op = O_constant; 248 expn.X_add_number = c; 249 emit_expr (&expn, 2); 250 } 251 252 /* Walk backwards in the frag chain. */ 253 254 static fragS * 255 frag_prev (fragS *frag, segT seg) 256 { 257 segment_info_type *seginfo = seg_info (seg); 258 fragS *fragp; 259 260 for (fragp = seginfo->frchainP->frch_root; fragp; fragp = fragp->fr_next) 261 if (fragp->fr_next == frag) 262 return fragp; 263 264 return NULL; 265 } 266 267 static fragS * 268 bit_offset_frag (fragS *frag, segT seg) 269 { 270 while (frag != NULL) 271 { 272 if (frag->fr_fix == 0 273 && frag->fr_opcode == NULL 274 && frag->tc_frag_data == 0) 275 frag = frag_prev (frag, seg); 276 else 277 return frag; 278 } 279 return NULL; 280 } 281 282 /* Return the number of bits allocated in the most recent word, or zero if 283 none. .field/.space/.bes may leave words partially allocated. */ 284 285 static int 286 frag_bit_offset (fragS *frag, segT seg) 287 { 288 frag = bit_offset_frag (frag, seg); 289 290 if (frag) 291 return frag->fr_opcode != NULL ? -1 : frag->tc_frag_data; 292 293 return 0; 294 } 295 296 /* Read an expression from a C string; returns a pointer past the end of the 297 expression. */ 298 299 static char * 300 parse_expression (char *str, expressionS *expn) 301 { 302 char *s; 303 char *tmp; 304 305 tmp = input_line_pointer; /* Save line pointer. */ 306 input_line_pointer = str; 307 expression (expn); 308 s = input_line_pointer; 309 input_line_pointer = tmp; /* Restore line pointer. */ 310 return s; /* Return pointer to where parsing stopped. */ 311 } 312 313 /* .asg "character-string"|character-string, symbol 314 315 .eval is the only pseudo-op allowed to perform arithmetic on substitution 316 symbols. all other use of symbols defined with .asg are currently 317 unsupported. */ 318 319 static void 320 tic54x_asg (int x ATTRIBUTE_UNUSED) 321 { 322 int c; 323 char *name; 324 char *str; 325 char *tmp; 326 int quoted = *input_line_pointer == '"'; 327 328 ILLEGAL_WITHIN_STRUCT (); 329 330 if (quoted) 331 { 332 int len; 333 str = demand_copy_C_string (&len); 334 c = *input_line_pointer; 335 } 336 else 337 { 338 str = input_line_pointer; 339 while ((c = *input_line_pointer) != ',') 340 { 341 if (is_end_of_line[(int) *input_line_pointer]) 342 break; 343 ++input_line_pointer; 344 } 345 *input_line_pointer = 0; 346 } 347 if (c != ',') 348 { 349 as_bad (_("Comma and symbol expected for '.asg STRING, SYMBOL'")); 350 ignore_rest_of_line (); 351 return; 352 } 353 354 name = ++input_line_pointer; 355 c = get_symbol_end (); /* Get terminator. */ 356 if (!ISALPHA (*name)) 357 { 358 as_bad (_("symbols assigned with .asg must begin with a letter")); 359 ignore_rest_of_line (); 360 return; 361 } 362 363 tmp = xmalloc (strlen (str) + 1); 364 strcpy (tmp, str); 365 str = tmp; 366 tmp = xmalloc (strlen (name) + 1); 367 strcpy (tmp, name); 368 name = tmp; 369 subsym_create_or_replace (name, str); 370 *input_line_pointer = c; 371 demand_empty_rest_of_line (); 372 } 373 374 /* .eval expression, symbol 375 There's something screwy about this. The other assembler sometimes does and 376 sometimes doesn't substitute symbols defined with .eval. 377 We'll put the symbols into the subsym table as well as the normal symbol 378 table, since that's what works best. */ 379 380 static void 381 tic54x_eval (int x ATTRIBUTE_UNUSED) 382 { 383 char c; 384 int value; 385 char *name; 386 symbolS *symbolP; 387 char valuestr[32], *tmp; 388 int quoted; 389 390 ILLEGAL_WITHIN_STRUCT (); 391 392 SKIP_WHITESPACE (); 393 394 quoted = *input_line_pointer == '"'; 395 if (quoted) 396 ++input_line_pointer; 397 value = get_absolute_expression (); 398 if (quoted) 399 { 400 if (*input_line_pointer != '"') 401 { 402 as_bad (_("Unterminated string after absolute expression")); 403 ignore_rest_of_line (); 404 return; 405 } 406 ++input_line_pointer; 407 } 408 if (*input_line_pointer++ != ',') 409 { 410 as_bad (_("Comma and symbol expected for '.eval EXPR, SYMBOL'")); 411 ignore_rest_of_line (); 412 return; 413 } 414 name = input_line_pointer; 415 c = get_symbol_end (); /* Get terminator. */ 416 tmp = xmalloc (strlen (name) + 1); 417 name = strcpy (tmp, name); 418 *input_line_pointer = c; 419 420 if (!ISALPHA (*name)) 421 { 422 as_bad (_("symbols assigned with .eval must begin with a letter")); 423 ignore_rest_of_line (); 424 return; 425 } 426 symbolP = symbol_new (name, absolute_section, 427 (valueT) value, &zero_address_frag); 428 SF_SET_LOCAL (symbolP); 429 symbol_table_insert (symbolP); 430 431 /* The "other" assembler sometimes doesn't put .eval's in the subsym table 432 But since there's not written rule as to when, don't even bother trying 433 to match their behavior. */ 434 sprintf (valuestr, "%d", value); 435 tmp = xmalloc (strlen (valuestr) + 1); 436 strcpy (tmp, valuestr); 437 subsym_create_or_replace (name, tmp); 438 439 demand_empty_rest_of_line (); 440 } 441 442 /* .bss symbol, size [, [blocking flag] [, alignment flag] 443 444 alignment is to a longword boundary; blocking is to 128-word boundary. 445 446 1) if there is a hole in memory, this directive should attempt to fill it 447 (not yet implemented). 448 449 2) if the blocking flag is not set, allocate at the current SPC 450 otherwise, check to see if the current SPC plus the space to be 451 allocated crosses the page boundary (128 words). 452 if there's not enough space, create a hole and align with the next page 453 boundary. 454 (not yet implemented). */ 455 456 static void 457 tic54x_bss (int x ATTRIBUTE_UNUSED) 458 { 459 char c; 460 char *name; 461 char *p; 462 int words; 463 segT current_seg; 464 subsegT current_subseg; 465 symbolS *symbolP; 466 int block = 0; 467 int align = 0; 468 469 ILLEGAL_WITHIN_STRUCT (); 470 471 current_seg = now_seg; /* Save current seg. */ 472 current_subseg = now_subseg; /* Save current subseg. */ 473 474 name = input_line_pointer; 475 c = get_symbol_end (); /* Get terminator. */ 476 if (c != ',') 477 { 478 as_bad (_(".bss size argument missing\n")); 479 ignore_rest_of_line (); 480 return; 481 } 482 483 ++input_line_pointer; 484 words = get_absolute_expression (); 485 if (words < 0) 486 { 487 as_bad (_(".bss size %d < 0!"), words); 488 ignore_rest_of_line (); 489 return; 490 } 491 492 if (*input_line_pointer == ',') 493 { 494 /* The blocking flag may be missing. */ 495 ++input_line_pointer; 496 if (*input_line_pointer != ',') 497 block = get_absolute_expression (); 498 else 499 block = 0; 500 501 if (*input_line_pointer == ',') 502 { 503 ++input_line_pointer; 504 align = get_absolute_expression (); 505 } 506 else 507 align = 0; 508 } 509 else 510 block = align = 0; 511 512 subseg_set (bss_section, 0); 513 symbolP = symbol_find_or_make (name); 514 515 if (S_GET_SEGMENT (symbolP) == bss_section) 516 symbolP->sy_frag->fr_symbol = (symbolS *) NULL; 517 518 symbol_set_frag (symbolP, frag_now); 519 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, 520 (offsetT) (words * OCTETS_PER_BYTE), (char *) 0); 521 *p = 0; /* Fill char. */ 522 523 S_SET_SEGMENT (symbolP, bss_section); 524 525 /* The symbol may already have been created with a preceding 526 ".globl" directive -- be careful not to step on storage class 527 in that case. Otherwise, set it to static. */ 528 if (S_GET_STORAGE_CLASS (symbolP) != C_EXT) 529 S_SET_STORAGE_CLASS (symbolP, C_STAT); 530 531 if (align) 532 { 533 /* s_align eats end of line; restore it */ 534 s_align_bytes (4); 535 --input_line_pointer; 536 } 537 538 if (block) 539 bss_section->flags |= SEC_TIC54X_BLOCK; 540 541 subseg_set (current_seg, current_subseg); /* Restore current seg. */ 542 demand_empty_rest_of_line (); 543 } 544 545 static void 546 stag_add_field_symbols (struct stag *stag, 547 const char *path, 548 bfd_vma base_offset, 549 symbolS *rootsym, 550 const char *root_stag_name) 551 { 552 char prefix[strlen (path) + 2]; 553 struct stag_field *field = stag->field; 554 555 /* Construct a symbol for every field contained within this structure 556 including fields within structure fields. */ 557 strcpy (prefix, path); 558 if (*path) 559 strcat (prefix, "."); 560 561 while (field != NULL) 562 { 563 int len = strlen (prefix) + strlen (field->name) + 2; 564 char *name = xmalloc (len); 565 strcpy (name, prefix); 566 strcat (name, field->name); 567 568 if (rootsym == NULL) 569 { 570 symbolS *sym; 571 sym = symbol_new (name, absolute_section, 572 (field->stag ? field->offset : 573 (valueT) (base_offset + field->offset)), 574 &zero_address_frag); 575 SF_SET_LOCAL (sym); 576 symbol_table_insert (sym); 577 } 578 else 579 { 580 char *replacement = xmalloc (strlen (name) 581 + strlen (stag->name) + 2); 582 strcpy (replacement, S_GET_NAME (rootsym)); 583 strcat (replacement, "+"); 584 strcat (replacement, root_stag_name); 585 strcat (replacement, name + strlen (S_GET_NAME (rootsym))); 586 hash_insert (subsym_hash[0], name, replacement); 587 } 588 589 /* Recurse if the field is a structure. 590 Note the field offset is relative to the outermost struct. */ 591 if (field->stag != NULL) 592 stag_add_field_symbols (field->stag, name, 593 field->offset, 594 rootsym, root_stag_name); 595 field = field->next; 596 } 597 } 598 599 /* Keep track of stag fields so that when structures are nested we can add the 600 complete dereferencing symbols to the symbol table. */ 601 602 static void 603 stag_add_field (struct stag *parent, 604 const char *name, 605 bfd_vma offset, 606 struct stag *stag) 607 { 608 struct stag_field *sfield = xmalloc (sizeof (struct stag_field)); 609 610 memset (sfield, 0, sizeof (*sfield)); 611 sfield->name = strcpy (xmalloc (strlen (name) + 1), name); 612 sfield->offset = offset; 613 sfield->bitfield_offset = parent->current_bitfield_offset; 614 sfield->stag = stag; 615 if (parent->field == NULL) 616 parent->field = sfield; 617 else 618 { 619 struct stag_field *sf = parent->field; 620 while (sf->next != NULL) 621 sf = sf->next; 622 sf->next = sfield; 623 } 624 /* Only create a symbol for this field if the parent has no name. */ 625 if (!strncmp (".fake", parent->name, 5)) 626 { 627 symbolS *sym = symbol_new (name, absolute_section, 628 (valueT) offset, &zero_address_frag); 629 SF_SET_LOCAL (sym); 630 symbol_table_insert (sym); 631 } 632 } 633 634 /* [STAG] .struct [OFFSET] 635 Start defining structure offsets (symbols in absolute section). */ 636 637 static void 638 tic54x_struct (int arg) 639 { 640 int start_offset = 0; 641 int is_union = arg; 642 643 if (!current_stag) 644 { 645 /* Starting a new struct, switch to absolute section. */ 646 stag_saved_seg = now_seg; 647 stag_saved_subseg = now_subseg; 648 subseg_set (absolute_section, 0); 649 } 650 /* Align the current pointer. */ 651 else if (current_stag->current_bitfield_offset != 0) 652 { 653 ++abs_section_offset; 654 current_stag->current_bitfield_offset = 0; 655 } 656 657 /* Offset expression is only meaningful for global .structs. */ 658 if (!is_union) 659 { 660 /* Offset is ignored in inner structs. */ 661 SKIP_WHITESPACE (); 662 if (!is_end_of_line[(int) *input_line_pointer]) 663 start_offset = get_absolute_expression (); 664 else 665 start_offset = 0; 666 } 667 668 if (current_stag) 669 { 670 /* Nesting, link to outer one. */ 671 current_stag->inner = (struct stag *) xmalloc (sizeof (struct stag)); 672 memset (current_stag->inner, 0, sizeof (struct stag)); 673 current_stag->inner->outer = current_stag; 674 current_stag = current_stag->inner; 675 if (start_offset) 676 as_warn (_("Offset on nested structures is ignored")); 677 start_offset = abs_section_offset; 678 } 679 else 680 { 681 current_stag = (struct stag *) xmalloc (sizeof (struct stag)); 682 memset (current_stag, 0, sizeof (struct stag)); 683 abs_section_offset = start_offset; 684 } 685 current_stag->is_union = is_union; 686 687 if (line_label == NULL) 688 { 689 static int struct_count = 0; 690 char fake[] = ".fake_stagNNNNNNN"; 691 sprintf (fake, ".fake_stag%d", struct_count++); 692 current_stag->sym = symbol_new (fake, absolute_section, 693 (valueT) abs_section_offset, 694 &zero_address_frag); 695 } 696 else 697 { 698 char label[strlen (S_GET_NAME (line_label)) + 1]; 699 strcpy (label, S_GET_NAME (line_label)); 700 current_stag->sym = symbol_new (label, absolute_section, 701 (valueT) abs_section_offset, 702 &zero_address_frag); 703 } 704 current_stag->name = S_GET_NAME (current_stag->sym); 705 SF_SET_LOCAL (current_stag->sym); 706 /* Nested .structs don't go into the symbol table. */ 707 if (current_stag->outer == NULL) 708 symbol_table_insert (current_stag->sym); 709 710 line_label = NULL; 711 } 712 713 /* [LABEL] .endstruct 714 finish defining structure offsets; optional LABEL's value will be the size 715 of the structure. */ 716 717 static void 718 tic54x_endstruct (int is_union) 719 { 720 int size; 721 const char *path = 722 !strncmp (current_stag->name, ".fake", 5) ? "" : current_stag->name; 723 724 if (!current_stag || current_stag->is_union != is_union) 725 { 726 as_bad (_(".end%s without preceding .%s"), 727 is_union ? "union" : "struct", 728 is_union ? "union" : "struct"); 729 ignore_rest_of_line (); 730 return; 731 } 732 733 /* Align end of structures. */ 734 if (current_stag->current_bitfield_offset) 735 { 736 ++abs_section_offset; 737 current_stag->current_bitfield_offset = 0; 738 } 739 740 if (current_stag->is_union) 741 size = current_stag->size; 742 else 743 size = abs_section_offset - S_GET_VALUE (current_stag->sym); 744 if (line_label != NULL) 745 { 746 S_SET_VALUE (line_label, size); 747 symbol_table_insert (line_label); 748 line_label = NULL; 749 } 750 751 /* Union size has already been calculated. */ 752 if (!current_stag->is_union) 753 current_stag->size = size; 754 /* Nested .structs don't get put in the stag table. */ 755 if (current_stag->outer == NULL) 756 { 757 hash_insert (stag_hash, current_stag->name, current_stag); 758 stag_add_field_symbols (current_stag, path, 759 S_GET_VALUE (current_stag->sym), 760 NULL, NULL); 761 } 762 current_stag = current_stag->outer; 763 764 /* If this is a nested .struct/.union, add it as a field to the enclosing 765 one. otherwise, restore the section we were in. */ 766 if (current_stag != NULL) 767 { 768 stag_add_field (current_stag, current_stag->inner->name, 769 S_GET_VALUE (current_stag->inner->sym), 770 current_stag->inner); 771 } 772 else 773 subseg_set (stag_saved_seg, stag_saved_subseg); 774 } 775 776 /* [LABEL] .tag STAG 777 Reference a structure within a structure, as a sized field with an optional 778 label. 779 If used outside of a .struct/.endstruct, overlays the given structure 780 format on the existing allocated space. */ 781 782 static void 783 tic54x_tag (int ignore ATTRIBUTE_UNUSED) 784 { 785 char *name = input_line_pointer; 786 int c = get_symbol_end (); 787 struct stag *stag = (struct stag *) hash_find (stag_hash, name); 788 789 if (!stag) 790 { 791 if (*name) 792 as_bad (_("Unrecognized struct/union tag '%s'"), name); 793 else 794 as_bad (_(".tag requires a structure tag")); 795 ignore_rest_of_line (); 796 return; 797 } 798 if (line_label == NULL) 799 { 800 as_bad (_("Label required for .tag")); 801 ignore_rest_of_line (); 802 return; 803 } 804 else 805 { 806 char label[strlen (S_GET_NAME (line_label)) + 1]; 807 808 strcpy (label, S_GET_NAME (line_label)); 809 if (current_stag != NULL) 810 stag_add_field (current_stag, label, 811 abs_section_offset - S_GET_VALUE (current_stag->sym), 812 stag); 813 else 814 { 815 symbolS *sym = symbol_find (label); 816 817 if (!sym) 818 { 819 as_bad (_(".tag target '%s' undefined"), label); 820 ignore_rest_of_line (); 821 return; 822 } 823 stag_add_field_symbols (stag, S_GET_NAME (sym), 824 S_GET_VALUE (stag->sym), sym, stag->name); 825 } 826 } 827 828 /* Bump by the struct size, but only if we're within a .struct section. */ 829 if (current_stag != NULL && !current_stag->is_union) 830 abs_section_offset += stag->size; 831 832 *input_line_pointer = c; 833 demand_empty_rest_of_line (); 834 line_label = NULL; 835 } 836 837 /* Handle all .byte, .char, .double, .field, .float, .half, .int, .long, 838 .short, .string, .ubyte, .uchar, .uhalf, .uint, .ulong, .ushort, .uword, 839 and .word. */ 840 841 static void 842 tic54x_struct_field (int type) 843 { 844 int size; 845 int count = 1; 846 int new_bitfield_offset = 0; 847 int field_align = current_stag->current_bitfield_offset != 0; 848 int longword_align = 0; 849 850 SKIP_WHITESPACE (); 851 if (!is_end_of_line[(int) *input_line_pointer]) 852 count = get_absolute_expression (); 853 854 switch (type) 855 { 856 case 'b': 857 case 'B': 858 case 'c': 859 case 'C': 860 case 'h': 861 case 'H': 862 case 'i': 863 case 'I': 864 case 's': 865 case 'S': 866 case 'w': 867 case 'W': 868 case '*': /* String. */ 869 size = 1; 870 break; 871 case 'f': 872 case 'l': 873 case 'L': 874 longword_align = 1; 875 size = 2; 876 break; 877 case '.': /* Bitfield. */ 878 size = 0; 879 if (count < 1 || count > 32) 880 { 881 as_bad (_(".field count '%d' out of range (1 <= X <= 32)"), count); 882 ignore_rest_of_line (); 883 return; 884 } 885 if (current_stag->current_bitfield_offset + count > 16) 886 { 887 /* Set the appropriate size and new field offset. */ 888 if (count == 32) 889 { 890 size = 2; 891 count = 1; 892 } 893 else if (count > 16) 894 { 895 size = 1; 896 count = 1; 897 new_bitfield_offset = count - 16; 898 } 899 else 900 new_bitfield_offset = count; 901 } 902 else 903 { 904 field_align = 0; 905 new_bitfield_offset = current_stag->current_bitfield_offset + count; 906 } 907 break; 908 default: 909 as_bad (_("Unrecognized field type '%c'"), type); 910 ignore_rest_of_line (); 911 return; 912 } 913 914 if (field_align) 915 { 916 /* Align to the actual starting position of the field. */ 917 current_stag->current_bitfield_offset = 0; 918 ++abs_section_offset; 919 } 920 /* Align to longword boundary. */ 921 if (longword_align && (abs_section_offset & 0x1)) 922 ++abs_section_offset; 923 924 if (line_label == NULL) 925 { 926 static int fieldno = 0; 927 char fake[] = ".fake_fieldNNNNN"; 928 929 sprintf (fake, ".fake_field%d", fieldno++); 930 stag_add_field (current_stag, fake, 931 abs_section_offset - S_GET_VALUE (current_stag->sym), 932 NULL); 933 } 934 else 935 { 936 char label[strlen (S_GET_NAME (line_label) + 1)]; 937 938 strcpy (label, S_GET_NAME (line_label)); 939 stag_add_field (current_stag, label, 940 abs_section_offset - S_GET_VALUE (current_stag->sym), 941 NULL); 942 } 943 944 if (current_stag->is_union) 945 { 946 /* Note we treat the element as if it were an array of COUNT. */ 947 if (current_stag->size < (unsigned) size * count) 948 current_stag->size = size * count; 949 } 950 else 951 { 952 abs_section_offset += (unsigned) size * count; 953 current_stag->current_bitfield_offset = new_bitfield_offset; 954 } 955 line_label = NULL; 956 } 957 958 /* Handle .byte, .word. .int, .long and all variants. */ 959 960 static void 961 tic54x_cons (int type) 962 { 963 unsigned int c; 964 int octets; 965 966 /* If we're within a .struct construct, don't actually allocate space. */ 967 if (current_stag != NULL) 968 { 969 tic54x_struct_field (type); 970 return; 971 } 972 973 #ifdef md_flush_pending_output 974 md_flush_pending_output (); 975 #endif 976 977 generate_lineno_debug (); 978 979 /* Align long words to long word boundaries (4 octets). */ 980 if (type == 'l' || type == 'L') 981 { 982 frag_align (2, 0, 2); 983 /* If there's a label, assign it to the first allocated word. */ 984 if (line_label != NULL) 985 { 986 symbol_set_frag (line_label, frag_now); 987 S_SET_VALUE (line_label, frag_now_fix ()); 988 } 989 } 990 991 switch (type) 992 { 993 case 'l': 994 case 'L': 995 case 'x': 996 octets = 4; 997 break; 998 case 'b': 999 case 'B': 1000 case 'c': 1001 case 'C': 1002 octets = 1; 1003 break; 1004 default: 1005 octets = 2; 1006 break; 1007 } 1008 1009 do 1010 { 1011 if (*input_line_pointer == '"') 1012 { 1013 input_line_pointer++; 1014 while (is_a_char (c = next_char_of_string ())) 1015 tic54x_emit_char (c); 1016 know (input_line_pointer[-1] == '\"'); 1017 } 1018 else 1019 { 1020 expressionS expn; 1021 1022 input_line_pointer = parse_expression (input_line_pointer, &expn); 1023 if (expn.X_op == O_constant) 1024 { 1025 offsetT value = expn.X_add_number; 1026 /* Truncate overflows. */ 1027 switch (octets) 1028 { 1029 case 1: 1030 if ((value > 0 && value > 0xFF) 1031 || (value < 0 && value < - 0x100)) 1032 as_warn (_("Overflow in expression, truncated to 8 bits")); 1033 break; 1034 case 2: 1035 if ((value > 0 && value > 0xFFFF) 1036 || (value < 0 && value < - 0x10000)) 1037 as_warn (_("Overflow in expression, truncated to 16 bits")); 1038 break; 1039 } 1040 } 1041 if (expn.X_op != O_constant && octets < 2) 1042 { 1043 /* Disallow .byte with a non constant expression that will 1044 require relocation. */ 1045 as_bad (_("Relocatable values require at least WORD storage")); 1046 ignore_rest_of_line (); 1047 return; 1048 } 1049 1050 if (expn.X_op != O_constant 1051 && amode == c_mode 1052 && octets == 4) 1053 { 1054 /* FIXME -- at one point TI tools used to output REL16 1055 relocations, but I don't think the latest tools do at all 1056 The current tools output extended relocations regardless of 1057 the addressing mode (I actually think that ".c_mode" is 1058 totally ignored in the latest tools). */ 1059 amode = far_mode; 1060 emitting_long = 1; 1061 emit_expr (&expn, 4); 1062 emitting_long = 0; 1063 amode = c_mode; 1064 } 1065 else 1066 { 1067 emitting_long = octets == 4; 1068 emit_expr (&expn, (octets == 1) ? 2 : octets); 1069 emitting_long = 0; 1070 } 1071 } 1072 } 1073 while (*input_line_pointer++ == ','); 1074 1075 input_line_pointer--; /* Put terminator back into stream. */ 1076 demand_empty_rest_of_line (); 1077 } 1078 1079 /* .global <symbol>[,...,<symbolN>] 1080 .def <symbol>[,...,<symbolN>] 1081 .ref <symbol>[,...,<symbolN>] 1082 1083 These all identify global symbols. 1084 1085 .def means the symbol is defined in the current module and can be accessed 1086 by other files. The symbol should be placed in the symbol table. 1087 1088 .ref means the symbol is used in the current module but defined in another 1089 module. The linker is to resolve this symbol's definition at link time. 1090 1091 .global should act as a .ref or .def, as needed. 1092 1093 global, def and ref all have symbol storage classes of C_EXT. 1094 1095 I can't identify any difference in how the "other" c54x assembler treats 1096 these, so we ignore the type here. */ 1097 1098 void 1099 tic54x_global (int type) 1100 { 1101 char *name; 1102 int c; 1103 symbolS *symbolP; 1104 1105 if (type == 'r') 1106 as_warn (_("Use of .def/.ref is deprecated. Use .global instead")); 1107 1108 ILLEGAL_WITHIN_STRUCT (); 1109 1110 do 1111 { 1112 name = input_line_pointer; 1113 c = get_symbol_end (); 1114 symbolP = symbol_find_or_make (name); 1115 1116 *input_line_pointer = c; 1117 S_SET_STORAGE_CLASS (symbolP, C_EXT); 1118 if (c == ',') 1119 { 1120 input_line_pointer++; 1121 if (is_end_of_line[(int) *input_line_pointer]) 1122 c = *input_line_pointer; 1123 } 1124 } 1125 while (c == ','); 1126 1127 demand_empty_rest_of_line (); 1128 } 1129 1130 /* Remove the symbol from the local label hash lookup. */ 1131 1132 static void 1133 tic54x_remove_local_label (const char *key, void *value ATTRIBUTE_UNUSED) 1134 { 1135 void *elem = hash_delete (local_label_hash[macro_level], key, FALSE); 1136 free (elem); 1137 } 1138 1139 /* Reset all local labels. */ 1140 1141 static void 1142 tic54x_clear_local_labels (int ignored ATTRIBUTE_UNUSED) 1143 { 1144 hash_traverse (local_label_hash[macro_level], tic54x_remove_local_label); 1145 } 1146 1147 /* .text 1148 .data 1149 .sect "section name" 1150 1151 Initialized section 1152 make sure local labels get cleared when changing sections 1153 1154 ARG is 't' for text, 'd' for data, or '*' for a named section 1155 1156 For compatibility, '*' sections are SEC_CODE if instructions are 1157 encountered, or SEC_DATA if not. 1158 */ 1159 1160 static void 1161 tic54x_sect (int arg) 1162 { 1163 ILLEGAL_WITHIN_STRUCT (); 1164 1165 /* Local labels are cleared when changing sections. */ 1166 tic54x_clear_local_labels (0); 1167 1168 if (arg == 't') 1169 s_text (0); 1170 else if (arg == 'd') 1171 s_data (0); 1172 else 1173 { 1174 char *name = NULL; 1175 int len; 1176 1177 /* If there are quotes, remove them. */ 1178 if (*input_line_pointer == '"') 1179 { 1180 name = demand_copy_C_string (&len); 1181 demand_empty_rest_of_line (); 1182 name = strcpy (xmalloc (len + 10), name); 1183 } 1184 else 1185 { 1186 int c; 1187 name = input_line_pointer; 1188 c = get_symbol_end (); 1189 len = strlen(name); 1190 name = strcpy (xmalloc (len + 10), name); 1191 *input_line_pointer = c; 1192 demand_empty_rest_of_line (); 1193 } 1194 /* Make sure all named initialized sections flagged properly. If we 1195 encounter instructions, we'll flag it with SEC_CODE as well. */ 1196 strcat (name, ",\"w\"\n"); 1197 input_scrub_insert_line (name); 1198 obj_coff_section (0); 1199 1200 /* If there was a line label, make sure that it gets assigned the proper 1201 section. This is for compatibility, even though the actual behavior 1202 is not explicitly defined. For consistency, we make .sect behave 1203 like .usect, since that is probably what people expect. */ 1204 if (line_label != NULL) 1205 { 1206 S_SET_SEGMENT (line_label, now_seg); 1207 symbol_set_frag (line_label, frag_now); 1208 S_SET_VALUE (line_label, frag_now_fix ()); 1209 if (S_GET_STORAGE_CLASS (line_label) != C_EXT) 1210 S_SET_STORAGE_CLASS (line_label, C_LABEL); 1211 } 1212 } 1213 } 1214 1215 /* [symbol] .space space_in_bits 1216 [symbol] .bes space_in_bits 1217 BES puts the symbol at the *last* word allocated 1218 1219 cribbed from s_space. */ 1220 1221 static void 1222 tic54x_space (int arg) 1223 { 1224 expressionS expn; 1225 char *p = 0; 1226 int octets = 0; 1227 long words; 1228 int bits_per_byte = (OCTETS_PER_BYTE * 8); 1229 int bit_offset = 0; 1230 symbolS *label = line_label; 1231 int bes = arg; 1232 1233 ILLEGAL_WITHIN_STRUCT (); 1234 1235 #ifdef md_flush_pending_output 1236 md_flush_pending_output (); 1237 #endif 1238 1239 /* Read the bit count. */ 1240 expression (&expn); 1241 1242 /* Some expressions are unresolvable until later in the assembly pass; 1243 postpone until relaxation/fixup. we also have to postpone if a previous 1244 partial allocation has not been completed yet. */ 1245 if (expn.X_op != O_constant || frag_bit_offset (frag_now, now_seg) == -1) 1246 { 1247 struct bit_info *bi = xmalloc (sizeof (struct bit_info)); 1248 1249 bi->seg = now_seg; 1250 bi->type = bes; 1251 bi->sym = label; 1252 p = frag_var (rs_machine_dependent, 1253 65536 * 2, 1, (relax_substateT) 0, 1254 make_expr_symbol (&expn), (offsetT) 0, 1255 (char *) bi); 1256 if (p) 1257 *p = 0; 1258 1259 return; 1260 } 1261 1262 /* Reduce the required size by any bit offsets currently left over 1263 from a previous .space/.bes/.field directive. */ 1264 bit_offset = frag_now->tc_frag_data; 1265 if (bit_offset != 0 && bit_offset < 16) 1266 { 1267 int spare_bits = bits_per_byte - bit_offset; 1268 1269 if (spare_bits >= expn.X_add_number) 1270 { 1271 /* Don't have to do anything; sufficient bits have already been 1272 allocated; just point the label to the right place. */ 1273 if (label != NULL) 1274 { 1275 symbol_set_frag (label, frag_now); 1276 S_SET_VALUE (label, frag_now_fix () - 1); 1277 label = NULL; 1278 } 1279 frag_now->tc_frag_data += expn.X_add_number; 1280 goto getout; 1281 } 1282 expn.X_add_number -= spare_bits; 1283 /* Set the label to point to the first word allocated, which in this 1284 case is the previous word, which was only partially filled. */ 1285 if (!bes && label != NULL) 1286 { 1287 symbol_set_frag (label, frag_now); 1288 S_SET_VALUE (label, frag_now_fix () - 1); 1289 label = NULL; 1290 } 1291 } 1292 /* Convert bits to bytes/words and octets, rounding up. */ 1293 words = ((expn.X_add_number + bits_per_byte - 1) / bits_per_byte); 1294 /* How many do we have left over? */ 1295 bit_offset = expn.X_add_number % bits_per_byte; 1296 octets = words * OCTETS_PER_BYTE; 1297 if (octets < 0) 1298 { 1299 as_warn (_(".space/.bes repeat count is negative, ignored")); 1300 goto getout; 1301 } 1302 else if (octets == 0) 1303 { 1304 as_warn (_(".space/.bes repeat count is zero, ignored")); 1305 goto getout; 1306 } 1307 1308 /* If we are in the absolute section, just bump the offset. */ 1309 if (now_seg == absolute_section) 1310 { 1311 abs_section_offset += words; 1312 if (bes && label != NULL) 1313 S_SET_VALUE (label, abs_section_offset - 1); 1314 frag_now->tc_frag_data = bit_offset; 1315 goto getout; 1316 } 1317 1318 if (!need_pass_2) 1319 p = frag_var (rs_fill, 1, 1, 1320 (relax_substateT) 0, (symbolS *) 0, 1321 (offsetT) octets, (char *) 0); 1322 1323 /* Make note of how many bits of this word we've allocated so far. */ 1324 frag_now->tc_frag_data = bit_offset; 1325 1326 /* .bes puts label at *last* word allocated. */ 1327 if (bes && label != NULL) 1328 { 1329 symbol_set_frag (label, frag_now); 1330 S_SET_VALUE (label, frag_now_fix () - 1); 1331 } 1332 1333 if (p) 1334 *p = 0; 1335 1336 getout: 1337 1338 demand_empty_rest_of_line (); 1339 } 1340 1341 /* [symbol] .usect "section-name", size-in-words 1342 [, [blocking-flag] [, alignment-flag]] 1343 1344 Uninitialized section. 1345 Non-zero blocking means that if the section would cross a page (128-word) 1346 boundary, it will be page-aligned. 1347 Non-zero alignment aligns on a longword boundary. 1348 1349 Has no effect on the current section. */ 1350 1351 static void 1352 tic54x_usect (int x ATTRIBUTE_UNUSED) 1353 { 1354 char c; 1355 char *name; 1356 char *section_name; 1357 char *p; 1358 segT seg; 1359 int size, blocking_flag, alignment_flag; 1360 segT current_seg; 1361 subsegT current_subseg; 1362 flagword flags; 1363 1364 ILLEGAL_WITHIN_STRUCT (); 1365 1366 current_seg = now_seg; /* Save current seg. */ 1367 current_subseg = now_subseg; /* Save current subseg. */ 1368 1369 if (*input_line_pointer == '"') 1370 input_line_pointer++; 1371 section_name = input_line_pointer; 1372 c = get_symbol_end (); /* Get terminator. */ 1373 input_line_pointer++; /* Skip null symbol terminator. */ 1374 name = xmalloc (input_line_pointer - section_name + 1); 1375 strcpy (name, section_name); 1376 1377 if (*input_line_pointer == ',') 1378 ++input_line_pointer; 1379 else if (c != ',') 1380 { 1381 as_bad (_("Missing size argument")); 1382 ignore_rest_of_line (); 1383 return; 1384 } 1385 1386 size = get_absolute_expression (); 1387 1388 /* Read a possibly present third argument (blocking flag). */ 1389 if (*input_line_pointer == ',') 1390 { 1391 ++input_line_pointer; 1392 if (*input_line_pointer != ',') 1393 blocking_flag = get_absolute_expression (); 1394 else 1395 blocking_flag = 0; 1396 1397 /* Read a possibly present fourth argument (alignment flag). */ 1398 if (*input_line_pointer == ',') 1399 { 1400 ++input_line_pointer; 1401 alignment_flag = get_absolute_expression (); 1402 } 1403 else 1404 alignment_flag = 0; 1405 } 1406 else 1407 blocking_flag = alignment_flag = 0; 1408 1409 seg = subseg_new (name, 0); 1410 flags = bfd_get_section_flags (stdoutput, seg) | SEC_ALLOC; 1411 1412 if (alignment_flag) 1413 { 1414 /* s_align eats end of line; restore it. */ 1415 s_align_bytes (4); 1416 --input_line_pointer; 1417 } 1418 1419 if (line_label != NULL) 1420 { 1421 S_SET_SEGMENT (line_label, seg); 1422 symbol_set_frag (line_label, frag_now); 1423 S_SET_VALUE (line_label, frag_now_fix ()); 1424 /* Set scl to label, since that's what TI does. */ 1425 if (S_GET_STORAGE_CLASS (line_label) != C_EXT) 1426 S_SET_STORAGE_CLASS (line_label, C_LABEL); 1427 } 1428 1429 seg_info (seg)->bss = 1; /* Uninitialized data. */ 1430 1431 p = frag_var (rs_fill, 1, 1, 1432 (relax_substateT) 0, (symbolS *) line_label, 1433 size * OCTETS_PER_BYTE, (char *) 0); 1434 *p = 0; 1435 1436 if (blocking_flag) 1437 flags |= SEC_TIC54X_BLOCK; 1438 1439 if (!bfd_set_section_flags (stdoutput, seg, flags)) 1440 as_warn (_("Error setting flags for \"%s\": %s"), name, 1441 bfd_errmsg (bfd_get_error ())); 1442 1443 subseg_set (current_seg, current_subseg); /* Restore current seg. */ 1444 demand_empty_rest_of_line (); 1445 } 1446 1447 static enum cpu_version 1448 lookup_version (const char *ver) 1449 { 1450 enum cpu_version version = VNONE; 1451 1452 if (ver[0] == '5' && ver[1] == '4') 1453 { 1454 if (strlen (ver) == 3 1455 && (ver[2] == '1' || ver[2] == '2' || ver[2] == '3' 1456 || ver[2] == '5' || ver[2] == '8' || ver[2] == '9')) 1457 version = ver[2] - '0'; 1458 else if (strlen (ver) == 5 1459 && TOUPPER (ver[3]) == 'L' 1460 && TOUPPER (ver[4]) == 'P' 1461 && (ver[2] == '5' || ver[2] == '6')) 1462 version = ver[2] - '0' + 10; 1463 } 1464 1465 return version; 1466 } 1467 1468 static void 1469 set_cpu (enum cpu_version version) 1470 { 1471 cpu = version; 1472 if (version == V545LP || version == V546LP) 1473 { 1474 symbolS *symbolP = symbol_new ("__allow_lp", absolute_section, 1475 (valueT) 1, &zero_address_frag); 1476 SF_SET_LOCAL (symbolP); 1477 symbol_table_insert (symbolP); 1478 } 1479 } 1480 1481 /* .version cpu-version 1482 cpu-version may be one of the following: 1483 541 1484 542 1485 543 1486 545 1487 545LP 1488 546LP 1489 548 1490 549 1491 1492 This is for compatibility only. It currently has no affect on assembly. */ 1493 static int cpu_needs_set = 1; 1494 1495 static void 1496 tic54x_version (int x ATTRIBUTE_UNUSED) 1497 { 1498 enum cpu_version version = VNONE; 1499 enum cpu_version old_version = cpu; 1500 int c; 1501 char *ver; 1502 1503 ILLEGAL_WITHIN_STRUCT (); 1504 1505 SKIP_WHITESPACE (); 1506 ver = input_line_pointer; 1507 while (!is_end_of_line[(int) *input_line_pointer]) 1508 ++input_line_pointer; 1509 c = *input_line_pointer; 1510 *input_line_pointer = 0; 1511 1512 version = lookup_version (ver); 1513 1514 if (cpu != VNONE && cpu != version) 1515 as_warn (_("CPU version has already been set")); 1516 1517 if (version == VNONE) 1518 { 1519 as_bad (_("Unrecognized version '%s'"), ver); 1520 ignore_rest_of_line (); 1521 return; 1522 } 1523 else if (assembly_begun && version != old_version) 1524 { 1525 as_bad (_("Changing of CPU version on the fly not supported")); 1526 ignore_rest_of_line (); 1527 return; 1528 } 1529 1530 set_cpu (version); 1531 1532 *input_line_pointer = c; 1533 demand_empty_rest_of_line (); 1534 } 1535 1536 /* 'f' = float, 'x' = xfloat, 'd' = double, 'l' = ldouble. */ 1537 1538 static void 1539 tic54x_float_cons (int type) 1540 { 1541 if (current_stag != 0) 1542 tic54x_struct_field ('f'); 1543 1544 #ifdef md_flush_pending_output 1545 md_flush_pending_output (); 1546 #endif 1547 1548 /* Align to long word boundary (4 octets) unless it's ".xfloat". */ 1549 if (type != 'x') 1550 { 1551 frag_align (2, 0, 2); 1552 /* If there's a label, assign it to the first allocated word. */ 1553 if (line_label != NULL) 1554 { 1555 symbol_set_frag (line_label, frag_now); 1556 S_SET_VALUE (line_label, frag_now_fix ()); 1557 } 1558 } 1559 1560 float_cons ('f'); 1561 } 1562 1563 /* The argument is capitalized if it should be zero-terminated 1564 's' is normal string with upper 8-bits zero-filled, 'p' is packed. 1565 Code copied from stringer, and slightly modified so that strings are packed 1566 and encoded into the correct octets. */ 1567 1568 static void 1569 tic54x_stringer (int type) 1570 { 1571 unsigned int c; 1572 int append_zero = type == 'S' || type == 'P'; 1573 int packed = type == 'p' || type == 'P'; 1574 int last_char = -1; /* Packed strings need two bytes at a time to encode. */ 1575 1576 if (current_stag != NULL) 1577 { 1578 tic54x_struct_field ('*'); 1579 return; 1580 } 1581 1582 #ifdef md_flush_pending_output 1583 md_flush_pending_output (); 1584 #endif 1585 1586 c = ','; /* Do loop. */ 1587 while (c == ',') 1588 { 1589 SKIP_WHITESPACE (); 1590 switch (*input_line_pointer) 1591 { 1592 default: 1593 { 1594 unsigned short value = get_absolute_expression (); 1595 FRAG_APPEND_1_CHAR ( value & 0xFF); 1596 FRAG_APPEND_1_CHAR ((value >> 8) & 0xFF); 1597 break; 1598 } 1599 case '\"': 1600 ++input_line_pointer; /* -> 1st char of string. */ 1601 while (is_a_char (c = next_char_of_string ())) 1602 { 1603 if (!packed) 1604 { 1605 FRAG_APPEND_1_CHAR (c); 1606 FRAG_APPEND_1_CHAR (0); 1607 } 1608 else 1609 { 1610 /* Packed strings are filled MS octet first. */ 1611 if (last_char == -1) 1612 last_char = c; 1613 else 1614 { 1615 FRAG_APPEND_1_CHAR (c); 1616 FRAG_APPEND_1_CHAR (last_char); 1617 last_char = -1; 1618 } 1619 } 1620 } 1621 if (append_zero) 1622 { 1623 if (packed && last_char != -1) 1624 { 1625 FRAG_APPEND_1_CHAR (0); 1626 FRAG_APPEND_1_CHAR (last_char); 1627 last_char = -1; 1628 } 1629 else 1630 { 1631 FRAG_APPEND_1_CHAR (0); 1632 FRAG_APPEND_1_CHAR (0); 1633 } 1634 } 1635 know (input_line_pointer[-1] == '\"'); 1636 break; 1637 } 1638 SKIP_WHITESPACE (); 1639 c = *input_line_pointer; 1640 if (!is_end_of_line[c]) 1641 ++input_line_pointer; 1642 } 1643 1644 /* Finish up any leftover packed string. */ 1645 if (packed && last_char != -1) 1646 { 1647 FRAG_APPEND_1_CHAR (0); 1648 FRAG_APPEND_1_CHAR (last_char); 1649 } 1650 demand_empty_rest_of_line (); 1651 } 1652 1653 static void 1654 tic54x_p2align (int arg ATTRIBUTE_UNUSED) 1655 { 1656 as_bad (_("p2align not supported on this target")); 1657 } 1658 1659 static void 1660 tic54x_align_words (int arg) 1661 { 1662 /* Only ".align" with no argument is allowed within .struct/.union. */ 1663 int count = arg; 1664 1665 if (!is_end_of_line[(int) *input_line_pointer]) 1666 { 1667 if (arg == 2) 1668 as_warn (_("Argument to .even ignored")); 1669 else 1670 count = get_absolute_expression (); 1671 } 1672 1673 if (current_stag != NULL && arg == 128) 1674 { 1675 if (current_stag->current_bitfield_offset != 0) 1676 { 1677 current_stag->current_bitfield_offset = 0; 1678 ++abs_section_offset; 1679 } 1680 demand_empty_rest_of_line (); 1681 return; 1682 } 1683 1684 ILLEGAL_WITHIN_STRUCT (); 1685 1686 s_align_bytes (count << 1); 1687 } 1688 1689 /* Initialize multiple-bit fields withing a single word of memory. */ 1690 1691 static void 1692 tic54x_field (int ignore ATTRIBUTE_UNUSED) 1693 { 1694 expressionS expn; 1695 int size = 16; 1696 char *p; 1697 valueT value; 1698 symbolS *label = line_label; 1699 1700 if (current_stag != NULL) 1701 { 1702 tic54x_struct_field ('.'); 1703 return; 1704 } 1705 1706 input_line_pointer = parse_expression (input_line_pointer, &expn); 1707 1708 if (*input_line_pointer == ',') 1709 { 1710 ++input_line_pointer; 1711 size = get_absolute_expression (); 1712 if (size < 1 || size > 32) 1713 { 1714 as_bad (_("Invalid field size, must be from 1 to 32")); 1715 ignore_rest_of_line (); 1716 return; 1717 } 1718 } 1719 1720 /* Truncate values to the field width. */ 1721 if (expn.X_op != O_constant) 1722 { 1723 /* If the expression value is relocatable, the field size *must* 1724 be 16. */ 1725 if (size != 16) 1726 { 1727 as_bad (_("field size must be 16 when value is relocatable")); 1728 ignore_rest_of_line (); 1729 return; 1730 } 1731 1732 frag_now->tc_frag_data = 0; 1733 emit_expr (&expn, 2); 1734 } 1735 else 1736 { 1737 unsigned long fmask = (size == 32) ? 0xFFFFFFFF : (1ul << size) - 1; 1738 1739 value = expn.X_add_number; 1740 expn.X_add_number &= fmask; 1741 if (value != (valueT) expn.X_add_number) 1742 as_warn (_("field value truncated")); 1743 value = expn.X_add_number; 1744 /* Bits are stored MS first. */ 1745 while (size >= 16) 1746 { 1747 frag_now->tc_frag_data = 0; 1748 p = frag_more (2); 1749 md_number_to_chars (p, (value >> (size - 16)) & 0xFFFF, 2); 1750 size -= 16; 1751 } 1752 if (size > 0) 1753 { 1754 int bit_offset = frag_bit_offset (frag_now, now_seg); 1755 1756 fragS *alloc_frag = bit_offset_frag (frag_now, now_seg); 1757 if (bit_offset == -1) 1758 { 1759 struct bit_info *bi = xmalloc (sizeof (struct bit_info)); 1760 /* We don't know the previous offset at this time, so store the 1761 info we need and figure it out later. */ 1762 expressionS size_exp; 1763 1764 size_exp.X_op = O_constant; 1765 size_exp.X_add_number = size; 1766 bi->seg = now_seg; 1767 bi->type = TYPE_FIELD; 1768 bi->value = value; 1769 p = frag_var (rs_machine_dependent, 1770 4, 1, (relax_substateT) 0, 1771 make_expr_symbol (&size_exp), (offsetT) 0, 1772 (char *) bi); 1773 goto getout; 1774 } 1775 else if (bit_offset == 0 || bit_offset + size > 16) 1776 { 1777 /* Align a new field. */ 1778 p = frag_more (2); 1779 frag_now->tc_frag_data = 0; 1780 alloc_frag = frag_now; 1781 } 1782 else 1783 { 1784 /* Put the new value entirely within the existing one. */ 1785 p = alloc_frag == frag_now ? 1786 frag_now->fr_literal + frag_now_fix_octets () - 2 : 1787 alloc_frag->fr_literal; 1788 if (label != NULL) 1789 { 1790 symbol_set_frag (label, alloc_frag); 1791 if (alloc_frag == frag_now) 1792 S_SET_VALUE (label, frag_now_fix () - 1); 1793 label = NULL; 1794 } 1795 } 1796 value <<= 16 - alloc_frag->tc_frag_data - size; 1797 1798 /* OR in existing value. */ 1799 if (alloc_frag->tc_frag_data) 1800 value |= ((unsigned short) p[1] << 8) | p[0]; 1801 md_number_to_chars (p, value, 2); 1802 alloc_frag->tc_frag_data += size; 1803 if (alloc_frag->tc_frag_data == 16) 1804 alloc_frag->tc_frag_data = 0; 1805 } 1806 } 1807 getout: 1808 demand_empty_rest_of_line (); 1809 } 1810 1811 /* Ideally, we want to check SEC_LOAD and SEC_HAS_CONTENTS, but those aren't 1812 available yet. seg_info ()->bss is the next best thing. */ 1813 1814 static int 1815 tic54x_initialized_section (segT seg) 1816 { 1817 return !seg_info (seg)->bss; 1818 } 1819 1820 /* .clink ["section name"] 1821 1822 Marks the section as conditionally linked (link only if contents are 1823 referenced elsewhere. 1824 Without a name, refers to the current initialized section. 1825 Name is required for uninitialized sections. */ 1826 1827 static void 1828 tic54x_clink (int ignored ATTRIBUTE_UNUSED) 1829 { 1830 segT seg = now_seg; 1831 1832 ILLEGAL_WITHIN_STRUCT (); 1833 1834 if (*input_line_pointer == '\"') 1835 { 1836 char *section_name = ++input_line_pointer; 1837 char *name; 1838 1839 while (is_a_char (next_char_of_string ())) 1840 ; 1841 know (input_line_pointer[-1] == '\"'); 1842 input_line_pointer[-1] = 0; 1843 name = xmalloc (input_line_pointer - section_name + 1); 1844 strcpy (name, section_name); 1845 1846 seg = bfd_get_section_by_name (stdoutput, name); 1847 if (seg == NULL) 1848 { 1849 as_bad (_("Unrecognized section '%s'"), section_name); 1850 ignore_rest_of_line (); 1851 return; 1852 } 1853 } 1854 else 1855 { 1856 if (!tic54x_initialized_section (seg)) 1857 { 1858 as_bad (_("Current section is unitialized, " 1859 "section name required for .clink")); 1860 ignore_rest_of_line (); 1861 return; 1862 } 1863 } 1864 1865 seg->flags |= SEC_TIC54X_CLINK; 1866 1867 demand_empty_rest_of_line (); 1868 } 1869 1870 /* Change the default include directory to be the current source file's 1871 directory, instead of the current working directory. If DOT is non-zero, 1872 set to "." instead. */ 1873 1874 static void 1875 tic54x_set_default_include (int dot) 1876 { 1877 char *dir = "."; 1878 char *tmp = NULL; 1879 1880 if (!dot) 1881 { 1882 char *curfile; 1883 unsigned lineno; 1884 1885 as_where (&curfile, &lineno); 1886 dir = strcpy (xmalloc (strlen (curfile) + 1), curfile); 1887 tmp = strrchr (dir, '/'); 1888 } 1889 if (tmp != NULL) 1890 { 1891 int len; 1892 1893 *tmp = '\0'; 1894 len = strlen (dir); 1895 if (include_dir_count == 0) 1896 { 1897 include_dirs = (char **) xmalloc (sizeof (*include_dirs)); 1898 include_dir_count = 1; 1899 } 1900 include_dirs[0] = dir; 1901 if (len > include_dir_maxlen) 1902 include_dir_maxlen = len; 1903 } 1904 else if (include_dirs != NULL) 1905 include_dirs[0] = "."; 1906 } 1907 1908 /* .include "filename" | filename 1909 .copy "filename" | filename 1910 1911 FIXME 'include' file should be omitted from any output listing, 1912 'copy' should be included in any output listing 1913 FIXME -- prevent any included files from changing listing (compat only) 1914 FIXME -- need to include source file directory in search path; what's a 1915 good way to do this? 1916 1917 Entering/exiting included/copied file clears all local labels. */ 1918 1919 static void 1920 tic54x_include (int ignored ATTRIBUTE_UNUSED) 1921 { 1922 char newblock[] = " .newblock\n"; 1923 char *filename; 1924 char *input; 1925 int len, c = -1; 1926 1927 ILLEGAL_WITHIN_STRUCT (); 1928 1929 SKIP_WHITESPACE (); 1930 1931 if (*input_line_pointer == '"') 1932 { 1933 filename = demand_copy_C_string (&len); 1934 demand_empty_rest_of_line (); 1935 } 1936 else 1937 { 1938 filename = input_line_pointer; 1939 while (!is_end_of_line[(int) *input_line_pointer]) 1940 ++input_line_pointer; 1941 c = *input_line_pointer; 1942 *input_line_pointer = '\0'; 1943 filename = strcpy (xmalloc (strlen (filename) + 1), filename); 1944 *input_line_pointer = c; 1945 demand_empty_rest_of_line (); 1946 } 1947 /* Insert a partial line with the filename (for the sake of s_include) 1948 and a .newblock. 1949 The included file will be inserted before the newblock, so that the 1950 newblock is executed after the included file is processed. */ 1951 input = xmalloc (sizeof (newblock) + strlen (filename) + 4); 1952 sprintf (input, "\"%s\"\n%s", filename, newblock); 1953 input_scrub_insert_line (input); 1954 1955 tic54x_clear_local_labels (0); 1956 1957 tic54x_set_default_include (0); 1958 1959 s_include (0); 1960 } 1961 1962 static void 1963 tic54x_message (int type) 1964 { 1965 char *msg; 1966 char c; 1967 int len; 1968 1969 ILLEGAL_WITHIN_STRUCT (); 1970 1971 if (*input_line_pointer == '"') 1972 msg = demand_copy_C_string (&len); 1973 else 1974 { 1975 msg = input_line_pointer; 1976 while (!is_end_of_line[(int) *input_line_pointer]) 1977 ++input_line_pointer; 1978 c = *input_line_pointer; 1979 *input_line_pointer = 0; 1980 msg = strcpy (xmalloc (strlen (msg) + 1), msg); 1981 *input_line_pointer = c; 1982 } 1983 1984 switch (type) 1985 { 1986 case 'm': 1987 as_tsktsk ("%s", msg); 1988 break; 1989 case 'w': 1990 as_warn ("%s", msg); 1991 break; 1992 case 'e': 1993 as_bad ("%s", msg); 1994 break; 1995 } 1996 1997 demand_empty_rest_of_line (); 1998 } 1999 2000 /* .label <symbol> 2001 Define a special symbol that refers to the loadtime address rather than the 2002 runtime address within the current section. 2003 2004 This symbol gets a special storage class so that when it is resolved, it is 2005 resolved relative to the load address (lma) of the section rather than the 2006 run address (vma). */ 2007 2008 static void 2009 tic54x_label (int ignored ATTRIBUTE_UNUSED) 2010 { 2011 char *name = input_line_pointer; 2012 symbolS *symbolP; 2013 int c; 2014 2015 ILLEGAL_WITHIN_STRUCT (); 2016 2017 c = get_symbol_end (); 2018 symbolP = colon (name); 2019 S_SET_STORAGE_CLASS (symbolP, C_STATLAB); 2020 2021 *input_line_pointer = c; 2022 demand_empty_rest_of_line (); 2023 } 2024 2025 /* .mmregs 2026 Install all memory-mapped register names into the symbol table as 2027 absolute local symbols. */ 2028 2029 static void 2030 tic54x_mmregs (int ignored ATTRIBUTE_UNUSED) 2031 { 2032 symbol *sym; 2033 2034 ILLEGAL_WITHIN_STRUCT (); 2035 2036 for (sym = (symbol *) mmregs; sym->name; sym++) 2037 { 2038 symbolS *symbolP = symbol_new (sym->name, absolute_section, 2039 (valueT) sym->value, &zero_address_frag); 2040 SF_SET_LOCAL (symbolP); 2041 symbol_table_insert (symbolP); 2042 } 2043 } 2044 2045 /* .loop [count] 2046 Count defaults to 1024. */ 2047 2048 static void 2049 tic54x_loop (int count) 2050 { 2051 ILLEGAL_WITHIN_STRUCT (); 2052 2053 SKIP_WHITESPACE (); 2054 if (!is_end_of_line[(int) *input_line_pointer]) 2055 count = get_absolute_expression (); 2056 2057 do_repeat (count, "LOOP", "ENDLOOP"); 2058 } 2059 2060 /* Normally, endloop gets eaten by the preceding loop. */ 2061 2062 static void 2063 tic54x_endloop (int ignore ATTRIBUTE_UNUSED) 2064 { 2065 as_bad (_("ENDLOOP without corresponding LOOP")); 2066 ignore_rest_of_line (); 2067 } 2068 2069 /* .break [condition]. */ 2070 2071 static void 2072 tic54x_break (int ignore ATTRIBUTE_UNUSED) 2073 { 2074 int cond = 1; 2075 2076 ILLEGAL_WITHIN_STRUCT (); 2077 2078 SKIP_WHITESPACE (); 2079 if (!is_end_of_line[(int) *input_line_pointer]) 2080 cond = get_absolute_expression (); 2081 2082 if (cond) 2083 end_repeat (substitution_line ? 1 : 0); 2084 } 2085 2086 static void 2087 set_address_mode (int mode) 2088 { 2089 amode = mode; 2090 if (mode == far_mode) 2091 { 2092 symbolS *symbolP = symbol_new ("__allow_far", absolute_section, 2093 (valueT) 1, &zero_address_frag); 2094 SF_SET_LOCAL (symbolP); 2095 symbol_table_insert (symbolP); 2096 } 2097 } 2098 2099 static int address_mode_needs_set = 1; 2100 2101 static void 2102 tic54x_address_mode (int mode) 2103 { 2104 if (assembly_begun && amode != (unsigned) mode) 2105 { 2106 as_bad (_("Mixing of normal and extended addressing not supported")); 2107 ignore_rest_of_line (); 2108 return; 2109 } 2110 if (mode == far_mode && cpu != VNONE && cpu != V548 && cpu != V549) 2111 { 2112 as_bad (_("Extended addressing not supported on the specified CPU")); 2113 ignore_rest_of_line (); 2114 return; 2115 } 2116 2117 set_address_mode (mode); 2118 demand_empty_rest_of_line (); 2119 } 2120 2121 /* .sblock "section"|section [,...,"section"|section] 2122 Designate initialized sections for blocking. */ 2123 2124 static void 2125 tic54x_sblock (int ignore ATTRIBUTE_UNUSED) 2126 { 2127 int c = ','; 2128 2129 ILLEGAL_WITHIN_STRUCT (); 2130 2131 while (c == ',') 2132 { 2133 segT seg; 2134 char *name; 2135 2136 if (*input_line_pointer == '"') 2137 { 2138 int len; 2139 2140 name = demand_copy_C_string (&len); 2141 } 2142 else 2143 { 2144 char *section_name = input_line_pointer; 2145 2146 c = get_symbol_end (); 2147 name = xmalloc (strlen (section_name) + 1); 2148 strcpy (name, section_name); 2149 *input_line_pointer = c; 2150 } 2151 2152 seg = bfd_get_section_by_name (stdoutput, name); 2153 if (seg == NULL) 2154 { 2155 as_bad (_("Unrecognized section '%s'"), name); 2156 ignore_rest_of_line (); 2157 return; 2158 } 2159 else if (!tic54x_initialized_section (seg)) 2160 { 2161 as_bad (_(".sblock may be used for initialized sections only")); 2162 ignore_rest_of_line (); 2163 return; 2164 } 2165 seg->flags |= SEC_TIC54X_BLOCK; 2166 2167 c = *input_line_pointer; 2168 if (!is_end_of_line[(int) c]) 2169 ++input_line_pointer; 2170 } 2171 2172 demand_empty_rest_of_line (); 2173 } 2174 2175 /* symbol .set value 2176 symbol .equ value 2177 2178 value must be defined externals; no forward-referencing allowed 2179 symbols assigned with .set/.equ may not be redefined. */ 2180 2181 static void 2182 tic54x_set (int ignore ATTRIBUTE_UNUSED) 2183 { 2184 symbolS *symbolP; 2185 char *name; 2186 2187 ILLEGAL_WITHIN_STRUCT (); 2188 2189 if (!line_label) 2190 { 2191 as_bad (_("Symbol missing for .set/.equ")); 2192 ignore_rest_of_line (); 2193 return; 2194 } 2195 name = xstrdup (S_GET_NAME (line_label)); 2196 line_label = NULL; 2197 if ((symbolP = symbol_find (name)) == NULL 2198 && (symbolP = md_undefined_symbol (name)) == NULL) 2199 { 2200 symbolP = symbol_new (name, absolute_section, 0, &zero_address_frag); 2201 S_SET_STORAGE_CLASS (symbolP, C_STAT); 2202 } 2203 free (name); 2204 S_SET_DATA_TYPE (symbolP, T_INT); 2205 S_SET_SEGMENT (symbolP, absolute_section); 2206 symbol_table_insert (symbolP); 2207 pseudo_set (symbolP); 2208 demand_empty_rest_of_line (); 2209 } 2210 2211 /* .fclist 2212 .fcnolist 2213 List false conditional blocks. */ 2214 2215 static void 2216 tic54x_fclist (int show) 2217 { 2218 if (show) 2219 listing &= ~LISTING_NOCOND; 2220 else 2221 listing |= LISTING_NOCOND; 2222 demand_empty_rest_of_line (); 2223 } 2224 2225 static void 2226 tic54x_sslist (int show) 2227 { 2228 ILLEGAL_WITHIN_STRUCT (); 2229 2230 listing_sslist = show; 2231 } 2232 2233 /* .var SYM[,...,SYMN] 2234 Define a substitution string to be local to a macro. */ 2235 2236 static void 2237 tic54x_var (int ignore ATTRIBUTE_UNUSED) 2238 { 2239 static char empty[] = ""; 2240 char *name; 2241 int c; 2242 2243 ILLEGAL_WITHIN_STRUCT (); 2244 2245 if (macro_level == 0) 2246 { 2247 as_bad (_(".var may only be used within a macro definition")); 2248 ignore_rest_of_line (); 2249 return; 2250 } 2251 do 2252 { 2253 if (!ISALPHA (*input_line_pointer)) 2254 { 2255 as_bad (_("Substitution symbols must begin with a letter")); 2256 ignore_rest_of_line (); 2257 return; 2258 } 2259 name = input_line_pointer; 2260 c = get_symbol_end (); 2261 /* .var symbols start out with a null string. */ 2262 name = strcpy (xmalloc (strlen (name) + 1), name); 2263 hash_insert (subsym_hash[macro_level], name, empty); 2264 *input_line_pointer = c; 2265 if (c == ',') 2266 { 2267 ++input_line_pointer; 2268 if (is_end_of_line[(int) *input_line_pointer]) 2269 c = *input_line_pointer; 2270 } 2271 } 2272 while (c == ','); 2273 2274 demand_empty_rest_of_line (); 2275 } 2276 2277 /* .mlib <macro library filename> 2278 2279 Macro libraries are archived (standard AR-format) text macro definitions 2280 Expand the file and include it. 2281 2282 FIXME need to try the source file directory as well. */ 2283 2284 static void 2285 tic54x_mlib (int ignore ATTRIBUTE_UNUSED) 2286 { 2287 char *filename; 2288 char *path; 2289 int len, i; 2290 bfd *abfd, *mbfd; 2291 2292 ILLEGAL_WITHIN_STRUCT (); 2293 2294 /* Parse the filename. */ 2295 if (*input_line_pointer == '"') 2296 { 2297 if ((filename = demand_copy_C_string (&len)) == NULL) 2298 return; 2299 } 2300 else 2301 { 2302 SKIP_WHITESPACE (); 2303 len = 0; 2304 while (!is_end_of_line[(int) *input_line_pointer] 2305 && !ISSPACE (*input_line_pointer)) 2306 { 2307 obstack_1grow (¬es, *input_line_pointer); 2308 ++input_line_pointer; 2309 ++len; 2310 } 2311 obstack_1grow (¬es, '\0'); 2312 filename = obstack_finish (¬es); 2313 } 2314 demand_empty_rest_of_line (); 2315 2316 tic54x_set_default_include (0); 2317 path = xmalloc ((unsigned long) len + include_dir_maxlen + 5); 2318 2319 for (i = 0; i < include_dir_count; i++) 2320 { 2321 FILE *try; 2322 2323 strcpy (path, include_dirs[i]); 2324 strcat (path, "/"); 2325 strcat (path, filename); 2326 if ((try = fopen (path, "r")) != NULL) 2327 { 2328 fclose (try); 2329 break; 2330 } 2331 } 2332 2333 if (i >= include_dir_count) 2334 { 2335 free (path); 2336 path = filename; 2337 } 2338 2339 /* FIXME: if path is found, malloc'd storage is not freed. Of course, this 2340 happens all over the place, and since the assembler doesn't usually keep 2341 running for a very long time, it really doesn't matter. */ 2342 register_dependency (path); 2343 2344 /* Expand all archive entries to temporary files and include them. */ 2345 abfd = bfd_openr (path, NULL); 2346 if (!abfd) 2347 { 2348 as_bad (_("can't open macro library file '%s' for reading: %s"), 2349 path, bfd_errmsg (bfd_get_error ())); 2350 ignore_rest_of_line (); 2351 return; 2352 } 2353 if (!bfd_check_format (abfd, bfd_archive)) 2354 { 2355 as_bad (_("File '%s' not in macro archive format"), path); 2356 ignore_rest_of_line (); 2357 return; 2358 } 2359 2360 /* Open each BFD as binary (it should be straight ASCII text). */ 2361 for (mbfd = bfd_openr_next_archived_file (abfd, NULL); 2362 mbfd != NULL; mbfd = bfd_openr_next_archived_file (abfd, mbfd)) 2363 { 2364 /* Get a size at least as big as the archive member. */ 2365 bfd_size_type size = bfd_get_size (mbfd); 2366 char *buf = xmalloc (size); 2367 char *fname = tmpnam (NULL); 2368 FILE *ftmp; 2369 2370 /* We're not sure how big it is, but it will be smaller than "size". */ 2371 size = bfd_bread (buf, size, mbfd); 2372 2373 /* Write to a temporary file, then use s_include to include it 2374 a bit of a hack. */ 2375 ftmp = fopen (fname, "w+b"); 2376 fwrite ((void *) buf, size, 1, ftmp); 2377 if (size == 0 || buf[size - 1] != '\n') 2378 fwrite ("\n", 1, 1, ftmp); 2379 fclose (ftmp); 2380 free (buf); 2381 input_scrub_insert_file (fname); 2382 unlink (fname); 2383 } 2384 } 2385 2386 const pseudo_typeS md_pseudo_table[] = 2387 { 2388 { "algebraic", s_ignore , 0 }, 2389 { "align" , tic54x_align_words , 128 }, 2390 { "ascii" , tic54x_stringer , 'p' }, 2391 { "asciz" , tic54x_stringer , 'P' }, 2392 { "even" , tic54x_align_words , 2 }, 2393 { "asg" , tic54x_asg , 0 }, 2394 { "eval" , tic54x_eval , 0 }, 2395 { "bss" , tic54x_bss , 0 }, 2396 { "byte" , tic54x_cons , 'b' }, 2397 { "ubyte" , tic54x_cons , 'B' }, 2398 { "char" , tic54x_cons , 'c' }, 2399 { "uchar" , tic54x_cons , 'C' }, 2400 { "clink" , tic54x_clink , 0 }, 2401 { "c_mode" , tic54x_address_mode , c_mode }, 2402 { "copy" , tic54x_include , 'c' }, 2403 { "include" , tic54x_include , 'i' }, 2404 { "data" , tic54x_sect , 'd' }, 2405 { "double" , tic54x_float_cons , 'd' }, 2406 { "ldouble" , tic54x_float_cons , 'l' }, 2407 { "drlist" , s_ignore , 0 }, 2408 { "drnolist" , s_ignore , 0 }, 2409 { "emsg" , tic54x_message , 'e' }, 2410 { "mmsg" , tic54x_message , 'm' }, 2411 { "wmsg" , tic54x_message , 'w' }, 2412 { "far_mode" , tic54x_address_mode , far_mode }, 2413 { "fclist" , tic54x_fclist , 1 }, 2414 { "fcnolist" , tic54x_fclist , 0 }, 2415 { "field" , tic54x_field , -1 }, 2416 { "float" , tic54x_float_cons , 'f' }, 2417 { "xfloat" , tic54x_float_cons , 'x' }, 2418 { "global" , tic54x_global , 'g' }, 2419 { "def" , tic54x_global , 'd' }, 2420 { "ref" , tic54x_global , 'r' }, 2421 { "half" , tic54x_cons , 'h' }, 2422 { "uhalf" , tic54x_cons , 'H' }, 2423 { "short" , tic54x_cons , 's' }, 2424 { "ushort" , tic54x_cons , 'S' }, 2425 { "if" , s_if , (int) O_ne }, 2426 { "elseif" , s_elseif , (int) O_ne }, 2427 { "else" , s_else , 0 }, 2428 { "endif" , s_endif , 0 }, 2429 { "int" , tic54x_cons , 'i' }, 2430 { "uint" , tic54x_cons , 'I' }, 2431 { "word" , tic54x_cons , 'w' }, 2432 { "uword" , tic54x_cons , 'W' }, 2433 { "label" , tic54x_label , 0 }, /* Loadtime 2434 address. */ 2435 { "length" , s_ignore , 0 }, 2436 { "width" , s_ignore , 0 }, 2437 { "long" , tic54x_cons , 'l' }, 2438 { "ulong" , tic54x_cons , 'L' }, 2439 { "xlong" , tic54x_cons , 'x' }, 2440 { "loop" , tic54x_loop , 1024 }, 2441 { "break" , tic54x_break , 0 }, 2442 { "endloop" , tic54x_endloop , 0 }, 2443 { "mlib" , tic54x_mlib , 0 }, 2444 { "mlist" , s_ignore , 0 }, 2445 { "mnolist" , s_ignore , 0 }, 2446 { "mmregs" , tic54x_mmregs , 0 }, 2447 { "newblock" , tic54x_clear_local_labels, 0 }, 2448 { "option" , s_ignore , 0 }, 2449 { "p2align" , tic54x_p2align , 0 }, 2450 { "sblock" , tic54x_sblock , 0 }, 2451 { "sect" , tic54x_sect , '*' }, 2452 { "set" , tic54x_set , 0 }, 2453 { "equ" , tic54x_set , 0 }, 2454 { "space" , tic54x_space , 0 }, 2455 { "bes" , tic54x_space , 1 }, 2456 { "sslist" , tic54x_sslist , 1 }, 2457 { "ssnolist" , tic54x_sslist , 0 }, 2458 { "string" , tic54x_stringer , 's' }, 2459 { "pstring" , tic54x_stringer , 'p' }, 2460 { "struct" , tic54x_struct , 0 }, 2461 { "tag" , tic54x_tag , 0 }, 2462 { "endstruct", tic54x_endstruct , 0 }, 2463 { "tab" , s_ignore , 0 }, 2464 { "text" , tic54x_sect , 't' }, 2465 { "union" , tic54x_struct , 1 }, 2466 { "endunion" , tic54x_endstruct , 1 }, 2467 { "usect" , tic54x_usect , 0 }, 2468 { "var" , tic54x_var , 0 }, 2469 { "version" , tic54x_version , 0 }, 2470 {0 , 0 , 0 } 2471 }; 2472 2473 int 2474 md_parse_option (int c, char *arg) 2475 { 2476 switch (c) 2477 { 2478 default: 2479 return 0; 2480 case OPTION_COFF_VERSION: 2481 { 2482 int version = atoi (arg); 2483 2484 if (version != 0 && version != 1 && version != 2) 2485 as_fatal (_("Bad COFF version '%s'"), arg); 2486 /* FIXME -- not yet implemented. */ 2487 break; 2488 } 2489 case OPTION_CPU_VERSION: 2490 { 2491 cpu = lookup_version (arg); 2492 cpu_needs_set = 1; 2493 if (cpu == VNONE) 2494 as_fatal (_("Bad CPU version '%s'"), arg); 2495 break; 2496 } 2497 case OPTION_ADDRESS_MODE: 2498 amode = far_mode; 2499 address_mode_needs_set = 1; 2500 break; 2501 case OPTION_STDERR_TO_FILE: 2502 { 2503 char *filename = arg; 2504 FILE *fp = fopen (filename, "w+"); 2505 2506 if (fp == NULL) 2507 as_fatal (_("Can't redirect stderr to the file '%s'"), filename); 2508 fclose (fp); 2509 if ((fp = freopen (filename, "w+", stderr)) == NULL) 2510 as_fatal (_("Can't redirect stderr to the file '%s'"), filename); 2511 break; 2512 } 2513 } 2514 2515 return 1; 2516 } 2517 2518 /* Create a "local" substitution string hash table for a new macro level 2519 Some docs imply that macros have to use .newblock in order to be able 2520 to re-use a local label. We effectively do an automatic .newblock by 2521 deleting the local label hash between macro invocations. */ 2522 2523 void 2524 tic54x_macro_start (void) 2525 { 2526 ++macro_level; 2527 subsym_hash[macro_level] = hash_new (); 2528 local_label_hash[macro_level] = hash_new (); 2529 } 2530 2531 void 2532 tic54x_macro_info (const macro_entry *macro) 2533 { 2534 const formal_entry *entry; 2535 2536 /* Put the formal args into the substitution symbol table. */ 2537 for (entry = macro->formals; entry; entry = entry->next) 2538 { 2539 char *name = strncpy (xmalloc (entry->name.len + 1), 2540 entry->name.ptr, entry->name.len); 2541 char *value = strncpy (xmalloc (entry->actual.len + 1), 2542 entry->actual.ptr, entry->actual.len); 2543 2544 name[entry->name.len] = '\0'; 2545 value[entry->actual.len] = '\0'; 2546 hash_insert (subsym_hash[macro_level], name, value); 2547 } 2548 } 2549 2550 /* Get rid of this macro's .var's, arguments, and local labels. */ 2551 2552 void 2553 tic54x_macro_end (void) 2554 { 2555 hash_die (subsym_hash[macro_level]); 2556 subsym_hash[macro_level] = NULL; 2557 hash_die (local_label_hash[macro_level]); 2558 local_label_hash[macro_level] = NULL; 2559 --macro_level; 2560 } 2561 2562 static int 2563 subsym_symlen (char *a, char *ignore ATTRIBUTE_UNUSED) 2564 { 2565 return strlen (a); 2566 } 2567 2568 /* Compare symbol A to string B. */ 2569 2570 static int 2571 subsym_symcmp (char *a, char *b) 2572 { 2573 return strcmp (a, b); 2574 } 2575 2576 /* Return the index of the first occurrence of B in A, or zero if none 2577 assumes b is an integer char value as a string. Index is one-based. */ 2578 2579 static int 2580 subsym_firstch (char *a, char *b) 2581 { 2582 int val = atoi (b); 2583 char *tmp = strchr (a, val); 2584 2585 return tmp ? tmp - a + 1 : 0; 2586 } 2587 2588 /* Similar to firstch, but returns index of last occurrence of B in A. */ 2589 2590 static int 2591 subsym_lastch (char *a, char *b) 2592 { 2593 int val = atoi (b); 2594 char *tmp = strrchr (a, val); 2595 2596 return tmp ? tmp - a + 1 : 0; 2597 } 2598 2599 /* Returns 1 if string A is defined in the symbol table (NOT the substitution 2600 symbol table). */ 2601 2602 static int 2603 subsym_isdefed (char *a, char *ignore ATTRIBUTE_UNUSED) 2604 { 2605 symbolS *symbolP = symbol_find (a); 2606 2607 return symbolP != NULL; 2608 } 2609 2610 /* Assign first member of comma-separated list B (e.g. "1,2,3") to the symbol 2611 A, or zero if B is a null string. Both arguments *must* be substitution 2612 symbols, unsubstituted. */ 2613 2614 static int 2615 subsym_ismember (char *sym, char *list) 2616 { 2617 char *elem, *ptr, *listv; 2618 2619 if (!list) 2620 return 0; 2621 2622 listv = subsym_lookup (list, macro_level); 2623 if (!listv) 2624 { 2625 as_bad (_("Undefined substitution symbol '%s'"), list); 2626 ignore_rest_of_line (); 2627 return 0; 2628 } 2629 2630 ptr = elem = xmalloc (strlen (listv) + 1); 2631 strcpy (elem, listv); 2632 while (*ptr && *ptr != ',') 2633 ++ptr; 2634 *ptr++ = 0; 2635 2636 subsym_create_or_replace (sym, elem); 2637 2638 /* Reassign the list. */ 2639 subsym_create_or_replace (list, ptr); 2640 2641 /* Assume this value, docs aren't clear. */ 2642 return *list != 0; 2643 } 2644 2645 /* Return zero if not a constant; otherwise: 2646 1 if binary 2647 2 if octal 2648 3 if hexadecimal 2649 4 if character 2650 5 if decimal. */ 2651 2652 static int 2653 subsym_iscons (char *a, char *ignore ATTRIBUTE_UNUSED) 2654 { 2655 expressionS expn; 2656 2657 parse_expression (a, &expn); 2658 2659 if (expn.X_op == O_constant) 2660 { 2661 int len = strlen (a); 2662 2663 switch (TOUPPER (a[len - 1])) 2664 { 2665 case 'B': 2666 return 1; 2667 case 'Q': 2668 return 2; 2669 case 'H': 2670 return 3; 2671 case '\'': 2672 return 4; 2673 default: 2674 break; 2675 } 2676 /* No suffix; either octal, hex, or decimal. */ 2677 if (*a == '0' && len > 1) 2678 { 2679 if (TOUPPER (a[1]) == 'X') 2680 return 3; 2681 return 2; 2682 } 2683 return 5; 2684 } 2685 2686 return 0; 2687 } 2688 2689 /* Return 1 if A is a valid symbol name. Expects string input. */ 2690 2691 static int 2692 subsym_isname (char *a, char *ignore ATTRIBUTE_UNUSED) 2693 { 2694 if (!is_name_beginner (*a)) 2695 return 0; 2696 while (*a) 2697 { 2698 if (!is_part_of_name (*a)) 2699 return 0; 2700 ++a; 2701 } 2702 return 1; 2703 } 2704 2705 /* Return whether the string is a register; accepts ar0-7, unless .mmregs has 2706 been seen; if so, recognize any memory-mapped register. 2707 Note this does not recognize "A" or "B" accumulators. */ 2708 2709 static int 2710 subsym_isreg (char *a, char *ignore ATTRIBUTE_UNUSED) 2711 { 2712 if (hash_find (reg_hash, a)) 2713 return 1; 2714 if (hash_find (mmreg_hash, a)) 2715 return 1; 2716 return 0; 2717 } 2718 2719 /* Return the structure size, given the stag. */ 2720 2721 static int 2722 subsym_structsz (char *name, char *ignore ATTRIBUTE_UNUSED) 2723 { 2724 struct stag *stag = (struct stag *) hash_find (stag_hash, name); 2725 2726 if (stag) 2727 return stag->size; 2728 2729 return 0; 2730 } 2731 2732 /* If anybody actually uses this, they can fix it :) 2733 FIXME I'm not sure what the "reference point" of a structure is. It might 2734 be either the initial offset given .struct, or it may be the offset of the 2735 structure within another structure, or it might be something else 2736 altogether. since the TI assembler doesn't seem to ever do anything but 2737 return zero, we punt and return zero. */ 2738 2739 static int 2740 subsym_structacc (char *stag_name ATTRIBUTE_UNUSED, 2741 char *ignore ATTRIBUTE_UNUSED) 2742 { 2743 return 0; 2744 } 2745 2746 static float 2747 math_ceil (float arg1, float ignore ATTRIBUTE_UNUSED) 2748 { 2749 return (float) ceil (arg1); 2750 } 2751 2752 static float 2753 math_cvi (float arg1, float ignore ATTRIBUTE_UNUSED) 2754 { 2755 return (int) arg1; 2756 } 2757 2758 static float 2759 math_floor (float arg1, float ignore ATTRIBUTE_UNUSED) 2760 { 2761 return (float) floor (arg1); 2762 } 2763 2764 static float 2765 math_fmod (float arg1, float arg2) 2766 { 2767 return (int) arg1 % (int) arg2; 2768 } 2769 2770 static float 2771 math_int (float arg1, float ignore ATTRIBUTE_UNUSED) 2772 { 2773 return ((float) ((int) arg1)) == arg1; 2774 } 2775 2776 static float 2777 math_round (float arg1, float ignore ATTRIBUTE_UNUSED) 2778 { 2779 return arg1 > 0 ? (int) (arg1 + 0.5) : (int) (arg1 - 0.5); 2780 } 2781 2782 static float 2783 math_sgn (float arg1, float ignore ATTRIBUTE_UNUSED) 2784 { 2785 return (arg1 < 0) ? -1 : (arg1 ? 1 : 0); 2786 } 2787 2788 static float 2789 math_trunc (float arg1, float ignore ATTRIBUTE_UNUSED) 2790 { 2791 return (int) arg1; 2792 } 2793 2794 static float 2795 math_acos (float arg1, float ignore ATTRIBUTE_UNUSED) 2796 { 2797 return (float) acos (arg1); 2798 } 2799 2800 static float 2801 math_asin (float arg1, float ignore ATTRIBUTE_UNUSED) 2802 { 2803 return (float) asin (arg1); 2804 } 2805 2806 static float 2807 math_atan (float arg1, float ignore ATTRIBUTE_UNUSED) 2808 { 2809 return (float) atan (arg1); 2810 } 2811 2812 static float 2813 math_atan2 (float arg1, float arg2) 2814 { 2815 return (float) atan2 (arg1, arg2); 2816 } 2817 2818 static float 2819 math_cosh (float arg1, float ignore ATTRIBUTE_UNUSED) 2820 { 2821 return (float) cosh (arg1); 2822 } 2823 2824 static float 2825 math_cos (float arg1, float ignore ATTRIBUTE_UNUSED) 2826 { 2827 return (float) cos (arg1); 2828 } 2829 2830 static float 2831 math_cvf (float arg1, float ignore ATTRIBUTE_UNUSED) 2832 { 2833 return (float) arg1; 2834 } 2835 2836 static float 2837 math_exp (float arg1, float ignore ATTRIBUTE_UNUSED) 2838 { 2839 return (float) exp (arg1); 2840 } 2841 2842 static float 2843 math_fabs (float arg1, float ignore ATTRIBUTE_UNUSED) 2844 { 2845 return (float) fabs (arg1); 2846 } 2847 2848 /* expr1 * 2^expr2. */ 2849 2850 static float 2851 math_ldexp (float arg1, float arg2) 2852 { 2853 return arg1 * (float) pow (2.0, arg2); 2854 } 2855 2856 static float 2857 math_log10 (float arg1, float ignore ATTRIBUTE_UNUSED) 2858 { 2859 return (float) log10 (arg1); 2860 } 2861 2862 static float 2863 math_log (float arg1, float ignore ATTRIBUTE_UNUSED) 2864 { 2865 return (float) log (arg1); 2866 } 2867 2868 static float 2869 math_max (float arg1, float arg2) 2870 { 2871 return (arg1 > arg2) ? arg1 : arg2; 2872 } 2873 2874 static float 2875 math_min (float arg1, float arg2) 2876 { 2877 return (arg1 < arg2) ? arg1 : arg2; 2878 } 2879 2880 static float 2881 math_pow (float arg1, float arg2) 2882 { 2883 return (float) pow (arg1, arg2); 2884 } 2885 2886 static float 2887 math_sin (float arg1, float ignore ATTRIBUTE_UNUSED) 2888 { 2889 return (float) sin (arg1); 2890 } 2891 2892 static float 2893 math_sinh (float arg1, float ignore ATTRIBUTE_UNUSED) 2894 { 2895 return (float) sinh (arg1); 2896 } 2897 2898 static float 2899 math_sqrt (float arg1, float ignore ATTRIBUTE_UNUSED) 2900 { 2901 return (float) sqrt (arg1); 2902 } 2903 2904 static float 2905 math_tan (float arg1, float ignore ATTRIBUTE_UNUSED) 2906 { 2907 return (float) tan (arg1); 2908 } 2909 2910 static float 2911 math_tanh (float arg1, float ignore ATTRIBUTE_UNUSED) 2912 { 2913 return (float) tanh (arg1); 2914 } 2915 2916 /* Built-in substitution symbol functions and math functions. */ 2917 typedef struct 2918 { 2919 char *name; 2920 int (*proc) (char *, char *); 2921 int nargs; 2922 } subsym_proc_entry; 2923 2924 static const subsym_proc_entry subsym_procs[] = 2925 { 2926 /* Assembler built-in string substitution functions. */ 2927 { "$symlen", subsym_symlen, 1, }, 2928 { "$symcmp", subsym_symcmp, 2, }, 2929 { "$firstch", subsym_firstch, 2, }, 2930 { "$lastch", subsym_lastch, 2, }, 2931 { "$isdefed", subsym_isdefed, 1, }, 2932 { "$ismember", subsym_ismember, 2, }, 2933 { "$iscons", subsym_iscons, 1, }, 2934 { "$isname", subsym_isname, 1, }, 2935 { "$isreg", subsym_isreg, 1, }, 2936 { "$structsz", subsym_structsz, 1, }, 2937 { "$structacc", subsym_structacc, 1, }, 2938 { NULL, NULL, 0 }, 2939 }; 2940 2941 typedef struct 2942 { 2943 char *name; 2944 float (*proc) (float, float); 2945 int nargs; 2946 int int_return; 2947 } math_proc_entry; 2948 2949 static const math_proc_entry math_procs[] = 2950 { 2951 /* Integer-returning built-in math functions. */ 2952 { "$cvi", math_cvi, 1, 1 }, 2953 { "$int", math_int, 1, 1 }, 2954 { "$sgn", math_sgn, 1, 1 }, 2955 2956 /* Float-returning built-in math functions. */ 2957 { "$acos", math_acos, 1, 0 }, 2958 { "$asin", math_asin, 1, 0 }, 2959 { "$atan", math_atan, 1, 0 }, 2960 { "$atan2", math_atan2, 2, 0 }, 2961 { "$ceil", math_ceil, 1, 0 }, 2962 { "$cosh", math_cosh, 1, 0 }, 2963 { "$cos", math_cos, 1, 0 }, 2964 { "$cvf", math_cvf, 1, 0 }, 2965 { "$exp", math_exp, 1, 0 }, 2966 { "$fabs", math_fabs, 1, 0 }, 2967 { "$floor", math_floor, 1, 0 }, 2968 { "$fmod", math_fmod, 2, 0 }, 2969 { "$ldexp", math_ldexp, 2, 0 }, 2970 { "$log10", math_log10, 1, 0 }, 2971 { "$log", math_log, 1, 0 }, 2972 { "$max", math_max, 2, 0 }, 2973 { "$min", math_min, 2, 0 }, 2974 { "$pow", math_pow, 2, 0 }, 2975 { "$round", math_round, 1, 0 }, 2976 { "$sin", math_sin, 1, 0 }, 2977 { "$sinh", math_sinh, 1, 0 }, 2978 { "$sqrt", math_sqrt, 1, 0 }, 2979 { "$tan", math_tan, 1, 0 }, 2980 { "$tanh", math_tanh, 1, 0 }, 2981 { "$trunc", math_trunc, 1, 0 }, 2982 { NULL, NULL, 0, 0 }, 2983 }; 2984 2985 void 2986 md_begin (void) 2987 { 2988 insn_template *tm; 2989 symbol *sym; 2990 const subsym_proc_entry *subsym_proc; 2991 const math_proc_entry *math_proc; 2992 const char *hash_err; 2993 char **symname; 2994 char *TIC54X_DIR = getenv ("TIC54X_DIR"); 2995 char *A_DIR = TIC54X_DIR ? TIC54X_DIR : getenv ("A_DIR"); 2996 2997 local_label_id = 0; 2998 2999 /* Look for A_DIR and add it to the include list. */ 3000 if (A_DIR != NULL) 3001 { 3002 char *tmp = xstrdup (A_DIR); 3003 3004 do 3005 { 3006 char *next = strchr (tmp, ';'); 3007 3008 if (next) 3009 *next++ = '\0'; 3010 add_include_dir (tmp); 3011 tmp = next; 3012 } 3013 while (tmp != NULL); 3014 } 3015 3016 op_hash = hash_new (); 3017 for (tm = (insn_template *) tic54x_optab; tm->name; tm++) 3018 { 3019 if (hash_find (op_hash, tm->name)) 3020 continue; 3021 hash_err = hash_insert (op_hash, tm->name, (char *) tm); 3022 if (hash_err) 3023 as_fatal ("Internal Error: Can't hash %s: %s", 3024 tm->name, hash_err); 3025 } 3026 parop_hash = hash_new (); 3027 for (tm = (insn_template *) tic54x_paroptab; tm->name; tm++) 3028 { 3029 if (hash_find (parop_hash, tm->name)) 3030 continue; 3031 hash_err = hash_insert (parop_hash, tm->name, (char *) tm); 3032 if (hash_err) 3033 as_fatal ("Internal Error: Can't hash %s: %s", 3034 tm->name, hash_err); 3035 } 3036 reg_hash = hash_new (); 3037 for (sym = (symbol *) regs; sym->name; sym++) 3038 { 3039 /* Add basic registers to the symbol table. */ 3040 symbolS *symbolP = symbol_new (sym->name, absolute_section, 3041 (valueT) sym->value, &zero_address_frag); 3042 SF_SET_LOCAL (symbolP); 3043 symbol_table_insert (symbolP); 3044 hash_err = hash_insert (reg_hash, sym->name, (char *) sym); 3045 } 3046 for (sym = (symbol *) mmregs; sym->name; sym++) 3047 hash_err = hash_insert (reg_hash, sym->name, (char *) sym); 3048 mmreg_hash = hash_new (); 3049 for (sym = (symbol *) mmregs; sym->name; sym++) 3050 hash_err = hash_insert (mmreg_hash, sym->name, (char *) sym); 3051 3052 cc_hash = hash_new (); 3053 for (sym = (symbol *) condition_codes; sym->name; sym++) 3054 hash_err = hash_insert (cc_hash, sym->name, (char *) sym); 3055 3056 cc2_hash = hash_new (); 3057 for (sym = (symbol *) cc2_codes; sym->name; sym++) 3058 hash_err = hash_insert (cc2_hash, sym->name, (char *) sym); 3059 3060 cc3_hash = hash_new (); 3061 for (sym = (symbol *) cc3_codes; sym->name; sym++) 3062 hash_err = hash_insert (cc3_hash, sym->name, (char *) sym); 3063 3064 sbit_hash = hash_new (); 3065 for (sym = (symbol *) status_bits; sym->name; sym++) 3066 hash_err = hash_insert (sbit_hash, sym->name, (char *) sym); 3067 3068 misc_symbol_hash = hash_new (); 3069 for (symname = (char **) misc_symbols; *symname; symname++) 3070 hash_err = hash_insert (misc_symbol_hash, *symname, *symname); 3071 3072 /* Only the base substitution table and local label table are initialized; 3073 the others (for local macro substitution) get instantiated as needed. */ 3074 local_label_hash[0] = hash_new (); 3075 subsym_hash[0] = hash_new (); 3076 for (subsym_proc = subsym_procs; subsym_proc->name; subsym_proc++) 3077 hash_err = hash_insert (subsym_hash[0], subsym_proc->name, 3078 (char *) subsym_proc); 3079 3080 math_hash = hash_new (); 3081 for (math_proc = math_procs; math_proc->name; math_proc++) 3082 { 3083 /* Insert into the main subsym hash for recognition; insert into 3084 the math hash to actually store information. */ 3085 hash_err = hash_insert (subsym_hash[0], math_proc->name, 3086 (char *) math_proc); 3087 hash_err = hash_insert (math_hash, math_proc->name, 3088 (char *) math_proc); 3089 } 3090 subsym_recurse_hash = hash_new (); 3091 stag_hash = hash_new (); 3092 } 3093 3094 static int 3095 is_accumulator (struct opstruct *operand) 3096 { 3097 return strcasecmp (operand->buf, "a") == 0 3098 || strcasecmp (operand->buf, "b") == 0; 3099 } 3100 3101 /* Return the number of operands found, or -1 on error, copying the 3102 operands into the given array and the accompanying expressions into 3103 the next array. */ 3104 3105 static int 3106 get_operands (struct opstruct operands[], char *line) 3107 { 3108 char *lptr = line; 3109 int numexp = 0; 3110 int expecting_operand = 0; 3111 int i; 3112 3113 while (numexp < MAX_OPERANDS && !is_end_of_line[(int) *lptr]) 3114 { 3115 int paren_not_balanced = 0; 3116 char *op_start, *op_end; 3117 3118 while (*lptr && ISSPACE (*lptr)) 3119 ++lptr; 3120 op_start = lptr; 3121 while (paren_not_balanced || *lptr != ',') 3122 { 3123 if (*lptr == '\0') 3124 { 3125 if (paren_not_balanced) 3126 { 3127 as_bad (_("Unbalanced parenthesis in operand %d"), numexp); 3128 return -1; 3129 } 3130 else 3131 break; 3132 } 3133 if (*lptr == '(') 3134 ++paren_not_balanced; 3135 else if (*lptr == ')') 3136 --paren_not_balanced; 3137 ++lptr; 3138 } 3139 op_end = lptr; 3140 if (op_end != op_start) 3141 { 3142 int len = op_end - op_start; 3143 3144 strncpy (operands[numexp].buf, op_start, len); 3145 operands[numexp].buf[len] = 0; 3146 /* Trim trailing spaces; while the preprocessor gets rid of most, 3147 there are weird usage patterns that can introduce them 3148 (i.e. using strings for macro args). */ 3149 while (len > 0 && ISSPACE (operands[numexp].buf[len - 1])) 3150 operands[numexp].buf[--len] = 0; 3151 lptr = op_end; 3152 ++numexp; 3153 } 3154 else 3155 { 3156 if (expecting_operand || *lptr == ',') 3157 { 3158 as_bad (_("Expecting operand after ','")); 3159 return -1; 3160 } 3161 } 3162 if (*lptr == ',') 3163 { 3164 if (*++lptr == '\0') 3165 { 3166 as_bad (_("Expecting operand after ','")); 3167 return -1; 3168 } 3169 expecting_operand = 1; 3170 } 3171 } 3172 3173 while (*lptr && ISSPACE (*lptr++)) 3174 ; 3175 if (!is_end_of_line[(int) *lptr]) 3176 { 3177 as_bad (_("Extra junk on line")); 3178 return -1; 3179 } 3180 3181 /* OK, now parse them into expressions. */ 3182 for (i = 0; i < numexp; i++) 3183 { 3184 memset (&operands[i].exp, 0, sizeof (operands[i].exp)); 3185 if (operands[i].buf[0] == '#') 3186 { 3187 /* Immediate. */ 3188 parse_expression (operands[i].buf + 1, &operands[i].exp); 3189 } 3190 else if (operands[i].buf[0] == '@') 3191 { 3192 /* Direct notation. */ 3193 parse_expression (operands[i].buf + 1, &operands[i].exp); 3194 } 3195 else if (operands[i].buf[0] == '*') 3196 { 3197 /* Indirect. */ 3198 char *paren = strchr (operands[i].buf, '('); 3199 3200 /* Allow immediate syntax in the inner expression. */ 3201 if (paren && paren[1] == '#') 3202 *++paren = '('; 3203 3204 /* Pull out the lk expression or SP offset, if present. */ 3205 if (paren != NULL) 3206 { 3207 int len = strlen (paren); 3208 char *end = paren + len; 3209 int c; 3210 3211 while (end[-1] != ')') 3212 if (--end <= paren) 3213 { 3214 as_bad (_("Badly formed address expression")); 3215 return -1; 3216 } 3217 c = *end; 3218 *end = '\0'; 3219 parse_expression (paren, &operands[i].exp); 3220 *end = c; 3221 } 3222 else 3223 operands[i].exp.X_op = O_absent; 3224 } 3225 else 3226 parse_expression (operands[i].buf, &operands[i].exp); 3227 } 3228 3229 return numexp; 3230 } 3231 3232 /* Predicates for different operand types. */ 3233 3234 static int 3235 is_immediate (struct opstruct *operand) 3236 { 3237 return *operand->buf == '#'; 3238 } 3239 3240 /* This is distinguished from immediate because some numbers must be constants 3241 and must *not* have the '#' prefix. */ 3242 3243 static int 3244 is_absolute (struct opstruct *operand) 3245 { 3246 return operand->exp.X_op == O_constant && !is_immediate (operand); 3247 } 3248 3249 /* Is this an indirect operand? */ 3250 3251 static int 3252 is_indirect (struct opstruct *operand) 3253 { 3254 return operand->buf[0] == '*'; 3255 } 3256 3257 /* Is this a valid dual-memory operand? */ 3258 3259 static int 3260 is_dual (struct opstruct *operand) 3261 { 3262 if (is_indirect (operand) && strncasecmp (operand->buf, "*ar", 3) == 0) 3263 { 3264 char *tmp = operand->buf + 3; 3265 int arf; 3266 int valid_mod; 3267 3268 arf = *tmp++ - '0'; 3269 /* Only allow *ARx, *ARx-, *ARx+, or *ARx+0%. */ 3270 valid_mod = *tmp == '\0' || 3271 strcasecmp (tmp, "-") == 0 || 3272 strcasecmp (tmp, "+") == 0 || 3273 strcasecmp (tmp, "+0%") == 0; 3274 return arf >= 2 && arf <= 5 && valid_mod; 3275 } 3276 return 0; 3277 } 3278 3279 static int 3280 is_mmreg (struct opstruct *operand) 3281 { 3282 return (is_absolute (operand) 3283 || is_immediate (operand) 3284 || hash_find (mmreg_hash, operand->buf) != 0); 3285 } 3286 3287 static int 3288 is_type (struct opstruct *operand, enum optype type) 3289 { 3290 switch (type) 3291 { 3292 case OP_None: 3293 return operand->buf[0] == 0; 3294 case OP_Xmem: 3295 case OP_Ymem: 3296 return is_dual (operand); 3297 case OP_Sind: 3298 return is_indirect (operand); 3299 case OP_xpmad_ms7: 3300 /* This one *must* be immediate. */ 3301 return is_immediate (operand); 3302 case OP_xpmad: 3303 case OP_pmad: 3304 case OP_PA: 3305 case OP_dmad: 3306 case OP_Lmem: 3307 case OP_MMR: 3308 return 1; 3309 case OP_Smem: 3310 /* Address may be a numeric, indirect, or an expression. */ 3311 return !is_immediate (operand); 3312 case OP_MMRY: 3313 case OP_MMRX: 3314 return is_mmreg (operand); 3315 case OP_SRC: 3316 case OP_SRC1: 3317 case OP_RND: 3318 case OP_DST: 3319 return is_accumulator (operand); 3320 case OP_B: 3321 return is_accumulator (operand) && TOUPPER (operand->buf[0]) == 'B'; 3322 case OP_A: 3323 return is_accumulator (operand) && TOUPPER (operand->buf[0]) == 'A'; 3324 case OP_ARX: 3325 return strncasecmp ("ar", operand->buf, 2) == 0 3326 && ISDIGIT (operand->buf[2]); 3327 case OP_SBIT: 3328 return hash_find (sbit_hash, operand->buf) != 0 || is_absolute (operand); 3329 case OP_CC: 3330 return hash_find (cc_hash, operand->buf) != 0; 3331 case OP_CC2: 3332 return hash_find (cc2_hash, operand->buf) != 0; 3333 case OP_CC3: 3334 return hash_find (cc3_hash, operand->buf) != 0 3335 || is_immediate (operand) || is_absolute (operand); 3336 case OP_16: 3337 return (is_immediate (operand) || is_absolute (operand)) 3338 && operand->exp.X_add_number == 16; 3339 case OP_N: 3340 /* Allow st0 or st1 instead of a numeric. */ 3341 return is_absolute (operand) || is_immediate (operand) || 3342 strcasecmp ("st0", operand->buf) == 0 || 3343 strcasecmp ("st1", operand->buf) == 0; 3344 case OP_12: 3345 case OP_123: 3346 return is_absolute (operand) || is_immediate (operand); 3347 case OP_SHFT: 3348 return (is_immediate (operand) || is_absolute (operand)) 3349 && operand->exp.X_add_number >= 0 && operand->exp.X_add_number < 16; 3350 case OP_SHIFT: 3351 /* Let this one catch out-of-range values. */ 3352 return (is_immediate (operand) || is_absolute (operand)) 3353 && operand->exp.X_add_number != 16; 3354 case OP_BITC: 3355 case OP_031: 3356 case OP_k8: 3357 return is_absolute (operand) || is_immediate (operand); 3358 case OP_k8u: 3359 return is_immediate (operand) 3360 && operand->exp.X_op == O_constant 3361 && operand->exp.X_add_number >= 0 3362 && operand->exp.X_add_number < 256; 3363 case OP_lk: 3364 case OP_lku: 3365 /* Allow anything; assumes opcodes are ordered with Smem operands 3366 versions first. */ 3367 return 1; 3368 case OP_k5: 3369 case OP_k3: 3370 case OP_k9: 3371 /* Just make sure it's an integer; check range later. */ 3372 return is_immediate (operand); 3373 case OP_T: 3374 return strcasecmp ("t", operand->buf) == 0 || 3375 strcasecmp ("treg", operand->buf) == 0; 3376 case OP_TS: 3377 return strcasecmp ("ts", operand->buf) == 0; 3378 case OP_ASM: 3379 return strcasecmp ("asm", operand->buf) == 0; 3380 case OP_TRN: 3381 return strcasecmp ("trn", operand->buf) == 0; 3382 case OP_DP: 3383 return strcasecmp ("dp", operand->buf) == 0; 3384 case OP_ARP: 3385 return strcasecmp ("arp", operand->buf) == 0; 3386 default: 3387 return 0; 3388 } 3389 } 3390 3391 static int 3392 operands_match (tic54x_insn *insn, 3393 struct opstruct *operands, 3394 int opcount, 3395 const enum optype *refoptype, 3396 int minops, 3397 int maxops) 3398 { 3399 int op = 0, refop = 0; 3400 3401 if (opcount == 0 && minops == 0) 3402 return 1; 3403 3404 while (op <= maxops && refop <= maxops) 3405 { 3406 while (!is_type (&operands[op], OPTYPE (refoptype[refop]))) 3407 { 3408 /* Skip an optional template operand if it doesn't agree 3409 with the current operand. */ 3410 if (refoptype[refop] & OPT) 3411 { 3412 ++refop; 3413 --maxops; 3414 if (refop > maxops) 3415 return 0; 3416 } 3417 else 3418 return 0; 3419 } 3420 3421 /* Save the actual operand type for later use. */ 3422 operands[op].type = OPTYPE (refoptype[refop]); 3423 ++refop; 3424 ++op; 3425 /* Have we matched them all yet? */ 3426 if (op == opcount) 3427 { 3428 while (op < maxops) 3429 { 3430 /* If a later operand is *not* optional, no match. */ 3431 if ((refoptype[refop] & OPT) == 0) 3432 return 0; 3433 /* Flag any implicit default OP_DST operands so we know to add 3434 them explicitly when encoding the operand later. */ 3435 if (OPTYPE (refoptype[refop]) == OP_DST) 3436 insn->using_default_dst = 1; 3437 ++refop; 3438 ++op; 3439 } 3440 3441 return 1; 3442 } 3443 } 3444 3445 return 0; 3446 } 3447 3448 /* 16-bit direct memory address 3449 Explicit dmad operands are always in last word of insn (usually second 3450 word, but bumped to third if lk addressing is used) 3451 3452 We allow *(dmad) notation because the TI assembler allows it. 3453 3454 XPC_CODE: 3455 0 for 16-bit addresses 3456 1 for full 23-bit addresses 3457 2 for the upper 7 bits of a 23-bit address (LDX). */ 3458 3459 static int 3460 encode_dmad (tic54x_insn *insn, struct opstruct *operand, int xpc_code) 3461 { 3462 int op = 1 + insn->is_lkaddr; 3463 3464 /* Only allow *(dmad) expressions; all others are invalid. */ 3465 if (is_indirect (operand) && operand->buf[strlen (operand->buf) - 1] != ')') 3466 { 3467 as_bad (_("Invalid dmad syntax '%s'"), operand->buf); 3468 return 0; 3469 } 3470 3471 insn->opcode[op].addr_expr = operand->exp; 3472 3473 if (insn->opcode[op].addr_expr.X_op == O_constant) 3474 { 3475 valueT value = insn->opcode[op].addr_expr.X_add_number; 3476 3477 if (xpc_code == 1) 3478 { 3479 insn->opcode[0].word &= 0xFF80; 3480 insn->opcode[0].word |= (value >> 16) & 0x7F; 3481 insn->opcode[1].word = value & 0xFFFF; 3482 } 3483 else if (xpc_code == 2) 3484 insn->opcode[op].word = (value >> 16) & 0xFFFF; 3485 else 3486 insn->opcode[op].word = value; 3487 } 3488 else 3489 { 3490 /* Do the fixup later; just store the expression. */ 3491 insn->opcode[op].word = 0; 3492 insn->opcode[op].r_nchars = 2; 3493 3494 if (amode == c_mode) 3495 insn->opcode[op].r_type = BFD_RELOC_TIC54X_16_OF_23; 3496 else if (xpc_code == 1) 3497 { 3498 /* This relocation spans two words, so adjust accordingly. */ 3499 insn->opcode[0].addr_expr = operand->exp; 3500 insn->opcode[0].r_type = BFD_RELOC_TIC54X_23; 3501 insn->opcode[0].r_nchars = 4; 3502 insn->opcode[0].unresolved = 1; 3503 /* It's really 2 words, but we want to stop encoding after the 3504 first, since we must encode both words at once. */ 3505 insn->words = 1; 3506 } 3507 else if (xpc_code == 2) 3508 insn->opcode[op].r_type = BFD_RELOC_TIC54X_MS7_OF_23; 3509 else 3510 insn->opcode[op].r_type = BFD_RELOC_TIC54X_16_OF_23; 3511 3512 insn->opcode[op].unresolved = 1; 3513 } 3514 3515 return 1; 3516 } 3517 3518 /* 7-bit direct address encoding. */ 3519 3520 static int 3521 encode_address (tic54x_insn *insn, struct opstruct *operand) 3522 { 3523 /* Assumes that dma addresses are *always* in word 0 of the opcode. */ 3524 insn->opcode[0].addr_expr = operand->exp; 3525 3526 if (operand->exp.X_op == O_constant) 3527 insn->opcode[0].word |= (operand->exp.X_add_number & 0x7F); 3528 else 3529 { 3530 if (operand->exp.X_op == O_register) 3531 as_bad (_("Use the .mmregs directive to use memory-mapped register names such as '%s'"), operand->buf); 3532 /* Do the fixup later; just store the expression. */ 3533 insn->opcode[0].r_nchars = 1; 3534 insn->opcode[0].r_type = BFD_RELOC_TIC54X_PARTLS7; 3535 insn->opcode[0].unresolved = 1; 3536 } 3537 3538 return 1; 3539 } 3540 3541 static int 3542 encode_indirect (tic54x_insn *insn, struct opstruct *operand) 3543 { 3544 int arf; 3545 int mod; 3546 3547 if (insn->is_lkaddr) 3548 { 3549 /* lk addresses always go in the second insn word. */ 3550 mod = ((TOUPPER (operand->buf[1]) == 'A') ? 12 : 3551 (operand->buf[1] == '(') ? 15 : 3552 (strchr (operand->buf, '%') != NULL) ? 14 : 13); 3553 arf = ((mod == 12) ? operand->buf[3] - '0' : 3554 (mod == 15) ? 0 : operand->buf[4] - '0'); 3555 3556 insn->opcode[1].addr_expr = operand->exp; 3557 3558 if (operand->exp.X_op == O_constant) 3559 insn->opcode[1].word = operand->exp.X_add_number; 3560 else 3561 { 3562 insn->opcode[1].word = 0; 3563 insn->opcode[1].r_nchars = 2; 3564 insn->opcode[1].r_type = BFD_RELOC_TIC54X_16_OF_23; 3565 insn->opcode[1].unresolved = 1; 3566 } 3567 } 3568 else if (strncasecmp (operand->buf, "*sp (", 4) == 0) 3569 { 3570 /* Stack offsets look the same as 7-bit direct addressing. */ 3571 return encode_address (insn, operand); 3572 } 3573 else 3574 { 3575 arf = (TOUPPER (operand->buf[1]) == 'A' ? 3576 operand->buf[3] : operand->buf[4]) - '0'; 3577 3578 if (operand->buf[1] == '+') 3579 { 3580 mod = 3; /* *+ARx */ 3581 if (insn->tm->flags & FL_SMR) 3582 as_warn (_("Address mode *+ARx is write-only. " 3583 "Results of reading are undefined.")); 3584 } 3585 else if (operand->buf[4] == '\0') 3586 mod = 0; /* *ARx */ 3587 else if (operand->buf[5] == '\0') 3588 mod = (operand->buf[4] == '-' ? 1 : 2); /* *ARx+ / *ARx- */ 3589 else if (operand->buf[6] == '\0') 3590 { 3591 if (operand->buf[5] == '0') 3592 mod = (operand->buf[4] == '-' ? 5 : 6); /* *ARx+0 / *ARx-0 */ 3593 else 3594 mod = (operand->buf[4] == '-' ? 8 : 10);/* *ARx+% / *ARx-% */ 3595 } 3596 else if (TOUPPER (operand->buf[6]) == 'B') 3597 mod = (operand->buf[4] == '-' ? 4 : 7); /* ARx+0B / *ARx-0B */ 3598 else if (TOUPPER (operand->buf[6]) == '%') 3599 mod = (operand->buf[4] == '-' ? 9 : 11); /* ARx+0% / *ARx - 0% */ 3600 else 3601 { 3602 as_bad (_("Unrecognized indirect address format \"%s\""), 3603 operand->buf); 3604 return 0; 3605 } 3606 } 3607 3608 insn->opcode[0].word |= 0x80 | (mod << 3) | arf; 3609 3610 return 1; 3611 } 3612 3613 static int 3614 encode_integer (tic54x_insn *insn, 3615 struct opstruct *operand, 3616 int which, 3617 int min, 3618 int max, 3619 unsigned short mask) 3620 { 3621 long parse, integer; 3622 3623 insn->opcode[which].addr_expr = operand->exp; 3624 3625 if (operand->exp.X_op == O_constant) 3626 { 3627 parse = operand->exp.X_add_number; 3628 /* Hack -- fixup for 16-bit hex quantities that get converted positive 3629 instead of negative. */ 3630 if ((parse & 0x8000) && min == -32768 && max == 32767) 3631 integer = (short) parse; 3632 else 3633 integer = parse; 3634 3635 if (integer >= min && integer <= max) 3636 { 3637 insn->opcode[which].word |= (integer & mask); 3638 return 1; 3639 } 3640 as_bad (_("Operand '%s' out of range (%d <= x <= %d)"), 3641 operand->buf, min, max); 3642 } 3643 else 3644 { 3645 if (insn->opcode[which].addr_expr.X_op == O_constant) 3646 { 3647 insn->opcode[which].word |= 3648 insn->opcode[which].addr_expr.X_add_number & mask; 3649 } 3650 else 3651 { 3652 /* Do the fixup later; just store the expression. */ 3653 bfd_reloc_code_real_type rtype = 3654 (mask == 0x1FF ? BFD_RELOC_TIC54X_PARTMS9 : 3655 mask == 0xFFFF ? BFD_RELOC_TIC54X_16_OF_23 : 3656 mask == 0x7F ? BFD_RELOC_TIC54X_PARTLS7 : BFD_RELOC_8); 3657 int size = (mask == 0x1FF || mask == 0xFFFF) ? 2 : 1; 3658 3659 if (rtype == BFD_RELOC_8) 3660 as_bad (_("Error in relocation handling")); 3661 3662 insn->opcode[which].r_nchars = size; 3663 insn->opcode[which].r_type = rtype; 3664 insn->opcode[which].unresolved = 1; 3665 } 3666 3667 return 1; 3668 } 3669 3670 return 0; 3671 } 3672 3673 static int 3674 encode_condition (tic54x_insn *insn, struct opstruct *operand) 3675 { 3676 symbol *cc = (symbol *) hash_find (cc_hash, operand->buf); 3677 if (!cc) 3678 { 3679 as_bad (_("Unrecognized condition code \"%s\""), operand->buf); 3680 return 0; 3681 } 3682 #define CC_GROUP 0x40 3683 #define CC_ACC 0x08 3684 #define CATG_A1 0x07 3685 #define CATG_B1 0x30 3686 #define CATG_A2 0x30 3687 #define CATG_B2 0x0C 3688 #define CATG_C2 0x03 3689 /* Disallow group 1 conditions mixed with group 2 conditions 3690 if group 1, allow only one category A and one category B 3691 if group 2, allow only one each of category A, B, and C. */ 3692 if (((insn->opcode[0].word & 0xFF) != 0)) 3693 { 3694 if ((insn->opcode[0].word & CC_GROUP) != (cc->value & CC_GROUP)) 3695 { 3696 as_bad (_("Condition \"%s\" does not match preceding group"), 3697 operand->buf); 3698 return 0; 3699 } 3700 if (insn->opcode[0].word & CC_GROUP) 3701 { 3702 if ((insn->opcode[0].word & CC_ACC) != (cc->value & CC_ACC)) 3703 { 3704 as_bad (_("Condition \"%s\" uses a different accumulator from " 3705 "a preceding condition"), 3706 operand->buf); 3707 return 0; 3708 } 3709 if ((insn->opcode[0].word & CATG_A1) && (cc->value & CATG_A1)) 3710 { 3711 as_bad (_("Only one comparison conditional allowed")); 3712 return 0; 3713 } 3714 if ((insn->opcode[0].word & CATG_B1) && (cc->value & CATG_B1)) 3715 { 3716 as_bad (_("Only one overflow conditional allowed")); 3717 return 0; 3718 } 3719 } 3720 else if ( ((insn->opcode[0].word & CATG_A2) && (cc->value & CATG_A2)) 3721 || ((insn->opcode[0].word & CATG_B2) && (cc->value & CATG_B2)) 3722 || ((insn->opcode[0].word & CATG_C2) && (cc->value & CATG_C2))) 3723 { 3724 as_bad (_("Duplicate %s conditional"), operand->buf); 3725 return 0; 3726 } 3727 } 3728 3729 insn->opcode[0].word |= cc->value; 3730 return 1; 3731 } 3732 3733 static int 3734 encode_cc3 (tic54x_insn *insn, struct opstruct *operand) 3735 { 3736 symbol *cc3 = (symbol *) hash_find (cc3_hash, operand->buf); 3737 int value = cc3 ? cc3->value : operand->exp.X_add_number << 8; 3738 3739 if ((value & 0x0300) != value) 3740 { 3741 as_bad (_("Unrecognized condition code \"%s\""), operand->buf); 3742 return 0; 3743 } 3744 insn->opcode[0].word |= value; 3745 return 1; 3746 } 3747 3748 static int 3749 encode_arx (tic54x_insn *insn, struct opstruct *operand) 3750 { 3751 int arf = strlen (operand->buf) >= 3 ? operand->buf[2] - '0' : -1; 3752 3753 if (strncasecmp ("ar", operand->buf, 2) || arf < 0 || arf > 7) 3754 { 3755 as_bad (_("Invalid auxiliary register (use AR0-AR7)")); 3756 return 0; 3757 } 3758 insn->opcode[0].word |= arf; 3759 return 1; 3760 } 3761 3762 static int 3763 encode_cc2 (tic54x_insn *insn, struct opstruct *operand) 3764 { 3765 symbol *cc2 = (symbol *) hash_find (cc2_hash, operand->buf); 3766 3767 if (!cc2) 3768 { 3769 as_bad (_("Unrecognized condition code \"%s\""), operand->buf); 3770 return 0; 3771 } 3772 insn->opcode[0].word |= cc2->value; 3773 return 1; 3774 } 3775 3776 static int 3777 encode_operand (tic54x_insn *insn, enum optype type, struct opstruct *operand) 3778 { 3779 int ext = (insn->tm->flags & FL_EXT) != 0; 3780 3781 if (type == OP_MMR && operand->exp.X_op != O_constant) 3782 { 3783 /* Disallow long-constant addressing for memory-mapped addressing. */ 3784 if (insn->is_lkaddr) 3785 { 3786 as_bad (_("lk addressing modes are invalid for memory-mapped " 3787 "register addressing")); 3788 return 0; 3789 } 3790 type = OP_Smem; 3791 /* Warn about *+ARx when used with MMR operands. */ 3792 if (strncasecmp (operand->buf, "*+ar", 4) == 0) 3793 { 3794 as_warn (_("Address mode *+ARx is not allowed in memory-mapped " 3795 "register addressing. Resulting behavior is " 3796 "undefined.")); 3797 } 3798 } 3799 3800 switch (type) 3801 { 3802 case OP_None: 3803 return 1; 3804 case OP_dmad: 3805 /* 16-bit immediate value. */ 3806 return encode_dmad (insn, operand, 0); 3807 case OP_SRC: 3808 if (TOUPPER (*operand->buf) == 'B') 3809 { 3810 insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 9); 3811 if (insn->using_default_dst) 3812 insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 8); 3813 } 3814 return 1; 3815 case OP_RND: 3816 /* Make sure this agrees with the OP_DST operand. */ 3817 if (!((TOUPPER (operand->buf[0]) == 'B') ^ 3818 ((insn->opcode[0].word & (1 << 8)) != 0))) 3819 { 3820 as_bad (_("Destination accumulator for each part of this parallel " 3821 "instruction must be different")); 3822 return 0; 3823 } 3824 return 1; 3825 case OP_SRC1: 3826 case OP_DST: 3827 if (TOUPPER (operand->buf[0]) == 'B') 3828 insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 8); 3829 return 1; 3830 case OP_Xmem: 3831 case OP_Ymem: 3832 { 3833 int mod = (operand->buf[4] == '\0' ? 0 : /* *arx */ 3834 operand->buf[4] == '-' ? 1 : /* *arx- */ 3835 operand->buf[5] == '\0' ? 2 : 3); /* *arx+, *arx+0% */ 3836 int arf = operand->buf[3] - '0' - 2; 3837 int code = (mod << 2) | arf; 3838 insn->opcode[0].word |= (code << (type == OP_Xmem ? 4 : 0)); 3839 return 1; 3840 } 3841 case OP_Lmem: 3842 case OP_Smem: 3843 if (!is_indirect (operand)) 3844 return encode_address (insn, operand); 3845 /* Fall through. */ 3846 case OP_Sind: 3847 return encode_indirect (insn, operand); 3848 case OP_xpmad_ms7: 3849 return encode_dmad (insn, operand, 2); 3850 case OP_xpmad: 3851 return encode_dmad (insn, operand, 1); 3852 case OP_PA: 3853 case OP_pmad: 3854 return encode_dmad (insn, operand, 0); 3855 case OP_ARX: 3856 return encode_arx (insn, operand); 3857 case OP_MMRX: 3858 case OP_MMRY: 3859 case OP_MMR: 3860 { 3861 int value = operand->exp.X_add_number; 3862 3863 if (type == OP_MMR) 3864 insn->opcode[0].word |= value; 3865 else 3866 { 3867 if (value < 16 || value > 24) 3868 { 3869 as_bad (_("Memory mapped register \"%s\" out of range"), 3870 operand->buf); 3871 return 0; 3872 } 3873 if (type == OP_MMRX) 3874 insn->opcode[0].word |= (value - 16) << 4; 3875 else 3876 insn->opcode[0].word |= (value - 16); 3877 } 3878 return 1; 3879 } 3880 case OP_B: 3881 case OP_A: 3882 return 1; 3883 case OP_SHFT: 3884 return encode_integer (insn, operand, ext + insn->is_lkaddr, 3885 0, 15, 0xF); 3886 case OP_SHIFT: 3887 return encode_integer (insn, operand, ext + insn->is_lkaddr, 3888 -16, 15, 0x1F); 3889 case OP_lk: 3890 return encode_integer (insn, operand, 1 + insn->is_lkaddr, 3891 -32768, 32767, 0xFFFF); 3892 case OP_CC: 3893 return encode_condition (insn, operand); 3894 case OP_CC2: 3895 return encode_cc2 (insn, operand); 3896 case OP_CC3: 3897 return encode_cc3 (insn, operand); 3898 case OP_BITC: 3899 return encode_integer (insn, operand, 0, 0, 15, 0xF); 3900 case OP_k8: 3901 return encode_integer (insn, operand, 0, -128, 127, 0xFF); 3902 case OP_123: 3903 { 3904 int value = operand->exp.X_add_number; 3905 int code; 3906 if (value < 1 || value > 3) 3907 { 3908 as_bad (_("Invalid operand (use 1, 2, or 3)")); 3909 return 0; 3910 } 3911 code = value == 1 ? 0 : value == 2 ? 0x2 : 0x1; 3912 insn->opcode[0].word |= (code << 8); 3913 return 1; 3914 } 3915 case OP_031: 3916 return encode_integer (insn, operand, 0, 0, 31, 0x1F); 3917 case OP_k8u: 3918 return encode_integer (insn, operand, 0, 0, 255, 0xFF); 3919 case OP_lku: 3920 return encode_integer (insn, operand, 1 + insn->is_lkaddr, 3921 0, 65535, 0xFFFF); 3922 case OP_SBIT: 3923 { 3924 symbol *sbit = (symbol *) hash_find (sbit_hash, operand->buf); 3925 int value = is_absolute (operand) ? 3926 operand->exp.X_add_number : (sbit ? sbit->value : -1); 3927 int reg = 0; 3928 3929 if (insn->opcount == 1) 3930 { 3931 if (!sbit) 3932 { 3933 as_bad (_("A status register or status bit name is required")); 3934 return 0; 3935 } 3936 /* Guess the register based on the status bit; "ovb" is the last 3937 status bit defined for st0. */ 3938 if (sbit > (symbol *) hash_find (sbit_hash, "ovb")) 3939 reg = 1; 3940 } 3941 if (value == -1) 3942 { 3943 as_bad (_("Unrecognized status bit \"%s\""), operand->buf); 3944 return 0; 3945 } 3946 insn->opcode[0].word |= value; 3947 insn->opcode[0].word |= (reg << 9); 3948 return 1; 3949 } 3950 case OP_N: 3951 if (strcasecmp (operand->buf, "st0") == 0 3952 || strcasecmp (operand->buf, "st1") == 0) 3953 { 3954 insn->opcode[0].word |= 3955 ((unsigned short) (operand->buf[2] - '0')) << 9; 3956 return 1; 3957 } 3958 else if (operand->exp.X_op == O_constant 3959 && (operand->exp.X_add_number == 0 3960 || operand->exp.X_add_number == 1)) 3961 { 3962 insn->opcode[0].word |= 3963 ((unsigned short) (operand->exp.X_add_number)) << 9; 3964 return 1; 3965 } 3966 as_bad (_("Invalid status register \"%s\""), operand->buf); 3967 return 0; 3968 case OP_k5: 3969 return encode_integer (insn, operand, 0, -16, 15, 0x1F); 3970 case OP_k3: 3971 return encode_integer (insn, operand, 0, 0, 7, 0x7); 3972 case OP_k9: 3973 return encode_integer (insn, operand, 0, 0, 0x1FF, 0x1FF); 3974 case OP_12: 3975 if (operand->exp.X_add_number != 1 3976 && operand->exp.X_add_number != 2) 3977 { 3978 as_bad (_("Operand \"%s\" out of range (use 1 or 2)"), operand->buf); 3979 return 0; 3980 } 3981 insn->opcode[0].word |= (operand->exp.X_add_number - 1) << 9; 3982 return 1; 3983 case OP_16: 3984 case OP_T: 3985 case OP_TS: 3986 case OP_ASM: 3987 case OP_TRN: 3988 case OP_DP: 3989 case OP_ARP: 3990 /* No encoding necessary. */ 3991 return 1; 3992 default: 3993 return 0; 3994 } 3995 3996 return 1; 3997 } 3998 3999 static void 4000 emit_insn (tic54x_insn *insn) 4001 { 4002 int i; 4003 flagword oldflags = bfd_get_section_flags (stdoutput, now_seg); 4004 flagword flags = oldflags | SEC_CODE; 4005 4006 if (! bfd_set_section_flags (stdoutput, now_seg, flags)) 4007 as_warn (_("error setting flags for \"%s\": %s"), 4008 bfd_section_name (stdoutput, now_seg), 4009 bfd_errmsg (bfd_get_error ())); 4010 4011 for (i = 0; i < insn->words; i++) 4012 { 4013 int size = (insn->opcode[i].unresolved 4014 && insn->opcode[i].r_type == BFD_RELOC_TIC54X_23) ? 4 : 2; 4015 char *p = frag_more (size); 4016 4017 if (size == 2) 4018 md_number_to_chars (p, (valueT) insn->opcode[i].word, 2); 4019 else 4020 md_number_to_chars (p, (valueT) insn->opcode[i].word << 16, 4); 4021 4022 if (insn->opcode[i].unresolved) 4023 fix_new_exp (frag_now, p - frag_now->fr_literal, 4024 insn->opcode[i].r_nchars, &insn->opcode[i].addr_expr, 4025 FALSE, insn->opcode[i].r_type); 4026 } 4027 } 4028 4029 /* Convert the operand strings into appropriate opcode values 4030 return the total number of words used by the instruction. */ 4031 4032 static int 4033 build_insn (tic54x_insn *insn) 4034 { 4035 int i; 4036 4037 /* Only non-parallel instructions support lk addressing. */ 4038 if (!(insn->tm->flags & FL_PAR)) 4039 { 4040 for (i = 0; i < insn->opcount; i++) 4041 { 4042 if ((OPTYPE (insn->operands[i].type) == OP_Smem 4043 || OPTYPE (insn->operands[i].type) == OP_Lmem 4044 || OPTYPE (insn->operands[i].type) == OP_Sind) 4045 && strchr (insn->operands[i].buf, '(') 4046 /* Don't mistake stack-relative addressing for lk addressing. */ 4047 && strncasecmp (insn->operands[i].buf, "*sp (", 4) != 0) 4048 { 4049 insn->is_lkaddr = 1; 4050 insn->lkoperand = i; 4051 break; 4052 } 4053 } 4054 } 4055 insn->words = insn->tm->words + insn->is_lkaddr; 4056 4057 insn->opcode[0].word = insn->tm->opcode; 4058 if (insn->tm->flags & FL_EXT) 4059 insn->opcode[1 + insn->is_lkaddr].word = insn->tm->opcode2; 4060 4061 for (i = 0; i < insn->opcount; i++) 4062 { 4063 enum optype type = insn->operands[i].type; 4064 4065 if (!encode_operand (insn, type, &insn->operands[i])) 4066 return 0; 4067 } 4068 if (insn->tm->flags & FL_PAR) 4069 for (i = 0; i < insn->paropcount; i++) 4070 { 4071 enum optype partype = insn->paroperands[i].type; 4072 4073 if (!encode_operand (insn, partype, &insn->paroperands[i])) 4074 return 0; 4075 } 4076 4077 emit_insn (insn); 4078 4079 return insn->words; 4080 } 4081 4082 static int 4083 optimize_insn (tic54x_insn *insn) 4084 { 4085 /* Optimize some instructions, helping out the brain-dead programmer. */ 4086 #define is_zero(op) ((op).exp.X_op == O_constant && (op).exp.X_add_number == 0) 4087 if (strcasecmp (insn->tm->name, "add") == 0) 4088 { 4089 if (insn->opcount > 1 4090 && is_accumulator (&insn->operands[insn->opcount - 2]) 4091 && is_accumulator (&insn->operands[insn->opcount - 1]) 4092 && strcasecmp (insn->operands[insn->opcount - 2].buf, 4093 insn->operands[insn->opcount - 1].buf) == 0) 4094 { 4095 --insn->opcount; 4096 insn->using_default_dst = 1; 4097 return 1; 4098 } 4099 4100 /* Try to collapse if Xmem and shift count is zero. */ 4101 if ((OPTYPE (insn->tm->operand_types[0]) == OP_Xmem 4102 && OPTYPE (insn->tm->operand_types[1]) == OP_SHFT 4103 && is_zero (insn->operands[1])) 4104 /* Or if Smem, shift is zero or absent, and SRC == DST. */ 4105 || (OPTYPE (insn->tm->operand_types[0]) == OP_Smem 4106 && OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT 4107 && is_type (&insn->operands[1], OP_SHIFT) 4108 && is_zero (insn->operands[1]) && insn->opcount == 3)) 4109 { 4110 insn->operands[1] = insn->operands[2]; 4111 insn->opcount = 2; 4112 return 1; 4113 } 4114 } 4115 else if (strcasecmp (insn->tm->name, "ld") == 0) 4116 { 4117 if (insn->opcount == 3 && insn->operands[0].type != OP_SRC) 4118 { 4119 if ((OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT 4120 || OPTYPE (insn->tm->operand_types[1]) == OP_SHFT) 4121 && is_zero (insn->operands[1]) 4122 && (OPTYPE (insn->tm->operand_types[0]) != OP_lk 4123 || (insn->operands[0].exp.X_op == O_constant 4124 && insn->operands[0].exp.X_add_number <= 255 4125 && insn->operands[0].exp.X_add_number >= 0))) 4126 { 4127 insn->operands[1] = insn->operands[2]; 4128 insn->opcount = 2; 4129 return 1; 4130 } 4131 } 4132 } 4133 else if (strcasecmp (insn->tm->name, "sth") == 0 4134 || strcasecmp (insn->tm->name, "stl") == 0) 4135 { 4136 if ((OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT 4137 || OPTYPE (insn->tm->operand_types[1]) == OP_SHFT) 4138 && is_zero (insn->operands[1])) 4139 { 4140 insn->operands[1] = insn->operands[2]; 4141 insn->opcount = 2; 4142 return 1; 4143 } 4144 } 4145 else if (strcasecmp (insn->tm->name, "sub") == 0) 4146 { 4147 if (insn->opcount > 1 4148 && is_accumulator (&insn->operands[insn->opcount - 2]) 4149 && is_accumulator (&insn->operands[insn->opcount - 1]) 4150 && strcasecmp (insn->operands[insn->opcount - 2].buf, 4151 insn->operands[insn->opcount - 1].buf) == 0) 4152 { 4153 --insn->opcount; 4154 insn->using_default_dst = 1; 4155 return 1; 4156 } 4157 4158 if ( ((OPTYPE (insn->tm->operand_types[0]) == OP_Smem 4159 && OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT) 4160 || (OPTYPE (insn->tm->operand_types[0]) == OP_Xmem 4161 && OPTYPE (insn->tm->operand_types[1]) == OP_SHFT)) 4162 && is_zero (insn->operands[1]) 4163 && insn->opcount == 3) 4164 { 4165 insn->operands[1] = insn->operands[2]; 4166 insn->opcount = 2; 4167 return 1; 4168 } 4169 } 4170 return 0; 4171 } 4172 4173 /* Find a matching template if possible, and get the operand strings. */ 4174 4175 static int 4176 tic54x_parse_insn (tic54x_insn *insn, char *line) 4177 { 4178 insn->tm = (insn_template *) hash_find (op_hash, insn->mnemonic); 4179 if (!insn->tm) 4180 { 4181 as_bad (_("Unrecognized instruction \"%s\""), insn->mnemonic); 4182 return 0; 4183 } 4184 4185 insn->opcount = get_operands (insn->operands, line); 4186 if (insn->opcount < 0) 4187 return 0; 4188 4189 /* Check each variation of operands for this mnemonic. */ 4190 while (insn->tm->name && strcasecmp (insn->tm->name, insn->mnemonic) == 0) 4191 { 4192 if (insn->opcount >= insn->tm->minops 4193 && insn->opcount <= insn->tm->maxops 4194 && operands_match (insn, &insn->operands[0], insn->opcount, 4195 insn->tm->operand_types, 4196 insn->tm->minops, insn->tm->maxops)) 4197 { 4198 /* SUCCESS! now try some optimizations. */ 4199 if (optimize_insn (insn)) 4200 { 4201 insn->tm = (insn_template *) hash_find (op_hash, 4202 insn->mnemonic); 4203 continue; 4204 } 4205 4206 return 1; 4207 } 4208 ++(insn->tm); 4209 } 4210 as_bad (_("Unrecognized operand list '%s' for instruction '%s'"), 4211 line, insn->mnemonic); 4212 return 0; 4213 } 4214 4215 /* We set this in start_line_hook, 'cause if we do a line replacement, we 4216 won't be able to see the next line. */ 4217 static int parallel_on_next_line_hint = 0; 4218 4219 /* See if this is part of a parallel instruction 4220 Look for a subsequent line starting with "||". */ 4221 4222 static int 4223 next_line_shows_parallel (char *next_line) 4224 { 4225 /* Look for the second half. */ 4226 while (ISSPACE (*next_line)) 4227 ++next_line; 4228 4229 return (next_line[0] == PARALLEL_SEPARATOR 4230 && next_line[1] == PARALLEL_SEPARATOR); 4231 } 4232 4233 static int 4234 tic54x_parse_parallel_insn_firstline (tic54x_insn *insn, char *line) 4235 { 4236 insn->tm = (insn_template *) hash_find (parop_hash, insn->mnemonic); 4237 if (!insn->tm) 4238 { 4239 as_bad (_("Unrecognized parallel instruction \"%s\""), 4240 insn->mnemonic); 4241 return 0; 4242 } 4243 4244 while (insn->tm->name && strcasecmp (insn->tm->name, 4245 insn->mnemonic) == 0) 4246 { 4247 insn->opcount = get_operands (insn->operands, line); 4248 if (insn->opcount < 0) 4249 return 0; 4250 if (insn->opcount == 2 4251 && operands_match (insn, &insn->operands[0], insn->opcount, 4252 insn->tm->operand_types, 2, 2)) 4253 { 4254 return 1; 4255 } 4256 ++(insn->tm); 4257 } 4258 /* Didn't find a matching parallel; try for a normal insn. */ 4259 return 0; 4260 } 4261 4262 /* Parse the second line of a two-line parallel instruction. */ 4263 4264 static int 4265 tic54x_parse_parallel_insn_lastline (tic54x_insn *insn, char *line) 4266 { 4267 int valid_mnemonic = 0; 4268 4269 insn->paropcount = get_operands (insn->paroperands, line); 4270 while (insn->tm->name && strcasecmp (insn->tm->name, 4271 insn->mnemonic) == 0) 4272 { 4273 if (strcasecmp (insn->tm->parname, insn->parmnemonic) == 0) 4274 { 4275 valid_mnemonic = 1; 4276 4277 if (insn->paropcount >= insn->tm->minops 4278 && insn->paropcount <= insn->tm->maxops 4279 && operands_match (insn, insn->paroperands, 4280 insn->paropcount, 4281 insn->tm->paroperand_types, 4282 insn->tm->minops, insn->tm->maxops)) 4283 return 1; 4284 } 4285 ++(insn->tm); 4286 } 4287 if (valid_mnemonic) 4288 as_bad (_("Invalid operand (s) for parallel instruction \"%s\""), 4289 insn->parmnemonic); 4290 else 4291 as_bad (_("Unrecognized parallel instruction combination \"%s || %s\""), 4292 insn->mnemonic, insn->parmnemonic); 4293 4294 return 0; 4295 } 4296 4297 /* If quotes found, return copy of line up to closing quote; 4298 otherwise up until terminator. 4299 If it's a string, pass as-is; otherwise attempt substitution symbol 4300 replacement on the value. */ 4301 4302 static char * 4303 subsym_get_arg (char *line, char *terminators, char **str, int nosub) 4304 { 4305 char *ptr = line; 4306 char *endp; 4307 int is_string = *line == '"'; 4308 int is_char = ISDIGIT (*line); 4309 4310 if (is_char) 4311 { 4312 while (ISDIGIT (*ptr)) 4313 ++ptr; 4314 endp = ptr; 4315 *str = xmalloc (ptr - line + 1); 4316 strncpy (*str, line, ptr - line); 4317 (*str)[ptr - line] = 0; 4318 } 4319 else if (is_string) 4320 { 4321 char *savedp = input_line_pointer; 4322 int len; 4323 4324 input_line_pointer = ptr; 4325 *str = demand_copy_C_string (&len); 4326 endp = input_line_pointer; 4327 input_line_pointer = savedp; 4328 4329 /* Do forced substitutions if requested. */ 4330 if (!nosub && **str == ':') 4331 *str = subsym_substitute (*str, 1); 4332 } 4333 else 4334 { 4335 char *term = terminators; 4336 char *value = NULL; 4337 4338 while (*ptr && *ptr != *term) 4339 { 4340 if (!*term) 4341 { 4342 term = terminators; 4343 ++ptr; 4344 } 4345 else 4346 ++term; 4347 } 4348 endp = ptr; 4349 *str = xmalloc (ptr - line + 1); 4350 strncpy (*str, line, ptr - line); 4351 (*str)[ptr - line] = 0; 4352 /* Do simple substitution, if available. */ 4353 if (!nosub && (value = subsym_lookup (*str, macro_level)) != NULL) 4354 *str = value; 4355 } 4356 4357 return endp; 4358 } 4359 4360 /* Replace the given substitution string. 4361 We start at the innermost macro level, so that existing locals remain local 4362 Note: we're treating macro args identically to .var's; I don't know if 4363 that's compatible w/TI's assembler. */ 4364 4365 static void 4366 subsym_create_or_replace (char *name, char *value) 4367 { 4368 int i; 4369 4370 for (i = macro_level; i > 0; i--) 4371 { 4372 if (hash_find (subsym_hash[i], name)) 4373 { 4374 hash_replace (subsym_hash[i], name, value); 4375 return; 4376 } 4377 } 4378 if (hash_find (subsym_hash[0], name)) 4379 hash_replace (subsym_hash[0], name, value); 4380 else 4381 hash_insert (subsym_hash[0], name, value); 4382 } 4383 4384 /* Look up the substitution string replacement for the given symbol. 4385 Start with the innermost macro substitution table given and work 4386 outwards. */ 4387 4388 static char * 4389 subsym_lookup (char *name, int nest_level) 4390 { 4391 char *value = hash_find (subsym_hash[nest_level], name); 4392 4393 if (value || nest_level == 0) 4394 return value; 4395 4396 return subsym_lookup (name, nest_level - 1); 4397 } 4398 4399 /* Do substitution-symbol replacement on the given line (recursively). 4400 return the argument if no substitution was done 4401 4402 Also look for built-in functions ($func (arg)) and local labels. 4403 4404 If FORCED is set, look for forced substitutions of the form ':SYMBOL:'. */ 4405 4406 static char * 4407 subsym_substitute (char *line, int forced) 4408 { 4409 /* For each apparent symbol, see if it's a substitution symbol, and if so, 4410 replace it in the input. */ 4411 char *replacement; /* current replacement for LINE. */ 4412 char *head; /* Start of line. */ 4413 char *ptr; /* Current examination point. */ 4414 int changed = 0; /* Did we make a substitution? */ 4415 int eval_line = 0; /* Is this line a .eval/.asg statement? */ 4416 int eval_symbol = 0; /* Are we in the middle of the symbol for 4417 .eval/.asg? */ 4418 char *eval_end = NULL; 4419 int recurse = 1; 4420 int line_conditional = 0; 4421 char *tmp; 4422 4423 /* Work with a copy of the input line. */ 4424 replacement = xmalloc (strlen (line) + 1); 4425 strcpy (replacement, line); 4426 4427 ptr = head = replacement; 4428 4429 /* Flag lines where we might need to replace a single '=' with two; 4430 GAS uses single '=' to assign macro args values, and possibly other 4431 places, so limit what we replace. */ 4432 if (strstr (line, ".if") 4433 || strstr (line, ".elseif") 4434 || strstr (line, ".break")) 4435 line_conditional = 1; 4436 4437 /* Watch out for .eval, so that we avoid doing substitution on the 4438 symbol being assigned a value. */ 4439 if (strstr (line, ".eval") || strstr (line, ".asg")) 4440 eval_line = 1; 4441 4442 /* If it's a macro definition, don't do substitution on the argument 4443 names. */ 4444 if (strstr (line, ".macro")) 4445 return line; 4446 4447 while (!is_end_of_line[(int) *ptr]) 4448 { 4449 int current_char = *ptr; 4450 4451 /* Need to update this since LINE may have been modified. */ 4452 if (eval_line) 4453 eval_end = strrchr (ptr, ','); 4454 4455 /* Replace triple double quotes with bounding quote/escapes. */ 4456 if (current_char == '"' && ptr[1] == '"' && ptr[2] == '"') 4457 { 4458 ptr[1] = '\\'; 4459 tmp = strstr (ptr + 2, "\"\"\""); 4460 if (tmp) 4461 tmp[0] = '\\'; 4462 changed = 1; 4463 } 4464 4465 /* Replace a single '=' with a '=='; 4466 for compatibility with older code only. */ 4467 if (line_conditional && current_char == '=') 4468 { 4469 if (ptr[1] == '=') 4470 { 4471 ptr += 2; 4472 continue; 4473 } 4474 *ptr++ = '\0'; 4475 tmp = xmalloc (strlen (head) + 2 + strlen (ptr) + 1); 4476 sprintf (tmp, "%s==%s", head, ptr); 4477 /* Continue examining after the '=='. */ 4478 ptr = tmp + strlen (head) + 2; 4479 free (replacement); 4480 head = replacement = tmp; 4481 changed = 1; 4482 } 4483 4484 /* Flag when we've reached the symbol part of .eval/.asg. */ 4485 if (eval_line && ptr >= eval_end) 4486 eval_symbol = 1; 4487 4488 /* For each apparent symbol, see if it's a substitution symbol, and if 4489 so, replace it in the input. */ 4490 if ((forced && current_char == ':') 4491 || (!forced && is_name_beginner (current_char))) 4492 { 4493 char *name; /* Symbol to be replaced. */ 4494 char *savedp = input_line_pointer; 4495 int c; 4496 char *value = NULL; 4497 char *tail; /* Rest of line after symbol. */ 4498 4499 /* Skip the colon. */ 4500 if (forced) 4501 ++ptr; 4502 4503 name = input_line_pointer = ptr; 4504 c = get_symbol_end (); 4505 /* '?' is not normally part of a symbol, but it IS part of a local 4506 label. */ 4507 if (c == '?') 4508 { 4509 *input_line_pointer++ = c; 4510 c = *input_line_pointer; 4511 *input_line_pointer = '\0'; 4512 } 4513 /* Avoid infinite recursion; if a symbol shows up a second time for 4514 substitution, leave it as is. */ 4515 if (hash_find (subsym_recurse_hash, name) == NULL) 4516 value = subsym_lookup (name, macro_level); 4517 else 4518 as_warn (_("%s symbol recursion stopped at " 4519 "second appearance of '%s'"), 4520 forced ? "Forced substitution" : "Substitution", name); 4521 ptr = tail = input_line_pointer; 4522 input_line_pointer = savedp; 4523 4524 /* Check for local labels; replace them with the appropriate 4525 substitution. */ 4526 if ((*name == '$' && ISDIGIT (name[1]) && name[2] == '\0') 4527 || name[strlen (name) - 1] == '?') 4528 { 4529 /* Use an existing identifier for that label if, available, or 4530 create a new, unique identifier. */ 4531 value = hash_find (local_label_hash[macro_level], name); 4532 if (value == NULL) 4533 { 4534 char digit[11]; 4535 char *namecopy = strcpy (xmalloc (strlen (name) + 1), name); 4536 4537 value = strcpy (xmalloc (strlen (name) + sizeof (digit) + 1), 4538 name); 4539 if (*value != '$') 4540 value[strlen (value) - 1] = '\0'; 4541 sprintf (digit, ".%d", local_label_id++); 4542 strcat (value, digit); 4543 hash_insert (local_label_hash[macro_level], namecopy, value); 4544 } 4545 /* Indicate where to continue looking for substitutions. */ 4546 ptr = tail; 4547 } 4548 /* Check for built-in subsym and math functions. */ 4549 else if (value != NULL && *name == '$') 4550 { 4551 subsym_proc_entry *entry = (subsym_proc_entry *) value; 4552 math_proc_entry *math_entry = hash_find (math_hash, name); 4553 char *arg1, *arg2 = NULL; 4554 4555 *ptr = c; 4556 if (entry == NULL) 4557 { 4558 as_bad (_("Unrecognized substitution symbol function")); 4559 break; 4560 } 4561 else if (*ptr != '(') 4562 { 4563 as_bad (_("Missing '(' after substitution symbol function")); 4564 break; 4565 } 4566 ++ptr; 4567 if (math_entry != NULL) 4568 { 4569 float farg1, farg2 = 0; 4570 volatile float fresult; 4571 4572 farg1 = (float) strtod (ptr, &ptr); 4573 if (math_entry->nargs == 2) 4574 { 4575 if (*ptr++ != ',') 4576 { 4577 as_bad (_("Expecting second argument")); 4578 break; 4579 } 4580 farg2 = (float) strtod (ptr, &ptr); 4581 } 4582 fresult = (*math_entry->proc) (farg1, farg2); 4583 value = xmalloc (128); 4584 if (math_entry->int_return) 4585 sprintf (value, "%d", (int) fresult); 4586 else 4587 sprintf (value, "%f", fresult); 4588 if (*ptr++ != ')') 4589 { 4590 as_bad (_("Extra junk in function call, expecting ')'")); 4591 break; 4592 } 4593 /* Don't bother recursing; the replacement isn't a 4594 symbol. */ 4595 recurse = 0; 4596 } 4597 else 4598 { 4599 int val; 4600 int arg_type[2] = { *ptr == '"' , 0 }; 4601 int ismember = !strcmp (entry->name, "$ismember"); 4602 4603 /* Parse one or two args, which must be a substitution 4604 symbol, string or a character-string constant. */ 4605 /* For all functions, a string or substitution symbol may be 4606 used, with the following exceptions: 4607 firstch/lastch: 2nd arg must be character constant 4608 ismember: both args must be substitution symbols. */ 4609 ptr = subsym_get_arg (ptr, ",)", &arg1, ismember); 4610 if (!arg1) 4611 break; 4612 if (entry->nargs == 2) 4613 { 4614 if (*ptr++ != ',') 4615 { 4616 as_bad (_("Function expects two arguments")); 4617 break; 4618 } 4619 /* Character constants are converted to numerics 4620 by the preprocessor. */ 4621 arg_type[1] = (ISDIGIT (*ptr)) ? 2 : (*ptr == '"'); 4622 ptr = subsym_get_arg (ptr, ")", &arg2, ismember); 4623 } 4624 /* Args checking. */ 4625 if ((!strcmp (entry->name, "$firstch") 4626 || !strcmp (entry->name, "$lastch")) 4627 && arg_type[1] != 2) 4628 { 4629 as_bad (_("Expecting character constant argument")); 4630 break; 4631 } 4632 if (ismember 4633 && (arg_type[0] != 0 || arg_type[1] != 0)) 4634 { 4635 as_bad (_("Both arguments must be substitution symbols")); 4636 break; 4637 } 4638 if (*ptr++ != ')') 4639 { 4640 as_bad (_("Extra junk in function call, expecting ')'")); 4641 break; 4642 } 4643 val = (*entry->proc) (arg1, arg2); 4644 value = xmalloc (64); 4645 sprintf (value, "%d", val); 4646 } 4647 /* Fix things up to replace the entire expression, not just the 4648 function name. */ 4649 tail = ptr; 4650 c = *tail; 4651 } 4652 4653 if (value != NULL && !eval_symbol) 4654 { 4655 /* Replace the symbol with its string replacement and 4656 continue. Recursively replace VALUE until either no 4657 substitutions are performed, or a substitution that has been 4658 previously made is encountered again. 4659 4660 put the symbol into the recursion hash table so we only 4661 try to replace a symbol once. */ 4662 if (recurse) 4663 { 4664 hash_insert (subsym_recurse_hash, name, name); 4665 value = subsym_substitute (value, macro_level > 0); 4666 hash_delete (subsym_recurse_hash, name, FALSE); 4667 } 4668 4669 /* Temporarily zero-terminate where the symbol started. */ 4670 *name = 0; 4671 if (forced) 4672 { 4673 if (c == '(') 4674 { 4675 /* Subscripted substitution symbol -- use just the 4676 indicated portion of the string; the description 4677 kinda indicates that forced substitution is not 4678 supposed to be recursive, but I'm not sure. */ 4679 unsigned beg, len = 1; /* default to a single char */ 4680 char *newval = strcpy (xmalloc (strlen (value) + 1), 4681 value); 4682 4683 savedp = input_line_pointer; 4684 input_line_pointer = tail + 1; 4685 beg = get_absolute_expression (); 4686 if (beg < 1) 4687 { 4688 as_bad (_("Invalid subscript (use 1 to %d)"), 4689 (int) strlen (value)); 4690 break; 4691 } 4692 if (*input_line_pointer == ',') 4693 { 4694 ++input_line_pointer; 4695 len = get_absolute_expression (); 4696 if (beg + len > strlen (value)) 4697 { 4698 as_bad (_("Invalid length (use 0 to %d"), 4699 (int) strlen (value) - beg); 4700 break; 4701 } 4702 } 4703 newval += beg - 1; 4704 newval[len] = 0; 4705 tail = input_line_pointer; 4706 if (*tail++ != ')') 4707 { 4708 as_bad (_("Missing ')' in subscripted substitution " 4709 "symbol expression")); 4710 break; 4711 } 4712 c = *tail; 4713 input_line_pointer = savedp; 4714 4715 value = newval; 4716 } 4717 name[-1] = 0; 4718 } 4719 tmp = xmalloc (strlen (head) + strlen (value) + 4720 strlen (tail + 1) + 2); 4721 strcpy (tmp, head); 4722 strcat (tmp, value); 4723 /* Make sure forced substitutions are properly terminated. */ 4724 if (forced) 4725 { 4726 if (c != ':') 4727 { 4728 as_bad (_("Missing forced substitution terminator ':'")); 4729 break; 4730 } 4731 ++tail; 4732 } 4733 else 4734 /* Restore the character after the symbol end. */ 4735 *tail = c; 4736 strcat (tmp, tail); 4737 /* Continue examining after the replacement value. */ 4738 ptr = tmp + strlen (head) + strlen (value); 4739 free (replacement); 4740 head = replacement = tmp; 4741 changed = 1; 4742 } 4743 else 4744 *ptr = c; 4745 } 4746 else 4747 { 4748 ++ptr; 4749 } 4750 } 4751 4752 if (changed) 4753 return replacement; 4754 else 4755 return line; 4756 } 4757 4758 /* We use this to handle substitution symbols 4759 hijack input_line_pointer, replacing it with our substituted string. 4760 4761 .sslist should enable listing the line after replacements are made... 4762 4763 returns the new buffer limit. */ 4764 4765 void 4766 tic54x_start_line_hook (void) 4767 { 4768 char *line, *endp; 4769 char *replacement = NULL; 4770 4771 /* Work with a copy of the input line, including EOL char. */ 4772 endp = input_line_pointer; 4773 while (!is_end_of_line[(int) *endp++]) 4774 ; 4775 line = xmalloc (endp - input_line_pointer + 1); 4776 strncpy (line, input_line_pointer, endp - input_line_pointer + 1); 4777 line[endp - input_line_pointer] = 0; 4778 4779 /* Scan ahead for parallel insns. */ 4780 parallel_on_next_line_hint = next_line_shows_parallel (endp); 4781 4782 /* If within a macro, first process forced replacements. */ 4783 if (macro_level > 0) 4784 replacement = subsym_substitute (line, 1); 4785 else 4786 replacement = line; 4787 replacement = subsym_substitute (replacement, 0); 4788 4789 if (replacement != line) 4790 { 4791 char *tmp = replacement; 4792 char *comment = strchr (replacement, ';'); 4793 char endc = replacement[strlen (replacement) - 1]; 4794 4795 /* Clean up the replacement; we'd prefer to have this done by the 4796 standard preprocessing equipment (maybe do_scrub_chars?) 4797 but for now, do a quick-and-dirty. */ 4798 if (comment != NULL) 4799 { 4800 comment[0] = endc; 4801 comment[1] = 0; 4802 --comment; 4803 } 4804 else 4805 comment = replacement + strlen (replacement) - 1; 4806 4807 /* Trim trailing whitespace. */ 4808 while (ISSPACE (*comment)) 4809 { 4810 comment[0] = endc; 4811 comment[1] = 0; 4812 --comment; 4813 } 4814 4815 /* Compact leading whitespace. */ 4816 while (ISSPACE (tmp[0]) && ISSPACE (tmp[1])) 4817 ++tmp; 4818 4819 input_line_pointer = endp; 4820 input_scrub_insert_line (tmp); 4821 free (replacement); 4822 free (line); 4823 /* Keep track of whether we've done a substitution. */ 4824 substitution_line = 1; 4825 } 4826 else 4827 { 4828 /* No change. */ 4829 free (line); 4830 substitution_line = 0; 4831 } 4832 } 4833 4834 /* This is the guts of the machine-dependent assembler. STR points to a 4835 machine dependent instruction. This function is supposed to emit 4836 the frags/bytes it assembles to. */ 4837 void 4838 md_assemble (char *line) 4839 { 4840 static int repeat_slot = 0; 4841 static int delay_slots = 0; /* How many delay slots left to fill? */ 4842 static int is_parallel = 0; 4843 static tic54x_insn insn; 4844 char *lptr; 4845 char *savedp = input_line_pointer; 4846 int c; 4847 4848 input_line_pointer = line; 4849 c = get_symbol_end (); 4850 4851 if (cpu == VNONE) 4852 cpu = V542; 4853 if (address_mode_needs_set) 4854 { 4855 set_address_mode (amode); 4856 address_mode_needs_set = 0; 4857 } 4858 if (cpu_needs_set) 4859 { 4860 set_cpu (cpu); 4861 cpu_needs_set = 0; 4862 } 4863 assembly_begun = 1; 4864 4865 if (is_parallel) 4866 { 4867 is_parallel = 0; 4868 4869 strcpy (insn.parmnemonic, line); 4870 lptr = input_line_pointer; 4871 *lptr = c; 4872 input_line_pointer = savedp; 4873 4874 if (tic54x_parse_parallel_insn_lastline (&insn, lptr)) 4875 { 4876 int words = build_insn (&insn); 4877 4878 if (delay_slots != 0) 4879 { 4880 if (words > delay_slots) 4881 { 4882 as_bad (_("Instruction does not fit in available delay " 4883 "slots (%d-word insn, %d slots left)"), 4884 words, delay_slots); 4885 delay_slots = 0; 4886 return; 4887 } 4888 delay_slots -= words; 4889 } 4890 } 4891 return; 4892 } 4893 4894 memset (&insn, 0, sizeof (insn)); 4895 strcpy (insn.mnemonic, line); 4896 lptr = input_line_pointer; 4897 *lptr = c; 4898 input_line_pointer = savedp; 4899 4900 /* See if this line is part of a parallel instruction; if so, either this 4901 line or the next line will have the "||" specifier preceding the 4902 mnemonic, and we look for it in the parallel insn hash table. */ 4903 if (strstr (line, "||") != NULL || parallel_on_next_line_hint) 4904 { 4905 char *tmp = strstr (line, "||"); 4906 if (tmp != NULL) 4907 *tmp = '\0'; 4908 4909 if (tic54x_parse_parallel_insn_firstline (&insn, lptr)) 4910 { 4911 is_parallel = 1; 4912 /* If the parallel part is on the same line, process it now, 4913 otherwise let the assembler pick up the next line for us. */ 4914 if (tmp != NULL) 4915 { 4916 while (ISSPACE (tmp[2])) 4917 ++tmp; 4918 md_assemble (tmp + 2); 4919 } 4920 } 4921 else 4922 { 4923 as_bad (_("Unrecognized parallel instruction '%s'"), line); 4924 } 4925 return; 4926 } 4927 4928 if (tic54x_parse_insn (&insn, lptr)) 4929 { 4930 int words; 4931 4932 if ((insn.tm->flags & FL_LP) 4933 && cpu != V545LP && cpu != V546LP) 4934 { 4935 as_bad (_("Instruction '%s' requires an LP cpu version"), 4936 insn.tm->name); 4937 return; 4938 } 4939 if ((insn.tm->flags & FL_FAR) 4940 && amode != far_mode) 4941 { 4942 as_bad (_("Instruction '%s' requires far mode addressing"), 4943 insn.tm->name); 4944 return; 4945 } 4946 4947 words = build_insn (&insn); 4948 4949 /* Is this instruction in a delay slot? */ 4950 if (delay_slots) 4951 { 4952 if (words > delay_slots) 4953 { 4954 as_warn (_("Instruction does not fit in available delay " 4955 "slots (%d-word insn, %d slots left). " 4956 "Resulting behavior is undefined."), 4957 words, delay_slots); 4958 delay_slots = 0; 4959 return; 4960 } 4961 /* Branches in delay slots are not allowed. */ 4962 if (insn.tm->flags & FL_BMASK) 4963 { 4964 as_warn (_("Instructions which cause PC discontinuity are not " 4965 "allowed in a delay slot. " 4966 "Resulting behavior is undefined.")); 4967 } 4968 delay_slots -= words; 4969 } 4970 4971 /* Is this instruction the target of a repeat? */ 4972 if (repeat_slot) 4973 { 4974 if (insn.tm->flags & FL_NR) 4975 as_warn (_("'%s' is not repeatable. " 4976 "Resulting behavior is undefined."), 4977 insn.tm->name); 4978 else if (insn.is_lkaddr) 4979 as_warn (_("Instructions using long offset modifiers or absolute " 4980 "addresses are not repeatable. " 4981 "Resulting behavior is undefined.")); 4982 repeat_slot = 0; 4983 } 4984 4985 /* Make sure we check the target of a repeat instruction. */ 4986 if (insn.tm->flags & B_REPEAT) 4987 { 4988 repeat_slot = 1; 4989 /* FIXME -- warn if repeat_slot == 1 at EOF. */ 4990 } 4991 /* Make sure we check our delay slots for validity. */ 4992 if (insn.tm->flags & FL_DELAY) 4993 { 4994 delay_slots = 2; 4995 /* FIXME -- warn if delay_slots != 0 at EOF. */ 4996 } 4997 } 4998 } 4999 5000 /* Do a final adjustment on the symbol table; in this case, make sure we have 5001 a ".file" symbol. */ 5002 5003 void 5004 tic54x_adjust_symtab (void) 5005 { 5006 if (symbol_rootP == NULL 5007 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE) 5008 { 5009 char *filename; 5010 unsigned lineno; 5011 as_where (&filename, &lineno); 5012 c_dot_file_symbol (filename, 0); 5013 } 5014 } 5015 5016 /* In order to get gas to ignore any | chars at the start of a line, 5017 this function returns true if a | is found in a line. 5018 This lets us process parallel instructions, which span two lines. */ 5019 5020 int 5021 tic54x_unrecognized_line (int c) 5022 { 5023 return c == PARALLEL_SEPARATOR; 5024 } 5025 5026 /* Watch for local labels of the form $[0-9] and [_a-zA-Z][_a-zA-Z0-9]*? 5027 Encode their names so that only we see them and can map them to the 5028 appropriate places. 5029 FIXME -- obviously this isn't done yet. These locals still show up in the 5030 symbol table. */ 5031 void 5032 tic54x_define_label (symbolS *sym) 5033 { 5034 /* Just in case we need this later; note that this is not necessarily the 5035 same thing as line_label... 5036 When aligning or assigning labels to fields, sometimes the label is 5037 assigned other than the address at which the label appears. 5038 FIXME -- is this really needed? I think all the proper label assignment 5039 is done in tic54x_cons. */ 5040 last_label_seen = sym; 5041 } 5042 5043 /* Try to parse something that normal parsing failed at. */ 5044 5045 symbolS * 5046 tic54x_undefined_symbol (char *name) 5047 { 5048 symbol *sym; 5049 5050 /* Not sure how to handle predefined symbols. */ 5051 if ((sym = (symbol *) hash_find (cc_hash, name)) != NULL || 5052 (sym = (symbol *) hash_find (cc2_hash, name)) != NULL || 5053 (sym = (symbol *) hash_find (cc3_hash, name)) != NULL || 5054 (sym = (symbol *) hash_find (misc_symbol_hash, name)) != NULL || 5055 (sym = (symbol *) hash_find (sbit_hash, name)) != NULL) 5056 { 5057 return symbol_new (name, reg_section, 5058 (valueT) sym->value, 5059 &zero_address_frag); 5060 } 5061 5062 if ((sym = (symbol *) hash_find (reg_hash, name)) != NULL || 5063 (sym = (symbol *) hash_find (mmreg_hash, name)) != NULL || 5064 !strcasecmp (name, "a") || !strcasecmp (name, "b")) 5065 { 5066 return symbol_new (name, reg_section, 5067 (valueT) sym ? sym->value : 0, 5068 &zero_address_frag); 5069 } 5070 5071 return NULL; 5072 } 5073 5074 /* Parse a name in an expression before the expression parser takes a stab at 5075 it. */ 5076 5077 int 5078 tic54x_parse_name (char *name ATTRIBUTE_UNUSED, 5079 expressionS *expn ATTRIBUTE_UNUSED) 5080 { 5081 return 0; 5082 } 5083 5084 char * 5085 md_atof (int type, char *literalP, int *sizeP) 5086 { 5087 /* Target data is little-endian, but floats are stored 5088 big-"word"ian. ugh. */ 5089 return ieee_md_atof (type, literalP, sizeP, TRUE); 5090 } 5091 5092 arelent * 5093 tc_gen_reloc (asection *section, fixS *fixP) 5094 { 5095 arelent *rel; 5096 bfd_reloc_code_real_type code = fixP->fx_r_type; 5097 asymbol *sym = symbol_get_bfdsym (fixP->fx_addsy); 5098 5099 rel = (arelent *) xmalloc (sizeof (arelent)); 5100 rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); 5101 *rel->sym_ptr_ptr = sym; 5102 /* We assume that all rel->address are host byte offsets. */ 5103 rel->address = fixP->fx_frag->fr_address + fixP->fx_where; 5104 rel->address /= OCTETS_PER_BYTE; 5105 rel->howto = bfd_reloc_type_lookup (stdoutput, code); 5106 if (!strcmp (sym->name, section->name)) 5107 rel->howto += HOWTO_BANK; 5108 5109 if (!rel->howto) 5110 { 5111 const char *name = S_GET_NAME (fixP->fx_addsy); 5112 if (name == NULL) 5113 name = "<unknown>"; 5114 as_fatal ("Cannot generate relocation type for symbol %s, code %s", 5115 name, bfd_get_reloc_code_name (code)); 5116 return NULL; 5117 } 5118 return rel; 5119 } 5120 5121 /* Handle cons expressions. */ 5122 5123 void 5124 tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *expn, 5125 bfd_reloc_code_real_type r) 5126 { 5127 switch (octets) 5128 { 5129 default: 5130 as_bad (_("Unsupported relocation size %d"), octets); 5131 r = BFD_RELOC_TIC54X_16_OF_23; 5132 break; 5133 case 2: 5134 r = BFD_RELOC_TIC54X_16_OF_23; 5135 break; 5136 case 4: 5137 /* TI assembler always uses this, regardless of addressing mode. */ 5138 if (emitting_long) 5139 r = BFD_RELOC_TIC54X_23; 5140 else 5141 /* We never want to directly generate this; this is provided for 5142 stabs support only. */ 5143 r = BFD_RELOC_32; 5144 break; 5145 } 5146 fix_new_exp (frag, where, octets, expn, 0, r); 5147 } 5148 5149 /* Attempt to simplify or even eliminate a fixup. 5150 To indicate that a fixup has been eliminated, set fixP->fx_done. 5151 5152 If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry. */ 5153 5154 void 5155 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) 5156 { 5157 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; 5158 valueT val = * valP; 5159 5160 switch (fixP->fx_r_type) 5161 { 5162 default: 5163 as_fatal ("Bad relocation type: 0x%02x", fixP->fx_r_type); 5164 return; 5165 case BFD_RELOC_TIC54X_MS7_OF_23: 5166 val = (val >> 16) & 0x7F; 5167 /* Fall through. */ 5168 case BFD_RELOC_TIC54X_16_OF_23: 5169 case BFD_RELOC_16: 5170 bfd_put_16 (stdoutput, val, buf); 5171 /* Indicate what we're actually writing, so that we don't get warnings 5172 about exceeding available space. */ 5173 *valP = val & 0xFFFF; 5174 break; 5175 case BFD_RELOC_TIC54X_PARTLS7: 5176 bfd_put_16 (stdoutput, 5177 (bfd_get_16 (stdoutput, buf) & 0xFF80) | (val & 0x7F), 5178 buf); 5179 /* Indicate what we're actually writing, so that we don't get warnings 5180 about exceeding available space. */ 5181 *valP = val & 0x7F; 5182 break; 5183 case BFD_RELOC_TIC54X_PARTMS9: 5184 /* TI assembler doesn't shift its encoding for relocatable files, and is 5185 thus incompatible with this implementation's relocatable files. */ 5186 bfd_put_16 (stdoutput, 5187 (bfd_get_16 (stdoutput, buf) & 0xFE00) | (val >> 7), 5188 buf); 5189 break; 5190 case BFD_RELOC_32: 5191 case BFD_RELOC_TIC54X_23: 5192 bfd_put_32 (stdoutput, 5193 (bfd_get_32 (stdoutput, buf) & 0xFF800000) | val, 5194 buf); 5195 break; 5196 } 5197 5198 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) 5199 fixP->fx_done = 1; 5200 } 5201 5202 /* This is our chance to record section alignment 5203 don't need to do anything here, since BFD does the proper encoding. */ 5204 5205 valueT 5206 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT section_size) 5207 { 5208 return section_size; 5209 } 5210 5211 long 5212 md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED) 5213 { 5214 return 0; 5215 } 5216 5217 /* Mostly little-endian, but longwords (4 octets) get MS word stored 5218 first. */ 5219 5220 void 5221 tic54x_number_to_chars (char *buf, valueT val, int n) 5222 { 5223 if (n != 4) 5224 number_to_chars_littleendian (buf, val, n); 5225 else 5226 { 5227 number_to_chars_littleendian (buf , val >> 16 , 2); 5228 number_to_chars_littleendian (buf + 2, val & 0xFFFF, 2); 5229 } 5230 } 5231 5232 int 5233 tic54x_estimate_size_before_relax (fragS *frag ATTRIBUTE_UNUSED, 5234 segT seg ATTRIBUTE_UNUSED) 5235 { 5236 return 0; 5237 } 5238 5239 /* We use this to handle bit allocations which we couldn't handle before due 5240 to symbols being in different frags. return number of octets added. */ 5241 5242 int 5243 tic54x_relax_frag (fragS *frag, long stretch ATTRIBUTE_UNUSED) 5244 { 5245 symbolS *sym = frag->fr_symbol; 5246 int growth = 0; 5247 int i; 5248 5249 if (sym != NULL) 5250 { 5251 struct bit_info *bi = (struct bit_info *) frag->fr_opcode; 5252 int bit_offset = frag_bit_offset (frag_prev (frag, bi->seg), bi->seg); 5253 int size = S_GET_VALUE (sym); 5254 fragS *prev_frag = bit_offset_frag (frag_prev (frag, bi->seg), bi->seg); 5255 int available = 16 - bit_offset; 5256 5257 if (symbol_get_frag (sym) != &zero_address_frag 5258 || S_IS_COMMON (sym) 5259 || !S_IS_DEFINED (sym)) 5260 as_bad_where (frag->fr_file, frag->fr_line, 5261 _("non-absolute value used with .space/.bes")); 5262 5263 if (size < 0) 5264 { 5265 as_warn (_("negative value ignored in %s"), 5266 bi->type == TYPE_SPACE ? ".space" : 5267 bi->type == TYPE_BES ? ".bes" : ".field"); 5268 growth = 0; 5269 frag->tc_frag_data = frag->fr_fix = 0; 5270 return 0; 5271 } 5272 5273 if (bi->type == TYPE_FIELD) 5274 { 5275 /* Bit fields of 16 or larger will have already been handled. */ 5276 if (bit_offset != 0 && available >= size) 5277 { 5278 char *p = prev_frag->fr_literal; 5279 5280 valueT value = bi->value; 5281 value <<= available - size; 5282 value |= ((unsigned short) p[1] << 8) | p[0]; 5283 md_number_to_chars (p, value, 2); 5284 if ((prev_frag->tc_frag_data += size) == 16) 5285 prev_frag->tc_frag_data = 0; 5286 if (bi->sym) 5287 symbol_set_frag (bi->sym, prev_frag); 5288 /* This frag is no longer used. */ 5289 growth = -frag->fr_fix; 5290 frag->fr_fix = 0; 5291 frag->tc_frag_data = 0; 5292 } 5293 else 5294 { 5295 char *p = frag->fr_literal; 5296 5297 valueT value = bi->value << (16 - size); 5298 md_number_to_chars (p, value, 2); 5299 if ((frag->tc_frag_data = size) == 16) 5300 frag->tc_frag_data = 0; 5301 growth = 0; 5302 } 5303 } 5304 else 5305 { 5306 if (bit_offset != 0 && bit_offset < 16) 5307 { 5308 if (available >= size) 5309 { 5310 if ((prev_frag->tc_frag_data += size) == 16) 5311 prev_frag->tc_frag_data = 0; 5312 if (bi->sym) 5313 symbol_set_frag (bi->sym, prev_frag); 5314 /* This frag is no longer used. */ 5315 growth = -frag->fr_fix; 5316 frag->fr_fix = 0; 5317 frag->tc_frag_data = 0; 5318 goto getout; 5319 } 5320 if (bi->type == TYPE_SPACE && bi->sym) 5321 symbol_set_frag (bi->sym, prev_frag); 5322 size -= available; 5323 } 5324 growth = (size + 15) / 16 * OCTETS_PER_BYTE - frag->fr_fix; 5325 for (i = 0; i < growth; i++) 5326 frag->fr_literal[i] = 0; 5327 frag->fr_fix = growth; 5328 frag->tc_frag_data = size % 16; 5329 /* Make sure any BES label points to the LAST word allocated. */ 5330 if (bi->type == TYPE_BES && bi->sym) 5331 S_SET_VALUE (bi->sym, frag->fr_fix / OCTETS_PER_BYTE - 1); 5332 } 5333 getout: 5334 frag->fr_symbol = 0; 5335 frag->fr_opcode = 0; 5336 free ((void *) bi); 5337 } 5338 return growth; 5339 } 5340 5341 void 5342 tic54x_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, 5343 segT seg ATTRIBUTE_UNUSED, 5344 fragS *frag) 5345 { 5346 /* Offset is in bytes. */ 5347 frag->fr_offset = (frag->fr_next->fr_address 5348 - frag->fr_address 5349 - frag->fr_fix) / frag->fr_var; 5350 if (frag->fr_offset < 0) 5351 { 5352 as_bad_where (frag->fr_file, frag->fr_line, 5353 _("attempt to .space/.bes backwards? (%ld)"), 5354 (long) frag->fr_offset); 5355 } 5356 frag->fr_type = rs_space; 5357 } 5358 5359 /* We need to avoid having labels defined for certain directives/pseudo-ops 5360 since once the label is defined, it's in the symbol table for good. TI 5361 syntax puts the symbol *before* the pseudo (which is kinda like MRI syntax, 5362 I guess, except I've never seen a definition of MRI syntax). 5363 5364 C is the character that used to be at *REST, which points to the end of the 5365 label. 5366 5367 Don't allow labels to start with '.' */ 5368 5369 int 5370 tic54x_start_label (int c, char *rest) 5371 { 5372 /* If within .struct/.union, no auto line labels, please. */ 5373 if (current_stag != NULL) 5374 return 0; 5375 5376 /* Disallow labels starting with "." */ 5377 if (c != ':') 5378 { 5379 char *label = rest; 5380 5381 while (!is_end_of_line[(int) label[-1]]) 5382 --label; 5383 if (*label == '.') 5384 { 5385 as_bad (_("Invalid label '%s'"), label); 5386 return 0; 5387 } 5388 } 5389 5390 if (is_end_of_line[(int) c]) 5391 return 1; 5392 5393 if (ISSPACE (c)) 5394 while (ISSPACE (c = *++rest)) 5395 ; 5396 if (c == '.') 5397 { 5398 /* Don't let colon () define a label for any of these... */ 5399 return (strncasecmp (rest, ".tag", 4) != 0 || !ISSPACE (rest[4])) 5400 && (strncasecmp (rest, ".struct", 7) != 0 || !ISSPACE (rest[7])) 5401 && (strncasecmp (rest, ".union", 6) != 0 || !ISSPACE (rest[6])) 5402 && (strncasecmp (rest, ".macro", 6) != 0 || !ISSPACE (rest[6])) 5403 && (strncasecmp (rest, ".set", 4) != 0 || !ISSPACE (rest[4])) 5404 && (strncasecmp (rest, ".equ", 4) != 0 || !ISSPACE (rest[4])); 5405 } 5406 5407 return 1; 5408 } 5409