1 /* tc-w65.c -- Assemble code for the W65816 2 Copyright 1995, 1998, 2000, 2001, 2002 Free Software Foundation, Inc. 3 4 This file is part of GAS, the GNU Assembler. 5 6 GAS is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GAS is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GAS; see the file COPYING. If not, write to the Free 18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 19 02111-1307, USA. */ 20 21 /* Written By Steve Chamberlain <sac@cygnus.com>. */ 22 23 #include <stdio.h> 24 #include "as.h" 25 #include "bfd.h" 26 #include "subsegs.h" 27 #define DEFINE_TABLE 28 #include "../opcodes/w65-opc.h" 29 30 const char comment_chars[] = "!"; 31 const char line_separator_chars[] = ";"; 32 const char line_comment_chars[] = "!#"; 33 34 /* This table describes all the machine specific pseudo-ops the assembler 35 has to support. The fields are: 36 37 pseudo-op name without dot 38 function to call to execute this pseudo-op 39 Integer arg to pass to the function */ 40 41 #define OP_BCC 0x90 42 #define OP_BCS 0xB0 43 #define OP_BEQ 0xF0 44 #define OP_BMI 0x30 45 #define OP_BNE 0xD0 46 #define OP_BPL 0x10 47 #define OP_BRA 0x80 48 #define OP_BRL 0x82 49 #define OP_BVC 0x50 50 #define OP_BVS 0x70 51 52 static void s_longa PARAMS ((int)); 53 static char *parse_exp PARAMS ((char *)); 54 static char *get_operands PARAMS ((const struct opinfo *, char *)); 55 static const struct opinfo *get_specific PARAMS ((const struct opinfo *)); 56 static void build_Mytes PARAMS ((const struct opinfo *)); 57 58 59 const pseudo_typeS md_pseudo_table[] = { 60 {"int", cons, 2}, 61 {"word", cons, 2}, 62 {"longa", s_longa, 0}, 63 {"longi", s_longa, 1}, 64 {0, 0, 0} 65 }; 66 67 #if 0 68 int md_reloc_size; 69 #endif 70 71 const char EXP_CHARS[] = "eE"; 72 73 /* Chars that mean this number is a floating point constant. */ 74 /* As in 0f12.456 */ 75 /* or 0d1.2345e12 */ 76 const char FLT_CHARS[] = "rRsSfFdDxXpP"; 77 78 /* Opcode mnemonics */ 79 static struct hash_control *opcode_hash_control; 80 81 int M; /* M flag */ 82 int X; /* X flag */ 83 84 #define C(a,b) ENCODE_RELAX(a,b) 85 #define ENCODE_RELAX(what,length) (((what) << 2) + (length)) 86 87 #define GET_WHAT(x) ((x>>2)) 88 89 #define BYTE_DISP 1 90 #define WORD_DISP 2 91 #define UNDEF_BYTE_DISP 0 92 #define UNDEF_WORD_DISP 3 93 94 #define COND_BRANCH 1 95 #define UNCOND_BRANCH 2 96 #define END 3 97 98 #define BYTE_F 127 /* How far we can branch forwards */ 99 #define BYTE_B -126 /* How far we can branch backwards */ 100 #define WORD_F 32767 101 #define WORD_B 32768 102 103 relax_typeS md_relax_table[C (END, 0)] = { 104 { 0, 0, 0, 0 }, 105 { 0, 0, 0, 0 }, 106 { 0, 0, 0, 0 }, 107 { 0, 0, 0, 0 }, 108 109 /* COND_BRANCH */ 110 { 0, 0, 0, 0 }, /* UNDEF_BYTE_DISP */ 111 { BYTE_F, BYTE_B, 2, C (COND_BRANCH, WORD_DISP) }, /* BYTE_DISP */ 112 { WORD_F, WORD_B, 5, 0 }, /* WORD_DISP */ 113 { 0, 0, 5, 0 }, /* UNDEF_WORD_DISP */ 114 115 /* UNCOND_BRANCH */ 116 { 0, 0, 0, 0 }, /* UNDEF_BYTE_DISP */ 117 { BYTE_F, BYTE_B, 2, C (UNCOND_BRANCH, WORD_DISP) }, /* BYTE_DISP */ 118 { WORD_F, WORD_B, 3, 0 }, /* WORD_DISP */ 119 { 0, 0, 3, 0 } /* UNDEF_WORD_DISP */ 120 121 }; 122 123 /* This function is called once, at assembler startup time. This 124 should set up all the tables, etc that the MD part of the assembler 125 needs. */ 126 127 static void 128 s_longa (xmode) 129 int xmode; 130 { 131 int *p = xmode ? &X : &M; 132 while (*input_line_pointer == ' ') 133 input_line_pointer++; 134 if (strncmp (input_line_pointer, "on", 2) == 0) 135 { 136 input_line_pointer += 2; 137 *p = 0; 138 } 139 else if (strncmp (input_line_pointer, "off", 3) == 0) 140 { 141 *p = 1; 142 input_line_pointer += 3; 143 } 144 else 145 as_bad (_("need on or off.")); 146 demand_empty_rest_of_line (); 147 } 148 149 void 150 md_begin () 151 { 152 const struct opinfo *opcode; 153 char *prev_name = ""; 154 155 opcode_hash_control = hash_new (); 156 157 /* Insert unique names into hash table. */ 158 for (opcode = optable; opcode->name; opcode++) 159 { 160 if (strcmp (prev_name, opcode->name)) 161 { 162 prev_name = opcode->name; 163 hash_insert (opcode_hash_control, opcode->name, (char *) opcode); 164 } 165 } 166 167 flag_signed_overflow_ok = 1; 168 } 169 170 static expressionS immediate; /* absolute expression */ 171 static expressionS immediate1; /* absolute expression */ 172 int expr_size; 173 int expr_shift; 174 int tc_cons_reloc; 175 176 void 177 w65_expression (dest) 178 expressionS *dest; 179 { 180 expr_size = 0; 181 expr_shift = 0; 182 tc_cons_reloc = 0; 183 while (*input_line_pointer == ' ') 184 input_line_pointer++; 185 186 if (*input_line_pointer == '<') 187 { 188 expr_size = 1; 189 input_line_pointer++; 190 } 191 else if (*input_line_pointer == '>') 192 { 193 expr_shift = 1; 194 input_line_pointer++; 195 } 196 else if (*input_line_pointer == '^') 197 { 198 expr_shift = 2; 199 input_line_pointer++; 200 } 201 202 expr (0, dest); 203 } 204 205 int amode; 206 207 static char * 208 parse_exp (s) 209 char *s; 210 { 211 char *save; 212 char *new; 213 214 save = input_line_pointer; 215 input_line_pointer = s; 216 w65_expression (&immediate); 217 if (immediate.X_op == O_absent) 218 as_bad (_("missing operand")); 219 new = input_line_pointer; 220 input_line_pointer = save; 221 return new; 222 } 223 224 static char * 225 get_operands (info, ptr) 226 const struct opinfo *info; 227 char *ptr; 228 { 229 register int override_len = 0; 230 register int bytes = 0; 231 232 while (*ptr == ' ') 233 ptr++; 234 235 if (ptr[0] == '#') 236 { 237 ptr++; 238 switch (info->amode) 239 { 240 case ADDR_IMMTOI: 241 bytes = X ? 1 : 2; 242 amode = ADDR_IMMTOI; 243 break; 244 case ADDR_IMMTOA: 245 bytes = M ? 1 : 2; 246 amode = ADDR_IMMTOA; 247 break; 248 case ADDR_IMMCOP: 249 bytes = 1; 250 amode = ADDR_IMMCOP; 251 break; 252 case ADDR_DIR: 253 bytes = 2; 254 amode = ADDR_ABS; 255 break; 256 default: 257 abort (); 258 break; 259 } 260 ptr = parse_exp (ptr); 261 } 262 else if (ptr[0] == '!') 263 { 264 ptr = parse_exp (ptr + 1); 265 if (ptr[0] == ',') 266 { 267 if (ptr[1] == 'y') 268 { 269 amode = ADDR_ABS_IDX_Y; 270 bytes = 2; 271 ptr += 2; 272 } 273 else if (ptr[1] == 'x') 274 { 275 amode = ADDR_ABS_IDX_X; 276 bytes = 2; 277 ptr += 2; 278 } 279 else 280 { 281 as_bad (_("syntax error after <exp")); 282 } 283 } 284 else 285 { 286 amode = ADDR_ABS; 287 bytes = 2; 288 } 289 } 290 else if (ptr[0] == '>') 291 { 292 ptr = parse_exp (ptr + 1); 293 if (ptr[0] == ',' && ptr[1] == 'x') 294 { 295 amode = ADDR_ABS_LONG_IDX_X; 296 bytes = 3; 297 ptr += 2; 298 } 299 else 300 { 301 amode = ADDR_ABS_LONG; 302 bytes = 3; 303 } 304 } 305 else if (ptr[0] == '<') 306 { 307 ptr = parse_exp (ptr + 1); 308 if (ptr[0] == ',') 309 { 310 if (ptr[1] == 'y') 311 { 312 amode = ADDR_DIR_IDX_Y; 313 ptr += 2; 314 bytes = 2; 315 } 316 else if (ptr[1] == 'x') 317 { 318 amode = ADDR_DIR_IDX_X; 319 ptr += 2; 320 bytes = 2; 321 } 322 else 323 { 324 as_bad (_("syntax error after <exp")); 325 } 326 } 327 else 328 { 329 amode = ADDR_DIR; 330 bytes = 1; 331 } 332 } 333 else if (ptr[0] == 'a') 334 { 335 amode = ADDR_ACC; 336 } 337 else if (ptr[0] == '(') 338 { 339 /* Look for (exp),y 340 (<exp),y 341 (exp,x) 342 (<exp,x) 343 (exp) 344 (!exp) 345 (exp) 346 (<exp) 347 (exp,x) 348 (!exp,x) 349 (exp,s) 350 (exp,s),y */ 351 352 ptr++; 353 if (ptr[0] == '<') 354 { 355 override_len = 1; 356 ptr++; 357 } 358 else if (ptr[0] == '!') 359 { 360 override_len = 2; 361 ptr++; 362 } 363 else if (ptr[0] == '>') 364 { 365 override_len = 3; 366 ptr++; 367 } 368 else 369 { 370 override_len = 0; 371 } 372 ptr = parse_exp (ptr); 373 374 if (ptr[0] == ',') 375 { 376 ptr++; 377 if (ptr[0] == 'x' && ptr[1] == ')') 378 { 379 ptr += 2; 380 381 if (override_len == 1) 382 { 383 amode = ADDR_DIR_IDX_IND_X; 384 bytes = 2; 385 } 386 else 387 { 388 amode = ADDR_ABS_IND_IDX; 389 bytes = 2; 390 } 391 } 392 else if (ptr[0] == 's' && ptr[1] == ')' 393 && ptr[2] == ',' && ptr[3] == 'y') 394 { 395 amode = ADDR_STACK_REL_INDX_IDX; 396 bytes = 1; 397 ptr += 4; 398 } 399 } 400 else if (ptr[0] == ')') 401 { 402 if (ptr[1] == ',' && ptr[2] == 'y') 403 { 404 amode = ADDR_DIR_IND_IDX_Y; 405 ptr += 3; 406 bytes = 2; 407 } 408 else 409 { 410 if (override_len == 1) 411 { 412 amode = ADDR_DIR_IND; 413 bytes = 1; 414 } 415 else 416 { 417 amode = ADDR_ABS_IND; 418 bytes = 2; 419 } 420 ptr++; 421 422 } 423 } 424 } 425 else if (ptr[0] == '[') 426 { 427 ptr = parse_exp (ptr + 1); 428 if (ptr[0] == ']') 429 { 430 ptr++; 431 if (ptr[0] == ',' && ptr[1] == 'y') 432 { 433 bytes = 1; 434 amode = ADDR_DIR_IND_IDX_Y_LONG; 435 ptr += 2; 436 } 437 else 438 { 439 if (info->code == O_jmp) 440 { 441 bytes = 2; 442 amode = ADDR_ABS_IND_LONG; 443 } 444 else 445 { 446 bytes = 1; 447 amode = ADDR_DIR_IND_LONG; 448 } 449 } 450 } 451 } 452 else 453 { 454 ptr = parse_exp (ptr); 455 if (ptr[0] == ',') 456 { 457 if (ptr[1] == 'y') 458 { 459 if (override_len == 1) 460 { 461 bytes = 1; 462 amode = ADDR_DIR_IDX_Y; 463 } 464 else 465 { 466 amode = ADDR_ABS_IDX_Y; 467 bytes = 2; 468 } 469 ptr += 2; 470 } 471 else if (ptr[1] == 'x') 472 { 473 if (override_len == 1) 474 { 475 amode = ADDR_DIR_IDX_X; 476 bytes = 1; 477 } 478 else 479 { 480 amode = ADDR_ABS_IDX_X; 481 bytes = 2; 482 } 483 ptr += 2; 484 } 485 else if (ptr[1] == 's') 486 { 487 bytes = 1; 488 amode = ADDR_STACK_REL; 489 ptr += 2; 490 } 491 else 492 { 493 bytes = 1; 494 immediate1 = immediate; 495 ptr = parse_exp (ptr + 1); 496 amode = ADDR_BLOCK_MOVE; 497 } 498 } 499 else 500 { 501 switch (info->amode) 502 { 503 case ADDR_PC_REL: 504 amode = ADDR_PC_REL; 505 bytes = 1; 506 break; 507 case ADDR_PC_REL_LONG: 508 amode = ADDR_PC_REL_LONG; 509 bytes = 2; 510 break; 511 default: 512 if (override_len == 1) 513 { 514 amode = ADDR_DIR; 515 bytes = 1; 516 } 517 else if (override_len == 3) 518 { 519 bytes = 3; 520 amode = ADDR_ABS_LONG; 521 } 522 else 523 { 524 amode = ADDR_ABS; 525 bytes = 2; 526 } 527 } 528 } 529 } 530 531 switch (bytes) 532 { 533 case 1: 534 switch (expr_shift) 535 { 536 case 0: 537 if (amode == ADDR_DIR) 538 tc_cons_reloc = R_W65_DP; 539 else 540 tc_cons_reloc = R_W65_ABS8; 541 break; 542 case 1: 543 tc_cons_reloc = R_W65_ABS8S8; 544 break; 545 case 2: 546 tc_cons_reloc = R_W65_ABS8S16; 547 break; 548 } 549 break; 550 case 2: 551 switch (expr_shift) 552 { 553 case 0: 554 tc_cons_reloc = R_W65_ABS16; 555 break; 556 case 1: 557 tc_cons_reloc = R_W65_ABS16S8; 558 break; 559 case 2: 560 tc_cons_reloc = R_W65_ABS16S16; 561 break; 562 } 563 } 564 return ptr; 565 } 566 567 /* Passed a pointer to a list of opcodes which use different 568 addressing modes, return the opcode which matches the opcodes 569 provided. */ 570 571 static const struct opinfo * 572 get_specific (opcode) 573 const struct opinfo *opcode; 574 { 575 int ocode = opcode->code; 576 577 for (; opcode->code == ocode; opcode++) 578 { 579 if (opcode->amode == amode) 580 return opcode; 581 } 582 return 0; 583 } 584 585 /* Now we know what sort of opcodes it is, let's build the bytes. */ 586 587 static void 588 build_Mytes (opcode) 589 const struct opinfo *opcode; 590 { 591 int size; 592 int type; 593 int pcrel; 594 char *output; 595 596 if (opcode->amode == ADDR_IMPLIED) 597 { 598 output = frag_more (1); 599 } 600 else if (opcode->amode == ADDR_PC_REL) 601 { 602 int type; 603 604 /* This is a relaxable insn, so we do some special handling. */ 605 type = opcode->val == OP_BRA ? UNCOND_BRANCH : COND_BRANCH; 606 output = frag_var (rs_machine_dependent, 607 md_relax_table[C (type, WORD_DISP)].rlx_length, 608 md_relax_table[C (type, BYTE_DISP)].rlx_length, 609 C (type, UNDEF_BYTE_DISP), 610 immediate.X_add_symbol, 611 immediate.X_add_number, 612 0); 613 } 614 else 615 { 616 switch (opcode->amode) 617 { 618 GETINFO (size, type, pcrel); 619 default: 620 abort (); 621 } 622 623 /* If something special was done in the expression modify the 624 reloc type. */ 625 if (tc_cons_reloc) 626 type = tc_cons_reloc; 627 628 /* 1 byte for the opcode + the bytes for the addrmode. */ 629 output = frag_more (size + 1); 630 631 if (opcode->amode == ADDR_BLOCK_MOVE) 632 { 633 /* Two relocs for this one. */ 634 fix_new_exp (frag_now, 635 output + 1 - frag_now->fr_literal, 636 1, 637 &immediate, 638 0, 639 R_W65_ABS8S16); 640 641 fix_new_exp (frag_now, 642 output + 2 - frag_now->fr_literal, 643 1, 644 &immediate1, 645 0, 646 R_W65_ABS8S16); 647 } 648 else if (type >= 0 649 && opcode->amode != ADDR_IMPLIED 650 && opcode->amode != ADDR_ACC 651 && opcode->amode != ADDR_STACK) 652 { 653 fix_new_exp (frag_now, 654 output + 1 - frag_now->fr_literal, 655 size, 656 &immediate, 657 pcrel, 658 type); 659 } 660 } 661 output[0] = opcode->val; 662 } 663 664 /* This is the guts of the machine-dependent assembler. STR points to 665 a machine dependent instruction. This function is supposed to emit 666 the frags/bytes it assembles to. */ 667 668 void 669 md_assemble (str) 670 char *str; 671 { 672 const struct opinfo *opcode; 673 char name[20]; 674 675 /* Drop leading whitespace */ 676 while (*str == ' ') 677 str++; 678 679 /* all opcodes are three letters */ 680 name[0] = str[0]; 681 name[1] = str[1]; 682 name[2] = str[2]; 683 name[3] = 0; 684 685 tc_cons_reloc = 0; 686 str += 3; 687 opcode = (struct opinfo *) hash_find (opcode_hash_control, name); 688 689 if (opcode == NULL) 690 { 691 as_bad (_("unknown opcode")); 692 return; 693 } 694 695 if (opcode->amode != ADDR_IMPLIED 696 && opcode->amode != ADDR_STACK) 697 { 698 get_operands (opcode, str); 699 opcode = get_specific (opcode); 700 } 701 702 if (opcode == 0) 703 { 704 /* Couldn't find an opcode which matched the operands. */ 705 706 char *where = frag_more (1); 707 708 where[0] = 0x0; 709 where[1] = 0x0; 710 as_bad (_("invalid operands for opcode")); 711 return; 712 } 713 714 build_Mytes (opcode); 715 } 716 717 symbolS * 718 md_undefined_symbol (name) 719 char *name ATTRIBUTE_UNUSED; 720 { 721 return 0; 722 } 723 724 /* Various routines to kill one day. */ 725 /* Equal to MAX_PRECISION in atof-ieee.c. */ 726 #define MAX_LITTLENUMS 6 727 728 /* Turn a string in input_line_pointer into a floating point constant 729 of type TYPE, and store the appropriate bytes in *LITP. The number 730 of LITTLENUMS emitted is stored in *SIZEP. An error message is 731 returned, or NULL on OK. */ 732 733 char * 734 md_atof (type, litP, sizeP) 735 char type; 736 char *litP; 737 int *sizeP; 738 { 739 int prec; 740 LITTLENUM_TYPE words[MAX_LITTLENUMS]; 741 LITTLENUM_TYPE *wordP; 742 char *t; 743 744 switch (type) 745 { 746 case 'f': 747 case 'F': 748 case 's': 749 case 'S': 750 prec = 2; 751 break; 752 753 case 'd': 754 case 'D': 755 case 'r': 756 case 'R': 757 prec = 4; 758 break; 759 760 case 'x': 761 case 'X': 762 prec = 6; 763 break; 764 765 case 'p': 766 case 'P': 767 prec = 6; 768 break; 769 770 default: 771 *sizeP = 0; 772 return _("Bad call to MD_NTOF()"); 773 } 774 t = atof_ieee (input_line_pointer, type, words); 775 if (t) 776 input_line_pointer = t; 777 778 *sizeP = prec * sizeof (LITTLENUM_TYPE); 779 for (wordP = words + prec - 1; prec--;) 780 { 781 md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE)); 782 litP += sizeof (LITTLENUM_TYPE); 783 } 784 return 0; 785 } 786 787 int 788 md_parse_option (c, a) 789 int c ATTRIBUTE_UNUSED; 790 char *a ATTRIBUTE_UNUSED; 791 { 792 return 0; 793 } 794 795 /* Called after relaxing, change the frags so they know how big they 796 are. */ 797 798 void 799 md_convert_frag (headers, seg, fragP) 800 object_headers *headers ATTRIBUTE_UNUSED; 801 segT seg ATTRIBUTE_UNUSED; 802 fragS *fragP; 803 { 804 int disp_size = 0; 805 int inst_size = 0; 806 unsigned char *buffer = 807 (unsigned char *) (fragP->fr_fix + fragP->fr_literal); 808 809 switch (fragP->fr_subtype) 810 { 811 case C (COND_BRANCH, BYTE_DISP): 812 case C (UNCOND_BRANCH, BYTE_DISP): 813 disp_size = 1; 814 inst_size = 1; 815 break; 816 817 /* Conditional branches to a known 16 bit displacement. */ 818 case C (COND_BRANCH, WORD_DISP): 819 switch (buffer[0]) 820 { 821 case OP_BCC: 822 case OP_BCS: 823 case OP_BEQ: 824 case OP_BMI: 825 case OP_BNE: 826 case OP_BPL: 827 case OP_BVS: 828 case OP_BVC: 829 /* Invert the sense of the test */ 830 buffer[0] ^= 0x20; 831 buffer[1] = 3; /* Jump over following brl */ 832 buffer[2] = OP_BRL; 833 buffer[3] = 0; 834 buffer[4] = 0; 835 disp_size = 2; 836 inst_size = 3; 837 break; 838 default: 839 abort (); 840 } 841 break; 842 case C (UNCOND_BRANCH, WORD_DISP): 843 /* Unconditional branches to a known 16 bit displacement. */ 844 845 switch (buffer[0]) 846 { 847 case OP_BRA: 848 buffer[0] = OP_BRL; 849 disp_size = 2; 850 inst_size = 1; 851 break; 852 default: 853 abort (); 854 } 855 break; 856 /* Got to create a branch over a reloc here. */ 857 case C (COND_BRANCH, UNDEF_WORD_DISP): 858 buffer[0] ^= 0x20; /* invert test */ 859 buffer[1] = 3; 860 buffer[2] = OP_BRL; 861 buffer[3] = 0; 862 buffer[4] = 0; 863 fix_new (fragP, 864 fragP->fr_fix + 3, 865 4, 866 fragP->fr_symbol, 867 fragP->fr_offset, 868 0, 869 R_W65_PCR16); 870 871 fragP->fr_fix += disp_size + inst_size; 872 fragP->fr_var = 0; 873 break; 874 case C (UNCOND_BRANCH, UNDEF_WORD_DISP): 875 buffer[0] = OP_BRL; 876 buffer[1] = 0; 877 buffer[2] = 0; 878 fix_new (fragP, 879 fragP->fr_fix + 1, 880 4, 881 fragP->fr_symbol, 882 fragP->fr_offset, 883 0, 884 R_W65_PCR16); 885 886 fragP->fr_fix += disp_size + inst_size; 887 fragP->fr_var = 0; 888 break; 889 default: 890 abort (); 891 } 892 if (inst_size) 893 { 894 /* Get the address of the end of the instruction. */ 895 int next_inst = (fragP->fr_fix + fragP->fr_address 896 + disp_size + inst_size); 897 int targ_addr = (S_GET_VALUE (fragP->fr_symbol) + 898 fragP->fr_offset); 899 int disp = targ_addr - next_inst; 900 901 md_number_to_chars (buffer + inst_size, disp, disp_size); 902 fragP->fr_fix += disp_size + inst_size; 903 fragP->fr_var = 0; 904 } 905 } 906 907 valueT 908 md_section_align (seg, size) 909 segT seg; 910 valueT size; 911 { 912 return ((size + (1 << section_alignment[(int) seg]) - 1) 913 & (-1 << section_alignment[(int) seg])); 914 } 915 916 void 917 md_apply_fix3 (fixP, valP, seg) 918 fixS *fixP; 919 valueT * valP; 920 segT seg ATTRIBUTE_UNUSED; 921 { 922 long val = * (long *) valP; 923 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; 924 int addr = fixP->fx_frag->fr_address + fixP->fx_where; 925 926 if (fixP->fx_r_type == 0) 927 { 928 if (fixP->fx_size == 1) 929 fixP->fx_r_type = R_W65_ABS8; 930 else 931 fixP->fx_r_type = R_W65_ABS16; 932 } 933 934 switch (fixP->fx_r_type) 935 { 936 case R_W65_ABS8S16: 937 val >>= 8; 938 case R_W65_ABS8S8: 939 val >>= 8; 940 case R_W65_ABS8: 941 *buf++ = val; 942 break; 943 case R_W65_ABS16S16: 944 val >>= 8; 945 case R_W65_ABS16S8: 946 val >>= 8; 947 case R_W65_ABS16: 948 *buf++ = val >> 0; 949 *buf++ = val >> 8; 950 break; 951 case R_W65_ABS24: 952 *buf++ = val >> 0; 953 *buf++ = val >> 8; 954 *buf++ = val >> 16; 955 break; 956 case R_W65_PCR8: 957 *buf++ = val - addr - 1; 958 break; 959 case R_W65_PCR16: 960 val = val - addr - 1; 961 *buf++ = val; 962 *buf++ = val >> 8; 963 break; 964 case R_W65_DP: 965 *buf++ = val; 966 break; 967 968 default: 969 abort (); 970 } 971 972 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) 973 fixP->fx_done = 1; 974 } 975 976 /* Put number into target byte order. */ 977 978 void 979 md_number_to_chars (ptr, use, nbytes) 980 char *ptr; 981 valueT use; 982 int nbytes; 983 { 984 number_to_chars_littleendian (ptr, use, nbytes); 985 } 986 987 long 988 md_pcrel_from (fixP) 989 fixS *fixP; 990 { 991 int gap = fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address - 1; 992 return gap; 993 } 994 995 void 996 tc_coff_symbol_emit_hook (x) 997 symbolS *x ATTRIBUTE_UNUSED; 998 { 999 } 1000 1001 short 1002 tc_coff_fix2rtype (fix_ptr) 1003 fixS *fix_ptr; 1004 { 1005 return fix_ptr->fx_r_type; 1006 } 1007 1008 void 1009 tc_reloc_mangle (fix_ptr, intr, base) 1010 fixS *fix_ptr; 1011 struct internal_reloc *intr; 1012 bfd_vma base; 1013 1014 { 1015 symbolS *symbol_ptr; 1016 1017 symbol_ptr = fix_ptr->fx_addsy; 1018 1019 /* If this relocation is attached to a symbol then it's ok 1020 to output it */ 1021 if (fix_ptr->fx_r_type == RELOC_32) 1022 { 1023 /* cons likes to create reloc32's whatever the size of the reloc.. 1024 */ 1025 switch (fix_ptr->fx_size) 1026 { 1027 case 2: 1028 intr->r_type = R_IMM16; 1029 break; 1030 case 1: 1031 intr->r_type = R_IMM8; 1032 break; 1033 default: 1034 abort (); 1035 } 1036 } 1037 else 1038 { 1039 if (fix_ptr->fx_size == 4) 1040 intr->r_type = R_W65_ABS24; 1041 else 1042 intr->r_type = fix_ptr->fx_r_type; 1043 } 1044 1045 intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base; 1046 intr->r_offset = fix_ptr->fx_offset; 1047 1048 /* Turn the segment of the symbol into an offset. */ 1049 if (symbol_ptr) 1050 { 1051 symbolS *dot; 1052 1053 dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot; 1054 if (dot) 1055 { 1056 intr->r_offset += S_GET_VALUE (symbol_ptr); 1057 intr->r_symndx = dot->sy_number; 1058 } 1059 else 1060 { 1061 intr->r_symndx = symbol_ptr->sy_number; 1062 } 1063 } 1064 else 1065 { 1066 intr->r_symndx = -1; 1067 } 1068 } 1069 1070 int 1071 tc_coff_sizemachdep (frag) 1072 fragS *frag; 1073 { 1074 return md_relax_table[frag->fr_subtype].rlx_length; 1075 } 1076 1077 /* Called just before address relaxation, return the length by which a 1078 fragment must grow to reach it's destination. */ 1079 1080 int 1081 md_estimate_size_before_relax (fragP, segment_type) 1082 register fragS *fragP; 1083 register segT segment_type; 1084 { 1085 int what; 1086 1087 switch (fragP->fr_subtype) 1088 { 1089 default: 1090 abort (); 1091 1092 case C (COND_BRANCH, UNDEF_BYTE_DISP): 1093 case C (UNCOND_BRANCH, UNDEF_BYTE_DISP): 1094 what = GET_WHAT (fragP->fr_subtype); 1095 /* Used to be a branch to somewhere which was unknown. */ 1096 if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type) 1097 { 1098 /* Got a symbol and it's defined in this segment, become byte 1099 sized - maybe it will fix up. */ 1100 fragP->fr_subtype = C (what, BYTE_DISP); 1101 } 1102 else 1103 { 1104 /* Its got a segment, but its not ours, so it will always be 1105 long. */ 1106 fragP->fr_subtype = C (what, UNDEF_WORD_DISP); 1107 } 1108 break; 1109 1110 case C (COND_BRANCH, BYTE_DISP): 1111 case C (COND_BRANCH, WORD_DISP): 1112 case C (COND_BRANCH, UNDEF_WORD_DISP): 1113 case C (UNCOND_BRANCH, BYTE_DISP): 1114 case C (UNCOND_BRANCH, WORD_DISP): 1115 case C (UNCOND_BRANCH, UNDEF_WORD_DISP): 1116 /* When relaxing a section for the second time, we don't need to 1117 do anything besides return the current size. */ 1118 break; 1119 } 1120 1121 fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length; 1122 return fragP->fr_var; 1123 } 1124 1125 const char *md_shortopts = ""; 1126 struct option md_longopts[] = { 1127 #define OPTION_RELAX (OPTION_MD_BASE) 1128 {NULL, no_argument, NULL, 0} 1129 }; 1130 1131 void 1132 md_show_usage (stream) 1133 FILE *stream ATTRIBUTE_UNUSED; 1134 { 1135 } 1136 1137 size_t md_longopts_size = sizeof (md_longopts); 1138