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