1 /* tc-pdp11.c - pdp11-specific - 2 Copyright 2001, 2002, 2004, 2005 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 18 the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 19 20 #include "as.h" 21 #include "safe-ctype.h" 22 #include "opcode/pdp11.h" 23 24 extern int flonum_gen2vax (int, FLONUM_TYPE * f, LITTLENUM_TYPE *); 25 26 #define TRUE 1 27 #define FALSE 0 28 29 /* A representation for PDP-11 machine code. */ 30 struct pdp11_code 31 { 32 char *error; 33 int code; 34 int additional; /* Is there an additional word? */ 35 int word; /* Additional word, if any. */ 36 struct 37 { 38 bfd_reloc_code_real_type type; 39 expressionS exp; 40 int pc_rel; 41 } reloc; 42 }; 43 44 /* Instruction set extensions. 45 46 If you change this from an array to something else, please update 47 the "PDP-11 instruction set extensions" comment in pdp11.h. */ 48 int pdp11_extension[PDP11_EXT_NUM]; 49 50 /* Assembly options. */ 51 52 #define ASM_OPT_PIC 1 53 #define ASM_OPT_NUM 2 54 55 int asm_option[ASM_OPT_NUM]; 56 57 /* These chars start a comment anywhere in a source file (except inside 58 another comment. */ 59 const char comment_chars[] = "#/"; 60 61 /* These chars only start a comment at the beginning of a line. */ 62 const char line_comment_chars[] = "#/"; 63 64 const char line_separator_chars[] = ";"; 65 66 /* Chars that can be used to separate mant from exp in floating point nums. */ 67 const char EXP_CHARS[] = "eE"; 68 69 /* Chars that mean this number is a floating point constant. */ 70 /* as in 0f123.456. */ 71 /* or 0H1.234E-12 (see exp chars above). */ 72 const char FLT_CHARS[] = "dDfF"; 73 74 void pseudo_even (int); 75 void pseudo_bss (int); 76 77 const pseudo_typeS md_pseudo_table[] = 78 { 79 { "bss", pseudo_bss, 0 }, 80 { "even", pseudo_even, 0 }, 81 { 0, 0, 0 }, 82 }; 83 84 static struct hash_control *insn_hash = NULL; 85 86 static int 87 set_option (char *arg) 88 { 89 int yes = 1; 90 91 if (strcmp (arg, "all-extensions") == 0 92 || strcmp (arg, "all") == 0) 93 { 94 memset (pdp11_extension, ~0, sizeof pdp11_extension); 95 pdp11_extension[PDP11_NONE] = 0; 96 return 1; 97 } 98 else if (strcmp (arg, "no-extensions") == 0) 99 { 100 memset (pdp11_extension, 0, sizeof pdp11_extension); 101 pdp11_extension[PDP11_BASIC] = 1; 102 return 1; 103 } 104 105 if (strncmp (arg, "no-", 3) == 0) 106 { 107 yes = 0; 108 arg += 3; 109 } 110 111 /* Commersial instructions. */ 112 if (strcmp (arg, "cis") == 0) 113 pdp11_extension[PDP11_CIS] = yes; 114 /* Call supervisor mode. */ 115 else if (strcmp (arg, "csm") == 0) 116 pdp11_extension[PDP11_CSM] = yes; 117 /* Extended instruction set. */ 118 else if (strcmp (arg, "eis") == 0) 119 pdp11_extension[PDP11_EIS] = pdp11_extension[PDP11_LEIS] = yes; 120 /* KEV11 floating-point. */ 121 else if (strcmp (arg, "fis") == 0 122 || strcmp (arg, "kev11") == 0 123 || strcmp (arg, "kev-11") == 0) 124 pdp11_extension[PDP11_FIS] = yes; 125 /* FP-11 floating-point. */ 126 else if (strcmp (arg, "fpp") == 0 127 || strcmp (arg, "fpu") == 0 128 || strcmp (arg, "fp11") == 0 129 || strcmp (arg, "fp-11") == 0 130 || strcmp (arg, "fpj11") == 0 131 || strcmp (arg, "fp-j11") == 0 132 || strcmp (arg, "fpj-11") == 0) 133 pdp11_extension[PDP11_FPP] = yes; 134 /* Limited extended insns. */ 135 else if (strcmp (arg, "limited-eis") == 0) 136 { 137 pdp11_extension[PDP11_LEIS] = yes; 138 if (!pdp11_extension[PDP11_LEIS]) 139 pdp11_extension[PDP11_EIS] = 0; 140 } 141 /* Move from processor type. */ 142 else if (strcmp (arg, "mfpt") == 0) 143 pdp11_extension[PDP11_MFPT] = yes; 144 /* Multiprocessor insns: */ 145 else if (strncmp (arg, "mproc", 5) == 0 146 /* TSTSET, WRTLCK */ 147 || strncmp (arg, "multiproc", 9) == 0) 148 pdp11_extension[PDP11_MPROC] = yes; 149 /* Move from/to proc status. */ 150 else if (strcmp (arg, "mxps") == 0) 151 pdp11_extension[PDP11_MXPS] = yes; 152 /* Position-independent code. */ 153 else if (strcmp (arg, "pic") == 0) 154 asm_option[ASM_OPT_PIC] = yes; 155 /* Set priority level. */ 156 else if (strcmp (arg, "spl") == 0) 157 pdp11_extension[PDP11_SPL] = yes; 158 /* Microcode instructions: */ 159 else if (strcmp (arg, "ucode") == 0 160 /* LDUB, MED, XFC */ 161 || strcmp (arg, "microcode") == 0) 162 pdp11_extension[PDP11_UCODE] = yes; 163 else 164 return 0; 165 166 return 1; 167 } 168 169 170 static void 171 init_defaults (void) 172 { 173 static int first = 1; 174 175 if (first) 176 { 177 set_option ("all-extensions"); 178 set_option ("pic"); 179 first = 0; 180 } 181 } 182 183 void 184 md_begin (void) 185 { 186 int i; 187 188 init_defaults (); 189 190 insn_hash = hash_new (); 191 if (insn_hash == NULL) 192 as_fatal ("Virtual memory exhausted"); 193 194 for (i = 0; i < pdp11_num_opcodes; i++) 195 hash_insert (insn_hash, pdp11_opcodes[i].name, (void *) (pdp11_opcodes + i)); 196 for (i = 0; i < pdp11_num_aliases; i++) 197 hash_insert (insn_hash, pdp11_aliases[i].name, (void *) (pdp11_aliases + i)); 198 } 199 200 void 201 md_number_to_chars (char con[], valueT value, int nbytes) 202 { 203 /* On a PDP-11, 0x1234 is stored as "\x12\x34", and 204 0x12345678 is stored as "\x56\x78\x12\x34". It's 205 anyones guess what 0x123456 would be stored like. */ 206 207 switch (nbytes) 208 { 209 case 0: 210 break; 211 case 1: 212 con[0] = value & 0xff; 213 break; 214 case 2: 215 con[0] = value & 0xff; 216 con[1] = (value >> 8) & 0xff; 217 break; 218 case 4: 219 con[0] = (value >> 16) & 0xff; 220 con[1] = (value >> 24) & 0xff; 221 con[2] = value & 0xff; 222 con[3] = (value >> 8) & 0xff; 223 break; 224 default: 225 BAD_CASE (nbytes); 226 } 227 } 228 229 /* Fix up some data or instructions after we find out the value of a symbol 230 that they reference. Knows about order of bytes in address. */ 231 232 void 233 md_apply_fix (fixS *fixP, 234 valueT * valP, 235 segT seg ATTRIBUTE_UNUSED) 236 { 237 valueT code; 238 valueT mask; 239 valueT val = * valP; 240 char *buf; 241 int shift; 242 int size; 243 244 buf = fixP->fx_where + fixP->fx_frag->fr_literal; 245 size = fixP->fx_size; 246 code = md_chars_to_number ((unsigned char *) buf, size); 247 248 switch (fixP->fx_r_type) 249 { 250 case BFD_RELOC_16: 251 case BFD_RELOC_16_PCREL: 252 mask = 0xffff; 253 shift = 0; 254 break; 255 case BFD_RELOC_PDP11_DISP_8_PCREL: 256 mask = 0x00ff; 257 shift = 1; 258 break; 259 case BFD_RELOC_PDP11_DISP_6_PCREL: 260 mask = 0x003f; 261 shift = 1; 262 val = -val; 263 break; 264 default: 265 BAD_CASE (fixP->fx_r_type); 266 } 267 268 if (fixP->fx_addsy != NULL) 269 val += symbol_get_bfdsym (fixP->fx_addsy)->section->vma; 270 /* *value += fixP->fx_addsy->bsym->section->vma; */ 271 272 code &= ~mask; 273 code |= (val >> shift) & mask; 274 number_to_chars_littleendian (buf, code, size); 275 276 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) 277 fixP->fx_done = 1; 278 } 279 280 long 281 md_chars_to_number (con, nbytes) 282 unsigned char con[]; /* Low order byte 1st. */ 283 int nbytes; /* Number of bytes in the input. */ 284 { 285 /* On a PDP-11, 0x1234 is stored as "\x12\x34", and 286 0x12345678 is stored as "\x56\x78\x12\x34". It's 287 anyones guess what 0x123456 would be stored like. */ 288 switch (nbytes) 289 { 290 case 0: 291 return 0; 292 case 1: 293 return con[0]; 294 case 2: 295 return (con[1] << BITS_PER_CHAR) | con[0]; 296 case 4: 297 return 298 (((con[1] << BITS_PER_CHAR) | con[0]) << (2 * BITS_PER_CHAR)) 299 |((con[3] << BITS_PER_CHAR) | con[2]); 300 default: 301 BAD_CASE (nbytes); 302 return 0; 303 } 304 } 305 306 static char * 307 skip_whitespace (char *str) 308 { 309 while (*str == ' ' || *str == '\t') 310 str++; 311 return str; 312 } 313 314 static char * 315 find_whitespace (char *str) 316 { 317 while (*str != ' ' && *str != '\t' && *str != 0) 318 str++; 319 return str; 320 } 321 322 static char * 323 parse_reg (char *str, struct pdp11_code *operand) 324 { 325 str = skip_whitespace (str); 326 if (TOLOWER (*str) == 'r') 327 { 328 str++; 329 switch (*str) 330 { 331 case '0': case '1': case '2': case '3': 332 case '4': case '5': case '6': case '7': 333 operand->code = *str - '0'; 334 str++; 335 break; 336 default: 337 operand->error = "Bad register name"; 338 return str - 1; 339 } 340 } 341 else if (strncmp (str, "sp", 2) == 0 342 || strncmp (str, "SP", 2) == 0) 343 { 344 operand->code = 6; 345 str += 2; 346 } 347 else if (strncmp (str, "pc", 2) == 0 348 || strncmp (str, "PC", 2) == 0) 349 { 350 operand->code = 7; 351 str += 2; 352 } 353 else 354 { 355 operand->error = "Bad register name"; 356 return str; 357 } 358 359 return str; 360 } 361 362 static char * 363 parse_ac5 (char *str, struct pdp11_code *operand) 364 { 365 str = skip_whitespace (str); 366 if (strncmp (str, "fr", 2) == 0 367 || strncmp (str, "FR", 2) == 0 368 || strncmp (str, "ac", 2) == 0 369 || strncmp (str, "AC", 2) == 0) 370 { 371 str += 2; 372 switch (*str) 373 { 374 case '0': case '1': case '2': case '3': 375 case '4': case '5': 376 operand->code = *str - '0'; 377 str++; 378 break; 379 default: 380 operand->error = "Bad register name"; 381 return str - 2; 382 } 383 } 384 else 385 { 386 operand->error = "Bad register name"; 387 return str; 388 } 389 390 return str; 391 } 392 393 static char * 394 parse_ac (char *str, struct pdp11_code *operand) 395 { 396 str = parse_ac5 (str, operand); 397 if (!operand->error && operand->code > 3) 398 { 399 operand->error = "Bad register name"; 400 return str - 3; 401 } 402 403 return str; 404 } 405 406 static char * 407 parse_expression (char *str, struct pdp11_code *operand) 408 { 409 char *save_input_line_pointer; 410 segT seg; 411 412 save_input_line_pointer = input_line_pointer; 413 input_line_pointer = str; 414 seg = expression (&operand->reloc.exp); 415 if (seg == NULL) 416 { 417 input_line_pointer = save_input_line_pointer; 418 operand->error = "Error in expression"; 419 return str; 420 } 421 422 str = input_line_pointer; 423 input_line_pointer = save_input_line_pointer; 424 425 operand->reloc.pc_rel = 0; 426 427 return str; 428 } 429 430 static char * 431 parse_op_no_deferred (char *str, struct pdp11_code *operand) 432 { 433 LITTLENUM_TYPE literal_float[2]; 434 435 str = skip_whitespace (str); 436 437 switch (*str) 438 { 439 case '(': /* (rn) and (rn)+ */ 440 str = parse_reg (str + 1, operand); 441 if (operand->error) 442 return str; 443 str = skip_whitespace (str); 444 if (*str != ')') 445 { 446 operand->error = "Missing ')'"; 447 return str; 448 } 449 str++; 450 if (*str == '+') 451 { 452 operand->code |= 020; 453 str++; 454 } 455 else 456 { 457 operand->code |= 010; 458 } 459 break; 460 461 /* Immediate. */ 462 case '#': 463 case '$': 464 str = parse_expression (str + 1, operand); 465 if (operand->error) 466 return str; 467 operand->additional = TRUE; 468 operand->word = operand->reloc.exp.X_add_number; 469 switch (operand->reloc.exp.X_op) 470 { 471 case O_constant: 472 break; 473 case O_symbol: 474 case O_add: 475 case O_subtract: 476 operand->reloc.type = BFD_RELOC_16; 477 operand->reloc.pc_rel = 0; 478 break; 479 case O_big: 480 if (operand->reloc.exp.X_add_number > 0) 481 { 482 operand->error = "Error in expression"; 483 break; 484 } 485 /* It's a floating literal... */ 486 know (operand->reloc.exp.X_add_number < 0); 487 flonum_gen2vax ('f', &generic_floating_point_number, literal_float); 488 operand->word = literal_float[0]; 489 if (literal_float[1] != 0) 490 as_warn (_("Low order bits truncated in immediate float operand")); 491 break; 492 default: 493 operand->error = "Error in expression"; 494 break; 495 } 496 operand->code = 027; 497 break; 498 499 /* label, d(rn), -(rn) */ 500 default: 501 { 502 char *old = str; 503 504 if (strncmp (str, "-(", 2) == 0) /* -(rn) */ 505 { 506 str = parse_reg (str + 2, operand); 507 if (operand->error) 508 return str; 509 str = skip_whitespace (str); 510 if (*str != ')') 511 { 512 operand->error = "Missing ')'"; 513 return str; 514 } 515 operand->code |= 040; 516 str++; 517 break; 518 } 519 520 str = parse_expression (str, operand); 521 if (operand->error) 522 return str; 523 524 str = skip_whitespace (str); 525 526 if (*str != '(') 527 { 528 if (operand->reloc.exp.X_op != O_symbol) 529 { 530 operand->error = "Label expected"; 531 return old; 532 } 533 operand->code = 067; 534 operand->additional = 1; 535 operand->word = 0; 536 operand->reloc.type = BFD_RELOC_16_PCREL; 537 operand->reloc.pc_rel = 1; 538 break; 539 } 540 541 /* d(rn) */ 542 str++; 543 str = parse_reg (str, operand); 544 if (operand->error) 545 return str; 546 547 str = skip_whitespace (str); 548 549 if (*str != ')') 550 { 551 operand->error = "Missing ')'"; 552 return str; 553 } 554 555 str++; 556 operand->additional = TRUE; 557 operand->code |= 060; 558 switch (operand->reloc.exp.X_op) 559 { 560 case O_symbol: 561 operand->word = 0; 562 operand->reloc.pc_rel = 1; 563 break; 564 case O_constant: 565 if ((operand->code & 7) == 7) 566 { 567 operand->reloc.pc_rel = 1; 568 operand->word = operand->reloc.exp.X_add_number; 569 } 570 else 571 operand->word = operand->reloc.exp.X_add_number; 572 573 break; 574 default: 575 BAD_CASE (operand->reloc.exp.X_op); 576 } 577 break; 578 } 579 } 580 581 return str; 582 } 583 584 static char * 585 parse_op_noreg (char *str, struct pdp11_code *operand) 586 { 587 str = skip_whitespace (str); 588 operand->error = NULL; 589 590 if (*str == '@' || *str == '*') 591 { 592 str = parse_op_no_deferred (str + 1, operand); 593 if (operand->error) 594 return str; 595 operand->code |= 010; 596 } 597 else 598 str = parse_op_no_deferred (str, operand); 599 600 return str; 601 } 602 603 static char * 604 parse_op (char *str, struct pdp11_code *operand) 605 { 606 str = skip_whitespace (str); 607 608 str = parse_reg (str, operand); 609 if (!operand->error) 610 return str; 611 612 operand->error = NULL; 613 parse_ac5 (str, operand); 614 if (!operand->error) 615 { 616 operand->error = "Float AC not legal as integer operand"; 617 return str; 618 } 619 620 return parse_op_noreg (str, operand); 621 } 622 623 static char * 624 parse_fop (char *str, struct pdp11_code *operand) 625 { 626 str = skip_whitespace (str); 627 628 str = parse_ac5 (str, operand); 629 if (!operand->error) 630 return str; 631 632 operand->error = NULL; 633 parse_reg (str, operand); 634 if (!operand->error) 635 { 636 operand->error = "General register not legal as float operand"; 637 return str; 638 } 639 640 return parse_op_noreg (str, operand); 641 } 642 643 static char * 644 parse_separator (char *str, int *error) 645 { 646 str = skip_whitespace (str); 647 *error = (*str != ','); 648 if (!*error) 649 str++; 650 return str; 651 } 652 653 void 654 md_assemble (char *instruction_string) 655 { 656 const struct pdp11_opcode *op; 657 struct pdp11_code insn, op1, op2; 658 int error; 659 int size; 660 char *err = NULL; 661 char *str; 662 char *p; 663 char c; 664 665 str = skip_whitespace (instruction_string); 666 p = find_whitespace (str); 667 if (p - str == 0) 668 { 669 as_bad ("No instruction found"); 670 return; 671 } 672 673 c = *p; 674 *p = '\0'; 675 op = (struct pdp11_opcode *)hash_find (insn_hash, str); 676 *p = c; 677 if (op == 0) 678 { 679 as_bad (_("Unknown instruction '%s'"), str); 680 return; 681 } 682 683 if (!pdp11_extension[op->extension]) 684 { 685 as_warn ("Unsupported instruction set extension: %s", op->name); 686 return; 687 } 688 689 insn.error = NULL; 690 insn.code = op->opcode; 691 insn.reloc.type = BFD_RELOC_NONE; 692 op1.error = NULL; 693 op1.additional = FALSE; 694 op1.reloc.type = BFD_RELOC_NONE; 695 op2.error = NULL; 696 op2.additional = FALSE; 697 op2.reloc.type = BFD_RELOC_NONE; 698 699 str = p; 700 size = 2; 701 702 switch (op->type) 703 { 704 case PDP11_OPCODE_NO_OPS: 705 str = skip_whitespace (str); 706 if (*str == 0) 707 str = ""; 708 break; 709 710 case PDP11_OPCODE_IMM3: 711 case PDP11_OPCODE_IMM6: 712 case PDP11_OPCODE_IMM8: 713 str = skip_whitespace (str); 714 if (*str == '#' || *str == '$') 715 str++; 716 str = parse_expression (str, &op1); 717 if (op1.error) 718 break; 719 if (op1.reloc.exp.X_op != O_constant || op1.reloc.type != BFD_RELOC_NONE) 720 { 721 op1.error = "operand is not an absolute constant"; 722 break; 723 } 724 switch (op->type) 725 { 726 case PDP11_OPCODE_IMM3: 727 if (op1.reloc.exp.X_add_number & ~7) 728 { 729 op1.error = "3-bit immediate out of range"; 730 break; 731 } 732 break; 733 case PDP11_OPCODE_IMM6: 734 if (op1.reloc.exp.X_add_number & ~0x3f) 735 { 736 op1.error = "6-bit immediate out of range"; 737 break; 738 } 739 break; 740 case PDP11_OPCODE_IMM8: 741 if (op1.reloc.exp.X_add_number & ~0xff) 742 { 743 op1.error = "8-bit immediate out of range"; 744 break; 745 } 746 break; 747 } 748 insn.code |= op1.reloc.exp.X_add_number; 749 break; 750 751 case PDP11_OPCODE_DISPL: 752 { 753 char *new; 754 new = parse_expression (str, &op1); 755 op1.code = 0; 756 op1.reloc.pc_rel = 1; 757 op1.reloc.type = BFD_RELOC_PDP11_DISP_8_PCREL; 758 if (op1.reloc.exp.X_op != O_symbol) 759 { 760 op1.error = "Symbol expected"; 761 break; 762 } 763 if (op1.code & ~0xff) 764 { 765 err = "8-bit displacement out of range"; 766 break; 767 } 768 str = new; 769 insn.code |= op1.code; 770 insn.reloc = op1.reloc; 771 } 772 break; 773 774 case PDP11_OPCODE_REG: 775 str = parse_reg (str, &op1); 776 if (op1.error) 777 break; 778 insn.code |= op1.code; 779 break; 780 781 case PDP11_OPCODE_OP: 782 str = parse_op (str, &op1); 783 if (op1.error) 784 break; 785 insn.code |= op1.code; 786 if (op1.additional) 787 size += 2; 788 break; 789 790 case PDP11_OPCODE_FOP: 791 str = parse_fop (str, &op1); 792 if (op1.error) 793 break; 794 insn.code |= op1.code; 795 if (op1.additional) 796 size += 2; 797 break; 798 799 case PDP11_OPCODE_REG_OP: 800 str = parse_reg (str, &op2); 801 if (op2.error) 802 break; 803 insn.code |= op2.code << 6; 804 str = parse_separator (str, &error); 805 if (error) 806 { 807 op2.error = "Missing ','"; 808 break; 809 } 810 str = parse_op (str, &op1); 811 if (op1.error) 812 break; 813 insn.code |= op1.code; 814 if (op1.additional) 815 size += 2; 816 break; 817 818 case PDP11_OPCODE_REG_OP_REV: 819 str = parse_op (str, &op1); 820 if (op1.error) 821 break; 822 insn.code |= op1.code; 823 if (op1.additional) 824 size += 2; 825 str = parse_separator (str, &error); 826 if (error) 827 { 828 op2.error = "Missing ','"; 829 break; 830 } 831 str = parse_reg (str, &op2); 832 if (op2.error) 833 break; 834 insn.code |= op2.code << 6; 835 break; 836 837 case PDP11_OPCODE_AC_FOP: 838 str = parse_ac (str, &op2); 839 if (op2.error) 840 break; 841 insn.code |= op2.code << 6; 842 str = parse_separator (str, &error); 843 if (error) 844 { 845 op1.error = "Missing ','"; 846 break; 847 } 848 str = parse_fop (str, &op1); 849 if (op1.error) 850 break; 851 insn.code |= op1.code; 852 if (op1.additional) 853 size += 2; 854 break; 855 856 case PDP11_OPCODE_FOP_AC: 857 str = parse_fop (str, &op1); 858 if (op1.error) 859 break; 860 insn.code |= op1.code; 861 if (op1.additional) 862 size += 2; 863 str = parse_separator (str, &error); 864 if (error) 865 { 866 op1.error = "Missing ','"; 867 break; 868 } 869 str = parse_ac (str, &op2); 870 if (op2.error) 871 break; 872 insn.code |= op2.code << 6; 873 break; 874 875 case PDP11_OPCODE_AC_OP: 876 str = parse_ac (str, &op2); 877 if (op2.error) 878 break; 879 insn.code |= op2.code << 6; 880 str = parse_separator (str, &error); 881 if (error) 882 { 883 op1.error = "Missing ','"; 884 break; 885 } 886 str = parse_op (str, &op1); 887 if (op1.error) 888 break; 889 insn.code |= op1.code; 890 if (op1.additional) 891 size += 2; 892 break; 893 894 case PDP11_OPCODE_OP_AC: 895 str = parse_op (str, &op1); 896 if (op1.error) 897 break; 898 insn.code |= op1.code; 899 if (op1.additional) 900 size += 2; 901 str = parse_separator (str, &error); 902 if (error) 903 { 904 op1.error = "Missing ','"; 905 break; 906 } 907 str = parse_ac (str, &op2); 908 if (op2.error) 909 break; 910 insn.code |= op2.code << 6; 911 break; 912 913 case PDP11_OPCODE_OP_OP: 914 str = parse_op (str, &op1); 915 if (op1.error) 916 break; 917 insn.code |= op1.code << 6; 918 if (op1.additional) 919 size += 2; 920 str = parse_separator (str, &error); 921 if (error) 922 { 923 op2.error = "Missing ','"; 924 break; 925 } 926 str = parse_op (str, &op2); 927 if (op2.error) 928 break; 929 insn.code |= op2.code; 930 if (op2.additional) 931 size += 2; 932 break; 933 934 case PDP11_OPCODE_REG_DISPL: 935 { 936 char *new; 937 str = parse_reg (str, &op2); 938 if (op2.error) 939 break; 940 insn.code |= op2.code << 6; 941 str = parse_separator (str, &error); 942 if (error) 943 { 944 op1.error = "Missing ','"; 945 break; 946 } 947 new = parse_expression (str, &op1); 948 op1.code = 0; 949 op1.reloc.pc_rel = 1; 950 op1.reloc.type = BFD_RELOC_PDP11_DISP_6_PCREL; 951 if (op1.reloc.exp.X_op != O_symbol) 952 { 953 op1.error = "Symbol expected"; 954 break; 955 } 956 if (op1.code & ~0x3f) 957 { 958 err = "6-bit displacement out of range"; 959 break; 960 } 961 str = new; 962 insn.code |= op1.code; 963 insn.reloc = op1.reloc; 964 } 965 break; 966 967 default: 968 BAD_CASE (op->type); 969 } 970 971 if (op1.error) 972 err = op1.error; 973 else if (op2.error) 974 err = op2.error; 975 else 976 { 977 str = skip_whitespace (str); 978 if (*str) 979 err = "Too many operands"; 980 } 981 982 { 983 char *to = NULL; 984 985 if (err) 986 { 987 as_bad (err); 988 return; 989 } 990 991 to = frag_more (size); 992 993 md_number_to_chars (to, insn.code, 2); 994 if (insn.reloc.type != BFD_RELOC_NONE) 995 fix_new_exp (frag_now, to - frag_now->fr_literal, 2, 996 &insn.reloc.exp, insn.reloc.pc_rel, insn.reloc.type); 997 to += 2; 998 999 if (op1.additional) 1000 { 1001 md_number_to_chars (to, op1.word, 2); 1002 if (op1.reloc.type != BFD_RELOC_NONE) 1003 fix_new_exp (frag_now, to - frag_now->fr_literal, 2, 1004 &op1.reloc.exp, op1.reloc.pc_rel, op1.reloc.type); 1005 to += 2; 1006 } 1007 1008 if (op2.additional) 1009 { 1010 md_number_to_chars (to, op2.word, 2); 1011 if (op2.reloc.type != BFD_RELOC_NONE) 1012 fix_new_exp (frag_now, to - frag_now->fr_literal, 2, 1013 &op2.reloc.exp, op2.reloc.pc_rel, op2.reloc.type); 1014 } 1015 } 1016 } 1017 1018 int 1019 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED, 1020 segT segment ATTRIBUTE_UNUSED) 1021 { 1022 return 0; 1023 } 1024 1025 void 1026 md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, 1027 segT seg ATTRIBUTE_UNUSED, 1028 fragS *fragP ATTRIBUTE_UNUSED) 1029 { 1030 } 1031 1032 int md_short_jump_size = 2; 1033 int md_long_jump_size = 4; 1034 1035 void 1036 md_create_short_jump (char *ptr ATTRIBUTE_UNUSED, 1037 addressT from_addr ATTRIBUTE_UNUSED, 1038 addressT to_addr ATTRIBUTE_UNUSED, 1039 fragS *frag ATTRIBUTE_UNUSED, 1040 symbolS *to_symbol ATTRIBUTE_UNUSED) 1041 { 1042 } 1043 1044 void 1045 md_create_long_jump (char *ptr ATTRIBUTE_UNUSED, 1046 addressT from_addr ATTRIBUTE_UNUSED, 1047 addressT to_addr ATTRIBUTE_UNUSED, 1048 fragS *frag ATTRIBUTE_UNUSED, 1049 symbolS *to_symbol ATTRIBUTE_UNUSED) 1050 { 1051 } 1052 1053 static int 1054 set_cpu_model (char *arg) 1055 { 1056 char buf[4]; 1057 char *model = buf; 1058 1059 if (arg[0] == 'k') 1060 arg++; 1061 1062 *model++ = *arg++; 1063 1064 if (strchr ("abdx", model[-1]) == NULL) 1065 return 0; 1066 1067 if (model[-1] == 'd') 1068 { 1069 if (arg[0] == 'f' || arg[0] == 'j') 1070 model[-1] = *arg++; 1071 } 1072 else if (model[-1] == 'x') 1073 { 1074 if (arg[0] == 't') 1075 model[-1] = *arg++; 1076 } 1077 1078 if (arg[0] == '-') 1079 arg++; 1080 1081 if (strncmp (arg, "11", 2) != 0) 1082 return 0; 1083 arg += 2; 1084 1085 if (arg[0] == '-') 1086 { 1087 if (*++arg == 0) 1088 return 0; 1089 } 1090 1091 /* Allow up to two revision letters. */ 1092 if (arg[0] != 0) 1093 *model++ = *arg++; 1094 if (arg[0] != 0) 1095 *model++ = *arg++; 1096 1097 *model++ = 0; 1098 1099 set_option ("no-extensions"); 1100 1101 /* KA11 (11/15/20). */ 1102 if (strncmp (buf, "a", 1) == 0) 1103 return 1; /* No extensions. */ 1104 1105 /* KB11 (11/45/50/55/70). */ 1106 else if (strncmp (buf, "b", 1) == 0) 1107 return set_option ("eis") && set_option ("spl"); 1108 1109 /* KD11-A (11/35/40). */ 1110 else if (strncmp (buf, "da", 2) == 0) 1111 return set_option ("limited-eis"); 1112 1113 /* KD11-B (11/05/10). */ 1114 else if (strncmp (buf, "db", 2) == 0 1115 /* KD11-D (11/04). */ 1116 || strncmp (buf, "dd", 2) == 0) 1117 return 1; /* no extensions */ 1118 1119 /* KD11-E (11/34). */ 1120 else if (strncmp (buf, "de", 2) == 0) 1121 return set_option ("eis") && set_option ("mxps"); 1122 1123 /* KD11-F (11/03). */ 1124 else if (strncmp (buf, "df", 2) == 0 1125 /* KD11-H (11/03). */ 1126 || strncmp (buf, "dh", 2) == 0 1127 /* KD11-Q (11/03). */ 1128 || strncmp (buf, "dq", 2) == 0) 1129 return set_option ("limited-eis") && set_option ("mxps"); 1130 1131 /* KD11-K (11/60). */ 1132 else if (strncmp (buf, "dk", 2) == 0) 1133 return set_option ("eis") 1134 && set_option ("mxps") 1135 && set_option ("ucode"); 1136 1137 /* KD11-Z (11/44). */ 1138 else if (strncmp (buf, "dz", 2) == 0) 1139 return set_option ("csm") 1140 && set_option ("eis") 1141 && set_option ("mfpt") 1142 && set_option ("mxps") 1143 && set_option ("spl"); 1144 1145 /* F11 (11/23/24). */ 1146 else if (strncmp (buf, "f", 1) == 0) 1147 return set_option ("eis") 1148 && set_option ("mfpt") 1149 && set_option ("mxps"); 1150 1151 /* J11 (11/53/73/83/84/93/94). */ 1152 else if (strncmp (buf, "j", 1) == 0) 1153 return set_option ("csm") 1154 && set_option ("eis") 1155 && set_option ("mfpt") 1156 && set_option ("multiproc") 1157 && set_option ("mxps") 1158 && set_option ("spl"); 1159 1160 /* T11 (11/21). */ 1161 else if (strncmp (buf, "t", 1) == 0) 1162 return set_option ("limited-eis") 1163 && set_option ("mxps"); 1164 1165 else 1166 return 0; 1167 } 1168 1169 static int 1170 set_machine_model (char *arg) 1171 { 1172 if (strncmp (arg, "pdp-11/", 7) != 0 1173 && strncmp (arg, "pdp11/", 6) != 0 1174 && strncmp (arg, "11/", 3) != 0) 1175 return 0; 1176 1177 if (strncmp (arg, "pdp", 3) == 0) 1178 arg += 3; 1179 if (arg[0] == '-') 1180 arg++; 1181 if (strncmp (arg, "11/", 3) == 0) 1182 arg += 3; 1183 1184 if (strcmp (arg, "03") == 0) 1185 return set_cpu_model ("kd11f"); 1186 1187 else if (strcmp (arg, "04") == 0) 1188 return set_cpu_model ("kd11d"); 1189 1190 else if (strcmp (arg, "05") == 0 1191 || strcmp (arg, "10") == 0) 1192 return set_cpu_model ("kd11b"); 1193 1194 else if (strcmp (arg, "15") == 0 1195 || strcmp (arg, "20") == 0) 1196 return set_cpu_model ("ka11"); 1197 1198 else if (strcmp (arg, "21") == 0) 1199 return set_cpu_model ("t11"); 1200 1201 else if (strcmp (arg, "23") == 0 1202 || strcmp (arg, "24") == 0) 1203 return set_cpu_model ("f11"); 1204 1205 else if (strcmp (arg, "34") == 0 1206 || strcmp (arg, "34a") == 0) 1207 return set_cpu_model ("kd11e"); 1208 1209 else if (strcmp (arg, "35") == 0 1210 || strcmp (arg, "40") == 0) 1211 return set_cpu_model ("kd11da"); 1212 1213 else if (strcmp (arg, "44") == 0) 1214 return set_cpu_model ("kd11dz"); 1215 1216 else if (strcmp (arg, "45") == 0 1217 || strcmp (arg, "50") == 0 1218 || strcmp (arg, "55") == 0 1219 || strcmp (arg, "70") == 0) 1220 return set_cpu_model ("kb11"); 1221 1222 else if (strcmp (arg, "60") == 0) 1223 return set_cpu_model ("kd11k"); 1224 1225 else if (strcmp (arg, "53") == 0 1226 || strcmp (arg, "73") == 0 1227 || strcmp (arg, "83") == 0 1228 || strcmp (arg, "84") == 0 1229 || strcmp (arg, "93") == 0 1230 || strcmp (arg, "94") == 0) 1231 return set_cpu_model ("j11") 1232 && set_option ("fpp"); 1233 1234 else 1235 return 0; 1236 } 1237 1238 const char *md_shortopts = "m:"; 1239 1240 struct option md_longopts[] = 1241 { 1242 #define OPTION_CPU 257 1243 { "cpu", required_argument, NULL, OPTION_CPU }, 1244 #define OPTION_MACHINE 258 1245 { "machine", required_argument, NULL, OPTION_MACHINE }, 1246 #define OPTION_PIC 259 1247 { "pic", no_argument, NULL, OPTION_PIC }, 1248 { NULL, no_argument, NULL, 0 } 1249 }; 1250 1251 size_t md_longopts_size = sizeof (md_longopts); 1252 1253 /* Invocation line includes a switch not recognized by the base assembler. 1254 See if it's a processor-specific option. */ 1255 1256 int 1257 md_parse_option (int c, char *arg) 1258 { 1259 init_defaults (); 1260 1261 switch (c) 1262 { 1263 case 'm': 1264 if (set_option (arg)) 1265 return 1; 1266 if (set_cpu_model (arg)) 1267 return 1; 1268 if (set_machine_model (arg)) 1269 return 1; 1270 break; 1271 1272 case OPTION_CPU: 1273 if (set_cpu_model (arg)) 1274 return 1; 1275 break; 1276 1277 case OPTION_MACHINE: 1278 if (set_machine_model (arg)) 1279 return 1; 1280 break; 1281 1282 case OPTION_PIC: 1283 if (set_option ("pic")) 1284 return 1; 1285 break; 1286 1287 default: 1288 break; 1289 } 1290 1291 return 0; 1292 } 1293 1294 void 1295 md_show_usage (FILE *stream) 1296 { 1297 fprintf (stream, "\ 1298 \n\ 1299 PDP-11 instruction set extentions:\n\ 1300 \n\ 1301 -m(no-)cis allow (disallow) commersial instruction set\n\ 1302 -m(no-)csm allow (disallow) CSM instruction\n\ 1303 -m(no-)eis allow (disallow) full extended instruction set\n\ 1304 -m(no-)fis allow (disallow) KEV11 floating-point instructions\n\ 1305 -m(no-)fpp allow (disallow) FP-11 floating-point instructions\n\ 1306 -m(no-)fpu allow (disallow) FP-11 floating-point instructions\n\ 1307 -m(no-)limited-eis allow (disallow) limited extended instruction set\n\ 1308 -m(no-)mfpt allow (disallow) processor type instruction\n\ 1309 -m(no-)multiproc allow (disallow) multiprocessor instructions\n\ 1310 -m(no-)mxps allow (disallow) processor status instructions\n\ 1311 -m(no-)spl allow (disallow) SPL instruction\n\ 1312 -m(no-)ucode allow (disallow) microcode instructions\n\ 1313 -mall-extensions allow all instruction set extensions\n\ 1314 (this is the default)\n\ 1315 -mno-extentions disallow all instruction set extensions\n\ 1316 -pic generate position-indepenent code\n\ 1317 \n\ 1318 PDP-11 CPU model options:\n\ 1319 \n\ 1320 -mka11* KA11 CPU. base line instruction set only\n\ 1321 -mkb11* KB11 CPU. enable full EIS and SPL\n\ 1322 -mkd11a* KD11-A CPU. enable limited EIS\n\ 1323 -mkd11b* KD11-B CPU. base line instruction set only\n\ 1324 -mkd11d* KD11-D CPU. base line instruction set only\n\ 1325 -mkd11e* KD11-E CPU. enable full EIS, MTPS, and MFPS\n\ 1326 -mkd11f* KD11-F CPU. enable limited EIS, MTPS, and MFPS\n\ 1327 -mkd11h* KD11-H CPU. enable limited EIS, MTPS, and MFPS\n\ 1328 -mkd11q* KD11-Q CPU. enable limited EIS, MTPS, and MFPS\n\ 1329 -mkd11k* KD11-K CPU. enable full EIS, MTPS, MFPS, LDUB, MED,\n\ 1330 XFC, and MFPT\n\ 1331 -mkd11z* KD11-Z CPU. enable full EIS, MTPS, MFPS, MFPT, SPL,\n\ 1332 and CSM\n\ 1333 -mf11* F11 CPU. enable full EIS, MFPS, MTPS, and MFPT\n\ 1334 -mj11* J11 CPU. enable full EIS, MTPS, MFPS, MFPT, SPL,\n\ 1335 CSM, TSTSET, and WRTLCK\n\ 1336 -mt11* T11 CPU. enable limited EIS, MTPS, and MFPS\n\ 1337 \n\ 1338 PDP-11 machine model options:\n\ 1339 \n\ 1340 -m11/03 same as -mkd11f\n\ 1341 -m11/04 same as -mkd11d\n\ 1342 -m11/05 same as -mkd11b\n\ 1343 -m11/10 same as -mkd11b\n\ 1344 -m11/15 same as -mka11\n\ 1345 -m11/20 same as -mka11\n\ 1346 -m11/21 same as -mt11\n\ 1347 -m11/23 same as -mf11\n\ 1348 -m11/24 same as -mf11\n\ 1349 -m11/34 same as -mkd11e\n\ 1350 -m11/34a same as -mkd11e -mfpp\n\ 1351 -m11/35 same as -mkd11a\n\ 1352 -m11/40 same as -mkd11a\n\ 1353 -m11/44 same as -mkd11z\n\ 1354 -m11/45 same as -mkb11\n\ 1355 -m11/50 same as -mkb11\n\ 1356 -m11/53 same as -mj11\n\ 1357 -m11/55 same as -mkb11\n\ 1358 -m11/60 same as -mkd11k\n\ 1359 -m11/70 same as -mkb11\n\ 1360 -m11/73 same as -mj11\n\ 1361 -m11/83 same as -mj11\n\ 1362 -m11/84 same as -mj11\n\ 1363 -m11/93 same as -mj11\n\ 1364 -m11/94 same as -mj11\n\ 1365 "); 1366 } 1367 1368 symbolS * 1369 md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 1370 { 1371 return 0; 1372 } 1373 1374 valueT 1375 md_section_align (segT segment ATTRIBUTE_UNUSED, 1376 valueT size) 1377 { 1378 return (size + 1) & ~1; 1379 } 1380 1381 long 1382 md_pcrel_from (fixS *fixP) 1383 { 1384 return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size; 1385 } 1386 1387 /* Translate internal representation of relocation info to BFD target 1388 format. */ 1389 1390 arelent * 1391 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, 1392 fixS *fixp) 1393 { 1394 arelent *reloc; 1395 bfd_reloc_code_real_type code; 1396 1397 reloc = xmalloc (sizeof (* reloc)); 1398 1399 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); 1400 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 1401 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 1402 1403 /* This is taken account for in md_apply_fix(). */ 1404 reloc->addend = -symbol_get_bfdsym (fixp->fx_addsy)->section->vma; 1405 1406 switch (fixp->fx_r_type) 1407 { 1408 case BFD_RELOC_16: 1409 if (fixp->fx_pcrel) 1410 code = BFD_RELOC_16_PCREL; 1411 else 1412 code = BFD_RELOC_16; 1413 break; 1414 1415 case BFD_RELOC_16_PCREL: 1416 code = BFD_RELOC_16_PCREL; 1417 break; 1418 1419 default: 1420 BAD_CASE (fixp->fx_r_type); 1421 return NULL; 1422 } 1423 1424 reloc->howto = bfd_reloc_type_lookup (stdoutput, code); 1425 1426 if (reloc->howto == NULL) 1427 { 1428 as_bad_where (fixp->fx_file, fixp->fx_line, 1429 "Can not represent %s relocation in this object file format", 1430 bfd_get_reloc_code_name (code)); 1431 return NULL; 1432 } 1433 1434 return reloc; 1435 } 1436 1437 void 1438 pseudo_bss (int c ATTRIBUTE_UNUSED) 1439 { 1440 int temp; 1441 1442 temp = get_absolute_expression (); 1443 subseg_set (bss_section, temp); 1444 demand_empty_rest_of_line (); 1445 } 1446 1447 void 1448 pseudo_even (int c ATTRIBUTE_UNUSED) 1449 { 1450 int alignment = 1; /* 2^1 */ 1451 frag_align (alignment, 0, 1); 1452 record_alignment (now_seg, alignment); 1453 } 1454