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 */
29 #include "opcode/ns32k.h"
37 #define IIF_ENTRIES 13 /* number of entries in iif */
38 #define PRIVATE_SIZE 256 /* size of my garbage memory */
40 #define DEFAULT -1 /* addr_mode returns this value when plain constant or label is encountered */
42 #define IIF(ptr,a1,c1,e1,g1,i1,k1,m1,o1,q1,s1,u1) \
43 iif.iifP[ptr].type= a1; \
44 iif.iifP[ptr].size= c1; \
45 iif.iifP[ptr].object= e1; \
46 iif.iifP[ptr].object_adjust= g1; \
47 iif.iifP[ptr].pcrel= i1; \
48 iif.iifP[ptr].pcrel_adjust= k1; \
49 iif.iifP[ptr].im_disp= m1; \
50 iif.iifP[ptr].relax_substate= o1; \
51 iif.iifP[ptr].bit_fixP= q1; \
52 iif.iifP[ptr].addr_mode= s1; \
53 iif.iifP[ptr].bsr= u1;
55 #ifdef SEQUENT_COMPATABILITY
56 #define LINE_COMMENT_CHARS "|"
57 #define ABSOLUTE_PREFIX '@'
58 #define IMMEDIATE_PREFIX '#'
61 #ifndef LINE_COMMENT_CHARS
62 #define LINE_COMMENT_CHARS "#"
65 const char comment_chars
[] = "#";
66 const char line_comment_chars
[] = LINE_COMMENT_CHARS
;
67 const char line_separator_chars
[] = "";
68 #if !defined(ABSOLUTE_PREFIX) && !defined(IMMEDIATE_PREFIX)
69 #define ABSOLUTE_PREFIX '@' /* One or the other MUST be defined */
74 char mode
; /* addressing mode of operand (0-31) */
75 char scaled_mode
; /* mode combined with scaled mode */
76 char scaled_reg
; /* register used in scaled+1 (1-8) */
77 char float_flag
; /* set if R0..R7 was F0..F7 ie a floating-point-register */
78 char am_size
; /* estimated max size of general addr-mode parts*/
79 char im_disp
; /* if im_disp==1 we have a displacement */
80 char pcrel
; /* 1 if pcrel, this is really redundant info */
81 char disp_suffix
[2]; /* length of displacement(s), 0=undefined */
82 char *disp
[2]; /* pointer(s) at displacement(s)
83 or immediates(s) (ascii) */
84 char index_byte
; /* index byte */
86 typedef struct addr_mode addr_modeS
;
89 char *freeptr
, *freeptr_static
; /* points at some number of free bytes */
90 struct hash_control
*inst_hash_handle
;
92 struct ns32k_opcode
*desc
; /* pointer at description of instruction */
93 addr_modeS addr_modeP
;
94 const char EXP_CHARS
[] = "eE";
95 const char FLT_CHARS
[] = "fd"; /* we don't want to support lowercase, do we */
97 /* UPPERCASE denotes live names
98 * when an instruction is built, IIF is used as an intermidiate form to store
99 * the actual parts of the instruction. A ns32k machine instruction can
100 * be divided into a couple of sub PARTs. When an instruction is assembled
101 * the appropriate PART get an assignment. When an IIF has been completed it's
102 * converted to a FRAGment as specified in AS.H */
104 /* internal structs */
114 int type
; /* how to interpret object */
115 int size
; /* Estimated max size of object */
116 unsigned long object
; /* binary data */
117 int object_adjust
; /* number added to object */
118 int pcrel
; /* True if object is pcrel */
119 int pcrel_adjust
; /* length in bytes from the
120 instruction start to the
122 int im_disp
; /* True if the object is a displacement */
123 relax_substateT relax_substate
; /* Initial relaxsubstate */
124 bit_fixS
*bit_fixP
; /* Pointer at bit_fix struct */
125 int addr_mode
; /* What addrmode do we associate with this iif-entry */
126 char bsr
; /* Sequent hack */
129 iif_entryT
; /* Internal Instruction Format */
133 int instr_size
; /* Max size of instruction in bytes. */
134 iif_entryT iifP
[IIF_ENTRIES
+ 1];
136 struct int_ins_form iif
;
138 char *input_line_pointer
;
139 /* description of the PARTs in IIF
141 * 0 total length in bytes of entries in iif
154 * For every entry there is a datalength in bytes. This is stored in size[n].
155 * 0, the objectlength is not explicitly given by the instruction
156 * and the operand is undefined. This is a case for relaxation.
157 * Reserve 4 bytes for the final object.
159 * 1, the entry contains one byte
160 * 2, the entry contains two bytes
161 * 3, the entry contains three bytes
162 * 4, the entry contains four bytes
165 * Furthermore, every entry has a data type identifier in type[n].
167 * 0, the entry is void, ignore it.
168 * 1, the entry is a binary number.
169 * 2, the entry is a pointer at an expression.
170 * Where expression may be as simple as a single '1',
171 * and as complicated as foo-bar+12,
172 * foo and bar may be undefined but suffixed by :{b|w|d} to
173 * control the length of the object.
175 * 3, the entry is a pointer at a bignum struct
178 * The low-order-byte coresponds to low physical memory.
179 * Obviously a FRAGment must be created for each valid disp in PART whose
180 * datalength is undefined (to bad) .
181 * The case where just the expression is undefined is less severe and is
182 * handled by fix. Here the number of bytes in the objectfile is known.
183 * With this representation we simplify the assembly and separates the
184 * machine dependent/independent parts in a more clean way (said OE)
187 struct option opt1
[] = /* restore, exit */
199 struct option opt2
[] = /* save, enter */
211 struct option opt3
[] = /* setcfg */
219 struct option opt4
[] = /* cinv */
226 struct option opt5
[] = /* string inst */
233 struct option opt6
[] = /* plain reg ext,cvtp etc */
246 #if !defined(NS32032) && !defined(NS32532)
250 struct option cpureg_532
[] = /* lpr spr */
263 {"intbase", 0xe, 0xff},
267 struct option mmureg_532
[] = /* lmr smr */
274 {"ivar0", 0xe, 0xff},
275 {"ivar1", 0xf, 0xff},
279 struct option cpureg_032
[] = /* lpr spr */
286 {"intbase", 0xe, 0xff},
290 struct option mmureg_032
[] = /* lmr smr */
306 struct option
*cpureg
= cpureg_532
;
307 struct option
*mmureg
= mmureg_532
;
309 struct option
*cpureg
= cpureg_032
;
310 struct option
*mmureg
= mmureg_032
;
314 const pseudo_typeS md_pseudo_table
[] =
319 #define IND(x,y) (((x)<<2)+(y))
321 /* those are index's to relax groups in md_relax_table
322 ie it must be multiplied by 4 to point at a group start. Viz IND(x,y)
323 Se function relax_segment in write.c for more info */
328 /* those are index's to entries in a relax group */
334 /* Those limits are calculated from the displacement start in memory.
335 The ns32k uses the begining of the instruction as displacement base.
336 This type of displacements could be handled here by moving the limit window
337 up or down. I choose to use an internal displacement base-adjust as there
338 are other routines that must consider this. Also, as we have two various
339 offset-adjusts in the ns32k (acb versus br/brs/jsr/bcond), two set of limits
340 would have had to be used.
341 Now we dont have to think about that. */
344 const relax_typeS md_relax_table
[] =
351 {(63), (-64), 1, IND (BRANCH
, WORD
)},
352 {(8192), (-8192), 2, IND (BRANCH
, DOUBLE
)},
357 /* Array used to test if mode contains displacements.
358 Value is true if mode contains displacement. */
361 {0, 0, 0, 0, 0, 0, 0, 0,
362 1, 1, 1, 1, 1, 1, 1, 1,
363 1, 1, 1, 0, 0, 1, 1, 0,
364 1, 1, 1, 1, 1, 1, 1, 1};
366 /* Array used to calculate max size of displacements */
374 static segT
evaluate_expr (expressionS
* resultP
, char *ptr
);
375 static void md_number_to_disp (char *buf
, long val
, int n
);
376 static void md_number_to_imm (char *buf
, long val
, int n
);
378 #else /* not __STDC__ */
380 static segT
evaluate_expr ();
381 static void md_number_to_disp ();
382 static void md_number_to_imm ();
384 #endif /* not __STDC__ */
386 /* Parses a general operand into an addressingmode struct
388 in: pointer at operand in ascii form
389 pointer at addr_mode struct for result
390 the level of recursion. (always 0 or 1)
392 out: data in addr_mode struct
395 addr_mode (operand
, addr_modeP
, recursive_level
)
397 register addr_modeS
*addr_modeP
;
405 mode
= DEFAULT
; /* default */
406 addr_modeP
->scaled_mode
= 0; /* why not */
407 addr_modeP
->scaled_reg
= 0; /* if 0, not scaled index */
408 addr_modeP
->float_flag
= 0;
409 addr_modeP
->am_size
= 0;
410 addr_modeP
->im_disp
= 0;
411 addr_modeP
->pcrel
= 0; /* not set in this function */
412 addr_modeP
->disp_suffix
[0] = 0;
413 addr_modeP
->disp_suffix
[1] = 0;
414 addr_modeP
->disp
[0] = NULL
;
415 addr_modeP
->disp
[1] = NULL
;
420 } /* we don't want this */
424 /* the following three case statements controls the mode-chars
425 this is the place to ed if you want to change them */
426 #ifdef ABSOLUTE_PREFIX
427 case ABSOLUTE_PREFIX
:
428 if (str
[strl
- 1] == ']')
430 addr_modeP
->mode
= 21; /* absolute */
431 addr_modeP
->disp
[0] = str
+ 1;
434 #ifdef IMMEDIATE_PREFIX
435 case IMMEDIATE_PREFIX
:
436 if (str
[strl
- 1] == ']')
438 addr_modeP
->mode
= 20; /* immediate */
439 addr_modeP
->disp
[0] = str
+ 1;
443 if (str
[strl
- 1] != ']')
449 if (str
[2] != '\000')
451 addr_modeP
->mode
= 27; /* pc-relativ */
452 addr_modeP
->disp
[0] = str
+ 2;
456 as_warn ("Invalid syntax in PC-relative addressing mode");
462 if (str
[strl
- 1] != ']')
464 if ((!strncmp (str
, "ext(", 4)) && strl
> 7)
466 addr_modeP
->disp
[0] = str
+ 4;
470 { /* disp[0]'s termination point */
477 while (j
< strl
&& i
!= 0);
478 if (i
!= 0 || !(str
[j
+ 1] == '-' || str
[j
+ 1] == '+'))
480 as_warn ("Invalid syntax in External addressing mode");
483 str
[j
] = '\000'; /* null terminate disp[0] */
484 addr_modeP
->disp
[1] = str
+ j
+ 2;
485 addr_modeP
->mode
= 22;
499 addr_modeP
->float_flag
= 1;
501 if (str
[1] >= '0' && str
[1] < '8')
503 addr_modeP
->mode
= str
[1] - '0';
508 if (!strncmp (str
, "tos", 3))
510 addr_modeP
->mode
= 23;/* TopOfStack */
517 if (str
[strl
- 1] == ')')
519 if (str
[strl
- 2] == ')')
521 if (!strncmp (&str
[strl
- 5], "(fp", 3))
523 mode
= 16; /* Memory Relative */
525 if (!strncmp (&str
[strl
- 5], "(sp", 3))
529 if (!strncmp (&str
[strl
- 5], "(sb", 3))
534 { /* memory relative */
535 addr_modeP
->mode
= mode
;
536 j
= strl
- 5; /* temp for end of disp[0] */
541 if (str
[strl
] == ')')
543 if (str
[strl
] == '(')
546 while (strl
> -1 && i
!= 0);
549 as_warn ("Invalid syntax in Memory Relative addressing mode");
552 addr_modeP
->disp
[1] = str
;
553 addr_modeP
->disp
[0] = str
+ strl
+ 1;
554 str
[j
] = '\000'; /* null terminate disp[0] */
555 str
[strl
] = '\000'; /* null terminate disp[1] */
559 switch (str
[strl
- 3])
563 if (str
[strl
- 2] >= '0' && str
[strl
- 2] < '8' && str
[strl
- 4] == '(')
565 addr_modeP
->mode
= str
[strl
- 2] - '0' + 8;
566 addr_modeP
->disp
[0] = str
;
568 return (-1); /* reg rel */
571 if (!strncmp (&str
[strl
- 4], "(fp", 3))
575 if (!strncmp (&str
[strl
- 4], "(sp", 3))
579 if (!strncmp (&str
[strl
- 4], "(sb", 3))
583 if (!strncmp (&str
[strl
- 4], "(pc", 3))
589 addr_modeP
->mode
= mode
;
590 addr_modeP
->disp
[0] = str
;
591 str
[strl
- 4] = '\0';
592 return (-1); /* memory space */
596 /* no trailing ')' do we have a ']' ? */
597 if (str
[strl
- 1] == ']')
599 switch (str
[strl
- 2])
614 as_warn ("Invalid scaled-indexed mode, use (b,w,d,q)");
615 if (str
[strl
- 3] != ':' || str
[strl
- 6] != '[' ||
616 str
[strl
- 5] == 'r' || str
[strl
- 4] < '0' || str
[strl
- 4] > '7')
618 as_warn ("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}");
622 if (recursive_level
> 0)
624 as_warn ("Scaled-indexed addressing mode combined with scaled-index");
627 addr_modeP
->am_size
+= 1; /* scaled index byte */
628 j
= str
[strl
- 4] - '0'; /* store temporary */
629 str
[strl
- 6] = '\000'; /* nullterminate for recursive call */
630 i
= addr_mode (str
, addr_modeP
, 1);
631 if (!i
|| addr_modeP
->mode
== 20)
633 as_warn ("Invalid or illegal addressing mode combined with scaled-index");
636 addr_modeP
->scaled_mode
= addr_modeP
->mode
; /* store the inferior mode */
637 addr_modeP
->mode
= mode
;
638 addr_modeP
->scaled_reg
= j
+ 1;
643 addr_modeP
->mode
= DEFAULT
; /* default to whatever */
644 addr_modeP
->disp
[0] = str
;
648 /* ptr points at string
649 addr_modeP points at struct with result
650 This routine calls addr_mode to determine the general addr.mode of
651 the operand. When this is ready it parses the displacements for size
652 specifying suffixes and determines size of immediate mode via ns32k-opcode.
653 Also builds index bytes if needed.
656 get_addr_mode (ptr
, addr_modeP
)
658 addr_modeS
*addr_modeP
;
661 addr_mode (ptr
, addr_modeP
, 0);
662 if (addr_modeP
->mode
== DEFAULT
|| addr_modeP
->scaled_mode
== -1)
664 /* resolve ambigious operands, this shouldn't
665 be necessary if one uses standard NSC operand
666 syntax. But the sequent compiler doesn't!!!
667 This finds a proper addressinging mode if it
668 is implicitly stated. See ns32k-opcode.h */
669 (void) evaluate_expr (&exprP
, ptr
); /* this call takes time Sigh! */
670 if (addr_modeP
->mode
== DEFAULT
)
672 if (exprP
.X_add_symbol
|| exprP
.X_subtract_symbol
)
674 addr_modeP
->mode
= desc
->default_model
; /* we have a label */
678 addr_modeP
->mode
= desc
->default_modec
; /* we have a constant */
683 if (exprP
.X_add_symbol
|| exprP
.X_subtract_symbol
)
685 addr_modeP
->scaled_mode
= desc
->default_model
;
689 addr_modeP
->scaled_mode
= desc
->default_modec
;
692 /* must put this mess down in addr_mode to handle the scaled case better */
694 /* It appears as the sequent compiler wants an absolute when we have a
695 label without @. Constants becomes immediates besides the addr case.
696 Think it does so with local labels too, not optimum, pcrel is better.
697 When I have time I will make gas check this and select pcrel when possible
698 Actually that is trivial.
700 if (tmp
= addr_modeP
->scaled_reg
)
701 { /* build indexbyte */
702 tmp
--; /* remember regnumber comes incremented for flagpurpose */
703 tmp
|= addr_modeP
->scaled_mode
<< 3;
704 addr_modeP
->index_byte
= (char) tmp
;
705 addr_modeP
->am_size
+= 1;
707 if (disp_test
[addr_modeP
->mode
])
708 { /* there was a displacement, probe for length specifying suffix*/
711 register char suffix
;
712 register char suffix_sub
;
715 register char *fromP
;
717 addr_modeP
->pcrel
= 0;
718 if (disp_test
[addr_modeP
->mode
])
719 { /* there is a displacement */
720 if (addr_modeP
->mode
== 27 || addr_modeP
->scaled_mode
== 27)
721 { /* do we have pcrel. mode */
722 addr_modeP
->pcrel
= 1;
724 addr_modeP
->im_disp
= 1;
725 for (i
= 0; i
< 2; i
++)
727 suffix_sub
= suffix
= 0;
728 if (toP
= addr_modeP
->disp
[i
])
729 { /* suffix of expression, the largest size rules */
739 as_warn ("Premature end of suffix--Defaulting to d");
752 as_warn ("Bad suffix after ':' use {b|w|d} Defaulting to d");
756 toP
--; /* So we write over the ':' */
757 if (suffix
< suffix_sub
)
761 *toP
= '\0';/* terminate properly */
762 addr_modeP
->disp_suffix
[i
] = suffix
;
763 addr_modeP
->am_size
+= suffix
? suffix
: 4;
771 if (addr_modeP
->mode
== 20)
772 { /* look in ns32k_opcode for size */
773 addr_modeP
->disp_suffix
[0] = addr_modeP
->am_size
= desc
->im_size
;
774 addr_modeP
->im_disp
= 0;
777 return addr_modeP
->mode
;
781 /* read an optionlist */
783 optlist (str
, optionP
, default_map
)
784 char *str
; /* the string to extract options from */
785 struct option
*optionP
; /* how to search the string */
786 unsigned long *default_map
;/* default pattern and output */
788 register int i
, j
, k
, strlen1
, strlen2
;
789 register char *patternP
, *strP
;
790 strlen1
= strlen (str
);
793 as_fatal ("Very short instr to option, ie you can't do it on a NULLstr");
795 for (i
= 0; optionP
[i
].pattern
!= 0; i
++)
797 strlen2
= strlen (optionP
[i
].pattern
);
798 for (j
= 0; j
< strlen1
; j
++)
800 patternP
= optionP
[i
].pattern
;
802 for (k
= 0; k
< strlen2
; k
++)
804 if (*(strP
++) != *(patternP
++))
809 *default_map
|= optionP
[i
].or;
810 *default_map
&= optionP
[i
].and;
816 /* search struct for symbols
817 This function is used to get the short integer form of reg names
818 in the instructions lmr, smr, lpr, spr
819 return true if str is found in list */
822 list_search (str
, optionP
, default_map
)
823 char *str
; /* the string to match */
824 struct option
*optionP
; /* list to search */
825 unsigned long *default_map
;/* default pattern and output */
828 for (i
= 0; optionP
[i
].pattern
!= 0; i
++)
830 if (!strncmp (optionP
[i
].pattern
, str
, 20))
831 { /* use strncmp to be safe */
832 *default_map
|= optionP
[i
].or;
833 *default_map
&= optionP
[i
].and;
837 as_warn ("No such entry in list. (cpu/mmu register)");
842 evaluate_expr (resultP
, ptr
)
843 expressionS
*resultP
;
846 register char *tmp_line
;
847 register segT segment
;
848 tmp_line
= input_line_pointer
;
849 input_line_pointer
= ptr
;
850 segment
= expression (&exprP
);
851 input_line_pointer
= tmp_line
;
855 /* Convert operands to iif-format and adds bitfields to the opcode.
856 Operands are parsed in such an order that the opcode is updated from
857 its most significant bit, that is when the operand need to alter the
859 Be carefull not to put to objects in the same iif-slot.
863 encode_operand (argc
, argv
, operandsP
, suffixP
, im_size
, opcode_bit_ptr
)
872 int pcrel
, tmp
, b
, loop
, pcrel_adjust
;
873 for (loop
= 0; loop
< argc
; loop
++)
875 i
= operandsP
[loop
<< 1] - '1'; /* what operand are we supposed to work on */
877 as_fatal ("Internal consistency error. check ns32k-opcode.h");
881 switch (operandsP
[(loop
<< 1) + 1])
883 case 'f': /* operand of sfsr turns out to be a nasty specialcase */
885 case 'F': /* 32 bit float general form */
886 case 'L': /* 64 bit float */
887 case 'Q': /* quad-word */
890 case 'D': /* double-word */
891 case 'A': /* double-word gen-address-form ie no regs allowed */
892 get_addr_mode (argv
[i
], &addr_modeP
);
893 iif
.instr_size
+= addr_modeP
.am_size
;
894 if (opcode_bit_ptr
== desc
->opcode_size
)
898 for (j
= b
; j
< (b
+ 2); j
++)
900 if (addr_modeP
.disp
[j
- b
])
904 addr_modeP
.disp_suffix
[j
- b
],
905 (unsigned long) addr_modeP
.disp
[j
- b
],
908 iif
.instr_size
- addr_modeP
.am_size
, /* this aint used (now) */
912 addr_modeP
.scaled_reg
? addr_modeP
.scaled_mode
: addr_modeP
.mode
,
917 iif
.iifP
[1].object
|= ((long) addr_modeP
.mode
) << opcode_bit_ptr
;
918 if (addr_modeP
.scaled_reg
)
921 IIF (j
, 1, 1, (unsigned long) addr_modeP
.index_byte
, 0, 0, 0, 0, 0, NULL
, -1, 0);
924 case 'b': /* multiple instruction disp */
925 freeptr
++; /* OVE:this is an useful hack */
926 tmp
= (int) sprintf (freeptr
,
928 argv
[i
], desc
->im_size
);
930 freeptr
= (char *) tmp
;
931 pcrel
-= 1; /* make pcrel 0 inspite of what case 'p': wants */
933 case 'p': /* displacement - pc relative addressing */
936 case 'd': /* displacement */
937 iif
.instr_size
+= suffixP
[i
] ? suffixP
[i
] : 4;
938 IIF (12, 2, suffixP
[i
], (unsigned long) argv
[i
], 0,
939 pcrel
, pcrel_adjust
, 1, IND (BRANCH
, BYTE
), NULL
, -1, 0);
941 case 'H': /* sequent-hack: the linker wants a bit set when bsr */
943 iif
.instr_size
+= suffixP
[i
] ? suffixP
[i
] : 4;
944 IIF (12, 2, suffixP
[i
], (unsigned long) argv
[i
], 0,
945 pcrel
, pcrel_adjust
, 1, IND (BRANCH
, BYTE
), NULL
, -1, 1);
947 case 'q': /* quick */
949 IIF (11, 2, 42, (unsigned long) argv
[i
], 0, 0, 0, 0, 0,
950 bit_fix_new (4, opcode_bit_ptr
, -8, 7, 0, 1, 0), -1, 0);
952 case 'r': /* register number (3 bits) */
953 list_search (argv
[i
], opt6
, &tmp
);
955 iif
.iifP
[1].object
|= tmp
<< opcode_bit_ptr
;
957 case 'O': /* setcfg instruction optionslist */
958 optlist (argv
[i
], opt3
, &tmp
);
960 iif
.iifP
[1].object
|= tmp
<< 15;
962 case 'C': /* cinv instruction optionslist */
963 optlist (argv
[i
], opt4
, &tmp
);
965 iif
.iifP
[1].object
|= tmp
<< 15; /*insert the regtype in opcode */
967 case 'S': /* stringinstruction optionslist */
968 optlist (argv
[i
], opt5
, &tmp
);
970 iif
.iifP
[1].object
|= tmp
<< 15;
973 case 'U': /* registerlist */
974 IIF (10, 1, 1, 0, 0, 0, 0, 0, 0, NULL
, -1, 0);
975 switch (operandsP
[(i
<< 1) + 1])
977 case 'u': /* restore, exit */
978 optlist (argv
[i
], opt1
, &iif
.iifP
[10].object
);
980 case 'U': /* save,enter */
981 optlist (argv
[i
], opt2
, &iif
.iifP
[10].object
);
986 case 'M': /* mmu register */
987 list_search (argv
[i
], mmureg
, &tmp
);
989 iif
.iifP
[1].object
|= tmp
<< opcode_bit_ptr
;
991 case 'P': /* cpu register */
992 list_search (argv
[i
], cpureg
, &tmp
);
994 iif
.iifP
[1].object
|= tmp
<< opcode_bit_ptr
;
996 case 'g': /* inss exts */
997 iif
.instr_size
+= 1; /* 1 byte is allocated after the opcode */
999 (unsigned long) argv
[i
], /* i always 2 here */
1001 bit_fix_new (3, 5, 0, 7, 0, 0, 0), /* a bit_fix is targeted to the byte */
1005 (unsigned long) argv
[i
], /* i always 3 here */
1007 bit_fix_new (5, 0, 1, 32, -1, 0, -1), -1, 0);
1010 iif
.instr_size
+= 1;
1011 b
= 2 + i
; /* put the extension byte after opcode */
1012 IIF (b
, 2, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0);
1014 as_fatal ("Bad opcode-table-option, check in file ns32k-opcode.h");
1019 /* in: instruction line
1020 out: internal structure of instruction
1021 that has been prepared for direct conversion to fragment(s) and
1022 fixes in a systematical fashion
1023 Return-value = recursive_level
1025 /* build iif of one assembly text line */
1027 parse (line
, recursive_level
)
1029 int recursive_level
;
1031 register char *lineptr
, c
, suffix_separator
;
1035 char suffix
[MAX_ARGS
], *argv
[MAX_ARGS
]; /* no more than 4 operands */
1036 if (recursive_level
<= 0)
1037 { /* called from md_assemble */
1038 for (lineptr
= line
; (*lineptr
) != '\0' && (*lineptr
) != ' '; lineptr
++);
1041 if (!(desc
= (struct ns32k_opcode
*) hash_find (inst_hash_handle
, line
)))
1043 as_fatal ("No such opcode");
1052 if (*desc
->operands
)
1054 if (*lineptr
++ != '\0')
1058 while (*lineptr
!= '\0')
1060 if (desc
->operands
[argc
<< 1])
1063 arg_type
= desc
->operands
[(argc
<< 1) + 1];
1069 case 'H': /* the operand is supposed to be a displacement */
1070 /* Hackwarning: do not forget to update the 4 cases above when editing ns32k-opcode.h */
1071 suffix_separator
= ':';
1074 suffix_separator
= '\255'; /* if this char occurs we loose */
1076 suffix
[argc
] = 0; /* 0 when no ':' is encountered */
1077 argv
[argc
] = freeptr
;
1079 while ((c
= *lineptr
) != '\0' && c
!= sep
)
1094 if (c
== suffix_separator
)
1095 { /* ':' - label/suffix separator */
1108 as_warn ("Bad suffix, defaulting to d");
1110 if (lineptr
[1] == '\0' || lineptr
[1] == sep
)
1124 if (*lineptr
== '\0')
1130 as_fatal ("Too many operands passed to instruction");
1135 if (argc
!= strlen (desc
->operands
) / 2)
1137 if (strlen (desc
->default_args
))
1138 { /* we can apply default, dont goof */
1139 if (parse (desc
->default_args
, 1) != 1)
1140 { /* check error in default */
1141 as_fatal ("Wrong numbers of operands in default, check ns32k-opcodes.h");
1146 as_fatal ("Wrong number of operands");
1150 for (i
= 0; i
< IIF_ENTRIES
; i
++)
1152 iif
.iifP
[i
].type
= 0; /* mark all entries as void*/
1155 /* build opcode iif-entry */
1156 iif
.instr_size
= desc
->opcode_size
/ 8;
1157 IIF (1, 1, iif
.instr_size
, desc
->opcode_seed
, 0, 0, 0, 0, 0, 0, -1, 0);
1159 /* this call encodes operands to iif format */
1162 encode_operand (argc
,
1169 return recursive_level
;
1173 /* Convert iif to fragments.
1174 From this point we start to dribble with functions in other files than
1175 this one.(Except hash.c) So, if it's possible to make an iif for an other
1176 CPU, you don't need to know what frags, relax, obstacks, etc is in order
1177 to port this assembler. You only need to know if it's possible to reduce
1178 your cpu-instruction to iif-format (takes some work) and adopt the other
1179 md_? parts according to given instructions
1180 Note that iif was invented for the clean ns32k`s architecure.
1194 int rem_size
; /* count the remaining bytes of instruction */
1197 int size_so_far
= 0; /* used to calculate pcrel_adjust */
1199 rem_size
= iif
.instr_size
;
1200 memP
= frag_more (iif
.instr_size
); /* make sure we have enough bytes for instruction */
1202 inst_offset
= (char *) (memP
- frag_now
->fr_literal
);
1203 inst_frag
= frag_now
;
1204 for (i
= 0; i
< IIF_ENTRIES
; i
++)
1206 if (type
= iif
.iifP
[i
].type
)
1207 { /* the object exist, so handle it */
1208 switch (size
= iif
.iifP
[i
].size
)
1211 size
= 0; /* it's a bitfix that operates on an existing object*/
1212 if (iif
.iifP
[i
].bit_fixP
->fx_bit_base
)
1213 { /* expand fx_bit_base to point at opcode */
1214 iif
.iifP
[i
].bit_fixP
->fx_bit_base
= (long) inst_opcode
;
1216 case 8: /* bignum or doublefloat */
1217 memset (memP
, '\0', 8);
1221 case 4: /* the final size in objectmemory is known */
1222 j
= (unsigned long) iif
.iifP
[i
].bit_fixP
;
1225 case 1: /* the object is pure binary */
1226 if (j
|| iif
.iifP
[i
].pcrel
)
1228 fix_new_ns32k (frag_now
,
1229 (long) (memP
- frag_now
->fr_literal
),
1235 (char) size_so_far
, /*iif.iifP[i].pcrel_adjust,*/
1236 iif
.iifP
[i
].im_disp
,
1238 iif
.iifP
[i
].bsr
); /* sequent hack */
1241 { /* good, just put them bytes out */
1242 switch (iif
.iifP
[i
].im_disp
)
1245 md_number_to_chars (memP
, iif
.iifP
[i
].object
, size
);
1248 md_number_to_disp (memP
, iif
.iifP
[i
].object
, size
);
1251 as_fatal ("iif convert internal pcrel/binary");
1257 case 2: /* the object is a pointer at an expression, so unpack
1258 it, note that bignums may result from the expression
1260 if ((segment
= evaluate_expr (&exprP
, (char *) iif
.iifP
[i
].object
)) == SEG_BIG
|| size
== 8)
1262 if ((k
= exprP
.X_add_number
) > 0)
1263 { /* we have a bignum ie a quad */
1264 /* this can only happens in a long suffixed instruction */
1265 memset (memP
, '\0', size
); /* size normally is 8 */
1267 as_warn ("Bignum too big for long");
1270 for (l
= 0; k
> 0; k
--, l
+= 2)
1272 md_number_to_chars (memP
+ l
, generic_bignum
[l
>> 1], sizeof (LITTLENUM_TYPE
));
1277 LITTLENUM_TYPE words
[4];
1282 gen_to_words (words
, 2, 8);
1283 md_number_to_imm (memP
, (long) words
[0], sizeof (LITTLENUM_TYPE
));
1284 md_number_to_imm (memP
+ sizeof (LITTLENUM_TYPE
), (long) words
[1], sizeof (LITTLENUM_TYPE
));
1287 gen_to_words (words
, 4, 11);
1288 md_number_to_imm (memP
, (long) words
[0], sizeof (LITTLENUM_TYPE
));
1289 md_number_to_imm (memP
+ sizeof (LITTLENUM_TYPE
), (long) words
[1], sizeof (LITTLENUM_TYPE
));
1290 md_number_to_imm (memP
+ 2 * sizeof (LITTLENUM_TYPE
), (long) words
[2], sizeof (LITTLENUM_TYPE
));
1291 md_number_to_imm (memP
+ 3 * sizeof (LITTLENUM_TYPE
), (long) words
[3], sizeof (LITTLENUM_TYPE
));
1300 exprP
.X_add_symbol
||
1301 exprP
.X_subtract_symbol
||
1304 /* the expression was undefined due to an undefined label */
1305 /* create a fix so we can fix the object later */
1306 exprP
.X_add_number
+= iif
.iifP
[i
].object_adjust
;
1307 fix_new_ns32k (frag_now
,
1308 (long) (memP
- frag_now
->fr_literal
),
1311 exprP
.X_subtract_symbol
,
1314 (char) size_so_far
, /*iif.iifP[i].pcrel_adjust,*/
1315 iif
.iifP
[i
].im_disp
,
1317 iif
.iifP
[i
].bsr
); /* sequent hack */
1321 { /* good, just put them bytes out */
1322 switch (iif
.iifP
[i
].im_disp
)
1325 md_number_to_imm (memP
, exprP
.X_add_number
, size
);
1328 md_number_to_disp (memP
, exprP
.X_add_number
, size
);
1331 as_fatal ("iif convert internal pcrel/pointer");
1338 as_fatal ("Internal logic error in iif.iifP[n].type");
1341 case 0: /* To bad, the object may be undefined as far as its final
1342 nsize in object memory is concerned. The size of the object
1343 in objectmemory is not explicitly given.
1344 If the object is defined its length can be determined and
1345 a fix can replace the frag.
1349 segment
= evaluate_expr (&exprP
, (char *) iif
.iifP
[i
].object
);
1350 if ((exprP
.X_add_symbol
|| exprP
.X_subtract_symbol
) &&
1352 { /* OVE: hack, clamp to 4 bytes */
1353 size
= 4; /* we dont wan't to frag this, use 4 so it reaches */
1354 fix_new_ns32k (frag_now
,
1355 (long) (memP
- frag_now
->fr_literal
),
1358 exprP
.X_subtract_symbol
,
1360 0, /* never iif.iifP[i].pcrel, */
1361 (char) size_so_far
, /*iif.iifP[i].pcrel_adjust,*/
1362 1, /* always iif.iifP[i].im_disp, */
1366 break; /* exit this absolute hack */
1369 if (exprP
.X_add_symbol
|| exprP
.X_subtract_symbol
)
1371 if (exprP
.X_subtract_symbol
)
1372 { /* We cant relax this case */
1373 as_fatal ("Can't relax difference");
1377 /* at this stage we must undo some of the effect caused
1378 by frag_more, ie we must make sure that frag_var causes
1379 frag_new to creat a valid fix-size in the frag it`s closing
1381 temp
= -(rem_size
- 4);
1382 obstack_blank_fast (&frags
, temp
);
1383 /* we rewind none, some or all of the requested size we
1384 requested by the first frag_more for this iif chunk.
1385 Note: that we allocate 4 bytes to an object we NOT YET
1386 know the size of, thus rem_size-4.
1388 (void) frag_variant (rs_machine_dependent
,
1391 IND (BRANCH
, UNDEF
), /* expecting the worst */
1394 (char *) inst_opcode
,
1395 (char) size_so_far
, /*iif.iifP[i].pcrel_adjust);*/
1396 iif
.iifP
[i
].bsr
); /* sequent linker hack */
1400 memP
= frag_more (rem_size
);
1405 { /* Double work, this is done in md_number_to_disp */
1406 /* exprP.X_add_number; what was this supposed to be?
1408 if (-64 <= exprP
.X_add_number
&& exprP
.X_add_number
<= 63)
1414 if (-8192 <= exprP
.X_add_number
&& exprP
.X_add_number
<= 8191)
1420 if (-0x1f000000 <= exprP
.X_add_number
&&
1421 exprP
.X_add_number
<= 0x1fffffff)
1422 /* if (-0x40000000<=exprP.X_add_number &&
1423 exprP.X_add_number<=0x3fffffff) */
1429 as_warn ("Displacement to large for :d");
1434 /* rewind the bytes not used */
1436 md_number_to_disp (memP
, exprP
.X_add_number
, size
);
1437 obstack_blank_fast (&frags
, temp
);
1439 rem_size
-= 4; /* we allocated this amount */
1444 as_fatal ("Internal logic error in iif.iifP[].type");
1446 size_so_far
+= size
;
1456 freeptr
= freeptr_static
;
1457 parse (line
, 0); /* explode line to more fix form in iif */
1458 convert_iif (); /* convert iif to frags, fix's etc */
1460 printf (" \t\t\t%s\n", line
);
1468 /* build a hashtable of the instructions */
1469 register const struct ns32k_opcode
*ptr
;
1470 register char *stat
;
1471 inst_hash_handle
= hash_new ();
1472 for (ptr
= ns32k_opcodes
; ptr
< endop
; ptr
++)
1474 if (*(stat
= hash_insert (inst_hash_handle
, ptr
->name
, (char *) ptr
)))
1476 as_fatal ("Can't hash %s: %s", ptr
->name
, stat
); /*fatal*/
1480 freeptr_static
= (char *) malloc (PRIVATE_SIZE
); /* some private space please! */
1487 free (freeptr_static
);
1490 /* Must be equal to MAX_PRECISON in atof-ieee.c */
1491 #define MAX_LITTLENUMS 6
1493 /* Turn the string pointed to by litP into a floating point constant of type
1494 type, and emit the appropriate bytes. The number of LITTLENUMS emitted
1495 is stored in *sizeP . An error message is returned, or NULL on OK.
1498 md_atof (type
, litP
, sizeP
)
1504 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1505 LITTLENUM_TYPE
*wordP
;
1519 return "Bad call to MD_ATOF()";
1521 t
= atof_ns32k (input_line_pointer
, type
, words
);
1523 input_line_pointer
= t
;
1525 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1526 for (wordP
= words
+ prec
; prec
--;)
1528 md_number_to_chars (litP
, (long) (*--wordP
), sizeof (LITTLENUM_TYPE
));
1529 litP
+= sizeof (LITTLENUM_TYPE
);
1531 return ""; /* Someone should teach Dean about null pointers */
1534 /* Convert number to chars in correct order */
1537 md_number_to_chars (buf
, value
, nbytes
)
1545 printf ("%x ", value
& 0xff);
1547 *buf
++ = value
; /* Lint wants & MASK_CHAR. */
1548 value
>>= BITS_PER_CHAR
;
1550 } /* md_number_to_chars() */
1553 /* This is a variant of md_numbers_to_chars. The reason for its' existence
1554 is the fact that ns32k uses Huffman coded displacements. This implies
1555 that the bit order is reversed in displacements and that they are prefixed
1560 10xxxxxx xxxxxxxx word
1561 11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx double word
1563 This must be taken care of and we do it here!
1566 md_number_to_disp (buf
, val
, n
)
1574 if (val
< -64 || val
> 63)
1575 as_warn ("Byte displacement out of range. line number not valid");
1578 printf ("%x ", val
& 0xff);
1583 if (val
< -8192 || val
> 8191)
1584 as_warn ("Word displacement out of range. line number not valid");
1588 printf ("%x ", val
>> 8 & 0xff);
1590 *buf
++ = (val
>> 8);
1592 printf ("%x ", val
& 0xff);
1597 if (val
< -0x1f000000 || val
>= 0x20000000)
1598 /* if (val < -0x20000000 || val >= 0x20000000) */
1599 as_warn ("Double word displacement out of range");
1602 printf ("%x ", val
>> 24 & 0xff);
1604 *buf
++ = (val
>> 24);
1606 printf ("%x ", val
>> 16 & 0xff);
1608 *buf
++ = (val
>> 16);
1610 printf ("%x ", val
>> 8 & 0xff);
1612 *buf
++ = (val
>> 8);
1614 printf ("%x ", val
& 0xff);
1619 as_fatal ("Internal logic error. line %s, file \"%s\"", __LINE__
, __FILE__
);
1624 md_number_to_imm (buf
, val
, n
)
1633 printf ("%x ", val
& 0xff);
1639 printf ("%x ", val
>> 8 & 0xff);
1641 *buf
++ = (val
>> 8);
1643 printf ("%x ", val
& 0xff);
1649 printf ("%x ", val
>> 24 & 0xff);
1651 *buf
++ = (val
>> 24);
1653 printf ("%x ", val
>> 16 & 0xff);
1655 *buf
++ = (val
>> 16);
1657 printf ("%x ", val
>> 8 & 0xff);
1659 *buf
++ = (val
>> 8);
1661 printf ("%x ", val
& 0xff);
1666 as_fatal ("Internal logic error. line %s, file \"%s\"", __LINE__
, __FILE__
);
1670 /* Translate internal representation of relocation info into target format.
1672 OVE: on a ns32k the twiddling continues at an even deeper level
1673 here we have to distinguish between displacements and immediates.
1675 The sequent has a bit for this. It also has a bit for relocobjects that
1676 points at the target for a bsr (BranchSubRoutine) !?!?!?!
1678 This md_ri.... is tailored for sequent.
1683 md_ri_to_chars (the_bytes
, ri
)
1685 struct reloc_info_generic
*ri
;
1690 } /* sequent seems to want this */
1691 md_number_to_chars (the_bytes
, ri
->r_address
, sizeof (ri
->r_address
));
1692 md_number_to_chars (the_bytes
+ 4, ((long) (ri
->r_symbolnum
)
1693 | (long) (ri
->r_pcrel
<< 24)
1694 | (long) (ri
->r_length
<< 25)
1695 | (long) (ri
->r_extern
<< 27)
1696 | (long) (ri
->r_bsr
<< 28)
1697 | (long) (ri
->r_disp
<< 29)),
1699 /* the first and second md_number_to_chars never overlaps (32bit cpu case) */
1702 #endif /* comment */
1706 tc_aout_fix_to_chars (where
, fixP
, segment_address_in_file
)
1709 relax_addressT segment_address_in_file
;
1712 * In: length of relocation (or of address) in chars: 1, 2 or 4.
1713 * Out: GNU LD relocation length code: 0, 1, or 2.
1716 static unsigned char nbytes_r_length
[] =
1720 know (fixP
->fx_addsy
!= NULL
);
1722 md_number_to_chars (where
,
1723 fixP
->fx_frag
->fr_address
+ fixP
->fx_where
- segment_address_in_file
,
1726 r_symbolnum
= (S_IS_DEFINED (fixP
->fx_addsy
)
1727 ? S_GET_TYPE (fixP
->fx_addsy
)
1728 : fixP
->fx_addsy
->sy_number
);
1730 md_number_to_chars (where
,
1731 ((long) (r_symbolnum
)
1732 | (long) (fixP
->fx_pcrel
<< 24)
1733 | (long) (nbytes_r_length
[fixP
->fx_size
] << 25)
1734 | (long) ((!S_IS_DEFINED (fixP
->fx_addsy
)) << 27)
1735 | (long) (fixP
->fx_bsr
<< 28)
1736 | (long) (fixP
->fx_im_disp
<< 29)),
1740 } /* tc_aout_fix_to_chars() */
1742 #endif /* OBJ_AOUT */
1744 /* fast bitfiddling support */
1745 /* mask used to zero bitfield before oring in the true field */
1747 static unsigned long l_mask
[] =
1749 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
1750 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
1751 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
1752 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
1753 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
1754 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
1755 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
1756 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000,
1758 static unsigned long r_mask
[] =
1760 0x00000000, 0x00000001, 0x00000003, 0x00000007,
1761 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
1762 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
1763 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
1764 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
1765 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
1766 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
1767 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
1769 #define MASK_BITS 31
1770 /* Insert bitfield described by field_ptr and val at buf
1771 This routine is written for modification of the first 4 bytes pointed
1772 to by buf, to yield speed.
1773 The ifdef stuff is for selection between a ns32k-dependent routine
1774 and a general version. (My advice: use the general version!)
1778 md_number_to_field (buf
, val
, field_ptr
)
1781 register bit_fixS
*field_ptr
;
1783 register unsigned long object
;
1784 register unsigned long mask
;
1785 /* define ENDIAN on a ns32k machine */
1787 register unsigned long *mem_ptr
;
1789 register char *mem_ptr
;
1791 if (field_ptr
->fx_bit_min
<= val
&& val
<= field_ptr
->fx_bit_max
)
1794 if (field_ptr
->fx_bit_base
)
1795 { /* override buf */
1796 mem_ptr
= (unsigned long *) field_ptr
->fx_bit_base
;
1800 mem_ptr
= (unsigned long *) buf
;
1803 if (field_ptr
->fx_bit_base
)
1804 { /* override buf */
1805 mem_ptr
= (char *) field_ptr
->fx_bit_base
;
1812 mem_ptr
+= field_ptr
->fx_bit_base_adj
;
1813 #ifdef ENDIAN /* we have a nice ns32k machine with lowbyte at low-physical mem */
1814 object
= *mem_ptr
; /* get some bytes */
1815 #else /* OVE Goof! the machine is a m68k or dito */
1816 /* That takes more byte fiddling */
1818 object
|= mem_ptr
[3] & 0xff;
1820 object
|= mem_ptr
[2] & 0xff;
1822 object
|= mem_ptr
[1] & 0xff;
1824 object
|= mem_ptr
[0] & 0xff;
1827 mask
|= (r_mask
[field_ptr
->fx_bit_offset
]);
1828 mask
|= (l_mask
[field_ptr
->fx_bit_offset
+ field_ptr
->fx_bit_size
]);
1830 val
+= field_ptr
->fx_bit_add
;
1831 object
|= ((val
<< field_ptr
->fx_bit_offset
) & (mask
^ 0xffffffff));
1835 mem_ptr
[0] = (char) object
;
1837 mem_ptr
[1] = (char) object
;
1839 mem_ptr
[2] = (char) object
;
1841 mem_ptr
[3] = (char) object
;
1846 as_warn ("Bit field out of range");
1850 /* Apply a fixS (fixup of an instruction or data that we didn't have
1851 enough info to complete immediately) to the data in a frag.
1853 On the ns32k, everything is in a different format, so we have broken
1854 out separate functions for each kind of thing we could be fixing.
1855 They all get called from here. */
1858 md_apply_fix (fixP
, val
)
1862 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
1864 if (fixP
->fx_bit_fixP
)
1865 { /* Bitfields to fix, sigh */
1866 md_number_to_field (buf
, val
, fixP
->fx_bit_fixP
);
1869 switch (fixP
->fx_im_disp
)
1872 case 0: /* Immediate field */
1873 md_number_to_imm (buf
, val
, fixP
->fx_size
);
1876 case 1: /* Displacement field */
1877 md_number_to_disp (buf
,
1878 fixP
->fx_pcrel
? val
+ fixP
->fx_pcrel_adjust
: val
,
1882 case 2: /* Pointer in a data object */
1883 md_number_to_chars (buf
, val
, fixP
->fx_size
);
1888 /* Convert a relaxed displacement to ditto in final output */
1891 md_convert_frag (headers
, fragP
)
1892 object_headers
*headers
;
1893 register fragS
*fragP
;
1898 /* Address in gas core of the place to store the displacement. */
1899 register char *buffer_address
= fragP
->fr_fix
+ fragP
->fr_literal
;
1900 /* Address in object code of the displacement. */
1901 register int object_address
= fragP
->fr_fix
+ fragP
->fr_address
;
1903 know (fragP
->fr_symbol
);
1905 /* The displacement of the address, from current location. */
1906 disp
= (S_GET_VALUE (fragP
->fr_symbol
) + fragP
->fr_offset
) - object_address
;
1907 disp
+= fragP
->fr_pcrel_adjust
;
1909 switch (fragP
->fr_subtype
)
1911 case IND (BRANCH
, BYTE
):
1914 case IND (BRANCH
, WORD
):
1917 case IND (BRANCH
, DOUBLE
):
1923 md_number_to_disp (buffer_address
, (long) disp
, (int) ext
);
1924 fragP
->fr_fix
+= ext
;
1930 /* This function returns the estimated size a variable object will occupy,
1931 one can say that we tries to guess the size of the objects before we
1935 md_estimate_size_before_relax (fragP
, segment
)
1936 register fragS
*fragP
;
1940 old_fix
= fragP
->fr_fix
;
1941 switch (fragP
->fr_subtype
)
1943 case IND (BRANCH
, UNDEF
):
1944 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
)
1946 /* the symbol has been assigned a value */
1947 fragP
->fr_subtype
= IND (BRANCH
, BYTE
);
1951 /* we don't relax symbols defined in an other segment
1952 the thing to do is to assume the object will occupy 4 bytes */
1953 fix_new_ns32k (fragP
,
1954 (int) (fragP
->fr_fix
),
1960 fragP
->fr_pcrel_adjust
,
1963 fragP
->fr_bsr
); /*sequent hack */
1965 /* fragP->fr_opcode[1]=0xff; */
1969 case IND (BRANCH
, BYTE
):
1975 return fragP
->fr_var
+ fragP
->fr_fix
- old_fix
;
1978 int md_short_jump_size
= 3;
1979 int md_long_jump_size
= 5;
1980 int md_reloc_size
= 8; /* Size of relocation record */
1983 md_create_short_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
1985 long from_addr
, to_addr
;
1991 offset
= to_addr
- from_addr
;
1992 md_number_to_chars (ptr
, (long) 0xEA, 1);
1993 md_number_to_disp (ptr
+ 1, (long) offset
, 2);
1997 md_create_long_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
1999 long from_addr
, to_addr
;
2005 offset
= to_addr
- from_addr
;
2006 md_number_to_chars (ptr
, (long) 0xEA, 2);
2007 md_number_to_disp (ptr
+ 2, (long) offset
, 4);
2010 /* JF this is a new function to parse machine-dep options */
2012 md_parse_option (argP
, cntP
, vecP
)
2022 if (!strcmp (*argP
, "32032"))
2024 cpureg
= cpureg_032
;
2025 mmureg
= mmureg_032
;
2027 else if (!strcmp (*argP
, "32532"))
2029 cpureg
= cpureg_532
;
2030 mmureg
= mmureg_532
;
2033 as_warn ("Unknown -m option ignored");
2048 * Create a bit_fixS in obstack 'notes'.
2049 * This struct is used to profile the normal fix. If the bit_fixP is a
2050 * valid pointer (not NULL) the bit_fix data will be used to format the fix.
2053 bit_fix_new (size
, offset
, min
, max
, add
, base_type
, base_adj
)
2054 char size
; /* Length of bitfield */
2055 char offset
; /* Bit offset to bitfield */
2056 long base_type
; /* 0 or 1, if 1 it's exploded to opcode ptr */
2058 long min
; /* Signextended min for bitfield */
2059 long max
; /* Signextended max for bitfield */
2060 long add
; /* Add mask, used for huffman prefix */
2062 register bit_fixS
*bit_fixP
;
2064 bit_fixP
= (bit_fixS
*) obstack_alloc (¬es
, sizeof (bit_fixS
));
2066 bit_fixP
->fx_bit_size
= size
;
2067 bit_fixP
->fx_bit_offset
= offset
;
2068 bit_fixP
->fx_bit_base
= base_type
;
2069 bit_fixP
->fx_bit_base_adj
= base_adj
;
2070 bit_fixP
->fx_bit_max
= max
;
2071 bit_fixP
->fx_bit_min
= min
;
2072 bit_fixP
->fx_bit_add
= add
;
2078 fix_new_ns32k (frag
, where
, size
, add_symbol
, sub_symbol
, offset
, pcrel
,
2079 pcrel_adjust
, im_disp
, bit_fixP
, bsr
)
2080 fragS
*frag
; /* Which frag? */
2081 int where
; /* Where in that frag? */
2082 int size
; /* 1, 2 or 4 usually. */
2083 symbolS
*add_symbol
; /* X_add_symbol. */
2084 symbolS
*sub_symbol
; /* X_subtract_symbol. */
2085 long offset
; /* X_add_number. */
2086 int pcrel
; /* TRUE if PC-relative relocation. */
2087 char pcrel_adjust
; /* not zero if adjustment of pcrel offset is needed */
2088 char im_disp
; /* true if the value to write is a displacement */
2089 bit_fixS
*bit_fixP
; /* pointer at struct of bit_fix's, ignored if NULL */
2090 char bsr
; /* sequent-linker-hack: 1 when relocobject is a bsr */
2093 fixS
*fixP
= fix_new (frag
, where
, size
, add_symbol
, sub_symbol
,
2094 offset
, pcrel
, NO_RELOC
);
2096 fixP
->fx_pcrel_adjust
= pcrel_adjust
;
2097 fixP
->fx_im_disp
= im_disp
;
2098 fixP
->fx_bit_fixP
= bit_fixP
;
2100 } /* fix_new_ns32k() */
2102 /* We have no need to default values of symbols. */
2105 md_undefined_symbol (name
)
2111 /* Parse an operand that is machine-specific.
2112 We just return without modifying the expression if we have nothing
2117 md_operand (expressionP
)
2118 expressionS
*expressionP
;
2122 /* Round up a section size to the appropriate boundary. */
2124 md_section_align (segment
, size
)
2128 return size
; /* Byte alignment is fine */
2131 /* Exactly what point is a PC-relative offset relative TO?
2132 On the National warts, they're relative to the address of the offset,
2133 with some funny adjustments in some circumstances during blue moons.
2134 (??? Is this right? FIXME-SOON) */
2136 md_pcrel_from (fixP
)
2140 res
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2141 #ifdef SEQUENT_COMPATABILITY
2142 if (fixP
->fx_frag
->fr_bsr
)
2143 res
+= 0x12 /* FOO Kludge alert! */
2154 /* end of tc-ns32k.c */