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