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