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