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