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