tc-ns32k.c revision 1.2
1/* ns32k.c  -- Assemble on the National Semiconductor 32k series
2   Copyright (C) 1987, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
3
4   This file is part of GAS, the GNU Assembler.
5
6   GAS is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   GAS is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with GAS; see the file COPYING.  If not, write to
18   the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20/*#define SHOW_NUM 1*//* uncomment for debugging */
21
22#include <stdio.h>
23#include <ctype.h>
24
25#include "as.h"
26#include "opcode/ns32k.h"
27
28#include "obstack.h"
29
30/* Macros */
31#define IIF_ENTRIES 13		/* number of entries in iif */
32#define PRIVATE_SIZE 256	/* size of my garbage memory */
33#define MAX_ARGS 4
34#define DEFAULT	-1		/* addr_mode returns this value when plain constant or label is encountered */
35
36#define IIF(ptr,a1,c1,e1,g1,i1,k1,m1,o1,q1,s1,u1) \
37    iif.iifP[ptr].type= a1; \
38    iif.iifP[ptr].size= c1; \
39    iif.iifP[ptr].object= e1; \
40    iif.iifP[ptr].object_adjust= g1; \
41    iif.iifP[ptr].pcrel= i1; \
42    iif.iifP[ptr].pcrel_adjust= k1; \
43    iif.iifP[ptr].im_disp= m1; \
44    iif.iifP[ptr].relax_substate= o1; \
45    iif.iifP[ptr].bit_fixP= q1; \
46    iif.iifP[ptr].addr_mode= s1; \
47    iif.iifP[ptr].bsr= u1;
48
49#ifdef SEQUENT_COMPATABILITY
50#define LINE_COMMENT_CHARS "|"
51#define ABSOLUTE_PREFIX '@'
52#define IMMEDIATE_PREFIX '#'
53#endif
54
55#ifndef LINE_COMMENT_CHARS
56#define LINE_COMMENT_CHARS "#"
57#endif
58
59const char comment_chars[] = "#";
60const char line_comment_chars[] = LINE_COMMENT_CHARS;
61const char line_separator_chars[] = "";
62#if !defined(ABSOLUTE_PREFIX) && !defined(IMMEDIATE_PREFIX)
63#define ABSOLUTE_PREFIX '@'	/* One or the other MUST be defined */
64#endif
65
66struct addr_mode
67  {
68    char mode;			/* addressing mode of operand (0-31) */
69    char scaled_mode;		/* mode combined with scaled mode */
70    char scaled_reg;		/* register used in scaled+1 (1-8) */
71    char float_flag;		/* set if R0..R7 was F0..F7 ie a floating-point-register */
72    char am_size;		/* estimated max size of general addr-mode parts*/
73    char im_disp;		/* if im_disp==1 we have a displacement */
74    char pcrel;			/* 1 if pcrel, this is really redundant info */
75    char disp_suffix[2];	/* length of displacement(s), 0=undefined */
76    char *disp[2];		/* pointer(s) at displacement(s)
77				   or immediates(s)     (ascii) */
78    char index_byte;		/* index byte */
79  };
80typedef struct addr_mode addr_modeS;
81
82
83char *freeptr, *freeptr_static;	/* points at some number of free bytes */
84struct hash_control *inst_hash_handle;
85
86struct ns32k_opcode *desc;	/* pointer at description of instruction */
87addr_modeS addr_modeP;
88const char EXP_CHARS[] = "eE";
89const char FLT_CHARS[] = "fd";	/* we don't want to support lowercase, do we */
90
91/* UPPERCASE denotes live names
92 * when an instruction is built, IIF is used as an intermidiate form to store
93 * the actual parts of the instruction. A ns32k machine instruction can
94 * be divided into a couple of sub PARTs. When an instruction is assembled
95 * the appropriate PART get an assignment. When an IIF has been completed it's
96 * converted to a FRAGment as specified in AS.H */
97
98/* internal structs */
99struct ns32k_option
100  {
101    char *pattern;
102    unsigned long or;
103    unsigned long and;
104  };
105
106typedef struct
107  {
108    int type;			/* how to interpret object */
109    int size;			/* Estimated max size of object */
110    unsigned long object;	/* binary data */
111    int object_adjust;		/* number added to object */
112    int pcrel;			/* True if object is pcrel */
113    int pcrel_adjust;		/* length in bytes from the
114					   instruction start to the
115					   displacement */
116    int im_disp;		/* True if the object is a displacement */
117    relax_substateT relax_substate;	/* Initial relaxsubstate */
118    bit_fixS *bit_fixP;		/* Pointer at bit_fix struct */
119    int addr_mode;		/* What addrmode do we associate with this iif-entry */
120    char bsr;			/* Sequent hack */
121  }
122
123iif_entryT;			/* Internal Instruction Format */
124
125struct int_ins_form
126  {
127    int instr_size;		/* Max size of instruction in bytes. */
128    iif_entryT iifP[IIF_ENTRIES + 1];
129  };
130struct int_ins_form iif;
131expressionS exprP;
132char *input_line_pointer;
133/* description of the PARTs in IIF
134 *object[n]:
135 * 0	total length in bytes of entries in iif
136 * 1	opcode
137 * 2	index_byte_a
138 * 3	index_byte_b
139 * 4	disp_a_1
140 * 5	disp_a_2
141 * 6	disp_b_1
142 * 7	disp_b_2
143 * 8	imm_a
144 * 9	imm_b
145 * 10	implied1
146 * 11	implied2
147 *
148 * For every entry there is a datalength in bytes. This is stored in size[n].
149 *	 0,	the objectlength is not explicitly given by the instruction
150 *		and the operand is undefined. This is a case for relaxation.
151 *		Reserve 4 bytes for the final object.
152 *
153 *	 1,	the entry contains one byte
154 *	 2,	the entry contains two bytes
155 *	 3,	the entry contains three bytes
156 *	 4,	the entry contains four bytes
157 *	etc
158 *
159 * Furthermore, every entry has a data type identifier in type[n].
160 *
161 * 	 0,	the entry is void, ignore it.
162 * 	 1,	the entry is a binary number.
163 *	 2,	the entry is a pointer at an expression.
164 *		Where expression may be as simple as a single '1',
165 *		and as complicated as  foo-bar+12,
166 * 		foo and bar may be undefined but suffixed by :{b|w|d} to
167 *		control the length of the object.
168 *
169 *	 3,	the entry is a pointer at a bignum struct
170 *
171 *
172 * The low-order-byte coresponds to low physical memory.
173 * Obviously a FRAGment must be created for each valid disp in PART whose
174 * datalength is undefined (to bad) .
175 * The case where just the expression is undefined is less severe and is
176 * handled by fix. Here the number of bytes in the objectfile is known.
177 * With this representation we simplify the assembly and separates the
178 * machine dependent/independent parts in a more clean way (said OE)
179 */
180
181struct ns32k_option opt1[] =		/* restore, exit */
182{
183  {"r0", 0x80, 0xff},
184  {"r1", 0x40, 0xff},
185  {"r2", 0x20, 0xff},
186  {"r3", 0x10, 0xff},
187  {"r4", 0x08, 0xff},
188  {"r5", 0x04, 0xff},
189  {"r6", 0x02, 0xff},
190  {"r7", 0x01, 0xff},
191  {0, 0x00, 0xff}
192};
193struct ns32k_option opt2[] =		/* save, enter */
194{
195  {"r0", 0x01, 0xff},
196  {"r1", 0x02, 0xff},
197  {"r2", 0x04, 0xff},
198  {"r3", 0x08, 0xff},
199  {"r4", 0x10, 0xff},
200  {"r5", 0x20, 0xff},
201  {"r6", 0x40, 0xff},
202  {"r7", 0x80, 0xff},
203  {0, 0x00, 0xff}
204};
205struct ns32k_option opt3[] =		/* setcfg */
206{
207  {"c", 0x8, 0xff},
208  {"m", 0x4, 0xff},
209  {"f", 0x2, 0xff},
210  {"i", 0x1, 0xff},
211  {0, 0x0, 0xff}
212};
213struct ns32k_option opt4[] =		/* cinv */
214{
215  {"a", 0x4, 0xff},
216  {"i", 0x2, 0xff},
217  {"d", 0x1, 0xff},
218  {0, 0x0, 0xff}
219};
220struct ns32k_option opt5[] =		/* string inst */
221{
222  {"b", 0x2, 0xff},
223  {"u", 0xc, 0xff},
224  {"w", 0x4, 0xff},
225  {0, 0x0, 0xff}
226};
227struct ns32k_option opt6[] =		/* plain reg ext,cvtp etc */
228{
229  {"r0", 0x00, 0xff},
230  {"r1", 0x01, 0xff},
231  {"r2", 0x02, 0xff},
232  {"r3", 0x03, 0xff},
233  {"r4", 0x04, 0xff},
234  {"r5", 0x05, 0xff},
235  {"r6", 0x06, 0xff},
236  {"r7", 0x07, 0xff},
237  {0, 0x00, 0xff}
238};
239
240#if !defined(NS32032) && !defined(NS32532)
241#define NS32532
242#endif
243
244struct ns32k_option cpureg_532[] =	/* lpr spr */
245{
246  {"us", 0x0, 0xff},
247  {"dcr", 0x1, 0xff},
248  {"bpc", 0x2, 0xff},
249  {"dsr", 0x3, 0xff},
250  {"car", 0x4, 0xff},
251  {"fp", 0x8, 0xff},
252  {"sp", 0x9, 0xff},
253  {"sb", 0xa, 0xff},
254  {"usp", 0xb, 0xff},
255  {"cfg", 0xc, 0xff},
256  {"psr", 0xd, 0xff},
257  {"intbase", 0xe, 0xff},
258  {"mod", 0xf, 0xff},
259  {0, 0x00, 0xff}
260};
261struct ns32k_option mmureg_532[] =	/* lmr smr */
262{
263  {"mcr", 0x9, 0xff},
264  {"msr", 0xa, 0xff},
265  {"tear", 0xb, 0xff},
266  {"ptb0", 0xc, 0xff},
267  {"ptb1", 0xd, 0xff},
268  {"ivar0", 0xe, 0xff},
269  {"ivar1", 0xf, 0xff},
270  {0, 0x0, 0xff}
271};
272
273struct ns32k_option cpureg_032[] =	/* lpr spr */
274{
275  {"upsr", 0x0, 0xff},
276  {"fp", 0x8, 0xff},
277  {"sp", 0x9, 0xff},
278  {"sb", 0xa, 0xff},
279  {"psr", 0xd, 0xff},
280  {"intbase", 0xe, 0xff},
281  {"mod", 0xf, 0xff},
282  {0, 0x0, 0xff}
283};
284struct ns32k_option mmureg_032[] =	/* lmr smr */
285{
286  {"bpr0", 0x0, 0xff},
287  {"bpr1", 0x1, 0xff},
288  {"pf0", 0x4, 0xff},
289  {"pf1", 0x5, 0xff},
290  {"sc", 0x8, 0xff},
291  {"msr", 0xa, 0xff},
292  {"bcnt", 0xb, 0xff},
293  {"ptb0", 0xc, 0xff},
294  {"ptb1", 0xd, 0xff},
295  {"eia", 0xf, 0xff},
296  {0, 0x0, 0xff}
297};
298
299#if defined(NS32532)
300struct ns32k_option *cpureg = cpureg_532;
301struct ns32k_option *mmureg = mmureg_532;
302#else
303struct ns32k_option *cpureg = cpureg_032;
304struct ns32k_option *mmureg = mmureg_032;
305#endif
306
307
308const pseudo_typeS md_pseudo_table[] =
309{				/* so far empty */
310  {0, 0, 0}
311};
312
313#define IND(x,y)	(((x)<<2)+(y))
314
315/* those are index's to relax groups in md_relax_table
316   ie it must be multiplied by 4 to point at a group start. Viz IND(x,y)
317   Se function relax_segment in write.c for more info */
318
319#define BRANCH		1
320#define PCREL		2
321
322/* those are index's to entries in a relax group */
323
324#define BYTE		0
325#define WORD		1
326#define DOUBLE		2
327#define UNDEF           3
328/* Those limits are calculated from the displacement start in memory.
329   The ns32k uses the begining of the instruction as displacement base.
330   This type of displacements could be handled here by moving the limit window
331   up or down. I choose to use an internal displacement base-adjust as there
332   are other routines that must consider this. Also, as we have two various
333   offset-adjusts in the ns32k (acb versus br/brs/jsr/bcond), two set of limits
334   would have had to be used.
335   Now we dont have to think about that. */
336
337
338const relax_typeS md_relax_table[] =
339{
340  {1, 1, 0, 0},
341  {1, 1, 0, 0},
342  {1, 1, 0, 0},
343  {1, 1, 0, 0},
344
345  {(63), (-64), 1, IND (BRANCH, WORD)},
346  {(8192), (-8192), 2, IND (BRANCH, DOUBLE)},
347  {0, 0, 4, 0},
348  {1, 1, 0, 0}
349};
350
351/* Array used to test if mode contains displacements.
352   Value is true if mode contains displacement. */
353
354char disp_test[] =
355{0, 0, 0, 0, 0, 0, 0, 0,
356 1, 1, 1, 1, 1, 1, 1, 1,
357 1, 1, 1, 0, 0, 1, 1, 0,
358 1, 1, 1, 1, 1, 1, 1, 1};
359
360/* Array used to calculate max size of displacements */
361
362char disp_size[] =
363{4, 1, 2, 0, 4};
364
365static void evaluate_expr PARAMS ((expressionS * resultP, char *ptr));
366static void md_number_to_disp PARAMS ((char *buf, long val, int n));
367static void md_number_to_imm PARAMS ((char *buf, long val, int n));
368
369/* Parses a general operand into an addressingmode struct
370
371   in:  pointer at operand in ascii form
372   pointer at addr_mode struct for result
373   the level of recursion. (always 0 or 1)
374
375   out: data in addr_mode struct
376   */
377int
378addr_mode (operand, addr_modeP, recursive_level)
379     char *operand;
380     register addr_modeS *addr_modeP;
381     int recursive_level;
382{
383  register char *str;
384  register int i;
385  register int strl;
386  register int mode;
387  int j;
388  mode = DEFAULT;		/* default */
389  addr_modeP->scaled_mode = 0;	/* why not */
390  addr_modeP->scaled_reg = 0;	/* if 0, not scaled index */
391  addr_modeP->float_flag = 0;
392  addr_modeP->am_size = 0;
393  addr_modeP->im_disp = 0;
394  addr_modeP->pcrel = 0;	/* not set in this function */
395  addr_modeP->disp_suffix[0] = 0;
396  addr_modeP->disp_suffix[1] = 0;
397  addr_modeP->disp[0] = NULL;
398  addr_modeP->disp[1] = NULL;
399  str = operand;
400  if (str[0] == 0)
401    {
402      return (0);
403    }				/* we don't want this */
404  strl = strlen (str);
405  switch (str[0])
406    {
407      /* the following three case statements controls the mode-chars
408		   this is the place to ed if you want to change them */
409#ifdef ABSOLUTE_PREFIX
410    case ABSOLUTE_PREFIX:
411      if (str[strl - 1] == ']')
412	break;
413      addr_modeP->mode = 21;	/* absolute */
414      addr_modeP->disp[0] = str + 1;
415      return (-1);
416#endif
417#ifdef IMMEDIATE_PREFIX
418    case IMMEDIATE_PREFIX:
419      if (str[strl - 1] == ']')
420	break;
421      addr_modeP->mode = 20;	/* immediate */
422      addr_modeP->disp[0] = str + 1;
423      return (-1);
424#endif
425    case '.':
426      if (str[strl - 1] != ']')
427	{
428	  switch (str[1])
429	    {
430	    case '-':
431	    case '+':
432	      if (str[2] != '\000')
433		{
434		  addr_modeP->mode = 27;	/* pc-relativ */
435		  addr_modeP->disp[0] = str + 2;
436		  return (-1);
437		}
438	    default:
439	      as_warn ("Invalid syntax in PC-relative addressing mode");
440	      return (0);
441	    }
442	}
443      break;
444    case 'e':
445      if (str[strl - 1] != ']')
446	{
447	  if ((!strncmp (str, "ext(", 4)) && strl > 7)
448	    {			/* external */
449	      addr_modeP->disp[0] = str + 4;
450	      i = 0;
451	      j = 2;
452	      do
453		{		/* disp[0]'s termination point */
454		  j += 1;
455		  if (str[j] == '(')
456		    i++;
457		  if (str[j] == ')')
458		    i--;
459		}
460	      while (j < strl && i != 0);
461	      if (i != 0 || !(str[j + 1] == '-' || str[j + 1] == '+'))
462		{
463		  as_warn ("Invalid syntax in External addressing mode");
464		  return (0);
465		}
466	      str[j] = '\000';	/* null terminate disp[0] */
467	      addr_modeP->disp[1] = str + j + 2;
468	      addr_modeP->mode = 22;
469	      return (-1);
470	    }
471	}
472      break;
473    default:;
474    }
475  strl = strlen (str);
476  switch (strl)
477    {
478    case 2:
479      switch (str[0])
480	{
481	case 'f':
482	  addr_modeP->float_flag = 1;
483	case 'r':
484	  if (str[1] >= '0' && str[1] < '8')
485	    {
486	      addr_modeP->mode = str[1] - '0';
487	      return (-1);
488	    }
489	}
490    case 3:
491      if (!strncmp (str, "tos", 3))
492	{
493	  addr_modeP->mode = 23;/* TopOfStack */
494	  return (-1);
495	}
496    default:;
497    }
498  if (strl > 4)
499    {
500      if (str[strl - 1] == ')')
501	{
502	  if (str[strl - 2] == ')')
503	    {
504	      if (!strncmp (&str[strl - 5], "(fp", 3))
505		{
506		  mode = 16;	/* Memory Relative */
507		}
508	      if (!strncmp (&str[strl - 5], "(sp", 3))
509		{
510		  mode = 17;
511		}
512	      if (!strncmp (&str[strl - 5], "(sb", 3))
513		{
514		  mode = 18;
515		}
516	      if (mode != DEFAULT)
517		{		/* memory relative */
518		  addr_modeP->mode = mode;
519		  j = strl - 5;	/* temp for end of disp[0] */
520		  i = 0;
521		  do
522		    {
523		      strl -= 1;
524		      if (str[strl] == ')')
525			i++;
526		      if (str[strl] == '(')
527			i--;
528		    }
529		  while (strl > -1 && i != 0);
530		  if (i != 0)
531		    {
532		      as_warn ("Invalid syntax in Memory Relative addressing mode");
533		      return (0);
534		    }
535		  addr_modeP->disp[1] = str;
536		  addr_modeP->disp[0] = str + strl + 1;
537		  str[j] = '\000';	/* null terminate disp[0] */
538		  str[strl] = '\000';	/* null terminate disp[1] */
539		  return (-1);
540		}
541	    }
542	  switch (str[strl - 3])
543	    {
544	    case 'r':
545	    case 'R':
546	      if (str[strl - 2] >= '0' && str[strl - 2] < '8' && str[strl - 4] == '(')
547		{
548		  addr_modeP->mode = str[strl - 2] - '0' + 8;
549		  addr_modeP->disp[0] = str;
550		  str[strl - 4] = 0;
551		  return (-1);	/* reg rel */
552		}
553	    default:
554	      if (!strncmp (&str[strl - 4], "(fp", 3))
555		{
556		  mode = 24;
557		}
558	      if (!strncmp (&str[strl - 4], "(sp", 3))
559		{
560		  mode = 25;
561		}
562	      if (!strncmp (&str[strl - 4], "(sb", 3))
563		{
564		  mode = 26;
565		}
566	      if (!strncmp (&str[strl - 4], "(pc", 3))
567		{
568		  mode = 27;
569		}
570	      if (mode != DEFAULT)
571		{
572		  addr_modeP->mode = mode;
573		  addr_modeP->disp[0] = str;
574		  str[strl - 4] = '\0';
575		  return (-1);	/* memory space */
576		}
577	    }
578	}
579      /* no trailing ')' do we have a ']' ? */
580      if (str[strl - 1] == ']')
581	{
582	  switch (str[strl - 2])
583	    {
584	    case 'b':
585	      mode = 28;
586	      break;
587	    case 'w':
588	      mode = 29;
589	      break;
590	    case 'd':
591	      mode = 30;
592	      break;
593	    case 'q':
594	      mode = 31;
595	      break;
596	    default:;
597	      as_warn ("Invalid scaled-indexed mode, use (b,w,d,q)");
598	      if (str[strl - 3] != ':' || str[strl - 6] != '[' ||
599		  str[strl - 5] == 'r' || str[strl - 4] < '0' || str[strl - 4] > '7')
600		{
601		  as_warn ("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}");
602		}
603	    }			/* scaled index */
604	  {
605	    if (recursive_level > 0)
606	      {
607		as_warn ("Scaled-indexed addressing mode combined with scaled-index");
608		return (0);
609	      }
610	    addr_modeP->am_size += 1;	/* scaled index byte */
611	    j = str[strl - 4] - '0';	/* store temporary */
612	    str[strl - 6] = '\000';	/* nullterminate for recursive call */
613	    i = addr_mode (str, addr_modeP, 1);
614	    if (!i || addr_modeP->mode == 20)
615	      {
616		as_warn ("Invalid or illegal addressing mode combined with scaled-index");
617		return (0);
618	      }
619	    addr_modeP->scaled_mode = addr_modeP->mode;	/* store the inferior mode */
620	    addr_modeP->mode = mode;
621	    addr_modeP->scaled_reg = j + 1;
622	    return (-1);
623	  }
624	}
625    }
626  addr_modeP->mode = DEFAULT;	/* default to whatever */
627  addr_modeP->disp[0] = str;
628  return (-1);
629}
630
631/* ptr points at string
632   addr_modeP points at struct with result
633   This routine calls addr_mode to determine the general addr.mode of
634   the operand. When this is ready it parses the displacements for size
635   specifying suffixes and determines size of immediate mode via ns32k-opcode.
636   Also builds index bytes if needed.
637   */
638int
639get_addr_mode (ptr, addr_modeP)
640     char *ptr;
641     addr_modeS *addr_modeP;
642{
643  int tmp;
644  addr_mode (ptr, addr_modeP, 0);
645  if (addr_modeP->mode == DEFAULT || addr_modeP->scaled_mode == -1)
646    {
647      /* resolve ambigious operands, this shouldn't
648	 be necessary if one uses standard NSC operand
649	 syntax. But the sequent compiler doesn't!!!
650	 This finds a proper addressinging mode if it
651	 is implicitly stated. See ns32k-opcode.h */
652      (void) evaluate_expr (&exprP, ptr);	/* this call takes time Sigh! */
653      if (addr_modeP->mode == DEFAULT)
654	{
655	  if (exprP.X_add_symbol || exprP.X_op_symbol)
656	    {
657	      addr_modeP->mode = desc->default_model;	/* we have a label */
658	    }
659	  else
660	    {
661	      addr_modeP->mode = desc->default_modec;	/* we have a constant */
662	    }
663	}
664      else
665	{
666	  if (exprP.X_add_symbol || exprP.X_op_symbol)
667	    {
668	      addr_modeP->scaled_mode = desc->default_model;
669	    }
670	  else
671	    {
672	      addr_modeP->scaled_mode = desc->default_modec;
673	    }
674	}
675      /* must put this mess down in addr_mode to handle the scaled case better */
676    }
677  /* It appears as the sequent compiler wants an absolute when we have a
678	   label without @. Constants becomes immediates besides the addr case.
679	   Think it does so with local labels too, not optimum, pcrel is better.
680	   When I have time I will make gas check this and select pcrel when possible
681	   Actually that is trivial.
682	   */
683  if (tmp = addr_modeP->scaled_reg)
684    {				/* build indexbyte */
685      tmp--;			/* remember regnumber comes incremented for flagpurpose */
686      tmp |= addr_modeP->scaled_mode << 3;
687      addr_modeP->index_byte = (char) tmp;
688      addr_modeP->am_size += 1;
689    }
690  if (disp_test[addr_modeP->mode])
691    {				/* there was a displacement, probe for length specifying suffix*/
692      {
693	register char c;
694	register char suffix;
695	register char suffix_sub;
696	register int i;
697	register char *toP;
698	register char *fromP;
699
700	addr_modeP->pcrel = 0;
701	if (disp_test[addr_modeP->mode])
702	  {			/* there is a displacement */
703	    if (addr_modeP->mode == 27 || addr_modeP->scaled_mode == 27)
704	      {			/* do we have pcrel. mode */
705		addr_modeP->pcrel = 1;
706	      }
707	    addr_modeP->im_disp = 1;
708	    for (i = 0; i < 2; i++)
709	      {
710		suffix_sub = suffix = 0;
711		if (toP = addr_modeP->disp[i])
712		  {		/* suffix of expression, the largest size rules */
713		    fromP = toP;
714		    while (c = *fromP++)
715		      {
716			*toP++ = c;
717			if (c == ':')
718			  {
719			    switch (*fromP)
720			      {
721			      case '\0':
722				as_warn ("Premature end of suffix--Defaulting to d");
723				suffix = 4;
724				continue;
725			      case 'b':
726				suffix_sub = 1;
727				break;
728			      case 'w':
729				suffix_sub = 2;
730				break;
731			      case 'd':
732				suffix_sub = 4;
733				break;
734			      default:
735				as_warn ("Bad suffix after ':' use {b|w|d} Defaulting to d");
736				suffix = 4;
737			      }
738			    fromP++;
739			    toP--;	/* So we write over the ':' */
740			    if (suffix < suffix_sub)
741			      suffix = suffix_sub;
742			  }
743		      }
744		    *toP = '\0';/* terminate properly */
745		    addr_modeP->disp_suffix[i] = suffix;
746		    addr_modeP->am_size += suffix ? suffix : 4;
747		  }
748	      }
749	  }
750      }
751    }
752  else
753    {
754      if (addr_modeP->mode == 20)
755	{			/* look in ns32k_opcode for size */
756	  addr_modeP->disp_suffix[0] = addr_modeP->am_size = desc->im_size;
757	  addr_modeP->im_disp = 0;
758	}
759    }
760  return addr_modeP->mode;
761}
762
763
764/* read an optionlist */
765void
766optlist (str, optionP, default_map)
767     char *str;			/* the string to extract options from */
768     struct ns32k_option *optionP;	/* how to search the string */
769     unsigned long *default_map;/* default pattern and output */
770{
771  register int i, j, k, strlen1, strlen2;
772  register char *patternP, *strP;
773  strlen1 = strlen (str);
774  if (strlen1 < 1)
775    {
776      as_fatal ("Very short instr to option, ie you can't do it on a NULLstr");
777    }
778  for (i = 0; optionP[i].pattern != 0; i++)
779    {
780      strlen2 = strlen (optionP[i].pattern);
781      for (j = 0; j < strlen1; j++)
782	{
783	  patternP = optionP[i].pattern;
784	  strP = &str[j];
785	  for (k = 0; k < strlen2; k++)
786	    {
787	      if (*(strP++) != *(patternP++))
788		break;
789	    }
790	  if (k == strlen2)
791	    {			/* match */
792	      *default_map |= optionP[i].or;
793	      *default_map &= optionP[i].and;
794	    }
795	}
796    }
797}
798
799/* search struct for symbols
800   This function is used to get the short integer form of reg names
801   in the instructions lmr, smr, lpr, spr
802   return true if str is found in list */
803
804int
805list_search (str, optionP, default_map)
806     char *str;			/* the string to match */
807     struct ns32k_option *optionP;	/* list to search */
808     unsigned long *default_map;/* default pattern and output */
809{
810  register int i;
811  for (i = 0; optionP[i].pattern != 0; i++)
812    {
813      if (!strncmp (optionP[i].pattern, str, 20))
814	{			/* use strncmp to be safe */
815	  *default_map |= optionP[i].or;
816	  *default_map &= optionP[i].and;
817	  return -1;
818	}
819    }
820  as_warn ("No such entry in list. (cpu/mmu register)");
821  return 0;
822}
823
824static void
825evaluate_expr (resultP, ptr)
826     expressionS *resultP;
827     char *ptr;
828{
829  register char *tmp_line;
830
831  tmp_line = input_line_pointer;
832  input_line_pointer = ptr;
833  expression (&exprP);
834  input_line_pointer = tmp_line;
835}
836
837/* Convert operands to iif-format and adds bitfields to the opcode.
838   Operands are parsed in such an order that the opcode is updated from
839   its most significant bit, that is when the operand need to alter the
840   opcode.
841   Be carefull not to put to objects in the same iif-slot.
842   */
843
844void
845encode_operand (argc, argv, operandsP, suffixP, im_size, opcode_bit_ptr)
846     int argc;
847     char **argv;
848     char *operandsP;
849     char *suffixP;
850     char im_size;
851     char opcode_bit_ptr;
852{
853  register int i, j;
854  char d;
855  int pcrel, tmp, b, loop, pcrel_adjust;
856  for (loop = 0; loop < argc; loop++)
857    {
858      i = operandsP[loop << 1] - '1';	/* what operand are we supposed to work on */
859      if (i > 3)
860	as_fatal ("Internal consistency error.  check ns32k-opcode.h");
861      pcrel = 0;
862      pcrel_adjust = 0;
863      tmp = 0;
864      switch ((d = operandsP[(loop << 1) + 1]))
865	{
866	case 'f':		/* operand of sfsr turns out to be a nasty specialcase */
867	  opcode_bit_ptr -= 5;
868	case 'Z':		/* float not immediate */
869	case 'F':		/* 32 bit float	general form */
870	case 'L':		/* 64 bit float	*/
871	case 'I':		/* integer not immediate */
872	case 'B':		/* byte	 */
873	case 'W':		/* word	 */
874	case 'D':		/* double-word	*/
875	case 'A':		/* double-word	gen-address-form ie no regs allowed */
876	  get_addr_mode (argv[i], &addr_modeP);
877	  if((addr_modeP.mode == 20) &&
878	     (d == 'I' || d == 'Z' || d == 'A')) {
879	    as_fatal(d == 'A'? "Address of immediate operand":
880		     "Invalid immediate write operand.");
881	  }
882	  iif.instr_size += addr_modeP.am_size;
883	  if (opcode_bit_ptr == desc->opcode_size)
884	    b = 4;
885	  else
886	    b = 6;
887	  for (j = b; j < (b + 2); j++)
888	    {
889	      if (addr_modeP.disp[j - b])
890		{
891		  IIF (j,
892		       2,
893		       addr_modeP.disp_suffix[j - b],
894		       (unsigned long) addr_modeP.disp[j - b],
895		       0,
896		       addr_modeP.pcrel,
897		       iif.instr_size - addr_modeP.am_size,	/* this aint used (now) */
898		       addr_modeP.im_disp,
899		       IND (BRANCH, BYTE),
900		       NULL,
901		       addr_modeP.scaled_reg ? addr_modeP.scaled_mode : addr_modeP.mode,
902		       0);
903		}
904	    }
905	  opcode_bit_ptr -= 5;
906	  iif.iifP[1].object |= ((long) addr_modeP.mode) << opcode_bit_ptr;
907	  if (addr_modeP.scaled_reg)
908	    {
909	      j = b / 2;
910	      IIF (j, 1, 1, (unsigned long) addr_modeP.index_byte, 0, 0, 0, 0, 0, NULL, -1, 0);
911	    }
912	  break;
913	case 'b':		/* multiple instruction disp */
914	  freeptr++;		/* OVE:this is an useful hack */
915	  sprintf (freeptr, "((%s-1)*%d)\000", argv[i], desc->im_size);
916	  argv[i] = freeptr;
917	  pcrel -= 1;		/* make pcrel 0 inspite of what case 'p': wants */
918	  /* fall thru */
919	case 'p':		/* displacement - pc relative addressing */
920	  pcrel += 1;
921	  /* fall thru */
922	case 'd':		/* displacement */
923	  iif.instr_size += suffixP[i] ? suffixP[i] : 4;
924	  IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
925	       pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 0);
926	  break;
927	case 'H':		/* sequent-hack: the linker wants a bit set when bsr */
928	  pcrel = 1;
929	  iif.instr_size += suffixP[i] ? suffixP[i] : 4;
930	  IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
931	       pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 1);
932	  break;
933	case 'q':		/* quick */
934	  opcode_bit_ptr -= 4;
935	  IIF (11, 2, 42, (unsigned long) argv[i], 0, 0, 0, 0, 0,
936	       bit_fix_new (4, opcode_bit_ptr, -8, 7, 0, 1, 0), -1, 0);
937	  break;
938	case 'r':		/* register number (3 bits) */
939	  list_search (argv[i], opt6, &tmp);
940	  opcode_bit_ptr -= 3;
941	  iif.iifP[1].object |= tmp << opcode_bit_ptr;
942	  break;
943	case 'O':		/* setcfg instruction optionslist */
944	  optlist (argv[i], opt3, &tmp);
945	  opcode_bit_ptr -= 4;
946	  iif.iifP[1].object |= tmp << 15;
947	  break;
948	case 'C':		/* cinv instruction optionslist */
949	  optlist (argv[i], opt4, &tmp);
950	  opcode_bit_ptr -= 4;
951	  iif.iifP[1].object |= tmp << 15;	/*insert the regtype in opcode */
952	  break;
953	case 'S':		/* stringinstruction optionslist */
954	  optlist (argv[i], opt5, &tmp);
955	  opcode_bit_ptr -= 4;
956	  iif.iifP[1].object |= tmp << 15;
957	  break;
958	case 'u':
959	case 'U':		/* registerlist */
960	  IIF (10, 1, 1, 0, 0, 0, 0, 0, 0, NULL, -1, 0);
961	  switch (operandsP[(i << 1) + 1])
962	    {
963	    case 'u':		/* restore, exit */
964	      optlist (argv[i], opt1, &iif.iifP[10].object);
965	      break;
966	    case 'U':		/* save,enter */
967	      optlist (argv[i], opt2, &iif.iifP[10].object);
968	      break;
969	    }
970	  iif.instr_size += 1;
971	  break;
972	case 'M':		/* mmu register */
973	  list_search (argv[i], mmureg, &tmp);
974	  opcode_bit_ptr -= 4;
975	  iif.iifP[1].object |= tmp << opcode_bit_ptr;
976	  break;
977	case 'P':		/* cpu register  */
978	  list_search (argv[i], cpureg, &tmp);
979	  opcode_bit_ptr -= 4;
980	  iif.iifP[1].object |= tmp << opcode_bit_ptr;
981	  break;
982	case 'g':		/* inss exts */
983	  iif.instr_size += 1;	/* 1 byte is allocated after the opcode */
984	  IIF (10, 2, 1,
985	       (unsigned long) argv[i],	/* i always 2 here */
986	       0, 0, 0, 0, 0,
987	       bit_fix_new (3, 5, 0, 7, 0, 0, 0),	/* a bit_fix is targeted to the byte */
988	       -1, 0);
989	  break;
990	case 'G':
991	  IIF (11, 2, 42,
992	       (unsigned long) argv[i],	/* i always 3 here */
993	       0, 0, 0, 0, 0,
994	       bit_fix_new (5, 0, 1, 32, -1, 0, -1), -1, 0);
995	  break;
996	case 'i':
997	  iif.instr_size += 1;
998	  b = 2 + i;		/* put the extension byte after opcode */
999	  IIF (b, 2, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0);
1000	  break;
1001	default:
1002	  as_fatal ("Bad opcode-table-option, check in file ns32k-opcode.h");
1003	}
1004    }
1005}
1006
1007/* in:  instruction line
1008   out: internal structure of instruction
1009   that has been prepared for direct conversion to fragment(s) and
1010   fixes in a systematical fashion
1011   Return-value = recursive_level
1012   */
1013/* build iif of one assembly text line */
1014int
1015parse (line, recursive_level)
1016     char *line;
1017     int recursive_level;
1018{
1019  register char *lineptr, c, suffix_separator;
1020  register int i;
1021  int argc, arg_type;
1022  char sqr, sep;
1023  char suffix[MAX_ARGS], *argv[MAX_ARGS];	/* no more than 4 operands */
1024  if (recursive_level <= 0)
1025    {				/* called from md_assemble */
1026      for (lineptr = line; (*lineptr) != '\0' && (*lineptr) != ' '; lineptr++);
1027      c = *lineptr;
1028      *lineptr = '\0';
1029      if (!(desc = (struct ns32k_opcode *) hash_find (inst_hash_handle, line)))
1030	{
1031	  as_fatal ("No such opcode");
1032	}
1033      *lineptr = c;
1034    }
1035  else
1036    {
1037      lineptr = line;
1038    }
1039  argc = 0;
1040  if (*desc->operands)
1041    {
1042      if (*lineptr++ != '\0')
1043	{
1044	  sqr = '[';
1045	  sep = ',';
1046	  while (*lineptr != '\0')
1047	    {
1048	      if (desc->operands[argc << 1])
1049		{
1050		  suffix[argc] = 0;
1051		  arg_type = desc->operands[(argc << 1) + 1];
1052		  switch (arg_type)
1053		    {
1054		    case 'd':
1055		    case 'b':
1056		    case 'p':
1057		    case 'H':	/* the operand is supposed to be a displacement */
1058		      /* Hackwarning: do not forget to update the 4 cases above when editing ns32k-opcode.h */
1059		      suffix_separator = ':';
1060		      break;
1061		    default:
1062		      suffix_separator = '\255';	/* if this char occurs we loose */
1063		    }
1064		  suffix[argc] = 0;	/* 0 when no ':' is encountered */
1065		  argv[argc] = freeptr;
1066		  *freeptr = '\0';
1067		  while ((c = *lineptr) != '\0' && c != sep)
1068		    {
1069		      if (c == sqr)
1070			{
1071			  if (sqr == '[')
1072			    {
1073			      sqr = ']';
1074			      sep = '\0';
1075			    }
1076			  else
1077			    {
1078			      sqr = '[';
1079			      sep = ',';
1080			    }
1081			}
1082		      if (c == suffix_separator)
1083			{	/* ':' - label/suffix separator */
1084			  switch (lineptr[1])
1085			    {
1086			    case 'b':
1087			      suffix[argc] = 1;
1088			      break;
1089			    case 'w':
1090			      suffix[argc] = 2;
1091			      break;
1092			    case 'd':
1093			      suffix[argc] = 4;
1094			      break;
1095			    default:
1096			      as_warn ("Bad suffix, defaulting to d");
1097			      suffix[argc] = 4;
1098			      if (lineptr[1] == '\0' || lineptr[1] == sep)
1099				{
1100				  lineptr += 1;
1101				  continue;
1102				}
1103			    }
1104			  lineptr += 2;
1105			  continue;
1106			}
1107		      *freeptr++ = c;
1108		      lineptr++;
1109		    }
1110		  *freeptr++ = '\0';
1111		  argc += 1;
1112		  if (*lineptr == '\0')
1113		    continue;
1114		  lineptr += 1;
1115		}
1116	      else
1117		{
1118		  as_fatal ("Too many operands passed to instruction");
1119		}
1120	    }
1121	}
1122    }
1123  if (argc != strlen (desc->operands) / 2)
1124    {
1125      if (strlen (desc->default_args))
1126	{			/* we can apply default, dont goof */
1127	  if (parse (desc->default_args, 1) != 1)
1128	    {			/* check error in default */
1129	      as_fatal ("Wrong numbers of operands in default, check ns32k-opcodes.h");
1130	    }
1131	}
1132      else
1133	{
1134	  as_fatal ("Wrong number of operands");
1135	}
1136
1137    }
1138  for (i = 0; i < IIF_ENTRIES; i++)
1139    {
1140      iif.iifP[i].type = 0;	/* mark all entries as void*/
1141    }
1142
1143  /* build opcode iif-entry */
1144  iif.instr_size = desc->opcode_size / 8;
1145  IIF (1, 1, iif.instr_size, desc->opcode_seed, 0, 0, 0, 0, 0, 0, -1, 0);
1146
1147  /* this call encodes operands to iif format */
1148  if (argc)
1149    {
1150      encode_operand (argc,
1151		      argv,
1152		      &desc->operands[0],
1153		      &suffix[0],
1154		      desc->im_size,
1155		      desc->opcode_size);
1156    }
1157  return recursive_level;
1158}
1159
1160
1161/* Convert iif to fragments.  From this point we start to dribble with
1162 * functions in other files than this one.(Except hash.c) So, if it's
1163 * possible to make an iif for an other CPU, you don't need to know
1164 * what frags, relax, obstacks, etc is in order to port this
1165 * assembler. You only need to know if it's possible to reduce your
1166 * cpu-instruction to iif-format (takes some work) and adopt the other
1167 * md_? parts according to given instructions Note that iif was
1168 * invented for the clean ns32k`s architecure.
1169   */
1170
1171/* GAS for the ns32k has a problem. PC relative displacements are relative
1172 * to the address of the opcode, not the address of the operand. We can
1173 * keep track of the offset between the operand and the opcode in
1174 * pcrel_adjust. That is what it is for. However, we get into trouble
1175 * where there is two or more pc-relative operands and the size of the
1176 * first one can't be determined. Then in the relax phase, the size of the
1177 * first operand will change and pcrel_adjust will no longer be correct.
1178 * In an earlier attempt to fix this, I added an extra field to frags to
1179 * keep track of how much the pcrel_adjust had changed during relax.
1180 * That meant cluttering up write.c with (more) ns32k dependent things.
1181 * The current solution is to note that operands whose size isn't determined
1182 * yet must be in the variable part of a frag. The next operand (if any)]
1183 * must be in a new frag. What we need is a way to find out where in what
1184 * frag the opcode for this operand is.
1185 * What we do is allocate and extra structure and for frags which do not
1186 * contain the opcode, use the opcode pointer to point at this new
1187 * structure. Requires that a pointer to a struct can be cast to a pointer
1188 * to char * without loss.
1189 */
1190struct opcode_location {
1191  fragS *fragP;
1192  unsigned int offset;
1193};
1194
1195void
1196convert_iif ()
1197{
1198  int i;
1199  bit_fixS *j;
1200  fragS *inst_frag;
1201  unsigned int inst_offset;
1202  char *inst_opcode;
1203  struct opcode_location *opcode_location;
1204  fragS *opcode_frag;
1205  char *memP;
1206  int l;
1207  int k;
1208  int rem_size;			/* count the remaining bytes of instruction */
1209  char type;
1210  char size = 0;
1211  int size_so_far = 0;		/* used to calculate pcrel_adjust */
1212  char first = 1;		/* true until after the first frag of this
1213 				 * instruction has been done
1214 				 */
1215
1216  rem_size = iif.instr_size;
1217  memP = frag_more (iif.instr_size);	/* make sure we have enough bytes for instruction */
1218  inst_opcode = memP;
1219  inst_offset = (memP - frag_now->fr_literal);
1220  inst_frag = frag_now;
1221
1222  for (i = 0; i < IIF_ENTRIES; i++)
1223    {
1224      if (type = iif.iifP[i].type)
1225	{			/* the object exist, so handle it */
1226	  switch (size = iif.iifP[i].size)
1227	    {
1228	    case 42:
1229	      size = 0;		/* it's a bitfix that operates on an existing object*/
1230	      if (iif.iifP[i].bit_fixP->fx_bit_base)
1231		{		/* expand fx_bit_base to point at opcode */
1232		  iif.iifP[i].bit_fixP->fx_bit_base = (long) inst_opcode;
1233		}
1234	    case 8:		/* bignum or doublefloat */
1235	      memset (memP, '\0', size);
1236	    case 1:
1237	    case 2:
1238	    case 3:
1239	    case 4:		/* the final size in objectmemory is known */
1240	      j = iif.iifP[i].bit_fixP;
1241	      switch (type)
1242		{
1243		case 1:	/* the object is pure binary */
1244		  if (j || iif.iifP[i].pcrel)
1245		    {
1246		      fix_new_ns32k (frag_now,
1247				     (long) (memP - frag_now->fr_literal),
1248				     size,
1249				     0,
1250				     iif.iifP[i].object,
1251				     iif.iifP[i].pcrel,
1252				     (char) (first? size_so_far: 0),	/*iif.iifP[i].pcrel_adjust,*/
1253				     iif.iifP[i].im_disp,
1254				     j,
1255				     iif.iifP[i].bsr);	/* sequent hack */
1256		    }
1257		  else
1258		    {		/* good, just put them bytes out */
1259		      switch (iif.iifP[i].im_disp)
1260			{
1261			case 0:
1262			  md_number_to_chars (memP, iif.iifP[i].object, size);
1263			  break;
1264			case 1:
1265			  md_number_to_disp (memP, iif.iifP[i].object, size);
1266			  break;
1267			default:
1268			  as_fatal ("iif convert internal pcrel/binary");
1269			}
1270		    }
1271		  memP += size;
1272		  rem_size -= size;
1273		  break;
1274		case 2:	/* the object is a pointer at an expression, so unpack
1275					   it, note that bignums may result from the expression
1276					   */
1277		  evaluate_expr (&exprP, (char *) iif.iifP[i].object);
1278		  if (exprP.X_op == O_big || size == 8)
1279		    {
1280		      if ((k = exprP.X_add_number) > 0)
1281			{	/* we have a bignum ie a quad */
1282			  /* this can only happens in a long suffixed instruction */
1283			  memset (memP, '\0', size);	/* size normally is 8 */
1284			  if (k * 2 > size)
1285			    as_warn ("Bignum too big for long");
1286			  if (k == 3)
1287			    memP += 2;
1288			  for (l = 0; k > 0; k--, l += 2)
1289			    {
1290			      md_number_to_chars (memP + l, generic_bignum[l >> 1], sizeof (LITTLENUM_TYPE));
1291			    }
1292			}
1293		      else
1294			{	/* flonum */
1295			  LITTLENUM_TYPE words[4];
1296
1297			  switch (size)
1298			    {
1299			    case 4:
1300			      gen_to_words (words, 2, 8);
1301			      md_number_to_imm (memP, (long) words[0], sizeof (LITTLENUM_TYPE));
1302			      md_number_to_imm (memP + sizeof (LITTLENUM_TYPE), (long) words[1], sizeof (LITTLENUM_TYPE));
1303			      break;
1304			    case 8:
1305			      gen_to_words (words, 4, 11);
1306			      md_number_to_imm (memP, (long) words[0], sizeof (LITTLENUM_TYPE));
1307			      md_number_to_imm (memP + sizeof (LITTLENUM_TYPE), (long) words[1], sizeof (LITTLENUM_TYPE));
1308			      md_number_to_imm (memP + 2 * sizeof (LITTLENUM_TYPE), (long) words[2], sizeof (LITTLENUM_TYPE));
1309			      md_number_to_imm (memP + 3 * sizeof (LITTLENUM_TYPE), (long) words[3], sizeof (LITTLENUM_TYPE));
1310			      break;
1311			    }
1312			}
1313		      memP += size;
1314		      rem_size -= size;
1315		      break;
1316		    }
1317		  if (j ||
1318		      exprP.X_add_symbol ||
1319		      exprP.X_op_symbol ||
1320		      iif.iifP[i].pcrel)
1321		    {		/* fixit */
1322		      /* the expression was undefined due to an undefined label */
1323		      /* create a fix so we can fix the object later */
1324		      exprP.X_add_number += iif.iifP[i].object_adjust;
1325		      fix_new_ns32k_exp (frag_now,
1326					 (long) (memP - frag_now->fr_literal),
1327					 size,
1328					 &exprP,
1329					 iif.iifP[i].pcrel,
1330					 (char) (first? size_so_far: 0),	/*iif.iifP[i].pcrel_adjust,*/
1331					 iif.iifP[i].im_disp,
1332					 j,
1333					 iif.iifP[i].bsr);	/* sequent hack */
1334
1335		    }
1336		  else
1337		    {		/* good, just put them bytes out */
1338		      switch (iif.iifP[i].im_disp)
1339			{
1340			case 0:
1341			  md_number_to_imm (memP, exprP.X_add_number, size);
1342			  break;
1343			case 1:
1344			  md_number_to_disp (memP, exprP.X_add_number, size);
1345			  break;
1346			default:
1347			  as_fatal ("iif convert internal pcrel/pointer");
1348			}
1349		    }
1350		  memP += size;
1351		  rem_size -= size;
1352		  break;
1353		default:
1354		  as_fatal ("Internal logic error in iif.iifP[n].type");
1355		}
1356	      break;
1357	    case 0: /* To bad, the object may be undefined as far as
1358		     * its final nsize in object memory is concerned.
1359		     * The size of the object in objectmemory is not
1360		     * explicitly given.  If the object is defined its
1361		     * length can be determined and a fix can replace
1362		     * the frag.
1363					    */
1364	      {
1365		int temp;
1366		evaluate_expr (&exprP, (char *) iif.iifP[i].object);
1367		if ((exprP.X_add_symbol || exprP.X_op_symbol) &&
1368		    !iif.iifP[i].pcrel)
1369		  {		/* OVE: hack, clamp to 4 bytes */
1370		    size = 4;	/* we dont wan't to frag this, use 4 so it reaches */
1371		    fix_new_ns32k_exp (frag_now,
1372				       (long) (memP - frag_now->fr_literal),
1373				       size,
1374				       &exprP,
1375				       0,	/* never iif.iifP[i].pcrel, */
1376				       (char) (first? size_so_far: 0),	/*iif.iifP[i].pcrel_adjust,*/
1377				       1,	/* always iif.iifP[i].im_disp, */
1378				       (bit_fixS *) 0, 0);
1379		    memP += size;
1380		    rem_size -= 4;
1381		    break;	/* exit this absolute hack */
1382		  }
1383
1384		if (exprP.X_add_symbol || exprP.X_op_symbol)
1385		  {		/* frag it */
1386		    if (exprP.X_op_symbol)
1387		      {		/* We cant relax this case */
1388			as_fatal ("Can't relax difference");
1389		      }
1390		    else
1391		      {
1392
1393			/* at this stage we must undo some of the
1394			 * effect caused by frag_more, ie we must make
1395			 * sure that frag_var causes frag_new to creat
1396			 * a valid fix-size in the frag it`s closing
1397			 * * we rewind none, some or all of the
1398			 * requested size we requested by the first
1399			 * frag_more for this iif chunk.  Note: that
1400			 * we allocate 4 bytes to an object we NOT YET
1401			 * know the size of, thus rem_size-4.
1402							   */
1403
1404			/* Size is not important. This gets fixed by relax,
1405			 * but we assume 0 in what follows
1406			 */
1407			size = 0;
1408
1409			temp = -(rem_size - 4);
1410			frag_grow (temp);
1411
1412			{
1413			  fragS *old_frag = frag_now;
1414			  frag_variant (rs_machine_dependent,
1415					4,
1416					0, /* size */
1417					IND (BRANCH, UNDEF), /* expecting the worst */
1418					exprP.X_add_symbol,
1419					exprP.X_add_number,
1420					(first
1421					 ? inst_opcode
1422					 : (char *) opcode_location));
1423			  if (first)
1424			    old_frag->fr_pcrel_adjust = (char) size_so_far;
1425			  old_frag->fr_bsr = iif.iifP[i].bsr;
1426			}
1427
1428			if (first) {
1429			  /* The opcode is really in the last frag.
1430			   * overload the inst_opcode pointer.
1431			   */
1432			  opcode_location
1433			    = (struct opcode_location *) obstack_alloc(&notes, sizeof(struct opcode_location));
1434			  opcode_location->fragP = inst_frag;
1435			  opcode_location->offset = inst_offset;
1436
1437			  first = 0;
1438			}
1439
1440			rem_size -= 4;
1441			if (rem_size > 0)
1442			  {
1443			    memP = frag_more (rem_size);
1444			  }
1445		      }
1446		  }
1447		else
1448		  {		/* Double work, this is done in md_number_to_disp */
1449		    /*	      exprP.X_add_number; what was this supposed to be?
1450							      xoxorich. */
1451		    if (-64 <= exprP.X_add_number && exprP.X_add_number <= 63)
1452		      {
1453			size = 1;
1454		      }
1455		    else
1456		      {
1457			if (-8192 <= exprP.X_add_number && exprP.X_add_number <= 8191)
1458			  {
1459			    size = 2;
1460			  }
1461			else
1462			  {
1463			    if (-0x20000000<=exprP.X_add_number &&
1464				exprP.X_add_number<=0x1fffffff)
1465			      {
1466				size = 4;
1467			      }
1468			    else
1469			      {
1470				as_warn ("Displacement to large for :d");
1471				size = 4;
1472			      }
1473			  }
1474		      }
1475		    /* rewind the bytes not used */
1476		    temp = -(4 - size);
1477		    md_number_to_disp (memP, exprP.X_add_number, size);
1478		    frag_grow (temp);
1479		    memP += size;
1480		    rem_size -= 4;	/* we allocated this amount */
1481		  }
1482	      }
1483	      break;
1484	    default:
1485	      as_fatal ("Internal logic error in iif.iifP[].type");
1486	    }
1487	  size_so_far += size;
1488	  size = 0;
1489	}
1490    }
1491}
1492
1493#ifdef BFD_ASSEMBLER
1494/* This functionality should really be in the bfd library */
1495static bfd_reloc_code_real_type
1496reloc (int size, int pcrel, int type)
1497{
1498  int length, index;
1499  bfd_reloc_code_real_type relocs[] = {
1500    BFD_RELOC_NS32K_IMM_8,
1501    BFD_RELOC_NS32K_IMM_16,
1502    BFD_RELOC_NS32K_IMM_32,
1503    BFD_RELOC_NS32K_IMM_8_PCREL,
1504    BFD_RELOC_NS32K_IMM_16_PCREL,
1505    BFD_RELOC_NS32K_IMM_32_PCREL,
1506
1507    /* ns32k displacements */
1508    BFD_RELOC_NS32K_DISP_8,
1509    BFD_RELOC_NS32K_DISP_16,
1510    BFD_RELOC_NS32K_DISP_32,
1511    BFD_RELOC_NS32K_DISP_8_PCREL,
1512    BFD_RELOC_NS32K_DISP_16_PCREL,
1513    BFD_RELOC_NS32K_DISP_32_PCREL,
1514
1515    /* Normal 2's complement */
1516    BFD_RELOC_8,
1517    BFD_RELOC_16,
1518    BFD_RELOC_32,
1519    BFD_RELOC_8_PCREL,
1520    BFD_RELOC_16_PCREL,
1521    BFD_RELOC_32_PCREL
1522    };
1523  switch (size)
1524    {
1525    case 1:
1526      length = 0;
1527      break;
1528    case 2:
1529      length = 1;
1530      break;
1531    case 4:
1532      length = 2;
1533      break;
1534    default:
1535      length = -1;
1536      break;
1537    }
1538  index = length + 3 * pcrel + 6 * type;
1539  if (index >= 0 && index < sizeof(relocs)/sizeof(relocs[0]))
1540    return relocs[index];
1541  as_bad ("Can not do %d byte %s relocation for storage type %d", size,
1542	  pcrel ? "pc-relative" : "", type);
1543  return BFD_RELOC_NONE;
1544
1545}
1546
1547#endif
1548
1549void
1550md_assemble (line)
1551     char *line;
1552{
1553  freeptr = freeptr_static;
1554  parse (line, 0);		/* explode line to more fix form in iif */
1555  convert_iif ();		/* convert iif to frags, fix's etc */
1556#ifdef SHOW_NUM
1557  printf (" \t\t\t%s\n", line);
1558#endif
1559}
1560
1561
1562void
1563md_begin ()
1564{
1565  /* build a hashtable of the instructions */
1566  const struct ns32k_opcode *ptr;
1567  const char *stat;
1568  inst_hash_handle = hash_new ();
1569  for (ptr = ns32k_opcodes; ptr < endop; ptr++)
1570    {
1571      if ((stat = hash_insert (inst_hash_handle, ptr->name, (char *) ptr)))
1572	{
1573	  as_fatal ("Can't hash %s: %s", ptr->name, stat);	/*fatal*/
1574	}
1575    }
1576  freeptr_static = (char *) malloc (PRIVATE_SIZE);	/* some private space please! */
1577}
1578
1579/* Must be equal to MAX_PRECISON in atof-ieee.c */
1580#define MAX_LITTLENUMS 6
1581
1582/* Turn the string pointed to by litP into a floating point constant of type
1583   type, and emit the appropriate bytes.  The number of LITTLENUMS emitted
1584   is stored in *sizeP .  An error message is returned, or NULL on OK.
1585   */
1586char *
1587md_atof (type, litP, sizeP)
1588     char type;
1589     char *litP;
1590     int *sizeP;
1591{
1592  int prec;
1593  LITTLENUM_TYPE words[MAX_LITTLENUMS];
1594  LITTLENUM_TYPE *wordP;
1595  char *t;
1596
1597  switch (type)
1598    {
1599    case 'f':
1600      prec = 2;
1601      break;
1602
1603    case 'd':
1604      prec = 4;
1605      break;
1606    default:
1607      *sizeP = 0;
1608      return "Bad call to MD_ATOF()";
1609    }
1610  t = atof_ieee (input_line_pointer, type, words);
1611  if (t)
1612    input_line_pointer = t;
1613
1614  *sizeP = prec * sizeof (LITTLENUM_TYPE);
1615  for (wordP = words + prec; prec--;)
1616    {
1617      md_number_to_chars (litP, (long) (*--wordP), sizeof (LITTLENUM_TYPE));
1618      litP += sizeof (LITTLENUM_TYPE);
1619    }
1620  return 0;
1621}
1622
1623/* Convert number to chars in correct order */
1624
1625void
1626md_number_to_chars (buf, value, nbytes)
1627     char *buf;
1628     valueT value;
1629     int nbytes;
1630{
1631  number_to_chars_littleendian (buf, value, nbytes);
1632}
1633
1634
1635/* This is a variant of md_numbers_to_chars. The reason for its' existence
1636   is the fact that ns32k uses Huffman coded displacements. This implies
1637   that the bit order is reversed in displacements and that they are prefixed
1638   with a size-tag.
1639
1640   binary: msb -> lsb
1641   0xxxxxxx				byte
1642   10xxxxxx xxxxxxxx			word
1643   11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx	double word
1644
1645   This must be taken care of and we do it here!
1646   */
1647static void
1648md_number_to_disp (buf, val, n)
1649     char *buf;
1650     long val;
1651     char n;
1652{
1653  switch (n)
1654    {
1655    case 1:
1656      if (val < -64 || val > 63)
1657	as_warn ("Byte displacement out of range.  line number not valid");
1658      val &= 0x7f;
1659#ifdef SHOW_NUM
1660      printf ("%x ", val & 0xff);
1661#endif
1662      *buf++ = val;
1663      break;
1664    case 2:
1665      if (val < -8192 || val > 8191)
1666	as_warn ("Word displacement out of range.  line number not valid");
1667      val &= 0x3fff;
1668      val |= 0x8000;
1669#ifdef SHOW_NUM
1670      printf ("%x ", val >> 8 & 0xff);
1671#endif
1672      *buf++ = (val >> 8);
1673#ifdef SHOW_NUM
1674      printf ("%x ", val & 0xff);
1675#endif
1676      *buf++ = val;
1677      break;
1678    case 4:
1679      if (val < -0x20000000 || val >= 0x20000000)
1680	as_warn ("Double word displacement out of range");
1681      val |= 0xc0000000;
1682#ifdef SHOW_NUM
1683      printf ("%x ", val >> 24 & 0xff);
1684#endif
1685      *buf++ = (val >> 24);
1686#ifdef SHOW_NUM
1687      printf ("%x ", val >> 16 & 0xff);
1688#endif
1689      *buf++ = (val >> 16);
1690#ifdef SHOW_NUM
1691      printf ("%x ", val >> 8 & 0xff);
1692#endif
1693      *buf++ = (val >> 8);
1694#ifdef SHOW_NUM
1695      printf ("%x ", val & 0xff);
1696#endif
1697      *buf++ = val;
1698      break;
1699    default:
1700      as_fatal ("Internal logic error.  line %s, file \"%s\"", __LINE__, __FILE__);
1701    }
1702}
1703
1704static void
1705md_number_to_imm (buf, val, n)
1706     char *buf;
1707     long val;
1708     char n;
1709{
1710  switch (n)
1711    {
1712    case 1:
1713#ifdef SHOW_NUM
1714      printf ("%x ", val & 0xff);
1715#endif
1716      *buf++ = val;
1717      break;
1718    case 2:
1719#ifdef SHOW_NUM
1720      printf ("%x ", val >> 8 & 0xff);
1721#endif
1722      *buf++ = (val >> 8);
1723#ifdef SHOW_NUM
1724      printf ("%x ", val & 0xff);
1725#endif
1726      *buf++ = val;
1727      break;
1728    case 4:
1729#ifdef SHOW_NUM
1730      printf ("%x ", val >> 24 & 0xff);
1731#endif
1732      *buf++ = (val >> 24);
1733#ifdef SHOW_NUM
1734      printf ("%x ", val >> 16 & 0xff);
1735#endif
1736      *buf++ = (val >> 16);
1737#ifdef SHOW_NUM
1738      printf ("%x ", val >> 8 & 0xff);
1739#endif
1740      *buf++ = (val >> 8);
1741#ifdef SHOW_NUM
1742      printf ("%x ", val & 0xff);
1743#endif
1744      *buf++ = val;
1745      break;
1746    default:
1747      as_fatal ("Internal logic error. line %s, file \"%s\"", __LINE__, __FILE__);
1748    }
1749}
1750
1751/* Translate internal representation of relocation info into target format.
1752
1753   OVE: on a ns32k the twiddling continues at an even deeper level
1754   here we have to distinguish between displacements and immediates.
1755
1756   The sequent has a bit for this. It also has a bit for relocobjects that
1757   points at the target for a bsr (BranchSubRoutine) !?!?!?!
1758
1759   This md_ri.... is tailored for sequent.
1760   */
1761
1762#ifdef comment
1763void
1764md_ri_to_chars (the_bytes, ri)
1765     char *the_bytes;
1766     struct reloc_info_generic *ri;
1767{
1768  if (ri->r_bsr)
1769    {
1770      ri->r_pcrel = 0;
1771    }				/* sequent seems to want this */
1772  md_number_to_chars (the_bytes, ri->r_address, sizeof (ri->r_address));
1773  md_number_to_chars (the_bytes + 4, ((long) (ri->r_symbolnum)
1774				      | (long) (ri->r_pcrel << 24)
1775				      | (long) (ri->r_length << 25)
1776				      | (long) (ri->r_extern << 27)
1777				      | (long) (ri->r_bsr << 28)
1778				      | (long) (ri->r_disp << 29)),
1779		      4);
1780  /* the first and second md_number_to_chars never overlaps (32bit cpu case) */
1781}
1782
1783#endif /* comment */
1784
1785/* fast bitfiddling support */
1786/* mask used to zero bitfield before oring in the true field */
1787
1788static unsigned long l_mask[] =
1789{
1790  0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
1791  0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
1792  0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
1793  0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
1794  0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
1795  0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
1796  0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
1797  0xf0000000, 0xe0000000, 0xc0000000, 0x80000000,
1798};
1799static unsigned long r_mask[] =
1800{
1801  0x00000000, 0x00000001, 0x00000003, 0x00000007,
1802  0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
1803  0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
1804  0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
1805  0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
1806  0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
1807  0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
1808  0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
1809};
1810#define MASK_BITS 31
1811/* Insert bitfield described by field_ptr and val at buf
1812   This routine is written for modification of the first 4 bytes pointed
1813   to by buf, to yield speed.
1814   The ifdef stuff is for selection between a ns32k-dependent routine
1815   and a general version. (My advice: use the general version!)
1816   */
1817
1818static void
1819md_number_to_field (buf, val, field_ptr)
1820     register char *buf;
1821     register long val;
1822     register bit_fixS *field_ptr;
1823{
1824  register unsigned long object;
1825  register unsigned long mask;
1826  /* define ENDIAN on a ns32k machine */
1827#ifdef ENDIAN
1828  register unsigned long *mem_ptr;
1829#else
1830  register char *mem_ptr;
1831#endif
1832  if (field_ptr->fx_bit_min <= val && val <= field_ptr->fx_bit_max)
1833    {
1834#ifdef ENDIAN
1835      if (field_ptr->fx_bit_base)
1836	{			/* override buf */
1837	  mem_ptr = (unsigned long *) field_ptr->fx_bit_base;
1838	}
1839      else
1840	{
1841	  mem_ptr = (unsigned long *) buf;
1842	}
1843      mem_ptr = ((unsigned long *)
1844		 ((char *) mem_ptr + field_ptr->fx_bit_base_adj));
1845#else
1846      if (field_ptr->fx_bit_base)
1847	{			/* override buf */
1848	  mem_ptr = (char *) field_ptr->fx_bit_base;
1849	}
1850      else
1851	{
1852	  mem_ptr = buf;
1853	}
1854      mem_ptr += field_ptr->fx_bit_base_adj;
1855#endif
1856#ifdef ENDIAN			/* we have a nice ns32k machine with lowbyte at low-physical mem */
1857      object = *mem_ptr;	/* get some bytes */
1858#else /* OVE Goof! the machine is a m68k or dito */
1859      /* That takes more byte fiddling */
1860      object = 0;
1861      object |= mem_ptr[3] & 0xff;
1862      object <<= 8;
1863      object |= mem_ptr[2] & 0xff;
1864      object <<= 8;
1865      object |= mem_ptr[1] & 0xff;
1866      object <<= 8;
1867      object |= mem_ptr[0] & 0xff;
1868#endif
1869      mask = 0;
1870      mask |= (r_mask[field_ptr->fx_bit_offset]);
1871      mask |= (l_mask[field_ptr->fx_bit_offset + field_ptr->fx_bit_size]);
1872      object &= mask;
1873      val += field_ptr->fx_bit_add;
1874      object |= ((val << field_ptr->fx_bit_offset) & (mask ^ 0xffffffff));
1875#ifdef ENDIAN
1876      *mem_ptr = object;
1877#else
1878      mem_ptr[0] = (char) object;
1879      object >>= 8;
1880      mem_ptr[1] = (char) object;
1881      object >>= 8;
1882      mem_ptr[2] = (char) object;
1883      object >>= 8;
1884      mem_ptr[3] = (char) object;
1885#endif
1886    }
1887  else
1888    {
1889      as_warn ("Bit field out of range");
1890    }
1891}
1892
1893int md_pcrel_adjust (fragS *fragP)
1894{
1895  fragS *opcode_frag;
1896  int ret;
1897  int st = fragP->fr_subtype;
1898  unsigned int opcode_address;
1899  if ((st >> 2) == BRANCH && fragP->fr_pcrel_adjust == 0) {
1900    unsigned int offset;
1901    opcode_frag = ((struct opcode_location *) fragP->fr_opcode)->fragP;
1902    offset = ((struct opcode_location *) fragP->fr_opcode)->offset;
1903    opcode_address = offset + opcode_frag->fr_address;
1904    ret = fragP->fr_address - opcode_address;
1905  }
1906  else
1907    ret = fragP->fr_pcrel_adjust;
1908  return ret;
1909}
1910
1911int md_fix_pcrel_adjust (fixS *fixP)
1912{
1913  fragS *fragP = fixP->fx_frag;
1914  fragS *opcode_frag;
1915  int ret;
1916  int st = fragP->fr_subtype;
1917  unsigned int opcode_address;
1918  if (fixP->fx_pcrel && fixP->fx_pcrel_adjust == 0) {
1919    unsigned int offset;
1920    opcode_frag = ((struct opcode_location *) fragP->fr_opcode)->fragP;
1921    offset = ((struct opcode_location *) fragP->fr_opcode)->offset;
1922    opcode_address = offset + opcode_frag->fr_address;
1923    ret = fragP->fr_address - opcode_address;
1924  }
1925  else
1926    ret = fixP->fx_pcrel_adjust;
1927  return ret;
1928}
1929
1930/* Apply a fixS (fixup of an instruction or data that we didn't have
1931   enough info to complete immediately) to the data in a frag.
1932
1933   On the ns32k, everything is in a different format, so we have broken
1934   out separate functions for each kind of thing we could be fixing.
1935   They all get called from here.  */
1936
1937#ifdef BFD_ASSEMBLER
1938int
1939md_apply_fix (fixP, valp)
1940     fixS *fixP;
1941     valueT *valp;
1942#else
1943void
1944md_apply_fix (fixP, val)
1945     fixS *fixP;
1946     long val;
1947#endif
1948{
1949#ifdef BFD_ASSEMBLER
1950  long val = *valp;
1951#endif
1952  fragS *fragP = fixP->fx_frag;
1953
1954  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1955
1956  if (fixP->fx_bit_fixP)
1957    {				/* Bitfields to fix, sigh */
1958      md_number_to_field (buf, val, fixP->fx_bit_fixP);
1959    }
1960  else
1961    switch (fixP->fx_im_disp)
1962      {
1963
1964      case 0:			/* Immediate field */
1965	md_number_to_imm (buf, val, fixP->fx_size);
1966	break;
1967
1968      case 1:			/* Displacement field */
1969	/* Calculate offset */
1970	{
1971	md_number_to_disp (buf,
1972			     fixP->fx_pcrel ? val + md_fix_pcrel_adjust(fixP): val,
1973			   fixP->fx_size);
1974	}
1975	break;
1976
1977      case 2:			/* Pointer in a data object */
1978	md_number_to_chars (buf, val, fixP->fx_size);
1979	break;
1980      }
1981#ifdef BSD_ASSEMBLER
1982  return 1;
1983#endif
1984}
1985
1986/* Convert a relaxed displacement to ditto in final output */
1987
1988#ifndef BFD_ASSEMBLER
1989void
1990md_convert_frag (headers, sec, fragP)
1991     object_headers *headers;
1992     segT sec;
1993     register fragS *fragP;
1994#else
1995void
1996md_convert_frag (abfd, sec, fragP)
1997     bfd *abfd;
1998     segT sec;
1999     register fragS *fragP;
2000#endif
2001{
2002  long disp;
2003  long ext = 0;
2004
2005  /* Address in gas core of the place to store the displacement.  */
2006  register char *buffer_address = fragP->fr_fix + fragP->fr_literal;
2007  /* Address in object code of the displacement.  */
2008  int object_address;
2009
2010  fragS *opcode_frag;
2011
2012  switch (fragP->fr_subtype)
2013    {
2014    case IND (BRANCH, BYTE):
2015      ext = 1;
2016      break;
2017    case IND (BRANCH, WORD):
2018      ext = 2;
2019      break;
2020    case IND (BRANCH, DOUBLE):
2021      ext = 4;
2022      break;
2023    }
2024
2025  if(ext == 0)
2026    return;
2027
2028  know (fragP->fr_symbol);
2029
2030  object_address = fragP->fr_fix + fragP->fr_address;
2031  /* The displacement of the address, from current location.  */
2032  disp = (S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset) - object_address;
2033#ifdef BFD_ASSEMBLER
2034  disp += fragP->fr_symbol->sy_frag->fr_address;
2035#endif
2036  disp += md_pcrel_adjust(fragP);
2037
2038      md_number_to_disp (buffer_address, (long) disp, (int) ext);
2039      fragP->fr_fix += ext;
2040}
2041
2042/* This function returns the estimated size a variable object will occupy,
2043   one can say that we tries to guess the size of the objects before we
2044   actually know it */
2045
2046int
2047md_estimate_size_before_relax (fragP, segment)
2048     register fragS *fragP;
2049     segT segment;
2050{
2051  int old_fix;
2052  old_fix = fragP->fr_fix;
2053  switch (fragP->fr_subtype)
2054    {
2055    case IND (BRANCH, UNDEF):
2056      if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
2057	{
2058	  /* the symbol has been assigned a value */
2059	  fragP->fr_subtype = IND (BRANCH, BYTE);
2060	}
2061      else
2062	{
2063	  /* we don't relax symbols defined in an other segment
2064		       the thing to do is to assume the object will occupy 4 bytes */
2065	  fix_new_ns32k (fragP,
2066			 (int) (fragP->fr_fix),
2067			 4,
2068			 fragP->fr_symbol,
2069			 fragP->fr_offset,
2070			 1,
2071			 fragP->fr_pcrel_adjust,
2072			 1,
2073			 0,
2074			 fragP->fr_bsr);	/*sequent hack */
2075	  fragP->fr_fix += 4;
2076	  /* fragP->fr_opcode[1]=0xff; */
2077	  frag_wane (fragP);
2078	  break;
2079	}
2080    case IND (BRANCH, BYTE):
2081      fragP->fr_var += 1;
2082      break;
2083    default:
2084      break;
2085    }
2086  return fragP->fr_var + fragP->fr_fix - old_fix;
2087}
2088
2089int md_short_jump_size = 3;
2090int md_long_jump_size = 5;
2091const int md_reloc_size = 8;	/* Size of relocation record */
2092
2093void
2094md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
2095     char *ptr;
2096     addressT from_addr, to_addr;
2097     fragS *frag;
2098     symbolS *to_symbol;
2099{
2100  valueT offset;
2101
2102  offset = to_addr - from_addr;
2103  md_number_to_chars (ptr, (valueT) 0xEA, 1);
2104  md_number_to_disp (ptr + 1, (valueT) offset, 2);
2105}
2106
2107void
2108md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
2109     char *ptr;
2110     addressT from_addr, to_addr;
2111     fragS *frag;
2112     symbolS *to_symbol;
2113{
2114  valueT offset;
2115
2116  offset = to_addr - from_addr;
2117  md_number_to_chars (ptr, (valueT) 0xEA, 1);
2118  md_number_to_disp (ptr + 1, (valueT) offset, 4);
2119}
2120
2121CONST char *md_shortopts = "m:";
2122struct option md_longopts[] = {
2123  {NULL, no_argument, NULL, 0}
2124};
2125size_t md_longopts_size = sizeof(md_longopts);
2126
2127int
2128md_parse_option (c, arg)
2129     int c;
2130     char *arg;
2131{
2132  switch (c)
2133    {
2134    case 'm':
2135      if (!strcmp (arg, "32032"))
2136	{
2137	  cpureg = cpureg_032;
2138	  mmureg = mmureg_032;
2139	}
2140      else if (!strcmp (arg, "32532"))
2141	{
2142	  cpureg = cpureg_532;
2143	  mmureg = mmureg_532;
2144	}
2145      else
2146	{
2147	  as_bad ("invalid architecture option -m%s", arg);
2148	  return 0;
2149	}
2150      break;
2151
2152    default:
2153      return 0;
2154    }
2155
2156  return 1;
2157}
2158
2159void
2160md_show_usage (stream)
2161     FILE *stream;
2162{
2163  fprintf(stream, "\
2164NS32K options:\n\
2165-m32032 | -m32532	select variant of NS32K architecture\n");
2166}
2167
2168
2169/*
2170 *			bit_fix_new()
2171 *
2172 * Create a bit_fixS in obstack 'notes'.
2173 * This struct is used to profile the normal fix. If the bit_fixP is a
2174 * valid pointer (not NULL) the bit_fix data will be used to format the fix.
2175 */
2176bit_fixS *
2177bit_fix_new (size, offset, min, max, add, base_type, base_adj)
2178     char size;			/* Length of bitfield		*/
2179     char offset;		/* Bit offset to bitfield	*/
2180     long min;			/* Signextended min for bitfield */
2181     long max;			/* Signextended max for bitfield */
2182     long add;			/* Add mask, used for huffman prefix */
2183     long base_type;		/* 0 or 1, if 1 it's exploded to opcode ptr */
2184     long base_adj;
2185{
2186  register bit_fixS *bit_fixP;
2187
2188  bit_fixP = (bit_fixS *) obstack_alloc (&notes, sizeof (bit_fixS));
2189
2190  bit_fixP->fx_bit_size = size;
2191  bit_fixP->fx_bit_offset = offset;
2192  bit_fixP->fx_bit_base = base_type;
2193  bit_fixP->fx_bit_base_adj = base_adj;
2194  bit_fixP->fx_bit_max = max;
2195  bit_fixP->fx_bit_min = min;
2196  bit_fixP->fx_bit_add = add;
2197
2198  return (bit_fixP);
2199}
2200
2201void
2202fix_new_ns32k (frag, where, size, add_symbol, offset, pcrel,
2203	       pcrel_adjust, im_disp, bit_fixP, bsr)
2204     fragS *frag;		/* Which frag? */
2205     int where;			/* Where in that frag? */
2206     int size;			/* 1, 2  or 4 usually. */
2207     symbolS *add_symbol;	/* X_add_symbol. */
2208     long offset;		/* X_add_number. */
2209     int pcrel;			/* TRUE if PC-relative relocation. */
2210     char pcrel_adjust;		/* not zero if adjustment of pcrel offset is needed */
2211     char im_disp;		/* true if the value to write is a displacement */
2212     bit_fixS *bit_fixP;	/* pointer at struct of bit_fix's, ignored if NULL */
2213     char bsr;			/* sequent-linker-hack: 1 when relocobject is a bsr */
2214
2215{
2216  fixS *fixP = fix_new (frag, where, size, add_symbol,
2217			offset, pcrel,
2218#ifdef BFD_ASSEMBLER
2219			bit_fixP? NO_RELOC: reloc(size, pcrel, im_disp)
2220#else
2221			NO_RELOC
2222#endif
2223			);
2224
2225  fixP->fx_pcrel_adjust = pcrel_adjust;
2226  fixP->fx_im_disp = im_disp;
2227  fixP->fx_bit_fixP = bit_fixP;
2228  fixP->fx_bsr = bsr;
2229}				/* fix_new_ns32k() */
2230
2231void
2232fix_new_ns32k_exp (frag, where, size, exp, pcrel,
2233		   pcrel_adjust, im_disp, bit_fixP, bsr)
2234     fragS *frag;		/* Which frag? */
2235     int where;			/* Where in that frag? */
2236     int size;			/* 1, 2  or 4 usually. */
2237     expressionS *exp;		/* Expression. */
2238     int pcrel;			/* TRUE if PC-relative relocation. */
2239     char pcrel_adjust;		/* not zero if adjustment of pcrel offset is needed */
2240     char im_disp;		/* true if the value to write is a displacement */
2241     bit_fixS *bit_fixP;	/* pointer at struct of bit_fix's, ignored if NULL */
2242     char bsr;			/* sequent-linker-hack: 1 when relocobject is a bsr */
2243{
2244  fixS *fixP = fix_new_exp (frag, where, size, exp, pcrel,
2245#ifdef BFD_ASSEMBLER
2246			    bit_fixP? NO_RELOC: reloc(size, pcrel, im_disp)
2247#else
2248			    NO_RELOC
2249#endif
2250			    );
2251
2252  fixP->fx_pcrel_adjust = pcrel_adjust;
2253  fixP->fx_im_disp = im_disp;
2254  fixP->fx_bit_fixP = bit_fixP;
2255  fixP->fx_bsr = bsr;
2256}				/* fix_new_ns32k() */
2257
2258/* This is TC_CONS_FIX_NEW, called by emit_expr in read.c.  */
2259
2260void
2261cons_fix_new_ns32k (frag, where, size, exp)
2262     fragS *frag;		/* Which frag? */
2263     int where;			/* Where in that frag? */
2264     int size;			/* 1, 2  or 4 usually. */
2265     expressionS *exp;		/* Expression. */
2266{
2267  fix_new_ns32k_exp (frag, where, size, exp,
2268		     0, 0, 2, 0, 0);
2269}
2270
2271/* We have no need to default values of symbols.  */
2272
2273symbolS *
2274md_undefined_symbol (name)
2275     char *name;
2276{
2277  return 0;
2278}
2279
2280/* Round up a section size to the appropriate boundary.  */
2281valueT
2282md_section_align (segment, size)
2283     segT segment;
2284     valueT size;
2285{
2286  return size;			/* Byte alignment is fine */
2287}
2288
2289/* Exactly what point is a PC-relative offset relative TO?
2290   On the National warts, they're relative to the address of the offset,
2291   with some funny adjustments in some circumstances during blue moons.
2292   (??? Is this right?  FIXME-SOON) */
2293long
2294md_pcrel_from (fixP)
2295     fixS *fixP;
2296{
2297  long res;
2298  res = fixP->fx_where + fixP->fx_frag->fr_address;
2299#ifdef SEQUENT_COMPATABILITY
2300  if (fixP->fx_frag->fr_bsr)
2301    res += 0x12			/* FOO Kludge alert! */
2302#endif
2303      return res;
2304}
2305
2306#ifdef BFD_ASSEMBLER
2307
2308arelent *
2309tc_gen_reloc (section, fixp)
2310     asection *section;
2311     fixS *fixp;
2312{
2313  arelent *rel;
2314  bfd_reloc_code_real_type code;
2315
2316  code = reloc(fixp->fx_size, fixp->fx_pcrel, fixp->fx_im_disp);
2317
2318  rel = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
2319  assert (rel != 0);
2320  rel->sym_ptr_ptr = &fixp->fx_addsy->bsym;
2321  rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
2322  if (fixp->fx_pcrel)
2323    rel->addend = fixp->fx_addnumber;
2324  else
2325    rel->addend = 0;
2326
2327  rel->howto = bfd_reloc_type_lookup (stdoutput, code);
2328  if (!rel->howto)
2329    {
2330      const char *name;
2331
2332      name = S_GET_NAME (fixp->fx_addsy);
2333      if (name == NULL)
2334	name = "<unknown>";
2335      as_fatal ("Cannot find relocation type for symbol %s, code %d",
2336		name, (int) code);
2337    }
2338
2339  return rel;
2340}
2341#else /* BFD_ASSEMBLER */
2342
2343#ifdef OBJ_AOUT
2344void
2345tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
2346     char *where;
2347     struct fix *fixP;
2348     relax_addressT segment_address_in_file;
2349{
2350  /*
2351   * In: length of relocation (or of address) in chars: 1, 2 or 4.
2352   * Out: GNU LD relocation length code: 0, 1, or 2.
2353   */
2354
2355  static unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2};
2356  long r_symbolnum;
2357
2358  know (fixP->fx_addsy != NULL);
2359
2360  md_number_to_chars (where,
2361       fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
2362		      4);
2363
2364  r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
2365		 ? S_GET_TYPE (fixP->fx_addsy)
2366		 : fixP->fx_addsy->sy_number);
2367
2368  md_number_to_chars (where + 4,
2369		      ((long) (r_symbolnum)
2370		       | (long) (fixP->fx_pcrel << 24)
2371		       | (long) (nbytes_r_length[fixP->fx_size] << 25)
2372		       | (long) ((!S_IS_DEFINED (fixP->fx_addsy)) << 27)
2373		       | (long) (fixP->fx_bsr << 28)
2374		       | (long) (fixP->fx_im_disp << 29)),
2375		      4);
2376}
2377
2378#endif /* OBJ_AOUT */
2379#endif /* BFD_ASSMEBLER */
2380/*
2381 * Local Variables:
2382 * comment-column: 0
2383 * End:
2384 */
2385
2386/* end of tc-ns32k.c */
2387