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