1440a403fSchristos /* tc-pdp11.c - pdp11-specific -
2*b88e3e88Schristos    Copyright (C) 2001-2020 Free Software Foundation, Inc.
3440a403fSchristos 
4440a403fSchristos    This file is part of GAS, the GNU Assembler.
5440a403fSchristos 
6440a403fSchristos    GAS is free software; you can redistribute it and/or modify
7440a403fSchristos    it under the terms of the GNU General Public License as published by
8440a403fSchristos    the Free Software Foundation; either version 3, or (at your option)
9440a403fSchristos    any later version.
10440a403fSchristos 
11440a403fSchristos    GAS is distributed in the hope that it will be useful,
12440a403fSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
13440a403fSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14440a403fSchristos    GNU General Public License for more details.
15440a403fSchristos 
16440a403fSchristos    You should have received a copy of the GNU General Public License
17440a403fSchristos    along with GAS; see the file COPYING.  If not, write to
18440a403fSchristos    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
19440a403fSchristos    Boston, MA 02110-1301, USA.  */
20440a403fSchristos 
21440a403fSchristos #include "as.h"
22440a403fSchristos #include "safe-ctype.h"
23440a403fSchristos #include "opcode/pdp11.h"
24440a403fSchristos 
25440a403fSchristos extern int flonum_gen2vax (int, FLONUM_TYPE * f, LITTLENUM_TYPE *);
26440a403fSchristos 
27440a403fSchristos #define TRUE  1
28440a403fSchristos #define FALSE 0
29440a403fSchristos 
30440a403fSchristos /* A representation for PDP-11 machine code.  */
31440a403fSchristos struct pdp11_code
32440a403fSchristos {
33440a403fSchristos   const char *error;
34440a403fSchristos   int code;
35440a403fSchristos   int additional;	/* Is there an additional word?  */
36440a403fSchristos   int word;		/* Additional word, if any.  */
37440a403fSchristos   struct
38440a403fSchristos   {
39440a403fSchristos     bfd_reloc_code_real_type type;
40440a403fSchristos     expressionS exp;
41440a403fSchristos     int pc_rel;
42440a403fSchristos   } reloc;
43440a403fSchristos };
44440a403fSchristos 
45440a403fSchristos /* Instruction set extensions.
46440a403fSchristos 
47440a403fSchristos    If you change this from an array to something else, please update
48440a403fSchristos    the "PDP-11 instruction set extensions" comment in pdp11.h.  */
49440a403fSchristos int pdp11_extension[PDP11_EXT_NUM];
50440a403fSchristos 
51440a403fSchristos /* Assembly options.  */
52440a403fSchristos 
53440a403fSchristos #define ASM_OPT_PIC 1
54440a403fSchristos #define ASM_OPT_NUM 2
55440a403fSchristos 
56440a403fSchristos int asm_option[ASM_OPT_NUM];
57440a403fSchristos 
58440a403fSchristos /* These chars start a comment anywhere in a source file (except inside
59440a403fSchristos    another comment.  */
60440a403fSchristos const char comment_chars[] = "#/";
61440a403fSchristos 
62440a403fSchristos /* These chars only start a comment at the beginning of a line.  */
63440a403fSchristos const char line_comment_chars[] = "#/";
64440a403fSchristos 
65440a403fSchristos const char line_separator_chars[] = ";";
66440a403fSchristos 
67440a403fSchristos /* Chars that can be used to separate mant from exp in floating point nums.  */
68440a403fSchristos const char EXP_CHARS[] = "eE";
69440a403fSchristos 
70440a403fSchristos /* Chars that mean this number is a floating point constant.  */
71440a403fSchristos /* as in 0f123.456.  */
72440a403fSchristos /* or    0H1.234E-12 (see exp chars above).  */
73440a403fSchristos const char FLT_CHARS[] = "dDfF";
74440a403fSchristos 
75440a403fSchristos void pseudo_even (int);
76440a403fSchristos void pseudo_bss (int);
77440a403fSchristos 
78440a403fSchristos const pseudo_typeS md_pseudo_table[] =
79440a403fSchristos {
80440a403fSchristos   { "bss", pseudo_bss, 0 },
81440a403fSchristos   { "even", pseudo_even, 0 },
82440a403fSchristos   { 0, 0, 0 },
83440a403fSchristos };
84440a403fSchristos 
85440a403fSchristos static struct hash_control *insn_hash = NULL;
86440a403fSchristos 
87440a403fSchristos static int
set_option(const char * arg)88440a403fSchristos set_option (const char *arg)
89440a403fSchristos {
90440a403fSchristos   int yes = 1;
91440a403fSchristos 
92440a403fSchristos   if (strcmp (arg, "all-extensions") == 0
93440a403fSchristos       || strcmp (arg, "all") == 0)
94440a403fSchristos     {
95440a403fSchristos       memset (pdp11_extension, ~0, sizeof pdp11_extension);
96440a403fSchristos       pdp11_extension[PDP11_NONE] = 0;
97440a403fSchristos       return 1;
98440a403fSchristos     }
99440a403fSchristos   else if (strcmp (arg, "no-extensions") == 0)
100440a403fSchristos     {
101440a403fSchristos       memset (pdp11_extension, 0, sizeof pdp11_extension);
102440a403fSchristos       pdp11_extension[PDP11_BASIC] = 1;
103440a403fSchristos       return 1;
104440a403fSchristos     }
105440a403fSchristos 
106440a403fSchristos   if (strncmp (arg, "no-", 3) == 0)
107440a403fSchristos     {
108440a403fSchristos       yes = 0;
109440a403fSchristos       arg += 3;
110440a403fSchristos     }
111440a403fSchristos 
11206324dcfSchristos   /* Commercial instructions.  */
113440a403fSchristos   if (strcmp (arg, "cis") == 0)
114440a403fSchristos     pdp11_extension[PDP11_CIS] = yes;
115440a403fSchristos   /* Call supervisor mode.  */
116440a403fSchristos   else if (strcmp (arg, "csm") == 0)
117440a403fSchristos     pdp11_extension[PDP11_CSM] = yes;
118440a403fSchristos   /* Extended instruction set.  */
119440a403fSchristos   else if (strcmp (arg, "eis") == 0)
120440a403fSchristos     pdp11_extension[PDP11_EIS] = pdp11_extension[PDP11_LEIS] = yes;
121440a403fSchristos   /* KEV11 floating-point.  */
122440a403fSchristos   else if (strcmp (arg, "fis") == 0
123440a403fSchristos 	   || strcmp (arg, "kev11") == 0
124440a403fSchristos 	   || strcmp (arg, "kev-11") == 0)
125440a403fSchristos     pdp11_extension[PDP11_FIS] = yes;
126440a403fSchristos   /* FP-11 floating-point.  */
127440a403fSchristos   else if (strcmp (arg, "fpp") == 0
128440a403fSchristos 	   || strcmp (arg, "fpu") == 0
129440a403fSchristos 	   || strcmp (arg, "fp11") == 0
130440a403fSchristos 	   || strcmp (arg, "fp-11") == 0
131440a403fSchristos 	   || strcmp (arg, "fpj11") == 0
132440a403fSchristos 	   || strcmp (arg, "fp-j11") == 0
133440a403fSchristos 	   || strcmp (arg, "fpj-11") == 0)
134440a403fSchristos     pdp11_extension[PDP11_FPP] = yes;
135440a403fSchristos   /* Limited extended insns.  */
136440a403fSchristos   else if (strcmp (arg, "limited-eis") == 0)
137440a403fSchristos     {
138440a403fSchristos       pdp11_extension[PDP11_LEIS] = yes;
139440a403fSchristos       if (!pdp11_extension[PDP11_LEIS])
140440a403fSchristos 	pdp11_extension[PDP11_EIS] = 0;
141440a403fSchristos     }
142440a403fSchristos   /* Move from processor type.  */
143440a403fSchristos   else if (strcmp (arg, "mfpt") == 0)
144440a403fSchristos     pdp11_extension[PDP11_MFPT] = yes;
145440a403fSchristos   /* Multiprocessor insns:  */
146440a403fSchristos   else if (strncmp (arg, "mproc", 5) == 0
147440a403fSchristos 	   /* TSTSET, WRTLCK */
148440a403fSchristos 	   || strncmp (arg, "multiproc", 9) == 0)
149440a403fSchristos     pdp11_extension[PDP11_MPROC] = yes;
150440a403fSchristos   /* Move from/to proc status.  */
151440a403fSchristos   else if (strcmp (arg, "mxps") == 0)
152440a403fSchristos     pdp11_extension[PDP11_MXPS] = yes;
153440a403fSchristos   /* Position-independent code.  */
154440a403fSchristos   else if (strcmp (arg, "pic") == 0)
155440a403fSchristos     asm_option[ASM_OPT_PIC] = yes;
156440a403fSchristos   /* Set priority level.  */
157440a403fSchristos   else if (strcmp (arg, "spl") == 0)
158440a403fSchristos     pdp11_extension[PDP11_SPL] = yes;
159440a403fSchristos   /* Microcode instructions:  */
160440a403fSchristos   else if (strcmp (arg, "ucode") == 0
161440a403fSchristos 	   /* LDUB, MED, XFC */
162440a403fSchristos 	   || strcmp (arg, "microcode") == 0)
163440a403fSchristos     pdp11_extension[PDP11_UCODE] = yes;
164440a403fSchristos   else
165440a403fSchristos     return 0;
166440a403fSchristos 
167440a403fSchristos   return 1;
168440a403fSchristos }
169440a403fSchristos 
170440a403fSchristos 
171440a403fSchristos static void
init_defaults(void)172440a403fSchristos init_defaults (void)
173440a403fSchristos {
174440a403fSchristos   static int first = 1;
175440a403fSchristos 
176440a403fSchristos   if (first)
177440a403fSchristos     {
178440a403fSchristos       set_option ("all-extensions");
179440a403fSchristos       set_option ("pic");
180440a403fSchristos       first = 0;
181440a403fSchristos     }
182440a403fSchristos }
183440a403fSchristos 
184440a403fSchristos void
md_begin(void)185440a403fSchristos md_begin (void)
186440a403fSchristos {
187440a403fSchristos   int i;
188440a403fSchristos 
189440a403fSchristos   init_defaults ();
190440a403fSchristos 
191440a403fSchristos   insn_hash = hash_new ();
192440a403fSchristos   if (insn_hash == NULL)
193440a403fSchristos     as_fatal (_("Virtual memory exhausted"));
194440a403fSchristos 
195440a403fSchristos   for (i = 0; i < pdp11_num_opcodes; i++)
196440a403fSchristos     hash_insert (insn_hash, pdp11_opcodes[i].name, (void *) (pdp11_opcodes + i));
197440a403fSchristos   for (i = 0; i < pdp11_num_aliases; i++)
198440a403fSchristos     hash_insert (insn_hash, pdp11_aliases[i].name, (void *) (pdp11_aliases + i));
199440a403fSchristos }
200440a403fSchristos 
201440a403fSchristos void
md_number_to_chars(char con[],valueT value,int nbytes)202440a403fSchristos md_number_to_chars (char con[], valueT value, int nbytes)
203440a403fSchristos {
204440a403fSchristos   /* On a PDP-11, 0x1234 is stored as "\x12\x34", and
205440a403fSchristos      0x12345678 is stored as "\x56\x78\x12\x34". It's
20606324dcfSchristos      anyone's guess what 0x123456 would be stored like.  */
207440a403fSchristos 
208440a403fSchristos   switch (nbytes)
209440a403fSchristos     {
210440a403fSchristos     case 0:
211440a403fSchristos       break;
212440a403fSchristos     case 1:
213440a403fSchristos       con[0] =  value       & 0xff;
214440a403fSchristos       break;
215440a403fSchristos     case 2:
216440a403fSchristos       con[0] =  value        & 0xff;
217440a403fSchristos       con[1] = (value >>  8) & 0xff;
218440a403fSchristos       break;
219440a403fSchristos     case 4:
220440a403fSchristos       con[0] = (value >> 16) & 0xff;
221440a403fSchristos       con[1] = (value >> 24) & 0xff;
222440a403fSchristos       con[2] =  value        & 0xff;
223440a403fSchristos       con[3] = (value >>  8) & 0xff;
224440a403fSchristos       break;
225440a403fSchristos     default:
226440a403fSchristos       BAD_CASE (nbytes);
227440a403fSchristos     }
228440a403fSchristos }
229440a403fSchristos 
230440a403fSchristos /* Fix up some data or instructions after we find out the value of a symbol
231440a403fSchristos    that they reference.  Knows about order of bytes in address.  */
232440a403fSchristos 
233440a403fSchristos void
md_apply_fix(fixS * fixP,valueT * valP,segT seg ATTRIBUTE_UNUSED)234440a403fSchristos md_apply_fix (fixS *fixP,
235440a403fSchristos 	       valueT * valP,
236440a403fSchristos 	       segT seg ATTRIBUTE_UNUSED)
237440a403fSchristos {
238440a403fSchristos   valueT code;
239440a403fSchristos   valueT mask;
240440a403fSchristos   valueT val = * valP;
241440a403fSchristos   char *buf;
242440a403fSchristos   int shift;
243440a403fSchristos   int size;
244440a403fSchristos 
245440a403fSchristos   buf = fixP->fx_where + fixP->fx_frag->fr_literal;
246440a403fSchristos   size = fixP->fx_size;
247440a403fSchristos   code = md_chars_to_number ((unsigned char *) buf, size);
248440a403fSchristos 
249440a403fSchristos   switch (fixP->fx_r_type)
250440a403fSchristos     {
251*b88e3e88Schristos     case BFD_RELOC_8:
252*b88e3e88Schristos       mask = 0xff;
253*b88e3e88Schristos       shift = 0;
254*b88e3e88Schristos       break;
255440a403fSchristos     case BFD_RELOC_16:
256440a403fSchristos     case BFD_RELOC_16_PCREL:
257440a403fSchristos       mask = 0xffff;
258440a403fSchristos       shift = 0;
259440a403fSchristos       break;
260440a403fSchristos     case BFD_RELOC_PDP11_DISP_8_PCREL:
261440a403fSchristos       mask = 0x00ff;
262440a403fSchristos       shift = 1;
263440a403fSchristos       break;
264440a403fSchristos     case BFD_RELOC_PDP11_DISP_6_PCREL:
265440a403fSchristos       mask = 0x003f;
266440a403fSchristos       shift = 1;
267440a403fSchristos       val = -val;
268440a403fSchristos       break;
269440a403fSchristos     default:
270440a403fSchristos       BAD_CASE (fixP->fx_r_type);
271440a403fSchristos     }
272440a403fSchristos 
273440a403fSchristos   if (fixP->fx_addsy != NULL)
274440a403fSchristos     val += symbol_get_bfdsym (fixP->fx_addsy)->section->vma;
275440a403fSchristos     /* *value += fixP->fx_addsy->bsym->section->vma; */
276440a403fSchristos 
277440a403fSchristos   code &= ~mask;
278440a403fSchristos   code |= (val >> shift) & mask;
279440a403fSchristos   number_to_chars_littleendian (buf, code, size);
280440a403fSchristos 
281440a403fSchristos   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
282440a403fSchristos     fixP->fx_done = 1;
283440a403fSchristos }
284440a403fSchristos 
285440a403fSchristos long
md_chars_to_number(unsigned char * con,int nbytes)286440a403fSchristos md_chars_to_number (unsigned char *con, int nbytes)
287440a403fSchristos {
288440a403fSchristos   /* On a PDP-11, 0x1234 is stored as "\x12\x34", and
289440a403fSchristos      0x12345678 is stored as "\x56\x78\x12\x34". It's
29006324dcfSchristos      anyone's guess what 0x123456 would be stored like.  */
291440a403fSchristos   switch (nbytes)
292440a403fSchristos     {
293440a403fSchristos     case 0:
294440a403fSchristos       return 0;
295440a403fSchristos     case 1:
296440a403fSchristos       return con[0];
297440a403fSchristos     case 2:
298440a403fSchristos       return (con[1] << BITS_PER_CHAR) | con[0];
299440a403fSchristos     case 4:
300440a403fSchristos       return
301440a403fSchristos 	(((con[1] << BITS_PER_CHAR) | con[0]) << (2 * BITS_PER_CHAR))
302440a403fSchristos 	|((con[3] << BITS_PER_CHAR) | con[2]);
303440a403fSchristos     default:
304440a403fSchristos       BAD_CASE (nbytes);
305440a403fSchristos       return 0;
306440a403fSchristos     }
307440a403fSchristos }
308440a403fSchristos 
309440a403fSchristos static char *
skip_whitespace(char * str)310440a403fSchristos skip_whitespace (char *str)
311440a403fSchristos {
312440a403fSchristos   while (*str == ' ' || *str == '\t')
313440a403fSchristos     str++;
314440a403fSchristos   return str;
315440a403fSchristos }
316440a403fSchristos 
317440a403fSchristos static char *
find_whitespace(char * str)318440a403fSchristos find_whitespace (char *str)
319440a403fSchristos {
320440a403fSchristos   while (*str != ' ' && *str != '\t' && *str != 0)
321440a403fSchristos     str++;
322440a403fSchristos   return str;
323440a403fSchristos }
324440a403fSchristos 
325440a403fSchristos static char *
parse_reg(char * str,struct pdp11_code * operand)326440a403fSchristos parse_reg (char *str, struct pdp11_code *operand)
327440a403fSchristos {
328440a403fSchristos   str = skip_whitespace (str);
329440a403fSchristos   if (TOLOWER (*str) == 'r')
330440a403fSchristos     {
331440a403fSchristos       str++;
332440a403fSchristos       switch (*str)
333440a403fSchristos 	{
334440a403fSchristos 	case '0': case '1': case '2': case '3':
335440a403fSchristos 	case '4': case '5': case '6': case '7':
336440a403fSchristos 	  operand->code = *str - '0';
337440a403fSchristos 	  str++;
338440a403fSchristos 	  break;
339440a403fSchristos 	default:
340440a403fSchristos 	  operand->error = _("Bad register name");
341440a403fSchristos 	  return str - 1;
342440a403fSchristos 	}
343440a403fSchristos     }
344440a403fSchristos   else if (strncmp (str, "sp", 2) == 0
345440a403fSchristos 	   || strncmp (str, "SP", 2) == 0)
346440a403fSchristos     {
347440a403fSchristos       operand->code = 6;
348440a403fSchristos       str += 2;
349440a403fSchristos     }
350440a403fSchristos   else if (strncmp (str, "pc", 2) == 0
351440a403fSchristos 	   || strncmp (str, "PC", 2) == 0)
352440a403fSchristos     {
353440a403fSchristos       operand->code = 7;
354440a403fSchristos       str += 2;
355440a403fSchristos     }
356440a403fSchristos   else
357440a403fSchristos     operand->error = _("Bad register name");
358440a403fSchristos 
359440a403fSchristos   return str;
360440a403fSchristos }
361440a403fSchristos 
362440a403fSchristos static char *
parse_ac5(char * str,struct pdp11_code * operand)363440a403fSchristos parse_ac5 (char *str, struct pdp11_code *operand)
364440a403fSchristos {
365440a403fSchristos   str = skip_whitespace (str);
366440a403fSchristos   if (strncmp (str, "fr", 2) == 0
367440a403fSchristos       || strncmp (str, "FR", 2) == 0
368440a403fSchristos       || strncmp (str, "ac", 2) == 0
369440a403fSchristos       || strncmp (str, "AC", 2) == 0)
370440a403fSchristos     {
371440a403fSchristos       str += 2;
372440a403fSchristos       switch (*str)
373440a403fSchristos 	{
374440a403fSchristos 	case '0': case '1': case '2': case '3':
375440a403fSchristos         case '4': case '5':
376440a403fSchristos 	  operand->code = *str - '0';
377440a403fSchristos 	  str++;
378440a403fSchristos 	  break;
379440a403fSchristos 	default:
380440a403fSchristos 	  operand->error = _("Bad register name");
381440a403fSchristos 	  return str - 2;
382440a403fSchristos 	}
383440a403fSchristos     }
384440a403fSchristos   else
385440a403fSchristos     {
386440a403fSchristos       operand->error = _("Bad register name");
387440a403fSchristos       return str;
388440a403fSchristos     }
389440a403fSchristos 
390440a403fSchristos   return str;
391440a403fSchristos }
392440a403fSchristos 
393440a403fSchristos static char *
parse_ac(char * str,struct pdp11_code * operand)394440a403fSchristos parse_ac (char *str, struct pdp11_code *operand)
395440a403fSchristos {
396440a403fSchristos   str = parse_ac5 (str, operand);
397440a403fSchristos   if (!operand->error && operand->code > 3)
398440a403fSchristos     {
399440a403fSchristos       operand->error = _("Bad register name");
400440a403fSchristos 	  return str - 3;
401440a403fSchristos     }
402440a403fSchristos 
403440a403fSchristos   return str;
404440a403fSchristos }
405440a403fSchristos 
406440a403fSchristos static char *
parse_expression(char * str,struct pdp11_code * operand)407440a403fSchristos parse_expression (char *str, struct pdp11_code *operand)
408440a403fSchristos {
409440a403fSchristos   char *save_input_line_pointer;
410440a403fSchristos   segT seg;
411440a403fSchristos 
412440a403fSchristos   save_input_line_pointer = input_line_pointer;
413440a403fSchristos   input_line_pointer = str;
414440a403fSchristos   seg = expression (&operand->reloc.exp);
415440a403fSchristos   if (seg == NULL)
416440a403fSchristos     {
417440a403fSchristos       input_line_pointer = save_input_line_pointer;
418440a403fSchristos       operand->error = _("Error in expression");
419440a403fSchristos       return str;
420440a403fSchristos     }
421440a403fSchristos 
422440a403fSchristos   str = input_line_pointer;
423440a403fSchristos   input_line_pointer = save_input_line_pointer;
424440a403fSchristos 
425440a403fSchristos   operand->reloc.pc_rel = 0;
426440a403fSchristos 
427440a403fSchristos   return str;
428440a403fSchristos }
429440a403fSchristos 
430440a403fSchristos static char *
parse_op_no_deferred(char * str,struct pdp11_code * operand)431440a403fSchristos parse_op_no_deferred (char *str, struct pdp11_code *operand)
432440a403fSchristos {
433440a403fSchristos   LITTLENUM_TYPE literal_float[2];
434440a403fSchristos 
435440a403fSchristos   str = skip_whitespace (str);
436440a403fSchristos 
437440a403fSchristos   switch (*str)
438440a403fSchristos     {
439440a403fSchristos     case '(':				/* (rn) and (rn)+ */
440440a403fSchristos       str = parse_reg (str + 1, operand);
441440a403fSchristos       if (operand->error)
442440a403fSchristos 	return str;
443440a403fSchristos       str = skip_whitespace (str);
444440a403fSchristos       if (*str != ')')
445440a403fSchristos 	{
446440a403fSchristos 	  operand->error = _("Missing ')'");
447440a403fSchristos 	  return str;
448440a403fSchristos 	}
449440a403fSchristos       str++;
450440a403fSchristos       if (*str == '+')
451440a403fSchristos 	{
452440a403fSchristos 	  operand->code |= 020;
453440a403fSchristos 	  str++;
454440a403fSchristos 	}
455440a403fSchristos       else
456440a403fSchristos 	{
457440a403fSchristos 	  operand->code |= 010;
458440a403fSchristos 	}
459440a403fSchristos       break;
460440a403fSchristos 
461440a403fSchristos       /* Immediate.  */
462440a403fSchristos     case '#':
463440a403fSchristos     case '$':
464440a403fSchristos       str = parse_expression (str + 1, operand);
465440a403fSchristos       if (operand->error)
466440a403fSchristos 	return str;
467440a403fSchristos       operand->additional = TRUE;
468440a403fSchristos       operand->word = operand->reloc.exp.X_add_number;
469440a403fSchristos       switch (operand->reloc.exp.X_op)
470440a403fSchristos 	{
471440a403fSchristos 	case O_constant:
472440a403fSchristos 	  break;
473440a403fSchristos 	case O_symbol:
474440a403fSchristos 	case O_add:
475440a403fSchristos 	case O_subtract:
476440a403fSchristos 	  operand->reloc.type = BFD_RELOC_16;
477440a403fSchristos 	  operand->reloc.pc_rel = 0;
478440a403fSchristos 	  break;
479440a403fSchristos         case O_big:
480440a403fSchristos           if (operand->reloc.exp.X_add_number > 0)
481440a403fSchristos             {
482440a403fSchristos               operand->error = _("Error in expression");
483440a403fSchristos               break;
484440a403fSchristos             }
485440a403fSchristos           /* It's a floating literal...  */
486440a403fSchristos           know (operand->reloc.exp.X_add_number < 0);
487440a403fSchristos           flonum_gen2vax ('f', &generic_floating_point_number, literal_float);
488440a403fSchristos           operand->word = literal_float[0];
489440a403fSchristos           if (literal_float[1] != 0)
490440a403fSchristos             as_warn (_("Low order bits truncated in immediate float operand"));
491440a403fSchristos           break;
492440a403fSchristos 	default:
493440a403fSchristos 	  operand->error = _("Error in expression");
494440a403fSchristos 	  break;
495440a403fSchristos 	}
496440a403fSchristos       operand->code = 027;
497440a403fSchristos       break;
498440a403fSchristos 
499440a403fSchristos       /* label, d(rn), -(rn)  */
500440a403fSchristos     default:
501440a403fSchristos       {
502440a403fSchristos 	if (strncmp (str, "-(", 2) == 0)	/* -(rn) */
503440a403fSchristos 	  {
504440a403fSchristos 	    str = parse_reg (str + 2, operand);
505440a403fSchristos 	    if (operand->error)
506440a403fSchristos 	      return str;
507440a403fSchristos 	    str = skip_whitespace (str);
508440a403fSchristos 	    if (*str != ')')
509440a403fSchristos 	      {
510440a403fSchristos 		operand->error = _("Missing ')'");
511440a403fSchristos 		return str;
512440a403fSchristos 	      }
513440a403fSchristos 	    operand->code |= 040;
514440a403fSchristos 	    str++;
515440a403fSchristos 	    break;
516440a403fSchristos 	  }
517440a403fSchristos 
518440a403fSchristos 	str = parse_expression (str, operand);
519440a403fSchristos 	if (operand->error)
520440a403fSchristos 	  return str;
521440a403fSchristos 
522440a403fSchristos 	str = skip_whitespace (str);
523440a403fSchristos 
524440a403fSchristos 	if (*str != '(')
525440a403fSchristos 	  {
526440a403fSchristos 	    operand->code = 067;
527440a403fSchristos 	    operand->additional = 1;
528440a403fSchristos 	    operand->word = 0;
529440a403fSchristos 	    operand->reloc.type = BFD_RELOC_16_PCREL;
530440a403fSchristos 	    operand->reloc.pc_rel = 1;
531440a403fSchristos 	    break;
532440a403fSchristos 	  }
533440a403fSchristos 
534440a403fSchristos 	/* d(rn) */
535440a403fSchristos 	str++;
536440a403fSchristos 	str = parse_reg (str, operand);
537440a403fSchristos 	if (operand->error)
538440a403fSchristos 	  return str;
539440a403fSchristos 
540440a403fSchristos 	str = skip_whitespace (str);
541440a403fSchristos 
542440a403fSchristos 	if (*str != ')')
543440a403fSchristos 	  {
544440a403fSchristos 	    operand->error = _("Missing ')'");
545440a403fSchristos 	    return str;
546440a403fSchristos 	  }
547440a403fSchristos 
548440a403fSchristos 	str++;
549440a403fSchristos 	operand->additional = TRUE;
550440a403fSchristos 	operand->code |= 060;
551440a403fSchristos 	switch (operand->reloc.exp.X_op)
552440a403fSchristos 	  {
553440a403fSchristos 	  case O_symbol:
554440a403fSchristos 	    operand->reloc.type = BFD_RELOC_16;
555440a403fSchristos 	    operand->reloc.pc_rel = 0;
556440a403fSchristos 	    break;
557440a403fSchristos 	  case O_constant:
558440a403fSchristos 	    if ((operand->code & 7) == 7)
559440a403fSchristos 	      {
560440a403fSchristos 		operand->reloc.pc_rel = 1;
561440a403fSchristos 		operand->word = operand->reloc.exp.X_add_number;
562440a403fSchristos 	      }
563440a403fSchristos 	    else
564440a403fSchristos 	      operand->word = operand->reloc.exp.X_add_number;
565440a403fSchristos 
566440a403fSchristos 	    break;
567440a403fSchristos 	  default:
568440a403fSchristos 	    BAD_CASE (operand->reloc.exp.X_op);
569440a403fSchristos 	  }
570440a403fSchristos 	break;
571440a403fSchristos       }
572440a403fSchristos     }
573440a403fSchristos 
574440a403fSchristos   return str;
575440a403fSchristos }
576440a403fSchristos 
577440a403fSchristos static char *
parse_op_noreg(char * str,struct pdp11_code * operand)578440a403fSchristos parse_op_noreg (char *str, struct pdp11_code *operand)
579440a403fSchristos {
580440a403fSchristos   str = skip_whitespace (str);
581440a403fSchristos   operand->error = NULL;
582440a403fSchristos 
583440a403fSchristos   if (*str == '@' || *str == '*')
584440a403fSchristos     {
585*b88e3e88Schristos       /* @(Rn) == @0(Rn): Mode 7, Indexed deferred.
586*b88e3e88Schristos 	 Check for auto-increment deferred.  */
587*b88e3e88Schristos       if (str[1] == '('
588*b88e3e88Schristos 	  && str[2] != 0
589*b88e3e88Schristos 	  && str[3] != 0
590*b88e3e88Schristos 	  && str[4] != 0
591*b88e3e88Schristos 	  && str[5] != '+')
592*b88e3e88Schristos         {
593*b88e3e88Schristos 	  /* Change implied to explicit index deferred.  */
594*b88e3e88Schristos           *str = '0';
595*b88e3e88Schristos           str = parse_op_no_deferred (str, operand);
596*b88e3e88Schristos         }
597*b88e3e88Schristos       else
598*b88e3e88Schristos         {
599*b88e3e88Schristos           /* @Rn == (Rn): Register deferred.  */
600*b88e3e88Schristos           str = parse_reg (str + 1, operand);
601*b88e3e88Schristos 
602*b88e3e88Schristos           /* Not @Rn */
603*b88e3e88Schristos           if (operand->error)
604*b88e3e88Schristos 	    {
605*b88e3e88Schristos 	      operand->error = NULL;
606*b88e3e88Schristos 	      str = parse_op_no_deferred (str, operand);
607*b88e3e88Schristos 	    }
608*b88e3e88Schristos         }
609*b88e3e88Schristos 
610440a403fSchristos       if (operand->error)
611440a403fSchristos 	return str;
612*b88e3e88Schristos 
613440a403fSchristos       operand->code |= 010;
614440a403fSchristos     }
615440a403fSchristos   else
616440a403fSchristos     str = parse_op_no_deferred (str, operand);
617440a403fSchristos 
618440a403fSchristos   return str;
619440a403fSchristos }
620440a403fSchristos 
621440a403fSchristos static char *
parse_op(char * str,struct pdp11_code * operand)622440a403fSchristos parse_op (char *str, struct pdp11_code *operand)
623440a403fSchristos {
624440a403fSchristos   str = skip_whitespace (str);
625440a403fSchristos 
626440a403fSchristos   str = parse_reg (str, operand);
627440a403fSchristos   if (!operand->error)
628440a403fSchristos     return str;
629440a403fSchristos 
630440a403fSchristos   operand->error = NULL;
631440a403fSchristos   parse_ac5 (str, operand);
632440a403fSchristos   if (!operand->error)
633440a403fSchristos     {
634440a403fSchristos       operand->error = _("Float AC not legal as integer operand");
635440a403fSchristos       return str;
636440a403fSchristos     }
637440a403fSchristos 
638440a403fSchristos   return parse_op_noreg (str, operand);
639440a403fSchristos }
640440a403fSchristos 
641440a403fSchristos static char *
parse_fop(char * str,struct pdp11_code * operand)642440a403fSchristos parse_fop (char *str, struct pdp11_code *operand)
643440a403fSchristos {
644440a403fSchristos   str = skip_whitespace (str);
645440a403fSchristos 
646440a403fSchristos   str = parse_ac5 (str, operand);
647440a403fSchristos   if (!operand->error)
648440a403fSchristos     return str;
649440a403fSchristos 
650440a403fSchristos   operand->error = NULL;
651440a403fSchristos   parse_reg (str, operand);
652440a403fSchristos   if (!operand->error)
653440a403fSchristos     {
654440a403fSchristos       operand->error = _("General register not legal as float operand");
655440a403fSchristos       return str;
656440a403fSchristos     }
657440a403fSchristos 
658440a403fSchristos   return parse_op_noreg (str, operand);
659440a403fSchristos }
660440a403fSchristos 
661440a403fSchristos static char *
parse_separator(char * str,int * error)662440a403fSchristos parse_separator (char *str, int *error)
663440a403fSchristos {
664440a403fSchristos   str = skip_whitespace (str);
665440a403fSchristos   *error = (*str != ',');
666440a403fSchristos   if (!*error)
667440a403fSchristos     str++;
668440a403fSchristos   return str;
669440a403fSchristos }
670440a403fSchristos 
671440a403fSchristos void
md_assemble(char * instruction_string)672440a403fSchristos md_assemble (char *instruction_string)
673440a403fSchristos {
674440a403fSchristos   const struct pdp11_opcode *op;
675440a403fSchristos   struct pdp11_code insn, op1, op2;
676440a403fSchristos   int error;
677440a403fSchristos   int size;
678440a403fSchristos   const char *err = NULL;
679440a403fSchristos   char *str;
680440a403fSchristos   char *p;
681440a403fSchristos   char c;
682440a403fSchristos 
683440a403fSchristos   str = skip_whitespace (instruction_string);
684440a403fSchristos   p = find_whitespace (str);
685440a403fSchristos   if (p - str == 0)
686440a403fSchristos     {
687440a403fSchristos       as_bad (_("No instruction found"));
688440a403fSchristos       return;
689440a403fSchristos     }
690440a403fSchristos 
691440a403fSchristos   c = *p;
692440a403fSchristos   *p = '\0';
693440a403fSchristos   op = (struct pdp11_opcode *)hash_find (insn_hash, str);
694440a403fSchristos   *p = c;
695440a403fSchristos   if (op == 0)
696440a403fSchristos     {
697440a403fSchristos       as_bad (_("Unknown instruction '%s'"), str);
698440a403fSchristos       return;
699440a403fSchristos     }
700440a403fSchristos 
701440a403fSchristos   if (!pdp11_extension[op->extension])
702440a403fSchristos     {
703440a403fSchristos       as_warn (_("Unsupported instruction set extension: %s"), op->name);
704440a403fSchristos       return;
705440a403fSchristos     }
706440a403fSchristos 
707440a403fSchristos   insn.error = NULL;
708440a403fSchristos   insn.code = op->opcode;
709440a403fSchristos   insn.reloc.type = BFD_RELOC_NONE;
710440a403fSchristos   op1.error = NULL;
711440a403fSchristos   op1.additional = FALSE;
712440a403fSchristos   op1.reloc.type = BFD_RELOC_NONE;
713440a403fSchristos   op2.error = NULL;
714440a403fSchristos   op2.additional = FALSE;
715440a403fSchristos   op2.reloc.type = BFD_RELOC_NONE;
716440a403fSchristos 
717440a403fSchristos   str = p;
718440a403fSchristos   size = 2;
719440a403fSchristos 
720440a403fSchristos   switch (op->type)
721440a403fSchristos     {
722440a403fSchristos     case PDP11_OPCODE_NO_OPS:
723440a403fSchristos       str = skip_whitespace (str);
724440a403fSchristos       break;
725440a403fSchristos 
726440a403fSchristos     case PDP11_OPCODE_IMM3:
727440a403fSchristos     case PDP11_OPCODE_IMM6:
728440a403fSchristos     case PDP11_OPCODE_IMM8:
729440a403fSchristos       str = skip_whitespace (str);
730440a403fSchristos       if (*str == '#' || *str == '$')
731440a403fSchristos 	str++;
732440a403fSchristos       str = parse_expression (str, &op1);
733440a403fSchristos       if (op1.error)
734440a403fSchristos 	break;
735440a403fSchristos       if (op1.reloc.exp.X_op != O_constant || op1.reloc.type != BFD_RELOC_NONE)
736440a403fSchristos 	{
737440a403fSchristos 	  op1.error = _("operand is not an absolute constant");
738440a403fSchristos 	  break;
739440a403fSchristos 	}
740440a403fSchristos       switch (op->type)
741440a403fSchristos 	{
742440a403fSchristos 	case PDP11_OPCODE_IMM3:
743440a403fSchristos 	  if (op1.reloc.exp.X_add_number & ~7)
744440a403fSchristos 	    {
745440a403fSchristos 	      op1.error = _("3-bit immediate out of range");
746440a403fSchristos 	      break;
747440a403fSchristos 	    }
748440a403fSchristos 	  break;
749440a403fSchristos 	case PDP11_OPCODE_IMM6:
750440a403fSchristos 	  if (op1.reloc.exp.X_add_number & ~0x3f)
751440a403fSchristos 	    {
752440a403fSchristos 	      op1.error = _("6-bit immediate out of range");
753440a403fSchristos 	      break;
754440a403fSchristos 	    }
755440a403fSchristos 	  break;
756440a403fSchristos 	case PDP11_OPCODE_IMM8:
757440a403fSchristos 	  if (op1.reloc.exp.X_add_number & ~0xff)
758440a403fSchristos 	    {
759440a403fSchristos 	      op1.error = _("8-bit immediate out of range");
760440a403fSchristos 	      break;
761440a403fSchristos 	    }
762440a403fSchristos 	  break;
763440a403fSchristos 	}
764440a403fSchristos       insn.code |= op1.reloc.exp.X_add_number;
765440a403fSchristos       break;
766440a403fSchristos 
767440a403fSchristos     case PDP11_OPCODE_DISPL:
768440a403fSchristos       {
769440a403fSchristos 	char *new_pointer;
770440a403fSchristos 	new_pointer = parse_expression (str, &op1);
771440a403fSchristos 	op1.code = 0;
772440a403fSchristos 	op1.reloc.pc_rel = 1;
773440a403fSchristos 	op1.reloc.type = BFD_RELOC_PDP11_DISP_8_PCREL;
774440a403fSchristos 	if (op1.reloc.exp.X_op != O_symbol)
775440a403fSchristos 	  {
776440a403fSchristos 	    op1.error = _("Symbol expected");
777440a403fSchristos 	    break;
778440a403fSchristos 	  }
779440a403fSchristos 	if (op1.code & ~0xff)
780440a403fSchristos 	  {
781440a403fSchristos 	    err = _("8-bit displacement out of range");
782440a403fSchristos 	    break;
783440a403fSchristos 	  }
784440a403fSchristos 	str = new_pointer;
785440a403fSchristos 	insn.code |= op1.code;
786440a403fSchristos 	insn.reloc = op1.reloc;
787440a403fSchristos       }
788440a403fSchristos       break;
789440a403fSchristos 
790440a403fSchristos     case PDP11_OPCODE_REG:
791440a403fSchristos       str = parse_reg (str, &op1);
792440a403fSchristos       if (op1.error)
793440a403fSchristos 	break;
794440a403fSchristos       insn.code |= op1.code;
795440a403fSchristos       break;
796440a403fSchristos 
797440a403fSchristos     case PDP11_OPCODE_OP:
798440a403fSchristos       str = parse_op (str, &op1);
799440a403fSchristos       if (op1.error)
800440a403fSchristos 	break;
801440a403fSchristos       insn.code |= op1.code;
802440a403fSchristos       if (op1.additional)
803440a403fSchristos 	size += 2;
804440a403fSchristos       break;
805440a403fSchristos 
806440a403fSchristos     case PDP11_OPCODE_FOP:
807440a403fSchristos       str = parse_fop (str, &op1);
808440a403fSchristos       if (op1.error)
809440a403fSchristos 	break;
810440a403fSchristos       insn.code |= op1.code;
811440a403fSchristos       if (op1.additional)
812440a403fSchristos 	size += 2;
813440a403fSchristos       break;
814440a403fSchristos 
815440a403fSchristos     case PDP11_OPCODE_REG_OP:
816440a403fSchristos       str = parse_reg (str, &op2);
817440a403fSchristos       if (op2.error)
818440a403fSchristos 	break;
819440a403fSchristos       insn.code |= op2.code << 6;
820440a403fSchristos       str = parse_separator (str, &error);
821440a403fSchristos       if (error)
822440a403fSchristos 	{
823440a403fSchristos 	  op2.error = _("Missing ','");
824440a403fSchristos 	  break;
825440a403fSchristos 	}
826440a403fSchristos       str = parse_op (str, &op1);
827440a403fSchristos       if (op1.error)
828440a403fSchristos 	break;
829440a403fSchristos       insn.code |= op1.code;
830440a403fSchristos       if (op1.additional)
831440a403fSchristos 	size += 2;
832440a403fSchristos       break;
833440a403fSchristos 
834440a403fSchristos     case PDP11_OPCODE_REG_OP_REV:
835440a403fSchristos       str = parse_op (str, &op1);
836440a403fSchristos       if (op1.error)
837440a403fSchristos 	break;
838440a403fSchristos       insn.code |= op1.code;
839440a403fSchristos       if (op1.additional)
840440a403fSchristos 	size += 2;
841440a403fSchristos       str = parse_separator (str, &error);
842440a403fSchristos       if (error)
843440a403fSchristos 	{
844440a403fSchristos 	  op2.error = _("Missing ','");
845440a403fSchristos 	  break;
846440a403fSchristos 	}
847440a403fSchristos       str = parse_reg (str, &op2);
848440a403fSchristos       if (op2.error)
849440a403fSchristos 	break;
850440a403fSchristos       insn.code |= op2.code << 6;
851440a403fSchristos       break;
852440a403fSchristos 
853440a403fSchristos     case PDP11_OPCODE_AC_FOP:
854440a403fSchristos       str = parse_ac (str, &op2);
855440a403fSchristos       if (op2.error)
856440a403fSchristos 	break;
857440a403fSchristos       insn.code |= op2.code << 6;
858440a403fSchristos       str = parse_separator (str, &error);
859440a403fSchristos       if (error)
860440a403fSchristos 	{
861440a403fSchristos 	  op1.error = _("Missing ','");
862440a403fSchristos 	  break;
863440a403fSchristos 	}
864440a403fSchristos       str = parse_fop (str, &op1);
865440a403fSchristos       if (op1.error)
866440a403fSchristos 	break;
867440a403fSchristos       insn.code |= op1.code;
868440a403fSchristos       if (op1.additional)
869440a403fSchristos 	size += 2;
870440a403fSchristos       break;
871440a403fSchristos 
872440a403fSchristos     case PDP11_OPCODE_FOP_AC:
873440a403fSchristos       str = parse_fop (str, &op1);
874440a403fSchristos       if (op1.error)
875440a403fSchristos 	break;
876440a403fSchristos       insn.code |= op1.code;
877440a403fSchristos       if (op1.additional)
878440a403fSchristos 	size += 2;
879440a403fSchristos       str = parse_separator (str, &error);
880440a403fSchristos       if (error)
881440a403fSchristos 	{
882440a403fSchristos 	  op1.error = _("Missing ','");
883440a403fSchristos 	  break;
884440a403fSchristos 	}
885440a403fSchristos       str = parse_ac (str, &op2);
886440a403fSchristos       if (op2.error)
887440a403fSchristos 	break;
888440a403fSchristos       insn.code |= op2.code << 6;
889440a403fSchristos       break;
890440a403fSchristos 
891440a403fSchristos     case PDP11_OPCODE_AC_OP:
892440a403fSchristos       str = parse_ac (str, &op2);
893440a403fSchristos       if (op2.error)
894440a403fSchristos 	break;
895440a403fSchristos       insn.code |= op2.code << 6;
896440a403fSchristos       str = parse_separator (str, &error);
897440a403fSchristos       if (error)
898440a403fSchristos 	{
899440a403fSchristos 	  op1.error = _("Missing ','");
900440a403fSchristos 	  break;
901440a403fSchristos 	}
902440a403fSchristos       str = parse_op (str, &op1);
903440a403fSchristos       if (op1.error)
904440a403fSchristos 	break;
905440a403fSchristos       insn.code |= op1.code;
906440a403fSchristos       if (op1.additional)
907440a403fSchristos 	size += 2;
908440a403fSchristos       break;
909440a403fSchristos 
910440a403fSchristos     case PDP11_OPCODE_OP_AC:
911440a403fSchristos       str = parse_op (str, &op1);
912440a403fSchristos       if (op1.error)
913440a403fSchristos 	break;
914440a403fSchristos       insn.code |= op1.code;
915440a403fSchristos       if (op1.additional)
916440a403fSchristos 	size += 2;
917440a403fSchristos       str = parse_separator (str, &error);
918440a403fSchristos       if (error)
919440a403fSchristos 	{
920440a403fSchristos 	  op1.error = _("Missing ','");
921440a403fSchristos 	  break;
922440a403fSchristos 	}
923440a403fSchristos       str = parse_ac (str, &op2);
924440a403fSchristos       if (op2.error)
925440a403fSchristos 	break;
926440a403fSchristos       insn.code |= op2.code << 6;
927440a403fSchristos       break;
928440a403fSchristos 
929440a403fSchristos     case PDP11_OPCODE_OP_OP:
930440a403fSchristos       str = parse_op (str, &op1);
931440a403fSchristos       if (op1.error)
932440a403fSchristos 	break;
933440a403fSchristos       insn.code |= op1.code << 6;
934440a403fSchristos       if (op1.additional)
935440a403fSchristos 	size += 2;
936440a403fSchristos       str = parse_separator (str, &error);
937440a403fSchristos       if (error)
938440a403fSchristos 	{
939440a403fSchristos 	  op2.error = _("Missing ','");
940440a403fSchristos 	  break;
941440a403fSchristos 	}
942440a403fSchristos       str = parse_op (str, &op2);
943440a403fSchristos       if (op2.error)
944440a403fSchristos 	break;
945440a403fSchristos       insn.code |= op2.code;
946440a403fSchristos       if (op2.additional)
947440a403fSchristos 	size += 2;
948440a403fSchristos       break;
949440a403fSchristos 
950440a403fSchristos     case PDP11_OPCODE_REG_DISPL:
951440a403fSchristos       {
952440a403fSchristos 	char *new_pointer;
953440a403fSchristos 	str = parse_reg (str, &op2);
954440a403fSchristos 	if (op2.error)
955440a403fSchristos 	  break;
956440a403fSchristos 	insn.code |= op2.code << 6;
957440a403fSchristos 	str = parse_separator (str, &error);
958440a403fSchristos 	if (error)
959440a403fSchristos 	  {
960440a403fSchristos 	    op1.error = _("Missing ','");
961440a403fSchristos 	    break;
962440a403fSchristos 	  }
963440a403fSchristos 	new_pointer = parse_expression (str, &op1);
964440a403fSchristos 	op1.code = 0;
965440a403fSchristos 	op1.reloc.pc_rel = 1;
966440a403fSchristos 	op1.reloc.type = BFD_RELOC_PDP11_DISP_6_PCREL;
967440a403fSchristos 	if (op1.reloc.exp.X_op != O_symbol)
968440a403fSchristos 	  {
969440a403fSchristos 	    op1.error = _("Symbol expected");
970440a403fSchristos 	    break;
971440a403fSchristos 	  }
972440a403fSchristos 	if (op1.code & ~0x3f)
973440a403fSchristos 	  {
974440a403fSchristos 	    err = _("6-bit displacement out of range");
975440a403fSchristos 	    break;
976440a403fSchristos 	  }
977440a403fSchristos 	str = new_pointer;
978440a403fSchristos 	insn.code |= op1.code;
979440a403fSchristos 	insn.reloc = op1.reloc;
980440a403fSchristos       }
981440a403fSchristos       break;
982440a403fSchristos 
983440a403fSchristos     default:
984440a403fSchristos       BAD_CASE (op->type);
985440a403fSchristos     }
986440a403fSchristos 
987440a403fSchristos   if (op1.error)
988440a403fSchristos     err = op1.error;
989440a403fSchristos   else if (op2.error)
990440a403fSchristos     err = op2.error;
991440a403fSchristos   else
992440a403fSchristos     {
993440a403fSchristos       str = skip_whitespace (str);
994440a403fSchristos       if (*str)
995440a403fSchristos 	err = _("Too many operands");
996440a403fSchristos     }
997440a403fSchristos 
998440a403fSchristos   {
999440a403fSchristos     char *to = NULL;
1000440a403fSchristos 
1001440a403fSchristos     if (err)
1002440a403fSchristos       {
1003440a403fSchristos 	as_bad ("%s", err);
1004440a403fSchristos 	return;
1005440a403fSchristos       }
1006440a403fSchristos 
1007440a403fSchristos     to = frag_more (size);
1008440a403fSchristos 
1009440a403fSchristos     md_number_to_chars (to, insn.code, 2);
1010440a403fSchristos     if (insn.reloc.type != BFD_RELOC_NONE)
1011440a403fSchristos       fix_new_exp (frag_now, to - frag_now->fr_literal, 2,
1012440a403fSchristos 		   &insn.reloc.exp, insn.reloc.pc_rel, insn.reloc.type);
1013440a403fSchristos     to += 2;
1014440a403fSchristos 
1015440a403fSchristos     if (op1.additional)
1016440a403fSchristos       {
1017440a403fSchristos 	md_number_to_chars (to, op1.word, 2);
1018440a403fSchristos 	if (op1.reloc.type != BFD_RELOC_NONE)
1019440a403fSchristos 	  fix_new_exp (frag_now, to - frag_now->fr_literal, 2,
1020440a403fSchristos 		       &op1.reloc.exp, op1.reloc.pc_rel, op1.reloc.type);
1021440a403fSchristos 	to += 2;
1022440a403fSchristos       }
1023440a403fSchristos 
1024440a403fSchristos     if (op2.additional)
1025440a403fSchristos       {
1026440a403fSchristos 	md_number_to_chars (to, op2.word, 2);
1027440a403fSchristos 	if (op2.reloc.type != BFD_RELOC_NONE)
1028440a403fSchristos 	  fix_new_exp (frag_now, to - frag_now->fr_literal, 2,
1029440a403fSchristos 		       &op2.reloc.exp, op2.reloc.pc_rel, op2.reloc.type);
1030440a403fSchristos       }
1031440a403fSchristos   }
1032440a403fSchristos }
1033440a403fSchristos 
1034440a403fSchristos int
md_estimate_size_before_relax(fragS * fragP ATTRIBUTE_UNUSED,segT segment ATTRIBUTE_UNUSED)1035440a403fSchristos md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1036440a403fSchristos 			       segT segment ATTRIBUTE_UNUSED)
1037440a403fSchristos {
1038440a403fSchristos   return 0;
1039440a403fSchristos }
1040440a403fSchristos 
1041440a403fSchristos void
md_convert_frag(bfd * headers ATTRIBUTE_UNUSED,segT seg ATTRIBUTE_UNUSED,fragS * fragP ATTRIBUTE_UNUSED)1042440a403fSchristos md_convert_frag (bfd *headers ATTRIBUTE_UNUSED,
1043440a403fSchristos 		 segT seg ATTRIBUTE_UNUSED,
1044440a403fSchristos 		 fragS *fragP ATTRIBUTE_UNUSED)
1045440a403fSchristos {
1046440a403fSchristos }
1047440a403fSchristos 
1048440a403fSchristos int md_short_jump_size = 2;
1049440a403fSchristos int md_long_jump_size = 4;
1050440a403fSchristos 
1051440a403fSchristos void
md_create_short_jump(char * ptr ATTRIBUTE_UNUSED,addressT from_addr ATTRIBUTE_UNUSED,addressT to_addr ATTRIBUTE_UNUSED,fragS * frag ATTRIBUTE_UNUSED,symbolS * to_symbol ATTRIBUTE_UNUSED)1052440a403fSchristos md_create_short_jump (char *ptr ATTRIBUTE_UNUSED,
1053440a403fSchristos 		      addressT from_addr ATTRIBUTE_UNUSED,
1054440a403fSchristos 		      addressT to_addr ATTRIBUTE_UNUSED,
1055440a403fSchristos 		      fragS *frag ATTRIBUTE_UNUSED,
1056440a403fSchristos 		      symbolS *to_symbol ATTRIBUTE_UNUSED)
1057440a403fSchristos {
1058440a403fSchristos }
1059440a403fSchristos 
1060440a403fSchristos void
md_create_long_jump(char * ptr ATTRIBUTE_UNUSED,addressT from_addr ATTRIBUTE_UNUSED,addressT to_addr ATTRIBUTE_UNUSED,fragS * frag ATTRIBUTE_UNUSED,symbolS * to_symbol ATTRIBUTE_UNUSED)1061440a403fSchristos md_create_long_jump (char *ptr ATTRIBUTE_UNUSED,
1062440a403fSchristos 		     addressT from_addr ATTRIBUTE_UNUSED,
1063440a403fSchristos 		     addressT to_addr ATTRIBUTE_UNUSED,
1064440a403fSchristos 		     fragS *frag ATTRIBUTE_UNUSED,
1065440a403fSchristos 		     symbolS *to_symbol ATTRIBUTE_UNUSED)
1066440a403fSchristos {
1067440a403fSchristos }
1068440a403fSchristos 
1069440a403fSchristos static int
set_cpu_model(const char * arg)1070440a403fSchristos set_cpu_model (const char *arg)
1071440a403fSchristos {
1072440a403fSchristos   char buf[4];
1073440a403fSchristos   char *model = buf;
1074440a403fSchristos 
1075440a403fSchristos   if (arg[0] == 'k')
1076440a403fSchristos     arg++;
1077440a403fSchristos 
1078440a403fSchristos   *model++ = *arg++;
1079440a403fSchristos 
1080440a403fSchristos   if (strchr ("abdx", model[-1]) == NULL)
1081440a403fSchristos     return 0;
1082440a403fSchristos 
1083440a403fSchristos   if (model[-1] == 'd')
1084440a403fSchristos     {
1085440a403fSchristos       if (arg[0] == 'f' || arg[0] == 'j')
1086440a403fSchristos 	model[-1] = *arg++;
1087440a403fSchristos     }
1088440a403fSchristos   else if (model[-1] == 'x')
1089440a403fSchristos     {
1090440a403fSchristos       if (arg[0] == 't')
1091440a403fSchristos 	model[-1] = *arg++;
1092440a403fSchristos     }
1093440a403fSchristos 
1094440a403fSchristos   if (arg[0] == '-')
1095440a403fSchristos     arg++;
1096440a403fSchristos 
1097440a403fSchristos   if (strncmp (arg, "11", 2) != 0)
1098440a403fSchristos     return 0;
1099440a403fSchristos   arg += 2;
1100440a403fSchristos 
1101440a403fSchristos   if (arg[0] == '-')
1102440a403fSchristos     {
1103440a403fSchristos       if (*++arg == 0)
1104440a403fSchristos 	return 0;
1105440a403fSchristos     }
1106440a403fSchristos 
1107440a403fSchristos   /* Allow up to two revision letters.  */
1108440a403fSchristos   if (arg[0] != 0)
1109440a403fSchristos     *model++ = *arg++;
1110440a403fSchristos   if (arg[0] != 0)
1111440a403fSchristos     *model++ = *arg++;
1112440a403fSchristos 
1113440a403fSchristos   *model++ = 0;
1114440a403fSchristos 
1115440a403fSchristos   set_option ("no-extensions");
1116440a403fSchristos 
1117440a403fSchristos   /* KA11 (11/15/20).  */
1118440a403fSchristos   if (strncmp (buf, "a", 1) == 0)
1119440a403fSchristos     return 1; /* No extensions.  */
1120440a403fSchristos 
1121440a403fSchristos   /* KB11 (11/45/50/55/70).  */
1122440a403fSchristos   else if (strncmp (buf, "b", 1) == 0)
1123440a403fSchristos     return set_option ("eis") && set_option ("spl");
1124440a403fSchristos 
1125440a403fSchristos   /* KD11-A (11/35/40).  */
1126440a403fSchristos   else if (strncmp (buf, "da", 2) == 0)
1127440a403fSchristos     return set_option ("limited-eis");
1128440a403fSchristos 
1129440a403fSchristos   /* KD11-B (11/05/10).  */
1130440a403fSchristos   else if (strncmp (buf, "db", 2) == 0
1131440a403fSchristos 	   /* KD11-D (11/04).  */
1132440a403fSchristos 	   || strncmp (buf, "dd", 2) == 0)
1133440a403fSchristos     return 1; /* no extensions */
1134440a403fSchristos 
1135440a403fSchristos   /* KD11-E (11/34).  */
1136440a403fSchristos   else if (strncmp (buf, "de", 2) == 0)
1137440a403fSchristos     return set_option ("eis") && set_option ("mxps");
1138440a403fSchristos 
1139440a403fSchristos   /* KD11-F (11/03).  */
1140440a403fSchristos   else if (strncmp (buf, "df", 2) == 0
1141440a403fSchristos 	   /* KD11-H (11/03).  */
1142440a403fSchristos 	   || strncmp (buf, "dh", 2) == 0
1143440a403fSchristos 	   /* KD11-Q (11/03).  */
1144440a403fSchristos 	   || strncmp (buf, "dq", 2) == 0)
1145440a403fSchristos     return set_option ("limited-eis") && set_option ("mxps");
1146440a403fSchristos 
1147440a403fSchristos   /* KD11-K (11/60).  */
1148440a403fSchristos   else if (strncmp (buf, "dk", 2) == 0)
1149440a403fSchristos     return set_option ("eis")
1150440a403fSchristos       && set_option ("mxps")
1151440a403fSchristos       && set_option ("ucode");
1152440a403fSchristos 
1153440a403fSchristos   /* KD11-Z (11/44).  */
1154440a403fSchristos   else if (strncmp (buf, "dz", 2) == 0)
1155440a403fSchristos     return set_option ("csm")
1156440a403fSchristos       && set_option ("eis")
1157440a403fSchristos       && set_option ("mfpt")
1158440a403fSchristos       && set_option ("mxps")
1159440a403fSchristos       && set_option ("spl");
1160440a403fSchristos 
1161440a403fSchristos   /* F11 (11/23/24).  */
1162440a403fSchristos   else if (strncmp (buf, "f", 1) == 0)
1163440a403fSchristos     return set_option ("eis")
1164440a403fSchristos       && set_option ("mfpt")
1165440a403fSchristos       && set_option ("mxps");
1166440a403fSchristos 
1167440a403fSchristos   /* J11 (11/53/73/83/84/93/94).  */
1168440a403fSchristos   else if (strncmp (buf, "j", 1) == 0)
1169440a403fSchristos     return set_option ("csm")
1170440a403fSchristos       && set_option ("eis")
1171440a403fSchristos       && set_option ("mfpt")
1172440a403fSchristos       && set_option ("multiproc")
1173440a403fSchristos       && set_option ("mxps")
1174440a403fSchristos       && set_option ("spl");
1175440a403fSchristos 
1176440a403fSchristos   /* T11 (11/21).  */
1177440a403fSchristos   else if (strncmp (buf, "t", 1) == 0)
1178440a403fSchristos     return set_option ("limited-eis")
1179440a403fSchristos       && set_option ("mxps");
1180440a403fSchristos 
1181440a403fSchristos   else
1182440a403fSchristos     return 0;
1183440a403fSchristos }
1184440a403fSchristos 
1185440a403fSchristos static int
set_machine_model(const char * arg)1186440a403fSchristos set_machine_model (const char *arg)
1187440a403fSchristos {
1188440a403fSchristos   if (strncmp (arg, "pdp-11/", 7) != 0
1189440a403fSchristos       && strncmp (arg, "pdp11/", 6) != 0
1190440a403fSchristos       && strncmp (arg, "11/", 3) != 0)
1191440a403fSchristos     return 0;
1192440a403fSchristos 
1193440a403fSchristos   if (strncmp (arg, "pdp", 3) == 0)
1194440a403fSchristos     arg += 3;
1195440a403fSchristos   if (arg[0] == '-')
1196440a403fSchristos     arg++;
1197440a403fSchristos   if (strncmp (arg, "11/", 3) == 0)
1198440a403fSchristos     arg += 3;
1199440a403fSchristos 
1200440a403fSchristos   if (strcmp (arg, "03") == 0)
1201440a403fSchristos     return set_cpu_model ("kd11f");
1202440a403fSchristos 
1203440a403fSchristos   else if (strcmp (arg, "04") == 0)
1204440a403fSchristos     return set_cpu_model ("kd11d");
1205440a403fSchristos 
1206440a403fSchristos   else if (strcmp (arg, "05") == 0
1207440a403fSchristos 	   || strcmp (arg, "10") == 0)
1208440a403fSchristos     return set_cpu_model ("kd11b");
1209440a403fSchristos 
1210440a403fSchristos   else if (strcmp (arg, "15") == 0
1211440a403fSchristos 	   || strcmp (arg, "20") == 0)
1212440a403fSchristos     return set_cpu_model ("ka11");
1213440a403fSchristos 
1214440a403fSchristos   else if (strcmp (arg, "21") == 0)
1215440a403fSchristos     return set_cpu_model ("t11");
1216440a403fSchristos 
1217440a403fSchristos   else if (strcmp (arg, "23") == 0
1218440a403fSchristos 	   || strcmp (arg, "24") == 0)
1219440a403fSchristos     return set_cpu_model ("f11");
1220440a403fSchristos 
1221440a403fSchristos   else if (strcmp (arg, "34") == 0
1222440a403fSchristos 	   || strcmp (arg, "34a") == 0)
1223440a403fSchristos     return set_cpu_model ("kd11e");
1224440a403fSchristos 
1225440a403fSchristos   else if (strcmp (arg, "35") == 0
1226440a403fSchristos 	   || strcmp (arg, "40") == 0)
1227440a403fSchristos     return set_cpu_model ("kd11da");
1228440a403fSchristos 
1229440a403fSchristos   else if (strcmp (arg, "44") == 0)
1230440a403fSchristos     return set_cpu_model ("kd11dz");
1231440a403fSchristos 
1232440a403fSchristos   else if (strcmp (arg, "45") == 0
1233440a403fSchristos 	   || strcmp (arg, "50") == 0
1234440a403fSchristos 	   || strcmp (arg, "55") == 0
1235440a403fSchristos 	   || strcmp (arg, "70") == 0)
1236440a403fSchristos     return set_cpu_model ("kb11");
1237440a403fSchristos 
1238440a403fSchristos   else if (strcmp (arg, "60") == 0)
1239440a403fSchristos     return set_cpu_model ("kd11k");
1240440a403fSchristos 
1241440a403fSchristos   else if (strcmp (arg, "53") == 0
1242440a403fSchristos 	   || strcmp (arg, "73") == 0
1243440a403fSchristos 	   || strcmp (arg, "83") == 0
1244440a403fSchristos 	   || strcmp (arg, "84") == 0
1245440a403fSchristos 	   || strcmp (arg, "93") == 0
1246440a403fSchristos 	   || strcmp (arg, "94") == 0)
1247440a403fSchristos     return set_cpu_model ("j11")
1248440a403fSchristos       && set_option ("fpp");
1249440a403fSchristos 
1250440a403fSchristos   else
1251440a403fSchristos     return 0;
1252440a403fSchristos }
1253440a403fSchristos 
1254440a403fSchristos const char *md_shortopts = "m:";
1255440a403fSchristos 
1256440a403fSchristos struct option md_longopts[] =
1257440a403fSchristos {
1258440a403fSchristos #define OPTION_CPU 257
1259440a403fSchristos   { "cpu", required_argument, NULL, OPTION_CPU },
1260440a403fSchristos #define OPTION_MACHINE 258
1261440a403fSchristos   { "machine", required_argument, NULL, OPTION_MACHINE },
1262440a403fSchristos #define OPTION_PIC 259
1263440a403fSchristos   { "pic", no_argument, NULL, OPTION_PIC },
1264440a403fSchristos   { NULL, no_argument, NULL, 0 }
1265440a403fSchristos };
1266440a403fSchristos 
1267440a403fSchristos size_t md_longopts_size = sizeof (md_longopts);
1268440a403fSchristos 
1269440a403fSchristos /* Invocation line includes a switch not recognized by the base assembler.
1270440a403fSchristos    See if it's a processor-specific option.  */
1271440a403fSchristos 
1272440a403fSchristos int
md_parse_option(int c,const char * arg)1273440a403fSchristos md_parse_option (int c, const char *arg)
1274440a403fSchristos {
1275440a403fSchristos   init_defaults ();
1276440a403fSchristos 
1277440a403fSchristos   switch (c)
1278440a403fSchristos     {
1279440a403fSchristos     case 'm':
1280440a403fSchristos       if (set_option (arg))
1281440a403fSchristos 	return 1;
1282440a403fSchristos       if (set_cpu_model (arg))
1283440a403fSchristos 	return 1;
1284440a403fSchristos       if (set_machine_model (arg))
1285440a403fSchristos 	return 1;
1286440a403fSchristos       break;
1287440a403fSchristos 
1288440a403fSchristos     case OPTION_CPU:
1289440a403fSchristos       if (set_cpu_model (arg))
1290440a403fSchristos 	return 1;
1291440a403fSchristos       break;
1292440a403fSchristos 
1293440a403fSchristos     case OPTION_MACHINE:
1294440a403fSchristos       if (set_machine_model (arg))
1295440a403fSchristos 	return 1;
1296440a403fSchristos       break;
1297440a403fSchristos 
1298440a403fSchristos     case OPTION_PIC:
1299440a403fSchristos       if (set_option ("pic"))
1300440a403fSchristos 	return 1;
1301440a403fSchristos       break;
1302440a403fSchristos 
1303440a403fSchristos     default:
1304440a403fSchristos       break;
1305440a403fSchristos     }
1306440a403fSchristos 
1307440a403fSchristos   return 0;
1308440a403fSchristos }
1309440a403fSchristos 
1310440a403fSchristos void
md_show_usage(FILE * stream)1311440a403fSchristos md_show_usage (FILE *stream)
1312440a403fSchristos {
1313440a403fSchristos   fprintf (stream, "\
1314440a403fSchristos \n\
131506324dcfSchristos PDP-11 instruction set extensions:\n\
1316440a403fSchristos \n\
131706324dcfSchristos -m(no-)cis		allow (disallow) commercial instruction set\n\
1318440a403fSchristos -m(no-)csm		allow (disallow) CSM instruction\n\
1319440a403fSchristos -m(no-)eis		allow (disallow) full extended instruction set\n\
1320440a403fSchristos -m(no-)fis		allow (disallow) KEV11 floating-point instructions\n\
1321440a403fSchristos -m(no-)fpp		allow (disallow) FP-11 floating-point instructions\n\
1322440a403fSchristos -m(no-)fpu		allow (disallow) FP-11 floating-point instructions\n\
1323440a403fSchristos -m(no-)limited-eis	allow (disallow) limited extended instruction set\n\
1324440a403fSchristos -m(no-)mfpt		allow (disallow) processor type instruction\n\
1325440a403fSchristos -m(no-)multiproc	allow (disallow) multiprocessor instructions\n\
1326440a403fSchristos -m(no-)mxps		allow (disallow) processor status instructions\n\
1327440a403fSchristos -m(no-)spl		allow (disallow) SPL instruction\n\
1328440a403fSchristos -m(no-)ucode		allow (disallow) microcode instructions\n\
1329440a403fSchristos -mall-extensions	allow all instruction set extensions\n\
1330440a403fSchristos 			(this is the default)\n\
133106324dcfSchristos -mno-extensions		disallow all instruction set extensions\n\
133206324dcfSchristos -pic			generate position-independent code\n\
1333440a403fSchristos \n\
1334440a403fSchristos PDP-11 CPU model options:\n\
1335440a403fSchristos \n\
1336440a403fSchristos -mka11*			KA11 CPU.  base line instruction set only\n\
1337440a403fSchristos -mkb11*			KB11 CPU.  enable full EIS and SPL\n\
1338440a403fSchristos -mkd11a*		KD11-A CPU.  enable limited EIS\n\
1339440a403fSchristos -mkd11b*		KD11-B CPU.  base line instruction set only\n\
1340440a403fSchristos -mkd11d*		KD11-D CPU.  base line instruction set only\n\
1341440a403fSchristos -mkd11e*		KD11-E CPU.  enable full EIS, MTPS, and MFPS\n\
1342440a403fSchristos -mkd11f*		KD11-F CPU.  enable limited EIS, MTPS, and MFPS\n\
1343440a403fSchristos -mkd11h*		KD11-H CPU.  enable limited EIS, MTPS, and MFPS\n\
1344440a403fSchristos -mkd11q*		KD11-Q CPU.  enable limited EIS, MTPS, and MFPS\n\
1345440a403fSchristos -mkd11k*		KD11-K CPU.  enable full EIS, MTPS, MFPS, LDUB, MED,\n\
1346440a403fSchristos 			XFC, and MFPT\n\
1347440a403fSchristos -mkd11z*		KD11-Z CPU.  enable full EIS, MTPS, MFPS, MFPT, SPL,\n\
1348440a403fSchristos 			and CSM\n\
1349440a403fSchristos -mf11*			F11 CPU.  enable full EIS, MFPS, MTPS, and MFPT\n\
1350440a403fSchristos -mj11*			J11 CPU.  enable full EIS, MTPS, MFPS, MFPT, SPL,\n\
1351440a403fSchristos 			CSM, TSTSET, and WRTLCK\n\
1352440a403fSchristos -mt11*			T11 CPU.  enable limited EIS, MTPS, and MFPS\n\
1353440a403fSchristos \n\
1354440a403fSchristos PDP-11 machine model options:\n\
1355440a403fSchristos \n\
1356440a403fSchristos -m11/03			same as -mkd11f\n\
1357440a403fSchristos -m11/04			same as -mkd11d\n\
1358440a403fSchristos -m11/05			same as -mkd11b\n\
1359440a403fSchristos -m11/10			same as -mkd11b\n\
1360440a403fSchristos -m11/15			same as -mka11\n\
1361440a403fSchristos -m11/20			same as -mka11\n\
1362440a403fSchristos -m11/21			same as -mt11\n\
1363440a403fSchristos -m11/23			same as -mf11\n\
1364440a403fSchristos -m11/24			same as -mf11\n\
1365440a403fSchristos -m11/34			same as -mkd11e\n\
1366440a403fSchristos -m11/34a		same as -mkd11e -mfpp\n\
1367440a403fSchristos -m11/35			same as -mkd11a\n\
1368440a403fSchristos -m11/40			same as -mkd11a\n\
1369440a403fSchristos -m11/44			same as -mkd11z\n\
1370440a403fSchristos -m11/45			same as -mkb11\n\
1371440a403fSchristos -m11/50			same as -mkb11\n\
1372440a403fSchristos -m11/53			same as -mj11\n\
1373440a403fSchristos -m11/55			same as -mkb11\n\
1374440a403fSchristos -m11/60			same as -mkd11k\n\
1375440a403fSchristos -m11/70			same as -mkb11\n\
1376440a403fSchristos -m11/73			same as -mj11\n\
1377440a403fSchristos -m11/83			same as -mj11\n\
1378440a403fSchristos -m11/84			same as -mj11\n\
1379440a403fSchristos -m11/93			same as -mj11\n\
1380440a403fSchristos -m11/94			same as -mj11\n\
1381440a403fSchristos ");
1382440a403fSchristos }
1383440a403fSchristos 
1384440a403fSchristos symbolS *
md_undefined_symbol(char * name ATTRIBUTE_UNUSED)1385440a403fSchristos md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1386440a403fSchristos {
1387440a403fSchristos   return 0;
1388440a403fSchristos }
1389440a403fSchristos 
1390440a403fSchristos valueT
md_section_align(segT segment ATTRIBUTE_UNUSED,valueT size)1391440a403fSchristos md_section_align (segT segment ATTRIBUTE_UNUSED,
1392440a403fSchristos 		  valueT size)
1393440a403fSchristos {
1394440a403fSchristos   return (size + 1) & ~1;
1395440a403fSchristos }
1396440a403fSchristos 
1397440a403fSchristos long
md_pcrel_from(fixS * fixP)1398440a403fSchristos md_pcrel_from (fixS *fixP)
1399440a403fSchristos {
1400440a403fSchristos   return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1401440a403fSchristos }
1402440a403fSchristos 
1403440a403fSchristos /* Translate internal representation of relocation info to BFD target
1404440a403fSchristos    format.  */
1405440a403fSchristos 
1406440a403fSchristos arelent *
tc_gen_reloc(asection * section ATTRIBUTE_UNUSED,fixS * fixp)1407440a403fSchristos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1408440a403fSchristos 	      fixS *fixp)
1409440a403fSchristos {
1410440a403fSchristos   arelent *reloc;
1411440a403fSchristos   bfd_reloc_code_real_type code;
1412440a403fSchristos 
1413440a403fSchristos   reloc = XNEW (arelent);
1414440a403fSchristos 
1415440a403fSchristos   reloc->sym_ptr_ptr = XNEW (asymbol *);
1416440a403fSchristos   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1417440a403fSchristos   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1418440a403fSchristos 
1419440a403fSchristos   /* This is taken account for in md_apply_fix().  */
1420440a403fSchristos   reloc->addend = -symbol_get_bfdsym (fixp->fx_addsy)->section->vma;
1421440a403fSchristos 
1422440a403fSchristos   switch (fixp->fx_r_type)
1423440a403fSchristos     {
1424440a403fSchristos     case BFD_RELOC_16:
1425440a403fSchristos       if (fixp->fx_pcrel)
1426440a403fSchristos 	code = BFD_RELOC_16_PCREL;
1427440a403fSchristos       else
1428440a403fSchristos 	code = BFD_RELOC_16;
1429440a403fSchristos       break;
1430440a403fSchristos 
1431440a403fSchristos     case BFD_RELOC_16_PCREL:
1432440a403fSchristos       code = BFD_RELOC_16_PCREL;
1433440a403fSchristos       break;
1434440a403fSchristos 
1435440a403fSchristos     default:
1436440a403fSchristos       BAD_CASE (fixp->fx_r_type);
1437440a403fSchristos       return NULL;
1438440a403fSchristos     }
1439440a403fSchristos 
1440440a403fSchristos   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
1441440a403fSchristos 
1442440a403fSchristos   if (reloc->howto == NULL)
1443440a403fSchristos     {
1444440a403fSchristos       as_bad_where (fixp->fx_file, fixp->fx_line,
1445440a403fSchristos 		    _("Can not represent %s relocation in this object file format"),
1446440a403fSchristos 		    bfd_get_reloc_code_name (code));
1447440a403fSchristos       return NULL;
1448440a403fSchristos     }
1449440a403fSchristos 
1450440a403fSchristos   return reloc;
1451440a403fSchristos }
1452440a403fSchristos 
1453440a403fSchristos void
pseudo_bss(int c ATTRIBUTE_UNUSED)1454440a403fSchristos pseudo_bss (int c ATTRIBUTE_UNUSED)
1455440a403fSchristos {
1456440a403fSchristos   int temp;
1457440a403fSchristos 
1458440a403fSchristos   temp = get_absolute_expression ();
1459440a403fSchristos   subseg_set (bss_section, temp);
1460440a403fSchristos   demand_empty_rest_of_line ();
1461440a403fSchristos }
1462440a403fSchristos 
1463440a403fSchristos void
pseudo_even(int c ATTRIBUTE_UNUSED)1464440a403fSchristos pseudo_even (int c ATTRIBUTE_UNUSED)
1465440a403fSchristos {
1466440a403fSchristos   int alignment = 1; /* 2^1 */
1467440a403fSchristos   frag_align (alignment, 0, 1);
1468440a403fSchristos   record_alignment (now_seg, alignment);
1469440a403fSchristos }
1470440a403fSchristos 
1471440a403fSchristos const char *
md_atof(int type,char * litP,int * sizeP)1472440a403fSchristos md_atof (int type, char * litP, int * sizeP)
1473440a403fSchristos {
1474440a403fSchristos   return vax_md_atof (type, litP, sizeP);
1475440a403fSchristos }
1476