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