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