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