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