tc-pdp11.c revision 1.1 1 1.1 christos /* tc-pdp11.c - pdp11-specific -
2 1.1 christos Copyright 2001, 2002, 2004, 2005, 2007, 2009
3 1.1 christos Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This file is part of GAS, the GNU Assembler.
6 1.1 christos
7 1.1 christos GAS is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3, or (at your option)
10 1.1 christos any later version.
11 1.1 christos
12 1.1 christos GAS is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with GAS; see the file COPYING. If not, write to
19 1.1 christos the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20 1.1 christos Boston, MA 02110-1301, USA. */
21 1.1 christos
22 1.1 christos #include "as.h"
23 1.1 christos #include "safe-ctype.h"
24 1.1 christos #include "opcode/pdp11.h"
25 1.1 christos
26 1.1 christos extern int flonum_gen2vax (int, FLONUM_TYPE * f, LITTLENUM_TYPE *);
27 1.1 christos
28 1.1 christos #define TRUE 1
29 1.1 christos #define FALSE 0
30 1.1 christos
31 1.1 christos /* A representation for PDP-11 machine code. */
32 1.1 christos struct pdp11_code
33 1.1 christos {
34 1.1 christos char *error;
35 1.1 christos int code;
36 1.1 christos int additional; /* Is there an additional word? */
37 1.1 christos int word; /* Additional word, if any. */
38 1.1 christos struct
39 1.1 christos {
40 1.1 christos bfd_reloc_code_real_type type;
41 1.1 christos expressionS exp;
42 1.1 christos int pc_rel;
43 1.1 christos } reloc;
44 1.1 christos };
45 1.1 christos
46 1.1 christos /* Instruction set extensions.
47 1.1 christos
48 1.1 christos If you change this from an array to something else, please update
49 1.1 christos the "PDP-11 instruction set extensions" comment in pdp11.h. */
50 1.1 christos int pdp11_extension[PDP11_EXT_NUM];
51 1.1 christos
52 1.1 christos /* Assembly options. */
53 1.1 christos
54 1.1 christos #define ASM_OPT_PIC 1
55 1.1 christos #define ASM_OPT_NUM 2
56 1.1 christos
57 1.1 christos int asm_option[ASM_OPT_NUM];
58 1.1 christos
59 1.1 christos /* These chars start a comment anywhere in a source file (except inside
60 1.1 christos another comment. */
61 1.1 christos const char comment_chars[] = "#/";
62 1.1 christos
63 1.1 christos /* These chars only start a comment at the beginning of a line. */
64 1.1 christos const char line_comment_chars[] = "#/";
65 1.1 christos
66 1.1 christos const char line_separator_chars[] = ";";
67 1.1 christos
68 1.1 christos /* Chars that can be used to separate mant from exp in floating point nums. */
69 1.1 christos const char EXP_CHARS[] = "eE";
70 1.1 christos
71 1.1 christos /* Chars that mean this number is a floating point constant. */
72 1.1 christos /* as in 0f123.456. */
73 1.1 christos /* or 0H1.234E-12 (see exp chars above). */
74 1.1 christos const char FLT_CHARS[] = "dDfF";
75 1.1 christos
76 1.1 christos void pseudo_even (int);
77 1.1 christos void pseudo_bss (int);
78 1.1 christos
79 1.1 christos const pseudo_typeS md_pseudo_table[] =
80 1.1 christos {
81 1.1 christos { "bss", pseudo_bss, 0 },
82 1.1 christos { "even", pseudo_even, 0 },
83 1.1 christos { 0, 0, 0 },
84 1.1 christos };
85 1.1 christos
86 1.1 christos static struct hash_control *insn_hash = NULL;
87 1.1 christos
88 1.1 christos static int
90 1.1 christos set_option (char *arg)
91 1.1 christos {
92 1.1 christos int yes = 1;
93 1.1 christos
94 1.1 christos if (strcmp (arg, "all-extensions") == 0
95 1.1 christos || strcmp (arg, "all") == 0)
96 1.1 christos {
97 1.1 christos memset (pdp11_extension, ~0, sizeof pdp11_extension);
98 1.1 christos pdp11_extension[PDP11_NONE] = 0;
99 1.1 christos return 1;
100 1.1 christos }
101 1.1 christos else if (strcmp (arg, "no-extensions") == 0)
102 1.1 christos {
103 1.1 christos memset (pdp11_extension, 0, sizeof pdp11_extension);
104 1.1 christos pdp11_extension[PDP11_BASIC] = 1;
105 1.1 christos return 1;
106 1.1 christos }
107 1.1 christos
108 1.1 christos if (strncmp (arg, "no-", 3) == 0)
109 1.1 christos {
110 1.1 christos yes = 0;
111 1.1 christos arg += 3;
112 1.1 christos }
113 1.1 christos
114 1.1 christos /* Commersial instructions. */
115 1.1 christos if (strcmp (arg, "cis") == 0)
116 1.1 christos pdp11_extension[PDP11_CIS] = yes;
117 1.1 christos /* Call supervisor mode. */
118 1.1 christos else if (strcmp (arg, "csm") == 0)
119 1.1 christos pdp11_extension[PDP11_CSM] = yes;
120 1.1 christos /* Extended instruction set. */
121 1.1 christos else if (strcmp (arg, "eis") == 0)
122 1.1 christos pdp11_extension[PDP11_EIS] = pdp11_extension[PDP11_LEIS] = yes;
123 1.1 christos /* KEV11 floating-point. */
124 1.1 christos else if (strcmp (arg, "fis") == 0
125 1.1 christos || strcmp (arg, "kev11") == 0
126 1.1 christos || strcmp (arg, "kev-11") == 0)
127 1.1 christos pdp11_extension[PDP11_FIS] = yes;
128 1.1 christos /* FP-11 floating-point. */
129 1.1 christos else if (strcmp (arg, "fpp") == 0
130 1.1 christos || strcmp (arg, "fpu") == 0
131 1.1 christos || strcmp (arg, "fp11") == 0
132 1.1 christos || strcmp (arg, "fp-11") == 0
133 1.1 christos || strcmp (arg, "fpj11") == 0
134 1.1 christos || strcmp (arg, "fp-j11") == 0
135 1.1 christos || strcmp (arg, "fpj-11") == 0)
136 1.1 christos pdp11_extension[PDP11_FPP] = yes;
137 1.1 christos /* Limited extended insns. */
138 1.1 christos else if (strcmp (arg, "limited-eis") == 0)
139 1.1 christos {
140 1.1 christos pdp11_extension[PDP11_LEIS] = yes;
141 1.1 christos if (!pdp11_extension[PDP11_LEIS])
142 1.1 christos pdp11_extension[PDP11_EIS] = 0;
143 1.1 christos }
144 1.1 christos /* Move from processor type. */
145 1.1 christos else if (strcmp (arg, "mfpt") == 0)
146 1.1 christos pdp11_extension[PDP11_MFPT] = yes;
147 1.1 christos /* Multiprocessor insns: */
148 1.1 christos else if (strncmp (arg, "mproc", 5) == 0
149 1.1 christos /* TSTSET, WRTLCK */
150 1.1 christos || strncmp (arg, "multiproc", 9) == 0)
151 1.1 christos pdp11_extension[PDP11_MPROC] = yes;
152 1.1 christos /* Move from/to proc status. */
153 1.1 christos else if (strcmp (arg, "mxps") == 0)
154 1.1 christos pdp11_extension[PDP11_MXPS] = yes;
155 1.1 christos /* Position-independent code. */
156 1.1 christos else if (strcmp (arg, "pic") == 0)
157 1.1 christos asm_option[ASM_OPT_PIC] = yes;
158 1.1 christos /* Set priority level. */
159 1.1 christos else if (strcmp (arg, "spl") == 0)
160 1.1 christos pdp11_extension[PDP11_SPL] = yes;
161 1.1 christos /* Microcode instructions: */
162 1.1 christos else if (strcmp (arg, "ucode") == 0
163 1.1 christos /* LDUB, MED, XFC */
164 1.1 christos || strcmp (arg, "microcode") == 0)
165 1.1 christos pdp11_extension[PDP11_UCODE] = yes;
166 1.1 christos else
167 1.1 christos return 0;
168 1.1 christos
169 1.1 christos return 1;
170 1.1 christos }
171 1.1 christos
172 1.1 christos
173 1.1 christos static void
174 1.1 christos init_defaults (void)
175 1.1 christos {
176 1.1 christos static int first = 1;
177 1.1 christos
178 1.1 christos if (first)
179 1.1 christos {
180 1.1 christos set_option ("all-extensions");
181 1.1 christos set_option ("pic");
182 1.1 christos first = 0;
183 1.1 christos }
184 1.1 christos }
185 1.1 christos
186 1.1 christos void
187 1.1 christos md_begin (void)
188 1.1 christos {
189 1.1 christos int i;
190 1.1 christos
191 1.1 christos init_defaults ();
192 1.1 christos
193 1.1 christos insn_hash = hash_new ();
194 1.1 christos if (insn_hash == NULL)
195 1.1 christos as_fatal (_("Virtual memory exhausted"));
196 1.1 christos
197 1.1 christos for (i = 0; i < pdp11_num_opcodes; i++)
198 1.1 christos hash_insert (insn_hash, pdp11_opcodes[i].name, (void *) (pdp11_opcodes + i));
199 1.1 christos for (i = 0; i < pdp11_num_aliases; i++)
200 1.1 christos hash_insert (insn_hash, pdp11_aliases[i].name, (void *) (pdp11_aliases + i));
201 1.1 christos }
202 1.1 christos
203 1.1 christos void
204 1.1 christos md_number_to_chars (char con[], valueT value, int nbytes)
205 1.1 christos {
206 1.1 christos /* On a PDP-11, 0x1234 is stored as "\x12\x34", and
207 1.1 christos 0x12345678 is stored as "\x56\x78\x12\x34". It's
208 1.1 christos anyones guess what 0x123456 would be stored like. */
209 1.1 christos
210 1.1 christos switch (nbytes)
211 1.1 christos {
212 1.1 christos case 0:
213 1.1 christos break;
214 1.1 christos case 1:
215 1.1 christos con[0] = value & 0xff;
216 1.1 christos break;
217 1.1 christos case 2:
218 1.1 christos con[0] = value & 0xff;
219 1.1 christos con[1] = (value >> 8) & 0xff;
220 1.1 christos break;
221 1.1 christos case 4:
222 1.1 christos con[0] = (value >> 16) & 0xff;
223 1.1 christos con[1] = (value >> 24) & 0xff;
224 1.1 christos con[2] = value & 0xff;
225 1.1 christos con[3] = (value >> 8) & 0xff;
226 1.1 christos break;
227 1.1 christos default:
228 1.1 christos BAD_CASE (nbytes);
229 1.1 christos }
230 1.1 christos }
231 1.1 christos
232 1.1 christos /* Fix up some data or instructions after we find out the value of a symbol
233 1.1 christos that they reference. Knows about order of bytes in address. */
234 1.1 christos
235 1.1 christos void
236 1.1 christos md_apply_fix (fixS *fixP,
237 1.1 christos valueT * valP,
238 1.1 christos segT seg ATTRIBUTE_UNUSED)
239 1.1 christos {
240 1.1 christos valueT code;
241 1.1 christos valueT mask;
242 1.1 christos valueT val = * valP;
243 1.1 christos char *buf;
244 1.1 christos int shift;
245 1.1 christos int size;
246 1.1 christos
247 1.1 christos buf = fixP->fx_where + fixP->fx_frag->fr_literal;
248 1.1 christos size = fixP->fx_size;
249 1.1 christos code = md_chars_to_number ((unsigned char *) buf, size);
250 1.1 christos
251 1.1 christos switch (fixP->fx_r_type)
252 1.1 christos {
253 1.1 christos case BFD_RELOC_16:
254 1.1 christos case BFD_RELOC_16_PCREL:
255 1.1 christos mask = 0xffff;
256 1.1 christos shift = 0;
257 1.1 christos break;
258 1.1 christos case BFD_RELOC_PDP11_DISP_8_PCREL:
259 1.1 christos mask = 0x00ff;
260 1.1 christos shift = 1;
261 1.1 christos break;
262 1.1 christos case BFD_RELOC_PDP11_DISP_6_PCREL:
263 1.1 christos mask = 0x003f;
264 1.1 christos shift = 1;
265 1.1 christos val = -val;
266 1.1 christos break;
267 1.1 christos default:
268 1.1 christos BAD_CASE (fixP->fx_r_type);
269 1.1 christos }
270 1.1 christos
271 1.1 christos if (fixP->fx_addsy != NULL)
272 1.1 christos val += symbol_get_bfdsym (fixP->fx_addsy)->section->vma;
273 1.1 christos /* *value += fixP->fx_addsy->bsym->section->vma; */
274 1.1 christos
275 1.1 christos code &= ~mask;
276 1.1 christos code |= (val >> shift) & mask;
277 1.1 christos number_to_chars_littleendian (buf, code, size);
278 1.1 christos
279 1.1 christos if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
280 1.1 christos fixP->fx_done = 1;
281 1.1 christos }
282 1.1 christos
283 1.1 christos long
284 1.1 christos md_chars_to_number (con, nbytes)
285 1.1 christos unsigned char con[]; /* Low order byte 1st. */
286 1.1 christos int nbytes; /* Number of bytes in the input. */
287 1.1 christos {
288 1.1 christos /* On a PDP-11, 0x1234 is stored as "\x12\x34", and
289 1.1 christos 0x12345678 is stored as "\x56\x78\x12\x34". It's
290 1.1 christos anyones guess what 0x123456 would be stored like. */
291 1.1 christos switch (nbytes)
292 1.1 christos {
293 1.1 christos case 0:
294 1.1 christos return 0;
295 1.1 christos case 1:
296 1.1 christos return con[0];
297 1.1 christos case 2:
298 1.1 christos return (con[1] << BITS_PER_CHAR) | con[0];
299 1.1 christos case 4:
300 1.1 christos return
301 1.1 christos (((con[1] << BITS_PER_CHAR) | con[0]) << (2 * BITS_PER_CHAR))
302 1.1 christos |((con[3] << BITS_PER_CHAR) | con[2]);
303 1.1 christos default:
304 1.1 christos BAD_CASE (nbytes);
305 1.1 christos return 0;
306 1.1 christos }
307 1.1 christos }
308 1.1 christos
309 1.1 christos static char *
311 1.1 christos skip_whitespace (char *str)
312 1.1 christos {
313 1.1 christos while (*str == ' ' || *str == '\t')
314 1.1 christos str++;
315 1.1 christos return str;
316 1.1 christos }
317 1.1 christos
318 1.1 christos static char *
319 1.1 christos find_whitespace (char *str)
320 1.1 christos {
321 1.1 christos while (*str != ' ' && *str != '\t' && *str != 0)
322 1.1 christos str++;
323 1.1 christos return str;
324 1.1 christos }
325 1.1 christos
326 1.1 christos static char *
327 1.1 christos parse_reg (char *str, struct pdp11_code *operand)
328 1.1 christos {
329 1.1 christos str = skip_whitespace (str);
330 1.1 christos if (TOLOWER (*str) == 'r')
331 1.1 christos {
332 1.1 christos str++;
333 1.1 christos switch (*str)
334 1.1 christos {
335 1.1 christos case '0': case '1': case '2': case '3':
336 1.1 christos case '4': case '5': case '6': case '7':
337 1.1 christos operand->code = *str - '0';
338 1.1 christos str++;
339 1.1 christos break;
340 1.1 christos default:
341 1.1 christos operand->error = _("Bad register name");
342 1.1 christos return str - 1;
343 1.1 christos }
344 1.1 christos }
345 1.1 christos else if (strncmp (str, "sp", 2) == 0
346 1.1 christos || strncmp (str, "SP", 2) == 0)
347 1.1 christos {
348 1.1 christos operand->code = 6;
349 1.1 christos str += 2;
350 1.1 christos }
351 1.1 christos else if (strncmp (str, "pc", 2) == 0
352 1.1 christos || strncmp (str, "PC", 2) == 0)
353 1.1 christos {
354 1.1 christos operand->code = 7;
355 1.1 christos str += 2;
356 1.1 christos }
357 1.1 christos else
358 1.1 christos {
359 1.1 christos operand->error = _("Bad register name");
360 1.1 christos return str;
361 1.1 christos }
362 1.1 christos
363 1.1 christos return str;
364 1.1 christos }
365 1.1 christos
366 1.1 christos static char *
367 1.1 christos parse_ac5 (char *str, struct pdp11_code *operand)
368 1.1 christos {
369 1.1 christos str = skip_whitespace (str);
370 1.1 christos if (strncmp (str, "fr", 2) == 0
371 1.1 christos || strncmp (str, "FR", 2) == 0
372 1.1 christos || strncmp (str, "ac", 2) == 0
373 1.1 christos || strncmp (str, "AC", 2) == 0)
374 1.1 christos {
375 1.1 christos str += 2;
376 1.1 christos switch (*str)
377 1.1 christos {
378 1.1 christos case '0': case '1': case '2': case '3':
379 1.1 christos case '4': case '5':
380 1.1 christos operand->code = *str - '0';
381 1.1 christos str++;
382 1.1 christos break;
383 1.1 christos default:
384 1.1 christos operand->error = _("Bad register name");
385 1.1 christos return str - 2;
386 1.1 christos }
387 1.1 christos }
388 1.1 christos else
389 1.1 christos {
390 1.1 christos operand->error = _("Bad register name");
391 1.1 christos return str;
392 1.1 christos }
393 1.1 christos
394 1.1 christos return str;
395 1.1 christos }
396 1.1 christos
397 1.1 christos static char *
398 1.1 christos parse_ac (char *str, struct pdp11_code *operand)
399 1.1 christos {
400 1.1 christos str = parse_ac5 (str, operand);
401 1.1 christos if (!operand->error && operand->code > 3)
402 1.1 christos {
403 1.1 christos operand->error = _("Bad register name");
404 1.1 christos return str - 3;
405 1.1 christos }
406 1.1 christos
407 1.1 christos return str;
408 1.1 christos }
409 1.1 christos
410 1.1 christos static char *
411 1.1 christos parse_expression (char *str, struct pdp11_code *operand)
412 1.1 christos {
413 1.1 christos char *save_input_line_pointer;
414 1.1 christos segT seg;
415 1.1 christos
416 1.1 christos save_input_line_pointer = input_line_pointer;
417 1.1 christos input_line_pointer = str;
418 1.1 christos seg = expression (&operand->reloc.exp);
419 1.1 christos if (seg == NULL)
420 1.1 christos {
421 1.1 christos input_line_pointer = save_input_line_pointer;
422 1.1 christos operand->error = _("Error in expression");
423 1.1 christos return str;
424 1.1 christos }
425 1.1 christos
426 1.1 christos str = input_line_pointer;
427 1.1 christos input_line_pointer = save_input_line_pointer;
428 1.1 christos
429 1.1 christos operand->reloc.pc_rel = 0;
430 1.1 christos
431 1.1 christos return str;
432 1.1 christos }
433 1.1 christos
434 1.1 christos static char *
435 1.1 christos parse_op_no_deferred (char *str, struct pdp11_code *operand)
436 1.1 christos {
437 1.1 christos LITTLENUM_TYPE literal_float[2];
438 1.1 christos
439 1.1 christos str = skip_whitespace (str);
440 1.1 christos
441 1.1 christos switch (*str)
442 1.1 christos {
443 1.1 christos case '(': /* (rn) and (rn)+ */
444 1.1 christos str = parse_reg (str + 1, operand);
445 1.1 christos if (operand->error)
446 1.1 christos return str;
447 1.1 christos str = skip_whitespace (str);
448 1.1 christos if (*str != ')')
449 1.1 christos {
450 1.1 christos operand->error = _("Missing ')'");
451 1.1 christos return str;
452 1.1 christos }
453 1.1 christos str++;
454 1.1 christos if (*str == '+')
455 1.1 christos {
456 1.1 christos operand->code |= 020;
457 1.1 christos str++;
458 1.1 christos }
459 1.1 christos else
460 1.1 christos {
461 1.1 christos operand->code |= 010;
462 1.1 christos }
463 1.1 christos break;
464 1.1 christos
465 1.1 christos /* Immediate. */
466 1.1 christos case '#':
467 1.1 christos case '$':
468 1.1 christos str = parse_expression (str + 1, operand);
469 1.1 christos if (operand->error)
470 1.1 christos return str;
471 1.1 christos operand->additional = TRUE;
472 1.1 christos operand->word = operand->reloc.exp.X_add_number;
473 1.1 christos switch (operand->reloc.exp.X_op)
474 1.1 christos {
475 1.1 christos case O_constant:
476 1.1 christos break;
477 1.1 christos case O_symbol:
478 1.1 christos case O_add:
479 1.1 christos case O_subtract:
480 1.1 christos operand->reloc.type = BFD_RELOC_16;
481 1.1 christos operand->reloc.pc_rel = 0;
482 1.1 christos break;
483 1.1 christos case O_big:
484 1.1 christos if (operand->reloc.exp.X_add_number > 0)
485 1.1 christos {
486 1.1 christos operand->error = _("Error in expression");
487 1.1 christos break;
488 1.1 christos }
489 1.1 christos /* It's a floating literal... */
490 1.1 christos know (operand->reloc.exp.X_add_number < 0);
491 1.1 christos flonum_gen2vax ('f', &generic_floating_point_number, literal_float);
492 1.1 christos operand->word = literal_float[0];
493 1.1 christos if (literal_float[1] != 0)
494 1.1 christos as_warn (_("Low order bits truncated in immediate float operand"));
495 1.1 christos break;
496 1.1 christos default:
497 1.1 christos operand->error = _("Error in expression");
498 1.1 christos break;
499 1.1 christos }
500 1.1 christos operand->code = 027;
501 1.1 christos break;
502 1.1 christos
503 1.1 christos /* label, d(rn), -(rn) */
504 1.1 christos default:
505 1.1 christos {
506 1.1 christos if (strncmp (str, "-(", 2) == 0) /* -(rn) */
507 1.1 christos {
508 1.1 christos str = parse_reg (str + 2, operand);
509 1.1 christos if (operand->error)
510 1.1 christos return str;
511 1.1 christos str = skip_whitespace (str);
512 1.1 christos if (*str != ')')
513 1.1 christos {
514 1.1 christos operand->error = _("Missing ')'");
515 1.1 christos return str;
516 1.1 christos }
517 1.1 christos operand->code |= 040;
518 1.1 christos str++;
519 1.1 christos break;
520 1.1 christos }
521 1.1 christos
522 1.1 christos str = parse_expression (str, operand);
523 1.1 christos if (operand->error)
524 1.1 christos return str;
525 1.1 christos
526 1.1 christos str = skip_whitespace (str);
527 1.1 christos
528 1.1 christos if (*str != '(')
529 1.1 christos {
530 1.1 christos operand->code = 067;
531 1.1 christos operand->additional = 1;
532 1.1 christos operand->word = 0;
533 1.1 christos operand->reloc.type = BFD_RELOC_16_PCREL;
534 1.1 christos operand->reloc.pc_rel = 1;
535 1.1 christos break;
536 1.1 christos }
537 1.1 christos
538 1.1 christos /* d(rn) */
539 1.1 christos str++;
540 1.1 christos str = parse_reg (str, operand);
541 1.1 christos if (operand->error)
542 1.1 christos return str;
543 1.1 christos
544 1.1 christos str = skip_whitespace (str);
545 1.1 christos
546 1.1 christos if (*str != ')')
547 1.1 christos {
548 1.1 christos operand->error = _("Missing ')'");
549 1.1 christos return str;
550 1.1 christos }
551 1.1 christos
552 1.1 christos str++;
553 1.1 christos operand->additional = TRUE;
554 1.1 christos operand->code |= 060;
555 1.1 christos switch (operand->reloc.exp.X_op)
556 1.1 christos {
557 1.1 christos case O_symbol:
558 1.1 christos operand->reloc.type = BFD_RELOC_16;
559 1.1 christos operand->reloc.pc_rel = 0;
560 1.1 christos break;
561 1.1 christos case O_constant:
562 1.1 christos if ((operand->code & 7) == 7)
563 1.1 christos {
564 1.1 christos operand->reloc.pc_rel = 1;
565 1.1 christos operand->word = operand->reloc.exp.X_add_number;
566 1.1 christos }
567 1.1 christos else
568 1.1 christos operand->word = operand->reloc.exp.X_add_number;
569 1.1 christos
570 1.1 christos break;
571 1.1 christos default:
572 1.1 christos BAD_CASE (operand->reloc.exp.X_op);
573 1.1 christos }
574 1.1 christos break;
575 1.1 christos }
576 1.1 christos }
577 1.1 christos
578 1.1 christos return str;
579 1.1 christos }
580 1.1 christos
581 1.1 christos static char *
582 1.1 christos parse_op_noreg (char *str, struct pdp11_code *operand)
583 1.1 christos {
584 1.1 christos str = skip_whitespace (str);
585 1.1 christos operand->error = NULL;
586 1.1 christos
587 1.1 christos if (*str == '@' || *str == '*')
588 1.1 christos {
589 1.1 christos str = parse_op_no_deferred (str + 1, operand);
590 1.1 christos if (operand->error)
591 1.1 christos return str;
592 1.1 christos operand->code |= 010;
593 1.1 christos }
594 1.1 christos else
595 1.1 christos str = parse_op_no_deferred (str, operand);
596 1.1 christos
597 1.1 christos return str;
598 1.1 christos }
599 1.1 christos
600 1.1 christos static char *
601 1.1 christos parse_op (char *str, struct pdp11_code *operand)
602 1.1 christos {
603 1.1 christos str = skip_whitespace (str);
604 1.1 christos
605 1.1 christos str = parse_reg (str, operand);
606 1.1 christos if (!operand->error)
607 1.1 christos return str;
608 1.1 christos
609 1.1 christos operand->error = NULL;
610 1.1 christos parse_ac5 (str, operand);
611 1.1 christos if (!operand->error)
612 1.1 christos {
613 1.1 christos operand->error = _("Float AC not legal as integer operand");
614 1.1 christos return str;
615 1.1 christos }
616 1.1 christos
617 1.1 christos return parse_op_noreg (str, operand);
618 1.1 christos }
619 1.1 christos
620 1.1 christos static char *
621 1.1 christos parse_fop (char *str, struct pdp11_code *operand)
622 1.1 christos {
623 1.1 christos str = skip_whitespace (str);
624 1.1 christos
625 1.1 christos str = parse_ac5 (str, operand);
626 1.1 christos if (!operand->error)
627 1.1 christos return str;
628 1.1 christos
629 1.1 christos operand->error = NULL;
630 1.1 christos parse_reg (str, operand);
631 1.1 christos if (!operand->error)
632 1.1 christos {
633 1.1 christos operand->error = _("General register not legal as float operand");
634 1.1 christos return str;
635 1.1 christos }
636 1.1 christos
637 1.1 christos return parse_op_noreg (str, operand);
638 1.1 christos }
639 1.1 christos
640 1.1 christos static char *
641 1.1 christos parse_separator (char *str, int *error)
642 1.1 christos {
643 1.1 christos str = skip_whitespace (str);
644 1.1 christos *error = (*str != ',');
645 1.1 christos if (!*error)
646 1.1 christos str++;
647 1.1 christos return str;
648 1.1 christos }
649 1.1 christos
650 1.1 christos void
651 1.1 christos md_assemble (char *instruction_string)
652 1.1 christos {
653 1.1 christos const struct pdp11_opcode *op;
654 1.1 christos struct pdp11_code insn, op1, op2;
655 1.1 christos int error;
656 1.1 christos int size;
657 1.1 christos char *err = NULL;
658 1.1 christos char *str;
659 1.1 christos char *p;
660 1.1 christos char c;
661 1.1 christos
662 1.1 christos str = skip_whitespace (instruction_string);
663 1.1 christos p = find_whitespace (str);
664 1.1 christos if (p - str == 0)
665 1.1 christos {
666 1.1 christos as_bad (_("No instruction found"));
667 1.1 christos return;
668 1.1 christos }
669 1.1 christos
670 1.1 christos c = *p;
671 1.1 christos *p = '\0';
672 1.1 christos op = (struct pdp11_opcode *)hash_find (insn_hash, str);
673 1.1 christos *p = c;
674 1.1 christos if (op == 0)
675 1.1 christos {
676 1.1 christos as_bad (_("Unknown instruction '%s'"), str);
677 1.1 christos return;
678 1.1 christos }
679 1.1 christos
680 1.1 christos if (!pdp11_extension[op->extension])
681 1.1 christos {
682 1.1 christos as_warn (_("Unsupported instruction set extension: %s"), op->name);
683 1.1 christos return;
684 1.1 christos }
685 1.1 christos
686 1.1 christos insn.error = NULL;
687 1.1 christos insn.code = op->opcode;
688 1.1 christos insn.reloc.type = BFD_RELOC_NONE;
689 1.1 christos op1.error = NULL;
690 1.1 christos op1.additional = FALSE;
691 1.1 christos op1.reloc.type = BFD_RELOC_NONE;
692 1.1 christos op2.error = NULL;
693 1.1 christos op2.additional = FALSE;
694 1.1 christos op2.reloc.type = BFD_RELOC_NONE;
695 1.1 christos
696 1.1 christos str = p;
697 1.1 christos size = 2;
698 1.1 christos
699 1.1 christos switch (op->type)
700 1.1 christos {
701 1.1 christos case PDP11_OPCODE_NO_OPS:
702 1.1 christos str = skip_whitespace (str);
703 1.1 christos if (*str == 0)
704 1.1 christos str = "";
705 1.1 christos break;
706 1.1 christos
707 1.1 christos case PDP11_OPCODE_IMM3:
708 1.1 christos case PDP11_OPCODE_IMM6:
709 1.1 christos case PDP11_OPCODE_IMM8:
710 1.1 christos str = skip_whitespace (str);
711 1.1 christos if (*str == '#' || *str == '$')
712 1.1 christos str++;
713 1.1 christos str = parse_expression (str, &op1);
714 1.1 christos if (op1.error)
715 1.1 christos break;
716 1.1 christos if (op1.reloc.exp.X_op != O_constant || op1.reloc.type != BFD_RELOC_NONE)
717 1.1 christos {
718 1.1 christos op1.error = _("operand is not an absolute constant");
719 1.1 christos break;
720 1.1 christos }
721 1.1 christos switch (op->type)
722 1.1 christos {
723 1.1 christos case PDP11_OPCODE_IMM3:
724 1.1 christos if (op1.reloc.exp.X_add_number & ~7)
725 1.1 christos {
726 1.1 christos op1.error = _("3-bit immediate out of range");
727 1.1 christos break;
728 1.1 christos }
729 1.1 christos break;
730 1.1 christos case PDP11_OPCODE_IMM6:
731 1.1 christos if (op1.reloc.exp.X_add_number & ~0x3f)
732 1.1 christos {
733 1.1 christos op1.error = _("6-bit immediate out of range");
734 1.1 christos break;
735 1.1 christos }
736 1.1 christos break;
737 1.1 christos case PDP11_OPCODE_IMM8:
738 1.1 christos if (op1.reloc.exp.X_add_number & ~0xff)
739 1.1 christos {
740 1.1 christos op1.error = _("8-bit immediate out of range");
741 1.1 christos break;
742 1.1 christos }
743 1.1 christos break;
744 1.1 christos }
745 1.1 christos insn.code |= op1.reloc.exp.X_add_number;
746 1.1 christos break;
747 1.1 christos
748 1.1 christos case PDP11_OPCODE_DISPL:
749 1.1 christos {
750 1.1 christos char *new_pointer;
751 1.1 christos new_pointer = parse_expression (str, &op1);
752 1.1 christos op1.code = 0;
753 1.1 christos op1.reloc.pc_rel = 1;
754 1.1 christos op1.reloc.type = BFD_RELOC_PDP11_DISP_8_PCREL;
755 1.1 christos if (op1.reloc.exp.X_op != O_symbol)
756 1.1 christos {
757 1.1 christos op1.error = _("Symbol expected");
758 1.1 christos break;
759 1.1 christos }
760 1.1 christos if (op1.code & ~0xff)
761 1.1 christos {
762 1.1 christos err = _("8-bit displacement out of range");
763 1.1 christos break;
764 1.1 christos }
765 1.1 christos str = new_pointer;
766 1.1 christos insn.code |= op1.code;
767 1.1 christos insn.reloc = op1.reloc;
768 1.1 christos }
769 1.1 christos break;
770 1.1 christos
771 1.1 christos case PDP11_OPCODE_REG:
772 1.1 christos str = parse_reg (str, &op1);
773 1.1 christos if (op1.error)
774 1.1 christos break;
775 1.1 christos insn.code |= op1.code;
776 1.1 christos break;
777 1.1 christos
778 1.1 christos case PDP11_OPCODE_OP:
779 1.1 christos str = parse_op (str, &op1);
780 1.1 christos if (op1.error)
781 1.1 christos break;
782 1.1 christos insn.code |= op1.code;
783 1.1 christos if (op1.additional)
784 1.1 christos size += 2;
785 1.1 christos break;
786 1.1 christos
787 1.1 christos case PDP11_OPCODE_FOP:
788 1.1 christos str = parse_fop (str, &op1);
789 1.1 christos if (op1.error)
790 1.1 christos break;
791 1.1 christos insn.code |= op1.code;
792 1.1 christos if (op1.additional)
793 1.1 christos size += 2;
794 1.1 christos break;
795 1.1 christos
796 1.1 christos case PDP11_OPCODE_REG_OP:
797 1.1 christos str = parse_reg (str, &op2);
798 1.1 christos if (op2.error)
799 1.1 christos break;
800 1.1 christos insn.code |= op2.code << 6;
801 1.1 christos str = parse_separator (str, &error);
802 1.1 christos if (error)
803 1.1 christos {
804 1.1 christos op2.error = _("Missing ','");
805 1.1 christos break;
806 1.1 christos }
807 1.1 christos str = parse_op (str, &op1);
808 1.1 christos if (op1.error)
809 1.1 christos break;
810 1.1 christos insn.code |= op1.code;
811 1.1 christos if (op1.additional)
812 1.1 christos size += 2;
813 1.1 christos break;
814 1.1 christos
815 1.1 christos case PDP11_OPCODE_REG_OP_REV:
816 1.1 christos str = parse_op (str, &op1);
817 1.1 christos if (op1.error)
818 1.1 christos break;
819 1.1 christos insn.code |= op1.code;
820 1.1 christos if (op1.additional)
821 1.1 christos size += 2;
822 1.1 christos str = parse_separator (str, &error);
823 1.1 christos if (error)
824 1.1 christos {
825 1.1 christos op2.error = _("Missing ','");
826 1.1 christos break;
827 1.1 christos }
828 1.1 christos str = parse_reg (str, &op2);
829 1.1 christos if (op2.error)
830 1.1 christos break;
831 1.1 christos insn.code |= op2.code << 6;
832 1.1 christos break;
833 1.1 christos
834 1.1 christos case PDP11_OPCODE_AC_FOP:
835 1.1 christos str = parse_ac (str, &op2);
836 1.1 christos if (op2.error)
837 1.1 christos break;
838 1.1 christos insn.code |= op2.code << 6;
839 1.1 christos str = parse_separator (str, &error);
840 1.1 christos if (error)
841 1.1 christos {
842 1.1 christos op1.error = _("Missing ','");
843 1.1 christos break;
844 1.1 christos }
845 1.1 christos str = parse_fop (str, &op1);
846 1.1 christos if (op1.error)
847 1.1 christos break;
848 1.1 christos insn.code |= op1.code;
849 1.1 christos if (op1.additional)
850 1.1 christos size += 2;
851 1.1 christos break;
852 1.1 christos
853 1.1 christos case PDP11_OPCODE_FOP_AC:
854 1.1 christos str = parse_fop (str, &op1);
855 1.1 christos if (op1.error)
856 1.1 christos break;
857 1.1 christos insn.code |= op1.code;
858 1.1 christos if (op1.additional)
859 1.1 christos size += 2;
860 1.1 christos str = parse_separator (str, &error);
861 1.1 christos if (error)
862 1.1 christos {
863 1.1 christos op1.error = _("Missing ','");
864 1.1 christos break;
865 1.1 christos }
866 1.1 christos str = parse_ac (str, &op2);
867 1.1 christos if (op2.error)
868 1.1 christos break;
869 1.1 christos insn.code |= op2.code << 6;
870 1.1 christos break;
871 1.1 christos
872 1.1 christos case PDP11_OPCODE_AC_OP:
873 1.1 christos str = parse_ac (str, &op2);
874 1.1 christos if (op2.error)
875 1.1 christos break;
876 1.1 christos insn.code |= op2.code << 6;
877 1.1 christos str = parse_separator (str, &error);
878 1.1 christos if (error)
879 1.1 christos {
880 1.1 christos op1.error = _("Missing ','");
881 1.1 christos break;
882 1.1 christos }
883 1.1 christos str = parse_op (str, &op1);
884 1.1 christos if (op1.error)
885 1.1 christos break;
886 1.1 christos insn.code |= op1.code;
887 1.1 christos if (op1.additional)
888 1.1 christos size += 2;
889 1.1 christos break;
890 1.1 christos
891 1.1 christos case PDP11_OPCODE_OP_AC:
892 1.1 christos str = parse_op (str, &op1);
893 1.1 christos if (op1.error)
894 1.1 christos break;
895 1.1 christos insn.code |= op1.code;
896 1.1 christos if (op1.additional)
897 1.1 christos size += 2;
898 1.1 christos str = parse_separator (str, &error);
899 1.1 christos if (error)
900 1.1 christos {
901 1.1 christos op1.error = _("Missing ','");
902 1.1 christos break;
903 1.1 christos }
904 1.1 christos str = parse_ac (str, &op2);
905 1.1 christos if (op2.error)
906 1.1 christos break;
907 1.1 christos insn.code |= op2.code << 6;
908 1.1 christos break;
909 1.1 christos
910 1.1 christos case PDP11_OPCODE_OP_OP:
911 1.1 christos str = parse_op (str, &op1);
912 1.1 christos if (op1.error)
913 1.1 christos break;
914 1.1 christos insn.code |= op1.code << 6;
915 1.1 christos if (op1.additional)
916 1.1 christos size += 2;
917 1.1 christos str = parse_separator (str, &error);
918 1.1 christos if (error)
919 1.1 christos {
920 1.1 christos op2.error = _("Missing ','");
921 1.1 christos break;
922 1.1 christos }
923 1.1 christos str = parse_op (str, &op2);
924 1.1 christos if (op2.error)
925 1.1 christos break;
926 1.1 christos insn.code |= op2.code;
927 1.1 christos if (op2.additional)
928 1.1 christos size += 2;
929 1.1 christos break;
930 1.1 christos
931 1.1 christos case PDP11_OPCODE_REG_DISPL:
932 1.1 christos {
933 1.1 christos char *new_pointer;
934 1.1 christos str = parse_reg (str, &op2);
935 1.1 christos if (op2.error)
936 1.1 christos break;
937 1.1 christos insn.code |= op2.code << 6;
938 1.1 christos str = parse_separator (str, &error);
939 1.1 christos if (error)
940 1.1 christos {
941 1.1 christos op1.error = _("Missing ','");
942 1.1 christos break;
943 1.1 christos }
944 1.1 christos new_pointer = parse_expression (str, &op1);
945 1.1 christos op1.code = 0;
946 1.1 christos op1.reloc.pc_rel = 1;
947 1.1 christos op1.reloc.type = BFD_RELOC_PDP11_DISP_6_PCREL;
948 1.1 christos if (op1.reloc.exp.X_op != O_symbol)
949 1.1 christos {
950 1.1 christos op1.error = _("Symbol expected");
951 1.1 christos break;
952 1.1 christos }
953 1.1 christos if (op1.code & ~0x3f)
954 1.1 christos {
955 1.1 christos err = _("6-bit displacement out of range");
956 1.1 christos break;
957 1.1 christos }
958 1.1 christos str = new_pointer;
959 1.1 christos insn.code |= op1.code;
960 1.1 christos insn.reloc = op1.reloc;
961 1.1 christos }
962 1.1 christos break;
963 1.1 christos
964 1.1 christos default:
965 1.1 christos BAD_CASE (op->type);
966 1.1 christos }
967 1.1 christos
968 1.1 christos if (op1.error)
969 1.1 christos err = op1.error;
970 1.1 christos else if (op2.error)
971 1.1 christos err = op2.error;
972 1.1 christos else
973 1.1 christos {
974 1.1 christos str = skip_whitespace (str);
975 1.1 christos if (*str)
976 1.1 christos err = _("Too many operands");
977 1.1 christos }
978 1.1 christos
979 1.1 christos {
980 1.1 christos char *to = NULL;
981 1.1 christos
982 1.1 christos if (err)
983 1.1 christos {
984 1.1 christos as_bad ("%s", err);
985 1.1 christos return;
986 1.1 christos }
987 1.1 christos
988 1.1 christos to = frag_more (size);
989 1.1 christos
990 1.1 christos md_number_to_chars (to, insn.code, 2);
991 1.1 christos if (insn.reloc.type != BFD_RELOC_NONE)
992 1.1 christos fix_new_exp (frag_now, to - frag_now->fr_literal, 2,
993 1.1 christos &insn.reloc.exp, insn.reloc.pc_rel, insn.reloc.type);
994 1.1 christos to += 2;
995 1.1 christos
996 1.1 christos if (op1.additional)
997 1.1 christos {
998 1.1 christos md_number_to_chars (to, op1.word, 2);
999 1.1 christos if (op1.reloc.type != BFD_RELOC_NONE)
1000 1.1 christos fix_new_exp (frag_now, to - frag_now->fr_literal, 2,
1001 1.1 christos &op1.reloc.exp, op1.reloc.pc_rel, op1.reloc.type);
1002 1.1 christos to += 2;
1003 1.1 christos }
1004 1.1 christos
1005 1.1 christos if (op2.additional)
1006 1.1 christos {
1007 1.1 christos md_number_to_chars (to, op2.word, 2);
1008 1.1 christos if (op2.reloc.type != BFD_RELOC_NONE)
1009 1.1 christos fix_new_exp (frag_now, to - frag_now->fr_literal, 2,
1010 1.1 christos &op2.reloc.exp, op2.reloc.pc_rel, op2.reloc.type);
1011 1.1 christos }
1012 1.1 christos }
1013 1.1 christos }
1014 1.1 christos
1015 1.1 christos int
1016 1.1 christos md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1017 1.1 christos segT segment ATTRIBUTE_UNUSED)
1018 1.1 christos {
1019 1.1 christos return 0;
1020 1.1 christos }
1021 1.1 christos
1022 1.1 christos void
1023 1.1 christos md_convert_frag (bfd *headers ATTRIBUTE_UNUSED,
1024 1.1 christos segT seg ATTRIBUTE_UNUSED,
1025 1.1 christos fragS *fragP ATTRIBUTE_UNUSED)
1026 1.1 christos {
1027 1.1 christos }
1028 1.1 christos
1029 1.1 christos int md_short_jump_size = 2;
1030 1.1 christos int md_long_jump_size = 4;
1031 1.1 christos
1032 1.1 christos void
1033 1.1 christos md_create_short_jump (char *ptr ATTRIBUTE_UNUSED,
1034 1.1 christos addressT from_addr ATTRIBUTE_UNUSED,
1035 1.1 christos addressT to_addr ATTRIBUTE_UNUSED,
1036 1.1 christos fragS *frag ATTRIBUTE_UNUSED,
1037 1.1 christos symbolS *to_symbol ATTRIBUTE_UNUSED)
1038 1.1 christos {
1039 1.1 christos }
1040 1.1 christos
1041 1.1 christos void
1042 1.1 christos md_create_long_jump (char *ptr ATTRIBUTE_UNUSED,
1043 1.1 christos addressT from_addr ATTRIBUTE_UNUSED,
1044 1.1 christos addressT to_addr ATTRIBUTE_UNUSED,
1045 1.1 christos fragS *frag ATTRIBUTE_UNUSED,
1046 1.1 christos symbolS *to_symbol ATTRIBUTE_UNUSED)
1047 1.1 christos {
1048 1.1 christos }
1049 1.1 christos
1050 1.1 christos static int
1051 1.1 christos set_cpu_model (char *arg)
1052 1.1 christos {
1053 1.1 christos char buf[4];
1054 1.1 christos char *model = buf;
1055 1.1 christos
1056 1.1 christos if (arg[0] == 'k')
1057 1.1 christos arg++;
1058 1.1 christos
1059 1.1 christos *model++ = *arg++;
1060 1.1 christos
1061 1.1 christos if (strchr ("abdx", model[-1]) == NULL)
1062 1.1 christos return 0;
1063 1.1 christos
1064 1.1 christos if (model[-1] == 'd')
1065 1.1 christos {
1066 1.1 christos if (arg[0] == 'f' || arg[0] == 'j')
1067 1.1 christos model[-1] = *arg++;
1068 1.1 christos }
1069 1.1 christos else if (model[-1] == 'x')
1070 1.1 christos {
1071 1.1 christos if (arg[0] == 't')
1072 1.1 christos model[-1] = *arg++;
1073 1.1 christos }
1074 1.1 christos
1075 1.1 christos if (arg[0] == '-')
1076 1.1 christos arg++;
1077 1.1 christos
1078 1.1 christos if (strncmp (arg, "11", 2) != 0)
1079 1.1 christos return 0;
1080 1.1 christos arg += 2;
1081 1.1 christos
1082 1.1 christos if (arg[0] == '-')
1083 1.1 christos {
1084 1.1 christos if (*++arg == 0)
1085 1.1 christos return 0;
1086 1.1 christos }
1087 1.1 christos
1088 1.1 christos /* Allow up to two revision letters. */
1089 1.1 christos if (arg[0] != 0)
1090 1.1 christos *model++ = *arg++;
1091 1.1 christos if (arg[0] != 0)
1092 1.1 christos *model++ = *arg++;
1093 1.1 christos
1094 1.1 christos *model++ = 0;
1095 1.1 christos
1096 1.1 christos set_option ("no-extensions");
1097 1.1 christos
1098 1.1 christos /* KA11 (11/15/20). */
1099 1.1 christos if (strncmp (buf, "a", 1) == 0)
1100 1.1 christos return 1; /* No extensions. */
1101 1.1 christos
1102 1.1 christos /* KB11 (11/45/50/55/70). */
1103 1.1 christos else if (strncmp (buf, "b", 1) == 0)
1104 1.1 christos return set_option ("eis") && set_option ("spl");
1105 1.1 christos
1106 1.1 christos /* KD11-A (11/35/40). */
1107 1.1 christos else if (strncmp (buf, "da", 2) == 0)
1108 1.1 christos return set_option ("limited-eis");
1109 1.1 christos
1110 1.1 christos /* KD11-B (11/05/10). */
1111 1.1 christos else if (strncmp (buf, "db", 2) == 0
1112 1.1 christos /* KD11-D (11/04). */
1113 1.1 christos || strncmp (buf, "dd", 2) == 0)
1114 1.1 christos return 1; /* no extensions */
1115 1.1 christos
1116 1.1 christos /* KD11-E (11/34). */
1117 1.1 christos else if (strncmp (buf, "de", 2) == 0)
1118 1.1 christos return set_option ("eis") && set_option ("mxps");
1119 1.1 christos
1120 1.1 christos /* KD11-F (11/03). */
1121 1.1 christos else if (strncmp (buf, "df", 2) == 0
1122 1.1 christos /* KD11-H (11/03). */
1123 1.1 christos || strncmp (buf, "dh", 2) == 0
1124 1.1 christos /* KD11-Q (11/03). */
1125 1.1 christos || strncmp (buf, "dq", 2) == 0)
1126 1.1 christos return set_option ("limited-eis") && set_option ("mxps");
1127 1.1 christos
1128 1.1 christos /* KD11-K (11/60). */
1129 1.1 christos else if (strncmp (buf, "dk", 2) == 0)
1130 1.1 christos return set_option ("eis")
1131 1.1 christos && set_option ("mxps")
1132 1.1 christos && set_option ("ucode");
1133 1.1 christos
1134 1.1 christos /* KD11-Z (11/44). */
1135 1.1 christos else if (strncmp (buf, "dz", 2) == 0)
1136 1.1 christos return set_option ("csm")
1137 1.1 christos && set_option ("eis")
1138 1.1 christos && set_option ("mfpt")
1139 1.1 christos && set_option ("mxps")
1140 1.1 christos && set_option ("spl");
1141 1.1 christos
1142 1.1 christos /* F11 (11/23/24). */
1143 1.1 christos else if (strncmp (buf, "f", 1) == 0)
1144 1.1 christos return set_option ("eis")
1145 1.1 christos && set_option ("mfpt")
1146 1.1 christos && set_option ("mxps");
1147 1.1 christos
1148 1.1 christos /* J11 (11/53/73/83/84/93/94). */
1149 1.1 christos else if (strncmp (buf, "j", 1) == 0)
1150 1.1 christos return set_option ("csm")
1151 1.1 christos && set_option ("eis")
1152 1.1 christos && set_option ("mfpt")
1153 1.1 christos && set_option ("multiproc")
1154 1.1 christos && set_option ("mxps")
1155 1.1 christos && set_option ("spl");
1156 1.1 christos
1157 1.1 christos /* T11 (11/21). */
1158 1.1 christos else if (strncmp (buf, "t", 1) == 0)
1159 1.1 christos return set_option ("limited-eis")
1160 1.1 christos && set_option ("mxps");
1161 1.1 christos
1162 1.1 christos else
1163 1.1 christos return 0;
1164 1.1 christos }
1165 1.1 christos
1166 1.1 christos static int
1167 1.1 christos set_machine_model (char *arg)
1168 1.1 christos {
1169 1.1 christos if (strncmp (arg, "pdp-11/", 7) != 0
1170 1.1 christos && strncmp (arg, "pdp11/", 6) != 0
1171 1.1 christos && strncmp (arg, "11/", 3) != 0)
1172 1.1 christos return 0;
1173 1.1 christos
1174 1.1 christos if (strncmp (arg, "pdp", 3) == 0)
1175 1.1 christos arg += 3;
1176 1.1 christos if (arg[0] == '-')
1177 1.1 christos arg++;
1178 1.1 christos if (strncmp (arg, "11/", 3) == 0)
1179 1.1 christos arg += 3;
1180 1.1 christos
1181 1.1 christos if (strcmp (arg, "03") == 0)
1182 1.1 christos return set_cpu_model ("kd11f");
1183 1.1 christos
1184 1.1 christos else if (strcmp (arg, "04") == 0)
1185 1.1 christos return set_cpu_model ("kd11d");
1186 1.1 christos
1187 1.1 christos else if (strcmp (arg, "05") == 0
1188 1.1 christos || strcmp (arg, "10") == 0)
1189 1.1 christos return set_cpu_model ("kd11b");
1190 1.1 christos
1191 1.1 christos else if (strcmp (arg, "15") == 0
1192 1.1 christos || strcmp (arg, "20") == 0)
1193 1.1 christos return set_cpu_model ("ka11");
1194 1.1 christos
1195 1.1 christos else if (strcmp (arg, "21") == 0)
1196 1.1 christos return set_cpu_model ("t11");
1197 1.1 christos
1198 1.1 christos else if (strcmp (arg, "23") == 0
1199 1.1 christos || strcmp (arg, "24") == 0)
1200 1.1 christos return set_cpu_model ("f11");
1201 1.1 christos
1202 1.1 christos else if (strcmp (arg, "34") == 0
1203 1.1 christos || strcmp (arg, "34a") == 0)
1204 1.1 christos return set_cpu_model ("kd11e");
1205 1.1 christos
1206 1.1 christos else if (strcmp (arg, "35") == 0
1207 1.1 christos || strcmp (arg, "40") == 0)
1208 1.1 christos return set_cpu_model ("kd11da");
1209 1.1 christos
1210 1.1 christos else if (strcmp (arg, "44") == 0)
1211 1.1 christos return set_cpu_model ("kd11dz");
1212 1.1 christos
1213 1.1 christos else if (strcmp (arg, "45") == 0
1214 1.1 christos || strcmp (arg, "50") == 0
1215 1.1 christos || strcmp (arg, "55") == 0
1216 1.1 christos || strcmp (arg, "70") == 0)
1217 1.1 christos return set_cpu_model ("kb11");
1218 1.1 christos
1219 1.1 christos else if (strcmp (arg, "60") == 0)
1220 1.1 christos return set_cpu_model ("kd11k");
1221 1.1 christos
1222 1.1 christos else if (strcmp (arg, "53") == 0
1223 1.1 christos || strcmp (arg, "73") == 0
1224 1.1 christos || strcmp (arg, "83") == 0
1225 1.1 christos || strcmp (arg, "84") == 0
1226 1.1 christos || strcmp (arg, "93") == 0
1227 1.1 christos || strcmp (arg, "94") == 0)
1228 1.1 christos return set_cpu_model ("j11")
1229 1.1 christos && set_option ("fpp");
1230 1.1 christos
1231 1.1 christos else
1232 1.1 christos return 0;
1233 1.1 christos }
1234 1.1 christos
1235 1.1 christos const char *md_shortopts = "m:";
1236 1.1 christos
1237 1.1 christos struct option md_longopts[] =
1238 1.1 christos {
1239 1.1 christos #define OPTION_CPU 257
1240 1.1 christos { "cpu", required_argument, NULL, OPTION_CPU },
1241 1.1 christos #define OPTION_MACHINE 258
1242 1.1 christos { "machine", required_argument, NULL, OPTION_MACHINE },
1243 1.1 christos #define OPTION_PIC 259
1244 1.1 christos { "pic", no_argument, NULL, OPTION_PIC },
1245 1.1 christos { NULL, no_argument, NULL, 0 }
1246 1.1 christos };
1247 1.1 christos
1248 1.1 christos size_t md_longopts_size = sizeof (md_longopts);
1249 1.1 christos
1250 1.1 christos /* Invocation line includes a switch not recognized by the base assembler.
1251 1.1 christos See if it's a processor-specific option. */
1252 1.1 christos
1253 1.1 christos int
1254 1.1 christos md_parse_option (int c, char *arg)
1255 1.1 christos {
1256 1.1 christos init_defaults ();
1257 1.1 christos
1258 1.1 christos switch (c)
1259 1.1 christos {
1260 1.1 christos case 'm':
1261 1.1 christos if (set_option (arg))
1262 1.1 christos return 1;
1263 1.1 christos if (set_cpu_model (arg))
1264 1.1 christos return 1;
1265 1.1 christos if (set_machine_model (arg))
1266 1.1 christos return 1;
1267 1.1 christos break;
1268 1.1 christos
1269 1.1 christos case OPTION_CPU:
1270 1.1 christos if (set_cpu_model (arg))
1271 1.1 christos return 1;
1272 1.1 christos break;
1273 1.1 christos
1274 1.1 christos case OPTION_MACHINE:
1275 1.1 christos if (set_machine_model (arg))
1276 1.1 christos return 1;
1277 1.1 christos break;
1278 1.1 christos
1279 1.1 christos case OPTION_PIC:
1280 1.1 christos if (set_option ("pic"))
1281 1.1 christos return 1;
1282 1.1 christos break;
1283 1.1 christos
1284 1.1 christos default:
1285 1.1 christos break;
1286 1.1 christos }
1287 1.1 christos
1288 1.1 christos return 0;
1289 1.1 christos }
1290 1.1 christos
1291 1.1 christos void
1292 1.1 christos md_show_usage (FILE *stream)
1293 1.1 christos {
1294 1.1 christos fprintf (stream, "\
1295 1.1 christos \n\
1296 1.1 christos PDP-11 instruction set extentions:\n\
1297 1.1 christos \n\
1298 1.1 christos -m(no-)cis allow (disallow) commersial instruction set\n\
1299 1.1 christos -m(no-)csm allow (disallow) CSM instruction\n\
1300 1.1 christos -m(no-)eis allow (disallow) full extended instruction set\n\
1301 1.1 christos -m(no-)fis allow (disallow) KEV11 floating-point instructions\n\
1302 1.1 christos -m(no-)fpp allow (disallow) FP-11 floating-point instructions\n\
1303 1.1 christos -m(no-)fpu allow (disallow) FP-11 floating-point instructions\n\
1304 1.1 christos -m(no-)limited-eis allow (disallow) limited extended instruction set\n\
1305 1.1 christos -m(no-)mfpt allow (disallow) processor type instruction\n\
1306 1.1 christos -m(no-)multiproc allow (disallow) multiprocessor instructions\n\
1307 1.1 christos -m(no-)mxps allow (disallow) processor status instructions\n\
1308 1.1 christos -m(no-)spl allow (disallow) SPL instruction\n\
1309 1.1 christos -m(no-)ucode allow (disallow) microcode instructions\n\
1310 1.1 christos -mall-extensions allow all instruction set extensions\n\
1311 1.1 christos (this is the default)\n\
1312 1.1 christos -mno-extentions disallow all instruction set extensions\n\
1313 1.1 christos -pic generate position-indepenent code\n\
1314 1.1 christos \n\
1315 1.1 christos PDP-11 CPU model options:\n\
1316 1.1 christos \n\
1317 1.1 christos -mka11* KA11 CPU. base line instruction set only\n\
1318 1.1 christos -mkb11* KB11 CPU. enable full EIS and SPL\n\
1319 1.1 christos -mkd11a* KD11-A CPU. enable limited EIS\n\
1320 1.1 christos -mkd11b* KD11-B CPU. base line instruction set only\n\
1321 1.1 christos -mkd11d* KD11-D CPU. base line instruction set only\n\
1322 1.1 christos -mkd11e* KD11-E CPU. enable full EIS, MTPS, and MFPS\n\
1323 1.1 christos -mkd11f* KD11-F CPU. enable limited EIS, MTPS, and MFPS\n\
1324 1.1 christos -mkd11h* KD11-H CPU. enable limited EIS, MTPS, and MFPS\n\
1325 1.1 christos -mkd11q* KD11-Q CPU. enable limited EIS, MTPS, and MFPS\n\
1326 1.1 christos -mkd11k* KD11-K CPU. enable full EIS, MTPS, MFPS, LDUB, MED,\n\
1327 1.1 christos XFC, and MFPT\n\
1328 1.1 christos -mkd11z* KD11-Z CPU. enable full EIS, MTPS, MFPS, MFPT, SPL,\n\
1329 1.1 christos and CSM\n\
1330 1.1 christos -mf11* F11 CPU. enable full EIS, MFPS, MTPS, and MFPT\n\
1331 1.1 christos -mj11* J11 CPU. enable full EIS, MTPS, MFPS, MFPT, SPL,\n\
1332 1.1 christos CSM, TSTSET, and WRTLCK\n\
1333 1.1 christos -mt11* T11 CPU. enable limited EIS, MTPS, and MFPS\n\
1334 1.1 christos \n\
1335 1.1 christos PDP-11 machine model options:\n\
1336 1.1 christos \n\
1337 1.1 christos -m11/03 same as -mkd11f\n\
1338 1.1 christos -m11/04 same as -mkd11d\n\
1339 1.1 christos -m11/05 same as -mkd11b\n\
1340 1.1 christos -m11/10 same as -mkd11b\n\
1341 1.1 christos -m11/15 same as -mka11\n\
1342 1.1 christos -m11/20 same as -mka11\n\
1343 1.1 christos -m11/21 same as -mt11\n\
1344 1.1 christos -m11/23 same as -mf11\n\
1345 1.1 christos -m11/24 same as -mf11\n\
1346 1.1 christos -m11/34 same as -mkd11e\n\
1347 1.1 christos -m11/34a same as -mkd11e -mfpp\n\
1348 1.1 christos -m11/35 same as -mkd11a\n\
1349 1.1 christos -m11/40 same as -mkd11a\n\
1350 1.1 christos -m11/44 same as -mkd11z\n\
1351 1.1 christos -m11/45 same as -mkb11\n\
1352 1.1 christos -m11/50 same as -mkb11\n\
1353 1.1 christos -m11/53 same as -mj11\n\
1354 1.1 christos -m11/55 same as -mkb11\n\
1355 1.1 christos -m11/60 same as -mkd11k\n\
1356 1.1 christos -m11/70 same as -mkb11\n\
1357 1.1 christos -m11/73 same as -mj11\n\
1358 1.1 christos -m11/83 same as -mj11\n\
1359 1.1 christos -m11/84 same as -mj11\n\
1360 1.1 christos -m11/93 same as -mj11\n\
1361 1.1 christos -m11/94 same as -mj11\n\
1362 1.1 christos ");
1363 1.1 christos }
1364 1.1 christos
1365 1.1 christos symbolS *
1366 1.1 christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1367 1.1 christos {
1368 1.1 christos return 0;
1369 1.1 christos }
1370 1.1 christos
1371 1.1 christos valueT
1372 1.1 christos md_section_align (segT segment ATTRIBUTE_UNUSED,
1373 1.1 christos valueT size)
1374 1.1 christos {
1375 1.1 christos return (size + 1) & ~1;
1376 1.1 christos }
1377 1.1 christos
1378 1.1 christos long
1379 1.1 christos md_pcrel_from (fixS *fixP)
1380 1.1 christos {
1381 1.1 christos return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1382 1.1 christos }
1383 1.1 christos
1384 1.1 christos /* Translate internal representation of relocation info to BFD target
1385 1.1 christos format. */
1386 1.1 christos
1387 1.1 christos arelent *
1388 1.1 christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1389 1.1 christos fixS *fixp)
1390 1.1 christos {
1391 1.1 christos arelent *reloc;
1392 1.1 christos bfd_reloc_code_real_type code;
1393 1.1 christos
1394 1.1 christos reloc = xmalloc (sizeof (* reloc));
1395 1.1 christos
1396 1.1 christos reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1397 1.1 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1398 1.1 christos reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1399 1.1 christos
1400 1.1 christos /* This is taken account for in md_apply_fix(). */
1401 1.1 christos reloc->addend = -symbol_get_bfdsym (fixp->fx_addsy)->section->vma;
1402 1.1 christos
1403 1.1 christos switch (fixp->fx_r_type)
1404 1.1 christos {
1405 1.1 christos case BFD_RELOC_16:
1406 1.1 christos if (fixp->fx_pcrel)
1407 1.1 christos code = BFD_RELOC_16_PCREL;
1408 1.1 christos else
1409 1.1 christos code = BFD_RELOC_16;
1410 1.1 christos break;
1411 1.1 christos
1412 1.1 christos case BFD_RELOC_16_PCREL:
1413 1.1 christos code = BFD_RELOC_16_PCREL;
1414 1.1 christos break;
1415 1.1 christos
1416 1.1 christos default:
1417 1.1 christos BAD_CASE (fixp->fx_r_type);
1418 1.1 christos return NULL;
1419 1.1 christos }
1420 1.1 christos
1421 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
1422 1.1 christos
1423 1.1 christos if (reloc->howto == NULL)
1424 1.1 christos {
1425 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line,
1426 1.1 christos _("Can not represent %s relocation in this object file format"),
1427 1.1 christos bfd_get_reloc_code_name (code));
1428 1.1 christos return NULL;
1429 1.1 christos }
1430 1.1 christos
1431 1.1 christos return reloc;
1432 1.1 christos }
1433 1.1 christos
1434 1.1 christos void
1435 1.1 christos pseudo_bss (int c ATTRIBUTE_UNUSED)
1436 1.1 christos {
1437 1.1 christos int temp;
1438 1.1 christos
1439 1.1 christos temp = get_absolute_expression ();
1440 1.1 christos subseg_set (bss_section, temp);
1441 1.1 christos demand_empty_rest_of_line ();
1442 1.1 christos }
1443 1.1 christos
1444 1.1 christos void
1445 1.1 christos pseudo_even (int c ATTRIBUTE_UNUSED)
1446 1.1 christos {
1447 1.1 christos int alignment = 1; /* 2^1 */
1448 1.1 christos frag_align (alignment, 0, 1);
1449 1.1 christos record_alignment (now_seg, alignment);
1450 1.1 christos }
1451 1.1 christos
1452 1.1 christos char *
1453 1.1 christos md_atof (int type, char * litP, int * sizeP)
1454 1.1 christos {
1455 return vax_md_atof (type, litP, sizeP);
1456 }
1457