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