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