2003-05-23 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gas / config / tc-i860.c
... / ...
CommitLineData
1/* tc-i860.c -- Assembler for the Intel i860 architecture.
2 Copyright 1989, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4
5 Brought back from the dead and completely reworked
6 by Jason Eckhardt <jle@cygnus.com>.
7
8 This file is part of GAS, the GNU Assembler.
9
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License along
21 with GAS; see the file COPYING. If not, write to the Free Software
22 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23
24#include <stdio.h>
25#include <string.h>
26#include "as.h"
27#include "safe-ctype.h"
28#include "subsegs.h"
29#include "opcode/i860.h"
30#include "elf/i860.h"
31
32/* Defined by default since this is primarily a SVR4/860 assembler.
33 However, I'm trying to leave the door open for Intel syntax. Of course,
34 if full support for anything other than SVR4 is done, then we should
35 select this based on a command-line flag. */
36#define SYNTAX_SVR4
37
38/* The opcode hash table. */
39static struct hash_control *op_hash = NULL;
40
41/* These characters always start a comment. */
42const char comment_chars[] = "#!/";
43
44/* These characters start a comment at the beginning of a line. */
45const char line_comment_chars[] = "#/";
46
47const char line_separator_chars[] = ";";
48
49/* Characters that can be used to separate the mantissa from the exponent
50 in floating point numbers. */
51const char EXP_CHARS[] = "eE";
52
53/* Characters that indicate this number is a floating point constant.
54 As in 0f12.456 or 0d1.2345e12. */
55const char FLT_CHARS[] = "rRsSfFdDxXpP";
56
57/* Register prefix. */
58#ifdef SYNTAX_SVR4
59static const char reg_prefix = '%';
60#else
61static const char reg_prefix = 0;
62#endif
63
64#define MAX_FIXUPS 2
65
66struct i860_it
67{
68 char *error;
69 unsigned long opcode;
70 enum expand_type expand;
71 struct i860_fi
72 {
73 expressionS exp;
74 bfd_reloc_code_real_type reloc;
75 int pcrel;
76 valueT fup;
77 } fi[MAX_FIXUPS];
78} the_insn;
79
80/* The current fixup count. */
81static int fc;
82
83static char *expr_end;
84
85/* Indicates error if a pseudo operation was expanded after a branch. */
86static char last_expand;
87
88/* If true, then warn if any pseudo operations were expanded. */
89static int target_warn_expand = 0;
90
91/* Prototypes. */
92static void i860_process_insn PARAMS ((char *));
93static void s_dual PARAMS ((int));
94static void s_enddual PARAMS ((int));
95static void s_atmp PARAMS ((int));
96static int i860_get_expression PARAMS ((char *));
97static bfd_reloc_code_real_type obtain_reloc_for_imm16
98 PARAMS ((fixS *, long *));
99#ifdef DEBUG_I860
100static void print_insn PARAMS ((struct i860_it *));
101#endif
102
103const pseudo_typeS md_pseudo_table[] =
104{
105#ifdef OBJ_ELF
106 {"align", s_align_bytes, 0},
107#endif
108 {"dual", s_dual, 0},
109 {"enddual", s_enddual, 0},
110 {"atmp", s_atmp, 0},
111 {NULL, 0, 0},
112};
113
114/* Dual-instruction mode handling. */
115enum dual
116{
117 DUAL_OFF = 0, DUAL_ON, DUAL_DDOT, DUAL_ONDDOT,
118};
119static enum dual dual_mode = DUAL_OFF;
120
121/* Handle ".dual" directive. */
122static void
123s_dual (ignore)
124 int ignore ATTRIBUTE_UNUSED;
125{
126 dual_mode = DUAL_ON;
127}
128
129/* Handle ".enddual" directive. */
130static void
131s_enddual (ignore)
132 int ignore ATTRIBUTE_UNUSED;
133{
134 dual_mode = DUAL_OFF;
135}
136
137/* Temporary register used when expanding assembler pseudo operations. */
138static int atmp = 31;
139
140static void
141s_atmp (ignore)
142 int ignore ATTRIBUTE_UNUSED;
143{
144 register int temp;
145 if (strncmp (input_line_pointer, "sp", 2) == 0)
146 {
147 input_line_pointer += 2;
148 atmp = 2;
149 }
150 else if (strncmp (input_line_pointer, "fp", 2) == 0)
151 {
152 input_line_pointer += 2;
153 atmp = 3;
154 }
155 else if (strncmp (input_line_pointer, "r", 1) == 0)
156 {
157 input_line_pointer += 1;
158 temp = get_absolute_expression ();
159 if (temp >= 0 && temp <= 31)
160 atmp = temp;
161 else
162 as_bad (_("Unknown temporary pseudo register"));
163 }
164 else
165 {
166 as_bad (_("Unknown temporary pseudo register"));
167 }
168 demand_empty_rest_of_line ();
169}
170
171/* This function is called once, at assembler startup time. It should
172 set up all the tables and data structures that the MD part of the
173 assembler will need. */
174void
175md_begin ()
176{
177 const char *retval = NULL;
178 int lose = 0;
179 unsigned int i = 0;
180
181 op_hash = hash_new ();
182
183 while (i860_opcodes[i].name != NULL)
184 {
185 const char *name = i860_opcodes[i].name;
186 retval = hash_insert (op_hash, name, (PTR)&i860_opcodes[i]);
187 if (retval != NULL)
188 {
189 fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
190 i860_opcodes[i].name, retval);
191 lose = 1;
192 }
193 do
194 {
195 if (i860_opcodes[i].match & i860_opcodes[i].lose)
196 {
197 fprintf (stderr,
198 _("internal error: losing opcode: `%s' \"%s\"\n"),
199 i860_opcodes[i].name, i860_opcodes[i].args);
200 lose = 1;
201 }
202 ++i;
203 }
204 while (i860_opcodes[i].name != NULL
205 && strcmp (i860_opcodes[i].name, name) == 0);
206 }
207
208 if (lose)
209 as_fatal (_("Defective assembler. No assembly attempted."));
210}
211
212/* This is the core of the machine-dependent assembler. STR points to a
213 machine dependent instruction. This function emits the frags/bytes
214 it assembles to. */
215void
216md_assemble (str)
217 char *str;
218{
219 char *destp;
220 int num_opcodes = 1;
221 int i;
222 struct i860_it pseudo[3];
223
224 assert (str);
225 fc = 0;
226
227 /* Assemble the instruction. */
228 i860_process_insn (str);
229
230 /* Check for expandable flag to produce pseudo-instructions. This
231 is an undesirable feature that should be avoided. */
232 if (the_insn.expand != 0
233 && ! (the_insn.fi[0].fup & (OP_SEL_HA | OP_SEL_H | OP_SEL_L | OP_SEL_GOT
234 | OP_SEL_GOTOFF | OP_SEL_PLT)))
235 {
236 for (i = 0; i < 3; i++)
237 pseudo[i] = the_insn;
238
239 fc = 1;
240 switch (the_insn.expand)
241 {
242
243 case E_DELAY:
244 num_opcodes = 1;
245 break;
246
247 case E_MOV:
248 if (the_insn.fi[0].exp.X_add_symbol == NULL
249 && the_insn.fi[0].exp.X_op_symbol == NULL
250 && (the_insn.fi[0].exp.X_add_number < (1 << 15)
251 && the_insn.fi[0].exp.X_add_number >= -(1 << 15)))
252 break;
253
254 /* Emit "or l%const,r0,ireg_dest". */
255 pseudo[0].opcode = (the_insn.opcode & 0x001f0000) | 0xe4000000;
256 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
257
258 /* Emit "orh h%const,ireg_dest,ireg_dest". */
259 pseudo[1].opcode = (the_insn.opcode & 0x03ffffff) | 0xec000000
260 | ((the_insn.opcode & 0x001f0000) << 5);
261 pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
262
263 num_opcodes = 2;
264 break;
265
266 case E_ADDR:
267 if (the_insn.fi[0].exp.X_add_symbol == NULL
268 && the_insn.fi[0].exp.X_op_symbol == NULL
269 && (the_insn.fi[0].exp.X_add_number < (1 << 15)
270 && the_insn.fi[0].exp.X_add_number >= -(1 << 15)))
271 break;
272
273 /* Emit "orh ha%addr_expr,r0,r31". */
274 pseudo[0].opcode = 0xec000000 | (atmp << 16);
275 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_HA);
276
277 /* Emit "l%addr_expr(r31),ireg_dest". We pick up the fixup
278 information from the original instruction. */
279 pseudo[1].opcode = (the_insn.opcode & ~0x03e00000) | (atmp << 21);
280 pseudo[1].fi[0].fup = the_insn.fi[0].fup | OP_SEL_L;
281
282 num_opcodes = 2;
283 break;
284
285 case E_U32:
286 if (the_insn.fi[0].exp.X_add_symbol == NULL
287 && the_insn.fi[0].exp.X_op_symbol == NULL
288 && (the_insn.fi[0].exp.X_add_number < (1 << 16)
289 && the_insn.fi[0].exp.X_add_number >= 0))
290 break;
291
292 /* Emit "$(opcode)h h%const,ireg_src2,r31". */
293 pseudo[0].opcode = (the_insn.opcode & 0xf3e0ffff) | 0x0c000000
294 | (atmp << 16);
295 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
296
297 /* Emit "$(opcode) l%const,r31,ireg_dest". */
298 pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000
299 | (atmp << 21);
300 pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
301
302 num_opcodes = 2;
303 break;
304
305 case E_AND:
306 if (the_insn.fi[0].exp.X_add_symbol == NULL
307 && the_insn.fi[0].exp.X_op_symbol == NULL
308 && (the_insn.fi[0].exp.X_add_number < (1 << 16)
309 && the_insn.fi[0].exp.X_add_number >= 0))
310 break;
311
312 /* Emit "andnot h%const,ireg_src2,r31". */
313 pseudo[0].opcode = (the_insn.opcode & 0x03e0ffff) | 0xd4000000
314 | (atmp << 16);
315 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
316 pseudo[0].fi[0].exp.X_add_number =
317 -1 - the_insn.fi[0].exp.X_add_number;
318
319 /* Emit "andnot l%const,r31,ireg_dest". */
320 pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000
321 | (atmp << 21);
322 pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
323 pseudo[1].fi[0].exp.X_add_number =
324 -1 - the_insn.fi[0].exp.X_add_number;
325
326 num_opcodes = 2;
327 break;
328
329 case E_S32:
330 if (the_insn.fi[0].exp.X_add_symbol == NULL
331 && the_insn.fi[0].exp.X_op_symbol == NULL
332 && (the_insn.fi[0].exp.X_add_number < (1 << 15)
333 && the_insn.fi[0].exp.X_add_number >= -(1 << 15)))
334 break;
335
336 /* Emit "orh h%const,r0,r31". */
337 pseudo[0].opcode = 0xec000000 | (atmp << 16);
338 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
339
340 /* Emit "or l%const,r31,r31". */
341 pseudo[1].opcode = 0xe4000000 | (atmp << 21) | (atmp << 16);
342 pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
343
344 /* Emit "r31,ireg_src2,ireg_dest". */
345 pseudo[2].opcode = (the_insn.opcode & ~0x0400ffff) | (atmp << 11);
346 pseudo[2].fi[0].fup = OP_IMM_S16;
347
348 num_opcodes = 3;
349 break;
350
351 default:
352 as_fatal (_("failed sanity check."));
353 }
354
355 the_insn = pseudo[0];
356
357 /* Warn if an opcode is expanded after a delayed branch. */
358 if (num_opcodes > 1 && last_expand == 1)
359 as_warn (_("Expanded opcode after delayed branch: `%s'"), str);
360
361 /* Warn if an opcode is expanded in dual mode. */
362 if (num_opcodes > 1 && dual_mode != DUAL_OFF)
363 as_warn (_("Expanded opcode in dual mode: `%s'"), str);
364
365 /* Notify if any expansions happen. */
366 if (target_warn_expand && num_opcodes > 1)
367 as_warn (_("An instruction was expanded (%s)"), str);
368 }
369
370 i = 0;
371 do
372 {
373 int tmp;
374
375 /* Output the opcode. Note that the i860 always reads instructions
376 as little-endian data. */
377 destp = frag_more (4);
378 number_to_chars_littleendian (destp, the_insn.opcode, 4);
379
380 /* Check for expanded opcode after branch or in dual mode. */
381 last_expand = the_insn.fi[0].pcrel;
382
383 /* Output the symbol-dependent stuff. Only btne and bte will ever
384 loop more than once here, since only they (possibly) have more
385 than one fixup. */
386 for (tmp = 0; tmp < fc; tmp++)
387 {
388 if (the_insn.fi[tmp].fup != OP_NONE)
389 {
390 fixS *fix;
391 fix = fix_new_exp (frag_now,
392 destp - frag_now->fr_literal,
393 4,
394 &the_insn.fi[tmp].exp,
395 the_insn.fi[tmp].pcrel,
396 the_insn.fi[tmp].reloc);
397
398 /* Despite the odd name, this is a scratch field. We use
399 it to encode operand type information. */
400 fix->fx_addnumber = the_insn.fi[tmp].fup;
401 }
402 }
403 the_insn = pseudo[++i];
404 }
405 while (--num_opcodes > 0);
406
407}
408
409/* Assemble the instruction pointed to by STR. */
410static void
411i860_process_insn (str)
412 char *str;
413{
414 char *s;
415 const char *args;
416 char c;
417 struct i860_opcode *insn;
418 char *args_start;
419 unsigned long opcode;
420 unsigned int mask;
421 int match = 0;
422 int comma = 0;
423
424#if 1 /* For compiler warnings. */
425 args = 0;
426 insn = 0;
427 args_start = 0;
428 opcode = 0;
429#endif
430
431 for (s = str; ISLOWER (*s) || *s == '.' || *s == '3'
432 || *s == '2' || *s == '1'; ++s)
433 ;
434
435 switch (*s)
436 {
437 case '\0':
438 break;
439
440 case ',':
441 comma = 1;
442
443 /*FALLTHROUGH*/
444
445 case ' ':
446 *s++ = '\0';
447 break;
448
449 default:
450 as_fatal (_("Unknown opcode: `%s'"), str);
451 }
452
453 /* Check for dual mode ("d.") opcode prefix. */
454 if (strncmp (str, "d.", 2) == 0)
455 {
456 if (dual_mode == DUAL_ON)
457 dual_mode = DUAL_ONDDOT;
458 else
459 dual_mode = DUAL_DDOT;
460 str += 2;
461 }
462
463 if ((insn = (struct i860_opcode *) hash_find (op_hash, str)) == NULL)
464 {
465 if (dual_mode == DUAL_DDOT || dual_mode == DUAL_ONDDOT)
466 str -= 2;
467 as_bad (_("Unknown opcode: `%s'"), str);
468 return;
469 }
470
471 if (comma)
472 *--s = ',';
473
474 args_start = s;
475 for (;;)
476 {
477 int t;
478 opcode = insn->match;
479 memset (&the_insn, '\0', sizeof (the_insn));
480 fc = 0;
481 for (t = 0; t < MAX_FIXUPS; t++)
482 {
483 the_insn.fi[t].reloc = BFD_RELOC_NONE;
484 the_insn.fi[t].pcrel = 0;
485 the_insn.fi[t].fup = OP_NONE;
486 }
487
488 /* Build the opcode, checking as we go that the operands match. */
489 for (args = insn->args; ; ++args)
490 {
491 if (fc > MAX_FIXUPS)
492 abort ();
493
494 switch (*args)
495 {
496
497 /* End of args. */
498 case '\0':
499 if (*s == '\0')
500 match = 1;
501 break;
502
503 /* These must match exactly. */
504 case '+':
505 case '(':
506 case ')':
507 case ',':
508 case ' ':
509 if (*s++ == *args)
510 continue;
511 break;
512
513 /* Must be at least one digit. */
514 case '#':
515 if (ISDIGIT (*s++))
516 {
517 while (ISDIGIT (*s))
518 ++s;
519 continue;
520 }
521 break;
522
523 /* Next operand must be a register. */
524 case '1':
525 case '2':
526 case 'd':
527 /* Check for register prefix if necessary. */
528 if (reg_prefix && *s != reg_prefix)
529 goto error;
530 else
531 s++;
532
533 switch (*s)
534 {
535 /* Frame pointer. */
536 case 'f':
537 s++;
538 if (*s++ == 'p')
539 {
540 mask = 0x3;
541 break;
542 }
543 goto error;
544
545 /* Stack pointer. */
546 case 's':
547 s++;
548 if (*s++ == 'p')
549 {
550 mask = 0x2;
551 break;
552 }
553 goto error;
554
555 /* Any register r0..r31. */
556 case 'r':
557 s++;
558 if (!ISDIGIT (c = *s++))
559 {
560 goto error;
561 }
562 if (ISDIGIT (*s))
563 {
564 if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
565 goto error;
566 }
567 else
568 c -= '0';
569 mask = c;
570 break;
571
572 /* Not this opcode. */
573 default:
574 goto error;
575 }
576
577 /* Obtained the register, now place it in the opcode. */
578 switch (*args)
579 {
580 case '1':
581 opcode |= mask << 11;
582 continue;
583
584 case '2':
585 opcode |= mask << 21;
586 continue;
587
588 case 'd':
589 opcode |= mask << 16;
590 continue;
591
592 }
593 break;
594
595 /* Next operand is a floating point register. */
596 case 'e':
597 case 'f':
598 case 'g':
599 /* Check for register prefix if necessary. */
600 if (reg_prefix && *s != reg_prefix)
601 goto error;
602 else
603 s++;
604
605 if (*s++ == 'f' && ISDIGIT (*s))
606 {
607 mask = *s++;
608 if (ISDIGIT (*s))
609 {
610 mask = 10 * (mask - '0') + (*s++ - '0');
611 if (mask >= 32)
612 {
613 break;
614 }
615 }
616 else
617 mask -= '0';
618
619 switch (*args)
620 {
621
622 case 'e':
623 opcode |= mask << 11;
624 continue;
625
626 case 'f':
627 opcode |= mask << 21;
628 continue;
629
630 case 'g':
631 opcode |= mask << 16;
632 if (dual_mode != DUAL_OFF)
633 opcode |= (1 << 9);
634 if (dual_mode == DUAL_DDOT)
635 dual_mode = DUAL_OFF;
636 if (dual_mode == DUAL_ONDDOT)
637 dual_mode = DUAL_ON;
638 if ((opcode & (1 << 10)) && mask != 0
639 && (mask == ((opcode >> 11) & 0x1f)))
640 as_warn (_("Pipelined instruction: fsrc1 = fdest"));
641 continue;
642 }
643 }
644 break;
645
646 /* Next operand must be a control register. */
647 case 'c':
648 /* Check for register prefix if necessary. */
649 if (reg_prefix && *s != reg_prefix)
650 goto error;
651 else
652 s++;
653
654 if (strncmp (s, "fir", 3) == 0)
655 {
656 opcode |= 0x0 << 21;
657 s += 3;
658 continue;
659 }
660 if (strncmp (s, "psr", 3) == 0)
661 {
662 opcode |= 0x1 << 21;
663 s += 3;
664 continue;
665 }
666 if (strncmp (s, "dirbase", 7) == 0)
667 {
668 opcode |= 0x2 << 21;
669 s += 7;
670 continue;
671 }
672 if (strncmp (s, "db", 2) == 0)
673 {
674 opcode |= 0x3 << 21;
675 s += 2;
676 continue;
677 }
678 if (strncmp (s, "fsr", 3) == 0)
679 {
680 opcode |= 0x4 << 21;
681 s += 3;
682 continue;
683 }
684 if (strncmp (s, "epsr", 4) == 0)
685 {
686 opcode |= 0x5 << 21;
687 s += 4;
688 continue;
689 }
690 break;
691
692 /* 5-bit immediate in src1. */
693 case '5':
694 if (! i860_get_expression (s))
695 {
696 s = expr_end;
697 the_insn.fi[fc].fup |= OP_IMM_U5;
698 fc++;
699 continue;
700 }
701 break;
702
703 /* 26-bit immediate, relative branch (lbroff). */
704 case 'l':
705 the_insn.fi[fc].pcrel = 1;
706 the_insn.fi[fc].fup |= OP_IMM_BR26;
707 goto immediate;
708
709 /* 16-bit split immediate, relative branch (sbroff). */
710 case 'r':
711 the_insn.fi[fc].pcrel = 1;
712 the_insn.fi[fc].fup |= OP_IMM_BR16;
713 goto immediate;
714
715 /* 16-bit split immediate. */
716 case 's':
717 the_insn.fi[fc].fup |= OP_IMM_SPLIT16;
718 goto immediate;
719
720 /* 16-bit split immediate, byte aligned (st.b). */
721 case 'S':
722 the_insn.fi[fc].fup |= OP_IMM_SPLIT16;
723 goto immediate;
724
725 /* 16-bit split immediate, half-word aligned (st.s). */
726 case 'T':
727 the_insn.fi[fc].fup |= (OP_IMM_SPLIT16 | OP_ENCODE1 | OP_ALIGN2);
728 goto immediate;
729
730 /* 16-bit split immediate, word aligned (st.l). */
731 case 'U':
732 the_insn.fi[fc].fup |= (OP_IMM_SPLIT16 | OP_ENCODE1 | OP_ALIGN4);
733 goto immediate;
734
735 /* 16-bit immediate. */
736 case 'i':
737 the_insn.fi[fc].fup |= OP_IMM_S16;
738 goto immediate;
739
740 /* 16-bit immediate, byte aligned (ld.b). */
741 case 'I':
742 the_insn.fi[fc].fup |= OP_IMM_S16;
743 goto immediate;
744
745 /* 16-bit immediate, half-word aligned (ld.s). */
746 case 'J':
747 the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE1 | OP_ALIGN2);
748 goto immediate;
749
750 /* 16-bit immediate, word aligned (ld.l, {p}fld.l, fst.l). */
751 case 'K':
752 if (insn->name[0] == 'l')
753 the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE1 | OP_ALIGN4);
754 else
755 the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE2 | OP_ALIGN4);
756 goto immediate;
757
758 /* 16-bit immediate, double-word aligned ({p}fld.d, fst.d). */
759 case 'L':
760 the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE3 | OP_ALIGN8);
761 goto immediate;
762
763 /* 16-bit immediate, quad-word aligned (fld.q, fst.q). */
764 case 'M':
765 the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE3 | OP_ALIGN16);
766
767 /*FALLTHROUGH*/
768
769 /* Handle the immediate for either the Intel syntax or
770 SVR4 syntax. The Intel syntax is "ha%immediate"
771 whereas SVR4 syntax is "[immediate]@ha". */
772 immediate:
773#ifdef SYNTAX_SVR4
774 if (*s == ' ')
775 s++;
776
777 /* Note that if i860_get_expression() fails, we will still
778 have created U entries in the symbol table for the
779 'symbols' in the input string. Try not to create U
780 symbols for registers, etc. */
781 if (! i860_get_expression (s))
782 s = expr_end;
783 else
784 goto error;
785
786 if (strncmp (s, "@ha", 3) == 0)
787 {
788 the_insn.fi[fc].fup |= OP_SEL_HA;
789 s += 3;
790 }
791 else if (strncmp (s, "@h", 2) == 0)
792 {
793 the_insn.fi[fc].fup |= OP_SEL_H;
794 s += 2;
795 }
796 else if (strncmp (s, "@l", 2) == 0)
797 {
798 the_insn.fi[fc].fup |= OP_SEL_L;
799 s += 2;
800 }
801 else if (strncmp (s, "@gotoff", 7) == 0
802 || strncmp (s, "@GOTOFF", 7) == 0)
803 {
804 as_bad (_("Assembler does not yet support PIC"));
805 the_insn.fi[fc].fup |= OP_SEL_GOTOFF;
806 s += 7;
807 }
808 else if (strncmp (s, "@got", 4) == 0
809 || strncmp (s, "@GOT", 4) == 0)
810 {
811 as_bad (_("Assembler does not yet support PIC"));
812 the_insn.fi[fc].fup |= OP_SEL_GOT;
813 s += 4;
814 }
815 else if (strncmp (s, "@plt", 4) == 0
816 || strncmp (s, "@PLT", 4) == 0)
817 {
818 as_bad (_("Assembler does not yet support PIC"));
819 the_insn.fi[fc].fup |= OP_SEL_PLT;
820 s += 4;
821 }
822
823 the_insn.expand = insn->expand;
824 fc++;
825
826 continue;
827#else /* ! SYNTAX_SVR4 */
828 if (*s == ' ')
829 s++;
830 if (strncmp (s, "ha%", 3) == 0)
831 {
832 the_insn.fi[fc].fup |= OP_SEL_HA;
833 s += 3;
834 }
835 else if (strncmp (s, "h%", 2) == 0)
836 {
837 the_insn.fi[fc].fup |= OP_SEL_H;
838 s += 2;
839 }
840 else if (strncmp (s, "l%", 2) == 0)
841 {
842 the_insn.fi[fc].fup |= OP_SEL_L;
843 s += 2;
844 }
845 the_insn.expand = insn->expand;
846
847 /* Note that if i860_get_expression() fails, we will still
848 have created U entries in the symbol table for the
849 'symbols' in the input string. Try not to create U
850 symbols for registers, etc. */
851 if (! i860_get_expression (s))
852 s = expr_end;
853 else
854 goto error;
855
856 fc++;
857 continue;
858#endif /* SYNTAX_SVR4 */
859 break;
860
861 default:
862 as_fatal (_("failed sanity check."));
863 }
864 break;
865 }
866 error:
867 if (match == 0)
868 {
869 /* Args don't match. */
870 if (insn[1].name != NULL
871 && ! strcmp (insn->name, insn[1].name))
872 {
873 ++insn;
874 s = args_start;
875 continue;
876 }
877 else
878 {
879 as_bad (_("Illegal operands for %s"), insn->name);
880 return;
881 }
882 }
883 break;
884 }
885
886 the_insn.opcode = opcode;
887}
888
889static int
890i860_get_expression (str)
891 char *str;
892{
893 char *save_in;
894 segT seg;
895
896 save_in = input_line_pointer;
897 input_line_pointer = str;
898 seg = expression (&the_insn.fi[fc].exp);
899 if (seg != absolute_section
900 && seg != undefined_section
901 && ! SEG_NORMAL (seg))
902 {
903 the_insn.error = _("bad segment");
904 expr_end = input_line_pointer;
905 input_line_pointer = save_in;
906 return 1;
907 }
908 expr_end = input_line_pointer;
909 input_line_pointer = save_in;
910 return 0;
911}
912
913/* Turn a string in input_line_pointer into a floating point constant of
914 type TYPE, and store the appropriate bytes in *LITP. The number of
915 LITTLENUMS emitted is stored in *SIZEP. An error message is returned,
916 or NULL on OK. */
917
918/* Equal to MAX_PRECISION in atof-ieee.c. */
919#define MAX_LITTLENUMS 6
920
921char *
922md_atof (type, litP, sizeP)
923 char type;
924 char *litP;
925 int *sizeP;
926{
927 int prec;
928 LITTLENUM_TYPE words[MAX_LITTLENUMS];
929 LITTLENUM_TYPE *wordP;
930 char *t;
931
932 switch (type)
933 {
934 case 'f':
935 case 'F':
936 case 's':
937 case 'S':
938 prec = 2;
939 break;
940
941 case 'd':
942 case 'D':
943 case 'r':
944 case 'R':
945 prec = 4;
946 break;
947
948 case 'x':
949 case 'X':
950 prec = 6;
951 break;
952
953 case 'p':
954 case 'P':
955 prec = 6;
956 break;
957
958 default:
959 *sizeP = 0;
960 return _("Bad call to MD_ATOF()");
961 }
962 t = atof_ieee (input_line_pointer, type, words);
963 if (t)
964 input_line_pointer = t;
965 *sizeP = prec * sizeof (LITTLENUM_TYPE);
966 for (wordP = words; prec--;)
967 {
968 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
969 litP += sizeof (LITTLENUM_TYPE);
970 }
971 return 0;
972}
973
974/* Write out in current endian mode. */
975void
976md_number_to_chars (buf, val, n)
977 char *buf;
978 valueT val;
979 int n;
980{
981 if (target_big_endian)
982 number_to_chars_bigendian (buf, val, n);
983 else
984 number_to_chars_littleendian (buf, val, n);
985}
986
987/* This should never be called for i860. */
988int
989md_estimate_size_before_relax (fragP, segtype)
990 register fragS *fragP ATTRIBUTE_UNUSED;
991 segT segtype ATTRIBUTE_UNUSED;
992{
993 as_fatal (_("i860_estimate_size_before_relax\n"));
994}
995
996#ifdef DEBUG_I860
997static void
998print_insn (insn)
999 struct i860_it *insn;
1000{
1001 if (insn->error)
1002 fprintf (stderr, "ERROR: %s\n", insn->error);
1003
1004 fprintf (stderr, "opcode = 0x%08lx\t", insn->opcode);
1005 fprintf (stderr, "expand = 0x%x\t", insn->expand);
1006 fprintf (stderr, "reloc = %s\t\n",
1007 bfd_get_reloc_code_name (insn->reloc));
1008 fprintf (stderr, "exp = {\n");
1009 fprintf (stderr, "\t\tX_add_symbol = %s\n",
1010 insn->exp.X_add_symbol ?
1011 (S_GET_NAME (insn->exp.X_add_symbol) ?
1012 S_GET_NAME (insn->exp.X_add_symbol) : "???") : "0");
1013 fprintf (stderr, "\t\tX_op_symbol = %s\n",
1014 insn->exp.X_op_symbol ?
1015 (S_GET_NAME (insn->exp.X_op_symbol) ?
1016 S_GET_NAME (insn->exp.X_op_symbol) : "???") : "0");
1017 fprintf (stderr, "\t\tX_add_number = %lx\n",
1018 insn->exp.X_add_number);
1019 fprintf (stderr, "}\n");
1020}
1021#endif /* DEBUG_I860 */
1022
1023\f
1024#ifdef OBJ_ELF
1025const char *md_shortopts = "VQ:";
1026#else
1027const char *md_shortopts = "";
1028#endif
1029
1030#define OPTION_EB (OPTION_MD_BASE + 0)
1031#define OPTION_EL (OPTION_MD_BASE + 1)
1032#define OPTION_WARN_EXPAND (OPTION_MD_BASE + 2)
1033
1034struct option md_longopts[] = {
1035 { "EB", no_argument, NULL, OPTION_EB },
1036 { "EL", no_argument, NULL, OPTION_EL },
1037 { "mwarn-expand", no_argument, NULL, OPTION_WARN_EXPAND },
1038 { NULL, no_argument, NULL, 0 }
1039};
1040size_t md_longopts_size = sizeof (md_longopts);
1041
1042int
1043md_parse_option (c, arg)
1044 int c;
1045 char *arg ATTRIBUTE_UNUSED;
1046{
1047 switch (c)
1048 {
1049 case OPTION_EB:
1050 target_big_endian = 1;
1051 break;
1052
1053 case OPTION_EL:
1054 target_big_endian = 0;
1055 break;
1056
1057 case OPTION_WARN_EXPAND:
1058 target_warn_expand = 1;
1059 break;
1060
1061#ifdef OBJ_ELF
1062 /* SVR4 argument compatibility (-V): print version ID. */
1063 case 'V':
1064 print_version_id ();
1065 break;
1066
1067 /* SVR4 argument compatibility (-Qy, -Qn): controls whether
1068 a .comment section should be emitted or not (ignored). */
1069 case 'Q':
1070 break;
1071#endif
1072
1073 default:
1074 return 0;
1075 }
1076
1077 return 1;
1078}
1079
1080void
1081md_show_usage (stream)
1082 FILE *stream;
1083{
1084 fprintf (stream, _("\
1085 -EL generate code for little endian mode (default)\n\
1086 -EB generate code for big endian mode\n\
1087 -mwarn-expand warn if pseudo operations are expanded\n"));
1088#ifdef OBJ_ELF
1089 /* SVR4 compatibility flags. */
1090 fprintf (stream, _("\
1091 -V print assembler version number\n\
1092 -Qy, -Qn ignored\n"));
1093#endif
1094}
1095
1096\f
1097/* We have no need to default values of symbols. */
1098symbolS *
1099md_undefined_symbol (name)
1100 char *name ATTRIBUTE_UNUSED;
1101{
1102 return 0;
1103}
1104
1105/* The i860 denotes auto-increment with '++'. */
1106void
1107md_operand (exp)
1108 expressionS *exp;
1109{
1110 char *s;
1111
1112 for (s = input_line_pointer; *s; s++)
1113 {
1114 if (s[0] == '+' && s[1] == '+')
1115 {
1116 input_line_pointer += 2;
1117 exp->X_op = O_register;
1118 break;
1119 }
1120 }
1121}
1122
1123/* Round up a section size to the appropriate boundary. */
1124valueT
1125md_section_align (segment, size)
1126 segT segment ATTRIBUTE_UNUSED;
1127 valueT size ATTRIBUTE_UNUSED;
1128{
1129 /* Byte alignment is fine. */
1130 return size;
1131}
1132
1133/* On the i860, a PC-relative offset is relative to the address of the
1134 of the offset plus its size. */
1135long
1136md_pcrel_from (fixP)
1137 fixS *fixP;
1138{
1139 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
1140}
1141
1142/* Determine the relocation needed for non PC-relative 16-bit immediates.
1143 Also adjust the given immediate as necessary. Finally, check that
1144 all constraints (such as alignment) are satisfied. */
1145static bfd_reloc_code_real_type
1146obtain_reloc_for_imm16 (fix, val)
1147 fixS *fix;
1148 long *val;
1149{
1150 valueT fup = fix->fx_addnumber;
1151 bfd_reloc_code_real_type reloc;
1152
1153 if (fix->fx_pcrel)
1154 abort ();
1155
1156 /* Check alignment restrictions. */
1157 if ((fup & OP_ALIGN2) && (*val & 0x1))
1158 as_bad_where (fix->fx_file, fix->fx_line,
1159 _("This immediate requires 0 MOD 2 alignment"));
1160 else if ((fup & OP_ALIGN4) && (*val & 0x3))
1161 as_bad_where (fix->fx_file, fix->fx_line,
1162 _("This immediate requires 0 MOD 4 alignment"));
1163 else if ((fup & OP_ALIGN8) && (*val & 0x7))
1164 as_bad_where (fix->fx_file, fix->fx_line,
1165 _("This immediate requires 0 MOD 8 alignment"));
1166 else if ((fup & OP_ALIGN16) && (*val & 0xf))
1167 as_bad_where (fix->fx_file, fix->fx_line,
1168 _("This immediate requires 0 MOD 16 alignment"));
1169
1170 if (fup & OP_SEL_HA)
1171 {
1172 *val = (*val >> 16) + (*val & 0x8000 ? 1 : 0);
1173 reloc = BFD_RELOC_860_HIGHADJ;
1174 }
1175 else if (fup & OP_SEL_H)
1176 {
1177 *val >>= 16;
1178 reloc = BFD_RELOC_860_HIGH;
1179 }
1180 else if (fup & OP_SEL_L)
1181 {
1182 int num_encode;
1183 if (fup & OP_IMM_SPLIT16)
1184 {
1185 if (fup & OP_ENCODE1)
1186 {
1187 num_encode = 1;
1188 reloc = BFD_RELOC_860_SPLIT1;
1189 }
1190 else if (fup & OP_ENCODE2)
1191 {
1192 num_encode = 2;
1193 reloc = BFD_RELOC_860_SPLIT2;
1194 }
1195 else
1196 {
1197 num_encode = 0;
1198 reloc = BFD_RELOC_860_SPLIT0;
1199 }
1200 }
1201 else
1202 {
1203 if (fup & OP_ENCODE1)
1204 {
1205 num_encode = 1;
1206 reloc = BFD_RELOC_860_LOW1;
1207 }
1208 else if (fup & OP_ENCODE2)
1209 {
1210 num_encode = 2;
1211 reloc = BFD_RELOC_860_LOW2;
1212 }
1213 else if (fup & OP_ENCODE3)
1214 {
1215 num_encode = 3;
1216 reloc = BFD_RELOC_860_LOW3;
1217 }
1218 else
1219 {
1220 num_encode = 0;
1221 reloc = BFD_RELOC_860_LOW0;
1222 }
1223 }
1224
1225 /* Preserve size encode bits. */
1226 *val &= ~((1 << num_encode) - 1);
1227 }
1228 else
1229 {
1230 /* No selector. What reloc do we generate (???)? */
1231 reloc = BFD_RELOC_32;
1232 }
1233
1234 return reloc;
1235}
1236
1237/* Attempt to simplify or eliminate a fixup. To indicate that a fixup
1238 has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
1239 we will have to generate a reloc entry. */
1240
1241void
1242md_apply_fix3 (fix, valP, seg)
1243 fixS * fix;
1244 valueT * valP;
1245 segT seg ATTRIBUTE_UNUSED;
1246{
1247 char *buf;
1248 long val = *valP;
1249 unsigned long insn;
1250 valueT fup;
1251
1252 buf = fix->fx_frag->fr_literal + fix->fx_where;
1253
1254 /* Recall that earlier we stored the opcode little-endian. */
1255 insn = bfd_getl32 (buf);
1256
1257 /* We stored a fix-up in this oddly-named scratch field. */
1258 fup = fix->fx_addnumber;
1259
1260 /* Determine the necessary relocations as well as inserting an
1261 immediate into the instruction. */
1262 if (fup & OP_IMM_U5)
1263 {
1264 if (val & ~0x1f)
1265 as_bad_where (fix->fx_file, fix->fx_line,
1266 _("5-bit immediate too large"));
1267 if (fix->fx_addsy)
1268 as_bad_where (fix->fx_file, fix->fx_line,
1269 _("5-bit field must be absolute"));
1270
1271 insn |= (val & 0x1f) << 11;
1272 bfd_putl32 (insn, buf);
1273 fix->fx_r_type = BFD_RELOC_NONE;
1274 fix->fx_done = 1;
1275 }
1276 else if (fup & OP_IMM_S16)
1277 {
1278 fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val);
1279
1280 /* Insert the immediate. */
1281 if (fix->fx_addsy)
1282 fix->fx_done = 0;
1283 else
1284 {
1285 insn |= val & 0xffff;
1286 bfd_putl32 (insn, buf);
1287 fix->fx_r_type = BFD_RELOC_NONE;
1288 fix->fx_done = 1;
1289 }
1290 }
1291 else if (fup & OP_IMM_U16)
1292 abort ();
1293
1294 else if (fup & OP_IMM_SPLIT16)
1295 {
1296 fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val);
1297
1298 /* Insert the immediate. */
1299 if (fix->fx_addsy)
1300 fix->fx_done = 0;
1301 else
1302 {
1303 insn |= val & 0x7ff;
1304 insn |= (val & 0xf800) << 5;
1305 bfd_putl32 (insn, buf);
1306 fix->fx_r_type = BFD_RELOC_NONE;
1307 fix->fx_done = 1;
1308 }
1309 }
1310 else if (fup & OP_IMM_BR16)
1311 {
1312 if (val & 0x3)
1313 as_bad_where (fix->fx_file, fix->fx_line,
1314 _("A branch offset requires 0 MOD 4 alignment"));
1315
1316 val = val >> 2;
1317
1318 /* Insert the immediate. */
1319 if (fix->fx_addsy)
1320 {
1321 fix->fx_done = 0;
1322 fix->fx_r_type = BFD_RELOC_860_PC16;
1323 }
1324 else
1325 {
1326 insn |= (val & 0x7ff);
1327 insn |= ((val & 0xf800) << 5);
1328 bfd_putl32 (insn, buf);
1329 fix->fx_r_type = BFD_RELOC_NONE;
1330 fix->fx_done = 1;
1331 }
1332 }
1333 else if (fup & OP_IMM_BR26)
1334 {
1335 if (val & 0x3)
1336 as_bad_where (fix->fx_file, fix->fx_line,
1337 _("A branch offset requires 0 MOD 4 alignment"));
1338
1339 val >>= 2;
1340
1341 /* Insert the immediate. */
1342 if (fix->fx_addsy)
1343 {
1344 fix->fx_r_type = BFD_RELOC_860_PC26;
1345 fix->fx_done = 0;
1346 }
1347 else
1348 {
1349 insn |= (val & 0x3ffffff);
1350 bfd_putl32 (insn, buf);
1351 fix->fx_r_type = BFD_RELOC_NONE;
1352 fix->fx_done = 1;
1353 }
1354 }
1355 else if (fup != OP_NONE)
1356 {
1357 as_bad_where (fix->fx_file, fix->fx_line,
1358 _("Unrecognized fix-up (0x%08lx)"), (unsigned long) fup);
1359 abort ();
1360 }
1361 else
1362 {
1363 /* I believe only fix-ups such as ".long .ep.main-main+0xc8000000"
1364 reach here (???). */
1365 if (fix->fx_addsy)
1366 {
1367 fix->fx_r_type = BFD_RELOC_32;
1368 fix->fx_done = 0;
1369 }
1370 else
1371 {
1372 insn |= (val & 0xffffffff);
1373 bfd_putl32 (insn, buf);
1374 fix->fx_r_type = BFD_RELOC_NONE;
1375 fix->fx_done = 1;
1376 }
1377 }
1378}
1379
1380/* Generate a machine dependent reloc from a fixup. */
1381arelent*
1382tc_gen_reloc (section, fixp)
1383 asection *section ATTRIBUTE_UNUSED;
1384 fixS *fixp;
1385{
1386 arelent *reloc;
1387
1388 reloc = xmalloc (sizeof (*reloc));
1389 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1390 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1391 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1392 reloc->addend = fixp->fx_offset;
1393 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1394
1395 if (! reloc->howto)
1396 {
1397 as_bad_where (fixp->fx_file, fixp->fx_line,
1398 "Cannot represent %s relocation in object file",
1399 bfd_get_reloc_code_name (fixp->fx_r_type));
1400 }
1401 return reloc;
1402}
This page took 0.033124 seconds and 4 git commands to generate.