source: trunk/binutils/gas/config/tc-pdp11.c@ 2562

Last change on this file since 2562 was 607, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 38.7 KB
Line 
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
32static int set_option PARAMS ((char *arg));
33static int set_cpu_model PARAMS ((char *arg));
34static int set_machine_model PARAMS ((char *arg));
35
36extern 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 */
45struct 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 */
65int 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
74int asm_option[ASM_OPT_NUM];
75
76/* These chars start a comment anywhere in a source file (except inside
77 another comment */
78const char comment_chars[] = "#/";
79
80/* These chars only start a comment at the beginning of a line. */
81const char line_comment_chars[] = "#/";
82
83const char line_separator_chars[] = ";";
84
85/* Chars that can be used to separate mant from exp in floating point nums */
86const 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) */
91const char FLT_CHARS[] = "dDfF";
92
93void pseudo_even (int);
94void pseudo_bss (int);
95
96const pseudo_typeS md_pseudo_table[] =
97{
98 { "bss", pseudo_bss, 0 },
99 { "even", pseudo_even, 0 },
100 { 0, 0, 0 },
101};
102
103static void
104init_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
116static struct hash_control *insn_hash = NULL;
117
118void
119md_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
135void
136md_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
171void
172md_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
219long
220md_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
247
248static char *
249skip_whitespace (char *str)
250{
251 while (*str == ' ' || *str == '\t')
252 str++;
253 return str;
254}
255
256static char *
257find_whitespace (char *str)
258{
259 while (*str != ' ' && *str != '\t' && *str != 0)
260 str++;
261 return str;
262}
263
264static char *
265parse_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
304static char *
305parse_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
335static char *
336parse_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
348static char *
349parse_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
396static char *
397parse_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
548static char *
549parse_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
567static char *
568parse_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
587static char *
588parse_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
607static char *
608parse_separator (char *str, int *error)
609{
610 str = skip_whitespace (str);
611 *error = (*str != ',');
612 if (!*error)
613 str++;
614 return str;
615}
616
617void
618md_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
1007int
1008md_estimate_size_before_relax (fragP, segment)
1009 fragS *fragP ATTRIBUTE_UNUSED;
1010 segT segment ATTRIBUTE_UNUSED;
1011{
1012 return 0;
1013}
1014
1015void
1016md_convert_frag (headers, seg, fragP)
1017 bfd *headers ATTRIBUTE_UNUSED;
1018 segT seg ATTRIBUTE_UNUSED;
1019 fragS *fragP ATTRIBUTE_UNUSED;
1020{
1021}
1022
1023const int md_short_jump_size = 2;
1024const int md_long_jump_size = 4;
1025
1026void
1027md_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
1036void
1037md_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
1046static int
1047set_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
1116static int
1117set_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
1223static int
1224set_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
1293const char *md_shortopts = "m:";
1294
1295struct 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
1306size_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
1314int
1315md_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 as_bad ("unrecognized option `-%c%s'", c, arg ? arg : "");
1352
1353 return 0;
1354}
1355
1356/*
1357One possible way of parsing options.
1358
1359enum
1360{
1361 OPTION_CSM,
1362 OPTION_CIS,
1363 ...
1364};
1365
1366struct
1367{
1368 const char *pattern;
1369 int opt;
1370 const char *description;
1371} options;
1372
1373static struct options extension_opts[] =
1374{
1375 { "Ncsm", OPTION_CSM,
1376 "allow (disallow) CSM instruction" },
1377 { "Ncis", OPTION_CIS,
1378 "allow (disallow) commersial instruction set" },
1379 { "Neis", OPTION_EIS,
1380 "allow (disallow) extended instruction set" },
1381 ...
1382 { "all-extensions", OPTION_ALL_EXTENSIONS,
1383 "allow all instruction set extensions\n\
1384 (this is the default)" },
1385 { "no-extensions", OPTION_NO_EXTENSIONS,
1386 "disallow all instruction set extensions" },
1387 { "pic", OPTION_PIC,
1388 "position-independent code" },
1389};
1390
1391static struct options cpu_opts[] =
1392{
1393 { "Ka_11_*", OPTION_KA11, "KA11 CPU. ..." },
1394 { "Kb_11_*", OPTION_KB11, "KB11 CPU. ..." },
1395 { "Kd_11_a*", OPTION_KD11A, "KD11-A CPU. ..." },
1396 { "Kd_11_b*", OPTION_KD11B, "KD11-B CPU. ..." },
1397 { "Kd_11_d*", OPTION_KD11D, "KD11-D CPU. ..." },
1398 { "Kd_11_e*", OPTION_KD11E, "KD11-E CPU. ..." },
1399 { "Kd_11_f*", OPTION_KD11F, "KD11-F CPU. ..." },
1400 { "Kd_11_h*", OPTION_KD11H, "KD11-H CPU. ..." },
1401 { "Kd_11_q*", OPTION_KD11Q, "KD11-Q CPU. ..." },
1402 { "Kd_11_z*", OPTION_KD11Z, "KD11-Z CPU. ..." },
1403 { "Df_11_*", OPTION_F11, "F11 CPU. ..." },
1404 { "Dj_11_*", OPTION_J11, "J11 CPU. ..." },
1405 { "Dt_11_*", OPTION_T11, "T11 CPU. ..." },
1406};
1407
1408static struct options model_opts[] =
1409{
1410 { "P03", OPTION_PDP11_03, "same as ..." },
1411 { "P04", OPTION_PDP11_04, "same as ..." },
1412 { "P05", OPTION_PDP11_05, "same as ..." },
1413 { "P10", OPTION_PDP11_10, "same as ..." },
1414 { "P15", OPTION_PDP11_15, "same as ..." },
1415 { "P20", OPTION_PDP11_20, "same as ..." },
1416 { "P21", OPTION_PDP11_21, "same as ..." },
1417 { "P24", OPTION_PDP11_24, "same as ..." },
1418 { "P34", OPTION_PDP11_34, "same as ..." },
1419 { "P34a", OPTION_PDP11_34A, "same as ..." },
1420 { "P40", OPTION_PDP11_40, "same as ..." },
1421 { "P44", OPTION_PDP11_44, "same as ..." },
1422 { "P45", OPTION_PDP11_45, "same as ..." },
1423 { "P50", OPTION_PDP11_50, "same as ..." },
1424 { "P53", OPTION_PDP11_53, "same as ..." },
1425 { "P55", OPTION_PDP11_55, "same as ..." },
1426 { "P60", OPTION_PDP11_60, "same as ..." },
1427 { "P70", OPTION_PDP11_70, "same as ..." },
1428 { "P73", OPTION_PDP11_73, "same as ..." },
1429 { "P83", OPTION_PDP11_83, "same as ..." },
1430 { "P84", OPTION_PDP11_84, "same as ..." },
1431 { "P93", OPTION_PDP11_93, "same as ..." },
1432 { "P94", OPTION_PDP11_94, "same as ..." },
1433};
1434
1435struct
1436{
1437 const char *title;
1438 struct options *opts;
1439 int num;
1440} all_opts[] =
1441{
1442 { "PDP-11 instruction set extentions",
1443 extension_opts,
1444 sizeof extension_opts / sizeof extension_opts[0] },
1445 { "PDP-11 CPU model options",
1446 cpu_opts,
1447 sizeof cpu_opts / sizeof cpu_opts[0] },
1448 { "PDP-11 machine model options",
1449 model_opts,
1450 sizeof model_opts / sizeof model_opts[0] },
1451};
1452
1453int
1454parse_match (char *arg, char *pattern)
1455{
1456 int yes = 1;
1457
1458 while (*pattern)
1459 {
1460 switch (*pattern++)
1461 {
1462 case 'N':
1463 if (strncmp (arg, "no-") == 0)
1464 {
1465 yes = 0;
1466 arg += 3;
1467 }
1468 break;
1469
1470 case 'K':
1471 if (arg[0] == 'k')
1472 arg++;
1473 break;
1474
1475 case 'D':
1476 if (strncmp (arg, "kd", 2) == 0)
1477 arg +=2;
1478 break;
1479
1480 case 'P':
1481 if (strncmp (arg, "pdp-11/", 7) == 0)
1482 arg += 7;
1483 else if (strncmp (arg, "pdp11/", 6) == 0)
1484 arg += 6;
1485 else if (strncmp (arg, "11/", 3) == 0)
1486 arg += 3;
1487 break;
1488
1489 case '_':
1490 if (arg[0] == "-")
1491 {
1492 if (*++arg == 0)
1493 return 0;
1494 }
1495 break;
1496
1497 case '*':
1498 return 1;
1499
1500 default:
1501 if (*arg++ != pattern[-1])
1502 return 0;
1503 }
1504 }
1505
1506 return arg[0] == 0;
1507}
1508
1509int
1510fprint_opt (stream, pattern)
1511 FILE *stream;
1512 const char *pattern;
1513{
1514 int n;
1515
1516 while (*pattern)
1517 {
1518 switch (*pattern++)
1519 {
1520 case 'N':
1521 n += fprintf (stream, "(no-)");
1522 break;
1523
1524 case 'K':
1525 n += fprintf (stream, "k");
1526 break;
1527
1528 case 'P':
1529 n += fprintf (stream "11/");
1530 break;
1531
1532 case 'D':
1533 case '_':
1534 case '*':
1535 break;
1536
1537 default:
1538 fputc (pattern[-1], stream);
1539 n++;
1540 }
1541 }
1542
1543 return n;
1544}
1545
1546int
1547parse_option (char *arg)
1548{
1549 int i, j;
1550
1551 for (i = 0; i < sizeof all_opts / sizeof all_opts[0]; i++)
1552 {
1553 for (j = 0; j < all_opts[i].num; j++)
1554 {
1555 if (parse_match (arg, all_opts[i].opts[j].pattern))
1556 {
1557 set_option (all_opts[i].opts[j].opt);
1558 return 1;
1559 }
1560 }
1561 }
1562
1563 return 0;
1564}
1565
1566static void
1567fprint_space (stream, n)
1568 FILE *stream;
1569 int n;
1570{
1571 while (n--)
1572 fputc (' ', stream);
1573}
1574
1575void
1576md_show_usage (stream)
1577 FILE *stream;
1578{
1579 int i, j, n;
1580
1581 for (i = 0; i < sizeof all_opts / sizeof all_opts[0]; i++)
1582 {
1583 fprintf (stream "\n%s:\n\n", all_opts[i].title);
1584
1585 for (j = 0; j < all_opts[i].num; j++)
1586 {
1587 fprintf (stream, "-m");
1588 n = fprintf_opt (stream, all_opts[i].opts[j].pattern);
1589 fprint_space (stream, 22 - n);
1590 fprintf (stream, "%s\n", all_opts[i].opts[j].description);
1591 }
1592 }
1593}
1594*/
1595
1596void
1597md_show_usage (stream)
1598 FILE *stream;
1599{
1600 fprintf (stream, "\
1601\n\
1602PDP-11 instruction set extentions:\n\
1603\n\
1604-m(no-)cis allow (disallow) commersial instruction set\n\
1605-m(no-)csm allow (disallow) CSM instruction\n\
1606-m(no-)eis allow (disallow) full extended instruction set\n\
1607-m(no-)fis allow (disallow) KEV11 floating-point instructions\n\
1608-m(no-)fpp allow (disallow) FP-11 floating-point instructions\n\
1609-m(no-)fpu allow (disallow) FP-11 floating-point instructions\n\
1610-m(no-)limited-eis allow (disallow) limited extended instruction set\n\
1611-m(no-)mfpt allow (disallow) processor type instruction\n\
1612-m(no-)multiproc allow (disallow) multiprocessor instructions\n\
1613-m(no-)mxps allow (disallow) processor status instructions\n\
1614-m(no-)spl allow (disallow) SPL instruction\n\
1615-m(no-)ucode allow (disallow) microcode instructions\n\
1616-mall-extensions allow all instruction set extensions\n\
1617 (this is the default)\n\
1618-mno-extentions disallow all instruction set extensions\n\
1619-pic generate position-indepenent code\n\
1620\n\
1621PDP-11 CPU model options:\n\
1622\n\
1623-mka11* KA11 CPU. base line instruction set only\n\
1624-mkb11* KB11 CPU. enable full EIS and SPL\n\
1625-mkd11a* KD11-A CPU. enable limited EIS\n\
1626-mkd11b* KD11-B CPU. base line instruction set only\n\
1627-mkd11d* KD11-D CPU. base line instruction set only\n\
1628-mkd11e* KD11-E CPU. enable full EIS, MTPS, and MFPS\n\
1629-mkd11f* KD11-F CPU. enable limited EIS, MTPS, and MFPS\n\
1630-mkd11h* KD11-H CPU. enable limited EIS, MTPS, and MFPS\n\
1631-mkd11q* KD11-Q CPU. enable limited EIS, MTPS, and MFPS\n\
1632-mkd11k* KD11-K CPU. enable full EIS, MTPS, MFPS, LDUB, MED,\n\
1633 XFC, and MFPT\n\
1634-mkd11z* KD11-Z CPU. enable full EIS, MTPS, MFPS, MFPT, SPL,\n\
1635 and CSM\n\
1636-mf11* F11 CPU. enable full EIS, MFPS, MTPS, and MFPT\n\
1637-mj11* J11 CPU. enable full EIS, MTPS, MFPS, MFPT, SPL,\n\
1638 CSM, TSTSET, and WRTLCK\n\
1639-mt11* T11 CPU. enable limited EIS, MTPS, and MFPS\n\
1640\n\
1641PDP-11 machine model options:\n\
1642\n\
1643-m11/03 same as -mkd11f\n\
1644-m11/04 same as -mkd11d\n\
1645-m11/05 same as -mkd11b\n\
1646-m11/10 same as -mkd11b\n\
1647-m11/15 same as -mka11\n\
1648-m11/20 same as -mka11\n\
1649-m11/21 same as -mt11\n\
1650-m11/23 same as -mf11\n\
1651-m11/24 same as -mf11\n\
1652-m11/34 same as -mkd11e\n\
1653-m11/34a same as -mkd11e -mfpp\n\
1654-m11/35 same as -mkd11a\n\
1655-m11/40 same as -mkd11a\n\
1656-m11/44 same as -mkd11z\n\
1657-m11/45 same as -mkb11\n\
1658-m11/50 same as -mkb11\n\
1659-m11/53 same as -mj11\n\
1660-m11/55 same as -mkb11\n\
1661-m11/60 same as -mkd11k\n\
1662-m11/70 same as -mkb11\n\
1663-m11/73 same as -mj11\n\
1664-m11/83 same as -mj11\n\
1665-m11/84 same as -mj11\n\
1666-m11/93 same as -mj11\n\
1667-m11/94 same as -mj11\n\
1668");
1669}
1670
1671symbolS *
1672md_undefined_symbol (name)
1673 char *name ATTRIBUTE_UNUSED;
1674{
1675 return 0;
1676}
1677
1678valueT
1679md_section_align (segment, size)
1680 segT segment ATTRIBUTE_UNUSED;
1681 valueT size;
1682{
1683 return (size + 1) & ~1;
1684}
1685
1686long
1687md_pcrel_from (fixP)
1688 fixS *fixP;
1689{
1690 return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1691}
1692
1693/* Translate internal representation of relocation info to BFD target
1694 format. */
1695arelent *
1696tc_gen_reloc (section, fixp)
1697 asection *section ATTRIBUTE_UNUSED;
1698 fixS *fixp;
1699{
1700 arelent *reloc;
1701 bfd_reloc_code_real_type code;
1702
1703 reloc = (arelent *) xmalloc (sizeof (arelent));
1704
1705 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1706 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1707 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1708
1709 /* This is taken account for in md_apply_fix3(). */
1710 reloc->addend = -symbol_get_bfdsym (fixp->fx_addsy)->section->vma;
1711
1712 switch (fixp->fx_r_type)
1713 {
1714 case BFD_RELOC_16:
1715 if (fixp->fx_pcrel)
1716 code = BFD_RELOC_16_PCREL;
1717 else
1718 code = BFD_RELOC_16;
1719 break;
1720
1721 case BFD_RELOC_16_PCREL:
1722 code = BFD_RELOC_16_PCREL;
1723 break;
1724
1725 default:
1726 BAD_CASE (fixp->fx_r_type);
1727 return NULL;
1728 }
1729
1730 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
1731
1732 if (reloc->howto == NULL)
1733 {
1734 as_bad_where (fixp->fx_file, fixp->fx_line,
1735 "Can not represent %s relocation in this object file format",
1736 bfd_get_reloc_code_name (code));
1737 return NULL;
1738 }
1739
1740 return reloc;
1741}
1742
1743void
1744pseudo_bss (c)
1745 int c ATTRIBUTE_UNUSED;
1746{
1747 int temp;
1748
1749 temp = get_absolute_expression ();
1750 subseg_set (bss_section, temp);
1751 demand_empty_rest_of_line ();
1752}
1753
1754void
1755pseudo_even (c)
1756 int c ATTRIBUTE_UNUSED;
1757{
1758 int alignment = 1; /* 2^1 */
1759 frag_align (alignment, 0, 1);
1760 record_alignment (now_seg, alignment);
1761}
1762
1763/* end of tc-pdp11.c */
Note: See TracBrowser for help on using the repository browser.