1 /* tc-i860.c -- Assembler for the Intel i860 architecture. 2 Copyright (C) 1989-2014 Free Software Foundation, Inc. 3 4 Brought back from the dead and completely reworked 5 by Jason Eckhardt <jle (at) cygnus.com>. 6 7 This file is part of GAS, the GNU Assembler. 8 9 GAS is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3, or (at your option) 12 any later version. 13 14 GAS is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License along 20 with GAS; see the file COPYING. If not, write to the Free Software 21 Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 22 23 #include "as.h" 24 #include "safe-ctype.h" 25 #include "subsegs.h" 26 #include "opcode/i860.h" 27 #include "elf/i860.h" 28 29 30 /* The opcode hash table. */ 31 static struct hash_control *op_hash = NULL; 32 33 /* These characters always start a comment. */ 34 const char comment_chars[] = "#!/"; 35 36 /* These characters start a comment at the beginning of a line. */ 37 const char line_comment_chars[] = "#/"; 38 39 const char line_separator_chars[] = ";"; 40 41 /* Characters that can be used to separate the mantissa from the exponent 42 in floating point numbers. */ 43 const char EXP_CHARS[] = "eE"; 44 45 /* Characters that indicate this number is a floating point constant. 46 As in 0f12.456 or 0d1.2345e12. */ 47 const char FLT_CHARS[] = "rRsSfFdDxXpP"; 48 49 /* Register prefix (depends on syntax). */ 50 static char reg_prefix; 51 52 #define MAX_FIXUPS 2 53 54 struct i860_it 55 { 56 char *error; 57 unsigned long opcode; 58 enum expand_type expand; 59 struct i860_fi 60 { 61 expressionS exp; 62 bfd_reloc_code_real_type reloc; 63 int pcrel; 64 valueT fup; 65 } fi[MAX_FIXUPS]; 66 } the_insn; 67 68 /* The current fixup count. */ 69 static int fc; 70 71 static char *expr_end; 72 73 /* Indicates error if a pseudo operation was expanded after a branch. */ 74 static char last_expand; 75 76 /* If true, then warn if any pseudo operations were expanded. */ 77 static int target_warn_expand = 0; 78 79 /* If true, then XP support is enabled. */ 80 static int target_xp = 0; 81 82 /* If true, then Intel syntax is enabled (default to AT&T/SVR4 syntax). */ 83 static int target_intel_syntax = 0; 84 85 86 /* Prototypes. */ 87 static void i860_process_insn (char *); 88 static void s_dual (int); 89 static void s_enddual (int); 90 static void s_atmp (int); 91 static void s_align_wrapper (int); 92 static int i860_get_expression (char *); 93 static bfd_reloc_code_real_type obtain_reloc_for_imm16 (fixS *, long *); 94 #ifdef DEBUG_I860 95 static void print_insn (struct i860_it *); 96 #endif 97 98 const pseudo_typeS md_pseudo_table[] = 99 { 100 {"align", s_align_wrapper, 0}, 101 {"dual", s_dual, 0}, 102 {"enddual", s_enddual, 0}, 103 {"atmp", s_atmp, 0}, 104 {NULL, 0, 0}, 105 }; 106 107 /* Dual-instruction mode handling. */ 108 enum dual 109 { 110 DUAL_OFF = 0, DUAL_ON, DUAL_DDOT, DUAL_ONDDOT, 111 }; 112 static enum dual dual_mode = DUAL_OFF; 113 114 /* Handle ".dual" directive. */ 115 static void 116 s_dual (int ignore ATTRIBUTE_UNUSED) 117 { 118 if (target_intel_syntax) 119 dual_mode = DUAL_ON; 120 else 121 as_bad (_("Directive .dual available only with -mintel-syntax option")); 122 } 123 124 /* Handle ".enddual" directive. */ 125 static void 126 s_enddual (int ignore ATTRIBUTE_UNUSED) 127 { 128 if (target_intel_syntax) 129 dual_mode = DUAL_OFF; 130 else 131 as_bad (_("Directive .enddual available only with -mintel-syntax option")); 132 } 133 134 /* Temporary register used when expanding assembler pseudo operations. */ 135 static int atmp = 31; 136 137 static void 138 s_atmp (int ignore ATTRIBUTE_UNUSED) 139 { 140 int temp; 141 142 if (! target_intel_syntax) 143 { 144 as_bad (_("Directive .atmp available only with -mintel-syntax option")); 145 demand_empty_rest_of_line (); 146 return; 147 } 148 149 if (strncmp (input_line_pointer, "sp", 2) == 0) 150 { 151 input_line_pointer += 2; 152 atmp = 2; 153 } 154 else if (strncmp (input_line_pointer, "fp", 2) == 0) 155 { 156 input_line_pointer += 2; 157 atmp = 3; 158 } 159 else if (strncmp (input_line_pointer, "r", 1) == 0) 160 { 161 input_line_pointer += 1; 162 temp = get_absolute_expression (); 163 if (temp >= 0 && temp <= 31) 164 atmp = temp; 165 else 166 as_bad (_("Unknown temporary pseudo register")); 167 } 168 else 169 { 170 as_bad (_("Unknown temporary pseudo register")); 171 } 172 demand_empty_rest_of_line (); 173 } 174 175 /* Handle ".align" directive depending on syntax mode. 176 AT&T/SVR4 syntax uses the standard align directive. However, 177 the Intel syntax additionally allows keywords for the alignment 178 parameter: ".align type", where type is one of {.short, .long, 179 .quad, .single, .double} representing alignments of 2, 4, 180 16, 4, and 8, respectively. */ 181 static void 182 s_align_wrapper (int arg) 183 { 184 char *parm = input_line_pointer; 185 186 if (target_intel_syntax) 187 { 188 /* Replace a keyword with the equivalent integer so the 189 standard align routine can parse the directive. */ 190 if (strncmp (parm, ".short", 6) == 0) 191 strncpy (parm, " 2", 6); 192 else if (strncmp (parm, ".long", 5) == 0) 193 strncpy (parm, " 4", 5); 194 else if (strncmp (parm, ".quad", 5) == 0) 195 strncpy (parm, " 16", 5); 196 else if (strncmp (parm, ".single", 7) == 0) 197 strncpy (parm, " 4", 7); 198 else if (strncmp (parm, ".double", 7) == 0) 199 strncpy (parm, " 8", 7); 200 201 while (*input_line_pointer == ' ') 202 ++input_line_pointer; 203 } 204 205 s_align_bytes (arg); 206 } 207 208 /* This function is called once, at assembler startup time. It should 209 set up all the tables and data structures that the MD part of the 210 assembler will need. */ 211 void 212 md_begin (void) 213 { 214 const char *retval = NULL; 215 int lose = 0; 216 unsigned int i = 0; 217 218 op_hash = hash_new (); 219 220 while (i860_opcodes[i].name != NULL) 221 { 222 const char *name = i860_opcodes[i].name; 223 retval = hash_insert (op_hash, name, (void *) &i860_opcodes[i]); 224 if (retval != NULL) 225 { 226 fprintf (stderr, _("internal error: can't hash `%s': %s\n"), 227 i860_opcodes[i].name, retval); 228 lose = 1; 229 } 230 do 231 { 232 if (i860_opcodes[i].match & i860_opcodes[i].lose) 233 { 234 fprintf (stderr, 235 _("internal error: losing opcode: `%s' \"%s\"\n"), 236 i860_opcodes[i].name, i860_opcodes[i].args); 237 lose = 1; 238 } 239 ++i; 240 } 241 while (i860_opcodes[i].name != NULL 242 && strcmp (i860_opcodes[i].name, name) == 0); 243 } 244 245 if (lose) 246 as_fatal (_("Defective assembler. No assembly attempted.")); 247 248 /* Set the register prefix for either Intel or AT&T/SVR4 syntax. */ 249 reg_prefix = target_intel_syntax ? 0 : '%'; 250 } 251 252 /* This is the core of the machine-dependent assembler. STR points to a 253 machine dependent instruction. This function emits the frags/bytes 254 it assembles to. */ 255 void 256 md_assemble (char *str) 257 { 258 char *destp; 259 int num_opcodes = 1; 260 int i; 261 struct i860_it pseudo[3]; 262 263 gas_assert (str); 264 fc = 0; 265 266 /* Assemble the instruction. */ 267 i860_process_insn (str); 268 269 /* Check for expandable flag to produce pseudo-instructions. This 270 is an undesirable feature that should be avoided. */ 271 if (the_insn.expand != 0 && the_insn.expand != XP_ONLY 272 && ! (the_insn.fi[0].fup & (OP_SEL_HA | OP_SEL_H | OP_SEL_L | OP_SEL_GOT 273 | OP_SEL_GOTOFF | OP_SEL_PLT))) 274 { 275 for (i = 0; i < 3; i++) 276 pseudo[i] = the_insn; 277 278 fc = 1; 279 switch (the_insn.expand) 280 { 281 282 case E_DELAY: 283 num_opcodes = 1; 284 break; 285 286 case E_MOV: 287 if (the_insn.fi[0].exp.X_add_symbol == NULL 288 && the_insn.fi[0].exp.X_op_symbol == NULL 289 && (the_insn.fi[0].exp.X_add_number < (1 << 15) 290 && the_insn.fi[0].exp.X_add_number >= -(1 << 15))) 291 break; 292 293 /* Emit "or l%const,r0,ireg_dest". */ 294 pseudo[0].opcode = (the_insn.opcode & 0x001f0000) | 0xe4000000; 295 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_L); 296 297 /* Emit "orh h%const,ireg_dest,ireg_dest". */ 298 pseudo[1].opcode = (the_insn.opcode & 0x03ffffff) | 0xec000000 299 | ((the_insn.opcode & 0x001f0000) << 5); 300 pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_H); 301 302 num_opcodes = 2; 303 break; 304 305 case E_ADDR: 306 if (the_insn.fi[0].exp.X_add_symbol == NULL 307 && the_insn.fi[0].exp.X_op_symbol == NULL 308 && (the_insn.fi[0].exp.X_add_number < (1 << 15) 309 && the_insn.fi[0].exp.X_add_number >= -(1 << 15))) 310 break; 311 312 /* Emit "orh ha%addr_expr,ireg_src2,r31". */ 313 pseudo[0].opcode = 0xec000000 | (the_insn.opcode & 0x03e00000) 314 | (atmp << 16); 315 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_HA); 316 317 /* Emit "l%addr_expr(r31),ireg_dest". We pick up the fixup 318 information from the original instruction. */ 319 pseudo[1].opcode = (the_insn.opcode & ~0x03e00000) | (atmp << 21); 320 pseudo[1].fi[0].fup = the_insn.fi[0].fup | OP_SEL_L; 321 322 num_opcodes = 2; 323 break; 324 325 case E_U32: 326 if (the_insn.fi[0].exp.X_add_symbol == NULL 327 && the_insn.fi[0].exp.X_op_symbol == NULL 328 && (the_insn.fi[0].exp.X_add_number < (1 << 16) 329 && the_insn.fi[0].exp.X_add_number >= 0)) 330 break; 331 332 /* Emit "$(opcode)h h%const,ireg_src2,r31". */ 333 pseudo[0].opcode = (the_insn.opcode & 0xf3e0ffff) | 0x0c000000 334 | (atmp << 16); 335 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H); 336 337 /* Emit "$(opcode) l%const,r31,ireg_dest". */ 338 pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000 339 | (atmp << 21); 340 pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L); 341 342 num_opcodes = 2; 343 break; 344 345 case E_AND: 346 if (the_insn.fi[0].exp.X_add_symbol == NULL 347 && the_insn.fi[0].exp.X_op_symbol == NULL 348 && (the_insn.fi[0].exp.X_add_number < (1 << 16) 349 && the_insn.fi[0].exp.X_add_number >= 0)) 350 break; 351 352 /* Emit "andnot h%const,ireg_src2,r31". */ 353 pseudo[0].opcode = (the_insn.opcode & 0x03e0ffff) | 0xd4000000 354 | (atmp << 16); 355 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H); 356 pseudo[0].fi[0].exp.X_add_number = 357 -1 - the_insn.fi[0].exp.X_add_number; 358 359 /* Emit "andnot l%const,r31,ireg_dest". */ 360 pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000 361 | (atmp << 21); 362 pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L); 363 pseudo[1].fi[0].exp.X_add_number = 364 -1 - the_insn.fi[0].exp.X_add_number; 365 366 num_opcodes = 2; 367 break; 368 369 case E_S32: 370 if (the_insn.fi[0].exp.X_add_symbol == NULL 371 && the_insn.fi[0].exp.X_op_symbol == NULL 372 && (the_insn.fi[0].exp.X_add_number < (1 << 15) 373 && the_insn.fi[0].exp.X_add_number >= -(1 << 15))) 374 break; 375 376 /* Emit "orh h%const,r0,r31". */ 377 pseudo[0].opcode = 0xec000000 | (atmp << 16); 378 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H); 379 380 /* Emit "or l%const,r31,r31". */ 381 pseudo[1].opcode = 0xe4000000 | (atmp << 21) | (atmp << 16); 382 pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L); 383 384 /* Emit "r31,ireg_src2,ireg_dest". */ 385 pseudo[2].opcode = (the_insn.opcode & ~0x0400ffff) | (atmp << 11); 386 pseudo[2].fi[0].fup = OP_IMM_S16; 387 388 num_opcodes = 3; 389 break; 390 391 default: 392 as_fatal (_("failed sanity check.")); 393 } 394 395 the_insn = pseudo[0]; 396 397 /* Warn if an opcode is expanded after a delayed branch. */ 398 if (num_opcodes > 1 && last_expand == 1) 399 as_warn (_("Expanded opcode after delayed branch: `%s'"), str); 400 401 /* Warn if an opcode is expanded in dual mode. */ 402 if (num_opcodes > 1 && dual_mode != DUAL_OFF) 403 as_warn (_("Expanded opcode in dual mode: `%s'"), str); 404 405 /* Notify if any expansions happen. */ 406 if (target_warn_expand && num_opcodes > 1) 407 as_warn (_("An instruction was expanded (%s)"), str); 408 } 409 410 dwarf2_emit_insn (0); 411 i = 0; 412 do 413 { 414 int tmp; 415 416 /* Output the opcode. Note that the i860 always reads instructions 417 as little-endian data. */ 418 destp = frag_more (4); 419 number_to_chars_littleendian (destp, the_insn.opcode, 4); 420 421 /* Check for expanded opcode after branch or in dual mode. */ 422 last_expand = the_insn.fi[0].pcrel; 423 424 /* Output the symbol-dependent stuff. Only btne and bte will ever 425 loop more than once here, since only they (possibly) have more 426 than one fixup. */ 427 for (tmp = 0; tmp < fc; tmp++) 428 { 429 if (the_insn.fi[tmp].fup != OP_NONE) 430 { 431 fixS *fix; 432 fix = fix_new_exp (frag_now, 433 destp - frag_now->fr_literal, 434 4, 435 &the_insn.fi[tmp].exp, 436 the_insn.fi[tmp].pcrel, 437 the_insn.fi[tmp].reloc); 438 439 /* Despite the odd name, this is a scratch field. We use 440 it to encode operand type information. */ 441 fix->fx_addnumber = the_insn.fi[tmp].fup; 442 } 443 } 444 the_insn = pseudo[++i]; 445 } 446 while (--num_opcodes > 0); 447 448 } 449 450 /* Assemble the instruction pointed to by STR. */ 451 static void 452 i860_process_insn (char *str) 453 { 454 char *s; 455 const char *args; 456 char c; 457 struct i860_opcode *insn; 458 char *args_start; 459 unsigned long opcode; 460 unsigned int mask; 461 int match = 0; 462 int comma = 0; 463 464 #if 1 /* For compiler warnings. */ 465 args = 0; 466 insn = 0; 467 args_start = 0; 468 opcode = 0; 469 #endif 470 471 for (s = str; ISLOWER (*s) || *s == '.' || *s == '3' 472 || *s == '2' || *s == '1'; ++s) 473 ; 474 475 switch (*s) 476 { 477 case '\0': 478 break; 479 480 case ',': 481 comma = 1; 482 483 /*FALLTHROUGH*/ 484 485 case ' ': 486 *s++ = '\0'; 487 break; 488 489 default: 490 as_fatal (_("Unknown opcode: `%s'"), str); 491 } 492 493 /* Check for dual mode ("d.") opcode prefix. */ 494 if (strncmp (str, "d.", 2) == 0) 495 { 496 if (dual_mode == DUAL_ON) 497 dual_mode = DUAL_ONDDOT; 498 else 499 dual_mode = DUAL_DDOT; 500 str += 2; 501 } 502 503 if ((insn = (struct i860_opcode *) hash_find (op_hash, str)) == NULL) 504 { 505 if (dual_mode == DUAL_DDOT || dual_mode == DUAL_ONDDOT) 506 str -= 2; 507 as_bad (_("Unknown opcode: `%s'"), str); 508 return; 509 } 510 511 if (comma) 512 *--s = ','; 513 514 args_start = s; 515 for (;;) 516 { 517 int t; 518 opcode = insn->match; 519 memset (&the_insn, '\0', sizeof (the_insn)); 520 fc = 0; 521 for (t = 0; t < MAX_FIXUPS; t++) 522 { 523 the_insn.fi[t].reloc = BFD_RELOC_NONE; 524 the_insn.fi[t].pcrel = 0; 525 the_insn.fi[t].fup = OP_NONE; 526 } 527 528 /* Build the opcode, checking as we go that the operands match. */ 529 for (args = insn->args; ; ++args) 530 { 531 if (fc > MAX_FIXUPS) 532 abort (); 533 534 switch (*args) 535 { 536 537 /* End of args. */ 538 case '\0': 539 if (*s == '\0') 540 match = 1; 541 break; 542 543 /* These must match exactly. */ 544 case '+': 545 case '(': 546 case ')': 547 case ',': 548 case ' ': 549 if (*s++ == *args) 550 continue; 551 break; 552 553 /* Must be at least one digit. */ 554 case '#': 555 if (ISDIGIT (*s++)) 556 { 557 while (ISDIGIT (*s)) 558 ++s; 559 continue; 560 } 561 break; 562 563 /* Next operand must be a register. */ 564 case '1': 565 case '2': 566 case 'd': 567 /* Check for register prefix if necessary. */ 568 if (reg_prefix && *s != reg_prefix) 569 goto error; 570 else if (reg_prefix) 571 s++; 572 573 switch (*s) 574 { 575 /* Frame pointer. */ 576 case 'f': 577 s++; 578 if (*s++ == 'p') 579 { 580 mask = 0x3; 581 break; 582 } 583 goto error; 584 585 /* Stack pointer. */ 586 case 's': 587 s++; 588 if (*s++ == 'p') 589 { 590 mask = 0x2; 591 break; 592 } 593 goto error; 594 595 /* Any register r0..r31. */ 596 case 'r': 597 s++; 598 if (!ISDIGIT (c = *s++)) 599 { 600 goto error; 601 } 602 if (ISDIGIT (*s)) 603 { 604 if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) 605 goto error; 606 } 607 else 608 c -= '0'; 609 mask = c; 610 break; 611 612 /* Not this opcode. */ 613 default: 614 goto error; 615 } 616 617 /* Obtained the register, now place it in the opcode. */ 618 switch (*args) 619 { 620 case '1': 621 opcode |= mask << 11; 622 continue; 623 624 case '2': 625 opcode |= mask << 21; 626 continue; 627 628 case 'd': 629 opcode |= mask << 16; 630 continue; 631 632 } 633 break; 634 635 /* Next operand is a floating point register. */ 636 case 'e': 637 case 'f': 638 case 'g': 639 /* Check for register prefix if necessary. */ 640 if (reg_prefix && *s != reg_prefix) 641 goto error; 642 else if (reg_prefix) 643 s++; 644 645 if (*s++ == 'f' && ISDIGIT (*s)) 646 { 647 mask = *s++; 648 if (ISDIGIT (*s)) 649 { 650 mask = 10 * (mask - '0') + (*s++ - '0'); 651 if (mask >= 32) 652 { 653 break; 654 } 655 } 656 else 657 mask -= '0'; 658 659 switch (*args) 660 { 661 662 case 'e': 663 opcode |= mask << 11; 664 continue; 665 666 case 'f': 667 opcode |= mask << 21; 668 continue; 669 670 case 'g': 671 opcode |= mask << 16; 672 if ((opcode & (1 << 10)) && mask != 0 673 && (mask == ((opcode >> 11) & 0x1f))) 674 as_warn (_("Pipelined instruction: fsrc1 = fdest")); 675 continue; 676 } 677 } 678 break; 679 680 /* Next operand must be a control register. */ 681 case 'c': 682 /* Check for register prefix if necessary. */ 683 if (reg_prefix && *s != reg_prefix) 684 goto error; 685 else if (reg_prefix) 686 s++; 687 688 if (strncmp (s, "fir", 3) == 0) 689 { 690 opcode |= 0x0 << 21; 691 s += 3; 692 continue; 693 } 694 if (strncmp (s, "psr", 3) == 0) 695 { 696 opcode |= 0x1 << 21; 697 s += 3; 698 continue; 699 } 700 if (strncmp (s, "dirbase", 7) == 0) 701 { 702 opcode |= 0x2 << 21; 703 s += 7; 704 continue; 705 } 706 if (strncmp (s, "db", 2) == 0) 707 { 708 opcode |= 0x3 << 21; 709 s += 2; 710 continue; 711 } 712 if (strncmp (s, "fsr", 3) == 0) 713 { 714 opcode |= 0x4 << 21; 715 s += 3; 716 continue; 717 } 718 if (strncmp (s, "epsr", 4) == 0) 719 { 720 opcode |= 0x5 << 21; 721 s += 4; 722 continue; 723 } 724 /* The remaining control registers are XP only. */ 725 if (target_xp && strncmp (s, "bear", 4) == 0) 726 { 727 opcode |= 0x6 << 21; 728 s += 4; 729 continue; 730 } 731 if (target_xp && strncmp (s, "ccr", 3) == 0) 732 { 733 opcode |= 0x7 << 21; 734 s += 3; 735 continue; 736 } 737 if (target_xp && strncmp (s, "p0", 2) == 0) 738 { 739 opcode |= 0x8 << 21; 740 s += 2; 741 continue; 742 } 743 if (target_xp && strncmp (s, "p1", 2) == 0) 744 { 745 opcode |= 0x9 << 21; 746 s += 2; 747 continue; 748 } 749 if (target_xp && strncmp (s, "p2", 2) == 0) 750 { 751 opcode |= 0xa << 21; 752 s += 2; 753 continue; 754 } 755 if (target_xp && strncmp (s, "p3", 2) == 0) 756 { 757 opcode |= 0xb << 21; 758 s += 2; 759 continue; 760 } 761 break; 762 763 /* 5-bit immediate in src1. */ 764 case '5': 765 if (! i860_get_expression (s)) 766 { 767 s = expr_end; 768 the_insn.fi[fc].fup |= OP_IMM_U5; 769 fc++; 770 continue; 771 } 772 break; 773 774 /* 26-bit immediate, relative branch (lbroff). */ 775 case 'l': 776 the_insn.fi[fc].pcrel = 1; 777 the_insn.fi[fc].fup |= OP_IMM_BR26; 778 goto immediate; 779 780 /* 16-bit split immediate, relative branch (sbroff). */ 781 case 'r': 782 the_insn.fi[fc].pcrel = 1; 783 the_insn.fi[fc].fup |= OP_IMM_BR16; 784 goto immediate; 785 786 /* 16-bit split immediate. */ 787 case 's': 788 the_insn.fi[fc].fup |= OP_IMM_SPLIT16; 789 goto immediate; 790 791 /* 16-bit split immediate, byte aligned (st.b). */ 792 case 'S': 793 the_insn.fi[fc].fup |= OP_IMM_SPLIT16; 794 goto immediate; 795 796 /* 16-bit split immediate, half-word aligned (st.s). */ 797 case 'T': 798 the_insn.fi[fc].fup |= (OP_IMM_SPLIT16 | OP_ENCODE1 | OP_ALIGN2); 799 goto immediate; 800 801 /* 16-bit split immediate, word aligned (st.l). */ 802 case 'U': 803 the_insn.fi[fc].fup |= (OP_IMM_SPLIT16 | OP_ENCODE1 | OP_ALIGN4); 804 goto immediate; 805 806 /* 16-bit immediate. */ 807 case 'i': 808 the_insn.fi[fc].fup |= OP_IMM_S16; 809 goto immediate; 810 811 /* 16-bit immediate, byte aligned (ld.b). */ 812 case 'I': 813 the_insn.fi[fc].fup |= OP_IMM_S16; 814 goto immediate; 815 816 /* 16-bit immediate, half-word aligned (ld.s). */ 817 case 'J': 818 the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE1 | OP_ALIGN2); 819 goto immediate; 820 821 /* 16-bit immediate, word aligned (ld.l, {p}fld.l, fst.l). */ 822 case 'K': 823 if (insn->name[0] == 'l') 824 the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE1 | OP_ALIGN4); 825 else 826 the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE2 | OP_ALIGN4); 827 goto immediate; 828 829 /* 16-bit immediate, double-word aligned ({p}fld.d, fst.d). */ 830 case 'L': 831 the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE3 | OP_ALIGN8); 832 goto immediate; 833 834 /* 16-bit immediate, quad-word aligned (fld.q, fst.q). */ 835 case 'M': 836 the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE3 | OP_ALIGN16); 837 838 /*FALLTHROUGH*/ 839 840 /* Handle the immediate for either the Intel syntax or 841 SVR4 syntax. The Intel syntax is "ha%immediate" 842 whereas SVR4 syntax is "[immediate]@ha". */ 843 immediate: 844 if (target_intel_syntax == 0) 845 { 846 /* AT&T/SVR4 syntax. */ 847 if (*s == ' ') 848 s++; 849 850 /* Note that if i860_get_expression() fails, we will still 851 have created U entries in the symbol table for the 852 'symbols' in the input string. Try not to create U 853 symbols for registers, etc. */ 854 if (! i860_get_expression (s)) 855 s = expr_end; 856 else 857 goto error; 858 859 if (strncmp (s, "@ha", 3) == 0) 860 { 861 the_insn.fi[fc].fup |= OP_SEL_HA; 862 s += 3; 863 } 864 else if (strncmp (s, "@h", 2) == 0) 865 { 866 the_insn.fi[fc].fup |= OP_SEL_H; 867 s += 2; 868 } 869 else if (strncmp (s, "@l", 2) == 0) 870 { 871 the_insn.fi[fc].fup |= OP_SEL_L; 872 s += 2; 873 } 874 else if (strncmp (s, "@gotoff", 7) == 0 875 || strncmp (s, "@GOTOFF", 7) == 0) 876 { 877 as_bad (_("Assembler does not yet support PIC")); 878 the_insn.fi[fc].fup |= OP_SEL_GOTOFF; 879 s += 7; 880 } 881 else if (strncmp (s, "@got", 4) == 0 882 || strncmp (s, "@GOT", 4) == 0) 883 { 884 as_bad (_("Assembler does not yet support PIC")); 885 the_insn.fi[fc].fup |= OP_SEL_GOT; 886 s += 4; 887 } 888 else if (strncmp (s, "@plt", 4) == 0 889 || strncmp (s, "@PLT", 4) == 0) 890 { 891 as_bad (_("Assembler does not yet support PIC")); 892 the_insn.fi[fc].fup |= OP_SEL_PLT; 893 s += 4; 894 } 895 896 the_insn.expand = insn->expand; 897 fc++; 898 899 continue; 900 } 901 else 902 { 903 /* Intel syntax. */ 904 if (*s == ' ') 905 s++; 906 if (strncmp (s, "ha%", 3) == 0) 907 { 908 the_insn.fi[fc].fup |= OP_SEL_HA; 909 s += 3; 910 } 911 else if (strncmp (s, "h%", 2) == 0) 912 { 913 the_insn.fi[fc].fup |= OP_SEL_H; 914 s += 2; 915 } 916 else if (strncmp (s, "l%", 2) == 0) 917 { 918 the_insn.fi[fc].fup |= OP_SEL_L; 919 s += 2; 920 } 921 the_insn.expand = insn->expand; 922 923 /* Note that if i860_get_expression() fails, we will still 924 have created U entries in the symbol table for the 925 'symbols' in the input string. Try not to create U 926 symbols for registers, etc. */ 927 if (! i860_get_expression (s)) 928 s = expr_end; 929 else 930 goto error; 931 932 fc++; 933 continue; 934 } 935 break; 936 937 default: 938 as_fatal (_("failed sanity check.")); 939 } 940 break; 941 } 942 error: 943 if (match == 0) 944 { 945 /* Args don't match. */ 946 if (insn[1].name != NULL 947 && ! strcmp (insn->name, insn[1].name)) 948 { 949 ++insn; 950 s = args_start; 951 continue; 952 } 953 else 954 { 955 as_bad (_("Illegal operands for %s"), insn->name); 956 return; 957 } 958 } 959 break; 960 } 961 962 /* Set the dual bit on this instruction if necessary. */ 963 if (dual_mode != DUAL_OFF) 964 { 965 if ((opcode & 0xfc000000) == 0x48000000 || opcode == 0xb0000000) 966 { 967 /* The instruction is a flop or a fnop, so set its dual bit 968 (but check that it is 8-byte aligned). */ 969 if (((frag_now->fr_address + frag_now_fix_octets ()) & 7) == 0) 970 opcode |= (1 << 9); 971 else 972 as_bad (_("'d.%s' must be 8-byte aligned"), insn->name); 973 974 if (dual_mode == DUAL_DDOT) 975 dual_mode = DUAL_OFF; 976 else if (dual_mode == DUAL_ONDDOT) 977 dual_mode = DUAL_ON; 978 } 979 else if (dual_mode == DUAL_DDOT || dual_mode == DUAL_ONDDOT) 980 as_bad (_("Prefix 'd.' invalid for instruction `%s'"), insn->name); 981 } 982 983 the_insn.opcode = opcode; 984 985 /* Only recognize XP instructions when the user has requested it. */ 986 if (insn->expand == XP_ONLY && ! target_xp) 987 as_bad (_("Unknown opcode: `%s'"), insn->name); 988 } 989 990 static int 991 i860_get_expression (char *str) 992 { 993 char *save_in; 994 segT seg; 995 996 save_in = input_line_pointer; 997 input_line_pointer = str; 998 seg = expression (&the_insn.fi[fc].exp); 999 if (seg != absolute_section 1000 && seg != undefined_section 1001 && ! SEG_NORMAL (seg)) 1002 { 1003 the_insn.error = _("bad segment"); 1004 expr_end = input_line_pointer; 1005 input_line_pointer = save_in; 1006 return 1; 1007 } 1008 expr_end = input_line_pointer; 1009 input_line_pointer = save_in; 1010 return 0; 1011 } 1012 1013 char * 1014 md_atof (int type, char *litP, int *sizeP) 1015 { 1016 return ieee_md_atof (type, litP, sizeP, TRUE); 1017 } 1018 1019 /* Write out in current endian mode. */ 1020 void 1021 md_number_to_chars (char *buf, valueT val, int n) 1022 { 1023 if (target_big_endian) 1024 number_to_chars_bigendian (buf, val, n); 1025 else 1026 number_to_chars_littleendian (buf, val, n); 1027 } 1028 1029 /* This should never be called for i860. */ 1030 int 1031 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED, 1032 segT segtype ATTRIBUTE_UNUSED) 1033 { 1034 as_fatal (_("relaxation not supported\n")); 1035 } 1036 1037 #ifdef DEBUG_I860 1038 static void 1039 print_insn (struct i860_it *insn) 1040 { 1041 if (insn->error) 1042 fprintf (stderr, "ERROR: %s\n", insn->error); 1043 1044 fprintf (stderr, "opcode = 0x%08lx\t", insn->opcode); 1045 fprintf (stderr, "expand = 0x%x\t", insn->expand); 1046 fprintf (stderr, "reloc = %s\t\n", 1047 bfd_get_reloc_code_name (insn->reloc)); 1048 fprintf (stderr, "exp = {\n"); 1049 fprintf (stderr, "\t\tX_add_symbol = %s\n", 1050 insn->exp.X_add_symbol ? 1051 (S_GET_NAME (insn->exp.X_add_symbol) ? 1052 S_GET_NAME (insn->exp.X_add_symbol) : "???") : "0"); 1053 fprintf (stderr, "\t\tX_op_symbol = %s\n", 1054 insn->exp.X_op_symbol ? 1055 (S_GET_NAME (insn->exp.X_op_symbol) ? 1056 S_GET_NAME (insn->exp.X_op_symbol) : "???") : "0"); 1057 fprintf (stderr, "\t\tX_add_number = %lx\n", 1058 insn->exp.X_add_number); 1059 fprintf (stderr, "}\n"); 1060 } 1061 #endif /* DEBUG_I860 */ 1062 1063 1064 #ifdef OBJ_ELF 1066 const char *md_shortopts = "VQ:"; 1067 #else 1068 const char *md_shortopts = ""; 1069 #endif 1070 1071 #define OPTION_EB (OPTION_MD_BASE + 0) 1072 #define OPTION_EL (OPTION_MD_BASE + 1) 1073 #define OPTION_WARN_EXPAND (OPTION_MD_BASE + 2) 1074 #define OPTION_XP (OPTION_MD_BASE + 3) 1075 #define OPTION_INTEL_SYNTAX (OPTION_MD_BASE + 4) 1076 1077 struct option md_longopts[] = { 1078 { "EB", no_argument, NULL, OPTION_EB }, 1079 { "EL", no_argument, NULL, OPTION_EL }, 1080 { "mwarn-expand", no_argument, NULL, OPTION_WARN_EXPAND }, 1081 { "mxp", no_argument, NULL, OPTION_XP }, 1082 { "mintel-syntax",no_argument, NULL, OPTION_INTEL_SYNTAX }, 1083 { NULL, no_argument, NULL, 0 } 1084 }; 1085 size_t md_longopts_size = sizeof (md_longopts); 1086 1087 int 1088 md_parse_option (int c, char *arg ATTRIBUTE_UNUSED) 1089 { 1090 switch (c) 1091 { 1092 case OPTION_EB: 1093 target_big_endian = 1; 1094 break; 1095 1096 case OPTION_EL: 1097 target_big_endian = 0; 1098 break; 1099 1100 case OPTION_WARN_EXPAND: 1101 target_warn_expand = 1; 1102 break; 1103 1104 case OPTION_XP: 1105 target_xp = 1; 1106 break; 1107 1108 case OPTION_INTEL_SYNTAX: 1109 target_intel_syntax = 1; 1110 break; 1111 1112 #ifdef OBJ_ELF 1113 /* SVR4 argument compatibility (-V): print version ID. */ 1114 case 'V': 1115 print_version_id (); 1116 break; 1117 1118 /* SVR4 argument compatibility (-Qy, -Qn): controls whether 1119 a .comment section should be emitted or not (ignored). */ 1120 case 'Q': 1121 break; 1122 #endif 1123 1124 default: 1125 return 0; 1126 } 1127 1128 return 1; 1129 } 1130 1131 void 1132 md_show_usage (FILE *stream) 1133 { 1134 fprintf (stream, _("\ 1135 -EL generate code for little endian mode (default)\n\ 1136 -EB generate code for big endian mode\n\ 1137 -mwarn-expand warn if pseudo operations are expanded\n\ 1138 -mxp enable i860XP support (disabled by default)\n\ 1139 -mintel-syntax enable Intel syntax (default to AT&T/SVR4)\n")); 1140 #ifdef OBJ_ELF 1141 /* SVR4 compatibility flags. */ 1142 fprintf (stream, _("\ 1143 -V print assembler version number\n\ 1144 -Qy, -Qn ignored\n")); 1145 #endif 1146 } 1147 1148 1149 /* We have no need to default values of symbols. */ 1151 symbolS * 1152 md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 1153 { 1154 return 0; 1155 } 1156 1157 /* The i860 denotes auto-increment with '++'. */ 1158 void 1159 md_operand (expressionS *exp) 1160 { 1161 char *s; 1162 1163 for (s = input_line_pointer; *s; s++) 1164 { 1165 if (s[0] == '+' && s[1] == '+') 1166 { 1167 input_line_pointer += 2; 1168 exp->X_op = O_register; 1169 break; 1170 } 1171 } 1172 } 1173 1174 /* Round up a section size to the appropriate boundary. */ 1175 valueT 1176 md_section_align (segT segment ATTRIBUTE_UNUSED, 1177 valueT size ATTRIBUTE_UNUSED) 1178 { 1179 /* Byte alignment is fine. */ 1180 return size; 1181 } 1182 1183 /* On the i860, a PC-relative offset is relative to the address of the 1184 offset plus its size. */ 1185 long 1186 md_pcrel_from (fixS *fixP) 1187 { 1188 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; 1189 } 1190 1191 /* Determine the relocation needed for non PC-relative 16-bit immediates. 1192 Also adjust the given immediate as necessary. Finally, check that 1193 all constraints (such as alignment) are satisfied. */ 1194 static bfd_reloc_code_real_type 1195 obtain_reloc_for_imm16 (fixS *fix, long *val) 1196 { 1197 valueT fup = fix->fx_addnumber; 1198 bfd_reloc_code_real_type reloc; 1199 1200 if (fix->fx_pcrel) 1201 abort (); 1202 1203 /* Check alignment restrictions. */ 1204 if ((fup & OP_ALIGN2) && (*val & 0x1)) 1205 as_bad_where (fix->fx_file, fix->fx_line, 1206 _("This immediate requires 0 MOD 2 alignment")); 1207 else if ((fup & OP_ALIGN4) && (*val & 0x3)) 1208 as_bad_where (fix->fx_file, fix->fx_line, 1209 _("This immediate requires 0 MOD 4 alignment")); 1210 else if ((fup & OP_ALIGN8) && (*val & 0x7)) 1211 as_bad_where (fix->fx_file, fix->fx_line, 1212 _("This immediate requires 0 MOD 8 alignment")); 1213 else if ((fup & OP_ALIGN16) && (*val & 0xf)) 1214 as_bad_where (fix->fx_file, fix->fx_line, 1215 _("This immediate requires 0 MOD 16 alignment")); 1216 1217 if (fup & OP_SEL_HA) 1218 { 1219 *val = (*val >> 16) + (*val & 0x8000 ? 1 : 0); 1220 reloc = BFD_RELOC_860_HIGHADJ; 1221 } 1222 else if (fup & OP_SEL_H) 1223 { 1224 *val >>= 16; 1225 reloc = BFD_RELOC_860_HIGH; 1226 } 1227 else if (fup & OP_SEL_L) 1228 { 1229 int num_encode; 1230 if (fup & OP_IMM_SPLIT16) 1231 { 1232 if (fup & OP_ENCODE1) 1233 { 1234 num_encode = 1; 1235 reloc = BFD_RELOC_860_SPLIT1; 1236 } 1237 else if (fup & OP_ENCODE2) 1238 { 1239 num_encode = 2; 1240 reloc = BFD_RELOC_860_SPLIT2; 1241 } 1242 else 1243 { 1244 num_encode = 0; 1245 reloc = BFD_RELOC_860_SPLIT0; 1246 } 1247 } 1248 else 1249 { 1250 if (fup & OP_ENCODE1) 1251 { 1252 num_encode = 1; 1253 reloc = BFD_RELOC_860_LOW1; 1254 } 1255 else if (fup & OP_ENCODE2) 1256 { 1257 num_encode = 2; 1258 reloc = BFD_RELOC_860_LOW2; 1259 } 1260 else if (fup & OP_ENCODE3) 1261 { 1262 num_encode = 3; 1263 reloc = BFD_RELOC_860_LOW3; 1264 } 1265 else 1266 { 1267 num_encode = 0; 1268 reloc = BFD_RELOC_860_LOW0; 1269 } 1270 } 1271 1272 /* Preserve size encode bits. */ 1273 *val &= ~((1 << num_encode) - 1); 1274 } 1275 else 1276 { 1277 /* No selector. What reloc do we generate (???)? */ 1278 reloc = BFD_RELOC_32; 1279 } 1280 1281 return reloc; 1282 } 1283 1284 /* Attempt to simplify or eliminate a fixup. To indicate that a fixup 1285 has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL, 1286 we will have to generate a reloc entry. */ 1287 1288 void 1289 md_apply_fix (fixS *fix, valueT *valP, segT seg ATTRIBUTE_UNUSED) 1290 { 1291 char *buf; 1292 long val = *valP; 1293 unsigned long insn; 1294 valueT fup; 1295 1296 buf = fix->fx_frag->fr_literal + fix->fx_where; 1297 1298 /* Recall that earlier we stored the opcode little-endian. */ 1299 insn = bfd_getl32 (buf); 1300 1301 /* We stored a fix-up in this oddly-named scratch field. */ 1302 fup = fix->fx_addnumber; 1303 1304 /* Determine the necessary relocations as well as inserting an 1305 immediate into the instruction. */ 1306 if (fup & OP_IMM_U5) 1307 { 1308 if (val & ~0x1f) 1309 as_bad_where (fix->fx_file, fix->fx_line, 1310 _("5-bit immediate too large")); 1311 if (fix->fx_addsy) 1312 as_bad_where (fix->fx_file, fix->fx_line, 1313 _("5-bit field must be absolute")); 1314 1315 insn |= (val & 0x1f) << 11; 1316 bfd_putl32 (insn, buf); 1317 fix->fx_r_type = BFD_RELOC_NONE; 1318 fix->fx_done = 1; 1319 } 1320 else if (fup & OP_IMM_S16) 1321 { 1322 fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val); 1323 1324 /* Insert the immediate. */ 1325 if (fix->fx_addsy) 1326 fix->fx_done = 0; 1327 else 1328 { 1329 insn |= val & 0xffff; 1330 bfd_putl32 (insn, buf); 1331 fix->fx_r_type = BFD_RELOC_NONE; 1332 fix->fx_done = 1; 1333 } 1334 } 1335 else if (fup & OP_IMM_U16) 1336 abort (); 1337 1338 else if (fup & OP_IMM_SPLIT16) 1339 { 1340 fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val); 1341 1342 /* Insert the immediate. */ 1343 if (fix->fx_addsy) 1344 fix->fx_done = 0; 1345 else 1346 { 1347 insn |= val & 0x7ff; 1348 insn |= (val & 0xf800) << 5; 1349 bfd_putl32 (insn, buf); 1350 fix->fx_r_type = BFD_RELOC_NONE; 1351 fix->fx_done = 1; 1352 } 1353 } 1354 else if (fup & OP_IMM_BR16) 1355 { 1356 if (val & 0x3) 1357 as_bad_where (fix->fx_file, fix->fx_line, 1358 _("A branch offset requires 0 MOD 4 alignment")); 1359 1360 val = val >> 2; 1361 1362 /* Insert the immediate. */ 1363 if (fix->fx_addsy) 1364 { 1365 fix->fx_done = 0; 1366 fix->fx_r_type = BFD_RELOC_860_PC16; 1367 } 1368 else 1369 { 1370 insn |= (val & 0x7ff); 1371 insn |= ((val & 0xf800) << 5); 1372 bfd_putl32 (insn, buf); 1373 fix->fx_r_type = BFD_RELOC_NONE; 1374 fix->fx_done = 1; 1375 } 1376 } 1377 else if (fup & OP_IMM_BR26) 1378 { 1379 if (val & 0x3) 1380 as_bad_where (fix->fx_file, fix->fx_line, 1381 _("A branch offset requires 0 MOD 4 alignment")); 1382 1383 val >>= 2; 1384 1385 /* Insert the immediate. */ 1386 if (fix->fx_addsy) 1387 { 1388 fix->fx_r_type = BFD_RELOC_860_PC26; 1389 fix->fx_done = 0; 1390 } 1391 else 1392 { 1393 insn |= (val & 0x3ffffff); 1394 bfd_putl32 (insn, buf); 1395 fix->fx_r_type = BFD_RELOC_NONE; 1396 fix->fx_done = 1; 1397 } 1398 } 1399 else if (fup != OP_NONE) 1400 { 1401 as_bad_where (fix->fx_file, fix->fx_line, 1402 _("Unrecognized fix-up (0x%08lx)"), (unsigned long) fup); 1403 abort (); 1404 } 1405 else 1406 { 1407 /* I believe only fix-ups such as ".long .ep.main-main+0xc8000000" 1408 reach here (???). */ 1409 if (fix->fx_addsy) 1410 { 1411 fix->fx_r_type = BFD_RELOC_32; 1412 fix->fx_done = 0; 1413 } 1414 else 1415 { 1416 insn |= (val & 0xffffffff); 1417 bfd_putl32 (insn, buf); 1418 fix->fx_r_type = BFD_RELOC_NONE; 1419 fix->fx_done = 1; 1420 } 1421 } 1422 } 1423 1424 /* Generate a machine dependent reloc from a fixup. */ 1425 arelent* 1426 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, 1427 fixS *fixp) 1428 { 1429 arelent *reloc; 1430 1431 reloc = xmalloc (sizeof (*reloc)); 1432 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); 1433 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 1434 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 1435 reloc->addend = fixp->fx_offset; 1436 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 1437 1438 if (! reloc->howto) 1439 { 1440 as_bad_where (fixp->fx_file, fixp->fx_line, 1441 "Cannot represent %s relocation in object file", 1442 bfd_get_reloc_code_name (fixp->fx_r_type)); 1443 } 1444 return reloc; 1445 } 1446 1447 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents 1448 of an rs_align_code fragment. */ 1449 1450 void 1451 i860_handle_align (fragS *fragp) 1452 { 1453 /* Instructions are always stored little-endian on the i860. */ 1454 static const unsigned char le_nop[] = { 0x00, 0x00, 0x00, 0xA0 }; 1455 1456 int bytes; 1457 char *p; 1458 1459 if (fragp->fr_type != rs_align_code) 1460 return; 1461 1462 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix; 1463 p = fragp->fr_literal + fragp->fr_fix; 1464 1465 /* Make sure we are on a 4-byte boundary, in case someone has been 1466 putting data into a text section. */ 1467 if (bytes & 3) 1468 { 1469 int fix = bytes & 3; 1470 memset (p, 0, fix); 1471 p += fix; 1472 fragp->fr_fix += fix; 1473 } 1474 1475 memcpy (p, le_nop, 4); 1476 fragp->fr_var = 4; 1477 } 1478 1479 /* This is called after a user-defined label is seen. We check 1480 if the label has a double colon (valid in Intel syntax mode only), 1481 in which case it should be externalized. */ 1482 1483 void 1484 i860_check_label (symbolS *labelsym) 1485 { 1486 /* At this point, the current line pointer is sitting on the character 1487 just after the first colon on the label. */ 1488 if (target_intel_syntax && *input_line_pointer == ':') 1489 { 1490 S_SET_EXTERNAL (labelsym); 1491 input_line_pointer++; 1492 } 1493 } 1494