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