]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-ns32k.c
Convert unmaintained files over to ISO-C90 and fix formatting.
[thirdparty/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,
aef6203b 3 2001, 2002, 2003, 2005
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) \
ea1562b3
NC
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;
252b5132
RH
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
ea1562b3
NC
73{
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
4eb6b71c 78 floating-point-register. */
ea1562b3 79 char am_size; /* Estimated max size of general addr-mode
4eb6b71c 80 parts. */
ea1562b3
NC
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)
4eb6b71c 85 or immediates(s) (ascii). */
ea1562b3
NC
86 char index_byte; /* Index byte. */
87};
252b5132
RH
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
ea1562b3
NC
115{
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
4eb6b71c 122 start to the displacement. */
ea1562b3
NC
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
4eb6b71c 127 iif-entry. */
ea1562b3
NC
128 char bsr; /* Sequent hack. */
129} iif_entryT; /* Internal Instruction Format. */
252b5132
RH
130
131struct int_ins_form
ea1562b3
NC
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
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
67c1ffbe 179 The low-order-byte corresponds to low physical memory.
c6a7ab1f
NC
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.
67c1ffbe 335 The ns32k uses the beginning of the instruction as displacement
252b5132
RH
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
c6a7ab1f
NC
370/* Parse a general operand into an addressingmode struct
371
372 In: pointer at operand in ascii form
373 pointer at addr_mode struct for result
374 the level of recursion. (always 0 or 1)
252b5132 375
c6a7ab1f 376 Out: data in addr_mode struct. */
252b5132 377
4eb6b71c 378static int
ea1562b3
NC
379addr_mode (char *operand,
380 addr_modeS *addr_modeP,
381 int recursive_level)
252b5132 382{
4eb6b71c
NC
383 char *str;
384 int i;
385 int strl;
386 int mode;
252b5132 387 int j;
0b7410c4 388
4eb6b71c
NC
389 mode = DEFAULT; /* Default. */
390 addr_modeP->scaled_mode = 0; /* Why not. */
391 addr_modeP->scaled_reg = 0; /* If 0, not scaled index. */
252b5132
RH
392 addr_modeP->float_flag = 0;
393 addr_modeP->am_size = 0;
394 addr_modeP->im_disp = 0;
4eb6b71c 395 addr_modeP->pcrel = 0; /* Not set in this function. */
252b5132
RH
396 addr_modeP->disp_suffix[0] = 0;
397 addr_modeP->disp_suffix[1] = 0;
398 addr_modeP->disp[0] = NULL;
399 addr_modeP->disp[1] = NULL;
400 str = operand;
0b7410c4 401
252b5132 402 if (str[0] == 0)
c6a7ab1f
NC
403 return 0;
404
252b5132 405 strl = strlen (str);
0b7410c4 406
252b5132
RH
407 switch (str[0])
408 {
c6a7ab1f
NC
409 /* The following three case statements controls the mode-chars
410 this is the place to ed if you want to change them. */
252b5132
RH
411#ifdef ABSOLUTE_PREFIX
412 case ABSOLUTE_PREFIX:
413 if (str[strl - 1] == ']')
414 break;
415 addr_modeP->mode = 21; /* absolute */
416 addr_modeP->disp[0] = str + 1;
c6a7ab1f 417 return -1;
252b5132
RH
418#endif
419#ifdef IMMEDIATE_PREFIX
420 case IMMEDIATE_PREFIX:
421 if (str[strl - 1] == ']')
422 break;
423 addr_modeP->mode = 20; /* immediate */
424 addr_modeP->disp[0] = str + 1;
c6a7ab1f 425 return -1;
252b5132
RH
426#endif
427 case '.':
428 if (str[strl - 1] != ']')
429 {
430 switch (str[1])
431 {
432 case '-':
433 case '+':
434 if (str[2] != '\000')
435 {
67c1ffbe 436 addr_modeP->mode = 27; /* pc-relative */
252b5132 437 addr_modeP->disp[0] = str + 2;
c6a7ab1f 438 return -1;
252b5132
RH
439 }
440 default:
4eb6b71c 441 as_bad (_("Invalid syntax in PC-relative addressing mode"));
c6a7ab1f 442 return 0;
252b5132
RH
443 }
444 }
445 break;
446 case 'e':
447 if (str[strl - 1] != ']')
448 {
449 if ((!strncmp (str, "ext(", 4)) && strl > 7)
450 { /* external */
451 addr_modeP->disp[0] = str + 4;
452 i = 0;
453 j = 2;
454 do
4eb6b71c 455 { /* disp[0]'s termination point. */
252b5132
RH
456 j += 1;
457 if (str[j] == '(')
458 i++;
459 if (str[j] == ')')
460 i--;
461 }
462 while (j < strl && i != 0);
463 if (i != 0 || !(str[j + 1] == '-' || str[j + 1] == '+'))
464 {
4eb6b71c 465 as_bad (_("Invalid syntax in External addressing mode"));
252b5132
RH
466 return (0);
467 }
468 str[j] = '\000'; /* null terminate disp[0] */
469 addr_modeP->disp[1] = str + j + 2;
470 addr_modeP->mode = 22;
c6a7ab1f 471 return -1;
252b5132
RH
472 }
473 }
474 break;
0b7410c4 475
c6a7ab1f
NC
476 default:
477 ;
252b5132 478 }
0b7410c4 479
252b5132 480 strl = strlen (str);
0b7410c4 481
252b5132
RH
482 switch (strl)
483 {
484 case 2:
485 switch (str[0])
486 {
487 case 'f':
488 addr_modeP->float_flag = 1;
c6a7ab1f 489 /* Drop through. */
252b5132
RH
490 case 'r':
491 if (str[1] >= '0' && str[1] < '8')
492 {
493 addr_modeP->mode = str[1] - '0';
c6a7ab1f 494 return -1;
252b5132 495 }
c6a7ab1f
NC
496 break;
497 default:
498 break;
252b5132 499 }
c6a7ab1f 500 /* Drop through. */
0b7410c4 501
252b5132
RH
502 case 3:
503 if (!strncmp (str, "tos", 3))
504 {
505 addr_modeP->mode = 23; /* TopOfStack */
c6a7ab1f 506 return -1;
252b5132 507 }
c6a7ab1f 508 break;
0b7410c4 509
c6a7ab1f
NC
510 default:
511 break;
252b5132 512 }
0b7410c4 513
252b5132
RH
514 if (strl > 4)
515 {
516 if (str[strl - 1] == ')')
517 {
518 if (str[strl - 2] == ')')
519 {
520 if (!strncmp (&str[strl - 5], "(fp", 3))
c6a7ab1f
NC
521 mode = 16; /* Memory Relative. */
522 else if (!strncmp (&str[strl - 5], "(sp", 3))
523 mode = 17;
524 else if (!strncmp (&str[strl - 5], "(sb", 3))
525 mode = 18;
526
252b5132 527 if (mode != DEFAULT)
4eb6b71c
NC
528 {
529 /* Memory relative. */
252b5132 530 addr_modeP->mode = mode;
c6a7ab1f 531 j = strl - 5; /* Temp for end of disp[0]. */
252b5132 532 i = 0;
0b7410c4 533
252b5132
RH
534 do
535 {
536 strl -= 1;
537 if (str[strl] == ')')
538 i++;
539 if (str[strl] == '(')
540 i--;
541 }
542 while (strl > -1 && i != 0);
0b7410c4 543
252b5132
RH
544 if (i != 0)
545 {
4eb6b71c 546 as_bad (_("Invalid syntax in Memory Relative addressing mode"));
252b5132
RH
547 return (0);
548 }
0b7410c4 549
252b5132
RH
550 addr_modeP->disp[1] = str;
551 addr_modeP->disp[0] = str + strl + 1;
0b7410c4 552 str[j] = '\000'; /* Null terminate disp[0] . */
c6a7ab1f 553 str[strl] = '\000'; /* Null terminate disp[1]. */
0b7410c4 554
c6a7ab1f 555 return -1;
252b5132
RH
556 }
557 }
0b7410c4 558
252b5132
RH
559 switch (str[strl - 3])
560 {
561 case 'r':
562 case 'R':
563 if (str[strl - 2] >= '0'
564 && str[strl - 2] < '8'
565 && str[strl - 4] == '(')
566 {
567 addr_modeP->mode = str[strl - 2] - '0' + 8;
568 addr_modeP->disp[0] = str;
569 str[strl - 4] = 0;
c6a7ab1f 570 return -1; /* reg rel */
252b5132 571 }
c6a7ab1f 572 /* Drop through. */
0b7410c4 573
252b5132
RH
574 default:
575 if (!strncmp (&str[strl - 4], "(fp", 3))
c6a7ab1f
NC
576 mode = 24;
577 else if (!strncmp (&str[strl - 4], "(sp", 3))
578 mode = 25;
579 else if (!strncmp (&str[strl - 4], "(sb", 3))
580 mode = 26;
581 else if (!strncmp (&str[strl - 4], "(pc", 3))
582 mode = 27;
0b7410c4 583
252b5132
RH
584 if (mode != DEFAULT)
585 {
586 addr_modeP->mode = mode;
587 addr_modeP->disp[0] = str;
588 str[strl - 4] = '\0';
0b7410c4 589
c6a7ab1f 590 return -1; /* Memory space. */
252b5132
RH
591 }
592 }
593 }
0b7410c4 594
c6a7ab1f 595 /* No trailing ')' do we have a ']' ? */
252b5132
RH
596 if (str[strl - 1] == ']')
597 {
598 switch (str[strl - 2])
599 {
600 case 'b':
601 mode = 28;
602 break;
603 case 'w':
604 mode = 29;
605 break;
606 case 'd':
607 mode = 30;
608 break;
609 case 'q':
610 mode = 31;
611 break;
c6a7ab1f 612 default:
4eb6b71c 613 as_bad (_("Invalid scaled-indexed mode, use (b,w,d,q)"));
0b7410c4 614
252b5132
RH
615 if (str[strl - 3] != ':' || str[strl - 6] != '['
616 || str[strl - 5] == 'r' || str[strl - 4] < '0'
617 || str[strl - 4] > '7')
4eb6b71c 618 as_bad (_("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}"));
c6a7ab1f
NC
619 } /* Scaled index. */
620
621 if (recursive_level > 0)
622 {
4eb6b71c 623 as_bad (_("Scaled-indexed addressing mode combined with scaled-index"));
c6a7ab1f
NC
624 return 0;
625 }
0b7410c4 626
4eb6b71c
NC
627 addr_modeP->am_size += 1; /* scaled index byte. */
628 j = str[strl - 4] - '0'; /* store temporary. */
629 str[strl - 6] = '\000'; /* nullterminate for recursive call. */
c6a7ab1f 630 i = addr_mode (str, addr_modeP, 1);
0b7410c4 631
c6a7ab1f
NC
632 if (!i || addr_modeP->mode == 20)
633 {
4eb6b71c 634 as_bad (_("Invalid or illegal addressing mode combined with scaled-index"));
c6a7ab1f
NC
635 return 0;
636 }
0b7410c4 637
c6a7ab1f
NC
638 addr_modeP->scaled_mode = addr_modeP->mode; /* Store the inferior mode. */
639 addr_modeP->mode = mode;
640 addr_modeP->scaled_reg = j + 1;
0b7410c4 641
c6a7ab1f 642 return -1;
252b5132
RH
643 }
644 }
0b7410c4 645
c6a7ab1f 646 addr_modeP->mode = DEFAULT; /* Default to whatever. */
252b5132 647 addr_modeP->disp[0] = str;
0b7410c4 648
c6a7ab1f 649 return -1;
252b5132
RH
650}
651\f
ea1562b3
NC
652static void
653evaluate_expr (expressionS *resultP, char *ptr)
654{
655 char *tmp_line;
656
657 tmp_line = input_line_pointer;
658 input_line_pointer = ptr;
659 expression (resultP);
660 input_line_pointer = tmp_line;
661}
662
252b5132
RH
663/* ptr points at string addr_modeP points at struct with result This
664 routine calls addr_mode to determine the general addr.mode of the
665 operand. When this is ready it parses the displacements for size
666 specifying suffixes and determines size of immediate mode via
667 ns32k-opcode. Also builds index bytes if needed. */
c6a7ab1f 668
4eb6b71c 669static int
ea1562b3 670get_addr_mode (char *ptr, addr_modeS *addr_modeP)
252b5132
RH
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 {
67c1ffbe 678 /* Resolve ambiguous operands, this shouldn't be necessary if
252b5132 679 one uses standard NSC operand syntax. But the sequent
67c1ffbe 680 compiler doesn't!!! This finds a proper addressing 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 804static void
ea1562b3
NC
805optlist (char *str, /* The string to extract options from. */
806 struct ns32k_option *optionP, /* How to search the string. */
807 unsigned long *default_map) /* Default pattern and output. */
252b5132 808{
4eb6b71c
NC
809 int i, j, k, strlen1, strlen2;
810 char *patternP, *strP;
0b7410c4 811
252b5132 812 strlen1 = strlen (str);
0b7410c4 813
252b5132 814 if (strlen1 < 1)
c6a7ab1f 815 as_fatal (_("Very short instr to option, ie you can't do it on a NULLstr"));
0b7410c4 816
252b5132
RH
817 for (i = 0; optionP[i].pattern != 0; i++)
818 {
819 strlen2 = strlen (optionP[i].pattern);
0b7410c4 820
252b5132
RH
821 for (j = 0; j < strlen1; j++)
822 {
823 patternP = optionP[i].pattern;
824 strP = &str[j];
0b7410c4 825
252b5132
RH
826 for (k = 0; k < strlen2; k++)
827 {
828 if (*(strP++) != *(patternP++))
829 break;
830 }
0b7410c4 831
252b5132
RH
832 if (k == strlen2)
833 { /* match */
834 *default_map |= optionP[i].or;
835 *default_map &= optionP[i].and;
836 }
837 }
838 }
839}
840
c6a7ab1f 841/* Search struct for symbols.
252b5132
RH
842 This function is used to get the short integer form of reg names in
843 the instructions lmr, smr, lpr, spr return true if str is found in
c6a7ab1f 844 list. */
252b5132 845
4eb6b71c 846static int
ea1562b3
NC
847list_search (char *str, /* The string to match. */
848 struct ns32k_option *optionP, /* List to search. */
849 unsigned long *default_map) /* Default pattern and output. */
252b5132 850{
4eb6b71c 851 int i;
0b7410c4 852
252b5132
RH
853 for (i = 0; optionP[i].pattern != 0; i++)
854 {
855 if (!strncmp (optionP[i].pattern, str, 20))
c6a7ab1f
NC
856 {
857 /* Use strncmp to be safe. */
252b5132
RH
858 *default_map |= optionP[i].or;
859 *default_map &= optionP[i].and;
0b7410c4 860
252b5132
RH
861 return -1;
862 }
863 }
0b7410c4 864
4eb6b71c 865 as_bad (_("No such entry in list. (cpu/mmu register)"));
252b5132
RH
866 return 0;
867}
ea1562b3
NC
868\f
869/* Create a bit_fixS in obstack 'notes'.
870 This struct is used to profile the normal fix. If the bit_fixP is a
871 valid pointer (not NULL) the bit_fix data will be used to format
872 the fix. */
252b5132 873
ea1562b3
NC
874static bit_fixS *
875bit_fix_new (int size, /* Length of bitfield. */
876 int offset, /* Bit offset to bitfield. */
877 long min, /* Signextended min for bitfield. */
878 long max, /* Signextended max for bitfield. */
879 long add, /* Add mask, used for huffman prefix. */
880 long base_type, /* 0 or 1, if 1 it's exploded to opcode ptr. */
881 long base_adj)
252b5132 882{
ea1562b3 883 bit_fixS *bit_fixP;
252b5132 884
ea1562b3
NC
885 bit_fixP = (bit_fixS *) obstack_alloc (&notes, sizeof (bit_fixS));
886
887 bit_fixP->fx_bit_size = size;
888 bit_fixP->fx_bit_offset = offset;
889 bit_fixP->fx_bit_base = base_type;
890 bit_fixP->fx_bit_base_adj = base_adj;
891 bit_fixP->fx_bit_max = max;
892 bit_fixP->fx_bit_min = min;
893 bit_fixP->fx_bit_add = add;
894
895 return bit_fixP;
252b5132 896}
ea1562b3 897
252b5132
RH
898/* Convert operands to iif-format and adds bitfields to the opcode.
899 Operands are parsed in such an order that the opcode is updated from
900 its most significant bit, that is when the operand need to alter the
901 opcode.
67c1ffbe 902 Be careful not to put to objects in the same iif-slot. */
252b5132 903
4eb6b71c 904static void
ea1562b3
NC
905encode_operand (int argc,
906 char **argv,
907 const char *operandsP,
908 const char *suffixP,
909 char im_size ATTRIBUTE_UNUSED,
910 char opcode_bit_ptr)
252b5132 911{
4eb6b71c 912 int i, j;
252b5132 913 char d;
4eb6b71c
NC
914 int pcrel, b, loop, pcrel_adjust;
915 unsigned long tmp;
0b7410c4 916
252b5132
RH
917 for (loop = 0; loop < argc; loop++)
918 {
c6a7ab1f
NC
919 /* What operand are we supposed to work on. */
920 i = operandsP[loop << 1] - '1';
252b5132
RH
921 if (i > 3)
922 as_fatal (_("Internal consistency error. check ns32k-opcode.h"));
0b7410c4 923
252b5132
RH
924 pcrel = 0;
925 pcrel_adjust = 0;
926 tmp = 0;
0b7410c4 927
252b5132
RH
928 switch ((d = operandsP[(loop << 1) + 1]))
929 {
4eb6b71c
NC
930 case 'f': /* Operand of sfsr turns out to be a nasty
931 specialcase. */
252b5132 932 opcode_bit_ptr -= 5;
4eb6b71c
NC
933 case 'Z': /* Float not immediate. */
934 case 'F': /* 32 bit float general form. */
935 case 'L': /* 64 bit float. */
936 case 'I': /* Integer not immediate. */
937 case 'B': /* Byte */
938 case 'W': /* Word */
939 case 'D': /* Double-word. */
940 case 'A': /* Double-word gen-address-form ie no regs
941 allowed. */
252b5132 942 get_addr_mode (argv[i], &addr_modeP);
0b7410c4 943
c6a7ab1f
NC
944 if ((addr_modeP.mode == 20) &&
945 (d == 'I' || d == 'Z' || d == 'A'))
946 as_fatal (d == 'A'? _("Address of immediate operand"):
947 _("Invalid immediate write operand."));
252b5132
RH
948
949 if (opcode_bit_ptr == desc->opcode_size)
950 b = 4;
951 else
952 b = 6;
0b7410c4 953
252b5132
RH
954 for (j = b; j < (b + 2); j++)
955 {
956 if (addr_modeP.disp[j - b])
957 {
958 IIF (j,
959 2,
960 addr_modeP.disp_suffix[j - b],
961 (unsigned long) addr_modeP.disp[j - b],
962 0,
963 addr_modeP.pcrel,
964 iif.instr_size,
965 addr_modeP.im_disp,
966 IND (BRANCH, BYTE),
967 NULL,
968 (addr_modeP.scaled_reg ? addr_modeP.scaled_mode
969 : addr_modeP.mode),
970 0);
971 }
972 }
0b7410c4 973
252b5132
RH
974 opcode_bit_ptr -= 5;
975 iif.iifP[1].object |= ((long) addr_modeP.mode) << opcode_bit_ptr;
0b7410c4 976
252b5132
RH
977 if (addr_modeP.scaled_reg)
978 {
979 j = b / 2;
980 IIF (j, 1, 1, (unsigned long) addr_modeP.index_byte,
981 0, 0, 0, 0, 0, NULL, -1, 0);
982 }
983 break;
0b7410c4 984
4eb6b71c
NC
985 case 'b': /* Multiple instruction disp. */
986 freeptr++; /* OVE:this is an useful hack. */
987 sprintf (freeptr, "((%s-1)*%d)", argv[i], desc->im_size);
252b5132 988 argv[i] = freeptr;
67c1ffbe 989 pcrel -= 1; /* Make pcrel 0 in spite of what case 'p':
4eb6b71c 990 wants. */
252b5132 991 /* fall thru */
4eb6b71c 992 case 'p': /* Displacement - pc relative addressing. */
252b5132
RH
993 pcrel += 1;
994 /* fall thru */
4eb6b71c 995 case 'd': /* Displacement. */
252b5132
RH
996 iif.instr_size += suffixP[i] ? suffixP[i] : 4;
997 IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
998 pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 0);
999 break;
4eb6b71c
NC
1000 case 'H': /* Sequent-hack: the linker wants a bit set
1001 when bsr. */
252b5132
RH
1002 pcrel = 1;
1003 iif.instr_size += suffixP[i] ? suffixP[i] : 4;
1004 IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
1005 pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 1);
1006 break;
1007 case 'q': /* quick */
1008 opcode_bit_ptr -= 4;
1009 IIF (11, 2, 42, (unsigned long) argv[i], 0, 0, 0, 0, 0,
1010 bit_fix_new (4, opcode_bit_ptr, -8, 7, 0, 1, 0), -1, 0);
1011 break;
4eb6b71c 1012 case 'r': /* Register number (3 bits). */
252b5132
RH
1013 list_search (argv[i], opt6, &tmp);
1014 opcode_bit_ptr -= 3;
1015 iif.iifP[1].object |= tmp << opcode_bit_ptr;
1016 break;
4eb6b71c 1017 case 'O': /* Setcfg instruction optionslist. */
252b5132
RH
1018 optlist (argv[i], opt3, &tmp);
1019 opcode_bit_ptr -= 4;
1020 iif.iifP[1].object |= tmp << 15;
1021 break;
4eb6b71c 1022 case 'C': /* Cinv instruction optionslist. */
252b5132
RH
1023 optlist (argv[i], opt4, &tmp);
1024 opcode_bit_ptr -= 4;
4eb6b71c 1025 iif.iifP[1].object |= tmp << 15; /* Insert the regtype in opcode. */
252b5132 1026 break;
4eb6b71c 1027 case 'S': /* String instruction options list. */
252b5132
RH
1028 optlist (argv[i], opt5, &tmp);
1029 opcode_bit_ptr -= 4;
1030 iif.iifP[1].object |= tmp << 15;
1031 break;
1032 case 'u':
4eb6b71c 1033 case 'U': /* Register list. */
252b5132
RH
1034 IIF (10, 1, 1, 0, 0, 0, 0, 0, 0, NULL, -1, 0);
1035 switch (operandsP[(i << 1) + 1])
1036 {
4eb6b71c 1037 case 'u': /* Restore, exit. */
252b5132
RH
1038 optlist (argv[i], opt1, &iif.iifP[10].object);
1039 break;
4eb6b71c 1040 case 'U': /* Save, enter. */
252b5132
RH
1041 optlist (argv[i], opt2, &iif.iifP[10].object);
1042 break;
1043 }
1044 iif.instr_size += 1;
1045 break;
4eb6b71c 1046 case 'M': /* MMU register. */
252b5132
RH
1047 list_search (argv[i], mmureg, &tmp);
1048 opcode_bit_ptr -= 4;
1049 iif.iifP[1].object |= tmp << opcode_bit_ptr;
1050 break;
4eb6b71c 1051 case 'P': /* CPU register. */
252b5132
RH
1052 list_search (argv[i], cpureg, &tmp);
1053 opcode_bit_ptr -= 4;
1054 iif.iifP[1].object |= tmp << opcode_bit_ptr;
1055 break;
4eb6b71c
NC
1056 case 'g': /* Inss exts. */
1057 iif.instr_size += 1; /* 1 byte is allocated after the opcode. */
252b5132 1058 IIF (10, 2, 1,
4eb6b71c 1059 (unsigned long) argv[i], /* i always 2 here. */
252b5132 1060 0, 0, 0, 0, 0,
4eb6b71c
NC
1061 bit_fix_new (3, 5, 0, 7, 0, 0, 0), /* A bit_fix is targeted to
1062 the byte. */
252b5132
RH
1063 -1, 0);
1064 break;
1065 case 'G':
1066 IIF (11, 2, 42,
4eb6b71c 1067 (unsigned long) argv[i], /* i always 3 here. */
252b5132
RH
1068 0, 0, 0, 0, 0,
1069 bit_fix_new (5, 0, 1, 32, -1, 0, -1), -1, 0);
1070 break;
1071 case 'i':
1072 iif.instr_size += 1;
4eb6b71c 1073 b = 2 + i; /* Put the extension byte after opcode. */
252b5132
RH
1074 IIF (b, 2, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0);
1075 break;
1076 default:
1077 as_fatal (_("Bad opcode-table-option, check in file ns32k-opcode.h"));
1078 }
1079 }
1080}
1081\f
1082/* in: instruction line
1083 out: internal structure of instruction
1084 that has been prepared for direct conversion to fragment(s) and
1085 fixes in a systematical fashion
4eb6b71c 1086 Return-value = recursive_level. */
c6a7ab1f
NC
1087/* Build iif of one assembly text line. */
1088
4eb6b71c 1089static int
ea1562b3 1090parse (const char *line, int recursive_level)
252b5132 1091{
4cd62c96
AM
1092 const char *lineptr;
1093 char c, suffix_separator;
4eb6b71c
NC
1094 int i;
1095 unsigned int argc;
1096 int arg_type;
252b5132 1097 char sqr, sep;
c6a7ab1f 1098 char suffix[MAX_ARGS], *argv[MAX_ARGS]; /* No more than 4 operands. */
0b7410c4 1099
252b5132 1100 if (recursive_level <= 0)
c6a7ab1f
NC
1101 {
1102 /* Called from md_assemble. */
1103 for (lineptr = line; (*lineptr) != '\0' && (*lineptr) != ' '; lineptr++)
1104 continue;
0b7410c4 1105
252b5132 1106 c = *lineptr;
4cd62c96 1107 *(char *) lineptr = '\0';
0b7410c4 1108
252b5132 1109 if (!(desc = (struct ns32k_opcode *) hash_find (inst_hash_handle, line)))
c6a7ab1f
NC
1110 as_fatal (_("No such opcode"));
1111
4cd62c96 1112 *(char *) lineptr = c;
252b5132
RH
1113 }
1114 else
ea1562b3 1115 lineptr = line;
0b7410c4 1116
252b5132 1117 argc = 0;
0b7410c4 1118
252b5132
RH
1119 if (*desc->operands)
1120 {
1121 if (*lineptr++ != '\0')
1122 {
1123 sqr = '[';
1124 sep = ',';
0b7410c4 1125
252b5132
RH
1126 while (*lineptr != '\0')
1127 {
1128 if (desc->operands[argc << 1])
1129 {
1130 suffix[argc] = 0;
1131 arg_type = desc->operands[(argc << 1) + 1];
0b7410c4 1132
252b5132
RH
1133 switch (arg_type)
1134 {
1135 case 'd':
1136 case 'b':
1137 case 'p':
c6a7ab1f
NC
1138 case 'H':
1139 /* The operand is supposed to be a displacement. */
252b5132 1140 /* Hackwarning: do not forget to update the 4
c6a7ab1f 1141 cases above when editing ns32k-opcode.h. */
252b5132
RH
1142 suffix_separator = ':';
1143 break;
1144 default:
c6a7ab1f
NC
1145 /* If this char occurs we loose. */
1146 suffix_separator = '\255';
1147 break;
252b5132 1148 }
0b7410c4 1149
4eb6b71c 1150 suffix[argc] = 0; /* 0 when no ':' is encountered. */
252b5132
RH
1151 argv[argc] = freeptr;
1152 *freeptr = '\0';
0b7410c4 1153
252b5132
RH
1154 while ((c = *lineptr) != '\0' && c != sep)
1155 {
1156 if (c == sqr)
1157 {
1158 if (sqr == '[')
1159 {
1160 sqr = ']';
1161 sep = '\0';
1162 }
1163 else
1164 {
1165 sqr = '[';
1166 sep = ',';
1167 }
1168 }
0b7410c4 1169
252b5132 1170 if (c == suffix_separator)
c6a7ab1f
NC
1171 {
1172 /* ':' - label/suffix separator. */
252b5132
RH
1173 switch (lineptr[1])
1174 {
1175 case 'b':
1176 suffix[argc] = 1;
1177 break;
1178 case 'w':
1179 suffix[argc] = 2;
1180 break;
1181 case 'd':
1182 suffix[argc] = 4;
1183 break;
1184 default:
1185 as_warn (_("Bad suffix, defaulting to d"));
1186 suffix[argc] = 4;
1187 if (lineptr[1] == '\0' || lineptr[1] == sep)
1188 {
1189 lineptr += 1;
1190 continue;
1191 }
c6a7ab1f 1192 break;
252b5132 1193 }
0b7410c4 1194
252b5132
RH
1195 lineptr += 2;
1196 continue;
1197 }
0b7410c4 1198
252b5132
RH
1199 *freeptr++ = c;
1200 lineptr++;
1201 }
0b7410c4 1202
252b5132
RH
1203 *freeptr++ = '\0';
1204 argc += 1;
0b7410c4 1205
252b5132
RH
1206 if (*lineptr == '\0')
1207 continue;
0b7410c4 1208
252b5132
RH
1209 lineptr += 1;
1210 }
1211 else
ea1562b3 1212 as_fatal (_("Too many operands passed to instruction"));
252b5132
RH
1213 }
1214 }
1215 }
0b7410c4 1216
252b5132
RH
1217 if (argc != strlen (desc->operands) / 2)
1218 {
1219 if (strlen (desc->default_args))
c6a7ab1f
NC
1220 {
1221 /* We can apply default, don't goof. */
252b5132 1222 if (parse (desc->default_args, 1) != 1)
c6a7ab1f
NC
1223 /* Check error in default. */
1224 as_fatal (_("Wrong numbers of operands in default, check ns32k-opcodes.h"));
252b5132
RH
1225 }
1226 else
ea1562b3 1227 as_fatal (_("Wrong number of operands"));
252b5132 1228 }
0b7410c4 1229
252b5132 1230 for (i = 0; i < IIF_ENTRIES; i++)
c6a7ab1f
NC
1231 /* Mark all entries as void. */
1232 iif.iifP[i].type = 0;
252b5132 1233
c6a7ab1f 1234 /* Build opcode iif-entry. */
252b5132
RH
1235 iif.instr_size = desc->opcode_size / 8;
1236 IIF (1, 1, iif.instr_size, desc->opcode_seed, 0, 0, 0, 0, 0, 0, -1, 0);
1237
c6a7ab1f 1238 /* This call encodes operands to iif format. */
252b5132 1239 if (argc)
ea1562b3
NC
1240 encode_operand (argc, argv, &desc->operands[0],
1241 &suffix[0], desc->im_size, desc->opcode_size);
1242
252b5132
RH
1243 return recursive_level;
1244}
1245\f
ea1562b3
NC
1246#ifdef BFD_ASSEMBLER
1247/* This functionality should really be in the bfd library. */
252b5132 1248
ea1562b3
NC
1249static bfd_reloc_code_real_type
1250reloc (int size, int pcrel, int type)
252b5132 1251{
ea1562b3
NC
1252 int length, index;
1253 bfd_reloc_code_real_type relocs[] =
1254 {
1255 BFD_RELOC_NS32K_IMM_8,
1256 BFD_RELOC_NS32K_IMM_16,
1257 BFD_RELOC_NS32K_IMM_32,
1258 BFD_RELOC_NS32K_IMM_8_PCREL,
1259 BFD_RELOC_NS32K_IMM_16_PCREL,
1260 BFD_RELOC_NS32K_IMM_32_PCREL,
252b5132 1261
ea1562b3
NC
1262 /* ns32k displacements. */
1263 BFD_RELOC_NS32K_DISP_8,
1264 BFD_RELOC_NS32K_DISP_16,
1265 BFD_RELOC_NS32K_DISP_32,
1266 BFD_RELOC_NS32K_DISP_8_PCREL,
1267 BFD_RELOC_NS32K_DISP_16_PCREL,
1268 BFD_RELOC_NS32K_DISP_32_PCREL,
252b5132 1269
ea1562b3
NC
1270 /* Normal 2's complement. */
1271 BFD_RELOC_8,
1272 BFD_RELOC_16,
1273 BFD_RELOC_32,
1274 BFD_RELOC_8_PCREL,
1275 BFD_RELOC_16_PCREL,
1276 BFD_RELOC_32_PCREL
1277 };
1278
1279 switch (size)
252b5132 1280 {
ea1562b3
NC
1281 case 1:
1282 length = 0;
1283 break;
1284 case 2:
1285 length = 1;
1286 break;
1287 case 4:
1288 length = 2;
1289 break;
1290 default:
1291 length = -1;
1292 break;
1293 }
0b7410c4 1294
ea1562b3 1295 index = length + 3 * pcrel + 6 * type;
0b7410c4 1296
ea1562b3
NC
1297 if (index >= 0 && (unsigned int) index < sizeof (relocs) / sizeof (relocs[0]))
1298 return relocs[index];
0b7410c4 1299
ea1562b3
NC
1300 if (pcrel)
1301 as_bad (_("Can not do %d byte pc-relative relocation for storage type %d"),
1302 size, type);
1303 else
1304 as_bad (_("Can not do %d byte relocation for storage type %d"),
1305 size, type);
0b7410c4 1306
ea1562b3 1307 return BFD_RELOC_NONE;
0b7410c4 1308
ea1562b3
NC
1309}
1310#endif
252b5132 1311
ea1562b3
NC
1312static void
1313fix_new_ns32k (fragS *frag, /* Which frag? */
1314 int where, /* Where in that frag? */
1315 int size, /* 1, 2 or 4 usually. */
1316 symbolS *add_symbol, /* X_add_symbol. */
1317 long offset, /* X_add_number. */
1318 int pcrel, /* True if PC-relative relocation. */
1319 char im_disp, /* True if the value to write is a
1320 displacement. */
1321 bit_fixS *bit_fixP, /* Pointer at struct of bit_fix's, ignored if
1322 NULL. */
1323 char bsr, /* Sequent-linker-hack: 1 when relocobject is
1324 a bsr. */
1325 fragS *opcode_frag,
1326 unsigned int opcode_offset)
1327{
1328 fixS *fixP = fix_new (frag, where, size, add_symbol,
1329 offset, pcrel,
1330#ifdef BFD_ASSEMBLER
1331 bit_fixP ? NO_RELOC : reloc (size, pcrel, im_disp)
1332#else
1333 NO_RELOC
1334#endif
1335 );
1336
1337 fix_opcode_frag (fixP) = opcode_frag;
1338 fix_opcode_offset (fixP) = opcode_offset;
1339 fix_im_disp (fixP) = im_disp;
1340 fix_bsr (fixP) = bsr;
1341 fix_bit_fixP (fixP) = bit_fixP;
1342 /* We have a MD overflow check for displacements. */
1343 fixP->fx_no_overflow = (im_disp != 0);
1344}
1345
1346static void
1347fix_new_ns32k_exp (fragS *frag, /* Which frag? */
1348 int where, /* Where in that frag? */
1349 int size, /* 1, 2 or 4 usually. */
1350 expressionS *exp, /* Expression. */
1351 int pcrel, /* True if PC-relative relocation. */
1352 char im_disp, /* True if the value to write is a
1353 displacement. */
1354 bit_fixS *bit_fixP, /* Pointer at struct of bit_fix's, ignored if
1355 NULL. */
1356 char bsr, /* Sequent-linker-hack: 1 when relocobject is
1357 a bsr. */
1358 fragS *opcode_frag,
1359 unsigned int opcode_offset)
1360{
1361 fixS *fixP = fix_new_exp (frag, where, size, exp, pcrel,
1362#ifdef BFD_ASSEMBLER
1363 bit_fixP ? NO_RELOC : reloc (size, pcrel, im_disp)
1364#else
1365 NO_RELOC
1366#endif
1367 );
1368
1369 fix_opcode_frag (fixP) = opcode_frag;
1370 fix_opcode_offset (fixP) = opcode_offset;
1371 fix_im_disp (fixP) = im_disp;
1372 fix_bsr (fixP) = bsr;
1373 fix_bit_fixP (fixP) = bit_fixP;
1374 /* We have a MD overflow check for displacements. */
1375 fixP->fx_no_overflow = (im_disp != 0);
1376}
1377
1378/* Convert number to chars in correct order. */
1379
1380void
1381md_number_to_chars (char *buf, valueT value, int nbytes)
1382{
1383 number_to_chars_littleendian (buf, value, nbytes);
1384}
1385
1386/* This is a variant of md_numbers_to_chars. The reason for its'
1387 existence is the fact that ns32k uses Huffman coded
1388 displacements. This implies that the bit order is reversed in
1389 displacements and that they are prefixed with a size-tag.
1390
1391 binary: msb -> lsb
1392 0xxxxxxx byte
1393 10xxxxxx xxxxxxxx word
1394 11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx double word
1395
1396 This must be taken care of and we do it here! */
1397
1398static void
1399md_number_to_disp (char *buf, long val, int n)
1400{
1401 switch (n)
1402 {
1403 case 1:
1404 if (val < -64 || val > 63)
1405 as_bad (_("value of %ld out of byte displacement range."), val);
1406 val &= 0x7f;
1407#ifdef SHOW_NUM
1408 printf ("%x ", val & 0xff);
1409#endif
1410 *buf++ = val;
1411 break;
1412
1413 case 2:
1414 if (val < -8192 || val > 8191)
1415 as_bad (_("value of %ld out of word displacement range."), val);
1416 val &= 0x3fff;
1417 val |= 0x8000;
1418#ifdef SHOW_NUM
1419 printf ("%x ", val >> 8 & 0xff);
1420#endif
1421 *buf++ = (val >> 8);
1422#ifdef SHOW_NUM
1423 printf ("%x ", val & 0xff);
1424#endif
1425 *buf++ = val;
1426 break;
1427
1428 case 4:
1429 if (val < -0x20000000 || val >= 0x20000000)
1430 as_bad (_("value of %ld out of double word displacement range."), val);
1431 val |= 0xc0000000;
1432#ifdef SHOW_NUM
1433 printf ("%x ", val >> 24 & 0xff);
1434#endif
1435 *buf++ = (val >> 24);
1436#ifdef SHOW_NUM
1437 printf ("%x ", val >> 16 & 0xff);
1438#endif
1439 *buf++ = (val >> 16);
1440#ifdef SHOW_NUM
1441 printf ("%x ", val >> 8 & 0xff);
1442#endif
1443 *buf++ = (val >> 8);
1444#ifdef SHOW_NUM
1445 printf ("%x ", val & 0xff);
1446#endif
1447 *buf++ = val;
1448 break;
1449
1450 default:
1451 as_fatal (_("Internal logic error. line %d, file \"%s\""),
1452 __LINE__, __FILE__);
1453 }
1454}
1455
1456static void
1457md_number_to_imm (char *buf, long val, int n)
1458{
1459 switch (n)
1460 {
1461 case 1:
1462#ifdef SHOW_NUM
1463 printf ("%x ", val & 0xff);
1464#endif
1465 *buf++ = val;
1466 break;
1467
1468 case 2:
1469#ifdef SHOW_NUM
1470 printf ("%x ", val >> 8 & 0xff);
1471#endif
1472 *buf++ = (val >> 8);
1473#ifdef SHOW_NUM
1474 printf ("%x ", val & 0xff);
1475#endif
1476 *buf++ = val;
1477 break;
1478
1479 case 4:
1480#ifdef SHOW_NUM
1481 printf ("%x ", val >> 24 & 0xff);
1482#endif
1483 *buf++ = (val >> 24);
1484#ifdef SHOW_NUM
1485 printf ("%x ", val >> 16 & 0xff);
1486#endif
1487 *buf++ = (val >> 16);
1488#ifdef SHOW_NUM
1489 printf ("%x ", val >> 8 & 0xff);
1490#endif
1491 *buf++ = (val >> 8);
1492#ifdef SHOW_NUM
1493 printf ("%x ", val & 0xff);
1494#endif
1495 *buf++ = val;
1496 break;
1497
1498 default:
1499 as_fatal (_("Internal logic error. line %d, file \"%s\""),
1500 __LINE__, __FILE__);
1501 }
1502}
1503
1504/* Fast bitfiddling support. */
1505/* Mask used to zero bitfield before oring in the true field. */
1506
1507static unsigned long l_mask[] =
1508{
1509 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
1510 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
1511 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
1512 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
1513 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
1514 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
1515 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
1516 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000,
1517};
1518static unsigned long r_mask[] =
1519{
1520 0x00000000, 0x00000001, 0x00000003, 0x00000007,
1521 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
1522 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
1523 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
1524 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
1525 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
1526 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
1527 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
1528};
1529#define MASK_BITS 31
1530/* Insert bitfield described by field_ptr and val at buf
1531 This routine is written for modification of the first 4 bytes pointed
1532 to by buf, to yield speed.
1533 The ifdef stuff is for selection between a ns32k-dependent routine
1534 and a general version. (My advice: use the general version!). */
1535
1536static void
1537md_number_to_field (char *buf, long val, bit_fixS *field_ptr)
1538{
1539 unsigned long object;
1540 unsigned long mask;
1541 /* Define ENDIAN on a ns32k machine. */
1542#ifdef ENDIAN
1543 unsigned long *mem_ptr;
1544#else
1545 char *mem_ptr;
1546#endif
1547
1548 if (field_ptr->fx_bit_min <= val && val <= field_ptr->fx_bit_max)
1549 {
1550#ifdef ENDIAN
1551 if (field_ptr->fx_bit_base)
1552 /* Override buf. */
1553 mem_ptr = (unsigned long *) field_ptr->fx_bit_base;
1554 else
1555 mem_ptr = (unsigned long *) buf;
1556
1557 mem_ptr = ((unsigned long *)
1558 ((char *) mem_ptr + field_ptr->fx_bit_base_adj));
1559#else
1560 if (field_ptr->fx_bit_base)
1561 mem_ptr = (char *) field_ptr->fx_bit_base;
1562 else
1563 mem_ptr = buf;
1564
1565 mem_ptr += field_ptr->fx_bit_base_adj;
1566#endif
1567#ifdef ENDIAN
1568 /* We have a nice ns32k machine with lowbyte at low-physical mem. */
1569 object = *mem_ptr; /* get some bytes */
1570#else /* OVE Goof! the machine is a m68k or dito. */
1571 /* That takes more byte fiddling. */
1572 object = 0;
1573 object |= mem_ptr[3] & 0xff;
1574 object <<= 8;
1575 object |= mem_ptr[2] & 0xff;
1576 object <<= 8;
1577 object |= mem_ptr[1] & 0xff;
1578 object <<= 8;
1579 object |= mem_ptr[0] & 0xff;
1580#endif
1581 mask = 0;
1582 mask |= (r_mask[field_ptr->fx_bit_offset]);
1583 mask |= (l_mask[field_ptr->fx_bit_offset + field_ptr->fx_bit_size]);
1584 object &= mask;
1585 val += field_ptr->fx_bit_add;
1586 object |= ((val << field_ptr->fx_bit_offset) & (mask ^ 0xffffffff));
1587#ifdef ENDIAN
1588 *mem_ptr = object;
1589#else
1590 mem_ptr[0] = (char) object;
1591 object >>= 8;
1592 mem_ptr[1] = (char) object;
1593 object >>= 8;
1594 mem_ptr[2] = (char) object;
1595 object >>= 8;
1596 mem_ptr[3] = (char) object;
1597#endif
1598 }
1599 else
1600 as_bad (_("Bit field out of range"));
1601}
1602
1603/* Convert iif to fragments. From this point we start to dribble with
1604 functions in other files than this one.(Except hash.c) So, if it's
1605 possible to make an iif for an other CPU, you don't need to know
1606 what frags, relax, obstacks, etc is in order to port this
1607 assembler. You only need to know if it's possible to reduce your
1608 cpu-instruction to iif-format (takes some work) and adopt the other
1609 md_? parts according to given instructions Note that iif was
1610 invented for the clean ns32k`s architecture. */
1611
1612/* GAS for the ns32k has a problem. PC relative displacements are
1613 relative to the address of the opcode, not the address of the
1614 operand. We used to keep track of the offset between the operand
1615 and the opcode in pcrel_adjust for each frag and each fix. However,
1616 we get into trouble where there are two or more pc-relative
1617 operands and the size of the first one can't be determined. Then in
1618 the relax phase, the size of the first operand will change and
1619 pcrel_adjust will no longer be correct. The current solution is
1620 keep a pointer to the frag with the opcode in it and the offset in
1621 that frag for each frag and each fix. Then, when needed, we can
1622 always figure out how far it is between the opcode and the pcrel
1623 object. See also md_pcrel_adjust and md_fix_pcrel_adjust. For
1624 objects not part of an instruction, the pointer to the opcode frag
1625 is always zero. */
1626
1627static void
1628convert_iif (void)
1629{
1630 int i;
1631 bit_fixS *j;
1632 fragS *inst_frag;
1633 unsigned int inst_offset;
1634 char *inst_opcode;
1635 char *memP;
1636 int l;
1637 int k;
1638 char type;
1639 char size = 0;
1640
1641 frag_grow (iif.instr_size); /* This is important. */
1642 memP = frag_more (0);
1643 inst_opcode = memP;
1644 inst_offset = (memP - frag_now->fr_literal);
1645 inst_frag = frag_now;
1646
1647 for (i = 0; i < IIF_ENTRIES; i++)
1648 {
1649 if ((type = iif.iifP[i].type))
1650 {
1651 /* The object exist, so handle it. */
1652 switch (size = iif.iifP[i].size)
1653 {
1654 case 42:
1655 size = 0;
1656 /* It's a bitfix that operates on an existing object. */
1657 if (iif.iifP[i].bit_fixP->fx_bit_base)
1658 /* Expand fx_bit_base to point at opcode. */
1659 iif.iifP[i].bit_fixP->fx_bit_base = (long) inst_opcode;
1660 /* Fall through. */
1661
1662 case 8: /* bignum or doublefloat. */
1663 case 1:
1664 case 2:
1665 case 3:
1666 case 4:
1667 /* The final size in objectmemory is known. */
1668 memP = frag_more (size);
1669 j = iif.iifP[i].bit_fixP;
1670
1671 switch (type)
1672 {
1673 case 1: /* The object is pure binary. */
1674 if (j)
1675 md_number_to_field (memP, exprP.X_add_number, j);
1676
1677 else if (iif.iifP[i].pcrel)
1678 fix_new_ns32k (frag_now,
1679 (long) (memP - frag_now->fr_literal),
1680 size,
1681 0,
1682 iif.iifP[i].object,
1683 iif.iifP[i].pcrel,
1684 iif.iifP[i].im_disp,
1685 0,
1686 iif.iifP[i].bsr, /* Sequent hack. */
1687 inst_frag, inst_offset);
1688 else
1689 {
1690 /* Good, just put them bytes out. */
1691 switch (iif.iifP[i].im_disp)
1692 {
1693 case 0:
1694 md_number_to_chars (memP, iif.iifP[i].object, size);
1695 break;
1696 case 1:
1697 md_number_to_disp (memP, iif.iifP[i].object, size);
1698 break;
1699 default:
1700 as_fatal (_("iif convert internal pcrel/binary"));
1701 }
1702 }
1703 break;
1704
1705 case 2:
1706 /* The object is a pointer at an expression, so
1707 unpack it, note that bignums may result from the
1708 expression. */
1709 evaluate_expr (&exprP, (char *) iif.iifP[i].object);
1710 if (exprP.X_op == O_big || size == 8)
1711 {
1712 if ((k = exprP.X_add_number) > 0)
1713 {
1714 /* We have a bignum ie a quad. This can only
1715 happens in a long suffixed instruction. */
1716 if (k * 2 > size)
1717 as_bad (_("Bignum too big for long"));
1718
1719 if (k == 3)
1720 memP += 2;
1721
1722 for (l = 0; k > 0; k--, l += 2)
1723 md_number_to_chars (memP + l,
1724 generic_bignum[l >> 1],
1725 sizeof (LITTLENUM_TYPE));
1726 }
1727 else
1728 {
1729 /* flonum. */
1730 LITTLENUM_TYPE words[4];
1731
1732 switch (size)
1733 {
1734 case 4:
1735 gen_to_words (words, 2, 8);
1736 md_number_to_imm (memP, (long) words[0],
1737 sizeof (LITTLENUM_TYPE));
1738 md_number_to_imm (memP + sizeof (LITTLENUM_TYPE),
1739 (long) words[1],
1740 sizeof (LITTLENUM_TYPE));
1741 break;
1742 case 8:
1743 gen_to_words (words, 4, 11);
1744 md_number_to_imm (memP, (long) words[0],
1745 sizeof (LITTLENUM_TYPE));
1746 md_number_to_imm (memP + sizeof (LITTLENUM_TYPE),
1747 (long) words[1],
1748 sizeof (LITTLENUM_TYPE));
1749 md_number_to_imm ((memP + 2
1750 * sizeof (LITTLENUM_TYPE)),
1751 (long) words[2],
1752 sizeof (LITTLENUM_TYPE));
1753 md_number_to_imm ((memP + 3
1754 * sizeof (LITTLENUM_TYPE)),
1755 (long) words[3],
1756 sizeof (LITTLENUM_TYPE));
1757 break;
1758 }
1759 }
1760 break;
1761 }
1762 if (exprP.X_add_symbol ||
1763 exprP.X_op_symbol ||
1764 iif.iifP[i].pcrel)
252b5132
RH
1765 {
1766 /* The expression was undefined due to an
1767 undefined label. Create a fix so we can fix
c6a7ab1f 1768 the object later. */
252b5132
RH
1769 exprP.X_add_number += iif.iifP[i].object_adjust;
1770 fix_new_ns32k_exp (frag_now,
1771 (long) (memP - frag_now->fr_literal),
1772 size,
1773 &exprP,
1774 iif.iifP[i].pcrel,
1775 iif.iifP[i].im_disp,
1776 j,
1777 iif.iifP[i].bsr,
1778 inst_frag, inst_offset);
1779 }
4eb6b71c 1780 else if (j)
ea1562b3 1781 md_number_to_field (memP, exprP.X_add_number, j);
252b5132
RH
1782 else
1783 {
c6a7ab1f 1784 /* Good, just put them bytes out. */
252b5132
RH
1785 switch (iif.iifP[i].im_disp)
1786 {
1787 case 0:
1788 md_number_to_imm (memP, exprP.X_add_number, size);
1789 break;
1790 case 1:
1791 md_number_to_disp (memP, exprP.X_add_number, size);
1792 break;
1793 default:
1794 as_fatal (_("iif convert internal pcrel/pointer"));
1795 }
1796 }
1797 break;
1798 default:
1799 as_fatal (_("Internal logic error in iif.iifP[n].type"));
1800 }
1801 break;
0b7410c4 1802
252b5132 1803 case 0:
c6a7ab1f 1804 /* Too bad, the object may be undefined as far as its
252b5132
RH
1805 final nsize in object memory is concerned. The size
1806 of the object in objectmemory is not explicitly
1807 given. If the object is defined its length can be
c6a7ab1f 1808 determined and a fix can replace the frag. */
252b5132
RH
1809 {
1810 evaluate_expr (&exprP, (char *) iif.iifP[i].object);
0b7410c4 1811
252b5132
RH
1812 if ((exprP.X_add_symbol || exprP.X_op_symbol) &&
1813 !iif.iifP[i].pcrel)
1814 {
4eb6b71c
NC
1815 /* Size is unknown until link time so have to default. */
1816 size = default_disp_size; /* Normally 4 bytes. */
07726851 1817 memP = frag_more (size);
252b5132
RH
1818 fix_new_ns32k_exp (frag_now,
1819 (long) (memP - frag_now->fr_literal),
1820 size,
1821 &exprP,
1822 0, /* never iif.iifP[i].pcrel, */
1823 1, /* always iif.iifP[i].im_disp */
1824 (bit_fixS *) 0, 0,
1825 inst_frag,
1826 inst_offset);
4eb6b71c 1827 break; /* Exit this absolute hack. */
252b5132
RH
1828 }
1829
1830 if (exprP.X_add_symbol || exprP.X_op_symbol)
c6a7ab1f
NC
1831 {
1832 /* Frag it. */
252b5132 1833 if (exprP.X_op_symbol)
ea1562b3
NC
1834 /* We cant relax this case. */
1835 as_fatal (_("Can't relax difference"));
252b5132
RH
1836 else
1837 {
c6a7ab1f
NC
1838 /* Size is not important. This gets fixed by
1839 relax, but we assume 0 in what follows. */
07726851 1840 memP = frag_more (4); /* Max size. */
252b5132
RH
1841 size = 0;
1842
1843 {
1844 fragS *old_frag = frag_now;
1845 frag_variant (rs_machine_dependent,
c6a7ab1f
NC
1846 4, /* Max size. */
1847 0, /* Size. */
1848 IND (BRANCH, UNDEF), /* Expecting
1849 the worst. */
252b5132
RH
1850 exprP.X_add_symbol,
1851 exprP.X_add_number,
1852 inst_opcode);
c6a7ab1f
NC
1853 frag_opcode_frag (old_frag) = inst_frag;
1854 frag_opcode_offset (old_frag) = inst_offset;
1855 frag_bsr (old_frag) = iif.iifP[i].bsr;
252b5132
RH
1856 }
1857 }
1858 }
1859 else
1860 {
c6a7ab1f 1861 /* This duplicates code in md_number_to_disp. */
252b5132 1862 if (-64 <= exprP.X_add_number && exprP.X_add_number <= 63)
ea1562b3 1863 size = 1;
252b5132
RH
1864 else
1865 {
1866 if (-8192 <= exprP.X_add_number
1867 && exprP.X_add_number <= 8191)
ea1562b3 1868 size = 2;
252b5132
RH
1869 else
1870 {
c6a7ab1f
NC
1871 if (-0x20000000 <= exprP.X_add_number
1872 && exprP.X_add_number<=0x1fffffff)
ea1562b3 1873 size = 4;
252b5132
RH
1874 else
1875 {
4eb6b71c 1876 as_bad (_("Displacement to large for :d"));
252b5132
RH
1877 size = 4;
1878 }
1879 }
1880 }
0b7410c4 1881
c6a7ab1f 1882 memP = frag_more (size);
252b5132
RH
1883 md_number_to_disp (memP, exprP.X_add_number, size);
1884 }
1885 }
1886 break;
0b7410c4 1887
252b5132
RH
1888 default:
1889 as_fatal (_("Internal logic error in iif.iifP[].type"));
1890 }
1891 }
ea1562b3
NC
1892 }
1893}
1894\f
1895void
1896md_assemble (char *line)
1897{
1898 freeptr = freeptr_static;
1899 parse (line, 0); /* Explode line to more fix form in iif. */
1900 convert_iif (); /* Convert iif to frags, fix's etc. */
252b5132 1901#ifdef SHOW_NUM
ea1562b3 1902 printf (" \t\t\t%s\n", line);
252b5132 1903#endif
252b5132
RH
1904}
1905
ea1562b3
NC
1906void
1907md_begin (void)
252b5132 1908{
ea1562b3
NC
1909 /* Build a hashtable of the instructions. */
1910 const struct ns32k_opcode *ptr;
1911 const char *stat;
1912 const struct ns32k_opcode *endop;
1913
1914 inst_hash_handle = hash_new ();
1915
1916 endop = ns32k_opcodes + sizeof (ns32k_opcodes) / sizeof (ns32k_opcodes[0]);
1917 for (ptr = ns32k_opcodes; ptr < endop; ptr++)
252b5132 1918 {
ea1562b3
NC
1919 if ((stat = hash_insert (inst_hash_handle, ptr->name, (char *) ptr)))
1920 /* Fatal. */
1921 as_fatal (_("Can't hash %s: %s"), ptr->name, stat);
252b5132 1922 }
ea1562b3
NC
1923
1924 /* Some private space please! */
1925 freeptr_static = (char *) malloc (PRIVATE_SIZE);
252b5132
RH
1926}
1927
ea1562b3
NC
1928/* Must be equal to MAX_PRECISON in atof-ieee.c. */
1929#define MAX_LITTLENUMS 6
252b5132 1930
ea1562b3
NC
1931/* Turn the string pointed to by litP into a floating point constant
1932 of type TYPE, and emit the appropriate bytes. The number of
1933 LITTLENUMS emitted is stored in *SIZEP. An error message is
1934 returned, or NULL on OK. */
252b5132 1935
ea1562b3
NC
1936char *
1937md_atof (int type, char *litP, int *sizeP)
252b5132 1938{
ea1562b3
NC
1939 int prec;
1940 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1941 LITTLENUM_TYPE *wordP;
1942 char *t;
4eb6b71c 1943
ea1562b3 1944 switch (type)
252b5132 1945 {
ea1562b3
NC
1946 case 'f':
1947 prec = 2;
1948 break;
c6a7ab1f 1949
ea1562b3
NC
1950 case 'd':
1951 prec = 4;
1952 break;
1953 default:
1954 *sizeP = 0;
1955 return _("Bad call to MD_ATOF()");
252b5132 1956 }
ea1562b3
NC
1957
1958 t = atof_ieee (input_line_pointer, type, words);
1959 if (t)
1960 input_line_pointer = t;
1961
1962 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1963
1964 for (wordP = words + prec; prec--;)
252b5132 1965 {
ea1562b3
NC
1966 md_number_to_chars (litP, (long) (*--wordP), sizeof (LITTLENUM_TYPE));
1967 litP += sizeof (LITTLENUM_TYPE);
252b5132 1968 }
252b5132 1969
ea1562b3
NC
1970 return 0;
1971}
1972\f
c6a7ab1f 1973int
ea1562b3 1974md_pcrel_adjust (fragS *fragP)
252b5132
RH
1975{
1976 fragS *opcode_frag;
1977 addressT opcode_address;
1978 unsigned int offset;
0b7410c4 1979
c6a7ab1f 1980 opcode_frag = frag_opcode_frag (fragP);
252b5132
RH
1981 if (opcode_frag == 0)
1982 return 0;
0b7410c4 1983
c6a7ab1f 1984 offset = frag_opcode_offset (fragP);
252b5132 1985 opcode_address = offset + opcode_frag->fr_address;
0b7410c4 1986
252b5132
RH
1987 return fragP->fr_address + fragP->fr_fix - opcode_address;
1988}
1989
4eb6b71c 1990static int
ea1562b3 1991md_fix_pcrel_adjust (fixS *fixP)
252b5132 1992{
252b5132
RH
1993 fragS *opcode_frag;
1994 addressT opcode_address;
1995 unsigned int offset;
0b7410c4 1996
c6a7ab1f 1997 opcode_frag = fix_opcode_frag (fixP);
252b5132
RH
1998 if (opcode_frag == 0)
1999 return 0;
0b7410c4 2000
c6a7ab1f 2001 offset = fix_opcode_offset (fixP);
252b5132 2002 opcode_address = offset + opcode_frag->fr_address;
0b7410c4 2003
252b5132
RH
2004 return fixP->fx_where + fixP->fx_frag->fr_address - opcode_address;
2005}
2006
2007/* Apply a fixS (fixup of an instruction or data that we didn't have
2008 enough info to complete immediately) to the data in a frag.
2009
2010 On the ns32k, everything is in a different format, so we have broken
2011 out separate functions for each kind of thing we could be fixing.
2012 They all get called from here. */
2013
252b5132 2014void
ea1562b3 2015md_apply_fix3 (fixS *fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
252b5132 2016{
94f592af 2017 long val = * (long *) valP;
252b5132
RH
2018 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
2019
c6a7ab1f 2020 if (fix_bit_fixP (fixP))
ea1562b3
NC
2021 /* Bitfields to fix, sigh. */
2022 md_number_to_field (buf, val, fix_bit_fixP (fixP));
94f592af
NC
2023 else switch (fix_im_disp (fixP))
2024 {
2025 case 0:
2026 /* Immediate field. */
2027 md_number_to_imm (buf, val, fixP->fx_size);
2028 break;
252b5132 2029
94f592af
NC
2030 case 1:
2031 /* Displacement field. */
4eb6b71c 2032 /* Calculate offset. */
94f592af
NC
2033 md_number_to_disp (buf,
2034 (fixP->fx_pcrel ? val + md_fix_pcrel_adjust (fixP)
2035 : val), fixP->fx_size);
2036 break;
2037
2038 case 2:
2039 /* Pointer in a data object. */
2040 md_number_to_chars (buf, val, fixP->fx_size);
2041 break;
2042 }
2043
2044 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
2045 fixP->fx_done = 1;
252b5132
RH
2046}
2047\f
4eb6b71c 2048/* Convert a relaxed displacement to ditto in final output. */
252b5132
RH
2049
2050#ifndef BFD_ASSEMBLER
2051void
ea1562b3
NC
2052md_convert_frag (object_headers *headers,
2053 segT sec,
2054 fragS *fragP)
252b5132
RH
2055#else
2056void
ea1562b3
NC
2057md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
2058 segT sec ATTRIBUTE_UNUSED,
2059 fragS *fragP)
252b5132
RH
2060#endif
2061{
2062 long disp;
2063 long ext = 0;
252b5132 2064 /* Address in gas core of the place to store the displacement. */
4eb6b71c 2065 char *buffer_address = fragP->fr_fix + fragP->fr_literal;
252b5132
RH
2066 /* Address in object code of the displacement. */
2067 int object_address;
2068
252b5132
RH
2069 switch (fragP->fr_subtype)
2070 {
2071 case IND (BRANCH, BYTE):
2072 ext = 1;
2073 break;
2074 case IND (BRANCH, WORD):
2075 ext = 2;
2076 break;
2077 case IND (BRANCH, DOUBLE):
2078 ext = 4;
2079 break;
2080 }
2081
c6a7ab1f 2082 if (ext == 0)
252b5132
RH
2083 return;
2084
2085 know (fragP->fr_symbol);
2086
2087 object_address = fragP->fr_fix + fragP->fr_address;
0b7410c4 2088
252b5132
RH
2089 /* The displacement of the address, from current location. */
2090 disp = (S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset) - object_address;
c6a7ab1f 2091 disp += md_pcrel_adjust (fragP);
252b5132
RH
2092
2093 md_number_to_disp (buffer_address, (long) disp, (int) ext);
2094 fragP->fr_fix += ext;
2095}
2096
2097/* This function returns the estimated size a variable object will occupy,
2098 one can say that we tries to guess the size of the objects before we
c6a7ab1f 2099 actually know it. */
252b5132
RH
2100
2101int
ea1562b3 2102md_estimate_size_before_relax (fragS *fragP, segT segment)
252b5132 2103{
606ab118 2104 if (fragP->fr_subtype == IND (BRANCH, UNDEF))
252b5132 2105 {
606ab118 2106 if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
252b5132 2107 {
606ab118 2108 /* We don't relax symbols defined in another segment. The
c6a7ab1f 2109 thing to do is to assume the object will occupy 4 bytes. */
252b5132
RH
2110 fix_new_ns32k (fragP,
2111 (int) (fragP->fr_fix),
2112 4,
2113 fragP->fr_symbol,
2114 fragP->fr_offset,
2115 1,
2116 1,
2117 0,
4eb6b71c 2118 frag_bsr(fragP), /* Sequent hack. */
c6a7ab1f
NC
2119 frag_opcode_frag (fragP),
2120 frag_opcode_offset (fragP));
252b5132 2121 fragP->fr_fix += 4;
252b5132 2122 frag_wane (fragP);
606ab118 2123 return 4;
252b5132 2124 }
93c2a809 2125
606ab118
AM
2126 /* Relaxable case. Set up the initial guess for the variable
2127 part of the frag. */
2128 fragP->fr_subtype = IND (BRANCH, BYTE);
252b5132 2129 }
0b7410c4 2130
606ab118
AM
2131 if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
2132 abort ();
2133
2134 /* Return the size of the variable part of the frag. */
2135 return md_relax_table[fragP->fr_subtype].rlx_length;
252b5132
RH
2136}
2137
2138int md_short_jump_size = 3;
2139int md_long_jump_size = 5;
c6a7ab1f 2140const int md_reloc_size = 8; /* Size of relocation record. */
252b5132
RH
2141
2142void
ea1562b3
NC
2143md_create_short_jump (char *ptr,
2144 addressT from_addr,
2145 addressT to_addr,
2146 fragS *frag ATTRIBUTE_UNUSED,
2147 symbolS *to_symbol ATTRIBUTE_UNUSED)
252b5132
RH
2148{
2149 valueT offset;
2150
2151 offset = to_addr - from_addr;
2152 md_number_to_chars (ptr, (valueT) 0xEA, 1);
2153 md_number_to_disp (ptr + 1, (valueT) offset, 2);
2154}
2155
2156void
ea1562b3
NC
2157md_create_long_jump (char *ptr,
2158 addressT from_addr,
2159 addressT to_addr,
2160 fragS *frag ATTRIBUTE_UNUSED,
2161 symbolS *to_symbol ATTRIBUTE_UNUSED)
252b5132
RH
2162{
2163 valueT offset;
2164
2165 offset = to_addr - from_addr;
2166 md_number_to_chars (ptr, (valueT) 0xEA, 1);
2167 md_number_to_disp (ptr + 1, (valueT) offset, 4);
2168}
2169\f
5a38dc70 2170const char *md_shortopts = "m:";
c6a7ab1f
NC
2171
2172struct option md_longopts[] =
2173{
4eb6b71c
NC
2174#define OPTION_DISP_SIZE (OPTION_MD_BASE)
2175 {"disp-size-default", required_argument , NULL, OPTION_DISP_SIZE},
252b5132
RH
2176 {NULL, no_argument, NULL, 0}
2177};
c6a7ab1f
NC
2178
2179size_t md_longopts_size = sizeof (md_longopts);
252b5132
RH
2180
2181int
ea1562b3 2182md_parse_option (int c, char *arg)
252b5132
RH
2183{
2184 switch (c)
2185 {
2186 case 'm':
2187 if (!strcmp (arg, "32032"))
2188 {
2189 cpureg = cpureg_032;
2190 mmureg = mmureg_032;
2191 }
2192 else if (!strcmp (arg, "32532"))
2193 {
2194 cpureg = cpureg_532;
2195 mmureg = mmureg_532;
2196 }
2197 else
2198 {
4eb6b71c 2199 as_warn (_("invalid architecture option -m%s, ignored"), arg);
252b5132
RH
2200 return 0;
2201 }
2202 break;
4eb6b71c
NC
2203 case OPTION_DISP_SIZE:
2204 {
2205 int size = atoi(arg);
2206 switch (size)
2207 {
2208 case 1: case 2: case 4:
2209 default_disp_size = size;
2210 break;
2211 default:
2212 as_warn (_("invalid default displacement size \"%s\". Defaulting to %d."),
2213 arg, default_disp_size);
2214 }
2215 break;
2216 }
252b5132
RH
2217
2218 default:
2219 return 0;
2220 }
2221
2222 return 1;
2223}
2224
2225void
ea1562b3 2226md_show_usage (FILE *stream)
252b5132 2227{
c6a7ab1f 2228 fprintf (stream, _("\
252b5132 2229NS32K options:\n\
4eb6b71c
NC
2230-m32032 | -m32532 select variant of NS32K architecture\n\
2231--disp-size-default=<1|2|4>\n"));
252b5132 2232}
252b5132 2233\f
252b5132
RH
2234/* This is TC_CONS_FIX_NEW, called by emit_expr in read.c. */
2235
2236void
ea1562b3
NC
2237cons_fix_new_ns32k (fragS *frag, /* Which frag? */
2238 int where, /* Where in that frag? */
2239 int size, /* 1, 2 or 4 usually. */
2240 expressionS *exp) /* Expression. */
252b5132
RH
2241{
2242 fix_new_ns32k_exp (frag, where, size, exp,
2243 0, 2, 0, 0, 0, 0);
2244}
2245
2246/* We have no need to default values of symbols. */
2247
2248symbolS *
ea1562b3 2249md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
252b5132
RH
2250{
2251 return 0;
2252}
2253
2254/* Round up a section size to the appropriate boundary. */
c6a7ab1f 2255
252b5132 2256valueT
ea1562b3 2257md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
252b5132 2258{
c6a7ab1f 2259 return size; /* Byte alignment is fine. */
252b5132
RH
2260}
2261
2262/* Exactly what point is a PC-relative offset relative TO? On the
c6a7ab1f
NC
2263 ns32k, they're relative to the start of the instruction. */
2264
252b5132 2265long
ea1562b3 2266md_pcrel_from (fixS *fixP)
252b5132
RH
2267{
2268 long res;
4eb6b71c 2269
252b5132
RH
2270 res = fixP->fx_where + fixP->fx_frag->fr_address;
2271#ifdef SEQUENT_COMPATABILITY
c6a7ab1f
NC
2272 if (frag_bsr (fixP->fx_frag))
2273 res += 0x12 /* FOO Kludge alert! */
252b5132
RH
2274#endif
2275 return res;
2276}
2277
2278#ifdef BFD_ASSEMBLER
2279
2280arelent *
ea1562b3 2281tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
252b5132
RH
2282{
2283 arelent *rel;
2284 bfd_reloc_code_real_type code;
2285
c6a7ab1f 2286 code = reloc (fixp->fx_size, fixp->fx_pcrel, fix_im_disp (fixp));
252b5132 2287
ea1562b3
NC
2288 rel = xmalloc (sizeof (arelent));
2289 rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
310b5aa2 2290 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
252b5132
RH
2291 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
2292 if (fixp->fx_pcrel)
2293 rel->addend = fixp->fx_addnumber;
2294 else
2295 rel->addend = 0;
2296
2297 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
2298 if (!rel->howto)
2299 {
2300 const char *name;
2301
2302 name = S_GET_NAME (fixp->fx_addsy);
2303 if (name == NULL)
2304 name = _("<unknown>");
2305 as_fatal (_("Cannot find relocation type for symbol %s, code %d"),
2306 name, (int) code);
2307 }
2308
2309 return rel;
2310}
2311#else /* BFD_ASSEMBLER */
2312
2313#ifdef OBJ_AOUT
2314void
ea1562b3
NC
2315cons_fix_new_ns32k (char *where,
2316 struct fix *fixP,
2317 relax_addressT segment_address_in_file)
252b5132 2318{
c6a7ab1f
NC
2319 /* In: Length of relocation (or of address) in chars: 1, 2 or 4.
2320 Out: GNU LD relocation length code: 0, 1, or 2. */
252b5132 2321
c6a7ab1f 2322 static unsigned char nbytes_r_length[] = { 42, 0, 1, 42, 2 };
252b5132
RH
2323 long r_symbolnum;
2324
2325 know (fixP->fx_addsy != NULL);
2326
2327 md_number_to_chars (where,
2328 fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
2329 4);
2330
2331 r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
2332 ? S_GET_TYPE (fixP->fx_addsy)
2333 : fixP->fx_addsy->sy_number);
2334
2335 md_number_to_chars (where + 4,
2336 ((long) (r_symbolnum)
2337 | (long) (fixP->fx_pcrel << 24)
2338 | (long) (nbytes_r_length[fixP->fx_size] << 25)
2339 | (long) ((!S_IS_DEFINED (fixP->fx_addsy)) << 27)
c6a7ab1f
NC
2340 | (long) (fix_bsr (fixP) << 28)
2341 | (long) (fix_im_disp (fixP) << 29)),
252b5132
RH
2342 4);
2343}
2344
2345#endif /* OBJ_AOUT */
67c1ffbe 2346#endif /* BFD_ASSEMBLER */