1 /* ns32k.c -- Assemble on the National Semiconductor 32k series
2 Copyright (C) 1987, 1992 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
20 /*#define SHOW_NUM 1*//* uncomment for debugging */
24 #include "opcode/ns32k.h"
31 #define IIF_ENTRIES 13 /* number of entries in iif */
32 #define PRIVATE_SIZE 256 /* size of my garbage memory */
34 #define DEFAULT -1 /* addr_mode returns this value when plain constant or label is encountered */
36 #define IIF(ptr,a1,c1,e1,g1,i1,k1,m1,o1,q1,s1,u1) \
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;
49 #ifdef SEQUENT_COMPATABILITY
50 #define LINE_COMMENT_CHARS "|"
51 #define ABSOLUTE_PREFIX '@'
52 #define IMMEDIATE_PREFIX '#'
55 #ifndef LINE_COMMENT_CHARS
56 #define LINE_COMMENT_CHARS "#"
59 const char comment_chars
[] = "#";
60 const char line_comment_chars
[] = LINE_COMMENT_CHARS
;
61 const char line_separator_chars
[] = "";
62 #if !defined(ABSOLUTE_PREFIX) && !defined(IMMEDIATE_PREFIX)
63 #define ABSOLUTE_PREFIX '@' /* One or the other MUST be defined */
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)
77 or immediates(s) (ascii) */
78 char index_byte
; /* index byte */
80 typedef struct addr_mode addr_modeS
;
83 char *freeptr
, *freeptr_static
; /* points at some number of free bytes */
84 struct hash_control
*inst_hash_handle
;
86 struct ns32k_opcode
*desc
; /* pointer at description of instruction */
87 addr_modeS addr_modeP
;
88 const char EXP_CHARS
[] = "eE";
89 const char FLT_CHARS
[] = "fd"; /* we don't want to support lowercase, do we */
91 /* UPPERCASE denotes live names
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 */
98 /* internal structs */
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
114 instruction start to the
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 */
123 iif_entryT
; /* Internal Instruction Format */
127 int instr_size
; /* Max size of instruction in bytes. */
128 iif_entryT iifP
[IIF_ENTRIES
+ 1];
130 struct int_ins_form iif
;
132 char *input_line_pointer
;
133 /* description of the PARTs in IIF
135 * 0 total length in bytes of entries in iif
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.
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
159 * Furthermore, every entry has a data type identifier in type[n].
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.
169 * 3, the entry is a pointer at a bignum struct
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)
181 struct option opt1
[] = /* restore, exit */
193 struct option opt2
[] = /* save, enter */
205 struct option opt3
[] = /* setcfg */
213 struct option opt4
[] = /* cinv */
220 struct option opt5
[] = /* string inst */
227 struct option opt6
[] = /* plain reg ext,cvtp etc */
240 #if !defined(NS32032) && !defined(NS32532)
244 struct option cpureg_532
[] = /* lpr spr */
257 {"intbase", 0xe, 0xff},
261 struct option mmureg_532
[] = /* lmr smr */
268 {"ivar0", 0xe, 0xff},
269 {"ivar1", 0xf, 0xff},
273 struct option cpureg_032
[] = /* lpr spr */
280 {"intbase", 0xe, 0xff},
284 struct option mmureg_032
[] = /* lmr smr */
300 struct option
*cpureg
= cpureg_532
;
301 struct option
*mmureg
= mmureg_532
;
303 struct option
*cpureg
= cpureg_032
;
304 struct option
*mmureg
= mmureg_032
;
308 const pseudo_typeS md_pseudo_table
[] =
313 #define IND(x,y) (((x)<<2)+(y))
315 /* those are index's to relax groups in md_relax_table
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 */
322 /* those are index's to entries in a relax group */
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. */
338 const relax_typeS md_relax_table
[] =
345 {(63), (-64), 1, IND (BRANCH
, WORD
)},
346 {(8192), (-8192), 2, IND (BRANCH
, DOUBLE
)},
351 /* Array used to test if mode contains displacements.
352 Value is true if mode contains displacement. */
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};
360 /* Array used to calculate max size of displacements */
368 static segT
evaluate_expr (expressionS
* resultP
, char *ptr
);
369 static void md_number_to_disp (char *buf
, long val
, int n
);
370 static void md_number_to_imm (char *buf
, long val
, int n
);
372 #else /* not __STDC__ */
374 static segT
evaluate_expr ();
375 static void md_number_to_disp ();
376 static void md_number_to_imm ();
378 #endif /* not __STDC__ */
380 /* Parses a general operand into an addressingmode struct
382 in: pointer at operand in ascii form
383 pointer at addr_mode struct for result
384 the level of recursion. (always 0 or 1)
386 out: data in addr_mode struct
389 addr_mode (operand
, addr_modeP
, recursive_level
)
391 register addr_modeS
*addr_modeP
;
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
;
414 } /* we don't want this */
418 /* the following three case statements controls the mode-chars
419 this is the place to ed if you want to change them */
420 #ifdef ABSOLUTE_PREFIX
421 case ABSOLUTE_PREFIX
:
422 if (str
[strl
- 1] == ']')
424 addr_modeP
->mode
= 21; /* absolute */
425 addr_modeP
->disp
[0] = str
+ 1;
428 #ifdef IMMEDIATE_PREFIX
429 case IMMEDIATE_PREFIX
:
430 if (str
[strl
- 1] == ']')
432 addr_modeP
->mode
= 20; /* immediate */
433 addr_modeP
->disp
[0] = str
+ 1;
437 if (str
[strl
- 1] != ']')
443 if (str
[2] != '\000')
445 addr_modeP
->mode
= 27; /* pc-relativ */
446 addr_modeP
->disp
[0] = str
+ 2;
450 as_warn ("Invalid syntax in PC-relative addressing mode");
456 if (str
[strl
- 1] != ']')
458 if ((!strncmp (str
, "ext(", 4)) && strl
> 7)
460 addr_modeP
->disp
[0] = str
+ 4;
464 { /* disp[0]'s termination point */
471 while (j
< strl
&& i
!= 0);
472 if (i
!= 0 || !(str
[j
+ 1] == '-' || str
[j
+ 1] == '+'))
474 as_warn ("Invalid syntax in External addressing mode");
477 str
[j
] = '\000'; /* null terminate disp[0] */
478 addr_modeP
->disp
[1] = str
+ j
+ 2;
479 addr_modeP
->mode
= 22;
493 addr_modeP
->float_flag
= 1;
495 if (str
[1] >= '0' && str
[1] < '8')
497 addr_modeP
->mode
= str
[1] - '0';
502 if (!strncmp (str
, "tos", 3))
504 addr_modeP
->mode
= 23;/* TopOfStack */
511 if (str
[strl
- 1] == ')')
513 if (str
[strl
- 2] == ')')
515 if (!strncmp (&str
[strl
- 5], "(fp", 3))
517 mode
= 16; /* Memory Relative */
519 if (!strncmp (&str
[strl
- 5], "(sp", 3))
523 if (!strncmp (&str
[strl
- 5], "(sb", 3))
528 { /* memory relative */
529 addr_modeP
->mode
= mode
;
530 j
= strl
- 5; /* temp for end of disp[0] */
535 if (str
[strl
] == ')')
537 if (str
[strl
] == '(')
540 while (strl
> -1 && i
!= 0);
543 as_warn ("Invalid syntax in Memory Relative addressing mode");
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] */
553 switch (str
[strl
- 3])
557 if (str
[strl
- 2] >= '0' && str
[strl
- 2] < '8' && str
[strl
- 4] == '(')
559 addr_modeP
->mode
= str
[strl
- 2] - '0' + 8;
560 addr_modeP
->disp
[0] = str
;
562 return (-1); /* reg rel */
565 if (!strncmp (&str
[strl
- 4], "(fp", 3))
569 if (!strncmp (&str
[strl
- 4], "(sp", 3))
573 if (!strncmp (&str
[strl
- 4], "(sb", 3))
577 if (!strncmp (&str
[strl
- 4], "(pc", 3))
583 addr_modeP
->mode
= mode
;
584 addr_modeP
->disp
[0] = str
;
585 str
[strl
- 4] = '\0';
586 return (-1); /* memory space */
590 /* no trailing ')' do we have a ']' ? */
591 if (str
[strl
- 1] == ']')
593 switch (str
[strl
- 2])
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')
612 as_warn ("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}");
616 if (recursive_level
> 0)
618 as_warn ("Scaled-indexed addressing mode combined with scaled-index");
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)
627 as_warn ("Invalid or illegal addressing mode combined with scaled-index");
630 addr_modeP
->scaled_mode
= addr_modeP
->mode
; /* store the inferior mode */
631 addr_modeP
->mode
= mode
;
632 addr_modeP
->scaled_reg
= j
+ 1;
637 addr_modeP
->mode
= DEFAULT
; /* default to whatever */
638 addr_modeP
->disp
[0] = str
;
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.
650 get_addr_mode (ptr
, addr_modeP
)
652 addr_modeS
*addr_modeP
;
655 addr_mode (ptr
, addr_modeP
, 0);
656 if (addr_modeP
->mode
== DEFAULT
|| addr_modeP
->scaled_mode
== -1)
658 /* resolve ambigious operands, this shouldn't
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 */
663 (void) evaluate_expr (&exprP
, ptr
); /* this call takes time Sigh! */
664 if (addr_modeP
->mode
== DEFAULT
)
666 if (exprP
.X_add_symbol
|| exprP
.X_subtract_symbol
)
668 addr_modeP
->mode
= desc
->default_model
; /* we have a label */
672 addr_modeP
->mode
= desc
->default_modec
; /* we have a constant */
677 if (exprP
.X_add_symbol
|| exprP
.X_subtract_symbol
)
679 addr_modeP
->scaled_mode
= desc
->default_model
;
683 addr_modeP
->scaled_mode
= desc
->default_modec
;
686 /* must put this mess down in addr_mode to handle the scaled case better */
688 /* It appears as the sequent compiler wants an absolute when we have a
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.
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;
701 if (disp_test
[addr_modeP
->mode
])
702 { /* there was a displacement, probe for length specifying suffix*/
705 register char suffix
;
706 register char suffix_sub
;
709 register char *fromP
;
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;
718 addr_modeP
->im_disp
= 1;
719 for (i
= 0; i
< 2; i
++)
721 suffix_sub
= suffix
= 0;
722 if (toP
= addr_modeP
->disp
[i
])
723 { /* suffix of expression, the largest size rules */
733 as_warn ("Premature end of suffix--Defaulting to d");
746 as_warn ("Bad suffix after ':' use {b|w|d} Defaulting to d");
750 toP
--; /* So we write over the ':' */
751 if (suffix
< suffix_sub
)
755 *toP
= '\0';/* terminate properly */
756 addr_modeP
->disp_suffix
[i
] = suffix
;
757 addr_modeP
->am_size
+= suffix
? suffix
: 4;
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;
771 return addr_modeP
->mode
;
775 /* read an optionlist */
777 optlist (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 */
782 register int i
, j
, k
, strlen1
, strlen2
;
783 register char *patternP
, *strP
;
784 strlen1
= strlen (str
);
787 as_fatal ("Very short instr to option, ie you can't do it on a NULLstr");
789 for (i
= 0; optionP
[i
].pattern
!= 0; i
++)
791 strlen2
= strlen (optionP
[i
].pattern
);
792 for (j
= 0; j
< strlen1
; j
++)
794 patternP
= optionP
[i
].pattern
;
796 for (k
= 0; k
< strlen2
; k
++)
798 if (*(strP
++) != *(patternP
++))
803 *default_map
|= optionP
[i
].or;
804 *default_map
&= optionP
[i
].and;
810 /* search struct for symbols
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 */
816 list_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 */
822 for (i
= 0; optionP
[i
].pattern
!= 0; i
++)
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;
831 as_warn ("No such entry in list. (cpu/mmu register)");
836 evaluate_expr (resultP
, ptr
)
837 expressionS
*resultP
;
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
;
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
853 Be carefull not to put to objects in the same iif-slot.
857 encode_operand (argc
, argv
, operandsP
, suffixP
, im_size
, opcode_bit_ptr
)
866 int pcrel
, tmp
, b
, loop
, pcrel_adjust
;
867 for (loop
= 0; loop
< argc
; loop
++)
869 i
= operandsP
[loop
<< 1] - '1'; /* what operand are we supposed to work on */
871 as_fatal ("Internal consistency error. check ns32k-opcode.h");
875 switch (operandsP
[(loop
<< 1) + 1])
877 case 'f': /* operand of sfsr turns out to be a nasty specialcase */
879 case 'F': /* 32 bit float general form */
880 case 'L': /* 64 bit float */
881 case 'Q': /* quad-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
)
892 for (j
= b
; j
< (b
+ 2); j
++)
894 if (addr_modeP
.disp
[j
- b
])
898 addr_modeP
.disp_suffix
[j
- b
],
899 (unsigned long) addr_modeP
.disp
[j
- b
],
902 iif
.instr_size
- addr_modeP
.am_size
, /* this aint used (now) */
906 addr_modeP
.scaled_reg
? addr_modeP
.scaled_mode
: addr_modeP
.mode
,
911 iif
.iifP
[1].object
|= ((long) addr_modeP
.mode
) << opcode_bit_ptr
;
912 if (addr_modeP
.scaled_reg
)
915 IIF (j
, 1, 1, (unsigned long) addr_modeP
.index_byte
, 0, 0, 0, 0, 0, NULL
, -1, 0);
918 case 'b': /* multiple instruction disp */
919 freeptr
++; /* OVE:this is an useful hack */
920 tmp
= (int) sprintf (freeptr
,
922 argv
[i
], desc
->im_size
);
924 freeptr
= (char *) tmp
;
925 pcrel
-= 1; /* make pcrel 0 inspite of what case 'p': wants */
927 case 'p': /* displacement - pc relative addressing */
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);
935 case 'H': /* sequent-hack: the linker wants a bit set when bsr */
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);
941 case 'q': /* quick */
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);
946 case 'r': /* register number (3 bits) */
947 list_search (argv
[i
], opt6
, &tmp
);
949 iif
.iifP
[1].object
|= tmp
<< opcode_bit_ptr
;
951 case 'O': /* setcfg instruction optionslist */
952 optlist (argv
[i
], opt3
, &tmp
);
954 iif
.iifP
[1].object
|= tmp
<< 15;
956 case 'C': /* cinv instruction optionslist */
957 optlist (argv
[i
], opt4
, &tmp
);
959 iif
.iifP
[1].object
|= tmp
<< 15; /*insert the regtype in opcode */
961 case 'S': /* stringinstruction optionslist */
962 optlist (argv
[i
], opt5
, &tmp
);
964 iif
.iifP
[1].object
|= tmp
<< 15;
967 case 'U': /* registerlist */
968 IIF (10, 1, 1, 0, 0, 0, 0, 0, 0, NULL
, -1, 0);
969 switch (operandsP
[(i
<< 1) + 1])
971 case 'u': /* restore, exit */
972 optlist (argv
[i
], opt1
, &iif
.iifP
[10].object
);
974 case 'U': /* save,enter */
975 optlist (argv
[i
], opt2
, &iif
.iifP
[10].object
);
980 case 'M': /* mmu register */
981 list_search (argv
[i
], mmureg
, &tmp
);
983 iif
.iifP
[1].object
|= tmp
<< opcode_bit_ptr
;
985 case 'P': /* cpu register */
986 list_search (argv
[i
], cpureg
, &tmp
);
988 iif
.iifP
[1].object
|= tmp
<< opcode_bit_ptr
;
990 case 'g': /* inss exts */
991 iif
.instr_size
+= 1; /* 1 byte is allocated after the opcode */
993 (unsigned long) argv
[i
], /* i always 2 here */
995 bit_fix_new (3, 5, 0, 7, 0, 0, 0), /* a bit_fix is targeted to the byte */
999 (unsigned long) argv
[i
], /* i always 3 here */
1001 bit_fix_new (5, 0, 1, 32, -1, 0, -1), -1, 0);
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);
1008 as_fatal ("Bad opcode-table-option, check in file ns32k-opcode.h");
1013 /* in: instruction line
1014 out: internal structure of instruction
1015 that has been prepared for direct conversion to fragment(s) and
1016 fixes in a systematical fashion
1017 Return-value = recursive_level
1019 /* build iif of one assembly text line */
1021 parse (line
, recursive_level
)
1023 int recursive_level
;
1025 register char *lineptr
, c
, suffix_separator
;
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
++);
1035 if (!(desc
= (struct ns32k_opcode
*) hash_find (inst_hash_handle
, line
)))
1037 as_fatal ("No such opcode");
1046 if (*desc
->operands
)
1048 if (*lineptr
++ != '\0')
1052 while (*lineptr
!= '\0')
1054 if (desc
->operands
[argc
<< 1])
1057 arg_type
= desc
->operands
[(argc
<< 1) + 1];
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
= ':';
1068 suffix_separator
= '\255'; /* if this char occurs we loose */
1070 suffix
[argc
] = 0; /* 0 when no ':' is encountered */
1071 argv
[argc
] = freeptr
;
1073 while ((c
= *lineptr
) != '\0' && c
!= sep
)
1088 if (c
== suffix_separator
)
1089 { /* ':' - label/suffix separator */
1102 as_warn ("Bad suffix, defaulting to d");
1104 if (lineptr
[1] == '\0' || lineptr
[1] == sep
)
1118 if (*lineptr
== '\0')
1124 as_fatal ("Too many operands passed to instruction");
1129 if (argc
!= strlen (desc
->operands
) / 2)
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");
1140 as_fatal ("Wrong number of operands");
1144 for (i
= 0; i
< IIF_ENTRIES
; i
++)
1146 iif
.iifP
[i
].type
= 0; /* mark all entries as void*/
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);
1153 /* this call encodes operands to iif format */
1156 encode_operand (argc
,
1163 return recursive_level
;
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.
1188 int rem_size
; /* count the remaining bytes of instruction */
1191 int size_so_far
= 0; /* used to calculate pcrel_adjust */
1193 rem_size
= iif
.instr_size
;
1194 memP
= frag_more (iif
.instr_size
); /* make sure we have enough bytes for instruction */
1196 inst_offset
= (char *) (memP
- frag_now
->fr_literal
);
1197 inst_frag
= frag_now
;
1198 for (i
= 0; i
< IIF_ENTRIES
; i
++)
1200 if (type
= iif
.iifP
[i
].type
)
1201 { /* the object exist, so handle it */
1202 switch (size
= iif
.iifP
[i
].size
)
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
;
1210 case 8: /* bignum or doublefloat */
1211 memset (memP
, '\0', 8);
1215 case 4: /* the final size in objectmemory is known */
1216 j
= (unsigned long) iif
.iifP
[i
].bit_fixP
;
1219 case 1: /* the object is pure binary */
1220 if (j
|| iif
.iifP
[i
].pcrel
)
1222 fix_new_ns32k (frag_now
,
1223 (long) (memP
- frag_now
->fr_literal
),
1229 (char) size_so_far
, /*iif.iifP[i].pcrel_adjust,*/
1230 iif
.iifP
[i
].im_disp
,
1232 iif
.iifP
[i
].bsr
); /* sequent hack */
1235 { /* good, just put them bytes out */
1236 switch (iif
.iifP
[i
].im_disp
)
1239 md_number_to_chars (memP
, iif
.iifP
[i
].object
, size
);
1242 md_number_to_disp (memP
, iif
.iifP
[i
].object
, size
);
1245 as_fatal ("iif convert internal pcrel/binary");
1251 case 2: /* the object is a pointer at an expression, so unpack
1252 it, note that bignums may result from the expression
1254 if ((segment
= evaluate_expr (&exprP
, (char *) iif
.iifP
[i
].object
)) == SEG_BIG
|| size
== 8)
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 */
1261 as_warn ("Bignum too big for long");
1264 for (l
= 0; k
> 0; k
--, l
+= 2)
1266 md_number_to_chars (memP
+ l
, generic_bignum
[l
>> 1], sizeof (LITTLENUM_TYPE
));
1271 LITTLENUM_TYPE words
[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
));
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
));
1294 exprP
.X_add_symbol
||
1295 exprP
.X_subtract_symbol
||
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
),
1305 exprP
.X_subtract_symbol
,
1308 (char) size_so_far
, /*iif.iifP[i].pcrel_adjust,*/
1309 iif
.iifP
[i
].im_disp
,
1311 iif
.iifP
[i
].bsr
); /* sequent hack */
1315 { /* good, just put them bytes out */
1316 switch (iif
.iifP
[i
].im_disp
)
1319 md_number_to_imm (memP
, exprP
.X_add_number
, size
);
1322 md_number_to_disp (memP
, exprP
.X_add_number
, size
);
1325 as_fatal ("iif convert internal pcrel/pointer");
1332 as_fatal ("Internal logic error in iif.iifP[n].type");
1335 case 0: /* To bad, the object may be undefined as far as its final
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.
1343 segment
= evaluate_expr (&exprP
, (char *) iif
.iifP
[i
].object
);
1344 if ((exprP
.X_add_symbol
|| exprP
.X_subtract_symbol
) &&
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
),
1352 exprP
.X_subtract_symbol
,
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, */
1360 break; /* exit this absolute hack */
1363 if (exprP
.X_add_symbol
|| exprP
.X_subtract_symbol
)
1365 if (exprP
.X_subtract_symbol
)
1366 { /* We cant relax this case */
1367 as_fatal ("Can't relax difference");
1371 /* at this stage we must undo some of the effect caused
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
1375 temp
= -(rem_size
- 4);
1376 obstack_blank_fast (&frags
, temp
);
1377 /* we rewind none, some or all of the requested size we
1378 requested by the first frag_more for this iif chunk.
1379 Note: that we allocate 4 bytes to an object we NOT YET
1380 know the size of, thus rem_size-4.
1382 (void) frag_variant (rs_machine_dependent
,
1385 IND (BRANCH
, UNDEF
), /* expecting the worst */
1388 (char *) inst_opcode
,
1389 (char) size_so_far
, /*iif.iifP[i].pcrel_adjust);*/
1390 iif
.iifP
[i
].bsr
); /* sequent linker hack */
1394 memP
= frag_more (rem_size
);
1399 { /* Double work, this is done in md_number_to_disp */
1400 /* exprP.X_add_number; what was this supposed to be?
1402 if (-64 <= exprP
.X_add_number
&& exprP
.X_add_number
<= 63)
1408 if (-8192 <= exprP
.X_add_number
&& exprP
.X_add_number
<= 8191)
1414 if (-0x1f000000 <= exprP
.X_add_number
&&
1415 exprP
.X_add_number
<= 0x1fffffff)
1416 /* if (-0x40000000<=exprP.X_add_number &&
1417 exprP.X_add_number<=0x3fffffff) */
1423 as_warn ("Displacement to large for :d");
1428 /* rewind the bytes not used */
1430 md_number_to_disp (memP
, exprP
.X_add_number
, size
);
1431 obstack_blank_fast (&frags
, temp
);
1433 rem_size
-= 4; /* we allocated this amount */
1438 as_fatal ("Internal logic error in iif.iifP[].type");
1440 size_so_far
+= size
;
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 */
1454 printf (" \t\t\t%s\n", line
);
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
++)
1468 if (*(stat
= hash_insert (inst_hash_handle
, ptr
->name
, (char *) ptr
)))
1470 as_fatal ("Can't hash %s: %s", ptr
->name
, stat
); /*fatal*/
1474 freeptr_static
= (char *) malloc (PRIVATE_SIZE
); /* some private space please! */
1481 free (freeptr_static
);
1484 /* Must be equal to MAX_PRECISON in atof-ieee.c */
1485 #define MAX_LITTLENUMS 6
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.
1492 md_atof (type
, litP
, sizeP
)
1498 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1499 LITTLENUM_TYPE
*wordP
;
1513 return "Bad call to MD_ATOF()";
1515 t
= atof_ns32k (input_line_pointer
, type
, words
);
1517 input_line_pointer
= t
;
1519 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1520 for (wordP
= words
+ prec
; prec
--;)
1522 md_number_to_chars (litP
, (long) (*--wordP
), sizeof (LITTLENUM_TYPE
));
1523 litP
+= sizeof (LITTLENUM_TYPE
);
1525 return ""; /* Someone should teach Dean about null pointers */
1528 /* Convert number to chars in correct order */
1531 md_number_to_chars (buf
, value
, nbytes
)
1539 printf ("%x ", value
& 0xff);
1541 *buf
++ = value
; /* Lint wants & MASK_CHAR. */
1542 value
>>= BITS_PER_CHAR
;
1544 } /* md_number_to_chars() */
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
1554 10xxxxxx xxxxxxxx word
1555 11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx double word
1557 This must be taken care of and we do it here!
1560 md_number_to_disp (buf
, val
, n
)
1568 if (val
< -64 || val
> 63)
1569 as_warn ("Byte displacement out of range. line number not valid");
1572 printf ("%x ", val
& 0xff);
1577 if (val
< -8192 || val
> 8191)
1578 as_warn ("Word displacement out of range. line number not valid");
1582 printf ("%x ", val
>> 8 & 0xff);
1584 *buf
++ = (val
>> 8);
1586 printf ("%x ", val
& 0xff);
1591 if (val
< -0x1f000000 || val
>= 0x20000000)
1592 /* if (val < -0x20000000 || val >= 0x20000000) */
1593 as_warn ("Double word displacement out of range");
1596 printf ("%x ", val
>> 24 & 0xff);
1598 *buf
++ = (val
>> 24);
1600 printf ("%x ", val
>> 16 & 0xff);
1602 *buf
++ = (val
>> 16);
1604 printf ("%x ", val
>> 8 & 0xff);
1606 *buf
++ = (val
>> 8);
1608 printf ("%x ", val
& 0xff);
1613 as_fatal ("Internal logic error. line %s, file \"%s\"", __LINE__
, __FILE__
);
1618 md_number_to_imm (buf
, val
, n
)
1627 printf ("%x ", val
& 0xff);
1633 printf ("%x ", val
>> 8 & 0xff);
1635 *buf
++ = (val
>> 8);
1637 printf ("%x ", val
& 0xff);
1643 printf ("%x ", val
>> 24 & 0xff);
1645 *buf
++ = (val
>> 24);
1647 printf ("%x ", val
>> 16 & 0xff);
1649 *buf
++ = (val
>> 16);
1651 printf ("%x ", val
>> 8 & 0xff);
1653 *buf
++ = (val
>> 8);
1655 printf ("%x ", val
& 0xff);
1660 as_fatal ("Internal logic error. line %s, file \"%s\"", __LINE__
, __FILE__
);
1664 /* Translate internal representation of relocation info into target format.
1666 OVE: on a ns32k the twiddling continues at an even deeper level
1667 here we have to distinguish between displacements and immediates.
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) !?!?!?!
1672 This md_ri.... is tailored for sequent.
1677 md_ri_to_chars (the_bytes
, ri
)
1679 struct reloc_info_generic
*ri
;
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)),
1693 /* the first and second md_number_to_chars never overlaps (32bit cpu case) */
1696 #endif /* comment */
1700 tc_aout_fix_to_chars (where
, fixP
, segment_address_in_file
)
1703 relax_addressT segment_address_in_file
;
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.
1710 static unsigned char nbytes_r_length
[] = {42, 0, 1, 42, 2};
1713 know (fixP
->fx_addsy
!= NULL
);
1715 md_number_to_chars (where
,
1716 fixP
->fx_frag
->fr_address
+ fixP
->fx_where
- segment_address_in_file
,
1719 r_symbolnum
= (S_IS_DEFINED (fixP
->fx_addsy
)
1720 ? S_GET_TYPE (fixP
->fx_addsy
)
1721 : fixP
->fx_addsy
->sy_number
);
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)),
1733 #endif /* OBJ_AOUT */
1735 /* fast bitfiddling support */
1736 /* mask used to zero bitfield before oring in the true field */
1738 static unsigned long l_mask
[] =
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,
1749 static unsigned long r_mask
[] =
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,
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!)
1769 md_number_to_field (buf
, val
, field_ptr
)
1772 register bit_fixS
*field_ptr
;
1774 register unsigned long object
;
1775 register unsigned long mask
;
1776 /* define ENDIAN on a ns32k machine */
1778 register unsigned long *mem_ptr
;
1780 register char *mem_ptr
;
1782 if (field_ptr
->fx_bit_min
<= val
&& val
<= field_ptr
->fx_bit_max
)
1785 if (field_ptr
->fx_bit_base
)
1786 { /* override buf */
1787 mem_ptr
= (unsigned long *) field_ptr
->fx_bit_base
;
1791 mem_ptr
= (unsigned long *) buf
;
1794 if (field_ptr
->fx_bit_base
)
1795 { /* override buf */
1796 mem_ptr
= (char *) field_ptr
->fx_bit_base
;
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 */
1806 #else /* OVE Goof! the machine is a m68k or dito */
1807 /* That takes more byte fiddling */
1809 object
|= mem_ptr
[3] & 0xff;
1811 object
|= mem_ptr
[2] & 0xff;
1813 object
|= mem_ptr
[1] & 0xff;
1815 object
|= mem_ptr
[0] & 0xff;
1818 mask
|= (r_mask
[field_ptr
->fx_bit_offset
]);
1819 mask
|= (l_mask
[field_ptr
->fx_bit_offset
+ field_ptr
->fx_bit_size
]);
1821 val
+= field_ptr
->fx_bit_add
;
1822 object
|= ((val
<< field_ptr
->fx_bit_offset
) & (mask
^ 0xffffffff));
1826 mem_ptr
[0] = (char) object
;
1828 mem_ptr
[1] = (char) object
;
1830 mem_ptr
[2] = (char) object
;
1832 mem_ptr
[3] = (char) object
;
1837 as_warn ("Bit field out of range");
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.
1844 On the ns32k, everything is in a different format, so we have broken
1845 out separate functions for each kind of thing we could be fixing.
1846 They all get called from here. */
1849 md_apply_fix (fixP
, val
)
1853 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
1855 if (fixP
->fx_bit_fixP
)
1856 { /* Bitfields to fix, sigh */
1857 md_number_to_field (buf
, val
, fixP
->fx_bit_fixP
);
1860 switch (fixP
->fx_im_disp
)
1863 case 0: /* Immediate field */
1864 md_number_to_imm (buf
, val
, fixP
->fx_size
);
1867 case 1: /* Displacement field */
1868 md_number_to_disp (buf
,
1869 fixP
->fx_pcrel
? val
+ fixP
->fx_pcrel_adjust
: val
,
1873 case 2: /* Pointer in a data object */
1874 md_number_to_chars (buf
, val
, fixP
->fx_size
);
1879 /* Convert a relaxed displacement to ditto in final output */
1882 md_convert_frag (headers
, fragP
)
1883 object_headers
*headers
;
1884 register fragS
*fragP
;
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
;
1894 know (fragP
->fr_symbol
);
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
;
1900 switch (fragP
->fr_subtype
)
1902 case IND (BRANCH
, BYTE
):
1905 case IND (BRANCH
, WORD
):
1908 case IND (BRANCH
, DOUBLE
):
1914 md_number_to_disp (buffer_address
, (long) disp
, (int) ext
);
1915 fragP
->fr_fix
+= ext
;
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
1926 md_estimate_size_before_relax (fragP
, segment
)
1927 register fragS
*fragP
;
1931 old_fix
= fragP
->fr_fix
;
1932 switch (fragP
->fr_subtype
)
1934 case IND (BRANCH
, UNDEF
):
1935 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
)
1937 /* the symbol has been assigned a value */
1938 fragP
->fr_subtype
= IND (BRANCH
, BYTE
);
1942 /* we don't relax symbols defined in an other segment
1943 the thing to do is to assume the object will occupy 4 bytes */
1944 fix_new_ns32k (fragP
,
1945 (int) (fragP
->fr_fix
),
1951 fragP
->fr_pcrel_adjust
,
1954 fragP
->fr_bsr
); /*sequent hack */
1956 /* fragP->fr_opcode[1]=0xff; */
1960 case IND (BRANCH
, BYTE
):
1966 return fragP
->fr_var
+ fragP
->fr_fix
- old_fix
;
1969 int md_short_jump_size
= 3;
1970 int md_long_jump_size
= 5;
1971 const int md_reloc_size
= 8; /* Size of relocation record */
1974 md_create_short_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
1976 addressT from_addr
, to_addr
;
1982 offset
= to_addr
- from_addr
;
1983 md_number_to_chars (ptr
, (valueT
) 0xEA, 1);
1984 md_number_to_disp (ptr
+ 1, (valueT
) offset
, 2);
1988 md_create_long_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
1990 addressT from_addr
, to_addr
;
1996 offset
= to_addr
- from_addr
;
1997 md_number_to_chars (ptr
, (valueT
) 0xEA, 2);
1998 md_number_to_disp (ptr
+ 2, (valueT
) offset
, 4);
2001 /* JF this is a new function to parse machine-dep options */
2003 md_parse_option (argP
, cntP
, vecP
)
2013 if (!strcmp (*argP
, "32032"))
2015 cpureg
= cpureg_032
;
2016 mmureg
= mmureg_032
;
2018 else if (!strcmp (*argP
, "32532"))
2020 cpureg
= cpureg_532
;
2021 mmureg
= mmureg_532
;
2024 as_warn ("Unknown -m option ignored");
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.
2044 bit_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 */
2049 long min
; /* Signextended min for bitfield */
2050 long max
; /* Signextended max for bitfield */
2051 long add
; /* Add mask, used for huffman prefix */
2053 register bit_fixS
*bit_fixP
;
2055 bit_fixP
= (bit_fixS
*) obstack_alloc (¬es
, sizeof (bit_fixS
));
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
;
2069 fix_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 */
2084 fixS
*fixP
= fix_new (frag
, where
, size
, add_symbol
, sub_symbol
,
2085 offset
, pcrel
, NO_RELOC
);
2087 fixP
->fx_pcrel_adjust
= pcrel_adjust
;
2088 fixP
->fx_im_disp
= im_disp
;
2089 fixP
->fx_bit_fixP
= bit_fixP
;
2091 } /* fix_new_ns32k() */
2093 /* This is TC_CONS_FIX_NEW, called by emit_expr in read.c. */
2096 cons_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. */
2102 fix_new_ns32k (frag
, where
, size
, exp
->X_add_symbol
,
2103 exp
->X_subtract_symbol
, exp
->X_add_number
,
2107 /* We have no need to default values of symbols. */
2110 md_undefined_symbol (name
)
2116 /* Parse an operand that is machine-specific.
2117 We just return without modifying the expression if we have nothing
2122 md_operand (expressionP
)
2123 expressionS
*expressionP
;
2127 /* Round up a section size to the appropriate boundary. */
2129 md_section_align (segment
, size
)
2133 return size
; /* Byte alignment is fine */
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) */
2141 md_pcrel_from (fixP
)
2145 res
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2146 #ifdef SEQUENT_COMPATABILITY
2147 if (fixP
->fx_frag
->fr_bsr
)
2148 res
+= 0x12 /* FOO Kludge alert! */
2159 /* end of tc-ns32k.c */