OSDN Git Service

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