2003-08-07 Elena Zannoni <ezannoni@redhat.com>
[deliverable/binutils-gdb.git] / gas / config / tc-i860.c
CommitLineData
305d537e 1/* tc-i860.c -- Assembler for the Intel i860 architecture.
14218d5f 2 Copyright 1989, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003
305d537e
JE
3 Free Software Foundation, Inc.
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
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
305d537e
JE
24#include <stdio.h>
25#include <string.h>
252b5132 26#include "as.h"
3882b010 27#include "safe-ctype.h"
305d537e 28#include "subsegs.h"
252b5132 29#include "opcode/i860.h"
305d537e 30#include "elf/i860.h"
252b5132 31
252b5132 32
305d537e 33/* The opcode hash table. */
252b5132
RH
34static struct hash_control *op_hash = NULL;
35
305d537e
JE
36/* These characters always start a comment. */
37const char comment_chars[] = "#!/";
252b5132 38
305d537e 39/* These characters start a comment at the beginning of a line. */
252b5132
RH
40const char line_comment_chars[] = "#/";
41
63a0b638 42const char line_separator_chars[] = ";";
252b5132 43
305d537e
JE
44/* Characters that can be used to separate the mantissa from the exponent
45 in floating point numbers. */
252b5132
RH
46const char EXP_CHARS[] = "eE";
47
305d537e
JE
48/* Characters that indicate this number is a floating point constant.
49 As in 0f12.456 or 0d1.2345e12. */
252b5132
RH
50const char FLT_CHARS[] = "rRsSfFdDxXpP";
51
87505968
JE
52/* Register prefix (depends on syntax). */
53static char reg_prefix;
305d537e 54
673a54e3
JE
55#define MAX_FIXUPS 2
56
252b5132 57struct i860_it
305d537e
JE
58{
59 char *error;
60 unsigned long opcode;
305d537e 61 enum expand_type expand;
673a54e3
JE
62 struct i860_fi
63 {
64 expressionS exp;
65 bfd_reloc_code_real_type reloc;
66 int pcrel;
67 valueT fup;
68 } fi[MAX_FIXUPS];
305d537e
JE
69} the_insn;
70
673a54e3
JE
71/* The current fixup count. */
72static int fc;
73
305d537e 74static char *expr_end;
252b5132 75
305d537e
JE
76/* Indicates error if a pseudo operation was expanded after a branch. */
77static char last_expand;
252b5132 78
305d537e
JE
79/* If true, then warn if any pseudo operations were expanded. */
80static int target_warn_expand = 0;
252b5132 81
14218d5f
JE
82/* If true, then XP support is enabled. */
83static int target_xp = 0;
84
87505968
JE
85/* If true, then Intel syntax is enabled (default to AT&T/SVR4 syntax). */
86static int target_intel_syntax = 0;
87
88
305d537e 89/* Prototypes. */
7734b6e9
JE
90static void i860_process_insn (char *);
91static void s_dual (int);
92static void s_enddual (int);
93static void s_atmp (int);
820aff55 94static void s_align_wrapper (int);
7734b6e9
JE
95static int i860_get_expression (char *);
96static bfd_reloc_code_real_type obtain_reloc_for_imm16 (fixS *, long *);
305d537e 97#ifdef DEBUG_I860
7734b6e9 98static void print_insn (struct i860_it *);
305d537e 99#endif
252b5132 100
305d537e
JE
101const pseudo_typeS md_pseudo_table[] =
102{
820aff55
JE
103 {"align", s_align_wrapper, 0},
104 {"dual", s_dual, 0},
105 {"enddual", s_enddual, 0},
106 {"atmp", s_atmp, 0},
107 {NULL, 0, 0},
305d537e
JE
108};
109
305d537e 110/* Dual-instruction mode handling. */
252b5132
RH
111enum dual
112{
113 DUAL_OFF = 0, DUAL_ON, DUAL_DDOT, DUAL_ONDDOT,
114};
305d537e
JE
115static enum dual dual_mode = DUAL_OFF;
116
305d537e 117/* Handle ".dual" directive. */
252b5132 118static void
7734b6e9 119s_dual (int ignore ATTRIBUTE_UNUSED)
252b5132 120{
5ea0549d
JE
121 if (target_intel_syntax)
122 dual_mode = DUAL_ON;
123 else
124 as_bad (_("Directive .dual available only with -mintel-syntax option"));
252b5132
RH
125}
126
305d537e 127/* Handle ".enddual" directive. */
252b5132 128static void
7734b6e9 129s_enddual (int ignore ATTRIBUTE_UNUSED)
252b5132 130{
5ea0549d
JE
131 if (target_intel_syntax)
132 dual_mode = DUAL_OFF;
133 else
134 as_bad (_("Directive .enddual available only with -mintel-syntax option"));
252b5132
RH
135}
136
305d537e
JE
137/* Temporary register used when expanding assembler pseudo operations. */
138static int atmp = 31;
252b5132
RH
139
140static void
7734b6e9 141s_atmp (int ignore ATTRIBUTE_UNUSED)
252b5132 142{
5ea0549d
JE
143 int temp;
144
145 if (! target_intel_syntax)
146 {
147 as_bad (_("Directive .atmp available only with -mintel-syntax option"));
148 demand_empty_rest_of_line ();
149 return;
150 }
151
252b5132
RH
152 if (strncmp (input_line_pointer, "sp", 2) == 0)
153 {
154 input_line_pointer += 2;
155 atmp = 2;
156 }
157 else if (strncmp (input_line_pointer, "fp", 2) == 0)
158 {
159 input_line_pointer += 2;
160 atmp = 3;
161 }
162 else if (strncmp (input_line_pointer, "r", 1) == 0)
163 {
164 input_line_pointer += 1;
165 temp = get_absolute_expression ();
166 if (temp >= 0 && temp <= 31)
167 atmp = temp;
168 else
169 as_bad (_("Unknown temporary pseudo register"));
170 }
171 else
172 {
173 as_bad (_("Unknown temporary pseudo register"));
174 }
175 demand_empty_rest_of_line ();
176}
177
820aff55
JE
178/* Handle ".align" directive depending on syntax mode.
179 AT&T/SVR4 syntax uses the standard align directive. However,
180 the Intel syntax additionally allows keywords for the alignment
181 parameter: ".align type", where type is one of {.short, .long,
182 .quad, .single, .double} representing alignments of 2, 4,
183 16, 4, and 8, respectively. */
184static void
185s_align_wrapper (int arg)
186{
187 char *parm = input_line_pointer;
188
189 if (target_intel_syntax)
190 {
191 /* Replace a keyword with the equivalent integer so the
192 standard align routine can parse the directive. */
193 if (strncmp (parm, ".short", 6) == 0)
194 strncpy (parm, " 2", 6);
195 else if (strncmp (parm, ".long", 5) == 0)
196 strncpy (parm, " 4", 5);
197 else if (strncmp (parm, ".quad", 5) == 0)
198 strncpy (parm, " 16", 5);
199 else if (strncmp (parm, ".single", 7) == 0)
200 strncpy (parm, " 4", 7);
201 else if (strncmp (parm, ".double", 7) == 0)
202 strncpy (parm, " 8", 7);
203
204 while (*input_line_pointer == ' ')
205 ++input_line_pointer;
206 }
207
208 s_align_bytes (arg);
209}
210
252b5132 211/* This function is called once, at assembler startup time. It should
305d537e
JE
212 set up all the tables and data structures that the MD part of the
213 assembler will need. */
252b5132 214void
7734b6e9 215md_begin (void)
252b5132 216{
305d537e 217 const char *retval = NULL;
252b5132 218 int lose = 0;
305d537e 219 unsigned int i = 0;
252b5132
RH
220
221 op_hash = hash_new ();
222
305d537e 223 while (i860_opcodes[i].name != NULL)
252b5132
RH
224 {
225 const char *name = i860_opcodes[i].name;
305d537e 226 retval = hash_insert (op_hash, name, (PTR)&i860_opcodes[i]);
252b5132
RH
227 if (retval != NULL)
228 {
229 fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
230 i860_opcodes[i].name, retval);
231 lose = 1;
232 }
233 do
234 {
235 if (i860_opcodes[i].match & i860_opcodes[i].lose)
236 {
305d537e
JE
237 fprintf (stderr,
238 _("internal error: losing opcode: `%s' \"%s\"\n"),
252b5132
RH
239 i860_opcodes[i].name, i860_opcodes[i].args);
240 lose = 1;
241 }
242 ++i;
243 }
305d537e
JE
244 while (i860_opcodes[i].name != NULL
245 && strcmp (i860_opcodes[i].name, name) == 0);
252b5132
RH
246 }
247
248 if (lose)
305d537e 249 as_fatal (_("Defective assembler. No assembly attempted."));
87505968
JE
250
251 /* Set the register prefix for either Intel or AT&T/SVR4 syntax. */
252 reg_prefix = target_intel_syntax ? 0 : '%';
252b5132
RH
253}
254
305d537e
JE
255/* This is the core of the machine-dependent assembler. STR points to a
256 machine dependent instruction. This function emits the frags/bytes
257 it assembles to. */
252b5132 258void
7734b6e9 259md_assemble (char *str)
252b5132 260{
305d537e
JE
261 char *destp;
262 int num_opcodes = 1;
252b5132
RH
263 int i;
264 struct i860_it pseudo[3];
265
266 assert (str);
673a54e3 267 fc = 0;
252b5132 268
305d537e
JE
269 /* Assemble the instruction. */
270 i860_process_insn (str);
271
272 /* Check for expandable flag to produce pseudo-instructions. This
273 is an undesirable feature that should be avoided. */
14218d5f 274 if (the_insn.expand != 0 && the_insn.expand != XP_ONLY
673a54e3 275 && ! (the_insn.fi[0].fup & (OP_SEL_HA | OP_SEL_H | OP_SEL_L | OP_SEL_GOT
305d537e 276 | OP_SEL_GOTOFF | OP_SEL_PLT)))
252b5132
RH
277 {
278 for (i = 0; i < 3; i++)
279 pseudo[i] = the_insn;
280
673a54e3 281 fc = 1;
252b5132
RH
282 switch (the_insn.expand)
283 {
284
285 case E_DELAY:
305d537e 286 num_opcodes = 1;
252b5132
RH
287 break;
288
289 case E_MOV:
673a54e3
JE
290 if (the_insn.fi[0].exp.X_add_symbol == NULL
291 && the_insn.fi[0].exp.X_op_symbol == NULL
292 && (the_insn.fi[0].exp.X_add_number < (1 << 15)
293 && the_insn.fi[0].exp.X_add_number >= -(1 << 15)))
252b5132 294 break;
305d537e
JE
295
296 /* Emit "or l%const,r0,ireg_dest". */
252b5132 297 pseudo[0].opcode = (the_insn.opcode & 0x001f0000) | 0xe4000000;
673a54e3 298 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
305d537e
JE
299
300 /* Emit "orh h%const,ireg_dest,ireg_dest". */
301 pseudo[1].opcode = (the_insn.opcode & 0x03ffffff) | 0xec000000
302 | ((the_insn.opcode & 0x001f0000) << 5);
673a54e3 303 pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
305d537e
JE
304
305 num_opcodes = 2;
252b5132
RH
306 break;
307
308 case E_ADDR:
673a54e3
JE
309 if (the_insn.fi[0].exp.X_add_symbol == NULL
310 && the_insn.fi[0].exp.X_op_symbol == NULL
311 && (the_insn.fi[0].exp.X_add_number < (1 << 15)
312 && the_insn.fi[0].exp.X_add_number >= -(1 << 15)))
252b5132 313 break;
305d537e
JE
314
315 /* Emit "orh ha%addr_expr,r0,r31". */
252b5132 316 pseudo[0].opcode = 0xec000000 | (atmp << 16);
673a54e3 317 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_HA);
305d537e
JE
318
319 /* Emit "l%addr_expr(r31),ireg_dest". We pick up the fixup
320 information from the original instruction. */
321 pseudo[1].opcode = (the_insn.opcode & ~0x03e00000) | (atmp << 21);
673a54e3 322 pseudo[1].fi[0].fup = the_insn.fi[0].fup | OP_SEL_L;
305d537e
JE
323
324 num_opcodes = 2;
252b5132
RH
325 break;
326
305d537e 327 case E_U32:
673a54e3
JE
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 << 16)
331 && the_insn.fi[0].exp.X_add_number >= 0))
252b5132 332 break;
305d537e
JE
333
334 /* Emit "$(opcode)h h%const,ireg_src2,r31". */
335 pseudo[0].opcode = (the_insn.opcode & 0xf3e0ffff) | 0x0c000000
336 | (atmp << 16);
673a54e3 337 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
305d537e
JE
338
339 /* Emit "$(opcode) l%const,r31,ireg_dest". */
340 pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000
341 | (atmp << 21);
673a54e3 342 pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
305d537e
JE
343
344 num_opcodes = 2;
252b5132
RH
345 break;
346
305d537e 347 case E_AND:
673a54e3
JE
348 if (the_insn.fi[0].exp.X_add_symbol == NULL
349 && the_insn.fi[0].exp.X_op_symbol == NULL
350 && (the_insn.fi[0].exp.X_add_number < (1 << 16)
351 && the_insn.fi[0].exp.X_add_number >= 0))
252b5132 352 break;
305d537e
JE
353
354 /* Emit "andnot h%const,ireg_src2,r31". */
355 pseudo[0].opcode = (the_insn.opcode & 0x03e0ffff) | 0xd4000000
356 | (atmp << 16);
673a54e3
JE
357 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
358 pseudo[0].fi[0].exp.X_add_number =
359 -1 - the_insn.fi[0].exp.X_add_number;
305d537e
JE
360
361 /* Emit "andnot l%const,r31,ireg_dest". */
362 pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000
363 | (atmp << 21);
673a54e3
JE
364 pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
365 pseudo[1].fi[0].exp.X_add_number =
366 -1 - the_insn.fi[0].exp.X_add_number;
305d537e
JE
367
368 num_opcodes = 2;
252b5132
RH
369 break;
370
371 case E_S32:
673a54e3
JE
372 if (the_insn.fi[0].exp.X_add_symbol == NULL
373 && the_insn.fi[0].exp.X_op_symbol == NULL
374 && (the_insn.fi[0].exp.X_add_number < (1 << 15)
375 && the_insn.fi[0].exp.X_add_number >= -(1 << 15)))
252b5132 376 break;
305d537e
JE
377
378 /* Emit "orh h%const,r0,r31". */
252b5132 379 pseudo[0].opcode = 0xec000000 | (atmp << 16);
673a54e3 380 pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
305d537e
JE
381
382 /* Emit "or l%const,r31,r31". */
252b5132 383 pseudo[1].opcode = 0xe4000000 | (atmp << 21) | (atmp << 16);
673a54e3 384 pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
305d537e
JE
385
386 /* Emit "r31,ireg_src2,ireg_dest". */
252b5132 387 pseudo[2].opcode = (the_insn.opcode & ~0x0400ffff) | (atmp << 11);
673a54e3 388 pseudo[2].fi[0].fup = OP_IMM_S16;
305d537e
JE
389
390 num_opcodes = 3;
252b5132
RH
391 break;
392
393 default:
394 as_fatal (_("failed sanity check."));
395 }
396
397 the_insn = pseudo[0];
305d537e
JE
398
399 /* Warn if an opcode is expanded after a delayed branch. */
400 if (num_opcodes > 1 && last_expand == 1)
252b5132 401 as_warn (_("Expanded opcode after delayed branch: `%s'"), str);
305d537e
JE
402
403 /* Warn if an opcode is expanded in dual mode. */
404 if (num_opcodes > 1 && dual_mode != DUAL_OFF)
252b5132 405 as_warn (_("Expanded opcode in dual mode: `%s'"), str);
305d537e
JE
406
407 /* Notify if any expansions happen. */
408 if (target_warn_expand && num_opcodes > 1)
409 as_warn (_("An instruction was expanded (%s)"), str);
252b5132
RH
410 }
411
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
305d537e
JE
1014/* Turn a string in input_line_pointer into a floating point constant of
1015 type TYPE, and store the appropriate bytes in *LITP. The number of
1016 LITTLENUMS emitted is stored in *SIZEP. An error message is returned,
1017 or NULL on OK. */
252b5132 1018
305d537e 1019/* Equal to MAX_PRECISION in atof-ieee.c. */
252b5132
RH
1020#define MAX_LITTLENUMS 6
1021
1022char *
7734b6e9 1023md_atof (int type, char *litP, int *sizeP)
252b5132
RH
1024{
1025 int prec;
1026 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1027 LITTLENUM_TYPE *wordP;
1028 char *t;
252b5132
RH
1029
1030 switch (type)
1031 {
252b5132
RH
1032 case 'f':
1033 case 'F':
1034 case 's':
1035 case 'S':
1036 prec = 2;
1037 break;
1038
1039 case 'd':
1040 case 'D':
1041 case 'r':
1042 case 'R':
1043 prec = 4;
1044 break;
1045
1046 case 'x':
1047 case 'X':
1048 prec = 6;
1049 break;
1050
1051 case 'p':
1052 case 'P':
1053 prec = 6;
1054 break;
1055
1056 default:
1057 *sizeP = 0;
1058 return _("Bad call to MD_ATOF()");
1059 }
1060 t = atof_ieee (input_line_pointer, type, words);
1061 if (t)
1062 input_line_pointer = t;
1063 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1064 for (wordP = words; prec--;)
1065 {
1066 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
1067 litP += sizeof (LITTLENUM_TYPE);
1068 }
1069 return 0;
1070}
1071
305d537e 1072/* Write out in current endian mode. */
252b5132 1073void
7734b6e9 1074md_number_to_chars (char *buf, valueT val, int n)
252b5132 1075{
305d537e
JE
1076 if (target_big_endian)
1077 number_to_chars_bigendian (buf, val, n);
1078 else
1079 number_to_chars_littleendian (buf, val, n);
252b5132
RH
1080}
1081
305d537e 1082/* This should never be called for i860. */
252b5132 1083int
7734b6e9
JE
1084md_estimate_size_before_relax (register fragS *fragP ATTRIBUTE_UNUSED,
1085 segT segtype ATTRIBUTE_UNUSED)
252b5132
RH
1086{
1087 as_fatal (_("i860_estimate_size_before_relax\n"));
1088}
1089
305d537e 1090#ifdef DEBUG_I860
252b5132 1091static void
7734b6e9 1092print_insn (struct i860_it *insn)
252b5132
RH
1093{
1094 if (insn->error)
305d537e
JE
1095 fprintf (stderr, "ERROR: %s\n", insn->error);
1096
1097 fprintf (stderr, "opcode = 0x%08lx\t", insn->opcode);
1098 fprintf (stderr, "expand = 0x%x\t", insn->expand);
1099 fprintf (stderr, "reloc = %s\t\n",
1100 bfd_get_reloc_code_name (insn->reloc));
252b5132
RH
1101 fprintf (stderr, "exp = {\n");
1102 fprintf (stderr, "\t\tX_add_symbol = %s\n",
1103 insn->exp.X_add_symbol ?
1104 (S_GET_NAME (insn->exp.X_add_symbol) ?
1105 S_GET_NAME (insn->exp.X_add_symbol) : "???") : "0");
1106 fprintf (stderr, "\t\tX_op_symbol = %s\n",
1107 insn->exp.X_op_symbol ?
1108 (S_GET_NAME (insn->exp.X_op_symbol) ?
1109 S_GET_NAME (insn->exp.X_op_symbol) : "???") : "0");
305d537e 1110 fprintf (stderr, "\t\tX_add_number = %lx\n",
252b5132
RH
1111 insn->exp.X_add_number);
1112 fprintf (stderr, "}\n");
1113}
305d537e
JE
1114#endif /* DEBUG_I860 */
1115
252b5132 1116\f
305d537e 1117#ifdef OBJ_ELF
5a38dc70 1118const char *md_shortopts = "VQ:";
305d537e 1119#else
5a38dc70 1120const char *md_shortopts = "";
305d537e
JE
1121#endif
1122
305d537e
JE
1123#define OPTION_EB (OPTION_MD_BASE + 0)
1124#define OPTION_EL (OPTION_MD_BASE + 1)
1125#define OPTION_WARN_EXPAND (OPTION_MD_BASE + 2)
14218d5f 1126#define OPTION_XP (OPTION_MD_BASE + 3)
87505968 1127#define OPTION_INTEL_SYNTAX (OPTION_MD_BASE + 4)
305d537e 1128
252b5132 1129struct option md_longopts[] = {
305d537e
JE
1130 { "EB", no_argument, NULL, OPTION_EB },
1131 { "EL", no_argument, NULL, OPTION_EL },
1132 { "mwarn-expand", no_argument, NULL, OPTION_WARN_EXPAND },
14218d5f 1133 { "mxp", no_argument, NULL, OPTION_XP },
87505968 1134 { "mintel-syntax",no_argument, NULL, OPTION_INTEL_SYNTAX },
305d537e 1135 { NULL, no_argument, NULL, 0 }
252b5132 1136};
305d537e
JE
1137size_t md_longopts_size = sizeof (md_longopts);
1138
252b5132 1139int
7734b6e9 1140md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
252b5132 1141{
305d537e
JE
1142 switch (c)
1143 {
1144 case OPTION_EB:
1145 target_big_endian = 1;
1146 break;
1147
1148 case OPTION_EL:
1149 target_big_endian = 0;
1150 break;
1151
1152 case OPTION_WARN_EXPAND:
1153 target_warn_expand = 1;
1154 break;
1155
14218d5f
JE
1156 case OPTION_XP:
1157 target_xp = 1;
1158 break;
1159
87505968
JE
1160 case OPTION_INTEL_SYNTAX:
1161 target_intel_syntax = 1;
1162 break;
1163
305d537e
JE
1164#ifdef OBJ_ELF
1165 /* SVR4 argument compatibility (-V): print version ID. */
1166 case 'V':
1167 print_version_id ();
1168 break;
1169
1170 /* SVR4 argument compatibility (-Qy, -Qn): controls whether
1171 a .comment section should be emitted or not (ignored). */
1172 case 'Q':
1173 break;
1174#endif
1175
1176 default:
1177 return 0;
1178 }
1179
1180 return 1;
252b5132
RH
1181}
1182
1183void
7734b6e9 1184md_show_usage (FILE *stream)
252b5132 1185{
305d537e
JE
1186 fprintf (stream, _("\
1187 -EL generate code for little endian mode (default)\n\
1188 -EB generate code for big endian mode\n\
14218d5f 1189 -mwarn-expand warn if pseudo operations are expanded\n\
87505968
JE
1190 -mxp enable i860XP support (disabled by default)\n\
1191 -mintel-syntax enable Intel syntax (default to AT&T/SVR4)\n"));
305d537e
JE
1192#ifdef OBJ_ELF
1193 /* SVR4 compatibility flags. */
1194 fprintf (stream, _("\
1195 -V print assembler version number\n\
1196 -Qy, -Qn ignored\n"));
1197#endif
252b5132 1198}
305d537e 1199
252b5132 1200\f
305d537e
JE
1201/* We have no need to default values of symbols. */
1202symbolS *
7734b6e9 1203md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
305d537e
JE
1204{
1205 return 0;
1206}
1207
305d537e 1208/* The i860 denotes auto-increment with '++'. */
252b5132 1209void
7734b6e9 1210md_operand (expressionS *exp)
252b5132 1211{
305d537e 1212 char *s;
252b5132 1213
f869cfc6 1214 for (s = input_line_pointer; *s; s++)
252b5132 1215 {
305d537e 1216 if (s[0] == '+' && s[1] == '+')
252b5132 1217 {
305d537e
JE
1218 input_line_pointer += 2;
1219 exp->X_op = O_register;
1220 break;
252b5132 1221 }
305d537e
JE
1222 }
1223}
1224
305d537e
JE
1225/* Round up a section size to the appropriate boundary. */
1226valueT
7734b6e9
JE
1227md_section_align (segT segment ATTRIBUTE_UNUSED,
1228 valueT size ATTRIBUTE_UNUSED)
305d537e
JE
1229{
1230 /* Byte alignment is fine. */
1231 return size;
1232}
1233
305d537e
JE
1234/* On the i860, a PC-relative offset is relative to the address of the
1235 of the offset plus its size. */
1236long
7734b6e9 1237md_pcrel_from (fixS *fixP)
305d537e
JE
1238{
1239 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
1240}
252b5132 1241
305d537e
JE
1242/* Determine the relocation needed for non PC-relative 16-bit immediates.
1243 Also adjust the given immediate as necessary. Finally, check that
1244 all constraints (such as alignment) are satisfied. */
1245static bfd_reloc_code_real_type
7734b6e9 1246obtain_reloc_for_imm16 (fixS *fix, long *val)
305d537e
JE
1247{
1248 valueT fup = fix->fx_addnumber;
4a4f25cf 1249 bfd_reloc_code_real_type reloc;
305d537e
JE
1250
1251 if (fix->fx_pcrel)
1252 abort ();
1253
1254 /* Check alignment restrictions. */
1255 if ((fup & OP_ALIGN2) && (*val & 0x1))
1256 as_bad_where (fix->fx_file, fix->fx_line,
1257 _("This immediate requires 0 MOD 2 alignment"));
1258 else if ((fup & OP_ALIGN4) && (*val & 0x3))
1259 as_bad_where (fix->fx_file, fix->fx_line,
1260 _("This immediate requires 0 MOD 4 alignment"));
1261 else if ((fup & OP_ALIGN8) && (*val & 0x7))
1262 as_bad_where (fix->fx_file, fix->fx_line,
1263 _("This immediate requires 0 MOD 8 alignment"));
1264 else if ((fup & OP_ALIGN16) && (*val & 0xf))
1265 as_bad_where (fix->fx_file, fix->fx_line,
1266 _("This immediate requires 0 MOD 16 alignment"));
1267
1268 if (fup & OP_SEL_HA)
1269 {
1270 *val = (*val >> 16) + (*val & 0x8000 ? 1 : 0);
1271 reloc = BFD_RELOC_860_HIGHADJ;
1272 }
1273 else if (fup & OP_SEL_H)
1274 {
1275 *val >>= 16;
1276 reloc = BFD_RELOC_860_HIGH;
1277 }
1278 else if (fup & OP_SEL_L)
1279 {
1280 int num_encode;
1281 if (fup & OP_IMM_SPLIT16)
252b5132 1282 {
305d537e 1283 if (fup & OP_ENCODE1)
252b5132 1284 {
305d537e
JE
1285 num_encode = 1;
1286 reloc = BFD_RELOC_860_SPLIT1;
1287 }
1288 else if (fup & OP_ENCODE2)
1289 {
1290 num_encode = 2;
1291 reloc = BFD_RELOC_860_SPLIT2;
252b5132
RH
1292 }
1293 else
1294 {
305d537e
JE
1295 num_encode = 0;
1296 reloc = BFD_RELOC_860_SPLIT0;
252b5132 1297 }
305d537e
JE
1298 }
1299 else
1300 {
1301 if (fup & OP_ENCODE1)
252b5132 1302 {
305d537e
JE
1303 num_encode = 1;
1304 reloc = BFD_RELOC_860_LOW1;
252b5132 1305 }
305d537e 1306 else if (fup & OP_ENCODE2)
252b5132 1307 {
305d537e
JE
1308 num_encode = 2;
1309 reloc = BFD_RELOC_860_LOW2;
1310 }
1311 else if (fup & OP_ENCODE3)
1312 {
1313 num_encode = 3;
1314 reloc = BFD_RELOC_860_LOW3;
252b5132
RH
1315 }
1316 else
1317 {
305d537e
JE
1318 num_encode = 0;
1319 reloc = BFD_RELOC_860_LOW0;
252b5132 1320 }
252b5132 1321 }
305d537e
JE
1322
1323 /* Preserve size encode bits. */
1324 *val &= ~((1 << num_encode) - 1);
252b5132 1325 }
305d537e
JE
1326 else
1327 {
1328 /* No selector. What reloc do we generate (???)? */
1329 reloc = BFD_RELOC_32;
1330 }
1331
1332 return reloc;
252b5132
RH
1333}
1334
305d537e
JE
1335/* Attempt to simplify or eliminate a fixup. To indicate that a fixup
1336 has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
1337 we will have to generate a reloc entry. */
94f592af
NC
1338
1339void
7734b6e9 1340md_apply_fix3 (fixS *fix, valueT *valP, segT seg ATTRIBUTE_UNUSED)
305d537e 1341{
305d537e 1342 char *buf;
a161fe53 1343 long val = *valP;
305d537e
JE
1344 unsigned long insn;
1345 valueT fup;
252b5132 1346
305d537e 1347 buf = fix->fx_frag->fr_literal + fix->fx_where;
252b5132 1348
305d537e
JE
1349 /* Recall that earlier we stored the opcode little-endian. */
1350 insn = bfd_getl32 (buf);
252b5132 1351
305d537e
JE
1352 /* We stored a fix-up in this oddly-named scratch field. */
1353 fup = fix->fx_addnumber;
1354
1355 /* Determine the necessary relocations as well as inserting an
1356 immediate into the instruction. */
673a54e3 1357 if (fup & OP_IMM_U5)
252b5132 1358 {
305d537e
JE
1359 if (val & ~0x1f)
1360 as_bad_where (fix->fx_file, fix->fx_line,
1361 _("5-bit immediate too large"));
1362 if (fix->fx_addsy)
1363 as_bad_where (fix->fx_file, fix->fx_line,
1364 _("5-bit field must be absolute"));
1365
1366 insn |= (val & 0x1f) << 11;
1367 bfd_putl32 (insn, buf);
1368 fix->fx_r_type = BFD_RELOC_NONE;
1369 fix->fx_done = 1;
252b5132 1370 }
305d537e 1371 else if (fup & OP_IMM_S16)
252b5132 1372 {
305d537e 1373 fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val);
252b5132 1374
305d537e 1375 /* Insert the immediate. */
ded0649c
JE
1376 if (fix->fx_addsy)
1377 fix->fx_done = 0;
1378 else
1379 {
1380 insn |= val & 0xffff;
1381 bfd_putl32 (insn, buf);
1382 fix->fx_r_type = BFD_RELOC_NONE;
1383 fix->fx_done = 1;
1384 }
305d537e
JE
1385 }
1386 else if (fup & OP_IMM_U16)
94f592af
NC
1387 abort ();
1388
305d537e
JE
1389 else if (fup & OP_IMM_SPLIT16)
1390 {
1391 fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val);
1392
1393 /* Insert the immediate. */
ded0649c
JE
1394 if (fix->fx_addsy)
1395 fix->fx_done = 0;
1396 else
1397 {
1398 insn |= val & 0x7ff;
1399 insn |= (val & 0xf800) << 5;
1400 bfd_putl32 (insn, buf);
1401 fix->fx_r_type = BFD_RELOC_NONE;
1402 fix->fx_done = 1;
1403 }
4a4f25cf 1404 }
305d537e 1405 else if (fup & OP_IMM_BR16)
252b5132 1406 {
305d537e
JE
1407 if (val & 0x3)
1408 as_bad_where (fix->fx_file, fix->fx_line,
1409 _("A branch offset requires 0 MOD 4 alignment"));
1410
1411 val = val >> 2;
1412
1413 /* Insert the immediate. */
ded0649c
JE
1414 if (fix->fx_addsy)
1415 {
1416 fix->fx_done = 0;
1417 fix->fx_r_type = BFD_RELOC_860_PC16;
1418 }
1419 else
1420 {
1421 insn |= (val & 0x7ff);
1422 insn |= ((val & 0xf800) << 5);
1423 bfd_putl32 (insn, buf);
1424 fix->fx_r_type = BFD_RELOC_NONE;
1425 fix->fx_done = 1;
1426 }
252b5132 1427 }
305d537e 1428 else if (fup & OP_IMM_BR26)
252b5132 1429 {
305d537e
JE
1430 if (val & 0x3)
1431 as_bad_where (fix->fx_file, fix->fx_line,
1432 _("A branch offset requires 0 MOD 4 alignment"));
252b5132 1433
305d537e 1434 val >>= 2;
252b5132 1435
305d537e 1436 /* Insert the immediate. */
ded0649c
JE
1437 if (fix->fx_addsy)
1438 {
1439 fix->fx_r_type = BFD_RELOC_860_PC26;
1440 fix->fx_done = 0;
1441 }
1442 else
1443 {
1444 insn |= (val & 0x3ffffff);
1445 bfd_putl32 (insn, buf);
1446 fix->fx_r_type = BFD_RELOC_NONE;
1447 fix->fx_done = 1;
1448 }
305d537e
JE
1449 }
1450 else if (fup != OP_NONE)
1451 {
4a4f25cf 1452 as_bad_where (fix->fx_file, fix->fx_line,
d444b726 1453 _("Unrecognized fix-up (0x%08lx)"), (unsigned long) fup);
305d537e
JE
1454 abort ();
1455 }
1456 else
1457 {
1458 /* I believe only fix-ups such as ".long .ep.main-main+0xc8000000"
1459 reach here (???). */
ded0649c
JE
1460 if (fix->fx_addsy)
1461 {
1462 fix->fx_r_type = BFD_RELOC_32;
1463 fix->fx_done = 0;
1464 }
1465 else
1466 {
1467 insn |= (val & 0xffffffff);
1468 bfd_putl32 (insn, buf);
1469 fix->fx_r_type = BFD_RELOC_NONE;
1470 fix->fx_done = 1;
1471 }
305d537e 1472 }
252b5132
RH
1473}
1474
305d537e
JE
1475/* Generate a machine dependent reloc from a fixup. */
1476arelent*
7734b6e9
JE
1477tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1478 fixS *fixp)
252b5132 1479{
305d537e 1480 arelent *reloc;
252b5132 1481
305d537e
JE
1482 reloc = xmalloc (sizeof (*reloc));
1483 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1484 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1485 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1486 reloc->addend = fixp->fx_offset;
1487 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
252b5132 1488
305d537e 1489 if (! reloc->howto)
252b5132 1490 {
305d537e
JE
1491 as_bad_where (fixp->fx_file, fixp->fx_line,
1492 "Cannot represent %s relocation in object file",
1493 bfd_get_reloc_code_name (fixp->fx_r_type));
252b5132 1494 }
305d537e 1495 return reloc;
252b5132 1496}
e15f6d30
JE
1497
1498/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
1499 of an rs_align_code fragment. */
1500
1501void
1502i860_handle_align (fragS *fragp)
1503{
1504 /* Instructions are always stored little-endian on the i860. */
1505 static const unsigned char le_nop[] = { 0x00, 0x00, 0x00, 0xA0 };
1506
1507 int bytes;
1508 char *p;
1509
1510 if (fragp->fr_type != rs_align_code)
1511 return;
1512
1513 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
1514 p = fragp->fr_literal + fragp->fr_fix;
1515
1516 /* Make sure we are on a 4-byte boundary, in case someone has been
1517 putting data into a text section. */
1518 if (bytes & 3)
1519 {
1520 int fix = bytes & 3;
1521 memset (p, 0, fix);
1522 p += fix;
1523 fragp->fr_fix += fix;
1524 }
1525
1526 memcpy (p, le_nop, 4);
1527 fragp->fr_var = 4;
1528}
1529
This page took 0.344364 seconds and 4 git commands to generate.