1/* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30 2 Copyright (C) 1998-2017 Free Software Foundation, Inc. 3 Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au) 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 TMS320C30 machine specific gas. 23 Written by Steven Haworth (steve@pm.cse.rmit.edu.au). 24 Bugs & suggestions are completely welcome. This is free software. 25 Please help us make it better. */ 26 27#include "as.h" 28#include "safe-ctype.h" 29#include "opcode/tic30.h" 30 31/* Put here all non-digit non-letter characters that may occur in an 32 operand. */ 33static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]"; 34static const char *ordinal_names[] = 35{ 36 N_("first"), N_("second"), N_("third"), N_("fourth"), N_("fifth") 37}; 38 39const char comment_chars[] = ";"; 40const char line_comment_chars[] = "*"; 41const char line_separator_chars[] = ""; 42 43const char *md_shortopts = ""; 44struct option md_longopts[] = 45{ 46 {NULL, no_argument, NULL, 0} 47}; 48 49size_t md_longopts_size = sizeof (md_longopts); 50 51/* Chars that mean this number is a floating point constant. 52 As in 0f12.456 53 or 0d1.2345e12. */ 54const char FLT_CHARS[] = "fFdDxX"; 55 56/* Chars that can be used to separate mant from exp in floating point 57 nums. */ 58const char EXP_CHARS[] = "eE"; 59 60/* Tables for lexical analysis. */ 61static char opcode_chars[256]; 62static char register_chars[256]; 63static char operand_chars[256]; 64static char space_chars[256]; 65static char identifier_chars[256]; 66static char digit_chars[256]; 67 68/* Lexical macros. */ 69#define is_opcode_char(x) (opcode_chars [(unsigned char) x]) 70#define is_operand_char(x) (operand_chars [(unsigned char) x]) 71#define is_register_char(x) (register_chars [(unsigned char) x]) 72#define is_space_char(x) (space_chars [(unsigned char) x]) 73#define is_identifier_char(x) (identifier_chars [(unsigned char) x]) 74#define is_digit_char(x) (digit_chars [(unsigned char) x]) 75 76const pseudo_typeS md_pseudo_table[] = 77{ 78 {0, 0, 0} 79}; 80 81static int ATTRIBUTE_PRINTF_1 82debug (const char *string, ...) 83{ 84 if (flag_debug) 85 { 86 char str[100]; 87 va_list argptr; 88 89 va_start (argptr, string); 90 vsprintf (str, string, argptr); 91 va_end (argptr); 92 if (str[0] == '\0') 93 return (0); 94 fputs (str, USE_STDOUT ? stdout : stderr); 95 return strlen (str); 96 } 97 else 98 return 0; 99} 100 101/* Hash table for opcode lookup. */ 102static struct hash_control *op_hash; 103/* Hash table for parallel opcode lookup. */ 104static struct hash_control *parop_hash; 105/* Hash table for register lookup. */ 106static struct hash_control *reg_hash; 107/* Hash table for indirect addressing lookup. */ 108static struct hash_control *ind_hash; 109 110void 111md_begin (void) 112{ 113 const char *hash_err; 114 115 debug ("In md_begin()\n"); 116 op_hash = hash_new (); 117 118 { 119 const insn_template *current_optab = tic30_optab; 120 121 for (; current_optab < tic30_optab_end; current_optab++) 122 { 123 hash_err = hash_insert (op_hash, current_optab->name, 124 (char *) current_optab); 125 if (hash_err) 126 as_fatal ("Internal Error: Can't Hash %s: %s", 127 current_optab->name, hash_err); 128 } 129 } 130 131 parop_hash = hash_new (); 132 133 { 134 const partemplate *current_parop = tic30_paroptab; 135 136 for (; current_parop < tic30_paroptab_end; current_parop++) 137 { 138 hash_err = hash_insert (parop_hash, current_parop->name, 139 (char *) current_parop); 140 if (hash_err) 141 as_fatal ("Internal Error: Can't Hash %s: %s", 142 current_parop->name, hash_err); 143 } 144 } 145 146 reg_hash = hash_new (); 147 148 { 149 const reg *current_reg = tic30_regtab; 150 151 for (; current_reg < tic30_regtab_end; current_reg++) 152 { 153 hash_err = hash_insert (reg_hash, current_reg->name, 154 (char *) current_reg); 155 if (hash_err) 156 as_fatal ("Internal Error: Can't Hash %s: %s", 157 current_reg->name, hash_err); 158 } 159 } 160 161 ind_hash = hash_new (); 162 163 { 164 const ind_addr_type *current_ind = tic30_indaddr_tab; 165 166 for (; current_ind < tic30_indaddrtab_end; current_ind++) 167 { 168 hash_err = hash_insert (ind_hash, current_ind->syntax, 169 (char *) current_ind); 170 if (hash_err) 171 as_fatal ("Internal Error: Can't Hash %s: %s", 172 current_ind->syntax, hash_err); 173 } 174 } 175 176 /* Fill in lexical tables: opcode_chars, operand_chars, space_chars. */ 177 { 178 int c; 179 char *p; 180 181 for (c = 0; c < 256; c++) 182 { 183 if (ISLOWER (c) || ISDIGIT (c)) 184 { 185 opcode_chars[c] = c; 186 register_chars[c] = c; 187 } 188 else if (ISUPPER (c)) 189 { 190 opcode_chars[c] = TOLOWER (c); 191 register_chars[c] = opcode_chars[c]; 192 } 193 else if (c == ')' || c == '(') 194 register_chars[c] = c; 195 196 if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c)) 197 operand_chars[c] = c; 198 199 if (ISDIGIT (c) || c == '-') 200 digit_chars[c] = c; 201 202 if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c)) 203 identifier_chars[c] = c; 204 205 if (c == ' ' || c == '\t') 206 space_chars[c] = c; 207 208 if (c == '_') 209 opcode_chars[c] = c; 210 } 211 for (p = operand_special_chars; *p != '\0'; p++) 212 operand_chars[(unsigned char) *p] = *p; 213 } 214} 215 216/* Address Mode OR values. */ 217#define AM_Register 0x00000000 218#define AM_Direct 0x00200000 219#define AM_Indirect 0x00400000 220#define AM_Immediate 0x00600000 221#define AM_NotReq 0xFFFFFFFF 222 223/* PC Relative OR values. */ 224#define PC_Register 0x00000000 225#define PC_Relative 0x02000000 226 227typedef struct 228{ 229 unsigned op_type; 230 struct 231 { 232 int resolved; 233 unsigned address; 234 char *label; 235 expressionS direct_expr; 236 } direct; 237 struct 238 { 239 unsigned mod; 240 int ARnum; 241 unsigned char disp; 242 } indirect; 243 struct 244 { 245 unsigned opcode; 246 } reg; 247 struct 248 { 249 int resolved; 250 int decimal_found; 251 float f_number; 252 int s_number; 253 unsigned int u_number; 254 char *label; 255 expressionS imm_expr; 256 } immediate; 257} operand; 258 259insn_template *opcode; 260 261struct tic30_insn 262{ 263 insn_template *tm; /* Template of current instruction. */ 264 unsigned opcode; /* Final opcode. */ 265 unsigned int operands; /* Number of given operands. */ 266 /* Type of operand given in instruction. */ 267 operand *operand_type[MAX_OPERANDS]; 268 unsigned addressing_mode; /* Final addressing mode of instruction. */ 269}; 270 271struct tic30_insn insn; 272static int found_parallel_insn; 273 274static char output_invalid_buf[sizeof (unsigned char) * 2 + 6]; 275 276static char * 277output_invalid (char c) 278{ 279 if (ISPRINT (c)) 280 snprintf (output_invalid_buf, sizeof (output_invalid_buf), 281 "'%c'", c); 282 else 283 snprintf (output_invalid_buf, sizeof (output_invalid_buf), 284 "(0x%x)", (unsigned char) c); 285 return output_invalid_buf; 286} 287 288/* next_line points to the next line after the current instruction 289 (current_line). Search for the parallel bars, and if found, merge two 290 lines into internal syntax for a parallel instruction: 291 q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2] 292 By this stage, all comments are scrubbed, and only the bare lines are 293 given. */ 294 295#define NONE 0 296#define START_OPCODE 1 297#define END_OPCODE 2 298#define START_OPERANDS 3 299#define END_OPERANDS 4 300 301static char * 302tic30_find_parallel_insn (char *current_line, char *next_line) 303{ 304 int found_parallel = 0; 305 char first_opcode[256]; 306 char second_opcode[256]; 307 char first_operands[256]; 308 char second_operands[256]; 309 char *parallel_insn; 310 311 debug ("In tic30_find_parallel_insn()\n"); 312 while (!is_end_of_line[(unsigned char) *next_line]) 313 { 314 if (*next_line == PARALLEL_SEPARATOR 315 && *(next_line + 1) == PARALLEL_SEPARATOR) 316 { 317 found_parallel = 1; 318 next_line++; 319 break; 320 } 321 next_line++; 322 } 323 if (!found_parallel) 324 return NULL; 325 debug ("Found a parallel instruction\n"); 326 327 { 328 int i; 329 char *op, *operands, *line; 330 331 for (i = 0; i < 2; i++) 332 { 333 if (i == 0) 334 { 335 op = &first_opcode[0]; 336 operands = &first_operands[0]; 337 line = current_line; 338 } 339 else 340 { 341 op = &second_opcode[0]; 342 operands = &second_operands[0]; 343 line = next_line; 344 } 345 346 { 347 int search_status = NONE; 348 int char_ptr = 0; 349 char c; 350 351 while (!is_end_of_line[(unsigned char) (c = *line)]) 352 { 353 if (is_opcode_char (c) && search_status == NONE) 354 { 355 op[char_ptr++] = TOLOWER (c); 356 search_status = START_OPCODE; 357 } 358 else if (is_opcode_char (c) && search_status == START_OPCODE) 359 op[char_ptr++] = TOLOWER (c); 360 else if (!is_opcode_char (c) && search_status == START_OPCODE) 361 { 362 op[char_ptr] = '\0'; 363 char_ptr = 0; 364 search_status = END_OPCODE; 365 } 366 else if (is_operand_char (c) && search_status == START_OPERANDS) 367 operands[char_ptr++] = c; 368 369 if (is_operand_char (c) && search_status == END_OPCODE) 370 { 371 operands[char_ptr++] = c; 372 search_status = START_OPERANDS; 373 } 374 375 line++; 376 } 377 if (search_status != START_OPERANDS) 378 return NULL; 379 operands[char_ptr] = '\0'; 380 } 381 } 382 } 383 384 parallel_insn = concat ("q_", first_opcode, "_", second_opcode, " ", 385 first_operands, " | ", second_operands, 386 (char *) NULL); 387 debug ("parallel insn = %s\n", parallel_insn); 388 return parallel_insn; 389} 390 391#undef NONE 392#undef START_OPCODE 393#undef END_OPCODE 394#undef START_OPERANDS 395#undef END_OPERANDS 396 397static operand * 398tic30_operand (char *token) 399{ 400 unsigned int count; 401 operand *current_op; 402 403 debug ("In tic30_operand with %s\n", token); 404 current_op = XCNEW (operand); 405 406 if (*token == DIRECT_REFERENCE) 407 { 408 char *token_posn = token + 1; 409 int direct_label = 0; 410 411 debug ("Found direct reference\n"); 412 while (*token_posn) 413 { 414 if (!is_digit_char (*token_posn)) 415 direct_label = 1; 416 token_posn++; 417 } 418 419 if (direct_label) 420 { 421 char *save_input_line_pointer; 422 segT retval; 423 424 debug ("Direct reference is a label\n"); 425 current_op->direct.label = token + 1; 426 save_input_line_pointer = input_line_pointer; 427 input_line_pointer = token + 1; 428 debug ("Current input_line_pointer: %s\n", input_line_pointer); 429 retval = expression (¤t_op->direct.direct_expr); 430 431 debug ("Expression type: %d\n", 432 current_op->direct.direct_expr.X_op); 433 debug ("Expression addnum: %ld\n", 434 (long) current_op->direct.direct_expr.X_add_number); 435 debug ("Segment: %p\n", retval); 436 437 input_line_pointer = save_input_line_pointer; 438 439 if (current_op->direct.direct_expr.X_op == O_constant) 440 { 441 current_op->direct.address = 442 current_op->direct.direct_expr.X_add_number; 443 current_op->direct.resolved = 1; 444 } 445 } 446 else 447 { 448 debug ("Direct reference is a number\n"); 449 current_op->direct.address = atoi (token + 1); 450 current_op->direct.resolved = 1; 451 } 452 current_op->op_type = Direct; 453 } 454 else if (*token == INDIRECT_REFERENCE) 455 { 456 /* Indirect reference operand. */ 457 int found_ar = 0; 458 int found_disp = 0; 459 int ar_number = -1; 460 int disp_number = 0; 461 int buffer_posn = 1; 462 ind_addr_type *ind_addr_op; 463 char * ind_buffer; 464 465 ind_buffer = XNEWVEC (char, strlen (token)); 466 467 debug ("Found indirect reference\n"); 468 ind_buffer[0] = *token; 469 470 for (count = 1; count < strlen (token); count++) 471 { 472 /* Strip operand. */ 473 ind_buffer[buffer_posn] = TOLOWER (*(token + count)); 474 475 if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A') 476 && (*(token + count) == 'r' || *(token + count) == 'R')) 477 { 478 /* AR reference is found, so get its number and remove 479 it from the buffer so it can pass through hash_find(). */ 480 if (found_ar) 481 { 482 as_bad (_("More than one AR register found in indirect reference")); 483 free (ind_buffer); 484 return NULL; 485 } 486 if (*(token + count + 1) < '0' || *(token + count + 1) > '7') 487 { 488 as_bad (_("Illegal AR register in indirect reference")); 489 free (ind_buffer); 490 return NULL; 491 } 492 ar_number = *(token + count + 1) - '0'; 493 found_ar = 1; 494 count++; 495 } 496 497 if (*(token + count) == '(') 498 { 499 /* Parenthesis found, so check if a displacement value is 500 inside. If so, get the value and remove it from the 501 buffer. */ 502 if (is_digit_char (*(token + count + 1))) 503 { 504 char disp[10]; 505 int disp_posn = 0; 506 507 if (found_disp) 508 { 509 as_bad (_("More than one displacement found in indirect reference")); 510 free (ind_buffer); 511 return NULL; 512 } 513 count++; 514 while (*(token + count) != ')') 515 { 516 if (!is_digit_char (*(token + count))) 517 { 518 as_bad (_("Invalid displacement in indirect reference")); 519 free (ind_buffer); 520 return NULL; 521 } 522 disp[disp_posn++] = *(token + (count++)); 523 } 524 disp[disp_posn] = '\0'; 525 disp_number = atoi (disp); 526 count--; 527 found_disp = 1; 528 } 529 } 530 buffer_posn++; 531 } 532 533 ind_buffer[buffer_posn] = '\0'; 534 if (!found_ar) 535 { 536 as_bad (_("AR register not found in indirect reference")); 537 free (ind_buffer); 538 return NULL; 539 } 540 541 ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer); 542 if (ind_addr_op) 543 { 544 debug ("Found indirect reference: %s\n", ind_addr_op->syntax); 545 if (ind_addr_op->displacement == IMPLIED_DISP) 546 { 547 found_disp = 1; 548 disp_number = 1; 549 } 550 else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp) 551 { 552 /* Maybe an implied displacement of 1 again. */ 553 as_bad (_("required displacement wasn't given in indirect reference")); 554 free (ind_buffer); 555 return NULL; 556 } 557 } 558 else 559 { 560 as_bad (_("illegal indirect reference")); 561 free (ind_buffer); 562 return NULL; 563 } 564 565 if (found_disp && (disp_number < 0 || disp_number > 255)) 566 { 567 as_bad (_("displacement must be an unsigned 8-bit number")); 568 free (ind_buffer); 569 return NULL; 570 } 571 572 current_op->indirect.mod = ind_addr_op->modfield; 573 current_op->indirect.disp = disp_number; 574 current_op->indirect.ARnum = ar_number; 575 current_op->op_type = Indirect; 576 free (ind_buffer); 577 } 578 else 579 { 580 reg *regop = (reg *) hash_find (reg_hash, token); 581 582 if (regop) 583 { 584 debug ("Found register operand: %s\n", regop->name); 585 if (regop->regtype == REG_ARn) 586 current_op->op_type = ARn; 587 else if (regop->regtype == REG_Rn) 588 current_op->op_type = Rn; 589 else if (regop->regtype == REG_DP) 590 current_op->op_type = DPReg; 591 else 592 current_op->op_type = OtherReg; 593 current_op->reg.opcode = regop->opcode; 594 } 595 else 596 { 597 if (!is_digit_char (*token) 598 || *(token + 1) == 'x' 599 || strchr (token, 'h')) 600 { 601 char *save_input_line_pointer; 602 segT retval; 603 604 debug ("Probably a label: %s\n", token); 605 current_op->immediate.label = xstrdup (token); 606 save_input_line_pointer = input_line_pointer; 607 input_line_pointer = token; 608 609 debug ("Current input_line_pointer: %s\n", input_line_pointer); 610 retval = expression (¤t_op->immediate.imm_expr); 611 debug ("Expression type: %d\n", 612 current_op->immediate.imm_expr.X_op); 613 debug ("Expression addnum: %ld\n", 614 (long) current_op->immediate.imm_expr.X_add_number); 615 debug ("Segment: %p\n", retval); 616 input_line_pointer = save_input_line_pointer; 617 618 if (current_op->immediate.imm_expr.X_op == O_constant) 619 { 620 current_op->immediate.s_number 621 = current_op->immediate.imm_expr.X_add_number; 622 current_op->immediate.u_number 623 = (unsigned int) current_op->immediate.imm_expr.X_add_number; 624 current_op->immediate.resolved = 1; 625 } 626 } 627 else 628 { 629 debug ("Found a number or displacement\n"); 630 for (count = 0; count < strlen (token); count++) 631 if (*(token + count) == '.') 632 current_op->immediate.decimal_found = 1; 633 current_op->immediate.label = xstrdup (token); 634 current_op->immediate.f_number = (float) atof (token); 635 current_op->immediate.s_number = (int) atoi (token); 636 current_op->immediate.u_number = (unsigned int) atoi (token); 637 current_op->immediate.resolved = 1; 638 } 639 current_op->op_type = Disp | Abs24 | Imm16 | Imm24; 640 if (current_op->immediate.u_number <= 31) 641 current_op->op_type |= IVector; 642 } 643 } 644 return current_op; 645} 646 647struct tic30_par_insn 648{ 649 partemplate *tm; /* Template of current parallel instruction. */ 650 unsigned operands[2]; /* Number of given operands for each insn. */ 651 /* Type of operand given in instruction. */ 652 operand *operand_type[2][MAX_OPERANDS]; 653 int swap_operands; /* Whether to swap operands around. */ 654 unsigned p_field; /* Value of p field in multiply add/sub instructions. */ 655 unsigned opcode; /* Final opcode. */ 656}; 657 658struct tic30_par_insn p_insn; 659 660static int 661tic30_parallel_insn (char *token) 662{ 663 static partemplate *p_opcode; 664 char *current_posn = token; 665 char *token_start; 666 char save_char; 667 668 debug ("In tic30_parallel_insn with %s\n", token); 669 memset (&p_insn, '\0', sizeof (p_insn)); 670 671 while (is_opcode_char (*current_posn)) 672 current_posn++; 673 { 674 /* Find instruction. */ 675 save_char = *current_posn; 676 *current_posn = '\0'; 677 p_opcode = (partemplate *) hash_find (parop_hash, token); 678 if (p_opcode) 679 { 680 debug ("Found instruction %s\n", p_opcode->name); 681 p_insn.tm = p_opcode; 682 } 683 else 684 { 685 char first_opcode[6] = {0}; 686 char second_opcode[6] = {0}; 687 unsigned int i; 688 int current_opcode = -1; 689 int char_ptr = 0; 690 691 for (i = 0; i < strlen (token); i++) 692 { 693 char ch = *(token + i); 694 695 if (ch == '_' && current_opcode == -1) 696 { 697 current_opcode = 0; 698 continue; 699 } 700 701 if (ch == '_' && current_opcode == 0) 702 { 703 current_opcode = 1; 704 char_ptr = 0; 705 continue; 706 } 707 708 switch (current_opcode) 709 { 710 case 0: 711 first_opcode[char_ptr++] = ch; 712 break; 713 case 1: 714 second_opcode[char_ptr++] = ch; 715 break; 716 } 717 } 718 719 debug ("first_opcode = %s\n", first_opcode); 720 debug ("second_opcode = %s\n", second_opcode); 721 sprintf (token, "q_%s_%s", second_opcode, first_opcode); 722 p_opcode = (partemplate *) hash_find (parop_hash, token); 723 724 if (p_opcode) 725 { 726 debug ("Found instruction %s\n", p_opcode->name); 727 p_insn.tm = p_opcode; 728 p_insn.swap_operands = 1; 729 } 730 else 731 return 0; 732 } 733 *current_posn = save_char; 734 } 735 736 { 737 /* Find operands. */ 738 int paren_not_balanced; 739 int expecting_operand = 0; 740 int found_separator = 0; 741 742 do 743 { 744 /* Skip optional white space before operand. */ 745 while (!is_operand_char (*current_posn) 746 && *current_posn != END_OF_INSN) 747 { 748 if (!is_space_char (*current_posn) 749 && *current_posn != PARALLEL_SEPARATOR) 750 { 751 as_bad (_("Invalid character %s before %s operand"), 752 output_invalid (*current_posn), 753 ordinal_names[insn.operands]); 754 return 1; 755 } 756 if (*current_posn == PARALLEL_SEPARATOR) 757 found_separator = 1; 758 current_posn++; 759 } 760 761 token_start = current_posn; 762 paren_not_balanced = 0; 763 764 while (paren_not_balanced || *current_posn != ',') 765 { 766 if (*current_posn == END_OF_INSN) 767 { 768 if (paren_not_balanced) 769 { 770 as_bad (_("Unbalanced parenthesis in %s operand."), 771 ordinal_names[insn.operands]); 772 return 1; 773 } 774 else 775 break; 776 } 777 else if (*current_posn == PARALLEL_SEPARATOR) 778 { 779 while (is_space_char (*(current_posn - 1))) 780 current_posn--; 781 break; 782 } 783 else if (!is_operand_char (*current_posn) 784 && !is_space_char (*current_posn)) 785 { 786 as_bad (_("Invalid character %s in %s operand"), 787 output_invalid (*current_posn), 788 ordinal_names[insn.operands]); 789 return 1; 790 } 791 792 if (*current_posn == '(') 793 ++paren_not_balanced; 794 if (*current_posn == ')') 795 --paren_not_balanced; 796 current_posn++; 797 } 798 799 if (current_posn != token_start) 800 { 801 /* Yes, we've read in another operand. */ 802 p_insn.operands[found_separator]++; 803 if (p_insn.operands[found_separator] > MAX_OPERANDS) 804 { 805 as_bad (_("Spurious operands; (%d operands/instruction max)"), 806 MAX_OPERANDS); 807 return 1; 808 } 809 810 /* Now parse operand adding info to 'insn' as we go along. */ 811 save_char = *current_posn; 812 *current_posn = '\0'; 813 p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] = 814 tic30_operand (token_start); 815 *current_posn = save_char; 816 if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1]) 817 return 1; 818 } 819 else 820 { 821 if (expecting_operand) 822 { 823 as_bad (_("Expecting operand after ','; got nothing")); 824 return 1; 825 } 826 if (*current_posn == ',') 827 { 828 as_bad (_("Expecting operand before ','; got nothing")); 829 return 1; 830 } 831 } 832 833 /* Now *current_posn must be either ',' or END_OF_INSN. */ 834 if (*current_posn == ',') 835 { 836 if (*++current_posn == END_OF_INSN) 837 { 838 /* Just skip it, if it's \n complain. */ 839 as_bad (_("Expecting operand after ','; got nothing")); 840 return 1; 841 } 842 expecting_operand = 1; 843 } 844 } 845 while (*current_posn != END_OF_INSN); 846 } 847 848 if (p_insn.swap_operands) 849 { 850 int temp_num, i; 851 operand *temp_op; 852 853 temp_num = p_insn.operands[0]; 854 p_insn.operands[0] = p_insn.operands[1]; 855 p_insn.operands[1] = temp_num; 856 for (i = 0; i < MAX_OPERANDS; i++) 857 { 858 temp_op = p_insn.operand_type[0][i]; 859 p_insn.operand_type[0][i] = p_insn.operand_type[1][i]; 860 p_insn.operand_type[1][i] = temp_op; 861 } 862 } 863 864 if (p_insn.operands[0] != p_insn.tm->operands_1) 865 { 866 as_bad (_("incorrect number of operands given in the first instruction")); 867 return 1; 868 } 869 870 if (p_insn.operands[1] != p_insn.tm->operands_2) 871 { 872 as_bad (_("incorrect number of operands given in the second instruction")); 873 return 1; 874 } 875 876 debug ("Number of operands in first insn: %d\n", p_insn.operands[0]); 877 debug ("Number of operands in second insn: %d\n", p_insn.operands[1]); 878 879 { 880 /* Now check if operands are correct. */ 881 int count; 882 int num_rn = 0; 883 int num_ind = 0; 884 885 for (count = 0; count < 2; count++) 886 { 887 unsigned int i; 888 for (i = 0; i < p_insn.operands[count]; i++) 889 { 890 if ((p_insn.operand_type[count][i]->op_type & 891 p_insn.tm->operand_types[count][i]) == 0) 892 { 893 as_bad (_("%s instruction, operand %d doesn't match"), 894 ordinal_names[count], i + 1); 895 return 1; 896 } 897 898 /* Get number of R register and indirect reference contained 899 within the first two operands of each instruction. This is 900 required for the multiply parallel instructions which require 901 two R registers and two indirect references, but not in any 902 particular place. */ 903 if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2) 904 num_rn++; 905 else if ((p_insn.operand_type[count][i]->op_type & Indirect) 906 && i < 2) 907 num_ind++; 908 } 909 } 910 911 if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn)) 912 == (Indirect | Rn)) 913 { 914 /* Check for the multiply instructions. */ 915 if (num_rn != 2) 916 { 917 as_bad (_("incorrect format for multiply parallel instruction")); 918 return 1; 919 } 920 921 if (num_ind != 2) 922 { 923 /* Shouldn't get here. */ 924 as_bad (_("incorrect format for multiply parallel instruction")); 925 return 1; 926 } 927 928 if ((p_insn.operand_type[0][2]->reg.opcode != 0x00) 929 && (p_insn.operand_type[0][2]->reg.opcode != 0x01)) 930 { 931 as_bad (_("destination for multiply can only be R0 or R1")); 932 return 1; 933 } 934 935 if ((p_insn.operand_type[1][2]->reg.opcode != 0x02) 936 && (p_insn.operand_type[1][2]->reg.opcode != 0x03)) 937 { 938 as_bad (_("destination for add/subtract can only be R2 or R3")); 939 return 1; 940 } 941 942 /* Now determine the P field for the instruction. */ 943 if (p_insn.operand_type[0][0]->op_type & Indirect) 944 { 945 if (p_insn.operand_type[0][1]->op_type & Indirect) 946 p_insn.p_field = 0x00000000; /* Ind * Ind, Rn +/- Rn. */ 947 else if (p_insn.operand_type[1][0]->op_type & Indirect) 948 p_insn.p_field = 0x01000000; /* Ind * Rn, Ind +/- Rn. */ 949 else 950 p_insn.p_field = 0x03000000; /* Ind * Rn, Rn +/- Ind. */ 951 } 952 else 953 { 954 if (p_insn.operand_type[0][1]->op_type & Rn) 955 p_insn.p_field = 0x02000000; /* Rn * Rn, Ind +/- Ind. */ 956 else if (p_insn.operand_type[1][0]->op_type & Indirect) 957 { 958 operand *temp; 959 p_insn.p_field = 0x01000000; /* Rn * Ind, Ind +/- Rn. */ 960 /* Need to swap the two multiply operands around so that 961 everything is in its place for the opcode makeup. 962 ie so Ind * Rn, Ind +/- Rn. */ 963 temp = p_insn.operand_type[0][0]; 964 p_insn.operand_type[0][0] = p_insn.operand_type[0][1]; 965 p_insn.operand_type[0][1] = temp; 966 } 967 else 968 { 969 operand *temp; 970 p_insn.p_field = 0x03000000; /* Rn * Ind, Rn +/- Ind. */ 971 temp = p_insn.operand_type[0][0]; 972 p_insn.operand_type[0][0] = p_insn.operand_type[0][1]; 973 p_insn.operand_type[0][1] = temp; 974 } 975 } 976 } 977 } 978 979 debug ("P field: %08X\n", p_insn.p_field); 980 981 /* Finalise opcode. This is easier for parallel instructions as they have 982 to be fully resolved, there are no memory addresses allowed, except 983 through indirect addressing, so there are no labels to resolve. */ 984 p_insn.opcode = p_insn.tm->base_opcode; 985 986 switch (p_insn.tm->oporder) 987 { 988 case OO_4op1: 989 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum); 990 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3); 991 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8); 992 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11); 993 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16); 994 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22); 995 break; 996 997 case OO_4op2: 998 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum); 999 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3); 1000 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8); 1001 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11); 1002 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19); 1003 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22); 1004 if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode) 1005 as_warn (_("loading the same register in parallel operation")); 1006 break; 1007 1008 case OO_4op3: 1009 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum); 1010 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3); 1011 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8); 1012 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11); 1013 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16); 1014 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22); 1015 break; 1016 1017 case OO_5op1: 1018 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum); 1019 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3); 1020 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8); 1021 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11); 1022 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16); 1023 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19); 1024 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22); 1025 break; 1026 1027 case OO_5op2: 1028 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum); 1029 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3); 1030 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8); 1031 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11); 1032 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16); 1033 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19); 1034 p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22); 1035 break; 1036 1037 case OO_PField: 1038 p_insn.opcode |= p_insn.p_field; 1039 if (p_insn.operand_type[0][2]->reg.opcode == 0x01) 1040 p_insn.opcode |= 0x00800000; 1041 if (p_insn.operand_type[1][2]->reg.opcode == 0x03) 1042 p_insn.opcode |= 0x00400000; 1043 1044 switch (p_insn.p_field) 1045 { 1046 case 0x00000000: 1047 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum); 1048 p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3); 1049 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8); 1050 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11); 1051 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16); 1052 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19); 1053 break; 1054 case 0x01000000: 1055 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum); 1056 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3); 1057 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8); 1058 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11); 1059 p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16); 1060 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19); 1061 break; 1062 case 0x02000000: 1063 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum); 1064 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3); 1065 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8); 1066 p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11); 1067 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16); 1068 p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19); 1069 break; 1070 case 0x03000000: 1071 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum); 1072 p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3); 1073 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8); 1074 p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11); 1075 p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16); 1076 p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19); 1077 break; 1078 } 1079 break; 1080 } 1081 1082 { 1083 char *p; 1084 1085 p = frag_more (INSN_SIZE); 1086 md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE); 1087 } 1088 1089 { 1090 unsigned int i, j; 1091 1092 for (i = 0; i < 2; i++) 1093 for (j = 0; j < p_insn.operands[i]; j++) 1094 free (p_insn.operand_type[i][j]); 1095 } 1096 1097 debug ("Final opcode: %08X\n", p_insn.opcode); 1098 debug ("\n"); 1099 1100 return 1; 1101} 1102 1103/* In order to get gas to ignore any | chars at the start of a line, 1104 this function returns true if a | is found in a line. */ 1105 1106int 1107tic30_unrecognized_line (int c) 1108{ 1109 debug ("In tc_unrecognized_line\n"); 1110 return (c == PARALLEL_SEPARATOR); 1111} 1112 1113int 1114md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED, 1115 segT segment ATTRIBUTE_UNUSED) 1116{ 1117 debug ("In md_estimate_size_before_relax()\n"); 1118 return 0; 1119} 1120 1121void 1122md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, 1123 segT sec ATTRIBUTE_UNUSED, 1124 fragS *fragP ATTRIBUTE_UNUSED) 1125{ 1126 debug ("In md_convert_frag()\n"); 1127} 1128 1129void 1130md_apply_fix (fixS *fixP, 1131 valueT *valP, 1132 segT seg ATTRIBUTE_UNUSED) 1133{ 1134 valueT value = *valP; 1135 1136 debug ("In md_apply_fix() with value = %ld\n", (long) value); 1137 debug ("Values in fixP\n"); 1138 debug ("fx_size = %d\n", fixP->fx_size); 1139 debug ("fx_pcrel = %d\n", fixP->fx_pcrel); 1140 debug ("fx_where = %ld\n", fixP->fx_where); 1141 debug ("fx_offset = %d\n", (int) fixP->fx_offset); 1142 { 1143 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where; 1144 1145 value /= INSN_SIZE; 1146 if (fixP->fx_size == 1) 1147 /* Special fix for LDP instruction. */ 1148 value = (value & 0x00FF0000) >> 16; 1149 1150 debug ("new value = %ld\n", (long) value); 1151 md_number_to_chars (buf, value, fixP->fx_size); 1152 } 1153 1154 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) 1155 fixP->fx_done = 1; 1156} 1157 1158int 1159md_parse_option (int c ATTRIBUTE_UNUSED, 1160 const char *arg ATTRIBUTE_UNUSED) 1161{ 1162 debug ("In md_parse_option()\n"); 1163 return 0; 1164} 1165 1166void 1167md_show_usage (FILE *stream ATTRIBUTE_UNUSED) 1168{ 1169 debug ("In md_show_usage()\n"); 1170} 1171 1172symbolS * 1173md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 1174{ 1175 debug ("In md_undefined_symbol()\n"); 1176 return (symbolS *) 0; 1177} 1178 1179valueT 1180md_section_align (segT segment, valueT size) 1181{ 1182 debug ("In md_section_align() segment = %p and size = %lu\n", 1183 segment, (unsigned long) size); 1184 size = (size + 3) / 4; 1185 size *= 4; 1186 debug ("New size value = %lu\n", (unsigned long) size); 1187 return size; 1188} 1189 1190long 1191md_pcrel_from (fixS *fixP) 1192{ 1193 int offset; 1194 1195 debug ("In md_pcrel_from()\n"); 1196 debug ("fx_where = %ld\n", fixP->fx_where); 1197 debug ("fx_size = %d\n", fixP->fx_size); 1198 /* Find the opcode that represents the current instruction in the 1199 fr_literal storage area, and check bit 21. Bit 21 contains whether the 1200 current instruction is a delayed one or not, and then set the offset 1201 value appropriately. */ 1202 if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20) 1203 offset = 3; 1204 else 1205 offset = 1; 1206 debug ("offset = %d\n", offset); 1207 /* PC Relative instructions have a format: 1208 displacement = Label - (PC + offset) 1209 This function returns PC + offset where: 1210 fx_where - fx_size = PC 1211 INSN_SIZE * offset = offset number of instructions. */ 1212 return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset); 1213} 1214 1215const char * 1216md_atof (int what_statement_type, 1217 char *literalP, 1218 int *sizeP) 1219{ 1220 int prec; 1221 char *token; 1222 char keepval; 1223 unsigned long value; 1224 float float_value; 1225 1226 debug ("In md_atof()\n"); 1227 debug ("precision = %c\n", what_statement_type); 1228 debug ("literal = %s\n", literalP); 1229 debug ("line = "); 1230 token = input_line_pointer; 1231 while (!is_end_of_line[(unsigned char) *input_line_pointer] 1232 && (*input_line_pointer != ',')) 1233 { 1234 debug ("%c", *input_line_pointer); 1235 input_line_pointer++; 1236 } 1237 1238 keepval = *input_line_pointer; 1239 *input_line_pointer = '\0'; 1240 debug ("\n"); 1241 float_value = (float) atof (token); 1242 *input_line_pointer = keepval; 1243 debug ("float_value = %f\n", float_value); 1244 1245 switch (what_statement_type) 1246 { 1247 case 'f': 1248 case 'F': 1249 case 's': 1250 case 'S': 1251 prec = 2; 1252 break; 1253 1254 case 'd': 1255 case 'D': 1256 case 'r': 1257 case 'R': 1258 prec = 4; 1259 break; 1260 1261 default: 1262 *sizeP = 0; 1263 return _("Unrecognized or unsupported floating point constant"); 1264 } 1265 1266 if (float_value == 0.0) 1267 value = (prec == 2) ? 0x00008000L : 0x80000000L; 1268 else 1269 { 1270 unsigned long exp, sign, mant, tmsfloat; 1271 union 1272 { 1273 float f; 1274 long l; 1275 } 1276 converter; 1277 1278 converter.f = float_value; 1279 tmsfloat = converter.l; 1280 sign = tmsfloat & 0x80000000; 1281 mant = tmsfloat & 0x007FFFFF; 1282 exp = tmsfloat & 0x7F800000; 1283 exp <<= 1; 1284 if (exp == 0xFF000000) 1285 { 1286 if (mant == 0) 1287 value = 0x7F7FFFFF; 1288 else if (sign == 0) 1289 value = 0x7F7FFFFF; 1290 else 1291 value = 0x7F800000; 1292 } 1293 else 1294 { 1295 exp -= 0x7F000000; 1296 if (sign) 1297 { 1298 mant = mant & 0x007FFFFF; 1299 mant = -mant; 1300 mant = mant & 0x00FFFFFF; 1301 if (mant == 0) 1302 { 1303 mant |= 0x00800000; 1304 exp = (long) exp - 0x01000000; 1305 } 1306 } 1307 tmsfloat = exp | mant; 1308 value = tmsfloat; 1309 } 1310 if (prec == 2) 1311 { 1312 long expon, mantis; 1313 1314 if (tmsfloat == 0x80000000) 1315 value = 0x8000; 1316 else 1317 { 1318 value = 0; 1319 expon = (tmsfloat & 0xFF000000); 1320 expon >>= 24; 1321 mantis = tmsfloat & 0x007FFFFF; 1322 if (tmsfloat & 0x00800000) 1323 { 1324 mantis |= 0xFF000000; 1325 mantis += 0x00000800; 1326 mantis >>= 12; 1327 mantis |= 0x00000800; 1328 mantis &= 0x0FFF; 1329 if (expon > 7) 1330 value = 0x7800; 1331 } 1332 else 1333 { 1334 mantis |= 0x00800000; 1335 mantis += 0x00000800; 1336 expon += (mantis >> 24); 1337 mantis >>= 12; 1338 mantis &= 0x07FF; 1339 if (expon > 7) 1340 value = 0x77FF; 1341 } 1342 if (expon < -8) 1343 value = 0x8000; 1344 if (value == 0) 1345 { 1346 mantis = (expon << 12) | mantis; 1347 value = mantis & 0xFFFF; 1348 } 1349 } 1350 } 1351 } 1352 md_number_to_chars (literalP, value, prec); 1353 *sizeP = prec; 1354 return NULL; 1355} 1356 1357void 1358md_number_to_chars (char *buf, valueT val, int n) 1359{ 1360 debug ("In md_number_to_chars()\n"); 1361 number_to_chars_bigendian (buf, val, n); 1362} 1363 1364#define F(SZ,PCREL) (((SZ) << 1) + (PCREL)) 1365#define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break 1366 1367arelent * 1368tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP) 1369{ 1370 arelent *rel; 1371 bfd_reloc_code_real_type code = 0; 1372 1373 debug ("In tc_gen_reloc()\n"); 1374 debug ("fixP.size = %d\n", fixP->fx_size); 1375 debug ("fixP.pcrel = %d\n", fixP->fx_pcrel); 1376 debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy)); 1377 1378 switch (F (fixP->fx_size, fixP->fx_pcrel)) 1379 { 1380 MAP (1, 0, BFD_RELOC_TIC30_LDP); 1381 MAP (2, 0, BFD_RELOC_16); 1382 MAP (3, 0, BFD_RELOC_24); 1383 MAP (2, 1, BFD_RELOC_16_PCREL); 1384 MAP (4, 0, BFD_RELOC_32); 1385 default: 1386 as_bad (_("Can not do %d byte %srelocation"), fixP->fx_size, 1387 fixP->fx_pcrel ? _("pc-relative ") : ""); 1388 } 1389#undef MAP 1390#undef F 1391 1392 rel = XNEW (arelent); 1393 gas_assert (rel != 0); 1394 rel->sym_ptr_ptr = XNEW (asymbol *); 1395 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy); 1396 rel->address = fixP->fx_frag->fr_address + fixP->fx_where; 1397 rel->addend = 0; 1398 rel->howto = bfd_reloc_type_lookup (stdoutput, code); 1399 if (!rel->howto) 1400 { 1401 const char *name; 1402 1403 name = S_GET_NAME (fixP->fx_addsy); 1404 if (name == NULL) 1405 name = "<unknown>"; 1406 as_fatal ("Cannot generate relocation type for symbol %s, code %s", 1407 name, bfd_get_reloc_code_name (code)); 1408 } 1409 return rel; 1410} 1411 1412void 1413md_operand (expressionS *expressionP ATTRIBUTE_UNUSED) 1414{ 1415 debug ("In md_operand()\n"); 1416} 1417 1418void 1419md_assemble (char *line) 1420{ 1421 insn_template *op; 1422 char *current_posn; 1423 char *token_start; 1424 char save_char; 1425 unsigned int count; 1426 1427 debug ("In md_assemble() with argument %s\n", line); 1428 memset (&insn, '\0', sizeof (insn)); 1429 if (found_parallel_insn) 1430 { 1431 debug ("Line is second part of parallel instruction\n\n"); 1432 found_parallel_insn = 0; 1433 return; 1434 } 1435 if ((current_posn = 1436 tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL) 1437 current_posn = line; 1438 else 1439 found_parallel_insn = 1; 1440 1441 while (is_space_char (*current_posn)) 1442 current_posn++; 1443 1444 token_start = current_posn; 1445 1446 if (!is_opcode_char (*current_posn)) 1447 { 1448 as_bad (_("Invalid character %s in opcode"), 1449 output_invalid (*current_posn)); 1450 return; 1451 } 1452 /* Check if instruction is a parallel instruction 1453 by seeing if the first character is a q. */ 1454 if (*token_start == 'q') 1455 { 1456 if (tic30_parallel_insn (token_start)) 1457 { 1458 if (found_parallel_insn) 1459 free (token_start); 1460 return; 1461 } 1462 } 1463 while (is_opcode_char (*current_posn)) 1464 current_posn++; 1465 { 1466 /* Find instruction. */ 1467 save_char = *current_posn; 1468 *current_posn = '\0'; 1469 op = (insn_template *) hash_find (op_hash, token_start); 1470 if (op) 1471 { 1472 debug ("Found instruction %s\n", op->name); 1473 insn.tm = op; 1474 } 1475 else 1476 { 1477 debug ("Didn't find insn\n"); 1478 as_bad (_("Unknown TMS320C30 instruction: %s"), token_start); 1479 return; 1480 } 1481 *current_posn = save_char; 1482 } 1483 1484 if (*current_posn != END_OF_INSN) 1485 { 1486 /* Find operands. */ 1487 int paren_not_balanced; 1488 int expecting_operand = 0; 1489 int this_operand; 1490 do 1491 { 1492 /* Skip optional white space before operand. */ 1493 while (!is_operand_char (*current_posn) 1494 && *current_posn != END_OF_INSN) 1495 { 1496 if (!is_space_char (*current_posn)) 1497 { 1498 as_bad (_("Invalid character %s before %s operand"), 1499 output_invalid (*current_posn), 1500 ordinal_names[insn.operands]); 1501 return; 1502 } 1503 current_posn++; 1504 } 1505 token_start = current_posn; 1506 paren_not_balanced = 0; 1507 while (paren_not_balanced || *current_posn != ',') 1508 { 1509 if (*current_posn == END_OF_INSN) 1510 { 1511 if (paren_not_balanced) 1512 { 1513 as_bad (_("Unbalanced parenthesis in %s operand."), 1514 ordinal_names[insn.operands]); 1515 return; 1516 } 1517 else 1518 break; 1519 } 1520 else if (!is_operand_char (*current_posn) 1521 && !is_space_char (*current_posn)) 1522 { 1523 as_bad (_("Invalid character %s in %s operand"), 1524 output_invalid (*current_posn), 1525 ordinal_names[insn.operands]); 1526 return; 1527 } 1528 if (*current_posn == '(') 1529 ++paren_not_balanced; 1530 if (*current_posn == ')') 1531 --paren_not_balanced; 1532 current_posn++; 1533 } 1534 if (current_posn != token_start) 1535 { 1536 /* Yes, we've read in another operand. */ 1537 this_operand = insn.operands++; 1538 if (insn.operands > MAX_OPERANDS) 1539 { 1540 as_bad (_("Spurious operands; (%d operands/instruction max)"), 1541 MAX_OPERANDS); 1542 return; 1543 } 1544 1545 /* Now parse operand adding info to 'insn' as we go along. */ 1546 save_char = *current_posn; 1547 *current_posn = '\0'; 1548 insn.operand_type[this_operand] = tic30_operand (token_start); 1549 *current_posn = save_char; 1550 if (insn.operand_type[this_operand] == NULL) 1551 return; 1552 } 1553 else 1554 { 1555 if (expecting_operand) 1556 { 1557 as_bad (_("Expecting operand after ','; got nothing")); 1558 return; 1559 } 1560 if (*current_posn == ',') 1561 { 1562 as_bad (_("Expecting operand before ','; got nothing")); 1563 return; 1564 } 1565 } 1566 1567 /* Now *current_posn must be either ',' or END_OF_INSN. */ 1568 if (*current_posn == ',') 1569 { 1570 if (*++current_posn == END_OF_INSN) 1571 { 1572 /* Just skip it, if it's \n complain. */ 1573 as_bad (_("Expecting operand after ','; got nothing")); 1574 return; 1575 } 1576 expecting_operand = 1; 1577 } 1578 } 1579 while (*current_posn != END_OF_INSN); 1580 } 1581 1582 debug ("Number of operands found: %d\n", insn.operands); 1583 1584 /* Check that number of operands is correct. */ 1585 if (insn.operands != insn.tm->operands) 1586 { 1587 unsigned int i; 1588 unsigned int numops = insn.tm->operands; 1589 1590 /* If operands are not the same, then see if any of the operands are 1591 not required. Then recheck with number of given operands. If they 1592 are still not the same, then give an error, otherwise carry on. */ 1593 for (i = 0; i < insn.tm->operands; i++) 1594 if (insn.tm->operand_types[i] & NotReq) 1595 numops--; 1596 if (insn.operands != numops) 1597 { 1598 as_bad (_("Incorrect number of operands given")); 1599 return; 1600 } 1601 } 1602 insn.addressing_mode = AM_NotReq; 1603 for (count = 0; count < insn.operands; count++) 1604 { 1605 if (insn.operand_type[count]->op_type & insn.tm->operand_types[count]) 1606 { 1607 debug ("Operand %d matches\n", count + 1); 1608 /* If instruction has two operands and has an AddressMode 1609 modifier then set addressing mode type for instruction. */ 1610 if (insn.tm->opcode_modifier == AddressMode) 1611 { 1612 int addr_insn = 0; 1613 /* Store instruction uses the second 1614 operand for the address mode. */ 1615 if ((insn.tm->operand_types[1] & (Indirect | Direct)) 1616 == (Indirect | Direct)) 1617 addr_insn = 1; 1618 1619 if (insn.operand_type[addr_insn]->op_type & (AllReg)) 1620 insn.addressing_mode = AM_Register; 1621 else if (insn.operand_type[addr_insn]->op_type & Direct) 1622 insn.addressing_mode = AM_Direct; 1623 else if (insn.operand_type[addr_insn]->op_type & Indirect) 1624 insn.addressing_mode = AM_Indirect; 1625 else 1626 insn.addressing_mode = AM_Immediate; 1627 } 1628 } 1629 else 1630 { 1631 as_bad (_("The %s operand doesn't match"), ordinal_names[count]); 1632 return; 1633 } 1634 } 1635 1636 /* Now set the addressing mode for 3 operand instructions. */ 1637 if ((insn.tm->operand_types[0] & op3T1) 1638 && (insn.tm->operand_types[1] & op3T2)) 1639 { 1640 /* Set the addressing mode to the values used for 2 operand 1641 instructions in the G addressing field of the opcode. */ 1642 char *p; 1643 switch (insn.operand_type[0]->op_type) 1644 { 1645 case Rn: 1646 case ARn: 1647 case DPReg: 1648 case OtherReg: 1649 if (insn.operand_type[1]->op_type & (AllReg)) 1650 insn.addressing_mode = AM_Register; 1651 else if (insn.operand_type[1]->op_type & Indirect) 1652 insn.addressing_mode = AM_Direct; 1653 else 1654 { 1655 /* Shouldn't make it to this stage. */ 1656 as_bad (_("Incompatible first and second operands in instruction")); 1657 return; 1658 } 1659 break; 1660 case Indirect: 1661 if (insn.operand_type[1]->op_type & (AllReg)) 1662 insn.addressing_mode = AM_Indirect; 1663 else if (insn.operand_type[1]->op_type & Indirect) 1664 insn.addressing_mode = AM_Immediate; 1665 else 1666 { 1667 /* Shouldn't make it to this stage. */ 1668 as_bad (_("Incompatible first and second operands in instruction")); 1669 return; 1670 } 1671 break; 1672 } 1673 /* Now make up the opcode for the 3 operand instructions. As in 1674 parallel instructions, there will be no unresolved values, so they 1675 can be fully formed and added to the frag table. */ 1676 insn.opcode = insn.tm->base_opcode; 1677 if (insn.operand_type[0]->op_type & Indirect) 1678 { 1679 insn.opcode |= (insn.operand_type[0]->indirect.ARnum); 1680 insn.opcode |= (insn.operand_type[0]->indirect.mod << 3); 1681 } 1682 else 1683 insn.opcode |= (insn.operand_type[0]->reg.opcode); 1684 1685 if (insn.operand_type[1]->op_type & Indirect) 1686 { 1687 insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8); 1688 insn.opcode |= (insn.operand_type[1]->indirect.mod << 11); 1689 } 1690 else 1691 insn.opcode |= (insn.operand_type[1]->reg.opcode << 8); 1692 1693 if (insn.operands == 3) 1694 insn.opcode |= (insn.operand_type[2]->reg.opcode << 16); 1695 1696 insn.opcode |= insn.addressing_mode; 1697 p = frag_more (INSN_SIZE); 1698 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1699 } 1700 else 1701 { 1702 /* Not a three operand instruction. */ 1703 char *p; 1704 int am_insn = -1; 1705 insn.opcode = insn.tm->base_opcode; 1706 /* Create frag for instruction - all instructions are 4 bytes long. */ 1707 p = frag_more (INSN_SIZE); 1708 if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode)) 1709 { 1710 insn.opcode |= insn.addressing_mode; 1711 if (insn.addressing_mode == AM_Indirect) 1712 { 1713 /* Determine which operand gives the addressing mode. */ 1714 if (insn.operand_type[0]->op_type & Indirect) 1715 am_insn = 0; 1716 if ((insn.operands > 1) 1717 && (insn.operand_type[1]->op_type & Indirect)) 1718 am_insn = 1; 1719 insn.opcode |= (insn.operand_type[am_insn]->indirect.disp); 1720 insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8); 1721 insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11); 1722 if (insn.operands > 1) 1723 insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16); 1724 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1725 } 1726 else if (insn.addressing_mode == AM_Register) 1727 { 1728 insn.opcode |= (insn.operand_type[0]->reg.opcode); 1729 if (insn.operands > 1) 1730 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16); 1731 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1732 } 1733 else if (insn.addressing_mode == AM_Direct) 1734 { 1735 if (insn.operand_type[0]->op_type & Direct) 1736 am_insn = 0; 1737 if ((insn.operands > 1) 1738 && (insn.operand_type[1]->op_type & Direct)) 1739 am_insn = 1; 1740 if (insn.operands > 1) 1741 insn.opcode |= 1742 (insn.operand_type[! am_insn]->reg.opcode << 16); 1743 if (insn.operand_type[am_insn]->direct.resolved == 1) 1744 { 1745 /* Resolved values can be placed straight 1746 into instruction word, and output. */ 1747 insn.opcode |= 1748 (insn.operand_type[am_insn]->direct.address & 0x0000FFFF); 1749 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1750 } 1751 else 1752 { 1753 /* Unresolved direct addressing mode instruction. */ 1754 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1755 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, 1756 & insn.operand_type[am_insn]->direct.direct_expr, 1757 0, 0); 1758 } 1759 } 1760 else if (insn.addressing_mode == AM_Immediate) 1761 { 1762 if (insn.operand_type[0]->immediate.resolved == 1) 1763 { 1764 char *keeploc; 1765 int size; 1766 1767 if (insn.operands > 1) 1768 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16); 1769 1770 switch (insn.tm->imm_arg_type) 1771 { 1772 case Imm_Float: 1773 debug ("Floating point first operand\n"); 1774 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1775 1776 keeploc = input_line_pointer; 1777 input_line_pointer = 1778 insn.operand_type[0]->immediate.label; 1779 1780 if (md_atof ('f', p + 2, & size) != 0) 1781 { 1782 as_bad (_("invalid short form floating point immediate operand")); 1783 return; 1784 } 1785 1786 input_line_pointer = keeploc; 1787 break; 1788 1789 case Imm_UInt: 1790 debug ("Unsigned int first operand\n"); 1791 if (insn.operand_type[0]->immediate.decimal_found) 1792 as_warn (_("rounding down first operand float to unsigned int")); 1793 if (insn.operand_type[0]->immediate.u_number > 0xFFFF) 1794 as_warn (_("only lower 16-bits of first operand are used")); 1795 insn.opcode |= 1796 (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL); 1797 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1798 break; 1799 1800 case Imm_SInt: 1801 debug ("Int first operand\n"); 1802 1803 if (insn.operand_type[0]->immediate.decimal_found) 1804 as_warn (_("rounding down first operand float to signed int")); 1805 1806 if (insn.operand_type[0]->immediate.s_number < -32768 || 1807 insn.operand_type[0]->immediate.s_number > 32767) 1808 { 1809 as_bad (_("first operand is too large for 16-bit signed int")); 1810 return; 1811 } 1812 insn.opcode |= 1813 (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL); 1814 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1815 break; 1816 } 1817 } 1818 else 1819 { 1820 /* Unresolved immediate label. */ 1821 if (insn.operands > 1) 1822 insn.opcode |= (insn.operand_type[1]->reg.opcode << 16); 1823 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1824 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, 1825 & insn.operand_type[0]->immediate.imm_expr, 1826 0, 0); 1827 } 1828 } 1829 } 1830 else if (insn.tm->opcode_modifier == PCRel) 1831 { 1832 /* Conditional Branch and Call instructions. */ 1833 if ((insn.tm->operand_types[0] & (AllReg | Disp)) 1834 == (AllReg | Disp)) 1835 { 1836 if (insn.operand_type[0]->op_type & (AllReg)) 1837 { 1838 insn.opcode |= (insn.operand_type[0]->reg.opcode); 1839 insn.opcode |= PC_Register; 1840 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1841 } 1842 else 1843 { 1844 insn.opcode |= PC_Relative; 1845 if (insn.operand_type[0]->immediate.resolved == 1) 1846 { 1847 insn.opcode |= 1848 (insn.operand_type[0]->immediate.s_number & 0x0000FFFF); 1849 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1850 } 1851 else 1852 { 1853 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1854 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 1855 2, & insn.operand_type[0]->immediate.imm_expr, 1856 1, 0); 1857 } 1858 } 1859 } 1860 else if ((insn.tm->operand_types[0] & ARn) == ARn) 1861 { 1862 /* Decrement and Branch instructions. */ 1863 insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22); 1864 if (insn.operand_type[1]->op_type & (AllReg)) 1865 { 1866 insn.opcode |= (insn.operand_type[1]->reg.opcode); 1867 insn.opcode |= PC_Register; 1868 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1869 } 1870 else if (insn.operand_type[1]->immediate.resolved == 1) 1871 { 1872 if (insn.operand_type[0]->immediate.decimal_found) 1873 { 1874 as_bad (_("first operand is floating point")); 1875 return; 1876 } 1877 if (insn.operand_type[0]->immediate.s_number < -32768 || 1878 insn.operand_type[0]->immediate.s_number > 32767) 1879 { 1880 as_bad (_("first operand is too large for 16-bit signed int")); 1881 return; 1882 } 1883 insn.opcode |= (insn.operand_type[1]->immediate.s_number); 1884 insn.opcode |= PC_Relative; 1885 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1886 } 1887 else 1888 { 1889 insn.opcode |= PC_Relative; 1890 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1891 fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2, 1892 & insn.operand_type[1]->immediate.imm_expr, 1893 1, 0); 1894 } 1895 } 1896 } 1897 else if (insn.tm->operand_types[0] == IVector) 1898 { 1899 /* Trap instructions. */ 1900 if (insn.operand_type[0]->op_type & IVector) 1901 insn.opcode |= (insn.operand_type[0]->immediate.u_number); 1902 else 1903 { 1904 /* Shouldn't get here. */ 1905 as_bad (_("interrupt vector for trap instruction out of range")); 1906 return; 1907 } 1908 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1909 } 1910 else if (insn.tm->opcode_modifier == StackOp 1911 || insn.tm->opcode_modifier == Rotate) 1912 { 1913 /* Push, Pop and Rotate instructions. */ 1914 insn.opcode |= (insn.operand_type[0]->reg.opcode << 16); 1915 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1916 } 1917 else if ((insn.tm->operand_types[0] & (Abs24 | Direct)) 1918 == (Abs24 | Direct)) 1919 { 1920 /* LDP Instruction needs to be tested 1921 for before the next section. */ 1922 if (insn.operand_type[0]->op_type & Direct) 1923 { 1924 if (insn.operand_type[0]->direct.resolved == 1) 1925 { 1926 /* Direct addressing uses lower 8 bits of direct address. */ 1927 insn.opcode |= 1928 (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16; 1929 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1930 } 1931 else 1932 { 1933 fixS *fix; 1934 1935 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1936 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1937 1, &insn.operand_type[0]->direct.direct_expr, 0, 0); 1938 /* Ensure that the assembler doesn't complain 1939 about fitting a 24-bit address into 8 bits. */ 1940 fix->fx_no_overflow = 1; 1941 } 1942 } 1943 else 1944 { 1945 if (insn.operand_type[0]->immediate.resolved == 1) 1946 { 1947 /* Immediate addressing uses upper 8 bits of address. */ 1948 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF) 1949 { 1950 as_bad (_("LDP instruction needs a 24-bit operand")); 1951 return; 1952 } 1953 insn.opcode |= 1954 ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16); 1955 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1956 } 1957 else 1958 { 1959 fixS *fix; 1960 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1961 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1962 1, &insn.operand_type[0]->immediate.imm_expr, 1963 0, 0); 1964 fix->fx_no_overflow = 1; 1965 } 1966 } 1967 } 1968 else if (insn.tm->operand_types[0] & (Imm24)) 1969 { 1970 /* Unconditional Branch and Call instructions. */ 1971 if (insn.operand_type[0]->immediate.resolved == 1) 1972 { 1973 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF) 1974 as_warn (_("first operand is too large for a 24-bit displacement")); 1975 insn.opcode |= 1976 (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF); 1977 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1978 } 1979 else 1980 { 1981 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1982 fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3, 1983 & insn.operand_type[0]->immediate.imm_expr, 0, 0); 1984 } 1985 } 1986 else if (insn.tm->operand_types[0] & NotReq) 1987 /* Check for NOP instruction without arguments. */ 1988 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1989 1990 else if (insn.tm->operands == 0) 1991 /* Check for instructions without operands. */ 1992 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE); 1993 } 1994 debug ("Addressing mode: %08X\n", insn.addressing_mode); 1995 { 1996 unsigned int i; 1997 1998 for (i = 0; i < insn.operands; i++) 1999 { 2000 if (insn.operand_type[i]->immediate.label) 2001 free (insn.operand_type[i]->immediate.label); 2002 free (insn.operand_type[i]); 2003 } 2004 } 2005 debug ("Final opcode: %08X\n", insn.opcode); 2006 debug ("\n"); 2007} 2008