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