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