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