Add a note to the GDB/NEWS file mentioning that the ARM simulator now
[deliverable/binutils-gdb.git] / gas / config / tc-or32.c
CommitLineData
3b16e843 1/* Assembly backend for the OpenRISC 1000.
4b95cf5c 2 Copyright (C) 2002-2014 Free Software Foundation, Inc.
3b16e843
NC
3 Contributed by Damjan Lampret <lampret@opencores.org>.
4 Modified bu Johan Rydberg, <johan.rydberg@netinsight.se>.
5 Based upon a29k port.
6
7 This file is part of GAS, the GNU Assembler.
8
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
ec2655a6 11 the Free Software Foundation; either version 3, or (at your option)
3b16e843
NC
12 any later version.
13
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to
4b4da160
NC
21 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
22 Boston, MA 02110-1301, USA. */
3b16e843
NC
23
24/* tc-a29k.c used as a template. */
25
3b16e843 26#include "as.h"
df7b86aa 27#include "safe-ctype.h"
3b16e843 28#include "opcode/or32.h"
5d6255fe 29#include "elf/or32.h"
3b16e843
NC
30
31#define DEBUG 0
32
33#ifndef REGISTER_PREFIX
34#define REGISTER_PREFIX '%'
35#endif
36
37/* Make it easier to clone this machine desc into another one. */
38#define machine_opcode or32_opcode
39#define machine_opcodes or32_opcodes
40#define machine_ip or32_ip
41#define machine_it or32_it
42
43/* Handle of the OPCODE hash table. */
44static struct hash_control *op_hash = NULL;
45
46struct machine_it
ea1562b3
NC
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 int reloc;
55}
3b16e843
NC
56the_insn;
57
3b16e843 58const pseudo_typeS md_pseudo_table[] =
ea1562b3
NC
59{
60 {"align", s_align_bytes, 4 },
61 {"space", s_space, 0 },
62 {"cputype", s_ignore, 0 },
63 {"reg", s_lsym, 0 }, /* Register equate, same as equ. */
64 {"sect", s_ignore, 0 }, /* Creation of coff sections. */
65 {"proc", s_ignore, 0 }, /* Start of a function. */
66 {"endproc", s_ignore, 0 }, /* Function end. */
67 {"word", cons, 4 },
68 {NULL, 0, 0 },
69};
3b16e843
NC
70
71int md_short_jump_size = 4;
72int md_long_jump_size = 4;
73
3b16e843
NC
74/* This array holds the chars that always start a comment.
75 If the pre-processor is disabled, these aren't very useful. */
76const char comment_chars[] = "#";
77
78/* This array holds the chars that only start a comment at the beginning of
79 a line. If the line seems to have the form '# 123 filename'
80 .line and .file directives will appear in the pre-processed output. */
81/* Note that input_file.c hand checks for '#' at the beginning of the
82 first line of the input file. This is because the compiler outputs
83 #NO_APP at the beginning of its output. */
84/* Also note that comments like this one will always work. */
85const char line_comment_chars[] = "#";
86
87/* We needed an unused char for line separation to work around the
88 lack of macros, using sed and such. */
89const char line_separator_chars[] = ";";
90
91/* Chars that can be used to separate mant from exp in floating point nums. */
92const char EXP_CHARS[] = "eE";
93
94/* Chars that mean this number is a floating point constant.
95 As in 0f12.456
96 or 0d1.2345e12. */
97const char FLT_CHARS[] = "rRsSfFdDxXpP";
98
99/* "l.jalr r9" precalculated opcode. */
100static unsigned long jalr_r9_opcode;
101
ea1562b3 102static void machine_ip (char *);
3b16e843 103
3b16e843
NC
104
105/* Set bits in machine opcode according to insn->encoding
5d6255fe 106 description and passed operand. */
3b16e843 107
5d6255fe 108static void
ea1562b3
NC
109encode (const struct machine_opcode *insn,
110 unsigned long *opcode,
111 signed long param_val,
112 char param_ch)
3b16e843
NC
113{
114 int opc_pos = 0;
115 int param_pos = 0;
116 char *enc;
117
118#if DEBUG
119 printf (" encode: opcode=%.8lx param_val=%.8lx abs=%.8lx param_ch=%c\n",
120 *opcode, param_val, abs (param_val), param_ch);
121#endif
122 for (enc = insn->encoding; *enc != '\0'; enc++)
123 if (*enc == param_ch)
124 {
125 if (enc - 2 >= insn->encoding && (*(enc - 2) == '0') && (*(enc - 1) == 'x'))
126 continue;
127 else
128 param_pos ++;
129 }
130
131 opc_pos = 32;
132
133 for (enc = insn->encoding; *enc != '\0';)
134 {
5d6255fe 135 if ((*enc == '0') && (*(enc + 1) == 'x'))
3b16e843
NC
136 {
137 int tmp = strtol (enc, NULL, 16);
138
139 opc_pos -= 4;
140 *opcode |= tmp << opc_pos;
141 enc += 3;
142 }
5d6255fe 143 else if ((*enc == '0') || (*enc == '-'))
3b16e843
NC
144 {
145 opc_pos--;
146 enc++;
147 }
5d6255fe 148 else if (*enc == '1')
3b16e843
NC
149 {
150 opc_pos--;
151 *opcode |= 1 << opc_pos;
152 enc++;
153 }
5d6255fe 154 else if (*enc == param_ch)
3b16e843
NC
155 {
156 opc_pos--;
157 param_pos--;
158 *opcode |= ((param_val >> param_pos) & 0x1) << opc_pos;
159 enc++;
160 }
5d6255fe 161 else if (ISALPHA (*enc))
3b16e843
NC
162 {
163 opc_pos--;
164 enc++;
165 }
166 else
167 enc++;
168 }
5d6255fe 169
3b16e843
NC
170#if DEBUG
171 printf (" opcode=%.8lx\n", *opcode);
172#endif
173}
174
175/* This function is called once, at assembler startup time. It should
176 set up all the tables, etc., that the MD part of the assembler will
177 need. */
178
179void
ea1562b3 180md_begin (void)
3b16e843
NC
181{
182 const char *retval = NULL;
183 int lose = 0;
184 int skipnext = 0;
185 unsigned int i;
186
187 /* Hash up all the opcodes for fast use later. */
188 op_hash = hash_new ();
189
190 for (i = 0; i < or32_num_opcodes; i++)
191 {
192 const char *name = machine_opcodes[i].name;
193
194 if (skipnext)
195 {
196 skipnext = 0;
197 continue;
198 }
199
ea1562b3 200 retval = hash_insert (op_hash, name, (void *) &machine_opcodes[i]);
3b16e843
NC
201 if (retval != NULL)
202 {
203 fprintf (stderr, "internal error: can't hash `%s': %s\n",
204 machine_opcodes[i].name, retval);
205 lose = 1;
206 }
207 }
208
209 if (lose)
210 as_fatal (_("Broken assembler. No assembly attempted."));
211
212 encode (&machine_opcodes[insn_index ("l.jalr")], &jalr_r9_opcode, 9, 'B');
213}
214
67c1ffbe 215/* Returns non zero if instruction is to be used. */
3b16e843
NC
216
217static int
ea1562b3 218check_invalid_opcode (unsigned long opcode)
3b16e843
NC
219{
220 return opcode == jalr_r9_opcode;
221}
222
223/* Assemble a single instruction. Its label has already been handled
224 by the generic front end. We just parse opcode and operands, and
225 produce the bytes of data and relocation. */
226
227void
ea1562b3 228md_assemble (char *str)
3b16e843
NC
229{
230 char *toP;
231
232#if DEBUG
233 printf ("NEW INSTRUCTION\n");
234#endif
235
236 know (str);
237 machine_ip (str);
238 toP = frag_more (4);
239
240 /* Put out the opcode. */
241 md_number_to_chars (toP, the_insn.opcode, 4);
242
243 /* Put out the symbol-dependent stuff. */
3b16e843 244 if (the_insn.reloc != BFD_RELOC_NONE)
3b16e843
NC
245 {
246 fix_new_exp (frag_now,
247 (toP - frag_now->fr_literal + the_insn.reloc_offset),
248 4, /* size */
249 &the_insn.exp,
250 the_insn.pcrel,
251 the_insn.reloc);
252 }
253}
254
255/* This is true of the we have issued a "lo(" or "hi"(. */
256static int waiting_for_shift = 0;
257
258static int mask_or_shift = 0;
259
3b16e843 260static char *
ea1562b3 261parse_operand (char *s, expressionS *operandp, int opt)
3b16e843
NC
262{
263 char *save = input_line_pointer;
d3ce72d0 264 char *new_pointer;
3b16e843
NC
265
266#if DEBUG
267 printf (" PROCESS NEW OPERAND(%s) == %c (%d)\n", s, opt ? opt : '!', opt);
268#endif
269
270 input_line_pointer = s;
271
272 if (strncasecmp (s, "HI(", 3) == 0)
273 {
274 waiting_for_shift = 1;
275 mask_or_shift = BFD_RELOC_HI16;
276
277 input_line_pointer += 3;
278 }
279 else if (strncasecmp (s, "LO(", 3) == 0)
280 {
281 mask_or_shift = BFD_RELOC_LO16;
282
283 input_line_pointer += 3;
284 }
285 else
286 mask_or_shift = 0;
287
288 if ((*s == '(') && (*(s+1) == 'r'))
289 s++;
290
5d6255fe 291 if ((*s == 'r') && ISDIGIT (*(s + 1)))
3b16e843
NC
292 {
293 operandp->X_add_number = strtol (s + 1, NULL, 10);
294 operandp->X_op = O_register;
295 for (; (*s != ',') && (*s != '\0');)
5d6255fe 296 s++;
3b16e843 297 input_line_pointer = save;
5d6255fe 298 return s;
3b16e843
NC
299 }
300
301 expression (operandp);
302
303 if (operandp->X_op == O_absent)
304 {
305 if (! opt)
306 as_bad (_("missing operand"));
307 else
308 {
309 operandp->X_add_number = 0;
310 operandp->X_op = O_constant;
311 }
312 }
5d6255fe 313
d3ce72d0 314 new_pointer = input_line_pointer;
3b16e843 315 input_line_pointer = save;
5d6255fe 316
3b16e843 317#if DEBUG
d3ce72d0
NC
318 printf (" %s=parse_operand(%s): operandp->X_op = %u\n", new_pointer, s,
319 operandp->X_op);
3b16e843
NC
320#endif
321
d3ce72d0 322 return new_pointer;
3b16e843 323}
3b16e843
NC
324
325/* Instruction parsing. Takes a string containing the opcode.
326 Operands are at input_line_pointer. Output is in the_insn.
327 Warnings or errors are generated. */
328
3b16e843 329static void
ea1562b3 330machine_ip (char *str)
3b16e843
NC
331{
332 char *s;
333 const char *args;
334 const struct machine_opcode *insn;
3b16e843
NC
335 unsigned long opcode;
336 expressionS the_operand;
337 expressionS *operand = &the_operand;
338 unsigned int regno;
339 int reloc = BFD_RELOC_NONE;
340
341#if DEBUG
342 printf ("machine_ip(%s)\n", str);
343#endif
344
345 s = str;
346 for (; ISALNUM (*s) || *s == '.'; ++s)
347 if (ISUPPER (*s))
348 *s = TOLOWER (*s);
349
350 switch (*s)
351 {
352 case '\0':
353 break;
354
355 case ' ': /* FIXME-SOMEDAY more whitespace. */
356 *s++ = '\0';
357 break;
358
359 default:
360 as_bad (_("unknown opcode1: `%s'"), str);
361 return;
362 }
363
364 if ((insn = (struct machine_opcode *) hash_find (op_hash, str)) == NULL)
365 {
366 as_bad (_("unknown opcode2 `%s'."), str);
367 return;
368 }
369
3b16e843
NC
370 opcode = 0;
371 memset (&the_insn, '\0', sizeof (the_insn));
372 the_insn.reloc = BFD_RELOC_NONE;
373
374 reloc = BFD_RELOC_NONE;
375
376 /* Build the opcode, checking as we go to make sure that the
377 operands match.
5d6255fe 378
3b16e843
NC
379 If an operand matches, we modify the_insn or opcode appropriately,
380 and do a "continue". If an operand fails to match, we "break". */
381 if (insn->args[0] != '\0')
ea1562b3
NC
382 /* Prime the pump. */
383 s = parse_operand (s, operand, insn->args[0] == 'I');
3b16e843
NC
384
385 for (args = insn->args;; ++args)
386 {
387#if DEBUG
388 printf (" args = %s\n", args);
389#endif
390 switch (*args)
391 {
392 case '\0': /* End of args. */
393 /* We have have 0 args, do the bazoooka! */
394 if (args == insn->args)
395 encode (insn, &opcode, 0, 0);
396
397 if (*s == '\0')
398 {
399 /* We are truly done. */
400 the_insn.opcode = opcode;
401 if (check_invalid_opcode (opcode))
5d6255fe 402 as_bad (_("instruction not allowed: %s"), str);
3b16e843
NC
403 return;
404 }
405 as_bad (_("too many operands: %s"), s);
406 break;
407
408 case ',': /* Must match a comma. */
409 if (*s++ == ',')
410 {
411 reloc = BFD_RELOC_NONE;
412
413 /* Parse next operand. */
414 s = parse_operand (s, operand, args[1] == 'I');
415#if DEBUG
416 printf (" ',' case: operand->X_add_number = %d, *args = %s, *s = %s\n",
417 operand->X_add_number, args, s);
5d6255fe 418#endif
3b16e843
NC
419 continue;
420 }
421 break;
422
423 case '(': /* Must match a (. */
424 s = parse_operand (s, operand, args[1] == 'I');
425 continue;
5d6255fe 426
3b16e843
NC
427 case ')': /* Must match a ). */
428 continue;
429
430 case 'r': /* A general register. */
431 args++;
432
433 if (operand->X_op != O_register)
434 break; /* Only registers. */
5d6255fe 435
3b16e843
NC
436 know (operand->X_add_symbol == 0);
437 know (operand->X_op_symbol == 0);
438 regno = operand->X_add_number;
439 encode (insn, &opcode, regno, *args);
440#if DEBUG
441 printf (" r: operand->X_op = %d\n", operand->X_op);
442#endif
443 continue;
444
445 default:
446 /* if (! ISALPHA (*args))
447 break; */ /* Only immediate values. */
5d6255fe 448
3b16e843
NC
449 if (mask_or_shift)
450 {
451#if DEBUG
452 printf ("mask_or_shift = %d\n", mask_or_shift);
453#endif
454 reloc = mask_or_shift;
455 }
456 mask_or_shift = 0;
5d6255fe
KH
457
458 if (strncasecmp (args, "LO(", 3) == 0)
3b16e843
NC
459 {
460#if DEBUG
461 printf ("reloc_const\n");
462#endif
463 reloc = BFD_RELOC_LO16;
464 }
5d6255fe 465 else if (strncasecmp (args, "HI(", 3) == 0)
3b16e843
NC
466 {
467#if DEBUG
468 printf ("reloc_consth\n");
469#endif
470 reloc = BFD_RELOC_HI16;
471 }
5d6255fe
KH
472
473 if (*s == '(')
ea1562b3 474 operand->X_op = O_constant;
3b16e843
NC
475 else if (*s == ')')
476 s += 1;
477#if DEBUG
478 printf (" default case: operand->X_add_number = %d, *args = %s, *s = %s\n", operand->X_add_number, args, s);
479#endif
480 if (operand->X_op == O_constant)
481 {
482 if (reloc == BFD_RELOC_NONE)
483 {
484 bfd_vma v, mask;
485
486 mask = 0x3ffffff;
487 v = abs (operand->X_add_number) & ~ mask;
488 if (v)
489 as_bad (_("call/jmp target out of range (1)"));
490 }
491
492 if (reloc == BFD_RELOC_HI16)
493 operand->X_add_number = ((operand->X_add_number >> 16) & 0xffff);
494
495 the_insn.pcrel = 0;
496 encode (insn, &opcode, operand->X_add_number, *args);
497 /* the_insn.reloc = BFD_RELOC_NONE; */
5d6255fe 498 continue;
3b16e843
NC
499 }
500
501 if (reloc == BFD_RELOC_NONE)
502 the_insn.reloc = BFD_RELOC_32_GOT_PCREL;
503 else
504 the_insn.reloc = reloc;
505
506 /* the_insn.reloc = insn->reloc; */
507#if DEBUG
508 printf (" reloc sym=%d\n", the_insn.reloc);
509 printf (" BFD_RELOC_NONE=%d\n", BFD_RELOC_NONE);
510#endif
511 the_insn.exp = *operand;
5d6255fe 512
3b16e843
NC
513 /* the_insn.reloc_offset = 1; */
514 the_insn.pcrel = 1; /* Assume PC-relative jump. */
515
516 /* FIXME-SOON, Do we figure out whether abs later, after
517 know sym val? */
518 if (reloc == BFD_RELOC_LO16 || reloc == BFD_RELOC_HI16)
519 the_insn.pcrel = 0;
520
521 encode (insn, &opcode, operand->X_add_number, *args);
522 continue;
523 }
5d6255fe 524
3b16e843
NC
525 /* Types or values of args don't match. */
526 as_bad (_("invalid operands"));
527 return;
528 }
529}
530
3b16e843 531char *
ea1562b3 532md_atof (int type, char * litP, int * sizeP)
3b16e843 533{
499ac353 534 return ieee_md_atof (type, litP, sizeP, TRUE);
3b16e843
NC
535}
536
537/* Write out big-endian. */
538
539void
ea1562b3 540md_number_to_chars (char *buf, valueT val, int n)
3b16e843
NC
541{
542 number_to_chars_bigendian (buf, val, n);
543}
544
3b16e843 545void
55cf6793 546md_apply_fix (fixS * fixP, valueT * val, segT seg ATTRIBUTE_UNUSED)
3b16e843
NC
547{
548 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
549 long t_val;
550
551 t_val = (long) *val;
552
553#if DEBUG
554 printf ("md_apply_fix val:%x\n", t_val);
555#endif
556
557 fixP->fx_addnumber = t_val; /* Remember value for emit_reloc. */
558
3b16e843
NC
559 switch (fixP->fx_r_type)
560 {
561 case BFD_RELOC_32: /* XXXXXXXX pattern in a word. */
562#if DEBUG
563 printf ("reloc_const: val=%x\n", t_val);
564#endif
565 buf[0] = t_val >> 24;
566 buf[1] = t_val >> 16;
567 buf[2] = t_val >> 8;
568 buf[3] = t_val;
569 break;
570
571 case BFD_RELOC_16: /* XXXX0000 pattern in a word. */
572#if DEBUG
573 printf ("reloc_const: val=%x\n", t_val);
574#endif
575 buf[0] = t_val >> 8;
576 buf[1] = t_val;
577 break;
578
579 case BFD_RELOC_8: /* XX000000 pattern in a word. */
580#if DEBUG
581 printf ("reloc_const: val=%x\n", t_val);
582#endif
583 buf[0] = t_val;
584 break;
585
586 case BFD_RELOC_LO16: /* 0000XXXX pattern in a word. */
587#if DEBUG
588 printf ("reloc_const: val=%x\n", t_val);
589#endif
590 buf[2] = t_val >> 8; /* Holds bits 0000XXXX. */
591 buf[3] = t_val;
592 break;
593
594 case BFD_RELOC_HI16: /* 0000XXXX pattern in a word. */
595#if DEBUG
596 printf ("reloc_consth: val=%x\n", t_val);
597#endif
598 buf[2] = t_val >> 24; /* Holds bits XXXX0000. */
599 buf[3] = t_val >> 16;
600 break;
601
602 case BFD_RELOC_32_GOT_PCREL: /* 0000XXXX pattern in a word. */
603 if (!fixP->fx_done)
65ec77d2 604 ;
3b16e843
NC
605 else if (fixP->fx_pcrel)
606 {
607 long v = t_val >> 28;
608
609 if (v != 0 && v != -1)
610 as_bad_where (fixP->fx_file, fixP->fx_line,
611 _("call/jmp target out of range (2)"));
612 }
613 else
614 /* This case was supposed to be handled in machine_ip. */
615 abort ();
616
617 buf[0] |= (t_val >> 26) & 0x03; /* Holds bits 0FFFFFFC of address. */
618 buf[1] = t_val >> 18;
619 buf[2] = t_val >> 10;
620 buf[3] = t_val >> 2;
621 break;
622
623 case BFD_RELOC_VTABLE_INHERIT:
624 case BFD_RELOC_VTABLE_ENTRY:
625 fixP->fx_done = 0;
626 break;
627
628 case BFD_RELOC_NONE:
629 default:
630 as_bad (_("bad relocation type: 0x%02x"), fixP->fx_r_type);
631 break;
632 }
633
634 if (fixP->fx_addsy == (symbolS *) NULL)
635 fixP->fx_done = 1;
636}
3b16e843
NC
637
638/* Should never be called for or32. */
639
640void
ea1562b3
NC
641md_create_short_jump (char * ptr ATTRIBUTE_UNUSED,
642 addressT from_addr ATTRIBUTE_UNUSED,
643 addressT to_addr ATTRIBUTE_UNUSED,
644 fragS * frag ATTRIBUTE_UNUSED,
645 symbolS * to_symbol ATTRIBUTE_UNUSED)
3b16e843
NC
646{
647 as_fatal ("or32_create_short_jmp\n");
648}
649
650/* Should never be called for or32. */
651
3b16e843 652void
ea1562b3
NC
653md_convert_frag (bfd * headers ATTRIBUTE_UNUSED,
654 segT seg ATTRIBUTE_UNUSED,
655 fragS * fragP ATTRIBUTE_UNUSED)
3b16e843
NC
656{
657 as_fatal ("or32_convert_frag\n");
5d6255fe 658}
3b16e843
NC
659
660/* Should never be called for or32. */
661
662void
ea1562b3
NC
663md_create_long_jump (char * ptr ATTRIBUTE_UNUSED,
664 addressT from_addr ATTRIBUTE_UNUSED,
665 addressT to_addr ATTRIBUTE_UNUSED,
666 fragS * frag ATTRIBUTE_UNUSED,
667 symbolS * to_symbol ATTRIBUTE_UNUSED)
3b16e843
NC
668{
669 as_fatal ("or32_create_long_jump\n");
670}
671
672/* Should never be called for or32. */
673
674int
ea1562b3
NC
675md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
676 segT segtype ATTRIBUTE_UNUSED)
3b16e843
NC
677{
678 as_fatal ("or32_estimate_size_before_relax\n");
679 return 0;
680}
681
682/* Translate internal representation of relocation info to target format.
683
684 On sparc/29k: first 4 bytes are normal unsigned long address, next three
685 bytes are index, most sig. byte first. Byte 7 is broken up with
686 bit 7 as external, bits 6 & 5 unused, and the lower
687 five bits as relocation type. Next 4 bytes are long addend. */
688/* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com. */
689
690#ifdef OBJ_AOUT
691void
ea1562b3
NC
692tc_aout_fix_to_chars (char *where,
693 fixS *fixP,
694 relax_addressT segment_address_in_file)
3b16e843
NC
695{
696 long r_symbolnum;
697
698#if DEBUG
699 printf ("tc_aout_fix_to_chars\n");
5d6255fe 700#endif
3b16e843
NC
701
702 know (fixP->fx_r_type < BFD_RELOC_NONE);
703 know (fixP->fx_addsy != NULL);
704
705 md_number_to_chars
706 (where,
707 fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
708 4);
709
710 r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
711 ? S_GET_TYPE (fixP->fx_addsy)
712 : fixP->fx_addsy->sy_number);
713
714 where[4] = (r_symbolnum >> 16) & 0x0ff;
715 where[5] = (r_symbolnum >> 8) & 0x0ff;
716 where[6] = r_symbolnum & 0x0ff;
717 where[7] = (((!S_IS_DEFINED (fixP->fx_addsy)) << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F);
718
719 /* Also easy. */
720 md_number_to_chars (&where[8], fixP->fx_addnumber, 4);
721}
722
723#endif /* OBJ_AOUT */
724\f
725const char *md_shortopts = "";
726
727struct option md_longopts[] =
ea1562b3
NC
728{
729 { NULL, no_argument, NULL, 0 }
730};
3b16e843
NC
731size_t md_longopts_size = sizeof (md_longopts);
732
733int
ea1562b3 734md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED)
3b16e843
NC
735{
736 return 0;
737}
738
739void
ea1562b3 740md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
3b16e843
NC
741{
742}
743\f
744/* This is called when a line is unrecognized. This is used to handle
745 definitions of or32 style local labels. */
746
747int
ea1562b3 748or32_unrecognized_line (int c)
3b16e843
NC
749{
750 int lab;
751 char *s;
752
753 if (c != '$'
754 || ! ISDIGIT ((unsigned char) input_line_pointer[0]))
755 return 0;
756
757 s = input_line_pointer;
758
759 lab = 0;
760 while (ISDIGIT ((unsigned char) *s))
761 {
762 lab = lab * 10 + *s - '0';
763 ++s;
764 }
765
766 if (*s != ':')
767 /* Not a label definition. */
768 return 0;
769
770 if (dollar_label_defined (lab))
771 {
772 as_bad (_("label \"$%d\" redefined"), lab);
773 return 0;
774 }
775
776 define_dollar_label (lab);
777 colon (dollar_label_name (lab, 0));
778 input_line_pointer = s + 1;
779
780 return 1;
781}
782
3b16e843
NC
783/* Default the values of symbols known that should be "predefined". We
784 don't bother to predefine them unless you actually use one, since there
785 are a lot of them. */
786
787symbolS *
ea1562b3 788md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
3b16e843 789{
3b16e843
NC
790 return NULL;
791}
792
793/* Parse an operand that is machine-specific. */
794
795void
ea1562b3 796md_operand (expressionS *expressionP)
3b16e843
NC
797{
798#if DEBUG
799 printf (" md_operand(input_line_pointer = %s)\n", input_line_pointer);
800#endif
801
802 if (input_line_pointer[0] == REGISTER_PREFIX && input_line_pointer[1] == 'r')
803 {
804 /* We have a numeric register expression. No biggy. */
805 input_line_pointer += 2; /* Skip %r */
806 (void) expression (expressionP);
807
808 if (expressionP->X_op != O_constant
809 || expressionP->X_add_number > 255)
810 as_bad (_("Invalid expression after %%%%\n"));
811 expressionP->X_op = O_register;
812 }
813 else if (input_line_pointer[0] == '&')
814 {
815 /* We are taking the 'address' of a register...this one is not
816 in the manual, but it *is* in traps/fpsymbol.h! What they
817 seem to want is the register number, as an absolute number. */
818 input_line_pointer++; /* Skip & */
819 (void) expression (expressionP);
820
821 if (expressionP->X_op != O_register)
822 as_bad (_("invalid register in & expression"));
823 else
824 expressionP->X_op = O_constant;
825 }
826 else if (input_line_pointer[0] == '$'
827 && ISDIGIT ((unsigned char) input_line_pointer[1]))
828 {
829 long lab;
830 char *name;
831 symbolS *sym;
5d6255fe 832
3b16e843
NC
833 /* This is a local label. */
834 ++input_line_pointer;
835 lab = (long) get_absolute_expression ();
836
837 if (dollar_label_defined (lab))
838 {
839 name = dollar_label_name (lab, 0);
840 sym = symbol_find (name);
841 }
842 else
843 {
844 name = dollar_label_name (lab, 1);
845 sym = symbol_find_or_make (name);
846 }
847
848 expressionP->X_op = O_symbol;
849 expressionP->X_add_symbol = sym;
850 expressionP->X_add_number = 0;
851 }
852 else if (input_line_pointer[0] == '$')
853 {
854 char *s;
855 char type;
856 int fieldnum, fieldlimit;
857 LITTLENUM_TYPE floatbuf[8];
858
859 /* $float(), $doubleN(), or $extendN() convert floating values
860 to integers. */
861 s = input_line_pointer;
862
863 ++s;
864
865 fieldnum = 0;
866 if (strncmp (s, "double", sizeof "double" - 1) == 0)
867 {
868 s += sizeof "double" - 1;
869 type = 'd';
870 fieldlimit = 2;
871 }
872 else if (strncmp (s, "float", sizeof "float" - 1) == 0)
873 {
874 s += sizeof "float" - 1;
875 type = 'f';
876 fieldlimit = 1;
877 }
878 else if (strncmp (s, "extend", sizeof "extend" - 1) == 0)
879 {
880 s += sizeof "extend" - 1;
881 type = 'x';
882 fieldlimit = 4;
883 }
5d6255fe 884 else
3b16e843
NC
885 return;
886
887 if (ISDIGIT (*s))
888 {
889 fieldnum = *s - '0';
890 ++s;
891 }
892 if (fieldnum >= fieldlimit)
893 return;
894
895 SKIP_WHITESPACE ();
896 if (*s != '(')
897 return;
898 ++s;
899 SKIP_WHITESPACE ();
900
901 s = atof_ieee (s, type, floatbuf);
902 if (s == NULL)
903 return;
904 s = s;
905
906 SKIP_WHITESPACE ();
907 if (*s != ')')
908 return;
909 ++s;
910 SKIP_WHITESPACE ();
911
912 input_line_pointer = s;
5d6255fe 913 expressionP->X_op = O_constant;
3b16e843
NC
914 expressionP->X_unsigned = 1;
915 expressionP->X_add_number = ((floatbuf[fieldnum * 2]
916 << LITTLENUM_NUMBER_OF_BITS)
917 + floatbuf[fieldnum * 2 + 1]);
918 }
919}
920
921/* Round up a section size to the appropriate boundary. */
922
923valueT
ea1562b3 924md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size ATTRIBUTE_UNUSED)
3b16e843
NC
925{
926 return size; /* Byte alignment is fine. */
927}
928
929/* Exactly what point is a PC-relative offset relative TO?
930 On the 29000, they're relative to the address of the instruction,
931 which we have set up as the address of the fixup too. */
932
933long
ea1562b3 934md_pcrel_from (fixS *fixP)
3b16e843
NC
935{
936 return fixP->fx_where + fixP->fx_frag->fr_address;
937}
938
939/* Generate a reloc for a fixup. */
940
3b16e843 941arelent *
ea1562b3 942tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
3b16e843
NC
943{
944 arelent *reloc;
945
ea1562b3
NC
946 reloc = xmalloc (sizeof (arelent));
947 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3b16e843
NC
948 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
949 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
950 /* reloc->address = fixp->fx_frag->fr_address + fixp->fx_where + fixp->fx_addnumber;*/
951 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
952
953 if (reloc->howto == (reloc_howto_type *) NULL)
954 {
955 as_bad_where (fixp->fx_file, fixp->fx_line,
956 _("reloc %d not supported by object file format"),
957 (int) fixp->fx_r_type);
958 return NULL;
959 }
960
a161fe53
AM
961 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
962 reloc->address = fixp->fx_offset;
3b16e843 963
a161fe53 964 reloc->addend = fixp->fx_addnumber;
3b16e843
NC
965 return reloc;
966}
This page took 0.705643 seconds and 4 git commands to generate.