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"
36 #define IIF_ENTRIES 13 /* number of entries in iif */
37 #define PRIVATE_SIZE 256 /* size of my garbage memory */
39 #define DEFAULT -1 /* addr_mode returns this value when plain constant or label is encountered */
41 #define IIF(ptr,a1,c1,e1,g1,i1,k1,m1,o1,q1,s1,u1) \
42 iif.iifP[ptr].type= a1; \
43 iif.iifP[ptr].size= c1; \
44 iif.iifP[ptr].object= e1; \
45 iif.iifP[ptr].object_adjust= g1; \
46 iif.iifP[ptr].pcrel= i1; \
47 iif.iifP[ptr].pcrel_adjust= k1; \
48 iif.iifP[ptr].im_disp= m1; \
49 iif.iifP[ptr].relax_substate= o1; \
50 iif.iifP[ptr].bit_fixP= q1; \
51 iif.iifP[ptr].addr_mode= s1; \
52 iif.iifP[ptr].bsr= u1;
55 #define LINE_COMMENT_CHARS "|"
56 #define ABSOLUTE_PREFIX '@'
57 #define IMMEDIATE_PREFIX '#'
60 #ifndef LINE_COMMENT_CHARS
61 #define LINE_COMMENT_CHARS "#"
64 const char comment_chars[] = "#";
65 const char line_comment_chars[] = LINE_COMMENT_CHARS;
66 #if !defined(ABSOLUTE_PREFIX) && !defined(IMMEDIATE_PREFIX)
67 #define ABSOLUTE_PREFIX '@' /* One or the other MUST be defined */
71 char mode; /* addressing mode of operand (0-31) */
72 char scaled_mode; /* mode combined with scaled mode */
73 char scaled_reg; /* register used in scaled+1 (1-8) */
74 char float_flag; /* set if R0..R7 was F0..F7 ie a floating-point-register */
75 char am_size; /* estimated max size of general addr-mode parts*/
76 char im_disp; /* if im_disp == 1 we have a displacement */
77 char pcrel; /* 1 if pcrel, this is really redundant info */
78 char disp_suffix[2]; /* length of displacement(s), 0=undefined */
79 char *disp[2]; /* pointer(s) at displacement(s)
80 or immediates(s) (ascii) */
81 char index_byte; /* index byte */
83 typedef struct addr_mode addr_modeS;
86 char *freeptr,*freeptr_static; /* points at some number of free bytes */
87 struct hash_control *inst_hash_handle;
89 struct ns32k_opcode *desc; /* pointer at description of instruction */
90 addr_modeS addr_modeP;
91 char EXP_CHARS[] = "eE";
92 char FLT_CHARS[] = "fd"; /* we don't want to support lowercase, do we */
94 /* UPPERCASE denotes live names
95 * when an instruction is built, IIF is used as an intermidiate form to store
96 * the actual parts of the instruction. A ns32k machine instruction can
97 * be divided into a couple of sub PARTs. When an instruction is assembled
98 * the appropriate PART get an assignment. When an IIF has been completed it's
99 * converted to a FRAGment as specified in AS.H */
101 /* internal structs */
109 int type; /* how to interpret object */
110 int size; /* Estimated max size of object */
111 unsigned long object; /* binary data */
112 int object_adjust; /* number added to object */
113 int pcrel; /* True if object is pcrel */
114 int pcrel_adjust; /* length in bytes from the
115 instruction start to the
117 int im_disp; /* True if the object is a displacement */
118 relax_substateT relax_substate; /* Initial relaxsubstate */
119 bit_fixS *bit_fixP; /* Pointer at bit_fix struct */
120 int addr_mode; /* What addrmode do we associate with this iif-entry */
121 char bsr; /* Sequent hack */
122 }iif_entryT; /* Internal Instruction Format */
124 struct int_ins_form {
125 int instr_size; /* Max size of instruction in bytes. */
126 iif_entryT iifP[IIF_ENTRIES + 1];
128 struct int_ins_form iif;
130 char *input_line_pointer;
131 /* description of the PARTs in IIF
133 * 0 total length in bytes of entries in iif
146 * For every entry there is a datalength in bytes. This is stored in size[n].
147 * 0, the objectlength is not explicitly given by the instruction
148 * and the operand is undefined. This is a case for relaxation.
149 * Reserve 4 bytes for the final object.
151 * 1, the entry contains one byte
152 * 2, the entry contains two bytes
153 * 3, the entry contains three bytes
154 * 4, the entry contains four bytes
157 * Furthermore, every entry has a data type identifier in type[n].
159 * 0, the entry is void, ignore it.
160 * 1, the entry is a binary number.
161 * 2, the entry is a pointer at an expression.
162 * Where expression may be as simple as a single '1',
163 * and as complicated as foo-bar+12,
164 * foo and bar may be undefined but suffixed by :{b|w|d} to
165 * control the length of the object.
167 * 3, the entry is a pointer at a bignum struct
170 * The low-order-byte coresponds to low physical memory.
171 * Obviously a FRAGment must be created for each valid disp in PART whose
172 * datalength is undefined (to bad) .
173 * The case where just the expression is undefined is less severe and is
174 * handled by fix. Here the number of bytes in the objectfile is known.
175 * With this representation we simplify the assembly and separates the
176 * machine dependent/independent parts in a more clean way (said OE)
179 struct option opt1[]= /* restore, exit */
181 { "r0", 0x80, 0xff },
182 { "r1", 0x40, 0xff },
183 { "r2", 0x20, 0xff },
184 { "r3", 0x10, 0xff },
185 { "r4", 0x08, 0xff },
186 { "r5", 0x04, 0xff },
187 { "r6", 0x02, 0xff },
188 { "r7", 0x01, 0xff },
191 struct option opt2[]= /* save, enter */
193 { "r0", 0x01, 0xff },
194 { "r1", 0x02, 0xff },
195 { "r2", 0x04, 0xff },
196 { "r3", 0x08, 0xff },
197 { "r4", 0x10, 0xff },
198 { "r5", 0x20, 0xff },
199 { "r6", 0x40, 0xff },
200 { "r7", 0x80, 0xff },
203 struct option opt3[]= /* setcfg */
211 struct option opt4[]= /* cinv */
218 struct option opt5[]= /* string inst */
225 struct option opt6[]= /* plain reg ext,cvtp etc */
227 { "r0", 0x00, 0xff },
228 { "r1", 0x01, 0xff },
229 { "r2", 0x02, 0xff },
230 { "r3", 0x03, 0xff },
231 { "r4", 0x04, 0xff },
232 { "r5", 0x05, 0xff },
233 { "r6", 0x06, 0xff },
234 { "r7", 0x07, 0xff },
238 #if !defined(NS32032) && !defined(NS32532)
242 struct option cpureg_532[]= /* lpr spr */
245 { "dcr", 0x1, 0xff },
246 { "bpc", 0x2, 0xff },
247 { "dsr", 0x3, 0xff },
248 { "car", 0x4, 0xff },
252 { "usp", 0xb, 0xff },
253 { "cfg", 0xc, 0xff },
254 { "psr", 0xd, 0xff },
255 { "intbase", 0xe, 0xff },
256 { "mod", 0xf, 0xff },
259 struct option mmureg_532[]= /* lmr smr */
261 { "mcr", 0x9, 0xff },
262 { "msr", 0xa, 0xff },
263 { "tear", 0xb, 0xff },
264 { "ptb0", 0xc, 0xff },
265 { "ptb1", 0xd, 0xff },
266 { "ivar0", 0xe, 0xff },
267 { "ivar1", 0xf, 0xff },
271 struct option cpureg_032[]= /* lpr spr */
273 { "upsr", 0x0, 0xff },
277 { "psr", 0xd, 0xff },
278 { "intbase", 0xe, 0xff },
279 { "mod", 0xf, 0xff },
282 struct option mmureg_032[]= /* lmr smr */
284 { "bpr0", 0x0, 0xff },
285 { "bpr1", 0x1, 0xff },
286 { "pf0", 0x4, 0xff },
287 { "pf1", 0x5, 0xff },
289 { "msr", 0xa, 0xff },
290 { "bcnt", 0xb, 0xff },
291 { "ptb0", 0xc, 0xff },
292 { "ptb1", 0xd, 0xff },
293 { "eia", 0xf, 0xff },
298 struct option *cpureg = cpureg_532;
299 struct option *mmureg = mmureg_532;
301 struct option *cpureg = cpureg_032;
302 struct option *mmureg = mmureg_032;
306 const pseudo_typeS md_pseudo_table[]={ /* so far empty */
310 #define IND(x,y) (((x)<<2)+(y))
312 /* those are index's to relax groups in md_relax_table
313 ie it must be multiplied by 4 to point at a group start. Viz IND(x,y)
314 Se function relax_segment in write.c for more info */
319 /* those are index's to entries in a relax group */
325 /* Those limits are calculated from the displacement start in memory.
326 The ns32k uses the begining of the instruction as displacement base.
327 This type of displacements could be handled here by moving the limit window
328 up or down. I choose to use an internal displacement base-adjust as there
329 are other routines that must consider this. Also, as we have two various
330 offset-adjusts in the ns32k (acb versus br/brs/jsr/bcond), two set of limits
331 would have had to be used.
332 Now we dont have to think about that. */
335 const relax_typeS md_relax_table[] = {
341 { (63), (-64), 1, IND(BRANCH,WORD) },
342 { (8191), (-8192), 2, IND(BRANCH,DOUBLE) },
347 /* Array used to test if mode contains displacements.
348 Value is true if mode contains displacement. */
350 char disp_test[] = { 0,0,0,0,0,0,0,0,
355 /* Array used to calculate max size of displacements */
357 char disp_size[] = { 4,1,2,0,4 };
360 /* In pic-mode all external pc-relative references are jmpslot
361 references except references to __GLOBAL_OFFSET_TABLE_. */
362 static symbolS *got_symbol;
364 /* The size of got-offsets. */
365 static int got_offset_size = 2;
372 static segT evaluate_expr(expressionS *resultP, char *ptr);
373 static void md_number_to_disp(char *buf, long val, int n);
374 static void md_number_to_imm(char *buf, long val, int n);
376 #else /* not __STDC__ */
378 static segT evaluate_expr();
379 static void md_number_to_disp();
380 static void md_number_to_imm();
382 #endif /* not __STDC__ */
384 /* Parses a general operand into an addressingmode struct
386 in: pointer at operand in ascii form
387 pointer at addr_mode struct for result
388 the level of recursion. (always 0 or 1)
390 out: data in addr_mode struct
392 int addr_mode(operand,addr_modeP,recursive_level)
394 register addr_modeS *addr_modeP;
402 mode = DEFAULT; /* default */
403 addr_modeP->scaled_mode=0; /* why not */
404 addr_modeP->scaled_reg=0; /* if 0, not scaled index */
405 addr_modeP->float_flag=0;
406 addr_modeP->am_size=0;
407 addr_modeP->im_disp=0;
408 addr_modeP->pcrel=0; /* not set in this function */
409 addr_modeP->disp_suffix[0]=0;
410 addr_modeP->disp_suffix[1]=0;
411 addr_modeP->disp[0]=NULL;
412 addr_modeP->disp[1]=NULL;
414 if (str[0] == 0) {return (0);} /* we don't want this */
417 /* the following three case statements controls the mode-chars
418 this is the place to ed if you want to change them */
419 #ifdef ABSOLUTE_PREFIX
420 case ABSOLUTE_PREFIX:
421 if (str[strl-1] == ']') break;
422 addr_modeP->mode=21; /* absolute */
423 addr_modeP->disp[0]=str+1;
426 #ifdef IMMEDIATE_PREFIX
427 case IMMEDIATE_PREFIX:
428 if (str[strl-1] == ']') break;
429 addr_modeP->mode=20; /* immediate */
430 addr_modeP->disp[0]=str+1;
434 if (str[strl-1] != ']') {
437 if (str[2] != '\000') {
438 addr_modeP->mode=27; /* pc-relativ */
439 addr_modeP->disp[0]=str+2;
443 as_warn("Invalid syntax in PC-relative addressing mode");
449 if (str[strl-1] != ']') {
450 if ((!strncmp(str,"ext(",4)) && strl>7) { /* external */
451 addr_modeP->disp[0]=str+4;
454 do { /* disp[0]'s termination point */
456 if (str[j] == '(') i++;
457 if (str[j] == ')') i--;
458 } while (j < strl && i != 0);
459 if (i != 0 || !(str[j+1] == '-' || str[j+1] == '+') ) {
460 as_warn("Invalid syntax in External addressing mode");
463 str[j]='\000'; /* null terminate disp[0] */
464 addr_modeP->disp[1]=str+j+2;
476 case'f':addr_modeP->float_flag=1;
478 if (str[1] >= '0' && str[1] < '8') {
479 addr_modeP->mode=str[1]-'0';
484 if (!strncmp(str,"tos",3)) {
485 addr_modeP->mode=23; /* TopOfStack */
491 if (str[strl - 1] == ')') {
492 if (str[strl - 2] == ')') {
493 if (!strncmp(&str[strl-5],"(fp",3)) {
494 mode=16; /* Memory Relative */
496 if (!strncmp(&str[strl-5],"(sp",3)) {
499 if (!strncmp(&str[strl-5],"(sb",3)) {
502 if (mode != DEFAULT) { /* memory relative */
503 addr_modeP->mode=mode;
504 j=strl-5; /* temp for end of disp[0] */
508 if (str[strl] == ')') i++;
509 if (str[strl] == '(') i--;
510 } while (strl>-1 && i != 0);
512 as_warn("Invalid syntax in Memory Relative addressing mode");
515 addr_modeP->disp[1]=str;
516 addr_modeP->disp[0]=str+strl+1;
517 str[j]='\000'; /* null terminate disp[0] */
518 str[strl]='\000'; /* null terminate disp[1] */
522 switch (str[strl-3]) {
524 if (str[strl - 2] >= '0' && str[strl - 2] < '8' && str[strl - 4] == '(') {
525 addr_modeP->mode=str[strl-2]-'0'+8;
526 addr_modeP->disp[0]=str;
528 return (-1); /* reg rel */
531 if (!strncmp(&str[strl-4],"(fp",3)) {
534 if (!strncmp(&str[strl-4],"(sp",3)) {
537 if (!strncmp(&str[strl-4],"(sb",3)) {
540 if (!strncmp(&str[strl-4],"(pc",3)) {
543 if (mode != DEFAULT) {
544 addr_modeP->mode=mode;
545 addr_modeP->disp[0]=str;
547 return (-1); /* memory space */
551 /* no trailing ')' do we have a ']' ? */
552 if (str[strl - 1] == ']') {
553 switch (str[strl-2]) {
554 case'b':mode=28;break;
555 case'w':mode=29;break;
556 case'd':mode=30;break;
557 case'q':mode=31;break;
559 as_warn("Invalid scaled-indexed mode, use (b,w,d,q)");
560 if (str[strl - 3] != ':' || str[strl - 6] != '[' ||
561 str[strl - 5] == 'r' || str[strl - 4] < '0' || str[strl - 4] > '7') {
562 as_warn("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}");
566 if (recursive_level>0) {
567 as_warn("Scaled-indexed addressing mode combined with scaled-index");
570 addr_modeP->am_size+=1; /* scaled index byte */
571 j=str[strl-4]-'0'; /* store temporary */
572 str[strl-6]='\000'; /* nullterminate for recursive call */
573 i=addr_mode(str,addr_modeP,1);
574 if (!i || addr_modeP->mode == 20) {
575 as_warn("Invalid or illegal addressing mode combined with scaled-index");
578 addr_modeP->scaled_mode=addr_modeP->mode; /* store the inferior mode */
579 addr_modeP->mode=mode;
580 addr_modeP->scaled_reg=j+1;
585 addr_modeP->mode = DEFAULT; /* default to whatever */
586 addr_modeP->disp[0]=str;
590 /* ptr points at string
591 addr_modeP points at struct with result
592 This routine calls addr_mode to determine the general addr.mode of
593 the operand. When this is ready it parses the displacements for size
594 specifying suffixes and determines size of immediate mode via ns32k-opcode.
595 Also builds index bytes if needed.
597 int get_addr_mode(ptr,addr_modeP)
599 addr_modeS *addr_modeP;
602 addr_mode(ptr,addr_modeP,0);
603 if (addr_modeP->mode == DEFAULT || addr_modeP->scaled_mode == -1) {
604 /* resolve ambigious operands, this shouldn't
605 be necessary if one uses standard NSC operand
606 syntax. But the sequent compiler doesn't!!!
607 This finds a proper addressinging mode if it
608 is implicitly stated. See ns32k-opcode.h */
609 (void)evaluate_expr(&exprP,ptr); /* this call takes time Sigh! */
610 if (addr_modeP->mode == DEFAULT) {
611 if (exprP.X_add_symbol || exprP.X_subtract_symbol) {
612 addr_modeP->mode=desc->default_model; /* we have a label */
614 addr_modeP->mode=desc->default_modec; /* we have a constant */
617 if (exprP.X_add_symbol || exprP.X_subtract_symbol) {
618 addr_modeP->scaled_mode=desc->default_model;
620 addr_modeP->scaled_mode=desc->default_modec;
623 /* must put this mess down in addr_mode to handle the scaled case better */
625 /* It appears as the sequent compiler wants an absolute when we have a
626 label without @. Constants becomes immediates besides the addr case.
627 Think it does so with local labels too, not optimum, pcrel is better.
628 When I have time I will make gas check this and select pcrel when possible
629 Actually that is trivial.
631 if (tmp=addr_modeP->scaled_reg) { /* build indexbyte */
632 tmp--; /* remember regnumber comes incremented for flagpurpose */
633 tmp|=addr_modeP->scaled_mode<<3;
634 addr_modeP->index_byte=(char)tmp;
635 addr_modeP->am_size+=1;
637 if (disp_test[addr_modeP->mode]) { /* there was a displacement, probe for length specifying suffix*/
640 register char suffix;
641 register char suffix_sub;
644 register char *fromP;
647 if (disp_test[addr_modeP->mode]) { /* there is a displacement */
648 if (addr_modeP->mode == 27 || addr_modeP->scaled_mode == 27) { /* do we have pcrel. mode */
651 addr_modeP->im_disp=1;
654 if (toP=addr_modeP->disp[i]) { /* suffix of expression, the largest size rules */
656 while (c = *fromP++) {
661 as_warn("Premature end of suffix--Defaulting to d");
664 case 'b':suffix_sub=1;break;
665 case 'w':suffix_sub=2;break;
666 case 'd':suffix_sub=4;break;
668 as_warn("Bad suffix after ':' use {b|w|d} Defaulting to d");
672 toP--; /* So we write over the ':' */
673 if (suffix<suffix_sub) suffix=suffix_sub;
676 *toP='\0'; /* terminate properly */
677 addr_modeP->disp_suffix[i]=suffix;
678 addr_modeP->am_size+=suffix ? suffix : 4;
684 if (addr_modeP->mode == 20) { /* look in ns32k_opcode for size */
685 addr_modeP->disp_suffix[0]=addr_modeP->am_size=desc->im_size;
686 addr_modeP->im_disp=0;
689 return addr_modeP->mode;
693 /* read an optionlist */
694 void optlist(str,optionP,default_map)
695 char *str; /* the string to extract options from */
696 struct option *optionP; /* how to search the string */
697 unsigned long *default_map; /* default pattern and output */
699 register int i,j,k,strlen1,strlen2;
700 register char *patternP,*strP;
703 as_fatal("Very short instr to option, ie you can't do it on a NULLstr");
705 for (i = 0; optionP[i].pattern != 0; i++) {
706 strlen2=strlen(optionP[i].pattern);
707 for (j=0;j<strlen1;j++) {
708 patternP=optionP[i].pattern;
710 for (k=0;k<strlen2;k++) {
711 if (*(strP++) != *(patternP++)) break;
713 if (k == strlen2) { /* match */
714 *default_map|=optionP[i].or;
715 *default_map&=optionP[i].and;
720 /* search struct for symbols
721 This function is used to get the short integer form of reg names
722 in the instructions lmr, smr, lpr, spr
723 return true if str is found in list */
725 int list_search(str,optionP,default_map)
726 char *str; /* the string to match */
727 struct option *optionP; /* list to search */
728 unsigned long *default_map; /* default pattern and output */
731 for (i = 0; optionP[i].pattern != 0; i++) {
732 if (!strncmp(optionP[i].pattern,str,20)) { /* use strncmp to be safe */
733 *default_map|=optionP[i].or;
734 *default_map&=optionP[i].and;
738 as_warn("No such entry in list. (cpu/mmu register)");
741 static segT evaluate_expr(resultP,ptr)
742 expressionS *resultP;
745 register char *tmp_line;
746 register segT segment;
747 tmp_line = input_line_pointer;
748 input_line_pointer = ptr;
749 segment = expression(&exprP);
750 input_line_pointer = tmp_line;
754 /* Convert operands to iif-format and adds bitfields to the opcode.
755 Operands are parsed in such an order that the opcode is updated from
756 its most significant bit, that is when the operand need to alter the
758 Be carefull not to put to objects in the same iif-slot.
761 void encode_operand(argc,argv,operandsP,suffixP,im_size,opcode_bit_ptr)
770 int pcrel,tmp,b,loop,pcrel_adjust;
771 for (loop=0;loop<argc;loop++) {
772 i=operandsP[loop<<1]-'1'; /* what operand are we supposed to work on */
773 if (i>3) as_fatal("Internal consistency error. check ns32k-opcode.h");
777 switch (operandsP[(loop<<1)+1]) {
778 case 'f': /* operand of sfsr turns out to be a nasty specialcase */
780 case 'F': /* 32 bit float general form */
781 case 'L': /* 64 bit float */
782 case 'Q': /* quad-word */
785 case 'D': /* double-word */
786 case 'A': /* double-word gen-address-form ie no regs allowed */
787 get_addr_mode(argv[i],&addr_modeP);
788 iif.instr_size+=addr_modeP.am_size;
789 if (opcode_bit_ptr == desc->opcode_size) b = 4; else b = 6;
790 for (j=b;j<(b+2);j++) {
791 if (addr_modeP.disp[j-b]) {
794 addr_modeP.disp_suffix[j-b],
795 (unsigned long)addr_modeP.disp[j-b],
798 iif.instr_size-addr_modeP.am_size, /* this aint used (now) */
802 addr_modeP.scaled_reg ? addr_modeP.scaled_mode:addr_modeP.mode,
807 iif.iifP[1].object|=((long)addr_modeP.mode)<<opcode_bit_ptr;
808 if (addr_modeP.scaled_reg) {
810 IIF(j,1,1, (unsigned long)addr_modeP.index_byte,0,0,0,0,0, NULL,-1,0);
813 case 'b': /* multiple instruction disp */
814 freeptr++; /* OVE:this is an useful hack */
815 tmp = (int) sprintf(freeptr,
817 argv[i], desc->im_size);
820 pcrel-=1; /* make pcrel 0 inspite of what case 'p': wants */
822 case 'p': /* displacement - pc relative addressing */
825 case 'd': /* displacement */
826 iif.instr_size+=suffixP[i] ? suffixP[i] : 4;
827 IIF(12, 2, suffixP[i], (unsigned long)argv[i], 0,
828 pcrel, pcrel_adjust, 1, IND(BRANCH,BYTE), NULL,-1,0);
830 case 'H': /* sequent-hack: the linker wants a bit set when bsr */
832 iif.instr_size+=suffixP[i] ? suffixP[i] : 4;
833 IIF(12, 2, suffixP[i], (unsigned long)argv[i], 0,
834 pcrel, pcrel_adjust, 1, IND(BRANCH,BYTE), NULL,-1, 1);
836 case 'q': /* quick */
838 IIF(11,2,42,(unsigned long)argv[i],0,0,0,0,0,
839 bit_fix_new(4,opcode_bit_ptr,-8,7,0,1,0),-1,0);
841 case 'r': /* register number (3 bits) */
842 list_search(argv[i],opt6,&tmp);
844 iif.iifP[1].object|=tmp<<opcode_bit_ptr;
846 case 'O': /* setcfg instruction optionslist */
847 optlist(argv[i],opt3,&tmp);
849 iif.iifP[1].object|=tmp<<15;
851 case 'C': /* cinv instruction optionslist */
852 optlist(argv[i],opt4,&tmp);
854 iif.iifP[1].object|=tmp<<15;/*insert the regtype in opcode */
856 case 'S': /* stringinstruction optionslist */
857 optlist(argv[i],opt5,&tmp);
859 iif.iifP[1].object|=tmp<<15;
861 case 'u':case 'U': /* registerlist */
862 IIF(10,1,1,0,0,0,0,0,0,NULL,-1,0);
863 switch (operandsP[(i<<1)+1]) {
864 case 'u': /* restore, exit */
865 optlist(argv[i],opt1,&iif.iifP[10].object);
867 case 'U': /* save,enter */
868 optlist(argv[i],opt2,&iif.iifP[10].object);
873 case 'M': /* mmu register */
874 list_search(argv[i],mmureg,&tmp);
876 iif.iifP[1].object|=tmp<<opcode_bit_ptr;
878 case 'P': /* cpu register */
879 list_search(argv[i],cpureg,&tmp);
881 iif.iifP[1].object|=tmp<<opcode_bit_ptr;
883 case 'g': /* inss exts */
884 iif.instr_size+=1; /* 1 byte is allocated after the opcode */
886 (unsigned long)argv[i], /* i always 2 here */
888 bit_fix_new(3,5,0,7,0,0,0), /* a bit_fix is targeted to the byte */
892 (unsigned long)argv[i], /* i always 3 here */
894 bit_fix_new(5,0,1,32,-1,0,-1),-1,0);
898 b=2+i; /* put the extension byte after opcode */
899 IIF(b,2,1,0,0,0,0,0,0,0,-1,0);
901 as_fatal("Bad opcode-table-option, check in file ns32k-opcode.h");
906 /* in: instruction line
907 out: internal structure of instruction
908 that has been prepared for direct conversion to fragment(s) and
909 fixes in a systematical fashion
910 Return-value = recursive_level
912 /* build iif of one assembly text line */
913 int parse(line,recursive_level)
917 register char *lineptr,c,suffix_separator;
921 char suffix[MAX_ARGS],*argv[MAX_ARGS];/* no more than 4 operands */
922 if (recursive_level <= 0) { /* called from md_assemble */
923 for (lineptr=line; (*lineptr) != '\0' && (*lineptr) != ' '; lineptr++);
926 desc = (struct ns32k_opcode*) hash_find(inst_hash_handle,line);
928 as_fatal("No such opcode");
935 if (*desc->operands != NULL) {
936 if (*lineptr++ != '\0') {
939 while (*lineptr != '\0') {
940 if (desc->operands[argc << 1]) {
943 desc->operands[(argc << 1) + 1];
948 case 'H': /* the operand is supposed to be a displacement */
949 /* Hackwarning: do not forget to update the 4 cases above when editing ns32k-opcode.h */
950 suffix_separator = ':';
953 suffix_separator = '\255'; /* if this char occurs we loose */
955 suffix[argc] = 0; /* 0 when no ':' is encountered */
956 argv[argc] = freeptr;
958 while ((c = *lineptr) != '\0' && c != sep) {
968 if (c == suffix_separator) { /* ':' - label/suffix separator */
969 switch (lineptr[1]) {
970 case 'b': suffix[argc] = 1; break;
971 case 'w': suffix[argc] = 2; break;
972 case 'd': suffix[argc] = 4; break;
973 default: as_warn("Bad suffix, defaulting to d");
975 if (lineptr[1] == '\0' || lineptr[1] == sep) {
988 if (*lineptr == '\0') continue;
991 as_fatal("Too many operands passed to instruction");
996 if (argc != strlen(desc->operands) / 2) {
997 if (strlen(desc->default_args) != 0) { /* we can apply default, dont goof */
998 if (parse(desc->default_args,1) != 1) { /* check error in default */
999 as_fatal("Wrong numbers of operands in default, check ns32k-opcodes.h");
1002 as_fatal("Wrong number of operands");
1006 for (i = 0; i < IIF_ENTRIES; i++) {
1007 iif.iifP[i].type = 0; /* mark all entries as void*/
1010 /* build opcode iif-entry */
1011 iif.instr_size = desc->opcode_size / 8;
1012 IIF(1,1,iif.instr_size,desc->opcode_seed,0,0,0,0,0,0,-1,0);
1014 /* this call encodes operands to iif format */
1016 encode_operand(argc,
1023 return(recursive_level);
1027 /* Convert iif to fragments.
1028 From this point we start to dribble with functions in other files than
1029 this one.(Except hash.c) So, if it's possible to make an iif for an other
1030 CPU, you don't need to know what frags, relax, obstacks, etc is in order
1031 to port this assembler. You only need to know if it's possible to reduce
1032 your cpu-instruction to iif-format (takes some work) and adopt the other
1033 md_? parts according to given instructions
1034 Note that iif was invented for the clean ns32k`s architecure.
1036 void convert_iif() {
1046 int rem_size; /* count the remaining bytes of instruction */
1049 int size_so_far = 0; /* used to calculate pcrel_adjust */
1050 int pcrel_symbols = 0;/* kludge by jkp@hut.fi to make
1051 movd _foo(pc),_bar(pc) work.
1052 It should be done with two frags
1053 for one insn, but I don't understand
1054 enough to make it work */
1056 rem_size = iif.instr_size;
1057 memP = frag_more(iif.instr_size); /* make sure we have enough bytes for instruction */
1059 inst_offset = (char *)(memP-frag_now->fr_literal);
1060 inst_frag = frag_now;
1061 for (i=0; i < IIF_ENTRIES; i++) { /* jkp kludge alert */
1062 if (iif.iifP[i].type && iif.iifP[i].size == 0 &&
1063 iif.iifP[i].pcrel) {
1064 evaluate_expr(&exprP, (char *)iif.iifP[i].object);
1065 if (exprP.X_add_symbol || exprP.X_subtract_symbol)
1069 for (i=0;i<IIF_ENTRIES;i++) {
1070 if (type=iif.iifP[i].type) { /* the object exist, so handle it */
1073 if ((i == 4 || i == 6)
1075 && (iif.iifP[i].addr_mode == 18 || iif.iifP[i].addr_mode == 26))
1076 reloc_mode = RELOC_GLOB_DAT;
1078 reloc_mode = NO_RELOC;
1080 int reloc_mode = NO_RELOC;
1082 switch (size=iif.iifP[i].size) {
1083 case 42: size=0; /* it's a bitfix that operates on an existing object*/
1084 if (iif.iifP[i].bit_fixP->fx_bit_base) { /* expand fx_bit_base to point at opcode */
1085 iif.iifP[i].bit_fixP->fx_bit_base = (long) inst_opcode;
1087 case 8: /* bignum or doublefloat */
1088 memset(memP, '\0', 8);
1089 case 1:case 2:case 3:case 4:/* the final size in objectmemory is known */
1090 bit_fixP = iif.iifP[i].bit_fixP;
1092 case 1: /* the object is pure binary */
1093 if (bit_fixP || iif.iifP[i].pcrel) {
1094 fix_new_ns32k(frag_now,
1095 (long)(memP-frag_now->fr_literal),
1101 (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/
1102 iif.iifP[i].im_disp,
1104 iif.iifP[i].bsr, /* sequent hack */
1106 } else { /* good, just put them bytes out */
1107 switch (iif.iifP[i].im_disp) {
1109 md_number_to_chars(memP,iif.iifP[i].object,size);break;
1111 md_number_to_disp(memP,iif.iifP[i].object,size);break;
1112 default: as_fatal("iif convert internal pcrel/binary");
1118 case 2: /* the object is a pointer at an expression, so unpack
1119 it, note that bignums may result from the expression
1121 if ((segment = evaluate_expr(&exprP, (char*)iif.iifP[i].object)) == SEG_BIG || size == 8) {
1122 if ((k=exprP.X_add_number)>0) { /* we have a bignum ie a quad */
1123 /* this can only happens in a long suffixed instruction */
1124 memset(memP, '\0', size); /* size normally is 8 */
1125 if (k*2>size) as_warn("Bignum too big for long");
1126 if (k == 3) memP += 2;
1127 for (l=0;k>0;k--,l+=2) {
1128 md_number_to_chars(memP+l,generic_bignum[l>>1],sizeof(LITTLENUM_TYPE));
1130 } else { /* flonum */
1131 LITTLENUM_TYPE words[4];
1135 gen_to_words(words,2,8);
1136 md_number_to_imm(memP ,(long)words[0],sizeof(LITTLENUM_TYPE));
1137 md_number_to_imm(memP+sizeof(LITTLENUM_TYPE),(long)words[1],sizeof(LITTLENUM_TYPE));
1140 gen_to_words(words,4,11);
1141 md_number_to_imm(memP ,(long)words[0],sizeof(LITTLENUM_TYPE));
1142 md_number_to_imm(memP+sizeof(LITTLENUM_TYPE) ,(long)words[1],sizeof(LITTLENUM_TYPE));
1143 md_number_to_imm(memP+2*sizeof(LITTLENUM_TYPE),(long)words[2],sizeof(LITTLENUM_TYPE));
1144 md_number_to_imm(memP+3*sizeof(LITTLENUM_TYPE),(long)words[3],sizeof(LITTLENUM_TYPE));
1153 exprP.X_add_symbol ||
1154 exprP.X_subtract_symbol ||
1155 iif.iifP[i].pcrel) { /* fixit */
1156 /* the expression was undefined due to an undefined label */
1157 /* create a fix so we can fix the object later */
1158 exprP.X_add_number+=iif.iifP[i].object_adjust;
1159 fix_new_ns32k(frag_now,
1160 (long)(memP-frag_now->fr_literal),
1163 exprP.X_subtract_symbol,
1166 (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/
1167 iif.iifP[i].im_disp,
1169 iif.iifP[i].bsr, /* sequent hack */
1172 } else { /* good, just put them bytes out */
1173 switch (iif.iifP[i].im_disp) {
1175 md_number_to_imm(memP,exprP.X_add_number,size);break;
1177 md_number_to_disp(memP,exprP.X_add_number,size);break;
1178 default: as_fatal("iif convert internal pcrel/pointer");
1184 default: as_fatal("Internal logic error in iif.iifP[n].type");
1187 case 0: /* To bad, the object may be undefined as far as its final
1188 nsize in object memory is concerned. The size of the object
1189 in objectmemory is not explicitly given.
1190 If the object is defined its length can be determined and
1191 a fix can replace the frag.
1195 segment = evaluate_expr(&exprP, (char*)iif.iifP[i].object);
1196 if (((exprP.X_add_symbol || exprP.X_subtract_symbol) &&
1197 !iif.iifP[i].pcrel) || pcrel_symbols >= 2 /*jkp*/) { /* OVE: hack, clamp to 4 bytes */
1199 if (reloc_mode == RELOC_GLOB_DAT && got_offset_size == 2) {
1201 /* rewind the bytes not used */
1202 obstack_blank_fast(&frags, -2);
1205 size=4; /* we dont wan't to frag this, use 4 so it reaches */
1206 fix_new_ns32k(frag_now,
1207 (long)(memP-frag_now->fr_literal),
1210 exprP.X_subtract_symbol,
1212 pcrel_symbols >= 2 ? iif.iifP[i].pcrel : 0, /*jkp*//* never iif.iifP[i].pcrel, */
1213 (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/
1214 1, /* always iif.iifP[i].im_disp, */
1219 break; /* exit this absolute hack */
1222 if (exprP.X_add_symbol || exprP.X_subtract_symbol) { /* frag it */
1223 if (exprP.X_subtract_symbol) { /* We cant relax this case */
1224 as_fatal("Can't relax difference");
1226 /* at this stage we must undo some of the effect caused
1227 by frag_more, ie we must make sure that frag_var causes
1228 frag_new to creat a valid fix-size in the frag it`s closing
1230 temp = -(rem_size-4);
1231 obstack_blank_fast(&frags,temp);
1232 /* we rewind none, some or all of the requested size we
1233 requested by the first frag_more for this iif chunk.
1234 Note: that we allocate 4 bytes to an object we NOT YET
1235 know the size of, thus rem_size-4.
1237 (void) frag_variant(rs_machine_dependent,
1240 IND(BRANCH,UNDEF), /* expecting the worst */
1244 (char)size_so_far, /*iif.iifP[i].pcrel_adjust);*/
1245 iif.iifP[i].bsr); /* sequent linker hack */
1248 memP = frag_more(rem_size);
1251 } else {/* Double work, this is done in md_number_to_disp */
1252 /* exprP.X_add_number; fixme-soon what was this supposed to be? xoxorich. */
1253 if (-64 <= exprP.X_add_number && exprP.X_add_number <= 63) {
1256 if (-8192 <= exprP.X_add_number && exprP.X_add_number <= 8191) {
1259 /* Dave Taylor <taylor@think.com> says: Note: The reason the lower
1260 limit is -0x1f000000 and not -0x20000000 is that, according to
1261 Nat'l Semi's data sheet on the ns32532, ``the pattern 11100000
1262 for the most significant byte of the displacement is reserved by
1263 National for future enhancements''. */
1264 } else if (/* -0x40000000 <= exprP.X_add_number &&
1265 exprP.X_add_number <= 0x3fffffff */
1266 -0x1f000000 <= exprP.X_add_number &&
1267 exprP.X_add_number <= 0x1fffffff) {
1270 as_warn("Displacement too large for :d");
1274 /* rewind the bytes not used */
1276 md_number_to_disp(memP,exprP.X_add_number,size);
1277 obstack_blank_fast(&frags,temp);
1279 rem_size -= 4; /* we allocated this amount */
1284 as_fatal("Internal logic error in iif.iifP[].type");
1286 size_so_far += size;
1292 void md_assemble(line)
1295 freeptr=freeptr_static;
1296 parse(line,0); /* explode line to more fix form in iif */
1297 convert_iif(); /* convert iif to frags, fix's etc */
1299 printf(" \t\t\t%s\n",line);
1305 /* build a hashtable of the instructions */
1306 register const struct ns32k_opcode *ptr;
1307 register char *stat;
1308 inst_hash_handle=hash_new();
1309 for (ptr=ns32k_opcodes;ptr<endop;ptr++) {
1310 if (*(stat=hash_insert(inst_hash_handle,ptr->name,(char*)ptr))) {
1311 as_fatal("Can't hash %s: %s", ptr->name,stat); /*fatal*/
1315 freeptr_static=(char*)malloc(PRIVATE_SIZE); /* some private space please! */
1321 free(freeptr_static);
1324 /* Must be equal to MAX_PRECISON in atof-ieee.c */
1325 #define MAX_LITTLENUMS 6
1327 /* Turn the string pointed to by litP into a floating point constant of type
1328 type, and emit the appropriate bytes. The number of LITTLENUMS emitted
1329 is stored in *sizeP. An error message is returned, or NULL on OK.
1332 md_atof(type,litP,sizeP)
1338 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1339 LITTLENUM_TYPE *wordP;
1340 extern char *atof_ieee();
1353 return "Bad call to MD_ATOF()";
1355 t = atof_ieee(input_line_pointer, type, words);
1357 input_line_pointer=t;
1359 *sizeP = prec * sizeof(LITTLENUM_TYPE);
1360 for (wordP = words +prec; prec--;) {
1361 md_number_to_chars(litP, (long)(*--wordP), sizeof(LITTLENUM_TYPE));
1362 litP+=sizeof(LITTLENUM_TYPE);
1364 return ""; /* Someone should teach Dean about null pointers */
1367 /* Convert number to chars in correct order */
1370 md_number_to_chars(buf, value, nbytes)
1377 printf("%x ",value & 0xff);
1379 *buf++ = value; /* Lint wants & MASK_CHAR. */
1380 value >>= BITS_PER_CHAR;
1382 } /* md_number_to_chars() */
1385 /* This is a variant of md_numbers_to_chars. The reason for its' existence
1386 is the fact that ns32k uses Huffman coded displacements. This implies
1387 that the bit order is reversed in displacements and that they are prefixed
1392 10xxxxxx xxxxxxxx word
1393 11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx double word
1395 This must be taken care of and we do it here!
1397 static void md_number_to_disp(buf, val, n)
1404 if (val < -64 || val > 63)
1406 fprintf(stderr, "val = %d\n", val);
1407 as_warn("Byte displacement out of range. line number not valid");
1411 printf("%x ",val & 0xff);
1416 if (val < -8192 || val > 8191)
1417 as_warn("Word displacement out of range. line number not valid");
1421 printf("%x ",val>>8 & 0xff);
1425 printf("%x ",val & 0xff);
1431 /* Dave Taylor <taylor@think.com> says: Note: The reason the
1432 lower limit is -0x1f000000 and not -0x20000000 is that,
1433 according to Nat'l Semi's data sheet on the ns32532, ``the
1434 pattern 11100000 for the most significant byte of the
1435 displacement is reserved by National for future
1438 if (val < -0x1f000000 || val >= 0x20000000)
1439 as_warn("Double word displacement out of range");
1442 printf("%x ",val>>24 & 0xff);
1446 printf("%x ",val>>16 & 0xff);
1450 printf("%x ",val>>8 & 0xff);
1454 printf("%x ",val & 0xff);
1459 as_fatal("Internal logic error. line %s, file \"%s\"", __LINE__, __FILE__);
1463 static void md_number_to_imm(buf,val,n)
1471 printf("%x ",val & 0xff);
1477 printf("%x ",val>>8 & 0xff);
1481 printf("%x ",val & 0xff);
1487 printf("%x ",val>>24 & 0xff);
1491 printf("%x ",val>>16 & 0xff);
1495 printf("%x ",val>>8 & 0xff);
1499 printf("%x ",val & 0xff);
1504 as_fatal("Internal logic error. line %s, file \"%s\"", __LINE__, __FILE__);
1508 /* Translate internal representation of relocation info into target format.
1510 OVE: on a ns32k the twiddling continues at an even deeper level
1511 here we have to distinguish between displacements and immediates.
1513 The sequent has a bit for this. It also has a bit for relocobjects that
1514 points at the target for a bsr (BranchSubRoutine) !?!?!?!
1516 This md_ri.... is tailored for sequent.
1521 md_ri_to_chars(the_bytes, ri)
1523 struct reloc_info_generic *ri;
1525 if (ri->r_bsr) { ri->r_pcrel = 0; } /* sequent seems to want this */
1526 md_number_to_chars(the_bytes, ri->r_address, sizeof(ri->r_address));
1527 md_number_to_chars(the_bytes+4, ((long)(ri->r_symbolnum )
1528 | (long)(ri->r_pcrel << 24 )
1529 | (long)(ri->r_length << 25 )
1530 | (long)(ri->r_extern << 27 )
1531 | (long)(ri->r_bsr << 28 )
1532 | (long)(ri->r_disp << 29 )),
1534 /* the first and second md_number_to_chars never overlaps (32bit cpu case) */
1536 #endif /* comment */
1539 void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
1542 relax_addressT segment_address_in_file;
1545 * In: length of relocation (or of address) in chars: 1, 2 or 4.
1546 * Out: GNU LD relocation length code: 0, 1, or 2.
1549 static unsigned char nbytes_r_length[] = { 42, 0, 1, 42, 2 };
1553 know(fixP->fx_addsy != NULL);
1555 md_number_to_chars(where,
1556 fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
1559 r_symbolnum = (S_IS_DEFINED(fixP->fx_addsy)
1560 ? S_GET_TYPE(fixP->fx_addsy)
1561 : fixP->fx_addsy->sy_number);
1562 r_flags = (fixP->fx_pcrel ? 1 : 0)
1563 | ((nbytes_r_length[fixP->fx_size] & 3) << 1)
1564 | (!S_IS_DEFINED(fixP->fx_addsy) ? 8 : 0)
1565 #if defined(TE_SEQUENT)
1566 | (fixP->fx_bsr ? 0x10 : 0)
1568 /* Undefined pc-relative relocations are of type jmpslot */
1569 | ((!S_IS_DEFINED(fixP->fx_addsy)
1571 && fixP->fx_addsy != got_symbol
1572 && picmode) ? 0x10 : 0)
1574 | (fixP->fx_im_disp & 3) << 5;
1577 switch (fixP->fx_r_type) {
1581 if (picmode && S_IS_EXTERNAL(fixP->fx_addsy)) {
1582 r_symbolnum = fixP->fx_addsy->sy_number;
1583 r_flags |= 8; /* set extern bit */
1586 case RELOC_GLOB_DAT:
1587 if (!fixP->fx_pcrel) {
1588 r_flags |= 0x80; /* set baserel bit */
1589 r_symbolnum = fixP->fx_addsy->sy_number;
1590 if (S_IS_EXTERNAL(fixP->fx_addsy))
1594 case RELOC_RELATIVE:
1595 /* should never happen */
1596 as_fatal("relocation botch");
1601 where[4] = r_symbolnum & 0x0ff;
1602 where[5] = (r_symbolnum >> 8) & 0x0ff;
1603 where[6] = (r_symbolnum >> 16) & 0x0ff;
1607 } /* tc_aout_fix_to_chars() */
1610 #endif /* OBJ_AOUT */
1612 /* fast bitfiddling support */
1613 /* mask used to zero bitfield before oring in the true field */
1615 static unsigned long l_mask[] = {
1616 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
1617 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
1618 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
1619 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
1620 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
1621 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
1622 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
1623 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000,
1625 static unsigned long r_mask[] = {
1626 0x00000000, 0x00000001, 0x00000003, 0x00000007,
1627 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
1628 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
1629 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
1630 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
1631 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
1632 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
1633 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
1635 #define MASK_BITS 31
1636 /* Insert bitfield described by field_ptr and val at buf
1637 This routine is written for modification of the first 4 bytes pointed
1638 to by buf, to yield speed.
1639 The ifdef stuff is for selection between a ns32k-dependent routine
1640 and a general version. (My advice: use the general version!)
1644 md_number_to_field(buf,val,field_ptr)
1647 register bit_fixS *field_ptr;
1649 register unsigned long object;
1650 register unsigned long mask;
1651 /* define ENDIAN on a ns32k machine */
1653 register unsigned long *mem_ptr;
1655 register char *mem_ptr;
1657 if (field_ptr->fx_bit_min <= val && val <= field_ptr->fx_bit_max) {
1659 if (field_ptr->fx_bit_base) { /* override buf */
1660 mem_ptr=(unsigned long*)field_ptr->fx_bit_base;
1662 mem_ptr=(unsigned long*)buf;
1665 if (field_ptr->fx_bit_base) { /* override buf */
1666 mem_ptr=(char*)field_ptr->fx_bit_base;
1671 mem_ptr+=field_ptr->fx_bit_base_adj;
1672 #ifdef ENDIAN /* we have a nice ns32k machine with lowbyte at low-physical mem */
1673 object = *mem_ptr; /* get some bytes */
1674 #else /* OVE Goof! the machine is a m68k or dito */
1675 /* That takes more byte fiddling */
1677 object|=mem_ptr[3] & 0xff;
1679 object|=mem_ptr[2] & 0xff;
1681 object|=mem_ptr[1] & 0xff;
1683 object|=mem_ptr[0] & 0xff;
1686 mask|=(r_mask[field_ptr->fx_bit_offset]);
1687 mask|=(l_mask[field_ptr->fx_bit_offset+field_ptr->fx_bit_size]);
1689 val+=field_ptr->fx_bit_add;
1690 object|=((val<<field_ptr->fx_bit_offset) & (mask ^ 0xffffffff));
1694 mem_ptr[0]=(char)object;
1696 mem_ptr[1]=(char)object;
1698 mem_ptr[2]=(char)object;
1700 mem_ptr[3]=(char)object;
1703 as_warn("Bit field out of range");
1707 /* Apply a fixS (fixup of an instruction or data that we didn't have
1708 enough info to complete immediately) to the data in a frag.
1710 On the ns32k, everything is in a different format, so we have broken
1711 out separate functions for each kind of thing we could be fixing.
1712 They all get called from here. */
1715 md_apply_fix(fixP, val)
1719 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1721 if (fixP->fx_bit_fixP) { /* Bitfields to fix, sigh */
1722 md_number_to_field (buf, val, fixP->fx_bit_fixP);
1723 } else switch (fixP->fx_im_disp) {
1725 case 0: /* Immediate field */
1726 md_number_to_imm (buf, val, fixP->fx_size);
1729 case 1: /* Displacement field */
1730 md_number_to_disp (buf,
1731 fixP->fx_pcrel? val + fixP->fx_pcrel_adjust: val,
1735 case 2: /* Pointer in a data object */
1736 md_number_to_chars (buf, val, fixP->fx_size);
1741 /* Convert a relaxed displacement to ditto in final output */
1744 md_convert_frag(headers, fragP)
1745 object_headers *headers;
1746 register fragS *fragP;
1751 /* Address in gas core of the place to store the displacement. */
1752 register char *buffer_address = fragP->fr_fix + fragP->fr_literal;
1753 /* Address in object code of the displacement. */
1754 register int object_address = fragP->fr_fix + fragP->fr_address;
1756 know(fragP->fr_symbol);
1758 /* The displacement of the address, from current location. */
1759 disp = (S_GET_VALUE(fragP->fr_symbol) + fragP->fr_offset) - object_address;
1760 disp += fragP->fr_pcrel_adjust;
1762 switch (fragP->fr_subtype) {
1763 case IND(BRANCH,BYTE):
1766 case IND(BRANCH,WORD):
1769 case IND(BRANCH,DOUBLE):
1774 md_number_to_disp(buffer_address, (long)disp, (int)ext);
1775 fragP->fr_fix += ext;
1777 } /* md_convert_frag() */
1781 /* This function returns the estimated size a variable object will occupy,
1782 one can say that we tries to guess the size of the objects before we
1785 int md_estimate_size_before_relax(fragP, segment)
1786 register fragS *fragP;
1790 old_fix = fragP->fr_fix;
1791 switch (fragP->fr_subtype) {
1792 case IND(BRANCH,UNDEF):
1793 if (S_GET_SEGMENT(fragP->fr_symbol) == segment) {
1794 /* the symbol has been assigned a value */
1795 fragP->fr_subtype = IND(BRANCH,BYTE);
1797 /* we don't relax symbols defined in an other segment
1798 the thing to do is to assume the object will occupy 4 bytes */
1799 fix_new_ns32k(fragP,
1800 (int)(fragP->fr_fix),
1806 fragP->fr_pcrel_adjust,
1809 fragP->fr_bsr, /*sequent hack */
1812 /* fragP->fr_opcode[1]=0xff; */
1816 case IND(BRANCH,BYTE):
1822 return fragP->fr_var + fragP->fr_fix - old_fix;
1825 int md_short_jump_size = 3;
1826 int md_long_jump_size = 5;
1827 const int md_reloc_size = 8; /* Size of relocation record */
1830 md_create_short_jump(ptr,from_addr,to_addr,frag,to_symbol)
1839 offset = to_addr - from_addr;
1840 md_number_to_chars(ptr, (long)0xEA ,1);
1841 md_number_to_disp(ptr+1,(long)offset,2);
1845 md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol)
1854 offset= to_addr - from_addr;
1855 md_number_to_chars(ptr, (long)0xEA, 2);
1856 md_number_to_disp(ptr+2,(long)offset,4);
1859 /* JF this is a new function to parse machine-dep options */
1861 md_parse_option(argP,cntP,vecP)
1870 if (!strcmp(*argP,"32032")) {
1871 cpureg = cpureg_032;
1872 mmureg = mmureg_032;
1873 } else if (!strcmp(*argP, "32532")) {
1874 cpureg = cpureg_532;
1875 mmureg = mmureg_532;
1877 as_warn("Unknown -m option ignored");
1885 got_offset_size = 4;
1888 got_symbol = symbol_find_or_make("__GLOBAL_OFFSET_TABLE_");
1901 * Create a bit_fixS in obstack 'notes'.
1902 * This struct is used to profile the normal fix. If the bit_fixP is a
1903 * valid pointer (not NULL) the bit_fix data will be used to format the fix.
1905 bit_fixS *bit_fix_new(size, offset, min, max, add, base_type, base_adj)
1906 char size; /* Length of bitfield */
1907 char offset; /* Bit offset to bitfield */
1908 long base_type; /* 0 or 1, if 1 it's exploded to opcode ptr */
1910 long min; /* Signextended min for bitfield */
1911 long max; /* Signextended max for bitfield */
1912 long add; /* Add mask, used for huffman prefix */
1914 register bit_fixS * bit_fixP;
1916 bit_fixP = (bit_fixS *)obstack_alloc(¬es,sizeof(bit_fixS));
1918 bit_fixP->fx_bit_size = size;
1919 bit_fixP->fx_bit_offset = offset;
1920 bit_fixP->fx_bit_base = base_type;
1921 bit_fixP->fx_bit_base_adj = base_adj;
1922 bit_fixP->fx_bit_max = max;
1923 bit_fixP->fx_bit_min = min;
1924 bit_fixP->fx_bit_add = add;
1930 fix_new_ns32k(frag, where, size, add_symbol, sub_symbol, offset, pcrel,
1931 pcrel_adjust, im_disp, bit_fixP, bsr, r_type)
1932 fragS *frag; /* Which frag? */
1933 int where; /* Where in that frag? */
1934 int size; /* 1, 2 or 4 usually. */
1935 symbolS *add_symbol; /* X_add_symbol. */
1936 symbolS *sub_symbol; /* X_subtract_symbol. */
1937 long offset; /* X_add_number. */
1938 int pcrel; /* TRUE if PC-relative relocation. */
1939 char pcrel_adjust; /* not zero if adjustment of pcrel offset is needed */
1940 char im_disp; /* true if the value to write is a displacement */
1941 bit_fixS *bit_fixP; /* pointer at struct of bit_fix's, ignored if NULL */
1942 char bsr; /* sequent-linker-hack: 1 when relocobject is a bsr */
1943 int r_type; /* Relocation type */
1947 fixS *fixP = fix_new(frag, where, size, add_symbol, sub_symbol,
1948 offset, pcrel, r_type, NULL);
1950 fixS *fixP = fix_new(frag, where, size, add_symbol, sub_symbol,
1951 offset, pcrel, r_type);
1953 fixP->fx_pcrel_adjust = pcrel_adjust;
1954 fixP->fx_im_disp = im_disp;
1955 fixP->fx_bit_fixP = bit_fixP;
1958 if (r_type == RELOC_GLOB_DAT)
1959 add_symbol->sy_forceout = 1;
1961 } /* fix_new_ns32k() */
1963 /* We have no need to default values of symbols. */
1966 md_undefined_symbol (name)
1972 /* Parse an operand that is machine-specific.
1973 We just return without modifying the expression if we have nothing
1978 md_operand (expressionP)
1979 expressionS *expressionP;
1983 /* Round up a section size to the appropriate boundary. */
1985 md_section_align (segment, size)
1989 return size; /* Byte alignment is fine */
1992 /* Exactly what point is a PC-relative offset relative TO?
1993 On the National warts, they're relative to the address of the offset,
1994 with some funny adjustments in some circumstances during blue moons.
1995 (??? Is this right? FIXME-SOON) */
1997 md_pcrel_from (fixP)
2001 res = fixP->fx_where + fixP->fx_frag->fr_address;
2003 if (fixP->fx_frag->fr_bsr)
2004 res += 0x12; /* FOO Kludge alert! */
2015 /* end of tc-ns32k.c */