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