1 /* tc-metag.c -- Assembler for the Imagination Technologies Meta. 2 Copyright (C) 2013-2014 Free Software Foundation, Inc. 3 Contributed by Imagination Technologies Ltd. 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 #include "as.h" 23 #include "subsegs.h" 24 #include "symcat.h" 25 #include "safe-ctype.h" 26 #include "hashtab.h" 27 #include "libbfd.h" 28 29 #include <stdio.h> 30 31 #include "opcode/metag.h" 32 33 const char comment_chars[] = "!"; 34 const char line_comment_chars[] = "!#"; 35 const char line_separator_chars[] = ";"; 36 const char FLT_CHARS[] = "rRsSfFdDxXpP"; 37 const char EXP_CHARS[] = "eE"; 38 const char metag_symbol_chars[] = "["; 39 40 static char register_chars[256]; 41 static char mnemonic_chars[256]; 42 43 #define is_register_char(x) (register_chars[(unsigned char) x]) 44 #define is_mnemonic_char(x) (mnemonic_chars[(unsigned char) x]) 45 #define is_whitespace_char(x) (((x) == ' ') || ((x) == '\t')) 46 #define is_space_char(x) ((x) == ' ') 47 48 #define FPU_PREFIX_CHAR 'f' 49 #define DSP_PREFIX_CHAR 'd' 50 51 /* Instruction mnemonics that need disambiguating with respect to prefixes. */ 52 #define FFB_INSN "ffb" 53 #define DCACHE_INSN "dcache" 54 #define DEFR_INSN "defr" 55 56 #define FPU_DOUBLE_CHAR 'd' 57 #define FPU_PAIR_CHAR 'l' 58 59 #define DSP_DUAL_CHAR 'l' 60 61 #define END_OF_INSN '\0' 62 63 /* Maximum length of a mnemonic including all suffixes. */ 64 #define MAX_MNEMONIC_LEN 16 65 /* Maximum length of a register name. */ 66 #define MAX_REG_LEN 17 67 68 /* Addressing modes must be enclosed with square brackets. */ 69 #define ADDR_BEGIN_CHAR '[' 70 #define ADDR_END_CHAR ']' 71 /* Immediates must be prefixed with a hash. */ 72 #define IMM_CHAR '#' 73 74 #define COMMA ',' 75 #define PLUS '+' 76 #define MINUS '-' 77 78 /* Short units are those that can be encoded with 2 bits. */ 79 #define SHORT_UNITS "D0, D1, A0 or A1" 80 81 static unsigned int mcpu_opt = CoreMeta12; 82 static unsigned int mfpu_opt = 0; 83 static unsigned int mdsp_opt = 0; 84 85 const char * md_shortopts = "m:"; 86 87 struct option md_longopts[] = 88 { 89 {NULL, no_argument, NULL, 0} 90 }; 91 size_t md_longopts_size = sizeof (md_longopts); 92 93 /* Parser hash tables. */ 94 static htab_t mnemonic_htab; 95 static htab_t reg_htab; 96 static htab_t dsp_reg_htab; 97 static htab_t dsp_tmpl_reg_htab[2]; 98 static htab_t scond_htab; 99 100 #define GOT_NAME "__GLOBAL_OFFSET_TABLE__" 101 symbolS * GOT_symbol; 102 103 enum fpu_insn_width { 104 FPU_WIDTH_SINGLE, 105 FPU_WIDTH_DOUBLE, 106 FPU_WIDTH_PAIR, 107 }; 108 109 #define FPU_ACTION_ABS_CHAR 'a' 110 #define FPU_ACTION_INV_CHAR 'i' 111 #define FPU_ACTION_QUIET_CHAR 'q' 112 #define FPU_ACTION_ZERO_CHAR 'z' 113 114 #define FPU_ACTION_ABS 0x1 115 #define FPU_ACTION_INV 0x2 116 #define FPU_ACTION_QUIET 0x4 117 #define FPU_ACTION_ZERO 0x8 118 119 enum dsp_insn_width { 120 DSP_WIDTH_SINGLE, 121 DSP_WIDTH_DUAL, 122 }; 123 124 #define DSP_ACTION_QR64_CHAR 'q' 125 #define DSP_ACTION_UMUL_CHAR 'u' 126 #define DSP_ACTION_ROUND_CHAR 'r' 127 #define DSP_ACTION_CLAMP9_CHAR 'g' 128 #define DSP_ACTION_CLAMP8_CHAR 'b' 129 #define DSP_ACTION_MOD_CHAR 'm' 130 #define DSP_ACTION_ACC_ZERO_CHAR 'z' 131 #define DSP_ACTION_ACC_ADD_CHAR 'p' 132 #define DSP_ACTION_ACC_SUB_CHAR 'n' 133 #define DSP_ACTION_OV_CHAR 'o' 134 135 #define DSP_ACTION_QR64 0x001 136 #define DSP_ACTION_UMUL 0x002 137 #define DSP_ACTION_ROUND 0x004 138 #define DSP_ACTION_CLAMP9 0x008 139 #define DSP_ACTION_CLAMP8 0x010 140 #define DSP_ACTION_MOD 0x020 141 #define DSP_ACTION_ACC_ZERO 0x040 142 #define DSP_ACTION_ACC_ADD 0x080 143 #define DSP_ACTION_ACC_SUB 0x100 144 #define DSP_ACTION_OV 0x200 145 146 #define DSP_DAOPPAME_8_CHAR 'b' 147 #define DSP_DAOPPAME_16_CHAR 'w' 148 #define DSP_DAOPPAME_TEMP_CHAR 't' 149 #define DSP_DAOPPAME_HIGH_CHAR 'h' 150 151 #define DSP_DAOPPAME_8 0x1 152 #define DSP_DAOPPAME_16 0x2 153 #define DSP_DAOPPAME_TEMP 0x4 154 #define DSP_DAOPPAME_HIGH 0x8 155 156 /* Structure holding information about a parsed instruction. */ 157 typedef struct { 158 /* Instruction type. */ 159 enum insn_type type; 160 /* Split condition code. */ 161 enum scond_code scond; 162 163 /* Instruction bits. */ 164 unsigned int bits; 165 /* Size of the instruction in bytes. */ 166 size_t len; 167 168 /* FPU instruction encoding. */ 169 enum fpu_insn_width fpu_width; 170 unsigned int fpu_action_flags; 171 172 /* DSP instruction encoding. */ 173 enum dsp_insn_width dsp_width; 174 unsigned int dsp_action_flags; 175 unsigned int dsp_daoppame_flags; 176 177 /* Reloc encoding information, maximum of one reloc per insn. */ 178 enum bfd_reloc_code_real reloc_type; 179 int reloc_pcrel; 180 expressionS reloc_exp; 181 unsigned int reloc_size; 182 } metag_insn; 183 184 /* Structure holding information about a parsed addressing mode. */ 185 typedef struct { 186 const metag_reg *base_reg; 187 const metag_reg *offset_reg; 188 189 expressionS exp; 190 191 enum bfd_reloc_code_real reloc_type; 192 193 /* Whether we have an immediate or not. */ 194 unsigned short immediate:1; 195 /* Whether or not the base register is updated. */ 196 unsigned short update:1; 197 /* Whether the operation uses the address pre or post increment. */ 198 unsigned short post_increment:1; 199 /* Whether the immediate should be negated. */ 200 unsigned short negate:1; 201 } metag_addr; 202 203 /* Linked list of possible parsers for this instruction. */ 204 typedef struct _insn_templates { 205 const insn_template *template; 206 struct _insn_templates *next; 207 } insn_templates; 208 209 /* Parse an instruction that takes no operands. */ 210 static const char * 211 parse_none (const char *line, metag_insn *insn, 212 const insn_template *template) 213 { 214 insn->bits = template->meta_opcode; 215 insn->len = 4; 216 return line; 217 } 218 219 /* Return the next non-whitespace character in LINE or NULL. */ 220 static const char * 221 skip_whitespace (const char *line) 222 { 223 const char *l = line; 224 225 if (is_whitespace_char (*l)) 226 { 227 l++; 228 } 229 230 return l; 231 } 232 233 /* Return the next non-space character in LINE or NULL. */ 234 static const char * 235 skip_space (const char *line) 236 { 237 const char *l = line; 238 239 if (is_space_char (*l)) 240 { 241 l++; 242 } 243 244 return l; 245 } 246 247 /* Return the character after the current one in LINE if the current 248 character is a comma, otherwise NULL. */ 249 static const char * 250 skip_comma (const char *line) 251 { 252 const char *l = line; 253 254 if (l == NULL || *l != COMMA) 255 return NULL; 256 257 l++; 258 259 return l; 260 } 261 262 /* Return the metag_reg struct corresponding to NAME or NULL if no such 263 register exists. */ 264 static const metag_reg * 265 parse_gp_reg (const char *name) 266 { 267 const metag_reg *reg; 268 metag_reg entry; 269 270 entry.name = name; 271 272 reg = (const metag_reg *) htab_find (reg_htab, &entry); 273 274 return reg; 275 } 276 277 /* Parse a list of up to COUNT GP registers from LINE, returning the 278 registers parsed in REGS and the number parsed in REGS_READ. Return 279 a pointer to the next character or NULL. */ 280 static const char * 281 parse_gp_regs_list (const char *line, const metag_reg **regs, size_t count, 282 size_t *regs_read) 283 { 284 const char *l = line; 285 char reg_buf[MAX_REG_LEN]; 286 int seen_regs = 0; 287 size_t i; 288 289 for (i = 0; i < count; i++) 290 { 291 size_t len = 0; 292 const char *next; 293 294 next = l; 295 296 if (i > 0) 297 { 298 l = skip_comma (l); 299 if (l == NULL) 300 { 301 *regs_read = seen_regs; 302 return next; 303 } 304 } 305 306 while (is_register_char (*l)) 307 { 308 reg_buf[len] = *l; 309 l++; 310 len++; 311 if (!(len < MAX_REG_LEN)) 312 return NULL; 313 } 314 315 reg_buf[len] = '\0'; 316 317 if (len) 318 { 319 const metag_reg *reg = parse_gp_reg (reg_buf); 320 321 if (!reg) 322 { 323 *regs_read = seen_regs; 324 return next; 325 } 326 else 327 { 328 regs[i] = reg; 329 seen_regs++; 330 } 331 } 332 else 333 { 334 *regs_read = seen_regs; 335 return next; 336 } 337 } 338 339 *regs_read = seen_regs; 340 return l; 341 } 342 343 /* Parse a list of exactly COUNT GP registers from LINE, returning the 344 registers parsed in REGS. Return a pointer to the next character or NULL. */ 345 static const char * 346 parse_gp_regs (const char *line, const metag_reg **regs, size_t count) 347 { 348 const char *l = line; 349 size_t regs_read = 0; 350 351 l = parse_gp_regs_list (l, regs, count, ®s_read); 352 353 if (regs_read != count) 354 return NULL; 355 else 356 return l; 357 } 358 359 /* Parse a list of exactly COUNT FPU registers from LINE, returning the 360 registers parsed in REGS. Return a pointer to the next character or NULL. */ 361 static const char * 362 parse_fpu_regs (const char *line, const metag_reg **regs, size_t count) 363 { 364 const char *l = line; 365 size_t regs_read = 0; 366 367 l = parse_gp_regs_list (l, regs, count, ®s_read); 368 369 if (regs_read != count) 370 return NULL; 371 else 372 { 373 size_t i; 374 for (i = 0; i < count; i++) 375 { 376 if (regs[i]->unit != UNIT_FX) 377 return NULL; 378 } 379 return l; 380 } 381 } 382 383 /* Return TRUE if REG1 and REG2 are in paired units. */ 384 static bfd_boolean 385 is_unit_pair (const metag_reg *reg1, const metag_reg *reg2) 386 { 387 if ((reg1->unit == UNIT_A0 && 388 (reg2->unit == UNIT_A1)) || 389 (reg1->unit == UNIT_A1 && 390 (reg2->unit == UNIT_A0)) || 391 (reg1->unit == UNIT_D0 && 392 (reg2->unit == UNIT_D1)) || 393 (reg1->unit == UNIT_D1 && 394 (reg2->unit == UNIT_D0))) 395 return TRUE; 396 397 return FALSE; 398 } 399 400 /* Return TRUE if REG1 and REG2 form a register pair. */ 401 static bfd_boolean 402 is_reg_pair (const metag_reg *reg1, const metag_reg *reg2) 403 { 404 if (reg1->unit == UNIT_FX && 405 reg2->unit == UNIT_FX && 406 reg2->no == reg1->no + 1) 407 return TRUE; 408 409 if (reg1->no != reg2->no) 410 return FALSE; 411 412 return is_unit_pair (reg1, reg2); 413 } 414 415 /* Parse a pair of GP registers from LINE, returning the registers parsed 416 in REGS. Return a pointer to the next character or NULL. */ 417 static const char * 418 parse_pair_gp_regs (const char *line, const metag_reg **regs) 419 { 420 const char *l = line; 421 422 l = parse_gp_regs (line, regs, 2); 423 424 if (l == NULL) 425 { 426 l = parse_gp_regs (line, regs, 1); 427 428 if (l == NULL) 429 return NULL; 430 431 if (regs[0]->unit == UNIT_RD) 432 return l; 433 else 434 return NULL; 435 } 436 437 if (is_reg_pair (regs[0], regs[1])) 438 return l; 439 440 return NULL; 441 } 442 443 /* Parse a unit-to-unit MOV instruction. */ 444 static const char * 445 parse_mov_u2u (const char *line, metag_insn *insn, 446 const insn_template *template) 447 { 448 const metag_reg *regs[2]; 449 450 line = parse_gp_regs (line, regs, 2); 451 452 if (line == NULL) 453 return NULL; 454 455 if (!mfpu_opt && (regs[0]->unit == UNIT_FX || regs[1]->unit == UNIT_FX)) 456 { 457 as_bad (_("no floating point unit specified")); 458 return NULL; 459 } 460 461 insn->bits = (template->meta_opcode | 462 (regs[1]->no << 19) | 463 (regs[0]->no << 14) | 464 (regs[1]->unit << 10) | 465 (regs[0]->unit << 5)); 466 insn->len = 4; 467 return line; 468 } 469 470 /* Parse a MOV to port instruction. */ 471 static const char * 472 parse_mov_port (const char *line, metag_insn *insn, 473 const insn_template *template) 474 { 475 const char *l = line; 476 unsigned int is_movl = MINOR_OPCODE (template->meta_opcode) == MOVL_MINOR; 477 const metag_reg *dest_regs[2]; 478 const metag_reg *port_regs[1]; 479 480 if (is_movl) 481 l = parse_gp_regs (l, dest_regs, 2); 482 else 483 l = parse_gp_regs (l, dest_regs, 1); 484 485 if (l == NULL) 486 return NULL; 487 488 if (template->insn_type == INSN_FPU && dest_regs[0]->unit != UNIT_FX) 489 return NULL; 490 491 l = skip_comma (l); 492 493 if (l == NULL || 494 *l == END_OF_INSN) 495 return NULL; 496 497 l = parse_gp_regs (l, port_regs, 1); 498 499 if (l == NULL) 500 return NULL; 501 502 if (port_regs[0]->unit != UNIT_RD || 503 port_regs[0]->no != 0) 504 return NULL; 505 506 if (is_movl) 507 { 508 if (!is_unit_pair (dest_regs[0], dest_regs[1])) 509 return NULL; 510 511 insn->bits = (template->meta_opcode | 512 (dest_regs[0]->no << 14) | 513 (dest_regs[1]->no << 9) | 514 ((dest_regs[0]->unit & SHORT_UNIT_MASK) << 5)); 515 } 516 else 517 insn->bits = (template->meta_opcode | 518 (dest_regs[0]->no << 14) | 519 (dest_regs[0]->unit << 5)); 520 521 insn->len = 4; 522 return l; 523 } 524 525 /* Parse a MOVL to TTREC instruction. */ 526 static const char * 527 parse_movl_ttrec (const char *line, metag_insn *insn, 528 const insn_template *template) 529 { 530 const char *l = line; 531 const metag_reg *src_regs[2]; 532 const metag_reg *dest_regs[1]; 533 534 l = parse_gp_regs (l, dest_regs, 1); 535 536 if (l == NULL) 537 return NULL; 538 539 if (dest_regs[0]->unit != UNIT_TT || 540 dest_regs[0]->no != 3) 541 return NULL; 542 543 l = skip_comma (l); 544 545 if (l == NULL || 546 *l == END_OF_INSN) 547 return NULL; 548 549 l = parse_gp_regs (l, src_regs, 2); 550 551 if (l == NULL) 552 return NULL; 553 554 if (!is_unit_pair (src_regs[0], src_regs[1])) 555 return NULL; 556 557 insn->bits = (template->meta_opcode | 558 (src_regs[0]->no << 19) | 559 (src_regs[1]->no << 14) | 560 ((src_regs[0]->unit & SHORT_UNIT_MASK) << 7)); 561 562 insn->len = 4; 563 return l; 564 } 565 566 /* Parse an incrementing or decrementing addressing mode. */ 567 static const char * 568 parse_addr_incr_op (const char *line, metag_addr *addr) 569 { 570 const char *l = line; 571 const char *ll; 572 573 ll = l + 1; 574 575 if (*l == PLUS && 576 *ll == PLUS) 577 { 578 addr->update = 1; 579 ll++; 580 return ll; 581 } 582 else if (*l == MINUS && 583 *ll == MINUS) 584 { 585 addr->update = 1; 586 addr->negate = 1; 587 ll++; 588 return ll; 589 } 590 return NULL; 591 } 592 593 /* Parse an pre-incrementing or pre-decrementing addressing mode. */ 594 static const char * 595 parse_addr_pre_incr_op (const char *line, metag_addr *addr) 596 { 597 return parse_addr_incr_op (line, addr); 598 } 599 600 /* Parse an post-incrementing or post-decrementing addressing mode. */ 601 static const char * 602 parse_addr_post_incr_op (const char *line, metag_addr *addr) 603 { 604 const char *l; 605 606 l = parse_addr_incr_op (line, addr); 607 608 if (l == NULL) 609 return NULL; 610 611 addr->post_increment = 1; 612 613 return l; 614 } 615 616 /* Parse an infix addressing mode. */ 617 static const char * 618 parse_addr_op (const char *line, metag_addr *addr) 619 { 620 const char *l = line; 621 const char *ll; 622 623 ll = l + 1; 624 625 if (*l == PLUS) 626 { 627 if (*ll == PLUS) 628 { 629 addr->update = 1; 630 ll++; 631 return ll; 632 } 633 l++; 634 return l; 635 } 636 return NULL; 637 } 638 639 /* Parse the immediate portion of an addrssing mode. */ 640 static const char * 641 parse_imm_addr (const char *line, metag_addr *addr) 642 { 643 const char *l = line; 644 char *save_input_line_pointer; 645 expressionS *exp = &addr->exp; 646 647 /* Skip #. */ 648 if (*l == '#') 649 l++; 650 else 651 return NULL; 652 653 save_input_line_pointer = input_line_pointer; 654 input_line_pointer = (char *) l; 655 656 expression (exp); 657 658 l = input_line_pointer; 659 input_line_pointer = save_input_line_pointer; 660 661 if (exp->X_op == O_absent || exp->X_op == O_big) 662 { 663 return NULL; 664 } 665 else if (exp->X_op == O_constant) 666 { 667 return l; 668 } 669 else 670 { 671 if (exp->X_op == O_PIC_reloc && 672 exp->X_md == BFD_RELOC_METAG_GETSET_GOT) 673 { 674 exp->X_op = O_symbol; 675 addr->reloc_type = BFD_RELOC_METAG_GETSET_GOT; 676 } 677 else if (exp->X_op == O_PIC_reloc && 678 exp->X_md == BFD_RELOC_METAG_TLS_IE) 679 { 680 exp->X_op = O_symbol; 681 addr->reloc_type = BFD_RELOC_METAG_TLS_IE; 682 } 683 else if (exp->X_op == O_PIC_reloc && 684 exp->X_md == BFD_RELOC_METAG_GOTOFF) 685 { 686 exp->X_op = O_symbol; 687 addr->reloc_type = BFD_RELOC_METAG_GETSET_GOTOFF; 688 } 689 else 690 addr->reloc_type = BFD_RELOC_METAG_GETSETOFF; 691 return l; 692 } 693 } 694 695 /* Parse the offset portion of an addressing mode (register or immediate). */ 696 static const char * 697 parse_addr_offset (const char *line, metag_addr *addr, int size) 698 { 699 const char *l = line; 700 const metag_reg *regs[1]; 701 702 if (*l == IMM_CHAR) 703 { 704 /* ++ is a valid operator in our addressing but not in an expr. Make 705 sure that the expression parser never sees it. */ 706 char *ppp = strstr(l, "++"); 707 char ppch = '+'; 708 709 if (ppp) 710 *ppp = '\0'; 711 712 l = parse_imm_addr (l, addr); 713 714 if (ppp) 715 *ppp = ppch; 716 717 if (l == NULL) 718 return NULL; 719 720 if (addr->exp.X_add_number % size) 721 { 722 as_bad (_("offset must be a multiple of %d"), size); 723 return NULL; 724 } 725 726 addr->immediate = 1; 727 return l; 728 } 729 else 730 { 731 l = parse_gp_regs (l, regs, 1); 732 733 if (l == NULL) 734 return NULL; 735 736 if (regs[0]->unit != addr->base_reg->unit) 737 { 738 as_bad (_("offset and base must be from the same unit")); 739 return NULL; 740 } 741 742 addr->offset_reg = regs[0]; 743 return l; 744 } 745 } 746 747 /* Parse an addressing mode. */ 748 static const char * 749 parse_addr (const char *line, metag_addr *addr, unsigned int size) 750 { 751 const char *l = line; 752 const char *ll; 753 const metag_reg *regs[1]; 754 755 /* Skip opening square bracket. */ 756 l++; 757 758 ll = parse_addr_pre_incr_op (l, addr); 759 760 if (ll != NULL) 761 l = ll; 762 763 l = parse_gp_regs (l, regs, 1); 764 765 if (l == NULL) 766 return NULL; 767 768 addr->base_reg = regs[0]; 769 770 if (*l == ADDR_END_CHAR) 771 { 772 addr->exp.X_op = O_constant; 773 addr->exp.X_add_symbol = NULL; 774 addr->exp.X_op_symbol = NULL; 775 if (addr->update == 1) 776 { 777 /* We have a pre increment/decrement. */ 778 addr->exp.X_add_number = size; 779 } 780 else 781 { 782 /* Simple register with no offset (0 immediate). */ 783 addr->exp.X_add_number = 0; 784 } 785 addr->immediate = 1; 786 l++; 787 return l; 788 } 789 790 /* We already had a pre increment/decrement. */ 791 if (addr->update == 1) 792 return NULL; 793 794 ll = parse_addr_post_incr_op (l, addr); 795 796 if (ll && *ll == ADDR_END_CHAR) 797 { 798 if (addr->update == 1) 799 { 800 /* We have a post increment/decrement. */ 801 addr->exp.X_op = O_constant; 802 addr->exp.X_add_number = size; 803 addr->exp.X_add_symbol = NULL; 804 addr->exp.X_op_symbol = NULL; 805 addr->post_increment = 1; 806 } 807 addr->immediate = 1; 808 ll++; 809 return ll; 810 } 811 812 addr->post_increment = 0; 813 814 l = parse_addr_op (l, addr); 815 816 if (l == NULL) 817 return NULL; 818 819 l = parse_addr_offset (l, addr, size); 820 821 if (l == NULL) 822 return NULL; 823 824 if (*l == ADDR_END_CHAR) 825 { 826 l++; 827 return l; 828 } 829 830 /* We already had a pre increment/decrement. */ 831 if (addr->update == 1) 832 return NULL; 833 834 l = parse_addr_post_incr_op (l, addr); 835 836 if (l == NULL) 837 return NULL; 838 839 if (*l == ADDR_END_CHAR) 840 { 841 l++; 842 return l; 843 } 844 845 return NULL; 846 } 847 848 /* Parse a GET or pipeline MOV instruction. */ 849 static const char * 850 parse_get (const char *line, const metag_reg **regs, metag_addr *addr, 851 unsigned int size, bfd_boolean is_mov) 852 { 853 const char *l = line; 854 855 if (size == 8) 856 { 857 l = parse_pair_gp_regs (l, regs); 858 859 if (l == NULL) 860 return NULL; 861 } 862 else 863 { 864 l = parse_gp_regs (l, regs, 1); 865 866 if (l == NULL) 867 { 868 if (!is_mov) 869 as_bad (_("invalid destination register")); 870 return NULL; 871 } 872 } 873 874 l = skip_comma (l); 875 876 if (l == NULL || 877 *l == END_OF_INSN) 878 return NULL; 879 880 l = parse_addr (l, addr, size); 881 882 if (l == NULL) 883 { 884 if (!is_mov) 885 as_bad (_("invalid memory operand")); 886 return NULL; 887 } 888 889 return l; 890 } 891 892 /* Parse a SET instruction. */ 893 static const char * 894 parse_set (const char *line, const metag_reg **regs, metag_addr *addr, 895 unsigned int size) 896 { 897 const char *l = line; 898 899 l = parse_addr (l, addr, size); 900 901 if (l == NULL) 902 { 903 as_bad (_("invalid memory operand")); 904 return NULL; 905 } 906 907 l = skip_comma (l); 908 909 if (l == NULL || 910 *l == END_OF_INSN) 911 return NULL; 912 913 if (size == 8) 914 { 915 const char *ll = l; 916 917 ll = parse_pair_gp_regs (l, regs); 918 919 if (ll == NULL) 920 { 921 /* Maybe this is an RD register, which is 64 bits wide so needs no 922 pair. */ 923 l = parse_gp_regs (l, regs, 1); 924 925 if (l == NULL || 926 regs[0]->unit != UNIT_RD) 927 { 928 return NULL; 929 } 930 } 931 else 932 l = ll; 933 } 934 else 935 { 936 l = parse_gp_regs (l, regs, 1); 937 938 if (l == NULL) 939 { 940 as_bad (_("invalid source register")); 941 return NULL; 942 } 943 } 944 945 return l; 946 } 947 948 /* Check a signed integer value can be represented in the given number 949 of bits. */ 950 static bfd_boolean 951 within_signed_range (int value, unsigned int bits) 952 { 953 int min_val = -(1 << (bits - 1)); 954 int max_val = (1 << (bits - 1)) - 1; 955 return (value <= max_val) && (value >= min_val); 956 } 957 958 /* Check an unsigned integer value can be represented in the given number 959 of bits. */ 960 static bfd_boolean 961 within_unsigned_range (unsigned int value, unsigned int bits) 962 { 963 return value < (unsigned int)(1 << bits); 964 } 965 966 /* Return TRUE if UNIT can be expressed using a short code. */ 967 static bfd_boolean 968 is_short_unit (enum metag_unit unit) 969 { 970 switch (unit) 971 { 972 case UNIT_A0: 973 case UNIT_A1: 974 case UNIT_D0: 975 case UNIT_D1: 976 return TRUE; 977 default: 978 return FALSE; 979 } 980 } 981 982 /* Copy reloc data from ADDR to INSN. */ 983 static void 984 copy_addr_reloc (metag_insn *insn, metag_addr *addr) 985 { 986 memcpy (&insn->reloc_exp, &addr->exp, sizeof(insn->reloc_exp)); 987 insn->reloc_type = addr->reloc_type; 988 } 989 990 /* Parse a GET, SET or pipeline MOV instruction. */ 991 static const char * 992 parse_get_set (const char *line, metag_insn *insn, 993 const insn_template *template) 994 { 995 const char *l = line; 996 const metag_reg *regs[2]; 997 metag_addr addr; 998 unsigned int size = metag_get_set_size_bytes (template->meta_opcode); 999 bfd_boolean is_get = MAJOR_OPCODE (template->meta_opcode) == OPC_GET; 1000 unsigned int reg_no; 1001 1002 memset(&addr, 0, sizeof(addr)); 1003 addr.reloc_type = BFD_RELOC_UNUSED; 1004 1005 if (is_get) 1006 { 1007 bfd_boolean is_mov = strncmp (template->name, "MOV", 3) == 0; 1008 1009 l = parse_get (l, regs, &addr, size, is_mov); 1010 1011 if (l == NULL) 1012 return NULL; 1013 1014 if (!(regs[0]->unit == UNIT_D0 || 1015 regs[0]->unit == UNIT_D1 || 1016 regs[0]->unit == UNIT_A0 || 1017 regs[0]->unit == UNIT_A1 || 1018 (regs[0]->unit == UNIT_RD && is_mov) || 1019 (regs[0]->unit == UNIT_CT && size == 4) || 1020 (regs[0]->unit == UNIT_PC && size == 4) || 1021 (regs[0]->unit == UNIT_TR && size == 4) || 1022 (regs[0]->unit == UNIT_TT && (size == 4 || size == 8)) || 1023 regs[0]->unit == UNIT_FX)) 1024 { 1025 as_bad (_("invalid destination unit")); 1026 return NULL; 1027 } 1028 1029 if (regs[0]->unit == UNIT_RD) 1030 { 1031 if (regs[0]->no == 0) 1032 { 1033 as_bad (_("mov cannot use RD port as destination")); 1034 return NULL; 1035 } 1036 } 1037 1038 reg_no = regs[0]->no; 1039 } 1040 else 1041 { 1042 l = parse_set (l, regs, &addr, size); 1043 1044 if (l == NULL) 1045 return NULL; 1046 1047 if (!(regs[0]->unit == UNIT_D0 || 1048 regs[0]->unit == UNIT_D1 || 1049 regs[0]->unit == UNIT_A0 || 1050 regs[0]->unit == UNIT_A1 || 1051 regs[0]->unit == UNIT_RD || 1052 (regs[0]->unit == UNIT_CT && size == 4) || 1053 (regs[0]->unit == UNIT_PC && size == 4) || 1054 (regs[0]->unit == UNIT_TR && size == 4) || 1055 (regs[0]->unit == UNIT_TT && (size == 4 || size == 8)) || 1056 regs[0]->unit == UNIT_FX)) 1057 { 1058 as_bad (_("invalid source unit")); 1059 return NULL; 1060 } 1061 1062 if (addr.immediate == 0 && 1063 (regs[0]->unit == addr.base_reg->unit || 1064 (size == 8 && is_unit_pair (regs[0], addr.base_reg)))) 1065 { 1066 as_bad (_("source and address units must not be shared for this addressing mode")); 1067 return NULL; 1068 } 1069 1070 if (regs[0]->unit == UNIT_RD) 1071 { 1072 if (regs[0]->no != 0) 1073 { 1074 as_bad (_("set can only use RD port as source")); 1075 return NULL; 1076 } 1077 reg_no = 16; 1078 } 1079 else 1080 reg_no = regs[0]->no; 1081 } 1082 1083 insn->bits = (template->meta_opcode | 1084 (reg_no << 19) | 1085 (regs[0]->unit << 1)); 1086 1087 if (!is_short_unit (addr.base_reg->unit)) 1088 { 1089 as_bad (_("base unit must be one of %s"), SHORT_UNITS); 1090 return NULL; 1091 } 1092 1093 insn->bits |= ((addr.base_reg->no << 14) | 1094 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5)); 1095 1096 if (addr.immediate) 1097 { 1098 int offset = addr.exp.X_add_number; 1099 1100 copy_addr_reloc (insn, &addr); 1101 1102 if (addr.negate) 1103 offset = -offset; 1104 1105 offset = offset / (int)size; 1106 1107 if (!within_signed_range (offset, GET_SET_IMM_BITS)) 1108 { 1109 /* We already tried to encode as an extended GET/SET. */ 1110 as_bad (_("offset value out of range")); 1111 return NULL; 1112 } 1113 1114 offset = offset & GET_SET_IMM_MASK; 1115 1116 insn->bits |= (0x1 << 25); 1117 insn->bits |= (offset << 8); 1118 } 1119 else 1120 { 1121 insn->bits |= (addr.offset_reg->no << 9); 1122 } 1123 1124 if (addr.update) 1125 insn->bits |= (0x1 << 7); 1126 1127 if (addr.post_increment) 1128 insn->bits |= 0x1; 1129 1130 insn->len = 4; 1131 return l; 1132 } 1133 1134 /* Parse an extended GET or SET instruction. */ 1135 static const char * 1136 parse_get_set_ext (const char *line, metag_insn *insn, 1137 const insn_template *template) 1138 { 1139 const char *l = line; 1140 const metag_reg *regs[2]; 1141 metag_addr addr; 1142 unsigned int size = metag_get_set_ext_size_bytes (template->meta_opcode); 1143 bfd_boolean is_get = MINOR_OPCODE (template->meta_opcode) == GET_EXT_MINOR; 1144 bfd_boolean is_mov = MINOR_OPCODE (template->meta_opcode) == MOV_EXT_MINOR; 1145 unsigned int reg_unit; 1146 1147 memset(&addr, 0, sizeof(addr)); 1148 addr.reloc_type = BFD_RELOC_UNUSED; 1149 1150 if (is_get || is_mov) 1151 { 1152 l = parse_get (l, regs, &addr, size, is_mov); 1153 } 1154 else 1155 { 1156 l = parse_set (l, regs, &addr, size); 1157 } 1158 1159 if (l == NULL) 1160 return NULL; 1161 1162 /* Extended GET/SET does not support incrementing addressing. */ 1163 if (addr.update) 1164 return NULL; 1165 1166 if (is_mov) 1167 { 1168 if (regs[0]->unit != UNIT_RD) 1169 { 1170 as_bad (_("destination unit must be RD")); 1171 return NULL; 1172 } 1173 reg_unit = 0; 1174 } 1175 else 1176 { 1177 if (!is_short_unit (regs[0]->unit)) 1178 { 1179 return NULL; 1180 } 1181 reg_unit = regs[0]->unit; 1182 } 1183 1184 insn->bits = (template->meta_opcode | 1185 (regs[0]->no << 19) | 1186 ((reg_unit & SHORT_UNIT_MASK) << 3)); 1187 1188 if (!is_short_unit (addr.base_reg->unit)) 1189 { 1190 as_bad (_("base unit must be one of %s"), SHORT_UNITS); 1191 return NULL; 1192 } 1193 1194 if (addr.base_reg->no > 1) 1195 { 1196 return NULL; 1197 } 1198 1199 insn->bits |= ((addr.base_reg->no & EXT_BASE_REG_MASK) | 1200 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5)); 1201 1202 if (addr.immediate) 1203 { 1204 int offset = addr.exp.X_add_number; 1205 1206 copy_addr_reloc (insn, &addr); 1207 1208 if (addr.negate) 1209 offset = -offset; 1210 1211 offset = offset / (int)size; 1212 1213 if (!within_signed_range (offset, GET_SET_EXT_IMM_BITS)) 1214 { 1215 /* Parsing as a standard GET/SET provides a smaller offset. */ 1216 as_bad (_("offset value out of range")); 1217 return NULL; 1218 } 1219 1220 offset = offset & GET_SET_EXT_IMM_MASK; 1221 1222 insn->bits |= (offset << 7); 1223 } 1224 else 1225 { 1226 return NULL; 1227 } 1228 1229 insn->len = 4; 1230 return l; 1231 } 1232 1233 /* Parse an MGET or MSET instruction addressing mode. */ 1234 static const char * 1235 parse_mget_mset_addr (const char *line, metag_addr *addr) 1236 { 1237 const char *l = line; 1238 const char *ll; 1239 const metag_reg *regs[1]; 1240 1241 /* Skip opening square bracket. */ 1242 l++; 1243 1244 l = parse_gp_regs (l, regs, 1); 1245 1246 if (l == NULL) 1247 return NULL; 1248 1249 addr->base_reg = regs[0]; 1250 1251 ll = parse_addr_post_incr_op (l, addr); 1252 1253 if (ll != NULL) 1254 l = ll; 1255 1256 if (addr->negate == 1) 1257 return NULL; 1258 1259 if (*l == ADDR_END_CHAR) 1260 { 1261 l++; 1262 return l; 1263 } 1264 1265 return NULL; 1266 } 1267 1268 /* Parse an MGET instruction. */ 1269 static const char * 1270 parse_mget (const char *line, const metag_reg **regs, metag_addr *addr, 1271 size_t *regs_read) 1272 { 1273 const char *l = line; 1274 1275 l = parse_gp_regs_list (l, regs, MGET_MSET_MAX_REGS, regs_read); 1276 1277 if (l == NULL || 1278 *regs_read == 0) 1279 { 1280 as_bad (_("invalid destination register list")); 1281 return NULL; 1282 } 1283 1284 l = skip_comma (l); 1285 1286 if (l == NULL || 1287 *l == END_OF_INSN) 1288 return NULL; 1289 1290 l = parse_mget_mset_addr (l, addr); 1291 1292 if (l == NULL) 1293 { 1294 as_bad (_("invalid memory operand")); 1295 return NULL; 1296 } 1297 1298 return l; 1299 } 1300 1301 /* Parse an MSET instruction. */ 1302 static const char * 1303 parse_mset (const char *line, const metag_reg **regs, metag_addr *addr, 1304 size_t *regs_read) 1305 { 1306 const char *l = line; 1307 1308 l = parse_mget_mset_addr (l, addr); 1309 1310 if (l == NULL) 1311 { 1312 as_bad (_("invalid memory operand")); 1313 return NULL; 1314 } 1315 1316 l = skip_comma (l); 1317 1318 if (l == NULL || 1319 *l == END_OF_INSN) 1320 return NULL; 1321 1322 l = parse_gp_regs_list (l, regs, MGET_MSET_MAX_REGS, regs_read); 1323 1324 if (l == NULL || 1325 *regs_read == 0) 1326 { 1327 as_bad (_("invalid source register list")); 1328 return NULL; 1329 } 1330 1331 return l; 1332 } 1333 1334 /* Take a register list REGS of size REGS_READ and convert it into an 1335 rmask value if possible. Return the rmask value in RMASK and the 1336 lowest numbered register in LOWEST_REG. Return TRUE if the conversion 1337 was successful. */ 1338 static bfd_boolean 1339 check_rmask (const metag_reg **regs, size_t regs_read, bfd_boolean is_fpu, 1340 bfd_boolean is_64bit, unsigned int *lowest_reg, 1341 unsigned int *rmask) 1342 { 1343 unsigned int reg_unit = regs[0]->unit; 1344 size_t i; 1345 1346 for (i = 0; i < regs_read; i++) 1347 { 1348 if (is_fpu) 1349 { 1350 if (is_64bit && regs[i]->no % 2) 1351 { 1352 as_bad (_("register list must be even numbered")); 1353 return FALSE; 1354 } 1355 } 1356 else if (regs[i]->unit != reg_unit) 1357 { 1358 as_bad (_("register list must be from the same unit")); 1359 return FALSE; 1360 } 1361 1362 if (regs[i]->no < *lowest_reg) 1363 *lowest_reg = regs[i]->no; 1364 } 1365 1366 for (i = 0; i < regs_read; i++) 1367 { 1368 unsigned int next_bit, next_reg; 1369 if (regs[i]->no == *lowest_reg) 1370 continue; 1371 1372 if (is_fpu && is_64bit) 1373 next_reg = ((regs[i]->no / 2) - ((*lowest_reg / 2) + 1)); 1374 else 1375 next_reg = (regs[i]->no - (*lowest_reg + 1)); 1376 1377 next_bit = (1 << next_reg); 1378 1379 if (*rmask & next_bit) 1380 { 1381 as_bad (_("register list must not contain duplicates")); 1382 return FALSE; 1383 } 1384 1385 *rmask |= next_bit; 1386 } 1387 1388 return TRUE; 1389 } 1390 1391 /* Parse an MGET or MSET instruction. */ 1392 static const char * 1393 parse_mget_mset (const char *line, metag_insn *insn, 1394 const insn_template *template) 1395 { 1396 const char *l = line; 1397 const metag_reg *regs[MGET_MSET_MAX_REGS]; 1398 metag_addr addr; 1399 bfd_boolean is_get = MAJOR_OPCODE (template->meta_opcode) == OPC_GET; 1400 bfd_boolean is_fpu = (MINOR_OPCODE (template->meta_opcode) & 0x6) == 0x6; 1401 bfd_boolean is_64bit = (MINOR_OPCODE (template->meta_opcode) & 0x1) == 0x1; 1402 size_t regs_read = 0; 1403 unsigned int rmask = 0, reg_unit = 0, lowest_reg = 0xffffffff; 1404 1405 memset(&addr, 0, sizeof(addr)); 1406 addr.reloc_type = BFD_RELOC_UNUSED; 1407 1408 if (is_get) 1409 { 1410 l = parse_mget (l, regs, &addr, ®s_read); 1411 } 1412 else 1413 { 1414 l = parse_mset (l, regs, &addr, ®s_read); 1415 } 1416 1417 if (l == NULL) 1418 return NULL; 1419 1420 if (!check_rmask (regs, regs_read, is_fpu, is_64bit, &lowest_reg, &rmask)) 1421 return NULL; 1422 1423 reg_unit = regs[0]->unit; 1424 1425 if (is_fpu) 1426 { 1427 if (reg_unit != UNIT_FX) 1428 return NULL; 1429 1430 reg_unit = 0; 1431 } 1432 else if (reg_unit == UNIT_FX) 1433 return NULL; 1434 1435 insn->bits = (template->meta_opcode | 1436 (lowest_reg << 19) | 1437 ((reg_unit & SHORT_UNIT_MASK) << 3)); 1438 1439 if (!is_short_unit (addr.base_reg->unit)) 1440 { 1441 as_bad (_("base unit must be one of %s"), SHORT_UNITS); 1442 return NULL; 1443 } 1444 1445 insn->bits |= ((addr.base_reg->no << 14) | 1446 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5)); 1447 1448 insn->bits |= (rmask & RMASK_MASK) << 7; 1449 1450 insn->len = 4; 1451 return l; 1452 } 1453 1454 /* Parse a list of registers for MMOV pipeline prime. */ 1455 static const char * 1456 parse_mmov_prime_list (const char *line, const metag_reg **regs, 1457 unsigned int *rmask) 1458 { 1459 const char *l = line; 1460 const metag_reg *ra_regs[MMOV_MAX_REGS]; 1461 size_t regs_read = 0, i; 1462 unsigned int mask = 0; 1463 1464 l = parse_gp_regs_list (l, regs, 1, ®s_read); 1465 1466 /* First register must be a port. */ 1467 if (l == NULL || regs[0]->unit != UNIT_RD) 1468 return NULL; 1469 1470 l = skip_comma (l); 1471 1472 if (l == NULL) 1473 return NULL; 1474 1475 l = parse_gp_regs_list (l, ra_regs, MMOV_MAX_REGS, ®s_read); 1476 1477 if (l == NULL) 1478 return NULL; 1479 1480 /* Check remaining registers match the first. 1481 1482 Note that we also accept RA (0x10) as input for the remaining registers. 1483 Whilst this doesn't represent the instruction in any way we're stuck 1484 with it because the embedded assembler accepts it. */ 1485 for (i = 0; i < regs_read; i++) 1486 { 1487 if (ra_regs[i]->unit != UNIT_RD || 1488 (ra_regs[i]->no != 0x10 && ra_regs[i]->no != regs[0]->no)) 1489 return NULL; 1490 1491 mask = (mask << 1) | 0x1; 1492 } 1493 1494 *rmask = mask; 1495 1496 return l; 1497 } 1498 1499 /* Parse a MMOV instruction. */ 1500 static const char * 1501 parse_mmov (const char *line, metag_insn *insn, 1502 const insn_template *template) 1503 { 1504 const char *l = line; 1505 unsigned int is_fpu = template->insn_type == INSN_FPU; 1506 unsigned int is_prime = ((MINOR_OPCODE (template->meta_opcode) & 0x2) && 1507 !is_fpu); 1508 unsigned int is_64bit = MINOR_OPCODE (template->meta_opcode) & 0x1; 1509 unsigned int rmask = 0; 1510 1511 if (is_prime) 1512 { 1513 const metag_reg *reg; 1514 metag_addr addr; 1515 1516 memset (&addr, 0, sizeof(addr)); 1517 1518 l = parse_mmov_prime_list (l, ®, &rmask); 1519 1520 if (l == NULL) 1521 return NULL; 1522 1523 l = skip_comma (l); 1524 1525 if (l == NULL) 1526 return NULL; 1527 1528 l = parse_mget_mset_addr (l, &addr); 1529 1530 if (l == NULL) 1531 { 1532 as_bad (_("invalid memory operand")); 1533 return NULL; 1534 } 1535 1536 insn->bits = (template->meta_opcode | 1537 (reg->no << 19) | 1538 (addr.base_reg->no << 14) | 1539 ((rmask & RMASK_MASK) << 7) | 1540 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5)); 1541 } 1542 else 1543 { 1544 const metag_reg *regs[MMOV_MAX_REGS + 1]; 1545 unsigned int lowest_reg = 0xffffffff; 1546 size_t regs_read = 0; 1547 1548 l = parse_gp_regs_list (l, regs, MMOV_MAX_REGS + 1, ®s_read); 1549 1550 if (l == NULL || regs_read == 0) 1551 return NULL; 1552 1553 if (!is_short_unit (regs[0]->unit) && 1554 !(is_fpu && regs[0]->unit == UNIT_FX)) 1555 { 1556 return NULL; 1557 } 1558 1559 if (!(regs[regs_read-1]->unit == UNIT_RD && 1560 regs[regs_read-1]->no == 0)) 1561 { 1562 return NULL; 1563 } 1564 1565 if (!check_rmask (regs, regs_read - 1, is_fpu, is_64bit, &lowest_reg, 1566 &rmask)) 1567 return NULL; 1568 1569 if (is_fpu) 1570 { 1571 insn->bits = (template->meta_opcode | 1572 (regs[0]->no << 14) | 1573 ((rmask & RMASK_MASK) << 7)); 1574 } 1575 else 1576 { 1577 insn->bits = (template->meta_opcode | 1578 (regs[0]->no << 19) | 1579 ((rmask & RMASK_MASK) << 7) | 1580 ((regs[0]->unit & SHORT_UNIT_MASK) << 3)); 1581 } 1582 } 1583 1584 insn->len = 4; 1585 return l; 1586 } 1587 1588 /* Parse an immediate constant. */ 1589 static const char * 1590 parse_imm_constant (const char *line, metag_insn *insn, int *value) 1591 { 1592 const char *l = line; 1593 char *save_input_line_pointer; 1594 expressionS *exp = &insn->reloc_exp; 1595 1596 /* Skip #. */ 1597 if (*l == '#') 1598 l++; 1599 else 1600 return NULL; 1601 1602 save_input_line_pointer = input_line_pointer; 1603 input_line_pointer = (char *) l; 1604 1605 expression (exp); 1606 1607 l = input_line_pointer; 1608 input_line_pointer = save_input_line_pointer; 1609 1610 if (exp->X_op == O_constant) 1611 { 1612 *value = exp->X_add_number; 1613 1614 return l; 1615 } 1616 else 1617 { 1618 return NULL; 1619 } 1620 } 1621 1622 /* Parse an MDRD instruction. */ 1623 static const char * 1624 parse_mdrd (const char *line, metag_insn *insn, 1625 const insn_template *template) 1626 { 1627 const char *l = line; 1628 unsigned int rmask = 0; 1629 int value = 0, i; 1630 1631 l = parse_imm_constant (l, insn, &value); 1632 1633 if (l == NULL) 1634 return NULL; 1635 1636 if (value < 1 || value > 8) 1637 { 1638 as_bad (_("MDRD value must be between 1 and 8")); 1639 return NULL; 1640 } 1641 1642 for (i = 1; i < value; i++) 1643 { 1644 rmask <<= 1; 1645 rmask |= 1; 1646 } 1647 1648 insn->bits = (template->meta_opcode | 1649 (rmask << 7)); 1650 1651 insn->len = 4; 1652 return l; 1653 } 1654 1655 /* Parse a conditional SET instruction. */ 1656 static const char * 1657 parse_cond_set (const char *line, metag_insn *insn, 1658 const insn_template *template) 1659 { 1660 const char *l = line; 1661 const metag_reg *regs[2]; 1662 metag_addr addr; 1663 unsigned int size = metag_cond_set_size_bytes (template->meta_opcode); 1664 unsigned int reg_no; 1665 1666 memset(&addr, 0, sizeof(addr)); 1667 addr.reloc_type = BFD_RELOC_UNUSED; 1668 1669 l = parse_set (l, regs, &addr, size); 1670 1671 if (l == NULL) 1672 return NULL; 1673 1674 if (regs[0]->unit == UNIT_RD) 1675 { 1676 if (regs[0]->no != 0) 1677 { 1678 as_bad (_("set can only use RD port as source")); 1679 return NULL; 1680 } 1681 reg_no = 16; 1682 } 1683 else 1684 reg_no = regs[0]->no; 1685 1686 if (addr.update) 1687 return NULL; 1688 1689 if (!(addr.immediate && 1690 addr.exp.X_add_number == 0)) 1691 return NULL; 1692 1693 insn->bits = (template->meta_opcode | 1694 (reg_no << 19) | 1695 (regs[0]->unit << 10)); 1696 1697 if (!is_short_unit (addr.base_reg->unit)) 1698 { 1699 as_bad (_("base unit must be one of %s"), SHORT_UNITS); 1700 return NULL; 1701 } 1702 1703 insn->bits |= ((addr.base_reg->no << 14) | 1704 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5)); 1705 1706 insn->len = 4; 1707 return l; 1708 } 1709 1710 /* Parse an XFR instruction. */ 1711 static const char * 1712 parse_xfr (const char *line, metag_insn *insn, 1713 const insn_template *template) 1714 { 1715 const char *l = line; 1716 metag_addr dest_addr, src_addr; 1717 unsigned int size = 4; 1718 1719 memset(&dest_addr, 0, sizeof(dest_addr)); 1720 memset(&src_addr, 0, sizeof(src_addr)); 1721 dest_addr.reloc_type = BFD_RELOC_UNUSED; 1722 src_addr.reloc_type = BFD_RELOC_UNUSED; 1723 1724 l = parse_addr (l, &dest_addr, size); 1725 1726 if (l == NULL || 1727 dest_addr.immediate == 1) 1728 { 1729 as_bad (_("invalid destination memory operand")); 1730 return NULL; 1731 } 1732 1733 l = skip_comma (l); 1734 1735 if (l == NULL || 1736 *l == END_OF_INSN) 1737 return NULL; 1738 1739 l = parse_addr (l, &src_addr, size); 1740 1741 if (l == NULL || 1742 src_addr.immediate == 1) 1743 { 1744 as_bad (_("invalid source memory operand")); 1745 return NULL; 1746 } 1747 1748 if (!is_short_unit (dest_addr.base_reg->unit) || 1749 !is_short_unit (src_addr.base_reg->unit)) 1750 { 1751 as_bad (_("address units must be one of %s"), SHORT_UNITS); 1752 return NULL; 1753 } 1754 1755 if ((dest_addr.base_reg->unit != dest_addr.offset_reg->unit) || 1756 (src_addr.base_reg->unit != src_addr.offset_reg->unit)) 1757 { 1758 as_bad (_("base and offset must be from the same unit")); 1759 return NULL; 1760 } 1761 1762 if (dest_addr.update == 1 && 1763 src_addr.update == 1 && 1764 dest_addr.post_increment != src_addr.post_increment) 1765 { 1766 as_bad (_("source and destination increment mode must agree")); 1767 return NULL; 1768 } 1769 1770 insn->bits = (template->meta_opcode | 1771 (src_addr.base_reg->no << 19) | 1772 (src_addr.offset_reg->no << 14) | 1773 ((src_addr.base_reg->unit & SHORT_UNIT_MASK) << 2)); 1774 1775 insn->bits |= ((dest_addr.base_reg->no << 9) | 1776 (dest_addr.offset_reg->no << 4) | 1777 ((dest_addr.base_reg->unit & SHORT_UNIT_MASK))); 1778 1779 if (dest_addr.update == 1) 1780 insn->bits |= (1 << 26); 1781 1782 if (src_addr.update == 1) 1783 insn->bits |= (1 << 27); 1784 1785 if (dest_addr.post_increment == 1 || 1786 src_addr.post_increment == 1) 1787 insn->bits |= (1 << 24); 1788 1789 insn->len = 4; 1790 return l; 1791 } 1792 1793 /* Parse an 8bit immediate value. */ 1794 static const char * 1795 parse_imm8 (const char *line, metag_insn *insn, int *value) 1796 { 1797 const char *l = line; 1798 char *save_input_line_pointer; 1799 expressionS *exp = &insn->reloc_exp; 1800 1801 /* Skip #. */ 1802 if (*l == '#') 1803 l++; 1804 else 1805 return NULL; 1806 1807 save_input_line_pointer = input_line_pointer; 1808 input_line_pointer = (char *) l; 1809 1810 expression (exp); 1811 1812 l = input_line_pointer; 1813 input_line_pointer = save_input_line_pointer; 1814 1815 if (exp->X_op == O_absent || exp->X_op == O_big) 1816 { 1817 return NULL; 1818 } 1819 else if (exp->X_op == O_constant) 1820 { 1821 *value = exp->X_add_number; 1822 } 1823 else 1824 { 1825 insn->reloc_type = BFD_RELOC_METAG_REL8; 1826 insn->reloc_pcrel = 0; 1827 } 1828 1829 return l; 1830 } 1831 1832 /* Parse a 16bit immediate value. */ 1833 static const char * 1834 parse_imm16 (const char *line, metag_insn *insn, int *value) 1835 { 1836 const char *l = line; 1837 char *save_input_line_pointer; 1838 expressionS *exp = &insn->reloc_exp; 1839 bfd_boolean is_hi = FALSE; 1840 bfd_boolean is_lo = FALSE; 1841 1842 /* Skip #. */ 1843 if (*l == '#') 1844 l++; 1845 else 1846 return NULL; 1847 1848 if (strncasecmp (l, "HI", 2) == 0) 1849 { 1850 is_hi = TRUE; 1851 l += 2; 1852 } 1853 else if (strncasecmp (l, "LO", 2) == 0) 1854 { 1855 is_lo = TRUE; 1856 l += 2; 1857 } 1858 1859 save_input_line_pointer = input_line_pointer; 1860 input_line_pointer = (char *) l; 1861 1862 expression (exp); 1863 1864 l = input_line_pointer; 1865 input_line_pointer = save_input_line_pointer; 1866 1867 if (exp->X_op == O_absent || exp->X_op == O_big) 1868 { 1869 return NULL; 1870 } 1871 else if (exp->X_op == O_constant) 1872 { 1873 if (is_hi) 1874 *value = (exp->X_add_number >> 16) & IMM16_MASK; 1875 else if (is_lo) 1876 *value = exp->X_add_number & IMM16_MASK; 1877 else 1878 *value = exp->X_add_number; 1879 } 1880 else 1881 { 1882 if (exp->X_op == O_PIC_reloc) 1883 { 1884 exp->X_op = O_symbol; 1885 1886 if (exp->X_md == BFD_RELOC_METAG_GOTOFF) 1887 { 1888 if (is_hi) 1889 insn->reloc_type = BFD_RELOC_METAG_HI16_GOTOFF; 1890 else if (is_lo) 1891 insn->reloc_type = BFD_RELOC_METAG_LO16_GOTOFF; 1892 else 1893 return NULL; 1894 } 1895 else if (exp->X_md == BFD_RELOC_METAG_PLT) 1896 { 1897 if (is_hi) 1898 insn->reloc_type = BFD_RELOC_METAG_HI16_PLT; 1899 else if (is_lo) 1900 insn->reloc_type = BFD_RELOC_METAG_LO16_PLT; 1901 else 1902 return NULL; 1903 } 1904 else if (exp->X_md == BFD_RELOC_METAG_TLS_LDO) 1905 { 1906 if (is_hi) 1907 insn->reloc_type = BFD_RELOC_METAG_TLS_LDO_HI16; 1908 else if (is_lo) 1909 insn->reloc_type = BFD_RELOC_METAG_TLS_LDO_LO16; 1910 else 1911 return NULL; 1912 } 1913 else if (exp->X_md == BFD_RELOC_METAG_TLS_IENONPIC) 1914 { 1915 if (is_hi) 1916 insn->reloc_type = BFD_RELOC_METAG_TLS_IENONPIC_HI16; 1917 else if (is_lo) 1918 insn->reloc_type = BFD_RELOC_METAG_TLS_IENONPIC_LO16; 1919 else 1920 return NULL; 1921 } 1922 else if (exp->X_md == BFD_RELOC_METAG_TLS_LE) 1923 { 1924 if (is_hi) 1925 insn->reloc_type = BFD_RELOC_METAG_TLS_LE_HI16; 1926 else if (is_lo) 1927 insn->reloc_type = BFD_RELOC_METAG_TLS_LE_LO16; 1928 else 1929 return NULL; 1930 } 1931 else if (exp->X_md == BFD_RELOC_METAG_TLS_GD || 1932 exp->X_md == BFD_RELOC_METAG_TLS_LDM) 1933 insn->reloc_type = exp->X_md; 1934 } 1935 else 1936 { 1937 if (exp->X_op == O_symbol && exp->X_add_symbol == GOT_symbol) 1938 { 1939 if (is_hi) 1940 insn->reloc_type = BFD_RELOC_METAG_HI16_GOTPC; 1941 else if (is_lo) 1942 insn->reloc_type = BFD_RELOC_METAG_LO16_GOTPC; 1943 else 1944 return NULL; 1945 } 1946 else 1947 { 1948 if (is_hi) 1949 insn->reloc_type = BFD_RELOC_METAG_HIADDR16; 1950 else if (is_lo) 1951 insn->reloc_type = BFD_RELOC_METAG_LOADDR16; 1952 else 1953 insn->reloc_type = BFD_RELOC_METAG_REL16; 1954 } 1955 } 1956 1957 insn->reloc_pcrel = 0; 1958 } 1959 1960 return l; 1961 } 1962 1963 /* Parse a MOV to control unit instruction. */ 1964 static const char * 1965 parse_mov_ct (const char *line, metag_insn *insn, 1966 const insn_template *template) 1967 { 1968 const char *l = line; 1969 const metag_reg *regs[1]; 1970 unsigned int top = template->meta_opcode & 0x1; 1971 unsigned int is_trace = (template->meta_opcode >> 2) & 0x1; 1972 unsigned int sign_extend = 0; 1973 int value = 0; 1974 1975 l = parse_gp_regs (l, regs, 1); 1976 1977 if (l == NULL) 1978 return NULL; 1979 1980 if (is_trace) 1981 { 1982 if (regs[0]->unit != UNIT_TT) 1983 return NULL; 1984 } 1985 else 1986 { 1987 if (regs[0]->unit != UNIT_CT) 1988 return NULL; 1989 } 1990 1991 l = skip_comma (l); 1992 1993 if (l == NULL || 1994 *l == END_OF_INSN) 1995 return NULL; 1996 1997 l = parse_imm16 (l, insn, &value); 1998 1999 if (l == NULL) 2000 return NULL; 2001 2002 if (value < 0) 2003 sign_extend = 1; 2004 2005 insn->bits = (template->meta_opcode | 2006 (regs[0]->no << 19) | 2007 ((value & IMM16_MASK) << 3)); 2008 2009 if (sign_extend == 1 && top == 0) 2010 insn->bits |= (1 << 1); 2011 2012 insn->len = 4; 2013 return l; 2014 } 2015 2016 /* Parse a SWAP instruction. */ 2017 static const char * 2018 parse_swap (const char *line, metag_insn *insn, 2019 const insn_template *template) 2020 { 2021 const char *l = line; 2022 const metag_reg *regs[2]; 2023 2024 l = parse_gp_regs (l, regs, 2); 2025 2026 if (l == NULL) 2027 return NULL; 2028 2029 /* PC.r | CT.r | TR.r | TT.r are treated as if they are a single unit. */ 2030 switch (regs[0]->unit) 2031 { 2032 case UNIT_PC: 2033 case UNIT_CT: 2034 case UNIT_TR: 2035 case UNIT_TT: 2036 if (regs[1]->unit == UNIT_PC 2037 || regs[1]->unit == UNIT_CT 2038 || regs[1]->unit == UNIT_TR 2039 || regs[1]->unit == UNIT_TT) 2040 { 2041 as_bad (_("PC, CT, TR and TT are treated as if they are a single unit but operands must be in different units")); 2042 return NULL; 2043 } 2044 2045 default: 2046 /* Registers must be in different units. */ 2047 if (regs[0]->unit == regs[1]->unit) 2048 { 2049 as_bad (_("source and destination register must be in different units")); 2050 return NULL; 2051 } 2052 break; 2053 } 2054 2055 insn->bits = (template->meta_opcode 2056 | (regs[1]->no << 19) 2057 | (regs[0]->no << 14) 2058 | (regs[1]->unit << 10) 2059 | (regs[0]->unit << 5)); 2060 2061 insn->len = 4; 2062 return l; 2063 } 2064 2065 /* Parse a JUMP instruction. */ 2066 static const char * 2067 parse_jump (const char *line, metag_insn *insn, 2068 const insn_template *template) 2069 { 2070 const char *l = line; 2071 const metag_reg *regs[1]; 2072 int value = 0; 2073 2074 l = parse_gp_regs (l, regs, 1); 2075 2076 if (l == NULL) 2077 return NULL; 2078 2079 if (!is_short_unit (regs[0]->unit)) 2080 { 2081 as_bad (_("register unit must be one of %s"), SHORT_UNITS); 2082 return FALSE; 2083 } 2084 2085 l = skip_comma (l); 2086 2087 if (l == NULL || 2088 *l == END_OF_INSN) 2089 return NULL; 2090 2091 l = parse_imm16 (l, insn, &value); 2092 2093 if (l == NULL) 2094 return NULL; 2095 2096 insn->bits = (template->meta_opcode | 2097 (regs[0]->no << 19) | 2098 (regs[0]->unit & SHORT_UNIT_MASK) | 2099 ((value & IMM16_MASK) << 3)); 2100 2101 insn->len = 4; 2102 return l; 2103 } 2104 2105 /* Parse a 19bit immediate value. */ 2106 static const char * 2107 parse_imm19 (const char *line, metag_insn *insn, int *value) 2108 { 2109 const char *l = line; 2110 char *save_input_line_pointer; 2111 expressionS *exp = &insn->reloc_exp; 2112 2113 /* Skip #. */ 2114 if (*l == '#') 2115 l++; 2116 2117 save_input_line_pointer = input_line_pointer; 2118 input_line_pointer = (char *) l; 2119 2120 expression (exp); 2121 2122 l = input_line_pointer; 2123 input_line_pointer = save_input_line_pointer; 2124 2125 if (exp->X_op == O_absent || exp->X_op == O_big) 2126 { 2127 return NULL; 2128 } 2129 else if (exp->X_op == O_constant) 2130 { 2131 *value = exp->X_add_number; 2132 } 2133 else 2134 { 2135 if (exp->X_op == O_PIC_reloc) 2136 { 2137 exp->X_op = O_symbol; 2138 2139 if (exp->X_md == BFD_RELOC_METAG_PLT) 2140 insn->reloc_type = BFD_RELOC_METAG_RELBRANCH_PLT; 2141 else 2142 return NULL; 2143 } 2144 else 2145 insn->reloc_type = BFD_RELOC_METAG_RELBRANCH; 2146 insn->reloc_pcrel = 1; 2147 } 2148 2149 return l; 2150 } 2151 2152 /* Parse a CALLR instruction. */ 2153 static const char * 2154 parse_callr (const char *line, metag_insn *insn, 2155 const insn_template *template) 2156 { 2157 const char *l = line; 2158 const metag_reg *regs[1]; 2159 int value = 0; 2160 2161 l = parse_gp_regs (l, regs, 1); 2162 2163 if (l == NULL) 2164 return NULL; 2165 2166 if (!is_short_unit (regs[0]->unit)) 2167 { 2168 as_bad (_("link register unit must be one of %s"), SHORT_UNITS); 2169 return NULL; 2170 } 2171 2172 if (regs[0]->no & ~CALLR_REG_MASK) 2173 { 2174 as_bad (_("link register must be in a low numbered register")); 2175 return NULL; 2176 } 2177 2178 l = skip_comma (l); 2179 2180 if (l == NULL || 2181 *l == END_OF_INSN) 2182 return NULL; 2183 2184 l = parse_imm19 (l, insn, &value); 2185 2186 if (l == NULL) 2187 return NULL; 2188 2189 if (!within_signed_range (value / 4, IMM19_BITS)) 2190 { 2191 as_bad (_("target out of range")); 2192 return NULL; 2193 } 2194 2195 insn->bits = (template->meta_opcode | 2196 (regs[0]->no & CALLR_REG_MASK) | 2197 ((regs[0]->unit & SHORT_UNIT_MASK) << 3) | 2198 ((value & IMM19_MASK) << 5)); 2199 2200 insn->len = 4; 2201 return l; 2202 } 2203 2204 /* Return the value for the register field if we apply the O2R modifier 2205 to operand 2 REG, combined with UNIT_BIT derived from the destination 2206 register or source1. Uses address unit O2R if IS_ADDR is set. */ 2207 static int 2208 lookup_o2r (unsigned int is_addr, unsigned int unit_bit, const metag_reg *reg) 2209 { 2210 if (reg->no & ~O2R_REG_MASK) 2211 return -1; 2212 2213 if (is_addr) 2214 { 2215 if (unit_bit) 2216 { 2217 switch (reg->unit) 2218 { 2219 case UNIT_D1: 2220 return reg->no; 2221 case UNIT_D0: 2222 return (1 << 3) | reg->no; 2223 case UNIT_RD: 2224 return (2 << 3) | reg->no; 2225 case UNIT_A0: 2226 return (3 << 3) | reg->no; 2227 default: 2228 return -1; 2229 } 2230 } 2231 else 2232 { 2233 switch (reg->unit) 2234 { 2235 case UNIT_A1: 2236 return reg->no; 2237 case UNIT_D0: 2238 return (1 << 3) | reg->no; 2239 case UNIT_RD: 2240 return (2 << 3) | reg->no; 2241 case UNIT_D1: 2242 return (3 << 3) | reg->no; 2243 default: 2244 return -1; 2245 } 2246 } 2247 } 2248 else 2249 { 2250 if (unit_bit) 2251 { 2252 switch (reg->unit) 2253 { 2254 case UNIT_A1: 2255 return reg->no; 2256 case UNIT_D0: 2257 return (1 << 3) | reg->no; 2258 case UNIT_RD: 2259 return (2 << 3) | reg->no; 2260 case UNIT_A0: 2261 return (3 << 3) | reg->no; 2262 default: 2263 return -1; 2264 } 2265 } 2266 else 2267 { 2268 switch (reg->unit) 2269 { 2270 case UNIT_A1: 2271 return reg->no; 2272 case UNIT_D1: 2273 return (1 << 3) | reg->no; 2274 case UNIT_RD: 2275 return (2 << 3) | reg->no; 2276 case UNIT_A0: 2277 return (3 << 3) | reg->no; 2278 default: 2279 return -1; 2280 } 2281 } 2282 } 2283 } 2284 2285 /* Parse GP ALU instruction. */ 2286 static const char * 2287 parse_alu (const char *line, metag_insn *insn, 2288 const insn_template *template) 2289 { 2290 const char *l = line; 2291 const metag_reg *dest_regs[1]; 2292 const metag_reg *src_regs[2]; 2293 int value = 0; 2294 unsigned int o1z = 0; 2295 unsigned int imm = (template->meta_opcode >> 25) & 0x1; 2296 unsigned int cond = (template->meta_opcode >> 26) & 0x1; 2297 unsigned int ca = (template->meta_opcode >> 5) & 0x1; 2298 unsigned int top = template->meta_opcode & 0x1; 2299 unsigned int sign_extend = 0; 2300 unsigned int is_addr_op = MAJOR_OPCODE (template->meta_opcode) == OPC_ADDR; 2301 unsigned int is_mul = MAJOR_OPCODE (template->meta_opcode) == OPC_MUL; 2302 unsigned int unit_bit = 0; 2303 bfd_boolean is_quickrot = template->arg_type & GP_ARGS_QR; 2304 2305 l = parse_gp_regs (l, dest_regs, 1); 2306 2307 if (l == NULL) 2308 return NULL; 2309 2310 l = skip_comma (l); 2311 2312 if (l == NULL || 2313 *l == END_OF_INSN) 2314 return NULL; 2315 2316 if (is_addr_op) 2317 { 2318 if (dest_regs[0]->unit == UNIT_A0) 2319 unit_bit = 0; 2320 else if (dest_regs[0]->unit == UNIT_A1) 2321 unit_bit = 1; 2322 } 2323 else 2324 { 2325 if (dest_regs[0]->unit == UNIT_D0) 2326 unit_bit = 0; 2327 else if (dest_regs[0]->unit == UNIT_D1) 2328 unit_bit = 1; 2329 } 2330 2331 if ((MAJOR_OPCODE (template->meta_opcode) == OPC_ADDR || 2332 MAJOR_OPCODE (template->meta_opcode) == OPC_ADD || 2333 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB) && 2334 ((template->meta_opcode >> 2) & 0x1)) 2335 o1z = 1; 2336 2337 if (imm) 2338 { 2339 if (!cond) 2340 { 2341 if (is_addr_op) 2342 { 2343 if (dest_regs[0]->unit == UNIT_A0) 2344 unit_bit = 0; 2345 else if (dest_regs[0]->unit == UNIT_A1) 2346 unit_bit = 1; 2347 else 2348 return NULL; 2349 } 2350 else 2351 { 2352 if (dest_regs[0]->unit == UNIT_D0) 2353 unit_bit = 0; 2354 else if (dest_regs[0]->unit == UNIT_D1) 2355 unit_bit = 1; 2356 else 2357 return NULL; 2358 } 2359 } 2360 2361 if (cond) 2362 { 2363 l = parse_gp_regs (l, src_regs, 1); 2364 2365 if (l == NULL) 2366 return NULL; 2367 2368 l = skip_comma (l); 2369 2370 if (l == NULL || 2371 *l == END_OF_INSN) 2372 return NULL; 2373 2374 if (is_addr_op) 2375 { 2376 if (src_regs[0]->unit == UNIT_A0) 2377 unit_bit = 0; 2378 else if (src_regs[0]->unit == UNIT_A1) 2379 unit_bit = 1; 2380 else 2381 return NULL; 2382 } 2383 else 2384 { 2385 if (src_regs[0]->unit == UNIT_D0) 2386 unit_bit = 0; 2387 else if (src_regs[0]->unit == UNIT_D1) 2388 unit_bit = 1; 2389 else 2390 return NULL; 2391 } 2392 2393 if (src_regs[0]->unit != dest_regs[0]->unit && !ca) 2394 return NULL; 2395 2396 l = parse_imm8 (l, insn, &value); 2397 2398 if (l == NULL) 2399 return NULL; 2400 2401 if (!within_unsigned_range (value, IMM8_BITS)) 2402 return NULL; 2403 2404 insn->bits = (template->meta_opcode | 2405 (dest_regs[0]->no << 19) | 2406 (src_regs[0]->no << 14) | 2407 ((value & IMM8_MASK) << 6)); 2408 2409 if (ca) 2410 { 2411 if (is_addr_op) 2412 { 2413 if (src_regs[0]->unit == UNIT_A0) 2414 unit_bit = 0; 2415 else if (src_regs[0]->unit == UNIT_A1) 2416 unit_bit = 1; 2417 else 2418 return NULL; 2419 } 2420 else 2421 { 2422 if (src_regs[0]->unit == UNIT_D0) 2423 unit_bit = 0; 2424 else if (src_regs[0]->unit == UNIT_D1) 2425 unit_bit = 1; 2426 else 2427 return NULL; 2428 } 2429 2430 insn->bits |= dest_regs[0]->unit << 1; 2431 } 2432 } 2433 else if (o1z) 2434 { 2435 l = parse_imm16 (l, insn, &value); 2436 2437 if (l == NULL) 2438 return NULL; 2439 2440 if (value < 0) 2441 { 2442 if (!within_signed_range (value, IMM16_BITS)) 2443 { 2444 as_bad (_("immediate out of range")); 2445 return NULL; 2446 } 2447 sign_extend = 1; 2448 } 2449 else 2450 { 2451 if (!within_unsigned_range (value, IMM16_BITS)) 2452 { 2453 as_bad (_("immediate out of range")); 2454 return NULL; 2455 } 2456 } 2457 2458 insn->bits = (template->meta_opcode | 2459 (dest_regs[0]->no << 19) | 2460 ((value & IMM16_MASK) << 3)); 2461 } 2462 else 2463 { 2464 l = parse_gp_regs (l, src_regs, 1); 2465 2466 if (l == NULL) 2467 return NULL; 2468 2469 if (!(src_regs[0]->unit == dest_regs[0]->unit)) 2470 return NULL; 2471 2472 /* CPC is valid for address ops. */ 2473 if (src_regs[0]->no != dest_regs[0]->no && 2474 !(is_addr_op && src_regs[0]->no == 0x10)) 2475 return NULL; 2476 2477 l = skip_comma (l); 2478 2479 if (l == NULL || 2480 *l == END_OF_INSN) 2481 return NULL; 2482 2483 l = parse_imm16 (l, insn, &value); 2484 2485 if (l == NULL) 2486 return NULL; 2487 2488 if (value < 0) 2489 { 2490 if (!within_signed_range (value, IMM16_BITS)) 2491 { 2492 as_bad (_("immediate out of range")); 2493 return NULL; 2494 } 2495 sign_extend = 1; 2496 } 2497 else 2498 { 2499 if (!within_unsigned_range (value, IMM16_BITS)) 2500 { 2501 as_bad (_("immediate out of range")); 2502 return NULL; 2503 } 2504 } 2505 2506 insn->bits = (template->meta_opcode | 2507 (dest_regs[0]->no << 19) | 2508 (src_regs[0]->no << 19) | 2509 ((value & IMM16_MASK) << 3)); 2510 } 2511 } 2512 else 2513 { 2514 unsigned int o2r = 0; 2515 int rs2; 2516 2517 if (cond || !o1z) 2518 l = parse_gp_regs (l, src_regs, 2); 2519 else 2520 l = parse_gp_regs (l, src_regs, 1); 2521 2522 if (l == NULL) 2523 return NULL; 2524 2525 if (cond || !o1z) 2526 { 2527 if (is_addr_op) 2528 { 2529 if (src_regs[0]->unit == UNIT_A0) 2530 unit_bit = 0; 2531 else if (src_regs[0]->unit == UNIT_A1) 2532 unit_bit = 1; 2533 else 2534 return NULL; 2535 } 2536 else 2537 { 2538 if (src_regs[0]->unit == UNIT_D0) 2539 unit_bit = 0; 2540 else if (src_regs[0]->unit == UNIT_D1) 2541 unit_bit = 1; 2542 else 2543 return NULL; 2544 } 2545 } 2546 else 2547 { 2548 if (is_addr_op) 2549 { 2550 if (dest_regs[0]->unit == UNIT_A0) 2551 unit_bit = 0; 2552 else if (dest_regs[0]->unit == UNIT_A1) 2553 unit_bit = 1; 2554 else 2555 return NULL; 2556 } 2557 else 2558 { 2559 if (dest_regs[0]->unit == UNIT_D0) 2560 unit_bit = 0; 2561 else if (dest_regs[0]->unit == UNIT_D1) 2562 unit_bit = 1; 2563 else 2564 return NULL; 2565 } 2566 } 2567 2568 if (cond) 2569 { 2570 if (src_regs[0]->unit != src_regs[1]->unit) 2571 { 2572 rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[1]); 2573 2574 if (rs2 < 0) 2575 return NULL; 2576 2577 o2r = 1; 2578 } 2579 else 2580 { 2581 rs2 = src_regs[1]->no; 2582 } 2583 2584 insn->bits = (template->meta_opcode | 2585 (dest_regs[0]->no << 19) | 2586 (src_regs[0]->no << 14) | 2587 (rs2 << 9)); 2588 2589 if (is_mul) 2590 { 2591 if (dest_regs[0]->unit != src_regs[0]->unit && is_mul) 2592 { 2593 if (ca) 2594 { 2595 insn->bits |= dest_regs[0]->unit << 1; 2596 } 2597 else 2598 return NULL; 2599 } 2600 } 2601 else 2602 insn->bits |= dest_regs[0]->unit << 5; 2603 } 2604 else if (o1z) 2605 { 2606 if (dest_regs[0]->unit != src_regs[0]->unit) 2607 { 2608 rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[0]); 2609 2610 if (rs2 < 0) 2611 return NULL; 2612 2613 o2r = 1; 2614 } 2615 else 2616 { 2617 rs2 = src_regs[0]->no; 2618 } 2619 2620 insn->bits = (template->meta_opcode | 2621 (dest_regs[0]->no << 19) | 2622 (rs2 << 9)); 2623 } 2624 else 2625 { 2626 if (dest_regs[0]->unit != src_regs[0]->unit) 2627 return NULL; 2628 2629 if (dest_regs[0]->unit != src_regs[1]->unit) 2630 { 2631 rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[1]); 2632 2633 if (rs2 < 0) 2634 return NULL; 2635 2636 o2r = 1; 2637 } 2638 else 2639 { 2640 rs2 = src_regs[1]->no; 2641 } 2642 2643 insn->bits = (template->meta_opcode | 2644 (dest_regs[0]->no << 19) | 2645 (src_regs[0]->no << 14) | 2646 (rs2 << 9)); 2647 } 2648 2649 if (o2r) 2650 insn->bits |= 1; 2651 } 2652 2653 if (is_quickrot) 2654 { 2655 const metag_reg *qr_regs[1]; 2656 bfd_boolean limit_regs = imm && cond; 2657 2658 l = skip_comma (l); 2659 2660 if (l == NULL || 2661 *l == END_OF_INSN) 2662 return NULL; 2663 2664 l = parse_gp_regs (l, qr_regs, 1); 2665 2666 if (l == NULL) 2667 return NULL; 2668 2669 if (!((unit_bit == 0 && qr_regs[0]->unit != UNIT_A0) || 2670 !(unit_bit == 1 && qr_regs[0]->unit != UNIT_A1))) 2671 { 2672 as_bad (_("invalid quickrot unit specified")); 2673 return NULL; 2674 } 2675 2676 switch (qr_regs[0]->no) 2677 { 2678 case 2: 2679 break; 2680 case 3: 2681 if (!limit_regs) 2682 { 2683 insn->bits |= (1 << 7); 2684 break; 2685 } 2686 default: 2687 as_bad (_("invalid quickrot register specified")); 2688 return NULL; 2689 } 2690 } 2691 2692 if (sign_extend == 1 && top == 0) 2693 insn->bits |= (1 << 1); 2694 2695 insn->bits |= unit_bit << 24; 2696 insn->len = 4; 2697 return l; 2698 } 2699 2700 /* Parse a B instruction. */ 2701 static const char * 2702 parse_branch (const char *line, metag_insn *insn, 2703 const insn_template *template) 2704 { 2705 const char *l = line; 2706 int value = 0; 2707 2708 l = parse_imm19 (l, insn, &value); 2709 2710 if (l == NULL) 2711 return NULL; 2712 2713 if (!within_signed_range (value / 4, IMM19_BITS)) 2714 { 2715 as_bad (_("target out of range")); 2716 return NULL; 2717 } 2718 2719 insn->bits = (template->meta_opcode | 2720 ((value & IMM19_MASK) << 5)); 2721 2722 insn->len = 4; 2723 return l; 2724 } 2725 2726 /* Parse a KICK instruction. */ 2727 static const char * 2728 parse_kick (const char *line, metag_insn *insn, 2729 const insn_template *template) 2730 { 2731 const char *l = line; 2732 const metag_reg *regs[2]; 2733 2734 l = parse_gp_regs (l, regs, 2); 2735 2736 if (l == NULL) 2737 return NULL; 2738 2739 if (regs[1]->unit != UNIT_TR) 2740 { 2741 as_bad (_("source register must be in the trigger unit")); 2742 return NULL; 2743 } 2744 2745 insn->bits = (template->meta_opcode | 2746 (regs[1]->no << 19) | 2747 (regs[0]->no << 14) | 2748 (regs[0]->unit << 5)); 2749 2750 insn->len = 4; 2751 return l; 2752 } 2753 2754 /* Parse a SWITCH instruction. */ 2755 static const char * 2756 parse_switch (const char *line, metag_insn *insn, 2757 const insn_template *template) 2758 { 2759 const char *l = line; 2760 int value = 0; 2761 2762 l = parse_imm_constant (l, insn, &value); 2763 2764 if (l == NULL) 2765 return NULL; 2766 2767 if (!within_unsigned_range (value, IMM24_BITS)) 2768 { 2769 as_bad (_("target out of range")); 2770 return NULL; 2771 } 2772 2773 insn->bits = (template->meta_opcode | 2774 (value & IMM24_MASK)); 2775 2776 insn->len = 4; 2777 return l; 2778 } 2779 2780 /* Parse a shift instruction. */ 2781 static const char * 2782 parse_shift (const char *line, metag_insn *insn, 2783 const insn_template *template) 2784 { 2785 const char *l = line; 2786 const metag_reg *regs[2]; 2787 const metag_reg *src2_regs[1]; 2788 int value = 0; 2789 unsigned int cond = (template->meta_opcode >> 26) & 0x1; 2790 unsigned int ca = (template->meta_opcode >> 5) & 0x1; 2791 unsigned int unit_bit = 0; 2792 2793 l = parse_gp_regs (l, regs, 2); 2794 2795 if (l == NULL) 2796 return NULL; 2797 2798 l = skip_comma (l); 2799 2800 if (l == NULL || 2801 *l == END_OF_INSN) 2802 return NULL; 2803 2804 if (regs[1]->unit == UNIT_D0) 2805 unit_bit = 0; 2806 else if (regs[1]->unit == UNIT_D1) 2807 unit_bit = 1; 2808 else 2809 return NULL; 2810 2811 if (regs[0]->unit != regs[1]->unit && !(cond && ca)) 2812 return NULL; 2813 2814 if (*l == '#') 2815 { 2816 l = parse_imm_constant (l, insn, &value); 2817 2818 if (l == NULL) 2819 return NULL; 2820 2821 if (!within_unsigned_range (value, IMM5_BITS)) 2822 return NULL; 2823 2824 insn->bits = (template->meta_opcode | 2825 (1 << 25) | 2826 (regs[0]->no << 19) | 2827 (regs[1]->no << 14) | 2828 ((value & IMM5_MASK) << 9)); 2829 } 2830 else 2831 { 2832 l = parse_gp_regs (l, src2_regs, 1); 2833 2834 if (l == NULL) 2835 return NULL; 2836 2837 insn->bits = (template->meta_opcode | 2838 (regs[0]->no << 19) | 2839 (regs[1]->no << 14) | 2840 (src2_regs[0]->no << 9)); 2841 2842 if (src2_regs[0]->unit != regs[1]->unit) 2843 { 2844 as_bad(_("Source registers must be in the same unit")); 2845 return NULL; 2846 } 2847 } 2848 2849 if (regs[0]->unit != regs[1]->unit) 2850 { 2851 if (cond && ca) 2852 { 2853 if (regs[1]->unit == UNIT_D0) 2854 unit_bit = 0; 2855 else if (regs[1]->unit == UNIT_D1) 2856 unit_bit = 1; 2857 else 2858 return NULL; 2859 2860 insn->bits |= ((1 << 5) | 2861 (regs[0]->unit << 1)); 2862 } 2863 else 2864 return NULL; 2865 } 2866 2867 insn->bits |= unit_bit << 24; 2868 insn->len = 4; 2869 return l; 2870 } 2871 2872 /* Parse a MIN or MAX instruction. */ 2873 static const char * 2874 parse_min_max (const char *line, metag_insn *insn, 2875 const insn_template *template) 2876 { 2877 const char *l = line; 2878 const metag_reg *regs[3]; 2879 2880 l = parse_gp_regs (l, regs, 3); 2881 2882 if (l == NULL) 2883 return NULL; 2884 2885 if (!(regs[0]->unit == UNIT_D0 || 2886 regs[0]->unit == UNIT_D1)) 2887 return NULL; 2888 2889 if (!(regs[0]->unit == regs[1]->unit && 2890 regs[1]->unit == regs[2]->unit)) 2891 return NULL; 2892 2893 insn->bits = (template->meta_opcode | 2894 (regs[0]->no << 19) | 2895 (regs[1]->no << 14) | 2896 (regs[2]->no << 9)); 2897 2898 if (regs[0]->unit == UNIT_D1) 2899 insn->bits |= (1 << 24); 2900 2901 insn->len = 4; 2902 return l; 2903 } 2904 2905 /* Parse a bit operation instruction. */ 2906 static const char * 2907 parse_bitop (const char *line, metag_insn *insn, 2908 const insn_template *template) 2909 { 2910 const char *l = line; 2911 const metag_reg *regs[2]; 2912 unsigned int swap_inst = MAJOR_OPCODE (template->meta_opcode) == OPC_MISC; 2913 unsigned int is_bexl = 0; 2914 2915 if (swap_inst && 2916 ((template->meta_opcode >> 1) & 0xb) == 0xa) 2917 is_bexl = 1; 2918 2919 l = parse_gp_regs (l, regs, 2); 2920 2921 if (l == NULL) 2922 return NULL; 2923 2924 if (!(regs[0]->unit == UNIT_D0 || 2925 regs[0]->unit == UNIT_D1)) 2926 return NULL; 2927 2928 if (is_bexl) 2929 { 2930 if (regs[0]->unit == UNIT_D0 && 2931 regs[1]->unit != UNIT_D1) 2932 return NULL; 2933 else if (regs[0]->unit == UNIT_D1 && 2934 regs[1]->unit != UNIT_D0) 2935 return NULL; 2936 } 2937 else if (!(regs[0]->unit == regs[1]->unit)) 2938 return NULL; 2939 2940 insn->bits = (template->meta_opcode | 2941 (regs[0]->no << 19) | 2942 (regs[1]->no << 14)); 2943 2944 if (swap_inst) 2945 { 2946 if (regs[1]->unit == UNIT_D1) 2947 insn->bits |= 1; 2948 } 2949 else 2950 { 2951 if (regs[1]->unit == UNIT_D1) 2952 insn->bits |= (1 << 24); 2953 } 2954 2955 insn->len = 4; 2956 return l; 2957 } 2958 2959 /* Parse a CMP or TST instruction. */ 2960 static const char * 2961 parse_cmp (const char *line, metag_insn *insn, 2962 const insn_template *template) 2963 { 2964 const char *l = line; 2965 const metag_reg *dest_regs[1]; 2966 const metag_reg *src_regs[1]; 2967 int value = 0; 2968 unsigned int imm = (template->meta_opcode >> 25) & 0x1; 2969 unsigned int cond = (template->meta_opcode >> 26) & 0x1; 2970 unsigned int top = template->meta_opcode & 0x1; 2971 unsigned int sign_extend = 0; 2972 unsigned int unit_bit = 0; 2973 2974 l = parse_gp_regs (l, dest_regs, 1); 2975 2976 if (l == NULL) 2977 return NULL; 2978 2979 l = skip_comma (l); 2980 2981 if (l == NULL || 2982 *l == END_OF_INSN) 2983 return NULL; 2984 2985 if (dest_regs[0]->unit == UNIT_D0) 2986 unit_bit = 0; 2987 else if (dest_regs[0]->unit == UNIT_D1) 2988 unit_bit = 1; 2989 else 2990 return NULL; 2991 2992 if (imm) 2993 { 2994 if (cond) 2995 { 2996 l = parse_imm_constant (l, insn, &value); 2997 2998 if (l == NULL) 2999 return NULL; 3000 3001 if (!within_unsigned_range (value, IMM8_BITS)) 3002 return NULL; 3003 3004 insn->bits = (template->meta_opcode | 3005 (dest_regs[0]->no << 14) | 3006 ((value & IMM8_MASK) << 6)); 3007 3008 } 3009 else 3010 { 3011 l = parse_imm16 (l, insn, &value); 3012 3013 if (l == NULL) 3014 return NULL; 3015 3016 if (value < 0) 3017 { 3018 if (!within_signed_range (value, IMM16_BITS)) 3019 { 3020 as_bad (_("immediate out of range")); 3021 return NULL; 3022 } 3023 sign_extend = 1; 3024 } 3025 else 3026 { 3027 if (!within_unsigned_range (value, IMM16_BITS)) 3028 { 3029 as_bad (_("immediate out of range")); 3030 return NULL; 3031 } 3032 } 3033 3034 insn->bits = (template->meta_opcode | 3035 (dest_regs[0]->no << 19) | 3036 ((value & IMM16_MASK) << 3)); 3037 } 3038 } 3039 else 3040 { 3041 unsigned int o2r = 0; 3042 int rs2; 3043 3044 l = parse_gp_regs (l, src_regs, 1); 3045 3046 if (l == NULL) 3047 return NULL; 3048 3049 if (dest_regs[0]->unit != src_regs[0]->unit) 3050 { 3051 rs2 = lookup_o2r (0, unit_bit, src_regs[0]); 3052 3053 if (rs2 < 0) 3054 return NULL; 3055 3056 o2r = 1; 3057 } 3058 else 3059 { 3060 rs2 = src_regs[0]->no; 3061 } 3062 3063 insn->bits = (template->meta_opcode | 3064 (dest_regs[0]->no << 14) | 3065 (rs2 << 9)); 3066 3067 if (o2r) 3068 insn->bits |= 1; 3069 } 3070 3071 if (sign_extend == 1 && top == 0) 3072 insn->bits |= (1 << 1); 3073 3074 insn->bits |= unit_bit << 24; 3075 insn->len = 4; 3076 return l; 3077 } 3078 3079 /* Parse a CACHEW instruction. */ 3080 static const char * 3081 parse_cachew (const char *line, metag_insn *insn, 3082 const insn_template *template) 3083 { 3084 const char *l = line; 3085 const metag_reg *src_regs[2]; 3086 unsigned int size = ((template->meta_opcode >> 1) & 0x1) ? 8 : 4; 3087 metag_addr addr; 3088 int offset; 3089 3090 memset(&addr, 0, sizeof(addr)); 3091 addr.reloc_type = BFD_RELOC_UNUSED; 3092 3093 l = parse_addr (l, &addr, size); 3094 3095 if (l == NULL || 3096 !is_short_unit (addr.base_reg->unit) || 3097 addr.update || 3098 !addr.immediate) 3099 { 3100 as_bad (_("invalid memory operand")); 3101 return NULL; 3102 } 3103 3104 l = skip_comma (l); 3105 3106 if (l == NULL || 3107 *l == END_OF_INSN) 3108 return NULL; 3109 3110 if (size == 4) 3111 l = parse_gp_regs (l, src_regs, 1); 3112 else 3113 l = parse_pair_gp_regs (l, src_regs); 3114 3115 if (l == NULL || 3116 !is_short_unit (src_regs[0]->unit)) 3117 { 3118 as_bad (_("invalid source register")); 3119 return NULL; 3120 } 3121 3122 offset = addr.exp.X_add_number; 3123 3124 if (addr.negate) 3125 offset = -offset; 3126 3127 offset = offset / 64; 3128 3129 if (!within_signed_range (offset, GET_SET_IMM_BITS)) 3130 { 3131 as_bad (_("offset value out of range")); 3132 return NULL; 3133 } 3134 3135 insn->bits = (template->meta_opcode | 3136 (src_regs[0]->no << 19) | 3137 (addr.base_reg->no << 14) | 3138 ((offset & GET_SET_IMM_MASK) << 8) | 3139 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) | 3140 ((src_regs[0]->unit & SHORT_UNIT_MASK) << 3)); 3141 3142 insn->len = 4; 3143 return l; 3144 } 3145 3146 /* Parse a CACHEW instruction. */ 3147 static const char * 3148 parse_cacher (const char *line, metag_insn *insn, 3149 const insn_template *template) 3150 { 3151 const char *l = line; 3152 const metag_reg *dest_regs[2]; 3153 unsigned int size = ((template->meta_opcode >> 1) & 0x1) ? 8 : 4; 3154 metag_addr addr; 3155 int offset; 3156 3157 memset(&addr, 0, sizeof(addr)); 3158 addr.reloc_type = BFD_RELOC_UNUSED; 3159 3160 if (size == 4) 3161 l = parse_gp_regs (l, dest_regs, 1); 3162 else 3163 l = parse_pair_gp_regs (l, dest_regs); 3164 3165 if (l == NULL || 3166 !is_short_unit (dest_regs[0]->unit)) 3167 { 3168 as_bad (_("invalid destination register")); 3169 return NULL; 3170 } 3171 3172 l = skip_comma (l); 3173 3174 if (l == NULL || 3175 *l == END_OF_INSN) 3176 return NULL; 3177 3178 l = parse_addr (l, &addr, size); 3179 3180 if (l == NULL || 3181 !is_short_unit (addr.base_reg->unit) || 3182 addr.update || 3183 !addr.immediate) 3184 { 3185 as_bad (_("invalid memory operand")); 3186 return NULL; 3187 } 3188 3189 offset = addr.exp.X_add_number; 3190 3191 if (addr.negate) 3192 offset = -offset; 3193 3194 offset = offset / (int)size; 3195 3196 if (!within_signed_range (offset, GET_SET_IMM_BITS)) 3197 { 3198 as_bad (_("offset value out of range")); 3199 return NULL; 3200 } 3201 3202 insn->bits = (template->meta_opcode | 3203 (dest_regs[0]->no << 19) | 3204 (addr.base_reg->no << 14) | 3205 ((offset & GET_SET_IMM_MASK) << 8) | 3206 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) | 3207 ((dest_regs[0]->unit & SHORT_UNIT_MASK) << 3)); 3208 3209 insn->len = 4; 3210 return l; 3211 } 3212 3213 /* Parse an ICACHE instruction. */ 3214 static const char * 3215 parse_icache (const char *line, metag_insn *insn, 3216 const insn_template *template) 3217 { 3218 const char *l = line; 3219 int offset; 3220 int pfcount; 3221 3222 l = parse_imm_constant (l, insn, &offset); 3223 3224 if (l == NULL) 3225 return NULL; 3226 3227 if (!within_signed_range (offset, IMM15_BITS)) 3228 return NULL; 3229 3230 l = skip_comma (l); 3231 3232 l = parse_imm_constant (l, insn, &pfcount); 3233 3234 if (l == NULL) 3235 return NULL; 3236 3237 if (!within_unsigned_range (pfcount, IMM4_BITS)) 3238 return NULL; 3239 3240 insn->bits = (template->meta_opcode | 3241 ((offset & IMM15_MASK) << 9) | 3242 ((pfcount & IMM4_MASK) << 1)); 3243 3244 insn->len = 4; 3245 return l; 3246 } 3247 3248 /* Parse a LNKGET instruction. */ 3249 static const char * 3250 parse_lnkget (const char *line, metag_insn *insn, 3251 const insn_template *template) 3252 { 3253 const char *l = line; 3254 const metag_reg *dest_regs[2]; 3255 unsigned int size = metag_get_set_ext_size_bytes (template->meta_opcode); 3256 metag_addr addr; 3257 int offset; 3258 3259 memset(&addr, 0, sizeof(addr)); 3260 addr.reloc_type = BFD_RELOC_UNUSED; 3261 3262 if (size == 8) 3263 l = parse_pair_gp_regs (l, dest_regs); 3264 else 3265 l = parse_gp_regs (l, dest_regs, 1); 3266 3267 if (l == NULL || 3268 !is_short_unit (dest_regs[0]->unit)) 3269 { 3270 as_bad (_("invalid destination register")); 3271 return NULL; 3272 } 3273 3274 l = skip_comma (l); 3275 3276 if (l == NULL || 3277 *l == END_OF_INSN) 3278 return NULL; 3279 3280 l = parse_addr (l, &addr, size); 3281 3282 if (l == NULL || 3283 !is_short_unit (addr.base_reg->unit) || 3284 addr.update || 3285 !addr.immediate) 3286 { 3287 as_bad (_("invalid memory operand")); 3288 return NULL; 3289 } 3290 3291 offset = addr.exp.X_add_number; 3292 3293 if (addr.negate) 3294 offset = -offset; 3295 3296 offset = offset / size; 3297 3298 if (!within_signed_range (offset, GET_SET_IMM_BITS)) 3299 { 3300 as_bad (_("offset value out of range")); 3301 return NULL; 3302 } 3303 3304 insn->bits = (template->meta_opcode | 3305 (dest_regs[0]->no << 19) | 3306 (addr.base_reg->no << 14) | 3307 ((offset & GET_SET_IMM_MASK) << 8) | 3308 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) | 3309 ((dest_regs[0]->unit & SHORT_UNIT_MASK) << 3)); 3310 3311 insn->len = 4; 3312 return l; 3313 } 3314 3315 /* Parse an FPU MOV instruction. */ 3316 static const char * 3317 parse_fmov (const char *line, metag_insn *insn, 3318 const insn_template *template) 3319 { 3320 const char *l = line; 3321 const metag_reg *regs[2]; 3322 3323 l = parse_fpu_regs (l, regs, 2); 3324 3325 if (l == NULL) 3326 return NULL; 3327 3328 insn->bits = (template->meta_opcode | 3329 (regs[0]->no << 19) | 3330 (regs[1]->no << 14)); 3331 3332 if (insn->fpu_width == FPU_WIDTH_DOUBLE) 3333 insn->bits |= (1 << 5); 3334 else if (insn->fpu_width == FPU_WIDTH_PAIR) 3335 insn->bits |= (1 << 6); 3336 3337 insn->len = 4; 3338 return l; 3339 } 3340 3341 /* Parse an FPU MMOV instruction. */ 3342 static const char * 3343 parse_fmmov (const char *line, metag_insn *insn, 3344 const insn_template *template) 3345 { 3346 const char *l = line; 3347 bfd_boolean to_fpu = MAJOR_OPCODE (template->meta_opcode) == OPC_GET; 3348 bfd_boolean is_mmovl = MINOR_OPCODE (template->meta_opcode) & 0x1; 3349 size_t regs_read = 0; 3350 const metag_reg *regs[16]; 3351 unsigned int lowest_data_reg = 0xffffffff; 3352 unsigned int lowest_fpu_reg = 0xffffffff; 3353 unsigned int rmask = 0, data_unit; 3354 size_t i; 3355 int last_reg = -1; 3356 3357 if (insn->fpu_width != FPU_WIDTH_SINGLE) 3358 return NULL; 3359 3360 l = parse_gp_regs_list (l, regs, 16, ®s_read); 3361 3362 if (l == NULL) 3363 return NULL; 3364 3365 if (regs_read % 2) 3366 return NULL; 3367 3368 if (to_fpu) 3369 { 3370 for (i = 0; i < regs_read / 2; i++) 3371 { 3372 if (regs[i]->unit != UNIT_FX) 3373 return NULL; 3374 3375 if (last_reg == -1) 3376 { 3377 last_reg = regs[i]->no; 3378 lowest_fpu_reg = last_reg; 3379 } 3380 else 3381 { 3382 if (is_mmovl) 3383 { 3384 if (regs[i]->no != (unsigned int)(last_reg + 2)) 3385 return NULL; 3386 } 3387 else if (regs[i]->no != (unsigned int)(last_reg + 1)) 3388 return NULL; 3389 3390 last_reg = regs[i]->no; 3391 } 3392 } 3393 3394 if (regs[i]->unit == UNIT_D0) 3395 data_unit = 0; 3396 else if (regs[i]->unit == UNIT_D1) 3397 data_unit = 1; 3398 else 3399 return NULL; 3400 3401 if (!check_rmask (®s[i], regs_read / 2, TRUE, FALSE, &lowest_data_reg, 3402 &rmask)) 3403 return NULL; 3404 } 3405 else 3406 { 3407 if (regs[0]->unit == UNIT_D0) 3408 data_unit = 0; 3409 else if (regs[0]->unit == UNIT_D1) 3410 data_unit = 1; 3411 else 3412 return NULL; 3413 3414 if (!check_rmask (regs, regs_read / 2, TRUE, FALSE, &lowest_data_reg, 3415 &rmask)) 3416 return NULL; 3417 3418 for (i = regs_read / 2; i < regs_read; i++) 3419 { 3420 if (regs[i]->unit != UNIT_FX) 3421 return NULL; 3422 3423 if (last_reg == -1) 3424 { 3425 last_reg = regs[i]->no; 3426 lowest_fpu_reg = last_reg; 3427 } 3428 else 3429 { 3430 if (is_mmovl) 3431 { 3432 if (regs[i]->no != (unsigned int)(last_reg + 2)) 3433 return NULL; 3434 } 3435 else if (regs[i]->no != (unsigned int)(last_reg + 1)) 3436 return NULL; 3437 3438 last_reg = regs[i]->no; 3439 } 3440 } 3441 } 3442 3443 insn->bits = (template->meta_opcode | 3444 ((lowest_data_reg & REG_MASK) << 19) | 3445 ((lowest_fpu_reg & REG_MASK) << 14) | 3446 ((rmask & RMASK_MASK) << 7) | 3447 data_unit); 3448 3449 insn->len = 4; 3450 return l; 3451 } 3452 3453 /* Parse an FPU data unit MOV instruction. */ 3454 static const char * 3455 parse_fmov_data (const char *line, metag_insn *insn, 3456 const insn_template *template) 3457 { 3458 const char *l = line; 3459 unsigned int to_fpu = ((template->meta_opcode >> 7) & 0x1); 3460 const metag_reg *regs[2]; 3461 unsigned int base_unit; 3462 3463 if (insn->fpu_width == FPU_WIDTH_PAIR) 3464 return NULL; 3465 3466 l = parse_gp_regs (l, regs, 2); 3467 3468 if (l == NULL) 3469 return NULL; 3470 3471 if (to_fpu) 3472 { 3473 if (regs[0]->unit != UNIT_FX) 3474 return NULL; 3475 3476 if (regs[1]->unit == UNIT_D0) 3477 base_unit = 0; 3478 else if (regs[1]->unit == UNIT_D1) 3479 base_unit = 1; 3480 else 3481 return NULL; 3482 } 3483 else 3484 { 3485 if (regs[0]->unit == UNIT_D0) 3486 base_unit = 0; 3487 else if (regs[0]->unit == UNIT_D1) 3488 base_unit = 1; 3489 else 3490 return NULL; 3491 3492 if (regs[1]->unit != UNIT_FX) 3493 return NULL; 3494 } 3495 3496 insn->bits = (template->meta_opcode | 3497 (base_unit << 24) | 3498 (regs[0]->no << 19) | 3499 (regs[1]->no << 9)); 3500 3501 insn->len = 4; 3502 return l; 3503 } 3504 3505 /* Parse an FPU immediate MOV instruction. */ 3506 static const char * 3507 parse_fmov_i (const char *line, metag_insn *insn, 3508 const insn_template *template) 3509 { 3510 const char *l = line; 3511 const metag_reg *regs[1]; 3512 int value = 0; 3513 3514 l = parse_fpu_regs (l, regs, 1); 3515 3516 l = skip_comma (l); 3517 3518 if (l == NULL || 3519 *l == END_OF_INSN) 3520 return NULL; 3521 3522 l = parse_imm16 (l, insn, &value); 3523 3524 if (l == NULL) 3525 return NULL; 3526 3527 insn->bits = (template->meta_opcode | 3528 (regs[0]->no << 19) | 3529 ((value & IMM16_MASK) << 3)); 3530 3531 if (insn->fpu_width == FPU_WIDTH_DOUBLE) 3532 insn->bits |= (1 << 1); 3533 else if (insn->fpu_width == FPU_WIDTH_PAIR) 3534 insn->bits |= (1 << 2); 3535 3536 insn->len = 4; 3537 return l; 3538 } 3539 3540 /* Parse an FPU PACK instruction. */ 3541 static const char * 3542 parse_fpack (const char *line, metag_insn *insn, 3543 const insn_template *template) 3544 { 3545 const char *l = line; 3546 const metag_reg *regs[3]; 3547 3548 l = parse_fpu_regs (l, regs, 3); 3549 3550 if (l == NULL) 3551 return NULL; 3552 3553 if (regs[0]->no % 2) 3554 { 3555 as_bad (_("destination register should be even numbered")); 3556 return NULL; 3557 } 3558 3559 insn->bits = (template->meta_opcode | 3560 (regs[0]->no << 19) | 3561 (regs[1]->no << 14) | 3562 (regs[2]->no << 9)); 3563 3564 insn->len = 4; 3565 return l; 3566 } 3567 3568 /* Parse an FPU SWAP instruction. */ 3569 static const char * 3570 parse_fswap (const char *line, metag_insn *insn, 3571 const insn_template *template) 3572 { 3573 const char *l = line; 3574 const metag_reg *regs[2]; 3575 3576 if (insn->fpu_width != FPU_WIDTH_PAIR) 3577 return NULL; 3578 3579 l = parse_fpu_regs (l, regs, 2); 3580 3581 if (l == NULL) 3582 return NULL; 3583 3584 if (regs[0]->no % 2) 3585 return NULL; 3586 3587 if (regs[1]->no % 2) 3588 return NULL; 3589 3590 insn->bits = (template->meta_opcode | 3591 (regs[0]->no << 19) | 3592 (regs[1]->no << 14)); 3593 3594 insn->len = 4; 3595 return l; 3596 } 3597 3598 /* Parse an FPU CMP instruction. */ 3599 static const char * 3600 parse_fcmp (const char *line, metag_insn *insn, 3601 const insn_template *template) 3602 { 3603 const char *l = line, *l2; 3604 const metag_reg *regs1[1]; 3605 const metag_reg *regs2[1]; 3606 3607 l = parse_fpu_regs (l, regs1, 1); 3608 3609 l = skip_comma (l); 3610 3611 if (l == NULL || 3612 *l == END_OF_INSN) 3613 return NULL; 3614 3615 l2 = parse_fpu_regs (l, regs2, 1); 3616 3617 if (l2 != NULL) 3618 { 3619 insn->bits = (regs2[0]->no << 9); 3620 } 3621 else 3622 { 3623 int constant = 0; 3624 l2 = parse_imm_constant (l, insn, &constant); 3625 if (!l2 || constant != 0) 3626 { 3627 as_bad (_("comparison must be with register or #0")); 3628 return NULL; 3629 } 3630 insn->bits = (1 << 8); 3631 } 3632 3633 insn->bits |= (template->meta_opcode | 3634 (regs1[0]->no << 14)); 3635 3636 if (insn->fpu_action_flags & FPU_ACTION_ABS) 3637 insn->bits |= (1 << 19); 3638 3639 if (insn->fpu_action_flags & FPU_ACTION_QUIET) 3640 insn->bits |= (1 << 7); 3641 3642 if (insn->fpu_width == FPU_WIDTH_PAIR) 3643 insn->bits |= (1 << 6); 3644 else if (insn->fpu_width == FPU_WIDTH_DOUBLE) 3645 insn->bits |= (1 << 5); 3646 3647 insn->len = 4; 3648 return l2; 3649 } 3650 3651 /* Parse an FPU MIN or MAX instruction. */ 3652 static const char * 3653 parse_fminmax (const char *line, metag_insn *insn, 3654 const insn_template *template) 3655 { 3656 const char *l = line; 3657 const metag_reg *regs[3]; 3658 3659 l = parse_fpu_regs (l, regs, 3); 3660 3661 if (l == NULL) 3662 return NULL; 3663 3664 insn->bits = (template->meta_opcode | 3665 (regs[0]->no << 19) | 3666 (regs[1]->no << 14) | 3667 (regs[2]->no << 9)); 3668 3669 if (insn->fpu_width == FPU_WIDTH_PAIR) 3670 insn->bits |= (1 << 6); 3671 else if (insn->fpu_width == FPU_WIDTH_DOUBLE) 3672 insn->bits |= (1 << 5); 3673 3674 insn->len = 4; 3675 return l; 3676 } 3677 3678 /* Parse an FPU data conversion instruction. */ 3679 static const char * 3680 parse_fconv (const char *line, metag_insn *insn, 3681 const insn_template *template) 3682 { 3683 const char *l = line; 3684 const metag_reg *regs[2]; 3685 3686 if (insn->fpu_width == FPU_WIDTH_PAIR) 3687 { 3688 if (strncasecmp (template->name, "FTOH", 4) && 3689 strncasecmp (template->name, "HTOF", 4) && 3690 strncasecmp (template->name, "FTOI", 4) && 3691 strncasecmp (template->name, "ITOF", 4)) 3692 { 3693 as_bad (_("instruction cannot operate on pair values")); 3694 return NULL; 3695 } 3696 } 3697 3698 if (insn->fpu_action_flags & FPU_ACTION_ZERO) 3699 { 3700 if (strncasecmp (template->name, "FTOI", 4) && 3701 strncasecmp (template->name, "DTOI", 4) && 3702 strncasecmp (template->name, "DTOL", 4)) 3703 { 3704 as_bad (_("zero flag is not valid for this instruction")); 3705 return NULL; 3706 } 3707 } 3708 3709 l = parse_fpu_regs (l, regs, 2); 3710 3711 if (l == NULL) 3712 return NULL; 3713 3714 if (!strncasecmp (template->name, "DTOL", 4) || 3715 !strncasecmp (template->name, "LTOD", 4)) 3716 { 3717 if (regs[0]->no % 2) 3718 { 3719 as_bad (_("destination register should be even numbered")); 3720 return NULL; 3721 } 3722 3723 if (regs[1]->no % 2) 3724 { 3725 as_bad (_("source register should be even numbered")); 3726 return NULL; 3727 } 3728 } 3729 3730 insn->bits = (template->meta_opcode | 3731 (regs[0]->no << 19) | 3732 (regs[1]->no << 14)); 3733 3734 if (insn->fpu_width == FPU_WIDTH_PAIR) 3735 insn->bits |= (1 << 6); 3736 3737 if (insn->fpu_action_flags & FPU_ACTION_ZERO) 3738 insn->bits |= (1 << 12); 3739 3740 insn->len = 4; 3741 return l; 3742 } 3743 3744 /* Parse an FPU extended data conversion instruction. */ 3745 static const char * 3746 parse_fconvx (const char *line, metag_insn *insn, 3747 const insn_template *template) 3748 { 3749 const char *l = line; 3750 const metag_reg *regs[2]; 3751 int fraction_bits = 0; 3752 3753 if (insn->fpu_width == FPU_WIDTH_PAIR) 3754 { 3755 if (strncasecmp (template->name, "FTOX", 4) && 3756 strncasecmp (template->name, "XTOF", 4)) 3757 { 3758 as_bad (_("instruction cannot operate on pair values")); 3759 return NULL; 3760 } 3761 } 3762 3763 l = parse_fpu_regs (l, regs, 2); 3764 3765 l = skip_comma (l); 3766 3767 if (l == NULL || 3768 *l == END_OF_INSN) 3769 return NULL; 3770 3771 l = parse_imm_constant (l, insn, &fraction_bits); 3772 3773 if (l == NULL) 3774 return NULL; 3775 3776 insn->bits = (template->meta_opcode | 3777 (regs[0]->no << 19) | 3778 (regs[1]->no << 14)); 3779 3780 if (strncasecmp (template->name, "DTOXL", 5) && 3781 strncasecmp (template->name, "XLTOD", 5)) 3782 { 3783 if (!within_unsigned_range (fraction_bits, IMM5_BITS)) 3784 { 3785 as_bad (_("fraction bits value out of range")); 3786 return NULL; 3787 } 3788 insn->bits |= ((fraction_bits & IMM5_MASK) << 9); 3789 } 3790 else 3791 { 3792 if (!within_unsigned_range (fraction_bits, IMM6_BITS)) 3793 { 3794 as_bad (_("fraction bits value out of range")); 3795 return NULL; 3796 } 3797 insn->bits |= ((fraction_bits & IMM6_MASK) << 8); 3798 } 3799 3800 if (insn->fpu_width == FPU_WIDTH_PAIR) 3801 insn->bits |= (1 << 6); 3802 3803 insn->len = 4; 3804 return l; 3805 } 3806 3807 /* Parse an FPU basic arithmetic instruction. */ 3808 static const char * 3809 parse_fbarith (const char *line, metag_insn *insn, 3810 const insn_template *template) 3811 { 3812 const char *l = line; 3813 const metag_reg *regs[3]; 3814 3815 l = parse_fpu_regs (l, regs, 3); 3816 3817 if (l == NULL) 3818 return NULL; 3819 3820 insn->bits = (template->meta_opcode | 3821 (regs[0]->no << 19) | 3822 (regs[1]->no << 14) | 3823 (regs[2]->no << 9)); 3824 3825 if (insn->fpu_width == FPU_WIDTH_PAIR) 3826 insn->bits |= (1 << 6); 3827 else if (insn->fpu_width == FPU_WIDTH_DOUBLE) 3828 insn->bits |= (1 << 5); 3829 3830 if (insn->fpu_action_flags & FPU_ACTION_INV) 3831 insn->bits |= (1 << 7); 3832 3833 insn->len = 4; 3834 return l; 3835 } 3836 3837 /* Parse a floating point accumulator name. */ 3838 static const char * 3839 parse_acf (const char *line, int *part) 3840 { 3841 const char *l = line; 3842 size_t i; 3843 3844 for (i = 0; i < sizeof(metag_acftab)/sizeof(metag_acftab[0]); i++) 3845 { 3846 const metag_acf *acf = &metag_acftab[i]; 3847 size_t name_len = strlen (acf->name); 3848 3849 if (strncasecmp (l, acf->name, name_len) == 0) 3850 { 3851 l += name_len; 3852 *part = acf->part; 3853 return l; 3854 } 3855 } 3856 return NULL; 3857 } 3858 3859 /* Parse an FPU extended arithmetic instruction. */ 3860 static const char * 3861 parse_fearith (const char *line, metag_insn *insn, 3862 const insn_template *template) 3863 { 3864 const char *l = line; 3865 const metag_reg *regs[3]; 3866 bfd_boolean is_muz = (MINOR_OPCODE (template->meta_opcode) == 0x6 && 3867 ((template->meta_opcode >> 4) & 0x1)); 3868 unsigned int is_o3o = template->meta_opcode & 0x1; 3869 unsigned int is_mac = 0; 3870 unsigned int is_maw = 0; 3871 3872 if (!strncasecmp (template->name, "MAW", 3)) 3873 is_maw = 1; 3874 3875 if (!strncasecmp (template->name, "MAC", 3)) 3876 { 3877 int part; 3878 l = parse_acf (l, &part); 3879 3880 if (l == NULL || part != 0) 3881 return NULL; 3882 3883 l = skip_comma (l); 3884 3885 l = parse_fpu_regs (l, ®s[1], 2); 3886 3887 is_mac = 1; 3888 } 3889 else 3890 { 3891 if (is_o3o && is_maw) 3892 l = parse_fpu_regs (l, regs, 2); 3893 else 3894 l = parse_fpu_regs (l, regs, 3); 3895 } 3896 3897 if (l == NULL) 3898 return NULL; 3899 3900 if (is_o3o && is_maw) 3901 insn->bits = (template->meta_opcode | 3902 (regs[1]->no << 9)); 3903 else 3904 insn->bits = (template->meta_opcode | 3905 (regs[1]->no << 14)); 3906 3907 if (!(is_o3o && is_maw)) 3908 insn->bits |= (regs[2]->no << 9); 3909 3910 if (is_o3o && is_maw) 3911 insn->bits |= (regs[0]->no << 14); 3912 else if (!is_mac) 3913 insn->bits |= (regs[0]->no << 19); 3914 3915 if (insn->fpu_width == FPU_WIDTH_PAIR) 3916 insn->bits |= (1 << 6); 3917 else if (insn->fpu_width == FPU_WIDTH_DOUBLE) 3918 insn->bits |= (1 << 5); 3919 3920 if (!is_mac && !is_maw) 3921 if (insn->fpu_action_flags & FPU_ACTION_INV) 3922 insn->bits |= (1 << 7); 3923 3924 if (is_muz) 3925 if (insn->fpu_action_flags & FPU_ACTION_QUIET) 3926 insn->bits |= (1 << 1); 3927 3928 insn->len = 4; 3929 return l; 3930 } 3931 3932 /* Parse an FPU RCP or RSQ instruction. */ 3933 static const char * 3934 parse_frec (const char *line, metag_insn *insn, 3935 const insn_template *template) 3936 { 3937 const char *l = line; 3938 const metag_reg *regs[2]; 3939 3940 l = parse_fpu_regs (l, regs, 2); 3941 3942 if (l == NULL) 3943 return NULL; 3944 3945 insn->bits = (template->meta_opcode | 3946 (regs[0]->no << 19) | 3947 (regs[1]->no << 14)); 3948 3949 if (insn->fpu_width == FPU_WIDTH_PAIR) 3950 insn->bits |= (1 << 6); 3951 else if (insn->fpu_width == FPU_WIDTH_DOUBLE) 3952 insn->bits |= (1 << 5); 3953 3954 if (insn->fpu_action_flags & FPU_ACTION_ZERO) 3955 insn->bits |= (1 << 10); 3956 else if (insn->fpu_action_flags & FPU_ACTION_QUIET) 3957 insn->bits |= (1 << 9); 3958 3959 if (insn->fpu_action_flags & FPU_ACTION_INV) 3960 insn->bits |= (1 << 7); 3961 3962 insn->len = 4; 3963 return l; 3964 } 3965 3966 /* Parse an FPU vector arithmetic instruction. */ 3967 static const char * 3968 parse_fsimd (const char *line, metag_insn *insn, 3969 const insn_template *template) 3970 { 3971 const char *l = line; 3972 const metag_reg *regs[3]; 3973 3974 if (insn->fpu_width != FPU_WIDTH_PAIR) 3975 { 3976 as_bad (_("simd instructions operate on pair values (L prefix)")); 3977 return NULL; 3978 } 3979 3980 l = parse_fpu_regs (l, regs, 3); 3981 3982 if (l == NULL) 3983 return NULL; 3984 3985 if (regs[0]->no % 2) 3986 { 3987 as_bad (_("destination register should be even numbered")); 3988 return NULL; 3989 } 3990 3991 if ((regs[1]->no % 2) || 3992 (regs[2]->no % 2)) 3993 { 3994 as_bad (_("source registers should be even numbered")); 3995 return NULL; 3996 } 3997 3998 insn->bits = (template->meta_opcode | 3999 (regs[0]->no << 19) | 4000 (regs[1]->no << 14) | 4001 (regs[2]->no << 9)); 4002 4003 if (insn->fpu_action_flags & FPU_ACTION_INV) 4004 insn->bits |= (1 << 7); 4005 4006 insn->len = 4; 4007 return l; 4008 } 4009 4010 /* Parse an FPU accumulator GET or SET instruction. */ 4011 static const char * 4012 parse_fget_set_acf (const char *line, metag_insn *insn, 4013 const insn_template *template) 4014 { 4015 const char *l = line; 4016 int part; 4017 metag_addr addr; 4018 bfd_boolean is_get = MAJOR_OPCODE (template->meta_opcode) == OPC_GET; 4019 4020 memset(&addr, 0, sizeof(addr)); 4021 addr.reloc_type = BFD_RELOC_UNUSED; 4022 4023 if (is_get) 4024 { 4025 l = parse_acf (l, &part); 4026 4027 l = skip_comma (l); 4028 4029 if (l == NULL) 4030 return NULL; 4031 4032 l = parse_mget_mset_addr (l, &addr); 4033 } 4034 else 4035 { 4036 l = parse_mget_mset_addr (l, &addr); 4037 4038 l = skip_comma (l); 4039 4040 if (l == NULL) 4041 return NULL; 4042 4043 l = parse_acf (l, &part); 4044 } 4045 4046 if (l == NULL) 4047 return NULL; 4048 4049 insn->bits = (template->meta_opcode | 4050 (part << 19)); 4051 4052 if (!is_short_unit (addr.base_reg->unit)) 4053 { 4054 as_bad (_("base unit must be one of %s"), SHORT_UNITS); 4055 return NULL; 4056 } 4057 4058 insn->bits |= ((addr.base_reg->no << 14) | 4059 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5)); 4060 4061 insn->len = 4; 4062 return l; 4063 } 4064 4065 /* Copy the name of the next register in LINE to REG_BUF. */ 4066 static size_t 4067 strip_reg_name(const char *line, char *reg_buf) 4068 { 4069 const char *l = line; 4070 size_t len = 0; 4071 4072 while (is_register_char (*l)) 4073 { 4074 reg_buf[len] = *l; 4075 l++; 4076 len++; 4077 if (!(len < MAX_REG_LEN)) 4078 return 0; 4079 } 4080 4081 if (len) 4082 reg_buf[len] = '\0'; 4083 4084 return len; 4085 } 4086 4087 /* Parse a DSP register from LINE into REG using only the registers 4088 from DSP_REGTAB. Return the next character or NULL. */ 4089 static const char * 4090 __parse_dsp_reg (const char *line, const metag_reg **reg, htab_t dsp_regtab) 4091 { 4092 const char *l = line; 4093 char name[MAX_REG_LEN]; 4094 size_t len = 0; 4095 metag_reg entry; 4096 const metag_reg *_reg; 4097 4098 /* We don't entirely strip the register name because we might 4099 actually want to match whole string in the register table, 4100 e.g. "D0AW.1++" not just "D0AW.1". The string length of the table 4101 entry limits our comaprison to a reasonable bound anyway. */ 4102 while (is_register_char (*l) || *l == PLUS) 4103 { 4104 name[len] = *l; 4105 l++; 4106 len++; 4107 if (!(len < MAX_REG_LEN)) 4108 return NULL; 4109 } 4110 4111 if (!len) 4112 return NULL; 4113 4114 name[len] = '\0'; 4115 entry.name = name; 4116 4117 _reg = (const metag_reg *) htab_find (dsp_regtab, &entry); 4118 if (!_reg) 4119 return NULL; 4120 4121 *reg = _reg; 4122 4123 return l; 4124 } 4125 4126 /* Parse a DSP register and setup "reg" with a metag_reg whose "no" 4127 member is suitable for encoding into a DSP insn register field. */ 4128 static const char * 4129 parse_dsp_insn_reg (const char *line, const metag_reg **reg) 4130 { 4131 return __parse_dsp_reg (line, reg, dsp_reg_htab); 4132 } 4133 4134 /* Parse a DSP register and setup "reg" with a metag_reg whose "no" 4135 member is suitable for encoding into a DSP template definition insn 4136 register field. 4137 4138 There is a separate table for whether we're doing a load or a store 4139 definition. "load" specifies which table to look at. */ 4140 static const char * 4141 parse_dsp_template_reg (const char *line, const metag_reg **reg, 4142 bfd_boolean load) 4143 { 4144 return __parse_dsp_reg (line, reg, dsp_tmpl_reg_htab[load]); 4145 } 4146 4147 /* Parse a single DSP register from LINE. */ 4148 static const char * 4149 parse_dsp_reg (const char *line, const metag_reg **reg, 4150 bfd_boolean tmpl, bfd_boolean load) 4151 { 4152 if (tmpl) 4153 return parse_dsp_template_reg (line, reg, load); 4154 else 4155 return parse_dsp_insn_reg (line, reg); 4156 } 4157 4158 /* Return TRUE if UNIT is an address unit. */ 4159 static bfd_boolean 4160 is_addr_unit (enum metag_unit unit) 4161 { 4162 switch (unit) 4163 { 4164 case UNIT_A0: 4165 case UNIT_A1: 4166 return TRUE; 4167 default: 4168 return FALSE; 4169 } 4170 } 4171 4172 /* Return TRUE if UNIT1 and UNIT2 are equivalent units. */ 4173 static bfd_boolean 4174 is_same_data_unit (enum metag_unit unit1, enum metag_unit unit2) 4175 { 4176 if (unit1 == unit2) 4177 return TRUE; 4178 4179 switch (unit1) 4180 { 4181 case UNIT_D0: 4182 if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_RAM_D0) 4183 return TRUE; 4184 break; 4185 case UNIT_D1: 4186 if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_RAM_D1) 4187 return TRUE; 4188 break; 4189 case UNIT_ACC_D0: 4190 if (unit2 == UNIT_D0 || unit2 == UNIT_RAM_D0) 4191 return TRUE; 4192 break; 4193 case UNIT_ACC_D1: 4194 if (unit2 == UNIT_D1 || unit2 == UNIT_RAM_D1) 4195 return TRUE; 4196 break; 4197 case UNIT_RAM_D0: 4198 if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_D0) 4199 return TRUE; 4200 break; 4201 case UNIT_RAM_D1: 4202 if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_D1) 4203 return TRUE; 4204 break; 4205 default: 4206 return FALSE; 4207 } 4208 4209 return FALSE; 4210 } 4211 4212 /* Return TRUE if the register NUM is a quickrot control register. */ 4213 static bfd_boolean 4214 is_quickrot_reg (unsigned int num) 4215 { 4216 switch (num) 4217 { 4218 case 2: 4219 case 3: 4220 return TRUE; 4221 } 4222 4223 return FALSE; 4224 } 4225 4226 /* Return TRUE if REG is an accumulator register. */ 4227 static bfd_boolean 4228 is_accumulator_reg (const metag_reg *reg) 4229 { 4230 if (reg->unit == UNIT_ACC_D0 || reg->unit == UNIT_ACC_D1) 4231 return TRUE; 4232 4233 return FALSE; 4234 } 4235 4236 /* Return TRUE if REG is a DSP RAM register. */ 4237 static bfd_boolean 4238 is_dspram_reg (const metag_reg *reg) 4239 { 4240 if (reg->unit == UNIT_RAM_D0 || reg->unit == UNIT_RAM_D1) 4241 return TRUE; 4242 4243 return FALSE; 4244 } 4245 4246 static const char * 4247 __parse_gp_reg (const char *line, const metag_reg **reg, bfd_boolean load) 4248 { 4249 const char *l = line; 4250 char reg_buf[MAX_REG_LEN]; 4251 size_t len = 0; 4252 4253 if (l == NULL) 4254 return NULL; 4255 4256 /* Parse [DSPRAM.x]. */ 4257 if (*l == ADDR_BEGIN_CHAR) 4258 { 4259 l++; 4260 4261 if (l == NULL) 4262 return NULL; 4263 4264 l = parse_dsp_reg (l, reg, TRUE, load); 4265 if (l == NULL) 4266 return NULL; 4267 4268 if (*l == ADDR_END_CHAR) 4269 l++; 4270 else 4271 { 4272 as_bad (_("expected ']', not %c in %s"), *l, l); 4273 return NULL; 4274 } 4275 4276 return l; 4277 } 4278 else 4279 { 4280 4281 len = strip_reg_name (l, reg_buf); 4282 if (!len) 4283 return NULL; 4284 4285 l += len; 4286 *reg = parse_gp_reg (reg_buf); 4287 if (*reg == NULL) 4288 return NULL; 4289 } 4290 4291 return l; 4292 } 4293 4294 /* Parse a list of DSP/GP registers. TRY_GP indicates whether we 4295 should try to parse the register as a general-purpose register if 4296 we fail to parse it as a DSP one. TMPL indicates whether the 4297 registers are part of a template definition instruction. If this is 4298 a template definition instruction LOAD says whether it's a load 4299 template insn. FIRST_DST indicates whether the first register is 4300 a destination operand. */ 4301 static const char * 4302 parse_dsp_regs_list (const char *line, const metag_reg **regs, size_t count, 4303 size_t *regs_read, bfd_boolean try_gp, bfd_boolean tmpl, 4304 bfd_boolean load, bfd_boolean first_dst) 4305 { 4306 const char *l = line; 4307 int seen_regs = 0; 4308 size_t i; 4309 const metag_reg *reg; 4310 4311 for (i = 0; i < count; i++) 4312 { 4313 const char *next, *ll; 4314 4315 next = l; 4316 4317 if (i > 0) 4318 { 4319 l = skip_comma (l); 4320 if (l == NULL) 4321 { 4322 *regs_read = seen_regs; 4323 return next; 4324 } 4325 } 4326 4327 ll = parse_dsp_reg (l, ®, tmpl, load); 4328 4329 if (!ll) 4330 { 4331 if (try_gp) 4332 { 4333 l = __parse_gp_reg (l, ®, !(first_dst && i == 0)); 4334 if (l == NULL) 4335 { 4336 *regs_read = seen_regs; 4337 return next; 4338 } 4339 regs[i] = reg; 4340 seen_regs++; 4341 } 4342 else 4343 { 4344 *regs_read = seen_regs; 4345 return l; 4346 } 4347 } 4348 else 4349 { 4350 regs[i] = reg; 4351 seen_regs++; 4352 l = ll; 4353 } 4354 } 4355 4356 *regs_read = seen_regs; 4357 return l; 4358 } 4359 4360 /* Parse the following memory references: 4361 4362 - [Ax.r] 4363 - [Ax.r++] 4364 - [Ax.r--] 4365 - [Ax.r+Ax.r++] 4366 - [Ax.r-Ax.r--] 4367 4368 - [DSPRam] 4369 - [DSPRam++] 4370 - [DSPRam+DSPRam++] 4371 - [DSPRam-DSPRam--] */ 4372 static const char * 4373 parse_dsp_addr (const char *line, metag_addr *addr, unsigned int size, 4374 bfd_boolean load) 4375 { 4376 const char *l = line, *ll; 4377 const metag_reg *regs[1]; 4378 size_t regs_read; 4379 4380 /* Skip opening square bracket. */ 4381 l++; 4382 4383 l = parse_dsp_regs_list (l, regs, 1, ®s_read, TRUE, TRUE, load, FALSE); 4384 4385 if (l == NULL) 4386 return NULL; 4387 4388 if (!is_addr_unit (regs[0]->unit) && 4389 !is_dspram_reg (regs[0])) 4390 { 4391 as_bad (_("invalid register for memory access")); 4392 return NULL; 4393 } 4394 4395 addr->base_reg = regs[0]; 4396 4397 if (*l == ADDR_END_CHAR) 4398 { 4399 addr->exp.X_op = O_constant; 4400 addr->exp.X_add_symbol = NULL; 4401 addr->exp.X_op_symbol = NULL; 4402 4403 /* Simple register with no offset (0 immediate). */ 4404 addr->exp.X_add_number = 0; 4405 4406 addr->immediate = 1; 4407 l++; 4408 4409 return l; 4410 } 4411 4412 ll = parse_addr_post_incr_op (l, addr); 4413 4414 if (ll && *ll == ADDR_END_CHAR) 4415 { 4416 if (addr->update == 1) 4417 { 4418 /* We have a post increment/decrement. */ 4419 addr->exp.X_op = O_constant; 4420 addr->exp.X_add_number = size; 4421 addr->exp.X_add_symbol = NULL; 4422 addr->exp.X_op_symbol = NULL; 4423 addr->post_increment = 1; 4424 } 4425 addr->immediate = 1; 4426 ll++; 4427 return ll; 4428 } 4429 4430 addr->post_increment = 0; 4431 4432 l = parse_addr_op (l, addr); 4433 4434 if (l == NULL) 4435 return NULL; 4436 4437 l = parse_dsp_regs_list (l, regs, 1, ®s_read, TRUE, TRUE, load, FALSE); 4438 4439 if (l == NULL) 4440 return NULL; 4441 4442 if (regs[0]->unit != addr->base_reg->unit) 4443 { 4444 as_bad (_("offset and base must be from the same unit")); 4445 return NULL; 4446 } 4447 4448 addr->offset_reg = regs[0]; 4449 4450 if (*l == ADDR_END_CHAR) 4451 { 4452 l++; 4453 return l; 4454 } 4455 4456 l = parse_addr_post_incr_op (l, addr); 4457 4458 if (l == NULL) 4459 return NULL; 4460 4461 if (*l == ADDR_END_CHAR) 4462 { 4463 l++; 4464 return l; 4465 } 4466 4467 return NULL; 4468 } 4469 4470 /* Parse a DSP GET or SET instruction. */ 4471 static const char * 4472 parse_dget_set (const char *line, metag_insn *insn, 4473 const insn_template *template) 4474 { 4475 const char *l = line; 4476 metag_addr addr; 4477 int unit = 0; 4478 int rd_reg = 0; 4479 bfd_boolean is_get = (template->meta_opcode & 0x100); 4480 bfd_boolean is_dual = (template->meta_opcode & 0x4); 4481 bfd_boolean is_template = FALSE; 4482 const metag_reg *regs[2]; 4483 unsigned int size; 4484 size_t count, regs_read; 4485 4486 memset(&addr, 0, sizeof(addr)); 4487 addr.reloc_type = BFD_RELOC_UNUSED; 4488 4489 size = is_dual ? 8 : 4; 4490 count = is_dual ? 2 : 1; 4491 4492 if (is_get) 4493 { 4494 /* GETL can be used on one template table entry. */ 4495 if (*l == 'T') 4496 count = 1; 4497 4498 l = parse_dsp_regs_list (l, regs, count, ®s_read, FALSE, 4499 FALSE, FALSE, FALSE); 4500 l = skip_comma (l); 4501 4502 if (l == NULL) 4503 { 4504 as_bad (_("unexpected end of line")); 4505 return NULL; 4506 } 4507 4508 l = parse_addr (l, &addr, size); 4509 } 4510 else 4511 { 4512 l = parse_addr (l, &addr, size); 4513 4514 l = skip_comma (l); 4515 4516 if (l == NULL) 4517 return NULL; 4518 4519 /* GETL can be used on one template table entry. */ 4520 if (*l == 'T') 4521 count = 1; 4522 4523 l = parse_dsp_regs_list (l, regs, count, ®s_read, FALSE, FALSE, 4524 FALSE, FALSE); 4525 } 4526 4527 if (l == NULL) 4528 return NULL; 4529 4530 /* The first register dictates the unit. */ 4531 if (regs[0]->unit == UNIT_DT) 4532 is_template = TRUE; 4533 else 4534 { 4535 if (regs[0]->unit == UNIT_D0 || regs[0]->unit == UNIT_RAM_D0 || 4536 regs[0]->unit == UNIT_ACC_D0) 4537 unit = 0; 4538 else 4539 unit = 1; 4540 } 4541 4542 rd_reg = regs[0]->no; 4543 4544 /* The 'H' modifier allows a DSP GET/SET instruction to target the 4545 upper 8-bits of an accumulator. It is _only_ valid for the 4546 accumulators. */ 4547 if (insn->dsp_daoppame_flags & DSP_DAOPPAME_HIGH) 4548 { 4549 if (is_template || !(rd_reg >= 16 && rd_reg < 20)) 4550 { 4551 as_bad (_("'H' modifier only valid for accumulator registers")); 4552 return NULL; 4553 } 4554 4555 /* Top 8-bits of the accumulator. */ 4556 rd_reg |= 8; 4557 } 4558 4559 if (is_template) 4560 { 4561 insn->bits = (template->meta_opcode | (1 << 1)); 4562 } 4563 else 4564 { 4565 insn->bits = (template->meta_opcode | unit); 4566 } 4567 4568 insn->bits |= (rd_reg << 19); 4569 4570 if (addr.immediate) 4571 { 4572 int offset = addr.exp.X_add_number; 4573 4574 if (addr.negate) 4575 offset = -offset; 4576 4577 offset = offset / (int)size; 4578 4579 if (!within_signed_range (offset, DGET_SET_IMM_BITS)) 4580 { 4581 as_bad (_("offset value out of range")); 4582 return NULL; 4583 } 4584 4585 offset = offset & DGET_SET_IMM_MASK; 4586 4587 insn->bits |= (1 << 13); 4588 insn->bits |= (offset << 9); 4589 } 4590 else 4591 { 4592 int au = (addr.base_reg->unit == UNIT_A1); 4593 4594 insn->bits |= (au << 18); 4595 insn->bits |= ((addr.base_reg->no & REG_MASK) << 14); 4596 insn->bits |= ((addr.offset_reg->no & REG_MASK) << 9); 4597 } 4598 4599 if (is_dual) 4600 insn->bits |= (1 << 2); 4601 4602 if (!is_addr_unit (addr.base_reg->unit)) 4603 { 4604 as_bad (_("base unit must be either A0 or A1")); 4605 return NULL; 4606 } 4607 4608 unit = (addr.base_reg->unit == UNIT_A0) ? 0 : 1; 4609 insn->bits |= ((addr.base_reg->no << 14) | (unit << 18)); 4610 4611 insn->len = 4; 4612 4613 return l; 4614 } 4615 4616 /* Parse a DSP template instruction. */ 4617 static const char * 4618 parse_dtemplate (const char *line, metag_insn *insn, 4619 const insn_template *template) 4620 { 4621 const char *l = line; 4622 const metag_reg *regs[TEMPLATE_NUM_REGS]; 4623 bfd_boolean daop_only = FALSE; 4624 int regs_val[4]; 4625 int regs_which[4] = { -1, -1, -1, -1}; /* Register or immediate? */ 4626 int i; 4627 4628 for (i = 0; i < TEMPLATE_NUM_REGS; i++) 4629 { 4630 if (l == NULL) 4631 { 4632 as_bad (_("unexpected end of line")); 4633 return NULL; 4634 } 4635 4636 /* We may only have 3 register operands. */ 4637 if (*l == END_OF_INSN && i == 3) 4638 { 4639 daop_only = TRUE; 4640 break; 4641 } 4642 4643 if (i != 0) 4644 { 4645 l = skip_comma (l); 4646 if (l == NULL) 4647 return NULL; 4648 } 4649 4650 if (*l == IMM_CHAR) 4651 { 4652 l = parse_imm_constant (l, insn, ®s_val[i]); 4653 if (l == NULL) 4654 { 4655 as_bad (_("invalid immediate")); 4656 return NULL; 4657 } 4658 regs_which[i] = 0; 4659 } 4660 else 4661 { 4662 /* We can't tell from the template instantiation whether 4663 this is a load or store. So we have to try looking up the 4664 register name in both the load and store tables. */ 4665 const char *l2 = l; 4666 l = __parse_gp_reg (l, ®s[i], TRUE); 4667 if (l == NULL) 4668 { 4669 /* Try the store table too. */ 4670 l = __parse_gp_reg (l2, ®s[i], FALSE); 4671 if (l == NULL) 4672 { 4673 /* Then try a DSP register. */ 4674 l = parse_dsp_insn_reg (l2, ®s[i]); 4675 if (l == NULL || regs[i]->unit == UNIT_DT) 4676 { 4677 as_bad (_("invalid register")); 4678 return NULL; 4679 } 4680 } 4681 } 4682 regs_which[i] = 1; 4683 } 4684 } 4685 4686 insn->bits = template->meta_opcode; 4687 4688 if (regs_which[0] == 0) 4689 insn->bits |= (regs_val[0] << 19); 4690 else if (regs_which[0] == 1) 4691 insn->bits |= (regs[0]->no << 19); 4692 4693 if (regs_which[1] == 0) 4694 insn->bits |= (regs_val[1] << 14); 4695 else if (regs_which[1] == 1) 4696 insn->bits |= (regs[1]->no << 14); 4697 4698 if (regs_which[2] == 0) 4699 insn->bits |= (regs_val[2] << 9); 4700 else if (regs_which[2] == 1) 4701 insn->bits |= (regs[2]->no << 9); 4702 4703 if (regs_which[3] == 0) 4704 insn->bits |= (regs_val[3] << 4); 4705 else if (regs_which[3] == 1) 4706 insn->bits |= (regs[3]->no << 4); 4707 4708 /* DaOp only. */ 4709 if (daop_only) 4710 insn->bits |= (0x3 << 24); /* Set the minor opcode. */ 4711 else if (insn->dsp_daoppame_flags & DSP_DAOPPAME_HIGH) /* Half Load/Store. */ 4712 insn->bits |= (0x5 << 24); /* Set the minor opcode. */ 4713 4714 insn->len = 4; 4715 4716 return l; 4717 } 4718 4719 /* Parse a DSP Template definiton memory reference, e.g 4720 [A0.7+A0.5++]. DSPRAM is set to true by this function if this 4721 template definition is a DSP RAM template definition. */ 4722 static const char * 4723 template_mem_ref(const char *line, metag_addr *addr, 4724 bfd_boolean *dspram, int size, bfd_boolean load) 4725 { 4726 const char *l = line; 4727 4728 l = parse_dsp_addr (l, addr, size, load); 4729 4730 if (l != NULL) 4731 { 4732 if (is_addr_unit(addr->base_reg->unit)) 4733 *dspram = FALSE; 4734 else 4735 *dspram = TRUE; 4736 } 4737 4738 return l; 4739 } 4740 4741 /* Sets LOAD to TRUE if this is a Template load definiton (otherwise 4742 it's a store). Fills out ADDR, TEMPLATE_REG and ADDR_UNIT. */ 4743 static const char * 4744 parse_template_regs (const char *line, bfd_boolean *load, 4745 unsigned int *addr_unit, 4746 const metag_reg **template_reg, metag_addr *addr, 4747 bfd_boolean *dspram, int size) 4748 { 4749 const char *l = line; 4750 4751 if (l == NULL) 4752 return NULL; 4753 4754 /* DSP Template load definition (Tx, [Ax]) */ 4755 if (*l == 'T') 4756 { 4757 *load = TRUE; 4758 l = parse_dsp_reg (l, &template_reg[0], FALSE, FALSE); 4759 if (l == NULL) 4760 return NULL; 4761 4762 l = skip_comma (l); 4763 4764 l = template_mem_ref (l, addr, dspram, size, *load); 4765 4766 if (addr->base_reg->unit == UNIT_A1) 4767 *addr_unit = 1; 4768 4769 } 4770 else if (*l == ADDR_BEGIN_CHAR) /* DSP Template store ([Ax], Tx) */ 4771 { 4772 *load = FALSE; 4773 l = template_mem_ref (l, addr, dspram, size, *load); 4774 l = skip_comma(l); 4775 4776 if (l == NULL) 4777 return NULL; 4778 4779 l = parse_dsp_reg (l, &template_reg[0], FALSE, FALSE); 4780 if (l == NULL) 4781 return NULL; 4782 4783 if (addr->base_reg->unit == UNIT_A1) 4784 *addr_unit = 1; 4785 } 4786 else 4787 { 4788 as_bad (_("invalid register operand")); 4789 return NULL; 4790 } 4791 4792 return l; 4793 } 4794 4795 #define INVALID_SHIFT (-1) 4796 4797 static metag_reg _reg; 4798 4799 /* Parse a template instruction definition. */ 4800 static const char * 4801 interpret_template_regs(const char *line, metag_insn *insn, 4802 const metag_reg **regs, 4803 int *regs_shift, bfd_boolean *load, bfd_boolean *dspram, 4804 int size, int *ls_shift, int *au_shift, 4805 unsigned int *au, int *imm, int *imm_shift, 4806 unsigned int *imm_mask) 4807 { 4808 const char *l = line; 4809 metag_addr addr; 4810 const metag_reg *template_reg[1]; 4811 4812 memset (&addr, 0, sizeof(addr)); 4813 4814 regs_shift[0] = 19; 4815 regs_shift[1] = INVALID_SHIFT; 4816 4817 insn->bits |= (1 << 1); 4818 4819 l = skip_whitespace (l); 4820 4821 l = parse_template_regs (l, load, au, template_reg, 4822 &addr, dspram, size); 4823 if (l == NULL) 4824 { 4825 as_bad (_("could not parse template definition")); 4826 return NULL; 4827 } 4828 4829 regs[2] = template_reg[0]; 4830 regs_shift[2] = 9; 4831 4832 /* DSPRAM definition. */ 4833 if (*dspram) 4834 { 4835 4836 _reg = *addr.base_reg; 4837 4838 if (addr.immediate) 4839 { 4840 /* Set the post-increment bit in the register field. */ 4841 if (addr.update) 4842 _reg.no |= 0x1; 4843 } 4844 else 4845 { 4846 /* The bottom bit of the increment register tells us 4847 whether it's increment register 0 or 1. */ 4848 if (addr.offset_reg->no & 0x1) 4849 _reg.no |= 0x3; 4850 else 4851 _reg.no |= 0x2; 4852 } 4853 4854 regs[0] = &_reg; 4855 4856 insn->bits |= (0x3 << 17); /* This signifies a DSPRAM definition. */ 4857 } 4858 else /* DaOpPaMe definition. */ 4859 { 4860 regs[0] = addr.base_reg; 4861 if (addr.immediate) 4862 { 4863 /* Set the I bit. */ 4864 insn->bits |= (1 << 18); 4865 4866 if (addr.update == 1) 4867 { 4868 if (addr.negate == 1) 4869 *imm = 0x3; 4870 else 4871 *imm = 0x1; 4872 } 4873 4874 *imm_shift = 14; 4875 *imm_mask = 0x3; 4876 } 4877 else 4878 { 4879 /* Setup the offset register. */ 4880 regs[1] = addr.offset_reg; 4881 regs_shift[1] = 14; 4882 } 4883 *au_shift = 23; 4884 } 4885 4886 *ls_shift = 13; 4887 4888 return l; 4889 } 4890 4891 /* Does this combination of units need the O2R bit and can it be encoded? */ 4892 static bfd_boolean 4893 units_need_o2r (enum metag_unit unit1, enum metag_unit unit2) 4894 { 4895 if (unit1 == unit2) 4896 return FALSE; 4897 4898 if (unit1 == UNIT_D0 || unit1 == UNIT_ACC_D0 || unit1 == UNIT_RAM_D0) 4899 { 4900 if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_RAM_D0 || unit2 == UNIT_D0) 4901 return FALSE; 4902 4903 switch (unit2) 4904 { 4905 case UNIT_A1: 4906 case UNIT_D1: 4907 case UNIT_RD: 4908 case UNIT_A0: 4909 return TRUE; 4910 default: 4911 return FALSE; 4912 } 4913 } 4914 4915 if (unit1 == UNIT_D1 || unit1 == UNIT_ACC_D1 || unit1 == UNIT_RAM_D1) 4916 { 4917 if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_RAM_D1 || unit2 == UNIT_D1) 4918 return FALSE; 4919 4920 switch (unit2) 4921 { 4922 case UNIT_A1: 4923 case UNIT_D0: 4924 case UNIT_RD: 4925 case UNIT_A0: 4926 return TRUE; 4927 default: 4928 return FALSE; 4929 } 4930 } 4931 4932 return FALSE; 4933 } 4934 4935 /* Return TRUE if this is a DSP data unit. */ 4936 static bfd_boolean 4937 is_dsp_data_unit (const metag_reg *reg) 4938 { 4939 switch (reg->unit) 4940 { 4941 case UNIT_D0: 4942 case UNIT_D1: 4943 case UNIT_ACC_D0: 4944 case UNIT_ACC_D1: 4945 case UNIT_RAM_D0: 4946 case UNIT_RAM_D1: 4947 return TRUE; 4948 default: 4949 return FALSE; 4950 } 4951 } 4952 4953 static metag_reg o2r_reg; 4954 4955 /* Parse a DaOpPaMe load template definition. */ 4956 static const char * 4957 parse_dalu (const char *line, metag_insn *insn, 4958 const insn_template *template) 4959 { 4960 const char *l = line; 4961 const char *ll; 4962 const metag_reg *regs[4]; 4963 metag_addr addr; 4964 size_t regs_read; 4965 bfd_boolean is_mov = MAJOR_OPCODE (template->meta_opcode) == OPC_ADD; 4966 bfd_boolean is_cmp = ((MAJOR_OPCODE (template->meta_opcode) == OPC_CMP) && 4967 ((template->meta_opcode & 0xee) == 0)); 4968 bfd_boolean is_dual = (insn->dsp_width == DSP_WIDTH_DUAL); 4969 bfd_boolean is_quickrot64 = ((insn->dsp_action_flags & DSP_ACTION_QR64) != 0); 4970 int l1_shift = INVALID_SHIFT; 4971 bfd_boolean load = FALSE; 4972 int ls_shift = INVALID_SHIFT; 4973 bfd_boolean ar = FALSE; 4974 int ar_shift = INVALID_SHIFT; 4975 int regs_shift[3] = { INVALID_SHIFT, INVALID_SHIFT, INVALID_SHIFT }; 4976 int imm = 0; 4977 int imm_shift = INVALID_SHIFT; 4978 unsigned int imm_mask = 0; 4979 unsigned int au = 0; 4980 int au_shift = INVALID_SHIFT; 4981 unsigned int du = 0; 4982 int du_shift = INVALID_SHIFT; 4983 unsigned int sc = ((insn->dsp_action_flags & DSP_ACTION_OV) != 0); 4984 int sc_shift = INVALID_SHIFT; 4985 unsigned int om = ((insn->dsp_action_flags & DSP_ACTION_MOD) != 0); 4986 int om_shift = INVALID_SHIFT; 4987 unsigned int o2r = 0; 4988 int o2r_shift = INVALID_SHIFT; 4989 unsigned int qr = 0; 4990 int qr_shift = INVALID_SHIFT; 4991 int qd_shift = INVALID_SHIFT; 4992 unsigned int qn = 0; 4993 int qn_shift = INVALID_SHIFT; 4994 unsigned int a1 = ((insn->dsp_action_flags & (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ZERO)) != 0); 4995 int a1_shift = INVALID_SHIFT; 4996 unsigned int a2 = ((insn->dsp_action_flags & (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD)) != 0); 4997 int a2_shift = INVALID_SHIFT; 4998 unsigned su = ((insn->dsp_action_flags & DSP_ACTION_UMUL) != 0); 4999 int su_shift = INVALID_SHIFT; 5000 unsigned int ac; 5001 int ac_shift = INVALID_SHIFT; 5002 unsigned int mx = (((insn->dsp_daoppame_flags & DSP_DAOPPAME_8) != 0) || 5003 (insn->dsp_daoppame_flags & DSP_DAOPPAME_16) != 0); 5004 int mx_shift = INVALID_SHIFT; 5005 int size = is_dual ? 8 : 4; 5006 bfd_boolean dspram; 5007 bfd_boolean conditional = (MINOR_OPCODE (template->meta_opcode) & 0x4); 5008 5009 /* XFIXME: check the flags are valid with the instruction. */ 5010 if (is_quickrot64 && !(template->arg_type & DSP_ARGS_QR)) 5011 { 5012 as_bad (_("QUICKRoT 64-bit extension not applicable to this instruction")); 5013 return NULL; 5014 } 5015 5016 insn->bits = template->meta_opcode; 5017 5018 memset (regs, 0, sizeof (regs)); 5019 memset (&addr, 0, sizeof (addr)); 5020 5021 /* There are the following forms of DSP ALU instructions, 5022 5023 * Group 1: 5024 19. D[T] Op De.r,Dx.r,De.r 5025 1. D[T] Op De.r,Dx.r,De.r|ACe.r [Accumulator in src 2] 5026 3. D[T] Op De.r,Dx.r,De.r[,Ae.r] [QUICKRoT] 5027 2. D[T] Op ACe.e,ACx.r,ACo.e [cross-unit accumulator op] 5028 5. D[T] Op De.r|ACe.r,Dx.r,De.r 5029 20. D[T] Op De.r,Dx.r|ACx.r,De.r 5030 8. D Opcc De.r,Dx.r,Rx.r 5031 6. D Op De.r,Dx.r,Rx.r|RD 5032 17. D Op De.r|ACe.r,Dx.r,Rx.r|RD 5033 7. D Op De.e,Dx.r,#I16 5034 5035 * Group 2: 5036 4. D[T] Op Dx.r,De.r 5037 10. D Op Dx.r,Rx.r|RD 5038 13. D Op Dx.r,Rx.r 5039 11. D Op Dx.r,#I16 5040 12. D[T] Op De.r,Dx.r 5041 14. D Op DSPe.r,Dx.r 5042 15. D Op DSPx.r,#I16 5043 16. D Op De.r,DSPx.r 5044 18. D Op De.r,Dx.r|ACx.r 5045 5046 * Group 3: 5047 22. D Op De.r,Dx.r|ACx.r,De.r|#I5 5048 23. D Op Ux.r,Dx.r|ACx.r,De.r|#I5 5049 21. D Op De.r,Dx.r|ACx.r,#I5 */ 5050 5051 /* Group 1. */ 5052 if (template->arg_type & DSP_ARGS_1) 5053 { 5054 du_shift = 24; 5055 5056 /* Could this be a cross-unit accumulator op, 5057 e.g. ACe.e,ACx.r,ACo.e */ 5058 if (template->arg_type & DSP_ARGS_XACC) 5059 { 5060 ll = parse_dsp_regs_list (l, regs, 3, ®s_read, FALSE, FALSE, 5061 FALSE, FALSE); 5062 if (ll != NULL && regs_read == 3 5063 && is_accumulator_reg (regs[0])) 5064 { 5065 if (regs[0]->unit != regs[1]->unit || 5066 regs[2]->unit == regs[1]->unit) 5067 { 5068 as_bad (_("invalid operands for cross-unit op")); 5069 return NULL; 5070 } 5071 5072 du = (regs[1]->unit == UNIT_ACC_D1); 5073 regs_shift[1] = 19; 5074 l = ll; 5075 5076 /* All cross-unit accumulator ops have bits 8 and 6 set. */ 5077 insn->bits |= (5 << 6); 5078 5079 goto check_for_template; 5080 } 5081 5082 /* If we reach here, this instruction is not a 5083 cross-unit accumulator op. */ 5084 } 5085 5086 if (template->arg_type & DSP_ARGS_SPLIT8) 5087 om_shift = 7; 5088 5089 sc_shift = 5; 5090 l1_shift = 4; 5091 o2r_shift = 0; 5092 5093 /* De.r|ACe.r,Dx.r,De.r */ 5094 if (template->arg_type & DSP_ARGS_DACC) 5095 { 5096 /* XFIXME: these need moving? */ 5097 a2_shift = 7; 5098 su_shift = 6; 5099 a1_shift = 2; 5100 om_shift = 3; 5101 5102 ll = parse_dsp_reg (l, ®s[0], FALSE, FALSE); 5103 if (ll != NULL) 5104 { 5105 /* Using ACe.r as the dst requires one of the P,N or Z 5106 flags to be used. */ 5107 if (!(insn->dsp_action_flags & 5108 (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD|DSP_ACTION_ACC_ZERO))) 5109 { 5110 as_bad (_("missing flags: one of 'P', 'N' or 'Z' required")); 5111 return NULL; 5112 } 5113 5114 l = ll; 5115 l = skip_comma (l); 5116 l = parse_dsp_regs_list (l, ®s[1], 2, ®s_read, 5117 TRUE, FALSE, FALSE, FALSE); 5118 if (l == NULL || regs_read != 2) 5119 { 5120 as_bad (_("invalid register")); 5121 return NULL; 5122 } 5123 5124 if (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_RAM_D1) 5125 du = 1; 5126 5127 regs_shift[0] = 19; 5128 regs_shift[1] = 14; 5129 regs_shift[2] = 9; 5130 goto check_for_template; 5131 } 5132 5133 /* If we reach here, this instruction does not use the 5134 accumulator as the destination register. */ 5135 if ((insn->dsp_action_flags & 5136 (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD|DSP_ACTION_ACC_ZERO))) 5137 { 5138 as_bad (_("'P', 'N' or 'Z' flags may only be specified when accumulating")); 5139 return NULL; 5140 } 5141 } 5142 5143 regs_shift[0] = 19; 5144 5145 5146 l = parse_dsp_regs_list (l, regs, 2, ®s_read, TRUE, FALSE, FALSE, TRUE); 5147 if (l == NULL || regs_read != 2) 5148 return NULL; 5149 5150 l = skip_comma (l); 5151 if (l == NULL) 5152 return NULL; 5153 5154 if (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_RAM_D1) 5155 du = 1; 5156 5157 if (is_accumulator_reg(regs[0]) && !(template->arg_type & DSP_ARGS_DACC)) 5158 { 5159 as_bad (_("accumulator not a valid destination")); 5160 return NULL; 5161 } 5162 5163 /* Check for immediate, e.g. De.r,Dx.r,#I16 */ 5164 if (*l == IMM_CHAR) 5165 { 5166 l = parse_imm16 (l, insn, &imm); 5167 if (l == NULL) 5168 { 5169 as_bad (_("invalid immediate value")); 5170 return NULL; 5171 } 5172 5173 if (!within_signed_range (imm, IMM16_BITS)) 5174 { 5175 as_bad (_("immediate value out of range")); 5176 return NULL; 5177 } 5178 5179 if (regs[0]->unit != regs[1]->unit || regs[0]->no != regs[1]->no) 5180 { 5181 as_bad (_("immediate value not allowed when source & dest differ")); 5182 return NULL; 5183 } 5184 5185 imm_mask = 0xffff; 5186 imm_shift = 3; 5187 5188 /* Set the I-bit */ 5189 insn->bits |= (1 << 25); 5190 5191 insn->bits |= (0x3 << 0); 5192 5193 l1_shift = 2; 5194 5195 /* Remove any bits that have been set in the immediate 5196 field. */ 5197 insn->bits &= ~(imm_mask << imm_shift); 5198 } 5199 else 5200 { 5201 5202 regs_shift[1] = 14; 5203 regs_shift[2] = 9; 5204 5205 /* Is Rs2 an accumulator reg, e.g. De.r,Dx.r,De.r|ACe.r */ 5206 ll = parse_dsp_reg (l, ®s[2], FALSE, FALSE); 5207 if (ll != NULL) 5208 { 5209 l = ll; 5210 5211 if (!(template->arg_type & DSP_ARGS_ACC2)) 5212 { 5213 as_bad (_("invalid register operand: %s"), regs[2]->name); 5214 return NULL; 5215 } 5216 5217 om_shift = 3; 5218 ar_shift = 7; 5219 ar = TRUE; 5220 } 5221 else 5222 { 5223 /* De.r,Dx.r,De.r */ 5224 l = __parse_gp_reg (l, ®s[2], TRUE); 5225 if (l == NULL) 5226 return NULL; 5227 } 5228 5229 if (template->arg_type & DSP_ARGS_ACC2) 5230 om_shift = 3; 5231 5232 /* Is this a QUICKRoT instruction? De.r,Dx.r,De.r[,Ae.r] */ 5233 if (template->arg_type & DSP_ARGS_QR) 5234 { 5235 if (conditional) 5236 qn_shift = 5; 5237 else 5238 { 5239 qn_shift = 7; 5240 qr_shift = 6; 5241 qd_shift = 5; 5242 } 5243 5244 l = skip_comma (l); 5245 if (l == NULL) 5246 { 5247 as_bad (_("QUICKRoT extension requires 4 registers")); 5248 return NULL; 5249 } 5250 5251 l = __parse_gp_reg (l, ®s[3], TRUE); 5252 if (l == NULL) 5253 { 5254 as_bad (_("invalid fourth register")); 5255 return NULL; 5256 } 5257 5258 if (!is_addr_unit (regs[3]->unit) || 5259 !is_quickrot_reg (regs[3]->no)) 5260 { 5261 as_bad (_("A0.2,A0.3,A1.2,A1.3 required for QUICKRoT register")); 5262 return NULL; 5263 } 5264 5265 qn = (regs[3]->no == 3); 5266 } 5267 } 5268 5269 check_for_template: 5270 /* This is the common exit path. Check for o2r. */ 5271 if (regs[2] != NULL) 5272 { 5273 o2r = units_need_o2r (regs[1]->unit, regs[2]->unit); 5274 if (o2r) 5275 { 5276 o2r_reg.no = lookup_o2r (0, du, regs[2]); 5277 o2r_reg.unit = regs[2]->unit; 5278 regs[2] = &o2r_reg; 5279 } 5280 } 5281 5282 /* Check any DSP RAM pointers are valid for this unit. */ 5283 if ((du && (regs[0]->unit == UNIT_RAM_D0)) || 5284 (!du && (regs[0]->unit == UNIT_RAM_D1)) || 5285 (du && (regs[1]->unit == UNIT_RAM_D0)) || 5286 (!du && (regs[1]->unit == UNIT_RAM_D1)) || 5287 (du && regs[2] && (regs[2]->unit == UNIT_RAM_D0)) || 5288 (!du && regs[2] && (regs[2]->unit == UNIT_RAM_D1))) { 5289 as_bad (_("DSP RAM pointer in incorrect unit")); 5290 return NULL; 5291 } 5292 5293 /* Is this a template definition? */ 5294 if (IS_TEMPLATE_DEF (insn)) 5295 { 5296 l = interpret_template_regs(l, insn, regs, regs_shift, &load, 5297 &dspram, size, &ls_shift, &au_shift, 5298 &au, &imm, &imm_shift, &imm_mask); 5299 5300 if (l == NULL) 5301 return NULL; 5302 5303 if (!dspram) 5304 mx_shift = 0; 5305 } 5306 5307 goto matched; 5308 } 5309 5310 /* Group 2. */ 5311 if (template->arg_type & DSP_ARGS_2) 5312 { 5313 bfd_boolean is_xsd = ((MAJOR_OPCODE (template->meta_opcode) == OPC_MISC) && 5314 (MINOR_OPCODE (template->meta_opcode) == 0xa)); 5315 bfd_boolean is_fpu_mov = template->insn_type == INSN_DSP_FPU; 5316 bfd_boolean to_fpu = (template->meta_opcode >> 7) & 0x1; 5317 5318 if (is_xsd) 5319 du_shift = 0; 5320 else 5321 du_shift = 24; 5322 5323 l1_shift = 4; 5324 5325 /* CMPs and TSTs don't store to their destination operand. */ 5326 ll = __parse_gp_reg (l, regs, is_cmp); 5327 if (ll == NULL) 5328 { 5329 /* DSPe.r,Dx.r or DSPx.r,#I16 */ 5330 if (template->arg_type & DSP_ARGS_DSP_SRC1) 5331 { 5332 l = parse_dsp_reg (l, regs, FALSE, FALSE); 5333 if (l == NULL) 5334 { 5335 as_bad (_("invalid register operand #1")); 5336 return NULL; 5337 } 5338 5339 /* Only MOV instructions have a DSP register as a 5340 destination. Set the MOV DSPe.r opcode. The simple 5341 OR'ing is OK because the usual MOV opcode is 0x00. */ 5342 insn->bits = (0x91 << 24); 5343 du_shift = 0; 5344 l1_shift = 2; 5345 regs_shift[0] = 19; 5346 } 5347 else 5348 { 5349 as_bad (_("invalid register operand #2")); 5350 return NULL; 5351 } 5352 } 5353 else 5354 { 5355 l = ll; 5356 5357 /* Everything but CMP and TST. */ 5358 if (MAJOR_OPCODE (template->meta_opcode) == OPC_ADD || 5359 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB || 5360 MAJOR_OPCODE (insn->bits) == OPC_9 || 5361 MAJOR_OPCODE (template->meta_opcode) == OPC_MISC || 5362 ((template->meta_opcode & 0x0000002c) != 0)) 5363 regs_shift[0] = 19; 5364 else 5365 regs_shift[0] = 14; 5366 } 5367 5368 if (!is_dsp_data_unit (regs[0]) && !(regs[0]->unit == UNIT_FX && 5369 is_fpu_mov && to_fpu)) 5370 return NULL; 5371 5372 du = (regs[0]->unit == UNIT_D1 || regs[0]->unit == UNIT_RAM_D1 || 5373 regs[0]->unit == UNIT_ACC_D1); 5374 5375 l = skip_comma (l); 5376 5377 if (*l == IMM_CHAR) 5378 { 5379 if (template->arg_type & DSP_ARGS_IMM && 5380 !(is_mov && (MAJOR_OPCODE (insn->bits) != OPC_9))) 5381 { 5382 l = parse_imm16 (l, insn, &imm); 5383 if (l == NULL) 5384 { 5385 as_bad (_("invalid immediate value")); 5386 return NULL; 5387 } 5388 5389 if (!within_signed_range (imm, IMM16_BITS)) 5390 return NULL; 5391 5392 l1_shift = 2; 5393 regs_shift[0] = 19; 5394 5395 imm_mask = 0xffff; 5396 imm_shift = 3; 5397 5398 /* Set the I-bit unless it's a MOV because they're 5399 different. */ 5400 if (!(is_mov && MAJOR_OPCODE (insn->bits) == OPC_9)) 5401 insn->bits |= (1 << 25); 5402 5403 /* All instructions that takes immediates also have bit 1 set. */ 5404 insn->bits |= (1 << 1); 5405 5406 if (MAJOR_OPCODE (insn->bits) != OPC_9) 5407 insn->bits |= (1 << 0); 5408 5409 insn->bits &= ~(1 << 8); 5410 } 5411 else 5412 { 5413 as_bad (_("this instruction does not accept an immediate")); 5414 return NULL; 5415 } 5416 } 5417 else 5418 { 5419 if (MAJOR_OPCODE (insn->bits) != OPC_9) 5420 { 5421 insn->bits |= (1 << 8); 5422 l1_shift = 4; 5423 } 5424 5425 ll = __parse_gp_reg (l, ®s[1], TRUE); 5426 if (ll == NULL) 5427 { 5428 if (template->arg_type & DSP_ARGS_DSP_SRC2) 5429 { 5430 l = parse_dsp_reg (l, ®s[1], FALSE, FALSE); 5431 if (l == NULL) 5432 { 5433 as_bad (_("invalid register operand #3")); 5434 return NULL; 5435 } 5436 5437 /* MOV and NEG. */ 5438 if ((is_mov && (MAJOR_OPCODE (insn->bits) != OPC_9)) || 5439 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB) 5440 { 5441 if (is_accumulator_reg (regs[1])) 5442 { 5443 if (is_fpu_mov) 5444 { 5445 as_bad (_("this instruction does not accept an accumulator")); 5446 return NULL; 5447 } 5448 ar_shift = 7; 5449 ar = 1; 5450 regs_shift[1] = 9; 5451 } 5452 else 5453 { 5454 du_shift = 0; 5455 l1_shift = 2; 5456 regs_shift[1] = 14; 5457 insn->bits = (0x92 << 24); /* Set opcode. */ 5458 } 5459 } 5460 } 5461 else 5462 { 5463 as_bad (_("invalid register operand #4")); 5464 return NULL; 5465 } 5466 } 5467 else 5468 { 5469 /* Set the o2r bit if required. */ 5470 if (!is_fpu_mov && units_need_o2r (regs[0]->unit, regs[1]->unit)) 5471 { 5472 o2r_reg = *regs[1]; 5473 o2r_reg.no = lookup_o2r (0, du, regs[1]); 5474 regs[1] = &o2r_reg; 5475 o2r_shift = 0; 5476 o2r = 1; 5477 } 5478 else if (!is_dsp_data_unit (regs[1]) && 5479 !(is_fpu_mov && !to_fpu && regs[1]->unit == UNIT_FX)) 5480 return NULL; 5481 5482 if (is_fpu_mov && to_fpu) 5483 du = (regs[1]->unit == UNIT_D1 || 5484 regs[1]->unit == UNIT_RAM_D1 || 5485 regs[1]->unit == UNIT_ACC_D1); 5486 5487 l = ll; 5488 5489 if (MAJOR_OPCODE (insn->bits) == OPC_ADD || 5490 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB || 5491 (((template->meta_opcode & 0x0000002c) == 0) && 5492 MAJOR_OPCODE (template->meta_opcode) != OPC_MISC)) 5493 regs_shift[1] = 9; 5494 else 5495 regs_shift[1] = 14; 5496 } 5497 } 5498 5499 /* If it's an 0x0 MOV or NEG set some lower bits. */ 5500 if ((MAJOR_OPCODE (insn->bits) == OPC_ADD || 5501 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB) && !is_fpu_mov) 5502 { 5503 om_shift = 3; 5504 sc_shift = 5; 5505 insn->bits |= (1 << 2); 5506 } 5507 5508 /* Check for template definitons. */ 5509 if (IS_TEMPLATE_DEF (insn)) 5510 { 5511 l = interpret_template_regs(l, insn, regs, regs_shift, &load, 5512 &dspram, size, &ls_shift, &au_shift, 5513 &au, &imm, &imm_shift, &imm_mask); 5514 mx_shift = 0; 5515 5516 if (l == NULL) 5517 return NULL; 5518 } 5519 goto matched; 5520 } 5521 5522 /* Group 3. */ 5523 du_shift = 24; 5524 l1_shift = 4; 5525 5526 l = __parse_gp_reg (l, regs, FALSE); 5527 if (l == NULL) 5528 { 5529 as_bad (_("invalid register operand")); 5530 return NULL; 5531 } 5532 5533 l = skip_comma (l); 5534 5535 if (*l == 'A') 5536 { 5537 l = parse_dsp_reg (l, ®s[1], FALSE, FALSE); 5538 if (l == NULL) 5539 { 5540 as_bad (_("invalid accumulator register")); 5541 return NULL; 5542 } 5543 ac = 1; 5544 ac_shift = 0; 5545 } 5546 else 5547 { 5548 l = __parse_gp_reg (l, ®s[1], TRUE); 5549 if (l == NULL) 5550 { 5551 as_bad (_("invalid register operand")); 5552 return NULL; 5553 } 5554 } 5555 5556 regs_shift[0] = 19; 5557 regs_shift[1] = 14; 5558 5559 du = (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_ACC_D1 5560 || regs[1]->unit == UNIT_RAM_D1); 5561 5562 l = skip_comma (l); 5563 5564 if (*l == IMM_CHAR) 5565 { 5566 l = parse_imm_constant (l, insn, &imm); 5567 if (l == NULL) 5568 { 5569 as_bad (_("invalid immediate value")); 5570 return NULL; 5571 } 5572 5573 if (!within_unsigned_range (imm, IMM5_BITS)) 5574 return NULL; 5575 5576 imm_mask = 0x1f; 5577 imm_shift = 9; 5578 5579 /* Set the I-bit */ 5580 insn->bits |= (1 << 25); 5581 } 5582 else 5583 { 5584 regs_shift[2] = 9; 5585 l = __parse_gp_reg (l, ®s[2], TRUE); 5586 if (l == NULL) 5587 return NULL; 5588 } 5589 5590 /* Check for post-processing R,G,B flags. Conditional instructions 5591 do not have these bits. */ 5592 if (insn->dsp_action_flags & DSP_ACTION_CLAMP9) 5593 { 5594 if ((template->meta_opcode >> 26) & 0x1) 5595 { 5596 as_bad (_("conditional instruction cannot use G flag")); 5597 return NULL; 5598 } 5599 5600 insn->bits |= (1 << 3); 5601 } 5602 5603 if (insn->dsp_action_flags & DSP_ACTION_CLAMP8) 5604 { 5605 if ((template->meta_opcode >> 26) & 0x1) 5606 { 5607 as_bad (_("conditional instruction cannot use B flag")); 5608 return NULL; 5609 } 5610 5611 insn->bits |= (0x3 << 2); 5612 } 5613 5614 if (insn->dsp_action_flags & DSP_ACTION_ROUND) 5615 { 5616 if ((template->meta_opcode >> 26) & 0x1) 5617 { 5618 as_bad (_("conditional instruction cannot use R flag")); 5619 return NULL; 5620 } 5621 insn->bits |= (1 << 2); 5622 } 5623 5624 /* Conditional Data Unit Shift instructions cannot be dual unit. */ 5625 if ((template->meta_opcode >> 26) & 0x1) 5626 ls_shift = INVALID_SHIFT; 5627 5628 /* The Condition Is Always (CA) bit must be set if we're targetting a 5629 Ux.r register as the destination. This means that we can't have 5630 any other condition bits set. */ 5631 if (!is_same_data_unit (regs[1]->unit, regs[0]->unit)) 5632 { 5633 /* Set both the Conditional bit and the Condition is Always bit. */ 5634 insn->bits |= (1 << 26); 5635 insn->bits |= (1 << 5); 5636 5637 /* Fill out the Ud field. */ 5638 insn->bits |= (regs[0]->unit << 1); 5639 } 5640 5641 if (IS_TEMPLATE_DEF (insn)) 5642 { 5643 l = interpret_template_regs(l, insn, regs, regs_shift, &load, 5644 &dspram, size, &ls_shift, &au_shift, 5645 &au, &imm, &imm_shift, &imm_mask); 5646 5647 if (l == NULL) 5648 return NULL; 5649 5650 if (!dspram) 5651 mx_shift = 5; 5652 } 5653 5654 /* Fall through. */ 5655 matched: 5656 5657 /* Set the registers and immediate values. */ 5658 if (regs_shift[0] != INVALID_SHIFT) 5659 insn->bits |= (regs[0]->no << regs_shift[0]); 5660 5661 if (regs_shift[1] != INVALID_SHIFT) 5662 insn->bits |= (regs[1]->no << regs_shift[1]); 5663 5664 if (regs_shift[2] != INVALID_SHIFT) 5665 insn->bits |= (regs[2]->no << regs_shift[2]); 5666 5667 /* Does this insn have an 'IMM' bit? The immediate value should 5668 already have been masked. */ 5669 if (imm_shift != INVALID_SHIFT) 5670 insn->bits |= ((imm & imm_mask) << imm_shift); 5671 5672 /* Does this insn have an 'AU' bit? */ 5673 if (au_shift != INVALID_SHIFT) 5674 insn->bits |= (au << au_shift); 5675 5676 /* Does this instruction have an 'LS' bit? */ 5677 if (ls_shift != INVALID_SHIFT) 5678 insn->bits |= (load << ls_shift); 5679 5680 /* Does this instruction have an 'AR' bit? */ 5681 if (ar) 5682 insn->bits |= (1 << ar_shift); 5683 5684 if (du_shift != INVALID_SHIFT) 5685 insn->bits |= (du << du_shift); 5686 5687 if (sc_shift != INVALID_SHIFT) 5688 insn->bits |= (sc << sc_shift); 5689 5690 if (om_shift != INVALID_SHIFT) 5691 insn->bits |= (om << om_shift); 5692 5693 if (o2r_shift != INVALID_SHIFT) 5694 insn->bits |= (o2r << o2r_shift); 5695 5696 if (qn_shift != INVALID_SHIFT) 5697 insn->bits |= (qn << qn_shift); 5698 5699 if (qr_shift != INVALID_SHIFT) 5700 insn->bits |= (qr << qr_shift); 5701 5702 if (qd_shift != INVALID_SHIFT) 5703 insn->bits |= (is_quickrot64 << qd_shift); 5704 5705 if (a1_shift != INVALID_SHIFT) 5706 insn->bits |= (a1 << a1_shift); 5707 5708 if (a2_shift != INVALID_SHIFT) 5709 insn->bits |= (a2 << a2_shift); 5710 5711 if (su_shift != INVALID_SHIFT) 5712 insn->bits |= (su << su_shift); 5713 5714 if (imm_shift != INVALID_SHIFT) 5715 insn->bits |= ((imm & imm_mask) << imm_shift); 5716 5717 if (ac_shift != INVALID_SHIFT) 5718 insn->bits |= (ac << ac_shift); 5719 5720 if (mx_shift != INVALID_SHIFT) 5721 insn->bits |= (mx << mx_shift); 5722 5723 if (is_dual) 5724 { 5725 if (l1_shift == INVALID_SHIFT) 5726 { 5727 as_bad (_("'L' modifier not valid for this instruction")); 5728 return NULL; 5729 } 5730 5731 insn->bits |= (1 << l1_shift); 5732 } 5733 5734 insn->len = 4; 5735 5736 return l; 5737 } 5738 5739 typedef const char *(*insn_parser)(const char *, metag_insn *, 5740 const insn_template *); 5741 5742 /* Parser table. */ 5743 static const insn_parser insn_parsers[ENC_MAX] = 5744 { 5745 [ENC_NONE] = parse_none, 5746 [ENC_MOV_U2U] = parse_mov_u2u, 5747 [ENC_MOV_PORT] = parse_mov_port, 5748 [ENC_MMOV] = parse_mmov, 5749 [ENC_MDRD] = parse_mdrd, 5750 [ENC_MOVL_TTREC] = parse_movl_ttrec, 5751 [ENC_GET_SET] = parse_get_set, 5752 [ENC_GET_SET_EXT] = parse_get_set_ext, 5753 [ENC_MGET_MSET] = parse_mget_mset, 5754 [ENC_COND_SET] = parse_cond_set, 5755 [ENC_XFR] = parse_xfr, 5756 [ENC_MOV_CT] = parse_mov_ct, 5757 [ENC_SWAP] = parse_swap, 5758 [ENC_JUMP] = parse_jump, 5759 [ENC_CALLR] = parse_callr, 5760 [ENC_ALU] = parse_alu, 5761 [ENC_SHIFT] = parse_shift, 5762 [ENC_MIN_MAX] = parse_min_max, 5763 [ENC_BITOP] = parse_bitop, 5764 [ENC_CMP] = parse_cmp, 5765 [ENC_BRANCH] = parse_branch, 5766 [ENC_KICK] = parse_kick, 5767 [ENC_SWITCH] = parse_switch, 5768 [ENC_CACHER] = parse_cacher, 5769 [ENC_CACHEW] = parse_cachew, 5770 [ENC_ICACHE] = parse_icache, 5771 [ENC_LNKGET] = parse_lnkget, 5772 [ENC_FMOV] = parse_fmov, 5773 [ENC_FMMOV] = parse_fmmov, 5774 [ENC_FMOV_DATA] = parse_fmov_data, 5775 [ENC_FMOV_I] = parse_fmov_i, 5776 [ENC_FPACK] = parse_fpack, 5777 [ENC_FSWAP] = parse_fswap, 5778 [ENC_FCMP] = parse_fcmp, 5779 [ENC_FMINMAX] = parse_fminmax, 5780 [ENC_FCONV] = parse_fconv, 5781 [ENC_FCONVX] = parse_fconvx, 5782 [ENC_FBARITH] = parse_fbarith, 5783 [ENC_FEARITH] = parse_fearith, 5784 [ENC_FREC] = parse_frec, 5785 [ENC_FSIMD] = parse_fsimd, 5786 [ENC_FGET_SET_ACF] = parse_fget_set_acf, 5787 [ENC_DGET_SET] = parse_dget_set, 5788 [ENC_DTEMPLATE] = parse_dtemplate, 5789 [ENC_DALU] = parse_dalu, 5790 }; 5791 5792 struct metag_core_option 5793 { 5794 char *name; 5795 unsigned int value; 5796 }; 5797 5798 /* CPU type options. */ 5799 static const struct metag_core_option metag_cpus[] = 5800 { 5801 {"all", CoreMeta11|CoreMeta12|CoreMeta21}, 5802 {"metac11", CoreMeta11}, 5803 {"metac12", CoreMeta12}, 5804 {"metac21", CoreMeta21}, 5805 {NULL, 0}, 5806 }; 5807 5808 /* FPU type options. */ 5809 static const struct metag_core_option metag_fpus[] = 5810 { 5811 {"metac21", FpuMeta21}, 5812 {NULL, 0}, 5813 }; 5814 5815 /* DSP type options. */ 5816 static const struct metag_core_option metag_dsps[] = 5817 { 5818 {"metac21", DspMeta21}, 5819 {NULL, 0}, 5820 }; 5821 5822 /* Parse a CPU command line option. */ 5823 static int 5824 metag_parse_cpu (char * str) 5825 { 5826 const struct metag_core_option * opt; 5827 int optlen; 5828 5829 optlen = strlen (str); 5830 5831 if (optlen == 0) 5832 { 5833 as_bad (_("missing cpu name `%s'"), str); 5834 return 0; 5835 } 5836 5837 for (opt = metag_cpus; opt->name != NULL; opt++) 5838 if (strncmp (opt->name, str, optlen) == 0) 5839 { 5840 mcpu_opt = opt->value; 5841 return 1; 5842 } 5843 5844 as_bad (_("unknown cpu `%s'"), str); 5845 return 0; 5846 } 5847 5848 /* Parse an FPU command line option. */ 5849 static int 5850 metag_parse_fpu (char * str) 5851 { 5852 const struct metag_core_option * opt; 5853 int optlen; 5854 5855 optlen = strlen (str); 5856 5857 if (optlen == 0) 5858 { 5859 as_bad (_("missing fpu name `%s'"), str); 5860 return 0; 5861 } 5862 5863 for (opt = metag_fpus; opt->name != NULL; opt++) 5864 if (strncmp (opt->name, str, optlen) == 0) 5865 { 5866 mfpu_opt = opt->value; 5867 return 1; 5868 } 5869 5870 as_bad (_("unknown fpu `%s'"), str); 5871 return 0; 5872 } 5873 5874 /* Parse a DSP command line option. */ 5875 static int 5876 metag_parse_dsp (char * str) 5877 { 5878 const struct metag_core_option * opt; 5879 int optlen; 5880 5881 optlen = strlen (str); 5882 5883 if (optlen == 0) 5884 { 5885 as_bad (_("missing DSP name `%s'"), str); 5886 return 0; 5887 } 5888 5889 for (opt = metag_dsps; opt->name != NULL; opt++) 5890 if (strncmp (opt->name, str, optlen) == 0) 5891 { 5892 mdsp_opt = opt->value; 5893 return 1; 5894 } 5895 5896 as_bad (_("unknown DSP `%s'"), str); 5897 return 0; 5898 } 5899 5900 struct metag_long_option 5901 { 5902 char * option; /* Substring to match. */ 5903 char * help; /* Help information. */ 5904 int (* func) (char * subopt); /* Function to decode sub-option. */ 5905 char * deprecated; /* If non-null, print this message. */ 5906 }; 5907 5908 struct metag_long_option metag_long_opts[] = 5909 { 5910 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"), 5911 metag_parse_cpu, NULL}, 5912 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"), 5913 metag_parse_fpu, NULL}, 5914 {"mdsp=", N_("<dsp name>\t assemble for DSP architecture <dsp name>"), 5915 metag_parse_dsp, NULL}, 5916 {NULL, NULL, 0, NULL} 5917 }; 5918 5919 int 5920 md_parse_option (int c, char * arg) 5921 { 5922 struct metag_long_option *lopt; 5923 5924 for (lopt = metag_long_opts; lopt->option != NULL; lopt++) 5925 { 5926 /* These options are expected to have an argument. */ 5927 if (c == lopt->option[0] 5928 && arg != NULL 5929 && strncmp (arg, lopt->option + 1, 5930 strlen (lopt->option + 1)) == 0) 5931 { 5932 #if WARN_DEPRECATED 5933 /* If the option is deprecated, tell the user. */ 5934 if (lopt->deprecated != NULL) 5935 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg, 5936 _(lopt->deprecated)); 5937 #endif 5938 5939 /* Call the sup-option parser. */ 5940 return lopt->func (arg + strlen (lopt->option) - 1); 5941 } 5942 } 5943 5944 return 0; 5945 } 5946 5947 void 5948 md_show_usage (FILE * stream) 5949 { 5950 struct metag_long_option *lopt; 5951 5952 fprintf (stream, _(" Meta specific command line options:\n")); 5953 5954 for (lopt = metag_long_opts; lopt->option != NULL; lopt++) 5955 if (lopt->help != NULL) 5956 fprintf (stream, " -%s%s\n", lopt->option, _(lopt->help)); 5957 } 5958 5959 /* The target specific pseudo-ops which we support. */ 5960 const pseudo_typeS md_pseudo_table[] = 5961 { 5962 { "word", cons, 2 }, 5963 { NULL, NULL, 0 } 5964 }; 5965 5966 void 5967 md_begin (void) 5968 { 5969 int c; 5970 5971 for (c = 0; c < 256; c++) 5972 { 5973 if (ISDIGIT (c)) 5974 { 5975 register_chars[c] = c; 5976 /* LOCK0, LOCK1, LOCK2. */ 5977 mnemonic_chars[c] = c; 5978 } 5979 else if (ISLOWER (c)) 5980 { 5981 register_chars[c] = c; 5982 mnemonic_chars[c] = c; 5983 } 5984 else if (ISUPPER (c)) 5985 { 5986 register_chars[c] = c; 5987 mnemonic_chars[c] = c; 5988 } 5989 else if (c == '.') 5990 { 5991 register_chars[c] = c; 5992 } 5993 } 5994 } 5995 5996 /* Parse a split condition code prefix. */ 5997 static const char * 5998 parse_split_condition (const char *line, metag_insn *insn) 5999 { 6000 const char *l = line; 6001 const split_condition *scond; 6002 split_condition entry; 6003 char buf[4]; 6004 6005 memcpy (buf, l, 4); 6006 buf[3] = '\0'; 6007 6008 entry.name = buf; 6009 6010 scond = (const split_condition *) htab_find (scond_htab, &entry); 6011 6012 if (!scond) 6013 return NULL; 6014 6015 insn->scond = scond->code; 6016 6017 return l + strlen (scond->name); 6018 } 6019 6020 /* Parse an instruction prefix - F for float, D for DSP - and associated 6021 flags and condition codes. */ 6022 static const char * 6023 parse_prefix (const char *line, metag_insn *insn) 6024 { 6025 const char *l = line; 6026 6027 l = skip_whitespace (l); 6028 6029 insn->type = INSN_GP; 6030 6031 if (TOLOWER (*l) == FPU_PREFIX_CHAR) 6032 { 6033 if (strncasecmp (l, FFB_INSN, strlen(FFB_INSN))) 6034 { 6035 insn->type = INSN_FPU; 6036 6037 l++; 6038 6039 if (*l == END_OF_INSN) 6040 { 6041 as_bad (_("premature end of floating point prefix")); 6042 return NULL; 6043 } 6044 6045 if (TOLOWER (*l) == FPU_DOUBLE_CHAR) 6046 { 6047 insn->fpu_width = FPU_WIDTH_DOUBLE; 6048 l++; 6049 } 6050 else if (TOLOWER (*l) == FPU_PAIR_CHAR) 6051 { 6052 const char *l2 = l; 6053 6054 /* Check this isn't a split condition beginning with L. */ 6055 l2 = parse_split_condition (l2, insn); 6056 6057 if (l2 && is_whitespace_char (*l2)) 6058 { 6059 l = l2; 6060 } 6061 else 6062 { 6063 insn->fpu_width = FPU_WIDTH_PAIR; 6064 l++; 6065 } 6066 } 6067 else 6068 { 6069 insn->fpu_width = FPU_WIDTH_SINGLE; 6070 } 6071 6072 if (TOLOWER (*l) == FPU_ACTION_ABS_CHAR) 6073 { 6074 insn->fpu_action_flags |= FPU_ACTION_ABS; 6075 l++; 6076 } 6077 else if (TOLOWER (*l) == FPU_ACTION_INV_CHAR) 6078 { 6079 insn->fpu_action_flags |= FPU_ACTION_INV; 6080 l++; 6081 } 6082 6083 if (TOLOWER (*l) == FPU_ACTION_QUIET_CHAR) 6084 { 6085 insn->fpu_action_flags |= FPU_ACTION_QUIET; 6086 l++; 6087 } 6088 6089 if (TOLOWER (*l) == FPU_ACTION_ZERO_CHAR) 6090 { 6091 insn->fpu_action_flags |= FPU_ACTION_ZERO; 6092 l++; 6093 } 6094 6095 if (! is_whitespace_char (*l)) 6096 { 6097 l = parse_split_condition (l, insn); 6098 6099 if (!l) 6100 { 6101 as_bad (_("unknown floating point prefix character")); 6102 return NULL; 6103 } 6104 } 6105 6106 l = skip_space (l); 6107 } 6108 } 6109 else if (TOLOWER (*l) == DSP_PREFIX_CHAR) 6110 { 6111 if (strncasecmp (l, DCACHE_INSN, strlen (DCACHE_INSN)) && 6112 strncasecmp (l, DEFR_INSN, strlen (DEFR_INSN))) 6113 { 6114 const char *ll = l; 6115 insn->type = INSN_DSP; 6116 6117 l++; 6118 6119 insn->dsp_width = DSP_WIDTH_SINGLE; 6120 6121 while (!is_whitespace_char (*l)) 6122 { 6123 /* We have to check for split condition codes first 6124 because they are the longest strings to match, 6125 e.g. if the string contains "LLS" we want it to match 6126 the split condition code "LLS", not the dual unit 6127 character "L". */ 6128 ll = l; 6129 l = parse_split_condition (l, insn); 6130 6131 if (l == NULL) 6132 l = ll; 6133 else 6134 continue; 6135 6136 /* Accept an FPU prefix char which may be used when doing 6137 template MOV with FPU registers. */ 6138 if (TOLOWER(*l) == FPU_PREFIX_CHAR) 6139 { 6140 insn->type = INSN_DSP_FPU; 6141 l++; 6142 continue; 6143 } 6144 6145 if (TOLOWER(*l) == DSP_DUAL_CHAR) 6146 { 6147 insn->dsp_width = DSP_WIDTH_DUAL; 6148 l++; 6149 continue; 6150 } 6151 6152 if (TOLOWER(*l) == DSP_ACTION_QR64_CHAR) 6153 { 6154 insn->dsp_action_flags |= DSP_ACTION_QR64; 6155 l++; 6156 continue; 6157 } 6158 6159 if (TOLOWER(*l) == DSP_ACTION_UMUL_CHAR) 6160 { 6161 insn->dsp_action_flags |= DSP_ACTION_UMUL; 6162 l++; 6163 continue; 6164 } 6165 6166 if (TOLOWER(*l) == DSP_ACTION_ROUND_CHAR) 6167 { 6168 insn->dsp_action_flags |= DSP_ACTION_ROUND; 6169 l++; 6170 continue; 6171 } 6172 6173 if (TOLOWER(*l) == DSP_ACTION_CLAMP9_CHAR) 6174 { 6175 insn->dsp_action_flags |= DSP_ACTION_CLAMP9; 6176 l++; 6177 continue; 6178 } 6179 6180 if (TOLOWER(*l) == DSP_ACTION_CLAMP8_CHAR) 6181 { 6182 insn->dsp_action_flags |= DSP_ACTION_CLAMP8; 6183 l++; 6184 continue; 6185 } 6186 6187 if (TOLOWER(*l) == DSP_ACTION_MOD_CHAR) 6188 { 6189 insn->dsp_action_flags |= DSP_ACTION_MOD; 6190 l++; 6191 continue; 6192 } 6193 6194 if (TOLOWER(*l) == DSP_ACTION_ACC_ZERO_CHAR) 6195 { 6196 insn->dsp_action_flags |= DSP_ACTION_ACC_ZERO; 6197 l++; 6198 continue; 6199 } 6200 6201 if (TOLOWER(*l) == DSP_ACTION_ACC_ADD_CHAR) 6202 { 6203 insn->dsp_action_flags |= DSP_ACTION_ACC_ADD; 6204 l++; 6205 continue; 6206 } 6207 6208 if (TOLOWER(*l) == DSP_ACTION_ACC_SUB_CHAR) 6209 { 6210 insn->dsp_action_flags |= DSP_ACTION_ACC_SUB; 6211 l++; 6212 continue; 6213 } 6214 6215 if (TOLOWER(*l) == DSP_ACTION_OV_CHAR) 6216 { 6217 insn->dsp_action_flags |= DSP_ACTION_OV; 6218 l++; 6219 continue; 6220 } 6221 6222 if (TOLOWER(*l) == DSP_DAOPPAME_8_CHAR) 6223 { 6224 insn->dsp_daoppame_flags |= DSP_DAOPPAME_8; 6225 l++; 6226 continue; 6227 } 6228 6229 if (TOLOWER(*l) == DSP_DAOPPAME_16_CHAR) 6230 { 6231 insn->dsp_daoppame_flags |= DSP_DAOPPAME_16; 6232 l++; 6233 continue; 6234 } 6235 6236 if (TOLOWER(*l) == DSP_DAOPPAME_TEMP_CHAR) 6237 { 6238 insn->dsp_daoppame_flags |= DSP_DAOPPAME_TEMP; 6239 l++; 6240 continue; 6241 } 6242 6243 if (TOLOWER(*l) == DSP_DAOPPAME_HIGH_CHAR) 6244 { 6245 insn->dsp_daoppame_flags |= DSP_DAOPPAME_HIGH; 6246 l++; 6247 continue; 6248 } 6249 6250 as_bad (_("unknown DSP prefix character %c %s"), *l, l); 6251 return NULL; 6252 } 6253 6254 l = skip_space (l); 6255 } 6256 } 6257 6258 return l; 6259 } 6260 6261 /* Return a list of appropriate instruction parsers for MNEMONIC. */ 6262 static insn_templates * 6263 find_insn_templates (const char *mnemonic) 6264 { 6265 insn_template template; 6266 insn_templates entry; 6267 insn_templates *slot; 6268 6269 entry.template = &template; 6270 6271 memcpy ((void *)&entry.template->name, &mnemonic, sizeof (char *)); 6272 6273 slot = (insn_templates *) htab_find (mnemonic_htab, &entry); 6274 6275 if (slot) 6276 return slot; 6277 6278 return NULL; 6279 } 6280 6281 /* Make an uppercase copy of SRC into DST and return DST. */ 6282 static char * 6283 strupper (char * dst, const char *src) 6284 { 6285 size_t i = 0; 6286 6287 while (src[i]) 6288 { 6289 dst[i] = TOUPPER (src[i]); 6290 i++; 6291 } 6292 6293 dst[i] = 0; 6294 6295 return dst; 6296 } 6297 6298 /* Calculate a hash value for a template. */ 6299 static hashval_t 6300 hash_templates (const void *p) 6301 { 6302 insn_templates *tp = (insn_templates *)p; 6303 char buf[MAX_MNEMONIC_LEN]; 6304 6305 strupper (buf, tp->template->name); 6306 6307 return htab_hash_string (buf); 6308 } 6309 6310 /* Check if two templates are equal. */ 6311 static int 6312 eq_templates (const void *a, const void *b) 6313 { 6314 insn_templates *ta = (insn_templates *)a; 6315 insn_templates *tb = (insn_templates *)b; 6316 return strcasecmp (ta->template->name, tb->template->name) == 0; 6317 } 6318 6319 /* Create the hash table required for parsing instructions. */ 6320 static void 6321 create_mnemonic_htab (void) 6322 { 6323 size_t i, num_templates = sizeof(metag_optab)/sizeof(metag_optab[0]); 6324 6325 mnemonic_htab = htab_create_alloc (num_templates, hash_templates, 6326 eq_templates, NULL, xcalloc, free); 6327 6328 for (i = 0; i < num_templates; i++) 6329 { 6330 const insn_template *template = &metag_optab[i]; 6331 insn_templates **slot = NULL; 6332 insn_templates *new_entry; 6333 6334 new_entry = xmalloc (sizeof (insn_templates)); 6335 6336 new_entry->template = template; 6337 new_entry->next = NULL; 6338 6339 slot = (insn_templates **) htab_find_slot (mnemonic_htab, new_entry, 6340 INSERT); 6341 6342 if (*slot) 6343 { 6344 insn_templates *last_entry = *slot; 6345 6346 while (last_entry->next) 6347 last_entry = last_entry->next; 6348 6349 last_entry->next = new_entry; 6350 } 6351 else 6352 { 6353 *slot = new_entry; 6354 } 6355 } 6356 } 6357 6358 /* Calculate a hash value for a register. */ 6359 static hashval_t 6360 hash_regs (const void *p) 6361 { 6362 metag_reg *rp = (metag_reg *)p; 6363 char buf[MAX_REG_LEN]; 6364 6365 strupper (buf, rp->name); 6366 6367 return htab_hash_string (buf); 6368 } 6369 6370 /* Check if two registers are equal. */ 6371 static int 6372 eq_regs (const void *a, const void *b) 6373 { 6374 metag_reg *ra = (metag_reg *)a; 6375 metag_reg *rb = (metag_reg *)b; 6376 return strcasecmp (ra->name, rb->name) == 0; 6377 } 6378 6379 /* Create the hash table required for parsing registers. */ 6380 static void 6381 create_reg_htab (void) 6382 { 6383 size_t i, num_regs = sizeof(metag_regtab)/sizeof(metag_regtab[0]); 6384 6385 reg_htab = htab_create_alloc (num_regs, hash_regs, 6386 eq_regs, NULL, xcalloc, free); 6387 6388 for (i = 0; i < num_regs; i++) 6389 { 6390 const metag_reg *reg = &metag_regtab[i]; 6391 const metag_reg **slot; 6392 6393 slot = (const metag_reg **) htab_find_slot (reg_htab, reg, INSERT); 6394 6395 if (!*slot) 6396 *slot = reg; 6397 } 6398 } 6399 6400 /* Create the hash table required for parsing DSP registers. */ 6401 static void 6402 create_dspreg_htabs (void) 6403 { 6404 size_t i, num_regs = sizeof(metag_dsp_regtab)/sizeof(metag_dsp_regtab[0]); 6405 size_t h; 6406 6407 dsp_reg_htab = htab_create_alloc (num_regs, hash_regs, 6408 eq_regs, NULL, xcalloc, free); 6409 6410 for (i = 0; i < num_regs; i++) 6411 { 6412 const metag_reg *reg = &metag_dsp_regtab[i]; 6413 const metag_reg **slot; 6414 6415 slot = (const metag_reg **) htab_find_slot (dsp_reg_htab, reg, INSERT); 6416 6417 /* Make sure there are no hash table collisions, which would 6418 require chaining entries. */ 6419 BFD_ASSERT (*slot == NULL); 6420 *slot = reg; 6421 } 6422 6423 num_regs = sizeof(metag_dsp_tmpl_regtab[0])/sizeof(metag_dsp_tmpl_regtab[0][0]); 6424 6425 for (h = 0; h < 2; h++) 6426 { 6427 dsp_tmpl_reg_htab[h] = htab_create_alloc (num_regs, hash_regs, 6428 eq_regs, NULL, xcalloc, free); 6429 } 6430 6431 for (h = 0; h < 2; h++) 6432 { 6433 for (i = 0; i < num_regs; i++) 6434 { 6435 const metag_reg *reg = &metag_dsp_tmpl_regtab[h][i]; 6436 const metag_reg **slot; 6437 slot = (const metag_reg **) htab_find_slot (dsp_tmpl_reg_htab[h], 6438 reg, INSERT); 6439 6440 /* Make sure there are no hash table collisions, which would 6441 require chaining entries. */ 6442 BFD_ASSERT (*slot == NULL); 6443 *slot = reg; 6444 } 6445 } 6446 } 6447 6448 /* Calculate a hash value for a split condition code. */ 6449 static hashval_t 6450 hash_scond (const void *p) 6451 { 6452 split_condition *cp = (split_condition *)p; 6453 char buf[4]; 6454 6455 strupper (buf, cp->name); 6456 6457 return htab_hash_string (buf); 6458 } 6459 6460 /* Check if two split condition codes are equal. */ 6461 static int 6462 eq_scond (const void *a, const void *b) 6463 { 6464 split_condition *ra = (split_condition *)a; 6465 split_condition *rb = (split_condition *)b; 6466 6467 return strcasecmp (ra->name, rb->name) == 0; 6468 } 6469 6470 /* Create the hash table required for parsing split condition codes. */ 6471 static void 6472 create_scond_htab (void) 6473 { 6474 size_t i, nentries; 6475 6476 nentries = sizeof (metag_scondtab) / sizeof (metag_scondtab[0]); 6477 6478 scond_htab = htab_create_alloc (nentries, hash_scond, eq_scond, 6479 NULL, xcalloc, free); 6480 for (i = 0; i < nentries; i++) 6481 { 6482 const split_condition *scond = &metag_scondtab[i]; 6483 const split_condition **slot; 6484 6485 slot = (const split_condition **) htab_find_slot (scond_htab, 6486 scond, INSERT); 6487 /* Make sure there are no hash table collisions, which would 6488 require chaining entries. */ 6489 BFD_ASSERT (*slot == NULL); 6490 *slot = scond; 6491 } 6492 } 6493 6494 /* Entry point for instruction parsing. */ 6495 static bfd_boolean 6496 parse_insn (const char *line, metag_insn *insn) 6497 { 6498 char mnemonic[MAX_MNEMONIC_LEN]; 6499 const char *l = line; 6500 size_t mnemonic_len = 0; 6501 insn_templates *templates; 6502 6503 l = skip_space (l); 6504 6505 while (is_mnemonic_char(*l)) 6506 { 6507 l++; 6508 mnemonic_len++; 6509 } 6510 6511 if (mnemonic_len >= MAX_MNEMONIC_LEN) 6512 { 6513 as_bad (_("instruction mnemonic too long: %s"), line); 6514 return FALSE; 6515 } 6516 6517 strncpy(mnemonic, line, mnemonic_len); 6518 6519 mnemonic[mnemonic_len] = '\0'; 6520 6521 templates = find_insn_templates (mnemonic); 6522 6523 if (templates) 6524 { 6525 insn_templates *current_template = templates; 6526 6527 l = skip_space (l); 6528 6529 while (current_template) 6530 { 6531 const insn_template *template = current_template->template; 6532 enum insn_encoding encoding = template->encoding; 6533 insn_parser parser = insn_parsers[encoding]; 6534 6535 current_template = current_template->next; 6536 6537 if (template->insn_type == INSN_GP && 6538 !(template->core_flags & mcpu_opt)) 6539 continue; 6540 6541 if (template->insn_type == INSN_FPU && 6542 !(template->core_flags & mfpu_opt)) 6543 continue; 6544 6545 if (template->insn_type == INSN_DSP && 6546 !(template->core_flags & mdsp_opt)) 6547 continue; 6548 6549 if (template->insn_type == INSN_DSP_FPU && 6550 !((template->core_flags & mdsp_opt) && 6551 (template->core_flags & mfpu_opt))) 6552 continue; 6553 6554 /* DSP instructions always require special decoding */ 6555 if ((insn->type == INSN_DSP && (template->insn_type != INSN_DSP)) || 6556 ((template->insn_type == INSN_DSP) && insn->type != INSN_DSP) || 6557 (insn->type == INSN_DSP_FPU && (template->insn_type != INSN_DSP_FPU)) || 6558 ((template->insn_type == INSN_DSP_FPU) && insn->type != INSN_DSP_FPU)) 6559 continue; 6560 6561 if (parser) 6562 { 6563 const char *end = parser(l, insn, template); 6564 6565 if (end != NULL) 6566 { 6567 if (*end != END_OF_INSN) 6568 as_bad (_("junk at end of line: \"%s\""), line); 6569 else 6570 return TRUE; 6571 } 6572 } 6573 } 6574 6575 as_bad (_("failed to assemble instruction: \"%s\""), line); 6576 } 6577 else 6578 { 6579 if (insn->type == INSN_FPU) 6580 as_bad (_("unknown floating point mnemonic: \"%s\""), mnemonic); 6581 else 6582 as_bad (_("unknown mnemonic: \"%s\""), mnemonic); 6583 } 6584 return FALSE; 6585 } 6586 6587 static void 6588 output_insn (metag_insn *insn) 6589 { 6590 char *output; 6591 6592 output = frag_more (insn->len); 6593 dwarf2_emit_insn (insn->len); 6594 6595 if (insn->reloc_type != BFD_RELOC_UNUSED) 6596 { 6597 fix_new_exp (frag_now, output - frag_now->fr_literal, 6598 insn->reloc_size, &insn->reloc_exp, 6599 insn->reloc_pcrel, insn->reloc_type); 6600 } 6601 6602 md_number_to_chars (output, insn->bits, insn->len); 6603 } 6604 6605 void 6606 md_assemble (char *line) 6607 { 6608 const char *l = line; 6609 metag_insn insn; 6610 6611 memset (&insn, 0, sizeof(insn)); 6612 6613 insn.reloc_type = BFD_RELOC_UNUSED; 6614 insn.reloc_pcrel = 0; 6615 insn.reloc_size = 4; 6616 6617 if (!mnemonic_htab) 6618 { 6619 create_mnemonic_htab (); 6620 create_reg_htab (); 6621 create_dspreg_htabs (); 6622 create_scond_htab (); 6623 } 6624 6625 l = parse_prefix (l, &insn); 6626 6627 if (l == NULL) 6628 return; 6629 6630 if (insn.type == INSN_DSP && 6631 !mdsp_opt) 6632 { 6633 as_bad (_("cannot assemble DSP instruction, DSP option not set: %s"), 6634 line); 6635 return; 6636 } 6637 else if (insn.type == INSN_FPU && 6638 !mfpu_opt) 6639 { 6640 as_bad (_("cannot assemble FPU instruction, FPU option not set: %s"), 6641 line); 6642 return; 6643 } 6644 6645 if (!parse_insn (l, &insn)) 6646 return; 6647 6648 output_insn (&insn); 6649 } 6650 6651 void 6652 md_operand (expressionS * expressionP) 6653 { 6654 if (* input_line_pointer == IMM_CHAR) 6655 { 6656 input_line_pointer ++; 6657 expression (expressionP); 6658 } 6659 } 6660 6661 valueT 6662 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size) 6663 { 6664 return size; 6665 } 6666 6667 symbolS * 6668 md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 6669 { 6670 return NULL; 6671 } 6672 6673 /* Functions concerning relocs. */ 6674 6675 /* The location from which a PC relative jump should be calculated, 6676 given a PC relative reloc. */ 6677 6678 long 6679 md_pcrel_from_section (fixS * fixP, segT sec) 6680 { 6681 if ((fixP->fx_addsy != (symbolS *) NULL 6682 && (! S_IS_DEFINED (fixP->fx_addsy) 6683 || S_GET_SEGMENT (fixP->fx_addsy) != sec)) 6684 || metag_force_relocation (fixP)) 6685 { 6686 /* The symbol is undefined (or is defined but not in this section). 6687 Let the linker figure it out. */ 6688 return 0; 6689 } 6690 6691 return fixP->fx_frag->fr_address + fixP->fx_where; 6692 } 6693 6694 /* Write a value out to the object file, using the appropriate endianness. */ 6695 6696 void 6697 md_number_to_chars (char * buf, valueT val, int n) 6698 { 6699 number_to_chars_littleendian (buf, val, n); 6700 } 6701 6702 /* Turn a string in input_line_pointer into a floating point constant of type 6703 type, and store the appropriate bytes in *litP. The number of LITTLENUMS 6704 emitted is stored in *sizeP . An error message is returned, or NULL on OK. 6705 */ 6706 6707 /* Equal to MAX_PRECISION in atof-ieee.c */ 6708 #define MAX_LITTLENUMS 6 6709 6710 char * 6711 md_atof (int type, char * litP, int * sizeP) 6712 { 6713 int i; 6714 int prec; 6715 LITTLENUM_TYPE words [MAX_LITTLENUMS]; 6716 char * t; 6717 6718 switch (type) 6719 { 6720 case 'f': 6721 case 'F': 6722 case 's': 6723 case 'S': 6724 prec = 2; 6725 break; 6726 6727 case 'd': 6728 case 'D': 6729 case 'r': 6730 case 'R': 6731 prec = 4; 6732 break; 6733 6734 /* FIXME: Some targets allow other format chars for bigger sizes here. */ 6735 6736 default: 6737 * sizeP = 0; 6738 return _("Bad call to md_atof()"); 6739 } 6740 6741 t = atof_ieee (input_line_pointer, type, words); 6742 if (t) 6743 input_line_pointer = t; 6744 * sizeP = prec * sizeof (LITTLENUM_TYPE); 6745 6746 for (i = 0; i < prec; i++) 6747 { 6748 md_number_to_chars (litP, (valueT) words[i], 6749 sizeof (LITTLENUM_TYPE)); 6750 litP += sizeof (LITTLENUM_TYPE); 6751 } 6752 6753 return 0; 6754 } 6755 6756 /* If this function returns non-zero, it prevents the relocation 6757 against symbol(s) in the FIXP from being replaced with relocations 6758 against section symbols, and guarantees that a relocation will be 6759 emitted even when the value can be resolved locally. */ 6760 6761 int 6762 metag_force_relocation (fixS * fix) 6763 { 6764 switch (fix->fx_r_type) 6765 { 6766 case BFD_RELOC_METAG_RELBRANCH_PLT: 6767 case BFD_RELOC_METAG_TLS_LE: 6768 case BFD_RELOC_METAG_TLS_IE: 6769 case BFD_RELOC_METAG_TLS_LDO: 6770 case BFD_RELOC_METAG_TLS_LDM: 6771 case BFD_RELOC_METAG_TLS_GD: 6772 return 1; 6773 default: 6774 ; 6775 } 6776 6777 return generic_force_reloc (fix); 6778 } 6779 6780 bfd_boolean 6781 metag_fix_adjustable (fixS * fixP) 6782 { 6783 if (fixP->fx_addsy == NULL) 6784 return 1; 6785 6786 /* Prevent all adjustments to global symbols. */ 6787 if (S_IS_EXTERNAL (fixP->fx_addsy)) 6788 return 0; 6789 if (S_IS_WEAK (fixP->fx_addsy)) 6790 return 0; 6791 6792 if (fixP->fx_r_type == BFD_RELOC_METAG_HI16_GOTOFF || 6793 fixP->fx_r_type == BFD_RELOC_METAG_LO16_GOTOFF || 6794 fixP->fx_r_type == BFD_RELOC_METAG_GETSET_GOTOFF || 6795 fixP->fx_r_type == BFD_RELOC_METAG_GETSET_GOT || 6796 fixP->fx_r_type == BFD_RELOC_METAG_HI16_GOTPC || 6797 fixP->fx_r_type == BFD_RELOC_METAG_LO16_GOTPC || 6798 fixP->fx_r_type == BFD_RELOC_METAG_HI16_PLT || 6799 fixP->fx_r_type == BFD_RELOC_METAG_LO16_PLT || 6800 fixP->fx_r_type == BFD_RELOC_METAG_RELBRANCH_PLT) 6801 return 0; 6802 6803 /* We need the symbol name for the VTABLE entries. */ 6804 if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT 6805 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) 6806 return 0; 6807 6808 return 1; 6809 } 6810 6811 /* Return an initial guess of the length by which a fragment must grow to 6812 hold a branch to reach its destination. 6813 Also updates fr_type/fr_subtype as necessary. 6814 6815 Called just before doing relaxation. 6816 Any symbol that is now undefined will not become defined. 6817 The guess for fr_var is ACTUALLY the growth beyond fr_fix. 6818 Whatever we do to grow fr_fix or fr_var contributes to our returned value. 6819 Although it may not be explicit in the frag, pretend fr_var starts with a 6820 0 value. */ 6821 6822 int 6823 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, 6824 segT segment ATTRIBUTE_UNUSED) 6825 { 6826 /* No assembler relaxation is defined (or necessary) for this port. */ 6827 abort (); 6828 } 6829 6830 /* *fragP has been relaxed to its final size, and now needs to have 6831 the bytes inside it modified to conform to the new size. 6832 6833 Called after relaxation is finished. 6834 fragP->fr_type == rs_machine_dependent. 6835 fragP->fr_subtype is the subtype of what the address relaxed to. */ 6836 6837 void 6838 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED, 6839 fragS * fragP ATTRIBUTE_UNUSED) 6840 { 6841 /* No assembler relaxation is defined (or necessary) for this port. */ 6842 abort (); 6843 } 6844 6845 /* This is called from HANDLE_ALIGN in tc-metag.h. */ 6846 6847 void 6848 metag_handle_align (fragS * fragP) 6849 { 6850 static char const noop[4] = { 0xfe, 0xff, 0xff, 0xa0 }; 6851 int bytes, fix; 6852 char *p; 6853 6854 if (fragP->fr_type != rs_align_code) 6855 return; 6856 6857 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix; 6858 p = fragP->fr_literal + fragP->fr_fix; 6859 fix = 0; 6860 6861 if (bytes & 3) 6862 { 6863 fix = bytes & 3; 6864 memset (p, 0, fix); 6865 p += fix; 6866 bytes -= fix; 6867 } 6868 6869 while (bytes >= 4) 6870 { 6871 memcpy (p, noop, 4); 6872 p += 4; 6873 bytes -= 4; 6874 fix += 4; 6875 } 6876 6877 fragP->fr_fix += fix; 6878 fragP->fr_var = 4; 6879 } 6880 6881 static char * 6882 metag_end_of_match (char * cont, char * what) 6883 { 6884 int len = strlen (what); 6885 6886 if (strncasecmp (cont, what, strlen (what)) == 0 6887 && ! is_part_of_name (cont[len])) 6888 return cont + len; 6889 6890 return NULL; 6891 } 6892 6893 int 6894 metag_parse_name (char const * name, expressionS * exprP, enum expr_mode mode, 6895 char * nextcharP) 6896 { 6897 char *next = input_line_pointer; 6898 char *next_end; 6899 int reloc_type; 6900 operatorT op_type; 6901 segT segment; 6902 6903 exprP->X_op_symbol = NULL; 6904 exprP->X_md = BFD_RELOC_UNUSED; 6905 6906 if (strcmp (name, GOT_NAME) == 0) 6907 { 6908 if (! GOT_symbol) 6909 GOT_symbol = symbol_find_or_make (name); 6910 6911 exprP->X_add_symbol = GOT_symbol; 6912 no_suffix: 6913 /* If we have an absolute symbol or a 6914 reg, then we know its value now. */ 6915 segment = S_GET_SEGMENT (exprP->X_add_symbol); 6916 if (mode != expr_defer && segment == absolute_section) 6917 { 6918 exprP->X_op = O_constant; 6919 exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol); 6920 exprP->X_add_symbol = NULL; 6921 } 6922 else if (mode != expr_defer && segment == reg_section) 6923 { 6924 exprP->X_op = O_register; 6925 exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol); 6926 exprP->X_add_symbol = NULL; 6927 } 6928 else 6929 { 6930 exprP->X_op = O_symbol; 6931 exprP->X_add_number = 0; 6932 } 6933 6934 return 1; 6935 } 6936 6937 exprP->X_add_symbol = symbol_find_or_make (name); 6938 6939 if (*nextcharP != '@') 6940 goto no_suffix; 6941 else if ((next_end = metag_end_of_match (next + 1, "GOTOFF"))) 6942 { 6943 reloc_type = BFD_RELOC_METAG_GOTOFF; 6944 op_type = O_PIC_reloc; 6945 } 6946 else if ((next_end = metag_end_of_match (next + 1, "GOT"))) 6947 { 6948 reloc_type = BFD_RELOC_METAG_GETSET_GOT; 6949 op_type = O_PIC_reloc; 6950 } 6951 else if ((next_end = metag_end_of_match (next + 1, "PLT"))) 6952 { 6953 reloc_type = BFD_RELOC_METAG_PLT; 6954 op_type = O_PIC_reloc; 6955 } 6956 else if ((next_end = metag_end_of_match (next + 1, "TLSGD"))) 6957 { 6958 reloc_type = BFD_RELOC_METAG_TLS_GD; 6959 op_type = O_PIC_reloc; 6960 } 6961 else if ((next_end = metag_end_of_match (next + 1, "TLSLDM"))) 6962 { 6963 reloc_type = BFD_RELOC_METAG_TLS_LDM; 6964 op_type = O_PIC_reloc; 6965 } 6966 else if ((next_end = metag_end_of_match (next + 1, "TLSLDO"))) 6967 { 6968 reloc_type = BFD_RELOC_METAG_TLS_LDO; 6969 op_type = O_PIC_reloc; 6970 } 6971 else if ((next_end = metag_end_of_match (next + 1, "TLSIE"))) 6972 { 6973 reloc_type = BFD_RELOC_METAG_TLS_IE; 6974 op_type = O_PIC_reloc; 6975 } 6976 else if ((next_end = metag_end_of_match (next + 1, "TLSIENONPIC"))) 6977 { 6978 reloc_type = BFD_RELOC_METAG_TLS_IENONPIC; 6979 op_type = O_PIC_reloc; /* FIXME: is this correct? */ 6980 } 6981 else if ((next_end = metag_end_of_match (next + 1, "TLSLE"))) 6982 { 6983 reloc_type = BFD_RELOC_METAG_TLS_LE; 6984 op_type = O_PIC_reloc; 6985 } 6986 else 6987 goto no_suffix; 6988 6989 *input_line_pointer = *nextcharP; 6990 input_line_pointer = next_end; 6991 *nextcharP = *input_line_pointer; 6992 *input_line_pointer = '\0'; 6993 6994 exprP->X_op = op_type; 6995 exprP->X_add_number = 0; 6996 exprP->X_md = reloc_type; 6997 6998 return 1; 6999 } 7000 7001 /* If while processing a fixup, a reloc really needs to be created 7002 then it is done here. */ 7003 7004 arelent * 7005 tc_gen_reloc (seg, fixp) 7006 asection *seg ATTRIBUTE_UNUSED; 7007 fixS *fixp; 7008 { 7009 arelent *reloc; 7010 7011 reloc = (arelent *) xmalloc (sizeof (arelent)); 7012 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); 7013 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 7014 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 7015 7016 reloc->addend = fixp->fx_offset; 7017 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 7018 7019 if (reloc->howto == (reloc_howto_type *) NULL) 7020 { 7021 as_bad_where (fixp->fx_file, fixp->fx_line, 7022 /* xgettext:c-format. */ 7023 _("reloc %d not supported by object file format"), 7024 (int) fixp->fx_r_type); 7025 7026 xfree (reloc); 7027 7028 return NULL; 7029 } 7030 7031 return reloc; 7032 } 7033 7034 static unsigned int 7035 md_chars_to_number (char *val, int n) 7036 { 7037 int retval; 7038 unsigned char * where = (unsigned char *) val; 7039 7040 for (retval = 0; n--;) 7041 { 7042 retval <<= 8; 7043 retval |= where[n]; 7044 } 7045 return retval; 7046 } 7047 7048 void 7049 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) 7050 { 7051 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; 7052 int value = (int)*valP; 7053 7054 switch (fixP->fx_r_type) 7055 { 7056 case BFD_RELOC_METAG_TLS_GD: 7057 case BFD_RELOC_METAG_TLS_LE_HI16: 7058 case BFD_RELOC_METAG_TLS_LE_LO16: 7059 case BFD_RELOC_METAG_TLS_IE: 7060 case BFD_RELOC_METAG_TLS_IENONPIC_HI16: 7061 case BFD_RELOC_METAG_TLS_IENONPIC_LO16: 7062 case BFD_RELOC_METAG_TLS_LDM: 7063 case BFD_RELOC_METAG_TLS_LDO_HI16: 7064 case BFD_RELOC_METAG_TLS_LDO_LO16: 7065 S_SET_THREAD_LOCAL (fixP->fx_addsy); 7066 /* Fall through */ 7067 7068 case BFD_RELOC_METAG_HIADDR16: 7069 case BFD_RELOC_METAG_LOADDR16: 7070 case BFD_RELOC_VTABLE_INHERIT: 7071 case BFD_RELOC_VTABLE_ENTRY: 7072 fixP->fx_done = FALSE; 7073 break; 7074 7075 case BFD_RELOC_METAG_REL8: 7076 if (!within_unsigned_range (value, IMM8_BITS)) 7077 { 7078 as_bad_where (fixP->fx_file, fixP->fx_line, 7079 "rel8 out of range %d", value); 7080 } 7081 else 7082 { 7083 unsigned int newval; 7084 newval = md_chars_to_number (buf, 4); 7085 newval = (newval & 0xffffc03f) | ((value & IMM8_MASK) << 6); 7086 md_number_to_chars (buf, newval, 4); 7087 } 7088 break; 7089 case BFD_RELOC_METAG_REL16: 7090 if (!within_unsigned_range (value, IMM16_BITS)) 7091 { 7092 as_bad_where (fixP->fx_file, fixP->fx_line, 7093 "rel16 out of range %d", value); 7094 } 7095 else 7096 { 7097 unsigned int newval; 7098 newval = md_chars_to_number (buf, 4); 7099 newval = (newval & 0xfff80007) | ((value & IMM16_MASK) << 3); 7100 md_number_to_chars (buf, newval, 4); 7101 } 7102 break; 7103 7104 case BFD_RELOC_8: 7105 md_number_to_chars (buf, value, 1); 7106 break; 7107 case BFD_RELOC_16: 7108 md_number_to_chars (buf, value, 2); 7109 break; 7110 case BFD_RELOC_32: 7111 md_number_to_chars (buf, value, 4); 7112 break; 7113 case BFD_RELOC_64: 7114 md_number_to_chars (buf, value, 8); 7115 7116 case BFD_RELOC_METAG_RELBRANCH: 7117 if (!value) 7118 break; 7119 7120 value = value / 4; 7121 7122 if (!within_signed_range (value, IMM19_BITS)) 7123 { 7124 as_bad_where (fixP->fx_file, fixP->fx_line, 7125 "relbranch out of range %d", value); 7126 } 7127 else 7128 { 7129 unsigned int newval; 7130 newval = md_chars_to_number (buf, 4); 7131 newval = (newval & 0xff00001f) | ((value & IMM19_MASK) << 5); 7132 md_number_to_chars (buf, newval, 4); 7133 } 7134 break; 7135 default: 7136 break; 7137 } 7138 7139 if (fixP->fx_addsy == NULL) 7140 fixP->fx_done = TRUE; 7141 } 7142