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