1 /* tc-pdp11.c - pdp11-specific -
2 Copyright 2001, 2002, 2004 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
:
205 BAD_CASE (fixP
->fx_r_type
);
208 if (fixP
->fx_addsy
!= NULL
)
209 val
+= symbol_get_bfdsym (fixP
->fx_addsy
)->section
->vma
;
210 /* *value += fixP->fx_addsy->bsym->section->vma; */
213 code
|= (val
>> shift
) & mask
;
214 number_to_chars_littleendian (buf
, code
, size
);
216 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
221 md_chars_to_number (con
, nbytes
)
222 unsigned char con
[]; /* Low order byte 1st. */
223 int nbytes
; /* Number of bytes in the input. */
225 /* On a PDP-11, 0x1234 is stored as "\x12\x34", and
226 * 0x12345678 is stored as "\x56\x78\x12\x34". It's
227 * anyones guess what 0x123456 would be stored like.
237 return (con
[1] << BITS_PER_CHAR
) | con
[0];
240 (((con
[1] << BITS_PER_CHAR
) | con
[0]) << (2 * BITS_PER_CHAR
)) |
241 ((con
[3] << BITS_PER_CHAR
) | con
[2]);
249 skip_whitespace (char *str
)
251 while (*str
== ' ' || *str
== '\t')
257 find_whitespace (char *str
)
259 while (*str
!= ' ' && *str
!= '\t' && *str
!= 0)
265 parse_reg (char *str
, struct pdp11_code
*operand
)
267 str
= skip_whitespace (str
);
268 if (TOLOWER (*str
) == 'r')
273 case '0': case '1': case '2': case '3':
274 case '4': case '5': case '6': case '7':
275 operand
->code
= *str
- '0';
279 operand
->error
= "Bad register name";
283 else if (strncmp (str
, "sp", 2) == 0 ||
284 strncmp (str
, "SP", 2) == 0)
289 else if (strncmp (str
, "pc", 2) == 0 ||
290 strncmp (str
, "PC", 2) == 0)
297 operand
->error
= "Bad register name";
305 parse_ac5 (char *str
, struct pdp11_code
*operand
)
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)
316 case '0': case '1': case '2': case '3':
318 operand
->code
= *str
- '0';
322 operand
->error
= "Bad register name";
328 operand
->error
= "Bad register name";
336 parse_ac (char *str
, struct pdp11_code
*operand
)
338 str
= parse_ac5 (str
, operand
);
339 if (!operand
->error
&& operand
->code
> 3)
341 operand
->error
= "Bad register name";
349 parse_expression (char *str
, struct pdp11_code
*operand
)
351 char *save_input_line_pointer
;
354 save_input_line_pointer
= input_line_pointer
;
355 input_line_pointer
= str
;
356 seg
= expression (&operand
->reloc
.exp
);
359 input_line_pointer
= save_input_line_pointer
;
360 operand
->error
= "Error in expression";
364 str
= input_line_pointer
;
365 input_line_pointer
= save_input_line_pointer
;
367 operand
->reloc
.pc_rel
= 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
378 if (operand
->reloc
.exp
.X_op
== O_constant
)
384 /* FIXME: buffer overflow! */
388 sprintf (buf
, "%ld", operand
->reloc
.exp
.X_add_number
);
389 operand
->reloc
.exp
.X_add_number
= strtol (buf
, &end
, 8);
397 parse_op_no_deferred (char *str
, struct pdp11_code
*operand
)
399 LITTLENUM_TYPE literal_float
[2];
401 str
= skip_whitespace (str
);
405 case '(': /* (rn) and (rn)+ */
406 str
= parse_reg (str
+ 1, operand
);
409 str
= skip_whitespace (str
);
412 operand
->error
= "Missing ')'";
418 operand
->code
|= 020;
423 operand
->code
|= 010;
427 case '#': /* immediate */
429 str
= parse_expression (str
+ 1, operand
);
432 operand
->additional
= TRUE
;
433 operand
->word
= operand
->reloc
.exp
.X_add_number
;
434 switch (operand
->reloc
.exp
.X_op
)
441 operand
->reloc
.type
= BFD_RELOC_16
;
442 operand
->reloc
.pc_rel
= 0;
445 if (operand
->reloc
.exp
.X_add_number
> 0)
447 operand
->error
= "Error in expression";
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"));
458 operand
->error
= "Error in expression";
464 default: /* label, d(rn), -(rn) */
468 if (strncmp (str
, "-(", 2) == 0) /* -(rn) */
470 str
= parse_reg (str
+ 2, operand
);
473 str
= skip_whitespace (str
);
476 operand
->error
= "Missing ')'";
479 operand
->code
|= 040;
484 str
= parse_expression (str
, operand
);
488 str
= skip_whitespace (str
);
490 if (*str
!= '(') /* label */
492 if (operand
->reloc
.exp
.X_op
!= O_symbol
)
494 operand
->error
= "Label expected";
498 operand
->additional
= 1;
500 operand
->reloc
.type
= BFD_RELOC_16_PCREL
;
501 operand
->reloc
.pc_rel
= 1;
506 str
= parse_reg (str
, operand
);
510 str
= skip_whitespace (str
);
514 operand
->error
= "Missing ')'";
519 operand
->additional
= TRUE
;
520 operand
->code
|= 060;
521 switch (operand
->reloc
.exp
.X_op
)
525 operand
->reloc
.pc_rel
= 1;
528 if ((operand
->code
& 7) == 7)
530 operand
->reloc
.pc_rel
= 1;
531 operand
->word
= operand
->reloc
.exp
.X_add_number
;
535 operand
->word
= operand
->reloc
.exp
.X_add_number
;
539 BAD_CASE (operand
->reloc
.exp
.X_op
);
549 parse_op_noreg (char *str
, struct pdp11_code
*operand
)
551 str
= skip_whitespace (str
);
552 operand
->error
= NULL
;
554 if (*str
== '@' || *str
== '*')
556 str
= parse_op_no_deferred (str
+ 1, operand
);
559 operand
->code
|= 010;
562 str
= parse_op_no_deferred (str
, operand
);
568 parse_op (char *str
, struct pdp11_code
*operand
)
570 str
= skip_whitespace (str
);
572 str
= parse_reg (str
, operand
);
576 operand
->error
= NULL
;
577 parse_ac5 (str
, operand
);
580 operand
->error
= "Float AC not legal as integer operand";
584 return parse_op_noreg (str
, operand
);
588 parse_fop (char *str
, struct pdp11_code
*operand
)
590 str
= skip_whitespace (str
);
592 str
= parse_ac5 (str
, operand
);
596 operand
->error
= NULL
;
597 parse_reg (str
, operand
);
600 operand
->error
= "General register not legal as float operand";
604 return parse_op_noreg (str
, operand
);
608 parse_separator (char *str
, int *error
)
610 str
= skip_whitespace (str
);
611 *error
= (*str
!= ',');
618 md_assemble (instruction_string
)
619 char *instruction_string
;
621 const struct pdp11_opcode
*op
;
622 struct pdp11_code insn
, op1
, op2
;
630 str
= skip_whitespace (instruction_string
);
631 p
= find_whitespace (str
);
634 as_bad ("No instruction found");
640 op
= (struct pdp11_opcode
*)hash_find (insn_hash
, str
);
646 op1
.additional
= FALSE
;
647 op1
.reloc
.type
= BFD_RELOC_NONE
;
650 str
= parse_expression (str
, &op1
);
658 char *to
= frag_more (2);
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
);
666 as_bad (_("Unknown instruction '%s'"), str
);
672 if (!pdp11_extension
[op
->extension
])
674 as_warn ("Unsupported instruction set extension: %s", op
->name
);
679 insn
.code
= op
->opcode
;
680 insn
.reloc
.type
= BFD_RELOC_NONE
;
682 op1
.additional
= FALSE
;
683 op1
.reloc
.type
= BFD_RELOC_NONE
;
685 op2
.additional
= FALSE
;
686 op2
.reloc
.type
= BFD_RELOC_NONE
;
693 case PDP11_OPCODE_NO_OPS
:
694 str
= skip_whitespace (str
);
699 case PDP11_OPCODE_IMM3
:
700 case PDP11_OPCODE_IMM6
:
701 case PDP11_OPCODE_IMM8
:
702 str
= skip_whitespace (str
);
703 if (*str
== '#' || *str
== '$')
705 str
= parse_expression (str
, &op1
);
708 if (op1
.reloc
.exp
.X_op
!= O_constant
|| op1
.reloc
.type
!= BFD_RELOC_NONE
)
710 op1
.error
= "operand is not an absolute constant";
715 case PDP11_OPCODE_IMM3
:
716 if (op1
.reloc
.exp
.X_add_number
& ~7)
718 op1
.error
= "3-bit immediate out of range";
722 case PDP11_OPCODE_IMM6
:
723 if (op1
.reloc
.exp
.X_add_number
& ~0x3f)
725 op1
.error
= "6-bit immediate out of range";
729 case PDP11_OPCODE_IMM8
:
730 if (op1
.reloc
.exp
.X_add_number
& ~0xff)
732 op1
.error
= "8-bit immediate out of range";
737 insn
.code
|= op1
.reloc
.exp
.X_add_number
;
740 case PDP11_OPCODE_DISPL
:
743 new = parse_expression (str
, &op1
);
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
)
749 op1
.error
= "Symbol expected";
752 if (op1
.code
& ~0xff)
754 err
= "8-bit displacement out of range";
758 insn
.code
|= op1
.code
;
759 insn
.reloc
= op1
.reloc
;
763 case PDP11_OPCODE_REG
:
764 str
= parse_reg (str
, &op1
);
767 insn
.code
|= op1
.code
;
770 case PDP11_OPCODE_OP
:
771 str
= parse_op (str
, &op1
);
774 insn
.code
|= op1
.code
;
779 case PDP11_OPCODE_FOP
:
780 str
= parse_fop (str
, &op1
);
783 insn
.code
|= op1
.code
;
788 case PDP11_OPCODE_REG_OP
:
789 str
= parse_reg (str
, &op2
);
792 insn
.code
|= op2
.code
<< 6;
793 str
= parse_separator (str
, &error
);
796 op2
.error
= "Missing ','";
799 str
= parse_op (str
, &op1
);
802 insn
.code
|= op1
.code
;
807 case PDP11_OPCODE_REG_OP_REV
:
808 str
= parse_op (str
, &op1
);
811 insn
.code
|= op1
.code
;
814 str
= parse_separator (str
, &error
);
817 op2
.error
= "Missing ','";
820 str
= parse_reg (str
, &op2
);
823 insn
.code
|= op2
.code
<< 6;
826 case PDP11_OPCODE_AC_FOP
:
827 str
= parse_ac (str
, &op2
);
830 insn
.code
|= op2
.code
<< 6;
831 str
= parse_separator (str
, &error
);
834 op1
.error
= "Missing ','";
837 str
= parse_fop (str
, &op1
);
840 insn
.code
|= op1
.code
;
845 case PDP11_OPCODE_FOP_AC
:
846 str
= parse_fop (str
, &op1
);
849 insn
.code
|= op1
.code
;
852 str
= parse_separator (str
, &error
);
855 op1
.error
= "Missing ','";
858 str
= parse_ac (str
, &op2
);
861 insn
.code
|= op2
.code
<< 6;
864 case PDP11_OPCODE_AC_OP
:
865 str
= parse_ac (str
, &op2
);
868 insn
.code
|= op2
.code
<< 6;
869 str
= parse_separator (str
, &error
);
872 op1
.error
= "Missing ','";
875 str
= parse_op (str
, &op1
);
878 insn
.code
|= op1
.code
;
883 case PDP11_OPCODE_OP_AC
:
884 str
= parse_op (str
, &op1
);
887 insn
.code
|= op1
.code
;
890 str
= parse_separator (str
, &error
);
893 op1
.error
= "Missing ','";
896 str
= parse_ac (str
, &op2
);
899 insn
.code
|= op2
.code
<< 6;
902 case PDP11_OPCODE_OP_OP
:
903 str
= parse_op (str
, &op1
);
906 insn
.code
|= op1
.code
<< 6;
909 str
= parse_separator (str
, &error
);
912 op2
.error
= "Missing ','";
915 str
= parse_op (str
, &op2
);
918 insn
.code
|= op2
.code
;
923 case PDP11_OPCODE_REG_DISPL
:
926 str
= parse_reg (str
, &op2
);
929 insn
.code
|= op2
.code
<< 6;
930 str
= parse_separator (str
, &error
);
933 op1
.error
= "Missing ','";
936 new = parse_expression (str
, &op1
);
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
)
942 op1
.error
= "Symbol expected";
945 if (op1
.code
& ~0x3f)
947 err
= "6-bit displacement out of range";
951 insn
.code
|= op1
.code
;
952 insn
.reloc
= op1
.reloc
;
966 str
= skip_whitespace (str
);
968 err
= "Too many operands";
980 to
= frag_more (size
);
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
);
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
);
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
);
1008 md_estimate_size_before_relax (fragP
, segment
)
1009 fragS
*fragP ATTRIBUTE_UNUSED
;
1010 segT segment ATTRIBUTE_UNUSED
;
1016 md_convert_frag (headers
, seg
, fragP
)
1017 bfd
*headers ATTRIBUTE_UNUSED
;
1018 segT seg ATTRIBUTE_UNUSED
;
1019 fragS
*fragP ATTRIBUTE_UNUSED
;
1023 int md_short_jump_size
= 2;
1024 int md_long_jump_size
= 4;
1027 md_create_short_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
1028 char *ptr ATTRIBUTE_UNUSED
;
1029 addressT from_addr ATTRIBUTE_UNUSED
;
1030 addressT to_addr ATTRIBUTE_UNUSED
;
1031 fragS
*frag ATTRIBUTE_UNUSED
;
1032 symbolS
*to_symbol ATTRIBUTE_UNUSED
;
1037 md_create_long_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
1038 char *ptr ATTRIBUTE_UNUSED
;
1039 addressT from_addr ATTRIBUTE_UNUSED
;
1040 addressT to_addr ATTRIBUTE_UNUSED
;
1041 fragS
*frag ATTRIBUTE_UNUSED
;
1042 symbolS
*to_symbol ATTRIBUTE_UNUSED
;
1052 if (strcmp (arg
, "all-extensions") == 0 ||
1053 strcmp (arg
, "all") == 0)
1055 memset (pdp11_extension
, ~0, sizeof pdp11_extension
);
1056 pdp11_extension
[PDP11_NONE
] = 0;
1059 else if (strcmp (arg
, "no-extensions") == 0)
1061 memset (pdp11_extension
, 0, sizeof pdp11_extension
);
1062 pdp11_extension
[PDP11_BASIC
] = 1;
1066 if (strncmp (arg
, "no-", 3) == 0)
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 */
1092 pdp11_extension
[PDP11_LEIS
] = yes
;
1093 if (!pdp11_extension
[PDP11_LEIS
])
1094 pdp11_extension
[PDP11_EIS
] = 0;
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
;
1128 if (strchr ("abdx", model
[-1]) == NULL
)
1131 if (model
[-1] == 'd')
1133 if (arg
[0] == 'f' ||
1137 else if (model
[-1] == 'x')
1146 if (strncmp (arg
, "11", 2) != 0)
1156 /* allow up to two revision letters */
1164 set_option ("no-extensions");
1166 if (strncmp (buf
, "a", 1) == 0) /* KA11 (11/15/20) */
1167 return 1; /* no extensions */
1169 else if (strncmp (buf
, "b", 1) == 0) /* KB11 (11/45/50/55/70) */
1170 return set_option ("eis") &&
1173 else if (strncmp (buf
, "da", 2) == 0) /* KD11-A (11/35/40) */
1174 return set_option ("limited-eis");
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 */
1180 else if (strncmp (buf
, "de", 2) == 0) /* KD11-E (11/34) */
1181 return set_option ("eis") &&
1182 set_option ("mxps");
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");
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");
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") &&
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");
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") &&
1215 else if (strncmp (buf
, "t", 1) == 0) /* T11 (11/21) */
1216 return set_option ("limited-eis") &&
1217 set_option ("mxps");
1224 set_machine_model (arg
)
1227 if (strncmp (arg
, "pdp-11/", 7) != 0 &&
1228 strncmp (arg
, "pdp11/", 6) != 0 &&
1229 strncmp (arg
, "11/", 3) != 0)
1232 if (strncmp (arg
, "pdp", 3) == 0)
1236 if (strncmp (arg
, "11/", 3) == 0)
1239 if (strcmp (arg
, "03") == 0) /* 11/03 */
1240 return set_cpu_model ("kd11f"); /* KD11-F */
1242 else if (strcmp (arg
, "04") == 0) /* 11/04 */
1243 return set_cpu_model ("kd11d"); /* KD11-D */
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 */
1249 else if (strcmp (arg
, "15") == 0 || /* 11/15 or 11/20 */
1250 strcmp (arg
, "20") == 0)
1251 return set_cpu_model ("ka11"); /* KA11 */
1253 else if (strcmp (arg
, "21") == 0) /* 11/21 */
1254 return set_cpu_model ("t11"); /* T11 */
1256 else if (strcmp (arg
, "23") == 0 || /* 11/23 or 11/24 */
1257 strcmp (arg
, "24") == 0)
1258 return set_cpu_model ("f11"); /* F11 */
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 */
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 */
1268 else if (strcmp (arg
, "44") == 0) /* 11/44 */
1269 return set_cpu_model ("kd11dz"); /* KD11-Z */
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 */
1277 else if (strcmp (arg
, "60") == 0) /* 11/60 */
1278 return set_cpu_model ("kd11k"); /* KD11-K */ /* FPP? */
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. */
1293 const char *md_shortopts
= "m:";
1295 struct option md_longopts
[] =
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 }
1306 size_t md_longopts_size
= sizeof (md_longopts
);
1310 * Invocation line includes a switch not recognized by the base assembler.
1311 * See if it's a processor-specific option.
1315 md_parse_option (c
, arg
)
1324 if (set_option (arg
))
1326 if (set_cpu_model (arg
))
1328 if (set_machine_model (arg
))
1333 if (set_cpu_model (arg
))
1337 case OPTION_MACHINE
:
1338 if (set_machine_model (arg
))
1343 if (set_option ("pic"))
1355 One possible way of parsing options.
1366 const char *pattern;
1368 const char *description;
1371 static struct options extension_opts[] =
1373 { "Ncsm", OPTION_CSM,
1374 "allow (disallow) CSM instruction" },
1375 { "Ncis", OPTION_CIS,
1376 "allow (disallow) commersial instruction set" },
1377 { "Neis", OPTION_EIS,
1378 "allow (disallow) extended instruction set" },
1380 { "all-extensions", OPTION_ALL_EXTENSIONS,
1381 "allow all instruction set extensions\n\
1382 (this is the default)" },
1383 { "no-extensions", OPTION_NO_EXTENSIONS,
1384 "disallow all instruction set extensions" },
1385 { "pic", OPTION_PIC,
1386 "position-independent code" },
1389 static struct options cpu_opts[] =
1391 { "Ka_11_*", OPTION_KA11, "KA11 CPU. ..." },
1392 { "Kb_11_*", OPTION_KB11, "KB11 CPU. ..." },
1393 { "Kd_11_a*", OPTION_KD11A, "KD11-A CPU. ..." },
1394 { "Kd_11_b*", OPTION_KD11B, "KD11-B CPU. ..." },
1395 { "Kd_11_d*", OPTION_KD11D, "KD11-D CPU. ..." },
1396 { "Kd_11_e*", OPTION_KD11E, "KD11-E CPU. ..." },
1397 { "Kd_11_f*", OPTION_KD11F, "KD11-F CPU. ..." },
1398 { "Kd_11_h*", OPTION_KD11H, "KD11-H CPU. ..." },
1399 { "Kd_11_q*", OPTION_KD11Q, "KD11-Q CPU. ..." },
1400 { "Kd_11_z*", OPTION_KD11Z, "KD11-Z CPU. ..." },
1401 { "Df_11_*", OPTION_F11, "F11 CPU. ..." },
1402 { "Dj_11_*", OPTION_J11, "J11 CPU. ..." },
1403 { "Dt_11_*", OPTION_T11, "T11 CPU. ..." },
1406 static struct options model_opts[] =
1408 { "P03", OPTION_PDP11_03, "same as ..." },
1409 { "P04", OPTION_PDP11_04, "same as ..." },
1410 { "P05", OPTION_PDP11_05, "same as ..." },
1411 { "P10", OPTION_PDP11_10, "same as ..." },
1412 { "P15", OPTION_PDP11_15, "same as ..." },
1413 { "P20", OPTION_PDP11_20, "same as ..." },
1414 { "P21", OPTION_PDP11_21, "same as ..." },
1415 { "P24", OPTION_PDP11_24, "same as ..." },
1416 { "P34", OPTION_PDP11_34, "same as ..." },
1417 { "P34a", OPTION_PDP11_34A, "same as ..." },
1418 { "P40", OPTION_PDP11_40, "same as ..." },
1419 { "P44", OPTION_PDP11_44, "same as ..." },
1420 { "P45", OPTION_PDP11_45, "same as ..." },
1421 { "P50", OPTION_PDP11_50, "same as ..." },
1422 { "P53", OPTION_PDP11_53, "same as ..." },
1423 { "P55", OPTION_PDP11_55, "same as ..." },
1424 { "P60", OPTION_PDP11_60, "same as ..." },
1425 { "P70", OPTION_PDP11_70, "same as ..." },
1426 { "P73", OPTION_PDP11_73, "same as ..." },
1427 { "P83", OPTION_PDP11_83, "same as ..." },
1428 { "P84", OPTION_PDP11_84, "same as ..." },
1429 { "P93", OPTION_PDP11_93, "same as ..." },
1430 { "P94", OPTION_PDP11_94, "same as ..." },
1436 struct options *opts;
1440 { "PDP-11 instruction set extentions",
1442 sizeof extension_opts / sizeof extension_opts[0] },
1443 { "PDP-11 CPU model options",
1445 sizeof cpu_opts / sizeof cpu_opts[0] },
1446 { "PDP-11 machine model options",
1448 sizeof model_opts / sizeof model_opts[0] },
1452 parse_match (char *arg, char *pattern)
1461 if (strncmp (arg, "no-") == 0)
1474 if (strncmp (arg, "kd", 2) == 0)
1479 if (strncmp (arg, "pdp-11/", 7) == 0)
1481 else if (strncmp (arg, "pdp11/", 6) == 0)
1483 else if (strncmp (arg, "11/", 3) == 0)
1499 if (*arg++ != pattern[-1])
1508 fprint_opt (stream, pattern)
1510 const char *pattern;
1519 n += fprintf (stream, "(no-)");
1523 n += fprintf (stream, "k");
1527 n += fprintf (stream "11/");
1536 fputc (pattern[-1], stream);
1545 parse_option (char *arg)
1549 for (i = 0; i < sizeof all_opts / sizeof all_opts[0]; i++)
1551 for (j = 0; j < all_opts[i].num; j++)
1553 if (parse_match (arg, all_opts[i].opts[j].pattern))
1555 set_option (all_opts[i].opts[j].opt);
1565 fprint_space (stream, n)
1570 fputc (' ', stream);
1574 md_show_usage (stream)
1579 for (i = 0; i < sizeof all_opts / sizeof all_opts[0]; i++)
1581 fprintf (stream "\n%s:\n\n", all_opts[i].title);
1583 for (j = 0; j < all_opts[i].num; j++)
1585 fprintf (stream, "-m");
1586 n = fprintf_opt (stream, all_opts[i].opts[j].pattern);
1587 fprint_space (stream, 22 - n);
1588 fprintf (stream, "%s\n", all_opts[i].opts[j].description);
1595 md_show_usage (stream
)
1600 PDP-11 instruction set extentions:\n\
1602 -m(no-)cis allow (disallow) commersial instruction set\n\
1603 -m(no-)csm allow (disallow) CSM instruction\n\
1604 -m(no-)eis allow (disallow) full extended instruction set\n\
1605 -m(no-)fis allow (disallow) KEV11 floating-point instructions\n\
1606 -m(no-)fpp allow (disallow) FP-11 floating-point instructions\n\
1607 -m(no-)fpu allow (disallow) FP-11 floating-point instructions\n\
1608 -m(no-)limited-eis allow (disallow) limited extended instruction set\n\
1609 -m(no-)mfpt allow (disallow) processor type instruction\n\
1610 -m(no-)multiproc allow (disallow) multiprocessor instructions\n\
1611 -m(no-)mxps allow (disallow) processor status instructions\n\
1612 -m(no-)spl allow (disallow) SPL instruction\n\
1613 -m(no-)ucode allow (disallow) microcode instructions\n\
1614 -mall-extensions allow all instruction set extensions\n\
1615 (this is the default)\n\
1616 -mno-extentions disallow all instruction set extensions\n\
1617 -pic generate position-indepenent code\n\
1619 PDP-11 CPU model options:\n\
1621 -mka11* KA11 CPU. base line instruction set only\n\
1622 -mkb11* KB11 CPU. enable full EIS and SPL\n\
1623 -mkd11a* KD11-A CPU. enable limited EIS\n\
1624 -mkd11b* KD11-B CPU. base line instruction set only\n\
1625 -mkd11d* KD11-D CPU. base line instruction set only\n\
1626 -mkd11e* KD11-E CPU. enable full EIS, MTPS, and MFPS\n\
1627 -mkd11f* KD11-F CPU. enable limited EIS, MTPS, and MFPS\n\
1628 -mkd11h* KD11-H CPU. enable limited EIS, MTPS, and MFPS\n\
1629 -mkd11q* KD11-Q CPU. enable limited EIS, MTPS, and MFPS\n\
1630 -mkd11k* KD11-K CPU. enable full EIS, MTPS, MFPS, LDUB, MED,\n\
1632 -mkd11z* KD11-Z CPU. enable full EIS, MTPS, MFPS, MFPT, SPL,\n\
1634 -mf11* F11 CPU. enable full EIS, MFPS, MTPS, and MFPT\n\
1635 -mj11* J11 CPU. enable full EIS, MTPS, MFPS, MFPT, SPL,\n\
1636 CSM, TSTSET, and WRTLCK\n\
1637 -mt11* T11 CPU. enable limited EIS, MTPS, and MFPS\n\
1639 PDP-11 machine model options:\n\
1641 -m11/03 same as -mkd11f\n\
1642 -m11/04 same as -mkd11d\n\
1643 -m11/05 same as -mkd11b\n\
1644 -m11/10 same as -mkd11b\n\
1645 -m11/15 same as -mka11\n\
1646 -m11/20 same as -mka11\n\
1647 -m11/21 same as -mt11\n\
1648 -m11/23 same as -mf11\n\
1649 -m11/24 same as -mf11\n\
1650 -m11/34 same as -mkd11e\n\
1651 -m11/34a same as -mkd11e -mfpp\n\
1652 -m11/35 same as -mkd11a\n\
1653 -m11/40 same as -mkd11a\n\
1654 -m11/44 same as -mkd11z\n\
1655 -m11/45 same as -mkb11\n\
1656 -m11/50 same as -mkb11\n\
1657 -m11/53 same as -mj11\n\
1658 -m11/55 same as -mkb11\n\
1659 -m11/60 same as -mkd11k\n\
1660 -m11/70 same as -mkb11\n\
1661 -m11/73 same as -mj11\n\
1662 -m11/83 same as -mj11\n\
1663 -m11/84 same as -mj11\n\
1664 -m11/93 same as -mj11\n\
1665 -m11/94 same as -mj11\n\
1670 md_undefined_symbol (name
)
1671 char *name ATTRIBUTE_UNUSED
;
1677 md_section_align (segment
, size
)
1678 segT segment ATTRIBUTE_UNUSED
;
1681 return (size
+ 1) & ~1;
1685 md_pcrel_from (fixP
)
1688 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ fixP
->fx_size
;
1691 /* Translate internal representation of relocation info to BFD target
1694 tc_gen_reloc (section
, fixp
)
1695 asection
*section ATTRIBUTE_UNUSED
;
1699 bfd_reloc_code_real_type code
;
1701 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1703 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1704 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1705 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1707 /* This is taken account for in md_apply_fix3(). */
1708 reloc
->addend
= -symbol_get_bfdsym (fixp
->fx_addsy
)->section
->vma
;
1710 switch (fixp
->fx_r_type
)
1714 code
= BFD_RELOC_16_PCREL
;
1716 code
= BFD_RELOC_16
;
1719 case BFD_RELOC_16_PCREL
:
1720 code
= BFD_RELOC_16_PCREL
;
1724 BAD_CASE (fixp
->fx_r_type
);
1728 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
1730 if (reloc
->howto
== NULL
)
1732 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1733 "Can not represent %s relocation in this object file format",
1734 bfd_get_reloc_code_name (code
));
1743 int c ATTRIBUTE_UNUSED
;
1747 temp
= get_absolute_expression ();
1748 subseg_set (bss_section
, temp
);
1749 demand_empty_rest_of_line ();
1754 int c ATTRIBUTE_UNUSED
;
1756 int alignment
= 1; /* 2^1 */
1757 frag_align (alignment
, 0, 1);
1758 record_alignment (now_seg
, alignment
);
1761 /* end of tc-pdp11.c */