* no more relocation_info structures. We now squirt directly from
[deliverable/binutils-gdb.git] / gas / config / tc-a29k.c
CommitLineData
fecd2382
RP
1/* tc-a29k.c -- Assemble for the AMD 29000.
2 Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
3
4This file is part of GAS, the GNU Assembler.
5
6GAS is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
6026cd06 8the Free Software Foundation; either version 2, or (at your option)
fecd2382
RP
9any later version.
10
11GAS is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GAS; see the file COPYING. If not, write to
18the 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
36const 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 */
44static struct hash_control *op_hash = NULL;
45
46struct 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); */
59static void machine_ip(char *str);
60/* static void print_insn(struct machine_it *insn); */
61static void s_data1(void);
62static void s_use(void);
63
64#else /* __STDC__ */
65
66/* static int getExpression(); */
67static void machine_ip();
68/* static void print_insn(); */
69static void s_data1();
70static void s_use();
71
72#endif /* __STDC__ */
73
74const pseudo_typeS
75md_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
89int md_short_jump_size = 4;
90int md_long_jump_size = 4;
91int 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 */
95char 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 */
104char 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. */
108char line_separator_chars[] = "@";
109
110/* Chars that can be used to separate mant from exp in floating point nums */
111char EXP_CHARS[] = "eE";
112
113/* Chars that mean this number is a floating point constant */
114/* As in 0f12.456 */
115/* or 0d1.2345e12 */
116char 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
123static unsigned char octal[256];
124#define isoctal(c) octal[c]
125static 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
132static void
133s_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
165static void
166s_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
176static void
177insert_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
199void 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. */
237void
238md_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
321void 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
329void 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
356char *
357parse_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
395static void
396machine_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 abort();
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
678char *
679md_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 */
733void
734md_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 abort();
753 }
754 return;
755}
756
757void 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 abort(); /* 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 abort();
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
877short tc_coff_fix2rtype(fixP)
878fixS *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 */
896void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol)
897 char *ptr;
898 long from_addr, to_addr;
899fragS *frag;
900symbolS *to_symbol;
901{
902 fprintf(stderr, "a29k_create_short_jmp\n");
903 abort();
904}
905
fecd2382 906/* should never be called for 29k */
f6e504fe
RP
907void md_convert_frag(headers, fragP)
908object_headers *headers;
fecd2382
RP
909 register fragS *fragP;
910{
911 fprintf(stderr, "sparc_convert_frag\n");
912 abort();
913}
914
915/* should never be called for 29k */
916void md_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol)
917 char *ptr;
918 long from_addr,
919 to_addr;
920 fragS *frag;
921 symbolS *to_symbol;
922{
923 fprintf(stderr, "sparc_create_long_jump\n");
924 abort();
925}
926
927/* should never be called for sparc */
928int md_estimate_size_before_relax(fragP, segtype)
929 register fragS *fragP;
930segT segtype;
931{
932 fprintf(stderr, "sparc_estimate_size_before_relax\n");
933 abort();
934 return 0;
935}
936
937#if 0
938/* for debugging only */
939static void
940print_insn(insn)
941 struct machine_it *insn;
942{
943 char *Reloc[] = {
944 "RELOC_8",
945 "RELOC_16",
946 "RELOC_32",
947 "RELOC_DISP8",
948 "RELOC_DISP16",
949 "RELOC_DISP32",
950 "RELOC_WDISP30",
951 "RELOC_WDISP22",
952 "RELOC_HI22",
953 "RELOC_22",
954 "RELOC_13",
955 "RELOC_LO10",
956 "RELOC_SFA_BASE",
957 "RELOC_SFA_OFF13",
958 "RELOC_BASE10",
959 "RELOC_BASE13",
960 "RELOC_BASE22",
961 "RELOC_PC10",
962 "RELOC_PC22",
963 "RELOC_JMP_TBL",
964 "RELOC_SEGOFF16",
965 "RELOC_GLOB_DAT",
966 "RELOC_JMP_SLOT",
967 "RELOC_RELATIVE",
968 "NO_RELOC"
969 };
970
971 if (insn->error) {
972 fprintf(stderr, "ERROR: %s\n");
973 }
974 fprintf(stderr, "opcode=0x%08x\n", insn->opcode);
975 fprintf(stderr, "reloc = %s\n", Reloc[insn->reloc]);
976 fprintf(stderr, "exp = {\n");
977 fprintf(stderr, "\t\tX_add_symbol = %s\n",
978 insn->exp.X_add_symbol ?
979 (S_GET_NAME(insn->exp.X_add_symbol) ?
980 S_GET_NAME(insn->exp.X_add_symbol) : "???") : "0");
981 fprintf(stderr, "\t\tX_sub_symbol = %s\n",
982 insn->exp.X_subtract_symbol ?
983 (S_GET_NAME(insn->exp.X_subtract_symbol) ?
984 S_GET_NAME(insn->exp.X_subtract_symbol) : "???") : "0");
985 fprintf(stderr, "\t\tX_add_number = %d\n",
986 insn->exp.X_add_number);
987 fprintf(stderr, "}\n");
988 return;
989}
990#endif
991
a79c6033 992/* Translate internal representation of relocation info to target format.
fecd2382 993
a79c6033
RP
994 On sparc/29k: first 4 bytes are normal unsigned long address, next three
995 bytes are index, most sig. byte first. Byte 7 is broken up with
996 bit 7 as external, bits 6 & 5 unused, and the lower
997 five bits as relocation type. Next 4 bytes are long addend. */
998/* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
fecd2382 999
a79c6033 1000#ifdef OBJ_AOUT
fecd2382 1001
a79c6033
RP
1002void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
1003char *where;
1004fixS *fixP;
1005relax_addressT segment_address_in_file;
1006{
1007 long r_index;
1008
1009 know(fixP->fx_r_type < NO_RELOC);
1010 know(fixP->fx_addsy != NULL);
1011
1012 r_index = (S_IS_DEFINED(fixP->fx_addsy)
1013 ? S_GET_TYPE(fixP->fx_addsy)
1014 : fixP->fx_addsy->sy_number);
1015
1016 /* this is easy */
1017 md_number_to_chars(where,
1018 fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
1019 4);
1020
1021 /* now the fun stuff */
1022 where[4] = (r_index >> 16) & 0x0ff;
1023 where[5] = (r_index >> 8) & 0x0ff;
1024 where[6] = r_index & 0x0ff;
1025 where[7] = (((!S_IS_DEFINED(fixP->fx_addsy)) << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F);
1026 /* Also easy */
1027 md_number_to_chars(&where[8], fixP->fx_addnumber, 4);
fecd2382 1028
a79c6033
RP
1029 return;
1030} /* tc_aout_fix_to_chars() */
fecd2382
RP
1031
1032#endif /* OBJ_AOUT */
1033
1034int
1035md_parse_option(argP,cntP,vecP)
1036 char **argP;
1037 int *cntP;
1038 char ***vecP;
1039{
1040 return 1;
1041}
1042
1043
1044/* Default the values of symbols known that should be "predefined". We
1045 don't bother to predefine them unless you actually use one, since there
1046 are a lot of them. */
1047
1048symbolS *md_undefined_symbol (name)
1049 char *name;
1050{
1051 long regnum;
1052 char testbuf[5+ /*SLOP*/ 5];
1053
1054 if (name[0] == 'g' || name[0] == 'G' || name[0] == 'l' || name[0] == 'L')
1055 {
1056 /* Perhaps a global or local register name */
1057 if (name[1] == 'r' || name[1] == 'R')
1058 {
1059 /* Parse the number, make sure it has no extra zeroes or trailing
1060 chars */
1061 regnum = atol(&name[2]);
1062 if (regnum > 127)
1063 return 0;
1064 sprintf(testbuf, "%ld", regnum);
1065 if (strcmp (testbuf, &name[2]) != 0)
1066 return 0; /* gr007 or lr7foo or whatever */
1067
1068 /* We have a wiener! Define and return a new symbol for it. */
1069 if (name[0] == 'l' || name[0] == 'L')
1070 regnum += 128;
1071 return(symbol_new(name, SEG_REGISTER, regnum, &zero_address_frag));
1072 }
1073 }
1074
1075 return 0;
1076}
1077
1078/* Parse an operand that is machine-specific. */
1079
1080void md_operand(expressionP)
1081 expressionS *expressionP;
1082{
1083
1084 if (input_line_pointer[0] == '%' && input_line_pointer[1] == '%')
1085 {
1086 /* We have a numeric register expression. No biggy. */
1087 input_line_pointer += 2; /* Skip %% */
1088 (void)expression (expressionP);
1089 if (expressionP->X_seg != SEG_ABSOLUTE
1090 || expressionP->X_add_number > 255)
1091 as_bad("Invalid expression after %%%%\n");
1092 expressionP->X_seg = SEG_REGISTER;
1093 }
1094 else if (input_line_pointer[0] == '&')
1095 {
1096 /* We are taking the 'address' of a register...this one is not
1097 in the manual, but it *is* in traps/fpsymbol.h! What they
1098 seem to want is the register number, as an absolute number. */
1099 input_line_pointer++; /* Skip & */
1100 (void)expression (expressionP);
1101 if (expressionP->X_seg != SEG_REGISTER)
1102 as_bad("Invalid register in & expression");
1103 else
1104 expressionP->X_seg = SEG_ABSOLUTE;
1105 }
1106}
1107
1108/* Round up a section size to the appropriate boundary. */
1109long
1110md_section_align (segment, size)
1111 segT segment;
1112 long size;
1113{
1114 return size; /* Byte alignment is fine */
1115}
1116
1117/* Exactly what point is a PC-relative offset relative TO?
1118 On the 29000, they're relative to the address of the instruction,
1119 which we have set up as the address of the fixup too. */
1120long md_pcrel_from (fixP)
1121 fixS *fixP;
1122{
1123 return fixP->fx_where + fixP->fx_frag->fr_address;
1124}
1125
1126/*
1127 * Local Variables:
1128 * comment-column: 0
1129 * End:
1130 */
1131
1132/* end of tc-a29k.c */
This page took 0.068728 seconds and 4 git commands to generate.