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