* config/tc-mips.c (mips_validate_fix): New function.
[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
4cd62c96
AM
893static void encode_operand
894 PARAMS ((int, char **, const char *, const char *, char, char));
895
4eb6b71c 896static void
252b5132
RH
897encode_operand (argc, argv, operandsP, suffixP, im_size, opcode_bit_ptr)
898 int argc;
899 char **argv;
4cd62c96
AM
900 const char *operandsP;
901 const char *suffixP;
4eb6b71c 902 char im_size ATTRIBUTE_UNUSED;
252b5132
RH
903 char opcode_bit_ptr;
904{
4eb6b71c 905 int i, j;
252b5132 906 char d;
4eb6b71c
NC
907 int pcrel, b, loop, pcrel_adjust;
908 unsigned long tmp;
0b7410c4 909
252b5132
RH
910 for (loop = 0; loop < argc; loop++)
911 {
c6a7ab1f
NC
912 /* What operand are we supposed to work on. */
913 i = operandsP[loop << 1] - '1';
252b5132
RH
914 if (i > 3)
915 as_fatal (_("Internal consistency error. check ns32k-opcode.h"));
0b7410c4 916
252b5132
RH
917 pcrel = 0;
918 pcrel_adjust = 0;
919 tmp = 0;
0b7410c4 920
252b5132
RH
921 switch ((d = operandsP[(loop << 1) + 1]))
922 {
4eb6b71c
NC
923 case 'f': /* Operand of sfsr turns out to be a nasty
924 specialcase. */
252b5132 925 opcode_bit_ptr -= 5;
4eb6b71c
NC
926 case 'Z': /* Float not immediate. */
927 case 'F': /* 32 bit float general form. */
928 case 'L': /* 64 bit float. */
929 case 'I': /* Integer not immediate. */
930 case 'B': /* Byte */
931 case 'W': /* Word */
932 case 'D': /* Double-word. */
933 case 'A': /* Double-word gen-address-form ie no regs
934 allowed. */
252b5132 935 get_addr_mode (argv[i], &addr_modeP);
0b7410c4 936
c6a7ab1f
NC
937 if ((addr_modeP.mode == 20) &&
938 (d == 'I' || d == 'Z' || d == 'A'))
939 as_fatal (d == 'A'? _("Address of immediate operand"):
940 _("Invalid immediate write operand."));
252b5132
RH
941
942 if (opcode_bit_ptr == desc->opcode_size)
943 b = 4;
944 else
945 b = 6;
0b7410c4 946
252b5132
RH
947 for (j = b; j < (b + 2); j++)
948 {
949 if (addr_modeP.disp[j - b])
950 {
951 IIF (j,
952 2,
953 addr_modeP.disp_suffix[j - b],
954 (unsigned long) addr_modeP.disp[j - b],
955 0,
956 addr_modeP.pcrel,
957 iif.instr_size,
958 addr_modeP.im_disp,
959 IND (BRANCH, BYTE),
960 NULL,
961 (addr_modeP.scaled_reg ? addr_modeP.scaled_mode
962 : addr_modeP.mode),
963 0);
964 }
965 }
0b7410c4 966
252b5132
RH
967 opcode_bit_ptr -= 5;
968 iif.iifP[1].object |= ((long) addr_modeP.mode) << opcode_bit_ptr;
0b7410c4 969
252b5132
RH
970 if (addr_modeP.scaled_reg)
971 {
972 j = b / 2;
973 IIF (j, 1, 1, (unsigned long) addr_modeP.index_byte,
974 0, 0, 0, 0, 0, NULL, -1, 0);
975 }
976 break;
0b7410c4 977
4eb6b71c
NC
978 case 'b': /* Multiple instruction disp. */
979 freeptr++; /* OVE:this is an useful hack. */
980 sprintf (freeptr, "((%s-1)*%d)", argv[i], desc->im_size);
252b5132 981 argv[i] = freeptr;
4eb6b71c
NC
982 pcrel -= 1; /* Make pcrel 0 inspite of what case 'p':
983 wants. */
252b5132 984 /* fall thru */
4eb6b71c 985 case 'p': /* Displacement - pc relative addressing. */
252b5132
RH
986 pcrel += 1;
987 /* fall thru */
4eb6b71c 988 case 'd': /* Displacement. */
252b5132
RH
989 iif.instr_size += suffixP[i] ? suffixP[i] : 4;
990 IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
991 pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 0);
992 break;
4eb6b71c
NC
993 case 'H': /* Sequent-hack: the linker wants a bit set
994 when bsr. */
252b5132
RH
995 pcrel = 1;
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, 1);
999 break;
1000 case 'q': /* quick */
1001 opcode_bit_ptr -= 4;
1002 IIF (11, 2, 42, (unsigned long) argv[i], 0, 0, 0, 0, 0,
1003 bit_fix_new (4, opcode_bit_ptr, -8, 7, 0, 1, 0), -1, 0);
1004 break;
4eb6b71c 1005 case 'r': /* Register number (3 bits). */
252b5132
RH
1006 list_search (argv[i], opt6, &tmp);
1007 opcode_bit_ptr -= 3;
1008 iif.iifP[1].object |= tmp << opcode_bit_ptr;
1009 break;
4eb6b71c 1010 case 'O': /* Setcfg instruction optionslist. */
252b5132
RH
1011 optlist (argv[i], opt3, &tmp);
1012 opcode_bit_ptr -= 4;
1013 iif.iifP[1].object |= tmp << 15;
1014 break;
4eb6b71c 1015 case 'C': /* Cinv instruction optionslist. */
252b5132
RH
1016 optlist (argv[i], opt4, &tmp);
1017 opcode_bit_ptr -= 4;
4eb6b71c 1018 iif.iifP[1].object |= tmp << 15; /* Insert the regtype in opcode. */
252b5132 1019 break;
4eb6b71c 1020 case 'S': /* String instruction options list. */
252b5132
RH
1021 optlist (argv[i], opt5, &tmp);
1022 opcode_bit_ptr -= 4;
1023 iif.iifP[1].object |= tmp << 15;
1024 break;
1025 case 'u':
4eb6b71c 1026 case 'U': /* Register list. */
252b5132
RH
1027 IIF (10, 1, 1, 0, 0, 0, 0, 0, 0, NULL, -1, 0);
1028 switch (operandsP[(i << 1) + 1])
1029 {
4eb6b71c 1030 case 'u': /* Restore, exit. */
252b5132
RH
1031 optlist (argv[i], opt1, &iif.iifP[10].object);
1032 break;
4eb6b71c 1033 case 'U': /* Save, enter. */
252b5132
RH
1034 optlist (argv[i], opt2, &iif.iifP[10].object);
1035 break;
1036 }
1037 iif.instr_size += 1;
1038 break;
4eb6b71c 1039 case 'M': /* MMU register. */
252b5132
RH
1040 list_search (argv[i], mmureg, &tmp);
1041 opcode_bit_ptr -= 4;
1042 iif.iifP[1].object |= tmp << opcode_bit_ptr;
1043 break;
4eb6b71c 1044 case 'P': /* CPU register. */
252b5132
RH
1045 list_search (argv[i], cpureg, &tmp);
1046 opcode_bit_ptr -= 4;
1047 iif.iifP[1].object |= tmp << opcode_bit_ptr;
1048 break;
4eb6b71c
NC
1049 case 'g': /* Inss exts. */
1050 iif.instr_size += 1; /* 1 byte is allocated after the opcode. */
252b5132 1051 IIF (10, 2, 1,
4eb6b71c 1052 (unsigned long) argv[i], /* i always 2 here. */
252b5132 1053 0, 0, 0, 0, 0,
4eb6b71c
NC
1054 bit_fix_new (3, 5, 0, 7, 0, 0, 0), /* A bit_fix is targeted to
1055 the byte. */
252b5132
RH
1056 -1, 0);
1057 break;
1058 case 'G':
1059 IIF (11, 2, 42,
4eb6b71c 1060 (unsigned long) argv[i], /* i always 3 here. */
252b5132
RH
1061 0, 0, 0, 0, 0,
1062 bit_fix_new (5, 0, 1, 32, -1, 0, -1), -1, 0);
1063 break;
1064 case 'i':
1065 iif.instr_size += 1;
4eb6b71c 1066 b = 2 + i; /* Put the extension byte after opcode. */
252b5132
RH
1067 IIF (b, 2, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0);
1068 break;
1069 default:
1070 as_fatal (_("Bad opcode-table-option, check in file ns32k-opcode.h"));
1071 }
1072 }
1073}
1074\f
1075/* in: instruction line
1076 out: internal structure of instruction
1077 that has been prepared for direct conversion to fragment(s) and
1078 fixes in a systematical fashion
4eb6b71c 1079 Return-value = recursive_level. */
c6a7ab1f
NC
1080/* Build iif of one assembly text line. */
1081
4cd62c96
AM
1082static int parse PARAMS ((const char *, int));
1083
4eb6b71c 1084static int
252b5132 1085parse (line, recursive_level)
4cd62c96 1086 const char *line;
252b5132
RH
1087 int recursive_level;
1088{
4cd62c96
AM
1089 const char *lineptr;
1090 char c, suffix_separator;
4eb6b71c
NC
1091 int i;
1092 unsigned int argc;
1093 int arg_type;
252b5132 1094 char sqr, sep;
c6a7ab1f 1095 char suffix[MAX_ARGS], *argv[MAX_ARGS]; /* No more than 4 operands. */
0b7410c4 1096
252b5132 1097 if (recursive_level <= 0)
c6a7ab1f
NC
1098 {
1099 /* Called from md_assemble. */
1100 for (lineptr = line; (*lineptr) != '\0' && (*lineptr) != ' '; lineptr++)
1101 continue;
0b7410c4 1102
252b5132 1103 c = *lineptr;
4cd62c96 1104 *(char *) lineptr = '\0';
0b7410c4 1105
252b5132 1106 if (!(desc = (struct ns32k_opcode *) hash_find (inst_hash_handle, line)))
c6a7ab1f
NC
1107 as_fatal (_("No such opcode"));
1108
4cd62c96 1109 *(char *) lineptr = c;
252b5132
RH
1110 }
1111 else
1112 {
1113 lineptr = line;
1114 }
0b7410c4 1115
252b5132 1116 argc = 0;
0b7410c4 1117
252b5132
RH
1118 if (*desc->operands)
1119 {
1120 if (*lineptr++ != '\0')
1121 {
1122 sqr = '[';
1123 sep = ',';
0b7410c4 1124
252b5132
RH
1125 while (*lineptr != '\0')
1126 {
1127 if (desc->operands[argc << 1])
1128 {
1129 suffix[argc] = 0;
1130 arg_type = desc->operands[(argc << 1) + 1];
0b7410c4 1131
252b5132
RH
1132 switch (arg_type)
1133 {
1134 case 'd':
1135 case 'b':
1136 case 'p':
c6a7ab1f
NC
1137 case 'H':
1138 /* The operand is supposed to be a displacement. */
252b5132 1139 /* Hackwarning: do not forget to update the 4
c6a7ab1f 1140 cases above when editing ns32k-opcode.h. */
252b5132
RH
1141 suffix_separator = ':';
1142 break;
1143 default:
c6a7ab1f
NC
1144 /* If this char occurs we loose. */
1145 suffix_separator = '\255';
1146 break;
252b5132 1147 }
0b7410c4 1148
4eb6b71c 1149 suffix[argc] = 0; /* 0 when no ':' is encountered. */
252b5132
RH
1150 argv[argc] = freeptr;
1151 *freeptr = '\0';
0b7410c4 1152
252b5132
RH
1153 while ((c = *lineptr) != '\0' && c != sep)
1154 {
1155 if (c == sqr)
1156 {
1157 if (sqr == '[')
1158 {
1159 sqr = ']';
1160 sep = '\0';
1161 }
1162 else
1163 {
1164 sqr = '[';
1165 sep = ',';
1166 }
1167 }
0b7410c4 1168
252b5132 1169 if (c == suffix_separator)
c6a7ab1f
NC
1170 {
1171 /* ':' - label/suffix separator. */
252b5132
RH
1172 switch (lineptr[1])
1173 {
1174 case 'b':
1175 suffix[argc] = 1;
1176 break;
1177 case 'w':
1178 suffix[argc] = 2;
1179 break;
1180 case 'd':
1181 suffix[argc] = 4;
1182 break;
1183 default:
1184 as_warn (_("Bad suffix, defaulting to d"));
1185 suffix[argc] = 4;
1186 if (lineptr[1] == '\0' || lineptr[1] == sep)
1187 {
1188 lineptr += 1;
1189 continue;
1190 }
c6a7ab1f 1191 break;
252b5132 1192 }
0b7410c4 1193
252b5132
RH
1194 lineptr += 2;
1195 continue;
1196 }
0b7410c4 1197
252b5132
RH
1198 *freeptr++ = c;
1199 lineptr++;
1200 }
0b7410c4 1201
252b5132
RH
1202 *freeptr++ = '\0';
1203 argc += 1;
0b7410c4 1204
252b5132
RH
1205 if (*lineptr == '\0')
1206 continue;
0b7410c4 1207
252b5132
RH
1208 lineptr += 1;
1209 }
1210 else
1211 {
1212 as_fatal (_("Too many operands passed to instruction"));
1213 }
1214 }
1215 }
1216 }
0b7410c4 1217
252b5132
RH
1218 if (argc != strlen (desc->operands) / 2)
1219 {
1220 if (strlen (desc->default_args))
c6a7ab1f
NC
1221 {
1222 /* We can apply default, don't goof. */
252b5132 1223 if (parse (desc->default_args, 1) != 1)
c6a7ab1f
NC
1224 /* Check error in default. */
1225 as_fatal (_("Wrong numbers of operands in default, check ns32k-opcodes.h"));
252b5132
RH
1226 }
1227 else
1228 {
1229 as_fatal (_("Wrong number of operands"));
1230 }
252b5132 1231 }
0b7410c4 1232
252b5132 1233 for (i = 0; i < IIF_ENTRIES; i++)
c6a7ab1f
NC
1234 /* Mark all entries as void. */
1235 iif.iifP[i].type = 0;
252b5132 1236
c6a7ab1f 1237 /* Build opcode iif-entry. */
252b5132
RH
1238 iif.instr_size = desc->opcode_size / 8;
1239 IIF (1, 1, iif.instr_size, desc->opcode_seed, 0, 0, 0, 0, 0, 0, -1, 0);
1240
c6a7ab1f 1241 /* This call encodes operands to iif format. */
252b5132
RH
1242 if (argc)
1243 {
1244 encode_operand (argc,
1245 argv,
1246 &desc->operands[0],
1247 &suffix[0],
1248 desc->im_size,
1249 desc->opcode_size);
1250 }
1251 return recursive_level;
1252}
1253\f
252b5132 1254/* Convert iif to fragments. From this point we start to dribble with
c6a7ab1f
NC
1255 functions in other files than this one.(Except hash.c) So, if it's
1256 possible to make an iif for an other CPU, you don't need to know
1257 what frags, relax, obstacks, etc is in order to port this
1258 assembler. You only need to know if it's possible to reduce your
1259 cpu-instruction to iif-format (takes some work) and adopt the other
1260 md_? parts according to given instructions Note that iif was
1261 invented for the clean ns32k`s architecure. */
252b5132
RH
1262
1263/* GAS for the ns32k has a problem. PC relative displacements are
c6a7ab1f
NC
1264 relative to the address of the opcode, not the address of the
1265 operand. We used to keep track of the offset between the operand
1266 and the opcode in pcrel_adjust for each frag and each fix. However,
1267 we get into trouble where there are two or more pc-relative
1268 operands and the size of the first one can't be determined. Then in
1269 the relax phase, the size of the first operand will change and
1270 pcrel_adjust will no longer be correct. The current solution is
1271 keep a pointer to the frag with the opcode in it and the offset in
1272 that frag for each frag and each fix. Then, when needed, we can
1273 always figure out how far it is between the opcode and the pcrel
1274 object. See also md_pcrel_adjust and md_fix_pcrel_adjust. For
1275 objects not part of an instruction, the pointer to the opcode frag
1276 is always zero. */
252b5132 1277
4eb6b71c
NC
1278static void convert_iif PARAMS ((void));
1279static void
252b5132
RH
1280convert_iif ()
1281{
1282 int i;
1283 bit_fixS *j;
1284 fragS *inst_frag;
1285 unsigned int inst_offset;
1286 char *inst_opcode;
1287 char *memP;
1288 int l;
1289 int k;
1290 char type;
1291 char size = 0;
252b5132 1292
4eb6b71c 1293 frag_grow (iif.instr_size); /* This is important. */
252b5132
RH
1294 memP = frag_more (0);
1295 inst_opcode = memP;
1296 inst_offset = (memP - frag_now->fr_literal);
1297 inst_frag = frag_now;
1298
1299 for (i = 0; i < IIF_ENTRIES; i++)
1300 {
4eb6b71c 1301 if ((type = iif.iifP[i].type))
c6a7ab1f
NC
1302 {
1303 /* The object exist, so handle it. */
252b5132
RH
1304 switch (size = iif.iifP[i].size)
1305 {
1306 case 42:
c6a7ab1f
NC
1307 size = 0;
1308 /* It's a bitfix that operates on an existing object. */
252b5132 1309 if (iif.iifP[i].bit_fixP->fx_bit_base)
c6a7ab1f
NC
1310 /* Expand fx_bit_base to point at opcode. */
1311 iif.iifP[i].bit_fixP->fx_bit_base = (long) inst_opcode;
1312 /* Fall through. */
0b7410c4 1313
4eb6b71c 1314 case 8: /* bignum or doublefloat. */
252b5132
RH
1315 case 1:
1316 case 2:
1317 case 3:
c6a7ab1f
NC
1318 case 4:
1319 /* The final size in objectmemory is known. */
07726851 1320 memP = frag_more (size);
252b5132 1321 j = iif.iifP[i].bit_fixP;
0b7410c4 1322
252b5132
RH
1323 switch (type)
1324 {
c6a7ab1f 1325 case 1: /* The object is pure binary. */
4eb6b71c
NC
1326 if (j)
1327 {
1328 md_number_to_field(memP, exprP.X_add_number, j);
1329 }
1330 else if (iif.iifP[i].pcrel)
252b5132
RH
1331 {
1332 fix_new_ns32k (frag_now,
1333 (long) (memP - frag_now->fr_literal),
1334 size,
1335 0,
1336 iif.iifP[i].object,
1337 iif.iifP[i].pcrel,
1338 iif.iifP[i].im_disp,
4eb6b71c
NC
1339 0,
1340 iif.iifP[i].bsr, /* Sequent hack. */
252b5132
RH
1341 inst_frag, inst_offset);
1342 }
1343 else
c6a7ab1f
NC
1344 {
1345 /* Good, just put them bytes out. */
252b5132
RH
1346 switch (iif.iifP[i].im_disp)
1347 {
1348 case 0:
1349 md_number_to_chars (memP, iif.iifP[i].object, size);
1350 break;
1351 case 1:
1352 md_number_to_disp (memP, iif.iifP[i].object, size);
1353 break;
1354 default:
1355 as_fatal (_("iif convert internal pcrel/binary"));
1356 }
1357 }
1358 break;
0b7410c4 1359
252b5132 1360 case 2:
c6a7ab1f 1361 /* The object is a pointer at an expression, so
252b5132 1362 unpack it, note that bignums may result from the
c6a7ab1f 1363 expression. */
252b5132
RH
1364 evaluate_expr (&exprP, (char *) iif.iifP[i].object);
1365 if (exprP.X_op == O_big || size == 8)
1366 {
1367 if ((k = exprP.X_add_number) > 0)
1368 {
c6a7ab1f
NC
1369 /* We have a bignum ie a quad. This can only
1370 happens in a long suffixed instruction. */
252b5132 1371 if (k * 2 > size)
4eb6b71c 1372 as_bad (_("Bignum too big for long"));
0b7410c4 1373
252b5132
RH
1374 if (k == 3)
1375 memP += 2;
0b7410c4 1376
252b5132 1377 for (l = 0; k > 0; k--, l += 2)
4eb6b71c
NC
1378 md_number_to_chars (memP + l,
1379 generic_bignum[l >> 1],
1380 sizeof (LITTLENUM_TYPE));
252b5132
RH
1381 }
1382 else
c6a7ab1f
NC
1383 {
1384 /* flonum. */
252b5132
RH
1385 LITTLENUM_TYPE words[4];
1386
1387 switch (size)
1388 {
1389 case 4:
1390 gen_to_words (words, 2, 8);
1391 md_number_to_imm (memP, (long) words[0],
1392 sizeof (LITTLENUM_TYPE));
1393 md_number_to_imm (memP + sizeof (LITTLENUM_TYPE),
1394 (long) words[1],
1395 sizeof (LITTLENUM_TYPE));
1396 break;
1397 case 8:
1398 gen_to_words (words, 4, 11);
1399 md_number_to_imm (memP, (long) words[0],
1400 sizeof (LITTLENUM_TYPE));
1401 md_number_to_imm (memP + sizeof (LITTLENUM_TYPE),
1402 (long) words[1],
1403 sizeof (LITTLENUM_TYPE));
1404 md_number_to_imm ((memP + 2
1405 * sizeof (LITTLENUM_TYPE)),
1406 (long) words[2],
1407 sizeof (LITTLENUM_TYPE));
1408 md_number_to_imm ((memP + 3
1409 * sizeof (LITTLENUM_TYPE)),
1410 (long) words[3],
1411 sizeof (LITTLENUM_TYPE));
1412 break;
1413 }
1414 }
1415 break;
1416 }
4eb6b71c 1417 if (exprP.X_add_symbol ||
252b5132
RH
1418 exprP.X_op_symbol ||
1419 iif.iifP[i].pcrel)
1420 {
1421 /* The expression was undefined due to an
1422 undefined label. Create a fix so we can fix
c6a7ab1f 1423 the object later. */
252b5132
RH
1424 exprP.X_add_number += iif.iifP[i].object_adjust;
1425 fix_new_ns32k_exp (frag_now,
1426 (long) (memP - frag_now->fr_literal),
1427 size,
1428 &exprP,
1429 iif.iifP[i].pcrel,
1430 iif.iifP[i].im_disp,
1431 j,
1432 iif.iifP[i].bsr,
1433 inst_frag, inst_offset);
1434 }
4eb6b71c
NC
1435 else if (j)
1436 {
1437 md_number_to_field(memP, exprP.X_add_number, j);
1438 }
252b5132
RH
1439 else
1440 {
c6a7ab1f 1441 /* Good, just put them bytes out. */
252b5132
RH
1442 switch (iif.iifP[i].im_disp)
1443 {
1444 case 0:
1445 md_number_to_imm (memP, exprP.X_add_number, size);
1446 break;
1447 case 1:
1448 md_number_to_disp (memP, exprP.X_add_number, size);
1449 break;
1450 default:
1451 as_fatal (_("iif convert internal pcrel/pointer"));
1452 }
1453 }
1454 break;
1455 default:
1456 as_fatal (_("Internal logic error in iif.iifP[n].type"));
1457 }
1458 break;
0b7410c4 1459
252b5132 1460 case 0:
c6a7ab1f 1461 /* Too bad, the object may be undefined as far as its
252b5132
RH
1462 final nsize in object memory is concerned. The size
1463 of the object in objectmemory is not explicitly
1464 given. If the object is defined its length can be
c6a7ab1f 1465 determined and a fix can replace the frag. */
252b5132
RH
1466 {
1467 evaluate_expr (&exprP, (char *) iif.iifP[i].object);
0b7410c4 1468
252b5132
RH
1469 if ((exprP.X_add_symbol || exprP.X_op_symbol) &&
1470 !iif.iifP[i].pcrel)
1471 {
4eb6b71c
NC
1472 /* Size is unknown until link time so have to default. */
1473 size = default_disp_size; /* Normally 4 bytes. */
07726851 1474 memP = frag_more (size);
252b5132
RH
1475 fix_new_ns32k_exp (frag_now,
1476 (long) (memP - frag_now->fr_literal),
1477 size,
1478 &exprP,
1479 0, /* never iif.iifP[i].pcrel, */
1480 1, /* always iif.iifP[i].im_disp */
1481 (bit_fixS *) 0, 0,
1482 inst_frag,
1483 inst_offset);
4eb6b71c 1484 break; /* Exit this absolute hack. */
252b5132
RH
1485 }
1486
1487 if (exprP.X_add_symbol || exprP.X_op_symbol)
c6a7ab1f
NC
1488 {
1489 /* Frag it. */
252b5132 1490 if (exprP.X_op_symbol)
c6a7ab1f
NC
1491 {
1492 /* We cant relax this case. */
252b5132
RH
1493 as_fatal (_("Can't relax difference"));
1494 }
1495 else
1496 {
c6a7ab1f
NC
1497 /* Size is not important. This gets fixed by
1498 relax, but we assume 0 in what follows. */
07726851 1499 memP = frag_more (4); /* Max size. */
252b5132
RH
1500 size = 0;
1501
1502 {
1503 fragS *old_frag = frag_now;
1504 frag_variant (rs_machine_dependent,
c6a7ab1f
NC
1505 4, /* Max size. */
1506 0, /* Size. */
1507 IND (BRANCH, UNDEF), /* Expecting
1508 the worst. */
252b5132
RH
1509 exprP.X_add_symbol,
1510 exprP.X_add_number,
1511 inst_opcode);
c6a7ab1f
NC
1512 frag_opcode_frag (old_frag) = inst_frag;
1513 frag_opcode_offset (old_frag) = inst_offset;
1514 frag_bsr (old_frag) = iif.iifP[i].bsr;
252b5132
RH
1515 }
1516 }
1517 }
1518 else
1519 {
c6a7ab1f 1520 /* This duplicates code in md_number_to_disp. */
252b5132
RH
1521 if (-64 <= exprP.X_add_number && exprP.X_add_number <= 63)
1522 {
1523 size = 1;
1524 }
1525 else
1526 {
1527 if (-8192 <= exprP.X_add_number
1528 && exprP.X_add_number <= 8191)
1529 {
1530 size = 2;
1531 }
1532 else
1533 {
c6a7ab1f
NC
1534 if (-0x20000000 <= exprP.X_add_number
1535 && exprP.X_add_number<=0x1fffffff)
252b5132
RH
1536 {
1537 size = 4;
1538 }
1539 else
1540 {
4eb6b71c 1541 as_bad (_("Displacement to large for :d"));
252b5132
RH
1542 size = 4;
1543 }
1544 }
1545 }
0b7410c4 1546
c6a7ab1f 1547 memP = frag_more (size);
252b5132
RH
1548 md_number_to_disp (memP, exprP.X_add_number, size);
1549 }
1550 }
1551 break;
0b7410c4 1552
252b5132
RH
1553 default:
1554 as_fatal (_("Internal logic error in iif.iifP[].type"));
1555 }
1556 }
1557 }
1558}
1559\f
1560#ifdef BFD_ASSEMBLER
c6a7ab1f 1561/* This functionality should really be in the bfd library. */
252b5132
RH
1562static bfd_reloc_code_real_type
1563reloc (int size, int pcrel, int type)
1564{
1565 int length, index;
c6a7ab1f
NC
1566 bfd_reloc_code_real_type relocs[] =
1567 {
252b5132
RH
1568 BFD_RELOC_NS32K_IMM_8,
1569 BFD_RELOC_NS32K_IMM_16,
1570 BFD_RELOC_NS32K_IMM_32,
1571 BFD_RELOC_NS32K_IMM_8_PCREL,
1572 BFD_RELOC_NS32K_IMM_16_PCREL,
1573 BFD_RELOC_NS32K_IMM_32_PCREL,
1574
c6a7ab1f 1575 /* ns32k displacements. */
252b5132
RH
1576 BFD_RELOC_NS32K_DISP_8,
1577 BFD_RELOC_NS32K_DISP_16,
1578 BFD_RELOC_NS32K_DISP_32,
1579 BFD_RELOC_NS32K_DISP_8_PCREL,
1580 BFD_RELOC_NS32K_DISP_16_PCREL,
1581 BFD_RELOC_NS32K_DISP_32_PCREL,
1582
c6a7ab1f 1583 /* Normal 2's complement. */
252b5132
RH
1584 BFD_RELOC_8,
1585 BFD_RELOC_16,
1586 BFD_RELOC_32,
1587 BFD_RELOC_8_PCREL,
1588 BFD_RELOC_16_PCREL,
1589 BFD_RELOC_32_PCREL
c6a7ab1f 1590 };
0b7410c4 1591
252b5132
RH
1592 switch (size)
1593 {
1594 case 1:
1595 length = 0;
1596 break;
1597 case 2:
1598 length = 1;
1599 break;
1600 case 4:
1601 length = 2;
1602 break;
1603 default:
1604 length = -1;
1605 break;
1606 }
0b7410c4 1607
252b5132 1608 index = length + 3 * pcrel + 6 * type;
0b7410c4 1609
4eb6b71c 1610 if (index >= 0 && (unsigned int) index < sizeof (relocs) / sizeof (relocs[0]))
252b5132 1611 return relocs[index];
0b7410c4 1612
252b5132
RH
1613 if (pcrel)
1614 as_bad (_("Can not do %d byte pc-relative relocation for storage type %d"),
1615 size, type);
1616 else
1617 as_bad (_("Can not do %d byte relocation for storage type %d"),
1618 size, type);
0b7410c4 1619
252b5132
RH
1620 return BFD_RELOC_NONE;
1621
1622}
252b5132
RH
1623#endif
1624
1625void
1626md_assemble (line)
1627 char *line;
1628{
1629 freeptr = freeptr_static;
c6a7ab1f
NC
1630 parse (line, 0); /* Explode line to more fix form in iif. */
1631 convert_iif (); /* Convert iif to frags, fix's etc. */
252b5132
RH
1632#ifdef SHOW_NUM
1633 printf (" \t\t\t%s\n", line);
1634#endif
1635}
1636
252b5132
RH
1637void
1638md_begin ()
1639{
c6a7ab1f 1640 /* Build a hashtable of the instructions. */
252b5132
RH
1641 const struct ns32k_opcode *ptr;
1642 const char *stat;
1643 inst_hash_handle = hash_new ();
4cd62c96 1644 const struct ns32k_opcode *endop;
c6a7ab1f 1645
4cd62c96 1646 endop = ns32k_opcodes + sizeof (ns32k_opcodes) / sizeof (ns32k_opcodes[0]);
252b5132
RH
1647 for (ptr = ns32k_opcodes; ptr < endop; ptr++)
1648 {
1649 if ((stat = hash_insert (inst_hash_handle, ptr->name, (char *) ptr)))
c6a7ab1f
NC
1650 /* Fatal. */
1651 as_fatal (_("Can't hash %s: %s"), ptr->name, stat);
252b5132 1652 }
c6a7ab1f
NC
1653
1654 /* Some private space please! */
1655 freeptr_static = (char *) malloc (PRIVATE_SIZE);
252b5132
RH
1656}
1657
c6a7ab1f 1658/* Must be equal to MAX_PRECISON in atof-ieee.c. */
252b5132
RH
1659#define MAX_LITTLENUMS 6
1660
1661/* Turn the string pointed to by litP into a floating point constant
bc0d738a
NC
1662 of type TYPE, and emit the appropriate bytes. The number of
1663 LITTLENUMS emitted is stored in *SIZEP. An error message is
252b5132 1664 returned, or NULL on OK. */
bc0d738a 1665
252b5132
RH
1666char *
1667md_atof (type, litP, sizeP)
1668 char type;
1669 char *litP;
1670 int *sizeP;
1671{
1672 int prec;
1673 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1674 LITTLENUM_TYPE *wordP;
1675 char *t;
1676
1677 switch (type)
1678 {
1679 case 'f':
1680 prec = 2;
1681 break;
1682
1683 case 'd':
1684 prec = 4;
1685 break;
1686 default:
1687 *sizeP = 0;
1688 return _("Bad call to MD_ATOF()");
1689 }
0b7410c4 1690
252b5132
RH
1691 t = atof_ieee (input_line_pointer, type, words);
1692 if (t)
1693 input_line_pointer = t;
1694
1695 *sizeP = prec * sizeof (LITTLENUM_TYPE);
0b7410c4 1696
252b5132
RH
1697 for (wordP = words + prec; prec--;)
1698 {
1699 md_number_to_chars (litP, (long) (*--wordP), sizeof (LITTLENUM_TYPE));
1700 litP += sizeof (LITTLENUM_TYPE);
1701 }
0b7410c4 1702
252b5132
RH
1703 return 0;
1704}
1705\f
c6a7ab1f 1706/* Convert number to chars in correct order. */
252b5132
RH
1707
1708void
1709md_number_to_chars (buf, value, nbytes)
1710 char *buf;
1711 valueT value;
1712 int nbytes;
1713{
1714 number_to_chars_littleendian (buf, value, nbytes);
1715}
1716
252b5132
RH
1717/* This is a variant of md_numbers_to_chars. The reason for its'
1718 existence is the fact that ns32k uses Huffman coded
1719 displacements. This implies that the bit order is reversed in
1720 displacements and that they are prefixed with a size-tag.
1721
1722 binary: msb -> lsb
1723 0xxxxxxx byte
1724 10xxxxxx xxxxxxxx word
1725 11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx double word
1726
1727 This must be taken care of and we do it here! */
c6a7ab1f 1728
252b5132
RH
1729static void
1730md_number_to_disp (buf, val, n)
1731 char *buf;
1732 long val;
1733 char n;
1734{
1735 switch (n)
1736 {
1737 case 1:
1738 if (val < -64 || val > 63)
4eb6b71c 1739 as_bad (_("value of %ld out of byte displacement range."), val);
252b5132
RH
1740 val &= 0x7f;
1741#ifdef SHOW_NUM
1742 printf ("%x ", val & 0xff);
1743#endif
1744 *buf++ = val;
1745 break;
1746 case 2:
1747 if (val < -8192 || val > 8191)
4eb6b71c 1748 as_bad (_("value of %ld out of word displacement range."), val);
252b5132
RH
1749 val &= 0x3fff;
1750 val |= 0x8000;
1751#ifdef SHOW_NUM
1752 printf ("%x ", val >> 8 & 0xff);
1753#endif
1754 *buf++ = (val >> 8);
1755#ifdef SHOW_NUM
1756 printf ("%x ", val & 0xff);
1757#endif
1758 *buf++ = val;
1759 break;
1760 case 4:
1761 if (val < -0x20000000 || val >= 0x20000000)
4eb6b71c 1762 as_bad (_("value of %ld out of double word displacement range."), val);
252b5132
RH
1763 val |= 0xc0000000;
1764#ifdef SHOW_NUM
1765 printf ("%x ", val >> 24 & 0xff);
1766#endif
1767 *buf++ = (val >> 24);
1768#ifdef SHOW_NUM
1769 printf ("%x ", val >> 16 & 0xff);
1770#endif
1771 *buf++ = (val >> 16);
1772#ifdef SHOW_NUM
1773 printf ("%x ", val >> 8 & 0xff);
1774#endif
1775 *buf++ = (val >> 8);
1776#ifdef SHOW_NUM
1777 printf ("%x ", val & 0xff);
1778#endif
1779 *buf++ = val;
1780 break;
1781 default:
4eb6b71c 1782 as_fatal (_("Internal logic error. line %d, file \"%s\""),
252b5132
RH
1783 __LINE__, __FILE__);
1784 }
1785}
1786
1787static void
1788md_number_to_imm (buf, val, n)
1789 char *buf;
1790 long val;
1791 char n;
1792{
1793 switch (n)
1794 {
1795 case 1:
1796#ifdef SHOW_NUM
1797 printf ("%x ", val & 0xff);
1798#endif
1799 *buf++ = val;
1800 break;
1801 case 2:
1802#ifdef SHOW_NUM
1803 printf ("%x ", val >> 8 & 0xff);
1804#endif
1805 *buf++ = (val >> 8);
1806#ifdef SHOW_NUM
1807 printf ("%x ", val & 0xff);
1808#endif
1809 *buf++ = val;
1810 break;
1811 case 4:
1812#ifdef SHOW_NUM
1813 printf ("%x ", val >> 24 & 0xff);
1814#endif
1815 *buf++ = (val >> 24);
1816#ifdef SHOW_NUM
1817 printf ("%x ", val >> 16 & 0xff);
1818#endif
1819 *buf++ = (val >> 16);
1820#ifdef SHOW_NUM
1821 printf ("%x ", val >> 8 & 0xff);
1822#endif
1823 *buf++ = (val >> 8);
1824#ifdef SHOW_NUM
1825 printf ("%x ", val & 0xff);
1826#endif
1827 *buf++ = val;
1828 break;
1829 default:
4eb6b71c 1830 as_fatal (_("Internal logic error. line %d, file \"%s\""),
252b5132
RH
1831 __LINE__, __FILE__);
1832 }
1833}
1834
c6a7ab1f
NC
1835/* Fast bitfiddling support. */
1836/* Mask used to zero bitfield before oring in the true field. */
252b5132
RH
1837
1838static unsigned long l_mask[] =
1839{
1840 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
1841 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
1842 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
1843 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
1844 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
1845 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
1846 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
1847 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000,
1848};
1849static unsigned long r_mask[] =
1850{
1851 0x00000000, 0x00000001, 0x00000003, 0x00000007,
1852 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
1853 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
1854 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
1855 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
1856 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
1857 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
1858 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
1859};
1860#define MASK_BITS 31
1861/* Insert bitfield described by field_ptr and val at buf
1862 This routine is written for modification of the first 4 bytes pointed
1863 to by buf, to yield speed.
1864 The ifdef stuff is for selection between a ns32k-dependent routine
c6a7ab1f 1865 and a general version. (My advice: use the general version!). */
252b5132
RH
1866
1867static void
1868md_number_to_field (buf, val, field_ptr)
4eb6b71c
NC
1869 char *buf;
1870 long val;
1871 bit_fixS *field_ptr;
252b5132 1872{
4eb6b71c
NC
1873 unsigned long object;
1874 unsigned long mask;
1875 /* Define ENDIAN on a ns32k machine. */
252b5132 1876#ifdef ENDIAN
4eb6b71c 1877 unsigned long *mem_ptr;
252b5132 1878#else
4eb6b71c 1879 char *mem_ptr;
252b5132 1880#endif
4eb6b71c 1881
252b5132
RH
1882 if (field_ptr->fx_bit_min <= val && val <= field_ptr->fx_bit_max)
1883 {
1884#ifdef ENDIAN
1885 if (field_ptr->fx_bit_base)
c6a7ab1f
NC
1886 /* Override buf. */
1887 mem_ptr = (unsigned long *) field_ptr->fx_bit_base;
252b5132 1888 else
c6a7ab1f 1889 mem_ptr = (unsigned long *) buf;
0b7410c4 1890
252b5132
RH
1891 mem_ptr = ((unsigned long *)
1892 ((char *) mem_ptr + field_ptr->fx_bit_base_adj));
1893#else
1894 if (field_ptr->fx_bit_base)
c6a7ab1f 1895 mem_ptr = (char *) field_ptr->fx_bit_base;
252b5132 1896 else
c6a7ab1f
NC
1897 mem_ptr = buf;
1898
252b5132
RH
1899 mem_ptr += field_ptr->fx_bit_base_adj;
1900#endif
c6a7ab1f
NC
1901#ifdef ENDIAN
1902 /* We have a nice ns32k machine with lowbyte at low-physical mem. */
252b5132 1903 object = *mem_ptr; /* get some bytes */
4eb6b71c 1904#else /* OVE Goof! the machine is a m68k or dito. */
c6a7ab1f 1905 /* That takes more byte fiddling. */
252b5132
RH
1906 object = 0;
1907 object |= mem_ptr[3] & 0xff;
1908 object <<= 8;
1909 object |= mem_ptr[2] & 0xff;
1910 object <<= 8;
1911 object |= mem_ptr[1] & 0xff;
1912 object <<= 8;
1913 object |= mem_ptr[0] & 0xff;
1914#endif
1915 mask = 0;
1916 mask |= (r_mask[field_ptr->fx_bit_offset]);
1917 mask |= (l_mask[field_ptr->fx_bit_offset + field_ptr->fx_bit_size]);
1918 object &= mask;
1919 val += field_ptr->fx_bit_add;
1920 object |= ((val << field_ptr->fx_bit_offset) & (mask ^ 0xffffffff));
1921#ifdef ENDIAN
1922 *mem_ptr = object;
1923#else
1924 mem_ptr[0] = (char) object;
1925 object >>= 8;
1926 mem_ptr[1] = (char) object;
1927 object >>= 8;
1928 mem_ptr[2] = (char) object;
1929 object >>= 8;
1930 mem_ptr[3] = (char) object;
1931#endif
1932 }
1933 else
1934 {
4eb6b71c 1935 as_bad (_("Bit field out of range"));
252b5132
RH
1936 }
1937}
1938
c6a7ab1f
NC
1939int
1940md_pcrel_adjust (fragP)
1941 fragS *fragP;
252b5132
RH
1942{
1943 fragS *opcode_frag;
1944 addressT opcode_address;
1945 unsigned int offset;
0b7410c4 1946
c6a7ab1f 1947 opcode_frag = frag_opcode_frag (fragP);
252b5132
RH
1948 if (opcode_frag == 0)
1949 return 0;
0b7410c4 1950
c6a7ab1f 1951 offset = frag_opcode_offset (fragP);
252b5132 1952 opcode_address = offset + opcode_frag->fr_address;
0b7410c4 1953
252b5132
RH
1954 return fragP->fr_address + fragP->fr_fix - opcode_address;
1955}
1956
4eb6b71c
NC
1957static int md_fix_pcrel_adjust PARAMS ((fixS *fixP));
1958static int
c6a7ab1f
NC
1959md_fix_pcrel_adjust (fixP)
1960 fixS *fixP;
252b5132 1961{
252b5132
RH
1962 fragS *opcode_frag;
1963 addressT opcode_address;
1964 unsigned int offset;
0b7410c4 1965
c6a7ab1f 1966 opcode_frag = fix_opcode_frag (fixP);
252b5132
RH
1967 if (opcode_frag == 0)
1968 return 0;
0b7410c4 1969
c6a7ab1f 1970 offset = fix_opcode_offset (fixP);
252b5132 1971 opcode_address = offset + opcode_frag->fr_address;
0b7410c4 1972
252b5132
RH
1973 return fixP->fx_where + fixP->fx_frag->fr_address - opcode_address;
1974}
1975
1976/* Apply a fixS (fixup of an instruction or data that we didn't have
1977 enough info to complete immediately) to the data in a frag.
1978
1979 On the ns32k, everything is in a different format, so we have broken
1980 out separate functions for each kind of thing we could be fixing.
1981 They all get called from here. */
1982
252b5132 1983void
94f592af 1984md_apply_fix3 (fixP, valP, seg)
252b5132 1985 fixS *fixP;
94f592af
NC
1986 valueT * valP;
1987 segT seg ATTRIBUTE_UNUSED;
252b5132 1988{
94f592af 1989 long val = * (long *) valP;
252b5132
RH
1990 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1991
c6a7ab1f 1992 if (fix_bit_fixP (fixP))
4eb6b71c
NC
1993 {
1994 /* Bitfields to fix, sigh. */
1995 md_number_to_field (buf, val, fix_bit_fixP (fixP));
1996 }
94f592af
NC
1997 else switch (fix_im_disp (fixP))
1998 {
1999 case 0:
2000 /* Immediate field. */
2001 md_number_to_imm (buf, val, fixP->fx_size);
2002 break;
252b5132 2003
94f592af
NC
2004 case 1:
2005 /* Displacement field. */
4eb6b71c 2006 /* Calculate offset. */
94f592af
NC
2007 md_number_to_disp (buf,
2008 (fixP->fx_pcrel ? val + md_fix_pcrel_adjust (fixP)
2009 : val), fixP->fx_size);
2010 break;
2011
2012 case 2:
2013 /* Pointer in a data object. */
2014 md_number_to_chars (buf, val, fixP->fx_size);
2015 break;
2016 }
2017
2018 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
2019 fixP->fx_done = 1;
252b5132
RH
2020}
2021\f
4eb6b71c 2022/* Convert a relaxed displacement to ditto in final output. */
252b5132
RH
2023
2024#ifndef BFD_ASSEMBLER
2025void
2026md_convert_frag (headers, sec, fragP)
2027 object_headers *headers;
2028 segT sec;
4eb6b71c 2029 fragS *fragP;
252b5132
RH
2030#else
2031void
2032md_convert_frag (abfd, sec, fragP)
4eb6b71c
NC
2033 bfd *abfd ATTRIBUTE_UNUSED;
2034 segT sec ATTRIBUTE_UNUSED;
2035 fragS *fragP;
252b5132
RH
2036#endif
2037{
2038 long disp;
2039 long ext = 0;
252b5132 2040 /* Address in gas core of the place to store the displacement. */
4eb6b71c 2041 char *buffer_address = fragP->fr_fix + fragP->fr_literal;
252b5132
RH
2042 /* Address in object code of the displacement. */
2043 int object_address;
2044
252b5132
RH
2045 switch (fragP->fr_subtype)
2046 {
2047 case IND (BRANCH, BYTE):
2048 ext = 1;
2049 break;
2050 case IND (BRANCH, WORD):
2051 ext = 2;
2052 break;
2053 case IND (BRANCH, DOUBLE):
2054 ext = 4;
2055 break;
2056 }
2057
c6a7ab1f 2058 if (ext == 0)
252b5132
RH
2059 return;
2060
2061 know (fragP->fr_symbol);
2062
2063 object_address = fragP->fr_fix + fragP->fr_address;
0b7410c4 2064
252b5132
RH
2065 /* The displacement of the address, from current location. */
2066 disp = (S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset) - object_address;
c6a7ab1f 2067 disp += md_pcrel_adjust (fragP);
252b5132
RH
2068
2069 md_number_to_disp (buffer_address, (long) disp, (int) ext);
2070 fragP->fr_fix += ext;
2071}
2072
2073/* This function returns the estimated size a variable object will occupy,
2074 one can say that we tries to guess the size of the objects before we
c6a7ab1f 2075 actually know it. */
252b5132
RH
2076
2077int
2078md_estimate_size_before_relax (fragP, segment)
4eb6b71c 2079 fragS *fragP;
252b5132
RH
2080 segT segment;
2081{
606ab118 2082 if (fragP->fr_subtype == IND (BRANCH, UNDEF))
252b5132 2083 {
606ab118 2084 if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
252b5132 2085 {
606ab118 2086 /* We don't relax symbols defined in another segment. The
c6a7ab1f 2087 thing to do is to assume the object will occupy 4 bytes. */
252b5132
RH
2088 fix_new_ns32k (fragP,
2089 (int) (fragP->fr_fix),
2090 4,
2091 fragP->fr_symbol,
2092 fragP->fr_offset,
2093 1,
2094 1,
2095 0,
4eb6b71c 2096 frag_bsr(fragP), /* Sequent hack. */
c6a7ab1f
NC
2097 frag_opcode_frag (fragP),
2098 frag_opcode_offset (fragP));
252b5132 2099 fragP->fr_fix += 4;
c6a7ab1f
NC
2100#if 0
2101 fragP->fr_opcode[1] = 0xff;
2102#endif
252b5132 2103 frag_wane (fragP);
606ab118 2104 return 4;
252b5132 2105 }
93c2a809 2106
606ab118
AM
2107 /* Relaxable case. Set up the initial guess for the variable
2108 part of the frag. */
2109 fragP->fr_subtype = IND (BRANCH, BYTE);
252b5132 2110 }
0b7410c4 2111
606ab118
AM
2112 if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
2113 abort ();
2114
2115 /* Return the size of the variable part of the frag. */
2116 return md_relax_table[fragP->fr_subtype].rlx_length;
252b5132
RH
2117}
2118
2119int md_short_jump_size = 3;
2120int md_long_jump_size = 5;
c6a7ab1f 2121const int md_reloc_size = 8; /* Size of relocation record. */
252b5132
RH
2122
2123void
2124md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
2125 char *ptr;
2126 addressT from_addr, to_addr;
4eb6b71c
NC
2127 fragS *frag ATTRIBUTE_UNUSED;
2128 symbolS *to_symbol ATTRIBUTE_UNUSED;
252b5132
RH
2129{
2130 valueT offset;
2131
2132 offset = to_addr - from_addr;
2133 md_number_to_chars (ptr, (valueT) 0xEA, 1);
2134 md_number_to_disp (ptr + 1, (valueT) offset, 2);
2135}
2136
2137void
2138md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
2139 char *ptr;
2140 addressT from_addr, to_addr;
4eb6b71c
NC
2141 fragS *frag ATTRIBUTE_UNUSED;
2142 symbolS *to_symbol ATTRIBUTE_UNUSED;
252b5132
RH
2143{
2144 valueT offset;
2145
2146 offset = to_addr - from_addr;
2147 md_number_to_chars (ptr, (valueT) 0xEA, 1);
2148 md_number_to_disp (ptr + 1, (valueT) offset, 4);
2149}
2150\f
5a38dc70 2151const char *md_shortopts = "m:";
c6a7ab1f
NC
2152
2153struct option md_longopts[] =
2154{
4eb6b71c
NC
2155#define OPTION_DISP_SIZE (OPTION_MD_BASE)
2156 {"disp-size-default", required_argument , NULL, OPTION_DISP_SIZE},
252b5132
RH
2157 {NULL, no_argument, NULL, 0}
2158};
c6a7ab1f
NC
2159
2160size_t md_longopts_size = sizeof (md_longopts);
252b5132
RH
2161
2162int
2163md_parse_option (c, arg)
2164 int c;
2165 char *arg;
2166{
2167 switch (c)
2168 {
2169 case 'm':
2170 if (!strcmp (arg, "32032"))
2171 {
2172 cpureg = cpureg_032;
2173 mmureg = mmureg_032;
2174 }
2175 else if (!strcmp (arg, "32532"))
2176 {
2177 cpureg = cpureg_532;
2178 mmureg = mmureg_532;
2179 }
2180 else
2181 {
4eb6b71c 2182 as_warn (_("invalid architecture option -m%s, ignored"), arg);
252b5132
RH
2183 return 0;
2184 }
2185 break;
4eb6b71c
NC
2186 case OPTION_DISP_SIZE:
2187 {
2188 int size = atoi(arg);
2189 switch (size)
2190 {
2191 case 1: case 2: case 4:
2192 default_disp_size = size;
2193 break;
2194 default:
2195 as_warn (_("invalid default displacement size \"%s\". Defaulting to %d."),
2196 arg, default_disp_size);
2197 }
2198 break;
2199 }
252b5132
RH
2200
2201 default:
2202 return 0;
2203 }
2204
2205 return 1;
2206}
2207
2208void
2209md_show_usage (stream)
2210 FILE *stream;
2211{
c6a7ab1f 2212 fprintf (stream, _("\
252b5132 2213NS32K options:\n\
4eb6b71c
NC
2214-m32032 | -m32532 select variant of NS32K architecture\n\
2215--disp-size-default=<1|2|4>\n"));
252b5132 2216}
252b5132 2217\f
c6a7ab1f
NC
2218/* Create a bit_fixS in obstack 'notes'.
2219 This struct is used to profile the normal fix. If the bit_fixP is a
2220 valid pointer (not NULL) the bit_fix data will be used to format
2221 the fix. */
2222
252b5132
RH
2223bit_fixS *
2224bit_fix_new (size, offset, min, max, add, base_type, base_adj)
4eb6b71c
NC
2225 char size; /* Length of bitfield. */
2226 char offset; /* Bit offset to bitfield. */
2227 long min; /* Signextended min for bitfield. */
2228 long max; /* Signextended max for bitfield. */
2229 long add; /* Add mask, used for huffman prefix. */
2230 long base_type; /* 0 or 1, if 1 it's exploded to opcode ptr. */
252b5132
RH
2231 long base_adj;
2232{
4eb6b71c 2233 bit_fixS *bit_fixP;
252b5132
RH
2234
2235 bit_fixP = (bit_fixS *) obstack_alloc (&notes, sizeof (bit_fixS));
2236
2237 bit_fixP->fx_bit_size = size;
2238 bit_fixP->fx_bit_offset = offset;
2239 bit_fixP->fx_bit_base = base_type;
2240 bit_fixP->fx_bit_base_adj = base_adj;
2241 bit_fixP->fx_bit_max = max;
2242 bit_fixP->fx_bit_min = min;
2243 bit_fixP->fx_bit_add = add;
2244
4eb6b71c 2245 return bit_fixP;
252b5132
RH
2246}
2247
2248void
2249fix_new_ns32k (frag, where, size, add_symbol, offset, pcrel,
2250 im_disp, bit_fixP, bsr, opcode_frag, opcode_offset)
2251 fragS *frag; /* Which frag? */
2252 int where; /* Where in that frag? */
0b7410c4
KH
2253 int size; /* 1, 2 or 4 usually. */
2254 symbolS *add_symbol; /* X_add_symbol. */
2255 long offset; /* X_add_number. */
4eb6b71c
NC
2256 int pcrel; /* True if PC-relative relocation. */
2257 char im_disp; /* True if the value to write is a
2258 displacement. */
2259 bit_fixS *bit_fixP; /* Pointer at struct of bit_fix's, ignored if
2260 NULL. */
2261 char bsr; /* Sequent-linker-hack: 1 when relocobject is
2262 a bsr. */
252b5132
RH
2263 fragS *opcode_frag;
2264 unsigned int opcode_offset;
252b5132
RH
2265{
2266 fixS *fixP = fix_new (frag, where, size, add_symbol,
2267 offset, pcrel,
2268#ifdef BFD_ASSEMBLER
c6a7ab1f 2269 bit_fixP ? NO_RELOC : reloc (size, pcrel, im_disp)
252b5132
RH
2270#else
2271 NO_RELOC
2272#endif
2273 );
2274
c6a7ab1f
NC
2275 fix_opcode_frag (fixP) = opcode_frag;
2276 fix_opcode_offset (fixP) = opcode_offset;
2277 fix_im_disp (fixP) = im_disp;
2278 fix_bsr (fixP) = bsr;
2279 fix_bit_fixP (fixP) = bit_fixP;
4eb6b71c
NC
2280 /* We have a MD overflow check for displacements. */
2281 fixP->fx_no_overflow = (im_disp != 0);
c6a7ab1f 2282}
252b5132
RH
2283
2284void
2285fix_new_ns32k_exp (frag, where, size, exp, pcrel,
2286 im_disp, bit_fixP, bsr, opcode_frag, opcode_offset)
2287 fragS *frag; /* Which frag? */
2288 int where; /* Where in that frag? */
0b7410c4
KH
2289 int size; /* 1, 2 or 4 usually. */
2290 expressionS *exp; /* Expression. */
4eb6b71c
NC
2291 int pcrel; /* True if PC-relative relocation. */
2292 char im_disp; /* True if the value to write is a
2293 displacement. */
2294 bit_fixS *bit_fixP; /* Pointer at struct of bit_fix's, ignored if
2295 NULL. */
2296 char bsr; /* Sequent-linker-hack: 1 when relocobject is
2297 a bsr. */
252b5132
RH
2298 fragS *opcode_frag;
2299 unsigned int opcode_offset;
2300{
2301 fixS *fixP = fix_new_exp (frag, where, size, exp, pcrel,
2302#ifdef BFD_ASSEMBLER
c6a7ab1f 2303 bit_fixP ? NO_RELOC : reloc (size, pcrel, im_disp)
252b5132
RH
2304#else
2305 NO_RELOC
2306#endif
2307 );
2308
c6a7ab1f
NC
2309 fix_opcode_frag (fixP) = opcode_frag;
2310 fix_opcode_offset (fixP) = opcode_offset;
2311 fix_im_disp (fixP) = im_disp;
2312 fix_bsr (fixP) = bsr;
2313 fix_bit_fixP (fixP) = bit_fixP;
4eb6b71c
NC
2314 /* We have a MD overflow check for displacements. */
2315 fixP->fx_no_overflow = (im_disp != 0);
c6a7ab1f 2316}
252b5132
RH
2317
2318/* This is TC_CONS_FIX_NEW, called by emit_expr in read.c. */
2319
2320void
2321cons_fix_new_ns32k (frag, where, size, exp)
2322 fragS *frag; /* Which frag? */
2323 int where; /* Where in that frag? */
0b7410c4
KH
2324 int size; /* 1, 2 or 4 usually. */
2325 expressionS *exp; /* Expression. */
252b5132
RH
2326{
2327 fix_new_ns32k_exp (frag, where, size, exp,
2328 0, 2, 0, 0, 0, 0);
2329}
2330
2331/* We have no need to default values of symbols. */
2332
2333symbolS *
2334md_undefined_symbol (name)
4eb6b71c 2335 char *name ATTRIBUTE_UNUSED;
252b5132
RH
2336{
2337 return 0;
2338}
2339
2340/* Round up a section size to the appropriate boundary. */
c6a7ab1f 2341
252b5132
RH
2342valueT
2343md_section_align (segment, size)
4eb6b71c 2344 segT segment ATTRIBUTE_UNUSED;
252b5132
RH
2345 valueT size;
2346{
c6a7ab1f 2347 return size; /* Byte alignment is fine. */
252b5132
RH
2348}
2349
2350/* Exactly what point is a PC-relative offset relative TO? On the
c6a7ab1f
NC
2351 ns32k, they're relative to the start of the instruction. */
2352
252b5132
RH
2353long
2354md_pcrel_from (fixP)
2355 fixS *fixP;
2356{
2357 long res;
4eb6b71c 2358
252b5132
RH
2359 res = fixP->fx_where + fixP->fx_frag->fr_address;
2360#ifdef SEQUENT_COMPATABILITY
c6a7ab1f
NC
2361 if (frag_bsr (fixP->fx_frag))
2362 res += 0x12 /* FOO Kludge alert! */
252b5132
RH
2363#endif
2364 return res;
2365}
2366
2367#ifdef BFD_ASSEMBLER
2368
2369arelent *
2370tc_gen_reloc (section, fixp)
4eb6b71c 2371 asection *section ATTRIBUTE_UNUSED;
252b5132
RH
2372 fixS *fixp;
2373{
2374 arelent *rel;
2375 bfd_reloc_code_real_type code;
2376
c6a7ab1f 2377 code = reloc (fixp->fx_size, fixp->fx_pcrel, fix_im_disp (fixp));
252b5132
RH
2378
2379 rel = (arelent *) xmalloc (sizeof (arelent));
310b5aa2
ILT
2380 rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2381 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
252b5132
RH
2382 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
2383 if (fixp->fx_pcrel)
2384 rel->addend = fixp->fx_addnumber;
2385 else
2386 rel->addend = 0;
2387
2388 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
2389 if (!rel->howto)
2390 {
2391 const char *name;
2392
2393 name = S_GET_NAME (fixp->fx_addsy);
2394 if (name == NULL)
2395 name = _("<unknown>");
2396 as_fatal (_("Cannot find relocation type for symbol %s, code %d"),
2397 name, (int) code);
2398 }
2399
2400 return rel;
2401}
2402#else /* BFD_ASSEMBLER */
2403
2404#ifdef OBJ_AOUT
2405void
2406cons_fix_new_ns32k (where, fixP, segment_address_in_file)
2407 char *where;
2408 struct fix *fixP;
2409 relax_addressT segment_address_in_file;
2410{
c6a7ab1f
NC
2411 /* In: Length of relocation (or of address) in chars: 1, 2 or 4.
2412 Out: GNU LD relocation length code: 0, 1, or 2. */
252b5132 2413
c6a7ab1f 2414 static unsigned char nbytes_r_length[] = { 42, 0, 1, 42, 2 };
252b5132
RH
2415 long r_symbolnum;
2416
2417 know (fixP->fx_addsy != NULL);
2418
2419 md_number_to_chars (where,
2420 fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
2421 4);
2422
2423 r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
2424 ? S_GET_TYPE (fixP->fx_addsy)
2425 : fixP->fx_addsy->sy_number);
2426
2427 md_number_to_chars (where + 4,
2428 ((long) (r_symbolnum)
2429 | (long) (fixP->fx_pcrel << 24)
2430 | (long) (nbytes_r_length[fixP->fx_size] << 25)
2431 | (long) ((!S_IS_DEFINED (fixP->fx_addsy)) << 27)
c6a7ab1f
NC
2432 | (long) (fix_bsr (fixP) << 28)
2433 | (long) (fix_im_disp (fixP) << 29)),
252b5132
RH
2434 4);
2435}
2436
2437#endif /* OBJ_AOUT */
2438#endif /* BFD_ASSMEBLER */
This page took 0.28076 seconds and 4 git commands to generate.