Initial import from FreeBSD RELENG_4:
[dragonfly.git] / gnu / usr.bin / as / config / tc-a29k.c
1 /* tc-a29k.c -- Assemble for the AMD 29000.
2    Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
3
4    This file is part of GAS, the GNU Assembler.
5
6    GAS is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
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.
15
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.  */
19
20 /* John Gilmore has reorganized this module somewhat, to make it easier
21    to convert it to new machines' assemblers as desired.  There was too
22    much bloody rewriting required before.  There still probably is.  */
23
24 #include "as.h"
25
26 #include "opcode/a29k.h"
27
28 /* Make it easier to clone this machine desc into another one.  */
29 #define machine_opcode  a29k_opcode
30 #define machine_opcodes a29k_opcodes
31 #define machine_ip      a29k_ip
32 #define machine_it      a29k_it
33
34 const relax_typeS md_relax_table[] = { 0 };
35
36 #define IMMEDIATE_BIT   0x01000000      /* Turns RB into Immediate */
37 #define ABSOLUTE_BIT    0x01000000      /* Turns PC-relative to Absolute */
38 #define CE_BIT          0x00800000      /* Coprocessor enable in LOAD */
39 #define UI_BIT          0x00000080      /* Unsigned integer in CONVERT */
40
41 /* handle of the OPCODE hash table */
42 static struct hash_control *op_hash = NULL;
43
44 struct machine_it {
45         char    *error;
46         unsigned long opcode;
47         struct nlist *nlistp;
48         expressionS exp;
49         int pcrel;
50         int  reloc_offset;              /* Offset of reloc within insn */
51         enum reloc_type reloc;
52 } the_insn;
53
54 #if __STDC__ == 1
55
56 /* static int getExpression(char *str); */
57 static void machine_ip(char *str);
58 /* static void print_insn(struct machine_it *insn); */
59 static void s_data1(void);
60 static void s_use(void);
61
62 #else /* not __STDC__ */
63
64 /* static int getExpression(); */
65 static void machine_ip();
66 /* static void print_insn(); */
67 static void s_data1();
68 static void s_use();
69
70 #endif /* not __STDC__ */
71
72 const pseudo_typeS
73     md_pseudo_table[] = {
74             { "align",  s_align_bytes,  4 },
75             { "block",  s_space,        0 },
76             { "cputype",        s_ignore,       0 },    /* CPU as 29000 or 29050 */
77             { "reg",    s_lsym,         0 },    /* Register equate, same as equ */
78             { "space",  s_ignore,       0 },    /* Listing control */
79             { "sect",   s_ignore,       0 },    /* Creation of coff sections */
80             { "use",    s_use,          0 },
81             { "word",   cons,           4 },
82             { NULL,     0,              0 },
83     };
84
85 int md_short_jump_size = 4;
86 int md_long_jump_size = 4;
87 #if defined(BFD_HEADERS)
88 #ifdef RELSZ
89 const int md_reloc_size = RELSZ;        /* Coff headers */
90 #else
91 const int md_reloc_size = 12;           /* something else headers */
92 #endif
93 #else
94 const int md_reloc_size = 12;           /* Not bfdized*/
95 #endif
96
97 /* This array holds the chars that always start a comment.  If the
98    pre-processor is disabled, these aren't very useful */
99 char comment_chars[] = ";";
100
101 /* This array holds the chars that only start a comment at the beginning of
102    a line.  If the line seems to have the form '# 123 filename'
103    .line and .file directives will appear in the pre-processed output */
104 /* Note that input_file.c hand checks for '#' at the beginning of the
105    first line of the input file.  This is because the compiler outputs
106    #NO_APP at the beginning of its output. */
107 /* Also note that comments like this one will always work */
108 char line_comment_chars[] = "#";
109
110 /* We needed an unused char for line separation to work around the
111    lack of macros, using sed and such.  */
112 char line_separator_chars[] = "@";
113
114 /* Chars that can be used to separate mant from exp in floating point nums */
115 char EXP_CHARS[] = "eE";
116
117 /* Chars that mean this number is a floating point constant */
118 /* As in 0f12.456 */
119 /* or    0d1.2345e12 */
120 char FLT_CHARS[] = "rRsSfFdDxXpP";
121
122 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
123    changed in read.c. Ideally it shouldn't have to know about it at all,
124    but nothing is ideal around here.
125    */
126
127 static unsigned char octal[256];
128 #define isoctal(c)  octal[c]
129     static unsigned char toHex[256];
130
131 /*
132  *  anull bit - causes the branch delay slot instructions to not be executed
133  */
134 #define ANNUL       (1 << 29)
135
136 static void
137     s_use()
138 {
139
140         if (strncmp(input_line_pointer, ".text", 5) == 0) {
141                 input_line_pointer += 5;
142                 s_text();
143                 return;
144         }
145         if (strncmp(input_line_pointer, ".data", 5) == 0) {
146                 input_line_pointer += 5;
147                 s_data();
148                 return;
149         }
150         if (strncmp(input_line_pointer, ".data1", 6) == 0) {
151                 input_line_pointer += 6;
152                 s_data1();
153                 return;
154         }
155         /* Literals can't go in the text segment because you can't read
156            from instruction memory on some 29k's.  So, into initialized data. */
157         if (strncmp(input_line_pointer, ".lit", 4) == 0) {
158                 input_line_pointer += 4;
159                 subseg_new(SEG_DATA, 200);
160                 demand_empty_rest_of_line();
161                 return;
162         }
163
164         as_bad("Unknown segment type");
165         demand_empty_rest_of_line();
166         return;
167 }
168
169 static void
170     s_data1()
171 {
172         subseg_new(SEG_DATA, 1);
173         demand_empty_rest_of_line();
174         return;
175 }
176
177 /* Install symbol definition that maps REGNAME to REGNO.
178    FIXME-SOON:  These are not recognized in mixed case.  */
179
180 static void
181     insert_sreg (regname, regnum)
182 char *regname;
183 int regnum;
184 {
185         /* FIXME-SOON, put something in these syms so they won't be output to the symbol
186            table of the resulting object file.  */
187
188         /* Must be large enough to hold the names of the special registers.  */
189         char buf[80];
190         int i;
191
192         symbol_table_insert(symbol_new(regname, SEG_REGISTER, regnum, &zero_address_frag));
193         for (i = 0; regname[i]; i++)
194             buf[i] = islower (regname[i]) ? toupper (regname[i]) : regname[i];
195         buf[i] = '\0';
196
197         symbol_table_insert(symbol_new(buf, SEG_REGISTER, regnum, &zero_address_frag));
198 } /* insert_sreg() */
199
200 /* Install symbol definitions for assorted special registers.
201    See ASM29K Ref page 2-9.  */
202
203 void define_some_regs() {
204 #define SREG    256
205
206         /* Protected special-purpose register names */
207         insert_sreg ("vab", SREG+0);
208         insert_sreg ("ops", SREG+1);
209         insert_sreg ("cps", SREG+2);
210         insert_sreg ("cfg", SREG+3);
211         insert_sreg ("cha", SREG+4);
212         insert_sreg ("chd", SREG+5);
213         insert_sreg ("chc", SREG+6);
214         insert_sreg ("rbp", SREG+7);
215         insert_sreg ("tmc", SREG+8);
216         insert_sreg ("tmr", SREG+9);
217         insert_sreg ("pc0", SREG+10);
218         insert_sreg ("pc1", SREG+11);
219         insert_sreg ("pc2", SREG+12);
220         insert_sreg ("mmu", SREG+13);
221         insert_sreg ("lru", SREG+14);
222
223         /* Unprotected special-purpose register names */
224         insert_sreg ("ipc", SREG+128);
225         insert_sreg ("ipa", SREG+129);
226         insert_sreg ("ipb", SREG+130);
227         insert_sreg ("q",   SREG+131);
228         insert_sreg ("alu", SREG+132);
229         insert_sreg ("bp",  SREG+133);
230         insert_sreg ("fc",  SREG+134);
231         insert_sreg ("cr",  SREG+135);
232         insert_sreg ("fpe", SREG+160);
233         insert_sreg ("inte",SREG+161);
234         insert_sreg ("fps", SREG+162);
235         /*  "",    SREG+163);     Reserved */
236         insert_sreg ("exop",SREG+164);
237 } /* define_some_regs() */
238
239 /* This function is called once, at assembler startup time.  It should
240    set up all the tables, etc. that the MD part of the assembler will need.  */
241 void
242     md_begin()
243 {
244         register char *retval = NULL;
245         int lose = 0;
246         register int skipnext = 0;
247         register unsigned int i;
248         register char *strend, *strend2;
249
250         /* Hash up all the opcodes for fast use later.  */
251
252         op_hash = hash_new();
253         if (op_hash == NULL)
254             as_fatal("Virtual memory exhausted");
255
256         for (i = 0; i < num_opcodes; i++)
257             {
258                     const char *name = machine_opcodes[i].name;
259
260                     if (skipnext) {
261                             skipnext = 0;
262                             continue;
263                     }
264
265                     /* Hack to avoid multiple opcode entries.  We pre-locate all the
266                        variations (b/i field and P/A field) and handle them. */
267
268                     if (!strcmp (name, machine_opcodes[i+1].name)) {
269                             if ((machine_opcodes[i].opcode ^ machine_opcodes[i+1].opcode)
270                                 != 0x01000000)
271                                 goto bad_table;
272                             strend =  machine_opcodes[i  ].args+strlen(machine_opcodes[i  ].args)-1;
273                             strend2 = machine_opcodes[i+1].args+strlen(machine_opcodes[i+1].args)-1;
274                             switch (*strend) {
275                             case 'b':
276                                     if (*strend2 != 'i')  goto bad_table;
277                                     break;
278                             case 'i':
279                                     if (*strend2 != 'b')  goto bad_table;
280                                     break;
281                             case 'P':
282                                     if (*strend2 != 'A')  goto bad_table;
283                                     break;
284                             case 'A':
285                                     if (*strend2 != 'P')  goto bad_table;
286                                     break;
287                             default:
288                             bad_table:
289                                     fprintf (stderr, "internal error: can't handle opcode %s\n", name);
290                                     lose = 1;
291                             }
292
293                             /* OK, this is an i/b or A/P pair.  We skip the higher-valued one,
294                                and let the code for operand checking handle OR-ing in the bit.  */
295                             if (machine_opcodes[i].opcode & 1)
296                                 continue;
297                             else
298                                 skipnext = 1;
299                     }
300
301                     retval = hash_insert (op_hash, name, &machine_opcodes[i]);
302                     if (retval != NULL && *retval != '\0')
303                         {
304                                 fprintf (stderr, "internal error: can't hash `%s': %s\n",
305                                          machine_opcodes[i].name, retval);
306                                 lose = 1;
307                         }
308             }
309
310         if (lose)
311             as_fatal("Broken assembler.  No assembly attempted.");
312
313         for (i = '0'; i < '8'; ++i)
314             octal[i] = 1;
315         for (i = '0'; i <= '9'; ++i)
316             toHex[i] = i - '0';
317         for (i = 'a'; i <= 'f'; ++i)
318             toHex[i] = i + 10 - 'a';
319         for (i = 'A'; i <= 'F'; ++i)
320             toHex[i] = i + 10 - 'A';
321
322         define_some_regs ();
323 }
324
325 void md_end() {
326         return;
327 }
328
329 /* Assemble a single instruction.  Its label has already been handled
330    by the generic front end.  We just parse opcode and operands, and
331    produce the bytes of data and relocation.  */
332
333 void md_assemble(str)
334 char *str;
335 {
336         char *toP;
337         /* !!!!    int rsd; */
338
339         know(str);
340         machine_ip(str);
341         toP = frag_more(4);
342         /* put out the opcode */
343         md_number_to_chars(toP, the_insn.opcode, 4);
344
345         /* put out the symbol-dependent stuff */
346         if (the_insn.reloc != NO_RELOC) {
347                 fix_new(
348                         frag_now,                           /* which frag */
349                         (toP - frag_now->fr_literal + the_insn.reloc_offset), /* where */
350                         4,                                  /* size */
351                         the_insn.exp.X_add_symbol,
352                         the_insn.exp.X_subtract_symbol,
353                         the_insn.exp.X_add_number,
354                         the_insn.pcrel,
355                         the_insn.reloc
356                         );
357         }
358 }
359
360 char *
361     parse_operand (s, operandp)
362 char *s;
363 expressionS *operandp;
364 {
365         char *save = input_line_pointer;
366         char *new;
367         segT seg;
368
369         input_line_pointer = s;
370         seg = expr (0, operandp);
371         new = input_line_pointer;
372         input_line_pointer = save;
373
374         switch (seg) {
375         case SEG_ABSOLUTE:
376         case SEG_TEXT:
377         case SEG_DATA:
378         case SEG_BSS:
379         case SEG_UNKNOWN:
380         case SEG_DIFFERENCE:
381         case SEG_BIG:
382         case SEG_REGISTER:
383                 return new;
384
385         case SEG_ABSENT:
386                 as_bad("Missing operand");
387                 return new;
388
389         default:
390                 as_bad("Don't understand operand of type %s", segment_name (seg));
391                 return new;
392         }
393 }
394
395 /* Instruction parsing.  Takes a string containing the opcode.
396    Operands are at input_line_pointer.  Output is in the_insn.
397    Warnings or errors are generated.  */
398
399 static void
400     machine_ip(str)
401 char *str;
402 {
403         char *s;
404         const char *args;
405         /* !!!!    char c; */
406         /* !!!!    unsigned long i; */
407         struct machine_opcode *insn;
408         char *argsStart;
409         unsigned long   opcode;
410         /* !!!!    unsigned int mask; */
411         expressionS the_operand;
412         expressionS *operand = &the_operand;
413         unsigned int reg;
414
415         /* Must handle `div0' opcode.  */
416         s = str;
417         if (isalpha(*s))
418             for (; isalnum(*s); ++s)
419                 if (isupper (*s))
420                     *s = tolower (*s);
421
422         switch (*s) {
423         case '\0':
424                 break;
425
426         case ' ':               /* FIXME-SOMEDAY more whitespace */
427                 *s++ = '\0';
428                 break;
429
430         default:
431                 as_bad("Unknown opcode: `%s'", str);
432                 return;
433         }
434         if ((insn = (struct machine_opcode *) hash_find(op_hash, str)) == NULL) {
435                 as_bad("Unknown opcode `%s'.", str);
436                 return;
437         }
438         argsStart = s;
439         opcode = insn->opcode;
440         memset(&the_insn, '\0', sizeof(the_insn));
441         the_insn.reloc = NO_RELOC;
442
443         /*
444          * Build the opcode, checking as we go to make
445          * sure that the operands match.
446          *
447          * If an operand matches, we modify the_insn or opcode appropriately,
448          * and do a "continue".  If an operand fails to match, we "break".
449          */
450         if (insn->args[0] != '\0')
451             s = parse_operand (s, operand);     /* Prime the pump */
452
453         for (args = insn->args; ; ++args) {
454                 switch (*args) {
455
456                 case '\0':  /* end of args */
457                         if (*s == '\0') {
458                                 /* We are truly done. */
459                                 the_insn.opcode = opcode;
460                                 return;
461                         }
462                         as_bad("Too many operands: %s", s);
463                         break;
464
465                 case ',':       /* Must match a comma */
466                         if (*s++ == ',') {
467                                 s = parse_operand (s, operand); /* Parse next opnd */
468                                 continue;
469                         }
470                         break;
471
472                 case 'v':               /* Trap numbers (immediate field) */
473                         if (operand->X_seg == SEG_ABSOLUTE) {
474                                 if (operand->X_add_number < 256) {
475                                         opcode |= (operand->X_add_number << 16);
476                                         continue;
477                                 } else {
478                                         as_bad("Immediate value of %d is too large",
479                                                operand->X_add_number);
480                                         continue;
481                                 }
482                         }
483                         the_insn.reloc = RELOC_8;
484                         the_insn.reloc_offset = 1;      /* BIG-ENDIAN Byte 1 of insn */
485                         the_insn.exp = *operand;
486                         continue;
487
488                 case 'b':       /* A general register or 8-bit immediate */
489                 case 'i':
490                         /* We treat the two cases identically since we mashed
491                            them together in the opcode table.  */
492                         if (operand->X_seg == SEG_REGISTER)
493                             goto general_reg;
494
495                         opcode |= IMMEDIATE_BIT;
496                         if (operand->X_seg == SEG_ABSOLUTE) {
497                                 if (operand->X_add_number < 256) {
498                                         opcode |= operand->X_add_number;
499                                         continue;
500                                 } else {
501                                         as_bad("Immediate value of %d is too large",
502                                                operand->X_add_number);
503                                         continue;
504                                 }
505                         }
506                         the_insn.reloc = RELOC_8;
507                         the_insn.reloc_offset = 3;      /* BIG-ENDIAN Byte 3 of insn */
508                         the_insn.exp = *operand;
509                         continue;
510
511                 case 'a':   /* next operand must be a register */
512                 case 'c':
513                 general_reg:
514                         /* lrNNN or grNNN or %%expr or a user-def register name */
515                         if (operand->X_seg != SEG_REGISTER)
516                             break;              /* Only registers */
517                         know (operand->X_add_symbol == 0);
518                         know (operand->X_subtract_symbol == 0);
519                         reg = operand->X_add_number;
520                         if (reg >= SREG)
521                             break;              /* No special registers */
522
523                         /*
524                          * Got the register, now figure out where
525                          * it goes in the opcode.
526                          */
527                         switch (*args) {
528                         case 'a':
529                                 opcode |= reg << 8;
530                                 continue;
531
532                         case 'b':
533                         case 'i':
534                                 opcode |= reg;
535                                 continue;
536
537                         case 'c':
538                                 opcode |= reg << 16;
539                                 continue;
540                         }
541                         as_fatal("failed sanity check.");
542                         break;
543
544                 case 'x':               /* 16 bit constant, zero-extended */
545                 case 'X':               /* 16 bit constant, one-extended */
546                         if (operand->X_seg == SEG_ABSOLUTE) {
547                                 opcode |=  (operand->X_add_number & 0xFF)   << 0 |
548                                     ((operand->X_add_number & 0xFF00) << 8);
549                                 continue;
550                         }
551                         the_insn.reloc = RELOC_CONST;
552                         the_insn.exp = *operand;
553                         continue;
554
555                 case 'h':
556                         if (operand->X_seg == SEG_ABSOLUTE) {
557                                 opcode |=  (operand->X_add_number & 0x00FF0000) >> 16 |
558                                     (((unsigned long)operand->X_add_number
559                                       /* avoid sign ext */        & 0xFF000000) >> 8);
560                                 continue;
561                         }
562                         the_insn.reloc = RELOC_CONSTH;
563                         the_insn.exp = *operand;
564                         continue;
565
566                 case 'P':               /* PC-relative jump address */
567                 case 'A':               /* Absolute jump address */
568                         /* These two are treated together since we folded the
569                            opcode table entries together.  */
570                         if (operand->X_seg == SEG_ABSOLUTE) {
571                                 opcode |= ABSOLUTE_BIT |
572                                     (operand->X_add_number & 0x0003FC00) << 6 |
573                                         ((operand->X_add_number & 0x000003FC) >> 2);
574                                 continue;
575                         }
576                         the_insn.reloc = RELOC_JUMPTARG;
577                         the_insn.exp = *operand;
578                         the_insn.pcrel = 1;             /* Assume PC-relative jump */
579                         /* FIXME-SOON, Do we figure out whether abs later, after know sym val? */
580                         continue;
581
582                 case 'e':               /* Coprocessor enable bit for LOAD/STORE insn */
583                         if (operand->X_seg == SEG_ABSOLUTE) {
584                                 if (operand->X_add_number == 0)
585                                     continue;
586                                 if (operand->X_add_number == 1) {
587                                         opcode |= CE_BIT;
588                                         continue;
589                                 }
590                         }
591                         break;
592
593                 case 'n':               /* Control bits for LOAD/STORE instructions */
594                         if (operand->X_seg == SEG_ABSOLUTE &&
595                             operand->X_add_number < 128) {
596                                 opcode |= (operand->X_add_number << 16);
597                                 continue;
598                         }
599                         break;
600
601                 case 's':               /* Special register number */
602                         if (operand->X_seg != SEG_REGISTER)
603                             break;              /* Only registers */
604                         if (operand->X_add_number < SREG)
605                             break;              /* Not a special register */
606                         opcode |= (operand->X_add_number & 0xFF) << 8;
607                         continue;
608
609                 case 'u':               /* UI bit of CONVERT */
610                         if (operand->X_seg == SEG_ABSOLUTE) {
611                                 if (operand->X_add_number == 0)
612                                     continue;
613                                 if (operand->X_add_number == 1) {
614                                         opcode |= UI_BIT;
615                                         continue;
616                                 }
617                         }
618                         break;
619
620                 case 'r':               /* RND bits of CONVERT */
621                         if (operand->X_seg == SEG_ABSOLUTE &&
622                             operand->X_add_number < 8) {
623                                 opcode |= operand->X_add_number << 4;
624                                 continue;
625                         }
626                         break;
627
628                 case 'd':               /* FD bits of CONVERT */
629                         if (operand->X_seg == SEG_ABSOLUTE &&
630                             operand->X_add_number < 4) {
631                                 opcode |= operand->X_add_number << 2;
632                                 continue;
633                         }
634                         break;
635
636
637                 case 'f':               /* FS bits of CONVERT */
638                         if (operand->X_seg == SEG_ABSOLUTE &&
639                             operand->X_add_number < 4) {
640                                 opcode |= operand->X_add_number << 0;
641                                 continue;
642                         }
643                         break;
644
645                 case 'C':
646                         if (operand->X_seg == SEG_ABSOLUTE &&
647                             operand->X_add_number < 4) {
648                                 opcode |= operand->X_add_number << 16;
649                                 continue;
650                         }
651                         break;
652
653                 case 'F':
654                         if (operand->X_seg == SEG_ABSOLUTE &&
655                             operand->X_add_number < 16) {
656                                 opcode |= operand->X_add_number << 18;
657                                 continue;
658                         }
659                         break;
660
661                 default:
662                         BAD_CASE (*args);
663                 }
664                 /* Types or values of args don't match.  */
665                 as_bad("Invalid operands");
666                 return;
667         }
668 }
669
670 /*
671   This is identical to the md_atof in m68k.c.  I think this is right,
672   but I'm not sure.
673
674   Turn a string in input_line_pointer into a floating point constant of type
675   type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
676   emitted is stored in *sizeP. An error message is returned, or NULL on OK.
677   */
678
679 /* Equal to MAX_PRECISION in atof-ieee.c */
680 #define MAX_LITTLENUMS 6
681
682 char *
683     md_atof(type,litP,sizeP)
684 char type;
685 char *litP;
686 int *sizeP;
687 {
688         int     prec;
689         LITTLENUM_TYPE words[MAX_LITTLENUMS];
690         LITTLENUM_TYPE *wordP;
691         char    *t;
692
693         switch (type) {
694
695         case 'f':
696         case 'F':
697         case 's':
698         case 'S':
699                 prec = 2;
700                 break;
701
702         case 'd':
703         case 'D':
704         case 'r':
705         case 'R':
706                 prec = 4;
707                 break;
708
709         case 'x':
710         case 'X':
711                 prec = 6;
712                 break;
713
714         case 'p':
715         case 'P':
716                 prec = 6;
717                 break;
718
719         default:
720                 *sizeP=0;
721                 return "Bad call to MD_ATOF()";
722         }
723         t=atof_ieee(input_line_pointer,type,words);
724         if (t)
725             input_line_pointer=t;
726         *sizeP=prec * sizeof(LITTLENUM_TYPE);
727         for (wordP=words;prec--;) {
728                 md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
729                 litP+=sizeof(LITTLENUM_TYPE);
730         }
731         return "";      /* Someone should teach Dean about null pointers */
732 }
733
734 /*
735  * Write out big-endian.
736  */
737 void
738     md_number_to_chars(buf, val, n)
739 char *buf;
740 long val;
741 int n;
742 {
743
744         switch (n) {
745
746         case 4:
747                 *buf++ = val >> 24;
748                 *buf++ = val >> 16;
749         case 2:
750                 *buf++ = val >> 8;
751         case 1:
752                 *buf = val;
753                 break;
754
755         default:
756                 as_fatal("failed sanity check.");
757         }
758         return;
759 }
760
761 void md_apply_fix(fixP, val)
762 fixS *fixP;
763 long val;
764 {
765         char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
766
767         fixP->fx_addnumber = val;       /* Remember value for emit_reloc */
768
769
770         know(fixP->fx_size == 4);
771         know(fixP->fx_r_type < NO_RELOC);
772
773         /*
774          * This is a hack.  There should be a better way to
775          * handle this.
776          */
777         if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy) {
778                 val += fixP->fx_where + fixP->fx_frag->fr_address;
779         }
780
781         switch (fixP->fx_r_type) {
782
783         case RELOC_32:
784                 buf[0] = val >> 24;
785                 buf[1] = val >> 16;
786                 buf[2] = val >> 8;
787                 buf[3] = val;
788                 break;
789
790         case RELOC_8:
791                 buf[0] = val;
792                 break;
793
794         case RELOC_WDISP30:
795                 val = (val >>= 2) + 1;
796                 buf[0] |= (val >> 24) & 0x3f;
797                 buf[1]= (val >> 16);
798                 buf[2] = val >> 8;
799                 buf[3] = val;
800                 break;
801
802         case RELOC_HI22:
803                 buf[1] |= (val >> 26) & 0x3f;
804                 buf[2] = val >> 18;
805                 buf[3] = val >> 10;
806                 break;
807
808         case RELOC_LO10:
809                 buf[2] |= (val >> 8) & 0x03;
810                 buf[3] = val;
811                 break;
812
813         case RELOC_BASE13:
814                 buf[2] |= (val >> 8) & 0x1f;
815                 buf[3] = val;
816                 break;
817
818         case RELOC_WDISP22:
819                 val = (val >>= 2) + 1;
820                 /* FALLTHROUGH */
821         case RELOC_BASE22:
822                 buf[1] |= (val >> 16) & 0x3f;
823                 buf[2] = val >> 8;
824                 buf[3] = val;
825                 break;
826
827 #if 0
828         case RELOC_PC10:
829         case RELOC_PC22:
830         case RELOC_JMP_TBL:
831         case RELOC_SEGOFF16:
832         case RELOC_GLOB_DAT:
833         case RELOC_JMP_SLOT:
834         case RELOC_RELATIVE:
835 #endif
836         case RELOC_JUMPTARG:    /* 00XX00XX pattern in a word */
837                 buf[1] = val >> 10;     /* Holds bits 0003FFFC of address */
838                 buf[3] = val >> 2;
839                 break;
840
841         case RELOC_CONST:               /* 00XX00XX pattern in a word */
842                 buf[1] = val >> 8;      /* Holds bits 0000XXXX */
843                 buf[3] = val;
844                 break;
845
846         case RELOC_CONSTH:              /* 00XX00XX pattern in a word */
847                 buf[1] = val >> 24;     /* Holds bits XXXX0000 */
848                 buf[3] = val >> 16;
849                 break;
850
851         case NO_RELOC:
852         default:
853                 as_bad("bad relocation type: 0x%02x", fixP->fx_r_type);
854                 break;
855         }
856         return;
857 }
858
859 #ifdef OBJ_COFF
860 short tc_coff_fix2rtype(fixP)
861 fixS *fixP;
862 {
863
864         /* FIXME-NOW: relocation type handling is not yet written for
865            a29k. */
866
867
868         switch (fixP->fx_r_type) {
869         case RELOC_32:  return(R_WORD);
870         case RELOC_8:   return(R_BYTE);
871         case RELOC_CONST: return (R_ILOHALF);
872         case RELOC_CONSTH: return (R_IHIHALF);
873         case RELOC_JUMPTARG: return (R_IREL);
874         default:        printf("need %o3\n", fixP->fx_r_type);
875                 abort(0);
876         } /* switch on type */
877
878         return(0);
879 } /* tc_coff_fix2rtype() */
880 #endif /* OBJ_COFF */
881
882 /* should never be called for sparc */
883 void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol)
884 char *ptr;
885 long from_addr, to_addr;
886 fragS *frag;
887 symbolS *to_symbol;
888 {
889         as_fatal("a29k_create_short_jmp\n");
890 }
891
892 /* should never be called for 29k */
893 void md_convert_frag(headers, fragP)
894 object_headers *headers;
895 register fragS *fragP;
896 {
897         as_fatal("sparc_convert_frag\n");
898 }
899
900 /* should never be called for 29k */
901 void md_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol)
902 char    *ptr;
903 long    from_addr;
904 long    to_addr;
905 fragS   *frag;
906 symbolS *to_symbol;
907 {
908         as_fatal("sparc_create_long_jump\n");
909 }
910
911 /* should never be called for a29k */
912 int md_estimate_size_before_relax(fragP, segtype)
913 register fragS *fragP;
914 segT segtype;
915 {
916         as_fatal("sparc_estimate_size_before_relax\n");
917         return(0);
918 }
919
920 #if 0
921 /* for debugging only */
922 static void
923     print_insn(insn)
924 struct machine_it *insn;
925 {
926         char *Reloc[] = {
927                 "RELOC_8",
928                 "RELOC_16",
929                 "RELOC_32",
930                 "RELOC_DISP8",
931                 "RELOC_DISP16",
932                 "RELOC_DISP32",
933                 "RELOC_WDISP30",
934                 "RELOC_WDISP22",
935                 "RELOC_HI22",
936                 "RELOC_22",
937                 "RELOC_13",
938                 "RELOC_LO10",
939                 "RELOC_SFA_BASE",
940                 "RELOC_SFA_OFF13",
941                 "RELOC_BASE10",
942                 "RELOC_BASE13",
943                 "RELOC_BASE22",
944                 "RELOC_PC10",
945                 "RELOC_PC22",
946                 "RELOC_JMP_TBL",
947                 "RELOC_SEGOFF16",
948                 "RELOC_GLOB_DAT",
949                 "RELOC_JMP_SLOT",
950                 "RELOC_RELATIVE",
951                 "NO_RELOC"
952             };
953
954         if (insn->error) {
955                 fprintf(stderr, "ERROR: %s\n");
956         }
957         fprintf(stderr, "opcode=0x%08x\n", insn->opcode);
958         fprintf(stderr, "reloc = %s\n", Reloc[insn->reloc]);
959         fprintf(stderr, "exp =  {\n");
960         fprintf(stderr, "\t\tX_add_symbol = %s\n",
961                 insn->exp.X_add_symbol ?
962                 (S_GET_NAME(insn->exp.X_add_symbol) ?
963                  S_GET_NAME(insn->exp.X_add_symbol) : "???") : "0");
964         fprintf(stderr, "\t\tX_sub_symbol = %s\n",
965                 insn->exp.X_subtract_symbol ?
966                 (S_GET_NAME(insn->exp.X_subtract_symbol) ?
967                  S_GET_NAME(insn->exp.X_subtract_symbol) : "???") : "0");
968         fprintf(stderr, "\t\tX_add_number = %d\n",
969                 insn->exp.X_add_number);
970         fprintf(stderr, "}\n");
971         return;
972 }
973 #endif
974
975 /* Translate internal representation of relocation info to target format.
976
977    On sparc/29k: first 4 bytes are normal unsigned long address, next three
978    bytes are index, most sig. byte first.  Byte 7 is broken up with
979    bit 7 as external, bits 6 & 5 unused, and the lower
980    five bits as relocation type.  Next 4 bytes are long addend. */
981 /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
982
983 #ifdef OBJ_AOUT
984
985 void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
986 char *where;
987 fixS *fixP;
988 relax_addressT segment_address_in_file;
989 {
990         long r_symbolnum;
991
992         know(fixP->fx_r_type < NO_RELOC);
993         know(fixP->fx_addsy != NULL);
994
995         md_number_to_chars(where,
996                            fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
997                            4);
998
999         r_symbolnum = (S_IS_DEFINED(fixP->fx_addsy)
1000                        ? S_GET_TYPE(fixP->fx_addsy)
1001                        : fixP->fx_addsy->sy_number);
1002
1003         where[4] = (r_symbolnum >> 16) & 0x0ff;
1004         where[5] = (r_symbolnum >> 8) & 0x0ff;
1005         where[6] = r_symbolnum & 0x0ff;
1006         where[7] = (((!S_IS_DEFINED(fixP->fx_addsy)) << 7)  & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F);
1007         /* Also easy */
1008         md_number_to_chars(&where[8], fixP->fx_addnumber, 4);
1009
1010         return;
1011 } /* tc_aout_fix_to_chars() */
1012
1013 #endif /* OBJ_AOUT */
1014
1015 int
1016     md_parse_option(argP,cntP,vecP)
1017 char **argP;
1018 int *cntP;
1019 char ***vecP;
1020 {
1021         return(0);
1022 }
1023
1024
1025 /* Default the values of symbols known that should be "predefined".  We
1026    don't bother to predefine them unless you actually use one, since there
1027    are a lot of them.  */
1028
1029 symbolS *md_undefined_symbol (name)
1030 char *name;
1031 {
1032         long regnum;
1033         char testbuf[5+ /*SLOP*/ 5];
1034
1035         if (name[0] == 'g' || name[0] == 'G' || name[0] == 'l' || name[0] == 'L')
1036             {
1037                     /* Perhaps a global or local register name */
1038                     if (name[1] == 'r' || name[1] == 'R')
1039                         {
1040                                 /* Parse the number, make sure it has no extra zeroes or trailing
1041                                    chars */
1042                                 regnum = atol(&name[2]);
1043                                 if (regnum > 127)
1044                                     return 0;
1045                                 sprintf(testbuf, "%ld", regnum);
1046                                 if (strcmp (testbuf, &name[2]) != 0)
1047                                     return 0;   /* gr007 or lr7foo or whatever */
1048
1049                                 /* We have a wiener!  Define and return a new symbol for it.  */
1050                                 if (name[0] == 'l' || name[0] == 'L')
1051                                     regnum += 128;
1052                                 return(symbol_new(name, SEG_REGISTER, regnum, &zero_address_frag));
1053                         }
1054             }
1055
1056         return 0;
1057 }
1058
1059 /* Parse an operand that is machine-specific.  */
1060
1061 void md_operand(expressionP)
1062 expressionS *expressionP;
1063 {
1064
1065         if (input_line_pointer[0] == '%' && input_line_pointer[1] == '%')
1066             {
1067                     /* We have a numeric register expression.  No biggy.  */
1068                     input_line_pointer += 2;    /* Skip %% */
1069                     (void)expression (expressionP);
1070                     if (expressionP->X_seg != SEG_ABSOLUTE
1071                         || expressionP->X_add_number > 255)
1072                         as_bad("Invalid expression after %%%%\n");
1073                     expressionP->X_seg = SEG_REGISTER;
1074             }
1075         else if (input_line_pointer[0] == '&')
1076             {
1077                     /* We are taking the 'address' of a register...this one is not
1078                        in the manual, but it *is* in traps/fpsymbol.h!  What they
1079                        seem to want is the register number, as an absolute number.  */
1080                     input_line_pointer++;               /* Skip & */
1081                     (void)expression (expressionP);
1082                     if (expressionP->X_seg != SEG_REGISTER)
1083                         as_bad("Invalid register in & expression");
1084                     else
1085                         expressionP->X_seg = SEG_ABSOLUTE;
1086             }
1087 }
1088
1089 /* Round up a section size to the appropriate boundary.  */
1090 long
1091     md_section_align (segment, size)
1092 segT segment;
1093 long size;
1094 {
1095         return size;            /* Byte alignment is fine */
1096 }
1097
1098 /* Exactly what point is a PC-relative offset relative TO?
1099    On the 29000, they're relative to the address of the instruction,
1100    which we have set up as the address of the fixup too.  */
1101 long md_pcrel_from (fixP)
1102 fixS *fixP;
1103 {
1104         return fixP->fx_where + fixP->fx_frag->fr_address;
1105 }
1106
1107 /*
1108  * Local Variables:
1109  * comment-column: 0
1110  * End:
1111  */
1112
1113 /* end of tc-a29k.c */