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