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