1 /* tc-pdp11.c - pdp11-specific -
2 Copyright 2001, 2002 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
21 Apparently unused functions:
23 md_estimate_size_before_relax
29 #include "safe-ctype.h"
30 #include "opcode/pdp11.h"
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
));
36 extern int flonum_gen2vax
PARAMS ((char format_letter
, FLONUM_TYPE
* f
,
37 LITTLENUM_TYPE
* words
));
43 * A representation for PDP-11 machine code.
49 int additional
; /* is there an additional word? */
50 int word
; /* additional word, if any */
53 bfd_reloc_code_real_type type
;
60 * Instruction set extensions.
62 * If you change this from an array to something else, please update
63 * the "PDP-11 instruction set extensions" comment in pdp11.h.
65 int pdp11_extension
[PDP11_EXT_NUM
];
74 int asm_option
[ASM_OPT_NUM
];
76 /* These chars start a comment anywhere in a source file (except inside
78 const char comment_chars
[] = "#/";
80 /* These chars only start a comment at the beginning of a line. */
81 const char line_comment_chars
[] = "#/";
83 const char line_separator_chars
[] = ";";
85 /* Chars that can be used to separate mant from exp in floating point nums */
86 const char EXP_CHARS
[] = "eE";
88 /* Chars that mean this number is a floating point constant */
90 /* or 0H1.234E-12 (see exp chars above) */
91 const char FLT_CHARS
[] = "dDfF";
93 void pseudo_even (int);
94 void pseudo_bss (int);
96 const pseudo_typeS md_pseudo_table
[] =
98 { "bss", pseudo_bss
, 0 },
99 { "even", pseudo_even
, 0 },
106 static int first
= 1;
110 set_option ("all-extensions");
116 static struct hash_control
*insn_hash
= NULL
;
125 insn_hash
= hash_new ();
126 if (insn_hash
== NULL
)
127 as_fatal ("Virtual memory exhausted");
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
));
136 md_number_to_chars (con
, value
, nbytes
)
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.
151 con
[0] = value
& 0xff;
154 con
[0] = value
& 0xff;
155 con
[1] = (value
>> 8) & 0xff;
158 con
[0] = (value
>> 16) & 0xff;
159 con
[1] = (value
>> 24) & 0xff;
160 con
[2] = value
& 0xff;
161 con
[3] = (value
>> 8) & 0xff;
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. */
172 md_apply_fix3 (fixP
, valP
, seg
)
175 segT seg ATTRIBUTE_UNUSED
;
184 buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
185 size
= fixP
->fx_size
;
186 code
= md_chars_to_number (buf
, size
);
188 switch (fixP
->fx_r_type
)
191 case BFD_RELOC_16_PCREL
:
195 case BFD_RELOC_PDP11_DISP_8_PCREL
:
199 case BFD_RELOC_PDP11_DISP_6_PCREL
:
204 BAD_CASE (fixP
->fx_r_type
);
207 if (fixP
->fx_addsy
!= NULL
)
208 val
+= symbol_get_bfdsym (fixP
->fx_addsy
)->section
->vma
;
209 /* *value += fixP->fx_addsy->bsym->section->vma; */
212 code
|= (val
>> shift
) & mask
;
213 number_to_chars_littleendian (buf
, code
, size
);
215 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
220 md_chars_to_number (con
, nbytes
)
221 unsigned char con
[]; /* Low order byte 1st. */
222 int nbytes
; /* Number of bytes in the input. */
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.
236 return (con
[1] << BITS_PER_CHAR
) | con
[0];
239 (((con
[1] << BITS_PER_CHAR
) | con
[0]) << (2 * BITS_PER_CHAR
)) |
240 ((con
[3] << BITS_PER_CHAR
) | con
[2]);
248 skip_whitespace (char *str
)
250 while (*str
== ' ' || *str
== '\t')
256 find_whitespace (char *str
)
258 while (*str
!= ' ' && *str
!= '\t' && *str
!= 0)
264 parse_reg (char *str
, struct pdp11_code
*operand
)
266 str
= skip_whitespace (str
);
267 if (TOLOWER (*str
) == 'r')
272 case '0': case '1': case '2': case '3':
273 case '4': case '5': case '6': case '7':
274 operand
->code
= *str
- '0';
278 operand
->error
= "Bad register name";
282 else if (strncmp (str
, "sp", 2) == 0 ||
283 strncmp (str
, "SP", 2) == 0)
288 else if (strncmp (str
, "pc", 2) == 0 ||
289 strncmp (str
, "PC", 2) == 0)
296 operand
->error
= "Bad register name";
304 parse_ac5 (char *str
, struct pdp11_code
*operand
)
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)
315 case '0': case '1': case '2': case '3':
317 operand
->code
= *str
- '0';
321 operand
->error
= "Bad register name";
327 operand
->error
= "Bad register name";
335 parse_ac (char *str
, struct pdp11_code
*operand
)
337 str
= parse_ac5 (str
, operand
);
338 if (!operand
->error
&& operand
->code
> 3)
340 operand
->error
= "Bad register name";
348 parse_expression (char *str
, struct pdp11_code
*operand
)
350 char *save_input_line_pointer
;
353 save_input_line_pointer
= input_line_pointer
;
354 input_line_pointer
= str
;
355 seg
= expression (&operand
->reloc
.exp
);
358 input_line_pointer
= save_input_line_pointer
;
359 operand
->error
= "Error in expression";
363 str
= input_line_pointer
;
364 input_line_pointer
= save_input_line_pointer
;
366 operand
->reloc
.pc_rel
= 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
377 if (operand
->reloc
.exp
.X_op
== O_constant
)
383 /* FIXME: buffer overflow! */
387 sprintf (buf
, "%ld", operand
->reloc
.exp
.X_add_number
);
388 operand
->reloc
.exp
.X_add_number
= strtol (buf
, &end
, 8);
396 parse_op_no_deferred (char *str
, struct pdp11_code
*operand
)
398 LITTLENUM_TYPE literal_float
[2];
400 str
= skip_whitespace (str
);
404 case '(': /* (rn) and (rn)+ */
405 str
= parse_reg (str
+ 1, operand
);
408 str
= skip_whitespace (str
);
411 operand
->error
= "Missing ')'";
417 operand
->code
|= 020;
422 operand
->code
|= 010;
426 case '#': /* immediate */
428 str
= parse_expression (str
+ 1, operand
);
431 operand
->additional
= TRUE
;
432 operand
->word
= operand
->reloc
.exp
.X_add_number
;
433 switch (operand
->reloc
.exp
.X_op
)
440 operand
->reloc
.type
= BFD_RELOC_16
;
441 operand
->reloc
.pc_rel
= 0;
444 if (operand
->reloc
.exp
.X_add_number
> 0)
446 operand
->error
= "Error in expression";
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"));
457 operand
->error
= "Error in expression";
463 default: /* label, d(rn), -(rn) */
467 if (strncmp (str
, "-(", 2) == 0) /* -(rn) */
469 str
= parse_reg (str
+ 2, operand
);
472 str
= skip_whitespace (str
);
475 operand
->error
= "Missing ')'";
478 operand
->code
|= 040;
483 str
= parse_expression (str
, operand
);
487 str
= skip_whitespace (str
);
489 if (*str
!= '(') /* label */
491 if (operand
->reloc
.exp
.X_op
!= O_symbol
)
493 operand
->error
= "Label expected";
497 operand
->additional
= 1;
499 operand
->reloc
.type
= BFD_RELOC_16_PCREL
;
500 operand
->reloc
.pc_rel
= 1;
505 str
= parse_reg (str
, operand
);
509 str
= skip_whitespace (str
);
513 operand
->error
= "Missing ')'";
518 operand
->additional
= TRUE
;
519 operand
->code
|= 060;
520 switch (operand
->reloc
.exp
.X_op
)
524 operand
->reloc
.pc_rel
= 1;
527 if ((operand
->code
& 7) == 7)
529 operand
->reloc
.pc_rel
= 1;
530 operand
->word
= operand
->reloc
.exp
.X_add_number
;
534 operand
->word
= operand
->reloc
.exp
.X_add_number
;
538 BAD_CASE (operand
->reloc
.exp
.X_op
);
548 parse_op_noreg (char *str
, struct pdp11_code
*operand
)
550 str
= skip_whitespace (str
);
551 operand
->error
= NULL
;
553 if (*str
== '@' || *str
== '*')
555 str
= parse_op_no_deferred (str
+ 1, operand
);
558 operand
->code
|= 010;
561 str
= parse_op_no_deferred (str
, operand
);
567 parse_op (char *str
, struct pdp11_code
*operand
)
569 str
= skip_whitespace (str
);
571 str
= parse_reg (str
, operand
);
575 operand
->error
= NULL
;
576 parse_ac5 (str
, operand
);
579 operand
->error
= "Float AC not legal as integer operand";
583 return parse_op_noreg (str
, operand
);
587 parse_fop (char *str
, struct pdp11_code
*operand
)
589 str
= skip_whitespace (str
);
591 str
= parse_ac5 (str
, operand
);
595 operand
->error
= NULL
;
596 parse_reg (str
, operand
);
599 operand
->error
= "General register not legal as float operand";
603 return parse_op_noreg (str
, operand
);
607 parse_separator (char *str
, int *error
)
609 str
= skip_whitespace (str
);
610 *error
= (*str
!= ',');
617 md_assemble (instruction_string
)
618 char *instruction_string
;
620 const struct pdp11_opcode
*op
;
621 struct pdp11_code insn
, op1
, op2
;
629 str
= skip_whitespace (instruction_string
);
630 p
= find_whitespace (str
);
633 as_bad ("No instruction found");
639 op
= (struct pdp11_opcode
*)hash_find (insn_hash
, str
);
645 op1
.additional
= FALSE
;
646 op1
.reloc
.type
= BFD_RELOC_NONE
;
649 str
= parse_expression (str
, &op1
);
657 char *to
= frag_more (2);
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
);
665 as_bad (_("Unknown instruction '%s'"), str
);
671 if (!pdp11_extension
[op
->extension
])
673 as_warn ("Unsupported instruction set extension: %s", op
->name
);
678 insn
.code
= op
->opcode
;
679 insn
.reloc
.type
= BFD_RELOC_NONE
;
681 op1
.additional
= FALSE
;
682 op1
.reloc
.type
= BFD_RELOC_NONE
;
684 op2
.additional
= FALSE
;
685 op2
.reloc
.type
= BFD_RELOC_NONE
;
692 case PDP11_OPCODE_NO_OPS
:
693 str
= skip_whitespace (str
);
698 case PDP11_OPCODE_IMM3
:
699 case PDP11_OPCODE_IMM6
:
700 case PDP11_OPCODE_IMM8
:
701 str
= skip_whitespace (str
);
702 if (*str
== '#' || *str
== '$')
704 str
= parse_expression (str
, &op1
);
707 if (op1
.reloc
.exp
.X_op
!= O_constant
|| op1
.reloc
.type
!= BFD_RELOC_NONE
)
709 op1
.error
= "operand is not an absolute constant";
714 case PDP11_OPCODE_IMM3
:
715 if (op1
.reloc
.exp
.X_add_number
& ~7)
717 op1
.error
= "3-bit immediate out of range";
721 case PDP11_OPCODE_IMM6
:
722 if (op1
.reloc
.exp
.X_add_number
& ~0x3f)
724 op1
.error
= "6-bit immediate out of range";
728 case PDP11_OPCODE_IMM8
:
729 if (op1
.reloc
.exp
.X_add_number
& ~0xff)
731 op1
.error
= "8-bit immediate out of range";
736 insn
.code
|= op1
.reloc
.exp
.X_add_number
;
739 case PDP11_OPCODE_DISPL
:
742 new = parse_expression (str
, &op1
);
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
)
748 op1
.error
= "Symbol expected";
751 if (op1
.code
& ~0xff)
753 err
= "8-bit displacement out of range";
757 insn
.code
|= op1
.code
;
758 insn
.reloc
= op1
.reloc
;
762 case PDP11_OPCODE_REG
:
763 str
= parse_reg (str
, &op1
);
766 insn
.code
|= op1
.code
;
769 case PDP11_OPCODE_OP
:
770 str
= parse_op (str
, &op1
);
773 insn
.code
|= op1
.code
;
778 case PDP11_OPCODE_FOP
:
779 str
= parse_fop (str
, &op1
);
782 insn
.code
|= op1
.code
;
787 case PDP11_OPCODE_REG_OP
:
788 str
= parse_reg (str
, &op2
);
791 insn
.code
|= op2
.code
<< 6;
792 str
= parse_separator (str
, &error
);
795 op2
.error
= "Missing ','";
798 str
= parse_op (str
, &op1
);
801 insn
.code
|= op1
.code
;
806 case PDP11_OPCODE_REG_OP_REV
:
807 str
= parse_op (str
, &op1
);
810 insn
.code
|= op1
.code
;
813 str
= parse_separator (str
, &error
);
816 op2
.error
= "Missing ','";
819 str
= parse_reg (str
, &op2
);
822 insn
.code
|= op2
.code
<< 6;
825 case PDP11_OPCODE_AC_FOP
:
826 str
= parse_ac (str
, &op2
);
829 insn
.code
|= op2
.code
<< 6;
830 str
= parse_separator (str
, &error
);
833 op1
.error
= "Missing ','";
836 str
= parse_fop (str
, &op1
);
839 insn
.code
|= op1
.code
;
844 case PDP11_OPCODE_FOP_AC
:
845 str
= parse_fop (str
, &op1
);
848 insn
.code
|= op1
.code
;
851 str
= parse_separator (str
, &error
);
854 op1
.error
= "Missing ','";
857 str
= parse_ac (str
, &op2
);
860 insn
.code
|= op2
.code
<< 6;
863 case PDP11_OPCODE_AC_OP
:
864 str
= parse_ac (str
, &op2
);
867 insn
.code
|= op2
.code
<< 6;
868 str
= parse_separator (str
, &error
);
871 op1
.error
= "Missing ','";
874 str
= parse_op (str
, &op1
);
877 insn
.code
|= op1
.code
;
882 case PDP11_OPCODE_OP_AC
:
883 str
= parse_op (str
, &op1
);
886 insn
.code
|= op1
.code
;
889 str
= parse_separator (str
, &error
);
892 op1
.error
= "Missing ','";
895 str
= parse_ac (str
, &op2
);
898 insn
.code
|= op2
.code
<< 6;
901 case PDP11_OPCODE_OP_OP
:
902 str
= parse_op (str
, &op1
);
905 insn
.code
|= op1
.code
<< 6;
908 str
= parse_separator (str
, &error
);
911 op2
.error
= "Missing ','";
914 str
= parse_op (str
, &op2
);
917 insn
.code
|= op2
.code
;
922 case PDP11_OPCODE_REG_DISPL
:
925 str
= parse_reg (str
, &op2
);
928 insn
.code
|= op2
.code
<< 6;
929 str
= parse_separator (str
, &error
);
932 op1
.error
= "Missing ','";
935 new = parse_expression (str
, &op1
);
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
)
941 op1
.error
= "Symbol expected";
944 if (op1
.code
& ~0x3f)
946 err
= "6-bit displacement out of range";
950 insn
.code
|= op1
.code
;
951 insn
.reloc
= op1
.reloc
;
965 str
= skip_whitespace (str
);
967 err
= "Too many operands";
979 to
= frag_more (size
);
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
);
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
);
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
);
1007 md_estimate_size_before_relax (fragP
, segment
)
1008 fragS
*fragP ATTRIBUTE_UNUSED
;
1009 segT segment ATTRIBUTE_UNUSED
;
1015 md_convert_frag (headers
, seg
, fragP
)
1016 bfd
*headers ATTRIBUTE_UNUSED
;
1017 segT seg ATTRIBUTE_UNUSED
;
1018 fragS
*fragP ATTRIBUTE_UNUSED
;
1022 const int md_short_jump_size
= 2;
1023 const int md_long_jump_size
= 4;
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
;
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
;
1051 if (strcmp (arg
, "all-extensions") == 0 ||
1052 strcmp (arg
, "all") == 0)
1054 memset (pdp11_extension
, ~0, sizeof pdp11_extension
);
1055 pdp11_extension
[PDP11_NONE
] = 0;
1058 else if (strcmp (arg
, "no-extensions") == 0)
1060 memset (pdp11_extension
, 0, sizeof pdp11_extension
);
1061 pdp11_extension
[PDP11_BASIC
] = 1;
1065 if (strncmp (arg
, "no-", 3) == 0)
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 */
1091 pdp11_extension
[PDP11_LEIS
] = yes
;
1092 if (!pdp11_extension
[PDP11_LEIS
])
1093 pdp11_extension
[PDP11_EIS
] = 0;
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
;
1127 if (strchr ("abdx", model
[-1]) == NULL
)
1130 if (model
[-1] == 'd')
1132 if (arg
[0] == 'f' ||
1136 else if (model
[-1] == 'x')
1145 if (strncmp (arg
, "11", 2) != 0)
1155 /* allow up to two revision letters */
1163 set_option ("no-extensions");
1165 if (strncmp (buf
, "a", 1) == 0) /* KA11 (11/15/20) */
1166 return 1; /* no extensions */
1168 else if (strncmp (buf
, "b", 1) == 0) /* KB11 (11/45/50/55/70) */
1169 return set_option ("eis") &&
1172 else if (strncmp (buf
, "da", 2) == 0) /* KD11-A (11/35/40) */
1173 return set_option ("limited-eis");
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 */
1179 else if (strncmp (buf
, "de", 2) == 0) /* KD11-E (11/34) */
1180 return set_option ("eis") &&
1181 set_option ("mxps");
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");
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");
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") &&
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");
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") &&
1214 else if (strncmp (buf
, "t", 1) == 0) /* T11 (11/21) */
1215 return set_option ("limited-eis") &&
1216 set_option ("mxps");
1223 set_machine_model (arg
)
1226 if (strncmp (arg
, "pdp-11/", 7) != 0 &&
1227 strncmp (arg
, "pdp11/", 6) != 0 &&
1228 strncmp (arg
, "11/", 3) != 0)
1231 if (strncmp (arg
, "pdp", 3) == 0)
1235 if (strncmp (arg
, "11/", 3) == 0)
1238 if (strcmp (arg
, "03") == 0) /* 11/03 */
1239 return set_cpu_model ("kd11f"); /* KD11-F */
1241 else if (strcmp (arg
, "04") == 0) /* 11/04 */
1242 return set_cpu_model ("kd11d"); /* KD11-D */
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 */
1248 else if (strcmp (arg
, "15") == 0 || /* 11/15 or 11/20 */
1249 strcmp (arg
, "20") == 0)
1250 return set_cpu_model ("ka11"); /* KA11 */
1252 else if (strcmp (arg
, "21") == 0) /* 11/21 */
1253 return set_cpu_model ("t11"); /* T11 */
1255 else if (strcmp (arg
, "23") == 0 || /* 11/23 or 11/24 */
1256 strcmp (arg
, "24") == 0)
1257 return set_cpu_model ("f11"); /* F11 */
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 */
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 */
1267 else if (strcmp (arg
, "44") == 0) /* 11/44 */
1268 return set_cpu_model ("kd11dz"); /* KD11-Z */
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 */
1276 else if (strcmp (arg
, "60") == 0) /* 11/60 */
1277 return set_cpu_model ("kd11k"); /* KD11-K */ /* FPP? */
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. */
1292 const char *md_shortopts
= "m:";
1294 struct option md_longopts
[] =
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 }
1305 size_t md_longopts_size
= sizeof (md_longopts
);
1309 * Invocation line includes a switch not recognized by the base assembler.
1310 * See if it's a processor-specific option.
1314 md_parse_option (c
, arg
)
1323 if (set_option (arg
))
1325 if (set_cpu_model (arg
))
1327 if (set_machine_model (arg
))
1332 if (set_cpu_model (arg
))
1336 case OPTION_MACHINE
:
1337 if (set_machine_model (arg
))
1342 if (set_option ("pic"))
1350 as_bad ("unrecognized option `-%c%s'", c
, arg
? arg
: "");
1356 One possible way of parsing options.
1367 const char *pattern;
1369 const char *description;
1372 static struct options extension_opts[] =
1374 { "Ncsm", OPTION_CSM,
1375 "allow (disallow) CSM instruction" },
1376 { "Ncis", OPTION_CIS,
1377 "allow (disallow) commersial instruction set" },
1378 { "Neis", OPTION_EIS,
1379 "allow (disallow) extended instruction set" },
1381 { "all-extensions", OPTION_ALL_EXTENSIONS,
1382 "allow all instruction set extensions\n\
1383 (this is the default)" },
1384 { "no-extensions", OPTION_NO_EXTENSIONS,
1385 "disallow all instruction set extensions" },
1386 { "pic", OPTION_PIC,
1387 "position-independent code" },
1390 static struct options cpu_opts[] =
1392 { "Ka_11_*", OPTION_KA11, "KA11 CPU. ..." },
1393 { "Kb_11_*", OPTION_KB11, "KB11 CPU. ..." },
1394 { "Kd_11_a*", OPTION_KD11A, "KD11-A CPU. ..." },
1395 { "Kd_11_b*", OPTION_KD11B, "KD11-B CPU. ..." },
1396 { "Kd_11_d*", OPTION_KD11D, "KD11-D CPU. ..." },
1397 { "Kd_11_e*", OPTION_KD11E, "KD11-E CPU. ..." },
1398 { "Kd_11_f*", OPTION_KD11F, "KD11-F CPU. ..." },
1399 { "Kd_11_h*", OPTION_KD11H, "KD11-H CPU. ..." },
1400 { "Kd_11_q*", OPTION_KD11Q, "KD11-Q CPU. ..." },
1401 { "Kd_11_z*", OPTION_KD11Z, "KD11-Z CPU. ..." },
1402 { "Df_11_*", OPTION_F11, "F11 CPU. ..." },
1403 { "Dj_11_*", OPTION_J11, "J11 CPU. ..." },
1404 { "Dt_11_*", OPTION_T11, "T11 CPU. ..." },
1407 static struct options model_opts[] =
1409 { "P03", OPTION_PDP11_03, "same as ..." },
1410 { "P04", OPTION_PDP11_04, "same as ..." },
1411 { "P05", OPTION_PDP11_05, "same as ..." },
1412 { "P10", OPTION_PDP11_10, "same as ..." },
1413 { "P15", OPTION_PDP11_15, "same as ..." },
1414 { "P20", OPTION_PDP11_20, "same as ..." },
1415 { "P21", OPTION_PDP11_21, "same as ..." },
1416 { "P24", OPTION_PDP11_24, "same as ..." },
1417 { "P34", OPTION_PDP11_34, "same as ..." },
1418 { "P34a", OPTION_PDP11_34A, "same as ..." },
1419 { "P40", OPTION_PDP11_40, "same as ..." },
1420 { "P44", OPTION_PDP11_44, "same as ..." },
1421 { "P45", OPTION_PDP11_45, "same as ..." },
1422 { "P50", OPTION_PDP11_50, "same as ..." },
1423 { "P53", OPTION_PDP11_53, "same as ..." },
1424 { "P55", OPTION_PDP11_55, "same as ..." },
1425 { "P60", OPTION_PDP11_60, "same as ..." },
1426 { "P70", OPTION_PDP11_70, "same as ..." },
1427 { "P73", OPTION_PDP11_73, "same as ..." },
1428 { "P83", OPTION_PDP11_83, "same as ..." },
1429 { "P84", OPTION_PDP11_84, "same as ..." },
1430 { "P93", OPTION_PDP11_93, "same as ..." },
1431 { "P94", OPTION_PDP11_94, "same as ..." },
1437 struct options *opts;
1441 { "PDP-11 instruction set extentions",
1443 sizeof extension_opts / sizeof extension_opts[0] },
1444 { "PDP-11 CPU model options",
1446 sizeof cpu_opts / sizeof cpu_opts[0] },
1447 { "PDP-11 machine model options",
1449 sizeof model_opts / sizeof model_opts[0] },
1453 parse_match (char *arg, char *pattern)
1462 if (strncmp (arg, "no-") == 0)
1475 if (strncmp (arg, "kd", 2) == 0)
1480 if (strncmp (arg, "pdp-11/", 7) == 0)
1482 else if (strncmp (arg, "pdp11/", 6) == 0)
1484 else if (strncmp (arg, "11/", 3) == 0)
1500 if (*arg++ != pattern[-1])
1509 fprint_opt (stream, pattern)
1511 const char *pattern;
1520 n += fprintf (stream, "(no-)");
1524 n += fprintf (stream, "k");
1528 n += fprintf (stream "11/");
1537 fputc (pattern[-1], stream);
1546 parse_option (char *arg)
1550 for (i = 0; i < sizeof all_opts / sizeof all_opts[0]; i++)
1552 for (j = 0; j < all_opts[i].num; j++)
1554 if (parse_match (arg, all_opts[i].opts[j].pattern))
1556 set_option (all_opts[i].opts[j].opt);
1566 fprint_space (stream, n)
1571 fputc (' ', stream);
1575 md_show_usage (stream)
1580 for (i = 0; i < sizeof all_opts / sizeof all_opts[0]; i++)
1582 fprintf (stream "\n%s:\n\n", all_opts[i].title);
1584 for (j = 0; j < all_opts[i].num; j++)
1586 fprintf (stream, "-m");
1587 n = fprintf_opt (stream, all_opts[i].opts[j].pattern);
1588 fprint_space (stream, 22 - n);
1589 fprintf (stream, "%s\n", all_opts[i].opts[j].description);
1596 md_show_usage (stream
)
1601 PDP-11 instruction set extentions:\n\
1603 -m(no-)cis allow (disallow) commersial instruction set\n\
1604 -m(no-)csm allow (disallow) CSM instruction\n\
1605 -m(no-)eis allow (disallow) full extended instruction set\n\
1606 -m(no-)fis allow (disallow) KEV11 floating-point instructions\n\
1607 -m(no-)fpp allow (disallow) FP-11 floating-point instructions\n\
1608 -m(no-)fpu allow (disallow) FP-11 floating-point instructions\n\
1609 -m(no-)limited-eis allow (disallow) limited extended instruction set\n\
1610 -m(no-)mfpt allow (disallow) processor type instruction\n\
1611 -m(no-)multiproc allow (disallow) multiprocessor instructions\n\
1612 -m(no-)mxps allow (disallow) processor status instructions\n\
1613 -m(no-)spl allow (disallow) SPL instruction\n\
1614 -m(no-)ucode allow (disallow) microcode instructions\n\
1615 -mall-extensions allow all instruction set extensions\n\
1616 (this is the default)\n\
1617 -mno-extentions disallow all instruction set extensions\n\
1618 -pic generate position-indepenent code\n\
1620 PDP-11 CPU model options:\n\
1622 -mka11* KA11 CPU. base line instruction set only\n\
1623 -mkb11* KB11 CPU. enable full EIS and SPL\n\
1624 -mkd11a* KD11-A CPU. enable limited EIS\n\
1625 -mkd11b* KD11-B CPU. base line instruction set only\n\
1626 -mkd11d* KD11-D CPU. base line instruction set only\n\
1627 -mkd11e* KD11-E CPU. enable full EIS, MTPS, and MFPS\n\
1628 -mkd11f* KD11-F CPU. enable limited EIS, MTPS, and MFPS\n\
1629 -mkd11h* KD11-H CPU. enable limited EIS, MTPS, and MFPS\n\
1630 -mkd11q* KD11-Q CPU. enable limited EIS, MTPS, and MFPS\n\
1631 -mkd11k* KD11-K CPU. enable full EIS, MTPS, MFPS, LDUB, MED,\n\
1633 -mkd11z* KD11-Z CPU. enable full EIS, MTPS, MFPS, MFPT, SPL,\n\
1635 -mf11* F11 CPU. enable full EIS, MFPS, MTPS, and MFPT\n\
1636 -mj11* J11 CPU. enable full EIS, MTPS, MFPS, MFPT, SPL,\n\
1637 CSM, TSTSET, and WRTLCK\n\
1638 -mt11* T11 CPU. enable limited EIS, MTPS, and MFPS\n\
1640 PDP-11 machine model options:\n\
1642 -m11/03 same as -mkd11f\n\
1643 -m11/04 same as -mkd11d\n\
1644 -m11/05 same as -mkd11b\n\
1645 -m11/10 same as -mkd11b\n\
1646 -m11/15 same as -mka11\n\
1647 -m11/20 same as -mka11\n\
1648 -m11/21 same as -mt11\n\
1649 -m11/23 same as -mf11\n\
1650 -m11/24 same as -mf11\n\
1651 -m11/34 same as -mkd11e\n\
1652 -m11/34a same as -mkd11e -mfpp\n\
1653 -m11/35 same as -mkd11a\n\
1654 -m11/40 same as -mkd11a\n\
1655 -m11/44 same as -mkd11z\n\
1656 -m11/45 same as -mkb11\n\
1657 -m11/50 same as -mkb11\n\
1658 -m11/53 same as -mj11\n\
1659 -m11/55 same as -mkb11\n\
1660 -m11/60 same as -mkd11k\n\
1661 -m11/70 same as -mkb11\n\
1662 -m11/73 same as -mj11\n\
1663 -m11/83 same as -mj11\n\
1664 -m11/84 same as -mj11\n\
1665 -m11/93 same as -mj11\n\
1666 -m11/94 same as -mj11\n\
1671 md_undefined_symbol (name
)
1672 char *name ATTRIBUTE_UNUSED
;
1678 md_section_align (segment
, size
)
1679 segT segment ATTRIBUTE_UNUSED
;
1682 return (size
+ 1) & ~1;
1686 md_pcrel_from (fixP
)
1689 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ fixP
->fx_size
;
1692 /* Translate internal representation of relocation info to BFD target
1695 tc_gen_reloc (section
, fixp
)
1696 asection
*section ATTRIBUTE_UNUSED
;
1700 bfd_reloc_code_real_type code
;
1702 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1704 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1705 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1706 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1708 /* This is taken account for in md_apply_fix3(). */
1709 reloc
->addend
= -symbol_get_bfdsym (fixp
->fx_addsy
)->section
->vma
;
1711 switch (fixp
->fx_r_type
)
1715 code
= BFD_RELOC_16_PCREL
;
1717 code
= BFD_RELOC_16
;
1720 case BFD_RELOC_16_PCREL
:
1721 code
= BFD_RELOC_16_PCREL
;
1725 BAD_CASE (fixp
->fx_r_type
);
1729 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
1731 if (reloc
->howto
== NULL
)
1733 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1734 "Can not represent %s relocation in this object file format",
1735 bfd_get_reloc_code_name (code
));
1744 int c ATTRIBUTE_UNUSED
;
1748 temp
= get_absolute_expression ();
1749 subseg_set (bss_section
, temp
);
1750 demand_empty_rest_of_line ();
1755 int c ATTRIBUTE_UNUSED
;
1757 int alignment
= 1; /* 2^1 */
1758 frag_align (alignment
, 0, 1);
1759 record_alignment (now_seg
, alignment
);
1762 /* end of tc-pdp11.c */