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