]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/tc-pdp11.c
Fixes for the encoding and decoding of the PDP11's SOB instruction
[thirdparty/binutils-gdb.git] / gas / config / tc-pdp11.c
1 /* tc-pdp11.c - pdp11-specific -
2 Copyright 2001, 2002, 2004 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 2, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20 /*
21 Apparently unused functions:
22 md_convert_frag
23 md_estimate_size_before_relax
24 md_create_short_jump
25 md_create_long_jump
26 */
27
28 #include "as.h"
29 #include "safe-ctype.h"
30 #include "opcode/pdp11.h"
31
32 static int set_option PARAMS ((char *arg));
33 static int set_cpu_model PARAMS ((char *arg));
34 static int set_machine_model PARAMS ((char *arg));
35
36 extern int flonum_gen2vax PARAMS ((char format_letter, FLONUM_TYPE * f,
37 LITTLENUM_TYPE * words));
38
39 #define TRUE 1
40 #define FALSE 0
41
42 /*
43 * A representation for PDP-11 machine code.
44 */
45 struct pdp11_code
46 {
47 char *error;
48 int code;
49 int additional; /* is there an additional word? */
50 int word; /* additional word, if any */
51 struct
52 {
53 bfd_reloc_code_real_type type;
54 expressionS exp;
55 int pc_rel;
56 } reloc;
57 };
58
59 /*
60 * Instruction set extensions.
61 *
62 * If you change this from an array to something else, please update
63 * the "PDP-11 instruction set extensions" comment in pdp11.h.
64 */
65 int pdp11_extension[PDP11_EXT_NUM];
66
67 /*
68 * Assembly options.
69 */
70
71 #define ASM_OPT_PIC 1
72 #define ASM_OPT_NUM 2
73
74 int asm_option[ASM_OPT_NUM];
75
76 /* These chars start a comment anywhere in a source file (except inside
77 another comment */
78 const char comment_chars[] = "#/";
79
80 /* These chars only start a comment at the beginning of a line. */
81 const char line_comment_chars[] = "#/";
82
83 const char line_separator_chars[] = ";";
84
85 /* Chars that can be used to separate mant from exp in floating point nums */
86 const char EXP_CHARS[] = "eE";
87
88 /* Chars that mean this number is a floating point constant */
89 /* as in 0f123.456 */
90 /* or 0H1.234E-12 (see exp chars above) */
91 const char FLT_CHARS[] = "dDfF";
92
93 void pseudo_even (int);
94 void pseudo_bss (int);
95
96 const pseudo_typeS md_pseudo_table[] =
97 {
98 { "bss", pseudo_bss, 0 },
99 { "even", pseudo_even, 0 },
100 { 0, 0, 0 },
101 };
102
103 static void
104 init_defaults ()
105 {
106 static int first = 1;
107
108 if (first)
109 {
110 set_option ("all-extensions");
111 set_option ("pic");
112 first = 0;
113 }
114 }
115
116 static struct hash_control *insn_hash = NULL;
117
118 void
119 md_begin ()
120 {
121 int i;
122
123 init_defaults ();
124
125 insn_hash = hash_new ();
126 if (insn_hash == NULL)
127 as_fatal ("Virtual memory exhausted");
128
129 for (i = 0; i < pdp11_num_opcodes; i++)
130 hash_insert (insn_hash, pdp11_opcodes[i].name, (PTR)(pdp11_opcodes + i));
131 for (i = 0; i < pdp11_num_aliases; i++)
132 hash_insert (insn_hash, pdp11_aliases[i].name, (PTR)(pdp11_aliases + i));
133 }
134
135 void
136 md_number_to_chars (con, value, nbytes)
137 char con[];
138 valueT value;
139 int nbytes;
140 {
141 /* On a PDP-11, 0x1234 is stored as "\x12\x34", and
142 * 0x12345678 is stored as "\x56\x78\x12\x34". It's
143 * anyones guess what 0x123456 would be stored like.
144 */
145
146 switch (nbytes)
147 {
148 case 0:
149 break;
150 case 1:
151 con[0] = value & 0xff;
152 break;
153 case 2:
154 con[0] = value & 0xff;
155 con[1] = (value >> 8) & 0xff;
156 break;
157 case 4:
158 con[0] = (value >> 16) & 0xff;
159 con[1] = (value >> 24) & 0xff;
160 con[2] = value & 0xff;
161 con[3] = (value >> 8) & 0xff;
162 break;
163 default:
164 BAD_CASE (nbytes);
165 }
166 }
167
168 /* Fix up some data or instructions after we find out the value of a symbol
169 that they reference. Knows about order of bytes in address. */
170
171 void
172 md_apply_fix3 (fixP, valP, seg)
173 fixS *fixP;
174 valueT * valP;
175 segT seg ATTRIBUTE_UNUSED;
176 {
177 valueT code;
178 valueT mask;
179 valueT val = * valP;
180 char *buf;
181 int shift;
182 int size;
183
184 buf = fixP->fx_where + fixP->fx_frag->fr_literal;
185 size = fixP->fx_size;
186 code = md_chars_to_number (buf, size);
187
188 switch (fixP->fx_r_type)
189 {
190 case BFD_RELOC_16:
191 case BFD_RELOC_16_PCREL:
192 mask = 0xffff;
193 shift = 0;
194 break;
195 case BFD_RELOC_PDP11_DISP_8_PCREL:
196 mask = 0x00ff;
197 shift = 1;
198 break;
199 case BFD_RELOC_PDP11_DISP_6_PCREL:
200 mask = 0x003f;
201 shift = 1;
202 val = -val;
203 break;
204 default:
205 BAD_CASE (fixP->fx_r_type);
206 }
207
208 if (fixP->fx_addsy != NULL)
209 val += symbol_get_bfdsym (fixP->fx_addsy)->section->vma;
210 /* *value += fixP->fx_addsy->bsym->section->vma; */
211
212 code &= ~mask;
213 code |= (val >> shift) & mask;
214 number_to_chars_littleendian (buf, code, size);
215
216 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
217 fixP->fx_done = 1;
218 }
219
220 long
221 md_chars_to_number (con, nbytes)
222 unsigned char con[]; /* Low order byte 1st. */
223 int nbytes; /* Number of bytes in the input. */
224 {
225 /* On a PDP-11, 0x1234 is stored as "\x12\x34", and
226 * 0x12345678 is stored as "\x56\x78\x12\x34". It's
227 * anyones guess what 0x123456 would be stored like.
228 */
229
230 switch (nbytes)
231 {
232 case 0:
233 return 0;
234 case 1:
235 return con[0];
236 case 2:
237 return (con[1] << BITS_PER_CHAR) | con[0];
238 case 4:
239 return
240 (((con[1] << BITS_PER_CHAR) | con[0]) << (2 * BITS_PER_CHAR)) |
241 ((con[3] << BITS_PER_CHAR) | con[2]);
242 default:
243 BAD_CASE (nbytes);
244 return 0;
245 }
246 }
247 \f
248 static char *
249 skip_whitespace (char *str)
250 {
251 while (*str == ' ' || *str == '\t')
252 str++;
253 return str;
254 }
255
256 static char *
257 find_whitespace (char *str)
258 {
259 while (*str != ' ' && *str != '\t' && *str != 0)
260 str++;
261 return str;
262 }
263
264 static char *
265 parse_reg (char *str, struct pdp11_code *operand)
266 {
267 str = skip_whitespace (str);
268 if (TOLOWER (*str) == 'r')
269 {
270 str++;
271 switch (*str)
272 {
273 case '0': case '1': case '2': case '3':
274 case '4': case '5': case '6': case '7':
275 operand->code = *str - '0';
276 str++;
277 break;
278 default:
279 operand->error = "Bad register name";
280 return str - 1;
281 }
282 }
283 else if (strncmp (str, "sp", 2) == 0 ||
284 strncmp (str, "SP", 2) == 0)
285 {
286 operand->code = 6;
287 str += 2;
288 }
289 else if (strncmp (str, "pc", 2) == 0 ||
290 strncmp (str, "PC", 2) == 0)
291 {
292 operand->code = 7;
293 str += 2;
294 }
295 else
296 {
297 operand->error = "Bad register name";
298 return str;
299 }
300
301 return str;
302 }
303
304 static char *
305 parse_ac5 (char *str, struct pdp11_code *operand)
306 {
307 str = skip_whitespace (str);
308 if (strncmp (str, "fr", 2) == 0 ||
309 strncmp (str, "FR", 2) == 0 ||
310 strncmp (str, "ac", 2) == 0 ||
311 strncmp (str, "AC", 2) == 0)
312 {
313 str += 2;
314 switch (*str)
315 {
316 case '0': case '1': case '2': case '3':
317 case '4': case '5':
318 operand->code = *str - '0';
319 str++;
320 break;
321 default:
322 operand->error = "Bad register name";
323 return str - 2;
324 }
325 }
326 else
327 {
328 operand->error = "Bad register name";
329 return str;
330 }
331
332 return str;
333 }
334
335 static char *
336 parse_ac (char *str, struct pdp11_code *operand)
337 {
338 str = parse_ac5 (str, operand);
339 if (!operand->error && operand->code > 3)
340 {
341 operand->error = "Bad register name";
342 return str - 3;
343 }
344
345 return str;
346 }
347
348 static char *
349 parse_expression (char *str, struct pdp11_code *operand)
350 {
351 char *save_input_line_pointer;
352 segT seg;
353
354 save_input_line_pointer = input_line_pointer;
355 input_line_pointer = str;
356 seg = expression (&operand->reloc.exp);
357 if (seg == NULL)
358 {
359 input_line_pointer = save_input_line_pointer;
360 operand->error = "Error in expression";
361 return str;
362 }
363
364 str = input_line_pointer;
365 input_line_pointer = save_input_line_pointer;
366
367 operand->reloc.pc_rel = 0;
368
369 #if 0
370 /* FIXME: what follows is broken badly. You can't deal with differences
371 in radix conventions this way, because of symbolic constants, constant
372 expressions made up of pieces of differing radix, etc. The only
373 choices are to change ../expr.c to know about pdp11 conventions, or
374 to accept the fact that gas will use consistent conventions that differ
375 from those of traditional pdp11 assemblers. For now, I've
376 chosen the latter. paul koning, 12/23/2001
377 */
378 if (operand->reloc.exp.X_op == O_constant)
379 {
380 if (*str == '.')
381 str++;
382 else
383 {
384 /* FIXME: buffer overflow! */
385 char buf[100];
386 char *end;
387
388 sprintf (buf, "%ld", operand->reloc.exp.X_add_number);
389 operand->reloc.exp.X_add_number = strtol (buf, &end, 8);
390 }
391 }
392 #endif
393 return str;
394 }
395
396 static char *
397 parse_op_no_deferred (char *str, struct pdp11_code *operand)
398 {
399 LITTLENUM_TYPE literal_float[2];
400
401 str = skip_whitespace (str);
402
403 switch (*str)
404 {
405 case '(': /* (rn) and (rn)+ */
406 str = parse_reg (str + 1, operand);
407 if (operand->error)
408 return str;
409 str = skip_whitespace (str);
410 if (*str != ')')
411 {
412 operand->error = "Missing ')'";
413 return str;
414 }
415 str++;
416 if (*str == '+')
417 {
418 operand->code |= 020;
419 str++;
420 }
421 else
422 {
423 operand->code |= 010;
424 }
425 break;
426
427 case '#': /* immediate */
428 case '$':
429 str = parse_expression (str + 1, operand);
430 if (operand->error)
431 return str;
432 operand->additional = TRUE;
433 operand->word = operand->reloc.exp.X_add_number;
434 switch (operand->reloc.exp.X_op)
435 {
436 case O_constant:
437 break;
438 case O_symbol:
439 case O_add:
440 case O_subtract:
441 operand->reloc.type = BFD_RELOC_16;
442 operand->reloc.pc_rel = 0;
443 break;
444 case O_big:
445 if (operand->reloc.exp.X_add_number > 0)
446 {
447 operand->error = "Error in expression";
448 break;
449 }
450 /* it's a floating literal... */
451 know (operand->reloc.exp.X_add_number < 0);
452 flonum_gen2vax ('f', &generic_floating_point_number, literal_float);
453 operand->word = literal_float[0];
454 if (literal_float[1] != 0)
455 as_warn (_("Low order bits truncated in immediate float operand"));
456 break;
457 default:
458 operand->error = "Error in expression";
459 break;
460 }
461 operand->code = 027;
462 break;
463
464 default: /* label, d(rn), -(rn) */
465 {
466 char *old = str;
467
468 if (strncmp (str, "-(", 2) == 0) /* -(rn) */
469 {
470 str = parse_reg (str + 2, operand);
471 if (operand->error)
472 return str;
473 str = skip_whitespace (str);
474 if (*str != ')')
475 {
476 operand->error = "Missing ')'";
477 return str;
478 }
479 operand->code |= 040;
480 str++;
481 break;
482 }
483
484 str = parse_expression (str, operand);
485 if (operand->error)
486 return str;
487
488 str = skip_whitespace (str);
489
490 if (*str != '(') /* label */
491 {
492 if (operand->reloc.exp.X_op != O_symbol)
493 {
494 operand->error = "Label expected";
495 return old;
496 }
497 operand->code = 067;
498 operand->additional = 1;
499 operand->word = 0;
500 operand->reloc.type = BFD_RELOC_16_PCREL;
501 operand->reloc.pc_rel = 1;
502 break;
503 }
504
505 str++; /* d(rn) */
506 str = parse_reg (str, operand);
507 if (operand->error)
508 return str;
509
510 str = skip_whitespace (str);
511
512 if (*str != ')')
513 {
514 operand->error = "Missing ')'";
515 return str;
516 }
517
518 str++;
519 operand->additional = TRUE;
520 operand->code |= 060;
521 switch (operand->reloc.exp.X_op)
522 {
523 case O_symbol:
524 operand->word = 0;
525 operand->reloc.pc_rel = 1;
526 break;
527 case O_constant:
528 if ((operand->code & 7) == 7)
529 {
530 operand->reloc.pc_rel = 1;
531 operand->word = operand->reloc.exp.X_add_number;
532 }
533 else
534 {
535 operand->word = operand->reloc.exp.X_add_number;
536 }
537 break;
538 default:
539 BAD_CASE (operand->reloc.exp.X_op);
540 }
541 break;
542 }
543 }
544
545 return str;
546 }
547
548 static char *
549 parse_op_noreg (char *str, struct pdp11_code *operand)
550 {
551 str = skip_whitespace (str);
552 operand->error = NULL;
553
554 if (*str == '@' || *str == '*')
555 {
556 str = parse_op_no_deferred (str + 1, operand);
557 if (operand->error)
558 return str;
559 operand->code |= 010;
560 }
561 else
562 str = parse_op_no_deferred (str, operand);
563
564 return str;
565 }
566
567 static char *
568 parse_op (char *str, struct pdp11_code *operand)
569 {
570 str = skip_whitespace (str);
571
572 str = parse_reg (str, operand);
573 if (!operand->error)
574 return str;
575
576 operand->error = NULL;
577 parse_ac5 (str, operand);
578 if (!operand->error)
579 {
580 operand->error = "Float AC not legal as integer operand";
581 return str;
582 }
583
584 return parse_op_noreg (str, operand);
585 }
586
587 static char *
588 parse_fop (char *str, struct pdp11_code *operand)
589 {
590 str = skip_whitespace (str);
591
592 str = parse_ac5 (str, operand);
593 if (!operand->error)
594 return str;
595
596 operand->error = NULL;
597 parse_reg (str, operand);
598 if (!operand->error)
599 {
600 operand->error = "General register not legal as float operand";
601 return str;
602 }
603
604 return parse_op_noreg (str, operand);
605 }
606
607 static char *
608 parse_separator (char *str, int *error)
609 {
610 str = skip_whitespace (str);
611 *error = (*str != ',');
612 if (!*error)
613 str++;
614 return str;
615 }
616
617 void
618 md_assemble (instruction_string)
619 char *instruction_string;
620 {
621 const struct pdp11_opcode *op;
622 struct pdp11_code insn, op1, op2;
623 int error;
624 int size;
625 char *err = NULL;
626 char *str;
627 char *p;
628 char c;
629
630 str = skip_whitespace (instruction_string);
631 p = find_whitespace (str);
632 if (p - str == 0)
633 {
634 as_bad ("No instruction found");
635 return;
636 }
637
638 c = *p;
639 *p = '\0';
640 op = (struct pdp11_opcode *)hash_find (insn_hash, str);
641 *p = c;
642 if (op == 0)
643 {
644 #if 0
645 op1.error = NULL;
646 op1.additional = FALSE;
647 op1.reloc.type = BFD_RELOC_NONE;
648 op1.code = 0;
649 op1.word = 0;
650 str = parse_expression (str, &op1);
651 if (op1.error)
652 {
653 as_bad (op1.error);
654 return;
655 }
656
657 {
658 char *to = frag_more (2);
659
660 md_number_to_chars (to, op1.code, 2);
661 if (insn.reloc.type != BFD_RELOC_NONE)
662 fix_new_exp (frag_now, to - frag_now->fr_literal, 2,
663 &insn.reloc.exp, insn.reloc.pc_rel, insn.reloc.type);
664 }
665 #else
666 as_bad (_("Unknown instruction '%s'"), str);
667 #endif
668
669 return;
670 }
671
672 if (!pdp11_extension[op->extension])
673 {
674 as_warn ("Unsupported instruction set extension: %s", op->name);
675 return;
676 }
677
678 insn.error = NULL;
679 insn.code = op->opcode;
680 insn.reloc.type = BFD_RELOC_NONE;
681 op1.error = NULL;
682 op1.additional = FALSE;
683 op1.reloc.type = BFD_RELOC_NONE;
684 op2.error = NULL;
685 op2.additional = FALSE;
686 op2.reloc.type = BFD_RELOC_NONE;
687
688 str = p;
689 size = 2;
690
691 switch (op->type)
692 {
693 case PDP11_OPCODE_NO_OPS:
694 str = skip_whitespace (str);
695 if (*str == 0)
696 str = "";
697 break;
698
699 case PDP11_OPCODE_IMM3:
700 case PDP11_OPCODE_IMM6:
701 case PDP11_OPCODE_IMM8:
702 str = skip_whitespace (str);
703 if (*str == '#' || *str == '$')
704 str++;
705 str = parse_expression (str, &op1);
706 if (op1.error)
707 break;
708 if (op1.reloc.exp.X_op != O_constant || op1.reloc.type != BFD_RELOC_NONE)
709 {
710 op1.error = "operand is not an absolute constant";
711 break;
712 }
713 switch (op->type)
714 {
715 case PDP11_OPCODE_IMM3:
716 if (op1.reloc.exp.X_add_number & ~7)
717 {
718 op1.error = "3-bit immediate out of range";
719 break;
720 }
721 break;
722 case PDP11_OPCODE_IMM6:
723 if (op1.reloc.exp.X_add_number & ~0x3f)
724 {
725 op1.error = "6-bit immediate out of range";
726 break;
727 }
728 break;
729 case PDP11_OPCODE_IMM8:
730 if (op1.reloc.exp.X_add_number & ~0xff)
731 {
732 op1.error = "8-bit immediate out of range";
733 break;
734 }
735 break;
736 }
737 insn.code |= op1.reloc.exp.X_add_number;
738 break;
739
740 case PDP11_OPCODE_DISPL:
741 {
742 char *new;
743 new = parse_expression (str, &op1);
744 op1.code = 0;
745 op1.reloc.pc_rel = 1;
746 op1.reloc.type = BFD_RELOC_PDP11_DISP_8_PCREL;
747 if (op1.reloc.exp.X_op != O_symbol)
748 {
749 op1.error = "Symbol expected";
750 break;
751 }
752 if (op1.code & ~0xff)
753 {
754 err = "8-bit displacement out of range";
755 break;
756 }
757 str = new;
758 insn.code |= op1.code;
759 insn.reloc = op1.reloc;
760 }
761 break;
762
763 case PDP11_OPCODE_REG:
764 str = parse_reg (str, &op1);
765 if (op1.error)
766 break;
767 insn.code |= op1.code;
768 break;
769
770 case PDP11_OPCODE_OP:
771 str = parse_op (str, &op1);
772 if (op1.error)
773 break;
774 insn.code |= op1.code;
775 if (op1.additional)
776 size += 2;
777 break;
778
779 case PDP11_OPCODE_FOP:
780 str = parse_fop (str, &op1);
781 if (op1.error)
782 break;
783 insn.code |= op1.code;
784 if (op1.additional)
785 size += 2;
786 break;
787
788 case PDP11_OPCODE_REG_OP:
789 str = parse_reg (str, &op2);
790 if (op2.error)
791 break;
792 insn.code |= op2.code << 6;
793 str = parse_separator (str, &error);
794 if (error)
795 {
796 op2.error = "Missing ','";
797 break;
798 }
799 str = parse_op (str, &op1);
800 if (op1.error)
801 break;
802 insn.code |= op1.code;
803 if (op1.additional)
804 size += 2;
805 break;
806
807 case PDP11_OPCODE_REG_OP_REV:
808 str = parse_op (str, &op1);
809 if (op1.error)
810 break;
811 insn.code |= op1.code;
812 if (op1.additional)
813 size += 2;
814 str = parse_separator (str, &error);
815 if (error)
816 {
817 op2.error = "Missing ','";
818 break;
819 }
820 str = parse_reg (str, &op2);
821 if (op2.error)
822 break;
823 insn.code |= op2.code << 6;
824 break;
825
826 case PDP11_OPCODE_AC_FOP:
827 str = parse_ac (str, &op2);
828 if (op2.error)
829 break;
830 insn.code |= op2.code << 6;
831 str = parse_separator (str, &error);
832 if (error)
833 {
834 op1.error = "Missing ','";
835 break;
836 }
837 str = parse_fop (str, &op1);
838 if (op1.error)
839 break;
840 insn.code |= op1.code;
841 if (op1.additional)
842 size += 2;
843 break;
844
845 case PDP11_OPCODE_FOP_AC:
846 str = parse_fop (str, &op1);
847 if (op1.error)
848 break;
849 insn.code |= op1.code;
850 if (op1.additional)
851 size += 2;
852 str = parse_separator (str, &error);
853 if (error)
854 {
855 op1.error = "Missing ','";
856 break;
857 }
858 str = parse_ac (str, &op2);
859 if (op2.error)
860 break;
861 insn.code |= op2.code << 6;
862 break;
863
864 case PDP11_OPCODE_AC_OP:
865 str = parse_ac (str, &op2);
866 if (op2.error)
867 break;
868 insn.code |= op2.code << 6;
869 str = parse_separator (str, &error);
870 if (error)
871 {
872 op1.error = "Missing ','";
873 break;
874 }
875 str = parse_op (str, &op1);
876 if (op1.error)
877 break;
878 insn.code |= op1.code;
879 if (op1.additional)
880 size += 2;
881 break;
882
883 case PDP11_OPCODE_OP_AC:
884 str = parse_op (str, &op1);
885 if (op1.error)
886 break;
887 insn.code |= op1.code;
888 if (op1.additional)
889 size += 2;
890 str = parse_separator (str, &error);
891 if (error)
892 {
893 op1.error = "Missing ','";
894 break;
895 }
896 str = parse_ac (str, &op2);
897 if (op2.error)
898 break;
899 insn.code |= op2.code << 6;
900 break;
901
902 case PDP11_OPCODE_OP_OP:
903 str = parse_op (str, &op1);
904 if (op1.error)
905 break;
906 insn.code |= op1.code << 6;
907 if (op1.additional)
908 size += 2;
909 str = parse_separator (str, &error);
910 if (error)
911 {
912 op2.error = "Missing ','";
913 break;
914 }
915 str = parse_op (str, &op2);
916 if (op2.error)
917 break;
918 insn.code |= op2.code;
919 if (op2.additional)
920 size += 2;
921 break;
922
923 case PDP11_OPCODE_REG_DISPL:
924 {
925 char *new;
926 str = parse_reg (str, &op2);
927 if (op2.error)
928 break;
929 insn.code |= op2.code << 6;
930 str = parse_separator (str, &error);
931 if (error)
932 {
933 op1.error = "Missing ','";
934 break;
935 }
936 new = parse_expression (str, &op1);
937 op1.code = 0;
938 op1.reloc.pc_rel = 1;
939 op1.reloc.type = BFD_RELOC_PDP11_DISP_6_PCREL;
940 if (op1.reloc.exp.X_op != O_symbol)
941 {
942 op1.error = "Symbol expected";
943 break;
944 }
945 if (op1.code & ~0x3f)
946 {
947 err = "6-bit displacement out of range";
948 break;
949 }
950 str = new;
951 insn.code |= op1.code;
952 insn.reloc = op1.reloc;
953 }
954 break;
955
956 default:
957 BAD_CASE (op->type);
958 }
959
960 if (op1.error)
961 err = op1.error;
962 else if (op2.error)
963 err = op2.error;
964 else
965 {
966 str = skip_whitespace (str);
967 if (*str)
968 err = "Too many operands";
969 }
970
971 {
972 char *to = NULL;
973
974 if (err)
975 {
976 as_bad (err);
977 return;
978 }
979
980 to = frag_more (size);
981
982 md_number_to_chars (to, insn.code, 2);
983 if (insn.reloc.type != BFD_RELOC_NONE)
984 fix_new_exp (frag_now, to - frag_now->fr_literal, 2,
985 &insn.reloc.exp, insn.reloc.pc_rel, insn.reloc.type);
986 to += 2;
987
988 if (op1.additional)
989 {
990 md_number_to_chars (to, op1.word, 2);
991 if (op1.reloc.type != BFD_RELOC_NONE)
992 fix_new_exp (frag_now, to - frag_now->fr_literal, 2,
993 &op1.reloc.exp, op1.reloc.pc_rel, op1.reloc.type);
994 to += 2;
995 }
996
997 if (op2.additional)
998 {
999 md_number_to_chars (to, op2.word, 2);
1000 if (op2.reloc.type != BFD_RELOC_NONE)
1001 fix_new_exp (frag_now, to - frag_now->fr_literal, 2,
1002 &op2.reloc.exp, op2.reloc.pc_rel, op2.reloc.type);
1003 }
1004 }
1005 }
1006
1007 int
1008 md_estimate_size_before_relax (fragP, segment)
1009 fragS *fragP ATTRIBUTE_UNUSED;
1010 segT segment ATTRIBUTE_UNUSED;
1011 {
1012 return 0;
1013 }
1014
1015 void
1016 md_convert_frag (headers, seg, fragP)
1017 bfd *headers ATTRIBUTE_UNUSED;
1018 segT seg ATTRIBUTE_UNUSED;
1019 fragS *fragP ATTRIBUTE_UNUSED;
1020 {
1021 }
1022
1023 const int md_short_jump_size = 2;
1024 const int md_long_jump_size = 4;
1025
1026 void
1027 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
1028 char *ptr ATTRIBUTE_UNUSED;
1029 addressT from_addr ATTRIBUTE_UNUSED;
1030 addressT to_addr ATTRIBUTE_UNUSED;
1031 fragS *frag ATTRIBUTE_UNUSED;
1032 symbolS *to_symbol ATTRIBUTE_UNUSED;
1033 {
1034 }
1035
1036 void
1037 md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
1038 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
1046 static int
1047 set_option (arg)
1048 char *arg;
1049 {
1050 int yes = 1;
1051
1052 if (strcmp (arg, "all-extensions") == 0 ||
1053 strcmp (arg, "all") == 0)
1054 {
1055 memset (pdp11_extension, ~0, sizeof pdp11_extension);
1056 pdp11_extension[PDP11_NONE] = 0;
1057 return 1;
1058 }
1059 else if (strcmp (arg, "no-extensions") == 0)
1060 {
1061 memset (pdp11_extension, 0, sizeof pdp11_extension);
1062 pdp11_extension[PDP11_BASIC] = 1;
1063 return 1;
1064 }
1065
1066 if (strncmp (arg, "no-", 3) == 0)
1067 {
1068 yes = 0;
1069 arg += 3;
1070 }
1071
1072 if (strcmp (arg, "cis") == 0) /* commersial instructions */
1073 pdp11_extension[PDP11_CIS] = yes;
1074 else if (strcmp (arg, "csm") == 0) /* call supervisor mode */
1075 pdp11_extension[PDP11_CSM] = yes;
1076 else if (strcmp (arg, "eis") == 0) /* extended instruction set */
1077 pdp11_extension[PDP11_EIS] = pdp11_extension[PDP11_LEIS] = yes;
1078 else if (strcmp (arg, "fis") == 0 || /* KEV11 floating-point */
1079 strcmp (arg, "kev11") == 0 ||
1080 strcmp (arg, "kev-11") == 0)
1081 pdp11_extension[PDP11_FIS] = yes;
1082 else if (strcmp (arg, "fpp") == 0 || /* FP-11 floating-point */
1083 strcmp (arg, "fpu") == 0 ||
1084 strcmp (arg, "fp11") == 0 ||
1085 strcmp (arg, "fp-11") == 0 ||
1086 strcmp (arg, "fpj11") == 0 ||
1087 strcmp (arg, "fp-j11") == 0 ||
1088 strcmp (arg, "fpj-11") == 0)
1089 pdp11_extension[PDP11_FPP] = yes;
1090 else if (strcmp (arg, "limited-eis") == 0) /* limited extended insns */
1091 {
1092 pdp11_extension[PDP11_LEIS] = yes;
1093 if (!pdp11_extension[PDP11_LEIS])
1094 pdp11_extension[PDP11_EIS] = 0;
1095 }
1096 else if (strcmp (arg, "mfpt") == 0) /* move from processor type */
1097 pdp11_extension[PDP11_MFPT] = yes;
1098 else if (strncmp (arg, "mproc", 5) == 0 || /* multiprocessor insns: */
1099 strncmp (arg, "multiproc", 9) == 0 ) /* TSTSET, WRTLCK */
1100 pdp11_extension[PDP11_MPROC] = yes;
1101 else if (strcmp (arg, "mxps") == 0) /* move from/to proc status */
1102 pdp11_extension[PDP11_MXPS] = yes;
1103 else if (strcmp (arg, "pic") == 0) /* position-independent code */
1104 asm_option[ASM_OPT_PIC] = yes;
1105 else if (strcmp (arg, "spl") == 0) /* set priority level */
1106 pdp11_extension[PDP11_SPL] = yes;
1107 else if (strcmp (arg, "ucode") == 0 || /* microcode instructions: */
1108 strcmp (arg, "microcode") == 0) /* LDUB, MED, XFC */
1109 pdp11_extension[PDP11_UCODE] = yes;
1110 else
1111 return 0;
1112
1113 return 1;
1114 }
1115
1116 static int
1117 set_cpu_model (arg)
1118 char *arg;
1119 {
1120 char buf[4];
1121 char *model = buf;
1122
1123 if (arg[0] == 'k')
1124 arg++;
1125
1126 *model++ = *arg++;
1127
1128 if (strchr ("abdx", model[-1]) == NULL)
1129 return 0;
1130
1131 if (model[-1] == 'd')
1132 {
1133 if (arg[0] == 'f' ||
1134 arg[0] == 'j')
1135 model[-1] = *arg++;
1136 }
1137 else if (model[-1] == 'x')
1138 {
1139 if (arg[0] == 't')
1140 model[-1] = *arg++;
1141 }
1142
1143 if (arg[0] == '-')
1144 arg++;
1145
1146 if (strncmp (arg, "11", 2) != 0)
1147 return 0;
1148 arg += 2;
1149
1150 if (arg[0] == '-')
1151 {
1152 if (*++arg == 0)
1153 return 0;
1154 }
1155
1156 /* allow up to two revision letters */
1157 if (arg[0] != 0)
1158 *model++ = *arg++;
1159 if (arg[0] != 0)
1160 *model++ = *arg++;
1161
1162 *model++ = 0;
1163
1164 set_option ("no-extensions");
1165
1166 if (strncmp (buf, "a", 1) == 0) /* KA11 (11/15/20) */
1167 return 1; /* no extensions */
1168
1169 else if (strncmp (buf, "b", 1) == 0) /* KB11 (11/45/50/55/70) */
1170 return set_option ("eis") &&
1171 set_option ("spl");
1172
1173 else if (strncmp (buf, "da", 2) == 0) /* KD11-A (11/35/40) */
1174 return set_option ("limited-eis");
1175
1176 else if (strncmp (buf, "db", 2) == 0 || /* KD11-B (11/05/10) */
1177 strncmp (buf, "dd", 2) == 0) /* KD11-D (11/04) */
1178 return 1; /* no extensions */
1179
1180 else if (strncmp (buf, "de", 2) == 0) /* KD11-E (11/34) */
1181 return set_option ("eis") &&
1182 set_option ("mxps");
1183
1184 else if (strncmp (buf, "df", 2) == 0 || /* KD11-F (11/03) */
1185 strncmp (buf, "dh", 2) == 0 || /* KD11-H (11/03) */
1186 strncmp (buf, "dq", 2) == 0) /* KD11-Q (11/03) */
1187 return set_option ("limited-eis") &&
1188 set_option ("mxps");
1189
1190 else if (strncmp (buf, "dk", 2) == 0) /* KD11-K (11/60) */
1191 return set_option ("eis") &&
1192 set_option ("mxps") &&
1193 set_option ("ucode");
1194
1195 else if (strncmp (buf, "dz", 2) == 0) /* KD11-Z (11/44) */
1196 return set_option ("csm") &&
1197 set_option ("eis") &&
1198 set_option ("mfpt") &&
1199 set_option ("mxps") &&
1200 set_option ("spl");
1201
1202 else if (strncmp (buf, "f", 1) == 0) /* F11 (11/23/24) */
1203 return set_option ("eis") &&
1204 set_option ("mfpt") &&
1205 set_option ("mxps");
1206
1207 else if (strncmp (buf, "j", 1) == 0) /* J11 (11/53/73/83/84/93/94)*/
1208 return set_option ("csm") &&
1209 set_option ("eis") &&
1210 set_option ("mfpt") &&
1211 set_option ("multiproc") &&
1212 set_option ("mxps") &&
1213 set_option ("spl");
1214
1215 else if (strncmp (buf, "t", 1) == 0) /* T11 (11/21) */
1216 return set_option ("limited-eis") &&
1217 set_option ("mxps");
1218
1219 else
1220 return 0;
1221 }
1222
1223 static int
1224 set_machine_model (arg)
1225 char *arg;
1226 {
1227 if (strncmp (arg, "pdp-11/", 7) != 0 &&
1228 strncmp (arg, "pdp11/", 6) != 0 &&
1229 strncmp (arg, "11/", 3) != 0)
1230 return 0;
1231
1232 if (strncmp (arg, "pdp", 3) == 0)
1233 arg += 3;
1234 if (arg[0] == '-')
1235 arg++;
1236 if (strncmp (arg, "11/", 3) == 0)
1237 arg += 3;
1238
1239 if (strcmp (arg, "03") == 0) /* 11/03 */
1240 return set_cpu_model ("kd11f"); /* KD11-F */
1241
1242 else if (strcmp (arg, "04") == 0) /* 11/04 */
1243 return set_cpu_model ("kd11d"); /* KD11-D */
1244
1245 else if (strcmp (arg, "05") == 0 || /* 11/05 or 11/10 */
1246 strcmp (arg, "10") == 0)
1247 return set_cpu_model ("kd11b"); /* KD11-B */
1248
1249 else if (strcmp (arg, "15") == 0 || /* 11/15 or 11/20 */
1250 strcmp (arg, "20") == 0)
1251 return set_cpu_model ("ka11"); /* KA11 */
1252
1253 else if (strcmp (arg, "21") == 0) /* 11/21 */
1254 return set_cpu_model ("t11"); /* T11 */
1255
1256 else if (strcmp (arg, "23") == 0 || /* 11/23 or 11/24 */
1257 strcmp (arg, "24") == 0)
1258 return set_cpu_model ("f11"); /* F11 */
1259
1260 else if (strcmp (arg, "34") == 0 || /* 11/34 or 11/34a */
1261 strcmp (arg, "34a") == 0)
1262 return set_cpu_model ("kd11e"); /* KD11-E */
1263
1264 else if (strcmp (arg, "35") == 0 || /* 11/35 or 11/40 */
1265 strcmp (arg, "40") == 0)
1266 return set_cpu_model ("kd11da"); /* KD11-A */
1267
1268 else if (strcmp (arg, "44") == 0) /* 11/44 */
1269 return set_cpu_model ("kd11dz"); /* KD11-Z */
1270
1271 else if (strcmp (arg, "45") == 0 || /* 11/45/50/55/70 */
1272 strcmp (arg, "50") == 0 ||
1273 strcmp (arg, "55") == 0 ||
1274 strcmp (arg, "70") == 0)
1275 return set_cpu_model ("kb11"); /* KB11 */
1276
1277 else if (strcmp (arg, "60") == 0) /* 11/60 */
1278 return set_cpu_model ("kd11k"); /* KD11-K */ /* FPP? */
1279
1280 else if (strcmp (arg, "53") == 0 || /* 11/53/73/83/84/93/94 */
1281 strcmp (arg, "73") == 0 ||
1282 strcmp (arg, "83") == 0 ||
1283 strcmp (arg, "84") == 0 ||
1284 strcmp (arg, "93") == 0 ||
1285 strcmp (arg, "94") == 0)
1286 return set_cpu_model ("j11") && /* J11 */
1287 set_option ("fpp"); /* All J11 machines come */
1288 /* with FPP installed. */
1289 else
1290 return 0;
1291 }
1292
1293 const char *md_shortopts = "m:";
1294
1295 struct option md_longopts[] =
1296 {
1297 #define OPTION_CPU 257
1298 { "cpu", required_argument, NULL, OPTION_CPU },
1299 #define OPTION_MACHINE 258
1300 { "machine", required_argument, NULL, OPTION_MACHINE },
1301 #define OPTION_PIC 259
1302 { "pic", no_argument, NULL, OPTION_PIC },
1303 { NULL, no_argument, NULL, 0 }
1304 };
1305
1306 size_t md_longopts_size = sizeof (md_longopts);
1307
1308 /*
1309 * md_parse_option
1310 * Invocation line includes a switch not recognized by the base assembler.
1311 * See if it's a processor-specific option.
1312 */
1313
1314 int
1315 md_parse_option (c, arg)
1316 int c;
1317 char *arg;
1318 {
1319 init_defaults ();
1320
1321 switch (c)
1322 {
1323 case 'm':
1324 if (set_option (arg))
1325 return 1;
1326 if (set_cpu_model (arg))
1327 return 1;
1328 if (set_machine_model (arg))
1329 return 1;
1330 break;
1331
1332 case OPTION_CPU:
1333 if (set_cpu_model (arg))
1334 return 1;
1335 break;
1336
1337 case OPTION_MACHINE:
1338 if (set_machine_model (arg))
1339 return 1;
1340 break;
1341
1342 case OPTION_PIC:
1343 if (set_option ("pic"))
1344 return 1;
1345 break;
1346
1347 default:
1348 break;
1349 }
1350
1351 return 0;
1352 }
1353
1354 /*
1355 One possible way of parsing options.
1356
1357 enum
1358 {
1359 OPTION_CSM,
1360 OPTION_CIS,
1361 ...
1362 };
1363
1364 struct
1365 {
1366 const char *pattern;
1367 int opt;
1368 const char *description;
1369 } options;
1370
1371 static struct options extension_opts[] =
1372 {
1373 { "Ncsm", OPTION_CSM,
1374 "allow (disallow) CSM instruction" },
1375 { "Ncis", OPTION_CIS,
1376 "allow (disallow) commersial instruction set" },
1377 { "Neis", OPTION_EIS,
1378 "allow (disallow) extended instruction set" },
1379 ...
1380 { "all-extensions", OPTION_ALL_EXTENSIONS,
1381 "allow all instruction set extensions\n\
1382 (this is the default)" },
1383 { "no-extensions", OPTION_NO_EXTENSIONS,
1384 "disallow all instruction set extensions" },
1385 { "pic", OPTION_PIC,
1386 "position-independent code" },
1387 };
1388
1389 static struct options cpu_opts[] =
1390 {
1391 { "Ka_11_*", OPTION_KA11, "KA11 CPU. ..." },
1392 { "Kb_11_*", OPTION_KB11, "KB11 CPU. ..." },
1393 { "Kd_11_a*", OPTION_KD11A, "KD11-A CPU. ..." },
1394 { "Kd_11_b*", OPTION_KD11B, "KD11-B CPU. ..." },
1395 { "Kd_11_d*", OPTION_KD11D, "KD11-D CPU. ..." },
1396 { "Kd_11_e*", OPTION_KD11E, "KD11-E CPU. ..." },
1397 { "Kd_11_f*", OPTION_KD11F, "KD11-F CPU. ..." },
1398 { "Kd_11_h*", OPTION_KD11H, "KD11-H CPU. ..." },
1399 { "Kd_11_q*", OPTION_KD11Q, "KD11-Q CPU. ..." },
1400 { "Kd_11_z*", OPTION_KD11Z, "KD11-Z CPU. ..." },
1401 { "Df_11_*", OPTION_F11, "F11 CPU. ..." },
1402 { "Dj_11_*", OPTION_J11, "J11 CPU. ..." },
1403 { "Dt_11_*", OPTION_T11, "T11 CPU. ..." },
1404 };
1405
1406 static struct options model_opts[] =
1407 {
1408 { "P03", OPTION_PDP11_03, "same as ..." },
1409 { "P04", OPTION_PDP11_04, "same as ..." },
1410 { "P05", OPTION_PDP11_05, "same as ..." },
1411 { "P10", OPTION_PDP11_10, "same as ..." },
1412 { "P15", OPTION_PDP11_15, "same as ..." },
1413 { "P20", OPTION_PDP11_20, "same as ..." },
1414 { "P21", OPTION_PDP11_21, "same as ..." },
1415 { "P24", OPTION_PDP11_24, "same as ..." },
1416 { "P34", OPTION_PDP11_34, "same as ..." },
1417 { "P34a", OPTION_PDP11_34A, "same as ..." },
1418 { "P40", OPTION_PDP11_40, "same as ..." },
1419 { "P44", OPTION_PDP11_44, "same as ..." },
1420 { "P45", OPTION_PDP11_45, "same as ..." },
1421 { "P50", OPTION_PDP11_50, "same as ..." },
1422 { "P53", OPTION_PDP11_53, "same as ..." },
1423 { "P55", OPTION_PDP11_55, "same as ..." },
1424 { "P60", OPTION_PDP11_60, "same as ..." },
1425 { "P70", OPTION_PDP11_70, "same as ..." },
1426 { "P73", OPTION_PDP11_73, "same as ..." },
1427 { "P83", OPTION_PDP11_83, "same as ..." },
1428 { "P84", OPTION_PDP11_84, "same as ..." },
1429 { "P93", OPTION_PDP11_93, "same as ..." },
1430 { "P94", OPTION_PDP11_94, "same as ..." },
1431 };
1432
1433 struct
1434 {
1435 const char *title;
1436 struct options *opts;
1437 int num;
1438 } all_opts[] =
1439 {
1440 { "PDP-11 instruction set extentions",
1441 extension_opts,
1442 sizeof extension_opts / sizeof extension_opts[0] },
1443 { "PDP-11 CPU model options",
1444 cpu_opts,
1445 sizeof cpu_opts / sizeof cpu_opts[0] },
1446 { "PDP-11 machine model options",
1447 model_opts,
1448 sizeof model_opts / sizeof model_opts[0] },
1449 };
1450
1451 int
1452 parse_match (char *arg, char *pattern)
1453 {
1454 int yes = 1;
1455
1456 while (*pattern)
1457 {
1458 switch (*pattern++)
1459 {
1460 case 'N':
1461 if (strncmp (arg, "no-") == 0)
1462 {
1463 yes = 0;
1464 arg += 3;
1465 }
1466 break;
1467
1468 case 'K':
1469 if (arg[0] == 'k')
1470 arg++;
1471 break;
1472
1473 case 'D':
1474 if (strncmp (arg, "kd", 2) == 0)
1475 arg +=2;
1476 break;
1477
1478 case 'P':
1479 if (strncmp (arg, "pdp-11/", 7) == 0)
1480 arg += 7;
1481 else if (strncmp (arg, "pdp11/", 6) == 0)
1482 arg += 6;
1483 else if (strncmp (arg, "11/", 3) == 0)
1484 arg += 3;
1485 break;
1486
1487 case '_':
1488 if (arg[0] == "-")
1489 {
1490 if (*++arg == 0)
1491 return 0;
1492 }
1493 break;
1494
1495 case '*':
1496 return 1;
1497
1498 default:
1499 if (*arg++ != pattern[-1])
1500 return 0;
1501 }
1502 }
1503
1504 return arg[0] == 0;
1505 }
1506
1507 int
1508 fprint_opt (stream, pattern)
1509 FILE *stream;
1510 const char *pattern;
1511 {
1512 int n;
1513
1514 while (*pattern)
1515 {
1516 switch (*pattern++)
1517 {
1518 case 'N':
1519 n += fprintf (stream, "(no-)");
1520 break;
1521
1522 case 'K':
1523 n += fprintf (stream, "k");
1524 break;
1525
1526 case 'P':
1527 n += fprintf (stream "11/");
1528 break;
1529
1530 case 'D':
1531 case '_':
1532 case '*':
1533 break;
1534
1535 default:
1536 fputc (pattern[-1], stream);
1537 n++;
1538 }
1539 }
1540
1541 return n;
1542 }
1543
1544 int
1545 parse_option (char *arg)
1546 {
1547 int i, j;
1548
1549 for (i = 0; i < sizeof all_opts / sizeof all_opts[0]; i++)
1550 {
1551 for (j = 0; j < all_opts[i].num; j++)
1552 {
1553 if (parse_match (arg, all_opts[i].opts[j].pattern))
1554 {
1555 set_option (all_opts[i].opts[j].opt);
1556 return 1;
1557 }
1558 }
1559 }
1560
1561 return 0;
1562 }
1563
1564 static void
1565 fprint_space (stream, n)
1566 FILE *stream;
1567 int n;
1568 {
1569 while (n--)
1570 fputc (' ', stream);
1571 }
1572
1573 void
1574 md_show_usage (stream)
1575 FILE *stream;
1576 {
1577 int i, j, n;
1578
1579 for (i = 0; i < sizeof all_opts / sizeof all_opts[0]; i++)
1580 {
1581 fprintf (stream "\n%s:\n\n", all_opts[i].title);
1582
1583 for (j = 0; j < all_opts[i].num; j++)
1584 {
1585 fprintf (stream, "-m");
1586 n = fprintf_opt (stream, all_opts[i].opts[j].pattern);
1587 fprint_space (stream, 22 - n);
1588 fprintf (stream, "%s\n", all_opts[i].opts[j].description);
1589 }
1590 }
1591 }
1592 */
1593
1594 void
1595 md_show_usage (stream)
1596 FILE *stream;
1597 {
1598 fprintf (stream, "\
1599 \n\
1600 PDP-11 instruction set extentions:\n\
1601 \n\
1602 -m(no-)cis allow (disallow) commersial instruction set\n\
1603 -m(no-)csm allow (disallow) CSM instruction\n\
1604 -m(no-)eis allow (disallow) full extended instruction set\n\
1605 -m(no-)fis allow (disallow) KEV11 floating-point instructions\n\
1606 -m(no-)fpp allow (disallow) FP-11 floating-point instructions\n\
1607 -m(no-)fpu allow (disallow) FP-11 floating-point instructions\n\
1608 -m(no-)limited-eis allow (disallow) limited extended instruction set\n\
1609 -m(no-)mfpt allow (disallow) processor type instruction\n\
1610 -m(no-)multiproc allow (disallow) multiprocessor instructions\n\
1611 -m(no-)mxps allow (disallow) processor status instructions\n\
1612 -m(no-)spl allow (disallow) SPL instruction\n\
1613 -m(no-)ucode allow (disallow) microcode instructions\n\
1614 -mall-extensions allow all instruction set extensions\n\
1615 (this is the default)\n\
1616 -mno-extentions disallow all instruction set extensions\n\
1617 -pic generate position-indepenent code\n\
1618 \n\
1619 PDP-11 CPU model options:\n\
1620 \n\
1621 -mka11* KA11 CPU. base line instruction set only\n\
1622 -mkb11* KB11 CPU. enable full EIS and SPL\n\
1623 -mkd11a* KD11-A CPU. enable limited EIS\n\
1624 -mkd11b* KD11-B CPU. base line instruction set only\n\
1625 -mkd11d* KD11-D CPU. base line instruction set only\n\
1626 -mkd11e* KD11-E CPU. enable full EIS, MTPS, and MFPS\n\
1627 -mkd11f* KD11-F CPU. enable limited EIS, MTPS, and MFPS\n\
1628 -mkd11h* KD11-H CPU. enable limited EIS, MTPS, and MFPS\n\
1629 -mkd11q* KD11-Q CPU. enable limited EIS, MTPS, and MFPS\n\
1630 -mkd11k* KD11-K CPU. enable full EIS, MTPS, MFPS, LDUB, MED,\n\
1631 XFC, and MFPT\n\
1632 -mkd11z* KD11-Z CPU. enable full EIS, MTPS, MFPS, MFPT, SPL,\n\
1633 and CSM\n\
1634 -mf11* F11 CPU. enable full EIS, MFPS, MTPS, and MFPT\n\
1635 -mj11* J11 CPU. enable full EIS, MTPS, MFPS, MFPT, SPL,\n\
1636 CSM, TSTSET, and WRTLCK\n\
1637 -mt11* T11 CPU. enable limited EIS, MTPS, and MFPS\n\
1638 \n\
1639 PDP-11 machine model options:\n\
1640 \n\
1641 -m11/03 same as -mkd11f\n\
1642 -m11/04 same as -mkd11d\n\
1643 -m11/05 same as -mkd11b\n\
1644 -m11/10 same as -mkd11b\n\
1645 -m11/15 same as -mka11\n\
1646 -m11/20 same as -mka11\n\
1647 -m11/21 same as -mt11\n\
1648 -m11/23 same as -mf11\n\
1649 -m11/24 same as -mf11\n\
1650 -m11/34 same as -mkd11e\n\
1651 -m11/34a same as -mkd11e -mfpp\n\
1652 -m11/35 same as -mkd11a\n\
1653 -m11/40 same as -mkd11a\n\
1654 -m11/44 same as -mkd11z\n\
1655 -m11/45 same as -mkb11\n\
1656 -m11/50 same as -mkb11\n\
1657 -m11/53 same as -mj11\n\
1658 -m11/55 same as -mkb11\n\
1659 -m11/60 same as -mkd11k\n\
1660 -m11/70 same as -mkb11\n\
1661 -m11/73 same as -mj11\n\
1662 -m11/83 same as -mj11\n\
1663 -m11/84 same as -mj11\n\
1664 -m11/93 same as -mj11\n\
1665 -m11/94 same as -mj11\n\
1666 ");
1667 }
1668
1669 symbolS *
1670 md_undefined_symbol (name)
1671 char *name ATTRIBUTE_UNUSED;
1672 {
1673 return 0;
1674 }
1675
1676 valueT
1677 md_section_align (segment, size)
1678 segT segment ATTRIBUTE_UNUSED;
1679 valueT size;
1680 {
1681 return (size + 1) & ~1;
1682 }
1683
1684 long
1685 md_pcrel_from (fixP)
1686 fixS *fixP;
1687 {
1688 return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1689 }
1690
1691 /* Translate internal representation of relocation info to BFD target
1692 format. */
1693 arelent *
1694 tc_gen_reloc (section, fixp)
1695 asection *section ATTRIBUTE_UNUSED;
1696 fixS *fixp;
1697 {
1698 arelent *reloc;
1699 bfd_reloc_code_real_type code;
1700
1701 reloc = (arelent *) xmalloc (sizeof (arelent));
1702
1703 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1704 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1705 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1706
1707 /* This is taken account for in md_apply_fix3(). */
1708 reloc->addend = -symbol_get_bfdsym (fixp->fx_addsy)->section->vma;
1709
1710 switch (fixp->fx_r_type)
1711 {
1712 case BFD_RELOC_16:
1713 if (fixp->fx_pcrel)
1714 code = BFD_RELOC_16_PCREL;
1715 else
1716 code = BFD_RELOC_16;
1717 break;
1718
1719 case BFD_RELOC_16_PCREL:
1720 code = BFD_RELOC_16_PCREL;
1721 break;
1722
1723 default:
1724 BAD_CASE (fixp->fx_r_type);
1725 return NULL;
1726 }
1727
1728 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
1729
1730 if (reloc->howto == NULL)
1731 {
1732 as_bad_where (fixp->fx_file, fixp->fx_line,
1733 "Can not represent %s relocation in this object file format",
1734 bfd_get_reloc_code_name (code));
1735 return NULL;
1736 }
1737
1738 return reloc;
1739 }
1740
1741 void
1742 pseudo_bss (c)
1743 int c ATTRIBUTE_UNUSED;
1744 {
1745 int temp;
1746
1747 temp = get_absolute_expression ();
1748 subseg_set (bss_section, temp);
1749 demand_empty_rest_of_line ();
1750 }
1751
1752 void
1753 pseudo_even (c)
1754 int c ATTRIBUTE_UNUSED;
1755 {
1756 int alignment = 1; /* 2^1 */
1757 frag_align (alignment, 0, 1);
1758 record_alignment (now_seg, alignment);
1759 }
1760
1761 /* end of tc-pdp11.c */